From 6baa9b20a68a88c2fd751cbe8d7652009379351b Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 18 Apr 2011 11:25:44 +0000 Subject: sparc32: genirq support The conversion of sparc32 to genirq is based on original work done by David S. Miller. Daniel Hellstrom has helped in the conversion and implemented the shutdowm functionality. Marcel van Nies has tested this on Sparc Station 20 Test status: sun4c - not tested sun4m,pci - not tested sun4m,sbus - tested (Sparc Classic, Sparc Station 5, Sparc Station 20) sun4d - not tested leon - tested on various combinations of leon boards, including SMP variants generic Introduce use of GENERIC_HARDIRQS and GENERIC_IRQ_SHOW Allocate 64 IRQs - which is enough even for SS2000 Use a table of irq_bucket to maintain uses IRQs irq_bucket is also used to chain several irq's that must be called when the same intrrupt is asserted Use irq_link to link a interrupt source to the irq All plafforms must now supply their own build_device_irq method handler_irq rewriten to use generic irq support floppy Read FLOPPY_IRQ from platform device Use generic request_irq to register the floppy interrupt Rewrote sparc_floppy_irq to use the generic irq support pcic: Introduce irq_chip Store mask in chip_data for use in mask/unmask functions Add build_device_irq for pcic Use pcic_build_device_irq in pci_time_init allocate virtual irqs in pcic_fill_irq sun4c: Introduce irq_chip Store mask in chip_data for use in mask/unmask functions Add build_device_irq for sun4c Use sun4c_build_device_irq in sun4c_init_timers sun4m: Introduce irq_chip Introduce dedicated mask/unmask methods Introduce sun4m_handler_data that allow easy access to necessary data in the mask/unmask functions Add a helper method to enable profile_timer (used from smp) Added sun4m_build_device_irq Use sun4m_build_device_irq in sun4m_init_timers TODO: There is no replacement for smp_rotate that always scheduled next CPU as interrupt target upon an interrupt sun4d: Introduce irq_chip Introduce dedicated mask/unmask methods Introduce sun4d_handler_data that allow easy access to necessary data in mask/unmask fuctions Rewrote sun4d_handler_irq to use generic irq support TODO: The original implmentation of enable/disable had: if (irq < NR_IRQS) return; The new implmentation does not distingush between SBUS and cpu interrupts. I am no sure what is right here. I assume we need to do something for the cpu interrupts. I have not succeeded booting my sun4d box (with or without this patch) and my understanding of this platfrom is limited. So I would be a bit suprised if this works. leon: Introduce irq_chip Store mask in chip_data for use in mask/unmask functions Add build_device_irq for leon Use leon_build_device_irq in leon_init_timers Signed-off-by: Sam Ravnborg Acked-by: Daniel Hellstrom Tested-by: Daniel Hellstrom Tested-by: Marcel van Nies Cc: Thomas Gleixner Signed-off-by: David S. Miller --- arch/sparc/kernel/kernel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sparc/kernel/kernel.h') diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 24ad449886b..487d67a4e7f 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -37,6 +37,7 @@ extern void sun4c_init_IRQ(void); extern unsigned int lvl14_resolution; extern void sun4m_init_IRQ(void); +extern void sun4m_unmask_profile_irq(void); extern void sun4m_clear_profile_irq(int cpu); /* sun4d_irq.c */ -- cgit v1.2.3-70-g09d2 From cb1b8209815594613650772eeb889c170107dad4 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Thu, 21 Apr 2011 15:45:45 -0700 Subject: sparc: consolidate show_cpuinfo in cpu.c We have all the cpu related info in cpu.c - so move the remaining functions to support /proc/cpuinfo to this file. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/include/asm/pgtable_64.h | 3 + arch/sparc/include/asm/smp_64.h | 4 ++ arch/sparc/include/asm/system_64.h | 4 -- arch/sparc/kernel/cpu.c | 127 +++++++++++++++++++++++++++++++++++- arch/sparc/kernel/kernel.h | 4 +- arch/sparc/kernel/perf_event.c | 1 + arch/sparc/kernel/setup_32.c | 69 -------------------- arch/sparc/kernel/setup_64.c | 78 ---------------------- 8 files changed, 133 insertions(+), 157 deletions(-) (limited to 'arch/sparc/kernel/kernel.h') diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index f8dddb7045b..b77128c8052 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h @@ -699,6 +699,9 @@ extern pmd_t swapper_low_pmd_dir[2048]; extern void paging_init(void); extern unsigned long find_ecache_flush_span(unsigned long size); +struct seq_file; +extern void mmu_info(struct seq_file *); + /* These do nothing with the way I have things setup. */ #define mmu_lockarea(vaddr, len) (vaddr) #define mmu_unlockarea(vaddr, len) do { } while(0) diff --git a/arch/sparc/include/asm/smp_64.h b/arch/sparc/include/asm/smp_64.h index f49e11cd4de..20bca895071 100644 --- a/arch/sparc/include/asm/smp_64.h +++ b/arch/sparc/include/asm/smp_64.h @@ -49,6 +49,10 @@ extern void cpu_play_dead(void); extern void smp_fetch_global_regs(void); +struct seq_file; +void smp_bogo(struct seq_file *); +void smp_info(struct seq_file *); + #ifdef CONFIG_HOTPLUG_CPU extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h index e3b65d8cf41..3c96d3bb9f1 100644 --- a/arch/sparc/include/asm/system_64.h +++ b/arch/sparc/include/asm/system_64.h @@ -29,10 +29,6 @@ enum sparc_cpu { /* This cannot ever be a sun4c :) That's just history. */ #define ARCH_SUN4C 0 -extern const char *sparc_cpu_type; -extern const char *sparc_fpu_type; -extern const char *sparc_pmu_type; - extern char reboot_command[]; /* These are here in an effort to more fully work around Spitfire Errata diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 7925c54f413..c3483c71aa0 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -4,6 +4,7 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ +#include #include #include #include @@ -11,7 +12,9 @@ #include #include +#include #include +#include #include #include #include @@ -23,6 +26,9 @@ DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; EXPORT_PER_CPU_SYMBOL(__cpu_data); +int ncpus_probed; +unsigned int fsr_storage; + struct cpu_info { int psr_vers; const char *name; @@ -247,11 +253,10 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { * machine type value into consideration too. I will fix this. */ -const char *sparc_cpu_type; -const char *sparc_fpu_type; +static const char *sparc_cpu_type; +static const char *sparc_fpu_type; const char *sparc_pmu_type; -unsigned int fsr_storage; static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) { @@ -312,6 +317,122 @@ static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers) sparc_pmu_type = "Unknown PMU"; } +#ifdef CONFIG_SPARC32 +static int show_cpuinfo(struct seq_file *m, void *__unused) +{ + seq_printf(m, + "cpu\t\t: %s\n" + "fpu\t\t: %s\n" + "promlib\t\t: Version %d Revision %d\n" + "prom\t\t: %d.%d\n" + "type\t\t: %s\n" + "ncpus probed\t: %d\n" + "ncpus active\t: %d\n" +#ifndef CONFIG_SMP + "CPU0Bogo\t: %lu.%02lu\n" + "CPU0ClkTck\t: %ld\n" +#endif + , + sparc_cpu_type, + sparc_fpu_type , + romvec->pv_romvers, + prom_rev, + romvec->pv_printrev >> 16, + romvec->pv_printrev & 0xffff, + &cputypval[0], + ncpus_probed, + num_online_cpus() +#ifndef CONFIG_SMP + , cpu_data(0).udelay_val/(500000/HZ), + (cpu_data(0).udelay_val/(5000/HZ)) % 100, + cpu_data(0).clock_tick +#endif + ); + +#ifdef CONFIG_SMP + smp_bogo(m); +#endif + mmu_info(m); +#ifdef CONFIG_SMP + smp_info(m); +#endif + return 0; +} +#endif /* CONFIG_SPARC32 */ + +#ifdef CONFIG_SPARC64 +unsigned int dcache_parity_tl1_occurred; +unsigned int icache_parity_tl1_occurred; + + +static int show_cpuinfo(struct seq_file *m, void *__unused) +{ + seq_printf(m, + "cpu\t\t: %s\n" + "fpu\t\t: %s\n" + "pmu\t\t: %s\n" + "prom\t\t: %s\n" + "type\t\t: %s\n" + "ncpus probed\t: %d\n" + "ncpus active\t: %d\n" + "D$ parity tl1\t: %u\n" + "I$ parity tl1\t: %u\n" +#ifndef CONFIG_SMP + "Cpu0ClkTck\t: %016lx\n" +#endif + , + sparc_cpu_type, + sparc_fpu_type, + sparc_pmu_type, + prom_version, + ((tlb_type == hypervisor) ? + "sun4v" : + "sun4u"), + ncpus_probed, + num_online_cpus(), + dcache_parity_tl1_occurred, + icache_parity_tl1_occurred +#ifndef CONFIG_SMP + , cpu_data(0).clock_tick +#endif + ); +#ifdef CONFIG_SMP + smp_bogo(m); +#endif + mmu_info(m); +#ifdef CONFIG_SMP + smp_info(m); +#endif + return 0; +} +#endif /* CONFIG_SPARC64 */ + +static void *c_start(struct seq_file *m, loff_t *pos) +{ + /* The pointer we are returning is arbitrary, + * it just has to be non-NULL and not IS_ERR + * in the success case. + */ + return *pos == 0 ? &c_start : NULL; +} + +static void *c_next(struct seq_file *m, void *v, loff_t *pos) +{ + ++*pos; + return c_start(m, pos); +} + +static void c_stop(struct seq_file *m, void *v) +{ +} + +const struct seq_operations cpuinfo_op = { + .start =c_start, + .next = c_next, + .stop = c_stop, + .show = show_cpuinfo, +}; + #ifdef CONFIG_SPARC32 void __cpuinit cpu_probe(void) { diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 487d67a4e7f..6f6544cfa0e 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -6,11 +6,9 @@ #include /* cpu.c */ -extern const char *sparc_cpu_type; extern const char *sparc_pmu_type; -extern const char *sparc_fpu_type; - extern unsigned int fsr_storage; +extern int ncpus_probed; #ifdef CONFIG_SPARC32 /* cpu.c */ diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index ee8426ede7c..2cb0e1c001e 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c @@ -26,6 +26,7 @@ #include #include +#include "kernel.h" #include "kstack.h" /* Sparc64 chips have two performance counters, 32-bits each, with diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 7b8b76c9557..8f3031f6ecf 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -311,75 +311,6 @@ void __init setup_arch(char **cmdline_p) smp_setup_cpu_possible_map(); } -static int ncpus_probed; - -static int show_cpuinfo(struct seq_file *m, void *__unused) -{ - seq_printf(m, - "cpu\t\t: %s\n" - "fpu\t\t: %s\n" - "promlib\t\t: Version %d Revision %d\n" - "prom\t\t: %d.%d\n" - "type\t\t: %s\n" - "ncpus probed\t: %d\n" - "ncpus active\t: %d\n" -#ifndef CONFIG_SMP - "CPU0Bogo\t: %lu.%02lu\n" - "CPU0ClkTck\t: %ld\n" -#endif - , - sparc_cpu_type, - sparc_fpu_type , - romvec->pv_romvers, - prom_rev, - romvec->pv_printrev >> 16, - romvec->pv_printrev & 0xffff, - &cputypval[0], - ncpus_probed, - num_online_cpus() -#ifndef CONFIG_SMP - , cpu_data(0).udelay_val/(500000/HZ), - (cpu_data(0).udelay_val/(5000/HZ)) % 100, - cpu_data(0).clock_tick -#endif - ); - -#ifdef CONFIG_SMP - smp_bogo(m); -#endif - mmu_info(m); -#ifdef CONFIG_SMP - smp_info(m); -#endif - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - /* The pointer we are returning is arbitrary, - * it just has to be non-NULL and not IS_ERR - * in the success case. - */ - return *pos == 0 ? &c_start : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -const struct seq_operations cpuinfo_op = { - .start =c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; - extern int stop_a_enabled; void sun_do_break(void) diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c index 29bafe051bb..f3b6850cc8d 100644 --- a/arch/sparc/kernel/setup_64.c +++ b/arch/sparc/kernel/setup_64.c @@ -339,84 +339,6 @@ void __init setup_arch(char **cmdline_p) paging_init(); } -/* BUFFER is PAGE_SIZE bytes long. */ - -extern void smp_info(struct seq_file *); -extern void smp_bogo(struct seq_file *); -extern void mmu_info(struct seq_file *); - -unsigned int dcache_parity_tl1_occurred; -unsigned int icache_parity_tl1_occurred; - -int ncpus_probed; - -static int show_cpuinfo(struct seq_file *m, void *__unused) -{ - seq_printf(m, - "cpu\t\t: %s\n" - "fpu\t\t: %s\n" - "pmu\t\t: %s\n" - "prom\t\t: %s\n" - "type\t\t: %s\n" - "ncpus probed\t: %d\n" - "ncpus active\t: %d\n" - "D$ parity tl1\t: %u\n" - "I$ parity tl1\t: %u\n" -#ifndef CONFIG_SMP - "Cpu0ClkTck\t: %016lx\n" -#endif - , - sparc_cpu_type, - sparc_fpu_type, - sparc_pmu_type, - prom_version, - ((tlb_type == hypervisor) ? - "sun4v" : - "sun4u"), - ncpus_probed, - num_online_cpus(), - dcache_parity_tl1_occurred, - icache_parity_tl1_occurred -#ifndef CONFIG_SMP - , cpu_data(0).clock_tick -#endif - ); -#ifdef CONFIG_SMP - smp_bogo(m); -#endif - mmu_info(m); -#ifdef CONFIG_SMP - smp_info(m); -#endif - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - /* The pointer we are returning is arbitrary, - * it just has to be non-NULL and not IS_ERR - * in the success case. - */ - return *pos == 0 ? &c_start : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return c_start(m, pos); -} - -static void c_stop(struct seq_file *m, void *v) -{ -} - -const struct seq_operations cpuinfo_op = { - .start =c_start, - .next = c_next, - .stop = c_stop, - .show = show_cpuinfo, -}; - extern int stop_a_enabled; void sun_do_break(void) -- cgit v1.2.3-70-g09d2