get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 633511,
    "url": "http://patchwork.ozlabs.org/api/patches/633511/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/skiboot/patch/1465535032-26749-15-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-15-git-send-email-gwshan@linux.vnet.ibm.com>",
    "list_archive_url": null,
    "date": "2016-06-10T05:03:43",
    "name": "[v12,14/23] hw/p7ioc: Support PHB slot",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "a136f092f35ad64b50c1106ba7e89afb82515266",
    "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-15-git-send-email-gwshan@linux.vnet.ibm.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/633511/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/633511/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 [103.22.144.68])\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 3rQqsK3Kxnz9sD3\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 10 Jun 2016 15:06:45 +1000 (AEST)",
            "from ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3rQqsK2NlrzDqXn\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 10 Jun 2016 15:06:45 +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 3rQqqr74MgzDqP9\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:05:28 +1000 (AEST)",
            "from pps.filterd (m0049461.ppops.net [127.0.0.1])\n\tby mx0b-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id\n\tu5A53soQ013199\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 01:05:26 -0400",
            "from e23smtp05.au.ibm.com (e23smtp05.au.ibm.com [202.81.31.147])\n\tby mx0b-001b2d01.pphosted.com with ESMTP id 23fa5xy7ry-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:25 -0400",
            "from localhost\n\tby e23smtp05.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:22 +1000",
            "from d23dlp03.au.ibm.com (202.81.31.214)\n\tby e23smtp05.au.ibm.com (202.81.31.211) with IBM ESMTP SMTP Gateway:\n\tAuthorized Use Only! Violators will be prosecuted; \n\tFri, 10 Jun 2016 15:05:19 +1000",
            "from d23relay09.au.ibm.com (d23relay09.au.ibm.com [9.185.63.181])\n\tby d23dlp03.au.ibm.com (Postfix) with ESMTP id C02703578058\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:05:03 +1000 (EST)",
            "from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138])\n\tby d23relay09.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n\tu5A54jqI61800670\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:04:45 +1000",
            "from d23av02.au.ibm.com (localhost [127.0.0.1])\n\tby d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id\n\tu5A54dZk024849\n\tfor <skiboot@lists.ozlabs.org>; Fri, 10 Jun 2016 15:04:39 +1000",
            "from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.192.253.14])\n\tby d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id\n\tu5A54bQk024687; Fri, 10 Jun 2016 15:04:38 +1000",
            "from bran.ozlabs.ibm.com (haven.au.ibm.com [9.192.254.114])\n\tby ozlabs.au.ibm.com (Postfix) with ESMTP id 5D62BA01EB;\n\tFri, 10 Jun 2016 15:03:58 +1000 (AEST)",
            "from gwshan (shangw.ozlabs.ibm.com [10.61.2.199])\n\tby bran.ozlabs.ibm.com (Postfix) with ESMTP id 5B668E3B1A;\n\tFri, 10 Jun 2016 15:03:58 +1000 (AEST)",
            "by gwshan (Postfix, from userid 1000)\n\tid 3F1F5942CA3; Fri, 10 Jun 2016 15:03:58 +1000 (AEST)"
        ],
        "X-IBM-Helo": "d23dlp03.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:43 +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-0016-0000-0000-000001A403D7",
        "X-IBM-AV-DETECTION": "SAVI=unused REMOTE=unused XFE=unused",
        "x-cbparentid": "16061005-0017-0000-0000-000004CC7F76",
        "Message-Id": "<1465535032-26749-15-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 14/23] hw/p7ioc: Support PHB slot",
        "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": "This refactors functions used for PHB slot management for P7IOC.\nAlso, PHB slots are created before platform's PHB setup hook\n(platform.pci_setup_phb()). That means the platforms can override\nthe properties or methods of the PHB slot if necessary.\n\nSigned-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>\n---\n hw/p7ioc-phb.c  | 1134 ++++++++++++++++++++++---------------------------------\n include/p7ioc.h |   48 ++-\n 2 files changed, 470 insertions(+), 712 deletions(-)",
    "diff": "diff --git a/hw/p7ioc-phb.c b/hw/p7ioc-phb.c\nindex 9e52d31..f9b6815 100644\n--- a/hw/p7ioc-phb.c\n+++ b/hw/p7ioc-phb.c\n@@ -20,8 +20,9 @@\n #include <io.h>\n #include <timebase.h>\n #include <affinity.h>\n-#include <pci.h>\n #include <pci-cfg.h>\n+#include <pci.h>\n+#include <pci-slot.h>\n #include <interrupts.h>\n #include <opal.h>\n #include <ccan/str/str.h>\n@@ -41,19 +42,6 @@ static inline void p7ioc_phb_ioda_sel(struct p7ioc_phb *p, uint32_t table,\n \t\t SETFIELD(PHB_IODA_AD_TADR, 0ul, addr));\n }\n \n-/* Helper to set the state machine timeout */\n-static inline uint64_t p7ioc_set_sm_timeout(struct p7ioc_phb *p, uint64_t dur)\n-{\n-\tuint64_t target, now = mftb();\n-\n-\ttarget = now + dur;\n-\tif (target == 0)\n-\t\ttarget++;\n-\tp->delay_tgt_tb = target;\n-\n-\treturn dur;\n-}\n-\n static bool p7ioc_phb_fenced(struct p7ioc_phb *p)\n {\n \tstruct p7ioc *ioc = p->ioc;\n@@ -168,670 +156,6 @@ P7IOC_PCI_CFG_WRITE(8, uint8_t)\n P7IOC_PCI_CFG_WRITE(16, uint16_t)\n P7IOC_PCI_CFG_WRITE(32, uint32_t)\n \n-static int64_t p7ioc_presence_detect(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\tuint64_t reg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\n-\t/* XXX Test for PHB in error state ? */\n-\n-\tif (reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)\n-\t\treturn OPAL_SHPC_DEV_PRESENT;\n-\n-\treturn OPAL_SHPC_DEV_NOT_PRESENT;\n-}\n-\n-static int64_t p7ioc_link_state(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\tuint64_t reg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\tuint16_t lstat;\n-\tint64_t rc;\n-\n-\t/* XXX Test for PHB in error state ? */\n-\n-\t/* Link is up, let's find the actual speed */\n-\tif (!(reg & PHB_PCIE_DLP_TC_DL_LINKACT))\n-\t\treturn OPAL_SHPC_LINK_DOWN;\n-\n-\trc = p7ioc_pcicfg_read16(&p->phb, 0, p->ecap + PCICAP_EXP_LSTAT,\n-\t\t\t\t &lstat);\n-\tif (rc < 0) {\n-\t\t/* Shouldn't happen */\n-\t\tPHBERR(p, \"Failed to read link status\\n\");\n-\t\treturn OPAL_HARDWARE;\n-\t}\n-\tif (!(lstat & PCICAP_EXP_LSTAT_DLLL_ACT))\n-\t\treturn OPAL_SHPC_LINK_DOWN;\n-\n-\treturn GETFIELD(PCICAP_EXP_LSTAT_WIDTH, lstat);\n-}\n-\n-static int64_t p7ioc_sm_freset(struct p7ioc_phb *p)\n-{\n-\tuint64_t reg;\n-\tuint32_t cfg32;\n-\tuint64_t ci_idx = p->index + 2;\n-\n-\tswitch(p->state) {\n-\tcase P7IOC_PHB_STATE_FUNCTIONAL:\n-\t\t/* If the slot isn't present, we needn't do it */\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)) {\n-\t\t\tPHBDBG(p, \"Slot freset: no device\\n\");\n-\t\t\treturn OPAL_CLOSED;\n-\t\t}\n-\n-\t\t/* Mask PCIE port interrupts and AER receiver error */\n-\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7E00000000000000UL);\n-\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n-\t\t\tp->aercap + PCIECAP_AER_CE_MASK, &cfg32);\n-\t\tcfg32 |= PCIECAP_AER_CE_RECVR_ERR;\n-\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\tp->aercap + PCIECAP_AER_CE_MASK, cfg32);\n-\n-\t\t/* Mask CI port error and clear it */\n-\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK(ci_idx),\n-\t\t\t 0xa4f4000000000000ul);\n-\t\tout_be64(p->regs + PHB_LEM_ERROR_MASK,\n-\t\t\t 0xadb650c9808dd051ul);\n-\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx),\n-\t\t\t 0x0ul);\n-\n-\t\t/* Disable link to avoid training issues */\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\treg |= PHB_PCIE_DLP_TCTX_DISABLE;\n-\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg);\n-\t\tPHBDBG(p, \"Slot freset: disable link training\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_FRESET_DISABLE_LINK;\n-\t\tp->retries = 12;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_FRESET_DISABLE_LINK:\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\tif (reg & PHB_PCIE_DLP_TCRX_DISABLED) {\n-\t\t\t/* Turn on freset */\n-\t\t\treg = in_be64(p->regs + PHB_RESET);\n-\t\t\treg &= ~0x2000000000000000ul;\n-\t\t\tout_be64(p->regs + PHB_RESET, reg);\n-\t\t\tPHBDBG(p, \"Slot freset: assert\\n\");\n-\n-\t\t\tp->state = P7IOC_PHB_STATE_FRESET_ASSERT_DELAY;\n-\t\t\treturn p7ioc_set_sm_timeout(p, secs_to_tb(1));\n-\t\t}\n-\n-\t\tif (p->retries-- == 0) {\n-\t\t\tPHBDBG(p, \"Slot freset: timeout to disable link training\\n\");\n-\t\t\tgoto error;\n-\t\t}\n-\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_FRESET_ASSERT_DELAY:\n-\t\t/* Turn off freset */\n-\t\treg = in_be64(p->regs + PHB_RESET);\n-\t\treg |= 0x2000000000000000ul;\n-\t\tout_be64(p->regs + PHB_RESET, reg);\n-\t\tPHBDBG(p, \"Slot freset: deassert\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_FRESET_DEASSERT_DELAY;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(200));\n-\tcase P7IOC_PHB_STATE_FRESET_DEASSERT_DELAY:\n-\t\t/* Restore link control */\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\treg &= ~PHB_PCIE_DLP_TCTX_DISABLE;\n-\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg);\n-\t\tPHBDBG(p, \"Slot freset: enable link training\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_FRESET_WAIT_LINK;\n-\t\tp->retries = 100;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_FRESET_WAIT_LINK:\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\tif (reg & PHB_PCIE_DLP_TC_DL_LINKACT) {\n-\t\t\t/*\n-\t\t\t * Clear spurious errors and enable PCIE port\n-\t\t\t * interrupts\n-\t\t\t */\n-\t\t\tout_be64(p->regs + UTL_PCIE_PORT_STATUS,\n-\t\t\t\t 0x00E0000000000000UL);\n-                        out_be64(p->regs + UTL_PCIE_PORT_IRQ_EN,\n-\t\t\t\t 0xFE65000000000000UL);\n-\n-\t\t\t/* Clear AER receiver error status */\n-\t\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\t\tp->aercap + PCIECAP_AER_CE_STATUS,\n-\t\t\t\tPCIECAP_AER_CE_RECVR_ERR);\n-\t\t\t/* Unmask receiver error status in AER */\n-\t\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n-\t\t\t\tp->aercap + PCIECAP_AER_CE_MASK, &cfg32);\n-\t\t\tcfg32 &= ~PCIECAP_AER_CE_RECVR_ERR;\n-\t\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\t\tp->aercap + PCIECAP_AER_CE_MASK, cfg32);\n-\t\t\t/* Clear and Unmask CI port and PHB errors */\n-\t\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx),\n-\t\t\t\t 0x0ul);\n-\t\t\tout_be64(p->regs + PHB_LEM_FIR_ACCUM,\n-\t\t\t\t 0x0ul);\n-\t\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK_AND(ci_idx),\n-\t\t\t\t 0x0ul);\n-\t\t\tout_be64(p->regs + PHB_LEM_ERROR_MASK,\n-\t\t\t\t 0x1249a1147f500f2cul);\n-\t\t\tPHBDBG(p, \"Slot freset: link up!\\n\");\n-\n-\t\t\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\t\t\tp->flags &= ~P7IOC_PHB_CFG_BLOCKED;\n-\n-\t\t\t/*\n-\t\t\t * We might be required to restore bus numbers for PCI bridges\n-\t\t\t * for complete reset\n-\t\t\t */\n-\t\t\tif (p->flags & P7IOC_RESTORE_BUS_NUM) {\n-\t\t\t\tp->flags &= ~P7IOC_RESTORE_BUS_NUM;\n-\t\t\t\tpci_restore_bridge_buses(&p->phb, NULL);\n-\t\t\t}\n-\n-\t\t\treturn OPAL_SUCCESS;\n-\t\t}\n-\n-\t\tif (p->retries-- == 0) {\n-\t\t\tuint16_t val;\n-\n-\t\t\tif (p->gen == 1) {\n-\t\t\t\tPHBDBG(p, \"Slot freset: timeout for link up in Gen1 mode!\\n\");\n-\t\t\t\tgoto error;\n-\t\t\t}\n-\n-\t\t\tPHBDBG(p, \"Slot freset: timeout for link up.\\n\");\n-\t\t\tPHBDBG(p, \"Slot freset: fallback to Gen1.\\n\");\n-\t\t\tp->gen --;\n-\n-\t\t\t/* Limit speed to 2.5G */\n-\t\t\tp7ioc_pcicfg_read16(&p->phb, 0,\n-\t\t\t\t\tp->ecap + PCICAP_EXP_LCTL2, &val);\n-\t\t\tval = SETFIELD(PCICAP_EXP_LCTL2_TLSPD, val, 1);\n-\t\t\tp7ioc_pcicfg_write16(&p->phb, 0,\n-\t\t\t\t\tp->ecap + PCICAP_EXP_LCTL2,\n-\t\t\t\t\tval);\n-\n-\t\t\t/* Retrain */\n-\t\t\tp7ioc_pcicfg_read16(&p->phb, 0,\n-\t\t\t\t\tp->ecap + PCICAP_EXP_LCTL, &val);\n-\t\t\tp7ioc_pcicfg_write16(&p->phb, 0,\n-\t\t\t\t\tp->ecap + PCICAP_EXP_LCTL,\n-\t\t\t\t\tval | PCICAP_EXP_LCTL_LINK_RETRAIN);\n-\n-\t\t\t/* Enter FRESET_WAIT_LINK, again */\n-\t\t\tp->state = P7IOC_PHB_STATE_FRESET_WAIT_LINK;\n-\t\t\tp->retries = 100;\n-\t\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\t\t}\n-\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-error:\n-\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\treturn OPAL_HARDWARE;\n-}\n-\n-static int64_t p7ioc_freset(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\n-\tif (p->state != P7IOC_PHB_STATE_FUNCTIONAL)\n-\t\treturn OPAL_HARDWARE;\n-\n-\tp->flags |= P7IOC_PHB_CFG_BLOCKED;\n-\treturn p7ioc_sm_freset(p);\n-}\n-\n-static int64_t p7ioc_power_state(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\tuint64_t reg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\n-\t/* XXX Test for PHB in error state ? */\n-\n-\tif (reg & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)\n-\t\treturn OPAL_SHPC_POWER_ON;\n-\n-\treturn OPAL_SHPC_POWER_OFF;\n-}\n-\n-static int64_t p7ioc_sm_slot_power_off(struct p7ioc_phb *p)\n-{\n-\tuint64_t reg;\n-\n-\tswitch(p->state) {\n-\tcase P7IOC_PHB_STATE_FUNCTIONAL:\n-\t\t/*\n-\t\t * Check the presence and power status. If be not\n-\t\t * be present or power down, we stop here.\n-\t\t */\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)) {\n-\t\t\tPHBDBG(p, \"Slot power off: no device\\n\");\n-\t\t\treturn OPAL_CLOSED;\n-\t\t}\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)) {\n-\t\t\tPHBDBG(p, \"Slot power off: already off\\n\");\n-\t\t\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\t\t\treturn OPAL_SUCCESS;\n-\t\t}\n-\n-\t\t/*\n-\t\t * Mask PCIE port interrupt and turn power off\n-\t\t *\n-\t\t * We have to set bit 0 and clear it explicitly on PHB\n-\t\t * hotplug override register when doing power-off on the\n-\t\t * PHB slot. Otherwise, it won't take effect. That's the\n-\t\t * similar thing as we did for power-on.\n-\t\t */\n-\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7e00000000000000UL);\n-\t\treg = in_be64(p->regs + PHB_HOTPLUG_OVERRIDE);\n-\t\treg &= ~(0x8c00000000000000ul);\n-\t\treg |= 0x8400000000000000ul;\n-\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg);\n-\t\treg &= ~(0x8c00000000000000ul);\n-\t\treg |= 0x0c00000000000000ul;\n-\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg);\n-\t\tPHBDBG(p, \"Slot power off: powering off...\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_SPDOWN_STABILIZE_DELAY;\n-\t\treturn p7ioc_set_sm_timeout(p, secs_to_tb(2));\n-\tcase P7IOC_PHB_STATE_SPDOWN_STABILIZE_DELAY:\n-\t\t/*\n-\t\t * The link should be stabilized after 2 seconds.\n-\t\t * We still need poll registers to make sure the\n-\t\t * power is really down every 1ms until limited\n-\t\t * 1000 times.\n-\t\t */\n-\t\tp->retries = 1000;\n-\t\tp->state = P7IOC_PHB_STATE_SPDOWN_SLOT_STATUS;\n-\t\tPHBDBG(p, \"Slot power off: waiting for power off\\n\");\n-\tcase P7IOC_PHB_STATE_SPDOWN_SLOT_STATUS:\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)) {\n-\t\t\t/*\n-\t\t\t * We completed the task. Clear link errors\n-\t\t\t * and restore PCIE port interrupts.\n-\t\t\t */\n-\t\t\tout_be64(p->regs + UTL_PCIE_PORT_STATUS,\n-\t\t\t\t0x00E0000000000000ul);\n-\t\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN,\n-\t\t\t\t0xFE65000000000000ul);\n-\n-\t\t\tPHBDBG(p, \"Slot power off: power off completely\\n\");\n-\t\t\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\t\t\treturn OPAL_SUCCESS;\n-\t\t}\n-\n-\t\tif (p->retries-- == 0) {\n-\t\t\tPHBERR(p, \"Timeout powering off\\n\");\n-\t\t\tgoto error;\n-\t\t}\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(1));\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-error:\n-\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\treturn OPAL_HARDWARE;\n-}\n-\n-static int64_t p7ioc_slot_power_off(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\n-\tif (p->state != P7IOC_PHB_STATE_FUNCTIONAL)\n-\t\treturn OPAL_BUSY;\n-\n-\t/* run state machine */\n-\treturn p7ioc_sm_slot_power_off(p);\n-}\n-\n-static int64_t p7ioc_sm_slot_power_on(struct p7ioc_phb *p)\n-{\n-\tuint64_t reg;\n-\tuint32_t reg32;\n-\tuint64_t ci_idx = p->index + 2;\n-\n-\tswitch(p->state) {\n-\tcase P7IOC_PHB_STATE_FUNCTIONAL:\n-\t\t/* Check presence */\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)) {\n-\t\t\tPHBDBG(p, \"Slot power on: no device\\n\");\n-\t\t\treturn OPAL_CLOSED;\n-\t\t}\n-\n-\t\t/* Adjust UTL interrupt settings to disable various\n-\t\t * errors that would interfere with the process\n-\t\t */\n-\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7e00000000000000UL);\n-\n-\t\t/* If the power is not on, turn it on now */\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)) {\n-\t\t\t/*\n-\t\t\t * The hotplug override register will not properly\n-\t\t\t * initiate the poweron sequence unless bit 0\n-\t\t\t * transitions from 0 to 1. Since it can already be\n-\t\t\t * set to 1 as a result of a previous power-on\n-\t\t\t * operation (even if the slot power is now off)\n-\t\t\t * we need to first clear it, then set it to 1 or\n-\t\t\t * nothing will happen\n-\t\t\t */\n-\t\t\treg = in_be64(p->regs + PHB_HOTPLUG_OVERRIDE);\n-\t\t\treg &= ~(0x8c00000000000000ul);\n-\t\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg);\n-\t\t\treg |= 0x8400000000000000ul;\n-\t\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg);\n-\t\t\tp->state = P7IOC_PHB_STATE_SPUP_STABILIZE_DELAY;\n-\t\t\tPHBDBG(p, \"Slot power on: powering on...\\n\");\n-\t\t\treturn p7ioc_set_sm_timeout(p, secs_to_tb(2));\n-\t\t}\n-\t\t/* Power is already on */\n-\tpower_ok:\n-\t\t/* Mask AER receiver error */\n-\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n-\t\t\tp->aercap + PCIECAP_AER_CE_MASK, &reg32);\n-\t\treg32 |= PCIECAP_AER_CE_RECVR_ERR;\n-\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\tp->aercap + PCIECAP_AER_CE_MASK, reg32);\n-\n-\t\t/* Mask CI port error and clear it */\n-\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK(ci_idx),\n-\t\t\t 0xa4f4000000000000ul);\n-\t\tout_be64(p->regs + PHB_LEM_ERROR_MASK,\n-\t\t\t 0xadb650c9808dd051ul);\n-\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx),\n-\t\t\t 0x0ul);\n-\n-\t\t/* Disable link to avoid training issues */\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\treg |= PHB_PCIE_DLP_TCTX_DISABLE;\n-\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg);\n-\t\tPHBDBG(p, \"Slot power on: disable link training\\n\");\n-\n-\t\t/* Switch to state machine of fundamental reset */\n-                p->state = P7IOC_PHB_STATE_FRESET_DISABLE_LINK;\n-\t\tp->retries = 12;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_SPUP_STABILIZE_DELAY:\n-\t\t/* Come here after the 2s delay after power up */\n-\t\tp->retries = 1000;\n-\t\tp->state = P7IOC_PHB_STATE_SPUP_SLOT_STATUS;\n-\t\tPHBDBG(p, \"Slot power on: waiting for power\\n\");\n-\t\t/* Fall through */\n-\tcase P7IOC_PHB_STATE_SPUP_SLOT_STATUS:\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\n-\t\t/* Doc says to check LED status, but we ignore that, there\n-\t\t * no point really and it's easier that way\n-\t\t */\n-\t\tif (reg & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)\n-\t\t\tgoto power_ok;\n-\t\tif (p->retries-- == 0) {\n-\t\t\t/* XXX Improve error logging */\n-\t\t\tPHBERR(p, \"Timeout powering up slot\\n\");\n-\t\t\tgoto error;\n-\t\t}\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-\t/* Unknown state, hardware error ? */\n- error:\n-\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\treturn OPAL_HARDWARE;\n-}\n-\n-static int64_t p7ioc_slot_power_on(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\n-\tif (p->state != P7IOC_PHB_STATE_FUNCTIONAL)\n-\t\treturn OPAL_BUSY;\n-\n-\t/* run state machine */\n-\treturn p7ioc_sm_slot_power_on(p);\n-}\n-\n-/*\n- * The OS is expected to do fundamental reset after complete\n- * reset to make sure the PHB could be recovered from the\n- * fenced state. However, the OS needn't do that explicitly\n- * since fundamental reset will be done automatically while\n- * powering on the PHB.\n- */\n-static int64_t p7ioc_complete_reset(struct phb *phb, uint8_t assert)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\tstruct p7ioc *ioc = p->ioc;\n-\tuint64_t val64;\n-\n-\tif (assert == OPAL_ASSERT_RESET) {\n-\t\tif (p->state != P7IOC_PHB_STATE_FUNCTIONAL &&\n-\t\t    p->state != P7IOC_PHB_STATE_FENCED)\n-\t\t\treturn OPAL_HARDWARE;\n-\n-\t\tp->flags |= P7IOC_PHB_CFG_BLOCKED;\n-\t\tp7ioc_phb_reset(phb);\n-\n-\t\t/*\n-\t\t * According to the experiment, we probably still have\n-\t\t * the fenced state with the corresponding PHB in the Fence\n-\t\t * WOF and we need clear that explicitly. Besides, the RGC\n-\t\t * might already have informational error and we should clear\n-\t\t * that explicitly as well. Otherwise, RGC XIVE#0 won't issue\n-\t\t * interrupt any more.\n-\t\t */\n-\t\tval64 = in_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF);\n-\t\tval64 &= ~PPC_BIT(15 + p->index * 4);\n-\t\tout_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF, val64);\n-\n-\t\t/* Clear informational error from RGC */\n-\t\tval64 = in_be64(ioc->regs + P7IOC_RGC_LEM_BASE + P7IOC_LEM_WOF_OFFSET);\n-\t\tval64 &= ~PPC_BIT(18);\n-\t\tout_be64(ioc->regs + P7IOC_RGC_LEM_BASE + P7IOC_LEM_WOF_OFFSET, val64);\n-\t\tval64 = in_be64(ioc->regs + P7IOC_RGC_LEM_BASE + P7IOC_LEM_FIR_OFFSET);\n-\t\tval64 &= ~PPC_BIT(18);\n-\t\tout_be64(ioc->regs + P7IOC_RGC_LEM_BASE + P7IOC_LEM_FIR_OFFSET, val64);\n-\n-\t\treturn p7ioc_sm_slot_power_off(p);\n-\t} else {\n-\t\tif (p->state != P7IOC_PHB_STATE_FUNCTIONAL)\n-\t\t\treturn OPAL_HARDWARE;\n-\n-\t\t/* Restore bus numbers for bridges */\n-\t\tp->flags |= P7IOC_RESTORE_BUS_NUM;\n-\n-\t\treturn p7ioc_sm_slot_power_on(p);\n-\t}\n-\n-\t/* We shouldn't run to here */\n-\treturn OPAL_PARAMETER;\n-}\n-\n-/*\n- * We have to mask errors prior to disabling link training.\n- * Otherwise it would cause infinite frozen PEs. Also, we\n- * should have some delay after enabling link training. It's\n- * the conclusion from experiment and no document mentioned\n- * it.\n- */\n-static int64_t p7ioc_sm_hot_reset(struct p7ioc_phb *p)\n-{\n-\tuint64_t reg;\n-\tuint32_t cfg32;\n-\tuint16_t brctl;\n-\n-\tswitch(p->state) {\n-\tcase P7IOC_PHB_STATE_FUNCTIONAL:\n-\t\t/* If the slot isn't present, we needn't do it */\n-\t\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n-\t\tif (!(reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)) {\n-\t\t\tPHBDBG(p, \"Slot hot reset: no device\\n\");\n-\t\t\treturn OPAL_CLOSED;\n-\t\t}\n-\n-\t\t/* Mask PCIE port interrupts and AER receiver error */\n-\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7E00000000000000UL);\n-\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n-\t\t\tp->aercap + PCIECAP_AER_CE_MASK, &cfg32);\n-\t\tcfg32 |= PCIECAP_AER_CE_RECVR_ERR;\n-\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\tp->aercap + PCIECAP_AER_CE_MASK, cfg32);\n-\n-\t\t/* Disable link to avoid training issues */\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\treg |= PHB_PCIE_DLP_TCTX_DISABLE;\n-\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg);\n-\t\tPHBDBG(p, \"Slot hot reset: disable link training\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_HRESET_DISABLE_LINK;\n-\t\tp->retries = 12;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_HRESET_DISABLE_LINK:\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\tif (reg & PHB_PCIE_DLP_TCRX_DISABLED) {\n-\t\t\t/* Turn on host reset */\n-\t\t\tp7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &brctl);\n-\t\t\tbrctl |= PCI_CFG_BRCTL_SECONDARY_RESET;\n-\t\t\tp7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, brctl);\n-\t\t\tPHBDBG(p, \"Slot hot reset: assert reset\\n\");\n-\n-\t\t\tp->state = P7IOC_PHB_STATE_HRESET_DELAY;\n-\t\t\treturn p7ioc_set_sm_timeout(p, secs_to_tb(1));\n-\t\t}\n-\n-\t\tif (p->retries-- == 0) {\n-\t\t\tPHBDBG(p, \"Slot hot reset: timeout to disable link training\\n\");\n-\t\t\treturn OPAL_HARDWARE;\n-\t\t}\n-\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_HRESET_DELAY:\n-\t\t/* Turn off host reset */\n-\t\tp7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &brctl);\n-\t\tbrctl &= ~PCI_CFG_BRCTL_SECONDARY_RESET;\n-\t\tp7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, brctl);\n-\t\tPHBDBG(p, \"Slot hot reset: deassert reset\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_HRESET_ENABLE_LINK;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(200));\n-\tcase P7IOC_PHB_STATE_HRESET_ENABLE_LINK:\n-\t\t/* Restore link control */\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-\t\treg &= ~PHB_PCIE_DLP_TCTX_DISABLE;\n-\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg);\n-\t\tPHBDBG(p, \"Slot hot reset: enable link training\\n\");\n-\n-\t\tp->state = P7IOC_PHB_STATE_HRESET_WAIT_LINK;\n-\t\tp->retries = 100;\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tcase P7IOC_PHB_STATE_HRESET_WAIT_LINK:\n-\t\treg = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n-                if (reg & PHB_PCIE_DLP_TC_DL_LINKACT) {\n-\t\t\t/*\n-\t\t\t * Clear spurious errors and enable PCIE port\n-\t\t\t * interrupts\n-\t\t\t */\n-\t\t\tout_be64(p->regs + UTL_PCIE_PORT_STATUS, 0x00E0000000000000UL);\n-\t\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0xFE65000000000000UL);\n-\n-\t\t\t/* Clear AER receiver error status */\n-\t\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\t\tp->aercap + PCIECAP_AER_CE_STATUS,\n-\t\t\t\tPCIECAP_AER_CE_RECVR_ERR);\n-\t\t\t/* Unmask receiver error status in AER */\n-\t\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n-\t\t\t\tp->aercap + PCIECAP_AER_CE_MASK, &cfg32);\n-\t\t\tcfg32 &= ~PCIECAP_AER_CE_RECVR_ERR;\n-\t\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n-\t\t\t\tp->aercap + PCIECAP_AER_CE_MASK, cfg32);\n-\t\t\tPHBDBG(p, \"Slot hot reset: link up!\\n\");\n-\n-\t\t\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\t\t\tp->flags &= ~P7IOC_PHB_CFG_BLOCKED;\n-\t\t\treturn OPAL_SUCCESS;\n-\t\t}\n-\n-\t\tif (p->retries-- == 0) {\n-\t\t\tPHBDBG(p, \"Slot hot reset: timeout for link up\\n\");\n-\t\t\tgoto error;\n-\t\t}\n-\n-\t\treturn p7ioc_set_sm_timeout(p, msecs_to_tb(10));\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-\t/* Unknown state, hardware error ? */\n-error:\n-\tp->state = P7IOC_PHB_STATE_FUNCTIONAL;\n-\treturn OPAL_HARDWARE;\n-}\n-\n-static int64_t p7ioc_hot_reset(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\n-\tif (p->state != P7IOC_PHB_STATE_FUNCTIONAL)\n-\t\treturn OPAL_HARDWARE;\n-\n-\tp->flags |= P7IOC_PHB_CFG_BLOCKED;\n-\treturn p7ioc_sm_hot_reset(p);\n-}\n-\n-static int64_t p7ioc_poll(struct phb *phb)\n-{\n-\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(phb);\n-\tuint64_t now = mftb();\n-\n-\tif (p->state == P7IOC_PHB_STATE_FUNCTIONAL)\n-\t\treturn OPAL_SUCCESS;\n-\n-\t/* Check timer */\n-\tif (p->delay_tgt_tb &&\n-\t    tb_compare(now, p->delay_tgt_tb) == TB_ABEFOREB)\n-\t\treturn p->delay_tgt_tb - now;\n-\n-\t/* Expired (or not armed), clear it */\n-\tp->delay_tgt_tb = 0;\n-\n-\t/* Dispatch to the right state machine */\n-\tswitch(p->state) {\n-\tcase P7IOC_PHB_STATE_SPUP_STABILIZE_DELAY:\n-\tcase P7IOC_PHB_STATE_SPUP_SLOT_STATUS:\n-\t\treturn p7ioc_sm_slot_power_on(p);\n-\tcase P7IOC_PHB_STATE_SPDOWN_STABILIZE_DELAY:\n-\tcase P7IOC_PHB_STATE_SPDOWN_SLOT_STATUS:\n-\t\treturn p7ioc_sm_slot_power_off(p);\n-\tcase P7IOC_PHB_STATE_FRESET_DISABLE_LINK:\n-\tcase P7IOC_PHB_STATE_FRESET_ASSERT_DELAY:\n-\tcase P7IOC_PHB_STATE_FRESET_DEASSERT_DELAY:\n-\tcase P7IOC_PHB_STATE_FRESET_WAIT_LINK:\n-\t\treturn p7ioc_sm_freset(p);\n-\tcase P7IOC_PHB_STATE_HRESET_DISABLE_LINK:\n-\tcase P7IOC_PHB_STATE_HRESET_ASSERT:\n-\tcase P7IOC_PHB_STATE_HRESET_DELAY:\n-\tcase P7IOC_PHB_STATE_HRESET_ENABLE_LINK:\n-\tcase P7IOC_PHB_STATE_HRESET_WAIT_LINK:\n-\t\treturn p7ioc_sm_hot_reset(p);\n-\tdefault:\n-\t\tbreak;\n-\t}\n-\n-\t/* Unknown state, could be a HW error */\n-\treturn OPAL_HARDWARE;\n-}\n-\n static void p7ioc_eeh_read_phb_status(struct p7ioc_phb *p,\n \t\t\t\t      struct OpalIoP7IOCPhbErrorData *stat)\n {\n@@ -2563,6 +1887,446 @@ static int64_t p7ioc_papr_errinjct_reset(struct phb *phb)\n \treturn OPAL_SUCCESS;\n }\n \n+static int64_t p7ioc_get_presence_state(struct pci_slot *slot, uint8_t *val)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint64_t reg;\n+\n+\treg = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n+\tif (reg & PHB_PCIE_SLOTCTL2_PRSTN_STAT)\n+\t\t*val = OPAL_PCI_SLOT_PRESENT;\n+\telse\n+\t\t*val = OPAL_PCI_SLOT_EMPTY;\n+\n+\treturn OPAL_SUCCESS;\n+}\n+\n+static int64_t p7ioc_get_link_state(struct pci_slot *slot, uint8_t *val)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint64_t reg64;\n+\tuint16_t state;\n+\tint64_t rc;\n+\n+\t/* Check if the link training is completed */\n+\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\tif (!(reg64 & PHB_PCIE_DLP_TC_DL_LINKACT)) {\n+\t\t*val = 0;\n+\t\treturn OPAL_SUCCESS;\n+\t}\n+\n+\t/* Grab link width from PCIe capability */\n+\trc = p7ioc_pcicfg_read16(&p->phb, 0, p->ecap + PCICAP_EXP_LSTAT,\n+\t\t\t\t &state);\n+\tif (rc < 0) {\n+\t\tPHBERR(p, \"%s: Error %lld reading link status\\n\",\n+\t\t       __func__, rc);\n+\t\treturn OPAL_HARDWARE;\n+\t}\n+\n+\tif (state & PCICAP_EXP_LSTAT_DLLL_ACT)\n+\t\t*val = ((state & PCICAP_EXP_LSTAT_WIDTH) >> 4);\n+\telse\n+\t\t*val = 0;\n+\n+\treturn OPAL_SUCCESS;\n+}\n+\n+static int64_t p7ioc_get_power_state(struct pci_slot *slot, uint8_t *val)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint64_t reg64;\n+\n+\treg64 = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n+\tif (reg64 & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)\n+\t\t*val = PCI_SLOT_POWER_ON;\n+\telse\n+\t\t*val = PCI_SLOT_POWER_OFF;\n+\n+\treturn OPAL_SUCCESS;\n+}\n+\n+static int64_t p7ioc_set_power_state(struct pci_slot *slot, uint8_t val)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint64_t reg64;\n+\tuint8_t state = PCI_SLOT_POWER_OFF;\n+\n+\tif (val != PCI_SLOT_POWER_OFF && val != PCI_SLOT_POWER_ON)\n+\t\treturn OPAL_PARAMETER;\n+\n+\t/* If the power state has been put into the requested one */\n+\treg64 = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n+\tif (reg64 & PHB_PCIE_SLOTCTL2_PWR_EN_STAT)\n+\t\tstate = PCI_SLOT_POWER_ON;\n+\tif (state == val)\n+\t\treturn OPAL_SUCCESS;\n+\n+\t/* Power on/off */\n+\tif (val == PCI_SLOT_POWER_ON) {\n+\t\treg64 &= ~(0x8c00000000000000ul);\n+\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t\treg64 |= 0x8400000000000000ul;\n+\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t} else {\n+\t\treg64 &= ~(0x8c00000000000000ul);\n+\t\treg64 |= 0x8400000000000000ul;\n+\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t\treg64 &= ~(0x8c00000000000000ul);\n+\t\treg64 |= 0x0c00000000000000ul;\n+\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t}\n+\n+\treturn OPAL_SUCCESS;\n+}\n+\n+static void p7ioc_prepare_link_change(struct pci_slot *slot, bool up)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint64_t ci_idx = p->index + 2;\n+\tuint32_t cfg32;\n+\n+\tif (!up) {\n+\t\t/* Mask PCIE port interrupts and AER receiver error */\n+\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0x7E00000000000000);\n+\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n+\t\t\t\t    p->aercap + PCIECAP_AER_CE_MASK, &cfg32);\n+\t\tcfg32 |= PCIECAP_AER_CE_RECVR_ERR;\n+\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n+\t\t\t\t     p->aercap + PCIECAP_AER_CE_MASK, cfg32);\n+\n+\t\t/* Mask CI port error and clear it */\n+\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK(ci_idx),\n+\t\t\t 0xa4f4000000000000ul);\n+\t\tout_be64(p->regs + PHB_LEM_ERROR_MASK,\n+\t\t\t 0xadb650c9808dd051ul);\n+\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx),\n+\t\t\t 0x0ul);\n+\n+\t\t/* Block access to PCI-CFG space */\n+\t\tp->flags |= P7IOC_PHB_CFG_BLOCKED;\n+\t} else {\n+\t\t/* Clear spurious errors and enable PCIE port interrupts */\n+\t\tout_be64(p->regs + UTL_PCIE_PORT_STATUS, 0x00E0000000000000);\n+\t\tout_be64(p->regs + UTL_PCIE_PORT_IRQ_EN, 0xFE65000000000000);\n+\n+\t\t/* Clear AER receiver error status */\n+\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n+\t\t\t\t     p->aercap + PCIECAP_AER_CE_STATUS,\n+\t\t\t\t     PCIECAP_AER_CE_RECVR_ERR);\n+\t\t/* Unmask receiver error status in AER */\n+\t\tp7ioc_pcicfg_read32(&p->phb, 0,\n+\t\t\t\t    p->aercap + PCIECAP_AER_CE_MASK, &cfg32);\n+\t\tcfg32 &= ~PCIECAP_AER_CE_RECVR_ERR;\n+\t\tp7ioc_pcicfg_write32(&p->phb, 0,\n+\t\t\t\t     p->aercap + PCIECAP_AER_CE_MASK, cfg32);\n+\t\t/* Clear and Unmask CI port and PHB errors */\n+\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_FIR(ci_idx), 0x0ul);\n+\t\tout_be64(p->regs + PHB_LEM_FIR_ACCUM, 0x0ul);\n+\t\tout_be64(p->ioc->regs + P7IOC_CIn_LEM_ERR_MASK_AND(ci_idx),\n+\t\t\t 0x0ul);\n+\t\tout_be64(p->regs + PHB_LEM_ERROR_MASK, 0x1249a1147f500f2cul);\n+\n+\t\t/* Don't block access to PCI-CFG space */\n+\t\tp->flags &= ~P7IOC_PHB_CFG_BLOCKED;\n+\n+\t\t/* Restore slot's state */\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_NORMAL);\n+\n+\t\t/*\n+\t\t * We might lose the bus numbers in the reset and we need\n+\t\t * restore the bus numbers. Otherwise, some adpaters (e.g.\n+\t\t * IPR) can't be probed properly by kernel. We don't need\n+\t\t * restore bus numbers for all kinds of resets. However,\n+\t\t * it's not harmful to restore the bus numbers, which makes\n+\t\t * the logic simplified\n+\t\t */\n+\t\tpci_restore_bridge_buses(slot->phb, slot->pd);\n+\t\tif (slot->phb->ops->device_init)\n+\t\t\tpci_walk_dev(slot->phb, slot->pd,\n+\t\t\t\t     slot->phb->ops->device_init, NULL);\n+\t}\n+}\n+\n+static int64_t p7ioc_poll_link(struct pci_slot *slot)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint64_t reg64;\n+\n+\tswitch (slot->state) {\n+\tcase P7IOC_SLOT_NORMAL:\n+\tcase P7IOC_SLOT_LINK_START:\n+\t\tPHBDBG(p, \"LINK: Start polling\\n\");\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\t\treg64 &= ~PHB_PCIE_DLP_TCTX_DISABLE;\n+\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg64);\n+\t\tslot->retries = 100;\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_LINK_WAIT);\n+\t\treturn pci_slot_set_sm_timeout(slot, msecs_to_tb(10));\n+\tcase P7IOC_SLOT_LINK_WAIT:\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\t\tif (reg64 & PHB_PCIE_DLP_TC_DL_LINKACT) {\n+\t\t\tPHBDBG(p, \"LINK: Up\\n\");\n+\t\t\tslot->ops.prepare_link_change(slot, true);\n+\t\t\treturn OPAL_SUCCESS;\n+\t\t}\n+\n+\t\tif (slot->retries-- == 0) {\n+\t\t\tPHBERR(p, \"LINK: Timeout waiting for link up\\n\");\n+\t\t\tgoto out;\n+\t\t}\n+\t\treturn pci_slot_set_sm_timeout(slot, msecs_to_tb(10));\n+\tdefault:\n+\t\tPHBERR(p, \"LINK: Unexpected slot state %08x\\n\",\n+\t\t       slot->state);\n+\t}\n+\n+out:\n+\tpci_slot_set_state(slot, P7IOC_SLOT_NORMAL);\n+\treturn OPAL_HARDWARE;\n+}\n+\n+static int64_t p7ioc_hreset(struct pci_slot *slot)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint8_t presence = 1;\n+\tuint16_t brctl;\n+\tuint64_t reg64;\n+\n+\tswitch (slot->state) {\n+\tcase P7IOC_SLOT_NORMAL:\n+\t\tPHBDBG(p, \"HRESET: Starts\\n\");\n+\t\tif (slot->ops.get_presence_state)\n+\t\t\tslot->ops.get_presence_state(slot, &presence);\n+\t\tif (!presence) {\n+\t\t\tPHBDBG(p, \"HRESET: No device\\n\");\n+\t\t\treturn OPAL_SUCCESS;\n+\t\t}\n+\n+\t\tPHBDBG(p, \"HRESET: Prepare for link down\\n\");\n+\t\tslot->ops.prepare_link_change(slot, false);\n+\n+\t\t/* Disable link to avoid training issues */\n+\t\tPHBDBG(p, \"HRESET: Disable link training\\n\");\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\t\treg64 |= PHB_PCIE_DLP_TCTX_DISABLE;\n+\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg64);\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_HRESET_TRAINING);\n+\t\tslot->retries = 15;\n+\t\t/* fall through */\n+\tcase P7IOC_SLOT_HRESET_TRAINING:\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\t\tif (!(reg64 & PHB_PCIE_DLP_TCRX_DISABLED)) {\n+\t\t\tif (slot->retries -- == 0) {\n+\t\t\t\tPHBERR(p, \"HRESET: Timeout disabling link training\\n\");\n+\t\t\t\tgoto out;\n+\t\t\t}\n+\n+\t\t\treturn pci_slot_set_sm_timeout(slot, msecs_to_tb(10));\n+\t\t}\n+\t\t/* fall through */\n+\tcase P7IOC_SLOT_HRESET_START:\n+\t\tPHBDBG(p, \"HRESET: Assert\\n\");\n+\t\tp7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &brctl);\n+\t\tbrctl |= PCI_CFG_BRCTL_SECONDARY_RESET;\n+\t\tp7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, brctl);\n+\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_HRESET_DELAY);\n+\t\treturn pci_slot_set_sm_timeout(slot, secs_to_tb(1));\n+\tcase P7IOC_SLOT_HRESET_DELAY:\n+\t\tPHBDBG(p, \"HRESET: Deassert\\n\");\n+\t\tp7ioc_pcicfg_read16(&p->phb, 0, PCI_CFG_BRCTL, &brctl);\n+\t\tbrctl &= ~PCI_CFG_BRCTL_SECONDARY_RESET;\n+\t\tp7ioc_pcicfg_write16(&p->phb, 0, PCI_CFG_BRCTL, brctl);\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_HRESET_DELAY2);\n+\t\treturn pci_slot_set_sm_timeout(slot, msecs_to_tb(200));\n+\tcase P7IOC_SLOT_HRESET_DELAY2:\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_LINK_START);\n+\t\treturn slot->ops.poll_link(slot);\n+\tdefault:\n+\t\tPHBERR(p, \"HRESET: Unexpected slot state %08x\\n\",\n+\t\t       slot->state);\n+\t}\n+\n+out:\n+\tpci_slot_set_state(slot, P7IOC_SLOT_NORMAL);\n+\treturn OPAL_HARDWARE;\n+}\n+\n+static int64_t p7ioc_freset(struct pci_slot *slot)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tuint8_t presence = 1;\n+\tuint64_t reg64;\n+\n+\tswitch (slot->state) {\n+\tcase P7IOC_SLOT_NORMAL:\n+\tcase P7IOC_SLOT_FRESET_START:\n+\t\tPHBDBG(p, \"FRESET: Starts\\n\");\n+\t\tif (slot->ops.get_presence_state)\n+\t\t\tslot->ops.get_presence_state(slot, &presence);\n+\t\tif (!presence) {\n+\t\t\tPHBDBG(p, \"FRESET: No device\\n\");\n+\t\t\tpci_slot_set_state(slot, P7IOC_SLOT_NORMAL);\n+\t\t\treturn OPAL_SUCCESS;\n+\t\t}\n+\n+\t\tPHBDBG(p, \"FRESET: Prepare for link down\\n\");\n+\t\tslot->ops.prepare_link_change(slot, false);\n+\n+\t\t/* Check power state */\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_SLOTCTL2);\n+\t\tif (reg64 & PHB_PCIE_SLOTCTL2_PWR_EN_STAT) {\n+\t\t\tPHBDBG(p, \"FRESET: Power on, turn off\\n\");\n+\t\t\treg64 = in_be64(p->regs + PHB_HOTPLUG_OVERRIDE);\n+\t\t\treg64 &= ~(0x8c00000000000000ul);\n+\t\t\treg64 |= 0x8400000000000000ul;\n+\t\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t\t\treg64 &= ~(0x8c00000000000000ul);\n+\t\t\treg64 |= 0x0c00000000000000ul;\n+\t\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t\t\tpci_slot_set_state(slot, P7IOC_SLOT_FRESET_POWER_OFF);\n+\t\t\treturn pci_slot_set_sm_timeout(slot, secs_to_tb(2));\n+\t\t}\n+\t\t/* fall through */\n+\tcase P7IOC_SLOT_FRESET_POWER_OFF:\n+\t\tPHBDBG(p, \"FRESET: Power off, turn on\\n\");\n+\t\treg64 = in_be64(p->regs + PHB_HOTPLUG_OVERRIDE);\n+\t\treg64 &= ~(0x8c00000000000000ul);\n+\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t\treg64 |= 0x8400000000000000ul;\n+\t\tout_be64(p->regs + PHB_HOTPLUG_OVERRIDE, reg64);\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_FRESET_POWER_ON);\n+\t\treturn pci_slot_set_sm_timeout(slot, secs_to_tb(2));\n+\tcase P7IOC_SLOT_FRESET_POWER_ON:\n+\t\tPHBDBG(p, \"FRESET: Disable link training\\n\");\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\t\treg64 |= PHB_PCIE_DLP_TCTX_DISABLE;\n+\t\tout_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL, reg64);\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_HRESET_TRAINING);\n+\t\tslot->retries = 200;\n+\t\t/* fall through */\n+\tcase P7IOC_SLOT_HRESET_TRAINING:\n+\t\treg64 = in_be64(p->regs + PHB_PCIE_DLP_TRAIN_CTL);\n+\t\tif (!(reg64 & PHB_PCIE_DLP_TCRX_DISABLED)) {\n+\t\t\tif (slot->retries -- == 0) {\n+\t\t\t\tPHBERR(p, \"HRESET: Timeout disabling link training\\n\");\n+\t\t\t\tgoto out;\n+\t\t\t}\n+\n+\t\t\treturn pci_slot_set_sm_timeout(slot, msecs_to_tb(10));\n+\t\t}\n+\n+\t\tPHBDBG(p, \"FRESET: Assert\\n\");\n+\t\treg64 = in_be64(p->regs + PHB_RESET);\n+\t\treg64 &= ~0x2000000000000000ul;\n+\t\tout_be64(p->regs + PHB_RESET, reg64);\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_FRESET_ASSERT);\n+\t\treturn pci_slot_set_sm_timeout(slot, secs_to_tb(1));\n+\tcase P7IOC_SLOT_FRESET_ASSERT:\n+\t\tPHBDBG(p, \"FRESET: Deassert\\n\");\n+\t\treg64 = in_be64(p->regs + PHB_RESET);\n+\t\treg64 |= 0x2000000000000000ul;\n+\t\tout_be64(p->regs + PHB_RESET, reg64);\n+\t\tif (slot->ops.pfreset) {\n+\t\t\tpci_slot_set_state(slot,\n+\t\t\t\t\t   P7IOC_SLOT_PFRESET_START);\n+\t\t\treturn slot->ops.pfreset(slot);\n+\t\t}\n+\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_HRESET_START);\n+\t\treturn slot->ops.hreset(slot);\n+\tdefault:\n+\t\tPHBERR(p, \"FRESET: Unexpected slot state %08x\\n\",\n+\t\t       slot->state);\n+\t}\n+\n+out:\n+\tpci_slot_set_state(slot, P7IOC_SLOT_NORMAL);\n+\treturn OPAL_HARDWARE;\n+}\n+\n+static int64_t p7ioc_creset(struct pci_slot *slot)\n+{\n+\tstruct p7ioc_phb *p = phb_to_p7ioc_phb(slot->phb);\n+\tstruct p7ioc *ioc = p->ioc;\n+\tuint64_t reg64;\n+\n+\tswitch (slot->state) {\n+\tcase P7IOC_SLOT_NORMAL:\n+\t\tPHBDBG(p, \"CRESET: Starts\\n\");\n+\t\tp->flags |= P7IOC_PHB_CFG_BLOCKED;\n+\t\tp7ioc_phb_reset(slot->phb);\n+\n+\t\t/*\n+\t\t * According to the experiment, we probably still have the\n+\t\t * fenced state with the corresponding PHB in the Fence WOF\n+\t\t * and we need clear that explicitly. Besides, the RGC might\n+\t\t * already have informational error and we should clear that\n+\t\t * explicitly as well. Otherwise, RGC XIVE#0 won't issue\n+\t\t * interrupt any more.\n+\t\t */\n+\t\treg64 = in_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF);\n+\t\treg64 &= ~PPC_BIT(15 + p->index * 4);\n+\t\tout_be64(ioc->regs + P7IOC_CHIP_FENCE_WOF, reg64);\n+\n+\t\t/* Clear informational error from RGC */\n+\t\treg64 = in_be64(ioc->regs + P7IOC_RGC_LEM_BASE +\n+\t\t\t\tP7IOC_LEM_WOF_OFFSET);\n+\t\treg64 &= ~PPC_BIT(18);\n+\t\tout_be64(ioc->regs + P7IOC_RGC_LEM_BASE +\n+\t\t\t P7IOC_LEM_WOF_OFFSET, reg64);\n+\t\treg64 = in_be64(ioc->regs + P7IOC_RGC_LEM_BASE +\n+\t\t\t\tP7IOC_LEM_FIR_OFFSET);\n+\t\treg64 &= ~PPC_BIT(18);\n+\t\tout_be64(ioc->regs + P7IOC_RGC_LEM_BASE +\n+\t\t\t P7IOC_LEM_FIR_OFFSET, reg64);\n+\n+\t\t/* Swith to fundamental reset */\n+\t\tpci_slot_set_state(slot, P7IOC_SLOT_FRESET_START);\n+\t\treturn slot->ops.freset(slot);\n+\tdefault:\n+\t\tPHBERR(p, \"CRESET: Unexpected slot state %08x\\n\",\n+\t\t       slot->state);\n+\t}\n+\n+\tpci_slot_set_state(slot, P7IOC_SLOT_NORMAL);\n+\treturn OPAL_HARDWARE;\n+}\n+\n+static struct pci_slot *p7ioc_phb_slot_create(struct phb *phb)\n+{\n+\tstruct pci_slot *slot;\n+\n+\tslot = pci_slot_alloc(phb, NULL);\n+\tif (!slot)\n+\t\treturn NULL;\n+\n+\t/* Elementary functions */\n+\tslot->ops.get_presence_state   = p7ioc_get_presence_state;\n+\tslot->ops.get_link_state       = p7ioc_get_link_state;\n+\tslot->ops.get_power_state      = p7ioc_get_power_state;\n+\tslot->ops.get_attention_state  = NULL;\n+\tslot->ops.get_latch_state      = NULL;\n+\tslot->ops.set_power_state      = p7ioc_set_power_state;\n+\tslot->ops.set_attention_state  = NULL;\n+\n+\t/*\n+\t * For PHB slots, we have to split the fundamental reset\n+\t * into 2 steps. We might not have the first step which\n+\t * is to power off/on the slot, or it's controlled by\n+\t * individual platforms.\n+\t */\n+\tslot->ops.prepare_link_change  = p7ioc_prepare_link_change;\n+\tslot->ops.poll_link            = p7ioc_poll_link;\n+\tslot->ops.hreset               = p7ioc_hreset;\n+\tslot->ops.freset               = p7ioc_freset;\n+\tslot->ops.pfreset              = NULL;\n+\tslot->ops.creset               = p7ioc_creset;\n+\n+\treturn slot;\n+}\n+\n static const struct phb_ops p7ioc_phb_ops = {\n \t.cfg_read8\t\t= p7ioc_pcicfg_read8,\n \t.cfg_read16\t\t= p7ioc_pcicfg_read16,\n@@ -2596,15 +2360,6 @@ static const struct phb_ops p7ioc_phb_ops = {\n \t.get_msi_64\t\t= p7ioc_get_msi_64,\n \t.ioda_reset\t\t= p7ioc_ioda_reset,\n \t.papr_errinjct_reset\t= p7ioc_papr_errinjct_reset,\n-\t.presence_detect\t= p7ioc_presence_detect,\n-\t.link_state\t\t= p7ioc_link_state,\n-\t.power_state\t\t= p7ioc_power_state,\n-\t.slot_power_off\t\t= p7ioc_slot_power_off,\n-\t.slot_power_on\t\t= p7ioc_slot_power_on,\n-\t.complete_reset\t\t= p7ioc_complete_reset,\n-\t.hot_reset\t\t= p7ioc_hot_reset,\n-\t.fundamental_reset\t= p7ioc_freset,\n-\t.poll\t\t\t= p7ioc_poll,\n };\n \n /* p7ioc_phb_get_xive - Interrupt control from OPAL */\n@@ -2884,6 +2639,7 @@ void p7ioc_phb_setup(struct p7ioc *ioc, uint8_t index)\n {\n \tstruct p7ioc_phb *p = &ioc->phbs[index];\n \tunsigned int buid_base = ioc->buid_base + PHBn_BUID_BASE(index);\n+\tstruct pci_slot *slot;\n \n \tp->index = index;\n \tp->ioc = ioc;\n@@ -2924,6 +2680,10 @@ void p7ioc_phb_setup(struct p7ioc *ioc, uint8_t index)\n \t * get a useful OPAL ID for it\n \t */\n \tpci_register_phb(&p->phb, OPAL_DYNAMIC_PHB_ID);\n+\tslot = p7ioc_phb_slot_create(&p->phb);\n+\tif (!slot)\n+\t\tprlog(PR_NOTICE, \"P7IOC: Cannot create PHB#%d slot\\n\",\n+\t\t      p->phb.opal_id);\n \n \t/* Platform additional setup */\n \tif (platform.pci_setup_phb)\ndiff --git a/include/p7ioc.h b/include/p7ioc.h\nindex 85ea591..3b57a9c 100644\n--- a/include/p7ioc.h\n+++ b/include/p7ioc.h\n@@ -204,31 +204,32 @@ enum p7ioc_phb_state {\n \t/* PHB turned off by FSP (no clocks) */\n \tP7IOC_PHB_STATE_OFF,\n \n-\t/* Slot Power up state machine */\n-\tP7IOC_PHB_STATE_SPUP_STABILIZE_DELAY,\t\t/* Step 3 Delay 2s\t\t*/\n-\tP7IOC_PHB_STATE_SPUP_SLOT_STATUS,\t\t/* Step 4 waiting for status\t*/\n-\n-\t/* Slot Power down state machine */\n-\tP7IOC_PHB_STATE_SPDOWN_STABILIZE_DELAY,\t/* Step 2 Delay 2s\t\t*/\n-\tP7IOC_PHB_STATE_SPDOWN_SLOT_STATUS,\t/* Step 3 waiting for status\t*/\n-\n-\t/* Fundamental reset sequence */\n-\tP7IOC_PHB_STATE_FRESET_DISABLE_LINK,\t/* Disable link training\t\t*/\n-\tP7IOC_PHB_STATE_FRESET_ASSERT_DELAY,\t/* Delay on fundamental reset assert\t*/\n-\tP7IOC_PHB_STATE_FRESET_DEASSERT_DELAY,\t/* Delay on fundamental reset deassert\t*/\n-\tP7IOC_PHB_STATE_FRESET_WAIT_LINK,\t/* Wait for link up\t\t\t*/\n-\n-\t/* Hot Reset sequence */\n-\tP7IOC_PHB_STATE_HRESET_DISABLE_LINK,\t/* Disable Link training\t*/\n-\tP7IOC_PHB_STATE_HRESET_ASSERT,\t\t/* Hot reset assert\t\t*/\n-\tP7IOC_PHB_STATE_HRESET_DELAY,\t\t/* Hot reset delay\t\t*/\n-\tP7IOC_PHB_STATE_HRESET_ENABLE_LINK,\t/* Enable Link training\t\t*/\n-\tP7IOC_PHB_STATE_HRESET_WAIT_LINK,\t/* Wait link traing\t\t*/\n-\n \t/* Normal PHB functional state */\n \tP7IOC_PHB_STATE_FUNCTIONAL,\n };\n \n+/* P7IOC PHB slot states */\n+#define P7IOC_SLOT_NORMAL\t\t0x00000000\n+#define P7IOC_SLOT_LINK\t\t\t0x00000100\n+#define   P7IOC_SLOT_LINK_START\t\t0x00000101\n+#define   P7IOC_SLOT_LINK_WAIT\t\t0x00000102\n+#define P7IOC_SLOT_HRESET\t\t0x00000200\n+#define   P7IOC_SLOT_HRESET_START\t0x00000201\n+#define   P7IOC_SLOT_HRESET_TRAINING\t0x00000202\n+#define   P7IOC_SLOT_HRESET_DELAY\t0x00000203\n+#define   P7IOC_SLOT_HRESET_DELAY2\t0x00000204\n+#define P7IOC_SLOT_FRESET\t\t0x00000300\n+#define   P7IOC_SLOT_FRESET_START\t0x00000301\n+#define   P7IOC_SLOT_FRESET_TRAINING\t0x00000302\n+#define   P7IOC_SLOT_FRESET_POWER_OFF\t0x00000303\n+#define   P7IOC_SLOT_FRESET_POWER_ON\t0x00000304\n+#define   P7IOC_SLOT_FRESET_ASSERT\t0x00000305\n+#define   P7IOC_SLOT_FRESET_DEASSERT\t0x00000306\n+#define P7IOC_SLOT_PFRESET\t\t0x00000400\n+#define   P7IOC_SLOT_PFRESET_START\t0x00000401\n+#define P7IOC_SLOT_CRESET\t\t0x00000500\n+#define   P7IOC_SLOT_CRESET_START\t0x00000501\n+\n /*\n  * In order to support error detection and recovery on different\n  * types of IOCs (e.g. P5IOC, P7IOC, P8IOC), the best bet would\n@@ -286,12 +287,12 @@ struct p7ioc;\n \n #define P7IOC_PHB_CFG_USE_ASB\t0x00000001 /* ASB to access PCI-CFG     */\n #define P7IOC_PHB_CFG_BLOCKED\t0x00000002 /* PCI-CFG blocked except 0\t*/\n-#define P7IOC_RESTORE_BUS_NUM\t0x00000004 /* Restore buses after reset */\n \n struct p7ioc_phb {\n \tuint8_t\t\t\t\tindex;\t/* 0..5 index inside p7ioc */\n \tuint8_t\t\t\t\tgen;\n \tuint32_t\t\t\tflags;\n+\tenum p7ioc_phb_state\t\tstate;\n #define P7IOC_REV_DD10\t0x00a20001\n #define P7IOC_REV_DD11\t0x00a20002\n \tuint32_t\t\t\trev;\t/* Both major and minor have 2 bytes */\n@@ -302,9 +303,6 @@ struct p7ioc_phb {\n \tuint64_t\t\t\tio_base;\n \tuint64_t\t\t\tm32_base;\n \tuint64_t\t\t\tm64_base;\n-\tenum p7ioc_phb_state\t\tstate;\n-\tuint64_t\t\t\tdelay_tgt_tb;\n-\tuint64_t\t\t\tretries;\n \tint64_t\t\t\t\tecap;\t/* cached PCI-E cap offset */\n \tint64_t\t\t\t\taercap; /* cached AER ecap offset */\n \tuint64_t\t\t\tlxive_cache[8];\n",
    "prefixes": [
        "v12",
        "14/23"
    ]
}