ucc_geth: Add support to local-mac-address property
[powerpc.git] / drivers / pci / pci.c
index 212acd2..84c757b 100644 (file)
@@ -392,6 +392,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        if (state > PCI_D3hot)
                state = PCI_D3hot;
 
+       /*
+        * If the device or the parent bridge can't support PCI PM, ignore
+        * the request if we're doing anything besides putting it into D0
+        * (which would only happen on boot).
+        */
+       if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
+               return 0;
+
        /* Validate current state:
         * Can enter D0 from any state, but if we can only go deeper 
         * to sleep if we're already in a low power state
@@ -403,13 +411,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state)
        } else if (dev->current_state == state)
                return 0;        /* we're already there */
 
-       /*
-        * If the device or the parent bridge can't support PCI PM, ignore
-        * the request if we're doing anything besides putting it into D0
-        * (which would only happen on boot).
-        */
-       if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev))
-               return 0;
 
        /* find PCI PM capability in list */
        pm = pci_find_capability(dev, PCI_CAP_ID_PM);
@@ -633,8 +634,6 @@ pci_save_state(struct pci_dev *dev)
                pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]);
        if ((i = pci_save_msi_state(dev)) != 0)
                return i;
-       if ((i = pci_save_msix_state(dev)) != 0)
-               return i;
        if ((i = pci_save_pcie_state(dev)) != 0)
                return i;
        if ((i = pci_save_pcix_state(dev)) != 0)
@@ -672,7 +671,37 @@ pci_restore_state(struct pci_dev *dev)
        }
        pci_restore_pcix_state(dev);
        pci_restore_msi_state(dev);
-       pci_restore_msix_state(dev);
+
+       return 0;
+}
+
+static int do_pci_enable_device(struct pci_dev *dev, int bars)
+{
+       int err;
+
+       err = pci_set_power_state(dev, PCI_D0);
+       if (err < 0 && err != -EIO)
+               return err;
+       err = pcibios_enable_device(dev, bars);
+       if (err < 0)
+               return err;
+       pci_fixup_device(pci_fixup_enable, dev);
+
+       return 0;
+}
+
+/**
+ * __pci_reenable_device - Resume abandoned device
+ * @dev: PCI device to be resumed
+ *
+ *  Note this function is a backend of pci_default_resume and is not supposed
+ *  to be called by normal code, write proper resume handler and use it instead.
+ */
+int
+__pci_reenable_device(struct pci_dev *dev)
+{
+       if (atomic_read(&dev->enable_cnt))
+               return do_pci_enable_device(dev, (1 << PCI_NUM_RESOURCES) - 1);
        return 0;
 }
 
@@ -693,16 +722,9 @@ pci_enable_device_bars(struct pci_dev *dev, int bars)
        if (atomic_add_return(1, &dev->enable_cnt) > 1)
                return 0;               /* already enabled */
 
-       err = pci_set_power_state(dev, PCI_D0);
-       if (err < 0 && err != -EIO)
-               goto err_out;
-       err = pcibios_enable_device(dev, bars);
+       err = do_pci_enable_device(dev, bars);
        if (err < 0)
-               goto err_out;
-       pci_fixup_device(pci_fixup_enable, dev);
-
-err_out:
-       atomic_dec(&dev->enable_cnt);
+               atomic_dec(&dev->enable_cnt);
        return err;
 }
 
@@ -898,6 +920,47 @@ err_out:
        return -EBUSY;
 }
 
+/**
+ * pci_release_selected_regions - Release selected PCI I/O and memory resources
+ * @pdev: PCI device whose resources were previously reserved
+ * @bars: Bitmask of BARs to be released
+ *
+ * Release selected PCI I/O and memory resources previously reserved.
+ * Call this function only after all use of the PCI regions has ceased.
+ */
+void pci_release_selected_regions(struct pci_dev *pdev, int bars)
+{
+       int i;
+
+       for (i = 0; i < 6; i++)
+               if (bars & (1 << i))
+                       pci_release_region(pdev, i);
+}
+
+/**
+ * pci_request_selected_regions - Reserve selected PCI I/O and memory resources
+ * @pdev: PCI device whose resources are to be reserved
+ * @bars: Bitmask of BARs to be requested
+ * @res_name: Name to be associated with resource
+ */
+int pci_request_selected_regions(struct pci_dev *pdev, int bars,
+                                const char *res_name)
+{
+       int i;
+
+       for (i = 0; i < 6; i++)
+               if (bars & (1 << i))
+                       if(pci_request_region(pdev, i, res_name))
+                               goto err_out;
+       return 0;
+
+err_out:
+       while(--i >= 0)
+               if (bars & (1 << i))
+                       pci_release_region(pdev, i);
+
+       return -EBUSY;
+}
 
 /**
  *     pci_release_regions - Release reserved PCI I/O and memory resources
@@ -910,10 +973,7 @@ err_out:
 
 void pci_release_regions(struct pci_dev *pdev)
 {
-       int i;
-       
-       for (i = 0; i < 6; i++)
-               pci_release_region(pdev, i);
+       pci_release_selected_regions(pdev, (1 << 6) - 1);
 }
 
 /**
@@ -931,18 +991,7 @@ void pci_release_regions(struct pci_dev *pdev)
  */
 int pci_request_regions(struct pci_dev *pdev, const char *res_name)
 {
-       int i;
-       
-       for (i = 0; i < 6; i++)
-               if(pci_request_region(pdev, i, res_name))
-                       goto err_out;
-       return 0;
-
-err_out:
-       while(--i >= 0)
-               pci_release_region(pdev, i);
-               
-       return -EBUSY;
+       return pci_request_selected_regions(pdev, ((1 << 6) - 1), res_name);
 }
 
 /**
@@ -1125,7 +1174,23 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
        return 0;
 }
 #endif
-     
+
+/**
+ * pci_select_bars - Make BAR mask from the type of resource
+ * @pdev: the PCI device for which BAR mask is made
+ * @flags: resource type mask to be selected
+ *
+ * This helper routine makes bar mask from the type of resource.
+ */
+int pci_select_bars(struct pci_dev *dev, unsigned long flags)
+{
+       int i, bars = 0;
+       for (i = 0; i < PCI_NUM_RESOURCES; i++)
+               if (pci_resource_flags(dev, i) & flags)
+                       bars |= (1 << i);
+       return bars;
+}
+
 static int __devinit pci_init(void)
 {
        struct pci_dev *dev = NULL;
@@ -1158,12 +1223,6 @@ early_param("pci", pci_setup);
 
 device_initcall(pci_init);
 
-#if defined(CONFIG_ISA) || defined(CONFIG_EISA)
-/* FIXME: Some boxes have multiple ISA bridges! */
-struct pci_dev *isa_bridge;
-EXPORT_SYMBOL(isa_bridge);
-#endif
-
 EXPORT_SYMBOL_GPL(pci_restore_bars);
 EXPORT_SYMBOL(pci_enable_device_bars);
 EXPORT_SYMBOL(pci_enable_device);
@@ -1174,6 +1233,8 @@ EXPORT_SYMBOL(pci_release_regions);
 EXPORT_SYMBOL(pci_request_regions);
 EXPORT_SYMBOL(pci_release_region);
 EXPORT_SYMBOL(pci_request_region);
+EXPORT_SYMBOL(pci_release_selected_regions);
+EXPORT_SYMBOL(pci_request_selected_regions);
 EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
@@ -1182,13 +1243,10 @@ EXPORT_SYMBOL(pci_set_dma_mask);
 EXPORT_SYMBOL(pci_set_consistent_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
 EXPORT_SYMBOL(pci_find_parent_resource);
+EXPORT_SYMBOL(pci_select_bars);
 
 EXPORT_SYMBOL(pci_set_power_state);
 EXPORT_SYMBOL(pci_save_state);
 EXPORT_SYMBOL(pci_restore_state);
 EXPORT_SYMBOL(pci_enable_wake);
 
-/* Quirk info */
-
-EXPORT_SYMBOL(isa_dma_bridge_buggy);
-EXPORT_SYMBOL(pci_pci_problems);