Merge branch 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jan 2011 17:29:05 +0000 (09:29 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Jan 2011 17:29:05 +0000 (09:29 -0800)
* 'linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6:
  PCI/PM: Report wakeup events before resuming devices
  PCI/PM: Use pm_wakeup_event() directly for reporting wakeup events
  PCI: sysfs: Update ROM to include default owner write access
  x86/PCI: make Broadcom CNB20LE driver EMBEDDED and EXPERIMENTAL
  x86/PCI: don't use native Broadcom CNB20LE driver when ACPI is available
  PCI/ACPI: Request _OSC control once for each root bridge (v3)
  PCI: enable pci=bfsort by default on future Dell systems
  PCI/PCIe: Clear Root PME Status bits early during system resume
  PCI: pci-stub: ignore zero-length id parameters
  x86/PCI: irq and pci_ids patch for Intel Patsburg
  PCI: Skip id checking if no id is passed
  PCI: fix __pci_device_probe kernel-doc warning
  PCI: make pci_restore_state return void
  PCI: Disable ASPM if BIOS asks us to
  PCI: Add mask bit definition for MSI-X table
  PCI: MSI: Move MSI-X entry definition to pci_regs.h

Fix up trivial conflicts in drivers/net/{skge.c,sky2.c} that had in the
meantime been converted to not use legacy PCI power management, and thus
no longer use pci_restore_state() at all (and that caused trivial
conflicts with the "make pci_restore_state return void" patch)

36 files changed:
arch/x86/Kconfig
arch/x86/pci/broadcom_bus.c
arch/x86/pci/common.c
arch/x86/pci/irq.c
drivers/acpi/apei/hest.c
drivers/acpi/pci_root.c
drivers/media/video/cafe_ccic.c
drivers/net/myri10ge/myri10ge.c
drivers/net/sfc/falcon.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/pci/msi.c
drivers/pci/msi.h
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci-stub.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aer/aerdrv.c
drivers/pci/pcie/aer/aerdrv.h
drivers/pci/pcie/aspm.c
drivers/pci/pcie/pme.c
drivers/pci/pcie/portdrv.h
drivers/pci/pcie/portdrv_acpi.c
drivers/pci/pcie/portdrv_core.c
drivers/pci/pcie/portdrv_pci.c
drivers/scsi/ipr.c
drivers/scsi/pmcraid.c
drivers/staging/sm7xx/smtcfb.c
include/acpi/apei.h
include/linux/pci-acpi.h
include/linux/pci-aspm.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pci_regs.h
sound/pci/cs5535audio/cs5535audio_pm.c

index 50aa81f..47ae4a7 100644 (file)
@@ -1934,13 +1934,19 @@ config PCI_MMCONFIG
        depends on X86_64 && PCI && ACPI
 
 config PCI_CNB20LE_QUIRK
-       bool "Read CNB20LE Host Bridge Windows"
-       depends on PCI
+       bool "Read CNB20LE Host Bridge Windows" if EMBEDDED
+       default n
+       depends on PCI && EXPERIMENTAL
        help
          Read the PCI windows out of the CNB20LE host bridge. This allows
          PCI hotplug to work on systems with the CNB20LE chipset which do
          not have ACPI.
 
+         There's no public spec for this chipset, and this functionality
+         is known to be incomplete.
+
+         You should say N unless you know you need this.
+
 config DMAR
        bool "Support for DMA Remapping Devices (EXPERIMENTAL)"
        depends on PCI_MSI && ACPI && EXPERIMENTAL
index 0846a5b..ab8269b 100644 (file)
@@ -9,6 +9,7 @@
  * option) any later version.
  */
 
+#include <linux/acpi.h>
 #include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/pci.h>
@@ -25,12 +26,14 @@ static void __devinit cnb20le_res(struct pci_dev *dev)
        u8 fbus, lbus;
        int i;
 
+#ifdef CONFIG_ACPI
        /*
-        * The x86_pci_root_bus_res_quirks() function already refuses to use
-        * this information if ACPI _CRS was used. Therefore, we don't bother
-        * checking if ACPI is enabled, and just generate the information
-        * for both the ACPI _CRS and no ACPI cases.
+        * We should get host bridge information from ACPI unless the BIOS
+        * doesn't support it.
         */
+       if (acpi_os_get_root_pointer())
+               return;
+#endif
 
        info = &pci_root_info[pci_root_num];
        pci_root_num++;
index f7c8a39..5fe7502 100644 (file)
@@ -22,6 +22,7 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
 
 unsigned int pci_early_dump_regs;
 static int pci_bf_sort;
+static int smbios_type_b1_flag;
 int pci_routeirq;
 int noioapicquirk;
 #ifdef CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS
@@ -185,6 +186,39 @@ static int __devinit set_bf_sort(const struct dmi_system_id *d)
        return 0;
 }
 
+static void __devinit read_dmi_type_b1(const struct dmi_header *dm,
+                                      void *private_data)
+{
+       u8 *d = (u8 *)dm + 4;
+
+       if (dm->type != 0xB1)
+               return;
+       switch (((*(u32 *)d) >> 9) & 0x03) {
+       case 0x00:
+               printk(KERN_INFO "dmi type 0xB1 record - unknown flag\n");
+               break;
+       case 0x01: /* set pci=bfsort */
+               smbios_type_b1_flag = 1;
+               break;
+       case 0x02: /* do not set pci=bfsort */
+               smbios_type_b1_flag = 2;
+               break;
+       default:
+               break;
+       }
+}
+
+static int __devinit find_sort_method(const struct dmi_system_id *d)
+{
+       dmi_walk(read_dmi_type_b1, NULL);
+
+       if (smbios_type_b1_flag == 1) {
+               set_bf_sort(d);
+               return 0;
+       }
+       return -1;
+}
+
 /*
  * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus)
  */
@@ -212,6 +246,13 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = {
                },
        },
 #endif         /* __i386__ */
+       {
+               .callback = find_sort_method,
+               .ident = "Dell System",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+               },
+       },
        {
                .callback = set_bf_sort,
                .ident = "Dell PowerEdge 1950",
index 9f9bfb7..87e6c83 100644 (file)
@@ -589,7 +589,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
        case PCI_DEVICE_ID_INTEL_ICH10_1:
        case PCI_DEVICE_ID_INTEL_ICH10_2:
        case PCI_DEVICE_ID_INTEL_ICH10_3:
-       case PCI_DEVICE_ID_INTEL_PATSBURG_LPC:
+       case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0:
+       case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1:
                r->name = "PIIX/ICH";
                r->get = pirq_piix_get;
                r->set = pirq_piix_set;
index daa7bc6..4ee58e7 100644 (file)
@@ -195,24 +195,24 @@ static int __init setup_hest_disable(char *str)
 
 __setup("hest_disable", setup_hest_disable);
 
-static int __init hest_init(void)
+void __init acpi_hest_init(void)
 {
        acpi_status status;
        int rc = -ENODEV;
        unsigned int ghes_count = 0;
 
        if (acpi_disabled)
-               goto err;
+               return;
 
        if (hest_disable) {
-               pr_info(HEST_PFX "HEST tabling parsing is disabled.\n");
-               goto err;
+               pr_info(HEST_PFX "Table parsing disabled.\n");
+               return;
        }
 
        status = acpi_get_table(ACPI_SIG_HEST, 0,
                                (struct acpi_table_header **)&hest_tab);
        if (status == AE_NOT_FOUND) {
-               pr_info(HEST_PFX "Table is not found!\n");
+               pr_info(HEST_PFX "Table not found.\n");
                goto err;
        } else if (ACPI_FAILURE(status)) {
                const char *msg = acpi_format_exception(status);
@@ -226,15 +226,11 @@ static int __init hest_init(void)
                goto err;
 
        rc = hest_ghes_dev_register(ghes_count);
-       if (rc)
-               goto err;
-
-       pr_info(HEST_PFX "HEST table parsing is initialized.\n");
+       if (!rc) {
+               pr_info(HEST_PFX "Table parsing has been initialized.\n");
+               return;
+       }
 
-       return 0;
 err:
        hest_disable = 1;
-       return rc;
 }
-
-subsys_initcall(hest_init);
index 96668ad..d976679 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+#include <acpi/apei.h>
 
 #define PREFIX "ACPI: "
 
@@ -47,6 +48,11 @@ static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
+#define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \
+                               | OSC_ACTIVE_STATE_PWR_SUPPORT \
+                               | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \
+                               | OSC_MSI_SUPPORT)
+
 static const struct acpi_device_id root_device_ids[] = {
        {"PNP0A03", 0},
        {"", 0},
@@ -566,6 +572,33 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        if (flags != base_flags)
                acpi_pci_osc_support(root, flags);
 
+       if (!pcie_ports_disabled
+           && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
+               flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
+                       | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
+                       | OSC_PCI_EXPRESS_PME_CONTROL;
+
+               if (pci_aer_available()) {
+                       if (aer_acpi_firmware_first())
+                               dev_dbg(root->bus->bridge,
+                                       "PCIe errors handled by BIOS.\n");
+                       else
+                               flags |= OSC_PCI_EXPRESS_AER_CONTROL;
+               }
+
+               dev_info(root->bus->bridge,
+                       "Requesting ACPI _OSC control (0x%02x)\n", flags);
+
+               status = acpi_pci_osc_control_set(device->handle, &flags,
+                                       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+               if (ACPI_SUCCESS(status))
+                       dev_info(root->bus->bridge,
+                               "ACPI _OSC control (0x%02x) granted\n", flags);
+               else
+                       dev_dbg(root->bus->bridge,
+                               "ACPI _OSC request failed (code %d)\n", status);
+       }
+
        pci_acpi_add_bus_pm_notifier(device, root->bus);
        if (device->wakeup.flags.run_wake)
                device_set_run_wake(root->bus->bridge, true);
@@ -603,6 +636,8 @@ static int __init acpi_pci_root_init(void)
        if (acpi_pci_disabled)
                return 0;
 
+       acpi_hest_init();
+
        pci_acpi_crs_quirks();
        if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0)
                return -ENODEV;
index 789087c..49f1b8f 100644 (file)
@@ -2184,9 +2184,7 @@ static int cafe_pci_resume(struct pci_dev *pdev)
        struct cafe_camera *cam = to_cam(v4l2_dev);
        int ret = 0;
 
-       ret = pci_restore_state(pdev);
-       if (ret)
-               return ret;
+       pci_restore_state(pdev);
        ret = pci_enable_device(pdev);
 
        if (ret) {
index a37fcf1..ea5cfe2 100644 (file)
@@ -3403,9 +3403,7 @@ static int myri10ge_resume(struct pci_dev *pdev)
                return -EIO;
        }
 
-       status = pci_restore_state(pdev);
-       if (status)
-               return status;
+       pci_restore_state(pdev);
 
        status = pci_enable_device(pdev);
        if (status) {
index 70e4f7d..61ddd2c 100644 (file)
@@ -1107,22 +1107,9 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
 
        /* Restore PCI configuration if needed */
        if (method == RESET_TYPE_WORLD) {
-               if (efx_nic_is_dual_func(efx)) {
-                       rc = pci_restore_state(nic_data->pci_dev2);
-                       if (rc) {
-                               netif_err(efx, drv, efx->net_dev,
-                                         "failed to restore PCI config for "
-                                         "the secondary function\n");
-                               goto fail3;
-                       }
-               }
-               rc = pci_restore_state(efx->pci_dev);
-               if (rc) {
-                       netif_err(efx, drv, efx->net_dev,
-                                 "failed to restore PCI config for the "
-                                 "primary function\n");
-                       goto fail4;
-               }
+               if (efx_nic_is_dual_func(efx))
+                       pci_restore_state(nic_data->pci_dev2);
+               pci_restore_state(efx->pci_dev);
                netif_dbg(efx, drv, efx->net_dev,
                          "successfully restored PCI config\n");
        }
@@ -1133,7 +1120,7 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
                rc = -ETIMEDOUT;
                netif_err(efx, hw, efx->net_dev,
                          "timed out waiting for hardware reset\n");
-               goto fail5;
+               goto fail3;
        }
        netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n");
 
@@ -1141,11 +1128,9 @@ static int __falcon_reset_hw(struct efx_nic *efx, enum reset_type method)
 
        /* pci_save_state() and pci_restore_state() MUST be called in pairs */
 fail2:
-fail3:
        pci_restore_state(efx->pci_dev);
 fail1:
-fail4:
-fail5:
+fail3:
        return rc;
 }
 
index 73631c6..ace0b66 100644 (file)
@@ -363,12 +363,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev)
        struct rt2x00_dev *rt2x00dev = hw->priv;
 
        if (pci_set_power_state(pci_dev, PCI_D0) ||
-           pci_enable_device(pci_dev) ||
-           pci_restore_state(pci_dev)) {
+           pci_enable_device(pci_dev)) {
                ERROR(rt2x00dev, "Failed to resume device.\n");
                return -EIO;
        }
 
+       pci_restore_state(pci_dev);
        return rt2x00lib_resume(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_resume);
index 7c24dce..44b0aee 100644 (file)
@@ -168,8 +168,9 @@ static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
        u32 mask_bits = desc->masked;
        unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
                                                PCI_MSIX_ENTRY_VECTOR_CTRL;
-       mask_bits &= ~1;
-       mask_bits |= flag;
+       mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
+       if (flag)
+               mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
        writel(mask_bits, desc->mask_base + offset);
 
        return mask_bits;
index feff3be..65c42f8 100644 (file)
@@ -6,12 +6,6 @@
 #ifndef MSI_H
 #define MSI_H
 
-#define PCI_MSIX_ENTRY_SIZE            16
-#define  PCI_MSIX_ENTRY_LOWER_ADDR     0
-#define  PCI_MSIX_ENTRY_UPPER_ADDR     4
-#define  PCI_MSIX_ENTRY_DATA           8
-#define  PCI_MSIX_ENTRY_VECTOR_CTRL    12
-
 #define msi_control_reg(base)          (base + PCI_MSI_FLAGS)
 #define msi_lower_address_reg(base)    (base + PCI_MSI_ADDRESS_LO)
 #define msi_upper_address_reg(base)    (base + PCI_MSI_ADDRESS_HI)
index 24e19c5..6fe0772 100644 (file)
@@ -46,9 +46,9 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
        struct pci_dev *pci_dev = context;
 
        if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_dev) {
+               pci_wakeup_event(pci_dev);
                pci_check_pme_status(pci_dev);
                pm_runtime_resume(&pci_dev->dev);
-               pci_wakeup_event(pci_dev);
                if (pci_dev->subordinate)
                        pci_pme_wakeup_bus(pci_dev->subordinate);
        }
@@ -399,6 +399,7 @@ static int __init acpi_pci_init(void)
 
        if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
                printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
+               pcie_clear_aspm();
                pcie_no_aspm();
        }
 
index 8a6f797..88246dd 100644 (file)
@@ -338,7 +338,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
 }
 
 /**
- * __pci_device_probe()
+ * __pci_device_probe - check if a driver wants to claim a specific PCI device
  * @drv: driver to call to check if it wants the PCI device
  * @pci_dev: PCI device being probed
  * 
@@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev)
                        return error;
        }
 
-       return pci_restore_state(pci_dev);
+       pci_restore_state(pci_dev);
+       return 0;
 }
 
 static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
index f7b68ca..775e933 100644 (file)
@@ -47,6 +47,10 @@ static int __init pci_stub_init(void)
        if (rc)
                return rc;
 
+       /* no ids passed actually */
+       if (ids[0] == '\0')
+               return 0;
+
        /* add ids specified in the module parameter */
        p = ids;
        while ((id = strsep(&p, ","))) {
@@ -54,6 +58,9 @@ static int __init pci_stub_init(void)
                        subdevice = PCI_ANY_ID, class=0, class_mask=0;
                int fields;
 
+               if (!strlen(id))
+                       continue;
+
                fields = sscanf(id, "%x:%x:%x:%x:%x:%x",
                                &vendor, &device, &subvendor, &subdevice,
                                &class, &class_mask);
index 63d5042..8ecaac9 100644 (file)
@@ -1149,7 +1149,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
                sysfs_bin_attr_init(attr);
                attr->size = rom_size;
                attr->attr.name = "rom";
-               attr->attr.mode = S_IRUSR;
+               attr->attr.mode = S_IRUSR | S_IWUSR;
                attr->read = pci_read_rom;
                attr->write = pci_write_rom;
                retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
index 710c8a2..b714d78 100644 (file)
@@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev)
  * pci_restore_state - Restore the saved state of a PCI device
  * @dev: - PCI device that we're dealing with
  */
-int 
-pci_restore_state(struct pci_dev *dev)
+void pci_restore_state(struct pci_dev *dev)
 {
        int i;
        u32 val;
 
        if (!dev->state_saved)
-               return 0;
+               return;
 
        /* PCI Express register must be restored first */
        pci_restore_pcie_state(dev);
@@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev)
        pci_restore_iov_state(dev);
 
        dev->state_saved = false;
-
-       return 0;
 }
 
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
@@ -1300,22 +1297,6 @@ bool pci_check_pme_status(struct pci_dev *dev)
        return ret;
 }
 
-/*
- * Time to wait before the system can be put into a sleep state after reporting
- * a wakeup event signaled by a PCI device.
- */
-#define PCI_WAKEUP_COOLDOWN    100
-
-/**
- * pci_wakeup_event - Report a wakeup event related to a given PCI device.
- * @dev: Device to report the wakeup event for.
- */
-void pci_wakeup_event(struct pci_dev *dev)
-{
-       if (device_may_wakeup(&dev->dev))
-               pm_wakeup_event(&dev->dev, PCI_WAKEUP_COOLDOWN);
-}
-
 /**
  * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set.
  * @dev: Device to handle.
@@ -1327,8 +1308,8 @@ void pci_wakeup_event(struct pci_dev *dev)
 static int pci_pme_wakeup(struct pci_dev *dev, void *ign)
 {
        if (pci_check_pme_status(dev)) {
-               pm_request_resume(&dev->dev);
                pci_wakeup_event(dev);
+               pm_request_resume(&dev->dev);
        }
        return 0;
 }
index 7d33f66..f69d6e0 100644 (file)
@@ -74,6 +74,12 @@ extern void pci_pm_init(struct pci_dev *dev);
 extern void platform_pci_wakeup_init(struct pci_dev *dev);
 extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
 
+static inline void pci_wakeup_event(struct pci_dev *dev)
+{
+       /* Wait 100 ms before the system can be put into a sleep state. */
+       pm_wakeup_event(&dev->dev, 100);
+}
+
 static inline bool pci_is_bridge(struct pci_dev *pci_dev)
 {
        return !!(pci_dev->subordinate);
@@ -140,14 +146,6 @@ static inline void pci_no_msi(void) { }
 static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
 #endif
 
-#ifdef CONFIG_PCIEAER
-void pci_no_aer(void);
-bool pci_aer_available(void);
-#else
-static inline void pci_no_aer(void) { }
-static inline bool pci_aer_available(void) { return false; }
-#endif
-
 static inline int pci_no_d1d2(struct pci_dev *dev)
 {
        unsigned int parent_dstates = 0;
index 2b2b650..58ad791 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pci-acpi.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
index 9656e30..80c11d1 100644 (file)
@@ -132,7 +132,6 @@ static inline int aer_osc_setup(struct pcie_device *pciedev)
 
 #ifdef CONFIG_ACPI_APEI
 extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
-extern bool aer_acpi_firmware_first(void);
 #else
 static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
 {
@@ -140,8 +139,6 @@ static inline int pcie_aer_get_firmware_first(struct pci_dev *pci_dev)
                return pci_dev->__aer_firmware_first;
        return 0;
 }
-
-static inline bool aer_acpi_firmware_first(void) { return false; }
 #endif
 
 static inline void pcie_aer_force_firmware_first(struct pci_dev *pci_dev,
index 7122281..3188cd9 100644 (file)
@@ -68,7 +68,7 @@ struct pcie_link_state {
        struct aspm_latency acceptable[8];
 };
 
-static int aspm_disabled, aspm_force;
+static int aspm_disabled, aspm_force, aspm_clear_state;
 static DEFINE_MUTEX(aspm_lock);
 static LIST_HEAD(link_list);
 
@@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable)
 {
        /* Don't enable Clock PM if the link is not Clock PM capable */
        if (!link->clkpm_capable && enable)
-               return;
+               enable = 0;
        /* Need nothing if the specified equals to current state */
        if (link->clkpm_enabled == enable)
                return;
@@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
        struct pci_dev *child;
        int pos;
        u32 reg32;
+
+       if (aspm_clear_state)
+               return -EINVAL;
+
        /*
         * Some functions in a slot might not all be PCIe functions,
         * very strange. Disable ASPM for the whole slot
@@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
        struct pcie_link_state *link;
        int blacklist = !!pcie_aspm_sanity_check(pdev);
 
-       if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state)
+       if (!pci_is_pcie(pdev) || pdev->link_state)
                return;
        if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
            pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
                return;
 
+       if (aspm_disabled && !aspm_clear_state)
+               return;
+
        /* VIA has a strange chipset, root port is under a bridge */
        if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT &&
            pdev->bus->self)
@@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev)
        struct pci_dev *parent = pdev->bus->self;
        struct pcie_link_state *link, *root, *parent_link;
 
-       if (aspm_disabled || !pci_is_pcie(pdev) ||
+       if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) ||
            !parent || !parent->link_state)
                return;
        if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) &&
@@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str)
 
 __setup("pcie_aspm=", pcie_aspm_disable);
 
+void pcie_clear_aspm(void)
+{
+       if (!aspm_force)
+               aspm_clear_state = 1;
+}
+
 void pcie_no_aspm(void)
 {
        if (!aspm_force)
index 2f3c904..0057344 100644 (file)
@@ -26,9 +26,6 @@
 #include "../pci.h"
 #include "portdrv.h"
 
-#define PCI_EXP_RTSTA_PME      0x10000 /* PME status */
-#define PCI_EXP_RTSTA_PENDING  0x20000 /* PME pending */
-
 /*
  * If this switch is set, MSI will not be used for PCIe PME signaling.  This
  * causes the PCIe port driver to use INTx interrupts only, but it turns out
@@ -73,22 +70,6 @@ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
        pci_write_config_word(dev, rtctl_pos, rtctl);
 }
 
-/**
- * pcie_pme_clear_status - Clear root port PME interrupt status.
- * @dev: PCIe root port or event collector.
- */
-static void pcie_pme_clear_status(struct pci_dev *dev)
-{
-       int rtsta_pos;
-       u32 rtsta;
-
-       rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
-
-       pci_read_config_dword(dev, rtsta_pos, &rtsta);
-       rtsta |= PCI_EXP_RTSTA_PME;
-       pci_write_config_dword(dev, rtsta_pos, rtsta);
-}
-
 /**
  * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#.
  * @bus: PCI bus to scan.
@@ -103,8 +84,8 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus)
        list_for_each_entry(dev, &bus->devices, bus_list) {
                /* Skip PCIe devices in case we started from a root port. */
                if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) {
-                       pm_request_resume(&dev->dev);
                        pci_wakeup_event(dev);
+                       pm_request_resume(&dev->dev);
                        ret = true;
                }
 
@@ -206,8 +187,8 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
                /* The device is there, but we have to check its PME status. */
                found = pci_check_pme_status(dev);
                if (found) {
-                       pm_request_resume(&dev->dev);
                        pci_wakeup_event(dev);
+                       pm_request_resume(&dev->dev);
                }
                pci_dev_put(dev);
        } else if (devfn) {
@@ -253,7 +234,7 @@ static void pcie_pme_work_fn(struct work_struct *work)
                         * Clear PME status of the port.  If there are other
                         * pending PMEs, the status will be set again.
                         */
-                       pcie_pme_clear_status(port);
+                       pcie_clear_root_pme_status(port);
 
                        spin_unlock_irq(&data->lock);
                        pcie_pme_handle_request(port, rtsta & 0xffff);
@@ -378,7 +359,7 @@ static int pcie_pme_probe(struct pcie_device *srv)
 
        port = srv->port;
        pcie_pme_interrupt_enable(port, false);
-       pcie_pme_clear_status(port);
+       pcie_clear_root_pme_status(port);
 
        ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv);
        if (ret) {
@@ -402,7 +383,7 @@ static int pcie_pme_suspend(struct pcie_device *srv)
 
        spin_lock_irq(&data->lock);
        pcie_pme_interrupt_enable(port, false);
-       pcie_pme_clear_status(port);
+       pcie_clear_root_pme_status(port);
        data->noirq = true;
        spin_unlock_irq(&data->lock);
 
@@ -422,7 +403,7 @@ static int pcie_pme_resume(struct pcie_device *srv)
 
        spin_lock_irq(&data->lock);
        data->noirq = false;
-       pcie_pme_clear_status(port);
+       pcie_clear_root_pme_status(port);
        pcie_pme_interrupt_enable(port, true);
        spin_unlock_irq(&data->lock);
 
index 7b5aba0..bd00a01 100644 (file)
@@ -20,9 +20,6 @@
 
 #define get_descriptor_id(type, service) (((type - 4) << 4) | service)
 
-extern bool pcie_ports_disabled;
-extern bool pcie_ports_auto;
-
 extern struct bus_type pcie_port_bus_type;
 extern int pcie_port_device_register(struct pci_dev *dev);
 #ifdef CONFIG_PM
@@ -35,6 +32,8 @@ extern void pcie_port_bus_unregister(void);
 
 struct pci_dev;
 
+extern void pcie_clear_root_pme_status(struct pci_dev *dev);
+
 #ifdef CONFIG_PCIE_PME
 extern bool pcie_pme_msi_disabled;
 
index 5982b6a..a86b56e 100644 (file)
@@ -33,7 +33,7 @@
  */
 int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
 {
-       acpi_status status;
+       struct acpi_pci_root *root;
        acpi_handle handle;
        u32 flags;
 
@@ -44,26 +44,11 @@ int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
        if (!handle)
                return -EINVAL;
 
-       flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
-               | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
-               | OSC_PCI_EXPRESS_PME_CONTROL;
-
-       if (pci_aer_available()) {
-               if (aer_acpi_firmware_first())
-                       dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n");
-               else
-                       flags |= OSC_PCI_EXPRESS_AER_CONTROL;
-       }
-
-       status = acpi_pci_osc_control_set(handle, &flags,
-                                       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
-       if (ACPI_FAILURE(status)) {
-               dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n",
-                       status);
+       root = acpi_pci_find_root(handle);
+       if (!root)
                return -ENODEV;
-       }
 
-       dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags);
+       flags = root->osc_control_set;
 
        *srv_mask = PCIE_PORT_SERVICE_VC;
        if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
index a9c222d..5130d0d 100644 (file)
@@ -241,17 +241,17 @@ static int get_port_device_capability(struct pci_dev *dev)
        int cap_mask;
        int err;
 
+       if (pcie_ports_disabled)
+               return 0;
+
        err = pcie_port_platform_notify(dev, &cap_mask);
-       if (pcie_ports_auto) {
-               if (err) {
-                       pcie_no_aspm();
-                       return 0;
-               }
-       } else {
+       if (!pcie_ports_auto) {
                cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
                                | PCIE_PORT_SERVICE_VC;
                if (pci_aer_available())
                        cap_mask |= PCIE_PORT_SERVICE_AER;
+       } else if (err) {
+                       return 0;
        }
 
        pos = pci_pcie_cap(dev);
@@ -349,15 +349,18 @@ int pcie_port_device_register(struct pci_dev *dev)
        int status, capabilities, i, nr_service;
        int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
 
-       /* Get and check PCI Express port services */
-       capabilities = get_port_device_capability(dev);
-       if (!capabilities)
-               return -ENODEV;
-
        /* Enable PCI Express port device */
        status = pci_enable_device(dev);
        if (status)
                return status;
+
+       /* Get and check PCI Express port services */
+       capabilities = get_port_device_capability(dev);
+       if (!capabilities) {
+               pcie_no_aspm();
+               return 0;
+       }
+
        pci_set_master(dev);
        /*
         * Initialize service irqs. Don't use service devices that
index f9033e1..e0610bd 100644 (file)
@@ -57,6 +57,22 @@ __setup("pcie_ports=", pcie_port_setup);
 
 /* global data */
 
+/**
+ * pcie_clear_root_pme_status - Clear root port PME interrupt status.
+ * @dev: PCIe root port or event collector.
+ */
+void pcie_clear_root_pme_status(struct pci_dev *dev)
+{
+       int rtsta_pos;
+       u32 rtsta;
+
+       rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
+
+       pci_read_config_dword(dev, rtsta_pos, &rtsta);
+       rtsta |= PCI_EXP_RTSTA_PME;
+       pci_write_config_dword(dev, rtsta_pos, rtsta);
+}
+
 static int pcie_portdrv_restore_config(struct pci_dev *dev)
 {
        int retval;
@@ -69,6 +85,20 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
 }
 
 #ifdef CONFIG_PM
+static int pcie_port_resume_noirq(struct device *dev)
+{
+       struct pci_dev *pdev = to_pci_dev(dev);
+
+       /*
+        * Some BIOSes forget to clear Root PME Status bits after system wakeup
+        * which breaks ACPI-based runtime wakeup on PCI Express, so clear those
+        * bits now just in case (shouldn't hurt).
+        */
+       if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
+               pcie_clear_root_pme_status(pdev);
+       return 0;
+}
+
 static const struct dev_pm_ops pcie_portdrv_pm_ops = {
        .suspend        = pcie_port_device_suspend,
        .resume         = pcie_port_device_resume,
@@ -76,6 +106,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = {
        .thaw           = pcie_port_device_resume,
        .poweroff       = pcie_port_device_suspend,
        .restore        = pcie_port_device_resume,
+       .resume_noirq   = pcie_port_resume_noirq,
 };
 
 #define PCIE_PORTDRV_PM_OPS    (&pcie_portdrv_pm_ops)
@@ -327,10 +358,8 @@ static int __init pcie_portdrv_init(void)
 {
        int retval;
 
-       if (pcie_ports_disabled) {
-               pcie_no_aspm();
-               return -EACCES;
-       }
+       if (pcie_ports_disabled)
+               return pci_register_driver(&pcie_portdriver);
 
        dmi_check_system(pcie_portdrv_dmi_table);
 
index d3c5905..9c5c8be 100644 (file)
@@ -7515,16 +7515,10 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
 {
        struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
        volatile u32 int_reg;
-       int rc;
 
        ENTER;
        ioa_cfg->pdev->state_saved = true;
-       rc = pci_restore_state(ioa_cfg->pdev);
-
-       if (rc != PCIBIOS_SUCCESSFUL) {
-               ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
-               return IPR_RC_JOB_CONTINUE;
-       }
+       pci_restore_state(ioa_cfg->pdev);
 
        if (ipr_set_pcix_cmd_reg(ioa_cfg)) {
                ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
index 300d59f..321cf3a 100644 (file)
@@ -2228,12 +2228,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd)
                /* Once either bist or pci reset is done, restore PCI config
                 * space. If this fails, proceed with hard reset again
                 */
-               if (pci_restore_state(pinstance->pdev)) {
-                       pmcraid_info("config-space error resetting again\n");
-                       pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT;
-                       pmcraid_reset_alert(cmd);
-                       break;
-               }
+               pci_restore_state(pinstance->pdev);
 
                /* fail all pending commands */
                pmcraid_fail_outstanding_cmds(pinstance);
index f4b163f..0bc113c 100644 (file)
@@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
        /* when resuming, restore pci data and fb cursor */
        if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
                retv = pci_set_power_state(pdev, PCI_D0);
-               retv = pci_restore_state(pdev);
+               pci_restore_state(pdev);
                if (pci_enable_device(pdev))
                        return -1;
                pci_set_master(pdev);
index b336502..c4dbb13 100644 (file)
 extern int hest_disable;
 extern int erst_disable;
 
+#ifdef CONFIG_ACPI_APEI
+void __init acpi_hest_init(void);
+#else
+static inline void acpi_hest_init(void) { return; }
+#endif
+
 typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);
 int apei_hest_parse(apei_hest_func_t func, void *data);
 
index c8b6473..479d9bb 100644 (file)
@@ -40,4 +40,10 @@ static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
 { return NULL; }
 #endif
 
+#ifdef CONFIG_ACPI_APEI
+extern bool aer_acpi_firmware_first(void);
+#else
+static inline bool aer_acpi_firmware_first(void) { return false; }
+#endif
+
 #endif /* _PCI_ACPI_H_ */
index 91ba0b3..ce68105 100644 (file)
@@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev);
 extern void pcie_aspm_exit_link_state(struct pci_dev *pdev);
 extern void pcie_aspm_pm_state_change(struct pci_dev *pdev);
 extern void pci_disable_link_state(struct pci_dev *pdev, int state);
+extern void pcie_clear_aspm(void);
 extern void pcie_no_aspm(void);
 #else
 static inline void pcie_aspm_init_link_state(struct pci_dev *pdev)
@@ -41,7 +42,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev)
 static inline void pci_disable_link_state(struct pci_dev *pdev, int state)
 {
 }
-
+static inline void pcie_clear_aspm(void)
+{
+}
 static inline void pcie_no_aspm(void)
 {
 }
index 7454408..9e67dcd 100644 (file)
@@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size);
 
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev);
-int pci_restore_state(struct pci_dev *dev);
+void pci_restore_state(struct pci_dev *dev);
 int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state);
 int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
@@ -820,7 +820,6 @@ int pci_prepare_to_sleep(struct pci_dev *dev);
 int pci_back_from_sleep(struct pci_dev *dev);
 bool pci_dev_run_wake(struct pci_dev *dev);
 bool pci_check_pme_status(struct pci_dev *dev);
-void pci_wakeup_event(struct pci_dev *dev);
 void pci_pme_wakeup_bus(struct pci_bus *bus);
 
 static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state,
@@ -994,6 +993,9 @@ extern void pci_restore_msi_state(struct pci_dev *dev);
 extern int pci_msi_enabled(void);
 #endif
 
+extern bool pcie_ports_disabled;
+extern bool pcie_ports_auto;
+
 #ifndef CONFIG_PCIEASPM
 static inline int pcie_aspm_enabled(void)
 {
@@ -1003,6 +1005,14 @@ static inline int pcie_aspm_enabled(void)
 extern int pcie_aspm_enabled(void);
 #endif
 
+#ifdef CONFIG_PCIEAER
+void pci_no_aer(void);
+bool pci_aer_available(void);
+#else
+static inline void pci_no_aer(void) { }
+static inline bool pci_aer_available(void) { return false; }
+#endif
+
 #ifndef CONFIG_PCIE_ECRC
 static inline void pcie_set_ecrc_checking(struct pci_dev *dev)
 {
@@ -1168,10 +1178,8 @@ static inline int pci_save_state(struct pci_dev *dev)
        return 0;
 }
 
-static inline int pci_restore_state(struct pci_dev *dev)
-{
-       return 0;
-}
+static inline void pci_restore_state(struct pci_dev *dev)
+{ }
 
 static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 {
index ae0dc45..3adb06e 100644 (file)
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN        0x1c41
 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX        0x1c5f
 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS     0x1d22
-#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC       0x1d40
+#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0     0x1d40
+#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1     0x1d41
 #define PCI_DEVICE_ID_INTEL_82801AA_0  0x2410
 #define PCI_DEVICE_ID_INTEL_82801AA_1  0x2411
 #define PCI_DEVICE_ID_INTEL_82801AA_3  0x2413
index af83076..5b7e6b1 100644 (file)
 #define PCI_MSIX_PBA           8
 #define  PCI_MSIX_FLAGS_BIRMASK        (7 << 0)
 
+/* MSI-X entry's format */
+#define PCI_MSIX_ENTRY_SIZE            16
+#define  PCI_MSIX_ENTRY_LOWER_ADDR     0
+#define  PCI_MSIX_ENTRY_UPPER_ADDR     4
+#define  PCI_MSIX_ENTRY_DATA           8
+#define  PCI_MSIX_ENTRY_VECTOR_CTRL    12
+#define   PCI_MSIX_ENTRY_CTRL_MASKBIT  1
+
 /* CompactPCI Hotswap Register */
 
 #define PCI_CHSWP_CSR          2       /* Control and Status Register */
 #define  PCI_EXP_RTCTL_CRSSVE  0x10    /* CRS Software Visibility Enable */
 #define PCI_EXP_RTCAP          30      /* Root Capabilities */
 #define PCI_EXP_RTSTA          32      /* Root Status */
+#define PCI_EXP_RTSTA_PME      0x10000 /* PME status */
+#define PCI_EXP_RTSTA_PENDING  0x20000 /* PME pending */
 #define PCI_EXP_DEVCAP2                36      /* Device Capabilities 2 */
 #define  PCI_EXP_DEVCAP2_ARI   0x20    /* Alternative Routing-ID */
 #define PCI_EXP_DEVCTL2                40      /* Device Control 2 */
index a3301cc..185b000 100644 (file)
@@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
        int i;
 
        pci_set_power_state(pci, PCI_D0);
-       if (pci_restore_state(pci) < 0) {
-               printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
-                      "disabling device\n");
-               snd_card_disconnect(card);
-               return -EIO;
-       }
+       pci_restore_state(pci);
        if (pci_enable_device(pci) < 0) {
                printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
                       "disabling device\n");