diff options
-rw-r--r-- | arch/powerpc/platforms/iseries/iommu.c | 29 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/pci.c | 91 | ||||
-rw-r--r-- | arch/powerpc/platforms/iseries/vpdinfo.c | 2 | ||||
-rw-r--r-- | arch/ppc64/kernel/pci_iommu.c | 6 | ||||
-rw-r--r-- | include/asm-ppc64/iSeries/iSeries_pci.h | 30 | ||||
-rw-r--r-- | include/asm-ppc64/iommu.h | 4 | ||||
-rw-r--r-- | include/asm-ppc64/pci-bridge.h | 10 | ||||
-rw-r--r-- | include/asm-ppc64/prom.h | 3 |
8 files changed, 88 insertions, 87 deletions
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index 65c76dd1d3d..9ac735d5b81 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c @@ -89,15 +89,17 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages) */ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) { - struct iSeries_Device_Node *dp; + struct device_node *dp; list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) { - if ((dp->iommu_table != NULL) && - (dp->iommu_table->it_type == TCE_PCI) && - (dp->iommu_table->it_offset == tbl->it_offset) && - (dp->iommu_table->it_index == tbl->it_index) && - (dp->iommu_table->it_size == tbl->it_size)) - return dp->iommu_table; + struct iommu_table *it = PCI_DN(dp)->iommu_table; + + if ((it != NULL) && + (it->it_type == TCE_PCI) && + (it->it_offset == tbl->it_offset) && + (it->it_index == tbl->it_index) && + (it->it_size == tbl->it_size)) + return it; } return NULL; } @@ -111,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl) * 2. TCE table per Bus. * 3. TCE Table per IOA. */ -static void iommu_table_getparms(struct iSeries_Device_Node* dn, +static void iommu_table_getparms(struct device_node *dn, struct iommu_table* tbl) { struct iommu_table_cb *parms; @@ -123,7 +125,7 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, memset(parms, 0, sizeof(*parms)); parms->itc_busno = ISERIES_BUS(dn); - parms->itc_slotno = dn->LogicalSlot; + parms->itc_slotno = PCI_DN(dn)->LogicalSlot; parms->itc_virtbus = 0; HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms)); @@ -143,18 +145,19 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn, } -void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) +void iommu_devnode_init_iSeries(struct device_node *dn) { struct iommu_table *tbl; + struct pci_dn *pdn = PCI_DN(dn); tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); iommu_table_getparms(dn, tbl); /* Look for existing tce table */ - dn->iommu_table = iommu_table_find(tbl); - if (dn->iommu_table == NULL) - dn->iommu_table = iommu_init_table(tbl); + pdn->iommu_table = iommu_table_find(tbl); + if (pdn->iommu_table == NULL) + pdn->iommu_table = iommu_init_table(tbl); else kfree(tbl); } diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index 61a857218bc..501b1dcbfac 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c @@ -48,7 +48,7 @@ extern unsigned long io_page_mask; /* * Forward declares of prototypes. */ -static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn); +static struct device_node *find_Device_Node(int bus, int devfn); static void scan_PHB_slots(struct pci_controller *Phb); static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel); static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info); @@ -85,7 +85,7 @@ static long current_iomm_table_entry; /* * Lookup Tables. */ -static struct iSeries_Device_Node **iomm_table; +static struct device_node **iomm_table; static u8 *iobar_table; /* @@ -199,29 +199,35 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, /* * build_device_node(u16 Bus, int SubBus, u8 DevFn) */ -static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus, +static struct device_node *build_device_node(HvBusNumber Bus, HvSubBusNumber SubBus, int AgentId, int Function) { - struct iSeries_Device_Node *node; + struct device_node *node; + struct pci_dn *pdn; PPCDBG(PPCDBG_BUSWALK, "-build_device_node 0x%02X.%02X.%02X Function: %02X\n", Bus, SubBus, AgentId, Function); - node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL); + node = kmalloc(sizeof(struct device_node), GFP_KERNEL); if (node == NULL) return NULL; - - memset(node, 0, sizeof(struct iSeries_Device_Node)); + memset(node, 0, sizeof(struct device_node)); + pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); + if (pdn == NULL) { + kfree(node); + return NULL; + } + node->data = pdn; list_add_tail(&node->Device_List, &iSeries_Global_Device_List); #if 0 - node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); + pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); #endif - node->DsaAddr.DsaAddr = 0; - node->DsaAddr.Dsa.busNumber = Bus; - node->DsaAddr.Dsa.subBusNumber = SubBus; - node->DsaAddr.Dsa.deviceId = 0x10; - node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); + pdn->DsaAddr.DsaAddr = 0; + pdn->DsaAddr.Dsa.busNumber = Bus; + pdn->DsaAddr.Dsa.subBusNumber = SubBus; + pdn->DsaAddr.Dsa.deviceId = 0x10; + pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); return node; } @@ -294,7 +300,7 @@ void iSeries_pcibios_init(void) void __init iSeries_pci_final_fixup(void) { struct pci_dev *pdev = NULL; - struct iSeries_Device_Node *node; + struct device_node *node; int DeviceCount = 0; PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); @@ -311,7 +317,7 @@ void __init iSeries_pci_final_fixup(void) if (node != NULL) { ++DeviceCount; pdev->sysdata = (void *)node; - node->PciDev = pdev; + PCI_DN(node)->pcidev = pdev; PPCDBG(PPCDBG_BUSWALK, "pdev 0x%p <==> DevNode 0x%p\n", pdev, node); @@ -321,7 +327,7 @@ void __init iSeries_pci_final_fixup(void) } else printk("PCI: Device Tree not found for 0x%016lX\n", (unsigned long)pdev); - pdev->irq = node->Irq; + pdev->irq = PCI_DN(node)->Irq; } iSeries_activate_IRQs(); mf_display_src(0xC9000200); @@ -439,7 +445,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *BridgeInfo) { - struct iSeries_Device_Node *node; + struct device_node *node; HvSubBusNumber SubBus = BridgeInfo->subBusNumber; u16 VendorId = 0; int HvRc = 0; @@ -489,8 +495,8 @@ static int scan_bridge_slot(HvBusNumber Bus, ++DeviceCount; node = build_device_node(Bus, SubBus, EADsIdSel, Function); - node->Irq = Irq; - node->LogicalSlot = BridgeInfo->logicalSlotNumber; + PCI_DN(node)->Irq = Irq; + PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber; } /* for (Function = 0; Function < 8; ++Function) */ } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */ @@ -540,15 +546,16 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio); /* * Look down the chain to find the matching Device Device */ -static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn) +static struct device_node *find_Device_Node(int bus, int devfn) { struct list_head *pos; list_for_each(pos, &iSeries_Global_Device_List) { - struct iSeries_Device_Node *node = - list_entry(pos, struct iSeries_Device_Node, Device_List); + struct device_node *node = + list_entry(pos, struct device_node, Device_List); - if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn)) + if ((bus == ISERIES_BUS(node)) && + (devfn == PCI_DN(node)->devfn)) return node; } return NULL; @@ -560,12 +567,12 @@ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn) * Sanity Check Node PciDev to passed pci_dev * If none is found, returns a NULL which the client must handle. */ -static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev) +static struct device_node *get_Device_Node(struct pci_dev *pdev) { - struct iSeries_Device_Node *node; + struct device_node *node; node = pdev->sysdata; - if (node == NULL || node->PciDev != pdev) + if (node == NULL || PCI_DN(node)->pcidev != pdev) node = find_Device_Node(pdev->bus->number, pdev->devfn); return node; } @@ -593,7 +600,7 @@ static u64 hv_cfg_write_func[4] = { static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, int offset, int size, u32 *val) { - struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn); + struct device_node *node = find_Device_Node(bus->number, devfn); u64 fn; struct HvCallPci_LoadReturn ret; @@ -605,7 +612,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, } fn = hv_cfg_read_func[(size - 1) & 3]; - HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0); + HvCall3Ret16(fn, &ret, PCI_DN(node)->DsaAddr.DsaAddr, offset, 0); if (ret.rc != 0) { *val = ~0; @@ -623,7 +630,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, int offset, int size, u32 val) { - struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn); + struct device_node *node = find_Device_Node(bus->number, devfn); u64 fn; u64 ret; @@ -633,7 +640,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, return PCIBIOS_BAD_REGISTER_NUMBER; fn = hv_cfg_write_func[(size - 1) & 3]; - ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0); + ret = HvCall4(fn, PCI_DN(node)->DsaAddr.DsaAddr, offset, val, 0); if (ret != 0) return PCIBIOS_DEVICE_NOT_FOUND; @@ -655,14 +662,16 @@ static struct pci_ops iSeries_pci_ops = { * PCI: Device 23.90 ReadL Retry( 1) * PCI: Device 23.90 ReadL Retry Successful(1) */ -static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, +static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, int *retry, u64 ret) { if (ret != 0) { + struct pci_dn *pdn = PCI_DN(DevNode); + ++Pci_Error_Count; (*retry)++; printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", - TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn, + TextHdr, pdn->DsaAddr.Dsa.busNumber, pdn->devfn, *retry, (int)ret); /* * Bump the retry and check for retry count exceeded. @@ -685,14 +694,14 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, * Note: Make sure the passed variable end up on the stack to avoid * the exposure of being device global. */ -static inline struct iSeries_Device_Node *xlate_iomm_address( +static inline struct device_node *xlate_iomm_address( const volatile void __iomem *IoAddress, u64 *dsaptr, u64 *BarOffsetPtr) { unsigned long OrigIoAddr; unsigned long BaseIoAddr; unsigned long TableIndex; - struct iSeries_Device_Node *DevNode; + struct device_node *DevNode; OrigIoAddr = (unsigned long __force)IoAddress; if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory)) @@ -703,7 +712,7 @@ static inline struct iSeries_Device_Node *xlate_iomm_address( if (DevNode != NULL) { int barnum = iobar_table[TableIndex]; - *dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24); + *dsaptr = PCI_DN(DevNode)->DsaAddr.DsaAddr | (barnum << 24); *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; } else panic("PCI: Invalid PCI IoAddress detected!\n"); @@ -725,7 +734,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) u64 dsa; int retry = 0; struct HvCallPci_LoadReturn ret; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -755,7 +764,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) u64 dsa; int retry = 0; struct HvCallPci_LoadReturn ret; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -786,7 +795,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) u64 dsa; int retry = 0; struct HvCallPci_LoadReturn ret; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -824,7 +833,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) u64 dsa; int retry = 0; u64 rc; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -852,7 +861,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) u64 dsa; int retry = 0; u64 rc; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { @@ -880,7 +889,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) u64 dsa; int retry = 0; u64 rc; - struct iSeries_Device_Node *DevNode = + struct device_node *DevNode = xlate_iomm_address(IoAddress, &dsa, &BarOffset); if (DevNode == NULL) { diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c index 8b62f3bf1d2..d8a6796924e 100644 --- a/arch/powerpc/platforms/iseries/vpdinfo.c +++ b/arch/powerpc/platforms/iseries/vpdinfo.c @@ -240,7 +240,7 @@ out_free: */ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) { - struct iSeries_Device_Node *DevNode = PciDev->sysdata; + struct device_node *DevNode = PciDev->sysdata; u16 bus; u8 frame; char card[4]; diff --git a/arch/ppc64/kernel/pci_iommu.c b/arch/ppc64/kernel/pci_iommu.c index 19362ea1157..6c9dc67f59d 100644 --- a/arch/ppc64/kernel/pci_iommu.c +++ b/arch/ppc64/kernel/pci_iommu.c @@ -61,13 +61,7 @@ static inline struct iommu_table *devnode_table(struct device *dev) } else pdev = to_pci_dev(dev); -#ifdef CONFIG_PPC_ISERIES - return ISERIES_DEVNODE(pdev)->iommu_table; -#endif /* CONFIG_PPC_ISERIES */ - -#ifdef CONFIG_PPC_MULTIPLATFORM return PCI_DN(PCI_GET_DN(pdev))->iommu_table; -#endif /* CONFIG_PPC_MULTIPLATFORM */ } diff --git a/include/asm-ppc64/iSeries/iSeries_pci.h b/include/asm-ppc64/iSeries/iSeries_pci.h index 575f611f8b3..a4d88b49fd9 100644 --- a/include/asm-ppc64/iSeries/iSeries_pci.h +++ b/include/asm-ppc64/iSeries/iSeries_pci.h @@ -30,21 +30,19 @@ * End Change Activity */ -#include <asm/iSeries/HvCallPci.h> #include <asm/abs_addr.h> +#include <asm/prom.h> +#include <asm/pci-bridge.h> struct pci_dev; /* For Forward Reference */ -struct iSeries_Device_Node; /* - * Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure + * Gets iSeries Bus, SubBus, DevFn using device_node structure */ -#define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber -#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber -#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId -#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr -#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata) +#define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber +#define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber +#define ISERIES_DEVNODE(PciDev) ((struct device_node *)PciDev->sysdata) #define EADsMaxAgents 7 @@ -67,22 +65,6 @@ struct iSeries_Device_Node; #define ISERIES_HV_ADDR(virtaddr) \ (0x8000000000000000 | virt_to_abs(virtaddr)) -/* - * iSeries Device Information - */ -struct iSeries_Device_Node { - struct list_head Device_List; - struct pci_dev *PciDev; - union HvDsaMap DsaAddr; /* Direct Select Address */ - /* busNumber, subBusNumber, */ - /* deviceId, barNumber */ - int DevFn; /* Linux devfn */ - int Irq; /* Assigned IRQ */ - int Flags; /* Possible flags(disable/bist)*/ - u8 LogicalSlot; /* Hv Slot Index for Tces */ - struct iommu_table *iommu_table;/* Device TCE Table */ -}; - extern void iSeries_Device_Information(struct pci_dev*, int); #endif /* _ISERIES_64_PCI_H */ diff --git a/include/asm-ppc64/iommu.h b/include/asm-ppc64/iommu.h index a6a173d4950..d096faf4191 100644 --- a/include/asm-ppc64/iommu.h +++ b/include/asm-ppc64/iommu.h @@ -49,6 +49,7 @@ struct iommu_table { }; struct scatterlist; +struct device_node; #ifdef CONFIG_PPC_MULTIPLATFORM @@ -70,9 +71,8 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn); #ifdef CONFIG_PPC_ISERIES -struct iSeries_Device_Node; /* Creates table for an individual device node */ -extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn); +extern void iommu_devnode_init_iSeries(struct device_node *dn); #endif /* CONFIG_PPC_ISERIES */ diff --git a/include/asm-ppc64/pci-bridge.h b/include/asm-ppc64/pci-bridge.h index d8991389ab3..8ca5fce626b 100644 --- a/include/asm-ppc64/pci-bridge.h +++ b/include/asm-ppc64/pci-bridge.h @@ -4,6 +4,8 @@ #include <linux/pci.h> +#include <asm/iSeries/HvCallPci.h> + /* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -71,6 +73,14 @@ struct pci_dn { struct iommu_table *iommu_table; /* for phb's or bridges */ struct pci_dev *pcidev; /* back-pointer to the pci device */ struct device_node *node; /* back-pointer to the device_node */ +#ifdef CONFIG_PPC_ISERIES + union HvDsaMap DsaAddr; /* Direct Select Address */ + /* busNumber, subBusNumber, */ + /* deviceId, barNumber */ + int Irq; /* Assigned IRQ */ + int Flags; /* Possible flags(disable/bist)*/ + u8 LogicalSlot; /* Hv Slot Index for Tces */ +#endif u32 config_space[16]; /* saved PCI config space */ }; diff --git a/include/asm-ppc64/prom.h b/include/asm-ppc64/prom.h index c02ec1d6b90..cf0284e081e 100644 --- a/include/asm-ppc64/prom.h +++ b/include/asm-ppc64/prom.h @@ -137,6 +137,9 @@ struct device_node { struct kref kref; unsigned long _flags; void *data; +#ifdef CONFIG_PPC_ISERIES + struct list_head Device_List; +#endif }; extern struct device_node *of_chosen; |