From 5c8345bbe8e7cfd5bfa59f0e1fcef2e12a28e430 Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Tue, 18 Jan 2011 04:10:24 +0000 Subject: sparc: Replace open coded page alignment with PAGE_ALIGN macro. Signed-off-by: Kristoffer Glembo Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 41f7e4e0f72a..cea49c0756d2 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -254,7 +254,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, dma_addr_t *dma_addrp, gfp_t gfp) { struct platform_device *op = to_platform_device(dev); - unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; + unsigned long len_total = PAGE_ALIGN(len); unsigned long va; struct resource *res; int order; @@ -281,6 +281,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, goto err_nova; } mmu_inval_dma_area(va, len_total); + // XXX The mmu_map_dma_area does this for us below, see comments. // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); /* @@ -321,7 +322,7 @@ static void sbus_free_coherent(struct device *dev, size_t n, void *p, return; } - n = (n + PAGE_SIZE-1) & PAGE_MASK; + n = PAGE_ALIGN(n); if ((res->end-res->start)+1 != n) { printk("sbus_free_consistent: region 0x%lx asked 0x%zx\n", (long)((res->end-res->start)+1), n); @@ -430,7 +431,7 @@ arch_initcall(sparc_register_ioport); static void *pci32_alloc_coherent(struct device *dev, size_t len, dma_addr_t *pba, gfp_t gfp) { - unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; + unsigned long len_total = PAGE_ALIGN(len); unsigned long va; struct resource *res; int order; @@ -463,10 +464,6 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len, return NULL; } mmu_inval_dma_area(va, len_total); -#if 0 -/* P3 */ printk("pci_alloc_consistent: kva %lx uncva %lx phys %lx size %lx\n", - (long)va, (long)res->start, (long)virt_to_phys(va), len_total); -#endif sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ @@ -498,7 +495,7 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p, return; } - n = (n + PAGE_SIZE-1) & PAGE_MASK; + n = PAGE_ALIGN(n); if ((res->end-res->start)+1 != n) { printk("pci_free_consistent: region 0x%lx asked 0x%lx\n", (long)((res->end-res->start)+1), (long)n); @@ -574,7 +571,7 @@ static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl, BUG_ON(page_address(sg_page(sg)) == NULL); mmu_inval_dma_area( (unsigned long) page_address(sg_page(sg)), - (sg->length + PAGE_SIZE-1) & PAGE_MASK); + PAGE_ALIGN(sg->length)); } } } @@ -594,7 +591,7 @@ static void pci32_sync_single_for_cpu(struct device *dev, dma_addr_t ba, { if (dir != PCI_DMA_TODEVICE) { mmu_inval_dma_area((unsigned long)phys_to_virt(ba), - (size + PAGE_SIZE-1) & PAGE_MASK); + PAGE_ALIGN(size)); } } @@ -603,7 +600,7 @@ static void pci32_sync_single_for_device(struct device *dev, dma_addr_t ba, { if (dir != PCI_DMA_TODEVICE) { mmu_inval_dma_area((unsigned long)phys_to_virt(ba), - (size + PAGE_SIZE-1) & PAGE_MASK); + PAGE_ALIGN(size)); } } @@ -624,7 +621,7 @@ static void pci32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, BUG_ON(page_address(sg_page(sg)) == NULL); mmu_inval_dma_area( (unsigned long) page_address(sg_page(sg)), - (sg->length + PAGE_SIZE-1) & PAGE_MASK); + PAGE_ALIGN(sg->length)); } } } @@ -640,7 +637,7 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist * BUG_ON(page_address(sg_page(sg)) == NULL); mmu_inval_dma_area( (unsigned long) page_address(sg_page(sg)), - (sg->length + PAGE_SIZE-1) & PAGE_MASK); + PAGE_ALIGN(sg->length)); } } } @@ -717,7 +714,7 @@ static const struct file_operations sparc_io_proc_fops = { static struct resource *_sparc_find_resource(struct resource *root, unsigned long hit) { - struct resource *tmp; + struct resource *tmp; for (tmp = root->child; tmp != 0; tmp = tmp->sibling) { if (tmp->start <= hit && tmp->end >= hit) -- cgit v1.2.3 From b8682cefb861c61ced6ca2300a5ef96e91c6dbff Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Tue, 18 Jan 2011 04:10:25 +0000 Subject: sparc: Add pci32_unmap_page. Signed-off-by: Kristoffer Glembo Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index cea49c0756d2..1b9f07c07640 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -524,6 +524,13 @@ static dma_addr_t pci32_map_page(struct device *dev, struct page *page, return page_to_phys(page) + offset; } +static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size, + enum dma_data_direction dir, struct dma_attrs *attrs) +{ + if (dir != PCI_DMA_TODEVICE) + mmu_inval_dma_area((unsigned long)phys_to_virt(ba), PAGE_ALIGN(size)); +} + /* Map a set of buffers described by scatterlist in streaming * mode for DMA. This is the scather-gather version of the * above pci_map_single interface. Here the scatter gather list @@ -646,6 +653,7 @@ struct dma_map_ops pci32_dma_ops = { .alloc_coherent = pci32_alloc_coherent, .free_coherent = pci32_free_coherent, .map_page = pci32_map_page, + .unmap_page = pci32_unmap_page, .map_sg = pci32_map_sg, .unmap_sg = pci32_unmap_sg, .sync_single_for_cpu = pci32_sync_single_for_cpu, -- cgit v1.2.3 From 1830474696bb01a77a3cfff477c34e0aa087ecce Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Tue, 18 Jan 2011 04:10:26 +0000 Subject: sparc/leon: Add LEON dma_ops. This patch sets the dma_ops structure for LEON. It reuses the pci32_dma_ops. Signed-off-by: Kristoffer Glembo Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 1b9f07c07640..b81748119cf7 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -409,9 +409,6 @@ struct dma_map_ops sbus_dma_ops = { .sync_sg_for_device = sbus_sync_sg_for_device, }; -struct dma_map_ops *dma_ops = &sbus_dma_ops; -EXPORT_SYMBOL(dma_ops); - static int __init sparc_register_ioport(void) { register_proc_sparc_ioport(); @@ -423,7 +420,9 @@ arch_initcall(sparc_register_ioport); #endif /* CONFIG_SBUS */ -#ifdef CONFIG_PCI + +/* LEON reuses PCI DMA ops */ +#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON) /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices. @@ -663,7 +662,16 @@ struct dma_map_ops pci32_dma_ops = { }; EXPORT_SYMBOL(pci32_dma_ops); -#endif /* CONFIG_PCI */ +#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ + +#ifdef CONFIG_SPARC_LEON +struct dma_map_ops *dma_ops = &pci32_dma_ops; +#elif defined(CONFIG_SBUS) +struct dma_map_ops *dma_ops = &sbus_dma_ops; +#endif + +EXPORT_SYMBOL(dma_ops); + /* * Return whether the given PCI device DMA address mask can be -- cgit v1.2.3 From 1b19274083d67f66ce3097c8d2bebc22b7911e3f Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Tue, 18 Jan 2011 04:10:27 +0000 Subject: sparc/leon: Make mmu_inval_dma_area flush dcache for LEONs without snooping enabled. Signed-off-by: Kristoffer Glembo Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index b81748119cf7..815003b5fab6 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -50,10 +50,14 @@ #include #include -#ifdef CONFIG_SPARC_LEON -#define mmu_inval_dma_area(p, l) leon_flush_dcache_all() -#else +#ifndef CONFIG_SPARC_LEON #define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ +#else +static inline void mmu_inval_dma_area(unsigned long va, unsigned long len) +{ + if (!sparc_leon3_snooping_enabled()) + leon_flush_dcache_all(); +} #endif static struct resource *_sparc_find_resource(struct resource *r, -- cgit v1.2.3 From 7feee249d47f950a19ca142660ee41fe27b04b27 Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Tue, 18 Jan 2011 04:10:28 +0000 Subject: sparc: Make mmu_inval_dma_area take void * instead of unsigned long to minimize casts. Signed-off-by: Kristoffer Glembo Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 53 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 815003b5fab6..bd4fb10748b1 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -53,7 +53,7 @@ #ifndef CONFIG_SPARC_LEON #define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ #else -static inline void mmu_inval_dma_area(unsigned long va, unsigned long len) +static inline void mmu_inval_dma_area(void *va, unsigned long len) { if (!sparc_leon3_snooping_enabled()) leon_flush_dcache_all(); @@ -284,7 +284,7 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total); goto err_nova; } - mmu_inval_dma_area(va, len_total); + mmu_inval_dma_area((void *)va, len_total); // XXX The mmu_map_dma_area does this for us below, see comments. // sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); @@ -435,7 +435,7 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len, dma_addr_t *pba, gfp_t gfp) { unsigned long len_total = PAGE_ALIGN(len); - unsigned long va; + void *va; struct resource *res; int order; @@ -447,30 +447,34 @@ static void *pci32_alloc_coherent(struct device *dev, size_t len, } order = get_order(len_total); - va = __get_free_pages(GFP_KERNEL, order); - if (va == 0) { + va = (void *) __get_free_pages(GFP_KERNEL, order); + if (va == NULL) { printk("pci_alloc_consistent: no %ld pages\n", len_total>>PAGE_SHIFT); - return NULL; + goto err_nopages; } if ((res = kzalloc(sizeof(struct resource), GFP_KERNEL)) == NULL) { - free_pages(va, order); printk("pci_alloc_consistent: no core\n"); - return NULL; + goto err_nomem; } if (allocate_resource(&_sparc_dvma, res, len_total, _sparc_dvma.start, _sparc_dvma.end, PAGE_SIZE, NULL, NULL) != 0) { printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total); - free_pages(va, order); - kfree(res); - return NULL; + goto err_nova; } mmu_inval_dma_area(va, len_total); sparc_mapiorange(0, virt_to_phys(va), res->start, len_total); *pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */ return (void *) res->start; + +err_nova: + kfree(res); +err_nomem: + free_pages((unsigned long)va, order); +err_nopages: + return NULL; } /* Free and unmap a consistent DMA buffer. @@ -485,7 +489,7 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p, dma_addr_t ba) { struct resource *res; - unsigned long pgp; + void *pgp; if ((res = _sparc_find_resource(&_sparc_dvma, (unsigned long)p)) == NULL) { @@ -505,14 +509,14 @@ static void pci32_free_coherent(struct device *dev, size_t n, void *p, return; } - pgp = (unsigned long) phys_to_virt(ba); /* bus_to_virt actually */ + pgp = phys_to_virt(ba); /* bus_to_virt actually */ mmu_inval_dma_area(pgp, n); sparc_unmapiorange((unsigned long)p, n); release_resource(res); kfree(res); - free_pages(pgp, get_order(n)); + free_pages((unsigned long)pgp, get_order(n)); } /* @@ -531,7 +535,7 @@ static void pci32_unmap_page(struct device *dev, dma_addr_t ba, size_t size, enum dma_data_direction dir, struct dma_attrs *attrs) { if (dir != PCI_DMA_TODEVICE) - mmu_inval_dma_area((unsigned long)phys_to_virt(ba), PAGE_ALIGN(size)); + mmu_inval_dma_area(phys_to_virt(ba), PAGE_ALIGN(size)); } /* Map a set of buffers described by scatterlist in streaming @@ -579,9 +583,8 @@ static void pci32_unmap_sg(struct device *dev, struct scatterlist *sgl, if (dir != PCI_DMA_TODEVICE) { for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg_page(sg)) == NULL); - mmu_inval_dma_area( - (unsigned long) page_address(sg_page(sg)), - PAGE_ALIGN(sg->length)); + mmu_inval_dma_area(page_address(sg_page(sg)), + PAGE_ALIGN(sg->length)); } } } @@ -600,7 +603,7 @@ static void pci32_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, enum dma_data_direction dir) { if (dir != PCI_DMA_TODEVICE) { - mmu_inval_dma_area((unsigned long)phys_to_virt(ba), + mmu_inval_dma_area(phys_to_virt(ba), PAGE_ALIGN(size)); } } @@ -609,7 +612,7 @@ static void pci32_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, enum dma_data_direction dir) { if (dir != PCI_DMA_TODEVICE) { - mmu_inval_dma_area((unsigned long)phys_to_virt(ba), + mmu_inval_dma_area(phys_to_virt(ba), PAGE_ALIGN(size)); } } @@ -629,9 +632,8 @@ static void pci32_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl, if (dir != PCI_DMA_TODEVICE) { for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg_page(sg)) == NULL); - mmu_inval_dma_area( - (unsigned long) page_address(sg_page(sg)), - PAGE_ALIGN(sg->length)); + mmu_inval_dma_area(page_address(sg_page(sg)), + PAGE_ALIGN(sg->length)); } } } @@ -645,9 +647,8 @@ static void pci32_sync_sg_for_device(struct device *device, struct scatterlist * if (dir != PCI_DMA_TODEVICE) { for_each_sg(sgl, sg, nents, n) { BUG_ON(page_address(sg_page(sg)) == NULL); - mmu_inval_dma_area( - (unsigned long) page_address(sg_page(sg)), - PAGE_ALIGN(sg->length)); + mmu_inval_dma_area(page_address(sg_page(sg)), + PAGE_ALIGN(sg->length)); } } } -- cgit v1.2.3 From 0c7c6a3c05f1d6d7e99fff0ca4056dce3ce07484 Mon Sep 17 00:00:00 2001 From: Kristoffer Glembo Date: Tue, 18 Jan 2011 04:10:29 +0000 Subject: sparc: Fix sbus_alloc_coherent error handling. Order of kfree and free_pages were swapped in the error handling. Signed-off-by: Kristoffer Glembo Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/ioport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index bd4fb10748b1..c6ce9a6a4790 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -302,9 +302,9 @@ static void *sbus_alloc_coherent(struct device *dev, size_t len, err_noiommu: release_resource(res); err_nova: - free_pages(va, order); -err_nomem: kfree(res); +err_nomem: + free_pages(va, order); err_nopages: return NULL; } -- cgit v1.2.3 From 9f2264aca01888999d3946bd3ce1209b199c6e5d Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:14 +0000 Subject: sparc64: fix direct access to irq_desc GENERIC_HARDIRQS_NO_DEPRECATED require us to access data via irq_data. No functional changes as data has same layout due to use of union Signed-off-by: Sam Ravnborg Cc: Thomas Gleixner Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_64.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index 830d70a3e20b..ee67dae079c6 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -190,7 +190,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); #endif - seq_printf(p, " %9s", irq_desc[i].chip->name); + seq_printf(p, " %9s", irq_desc[i].irq_data.chip->name); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -284,7 +284,7 @@ static void sun4u_irq_enable(unsigned int virt_irq) unsigned int tid; cpuid = irq_choose_cpu(virt_irq, - irq_desc[virt_irq].affinity); + irq_desc[virt_irq].irq_data.affinity); imap = data->imap; tid = sun4u_compute_tid(imap, cpuid); @@ -360,7 +360,7 @@ static void sun4v_irq_enable(unsigned int virt_irq) { unsigned int ino = virt_irq_table[virt_irq].dev_ino; unsigned long cpuid = irq_choose_cpu(virt_irq, - irq_desc[virt_irq].affinity); + irq_desc[virt_irq].irq_data.affinity); int err; err = sun4v_intr_settarget(ino, cpuid); @@ -423,7 +423,7 @@ static void sun4v_virq_enable(unsigned int virt_irq) unsigned long cpuid, dev_handle, dev_ino; int err; - cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].affinity); + cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].irq_data.affinity); dev_handle = virt_irq_table[virt_irq].dev_handle; dev_ino = virt_irq_table[virt_irq].dev_ino; @@ -798,9 +798,9 @@ void fixup_irqs(void) raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); if (irq_desc[irq].action && !(irq_desc[irq].status & IRQ_PER_CPU)) { - if (irq_desc[irq].chip->set_affinity) - irq_desc[irq].chip->set_affinity(irq, - irq_desc[irq].affinity); + if (irq_desc[irq].irq_data.chip->set_affinity) + irq_desc[irq].irq_data.chip->set_affinity(irq, + irq_desc[irq].irq_data.affinity); } raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); } -- cgit v1.2.3 From d4d1ec48c4b1568338931bf8e7833543b78ec9d5 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:15 +0000 Subject: sparc: in handler_irq() rename irq parameter to pil The generic irq support uses "irq" to identify the virtual irq number. To avoid confusion rename the argument to handler_irq() to pil to match the name of the parameter in the PCR register. Signed-off-by: Sam Ravnborg Cc: Thomas Gleixner Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_32.c | 20 ++++++++++---------- arch/sparc/kernel/irq_64.c | 4 ++-- arch/sparc/kernel/sun4d_irq.c | 18 +++++++++--------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 5ad6e5c5dbb3..07c3e39c0235 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -320,7 +320,7 @@ void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) panic("bogus interrupt received"); } -void handler_irq(int irq, struct pt_regs * regs) +void handler_irq(int pil, struct pt_regs * regs) { struct pt_regs *old_regs; struct irqaction * action; @@ -331,23 +331,23 @@ void handler_irq(int irq, struct pt_regs * regs) old_regs = set_irq_regs(regs); irq_enter(); - disable_pil_irq(irq); + disable_pil_irq(pil); #ifdef CONFIG_SMP /* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */ - if((sparc_cpu_model==sun4m) && (irq < 10)) + if((sparc_cpu_model==sun4m) && (pil < 10)) smp4m_irq_rotate(cpu); #endif - action = sparc_irq[irq].action; - sparc_irq[irq].flags |= SPARC_IRQ_INPROGRESS; - kstat_cpu(cpu).irqs[irq]++; + action = sparc_irq[pil].action; + sparc_irq[pil].flags |= SPARC_IRQ_INPROGRESS; + kstat_cpu(cpu).irqs[pil]++; do { if (!action || !action->handler) - unexpected_irq(irq, NULL, regs); - action->handler(irq, action->dev_id); + unexpected_irq(pil, NULL, regs); + action->handler(pil, action->dev_id); action = action->next; } while (action); - sparc_irq[irq].flags &= ~SPARC_IRQ_INPROGRESS; - enable_pil_irq(irq); + sparc_irq[pil].flags &= ~SPARC_IRQ_INPROGRESS; + enable_pil_irq(pil); irq_exit(); set_irq_regs(old_regs); } diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index ee67dae079c6..d4d1233d4ec4 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -714,13 +714,13 @@ void ack_bad_irq(unsigned int virt_irq) void *hardirq_stack[NR_CPUS]; void *softirq_stack[NR_CPUS]; -void __irq_entry handler_irq(int irq, struct pt_regs *regs) +void __irq_entry handler_irq(int pil, struct pt_regs *regs) { unsigned long pstate, bucket_pa; struct pt_regs *old_regs; void *orig_sp; - clear_softint(1 << irq); + clear_softint(1 << pil); old_regs = set_irq_regs(regs); irq_enter(); diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index e11b4612dabb..3af649e64f0d 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -205,28 +205,28 @@ out_unlock: extern void unexpected_irq(int, void *, struct pt_regs *); -void sun4d_handler_irq(int irq, struct pt_regs * regs) +void sun4d_handler_irq(int pil, struct pt_regs * regs) { struct pt_regs *old_regs; struct irqaction * action; int cpu = smp_processor_id(); /* SBUS IRQ level (1 - 7) */ - int sbusl = pil_to_sbus[irq]; + int sbusl = pil_to_sbus[pil]; /* FIXME: Is this necessary?? */ cc_get_ipen(); - cc_set_iclr(1 << irq); + cc_set_iclr(1 << pil); old_regs = set_irq_regs(regs); irq_enter(); - kstat_cpu(cpu).irqs[irq]++; + kstat_cpu(cpu).irqs[pil]++; if (!sbusl) { - action = *(irq + irq_action); + action = *(pil + irq_action); if (!action) - unexpected_irq(irq, NULL, regs); + unexpected_irq(pil, NULL, regs); do { - action->handler(irq, action->dev_id); + action->handler(pil, action->dev_id); action = action->next; } while (action); } else { @@ -251,9 +251,9 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs) action = actionp->action; if (!action) - unexpected_irq(irq, NULL, regs); + unexpected_irq(pil, NULL, regs); do { - action->handler(irq, action->dev_id); + action->handler(pil, action->dev_id); action = action->next; } while (action); release_sbi(SBI2DEVID(sbino), slot); -- cgit v1.2.3 From cae78728003e41e9346b92f9a1cc5ca3c3e5e70e Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:16 +0000 Subject: sparc64: all pointers to irq_handler_data renamed to handler_data In preparation of moving to use irq_data.handler_data rename all pointers to irq_handler_data "handler_data". This will also prevent name clash when we introduce the new irq methods. Signed-off-by: Sam Ravnborg Cc: Thomas Gleixner Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_64.c | 78 +++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index d4d1233d4ec4..a763f9a6358e 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -277,15 +277,15 @@ static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) static void sun4u_irq_enable(unsigned int virt_irq) { - struct irq_handler_data *data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); - if (likely(data)) { + if (likely(handler_data)) { unsigned long cpuid, imap, val; unsigned int tid; cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].irq_data.affinity); - imap = data->imap; + imap = handler_data->imap; tid = sun4u_compute_tid(imap, cpuid); @@ -294,21 +294,21 @@ static void sun4u_irq_enable(unsigned int virt_irq) IMAP_AID_SAFARI | IMAP_NID_SAFARI); val |= tid | IMAP_VALID; upa_writeq(val, imap); - upa_writeq(ICLR_IDLE, data->iclr); + upa_writeq(ICLR_IDLE, handler_data->iclr); } } static int sun4u_set_affinity(unsigned int virt_irq, const struct cpumask *mask) { - struct irq_handler_data *data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); - if (likely(data)) { + if (likely(handler_data)) { unsigned long cpuid, imap, val; unsigned int tid; cpuid = irq_choose_cpu(virt_irq, mask); - imap = data->imap; + imap = handler_data->imap; tid = sun4u_compute_tid(imap, cpuid); @@ -317,7 +317,7 @@ static int sun4u_set_affinity(unsigned int virt_irq, IMAP_AID_SAFARI | IMAP_NID_SAFARI); val |= tid | IMAP_VALID; upa_writeq(val, imap); - upa_writeq(ICLR_IDLE, data->iclr); + upa_writeq(ICLR_IDLE, handler_data->iclr); } return 0; @@ -346,14 +346,14 @@ static void sun4u_irq_disable(unsigned int virt_irq) static void sun4u_irq_eoi(unsigned int virt_irq) { - struct irq_handler_data *data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); struct irq_desc *desc = irq_desc + virt_irq; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) return; - if (likely(data)) - upa_writeq(ICLR_IDLE, data->iclr); + if (likely(handler_data)) + upa_writeq(ICLR_IDLE, handler_data->iclr); } static void sun4v_irq_enable(unsigned int virt_irq) @@ -530,10 +530,10 @@ static struct irq_chip sun4v_virq = { static void pre_flow_handler(unsigned int virt_irq, struct irq_desc *desc) { - struct irq_handler_data *data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); unsigned int ino = virt_irq_table[virt_irq].dev_ino; - data->pre_handler(ino, data->arg1, data->arg2); + handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2); handle_fasteoi_irq(virt_irq, desc); } @@ -542,12 +542,12 @@ void irq_install_pre_handler(int virt_irq, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2) { - struct irq_handler_data *data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); struct irq_desc *desc = irq_desc + virt_irq; - data->pre_handler = func; - data->arg1 = arg1; - data->arg2 = arg2; + handler_data->pre_handler = func; + handler_data->arg1 = arg1; + handler_data->arg2 = arg2; desc->handle_irq = pre_flow_handler; } @@ -555,7 +555,7 @@ void irq_install_pre_handler(int virt_irq, unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; - struct irq_handler_data *data; + struct irq_handler_data *handler_data; unsigned int virt_irq; int ino; @@ -573,19 +573,19 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) "IVEC"); } - data = get_irq_chip_data(virt_irq); - if (unlikely(data)) + handler_data = get_irq_chip_data(virt_irq); + if (unlikely(handler_data)) goto out; - data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); - if (unlikely(!data)) { + handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_chip_data(virt_irq, data); + set_irq_chip_data(virt_irq, handler_data); - data->imap = imap; - data->iclr = iclr; + handler_data->imap = imap; + handler_data->iclr = iclr; out: return virt_irq; @@ -595,7 +595,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, struct irq_chip *chip) { struct ino_bucket *bucket; - struct irq_handler_data *data; + struct irq_handler_data *handler_data; unsigned int virt_irq; BUG_ON(tlb_type != hypervisor); @@ -610,23 +610,23 @@ static unsigned int sun4v_build_common(unsigned long sysino, "IVEC"); } - data = get_irq_chip_data(virt_irq); - if (unlikely(data)) + handler_data = get_irq_chip_data(virt_irq); + if (unlikely(handler_data)) goto out; - data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); - if (unlikely(!data)) { + handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_chip_data(virt_irq, data); + set_irq_chip_data(virt_irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct * register accesses. */ - data->imap = ~0UL; - data->iclr = ~0UL; + handler_data->imap = ~0UL; + handler_data->iclr = ~0UL; out: return virt_irq; @@ -641,7 +641,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) { - struct irq_handler_data *data; + struct irq_handler_data *handler_data; unsigned long hv_err, cookie; struct ino_bucket *bucket; struct irq_desc *desc; @@ -669,8 +669,8 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) handle_fasteoi_irq, "IVEC"); - data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); - if (unlikely(!data)) + handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + if (unlikely(!handler_data)) return 0; /* In order to make the LDC channel startup sequence easier, @@ -680,14 +680,14 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) desc = irq_desc + virt_irq; desc->status |= IRQ_NOAUTOEN; - set_irq_chip_data(virt_irq, data); + set_irq_chip_data(virt_irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct * register accesses. */ - data->imap = ~0UL; - data->iclr = ~0UL; + handler_data->imap = ~0UL; + handler_data->iclr = ~0UL; cookie = ~__pa(bucket); hv_err = sun4v_vintr_set_cookie(devhandle, devino, cookie); -- cgit v1.2.3 From e6ebd529e4a6ddac43bc447f39d1f8a0e4d79864 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:17 +0000 Subject: sparc64: use {get,set}_irq_data for handler_data {get,set}_irq_data uses the member "handler_data" in irq_data which fits the naem of the datatype. The change has no functional impact Signed-off-by: Sam Ravnborg Cc: Thomas Gleixner Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_64.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index a763f9a6358e..b07fc79b7d5d 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -277,7 +277,7 @@ static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) static void sun4u_irq_enable(unsigned int virt_irq) { - struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_data(virt_irq); if (likely(handler_data)) { unsigned long cpuid, imap, val; @@ -301,7 +301,7 @@ static void sun4u_irq_enable(unsigned int virt_irq) static int sun4u_set_affinity(unsigned int virt_irq, const struct cpumask *mask) { - struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_data(virt_irq); if (likely(handler_data)) { unsigned long cpuid, imap, val; @@ -346,7 +346,7 @@ static void sun4u_irq_disable(unsigned int virt_irq) static void sun4u_irq_eoi(unsigned int virt_irq) { - struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_data(virt_irq); struct irq_desc *desc = irq_desc + virt_irq; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -530,7 +530,7 @@ static struct irq_chip sun4v_virq = { static void pre_flow_handler(unsigned int virt_irq, struct irq_desc *desc) { - struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_data(virt_irq); unsigned int ino = virt_irq_table[virt_irq].dev_ino; handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2); @@ -542,7 +542,7 @@ void irq_install_pre_handler(int virt_irq, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2) { - struct irq_handler_data *handler_data = get_irq_chip_data(virt_irq); + struct irq_handler_data *handler_data = get_irq_data(virt_irq); struct irq_desc *desc = irq_desc + virt_irq; handler_data->pre_handler = func; @@ -573,7 +573,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) "IVEC"); } - handler_data = get_irq_chip_data(virt_irq); + handler_data = get_irq_data(virt_irq); if (unlikely(handler_data)) goto out; @@ -582,7 +582,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_chip_data(virt_irq, handler_data); + set_irq_data(virt_irq, handler_data); handler_data->imap = imap; handler_data->iclr = iclr; @@ -610,7 +610,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, "IVEC"); } - handler_data = get_irq_chip_data(virt_irq); + handler_data = get_irq_data(virt_irq); if (unlikely(handler_data)) goto out; @@ -619,7 +619,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_chip_data(virt_irq, handler_data); + set_irq_data(virt_irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct @@ -680,7 +680,7 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) desc = irq_desc + virt_irq; desc->status |= IRQ_NOAUTOEN; - set_irq_chip_data(virt_irq, handler_data); + set_irq_data(virt_irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct -- cgit v1.2.3 From 4832b992553ef6c714c604809d9d3f0f4d137b7e Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:18 +0000 Subject: sparc64: use up-to-data genirq functions Drop all uses of deprecated genirq features. The irq_set_affinity() call got a third paramter 'force' which is unused. For now genirq does not use this paramter and it is ignored by sparc. Signed-off-by: Sam Ravnborg Cc: Thomas Gleixner Cc: Josip Rodin Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 1 + arch/sparc/kernel/irq_64.c | 119 +++++++++++++++++++++++---------------------- 2 files changed, 61 insertions(+), 59 deletions(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 95695e97703e..13d2b6721da2 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -51,6 +51,7 @@ config SPARC64 select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select HAVE_GENERIC_HARDIRQS + select GENERIC_HARDIRQS_NO_DEPRECATED config ARCH_DEFCONFIG string diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index b07fc79b7d5d..f356e4cd7420 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -275,16 +275,15 @@ static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) real_hard_smp_processor_id() #endif -static void sun4u_irq_enable(unsigned int virt_irq) +static void sun4u_irq_enable(struct irq_data *data) { - struct irq_handler_data *handler_data = get_irq_data(virt_irq); + struct irq_handler_data *handler_data = data->handler_data; if (likely(handler_data)) { unsigned long cpuid, imap, val; unsigned int tid; - cpuid = irq_choose_cpu(virt_irq, - irq_desc[virt_irq].irq_data.affinity); + cpuid = irq_choose_cpu(data->irq, data->affinity); imap = handler_data->imap; tid = sun4u_compute_tid(imap, cpuid); @@ -298,16 +297,16 @@ static void sun4u_irq_enable(unsigned int virt_irq) } } -static int sun4u_set_affinity(unsigned int virt_irq, - const struct cpumask *mask) +static int sun4u_set_affinity(struct irq_data *data, + const struct cpumask *mask, bool force) { - struct irq_handler_data *handler_data = get_irq_data(virt_irq); + struct irq_handler_data *handler_data = data->handler_data; if (likely(handler_data)) { unsigned long cpuid, imap, val; unsigned int tid; - cpuid = irq_choose_cpu(virt_irq, mask); + cpuid = irq_choose_cpu(data->irq, mask); imap = handler_data->imap; tid = sun4u_compute_tid(imap, cpuid); @@ -340,14 +339,14 @@ static int sun4u_set_affinity(unsigned int virt_irq, * sees that, it also hooks up a default ->shutdown method which * invokes ->mask() which we do not want. See irq_chip_set_defaults(). */ -static void sun4u_irq_disable(unsigned int virt_irq) +static void sun4u_irq_disable(struct irq_data *data) { } -static void sun4u_irq_eoi(unsigned int virt_irq) +static void sun4u_irq_eoi(struct irq_data *data) { - struct irq_handler_data *handler_data = get_irq_data(virt_irq); - struct irq_desc *desc = irq_desc + virt_irq; + struct irq_handler_data *handler_data = data->handler_data; + struct irq_desc *desc = irq_desc + data->irq; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) return; @@ -356,11 +355,10 @@ static void sun4u_irq_eoi(unsigned int virt_irq) upa_writeq(ICLR_IDLE, handler_data->iclr); } -static void sun4v_irq_enable(unsigned int virt_irq) +static void sun4v_irq_enable(struct irq_data *data) { - unsigned int ino = virt_irq_table[virt_irq].dev_ino; - unsigned long cpuid = irq_choose_cpu(virt_irq, - irq_desc[virt_irq].irq_data.affinity); + unsigned int ino = virt_irq_table[data->irq].dev_ino; + unsigned long cpuid = irq_choose_cpu(data->irq, data->affinity); int err; err = sun4v_intr_settarget(ino, cpuid); @@ -377,11 +375,11 @@ static void sun4v_irq_enable(unsigned int virt_irq) ino, err); } -static int sun4v_set_affinity(unsigned int virt_irq, - const struct cpumask *mask) +static int sun4v_set_affinity(struct irq_data *data, + const struct cpumask *mask, bool force) { - unsigned int ino = virt_irq_table[virt_irq].dev_ino; - unsigned long cpuid = irq_choose_cpu(virt_irq, mask); + unsigned int ino = virt_irq_table[data->irq].dev_ino; + unsigned long cpuid = irq_choose_cpu(data->irq, mask); int err; err = sun4v_intr_settarget(ino, cpuid); @@ -392,9 +390,9 @@ static int sun4v_set_affinity(unsigned int virt_irq, return 0; } -static void sun4v_irq_disable(unsigned int virt_irq) +static void sun4v_irq_disable(struct irq_data *data) { - unsigned int ino = virt_irq_table[virt_irq].dev_ino; + unsigned int ino = virt_irq_table[data->irq].dev_ino; int err; err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); @@ -403,10 +401,10 @@ static void sun4v_irq_disable(unsigned int virt_irq) "err(%d)\n", ino, err); } -static void sun4v_irq_eoi(unsigned int virt_irq) +static void sun4v_irq_eoi(struct irq_data *data) { - unsigned int ino = virt_irq_table[virt_irq].dev_ino; - struct irq_desc *desc = irq_desc + virt_irq; + unsigned int ino = virt_irq_table[data->irq].dev_ino; + struct irq_desc *desc = irq_desc + data->irq; int err; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) @@ -418,15 +416,15 @@ static void sun4v_irq_eoi(unsigned int virt_irq) "err(%d)\n", ino, err); } -static void sun4v_virq_enable(unsigned int virt_irq) +static void sun4v_virq_enable(struct irq_data *data) { unsigned long cpuid, dev_handle, dev_ino; int err; - cpuid = irq_choose_cpu(virt_irq, irq_desc[virt_irq].irq_data.affinity); + cpuid = irq_choose_cpu(data->irq, data->affinity); - dev_handle = virt_irq_table[virt_irq].dev_handle; - dev_ino = virt_irq_table[virt_irq].dev_ino; + dev_handle = virt_irq_table[data->irq].dev_handle; + dev_ino = virt_irq_table[data->irq].dev_ino; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) @@ -447,16 +445,16 @@ static void sun4v_virq_enable(unsigned int virt_irq) dev_handle, dev_ino, err); } -static int sun4v_virt_set_affinity(unsigned int virt_irq, - const struct cpumask *mask) +static int sun4v_virt_set_affinity(struct irq_data *data, + const struct cpumask *mask, bool force) { unsigned long cpuid, dev_handle, dev_ino; int err; - cpuid = irq_choose_cpu(virt_irq, mask); + cpuid = irq_choose_cpu(data->irq, mask); - dev_handle = virt_irq_table[virt_irq].dev_handle; - dev_ino = virt_irq_table[virt_irq].dev_ino; + dev_handle = virt_irq_table[data->irq].dev_handle; + dev_ino = virt_irq_table[data->irq].dev_ino; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) @@ -467,13 +465,13 @@ static int sun4v_virt_set_affinity(unsigned int virt_irq, return 0; } -static void sun4v_virq_disable(unsigned int virt_irq) +static void sun4v_virq_disable(struct irq_data *data) { unsigned long dev_handle, dev_ino; int err; - dev_handle = virt_irq_table[virt_irq].dev_handle; - dev_ino = virt_irq_table[virt_irq].dev_ino; + dev_handle = virt_irq_table[data->irq].dev_handle; + dev_ino = virt_irq_table[data->irq].dev_ino; err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_DISABLED); @@ -483,17 +481,17 @@ static void sun4v_virq_disable(unsigned int virt_irq) dev_handle, dev_ino, err); } -static void sun4v_virq_eoi(unsigned int virt_irq) +static void sun4v_virq_eoi(struct irq_data *data) { - struct irq_desc *desc = irq_desc + virt_irq; + struct irq_desc *desc = irq_desc + data->irq; unsigned long dev_handle, dev_ino; int err; if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) return; - dev_handle = virt_irq_table[virt_irq].dev_handle; - dev_ino = virt_irq_table[virt_irq].dev_ino; + dev_handle = virt_irq_table[data->irq].dev_handle; + dev_ino = virt_irq_table[data->irq].dev_ino; err = sun4v_vintr_set_state(dev_handle, dev_ino, HV_INTR_STATE_IDLE); @@ -504,27 +502,27 @@ static void sun4v_virq_eoi(unsigned int virt_irq) } static struct irq_chip sun4u_irq = { - .name = "sun4u", - .enable = sun4u_irq_enable, - .disable = sun4u_irq_disable, - .eoi = sun4u_irq_eoi, - .set_affinity = sun4u_set_affinity, + .name = "sun4u", + .irq_enable = sun4u_irq_enable, + .irq_disable = sun4u_irq_disable, + .irq_eoi = sun4u_irq_eoi, + .irq_set_affinity = sun4u_set_affinity, }; static struct irq_chip sun4v_irq = { - .name = "sun4v", - .enable = sun4v_irq_enable, - .disable = sun4v_irq_disable, - .eoi = sun4v_irq_eoi, - .set_affinity = sun4v_set_affinity, + .name = "sun4v", + .irq_enable = sun4v_irq_enable, + .irq_disable = sun4v_irq_disable, + .irq_eoi = sun4v_irq_eoi, + .irq_set_affinity = sun4v_set_affinity, }; static struct irq_chip sun4v_virq = { - .name = "vsun4v", - .enable = sun4v_virq_enable, - .disable = sun4v_virq_disable, - .eoi = sun4v_virq_eoi, - .set_affinity = sun4v_virt_set_affinity, + .name = "vsun4v", + .irq_enable = sun4v_virq_enable, + .irq_disable = sun4v_virq_disable, + .irq_eoi = sun4v_virq_eoi, + .irq_set_affinity = sun4v_virt_set_affinity, }; static void pre_flow_handler(unsigned int virt_irq, @@ -798,9 +796,12 @@ void fixup_irqs(void) raw_spin_lock_irqsave(&irq_desc[irq].lock, flags); if (irq_desc[irq].action && !(irq_desc[irq].status & IRQ_PER_CPU)) { - if (irq_desc[irq].irq_data.chip->set_affinity) - irq_desc[irq].irq_data.chip->set_affinity(irq, - irq_desc[irq].irq_data.affinity); + struct irq_data *data = irq_get_irq_data(irq); + + if (data->chip->irq_set_affinity) + data->chip->irq_set_affinity(data, + data->affinity, + false); } raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags); } -- cgit v1.2.3 From fe41493f749797f516deb84ba07747fb7d8c04c1 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:19 +0000 Subject: sparc64: rename virt_irq => irq - I The generic irq support uses the term 'irq' for the allocated irq number. Fix it so sparc64 use the same term for an irq as the generic irq support does. For a naive reader this is less confusing. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/entry.h | 4 +- arch/sparc/kernel/irq_64.c | 153 ++++++++++++++++++++++----------------------- 2 files changed, 77 insertions(+), 80 deletions(-) diff --git a/arch/sparc/kernel/entry.h b/arch/sparc/kernel/entry.h index c011b932bb17..d1f1361c4167 100644 --- a/arch/sparc/kernel/entry.h +++ b/arch/sparc/kernel/entry.h @@ -213,8 +213,8 @@ extern struct cheetah_err_info *cheetah_error_log; struct ino_bucket { /*0x00*/unsigned long __irq_chain_pa; - /* Virtual interrupt number assigned to this INO. */ -/*0x08*/unsigned int __virt_irq; + /* Interrupt number assigned to this INO. */ +/*0x08*/unsigned int __irq; /*0x0c*/unsigned int __pad; }; diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index f356e4cd7420..eb16e3b8a2dd 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -82,7 +82,7 @@ static void bucket_clear_chain_pa(unsigned long bucket_pa) "i" (ASI_PHYS_USE_EC)); } -static unsigned int bucket_get_virt_irq(unsigned long bucket_pa) +static unsigned int bucket_get_irq(unsigned long bucket_pa) { unsigned int ret; @@ -90,21 +90,20 @@ static unsigned int bucket_get_virt_irq(unsigned long bucket_pa) : "=&r" (ret) : "r" (bucket_pa + offsetof(struct ino_bucket, - __virt_irq)), + __irq)), "i" (ASI_PHYS_USE_EC)); return ret; } -static void bucket_set_virt_irq(unsigned long bucket_pa, - unsigned int virt_irq) +static void bucket_set_irq(unsigned long bucket_pa, unsigned int irq) { __asm__ __volatile__("stwa %0, [%1] %2" : /* no outputs */ - : "r" (virt_irq), + : "r" (irq), "r" (bucket_pa + offsetof(struct ino_bucket, - __virt_irq)), + __irq)), "i" (ASI_PHYS_USE_EC)); } @@ -114,50 +113,49 @@ static struct { unsigned int dev_handle; unsigned int dev_ino; unsigned int in_use; -} virt_irq_table[NR_IRQS]; -static DEFINE_SPINLOCK(virt_irq_alloc_lock); +} irq_table[NR_IRQS]; +static DEFINE_SPINLOCK(irq_alloc_lock); -unsigned char virt_irq_alloc(unsigned int dev_handle, - unsigned int dev_ino) +unsigned char irq_alloc(unsigned int dev_handle, unsigned int dev_ino) { unsigned long flags; unsigned char ent; BUILD_BUG_ON(NR_IRQS >= 256); - spin_lock_irqsave(&virt_irq_alloc_lock, flags); + spin_lock_irqsave(&irq_alloc_lock, flags); for (ent = 1; ent < NR_IRQS; ent++) { - if (!virt_irq_table[ent].in_use) + if (!irq_table[ent].in_use) break; } if (ent >= NR_IRQS) { printk(KERN_ERR "IRQ: Out of virtual IRQs.\n"); ent = 0; } else { - virt_irq_table[ent].dev_handle = dev_handle; - virt_irq_table[ent].dev_ino = dev_ino; - virt_irq_table[ent].in_use = 1; + irq_table[ent].dev_handle = dev_handle; + irq_table[ent].dev_ino = dev_ino; + irq_table[ent].in_use = 1; } - spin_unlock_irqrestore(&virt_irq_alloc_lock, flags); + spin_unlock_irqrestore(&irq_alloc_lock, flags); return ent; } #ifdef CONFIG_PCI_MSI -void virt_irq_free(unsigned int virt_irq) +void irq_free(unsigned int irq) { unsigned long flags; - if (virt_irq >= NR_IRQS) + if (irq >= NR_IRQS) return; - spin_lock_irqsave(&virt_irq_alloc_lock, flags); + spin_lock_irqsave(&irq_alloc_lock, flags); - virt_irq_table[virt_irq].in_use = 0; + irq_table[irq].in_use = 0; - spin_unlock_irqrestore(&virt_irq_alloc_lock, flags); + spin_unlock_irqrestore(&irq_alloc_lock, flags); } #endif @@ -253,25 +251,25 @@ struct irq_handler_data { }; #ifdef CONFIG_SMP -static int irq_choose_cpu(unsigned int virt_irq, const struct cpumask *affinity) +static int irq_choose_cpu(unsigned int irq, const struct cpumask *affinity) { cpumask_t mask; int cpuid; cpumask_copy(&mask, affinity); if (cpus_equal(mask, cpu_online_map)) { - cpuid = map_to_cpu(virt_irq); + cpuid = map_to_cpu(irq); } else { cpumask_t tmp; cpus_and(tmp, cpu_online_map, mask); - cpuid = cpus_empty(tmp) ? map_to_cpu(virt_irq) : first_cpu(tmp); + cpuid = cpus_empty(tmp) ? map_to_cpu(irq) : first_cpu(tmp); } return cpuid; } #else -#define irq_choose_cpu(virt_irq, affinity) \ +#define irq_choose_cpu(irq, affinity) \ real_hard_smp_processor_id() #endif @@ -357,7 +355,7 @@ static void sun4u_irq_eoi(struct irq_data *data) static void sun4v_irq_enable(struct irq_data *data) { - unsigned int ino = virt_irq_table[data->irq].dev_ino; + unsigned int ino = irq_table[data->irq].dev_ino; unsigned long cpuid = irq_choose_cpu(data->irq, data->affinity); int err; @@ -378,7 +376,7 @@ static void sun4v_irq_enable(struct irq_data *data) static int sun4v_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - unsigned int ino = virt_irq_table[data->irq].dev_ino; + unsigned int ino = irq_table[data->irq].dev_ino; unsigned long cpuid = irq_choose_cpu(data->irq, mask); int err; @@ -392,7 +390,7 @@ static int sun4v_set_affinity(struct irq_data *data, static void sun4v_irq_disable(struct irq_data *data) { - unsigned int ino = virt_irq_table[data->irq].dev_ino; + unsigned int ino = irq_table[data->irq].dev_ino; int err; err = sun4v_intr_setenabled(ino, HV_INTR_DISABLED); @@ -403,7 +401,7 @@ static void sun4v_irq_disable(struct irq_data *data) static void sun4v_irq_eoi(struct irq_data *data) { - unsigned int ino = virt_irq_table[data->irq].dev_ino; + unsigned int ino = irq_table[data->irq].dev_ino; struct irq_desc *desc = irq_desc + data->irq; int err; @@ -423,8 +421,8 @@ static void sun4v_virq_enable(struct irq_data *data) cpuid = irq_choose_cpu(data->irq, data->affinity); - dev_handle = virt_irq_table[data->irq].dev_handle; - dev_ino = virt_irq_table[data->irq].dev_ino; + dev_handle = irq_table[data->irq].dev_handle; + dev_ino = irq_table[data->irq].dev_ino; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) @@ -453,8 +451,8 @@ static int sun4v_virt_set_affinity(struct irq_data *data, cpuid = irq_choose_cpu(data->irq, mask); - dev_handle = virt_irq_table[data->irq].dev_handle; - dev_ino = virt_irq_table[data->irq].dev_ino; + dev_handle = irq_table[data->irq].dev_handle; + dev_ino = irq_table[data->irq].dev_ino; err = sun4v_vintr_set_target(dev_handle, dev_ino, cpuid); if (err != HV_EOK) @@ -470,8 +468,8 @@ static void sun4v_virq_disable(struct irq_data *data) unsigned long dev_handle, dev_ino; int err; - dev_handle = virt_irq_table[data->irq].dev_handle; - dev_ino = virt_irq_table[data->irq].dev_ino; + dev_handle = irq_table[data->irq].dev_handle; + dev_ino = irq_table[data->irq].dev_ino; err = sun4v_vintr_set_valid(dev_handle, dev_ino, HV_INTR_DISABLED); @@ -490,8 +488,8 @@ static void sun4v_virq_eoi(struct irq_data *data) if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))) return; - dev_handle = virt_irq_table[data->irq].dev_handle; - dev_ino = virt_irq_table[data->irq].dev_ino; + dev_handle = irq_table[data->irq].dev_handle; + dev_ino = irq_table[data->irq].dev_ino; err = sun4v_vintr_set_state(dev_handle, dev_ino, HV_INTR_STATE_IDLE); @@ -525,23 +523,22 @@ static struct irq_chip sun4v_virq = { .irq_set_affinity = sun4v_virt_set_affinity, }; -static void pre_flow_handler(unsigned int virt_irq, - struct irq_desc *desc) +static void pre_flow_handler(unsigned int irq, struct irq_desc *desc) { - struct irq_handler_data *handler_data = get_irq_data(virt_irq); - unsigned int ino = virt_irq_table[virt_irq].dev_ino; + struct irq_handler_data *handler_data = get_irq_data(irq); + unsigned int ino = irq_table[irq].dev_ino; handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2); - handle_fasteoi_irq(virt_irq, desc); + handle_fasteoi_irq(irq, desc); } -void irq_install_pre_handler(int virt_irq, +void irq_install_pre_handler(int irq, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2) { - struct irq_handler_data *handler_data = get_irq_data(virt_irq); - struct irq_desc *desc = irq_desc + virt_irq; + struct irq_handler_data *handler_data = get_irq_data(irq); + struct irq_desc *desc = irq_desc + irq; handler_data->pre_handler = func; handler_data->arg1 = arg1; @@ -554,24 +551,24 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; struct irq_handler_data *handler_data; - unsigned int virt_irq; + unsigned int irq; int ino; BUG_ON(tlb_type == hypervisor); ino = (upa_readq(imap) & (IMAP_IGN | IMAP_INO)) + inofixup; bucket = &ivector_table[ino]; - virt_irq = bucket_get_virt_irq(__pa(bucket)); - if (!virt_irq) { - virt_irq = virt_irq_alloc(0, ino); - bucket_set_virt_irq(__pa(bucket), virt_irq); - set_irq_chip_and_handler_name(virt_irq, + irq = bucket_get_irq(__pa(bucket)); + if (!irq) { + irq = irq_alloc(0, ino); + bucket_set_irq(__pa(bucket), irq); + set_irq_chip_and_handler_name(irq, &sun4u_irq, handle_fasteoi_irq, "IVEC"); } - handler_data = get_irq_data(virt_irq); + handler_data = get_irq_data(irq); if (unlikely(handler_data)) goto out; @@ -580,13 +577,13 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_data(virt_irq, handler_data); + set_irq_data(irq, handler_data); handler_data->imap = imap; handler_data->iclr = iclr; out: - return virt_irq; + return irq; } static unsigned int sun4v_build_common(unsigned long sysino, @@ -594,21 +591,21 @@ static unsigned int sun4v_build_common(unsigned long sysino, { struct ino_bucket *bucket; struct irq_handler_data *handler_data; - unsigned int virt_irq; + unsigned int irq; BUG_ON(tlb_type != hypervisor); bucket = &ivector_table[sysino]; - virt_irq = bucket_get_virt_irq(__pa(bucket)); - if (!virt_irq) { - virt_irq = virt_irq_alloc(0, sysino); - bucket_set_virt_irq(__pa(bucket), virt_irq); - set_irq_chip_and_handler_name(virt_irq, chip, + irq = bucket_get_irq(__pa(bucket)); + if (!irq) { + irq = irq_alloc(0, sysino); + bucket_set_irq(__pa(bucket), irq); + set_irq_chip_and_handler_name(irq, chip, handle_fasteoi_irq, "IVEC"); } - handler_data = get_irq_data(virt_irq); + handler_data = get_irq_data(irq); if (unlikely(handler_data)) goto out; @@ -617,7 +614,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); } - set_irq_data(virt_irq, handler_data); + set_irq_data(irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct @@ -627,7 +624,7 @@ static unsigned int sun4v_build_common(unsigned long sysino, handler_data->iclr = ~0UL; out: - return virt_irq; + return irq; } unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) @@ -643,7 +640,7 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) unsigned long hv_err, cookie; struct ino_bucket *bucket; struct irq_desc *desc; - unsigned int virt_irq; + unsigned int irq; bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); if (unlikely(!bucket)) @@ -660,10 +657,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) ((unsigned long) bucket + sizeof(struct ino_bucket))); - virt_irq = virt_irq_alloc(devhandle, devino); - bucket_set_virt_irq(__pa(bucket), virt_irq); + irq = irq_alloc(devhandle, devino); + bucket_set_irq(__pa(bucket), irq); - set_irq_chip_and_handler_name(virt_irq, &sun4v_virq, + set_irq_chip_and_handler_name(irq, &sun4v_virq, handle_fasteoi_irq, "IVEC"); @@ -675,10 +672,10 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) * especially wrt. locking, we do not let request_irq() enable * the interrupt. */ - desc = irq_desc + virt_irq; + desc = irq_desc + irq; desc->status |= IRQ_NOAUTOEN; - set_irq_data(virt_irq, handler_data); + set_irq_data(irq, handler_data); /* Catch accidental accesses to these things. IMAP/ICLR handling * is done by hypervisor calls on sun4v platforms, not by direct @@ -695,18 +692,18 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) prom_halt(); } - return virt_irq; + return irq; } -void ack_bad_irq(unsigned int virt_irq) +void ack_bad_irq(unsigned int irq) { - unsigned int ino = virt_irq_table[virt_irq].dev_ino; + unsigned int ino = irq_table[irq].dev_ino; if (!ino) ino = 0xdeadbeef; - printk(KERN_CRIT "Unexpected IRQ from ino[%x] virt_irq[%u]\n", - ino, virt_irq); + printk(KERN_CRIT "Unexpected IRQ from ino[%x] irq[%u]\n", + ino, irq); } void *hardirq_stack[NR_CPUS]; @@ -739,16 +736,16 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs) while (bucket_pa) { struct irq_desc *desc; unsigned long next_pa; - unsigned int virt_irq; + unsigned int irq; next_pa = bucket_get_chain_pa(bucket_pa); - virt_irq = bucket_get_virt_irq(bucket_pa); + irq = bucket_get_irq(bucket_pa); bucket_clear_chain_pa(bucket_pa); - desc = irq_desc + virt_irq; + desc = irq_desc + irq; if (!(desc->status & IRQ_DISABLED)) - desc->handle_irq(virt_irq, desc); + desc->handle_irq(irq, desc); bucket_pa = next_pa; } -- cgit v1.2.3 From 44ed3c0c47906297924c3fde801dc160f6996f7c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 22 Jan 2011 11:32:20 +0000 Subject: sparc64: rename virt_irq => irq - II The generic irq support uses the term 'irq' for the allocated irq number. Fix it so sparc64 use the same term for an irq as the generic irq support does. For a naive reader this is less confusing. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/include/asm/irq_64.h | 18 ++++++++-------- arch/sparc/kernel/pci.c | 10 ++++----- arch/sparc/kernel/pci_fire.c | 8 +++---- arch/sparc/kernel/pci_impl.h | 4 ++-- arch/sparc/kernel/pci_msi.c | 44 +++++++++++++++++++-------------------- arch/sparc/kernel/pci_sun4v.c | 6 +++--- arch/sparc/kernel/prom_irqtrans.c | 16 +++++++------- 7 files changed, 53 insertions(+), 53 deletions(-) diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index a0b443cb3c1f..4f09666f0798 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h @@ -33,34 +33,34 @@ /* The largest number of unique interrupt sources we support. * If this needs to ever be larger than 255, you need to change - * the type of ino_bucket->virt_irq as appropriate. + * the type of ino_bucket->irq as appropriate. * - * ino_bucket->virt_irq allocation is made during {sun4v_,}build_irq(). + * ino_bucket->irq allocation is made during {sun4v_,}build_irq(). */ #define NR_IRQS 255 -extern void irq_install_pre_handler(int virt_irq, +extern void irq_install_pre_handler(int irq, void (*func)(unsigned int, void *, void *), void *arg1, void *arg2); #define irq_canonicalize(irq) (irq) extern unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap); extern unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino); extern unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino); -extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *virt_irq_p, +extern unsigned int sun4v_build_msi(u32 devhandle, unsigned int *irq_p, unsigned int msi_devino_start, unsigned int msi_devino_end); -extern void sun4v_destroy_msi(unsigned int virt_irq); -extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p, +extern void sun4v_destroy_msi(unsigned int irq); +extern unsigned int sun4u_build_msi(u32 portid, unsigned int *irq_p, unsigned int msi_devino_start, unsigned int msi_devino_end, unsigned long imap_base, unsigned long iclr_base); -extern void sun4u_destroy_msi(unsigned int virt_irq); +extern void sun4u_destroy_msi(unsigned int irq); -extern unsigned char virt_irq_alloc(unsigned int dev_handle, +extern unsigned char irq_alloc(unsigned int dev_handle, unsigned int dev_ino); #ifdef CONFIG_PCI_MSI -extern void virt_irq_free(unsigned int virt_irq); +extern void irq_free(unsigned int irq); #endif extern void __init init_IRQ(void); diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 4137579d9adc..bfede51c3afc 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -1001,22 +1001,22 @@ EXPORT_SYMBOL(pci_domain_nr); int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - unsigned int virt_irq; + unsigned int irq; if (!pbm->setup_msi_irq) return -EINVAL; - return pbm->setup_msi_irq(&virt_irq, pdev, desc); + return pbm->setup_msi_irq(&irq, pdev, desc); } -void arch_teardown_msi_irq(unsigned int virt_irq) +void arch_teardown_msi_irq(unsigned int irq) { - struct msi_desc *entry = get_irq_msi(virt_irq); + struct msi_desc *entry = get_irq_msi(irq); struct pci_dev *pdev = entry->dev; struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; if (pbm->teardown_msi_irq) - pbm->teardown_msi_irq(virt_irq, pdev); + pbm->teardown_msi_irq(irq, pdev); } #endif /* !(CONFIG_PCI_MSI) */ diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index be5e2441c6d7..43d691b67d52 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -277,7 +277,7 @@ static int pci_fire_msiq_build_irq(struct pci_pbm_info *pbm, { unsigned long cregs = (unsigned long) pbm->pbm_regs; unsigned long imap_reg, iclr_reg, int_ctrlr; - unsigned int virt_irq; + unsigned int irq; int fixup; u64 val; @@ -293,14 +293,14 @@ static int pci_fire_msiq_build_irq(struct pci_pbm_info *pbm, fixup = ((pbm->portid << 6) | devino) - int_ctrlr; - virt_irq = build_irq(fixup, iclr_reg, imap_reg); - if (!virt_irq) + irq = build_irq(fixup, iclr_reg, imap_reg); + if (!irq) return -ENOMEM; upa_writeq(EVENT_QUEUE_CONTROL_SET_EN, pbm->pbm_regs + EVENT_QUEUE_CONTROL_SET(msiqid)); - return virt_irq; + return irq; } static const struct sparc64_msiq_ops pci_fire_msiq_ops = { diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h index e20ed5f06e9c..6beb60df31d0 100644 --- a/arch/sparc/kernel/pci_impl.h +++ b/arch/sparc/kernel/pci_impl.h @@ -131,9 +131,9 @@ struct pci_pbm_info { void *msi_queues; unsigned long *msi_bitmap; unsigned int *msi_irq_table; - int (*setup_msi_irq)(unsigned int *virt_irq_p, struct pci_dev *pdev, + int (*setup_msi_irq)(unsigned int *irq_p, struct pci_dev *pdev, struct msi_desc *entry); - void (*teardown_msi_irq)(unsigned int virt_irq, struct pci_dev *pdev); + void (*teardown_msi_irq)(unsigned int irq, struct pci_dev *pdev); const struct sparc64_msiq_ops *msi_ops; #endif /* !(CONFIG_PCI_MSI) */ diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c index b210416ace7b..550e937720e7 100644 --- a/arch/sparc/kernel/pci_msi.c +++ b/arch/sparc/kernel/pci_msi.c @@ -31,12 +31,12 @@ static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie) err = ops->dequeue_msi(pbm, msiqid, &head, &msi); if (likely(err > 0)) { struct irq_desc *desc; - unsigned int virt_irq; + unsigned int irq; - virt_irq = pbm->msi_irq_table[msi - pbm->msi_first]; - desc = irq_desc + virt_irq; + irq = pbm->msi_irq_table[msi - pbm->msi_first]; + desc = irq_desc + irq; - desc->handle_irq(virt_irq, desc); + desc->handle_irq(irq, desc); } if (unlikely(err < 0)) @@ -121,7 +121,7 @@ static struct irq_chip msi_irq = { /* XXX affinity XXX */ }; -static int sparc64_setup_msi_irq(unsigned int *virt_irq_p, +static int sparc64_setup_msi_irq(unsigned int *irq_p, struct pci_dev *pdev, struct msi_desc *entry) { @@ -131,17 +131,17 @@ static int sparc64_setup_msi_irq(unsigned int *virt_irq_p, int msi, err; u32 msiqid; - *virt_irq_p = virt_irq_alloc(0, 0); + *irq_p = irq_alloc(0, 0); err = -ENOMEM; - if (!*virt_irq_p) + if (!*irq_p) goto out_err; - set_irq_chip_and_handler_name(*virt_irq_p, &msi_irq, + set_irq_chip_and_handler_name(*irq_p, &msi_irq, handle_simple_irq, "MSI"); err = alloc_msi(pbm); if (unlikely(err < 0)) - goto out_virt_irq_free; + goto out_irq_free; msi = err; @@ -152,7 +152,7 @@ static int sparc64_setup_msi_irq(unsigned int *virt_irq_p, if (err) goto out_msi_free; - pbm->msi_irq_table[msi - pbm->msi_first] = *virt_irq_p; + pbm->msi_irq_table[msi - pbm->msi_first] = *irq_p; if (entry->msi_attrib.is_64) { msg.address_hi = pbm->msi64_start >> 32; @@ -163,24 +163,24 @@ static int sparc64_setup_msi_irq(unsigned int *virt_irq_p, } msg.data = msi; - set_irq_msi(*virt_irq_p, entry); - write_msi_msg(*virt_irq_p, &msg); + set_irq_msi(*irq_p, entry); + write_msi_msg(*irq_p, &msg); return 0; out_msi_free: free_msi(pbm, msi); -out_virt_irq_free: - set_irq_chip(*virt_irq_p, NULL); - virt_irq_free(*virt_irq_p); - *virt_irq_p = 0; +out_irq_free: + set_irq_chip(*irq_p, NULL); + irq_free(*irq_p); + *irq_p = 0; out_err: return err; } -static void sparc64_teardown_msi_irq(unsigned int virt_irq, +static void sparc64_teardown_msi_irq(unsigned int irq, struct pci_dev *pdev) { struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; @@ -189,12 +189,12 @@ static void sparc64_teardown_msi_irq(unsigned int virt_irq, int i, err; for (i = 0; i < pbm->msi_num; i++) { - if (pbm->msi_irq_table[i] == virt_irq) + if (pbm->msi_irq_table[i] == irq) break; } if (i >= pbm->msi_num) { printk(KERN_ERR "%s: teardown: No MSI for irq %u\n", - pbm->name, virt_irq); + pbm->name, irq); return; } @@ -205,14 +205,14 @@ static void sparc64_teardown_msi_irq(unsigned int virt_irq, if (err) { printk(KERN_ERR "%s: teardown: ops->teardown() on MSI %u, " "irq %u, gives error %d\n", - pbm->name, msi_num, virt_irq, err); + pbm->name, msi_num, irq, err); return; } free_msi(pbm, msi_num); - set_irq_chip(virt_irq, NULL); - virt_irq_free(virt_irq); + set_irq_chip(irq, NULL); + irq_free(irq); } static int msi_bitmap_alloc(struct pci_pbm_info *pbm) diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 158cd739b263..629160772a9d 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -844,9 +844,9 @@ static int pci_sun4v_msiq_build_irq(struct pci_pbm_info *pbm, unsigned long msiqid, unsigned long devino) { - unsigned int virt_irq = sun4v_build_irq(pbm->devhandle, devino); + unsigned int irq = sun4v_build_irq(pbm->devhandle, devino); - if (!virt_irq) + if (!irq) return -ENOMEM; if (pci_sun4v_msiq_setstate(pbm->devhandle, msiqid, HV_MSIQSTATE_IDLE)) @@ -854,7 +854,7 @@ static int pci_sun4v_msiq_build_irq(struct pci_pbm_info *pbm, if (pci_sun4v_msiq_setvalid(pbm->devhandle, msiqid, HV_MSIQ_VALID)) return -EINVAL; - return virt_irq; + return irq; } static const struct sparc64_msiq_ops pci_sun4v_msiq_ops = { diff --git a/arch/sparc/kernel/prom_irqtrans.c b/arch/sparc/kernel/prom_irqtrans.c index ce651147fabc..570b98f6e897 100644 --- a/arch/sparc/kernel/prom_irqtrans.c +++ b/arch/sparc/kernel/prom_irqtrans.c @@ -227,7 +227,7 @@ static unsigned int sabre_irq_build(struct device_node *dp, unsigned long imap, iclr; unsigned long imap_off, iclr_off; int inofixup = 0; - int virt_irq; + int irq; ino &= 0x3f; if (ino < SABRE_ONBOARD_IRQ_BASE) { @@ -247,7 +247,7 @@ static unsigned int sabre_irq_build(struct device_node *dp, if ((ino & 0x20) == 0) inofixup = ino & 0x03; - virt_irq = build_irq(inofixup, iclr, imap); + irq = build_irq(inofixup, iclr, imap); /* If the parent device is a PCI<->PCI bridge other than * APB, we have to install a pre-handler to ensure that @@ -256,13 +256,13 @@ static unsigned int sabre_irq_build(struct device_node *dp, */ regs = of_get_property(dp, "reg", NULL); if (regs && sabre_device_needs_wsync(dp)) { - irq_install_pre_handler(virt_irq, + irq_install_pre_handler(irq, sabre_wsync_handler, (void *) (long) regs->phys_hi, (void *) irq_data); } - return virt_irq; + return irq; } static void __init sabre_irq_trans_init(struct device_node *dp) @@ -382,7 +382,7 @@ static unsigned int schizo_irq_build(struct device_node *dp, unsigned long pbm_regs = irq_data->pbm_regs; unsigned long imap, iclr; int ign_fixup; - int virt_irq; + int irq; int is_tomatillo; ino &= 0x3f; @@ -409,17 +409,17 @@ static unsigned int schizo_irq_build(struct device_node *dp, ign_fixup = (1 << 6); } - virt_irq = build_irq(ign_fixup, iclr, imap); + irq = build_irq(ign_fixup, iclr, imap); if (is_tomatillo) { - irq_install_pre_handler(virt_irq, + irq_install_pre_handler(irq, tomatillo_wsync_handler, ((irq_data->chip_version <= 4) ? (void *) 1 : (void *) 0), (void *) irq_data->sync_reg); } - return virt_irq; + return irq; } static void __init __schizo_irq_trans_init(struct device_node *dp, -- cgit v1.2.3 From 684151a75bf25f5aeb8a23010da91a34e17b7353 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Wed, 26 Jan 2011 06:36:35 +0000 Subject: sparc32: added U-Boot build target: uImage This is only for LEON as u-boot for SPARC only supports LEON. Signed-off-by: Daniel Hellstrom Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 33 +++++++++++++++++++++++++++++++++ arch/sparc/Makefile | 3 ++- arch/sparc/boot/Makefile | 31 +++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 13d2b6721da2..e48f471be547 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -461,6 +461,39 @@ config SPARC_LEON from www.gaisler.com. You can download a sparc-linux cross-compilation toolchain at www.gaisler.com. +if SPARC_LEON +menu "U-Boot options" + +config UBOOT_LOAD_ADDR + hex "uImage Load Address" + default 0x40004000 + ---help--- + U-Boot kernel load address, the address in physical address space + where u-boot will place the Linux kernel before booting it. + This address is normally the base address of main memory + 0x4000. + +config UBOOT_FLASH_ADDR + hex "uImage.o Load Address" + default 0x00080000 + ---help--- + Optional setting only affecting the uImage.o ELF-image used to + download the uImage file to the target using a ELF-loader other than + U-Boot. It may for example be used to download an uImage to FLASH with + the GRMON utility before even starting u-boot. + +config UBOOT_ENTRY_ADDR + hex "uImage Entry Address" + default 0xf0004000 + ---help--- + Do not change this unless you know what you're doing. This is + hardcoded by the SPARC32 and LEON port. + + This is the virtual address u-boot jumps to when booting the Linux + Kernel. + +endmenu +endif + endmenu menu "Bus options (PCI etc.)" diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 113225b241e0..ad1fb5d969f3 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -88,7 +88,7 @@ boot := arch/sparc/boot # Default target all: zImage -image zImage tftpboot.img vmlinux.aout: vmlinux +image zImage uImage tftpboot.img vmlinux.aout: vmlinux $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ archclean: @@ -102,6 +102,7 @@ ifeq ($(ARCH),sparc) define archhelp echo '* image - kernel image ($(boot)/image)' echo '* zImage - stripped kernel image ($(boot)/zImage)' + echo ' uImage - U-Boot SPARC32 Image (only for LEON)' echo ' tftpboot.img - image prepared for tftp' endef else diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index a2c5898c1ab1..9205416b1e67 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile @@ -5,6 +5,7 @@ ROOT_IMG := /usr/src/root.img ELFTOAOUT := elftoaout +MKIMAGE := $(srctree)/scripts/mkuboot.sh hostprogs-y := piggyback btfixupprep targets := tftpboot.img btfix.o btfix.S image zImage vmlinux.aout @@ -77,6 +78,36 @@ $(obj)/zImage: $(obj)/image $(obj)/vmlinux.aout: vmlinux FORCE $(call if_changed,elftoaout) @echo ' kernel: $@ is ready' +else + +# The following lines make a readable image for U-Boot. +# uImage - Binary file read by U-boot +# uImage.o - object file of uImage for loading with a +# flash programmer understanding ELF. + +OBJCOPYFLAGS_image.bin := -S -O binary -R .note -R .comment +$(obj)/image.bin: $(obj)/image FORCE + $(call if_changed,objcopy) + +$(obj)/image.gz: $(obj)/image.bin + $(call if_changed,gzip) + +quiet_cmd_uimage = UIMAGE $@ + cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A sparc -O linux -T kernel \ + -C gzip -a $(CONFIG_UBOOT_LOAD_ADDR) \ + -e $(CONFIG_UBOOT_ENTRY_ADDR) -n 'Linux-$(KERNELRELEASE)' \ + -d $< $@ + +quiet_cmd_uimage.o = UIMAGE.O $@ + cmd_uimage.o = $(LD) -Tdata $(CONFIG_UBOOT_FLASH_ADDR) \ + -r -b binary $@ -o $@.o + +targets += uImage +$(obj)/uImage: $(obj)/image.gz + $(call if_changed,uimage) + $(call if_changed,uimage.o) + @echo ' Image $@ is ready' + endif $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback System.map $(ROOT_IMG) FORCE -- cgit v1.2.3 From 7279b82cb1975ba4e337a549757f17418cfdffad Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Thu, 27 Jan 2011 01:26:58 +0000 Subject: SPARC/LEON: power down instruction different of different LEONs The way a LEON is powered down is implemented differently depending on CHIP type. The AMBA Plug&Play system ID tells revision of GRLIB and CHIP. This is for example needed by the GR-LEON4-ITX board and the UT699. Previously the power down support for LEON was limited to SMP, now both SMP and UP systems use the instruction. Signed-off-by: Daniel Hellstrom Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/include/asm/leon_amba.h | 6 +++ arch/sparc/kernel/Makefile | 1 + arch/sparc/kernel/leon_kernel.c | 9 ++++- arch/sparc/kernel/leon_pmc.c | 82 ++++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/leon_smp.c | 16 -------- 5 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 arch/sparc/kernel/leon_pmc.c diff --git a/arch/sparc/include/asm/leon_amba.h b/arch/sparc/include/asm/leon_amba.h index 263c719e96f5..e50f326e71bd 100644 --- a/arch/sparc/include/asm/leon_amba.h +++ b/arch/sparc/include/asm/leon_amba.h @@ -180,6 +180,7 @@ struct amba_ahb_device { struct device_node; void _amba_init(struct device_node *dp, struct device_node ***nextp); +extern unsigned long amba_system_id; extern struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; extern struct leon3_gptimer_regs_map *leon3_gptimer_regs; extern struct amba_apb_device leon_percpu_timer_dev[16]; @@ -254,6 +255,11 @@ extern unsigned int sparc_leon_eirq; #define GAISLER_L2C 0xffe /* internal device: leon2compat */ #define GAISLER_PLUGPLAY 0xfff /* internal device: plug & play configarea */ +/* Chip IDs */ +#define AEROFLEX_UT699 0x0699 +#define LEON4_NEXTREME1 0x0102 +#define GAISLER_GR712RC 0x0712 + #define amba_vendor(x) (((x) >> 24) & 0xff) #define amba_device(x) (((x) >> 12) & 0xfff) diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 599398fbbc7c..27e7f2542b1c 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -54,6 +54,7 @@ obj-y += of_device_$(BITS).o obj-$(CONFIG_SPARC64) += prom_irqtrans.o obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o +obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o obj-$(CONFIG_SPARC64) += reboot.o obj-$(CONFIG_SPARC64) += sysfs.o diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index fdab7f854f80..2f8a9a25d10d 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -30,6 +30,7 @@ struct amba_apb_device leon_percpu_timer_dev[16]; int leondebug_irq_disable; int leon_debug_irqout; static int dummy_master_l10_counter; +unsigned long amba_system_id; unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ @@ -117,10 +118,16 @@ void __init leon_init_timers(irq_handler_t counter_fn) master_l10_counter = (unsigned int *)&dummy_master_l10_counter; dummy_master_l10_counter = 0; - /*Find IRQMP IRQ Controller Registers base address otherwise bail out.*/ rootnp = of_find_node_by_path("/ambapp0"); if (!rootnp) goto bad; + + /* Find System ID: GRLIB build ID and optional CHIP ID */ + pp = of_find_property(rootnp, "systemid", &len); + if (pp) + amba_system_id = *(unsigned long *)pp->value; + + /* Find IRQMP IRQ Controller Registers base adr otherwise bail out */ np = of_find_node_by_name(rootnp, "GAISLER_IRQMP"); if (!np) { np = of_find_node_by_name(rootnp, "01_00d"); diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c new file mode 100644 index 000000000000..519ca923f59f --- /dev/null +++ b/arch/sparc/kernel/leon_pmc.c @@ -0,0 +1,82 @@ +/* leon_pmc.c: LEON Power-down cpu_idle() handler + * + * Copyright (C) 2011 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB + */ + +#include +#include + +#include +#include + +/* List of Systems that need fixup instructions around power-down instruction */ +unsigned int pmc_leon_fixup_ids[] = { + AEROFLEX_UT699, + GAISLER_GR712RC, + LEON4_NEXTREME1, + 0 +}; + +int pmc_leon_need_fixup(void) +{ + unsigned int systemid = amba_system_id >> 16; + unsigned int *id; + + id = &pmc_leon_fixup_ids[0]; + while (*id != 0) { + if (*id == systemid) + return 1; + id++; + } + + return 0; +} + +/* + * CPU idle callback function for systems that need some extra handling + * See .../arch/sparc/kernel/process.c + */ +void pmc_leon_idle_fixup(void) +{ + /* Prepare an address to a non-cachable region. APB is always + * none-cachable. One instruction is executed after the Sleep + * instruction, we make sure to read the bus and throw away the + * value by accessing a non-cachable area, also we make sure the + * MMU does not get a TLB miss here by using the MMU BYPASS ASI. + */ + register unsigned int address = (unsigned int)leon3_irqctrl_regs; + __asm__ __volatile__ ( + "mov %%g0, %%asr19\n" + "lda [%0] %1, %%g0\n" + : + : "r"(address), "i"(ASI_LEON_BYPASS)); +} + +/* + * CPU idle callback function + * See .../arch/sparc/kernel/process.c + */ +void pmc_leon_idle(void) +{ + /* For systems without power-down, this will be no-op */ + __asm__ __volatile__ ("mov %g0, %asr19\n\t"); +} + +/* Install LEON Power Down function */ +static int __init leon_pmc_install(void) +{ + /* Assign power management IDLE handler */ + if (pmc_leon_need_fixup()) + pm_idle = pmc_leon_idle_fixup; + else + pm_idle = pmc_leon_idle; + + printk(KERN_INFO "leon: power management initialized\n"); + + return 0; +} + +/* This driver is not critical to the boot process, don't care + * if initialized late. + */ +late_initcall(leon_pmc_install); diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index 16582d85368a..e9df87f4447f 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -437,15 +437,6 @@ void __init leon_blackbox_current(unsigned *addr) } -/* - * CPU idle callback function - * See .../arch/sparc/kernel/process.c - */ -void pmc_leon_idle(void) -{ - __asm__ volatile ("mov %g0, %asr19"); -} - void __init leon_init_smp(void) { /* Patch ipi15 trap table */ @@ -456,13 +447,6 @@ void __init leon_init_smp(void) BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id, BTFIXUPCALL_NORM); - -#ifndef PMC_NO_IDLE - /* Assign power management IDLE handler */ - pm_idle = pmc_leon_idle; - printk(KERN_INFO "leon: power management initialized\n"); -#endif - } #endif /* CONFIG_SPARC_LEON */ -- cgit v1.2.3 From 2666e476022c678b3758e753b20c22ca598dc73f Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Wed, 26 Jan 2011 06:37:05 +0000 Subject: sparc32/leon: FPU-FSR only available when FPU present Signed-off-by: Daniel Hellstrom Acked-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c index 0dc714fa23d8..7925c54f4133 100644 --- a/arch/sparc/kernel/cpu.c +++ b/arch/sparc/kernel/cpu.c @@ -324,7 +324,7 @@ void __cpuinit cpu_probe(void) psr = get_psr(); put_psr(psr | PSR_EF); #ifdef CONFIG_SPARC_LEON - fpu_vers = 7; + fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; #else fpu_vers = ((get_fsr() >> 17) & 0x7); #endif -- cgit v1.2.3 From e046b1e978f82e29da7670d6d680567e30dec69a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:17 +0000 Subject: sparc32: remove tick14.c The two methods included in tick14.c was nop because the static variable linux_lvl14 was always NULL. So remove the file and callers. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/Makefile | 1 - arch/sparc/kernel/tick14.c | 39 --------------------------------------- arch/sparc/prom/misc_32.c | 4 ---- 3 files changed, 44 deletions(-) delete mode 100644 arch/sparc/kernel/tick14.c diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 27e7f2542b1c..99aa4db6e9c2 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_SPARC32) += windows.o obj-y += cpu.o obj-$(CONFIG_SPARC32) += devices.o obj-$(CONFIG_SPARC32) += tadpole.o -obj-$(CONFIG_SPARC32) += tick14.o obj-y += ptrace_$(BITS).o obj-y += unaligned_$(BITS).o obj-y += una_asm_$(BITS).o diff --git a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c deleted file mode 100644 index 138bbf5f8724..000000000000 --- a/arch/sparc/kernel/tick14.c +++ /dev/null @@ -1,39 +0,0 @@ -/* tick14.c - * - * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk) - * - * This file handles the Sparc specific level14 ticker - * This is really useful for profiling OBP uses it for keyboard - * aborts and other stuff. - */ -#include - -extern unsigned long lvl14_save[5]; -static unsigned long *linux_lvl14 = NULL; -static unsigned long obp_lvl14[4]; - -/* - * Call with timer IRQ closed. - * First time we do it with disable_irq, later prom code uses spin_lock_irq(). - */ -void install_linux_ticker(void) -{ - - if (!linux_lvl14) - return; - linux_lvl14[0] = lvl14_save[0]; - linux_lvl14[1] = lvl14_save[1]; - linux_lvl14[2] = lvl14_save[2]; - linux_lvl14[3] = lvl14_save[3]; -} - -void install_obp_ticker(void) -{ - - if (!linux_lvl14) - return; - linux_lvl14[0] = obp_lvl14[0]; - linux_lvl14[1] = obp_lvl14[1]; - linux_lvl14[2] = obp_lvl14[2]; - linux_lvl14[3] = obp_lvl14[3]; -} diff --git a/arch/sparc/prom/misc_32.c b/arch/sparc/prom/misc_32.c index 8c278c311ba4..677b6a10fbde 100644 --- a/arch/sparc/prom/misc_32.c +++ b/arch/sparc/prom/misc_32.c @@ -54,15 +54,11 @@ EXPORT_SYMBOL(prom_feval); void prom_cmdline(void) { - extern void install_obp_ticker(void); - extern void install_linux_ticker(void); unsigned long flags; spin_lock_irqsave(&prom_lock, flags); - install_obp_ticker(); (*(romvec->pv_abort))(); restore_current(); - install_linux_ticker(); spin_unlock_irqrestore(&prom_lock, flags); set_auxio(AUXIO_LED, 0); } -- cgit v1.2.3 From b7afdb7e85d97294efa24fbfef7b1fa196ca808c Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:18 +0000 Subject: sparc32: add irq + smp declarations to headers In preparation for cleaning up a number of files add declarations for irq and smp related data/functions to the relevant headers. This showed that the extern declaration of cputypval differed in the two files where it was used. As cputypval is defined like this: cputypval: .asciz "sun4c" the correct representation is a char array. Fix users to use the new declaration. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/include/asm/mmu_32.h | 3 +++ arch/sparc/include/asm/smp_32.h | 6 ++++++ arch/sparc/kernel/irq_32.c | 6 +++--- arch/sparc/kernel/kernel.h | 47 +++++++++++++++++++++++++++++++++++++++++ arch/sparc/kernel/setup_32.c | 19 ++++++++--------- 5 files changed, 68 insertions(+), 13 deletions(-) diff --git a/arch/sparc/include/asm/mmu_32.h b/arch/sparc/include/asm/mmu_32.h index ccd36d26615a..6f056e535cf8 100644 --- a/arch/sparc/include/asm/mmu_32.h +++ b/arch/sparc/include/asm/mmu_32.h @@ -4,4 +4,7 @@ /* Default "unsigned long" context */ typedef unsigned long mm_context_t; +/* mm/srmmu.c */ +extern ctxd_t *srmmu_ctx_table_phys; + #endif diff --git a/arch/sparc/include/asm/smp_32.h b/arch/sparc/include/asm/smp_32.h index 841905c10215..d82d7f4c0a79 100644 --- a/arch/sparc/include/asm/smp_32.h +++ b/arch/sparc/include/asm/smp_32.h @@ -29,10 +29,16 @@ */ extern unsigned char boot_cpu_id; +extern volatile unsigned long cpu_callin_map[NR_CPUS]; +extern cpumask_t smp_commenced_mask; +extern struct linux_prom_registers smp_penguin_ctable; typedef void (*smpfunc_t)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); +void cpu_panic(void); +extern void smp4m_irq_rotate(int cpu); + /* * General functions that each host system must provide. */ diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 07c3e39c0235..85db35d894fc 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -130,9 +130,9 @@ EXPORT_SYMBOL(arch_local_irq_restore); static void irq_panic(void) { - extern char *cputypval; - prom_printf("machine: %s doesn't have irq handlers defined!\n",cputypval); - prom_halt(); + prom_printf("machine: %s doesn't have irq handlers defined!\n", + &cputypval[0]); + prom_halt(); } void (*sparc_init_timers)(irq_handler_t ) = diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 15d8a3f645c9..7eb736314381 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -26,6 +26,53 @@ extern int static_irq_count; extern spinlock_t irq_action_lock; extern void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs); +extern void init_IRQ(void); + +/* sun4c_irq.c */ +extern void sun4c_init_IRQ(void); + +/* sun4m_irq.c */ +extern unsigned int lvl14_resolution; + +extern void sun4m_init_IRQ(void); +extern void sun4m_clear_profile_irq(int cpu); + +/* sun4d_irq.c */ +extern spinlock_t sun4d_imsk_lock; + +extern void sun4d_init_IRQ(void); +extern int sun4d_request_irq(unsigned int irq, + irq_handler_t handler, + unsigned long irqflags, + const char *devname, void *dev_id); +extern int show_sun4d_interrupts(struct seq_file *, void *); +extern void sun4d_distribute_irqs(void); +extern void sun4d_free_irq(unsigned int irq, void *dev_id); + +/* head_32.S */ +extern unsigned int t_nmi[]; +extern unsigned int linux_trap_ipi15_sun4d[]; +extern unsigned int linux_trap_ipi15_sun4m[]; + +extern unsigned long trapbase_cpu1[]; +extern unsigned long trapbase_cpu2[]; +extern unsigned long trapbase_cpu3[]; + +extern char cputypval[]; + +/* entry.S */ +extern unsigned long lvl14_save[4]; +extern unsigned int real_irq_entry[]; +extern unsigned int smp4d_ticker[]; +extern unsigned int patchme_maybe_smp_msg[]; + +extern void floppy_hardint(void); + +/* trampoline_32.S */ +extern int __smp4m_processor_id(void); +extern int __smp4d_processor_id(void); +extern unsigned long sun4m_cpu_startup; +extern unsigned long sun4d_cpu_startup; #else /* CONFIG_SPARC32 */ #endif /* CONFIG_SPARC32 */ diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 648f2161b851..7b8b76c9557f 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -184,7 +184,6 @@ static void __init boot_flags_init(char *commands) */ extern void sun4c_probe_vac(void); -extern char cputypval; extern unsigned short root_flags; extern unsigned short root_dev; @@ -218,21 +217,21 @@ void __init setup_arch(char **cmdline_p) /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; - if (!strcmp(&cputypval,"sun4 ")) + if (!strcmp(&cputypval[0], "sun4 ")) sparc_cpu_model = sun4; - if (!strcmp(&cputypval,"sun4c")) + if (!strcmp(&cputypval[0], "sun4c")) sparc_cpu_model = sun4c; - if (!strcmp(&cputypval,"sun4m")) + if (!strcmp(&cputypval[0], "sun4m")) sparc_cpu_model = sun4m; - if (!strcmp(&cputypval,"sun4s")) + if (!strcmp(&cputypval[0], "sun4s")) sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */ - if (!strcmp(&cputypval,"sun4d")) + if (!strcmp(&cputypval[0], "sun4d")) sparc_cpu_model = sun4d; - if (!strcmp(&cputypval,"sun4e")) + if (!strcmp(&cputypval[0], "sun4e")) sparc_cpu_model = sun4e; - if (!strcmp(&cputypval,"sun4u")) + if (!strcmp(&cputypval[0], "sun4u")) sparc_cpu_model = sun4u; - if (!strncmp(&cputypval, "leon" , 4)) + if (!strncmp(&cputypval[0], "leon" , 4)) sparc_cpu_model = sparc_leon; printk("ARCH: "); @@ -335,7 +334,7 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) prom_rev, romvec->pv_printrev >> 16, romvec->pv_printrev & 0xffff, - &cputypval, + &cputypval[0], ncpus_probed, num_online_cpus() #ifndef CONFIG_SMP -- cgit v1.2.3 From e787098cfe69dad4e7cccf50352e830f539cd50a Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:19 +0000 Subject: sparc32,sun4c: irq file cleanup - drop filename in header - drop unused includes - add description of sun4c interrupts (from davem) - add spaces after reserved words This is partly based on a patch from: David Miller Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4c_irq.c | 81 +++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index 892fb884910a..f543b452ebc1 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c @@ -1,5 +1,5 @@ -/* sun4c_irq.c - * arch/sparc/kernel/sun4c_irq.c: +/* + * sun4c irq support * * djhr: Hacked out of irq.c into a CPU dependent version. * @@ -9,31 +9,41 @@ * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) */ -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include "irq.h" -#include -#include -#include -#include -#include -#include -#include #include -#include +#include #include #include -#include -#include + +#include "irq.h" + +/* Sun4c interrupts are typically laid out as follows: + * + * 1 - Software interrupt, SBUS level 1 + * 2 - SBUS level 2 + * 3 - ESP SCSI, SBUS level 3 + * 4 - Software interrupt + * 5 - Lance ethernet, SBUS level 4 + * 6 - Software interrupt + * 7 - Graphics card, SBUS level 5 + * 8 - SBUS level 6 + * 9 - SBUS level 7 + * 10 - Counter timer + * 11 - Floppy + * 12 - Zilog uart + * 13 - CS4231 audio + * 14 - Profiling timer + * 15 - NMI + * + * The interrupt enable bits in the interrupt mask register are + * really only used to enable/disable the timer interrupts, and + * for signalling software interrupts. There is also a master + * interrupt enable bit in this register. + * + * Interrupts are enabled by setting the SUN4C_INT_* bits, they + * are disabled by clearing those bits. + */ /* * Bit field defines for the interrupt registers on various @@ -49,26 +59,21 @@ #define SUN4C_INT_E4 0x04 /* Enable level 4 IRQ. */ #define SUN4C_INT_E1 0x02 /* Enable level 1 IRQ. */ -/* Pointer to the interrupt enable byte - * - * Dave Redman (djhr@tadpole.co.uk) - * What you may not be aware of is that entry.S requires this variable. - * - * --- linux_trap_nmi_sun4c -- - * - * so don't go making it static, like I tried. sigh. +/* + * Pointer to the interrupt enable byte + * Used by entry.S */ -unsigned char __iomem *interrupt_enable = NULL; +unsigned char __iomem *interrupt_enable; static void sun4c_disable_irq(unsigned int irq_nr) { unsigned long flags; unsigned char current_mask, new_mask; - + local_irq_save(flags); irq_nr &= (NR_IRQS - 1); current_mask = sbus_readb(interrupt_enable); - switch(irq_nr) { + switch (irq_nr) { case 1: new_mask = ((current_mask) & (~(SUN4C_INT_E1))); break; @@ -93,11 +98,11 @@ static void sun4c_enable_irq(unsigned int irq_nr) { unsigned long flags; unsigned char current_mask, new_mask; - + local_irq_save(flags); irq_nr &= (NR_IRQS - 1); current_mask = sbus_readb(interrupt_enable); - switch(irq_nr) { + switch (irq_nr) { case 1: new_mask = ((current_mask) | SUN4C_INT_E1); break; @@ -180,12 +185,14 @@ static void __init sun4c_init_timers(irq_handler_t counter_fn) prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err); prom_halt(); } - + sun4c_disable_irq(irq[1].pri); } #ifdef CONFIG_SMP -static void sun4c_nop(void) {} +static void sun4c_nop(void) +{ +} #endif void __init sun4c_init_IRQ(void) -- cgit v1.2.3 From aba20a8295a76310cd062be0736103ba5aee34fa Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:20 +0000 Subject: sparc32,sun4m: irq, smp files cleanup - drop filename in file header - drop unused includes - add description of sun4m interrupts (from davem) - add KERN_* to printk - fix spaces => tabs - add spaces after reserved words - drop all externs, they are now in header files This is partly based on a patch from: David Miller Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4m_irq.c | 182 +++++++++++++++++++++--------------------- arch/sparc/kernel/sun4m_smp.c | 91 +++++---------------- 2 files changed, 115 insertions(+), 158 deletions(-) diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 7f3b97ff62c1..3c6657a4caec 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -1,5 +1,5 @@ -/* sun4m_irq.c - * arch/sparc/kernel/sun4m_irq.c: +/* + * sun4m irq support * * djhr: Hacked out of irq.c into a CPU dependent version. * @@ -9,36 +9,92 @@ * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk) */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include #include -#include -#include #include #include #include -#include #include #include #include #include "irq.h" +#include "kernel.h" + +/* Sample sun4m IRQ layout: + * + * 0x22 - Power + * 0x24 - ESP SCSI + * 0x26 - Lance ethernet + * 0x2b - Floppy + * 0x2c - Zilog uart + * 0x32 - SBUS level 0 + * 0x33 - Parallel port, SBUS level 1 + * 0x35 - SBUS level 2 + * 0x37 - SBUS level 3 + * 0x39 - Audio, Graphics card, SBUS level 4 + * 0x3b - SBUS level 5 + * 0x3d - SBUS level 6 + * + * Each interrupt source has a mask bit in the interrupt registers. + * When the mask bit is set, this blocks interrupt deliver. So you + * clear the bit to enable the interrupt. + * + * Interrupts numbered less than 0x10 are software triggered interrupts + * and unused by Linux. + * + * Interrupt level assignment on sun4m: + * + * level source + * ------------------------------------------------------------ + * 1 softint-1 + * 2 softint-2, VME/SBUS level 1 + * 3 softint-3, VME/SBUS level 2 + * 4 softint-4, onboard SCSI + * 5 softint-5, VME/SBUS level 3 + * 6 softint-6, onboard ETHERNET + * 7 softint-7, VME/SBUS level 4 + * 8 softint-8, onboard VIDEO + * 9 softint-9, VME/SBUS level 5, Module Interrupt + * 10 softint-10, system counter/timer + * 11 softint-11, VME/SBUS level 6, Floppy + * 12 softint-12, Keyboard/Mouse, Serial + * 13 softint-13, VME/SBUS level 7, ISDN Audio + * 14 softint-14, per-processor counter/timer + * 15 softint-15, Asynchronous Errors (broadcast) + * + * Each interrupt source is masked distinctly in the sun4m interrupt + * registers. The PIL level alone is therefore ambiguous, since multiple + * interrupt sources map to a single PIL. + * + * This ambiguity is resolved in the 'intr' property for device nodes + * in the OF device tree. Each 'intr' property entry is composed of + * two 32-bit words. The first word is the IRQ priority value, which + * is what we're intersted in. The second word is the IRQ vector, which + * is unused. + * + * The low 4 bits of the IRQ priority indicate the PIL, and the upper + * 4 bits indicate onboard vs. SBUS leveled vs. VME leveled. 0x20 + * means onboard, 0x30 means SBUS leveled, and 0x40 means VME leveled. + * + * For example, an 'intr' IRQ priority value of 0x24 is onboard SCSI + * whereas a value of 0x33 is SBUS level 2. Here are some sample + * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and + * Tadpole S3 GX systems. + * + * esp: 0x24 onboard ESP SCSI + * le: 0x26 onboard Lance ETHERNET + * p9100: 0x32 SBUS level 1 P9100 video + * bpp: 0x33 SBUS level 2 BPP parallel port device + * DBRI: 0x39 SBUS level 5 DBRI ISDN audio + * SUNW,leo: 0x39 SBUS level 5 LEO video + * pcmcia: 0x3b SBUS level 6 PCMCIA controller + * uctrl: 0x3b SBUS level 6 UCTRL device + * modem: 0x3d SBUS level 7 MODEM + * zs: 0x2c onboard keyboard/mouse/serial + * floppy: 0x2b onboard Floppy + * power: 0x22 onboard power device (XXX unknown mask bit XXX) + */ + struct sun4m_irq_percpu { u32 pending; @@ -61,9 +117,9 @@ struct sun4m_irq_global __iomem *sun4m_irq_global; /* Dave Redman (djhr@tadpole.co.uk) * The sun4m interrupt registers. */ -#define SUN4M_INT_ENABLE 0x80000000 -#define SUN4M_INT_E14 0x00000080 -#define SUN4M_INT_E10 0x00080000 +#define SUN4M_INT_ENABLE 0x80000000 +#define SUN4M_INT_E14 0x00000080 +#define SUN4M_INT_E10 0x00080000 #define SUN4M_HARD_INT(x) (0x000000001 << (x)) #define SUN4M_SOFT_INT(x) (0x000010000 << (x)) @@ -99,59 +155,6 @@ struct sun4m_irq_global __iomem *sun4m_irq_global; #define OBP_INT_LEVEL_SBUS 0x30 #define OBP_INT_LEVEL_VME 0x40 -/* Interrupt level assignment on sun4m: - * - * level source - * ------------------------------------------------------------ - * 1 softint-1 - * 2 softint-2, VME/SBUS level 1 - * 3 softint-3, VME/SBUS level 2 - * 4 softint-4, onboard SCSI - * 5 softint-5, VME/SBUS level 3 - * 6 softint-6, onboard ETHERNET - * 7 softint-7, VME/SBUS level 4 - * 8 softint-8, onboard VIDEO - * 9 softint-9, VME/SBUS level 5, Module Interrupt - * 10 softint-10, system counter/timer - * 11 softint-11, VME/SBUS level 6, Floppy - * 12 softint-12, Keyboard/Mouse, Serial - * 13 softint-13, VME/SBUS level 7, ISDN Audio - * 14 softint-14, per-processor counter/timer - * 15 softint-15, Asynchronous Errors (broadcast) - * - * Each interrupt source is masked distinctly in the sun4m interrupt - * registers. The PIL level alone is therefore ambiguous, since multiple - * interrupt sources map to a single PIL. - * - * This ambiguity is resolved in the 'intr' property for device nodes - * in the OF device tree. Each 'intr' property entry is composed of - * two 32-bit words. The first word is the IRQ priority value, which - * is what we're intersted in. The second word is the IRQ vector, which - * is unused. - * - * The low 4 bits of the IRQ priority indicate the PIL, and the upper - * 4 bits indicate onboard vs. SBUS leveled vs. VME leveled. 0x20 - * means onboard, 0x30 means SBUS leveled, and 0x40 means VME leveled. - * - * For example, an 'intr' IRQ priority value of 0x24 is onboard SCSI - * whereas a value of 0x33 is SBUS level 2. Here are some sample - * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and - * Tadpole S3 GX systems. - * - * esp: 0x24 onboard ESP SCSI - * le: 0x26 onboard Lance ETHERNET - * p9100: 0x32 SBUS level 1 P9100 video - * bpp: 0x33 SBUS level 2 BPP parallel port device - * DBRI: 0x39 SBUS level 5 DBRI ISDN audio - * SUNW,leo: 0x39 SBUS level 5 LEO video - * pcmcia: 0x3b SBUS level 6 PCMCIA controller - * uctrl: 0x3b SBUS level 6 UCTRL device - * modem: 0x3d SBUS level 7 MODEM - * zs: 0x2c onboard keyboard/mouse/serial - * floppy: 0x2b onboard Floppy - * power: 0x22 onboard power device (XXX unknown mask bit XXX) - */ - static unsigned long irq_mask[0x50] = { /* SMP */ 0, SUN4M_SOFT_INT(1), @@ -193,7 +196,7 @@ static unsigned long irq_mask[0x50] = { static unsigned long sun4m_get_irqmask(unsigned int irq) { unsigned long mask; - + if (irq < 0x50) mask = irq_mask[irq]; else @@ -217,7 +220,7 @@ static void sun4m_disable_irq(unsigned int irq_nr) sbus_writel(mask, &sun4m_irq_global->mask_set); else sbus_writel(mask, &sun4m_irq_percpu[cpu]->set); - local_irq_restore(flags); + local_irq_restore(flags); } static void sun4m_enable_irq(unsigned int irq_nr) @@ -226,17 +229,17 @@ static void sun4m_enable_irq(unsigned int irq_nr) int cpu = smp_processor_id(); /* Dreadful floppy hack. When we use 0x2b instead of - * 0x0b the system blows (it starts to whistle!). - * So we continue to use 0x0b. Fixme ASAP. --P3 - */ - if (irq_nr != 0x0b) { + * 0x0b the system blows (it starts to whistle!). + * So we continue to use 0x0b. Fixme ASAP. --P3 + */ + if (irq_nr != 0x0b) { mask = sun4m_get_irqmask(irq_nr); local_irq_save(flags); if (irq_nr > 15) sbus_writel(mask, &sun4m_irq_global->mask_clear); else sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear); - local_irq_restore(flags); + local_irq_restore(flags); } else { local_irq_save(flags); sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear); @@ -260,7 +263,7 @@ static unsigned long cpu_pil_to_imask[16] = { /*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS, /*13*/ SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO, /*14*/ SUN4M_INT_E14, -/*15*/ SUN4M_INT_ERROR +/*15*/ SUN4M_INT_ERROR, }; /* We assume the caller has disabled local interrupts when these are called, @@ -280,12 +283,14 @@ static void sun4m_enable_pil_irq(unsigned int pil) static void sun4m_send_ipi(int cpu, int level) { unsigned long mask = sun4m_get_irqmask(level); + sbus_writel(mask, &sun4m_irq_percpu[cpu]->set); } static void sun4m_clear_ipi(int cpu, int level) { unsigned long mask = sun4m_get_irqmask(level); + sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear); } @@ -314,7 +319,7 @@ struct sun4m_timer_global { static struct sun4m_timer_global __iomem *timers_global; -#define TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10) +#define TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10) unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); @@ -407,7 +412,6 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn) #ifdef CONFIG_SMP { unsigned long flags; - extern unsigned long lvl14_save[4]; struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; /* For SMP we use the level 14 ticker, however the bootup code diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 762d6eedd944..5cc7dc51de3d 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c @@ -1,59 +1,22 @@ -/* sun4m_smp.c: Sparc SUN4M SMP support. +/* + * sun4m SMP support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ -#include - -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include #include #include #include #include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include #include "irq.h" +#include "kernel.h" #define IRQ_CROSS_CALL 15 -extern ctxd_t *srmmu_ctx_table_phys; - -extern volatile unsigned long cpu_callin_map[NR_CPUS]; -extern unsigned char boot_cpu_id; - -extern cpumask_t smp_commenced_mask; - -extern int __smp4m_processor_id(void); - -/*#define SMP_DEBUG*/ - -#ifdef SMP_DEBUG -#define SMP_PRINTK(x) printk x -#else -#define SMP_PRINTK(x) -#endif - static inline unsigned long swap_ulong(volatile unsigned long *ptr, unsigned long val) { @@ -64,7 +27,6 @@ swap_ulong(volatile unsigned long *ptr, unsigned long val) } static void smp_setup_percpu_timer(void); -extern void cpu_probe(void); void __cpuinit smp4m_callin(void) { @@ -96,7 +58,7 @@ void __cpuinit smp4m_callin(void) /* XXX: What's up with all the flushes? */ local_flush_cache_all(); local_flush_tlb_all(); - + cpu_probe(); /* Fix idle thread fields. */ @@ -119,9 +81,6 @@ void __cpuinit smp4m_callin(void) /* * Cycle through the processors asking the PROM to start each one. */ - -extern struct linux_prom_registers smp_penguin_ctable; - void __init smp4m_boot_cpus(void) { smp_setup_percpu_timer(); @@ -130,7 +89,6 @@ void __init smp4m_boot_cpus(void) int __cpuinit smp4m_boot_one_cpu(int i) { - extern unsigned long sun4m_cpu_startup; unsigned long *entry = &sun4m_cpu_startup; struct task_struct *p; int timeout; @@ -142,7 +100,7 @@ int __cpuinit smp4m_boot_one_cpu(int i) p = fork_idle(i); current_set[i] = task_thread_info(p); /* See trampoline.S for details... */ - entry += ((i-1) * 3); + entry += ((i - 1) * 3); /* * Initialize the contexts table @@ -154,20 +112,19 @@ int __cpuinit smp4m_boot_one_cpu(int i) smp_penguin_ctable.reg_size = 0; /* whirrr, whirrr, whirrrrrrrrr... */ - printk("Starting CPU %d at %p\n", i, entry); + printk(KERN_INFO "Starting CPU %d at %p\n", i, entry); local_flush_cache_all(); - prom_startcpu(cpu_node, - &smp_penguin_ctable, 0, (char *)entry); + prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); /* wheee... it's going... */ - for(timeout = 0; timeout < 10000; timeout++) { - if(cpu_callin_map[i]) + for (timeout = 0; timeout < 10000; timeout++) { + if (cpu_callin_map[i]) break; udelay(200); } if (!(cpu_callin_map[i])) { - printk("Processor %d is stuck.\n", i); + printk(KERN_ERR "Processor %d is stuck.\n", i); return -ENODEV; } @@ -202,6 +159,7 @@ void __init smp4m_smp_done(void) void smp4m_irq_rotate(int cpu) { int next = cpu_data(cpu).next; + if (next != cpu) set_irq_udt(next); } @@ -243,7 +201,7 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, cpu_clear(smp_processor_id(), mask); cpus_and(mask, cpu_online_map, mask); - for(i = 0; i < ncpus; i++) { + for (i = 0; i < ncpus; i++) { if (cpu_isset(i, mask)) { ccall_info.processors_in[i] = 0; ccall_info.processors_out[i] = 0; @@ -262,19 +220,18 @@ static void smp4m_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, do { if (!cpu_isset(i, mask)) continue; - while(!ccall_info.processors_in[i]) + while (!ccall_info.processors_in[i]) barrier(); - } while(++i < ncpus); + } while (++i < ncpus); i = 0; do { if (!cpu_isset(i, mask)) continue; - while(!ccall_info.processors_out[i]) + while (!ccall_info.processors_out[i]) barrier(); - } while(++i < ncpus); + } while (++i < ncpus); } - spin_unlock_irqrestore(&cross_call_lock, flags); } @@ -289,8 +246,6 @@ void smp4m_cross_call_irq(void) ccall_info.processors_out[i] = 1; } -extern void sun4m_clear_profile_irq(int cpu); - void smp4m_percpu_timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs; @@ -302,7 +257,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) profile_tick(CPU_PROFILING); - if(!--prof_counter(cpu)) { + if (!--prof_counter(cpu)) { int user = user_mode(regs); irq_enter(); @@ -314,8 +269,6 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs) set_irq_regs(old_regs); } -extern unsigned int lvl14_resolution; - static void __cpuinit smp_setup_percpu_timer(void) { int cpu = smp_processor_id(); @@ -323,7 +276,7 @@ static void __cpuinit smp_setup_percpu_timer(void) prof_counter(cpu) = prof_multiplier(cpu) = 1; load_profile_irq(cpu, lvl14_resolution); - if(cpu == boot_cpu_id) + if (cpu == boot_cpu_id) enable_pil_irq(14); } @@ -331,9 +284,9 @@ static void __init smp4m_blackbox_id(unsigned *addr) { int rd = *addr & 0x3e000000; int rs1 = rd >> 11; - + addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ - addr[1] = 0x8130200c | rd | rs1; /* srl reg, 0xc, reg */ + addr[1] = 0x8130200c | rd | rs1; /* srl reg, 0xc, reg */ addr[2] = 0x80082003 | rd | rs1; /* and reg, 3, reg */ } @@ -341,9 +294,9 @@ static void __init smp4m_blackbox_current(unsigned *addr) { int rd = *addr & 0x3e000000; int rs1 = rd >> 11; - + addr[0] = 0x81580000 | rd; /* rd %tbr, reg */ - addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */ + addr[2] = 0x8130200a | rd | rs1; /* srl reg, 0xa, reg */ addr[4] = 0x8008200c | rd | rs1; /* and reg, 0xc, reg */ } -- cgit v1.2.3 From e54f8548ff5285f57125c08d8092eec38dd05e0d Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:21 +0000 Subject: sparc32,sun4d: irq, smp files cleanup - drop filename in file header - drop unused includes - add description of sun4d interrupts (from davem) - add KERN_* to printk - fix spaces => tabs - add spaces after reserved words - fix indent of a whole code block in smp4d_boot_one_cpu() Note: two printk() was updated from debug to KERN_INFO in this code block - drop all externs, they are now in header files This is partly based on a patch from: David Miller Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4d_irq.c | 195 +++++++++++++++++++++++------------------- arch/sparc/kernel/sun4d_smp.c | 176 ++++++++++++++------------------------ 2 files changed, 174 insertions(+), 197 deletions(-) diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 3af649e64f0d..5fc4c220158c 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -1,49 +1,48 @@ /* - * arch/sparc/kernel/sun4d_irq.c: - * SS1000/SC2000 interrupt handling. + * SS1000/SC2000 interrupt handling. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Heavily based on arch/sparc/kernel/irq.c. */ -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include - -#include -#include -#include -#include -#include -#include + #include -#include -#include #include #include #include -#include -#include #include #include -#include #include "kernel.h" #include "irq.h" -/* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ +/* Sun4d interrupts fall roughly into two categories. SBUS and + * cpu local. CPU local interrupts cover the timer interrupts + * and whatnot, and we encode those as normal PILs between + * 0 and 15. + * + * SBUS interrupts are encoded integers including the board number + * (plus one), the SBUS level, and the SBUS slot number. Sun4D + * IRQ dispatch is done by: + * + * 1) Reading the BW local interrupt table in order to get the bus + * interrupt mask. + * + * This table is indexed by SBUS interrupt level which can be + * derived from the PIL we got interrupted on. + * + * 2) For each bus showing interrupt pending from #1, read the + * SBI interrupt state register. This will indicate which slots + * have interrupts pending for that SBUS interrupt level. + */ + +/* + * If you trust current SCSI layer to handle different + * SCSI IRQs, enable this. + * I don't trust it... -jj + */ /* #define DISTRIBUTE_IRQS */ struct sun4d_timer_regs { @@ -59,11 +58,9 @@ static struct sun4d_timer_regs __iomem *sun4d_timers; #define TIMER_IRQ 10 #define MAX_STATIC_ALLOC 4 -extern int static_irq_count; static unsigned char sbus_tid[32]; static struct irqaction *irq_action[NR_IRQS]; -extern spinlock_t irq_action_lock; static struct sbus_action { struct irqaction *action; @@ -71,11 +68,33 @@ static struct sbus_action { } *sbus_actions; static int pil_to_sbus[] = { - 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, + 0, + 0, + 1, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 0, }; static int sbus_to_pil[] = { - 0, 2, 3, 5, 7, 9, 11, 13, + 0, + 2, + 3, + 5, + 7, + 9, + 11, + 13, }; static int nsbi; @@ -86,7 +105,7 @@ DEFINE_SPINLOCK(sun4d_imsk_lock); int show_sun4d_interrupts(struct seq_file *p, void *v) { int i = *(loff_t *) v, j = 0, k = 0, sbusl; - struct irqaction * action; + struct irqaction *action; unsigned long flags; #ifdef CONFIG_SMP int x; @@ -96,13 +115,14 @@ int show_sun4d_interrupts(struct seq_file *p, void *v) if (i < NR_IRQS) { sbusl = pil_to_sbus[i]; if (!sbusl) { - action = *(i + irq_action); - if (!action) - goto out_unlock; + action = *(i + irq_action); + if (!action) + goto out_unlock; } else { for (j = 0; j < nsbi; j++) { for (k = 0; k < 4; k++) - if ((action = sbus_actions [(j << 5) + (sbusl << 2) + k].action)) + action = sbus_actions[(j << 5) + (sbusl << 2) + k].action; + if (action) goto found_it; } goto out_unlock; @@ -125,15 +145,17 @@ found_it: seq_printf(p, "%3d: ", i); (action->flags & IRQF_DISABLED) ? " +" : "", action->name); } - if (!sbusl) break; + if (!sbusl) + break; k++; - if (k < 4) - action = sbus_actions [(j << 5) + (sbusl << 2) + k].action; - else { + if (k < 4) { + action = sbus_actions[(j << 5) + (sbusl << 2) + k].action; + } else { j++; - if (j == nsbi) break; + if (j == nsbi) + break; k = 0; - action = sbus_actions [(j << 5) + (sbusl << 2)].action; + action = sbus_actions[(j << 5) + (sbusl << 2)].action; } } seq_putc(p, '\n'); @@ -147,7 +169,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) { struct irqaction *action, **actionp; struct irqaction *tmp = NULL; - unsigned long flags; + unsigned long flags; spin_lock_irqsave(&irq_action_lock, flags); if (irq < 15) @@ -156,7 +178,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) actionp = &(sbus_actions[irq - (1 << 5)].action); action = *actionp; if (!action) { - printk("Trying to free free IRQ%d\n",irq); + printk(KERN_ERR "Trying to free free IRQ%d\n", irq); goto out_unlock; } if (dev_id) { @@ -166,23 +188,25 @@ void sun4d_free_irq(unsigned int irq, void *dev_id) tmp = action; } if (!action) { - printk("Trying to free free shared IRQ%d\n",irq); + printk(KERN_ERR "Trying to free free shared IRQ%d\n", + irq); goto out_unlock; } } else if (action->flags & IRQF_SHARED) { - printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n", + irq); goto out_unlock; } - if (action->flags & SA_STATIC_ALLOC) - { - /* This interrupt is marked as specially allocated + if (action->flags & SA_STATIC_ALLOC) { + /* + * This interrupt is marked as specially allocated * so it is a bad idea to free it. */ - printk("Attempt to free statically allocated IRQ%d (%s)\n", + printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n", irq, action->name); goto out_unlock; } - + if (tmp) tmp->next = action->next; else @@ -203,21 +227,19 @@ out_unlock: spin_unlock_irqrestore(&irq_action_lock, flags); } -extern void unexpected_irq(int, void *, struct pt_regs *); - -void sun4d_handler_irq(int pil, struct pt_regs * regs) +void sun4d_handler_irq(int pil, struct pt_regs *regs) { struct pt_regs *old_regs; - struct irqaction * action; + struct irqaction *action; int cpu = smp_processor_id(); /* SBUS IRQ level (1 - 7) */ int sbusl = pil_to_sbus[pil]; - + /* FIXME: Is this necessary?? */ cc_get_ipen(); - + cc_set_iclr(1 << pil); - + old_regs = set_irq_regs(regs); irq_enter(); kstat_cpu(cpu).irqs[pil]++; @@ -235,9 +257,9 @@ void sun4d_handler_irq(int pil, struct pt_regs * regs) struct sbus_action *actionp; unsigned mask, slot; int sbil = (sbusl << 2); - + bw_clear_intr_mask(sbusl, bus_mask); - + /* Loop for each pending SBI */ for (sbino = 0; bus_mask; sbino++, bus_mask >>= 1) if (bus_mask & 1) { @@ -249,7 +271,7 @@ void sun4d_handler_irq(int pil, struct pt_regs * regs) if (mask & slot) { mask &= ~slot; action = actionp->action; - + if (!action) unexpected_irq(pil, NULL, regs); do { @@ -266,13 +288,13 @@ void sun4d_handler_irq(int pil, struct pt_regs * regs) int sun4d_request_irq(unsigned int irq, irq_handler_t handler, - unsigned long irqflags, const char * devname, void *dev_id) + unsigned long irqflags, const char *devname, void *dev_id) { struct irqaction *action, *tmp = NULL, **actionp; unsigned long flags; int ret; - - if(irq > 14 && irq < (1 << 5)) { + + if (irq > 14 && irq < (1 << 5)) { ret = -EINVAL; goto out; } @@ -289,7 +311,7 @@ int sun4d_request_irq(unsigned int irq, else actionp = irq + irq_action; action = *actionp; - + if (action) { if ((action->flags & IRQF_SHARED) && (irqflags & IRQF_SHARED)) { for (tmp = action; tmp->next; tmp = tmp->next); @@ -298,7 +320,8 @@ int sun4d_request_irq(unsigned int irq, goto out_unlock; } if ((action->flags & IRQF_DISABLED) ^ (irqflags & IRQF_DISABLED)) { - printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n", + irq); ret = -EBUSY; goto out_unlock; } @@ -312,14 +335,14 @@ int sun4d_request_irq(unsigned int irq, if (static_irq_count < MAX_STATIC_ALLOC) action = &static_irqaction[static_irq_count++]; else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", irq, devname); + printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", + irq, devname); } - + if (action == NULL) - action = kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - - if (!action) { + action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC); + + if (!action) { ret = -ENOMEM; goto out_unlock; } @@ -334,7 +357,7 @@ int sun4d_request_irq(unsigned int irq, tmp->next = action; else *actionp = action; - + __enable_irq(irq); ret = 0; @@ -348,7 +371,7 @@ static void sun4d_disable_irq(unsigned int irq) { int tid = sbus_tid[(irq >> 5) - 1]; unsigned long flags; - + if (irq < NR_IRQS) return; @@ -361,7 +384,7 @@ static void sun4d_enable_irq(unsigned int irq) { int tid = sbus_tid[(irq >> 5) - 1]; unsigned long flags; - + if (irq < NR_IRQS) return; @@ -411,7 +434,7 @@ void __init sun4d_distribute_irqs(void) int board = of_getintprop_default(dp, "board#", 0); if (sbus_tid[board] == 0xff) { int i = 31; - + if (cpus_empty(sbus_serving_map)) sbus_serving_map = cpu_present_map; while (cpu_isset(i, sbus_serving_map)) @@ -423,7 +446,8 @@ void __init sun4d_distribute_irqs(void) for_each_node_by_name(dp, "sbi") { int devid = of_getintprop_default(dp, "device-id", 0); int board = of_getintprop_default(dp, "board#", 0); - printk("sbus%d IRQs directed to CPU%d\n", board, sbus_tid[board]); + printk(KERN_ERR "sbus%d IRQs directed to CPU%d\n", + board, sbus_tid[board]); set_sbi_tid(devid, sbus_tid[board] << 3); } #else @@ -437,11 +461,11 @@ void __init sun4d_distribute_irqs(void) sbus_tid[board] = cpuid; set_sbi_tid(devid, cpuid << 3); } - printk("All sbus IRQs directed to CPU%d\n", cpuid); + printk(KERN_ERR "All sbus IRQs directed to CPU%d\n", cpuid); #endif } #endif - + static void sun4d_clear_clock_irq(void) { sbus_readl(&sun4d_timers->l10_timer_limit); @@ -466,10 +490,7 @@ static void __init sun4d_fixup_trap_table(void) { #ifdef CONFIG_SMP unsigned long flags; - extern unsigned long lvl14_save[4]; struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; - extern unsigned int real_irq_entry[], smp4d_ticker[]; - extern unsigned int patchme_maybe_smp_msg[]; /* Adjust so that we jump directly to smp4d_ticker */ lvl14_save[2] += smp4d_ticker - real_irq_entry; @@ -531,7 +552,8 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn) (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); if (err) { - prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err); + prom_printf("sun4d_init_timers: request_irq() failed with %d\n", + err); prom_halt(); } sun4d_load_profile_irqs(); @@ -550,7 +572,7 @@ void __init sun4d_init_sbi_irq(void) nsbi = 0; for_each_node_by_name(dp, "sbi") nsbi++; - sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); + sbus_actions = kzalloc(nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); if (!sbus_actions) { prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n"); prom_halt(); @@ -566,7 +588,8 @@ void __init sun4d_init_sbi_irq(void) /* Get rid of pending irqs from PROM */ mask = acquire_sbi(devid, 0xffffffff); if (mask) { - printk ("Clearing pending IRQs %08x on SBI %d\n", mask, board); + printk(KERN_ERR "Clearing pending IRQs %08x on SBI %d\n", + mask, board); release_sbi(devid, mask); } } diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 482f2ab92692..475d50b96cd0 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -1,4 +1,4 @@ -/* sun4d_smp.c: Sparc SS1000/SC2000 SMP support. +/* Sparc SS1000/SC2000 SMP support. * * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * @@ -6,59 +6,23 @@ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ -#include - -#include -#include -#include -#include #include -#include -#include -#include -#include -#include #include #include #include -#include -#include -#include - -#include -#include -#include -#include -#include #include +#include #include #include -#include +#include "kernel.h" #include "irq.h" -#define IRQ_CROSS_CALL 15 -extern ctxd_t *srmmu_ctx_table_phys; +#define IRQ_CROSS_CALL 15 -static volatile int smp_processors_ready = 0; +static volatile int smp_processors_ready; static int smp_highest_cpu; -extern volatile unsigned long cpu_callin_map[NR_CPUS]; -extern cpuinfo_sparc cpu_data[NR_CPUS]; -extern unsigned char boot_cpu_id; -extern volatile int smp_process_available; - -extern cpumask_t smp_commenced_mask; - -extern int __smp4d_processor_id(void); - -/* #define SMP_DEBUG */ - -#ifdef SMP_DEBUG -#define SMP_PRINTK(x) printk x -#else -#define SMP_PRINTK(x) -#endif static inline unsigned long sun4d_swap(volatile unsigned long *ptr, unsigned long val) { @@ -69,8 +33,6 @@ static inline unsigned long sun4d_swap(volatile unsigned long *ptr, unsigned lon } static void smp_setup_percpu_timer(void); -extern void cpu_probe(void); -extern void sun4d_distribute_irqs(void); static unsigned char cpu_leds[32]; @@ -86,9 +48,8 @@ static inline void show_leds(int cpuid) void __cpuinit smp4d_callin(void) { int cpuid = hard_smp4d_processor_id(); - extern spinlock_t sun4d_imsk_lock; unsigned long flags; - + /* Show we are alive */ cpu_leds[cpuid] = 0x6; show_leds(cpuid); @@ -118,15 +79,15 @@ void __cpuinit smp4d_callin(void) sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1); local_flush_cache_all(); local_flush_tlb_all(); - + cpu_probe(); - while((unsigned long)current_set[cpuid] < PAGE_OFFSET) + while ((unsigned long)current_set[cpuid] < PAGE_OFFSET) barrier(); - - while(current_set[cpuid]->cpu != cpuid) + + while (current_set[cpuid]->cpu != cpuid) barrier(); - + /* Fix idle thread fields. */ __asm__ __volatile__("ld [%0], %%g6\n\t" : : "r" (¤t_set[cpuid]) @@ -134,16 +95,16 @@ void __cpuinit smp4d_callin(void) cpu_leds[cpuid] = 0x9; show_leds(cpuid); - + /* Attach to the address space of init_task. */ atomic_inc(&init_mm.mm_count); current->active_mm = &init_mm; local_flush_cache_all(); local_flush_tlb_all(); - + local_irq_enable(); /* We don't allow PIL 14 yet */ - + while (!cpu_isset(cpuid, smp_commenced_mask)) barrier(); @@ -154,15 +115,9 @@ void __cpuinit smp4d_callin(void) } -extern void init_IRQ(void); -extern void cpu_panic(void); - /* * Cycle through the processors asking the PROM to start each one. */ - -extern struct linux_prom_registers smp_penguin_ctable; - void __init smp4d_boot_cpus(void) { if (boot_cpu_id) @@ -173,43 +128,42 @@ void __init smp4d_boot_cpus(void) int __cpuinit smp4d_boot_one_cpu(int i) { - extern unsigned long sun4d_cpu_startup; - unsigned long *entry = &sun4d_cpu_startup; - struct task_struct *p; - int timeout; - int cpu_node; + unsigned long *entry = &sun4d_cpu_startup; + struct task_struct *p; + int timeout; + int cpu_node; - cpu_find_by_instance(i, &cpu_node,NULL); - /* Cook up an idler for this guy. */ - p = fork_idle(i); - current_set[i] = task_thread_info(p); + cpu_find_by_instance(i, &cpu_node, NULL); + /* Cook up an idler for this guy. */ + p = fork_idle(i); + current_set[i] = task_thread_info(p); + + /* + * Initialize the contexts table + * Since the call to prom_startcpu() trashes the structure, + * we need to re-initialize it for each cpu + */ + smp_penguin_ctable.which_io = 0; + smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys; + smp_penguin_ctable.reg_size = 0; + + /* whirrr, whirrr, whirrrrrrrrr... */ + printk(KERN_INFO "Starting CPU %d at %p\n", i, entry); + local_flush_cache_all(); + prom_startcpu(cpu_node, + &smp_penguin_ctable, 0, (char *)entry); + + printk(KERN_INFO "prom_startcpu returned :)\n"); + + /* wheee... it's going... */ + for (timeout = 0; timeout < 10000; timeout++) { + if (cpu_callin_map[i]) + break; + udelay(200); + } - /* - * Initialize the contexts table - * Since the call to prom_startcpu() trashes the structure, - * we need to re-initialize it for each cpu - */ - smp_penguin_ctable.which_io = 0; - smp_penguin_ctable.phys_addr = (unsigned int) srmmu_ctx_table_phys; - smp_penguin_ctable.reg_size = 0; - - /* whirrr, whirrr, whirrrrrrrrr... */ - SMP_PRINTK(("Starting CPU %d at %p\n", i, entry)); - local_flush_cache_all(); - prom_startcpu(cpu_node, - &smp_penguin_ctable, 0, (char *)entry); - - SMP_PRINTK(("prom_startcpu returned :)\n")); - - /* wheee... it's going... */ - for(timeout = 0; timeout < 10000; timeout++) { - if(cpu_callin_map[i]) - break; - udelay(200); - } - if (!(cpu_callin_map[i])) { - printk("Processor %d is stuck.\n", i); + printk(KERN_ERR "Processor %d is stuck.\n", i); return -ENODEV; } @@ -255,14 +209,17 @@ static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4) { - if(smp_processors_ready) { + if (smp_processors_ready) { register int high = smp_highest_cpu; unsigned long flags; spin_lock_irqsave(&cross_call_lock, flags); { - /* If you make changes here, make sure gcc generates proper code... */ + /* + * If you make changes here, make sure + * gcc generates proper code... + */ register smpfunc_t f asm("i0") = func; register unsigned long a1 asm("i1") = arg1; register unsigned long a2 asm("i2") = arg2; @@ -284,7 +241,7 @@ static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, cpu_clear(smp_processor_id(), mask); cpus_and(mask, cpu_online_map, mask); - for(i = 0; i <= high; i++) { + for (i = 0; i <= high; i++) { if (cpu_isset(i, mask)) { ccall_info.processors_in[i] = 0; ccall_info.processors_out[i] = 0; @@ -300,17 +257,17 @@ static void smp4d_cross_call(smpfunc_t func, cpumask_t mask, unsigned long arg1, do { if (!cpu_isset(i, mask)) continue; - while(!ccall_info.processors_in[i]) + while (!ccall_info.processors_in[i]) barrier(); - } while(++i <= high); + } while (++i <= high); i = 0; do { if (!cpu_isset(i, mask)) continue; - while(!ccall_info.processors_out[i]) + while (!ccall_info.processors_out[i]) barrier(); - } while(++i <= high); + } while (++i <= high); } spin_unlock_irqrestore(&cross_call_lock, flags); @@ -336,7 +293,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) static char led_mask[] = { 0xe, 0xd, 0xb, 0x7, 0xb, 0xd }; old_regs = set_irq_regs(regs); - bw_get_prof_limit(cpu); + bw_get_prof_limit(cpu); bw_clear_intr_mask(0, 1); /* INTR_TABLE[0] & 1 is Profile IRQ */ cpu_tick[cpu]++; @@ -349,7 +306,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) profile_tick(CPU_PROFILING); - if(!--prof_counter(cpu)) { + if (!--prof_counter(cpu)) { int user = user_mode(regs); irq_enter(); @@ -361,8 +318,6 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs) set_irq_regs(old_regs); } -extern unsigned int lvl14_resolution; - static void __cpuinit smp_setup_percpu_timer(void) { int cpu = hard_smp4d_processor_id(); @@ -374,16 +329,16 @@ static void __cpuinit smp_setup_percpu_timer(void) void __init smp4d_blackbox_id(unsigned *addr) { int rd = *addr & 0x3e000000; - + addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ - addr[1] = 0x01000000; /* nop */ - addr[2] = 0x01000000; /* nop */ + addr[1] = 0x01000000; /* nop */ + addr[2] = 0x01000000; /* nop */ } void __init smp4d_blackbox_current(unsigned *addr) { int rd = *addr & 0x3e000000; - + addr[0] = 0xc0800800 | rd; /* lda [%g0] ASI_M_VIKING_TMP1, reg */ addr[2] = 0x81282002 | rd | (rd >> 11); /* sll reg, 2, reg */ addr[4] = 0x01000000; /* nop */ @@ -392,17 +347,16 @@ void __init smp4d_blackbox_current(unsigned *addr) void __init sun4d_init_smp(void) { int i; - extern unsigned int t_nmi[], linux_trap_ipi15_sun4d[], linux_trap_ipi15_sun4m[]; /* Patch ipi15 trap table */ t_nmi[1] = t_nmi[1] + (linux_trap_ipi15_sun4d - linux_trap_ipi15_sun4m); - + /* And set btfixup... */ BTFIXUPSET_BLACKBOX(hard_smp_processor_id, smp4d_blackbox_id); BTFIXUPSET_BLACKBOX(load_current, smp4d_blackbox_current); BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4d_processor_id, BTFIXUPCALL_NORM); - + for (i = 0; i < NR_CPUS; i++) { ccall_info.processors_in[i] = 1; ccall_info.processors_out[i] = 1; -- cgit v1.2.3 From a625a12a763fa5cfe9775aa354790782d89efb6f Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:22 +0000 Subject: sparc32,sun4d: drop unused code in sun4d_distribute_irqs() The preprocessor symbol was not defined and the code was therefore not in use. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4d_irq.c | 47 ------------------------------------------- 1 file changed, 47 deletions(-) diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 5fc4c220158c..b2e3fbf7c6fa 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -38,13 +38,6 @@ * have interrupts pending for that SBUS interrupt level. */ -/* - * If you trust current SCSI layer to handle different - * SCSI IRQs, enable this. - * I don't trust it... -jj - */ -/* #define DISTRIBUTE_IRQS */ - struct sun4d_timer_regs { u32 l10_timer_limit; u32 l10_cur_countx; @@ -412,45 +405,6 @@ void __init sun4d_distribute_irqs(void) { struct device_node *dp; -#ifdef DISTRIBUTE_IRQS - cpumask_t sbus_serving_map; - - sbus_serving_map = cpu_present_map; - for_each_node_by_name(dp, "sbi") { - int board = of_getintprop_default(dp, "board#", 0); - - if ((board * 2) == boot_cpu_id && cpu_isset(board * 2 + 1, cpu_present_map)) - sbus_tid[board] = (board * 2 + 1); - else if (cpu_isset(board * 2, cpu_present_map)) - sbus_tid[board] = (board * 2); - else if (cpu_isset(board * 2 + 1, cpu_present_map)) - sbus_tid[board] = (board * 2 + 1); - else - sbus_tid[board] = 0xff; - if (sbus_tid[board] != 0xff) - cpu_clear(sbus_tid[board], sbus_serving_map); - } - for_each_node_by_name(dp, "sbi") { - int board = of_getintprop_default(dp, "board#", 0); - if (sbus_tid[board] == 0xff) { - int i = 31; - - if (cpus_empty(sbus_serving_map)) - sbus_serving_map = cpu_present_map; - while (cpu_isset(i, sbus_serving_map)) - i--; - sbus_tid[board] = i; - cpu_clear(i, sbus_serving_map); - } - } - for_each_node_by_name(dp, "sbi") { - int devid = of_getintprop_default(dp, "device-id", 0); - int board = of_getintprop_default(dp, "board#", 0); - printk(KERN_ERR "sbus%d IRQs directed to CPU%d\n", - board, sbus_tid[board]); - set_sbi_tid(devid, sbus_tid[board] << 3); - } -#else int cpuid = cpu_logical_map(1); if (cpuid == -1) @@ -462,7 +416,6 @@ void __init sun4d_distribute_irqs(void) set_sbi_tid(devid, cpuid << 3); } printk(KERN_ERR "All sbus IRQs directed to CPU%d\n", cpuid); -#endif } #endif -- cgit v1.2.3 From 70044df4111e1afbff91a731785673aeb42a34fd Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:23 +0000 Subject: sparc32, sun4d: add comment in empty statement in sun4d_request_irq() This looked like a bug to me. Add a comment so next reader is hopefully less confused. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/sun4d_irq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index b2e3fbf7c6fa..609a13c85823 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -307,7 +307,8 @@ int sun4d_request_irq(unsigned int irq, if (action) { if ((action->flags & IRQF_SHARED) && (irqflags & IRQF_SHARED)) { - for (tmp = action; tmp->next; tmp = tmp->next); + for (tmp = action; tmp->next; tmp = tmp->next) + /* find last entry - tmp used below */; } else { ret = -EBUSY; goto out_unlock; -- cgit v1.2.3 From fd49bf48cac7126a8311592bea56518529a223e2 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 28 Jan 2011 22:08:24 +0000 Subject: sparc32: irq_32.c cleanup - drop filename in file header - drop unused includes - add KERN_* to printk - fix spaces => tabs - add spaces after reserved words - drop all externs, they are now in header files Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_32.c | 229 ++++++++++++++++++--------------------------- 1 file changed, 92 insertions(+), 137 deletions(-) diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 85db35d894fc..974dab046a04 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -1,8 +1,8 @@ /* - * arch/sparc/kernel/irq.c: Interrupt request handling routines. On the - * Sparc the IRQs are basically 'cast in stone' - * and you are supposed to probe the prom's device - * node trees to find out who's got which IRQ. + * Interrupt request handling routines. On the + * Sparc the IRQs are basically 'cast in stone' + * and you are supposed to probe the prom's device + * node trees to find out who's got which IRQ. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx) @@ -11,40 +11,10 @@ * Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org) */ -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include #include "kernel.h" @@ -57,6 +27,7 @@ #define SMP_NOP2 #define SMP_NOP3 #endif /* SMP */ + unsigned long arch_local_irq_save(void) { unsigned long retval; @@ -135,8 +106,7 @@ static void irq_panic(void) prom_halt(); } -void (*sparc_init_timers)(irq_handler_t ) = - (void (*)(irq_handler_t )) irq_panic; +void (*sparc_init_timers)(irq_handler_t) = (void (*)(irq_handler_t))irq_panic; /* * Dave Redman (djhr@tadpole.co.uk) @@ -145,7 +115,7 @@ void (*sparc_init_timers)(irq_handler_t ) = * instead, because some of the devices attach very early, I do something * equally sucky but at least we'll never try to free statically allocated * space or call kmalloc before kmalloc_init :(. - * + * * In fact it's the timer10 that attaches first.. then timer14 * then kmalloc_init is called.. then the tty interrupts attach. * hmmm.... @@ -166,22 +136,20 @@ DEFINE_SPINLOCK(irq_action_lock); int show_interrupts(struct seq_file *p, void *v) { - int i = *(loff_t *) v; - struct irqaction * action; + int i = *(loff_t *)v; + struct irqaction *action; unsigned long flags; #ifdef CONFIG_SMP int j; #endif - if (sparc_cpu_model == sun4d) { - extern int show_sun4d_interrupts(struct seq_file *, void *); - + if (sparc_cpu_model == sun4d) return show_sun4d_interrupts(p, v); - } + spin_lock_irqsave(&irq_action_lock, flags); if (i < NR_IRQS) { action = sparc_irq[i].action; - if (!action) + if (!action) goto out_unlock; seq_printf(p, "%3d: ", i); #ifndef CONFIG_SMP @@ -195,7 +163,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, " %c %s", (action->flags & IRQF_DISABLED) ? '+' : ' ', action->name); - for (action=action->next; action; action = action->next) { + for (action = action->next; action; action = action->next) { seq_printf(p, ",%s %s", (action->flags & IRQF_DISABLED) ? " +" : "", action->name); @@ -209,22 +177,20 @@ out_unlock: void free_irq(unsigned int irq, void *dev_id) { - struct irqaction * action; + struct irqaction *action; struct irqaction **actionp; - unsigned long flags; + unsigned long flags; unsigned int cpu_irq; - + if (sparc_cpu_model == sun4d) { - extern void sun4d_free_irq(unsigned int, void *); - sun4d_free_irq(irq, dev_id); return; } cpu_irq = irq & (NR_IRQS - 1); - if (cpu_irq > 14) { /* 14 irq levels on the sparc */ - printk("Trying to free bogus IRQ %d\n", irq); - return; - } + if (cpu_irq > 14) { /* 14 irq levels on the sparc */ + printk(KERN_ERR "Trying to free bogus IRQ %d\n", irq); + return; + } spin_lock_irqsave(&irq_action_lock, flags); @@ -232,7 +198,7 @@ void free_irq(unsigned int irq, void *dev_id) action = *actionp; if (!action->handler) { - printk("Trying to free free IRQ%d\n",irq); + printk(KERN_ERR "Trying to free free IRQ%d\n", irq); goto out_unlock; } if (dev_id) { @@ -242,19 +208,21 @@ void free_irq(unsigned int irq, void *dev_id) actionp = &action->next; } if (!action) { - printk("Trying to free free shared IRQ%d\n",irq); + printk(KERN_ERR "Trying to free free shared IRQ%d\n", + irq); goto out_unlock; } } else if (action->flags & IRQF_SHARED) { - printk("Trying to free shared IRQ%d with NULL device ID\n", irq); + printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n", + irq); goto out_unlock; } - if (action->flags & SA_STATIC_ALLOC) - { - /* This interrupt is marked as specially allocated + if (action->flags & SA_STATIC_ALLOC) { + /* + * This interrupt is marked as specially allocated * so it is a bad idea to free it. */ - printk("Attempt to free statically allocated IRQ%d (%s)\n", + printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n", irq, action->name); goto out_unlock; } @@ -275,7 +243,6 @@ void free_irq(unsigned int irq, void *dev_id) out_unlock: spin_unlock_irqrestore(&irq_action_lock, flags); } - EXPORT_SYMBOL(free_irq); /* @@ -297,44 +264,41 @@ void synchronize_irq(unsigned int irq) EXPORT_SYMBOL(synchronize_irq); #endif /* SMP */ -void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs) +void unexpected_irq(int irq, void *dev_id, struct pt_regs *regs) { - int i; - struct irqaction * action; + int i; + struct irqaction *action; unsigned int cpu_irq; - + cpu_irq = irq & (NR_IRQS - 1); action = sparc_irq[cpu_irq].action; - printk("IO device interrupt, irq = %d\n", irq); - printk("PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, + printk(KERN_ERR "IO device interrupt, irq = %d\n", irq); + printk(KERN_ERR "PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc, regs->npc, regs->u_regs[14]); if (action) { - printk("Expecting: "); - for (i = 0; i < 16; i++) - if (action->handler) - printk("[%s:%d:0x%x] ", action->name, - (int) i, (unsigned int) action->handler); + printk(KERN_ERR "Expecting: "); + for (i = 0; i < 16; i++) + if (action->handler) + printk(KERN_CONT "[%s:%d:0x%x] ", action->name, + i, (unsigned int)action->handler); } - printk("AIEEE\n"); + printk(KERN_ERR "AIEEE\n"); panic("bogus interrupt received"); } -void handler_irq(int pil, struct pt_regs * regs) +void handler_irq(int pil, struct pt_regs *regs) { struct pt_regs *old_regs; - struct irqaction * action; + struct irqaction *action; int cpu = smp_processor_id(); -#ifdef CONFIG_SMP - extern void smp4m_irq_rotate(int cpu); -#endif old_regs = set_irq_regs(regs); irq_enter(); disable_pil_irq(pil); #ifdef CONFIG_SMP /* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */ - if((sparc_cpu_model==sun4m) && (pil < 10)) + if ((sparc_cpu_model==sun4m) && (pil < 10)) smp4m_irq_rotate(cpu); #endif action = sparc_irq[pil].action; @@ -354,7 +318,8 @@ void handler_irq(int pil, struct pt_regs * regs) #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE) -/* Fast IRQs on the Sparc can only have one routine attached to them, +/* + * Fast IRQs on the Sparc can only have one routine attached to them, * thus no sharing possible. */ static int request_fast_irq(unsigned int irq, @@ -367,15 +332,13 @@ static int request_fast_irq(unsigned int irq, int ret; #if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON struct tt_entry *trap_table; - extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3; #endif - cpu_irq = irq & (NR_IRQS - 1); - if(cpu_irq > 14) { + if (cpu_irq > 14) { ret = -EINVAL; goto out; } - if(!handler) { + if (!handler) { ret = -EINVAL; goto out; } @@ -383,34 +346,33 @@ static int request_fast_irq(unsigned int irq, spin_lock_irqsave(&irq_action_lock, flags); action = sparc_irq[cpu_irq].action; - if(action) { - if(action->flags & IRQF_SHARED) + if (action) { + if (action->flags & IRQF_SHARED) panic("Trying to register fast irq when already shared.\n"); - if(irqflags & IRQF_SHARED) + if (irqflags & IRQF_SHARED) panic("Trying to register fast irq as shared.\n"); /* Anyway, someone already owns it so cannot be made fast. */ - printk("request_fast_irq: Trying to register yet already owned.\n"); + printk(KERN_ERR "request_fast_irq: Trying to register yet already owned.\n"); ret = -EBUSY; goto out_unlock; } - /* If this is flagged as statically allocated then we use our + /* + * If this is flagged as statically allocated then we use our * private struct which is never freed. */ if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Fast IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", - irq, devname); + if (static_irq_count < MAX_STATIC_ALLOC) + action = &static_irqaction[static_irq_count++]; + else + printk(KERN_ERR "Fast IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", + irq, devname); } - + if (action == NULL) - action = kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - - if (!action) { + action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC); + if (!action) { ret = -ENOMEM; goto out_unlock; } @@ -426,9 +388,12 @@ static int request_fast_irq(unsigned int irq, INSTANTIATE(sparc_ttable) #if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON - trap_table = &trapbase_cpu1; INSTANTIATE(trap_table) - trap_table = &trapbase_cpu2; INSTANTIATE(trap_table) - trap_table = &trapbase_cpu3; INSTANTIATE(trap_table) + trap_table = &trapbase_cpu1; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu2; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu3; + INSTANTIATE(trap_table) #endif #undef INSTANTIATE /* @@ -454,7 +419,8 @@ out: return ret; } -/* These variables are used to access state from the assembler +/* + * These variables are used to access state from the assembler * interrupt handler, floppy_hardint, so we cannot put these in * the floppy driver image because that would not work in the * modular case. @@ -477,8 +443,6 @@ EXPORT_SYMBOL(pdma_base); unsigned long pdma_areasize; EXPORT_SYMBOL(pdma_areasize); -extern void floppy_hardint(void); - static irq_handler_t floppy_irq_handler; void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) @@ -494,9 +458,11 @@ void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs) irq_exit(); enable_pil_irq(irq); set_irq_regs(old_regs); - // XXX Eek, it's totally changed with preempt_count() and such - // if (softirq_pending(cpu)) - // do_softirq(); + /* + * XXX Eek, it's totally changed with preempt_count() and such + * if (softirq_pending(cpu)) + * do_softirq(); + */ } int sparc_floppy_request_irq(int irq, unsigned long flags, @@ -511,21 +477,18 @@ EXPORT_SYMBOL(sparc_floppy_request_irq); int request_irq(unsigned int irq, irq_handler_t handler, - unsigned long irqflags, const char * devname, void *dev_id) + unsigned long irqflags, const char *devname, void *dev_id) { - struct irqaction * action, **actionp; + struct irqaction *action, **actionp; unsigned long flags; unsigned int cpu_irq; int ret; - - if (sparc_cpu_model == sun4d) { - extern int sun4d_request_irq(unsigned int, - irq_handler_t , - unsigned long, const char *, void *); + + if (sparc_cpu_model == sun4d) return sun4d_request_irq(irq, handler, irqflags, devname, dev_id); - } + cpu_irq = irq & (NR_IRQS - 1); - if(cpu_irq > 14) { + if (cpu_irq > 14) { ret = -EINVAL; goto out; } @@ -533,7 +496,7 @@ int request_irq(unsigned int irq, ret = -EINVAL; goto out; } - + spin_lock_irqsave(&irq_action_lock, flags); actionp = &sparc_irq[cpu_irq].action; @@ -544,7 +507,8 @@ int request_irq(unsigned int irq, goto out_unlock; } if ((action->flags & IRQF_DISABLED) != (irqflags & IRQF_DISABLED)) { - printk("Attempt to mix fast and slow interrupts on IRQ%d denied\n", irq); + printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n", + irq); ret = -EBUSY; goto out_unlock; } @@ -559,14 +523,12 @@ int request_irq(unsigned int irq, if (static_irq_count < MAX_STATIC_ALLOC) action = &static_irqaction[static_irq_count++]; else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", irq, devname); + printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n", + irq, devname); } - if (action == NULL) - action = kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - - if (!action) { + action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC); + if (!action) { ret = -ENOMEM; goto out_unlock; } @@ -587,7 +549,6 @@ out_unlock: out: return ret; } - EXPORT_SYMBOL(request_irq); void disable_irq_nosync(unsigned int irq) @@ -606,24 +567,22 @@ void enable_irq(unsigned int irq) { __enable_irq(irq); } - EXPORT_SYMBOL(enable_irq); -/* We really don't need these at all on the Sparc. We only have +/* + * We really don't need these at all on the Sparc. We only have * stubs here because they are exported to modules. */ unsigned long probe_irq_on(void) { return 0; } - EXPORT_SYMBOL(probe_irq_on); int probe_irq_off(unsigned long mask) { return 0; } - EXPORT_SYMBOL(probe_irq_off); /* djhr @@ -636,11 +595,7 @@ EXPORT_SYMBOL(probe_irq_off); void __init init_IRQ(void) { - extern void sun4c_init_IRQ( void ); - extern void sun4m_init_IRQ( void ); - extern void sun4d_init_IRQ( void ); - - switch(sparc_cpu_model) { + switch (sparc_cpu_model) { case sun4c: case sun4: sun4c_init_IRQ(); @@ -656,7 +611,7 @@ void __init init_IRQ(void) #endif sun4m_init_IRQ(); break; - + case sun4d: sun4d_init_IRQ(); break; -- cgit v1.2.3 From 5a0efea09f42f7c92bd98a38d66b4dff9589266b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 18 Feb 2011 14:06:47 -0800 Subject: sparc64: Sharpen address space randomization calculations. A recent patch to the x86 randomization code caused me to take a quick look at what we do on sparc64, and in doing so I noticed that we sometimes calculate a non-page-aligned randomization value and stick it into mmap_base. I also noticed that since I copied the logic over from PowerPC, the powerpc code has tweaked the randomization ranges in ways that would benefit us as well. For one thing, we should allow up to at least 8MB of randomization otherwise huge-page regions when HPAGE_SIZE is 4MB never randomize at all. And on the 64-bit side we were using up to 4GB. Tone it down to 1GB as 4GB can result in a lot of address space wastage. Finally, make sure all computations are unsigned. Signed-off-by: David S. Miller --- arch/sparc/kernel/sys_sparc_64.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index f836f4e93afe..96082d30def0 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -360,20 +360,25 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u } EXPORT_SYMBOL(get_fb_unmapped_area); -/* Essentially the same as PowerPC... */ -void arch_pick_mmap_layout(struct mm_struct *mm) +/* Essentially the same as PowerPC. */ +static unsigned long mmap_rnd(void) { - unsigned long random_factor = 0UL; - unsigned long gap; + unsigned long rnd = 0UL; if (current->flags & PF_RANDOMIZE) { - random_factor = get_random_int(); + unsigned long val = get_random_int(); if (test_thread_flag(TIF_32BIT)) - random_factor &= ((1 * 1024 * 1024) - 1); + rnd = (val % (1UL << (22UL-PAGE_SHIFT))); else - random_factor = ((random_factor << PAGE_SHIFT) & - 0xffffffffUL); + rnd = (val % (1UL << (29UL-PAGE_SHIFT))); } + return (rnd << PAGE_SHIFT) * 2; +} + +void arch_pick_mmap_layout(struct mm_struct *mm) +{ + unsigned long random_factor = mmap_rnd(); + unsigned long gap; /* * Fall back to the standard layout if the personality -- cgit v1.2.3 From 81043e811191b5ccc1e6c170ed26f4ac8388834f Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 23 Feb 2011 13:08:21 -0800 Subject: sparc: convert to clocksource_register_hz/khz This converts the sparc clocksources to use clocksource_register_hz/khz Signed-off-by: John Stultz Signed-off-by: David S. Miller --- arch/sparc/kernel/time_64.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c index e1862793a61d..95ec25faba39 100644 --- a/arch/sparc/kernel/time_64.c +++ b/arch/sparc/kernel/time_64.c @@ -816,14 +816,12 @@ void __init time_init(void) clocksource_hz2mult(freq, SPARC64_NSEC_PER_CYC_SHIFT); clocksource_tick.name = tick_ops->name; - clocksource_calc_mult_shift(&clocksource_tick, freq, 4); clocksource_tick.read = clocksource_tick_read; + clocksource_register_hz(&clocksource_tick, freq); printk("clocksource: mult[%x] shift[%d]\n", clocksource_tick.mult, clocksource_tick.shift); - clocksource_register(&clocksource_tick); - sparc64_clockevent.name = tick_ops->name; clockevents_calc_mult_shift(&sparc64_clockevent, freq, 4); -- cgit v1.2.3 From a2a211cb55f0f3d13d791f3d2adccc96032e6846 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 25 Feb 2011 22:59:20 -0800 Subject: sparc32: fix build with leon or floppy enabled Add a few includes back required to build with floppy enabled Fix declaration of trapbase_cpu* so it is now consistent Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/include/asm/leon.h | 3 --- arch/sparc/kernel/irq_32.c | 1 + arch/sparc/kernel/kernel.h | 8 +++++--- arch/sparc/kernel/leon_smp.c | 20 +++++++++++--------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/arch/sparc/include/asm/leon.h b/arch/sparc/include/asm/leon.h index 8580d1764f90..c04f96fb753c 100644 --- a/arch/sparc/include/asm/leon.h +++ b/arch/sparc/include/asm/leon.h @@ -375,9 +375,6 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu); extern unsigned int real_irq_entry[], smpleon_ticker[]; extern unsigned int patchme_maybe_smp_msg[]; -extern unsigned long trapbase_cpu1[]; -extern unsigned long trapbase_cpu2[]; -extern unsigned long trapbase_cpu3[]; extern unsigned int t_nmi[], linux_trap_ipi15_leon[]; extern unsigned int linux_trap_ipi15_sun4m[]; diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 974dab046a04..93afee00a927 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -14,6 +14,7 @@ #include #include +#include #include #include diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h index 7eb736314381..24ad449886be 100644 --- a/arch/sparc/kernel/kernel.h +++ b/arch/sparc/kernel/kernel.h @@ -3,6 +3,8 @@ #include +#include + /* cpu.c */ extern const char *sparc_cpu_type; extern const char *sparc_pmu_type; @@ -54,9 +56,9 @@ extern unsigned int t_nmi[]; extern unsigned int linux_trap_ipi15_sun4d[]; extern unsigned int linux_trap_ipi15_sun4m[]; -extern unsigned long trapbase_cpu1[]; -extern unsigned long trapbase_cpu2[]; -extern unsigned long trapbase_cpu3[]; +extern struct tt_entry trapbase_cpu1; +extern struct tt_entry trapbase_cpu2; +extern struct tt_entry trapbase_cpu3; extern char cputypval[]; diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index e9df87f4447f..8f5de4aa3c0a 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -41,6 +41,8 @@ #include #include +#include "kernel.h" + #ifdef CONFIG_SPARC_LEON #include "irq.h" @@ -261,23 +263,23 @@ void __init leon_smp_done(void) /* Free unneeded trap tables */ if (!cpu_isset(1, cpu_present_map)) { - ClearPageReserved(virt_to_page(trapbase_cpu1)); - init_page_count(virt_to_page(trapbase_cpu1)); - free_page((unsigned long)trapbase_cpu1); + ClearPageReserved(virt_to_page(&trapbase_cpu1)); + init_page_count(virt_to_page(&trapbase_cpu1)); + free_page((unsigned long)&trapbase_cpu1); totalram_pages++; num_physpages++; } if (!cpu_isset(2, cpu_present_map)) { - ClearPageReserved(virt_to_page(trapbase_cpu2)); - init_page_count(virt_to_page(trapbase_cpu2)); - free_page((unsigned long)trapbase_cpu2); + ClearPageReserved(virt_to_page(&trapbase_cpu2)); + init_page_count(virt_to_page(&trapbase_cpu2)); + free_page((unsigned long)&trapbase_cpu2); totalram_pages++; num_physpages++; } if (!cpu_isset(3, cpu_present_map)) { - ClearPageReserved(virt_to_page(trapbase_cpu3)); - init_page_count(virt_to_page(trapbase_cpu3)); - free_page((unsigned long)trapbase_cpu3); + ClearPageReserved(virt_to_page(&trapbase_cpu3)); + init_page_count(virt_to_page(&trapbase_cpu3)); + free_page((unsigned long)&trapbase_cpu3); totalram_pages++; num_physpages++; } -- cgit v1.2.3 From bbdc2661eabddd442240533a66b2290f77d89ccc Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 25 Feb 2011 23:00:19 -0800 Subject: sparc32: introduce sparc_irq_config sparc_irq_config is used to hold the platform specific irq setup. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/irq.h | 17 +++++++++++------ arch/sparc/kernel/irq_32.c | 10 +++------- arch/sparc/kernel/leon_kernel.c | 2 +- arch/sparc/kernel/sun4c_irq.c | 4 +++- arch/sparc/kernel/sun4d_irq.c | 4 +++- arch/sparc/kernel/sun4m_irq.c | 4 +++- arch/sparc/kernel/time_32.c | 2 +- 7 files changed, 25 insertions(+), 18 deletions(-) diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index db7513881530..4b4e54f32b26 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -1,5 +1,16 @@ #include +/* + * Platform specific irq configuration + * The individual platforms assign their platform + * specifics in their init functions. + */ +struct sparc_irq_config { + void (*init_timers)(irq_handler_t); +}; +extern struct sparc_irq_config sparc_irq_config; + + /* Dave Redman (djhr@tadpole.co.uk) * changed these to function pointers.. it saves cycles and will allow * the irq dependencies to be split into different files at a later date @@ -45,12 +56,6 @@ static inline void load_profile_irq(int cpu, int limit) BTFIXUP_CALL(load_profile_irq)(cpu, limit); } -extern void (*sparc_init_timers)(irq_handler_t lvl10_irq); - -extern void claim_ticker14(irq_handler_t irq_handler, - int irq, - unsigned int timeout); - #ifdef CONFIG_SMP BTFIXUPDEF_CALL(void, set_cpu_int, int, int) BTFIXUPDEF_CALL(void, clear_cpu_int, int, int) diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 93afee00a927..b80b8bf0bf00 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -29,6 +29,9 @@ #define SMP_NOP3 #endif /* SMP */ +/* platform specific irq setup */ +struct sparc_irq_config sparc_irq_config; + unsigned long arch_local_irq_save(void) { unsigned long retval; @@ -100,14 +103,7 @@ EXPORT_SYMBOL(arch_local_irq_restore); * */ -static void irq_panic(void) -{ - prom_printf("machine: %s doesn't have irq handlers defined!\n", - &cputypval[0]); - prom_halt(); -} -void (*sparc_init_timers)(irq_handler_t) = (void (*)(irq_handler_t))irq_panic; /* * Dave Redman (djhr@tadpole.co.uk) diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 2f8a9a25d10d..2969f777fa11 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -347,7 +347,7 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) void __init leon_init_IRQ(void) { - sparc_init_timers = leon_init_timers; + sparc_irq_config.init_timers = leon_init_timers; BTFIXUPSET_CALL(enable_irq, leon_enable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(disable_irq, leon_disable_irq, BTFIXUPCALL_NORM); diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c index f543b452ebc1..90eea38ad66f 100644 --- a/arch/sparc/kernel/sun4c_irq.c +++ b/arch/sparc/kernel/sun4c_irq.c @@ -221,7 +221,9 @@ void __init sun4c_init_IRQ(void) BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP); - sparc_init_timers = sun4c_init_timers; + + sparc_irq_config.init_timers = sun4c_init_timers; + #ifdef CONFIG_SMP BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 609a13c85823..fc1c22f121fd 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -557,7 +557,9 @@ void __init sun4d_init_IRQ(void) BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); - sparc_init_timers = sun4d_init_timers; + + sparc_irq_config.init_timers = sun4d_init_timers; + #ifdef CONFIG_SMP BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(clear_cpu_int, sun4d_clear_ipi, BTFIXUPCALL_NOP); diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 3c6657a4caec..1e13ce96dc7e 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -470,7 +470,9 @@ void __init sun4m_init_IRQ(void) BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM); - sparc_init_timers = sun4m_init_timers; + + sparc_irq_config.init_timers = sun4m_init_timers; + #ifdef CONFIG_SMP BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM); diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c index 19ab42a932db..8237dd4dfeb4 100644 --- a/arch/sparc/kernel/time_32.c +++ b/arch/sparc/kernel/time_32.c @@ -219,7 +219,7 @@ static void __init sbus_time_init(void) btfixup(); - sparc_init_timers(timer_interrupt); + sparc_irq_config.init_timers(timer_interrupt); } void __init time_init(void) -- cgit v1.2.3 From 1d05995b0880b23353741d5b2b826f7c2fd6a296 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 25 Feb 2011 23:01:19 -0800 Subject: sparc32: introduce build_device_irq build_device_irq() is used to encapsulate the plaform specific details when we build an irq. For now the default is a simple 1:1 but sun4d differs. This patch refactors functionality - but does not change the existing functionality. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/irq.h | 4 +++ arch/sparc/kernel/irq_32.c | 8 ++++++ arch/sparc/kernel/of_device_32.c | 59 ++++------------------------------------ arch/sparc/kernel/sun4d_irq.c | 51 ++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 54 deletions(-) diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 4b4e54f32b26..0b4d5b902165 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -1,3 +1,5 @@ +#include + #include /* @@ -7,6 +9,8 @@ */ struct sparc_irq_config { void (*init_timers)(irq_handler_t); + unsigned int (*build_device_irq)(struct platform_device *op, + unsigned int real_irq); }; extern struct sparc_irq_config sparc_irq_config; diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index b80b8bf0bf00..7c93df4099cb 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -582,6 +582,12 @@ int probe_irq_off(unsigned long mask) } EXPORT_SYMBOL(probe_irq_off); +static unsigned int build_device_irq(struct platform_device *op, + unsigned int real_irq) +{ + return real_irq; +} + /* djhr * This could probably be made indirect too and assigned in the CPU * bits of the code. That would be much nicer I think and would also @@ -592,6 +598,8 @@ EXPORT_SYMBOL(probe_irq_off); void __init init_IRQ(void) { + sparc_irq_config.build_device_irq = build_device_irq; + switch (sparc_cpu_model) { case sun4c: case sun4: diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 2d055a1e9cc2..a312af40ea84 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -13,6 +13,7 @@ #include #include "of_device_common.h" +#include "irq.h" /* * PCI bus specific translator @@ -355,7 +356,8 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, if (intr) { op->archdata.num_irqs = len / sizeof(struct linux_prom_irqs); for (i = 0; i < op->archdata.num_irqs; i++) - op->archdata.irqs[i] = intr[i].pri; + op->archdata.irqs[i] = + sparc_irq_config.build_device_irq(op, intr[i].pri); } else { const unsigned int *irq = of_get_property(dp, "interrupts", &len); @@ -363,64 +365,13 @@ static struct platform_device * __init scan_one_device(struct device_node *dp, if (irq) { op->archdata.num_irqs = len / sizeof(unsigned int); for (i = 0; i < op->archdata.num_irqs; i++) - op->archdata.irqs[i] = irq[i]; + op->archdata.irqs[i] = + sparc_irq_config.build_device_irq(op, irq[i]); } else { op->archdata.num_irqs = 0; } } - if (sparc_cpu_model == sun4d) { - static int pil_to_sbus[] = { - 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, - }; - struct device_node *io_unit, *sbi = dp->parent; - const struct linux_prom_registers *regs; - int board, slot; - - while (sbi) { - if (!strcmp(sbi->name, "sbi")) - break; - - sbi = sbi->parent; - } - if (!sbi) - goto build_resources; - - regs = of_get_property(dp, "reg", NULL); - if (!regs) - goto build_resources; - - slot = regs->which_io; - - /* If SBI's parent is not io-unit or the io-unit lacks - * a "board#" property, something is very wrong. - */ - if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { - printk("%s: Error, parent is not io-unit.\n", - sbi->full_name); - goto build_resources; - } - io_unit = sbi->parent; - board = of_getintprop_default(io_unit, "board#", -1); - if (board == -1) { - printk("%s: Error, lacks board# property.\n", - io_unit->full_name); - goto build_resources; - } - - for (i = 0; i < op->archdata.num_irqs; i++) { - int this_irq = op->archdata.irqs[i]; - int sbusl = pil_to_sbus[this_irq]; - - if (sbusl) - this_irq = (((board + 1) << 5) + - (sbusl << 2) + - slot); - - op->archdata.irqs[i] = this_irq; - } - } -build_resources: build_device_resources(op, parent); op->dev.parent = parent; diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index fc1c22f121fd..77b4a8992710 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -440,6 +440,56 @@ static void __init sun4d_load_profile_irqs(void) } } +unsigned int sun4d_build_device_irq(struct platform_device *op, + unsigned int real_irq) +{ + static int pil_to_sbus[] = { + 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, + }; + struct device_node *dp = op->dev.of_node; + struct device_node *io_unit, *sbi = dp->parent; + const struct linux_prom_registers *regs; + int board, slot; + int sbusl; + + while (sbi) { + if (!strcmp(sbi->name, "sbi")) + break; + + sbi = sbi->parent; + } + if (!sbi) + goto err_out; + + regs = of_get_property(dp, "reg", NULL); + if (!regs) + goto err_out; + + slot = regs->which_io; + + /* + * If SBI's parent is not io-unit or the io-unit lacks + * a "board#" property, something is very wrong. + */ + if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { + printk("%s: Error, parent is not io-unit.\n", sbi->full_name); + goto err_out; + } + io_unit = sbi->parent; + board = of_getintprop_default(io_unit, "board#", -1); + if (board == -1) { + printk("%s: Error, lacks board# property.\n", io_unit->full_name); + goto err_out; + } + + sbusl = pil_to_sbus[real_irq]; + if (sbusl) + return (((board + 1) << 5) + (sbusl << 2) + slot); + +err_out: + return real_irq; +} + static void __init sun4d_fixup_trap_table(void) { #ifdef CONFIG_SMP @@ -559,6 +609,7 @@ void __init sun4d_init_IRQ(void) BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); sparc_irq_config.init_timers = sun4d_init_timers; + sparc_irq_config.build_device_irq = sun4d_build_device_irq; #ifdef CONFIG_SMP BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM); -- cgit v1.2.3 From 0399bb5b918bd8ffbf065a3db142ff121aaa18e0 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Fri, 25 Feb 2011 23:02:11 -0800 Subject: sparc32,sun4m: percpu and global register definitions moved to irq.h entry.S access percpu + global data defined in sun4m_irq.c - so move the types to irq.h. This makes sparse happy and allow us to utilize asm-offsets later. Also updated a few comments in the sun4m_irq.c file. Signed-off-by: Sam Ravnborg Signed-off-by: David S. Miller --- arch/sparc/kernel/irq.h | 21 +++++++++++++++++++++ arch/sparc/kernel/sun4m_irq.c | 30 +++++++++--------------------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h index 0b4d5b902165..008453b798ec 100644 --- a/arch/sparc/kernel/irq.h +++ b/arch/sparc/kernel/irq.h @@ -2,6 +2,27 @@ #include +/* sun4m specific type definitions */ + +/* This maps direct to CPU specific interrupt registers */ +struct sun4m_irq_percpu { + u32 pending; + u32 clear; + u32 set; +}; + +/* This maps direct to global interrupt registers */ +struct sun4m_irq_global { + u32 pending; + u32 mask; + u32 mask_clear; + u32 mask_set; + u32 interrupt_target; +}; + +extern struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; +extern struct sun4m_irq_global __iomem *sun4m_irq_global; + /* * Platform specific irq configuration * The individual platforms assign their platform diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 1e13ce96dc7e..69df6257a32e 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -96,20 +96,6 @@ */ -struct sun4m_irq_percpu { - u32 pending; - u32 clear; - u32 set; -}; - -struct sun4m_irq_global { - u32 pending; - u32 mask; - u32 mask_clear; - u32 mask_set; - u32 interrupt_target; -}; - /* Code in entry.S needs to get at these register mappings. */ struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; struct sun4m_irq_global __iomem *sun4m_irq_global; @@ -155,8 +141,11 @@ struct sun4m_irq_global __iomem *sun4m_irq_global; #define OBP_INT_LEVEL_SBUS 0x30 #define OBP_INT_LEVEL_VME 0x40 +#define SUN4M_TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10) +#define SUM4M_PROFILE_IRQ (OBP_INT_LEVEL_ONBOARD | 14) + static unsigned long irq_mask[0x50] = { - /* SMP */ + /* 0x00 - SMP */ 0, SUN4M_SOFT_INT(1), SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3), SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5), @@ -165,7 +154,7 @@ static unsigned long irq_mask[0x50] = { SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11), SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13), SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15), - /* soft */ + /* 0x10 - soft */ 0, SUN4M_SOFT_INT(1), SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3), SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5), @@ -174,19 +163,19 @@ static unsigned long irq_mask[0x50] = { SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11), SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13), SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15), - /* onboard */ + /* 0x20 - onboard */ 0, 0, 0, 0, SUN4M_INT_SCSI, 0, SUN4M_INT_ETHERNET, 0, SUN4M_INT_VIDEO, SUN4M_INT_MODULE, SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY, (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS), SUN4M_INT_AUDIO, 0, SUN4M_INT_MODULE_ERR, - /* sbus */ + /* 0x30 - sbus */ 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1), 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3), 0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5), 0, SUN4M_INT_SBUS(6), 0, 0, - /* vme */ + /* 0x40 - vme */ 0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1), 0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3), 0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5), @@ -319,7 +308,6 @@ struct sun4m_timer_global { static struct sun4m_timer_global __iomem *timers_global; -#define TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10) unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); @@ -396,7 +384,7 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn) master_l10_counter = &timers_global->l10_count; - err = request_irq(TIMER_IRQ, counter_fn, + err = request_irq(SUN4M_TIMER_IRQ, counter_fn, (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL); if (err) { printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n", -- cgit v1.2.3 From c6fee0810df4e0f4cf9c4834d2569ca01c02cffc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 26 Feb 2011 23:40:02 -0800 Subject: sparc64: Fix build errors with gcc-4.6.0 Most of the warnings emitted (we fail arch/sparc file builds with -Werror) were legitimate but harmless, however one case (n2_pcr_write) was a genuine bug. Based almost entirely upon a patch by Sam Ravnborg. Reported-by: Dennis Gilmore Signed-off-by: David S. Miller --- arch/sparc/kernel/iommu.c | 3 --- arch/sparc/kernel/ldc.c | 28 ++++++++++++++++++---------- arch/sparc/kernel/pci.c | 1 + arch/sparc/kernel/pci_common.c | 11 +++++++---- arch/sparc/kernel/pci_fire.c | 2 -- arch/sparc/kernel/pci_schizo.c | 4 +--- arch/sparc/kernel/pci_sun4v.c | 3 +-- arch/sparc/kernel/pcr.c | 2 +- arch/sparc/kernel/ptrace_64.c | 3 ++- arch/sparc/kernel/smp_64.c | 11 ++++------- arch/sparc/kernel/traps_64.c | 3 +-- 11 files changed, 36 insertions(+), 35 deletions(-) diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 72509d0e34be..6f01e8c83197 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -333,13 +333,10 @@ static void dma_4u_free_coherent(struct device *dev, size_t size, void *cpu, dma_addr_t dvma) { struct iommu *iommu; - iopte_t *iopte; unsigned long flags, order, npages; npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT; iommu = dev->archdata.iommu; - iopte = iommu->page_table + - ((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT); spin_lock_irqsave(&iommu->lock, flags); diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index df39a0f0d27a..732b0bce6001 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -790,16 +790,20 @@ static void send_events(struct ldc_channel *lp, unsigned int event_mask) static irqreturn_t ldc_rx(int irq, void *dev_id) { struct ldc_channel *lp = dev_id; - unsigned long orig_state, hv_err, flags; + unsigned long orig_state, flags; unsigned int event_mask; spin_lock_irqsave(&lp->lock, flags); orig_state = lp->chan_state; - hv_err = sun4v_ldc_rx_get_state(lp->id, - &lp->rx_head, - &lp->rx_tail, - &lp->chan_state); + + /* We should probably check for hypervisor errors here and + * reset the LDC channel if we get one. + */ + sun4v_ldc_rx_get_state(lp->id, + &lp->rx_head, + &lp->rx_tail, + &lp->chan_state); ldcdbg(RX, "RX state[0x%02lx:0x%02lx] head[0x%04lx] tail[0x%04lx]\n", orig_state, lp->chan_state, lp->rx_head, lp->rx_tail); @@ -904,16 +908,20 @@ out: static irqreturn_t ldc_tx(int irq, void *dev_id) { struct ldc_channel *lp = dev_id; - unsigned long flags, hv_err, orig_state; + unsigned long flags, orig_state; unsigned int event_mask = 0; spin_lock_irqsave(&lp->lock, flags); orig_state = lp->chan_state; - hv_err = sun4v_ldc_tx_get_state(lp->id, - &lp->tx_head, - &lp->tx_tail, - &lp->chan_state); + + /* We should probably check for hypervisor errors here and + * reset the LDC channel if we get one. + */ + sun4v_ldc_tx_get_state(lp->id, + &lp->tx_head, + &lp->tx_tail, + &lp->chan_state); ldcdbg(TX, " TX state[0x%02lx:0x%02lx] head[0x%04lx] tail[0x%04lx]\n", orig_state, lp->chan_state, lp->tx_head, lp->tx_tail); diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index bfede51c3afc..44f41e312f73 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -675,6 +675,7 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) * humanoid. */ err = sysfs_create_file(&dev->dev.kobj, &dev_attr_obppath.attr); + (void) err; } list_for_each_entry(child_bus, &bus->children, node) pci_bus_register_of_sysfs(child_bus); diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 6c7a33af3ba6..6e3874b64488 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -295,14 +295,17 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int bus = bus_dev->number; unsigned int device = PCI_SLOT(devfn); unsigned int func = PCI_FUNC(devfn); - unsigned long ret; if (config_out_of_range(pbm, bus, devfn, where)) { /* Do nothing. */ } else { - ret = pci_sun4v_config_put(devhandle, - HV_PCI_DEVICE_BUILD(bus, device, func), - where, size, value); + /* We don't check for hypervisor errors here, but perhaps + * we should and influence our return value depending upon + * what kind of error is thrown. + */ + pci_sun4v_config_put(devhandle, + HV_PCI_DEVICE_BUILD(bus, device, func), + where, size, value); } return PCIBIOS_SUCCESSFUL; } diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 43d691b67d52..3d70f8326efd 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -214,11 +214,9 @@ static int pci_fire_msi_setup(struct pci_pbm_info *pbm, unsigned long msiqid, static int pci_fire_msi_teardown(struct pci_pbm_info *pbm, unsigned long msi) { - unsigned long msiqid; u64 val; val = upa_readq(pbm->pbm_regs + MSI_MAP(msi)); - msiqid = (val & MSI_MAP_EQNUM); val &= ~MSI_MAP_VALID; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 6783410ceb02..1d41af73a92f 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1313,7 +1313,7 @@ static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, const struct linux_prom64_registers *regs; struct device_node *dp = op->dev.of_node; const char *chipset_name; - int is_pbm_a, err; + int err; switch (chip_type) { case PBM_CHIP_TYPE_TOMATILLO: @@ -1343,8 +1343,6 @@ static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, */ regs = of_get_property(dp, "reg", NULL); - is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); - pbm->next = pci_pbm_root; pci_pbm_root = pbm; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 629160772a9d..6cf534681788 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -580,7 +580,7 @@ static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) { static const u32 vdma_default[] = { 0x80000000, 0x80000000 }; struct iommu *iommu = pbm->iommu; - unsigned long num_tsb_entries, sz, tsbsize; + unsigned long num_tsb_entries, sz; u32 dma_mask, dma_offset; const u32 *vdma; @@ -596,7 +596,6 @@ static int __devinit pci_sun4v_iommu_init(struct pci_pbm_info *pbm) dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL); num_tsb_entries = vdma[1] / IO_PAGE_SIZE; - tsbsize = num_tsb_entries * sizeof(iopte_t); dma_offset = vdma[0]; diff --git a/arch/sparc/kernel/pcr.c b/arch/sparc/kernel/pcr.c index 7c2ced612b8f..8ac23e660080 100644 --- a/arch/sparc/kernel/pcr.c +++ b/arch/sparc/kernel/pcr.c @@ -81,7 +81,7 @@ static void n2_pcr_write(u64 val) unsigned long ret; ret = sun4v_niagara2_setperf(HV_N2_PERF_SPARC_CTL, val); - if (val != HV_EOK) + if (ret != HV_EOK) write_pcr(val); } diff --git a/arch/sparc/kernel/ptrace_64.c b/arch/sparc/kernel/ptrace_64.c index 9ccc812bc09e..96ee50a80661 100644 --- a/arch/sparc/kernel/ptrace_64.c +++ b/arch/sparc/kernel/ptrace_64.c @@ -1086,6 +1086,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs) asmlinkage void syscall_trace_leave(struct pt_regs *regs) { +#ifdef CONFIG_AUDITSYSCALL if (unlikely(current->audit_context)) { unsigned long tstate = regs->tstate; int result = AUDITSC_SUCCESS; @@ -1095,7 +1096,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs) audit_syscall_exit(result, regs->u_regs[UREG_I0]); } - +#endif if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_exit(regs, regs->u_regs[UREG_G1]); diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 555a76d1f4a1..3e94a8c23238 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -189,7 +189,7 @@ static inline long get_delta (long *rt, long *master) void smp_synchronize_tick_client(void) { long i, delta, adj, adjust_latency = 0, done = 0; - unsigned long flags, rt, master_time_stamp, bound; + unsigned long flags, rt, master_time_stamp; #if DEBUG_TICK_SYNC struct { long rt; /* roundtrip time */ @@ -208,10 +208,8 @@ void smp_synchronize_tick_client(void) { for (i = 0; i < NUM_ROUNDS; i++) { delta = get_delta(&rt, &master_time_stamp); - if (delta == 0) { + if (delta == 0) done = 1; /* let's lock on to this... */ - bound = rt; - } if (!done) { if (i > 0) { @@ -933,13 +931,12 @@ void smp_flush_dcache_page_impl(struct page *page, int cpu) void flush_dcache_page_all(struct mm_struct *mm, struct page *page) { void *pg_addr; - int this_cpu; u64 data0; if (tlb_type == hypervisor) return; - this_cpu = get_cpu(); + preempt_disable(); #ifdef CONFIG_DEBUG_DCFLUSH atomic_inc(&dcpage_flushes); @@ -964,7 +961,7 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page) } __local_flush_dcache_page(page); - put_cpu(); + preempt_enable(); } void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs) diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 1e9770936c3b..1ed547bd850f 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -2152,7 +2152,7 @@ static void user_instruction_dump(unsigned int __user *pc) void show_stack(struct task_struct *tsk, unsigned long *_ksp) { - unsigned long fp, thread_base, ksp; + unsigned long fp, ksp; struct thread_info *tp; int count = 0; #ifdef CONFIG_FUNCTION_GRAPH_TRACER @@ -2173,7 +2173,6 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) flushw_all(); fp = ksp + STACK_BIAS; - thread_base = (unsigned long) tp; printk("Call Trace:\n"); do { -- cgit v1.2.3 From 35043c428f1fcb92feb5792f5878a8852ee00771 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 9 Mar 2011 12:54:27 -0800 Subject: sparc: Fix .size directive for do_int_load gas used to accept (and ignore?) .size directives which referred to undefined symbols, as this does. In binutils 2.21 these are treated as errors. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- arch/sparc/kernel/una_asm_64.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/kernel/una_asm_64.S b/arch/sparc/kernel/una_asm_64.S index be183fe41443..1c8d33228b2a 100644 --- a/arch/sparc/kernel/una_asm_64.S +++ b/arch/sparc/kernel/una_asm_64.S @@ -127,7 +127,7 @@ do_int_load: wr %o5, 0x0, %asi retl mov 0, %o0 - .size __do_int_load, .-__do_int_load + .size do_int_load, .-do_int_load .section __ex_table,"a" .word 4b, __retl_efault -- cgit v1.2.3 From c816be7b5f24585baa9eba1f2413935f771d6ad6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 9 Mar 2011 13:00:47 -0800 Subject: sparc32: Fix might-be-used-uninitialized warning in do_sparc_fault(). When we try to handle vmalloc faults, we can take a code path which uses "code" before we actually set it. Amusingly gcc-3.3 notices this yet gcc-4.x does not. Reported-by: Bob Breuer Signed-off-by: David S. Miller --- arch/sparc/mm/fault_32.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index 5b836f5aea90..b10ac4d62378 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -240,11 +240,10 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, * only copy the information from the master page table, * nothing more. */ + code = SEGV_MAPERR; if (!ARCH_SUN4C && address >= TASK_SIZE) goto vmalloc_fault; - code = SEGV_MAPERR; - /* * If we're in an interrupt or have no user * context, we must not take the fault.. -- cgit v1.2.3