sparc_config were used to handle the differences between the machines.
With only LEON supported sparc_config is no longer required.

This has the added benefit that we get rid of a rw variable
with several function pointers thus reducing our attack surface.

Signed-off-by: Sam Ravnborg <s...@ravnborg.org>
Cc: Sam Ravnborg <s...@ravnborg.org>
Cc: Arnd Bergmann <a...@kernel.org>
Cc: Andreas Larsson <andr...@gaisler.com>
---
 arch/sparc/include/asm/timer_32.h |   1 +
 arch/sparc/kernel/irq.h           |  32 ++-------
 arch/sparc/kernel/irq_32.c        |   3 -
 arch/sparc/kernel/leon_kernel.c   |  27 ++------
 arch/sparc/kernel/of_device_32.c  |   4 +-
 arch/sparc/kernel/time_32.c       | 110 +++++++++++++-----------------
 6 files changed, 61 insertions(+), 116 deletions(-)

diff --git a/arch/sparc/include/asm/timer_32.h 
b/arch/sparc/include/asm/timer_32.h
index eecd2696922d..1cd89a99966f 100644
--- a/arch/sparc/include/asm/timer_32.h
+++ b/arch/sparc/include/asm/timer_32.h
@@ -17,6 +17,7 @@
 #include <asm/cpu_type.h>  /* For SUN4M_NCPUS */
 
 #define SBUS_CLOCK_RATE   2000000 /* 2MHz */
+#define LEON_CLOCK_RATE   1000000
 #define TIMER_VALUE_SHIFT 9
 #define TIMER_VALUE_MASK  0x3fffff
 #define TIMER_LIMIT_BIT   (1 << 31)  /* Bit 31 in Counter-Timer register */
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 0d9b740725b4..ba0db1e4df6f 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -49,33 +49,6 @@ extern struct sun4m_irq_global __iomem *sun4m_irq_global;
 #define FEAT_L10_CLOCKEVENT  (1 << 1) /* L10 timer is used as a clockevent */
 #define FEAT_L14_ONESHOT     (1 << 2) /* L14 timer clockevent can oneshot */
 
-/*
- * Platform specific configuration
- * The individual platforms assign their platform
- * specifics in their init functions.
- */
-struct sparc_config {
-       void (*init_timers)(void);
-       unsigned int (*build_device_irq)(struct platform_device *op,
-                                        unsigned int real_irq);
-
-       /* generic clockevent features - see FEAT_* above */
-       int features;
-
-       /* clock rate used for clock event timer */
-       int clock_rate;
-
-       /* one period for clock source timer */
-       unsigned int cs_period;
-
-       /* function to obtain offsett for cs period */
-       unsigned int (*get_cycles_offset)(void);
-
-       void (*clear_clock_irq)(void);
-       void (*load_profile_irq)(int cpu, unsigned int limit);
-};
-extern struct sparc_config sparc_config;
-
 unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
 void irq_link(unsigned int irq);
 void irq_unlink(unsigned int irq);
@@ -89,6 +62,11 @@ void sun4m_nmi(struct pt_regs *regs);
 /* sun4d_irq.c */
 void sun4d_handler_irq(unsigned int pil, struct pt_regs *regs);
 
+/* leon_kernel.c */
+void leon_clear_clock_irq(void);
+void leon_load_profile_irq(int cpu, unsigned int limit);
+u32 leon_cycles_offset(void);
+
 #ifdef CONFIG_SMP
 
 /* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index a6af08fce796..f76f57073323 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -24,9 +24,6 @@
 #include "kernel.h"
 #include "irq.h"
 
-/* platform specific irq setup */
-struct sparc_config sparc_config;
-
 unsigned long arch_local_irq_save(void)
 {
        unsigned long retval;
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 49b37a0dcc2b..491dff89f52c 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -239,12 +239,6 @@ unsigned int leon_build_device_irq(unsigned int real_irq,
        return irq;
 }
 
-static unsigned int _leon_build_device_irq(struct platform_device *op,
-                                          unsigned int real_irq)
-{
-       return leon_build_device_irq(real_irq, handle_simple_irq, "edge", 0);
-}
-
 void leon_update_virq_handling(unsigned int virq,
                              irq_flow_handler_t flow_handler,
                              const char *name, int do_ack)
@@ -260,7 +254,7 @@ void leon_update_virq_handling(unsigned int virq,
        irq_set_chip_data(virq, (void *)mask);
 }
 
-static u32 leon_cycles_offset(void)
+u32 leon_cycles_offset(void)
 {
        u32 rld, val, ctrl, off;
 
@@ -314,14 +308,6 @@ void __init leon_init_timers(void)
        u32 config;
        u32 ctrl;
 
-       sparc_config.get_cycles_offset = leon_cycles_offset;
-       sparc_config.cs_period = 1000000 / HZ;
-       sparc_config.features |= FEAT_L10_CLOCKSOURCE;
-
-#ifndef CONFIG_SMP
-       sparc_config.features |= FEAT_L10_CLOCKEVENT;
-#endif
-
        leondebug_irq_disable = 0;
        leon_debug_irqout = 0;
        master_l10_counter = (u32 __iomem *)&dummy_master_l10_counter;
@@ -436,7 +422,7 @@ void __init leon_init_timers(void)
        err = request_irq(irq, leon_percpu_timer_ce_interrupt,
                          IRQF_PERCPU | IRQF_TIMER, "timer", NULL);
 #else
-       irq = _leon_build_device_irq(NULL, leon3_gptimer_irq);
+       irq = leon_build_device_irq(leon3_gptimer_irq, handle_simple_irq, 
"edge", 0);
        err = request_irq(irq, timer_interrupt, IRQF_TIMER, "timer", NULL);
 #endif
        if (err) {
@@ -455,7 +441,7 @@ void __init leon_init_timers(void)
        return;
 }
 
-static void leon_clear_clock_irq(void)
+void leon_clear_clock_irq(void)
 {
        u32 ctrl;
 
@@ -464,7 +450,7 @@ static void leon_clear_clock_irq(void)
                              ctrl & leon3_gptimer_ackmask);
 }
 
-static void leon_load_profile_irq(int cpu, unsigned int limit)
+void leon_load_profile_irq(int cpu, unsigned int limit)
 {
 }
 
@@ -487,9 +473,4 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int 
cpu)
 
 void __init leon_init_IRQ(void)
 {
-       sparc_config.init_timers      = leon_init_timers;
-       sparc_config.build_device_irq = _leon_build_device_irq;
-       sparc_config.clock_rate       = 1000000;
-       sparc_config.clear_clock_irq  = leon_clear_clock_irq;
-       sparc_config.load_profile_irq = leon_load_profile_irq;
 }
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 4ebf51e6e78e..c846acdb4455 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -358,7 +358,7 @@ static struct platform_device * __init 
scan_one_device(struct device_node *dp,
                op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs);
                for (i = 0; i < op->archdata.num_irqs; i++)
                        op->archdata.irqs[i] =
-                           sparc_config.build_device_irq(op, intr[i].pri);
+                           leon_build_device_irq(intr[i].pri, 
handle_simple_irq, "edge", 0);
        } else {
                const unsigned int *irq =
                        of_get_property(dp, "interrupts", &len);
@@ -367,7 +367,7 @@ static struct platform_device * __init 
scan_one_device(struct device_node *dp,
                        op->archdata.num_irqs = len / sizeof(unsigned int);
                        for (i = 0; i < op->archdata.num_irqs; i++)
                                op->archdata.irqs[i] =
-                                   sparc_config.build_device_irq(op, irq[i]);
+                                   leon_build_device_irq(irq[i], 
handle_simple_irq, "edge", 0);
                } else {
                        op->archdata.num_irqs = 0;
                }
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 0093cf4ecb06..8619a3d9953f 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -45,6 +45,7 @@
 #include <asm/idprom.h>
 #include <asm/page.h>
 #include <asm/irq_regs.h>
+#include <asm/leon.h>
 #include <asm/setup.h>
 
 #include "kernel.h"
@@ -89,10 +90,10 @@ irqreturn_t notrace timer_interrupt(int dummy, void *dev_id)
        if (timer_cs_enabled) {
                write_seqlock(&timer_cs_lock);
                timer_cs_internal_counter++;
-               sparc_config.clear_clock_irq();
+               leon_clear_clock_irq();
                write_sequnlock(&timer_cs_lock);
        } else {
-               sparc_config.clear_clock_irq();
+               leon_clear_clock_irq();
        }
 
        if (timer_ce_enabled)
@@ -101,39 +102,6 @@ irqreturn_t notrace timer_interrupt(int dummy, void 
*dev_id)
        return IRQ_HANDLED;
 }
 
-static int timer_ce_shutdown(struct clock_event_device *evt)
-{
-       timer_ce_enabled = 0;
-       smp_mb();
-       return 0;
-}
-
-static int timer_ce_set_periodic(struct clock_event_device *evt)
-{
-       timer_ce_enabled = 1;
-       smp_mb();
-       return 0;
-}
-
-static __init void setup_timer_ce(void)
-{
-       struct clock_event_device *ce = &timer_ce;
-
-       BUG_ON(smp_processor_id() != boot_cpu_id);
-
-       ce->name     = "timer_ce";
-       ce->rating   = 100;
-       ce->features = CLOCK_EVT_FEAT_PERIODIC;
-       ce->set_state_shutdown = timer_ce_shutdown;
-       ce->set_state_periodic = timer_ce_set_periodic;
-       ce->tick_resume = timer_ce_set_periodic;
-       ce->cpumask  = cpu_possible_mask;
-       ce->shift    = 32;
-       ce->mult     = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
-                             ce->shift);
-       clockevents_register_device(ce);
-}
-
 static unsigned int sbus_cycles_offset(void)
 {
        u32 val, offset;
@@ -143,7 +111,7 @@ static unsigned int sbus_cycles_offset(void)
 
        /* Limit hit? */
        if (val & TIMER_LIMIT_BIT)
-               offset += sparc_config.cs_period;
+               offset += 1000000 / HZ;
 
        return offset;
 }
@@ -157,11 +125,11 @@ static u64 timer_cs_read(struct clocksource *cs)
                seq = read_seqbegin(&timer_cs_lock);
 
                cycles = timer_cs_internal_counter;
-               offset = sparc_config.get_cycles_offset();
+               offset = sbus_cycles_offset();
        } while (read_seqretry(&timer_cs_lock, seq));
 
        /* Count absolute cycles */
-       cycles *= sparc_config.cs_period;
+       cycles *= LEON_CLOCK_RATE / HZ;
        cycles += offset;
 
        return cycles;
@@ -178,15 +146,47 @@ static struct clocksource timer_cs = {
 static __init int setup_timer_cs(void)
 {
        timer_cs_enabled = 1;
-       return clocksource_register_hz(&timer_cs, sparc_config.clock_rate);
+       return clocksource_register_hz(&timer_cs, LEON_CLOCK_RATE);
 }
 
 #ifdef CONFIG_SMP
+static int timer_ce_shutdown(struct clock_event_device *evt)
+{
+       timer_ce_enabled = 0;
+       smp_mb();
+       return 0;
+}
+
+static int timer_ce_set_periodic(struct clock_event_device *evt)
+{
+       timer_ce_enabled = 1;
+       smp_mb();
+       return 0;
+}
+
+static __init void setup_timer_ce(void)
+{
+       struct clock_event_device *ce = &timer_ce;
+
+       BUG_ON(smp_processor_id() != boot_cpu_id);
+
+       ce->name     = "timer_ce";
+       ce->rating   = 100;
+       ce->features = CLOCK_EVT_FEAT_PERIODIC;
+       ce->set_state_shutdown = timer_ce_shutdown;
+       ce->set_state_periodic = timer_ce_set_periodic;
+       ce->tick_resume = timer_ce_set_periodic;
+       ce->cpumask  = cpu_possible_mask;
+       ce->shift    = 32;
+       ce->mult     = div_sc(LEON_CLOCK_RATE, NSEC_PER_SEC, ce->shift);
+       clockevents_register_device(ce);
+}
+
 static int percpu_ce_shutdown(struct clock_event_device *evt)
 {
        int cpu = cpumask_first(evt->cpumask);
 
-       sparc_config.load_profile_irq(cpu, 0);
+       leon_load_profile_irq(cpu, 0);
        return 0;
 }
 
@@ -194,7 +194,7 @@ static int percpu_ce_set_periodic(struct clock_event_device 
*evt)
 {
        int cpu = cpumask_first(evt->cpumask);
 
-       sparc_config.load_profile_irq(cpu, SBUS_CLOCK_RATE / HZ);
+       leon_load_profile_irq(cpu, SBUS_CLOCK_RATE / HZ);
        return 0;
 }
 
@@ -204,7 +204,7 @@ static int percpu_ce_set_next_event(unsigned long delta,
        int cpu = cpumask_first(evt->cpumask);
        unsigned int next = (unsigned int)delta;
 
-       sparc_config.load_profile_irq(cpu, next);
+       leon_load_profile_irq(cpu, next);
        return 0;
 }
 
@@ -213,9 +213,6 @@ void register_percpu_ce(int cpu)
        struct clock_event_device *ce = &per_cpu(sparc32_clockevent, cpu);
        unsigned int features = CLOCK_EVT_FEAT_PERIODIC;
 
-       if (sparc_config.features & FEAT_L14_ONESHOT)
-               features |= CLOCK_EVT_FEAT_ONESHOT;
-
        ce->name           = "percpu_ce";
        ce->rating         = 200;
        ce->features       = features;
@@ -225,10 +222,9 @@ void register_percpu_ce(int cpu)
        ce->set_next_event = percpu_ce_set_next_event;
        ce->cpumask        = cpumask_of(cpu);
        ce->shift          = 32;
-       ce->mult           = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
-                                   ce->shift);
-       ce->max_delta_ns   = clockevent_delta2ns(sparc_config.clock_rate, ce);
-       ce->max_delta_ticks = (unsigned long)sparc_config.clock_rate;
+       ce->mult           = div_sc(LEON_CLOCK_RATE, NSEC_PER_SEC, ce->shift);
+       ce->max_delta_ns   = clockevent_delta2ns(LEON_CLOCK_RATE, ce);
+       ce->max_delta_ticks = (unsigned long)LEON_CLOCK_RATE;
        ce->min_delta_ns   = clockevent_delta2ns(100, ce);
        ce->min_delta_ticks = 100;
 
@@ -327,26 +323,18 @@ fs_initcall(clock_init);
 
 static void __init sparc32_late_time_init(void)
 {
-       if (sparc_config.features & FEAT_L10_CLOCKEVENT)
-               setup_timer_ce();
-       if (sparc_config.features & FEAT_L10_CLOCKSOURCE)
-               setup_timer_cs();
+       setup_timer_cs();
+
 #ifdef CONFIG_SMP
+       setup_timer_ce();
        register_percpu_ce(smp_processor_id());
 #endif
 }
 
-static void __init sbus_time_init(void)
-{
-       sparc_config.get_cycles_offset = sbus_cycles_offset;
-       sparc_config.init_timers();
-}
-
 void __init time_init(void)
 {
-       sparc_config.features = 0;
        late_time_init = sparc32_late_time_init;
 
-       sbus_time_init();
+       leon_init_timers();
 }
 
-- 
2.27.0

Reply via email to