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