aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/pciehp_hpc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 15:18:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-11 15:18:16 -0500
commit11bd04f6f35621193311c32e0721142b073a7794 (patch)
tree00979740582bb26e8d3756bf3526c85f19f66a46 /drivers/pci/hotplug/pciehp_hpc.c
parent4e2ccdb0409146f8cf64a11b6ef82a9c928ced2a (diff)
parent9e0b5b2c447ad0caa075a5cfef86def62e1782ff (diff)
Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: (109 commits) PCI: fix coding style issue in pci_save_state() PCI: add pci_request_acs PCI: fix BUG_ON triggered by logical PCIe root port removal PCI: remove ifdefed pci_cleanup_aer_correct_error_status PCI: unconditionally clear AER uncorr status register during cleanup x86/PCI: claim SR-IOV BARs in pcibios_allocate_resource PCI: portdrv: remove redundant definitions PCI: portdrv: remove unnecessary struct pcie_port_data PCI: portdrv: minor cleanup for pcie_port_device_register PCI: portdrv: add missing irq cleanup PCI: portdrv: enable device before irq initialization PCI: portdrv: cleanup service irqs initialization PCI: portdrv: check capabilities first PCI: portdrv: move PME capability check PCI: portdrv: remove redundant pcie type calculation PCI: portdrv: cleanup pcie_device registration PCI: portdrv: remove redundant pcie_port_device_probe PCI: Always set prefetchable base/limit upper32 registers PCI: read-modify-write the pcie device control register when initiating pcie flr PCI: show dma_mask bits in /sys ... Fixed up conflicts in: arch/x86/kernel/amd_iommu_init.c drivers/pci/dmar.c drivers/pci/hotplug/acpiphp_glue.c
Diffstat (limited to 'drivers/pci/hotplug/pciehp_hpc.c')
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c155
1 files changed, 51 insertions, 104 deletions
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9ef4605c1ef6..10040d58c8ef 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -45,25 +45,25 @@ static atomic_t pciehp_num_controllers = ATOMIC_INIT(0);
45static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) 45static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value)
46{ 46{
47 struct pci_dev *dev = ctrl->pcie->port; 47 struct pci_dev *dev = ctrl->pcie->port;
48 return pci_read_config_word(dev, ctrl->cap_base + reg, value); 48 return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value);
49} 49}
50 50
51static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) 51static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value)
52{ 52{
53 struct pci_dev *dev = ctrl->pcie->port; 53 struct pci_dev *dev = ctrl->pcie->port;
54 return pci_read_config_dword(dev, ctrl->cap_base + reg, value); 54 return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value);
55} 55}
56 56
57static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) 57static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value)
58{ 58{
59 struct pci_dev *dev = ctrl->pcie->port; 59 struct pci_dev *dev = ctrl->pcie->port;
60 return pci_write_config_word(dev, ctrl->cap_base + reg, value); 60 return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value);
61} 61}
62 62
63static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) 63static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value)
64{ 64{
65 struct pci_dev *dev = ctrl->pcie->port; 65 struct pci_dev *dev = ctrl->pcie->port;
66 return pci_write_config_dword(dev, ctrl->cap_base + reg, value); 66 return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value);
67} 67}
68 68
69/* Power Control Command */ 69/* Power Control Command */
@@ -318,8 +318,8 @@ int pciehp_get_attention_status(struct slot *slot, u8 *status)
318 return retval; 318 return retval;
319 } 319 }
320 320
321 ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", 321 ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n", __func__,
322 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); 322 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
323 323
324 atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6; 324 atten_led_state = (slot_ctrl & PCI_EXP_SLTCTL_AIC) >> 6;
325 325
@@ -356,8 +356,8 @@ int pciehp_get_power_status(struct slot *slot, u8 *status)
356 ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__); 356 ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
357 return retval; 357 return retval;
358 } 358 }
359 ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", 359 ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n", __func__,
360 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_ctrl); 360 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_ctrl);
361 361
362 pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10; 362 pwr_state = (slot_ctrl & PCI_EXP_SLTCTL_PCC) >> 10;
363 363
@@ -427,27 +427,24 @@ int pciehp_set_attention_status(struct slot *slot, u8 value)
427 struct controller *ctrl = slot->ctrl; 427 struct controller *ctrl = slot->ctrl;
428 u16 slot_cmd; 428 u16 slot_cmd;
429 u16 cmd_mask; 429 u16 cmd_mask;
430 int rc;
431 430
432 cmd_mask = PCI_EXP_SLTCTL_AIC; 431 cmd_mask = PCI_EXP_SLTCTL_AIC;
433 switch (value) { 432 switch (value) {
434 case 0 : /* turn off */ 433 case 0 : /* turn off */
435 slot_cmd = 0x00C0; 434 slot_cmd = 0x00C0;
436 break; 435 break;
437 case 1: /* turn on */ 436 case 1: /* turn on */
438 slot_cmd = 0x0040; 437 slot_cmd = 0x0040;
439 break; 438 break;
440 case 2: /* turn blink */ 439 case 2: /* turn blink */
441 slot_cmd = 0x0080; 440 slot_cmd = 0x0080;
442 break; 441 break;
443 default: 442 default:
444 return -1; 443 return -EINVAL;
445 } 444 }
446 rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 445 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
447 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 446 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
448 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 447 return pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
449
450 return rc;
451} 448}
452 449
453void pciehp_green_led_on(struct slot *slot) 450void pciehp_green_led_on(struct slot *slot)
@@ -459,8 +456,8 @@ void pciehp_green_led_on(struct slot *slot)
459 slot_cmd = 0x0100; 456 slot_cmd = 0x0100;
460 cmd_mask = PCI_EXP_SLTCTL_PIC; 457 cmd_mask = PCI_EXP_SLTCTL_PIC;
461 pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 458 pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
462 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 459 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
463 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 460 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
464} 461}
465 462
466void pciehp_green_led_off(struct slot *slot) 463void pciehp_green_led_off(struct slot *slot)
@@ -472,8 +469,8 @@ void pciehp_green_led_off(struct slot *slot)
472 slot_cmd = 0x0300; 469 slot_cmd = 0x0300;
473 cmd_mask = PCI_EXP_SLTCTL_PIC; 470 cmd_mask = PCI_EXP_SLTCTL_PIC;
474 pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 471 pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
475 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 472 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
476 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 473 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
477} 474}
478 475
479void pciehp_green_led_blink(struct slot *slot) 476void pciehp_green_led_blink(struct slot *slot)
@@ -485,8 +482,8 @@ void pciehp_green_led_blink(struct slot *slot)
485 slot_cmd = 0x0200; 482 slot_cmd = 0x0200;
486 cmd_mask = PCI_EXP_SLTCTL_PIC; 483 cmd_mask = PCI_EXP_SLTCTL_PIC;
487 pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 484 pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
488 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 485 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
489 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 486 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
490} 487}
491 488
492int pciehp_power_on_slot(struct slot * slot) 489int pciehp_power_on_slot(struct slot * slot)
@@ -514,97 +511,38 @@ int pciehp_power_on_slot(struct slot * slot)
514 return retval; 511 return retval;
515 } 512 }
516 } 513 }
514 ctrl->power_fault_detected = 0;
517 515
518 slot_cmd = POWER_ON; 516 slot_cmd = POWER_ON;
519 cmd_mask = PCI_EXP_SLTCTL_PCC; 517 cmd_mask = PCI_EXP_SLTCTL_PCC;
520 if (!pciehp_poll_mode) {
521 /* Enable power fault detection turned off at power off time */
522 slot_cmd |= PCI_EXP_SLTCTL_PFDE;
523 cmd_mask |= PCI_EXP_SLTCTL_PFDE;
524 }
525
526 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 518 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
527 if (retval) { 519 if (retval) {
528 ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd); 520 ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
529 return retval; 521 return retval;
530 } 522 }
531 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 523 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
532 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 524 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
533 525
534 ctrl->power_fault_detected = 0;
535 return retval; 526 return retval;
536} 527}
537 528
538static inline int pcie_mask_bad_dllp(struct controller *ctrl)
539{
540 struct pci_dev *dev = ctrl->pcie->port;
541 int pos;
542 u32 reg;
543
544 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
545 if (!pos)
546 return 0;
547 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
548 if (reg & PCI_ERR_COR_BAD_DLLP)
549 return 0;
550 reg |= PCI_ERR_COR_BAD_DLLP;
551 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
552 return 1;
553}
554
555static inline void pcie_unmask_bad_dllp(struct controller *ctrl)
556{
557 struct pci_dev *dev = ctrl->pcie->port;
558 u32 reg;
559 int pos;
560
561 pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
562 if (!pos)
563 return;
564 pci_read_config_dword(dev, pos + PCI_ERR_COR_MASK, &reg);
565 if (!(reg & PCI_ERR_COR_BAD_DLLP))
566 return;
567 reg &= ~PCI_ERR_COR_BAD_DLLP;
568 pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, reg);
569}
570
571int pciehp_power_off_slot(struct slot * slot) 529int pciehp_power_off_slot(struct slot * slot)
572{ 530{
573 struct controller *ctrl = slot->ctrl; 531 struct controller *ctrl = slot->ctrl;
574 u16 slot_cmd; 532 u16 slot_cmd;
575 u16 cmd_mask; 533 u16 cmd_mask;
576 int retval = 0; 534 int retval;
577 int changed;
578
579 /*
580 * Set Bad DLLP Mask bit in Correctable Error Mask
581 * Register. This is the workaround against Bad DLLP error
582 * that sometimes happens during turning power off the slot
583 * which conforms to PCI Express 1.0a spec.
584 */
585 changed = pcie_mask_bad_dllp(ctrl);
586 535
587 slot_cmd = POWER_OFF; 536 slot_cmd = POWER_OFF;
588 cmd_mask = PCI_EXP_SLTCTL_PCC; 537 cmd_mask = PCI_EXP_SLTCTL_PCC;
589 if (!pciehp_poll_mode) {
590 /* Disable power fault detection */
591 slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
592 cmd_mask |= PCI_EXP_SLTCTL_PFDE;
593 }
594
595 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); 538 retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
596 if (retval) { 539 if (retval) {
597 ctrl_err(ctrl, "Write command failed!\n"); 540 ctrl_err(ctrl, "Write command failed!\n");
598 retval = -1; 541 return retval;
599 goto out;
600 } 542 }
601 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", 543 ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
602 __func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd); 544 pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
603 out: 545 return 0;
604 if (changed)
605 pcie_unmask_bad_dllp(ctrl);
606
607 return retval;
608} 546}
609 547
610static irqreturn_t pcie_isr(int irq, void *dev_id) 548static irqreturn_t pcie_isr(int irq, void *dev_id)
@@ -840,11 +778,19 @@ int pcie_enable_notification(struct controller *ctrl)
840{ 778{
841 u16 cmd, mask; 779 u16 cmd, mask;
842 780
781 /*
782 * TBD: Power fault detected software notification support.
783 *
784 * Power fault detected software notification is not enabled
785 * now, because it caused power fault detected interrupt storm
786 * on some machines. On those machines, power fault detected
787 * bit in the slot status register was set again immediately
788 * when it is cleared in the interrupt service routine, and
789 * next power fault detected interrupt was notified again.
790 */
843 cmd = PCI_EXP_SLTCTL_PDCE; 791 cmd = PCI_EXP_SLTCTL_PDCE;
844 if (ATTN_BUTTN(ctrl)) 792 if (ATTN_BUTTN(ctrl))
845 cmd |= PCI_EXP_SLTCTL_ABPE; 793 cmd |= PCI_EXP_SLTCTL_ABPE;
846 if (POWER_CTRL(ctrl))
847 cmd |= PCI_EXP_SLTCTL_PFDE;
848 if (MRL_SENS(ctrl)) 794 if (MRL_SENS(ctrl))
849 cmd |= PCI_EXP_SLTCTL_MRLSCE; 795 cmd |= PCI_EXP_SLTCTL_MRLSCE;
850 if (!pciehp_poll_mode) 796 if (!pciehp_poll_mode)
@@ -866,7 +812,8 @@ static void pcie_disable_notification(struct controller *ctrl)
866 u16 mask; 812 u16 mask;
867 mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE | 813 mask = (PCI_EXP_SLTCTL_PDCE | PCI_EXP_SLTCTL_ABPE |
868 PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE | 814 PCI_EXP_SLTCTL_MRLSCE | PCI_EXP_SLTCTL_PFDE |
869 PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE); 815 PCI_EXP_SLTCTL_HPIE | PCI_EXP_SLTCTL_CCIE |
816 PCI_EXP_SLTCTL_DLLSCE);
870 if (pcie_write_cmd(ctrl, 0, mask)) 817 if (pcie_write_cmd(ctrl, 0, mask))
871 ctrl_warn(ctrl, "Cannot disable software notification\n"); 818 ctrl_warn(ctrl, "Cannot disable software notification\n");
872} 819}
@@ -934,7 +881,8 @@ static inline void dbg_ctrl(struct controller *ctrl)
934 pdev->subsystem_device); 881 pdev->subsystem_device);
935 ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n", 882 ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n",
936 pdev->subsystem_vendor); 883 pdev->subsystem_vendor);
937 ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base); 884 ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n",
885 pci_pcie_cap(pdev));
938 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { 886 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
939 if (!pci_resource_len(pdev, i)) 887 if (!pci_resource_len(pdev, i))
940 continue; 888 continue;
@@ -978,8 +926,7 @@ struct controller *pcie_init(struct pcie_device *dev)
978 goto abort; 926 goto abort;
979 } 927 }
980 ctrl->pcie = dev; 928 ctrl->pcie = dev;
981 ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP); 929 if (!pci_pcie_cap(pdev)) {
982 if (!ctrl->cap_base) {
983 ctrl_err(ctrl, "Cannot find PCI Express capability\n"); 930 ctrl_err(ctrl, "Cannot find PCI Express capability\n");
984 goto abort_ctrl; 931 goto abort_ctrl;
985 } 932 }