Received: by 10.223.185.116 with SMTP id b49csp2630967wrg; Mon, 5 Mar 2018 06:18:18 -0800 (PST) X-Google-Smtp-Source: AG47ELsKB4rSCqLy+Q7Na7K6U6fgMhpWNsV5mVfvdoN7N8DFViUnyrDau47x1QERixM5mPZEa3xt X-Received: by 10.99.110.199 with SMTP id j190mr12316564pgc.404.1520259498556; Mon, 05 Mar 2018 06:18:18 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520259498; cv=none; d=google.com; s=arc-20160816; b=twq1b1RdeTNAkIshfeUmTjeEsj7L5QYYq5Cf+nAaxvqwjN22W9ndRXcO4jfGEXL9cM Uha61bbYVsXi0csLkVgeuU1Eri0CEmn70Wi8cATDGovynV+7WJffuf3zhg7nVpUDcIwy B4hzioZZ56xDV2ePFDM64/WXjT4AHNVY3QLd+S2ONgBAClOzBusPoUJwlKrEHi6Jaouk VN1FRBXwEc4H3kW9zYtzoUJKa5mPbhqkvVr2HRHeZn5MNAuuaDIzxgbcVw85csyKXRYc YkByXxj+XEbt1CL/r3eF8ZOajtuMfywOtK9jqhOwyOYXh/yqGi3U2dLDw0C7du/yNdys EpYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=fGFO1m0YRkbJwsECglReG1i9enEFpGmZE9jqO1jW8S0=; b=wBte0lHqtlP7SpgOzSu8mZ+TSPD79RTE7YGXLyNt25ASo+9+/9vuqSG1UMXP5EVGl0 yZl3o5P3fjgt6p09E5gl6CtmdZQ6wBVj9vcrVybAeoCAFFX3xd+RQXqg5yepSk7BnmQ0 wOweb2UfYkf4u5KtT44Ck2CsHSiM6akH/TOZUBNacCMId+RVw+euAQ7SH8f4lsmVPKlD Q3xyy8DWQBBE+k2WteEStJJ45hquNmH+i1rmeQE8ilWboDE8emwJRcfxL2PebVvxWivL 1u217oCrQ4NuHMeB3u/rtomN7NVmvwwD4TIio7LAHn6vWW8qOVm1YUAhF5fgNUWM1EyQ Eb7A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q7si8416009pgc.69.2018.03.05.06.18.04; Mon, 05 Mar 2018 06:18:18 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964889AbeCENRD (ORCPT + 99 others); Mon, 5 Mar 2018 08:17:03 -0500 Received: from mail.rapiddevelopmentkit.de ([217.6.246.34]:37964 "EHLO root.phytec.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932449AbeCENQs (ORCPT ); Mon, 5 Mar 2018 08:16:48 -0500 Received: from idefix.phytec.de (idefix.phytec.de [172.16.0.10]) by root.phytec.de (Postfix) with ESMTP id 2D151A00345; Mon, 5 Mar 2018 14:16:50 +0100 (CET) Received: from augenblix.phytec.de ([172.16.0.56]) by idefix.phytec.de (IBM Domino Release 9.0.1FP7) with ESMTP id 2018030514164677-65305 ; Mon, 5 Mar 2018 14:16:46 +0100 From: Daniel Schultz To: lee.jones@linaro.org, linux-kernel@vger.kernel.org Cc: w.egorov@phytec.de Subject: [PATCH 2/2] mfd: rk808: Add restart functionality Date: Mon, 5 Mar 2018 14:16:41 +0100 Message-Id: <1520255801-8557-2-git-send-email-d.schultz@phytec.de> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520255801-8557-1-git-send-email-d.schultz@phytec.de> References: <1520255801-8557-1-git-send-email-d.schultz@phytec.de> X-MIMETrack: Itemize by SMTP Server on Idefix/Phytec(Release 9.0.1FP7|August 17, 2016) at 05.03.2018 14:16:46, Serialize by Router on Idefix/Phytec(Release 9.0.1FP7|August 17, 2016) at 05.03.2018 14:16:47, Serialize complete at 05.03.2018 14:16:47 X-TNEFEvaluated: 1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When using Rockchip SoCs with rk805/808/818 PMICs, restarts are realized by setting the reset registers in the "Clock and Reset Unit". Since all three shutdown functions have almost the same code, all logic from the shutdown functions can be refactored to a new function "rk808_update_bits", which can update a register by a given address and bitmask. After that, notifier blocks and the restart functions were added to the driver. Like the shutdown function, the restart is bound to the "rockchip,system-power-controller" device tree property and can easily revoked to the software restart by removing the property. Signed-off-by: Daniel Schultz --- drivers/mfd/rk808.c | 97 ++++++++++++++++++++++++++++++----------------- include/linux/mfd/rk808.h | 1 + 2 files changed, 63 insertions(+), 35 deletions(-) diff --git a/drivers/mfd/rk808.c b/drivers/mfd/rk808.c index d138721..2c68f8c 100644 --- a/drivers/mfd/rk808.c +++ b/drivers/mfd/rk808.c @@ -27,6 +27,7 @@ #include #include #include +#include struct rk808_reg_data { int addr; @@ -369,59 +370,73 @@ static const struct regmap_irq_chip rk818_irq_chip = { static struct i2c_client *rk808_i2c_client; -static void rk805_device_shutdown(void) +static void rk808_update_bits(unsigned int reg, unsigned int bit_mask) { int ret; struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); if (!rk808) { dev_warn(&rk808_i2c_client->dev, - "have no rk805, so do nothing here\n"); + "have no %s, so do nothing here\n", + rk808->regmap_irq_chip->name); return; } ret = regmap_update_bits(rk808->regmap, - RK805_DEV_CTRL_REG, - DEV_OFF, DEV_OFF); + reg, + bit_mask, bit_mask); if (ret) - dev_err(&rk808_i2c_client->dev, "power off error!\n"); + dev_err(&rk808_i2c_client->dev, "can't write to DEVCTRL: %x!\n", + ret); } -static void rk808_device_shutdown(void) +static void rk805_device_shutdown(void) { - int ret; - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); - - if (!rk808) { - dev_warn(&rk808_i2c_client->dev, - "have no rk808, so do nothing here\n"); - return; - } + rk808_update_bits(RK805_DEV_CTRL_REG, DEV_OFF); +} +static int rk805_restart_notify(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + rk808_update_bits(RK805_DEV_CTRL_REG, DEV_OFF_RST); + return NOTIFY_DONE; +} - ret = regmap_update_bits(rk808->regmap, - RK808_DEVCTRL_REG, - DEV_OFF_RST, DEV_OFF_RST); - if (ret) - dev_err(&rk808_i2c_client->dev, "power off error!\n"); +static void rk808_device_shutdown(void) +{ + rk808_update_bits(RK808_DEVCTRL_REG, DEV_OFF_RST); +} +static int rk808_restart_notify(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + rk808_update_bits(RK808_DEVCTRL_REG, DEV_OFF); + return NOTIFY_DONE; } static void rk818_device_shutdown(void) { - int ret; - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); + rk808_update_bits(RK818_DEVCTRL_REG, DEV_OFF_RST); +} +static int rk818_restart_notify(struct notifier_block *this, + unsigned long mode, void *cmd) +{ + rk808_update_bits(RK818_DEVCTRL_REG, DEV_OFF); + return NOTIFY_DONE; +} - if (!rk808) { - dev_warn(&rk808_i2c_client->dev, - "have no rk818, so do nothing here\n"); - return; - } +static struct notifier_block rk805_restart_handler = { + .notifier_call = rk805_restart_notify, + .priority = 196, +}; - ret = regmap_update_bits(rk808->regmap, - RK818_DEVCTRL_REG, - DEV_OFF_RST, DEV_OFF_RST); - if (ret) - dev_err(&rk808_i2c_client->dev, "power off error!\n"); -} +static struct notifier_block rk808_restart_handler = { + .notifier_call = rk808_restart_notify, + .priority = 196, +}; + +static struct notifier_block rk818_restart_handler = { + .notifier_call = rk818_restart_notify, + .priority = 196, +}; static const struct of_device_id rk808_of_match[] = { { .compatible = "rockchip,rk805" }, @@ -476,6 +491,7 @@ static int rk808_probe(struct i2c_client *client, cells = rk805s; nr_cells = ARRAY_SIZE(rk805s); pm_pwroff_fn = rk805_device_shutdown; + rk808->nb = &rk805_restart_handler; break; case RK808_ID: rk808->regmap_cfg = &rk808_regmap_config; @@ -485,6 +501,7 @@ static int rk808_probe(struct i2c_client *client, cells = rk808s; nr_cells = ARRAY_SIZE(rk808s); pm_pwroff_fn = rk808_device_shutdown; + rk808->nb = &rk808_restart_handler; break; case RK818_ID: rk808->regmap_cfg = &rk818_regmap_config; @@ -494,6 +511,7 @@ static int rk808_probe(struct i2c_client *client, cells = rk818s; nr_cells = ARRAY_SIZE(rk818s); pm_pwroff_fn = rk818_device_shutdown; + rk808->nb = &rk818_restart_handler; break; default: dev_err(&client->dev, "Unsupported RK8XX ID %lu\n", @@ -546,11 +564,18 @@ static int rk808_probe(struct i2c_client *client, pm_off = of_property_read_bool(np, "rockchip,system-power-controller"); - if (pm_off && !pm_power_off) { + if (pm_off) { rk808_i2c_client = client; - pm_power_off = pm_pwroff_fn; + if (!pm_power_off) + pm_power_off = pm_pwroff_fn; + if (rk808->nb) { + ret = register_restart_handler(rk808->nb); + if (ret) + dev_err(&client->dev, + "cannot register restart handler, %d\n", + ret); + } } - return 0; err_irq: @@ -564,6 +589,8 @@ static int rk808_remove(struct i2c_client *client) regmap_del_irq_chip(client->irq, rk808->irq_data); pm_power_off = NULL; + if (rk808->nb) + unregister_restart_handler(rk808->nb); return 0; } diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index 338e0f6..9c26ca2 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -453,5 +453,6 @@ struct rk808 { long variant; const struct regmap_config *regmap_cfg; const struct regmap_irq_chip *regmap_irq_chip; + struct notifier_block *nb; }; #endif /* __LINUX_REGULATOR_RK808_H */ -- 2.7.4