linux/drivers/pci/pcie/portdrv_pci.c
<<
>>
Prefs
   1/*
   2 * File:        portdrv_pci.c
   3 * Purpose:     PCI Express Port Bus Driver
   4 *
   5 * Copyright (C) 2004 Intel
   6 * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/pci.h>
  11#include <linux/kernel.h>
  12#include <linux/errno.h>
  13#include <linux/pm.h>
  14#include <linux/pm_runtime.h>
  15#include <linux/init.h>
  16#include <linux/pcieport_if.h>
  17#include <linux/aer.h>
  18#include <linux/dmi.h>
  19#include <linux/pci-aspm.h>
  20
  21#include "portdrv.h"
  22#include "aer/aerdrv.h"
  23
  24/*
  25 * Version Information
  26 */
  27#define DRIVER_VERSION "v1.0"
  28#define DRIVER_AUTHOR "tom.l.nguyen@intel.com"
  29#define DRIVER_DESC "PCIe Port Bus Driver"
  30MODULE_AUTHOR(DRIVER_AUTHOR);
  31MODULE_DESCRIPTION(DRIVER_DESC);
  32MODULE_LICENSE("GPL");
  33
  34/* If this switch is set, PCIe port native services should not be enabled. */
  35bool pcie_ports_disabled;
  36
  37/*
  38 * If this switch is set, ACPI _OSC will be used to determine whether or not to
  39 * enable PCIe port native services.
  40 */
  41bool pcie_ports_auto = true;
  42
  43static int __init pcie_port_setup(char *str)
  44{
  45        if (!strncmp(str, "compat", 6)) {
  46                pcie_ports_disabled = true;
  47        } else if (!strncmp(str, "native", 6)) {
  48                pcie_ports_disabled = false;
  49                pcie_ports_auto = false;
  50        } else if (!strncmp(str, "auto", 4)) {
  51                pcie_ports_disabled = false;
  52                pcie_ports_auto = true;
  53        }
  54
  55        return 1;
  56}
  57__setup("pcie_ports=", pcie_port_setup);
  58
  59/* global data */
  60
  61/**
  62 * pcie_clear_root_pme_status - Clear root port PME interrupt status.
  63 * @dev: PCIe root port or event collector.
  64 */
  65void pcie_clear_root_pme_status(struct pci_dev *dev)
  66{
  67        pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME);
  68}
  69
  70static int pcie_portdrv_restore_config(struct pci_dev *dev)
  71{
  72        int retval;
  73
  74        retval = pci_enable_device(dev);
  75        if (retval)
  76                return retval;
  77        pci_set_master(dev);
  78        return 0;
  79}
  80
  81#ifdef CONFIG_PM
  82static int pcie_port_resume_noirq(struct device *dev)
  83{
  84        struct pci_dev *pdev = to_pci_dev(dev);
  85
  86        /*
  87         * Some BIOSes forget to clear Root PME Status bits after system wakeup
  88         * which breaks ACPI-based runtime wakeup on PCI Express, so clear those
  89         * bits now just in case (shouldn't hurt).
  90         */
  91        if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT)
  92                pcie_clear_root_pme_status(pdev);
  93        return 0;
  94}
  95
  96#ifdef CONFIG_PM_RUNTIME
  97struct d3cold_info {
  98        bool no_d3cold;
  99        unsigned int d3cold_delay;
 100};
 101
 102static int pci_dev_d3cold_info(struct pci_dev *pdev, void *data)
 103{
 104        struct d3cold_info *info = data;
 105
 106        info->d3cold_delay = max_t(unsigned int, pdev->d3cold_delay,
 107                                   info->d3cold_delay);
 108        if (pdev->no_d3cold)
 109                info->no_d3cold = true;
 110        return 0;
 111}
 112
 113static int pcie_port_runtime_suspend(struct device *dev)
 114{
 115        struct pci_dev *pdev = to_pci_dev(dev);
 116        struct d3cold_info d3cold_info = {
 117                .no_d3cold      = false,
 118                .d3cold_delay   = PCI_PM_D3_WAIT,
 119        };
 120
 121        /*
 122         * If any subordinate device disable D3cold, we should not put
 123         * the port into D3cold.  The D3cold delay of port should be
 124         * the max of that of all subordinate devices.
 125         */
 126        pci_walk_bus(pdev->subordinate, pci_dev_d3cold_info, &d3cold_info);
 127        pdev->no_d3cold = d3cold_info.no_d3cold;
 128        pdev->d3cold_delay = d3cold_info.d3cold_delay;
 129        return 0;
 130}
 131
 132static int pcie_port_runtime_resume(struct device *dev)
 133{
 134        return 0;
 135}
 136
 137static int pci_dev_pme_poll(struct pci_dev *pdev, void *data)
 138{
 139        bool *pme_poll = data;
 140
 141        if (pdev->pme_poll)
 142                *pme_poll = true;
 143        return 0;
 144}
 145
 146static int pcie_port_runtime_idle(struct device *dev)
 147{
 148        struct pci_dev *pdev = to_pci_dev(dev);
 149        bool pme_poll = false;
 150
 151        /*
 152         * If any subordinate device needs pme poll, we should keep
 153         * the port in D0, because we need port in D0 to poll it.
 154         */
 155        pci_walk_bus(pdev->subordinate, pci_dev_pme_poll, &pme_poll);
 156        /* Delay for a short while to prevent too frequent suspend/resume */
 157        if (!pme_poll)
 158                pm_schedule_suspend(dev, 10);
 159        return -EBUSY;
 160}
 161#else
 162#define pcie_port_runtime_suspend       NULL
 163#define pcie_port_runtime_resume        NULL
 164#define pcie_port_runtime_idle          NULL
 165#endif
 166
 167static const struct dev_pm_ops pcie_portdrv_pm_ops = {
 168        .suspend        = pcie_port_device_suspend,
 169        .resume         = pcie_port_device_resume,
 170        .freeze         = pcie_port_device_suspend,
 171        .thaw           = pcie_port_device_resume,
 172        .poweroff       = pcie_port_device_suspend,
 173        .restore        = pcie_port_device_resume,
 174        .resume_noirq   = pcie_port_resume_noirq,
 175        .runtime_suspend = pcie_port_runtime_suspend,
 176        .runtime_resume = pcie_port_runtime_resume,
 177        .runtime_idle   = pcie_port_runtime_idle,
 178};
 179
 180#define PCIE_PORTDRV_PM_OPS     (&pcie_portdrv_pm_ops)
 181
 182#else /* !PM */
 183
 184#define PCIE_PORTDRV_PM_OPS     NULL
 185#endif /* !PM */
 186
 187/*
 188 * pcie_portdrv_probe - Probe PCI-Express port devices
 189 * @dev: PCI-Express port device being probed
 190 *
 191 * If detected invokes the pcie_port_device_register() method for
 192 * this port device.
 193 *
 194 */
 195static int pcie_portdrv_probe(struct pci_dev *dev,
 196                                        const struct pci_device_id *id)
 197{
 198        int status;
 199
 200        if (!pci_is_pcie(dev) ||
 201            ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) &&
 202             (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) &&
 203             (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM)))
 204                return -ENODEV;
 205
 206        status = pcie_port_device_register(dev);
 207        if (status)
 208                return status;
 209
 210        pci_save_state(dev);
 211        /*
 212         * D3cold may not work properly on some PCIe port, so disable
 213         * it by default.
 214         */
 215        dev->d3cold_allowed = false;
 216        return 0;
 217}
 218
 219static void pcie_portdrv_remove(struct pci_dev *dev)
 220{
 221        pcie_port_device_remove(dev);
 222}
 223
 224static int error_detected_iter(struct device *device, void *data)
 225{
 226        struct pcie_device *pcie_device;
 227        struct pcie_port_service_driver *driver;
 228        struct aer_broadcast_data *result_data;
 229        pci_ers_result_t status;
 230
 231        result_data = (struct aer_broadcast_data *) data;
 232
 233        if (device->bus == &pcie_port_bus_type && device->driver) {
 234                driver = to_service_driver(device->driver);
 235                if (!driver ||
 236                        !driver->err_handler ||
 237                        !driver->err_handler->error_detected)
 238                        return 0;
 239
 240                pcie_device = to_pcie_device(device);
 241
 242                /* Forward error detected message to service drivers */
 243                status = driver->err_handler->error_detected(
 244                        pcie_device->port,
 245                        result_data->state);
 246                result_data->result =
 247                        merge_result(result_data->result, status);
 248        }
 249
 250        return 0;
 251}
 252
 253static pci_ers_result_t pcie_portdrv_error_detected(struct pci_dev *dev,
 254                                        enum pci_channel_state error)
 255{
 256        struct aer_broadcast_data data = {error, PCI_ERS_RESULT_CAN_RECOVER};
 257
 258        /* get true return value from &data */
 259        device_for_each_child(&dev->dev, &data, error_detected_iter);
 260        return data.result;
 261}
 262
 263static int mmio_enabled_iter(struct device *device, void *data)
 264{
 265        struct pcie_device *pcie_device;
 266        struct pcie_port_service_driver *driver;
 267        pci_ers_result_t status, *result;
 268
 269        result = (pci_ers_result_t *) data;
 270
 271        if (device->bus == &pcie_port_bus_type && device->driver) {
 272                driver = to_service_driver(device->driver);
 273                if (driver &&
 274                        driver->err_handler &&
 275                        driver->err_handler->mmio_enabled) {
 276                        pcie_device = to_pcie_device(device);
 277
 278                        /* Forward error message to service drivers */
 279                        status = driver->err_handler->mmio_enabled(
 280                                        pcie_device->port);
 281                        *result = merge_result(*result, status);
 282                }
 283        }
 284
 285        return 0;
 286}
 287
 288static pci_ers_result_t pcie_portdrv_mmio_enabled(struct pci_dev *dev)
 289{
 290        pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
 291
 292        /* get true return value from &status */
 293        device_for_each_child(&dev->dev, &status, mmio_enabled_iter);
 294        return status;
 295}
 296
 297static int slot_reset_iter(struct device *device, void *data)
 298{
 299        struct pcie_device *pcie_device;
 300        struct pcie_port_service_driver *driver;
 301        pci_ers_result_t status, *result;
 302
 303        result = (pci_ers_result_t *) data;
 304
 305        if (device->bus == &pcie_port_bus_type && device->driver) {
 306                driver = to_service_driver(device->driver);
 307                if (driver &&
 308                        driver->err_handler &&
 309                        driver->err_handler->slot_reset) {
 310                        pcie_device = to_pcie_device(device);
 311
 312                        /* Forward error message to service drivers */
 313                        status = driver->err_handler->slot_reset(
 314                                        pcie_device->port);
 315                        *result = merge_result(*result, status);
 316                }
 317        }
 318
 319        return 0;
 320}
 321
 322static pci_ers_result_t pcie_portdrv_slot_reset(struct pci_dev *dev)
 323{
 324        pci_ers_result_t status = PCI_ERS_RESULT_RECOVERED;
 325
 326        /* If fatal, restore cfg space for possible link reset at upstream */
 327        if (dev->error_state == pci_channel_io_frozen) {
 328                dev->state_saved = true;
 329                pci_restore_state(dev);
 330                pcie_portdrv_restore_config(dev);
 331                pci_enable_pcie_error_reporting(dev);
 332        }
 333
 334        /* get true return value from &status */
 335        device_for_each_child(&dev->dev, &status, slot_reset_iter);
 336        return status;
 337}
 338
 339static int resume_iter(struct device *device, void *data)
 340{
 341        struct pcie_device *pcie_device;
 342        struct pcie_port_service_driver *driver;
 343
 344        if (device->bus == &pcie_port_bus_type && device->driver) {
 345                driver = to_service_driver(device->driver);
 346                if (driver &&
 347                        driver->err_handler &&
 348                        driver->err_handler->resume) {
 349                        pcie_device = to_pcie_device(device);
 350
 351                        /* Forward error message to service drivers */
 352                        driver->err_handler->resume(pcie_device->port);
 353                }
 354        }
 355
 356        return 0;
 357}
 358
 359static void pcie_portdrv_err_resume(struct pci_dev *dev)
 360{
 361        device_for_each_child(&dev->dev, NULL, resume_iter);
 362}
 363
 364/*
 365 * LINUX Device Driver Model
 366 */
 367static const struct pci_device_id port_pci_ids[] = { {
 368        /* handle any PCI-Express port */
 369        PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
 370        }, { /* end: all zeroes */ }
 371};
 372MODULE_DEVICE_TABLE(pci, port_pci_ids);
 373
 374static const struct pci_error_handlers pcie_portdrv_err_handler = {
 375        .error_detected = pcie_portdrv_error_detected,
 376        .mmio_enabled = pcie_portdrv_mmio_enabled,
 377        .slot_reset = pcie_portdrv_slot_reset,
 378        .resume = pcie_portdrv_err_resume,
 379};
 380
 381static struct pci_driver pcie_portdriver = {
 382        .name           = "pcieport",
 383        .id_table       = &port_pci_ids[0],
 384
 385        .probe          = pcie_portdrv_probe,
 386        .remove         = pcie_portdrv_remove,
 387
 388        .err_handler    = &pcie_portdrv_err_handler,
 389
 390        .driver.pm      = PCIE_PORTDRV_PM_OPS,
 391};
 392
 393static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d)
 394{
 395        pr_notice("%s detected: will not use MSI for PCIe PME signaling\n",
 396                  d->ident);
 397        pcie_pme_disable_msi();
 398        return 0;
 399}
 400
 401static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = {
 402        /*
 403         * Boxes that should not use MSI for PCIe PME signaling.
 404         */
 405        {
 406         .callback = dmi_pcie_pme_disable_msi,
 407         .ident = "MSI Wind U-100",
 408         .matches = {
 409                     DMI_MATCH(DMI_SYS_VENDOR,
 410                                "MICRO-STAR INTERNATIONAL CO., LTD"),
 411                     DMI_MATCH(DMI_PRODUCT_NAME, "U-100"),
 412                     },
 413         },
 414         {}
 415};
 416
 417static int __init pcie_portdrv_init(void)
 418{
 419        int retval;
 420
 421        if (pcie_ports_disabled)
 422                return pci_register_driver(&pcie_portdriver);
 423
 424        dmi_check_system(pcie_portdrv_dmi_table);
 425
 426        retval = pcie_port_bus_register();
 427        if (retval) {
 428                printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval);
 429                goto out;
 430        }
 431        retval = pci_register_driver(&pcie_portdriver);
 432        if (retval)
 433                pcie_port_bus_unregister();
 434 out:
 435        return retval;
 436}
 437
 438module_init(pcie_portdrv_init);
 439