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 /* Global variables */ 30 bool pciehp_debug; 31 bool pciehp_poll_mode; 32 int pciehp_poll_time; 33 static bool pciehp_force; 34 35 /* 36 * not really modular, but the easiest way to keep compat with existing 37 * bootargs behaviour is to continue using module_param here. 38 */ 39 module_param(pciehp_debug, bool, 0644); 40 module_param(pciehp_poll_mode, bool, 0644); 41 module_param(pciehp_poll_time, int, 0644); 42 module_param(pciehp_force, bool, 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 MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing"); 47 48 #define PCIE_MODULE_NAME "pciehp" 49 50 static int set_attention_status(struct hotplug_slot *slot, u8 value); 51 static int enable_slot(struct hotplug_slot *slot); 52 static int disable_slot(struct hotplug_slot *slot); 53 static int get_power_status(struct hotplug_slot *slot, u8 *value); 54 static int get_attention_status(struct hotplug_slot *slot, u8 *value); 55 static int get_latch_status(struct hotplug_slot *slot, u8 *value); 56 static int get_adapter_status(struct hotplug_slot *slot, u8 *value); 57 static int reset_slot(struct hotplug_slot *slot, int probe); 58 59 /** 60 * release_slot - free up the memory used by a slot 61 * @hotplug_slot: slot to free 62 */ 63 static void release_slot(struct hotplug_slot *hotplug_slot) 64 { 65 kfree(hotplug_slot->ops); 66 kfree(hotplug_slot->info); 67 kfree(hotplug_slot); 68 } 69 70 static int init_slot(struct controller *ctrl) 71 { 72 struct slot *slot = ctrl->slot; 73 struct hotplug_slot *hotplug = NULL; 74 struct hotplug_slot_info *info = NULL; 75 struct hotplug_slot_ops *ops = NULL; 76 char name[SLOT_NAME_SIZE]; 77 int retval = -ENOMEM; 78 79 hotplug = kzalloc(sizeof(*hotplug), GFP_KERNEL); 80 if (!hotplug) 81 goto out; 82 83 info = kzalloc(sizeof(*info), GFP_KERNEL); 84 if (!info) 85 goto out; 86 87 /* Setup hotplug slot ops */ 88 ops = kzalloc(sizeof(*ops), GFP_KERNEL); 89 if (!ops) 90 goto out; 91 92 ops->enable_slot = enable_slot; 93 ops->disable_slot = disable_slot; 94 ops->get_power_status = get_power_status; 95 ops->get_adapter_status = get_adapter_status; 96 ops->reset_slot = reset_slot; 97 if (MRL_SENS(ctrl)) 98 ops->get_latch_status = get_latch_status; 99 if (ATTN_LED(ctrl)) { 100 ops->get_attention_status = get_attention_status; 101 ops->set_attention_status = set_attention_status; 102 } else if (ctrl->pcie->port->hotplug_user_indicators) { 103 ops->get_attention_status = pciehp_get_raw_indicator_status; 104 ops->set_attention_status = pciehp_set_raw_indicator_status; 105 } 106 107 /* register this slot with the hotplug pci core */ 108 hotplug->info = info; 109 hotplug->private = slot; 110 hotplug->release = &release_slot; 111 hotplug->ops = ops; 112 slot->hotplug_slot = hotplug; 113 snprintf(name, SLOT_NAME_SIZE, "%u", PSN(ctrl)); 114 115 retval = pci_hp_register(hotplug, 116 ctrl->pcie->port->subordinate, 0, name); 117 if (retval) 118 ctrl_err(ctrl, "pci_hp_register failed: error %d\n", retval); 119 out: 120 if (retval) { 121 kfree(ops); 122 kfree(info); 123 kfree(hotplug); 124 } 125 return retval; 126 } 127 128 static void cleanup_slot(struct controller *ctrl) 129 { 130 pci_hp_deregister(ctrl->slot->hotplug_slot); 131 } 132 133 /* 134 * set_attention_status - Turns the Amber LED for a slot on, off or blink 135 */ 136 static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) 137 { 138 struct slot *slot = hotplug_slot->private; 139 140 pciehp_set_attention_status(slot, status); 141 return 0; 142 } 143 144 145 static int enable_slot(struct hotplug_slot *hotplug_slot) 146 { 147 struct slot *slot = hotplug_slot->private; 148 149 return pciehp_sysfs_enable_slot(slot); 150 } 151 152 153 static int disable_slot(struct hotplug_slot *hotplug_slot) 154 { 155 struct slot *slot = hotplug_slot->private; 156 157 return pciehp_sysfs_disable_slot(slot); 158 } 159 160 static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 161 { 162 struct slot *slot = hotplug_slot->private; 163 164 pciehp_get_power_status(slot, value); 165 return 0; 166 } 167 168 static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) 169 { 170 struct slot *slot = hotplug_slot->private; 171 172 pciehp_get_attention_status(slot, value); 173 return 0; 174 } 175 176 static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value) 177 { 178 struct slot *slot = hotplug_slot->private; 179 180 pciehp_get_latch_status(slot, value); 181 return 0; 182 } 183 184 static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 185 { 186 struct slot *slot = hotplug_slot->private; 187 188 pciehp_get_adapter_status(slot, value); 189 return 0; 190 } 191 192 static int reset_slot(struct hotplug_slot *hotplug_slot, int probe) 193 { 194 struct slot *slot = hotplug_slot->private; 195 196 return pciehp_reset_slot(slot, probe); 197 } 198 199 static int pciehp_probe(struct pcie_device *dev) 200 { 201 int rc; 202 struct controller *ctrl; 203 struct slot *slot; 204 u8 occupied, poweron; 205 206 /* If this is not a "hotplug" service, we have no business here. */ 207 if (dev->service != PCIE_PORT_SERVICE_HP) 208 return -ENODEV; 209 210 if (!dev->port->subordinate) { 211 /* Can happen if we run out of bus numbers during probe */ 212 dev_err(&dev->device, 213 "Hotplug bridge without secondary bus, ignoring\n"); 214 return -ENODEV; 215 } 216 217 ctrl = pcie_init(dev); 218 if (!ctrl) { 219 dev_err(&dev->device, "Controller initialization failed\n"); 220 return -ENODEV; 221 } 222 set_service_data(dev, ctrl); 223 224 /* Setup the slot information structures */ 225 rc = init_slot(ctrl); 226 if (rc) { 227 if (rc == -EBUSY) 228 ctrl_warn(ctrl, "Slot already registered by another hotplug driver\n"); 229 else 230 ctrl_err(ctrl, "Slot initialization failed (%d)\n", rc); 231 goto err_out_release_ctlr; 232 } 233 234 /* Enable events after we have setup the data structures */ 235 rc = pcie_init_notification(ctrl); 236 if (rc) { 237 ctrl_err(ctrl, "Notification initialization failed (%d)\n", rc); 238 goto err_out_free_ctrl_slot; 239 } 240 241 /* Check if slot is occupied */ 242 slot = ctrl->slot; 243 pciehp_get_adapter_status(slot, &occupied); 244 pciehp_get_power_status(slot, &poweron); 245 if (occupied && pciehp_force) { 246 mutex_lock(&slot->hotplug_lock); 247 pciehp_enable_slot(slot); 248 mutex_unlock(&slot->hotplug_lock); 249 } 250 /* If empty slot's power status is on, turn power off */ 251 if (!occupied && poweron && POWER_CTRL(ctrl)) 252 pciehp_power_off_slot(slot); 253 254 return 0; 255 256 err_out_free_ctrl_slot: 257 cleanup_slot(ctrl); 258 err_out_release_ctlr: 259 pciehp_release_ctrl(ctrl); 260 return -ENODEV; 261 } 262 263 static void pciehp_remove(struct pcie_device *dev) 264 { 265 struct controller *ctrl = get_service_data(dev); 266 267 cleanup_slot(ctrl); 268 pciehp_release_ctrl(ctrl); 269 } 270 271 #ifdef CONFIG_PM 272 static int pciehp_suspend(struct pcie_device *dev) 273 { 274 return 0; 275 } 276 277 static int pciehp_resume(struct pcie_device *dev) 278 { 279 struct controller *ctrl; 280 struct slot *slot; 281 u8 status; 282 283 ctrl = get_service_data(dev); 284 285 /* reinitialize the chipset's event detection logic */ 286 pcie_enable_notification(ctrl); 287 288 slot = ctrl->slot; 289 290 /* Check if slot is occupied */ 291 pciehp_get_adapter_status(slot, &status); 292 mutex_lock(&slot->hotplug_lock); 293 if (status) 294 pciehp_enable_slot(slot); 295 else 296 pciehp_disable_slot(slot); 297 mutex_unlock(&slot->hotplug_lock); 298 return 0; 299 } 300 #endif /* PM */ 301 302 static struct pcie_port_service_driver hpdriver_portdrv = { 303 .name = PCIE_MODULE_NAME, 304 .port_type = PCIE_ANY_PORT, 305 .service = PCIE_PORT_SERVICE_HP, 306 307 .probe = pciehp_probe, 308 .remove = pciehp_remove, 309 310 #ifdef CONFIG_PM 311 .suspend = pciehp_suspend, 312 .resume = pciehp_resume, 313 #endif /* PM */ 314 }; 315 316 static int __init pcied_init(void) 317 { 318 int retval = 0; 319 320 retval = pcie_port_service_register(&hpdriver_portdrv); 321 dbg("pcie_port_service_register = %d\n", retval); 322 if (retval) 323 dbg("Failure to register service\n"); 324 325 return retval; 326 } 327 device_initcall(pcied_init); 328