Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * PCI Hotplug Driver for PowerPC PowerNV platform.
0004  *
0005  * Copyright Gavin Shan, IBM Corporation 2016.
0006  */
0007 
0008 #include <linux/libfdt.h>
0009 #include <linux/module.h>
0010 #include <linux/pci.h>
0011 #include <linux/pci_hotplug.h>
0012 #include <linux/of_fdt.h>
0013 
0014 #include <asm/opal.h>
0015 #include <asm/pnv-pci.h>
0016 #include <asm/ppc-pci.h>
0017 
0018 #define DRIVER_VERSION  "0.1"
0019 #define DRIVER_AUTHOR   "Gavin Shan, IBM Corporation"
0020 #define DRIVER_DESC "PowerPC PowerNV PCI Hotplug Driver"
0021 
0022 #define SLOT_WARN(sl, x...) \
0023     ((sl)->pdev ? pci_warn((sl)->pdev, x) : dev_warn(&(sl)->bus->dev, x))
0024 
0025 struct pnv_php_event {
0026     bool            added;
0027     struct pnv_php_slot *php_slot;
0028     struct work_struct  work;
0029 };
0030 
0031 static LIST_HEAD(pnv_php_slot_list);
0032 static DEFINE_SPINLOCK(pnv_php_lock);
0033 
0034 static void pnv_php_register(struct device_node *dn);
0035 static void pnv_php_unregister_one(struct device_node *dn);
0036 static void pnv_php_unregister(struct device_node *dn);
0037 
0038 static void pnv_php_disable_irq(struct pnv_php_slot *php_slot,
0039                 bool disable_device)
0040 {
0041     struct pci_dev *pdev = php_slot->pdev;
0042     int irq = php_slot->irq;
0043     u16 ctrl;
0044 
0045     if (php_slot->irq > 0) {
0046         pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl);
0047         ctrl &= ~(PCI_EXP_SLTCTL_HPIE |
0048               PCI_EXP_SLTCTL_PDCE |
0049               PCI_EXP_SLTCTL_DLLSCE);
0050         pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl);
0051 
0052         free_irq(php_slot->irq, php_slot);
0053         php_slot->irq = 0;
0054     }
0055 
0056     if (php_slot->wq) {
0057         destroy_workqueue(php_slot->wq);
0058         php_slot->wq = NULL;
0059     }
0060 
0061     if (disable_device || irq > 0) {
0062         if (pdev->msix_enabled)
0063             pci_disable_msix(pdev);
0064         else if (pdev->msi_enabled)
0065             pci_disable_msi(pdev);
0066 
0067         pci_disable_device(pdev);
0068     }
0069 }
0070 
0071 static void pnv_php_free_slot(struct kref *kref)
0072 {
0073     struct pnv_php_slot *php_slot = container_of(kref,
0074                     struct pnv_php_slot, kref);
0075 
0076     WARN_ON(!list_empty(&php_slot->children));
0077     pnv_php_disable_irq(php_slot, false);
0078     kfree(php_slot->name);
0079     kfree(php_slot);
0080 }
0081 
0082 static inline void pnv_php_put_slot(struct pnv_php_slot *php_slot)
0083 {
0084 
0085     if (!php_slot)
0086         return;
0087 
0088     kref_put(&php_slot->kref, pnv_php_free_slot);
0089 }
0090 
0091 static struct pnv_php_slot *pnv_php_match(struct device_node *dn,
0092                       struct pnv_php_slot *php_slot)
0093 {
0094     struct pnv_php_slot *target, *tmp;
0095 
0096     if (php_slot->dn == dn) {
0097         kref_get(&php_slot->kref);
0098         return php_slot;
0099     }
0100 
0101     list_for_each_entry(tmp, &php_slot->children, link) {
0102         target = pnv_php_match(dn, tmp);
0103         if (target)
0104             return target;
0105     }
0106 
0107     return NULL;
0108 }
0109 
0110 struct pnv_php_slot *pnv_php_find_slot(struct device_node *dn)
0111 {
0112     struct pnv_php_slot *php_slot, *tmp;
0113     unsigned long flags;
0114 
0115     spin_lock_irqsave(&pnv_php_lock, flags);
0116     list_for_each_entry(tmp, &pnv_php_slot_list, link) {
0117         php_slot = pnv_php_match(dn, tmp);
0118         if (php_slot) {
0119             spin_unlock_irqrestore(&pnv_php_lock, flags);
0120             return php_slot;
0121         }
0122     }
0123     spin_unlock_irqrestore(&pnv_php_lock, flags);
0124 
0125     return NULL;
0126 }
0127 EXPORT_SYMBOL_GPL(pnv_php_find_slot);
0128 
0129 /*
0130  * Remove pdn for all children of the indicated device node.
0131  * The function should remove pdn in a depth-first manner.
0132  */
0133 static void pnv_php_rmv_pdns(struct device_node *dn)
0134 {
0135     struct device_node *child;
0136 
0137     for_each_child_of_node(dn, child) {
0138         pnv_php_rmv_pdns(child);
0139 
0140         pci_remove_device_node_info(child);
0141     }
0142 }
0143 
0144 /*
0145  * Detach all child nodes of the indicated device nodes. The
0146  * function should handle device nodes in depth-first manner.
0147  *
0148  * We should not invoke of_node_release() as the memory for
0149  * individual device node is part of large memory block. The
0150  * large block is allocated from memblock (system bootup) or
0151  * kmalloc() when unflattening the device tree by OF changeset.
0152  * We can not free the large block allocated from memblock. For
0153  * later case, it should be released at once.
0154  */
0155 static void pnv_php_detach_device_nodes(struct device_node *parent)
0156 {
0157     struct device_node *dn;
0158 
0159     for_each_child_of_node(parent, dn) {
0160         pnv_php_detach_device_nodes(dn);
0161 
0162         of_node_put(dn);
0163         of_detach_node(dn);
0164     }
0165 }
0166 
0167 static void pnv_php_rmv_devtree(struct pnv_php_slot *php_slot)
0168 {
0169     pnv_php_rmv_pdns(php_slot->dn);
0170 
0171     /*
0172      * Decrease the refcount if the device nodes were created
0173      * through OF changeset before detaching them.
0174      */
0175     if (php_slot->fdt)
0176         of_changeset_destroy(&php_slot->ocs);
0177     pnv_php_detach_device_nodes(php_slot->dn);
0178 
0179     if (php_slot->fdt) {
0180         kfree(php_slot->dt);
0181         kfree(php_slot->fdt);
0182         php_slot->dt        = NULL;
0183         php_slot->dn->child = NULL;
0184         php_slot->fdt       = NULL;
0185     }
0186 }
0187 
0188 /*
0189  * As the nodes in OF changeset are applied in reverse order, we
0190  * need revert the nodes in advance so that we have correct node
0191  * order after the changeset is applied.
0192  */
0193 static void pnv_php_reverse_nodes(struct device_node *parent)
0194 {
0195     struct device_node *child, *next;
0196 
0197     /* In-depth first */
0198     for_each_child_of_node(parent, child)
0199         pnv_php_reverse_nodes(child);
0200 
0201     /* Reverse the nodes in the child list */
0202     child = parent->child;
0203     parent->child = NULL;
0204     while (child) {
0205         next = child->sibling;
0206 
0207         child->sibling = parent->child;
0208         parent->child = child;
0209         child = next;
0210     }
0211 }
0212 
0213 static int pnv_php_populate_changeset(struct of_changeset *ocs,
0214                       struct device_node *dn)
0215 {
0216     struct device_node *child;
0217     int ret = 0;
0218 
0219     for_each_child_of_node(dn, child) {
0220         ret = of_changeset_attach_node(ocs, child);
0221         if (ret) {
0222             of_node_put(child);
0223             break;
0224         }
0225 
0226         ret = pnv_php_populate_changeset(ocs, child);
0227         if (ret) {
0228             of_node_put(child);
0229             break;
0230         }
0231     }
0232 
0233     return ret;
0234 }
0235 
0236 static void *pnv_php_add_one_pdn(struct device_node *dn, void *data)
0237 {
0238     struct pci_controller *hose = (struct pci_controller *)data;
0239     struct pci_dn *pdn;
0240 
0241     pdn = pci_add_device_node_info(hose, dn);
0242     if (!pdn)
0243         return ERR_PTR(-ENOMEM);
0244 
0245     return NULL;
0246 }
0247 
0248 static void pnv_php_add_pdns(struct pnv_php_slot *slot)
0249 {
0250     struct pci_controller *hose = pci_bus_to_host(slot->bus);
0251 
0252     pci_traverse_device_nodes(slot->dn, pnv_php_add_one_pdn, hose);
0253 }
0254 
0255 static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
0256 {
0257     void *fdt, *fdt1, *dt;
0258     int ret;
0259 
0260     /* We don't know the FDT blob size. We try to get it through
0261      * maximal memory chunk and then copy it to another chunk that
0262      * fits the real size.
0263      */
0264     fdt1 = kzalloc(0x10000, GFP_KERNEL);
0265     if (!fdt1) {
0266         ret = -ENOMEM;
0267         goto out;
0268     }
0269 
0270     ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
0271     if (ret) {
0272         SLOT_WARN(php_slot, "Error %d getting FDT blob\n", ret);
0273         goto free_fdt1;
0274     }
0275 
0276     fdt = kmemdup(fdt1, fdt_totalsize(fdt1), GFP_KERNEL);
0277     if (!fdt) {
0278         ret = -ENOMEM;
0279         goto free_fdt1;
0280     }
0281 
0282     /* Unflatten device tree blob */
0283     dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL);
0284     if (!dt) {
0285         ret = -EINVAL;
0286         SLOT_WARN(php_slot, "Cannot unflatten FDT\n");
0287         goto free_fdt;
0288     }
0289 
0290     /* Initialize and apply the changeset */
0291     of_changeset_init(&php_slot->ocs);
0292     pnv_php_reverse_nodes(php_slot->dn);
0293     ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn);
0294     if (ret) {
0295         pnv_php_reverse_nodes(php_slot->dn);
0296         SLOT_WARN(php_slot, "Error %d populating changeset\n",
0297               ret);
0298         goto free_dt;
0299     }
0300 
0301     php_slot->dn->child = NULL;
0302     ret = of_changeset_apply(&php_slot->ocs);
0303     if (ret) {
0304         SLOT_WARN(php_slot, "Error %d applying changeset\n", ret);
0305         goto destroy_changeset;
0306     }
0307 
0308     /* Add device node firmware data */
0309     pnv_php_add_pdns(php_slot);
0310     php_slot->fdt = fdt;
0311     php_slot->dt  = dt;
0312     kfree(fdt1);
0313     goto out;
0314 
0315 destroy_changeset:
0316     of_changeset_destroy(&php_slot->ocs);
0317 free_dt:
0318     kfree(dt);
0319     php_slot->dn->child = NULL;
0320 free_fdt:
0321     kfree(fdt);
0322 free_fdt1:
0323     kfree(fdt1);
0324 out:
0325     return ret;
0326 }
0327 
0328 static inline struct pnv_php_slot *to_pnv_php_slot(struct hotplug_slot *slot)
0329 {
0330     return container_of(slot, struct pnv_php_slot, slot);
0331 }
0332 
0333 int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
0334                  uint8_t state)
0335 {
0336     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0337     struct opal_msg msg;
0338     int ret;
0339 
0340     ret = pnv_pci_set_power_state(php_slot->id, state, &msg);
0341     if (ret > 0) {
0342         if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle ||
0343             be64_to_cpu(msg.params[2]) != state) {
0344             SLOT_WARN(php_slot, "Wrong msg (%lld, %lld, %lld)\n",
0345                   be64_to_cpu(msg.params[1]),
0346                   be64_to_cpu(msg.params[2]),
0347                   be64_to_cpu(msg.params[3]));
0348             return -ENOMSG;
0349         }
0350         if (be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
0351             ret = -ENODEV;
0352             goto error;
0353         }
0354     } else if (ret < 0) {
0355         goto error;
0356     }
0357 
0358     if (state == OPAL_PCI_SLOT_POWER_OFF || state == OPAL_PCI_SLOT_OFFLINE)
0359         pnv_php_rmv_devtree(php_slot);
0360     else
0361         ret = pnv_php_add_devtree(php_slot);
0362 
0363     return ret;
0364 
0365 error:
0366     SLOT_WARN(php_slot, "Error %d powering %s\n",
0367           ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
0368     return ret;
0369 }
0370 EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state);
0371 
0372 static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
0373 {
0374     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0375     uint8_t power_state = OPAL_PCI_SLOT_POWER_ON;
0376     int ret;
0377 
0378     /*
0379      * Retrieve power status from firmware. If we fail
0380      * getting that, the power status fails back to
0381      * be on.
0382      */
0383     ret = pnv_pci_get_power_state(php_slot->id, &power_state);
0384     if (ret) {
0385         SLOT_WARN(php_slot, "Error %d getting power status\n",
0386               ret);
0387     } else {
0388         *state = power_state;
0389     }
0390 
0391     return 0;
0392 }
0393 
0394 static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
0395 {
0396     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0397     uint8_t presence = OPAL_PCI_SLOT_EMPTY;
0398     int ret;
0399 
0400     /*
0401      * Retrieve presence status from firmware. If we can't
0402      * get that, it will fail back to be empty.
0403      */
0404     ret = pnv_pci_get_presence_state(php_slot->id, &presence);
0405     if (ret >= 0) {
0406         *state = presence;
0407         ret = 0;
0408     } else {
0409         SLOT_WARN(php_slot, "Error %d getting presence\n", ret);
0410     }
0411 
0412     return ret;
0413 }
0414 
0415 static int pnv_php_get_attention_state(struct hotplug_slot *slot, u8 *state)
0416 {
0417     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0418 
0419     *state = php_slot->attention_state;
0420     return 0;
0421 }
0422 
0423 static int pnv_php_set_attention_state(struct hotplug_slot *slot, u8 state)
0424 {
0425     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0426     struct pci_dev *bridge = php_slot->pdev;
0427     u16 new, mask;
0428 
0429     php_slot->attention_state = state;
0430     if (!bridge)
0431         return 0;
0432 
0433     mask = PCI_EXP_SLTCTL_AIC;
0434 
0435     if (state)
0436         new = PCI_EXP_SLTCTL_ATTN_IND_ON;
0437     else
0438         new = PCI_EXP_SLTCTL_ATTN_IND_OFF;
0439 
0440     pcie_capability_clear_and_set_word(bridge, PCI_EXP_SLTCTL, mask, new);
0441 
0442     return 0;
0443 }
0444 
0445 static int pnv_php_enable(struct pnv_php_slot *php_slot, bool rescan)
0446 {
0447     struct hotplug_slot *slot = &php_slot->slot;
0448     uint8_t presence = OPAL_PCI_SLOT_EMPTY;
0449     uint8_t power_status = OPAL_PCI_SLOT_POWER_ON;
0450     int ret;
0451 
0452     /* Check if the slot has been configured */
0453     if (php_slot->state != PNV_PHP_STATE_REGISTERED)
0454         return 0;
0455 
0456     /* Retrieve slot presence status */
0457     ret = pnv_php_get_adapter_state(slot, &presence);
0458     if (ret)
0459         return ret;
0460 
0461     /*
0462      * Proceed if there have nothing behind the slot. However,
0463      * we should leave the slot in registered state at the
0464      * beginning. Otherwise, the PCI devices inserted afterwards
0465      * won't be probed and populated.
0466      */
0467     if (presence == OPAL_PCI_SLOT_EMPTY) {
0468         if (!php_slot->power_state_check) {
0469             php_slot->power_state_check = true;
0470 
0471             return 0;
0472         }
0473 
0474         goto scan;
0475     }
0476 
0477     /*
0478      * If the power supply to the slot is off, we can't detect
0479      * adapter presence state. That means we have to turn the
0480      * slot on before going to probe slot's presence state.
0481      *
0482      * On the first time, we don't change the power status to
0483      * boost system boot with assumption that the firmware
0484      * supplies consistent slot power status: empty slot always
0485      * has its power off and non-empty slot has its power on.
0486      */
0487     if (!php_slot->power_state_check) {
0488         php_slot->power_state_check = true;
0489 
0490         ret = pnv_php_get_power_state(slot, &power_status);
0491         if (ret)
0492             return ret;
0493 
0494         if (power_status != OPAL_PCI_SLOT_POWER_ON)
0495             return 0;
0496     }
0497 
0498     /* Check the power status. Scan the slot if it is already on */
0499     ret = pnv_php_get_power_state(slot, &power_status);
0500     if (ret)
0501         return ret;
0502 
0503     if (power_status == OPAL_PCI_SLOT_POWER_ON)
0504         goto scan;
0505 
0506     /* Power is off, turn it on and then scan the slot */
0507     ret = pnv_php_set_slot_power_state(slot, OPAL_PCI_SLOT_POWER_ON);
0508     if (ret)
0509         return ret;
0510 
0511 scan:
0512     if (presence == OPAL_PCI_SLOT_PRESENT) {
0513         if (rescan) {
0514             pci_lock_rescan_remove();
0515             pci_hp_add_devices(php_slot->bus);
0516             pci_unlock_rescan_remove();
0517         }
0518 
0519         /* Rescan for child hotpluggable slots */
0520         php_slot->state = PNV_PHP_STATE_POPULATED;
0521         if (rescan)
0522             pnv_php_register(php_slot->dn);
0523     } else {
0524         php_slot->state = PNV_PHP_STATE_POPULATED;
0525     }
0526 
0527     return 0;
0528 }
0529 
0530 static int pnv_php_reset_slot(struct hotplug_slot *slot, bool probe)
0531 {
0532     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0533     struct pci_dev *bridge = php_slot->pdev;
0534     uint16_t sts;
0535 
0536     /*
0537      * The CAPI folks want pnv_php to drive OpenCAPI slots
0538      * which don't have a bridge. Only claim to support
0539      * reset_slot() if we have a bridge device (for now...)
0540      */
0541     if (probe)
0542         return !bridge;
0543 
0544     /* mask our interrupt while resetting the bridge */
0545     if (php_slot->irq > 0)
0546         disable_irq(php_slot->irq);
0547 
0548     pci_bridge_secondary_bus_reset(bridge);
0549 
0550     /* clear any state changes that happened due to the reset */
0551     pcie_capability_read_word(php_slot->pdev, PCI_EXP_SLTSTA, &sts);
0552     sts &= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
0553     pcie_capability_write_word(php_slot->pdev, PCI_EXP_SLTSTA, sts);
0554 
0555     if (php_slot->irq > 0)
0556         enable_irq(php_slot->irq);
0557 
0558     return 0;
0559 }
0560 
0561 static int pnv_php_enable_slot(struct hotplug_slot *slot)
0562 {
0563     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0564 
0565     return pnv_php_enable(php_slot, true);
0566 }
0567 
0568 static int pnv_php_disable_slot(struct hotplug_slot *slot)
0569 {
0570     struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
0571     int ret;
0572 
0573     /*
0574      * Allow to disable a slot already in the registered state to
0575      * cover cases where the slot couldn't be enabled and never
0576      * reached the populated state
0577      */
0578     if (php_slot->state != PNV_PHP_STATE_POPULATED &&
0579         php_slot->state != PNV_PHP_STATE_REGISTERED)
0580         return 0;
0581 
0582     /* Remove all devices behind the slot */
0583     pci_lock_rescan_remove();
0584     pci_hp_remove_devices(php_slot->bus);
0585     pci_unlock_rescan_remove();
0586 
0587     /* Detach the child hotpluggable slots */
0588     pnv_php_unregister(php_slot->dn);
0589 
0590     /* Notify firmware and remove device nodes */
0591     ret = pnv_php_set_slot_power_state(slot, OPAL_PCI_SLOT_POWER_OFF);
0592 
0593     php_slot->state = PNV_PHP_STATE_REGISTERED;
0594     return ret;
0595 }
0596 
0597 static const struct hotplug_slot_ops php_slot_ops = {
0598     .get_power_status   = pnv_php_get_power_state,
0599     .get_adapter_status = pnv_php_get_adapter_state,
0600     .get_attention_status   = pnv_php_get_attention_state,
0601     .set_attention_status   = pnv_php_set_attention_state,
0602     .enable_slot        = pnv_php_enable_slot,
0603     .disable_slot       = pnv_php_disable_slot,
0604     .reset_slot     = pnv_php_reset_slot,
0605 };
0606 
0607 static void pnv_php_release(struct pnv_php_slot *php_slot)
0608 {
0609     unsigned long flags;
0610 
0611     /* Remove from global or child list */
0612     spin_lock_irqsave(&pnv_php_lock, flags);
0613     list_del(&php_slot->link);
0614     spin_unlock_irqrestore(&pnv_php_lock, flags);
0615 
0616     /* Detach from parent */
0617     pnv_php_put_slot(php_slot);
0618     pnv_php_put_slot(php_slot->parent);
0619 }
0620 
0621 static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn)
0622 {
0623     struct pnv_php_slot *php_slot;
0624     struct pci_bus *bus;
0625     const char *label;
0626     uint64_t id;
0627     int ret;
0628 
0629     ret = of_property_read_string(dn, "ibm,slot-label", &label);
0630     if (ret)
0631         return NULL;
0632 
0633     if (pnv_pci_get_slot_id(dn, &id))
0634         return NULL;
0635 
0636     bus = pci_find_bus_by_node(dn);
0637     if (!bus)
0638         return NULL;
0639 
0640     php_slot = kzalloc(sizeof(*php_slot), GFP_KERNEL);
0641     if (!php_slot)
0642         return NULL;
0643 
0644     php_slot->name = kstrdup(label, GFP_KERNEL);
0645     if (!php_slot->name) {
0646         kfree(php_slot);
0647         return NULL;
0648     }
0649 
0650     if (dn->child && PCI_DN(dn->child))
0651         php_slot->slot_no = PCI_SLOT(PCI_DN(dn->child)->devfn);
0652     else
0653         php_slot->slot_no = -1;   /* Placeholder slot */
0654 
0655     kref_init(&php_slot->kref);
0656     php_slot->state                 = PNV_PHP_STATE_INITIALIZED;
0657     php_slot->dn                    = dn;
0658     php_slot->pdev                  = bus->self;
0659     php_slot->bus                   = bus;
0660     php_slot->id                    = id;
0661     php_slot->power_state_check     = false;
0662     php_slot->slot.ops              = &php_slot_ops;
0663 
0664     INIT_LIST_HEAD(&php_slot->children);
0665     INIT_LIST_HEAD(&php_slot->link);
0666 
0667     return php_slot;
0668 }
0669 
0670 static int pnv_php_register_slot(struct pnv_php_slot *php_slot)
0671 {
0672     struct pnv_php_slot *parent;
0673     struct device_node *dn = php_slot->dn;
0674     unsigned long flags;
0675     int ret;
0676 
0677     /* Check if the slot is registered or not */
0678     parent = pnv_php_find_slot(php_slot->dn);
0679     if (parent) {
0680         pnv_php_put_slot(parent);
0681         return -EEXIST;
0682     }
0683 
0684     /* Register PCI slot */
0685     ret = pci_hp_register(&php_slot->slot, php_slot->bus,
0686                   php_slot->slot_no, php_slot->name);
0687     if (ret) {
0688         SLOT_WARN(php_slot, "Error %d registering slot\n", ret);
0689         return ret;
0690     }
0691 
0692     /* Attach to the parent's child list or global list */
0693     while ((dn = of_get_parent(dn))) {
0694         if (!PCI_DN(dn)) {
0695             of_node_put(dn);
0696             break;
0697         }
0698 
0699         parent = pnv_php_find_slot(dn);
0700         if (parent) {
0701             of_node_put(dn);
0702             break;
0703         }
0704 
0705         of_node_put(dn);
0706     }
0707 
0708     spin_lock_irqsave(&pnv_php_lock, flags);
0709     php_slot->parent = parent;
0710     if (parent)
0711         list_add_tail(&php_slot->link, &parent->children);
0712     else
0713         list_add_tail(&php_slot->link, &pnv_php_slot_list);
0714     spin_unlock_irqrestore(&pnv_php_lock, flags);
0715 
0716     php_slot->state = PNV_PHP_STATE_REGISTERED;
0717     return 0;
0718 }
0719 
0720 static int pnv_php_enable_msix(struct pnv_php_slot *php_slot)
0721 {
0722     struct pci_dev *pdev = php_slot->pdev;
0723     struct msix_entry entry;
0724     int nr_entries, ret;
0725     u16 pcie_flag;
0726 
0727     /* Get total number of MSIx entries */
0728     nr_entries = pci_msix_vec_count(pdev);
0729     if (nr_entries < 0)
0730         return nr_entries;
0731 
0732     /* Check hotplug MSIx entry is in range */
0733     pcie_capability_read_word(pdev, PCI_EXP_FLAGS, &pcie_flag);
0734     entry.entry = (pcie_flag & PCI_EXP_FLAGS_IRQ) >> 9;
0735     if (entry.entry >= nr_entries)
0736         return -ERANGE;
0737 
0738     /* Enable MSIx */
0739     ret = pci_enable_msix_exact(pdev, &entry, 1);
0740     if (ret) {
0741         SLOT_WARN(php_slot, "Error %d enabling MSIx\n", ret);
0742         return ret;
0743     }
0744 
0745     return entry.vector;
0746 }
0747 
0748 static void pnv_php_event_handler(struct work_struct *work)
0749 {
0750     struct pnv_php_event *event =
0751         container_of(work, struct pnv_php_event, work);
0752     struct pnv_php_slot *php_slot = event->php_slot;
0753 
0754     if (event->added)
0755         pnv_php_enable_slot(&php_slot->slot);
0756     else
0757         pnv_php_disable_slot(&php_slot->slot);
0758 
0759     kfree(event);
0760 }
0761 
0762 static irqreturn_t pnv_php_interrupt(int irq, void *data)
0763 {
0764     struct pnv_php_slot *php_slot = data;
0765     struct pci_dev *pchild, *pdev = php_slot->pdev;
0766     struct eeh_dev *edev;
0767     struct eeh_pe *pe;
0768     struct pnv_php_event *event;
0769     u16 sts, lsts;
0770     u8 presence;
0771     bool added;
0772     unsigned long flags;
0773     int ret;
0774 
0775     pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
0776     sts &= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
0777     pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
0778 
0779     pci_dbg(pdev, "PCI slot [%s]: HP int! DLAct: %d, PresDet: %d\n",
0780             php_slot->name,
0781             !!(sts & PCI_EXP_SLTSTA_DLLSC),
0782             !!(sts & PCI_EXP_SLTSTA_PDC));
0783 
0784     if (sts & PCI_EXP_SLTSTA_DLLSC) {
0785         pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lsts);
0786         added = !!(lsts & PCI_EXP_LNKSTA_DLLLA);
0787     } else if (!(php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) &&
0788            (sts & PCI_EXP_SLTSTA_PDC)) {
0789         ret = pnv_pci_get_presence_state(php_slot->id, &presence);
0790         if (ret) {
0791             SLOT_WARN(php_slot,
0792                   "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
0793                   php_slot->name, ret, sts);
0794             return IRQ_HANDLED;
0795         }
0796 
0797         added = !!(presence == OPAL_PCI_SLOT_PRESENT);
0798     } else {
0799         pci_dbg(pdev, "PCI slot [%s]: Spurious IRQ?\n", php_slot->name);
0800         return IRQ_NONE;
0801     }
0802 
0803     /* Freeze the removed PE to avoid unexpected error reporting */
0804     if (!added) {
0805         pchild = list_first_entry_or_null(&php_slot->bus->devices,
0806                           struct pci_dev, bus_list);
0807         edev = pchild ? pci_dev_to_eeh_dev(pchild) : NULL;
0808         pe = edev ? edev->pe : NULL;
0809         if (pe) {
0810             eeh_serialize_lock(&flags);
0811             eeh_pe_mark_isolated(pe);
0812             eeh_serialize_unlock(flags);
0813             eeh_pe_set_option(pe, EEH_OPT_FREEZE_PE);
0814         }
0815     }
0816 
0817     /*
0818      * The PE is left in frozen state if the event is missed. It's
0819      * fine as the PCI devices (PE) aren't functional any more.
0820      */
0821     event = kzalloc(sizeof(*event), GFP_ATOMIC);
0822     if (!event) {
0823         SLOT_WARN(php_slot,
0824               "PCI slot [%s] missed hotplug event 0x%04x\n",
0825               php_slot->name, sts);
0826         return IRQ_HANDLED;
0827     }
0828 
0829     pci_info(pdev, "PCI slot [%s] %s (IRQ: %d)\n",
0830          php_slot->name, added ? "added" : "removed", irq);
0831     INIT_WORK(&event->work, pnv_php_event_handler);
0832     event->added = added;
0833     event->php_slot = php_slot;
0834     queue_work(php_slot->wq, &event->work);
0835 
0836     return IRQ_HANDLED;
0837 }
0838 
0839 static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
0840 {
0841     struct pci_dev *pdev = php_slot->pdev;
0842     u32 broken_pdc = 0;
0843     u16 sts, ctrl;
0844     int ret;
0845 
0846     /* Allocate workqueue */
0847     php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
0848     if (!php_slot->wq) {
0849         SLOT_WARN(php_slot, "Cannot alloc workqueue\n");
0850         pnv_php_disable_irq(php_slot, true);
0851         return;
0852     }
0853 
0854     /* Check PDC (Presence Detection Change) is broken or not */
0855     ret = of_property_read_u32(php_slot->dn, "ibm,slot-broken-pdc",
0856                    &broken_pdc);
0857     if (!ret && broken_pdc)
0858         php_slot->flags |= PNV_PHP_FLAG_BROKEN_PDC;
0859 
0860     /* Clear pending interrupts */
0861     pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &sts);
0862     if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC)
0863         sts |= PCI_EXP_SLTSTA_DLLSC;
0864     else
0865         sts |= (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC);
0866     pcie_capability_write_word(pdev, PCI_EXP_SLTSTA, sts);
0867 
0868     /* Request the interrupt */
0869     ret = request_irq(irq, pnv_php_interrupt, IRQF_SHARED,
0870               php_slot->name, php_slot);
0871     if (ret) {
0872         pnv_php_disable_irq(php_slot, true);
0873         SLOT_WARN(php_slot, "Error %d enabling IRQ %d\n", ret, irq);
0874         return;
0875     }
0876 
0877     /* Enable the interrupts */
0878     pcie_capability_read_word(pdev, PCI_EXP_SLTCTL, &ctrl);
0879     if (php_slot->flags & PNV_PHP_FLAG_BROKEN_PDC) {
0880         ctrl &= ~PCI_EXP_SLTCTL_PDCE;
0881         ctrl |= (PCI_EXP_SLTCTL_HPIE |
0882              PCI_EXP_SLTCTL_DLLSCE);
0883     } else {
0884         ctrl |= (PCI_EXP_SLTCTL_HPIE |
0885              PCI_EXP_SLTCTL_PDCE |
0886              PCI_EXP_SLTCTL_DLLSCE);
0887     }
0888     pcie_capability_write_word(pdev, PCI_EXP_SLTCTL, ctrl);
0889 
0890     /* The interrupt is initialized successfully when @irq is valid */
0891     php_slot->irq = irq;
0892 }
0893 
0894 static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
0895 {
0896     struct pci_dev *pdev = php_slot->pdev;
0897     int irq, ret;
0898 
0899     /*
0900      * The MSI/MSIx interrupt might have been occupied by other
0901      * drivers. Don't populate the surprise hotplug capability
0902      * in that case.
0903      */
0904     if (pci_dev_msi_enabled(pdev))
0905         return;
0906 
0907     ret = pci_enable_device(pdev);
0908     if (ret) {
0909         SLOT_WARN(php_slot, "Error %d enabling device\n", ret);
0910         return;
0911     }
0912 
0913     pci_set_master(pdev);
0914 
0915     /* Enable MSIx interrupt */
0916     irq = pnv_php_enable_msix(php_slot);
0917     if (irq > 0) {
0918         pnv_php_init_irq(php_slot, irq);
0919         return;
0920     }
0921 
0922     /*
0923      * Use MSI if MSIx doesn't work. Fail back to legacy INTx
0924      * if MSI doesn't work either
0925      */
0926     ret = pci_enable_msi(pdev);
0927     if (!ret || pdev->irq) {
0928         irq = pdev->irq;
0929         pnv_php_init_irq(php_slot, irq);
0930     }
0931 }
0932 
0933 static int pnv_php_register_one(struct device_node *dn)
0934 {
0935     struct pnv_php_slot *php_slot;
0936     u32 prop32;
0937     int ret;
0938 
0939     /* Check if it's hotpluggable slot */
0940     ret = of_property_read_u32(dn, "ibm,slot-pluggable", &prop32);
0941     if (ret || !prop32)
0942         return -ENXIO;
0943 
0944     ret = of_property_read_u32(dn, "ibm,reset-by-firmware", &prop32);
0945     if (ret || !prop32)
0946         return -ENXIO;
0947 
0948     php_slot = pnv_php_alloc_slot(dn);
0949     if (!php_slot)
0950         return -ENODEV;
0951 
0952     ret = pnv_php_register_slot(php_slot);
0953     if (ret)
0954         goto free_slot;
0955 
0956     ret = pnv_php_enable(php_slot, false);
0957     if (ret)
0958         goto unregister_slot;
0959 
0960     /* Enable interrupt if the slot supports surprise hotplug */
0961     ret = of_property_read_u32(dn, "ibm,slot-surprise-pluggable", &prop32);
0962     if (!ret && prop32)
0963         pnv_php_enable_irq(php_slot);
0964 
0965     return 0;
0966 
0967 unregister_slot:
0968     pnv_php_unregister_one(php_slot->dn);
0969 free_slot:
0970     pnv_php_put_slot(php_slot);
0971     return ret;
0972 }
0973 
0974 static void pnv_php_register(struct device_node *dn)
0975 {
0976     struct device_node *child;
0977 
0978     /*
0979      * The parent slots should be registered before their
0980      * child slots.
0981      */
0982     for_each_child_of_node(dn, child) {
0983         pnv_php_register_one(child);
0984         pnv_php_register(child);
0985     }
0986 }
0987 
0988 static void pnv_php_unregister_one(struct device_node *dn)
0989 {
0990     struct pnv_php_slot *php_slot;
0991 
0992     php_slot = pnv_php_find_slot(dn);
0993     if (!php_slot)
0994         return;
0995 
0996     php_slot->state = PNV_PHP_STATE_OFFLINE;
0997     pci_hp_deregister(&php_slot->slot);
0998     pnv_php_release(php_slot);
0999     pnv_php_put_slot(php_slot);
1000 }
1001 
1002 static void pnv_php_unregister(struct device_node *dn)
1003 {
1004     struct device_node *child;
1005 
1006     /* The child slots should go before their parent slots */
1007     for_each_child_of_node(dn, child) {
1008         pnv_php_unregister(child);
1009         pnv_php_unregister_one(child);
1010     }
1011 }
1012 
1013 static int __init pnv_php_init(void)
1014 {
1015     struct device_node *dn;
1016 
1017     pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
1018     for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
1019         pnv_php_register(dn);
1020 
1021     for_each_compatible_node(dn, NULL, "ibm,ioda3-phb")
1022         pnv_php_register(dn);
1023 
1024     for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb")
1025         pnv_php_register_one(dn); /* slot directly under the PHB */
1026     return 0;
1027 }
1028 
1029 static void __exit pnv_php_exit(void)
1030 {
1031     struct device_node *dn;
1032 
1033     for_each_compatible_node(dn, NULL, "ibm,ioda2-phb")
1034         pnv_php_unregister(dn);
1035 
1036     for_each_compatible_node(dn, NULL, "ibm,ioda3-phb")
1037         pnv_php_unregister(dn);
1038 
1039     for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb")
1040         pnv_php_unregister_one(dn); /* slot directly under the PHB */
1041 }
1042 
1043 module_init(pnv_php_init);
1044 module_exit(pnv_php_exit);
1045 
1046 MODULE_VERSION(DRIVER_VERSION);
1047 MODULE_LICENSE("GPL v2");
1048 MODULE_AUTHOR(DRIVER_AUTHOR);
1049 MODULE_DESCRIPTION(DRIVER_DESC);