diff options
26 files changed, 238 insertions, 295 deletions
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 81b3949a26db..19223ed2e619 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -15,7 +15,7 @@ #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of_gpio.h> #include <linux/pci.h> #include <linux/phy/phy.h> @@ -443,25 +443,6 @@ err_phy: return ret; } -static int __exit dra7xx_pcie_remove(struct platform_device *pdev) -{ - struct dra7xx_pcie *dra7xx = platform_get_drvdata(pdev); - struct pcie_port *pp = &dra7xx->pp; - struct device *dev = &pdev->dev; - int count = dra7xx->phy_count; - - if (pp->irq_domain) - irq_domain_remove(pp->irq_domain); - pm_runtime_put(dev); - pm_runtime_disable(dev); - while (count--) { - phy_power_off(dra7xx->phy[count]); - phy_exit(dra7xx->phy[count]); - } - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int dra7xx_pcie_suspend(struct device *dev) { @@ -545,19 +526,13 @@ static const struct of_device_id of_dra7xx_pcie_match[] = { { .compatible = "ti,dra7-pcie", }, {}, }; -MODULE_DEVICE_TABLE(of, of_dra7xx_pcie_match); static struct platform_driver dra7xx_pcie_driver = { - .remove = __exit_p(dra7xx_pcie_remove), .driver = { .name = "dra7-pcie", .of_match_table = of_dra7xx_pcie_match, + .suppress_bind_attrs = true, .pm = &dra7xx_pcie_pm_ops, }, }; - -module_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe); - -MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); -MODULE_DESCRIPTION("TI PCIe controller driver"); -MODULE_LICENSE("GPL v2"); +builtin_platform_driver_probe(dra7xx_pcie_driver, dra7xx_pcie_probe); diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index 219976103efc..c3ae9c7a6e33 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -16,7 +16,7 @@ #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of_gpio.h> #include <linux/pci.h> #include <linux/platform_device.h> @@ -624,7 +624,6 @@ static const struct of_device_id exynos_pcie_of_match[] = { { .compatible = "samsung,exynos5440-pcie", }, {}, }; -MODULE_DEVICE_TABLE(of, exynos_pcie_of_match); static struct platform_driver exynos_pcie_driver = { .remove = __exit_p(exynos_pcie_remove), @@ -641,7 +640,3 @@ static int __init exynos_pcie_init(void) return platform_driver_probe(&exynos_pcie_driver, exynos_pcie_probe); } subsys_initcall(exynos_pcie_init); - -MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); -MODULE_DESCRIPTION("Samsung PCIe host controller driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 9d9d34e959b6..946382fd4ea1 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -1,4 +1,6 @@ /* + * Generic PCI host driver common code + * * 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. @@ -17,7 +19,6 @@ */ #include <linux/kernel.h> -#include <linux/module.h> #include <linux/of_address.h> #include <linux/of_pci.h> #include <linux/pci-ecam.h> @@ -162,7 +163,3 @@ int pci_host_common_probe(struct platform_device *pdev, pci_bus_add_devices(bus); return 0; } - -MODULE_DESCRIPTION("Generic PCI host driver common code"); -MODULE_AUTHOR("Will Deacon <will.deacon@arm.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index b741a36a67f3..ead4a5c3480b 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -739,7 +739,6 @@ static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, }, {}, }; -MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); static struct platform_driver imx6_pcie_driver = { .driver = { @@ -749,14 +748,8 @@ static struct platform_driver imx6_pcie_driver = { .shutdown = imx6_pcie_shutdown, }; -/* 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"); +device_initcall(imx6_pcie_init); diff --git a/drivers/pci/host/pcie-altera-msi.c b/drivers/pci/host/pcie-altera-msi.c index 99177f4ccde2..369e033449c6 100644 --- a/drivers/pci/host/pcie-altera-msi.c +++ b/drivers/pci/host/pcie-altera-msi.c @@ -1,4 +1,8 @@ /* + * Altera PCIe MSI support + * + * Author: Ley Foon Tan <lftan@altera.com> + * * Copyright Altera Corporation (C) 2013-2015. All rights reserved * * This program is free software; you can redistribute it and/or modify it @@ -16,7 +20,7 @@ #include <linux/interrupt.h> #include <linux/irqchip/chained_irq.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/msi.h> #include <linux/of_address.h> #include <linux/of_irq.h> @@ -308,7 +312,3 @@ static int __init altera_msi_init(void) return platform_driver_register(&altera_msi_driver); } subsys_initcall(altera_msi_init); - -MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>"); -MODULE_DESCRIPTION("Altera PCIe MSI support"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index 2b7837650db8..48f2736a10cd 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c @@ -1,6 +1,9 @@ /* * Copyright Altera Corporation (C) 2013-2015. All rights reserved * + * Author: Ley Foon Tan <lftan@altera.com> + * Description: Altera PCIe host controller driver + * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. @@ -17,7 +20,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/irqchip/chained_irq.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of_address.h> #include <linux/of_irq.h> #include <linux/of_pci.h> @@ -568,7 +571,6 @@ static const struct of_device_id altera_pcie_of_match[] = { { .compatible = "altr,pcie-root-port-1.0", }, {}, }; -MODULE_DEVICE_TABLE(of, altera_pcie_of_match); static struct platform_driver altera_pcie_driver = { .probe = altera_pcie_probe, @@ -583,8 +585,4 @@ static int altera_pcie_init(void) { return platform_driver_register(&altera_pcie_driver); } -module_init(altera_pcie_init); - -MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>"); -MODULE_DESCRIPTION("Altera PCIe host controller driver"); -MODULE_LICENSE("GPL v2"); +device_initcall(altera_pcie_init); diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 12afce19890b..16374202cb8b 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -14,7 +14,6 @@ #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> -#include <linux/module.h> #include <linux/msi.h> #include <linux/of_address.h> #include <linux/of_pci.h> @@ -802,7 +801,3 @@ void dw_pcie_setup_rc(struct pcie_port *pp) val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); } - -MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); -MODULE_DESCRIPTION("Designware PCIe host controller driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c index f2f90c50f75d..5ec2d440a6b7 100644 --- a/drivers/pci/host/pcie-qcom.c +++ b/drivers/pci/host/pcie-qcom.c @@ -1,7 +1,11 @@ /* + * Qualcomm PCIe root complex driver + * * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. * Copyright 2015 Linaro Limited. * + * Author: Stanimir Varbanov <svarbanov@mm-sol.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 and * only version 2 as published by the Free Software Foundation. @@ -19,7 +23,7 @@ #include <linux/io.h> #include <linux/iopoll.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of_device.h> #include <linux/of_gpio.h> #include <linux/pci.h> @@ -570,37 +574,19 @@ static int qcom_pcie_probe(struct platform_device *pdev) return 0; } -static int qcom_pcie_remove(struct platform_device *pdev) -{ - struct qcom_pcie *pcie = platform_get_drvdata(pdev); - - qcom_ep_reset_assert(pcie); - phy_power_off(pcie->phy); - phy_exit(pcie->phy); - pcie->ops->deinit(pcie); - - return 0; -} - static const struct of_device_id qcom_pcie_match[] = { { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 }, { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, { } }; -MODULE_DEVICE_TABLE(of, qcom_pcie_match); static struct platform_driver qcom_pcie_driver = { .probe = qcom_pcie_probe, - .remove = qcom_pcie_remove, .driver = { .name = "qcom-pcie", + .suppress_bind_attrs = true, .of_match_table = qcom_pcie_match, }, }; - -module_platform_driver(qcom_pcie_driver); - -MODULE_AUTHOR("Stanimir Varbanov <svarbanov@mm-sol.com>"); -MODULE_DESCRIPTION("Qualcomm PCIe root complex driver"); -MODULE_LICENSE("GPL v2"); +builtin_platform_driver(qcom_pcie_driver); diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index a4060b85ab23..09aed85f275a 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -15,7 +15,7 @@ #include <linux/clk.h> #include <linux/interrupt.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/pci.h> #include <linux/phy/phy.h> @@ -355,7 +355,6 @@ static const struct of_device_id spear13xx_pcie_of_match[] = { { .compatible = "st,spear1340-pcie", }, {}, }; -MODULE_DEVICE_TABLE(of, spear13xx_pcie_of_match); static struct platform_driver spear13xx_pcie_driver = { .probe = spear13xx_pcie_probe, @@ -365,14 +364,8 @@ static struct platform_driver spear13xx_pcie_driver = { }, }; -/* SPEAr13xx PCIe driver does not allow module unload */ - static int __init spear13xx_pcie_init(void) { return platform_driver_register(&spear13xx_pcie_driver); } -module_init(spear13xx_pcie_init); - -MODULE_DESCRIPTION("ST Microelectronics SPEAr13xx PCIe host controller driver"); -MODULE_AUTHOR("Pratyush Anand <pratyush.anand@gmail.com>"); -MODULE_LICENSE("GPL v2"); +device_initcall(spear13xx_pcie_init); diff --git a/drivers/pci/host/pcie-xilinx-nwl.c b/drivers/pci/host/pcie-xilinx-nwl.c index 0b597d9190b4..df7fb8b69658 100644 --- a/drivers/pci/host/pcie-xilinx-nwl.c +++ b/drivers/pci/host/pcie-xilinx-nwl.c @@ -15,7 +15,7 @@ #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/msi.h> #include <linux/of_address.h> #include <linux/of_pci.h> @@ -459,40 +459,6 @@ static const struct irq_domain_ops dev_msi_domain_ops = { .free = nwl_irq_domain_free, }; -static void nwl_msi_free_irq_domain(struct nwl_pcie *pcie) -{ - struct nwl_msi *msi = &pcie->msi; - - if (msi->irq_msi0) - irq_set_chained_handler_and_data(msi->irq_msi0, NULL, NULL); - if (msi->irq_msi1) - irq_set_chained_handler_and_data(msi->irq_msi1, NULL, NULL); - - if (msi->msi_domain) - irq_domain_remove(msi->msi_domain); - if (msi->dev_domain) - irq_domain_remove(msi->dev_domain); - - kfree(msi->bitmap); - msi->bitmap = NULL; -} - -static void nwl_pcie_free_irq_domain(struct nwl_pcie *pcie) -{ - int i; - u32 irq; - - for (i = 0; i < INTX_NUM; i++) { - irq = irq_find_mapping(pcie->legacy_irq_domain, i + 1); - if (irq > 0) - irq_dispose_mapping(irq); - } - if (pcie->legacy_irq_domain) - irq_domain_remove(pcie->legacy_irq_domain); - - nwl_msi_free_irq_domain(pcie); -} - static int nwl_pcie_init_msi_irq_domain(struct nwl_pcie *pcie) { #ifdef CONFIG_PCI_MSI @@ -867,25 +833,12 @@ error: return err; } -static int nwl_pcie_remove(struct platform_device *pdev) -{ - struct nwl_pcie *pcie = platform_get_drvdata(pdev); - - nwl_pcie_free_irq_domain(pcie); - platform_set_drvdata(pdev, NULL); - return 0; -} - static struct platform_driver nwl_pcie_driver = { .driver = { .name = "nwl-pcie", + .suppress_bind_attrs = true, .of_match_table = nwl_pcie_of_match, }, .probe = nwl_pcie_probe, - .remove = nwl_pcie_remove, }; -module_platform_driver(nwl_pcie_driver); - -MODULE_AUTHOR("Xilinx, Inc"); -MODULE_DESCRIPTION("NWL PCIe driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(nwl_pcie_driver); diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c index a30e01639557..7b7dbd22bccc 100644 --- a/drivers/pci/host/pcie-xilinx.c +++ b/drivers/pci/host/pcie-xilinx.c @@ -18,7 +18,7 @@ #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/msi.h> #include <linux/of_address.h> #include <linux/of_pci.h> @@ -506,35 +506,6 @@ static irqreturn_t xilinx_pcie_intr_handler(int irq, void *data) } /** - * xilinx_pcie_free_irq_domain - Free IRQ domain - * @port: PCIe port information - */ -static void xilinx_pcie_free_irq_domain(struct xilinx_pcie_port *port) -{ - int i; - u32 irq, num_irqs; - - /* Free IRQ Domain */ - if (IS_ENABLED(CONFIG_PCI_MSI)) { - - free_pages(port->msi_pages, 0); - - num_irqs = XILINX_NUM_MSI_IRQS; - } else { - /* INTx */ - num_irqs = 4; - } - - for (i = 0; i < num_irqs; i++) { - irq = irq_find_mapping(port->irq_domain, i); - if (irq > 0) - irq_dispose_mapping(irq); - } - - irq_domain_remove(port->irq_domain); -} - -/** * xilinx_pcie_init_irq_domain - Initialize IRQ domain * @port: PCIe port information * @@ -724,21 +695,6 @@ error: return err; } -/** - * xilinx_pcie_remove - Remove function - * @pdev: Platform device pointer - * - * Return: '0' always - */ -static int xilinx_pcie_remove(struct platform_device *pdev) -{ - struct xilinx_pcie_port *port = platform_get_drvdata(pdev); - - xilinx_pcie_free_irq_domain(port); - - return 0; -} - static struct of_device_id xilinx_pcie_of_match[] = { { .compatible = "xlnx,axi-pcie-host-1.00.a", }, {} @@ -751,10 +707,5 @@ static struct platform_driver xilinx_pcie_driver = { .suppress_bind_attrs = true, }, .probe = xilinx_pcie_probe, - .remove = xilinx_pcie_remove, }; -module_platform_driver(xilinx_pcie_driver); - -MODULE_AUTHOR("Xilinx Inc"); -MODULE_DESCRIPTION("Xilinx AXI PCIe driver"); -MODULE_LICENSE("GPL v2"); +builtin_platform_driver(xilinx_pcie_driver); diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 555bcde3b196..60e66e027ebc 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h @@ -101,10 +101,8 @@ int cpci_unconfigure_slot(struct slot *slot); #ifdef CONFIG_HOTPLUG_PCI_CPCI int cpci_hotplug_init(int debug); -void cpci_hotplug_exit(void); #else static inline int cpci_hotplug_init(int debug) { return 0; } -static inline void cpci_hotplug_exit(void) { } #endif #endif /* _CPCI_HOTPLUG_H */ diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 7d3866c47312..7ec8a8f72c69 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -719,13 +719,3 @@ cpci_hotplug_init(int debug) cpci_debug = debug; return 0; } - -void __exit -cpci_hotplug_exit(void) -{ - /* - * Clean everything up. - */ - cpci_hp_stop(); - cpci_hp_unregister_controller(controller); -} diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 9acd1997c6fe..fea0b8b33589 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c @@ -25,7 +25,7 @@ * */ -#include <linux/module.h> +#include <linux/module.h> /* try_module_get & module_put */ #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/types.h> @@ -537,17 +537,11 @@ static int __init pci_hotplug_init(void) info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); return result; } +device_initcall(pci_hotplug_init); -static void __exit pci_hotplug_exit(void) -{ - cpci_hotplug_exit(); -} - -module_init(pci_hotplug_init); -module_exit(pci_hotplug_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); +/* + * not really modular, but the easiest way to keep compat with existing + * bootargs behaviour is to continue using module_param here. + */ module_param(debug, bool, 0644); MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index ac531e674a05..fb0f86335158 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -27,7 +27,6 @@ * */ -#include <linux/module.h> #include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/slab.h> @@ -47,10 +46,10 @@ static bool pciehp_force; #define DRIVER_AUTHOR "Dan Zink <dan.zink@compaq.com>, Greg Kroah-Hartman <greg@kroah.com>, Dely Sy <dely.l.sy@intel.com>" #define DRIVER_DESC "PCI Express Hot Plug Controller Driver" -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - +/* + * not really modular, but the easiest way to keep compat with existing + * bootargs behaviour is to continue using module_param here. + */ module_param(pciehp_debug, bool, 0644); module_param(pciehp_poll_mode, bool, 0644); module_param(pciehp_poll_time, int, 0644); @@ -337,13 +336,4 @@ static int __init pcied_init(void) return retval; } - -static void __exit pcied_cleanup(void) -{ - dbg("unload_pciehpd()\n"); - pcie_port_service_unregister(&hpdriver_portdrv); - info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); -} - -module_init(pcied_init); -module_exit(pcied_cleanup); +device_initcall(pcied_init); diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 9730c474b016..194521bfb1a3 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -332,6 +332,12 @@ static inline resource_size_t pci_resource_alignment(struct pci_dev *dev, void pci_enable_acs(struct pci_dev *dev); +#ifdef CONFIG_PCIE_PTM +void pci_ptm_init(struct pci_dev *dev); +#else +static inline void pci_ptm_init(struct pci_dev *dev) { } +#endif + struct pci_dev_reset_methods { u16 vendor; u16 device; diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 7fcea75afa4c..7ce77635e5ad 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig @@ -92,3 +92,14 @@ config PCIE_DPC will be handled by the DPC driver. If your system doesn't have this capability or you do not want to use this feature, it is safe to answer N. + +config PCIE_PTM + bool "PCIe Precision Time Measurement support" + default n + depends on PCIEPORTBUS + help + This enables PCI Express Precision Time Measurement (PTM) + support. + + This is only useful if you have devices that support PTM, but it + is safe to enable even if you don't. diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile index b24525b3dec1..36e35ea8fde7 100644 --- a/drivers/pci/pcie/Makefile +++ b/drivers/pci/pcie/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_PCIEAER) += aer/ obj-$(CONFIG_PCIE_PME) += pme.o obj-$(CONFIG_PCIE_DPC) += pcie-dpc.o +obj-$(CONFIG_PCIE_PTM) += ptm.o diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index b2992e60eeeb..139150b2bdfd 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c @@ -15,7 +15,6 @@ * */ -#include <linux/module.h> #include <linux/pci.h> #include <linux/pci-acpi.h> #include <linux/sched.h> @@ -37,9 +36,6 @@ #define DRIVER_VERSION "v1.0" #define DRIVER_AUTHOR "tom.l.nguyen@intel.com" #define DRIVER_DESC "Root Port Advanced Error Reporting Driver" -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); static int aer_probe(struct pcie_device *dev); static void aer_remove(struct pcie_device *dev); @@ -411,16 +407,4 @@ static int __init aer_service_init(void) return -ENXIO; return pcie_port_service_register(&aerdriver); } - -/** - * aer_service_exit - unregister AER root service driver - * - * Invoked when AER root service driver is unloaded. - */ -static void __exit aer_service_exit(void) -{ - pcie_port_service_unregister(&aerdriver); -} - -module_init(aer_service_init); -module_exit(aer_service_exit); +device_initcall(aer_service_init); diff --git a/drivers/pci/pcie/pcie-dpc.c b/drivers/pci/pcie/pcie-dpc.c index 250f87861786..9811b14d9ad8 100644 --- a/drivers/pci/pcie/pcie-dpc.c +++ b/drivers/pci/pcie/pcie-dpc.c @@ -1,5 +1,7 @@ /* * PCI Express Downstream Port Containment services driver + * Author: Keith Busch <keith.busch@intel.com> + * * Copyright (C) 2016 Intel Corp. * * This file is subject to the terms and conditions of the GNU General Public @@ -9,7 +11,7 @@ #include <linux/delay.h> #include <linux/interrupt.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/pci.h> #include <linux/pcieport_if.h> @@ -143,16 +145,4 @@ static int __init dpc_service_init(void) { return pcie_port_service_register(&dpcdriver); } - -static void __exit dpc_service_exit(void) -{ - pcie_port_service_unregister(&dpcdriver); -} - -MODULE_DESCRIPTION("PCI Express Downstream Port Containment driver"); -MODULE_AUTHOR("Keith Busch <keith.busch@intel.com>"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("0.1"); - -module_init(dpc_service_init); -module_exit(dpc_service_exit); +device_initcall(dpc_service_init); diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 1ae4c73e7a3c..884bad5320f8 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -10,7 +10,6 @@ * for more details. */ -#include <linux/module.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -449,17 +448,6 @@ static int pcie_pme_resume(struct pcie_device *srv) return 0; } -/** - * pcie_pme_remove - Prepare PCIe PME service device for removal. - * @srv - PCIe service device to remove. - */ -static void pcie_pme_remove(struct pcie_device *srv) -{ - pcie_pme_suspend(srv); - free_irq(srv->irq, srv); - kfree(get_service_data(srv)); -} - static struct pcie_port_service_driver pcie_pme_driver = { .name = "pcie_pme", .port_type = PCI_EXP_TYPE_ROOT_PORT, @@ -468,7 +456,6 @@ static struct pcie_port_service_driver pcie_pme_driver = { .probe = pcie_pme_probe, .suspend = pcie_pme_suspend, .resume = pcie_pme_resume, - .remove = pcie_pme_remove, }; /** @@ -478,5 +465,4 @@ static int __init pcie_pme_service_init(void) { return pcie_port_service_register(&pcie_pme_driver); } - -module_init(pcie_pme_service_init); +device_initcall(pcie_pme_service_init); diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 70d7ad8c6d17..79327cc14e7d 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -1,12 +1,13 @@ /* * File: portdrv_pci.c * Purpose: PCI Express Port Bus Driver + * Author: Tom Nguyen <tom.l.nguyen@intel.com> + * Version: v1.0 * * Copyright (C) 2004 Intel * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) */ -#include <linux/module.h> #include <linux/pci.h> #include <linux/kernel.h> #include <linux/errno.h> @@ -21,16 +22,6 @@ #include "portdrv.h" #include "aer/aerdrv.h" -/* - * Version Information - */ -#define DRIVER_VERSION "v1.0" -#define DRIVER_AUTHOR "tom.l.nguyen@intel.com" -#define DRIVER_DESC "PCIe Port Bus Driver" -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - /* If this switch is set, PCIe port native services should not be enabled. */ bool pcie_ports_disabled; @@ -341,7 +332,6 @@ static const struct pci_device_id port_pci_ids[] = { { PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0), }, { /* end: all zeroes */ } }; -MODULE_DEVICE_TABLE(pci, port_pci_ids); static const struct pci_error_handlers pcie_portdrv_err_handler = { .error_detected = pcie_portdrv_error_detected, @@ -406,5 +396,4 @@ static int __init pcie_portdrv_init(void) out: return retval; } - -module_init(pcie_portdrv_init); +device_initcall(pcie_portdrv_init); diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c new file mode 100644 index 000000000000..bab8ac63c4f3 --- /dev/null +++ b/drivers/pci/pcie/ptm.c @@ -0,0 +1,142 @@ +/* + * PCI Express Precision Time Measurement + * Copyright (c) 2016, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/pci.h> +#include "../pci.h" + +static void pci_ptm_info(struct pci_dev *dev) +{ + char clock_desc[8]; + + switch (dev->ptm_granularity) { + case 0: + snprintf(clock_desc, sizeof(clock_desc), "unknown"); + break; + case 255: + snprintf(clock_desc, sizeof(clock_desc), ">254ns"); + break; + default: + snprintf(clock_desc, sizeof(clock_desc), "%udns", + dev->ptm_granularity); + break; + } + dev_info(&dev->dev, "PTM enabled%s, %s granularity\n", + dev->ptm_root ? " (root)" : "", clock_desc); +} + +void pci_ptm_init(struct pci_dev *dev) +{ + int pos; + u32 cap, ctrl; + u8 local_clock; + struct pci_dev *ups; + + if (!pci_is_pcie(dev)) + return; + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); + if (!pos) + return; + + /* + * Enable PTM only on interior devices (root ports, switch ports, + * etc.) on the assumption that it causes no link traffic until an + * endpoint enables it. + */ + if ((pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT || + pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)) + return; + + pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap); + local_clock = (cap & PCI_PTM_GRANULARITY_MASK) >> 8; + + /* + * There's no point in enabling PTM unless it's enabled in the + * upstream device or this device can be a PTM Root itself. Per + * the spec recommendation (PCIe r3.1, sec 7.32.3), select the + * furthest upstream Time Source as the PTM Root. + */ + ups = pci_upstream_bridge(dev); + if (ups && ups->ptm_enabled) { + ctrl = PCI_PTM_CTRL_ENABLE; + if (ups->ptm_granularity == 0) + dev->ptm_granularity = 0; + else if (ups->ptm_granularity > local_clock) + dev->ptm_granularity = ups->ptm_granularity; + } else { + if (cap & PCI_PTM_CAP_ROOT) { + ctrl = PCI_PTM_CTRL_ENABLE | PCI_PTM_CTRL_ROOT; + dev->ptm_root = 1; + dev->ptm_granularity = local_clock; + } else + return; + } + + ctrl |= dev->ptm_granularity << 8; + pci_write_config_dword(dev, pos + PCI_PTM_CTRL, ctrl); + dev->ptm_enabled = 1; + + pci_ptm_info(dev); +} + +int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) +{ + int pos; + u32 cap, ctrl; + struct pci_dev *ups; + + if (!pci_is_pcie(dev)) + return -EINVAL; + + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_PTM); + if (!pos) + return -EINVAL; + + pci_read_config_dword(dev, pos + PCI_PTM_CAP, &cap); + if (!(cap & PCI_PTM_CAP_REQ)) + return -EINVAL; + + /* + * For a PCIe Endpoint, PTM is only useful if the endpoint can + * issue PTM requests to upstream devices that have PTM enabled. + * + * For Root Complex Integrated Endpoints, there is no upstream + * device, so there must be some implementation-specific way to + * associate the endpoint with a time source. + */ + if (pci_pcie_type(dev) == PCI_EXP_TYPE_ENDPOINT) { + ups = pci_upstream_bridge(dev); + if (!ups || !ups->ptm_enabled) + return -EINVAL; + + dev->ptm_granularity = ups->ptm_granularity; + } else if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) { + dev->ptm_granularity = 0; + } else + return -EINVAL; + + ctrl = PCI_PTM_CTRL_ENABLE; + ctrl |= dev->ptm_granularity << 8; + pci_write_config_dword(dev, pos + PCI_PTM_CTRL, ctrl); + dev->ptm_enabled = 1; + + pci_ptm_info(dev); + + if (granularity) + *granularity = dev->ptm_granularity; + return 0; +} +EXPORT_SYMBOL(pci_enable_ptm); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 157572420513..ab002671fa60 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1666,6 +1666,9 @@ static void pci_init_capabilities(struct pci_dev *dev) /* Enable ACS P2P upstream forwarding */ pci_enable_acs(dev); + /* Precision Time Measurement */ + pci_ptm_init(dev); + /* Advanced Error Reporting */ pci_aer_init(dev); } diff --git a/include/linux/pci.h b/include/linux/pci.h index ab6b02763916..84d222ad3c08 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -371,6 +371,12 @@ struct pci_dev { int rom_attr_enabled; /* has display of the rom attribute been enabled? */ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */ + +#ifdef CONFIG_PCIE_PTM + unsigned int ptm_root:1; + unsigned int ptm_enabled:1; + u8 ptm_granularity; +#endif #ifdef CONFIG_PCI_MSI const struct attribute_group **msi_irq_groups; #endif @@ -1408,6 +1414,13 @@ static inline void pci_disable_ats(struct pci_dev *d) { } static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; } #endif +#ifdef CONFIG_PCIE_PTM +int pci_enable_ptm(struct pci_dev *dev, u8 *granularity); +#else +static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) +{ return -EINVAL; } +#endif + void pci_cfg_access_lock(struct pci_dev *dev); bool pci_cfg_access_trylock(struct pci_dev *dev); void pci_cfg_access_unlock(struct pci_dev *dev); diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 404095124ae2..d812172d1d7b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -671,7 +671,8 @@ #define PCI_EXT_CAP_ID_PMUX 0x1A /* Protocol Multiplexing */ #define PCI_EXT_CAP_ID_PASID 0x1B /* Process Address Space ID */ #define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */ -#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DPC +#define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PTM #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 @@ -964,4 +965,13 @@ #define PCI_EXP_DPC_SOURCE_ID 10 /* DPC Source Identifier */ +/* Precision Time Measurement */ +#define PCI_PTM_CAP 0x04 /* PTM Capability */ +#define PCI_PTM_CAP_REQ 0x00000001 /* Requester capable */ +#define PCI_PTM_CAP_ROOT 0x00000004 /* Root capable */ +#define PCI_PTM_GRANULARITY_MASK 0x0000FF00 /* Clock granularity */ +#define PCI_PTM_CTRL 0x08 /* PTM Control */ +#define PCI_PTM_CTRL_ENABLE 0x00000001 /* PTM enable */ +#define PCI_PTM_CTRL_ROOT 0x00000002 /* Root select */ + #endif /* LINUX_PCI_REGS_H */ |