diff options
| author | Bjorn Helgaas <bhelgaas@google.com> | 2013-08-29 19:23:33 -0400 |
|---|---|---|
| committer | Bjorn Helgaas <bhelgaas@google.com> | 2013-08-29 19:23:33 -0400 |
| commit | e89c33168aad32436da842ddda307dcc31c0c4e2 (patch) | |
| tree | 831668bbda77e4b5ff463b26a75c8f88819436aa | |
| parent | 2e8b5f621dbe29425906852c6079afb6b28720cb (diff) | |
| parent | 3dc48af310709b85d07c8b0d3aa8f1ead02829d3 (diff) | |
Merge branch 'pci/misc' into next
* pci/misc:
PCI/ACPI: Fix _OSC ordering to allow PCIe hotplug use when available
PCI: exynos: Add I/O access wrappers
PCI: designware: Drop "addr" arg from dw_pcie_readl_rc()/dw_pcie_writel_rc()
| -rw-r--r-- | drivers/acpi/pci_root.c | 62 | ||||
| -rw-r--r-- | drivers/pci/host/pci-exynos.c | 160 | ||||
| -rw-r--r-- | drivers/pci/host/pcie-designware.c | 135 |
3 files changed, 184 insertions, 173 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index ce04eb28e029..d3874f425653 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -378,6 +378,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
| 378 | struct acpi_pci_root *root; | 378 | struct acpi_pci_root *root; |
| 379 | u32 flags, base_flags; | 379 | u32 flags, base_flags; |
| 380 | acpi_handle handle = device->handle; | 380 | acpi_handle handle = device->handle; |
| 381 | bool no_aspm = false, clear_aspm = false; | ||
| 381 | 382 | ||
| 382 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 383 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); |
| 383 | if (!root) | 384 | if (!root) |
| @@ -437,27 +438,6 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
| 437 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 438 | flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; |
| 438 | acpi_pci_osc_support(root, flags); | 439 | acpi_pci_osc_support(root, flags); |
| 439 | 440 | ||
| 440 | /* | ||
| 441 | * TBD: Need PCI interface for enumeration/configuration of roots. | ||
| 442 | */ | ||
| 443 | |||
| 444 | /* | ||
| 445 | * Scan the Root Bridge | ||
| 446 | * -------------------- | ||
| 447 | * Must do this prior to any attempt to bind the root device, as the | ||
| 448 | * PCI namespace does not get created until this call is made (and | ||
| 449 | * thus the root bridge's pci_dev does not exist). | ||
| 450 | */ | ||
| 451 | root->bus = pci_acpi_scan_root(root); | ||
| 452 | if (!root->bus) { | ||
| 453 | dev_err(&device->dev, | ||
| 454 | "Bus %04x:%02x not present in PCI namespace\n", | ||
| 455 | root->segment, (unsigned int)root->secondary.start); | ||
| 456 | result = -ENODEV; | ||
| 457 | goto end; | ||
| 458 | } | ||
| 459 | |||
| 460 | /* Indicate support for various _OSC capabilities. */ | ||
| 461 | if (pci_ext_cfg_avail()) | 441 | if (pci_ext_cfg_avail()) |
| 462 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | 442 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; |
| 463 | if (pcie_aspm_support_enabled()) { | 443 | if (pcie_aspm_support_enabled()) { |
| @@ -471,7 +451,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
| 471 | if (ACPI_FAILURE(status)) { | 451 | if (ACPI_FAILURE(status)) { |
| 472 | dev_info(&device->dev, "ACPI _OSC support " | 452 | dev_info(&device->dev, "ACPI _OSC support " |
| 473 | "notification failed, disabling PCIe ASPM\n"); | 453 | "notification failed, disabling PCIe ASPM\n"); |
| 474 | pcie_no_aspm(); | 454 | no_aspm = true; |
| 475 | flags = base_flags; | 455 | flags = base_flags; |
| 476 | } | 456 | } |
| 477 | } | 457 | } |
| @@ -503,7 +483,7 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
| 503 | * We have ASPM control, but the FADT indicates | 483 | * We have ASPM control, but the FADT indicates |
| 504 | * that it's unsupported. Clear it. | 484 | * that it's unsupported. Clear it. |
| 505 | */ | 485 | */ |
| 506 | pcie_clear_aspm(root->bus); | 486 | clear_aspm = true; |
| 507 | } | 487 | } |
| 508 | } else { | 488 | } else { |
| 509 | dev_info(&device->dev, | 489 | dev_info(&device->dev, |
| @@ -512,7 +492,14 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
| 512 | acpi_format_exception(status), flags); | 492 | acpi_format_exception(status), flags); |
| 513 | dev_info(&device->dev, | 493 | dev_info(&device->dev, |
| 514 | "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); | 494 | "ACPI _OSC control for PCIe not granted, disabling ASPM\n"); |
| 515 | pcie_no_aspm(); | 495 | /* |
| 496 | * We want to disable ASPM here, but aspm_disabled | ||
| 497 | * needs to remain in its state from boot so that we | ||
| 498 | * properly handle PCIe 1.1 devices. So we set this | ||
| 499 | * flag here, to defer the action until after the ACPI | ||
| 500 | * root scan. | ||
| 501 | */ | ||
| 502 | no_aspm = true; | ||
| 516 | } | 503 | } |
| 517 | } else { | 504 | } else { |
| 518 | dev_info(&device->dev, | 505 | dev_info(&device->dev, |
| @@ -520,6 +507,33 @@ static int acpi_pci_root_add(struct acpi_device *device, | |||
| 520 | "(_OSC support mask: 0x%02x)\n", flags); | 507 | "(_OSC support mask: 0x%02x)\n", flags); |
| 521 | } | 508 | } |
| 522 | 509 | ||
| 510 | /* | ||
| 511 | * TBD: Need PCI interface for enumeration/configuration of roots. | ||
| 512 | */ | ||
| 513 | |||
| 514 | /* | ||
| 515 | * Scan the Root Bridge | ||
| 516 | * -------------------- | ||
| 517 | * Must do this prior to any attempt to bind the root device, as the | ||
| 518 | * PCI namespace does not get created until this call is made (and | ||
| 519 | * thus the root bridge's pci_dev does not exist). | ||
| 520 | */ | ||
| 521 | root->bus = pci_acpi_scan_root(root); | ||
| 522 | if (!root->bus) { | ||
| 523 | dev_err(&device->dev, | ||
| 524 | "Bus %04x:%02x not present in PCI namespace\n", | ||
| 525 | root->segment, (unsigned int)root->secondary.start); | ||
| 526 | result = -ENODEV; | ||
| 527 | goto end; | ||
| 528 | } | ||
| 529 | |||
| 530 | if (clear_aspm) { | ||
| 531 | dev_info(&device->dev, "Disabling ASPM (FADT indicates it is unsupported)\n"); | ||
| 532 | pcie_clear_aspm(root->bus); | ||
| 533 | } | ||
| 534 | if (no_aspm) | ||
| 535 | pcie_no_aspm(); | ||
| 536 | |||
| 523 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 537 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
| 524 | if (device->wakeup.flags.run_wake) | 538 | if (device->wakeup.flags.run_wake) |
| 525 | device_set_run_wake(root->bus->bridge, true); | 539 | device_set_run_wake(root->bus->bridge, true); |
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index 012ca8aec71a..94e096bb2d0a 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c | |||
| @@ -91,19 +91,49 @@ struct exynos_pcie { | |||
| 91 | #define PCIE_PHY_TRSV3_RXCDR 0x2ec | 91 | #define PCIE_PHY_TRSV3_RXCDR 0x2ec |
| 92 | #define PCIE_PHY_TRSV3_LVCC 0x31c | 92 | #define PCIE_PHY_TRSV3_LVCC 0x31c |
| 93 | 93 | ||
| 94 | static inline void exynos_elb_writel(struct exynos_pcie *pcie, u32 val, u32 reg) | ||
| 95 | { | ||
| 96 | writel(val, pcie->elbi_base + reg); | ||
| 97 | } | ||
| 98 | |||
| 99 | static inline u32 exynos_elb_readl(struct exynos_pcie *pcie, u32 reg) | ||
| 100 | { | ||
| 101 | return readl(pcie->elbi_base + reg); | ||
| 102 | } | ||
| 103 | |||
| 104 | static inline void exynos_phy_writel(struct exynos_pcie *pcie, u32 val, u32 reg) | ||
| 105 | { | ||
| 106 | writel(val, pcie->phy_base + reg); | ||
| 107 | } | ||
| 108 | |||
| 109 | static inline u32 exynos_phy_readl(struct exynos_pcie *pcie, u32 reg) | ||
| 110 | { | ||
| 111 | return readl(pcie->phy_base + reg); | ||
| 112 | } | ||
| 113 | |||
| 114 | static inline void exynos_blk_writel(struct exynos_pcie *pcie, u32 val, u32 reg) | ||
| 115 | { | ||
| 116 | writel(val, pcie->block_base + reg); | ||
| 117 | } | ||
| 118 | |||
| 119 | static inline u32 exynos_blk_readl(struct exynos_pcie *pcie, u32 reg) | ||
| 120 | { | ||
| 121 | return readl(pcie->block_base + reg); | ||
| 122 | } | ||
| 123 | |||
| 94 | static void exynos_pcie_sideband_dbi_w_mode(struct pcie_port *pp, bool on) | 124 | static void exynos_pcie_sideband_dbi_w_mode(struct pcie_port *pp, bool on) |
| 95 | { | 125 | { |
| 96 | u32 val; | 126 | u32 val; |
| 97 | struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp); | 127 | struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp); |
| 98 | 128 | ||
| 99 | if (on) { | 129 | if (on) { |
| 100 | val = readl(exynos_pcie->elbi_base + PCIE_ELBI_SLV_AWMISC); | 130 | val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_AWMISC); |
| 101 | val |= PCIE_ELBI_SLV_DBI_ENABLE; | 131 | val |= PCIE_ELBI_SLV_DBI_ENABLE; |
| 102 | writel(val, exynos_pcie->elbi_base + PCIE_ELBI_SLV_AWMISC); | 132 | exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_AWMISC); |
| 103 | } else { | 133 | } else { |
| 104 | val = readl(exynos_pcie->elbi_base + PCIE_ELBI_SLV_AWMISC); | 134 | val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_AWMISC); |
| 105 | val &= ~PCIE_ELBI_SLV_DBI_ENABLE; | 135 | val &= ~PCIE_ELBI_SLV_DBI_ENABLE; |
| 106 | writel(val, exynos_pcie->elbi_base + PCIE_ELBI_SLV_AWMISC); | 136 | exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_AWMISC); |
| 107 | } | 137 | } |
| 108 | } | 138 | } |
| 109 | 139 | ||
| @@ -113,13 +143,13 @@ static void exynos_pcie_sideband_dbi_r_mode(struct pcie_port *pp, bool on) | |||
| 113 | struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp); | 143 | struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp); |
| 114 | 144 | ||
| 115 | if (on) { | 145 | if (on) { |
| 116 | val = readl(exynos_pcie->elbi_base + PCIE_ELBI_SLV_ARMISC); | 146 | val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_ARMISC); |
| 117 | val |= PCIE_ELBI_SLV_DBI_ENABLE; | 147 | val |= PCIE_ELBI_SLV_DBI_ENABLE; |
| 118 | writel(val, exynos_pcie->elbi_base + PCIE_ELBI_SLV_ARMISC); | 148 | exynos_elb_writel(exynos_pcie, val, PCIE_ELBI_SLV_ARMISC); |
| 119 | } else { | 149 | } else { |
| 120 | val = readl(exynos_pcie->elbi_base + PCIE_ELBI_SLV_ARMISC); | 150 | val = exynos_elb_readl(exynos_pcie, PCIE_ELBI_SLV_ARMISC); |
| 121 | val &= ~PCIE_ELBI_SLV_DBI_ENABLE; | 151 | val &= ~PCIE_ELBI_SLV_DBI_ENABLE; |
