Received: by 2002:a05:6a10:5bc5:0:0:0:0 with SMTP id os5csp1874476pxb; Thu, 28 Oct 2021 11:40:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxxBcRETbl26fxKGAk0vfUu7LXzaBbcK9qtUQfFp0veskijo1X/n2oQXN1oWKlSpiqUwT7p X-Received: by 2002:a05:6402:3512:: with SMTP id b18mr8213135edd.15.1635446416271; Thu, 28 Oct 2021 11:40:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1635446416; cv=none; d=google.com; s=arc-20160816; b=S4mJYkTjs1S6Re9PcoaKi0O+Ae79UOv9S26MNSZ4zewyRO4PULuHOrvlAsoxogS/2h 02wzVJD6YCJ/ZGPVh4kVyEA4dHsY1UDxWAm9LfWTTCTBCYULA+ASM2hlxJv4XhXPmfHL G29G8A+t3VDTRTVr5JGyRBayk9/3dwdUITT8+M/5ND/Q8nxTmUiB4aIE5n2YvJ+I26hH USCyPdaYwNehoHYi0FM07I0NwZBLXilvk45uMXZs+6apv0n7qOCS6XnQiEysJWy4rsbz p9aTwPC6GscxW6sYSj9E565poEincHBFGugiVeP+pz+XWChiyuX6vPXcopCn5J38UoF3 NsSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mR7X/IRD55/2aUJkOcwQinPxIZP7fj14y1hJFj2Tov8=; b=LhffzsrjAllem0hJzP2l7aEiLnDe+4zOldr73QlraO9MW4eobyhdzKM7oaIjakmv+g aCCUpzP3goG40rZ0stdRjX573QfGvBmF1fboT9rsGLkjD3GobL6inGtbsmMO5sz53nO7 AoK4/sghuTUDJl1xPV5wiOMjtt3mx8ChkqZshpPfz8sK4kRPz4SmGDQ9V7fE3bInY826 k63q4lq+R+jMnvYGZj2H8HJwmY+bPwEPzgra6kwrBaN314riuWA/+QSJOqa5N4MC2/vc z61CiUE0egklTvYDnVHFaES4z4IVwSEQ5TlcKnbNFBUKM9GDFNkOuGF6C+u+5iw9vZ8y gBUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=oVkXietc; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id sc24si6795610ejc.355.2021.10.28.11.39.51; Thu, 28 Oct 2021 11:40:16 -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=pass header.i=@linaro.org header.s=google header.b=oVkXietc; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231335AbhJ1SiH (ORCPT + 99 others); Thu, 28 Oct 2021 14:38:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60356 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231247AbhJ1SiC (ORCPT ); Thu, 28 Oct 2021 14:38:02 -0400 Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B01CC0613B9 for ; Thu, 28 Oct 2021 11:35:35 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id 188so12310993ljj.4 for ; Thu, 28 Oct 2021 11:35:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mR7X/IRD55/2aUJkOcwQinPxIZP7fj14y1hJFj2Tov8=; b=oVkXietcdHlzO8yulojwUbd/x80sHG/nhtTKAc6pmjYT27sY4wCda/6vpvlHObluDd ykDgLQW6UCEwJ8VGPSdgfTWkA3Adr12Dpjr/IpmbN7d7WdUniwR5WAB2r2e54r5rwfb7 bt2ppMzQgd5sB1j5f9T44WLkEsaiz/Dk5D/jDpuG+8rP/ZomDZj9jn0D9K3D4QoDxL3q /MIInomGW1Bu41RWYk11/ytEjSZYN1ECtvRDNi6X8OXUgoKOSoHCK/jbWhSmdHSXslc0 ZY2cENK5q34i3ZBcOsI/yZam4UcJh9W92COXkAgaux95iZng7vewGbDybDum2uh6Vj8t aqNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mR7X/IRD55/2aUJkOcwQinPxIZP7fj14y1hJFj2Tov8=; b=PCApj6/2SNf3xeteCdwqCr87InVMCzFCB17L7hS8Ft7Gvlkq3z+oUDkehNmQhs8xg+ eWWAG4MZF1ksbNTUAOctcLceqYEvM3a5v9TBIToZ4Ji+rxSp1SCOHix/avfpWjmEydbl ogX7lStpfUVMnqoWJUn8R0ktkTEF/p/c86bQZlaQ4HGa+sT74tFFvMaWw9Yx6VUZvfky NldAi32kiY/YeyTvXcmINUqHqHOcs07fwcYb0uj0zW406TJGFF2QDBW7cxDYAHXmUd3x Cnt46JG5kKndZqlprRIrMdEpXZ+nYxYRrloOureAp7IGRfcritMRRIKYAi1SFX1Jtf1a FmOA== X-Gm-Message-State: AOAM530bK6/c6G/qI1UwUv8eWckFSnEfWdUmck7djl9pQJ09h4CiDZYr leGJ1t8CRgzfZxvBZ7CC/OsKWA== X-Received: by 2002:a2e:891a:: with SMTP id d26mr6530702lji.91.1635446133295; Thu, 28 Oct 2021 11:35:33 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id f8sm390614lfu.5.2021.10.28.11.35.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Oct 2021 11:35:32 -0700 (PDT) From: Sam Protsenko To: Wim Van Sebroeck , Guenter Roeck , Rob Herring , Krzysztof Kozlowski Cc: linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH 3/7] watchdog: s3c2410: Make reset disable optional Date: Thu, 28 Oct 2021 21:35:23 +0300 Message-Id: <20211028183527.3050-4-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211028183527.3050-1-semen.protsenko@linaro.org> References: <20211028183527.3050-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Not all SoCs have AUTOMATIC_WDT_RESET_DISABLE register, examples are Exynos850 and Exynos9. On such chips reset disable register shouldn't be accessed. Provide a way to avoid handling that register. This is done by introducing separate callbacks to driver data structure: one for reset disable register, and one for mask reset register. Now those callbacks can be checked and called only when those were set in driver data. This commit doesn't bring any functional change to existing devices, but merely provides an infrastructure for upcoming chips support. Signed-off-by: Sam Protsenko --- drivers/watchdog/s3c2410_wdt.c | 81 ++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 2395f353e52d..7c163a257d3c 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -83,6 +83,8 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default 0)"); +struct s3c2410_wdt; + /** * struct s3c2410_wdt_variant - Per-variant config data * @@ -96,6 +98,11 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to * @rst_stat_bit: Bit number in the rst_stat register indicating a watchdog * reset. * @quirks: A bitfield of quirks. + * @disable_auto_reset: If set, this function will be called to disable + * automatic setting the WDT as a reset reason in RST_STAT on CPU reset; uses + * disable_reg field. + * @mask_reset: If set, this function will be called to mask WDT reset request; + * uses mask_reset_reg and mask_bit fields. */ struct s3c2410_wdt_variant { @@ -105,6 +112,8 @@ struct s3c2410_wdt_variant { int rst_stat_reg; int rst_stat_bit; u32 quirks; + int (*disable_auto_reset)(struct s3c2410_wdt *wdt, bool mask); + int (*mask_reset)(struct s3c2410_wdt *wdt, bool mask); }; struct s3c2410_wdt { @@ -121,6 +130,9 @@ struct s3c2410_wdt { struct regmap *pmureg; }; +static int s3c2410wdt_disable_wdt_reset(struct s3c2410_wdt *wdt, bool mask); +static int s3c2410wdt_mask_wdt_reset(struct s3c2410_wdt *wdt, bool mask); + static const struct s3c2410_wdt_variant drv_data_s3c2410 = { .quirks = 0 }; @@ -138,6 +150,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos5250 = { .rst_stat_bit = 20, .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ | QUIRK_HAS_WTCLRINT_REG, + .disable_auto_reset = s3c2410wdt_disable_wdt_reset, + .mask_reset = s3c2410wdt_mask_wdt_reset, }; static const struct s3c2410_wdt_variant drv_data_exynos5420 = { @@ -148,6 +162,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { .rst_stat_bit = 9, .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ | QUIRK_HAS_WTCLRINT_REG, + .disable_auto_reset = s3c2410wdt_disable_wdt_reset, + .mask_reset = s3c2410wdt_mask_wdt_reset, }; static const struct s3c2410_wdt_variant drv_data_exynos7 = { @@ -158,6 +174,8 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { .rst_stat_bit = 23, /* A57 WDTRESET */ .quirks = QUIRK_HAS_PMU_CONFIG | QUIRK_HAS_RST_STAT \ | QUIRK_HAS_WTCLRINT_REG, + .disable_auto_reset = s3c2410wdt_disable_wdt_reset, + .mask_reset = s3c2410wdt_mask_wdt_reset, }; static const struct of_device_id s3c2410_wdt_match[] = { @@ -200,35 +218,53 @@ static inline struct s3c2410_wdt *freq_to_wdt(struct notifier_block *nb) return container_of(nb, struct s3c2410_wdt, freq_transition); } -static int s3c2410wdt_mask_and_disable_reset(struct s3c2410_wdt *wdt, bool mask) +static int s3c2410wdt_disable_wdt_reset(struct s3c2410_wdt *wdt, bool mask) { + const u32 mask_val = 1 << wdt->drv_data->mask_bit; + const u32 val = mask ? mask_val : 0; int ret; - u32 mask_val = 1 << wdt->drv_data->mask_bit; - u32 val = 0; - /* No need to do anything if no PMU CONFIG needed */ - if (!(wdt->drv_data->quirks & QUIRK_HAS_PMU_CONFIG)) - return 0; + ret = regmap_update_bits(wdt->pmureg, wdt->drv_data->disable_reg, + mask_val, val); + if (ret < 0) + dev_err(wdt->dev, "failed to update reg(%d)\n", ret); - if (mask) - val = mask_val; + return ret; +} - ret = regmap_update_bits(wdt->pmureg, - wdt->drv_data->disable_reg, - mask_val, val); - if (ret < 0) - goto error; +static int s3c2410wdt_mask_wdt_reset(struct s3c2410_wdt *wdt, bool mask) +{ + const u32 mask_val = 1 << wdt->drv_data->mask_bit; + const u32 val = mask ? mask_val : 0; + int ret; - ret = regmap_update_bits(wdt->pmureg, - wdt->drv_data->mask_reset_reg, - mask_val, val); - error: + ret = regmap_update_bits(wdt->pmureg, wdt->drv_data->mask_reset_reg, + mask_val, val); if (ret < 0) dev_err(wdt->dev, "failed to update reg(%d)\n", ret); return ret; } +static int s3c2410wdt_enable(struct s3c2410_wdt *wdt, bool en) +{ + int ret; + + if (wdt->drv_data->disable_auto_reset) { + ret = wdt->drv_data->disable_auto_reset(wdt, !en); + if (ret < 0) + return ret; + } + + if (wdt->drv_data->mask_reset) { + ret = wdt->drv_data->mask_reset(wdt, !en); + if (ret < 0) + return ret; + } + + return 0; +} + static int s3c2410wdt_keepalive(struct watchdog_device *wdd) { struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd); @@ -609,7 +645,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) if (ret) goto err_cpufreq; - ret = s3c2410wdt_mask_and_disable_reset(wdt, false); + ret = s3c2410wdt_enable(wdt, true); if (ret < 0) goto err_unregister; @@ -655,7 +691,7 @@ static int s3c2410wdt_remove(struct platform_device *dev) int ret; struct s3c2410_wdt *wdt = platform_get_drvdata(dev); - ret = s3c2410wdt_mask_and_disable_reset(wdt, true); + ret = s3c2410wdt_enable(wdt, false); if (ret < 0) return ret; @@ -672,8 +708,7 @@ static void s3c2410wdt_shutdown(struct platform_device *dev) { struct s3c2410_wdt *wdt = platform_get_drvdata(dev); - s3c2410wdt_mask_and_disable_reset(wdt, true); - + s3c2410wdt_enable(wdt, false); s3c2410wdt_stop(&wdt->wdt_device); } @@ -688,7 +723,7 @@ static int s3c2410wdt_suspend(struct device *dev) wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON); wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT); - ret = s3c2410wdt_mask_and_disable_reset(wdt, true); + ret = s3c2410wdt_enable(wdt, false); if (ret < 0) return ret; @@ -708,7 +743,7 @@ static int s3c2410wdt_resume(struct device *dev) writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); - ret = s3c2410wdt_mask_and_disable_reset(wdt, false); + ret = s3c2410wdt_enable(wdt, true); if (ret < 0) return ret; -- 2.30.2