diff options
author | Gavin Shan <gwshan@linux.vnet.ibm.com> | 2015-03-17 01:15:03 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2015-03-23 22:15:50 -0400 |
commit | 3532a741f80c3b9ca975006f93a4a477e07e2cb3 (patch) | |
tree | a72f5e6bef1aba0cc720def5bda613770587648f /arch/powerpc/platforms | |
parent | cca87d303c85b257a7b0fd34f9d6fce1c59880a2 (diff) |
powerpc/powernv: Use pci_dn, not device_node, in PCI config accessor
The PCI config accessors previously relied on device_node. Unfortunately,
VFs don't have a corresponding device_node, so change the accessors to use
pci_dn instead.
[bhelgaas: changelog]
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/powernv/eeh-powernv.c | 14 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 69 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 4 |
3 files changed, 40 insertions, 47 deletions
diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index ede690630dfc..8eac8c57ee86 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c | |||
@@ -1038,21 +1038,31 @@ static inline bool pnv_eeh_cfg_blocked(struct device_node *dn) | |||
1038 | static int pnv_eeh_read_config(struct device_node *dn, | 1038 | static int pnv_eeh_read_config(struct device_node *dn, |
1039 | int where, int size, u32 *val) | 1039 | int where, int size, u32 *val) |
1040 | { | 1040 | { |
1041 | struct pci_dn *pdn = PCI_DN(dn); | ||
1042 | |||
1043 | if (!pdn) | ||
1044 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
1045 | |||
1041 | if (pnv_eeh_cfg_blocked(dn)) { | 1046 | if (pnv_eeh_cfg_blocked(dn)) { |
1042 | *val = 0xFFFFFFFF; | 1047 | *val = 0xFFFFFFFF; |
1043 | return PCIBIOS_SET_FAILED; | 1048 | return PCIBIOS_SET_FAILED; |
1044 | } | 1049 | } |
1045 | 1050 | ||
1046 | return pnv_pci_cfg_read(dn, where, size, val); | 1051 | return pnv_pci_cfg_read(pdn, where, size, val); |
1047 | } | 1052 | } |
1048 | 1053 | ||
1049 | static int pnv_eeh_write_config(struct device_node *dn, | 1054 | static int pnv_eeh_write_config(struct device_node *dn, |
1050 | int where, int size, u32 val) | 1055 | int where, int size, u32 val) |
1051 | { | 1056 | { |
1057 | struct pci_dn *pdn = PCI_DN(dn); | ||
1058 | |||
1059 | if (!pdn) | ||
1060 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
1061 | |||
1052 | if (pnv_eeh_cfg_blocked(dn)) | 1062 | if (pnv_eeh_cfg_blocked(dn)) |
1053 | return PCIBIOS_SET_FAILED; | 1063 | return PCIBIOS_SET_FAILED; |
1054 | 1064 | ||
1055 | return pnv_pci_cfg_write(dn, where, size, val); | 1065 | return pnv_pci_cfg_write(pdn, where, size, val); |
1056 | } | 1066 | } |
1057 | 1067 | ||
1058 | static void pnv_eeh_dump_hub_diag_common(struct OpalIoP7IOCErrorData *data) | 1068 | static void pnv_eeh_dump_hub_diag_common(struct OpalIoP7IOCErrorData *data) |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 54323d6b5166..946aa3d62c3c 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -366,9 +366,9 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no) | |||
366 | spin_unlock_irqrestore(&phb->lock, flags); | 366 | spin_unlock_irqrestore(&phb->lock, flags); |
367 | } | 367 | } |
368 | 368 | ||
369 | static void pnv_pci_config_check_eeh(struct pnv_phb *phb, | 369 | static void pnv_pci_config_check_eeh(struct pci_dn *pdn) |
370 | struct device_node *dn) | ||
371 | { | 370 | { |
371 | struct pnv_phb *phb = pdn->phb->private_data; | ||
372 | u8 fstate; | 372 | u8 fstate; |
373 | __be16 pcierr; | 373 | __be16 pcierr; |
374 | int pe_no; | 374 | int pe_no; |
@@ -379,7 +379,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, | |||
379 | * setup that yet. So all ER errors should be mapped to | 379 | * setup that yet. So all ER errors should be mapped to |
380 | * reserved PE. | 380 | * reserved PE. |
381 | */ | 381 | */ |
382 | pe_no = PCI_DN(dn)->pe_number; | 382 | pe_no = pdn->pe_number; |
383 | if (pe_no == IODA_INVALID_PE) { | 383 | if (pe_no == IODA_INVALID_PE) { |
384 | if (phb->type == PNV_PHB_P5IOC2) | 384 | if (phb->type == PNV_PHB_P5IOC2) |
385 | pe_no = 0; | 385 | pe_no = 0; |
@@ -407,8 +407,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, | |||
407 | } | 407 | } |
408 | 408 | ||
409 | cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n", | 409 | cfg_dbg(" -> EEH check, bdfn=%04x PE#%d fstate=%x\n", |
410 | (PCI_DN(dn)->busno << 8) | (PCI_DN(dn)->devfn), | 410 | (pdn->busno << 8) | (pdn->devfn), pe_no, fstate); |
411 | pe_no, fstate); | ||
412 | 411 | ||
413 | /* Clear the frozen state if applicable */ | 412 | /* Clear the frozen state if applicable */ |
414 | if (fstate == OPAL_EEH_STOPPED_MMIO_FREEZE || | 413 | if (fstate == OPAL_EEH_STOPPED_MMIO_FREEZE || |
@@ -425,10 +424,9 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb, | |||
425 | } | 424 | } |
426 | } | 425 | } |
427 | 426 | ||
428 | int pnv_pci_cfg_read(struct device_node *dn, | 427 | int pnv_pci_cfg_read(struct pci_dn *pdn, |
429 | int where, int size, u32 *val) | 428 | int where, int size, u32 *val) |
430 | { | 429 | { |
431 | struct pci_dn *pdn = PCI_DN(dn); | ||
432 | struct pnv_phb *phb = pdn->phb->private_data; | 430 | struct pnv_phb *phb = pdn->phb->private_data; |
433 | u32 bdfn = (pdn->busno << 8) | pdn->devfn; | 431 | u32 bdfn = (pdn->busno << 8) | pdn->devfn; |
434 | s64 rc; | 432 | s64 rc; |
@@ -462,10 +460,9 @@ int pnv_pci_cfg_read(struct device_node *dn, | |||
462 | return PCIBIOS_SUCCESSFUL; | 460 | return PCIBIOS_SUCCESSFUL; |
463 | } | 461 | } |
464 | 462 | ||
465 | int pnv_pci_cfg_write(struct device_node *dn, | 463 | int pnv_pci_cfg_write(struct pci_dn *pdn, |
466 | int where, int size, u32 val) | 464 | int where, int size, u32 val) |
467 | { | 465 | { |
468 | struct pci_dn *pdn = PCI_DN(dn); | ||
469 | struct pnv_phb *phb = pdn->phb->private_data; | 466 | struct pnv_phb *phb = pdn->phb->private_data; |
470 | u32 bdfn = (pdn->busno << 8) | pdn->devfn; | 467 | u32 bdfn = (pdn->busno << 8) | pdn->devfn; |
471 | 468 | ||
@@ -489,18 +486,17 @@ int pnv_pci_cfg_write(struct device_node *dn, | |||
489 | } | 486 | } |
490 | 487 | ||
491 | #if CONFIG_EEH | 488 | #if CONFIG_EEH |
492 | static bool pnv_pci_cfg_check(struct pci_controller *hose, | 489 | static bool pnv_pci_cfg_check(struct pci_dn *pdn) |
493 | struct device_node *dn) | ||
494 | { | 490 | { |
495 | struct eeh_dev *edev = NULL; | 491 | struct eeh_dev *edev = NULL; |
496 | struct pnv_phb *phb = hose->private_data; | 492 | struct pnv_phb *phb = pdn->phb->private_data; |
497 | 493 | ||
498 | /* EEH not enabled ? */ | 494 | /* EEH not enabled ? */ |
499 | if (!(phb->flags & PNV_PHB_FLAG_EEH)) | 495 | if (!(phb->flags & PNV_PHB_FLAG_EEH)) |
500 | return true; | 496 | return true; |
501 | 497 | ||
502 | /* PE reset or device removed ? */ | 498 | /* PE reset or device removed ? */ |
503 | edev = of_node_to_eeh_dev(dn); | 499 | edev = pdn->edev; |
504 | if (edev) { | 500 | if (edev) { |
505 | if (edev->pe && | 501 | if (edev->pe && |
506 | (edev->pe->state & EEH_PE_CFG_BLOCKED)) | 502 | (edev->pe->state & EEH_PE_CFG_BLOCKED)) |
@@ -513,8 +509,7 @@ static bool pnv_pci_cfg_check(struct pci_controller *hose, | |||
513 | return true; | 509 | return true; |
514 | } | 510 | } |
515 | #else | 511 | #else |
516 | static inline pnv_pci_cfg_check(struct pci_controller *hose, | 512 | static inline pnv_pci_cfg_check(struct pci_dn *pdn) |
517 | struct device_node *dn) | ||
518 | { | 513 | { |
519 | return true; | 514 | return true; |
520 | } | 515 | } |
@@ -524,32 +519,26 @@ static int pnv_pci_read_config(struct pci_bus *bus, | |||
524 | unsigned int devfn, | 519 | unsigned int devfn, |
525 | int where, int size, u32 *val) | 520 | int where, int size, u32 *val) |
526 | { | 521 | { |
527 | struct device_node *dn, *busdn = pci_bus_to_OF_node(bus); | ||
528 | struct pci_dn *pdn; | 522 | struct pci_dn *pdn; |
529 | struct pnv_phb *phb; | 523 | struct pnv_phb *phb; |
530 | bool found = false; | ||
531 | int ret; | 524 | int ret; |
532 | 525 | ||
533 | *val = 0xFFFFFFFF; | 526 | *val = 0xFFFFFFFF; |
534 | for (dn = busdn->child; dn; dn = dn->sibling) { | 527 | pdn = pci_get_pdn_by_devfn(bus, devfn); |
535 | pdn = PCI_DN(dn); | 528 | if (!pdn) |
536 | if (pdn && pdn->devfn == devfn) { | 529 | return PCIBIOS_DEVICE_NOT_FOUND; |
537 | phb = pdn->phb->private_data; | ||
538 | found = true; | ||
539 | break; | ||
540 | } | ||
541 | } | ||
542 | 530 | ||
543 | if (!found || !pnv_pci_cfg_check(pdn->phb, dn)) | 531 | if (!pnv_pci_cfg_check(pdn)) |
544 | return PCIBIOS_DEVICE_NOT_FOUND; | 532 | return PCIBIOS_DEVICE_NOT_FOUND; |
545 | 533 | ||
546 | ret = pnv_pci_cfg_read(dn, where, size, val); | 534 | ret = pnv_pci_cfg_read(pdn, where, size, val); |
547 | if (phb->flags & PNV_PHB_FLAG_EEH) { | 535 | phb = pdn->phb->private_data; |
536 | if (phb->flags & PNV_PHB_FLAG_EEH && pdn->edev) { | ||
548 | if (*val == EEH_IO_ERROR_VALUE(size) && | 537 | if (*val == EEH_IO_ERROR_VALUE(size) && |
549 | eeh_dev_check_failure(of_node_to_eeh_dev(dn))) | 538 | eeh_dev_check_failure(pdn->edev)) |
550 | return PCIBIOS_DEVICE_NOT_FOUND; | 539 | return PCIBIOS_DEVICE_NOT_FOUND; |
551 | } else { | 540 | } else { |
552 | pnv_pci_config_check_eeh(phb, dn); | 541 | pnv_pci_config_check_eeh(pdn); |
553 | } | 542 | } |
554 | 543 | ||
555 | return ret; | 544 | return ret; |
@@ -559,27 +548,21 @@ static int pnv_pci_write_config(struct pci_bus *bus, | |||
559 | unsigned int devfn, | 548 | unsigned int devfn, |
560 | int where, int size, u32 val) | 549 | int where, int size, u32 val) |
561 | { | 550 | { |
562 | struct device_node *dn, *busdn = pci_bus_to_OF_node(bus); | ||
563 | struct pci_dn *pdn; | 551 | struct pci_dn *pdn; |
564 | struct pnv_phb *phb; | 552 | struct pnv_phb *phb; |
565 | bool found = false; | ||
566 | int ret; | 553 | int ret; |
567 | 554 | ||
568 | for (dn = busdn->child; dn; dn = dn->sibling) { | 555 | pdn = pci_get_pdn_by_devfn(bus, devfn); |
569 | pdn = PCI_DN(dn); | 556 | if (!pdn) |
570 | if (pdn && pdn->devfn == devfn) { | 557 | return PCIBIOS_DEVICE_NOT_FOUND; |
571 | phb = pdn->phb->private_data; | ||
572 | found = true; | ||
573 | break; | ||
574 | } | ||
575 | } | ||
576 | 558 | ||
577 | if (!found || !pnv_pci_cfg_check(pdn->phb, dn)) | 559 | if (!pnv_pci_cfg_check(pdn)) |
578 | return PCIBIOS_DEVICE_NOT_FOUND; | 560 | return PCIBIOS_DEVICE_NOT_FOUND; |
579 | 561 | ||
580 | ret = pnv_pci_cfg_write(dn, where, size, val); | 562 | ret = pnv_pci_cfg_write(pdn, where, size, val); |
563 | phb = pdn->phb->private_data; | ||
581 | if (!(phb->flags & PNV_PHB_FLAG_EEH)) | 564 | if (!(phb->flags & PNV_PHB_FLAG_EEH)) |
582 | pnv_pci_config_check_eeh(phb, dn); | 565 | pnv_pci_config_check_eeh(pdn); |
583 | 566 | ||
584 | return ret; | 567 | return ret; |
585 | } | 568 | } |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 18ae927f7819..1f0cb66133a1 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -196,9 +196,9 @@ extern struct pci_ops pnv_pci_ops; | |||
196 | 196 | ||
197 | void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, | 197 | void pnv_pci_dump_phb_diag_data(struct pci_controller *hose, |
198 | unsigned char *log_buff); | 198 | unsigned char *log_buff); |
199 | int pnv_pci_cfg_read(struct device_node *dn, | 199 | int pnv_pci_cfg_read(struct pci_dn *pdn, |
200 | int where, int size, u32 *val); | 200 | int where, int size, u32 *val); |
201 | int pnv_pci_cfg_write(struct device_node *dn, | 201 | int pnv_pci_cfg_write(struct pci_dn *pdn, |
202 | int where, int size, u32 val); | 202 | int where, int size, u32 val); |
203 | extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, | 203 | extern void pnv_pci_setup_iommu_table(struct iommu_table *tbl, |
204 | void *tce_mem, u64 tce_size, | 204 | void *tce_mem, u64 tce_size, |