1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * PCI Express Hot Plug Controller Driver 4 * 5 * Copyright (C) 1995,2001 Compaq Computer Corporation 6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 7 * Copyright (C) 2001 IBM Corp. 8 * Copyright (C) 2003-2004 Intel Corporation 9 * 10 * All rights reserved. 11 * 12 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> 13 * 14 * Authors: 15 * Dan Zink <dan.zink@compaq.com> 16 * Greg Kroah-Hartman <greg@kroah.com> 17 * Dely Sy <dely.l.sy@intel.com>" 18 */ 19 20 #define pr_fmt(fmt) "pciehp: " fmt 21 #define dev_fmt pr_fmt 22 23 #include <linux/bitfield.h> 24 #include <linux/moduleparam.h> 25 #include <linux/kernel.h> 26 #include <linux/slab.h> 27 #include <linux/types.h> 28 #include <linux/pci.h> 29 #include "pciehp.h" 30 31 #include "../pci.h" 32 33 /* Global variables */ 34 bool pciehp_poll_mode; 35 int pciehp_poll_time; 36 37 /* 38 * not really modular, but the easiest way to keep compat with existing 39 * bootargs behaviour is to continue using module_param here. 40 */ 41 module_param(pciehp_poll_mode, bool, 0644); 42 module_param(pciehp_poll_time, int, 0644); 43 MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 44 MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 45 46 static int set_attention_status(struct hotplug_slot *slot, u8 value); 47 static int get_power_status(struct hotplug_slot *slot, u8 *value); 48 static int get_latch_status(struct hotplug_slot *slot, u8 *value); 49 static int get_adapter_status(struct hotplug_slot *slot, u8 *value); 50 51 static int init_slot(struct controller *ctrl) 52 { 53 struct hotplug_slot_ops *ops; 54 char name[SLOT_NAME_SIZE]; 55 int retval; 56 57 /* Setup hotplug slot ops */ 58 ops = kzalloc(sizeof(*ops), GFP_KERNEL); 59 if (!ops) 60 return -ENOMEM; 61 62 ops->enable_slot = pciehp_sysfs_enable_slot; 63 ops->disable_slot = pciehp_sysfs_disable_slot; 64 ops->get_power_status = get_power_status; 65 ops->get_adapter_status = get_adapter_status; 66 ops->reset_slot = pciehp_reset_slot; 67 if (MRL_SENS(ctrl)) 68 ops->get_latch_status = get_latch_status; 69 if (ATTN_LED(ctrl)) { 70 ops->get_attention_status = pciehp_get_attention_status; 71 ops->set_attention_status = set_attention_status; 72 } else if (ctrl->pcie->port->hotplug_user_indicators) { 73 ops->get_attention_status = pciehp_get_raw_indicator_status; 74 ops->set_attention_status = pciehp_set_raw_indicator_status; 75 } 76 77 /* register this slot with the hotplug pci core */ 78 ctrl->hotplug_slot.ops = ops; 79 snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); 80 81 retval = pci_hp_initialize(&ctrl->hotplug_slot, 82 ctrl->pcie->port->subordinate, 0, name); 83 if (retval) { 84 ctrl_err(ctrl, "pci_hp_initialize failed: error %d\n", retval); 85 kfree(ops); 86 } 87 return retval; 88 } 89 90 static void cleanup_slot(struct controller *ctrl) 91 { 92 struct hotplug_slot *hotplug_slot = &ctrl->hotplug_slot; 93 94 pci_hp_destroy(hotplug_slot); 95 kfree(hotplug_slot->ops); 96 } 97 98 /* 99 * set_attention_status - Turns the Attention Indicator on, off or blinking 100 */ 101 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 102 { 103 struct controller *ctrl = to_ctrl(hotplug_slot); 104 struct pci_dev *pdev = ctrl->pcie->port; 105 106 if (status) 107 status = FIELD_PREP(PCI_EXP_SLTCTL_AIC, status); 108 else 109 status = PCI_EXP_SLTCTL_ATTN_IND_OFF; 110 111 pci_config_pm_runtime_get(pdev); 112 pciehp_set_indicators(ctrl, INDICATOR_NOOP, status); 113 pci_config_pm_runtime_put(pdev); 114 return 0; 115 } 116 117 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 118 { 119 struct controller *ctrl = to_ctrl(hotplug_slot); 120 struct pci_dev *pdev = ctrl->pcie->port; 121 122 pci_config_pm_runtime_get(pdev); 123 pciehp_get_power_status(ctrl, value); 124 pci_config_pm_runtime_put(pdev); 125 return 0; 126 } 127 128 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 129 { 130 struct controller *ctrl = to_ctrl(hotplug_slot); 131 struct pci_dev *pdev = ctrl->pcie->port; 132 133 pci_config_pm_runtime_get(pdev); 134 pciehp_get_latch_status(ctrl, value); 135 pci_config_pm_runtime_put(pdev); 136 return 0; 137 } 138 139 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 140 { 141 struct controller *ctrl = to_ctrl(hotplug_slot); 142 struct pci_dev *pdev = ctrl->pcie->port; 143 int ret; 144 145 pci_config_pm_runtime_get(pdev); 146 ret = pciehp_card_present_or_link_active(ctrl); 147 pci_config_pm_runtime_put(pdev); 148 if (ret < 0) 149 return ret; 150 151 *value = ret; 152 return 0; 153 } 154 155 /** 156 * pciehp_check_presence() - synthesize event if presence has changed 157 * @ctrl: controller to check 158 * 159 * On probe and resume, an explicit presence check is necessary to bring up an 160 * occupied slot or bring down an unoccupied slot. This can't be triggered by 161 * events in the Slot Status register, they may be stale and are therefore 162 * cleared. Secondly, sending an interrupt for "events that occur while 163 * interrupt generation is disabled [when] interrupt generation is subsequently 164 * enabled" is optional per PCIe r4.0, sec 6.7.3.4. 165 */ 166 static void pciehp_check_presence(struct controller *ctrl) 167 { 168 int occupied; 169 170 down_read_nested(&ctrl->reset_lock, ctrl->depth); 171 mutex_lock(&ctrl->state_lock); 172 173 occupied = pciehp_card_present_or_link_active(ctrl); 174 if ((occupied > 0 && (ctrl->state == OFF_STATE || 175 ctrl->state == BLINKINGON_STATE)) || 176 (!occupied && (ctrl->state == ON_STATE || 177 ctrl->state == BLINKINGOFF_STATE))) 178 pciehp_request(ctrl, PCI_EXP_SLTSTA_PDC); 179 180 mutex_unlock(&ctrl->state_lock); 181 up_read(&ctrl->reset_lock); 182 } 183 184 static int pciehp_probe(struct pcie_device *dev) 185 { 186 int rc; 187 struct controller *ctrl; 188 189 /* If this is not a "hotplug" service, we have no business here. */ 190 if (dev->service != PCIE_PORT_SERVICE_HP) 191 return -ENODEV; 192 193 if (!dev->port->subordinate) { 194 /* Can happen if we run out of bus numbers during probe */ 195 pci_err(dev->port, 196 "Hotplug bridge without secondary bus, ignoring\n"); 197 return -ENODEV; 198 } 199 200 ctrl = pcie_init(dev); 201 if (!ctrl) { 202 pci_err(dev->port, "Controller initialization failed\n"); 203 return -ENODEV; 204 } 205 set_service_data(dev, ctrl); 206 207 /* Setup the slot information structures */ 208 rc = init_slot(ctrl); 209 if (rc) { 210 if (rc == -EBUSY) 211 ctrl_warn(ctrl, "Slot already registered by another hotplug driver\n"); 212 else 213 ctrl_err(ctrl, "Slot initialization failed (%d)\n", rc); 214 goto err_out_release_ctlr; 215 } 216 217 /* Enable events after we have setup the data structures */ 218 rc = pcie_init_notification(ctrl); 219 if (rc) { 220 ctrl_err(ctrl, "Notification initialization failed (%d)\n", rc); 221 goto err_out_free_ctrl_slot; 222 } 223 224 /* Publish to user space */ 225 rc = pci_hp_add(&ctrl->hotplug_slot); 226 if (rc) { 227 ctrl_err(ctrl, "Publication to user space failed (%d)\n", rc); 228 goto err_out_shutdown_notification; 229 } 230 231 pciehp_check_presence(ctrl); 232 233 return 0; 234 235 err_out_shutdown_notification: 236 pcie_shutdown_notification(ctrl); 237 err_out_free_ctrl_slot: 238 cleanup_slot(ctrl); 239 err_out_release_ctlr: 240 pciehp_release_ctrl(ctrl); 241 return -ENODEV; 242 } 243 244 static void pciehp_remove(struct pcie_device *dev) 245 { 246 struct controller *ctrl = get_service_data(dev); 247 248 pci_hp_del(&ctrl->hotplug_slot); 249 pcie_shutdown_notification(ctrl); 250 cleanup_slot(ctrl); 251 pciehp_release_ctrl(ctrl); 252 } 253 254 #ifdef CONFIG_PM 255 static bool pme_is_native(struct pcie_device *dev) 256 { 257 const struct pci_host_bridge *host; 258 259 host = pci_find_host_bridge(dev->port->bus); 260 return pcie_ports_native || host->native_pme; 261 } 262 263 static void pciehp_disable_interrupt(struct pcie_device *dev) 264 { 265 /* 266 * Disable hotplug interrupt so that it does not trigger 267 * immediately when the downstream link goes down. 268 */ 269 if (pme_is_native(dev)) 270 pcie_disable_interrupt(get_service_data(dev)); 271 } 272 273 #ifdef CONFIG_PM_SLEEP 274 static int pciehp_suspend(struct pcie_device *dev) 275 { 276 /* 277 * If the port is already runtime suspended we can keep it that 278 * way. 279 */ 280 if (dev_pm_skip_suspend(&dev->port->dev)) 281 return 0; 282 283 pciehp_disable_interrupt(dev); 284 return 0; 285 } 286 287 static int pciehp_resume_noirq(struct pcie_device *dev) 288 { 289 struct controller *ctrl = get_service_data(dev); 290 291 /* pci_restore_state() just wrote to the Slot Control register */ 292 ctrl->cmd_started = jiffies; 293 ctrl->cmd_busy = true; 294 295 /* clear spurious events from rediscovery of inserted card */ 296 if (ctrl->state == ON_STATE || ctrl->state == BLINKINGOFF_STATE) 297 pcie_clear_hotplug_events(ctrl); 298 299 return 0; 300 } 301 #endif 302 303 static int pciehp_resume(struct pcie_device *dev) 304 { 305 struct controller *ctrl = get_service_data(dev); 306 307 if (pme_is_native(dev)) 308 pcie_enable_interrupt(ctrl); 309 310 pciehp_check_presence(ctrl); 311 312 return 0; 313 } 314 315 static int pciehp_runtime_suspend(struct pcie_device *dev) 316 { 317 pciehp_disable_interrupt(dev); 318 return 0; 319 } 320 321 static int pciehp_runtime_resume(struct pcie_device *dev) 322 { 323 struct controller *ctrl = get_service_data(dev); 324 325 /* pci_restore_state() just wrote to the Slot Control register */ 326 ctrl->cmd_started = jiffies; 327 ctrl->cmd_busy = true; 328 329 /* clear spurious events from rediscovery of inserted card */ 330 if ((ctrl->state == ON_STATE || ctrl->state == BLINKINGOFF_STATE) && 331 pme_is_native(dev)) 332 pcie_clear_hotplug_events(ctrl); 333 334 return pciehp_resume(dev); 335 } 336 #endif /* PM */ 337 338 static struct pcie_port_service_driver hpdriver_portdrv = { 339 .name = "pciehp", 340 .port_type = PCIE_ANY_PORT, 341 .service = PCIE_PORT_SERVICE_HP, 342 343 .probe = pciehp_probe, 344 .remove = pciehp_remove, 345 346 #ifdef CONFIG_PM 347 #ifdef CONFIG_PM_SLEEP 348 .suspend = pciehp_suspend, 349 .resume_noirq = pciehp_resume_noirq, 350 .resume = pciehp_resume, 351 #endif 352 .runtime_suspend = pciehp_runtime_suspend, 353 .runtime_resume = pciehp_runtime_resume, 354 #endif /* PM */ 355 356 .slot_reset = pciehp_slot_reset, 357 }; 358 359 int __init pcie_hp_init(void) 360 { 361 int retval = 0; 362 363 retval = pcie_port_service_register(&hpdriver_portdrv); 364 pr_debug("pcie_port_service_register = %d\n", retval); 365 if (retval) 366 pr_debug("Failure to register service\n"); 367 368 return retval; 369 } 370