From patchwork Mon Jul 29 18:39:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carlo Caione X-Patchwork-Id: 11064365 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4AC62912 for ; Mon, 29 Jul 2019 18:42:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3F9292874A for ; Mon, 29 Jul 2019 18:42:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 33F602872E; Mon, 29 Jul 2019 18:42:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 69CD7285BD for ; Mon, 29 Jul 2019 18:42:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.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: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=XBYMXCYpAhtn7vE56X6INzXtNBd/Kq4J77ZH+iDaSJ4=; b=KR7Eq5DUcWkfja nSlKQ4scsWHpa25LGJBxWH0BjlW6PdsIGScM9XQL1GJKd2h5YPlyNYzEDt1jWlS/Ba8fSQ3iIvtl5 ouqNHIZ31DTv0vnYP0+i0u0MvVLZyeU22Uvs6+HuQjvqq6aGwI5jscAbkRAu9yAO3VgI+OpavFDcz hjPKIJj7wj9IY5vFT2RmSI4k/P0YIS7c2EtbJQ28lQ8J5GR9oTN5HVb1UuyDFU41daq5Pt8EA8084 ruq9Ql0zYiIPoNqYHOuUkbJePcoHNXexcw3t2uU0tOH9KRDA5TijfysAeBDRaCDNVHO4nxBGkiIyc /Q8y9SpQacukSsSPuKeQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1hsAan-0004ns-7m; Mon, 29 Jul 2019 18:41:53 +0000 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1hsAZS-0003i6-Po for linux-arm-kernel@lists.infradead.org; Mon, 29 Jul 2019 18:40:33 +0000 Received: by mail-wr1-x443.google.com with SMTP id z1so62928690wru.13 for ; Mon, 29 Jul 2019 11:40:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=yk22Z8JHzlgEU95z+MeljHJJxoVpT6sQyqAKg9tLY5U=; b=dx5FxhTIrR+KuBI9Gf5ymUQ2/cStpTGC3wuKFN03eNuQP/BydgV7kfxJ0otUDwewq1 gtIeE+bffQGFr7ShhV2nEWrlUIcGG6s8z8Cp1JHaY0m79OkutI917g8Q0z8nYhOMqFgy cqtH+LsjsC/5mGxtI4+Nmi2WoG35Em2SPc0TvKL8Tw1zpIiMslqOMUAQre9zSOpx7zV5 PH+QVzrPOo/QQDypc0AjQSrnJvtxkzTLg620KndSj9WIvvAXJJhg08DAodrK87/dpU+h R3RLuE3Kwo0QNiyXM1RZGfH8lfnD8XQ64IXaYV80N18RbOAAkjhvfNoFAZQI4GKHjCyd IgvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=yk22Z8JHzlgEU95z+MeljHJJxoVpT6sQyqAKg9tLY5U=; b=saf7Y0+63KPvrTbVULf8sXECW24pD5E9wcxm97pWJEKn/YlREKNxCd7cEGb1gFKFYx TBF3J5KUQ84riYQLcEjdP/FL8x7yhUy9Q8HR9uaoRdsLWzT9euQpH1D84voxmGDlOdLg Iwpt0WgX9c/D33Wj4jvks0CEBXEemA/9K07eoKLVvYYFK+9Oso8Zycmn0GbOdh5QXk7x R3SUZuyBetrc8y01NbJn4PCcftIqpdo0FYQ5PSZeaHDns+fgQx8OOAtqvUHseHTRQbZ8 0nb/uy09ZpSpdCp35zxm4tmk2hl9mlrD4TnvIq7iUpaULXCY1yH/CxfaoVREX+0TzAzR IjhA== X-Gm-Message-State: APjAAAXGVZ5dkkWzJ/Dv3PzilEhZC1UceJhwsAX8edMd3OI6SqQr10o/ thy/KjgmHRHKunik5cRXn10GYQ== X-Google-Smtp-Source: APXvYqwsSAAM0wmsZsQ/D1JTKzKEW/BvIsNSYJd7FhsJtS3NmClnVADYyqPc1eSd8uBcCECLdcyi7A== X-Received: by 2002:a5d:5152:: with SMTP id u18mr124859285wrt.9.1564425629514; Mon, 29 Jul 2019 11:40:29 -0700 (PDT) Received: from localhost.localdomain ([2a00:23c4:f78c:d00:1570:f96d:dab8:76ae]) by smtp.gmail.com with ESMTPSA id g8sm60735790wmf.17.2019.07.29.11.40.28 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 29 Jul 2019 11:40:28 -0700 (PDT) From: Carlo Caione To: srinivas.kandagatla@linaro.org, khilman@baylibre.com, narmstrong@baylibre.com, robh+dt@kernel.org, tglx@linutronix.de, jbrunet@baylibre.com, linux-arm-kernel@lists.infradead.org, linux-amlogic@lists.infradead.org, devicetree@vger.kernel.org Subject: [PATCH 4/5] firmware: meson_sm: Rework driver as a proper platform driver Date: Mon, 29 Jul 2019 19:39:40 +0100 Message-Id: <20190729183941.18164-5-ccaione@baylibre.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190729183941.18164-1-ccaione@baylibre.com> References: <20190729183941.18164-1-ccaione@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190729_114030_922116_C126CF91 X-CRM114-Status: GOOD ( 22.76 ) 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: Carlo Caione Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The secure monitor driver is currently a frankenstein driver which is registered as a platform driver but its functionality goes through a global struct accessed by the consumer drivers using exported helper functions. Try to tidy up the driver moving the firmware struct into the driver data and make the consumer drivers referencing the secure-monitor using a new property in the DT. Currently only the nvmem driver is using this API so we can fix it in the same commit. Signed-off-by: Carlo Caione Reviewed-by: Jerome Brunet --- drivers/firmware/meson/meson_sm.c | 94 +++++++++++++++++-------- drivers/nvmem/meson-efuse.c | 23 +++++- include/linux/firmware/meson/meson_sm.h | 15 ++-- 3 files changed, 93 insertions(+), 39 deletions(-) diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c index 772ca6726e7b..2e36a2aa274c 100644 --- a/drivers/firmware/meson/meson_sm.c +++ b/drivers/firmware/meson/meson_sm.c @@ -54,8 +54,6 @@ struct meson_sm_firmware { void __iomem *sm_shmem_out_base; }; -static struct meson_sm_firmware fw; - static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip, unsigned int cmd_index) { @@ -90,6 +88,7 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size) /** * meson_sm_call - generic SMC32 call to the secure-monitor * + * @fw: Pointer to secure-monitor firmware * @cmd_index: Index of the SMC32 function ID * @ret: Returned value * @arg0: SMC32 Argument 0 @@ -100,15 +99,15 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size) * * Return: 0 on success, a negative value on error */ -int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, - u32 arg1, u32 arg2, u32 arg3, u32 arg4) +int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index, + u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) { u32 cmd, lret; - if (!fw.chip) + if (!fw->chip) return -ENOENT; - cmd = meson_sm_get_cmd(fw.chip, cmd_index); + cmd = meson_sm_get_cmd(fw->chip, cmd_index); if (!cmd) return -EINVAL; @@ -124,6 +123,7 @@ EXPORT_SYMBOL(meson_sm_call); /** * meson_sm_call_read - retrieve data from secure-monitor * + * @fw: Pointer to secure-monitor firmware * @buffer: Buffer to store the retrieved data * @bsize: Size of the buffer * @cmd_index: Index of the SMC32 function ID @@ -137,22 +137,23 @@ EXPORT_SYMBOL(meson_sm_call); * When 0 is returned there is no guarantee about the amount of * data read and bsize bytes are copied in buffer. */ -int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) +int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer, + unsigned int bsize, unsigned int cmd_index, u32 arg0, + u32 arg1, u32 arg2, u32 arg3, u32 arg4) { u32 size; int ret; - if (!fw.chip) + if (!fw->chip) return -ENOENT; - if (!fw.chip->cmd_shmem_out_base) + if (!fw->chip->cmd_shmem_out_base) return -EINVAL; - if (bsize > fw.chip->shmem_size) + if (bsize > fw->chip->shmem_size) return -EINVAL; - if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) + if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0) return -EINVAL; if (size > bsize) @@ -164,7 +165,7 @@ int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, size = bsize; if (buffer) - memcpy(buffer, fw.sm_shmem_out_base, size); + memcpy(buffer, fw->sm_shmem_out_base, size); return ret; } @@ -173,6 +174,7 @@ EXPORT_SYMBOL(meson_sm_call_read); /** * meson_sm_call_write - send data to secure-monitor * + * @fw: Pointer to secure-monitor firmware * @buffer: Buffer containing data to send * @size: Size of the data to send * @cmd_index: Index of the SMC32 function ID @@ -184,23 +186,24 @@ EXPORT_SYMBOL(meson_sm_call_read); * * Return: size of sent data on success, a negative value on error */ -int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index, - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4) +int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer, + unsigned int size, unsigned int cmd_index, u32 arg0, + u32 arg1, u32 arg2, u32 arg3, u32 arg4) { u32 written; - if (!fw.chip) + if (!fw->chip) return -ENOENT; - if (size > fw.chip->shmem_size) + if (size > fw->chip->shmem_size) return -EINVAL; - if (!fw.chip->cmd_shmem_in_base) + if (!fw->chip->cmd_shmem_in_base) return -EINVAL; - memcpy(fw.sm_shmem_in_base, buffer, size); + memcpy(fw->sm_shmem_in_base, buffer, size); - if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0) + if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0) return -EINVAL; if (!written) @@ -210,6 +213,24 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index, } EXPORT_SYMBOL(meson_sm_call_write); +/** + * meson_sm_get - get pointer to meson_sm_firmware structure. + * + * @sm_node: Pointer to the secure-monitor Device Tree node. + * + * Return: NULL is the secure-monitor device is not ready. + */ +struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node) +{ + struct platform_device *pdev = of_find_device_by_node(sm_node); + + if (!pdev) + return NULL; + + return platform_get_drvdata(pdev); +} +EXPORT_SYMBOL_GPL(meson_sm_get); + #define SM_CHIP_ID_LENGTH 119 #define SM_CHIP_ID_OFFSET 4 #define SM_CHIP_ID_SIZE 12 @@ -217,14 +238,18 @@ EXPORT_SYMBOL(meson_sm_call_write); static ssize_t serial_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct platform_device *pdev = to_platform_device(dev); + struct meson_sm_firmware *fw; uint8_t *id_buf; int ret; + fw = platform_get_drvdata(pdev); + id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL); if (!id_buf) return -ENOMEM; - ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID, + ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID, 0, 0, 0, 0, 0); if (ret < 0) { kfree(id_buf); @@ -268,25 +293,34 @@ static const struct of_device_id meson_sm_ids[] = { static int __init meson_sm_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; const struct meson_sm_chip *chip; + struct meson_sm_firmware *fw; + + fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL); + if (!fw) + return -ENOMEM; - chip = of_match_device(meson_sm_ids, &pdev->dev)->data; + chip = of_match_device(meson_sm_ids, dev)->data; if (chip->cmd_shmem_in_base) { - fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, - chip->shmem_size); - if (WARN_ON(!fw.sm_shmem_in_base)) + fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, + chip->shmem_size); + if (WARN_ON(!fw->sm_shmem_in_base)) goto out; } if (chip->cmd_shmem_out_base) { - fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base, - chip->shmem_size); - if (WARN_ON(!fw.sm_shmem_out_base)) + fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base, + chip->shmem_size); + if (WARN_ON(!fw->sm_shmem_out_base)) goto out_in_base; } - fw.chip = chip; + fw->chip = chip; + + platform_set_drvdata(pdev, fw); + pr_info("secure-monitor enabled\n"); if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group)) @@ -295,7 +329,7 @@ static int __init meson_sm_probe(struct platform_device *pdev) return 0; out_in_base: - iounmap(fw.sm_shmem_in_base); + iounmap(fw->sm_shmem_in_base); out: return -EINVAL; } diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c index 9924b98db772..669d20d73877 100644 --- a/drivers/nvmem/meson-efuse.c +++ b/drivers/nvmem/meson-efuse.c @@ -17,20 +17,25 @@ struct meson_efuse { struct nvmem_device *nvmem; struct nvmem_config config; + struct meson_sm_firmware *fw; struct clk *clk; }; static int meson_efuse_read(void *context, unsigned int offset, void *val, size_t bytes) { - return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset, + struct meson_efuse *efuse = context; + + return meson_sm_call_read(efuse->fw, (u8 *)val, bytes, SM_EFUSE_READ, offset, bytes, 0, 0, 0); } static int meson_efuse_write(void *context, unsigned int offset, void *val, size_t bytes) { - return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset, + struct meson_efuse *efuse = context; + + return meson_sm_call_write(efuse->fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset, bytes, 0, 0, 0); } @@ -43,6 +48,7 @@ MODULE_DEVICE_TABLE(of, meson_efuse_match); static int meson_efuse_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + struct device_node *sm_np; struct meson_efuse *efuse; unsigned int size; int ret; @@ -51,6 +57,17 @@ static int meson_efuse_probe(struct platform_device *pdev) if (!efuse) return -ENOMEM; + sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0); + if (!sm_np) { + dev_err(&pdev->dev, "no secure-monitor node\n"); + return -ENODEV; + } + + efuse->fw = meson_sm_get(sm_np); + of_node_put(sm_np); + if (!efuse->fw) + return -EPROBE_DEFER; + efuse->clk = devm_clk_get(dev, NULL); if (IS_ERR(efuse->clk)) { ret = PTR_ERR(efuse->clk); @@ -73,7 +90,7 @@ static int meson_efuse_probe(struct platform_device *pdev) return ret; } - if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) { + if (meson_sm_call(efuse->fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) { dev_err(dev, "failed to get max user"); return -EINVAL; } diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h index 7613bf7c9442..6669e2a1d5fd 100644 --- a/include/linux/firmware/meson/meson_sm.h +++ b/include/linux/firmware/meson/meson_sm.h @@ -16,11 +16,14 @@ enum { struct meson_sm_firmware; -int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, u32 arg1, - u32 arg2, u32 arg3, u32 arg4); -int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index, - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); -int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index, - u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); +int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index, + u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4); +int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer, + unsigned int b_size, unsigned int cmd_index, u32 arg0, + u32 arg1, u32 arg2, u32 arg3, u32 arg4); +int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer, + unsigned int bsize, unsigned int cmd_index, u32 arg0, + u32 arg1, u32 arg2, u32 arg3, u32 arg4); +struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node); #endif /* _MESON_SM_FW_H_ */