diff options
author | 2017-11-28 16:19:52 +0000 | |
---|---|---|
committer | 2017-11-28 16:19:52 +0000 | |
commit | 69830d3909849dee33b9a2de88ece3d59c75a1b8 (patch) | |
tree | 67e22ac989e782ddc104f186dee54d1675e76923 /drivers/pci/setup-res.c | |
parent | ASoC: rk3399_gru_sound: Map BTN_0 to KEY_PLAYPAUSE (diff) | |
parent | ASoC: add snd_soc_disconnect_sync() (diff) | |
download | linux-dev-69830d3909849dee33b9a2de88ece3d59c75a1b8.tar.xz linux-dev-69830d3909849dee33b9a2de88ece3d59c75a1b8.zip |
Merge branch 'topic/disconnect' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-rcar
Diffstat (limited to 'drivers/pci/setup-res.c')
-rw-r--r-- | drivers/pci/setup-res.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index c039149cacb0..e815111f3f81 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -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; |