From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BE8D1C4363D for ; Thu, 8 Oct 2020 02:35:58 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 001772085B for ; Thu, 8 Oct 2020 02:35:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Pi7lrogz"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="RmymH21T" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 001772085B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Date:To:From: Subject:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=fq7EKGqdtNanYak4dHrV6G9rPtd+j7kWkmBk21qSpbM=; b=Pi7lrogz3weYMONxFy60hQ6b6 boEMjivvf43U3sQWxICF4aOEndnPbOpERaEPhBGVg/YARq5kWSIIR6TQ/eDPP1/zCJbXx3iGIo01u iFEnn03l5hN07KDo1E5u/hR7TJAqRfqoqIsli8xNf+8oIJy8pcBX+r5F1hhfObwpGJwfdd+3rqbrL indtxujyueKvUNeknGtkL1IxQ4dLhRP19ETzjpIyGeXVKr6zXgpawag+r7xcK9SA5N+SIMeQ8deT0 jF1t6QGGfzbc3Y27TU+K42Zm9UwqjU0OAmxoYJ5RCqHeFmJViIuU3qpwakOAZsMuNA/fzD14LFjZw zV6x+QTEg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kQLmV-0000uc-Uy; Thu, 08 Oct 2020 02:35:48 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kQLmQ-0000to-23; Thu, 08 Oct 2020 02:35:44 +0000 X-UUID: 941e4db970cb43a5810e6feb437c1f70-20201007 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=eUyQWurX7TEUFvUgroyyTolSOwQdWAlsjRrM01Zvm7Q=; b=RmymH21TpPcq9m+iGBio/irwVdu3VnHnSoqCHcxCwwXnxQMPRXT5WBLGb3WmxuMch4SpH3nzx5xDtCSjZ2sOMkMkpPlv91sASRsyUmK7dl9oeLdVn3LLiU9a2ymlvCvA8iIApU9DK1NhlcOkxnaB/3aG613jYhCV6YCnanWEjcQ=; X-UUID: 941e4db970cb43a5810e6feb437c1f70-20201007 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1879546882; Wed, 07 Oct 2020 18:35:24 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 7 Oct 2020 19:35:22 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 8 Oct 2020 10:35:14 +0800 Received: from [172.21.77.33] (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 8 Oct 2020 10:35:14 +0800 Message-ID: <1602124514.28301.17.camel@mtkswgap22> Subject: Re: [PATCH v7 2/2] soc: mediatek: add mt6779 devapc driver From: Neal Liu To: Matthias Brugger Date: Thu, 8 Oct 2020 10:35:14 +0800 In-Reply-To: References: <1598497593-15781-1-git-send-email-neal.liu@mediatek.com> <1598497593-15781-3-git-send-email-neal.liu@mediatek.com> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-TM-SNTS-SMTP: 9FA1AAA7491D792DC98672D1D1A0F49F3CA1AE3E773A0A3C478DB17D4AA32D362000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201007_223542_331818_B4B5D028 X-CRM114-Status: GOOD ( 48.68 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Chun-Kuang Hu , wsd_upstream@mediatek.com, devicetree@vger.kernel.org, lkml , Rob Herring , linux-mediatek@lists.infradead.org, Neal Liu , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org On Wed, 2020-10-07 at 12:44 +0200, Matthias Brugger wrote: > > On 27/08/2020 05:06, Neal Liu wrote: > > MediaTek bus fabric provides TrustZone security support and data > > protection to prevent slaves from being accessed by unexpected > > masters. > > The security violation is logged and sent to the processor for > > further analysis or countermeasures. > > > > Any occurrence of security violation would raise an interrupt, and > > it will be handled by mtk-devapc driver. The violation > > information is printed in order to find the murderer. > > "The violation information is printed in order to find the responsible component." > > Nobody got actually killed, right :) Correct ! > > > > > Signed-off-by: Neal Liu > > --- > > drivers/soc/mediatek/Kconfig | 9 ++ > > drivers/soc/mediatek/Makefile | 1 + > > drivers/soc/mediatek/mtk-devapc.c | 305 +++++++++++++++++++++++++++++++++++++ > > 3 files changed, 315 insertions(+) > > create mode 100644 drivers/soc/mediatek/mtk-devapc.c > > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig > > index 59a56cd..1177c98 100644 > > --- a/drivers/soc/mediatek/Kconfig > > +++ b/drivers/soc/mediatek/Kconfig > > @@ -17,6 +17,15 @@ config MTK_CMDQ > > time limitation, such as updating display configuration during the > > vblank. > > > > +config MTK_DEVAPC > > + tristate "Mediatek Device APC Support" > > + help > > + Say yes here to enable support for Mediatek Device APC driver. > > + This driver is mainly used to handle the violation which catches > > + unexpected transaction. > > + The violation information is logged for further analysis or > > + countermeasures. > > + > > config MTK_INFRACFG > > bool "MediaTek INFRACFG Support" > > select REGMAP > > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile > > index 01f9f87..abfd4ba 100644 > > --- a/drivers/soc/mediatek/Makefile > > +++ b/drivers/soc/mediatek/Makefile > > @@ -1,5 +1,6 @@ > > # SPDX-License-Identifier: GPL-2.0-only > > obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o > > +obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o > > obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o > > obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o > > obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o > > diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c > > new file mode 100644 > > index 0000000..0ba61d7 > > --- /dev/null > > +++ b/drivers/soc/mediatek/mtk-devapc.c > > @@ -0,0 +1,305 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2020 MediaTek Inc. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define VIO_MOD_TO_REG_IND(m) ((m) / 32) > > +#define VIO_MOD_TO_REG_OFF(m) ((m) % 32) > > + > > +struct mtk_devapc_vio_dbgs { > > + union { > > + u32 vio_dbg0; > > + struct { > > + u32 mstid:16; > > + u32 dmnid:6; > > + u32 vio_w:1; > > + u32 vio_r:1; > > + u32 addr_h:4; > > + u32 resv:4; > > + } dbg0_bits; > > + }; > > + > > + u32 vio_dbg1; > > +}; > > + > > +struct mtk_devapc_data { > > + u32 vio_idx_num; > > + u32 vio_mask_offset; > > + u32 vio_sta_offset; > > + u32 vio_dbg0_offset; > > + u32 vio_dbg1_offset; > > + u32 apc_con_offset; > > + u32 vio_shift_sta_offset; > > + u32 vio_shift_sel_offset; > > + u32 vio_shift_con_offset; > > +}; > > Please describe the fields of the struct, that will make it easier to understand > the driver. Okay, I'll try to add more description about this struct. May be like: struct mtk_devapc_data { /* numbers of violation index */ u32 vio_idx_num; /* reg offset */ u32 vio_mask_offset; u32 vio_sta_offset; u32 vio_dbg0_offset; u32 vio_dbg1_offset; u32 apc_con_offset; u32 vio_shift_sta_offset; u32 vio_shift_sel_offset; u32 vio_shift_con_offset; }; > > > + > > +struct mtk_devapc_context { > > + struct device *dev; > > + void __iomem *infra_base; > > + struct clk *infra_clk; > > + const struct mtk_devapc_data *data; > > +}; > > + > > +static void clear_vio_status(struct mtk_devapc_context *ctx) > > +{ > > + void __iomem *reg; > > + int i; > > + > > + reg = ctx->infra_base + ctx->data->vio_sta_offset; > > + > > + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num - 1); i++) > > + writel(GENMASK(31, 0), reg + 4 * i); > > + > > + writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num - 1), 0), > > + reg + 4 * i); > > +} > > + > > +static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask) > > +{ > > + void __iomem *reg; > > + u32 val; > > + int i; > > + > > + reg = ctx->infra_base + ctx->data->vio_mask_offset; > > + > > + if (mask) > > + val = GENMASK(31, 0); > > + else > > + val = 0; > > + > > + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num - 1); i++) > > Do I get that right? We have a number of virtual IO identifier. Their > correspondending interrupt are grouped in 32 bit registers. And we want to > enable/disable them by writing 0 or 1. We have to take care of the last > registers as it could be the case that vio_idx_num is not a multiple of 32, correct? > > In this case we should traverse VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1 > registers, which is (vio_idx_num / 32) - 1 and not (vio_idx_num - 1) / 32. > Yes, your understanding is correct. It should be VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1 instead of VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num - 1). > > + writel(val, reg + 4 * i); > > + > > + val = readl(reg + 4 * i); > > + if (mask) > > + val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num - 1), > > + 0); > > We have 511 IRQs, which gives us 31 bits in the last register to set/unset. > Thats 510..0 bits, so from what I understand, once again we want > GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0) > which is (vio_idx_num % 32) - 1 > > Correct or do I understand something wrong? > If so, same applies to clear_vio_status(). > Correct. I'll fix it on next patch. Thanks > > > + else > > + val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num - 1), > > + 0); > > + > > + writel(val, reg + 4 * i); > > +} > > + > > +#define PHY_DEVAPC_TIMEOUT 0x10000 > > + > > +/* > > + * devapc_sync_vio_dbg - do "shift" mechansim" to get full violation information. > > + * shift mechanism is depends on devapc hardware design. > > + * Mediatek devapc set multiple slaves as a group. > > + * When violation is triggered, violation info is kept > > + * inside devapc hardware. > > + * Driver should do shift mechansim to sync full violation > > + * info to VIO_DBGs registers. > > + * > > + */ > > +static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx) > > +{ > > + void __iomem *pd_vio_shift_sta_reg; > > + void __iomem *pd_vio_shift_sel_reg; > > + void __iomem *pd_vio_shift_con_reg; > > + int min_shift_group; > > + int ret; > > + u32 val; > > + > > + pd_vio_shift_sta_reg = ctx->infra_base + > > + ctx->data->vio_shift_sta_offset; > > + pd_vio_shift_sel_reg = ctx->infra_base + > > + ctx->data->vio_shift_sel_offset; > > + pd_vio_shift_con_reg = ctx->infra_base + > > + ctx->data->vio_shift_con_offset; > > + > > + /* Find the minimum shift group which has violation */ > > + val = readl(pd_vio_shift_sta_reg); > > + if (!val) > > + return false; > > So bit 0 of selection register (pd_vio_shift_sel_reg) does not represent a > violation group? > I don't know how the HW works, but is seems odd to me. In case that's bit 0 > actually doesn't represent anything: how can an interrupt be triggered without > any debug information present (means val == 0)? This check implies HW status has something wrong. It cannot get any debug information for this case. It won't happen in normal scenario. Should we remove this check? > > > + > > + min_shift_group = __ffs(val); > > + > > + /* Assign the group to sync */ > > + writel(0x1 << min_shift_group, pd_vio_shift_sel_reg); > > + > > + /* Start syncing */ > > + writel(0x1, pd_vio_shift_con_reg); > > + > > + ret = readl_poll_timeout(pd_vio_shift_con_reg, val, val == 0x3, 0, > > + PHY_DEVAPC_TIMEOUT); > > + if (ret) { > > + dev_err(ctx->dev, "%s: Shift violation info failed\n", __func__); > > In which case this can happen? I'm asking, because we are calling > devapc_sync_vio_dbg() in a while loop that could make the kernel hang here. > > Do I understand correctly, that we are using the while loop, because there can > be more then one violation group which got triggered (read, more then one bit is > set in pd_vio_shift_sta_reg)? Would it make more sense then to read the register > once and do all the shift operation for all groups which bit set to 1 in the > shift status register? Yes, your understanding is correct. This check also implies HW status has something wrong. We return false to skip further violation info dump. How could this case make the kernel hang? > > > + return false; > > + } > > + > > + /* Stop syncing */ > > + writel(0x0, pd_vio_shift_con_reg); > > + > > + /* Write clear */ > > + writel(0x1 << min_shift_group, pd_vio_shift_sta_reg); > > + > > + return true; > > +} > > + > > +/* > > + * devapc_extract_vio_dbg - extract full violation information after doing > > + * shift mechanism. > > + */ > > +static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx) > > +{ > > + struct mtk_devapc_vio_dbgs vio_dbgs; > > + void __iomem *vio_dbg0_reg; > > + void __iomem *vio_dbg1_reg; > > + > > + vio_dbg0_reg = ctx->infra_base + ctx->data->vio_dbg0_offset; > > + vio_dbg1_reg = ctx->infra_base + ctx->data->vio_dbg1_offset; > > + > > + vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg); > > + vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg); > > + > > + /* Print violation information */ > > + if (vio_dbgs.dbg0_bits.vio_w) > > + dev_info(ctx->dev, "Write Violation\n"); > > + else if (vio_dbgs.dbg0_bits.vio_r) > > + dev_info(ctx->dev, "Read Violation\n"); > > + > > + dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n", > > + vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid, > > + vio_dbgs.vio_dbg1); > > +} > > + > > +/* > > + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump > > + * violation information including which master violates > > + * access slave. > > + */ > > +static irqreturn_t devapc_violation_irq(int irq_number, > > + struct mtk_devapc_context *ctx) > > static irqreturn_t devapc_violation_irq(int irq_number, void *data) > { > struct mtk_devapc_context *ctx = data; Okay, I'll fix it on next patch. Thanks > > > +{ > > + while (devapc_sync_vio_dbg(ctx)) > > + devapc_extract_vio_dbg(ctx); > > + > > + clear_vio_status(ctx); > > + > > + return IRQ_HANDLED; > > +} > > + > > +/* > > + * start_devapc - unmask slave's irq to start receiving devapc violation. > > + */ > > +static void start_devapc(struct mtk_devapc_context *ctx) > > +{ > > + writel(BIT(31), ctx->infra_base + ctx->data->apc_con_offset); > > + > > + mask_module_irq(ctx, false); > > +} > > + > > +/* > > + * stop_devapc - mask slave's irq to stop service. > > + */ > > +static void stop_devapc(struct mtk_devapc_context *ctx) > > +{ > > + mask_module_irq(ctx, true); > > + > > + writel(BIT(2), ctx->infra_base + ctx->data->apc_con_offset); > > +} > > + > > +static const struct mtk_devapc_data devapc_mt6779 = { > > + .vio_idx_num = 511, > > + .vio_mask_offset = 0x0, > > + .vio_sta_offset = 0x400, > > + .vio_dbg0_offset = 0x900, > > + .vio_dbg1_offset = 0x904, > > + .apc_con_offset = 0xF00, > > + .vio_shift_sta_offset = 0xF10, > > + .vio_shift_sel_offset = 0xF14, > > + .vio_shift_con_offset = 0xF20, > > +}; > > + > > +static const struct of_device_id mtk_devapc_dt_match[] = { > > + { > > + .compatible = "mediatek,mt6779-devapc", > > + .data = &devapc_mt6779, > > + }, { > > + }, > > +}; > > + > > +static int mtk_devapc_probe(struct platform_device *pdev) > > +{ > > + struct device_node *node = pdev->dev.of_node; > > + struct mtk_devapc_context *ctx; > > + u32 devapc_irq; > > + int ret; > > + > > + if (IS_ERR(node)) > > + return -ENODEV; > > + > > + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); > > + if (!ctx) > > + return -ENOMEM; > > + > > + ctx->data = of_device_get_match_data(&pdev->dev); > > + ctx->dev = &pdev->dev; > > + > > + ctx->infra_base = of_iomap(node, 0); > > Does this mean the device is part of the infracfg block? > I wasn't able to find any information about it. I'm not sure why you would ask infracfg block. devapc is parts of our SoC infra, it's different with infracfg. > > > + if (!ctx->infra_base) > > + return -EINVAL; > > + > > + devapc_irq = irq_of_parse_and_map(node, 0); > > + if (!devapc_irq) > > + return -EINVAL; > > + > > + ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock"); > > + if (IS_ERR(ctx->infra_clk)) > > + return -EINVAL; > > + > > + if (clk_prepare_enable(ctx->infra_clk)) > > + return -EINVAL; > > + > > + ret = devm_request_irq(&pdev->dev, devapc_irq, > > + (irq_handler_t)devapc_violation_irq, > > No cast should be needed. Okay, I'll remove it on next patch. Thanks > > > + IRQF_TRIGGER_NONE, "devapc", ctx); > > + if (ret) { > > + clk_disable_unprepare(ctx->infra_clk); > > + return ret; > > + } > > + > > + platform_set_drvdata(pdev, ctx); > > + > > + start_devapc(ctx); > > + > > + return 0; > > +} > > + > > +static int mtk_devapc_remove(struct platform_device *pdev) > > +{ > > + struct mtk_devapc_context *ctx = platform_get_drvdata(pdev); > > + > > + stop_devapc(ctx); > > + > > + clk_disable_unprepare(ctx->infra_clk); > > + > > + return 0; > > +} > > + > > +static struct platform_driver mtk_devapc_driver = { > > + .probe = mtk_devapc_probe, > > + .remove = mtk_devapc_remove, > > + .driver = { > > + .name = KBUILD_MODNAME, > > .name = "mtk-devapc", Okay, I'll add it on next patch. Thanks > > Regards, > Matthias _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9E8E9C4363D for ; Thu, 8 Oct 2020 02:37:31 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 16D212145D for ; Thu, 8 Oct 2020 02:37:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="L+4jzT5O"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="RmymH21T" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 16D212145D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Date:To:From: Subject:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=26NVtkIbFYyFr1dREw0HxXPr3hHq3B2UslLqlGaZM1s=; b=L+4jzT5Of3DWM1iFi6ufOxxPI rtZqS97WVuZPo/yUWhMAxfxfNOUyDQoUrJh/mXJ365TcnWlXJjImTBZFto9GKMJYP1LvlkF0UqN6h cCDLgb1h/EBBQ9HjnpR+/ABt4oNTHo14sFl/6ENbuQMLj6sXg2VKehtir4lGylP2py3dMv4KECLfd hBwNPGApcq0KVCBK/kSzA0xlNZM+M/swsE1oIaqrq6+wBghGCO4zO2mLUlH+VAvMMBYI+VIV8V39J hOeGLzKY0UGMKZINy2QvO5m7Yq0sa2OXJ3JcNDJBeTO0irwrVdMKpnjwiK7cTW1nNwrccMBZLuETI zz5Vni5Sg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kQLmU-0000uN-DN; Thu, 08 Oct 2020 02:35:46 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kQLmQ-0000to-23; Thu, 08 Oct 2020 02:35:44 +0000 X-UUID: 941e4db970cb43a5810e6feb437c1f70-20201007 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=eUyQWurX7TEUFvUgroyyTolSOwQdWAlsjRrM01Zvm7Q=; b=RmymH21TpPcq9m+iGBio/irwVdu3VnHnSoqCHcxCwwXnxQMPRXT5WBLGb3WmxuMch4SpH3nzx5xDtCSjZ2sOMkMkpPlv91sASRsyUmK7dl9oeLdVn3LLiU9a2ymlvCvA8iIApU9DK1NhlcOkxnaB/3aG613jYhCV6YCnanWEjcQ=; X-UUID: 941e4db970cb43a5810e6feb437c1f70-20201007 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1879546882; Wed, 07 Oct 2020 18:35:24 -0800 Received: from MTKMBS02N2.mediatek.inc (172.21.101.101) by MTKMBS62DR.mediatek.inc (172.29.94.18) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Wed, 7 Oct 2020 19:35:22 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 8 Oct 2020 10:35:14 +0800 Received: from [172.21.77.33] (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 8 Oct 2020 10:35:14 +0800 Message-ID: <1602124514.28301.17.camel@mtkswgap22> Subject: Re: [PATCH v7 2/2] soc: mediatek: add mt6779 devapc driver From: Neal Liu To: Matthias Brugger Date: Thu, 8 Oct 2020 10:35:14 +0800 In-Reply-To: References: <1598497593-15781-1-git-send-email-neal.liu@mediatek.com> <1598497593-15781-3-git-send-email-neal.liu@mediatek.com> X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-TM-SNTS-SMTP: 9FA1AAA7491D792DC98672D1D1A0F49F3CA1AE3E773A0A3C478DB17D4AA32D362000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201007_223542_331818_B4B5D028 X-CRM114-Status: GOOD ( 48.68 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Chun-Kuang Hu , wsd_upstream@mediatek.com, devicetree@vger.kernel.org, lkml , Rob Herring , linux-mediatek@lists.infradead.org, Neal Liu , linux-arm-kernel@lists.infradead.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Wed, 2020-10-07 at 12:44 +0200, Matthias Brugger wrote: > > On 27/08/2020 05:06, Neal Liu wrote: > > MediaTek bus fabric provides TrustZone security support and data > > protection to prevent slaves from being accessed by unexpected > > masters. > > The security violation is logged and sent to the processor for > > further analysis or countermeasures. > > > > Any occurrence of security violation would raise an interrupt, and > > it will be handled by mtk-devapc driver. The violation > > information is printed in order to find the murderer. > > "The violation information is printed in order to find the responsible component." > > Nobody got actually killed, right :) Correct ! > > > > > Signed-off-by: Neal Liu > > --- > > drivers/soc/mediatek/Kconfig | 9 ++ > > drivers/soc/mediatek/Makefile | 1 + > > drivers/soc/mediatek/mtk-devapc.c | 305 +++++++++++++++++++++++++++++++++++++ > > 3 files changed, 315 insertions(+) > > create mode 100644 drivers/soc/mediatek/mtk-devapc.c > > > > diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig > > index 59a56cd..1177c98 100644 > > --- a/drivers/soc/mediatek/Kconfig > > +++ b/drivers/soc/mediatek/Kconfig > > @@ -17,6 +17,15 @@ config MTK_CMDQ > > time limitation, such as updating display configuration during the > > vblank. > > > > +config MTK_DEVAPC > > + tristate "Mediatek Device APC Support" > > + help > > + Say yes here to enable support for Mediatek Device APC driver. > > + This driver is mainly used to handle the violation which catches > > + unexpected transaction. > > + The violation information is logged for further analysis or > > + countermeasures. > > + > > config MTK_INFRACFG > > bool "MediaTek INFRACFG Support" > > select REGMAP > > diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile > > index 01f9f87..abfd4ba 100644 > > --- a/drivers/soc/mediatek/Makefile > > +++ b/drivers/soc/mediatek/Makefile > > @@ -1,5 +1,6 @@ > > # SPDX-License-Identifier: GPL-2.0-only > > obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o > > +obj-$(CONFIG_MTK_DEVAPC) += mtk-devapc.o > > obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o > > obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o > > obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o > > diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c > > new file mode 100644 > > index 0000000..0ba61d7 > > --- /dev/null > > +++ b/drivers/soc/mediatek/mtk-devapc.c > > @@ -0,0 +1,305 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (C) 2020 MediaTek Inc. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define VIO_MOD_TO_REG_IND(m) ((m) / 32) > > +#define VIO_MOD_TO_REG_OFF(m) ((m) % 32) > > + > > +struct mtk_devapc_vio_dbgs { > > + union { > > + u32 vio_dbg0; > > + struct { > > + u32 mstid:16; > > + u32 dmnid:6; > > + u32 vio_w:1; > > + u32 vio_r:1; > > + u32 addr_h:4; > > + u32 resv:4; > > + } dbg0_bits; > > + }; > > + > > + u32 vio_dbg1; > > +}; > > + > > +struct mtk_devapc_data { > > + u32 vio_idx_num; > > + u32 vio_mask_offset; > > + u32 vio_sta_offset; > > + u32 vio_dbg0_offset; > > + u32 vio_dbg1_offset; > > + u32 apc_con_offset; > > + u32 vio_shift_sta_offset; > > + u32 vio_shift_sel_offset; > > + u32 vio_shift_con_offset; > > +}; > > Please describe the fields of the struct, that will make it easier to understand > the driver. Okay, I'll try to add more description about this struct. May be like: struct mtk_devapc_data { /* numbers of violation index */ u32 vio_idx_num; /* reg offset */ u32 vio_mask_offset; u32 vio_sta_offset; u32 vio_dbg0_offset; u32 vio_dbg1_offset; u32 apc_con_offset; u32 vio_shift_sta_offset; u32 vio_shift_sel_offset; u32 vio_shift_con_offset; }; > > > + > > +struct mtk_devapc_context { > > + struct device *dev; > > + void __iomem *infra_base; > > + struct clk *infra_clk; > > + const struct mtk_devapc_data *data; > > +}; > > + > > +static void clear_vio_status(struct mtk_devapc_context *ctx) > > +{ > > + void __iomem *reg; > > + int i; > > + > > + reg = ctx->infra_base + ctx->data->vio_sta_offset; > > + > > + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num - 1); i++) > > + writel(GENMASK(31, 0), reg + 4 * i); > > + > > + writel(GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num - 1), 0), > > + reg + 4 * i); > > +} > > + > > +static void mask_module_irq(struct mtk_devapc_context *ctx, bool mask) > > +{ > > + void __iomem *reg; > > + u32 val; > > + int i; > > + > > + reg = ctx->infra_base + ctx->data->vio_mask_offset; > > + > > + if (mask) > > + val = GENMASK(31, 0); > > + else > > + val = 0; > > + > > + for (i = 0; i < VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num - 1); i++) > > Do I get that right? We have a number of virtual IO identifier. Their > correspondending interrupt are grouped in 32 bit registers. And we want to > enable/disable them by writing 0 or 1. We have to take care of the last > registers as it could be the case that vio_idx_num is not a multiple of 32, correct? > > In this case we should traverse VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1 > registers, which is (vio_idx_num / 32) - 1 and not (vio_idx_num - 1) / 32. > Yes, your understanding is correct. It should be VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num) - 1 instead of VIO_MOD_TO_REG_IND(ctx->data->vio_idx_num - 1). > > + writel(val, reg + 4 * i); > > + > > + val = readl(reg + 4 * i); > > + if (mask) > > + val |= GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num - 1), > > + 0); > > We have 511 IRQs, which gives us 31 bits in the last register to set/unset. > Thats 510..0 bits, so from what I understand, once again we want > GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num) - 1, 0) > which is (vio_idx_num % 32) - 1 > > Correct or do I understand something wrong? > If so, same applies to clear_vio_status(). > Correct. I'll fix it on next patch. Thanks > > > + else > > + val &= ~GENMASK(VIO_MOD_TO_REG_OFF(ctx->data->vio_idx_num - 1), > > + 0); > > + > > + writel(val, reg + 4 * i); > > +} > > + > > +#define PHY_DEVAPC_TIMEOUT 0x10000 > > + > > +/* > > + * devapc_sync_vio_dbg - do "shift" mechansim" to get full violation information. > > + * shift mechanism is depends on devapc hardware design. > > + * Mediatek devapc set multiple slaves as a group. > > + * When violation is triggered, violation info is kept > > + * inside devapc hardware. > > + * Driver should do shift mechansim to sync full violation > > + * info to VIO_DBGs registers. > > + * > > + */ > > +static int devapc_sync_vio_dbg(struct mtk_devapc_context *ctx) > > +{ > > + void __iomem *pd_vio_shift_sta_reg; > > + void __iomem *pd_vio_shift_sel_reg; > > + void __iomem *pd_vio_shift_con_reg; > > + int min_shift_group; > > + int ret; > > + u32 val; > > + > > + pd_vio_shift_sta_reg = ctx->infra_base + > > + ctx->data->vio_shift_sta_offset; > > + pd_vio_shift_sel_reg = ctx->infra_base + > > + ctx->data->vio_shift_sel_offset; > > + pd_vio_shift_con_reg = ctx->infra_base + > > + ctx->data->vio_shift_con_offset; > > + > > + /* Find the minimum shift group which has violation */ > > + val = readl(pd_vio_shift_sta_reg); > > + if (!val) > > + return false; > > So bit 0 of selection register (pd_vio_shift_sel_reg) does not represent a > violation group? > I don't know how the HW works, but is seems odd to me. In case that's bit 0 > actually doesn't represent anything: how can an interrupt be triggered without > any debug information present (means val == 0)? This check implies HW status has something wrong. It cannot get any debug information for this case. It won't happen in normal scenario. Should we remove this check? > > > + > > + min_shift_group = __ffs(val); > > + > > + /* Assign the group to sync */ > > + writel(0x1 << min_shift_group, pd_vio_shift_sel_reg); > > + > > + /* Start syncing */ > > + writel(0x1, pd_vio_shift_con_reg); > > + > > + ret = readl_poll_timeout(pd_vio_shift_con_reg, val, val == 0x3, 0, > > + PHY_DEVAPC_TIMEOUT); > > + if (ret) { > > + dev_err(ctx->dev, "%s: Shift violation info failed\n", __func__); > > In which case this can happen? I'm asking, because we are calling > devapc_sync_vio_dbg() in a while loop that could make the kernel hang here. > > Do I understand correctly, that we are using the while loop, because there can > be more then one violation group which got triggered (read, more then one bit is > set in pd_vio_shift_sta_reg)? Would it make more sense then to read the register > once and do all the shift operation for all groups which bit set to 1 in the > shift status register? Yes, your understanding is correct. This check also implies HW status has something wrong. We return false to skip further violation info dump. How could this case make the kernel hang? > > > + return false; > > + } > > + > > + /* Stop syncing */ > > + writel(0x0, pd_vio_shift_con_reg); > > + > > + /* Write clear */ > > + writel(0x1 << min_shift_group, pd_vio_shift_sta_reg); > > + > > + return true; > > +} > > + > > +/* > > + * devapc_extract_vio_dbg - extract full violation information after doing > > + * shift mechanism. > > + */ > > +static void devapc_extract_vio_dbg(struct mtk_devapc_context *ctx) > > +{ > > + struct mtk_devapc_vio_dbgs vio_dbgs; > > + void __iomem *vio_dbg0_reg; > > + void __iomem *vio_dbg1_reg; > > + > > + vio_dbg0_reg = ctx->infra_base + ctx->data->vio_dbg0_offset; > > + vio_dbg1_reg = ctx->infra_base + ctx->data->vio_dbg1_offset; > > + > > + vio_dbgs.vio_dbg0 = readl(vio_dbg0_reg); > > + vio_dbgs.vio_dbg1 = readl(vio_dbg1_reg); > > + > > + /* Print violation information */ > > + if (vio_dbgs.dbg0_bits.vio_w) > > + dev_info(ctx->dev, "Write Violation\n"); > > + else if (vio_dbgs.dbg0_bits.vio_r) > > + dev_info(ctx->dev, "Read Violation\n"); > > + > > + dev_info(ctx->dev, "Bus ID:0x%x, Dom ID:0x%x, Vio Addr:0x%x\n", > > + vio_dbgs.dbg0_bits.mstid, vio_dbgs.dbg0_bits.dmnid, > > + vio_dbgs.vio_dbg1); > > +} > > + > > +/* > > + * devapc_violation_irq - the devapc Interrupt Service Routine (ISR) will dump > > + * violation information including which master violates > > + * access slave. > > + */ > > +static irqreturn_t devapc_violation_irq(int irq_number, > > + struct mtk_devapc_context *ctx) > > static irqreturn_t devapc_violation_irq(int irq_number, void *data) > { > struct mtk_devapc_context *ctx = data; Okay, I'll fix it on next patch. Thanks > > > +{ > > + while (devapc_sync_vio_dbg(ctx)) > > + devapc_extract_vio_dbg(ctx); > > + > > + clear_vio_status(ctx); > > + > > + return IRQ_HANDLED; > > +} > > + > > +/* > > + * start_devapc - unmask slave's irq to start receiving devapc violation. > > + */ > > +static void start_devapc(struct mtk_devapc_context *ctx) > > +{ > > + writel(BIT(31), ctx->infra_base + ctx->data->apc_con_offset); > > + > > + mask_module_irq(ctx, false); > > +} > > + > > +/* > > + * stop_devapc - mask slave's irq to stop service. > > + */ > > +static void stop_devapc(struct mtk_devapc_context *ctx) > > +{ > > + mask_module_irq(ctx, true); > > + > > + writel(BIT(2), ctx->infra_base + ctx->data->apc_con_offset); > > +} > > + > > +static const struct mtk_devapc_data devapc_mt6779 = { > > + .vio_idx_num = 511, > > + .vio_mask_offset = 0x0, > > + .vio_sta_offset = 0x400, > > + .vio_dbg0_offset = 0x900, > > + .vio_dbg1_offset = 0x904, > > + .apc_con_offset = 0xF00, > > + .vio_shift_sta_offset = 0xF10, > > + .vio_shift_sel_offset = 0xF14, > > + .vio_shift_con_offset = 0xF20, > > +}; > > + > > +static const struct of_device_id mtk_devapc_dt_match[] = { > > + { > > + .compatible = "mediatek,mt6779-devapc", > > + .data = &devapc_mt6779, > > + }, { > > + }, > > +}; > > + > > +static int mtk_devapc_probe(struct platform_device *pdev) > > +{ > > + struct device_node *node = pdev->dev.of_node; > > + struct mtk_devapc_context *ctx; > > + u32 devapc_irq; > > + int ret; > > + > > + if (IS_ERR(node)) > > + return -ENODEV; > > + > > + ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); > > + if (!ctx) > > + return -ENOMEM; > > + > > + ctx->data = of_device_get_match_data(&pdev->dev); > > + ctx->dev = &pdev->dev; > > + > > + ctx->infra_base = of_iomap(node, 0); > > Does this mean the device is part of the infracfg block? > I wasn't able to find any information about it. I'm not sure why you would ask infracfg block. devapc is parts of our SoC infra, it's different with infracfg. > > > + if (!ctx->infra_base) > > + return -EINVAL; > > + > > + devapc_irq = irq_of_parse_and_map(node, 0); > > + if (!devapc_irq) > > + return -EINVAL; > > + > > + ctx->infra_clk = devm_clk_get(&pdev->dev, "devapc-infra-clock"); > > + if (IS_ERR(ctx->infra_clk)) > > + return -EINVAL; > > + > > + if (clk_prepare_enable(ctx->infra_clk)) > > + return -EINVAL; > > + > > + ret = devm_request_irq(&pdev->dev, devapc_irq, > > + (irq_handler_t)devapc_violation_irq, > > No cast should be needed. Okay, I'll remove it on next patch. Thanks > > > + IRQF_TRIGGER_NONE, "devapc", ctx); > > + if (ret) { > > + clk_disable_unprepare(ctx->infra_clk); > > + return ret; > > + } > > + > > + platform_set_drvdata(pdev, ctx); > > + > > + start_devapc(ctx); > > + > > + return 0; > > +} > > + > > +static int mtk_devapc_remove(struct platform_device *pdev) > > +{ > > + struct mtk_devapc_context *ctx = platform_get_drvdata(pdev); > > + > > + stop_devapc(ctx); > > + > > + clk_disable_unprepare(ctx->infra_clk); > > + > > + return 0; > > +} > > + > > +static struct platform_driver mtk_devapc_driver = { > > + .probe = mtk_devapc_probe, > > + .remove = mtk_devapc_remove, > > + .driver = { > > + .name = KBUILD_MODNAME, > > .name = "mtk-devapc", Okay, I'll add it on next patch. Thanks > > Regards, > Matthias _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.3 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3E5E2C4363D for ; Thu, 8 Oct 2020 02:35:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A858720B1F for ; Thu, 8 Oct 2020 02:35:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="RmymH21T" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728071AbgJHCf2 (ORCPT ); Wed, 7 Oct 2020 22:35:28 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:38386 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726400AbgJHCf2 (ORCPT ); Wed, 7 Oct 2020 22:35:28 -0400 X-UUID: 958e7bb231ba4636a740fa6b3a5f0275-20201008 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=eUyQWurX7TEUFvUgroyyTolSOwQdWAlsjRrM01Zvm7Q=; b=RmymH21TpPcq9m+iGBio/irwVdu3VnHnSoqCHcxCwwXnxQMPRXT5WBLGb3WmxuMch4SpH3nzx5xDtCSjZ2sOMkMkpPlv91sASRsyUmK7dl9oeLdVn3LLiU9a2ymlvCvA8iIApU9DK1NhlcOkxnaB/3aG613jYhCV6YCnanWEjcQ=; X-UUID: 958e7bb231ba4636a740fa6b3a5f0275-20201008 Received: from mtkexhb02.mediatek.inc [(172.21.101.103)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.14 Build 0819 with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1346983166; Thu, 08 Oct 2020 10:35:16 +0800 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs02n2.mediatek.inc (172.21.101.101) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 8 Oct 2020 10:35:14 +0800 Received: from [172.21.77.33] (172.21.77.33) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 8 Oct 2020 10:35:14 +0800 Message-ID: <1602124514.28301.17.camel@mtkswgap22> Subject: Re: [PATCH v7 2/2] soc: mediatek: add mt6779 devapc driver From: Neal Liu To: Matthias Brugger CC: Neal Liu , Rob Herring , Chun-Kuang Hu , , , , lkml , Date: Thu, 8 Oct 2020 10:35:14 +0800 In-Reply-To: References: <1598497593-15781-1-git-send-email-neal.liu@mediatek.com> <1598497593-15781-3-git-send-email-neal.liu@mediatek.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.2.3-0ubuntu6 MIME-Version: 1.0 X-TM-SNTS-SMTP: 9FA1AAA7491D792DC98672D1D1A0F49F3CA1AE3E773A0A3C478DB17D4AA32D362000:8 X-MTK: N Content-Transfer-Encoding: base64 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org T24gV2VkLCAyMDIwLTEwLTA3IGF0IDEyOjQ0ICswMjAwLCBNYXR0aGlhcyBCcnVnZ2VyIHdyb3Rl Og0KPiANCj4gT24gMjcvMDgvMjAyMCAwNTowNiwgTmVhbCBMaXUgd3JvdGU6DQo+ID4gTWVkaWFU ZWsgYnVzIGZhYnJpYyBwcm92aWRlcyBUcnVzdFpvbmUgc2VjdXJpdHkgc3VwcG9ydCBhbmQgZGF0 YQ0KPiA+IHByb3RlY3Rpb24gdG8gcHJldmVudCBzbGF2ZXMgZnJvbSBiZWluZyBhY2Nlc3NlZCBi eSB1bmV4cGVjdGVkDQo+ID4gbWFzdGVycy4NCj4gPiBUaGUgc2VjdXJpdHkgdmlvbGF0aW9uIGlz IGxvZ2dlZCBhbmQgc2VudCB0byB0aGUgcHJvY2Vzc29yIGZvcg0KPiA+IGZ1cnRoZXIgYW5hbHlz aXMgb3IgY291bnRlcm1lYXN1cmVzLg0KPiA+IA0KPiA+IEFueSBvY2N1cnJlbmNlIG9mIHNlY3Vy aXR5IHZpb2xhdGlvbiB3b3VsZCByYWlzZSBhbiBpbnRlcnJ1cHQsIGFuZA0KPiA+IGl0IHdpbGwg YmUgaGFuZGxlZCBieSBtdGstZGV2YXBjIGRyaXZlci4gVGhlIHZpb2xhdGlvbg0KPiA+IGluZm9y bWF0aW9uIGlzIHByaW50ZWQgaW4gb3JkZXIgdG8gZmluZCB0aGUgbXVyZGVyZXIuDQo+IA0KPiAi VGhlIHZpb2xhdGlvbiBpbmZvcm1hdGlvbiBpcyBwcmludGVkIGluIG9yZGVyIHRvIGZpbmQgdGhl IHJlc3BvbnNpYmxlIGNvbXBvbmVudC4iDQo+IA0KPiBOb2JvZHkgZ290IGFjdHVhbGx5IGtpbGxl ZCwgcmlnaHQgOikNCg0KQ29ycmVjdCAhDQo+IA0KPiA+IA0KPiA+IFNpZ25lZC1vZmYtYnk6IE5l YWwgTGl1IDxuZWFsLmxpdUBtZWRpYXRlay5jb20+DQo+ID4gLS0tDQo+ID4gICBkcml2ZXJzL3Nv Yy9tZWRpYXRlay9LY29uZmlnICAgICAgfCAgICA5ICsrDQo+ID4gICBkcml2ZXJzL3NvYy9tZWRp YXRlay9NYWtlZmlsZSAgICAgfCAgICAxICsNCj4gPiAgIGRyaXZlcnMvc29jL21lZGlhdGVrL210 ay1kZXZhcGMuYyB8ICAzMDUgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKw0K PiA+ICAgMyBmaWxlcyBjaGFuZ2VkLCAzMTUgaW5zZXJ0aW9ucygrKQ0KPiA+ICAgY3JlYXRlIG1v ZGUgMTAwNjQ0IGRyaXZlcnMvc29jL21lZGlhdGVrL210ay1kZXZhcGMuYw0KPiA+IA0KPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3NvYy9tZWRpYXRlay9LY29uZmlnIGIvZHJpdmVycy9zb2MvbWVk aWF0ZWsvS2NvbmZpZw0KPiA+IGluZGV4IDU5YTU2Y2QuLjExNzdjOTggMTAwNjQ0DQo+ID4gLS0t IGEvZHJpdmVycy9zb2MvbWVkaWF0ZWsvS2NvbmZpZw0KPiA+ICsrKyBiL2RyaXZlcnMvc29jL21l ZGlhdGVrL0tjb25maWcNCj4gPiBAQCAtMTcsNiArMTcsMTUgQEAgY29uZmlnIE1US19DTURRDQo+ ID4gICAJICB0aW1lIGxpbWl0YXRpb24sIHN1Y2ggYXMgdXBkYXRpbmcgZGlzcGxheSBjb25maWd1 cmF0aW9uIGR1cmluZyB0aGUNCj4gPiAgIAkgIHZibGFuay4NCj4gPiAgIA0KPiA+ICtjb25maWcg TVRLX0RFVkFQQw0KPiA+ICsJdHJpc3RhdGUgIk1lZGlhdGVrIERldmljZSBBUEMgU3VwcG9ydCIN Cj4gPiArCWhlbHANCj4gPiArCSAgU2F5IHllcyBoZXJlIHRvIGVuYWJsZSBzdXBwb3J0IGZvciBN ZWRpYXRlayBEZXZpY2UgQVBDIGRyaXZlci4NCj4gPiArCSAgVGhpcyBkcml2ZXIgaXMgbWFpbmx5 IHVzZWQgdG8gaGFuZGxlIHRoZSB2aW9sYXRpb24gd2hpY2ggY2F0Y2hlcw0KPiA+ICsJICB1bmV4 cGVjdGVkIHRyYW5zYWN0aW9uLg0KPiA+ICsJICBUaGUgdmlvbGF0aW9uIGluZm9ybWF0aW9uIGlz IGxvZ2dlZCBmb3IgZnVydGhlciBhbmFseXNpcyBvcg0KPiA+ICsJICBjb3VudGVybWVhc3VyZXMu DQo+ID4gKw0KPiA+ICAgY29uZmlnIE1US19JTkZSQUNGRw0KPiA+ICAgCWJvb2wgIk1lZGlhVGVr IElORlJBQ0ZHIFN1cHBvcnQiDQo+ID4gICAJc2VsZWN0IFJFR01BUA0KPiA+IGRpZmYgLS1naXQg YS9kcml2ZXJzL3NvYy9tZWRpYXRlay9NYWtlZmlsZSBiL2RyaXZlcnMvc29jL21lZGlhdGVrL01h a2VmaWxlDQo+ID4gaW5kZXggMDFmOWY4Ny4uYWJmZDRiYSAxMDA2NDQNCj4gPiAtLS0gYS9kcml2 ZXJzL3NvYy9tZWRpYXRlay9NYWtlZmlsZQ0KPiA+ICsrKyBiL2RyaXZlcnMvc29jL21lZGlhdGVr L01ha2VmaWxlDQo+ID4gQEAgLTEsNSArMSw2IEBADQo+ID4gICAjIFNQRFgtTGljZW5zZS1JZGVu dGlmaWVyOiBHUEwtMi4wLW9ubHkNCj4gPiAgIG9iai0kKENPTkZJR19NVEtfQ01EUSkgKz0gbXRr LWNtZHEtaGVscGVyLm8NCj4gPiArb2JqLSQoQ09ORklHX01US19ERVZBUEMpICs9IG10ay1kZXZh cGMubw0KPiA+ICAgb2JqLSQoQ09ORklHX01US19JTkZSQUNGRykgKz0gbXRrLWluZnJhY2ZnLm8N Cj4gPiAgIG9iai0kKENPTkZJR19NVEtfUE1JQ19XUkFQKSArPSBtdGstcG1pYy13cmFwLm8NCj4g PiAgIG9iai0kKENPTkZJR19NVEtfU0NQU1lTKSArPSBtdGstc2Nwc3lzLm8NCj4gPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9zb2MvbWVkaWF0ZWsvbXRrLWRldmFwYy5jIGIvZHJpdmVycy9zb2MvbWVk aWF0ZWsvbXRrLWRldmFwYy5jDQo+ID4gbmV3IGZpbGUgbW9kZSAxMDA2NDQNCj4gPiBpbmRleCAw MDAwMDAwLi4wYmE2MWQ3DQo+ID4gLS0tIC9kZXYvbnVsbA0KPiA+ICsrKyBiL2RyaXZlcnMvc29j L21lZGlhdGVrL210ay1kZXZhcGMuYw0KPiA+IEBAIC0wLDAgKzEsMzA1IEBADQo+ID4gKy8vIFNQ RFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wDQo+ID4gKy8qDQo+ID4gKyAqIENvcHlyaWdo dCAoQykgMjAyMCBNZWRpYVRlayBJbmMuDQo+ID4gKyAqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUg PGxpbnV4L2Nsay5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+DQo+ID4gKyNp bmNsdWRlIDxsaW51eC9pb3BvbGwuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0K PiA+ICsjaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+DQo+ID4gKyNpbmNsdWRlIDxs aW51eC9vZl9kZXZpY2UuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L29mX2lycS5oPg0KPiA+ICsj aW5jbHVkZSA8bGludXgvb2ZfYWRkcmVzcy5oPg0KPiA+ICsNCj4gPiArI2RlZmluZSBWSU9fTU9E X1RPX1JFR19JTkQobSkJKChtKSAvIDMyKQ0KPiA+ICsjZGVmaW5lIFZJT19NT0RfVE9fUkVHX09G RihtKQkoKG0pICUgMzIpDQo+ID4gKw0KPiA+ICtzdHJ1Y3QgbXRrX2RldmFwY192aW9fZGJncyB7 DQo+ID4gKwl1bmlvbiB7DQo+ID4gKwkJdTMyIHZpb19kYmcwOw0KPiA+ICsJCXN0cnVjdCB7DQo+ ID4gKwkJCXUzMiBtc3RpZDoxNjsNCj4gPiArCQkJdTMyIGRtbmlkOjY7DQo+ID4gKwkJCXUzMiB2 aW9fdzoxOw0KPiA+ICsJCQl1MzIgdmlvX3I6MTsNCj4gPiArCQkJdTMyIGFkZHJfaDo0Ow0KPiA+ ICsJCQl1MzIgcmVzdjo0Ow0KPiA+ICsJCX0gZGJnMF9iaXRzOw0KPiA+ICsJfTsNCj4gPiArDQo+ ID4gKwl1MzIgdmlvX2RiZzE7DQo+ID4gK307DQo+ID4gKw0KPiA+ICtzdHJ1Y3QgbXRrX2RldmFw Y19kYXRhIHsNCj4gPiArCXUzMiB2aW9faWR4X251bTsNCj4gPiArCXUzMiB2aW9fbWFza19vZmZz ZXQ7DQo+ID4gKwl1MzIgdmlvX3N0YV9vZmZzZXQ7DQo+ID4gKwl1MzIgdmlvX2RiZzBfb2Zmc2V0 Ow0KPiA+ICsJdTMyIHZpb19kYmcxX29mZnNldDsNCj4gPiArCXUzMiBhcGNfY29uX29mZnNldDsN Cj4gPiArCXUzMiB2aW9fc2hpZnRfc3RhX29mZnNldDsNCj4gPiArCXUzMiB2aW9fc2hpZnRfc2Vs X29mZnNldDsNCj4gPiArCXUzMiB2aW9fc2hpZnRfY29uX29mZnNldDsNCj4gPiArfTsNCj4gDQo+ IFBsZWFzZSBkZXNjcmliZSB0aGUgZmllbGRzIG9mIHRoZSBzdHJ1Y3QsIHRoYXQgd2lsbCBtYWtl IGl0IGVhc2llciB0byB1bmRlcnN0YW5kIA0KPiB0aGUgZHJpdmVyLg0KDQpPa2F5LCBJJ2xsIHRy eSB0byBhZGQgbW9yZSBkZXNjcmlwdGlvbiBhYm91dCB0aGlzIHN0cnVjdC4gTWF5IGJlIGxpa2U6 DQoNCnN0cnVjdCBtdGtfZGV2YXBjX2RhdGEgew0KCS8qIG51bWJlcnMgb2YgdmlvbGF0aW9uIGlu ZGV4ICovDQoJdTMyIHZpb19pZHhfbnVtOw0KDQoJLyogcmVnIG9mZnNldCAqLw0KCXUzMiB2aW9f bWFza19vZmZzZXQ7DQoJdTMyIHZpb19zdGFfb2Zmc2V0Ow0KCXUzMiB2aW9fZGJnMF9vZmZzZXQ7 DQoJdTMyIHZpb19kYmcxX29mZnNldDsNCgl1MzIgYXBjX2Nvbl9vZmZzZXQ7DQoJdTMyIHZpb19z aGlmdF9zdGFfb2Zmc2V0Ow0KCXUzMiB2aW9fc2hpZnRfc2VsX29mZnNldDsNCgl1MzIgdmlvX3No aWZ0X2Nvbl9vZmZzZXQ7DQp9Ow0KDQo+IA0KPiA+ICsNCj4gPiArc3RydWN0IG10a19kZXZhcGNf Y29udGV4dCB7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQo+ID4gKwl2b2lkIF9faW9tZW0g KmluZnJhX2Jhc2U7DQo+ID4gKwlzdHJ1Y3QgY2xrICppbmZyYV9jbGs7DQo+ID4gKwljb25zdCBz dHJ1Y3QgbXRrX2RldmFwY19kYXRhICpkYXRhOw0KPiA+ICt9Ow0KPiA+ICsNCj4gPiArc3RhdGlj IHZvaWQgY2xlYXJfdmlvX3N0YXR1cyhzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0ICpjdHgpDQo+ ID4gK3sNCj4gPiArCXZvaWQgX19pb21lbSAqcmVnOw0KPiA+ICsJaW50IGk7DQo+ID4gKw0KPiA+ ICsJcmVnID0gY3R4LT5pbmZyYV9iYXNlICsgY3R4LT5kYXRhLT52aW9fc3RhX29mZnNldDsNCj4g PiArDQo+ID4gKwlmb3IgKGkgPSAwOyBpIDwgVklPX01PRF9UT19SRUdfSU5EKGN0eC0+ZGF0YS0+ dmlvX2lkeF9udW0gLSAxKTsgaSsrKQ0KPiA+ICsJCXdyaXRlbChHRU5NQVNLKDMxLCAwKSwgcmVn ICsgNCAqIGkpOw0KPiA+ICsNCj4gPiArCXdyaXRlbChHRU5NQVNLKFZJT19NT0RfVE9fUkVHX09G RihjdHgtPmRhdGEtPnZpb19pZHhfbnVtIC0gMSksIDApLA0KPiA+ICsJICAgICAgIHJlZyArIDQg KiBpKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbWFza19tb2R1bGVfaXJxKHN0 cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmN0eCwgYm9vbCBtYXNrKQ0KPiA+ICt7DQo+ID4gKwl2 b2lkIF9faW9tZW0gKnJlZzsNCj4gPiArCXUzMiB2YWw7DQo+ID4gKwlpbnQgaTsNCj4gPiArDQo+ ID4gKwlyZWcgPSBjdHgtPmluZnJhX2Jhc2UgKyBjdHgtPmRhdGEtPnZpb19tYXNrX29mZnNldDsN Cj4gPiArDQo+ID4gKwlpZiAobWFzaykNCj4gPiArCQl2YWwgPSBHRU5NQVNLKDMxLCAwKTsNCj4g PiArCWVsc2UNCj4gPiArCQl2YWwgPSAwOw0KPiA+ICsNCj4gPiArCWZvciAoaSA9IDA7IGkgPCBW SU9fTU9EX1RPX1JFR19JTkQoY3R4LT5kYXRhLT52aW9faWR4X251bSAtIDEpOyBpKyspDQo+IA0K PiBEbyBJIGdldCB0aGF0IHJpZ2h0PyBXZSBoYXZlIGEgbnVtYmVyIG9mIHZpcnR1YWwgSU8gaWRl bnRpZmllci4gVGhlaXIgDQo+IGNvcnJlc3BvbmRlbmRpbmcgaW50ZXJydXB0IGFyZSBncm91cGVk IGluIDMyIGJpdCByZWdpc3RlcnMuIEFuZCB3ZSB3YW50IHRvIA0KPiBlbmFibGUvZGlzYWJsZSB0 aGVtIGJ5IHdyaXRpbmcgMCBvciAxLiBXZSBoYXZlIHRvIHRha2UgY2FyZSBvZiB0aGUgbGFzdCAN Cj4gcmVnaXN0ZXJzIGFzIGl0IGNvdWxkIGJlIHRoZSBjYXNlIHRoYXQgdmlvX2lkeF9udW0gaXMg bm90IGEgbXVsdGlwbGUgb2YgMzIsIGNvcnJlY3Q/DQo+IA0KPiBJbiB0aGlzIGNhc2Ugd2Ugc2hv dWxkIHRyYXZlcnNlIFZJT19NT0RfVE9fUkVHX0lORChjdHgtPmRhdGEtPnZpb19pZHhfbnVtKSAt IDEgDQo+IHJlZ2lzdGVycywgd2hpY2ggaXMgKHZpb19pZHhfbnVtIC8gMzIpIC0gMSBhbmQgbm90 ICh2aW9faWR4X251bSAtIDEpIC8gMzIuDQo+IA0KDQpZZXMsIHlvdXIgdW5kZXJzdGFuZGluZyBp cyBjb3JyZWN0LiBJdCBzaG91bGQgYmUNClZJT19NT0RfVE9fUkVHX0lORChjdHgtPmRhdGEtPnZp b19pZHhfbnVtKSAtIDEgaW5zdGVhZCBvZg0KVklPX01PRF9UT19SRUdfSU5EKGN0eC0+ZGF0YS0+ dmlvX2lkeF9udW0gLSAxKS4NCg0KPiA+ICsJCXdyaXRlbCh2YWwsIHJlZyArIDQgKiBpKTsNCj4g PiArDQo+ID4gKwl2YWwgPSByZWFkbChyZWcgKyA0ICogaSk7DQo+ID4gKwlpZiAobWFzaykNCj4g PiArCQl2YWwgfD0gR0VOTUFTSyhWSU9fTU9EX1RPX1JFR19PRkYoY3R4LT5kYXRhLT52aW9faWR4 X251bSAtIDEpLA0KPiA+ICsJCQkgICAgICAgMCk7DQo+IA0KPiBXZSBoYXZlIDUxMSBJUlFzLCB3 aGljaCBnaXZlcyB1cyAzMSBiaXRzIGluIHRoZSBsYXN0IHJlZ2lzdGVyIHRvIHNldC91bnNldC4g DQo+IFRoYXRzIDUxMC4uMCBiaXRzLCBzbyBmcm9tIHdoYXQgSSB1bmRlcnN0YW5kLCBvbmNlIGFn YWluIHdlIHdhbnQNCj4gR0VOTUFTSyhWSU9fTU9EX1RPX1JFR19PRkYoY3R4LT5kYXRhLT52aW9f aWR4X251bSkgLSAxLCAwKQ0KPiB3aGljaCBpcyAodmlvX2lkeF9udW0gJSAzMikgLSAxDQo+IA0K PiBDb3JyZWN0IG9yIGRvIEkgdW5kZXJzdGFuZCBzb21ldGhpbmcgd3Jvbmc/DQo+IElmIHNvLCBz YW1lIGFwcGxpZXMgdG8gY2xlYXJfdmlvX3N0YXR1cygpLg0KPiANCg0KQ29ycmVjdC4gSSdsbCBm aXggaXQgb24gbmV4dCBwYXRjaC4NClRoYW5rcw0KDQo+IA0KPiA+ICsJZWxzZQ0KPiA+ICsJCXZh bCAmPSB+R0VOTUFTSyhWSU9fTU9EX1RPX1JFR19PRkYoY3R4LT5kYXRhLT52aW9faWR4X251bSAt IDEpLA0KPiA+ICsJCQkJMCk7DQo+ID4gKw0KPiA+ICsJd3JpdGVsKHZhbCwgcmVnICsgNCAqIGkp Ow0KPiA+ICt9DQo+ID4gKw0KPiA+ICsjZGVmaW5lIFBIWV9ERVZBUENfVElNRU9VVAkweDEwMDAw DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBkZXZhcGNfc3luY192aW9fZGJnIC0gZG8gInNoaWZ0 IiBtZWNoYW5zaW0iIHRvIGdldCBmdWxsIHZpb2xhdGlvbiBpbmZvcm1hdGlvbi4NCj4gPiArICog ICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0IG1lY2hhbmlzbSBpcyBkZXBlbmRzIG9uIGRldmFw YyBoYXJkd2FyZSBkZXNpZ24uDQo+ID4gKyAqICAgICAgICAgICAgICAgICAgICAgICBNZWRpYXRl ayBkZXZhcGMgc2V0IG11bHRpcGxlIHNsYXZlcyBhcyBhIGdyb3VwLg0KPiA+ICsgKiAgICAgICAg ICAgICAgICAgICAgICAgV2hlbiB2aW9sYXRpb24gaXMgdHJpZ2dlcmVkLCB2aW9sYXRpb24gaW5m byBpcyBrZXB0DQo+ID4gKyAqICAgICAgICAgICAgICAgICAgICAgICBpbnNpZGUgZGV2YXBjIGhh cmR3YXJlLg0KPiA+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgRHJpdmVyIHNob3VsZCBkbyBz aGlmdCBtZWNoYW5zaW0gdG8gc3luYyBmdWxsIHZpb2xhdGlvbg0KPiA+ICsgKiAgICAgICAgICAg ICAgICAgICAgICAgaW5mbyB0byBWSU9fREJHcyByZWdpc3RlcnMuDQo+ID4gKyAqDQo+ID4gKyAq Lw0KPiA+ICtzdGF0aWMgaW50IGRldmFwY19zeW5jX3Zpb19kYmcoc3RydWN0IG10a19kZXZhcGNf Y29udGV4dCAqY3R4KQ0KPiA+ICt7DQo+ID4gKwl2b2lkIF9faW9tZW0gKnBkX3Zpb19zaGlmdF9z dGFfcmVnOw0KPiA+ICsJdm9pZCBfX2lvbWVtICpwZF92aW9fc2hpZnRfc2VsX3JlZzsNCj4gPiAr CXZvaWQgX19pb21lbSAqcGRfdmlvX3NoaWZ0X2Nvbl9yZWc7DQo+ID4gKwlpbnQgbWluX3NoaWZ0 X2dyb3VwOw0KPiA+ICsJaW50IHJldDsNCj4gPiArCXUzMiB2YWw7DQo+ID4gKw0KPiA+ICsJcGRf dmlvX3NoaWZ0X3N0YV9yZWcgPSBjdHgtPmluZnJhX2Jhc2UgKw0KPiA+ICsJCQkgICAgICAgY3R4 LT5kYXRhLT52aW9fc2hpZnRfc3RhX29mZnNldDsNCj4gPiArCXBkX3Zpb19zaGlmdF9zZWxfcmVn ID0gY3R4LT5pbmZyYV9iYXNlICsNCj4gPiArCQkJICAgICAgIGN0eC0+ZGF0YS0+dmlvX3NoaWZ0 X3NlbF9vZmZzZXQ7DQo+ID4gKwlwZF92aW9fc2hpZnRfY29uX3JlZyA9IGN0eC0+aW5mcmFfYmFz ZSArDQo+ID4gKwkJCSAgICAgICBjdHgtPmRhdGEtPnZpb19zaGlmdF9jb25fb2Zmc2V0Ow0KPiA+ ICsNCj4gPiArCS8qIEZpbmQgdGhlIG1pbmltdW0gc2hpZnQgZ3JvdXAgd2hpY2ggaGFzIHZpb2xh dGlvbiAqLw0KPiA+ICsJdmFsID0gcmVhZGwocGRfdmlvX3NoaWZ0X3N0YV9yZWcpOw0KPiA+ICsJ aWYgKCF2YWwpDQo+ID4gKwkJcmV0dXJuIGZhbHNlOw0KPiANCj4gU28gYml0IDAgb2Ygc2VsZWN0 aW9uIHJlZ2lzdGVyIChwZF92aW9fc2hpZnRfc2VsX3JlZykgZG9lcyBub3QgcmVwcmVzZW50IGEg DQo+IHZpb2xhdGlvbiBncm91cD8NCj4gSSBkb24ndCBrbm93IGhvdyB0aGUgSFcgd29ya3MsIGJ1 dCBpcyBzZWVtcyBvZGQgdG8gbWUuIEluIGNhc2UgdGhhdCdzIGJpdCAwIA0KPiBhY3R1YWxseSBk b2Vzbid0IHJlcHJlc2VudCBhbnl0aGluZzogaG93IGNhbiBhbiBpbnRlcnJ1cHQgYmUgdHJpZ2dl cmVkIHdpdGhvdXQgDQo+IGFueSBkZWJ1ZyBpbmZvcm1hdGlvbiBwcmVzZW50IChtZWFucyB2YWwg PT0gMCk/DQoNClRoaXMgY2hlY2sgaW1wbGllcyBIVyBzdGF0dXMgaGFzIHNvbWV0aGluZyB3cm9u Zy4gSXQgY2Fubm90IGdldCBhbnkNCmRlYnVnIGluZm9ybWF0aW9uIGZvciB0aGlzIGNhc2UuDQpJ dCB3b24ndCBoYXBwZW4gaW4gbm9ybWFsIHNjZW5hcmlvLiBTaG91bGQgd2UgcmVtb3ZlIHRoaXMg Y2hlY2s/DQoNCj4gDQo+ID4gKw0KPiA+ICsJbWluX3NoaWZ0X2dyb3VwID0gX19mZnModmFsKTsN Cj4gPiArDQo+ID4gKwkvKiBBc3NpZ24gdGhlIGdyb3VwIHRvIHN5bmMgKi8NCj4gPiArCXdyaXRl bCgweDEgPDwgbWluX3NoaWZ0X2dyb3VwLCBwZF92aW9fc2hpZnRfc2VsX3JlZyk7DQo+ID4gKw0K PiA+ICsJLyogU3RhcnQgc3luY2luZyAqLw0KPiA+ICsJd3JpdGVsKDB4MSwgcGRfdmlvX3NoaWZ0 X2Nvbl9yZWcpOw0KPiA+ICsNCj4gPiArCXJldCA9IHJlYWRsX3BvbGxfdGltZW91dChwZF92aW9f c2hpZnRfY29uX3JlZywgdmFsLCB2YWwgPT0gMHgzLCAwLA0KPiA+ICsJCQkJIFBIWV9ERVZBUENf VElNRU9VVCk7DQo+ID4gKwlpZiAocmV0KSB7DQo+ID4gKwkJZGV2X2VycihjdHgtPmRldiwgIiVz OiBTaGlmdCB2aW9sYXRpb24gaW5mbyBmYWlsZWRcbiIsIF9fZnVuY19fKTsNCj4gDQo+IEluIHdo aWNoIGNhc2UgdGhpcyBjYW4gaGFwcGVuPyBJJ20gYXNraW5nLCBiZWNhdXNlIHdlIGFyZSBjYWxs aW5nIA0KPiBkZXZhcGNfc3luY192aW9fZGJnKCkgaW4gYSB3aGlsZSBsb29wIHRoYXQgY291bGQg bWFrZSB0aGUga2VybmVsIGhhbmcgaGVyZS4NCj4gDQo+IERvIEkgdW5kZXJzdGFuZCBjb3JyZWN0 bHksIHRoYXQgd2UgYXJlIHVzaW5nIHRoZSB3aGlsZSBsb29wLCBiZWNhdXNlIHRoZXJlIGNhbiAN Cj4gYmUgbW9yZSB0aGVuIG9uZSB2aW9sYXRpb24gZ3JvdXAgd2hpY2ggZ290IHRyaWdnZXJlZCAo cmVhZCwgbW9yZSB0aGVuIG9uZSBiaXQgaXMgDQo+IHNldCBpbiBwZF92aW9fc2hpZnRfc3RhX3Jl Zyk/IFdvdWxkIGl0IG1ha2UgbW9yZSBzZW5zZSB0aGVuIHRvIHJlYWQgdGhlIHJlZ2lzdGVyIA0K PiBvbmNlIGFuZCBkbyBhbGwgdGhlIHNoaWZ0IG9wZXJhdGlvbiBmb3IgYWxsIGdyb3VwcyB3aGlj aCBiaXQgc2V0IHRvIDEgaW4gdGhlIA0KPiBzaGlmdCBzdGF0dXMgcmVnaXN0ZXI/DQoNClllcywg eW91ciB1bmRlcnN0YW5kaW5nIGlzIGNvcnJlY3QuDQpUaGlzIGNoZWNrIGFsc28gaW1wbGllcyBI VyBzdGF0dXMgaGFzIHNvbWV0aGluZyB3cm9uZy4gV2UgcmV0dXJuIGZhbHNlDQp0byBza2lwIGZ1 cnRoZXIgdmlvbGF0aW9uIGluZm8gZHVtcC4NCkhvdyBjb3VsZCB0aGlzIGNhc2UgbWFrZSB0aGUg a2VybmVsIGhhbmc/DQoNCj4gDQo+ID4gKwkJcmV0dXJuIGZhbHNlOw0KPiA+ICsJfQ0KPiA+ICsN Cj4gPiArCS8qIFN0b3Agc3luY2luZyAqLw0KPiA+ICsJd3JpdGVsKDB4MCwgcGRfdmlvX3NoaWZ0 X2Nvbl9yZWcpOw0KPiA+ICsNCj4gPiArCS8qIFdyaXRlIGNsZWFyICovDQo+ID4gKwl3cml0ZWwo MHgxIDw8IG1pbl9zaGlmdF9ncm91cCwgcGRfdmlvX3NoaWZ0X3N0YV9yZWcpOw0KPiA+ICsNCj4g PiArCXJldHVybiB0cnVlOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBkZXZhcGNf ZXh0cmFjdF92aW9fZGJnIC0gZXh0cmFjdCBmdWxsIHZpb2xhdGlvbiBpbmZvcm1hdGlvbiBhZnRl ciBkb2luZw0KPiA+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgICAgc2hpZnQgbWVjaGFuaXNt Lg0KPiA+ICsgKi8NCj4gPiArc3RhdGljIHZvaWQgZGV2YXBjX2V4dHJhY3RfdmlvX2RiZyhzdHJ1 Y3QgbXRrX2RldmFwY19jb250ZXh0ICpjdHgpDQo+ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfZGV2 YXBjX3Zpb19kYmdzIHZpb19kYmdzOw0KPiA+ICsJdm9pZCBfX2lvbWVtICp2aW9fZGJnMF9yZWc7 DQo+ID4gKwl2b2lkIF9faW9tZW0gKnZpb19kYmcxX3JlZzsNCj4gPiArDQo+ID4gKwl2aW9fZGJn MF9yZWcgPSBjdHgtPmluZnJhX2Jhc2UgKyBjdHgtPmRhdGEtPnZpb19kYmcwX29mZnNldDsNCj4g PiArCXZpb19kYmcxX3JlZyA9IGN0eC0+aW5mcmFfYmFzZSArIGN0eC0+ZGF0YS0+dmlvX2RiZzFf b2Zmc2V0Ow0KPiA+ICsNCj4gPiArCXZpb19kYmdzLnZpb19kYmcwID0gcmVhZGwodmlvX2RiZzBf cmVnKTsNCj4gPiArCXZpb19kYmdzLnZpb19kYmcxID0gcmVhZGwodmlvX2RiZzFfcmVnKTsNCj4g PiArDQo+ID4gKwkvKiBQcmludCB2aW9sYXRpb24gaW5mb3JtYXRpb24gKi8NCj4gPiArCWlmICh2 aW9fZGJncy5kYmcwX2JpdHMudmlvX3cpDQo+ID4gKwkJZGV2X2luZm8oY3R4LT5kZXYsICJXcml0 ZSBWaW9sYXRpb25cbiIpOw0KPiA+ICsJZWxzZSBpZiAodmlvX2RiZ3MuZGJnMF9iaXRzLnZpb19y KQ0KPiA+ICsJCWRldl9pbmZvKGN0eC0+ZGV2LCAiUmVhZCBWaW9sYXRpb25cbiIpOw0KPiA+ICsN Cj4gPiArCWRldl9pbmZvKGN0eC0+ZGV2LCAiQnVzIElEOjB4JXgsIERvbSBJRDoweCV4LCBWaW8g QWRkcjoweCV4XG4iLA0KPiA+ICsJCSB2aW9fZGJncy5kYmcwX2JpdHMubXN0aWQsIHZpb19kYmdz LmRiZzBfYml0cy5kbW5pZCwNCj4gPiArCQkgdmlvX2RiZ3MudmlvX2RiZzEpOw0KPiA+ICt9DQo+ ID4gKw0KPiA+ICsvKg0KPiA+ICsgKiBkZXZhcGNfdmlvbGF0aW9uX2lycSAtIHRoZSBkZXZhcGMg SW50ZXJydXB0IFNlcnZpY2UgUm91dGluZSAoSVNSKSB3aWxsIGR1bXANCj4gPiArICogICAgICAg ICAgICAgICAgICAgICAgICB2aW9sYXRpb24gaW5mb3JtYXRpb24gaW5jbHVkaW5nIHdoaWNoIG1h c3RlciB2aW9sYXRlcw0KPiA+ICsgKiAgICAgICAgICAgICAgICAgICAgICAgIGFjY2VzcyBzbGF2 ZS4NCj4gPiArICovDQo+ID4gK3N0YXRpYyBpcnFyZXR1cm5fdCBkZXZhcGNfdmlvbGF0aW9uX2ly cShpbnQgaXJxX251bWJlciwNCj4gPiArCQkJCQlzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0ICpj dHgpDQo+IA0KPiBzdGF0aWMgaXJxcmV0dXJuX3QgZGV2YXBjX3Zpb2xhdGlvbl9pcnEoaW50IGly cV9udW1iZXIsIHZvaWQgKmRhdGEpDQo+IHsNCj4gCXN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQg KmN0eCA9IGRhdGE7DQoNCk9rYXksIEknbGwgZml4IGl0IG9uIG5leHQgcGF0Y2guDQpUaGFua3MN Cg0KPiANCj4gPiArew0KPiA+ICsJd2hpbGUgKGRldmFwY19zeW5jX3Zpb19kYmcoY3R4KSkNCj4g PiArCQlkZXZhcGNfZXh0cmFjdF92aW9fZGJnKGN0eCk7DQo+ID4gKw0KPiA+ICsJY2xlYXJfdmlv X3N0YXR1cyhjdHgpOw0KPiA+ICsNCj4gPiArCXJldHVybiBJUlFfSEFORExFRDsNCj4gPiArfQ0K PiA+ICsNCj4gPiArLyoNCj4gPiArICogc3RhcnRfZGV2YXBjIC0gdW5tYXNrIHNsYXZlJ3MgaXJx IHRvIHN0YXJ0IHJlY2VpdmluZyBkZXZhcGMgdmlvbGF0aW9uLg0KPiA+ICsgKi8NCj4gPiArc3Rh dGljIHZvaWQgc3RhcnRfZGV2YXBjKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmN0eCkNCj4g PiArew0KPiA+ICsJd3JpdGVsKEJJVCgzMSksIGN0eC0+aW5mcmFfYmFzZSArIGN0eC0+ZGF0YS0+ YXBjX2Nvbl9vZmZzZXQpOw0KPiA+ICsNCj4gPiArCW1hc2tfbW9kdWxlX2lycShjdHgsIGZhbHNl KTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyoNCj4gPiArICogc3RvcF9kZXZhcGMgLSBtYXNrIHNs YXZlJ3MgaXJxIHRvIHN0b3Agc2VydmljZS4NCj4gPiArICovDQo+ID4gK3N0YXRpYyB2b2lkIHN0 b3BfZGV2YXBjKHN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmN0eCkNCj4gPiArew0KPiA+ICsJ bWFza19tb2R1bGVfaXJxKGN0eCwgdHJ1ZSk7DQo+ID4gKw0KPiA+ICsJd3JpdGVsKEJJVCgyKSwg Y3R4LT5pbmZyYV9iYXNlICsgY3R4LT5kYXRhLT5hcGNfY29uX29mZnNldCk7DQo+ID4gK30NCj4g PiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgbXRrX2RldmFwY19kYXRhIGRldmFwY19tdDY3 NzkgPSB7DQo+ID4gKwkudmlvX2lkeF9udW0gPSA1MTEsDQo+ID4gKwkudmlvX21hc2tfb2Zmc2V0 ID0gMHgwLA0KPiA+ICsJLnZpb19zdGFfb2Zmc2V0ID0gMHg0MDAsDQo+ID4gKwkudmlvX2RiZzBf b2Zmc2V0ID0gMHg5MDAsDQo+ID4gKwkudmlvX2RiZzFfb2Zmc2V0ID0gMHg5MDQsDQo+ID4gKwku YXBjX2Nvbl9vZmZzZXQgPSAweEYwMCwNCj4gPiArCS52aW9fc2hpZnRfc3RhX29mZnNldCA9IDB4 RjEwLA0KPiA+ICsJLnZpb19zaGlmdF9zZWxfb2Zmc2V0ID0gMHhGMTQsDQo+ID4gKwkudmlvX3No aWZ0X2Nvbl9vZmZzZXQgPSAweEYyMCwNCj4gPiArfTsNCj4gPiArDQo+ID4gK3N0YXRpYyBjb25z dCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIG10a19kZXZhcGNfZHRfbWF0Y2hbXSA9IHsNCj4gPiArCXsN Cj4gPiArCQkuY29tcGF0aWJsZSA9ICJtZWRpYXRlayxtdDY3NzktZGV2YXBjIiwNCj4gPiArCQku ZGF0YSA9ICZkZXZhcGNfbXQ2Nzc5LA0KPiA+ICsJfSwgew0KPiA+ICsJfSwNCj4gPiArfTsNCj4g PiArDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2RldmFwY19wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2KQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5vZGUgPSBwZGV2 LT5kZXYub2Zfbm9kZTsNCj4gPiArCXN0cnVjdCBtdGtfZGV2YXBjX2NvbnRleHQgKmN0eDsNCj4g PiArCXUzMiBkZXZhcGNfaXJxOw0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwlpZiAoSVNf RVJSKG5vZGUpKQ0KPiA+ICsJCXJldHVybiAtRU5PREVWOw0KPiA+ICsNCj4gPiArCWN0eCA9IGRl dm1fa3phbGxvYygmcGRldi0+ZGV2LCBzaXplb2YoKmN0eCksIEdGUF9LRVJORUwpOw0KPiA+ICsJ aWYgKCFjdHgpDQo+ID4gKwkJcmV0dXJuIC1FTk9NRU07DQo+ID4gKw0KPiA+ICsJY3R4LT5kYXRh ID0gb2ZfZGV2aWNlX2dldF9tYXRjaF9kYXRhKCZwZGV2LT5kZXYpOw0KPiA+ICsJY3R4LT5kZXYg PSAmcGRldi0+ZGV2Ow0KPiA+ICsNCj4gPiArCWN0eC0+aW5mcmFfYmFzZSA9IG9mX2lvbWFwKG5v ZGUsIDApOw0KPiANCj4gRG9lcyB0aGlzIG1lYW4gdGhlIGRldmljZSBpcyBwYXJ0IG9mIHRoZSBp bmZyYWNmZyBibG9jaz8NCj4gSSB3YXNuJ3QgYWJsZSB0byBmaW5kIGFueSBpbmZvcm1hdGlvbiBh Ym91dCBpdC4NCg0KSSdtIG5vdCBzdXJlIHdoeSB5b3Ugd291bGQgYXNrIGluZnJhY2ZnIGJsb2Nr LiBkZXZhcGMgaXMgcGFydHMgb2Ygb3VyDQpTb0MgaW5mcmEsIGl0J3MgZGlmZmVyZW50IHdpdGgg aW5mcmFjZmcuDQoNCj4gDQo+ID4gKwlpZiAoIWN0eC0+aW5mcmFfYmFzZSkNCj4gPiArCQlyZXR1 cm4gLUVJTlZBTDsNCj4gPiArDQo+ID4gKwlkZXZhcGNfaXJxID0gaXJxX29mX3BhcnNlX2FuZF9t YXAobm9kZSwgMCk7DQo+ID4gKwlpZiAoIWRldmFwY19pcnEpDQo+ID4gKwkJcmV0dXJuIC1FSU5W QUw7DQo+ID4gKw0KPiA+ICsJY3R4LT5pbmZyYV9jbGsgPSBkZXZtX2Nsa19nZXQoJnBkZXYtPmRl diwgImRldmFwYy1pbmZyYS1jbG9jayIpOw0KPiA+ICsJaWYgKElTX0VSUihjdHgtPmluZnJhX2Ns aykpDQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0KPiA+ICsJaWYgKGNsa19wcmVwYXJl X2VuYWJsZShjdHgtPmluZnJhX2NsaykpDQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKw0K PiA+ICsJcmV0ID0gZGV2bV9yZXF1ZXN0X2lycSgmcGRldi0+ZGV2LCBkZXZhcGNfaXJxLA0KPiA+ ICsJCQkgICAgICAgKGlycV9oYW5kbGVyX3QpZGV2YXBjX3Zpb2xhdGlvbl9pcnEsDQo+IA0KPiBO byBjYXN0IHNob3VsZCBiZSBuZWVkZWQuDQoNCk9rYXksIEknbGwgcmVtb3ZlIGl0IG9uIG5leHQg cGF0Y2guDQpUaGFua3MNCg0KPiANCj4gPiArCQkJICAgICAgIElSUUZfVFJJR0dFUl9OT05FLCAi ZGV2YXBjIiwgY3R4KTsNCj4gPiArCWlmIChyZXQpIHsNCj4gPiArCQljbGtfZGlzYWJsZV91bnBy ZXBhcmUoY3R4LT5pbmZyYV9jbGspOw0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKwl9DQo+ID4g Kw0KPiA+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgY3R4KTsNCj4gPiArDQo+ID4gKwlz dGFydF9kZXZhcGMoY3R4KTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0KPiA+ICsN Cj4gPiArc3RhdGljIGludCBtdGtfZGV2YXBjX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNl ICpwZGV2KQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2RldmFwY19jb250ZXh0ICpjdHggPSBw bGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiArDQo+ID4gKwlzdG9wX2RldmFwYyhjdHgp Ow0KPiA+ICsNCj4gPiArCWNsa19kaXNhYmxlX3VucHJlcGFyZShjdHgtPmluZnJhX2Nsayk7DQo+ ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBzdHJ1Y3Qg cGxhdGZvcm1fZHJpdmVyIG10a19kZXZhcGNfZHJpdmVyID0gew0KPiA+ICsJLnByb2JlID0gbXRr X2RldmFwY19wcm9iZSwNCj4gPiArCS5yZW1vdmUgPSBtdGtfZGV2YXBjX3JlbW92ZSwNCj4gPiAr CS5kcml2ZXIgPSB7DQo+ID4gKwkJLm5hbWUgPSBLQlVJTERfTU9ETkFNRSwNCj4gDQo+IC5uYW1l ID0gIm10ay1kZXZhcGMiLA0KDQpPa2F5LCBJJ2xsIGFkZCBpdCBvbiBuZXh0IHBhdGNoLg0KVGhh bmtzDQoNCj4gDQo+IFJlZ2FyZHMsDQo+IE1hdHRoaWFzDQoNCg==