From cfa0652c4eb4ca37f88fcdd7d871cf98d9d98c0e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 21:51:41 -0700 Subject: [SPARC64] PCI: Use common routine to fetch PBM properties. Namely bus-range and ino-bitmap. This allows us also to eliminate pci_controller_info's pci_{first,last}_busno fields as only the pbm ones are used now. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'arch/sparc64/kernel/pci_sun4v.c') diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 1ccf4c9a9a43..1491ba330583 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -802,20 +802,6 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) pbm->name, sz); } -static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) -{ - struct property *prop; - unsigned int *busrange; - - prop = of_find_property(pbm->prom_node, "bus-range", NULL); - - busrange = prop->value; - - pbm->pci_first_busno = busrange[0]; - pbm->pci_last_busno = busrange[1]; - -} - #ifdef CONFIG_PCI_MSI struct pci_sun4v_msiq_entry { u64 version_type; @@ -1271,7 +1257,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pci_determine_mem_io_space(pbm); - pci_sun4v_get_bus_range(pbm); + pci_get_pbm_props(pbm); pci_sun4v_iommu_init(pbm); pci_sun4v_msi_init(pbm); } -- cgit v1.2.2 From 34768bc8329194b14e42ee408a84edfa40059046 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 23:06:27 -0700 Subject: [SPARC64] PCI: Use root list of pbm's instead of pci_controller_info's The idea is to move more and more things into the pbm, with the eventual goal of eliminating the pci_controller_info entirely as there really isn't any need for it. This stage of the transformations requires some reworking of the PCI error interrupt handling. It might be tricky to get rid of the pci_controller_info parenting for a few reasons: 1) When we get an uncorrectable or correctable error we want to interrogate the IOMMU and streaming cache of both PBMs for error status. These errors come from the UPA front-end which is shared between the two PBM PCI bus segments. Historically speaking this is why I choose the datastructure hierarchy of pci_controller_info-->pci_pbm_info 2) The probing does a portid/devhandle match to look for the 'other' pbm, but this is entirely an artifact and can be eliminated trivially. What we could do to solve #1 is to have a "buddy" pointer from one pbm to another. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 47 ++++++++++++----------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) (limited to 'arch/sparc64/kernel/pci_sun4v.c') diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 1491ba330583..0a101cb22320 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -677,29 +677,15 @@ static struct pci_ops pci_sun4v_ops = { }; -static void pbm_scan_bus(struct pci_controller_info *p, - struct pci_pbm_info *pbm) -{ - pbm->pci_bus = pci_scan_one_pbm(pbm); -} - -static void pci_sun4v_scan_bus(struct pci_controller_info *p) +static void pci_sun4v_scan_bus(struct pci_pbm_info *pbm) { struct property *prop; struct device_node *dp; - if ((dp = p->pbm_A.prom_node) != NULL) { - prop = of_find_property(dp, "66mhz-capable", NULL); - p->pbm_A.is_66mhz_capable = (prop != NULL); - - pbm_scan_bus(p, &p->pbm_A); - } - if ((dp = p->pbm_B.prom_node) != NULL) { - prop = of_find_property(dp, "66mhz-capable", NULL); - p->pbm_B.is_66mhz_capable = (prop != NULL); - - pbm_scan_bus(p, &p->pbm_B); - } + 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); /* XXX register error interrupt handlers XXX */ } @@ -1246,6 +1232,11 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node else pbm = &p->pbm_A; + pbm->next = pci_pbm_root; + pci_pbm_root = pbm; + + pbm->scan_bus = pci_sun4v_scan_bus; + pbm->parent = p; pbm->prom_node = dp; @@ -1265,6 +1256,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node void sun4v_pci_init(struct device_node *dp, char *model_name) { struct pci_controller_info *p; + struct pci_pbm_info *pbm; struct iommu *iommu; struct property *prop; struct linux_prom64_registers *regs; @@ -1276,18 +1268,9 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff; - for (p = pci_controller_root; p; p = p->next) { - struct pci_pbm_info *pbm; - - if (p->pbm_A.prom_node && p->pbm_B.prom_node) - continue; - - pbm = (p->pbm_A.prom_node ? - &p->pbm_A : - &p->pbm_B); - + for (pbm = pci_pbm_root; pbm; pbm = pbm->next) { if (pbm->devhandle == (devhandle ^ 0x40)) { - pci_sun4v_pbm_init(p, dp, devhandle); + pci_sun4v_pbm_init(pbm->parent, dp, devhandle); return; } } @@ -1317,12 +1300,8 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->pbm_B.iommu = iommu; - p->next = pci_controller_root; - pci_controller_root = p; - p->index = pci_num_controllers++; - p->scan_bus = pci_sun4v_scan_bus; #ifdef CONFIG_PCI_MSI p->setup_msi_irq = pci_sun4v_setup_msi_irq; p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; -- cgit v1.2.2 From f1cd8de2c951e206b57fd76aff279cf13ea25815 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 23:24:05 -0700 Subject: [SPARC64]: Move pci_ops into pci_pbm_info. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sparc64/kernel/pci_sun4v.c') diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 0a101cb22320..ea61fec206a7 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1236,6 +1236,7 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pci_pbm_root = pbm; pbm->scan_bus = pci_sun4v_scan_bus; + pbm->pci_ops = &pci_sun4v_ops; pbm->parent = p; pbm->prom_node = dp; @@ -1306,7 +1307,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->setup_msi_irq = pci_sun4v_setup_msi_irq; p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; #endif - p->pci_ops = &pci_sun4v_ops; /* Like PSYCHO and SCHIZO we have a 2GB aligned area * for memory space. -- cgit v1.2.2 From e9870c4c0aef94580e28be11a1c6246dcabbe528 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 23:28:50 -0700 Subject: [SPARC64]: Move {setup,teardown}_msi_irq into pci_pbm_info. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 224 ++++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 113 deletions(-) (limited to 'arch/sparc64/kernel/pci_sun4v.c') diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index ea61fec206a7..7ebc04f9a880 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -991,114 +991,6 @@ h_error: return -EINVAL; } -static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) -{ - const u32 *val; - int len; - - val = of_get_property(pbm->prom_node, "#msi-eqs", &len); - if (!val || len != 4) - goto no_msi; - pbm->msiq_num = *val; - if (pbm->msiq_num) { - const struct msiq_prop { - u32 first_msiq; - u32 num_msiq; - u32 first_devino; - } *mqp; - const struct msi_range_prop { - u32 first_msi; - u32 num_msi; - } *mrng; - const struct addr_range_prop { - u32 msi32_high; - u32 msi32_low; - u32 msi32_len; - u32 msi64_high; - u32 msi64_low; - u32 msi64_len; - } *arng; - - val = of_get_property(pbm->prom_node, "msi-eq-size", &len); - if (!val || len != 4) - goto no_msi; - - pbm->msiq_ent_count = *val; - - mqp = of_get_property(pbm->prom_node, - "msi-eq-to-devino", &len); - if (!mqp || len != sizeof(struct msiq_prop)) - goto no_msi; - - pbm->msiq_first = mqp->first_msiq; - pbm->msiq_first_devino = mqp->first_devino; - - val = of_get_property(pbm->prom_node, "#msi", &len); - if (!val || len != 4) - goto no_msi; - pbm->msi_num = *val; - - mrng = of_get_property(pbm->prom_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); - if (!val || len != 4) - goto no_msi; - pbm->msi_data_mask = *val; - - val = of_get_property(pbm->prom_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", - &len); - if (!arng || len != sizeof(struct addr_range_prop)) - goto no_msi; - pbm->msi32_start = ((u64)arng->msi32_high << 32) | - (u64) arng->msi32_low; - pbm->msi64_start = ((u64)arng->msi64_high << 32) | - (u64) arng->msi64_low; - pbm->msi32_len = arng->msi32_len; - pbm->msi64_len = arng->msi64_len; - - if (msi_bitmap_alloc(pbm)) - goto no_msi; - - if (msi_queue_alloc(pbm)) { - msi_bitmap_free(pbm); - goto no_msi; - } - - printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " - "devino[0x%x]\n", - pbm->name, - pbm->msiq_first, pbm->msiq_num, - pbm->msiq_ent_count, - pbm->msiq_first_devino); - printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " - "width[%u]\n", - pbm->name, - pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, - pbm->msix_data_width); - printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " - "addr64[0x%lx:0x%x]\n", - pbm->name, - pbm->msi32_start, pbm->msi32_len, - pbm->msi64_start, pbm->msi64_len); - printk(KERN_INFO "%s: MSI queues at RA [%p]\n", - pbm->name, - pbm->msi_queues); - } - - return; - -no_msi: - pbm->msiq_num = 0; - printk(KERN_INFO "%s: No MSI support.\n", pbm->name); -} static int alloc_msi(struct pci_pbm_info *pbm) { @@ -1217,6 +1109,117 @@ static void pci_sun4v_teardown_msi_irq(unsigned int virt_irq, */ sun4v_destroy_msi(virt_irq); } + +static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) +{ + const u32 *val; + int len; + + val = of_get_property(pbm->prom_node, "#msi-eqs", &len); + if (!val || len != 4) + goto no_msi; + pbm->msiq_num = *val; + if (pbm->msiq_num) { + const struct msiq_prop { + u32 first_msiq; + u32 num_msiq; + u32 first_devino; + } *mqp; + const struct msi_range_prop { + u32 first_msi; + u32 num_msi; + } *mrng; + const struct addr_range_prop { + u32 msi32_high; + u32 msi32_low; + u32 msi32_len; + u32 msi64_high; + u32 msi64_low; + u32 msi64_len; + } *arng; + + val = of_get_property(pbm->prom_node, "msi-eq-size", &len); + if (!val || len != 4) + goto no_msi; + + pbm->msiq_ent_count = *val; + + mqp = of_get_property(pbm->prom_node, + "msi-eq-to-devino", &len); + if (!mqp || len != sizeof(struct msiq_prop)) + goto no_msi; + + pbm->msiq_first = mqp->first_msiq; + pbm->msiq_first_devino = mqp->first_devino; + + val = of_get_property(pbm->prom_node, "#msi", &len); + if (!val || len != 4) + goto no_msi; + pbm->msi_num = *val; + + mrng = of_get_property(pbm->prom_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); + if (!val || len != 4) + goto no_msi; + pbm->msi_data_mask = *val; + + val = of_get_property(pbm->prom_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", + &len); + if (!arng || len != sizeof(struct addr_range_prop)) + goto no_msi; + pbm->msi32_start = ((u64)arng->msi32_high << 32) | + (u64) arng->msi32_low; + pbm->msi64_start = ((u64)arng->msi64_high << 32) | + (u64) arng->msi64_low; + pbm->msi32_len = arng->msi32_len; + pbm->msi64_len = arng->msi64_len; + + if (msi_bitmap_alloc(pbm)) + goto no_msi; + + if (msi_queue_alloc(pbm)) { + msi_bitmap_free(pbm); + goto no_msi; + } + + printk(KERN_INFO "%s: MSI Queue first[%u] num[%u] count[%u] " + "devino[0x%x]\n", + pbm->name, + pbm->msiq_first, pbm->msiq_num, + pbm->msiq_ent_count, + pbm->msiq_first_devino); + printk(KERN_INFO "%s: MSI first[%u] num[%u] mask[0x%x] " + "width[%u]\n", + pbm->name, + pbm->msi_first, pbm->msi_num, pbm->msi_data_mask, + pbm->msix_data_width); + printk(KERN_INFO "%s: MSI addr32[0x%lx:0x%x] " + "addr64[0x%lx:0x%x]\n", + pbm->name, + pbm->msi32_start, pbm->msi32_len, + pbm->msi64_start, pbm->msi64_len); + printk(KERN_INFO "%s: MSI queues at RA [%p]\n", + pbm->name, + pbm->msi_queues); + } + pbm->setup_msi_irq = pci_sun4v_setup_msi_irq; + pbm->teardown_msi_irq = pci_sun4v_teardown_msi_irq; + + return; + +no_msi: + pbm->msiq_num = 0; + printk(KERN_INFO "%s: No MSI support.\n", pbm->name); +} #else /* CONFIG_PCI_MSI */ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm) { @@ -1303,11 +1306,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->index = pci_num_controllers++; -#ifdef CONFIG_PCI_MSI - p->setup_msi_irq = pci_sun4v_setup_msi_irq; - p->teardown_msi_irq = pci_sun4v_teardown_msi_irq; -#endif - /* Like PSYCHO and SCHIZO we have a 2GB aligned area * for memory space. */ -- cgit v1.2.2 From 6c108f1299754877bb5f73ccac5621eb603b97eb Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 7 May 2007 23:49:01 -0700 Subject: [SPARC64]: Move index info pci_pbm_info. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/sparc64/kernel/pci_sun4v.c') diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 7ebc04f9a880..ce46b0471693 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1241,6 +1241,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node pbm->scan_bus = pci_sun4v_scan_bus; pbm->pci_ops = &pci_sun4v_ops; + pbm->index = pci_num_pbms++; + pbm->parent = p; pbm->prom_node = dp; @@ -1304,8 +1306,6 @@ void sun4v_pci_init(struct device_node *dp, char *model_name) p->pbm_B.iommu = iommu; - p->index = pci_num_controllers++; - /* Like PSYCHO and SCHIZO we have a 2GB aligned area * for memory space. */ -- cgit v1.2.2 From c57c2ffb153a99769a15a2ff1729371ddee5601a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 8 May 2007 00:43:56 -0700 Subject: [SPARC64]: Kill asm-sparc64/pbm.h Everything it contains can be hidden in pci_impl.h Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/sparc64/kernel/pci_sun4v.c') diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index ce46b0471693..0c76a8891a96 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include -- cgit v1.2.2