PCI: Introduce platform_pci_power_manageable function
[deliverable/linux.git] / drivers / pci / pci.c
index a4445b7210bf7057e0322c5ba49d943ce1cbd056..f8074525267cabfb25f808e945bd107e77575832 100644 (file)
@@ -1,6 +1,4 @@
 /*
- *     $Id: pci.c,v 1.91 1999/01/21 13:34:01 davem Exp $
- *
  *     PCI Bus Services, see include/linux/pci.h for further explanation.
  *
  *     Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
@@ -18,6 +16,7 @@
 #include <linux/spinlock.h>
 #include <linux/string.h>
 #include <linux/log2.h>
+#include <linux/pci-aspm.h>
 #include <asm/dma.h>   /* isa_dma_bridge_buggy */
 #include "pci.h"
 
@@ -377,7 +376,32 @@ pci_restore_bars(struct pci_dev *dev)
                pci_update_resource(dev, &dev->resource[i], i);
 }
 
-int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t t);
+static struct pci_platform_pm_ops *pci_platform_pm;
+
+int pci_set_platform_pm(struct pci_platform_pm_ops *ops)
+{
+       if (!ops->is_manageable || !ops->set_state || !ops->choose_state)
+               return -EINVAL;
+       pci_platform_pm = ops;
+       return 0;
+}
+
+static inline bool platform_pci_power_manageable(struct pci_dev *dev)
+{
+       return pci_platform_pm ? pci_platform_pm->is_manageable(dev) : false;
+}
+
+static inline int platform_pci_set_power_state(struct pci_dev *dev,
+                                                pci_power_t t)
+{
+       return pci_platform_pm ? pci_platform_pm->set_state(dev, t) : -ENOSYS;
+}
+
+static inline pci_power_t platform_pci_choose_state(struct pci_dev *dev)
+{
+       return pci_platform_pm ?
+                       pci_platform_pm->choose_state(dev) : PCI_POWER_ERROR;
+}
 
 /**
  * pci_set_power_state - Set the power state of a PCI device
@@ -423,8 +447,8 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
         * to sleep if we're already in a low power state
         */
        if (state != PCI_D0 && dev->current_state > state) {
-               printk(KERN_ERR "%s(): %s: state=%d, current state=%d\n",
-                       __FUNCTION__, pci_name(dev), state, dev->current_state);
+               dev_err(&dev->dev, "invalid power transition "
+                       "(from state %d to %d)\n", dev->current_state, state);
                return -EINVAL;
        } else if (dev->current_state == state)
                return 0;        /* we're already there */
@@ -432,9 +456,8 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
 
        pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc);
        if ((pmc & PCI_PM_CAP_VER_MASK) > 3) {
-               printk(KERN_DEBUG
-                      "PCI: %s has unsupported PM cap regs version (%u)\n",
-                      pci_name(dev), pmc & PCI_PM_CAP_VER_MASK);
+               dev_printk(KERN_DEBUG, &dev->dev, "unsupported PM cap regs "
+                          "version (%u)\n", pmc & PCI_PM_CAP_VER_MASK);
                return -EIO;
        }
 
@@ -481,8 +504,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
         * Give firmware a chance to be called, such as ACPI _PRx, _PSx
         * Firmware method after native method ?
         */
-       if (platform_pci_set_power_state)
-               platform_pci_set_power_state(dev, state);
+       platform_pci_set_power_state(dev, state);
 
        dev->current_state = state;
 
@@ -501,11 +523,12 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        if (need_restore)
                pci_restore_bars(dev);
 
+       if (dev->bus->self)
+               pcie_aspm_pm_state_change(dev->bus->self);
+
        return 0;
 }
 
-pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state);
 /**
  * pci_choose_state - Choose the power state of a PCI device
  * @dev: PCI device to be suspended
@@ -523,11 +546,9 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
        if (!pci_find_capability(dev, PCI_CAP_ID_PM))
                return PCI_D0;
 
-       if (platform_pci_choose_state) {
-               ret = platform_pci_choose_state(dev, state);
-               if (ret != PCI_POWER_ERROR)
-                       return ret;
-       }
+       ret = platform_pci_choose_state(dev);
+       if (ret != PCI_POWER_ERROR)
+               return ret;
 
        switch (state.event) {
        case PM_EVENT_ON:
@@ -539,7 +560,8 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
        case PM_EVENT_HIBERNATE:
                return PCI_D3hot;
        default:
-               printk("Unrecognized suspend event %d\n", state.event);
+               dev_info(&dev->dev, "unrecognized suspend event %d\n",
+                        state.event);
                BUG();
        }
        return PCI_D0;
@@ -564,7 +586,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
        else
                found = 1;
        if (!save_state) {
-               dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
+               dev_err(&dev->dev, "out of memory in pci_save_pcie_state\n");
                return -ENOMEM;
        }
        cap = (u16 *)&save_state->data[0];
@@ -615,7 +637,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
        else
                found = 1;
        if (!save_state) {
-               dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n");
+               dev_err(&dev->dev, "out of memory in pci_save_pcie_state\n");
                return -ENOMEM;
        }
        cap = (u16 *)&save_state->data[0];
@@ -681,10 +703,9 @@ pci_restore_state(struct pci_dev *dev)
        for (i = 15; i >= 0; i--) {
                pci_read_config_dword(dev, i * 4, &val);
                if (val != dev->saved_config_space[i]) {
-                       printk(KERN_DEBUG "PM: Writing back config space on "
-                               "device %s at offset %x (was %x, writing %x)\n",
-                               pci_name(dev), i,
-                               val, (int)dev->saved_config_space[i]);
+                       dev_printk(KERN_DEBUG, &dev->dev, "restoring config "
+                               "space at offset %#x (was %#x, writing %#x)\n",
+                               i, val, (int)dev->saved_config_space[i]);
                        pci_write_config_dword(dev,i * 4,
                                dev->saved_config_space[i]);
                }
@@ -1112,13 +1133,11 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
        return 0;
 
 err_out:
-       printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%llx@%llx "
-               "for device %s\n",
-               pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
-               bar + 1, /* PCI BAR # */
-               (unsigned long long)pci_resource_len(pdev, bar),
-               (unsigned long long)pci_resource_start(pdev, bar),
-               pci_name(pdev));
+       dev_warn(&pdev->dev, "BAR %d: can't reserve %s region [%#llx-%#llx]\n",
+                bar,
+                pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
+                (unsigned long long)pci_resource_start(pdev, bar),
+                (unsigned long long)pci_resource_end(pdev, bar));
        return -EBUSY;
 }
 
@@ -1210,7 +1229,7 @@ pci_set_master(struct pci_dev *dev)
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        if (! (cmd & PCI_COMMAND_MASTER)) {
-               pr_debug("PCI: Enabling bus mastering for device %s\n", pci_name(dev));
+               dev_dbg(&dev->dev, "enabling bus mastering\n");
                cmd |= PCI_COMMAND_MASTER;
                pci_write_config_word(dev, PCI_COMMAND, cmd);
        }
@@ -1275,8 +1294,8 @@ pci_set_cacheline_size(struct pci_dev *dev)
        if (cacheline_size == pci_cache_line_size)
                return 0;
 
-       printk(KERN_DEBUG "PCI: cache line size of %d is not supported "
-              "by device %s\n", pci_cache_line_size << 2, pci_name(dev));
+       dev_printk(KERN_DEBUG, &dev->dev, "cache line size of %d is not "
+                  "supported\n", pci_cache_line_size << 2);
 
        return -EINVAL;
 }
@@ -1301,8 +1320,7 @@ pci_set_mwi(struct pci_dev *dev)
 
        pci_read_config_word(dev, PCI_COMMAND, &cmd);
        if (! (cmd & PCI_COMMAND_INVALIDATE)) {
-               pr_debug("PCI: Enabling Mem-Wr-Inval for device %s\n",
-                       pci_name(dev));
+               dev_dbg(&dev->dev, "enabling Mem-Wr-Inval\n");
                cmd |= PCI_COMMAND_INVALIDATE;
                pci_write_config_word(dev, PCI_COMMAND, cmd);
        }
This page took 0.026413 seconds and 5 git commands to generate.