From patchwork Tue Aug 29 09:23:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Lombard X-Patchwork-Id: 1827159 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=N+2VzQWB; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=patchwork.ozlabs.org) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RZhnl6Q2Gz1yfy for ; Tue, 29 Aug 2023 19:24:11 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=N+2VzQWB; dkim-atps=neutral Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4RZhnl5cHZz3bmP for ; Tue, 29 Aug 2023 19:24:11 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=N+2VzQWB; dkim-atps=neutral Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=linux.ibm.com (client-ip=148.163.158.5; helo=mx0b-001b2d01.pphosted.com; envelope-from=clombard@linux.ibm.com; receiver=lists.ozlabs.org) Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4RZhnG3WVNz2yW4 for ; Tue, 29 Aug 2023 19:23:46 +1000 (AEST) Received: from pps.filterd (m0353723.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 37T9DtqG004116 for ; Tue, 29 Aug 2023 09:23:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : subject : date : message-id : in-reply-to : references : content-transfer-encoding : mime-version; s=pp1; bh=EcTRUSO+oH+whTxskSvWb4igoKyvND0x/06mtfe7sj4=; b=N+2VzQWBRfV84Ka6sfVVnJ1ZLt+FVO18W4vN3uzKEaIHW0LnFiHGj75vndUpSPSRFy7G 04JT5phqZU+gVpdWiGtwoTeKgaXCIpE6DWkAdJUZQakQfHKYFDn9Iwyegng6wTKq15qz xbfWWYaN0hlvmcC2W9scmQOEPccHufNvG6sCpYZ82HL28AOf7ndOct9Z8vOGd6Mi6UXp 1T5ELDR4WPtq3GzR164gJXmctC3HCeDjhI68iNlhme+UHJpHEZKx6nYjdKgqfFp0QLeC QQhb8zon6L1uoTLbHR6bk4zIgK3RAB8dWDKDWEEbL3rv8SQyWp/1gJ2+Z/Vd0vb4Qh/L fw== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3sr87hqgkm-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 29 Aug 2023 09:23:42 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 37T8waAH004884 for ; Tue, 29 Aug 2023 09:23:42 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3squqsjk4q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 29 Aug 2023 09:23:42 +0000 Received: from smtpav02.fra02v.mail.ibm.com (smtpav02.fra02v.mail.ibm.com [10.20.54.101]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 37T9NeXk8585834 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 29 Aug 2023 09:23:40 GMT Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 791582004B for ; Tue, 29 Aug 2023 09:23:40 +0000 (GMT) Received: from smtpav02.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3B25220040 for ; Tue, 29 Aug 2023 09:23:40 +0000 (GMT) Received: from li-ac0ca24c-3330-11b2-a85c-93224c50ad7a.home (unknown [9.171.88.232]) by smtpav02.fra02v.mail.ibm.com (Postfix) with ESMTP for ; Tue, 29 Aug 2023 09:23:40 +0000 (GMT) From: Christophe Lombard To: skiboot@lists.ozlabs.org Date: Tue, 29 Aug 2023 11:23:19 +0200 Message-ID: <20230829092338.75785-3-clombard@linux.ibm.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230829092338.75785-1-clombard@linux.ibm.com> References: <20230829092338.75785-1-clombard@linux.ibm.com> X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 9L7-EwzCnF_Nh5riGgoWmeYPVJcKvgsQ X-Proofpoint-GUID: 9L7-EwzCnF_Nh5riGgoWmeYPVJcKvgsQ X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.267,Aquarius:18.0.957,Hydra:6.0.601,FMLib:17.11.176.26 definitions=2023-08-29_06,2023-08-28_04,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 priorityscore=1501 clxscore=1015 impostorscore=0 suspectscore=0 adultscore=0 mlxscore=0 malwarescore=0 phishscore=0 bulkscore=0 lowpriorityscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2308100000 definitions=main-2308290078 Subject: [Skiboot] [PATCH V10 02/21] hw/ast-bmc: Initialize ast lpc mctp binding X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" The Management Component Transport Protocol (MCTP) defines a communication model intended to facilitate communication. This patch initialize MCTP binding over LPC Bus interface. Several steps must be performed: - Initialize the MCTP core (mctp_init()). - Initialize a hardware binding as AST LPC mode host (mctp_astlpc_init()). - Register the hardware binding with the core (mctp_register_bus()), using a predefined EID (Host default is 9). To transmit a MCTP message, mctp_message_tx() is used. To receive a MCTP message, a callback need to be provided and registered through mctp_set_rx_all(). For the transfer of MCTP messages, two basics components are used: - A window of the LPC FW address space, where reads and writes are forwarded to BMC memory. - An interrupt mechanism using the KCS interface. hw/ast-bmc/ast-mctp.c is compilated if the compiler flag CONFIG_PLDM is set. Reviewed-by: Abhishek Singh Tomar Signed-off-by: Christophe Lombard --- hw/ast-bmc/Makefile.inc | 7 + hw/ast-bmc/ast-mctp.c | 364 ++++++++++++++++++++++++++++++++++++++ include/ast.h | 20 +++ platforms/astbmc/common.c | 41 +++++ 4 files changed, 432 insertions(+) create mode 100644 hw/ast-bmc/ast-mctp.c diff --git a/hw/ast-bmc/Makefile.inc b/hw/ast-bmc/Makefile.inc index e7ded0e88..546f2bc73 100644 --- a/hw/ast-bmc/Makefile.inc +++ b/hw/ast-bmc/Makefile.inc @@ -2,5 +2,12 @@ SUBDIRS += hw/ast-bmc AST_BMC_OBJS = ast-io.o ast-sf-ctrl.o + +ifeq ($(CONFIG_PLDM),1) +CPPFLAGS += -I$(SRC)/libmctp/ +#CFLAGS += -DAST_MCTP_DEBUG +AST_BMC_OBJS += ast-mctp.o +endif + AST_BMC = hw/ast-bmc/built-in.a $(AST_BMC): $(AST_BMC_OBJS:%=hw/ast-bmc/%) diff --git a/hw/ast-bmc/ast-mctp.c b/hw/ast-bmc/ast-mctp.c new file mode 100644 index 000000000..c2efb7b27 --- /dev/null +++ b/hw/ast-bmc/ast-mctp.c @@ -0,0 +1,364 @@ +// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later +// Copyright 2022 IBM Corp. + +#define pr_fmt(fmt) "AST-MCTP: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct mctp *mctp; +static struct mctp_binding_astlpc *astlpc; +static struct astlpc_ops_data *ops_data; +static struct lock mctp_lock = LOCK_UNLOCKED; + +/* Keyboard Controller Style (KCS) data register address */ +#define KCS_DATA_REG 0xca2 + +/* Keyboard Controller Style (KCS) status register address */ +#define KCS_STATUS_REG 0xca3 + +#define KCS_STATUS_BMC_READY 0x80 +#define KCS_STATUS_OBF 0x01 + +#define HOST_MAX_INCOMING_MESSAGE_ALLOCATION 131072 +#define DESIRED_MTU 32768 + +#define TX_POLL_MAX 5 + +/* + * The AST LPC binding is described here: + * + * https://github.com/openbmc/libmctp/blob/master/docs/bindings/vendor-ibm-astlpc.md + * + * Most of the binding is implemented in libmctp, but we need to provide + * accessors for the LPC FW space (for the packet buffer) and for the KCS + * peripheral (for the interrupt mechanism). + */ + +struct astlpc_ops_data { + uint16_t kcs_data_addr; /* LPC IO space offset for the data register */ + uint16_t kcs_stat_addr; + + /* address of the packet exchange buffer in FW space */ + uint32_t lpc_fw_addr; +}; + +static int astlpc_kcs_reg_read(void *binding_data, + enum mctp_binding_astlpc_kcs_reg reg, + uint8_t *val) +{ + struct astlpc_ops_data *ops_data = binding_data; + uint32_t addr; + + if (reg == MCTP_ASTLPC_KCS_REG_STATUS) + addr = ops_data->kcs_stat_addr; + else if (reg == MCTP_ASTLPC_KCS_REG_DATA) + addr = ops_data->kcs_data_addr; + else + return OPAL_PARAMETER; + + *val = lpc_inb(addr); + + return OPAL_SUCCESS; +} + +static int astlpc_kcs_reg_write(void *binding_data, + enum mctp_binding_astlpc_kcs_reg reg, + uint8_t val) +{ + struct astlpc_ops_data *ops_data = binding_data; + uint32_t addr; + + prlog(PR_TRACE, "%s 0x%hhx to %s\n", + __func__, val, reg ? "status" : "data"); + + if (reg == MCTP_ASTLPC_KCS_REG_STATUS) + addr = ops_data->kcs_stat_addr; + else if (reg == MCTP_ASTLPC_KCS_REG_DATA) + addr = ops_data->kcs_data_addr; + else + return OPAL_PARAMETER; + + lpc_outb(val, addr); + + return OPAL_SUCCESS; +} + +static int astlpc_read(void *binding_data, void *buf, long offset, + size_t len) +{ + struct astlpc_ops_data *ops_data = binding_data; + + prlog(PR_TRACE, "%s %zu bytes from 0x%lx (lpc: 0x%lx)\n", + __func__, len, offset, + ops_data->lpc_fw_addr + offset); + return lpc_fw_read(ops_data->lpc_fw_addr + offset, buf, len); +} + +static int astlpc_write(void *binding_data, const void *buf, + long offset, size_t len) +{ + struct astlpc_ops_data *ops_data = binding_data; + + prlog(PR_TRACE, "%s %zu bytes to offset 0x%lx (lpc: 0x%lx)\n", + __func__, len, offset, + ops_data->lpc_fw_addr + offset); + return lpc_fw_write(ops_data->lpc_fw_addr + offset, buf, len); +} + +static const struct mctp_binding_astlpc_ops astlpc_ops = { + .kcs_read = astlpc_kcs_reg_read, + .kcs_write = astlpc_kcs_reg_write, + .lpc_read = astlpc_read, + .lpc_write = astlpc_write, +}; + +/* we need a poller to crank the mctp state machine during boot */ +static void astlpc_poller(void *data) +{ + struct mctp_binding_astlpc *astlpc = (struct mctp_binding_astlpc *)data; + + if (astlpc) + mctp_astlpc_poll(astlpc); +} + +/* at runtime the interrupt should handle it */ +static void astlpc_interrupt(uint32_t chip_id __unused, + uint32_t irq_msk __unused) +{ + if (astlpc) + mctp_astlpc_poll(astlpc); +} + +static struct lpc_client kcs_lpc_client = { + .reset = NULL, + .interrupt = astlpc_interrupt, +}; + +static void drain_odr(struct astlpc_ops_data *ops_data) +{ + uint8_t kcs_status, kcs_data; + uint8_t drain_counter = 255; + + astlpc_kcs_reg_read(ops_data, MCTP_ASTLPC_KCS_REG_STATUS, &kcs_status); + + while (--drain_counter && (kcs_status & KCS_STATUS_OBF)) { + astlpc_kcs_reg_read(ops_data, MCTP_ASTLPC_KCS_REG_DATA, &kcs_data); + time_wait_ms(5); + astlpc_kcs_reg_read(ops_data, MCTP_ASTLPC_KCS_REG_STATUS, &kcs_status); + } +} + +static int astlpc_binding(void) +{ + struct mctp_bus *bus; + int counter = 0; + + ops_data = zalloc(sizeof(struct astlpc_ops_data)); + if (!ops_data) + return OPAL_NO_MEM; + + /* + * Current OpenBMC systems put the MCTP buffer 1MB down from + * the end of the LPC FW range. + * + * The size of the FW range is: 0x1000_0000 so the window be at: + * + * 0x1000_0000 - 2**20 == 0xff00000 + */ + ops_data->lpc_fw_addr = 0xff00000; + + /* values chosen by the OpenBMC driver */ + ops_data->kcs_data_addr = KCS_DATA_REG; + ops_data->kcs_stat_addr = KCS_STATUS_REG; + + /* Initialise the binding */ + astlpc = mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST, + DESIRED_MTU, + NULL, + &astlpc_ops, + ops_data); + if (!astlpc) { + prlog(PR_ERR, "binding init failed\n"); + return OPAL_HARDWARE; + } + + /* Read and discard any potentially stale messages in the ODR */ + drain_odr(ops_data); + + /* Register the binding to the LPC bus we are using for this + * MCTP configuration. + */ + if (mctp_register_bus(mctp, + mctp_binding_astlpc_core(astlpc), + HOST_EID)) { + prlog(PR_ERR, "failed to register bus\n"); + goto err; + } + + /* lpc/kcs status register poller */ + opal_add_poller(astlpc_poller, astlpc); + + /* Don't start sending messages to the BMC until the bus has + * been registered and tx has been enabled + */ + bus = mctp_binding_astlpc_core(astlpc)->bus; + + while ((bus == NULL) || + (mctp_bus_get_state(bus) == mctp_bus_state_constructed)) { + if (++counter >= 1000) { + prlog(PR_ERR, "failed to initialize MCTP channel\n"); + goto err; + } + time_wait_ms(5); + + /* Update bus pointer if it is a nullptr */ + if (bus == NULL) + bus = mctp_binding_astlpc_core(astlpc)->bus; + } + + return OPAL_SUCCESS; + +err: + mctp_astlpc_destroy(astlpc); + free(ops_data); + + return OPAL_HARDWARE; +} + +static void *mctp_malloc(size_t size) { return malloc(size); } +static void mctp_free(void *ptr) { return free(ptr); } +static void *mctp_realloc(void *ptr, size_t size) +{ + return realloc(ptr, size); +} + +#ifdef AST_MCTP_DEBUG +char buffer[320]; +static void mctp_log(int log_lvl, const char *fmt, va_list va) +{ + snprintf(buffer, sizeof(buffer), "%s\n", fmt); + vprlog(log_lvl, buffer, va); +} +#endif + +int ast_mctp_message_tx(bool tag_owner, uint8_t msg_tag, + uint8_t *msg, int msg_len) +{ + unsigned long stop_time; + int rc = OPAL_SUCCESS; + + lock(&mctp_lock); + + rc = mctp_message_tx(mctp, BMC_EID, tag_owner, msg_tag, + msg, msg_len); + unlock(&mctp_lock); + + /* do not poll when we respond to a BMC request */ + if (tag_owner) + return rc; + + /* read the Rx_complete command out of the ODR */ + stop_time = mftb() + msecs_to_tb(TX_POLL_MAX); + while (mftb() < stop_time && !mctp_astlpc_tx_done(astlpc)) + mctp_astlpc_poll(astlpc); + + return rc; +} + +static void message_rx(uint8_t eid, bool tag_owner, + uint8_t msg_tag, void *data __unused, + void *vmsg, size_t len) +{ + uint8_t *msg = (uint8_t *)vmsg; + + prlog(PR_TRACE, "message received: msg type: %x, len %zd" + " (eid: %d), rx tag %d owner %d\n", + *msg, len, eid, tag_owner, msg_tag); +} + +/* + * Initialize mctp binding for hbrt and provide interfaces for sending + * and receiving mctp messages. + */ +int ast_mctp_init(void) +{ + uint32_t kcs_serial_irq; + struct dt_node *n; + + /* Search mctp node */ + n = dt_find_compatible_node(dt_root, NULL, "mctp"); + if (!n) { + prlog(PR_ERR, "No MCTP device\n"); + return OPAL_PARAMETER; + } + + /* skiboot's malloc/free/realloc are macros so they need + * wrappers + */ + mctp_set_alloc_ops(mctp_malloc, mctp_free, mctp_realloc); + + /* + * /-----\ /---------\ + * | bmc | (eid: 8) <- lpc pcie / kcs -> (eid: 9) | skiboot | + * \-----/ \---------/ + */ + mctp = mctp_init(); + if (!mctp) { + prlog(PR_ERR, "mctp init failed\n"); + return OPAL_HARDWARE; + } + +#ifdef AST_MCTP_DEBUG + /* Setup the trace hook */ + mctp_set_log_custom(mctp_log); +#endif + + /* Set the max message size to be large enough */ + mctp_set_max_message_size(mctp, HOST_MAX_INCOMING_MESSAGE_ALLOCATION); + + /* Setup the message rx callback */ + mctp_set_rx_all(mctp, message_rx, NULL); + + /* Initialize the binding */ + if (astlpc_binding()) + goto err; + + /* register an lpc client so we get an interrupt */ + kcs_serial_irq = dt_prop_get_u32(n, "interrupts"); + kcs_lpc_client.interrupts = LPC_IRQ(kcs_serial_irq); + lpc_register_client(dt_get_chip_id(n), &kcs_lpc_client, IRQ_ATTR_TARGET_OPAL); + + return OPAL_SUCCESS; + +err: + prlog(PR_ERR, "Unable to initialize MCTP\n"); + mctp_destroy(mctp); + mctp = NULL; + + return OPAL_HARDWARE; +} + +void ast_mctp_exit(void) +{ + if (astlpc) { + mctp_astlpc_destroy(astlpc); + astlpc = NULL; + } + + if (mctp) { + mctp_destroy(mctp); + mctp = NULL; + } +} diff --git a/include/ast.h b/include/ast.h index 5e932398a..79efe4fcd 100644 --- a/include/ast.h +++ b/include/ast.h @@ -91,6 +91,26 @@ void ast_setup_ibt(uint16_t io_base, uint8_t irq); /* MBOX configuration */ void ast_setup_sio_mbox(uint16_t io_base, uint8_t irq); +/* MCTP configuration */ + +/* + * EID is the MCTP endpoint ID, which aids in routing MCTP packets. + * For the EIDs: the valid range is 8-254. + * We are saying that BMC is EID 8 and Skiboot is HOST_EID 9 + */ +#define BMC_EID 8 +#define HOST_EID 9 + +enum mctp_msg_type { + MCTP_MSG_TYPE_CONTROL = 0x00, + MCTP_MSG_TYPE_PLDM = 0x01, +}; + +int ast_mctp_message_tx(bool tag_owner, uint8_t msg_tag, + uint8_t *msg, int msg_len); +int ast_mctp_init(void); +void ast_mctp_exit(void); + #endif /* __SKIBOOT__ */ /* diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c index bfbba2d5f..6697230bd 100644 --- a/platforms/astbmc/common.c +++ b/platforms/astbmc/common.c @@ -31,6 +31,11 @@ #define MBOX_IO_COUNT 6 #define MBOX_LPC_IRQ 9 +/* MCTP config */ +#define MCTP_IO_BASE 0xca2 +#define MCTP_IO_COUNT 2 +#define MCTP_LPC_IRQ 11 + void astbmc_ext_irq_serirq_cpld(unsigned int chip_id) { lpc_all_interrupts(chip_id); @@ -227,6 +232,37 @@ static void astbmc_fixup_dt_system_id(void) dt_add_property_strings(dt_root, "system-id", "unavailable"); } +#ifdef CONFIG_PLDM +static void astbmc_fixup_dt_mctp(struct dt_node *lpc) +{ + struct dt_node *mctp; + char namebuf[32]; + + if (!lpc) + return; + + /* First check if the mbox interface is already there */ + dt_for_each_child(lpc, mctp) { + if (dt_node_is_compatible(mctp, "mctp")) + return; + } + + snprintf(namebuf, sizeof(namebuf), "mctp@i%x", MCTP_IO_BASE); + mctp = dt_new(lpc, namebuf); + + dt_add_property_cells(mctp, "reg", + 1, /* IO space */ + MCTP_IO_BASE, MCTP_IO_COUNT); + dt_add_property_strings(mctp, "compatible", "mctp"); + + /* Mark it as reserved to avoid Linux trying to claim it */ + dt_add_property_strings(mctp, "status", "reserved"); + + dt_add_property_cells(mctp, "interrupts", MCTP_LPC_IRQ); + dt_add_property_cells(mctp, "interrupt-parent", lpc->phandle); +} +#endif + static void astbmc_fixup_dt_bt(struct dt_node *lpc) { struct dt_node *bt; @@ -404,6 +440,11 @@ static void astbmc_fixup_dt(void) /* BT is not in HB either */ astbmc_fixup_dt_bt(primary_lpc); +#ifdef CONFIG_PLDM + /* Fixup the MCTP, that might be missing from HB */ + astbmc_fixup_dt_mctp(primary_lpc); +#endif + /* The pel logging code needs a system-id property to work so make sure we have one. */ astbmc_fixup_dt_system_id();