From patchwork Tue Nov 26 05:34:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Freddy.Hsin" X-Patchwork-Id: 11261417 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C233F1390 for ; Tue, 26 Nov 2019 05:35:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9A0952071E for ; Tue, 26 Nov 2019 05:35:18 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="gbIz5wXw" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727453AbfKZFfE (ORCPT ); Tue, 26 Nov 2019 00:35:04 -0500 Received: from mailgw01.mediatek.com ([210.61.82.183]:36382 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1727385AbfKZFfD (ORCPT ); Tue, 26 Nov 2019 00:35:03 -0500 X-UUID: 61b6324a1feb49fba40e1b4ef6a12df5-20191126 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=hFL5vz7eKp6uNs/FXh/b9reSAR4W3oNkLg9bRkAq17w=; b=gbIz5wXwxQPvWbcGAuP22JA7wttL1F4kpqmsHIr88vjvGRzqGMy3RPtKzCnsJz2ZM1tzn1PMsYhRidQqCchF8OSyt+DG2Sx/e+XFwovwzOHX1HjT8pGO3+s8yesi3vVF+5asOVyh9JI4/tsc1+Kk1mh8yJgEXbpSLM7/U4i1o1k=; X-UUID: 61b6324a1feb49fba40e1b4ef6a12df5-20191126 Received: from mtkcas07.mediatek.inc [(172.21.101.84)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0809 with TLS) with ESMTP id 804266126; Tue, 26 Nov 2019 13:34:55 +0800 Received: from mtkcas08.mediatek.inc (172.21.101.126) by mtkmbs07n2.mediatek.inc (172.21.101.141) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Tue, 26 Nov 2019 13:34:45 +0800 Received: from mtkswgap22.mediatek.inc (172.21.77.33) by mtkcas08.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Tue, 26 Nov 2019 13:34:34 +0800 From: To: , , , , , , , , , , , CC: , , Freddy Hsin Subject: [PATCH v1 1/4] power: reset: add reboot mode driver Date: Tue, 26 Nov 2019 13:34:47 +0800 Message-ID: <1574746490-625-2-git-send-email-freddy.hsin@mediatek.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1574746490-625-1-git-send-email-freddy.hsin@mediatek.com> References: <1574746490-625-1-git-send-email-freddy.hsin@mediatek.com> MIME-Version: 1.0 X-MTK: N Sender: linux-watchdog-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-watchdog@vger.kernel.org From: Freddy Hsin This driver parses the reboot commands like "reboot bootloader" and "reboot recovery" to get a boot mode described in the device tree , then call the write interfae to store the boot mode in mtk RGU (reset generation unit) non-volatile register, which can be read by the bootloader after system reboot, then the bootloader can take different action according to the mode stored. Signed-off-by: Freddy Hsin --- drivers/power/reset/Kconfig | 11 ++++ drivers/power/reset/Makefile | 1 + drivers/power/reset/mtk-reboot.c | 116 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 drivers/power/reset/mtk-reboot.c diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index a564237..31fedb8 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -256,5 +256,16 @@ config NVMEM_REBOOT_MODE then the bootloader can read it and take different action according to the mode. +config MTK_REBOOT_MODE + tristate "Mediatek SoCs reset driver" + depends on OF + depends on REGMAP + select REBOOT_MODE + help + Say y here will enable reboot mode driver. This will + get reboot mode arguments and store it in RGU mapped + register, then the bootloader can read it to take different + action according to the mode. + endif diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 85da3198..2c64104 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -30,3 +30,4 @@ obj-$(CONFIG_REBOOT_MODE) += reboot-mode.o obj-$(CONFIG_SYSCON_REBOOT_MODE) += syscon-reboot-mode.o obj-$(CONFIG_POWER_RESET_SC27XX) += sc27xx-poweroff.o obj-$(CONFIG_NVMEM_REBOOT_MODE) += nvmem-reboot-mode.o +obj-$(CONFIG_MTK_REBOOT_MODE) += mtk-reboot.o diff --git a/drivers/power/reset/mtk-reboot.c b/drivers/power/reset/mtk-reboot.c new file mode 100644 index 0000000..545c427 --- /dev/null +++ b/drivers/power/reset/mtk-reboot.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 MediaTek Inc. + * Author Freddy Hsin + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct regmap_config mtk_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + +struct mtk_reboot_mode { + struct regmap *map; + struct reboot_mode_driver reboot; + u32 offset; + u32 mask; +}; + +static int mtk_reboot_mode_write(struct reboot_mode_driver *reboot, + unsigned int magic) +{ + struct mtk_reboot_mode *mtk_rbm; + int ret; + + mtk_rbm = container_of(reboot, struct mtk_reboot_mode, reboot); + + ret = regmap_update_bits(mtk_rbm->map, mtk_rbm->offset, + mtk_rbm->mask, magic); + if (ret < 0) + dev_info(reboot->dev, "update reboot mode bits failed\n"); + + return ret; +} + +static int mtk_regmap_lookup_by_phandle(struct device *dev, + struct mtk_reboot_mode *mtk_rbm) +{ + struct device_node *toprgu_np; + struct device_node *np = dev->of_node; + void __iomem *base; + + toprgu_np = of_parse_phandle(np, "regmap", 0); + + if (!of_device_is_compatible(toprgu_np, "mediatek,toprgu")) + return -EINVAL; + + base = of_iomap(toprgu_np, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + mtk_rbm->map = devm_regmap_init_mmio(dev, base, + &mtk_regmap_config); + return PTR_ERR_OR_ZERO(mtk_rbm->map); +} + +static int mtk_reboot_mode_probe(struct platform_device *pdev) +{ + int ret; + struct mtk_reboot_mode *mtk_rbm; + + mtk_rbm = devm_kzalloc(&pdev->dev, sizeof(*mtk_rbm), GFP_KERNEL); + if (!mtk_rbm) + return -ENOMEM; + + mtk_rbm->reboot.dev = &pdev->dev; + mtk_rbm->reboot.write = mtk_reboot_mode_write; + mtk_rbm->mask = 0xf; + + ret = mtk_regmap_lookup_by_phandle(&pdev->dev, mtk_rbm); + if (ret) { + dev_info(&pdev->dev, "Couldn't create the toprgu regmap\n"); + return -EINVAL; + } + + if (of_property_read_u32(pdev->dev.of_node, "offset", + &mtk_rbm->offset)) + return -EINVAL; + + of_property_read_u32(pdev->dev.of_node, "mask", &mtk_rbm->mask); + + ret = devm_reboot_mode_register(&pdev->dev, &mtk_rbm->reboot); + if (ret) + dev_info(&pdev->dev, "can't register reboot mode\n"); + + return ret; +} + +static const struct of_device_id mtk_reboot_mode_of_match[] = { + { .compatible = "toprgu-reboot-mode" }, + {} +}; +MODULE_DEVICE_TABLE(of, mtk_reboot_mode_of_match); + +static struct platform_driver mtk_reboot_mode_driver = { + .probe = mtk_reboot_mode_probe, + .driver = { + .name = "toprgu-reboot-mode", + .of_match_table = mtk_reboot_mode_of_match, + }, +}; +module_platform_driver(mtk_reboot_mode_driver); + +MODULE_AUTHOR("Freddy Hsin "); +MODULE_DESCRIPTION("Mediatek reboot mode driver"); +MODULE_LICENSE("GPL v2");