From 783c98b911fce8d47aa2906468ca39d44d46d7ce Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 25 Aug 2008 16:21:08 -0700 Subject: sparc64: Use the cond_syscall()s in kernel/sys_ni.c instead of home-grown copy. This also allows arch/sparc64/kernel/pci.c to be properly CONFIG_PCI conditional compiled in the Makefile. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 55096195458..9bb4b8cbcac 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -28,22 +28,6 @@ #include "pci_impl.h" -#ifndef CONFIG_PCI -/* A "nop" PCI implementation. */ -asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - unsigned char *buf) -{ - return 0; -} -asmlinkage int sys_pciconfig_write(unsigned long bus, unsigned long dfn, - unsigned long off, unsigned long len, - unsigned char *buf) -{ - return 0; -} -#else - /* List of all PCI controllers found in the system. */ struct pci_pbm_info *pci_pbm_root = NULL; @@ -1215,5 +1199,3 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar, *start = rp->start - offset; *end = rp->end - offset; } - -#endif /* !(CONFIG_PCI) */ -- cgit v1.2.3-70-g09d2 From ae05f87ee2f403228bca6d28fef29d6be0bfbedc Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 29 Aug 2008 22:42:34 -0700 Subject: sparc64: Propagate PCI device archdata into OF device tree for EBUS. In order to convert EBUS drivers doing DMA into pure OF drivers, we need the of_device->dev.archdata setup properly. EBUS instances that can provide DMA for device nodes sit on PCI, so detect and propagate the information there. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 9bb4b8cbcac..71d423a1c17 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -337,6 +337,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, struct pci_bus *bus, int devfn) { struct dev_archdata *sd; + struct of_device *op; struct pci_dev *dev; const char *type; u32 class; @@ -350,14 +351,17 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, sd->stc = &pbm->stc; sd->host_controller = pbm; sd->prom_node = node; - sd->op = of_find_device_by_node(node); + sd->op = op = of_find_device_by_node(node); sd->numa_node = pbm->numa_node; - sd = &sd->op->dev.archdata; + sd = &op->dev.archdata; sd->iommu = pbm->iommu; sd->stc = &pbm->stc; sd->numa_node = pbm->numa_node; + if (!strcmp(node->name, "ebus")) + of_propagate_archdata(op); + type = of_get_property(node, "device_type", NULL); if (type == NULL) type = ""; -- cgit v1.2.3-70-g09d2 From 356d164757310cd822d71da2027d50ec39798b7f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 00:36:11 -0700 Subject: sparc: Kill EBUS driver layer. All that remains is the EBUS DMA programming library for sparc64. Signed-off-by: David S. Miller --- arch/sparc/include/asm/ebus.h | 8 - arch/sparc/include/asm/ebus_32.h | 99 --------- arch/sparc/include/asm/ebus_64.h | 64 ------ arch/sparc/kernel/Makefile | 1 - arch/sparc/kernel/ebus.c | 392 ------------------------------------ arch/sparc/kernel/pcic.c | 8 +- arch/sparc/kernel/sparc_ksyms.c | 4 - arch/sparc64/kernel/Makefile | 4 +- arch/sparc64/kernel/ebus.c | 295 +-------------------------- arch/sparc64/kernel/pci.c | 4 +- arch/sparc64/kernel/sparc64_ksyms.c | 4 - 11 files changed, 6 insertions(+), 877 deletions(-) delete mode 100644 arch/sparc/include/asm/ebus.h delete mode 100644 arch/sparc/include/asm/ebus_32.h delete mode 100644 arch/sparc/include/asm/ebus_64.h delete mode 100644 arch/sparc/kernel/ebus.c (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc/include/asm/ebus.h b/arch/sparc/include/asm/ebus.h deleted file mode 100644 index 83a6d16c22e..00000000000 --- a/arch/sparc/include/asm/ebus.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ___ASM_SPARC_EBUS_H -#define ___ASM_SPARC_EBUS_H -#if defined(__sparc__) && defined(__arch64__) -#include -#else -#include -#endif -#endif diff --git a/arch/sparc/include/asm/ebus_32.h b/arch/sparc/include/asm/ebus_32.h deleted file mode 100644 index f91f0b267ce..00000000000 --- a/arch/sparc/include/asm/ebus_32.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * ebus.h: PCI to Ebus pseudo driver software state. - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * - * Adopted for sparc by V. Roganov and G. Raiko. - */ - -#ifndef __SPARC_EBUS_H -#define __SPARC_EBUS_H - -#ifndef _LINUX_IOPORT_H -#include -#endif -#include -#include -#include - -struct linux_ebus_child { - struct linux_ebus_child *next; - struct linux_ebus_device *parent; - struct linux_ebus *bus; - struct device_node *prom_node; - struct resource resource[PROMREG_MAX]; - int num_addrs; - unsigned int irqs[PROMINTR_MAX]; - int num_irqs; -}; - -struct linux_ebus_device { - struct of_device ofdev; - struct linux_ebus_device *next; - struct linux_ebus_child *children; - struct linux_ebus *bus; - struct device_node *prom_node; - struct resource resource[PROMREG_MAX]; - int num_addrs; - unsigned int irqs[PROMINTR_MAX]; - int num_irqs; -}; -#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev) - -struct linux_ebus { - struct of_device ofdev; - struct linux_ebus *next; - struct linux_ebus_device *devices; - struct linux_pbm_info *parent; - struct pci_dev *self; - struct device_node *prom_node; -}; -#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev) - -struct linux_ebus_dma { - unsigned int dcsr; - unsigned int dacr; - unsigned int dbcr; -}; - -#define EBUS_DCSR_INT_PEND 0x00000001 -#define EBUS_DCSR_ERR_PEND 0x00000002 -#define EBUS_DCSR_DRAIN 0x00000004 -#define EBUS_DCSR_INT_EN 0x00000010 -#define EBUS_DCSR_RESET 0x00000080 -#define EBUS_DCSR_WRITE 0x00000100 -#define EBUS_DCSR_EN_DMA 0x00000200 -#define EBUS_DCSR_CYC_PEND 0x00000400 -#define EBUS_DCSR_DIAG_RD_DONE 0x00000800 -#define EBUS_DCSR_DIAG_WR_DONE 0x00001000 -#define EBUS_DCSR_EN_CNT 0x00002000 -#define EBUS_DCSR_TC 0x00004000 -#define EBUS_DCSR_DIS_CSR_DRN 0x00010000 -#define EBUS_DCSR_BURST_SZ_MASK 0x000c0000 -#define EBUS_DCSR_BURST_SZ_1 0x00080000 -#define EBUS_DCSR_BURST_SZ_4 0x00000000 -#define EBUS_DCSR_BURST_SZ_8 0x00040000 -#define EBUS_DCSR_BURST_SZ_16 0x000c0000 -#define EBUS_DCSR_DIAG_EN 0x00100000 -#define EBUS_DCSR_DIS_ERR_PEND 0x00400000 -#define EBUS_DCSR_TCI_DIS 0x00800000 -#define EBUS_DCSR_EN_NEXT 0x01000000 -#define EBUS_DCSR_DMA_ON 0x02000000 -#define EBUS_DCSR_A_LOADED 0x04000000 -#define EBUS_DCSR_NA_LOADED 0x08000000 -#define EBUS_DCSR_DEV_ID_MASK 0xf0000000 - -extern struct linux_ebus *ebus_chain; - -extern void ebus_init(void); - -#define for_each_ebus(bus) \ - for((bus) = ebus_chain; (bus); (bus) = (bus)->next) - -#define for_each_ebusdev(dev, bus) \ - for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) - -#define for_each_edevchild(dev, child) \ - for((child) = (dev)->children; (child); (child) = (child)->next) - -#endif /* !(__SPARC_EBUS_H) */ diff --git a/arch/sparc/include/asm/ebus_64.h b/arch/sparc/include/asm/ebus_64.h deleted file mode 100644 index cd102b8e28d..00000000000 --- a/arch/sparc/include/asm/ebus_64.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * ebus.h: PCI to Ebus pseudo driver software state. - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * Copyright (C) 1999 David S. Miller (davem@redhat.com) - */ - -#ifndef __SPARC64_EBUS_H -#define __SPARC64_EBUS_H - -#include - -#include -#include - -struct linux_ebus_child { - struct linux_ebus_child *next; - struct linux_ebus_device *parent; - struct linux_ebus *bus; - struct device_node *prom_node; - struct resource resource[PROMREG_MAX]; - int num_addrs; - unsigned int irqs[PROMINTR_MAX]; - int num_irqs; -}; - -struct linux_ebus_device { - struct of_device ofdev; - struct linux_ebus_device *next; - struct linux_ebus_child *children; - struct linux_ebus *bus; - struct device_node *prom_node; - struct resource resource[PROMREG_MAX]; - int num_addrs; - unsigned int irqs[PROMINTR_MAX]; - int num_irqs; -}; -#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev) - -struct linux_ebus { - struct of_device ofdev; - struct linux_ebus *next; - struct linux_ebus_device *devices; - struct pci_dev *self; - int index; - int is_rio; - struct device_node *prom_node; -}; -#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev) - -extern struct linux_ebus *ebus_chain; - -extern void ebus_init(void); - -#define for_each_ebus(bus) \ - for((bus) = ebus_chain; (bus); (bus) = (bus)->next) - -#define for_each_ebusdev(dev, bus) \ - for((dev) = (bus)->devices; (dev); (dev) = (dev)->next) - -#define for_each_edevchild(dev, child) \ - for((child) = (dev)->children; (child); (child) = (child)->next) - -#endif /* !(__SPARC64_EBUS_H) */ diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index eaf7cf4296a..a430231647e 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_PCI) += pcic.o obj-$(CONFIG_SUN4) += sun4setup.o obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o obj-$(CONFIG_SUN_AUXIO) += auxio.o -obj-$(CONFIG_PCI) += ebus.o obj-$(CONFIG_SUN_PM) += apc.o pmc.o obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o obj-$(CONFIG_SPARC_LED) += led.o diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c deleted file mode 100644 index 7e9397fc608..00000000000 --- a/arch/sparc/kernel/ebus.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * ebus.c: PCI to EBus bridge device. - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - * - * Adopted for sparc by V. Roganov and G. Raiko. - * Fixes for different platforms by Pete Zaitcev. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -struct linux_ebus *ebus_chain = NULL; - -/* We are together with pcic.c under CONFIG_PCI. */ -extern unsigned int pcic_pin_to_irq(unsigned int, const char *name); - -/* - * IRQ Blacklist - * Here we list PROMs and systems that are known to supply crap as IRQ numbers. - */ -struct ebus_device_irq { - char *name; - unsigned int pin; -}; - -struct ebus_system_entry { - char *esname; - struct ebus_device_irq *ipt; -}; - -static struct ebus_device_irq je1_1[] = { - { "8042", 3 }, - { "SUNW,CS4231", 0 }, - { "parallel", 0 }, - { "se", 2 }, - { NULL, 0 } -}; - -/* - * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32). - * Blacklist the sucker... Note that Gleb's system will work. - */ -static struct ebus_system_entry ebus_blacklist[] = { - { "SUNW,JavaEngine1", je1_1 }, - { NULL, NULL } -}; - -static struct ebus_device_irq *ebus_blackp = NULL; - -/* - */ -static inline unsigned long ebus_alloc(size_t size) -{ - return (unsigned long)kmalloc(size, GFP_ATOMIC); -} - -/* - */ -static int __init ebus_blacklist_irq(const char *name) -{ - struct ebus_device_irq *dp; - - if ((dp = ebus_blackp) != NULL) { - for (; dp->name != NULL; dp++) { - if (strcmp(name, dp->name) == 0) { - return pcic_pin_to_irq(dp->pin, name); - } - } - } - return 0; -} - -static void __init fill_ebus_child(struct device_node *dp, - struct linux_ebus_child *dev) -{ - const int *regs; - const int *irqs; - int i, len; - - dev->prom_node = dp; - regs = of_get_property(dp, "reg", &len); - if (!regs) - len = 0; - dev->num_addrs = len / sizeof(regs[0]); - - for (i = 0; i < dev->num_addrs; i++) { - if (regs[i] >= dev->parent->num_addrs) { - prom_printf("UGH: property for %s was %d, need < %d\n", - dev->prom_node->name, len, - dev->parent->num_addrs); - panic(__func__); - } - - /* XXX resource */ - dev->resource[i].start = - dev->parent->resource[regs[i]].start; - } - - for (i = 0; i < PROMINTR_MAX; i++) - dev->irqs[i] = PCI_IRQ_NONE; - - if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) { - dev->num_irqs = 1; - } else { - irqs = of_get_property(dp, "interrupts", &len); - if (!irqs) { - dev->num_irqs = 0; - dev->irqs[0] = 0; - if (dev->parent->num_irqs != 0) { - dev->num_irqs = 1; - dev->irqs[0] = dev->parent->irqs[0]; - } - } else { - dev->num_irqs = len / sizeof(irqs[0]); - if (irqs[0] == 0 || irqs[0] >= 8) { - /* - * XXX Zero is a valid pin number... - * This works as long as Ebus is not wired - * to INTA#. - */ - printk("EBUS: %s got bad irq %d from PROM\n", - dev->prom_node->name, irqs[0]); - dev->num_irqs = 0; - dev->irqs[0] = 0; - } else { - dev->irqs[0] = - pcic_pin_to_irq(irqs[0], - dev->prom_node->name); - } - } - } -} - -static void __init fill_ebus_device(struct device_node *dp, - struct linux_ebus_device *dev) -{ - const struct linux_prom_registers *regs; - struct linux_ebus_child *child; - struct dev_archdata *sd; - const int *irqs; - int i, n, len; - unsigned long baseaddr; - - dev->prom_node = dp; - - regs = of_get_property(dp, "reg", &len); - if (!regs) - len = 0; - if (len % sizeof(struct linux_prom_registers)) { - prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", - dev->prom_node->name, len, - (int)sizeof(struct linux_prom_registers)); - panic(__func__); - } - dev->num_addrs = len / sizeof(struct linux_prom_registers); - - for (i = 0; i < dev->num_addrs; i++) { - /* - * XXX Collect JE-1 PROM - * - * Example - JS-E with 3.11: - * /ebus - * regs - * 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000, - * 0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000, - * 0x82000014, 0x0, 0x38800000, 0x0, 0x00800000, - * ranges - * 0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000, - * 0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000, - * /ebus/8042 - * regs - * 0x00000001, 0x00300060, 0x00000008, - * 0x00000001, 0x00300060, 0x00000008, - */ - n = regs[i].which_io; - if (n >= 4) { - /* XXX This is copied from old JE-1 by Gleb. */ - n = (regs[i].which_io - 0x10) >> 2; - } else { - ; - } - -/* - * XXX Now as we have regions, why don't we make an on-demand allocation... - */ - dev->resource[i].start = 0; - if ((baseaddr = dev->bus->self->resource[n].start + - regs[i].phys_addr) != 0) { - /* dev->resource[i].name = dev->prom_name; */ - if ((baseaddr = (unsigned long) ioremap(baseaddr, - regs[i].reg_size)) == 0) { - panic("ebus: unable to remap dev %s", - dev->prom_node->name); - } - } - dev->resource[i].start = baseaddr; /* XXX Unaligned */ - } - - for (i = 0; i < PROMINTR_MAX; i++) - dev->irqs[i] = PCI_IRQ_NONE; - - if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) { - dev->num_irqs = 1; - } else { - irqs = of_get_property(dp, "interrupts", &len); - if (!irqs) { - dev->num_irqs = 0; - if ((dev->irqs[0] = dev->bus->self->irq) != 0) { - dev->num_irqs = 1; -/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */ - } - } else { - dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */ - if (irqs[0] == 0 || irqs[0] >= 8) { - /* See above for the parent. XXX */ - printk("EBUS: %s got bad irq %d from PROM\n", - dev->prom_node->name, irqs[0]); - dev->num_irqs = 0; - dev->irqs[0] = 0; - } else { - dev->irqs[0] = - pcic_pin_to_irq(irqs[0], - dev->prom_node->name); - } - } - } - - sd = &dev->ofdev.dev.archdata; - sd->prom_node = dp; - sd->op = &dev->ofdev; - sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; - - dev->ofdev.node = dp; - dev->ofdev.dev.parent = &dev->bus->ofdev.dev; - dev->ofdev.dev.bus = &ebus_bus_type; - sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node); - - /* Register with core */ - if (of_device_register(&dev->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); - - if ((dp = dp->child) != NULL) { - dev->children = (struct linux_ebus_child *) - ebus_alloc(sizeof(struct linux_ebus_child)); - - child = dev->children; - child->next = NULL; - child->parent = dev; - child->bus = dev->bus; - fill_ebus_child(dp, child); - - while ((dp = dp->sibling) != NULL) { - child->next = (struct linux_ebus_child *) - ebus_alloc(sizeof(struct linux_ebus_child)); - - child = child->next; - child->next = NULL; - child->parent = dev; - child->bus = dev->bus; - fill_ebus_child(dp, child); - } - } -} - -void __init ebus_init(void) -{ - const struct linux_prom_pci_registers *regs; - struct linux_pbm_info *pbm; - struct linux_ebus_device *dev; - struct linux_ebus *ebus; - struct ebus_system_entry *sp; - struct pci_dev *pdev; - struct pcidev_cookie *cookie; - struct device_node *dp; - struct resource *p; - unsigned short pci_command; - int len, reg, nreg; - int num_ebus = 0; - - dp = of_find_node_by_path("/"); - for (sp = ebus_blacklist; sp->esname != NULL; sp++) { - if (strcmp(dp->name, sp->esname) == 0) { - ebus_blackp = sp->ipt; - break; - } - } - - pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL); - if (!pdev) - return; - - cookie = pdev->sysdata; - dp = cookie->prom_node; - - ebus_chain = ebus = (struct linux_ebus *) - ebus_alloc(sizeof(struct linux_ebus)); - ebus->next = NULL; - - while (dp) { - struct device_node *nd; - - ebus->prom_node = dp; - ebus->self = pdev; - ebus->parent = pbm = cookie->pbm; - - /* Enable BUS Master. */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_command); - pci_command |= PCI_COMMAND_MASTER; - pci_write_config_word(pdev, PCI_COMMAND, pci_command); - - regs = of_get_property(dp, "reg", &len); - if (!regs) { - prom_printf("%s: can't find reg property\n", - __func__); - prom_halt(); - } - nreg = len / sizeof(struct linux_prom_pci_registers); - - p = &ebus->self->resource[0]; - for (reg = 0; reg < nreg; reg++) { - if (!(regs[reg].which_io & 0x03000000)) - continue; - - (p++)->start = regs[reg].phys_lo; - } - - ebus->ofdev.node = dp; - ebus->ofdev.dev.parent = &pdev->dev; - ebus->ofdev.dev.bus = &ebus_bus_type; - sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus); - - /* Register with core */ - if (of_device_register(&ebus->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); - - - nd = dp->child; - if (!nd) - goto next_ebus; - - ebus->devices = (struct linux_ebus_device *) - ebus_alloc(sizeof(struct linux_ebus_device)); - - dev = ebus->devices; - dev->next = NULL; - dev->children = NULL; - dev->bus = ebus; - fill_ebus_device(nd, dev); - - while ((nd = nd->sibling) != NULL) { - dev->next = (struct linux_ebus_device *) - ebus_alloc(sizeof(struct linux_ebus_device)); - - dev = dev->next; - dev->next = NULL; - dev->children = NULL; - dev->bus = ebus; - fill_ebus_device(nd, dev); - } - - next_ebus: - pdev = pci_get_device(PCI_VENDOR_ID_SUN, - PCI_DEVICE_ID_SUN_EBUS, pdev); - if (!pdev) - break; - - cookie = pdev->sysdata; - dp = cookie->prom_node; - - ebus->next = (struct linux_ebus *) - ebus_alloc(sizeof(struct linux_ebus)); - ebus = ebus->next; - ebus->next = NULL; - ++num_ebus; - } - if (pdev) - pci_dev_put(pdev); -} diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index 9a0aa4ec579..e5950b03df1 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -17,7 +17,6 @@ #include #include -#include #include /* for cache flushing. */ #include @@ -429,7 +428,6 @@ static int __init pcic_init(void) pcic_pbm_scan_bus(pcic); - ebus_init(); return 0; } @@ -492,10 +490,6 @@ static void pcic_map_pci_device(struct linux_pcic *pcic, * do ioremap() before accessing PC-style I/O, * we supply virtual, ready to access address. * - * Ebus devices do not come here even if - * CheerIO makes a similar conversion. - * See ebus.c for details. - * * Note that request_region() * works for these devices. * @@ -676,7 +670,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) } /* - * pcic_pin_to_irq() is exported to ebus.c. + * pcic_pin_to_irq() is exported to bus probing code */ unsigned int pcic_pin_to_irq(unsigned int pin, const char *name) diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 50ec48ddef6..6007ac5a736 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -45,9 +45,6 @@ #ifdef CONFIG_SBUS #include #endif -#ifdef CONFIG_PCI -#include -#endif #include #include @@ -152,7 +149,6 @@ EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached)); EXPORT_SYMBOL(sbus_set_sbus64); #endif #ifdef CONFIG_PCI -EXPORT_SYMBOL(ebus_chain); EXPORT_SYMBOL(insb); EXPORT_SYMBOL(outsb); EXPORT_SYMBOL(insw); diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 360a348e5bb..928aa7c8058 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -11,12 +11,12 @@ obj-y := process.o setup.o cpu.o idprom.o \ traps.o auxio.o una_asm.o sysfs.o iommu.o \ irq.o ptrace.o time.o sys_sparc.o signal.o \ unaligned.o central.o starfire.o \ - power.o sbus.o sparc64_ksyms.o \ + power.o sbus.o sparc64_ksyms.o ebus.o \ visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_PCI) += ebus.o pci.o pci_common.o \ +obj-$(CONFIG_PCI) += pci.o pci_common.o \ pci_psycho.o pci_sabre.o pci_schizo.o \ pci_sun4v.o pci_sun4v_asm.o pci_fire.o obj-$(CONFIG_PCI_MSI) += pci_msi.o diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index 88408741c32..77dbf6d45fa 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -1,5 +1,4 @@ -/* - * ebus.c: PCI to EBus bridge device. +/* ebus.c: EBUS DMA library code. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -9,24 +8,12 @@ #include #include #include -#include -#include #include #include -#include -#include -#include -#include -#include #include -#include -#include -#include #include -/* EBUS dma library. */ - #define EBDMA_CSR 0x00UL /* Control/Status */ #define EBDMA_ADDR 0x04UL /* DMA Address */ #define EBDMA_COUNT 0x08UL /* DMA Count */ @@ -268,283 +255,3 @@ void ebus_dma_enable(struct ebus_dma_info *p, int on) spin_unlock_irqrestore(&p->lock, flags); } EXPORT_SYMBOL(ebus_dma_enable); - -struct linux_ebus *ebus_chain = NULL; - -static inline void *ebus_alloc(size_t size) -{ - void *mem; - - mem = kzalloc(size, GFP_ATOMIC); - if (!mem) - panic("ebus_alloc: out of memory"); - return mem; -} - -static void __init fill_ebus_child(struct device_node *dp, - struct linux_ebus_child *dev, - int non_standard_regs) -{ - struct of_device *op; - const int *regs; - int i, len; - - dev->prom_node = dp; - printk(" (%s)", dp->name); - - regs = of_get_property(dp, "reg", &len); - if (!regs) - dev->num_addrs = 0; - else - dev->num_addrs = len / sizeof(regs[0]); - - if (non_standard_regs) { - /* This is to handle reg properties which are not - * in the parent relative format. One example are - * children of the i2c device on CompactPCI systems. - * - * So, for such devices we just record the property - * raw in the child resources. - */ - for (i = 0; i < dev->num_addrs; i++) - dev->resource[i].start = regs[i]; - } else { - for (i = 0; i < dev->num_addrs; i++) { - int rnum = regs[i]; - if (rnum >= dev->parent->num_addrs) { - prom_printf("UGH: property for %s was %d, need < %d\n", - dp->name, len, dev->parent->num_addrs); - prom_halt(); - } - dev->resource[i].start = dev->parent->resource[i].start; - dev->resource[i].end = dev->parent->resource[i].end; - dev->resource[i].flags = IORESOURCE_MEM; - dev->resource[i].name = dp->name; - } - } - - op = of_find_device_by_node(dp); - if (!op) { - dev->num_irqs = 0; - } else { - dev->num_irqs = op->num_irqs; - for (i = 0; i < dev->num_irqs; i++) - dev->irqs[i] = op->irqs[i]; - } - - if (!dev->num_irqs) { - /* - * Oh, well, some PROMs don't export interrupts - * property to children of EBus devices... - * - * Be smart about PS/2 keyboard and mouse. - */ - if (!strcmp(dev->parent->prom_node->name, "8042")) { - if (!strcmp(dev->prom_node->name, "kb_ps2")) { - dev->num_irqs = 1; - dev->irqs[0] = dev->parent->irqs[0]; - } else { - dev->num_irqs = 1; - dev->irqs[0] = dev->parent->irqs[1]; - } - } - } -} - -static int __init child_regs_nonstandard(struct linux_ebus_device *dev) -{ - if (!strcmp(dev->prom_node->name, "i2c") || - !strcmp(dev->prom_node->name, "SUNW,lombus")) - return 1; - return 0; -} - -static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev) -{ - struct linux_ebus_child *child; - struct dev_archdata *sd; - struct of_device *op; - int i, len; - - dev->prom_node = dp; - - printk(" [%s", dp->name); - - op = of_find_device_by_node(dp); - if (!op) { - dev->num_addrs = 0; - dev->num_irqs = 0; - } else { - const int *regs = of_get_property(dp, "reg", &len); - - if (!regs) - len = 0; - dev->num_addrs = len / sizeof(struct linux_prom_registers); - - for (i = 0; i < dev->num_addrs; i++) - memcpy(&dev->resource[i], - &op->resource[i], - sizeof(struct resource)); - - dev->num_irqs = op->num_irqs; - for (i = 0; i < dev->num_irqs; i++) - dev->irqs[i] = op->irqs[i]; - } - - sd = &dev->ofdev.dev.archdata; - sd->prom_node = dp; - sd->op = &dev->ofdev; - sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu; - sd->stc = dev->bus->ofdev.dev.parent->archdata.stc; - sd->numa_node = dev->bus->ofdev.dev.parent->archdata.numa_node; - - dev->ofdev.node = dp; - dev->ofdev.dev.parent = &dev->bus->ofdev.dev; - dev->ofdev.dev.bus = &ebus_bus_type; - dev_set_name(&dev->ofdev.dev, "ebus[%08x]", dp->node); - - /* Register with core */ - if (of_device_register(&dev->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); - - dp = dp->child; - if (dp) { - printk(" ->"); - dev->children = ebus_alloc(sizeof(struct linux_ebus_child)); - - child = dev->children; - child->next = NULL; - child->parent = dev; - child->bus = dev->bus; - fill_ebus_child(dp, child, - child_regs_nonstandard(dev)); - - while ((dp = dp->sibling) != NULL) { - child->next = ebus_alloc(sizeof(struct linux_ebus_child)); - - child = child->next; - child->next = NULL; - child->parent = dev; - child->bus = dev->bus; - fill_ebus_child(dp, child, - child_regs_nonstandard(dev)); - } - } - printk("]"); -} - -static struct pci_dev *find_next_ebus(struct pci_dev *start, int *is_rio_p) -{ - struct pci_dev *pdev = start; - - while ((pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_ANY_ID, pdev))) - if (pdev->device == PCI_DEVICE_ID_SUN_EBUS || - pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS) - break; - - *is_rio_p = !!(pdev && (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS)); - - return pdev; -} - -void __init ebus_init(void) -{ - struct linux_ebus_device *dev; - struct linux_ebus *ebus; - struct pci_dev *pdev; - struct device_node *dp; - int is_rio; - int num_ebus = 0; - - pdev = find_next_ebus(NULL, &is_rio); - if (!pdev) { - printk("ebus: No EBus's found.\n"); - return; - } - - dp = pci_device_to_OF_node(pdev); - - ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); - ebus->next = NULL; - ebus->is_rio = is_rio; - - while (dp) { - struct device_node *child; - - /* SUNW,pci-qfe uses four empty ebuses on it. - I think we should not consider them here, - as they have half of the properties this - code expects and once we do PCI hot-plug, - we'd have to tweak with the ebus_chain - in the runtime after initialization. -jj */ - if (!dp->child) { - pdev = find_next_ebus(pdev, &is_rio); - if (!pdev) { - if (ebus == ebus_chain) { - ebus_chain = NULL; - printk("ebus: No EBus's found.\n"); - return; - } - break; - } - ebus->is_rio = is_rio; - dp = pci_device_to_OF_node(pdev); - continue; - } - printk("ebus%d:", num_ebus); - - ebus->index = num_ebus; - ebus->prom_node = dp; - ebus->self = pdev; - - ebus->ofdev.node = dp; - ebus->ofdev.dev.parent = &pdev->dev; - ebus->ofdev.dev.bus = &ebus_bus_type; - dev_set_name(&ebus->ofdev.dev, "ebus%d", num_ebus); - - /* Register with core */ - if (of_device_register(&ebus->ofdev) != 0) - printk(KERN_DEBUG "ebus: device registration error for %s!\n", - dp->path_component_name); - - - child = dp->child; - if (!child) - goto next_ebus; - - ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); - - dev = ebus->devices; - dev->next = NULL; - dev->children = NULL; - dev->bus = ebus; - fill_ebus_device(child, dev); - - while ((child = child->sibling) != NULL) { - dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); - - dev = dev->next; - dev->next = NULL; - dev->children = NULL; - dev->bus = ebus; - fill_ebus_device(child, dev); - } - - next_ebus: - printk("\n"); - - pdev = find_next_ebus(pdev, &is_rio); - if (!pdev) - break; - - dp = pci_device_to_OF_node(pdev); - - ebus->next = ebus_alloc(sizeof(struct linux_ebus)); - ebus = ebus->next; - ebus->next = NULL; - ebus->is_rio = is_rio; - ++num_ebus; - } - pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */ -} diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 71d423a1c17..218778617ee 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -18,11 +18,12 @@ #include #include #include +#include +#include #include #include #include -#include #include #include @@ -808,7 +809,6 @@ static int __init pcibios_init(void) pci_scan_each_controller_bus(); - ebus_init(); power_init(); return 0; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 4c3a6a87c8a..30bba8b0a3b 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -45,9 +45,6 @@ #ifdef CONFIG_SBUS #include #endif -#ifdef CONFIG_PCI -#include -#endif #include #include #include @@ -165,7 +162,6 @@ EXPORT_SYMBOL(insb); EXPORT_SYMBOL(insw); EXPORT_SYMBOL(insl); #ifdef CONFIG_PCI -EXPORT_SYMBOL(ebus_chain); EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); EXPORT_SYMBOL(pci_map_single); -- cgit v1.2.3-70-g09d2 From c510b9bfa1c34c1452f7a4389ff6de4f72a78193 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 01:18:56 -0700 Subject: sparc64: Don't invoke power_init() from pcibios_init(). That's just silly, use device_initcall() instead. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 4 ---- arch/sparc64/kernel/power.c | 16 +++++----------- 2 files changed, 5 insertions(+), 15 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 218778617ee..83c50a62970 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -799,8 +799,6 @@ static void __init pci_scan_each_controller_bus(void) pbm->scan_bus(pbm); } -extern void power_init(void); - static int __init pcibios_init(void) { pci_controller_probe(); @@ -809,8 +807,6 @@ static int __init pcibios_init(void) pci_scan_each_controller_bus(); - power_init(); - return 0; } diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 3bb987a6d03..7536255ab57 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c @@ -1,29 +1,22 @@ /* power.c: Power management driver. * - * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1999, 2007, 2008 David S. Miller (davem@davemloft.net) */ #include #include #include -#include -#include -#include #include #include -#include #include #include -#include #include #include #include #include #include -#include - /* * sysctl - toggle power-off restriction for serial console * systems in machine_power_off() @@ -111,8 +104,9 @@ static struct of_platform_driver power_driver = { }, }; -void __init power_init(void) +static int __init power_init(void) { - of_register_driver(&power_driver, &of_platform_bus_type); - return; + return of_register_driver(&power_driver, &of_platform_bus_type); } + +device_initcall(power_init); -- cgit v1.2.3-70-g09d2 From 6d19c88f53bb3471a15152ea4fbdbebd36c0046c Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 02:30:24 -0700 Subject: sparc64: Convert SCHIZO PCI controller driver into a real driver. The idea is to convert all of the PCI controller drivers into genuine OF drivers, then we can get rid of this terrible probing table and infrastructure in arch/sparc64/kernel/pci.c Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 15 ++--- arch/sparc64/kernel/pci_schizo.c | 117 ++++++++++++++++++++++++++------------- 2 files changed, 84 insertions(+), 48 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 83c50a62970..73f1d42d486 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -167,9 +167,6 @@ void pci_config_write32(u32 *addr, u32 val) /* Probe for all PCI controllers in the system. */ extern void sabre_init(struct device_node *, const char *); extern void psycho_init(struct device_node *, const char *); -extern void schizo_init(struct device_node *, const char *); -extern void schizo_plus_init(struct device_node *, const char *); -extern void tomatillo_init(struct device_node *, const char *); extern void sun4v_pci_init(struct device_node *, const char *); extern void fire_pci_init(struct device_node *, const char *); @@ -182,12 +179,6 @@ static struct { { "pci108e,a001", sabre_init }, { "SUNW,psycho", psycho_init }, { "pci108e,8000", psycho_init }, - { "SUNW,schizo", schizo_init }, - { "pci108e,8001", schizo_init }, - { "SUNW,schizo+", schizo_plus_init }, - { "pci108e,8002", schizo_plus_init }, - { "SUNW,tomatillo", tomatillo_init }, - { "pci108e,a801", tomatillo_init }, { "SUNW,sun4v-pci", sun4v_pci_init }, { "pciex108e,80f0", fire_pci_init }, }; @@ -795,8 +786,10 @@ static void __init pci_scan_each_controller_bus(void) { struct pci_pbm_info *pbm; - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) - pbm->scan_bus(pbm); + for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { + if (pbm->scan_bus) + pbm->scan_bus(pbm); + } } static int __init pcibios_init(void) diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 9248c6737f0..b95dd548583 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1,6 +1,6 @@ /* pci_schizo.c: SCHIZO/TOMATILLO specific PCI controller support. * - * Copyright (C) 2001, 2002, 2003, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 2001, 2002, 2003, 2007, 2008 David S. Miller (davem@davemloft.net) */ #include @@ -13,14 +13,15 @@ #include #include -#include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" +#define DRIVER_NAME "schizo" +#define PFX DRIVER_NAME ": " + /* All SCHIZO registers are 64-bits. The following accessor * routines are how they are accessed. The REG parameter * is a physical address. @@ -1084,7 +1085,7 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void __init schizo_scan_bus(struct pci_pbm_info *pbm) +static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm) { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = @@ -1187,9 +1188,9 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) break; default: - prom_printf("SCHIZO: strange virtual-dma size.\n"); - prom_halt(); - }; + printk(KERN_ERR PFX "Strange virtual-dma size.\n"); + return -EINVAL; + } /* Register addresses, SCHIZO has iommu ctx flushing. */ iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; @@ -1212,7 +1213,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) tagbase = SCHIZO_IOMMU_TAG, database = SCHIZO_IOMMU_DATA; - for(i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) { schizo_write(pbm->pbm_regs + tagbase + (i * 8UL), 0); schizo_write(pbm->pbm_regs + database + (i * 8UL), 0); } @@ -1222,8 +1223,10 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) */ err = iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask, pbm->numa_node); - if (err) + if (err) { + printk(KERN_ERR PFX "iommu_table_init() fails with %d\n", err); return err; + } schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table)); @@ -1236,7 +1239,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) case 128: control |= SCHIZO_IOMMU_TSBSZ_128K; break; - }; + } control |= SCHIZO_IOMMU_CTRL_ENAB; schizo_write(iommu->iommu_control, control); @@ -1334,9 +1337,9 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } } -static int __init schizo_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 portid, - int chip_type) +static int __devinit schizo_pbm_init(struct pci_controller_info *p, + struct device_node *dp, u32 portid, + int chip_type) { const struct linux_prom64_registers *regs; struct pci_pbm_info *pbm; @@ -1382,7 +1385,6 @@ static int __init schizo_pbm_init(struct pci_controller_info *p, pbm->numa_node = -1; - pbm->scan_bus = schizo_scan_bus; pbm->pci_ops = &sun4u_pci_ops; pbm->config_space_reg_bits = 8; @@ -1420,6 +1422,8 @@ static int __init schizo_pbm_init(struct pci_controller_info *p, schizo_pbm_strbuf_init(pbm); + schizo_scan_bus(pbm); + return 0; } @@ -1433,8 +1437,7 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) return (x == y); } -static void __init __schizo_init(struct device_node *dp, char *model_name, - int chip_type) +static int __devinit __schizo_init(struct device_node *dp, unsigned long chip_type) { struct pci_controller_info *p; struct pci_pbm_info *pbm; @@ -1447,48 +1450,88 @@ static void __init __schizo_init(struct device_node *dp, char *model_name, if (portid_compare(pbm->portid, portid, chip_type)) { if (schizo_pbm_init(pbm->parent, dp, portid, chip_type)) - goto fatal_memory_error; - return; + return -ENOMEM; + return 0; } } p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) - goto fatal_memory_error; + if (!p) { + printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + goto out_free; + } iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); + goto out_free; + } p->pbm_A.iommu = iommu; iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM B iommu.\n"); + goto out_free; + } p->pbm_B.iommu = iommu; if (schizo_pbm_init(p, dp, portid, chip_type)) - goto fatal_memory_error; + goto out_free; - return; + return 0; -fatal_memory_error: - prom_printf("SCHIZO: Fatal memory allocation error.\n"); - prom_halt(); +out_free: + if (p) { + if (p->pbm_A.iommu) + kfree(p->pbm_A.iommu); + if (p->pbm_B.iommu) + kfree(p->pbm_B.iommu); + kfree(p); + } + return -ENOMEM; } -void __init schizo_init(struct device_node *dp, char *model_name) +static int __devinit schizo_probe(struct of_device *op, + const struct of_device_id *match) { - __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO); + return __schizo_init(op->node, (unsigned long) match->data); } -void __init schizo_plus_init(struct device_node *dp, char *model_name) -{ - __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); -} +/* The ordering of this table is very important. Some Tomatillo + * nodes announce that they are compatible with both pci108e,a801 + * and pci108e,8001. So list the chips in reverse chronological + * order. + */ +static struct of_device_id schizo_match[] = { + { + .name = "pci", + .compatible = "pci108e,a801", + .data = (void *) PBM_CHIP_TYPE_TOMATILLO, + }, + { + .name = "pci", + .compatible = "pci108e,8002", + .data = (void *) PBM_CHIP_TYPE_SCHIZO_PLUS, + }, + { + .name = "pci", + .compatible = "pci108e,8001", + .data = (void *) PBM_CHIP_TYPE_SCHIZO, + }, + {}, +}; -void __init tomatillo_init(struct device_node *dp, char *model_name) +static struct of_platform_driver schizo_driver = { + .name = DRIVER_NAME, + .match_table = schizo_match, + .probe = schizo_probe, +}; + +static int __init schizo_init(void) { - __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO); + return of_register_driver(&schizo_driver, &of_bus_type); } + +subsys_initcall(schizo_init); -- cgit v1.2.3-70-g09d2 From 3822b50964d6702b7d8ba18ffd132d4bf786a17e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 02:50:29 -0700 Subject: sparc64: Convert SUN4V PCI controller driver into a real driver. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 2 - arch/sparc64/kernel/pci_sun4v.c | 123 +++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 42 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 73f1d42d486..445f5882546 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -167,7 +167,6 @@ void pci_config_write32(u32 *addr, u32 val) /* Probe for all PCI controllers in the system. */ extern void sabre_init(struct device_node *, const char *); extern void psycho_init(struct device_node *, const char *); -extern void sun4v_pci_init(struct device_node *, const char *); extern void fire_pci_init(struct device_node *, const char *); static struct { @@ -179,7 +178,6 @@ static struct { { "pci108e,a001", sabre_init }, { "SUNW,psycho", psycho_init }, { "pci108e,8000", psycho_init }, - { "SUNW,sun4v-pci", sun4v_pci_init }, { "pciex108e,80f0", fire_pci_init }, }; #define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table) diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index a104c80d319..c1e72beade2 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -13,12 +13,10 @@ #include #include #include +#include #include #include -#include -#include -#include #include #include @@ -27,6 +25,9 @@ #include "pci_sun4v.h" +#define DRIVER_NAME "pci_sun4v" +#define PFX DRIVER_NAME ": " + static unsigned long vpci_major = 1; static unsigned long vpci_minor = 1; @@ -583,7 +584,7 @@ static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm, return cnt; } -static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) +static int __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) { struct iommu *iommu = pbm->iommu; struct property *prop; @@ -603,9 +604,9 @@ static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) } if ((vdma[0] | vdma[1]) & ~IO_PAGE_MASK) { - prom_printf("PCI-SUN4V: strange virtual-dma[%08x:%08x].\n", - vdma[0], vdma[1]); - prom_halt(); + printk(KERN_ERR PFX "Strange virtual-dma[%08x:%08x].\n", + vdma[0], vdma[1]); + return -EINVAL; }; dma_mask = (roundup_pow_of_two(vdma[1]) - 1UL); @@ -625,8 +626,8 @@ static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) sz = (sz + 7UL) & ~7UL; iommu->arena.map = kzalloc(sz, GFP_KERNEL); if (!iommu->arena.map) { - prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n"); - prom_halt(); + printk(KERN_ERR PFX "Error, kmalloc(arena.map) failed.\n"); + return -ENOMEM; } iommu->arena.limit = num_tsb_entries; @@ -634,6 +635,8 @@ static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) if (sz) printk("%s: Imported %lu TSB entries from OBP\n", pbm->name, sz); + + return 0; } #ifdef CONFIG_PCI_MSI @@ -890,10 +893,11 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) } #endif /* !(CONFIG_PCI_MSI) */ -static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 devhandle) +static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, + struct device_node *dp, u32 devhandle) { struct pci_pbm_info *pbm; + int err; if (devhandle & 0x40) pbm = &p->pbm_B; @@ -905,7 +909,6 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, pbm->numa_node = of_node_to_nid(dp); - pbm->scan_bus = pci_sun4v_scan_bus; pbm->pci_ops = &sun4v_pci_ops; pbm->config_space_reg_bits = 12; @@ -924,50 +927,58 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p, pci_determine_mem_io_space(pbm); pci_get_pbm_props(pbm); - pci_sun4v_iommu_init(pbm); + + err = pci_sun4v_iommu_init(pbm); + if (err) + return err; + pci_sun4v_msi_init(pbm); + + pci_sun4v_scan_bus(pbm); + + return 0; } -void __init sun4v_pci_init(struct device_node *dp, char *model_name) +static int __devinit pci_sun4v_probe(struct of_device *op, + const struct of_device_id *match) { + const struct linux_prom64_registers *regs; static int hvapi_negotiated = 0; struct pci_controller_info *p; struct pci_pbm_info *pbm; + struct device_node *dp; struct iommu *iommu; - struct property *prop; - struct linux_prom64_registers *regs; u32 devhandle; int i; + dp = op->node; + if (!hvapi_negotiated++) { int err = sun4v_hvapi_register(HV_GRP_PCI, vpci_major, &vpci_minor); if (err) { - prom_printf("SUN4V_PCI: Could not register hvapi, " - "err=%d\n", err); - prom_halt(); + printk(KERN_ERR PFX "Could not register hvapi, " + "err=%d\n", err); + return err; } - printk("SUN4V_PCI: Registered hvapi major[%lu] minor[%lu]\n", + printk(KERN_INFO PFX "Registered hvapi major[%lu] minor[%lu]\n", vpci_major, vpci_minor); dma_ops = &sun4v_dma_ops; } - prop = of_find_property(dp, "reg", NULL); - if (!prop) { - prom_printf("SUN4V_PCI: Could not find config registers\n"); - prom_halt(); + regs = of_get_property(dp, "reg", NULL); + if (!regs) { + printk(KERN_ERR PFX "Could not find config registers\n"); + return -ENODEV; } - regs = prop->value; - devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { if (pbm->devhandle == (devhandle ^ 0x40)) { - pci_sun4v_pbm_init(pbm->parent, dp, devhandle); - return; + return pci_sun4v_pbm_init(pbm->parent, dp, devhandle); } } @@ -975,31 +986,63 @@ void __init sun4v_pci_init(struct device_node *dp, char *model_name) unsigned long page = get_zeroed_page(GFP_ATOMIC); if (!page) - goto fatal_memory_error; + return -ENOMEM; per_cpu(iommu_batch, i).pglist = (u64 *) page; } p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) - goto fatal_memory_error; + if (!p) { + printk(KERN_ERR PFX "Could not allocate pci_controller_info\n"); + goto out_free; + } iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Could not allocate pbm A iommu\n"); + goto out_free; + } p->pbm_A.iommu = iommu; iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Could not allocate pbm B iommu\n"); + goto out_free; + } p->pbm_B.iommu = iommu; - pci_sun4v_pbm_init(p, dp, devhandle); - return; + return pci_sun4v_pbm_init(p, dp, devhandle); -fatal_memory_error: - prom_printf("SUN4V_PCI: Fatal memory allocation error.\n"); - prom_halt(); +out_free: + if (p) { + if (p->pbm_A.iommu) + kfree(p->pbm_A.iommu); + if (p->pbm_B.iommu) + kfree(p->pbm_B.iommu); + kfree(p); + } + return -ENOMEM; } + +static struct of_device_id pci_sun4v_match[] = { + { + .name = "pci", + .compatible = "SUNW,sun4v-pci", + }, + {}, +}; + +static struct of_platform_driver pci_sun4v_driver = { + .name = DRIVER_NAME, + .match_table = pci_sun4v_match, + .probe = pci_sun4v_probe, +}; + +static int __init pci_sun4v_init(void) +{ + return of_register_driver(&pci_sun4v_driver, &of_bus_type); +} + +subsys_initcall(pci_sun4v_init); -- cgit v1.2.3-70-g09d2 From b20bfe41badcbf38512fbe1118fe2e0817098e77 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 03:13:20 -0700 Subject: sparc64: Convert PSYCHO PCI controller driver into a real driver. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 3 -- arch/sparc64/kernel/pci_psycho.c | 95 +++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 28 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 445f5882546..c66c9bbc975 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -166,7 +166,6 @@ void pci_config_write32(u32 *addr, u32 val) /* Probe for all PCI controllers in the system. */ extern void sabre_init(struct device_node *, const char *); -extern void psycho_init(struct device_node *, const char *); extern void fire_pci_init(struct device_node *, const char *); static struct { @@ -176,8 +175,6 @@ static struct { { "SUNW,sabre", sabre_init }, { "pci108e,a000", sabre_init }, { "pci108e,a001", sabre_init }, - { "SUNW,psycho", psycho_init }, - { "pci108e,8000", psycho_init }, { "pciex108e,80f0", fire_pci_init }, }; #define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table) diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index ef5fe29202c..4e8f87aad20 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -17,11 +17,13 @@ #include #include #include -#include #include "pci_impl.h" #include "iommu_common.h" +#define DRIVER_NAME "psycho" +#define PFX DRIVER_NAME ": " + /* All PSYCHO registers are 64-bits. The following accessor * routines are how they are accessed. The REG parameter * is a physical address. @@ -840,7 +842,7 @@ static int psycho_iommu_init(struct pci_pbm_info *pbm) control = psycho_read(pbm->controller_regs + PSYCHO_IOMMU_CONTROL); control |= PSYCHO_IOMMU_CTRL_DENAB; psycho_write(pbm->controller_regs + PSYCHO_IOMMU_CONTROL, control); - for(i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) { psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TAG + (i * 8UL), 0); psycho_write(pbm->controller_regs + PSYCHO_IOMMU_DATA + (i * 8UL), 0); } @@ -850,8 +852,10 @@ static int psycho_iommu_init(struct pci_pbm_info *pbm) */ err = iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff, pbm->numa_node); - if (err) + if (err) { + printk(KERN_ERR PFX "iommu_table_init() fails\n"); return err; + } psycho_write(pbm->controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(iommu->page_table)); @@ -982,7 +986,6 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, pbm->numa_node = -1; - pbm->scan_bus = psycho_scan_bus; pbm->pci_ops = &sun4u_pci_ops; pbm->config_space_reg_bits = 8; @@ -1002,7 +1005,7 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, pbm->prom_node = dp; pbm->name = dp->full_name; - printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n", + printk(KERN_INFO "%s: PSYCHO PCI Bus Module ver[%x:%x]\n", pbm->name, pbm->chip_version, pbm->chip_revision); @@ -1011,24 +1014,28 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, pci_get_pbm_props(pbm); psycho_pbm_strbuf_init(pbm, is_pbm_a); + + psycho_scan_bus(pbm); } #define PSYCHO_CONFIGSPACE 0x001000000UL -void __init psycho_init(struct device_node *dp, char *model_name) +static int __devinit psycho_probe(struct of_device *op, + const struct of_device_id *match) { - struct linux_prom64_registers *pr_regs; + const struct linux_prom64_registers *pr_regs; + struct device_node *dp = op->node; struct pci_controller_info *p; struct pci_pbm_info *pbm; struct iommu *iommu; - struct property *prop; + int is_pbm_a, err; + const u32 *p32; u32 upa_portid; - int is_pbm_a; upa_portid = 0xff; - prop = of_find_property(dp, "upa-portid", NULL); - if (prop) - upa_portid = *(u32 *) prop->value; + p32 = of_get_property(dp, "upa-portid", NULL); + if (p32) + upa_portid = *p32; for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { struct pci_controller_info *p = pbm->parent; @@ -1036,24 +1043,34 @@ void __init psycho_init(struct device_node *dp, char *model_name) if (p->pbm_A.portid == upa_portid) { is_pbm_a = (p->pbm_A.prom_node == NULL); psycho_pbm_init(p, dp, is_pbm_a); - return; + return 0; } } + err = -ENOMEM; p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) - goto fatal_memory_error; + if (!p) { + printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + goto out_free; + } + iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); + goto out_free; + } p->pbm_A.iommu = p->pbm_B.iommu = iommu; p->pbm_A.portid = upa_portid; p->pbm_B.portid = upa_portid; - prop = of_find_property(dp, "reg", NULL); - pr_regs = prop->value; + pr_regs = of_get_property(dp, "reg", NULL); + err = -ENODEV; + if (!pr_regs) { + printk(KERN_ERR PFX "No reg property.\n"); + goto out_free; + } p->pbm_A.controller_regs = pr_regs[2].phys_addr; p->pbm_B.controller_regs = pr_regs[2].phys_addr; @@ -1063,14 +1080,42 @@ void __init psycho_init(struct device_node *dp, char *model_name) psycho_controller_hwinit(&p->pbm_A); - if (psycho_iommu_init(&p->pbm_A)) - goto fatal_memory_error; + err = psycho_iommu_init(&p->pbm_A); + if (err) + goto out_free; is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); + psycho_pbm_init(p, dp, is_pbm_a); - return; -fatal_memory_error: - prom_printf("PSYCHO: Fatal memory allocation error.\n"); - prom_halt(); + return 0; + +out_free: + if (p) { + if (p->pbm_A.iommu) + kfree(p->pbm_A.iommu); + kfree(p); + } + return err; +} + +static struct of_device_id psycho_match[] = { + { + .name = "pci", + .compatible = "pci108e,8000", + }, + {}, +}; + +static struct of_platform_driver psycho_driver = { + .name = DRIVER_NAME, + .match_table = psycho_match, + .probe = psycho_probe, +}; + +static int __init psycho_init(void) +{ + return of_register_driver(&psycho_driver, &of_bus_type); } + +subsys_initcall(psycho_init); -- cgit v1.2.3-70-g09d2 From edbe805b2b1044659e0727136213bdf42bd1b9d0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 03:14:01 -0700 Subject: sparc64: Convert SABRE PCI controller driver into a real driver. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 4 -- arch/sparc64/kernel/pci_sabre.c | 126 +++++++++++++++++++++++++++------------- 2 files changed, 85 insertions(+), 45 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index c66c9bbc975..c2ff2de4da5 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -165,16 +165,12 @@ void pci_config_write32(u32 *addr, u32 val) } /* Probe for all PCI controllers in the system. */ -extern void sabre_init(struct device_node *, const char *); extern void fire_pci_init(struct device_node *, const char *); static struct { char *model_name; void (*init)(struct device_node *, const char *); } pci_controller_table[] __initdata = { - { "SUNW,sabre", sabre_init }, - { "pci108e,a000", sabre_init }, - { "pci108e,a001", sabre_init }, { "pciex108e,80f0", fire_pci_init }, }; #define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table) diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index ade5184e75d..7cce4d8f4aa 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -16,13 +16,14 @@ #include #include #include -#include -#include #include #include "pci_impl.h" #include "iommu_common.h" +#define DRIVER_NAME "sabre" +#define PFX DRIVER_NAME ": " + /* All SABRE registers are 64-bits. The following accessor * routines are how they are accessed. The REG parameter * is a physical address. @@ -656,8 +657,8 @@ static void __init sabre_scan_bus(struct pci_pbm_info *pbm) * to live at bus 0. */ if (once != 0) { - prom_printf("SABRE: Multiple controllers unsupported.\n"); - prom_halt(); + printk(KERN_ERR PFX "Multiple controllers unsupported.\n"); + return; } once++; @@ -705,8 +706,10 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm, */ err = iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask, pbm->numa_node); - if (err) + if (err) { + printk(KERN_ERR PFX "iommu_table_init() failed\n"); return err; + } sabre_write(pbm->controller_regs + SABRE_IOMMU_TSBBASE, __pa(iommu->page_table)); @@ -722,9 +725,8 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm, control |= SABRE_IOMMU_TSBSZ_128K; break; default: - prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize); - prom_halt(); - break; + printk(KERN_ERR PFX "Illegal TSB size %d\n", tsbsize); + return -EINVAL; } sabre_write(pbm->controller_regs + SABRE_IOMMU_CONTROL, control); @@ -739,7 +741,6 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, pbm->numa_node = -1; - pbm->scan_bus = sabre_scan_bus; pbm->pci_ops = &sun4u_pci_ops; pbm->config_space_reg_bits = 8; @@ -751,46 +752,49 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, pci_get_pbm_props(pbm); pci_determine_mem_io_space(pbm); + + sabre_scan_bus(pbm); } -void __init sabre_init(struct device_node *dp, char *model_name) +static int __devinit sabre_probe(struct of_device *op, + const struct of_device_id *match) { const struct linux_prom64_registers *pr_regs; + struct device_node *dp = op->node; struct pci_controller_info *p; struct pci_pbm_info *pbm; + u32 upa_portid, dma_mask; struct iommu *iommu; - int tsbsize; + int tsbsize, err; const u32 *vdma; - u32 upa_portid, dma_mask; u64 clear_irq; - hummingbird_p = 0; - if (!strcmp(model_name, "pci108e,a001")) - hummingbird_p = 1; - else if (!strcmp(model_name, "SUNW,sabre")) { - const char *compat = of_get_property(dp, "compatible", NULL); - if (compat && !strcmp(compat, "pci108e,a001")) - hummingbird_p = 1; - if (!hummingbird_p) { - struct device_node *dp; - - /* Of course, Sun has to encode things a thousand - * different ways, inconsistently. - */ - for_each_node_by_type(dp, "cpu") { - if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe")) - hummingbird_p = 1; - } + hummingbird_p = (match->data != NULL); + if (!hummingbird_p) { + struct device_node *cpu_dp; + + /* Of course, Sun has to encode things a thousand + * different ways, inconsistently. + */ + for_each_node_by_type(cpu_dp, "cpu") { + if (!strcmp(cpu_dp->name, "SUNW,UltraSPARC-IIe")) + hummingbird_p = 1; } } + err = -ENOMEM; p = kzalloc(sizeof(*p), GFP_ATOMIC); - if (!p) - goto fatal_memory_error; + if (!p) { + printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + goto out_free; + } iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); + goto out_free; + } + pbm = &p->pbm_A; pbm->iommu = iommu; @@ -806,6 +810,11 @@ void __init sabre_init(struct device_node *dp, char *model_name) */ pr_regs = of_get_property(dp, "reg", NULL); + err = -ENODEV; + if (!pr_regs) { + printk(KERN_ERR PFX "No reg property\n"); + goto out_free; + } /* * First REG in property is base of entire SABRE register space. @@ -832,6 +841,10 @@ void __init sabre_init(struct device_node *dp, char *model_name) (pbm->controller_regs + SABRE_CONFIGSPACE); vdma = of_get_property(dp, "virtual-dma", NULL); + if (!vdma) { + printk(KERN_ERR PFX "No virtual-dma property\n"); + goto out_free; + } dma_mask = vdma[0]; switch(vdma[1]) { @@ -849,20 +862,51 @@ void __init sabre_init(struct device_node *dp, char *model_name) tsbsize = 128; break; default: - prom_printf("SABRE: strange virtual-dma size.\n"); - prom_halt(); + printk(KERN_ERR PFX "Strange virtual-dma size.\n"); + goto out_free; } - if (sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask)) - goto fatal_memory_error; + err = sabre_iommu_init(pbm, tsbsize, vdma[0], dma_mask); + if (err) + goto out_free; /* * Look for APB underneath. */ sabre_pbm_init(p, pbm, dp); - return; + return 0; -fatal_memory_error: - prom_printf("SABRE: Fatal memory allocation error.\n"); - prom_halt(); +out_free: + if (p) { + if (p->pbm_A.iommu) + kfree(p->pbm_A.iommu); + kfree(p); + } + return err; } + +static struct of_device_id sabre_match[] = { + { + .name = "pci", + .compatible = "pci108e,a001", + .data = (void *) 1, + }, + { + .name = "pci", + .compatible = "pci108e,a000", + }, + {}, +}; + +static struct of_platform_driver sabre_driver = { + .name = DRIVER_NAME, + .match_table = sabre_match, + .probe = sabre_probe, +}; + +static int __init sabre_init(void) +{ + return of_register_driver(&sabre_driver, &of_bus_type); +} + +subsys_initcall(sabre_init); -- cgit v1.2.3-70-g09d2 From c8049966b7f903ce61e94efbbddf581cf8860b85 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 30 Aug 2008 03:12:38 -0700 Subject: sparc64: Convert FIRE PCI controller driver into a real driver. And now all the by-hand PCI controller probing junk in pci.c can die too. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 96 ------------------------------------------ arch/sparc64/kernel/pci_fire.c | 80 +++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 118 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index c2ff2de4da5..2da32e4c985 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -164,79 +164,6 @@ void pci_config_write32(u32 *addr, u32 val) spin_unlock_irqrestore(&pci_poke_lock, flags); } -/* Probe for all PCI controllers in the system. */ -extern void fire_pci_init(struct device_node *, const char *); - -static struct { - char *model_name; - void (*init)(struct device_node *, const char *); -} pci_controller_table[] __initdata = { - { "pciex108e,80f0", fire_pci_init }, -}; -#define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table) - -static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp) -{ - int i; - - for (i = 0; i < PCI_NUM_CONTROLLER_TYPES; i++) { - if (!strncmp(model_name, - pci_controller_table[i].model_name, - namelen)) { - pci_controller_table[i].init(dp, model_name); - return 1; - } - } - - return 0; -} - -static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *)) -{ - struct device_node *dp; - int count = 0; - - for_each_node_by_name(dp, "pci") { - struct property *prop; - int len; - - prop = of_find_property(dp, "model", &len); - if (!prop) - prop = of_find_property(dp, "compatible", &len); - - if (prop) { - const char *model = prop->value; - int item_len = 0; - - /* Our value may be a multi-valued string in the - * case of some compatible properties. For sanity, - * only try the first one. - */ - while (model[item_len] && len) { - len--; - item_len++; - } - - if (handler(model, item_len, dp)) - count++; - } - } - - return count; -} - -/* Find each controller in the system, attach and initialize - * software state structure for each and link into the - * pci_pbm_root. Setup the controller enough such - * that bus scanning can be done. - */ -static void __init pci_controller_probe(void) -{ - printk("PCI: Probing for controllers.\n"); - - pci_controller_scan(pci_controller_init); -} - static int ofpci_verbose; static int __init ofpci_debug(char *str) @@ -773,29 +700,6 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) return bus; } -static void __init pci_scan_each_controller_bus(void) -{ - struct pci_pbm_info *pbm; - - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - if (pbm->scan_bus) - pbm->scan_bus(pbm); - } -} - -static int __init pcibios_init(void) -{ - pci_controller_probe(); - if (pci_pbm_root == NULL) - return 0; - - pci_scan_each_controller_bus(); - - return 0; -} - -subsys_initcall(pcibios_init); - void __devinit pcibios_fixup_bus(struct pci_bus *pbus) { struct pci_pbm_info *pbm = pbus->sysdata; diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index d23bb6f53cd..adc3fe44b08 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c @@ -8,13 +8,16 @@ #include #include #include +#include -#include #include #include #include "pci_impl.h" +#define DRIVER_NAME "fire" +#define PFX DRIVER_NAME ": " + #define fire_read(__reg) \ ({ u64 __ret; \ __asm__ __volatile__("ldxa [%1] %2, %0" \ @@ -452,7 +455,6 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, pbm->numa_node = -1; - pbm->scan_bus = pci_fire_scan_bus; pbm->pci_ops = &sun4u_pci_ops; pbm->config_space_reg_bits = 12; @@ -481,6 +483,8 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, pci_fire_msi_init(pbm); + pci_fire_scan_bus(pbm); + return 0; } @@ -491,43 +495,75 @@ static inline int portid_compare(u32 x, u32 y) return 0; } -void __init fire_pci_init(struct device_node *dp, const char *model_name) +static int __devinit fire_probe(struct of_device *op, + const struct of_device_id *match) { + struct device_node *dp = op->node; struct pci_controller_info *p; - u32 portid = of_getintprop_default(dp, "portid", 0xff); - struct iommu *iommu; struct pci_pbm_info *pbm; + struct iommu *iommu; + u32 portid; + int err; + portid = of_getintprop_default(dp, "portid", 0xff); for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - if (portid_compare(pbm->portid, portid)) { - if (pci_fire_pbm_init(pbm->parent, dp, portid)) - goto fatal_memory_error; - return; - } + if (portid_compare(pbm->portid, portid)) + return pci_fire_pbm_init(pbm->parent, dp, portid); } + err = -ENOMEM; p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) - goto fatal_memory_error; + if (!p) { + printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + goto out_free; + } iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); + goto out_free; + } p->pbm_A.iommu = iommu; iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) - goto fatal_memory_error; + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); + goto out_free; + } p->pbm_B.iommu = iommu; - if (pci_fire_pbm_init(p, dp, portid)) - goto fatal_memory_error; + return pci_fire_pbm_init(p, dp, portid); - return; +out_free: + if (p) { + if (p->pbm_A.iommu) + kfree(p->pbm_A.iommu); + if (p->pbm_B.iommu) + kfree(p->pbm_B.iommu); + kfree(p); + } + return err; +} + +static struct of_device_id fire_match[] = { + { + .name = "pci", + .compatible = "pciex108e,80f0", + }, + {}, +}; -fatal_memory_error: - prom_printf("PCI_FIRE: Fatal memory allocation error.\n"); - prom_halt(); +static struct of_platform_driver fire_driver = { + .name = DRIVER_NAME, + .match_table = fire_match, + .probe = fire_probe, +}; + +static int __init fire_init(void) +{ + return of_register_driver(&fire_driver, &of_bus_type); } + +subsys_initcall(fire_init); -- cgit v1.2.3-70-g09d2 From e822358ac24550d889895d5866797ae8c9b188c2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 1 Sep 2008 18:32:22 -0700 Subject: sparc64: Pass proper parent device down into root pci_create_bus() call. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 6 +++--- arch/sparc64/kernel/pci_fire.c | 18 +++++++----------- arch/sparc64/kernel/pci_psycho.c | 14 ++++++++------ arch/sparc64/kernel/pci_sabre.c | 13 ++++++++----- arch/sparc64/kernel/pci_schizo.c | 19 +++++++++++-------- arch/sparc64/kernel/pci_sun4v.c | 14 ++++++++------ 6 files changed, 45 insertions(+), 39 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 2da32e4c985..8e18fdf32a6 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -673,15 +673,15 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } -struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm) +struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, + struct device *parent) { struct device_node *node = pbm->prom_node; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); - /* XXX parent device? XXX */ - bus = pci_create_bus(NULL, pbm->pci_first_busno, pbm->pci_ops, pbm); + bus = pci_create_bus(parent, pbm->pci_first_busno, pbm->pci_ops, pbm); if (!bus) { printk(KERN_ERR "Failed to create bus for %s\n", node->full_name); diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 4fb1ef92cb1..1b44153f907 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c @@ -33,13 +33,6 @@ "i" (ASI_PHYS_BYPASS_EC_E) \ : "memory") -static void __init pci_fire_scan_bus(struct pci_pbm_info *pbm) -{ - pbm->pci_bus = pci_scan_one_pbm(pbm); - - /* XXX register error interrupt handlers XXX */ -} - #define FIRE_IOMMU_CONTROL 0x40000UL #define FIRE_IOMMU_TSBBASE 0x40008UL #define FIRE_IOMMU_FLUSH 0x40100UL @@ -439,9 +432,10 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) } static int __init pci_fire_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 portid) + struct of_device *op, u32 portid) { const struct linux_prom64_registers *regs; + struct device_node *dp = op->node; struct pci_pbm_info *pbm; int err; @@ -483,7 +477,9 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, pci_fire_msi_init(pbm); - pci_fire_scan_bus(pbm); + pbm->pci_bus = pci_scan_one_pbm(pbm, &op->dev); + + /* XXX register error interrupt handlers XXX */ return 0; } @@ -508,7 +504,7 @@ static int __devinit fire_probe(struct of_device *op, portid = of_getintprop_default(dp, "portid", 0xff); for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { if (portid_compare(pbm->portid, portid)) - return pci_fire_pbm_init(pbm->parent, dp, portid); + return pci_fire_pbm_init(pbm->parent, op, portid); } err = -ENOMEM; @@ -534,7 +530,7 @@ static int __devinit fire_probe(struct of_device *op, p->pbm_B.iommu = iommu; - return pci_fire_pbm_init(p, dp, portid); + return pci_fire_pbm_init(p, op, portid); out_free_iommu_A: kfree(p->pbm_A.iommu); diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 5ee84c5b963..47db875d023 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -803,11 +803,12 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void __init psycho_scan_bus(struct pci_pbm_info *pbm) +static void __init psycho_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = 0; - pbm->pci_bus = pci_scan_one_pbm(pbm); + pbm->pci_bus = pci_scan_one_pbm(pbm, parent); /* After the PCI bus scan is complete, we can register * the error interrupt handlers. @@ -971,8 +972,9 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL static void __init psycho_pbm_init(struct pci_controller_info *p, - struct device_node *dp, int is_pbm_a) + struct of_device *op, int is_pbm_a) { + struct device_node *dp = op->node; struct property *prop; struct pci_pbm_info *pbm; @@ -1015,7 +1017,7 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, psycho_pbm_strbuf_init(pbm, is_pbm_a); - psycho_scan_bus(pbm); + psycho_scan_bus(pbm, &op->dev); } #define PSYCHO_CONFIGSPACE 0x001000000UL @@ -1042,7 +1044,7 @@ static int __devinit psycho_probe(struct of_device *op, if (p->pbm_A.portid == upa_portid) { is_pbm_a = (p->pbm_A.prom_node == NULL); - psycho_pbm_init(p, dp, is_pbm_a); + psycho_pbm_init(p, op, is_pbm_a); return 0; } } @@ -1086,7 +1088,7 @@ static int __devinit psycho_probe(struct of_device *op, is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); - psycho_pbm_init(p, dp, is_pbm_a); + psycho_pbm_init(p, op, is_pbm_a); return 0; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index eee8fdca382..707d6d6130f 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -634,7 +634,8 @@ static void apb_init(struct pci_bus *sabre_bus) } } -static void __init sabre_scan_bus(struct pci_pbm_info *pbm) +static void __init sabre_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { static int once; @@ -662,7 +663,7 @@ static void __init sabre_scan_bus(struct pci_pbm_info *pbm) } once++; - pbm->pci_bus = pci_scan_one_pbm(pbm); + pbm->pci_bus = pci_scan_one_pbm(pbm, parent); if (!pbm->pci_bus) return; @@ -734,8 +735,10 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm, } static void __init sabre_pbm_init(struct pci_controller_info *p, - struct pci_pbm_info *pbm, struct device_node *dp) + struct pci_pbm_info *pbm, struct of_device *op) { + struct device_node *dp = op->node; + pbm->name = dp->full_name; printk("%s: SABRE PCI Bus Module\n", pbm->name); @@ -753,7 +756,7 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, pci_determine_mem_io_space(pbm); - sabre_scan_bus(pbm); + sabre_scan_bus(pbm, &op->dev); } static int __devinit sabre_probe(struct of_device *op, @@ -873,7 +876,7 @@ static int __devinit sabre_probe(struct of_device *op, /* * Look for APB underneath. */ - sabre_pbm_init(p, pbm, dp); + sabre_pbm_init(p, pbm, op); return 0; out_free_iommu: diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index bd7612aae17..64904b180f4 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1085,14 +1085,15 @@ static void pbm_config_busmastering(struct pci_pbm_info *pbm) pci_config_write8(addr, 64); } -static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm) +static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = (of_find_property(pbm->prom_node, "66mhz-capable", NULL) != NULL); - pbm->pci_bus = pci_scan_one_pbm(pbm); + pbm->pci_bus = pci_scan_one_pbm(pbm, parent); if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) tomatillo_register_error_handlers(pbm); @@ -1338,10 +1339,11 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } static int __devinit schizo_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 portid, + struct of_device *op, u32 portid, int chip_type) { const struct linux_prom64_registers *regs; + struct device_node *dp = op->node; struct pci_pbm_info *pbm; const char *chipset_name; int is_pbm_a, err; @@ -1422,7 +1424,7 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p, schizo_pbm_strbuf_init(pbm); - schizo_scan_bus(pbm); + schizo_scan_bus(pbm, &op->dev); return 0; } @@ -1437,8 +1439,9 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) return (x == y); } -static int __devinit __schizo_init(struct device_node *dp, unsigned long chip_type) +static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) { + struct device_node *dp = op->node; struct pci_controller_info *p; struct pci_pbm_info *pbm; struct iommu *iommu; @@ -1450,7 +1453,7 @@ static int __devinit __schizo_init(struct device_node *dp, unsigned long chip_ty err = -ENOMEM; for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { if (portid_compare(pbm->portid, portid, chip_type)) { - if (schizo_pbm_init(pbm->parent, dp, + if (schizo_pbm_init(pbm->parent, op, portid, chip_type)) goto out_err; return 0; @@ -1479,7 +1482,7 @@ static int __devinit __schizo_init(struct device_node *dp, unsigned long chip_ty p->pbm_B.iommu = iommu; - if (schizo_pbm_init(p, dp, portid, chip_type)) + if (schizo_pbm_init(p, op, portid, chip_type)) goto out_free_iommu_B; return 0; @@ -1500,7 +1503,7 @@ out_err: static int __devinit schizo_probe(struct of_device *op, const struct of_device_id *match) { - return __schizo_init(op->node, (unsigned long) match->data); + return __schizo_init(op, (unsigned long) match->data); } /* The ordering of this table is very important. Some Tomatillo diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 21864f06532..4839c503c88 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -543,7 +543,8 @@ static const struct dma_ops sun4v_dma_ops = { .sync_sg_for_cpu = dma_4v_sync_sg_for_cpu, }; -static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm) +static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm, + struct device *parent) { struct property *prop; struct device_node *dp; @@ -551,7 +552,7 @@ static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm) dp = pbm->prom_node; prop = of_find_property(dp, "66mhz-capable", NULL); pbm->is_66mhz_capable = (prop != NULL); - pbm->pci_bus = pci_scan_one_pbm(pbm); + pbm->pci_bus = pci_scan_one_pbm(pbm, parent); /* XXX register error interrupt handlers XXX */ } @@ -894,8 +895,9 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) #endif /* !(CONFIG_PCI_MSI) */ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, - struct device_node *dp, u32 devhandle) + struct of_device *op, u32 devhandle) { + struct device_node *dp = op->node; struct pci_pbm_info *pbm; int err; @@ -934,7 +936,7 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, pci_sun4v_msi_init(pbm); - pci_sun4v_scan_bus(pbm); + pci_sun4v_scan_bus(pbm, &op->dev); return 0; } @@ -979,7 +981,7 @@ static int __devinit pci_sun4v_probe(struct of_device *op, for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { if (pbm->devhandle == (devhandle ^ 0x40)) { - return pci_sun4v_pbm_init(pbm->parent, dp, devhandle); + return pci_sun4v_pbm_init(pbm->parent, op, devhandle); } } @@ -1015,7 +1017,7 @@ static int __devinit pci_sun4v_probe(struct of_device *op, p->pbm_B.iommu = iommu; - return pci_sun4v_pbm_init(p, dp, devhandle); + return pci_sun4v_pbm_init(p, op, devhandle); out_free_iommu_A: kfree(p->pbm_A.iommu); -- cgit v1.2.3-70-g09d2 From d3ae4b5bc7186a53731d35187ad4ba3bca147cf6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 9 Sep 2008 23:54:02 -0700 Subject: sparc64: Get rid of pci_controller_info. It is just used as a parent to encapsulate two PBM objects. But that layout is only really relevant and necessary for psycho PCI controllers, which unlike all the others share a single IOMMU instance between sibling PCI busses. Signed-off-by: David S. Miller --- arch/sparc/include/asm/iommu_64.h | 3 + arch/sparc64/kernel/pci.c | 4 +- arch/sparc64/kernel/pci_fire.c | 55 ++++--------- arch/sparc64/kernel/pci_impl.h | 16 ++-- arch/sparc64/kernel/pci_psycho.c | 161 ++++++++++++++++++-------------------- arch/sparc64/kernel/pci_sabre.c | 33 ++++---- arch/sparc64/kernel/pci_schizo.c | 84 +++++++++----------- arch/sparc64/kernel/pci_sun4v.c | 66 +++++++--------- 8 files changed, 181 insertions(+), 241 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc/include/asm/iommu_64.h b/arch/sparc/include/asm/iommu_64.h index d7b9afcba08..caf798b5619 100644 --- a/arch/sparc/include/asm/iommu_64.h +++ b/arch/sparc/include/asm/iommu_64.h @@ -48,6 +48,9 @@ struct strbuf { unsigned long strbuf_control; unsigned long strbuf_pflush; unsigned long strbuf_fsync; + unsigned long strbuf_err_stat; + unsigned long strbuf_tag_diag; + unsigned long strbuf_line_diag; unsigned long strbuf_ctxflush; unsigned long strbuf_ctxmatch_base; unsigned long strbuf_flushflag_pa; diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 8e18fdf32a6..3070f6faecc 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -977,14 +977,14 @@ int pcibus_to_node(struct pci_bus *pbus) EXPORT_SYMBOL(pcibus_to_node); #endif -/* Return the domain nuber for this pci bus */ +/* Return the domain number for this pci bus */ int pci_domain_nr(struct pci_bus *pbus) { struct pci_pbm_info *pbm = pbus->sysdata; int ret; - if (pbm == NULL || pbm->parent == NULL) { + if (!pbm) { ret = -ENXIO; } else { ret = pbm->index; diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index 1b44153f907..b538bfb0a47 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c @@ -431,22 +431,13 @@ static void pci_fire_hw_init(struct pci_pbm_info *pbm) fire_write(pbm->pbm_regs + FIRE_PEC_IENAB, ~(u64)0); } -static int __init pci_fire_pbm_init(struct pci_controller_info *p, +static int __init pci_fire_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 portid) { const struct linux_prom64_registers *regs; struct device_node *dp = op->node; - struct pci_pbm_info *pbm; int err; - if ((portid & 1) == 0) - pbm = &p->pbm_A; - else - pbm = &p->pbm_B; - - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - pbm->numa_node = -1; pbm->pci_ops = &sun4u_pci_ops; @@ -455,7 +446,6 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, pbm->index = pci_num_pbms++; pbm->portid = portid; - pbm->parent = p; pbm->prom_node = dp; pbm->name = dp->full_name; @@ -481,13 +471,9 @@ static int __init pci_fire_pbm_init(struct pci_controller_info *p, /* XXX register error interrupt handlers XXX */ - return 0; -} + pbm->next = pci_pbm_root; + pci_pbm_root = pbm; -static inline int portid_compare(u32 x, u32 y) -{ - if (x == (y ^ 1)) - return 1; return 0; } @@ -495,48 +481,41 @@ static int __devinit fire_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; - struct pci_controller_info *p; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; int err; portid = of_getintprop_default(dp, "portid", 0xff); - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - if (portid_compare(pbm->portid, portid)) - return pci_fire_pbm_init(pbm->parent, op, portid); - } err = -ENOMEM; - p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) { - printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + if (!pbm) { + printk(KERN_ERR PFX "Cannot allocate pci_pbminfo.\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); if (!iommu) { - printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); + printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; } - p->pbm_A.iommu = iommu; + pbm->iommu = iommu; - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) { - printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); - goto out_free_iommu_A; - } + err = pci_fire_pbm_init(pbm, op, portid); + if (err) + goto out_free_iommu; - p->pbm_B.iommu = iommu; + dev_set_drvdata(&op->dev, pbm); - return pci_fire_pbm_init(p, op, portid); + return 0; -out_free_iommu_A: - kfree(p->pbm_A.iommu); +out_free_iommu: + kfree(pbm->iommu); out_free_controller: - kfree(p); + kfree(pbm); out_err: return err; diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 4125f7513c6..4937ce903a8 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -56,15 +56,11 @@ struct sparc64_msiq_cookie { }; #endif -struct pci_controller_info; - struct pci_pbm_info { struct pci_pbm_info *next; + struct pci_pbm_info *sibling; int index; - /* PCI controller we sit under. */ - struct pci_controller_info *parent; - /* Physical address base of controller registers. */ unsigned long controller_regs; @@ -107,6 +103,10 @@ struct pci_pbm_info { /* This will be 12 on PCI-E controllers, 8 elsewhere. */ unsigned long config_space_reg_bits; + unsigned long pci_afsr; + unsigned long pci_afar; + unsigned long pci_csr; + /* State of 66MHz capabilities on this PBM. */ int is_66mhz_capable; int all_devs_66mhz; @@ -151,12 +151,6 @@ struct pci_pbm_info { int numa_node; }; -struct pci_controller_info { - /* The PCI bus modules controlled by us. */ - struct pci_pbm_info pbm_A; - struct pci_pbm_info pbm_B; -}; - extern struct pci_pbm_info *pci_pbm_root; extern int pci_num_pbms; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 0be850e6e58..70a7af092be 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -146,24 +146,16 @@ static unsigned long stc_error_buf[128]; static unsigned long stc_tag_buf[16]; static unsigned long stc_line_buf[16]; -static void __psycho_check_one_stc(struct pci_pbm_info *pbm, - int is_pbm_a) +static void psycho_check_stc_error(struct pci_pbm_info *pbm) { struct strbuf *strbuf = &pbm->stc; - unsigned long regbase = pbm->controller_regs; unsigned long err_base, tag_base, line_base; u64 control; int i; - if (is_pbm_a) { - err_base = regbase + PSYCHO_STC_ERR_A; - tag_base = regbase + PSYCHO_STC_TAG_A; - line_base = regbase + PSYCHO_STC_LINE_A; - } else { - err_base = regbase + PSYCHO_STC_ERR_B; - tag_base = regbase + PSYCHO_STC_TAG_B; - line_base = regbase + PSYCHO_STC_LINE_B; - } + err_base = strbuf->strbuf_err_stat; + tag_base = strbuf->strbuf_tag_diag; + line_base = strbuf->strbuf_line_diag; spin_lock(&stc_buf_lock); @@ -239,15 +231,6 @@ static void __psycho_check_one_stc(struct pci_pbm_info *pbm, spin_unlock(&stc_buf_lock); } -static void __psycho_check_stc_error(struct pci_pbm_info *pbm, - unsigned long afsr, - unsigned long afar, - enum psycho_error_type type) -{ - __psycho_check_one_stc(pbm, - (pbm == &pbm->parent->pbm_A)); -} - /* When an Uncorrectable Error or a PCI Error happens, we * interrogate the IOMMU state to see if it is the cause. */ @@ -386,7 +369,7 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, (data & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT); } } - __psycho_check_stc_error(pbm, afsr, afar, type); + psycho_check_stc_error(pbm); spin_unlock_irqrestore(&iommu->lock, flags); } @@ -412,7 +395,6 @@ static void psycho_check_iommu_error(struct pci_pbm_info *pbm, static irqreturn_t psycho_ue_intr(int irq, void *dev_id) { struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; unsigned long afsr_reg = pbm->controller_regs + PSYCHO_UE_AFSR; unsigned long afar_reg = pbm->controller_regs + PSYCHO_UE_AFAR; unsigned long afsr, afar, error_bits; @@ -465,8 +447,9 @@ static irqreturn_t psycho_ue_intr(int irq, void *dev_id) printk("]\n"); /* Interrogate both IOMMUs for error status. */ - psycho_check_iommu_error(&p->pbm_A, afsr, afar, UE_ERR); - psycho_check_iommu_error(&p->pbm_B, afsr, afar, UE_ERR); + psycho_check_iommu_error(pbm, afsr, afar, UE_ERR); + if (pbm->sibling) + psycho_check_iommu_error(pbm->sibling, afsr, afar, UE_ERR); return IRQ_HANDLED; } @@ -573,23 +556,18 @@ static irqreturn_t psycho_ce_intr(int irq, void *dev_id) #define PSYCHO_PCI_AFAR_A 0x2018UL #define PSYCHO_PCI_AFAR_B 0x4018UL -static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm_a) +static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm) { - unsigned long csr_reg, csr, csr_error_bits; + unsigned long csr, csr_error_bits; irqreturn_t ret = IRQ_NONE; u16 stat; - if (is_pbm_a) { - csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL; - } else { - csr_reg = pbm->controller_regs + PSYCHO_PCIB_CTRL; - } - csr = psycho_read(csr_reg); + csr = psycho_read(pbm->pci_csr); csr_error_bits = csr & (PSYCHO_PCICTRL_SBH_ERR | PSYCHO_PCICTRL_SERR); if (csr_error_bits) { /* Clear the errors. */ - psycho_write(csr_reg, csr); + psycho_write(pbm->pci_csr, csr); /* Log 'em. */ if (csr_error_bits & PSYCHO_PCICTRL_SBH_ERR) @@ -616,19 +594,12 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) { struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; unsigned long afsr_reg, afar_reg; unsigned long afsr, afar, error_bits; - int is_pbm_a, reported; + int reported; - is_pbm_a = (pbm == &pbm->parent->pbm_A); - if (is_pbm_a) { - afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_A; - afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_A; - } else { - afsr_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFSR_B; - afar_reg = p->pbm_A.controller_regs + PSYCHO_PCI_AFAR_B; - } + afsr_reg = pbm->pci_afsr; + afar_reg = pbm->pci_afar; /* Latch error status. */ afar = psycho_read(afar_reg); @@ -641,7 +612,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) PSYCHO_PCIAFSR_SMA | PSYCHO_PCIAFSR_STA | PSYCHO_PCIAFSR_SRTRY | PSYCHO_PCIAFSR_SPERR); if (!error_bits) - return psycho_pcierr_intr_other(pbm, is_pbm_a); + return psycho_pcierr_intr_other(pbm); psycho_write(afsr_reg, error_bits); /* Log the error. */ @@ -923,10 +894,16 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_A; pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_A; pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_A; + pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_A; + pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_A; + pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_A; } else { pbm->stc.strbuf_control = base + PSYCHO_STRBUF_CONTROL_B; pbm->stc.strbuf_pflush = base + PSYCHO_STRBUF_FLUSH_B; pbm->stc.strbuf_fsync = base + PSYCHO_STRBUF_FSYNC_B; + pbm->stc.strbuf_err_stat = base + PSYCHO_STC_ERR_B; + pbm->stc.strbuf_tag_diag = base + PSYCHO_STC_TAG_B; + pbm->stc.strbuf_line_diag= base + PSYCHO_STC_LINE_B; } /* PSYCHO's streaming buffer lacks ctx flushing. */ pbm->stc.strbuf_ctxflush = 0; @@ -971,16 +948,10 @@ static void psycho_pbm_strbuf_init(struct pci_pbm_info *pbm, #define PSYCHO_MEMSPACE_B 0x180000000UL #define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL -static void __init psycho_pbm_init(struct pci_controller_info *p, +static void __init psycho_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, int is_pbm_a) { struct device_node *dp = op->node; - struct pci_pbm_info *pbm; - - if (is_pbm_a) - pbm = &p->pbm_A; - else - pbm = &p->pbm_B; pbm->next = pci_pbm_root; pci_pbm_root = pbm; @@ -996,7 +967,6 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, pbm->chip_version = of_getintprop_default(dp, "version#", 0); pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0); - pbm->parent = p; pbm->prom_node = dp; pbm->name = dp->full_name; @@ -1013,6 +983,17 @@ static void __init psycho_pbm_init(struct pci_controller_info *p, psycho_scan_bus(pbm, &op->dev); } +static struct pci_pbm_info * __devinit psycho_find_sibling(u32 upa_portid) +{ + struct pci_pbm_info *pbm; + + for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { + if (pbm->portid == upa_portid) + return pbm; + } + return NULL; +} + #define PSYCHO_CONFIGSPACE 0x001000000UL static int __devinit psycho_probe(struct of_device *op, @@ -1020,7 +1001,6 @@ static int __devinit psycho_probe(struct of_device *op, { const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->node; - struct pci_controller_info *p; struct pci_pbm_info *pbm; struct iommu *iommu; int is_pbm_a, err; @@ -1028,33 +1008,26 @@ static int __devinit psycho_probe(struct of_device *op, upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - struct pci_controller_info *p = pbm->parent; - - if (p->pbm_A.portid == upa_portid) { - is_pbm_a = (p->pbm_A.prom_node == NULL); - psycho_pbm_init(p, op, is_pbm_a); - return 0; - } - } - err = -ENOMEM; - p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) { - printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + if (!pbm) { + printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) { - printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); - goto out_free_controller; + pbm->sibling = psycho_find_sibling(upa_portid); + if (pbm->sibling) { + iommu = pbm->sibling->iommu; + } else { + iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + if (!iommu) { + printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); + goto out_free_controller; + } } - p->pbm_A.iommu = p->pbm_B.iommu = iommu; - - p->pbm_A.portid = upa_portid; - p->pbm_B.portid = upa_portid; + pbm->iommu = iommu; + pbm->portid = upa_portid; pr_regs = of_get_property(dp, "reg", NULL); err = -ENODEV; @@ -1063,29 +1036,43 @@ static int __devinit psycho_probe(struct of_device *op, goto out_free_iommu; } - p->pbm_A.controller_regs = pr_regs[2].phys_addr; - p->pbm_B.controller_regs = pr_regs[2].phys_addr; + is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); + + pbm->controller_regs = pr_regs[2].phys_addr; + pbm->config_space = (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); - p->pbm_A.config_space = p->pbm_B.config_space = - (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); + if (is_pbm_a) { + pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_A; + pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_A; + pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIA_CTRL; + } else { + pbm->pci_afsr = pbm->controller_regs + PSYCHO_PCI_AFSR_B; + pbm->pci_afar = pbm->controller_regs + PSYCHO_PCI_AFAR_B; + pbm->pci_csr = pbm->controller_regs + PSYCHO_PCIB_CTRL; + } - psycho_controller_hwinit(&p->pbm_A); + psycho_controller_hwinit(pbm); + if (!pbm->sibling) { + err = psycho_iommu_init(pbm); + if (err) + goto out_free_iommu; + } - err = psycho_iommu_init(&p->pbm_A); - if (err) - goto out_free_iommu; + psycho_pbm_init(pbm, op, is_pbm_a); - is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); + if (pbm->sibling) + pbm->sibling->sibling = pbm; - psycho_pbm_init(p, op, is_pbm_a); + dev_set_drvdata(&op->dev, pbm); return 0; out_free_iommu: - kfree(p->pbm_A.iommu); + if (!pbm->sibling) + kfree(pbm->iommu); out_free_controller: - kfree(p); + kfree(pbm); out_err: return err; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 707d6d6130f..8f779b58d65 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -734,8 +734,8 @@ static int sabre_iommu_init(struct pci_pbm_info *pbm, return 0; } -static void __init sabre_pbm_init(struct pci_controller_info *p, - struct pci_pbm_info *pbm, struct of_device *op) +static void __init sabre_pbm_init(struct pci_pbm_info *pbm, + struct of_device *op) { struct device_node *dp = op->node; @@ -750,7 +750,6 @@ static void __init sabre_pbm_init(struct pci_controller_info *p, pbm->index = pci_num_pbms++; pbm->chip_type = PBM_CHIP_TYPE_SABRE; - pbm->parent = p; pbm->prom_node = dp; pci_get_pbm_props(pbm); @@ -764,7 +763,6 @@ static int __devinit sabre_probe(struct of_device *op, { const struct linux_prom64_registers *pr_regs; struct device_node *dp = op->node; - struct pci_controller_info *p; struct pci_pbm_info *pbm; u32 upa_portid, dma_mask; struct iommu *iommu; @@ -786,26 +784,22 @@ static int __devinit sabre_probe(struct of_device *op, } err = -ENOMEM; - p = kzalloc(sizeof(*p), GFP_ATOMIC); - if (!p) { - printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + if (!pbm) { + printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; } - iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; } - pbm = &p->pbm_A; pbm->iommu = iommu; upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - pbm->portid = upa_portid; /* @@ -840,8 +834,7 @@ static int __devinit sabre_probe(struct of_device *op, SABRE_PCICTRL_ARBPARK | SABRE_PCICTRL_AEN)); /* Now map in PCI config space for entire SABRE. */ - pbm->config_space = - (pbm->controller_regs + SABRE_CONFIGSPACE); + pbm->config_space = pbm->controller_regs + SABRE_CONFIGSPACE; vdma = of_get_property(dp, "virtual-dma", NULL); if (!vdma) { @@ -876,14 +869,20 @@ static int __devinit sabre_probe(struct of_device *op, /* * Look for APB underneath. */ - sabre_pbm_init(p, pbm, op); + sabre_pbm_init(pbm, op); + + pbm->next = pci_pbm_root; + pci_pbm_root = pbm; + + dev_set_drvdata(&op->dev, pbm); + return 0; out_free_iommu: - kfree(p->pbm_A.iommu); + kfree(pbm->iommu); out_free_controller: - kfree(p); + kfree(pbm); out_err: return err; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index e1c565744d3..67e3640bc69 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -358,11 +358,12 @@ static void schizo_check_iommu_error_pbm(struct pci_pbm_info *pbm, spin_unlock_irqrestore(&iommu->lock, flags); } -static void schizo_check_iommu_error(struct pci_controller_info *p, +static void schizo_check_iommu_error(struct pci_pbm_info *pbm, enum schizo_error_type type) { - schizo_check_iommu_error_pbm(&p->pbm_A, type); - schizo_check_iommu_error_pbm(&p->pbm_B, type); + schizo_check_iommu_error_pbm(pbm, type); + if (pbm->sibling) + schizo_check_iommu_error_pbm(pbm->sibling, type); } /* Uncorrectable ECC error status gathering. */ @@ -387,7 +388,6 @@ static void schizo_check_iommu_error(struct pci_controller_info *p, static irqreturn_t schizo_ue_intr(int irq, void *dev_id) { struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; unsigned long afsr_reg = pbm->controller_regs + SCHIZO_UE_AFSR; unsigned long afar_reg = pbm->controller_regs + SCHIZO_UE_AFAR; unsigned long afsr, afar, error_bits; @@ -450,7 +450,7 @@ static irqreturn_t schizo_ue_intr(int irq, void *dev_id) printk("]\n"); /* Interrogate IOMMU for error status. */ - schizo_check_iommu_error(p, UE_ERR); + schizo_check_iommu_error(pbm, UE_ERR); return IRQ_HANDLED; } @@ -651,7 +651,6 @@ static irqreturn_t schizo_pcierr_intr_other(struct pci_pbm_info *pbm) static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) { struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; unsigned long afsr_reg, afar_reg, base; unsigned long afsr, afar, error_bits; int reported; @@ -745,7 +744,7 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) * a bug in the IOMMU support code or a PCI device driver. */ if (error_bits & (SCHIZO_PCIAFSR_PTA | SCHIZO_PCIAFSR_STA)) { - schizo_check_iommu_error(p, PCI_ERR); + schizo_check_iommu_error(pbm, PCI_ERR); pci_scan_for_target_abort(pbm, pbm->pci_bus); } if (error_bits & (SCHIZO_PCIAFSR_PMA | SCHIZO_PCIAFSR_SMA)) @@ -806,7 +805,6 @@ static irqreturn_t schizo_pcierr_intr(int irq, void *dev_id) static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) { struct pci_pbm_info *pbm = dev_id; - struct pci_controller_info *p = pbm->parent; u64 errlog; errlog = schizo_read(pbm->controller_regs + SCHIZO_SAFARI_ERRLOG); @@ -822,7 +820,7 @@ static irqreturn_t schizo_safarierr_intr(int irq, void *dev_id) printk("%s: Safari/JBUS interrupt, UNMAPPED error, interrogating IOMMUs.\n", pbm->name); - schizo_check_iommu_error(p, SAFARI_ERR); + schizo_check_iommu_error(pbm, SAFARI_ERR); return IRQ_HANDLED; } @@ -1329,13 +1327,12 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) } } -static int __devinit schizo_pbm_init(struct pci_controller_info *p, +static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 portid, int chip_type) { const struct linux_prom64_registers *regs; struct device_node *dp = op->node; - struct pci_pbm_info *pbm; const char *chipset_name; int is_pbm_a, err; @@ -1368,10 +1365,6 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p, regs = of_get_property(dp, "reg", NULL); is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000); - if (is_pbm_a) - pbm = &p->pbm_A; - else - pbm = &p->pbm_B; pbm->next = pci_pbm_root; pci_pbm_root = pbm; @@ -1384,7 +1377,6 @@ static int __devinit schizo_pbm_init(struct pci_controller_info *p, pbm->index = pci_num_pbms++; pbm->portid = portid; - pbm->parent = p; pbm->prom_node = dp; pbm->chip_type = chip_type; @@ -1430,10 +1422,21 @@ static inline int portid_compare(u32 x, u32 y, int chip_type) return (x == y); } +static struct pci_pbm_info * __devinit schizo_find_sibling(u32 portid, + int chip_type) +{ + struct pci_pbm_info *pbm; + + for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { + if (portid_compare(pbm->portid, portid, chip_type)) + return pbm; + } + return NULL; +} + static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type) { struct device_node *dp = op->node; - struct pci_controller_info *p; struct pci_pbm_info *pbm; struct iommu *iommu; u32 portid; @@ -1442,50 +1445,37 @@ static int __devinit __schizo_init(struct of_device *op, unsigned long chip_type portid = of_getintprop_default(dp, "portid", 0xff); err = -ENOMEM; - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - if (portid_compare(pbm->portid, portid, chip_type)) { - if (schizo_pbm_init(pbm->parent, op, - portid, chip_type)) - goto out_err; - return 0; - } - } - - p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) { - printk(KERN_ERR PFX "Cannot allocate controller info.\n"); + pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + if (!pbm) { + printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); + pbm->sibling = schizo_find_sibling(portid, chip_type); + + iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); - goto out_free_controller; + goto out_free_pbm; } - p->pbm_A.iommu = iommu; + pbm->iommu = iommu; - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) { - printk(KERN_ERR PFX "Cannot allocate PBM B iommu.\n"); - goto out_free_iommu_A; - } + if (schizo_pbm_init(pbm, op, portid, chip_type)) + goto out_free_iommu; - p->pbm_B.iommu = iommu; + if (pbm->sibling) + pbm->sibling->sibling = pbm; - if (schizo_pbm_init(p, op, portid, chip_type)) - goto out_free_iommu_B; + dev_set_drvdata(&op->dev, pbm); return 0; -out_free_iommu_B: - kfree(p->pbm_B.iommu); - -out_free_iommu_A: - kfree(p->pbm_A.iommu); +out_free_iommu: + kfree(pbm->iommu); -out_free_controller: - kfree(p); +out_free_pbm: + kfree(pbm); out_err: return err; diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 6bed2f6bf7c..233b22b8b57 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -42,6 +42,7 @@ struct iommu_batch { }; static DEFINE_PER_CPU(struct iommu_batch, iommu_batch); +static int iommu_batch_initialized; /* Interrupts must be disabled. */ static inline void iommu_batch_start(struct device *dev, unsigned long prot, unsigned long entry) @@ -887,21 +888,12 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) } #endif /* !(CONFIG_PCI_MSI) */ -static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, +static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm, struct of_device *op, u32 devhandle) { struct device_node *dp = op->node; - struct pci_pbm_info *pbm; int err; - if (devhandle & 0x40) - pbm = &p->pbm_B; - else - pbm = &p->pbm_A; - - pbm->next = pci_pbm_root; - pci_pbm_root = pbm; - pbm->numa_node = of_node_to_nid(dp); pbm->pci_ops = &sun4v_pci_ops; @@ -909,7 +901,6 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, pbm->index = pci_num_pbms++; - pbm->parent = p; pbm->prom_node = dp; pbm->devhandle = devhandle; @@ -931,6 +922,9 @@ static int __init pci_sun4v_pbm_init(struct pci_controller_info *p, pci_sun4v_scan_bus(pbm, &op->dev); + pbm->next = pci_pbm_root; + pci_pbm_root = pbm; + return 0; } @@ -939,7 +933,6 @@ static int __devinit pci_sun4v_probe(struct of_device *op, { const struct linux_prom64_registers *regs; static int hvapi_negotiated = 0; - struct pci_controller_info *p; struct pci_pbm_info *pbm; struct device_node *dp; struct iommu *iommu; @@ -972,51 +965,46 @@ static int __devinit pci_sun4v_probe(struct of_device *op, } devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; - for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { - if (pbm->devhandle == (devhandle ^ 0x40)) { - return pci_sun4v_pbm_init(pbm->parent, op, devhandle); - } - } - err = -ENOMEM; - for_each_possible_cpu(i) { - unsigned long page = get_zeroed_page(GFP_ATOMIC); + if (!iommu_batch_initialized) { + for_each_possible_cpu(i) { + unsigned long page = get_zeroed_page(GFP_KERNEL); - if (!page) - goto out_err; + if (!page) + goto out_err; - per_cpu(iommu_batch, i).pglist = (u64 *) page; + per_cpu(iommu_batch, i).pglist = (u64 *) page; + } + iommu_batch_initialized = 1; } - p = kzalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); - if (!p) { - printk(KERN_ERR PFX "Could not allocate pci_controller_info\n"); + pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + if (!pbm) { + printk(KERN_ERR PFX "Could not allocate pci_pbm_info\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); + iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); if (!iommu) { - printk(KERN_ERR PFX "Could not allocate pbm A iommu\n"); + printk(KERN_ERR PFX "Could not allocate pbm iommu\n"); goto out_free_controller; } - p->pbm_A.iommu = iommu; + pbm->iommu = iommu; - iommu = kzalloc(sizeof(struct iommu), GFP_ATOMIC); - if (!iommu) { - printk(KERN_ERR PFX "Could not allocate pbm B iommu\n"); - goto out_free_iommu_A; - } + err = pci_sun4v_pbm_init(pbm, op, devhandle); + if (err) + goto out_free_iommu; - p->pbm_B.iommu = iommu; + dev_set_drvdata(&op->dev, pbm); - return pci_sun4v_pbm_init(p, op, devhandle); + return 0; -out_free_iommu_A: - kfree(p->pbm_A.iommu); +out_free_iommu: + kfree(pbm->iommu); out_free_controller: - kfree(p); + kfree(pbm); out_err: return err; -- cgit v1.2.3-70-g09d2 From 22fecbae4446ad470b9237ee9b79f80f343b3838 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 10 Sep 2008 00:19:28 -0700 Subject: sparc64: Record OF device instead of device node pointer in pci_pbm_info. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 2 +- arch/sparc64/kernel/pci_common.c | 8 ++++---- arch/sparc64/kernel/pci_fire.c | 2 +- arch/sparc64/kernel/pci_impl.h | 3 ++- arch/sparc64/kernel/pci_msi.c | 18 +++++++++--------- arch/sparc64/kernel/pci_psycho.c | 4 ++-- arch/sparc64/kernel/pci_sabre.c | 4 ++-- arch/sparc64/kernel/pci_schizo.c | 12 ++++++------ arch/sparc64/kernel/pci_sun4v.c | 6 +++--- 9 files changed, 30 insertions(+), 29 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 3070f6faecc..c6e81dea2cf 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -676,7 +676,7 @@ static void __devinit pci_bus_register_of_sysfs(struct pci_bus *bus) struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, struct device *parent) { - struct device_node *node = pbm->prom_node; + struct device_node *node = pbm->op->node; struct pci_bus *bus; printk("PCI: Scanning PBM %s\n", node->full_name); diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 09a5ec200c6..23b88082d0b 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -314,12 +314,12 @@ struct pci_ops sun4v_pci_ops = { void pci_get_pbm_props(struct pci_pbm_info *pbm) { - const u32 *val = of_get_property(pbm->prom_node, "bus-range", NULL); + const u32 *val = of_get_property(pbm->op->node, "bus-range", NULL); pbm->pci_first_busno = val[0]; pbm->pci_last_busno = val[1]; - val = of_get_property(pbm->prom_node, "ino-bitmap", NULL); + val = of_get_property(pbm->op->node, "ino-bitmap", NULL); if (val) { pbm->ino_bitmap = (((u64)val[1] << 32UL) | ((u64)val[0] << 0UL)); @@ -365,7 +365,7 @@ static void pci_register_legacy_regions(struct resource *io_res, static void pci_register_iommu_region(struct pci_pbm_info *pbm) { - const u32 *vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); + const u32 *vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); if (vdma) { struct resource *rp = kmalloc(sizeof(*rp), GFP_KERNEL); @@ -389,7 +389,7 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) int num_pbm_ranges; saw_mem = saw_io = 0; - pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i); + pbm_ranges = of_get_property(pbm->op->node, "ranges", &i); if (!pbm_ranges) { prom_printf("PCI: Fatal error, missing PBM ranges property " " for %s\n", diff --git a/arch/sparc64/kernel/pci_fire.c b/arch/sparc64/kernel/pci_fire.c index b538bfb0a47..7e1a9b6717b 100644 --- a/arch/sparc64/kernel/pci_fire.c +++ b/arch/sparc64/kernel/pci_fire.c @@ -446,7 +446,7 @@ static int __init pci_fire_pbm_init(struct pci_pbm_info *pbm, pbm->index = pci_num_pbms++; pbm->portid = portid; - pbm->prom_node = dp; + pbm->op = op; pbm->name = dp->full_name; regs = of_get_property(dp, "reg", NULL); diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index 4937ce903a8..b300f39e9e8 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -90,7 +91,7 @@ struct pci_pbm_info { char *name; /* OBP specific information. */ - struct device_node *prom_node; + struct of_device *op; u64 ino_bitmap; /* PBM I/O and Memory space resources. */ diff --git a/arch/sparc64/kernel/pci_msi.c b/arch/sparc64/kernel/pci_msi.c index 60c71e35021..2e680f34f72 100644 --- a/arch/sparc64/kernel/pci_msi.c +++ b/arch/sparc64/kernel/pci_msi.c @@ -323,7 +323,7 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, const u32 *val; int len; - val = of_get_property(pbm->prom_node, "#msi-eqs", &len); + val = of_get_property(pbm->op->node, "#msi-eqs", &len); if (!val || len != 4) goto no_msi; pbm->msiq_num = *val; @@ -346,16 +346,16 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, u32 msi64_len; } *arng; - val = of_get_property(pbm->prom_node, "msi-eq-size", &len); + val = of_get_property(pbm->op->node, "msi-eq-size", &len); if (!val || len != 4) goto no_msi; pbm->msiq_ent_count = *val; - mqp = of_get_property(pbm->prom_node, + mqp = of_get_property(pbm->op->node, "msi-eq-to-devino", &len); if (!mqp) - mqp = of_get_property(pbm->prom_node, + mqp = of_get_property(pbm->op->node, "msi-eq-devino", &len); if (!mqp || len != sizeof(struct msiq_prop)) goto no_msi; @@ -363,27 +363,27 @@ void sparc64_pbm_msi_init(struct pci_pbm_info *pbm, pbm->msiq_first = mqp->first_msiq; pbm->msiq_first_devino = mqp->first_devino; - val = of_get_property(pbm->prom_node, "#msi", &len); + val = of_get_property(pbm->op->node, "#msi", &len); if (!val || len != 4) goto no_msi; pbm->msi_num = *val; - mrng = of_get_property(pbm->prom_node, "msi-ranges", &len); + mrng = of_get_property(pbm->op->node, "msi-ranges", &len); if (!mrng || len != sizeof(struct msi_range_prop)) goto no_msi; pbm->msi_first = mrng->first_msi; - val = of_get_property(pbm->prom_node, "msi-data-mask", &len); + val = of_get_property(pbm->op->node, "msi-data-mask", &len); if (!val || len != 4) goto no_msi; pbm->msi_data_mask = *val; - val = of_get_property(pbm->prom_node, "msix-data-width", &len); + val = of_get_property(pbm->op->node, "msix-data-width", &len); if (!val || len != 4) goto no_msi; pbm->msix_data_width = *val; - arng = of_get_property(pbm->prom_node, "msi-address-ranges", + arng = of_get_property(pbm->op->node, "msi-address-ranges", &len); if (!arng || len != sizeof(struct addr_range_prop)) goto no_msi; diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 70a7af092be..4562b3e0b54 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -690,7 +690,7 @@ static irqreturn_t psycho_pcierr_intr(int irq, void *dev_id) #define PSYCHO_ECCCTRL_CE 0x2000000000000000UL /* Enable CE INterrupts */ static void psycho_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->prom_node); + struct of_device *op = of_find_device_by_node(pbm->op->node); unsigned long base = pbm->controller_regs; u64 tmp; int err; @@ -967,7 +967,7 @@ static void __init psycho_pbm_init(struct pci_pbm_info *pbm, pbm->chip_version = of_getintprop_default(dp, "version#", 0); pbm->chip_revision = of_getintprop_default(dp, "module-revision#", 0); - pbm->prom_node = dp; + pbm->op = op; pbm->name = dp->full_name; printk(KERN_INFO "%s: PSYCHO PCI Bus Module ver[%x:%x]\n", diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 8f779b58d65..196049bb14b 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -543,7 +543,7 @@ static irqreturn_t sabre_pcierr_intr(int irq, void *dev_id) static void sabre_register_error_handlers(struct pci_pbm_info *pbm) { - struct device_node *dp = pbm->prom_node; + struct device_node *dp = pbm->op->node; struct of_device *op; unsigned long base = pbm->controller_regs; u64 tmp; @@ -750,7 +750,7 @@ static void __init sabre_pbm_init(struct pci_pbm_info *pbm, pbm->index = pci_num_pbms++; pbm->chip_type = PBM_CHIP_TYPE_SABRE; - pbm->prom_node = dp; + pbm->op = op; pci_get_pbm_props(pbm); pci_determine_mem_io_space(pbm); diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 67e3640bc69..c30856541bb 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -862,7 +862,7 @@ static int pbm_routes_this_ino(struct pci_pbm_info *pbm, u32 ino) */ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->prom_node); + struct of_device *op = of_find_device_by_node(pbm->op->node); u64 tmp, err_mask, err_no_mask; int err; @@ -958,7 +958,7 @@ static void tomatillo_register_error_handlers(struct pci_pbm_info *pbm) static void schizo_register_error_handlers(struct pci_pbm_info *pbm) { - struct of_device *op = of_find_device_by_node(pbm->prom_node); + struct of_device *op = of_find_device_by_node(pbm->op->node); u64 tmp, err_mask, err_no_mask; int err; @@ -1088,7 +1088,7 @@ static void __devinit schizo_scan_bus(struct pci_pbm_info *pbm, { pbm_config_busmastering(pbm); pbm->is_66mhz_capable = - (of_find_property(pbm->prom_node, "66mhz-capable", NULL) + (of_find_property(pbm->op->node, "66mhz-capable", NULL) != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -1158,7 +1158,7 @@ static int schizo_pbm_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask; u64 control; - vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -1288,7 +1288,7 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - if (!of_find_property(pbm->prom_node, "no-bus-parking", NULL)) + if (!of_find_property(pbm->op->node, "no-bus-parking", NULL)) tmp |= SCHIZO_PCICTRL_PARK; else tmp &= ~SCHIZO_PCICTRL_PARK; @@ -1377,7 +1377,7 @@ static int __devinit schizo_pbm_init(struct pci_pbm_info *pbm, pbm->index = pci_num_pbms++; pbm->portid = portid; - pbm->prom_node = dp; + pbm->op = op; pbm->chip_type = chip_type; pbm->chip_version = of_getintprop_default(dp, "version#", 0); diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 233b22b8b57..97a77bcd255 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -550,7 +550,7 @@ static void __init pci_sun4v_scan_bus(struct pci_pbm_info *pbm, struct property *prop; struct device_node *dp; - dp = pbm->prom_node; + dp = pbm->op->node; prop = of_find_property(dp, "66mhz-capable", NULL); pbm->is_66mhz_capable = (prop != NULL); pbm->pci_bus = pci_scan_one_pbm(pbm, parent); @@ -594,7 +594,7 @@ static int __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm) u32 dma_mask, dma_offset; const u32 *vdma; - vdma = of_get_property(pbm->prom_node, "virtual-dma", NULL); + vdma = of_get_property(pbm->op->node, "virtual-dma", NULL); if (!vdma) vdma = vdma_default; @@ -901,7 +901,7 @@ static int __init pci_sun4v_pbm_init(struct pci_pbm_info *pbm, pbm->index = pci_num_pbms++; - pbm->prom_node = dp; + pbm->op = op; pbm->devhandle = devhandle; -- cgit v1.2.3-70-g09d2 From 77d10d0e63dcc4f961cb416447d64281300e5a01 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 11 Sep 2008 23:57:40 -0700 Subject: sparc64: Fix sparse warnings in pci.c 1) Declare pci_poke_* in pci_impl.h 2) of_create_pci_dev() should be static 3) ->setup_msi_irq() wants an unsigned int pointer not a plain int one 4) void value expression return in arch_teardown_msi_irq() Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 14 ++++++-------- arch/sparc64/kernel/pci_impl.h | 4 ++++ arch/sparc64/kernel/traps.c | 5 +---- 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index c6e81dea2cf..e12a0586b43 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -242,9 +242,9 @@ static void pci_parse_of_addrs(struct of_device *op, } } -struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, - struct device_node *node, - struct pci_bus *bus, int devfn) +static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, + struct device_node *node, + struct pci_bus *bus, int devfn) { struct dev_archdata *sd; struct of_device *op; @@ -998,7 +998,7 @@ 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; - int virt_irq; + unsigned int virt_irq; if (!pbm->setup_msi_irq) return -EINVAL; @@ -1012,10 +1012,8 @@ void arch_teardown_msi_irq(unsigned int virt_irq) struct pci_dev *pdev = entry->dev; struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller; - if (!pbm->teardown_msi_irq) - return; - - return pbm->teardown_msi_irq(virt_irq, pdev); + if (pbm->teardown_msi_irq) + pbm->teardown_msi_irq(virt_irq, pdev); } #endif /* !(CONFIG_PCI_MSI) */ diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h index b300f39e9e8..03186824327 100644 --- a/arch/sparc64/kernel/pci_impl.h +++ b/arch/sparc64/kernel/pci_impl.h @@ -178,4 +178,8 @@ extern void pci_config_write32(u32 *addr, u32 val); extern struct pci_ops sun4u_pci_ops; extern struct pci_ops sun4v_pci_ops; +extern volatile int pci_poke_in_progress; +extern volatile int pci_poke_cpu; +extern volatile int pci_poke_faulted; + #endif /* !(PCI_IMPL_H) */ diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 9378896589f..342da216423 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -341,10 +341,7 @@ void sun4v_data_access_exception_tl1(struct pt_regs *regs, unsigned long addr, u } #ifdef CONFIG_PCI -/* This is really pathetic... */ -extern volatile int pci_poke_in_progress; -extern volatile int pci_poke_cpu; -extern volatile int pci_poke_faulted; +#include "pci_impl.h" #endif /* When access exceptions happen, we must do this. */ -- cgit v1.2.3-70-g09d2 From 44b50e5a1af13c605d6c3b17a60e42eb0ee48d5f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 22 Sep 2008 15:42:24 -0700 Subject: sparc64: Fix missing devices due to PCI bridge test in of_create_pci_dev(). Just like in the arch/sparc64/kernel/of_device.c code fix commit 071d7f4c3b411beae08d27656e958070c43b78b4 ("sparc64: Fix SMP bootup with CONFIG_STACK_DEBUG or ftrace.") we have to check the OF device node name for "pci" instead of relying upon the 'device_type' property being there on all PCI bridges. Tested by Meelis Roos, and confirmed to make the PCI QFE devices reappear on the E3500 system. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sparc64/kernel/pci.c') diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 55096195458..80dad76f8b8 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -425,7 +425,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->current_state = 4; /* unknown power state */ dev->error_state = pci_channel_io_normal; - if (!strcmp(type, "pci") || !strcmp(type, "pciex")) { + if (!strcmp(node->name, "pci")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; dev->rom_base_reg = PCI_ROM_ADDRESS1; -- cgit v1.2.3-70-g09d2