1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * PCI Hotplug Driver for PowerPC PowerNV platform.
4 *
5 * Copyright Gavin Shan, IBM Corporation 2016.
6 */
7
8#include <linux/bitfield.h>
9#include <linux/libfdt.h>
10#include <linux/module.h>
11#include <linux/pci.h>
12#include <linux/pci_hotplug.h>
13#include <linux/of_fdt.h>
14
15#include <asm/opal.h>
16#include <asm/pnv-pci.h>
17#include <asm/ppc-pci.h>
18
19#define DRIVER_VERSION "0.1"
20#define DRIVER_AUTHOR "Gavin Shan, IBM Corporation"
21#define DRIVER_DESC "PowerPC PowerNV PCI Hotplug Driver"
22
23#define SLOT_WARN(sl, x...) \
24 ((sl)->pdev ? pci_warn((sl)->pdev, x) : dev_warn(&(sl)->bus->dev, x))
25
26struct pnv_php_event {
27 bool added;
28 struct pnv_php_slot *php_slot;
29 struct work_struct work;
30};
31
32static LIST_HEAD(pnv_php_slot_list);
33static DEFINE_SPINLOCK(pnv_php_lock);
34
35static void pnv_php_register(struct device_node *dn);
36static void pnv_php_unregister_one(struct device_node *dn);
37static void pnv_php_unregister(struct device_node *dn);
38
39static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
40 bool disable_device)
41{
42 struct pci_dev *pdev = php_slot->pdev;
43 int irq = php_slot->irq;
44 u16 ctrl;
45
46 if (php_slot->irq > 0) {
47 pcie_capability_read_word(dev: pdev, PCI_EXP_SLTCTL, val: &ctrl);
48 ctrl &= ~(PCI_EXP_SLTCTL_HPIE |
49 PCI_EXP_SLTCTL_PDCE |
50 PCI_EXP_SLTCTL_DLLSCE);
51 pcie_capability_write_word(dev: pdev, PCI_EXP_SLTCTL, val: ctrl);
52
53 free_irq(php_slot->irq, php_slot);
54 php_slot->irq = 0;
55 }
56
57 if (php_slot->wq) {
58 destroy_workqueue(wq: php_slot->wq);
59 php_slot->wq = NULL;
60 }
61
62 if (disable_device || irq > 0) {
63 if (pdev->msix_enabled)
64 pci_disable_msix(dev: pdev);
65 else if (pdev->msi_enabled)
66 pci_disable_msi(dev: pdev);
67
68 pci_disable_device(dev: pdev);
69 }
70}
71
72static void pnv_php_free_slot(struct kref *kref)
73{
74 struct pnv_php_slot *php_slot = container_of(kref,
75 struct pnv_php_slot, kref);
76
77 WARN_ON(!list_empty(&php_slot->children));
78 pnv_php_disable_irq(php_slot, disable_device: false);
79 kfree(objp: php_slot->name);
80 kfree(objp: php_slot);
81}
82
83static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot)
84{
85
86 if (!php_slot)
87 return;
88
89 kref_put(kref: &php_slot->kref, release: pnv_php_free_slot);
90}
91
92static struct pnv_php_slot *pnv_php_match(struct device_node *dn,
93 struct pnv_php_slot *php_slot)
94{
95 struct pnv_php_slot *target, *tmp;
96
97 if (php_slot->dn == dn) {
98 kref_get(kref: &php_slot->kref);
99 return php_slot;
100 }
101
102 list_for_each_entry(tmp, &php_slot->children, link) {
103 target = pnv_php_match(dn, php_slot: tmp);
104 if (target)
105 return target;
106 }
107
108 return NULL;
109}
110
111struct pnv_php_slot *pnv_php_find_slot(struct device_node *dn)
112{
113 struct pnv_php_slot *php_slot, *tmp;
114 unsigned long flags;
115
116 spin_lock_irqsave(&pnv_php_lock, flags);
117 list_for_each_entry(tmp, &pnv_php_slot_list, link) {
118 php_slot = pnv_php_match(dn, php_slot: tmp);
119 if (php_slot) {
120 spin_unlock_irqrestore(lock: &pnv_php_lock, flags);
121 return php_slot;
122 }
123 }
124 spin_unlock_irqrestore(lock: &pnv_php_lock, flags);
125
126 return NULL;
127}
128EXPORT_SYMBOL_GPL(pnv_php_find_slot);
129
130/*
131 * Remove pdn for all children of the indicated device node.
132 * The function should remove pdn in a depth-first manner.
133 */
134static void pnv_php_rmv_pdns(struct device_node *dn)
135{
136 struct device_node *child;
137
138 for_each_child_of_node(dn, child) {
139 pnv_php_rmv_pdns(dn: child);
140
141 pci_remove_device_node_info(child);
142 }
143}
144
145/*
146 * Detach all child nodes of the indicated device nodes. The
147 * function should handle device nodes in depth-first manner.
148 *
149 * We should not invoke of_node_release() as the memory for
150 * individual device node is part of large memory block. The
151 * large block is allocated from memblock (system bootup) or
152 * kmalloc() when unflattening the device tree by OF changeset.
153 * We can not free the large block allocated from memblock. For
154 * later case, it should be released at once.
155 */
156static void pnv_php_detach_device_nodes(struct device_node *parent)
157{
158 struct device_node *dn;
159
160 for_each_child_of_node(parent, dn) {
161 pnv_php_detach_device_nodes(parent: dn);
162
163 of_node_put(dn);
164 of_detach_node(dn);
165 }
166}
167
168static void pnv_php_rmv_devtree(struct pnv_php_slot *php_slot)
169{
170 pnv_php_rmv_pdns(dn: php_slot->dn);
171
172 /*
173 * Decrease the refcount if the device nodes were created
174 * through OF changeset before detaching them.
175 */
176 if (php_slot->fdt)
177 of_changeset_destroy(&php_slot->ocs);
178 pnv_php_detach_device_nodes(parent: php_slot->dn);
179
180 if (php_slot->fdt) {
181 kfree(objp: php_slot->dt);
182 kfree(objp: php_slot->fdt);
183 php_slot->dt = NULL;
184 php_slot->dn->child = NULL;
185 php_slot->fdt = NULL;
186 }
187}
188
189/*
190 * As the nodes in OF changeset are applied in reverse order, we
191 * need revert the nodes in advance so that we have correct node
192 * order after the changeset is applied.
193 */
194static void pnv_php_reverse_nodes(struct device_node *parent)
195{
196 struct device_node *child, *next;
197
198 /* In-depth first */
199 for_each_child_of_node(parent, child)
200 pnv_php_reverse_nodes(parent: child);
201
202 /* Reverse the nodes in the child list */
203 child = parent->child;
204 parent->child = NULL;
205 while (child) {
206 next = child->sibling;
207
208 child->sibling = parent->child;
209 parent->child = child;
210 child = next;
211 }
212}
213
214static int pnv_php_populate_changeset(struct of_changeset *ocs,
215 struct device_node *dn)
216{
217 struct device_node *child;
218 int ret = 0;
219
220 for_each_child_of_node(dn, child) {
221 ret = of_changeset_attach_node(ocs, child);
222 if (ret) {
223 of_node_put(child);
224 break;
225 }
226
227 ret = pnv_php_populate_changeset(ocs, dn: child);
228 if (ret) {
229 of_node_put(child);
230 break;
231 }
232 }
233
234 return ret;
235}
236
237static void *pnv_php_add_one_pdn(struct device_node *dn, void *data)
238{
239 struct pci_controller *hose = (struct pci_controller *)data;
240 struct pci_dn *pdn;
241
242 pdn = pci_add_device_node_info(hose, dn);
243 if (!pdn)
244 return ERR_PTR(error: -ENOMEM);
245
246 return NULL;
247}
248
249static void pnv_php_add_pdns(struct pnv_php_slot *slot)
250{
251 struct pci_controller *hose = pci_bus_to_host(slot->bus);
252
253 pci_traverse_device_nodes(slot->dn, pnv_php_add_one_pdn, hose);
254}
255
256static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
257{
258 void *fdt, *fdt1, *dt;
259 int ret;
260
261 /* We don't know the FDT blob size. We try to get it through
262 * maximal memory chunk and then copy it to another chunk that
263 * fits the real size.
264 */
265 fdt1 = kzalloc(size: 0x10000, GFP_KERNEL);
266 if (!fdt1) {
267 ret = -ENOMEM;
268 goto out;
269 }
270
271 ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
272 if (ret) {
273 SLOT_WARN(php_slot, "Error %d getting FDT blob\n", ret);
274 goto free_fdt1;
275 }
276
277 fdt = kmemdup(p: fdt1, fdt_totalsize(fdt1), GFP_KERNEL);
278 if (!fdt) {
279 ret = -ENOMEM;
280 goto free_fdt1;
281 }
282
283 /* Unflatten device tree blob */
284 dt = of_fdt_unflatten_tree(blob: fdt, dad: php_slot->dn, NULL);
285 if (!dt) {
286 ret = -EINVAL;
287 SLOT_WARN(php_slot, "Cannot unflatten FDT\n");
288 goto free_fdt;
289 }
290
291 /* Initialize and apply the changeset */
292 of_changeset_init(&php_slot->ocs);
293 pnv_php_reverse_nodes(parent: php_slot->dn);
294 ret = pnv_php_populate_changeset(ocs: &php_slot->ocs, dn: php_slot->dn);
295 if (ret) {
296 pnv_php_reverse_nodes(parent: php_slot->dn);
297 SLOT_WARN(php_slot, "Error %d populating changeset\n",
298 ret);
299 goto free_dt;
300 }
301
302 php_slot->dn->child = NULL;
303 ret = of_changeset_apply(&php_slot->ocs);
304 if (ret) {
305 SLOT_WARN(php_slot, "Error %d applying changeset\n", ret);
306 goto destroy_changeset;
307 }
308
309 /* Add device node firmware data */
310 pnv_php_add_pdns(slot: php_slot);
311 php_slot->fdt = fdt;
312 php_slot->dt = dt;
313 kfree(objp: fdt1);
314 goto out;
315
316destroy_changeset:
317 of_changeset_destroy(&php_slot->ocs);
318free_dt:
319 kfree(objp: dt);
320 php_slot->dn->child = NULL;
321free_fdt:
322 kfree(objp: fdt);
323free_fdt1:
324 kfree(objp: fdt1);
325out:
326 return ret;
327}
328
329static inline struct pnv_php_slot *to_pnv_php_slot(struct hotplug_slot *slot)
330{
331 return container_of(slot, struct pnv_php_slot, slot);
332}
333
334int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
335 uint8_t state)
336{
337 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
338 struct opal_msg msg;
339 int ret;
340
341 ret = pnv_pci_set_power_state(php_slot->id, state, &msg);
342 if (ret > 0) {
343 if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle ||
344 be64_to_cpu(msg.params[2]) != state) {
345 SLOT_WARN(php_slot, "Wrong msg (%lld, %lld, %lld)\n",
346 be64_to_cpu(msg.params[1]),
347 be64_to_cpu(msg.params[2]),
348 be64_to_cpu(msg.params[3]));
349 return -ENOMSG;
350 }
351 if (be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
352 ret = -ENODEV;
353 goto error;
354 }
355 } else if (ret < 0) {
356 goto error;
357 }
358
359 if (state == OPAL_PCI_SLOT_POWER_OFF || state == OPAL_PCI_SLOT_OFFLINE)
360 pnv_php_rmv_devtree(php_slot);
361 else
362 ret = pnv_php_add_devtree(php_slot);
363
364 return ret;
365
366error:
367 SLOT_WARN(php_slot, "Error %d powering %s\n",
368 ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
369 return ret;
370}
371EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state);
372
373static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
374{
375 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
376 uint8_t power_state = OPAL_PCI_SLOT_POWER_ON;
377 int ret;
378
379 /*
380 * Retrieve power status from firmware. If we fail
381 * getting that, the power status fails back to
382 * be on.
383 */
384 ret = pnv_pci_get_power_state(php_slot->id, &power_state);
385 if (ret) {
386 SLOT_WARN(php_slot, "Error %d getting power status\n",
387 ret);
388 } else {
389 *state = power_state;
390 }
391
392 return 0;
393}
394
395static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
396{
397 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
398 uint8_t presence = OPAL_PCI_SLOT_EMPTY;
399 int ret;
400
401 /*
402 * Retrieve presence status from firmware. If we can't
403 * get that, it will fail back to be empty.
404 */
405 ret = pnv_pci_get_presence_state(php_slot->id, &presence);
406 if (ret >= 0) {
407 *state = presence;
408 ret = 0;
409 } else {
410 SLOT_WARN(php_slot, "Error %d getting presence\n", ret);
411 }
412
413 return ret;
414}
415
416static int pnv_php_get_attention_state(struct hotplug_slot *slot, u8 *state)
417{
418 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
419
420 *state = php_slot->attention_state;
421 return 0;
422}
423
424static int pnv_php_set_attention_state(struct hotplug_slot *slot, u8 state)
425{
426 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
427 struct pci_dev *bridge = php_slot->pdev;
428 u16 new, mask;
429
430 php_slot->attention_state = state;
431 if (!bridge)
432 return 0;
433
434 mask = PCI_EXP_SLTCTL_AIC;
435
436 if (state)
437 new = PCI_EXP_SLTCTL_ATTN_IND_ON;
438 else
439 new = PCI_EXP_SLTCTL_ATTN_IND_OFF;
440
441 pcie_capability_clear_and_set_word(dev: bridge, PCI_EXP_SLTCTL, clear: mask, set: new);
442
443 return 0;
444}
445
446static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan)
447{
448 struct hotplug_slot *slot = &php_slot->slot;
449 uint8_t presence = OPAL_PCI_SLOT_EMPTY;
450 uint8_t power_status = OPAL_PCI_SLOT_POWER_ON;
451 int ret;
452
453 /* Check if the slot has been configured */
454 if (php_slot->state != PNV_PHP_STATE_REGISTERED)
455 return 0;
456
457 /* Retrieve slot presence status */
458 ret = pnv_php_get_adapter_state(slot, state: &presence);
459 if (ret)
460 return ret;
461
462 /*
463 * Proceed if there have nothing behind the slot. However,
464 * we should leave the slot in registered state at the
465 * beginning. Otherwise, the PCI devices inserted afterwards
466 * won't be probed and populated.
467 */
468 if (presence == OPAL_PCI_SLOT_EMPTY) {
469 if (!php_slot->power_state_check) {
470 php_slot->power_state_check = true;
471
472 return 0;
473 }
474
475 goto scan;
476 }
477
478 /*
479 * If the power supply to the slot is off, we can't detect
480 * adapter presence state. That means we have to turn the
481 * slot on before going to probe slot's presence state.
482 *
483 * On the first time, we don't change the power status to
484 * boost system boot with assumption that the firmware
485 * supplies consistent slot power status: empty slot always
486 * has its power off and non-empty slot has its power on.
487 */
488 if (!php_slot->power_state_check) {
489 php_slot->power_state_check = true;
490
491 ret = pnv_php_get_power_state(slot, state: &power_status);
492 if (ret)
493 return ret;
494
495 if (power_status != OPAL_PCI_SLOT_POWER_ON)
496 return 0;
497 }
498
499 /* Check the power status. Scan the slot if it is already on */
500 ret = pnv_php_get_power_state(slot, state: &power_status);
501 if (ret)
502 return ret;
503
504 if (power_status == OPAL_PCI_SLOT_POWER_ON)
505 goto scan;
506
507 /* Power is off, turn it on and then scan the slot */
508 ret = pnv_php_set_slot_power_state(slot, OPAL_PCI_SLOT_POWER_ON);
509 if (ret)
510 return ret;
511
512scan:
513 if (presence == OPAL_PCI_SLOT_PRESENT) {
514 if (rescan) {
515 pci_lock_rescan_remove();
516 pci_hp_add_devices(php_slot->bus);
517 pci_unlock_rescan_remove();
518 }
519
520 /* Rescan for child hotpluggable slots */
521 php_slot->state = PNV_PHP_STATE_POPULATED;
522 if (rescan)
523 pnv_php_register(dn: php_slot->dn);
524 } else {
525 php_slot->state = PNV_PHP_STATE_POPULATED;
526 }
527
528 return 0;
529}
530
531static int pnv_php_reset_slot(struct hotplug_slot *slot, bool probe)
532{
533 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
534 struct pci_dev *bridge = php_slot->pdev;
535 uint16_t sts;
536
537 /*
538 * The CAPI folks want pnv_php to drive OpenCAPI slots
539 * which don't have a bridge. Only claim to support
540 * reset_slot() if we have a bridge device (for now...)
541 */
542 if (probe)
543 return !bridge;
544
545 /* mask our interrupt while resetting the bridge */
546 if (php_slot->irq > 0)
547 disable_irq(irq: php_slot->irq);
548
549 pci_bridge_secondary_bus_reset(dev: bridge);
550
551 /* clear any state changes that happened due to the reset */
552 pcie_capability_read_word(dev: php_slot->pdev, PCI_EXP_SLTSTA, val: &sts);
553 sts &= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
554 pcie_capability_write_word(dev: php_slot->pdev, PCI_EXP_SLTSTA, val: sts);
555
556 if (php_slot->irq > 0)
557 enable_irq(irq: php_slot->irq);
558
559 return 0;
560}
561
562static int pnv_php_enable_slot(struct hotplug_slot *slot)
563{
564 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
565
566 return pnv_php_enable(php_slot, rescan: true);
567}
568
569static int pnv_php_disable_slot(struct hotplug_slot *slot)
570{
571 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
572 int ret;
573
574 /*
575 * Allow to disable a slot already in the registered state to
576 * cover cases where the slot couldn't be enabled and never
577 * reached the populated state
578 */
579 if (php_slot->state != PNV_PHP_STATE_POPULATED &&
580 php_slot->state != PNV_PHP_STATE_REGISTERED)
581 return 0;
582
583 /* Remove all devices behind the slot */
584 pci_lock_rescan_remove();
585 pci_hp_remove_devices(php_slot->bus);
586 pci_unlock_rescan_remove();
587
588 /* Detach the child hotpluggable slots */
589 pnv_php_unregister(dn: php_slot->dn);
590
591 /* Notify firmware and remove device nodes */
592 ret = pnv_php_set_slot_power_state(slot, OPAL_PCI_SLOT_POWER_OFF);
593
594 php_slot->state = PNV_PHP_STATE_REGISTERED;
595 return ret;
596}
597
598static const struct hotplug_slot_ops php_slot_ops = {
599 .get_power_status = pnv_php_get_power_state,
600 .get_adapter_status = pnv_php_get_adapter_state,
601 .get_attention_status = pnv_php_get_attention_state,
602 .set_attention_status = pnv_php_set_attention_state,
603 .enable_slot = pnv_php_enable_slot,
604 .disable_slot = pnv_php_disable_slot,
605 .reset_slot = pnv_php_reset_slot,
606};
607
608static void pnv_php_release(struct pnv_php_slot *php_slot)
609{
610 unsigned long flags;
611
612 /* Remove from global or child list */
613 spin_lock_irqsave(&pnv_php_lock, flags);
614 list_del(entry: &php_slot->link);
615 spin_unlock_irqrestore(lock: &pnv_php_lock, flags);
616
617 /* Detach from parent */
618 pnv_php_put_slot(php_slot);
619 pnv_php_put_slot(php_slot: php_slot->parent);
620}
621
622static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn)
623{
624 struct pnv_php_slot *php_slot;
625 struct pci_bus *bus;
626 const char *label;
627 uint64_t id;
628 int ret;
629
630 ret = of_property_read_string(dn, "ibm,slot-label", &label);
631 if (ret)
632 return NULL;
633
634 if (pnv_pci_get_slot_id(dn, &id))
635 return NULL;
636
637 bus = pci_find_bus_by_node(dn);
638 if (!bus)
639 return NULL;
640
641 php_slot = kzalloc(sizeof(*php_slot), GFP_KERNEL);
642 if (!php_slot)
643 return NULL;
644
645 php_slot->name = kstrdup(s: label, GFP_KERNEL);
646 if (!php_slot->name) {
647 kfree(objp: php_slot);
648 return NULL;
649 }
650
651 if (dn->child && PCI_DN(dn->child))
652 php_slot->slot_no = PCI_SLOT(PCI_DN(dn->child)->devfn);
653 else
654 php_slot->slot_no = -1; /* Placeholder slot */
655
656 kref_init(kref: &php_slot->kref);
657 php_slot->state = PNV_PHP_STATE_INITIALIZED;
658 php_slot->dn = dn;
659 php_slot->pdev = bus->self;
660 php_slot->bus = bus;
661 php_slot->id = id;
662 php_slot->power_state_check = false;
663 php_slot->slot.ops = &php_slot_ops;
664
665 INIT_LIST_HEAD(list: &php_slot->children);
666 INIT_LIST_HEAD(list: &php_slot->link);
667
668 return php_slot;
669}
670
671static int pnv_php_register_slot(struct pnv_php_slot *php_slot)
672{
673 struct pnv_php_slot *parent;
674 struct device_node *dn = php_slot->dn;
675 unsigned long flags;
676 int ret;
677
678 /* Check if the slot is registered or not */
679 parent = pnv_php_find_slot(php_slot->dn);
680 if (parent) {
681 pnv_php_put_slot(php_slot: parent);
682 return -EEXIST;
683 }
684
685 /* Register PCI slot */
686 ret = pci_hp_register(&php_slot->slot, php_slot->bus,
687 php_slot->slot_no, php_slot->name);
688 if (ret) {
689 SLOT_WARN(php_slot, "Error %d registering slot\n", ret);
690 return ret;
691 }
692
693 /* Attach to the parent's child list or global list */
694 while ((dn = of_get_parent(dn))) {
695 if (!PCI_DN(dn)) {
696 of_node_put(dn);
697 break;
698 }
699
700 parent = pnv_php_find_slot(dn);
701 if (parent) {
702 of_node_put(dn);
703 break;
704 }
705
706 of_node_put(dn);
707 }
708
709 spin_lock_irqsave(&pnv_php_lock, flags);
710 php_slot->parent = parent;
711 if (parent)
712 list_add_tail(new: &php_slot->link, head: &parent->children);
713 else
714 list_add_tail(new: &php_slot->link, head: &pnv_php_slot_list);
715 spin_unlock_irqrestore(lock: &pnv_php_lock, flags);
716
717 php_slot->state = PNV_PHP_STATE_REGISTERED;
718 return 0;
719}
720
721static int pnv_php_enable_msix(struct pnv_php_slot *php_slot)
722{
723 struct pci_dev *pdev = php_slot->pdev;
724 struct msix_entry entry;
725 int nr_entries, ret;
726 u16 pcie_flag;
727
728 /* Get total number of MSIx entries */
729 nr_entries = pci_msix_vec_count(dev: pdev);
730 if (nr_entries < 0)
731 return nr_entries;
732
733 /* Check hotplug MSIx entry is in range */
734 pcie_capability_read_word(dev: pdev, PCI_EXP_FLAGS, val: &pcie_flag);
735 entry.entry = FIELD_GET(PCI_EXP_FLAGS_IRQ, pcie_flag);
736 if (entry.entry >= nr_entries)
737 return -ERANGE;
738
739 /* Enable MSIx */
740 ret = pci_enable_msix_exact(dev: pdev, entries: &entry, nvec: 1);
741 if (ret) {
742 SLOT_WARN(php_slot, "Error %d enabling MSIx\n", ret);
743 return ret;
744 }
745
746 return entry.vector;
747}
748
749static void pnv_php_event_handler(struct work_struct *work)
750{
751 struct pnv_php_event *event =
752 container_of(work, struct pnv_php_event, work);
753 struct pnv_php_slot *php_slot = event->php_slot;
754
755 if (event->added)
756 pnv_php_enable_slot(slot: &php_slot->slot);
757 else
758 pnv_php_disable_slot(slot: &php_slot->slot);
759
760 kfree(objp: event);
761}
762
763static irqreturn_t pnv_php_interrupt(int irq, void *data)
764{
765 struct pnv_php_slot *php_slot = data;
766 struct pci_dev *pchild, *pdev = php_slot->pdev;
767 struct eeh_dev *edev;
768 struct eeh_pe *pe;
769 struct pnv_php_event *event;
770 u16 sts, lsts;
771 u8 presence;
772 bool added;
773 unsigned long flags;
774 int ret;
775
776 pcie_capability_read_word(dev: pdev, PCI_EXP_SLTSTA, val: &sts);
777 sts &= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
778 pcie_capability_write_word(dev: pdev, PCI_EXP_SLTSTA, val: sts);
779
780 pci_dbg(pdev, "PCI slot [%s]: HP int! DLAct: %d, PresDet: %d\n",
781 php_slot->name,
782 !!(sts & PCI_EXP_SLTSTA_DLLSC),
783 !!(sts & PCI_EXP_SLTSTA_PDC));
784
785 if (sts & PCI_EXP_SLTSTA_DLLSC) {
786 pcie_capability_read_word(dev: pdev, PCI_EXP_LNKSTA, val: &lsts);
787 added = !!(lsts & PCI_EXP_LNKSTA_DLLLA);
788 } else if (!(php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) &&
789 (sts & PCI_EXP_SLTSTA_PDC)) {
790 ret = pnv_pci_get_presence_state(php_slot->id, &presence);
791 if (ret) {
792 SLOT_WARN(php_slot,
793 "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
794 php_slot->name, ret, sts);
795 return IRQ_HANDLED;
796 }
797
798 added = !!(presence == OPAL_PCI_SLOT_PRESENT);
799 } else {
800 pci_dbg(pdev, "PCI slot [%s]: Spurious IRQ?\n", php_slot->name);
801 return IRQ_NONE;
802 }
803
804 /* Freeze the removed PE to avoid unexpected error reporting */
805 if (!added) {
806 pchild = list_first_entry_or_null(&php_slot->bus->devices,
807 struct pci_dev, bus_list);
808 edev = pchild ? pci_dev_to_eeh_dev(pchild) : NULL;
809 pe = edev ? edev->pe : NULL;
810 if (pe) {
811 eeh_serialize_lock(&flags);
812 eeh_pe_mark_isolated(pe);
813 eeh_serialize_unlock(flags);
814 eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE);
815 }
816 }
817
818 /*
819 * The PE is left in frozen state if the event is missed. It's
820 * fine as the PCI devices (PE) aren't functional any more.
821 */
822 event = kzalloc(size: sizeof(*event), GFP_ATOMIC);
823 if (!event) {
824 SLOT_WARN(php_slot,
825 "PCI slot [%s] missed hotplug event 0x%04x\n",
826 php_slot->name, sts);
827 return IRQ_HANDLED;
828 }
829
830 pci_info(pdev, "PCI slot [%s] %s (IRQ: %d)\n",
831 php_slot->name, added ? "added" : "removed", irq);
832 INIT_WORK(&event->work, pnv_php_event_handler);
833 event->added = added;
834 event->php_slot = php_slot;
835 queue_work(wq: php_slot->wq, work: &event->work);
836
837 return IRQ_HANDLED;
838}
839
840static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
841{
842 struct pci_dev *pdev = php_slot->pdev;
843 u32 broken_pdc = 0;
844 u16 sts, ctrl;
845 int ret;
846
847 /* Allocate workqueue */
848 php_slot->wq = alloc_workqueue(fmt: "pciehp-%s", flags: 0, max_active: 0, php_slot->name);
849 if (!php_slot->wq) {
850 SLOT_WARN(php_slot, "Cannot alloc workqueue\n");
851 pnv_php_disable_irq(php_slot, disable_device: true);
852 return;
853 }
854
855 /* Check PDC (Presence Detection Change) is broken or not */
856 ret = of_property_read_u32(php_slot->dn, "ibm,slot-broken-pdc",
857 &broken_pdc);
858 if (!ret && broken_pdc)
859 php_slot->flags |= PNV_PHP_FLAG_BROKEN_PDC;
860
861 /* Clear pending interrupts */
862 pcie_capability_read_word(dev: pdev, PCI_EXP_SLTSTA, val: &sts);
863 if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC)
864 sts |= PCI_EXP_SLTSTA_DLLSC;
865 else
866 sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
867 pcie_capability_write_word(dev: pdev, PCI_EXP_SLTSTA, val: sts);
868
869 /* Request the interrupt */
870 ret = request_irq(irq, handler: pnv_php_interrupt, IRQF_SHARED,
871 name: php_slot->name, dev: php_slot);
872 if (ret) {
873 pnv_php_disable_irq(php_slot, disable_device: true);
874 SLOT_WARN(php_slot, "Error %d enabling IRQ %d\n", ret, irq);
875 return;
876 }
877
878 /* Enable the interrupts */
879 pcie_capability_read_word(dev: pdev, PCI_EXP_SLTCTL, val: &ctrl);
880 if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) {
881 ctrl &= ~PCI_EXP_SLTCTL_PDCE;
882 ctrl |= (PCI_EXP_SLTCTL_HPIE |
883 PCI_EXP_SLTCTL_DLLSCE);
884 } else {
885 ctrl |= (PCI_EXP_SLTCTL_HPIE |
886 PCI_EXP_SLTCTL_PDCE |
887 PCI_EXP_SLTCTL_DLLSCE);
888 }
889 pcie_capability_write_word(dev: pdev, PCI_EXP_SLTCTL, val: ctrl);
890
891 /* The interrupt is initialized successfully when @irq is valid */
892 php_slot->irq = irq;
893}
894
895static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
896{
897 struct pci_dev *pdev = php_slot->pdev;
898 int irq, ret;
899
900 /*
901 * The MSI/MSIx interrupt might have been occupied by other
902 * drivers. Don't populate the surprise hotplug capability
903 * in that case.
904 */
905 if (pci_dev_msi_enabled(pci_dev: pdev))
906 return;
907
908 ret = pci_enable_device(dev: pdev);
909 if (ret) {
910 SLOT_WARN(php_slot, "Error %d enabling device\n", ret);
911 return;
912 }
913
914 pci_set_master(dev: pdev);
915
916 /* Enable MSIx interrupt */
917 irq = pnv_php_enable_msix(php_slot);
918 if (irq > 0) {
919 pnv_php_init_irq(php_slot, irq);
920 return;
921 }
922
923 /*
924 * Use MSI if MSIx doesn't work. Fail back to legacy INTx
925 * if MSI doesn't work either
926 */
927 ret = pci_enable_msi(dev: pdev);
928 if (!ret || pdev->irq) {
929 irq = pdev->irq;
930 pnv_php_init_irq(php_slot, irq);
931 }
932}
933
934static int pnv_php_register_one(struct device_node *dn)
935{
936 struct pnv_php_slot *php_slot;
937 u32 prop32;
938 int ret;
939
940 /* Check if it's hotpluggable slot */
941 ret = of_property_read_u32(dn, "ibm,slot-pluggable", &prop32);
942 if (ret || !prop32)
943 return -ENXIO;
944
945 ret = of_property_read_u32(dn, "ibm,reset-by-firmware", &prop32);
946 if (ret || !prop32)
947 return -ENXIO;
948
949 php_slot = pnv_php_alloc_slot(dn);
950 if (!php_slot)
951 return -ENODEV;
952
953 ret = pnv_php_register_slot(php_slot);
954 if (ret)
955 goto free_slot;
956
957 ret = pnv_php_enable(php_slot, rescan: false);
958 if (ret)
959 goto unregister_slot;
960
961 /* Enable interrupt if the slot supports surprise hotplug */
962 ret = of_property_read_u32(dn, "ibm,slot-surprise-pluggable", &prop32);
963 if (!ret && prop32)
964 pnv_php_enable_irq(php_slot);
965
966 return 0;
967
968unregister_slot:
969 pnv_php_unregister_one(dn: php_slot->dn);
970free_slot:
971 pnv_php_put_slot(php_slot);
972 return ret;
973}
974
975static void pnv_php_register(struct device_node *dn)
976{
977 struct device_node *child;
978
979 /*
980 * The parent slots should be registered before their
981 * child slots.
982 */
983 for_each_child_of_node(dn, child) {
984 pnv_php_register_one(dn: child);
985 pnv_php_register(dn: child);
986 }
987}
988
989static void pnv_php_unregister_one(struct device_node *dn)
990{
991 struct pnv_php_slot *php_slot;
992
993 php_slot = pnv_php_find_slot(dn);
994 if (!php_slot)
995 return;
996
997 php_slot->state = PNV_PHP_STATE_OFFLINE;
998 pci_hp_deregister(slot: &php_slot->slot);
999 pnv_php_release(php_slot);
1000 pnv_php_put_slot(php_slot);
1001}
1002
1003static void pnv_php_unregister(struct device_node *dn)
1004{
1005 struct device_node *child;
1006
1007 /* The child slots should go before their parent slots */
1008 for_each_child_of_node(dn, child) {
1009 pnv_php_unregister(dn: child);
1010 pnv_php_unregister_one(dn: child);
1011 }
1012}
1013
1014static int __init pnv_php_init(void)
1015{
1016 struct device_node *dn;
1017
1018 pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1019 for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
1020 pnv_php_register(dn);
1021
1022 for_each_compatible_node(dn, NULL, "ibm,ioda3-phb")
1023 pnv_php_register(dn);
1024
1025 for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb")
1026 pnv_php_register_one(dn); /* slot directly under the PHB */
1027 return 0;
1028}
1029
1030static void __exit pnv_php_exit(void)
1031{
1032 struct device_node *dn;
1033
1034 for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
1035 pnv_php_unregister(dn);
1036
1037 for_each_compatible_node(dn, NULL, "ibm,ioda3-phb")
1038 pnv_php_unregister(dn);
1039
1040 for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb")
1041 pnv_php_unregister_one(dn); /* slot directly under the PHB */
1042}
1043
1044module_init(pnv_php_init);
1045module_exit(pnv_php_exit);
1046
1047MODULE_VERSION(DRIVER_VERSION);
1048MODULE_LICENSE("GPL v2");
1049MODULE_AUTHOR(DRIVER_AUTHOR);
1050MODULE_DESCRIPTION(DRIVER_DESC);
1051

source code of linux/drivers/pci/hotplug/pnv_php.c