aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-02-23 22:19:03 -0500
committerBjorn Helgaas <bhelgaas@google.com>2012-02-23 22:19:03 -0500
commit39c2462e163448c7df466c7262109ec6a24d5f88 (patch)
tree58edadf5be6f48cc845baeaa1c5b58cd00591605
parent4b84b6e9b43cab04099ba7055322d31dbd789475 (diff)
parisc/PCI: get rid of device resource fixups
Tell the PCI core about host bridge address translation so it can take care of bus-to-resource conversion for us. CC: linux-parisc@vger.kernel.org Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--arch/parisc/include/asm/pci.h38
-rw-r--r--arch/parisc/kernel/pci.c52
-rw-r--r--drivers/parisc/dino.c27
-rw-r--r--drivers/parisc/lba_pci.c31
4 files changed, 13 insertions, 135 deletions
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h
index 2242a5c636c2..a8b591fdd564 100644
--- a/arch/parisc/include/asm/pci.h
+++ b/arch/parisc/include/asm/pci.h
@@ -82,38 +82,8 @@ struct pci_hba_data {
82 82
83#ifdef CONFIG_64BIT 83#ifdef CONFIG_64BIT
84#define PCI_F_EXTEND 0xffffffff00000000UL 84#define PCI_F_EXTEND 0xffffffff00000000UL
85#define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a)
86
87/* We need to know if an address is LMMMIO or GMMIO.
88 * LMMIO requires mangling and GMMIO we must use as-is.
89 */
90static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a)
91{
92 return(((a) & PCI_F_EXTEND) == PCI_F_EXTEND);
93}
94
95/*
96** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses.
97** See pci.c for more conversions used by Generic PCI code.
98**
99** Platform characteristics/firmware guarantee that
100** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO
101** (2) PA_VIEW == IO_VIEW for GMMIO
102*/
103#define PCI_BUS_ADDR(hba,a) (PCI_IS_LMMIO(hba,a) \
104 ? ((a) - hba->lmmio_space_offset) /* mangle LMMIO */ \
105 : (a)) /* GMMIO */
106#define PCI_HOST_ADDR(hba,a) (((a) & PCI_F_EXTEND) == 0 \
107 ? (a) + hba->lmmio_space_offset \
108 : (a))
109
110#else /* !CONFIG_64BIT */ 85#else /* !CONFIG_64BIT */
111
112#define PCI_BUS_ADDR(hba,a) (a)
113#define PCI_HOST_ADDR(hba,a) (a)
114#define PCI_F_EXTEND 0UL 86#define PCI_F_EXTEND 0UL
115#define PCI_IS_LMMIO(hba,a) (1) /* 32-bit doesn't support GMMIO */
116
117#endif /* !CONFIG_64BIT */ 87#endif /* !CONFIG_64BIT */
118 88
119/* 89/*
@@ -245,13 +215,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
245} 215}
246#endif 216#endif
247 217
248extern void 218#define ARCH_HAS_GENERIC_PCI_OFFSETS
249pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
250 struct resource *res);
251
252extern void
253pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
254 struct pci_bus_region *region);
255 219
256static inline void pcibios_penalize_isa_irq(int irq, int active) 220static inline void pcibios_penalize_isa_irq(int irq, int active)
257{ 221{
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index 9efd97405317..74d544b1cd22 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -195,58 +195,6 @@ void __init pcibios_init_bus(struct pci_bus *bus)
195 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); 195 pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl);
196} 196}
197 197
198/* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */
199void __devinit pcibios_resource_to_bus(struct pci_dev *dev,
200 struct pci_bus_region *region, struct resource *res)
201{
202#ifdef CONFIG_64BIT
203 struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
204#endif
205
206 if (res->flags & IORESOURCE_IO) {
207 /*
208 ** I/O space may see busnumbers here. Something
209 ** in the form of 0xbbxxxx where bb is the bus num
210 ** and xxxx is the I/O port space address.
211 ** Remaining address translation are done in the
212 ** PCI Host adapter specific code - ie dino_out8.
213 */
214 region->start = PCI_PORT_ADDR(res->start);
215 region->end = PCI_PORT_ADDR(res->end);
216 } else if (res->flags & IORESOURCE_MEM) {
217 /* Convert MMIO addr to PCI addr (undo global virtualization) */
218 region->start = PCI_BUS_ADDR(hba, res->start);
219 region->end = PCI_BUS_ADDR(hba, res->end);
220 }
221
222 DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n",
223 dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM",
224 region->start, region->end);
225}
226
227void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
228 struct pci_bus_region *region)
229{
230#ifdef CONFIG_64BIT
231 struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data);
232#endif
233
234 if (res->flags & IORESOURCE_MEM) {
235 res->start = PCI_HOST_ADDR(hba, region->start);
236 res->end = PCI_HOST_ADDR(hba, region->end);
237 }
238
239 if (res->flags & IORESOURCE_IO) {
240 res->start = region->start;
241 res->end = region->end;
242 }
243}
244
245#ifdef CONFIG_HOTPLUG
246EXPORT_SYMBOL(pcibios_resource_to_bus);
247EXPORT_SYMBOL(pcibios_bus_to_resource);
248#endif
249
250/* 198/*
251 * pcibios align resources() is called every time generic PCI code 199 * pcibios align resources() is called every time generic PCI code
252 * wants to generate a new address. The process of looking for 200 * wants to generate a new address. The process of looking for
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 7ff10c1e8664..0610e91bceb2 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -553,7 +553,6 @@ dino_fixup_bus(struct pci_bus *bus)
553 struct list_head *ln; 553 struct list_head *ln;
554 struct pci_dev *dev; 554 struct pci_dev *dev;
555 struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); 555 struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));
556 int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num);
557 556
558 DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", 557 DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n",
559 __func__, bus, bus->secondary, 558 __func__, bus, bus->secondary,
@@ -599,8 +598,6 @@ dino_fixup_bus(struct pci_bus *bus)
599 598
600 599
601 list_for_each(ln, &bus->devices) { 600 list_for_each(ln, &bus->devices) {
602 int i;
603
604 dev = pci_dev_b(ln); 601 dev = pci_dev_b(ln);
605 if (is_card_dino(&dino_dev->hba.dev->id)) 602 if (is_card_dino(&dino_dev->hba.dev->id))
606 dino_card_fixup(dev); 603 dino_card_fixup(dev);
@@ -612,21 +609,6 @@ dino_fixup_bus(struct pci_bus *bus)
612 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) 609 if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)
613 continue; 610 continue;
614 611
615 /* Adjust the I/O Port space addresses */
616 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
617 struct resource *res = &dev->resource[i];
618 if (res->flags & IORESOURCE_IO) {
619 res->start |= port_base;
620 res->end |= port_base;
621 }
622#ifdef __LP64__
623 /* Sign Extend MMIO addresses */
624 else if (res->flags & IORESOURCE_MEM) {
625 res->start |= F_EXTEND(0UL);
626 res->end |= F_EXTEND(0UL);
627 }
628#endif
629 }
630 /* null out the ROM resource if there is one (we don't 612 /* null out the ROM resource if there is one (we don't
631 * care about an expansion rom on parisc, since it 613 * care about an expansion rom on parisc, since it
632 * usually contains (x86) bios code) */ 614 * usually contains (x86) bios code) */
@@ -991,11 +973,14 @@ static int __init dino_probe(struct parisc_device *dev)
991 973
992 dev->dev.platform_data = dino_dev; 974 dev->dev.platform_data = dino_dev;
993 975
994 pci_add_resource(&resources, &dino_dev->hba.io_space); 976 pci_add_resource_offset(&resources, &dino_dev->hba.io_space,
977 HBA_PORT_BASE(dino_dev->hba.hba_num));
995 if (dino_dev->hba.lmmio_space.flags) 978 if (dino_dev->hba.lmmio_space.flags)
996 pci_add_resource(&resources, &dino_dev->hba.lmmio_space); 979 pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space,
980 dino_dev->hba.lmmio_space_offset);
997 if (dino_dev->hba.elmmio_space.flags) 981 if (dino_dev->hba.elmmio_space.flags)
998 pci_add_resource(&resources, &dino_dev->hba.elmmio_space); 982 pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space,
983 dino_dev->hba.lmmio_space_offset);
999 if (dino_dev->hba.gmmio_space.flags) 984 if (dino_dev->hba.gmmio_space.flags)
1000 pci_add_resource(&resources, &dino_dev->hba.gmmio_space); 985 pci_add_resource(&resources, &dino_dev->hba.gmmio_space);
1001 986
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index d5f3d753a108..e8857647e210 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -635,7 +635,6 @@ lba_fixup_bus(struct pci_bus *bus)
635 u16 status; 635 u16 status;
636#endif 636#endif
637 struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); 637 struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge));
638 int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num);
639 638
640 DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", 639 DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n",
641 bus, bus->secondary, bus->bridge->platform_data); 640 bus, bus->secondary, bus->bridge->platform_data);
@@ -726,27 +725,6 @@ lba_fixup_bus(struct pci_bus *bus)
726 if (!res->start) 725 if (!res->start)
727 continue; 726 continue;
728 727
729 if (res->flags & IORESOURCE_IO) {
730 DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ",
731 res->start, res->end);
732 res->start |= lba_portbase;
733 res->end |= lba_portbase;
734 DBG("[%lx/%lx]\n", res->start, res->end);
735 } else if (res->flags & IORESOURCE_MEM) {
736 /*
737 ** Convert PCI (IO_VIEW) addresses to
738 ** processor (PA_VIEW) addresses
739 */
740 DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ",
741 res->start, res->end);
742 res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start);
743 res->end = PCI_HOST_ADDR(HBA_DATA(ldev), res->end);
744 DBG("[%lx/%lx]\n", res->start, res->end);
745 } else {
746 DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX",
747 res->flags, res->start, res->end);
748 }
749
750 /* 728 /*
751 ** FIXME: this will result in whinging for devices 729 ** FIXME: this will result in whinging for devices
752 ** that share expansion ROMs (think quad tulip), but 730 ** that share expansion ROMs (think quad tulip), but
@@ -1514,11 +1492,14 @@ lba_driver_probe(struct parisc_device *dev)
1514 lba_dev->hba.lmmio_space.flags = 0; 1492 lba_dev->hba.lmmio_space.flags = 0;
1515 } 1493 }
1516 1494
1517 pci_add_resource(&resources, &lba_dev->hba.io_space); 1495 pci_add_resource_offset(&resources, &lba_dev->hba.io_space,
1496 HBA_PORT_BASE(lba_dev->hba.hba_num));
1518 if (lba_dev->hba.elmmio_space.start) 1497 if (lba_dev->hba.elmmio_space.start)
1519 pci_add_resource(&resources, &lba_dev->hba.elmmio_space); 1498 pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space,
1499 lba_dev->hba.lmmio_space_offset);
1520 if (lba_dev->hba.lmmio_space.flags) 1500 if (lba_dev->hba.lmmio_space.flags)
1521 pci_add_resource(&resources, &lba_dev->hba.lmmio_space); 1501 pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space,
1502 lba_dev->hba.lmmio_space_offset);
1522 if (lba_dev->hba.gmmio_space.flags) 1503 if (lba_dev->hba.gmmio_space.flags)
1523 pci_add_resource(&resources, &lba_dev->hba.gmmio_space); 1504 pci_add_resource(&resources, &lba_dev->hba.gmmio_space);
1524 1505