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