Received: by 2002:a25:e74b:0:0:0:0:0 with SMTP id e72csp443476ybh; Sat, 18 Jul 2020 08:49:05 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw47SqHlZUz2PaJQEmzECckLswFSHVLNxaQZ+59V3tGaEVc5FG73Srw1UsJtQu/bics2Ti6 X-Received: by 2002:a05:6402:1b0e:: with SMTP id by14mr13585981edb.266.1595087344986; Sat, 18 Jul 2020 08:49:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1595087344; cv=none; d=google.com; s=arc-20160816; b=qLmd+9uBfJSbiX0O8WEfmWhh/NKPgCIUrqdu8s6CKbFYQixa8X9hT3xDiQU63XET/k 41RA3lxlI3bFIXeZ2bnNq0z8fC9VdaeQcUY1MygBatxZ7/c1PqOzQej68c7hgGjZ1DbH WPK4Edy94jd+4v70Av4vf33tpeUw+/JhVNpEV0f5d7obg5SxcQRSwMrA0hNXX38Ifh5E aQYekl4Yyzp9ERB7dl1u5U9sZGEUNcrxtCc9u3nZY1wzkYIkS0wT1A3oMMhor2sklCpN Mh5tJ0aB8fF6gRDmrJq1529eDzLPYK5igatYpDQuLdVdd/UQA0AqxUjkmMd4xuA1KbgH 0lHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=wF2HYBC3pyaIsiFQbVZi3KWFI7tTTNiCmOxKrTh4ZZU=; b=jePdn0uIgFL8wxp3KI+6gsYjsv/CIehJ2QjxrBDVv5y9tr3LMTuQhDkRgJBBy1V5u0 dsvJroJn/Z3C+zsdtsn2g2HiHFO3AA7JUaB1m+4ew4C9ZSQ424pBJOZva7cPW1eX7Lrt rbVUgS+jX2zGzOsdWBgKIkKsz/WSs5UmYnMO4zWbXTa/gjsjYynm3i/DfSFVsCb0vW3P XGe2+mGfDffqYNVDpe/56iwgne7z8FPcvGoaSk0pjwF/INXktTlg4saIDcWXGel2DRyq FpDS6dZooRMc5zDfz8iiw5Eic2Lcjoyuw5Vig0a97b/lDbNjioHPK3yg83NUoS/i+HjW 9aVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@kemnade.info header.s=20180802 header.b=jxUTTIDg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z3si7214442ejc.547.2020.07.18.08.48.42; Sat, 18 Jul 2020 08:49:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@kemnade.info header.s=20180802 header.b=jxUTTIDg; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728087AbgGRPsA (ORCPT + 99 others); Sat, 18 Jul 2020 11:48:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726155AbgGRPsA (ORCPT ); Sat, 18 Jul 2020 11:48:00 -0400 Received: from mail.andi.de1.cc (mail.andi.de1.cc [IPv6:2a01:238:4321:8900:456f:ecd6:43e:202c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 88A2FC0619D2 for ; Sat, 18 Jul 2020 08:47:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=kemnade.info; s=20180802; h=Content-Transfer-Encoding:MIME-Version: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=wF2HYBC3pyaIsiFQbVZi3KWFI7tTTNiCmOxKrTh4ZZU=; b=jxUTTIDg2wxCCqjOSk97xr8S9s fSydb+UJpuPMqS4JEfEBC/+XEprhex90WGBvs33yNKeCqL21HWdDv022rlFZFKbpvYmZIScjC0pCq lz8tOdOYzYqaHS0Xw7M7MGxQgv4wQBm39uEVF1cf9yNMdstpmsglvpS1At2sa5ZGS/1M=; Received: from p200300ccff37d4001a3da2fffebfd33a.dip0.t-ipconnect.de ([2003:cc:ff37:d400:1a3d:a2ff:febf:d33a] helo=aktux) by mail.andi.de1.cc with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1jwp46-00061M-1b; Sat, 18 Jul 2020 17:47:54 +0200 Received: from andi by aktux with local (Exim 4.92) (envelope-from ) id 1jwp45-0004vM-K8; Sat, 18 Jul 2020 17:47:53 +0200 From: Andreas Kemnade To: lee.jones@linaro.org, linux-kernel@vger.kernel.org, j.neuschaefer@gmx.net, m.felsch@pengutronix.de Cc: Andreas Kemnade Subject: [PATCH] mfd: rn5t618: Make restart handler atomic safe Date: Sat, 18 Jul 2020 17:47:37 +0200 Message-Id: <20200718154737.18886-1-andreas@kemnade.info> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Score: -1.0 (-) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The restart handler is executed during the shutdown phase which is atomic/irq-less. The i2c framework supports atomic transfers since commit 63b96983a5dd ("i2c: core: introduce callbacks for atomic transfers") to address this use case. Using i2c regmap in that situation is not allowed: [ 165.177465] [ BUG: Invalid wait context ] [ 165.181479] 5.8.0-rc3-00003-g0e9088558027-dirty #11 Not tainted [ 165.187400] ----------------------------- [ 165.191410] systemd-shutdow/1 is trying to lock: [ 165.196030] d85b4438 (rn5t618:170:(&rn5t618_regmap_config)->lock){+.+.}-{3:3}, at: regmap_update_bits_base+0x30/0x70 [ 165.206573] other info that might help us debug this: [ 165.211625] context-{4:4} [ 165.214248] 2 locks held by systemd-shutdow/1: [ 165.218691] #0: c131c47c (system_transition_mutex){+.+.}-{3:3}, at: __do_sys_reboot+0x90/0x204 [ 165.227405] #1: c131efb4 (rcu_read_lock){....}-{1:2}, at: __atomic_notifier_call_chain+0x0/0x118 [ 165.236288] stack backtrace: [ 165.239174] CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 5.8.0-rc3-00003-g0e9088558027-dirty #11 [ 165.248220] Hardware name: Freescale i.MX6 SoloLite (Device Tree) [ 165.254330] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 165.262084] [] (show_stack) from [] (dump_stack+0xe8/0x120) [ 165.269407] [] (dump_stack) from [] (__lock_acquire+0x81c/0x2ca0) [ 165.277246] [] (__lock_acquire) from [] (lock_acquire+0xe4/0x490) [ 165.285090] [] (lock_acquire) from [] (__mutex_lock+0x74/0x954) [ 165.292756] [] (__mutex_lock) from [] (mutex_lock_nested+0x1c/0x24) [ 165.300769] [] (mutex_lock_nested) from [] (regmap_update_bits_base+0x30/0x70) [ 165.309741] [] (regmap_update_bits_base) from [] (rn5t618_trigger_poweroff_sequence+0x34/0x64) [ 165.320097] [] (rn5t618_trigger_poweroff_sequence) from [] (rn5t618_restart+0xc/0x2c) [ 165.329669] [] (rn5t618_restart) from [] (notifier_call_chain+0x48/0x80) [ 165.338113] [] (notifier_call_chain) from [] (__atomic_notifier_call_chain+0x70/0x118) [ 165.347770] [] (__atomic_notifier_call_chain) from [] (atomic_notifier_call_chain+0x18/0x20) [ 165.357949] [] (atomic_notifier_call_chain) from [] (machine_restart+0x68/0x80) [ 165.367001] [] (machine_restart) from [] (__do_sys_reboot+0x11c/0x204) [ 165.375272] [] (__do_sys_reboot) from [] (ret_fast_syscall+0x0/0x28) [ 165.383364] Exception stack(0xd80a5fa8 to 0xd80a5ff0) [ 165.388420] 5fa0: 00406948 00000000 fee1dead 28121969 01234567 73299b00 [ 165.396602] 5fc0: 00406948 00000000 00000000 00000058 be91abc8 00000000 be91ab60 004056f8 [ 165.404781] 5fe0: 00000058 be91aabc b6ed4d45 b6e56746 Signed-off-by: Andreas Kemnade --- drivers/mfd/rn5t618.c | 44 ++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 6b37dd479d71..2ef61b55cd4b 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -81,7 +81,7 @@ static const struct regmap_irq_chip rc5t619_irq_chip = { .mask_invert = true, }; -static struct rn5t618 *rn5t618_pm_power_off; +static struct i2c_client *rn5t618_pm_power_off; static struct notifier_block rn5t618_restart_handler; static int rn5t618_irq_init(struct rn5t618 *rn5t618) @@ -114,13 +114,37 @@ static int rn5t618_irq_init(struct rn5t618 *rn5t618) static void rn5t618_trigger_poweroff_sequence(bool repower) { + int ret; + /* disable automatic repower-on */ - regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_REPCNT, - RN5T618_REPCNT_REPWRON, - repower ? RN5T618_REPCNT_REPWRON : 0); - /* start power-off sequence */ - regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_SLPCNT, - RN5T618_SLPCNT_SWPWROFF, RN5T618_SLPCNT_SWPWROFF); + ret = i2c_smbus_read_byte_data(rn5t618_pm_power_off, RN5T618_REPCNT); + if (ret < 0) + goto err; + + ret &= ~RN5T618_REPCNT_REPWRON; + if (repower) + ret |= RN5T618_REPCNT_REPWRON; + + ret = i2c_smbus_write_byte_data(rn5t618_pm_power_off, + RN5T618_REPCNT, (u8)ret); + if (ret < 0) + goto err; + + ret = i2c_smbus_read_byte_data(rn5t618_pm_power_off, RN5T618_SLPCNT); + if (ret < 0) + goto err; + + ret |= RN5T618_SLPCNT_SWPWROFF; + + ret = i2c_smbus_write_byte_data(rn5t618_pm_power_off, + RN5T618_SLPCNT, (u8)ret); + if (ret < 0) + goto err; + + return; + +err: + dev_alert(&rn5t618_pm_power_off->dev, "Failed to shutdown (err = %d)\n", ret); } static void rn5t618_power_off(void) @@ -193,7 +217,7 @@ static int rn5t618_i2c_probe(struct i2c_client *i2c) return ret; } - rn5t618_pm_power_off = priv; + rn5t618_pm_power_off = i2c; if (of_device_is_system_power_controller(i2c->dev.of_node)) { if (!pm_power_off) pm_power_off = rn5t618_power_off; @@ -215,9 +239,7 @@ static int rn5t618_i2c_probe(struct i2c_client *i2c) static int rn5t618_i2c_remove(struct i2c_client *i2c) { - struct rn5t618 *priv = i2c_get_clientdata(i2c); - - if (priv == rn5t618_pm_power_off) { + if (i2c == rn5t618_pm_power_off) { rn5t618_pm_power_off = NULL; pm_power_off = NULL; } -- 2.20.1