From patchwork Tue Sep 8 12:43:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Yan X-Patchwork-Id: 7140871 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 52C61BEEC1 for ; Tue, 8 Sep 2015 12:48:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4FBB120626 for ; Tue, 8 Sep 2015 12:48:31 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 550F720622 for ; Tue, 8 Sep 2015 12:48:30 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZZIHz-00061I-G6; Tue, 08 Sep 2015 12:46:19 +0000 Received: from regular1.263xmail.com ([211.150.99.130]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZZIHs-0005Y7-Bl; Tue, 08 Sep 2015 12:46:16 +0000 Received: from andy.yan?rock-chips.com (unknown [192.168.167.229]) by regular1.263xmail.com (Postfix) with SMTP id F19D6868D; Tue, 8 Sep 2015 20:45:31 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id D69A045E; Tue, 8 Sep 2015 20:45:29 +0800 (CST) X-RL-SENDER: andy.yan@rock-chips.com X-FST-TO: heiko@sntech.de X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: andy.yan@rock-chips.com X-UNIQUE-TAG: <10aa6733b58b7762bbfe3867256ac6a7> X-ATTACHMENT-NUM: 0 X-SENDER: yxj@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith ESMTP id 675303TD3N; Tue, 08 Sep 2015 20:45:30 +0800 (CST) From: Andy Yan To: heiko@sntech.de Subject: [PATCH] ARM: rockchip: add reboot notifier Date: Tue, 8 Sep 2015 20:43:07 +0800 Message-Id: <1441716187-29446-1-git-send-email-andy.yan@rock-chips.com> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150908_054614_674986_9E8635AD X-CRM114-Status: GOOD ( 14.02 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-rockchip@lists.infradead.org, linux@arm.linux.org.uk, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Andy Yan MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP rockchip platform have a protocol to pass the the kernel reboot mode to bootloader by some special registers when system reboot.By this way the bootloader can take different action according to the different kernel reboot mode, for example, command "reboot loader" will reboot the board to rockusb mode, this is a very convenient way to get the board to download mode. Signed-off-by: Andy Yan --- arch/arm/mach-rockchip/Makefile | 2 +- arch/arm/mach-rockchip/loader.h | 22 +++++++++ arch/arm/mach-rockchip/reboot.c | 103 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-rockchip/loader.h create mode 100644 arch/arm/mach-rockchip/reboot.c diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 5c3a9b2..cd291e3 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -1,5 +1,5 @@ CFLAGS_platsmp.o := -march=armv7-a -obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o +obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o reboot.o obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-rockchip/loader.h b/arch/arm/mach-rockchip/loader.h new file mode 100644 index 0000000..bf51baa --- /dev/null +++ b/arch/arm/mach-rockchip/loader.h @@ -0,0 +1,22 @@ +#ifndef __MACH_ROCKCHIP_LOADER_H +#define __MACH_ROCKCHIP_LOADER_H + +/*high 24 bits is tag, low 8 bits is type*/ +#define SYS_LOADER_REBOOT_FLAG 0x5242C300 + +enum { + BOOT_NORMAL = 0, /* normal boot */ + BOOT_LOADER, /* enter loader rockusb mode */ + BOOT_MASKROM, /* enter maskrom rockusb mode (not support now) */ + BOOT_RECOVER, /* enter recover */ + BOOT_NORECOVER, /* do not enter recover */ + BOOT_SECONDOS, /* boot second OS (not support now)*/ + BOOT_WIPEDATA, /* enter recover and wipe data. */ + BOOT_WIPEALL, /* enter recover and wipe all data. */ + BOOT_CHECKIMG, /* check firmware img with backup part*/ + BOOT_FASTBOOT, /* enter fast boot mode */ + BOOT_SECUREBOOT_DISABLE, + BOOT_CHARGING, /* enter charge mode */ + BOOT_MAX /* MAX VALID BOOT TYPE.*/ +}; +#endif diff --git a/arch/arm/mach-rockchip/reboot.c b/arch/arm/mach-rockchip/reboot.c new file mode 100644 index 0000000..704bc16 --- /dev/null +++ b/arch/arm/mach-rockchip/reboot.c @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "loader.h" + +#define RK3188_PMU_SYS_REG0 0x40 +#define RK3288_PMU_SYS_REG0 0x94 + +struct regmap *regmap; +int flag_reg; + +static int rockchip_get_pmu_regmap(void) +{ + struct device_node *node; + + node = of_find_node_by_path("/cpus"); + + regmap = syscon_regmap_lookup_by_phandle(node, "rockchip,pmu"); + of_node_put(node); + if (!IS_ERR(regmap)) + return 0; + + regmap = syscon_regmap_lookup_by_compatible("rockchip,rk3066-pmu"); + of_node_put(node); + if (!IS_ERR(regmap)) + return 0; + + return -ENODEV; +} + +static int rockchip_get_reboot_flag_regmap(void) +{ + int ret = rockchip_get_pmu_regmap(); + + if (ret < 0) + return ret; + + if (of_machine_is_compatible("rockchip,rk3288")) { + flag_reg = RK3288_PMU_SYS_REG0; + return 0; + } else if (of_machine_is_compatible("rockchip,rk3066a") || + of_machine_is_compatible("rockchip,rk3066b") || + of_machine_is_compatible("rockchip,rk3188")) { + flag_reg = RK3188_PMU_SYS_REG0; + return 0; + } + + return -ENODEV; +} + +static void rockchip_get_reboot_flag(const char *cmd, u32 *flag) +{ + *flag = SYS_LOADER_REBOOT_FLAG + BOOT_NORMAL; + + if (cmd) { + if (!strcmp(cmd, "loader") || !strcmp(cmd, "bootloader")) + *flag = SYS_LOADER_REBOOT_FLAG + BOOT_LOADER; + else if (!strcmp(cmd, "recovery")) + *flag = SYS_LOADER_REBOOT_FLAG + BOOT_RECOVER; + else if (!strcmp(cmd, "charge")) + *flag = SYS_LOADER_REBOOT_FLAG + BOOT_CHARGING; + } +} + +static int rockchip_reboot_notify(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + u32 flag; + + rockchip_get_reboot_flag(cmd, &flag); + regmap_write(regmap, flag_reg, flag); + + return NOTIFY_DONE; +} + +static struct notifier_block rockchip_reboot_handler = { + .notifier_call = rockchip_reboot_notify, + .priority = 150, +}; + +static int __init rockchip_reboot_init(void) +{ + int ret = 0; + + if (!rockchip_get_reboot_flag_regmap()) { + ret = register_restart_handler(&rockchip_reboot_handler); + if (ret) + pr_err("%s: cannot register reboot handler, %d\n", + __func__, ret); + } + +return ret; +} + +module_init(rockchip_reboot_init); +MODULE_AUTHOR("Andy Yan