Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / drivers / pci / setup-res.c
index c039149..e815111 100644 (file)
@@ -397,6 +397,64 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
        return 0;
 }
 
+void pci_release_resource(struct pci_dev *dev, int resno)
+{
+       struct resource *res = dev->resource + resno;
+
+       dev_info(&dev->dev, "BAR %d: releasing %pR\n", resno, res);
+       release_resource(res);
+       res->end = resource_size(res) - 1;
+       res->start = 0;
+       res->flags |= IORESOURCE_UNSET;
+}
+EXPORT_SYMBOL(pci_release_resource);
+
+int pci_resize_resource(struct pci_dev *dev, int resno, int size)
+{
+       struct resource *res = dev->resource + resno;
+       int old, ret;
+       u32 sizes;
+       u16 cmd;
+
+       /* Make sure the resource isn't assigned before resizing it. */
+       if (!(res->flags & IORESOURCE_UNSET))
+               return -EBUSY;
+
+       pci_read_config_word(dev, PCI_COMMAND, &cmd);
+       if (cmd & PCI_COMMAND_MEMORY)
+               return -EBUSY;
+
+       sizes = pci_rebar_get_possible_sizes(dev, resno);
+       if (!sizes)
+               return -ENOTSUPP;
+
+       if (!(sizes & BIT(size)))
+               return -EINVAL;
+
+       old = pci_rebar_get_current_size(dev, resno);
+       if (old < 0)
+               return old;
+
+       ret = pci_rebar_set_size(dev, resno, size);
+       if (ret)
+               return ret;
+
+       res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
+
+       /* Check if the new config works by trying to assign everything. */
+       ret = pci_reassign_bridge_resources(dev->bus->self, res->flags);
+       if (ret)
+               goto error_resize;
+
+       return 0;
+
+error_resize:
+       pci_rebar_set_size(dev, resno, old);
+       res->end = res->start + pci_rebar_size_to_bytes(old) - 1;
+       return ret;
+}
+EXPORT_SYMBOL(pci_resize_resource);
+
 int pci_enable_resources(struct pci_dev *dev, int mask)
 {
        u16 cmd, old_cmd;