diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/Kconfig | 6 | ||||
-rw-r--r-- | drivers/pci/host/Makefile | 1 | ||||
-rw-r--r-- | drivers/pci/host/pci-imx6.c | 575 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 10 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 37 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 23 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_ibm.c | 58 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp.h | 2 | ||||
-rw-r--r-- | drivers/pci/pci-driver.c | 17 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 101 | ||||
-rw-r--r-- | drivers/pci/pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/pci.h | 4 | ||||
-rw-r--r-- | drivers/pci/probe.c | 4 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 23 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 4 |
17 files changed, 745 insertions, 128 deletions
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 3d9504811126..efa24d9a3361 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -15,6 +15,12 @@ config PCI_EXYNOS select PCIEPORTBUS select PCIE_DW +config PCI_IMX6 + bool "Freescale i.MX6 PCIe controller" + depends on SOC_IMX6Q + select PCIEPORTBUS + select PCIE_DW + config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" depends on ARCH_TEGRA diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index c9a997b2690d..287d6a053dda 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o +obj-$(CONFIG_PCI_IMX6) += pci-imx6.o obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c new file mode 100644 index 000000000000..5afa9226a080 --- /dev/null +++ b/drivers/pci/host/pci-imx6.c @@ -0,0 +1,575 @@ +/* + * PCIe host controller driver for Freescale i.MX6 SoCs + * + * Copyright (C) 2013 Kosagi + * http://www.kosagi.com + * + * Author: Sean Cross <xobs@kosagi.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> +#include <linux/module.h> +#include <linux/of_gpio.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/resource.h> +#include <linux/signal.h> +#include <linux/types.h> + +#include "pcie-designware.h" + +#define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp) + +struct imx6_pcie { + int reset_gpio; + int power_on_gpio; + int wake_up_gpio; + int disable_gpio; + struct clk *lvds_gate; + struct clk *sata_ref_100m; + struct clk *pcie_ref_125m; + struct clk *pcie_axi; + struct pcie_port pp; + struct regmap *iomuxc_gpr; + void __iomem *mem_base; +}; + +/* PCIe Port Logic registers (memory-mapped) */ +#define PL_OFFSET 0x700 +#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28) +#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c) + +#define PCIE_PHY_CTRL (PL_OFFSET + 0x114) +#define PCIE_PHY_CTRL_DATA_LOC 0 +#define PCIE_PHY_CTRL_CAP_ADR_LOC 16 +#define PCIE_PHY_CTRL_CAP_DAT_LOC 17 +#define PCIE_PHY_CTRL_WR_LOC 18 +#define PCIE_PHY_CTRL_RD_LOC 19 + +#define PCIE_PHY_STAT (PL_OFFSET + 0x110) +#define PCIE_PHY_STAT_ACK_LOC 16 + +/* PHY registers (not memory-mapped) */ +#define PCIE_PHY_RX_ASIC_OUT 0x100D + +#define PHY_RX_OVRD_IN_LO 0x1005 +#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5) +#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3) + +static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val) +{ + u32 val; + u32 max_iterations = 10; + u32 wait_counter = 0; + + do { + val = readl(dbi_base + PCIE_PHY_STAT); + val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1; + wait_counter++; + + if (val == exp_val) + return 0; + + udelay(1); + } while (wait_counter < max_iterations); + + return -ETIMEDOUT; +} + +static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr) +{ + u32 val; + int ret; + + val = addr << PCIE_PHY_CTRL_DATA_LOC; + writel(val, dbi_base + PCIE_PHY_CTRL); + + val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC); + writel(val, dbi_base + PCIE_PHY_CTRL); + + ret = pcie_phy_poll_ack(dbi_base, 1); + if (ret) + return ret; + + val = addr << PCIE_PHY_CTRL_DATA_LOC; + writel(val, dbi_base + PCIE_PHY_CTRL); + + ret = pcie_phy_poll_ack(dbi_base, 0); + if (ret) + return ret; + + return 0; +} + +/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */ +static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data) +{ + u32 val, phy_ctl; + int ret; + + ret = pcie_phy_wait_ack(dbi_base, addr); + if (ret) + return ret; + + /* assert Read signal */ + phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC; + writel(phy_ctl, dbi_base + PCIE_PHY_CTRL); + + ret = pcie_phy_poll_ack(dbi_base, 1); + if (ret) + return ret; + + val = readl(dbi_base + PCIE_PHY_STAT); + *data = val & 0xffff; + + /* deassert Read signal */ + writel(0x00, dbi_base + PCIE_PHY_CTRL); + + ret = pcie_phy_poll_ack(dbi_base, 0); + if (ret) + return ret; + + return 0; +} + +static int pcie_phy_write(void __iomem *dbi_base, int addr, int data) +{ + u32 var; + int ret; + + /* write addr */ + /* cap addr */ + ret = pcie_phy_wait_ack(dbi_base, addr); + if (ret) + return ret; + + var = data << PCIE_PHY_CTRL_DATA_LOC; + writel(var, dbi_base + PCIE_PHY_CTRL); + + /* capture data */ + var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC); + writel(var, dbi_base + PCIE_PHY_CTRL); + + ret = pcie_phy_poll_ack(dbi_base, 1); + if (ret) + return ret; + + /* deassert cap data */ + var = data << PCIE_PHY_CTRL_DATA_LOC; + writel(var, dbi_base + PCIE_PHY_CTRL); + + /* wait for ack de-assertion */ + ret = pcie_phy_poll_ack(dbi_base, 0); + if (ret) + return ret; + + /* assert wr signal */ + var = 0x1 << PCIE_PHY_CTRL_WR_LOC; + writel(var, dbi_base + PCIE_PHY_CTRL); + + /* wait for ack */ + ret = pcie_phy_poll_ack(dbi_base, 1); + if (ret) + return ret; + + /* deassert wr signal */ + var = data << PCIE_PHY_CTRL_DATA_LOC; + writel(var, dbi_base + PCIE_PHY_CTRL); + + /* wait for ack de-assertion */ + ret = pcie_phy_poll_ack(dbi_base, 0); + if (ret) + return ret; + + writel(0x0, dbi_base + PCIE_PHY_CTRL); + + return 0; +} + +/* Added for PCI abort handling */ +static int imx6q_pcie_abort_handler(unsigned long addr, + unsigned int fsr, struct pt_regs *regs) +{ + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) + regs->ARM_pc += 4; + return 0; +} + +static int imx6_pcie_assert_core_reset(struct pcie_port *pp) +{ + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16); + + gpio_set_value(imx6_pcie->reset_gpio, 0); + msleep(100); + gpio_set_value(imx6_pcie->reset_gpio, 1); + + return 0; +} + +static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) +{ + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); + int ret; + + if (gpio_is_valid(imx6_pcie->power_on_gpio)) + gpio_set_value(imx6_pcie->power_on_gpio, 1); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16); + + ret = clk_prepare_enable(imx6_pcie->sata_ref_100m); + if (ret) { + dev_err(pp->dev, "unable to enable sata_ref_100m\n"); + goto err_sata_ref; + } + + ret = clk_prepare_enable(imx6_pcie->pcie_ref_125m); + if (ret) { + dev_err(pp->dev, "unable to enable pcie_ref_125m\n"); + goto err_pcie_ref; + } + + ret = clk_prepare_enable(imx6_pcie->lvds_gate); + if (ret) { + dev_err(pp->dev, "unable to enable lvds_gate\n"); + goto err_lvds_gate; + } + + ret = clk_prepare_enable(imx6_pcie->pcie_axi); + if (ret) { + dev_err(pp->dev, "unable to enable pcie_axi\n"); + goto err_pcie_axi; + } + + /* allow the clocks to stabilize */ + usleep_range(200, 500); + + return 0; + +err_pcie_axi: + clk_disable_unprepare(imx6_pcie->lvds_gate); +err_lvds_gate: + clk_disable_unprepare(imx6_pcie->pcie_ref_125m); +err_pcie_ref: + clk_disable_unprepare(imx6_pcie->sata_ref_100m); +err_sata_ref: + return ret; + +} + +static void imx6_pcie_init_phy(struct pcie_port *pp) +{ + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); + + /* configure constant input signal to the pcie ctrl and phy */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_LOS_LEVEL, 9 << 4); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, + IMX6Q_GPR8_TX_DEEMPH_GEN1, 0 << 0); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, + IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB, 0 << 6); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, + IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB, 20 << 12); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, + IMX6Q_GPR8_TX_SWING_FULL, 127 << 18); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, + IMX6Q_GPR8_TX_SWING_LOW, 127 << 25); +} + +static void imx6_pcie_host_init(struct pcie_port *pp) +{ + int count = 0; + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); + + imx6_pcie_assert_core_reset(pp); + + imx6_pcie_init_phy(pp); + + imx6_pcie_deassert_core_reset(pp); + + dw_pcie_setup_rc(pp); + + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); + + while (!dw_pcie_link_up(pp)) { + usleep_range(100, 1000); + count++; + if (count >= 10) { + dev_err(pp->dev, "phy link never came up\n"); + dev_dbg(pp->dev, + "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", + readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), + readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); + break; + } + } + + return; +} + +static int imx6_pcie_link_up(struct pcie_port *pp) +{ + u32 rc, ltssm, rx_valid, temp; + + /* link is debug bit 36, debug register 1 starts at bit 32 */ + rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & (0x1 << (36 - 32)); + if (rc) + return -EAGAIN; + + /* + * From L0, initiate MAC entry to gen2 if EP/RC supports gen2. + * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2). + * If (MAC/LTSSM.state == Recovery.RcvrLock) + * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition + * to gen2 is stuck + */ + pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid); + ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F; + + if (rx_valid & 0x01) + return 0; + + if (ltssm != 0x0d) + return 0; + + dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n"); + + pcie_phy_read(pp->dbi_base, + PHY_RX_OVRD_IN_LO, &temp); + temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN + | PHY_RX_OVRD_IN_LO_RX_PLL_EN); + pcie_phy_write(pp->dbi_base, + PHY_RX_OVRD_IN_LO, temp); + + usleep_range(2000, 3000); + + pcie_phy_read(pp->dbi_base, + PHY_RX_OVRD_IN_LO, &temp); + temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN + | PHY_RX_OVRD_IN_LO_RX_PLL_EN); + pcie_phy_write(pp->dbi_base, + PHY_RX_OVRD_IN_LO, temp); + + return 0; +} + +static struct pcie_host_ops imx6_pcie_host_ops = { + .link_up = imx6_pcie_link_up, + .host_init = imx6_pcie_host_init, +}; + +static int imx6_add_pcie_port(struct pcie_port *pp, + struct platform_device *pdev) +{ + int ret; + + pp->irq = platform_get_irq(pdev, 0); + if (!pp->irq) { + dev_err(&pdev->dev, "failed to get irq\n"); + return -ENODEV; + } + + pp->root_bus_nr = -1; + pp->ops = &imx6_pcie_host_ops; + + spin_lock_init(&pp->conf_lock); + ret = dw_pcie_host_init(pp); + if (ret) { + dev_err(&pdev->dev, "failed to initialize host\n"); + return ret; + } + + return 0; +} + +static int __init imx6_pcie_probe(struct platform_device *pdev) +{ + struct imx6_pcie *imx6_pcie; + struct pcie_port *pp; + struct device_node *np = pdev->dev.of_node; + struct resource *dbi_base; + int ret; + + imx6_pcie = devm_kzalloc(&pdev->dev, sizeof(*imx6_pcie), GFP_KERNEL); + if (!imx6_pcie) + return -ENOMEM; + + pp = &imx6_pcie->pp; + pp->dev = &pdev->dev; + + /* Added for PCI abort handling */ + hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0, + "imprecise external abort"); + + dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!dbi_base) { + dev_err(&pdev->dev, "dbi_base memory resource not found\n"); + return -ENODEV; + } + + pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); + if (IS_ERR(pp->dbi_base)) { + dev_err(&pdev->dev, "unable to remap dbi_base\n"); + ret = PTR_ERR(pp->dbi_base); + goto err; + } + + /* Fetch GPIOs */ + imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (!gpio_is_valid(imx6_pcie->reset_gpio)) { + dev_err(&pdev->dev, "no reset-gpio defined\n"); + ret = -ENODEV; + } + ret = devm_gpio_request_one(&pdev->dev, + imx6_pcie->reset_gpio, + GPIOF_OUT_INIT_LOW, + "PCIe reset"); + if (ret) { + dev_err(&pdev->dev, "unable to get reset gpio\n"); + goto err; + } + + imx6_pcie->power_on_gpio = of_get_named_gpio(np, "power-on-gpio", 0); + if (gpio_is_valid(imx6_pcie->power_on_gpio)) { + ret = devm_gpio_request_one(&pdev->dev, + imx6_pcie->power_on_gpio, + GPIOF_OUT_INIT_LOW, + "PCIe power enable"); + if (ret) { + dev_err(&pdev->dev, "unable to get power-on gpio\n"); + goto err; + } + } + + imx6_pcie->wake_up_gpio = of_get_named_gpio(np, "wake-up-gpio", 0); + if (gpio_is_valid(imx6_pcie->wake_up_gpio)) { + ret = devm_gpio_request_one(&pdev->dev, + imx6_pcie->wake_up_gpio, + GPIOF_IN, + "PCIe wake up"); + if (ret) { + dev_err(&pdev->dev, "unable to get wake-up gpio\n"); + goto err; + } + } + + imx6_pcie->disable_gpio = of_get_named_gpio(np, "disable-gpio", 0); + if (gpio_is_valid(imx6_pcie->disable_gpio)) { + ret = devm_gpio_request_one(&pdev->dev, + imx6_pcie->disable_gpio, + GPIOF_OUT_INIT_HIGH, + "PCIe disable endpoint"); + if (ret) { + dev_err(&pdev->dev, "unable to get disable-ep gpio\n"); + goto err; + } + } + + /* Fetch clocks */ + imx6_pcie->lvds_gate = devm_clk_get(&pdev->dev, "lvds_gate"); + if (IS_ERR(imx6_pcie->lvds_gate)) { + dev_err(&pdev->dev, + "lvds_gate clock select missing or invalid\n"); + ret = PTR_ERR(imx6_pcie->lvds_gate); + goto err; + } + + imx6_pcie->sata_ref_100m = devm_clk_get(&pdev->dev, "sata_ref_100m"); + if (IS_ERR(imx6_pcie->sata_ref_100m)) { + dev_err(&pdev->dev, + "sata_ref_100m clock source missing or invalid\n"); + ret = PTR_ERR(imx6_pcie->sata_ref_100m); + goto err; + } + + imx6_pcie->pcie_ref_125m = devm_clk_get(&pdev->dev, "pcie_ref_125m"); + if (IS_ERR(imx6_pcie->pcie_ref_125m)) { + dev_err(&pdev->dev, + "pcie_ref_125m clock source missing or invalid\n"); + ret = PTR_ERR(imx6_pcie->pcie_ref_125m); + goto err; + } + + imx6_pcie->pcie_axi = devm_clk_get(&pdev->dev, "pcie_axi"); + if (IS_ERR(imx6_pcie->pcie_axi)) { + dev_err(&pdev->dev, + "pcie_axi clock source missing or invalid\n"); + ret = PTR_ERR(imx6_pcie->pcie_axi); + goto err; + } + + /* Grab GPR config register range */ + imx6_pcie->iomuxc_gpr = + syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); + if (IS_ERR(imx6_pcie->iomuxc_gpr)) { + dev_err(&pdev->dev, "unable to find iomuxc registers\n"); + ret = PTR_ERR(imx6_pcie->iomuxc_gpr); + goto err; + } + + ret = imx6_add_pcie_port(pp, pdev); + if (ret < 0) + goto err; + + platform_set_drvdata(pdev, imx6_pcie); + return 0; + +err: + return ret; +} + +static const struct of_device_id imx6_pcie_of_match[] = { + { .compatible = "fsl,imx6q-pcie", }, + {}, +}; +MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); + +static struct platform_driver imx6_pcie_driver = { + .driver = { + .name = "imx6q-pcie", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(imx6_pcie_of_match), + }, +}; + +/* Freescale PCIe driver does not allow module unload */ + +static int __init imx6_pcie_init(void) +{ + return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe); +} +module_init(imx6_pcie_init); + +MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>"); +MODULE_DESCRIPTION("Freescale i.MX6 PCIe host controller driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 2e9888a0635a..7c4f38dd42ba 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -408,7 +408,7 @@ static void __iomem *tegra_pcie_bus_map(struct tegra_pcie *pcie, list_for_each_entry(bus, &pcie->busses, list) if (bus->nr == busnr) - return bus->area->addr; + return (void __iomem *)bus->area->addr; bus = tegra_pcie_bus_alloc(pcie, busnr); if (IS_ERR(bus)) @@ -416,7 +416,7 @@ static void __iomem *tegra_pcie_bus_map(struct tegra_pcie *pcie, list_add_tail(&bus->list, &pcie->busses); - return bus->area->addr; + return (void __iomem *)bus->area->addr; } static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus, diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index 2a47e82821da..f8140164ec0b 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c @@ -338,7 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) acpi_handle chandle, handle; struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; - flags &= OSC_SHPC_NATIVE_HP_CONTROL; + flags &= OSC_PCI_SHPC_NATIVE_HP_CONTROL; if (!flags) { err("Invalid flags %u specified!\n", flags); return -EINVAL; diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index f4e028924667..26100f510b10 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -39,16 +39,6 @@ #include <linux/mutex.h> #include <linux/pci_hotplug.h> -#define dbg(format, arg...) \ - do { \ - if (acpiphp_debug) \ - printk(KERN_DEBUG "%s: " format, \ - MY_NAME , ## arg); \ - } while (0) -#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) - struct acpiphp_context; struct acpiphp_bridge; struct acpiphp_slot; diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index bf2203ef1308..8650d39db392 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -31,6 +31,8 @@ * */ +#define pr_fmt(fmt) "acpiphp: " fmt + #include <linux/init.h> #include <linux/module.h> #include <linux/moduleparam.h> @@ -43,12 +45,9 @@ #include <linux/smp.h> #include "acpiphp.h" -#define MY_NAME "acpiphp" - /* name size which is used for entries in pcihpfs */ #define SLOT_NAME_SIZE 21 /* {_SUN} */ -bool acpiphp_debug; bool acpiphp_disabled; /* local variables */ @@ -61,9 +60,7 @@ static struct acpiphp_attention_info *attention_info; MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); MODULE_PARM_DESC(disable, "disable acpiphp driver"); -module_param_named(debug, acpiphp_debug, bool, 0644); module_param_named(disable, acpiphp_disabled, bool, 0444); /* export the attention callback registration methods */ @@ -139,7 +136,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); + pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); /* enable the specified slot */ return acpiphp_enable_slot(slot->acpi_slot); @@ -156,7 +153,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); + pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); /* disable the specified slot */ return acpiphp_disable_and_eject_slot(slot->acpi_slot); @@ -176,8 +173,9 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) { int retval = -ENODEV; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot)); - + pr_debug("%s - physical_slot = %s\n", __func__, + hotplug_slot_name(hotplug_slot)); + if (attention_info && try_module_get(attention_info->owner)) { retval = attention_info->set_attn(hotplug_slot, status); module_put(attention_info->owner); @@ -199,7 +197,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); + pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); *value = acpiphp_get_power_status(slot->acpi_slot); @@ -221,7 +219,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) { int retval = -EINVAL; - dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot)); + pr_debug("%s - physical_slot = %s\n", __func__, + hotplug_slot_name(hotplug_slot)); if (attention_info && try_module_get(attention_info->owner)) { retval = attention_info->get_attn(hotplug_slot, value); @@ -244,7 +243,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); + pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); *value = acpiphp_get_latch_status(slot->acpi_slot); @@ -264,7 +263,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); + pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); *value = acpiphp_get_adapter_status(slot->acpi_slot); @@ -279,7 +278,7 @@ static void release_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = hotplug_slot->private; - dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); + pr_debug("%s - physical_slot = %s\n", __func__, slot_name(slot)); kfree(slot->hotplug_slot); kfree(slot); @@ -322,11 +321,11 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, if (retval == -EBUSY) goto error_hpslot; if (retval) { - err("pci_hp_register failed with error %d\n", retval); + pr_err("pci_hp_register failed with error %d\n", retval); goto error_hpslot; } - info("Slot [%s] registered\n", slot_name(slot)); + pr_info("Slot [%s] registered\n", slot_name(slot)); return 0; error_hpslot: @@ -343,17 +342,17 @@ void acpiphp_unregister_hotplug_slot(struct acpiphp_slot *acpiphp_slot) struct slot *slot = acpiphp_slot->slot; int retval = 0; - info("Slot [%s] unregistered\n", slot_name(slot)); + pr_info("Slot [%s] unregistered\n", slot_name(slot)); retval = pci_hp_deregister(slot->hotplug_slot); if (retval) - err("pci_hp_deregister failed with error %d\n", retval); + pr_err("pci_hp_deregister failed with error %d\n", retval); } void __init acpiphp_init(void) { - info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", + pr_info(DRIVER_DESC " version: " DRIVER_VERSION "%s\n", acpiphp_disabled ? ", disabled by user; please report a bug" : ""); } diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 0b7d23b4ad95..6557702a0592 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -39,6 +39,8 @@ * bus. It loses the refcount when the the driver unloads. */ +#define pr_fmt(fmt) "acpiphp_glue: " fmt + #include <linux/init.h> #include <linux/module.h> @@ -58,8 +60,6 @@ static LIST_HEAD(bridge_list); static DEFINE_MUTEX(bridge_mutex); static DEFINE_MUTEX(acpiphp_context_lock); -#define MY_NAME "acpiphp_glue" - static void handle_hotplug_event(acpi_handle handle, u32 type, void *data); static void acpiphp_sanitize_bus(struct pci_bus *bus); static void acpiphp_set_hpp_values(struct pci_bus *bus); @@ -335,7 +335,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, if (ACPI_FAILURE(status)) sun = bridge->nr_slots; - dbg("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", + pr_debug("found ACPI PCI Hotplug slot %llu at PCI %04x:%02x:%02x\n", sun, pci_domain_nr(pbus), pbus->number, device); retval = acpiphp_register_hotplug_slot(slot, sun); @@ -343,10 +343,10 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, slot->slot = NULL; bridge->nr_slots--; if (retval == -EBUSY) - warn("Slot %llu already registered by another " + pr_warn("Slot %llu already registered by another " "hotplug driver\n", sun); else - warn("acpiphp_register_hotplug_slot failed " + pr_warn("acpiphp_register_hotplug_slot failed " "(err code = 0x%x)\n", retval); } /* Even if the slot registration fails, we can still use it. */ @@ -369,7 +369,7 @@ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *data, if (register_hotplug_dock_device(handle, &acpiphp_dock_ops, context, acpiphp_dock_init, acpiphp_dock_release)) - dbg("failed to register dock device\n"); + pr_debug("failed to register dock device\n"); } /* install notify handler */ @@ -427,7 +427,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) ACPI_SYSTEM_NOTIFY, handle_hotplug_event); if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); + pr_err("failed to remove notify handler\n"); } } if (slot->slot) @@ -830,8 +830,9 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* bus re-enumerate */ - dbg("%s: Bus check notify on %s\n", __func__, objname); - dbg("%s: re-enumerating slots under %s\n", __func__, objname); + pr_debug("%s: Bus check notify on %s\n", __func__, objname); + pr_debug("%s: re-enumerating slots under %s\n", + __func__, objname); if (bridge) { acpiphp_check_bridge(bridge); } else { @@ -845,7 +846,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) case ACPI_NOTIFY_DEVICE_CHECK: /* device check */ - dbg("%s: Device check notify on %s\n", __func__, objname); + pr_debug("%s: Device check notify on %s\n", __func__, objname); if (bridge) { acpiphp_check_bridge(bridge); } else { @@ -866,7 +867,7 @@ static void hotplug_event(acpi_handle handle, u32 type, void *data) case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ - dbg("%s: Device eject notify on %s\n", __func__, objname); + pr_debug("%s: Device eject notify on %s\n", __func__, objname); acpiphp_disable_and_eject_slot(func->slot); break; } diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 2f5786c8522c..0d64c414bf78 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -25,6 +25,8 @@ * */ +#define pr_fmt(fmt) "acpiphp_ibm: " fmt + #include <linux/init.h> #include <linux/slab.h> #include <linux/module.h> @@ -43,23 +45,11 @@ #define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>" #define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver IBM extension" -static bool debug; MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); -module_param(debug, bool, 0644); -MODULE_PARM_DESC(debug, " Debugging mode enabled or not"); -#define MY_NAME "acpiphp_ibm" - -#undef dbg -#define dbg(format, arg...) \ -do { \ - if (debug) \ - printk(KERN_DEBUG "%s: " format, \ - MY_NAME , ## arg); \ -} while (0) #define FOUND_APCI 0x61504349 /* these are the names for the IBM ACPI pseudo-device */ @@ -189,7 +179,7 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status) ibm_slot = ibm_slot_from_id(hpslot_to_sun(slot)); - dbg("%s: set slot %d (%d) attention status to %d\n", __func__, + pr_debug("%s: set slot %d (%d) attention status to %d\n", __func__, ibm_slot->slot.slot_num, ibm_slot->slot.slot_id, (status ? 1 : 0)); @@ -202,10 +192,10 @@ static int ibm_set_attention_status(struct hotplug_slot *slot, u8 status) stat = acpi_evaluate_integer(ibm_acpi_handle, "APLS", ¶ms, &rc); if (ACPI_FAILURE(stat)) { - err("APLS evaluation failed: 0x%08x\n", stat); + pr_err("APLS evaluation failed: 0x%08x\n", stat); return -ENODEV; } else if (!rc) { - err("APLS method failed: 0x%08llx\n", rc); + pr_err("APLS method failed: 0x%08llx\n", rc); return -ERANGE; } return 0; @@ -234,7 +224,7 @@ static int ibm_get_attention_status(struct hotplug_slot *slot, u8 *status) else *status = 0; - dbg("%s: get slot %d (%d) attention status is %d\n", __func__, + pr_debug("%s: get slot %d (%d) attention status is %d\n", __func__, ibm_slot->slot.slot_num, ibm_slot->slot.slot_id, *status); @@ -266,10 +256,10 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) u8 subevent = event & 0xf0; struct notification *note = context; - dbg("%s: Received notification %02x\n", __func__, event); + pr_debug("%s: Received notification %02x\n", __func__, event); if (subevent == 0x80) { - dbg("%s: generationg bus event\n", __func__); + pr_debug("%s: generationg bus event\n", __func__); acpi_bus_generate_netlink_event(note->device->pnp.device_class, dev_name(¬e->device->dev), note->event, detail); @@ -301,7 +291,7 @@ static int ibm_get_table_from_acpi(char **bufp) status = acpi_evaluate_object(ibm_acpi_handle, "APCI", NULL, &buffer); if (ACPI_FAILURE(status)) { - err("%s: APCI evaluation failed\n", __func__); + pr_err("%s: APCI evaluation failed\n", __func__); return -ENODEV; } @@ -309,13 +299,13 @@ static int ibm_get_table_from_acpi(char **bufp) if (!(package) || (package->type != ACPI_TYPE_PACKAGE) || !(package->package.elements)) { - err("%s: Invalid APCI object\n", __func__); + pr_err("%s: Invalid APCI object\n", __func__); goto read_table_done; } for(size = 0, i = 0; i < package->package.count; i++) { if (package->package.elements[i].type != ACPI_TYPE_BUFFER) { - err("%s: Invalid APCI element %d\n", __func__, i); + pr_err("%s: Invalid APCI element %d\n", __func__, i); goto read_table_done; } size += package->package.elements[i].buffer.length; @@ -325,7 +315,7 @@ static int ibm_get_table_from_acpi(char **bufp) goto read_table_done; lbuf = kzalloc(size, GFP_KERNEL); - dbg("%s: element count: %i, ASL table size: %i, &table = 0x%p\n", + pr_debug("%s: element count: %i, ASL table size: %i, &table = 0x%p\n", __func__, package->package.count, size, lbuf); if (lbuf) { @@ -370,8 +360,8 @@ static ssize_t ibm_read_apci_table(struct file *filp, struct kobject *kobj, { int bytes_read = -EINVAL; char *table = NULL; - - dbg("%s: pos = %d, size = %zd\n", __func__, (int)pos, size); + + pr_debug("%s: pos = %d, size = %zd\n", __func__, (int)pos, size); if (pos == 0) { bytes_read = ibm_get_table_from_acpi(&table); @@ -403,7 +393,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, status = acpi_get_object_info(handle, &info); if (ACPI_FAILURE(status)) { - err("%s: Failed to get device information status=0x%x\n", + pr_err("%s: Failed to get device information status=0x%x\n", __func__, status); return retval; } @@ -411,7 +401,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, if (info->current_status && (info->valid & ACPI_VALID_HID) && (!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) || !strcmp(info->hardware_id.string, IBM_HARDWARE_ID2))) { - dbg("found hardware: %s, handle: %p\n", + pr_debug("found hardware: %s, handle: %p\n", info->hardware_id.string, handle); *phandle = handle; /* returning non-zero causes the search to stop @@ -432,18 +422,18 @@ static int __init ibm_acpiphp_init(void) struct acpi_device *device; struct kobject *sysdir = &pci_slots_kset->kobj; - dbg("%s\n", __func__); + pr_debug("%s\n", __func__); if (acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, ibm_find_acpi_device, NULL, &ibm_acpi_handle, NULL) != FOUND_APCI) { - err("%s: acpi_walk_namespace failed\n", __func__); + pr_err("%s: acpi_walk_namespace failed\n", __func__); retval = -ENODEV; goto init_return; } - dbg("%s: found IBM aPCI device\n", __func__); + pr_debug("%s: found IBM aPCI device\n", __func__); if (acpi_bus_get_device(ibm_acpi_handle, &device)) { - err("%s: acpi_bus_get_device failed\n", __func__); + pr_err("%s: acpi_bus_get_device failed\n", __func__); retval = -ENODEV; goto init_return; } @@ -457,7 +447,7 @@ static int __init ibm_acpiphp_init(void) ACPI_DEVICE_NOTIFY, ibm_handle_events, &ibm_note); if (ACPI_FAILURE(status)) { - err("%s: Failed to register notification handler\n", + pr_err("%s: Failed to register notification handler\n", __func__); retval = -EBUSY; goto init_cleanup; @@ -479,17 +469,17 @@ static void __exit ibm_acpiphp_exit(void) acpi_status status; struct kobject *sysdir = &pci_slots_kset->kobj; - dbg("%s\n", __func__); + pr_debug("%s\n", __func__); if (acpiphp_unregister_attention(&ibm_attention_info)) - err("%s: attention info deregistration failed", __func__); + pr_err("%s: attention info deregistration failed", __func__); status = acpi_remove_notify_handler( ibm_acpi_handle, ACPI_DEVICE_NOTIFY, ibm_handle_events); if (ACPI_FAILURE(status)) - err("%s: Notification handler removal failed\n", __func__); + pr_err("%s: Notification handler removal failed\n", __func__); /* remove the /sys entries */ sysfs_remove_bin_file(sysdir, &ibm_apci_table_attr); } diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index e260f207a90e..d876e4b3c6a9 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -191,7 +191,7 @@ static inline const char *slot_name(struct slot *slot) #include <linux/pci-acpi.h> static inline int get_hp_hw_control_from_firmware(struct pci_dev *dev) { - u32 flags = OSC_SHPC_NATIVE_HP_CONTROL; + u32 flags = OSC_PCI_SHPC_NATIVE_HP_CONTROL; return acpi_get_hp_hw_control_from_firmware(dev, flags); } #else diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 98f7b9b89507..9f85960a62ed 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -135,6 +135,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) return retval; return count; } +static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); /** * store_remove_id - remove a PCI device ID from this driver @@ -180,12 +181,14 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) return retval; return count; } +static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); -static struct driver_attribute pci_drv_attrs[] = { - __ATTR(new_id, S_IWUSR, NULL, store_new_id), - __ATTR(remove_id, S_IWUSR, NULL, store_remove_id), - __ATTR_NULL, +static struct attribute *pci_drv_attrs[] = { + &driver_attr_new_id.attr, + &driver_attr_remove_id.attr, + NULL, }; +ATTRIBUTE_GROUPS(pci_drv); /** * pci_match_id - See if a pci device matches a given pci_id table @@ -1316,9 +1319,9 @@ struct bus_type pci_bus_type = { .probe = pci_device_probe, .remove = pci_device_remove, .shutdown = pci_device_shutdown, - .dev_attrs = pci_dev_attrs, - .bus_attrs = pci_bus_attrs, - .drv_attrs = pci_drv_attrs, + .dev_groups = pci_dev_groups, + .bus_groups = pci_bus_groups, + .drv_groups = pci_drv_groups, .pm = PCI_PM_OPS_PTR, }; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 7128cfdd64aa..82cc45867eaa 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -42,7 +42,8 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf) \ \ pdev = to_pci_dev (dev); \ return sprintf (buf, format_string, pdev->field); \ -} +} \ +static DEVICE_ATTR_RO(field) pci_config_attr(vendor, "0x%04x\n"); pci_config_attr(device, "0x%04x\n"); @@ -73,6 +74,7 @@ static ssize_t broken_parity_status_store(struct device *dev, return count; } +static DEVICE_ATTR_RW(broken_parity_status); static ssize_t local_cpus_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -91,7 +93,7 @@ static ssize_t local_cpus_show(struct device *dev, buf[len] = '\0'; return len; } - +static DEVICE_ATTR_RO(local_cpus); static ssize_t local_cpulist_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -110,6 +112,7 @@ static ssize_t local_cpulist_show(struct device *dev, buf[len] = '\0'; return len; } +static DEVICE_ATTR_RO(local_cpulist); /* * PCI Bus Class Devices @@ -170,6 +173,7 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) } return (str - buf); } +static DEVICE_ATTR_RO(resource); static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -181,10 +185,11 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), (u8)(pci_dev->class)); } +static DEVICE_ATTR_RO(modalias); -static ssize_t is_enabled_store(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) +static ssize_t enabled_store(struct device *dev, + struct device_attribute *attr, const char *buf, + size_t count) { struct pci_dev *pdev = to_pci_dev(dev); unsigned long val; @@ -208,14 +213,15 @@ static ssize_t is_enabled_store(struct device *dev, return result < 0 ? result : count; } -static ssize_t is_enabled_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t enabled_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct pci_dev *pdev; pdev = to_pci_dev (dev); return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt)); } +static DEVICE_ATTR_RW(enabled); #ifdef CONFIG_NUMA static ssize_t @@ -223,6 +229,7 @@ numa_node_show(struct device *dev, struct device_attribute *attr, char *buf) { return sprintf (buf, "%d\n", dev->numa_node); } +static DEVICE_ATTR_RO(numa_node); #endif static ssize_t @@ -232,6 +239,7 @@ dma_mask_bits_show(struct device *dev, struct device_attribute *attr, char *buf) return sprintf (buf, "%d\n", fls64(pdev->dma_mask)); } +static DEVICE_ATTR_RO(dma_mask_bits); static ssize_t consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr, @@ -239,6 +247,7 @@ consistent_dma_mask_bits_show(struct device *dev, struct device_attribute *attr, { return sprintf (buf, "%d\n", fls64(dev->coherent_dma_mask)); } +static DEVICE_ATTR_RO(consistent_dma_mask_bits); static ssize_t msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -283,6 +292,7 @@ msi_bus_store(struct device *dev, struct device_attribute *attr, return count; } +static DEVICE_ATTR_RW(msi_bus); static DEFINE_MUTEX(pci_remove_rescan_mutex); static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, @@ -302,10 +312,20 @@ static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf, } return count; } +static BUS_ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store); + +static struct attribute *pci_bus_attrs[] = { + &bus_attr_rescan.attr, + NULL, +}; -struct bus_attribute pci_bus_attrs[] = { - __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store), - __ATTR_NULL +static const struct attribute_group pci_bus_group = { + .attrs = pci_bus_attrs, +}; + +const struct attribute_group *pci_bus_groups[] = { + &pci_bus_group, + NULL, }; static ssize_t @@ -325,8 +345,9 @@ dev_rescan_store(struct device *dev, struct device_attribute *attr, } return count; } -struct device_attribute dev_rescan_attr = __ATTR(rescan, (S_IWUSR|S_IWGRP), - NULL, dev_rescan_store); +static struct device_attribute dev_rescan_attr = __ATTR(rescan, + (S_IWUSR|S_IWGRP), + NULL, dev_rescan_store); static void remove_callback(struct device *dev) { @@ -356,8 +377,9 @@ remove_store(struct device *dev, struct device_attribute *dummy, count = ret; return count; } -struct device_attribute dev_remove_attr = __ATTR(remove, (S_IWUSR|S_IWGRP), - NULL, remove_store); +static struct device_attribute dev_remove_attr = __ATTR(remove, + (S_IWUSR|S_IWGRP), + NULL, remove_store); static ssize_t dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, @@ -404,6 +426,7 @@ static ssize_t d3cold_allowed_show(struct device *dev, struct pci_dev *pdev = to_pci_dev(dev); return sprintf (buf, "%u\n", pdev->d3cold_allowed); } +static DEVICE_ATTR_RW(d3cold_allowed); #endif #ifdef CONFIG_PCI_IOV @@ -489,30 +512,38 @@ static struct device_attribute sriov_numvfs_attr = sriov_numvfs_show, sriov_numvfs_store); #endif /* CONFIG_PCI_IOV */ -struct device_attribute pci_dev_attrs[] = { - __ATTR_RO(resource), - __ATTR_RO(vendor), - __ATTR_RO(device), - __ATTR_RO(subsystem_vendor), - __ATTR_RO(subsystem_device), - __ATTR_RO(class), - __ATTR_RO(irq), - __ATTR_RO(local_cpus), - __ATTR_RO(local_cpulist), - __ATTR_RO(modalias), +static struct attribute *pci_dev_attrs[] = { + &dev_attr_resource.attr, + &dev_attr_vendor.attr, + &dev_attr_device.attr, + &dev_attr_subsystem_vendor.attr, + &dev_attr_subsystem_device.attr, + &dev_attr_class.attr, + &dev_attr_irq.attr, + &dev_attr_local_cpus.attr, + &dev_attr_local_cpulist.attr, + &dev_attr_modalias.attr, #ifdef CONFIG_NUMA - __ATTR_RO(numa_node), + &dev_attr_numa_node.attr, #endif - __ATTR_RO(dma_mask_bits), - __ATTR_RO(consistent_dma_mask_bits), - __ATTR(enable, 0600, is_enabled_show, is_enabled_store), - __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), - broken_parity_status_show,broken_parity_status_store), - __ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store), + &dev_attr_dma_mask_bits.attr, + &dev_attr_consistent_dma_mask_bits.attr, + &dev_attr_enabled.attr, + &dev_attr_broken_parity_status.attr, + &dev_attr_msi_bus.attr, #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) - __ATTR(d3cold_allowed, 0644, d3cold_allowed_show, d3cold_allowed_store), + &dev_attr_d3cold_allowed.attr, #endif - __ATTR_NULL, + NULL, +}; + +static const struct attribute_group pci_dev_group = { + .attrs = pci_dev_attrs, +}; + +const struct attribute_group *pci_dev_groups[] = { + &pci_dev_group, + NULL, }; static struct attribute *pcibus_attrs[] = { @@ -544,7 +575,7 @@ boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf) !!(pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)); } -struct device_attribute vga_attr = __ATTR_RO(boot_vga); +static struct device_attribute vga_attr = __ATTR_RO(boot_vga); static ssize_t pci_read_config(struct file *filp, struct kobject *kobj, diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index e8ccf6c0f08a..ad7fc72a40a0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2854,7 +2854,7 @@ void __weak pcibios_set_master(struct pci_dev *dev) lat = pcibios_max_latency; else return; - dev_printk(KERN_DEBUG, &dev->dev, "setting latency timer to %d\n", lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 8a00c063d7bc..9c91ecc1301b 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -153,10 +153,10 @@ static inline int pci_no_d1d2(struct pci_dev *dev) return (dev->no_d1d2 || parent_dstates); } -extern struct device_attribute pci_dev_attrs[]; +extern const struct attribute_group *pci_dev_groups[]; extern const struct attribute_group *pcibus_groups[]; extern struct device_type pci_dev_type; -extern struct bus_attribute pci_bus_attrs[]; +extern const struct attribute_group *pci_bus_groups[]; /** diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 7ef0f868b3e0..5e14f5a51357 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -641,8 +641,7 @@ static void pci_set_bus_speed(struct pci_bus *bus) return; } - pos = pci_find_capability(bridge, PCI_CAP_ID_EXP); - if (pos) { + if (pci_is_pcie(bridge)) { u32 linkcap; u16 linksta; @@ -984,7 +983,6 @@ void set_pcie_port_type(struct pci_dev *pdev) pos = pci_find_capability(pdev, PCI_CAP_ID_EXP); if (!pos) return; - pdev->is_pcie = 1; pdev->pcie_cap = pos; pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); pdev->pcie_flags_reg = reg16; diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f6c31fabf3af..91490453c229 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2955,6 +2955,29 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); /* + * PCI devices which are on Intel chips can skip the 10ms delay + * before entering D3 mode. + */ +static void quirk_remove_d3_delay(struct pci_dev *dev) +{ + dev->d3_delay = 0; +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); + +/* * Some devices may pass our check in pci_intx_mask_supported if * PCI_COMMAND_INTX_DISABLE works though they actually do not properly * support this feature. diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index bc26d7990cc3..4ce83b26ae9e 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -982,7 +982,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, } min_align = calculate_mem_align(aligns, max_order); - min_align = max(min_align, window_alignment(bus, b_res->flags & mask)); + min_align = max(min_align, window_alignment(bus, b_res->flags)); size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); if (children_add_size > add_size) add_size = children_add_size; @@ -1136,7 +1136,7 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, } /* The root bus? */ - if (!bus->self) + if (pci_is_root_bus(bus)) return; switch (bus->self->class >> 8) { |