mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 15:12:13 +02:00
Merge branch 'pci/enumeration'
- Add a debug message on PCI device release (Niklas Schnelle) - Dynamically map ECAM regions to reduce vmalloc usage (Russell King) * pci/enumeration: PCI: Dynamically map ECAM regions PCI: Print a debug message on PCI device release
This commit is contained in:
commit
104eb9d8c9
|
|
@ -32,7 +32,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev,
|
|||
struct pci_config_window *cfg;
|
||||
unsigned int bus_range, bus_range_max, bsz;
|
||||
struct resource *conflict;
|
||||
int i, err;
|
||||
int err;
|
||||
|
||||
if (busr->start > busr->end)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
|
@ -50,6 +50,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev,
|
|||
cfg->busr.start = busr->start;
|
||||
cfg->busr.end = busr->end;
|
||||
cfg->busr.flags = IORESOURCE_BUS;
|
||||
cfg->bus_shift = bus_shift;
|
||||
bus_range = resource_size(&cfg->busr);
|
||||
bus_range_max = resource_size(cfgres) >> bus_shift;
|
||||
if (bus_range > bus_range_max) {
|
||||
|
|
@ -77,13 +78,6 @@ struct pci_config_window *pci_ecam_create(struct device *dev,
|
|||
cfg->winp = kcalloc(bus_range, sizeof(*cfg->winp), GFP_KERNEL);
|
||||
if (!cfg->winp)
|
||||
goto err_exit_malloc;
|
||||
for (i = 0; i < bus_range; i++) {
|
||||
cfg->winp[i] =
|
||||
pci_remap_cfgspace(cfgres->start + i * bsz,
|
||||
bsz);
|
||||
if (!cfg->winp[i])
|
||||
goto err_exit_iomap;
|
||||
}
|
||||
} else {
|
||||
cfg->win = pci_remap_cfgspace(cfgres->start, bus_range * bsz);
|
||||
if (!cfg->win)
|
||||
|
|
@ -129,6 +123,44 @@ void pci_ecam_free(struct pci_config_window *cfg)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pci_ecam_free);
|
||||
|
||||
static int pci_ecam_add_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_config_window *cfg = bus->sysdata;
|
||||
unsigned int bsz = 1 << cfg->bus_shift;
|
||||
unsigned int busn = bus->number;
|
||||
phys_addr_t start;
|
||||
|
||||
if (!per_bus_mapping)
|
||||
return 0;
|
||||
|
||||
if (busn < cfg->busr.start || busn > cfg->busr.end)
|
||||
return -EINVAL;
|
||||
|
||||
busn -= cfg->busr.start;
|
||||
start = cfg->res.start + busn * bsz;
|
||||
|
||||
cfg->winp[busn] = pci_remap_cfgspace(start, bsz);
|
||||
if (!cfg->winp[busn])
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pci_ecam_remove_bus(struct pci_bus *bus)
|
||||
{
|
||||
struct pci_config_window *cfg = bus->sysdata;
|
||||
unsigned int busn = bus->number;
|
||||
|
||||
if (!per_bus_mapping || busn < cfg->busr.start || busn > cfg->busr.end)
|
||||
return;
|
||||
|
||||
busn -= cfg->busr.start;
|
||||
if (cfg->winp[busn]) {
|
||||
iounmap(cfg->winp[busn]);
|
||||
cfg->winp[busn] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to implement the pci_ops ->map_bus method
|
||||
*/
|
||||
|
|
@ -167,6 +199,8 @@ EXPORT_SYMBOL_GPL(pci_ecam_map_bus);
|
|||
/* ECAM ops */
|
||||
const struct pci_ecam_ops pci_generic_ecam_ops = {
|
||||
.pci_ops = {
|
||||
.add_bus = pci_ecam_add_bus,
|
||||
.remove_bus = pci_ecam_remove_bus,
|
||||
.map_bus = pci_ecam_map_bus,
|
||||
.read = pci_generic_config_read,
|
||||
.write = pci_generic_config_write,
|
||||
|
|
@ -178,6 +212,8 @@ EXPORT_SYMBOL_GPL(pci_generic_ecam_ops);
|
|||
/* ECAM ops for 32-bit access only (non-compliant) */
|
||||
const struct pci_ecam_ops pci_32b_ops = {
|
||||
.pci_ops = {
|
||||
.add_bus = pci_ecam_add_bus,
|
||||
.remove_bus = pci_ecam_remove_bus,
|
||||
.map_bus = pci_ecam_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write32,
|
||||
|
|
@ -187,6 +223,8 @@ const struct pci_ecam_ops pci_32b_ops = {
|
|||
/* ECAM ops for 32-bit read only (non-compliant) */
|
||||
const struct pci_ecam_ops pci_32b_read_ops = {
|
||||
.pci_ops = {
|
||||
.add_bus = pci_ecam_add_bus,
|
||||
.remove_bus = pci_ecam_remove_bus,
|
||||
.map_bus = pci_ecam_map_bus,
|
||||
.read = pci_generic_config_read32,
|
||||
.write = pci_generic_config_write,
|
||||
|
|
|
|||
|
|
@ -2226,6 +2226,7 @@ static void pci_release_dev(struct device *dev)
|
|||
pci_bus_put(pci_dev->bus);
|
||||
kfree(pci_dev->driver_override);
|
||||
bitmap_free(pci_dev->dma_alias_mask);
|
||||
dev_dbg(dev, "device released\n");
|
||||
kfree(pci_dev);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct pci_ecam_ops {
|
|||
struct pci_config_window {
|
||||
struct resource res;
|
||||
struct resource busr;
|
||||
unsigned int bus_shift;
|
||||
void *priv;
|
||||
const struct pci_ecam_ops *ops;
|
||||
union {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user