Initial porting of xenomai on exynos4
authorArnaud Degroote <arnaud.degroote@isae-supaero.fr>
Fri, 23 Jan 2015 15:11:53 +0000 (16:11 +0100)
committerMarek Szyprowski <m.szyprowski@samsung.com>
Thu, 26 Apr 2018 11:28:38 +0000 (13:28 +0200)
Based on patch from kinsamanka

Signed-off-by: Arnaud Degroote <arnaud.degroote@isae-supaero.fr>
[patch taken from https://github.com/adegroote/linux.git
 linux-stable-xenomai-odroid-3.18.y branch]
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
drivers/clocksource/exynos_mct.c
drivers/irqchip/exynos-combiner.c
drivers/pinctrl/samsung/pinctrl-exynos.c
drivers/pinctrl/samsung/pinctrl-samsung.h

index f5c48c417c1a7a76b1cfa71a48b8ef6029996d81..6db3ba02237ff1edbcf2e0cd0b73c3c81e34913c 100644 (file)
@@ -25,6 +25,8 @@
 #include <linux/of_address.h>
 #include <linux/clocksource.h>
 #include <linux/sched_clock.h>
+#include <linux/ipipe.h>
+#include <linux/ipipe_tickdev.h>
 
 #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();
index 5945223b73fa2ceba647649e6c16c84fc5447d08..a11fd3b6e921762ff1a4be24e43e886fdd8494f8 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/ipipe.h>
 
 #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);
index 935b8d53f994d7a7a767d841690b5f361cb8d106..121e9f0fe8064b9f0442ec4739ac0f771ca5a381 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/err.h>
+#include <linux/ipipe.h>
 
 #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);
        }
 }
index f305e46edba0386325dc2810c15ebe95175d8e1e..df51b8c2d9a57981807616a84690769024578924 100644 (file)
@@ -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*/
 };