diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 53 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_ibm.c | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 2 | ||||
-rw-r--r-- | drivers/pci/ioapic.c | 1 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 17 | ||||
-rw-r--r-- | drivers/pci/pci-label.c | 130 | ||||
-rw-r--r-- | drivers/pci/probe.c | 21 | ||||
-rw-r--r-- | drivers/pci/remove.c | 17 |
9 files changed, 102 insertions, 144 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index b8ba2f79455..330f7e3a32d 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -25,7 +25,6 @@ */ #include <linux/clk.h> -#include <linux/clk/tegra.h> #include <linux/delay.h> #include <linux/export.h> #include <linux/interrupt.h> @@ -39,6 +38,7 @@ #include <linux/of_platform.h> #include <linux/pci.h> #include <linux/platform_device.h> +#include <linux/reset.h> #include <linux/sizes.h> #include <linux/slab.h> #include <linux/tegra-cpuidle.h> @@ -259,10 +259,13 @@ struct tegra_pcie { struct clk *pex_clk; struct clk *afi_clk; - struct clk *pcie_xclk; struct clk *pll_e; struct clk *cml_clk; + struct reset_control *pex_rst; + struct reset_control *afi_rst; + struct reset_control *pcie_xrst; + struct tegra_msi msi; struct list_head ports; @@ -858,7 +861,7 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie) pads_writel(pcie, value, PADS_CTL); /* take the PCIe interface module out of reset */ - tegra_periph_reset_deassert(pcie->pcie_xclk); + reset_control_deassert(pcie->pcie_xrst); /* finally enable PCIe */ value = afi_readl(pcie, AFI_CONFIGURATION); @@ -891,9 +894,9 @@ static void tegra_pcie_power_off(struct tegra_pcie *pcie) /* TODO: disable and unprepare clocks? */ - tegra_periph_reset_assert(pcie->pcie_xclk); - tegra_periph_reset_assert(pcie->afi_clk); - tegra_periph_reset_assert(pcie->pex_clk); + reset_control_assert(pcie->pcie_xrst); + reset_control_assert(pcie->afi_rst); + reset_control_assert(pcie->pex_rst); tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); @@ -921,9 +924,9 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) const struct tegra_pcie_soc_data *soc = pcie->soc_data; int err; - tegra_periph_reset_assert(pcie->pcie_xclk); - tegra_periph_reset_assert(pcie->afi_clk); - tegra_periph_reset_assert(pcie->pex_clk); + reset_control_assert(pcie->pcie_xrst); + reset_control_assert(pcie->afi_rst); + reset_control_assert(pcie->pex_rst); tegra_powergate_power_off(TEGRA_POWERGATE_PCIE); @@ -952,13 +955,14 @@ static int tegra_pcie_power_on(struct tegra_pcie *pcie) } err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE, - pcie->pex_clk); + pcie->pex_clk, + pcie->pex_rst); if (err) { dev_err(pcie->dev, "powerup sequence failed: %d\n", err); return err; } - tegra_periph_reset_deassert(pcie->afi_clk); + reset_control_deassert(pcie->afi_rst); err = clk_prepare_enable(pcie->afi_clk); if (err < 0) { @@ -996,10 +1000,6 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) if (IS_ERR(pcie->afi_clk)) return PTR_ERR(pcie->afi_clk); - pcie->pcie_xclk = devm_clk_get(pcie->dev, "pcie_xclk"); - if (IS_ERR(pcie->pcie_xclk)) - return PTR_ERR(pcie->pcie_xclk); - pcie->pll_e = devm_clk_get(pcie->dev, "pll_e"); if (IS_ERR(pcie->pll_e)) return PTR_ERR(pcie->pll_e); @@ -1013,6 +1013,23 @@ static int tegra_pcie_clocks_get(struct tegra_pcie *pcie) return 0; } +static int tegra_pcie_resets_get(struct tegra_pcie *pcie) +{ + pcie->pex_rst = devm_reset_control_get(pcie->dev, "pex"); + if (IS_ERR(pcie->pex_rst)) + return PTR_ERR(pcie->pex_rst); + + pcie->afi_rst = devm_reset_control_get(pcie->dev, "afi"); + if (IS_ERR(pcie->afi_rst)) + return PTR_ERR(pcie->afi_rst); + + pcie->pcie_xrst = devm_reset_control_get(pcie->dev, "pcie_x"); + if (IS_ERR(pcie->pcie_xrst)) + return PTR_ERR(pcie->pcie_xrst); + + return 0; +} + static int tegra_pcie_get_resources(struct tegra_pcie *pcie) { struct platform_device *pdev = to_platform_device(pcie->dev); @@ -1025,6 +1042,12 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie) return err; } + err = tegra_pcie_resets_get(pcie); + if (err) { + dev_err(&pdev->dev, "failed to get resets: %d\n", err); + return err; + } + err = tegra_pcie_power_on(pcie); if (err) { dev_err(&pdev->dev, "failed to power up: %d\n", err); diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index ee26bac2d37..cd929aed361 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -494,7 +494,7 @@ static void acpiphp_bus_add(acpi_handle handle) acpi_bus_scan(handle); acpi_bus_get_device(handle, &adev); - if (adev) + if (acpi_device_enumerated(adev)) acpi_device_set_power(adev, ACPI_STATE_D0); } diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index ecfac7e72d9..8dcccffd6e2 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -31,12 +31,11 @@ #include <linux/slab.h> #include <linux/module.h> #include <linux/kernel.h> -#include <acpi/acpi_bus.h> #include <linux/sysfs.h> #include <linux/kobject.h> -#include <asm/uaccess.h> #include <linux/moduleparam.h> #include <linux/pci.h> +#include <asm/uaccess.h> #include "acpiphp.h" #include "../pci.h" diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index ccb0925bcd7..88b37cad4b3 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -162,8 +162,6 @@ static inline const char *slot_name(struct slot *slot) } #ifdef CONFIG_ACPI -#include <acpi/acpi.h> -#include <acpi/acpi_bus.h> #include <linux/pci-acpi.h> void __init pciehp_acpi_slot_detection_init(void); diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c index 2c2930ea06a..6b2b7dddbbd 100644 --- a/drivers/pci/ioapic.c +++ b/drivers/pci/ioapic.c @@ -20,7 +20,6 @@ #include <linux/module.h> #include <linux/acpi.h> #include <linux/slab.h> -#include <acpi/acpi_bus.h> struct ioapic { acpi_handle handle; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 2bdbc008020..f49abef8848 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -12,9 +12,6 @@ #include <linux/pci.h> #include <linux/module.h> #include <linux/pci-aspm.h> -#include <acpi/acpi.h> -#include <acpi/acpi_bus.h> - #include <linux/pci-acpi.h> #include <linux/pm_runtime.h> #include <linux/pm_qos.h> @@ -306,10 +303,10 @@ void acpi_pci_remove_bus(struct pci_bus *bus) } /* ACPI bus type */ -static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) +static struct acpi_device *acpi_pci_find_companion(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); - bool is_bridge; + bool check_children; u64 addr; /* @@ -317,14 +314,12 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) * is set only after acpi_pci_find_device() has been called for the * given device. */ - is_bridge = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE + check_children = pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || pci_dev->hdr_type == PCI_HEADER_TYPE_CARDBUS; /* Please ref to ACPI spec for the syntax of _ADR */ addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); - *handle = acpi_find_child(ACPI_HANDLE(dev->parent), addr, is_bridge); - if (!*handle) - return -ENODEV; - return 0; + return acpi_find_child_device(ACPI_COMPANION(dev->parent), addr, + check_children); } static void pci_acpi_setup(struct device *dev) @@ -367,7 +362,7 @@ static bool pci_acpi_bus_match(struct device *dev) static struct acpi_bus_type acpi_pci_bus = { .name = "PCI", .match = pci_acpi_bus_match, - .find_device = acpi_pci_find_device, + .find_companion = acpi_pci_find_companion, .setup = pci_acpi_setup, .cleanup = pci_acpi_cleanup, }; diff --git a/drivers/pci/pci-label.c b/drivers/pci/pci-label.c index 6f5d343d251..45113daaa77 100644 --- a/drivers/pci/pci-label.c +++ b/drivers/pci/pci-label.c @@ -29,7 +29,6 @@ #include <linux/nls.h> #include <linux/acpi.h> #include <linux/pci-acpi.h> -#include <acpi/acpi_bus.h> #include "pci.h" #define DEVICE_LABEL_DSM 0x07 @@ -162,7 +161,6 @@ static const char device_label_dsm_uuid[] = { }; enum acpi_attr_enum { - ACPI_ATTR_NONE = 0, ACPI_ATTR_LABEL_SHOW, ACPI_ATTR_INDEX_SHOW, }; @@ -170,84 +168,61 @@ enum acpi_attr_enum { static void dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf) { int len; - len = utf16s_to_utf8s((const wchar_t *)obj-> - package.elements[1].string.pointer, - obj->package.elements[1].string.length, + len = utf16s_to_utf8s((const wchar_t *)obj->string.pointer, + obj->string.length, UTF16_LITTLE_ENDIAN, buf, PAGE_SIZE); buf[len] = '\n'; } static int -dsm_get_label(acpi_handle handle, int func, - struct acpi_buffer *output, - char *buf, enum acpi_attr_enum attribute) +dsm_get_label(struct device *dev, char *buf, enum acpi_attr_enum attr) { - struct acpi_object_list input; - union acpi_object params[4]; - union acpi_object *obj; - int len = 0; - - int err; - - input.count = 4; - input.pointer = params; - params[0].type = ACPI_TYPE_BUFFER; - params[0].buffer.length = sizeof(device_label_dsm_uuid); - params[0].buffer.pointer = (char *)device_label_dsm_uuid; - params[1].type = ACPI_TYPE_INTEGER; - params[1].integer.value = 0x02; - params[2].type = ACPI_TYPE_INTEGER; - params[2].integer.value = func; - params[3].type = ACPI_TYPE_PACKAGE; - params[3].package.count = 0; - params[3].package.elements = NULL; - - err = acpi_evaluate_object(handle, "_DSM", &input, output); - if (err) + acpi_handle handle; + union acpi_object *obj, *tmp; + int len = -1; + + handle = ACPI_HANDLE(dev); + if (!handle) return -1; - obj = (union acpi_object *)output->pointer; - - switch (obj->type) { - case ACPI_TYPE_PACKAGE: - if (obj->package.count != 2) - break; - len = obj->package.elements[0].integer.value; - if (buf) { - if (attribute == ACPI_ATTR_INDEX_SHOW) - scnprintf(buf, PAGE_SIZE, "%llu\n", - obj->package.elements[0].integer.value); - else if (attribute == ACPI_ATTR_LABEL_SHOW) - dsm_label_utf16s_to_utf8s(obj, buf); - kfree(output->pointer); - return strlen(buf); - } - kfree(output->pointer); - return len; - break; - default: - kfree(output->pointer); + obj = acpi_evaluate_dsm(handle, device_label_dsm_uuid, 0x2, + DEVICE_LABEL_DSM, NULL); + if (!obj) + return -1; + + tmp = obj->package.elements; + if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 2 && + tmp[0].type == ACPI_TYPE_INTEGER && + tmp[1].type == ACPI_TYPE_STRING) { + /* + * The second string element is optional even when + * this _DSM is implemented; when not implemented, + * this entry must return a null string. + */ + if (attr == ACPI_ATTR_INDEX_SHOW) + scnprintf(buf, PAGE_SIZE, "%llu\n", tmp->integer.value); + else if (attr == ACPI_ATTR_LABEL_SHOW) + dsm_label_utf16s_to_utf8s(tmp + 1, buf); + len = strlen(buf) > 0 ? strlen(buf) : -1; } - return -1; + + ACPI_FREE(obj); + + return len; } static bool device_has_dsm(struct device *dev) { acpi_handle handle; - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; handle = ACPI_HANDLE(dev); - if (!handle) - return FALSE; + return false; - if (dsm_get_label(handle, DEVICE_LABEL_DSM, &output, NULL, - ACPI_ATTR_NONE) > 0) - return TRUE; - - return FALSE; + return !!acpi_check_dsm(handle, device_label_dsm_uuid, 0x2, + 1 << DEVICE_LABEL_DSM); } static umode_t @@ -266,44 +241,13 @@ acpi_index_string_exist(struct kobject *kobj, struct attribute *attr, int n) static ssize_t acpilabel_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_handle handle; - int length; - - handle = ACPI_HANDLE(dev); - - if (!handle) - return -1; - - length = dsm_get_label(handle, DEVICE_LABEL_DSM, - &output, buf, ACPI_ATTR_LABEL_SHOW); - - if (length < 1) - return -1; - - return length; + return dsm_get_label(dev, buf, ACPI_ATTR_LABEL_SHOW); } static ssize_t acpiindex_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; - acpi_handle handle; - int length; - - handle = ACPI_HANDLE(dev); - - if (!handle) - return -1; - - length = dsm_get_label(handle, DEVICE_LABEL_DSM, - &output, buf, ACPI_ATTR_INDEX_SHOW); - - if (length < 0) - return -1; - - return length; - + return dsm_get_label(dev, buf, ACPI_ATTR_INDEX_SHOW); } static struct device_attribute acpi_attr_label = { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 04796c056d1..6e34498ec9f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1208,18 +1208,6 @@ static void pci_release_capabilities(struct pci_dev *dev) pci_free_cap_save_buffers(dev); } -static void pci_free_resources(struct pci_dev *dev) -{ - int i; - - pci_cleanup_rom(dev); - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *res = dev->resource + i; - if (res->parent) - release_resource(res); - } -} - /** * pci_release_dev - free a pci device structure when all users of it are finished. * @dev: device that's been disconnected @@ -1229,14 +1217,9 @@ static void pci_free_resources(struct pci_dev *dev) */ static void pci_release_dev(struct device *dev) { - struct pci_dev *pci_dev = to_pci_dev(dev); - - down_write(&pci_bus_sem); - list_del(&pci_dev->bus_list); - up_write(&pci_bus_sem); - - pci_free_resources(pci_dev); + struct pci_dev *pci_dev; + pci_dev = to_pci_dev(dev); pci_release_capabilities(pci_dev); pci_release_of_node(pci_dev); pcibios_release_device(pci_dev); diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 4ff36bfa785..8bd76c9ba21 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -3,6 +3,18 @@ #include <linux/pci-aspm.h> #include "pci.h" +static void pci_free_resources(struct pci_dev *dev) +{ + int i; + + pci_cleanup_rom(dev); + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *res = dev->resource + i; + if (res->parent) + release_resource(res); + } +} + static void pci_stop_dev(struct pci_dev *dev) { pci_pme_active(dev, false); @@ -25,6 +37,11 @@ static void pci_destroy_dev(struct pci_dev *dev) device_del(&dev->dev); + down_write(&pci_bus_sem); + list_del(&dev->bus_list); + up_write(&pci_bus_sem); + + pci_free_resources(dev); put_device(&dev->dev); } |