Merge branches 'imx/pata' and 'imx/sata' into next/driver
[pandora-kernel.git] / drivers / pci / pci.c
index 08a95b3..0ce6742 100644 (file)
@@ -77,6 +77,8 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
 unsigned long pci_hotplug_io_size  = DEFAULT_HOTPLUG_IO_SIZE;
 unsigned long pci_hotplug_mem_size = DEFAULT_HOTPLUG_MEM_SIZE;
 
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
+
 /*
  * The default CLS is used if arch didn't set CLS explicitly and not
  * all pci devices agree on the same value.  Arch can override either
@@ -3222,6 +3224,67 @@ out:
 }
 EXPORT_SYMBOL(pcie_set_readrq);
 
+/**
+ * pcie_get_mps - get PCI Express maximum payload size
+ * @dev: PCI device to query
+ *
+ * Returns maximum payload size in bytes
+ *    or appropriate error value.
+ */
+int pcie_get_mps(struct pci_dev *dev)
+{
+       int ret, cap;
+       u16 ctl;
+
+       cap = pci_pcie_cap(dev);
+       if (!cap)
+               return -EINVAL;
+
+       ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
+       if (!ret)
+               ret = 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+
+       return ret;
+}
+
+/**
+ * pcie_set_mps - set PCI Express maximum payload size
+ * @dev: PCI device to query
+ * @mps: maximum payload size in bytes
+ *    valid values are 128, 256, 512, 1024, 2048, 4096
+ *
+ * If possible sets maximum payload size
+ */
+int pcie_set_mps(struct pci_dev *dev, int mps)
+{
+       int cap, err = -EINVAL;
+       u16 ctl, v;
+
+       if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
+               goto out;
+
+       v = ffs(mps) - 8;
+       if (v > dev->pcie_mpss) 
+               goto out;
+       v <<= 5;
+
+       cap = pci_pcie_cap(dev);
+       if (!cap)
+               goto out;
+
+       err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl);
+       if (err)
+               goto out;
+
+       if ((ctl & PCI_EXP_DEVCTL_PAYLOAD) != v) {
+               ctl &= ~PCI_EXP_DEVCTL_PAYLOAD;
+               ctl |= v;
+               err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl);
+       }
+out:
+       return err;
+}
+
 /**
  * pci_select_bars - Make BAR mask from the type of resource
  * @dev: the PCI device for which BAR mask is made
@@ -3505,6 +3568,10 @@ static int __init pci_setup(char *str)
                                pci_hotplug_io_size = memparse(str + 9, &str);
                        } else if (!strncmp(str, "hpmemsize=", 10)) {
                                pci_hotplug_mem_size = memparse(str + 10, &str);
+                       } else if (!strncmp(str, "pcie_bus_safe", 13)) {
+                               pcie_bus_config = PCIE_BUS_SAFE;
+                       } else if (!strncmp(str, "pcie_bus_perf", 13)) {
+                               pcie_bus_config = PCIE_BUS_PERFORMANCE;
                        } else {
                                printk(KERN_ERR "PCI: Unknown option `%s'\n",
                                                str);