1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (C) 2024 Marvell. */ 3 4 #include <linux/cleanup.h> 5 #include <linux/container_of.h> 6 #include <linux/delay.h> 7 #include <linux/dev_printk.h> 8 #include <linux/init.h> 9 #include <linux/interrupt.h> 10 #include <linux/io-64-nonatomic-lo-hi.h> 11 #include <linux/kernel.h> 12 #include <linux/list.h> 13 #include <linux/module.h> 14 #include <linux/mutex.h> 15 #include <linux/pci.h> 16 #include <linux/pci_hotplug.h> 17 #include <linux/slab.h> 18 #include <linux/spinlock.h> 19 #include <linux/workqueue.h> 20 21 #define OCTEP_HP_INTR_OFFSET(x) (0x20400 + ((x) << 4)) 22 #define OCTEP_HP_INTR_VECTOR(x) (16 + (x)) 23 #define OCTEP_HP_DRV_NAME "octep_hp" 24 25 /* 26 * Type of MSI-X interrupts. OCTEP_HP_INTR_VECTOR() and 27 * OCTEP_HP_INTR_OFFSET() generate the vector and offset for an interrupt 28 * type. 29 */ 30 enum octep_hp_intr_type { 31 OCTEP_HP_INTR_INVALID = -1, 32 OCTEP_HP_INTR_ENA = 0, 33 OCTEP_HP_INTR_DIS = 1, 34 OCTEP_HP_INTR_MAX = 2, 35 }; 36 37 struct octep_hp_cmd { 38 struct list_head list; 39 enum octep_hp_intr_type intr_type; 40 u64 intr_val; 41 }; 42 43 struct octep_hp_slot { 44 struct list_head list; 45 struct hotplug_slot slot; 46 u16 slot_number; 47 struct pci_dev *hp_pdev; 48 unsigned int hp_devfn; 49 struct octep_hp_controller *ctrl; 50 }; 51 52 struct octep_hp_intr_info { 53 enum octep_hp_intr_type type; 54 int number; 55 char name[16]; 56 }; 57 58 struct octep_hp_controller { 59 void __iomem *base; 60 struct pci_dev *pdev; 61 struct octep_hp_intr_info intr[OCTEP_HP_INTR_MAX]; 62 struct work_struct work; 63 struct list_head slot_list; 64 struct mutex slot_lock; /* Protects slot_list */ 65 struct list_head hp_cmd_list; 66 spinlock_t hp_cmd_lock; /* Protects hp_cmd_list */ 67 }; 68 69 static void octep_hp_enable_pdev(struct octep_hp_controller *hp_ctrl, 70 struct octep_hp_slot *hp_slot) 71 { 72 guard(mutex)(&hp_ctrl->slot_lock); 73 if (hp_slot->hp_pdev) { 74 pci_dbg(hp_slot->hp_pdev, "Slot %s is already enabled\n", 75 hotplug_slot_name(&hp_slot->slot)); 76 return; 77 } 78 79 /* Scan the device and add it to the bus */ 80 hp_slot->hp_pdev = pci_scan_single_device(hp_ctrl->pdev->bus, 81 hp_slot->hp_devfn); 82 pci_bus_assign_resources(hp_ctrl->pdev->bus); 83 pci_bus_add_device(hp_slot->hp_pdev); 84 85 dev_dbg(&hp_slot->hp_pdev->dev, "Enabled slot %s\n", 86 hotplug_slot_name(&hp_slot->slot)); 87 } 88 89 static void octep_hp_disable_pdev(struct octep_hp_controller *hp_ctrl, 90 struct octep_hp_slot *hp_slot) 91 { 92 guard(mutex)(&hp_ctrl->slot_lock); 93 if (!hp_slot->hp_pdev) { 94 pci_dbg(hp_ctrl->pdev, "Slot %s is already disabled\n", 95 hotplug_slot_name(&hp_slot->slot)); 96 return; 97 } 98 99 pci_dbg(hp_slot->hp_pdev, "Disabling slot %s\n", 100 hotplug_slot_name(&hp_slot->slot)); 101 102 /* Remove the device from the bus */ 103 pci_stop_and_remove_bus_device_locked(hp_slot->hp_pdev); 104 hp_slot->hp_pdev = NULL; 105 } 106 107 static int octep_hp_enable_slot(struct hotplug_slot *slot) 108 { 109 struct octep_hp_slot *hp_slot = 110 container_of(slot, struct octep_hp_slot, slot); 111 112 octep_hp_enable_pdev(hp_slot->ctrl, hp_slot); 113 return 0; 114 } 115 116 static int octep_hp_disable_slot(struct hotplug_slot *slot) 117 { 118 struct octep_hp_slot *hp_slot = 119 container_of(slot, struct octep_hp_slot, slot); 120 121 octep_hp_disable_pdev(hp_slot->ctrl, hp_slot); 122 return 0; 123 } 124 125 static struct hotplug_slot_ops octep_hp_slot_ops = { 126 .enable_slot = octep_hp_enable_slot, 127 .disable_slot = octep_hp_disable_slot, 128 }; 129 130 #define SLOT_NAME_SIZE 16 131 static struct octep_hp_slot * 132 octep_hp_register_slot(struct octep_hp_controller *hp_ctrl, 133 struct pci_dev *pdev, u16 slot_number) 134 { 135 char slot_name[SLOT_NAME_SIZE]; 136 struct octep_hp_slot *hp_slot; 137 int ret; 138 139 hp_slot = kzalloc(sizeof(*hp_slot), GFP_KERNEL); 140 if (!hp_slot) 141 return ERR_PTR(-ENOMEM); 142 143 hp_slot->ctrl = hp_ctrl; 144 hp_slot->hp_pdev = pdev; 145 hp_slot->hp_devfn = pdev->devfn; 146 hp_slot->slot_number = slot_number; 147 hp_slot->slot.ops = &octep_hp_slot_ops; 148 149 snprintf(slot_name, sizeof(slot_name), "octep_hp_%u", slot_number); 150 ret = pci_hp_register(&hp_slot->slot, hp_ctrl->pdev->bus, 151 PCI_SLOT(pdev->devfn), slot_name); 152 if (ret) { 153 kfree(hp_slot); 154 return ERR_PTR(ret); 155 } 156 157 pci_info(pdev, "Registered slot %s for device %s\n", 158 slot_name, pci_name(pdev)); 159 160 list_add_tail(&hp_slot->list, &hp_ctrl->slot_list); 161 octep_hp_disable_pdev(hp_ctrl, hp_slot); 162 163 return hp_slot; 164 } 165 166 static void octep_hp_deregister_slot(void *data) 167 { 168 struct octep_hp_slot *hp_slot = data; 169 struct octep_hp_controller *hp_ctrl = hp_slot->ctrl; 170 171 pci_hp_deregister(&hp_slot->slot); 172 octep_hp_enable_pdev(hp_ctrl, hp_slot); 173 list_del(&hp_slot->list); 174 kfree(hp_slot); 175 } 176 177 static const char *octep_hp_cmd_name(enum octep_hp_intr_type type) 178 { 179 switch (type) { 180 case OCTEP_HP_INTR_ENA: 181 return "hotplug enable"; 182 case OCTEP_HP_INTR_DIS: 183 return "hotplug disable"; 184 default: 185 return "invalid"; 186 } 187 } 188 189 static void octep_hp_cmd_handler(struct octep_hp_controller *hp_ctrl, 190 struct octep_hp_cmd *hp_cmd) 191 { 192 struct octep_hp_slot *hp_slot; 193 194 /* 195 * Enable or disable the slots based on the slot mask. 196 * intr_val is a bit mask where each bit represents a slot. 197 */ 198 list_for_each_entry(hp_slot, &hp_ctrl->slot_list, list) { 199 if (!(hp_cmd->intr_val & BIT(hp_slot->slot_number))) 200 continue; 201 202 pci_info(hp_ctrl->pdev, "Received %s command for slot %s\n", 203 octep_hp_cmd_name(hp_cmd->intr_type), 204 hotplug_slot_name(&hp_slot->slot)); 205 206 switch (hp_cmd->intr_type) { 207 case OCTEP_HP_INTR_ENA: 208 octep_hp_enable_pdev(hp_ctrl, hp_slot); 209 break; 210 case OCTEP_HP_INTR_DIS: 211 octep_hp_disable_pdev(hp_ctrl, hp_slot); 212 break; 213 default: 214 break; 215 } 216 } 217 } 218 219 static void octep_hp_work_handler(struct work_struct *work) 220 { 221 struct octep_hp_controller *hp_ctrl; 222 struct octep_hp_cmd *hp_cmd; 223 unsigned long flags; 224 225 hp_ctrl = container_of(work, struct octep_hp_controller, work); 226 227 /* Process all the hotplug commands */ 228 spin_lock_irqsave(&hp_ctrl->hp_cmd_lock, flags); 229 while (!list_empty(&hp_ctrl->hp_cmd_list)) { 230 hp_cmd = list_first_entry(&hp_ctrl->hp_cmd_list, 231 struct octep_hp_cmd, list); 232 list_del(&hp_cmd->list); 233 spin_unlock_irqrestore(&hp_ctrl->hp_cmd_lock, flags); 234 235 octep_hp_cmd_handler(hp_ctrl, hp_cmd); 236 kfree(hp_cmd); 237 238 spin_lock_irqsave(&hp_ctrl->hp_cmd_lock, flags); 239 } 240 spin_unlock_irqrestore(&hp_ctrl->hp_cmd_lock, flags); 241 } 242 243 static enum octep_hp_intr_type octep_hp_intr_type(struct octep_hp_intr_info *intr, 244 int irq) 245 { 246 enum octep_hp_intr_type type; 247 248 for (type = OCTEP_HP_INTR_ENA; type < OCTEP_HP_INTR_MAX; type++) { 249 if (intr[type].number == irq) 250 return type; 251 } 252 253 return OCTEP_HP_INTR_INVALID; 254 } 255 256 static irqreturn_t octep_hp_intr_handler(int irq, void *data) 257 { 258 struct octep_hp_controller *hp_ctrl = data; 259 struct pci_dev *pdev = hp_ctrl->pdev; 260 enum octep_hp_intr_type type; 261 struct octep_hp_cmd *hp_cmd; 262 u64 intr_val; 263 264 type = octep_hp_intr_type(hp_ctrl->intr, irq); 265 if (type == OCTEP_HP_INTR_INVALID) { 266 pci_err(pdev, "Invalid interrupt %d\n", irq); 267 return IRQ_HANDLED; 268 } 269 270 /* Read and clear the interrupt */ 271 intr_val = readq(hp_ctrl->base + OCTEP_HP_INTR_OFFSET(type)); 272 writeq(intr_val, hp_ctrl->base + OCTEP_HP_INTR_OFFSET(type)); 273 274 hp_cmd = kzalloc(sizeof(*hp_cmd), GFP_ATOMIC); 275 if (!hp_cmd) 276 return IRQ_HANDLED; 277 278 hp_cmd->intr_val = intr_val; 279 hp_cmd->intr_type = type; 280 281 /* Add the command to the list and schedule the work */ 282 spin_lock(&hp_ctrl->hp_cmd_lock); 283 list_add_tail(&hp_cmd->list, &hp_ctrl->hp_cmd_list); 284 spin_unlock(&hp_ctrl->hp_cmd_lock); 285 schedule_work(&hp_ctrl->work); 286 287 return IRQ_HANDLED; 288 } 289 290 static void octep_hp_irq_cleanup(void *data) 291 { 292 struct octep_hp_controller *hp_ctrl = data; 293 294 pci_free_irq_vectors(hp_ctrl->pdev); 295 flush_work(&hp_ctrl->work); 296 } 297 298 static int octep_hp_request_irq(struct octep_hp_controller *hp_ctrl, 299 enum octep_hp_intr_type type) 300 { 301 struct pci_dev *pdev = hp_ctrl->pdev; 302 struct octep_hp_intr_info *intr; 303 int irq; 304 305 irq = pci_irq_vector(pdev, OCTEP_HP_INTR_VECTOR(type)); 306 if (irq < 0) 307 return irq; 308 309 intr = &hp_ctrl->intr[type]; 310 intr->number = irq; 311 intr->type = type; 312 snprintf(intr->name, sizeof(intr->name), "octep_hp_%d", type); 313 314 return devm_request_irq(&pdev->dev, irq, octep_hp_intr_handler, 315 IRQF_SHARED, intr->name, hp_ctrl); 316 } 317 318 static int octep_hp_controller_setup(struct pci_dev *pdev, 319 struct octep_hp_controller *hp_ctrl) 320 { 321 struct device *dev = &pdev->dev; 322 enum octep_hp_intr_type type; 323 int ret; 324 325 ret = pcim_enable_device(pdev); 326 if (ret) 327 return dev_err_probe(dev, ret, "Failed to enable PCI device\n"); 328 329 hp_ctrl->base = pcim_iomap_region(pdev, 0, OCTEP_HP_DRV_NAME); 330 if (IS_ERR(hp_ctrl->base)) 331 return dev_err_probe(dev, PTR_ERR(hp_ctrl->base), 332 "Failed to map PCI device region\n"); 333 334 pci_set_master(pdev); 335 pci_set_drvdata(pdev, hp_ctrl); 336 337 INIT_LIST_HEAD(&hp_ctrl->slot_list); 338 INIT_LIST_HEAD(&hp_ctrl->hp_cmd_list); 339 mutex_init(&hp_ctrl->slot_lock); 340 spin_lock_init(&hp_ctrl->hp_cmd_lock); 341 INIT_WORK(&hp_ctrl->work, octep_hp_work_handler); 342 hp_ctrl->pdev = pdev; 343 344 ret = pci_alloc_irq_vectors(pdev, 1, 345 OCTEP_HP_INTR_VECTOR(OCTEP_HP_INTR_MAX), 346 PCI_IRQ_MSIX); 347 if (ret < 0) 348 return dev_err_probe(dev, ret, "Failed to alloc MSI-X vectors\n"); 349 350 ret = devm_add_action(&pdev->dev, octep_hp_irq_cleanup, hp_ctrl); 351 if (ret) 352 return dev_err_probe(&pdev->dev, ret, "Failed to add IRQ cleanup action\n"); 353 354 for (type = OCTEP_HP_INTR_ENA; type < OCTEP_HP_INTR_MAX; type++) { 355 ret = octep_hp_request_irq(hp_ctrl, type); 356 if (ret) 357 return dev_err_probe(dev, ret, 358 "Failed to request IRQ for vector %d\n", 359 OCTEP_HP_INTR_VECTOR(type)); 360 } 361 362 return 0; 363 } 364 365 static int octep_hp_pci_probe(struct pci_dev *pdev, 366 const struct pci_device_id *id) 367 { 368 struct octep_hp_controller *hp_ctrl; 369 struct pci_dev *tmp_pdev, *next; 370 struct octep_hp_slot *hp_slot; 371 u16 slot_number = 0; 372 int ret; 373 374 hp_ctrl = devm_kzalloc(&pdev->dev, sizeof(*hp_ctrl), GFP_KERNEL); 375 if (!hp_ctrl) 376 return -ENOMEM; 377 378 ret = octep_hp_controller_setup(pdev, hp_ctrl); 379 if (ret) 380 return ret; 381 382 /* 383 * Register all hotplug slots. Hotplug controller is the first function 384 * of the PCI device. The hotplug slots are the remaining functions of 385 * the PCI device. The hotplug slot functions are logically removed from 386 * the bus during probing and are re-enabled by the driver when a 387 * hotplug event is received. 388 */ 389 list_for_each_entry_safe(tmp_pdev, next, &pdev->bus->devices, bus_list) { 390 if (tmp_pdev == pdev) 391 continue; 392 393 hp_slot = octep_hp_register_slot(hp_ctrl, tmp_pdev, slot_number); 394 if (IS_ERR(hp_slot)) 395 return dev_err_probe(&pdev->dev, PTR_ERR(hp_slot), 396 "Failed to register hotplug slot %u\n", 397 slot_number); 398 399 ret = devm_add_action(&pdev->dev, octep_hp_deregister_slot, 400 hp_slot); 401 if (ret) 402 return dev_err_probe(&pdev->dev, ret, 403 "Failed to add action for deregistering slot %u\n", 404 slot_number); 405 slot_number++; 406 } 407 408 return 0; 409 } 410 411 #define PCI_DEVICE_ID_CAVIUM_OCTEP_HP_CTLR 0xa0e3 412 static struct pci_device_id octep_hp_pci_map[] = { 413 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVICE_ID_CAVIUM_OCTEP_HP_CTLR) }, 414 { }, 415 }; 416 417 static struct pci_driver octep_hp = { 418 .name = OCTEP_HP_DRV_NAME, 419 .id_table = octep_hp_pci_map, 420 .probe = octep_hp_pci_probe, 421 }; 422 423 module_pci_driver(octep_hp); 424 425 MODULE_LICENSE("GPL"); 426 MODULE_AUTHOR("Marvell"); 427 MODULE_DESCRIPTION("Marvell OCTEON PCI Hotplug driver"); 428