aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
authorMichael Ellerman <mpe@ellerman.id.au>2015-04-06 23:24:55 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-04-06 23:24:55 -0400
commit428d4d6520a0b8683fe9eac6df3077001e13d00b (patch)
tree8afa1af0babc8f2c375acc244aae969846dfe199 /arch/powerpc/platforms/pseries
parent28ea605caac49497e5e34a73ee4f4682fc035f1d (diff)
parent027fa02f84e851e21daffdf8900d6117071890f8 (diff)
Merge branch 'next-eeh' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc into next
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c98
-rw-r--r--arch/powerpc/platforms/pseries/msi.c6
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c2
4 files changed, 41 insertions, 67 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index a6c7e19f5eb3..2039397cc75d 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -118,9 +118,8 @@ static int pseries_eeh_init(void)
118 return 0; 118 return 0;
119} 119}
120 120
121static int pseries_eeh_cap_start(struct device_node *dn) 121static int pseries_eeh_cap_start(struct pci_dn *pdn)
122{ 122{
123 struct pci_dn *pdn = PCI_DN(dn);
124 u32 status; 123 u32 status;
125 124
126 if (!pdn) 125 if (!pdn)
@@ -134,10 +133,9 @@ static int pseries_eeh_cap_start(struct device_node *dn)
134} 133}
135 134
136 135
137static int pseries_eeh_find_cap(struct device_node *dn, int cap) 136static int pseries_eeh_find_cap(struct pci_dn *pdn, int cap)
138{ 137{
139 struct pci_dn *pdn = PCI_DN(dn); 138 int pos = pseries_eeh_cap_start(pdn);
140 int pos = pseries_eeh_cap_start(dn);
141 int cnt = 48; /* Maximal number of capabilities */ 139 int cnt = 48; /* Maximal number of capabilities */
142 u32 id; 140 u32 id;
143 141
@@ -160,10 +158,9 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap)
160 return 0; 158 return 0;
161} 159}
162 160
163static int pseries_eeh_find_ecap(struct device_node *dn, int cap) 161static int pseries_eeh_find_ecap(struct pci_dn *pdn, int cap)
164{ 162{
165 struct pci_dn *pdn = PCI_DN(dn); 163 struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
166 struct eeh_dev *edev = of_node_to_eeh_dev(dn);
167 u32 header; 164 u32 header;
168 int pos = 256; 165 int pos = 256;
169 int ttl = (4096 - 256) / 8; 166 int ttl = (4096 - 256) / 8;
@@ -191,53 +188,44 @@ static int pseries_eeh_find_ecap(struct device_node *dn, int cap)
191} 188}
192 189
193/** 190/**
194 * pseries_eeh_of_probe - EEH probe on the given device 191 * pseries_eeh_probe - EEH probe on the given device
195 * @dn: OF node 192 * @pdn: PCI device node
196 * @flag: Unused 193 * @data: Unused
197 * 194 *
198 * When EEH module is installed during system boot, all PCI devices 195 * When EEH module is installed during system boot, all PCI devices
199 * are checked one by one to see if it supports EEH. The function 196 * are checked one by one to see if it supports EEH. The function
200 * is introduced for the purpose. 197 * is introduced for the purpose.
201 */ 198 */
202static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) 199static void *pseries_eeh_probe(struct pci_dn *pdn, void *data)
203{ 200{
204 struct eeh_dev *edev; 201 struct eeh_dev *edev;
205 struct eeh_pe pe; 202 struct eeh_pe pe;
206 struct pci_dn *pdn = PCI_DN(dn);
207 const __be32 *classp, *vendorp, *devicep;
208 u32 class_code;
209 const __be32 *regs;
210 u32 pcie_flags; 203 u32 pcie_flags;
211 int enable = 0; 204 int enable = 0;
212 int ret; 205 int ret;
213 206
214 /* Retrieve OF node and eeh device */ 207 /* Retrieve OF node and eeh device */
215 edev = of_node_to_eeh_dev(dn); 208 edev = pdn_to_eeh_dev(pdn);
216 if (edev->pe || !of_device_is_available(dn)) 209 if (!edev || edev->pe)
217 return NULL; 210 return NULL;
218 211
219 /* Retrieve class/vendor/device IDs */ 212 /* Check class/vendor/device IDs */
220 classp = of_get_property(dn, "class-code", NULL); 213 if (!pdn->vendor_id || !pdn->device_id || !pdn->class_code)
221 vendorp = of_get_property(dn, "vendor-id", NULL);
222 devicep = of_get_property(dn, "device-id", NULL);
223
224 /* Skip for bad OF node or PCI-ISA bridge */
225 if (!classp || !vendorp || !devicep)
226 return NULL;
227 if (dn->type && !strcmp(dn->type, "isa"))
228 return NULL; 214 return NULL;
229 215
230 class_code = of_read_number(classp, 1); 216 /* Skip for PCI-ISA bridge */
217 if ((pdn->class_code >> 8) == PCI_CLASS_BRIDGE_ISA)
218 return NULL;
231 219
232 /* 220 /*
233 * Update class code and mode of eeh device. We need 221 * Update class code and mode of eeh device. We need
234 * correctly reflects that current device is root port 222 * correctly reflects that current device is root port
235 * or PCIe switch downstream port. 223 * or PCIe switch downstream port.
236 */ 224 */
237 edev->class_code = class_code; 225 edev->class_code = pdn->class_code;
238 edev->pcix_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_PCIX); 226 edev->pcix_cap = pseries_eeh_find_cap(pdn, PCI_CAP_ID_PCIX);
239 edev->pcie_cap = pseries_eeh_find_cap(dn, PCI_CAP_ID_EXP); 227 edev->pcie_cap = pseries_eeh_find_cap(pdn, PCI_CAP_ID_EXP);
240 edev->aer_cap = pseries_eeh_find_ecap(dn, PCI_EXT_CAP_ID_ERR); 228 edev->aer_cap = pseries_eeh_find_ecap(pdn, PCI_EXT_CAP_ID_ERR);
241 edev->mode &= 0xFFFFFF00; 229 edev->mode &= 0xFFFFFF00;
242 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) { 230 if ((edev->class_code >> 8) == PCI_CLASS_BRIDGE_PCI) {
243 edev->mode |= EEH_DEV_BRIDGE; 231 edev->mode |= EEH_DEV_BRIDGE;
@@ -252,24 +240,16 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
252 } 240 }
253 } 241 }
254 242
255 /* Retrieve the device address */
256 regs = of_get_property(dn, "reg", NULL);
257 if (!regs) {
258 pr_warn("%s: OF node property %s::reg not found\n",
259 __func__, dn->full_name);
260 return NULL;
261 }
262
263 /* Initialize the fake PE */ 243 /* Initialize the fake PE */
264 memset(&pe, 0, sizeof(struct eeh_pe)); 244 memset(&pe, 0, sizeof(struct eeh_pe));
265 pe.phb = edev->phb; 245 pe.phb = edev->phb;
266 pe.config_addr = of_read_number(regs, 1); 246 pe.config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
267 247
268 /* Enable EEH on the device */ 248 /* Enable EEH on the device */
269 ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); 249 ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE);
270 if (!ret) { 250 if (!ret) {
271 edev->config_addr = of_read_number(regs, 1);
272 /* Retrieve PE address */ 251 /* Retrieve PE address */
252 edev->config_addr = (pdn->busno << 16) | (pdn->devfn << 8);
273 edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); 253 edev->pe_config_addr = eeh_ops->get_pe_addr(&pe);
274 pe.addr = edev->pe_config_addr; 254 pe.addr = edev->pe_config_addr;
275 255
@@ -285,16 +265,17 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
285 eeh_add_flag(EEH_ENABLED); 265 eeh_add_flag(EEH_ENABLED);
286 eeh_add_to_parent_pe(edev); 266 eeh_add_to_parent_pe(edev);
287 267
288 pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", 268 pr_debug("%s: EEH enabled on %02x:%02x.%01x PHB#%d-PE#%x\n",
289 __func__, dn->full_name, pe.phb->global_number, 269 __func__, pdn->busno, PCI_SLOT(pdn->devfn),
290 pe.addr, pe.config_addr); 270 PCI_FUNC(pdn->devfn), pe.phb->global_number,
291 } else if (dn->parent && of_node_to_eeh_dev(dn->parent) && 271 pe.addr);
292 (of_node_to_eeh_dev(dn->parent))->pe) { 272 } else if (pdn->parent && pdn_to_eeh_dev(pdn->parent) &&
273 (pdn_to_eeh_dev(pdn->parent))->pe) {
293 /* This device doesn't support EEH, but it may have an 274 /* This device doesn't support EEH, but it may have an
294 * EEH parent, in which case we mark it as supported. 275 * EEH parent, in which case we mark it as supported.
295 */ 276 */
296 edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr; 277 edev->config_addr = pdn_to_eeh_dev(pdn->parent)->config_addr;
297 edev->pe_config_addr = of_node_to_eeh_dev(dn->parent)->pe_config_addr; 278 edev->pe_config_addr = pdn_to_eeh_dev(pdn->parent)->pe_config_addr;
298 eeh_add_to_parent_pe(edev); 279 eeh_add_to_parent_pe(edev);
299 } 280 }
300 } 281 }
@@ -670,45 +651,36 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
670 651
671/** 652/**
672 * pseries_eeh_read_config - Read PCI config space 653 * pseries_eeh_read_config - Read PCI config space
673 * @dn: device node 654 * @pdn: PCI device node
674 * @where: PCI address 655 * @where: PCI address
675 * @size: size to read 656 * @size: size to read
676 * @val: return value 657 * @val: return value
677 * 658 *
678 * Read config space from the speicifed device 659 * Read config space from the speicifed device
679 */ 660 */
680static int pseries_eeh_read_config(struct device_node *dn, int where, int size, u32 *val) 661static int pseries_eeh_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
681{ 662{
682 struct pci_dn *pdn;
683
684 pdn = PCI_DN(dn);
685
686 return rtas_read_config(pdn, where, size, val); 663 return rtas_read_config(pdn, where, size, val);
687} 664}
688 665
689/** 666/**
690 * pseries_eeh_write_config - Write PCI config space 667 * pseries_eeh_write_config - Write PCI config space
691 * @dn: device node 668 * @pdn: PCI device node
692 * @where: PCI address 669 * @where: PCI address
693 * @size: size to write 670 * @size: size to write
694 * @val: value to be written 671 * @val: value to be written
695 * 672 *
696 * Write config space to the specified device 673 * Write config space to the specified device
697 */ 674 */
698static int pseries_eeh_write_config(struct device_node *dn, int where, int size, u32 val) 675static int pseries_eeh_write_config(struct pci_dn *pdn, int where, int size, u32 val)
699{ 676{
700 struct pci_dn *pdn;
701
702 pdn = PCI_DN(dn);
703
704 return rtas_write_config(pdn, where, size, val); 677 return rtas_write_config(pdn, where, size, val);
705} 678}
706 679
707static struct eeh_ops pseries_eeh_ops = { 680static struct eeh_ops pseries_eeh_ops = {
708 .name = "pseries", 681 .name = "pseries",
709 .init = pseries_eeh_init, 682 .init = pseries_eeh_init,
710 .of_probe = pseries_eeh_of_probe, 683 .probe = pseries_eeh_probe,
711 .dev_probe = NULL,
712 .set_option = pseries_eeh_set_option, 684 .set_option = pseries_eeh_set_option,
713 .get_pe_addr = pseries_eeh_get_pe_addr, 685 .get_pe_addr = pseries_eeh_get_pe_addr,
714 .get_state = pseries_eeh_get_state, 686 .get_state = pseries_eeh_get_state,
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 691a154c286d..c8d24f9a6948 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -195,6 +195,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
195static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) 195static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
196{ 196{
197 struct device_node *dn; 197 struct device_node *dn;
198 struct pci_dn *pdn;
198 struct eeh_dev *edev; 199 struct eeh_dev *edev;
199 200
200 /* Found our PE and assume 8 at that point. */ 201 /* Found our PE and assume 8 at that point. */
@@ -204,10 +205,11 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
204 return NULL; 205 return NULL;
205 206
206 /* Get the top level device in the PE */ 207 /* Get the top level device in the PE */
207 edev = of_node_to_eeh_dev(dn); 208 edev = pdn_to_eeh_dev(PCI_DN(dn));
208 if (edev->pe) 209 if (edev->pe)
209 edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); 210 edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list);
210 dn = eeh_dev_to_of_node(edev); 211 pdn = eeh_dev_to_pdn(edev);
212 dn = pdn ? pdn->node : NULL;
211 if (!dn) 213 if (!dn)
212 return NULL; 214 return NULL;
213 215
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 89e23811199c..f735f4fee48c 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -82,7 +82,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
82 eeh_dev_phb_init_dynamic(phb); 82 eeh_dev_phb_init_dynamic(phb);
83 83
84 if (dn->child) 84 if (dn->child)
85 eeh_add_device_tree_early(dn); 85 eeh_add_device_tree_early(PCI_DN(dn));
86 86
87 pcibios_scan_phb(phb); 87 pcibios_scan_phb(phb);
88 pcibios_finish_adding_to_bus(phb->bus); 88 pcibios_finish_adding_to_bus(phb->bus);
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index e445b6701f50..70304070a260 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -265,7 +265,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act
265 update_dn_pci_info(np, pci->phb); 265 update_dn_pci_info(np, pci->phb);
266 266
267 /* Create EEH device for the OF node */ 267 /* Create EEH device for the OF node */
268 eeh_dev_init(np, pci->phb); 268 eeh_dev_init(PCI_DN(np), pci->phb);
269 } 269 }
270 break; 270 break;
271 default: 271 default: