1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Common library for PCI host controller drivers 4 * 5 * Copyright (C) 2014 ARM Limited 6 * 7 * Author: Will Deacon <will.deacon@arm.com> 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/module.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/of.h> 14 #include <linux/of_address.h> 15 #include <linux/of_pci.h> 16 #include <linux/pci-ecam.h> 17 #include <linux/platform_device.h> 18 19 #include "pci-host-common.h" 20 21 /** 22 * pci_host_common_delete_ports - Cleanup function for port list 23 * @data: Pointer to the port list head 24 */ 25 void pci_host_common_delete_ports(void *data) 26 { 27 struct list_head *ports = data; 28 struct pci_host_perst *perst, *tmp_perst; 29 struct pci_host_port *port, *tmp_port; 30 31 list_for_each_entry_safe(port, tmp_port, ports, list) { 32 list_for_each_entry_safe(perst, tmp_perst, &port->perst, list) 33 list_del(&perst->list); 34 list_del(&port->list); 35 } 36 } 37 EXPORT_SYMBOL_GPL(pci_host_common_delete_ports); 38 39 /** 40 * pci_host_common_parse_perst - Parse PERST# from all nodes, depth first 41 * @dev: Device pointer 42 * @port: PCI host port 43 * @np: Device tree node to start parsing from 44 * 45 * Recursively parse PERST# GPIO from all PCIe bridge nodes starting from 46 * @np in a depth-first manner. 47 * 48 * Return: 0 on success, negative error code on failure. 49 */ 50 static int pci_host_common_parse_perst(struct device *dev, 51 struct pci_host_port *port, 52 struct device_node *np) 53 { 54 struct pci_host_perst *perst; 55 struct gpio_desc *reset; 56 int ret; 57 58 if (!of_property_present(np, "reset-gpios")) 59 goto parse_child_node; 60 61 reset = devm_fwnode_gpiod_get(dev, of_fwnode_handle(np), "reset", 62 GPIOD_ASIS, "PERST#"); 63 if (IS_ERR(reset)) { 64 /* 65 * FIXME: GPIOLIB currently supports exclusive GPIO access only. 66 * Non exclusive access is broken. But shared PERST# requires 67 * non-exclusive access. So once GPIOLIB properly supports it, 68 * implement it here. 69 */ 70 if (PTR_ERR(reset) == -EBUSY) 71 dev_err(dev, "Shared PERST# is not supported\n"); 72 73 return PTR_ERR(reset); 74 } 75 76 perst = devm_kzalloc(dev, sizeof(*perst), GFP_KERNEL); 77 if (!perst) 78 return -ENOMEM; 79 80 INIT_LIST_HEAD(&perst->list); 81 perst->desc = reset; 82 list_add_tail(&perst->list, &port->perst); 83 84 parse_child_node: 85 for_each_available_child_of_node_scoped(np, child) { 86 ret = pci_host_common_parse_perst(dev, port, child); 87 if (ret) 88 return ret; 89 } 90 91 return 0; 92 } 93 94 /** 95 * pci_host_common_parse_port - Parse a single Root Port node 96 * @dev: Device pointer 97 * @bridge: PCI host bridge 98 * @node: Device tree node of the Root Port 99 * 100 * Parse Root Port properties from the device tree. Currently it only 101 * handles the PERST# GPIO (including PERST# GPIOs from all PCIe bridge 102 * nodes under this Root Port), which is optional. 103 * 104 * NOTE: This helper fetches resources (like PERST# GPIO) optionally. If a 105 * controller driver has a hard dependency on certain resources (PHY, 106 * clocks, regulators, etc.), those resources MUST be modeled correctly in 107 * the DT binding and validated in DTS. This helper cannot enforce such 108 * dependencies and the driver may fail to operate if required resources 109 * are missing. 110 * 111 * Return: 0 on success, -ENODEV if PERST# found in RC node (legacy binding 112 * should be used), Other negative error codes on failure. 113 */ 114 static int pci_host_common_parse_port(struct device *dev, 115 struct pci_host_bridge *bridge, 116 struct device_node *node) 117 { 118 struct pci_host_port *port; 119 int ret; 120 121 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); 122 if (!port) 123 return -ENOMEM; 124 125 INIT_LIST_HEAD(&port->perst); 126 127 ret = pci_host_common_parse_perst(dev, port, node); 128 if (ret) 129 return ret; 130 131 /* 132 * 1. PERST# found in RP or its child nodes - list is not empty, 133 * continue 134 * 135 * 2. PERST# not found in RP/children, but found in RC node - 136 * return -ENODEV to fallback legacy binding 137 * 138 * 3. PERST# not found anywhere - list is empty, continue (optional 139 * PERST#) 140 */ 141 if (list_empty(&port->perst)) { 142 if (of_property_present(dev->of_node, "reset-gpios") || 143 of_property_present(dev->of_node, "reset-gpio")) 144 return -ENODEV; 145 } 146 147 INIT_LIST_HEAD(&port->list); 148 list_add_tail(&port->list, &bridge->ports); 149 150 return 0; 151 } 152 153 /** 154 * pci_host_common_parse_ports - Parse Root Port nodes from device tree 155 * @dev: Device pointer 156 * @bridge: PCI host bridge 157 * 158 * Iterate through child nodes of the host bridge and parse Root Port 159 * properties (currently only reset GPIOs). 160 * 161 * Return: 0 on success, -ENODEV if no ports found or PERST# found in RC 162 * node (legacy binding should be used), Other negative error codes on 163 * failure. 164 */ 165 int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *bridge) 166 { 167 int ret = -ENODEV; 168 169 for_each_available_child_of_node_scoped(dev->of_node, of_port) { 170 if (!of_node_is_type(of_port, "pci")) 171 continue; 172 ret = pci_host_common_parse_port(dev, bridge, of_port); 173 if (ret) 174 goto err_cleanup; 175 } 176 177 if (ret) 178 return ret; 179 180 return devm_add_action_or_reset(dev, pci_host_common_delete_ports, 181 &bridge->ports); 182 183 err_cleanup: 184 pci_host_common_delete_ports(&bridge->ports); 185 return ret; 186 } 187 EXPORT_SYMBOL_GPL(pci_host_common_parse_ports); 188 189 #define PCI_HOST_D3COLD_ALLOWED BIT(0) 190 #define PCI_HOST_PME_D3COLD_CAPABLE BIT(1) 191 192 193 static void gen_pci_unmap_cfg(void *ptr) 194 { 195 pci_ecam_free((struct pci_config_window *)ptr); 196 } 197 198 struct pci_config_window *pci_host_common_ecam_create(struct device *dev, 199 struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops) 200 { 201 int err; 202 struct resource cfgres; 203 struct resource_entry *bus; 204 struct pci_config_window *cfg; 205 206 err = of_address_to_resource(dev->of_node, 0, &cfgres); 207 if (err) { 208 dev_err(dev, "missing or malformed \"reg\" property\n"); 209 return ERR_PTR(err); 210 } 211 212 bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); 213 if (!bus) 214 return ERR_PTR(-ENODEV); 215 216 cfg = pci_ecam_create(dev, &cfgres, bus->res, ops); 217 if (IS_ERR(cfg)) 218 return cfg; 219 220 err = devm_add_action_or_reset(dev, gen_pci_unmap_cfg, cfg); 221 if (err) 222 return ERR_PTR(err); 223 224 return cfg; 225 } 226 EXPORT_SYMBOL_GPL(pci_host_common_ecam_create); 227 228 int pci_host_common_init(struct platform_device *pdev, 229 struct pci_host_bridge *bridge, 230 const struct pci_ecam_ops *ops) 231 { 232 struct device *dev = &pdev->dev; 233 struct pci_config_window *cfg; 234 235 of_pci_check_probe_only(); 236 237 platform_set_drvdata(pdev, bridge); 238 239 /* Parse and map our Configuration Space windows */ 240 cfg = pci_host_common_ecam_create(dev, bridge, ops); 241 if (IS_ERR(cfg)) 242 return PTR_ERR(cfg); 243 244 /* Do not reassign bus numbers if probe only */ 245 if (!pci_has_flag(PCI_PROBE_ONLY)) 246 pci_add_flags(PCI_REASSIGN_ALL_BUS); 247 248 bridge->sysdata = cfg; 249 bridge->ops = (struct pci_ops *)&ops->pci_ops; 250 bridge->enable_device = ops->enable_device; 251 bridge->disable_device = ops->disable_device; 252 bridge->msi_domain = true; 253 254 return pci_host_probe(bridge); 255 } 256 EXPORT_SYMBOL_GPL(pci_host_common_init); 257 258 int pci_host_common_probe(struct platform_device *pdev) 259 { 260 const struct pci_ecam_ops *ops; 261 struct pci_host_bridge *bridge; 262 263 ops = of_device_get_match_data(&pdev->dev); 264 if (!ops) 265 return -ENODEV; 266 267 bridge = devm_pci_alloc_host_bridge(&pdev->dev, 0); 268 if (!bridge) 269 return -ENOMEM; 270 271 return pci_host_common_init(pdev, bridge, ops); 272 } 273 EXPORT_SYMBOL_GPL(pci_host_common_probe); 274 275 void pci_host_common_remove(struct platform_device *pdev) 276 { 277 struct pci_host_bridge *bridge = platform_get_drvdata(pdev); 278 279 pci_lock_rescan_remove(); 280 pci_stop_root_bus(bridge->bus); 281 pci_remove_root_bus(bridge->bus); 282 pci_unlock_rescan_remove(); 283 } 284 EXPORT_SYMBOL_GPL(pci_host_common_remove); 285 286 static int __pci_host_common_d3cold_possible(struct pci_dev *pdev, 287 void *userdata) 288 { 289 u32 *flags = userdata; 290 291 if (!pdev->dev.driver && !pci_is_enabled(pdev)) 292 return 0; 293 294 if (pdev->current_state != PCI_D3hot) 295 goto exit; 296 297 if (device_may_wakeup(&pdev->dev)) { 298 if (!pci_pme_capable(pdev, PCI_D3cold)) 299 goto exit; 300 else 301 *flags |= PCI_HOST_PME_D3COLD_CAPABLE; 302 } 303 304 return 0; 305 306 exit: 307 *flags &= ~PCI_HOST_D3COLD_ALLOWED; 308 309 return -EOPNOTSUPP; 310 } 311 312 /** 313 * pci_host_common_d3cold_possible - Determine whether the host bridge can 314 * transition the devices into D3cold. 315 * 316 * @bridge: PCI host bridge to check 317 * @pme_capable: Pointer to update if there is any device capable of generating 318 * PME from D3cold. 319 * 320 * Walk downstream PCIe endpoint devices and determine whether the host bridge 321 * is permitted to transition the devices into D3cold. 322 * 323 * Devices under host bridge can enter D3cold only if all active PCIe 324 * endpoints are in PCI_D3hot and any wakeup-enabled endpoint is capable of 325 * generating PME from D3cold. Inactive endpoints are ignored. 326 * 327 * The @pme_capable output allows PCIe controller drivers to apply 328 * platform-specific handling to preserve wakeup functionality. 329 * 330 * Return: %true if the host bridge may enter D3cold, otherwise %false. 331 */ 332 bool pci_host_common_d3cold_possible(struct pci_host_bridge *bridge, 333 bool *pme_capable) 334 { 335 u32 flags = PCI_HOST_D3COLD_ALLOWED; 336 337 pci_walk_bus(bridge->bus, __pci_host_common_d3cold_possible, &flags); 338 339 *pme_capable = !!(flags & PCI_HOST_PME_D3COLD_CAPABLE); 340 341 return !!(flags & PCI_HOST_D3COLD_ALLOWED); 342 } 343 EXPORT_SYMBOL_GPL(pci_host_common_d3cold_possible); 344 345 MODULE_DESCRIPTION("Common library for PCI host controller drivers"); 346 MODULE_LICENSE("GPL v2"); 347