From 2f98492c5375e906e48c78d88351f45bb11b6a8a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Oct 2010 14:44:58 +0900 Subject: sh: Expose physical addressing mode through cpuinfo. CPUs can be in either the legacy 29-bit or 32-bit physical addressing modes. This follows the x86 approach of tracking the phys bits in cpuinfo and exposing it to userspace through procfs. This change was requested to permit kexec-tools to detect the physical addressing mode in order to determine the appropriate address mangling. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/init.c | 2 ++ arch/sh/kernel/setup.c | 3 +++ 2 files changed, 5 insertions(+) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 97661061ff20..fac742e514ee 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -340,6 +340,8 @@ asmlinkage void __cpuinit cpu_init(void) */ current_cpu_data.asid_cache = NO_CONTEXT; + current_cpu_data.phys_bits = __in_29bit_mode() ? 29 : 32; + speculative_execution_init(); expmask_init(); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 4e278467f76c..82c0a0c1df0d 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -52,6 +52,7 @@ struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = { .type = CPU_SH_NONE, .family = CPU_FAMILY_UNKNOWN, .loops_per_jiffy = 10000000, + .phys_bits = MAX_PHYSMEM_BITS, }, }; EXPORT_SYMBOL(cpu_data); @@ -432,6 +433,8 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (c->flags & CPU_HAS_L2_CACHE) show_cacheinfo(m, "scache", c->scache); + seq_printf(m, "address sizes\t: %u bits physical\n", c->phys_bits); + seq_printf(m, "bogomips\t: %lu.%02lu\n", c->loops_per_jiffy/(500000/HZ), (c->loops_per_jiffy/(5000/HZ)) % 100); -- cgit v1.2.3 From c4318baf00ed24b7fdcc255de33a18ab37ee8606 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 12 Oct 2010 02:03:09 +0900 Subject: sh: Sanitize sparse irq Switch over to the new allocator functions. Signed-off-by: Thomas Gleixner Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/ipr.c | 6 +++--- drivers/sh/intc/core.c | 10 +++++----- drivers/sh/intc/dynamic.c | 23 +++++++++-------------- 3 files changed, 17 insertions(+), 22 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index 9282d965a1b6..a4a9906e12d0 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -62,13 +62,13 @@ void register_ipr_controller(struct ipr_desc *desc) for (i = 0; i < desc->nr_irqs; i++) { struct ipr_data *p = desc->ipr_data + i; - struct irq_desc *irq_desc; + int res; BUG_ON(p->ipr_idx >= desc->nr_offsets); BUG_ON(!desc->ipr_offsets[p->ipr_idx]); - irq_desc = irq_to_desc_alloc_node(p->irq, numa_node_id()); - if (unlikely(!irq_desc)) { + res = irq_alloc_desc_at(p->irq, numa_node_id()); + if (unlikely(res != p->irq && res != -EEXIST)) printk(KERN_INFO "can not get irq_desc for %d\n", p->irq); continue; diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 306ed287077a..8f3c27e9f9e2 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -300,13 +300,13 @@ int __init register_intc_controller(struct intc_desc *desc) for (i = 0; i < hw->nr_vectors; i++) { struct intc_vect *vect = hw->vectors + i; unsigned int irq = evt2irq(vect->vect); - struct irq_desc *irq_desc; + int res; if (!vect->enum_id) continue; - irq_desc = irq_to_desc_alloc_node(irq, numa_node_id()); - if (unlikely(!irq_desc)) { + res = irq_alloc_desc_at(irq, numa_node_id()); + if (res != irq && res != -EEXIST) { pr_err("can't get irq_desc for %d\n", irq); continue; } @@ -326,8 +326,8 @@ int __init register_intc_controller(struct intc_desc *desc) * IRQ support, each vector still needs to have * its own backing irq_desc. */ - irq_desc = irq_to_desc_alloc_node(irq2, numa_node_id()); - if (unlikely(!irq_desc)) { + res = irq_alloc_desc_at(irq2, numa_node_id()); + if (res != irq2 && res != -EEXIST) { pr_err("can't get irq_desc for %d\n", irq2); continue; } diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c index 6caecdffe201..e994c7ed916e 100644 --- a/drivers/sh/intc/dynamic.c +++ b/drivers/sh/intc/dynamic.c @@ -37,7 +37,6 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) { unsigned int irq = 0, new; unsigned long flags; - struct irq_desc *desc; raw_spin_lock_irqsave(&vector_lock, flags); @@ -55,24 +54,20 @@ unsigned int create_irq_nr(unsigned int irq_want, int node) __set_bit(new, intc_irq_map); } - desc = irq_to_desc_alloc_node(new, node); - if (unlikely(!desc)) { + raw_spin_unlock_irqrestore(&vector_lock, flags); + + irq = irq_alloc_desc_at(new, node); + if (unlikely(irq != new)) { pr_err("can't get irq_desc for %d\n", new); - goto out_unlock; + return 0; } - desc = move_irq_desc(desc, node); - irq = new; + activate_irq(irq); + return 0; out_unlock: raw_spin_unlock_irqrestore(&vector_lock, flags); - - if (irq > 0) { - dynamic_irq_init(irq); - activate_irq(irq); - } - - return irq; + return 0; } int create_irq(void) @@ -91,7 +86,7 @@ void destroy_irq(unsigned int irq) { unsigned long flags; - dynamic_irq_cleanup(irq); + irq_free_desc(irq); raw_spin_lock_irqsave(&vector_lock, flags); __clear_bit(irq, intc_irq_map); -- cgit v1.2.3 From 38ab13441c36c0c470b7e4e3b30ec2fb6beba253 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 26 Oct 2010 16:05:08 +0900 Subject: sh: Switch dynamic IRQ creation to generic irq allocator. Now that the genirq code provides an IRQ bitmap of its own and the necessary API to manipulate it, there's no need to keep our own version around anymore. In the process we kill off some unused IRQ reservation code, with future users now having to tie in to the genirq API as normal. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq.c | 6 ---- drivers/sh/intc/core.c | 2 +- drivers/sh/intc/dynamic.c | 82 +++++------------------------------------------ include/linux/sh_intc.h | 3 -- 4 files changed, 9 insertions(+), 84 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 9dc447db8a44..d9f3b6e7c7cb 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -273,12 +273,6 @@ void __init init_IRQ(void) { plat_irq_setup(); - /* - * Pin any of the legacy IRQ vectors that haven't already been - * grabbed by the platform - */ - reserve_irq_legacy(); - /* Perform the machine specific initialisation */ if (sh_mv.mv_init_irq) sh_mv.mv_init_irq(); diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 8f3c27e9f9e2..0801089828e7 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -78,7 +78,7 @@ static void __init intc_register_irq(struct intc_desc *desc, * Register the IRQ position with the global IRQ map, then insert * it in to the radix tree. */ - reserve_irq_vector(irq); + irq_reserve_irqs(irq, 1); raw_spin_lock_irqsave(&intc_big_lock, flags); radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c index e994c7ed916e..4187cce20ffd 100644 --- a/drivers/sh/intc/dynamic.c +++ b/drivers/sh/intc/dynamic.c @@ -17,7 +17,7 @@ #include "internals.h" /* only for activate_irq() damage.. */ /* - * The intc_irq_map provides a global map of bound IRQ vectors for a + * The IRQ bitmap provides a global map of bound IRQ vectors for a * given platform. Allocation of IRQs are either static through the CPU * vector map, or dynamic in the case of board mux vectors or MSI. * @@ -27,104 +27,38 @@ * when dynamically creating IRQs, as well as tying in to otherwise * unused irq_desc positions in the sparse array. */ -static DECLARE_BITMAP(intc_irq_map, NR_IRQS); -static DEFINE_RAW_SPINLOCK(vector_lock); /* * Dynamic IRQ allocation and deallocation */ unsigned int create_irq_nr(unsigned int irq_want, int node) { - unsigned int irq = 0, new; - unsigned long flags; - - raw_spin_lock_irqsave(&vector_lock, flags); - - /* - * First try the wanted IRQ - */ - if (test_and_set_bit(irq_want, intc_irq_map) == 0) { - new = irq_want; - } else { - /* .. then fall back to scanning. */ - new = find_first_zero_bit(intc_irq_map, nr_irqs); - if (unlikely(new == nr_irqs)) - goto out_unlock; - - __set_bit(new, intc_irq_map); - } - - raw_spin_unlock_irqrestore(&vector_lock, flags); - - irq = irq_alloc_desc_at(new, node); - if (unlikely(irq != new)) { - pr_err("can't get irq_desc for %d\n", new); + int irq = irq_alloc_desc_at(irq_want, node); + if (irq < 0) return 0; - } activate_irq(irq); - return 0; - -out_unlock: - raw_spin_unlock_irqrestore(&vector_lock, flags); - return 0; + return irq; } int create_irq(void) { - int nid = cpu_to_node(smp_processor_id()); - int irq; - - irq = create_irq_nr(NR_IRQS_LEGACY, nid); - if (irq == 0) - irq = -1; + int irq = irq_alloc_desc(numa_node_id()); + if (irq >= 0) + activate_irq(irq); return irq; } void destroy_irq(unsigned int irq) { - unsigned long flags; - irq_free_desc(irq); - - raw_spin_lock_irqsave(&vector_lock, flags); - __clear_bit(irq, intc_irq_map); - raw_spin_unlock_irqrestore(&vector_lock, flags); -} - -int reserve_irq_vector(unsigned int irq) -{ - unsigned long flags; - int ret = 0; - - raw_spin_lock_irqsave(&vector_lock, flags); - if (test_and_set_bit(irq, intc_irq_map)) - ret = -EBUSY; - raw_spin_unlock_irqrestore(&vector_lock, flags); - - return ret; } void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) { - unsigned long flags; int i; - raw_spin_lock_irqsave(&vector_lock, flags); for (i = 0; i < nr_vecs; i++) - __set_bit(evt2irq(vectors[i].vect), intc_irq_map); - raw_spin_unlock_irqrestore(&vector_lock, flags); -} - -void reserve_irq_legacy(void) -{ - unsigned long flags; - int i, j; - - raw_spin_lock_irqsave(&vector_lock, flags); - j = find_first_bit(intc_irq_map, nr_irqs); - for (i = 0; i < j; i++) - __set_bit(i, intc_irq_map); - raw_spin_unlock_irqrestore(&vector_lock, flags); + irq_reserve_irqs(evt2irq(vectors[i].vect), 1); } diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index b4f183a31f13..f656d1a43dc0 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -129,7 +129,4 @@ static inline int register_intc_userimask(unsigned long addr) } #endif -int reserve_irq_vector(unsigned int irq); -void reserve_irq_legacy(void); - #endif /* __SH_INTC_H */ -- cgit v1.2.3 From 9cc1cf380e15f7314f8defb849b8e926d5755f8b Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Oct 2010 14:24:34 +0900 Subject: sh: Fix the sparsemem disabled build. The introduction of MAX_PHYSMEM_BITS in to the initial cpuinfo struct causes a build error when sparsemem is disabled and asm/sparsemem.h is not brought in by other means. Include it explicitly. Signed-off-by: Paul Mundt --- arch/sh/kernel/setup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 82c0a0c1df0d..d6b018c7ebdc 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * Initialize loops_per_jiffy as 10000000 (1000MIPS). -- cgit v1.2.3 From 8df3a615da1a9fee6c3e0dc561e56a499072213f Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Oct 2010 14:41:39 +0900 Subject: sh: IPR IRQs irq_data conversion. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/ipr.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c index a4a9906e12d0..7516c35ee514 100644 --- a/arch/sh/kernel/cpu/irq/ipr.c +++ b/arch/sh/kernel/cpu/irq/ipr.c @@ -24,25 +24,25 @@ #include #include -static inline struct ipr_desc *get_ipr_desc(unsigned int irq) +static inline struct ipr_desc *get_ipr_desc(struct irq_data *data) { - struct irq_chip *chip = get_irq_chip(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); return container_of(chip, struct ipr_desc, chip); } -static void disable_ipr_irq(unsigned int irq) +static void disable_ipr_irq(struct irq_data *data) { - struct ipr_data *p = get_irq_chip_data(irq); - unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx]; + struct ipr_data *p = irq_data_get_irq_chip_data(data); + unsigned long addr = get_ipr_desc(data)->ipr_offsets[p->ipr_idx]; /* Set the priority in IPR to 0 */ __raw_writew(__raw_readw(addr) & (0xffff ^ (0xf << p->shift)), addr); (void)__raw_readw(addr); /* Read back to flush write posting */ } -static void enable_ipr_irq(unsigned int irq) +static void enable_ipr_irq(struct irq_data *data) { - struct ipr_data *p = get_irq_chip_data(irq); - unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx]; + struct ipr_data *p = irq_data_get_irq_chip_data(data); + unsigned long addr = get_ipr_desc(data)->ipr_offsets[p->ipr_idx]; /* Set priority in IPR back to original value */ __raw_writew(__raw_readw(addr) | (p->priority << p->shift), addr); } @@ -56,9 +56,8 @@ void register_ipr_controller(struct ipr_desc *desc) { int i; - desc->chip.mask = disable_ipr_irq; - desc->chip.unmask = enable_ipr_irq; - desc->chip.mask_ack = disable_ipr_irq; + desc->chip.irq_mask = disable_ipr_irq; + desc->chip.irq_unmask = enable_ipr_irq; for (i = 0; i < desc->nr_irqs; i++) { struct ipr_data *p = desc->ipr_data + i; @@ -68,7 +67,7 @@ void register_ipr_controller(struct ipr_desc *desc) BUG_ON(!desc->ipr_offsets[p->ipr_idx]); res = irq_alloc_desc_at(p->irq, numa_node_id()); - if (unlikely(res != p->irq && res != -EEXIST)) + if (unlikely(res != p->irq && res != -EEXIST)) { printk(KERN_INFO "can not get irq_desc for %d\n", p->irq); continue; @@ -78,7 +77,7 @@ void register_ipr_controller(struct ipr_desc *desc) set_irq_chip_and_handler_name(p->irq, &desc->chip, handle_level_irq, "level"); set_irq_chip_data(p->irq, p); - disable_ipr_irq(p->irq); + disable_ipr_irq(irq_get_irq_data(p->irq)); } } EXPORT_SYMBOL(register_ipr_controller); -- cgit v1.2.3 From 949bf16648ff657839893f88ce296a3c4d89cd1a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Oct 2010 14:54:50 +0900 Subject: sh: imask IRQs irq_data conversion. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/irq/imask.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c index a351ed84eec5..32c825c9488e 100644 --- a/arch/sh/kernel/cpu/irq/imask.c +++ b/arch/sh/kernel/cpu/irq/imask.c @@ -51,16 +51,20 @@ static inline void set_interrupt_registers(int ip) : "t"); } -static void mask_imask_irq(unsigned int irq) +static void mask_imask_irq(struct irq_data *data) { + unsigned int irq = data->irq; + clear_bit(irq, imask_mask); if (interrupt_priority < IMASK_PRIORITY - irq) interrupt_priority = IMASK_PRIORITY - irq; set_interrupt_registers(interrupt_priority); } -static void unmask_imask_irq(unsigned int irq) +static void unmask_imask_irq(struct irq_data *data) { + unsigned int irq = data->irq; + set_bit(irq, imask_mask); interrupt_priority = IMASK_PRIORITY - find_first_zero_bit(imask_mask, IMASK_PRIORITY); @@ -69,9 +73,9 @@ static void unmask_imask_irq(unsigned int irq) static struct irq_chip imask_irq_chip = { .name = "SR.IMASK", - .mask = mask_imask_irq, - .unmask = unmask_imask_irq, - .mask_ack = mask_imask_irq, + .irq_mask = mask_imask_irq, + .irq_unmask = unmask_imask_irq, + .irq_mask_ack = mask_imask_irq, }; void make_imask_irq(unsigned int irq) -- cgit v1.2.3 From 31b37c73c56b4129ff22436af97b77719a4db852 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Oct 2010 15:34:51 +0900 Subject: sh64: update for IRQ flag handling naming changes. irq_32.c was updated for the new API, while irq_64.c was overlooked. This syncs them up and gets things building again. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq_64.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/irq_64.c b/arch/sh/kernel/irq_64.c index 32365ba0e039..8fc05b997b6d 100644 --- a/arch/sh/kernel/irq_64.c +++ b/arch/sh/kernel/irq_64.c @@ -11,17 +11,17 @@ #include #include -void notrace raw_local_irq_restore(unsigned long flags) +void notrace arch_local_irq_restore(unsigned long flags) { unsigned long long __dummy; - if (flags == RAW_IRQ_DISABLED) { + if (flags == ARCH_IRQ_DISABLED) { __asm__ __volatile__ ( "getcon " __SR ", %0\n\t" "or %0, %1, %0\n\t" "putcon %0, " __SR "\n\t" : "=&r" (__dummy) - : "r" (RAW_IRQ_DISABLED) + : "r" (ARCH_IRQ_DISABLED) ); } else { __asm__ __volatile__ ( @@ -29,13 +29,13 @@ void notrace raw_local_irq_restore(unsigned long flags) "and %0, %1, %0\n\t" "putcon %0, " __SR "\n\t" : "=&r" (__dummy) - : "r" (~RAW_IRQ_DISABLED) + : "r" (~ARCH_IRQ_DISABLED) ); } } -EXPORT_SYMBOL(raw_local_irq_restore); +EXPORT_SYMBOL(arch_local_irq_restore); -unsigned long notrace __raw_local_save_flags(void) +unsigned long notrace arch_local_save_flags(void) { unsigned long flags; @@ -43,9 +43,9 @@ unsigned long notrace __raw_local_save_flags(void) "getcon " __SR ", %0\n\t" "and %0, %1, %0" : "=&r" (flags) - : "r" (RAW_IRQ_DISABLED) + : "r" (ARCH_IRQ_DISABLED) ); return flags; } -EXPORT_SYMBOL(__raw_local_save_flags); +EXPORT_SYMBOL(arch_local_save_flags); -- cgit v1.2.3 From 815db1477a2ce44d248a4ff853a2bef3616c7478 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Oct 2010 15:38:59 +0900 Subject: sh64: irq_data conversion. Signed-off-by: Paul Mundt --- arch/sh/boards/mach-cayman/irq.c | 16 +++++-------- arch/sh/kernel/cpu/irq/intc-sh5.c | 49 +++++++-------------------------------- 2 files changed, 15 insertions(+), 50 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c index 1394b078db36..d7ac5af9d102 100644 --- a/arch/sh/boards/mach-cayman/irq.c +++ b/arch/sh/boards/mach-cayman/irq.c @@ -55,8 +55,9 @@ static struct irqaction cayman_action_pci2 = { .flags = IRQF_DISABLED, }; -static void enable_cayman_irq(unsigned int irq) +static void enable_cayman_irq(struct irq_data *data) { + unsigned int irq = data->irq; unsigned long flags; unsigned long mask; unsigned int reg; @@ -72,8 +73,9 @@ static void enable_cayman_irq(unsigned int irq) local_irq_restore(flags); } -void disable_cayman_irq(unsigned int irq) +static void disable_cayman_irq(struct irq_data *data) { + unsigned int irq = data->irq; unsigned long flags; unsigned long mask; unsigned int reg; @@ -89,16 +91,10 @@ void disable_cayman_irq(unsigned int irq) local_irq_restore(flags); } -static void ack_cayman_irq(unsigned int irq) -{ - disable_cayman_irq(irq); -} - struct irq_chip cayman_irq_type = { .name = "Cayman-IRQ", - .unmask = enable_cayman_irq, - .mask = disable_cayman_irq, - .mask_ack = ack_cayman_irq, + .irq_unmask = enable_cayman_irq, + .irq_mask = disable_cayman_irq, }; int cayman_irq_demux(int evt) diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c index 96a239583948..5af48f8357e5 100644 --- a/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -76,39 +76,11 @@ int intc_evt_to_irq[(0xE20/0x20)+1] = { }; static unsigned long intc_virt; - -static unsigned int startup_intc_irq(unsigned int irq); -static void shutdown_intc_irq(unsigned int irq); -static void enable_intc_irq(unsigned int irq); -static void disable_intc_irq(unsigned int irq); -static void mask_and_ack_intc(unsigned int); -static void end_intc_irq(unsigned int irq); - -static struct irq_chip intc_irq_type = { - .name = "INTC", - .startup = startup_intc_irq, - .shutdown = shutdown_intc_irq, - .enable = enable_intc_irq, - .disable = disable_intc_irq, - .ack = mask_and_ack_intc, - .end = end_intc_irq -}; - static int irlm; /* IRL mode */ -static unsigned int startup_intc_irq(unsigned int irq) -{ - enable_intc_irq(irq); - return 0; /* never anything pending */ -} - -static void shutdown_intc_irq(unsigned int irq) -{ - disable_intc_irq(irq); -} - -static void enable_intc_irq(unsigned int irq) +static void enable_intc_irq(struct irq_data *data) { + unsigned int irq = data->irq; unsigned long reg; unsigned long bitmask; @@ -126,8 +98,9 @@ static void enable_intc_irq(unsigned int irq) __raw_writel(bitmask, reg); } -static void disable_intc_irq(unsigned int irq) +static void disable_intc_irq(struct irq_data *data) { + unsigned int irq = data->irq; unsigned long reg; unsigned long bitmask; @@ -142,15 +115,11 @@ static void disable_intc_irq(unsigned int irq) __raw_writel(bitmask, reg); } -static void mask_and_ack_intc(unsigned int irq) -{ - disable_intc_irq(irq); -} - -static void end_intc_irq(unsigned int irq) -{ - enable_intc_irq(irq); -} +static struct irq_chip intc_irq_type = { + .name = "INTC", + .irq_enable = enable_intc_irq, + .irq_disable = disable_intc_irq, +}; void __init plat_irq_setup(void) { -- cgit v1.2.3 From faadfb04d92387bd7823d81e09d9b976332f9e44 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 27 Oct 2010 15:43:01 +0900 Subject: sh: update show_interrupts() for irq_data chip lookup. Presently the irq chip is found through the irq_desc, but as this is going away convert over to an irq_data lookup instead. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index d9f3b6e7c7cb..995301afa36d 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -56,6 +56,8 @@ int show_interrupts(struct seq_file *p, void *v) int i = *(loff_t *)v, j, prec; struct irqaction *action; struct irq_desc *desc; + struct irq_data *data; + struct irq_chip *chip; if (i > nr_irqs) return 0; @@ -77,6 +79,9 @@ int show_interrupts(struct seq_file *p, void *v) if (!desc) return 0; + data = irq_get_irq_data(i); + chip = irq_data_get_irq_chip(data); + raw_spin_lock_irqsave(&desc->lock, flags); for_each_online_cpu(j) any_count |= kstat_irqs_cpu(i, j); @@ -87,7 +92,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%*d: ", prec, i); for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); - seq_printf(p, " %14s", desc->chip->name); + seq_printf(p, " %14s", chip->name); seq_printf(p, "-%-8s", desc->name); if (action) { -- cgit v1.2.3 From 2e4f17d230d84579fef07836fb5f69bf1a0a47ad Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 13 Oct 2010 03:46:25 +0900 Subject: sh: oprofile: Fix up and extend op_name_from_perf_id(). op_name_from_perf_id() currently returns a local variable, which isn't terribly productive. As we only handle a single PMU case for now, simply allocate and free the string from the arch init/exit context and have op_name_from_perf_id() hand back the cached string. This also takes UTS_MACHINE in to account, given that we build for multiple architectures. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh4/perf_event.c | 2 +- arch/sh/kernel/cpu/sh4a/perf_event.c | 2 +- arch/sh/oprofile/Makefile | 2 ++ arch/sh/oprofile/common.c | 31 +++++++++++++++++-------------- 4 files changed, 21 insertions(+), 16 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/cpu/sh4/perf_event.c b/arch/sh/kernel/cpu/sh4/perf_event.c index 7f9ecc9c2d02..dbf3b4bb71fe 100644 --- a/arch/sh/kernel/cpu/sh4/perf_event.c +++ b/arch/sh/kernel/cpu/sh4/perf_event.c @@ -225,7 +225,7 @@ static void sh7750_pmu_enable_all(void) } static struct sh_pmu sh7750_pmu = { - .name = "SH7750", + .name = "sh7750", .num_events = 2, .event_map = sh7750_event_map, .max_events = ARRAY_SIZE(sh7750_general_events), diff --git a/arch/sh/kernel/cpu/sh4a/perf_event.c b/arch/sh/kernel/cpu/sh4a/perf_event.c index b8b873d8d6b5..580276525731 100644 --- a/arch/sh/kernel/cpu/sh4a/perf_event.c +++ b/arch/sh/kernel/cpu/sh4a/perf_event.c @@ -259,7 +259,7 @@ static void sh4a_pmu_enable_all(void) } static struct sh_pmu sh4a_pmu = { - .name = "SH-4A", + .name = "sh4a", .num_events = 2, .event_map = sh4a_event_map, .max_events = ARRAY_SIZE(sh4a_general_events), diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile index e85aae73e3dc..ce3b119021e7 100644 --- a/arch/sh/oprofile/Makefile +++ b/arch/sh/oprofile/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_OPROFILE) += oprofile.o +CFLAGS_common.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' + DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprof.o cpu_buffer.o buffer_sync.o \ event_buffer.o oprofile_files.o \ diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c index e10d89376f9b..84533142da9b 100644 --- a/arch/sh/oprofile/common.c +++ b/arch/sh/oprofile/common.c @@ -1,7 +1,7 @@ /* * arch/sh/oprofile/init.c * - * Copyright (C) 2003 - 2008 Paul Mundt + * Copyright (C) 2003 - 2010 Paul Mundt * * Based on arch/mips/oprofile/common.c: * @@ -18,38 +18,41 @@ #include #include #include +#include #include #ifdef CONFIG_HW_PERF_EVENTS extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth); +/* + * This will need to be reworked when multiple PMUs are supported. + */ +static char *sh_pmu_op_name; + char *op_name_from_perf_id(void) { - const char *pmu; - char buf[20]; - int size; - - pmu = perf_pmu_name(); - if (!pmu) - return NULL; - - size = snprintf(buf, sizeof(buf), "sh/%s", pmu); - if (size > -1 && size < sizeof(buf)) - return buf; - - return NULL; + return sh_pmu_op_name; } int __init oprofile_arch_init(struct oprofile_operations *ops) { ops->backtrace = sh_backtrace; + if (perf_num_counters() == 0) + return -ENODEV; + + sh_pmu_op_name = kasprintf(GFP_KERNEL, "%s/%s", + UTS_MACHINE, perf_pmu_name()); + if (unlikely(!sh_pmu_op_name)) + return -ENOMEM; + return oprofile_perf_init(ops); } void __exit oprofile_arch_exit(void) { oprofile_perf_exit(); + kfree(sh_pmu_op_name); } #else int __init oprofile_arch_init(struct oprofile_operations *ops) -- cgit v1.2.3 From fb41a49d96cd0fb6c63362ff1c8de22e9e7399af Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Thu, 28 Oct 2010 11:33:21 +0900 Subject: sh: fix up cpu hotplug IRQ migration for irq_data changes. This fixes up the __cpu_disable() path's IRQ migration for the irq_data changes. Signed-off-by: Paul Mundt --- arch/sh/kernel/irq.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'arch/sh/kernel') diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 995301afa36d..68ecbe6c881a 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -296,13 +296,16 @@ int __init arch_probe_nr_irqs(void) #endif #ifdef CONFIG_HOTPLUG_CPU -static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) +static void route_irq(struct irq_data *data, unsigned int irq, unsigned int cpu) { + struct irq_desc *desc = irq_to_desc(irq); + struct irq_chip *chip = irq_data_get_irq_chip(data); + printk(KERN_INFO "IRQ%u: moving from cpu%u to cpu%u\n", - irq, desc->node, cpu); + irq, data->node, cpu); raw_spin_lock_irq(&desc->lock); - desc->chip->set_affinity(irq, cpumask_of(cpu)); + chip->irq_set_affinity(data, cpumask_of(cpu), false); raw_spin_unlock_irq(&desc->lock); } @@ -313,24 +316,25 @@ static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) */ void migrate_irqs(void) { - struct irq_desc *desc; unsigned int irq, cpu = smp_processor_id(); - for_each_irq_desc(irq, desc) { - if (desc->node == cpu) { - unsigned int newcpu = cpumask_any_and(desc->affinity, + for_each_active_irq(irq) { + struct irq_data *data = irq_get_irq_data(irq); + + if (data->node == cpu) { + unsigned int newcpu = cpumask_any_and(data->affinity, cpu_online_mask); if (newcpu >= nr_cpu_ids) { if (printk_ratelimit()) printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n", irq, cpu); - cpumask_setall(desc->affinity); - newcpu = cpumask_any_and(desc->affinity, + cpumask_setall(data->affinity); + newcpu = cpumask_any_and(data->affinity, cpu_online_mask); } - route_irq(desc, irq, newcpu); + route_irq(data, irq, newcpu); } } } -- cgit v1.2.3