Lines Matching refs:php_slot
26 struct pnv_php_slot *php_slot; member
37 static void pnv_php_disable_irq(struct pnv_php_slot *php_slot, in pnv_php_disable_irq() argument
40 struct pci_dev *pdev = php_slot->pdev; in pnv_php_disable_irq()
41 int irq = php_slot->irq; in pnv_php_disable_irq()
44 if (php_slot->irq > 0) { in pnv_php_disable_irq()
51 free_irq(php_slot->irq, php_slot); in pnv_php_disable_irq()
52 php_slot->irq = 0; in pnv_php_disable_irq()
55 if (php_slot->wq) { in pnv_php_disable_irq()
56 destroy_workqueue(php_slot->wq); in pnv_php_disable_irq()
57 php_slot->wq = NULL; in pnv_php_disable_irq()
72 struct pnv_php_slot *php_slot = container_of(kref, in pnv_php_free_slot() local
75 WARN_ON(!list_empty(&php_slot->children)); in pnv_php_free_slot()
76 pnv_php_disable_irq(php_slot, false); in pnv_php_free_slot()
77 kfree(php_slot->name); in pnv_php_free_slot()
78 kfree(php_slot); in pnv_php_free_slot()
81 static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot) in pnv_php_put_slot() argument
84 if (!php_slot) in pnv_php_put_slot()
87 kref_put(&php_slot->kref, pnv_php_free_slot); in pnv_php_put_slot()
91 struct pnv_php_slot *php_slot) in pnv_php_match() argument
95 if (php_slot->dn == dn) { in pnv_php_match()
96 kref_get(&php_slot->kref); in pnv_php_match()
97 return php_slot; in pnv_php_match()
100 list_for_each_entry(tmp, &php_slot->children, link) { in pnv_php_match()
111 struct pnv_php_slot *php_slot, *tmp; in pnv_php_find_slot() local
116 php_slot = pnv_php_match(dn, tmp); in pnv_php_find_slot()
117 if (php_slot) { in pnv_php_find_slot()
119 return php_slot; in pnv_php_find_slot()
166 static void pnv_php_rmv_devtree(struct pnv_php_slot *php_slot) in pnv_php_rmv_devtree() argument
168 pnv_php_rmv_pdns(php_slot->dn); in pnv_php_rmv_devtree()
174 if (php_slot->fdt) in pnv_php_rmv_devtree()
175 of_changeset_destroy(&php_slot->ocs); in pnv_php_rmv_devtree()
176 pnv_php_detach_device_nodes(php_slot->dn); in pnv_php_rmv_devtree()
178 if (php_slot->fdt) { in pnv_php_rmv_devtree()
179 kfree(php_slot->dt); in pnv_php_rmv_devtree()
180 kfree(php_slot->fdt); in pnv_php_rmv_devtree()
181 php_slot->dt = NULL; in pnv_php_rmv_devtree()
182 php_slot->dn->child = NULL; in pnv_php_rmv_devtree()
183 php_slot->fdt = NULL; in pnv_php_rmv_devtree()
254 static int pnv_php_add_devtree(struct pnv_php_slot *php_slot) in pnv_php_add_devtree() argument
269 ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000); in pnv_php_add_devtree()
271 SLOT_WARN(php_slot, "Error %d getting FDT blob\n", ret); in pnv_php_add_devtree()
282 dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL); in pnv_php_add_devtree()
285 SLOT_WARN(php_slot, "Cannot unflatten FDT\n"); in pnv_php_add_devtree()
290 of_changeset_init(&php_slot->ocs); in pnv_php_add_devtree()
291 pnv_php_reverse_nodes(php_slot->dn); in pnv_php_add_devtree()
292 ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn); in pnv_php_add_devtree()
294 pnv_php_reverse_nodes(php_slot->dn); in pnv_php_add_devtree()
295 SLOT_WARN(php_slot, "Error %d populating changeset\n", in pnv_php_add_devtree()
300 php_slot->dn->child = NULL; in pnv_php_add_devtree()
301 ret = of_changeset_apply(&php_slot->ocs); in pnv_php_add_devtree()
303 SLOT_WARN(php_slot, "Error %d applying changeset\n", ret); in pnv_php_add_devtree()
308 pnv_php_add_pdns(php_slot); in pnv_php_add_devtree()
309 php_slot->fdt = fdt; in pnv_php_add_devtree()
310 php_slot->dt = dt; in pnv_php_add_devtree()
315 of_changeset_destroy(&php_slot->ocs); in pnv_php_add_devtree()
318 php_slot->dn->child = NULL; in pnv_php_add_devtree()
335 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_set_slot_power_state() local
339 ret = pnv_pci_set_power_state(php_slot->id, state, &msg); in pnv_php_set_slot_power_state()
341 if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle || in pnv_php_set_slot_power_state()
343 SLOT_WARN(php_slot, "Wrong msg (%lld, %lld, %lld)\n", in pnv_php_set_slot_power_state()
358 pnv_php_rmv_devtree(php_slot); in pnv_php_set_slot_power_state()
360 ret = pnv_php_add_devtree(php_slot); in pnv_php_set_slot_power_state()
365 SLOT_WARN(php_slot, "Error %d powering %s\n", in pnv_php_set_slot_power_state()
373 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_get_power_state() local
382 ret = pnv_pci_get_power_state(php_slot->id, &power_state); in pnv_php_get_power_state()
384 SLOT_WARN(php_slot, "Error %d getting power status\n", in pnv_php_get_power_state()
395 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_get_adapter_state() local
403 ret = pnv_pci_get_presence_state(php_slot->id, &presence); in pnv_php_get_adapter_state()
408 SLOT_WARN(php_slot, "Error %d getting presence\n", ret); in pnv_php_get_adapter_state()
416 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_get_attention_state() local
418 *state = php_slot->attention_state; in pnv_php_get_attention_state()
424 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_set_attention_state() local
425 struct pci_dev *bridge = php_slot->pdev; in pnv_php_set_attention_state()
428 php_slot->attention_state = state; in pnv_php_set_attention_state()
444 static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan) in pnv_php_enable() argument
446 struct hotplug_slot *slot = &php_slot->slot; in pnv_php_enable()
452 if (php_slot->state != PNV_PHP_STATE_REGISTERED) in pnv_php_enable()
467 if (!php_slot->power_state_check) { in pnv_php_enable()
468 php_slot->power_state_check = true; in pnv_php_enable()
486 if (!php_slot->power_state_check) { in pnv_php_enable()
487 php_slot->power_state_check = true; in pnv_php_enable()
514 pci_hp_add_devices(php_slot->bus); in pnv_php_enable()
519 php_slot->state = PNV_PHP_STATE_POPULATED; in pnv_php_enable()
521 pnv_php_register(php_slot->dn); in pnv_php_enable()
523 php_slot->state = PNV_PHP_STATE_POPULATED; in pnv_php_enable()
531 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_reset_slot() local
532 struct pci_dev *bridge = php_slot->pdev; in pnv_php_reset_slot()
544 if (php_slot->irq > 0) in pnv_php_reset_slot()
545 disable_irq(php_slot->irq); in pnv_php_reset_slot()
550 pcie_capability_read_word(php_slot->pdev, PCI_EXP_SLTSTA, &sts); in pnv_php_reset_slot()
552 pcie_capability_write_word(php_slot->pdev, PCI_EXP_SLTSTA, sts); in pnv_php_reset_slot()
554 if (php_slot->irq > 0) in pnv_php_reset_slot()
555 enable_irq(php_slot->irq); in pnv_php_reset_slot()
562 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_enable_slot() local
564 return pnv_php_enable(php_slot, true); in pnv_php_enable_slot()
569 struct pnv_php_slot *php_slot = to_pnv_php_slot(slot); in pnv_php_disable_slot() local
577 if (php_slot->state != PNV_PHP_STATE_POPULATED && in pnv_php_disable_slot()
578 php_slot->state != PNV_PHP_STATE_REGISTERED) in pnv_php_disable_slot()
583 pci_hp_remove_devices(php_slot->bus); in pnv_php_disable_slot()
587 pnv_php_unregister(php_slot->dn); in pnv_php_disable_slot()
592 php_slot->state = PNV_PHP_STATE_REGISTERED; in pnv_php_disable_slot()
606 static void pnv_php_release(struct pnv_php_slot *php_slot) in pnv_php_release() argument
612 list_del(&php_slot->link); in pnv_php_release()
616 pnv_php_put_slot(php_slot); in pnv_php_release()
617 pnv_php_put_slot(php_slot->parent); in pnv_php_release()
622 struct pnv_php_slot *php_slot; in pnv_php_alloc_slot() local
639 php_slot = kzalloc(sizeof(*php_slot), GFP_KERNEL); in pnv_php_alloc_slot()
640 if (!php_slot) in pnv_php_alloc_slot()
643 php_slot->name = kstrdup(label, GFP_KERNEL); in pnv_php_alloc_slot()
644 if (!php_slot->name) { in pnv_php_alloc_slot()
645 kfree(php_slot); in pnv_php_alloc_slot()
650 php_slot->slot_no = PCI_SLOT(PCI_DN(dn->child)->devfn); in pnv_php_alloc_slot()
652 php_slot->slot_no = -1; /* Placeholder slot */ in pnv_php_alloc_slot()
654 kref_init(&php_slot->kref); in pnv_php_alloc_slot()
655 php_slot->state = PNV_PHP_STATE_INITIALIZED; in pnv_php_alloc_slot()
656 php_slot->dn = dn; in pnv_php_alloc_slot()
657 php_slot->pdev = bus->self; in pnv_php_alloc_slot()
658 php_slot->bus = bus; in pnv_php_alloc_slot()
659 php_slot->id = id; in pnv_php_alloc_slot()
660 php_slot->power_state_check = false; in pnv_php_alloc_slot()
661 php_slot->slot.ops = &php_slot_ops; in pnv_php_alloc_slot()
663 INIT_LIST_HEAD(&php_slot->children); in pnv_php_alloc_slot()
664 INIT_LIST_HEAD(&php_slot->link); in pnv_php_alloc_slot()
666 return php_slot; in pnv_php_alloc_slot()
669 static int pnv_php_register_slot(struct pnv_php_slot *php_slot) in pnv_php_register_slot() argument
672 struct device_node *dn = php_slot->dn; in pnv_php_register_slot()
677 parent = pnv_php_find_slot(php_slot->dn); in pnv_php_register_slot()
684 ret = pci_hp_register(&php_slot->slot, php_slot->bus, in pnv_php_register_slot()
685 php_slot->slot_no, php_slot->name); in pnv_php_register_slot()
687 SLOT_WARN(php_slot, "Error %d registering slot\n", ret); in pnv_php_register_slot()
708 php_slot->parent = parent; in pnv_php_register_slot()
710 list_add_tail(&php_slot->link, &parent->children); in pnv_php_register_slot()
712 list_add_tail(&php_slot->link, &pnv_php_slot_list); in pnv_php_register_slot()
715 php_slot->state = PNV_PHP_STATE_REGISTERED; in pnv_php_register_slot()
719 static int pnv_php_enable_msix(struct pnv_php_slot *php_slot) in pnv_php_enable_msix() argument
721 struct pci_dev *pdev = php_slot->pdev; in pnv_php_enable_msix()
740 SLOT_WARN(php_slot, "Error %d enabling MSIx\n", ret); in pnv_php_enable_msix()
751 struct pnv_php_slot *php_slot = event->php_slot; in pnv_php_event_handler() local
754 pnv_php_enable_slot(&php_slot->slot); in pnv_php_event_handler()
756 pnv_php_disable_slot(&php_slot->slot); in pnv_php_event_handler()
763 struct pnv_php_slot *php_slot = data; in pnv_php_interrupt() local
764 struct pci_dev *pchild, *pdev = php_slot->pdev; in pnv_php_interrupt()
779 php_slot->name, in pnv_php_interrupt()
786 } else if (!(php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) && in pnv_php_interrupt()
788 ret = pnv_pci_get_presence_state(php_slot->id, &presence); in pnv_php_interrupt()
790 SLOT_WARN(php_slot, in pnv_php_interrupt()
792 php_slot->name, ret, sts); in pnv_php_interrupt()
798 pci_dbg(pdev, "PCI slot [%s]: Spurious IRQ?\n", php_slot->name); in pnv_php_interrupt()
804 pchild = list_first_entry_or_null(&php_slot->bus->devices, in pnv_php_interrupt()
822 SLOT_WARN(php_slot, in pnv_php_interrupt()
824 php_slot->name, sts); in pnv_php_interrupt()
829 php_slot->name, added ? "added" : "removed", irq); in pnv_php_interrupt()
832 event->php_slot = php_slot; in pnv_php_interrupt()
833 queue_work(php_slot->wq, &event->work); in pnv_php_interrupt()
838 static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq) in pnv_php_init_irq() argument
840 struct pci_dev *pdev = php_slot->pdev; in pnv_php_init_irq()
846 php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name); in pnv_php_init_irq()
847 if (!php_slot->wq) { in pnv_php_init_irq()
848 SLOT_WARN(php_slot, "Cannot alloc workqueue\n"); in pnv_php_init_irq()
849 pnv_php_disable_irq(php_slot, true); in pnv_php_init_irq()
854 ret = of_property_read_u32(php_slot->dn, "ibm,slot-broken-pdc", in pnv_php_init_irq()
857 php_slot->flags |= PNV_PHP_FLAG_BROKEN_PDC; in pnv_php_init_irq()
861 if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) in pnv_php_init_irq()
869 php_slot->name, php_slot); in pnv_php_init_irq()
871 pnv_php_disable_irq(php_slot, true); in pnv_php_init_irq()
872 SLOT_WARN(php_slot, "Error %d enabling IRQ %d\n", ret, irq); in pnv_php_init_irq()
878 if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) { in pnv_php_init_irq()
890 php_slot->irq = irq; in pnv_php_init_irq()
893 static void pnv_php_enable_irq(struct pnv_php_slot *php_slot) in pnv_php_enable_irq() argument
895 struct pci_dev *pdev = php_slot->pdev; in pnv_php_enable_irq()
908 SLOT_WARN(php_slot, "Error %d enabling device\n", ret); in pnv_php_enable_irq()
915 irq = pnv_php_enable_msix(php_slot); in pnv_php_enable_irq()
917 pnv_php_init_irq(php_slot, irq); in pnv_php_enable_irq()
928 pnv_php_init_irq(php_slot, irq); in pnv_php_enable_irq()
934 struct pnv_php_slot *php_slot; in pnv_php_register_one() local
947 php_slot = pnv_php_alloc_slot(dn); in pnv_php_register_one()
948 if (!php_slot) in pnv_php_register_one()
951 ret = pnv_php_register_slot(php_slot); in pnv_php_register_one()
955 ret = pnv_php_enable(php_slot, false); in pnv_php_register_one()
962 pnv_php_enable_irq(php_slot); in pnv_php_register_one()
967 pnv_php_unregister_one(php_slot->dn); in pnv_php_register_one()
969 pnv_php_put_slot(php_slot); in pnv_php_register_one()
989 struct pnv_php_slot *php_slot; in pnv_php_unregister_one() local
991 php_slot = pnv_php_find_slot(dn); in pnv_php_unregister_one()
992 if (!php_slot) in pnv_php_unregister_one()
995 php_slot->state = PNV_PHP_STATE_OFFLINE; in pnv_php_unregister_one()
996 pci_hp_deregister(&php_slot->slot); in pnv_php_unregister_one()
997 pnv_php_release(php_slot); in pnv_php_unregister_one()
998 pnv_php_put_slot(php_slot); in pnv_php_unregister_one()