Lines Matching +full:- +full:cfg

1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/pci-ecam.h>
15 * On 64-bit systems, we do a single ioremap for the whole config space
16 * since we have enough virtual address range available. On 32-bit, we
23 * - reserve mem region
24 * - alloc struct pci_config_window with space for all mappings
25 * - ioremap the config space
31 unsigned int bus_shift = ops->bus_shift; in pci_ecam_create()
32 struct pci_config_window *cfg; in pci_ecam_create() local
37 if (busr->start > busr->end) in pci_ecam_create()
38 return ERR_PTR(-EINVAL); in pci_ecam_create()
40 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); in pci_ecam_create()
41 if (!cfg) in pci_ecam_create()
42 return ERR_PTR(-ENOMEM); in pci_ecam_create()
44 /* ECAM-compliant platforms need not supply ops->bus_shift */ in pci_ecam_create()
48 cfg->parent = dev; in pci_ecam_create()
49 cfg->ops = ops; in pci_ecam_create()
50 cfg->busr.start = busr->start; in pci_ecam_create()
51 cfg->busr.end = busr->end; in pci_ecam_create()
52 cfg->busr.flags = IORESOURCE_BUS; in pci_ecam_create()
53 cfg->bus_shift = bus_shift; in pci_ecam_create()
54 bus_range = resource_size(&cfg->busr); in pci_ecam_create()
58 cfg->busr.end = busr->start + bus_range - 1; in pci_ecam_create()
60 cfgres, &cfg->busr, busr); in pci_ecam_create()
64 cfg->res.start = cfgres->start; in pci_ecam_create()
65 cfg->res.end = cfgres->end; in pci_ecam_create()
66 cfg->res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; in pci_ecam_create()
67 cfg->res.name = "PCI ECAM"; in pci_ecam_create()
69 conflict = request_resource_conflict(&iomem_resource, &cfg->res); in pci_ecam_create()
71 err = -EBUSY; in pci_ecam_create()
73 &cfg->res, conflict->name, conflict); in pci_ecam_create()
78 cfg->winp = kcalloc(bus_range, sizeof(*cfg->winp), GFP_KERNEL); in pci_ecam_create()
79 if (!cfg->winp) in pci_ecam_create()
82 cfg->win = pci_remap_cfgspace(cfgres->start, bus_range * bsz); in pci_ecam_create()
83 if (!cfg->win) in pci_ecam_create()
87 if (ops->init) { in pci_ecam_create()
88 err = ops->init(cfg); in pci_ecam_create()
92 dev_info(dev, "ECAM at %pR for %pR\n", &cfg->res, &cfg->busr); in pci_ecam_create()
93 return cfg; in pci_ecam_create()
98 err = -ENOMEM; in pci_ecam_create()
100 pci_ecam_free(cfg); in pci_ecam_create()
105 void pci_ecam_free(struct pci_config_window *cfg) in pci_ecam_free() argument
110 if (cfg->winp) { in pci_ecam_free()
111 for (i = 0; i < resource_size(&cfg->busr); i++) in pci_ecam_free()
112 if (cfg->winp[i]) in pci_ecam_free()
113 iounmap(cfg->winp[i]); in pci_ecam_free()
114 kfree(cfg->winp); in pci_ecam_free()
117 if (cfg->win) in pci_ecam_free()
118 iounmap(cfg->win); in pci_ecam_free()
120 if (cfg->res.parent) in pci_ecam_free()
121 release_resource(&cfg->res); in pci_ecam_free()
122 kfree(cfg); in pci_ecam_free()
128 struct pci_config_window *cfg = bus->sysdata; in pci_ecam_add_bus() local
129 unsigned int bsz = 1 << cfg->bus_shift; in pci_ecam_add_bus()
130 unsigned int busn = bus->number; in pci_ecam_add_bus()
136 if (busn < cfg->busr.start || busn > cfg->busr.end) in pci_ecam_add_bus()
137 return -EINVAL; in pci_ecam_add_bus()
139 busn -= cfg->busr.start; in pci_ecam_add_bus()
140 start = cfg->res.start + busn * bsz; in pci_ecam_add_bus()
142 cfg->winp[busn] = pci_remap_cfgspace(start, bsz); in pci_ecam_add_bus()
143 if (!cfg->winp[busn]) in pci_ecam_add_bus()
144 return -ENOMEM; in pci_ecam_add_bus()
151 struct pci_config_window *cfg = bus->sysdata; in pci_ecam_remove_bus() local
152 unsigned int busn = bus->number; in pci_ecam_remove_bus()
154 if (!per_bus_mapping || busn < cfg->busr.start || busn > cfg->busr.end) in pci_ecam_remove_bus()
157 busn -= cfg->busr.start; in pci_ecam_remove_bus()
158 if (cfg->winp[busn]) { in pci_ecam_remove_bus()
159 iounmap(cfg->winp[busn]); in pci_ecam_remove_bus()
160 cfg->winp[busn] = NULL; in pci_ecam_remove_bus()
165 * Function to implement the pci_ops ->map_bus method
170 struct pci_config_window *cfg = bus->sysdata; in pci_ecam_map_bus() local
171 unsigned int bus_shift = cfg->ops->bus_shift; in pci_ecam_map_bus()
172 unsigned int devfn_shift = cfg->ops->bus_shift - 8; in pci_ecam_map_bus()
173 unsigned int busn = bus->number; in pci_ecam_map_bus()
177 if (busn < cfg->busr.start || busn > cfg->busr.end) in pci_ecam_map_bus()
180 busn -= cfg->busr.start; in pci_ecam_map_bus()
182 base = cfg->winp[busn]; in pci_ecam_map_bus()
185 base = cfg->win; in pci_ecam_map_bus()
187 if (cfg->ops->bus_shift) { in pci_ecam_map_bus()
212 /* ECAM ops for 32-bit access only (non-compliant) */
223 /* ECAM ops for 32-bit read only (non-compliant) */