get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/633520/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 633520,
    "url": "http://patchwork.ozlabs.org/api/patches/633520/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/skiboot/patch/1465535032-26749-23-git-send-email-gwshan@linux.vnet.ibm.com/",
    "project": {
        "id": 44,
        "url": "http://patchwork.ozlabs.org/api/projects/44/?format=api",
        "name": "skiboot firmware development",
        "link_name": "skiboot",
        "list_id": "skiboot.lists.ozlabs.org",
        "list_email": "skiboot@lists.ozlabs.org",
        "web_url": "http://github.com/open-power/skiboot",
        "scm_url": "http://github.com/open-power/skiboot",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1465535032-26749-23-git-send-email-gwshan@linux.vnet.ibm.com>",
    "list_archive_url": null,
    "date": "2016-06-10T05:03:51",
    "name": "[v12,22/23] core/opal: Support PCI slot and new APIs",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "36fdc7319ed2f9a3ba13aa6cbc642e36b8c21999",
    "submitter": {
        "id": 63923,
        "url": "http://patchwork.ozlabs.org/api/people/63923/?format=api",
        "name": "Gavin Shan",
        "email": "gwshan@linux.vnet.ibm.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/skiboot/patch/1465535032-26749-23-git-send-email-gwshan@linux.vnet.ibm.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/633520/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/633520/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "skiboot@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "skiboot@lists.ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3rQqtY66khz9sD3\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 10 Jun 2016 15:07:49 +1000 (AEST)",
            "from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3rQqtY4vxPzDqdr\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 10 Jun 2016 15:07:49 +1000 (AEST)",
            "from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com\n\t[148.163.158.5])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3rQqrM4MrqzDqHw\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:05:55 +1000 (AEST)",
            "from pps.filterd (m0048817.ppops.net [127.0.0.1])\n\tby mx0b-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id\n\tu5A54X0j045918\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 01:05:53 -0400",
            "from e23smtp01.au.ibm.com (e23smtp01.au.ibm.com [202.81.31.143])\n\tby mx0b-001b2d01.pphosted.com with ESMTP id 23fm6pjtte-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 01:05:53 -0400",
            "from localhost\n\tby e23smtp01.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <skiboot@lists.ozlabs.org> from <gwshan@linux.vnet.ibm.com>;\n\tFri, 10 Jun 2016 15:05:49 +1000",
            "from d23dlp01.au.ibm.com (202.81.31.203)\n\tby e23smtp01.au.ibm.com (202.81.31.207) with IBM ESMTP SMTP Gateway:\n\tAuthorized Use Only! Violators will be prosecuted; \n\tFri, 10 Jun 2016 15:05:48 +1000",
            "from d23relay08.au.ibm.com (d23relay08.au.ibm.com [9.185.71.33])\n\tby d23dlp01.au.ibm.com (Postfix) with ESMTP id 11A7D2CE8046\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:05:43 +1000 (EST)",
            "from d23av06.au.ibm.com (d23av06.au.ibm.com [9.190.235.151])\n\tby d23relay08.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n\tu5A55W0760883064\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:05:32 +1000",
            "from d23av06.au.ibm.com (localhost [127.0.0.1])\n\tby d23av06.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id\n\tu5A5566s015025\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:05:07 +1000",
            "from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14])\n\tby d23av06.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id\n\tu5A556HV014551; Fri, 10 Jun 2016 15:05:06 +1000",
            "from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114])\n\tby ozlabs.au.ibm.com (Postfix) with ESMTP id 1E513A0389;\n\tFri, 10 Jun 2016 15:04:00 +1000 (AEST)",
            "from gwshan (shangw.ozlabs.ibm.com [10.61.2.199])\n\tby bran.ozlabs.ibm.com (Postfix) with ESMTP id 1D3C9E3B17;\n\tFri, 10 Jun 2016 15:04:00 +1000 (AEST)",
            "by gwshan (Postfix, from userid 1000)\n\tid 03343942CA3; Fri, 10 Jun 2016 15:03:59 +1000 (AEST)"
        ],
        "X-IBM-Helo": "d23dlp01.au.ibm.com",
        "X-IBM-MailFrom": "gwshan@linux.vnet.ibm.com",
        "X-IBM-RcptTo": "skiboot@lists.ozlabs.org",
        "From": "Gavin Shan <gwshan@linux.vnet.ibm.com>",
        "To": "skiboot@lists.ozlabs.org",
        "Date": "Fri, 10 Jun 2016 15:03:51 +1000",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1465535032-26749-1-git-send-email-gwshan@linux.vnet.ibm.com>",
        "References": "<1465535032-26749-1-git-send-email-gwshan@linux.vnet.ibm.com>",
        "X-TM-AS-MML": "disable",
        "X-Content-Scanned": "Fidelis XPS MAILER",
        "x-cbid": "16061005-1617-0000-0000-0000012AC839",
        "X-IBM-AV-DETECTION": "SAVI=unused REMOTE=unused XFE=unused",
        "x-cbparentid": "16061005-1618-0000-0000-0000460A8C73",
        "Message-Id": "<1465535032-26749-23-git-send-email-gwshan@linux.vnet.ibm.com>",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2016-06-10_04:, , signatures=0",
        "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=1\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000\n\tdefinitions=main-1606100058",
        "Subject": "[Skiboot] [PATCH v12 22/23] core/opal: Support PCI slot and new APIs",
        "X-BeenThere": "skiboot@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.22",
        "Precedence": "list",
        "List-Id": "Mailing list for skiboot development <skiboot.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/skiboot/>",
        "List-Post": "<mailto:skiboot@lists.ozlabs.org>",
        "List-Help": "<mailto:skiboot-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/skiboot>,\n\t<mailto:skiboot-request@lists.ozlabs.org?subject=subscribe>",
        "Cc": "alistair@popple.id.au",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org",
        "Sender": "\"Skiboot\"\n\t<skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org>"
    },
    "content": "The various reset requests are completed by PHB's callbacks. All\nof them (except reset on IODA table or error injection) are covered\nby PCI slot. opal_pci_poll() faces similar situation.\n\nThis reimplements opal_pci_reset() and opal_pci_poll() based on\nthe callbacks provided by PCI slot instead of PHB. Also, couple of\nnew APIs are introduced based on the callbacks in PCI slot as below:\n\n   * opal_pci_get_presence_state(): Check if there is adapter presented\n     behind the specified PHB or PCI slot.\n   * opal_pci_get_power_state(): Returns power supply state (on or off)\n     on the specified PHB or PCI slot.\n   * opal_pci_set_power_state(): Sets power supply state (on or off)\n     on the specified PHB or PCI slot. Besides, the state can be (offline\n     or online) without changing the PCI slot's power state.\n\nEventually, the definition of unused PHB's callbacks are removed.\n\nSigned-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>\nReviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>\nReviewed-by: Russell Currey <ruscur@russell.cc>\n---\n core/pci-opal.c                                  | 235 ++++++++++++++++++++---\n doc/opal-api/opal-pci-get-power-state-120.txt    |  19 ++\n doc/opal-api/opal-pci-get-presence-state-119.txt |  22 +++\n doc/opal-api/opal-pci-set-power-state-121.txt    |  36 ++++\n include/opal-api.h                               |   9 +-\n include/pci.h                                    |  72 -------\n 6 files changed, 293 insertions(+), 100 deletions(-)\n create mode 100644 doc/opal-api/opal-pci-get-power-state-120.txt\n create mode 100644 doc/opal-api/opal-pci-get-presence-state-119.txt\n create mode 100644 doc/opal-api/opal-pci-set-power-state-121.txt",
    "diff": "diff --git a/core/pci-opal.c b/core/pci-opal.c\nindex 40eda39..c0f399c 100644\n--- a/core/pci-opal.c\n+++ b/core/pci-opal.c\n@@ -18,7 +18,10 @@\n #include <opal-api.h>\n #include <pci.h>\n #include <pci-cfg.h>\n+#include <pci-slot.h>\n+#include <opal-msg.h>\n #include <timebase.h>\n+#include <timer.h>\n \n #define OPAL_PCICFG_ACCESS(op, cb, type)\t\\\n static int64_t opal_pci_config_##op(uint64_t phb_id,\t\t\t\\\n@@ -461,16 +464,15 @@ static int64_t opal_pci_map_pe_dma_window_real(uint64_t phb_id,\n }\n opal_call(OPAL_PCI_MAP_PE_DMA_WINDOW_REAL, opal_pci_map_pe_dma_window_real, 5);\n \n-static int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope,\n+static int64_t opal_pci_reset(uint64_t id, uint8_t reset_scope,\n                               uint8_t assert_state)\n {\n-\tstruct phb *phb = pci_get_phb(phb_id);\n+\tstruct pci_slot *slot = pci_slot_find(id);\n+\tstruct phb *phb = slot ? slot->phb : NULL;\n \tint64_t rc = OPAL_SUCCESS;\n \n-\tif (!phb)\n+\tif (!slot || !phb)\n \t\treturn OPAL_PARAMETER;\n-\tif (!phb->ops)\n-\t\treturn OPAL_UNSUPPORTED;\n \tif (assert_state != OPAL_ASSERT_RESET &&\n \t    assert_state != OPAL_DEASSERT_RESET)\n \t\treturn OPAL_PARAMETER;\n@@ -479,18 +481,22 @@ static int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope,\n \n \tswitch(reset_scope) {\n \tcase OPAL_RESET_PHB_COMPLETE:\n-\t\tif (!phb->ops->complete_reset) {\n+\t\t/* Complete reset is applicable to PHB slot only */\n+\t\tif (!slot->ops.creset || slot->pd) {\n \t\t\trc = OPAL_UNSUPPORTED;\n \t\t\tbreak;\n \t\t}\n \n-\t\trc = phb->ops->complete_reset(phb, assert_state);\n+\t\tif (assert_state != OPAL_ASSERT_RESET)\n+\t\t\tbreak;\n+\n+\t\trc = slot->ops.creset(slot);\n \t\tif (rc < 0)\n-\t\t\tprerror(\"PHB#%d: Failure on complete reset, rc=%lld\\n\",\n-\t\t\t\tphb->opal_id, rc);\n+\t\t\tprlog(PR_ERR, \"SLOT-%016llx: Error %lld on complete reset\\n\",\n+\t\t\t      slot->id, rc);\n \t\tbreak;\n \tcase OPAL_RESET_PCI_FUNDAMENTAL:\n-\t\tif (!phb->ops->fundamental_reset) {\n+\t\tif (!slot->ops.freset) {\n \t\t\trc = OPAL_UNSUPPORTED;\n \t\t\tbreak;\n \t\t}\n@@ -499,13 +505,13 @@ static int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope,\n \t\tif (assert_state != OPAL_ASSERT_RESET)\n \t\t\tbreak;\n \n-\t\trc = phb->ops->fundamental_reset(phb);\n+\t\trc = slot->ops.freset(slot);\n \t\tif (rc < 0)\n-\t\t\tprerror(\"PHB#%d: Failure on fundamental reset, rc=%lld\\n\",\n-\t\t\t\tphb->opal_id, rc);\n+\t\t\tprlog(PR_ERR, \"SLOT-%016llx: Error %lld on fundamental reset\\n\",\n+\t\t\t      slot->id, rc);\n \t\tbreak;\n \tcase OPAL_RESET_PCI_HOT:\n-\t\tif (!phb->ops->hot_reset) {\n+\t\tif (!slot->ops.hreset) {\n \t\t\trc = OPAL_UNSUPPORTED;\n \t\t\tbreak;\n \t\t}\n@@ -514,22 +520,34 @@ static int64_t opal_pci_reset(uint64_t phb_id, uint8_t reset_scope,\n \t\tif (assert_state != OPAL_ASSERT_RESET)\n \t\t\tbreak;\n \n-\t\trc = phb->ops->hot_reset(phb);\n+\t\trc = slot->ops.hreset(slot);\n \t\tif (rc < 0)\n-\t\t\tprerror(\"PHB#%d: Failure on hot reset, rc=%lld\\n\",\n-\t\t\t\tphb->opal_id, rc);\n+\t\t\tprlog(PR_ERR, \"SLOT-%016llx: Error %lld on hot reset\\n\",\n+\t\t\t      slot->id, rc);\n \t\tbreak;\n \tcase OPAL_RESET_PCI_IODA_TABLE:\n+\t\t/* It's allowed on PHB slot only */\n+\t\tif (slot->pd || !phb->ops || !phb->ops->ioda_reset) {\n+\t\t\trc = OPAL_UNSUPPORTED;\n+\t\t\tbreak;\n+\t\t}\n+\n \t\tif (assert_state != OPAL_ASSERT_RESET)\n \t\t\tbreak;\n-\t\tif (phb->ops->ioda_reset)\n-\t\t\tphb->ops->ioda_reset(phb, true);\n+\n+\t\trc = phb->ops->ioda_reset(phb, true);\n \t\tbreak;\n \tcase OPAL_RESET_PHB_ERROR:\n+\t\t/* It's allowed on PHB slot only */\n+\t\tif (slot->pd || !phb->ops || !phb->ops->papr_errinjct_reset) {\n+\t\t\trc = OPAL_UNSUPPORTED;\n+\t\t\tbreak;\n+\t\t}\n+\n \t\tif (assert_state != OPAL_ASSERT_RESET)\n \t\t\tbreak;\n-\t\tif (phb->ops->papr_errinjct_reset)\n-\t\t\tphb->ops->papr_errinjct_reset(phb);\n+\n+\t\trc = phb->ops->papr_errinjct_reset(phb);\n \t\tbreak;\n \tdefault:\n \t\trc = OPAL_UNSUPPORTED;\n@@ -560,18 +578,19 @@ static int64_t opal_pci_reinit(uint64_t phb_id,\n }\n opal_call(OPAL_PCI_REINIT, opal_pci_reinit, 3);\n \n-static int64_t opal_pci_poll(uint64_t phb_id)\n+static int64_t opal_pci_poll(uint64_t id)\n {\n-\tstruct phb *phb = pci_get_phb(phb_id);\n+\tstruct pci_slot *slot = pci_slot_find(id);\n+\tstruct phb *phb = slot ? slot->phb : NULL;\n \tint64_t rc;\n \n-\tif (!phb)\n+\tif (!slot || !phb)\n \t\treturn OPAL_PARAMETER;\n-\tif (!phb->ops || !phb->ops->poll)\n+\tif (!slot->ops.poll)\n \t\treturn OPAL_UNSUPPORTED;\n \n \tphb_lock(phb);\n-\trc = phb->ops->poll(phb);\n+\trc = slot->ops.poll(slot);\n \tphb_unlock(phb);\n \n \t/* Return milliseconds for caller to sleep: round up */\n@@ -585,6 +604,170 @@ static int64_t opal_pci_poll(uint64_t phb_id)\n }\n opal_call(OPAL_PCI_POLL, opal_pci_poll, 1);\n \n+static int64_t opal_pci_get_presence_state(uint64_t id, uint64_t data)\n+{\n+\tstruct pci_slot *slot = pci_slot_find(id);\n+\tstruct phb *phb = slot ? slot->phb : NULL;\n+\tuint8_t *presence = (uint8_t *)data;\n+\tint64_t rc;\n+\n+\tif (!slot || !phb)\n+\t\treturn OPAL_PARAMETER;\n+\tif (!slot->ops.get_presence_state)\n+\t\treturn OPAL_UNSUPPORTED;\n+\n+\tphb_lock(phb);\n+\trc = slot->ops.get_presence_state(slot, presence);\n+\tphb_unlock(phb);\n+\n+\treturn rc;\n+}\n+opal_call(OPAL_PCI_GET_PRESENCE_STATE, opal_pci_get_presence_state, 2);\n+\n+static int64_t opal_pci_get_power_state(uint64_t id, uint64_t data)\n+{\n+\tstruct pci_slot *slot = pci_slot_find(id);\n+\tstruct phb *phb = slot ? slot->phb : NULL;\n+\tuint8_t *power_state = (uint8_t *)data;\n+\tint64_t rc;\n+\n+\tif (!slot || !phb)\n+\t\treturn OPAL_PARAMETER;\n+\tif (!slot->ops.get_power_state)\n+\t\treturn OPAL_UNSUPPORTED;\n+\n+\tphb_lock(phb);\n+\trc = slot->ops.get_power_state(slot, power_state);\n+\tphb_unlock(phb);\n+\n+\treturn rc;\n+}\n+opal_call(OPAL_PCI_GET_POWER_STATE, opal_pci_get_power_state, 2);\n+\n+static void set_power_timer(struct timer *t __unused, void *data,\n+\t\t\t    uint64_t now __unused)\n+{\n+\tstruct pci_slot *slot = data;\n+\tstruct phb *phb = slot->phb;\n+\tstruct pci_device *pd = slot->pd;\n+\tstruct dt_node *dn = pd->dn;\n+\tuint8_t link;\n+\n+\tswitch (slot->state) {\n+\tcase PCI_SLOT_STATE_SPOWER_START:\n+\t\tif (slot->retries-- == 0) {\n+\t\t\tpci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);\n+\t\t\topal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,\n+\t\t\t\t       slot->async_token, dn->phandle,\n+\t\t\t\t       slot->power_state, OPAL_BUSY);\n+\t\t} else {\n+\t\t\tschedule_timer(&slot->timer, msecs_to_tb(10));\n+\t\t}\n+\n+\t\tbreak;\n+\tcase PCI_SLOT_STATE_SPOWER_DONE:\n+\t\tif (slot->power_state == OPAL_PCI_SLOT_POWER_OFF) {\n+\t\t\tpci_remove_bus(phb, &pd->children);\n+\t\t\tpci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);\n+\t\t\topal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,\n+\t\t\t\t       slot->async_token, dn->phandle,\n+\t\t\t\t       OPAL_PCI_SLOT_POWER_OFF, OPAL_SUCCESS);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\t/* Power on */\n+\t\tif (slot->ops.get_link_state(slot, &link) != OPAL_SUCCESS)\n+\t\t\tlink = 0;\n+\t\tif (link) {\n+\t\t\tslot->ops.prepare_link_change(slot, true);\n+\t\t\tpci_scan_bus(phb, pd->secondary_bus,\n+\t\t\t\t     pd->subordinate_bus,\n+\t\t\t\t     &pd->children, pd, true);\n+\t\t\tpci_add_device_nodes(phb, &pd->children, dn,\n+\t\t\t\t\t     &phb->lstate, 0);\n+\t\t\tpci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);\n+\t\t\topal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,\n+\t\t\t\t       slot->async_token, dn->phandle,\n+\t\t\t\t       OPAL_PCI_SLOT_POWER_ON, OPAL_SUCCESS);\n+\t\t} else if (slot->retries-- == 0) {\n+\t\t\tpci_slot_set_state(slot, PCI_SLOT_STATE_NORMAL);\n+\t\t\topal_queue_msg(OPAL_MSG_ASYNC_COMP, NULL, NULL,\n+\t\t\t\t       slot->async_token, dn->phandle,\n+\t\t\t\t       OPAL_PCI_SLOT_POWER_ON, OPAL_BUSY);\n+\t\t} else {\n+\t\t\tschedule_timer(&slot->timer, msecs_to_tb(10));\n+\t\t}\n+\n+\t\tbreak;\n+\tdefault:\n+\t\tprlog(PR_ERR, \"PCI SLOT %016llx: Unexpected state 0x%08x\\n\",\n+\t\t      slot->id, slot->state);\n+\t}\n+}\n+\n+static int64_t opal_pci_set_power_state(uint64_t async_token,\n+\t\t\t\t\tuint64_t id,\n+\t\t\t\t\tuint64_t data)\n+{\n+\tstruct pci_slot *slot = pci_slot_find(id);\n+\tstruct phb *phb = slot ? slot->phb : NULL;\n+\tstruct pci_device *pd = slot ? slot->pd : NULL;\n+\tuint8_t *state = (uint8_t *)data;\n+\tint64_t rc;\n+\n+\tif (!slot || !phb)\n+\t\treturn OPAL_PARAMETER;\n+\n+\tphb_lock(phb);\n+\tswitch (*state) {\n+\tcase OPAL_PCI_SLOT_POWER_OFF:\n+\t\tif (!slot->ops.prepare_link_change ||\n+\t\t    !slot->ops.set_power_state)\n+\t\t\treturn OPAL_UNSUPPORTED;\n+\n+\t\tslot->async_token = async_token;\n+\t\tslot->ops.prepare_link_change(slot, false);\n+\t\trc = slot->ops.set_power_state(slot, PCI_SLOT_POWER_OFF);\n+\t\tbreak;\n+\tcase OPAL_PCI_SLOT_POWER_ON:\n+\t\tif (!slot->ops.set_power_state ||\n+\t\t    !slot->ops.get_link_state)\n+\t\t\treturn OPAL_UNSUPPORTED;\n+\n+\t\tslot->async_token = async_token;\n+\t\trc = slot->ops.set_power_state(slot, PCI_SLOT_POWER_ON);\n+\t\tbreak;\n+\tcase OPAL_PCI_SLOT_OFFLINE:\n+\t\tif (!pd)\n+\t\t\treturn OPAL_PARAMETER;\n+\n+\t\tpci_remove_bus(phb, &pd->children);\n+\t\trc = OPAL_SUCCESS;\n+\t\tbreak;\n+\tcase OPAL_PCI_SLOT_ONLINE:\n+\t\tif (!pd)\n+\t\t\treturn OPAL_PARAMETER;\n+\t\tpci_scan_bus(phb, pd->secondary_bus, pd->subordinate_bus,\n+\t\t\t     &pd->children, pd, true);\n+\t\tpci_add_device_nodes(phb, &pd->children, pd->dn,\n+\t\t\t\t     &phb->lstate, 0);\n+\t\trc = OPAL_SUCCESS;\n+\t\tbreak;\n+\tdefault:\n+\t\trc = OPAL_PARAMETER;\n+\t}\n+\n+\tphb_unlock(phb);\n+\tif (rc == OPAL_ASYNC_COMPLETION) {\n+\t\tslot->retries = 500;\n+\t\tinit_timer(&slot->timer, set_power_timer, slot);\n+\t\tschedule_timer(&slot->timer, msecs_to_tb(10));\n+\t}\n+\n+\treturn rc;\n+}\n+opal_call(OPAL_PCI_SET_POWER_STATE, opal_pci_set_power_state, 3);\n+\n static int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id,\n \t\t\t\t\t   uint64_t tce_mem_addr,\n \t\t\t\t\t   uint64_t tce_mem_size)\ndiff --git a/doc/opal-api/opal-pci-get-power-state-120.txt b/doc/opal-api/opal-pci-get-power-state-120.txt\nnew file mode 100644\nindex 0000000..420cf8d\n--- /dev/null\n+++ b/doc/opal-api/opal-pci-get-power-state-120.txt\n@@ -0,0 +1,19 @@\n+OPAL_PCI_GET_POWER_STATE\n+---------------------------\n+\n+Get PCI slot power state\n+\n+Parameters:\n+\tuint64_t id: PCI slot ID\n+\tuint64_t data: memory buffer pointer for power state\n+\n+Calling:\n+\n+Retrieve PCI slot's power state. The retrieved power state is stored\n+in buffer pointed by @data.\n+\n+Return Codes:\n+\n+OPAL_SUCCESS - PCI slot's power state is retrieved successfully\n+OPAL_PARAMETER - The indicated PCI slot isn't found\n+OPAL_UNSUPPORTED - Power state retrieval not supported on the PCI slot\ndiff --git a/doc/opal-api/opal-pci-get-presence-state-119.txt b/doc/opal-api/opal-pci-get-presence-state-119.txt\nnew file mode 100644\nindex 0000000..f3fbd83\n--- /dev/null\n+++ b/doc/opal-api/opal-pci-get-presence-state-119.txt\n@@ -0,0 +1,22 @@\n+OPAL_PCI_GET_PRESENCE_STATE\n+---------------------------\n+\n+Get PCI slot presence state\n+\n+Parameters:\n+\tuint64_t id: PCI slot ID\n+\tuint64_t data: memory buffer pointer for presence state\n+\n+Calling:\n+\n+Retrieve PCI slot's presence state. The detected presence means there are\n+adapters inserted to the PCI slot. Otherwise, the PCI slot is regarded as\n+an empty one. The typical use is to ensure there are adapters existing\n+before probing the PCI slot in PCI hot add path. The retrieved presence\n+state is stored in buffer pointed by @data.\n+\n+Return Codes:\n+\n+OPAL_SUCCESS - PCI slot's presence state is retrieved successfully\n+OPAL_PARAMETER - The indicated PCI slot isn't found\n+OPAL_UNSUPPORTED - Presence retrieval not supported on the PCI slot\ndiff --git a/doc/opal-api/opal-pci-set-power-state-121.txt b/doc/opal-api/opal-pci-set-power-state-121.txt\nnew file mode 100644\nindex 0000000..92da235\n--- /dev/null\n+++ b/doc/opal-api/opal-pci-set-power-state-121.txt\n@@ -0,0 +1,36 @@\n+OPAL_PCI_SET_POWER_STATE\n+---------------------------\n+\n+Set PCI slot power state\n+\n+Parameters:\n+\tuint64_t async_token: Token of asynchronous message to be sent\n+                 on completion of OPAL_PCI_SLOT_POWER_{OFF, ON}. It is\n+                 ignored when @data is OPAL_PCI_SLOT_{OFFLINE, ONLINE}.\n+\tuint64_t id: PCI slot ID\n+\tuint64_t data: memory buffer pointer for the power state which\n+                 can be one of OPAL_PCI_SLOT_POWER_{OFF, ON, OFFLINE, ONLINE}.\n+\n+Calling:\n+\n+Set PCI slot's power state. The power state is stored in buffer pointed\n+by @data. The typical use is to hot add or remove adapters behind the\n+indicated PCI slot (by @id) in PCI hotplug path.\n+\n+User will receive an asychronous message after calling the API. The message\n+contains the API completion status: event (Power off or on), device node's\n+phandle identifying the PCI slot, errcode (e.g. OPAL_SUCCESS). The API returns\n+OPAL_ASYNC_COMPLETION for the case.\n+\n+The states OPAL_PCI_SLOT_OFFLINE and OPAL_PCI_SLOT_ONLINE are used for removing\n+or adding devices behind the slot. The device nodes in the device tree are\n+removed or added accordingly, without actually changing the slot's power state.\n+The API call will return OPAL_SUCCESS immediately and no further asynchronous\n+message will be sent.\n+\n+Return Codes:\n+\n+OPAL_SUCCESS - PCI hotplug on the slot is completed successfully\n+OPAL_ASYNC_COMPLETION - PCI hotplug needs further message to confirm\n+OPAL_PARAMETER - The indicated PCI slot isn't found\n+OPAL_UNSUPPORTED - Setting power state not supported on the PCI slot\ndiff --git a/include/opal-api.h b/include/opal-api.h\nindex 2b8bf57..08a7a43 100644\n--- a/include/opal-api.h\n+++ b/include/opal-api.h\n@@ -164,7 +164,10 @@\n #define OPAL_CEC_REBOOT2\t\t\t116\n #define OPAL_CONSOLE_FLUSH\t\t\t117\n #define OPAL_GET_DEVICE_TREE\t\t\t118\n-#define OPAL_LAST\t\t\t\t118\n+#define OPAL_PCI_GET_PRESENCE_STATE\t\t119\n+#define OPAL_PCI_GET_POWER_STATE\t\t120\n+#define OPAL_PCI_SET_POWER_STATE\t\t121\n+#define OPAL_LAST\t\t\t\t121\n \n /* Device tree flags */\n \n@@ -383,7 +386,9 @@ enum OpalPciSlotPresence {\n \n enum OpalPciSlotPower {\n \tOPAL_PCI_SLOT_POWER_OFF\t= 0,\n-\tOPAL_PCI_SLOT_POWER_ON\t= 1\n+\tOPAL_PCI_SLOT_POWER_ON\t= 1,\n+\tOPAL_PCI_SLOT_OFFLINE\t= 2,\n+\tOPAL_PCI_SLOT_ONLINE\t= 3\n };\n \n enum OpalSlotLedType {\ndiff --git a/include/pci.h b/include/pci.h\nindex ce46889..83c9683 100644\n--- a/include/pci.h\n+++ b/include/pci.h\n@@ -294,78 +294,6 @@ struct phb_ops {\n \t */\n \tint64_t (*pci_msi_eoi)(struct phb *phb, uint32_t hwirq);\n \n-\t/*\n-\t * Slot control\n-\t */\n-\n-\t/* presence_detect - Check for a present device\n-\t *\n-\t * Immediate return of:\n-\t *\n-\t * OPAL_SHPC_DEV_NOT_PRESENT = 0,\n-\t * OPAL_SHPC_DEV_PRESENT = 1\n-\t *\n-\t * or a negative OPAL error code\n-\t */\n-\tint64_t (*presence_detect)(struct phb *phb);\n-\n-\t/* link_state - Check link state\n-\t *\n-\t * Immediate return of:\n-\t *\n-\t * OPAL_SHPC_LINK_DOWN = 0,\n-\t * OPAL_SHPC_LINK_UP_x1 = 1,\n-\t * OPAL_SHPC_LINK_UP_x2 = 2,\n-\t * OPAL_SHPC_LINK_UP_x4 = 4,\n-\t * OPAL_SHPC_LINK_UP_x8 = 8,\n-\t * OPAL_SHPC_LINK_UP_x16 = 16,\n-\t * OPAL_SHPC_LINK_UP_x32 = 32\n-\t *\n-\t * or a negative OPAL error code\n-\t */\n-\tint64_t (*link_state)(struct phb *phb);\n-\n-\t/* power_state - Check slot power state\n-\t *\n-\t * Immediate return of:\n-\t *\n-\t * OPAL_SLOT_POWER_OFF = 0,\n-\t * OPAL_SLOT_POWER_ON = 1,\n-\t *\n-\t * or a negative OPAL error code\n-\t */\n-\tint64_t (*power_state)(struct phb *phb);\n-\n-\t/* slot_power_off - Start slot power off sequence\n-\t *\n-\t * Asynchronous function, returns a positive delay\n-\t * or a negative error code\n-\t */\n-\tint64_t (*slot_power_off)(struct phb *phb);\n-\n-\t/* slot_power_on - Start slot power on sequence\n-\t *\n-\t * Asynchronous function, returns a positive delay\n-\t * or a negative error code.\n-\t */\n-\tint64_t (*slot_power_on)(struct phb *phb);\n-\n-\t/* PHB power off and on after complete init */\n-\tint64_t (*complete_reset)(struct phb *phb, uint8_t assert);\n-\n-\t/* hot_reset - Hot Reset sequence */\n-\tint64_t (*hot_reset)(struct phb *phb);\n-\n-\t/* Fundamental reset */\n-\tint64_t (*fundamental_reset)(struct phb *phb);\n-\n-\t/* poll - Poll and advance asynchronous operations\n-\t *\n-\t * Returns a positive delay, 0 for success or a\n-\t * negative OPAL error code\n-\t */\n-\tint64_t (*poll)(struct phb *phb);\n-\n \t/* Put phb in capi mode or pcie mode */\n \tint64_t (*set_capi_mode)(struct phb *phb, uint64_t mode, uint64_t pe_number);\n \n",
    "prefixes": [
        "v12",
        "22/23"
    ]
}