Loading arch/mips/sibyte/bcm1480/smp.c +3 −2 Original line number Diff line number Diff line Loading @@ -69,8 +69,9 @@ void bcm1480_smp_init(void) void bcm1480_smp_finish(void) { extern void bcm1480_time_init(void); bcm1480_time_init(); extern void sb1480_clockevent_init(void); sb1480_clockevent_init(); local_irq_enable(); } Loading arch/mips/sibyte/bcm1480/time.c +49 −25 Original line number Diff line number Diff line Loading @@ -27,9 +27,8 @@ */ #include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/percpu.h> #include <linux/spinlock.h> #include <linux/kernel_stat.h> #include <asm/irq.h> #include <asm/addrspace.h> Loading Loading @@ -101,22 +100,33 @@ static void sibyte_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ case CLOCK_EVT_MODE_RESUME: ; } } struct clock_event_device sibyte_hpt_clockevent = { .name = "bcm1480-counter", .features = CLOCK_EVT_FEAT_PERIODIC, .set_mode = sibyte_set_mode, .shift = 32, .irq = 0, }; static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) { unsigned int cpu = smp_processor_id(); void __iomem *timer_init; unsigned int cnt; int res; timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); cnt = __raw_readq(timer_init); cnt += delta; __raw_writeq(cnt, timer_init); res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0; return res; } static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent); static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) { struct clock_event_device *cd = &sibyte_hpt_clockevent; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); /* Reset the timer */ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, Loading @@ -140,24 +150,21 @@ static struct irqaction sibyte_counter_irqaction = { * called directly from irq_handler.S when IP[4] is set during an * interrupt */ static void __init sb1480_clockevent_init(void) void __cpuinit sb1480_clockevent_init(void) { unsigned int cpu = smp_processor_id(); unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); setup_irq(irq, &sibyte_counter_irqaction); } void bcm1480_timer_interrupt(void) { int cpu = smp_processor_id(); int irq = K_BCM1480_INT_TIMER_0 + cpu; cd->name = "bcm1480-counter"; cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_MODE_ONESHOT; cd->set_next_event = sibyte_next_event; cd->set_mode = sibyte_set_mode; cd->irq = irq; clockevent_set_clock(cd, BCM1480_HPT_VALUE); /* Reset the timer */ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); ll_timer_interrupt(irq); setup_irq(irq, &sibyte_counter_irqaction); } static cycle_t bcm1480_hpt_read(void) Loading @@ -168,9 +175,26 @@ static cycle_t bcm1480_hpt_read(void) return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; } struct clocksource bcm1480_clocksource = { .name = "MIPS", .rating = 200, .read = bcm1480_hpt_read, .mask = CLOCKSOURCE_MASK(32), .shift = 32, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; void __init sb1480_clocksource_init(void) { struct clocksource *cs = &bcm1480_clocksource; clocksource_set_clock(cs, BCM1480_HPT_VALUE); clocksource_register(cs); } void __init bcm1480_hpt_setup(void) { clocksource_mips.read = bcm1480_hpt_read; mips_hpt_frequency = BCM1480_HPT_VALUE; sb1480_clocksource_init(); sb1480_clockevent_init(); } arch/mips/sibyte/sb1250/irq.c +2 −34 Original line number Diff line number Diff line Loading @@ -400,43 +400,11 @@ static void sb1250_kgdb_interrupt(void) #endif /* CONFIG_KGDB */ static inline void sb1250_timer_interrupt(void) { int cpu = smp_processor_id(); int irq = K_INT_TIMER_0 + cpu; irq_enter(); kstat_this_cpu.irqs[irq]++; write_seqlock(&xtime_lock); /* ACK interrupt */ ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); /* * call the generic timer interrupt handling */ do_timer(1); write_sequnlock(&xtime_lock); /* * In UP mode, we call local_timer_interrupt() to do profiling * and process accouting. * * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ local_timer_interrupt(irq); irq_exit(); } extern void sb1250_mailbox_interrupt(void); asmlinkage void plat_irq_dispatch(void) { unsigned int cpu = smp_processor_id(); unsigned int pending; /* Loading @@ -454,7 +422,7 @@ asmlinkage void plat_irq_dispatch(void) if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */ do_IRQ(MIPS_CPU_IRQ_BASE + 7); else if (pending & CAUSEF_IP4) sb1250_timer_interrupt(); do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */ #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) Loading arch/mips/sibyte/sb1250/smp.c +3 −2 Original line number Diff line number Diff line Loading @@ -57,8 +57,9 @@ void sb1250_smp_init(void) void sb1250_smp_finish(void) { extern void sb1250_time_init(void); sb1250_time_init(); extern void sb1250_clockevent_init(void); sb1250_clockevent_init(); local_irq_enable(); } Loading arch/mips/sibyte/sb1250/time.c +25 −79 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ static void sibyte_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ case CLOCK_EVT_MODE_RESUME: ; } } Loading Loading @@ -144,79 +145,7 @@ static struct irqaction sibyte_irqaction = { .name = "timer", }; /* * The general purpose timer ticks at 1 Mhz independent if * the rest of the system */ static void sibyte_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); void __iomem *timer_cfg, *timer_init; timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: __raw_writeq(0, timer_cfg); __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init); __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, timer_cfg); break; case CLOCK_EVT_MODE_ONESHOT: /* Stop the timer until we actually program a shot */ case CLOCK_EVT_MODE_SHUTDOWN: __raw_writeq(0, timer_cfg); break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ ; } } static int sibyte_next_event(unsigned long delta, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); void __iomem *timer_cfg, *timer_init; timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); __raw_writeq(0, timer_cfg); __raw_writeq(delta, timer_init); __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg); return 0; } struct clock_event_device sibyte_hpt_clockevent = { .name = "sb1250-counter", .features = CLOCK_EVT_FEAT_PERIODIC, .set_mode = sibyte_set_mode, .set_next_event = sibyte_next_event, .shift = 32, .irq = 0, }; static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) { struct clock_event_device *cd = &sibyte_hpt_clockevent; cd->event_handler(cd); return IRQ_HANDLED; } static struct irqaction sibyte_irqaction = { .handler = sibyte_counter_handler, .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "timer", }; static void __init sb1250_clockevent_init(void) void __cpuinit sb1250_clockevent_init(void) { struct clock_event_device *cd = &sibyte_hpt_clockevent; unsigned int cpu = smp_processor_id(); Loading Loading @@ -249,12 +178,6 @@ static void __init sb1250_clockevent_init(void) clockevents_register_device(cd); } void __init plat_time_init(void) { sb1250_clocksource_init(); sb1250_clockevent_init(); } /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over * again. Loading @@ -267,3 +190,26 @@ static cycle_t sb1250_hpt_read(void) return SB1250_HPT_VALUE - count; } struct clocksource bcm1250_clocksource = { .name = "MIPS", .rating = 200, .read = sb1250_hpt_read, .mask = CLOCKSOURCE_MASK(32), .shift = 32, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; void __init sb1250_clocksource_init(void) { struct clocksource *cs = &bcm1250_clocksource; clocksource_set_clock(cs, V_SCD_TIMER_FREQ); clocksource_register(cs); } void __init plat_time_init(void) { sb1250_clocksource_init(); sb1250_clockevent_init(); } Loading
arch/mips/sibyte/bcm1480/smp.c +3 −2 Original line number Diff line number Diff line Loading @@ -69,8 +69,9 @@ void bcm1480_smp_init(void) void bcm1480_smp_finish(void) { extern void bcm1480_time_init(void); bcm1480_time_init(); extern void sb1480_clockevent_init(void); sb1480_clockevent_init(); local_irq_enable(); } Loading
arch/mips/sibyte/bcm1480/time.c +49 −25 Original line number Diff line number Diff line Loading @@ -27,9 +27,8 @@ */ #include <linux/clockchips.h> #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/percpu.h> #include <linux/spinlock.h> #include <linux/kernel_stat.h> #include <asm/irq.h> #include <asm/addrspace.h> Loading Loading @@ -101,22 +100,33 @@ static void sibyte_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ case CLOCK_EVT_MODE_RESUME: ; } } struct clock_event_device sibyte_hpt_clockevent = { .name = "bcm1480-counter", .features = CLOCK_EVT_FEAT_PERIODIC, .set_mode = sibyte_set_mode, .shift = 32, .irq = 0, }; static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) { unsigned int cpu = smp_processor_id(); void __iomem *timer_init; unsigned int cnt; int res; timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); cnt = __raw_readq(timer_init); cnt += delta; __raw_writeq(cnt, timer_init); res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0; return res; } static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent); static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) { struct clock_event_device *cd = &sibyte_hpt_clockevent; unsigned int cpu = smp_processor_id(); struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); /* Reset the timer */ __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, Loading @@ -140,24 +150,21 @@ static struct irqaction sibyte_counter_irqaction = { * called directly from irq_handler.S when IP[4] is set during an * interrupt */ static void __init sb1480_clockevent_init(void) void __cpuinit sb1480_clockevent_init(void) { unsigned int cpu = smp_processor_id(); unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); setup_irq(irq, &sibyte_counter_irqaction); } void bcm1480_timer_interrupt(void) { int cpu = smp_processor_id(); int irq = K_BCM1480_INT_TIMER_0 + cpu; cd->name = "bcm1480-counter"; cd->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_MODE_ONESHOT; cd->set_next_event = sibyte_next_event; cd->set_mode = sibyte_set_mode; cd->irq = irq; clockevent_set_clock(cd, BCM1480_HPT_VALUE); /* Reset the timer */ __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); ll_timer_interrupt(irq); setup_irq(irq, &sibyte_counter_irqaction); } static cycle_t bcm1480_hpt_read(void) Loading @@ -168,9 +175,26 @@ static cycle_t bcm1480_hpt_read(void) return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; } struct clocksource bcm1480_clocksource = { .name = "MIPS", .rating = 200, .read = bcm1480_hpt_read, .mask = CLOCKSOURCE_MASK(32), .shift = 32, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; void __init sb1480_clocksource_init(void) { struct clocksource *cs = &bcm1480_clocksource; clocksource_set_clock(cs, BCM1480_HPT_VALUE); clocksource_register(cs); } void __init bcm1480_hpt_setup(void) { clocksource_mips.read = bcm1480_hpt_read; mips_hpt_frequency = BCM1480_HPT_VALUE; sb1480_clocksource_init(); sb1480_clockevent_init(); }
arch/mips/sibyte/sb1250/irq.c +2 −34 Original line number Diff line number Diff line Loading @@ -400,43 +400,11 @@ static void sb1250_kgdb_interrupt(void) #endif /* CONFIG_KGDB */ static inline void sb1250_timer_interrupt(void) { int cpu = smp_processor_id(); int irq = K_INT_TIMER_0 + cpu; irq_enter(); kstat_this_cpu.irqs[irq]++; write_seqlock(&xtime_lock); /* ACK interrupt */ ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); /* * call the generic timer interrupt handling */ do_timer(1); write_sequnlock(&xtime_lock); /* * In UP mode, we call local_timer_interrupt() to do profiling * and process accouting. * * In SMP mode, local_timer_interrupt() is invoked by appropriate * low-level local timer interrupt handler. */ local_timer_interrupt(irq); irq_exit(); } extern void sb1250_mailbox_interrupt(void); asmlinkage void plat_irq_dispatch(void) { unsigned int cpu = smp_processor_id(); unsigned int pending; /* Loading @@ -454,7 +422,7 @@ asmlinkage void plat_irq_dispatch(void) if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */ do_IRQ(MIPS_CPU_IRQ_BASE + 7); else if (pending & CAUSEF_IP4) sb1250_timer_interrupt(); do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */ #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) Loading
arch/mips/sibyte/sb1250/smp.c +3 −2 Original line number Diff line number Diff line Loading @@ -57,8 +57,9 @@ void sb1250_smp_init(void) void sb1250_smp_finish(void) { extern void sb1250_time_init(void); sb1250_time_init(); extern void sb1250_clockevent_init(void); sb1250_clockevent_init(); local_irq_enable(); } Loading
arch/mips/sibyte/sb1250/time.c +25 −79 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ static void sibyte_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ case CLOCK_EVT_MODE_RESUME: ; } } Loading Loading @@ -144,79 +145,7 @@ static struct irqaction sibyte_irqaction = { .name = "timer", }; /* * The general purpose timer ticks at 1 Mhz independent if * the rest of the system */ static void sibyte_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); void __iomem *timer_cfg, *timer_init; timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); switch (mode) { case CLOCK_EVT_MODE_PERIODIC: __raw_writeq(0, timer_cfg); __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init); __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, timer_cfg); break; case CLOCK_EVT_MODE_ONESHOT: /* Stop the timer until we actually program a shot */ case CLOCK_EVT_MODE_SHUTDOWN: __raw_writeq(0, timer_cfg); break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ ; } } static int sibyte_next_event(unsigned long delta, struct clock_event_device *evt) { unsigned int cpu = smp_processor_id(); void __iomem *timer_cfg, *timer_init; timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); __raw_writeq(0, timer_cfg); __raw_writeq(delta, timer_init); __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg); return 0; } struct clock_event_device sibyte_hpt_clockevent = { .name = "sb1250-counter", .features = CLOCK_EVT_FEAT_PERIODIC, .set_mode = sibyte_set_mode, .set_next_event = sibyte_next_event, .shift = 32, .irq = 0, }; static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) { struct clock_event_device *cd = &sibyte_hpt_clockevent; cd->event_handler(cd); return IRQ_HANDLED; } static struct irqaction sibyte_irqaction = { .handler = sibyte_counter_handler, .flags = IRQF_DISABLED | IRQF_PERCPU, .name = "timer", }; static void __init sb1250_clockevent_init(void) void __cpuinit sb1250_clockevent_init(void) { struct clock_event_device *cd = &sibyte_hpt_clockevent; unsigned int cpu = smp_processor_id(); Loading Loading @@ -249,12 +178,6 @@ static void __init sb1250_clockevent_init(void) clockevents_register_device(cd); } void __init plat_time_init(void) { sb1250_clocksource_init(); sb1250_clockevent_init(); } /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over * again. Loading @@ -267,3 +190,26 @@ static cycle_t sb1250_hpt_read(void) return SB1250_HPT_VALUE - count; } struct clocksource bcm1250_clocksource = { .name = "MIPS", .rating = 200, .read = sb1250_hpt_read, .mask = CLOCKSOURCE_MASK(32), .shift = 32, .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; void __init sb1250_clocksource_init(void) { struct clocksource *cs = &bcm1250_clocksource; clocksource_set_clock(cs, V_SCD_TIMER_FREQ); clocksource_register(cs); } void __init plat_time_init(void) { sb1250_clocksource_init(); sb1250_clockevent_init(); }