From: Arnaud Degroote Date: Fri, 23 Jan 2015 15:11:53 +0000 (+0100) Subject: Initial porting of xenomai on exynos4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5f53cb9237e99811f57ee579d054864db6fa5cf7;p=platform%2Fkernel%2Flinux-exynos.git Initial porting of xenomai on exynos4 Based on patch from kinsamanka Signed-off-by: Arnaud Degroote [patch taken from https://github.com/adegroote/linux.git linux-stable-xenomai-odroid-3.18.y branch] Signed-off-by: Marek Szyprowski --- diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index f5c48c417c1a..6db3ba02237f 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #define EXYNOS4_MCTREG(x) (x) #define EXYNOS4_MCT_G_CNT_L EXYNOS4_MCTREG(0x100) @@ -78,6 +80,7 @@ enum { }; static void __iomem *reg_base; +static u64 phys_base; static unsigned long clk_rate; static unsigned int mct_int_type; static int mct_irqs[MCT_NR_IRQS]; @@ -218,6 +221,17 @@ struct clocksource mct_frc = { .resume = exynos4_frc_resume, }; +#if defined(CONFIG_IPIPE) +static struct __ipipe_tscinfo tsc_info = { + .type = IPIPE_TSC_TYPE_FREERUNNING, + .u = { + { + .mask = 0xffffffff, + }, + }, +}; +#endif /* CONFIG_IPIPE */ + static u64 notrace exynos4_read_sched_clock(void) { return exynos4_read_count_32(); @@ -247,6 +261,13 @@ static void __init exynos4_clocksource_init(void) if (clocksource_register_hz(&mct_frc, clk_rate)) panic("%s: can't register clocksource\n", mct_frc.name); +#if defined(CONFIG_IPIPE) + tsc_info.freq = clk_rate; + tsc_info.counter_vaddr = (unsigned long)(reg_base + EXYNOS4_MCT_G_CNT_L); + tsc_info.u.counter_paddr = phys_base + EXYNOS4_MCT_G_CNT_L; + __ipipe_tsc_register(&tsc_info); +#endif /* CONFIG_IPIPE */ + sched_clock_register(exynos4_read_sched_clock, 32, clk_rate); } @@ -387,7 +408,7 @@ static void exynos4_mct_tick_start(unsigned long cycles, static int exynos4_tick_set_next_event(unsigned long cycles, struct clock_event_device *evt) { - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + struct mct_clock_event_device *mevt = raw_cpu_ptr(&percpu_mct_tick); exynos4_mct_tick_start(cycles, mevt); @@ -397,7 +418,7 @@ static int exynos4_tick_set_next_event(unsigned long cycles, static inline void exynos4_tick_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + struct mct_clock_event_device *mevt = raw_cpu_ptr(&percpu_mct_tick); unsigned long cycles_per_jiffy; exynos4_mct_tick_stop(mevt); @@ -438,12 +459,25 @@ static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) } } +#if defined(CONFIG_IPIPE) +static DEFINE_PER_CPU(struct ipipe_timer, mct_itimer); + +static void mct_tick_ack(void) +{ + struct mct_clock_event_device *mevt = raw_cpu_ptr(&percpu_mct_tick); + + exynos4_mct_tick_clear(mevt); +} +#endif /* CONFIG_IPIPE */ + static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) { struct mct_clock_event_device *mevt = dev_id; struct clock_event_device *evt = &mevt->evt; - exynos4_mct_tick_clear(mevt); + + if (!clockevent_ipipe_stolen(evt)) + exynos4_mct_tick_clear(mevt); evt->event_handler(evt); @@ -453,7 +487,7 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) static int exynos4_local_timer_setup(struct clock_event_device *evt) { struct mct_clock_event_device *mevt; - unsigned int cpu = smp_processor_id(); + unsigned int cpu = ipipe_processor_id(); mevt = container_of(evt, struct mct_clock_event_device, evt); @@ -479,6 +513,16 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } + +#if defined(CONFIG_IPIPE) + evt->ipipe_timer = raw_cpu_ptr(&mct_itimer); + if (mct_int_type == MCT_INT_SPI) + evt->ipipe_timer->irq = evt->irq; + else + evt->ipipe_timer->irq = mct_irqs[MCT_L0_IRQ]; + evt->ipipe_timer->ack = mct_tick_ack; +#endif + clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), 0xf, 0x7fffffff); @@ -514,11 +558,11 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, */ switch (action & ~CPU_TASKS_FROZEN) { case CPU_STARTING: - mevt = this_cpu_ptr(&percpu_mct_tick); + mevt = raw_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_setup(&mevt->evt); break; case CPU_DYING: - mevt = this_cpu_ptr(&percpu_mct_tick); + mevt = raw_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_stop(&mevt->evt); break; } @@ -533,7 +577,7 @@ static struct notifier_block exynos4_mct_cpu_nb = { static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base) { int err, cpu; - struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); + struct mct_clock_event_device *mevt = raw_cpu_ptr(&percpu_mct_tick); struct clk *mct_clk, *tick_clk; tick_clk = np ? of_clk_get_by_name(np, "fin_pll") : @@ -607,6 +651,7 @@ void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1) static void __init mct_init_dt(struct device_node *np, unsigned int int_type) { u32 nr_irqs, i; + struct resource mem; mct_int_type = int_type; @@ -626,6 +671,10 @@ static void __init mct_init_dt(struct device_node *np, unsigned int int_type) for (i = MCT_L0_IRQ; i < nr_irqs; i++) mct_irqs[i] = irq_of_parse_and_map(np, i); + if (of_address_to_resource(np, 0, &mem)) + mem.start = 0; + phys_base = mem.start; + exynos4_timer_resources(np, of_iomap(np, 0)); exynos4_clocksource_init(); exynos4_clockevent_init(); diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 5945223b73fa..a11fd3b6e921 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "irqchip.h" @@ -27,7 +28,7 @@ #define IRQ_IN_COMBINER 8 -static DEFINE_SPINLOCK(irq_controller_lock); +static IPIPE_DEFINE_SPINLOCK(irq_controller_lock); struct combiner_chip_data { unsigned int hwirq_offset; @@ -83,7 +84,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) if (unlikely(!cascade_irq)) handle_bad_irq(irq, desc); else - generic_handle_irq(cascade_irq); + ipipe_handle_demuxed_irq(cascade_irq); out: chained_irq_exit(chip, desc); diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index 935b8d53f994..121e9f0fe806 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "pinctrl-samsung.h" #include "pinctrl-exynos.h" @@ -295,7 +296,7 @@ static irqreturn_t exynos_eint_gpio_irq(int irq, void *data) virq = irq_linear_revmap(bank->irq_domain, pin); if (!virq) return IRQ_NONE; - generic_handle_irq(virq); + ipipe_handle_demuxed_irq(virq); return IRQ_HANDLED; } @@ -450,7 +451,7 @@ static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc) chip->irq_ack(&desc->irq_data); eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq); - generic_handle_irq(eint_irq); + ipipe_handle_demuxed_irq(eint_irq); chip->irq_unmask(&desc->irq_data); chained_irq_exit(chip, desc); } @@ -462,7 +463,7 @@ static inline void exynos_irq_demux_eint(unsigned long pend, while (pend) { irq = fls(pend) - 1; - generic_handle_irq(irq_find_mapping(domain, irq)); + ipipe_handle_demuxed_irq(irq_find_mapping(domain, irq)); pend &= ~(1 << irq); } } diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index f305e46edba0..df51b8c2d9a5 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -177,7 +177,7 @@ struct samsung_pin_bank { struct gpio_chip gpio_chip; struct pinctrl_gpio_range grange; struct exynos_irq_chip *irq_chip; - spinlock_t slock; + ipipe_spinlock_t slock; u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ };