* [PATCH V10 0/3] Add watchdog DT nodes and use syscon regmap interface to configure pmu registers
@ 2013-11-27 11:50 Leela Krishna Amudala
[not found] ` <1385553010-30183-1-git-send-email-l.krishna-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Leela Krishna Amudala @ 2013-11-27 11:50 UTC (permalink / raw)
To: linux-samsung-soc, wim
Cc: dianders, kgene.kim, t.figa, devicetree, linux-watchdog, cpgs,
linux
This patchset does the following things
- Adds pmusysreg device node to exynos5.dtsi file
- Adds watchdog DT nodes to Exynos5250 and 5420
- Uses syscon regmap interface to configure pmu registers
to mask/unmask enable/disable of watchdog.
This patch set is rebased on Kgene's for-next branch and tested on SMDK5420
changes since V9:
- added descriptions to s3c2410_wdt_variant structure fields
- moved calling s3c2410wdt_mask_and_disable_reset() function above s3c2410wdt_start() call in probe
- put dev_err message back to s3c2410wdt_mask_and_disable_reset() function
(suggested by Doug Anderson <dianders@chromium.org>)
changes since V8:
- modified the patch description for the below patch
"watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu register"
- removed MODULE_ALIAS in watchdog driver
- changed dev_warn to dev_err in one failure case handling (suggested by Guenter Roeck <linux@roeck-us.net>)
- renamed variable name from pmu_config to drv_data
- changed the compatible field description in documentation file
(suggested by Tomasz Figa <t.figa@samsung.com>)
changes since V7:
- re-ordered the patches in the series
- moved pmu_config_s3c2410 structure out of ifdef CONFIG_OF
and limited only this structure to platform match table
- renamed structure name from s3c_wdt_driver_ids to s3c2410_wdt_ids
- removed exynos variants from platform match table
(suggested by Tomasz Figa <t.figa@samsung.com>)
changes since V6:
- added SoC-specific compatible value to syscon node and documented it
- given more patch description for below patch
ARM: dts: update watchdog device nodes for Exynos5250 and Exynos5420
- added platform_device_id array for watchdog devices
- selected MFD_SYSCON in Kconfig entry for watchdog
Changes since V5:
- removed status property in DT nodes
- changed the return type for the function s3c2410wdt_mask_and_disable_reset()
and handled error cases
- Handled to get driver data in non-DT cases
- Addressed comments given by Tomasz Figa <t.figa@samsung.com>
Changes since V4:
- changed the node name from pmusysreg to syscon and node label from pmu_sys_reg to pmu_syscon
- changed the property name from samsung,pmusysreg to samsung,syscon-phandle
- used regmap_update_bits instead of remap_read/regmap_write
- Addressed other comments given by Tomasz Figa <t.figa@samsung.com>
Changes since V3:
- changed the compatible strings for watchdog node
- splitted up adding pmusysreg node and made it separate patch
- Addressed comments given by Sachin Kamat <sachin.kamat@linaro.org>
Changes since V2:
- used syscon regmap interface to configure pmu registers in WDT driver
(suggested by Tomasz Figa <t.figa@samsung.com>)
Changes since V1:
- Added new compatible string for Exynos5 SoCs
- Introduced quirk mechanism to program PMU registers
- Addressed comments given by Tomasz Figa <t.figa@samsung.com>
Leela Krishna Amudala (3):
ARM: dts: Add pmu sysreg node to exynos5250 and exynos5420 dtsi files
watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu
register
ARM: dts: update watchdog device nodes for Exynos5250 and Exynos5420
.../devicetree/bindings/arm/samsung/pmu.txt | 16 ++
.../devicetree/bindings/watchdog/samsung-wdt.txt | 21 ++-
arch/arm/boot/dts/exynos5.dtsi | 7 -
arch/arm/boot/dts/exynos5250.dtsi | 11 +-
arch/arm/boot/dts/exynos5420.dtsi | 14 ++
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/s3c2410_wdt.c | 164 ++++++++++++++++++--
7 files changed, 216 insertions(+), 18 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/samsung/pmu.txt
--
1.7.10.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH V10 1/3] ARM: dts: Add pmu sysreg node to exynos5250 and exynos5420 dtsi files
[not found] ` <1385553010-30183-1-git-send-email-l.krishna-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2013-11-27 11:50 ` Leela Krishna Amudala
0 siblings, 0 replies; 5+ messages in thread
From: Leela Krishna Amudala @ 2013-11-27 11:50 UTC (permalink / raw)
To: linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
wim-IQzOog9fTRqzQB+pC5nmwQ
Cc: dianders-F7+t8E8rja9g9hUCZPvPmw, kgene.kim-Sze3O3UU22JBDgjK7y7TUQ,
t.figa-Sze3O3UU22JBDgjK7y7TUQ, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA,
cpgs-Sze3O3UU22JBDgjK7y7TUQ, linux-0h96xk9xTtrk1uMJSBkQmQ
This patch adds pmusysreg node to exynos5250 and exynos5420 dtsi files to
handle PMU register accesses in a centralized way using syscon driver
Signed-off-by: Leela Krishna Amudala <l.krishna-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Tomasz Figa <t.figa-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Reviewed-by: Doug Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
Tested-by: Doug Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
---
Documentation/devicetree/bindings/arm/samsung/pmu.txt | 16 ++++++++++++++++
arch/arm/boot/dts/exynos5250.dtsi | 5 +++++
arch/arm/boot/dts/exynos5420.dtsi | 5 +++++
3 files changed, 26 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/samsung/pmu.txt
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
new file mode 100644
index 0000000..307e727
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -0,0 +1,16 @@
+SAMSUNG Exynos SoC series PMU Registers
+
+Properties:
+ - name : should be 'syscon';
+ - compatible : should contain two values. First value must be one from following list:
+ - "samsung,exynos5250-pmu" - for Exynos5250 SoC,
+ - "samsung,exynos5420-pmu" - for Exynos5420 SoC.
+ second value must be always "syscon".
+
+ - reg : offset and length of the register set.
+
+Example :
+pmu_syscon: syscon@10040000 {
+ compatible = "samsung,exynos5250-pmu", "syscon";
+ reg = <0x10040000 0x5000>;
+};
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 9db5047..2f264ad 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -163,6 +163,11 @@
interrupts = <0 47 0>;
};
+ pmu_syscon: syscon@10040000 {
+ compatible = "samsung,exynos5250-pmu", "syscon";
+ reg = <0x10040000 0x5000>;
+ };
+
watchdog {
clocks = <&clock 336>;
clock-names = "watchdog";
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 09aa06c..06e97a7 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -310,4 +310,9 @@
clocks = <&clock 431>, <&clock 143>;
clock-names = "mixer", "sclk_hdmi";
};
+
+ pmu_syscon: syscon@10040000 {
+ compatible = "samsung,exynos5420-pmu", "syscon";
+ reg = <0x10040000 0x5000>;
+ };
};
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V10 2/3] watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu register
2013-11-27 11:50 [PATCH V10 0/3] Add watchdog DT nodes and use syscon regmap interface to configure pmu registers Leela Krishna Amudala
[not found] ` <1385553010-30183-1-git-send-email-l.krishna-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
@ 2013-11-27 11:50 ` Leela Krishna Amudala
2013-11-27 16:58 ` Guenter Roeck
2013-11-27 11:50 ` [PATCH V10 3/3] ARM: dts: update watchdog device nodes for Exynos5250 and Exynos5420 Leela Krishna Amudala
2 siblings, 1 reply; 5+ messages in thread
From: Leela Krishna Amudala @ 2013-11-27 11:50 UTC (permalink / raw)
To: linux-samsung-soc, wim
Cc: dianders, kgene.kim, t.figa, devicetree, linux-watchdog, cpgs,
linux
Add device tree support for exynos5250 and 5420 SoCs and use syscon regmap interface
to configure AUTOMATIC_WDT_RESET_DISABLE and MASK_WDT_RESET_REQUEST registers of PMU
to mask/unmask enable/disable of watchdog in probe and s2r scenarios.
Signed-off-by: Leela Krishna Amudala <l.krishna@samsung.com>
---
.../devicetree/bindings/watchdog/samsung-wdt.txt | 21 ++-
drivers/watchdog/Kconfig | 1 +
drivers/watchdog/s3c2410_wdt.c | 164 ++++++++++++++++++--
3 files changed, 176 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
index 2aa486c..cfff375 100644
--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
@@ -5,10 +5,29 @@ after a preset amount of time during which the WDT reset event has not
occurred.
Required properties:
-- compatible : should be "samsung,s3c2410-wdt"
+- compatible : should be one among the following
+ (a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs
+ (b) "samsung,exynos5250-wdt" for Exynos5250
+ (c) "samsung,exynos5420-wdt" for Exynos5420
+
- reg : base physical address of the controller and length of memory mapped
region.
- interrupts : interrupt number to the cpu.
+- samsung,syscon-phandle : reference to syscon node (This property required only
+ in case of compatible being "samsung,exynos5250-wdt" or "samsung,exynos5420-wdt".
+ In case of Exynos5250 and 5420 this property points to syscon node holding the PMU
+ base address)
Optional properties:
- timeout-sec : contains the watchdog timeout in seconds.
+
+Example:
+
+watchdog@101D0000 {
+ compatible = "samsung,exynos5250-wdt";
+ reg = <0x101D0000 0x100>;
+ interrupts = <0 42 0>;
+ clocks = <&clock 336>;
+ clock-names = "watchdog";
+ samsung,syscon-phandle = <&pmu_syscon>;
+};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 5be6e91..24738c0 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -188,6 +188,7 @@ config S3C2410_WATCHDOG
tristate "S3C2410 Watchdog"
depends on HAVE_S3C2410_WATCHDOG
select WATCHDOG_CORE
+ select MFD_SYSCON if ARCH_EXYNOS5
help
Watchdog timer block in the Samsung SoCs. This will reboot
the system when the timer expires with the watchdog enabled.
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 7d8fd04..b00b535 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -40,6 +40,8 @@
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/of.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#define S3C2410_WTCON 0x00
#define S3C2410_WTDAT 0x04
@@ -60,6 +62,10 @@
#define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
#define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
+#define WDT_DISABLE_REG_OFFSET 0x0408
+#define WDT_MASK_RESET_REG_OFFSET 0x040c
+#define QUIRK_NEEDS_PMU_CONFIG (1 << 0)
+
static bool nowayout = WATCHDOG_NOWAYOUT;
static int tmr_margin;
static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT;
@@ -83,6 +89,25 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
"0 to reboot (default 0)");
MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)");
+/**
+ * struct s3c2410_wdt_variant - Per-variant config data
+ *
+ * @disable_reg: Offset in pmureg for the register that disables the watchdog
+ * timer reset functionality.
+ * @mask_reset_reg: Offset in pmureg for the register that masks the watchdog
+ * timer reset functionality.
+ * @mask_bit: Bit number for the watchdog timer in the disable register and the
+ * mask reset register.
+ * @quirks: A bitfield of quirks.
+ */
+
+struct s3c2410_wdt_variant {
+ int disable_reg;
+ int mask_reset_reg;
+ int mask_bit;
+ u32 quirks;
+};
+
struct s3c2410_wdt {
struct device *dev;
struct clk *clock;
@@ -93,8 +118,50 @@ struct s3c2410_wdt {
unsigned long wtdat_save;
struct watchdog_device wdt_device;
struct notifier_block freq_transition;
+ struct s3c2410_wdt_variant *drv_data;
+ struct regmap *pmureg;
+};
+
+static const struct s3c2410_wdt_variant drv_data_s3c2410 = {
+ .quirks = 0
+};
+
+#ifdef CONFIG_OF
+static const struct s3c2410_wdt_variant drv_data_exynos5250 = {
+ .disable_reg = WDT_DISABLE_REG_OFFSET,
+ .mask_reset_reg = WDT_MASK_RESET_REG_OFFSET,
+ .mask_bit = 20,
+ .quirks = QUIRK_NEEDS_PMU_CONFIG
+};
+
+static const struct s3c2410_wdt_variant drv_data_exynos5420 = {
+ .disable_reg = WDT_DISABLE_REG_OFFSET,
+ .mask_reset_reg = WDT_MASK_RESET_REG_OFFSET,
+ .mask_bit = 0,
+ .quirks = QUIRK_NEEDS_PMU_CONFIG
};
+static const struct of_device_id s3c2410_wdt_match[] = {
+ { .compatible = "samsung,s3c2410-wdt",
+ .data = &drv_data_s3c2410 },
+ { .compatible = "samsung,exynos5250-wdt",
+ .data = &drv_data_exynos5250 },
+ { .compatible = "samsung,exynos5420-wdt",
+ .data = &drv_data_exynos5420 },
+ {},
+};
+MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
+#endif
+
+static const struct platform_device_id s3c2410_wdt_ids[] = {
+ {
+ .name = "s3c2410-wdt",
+ .driver_data = (unsigned long)&drv_data_s3c2410,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(platform, s3c2410_wdt_ids);
+
/* watchdog control routines */
#define DBG(fmt, ...) \
@@ -110,6 +177,32 @@ 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)
+{
+ int ret;
+ u32 mask_val = 1 << wdt->drv_data->mask_bit;
+ u32 val = 0;
+
+ if (mask)
+ val = mask_val;
+
+ 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);
+ return ret;
+ }
+
+ 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_keepalive(struct watchdog_device *wdd)
{
struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd);
@@ -331,6 +424,20 @@ static inline void s3c2410wdt_cpufreq_deregister(struct s3c2410_wdt *wdt)
}
#endif
+/* s3c2410_get_wdt_driver_data */
+static inline struct s3c2410_wdt_variant *
+get_wdt_drv_data(struct platform_device *pdev)
+{
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(s3c2410_wdt_match, pdev->dev.of_node);
+ return (struct s3c2410_wdt_variant *)match->data;
+ } else {
+ return (struct s3c2410_wdt_variant *)
+ platform_get_device_id(pdev)->driver_data;
+ }
+}
+
static int s3c2410wdt_probe(struct platform_device *pdev)
{
struct device *dev;
@@ -353,6 +460,16 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
spin_lock_init(&wdt->lock);
wdt->wdt_device = s3c2410_wdd;
+ wdt->drv_data = get_wdt_drv_data(pdev);
+ if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
+ wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "samsung,syscon-phandle");
+ if (IS_ERR(wdt->pmureg)) {
+ dev_err(dev, "syscon regmap lookup failed.\n");
+ return PTR_ERR(wdt->pmureg);
+ }
+ }
+
wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (wdt_irq == NULL) {
dev_err(dev, "no irq resource specified\n");
@@ -421,6 +538,12 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
goto err_cpufreq;
}
+ if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
+ ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
+ if (ret < 0)
+ goto err_unregister;
+ }
+
if (tmr_atboot && started == 0) {
dev_info(dev, "starting watchdog timer\n");
s3c2410wdt_start(&wdt->wdt_device);
@@ -445,6 +568,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
return 0;
+ err_unregister:
+ watchdog_unregister_device(&wdt->wdt_device);
+
err_cpufreq:
s3c2410wdt_cpufreq_deregister(wdt);
@@ -458,8 +584,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
static int s3c2410wdt_remove(struct platform_device *dev)
{
+ int ret;
struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
+ if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
+ ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
+ if (ret < 0)
+ return ret;
+ }
+
watchdog_unregister_device(&wdt->wdt_device);
s3c2410wdt_cpufreq_deregister(wdt);
@@ -472,8 +605,15 @@ static int s3c2410wdt_remove(struct platform_device *dev)
static void s3c2410wdt_shutdown(struct platform_device *dev)
{
+ int ret;
struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
+ if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
+ ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
+ if (ret < 0)
+ dev_warn(wdt->dev, "failed to update pmu register");
+ }
+
s3c2410wdt_stop(&wdt->wdt_device);
}
@@ -481,12 +621,19 @@ static void s3c2410wdt_shutdown(struct platform_device *dev)
static int s3c2410wdt_suspend(struct device *dev)
{
+ int ret;
struct s3c2410_wdt *wdt = dev_get_drvdata(dev);
/* Save watchdog state, and turn it off. */
wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON);
wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT);
+ if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
+ ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
+ if (ret < 0)
+ return ret;
+ }
+
/* Note that WTCNT doesn't need to be saved. */
s3c2410wdt_stop(&wdt->wdt_device);
@@ -495,6 +642,7 @@ static int s3c2410wdt_suspend(struct device *dev)
static int s3c2410wdt_resume(struct device *dev)
{
+ int ret;
struct s3c2410_wdt *wdt = dev_get_drvdata(dev);
/* Restore watchdog state. */
@@ -502,6 +650,12 @@ 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);
+ if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
+ ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
+ if (ret < 0)
+ return ret;
+ }
+
dev_info(dev, "watchdog %sabled\n",
(wdt->wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
@@ -512,18 +666,11 @@ static int s3c2410wdt_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend,
s3c2410wdt_resume);
-#ifdef CONFIG_OF
-static const struct of_device_id s3c2410_wdt_match[] = {
- { .compatible = "samsung,s3c2410-wdt" },
- {},
-};
-MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
-#endif
-
static struct platform_driver s3c2410wdt_driver = {
.probe = s3c2410wdt_probe,
.remove = s3c2410wdt_remove,
.shutdown = s3c2410wdt_shutdown,
+ .id_table = s3c2410_wdt_ids,
.driver = {
.owner = THIS_MODULE,
.name = "s3c2410-wdt",
@@ -538,4 +685,3 @@ MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, "
"Dimitry Andric <dimitry.andric@tomtom.com>");
MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:s3c2410-wdt");
--
1.7.10.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH V10 3/3] ARM: dts: update watchdog device nodes for Exynos5250 and Exynos5420
2013-11-27 11:50 [PATCH V10 0/3] Add watchdog DT nodes and use syscon regmap interface to configure pmu registers Leela Krishna Amudala
[not found] ` <1385553010-30183-1-git-send-email-l.krishna-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-11-27 11:50 ` [PATCH V10 2/3] watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu register Leela Krishna Amudala
@ 2013-11-27 11:50 ` Leela Krishna Amudala
2 siblings, 0 replies; 5+ messages in thread
From: Leela Krishna Amudala @ 2013-11-27 11:50 UTC (permalink / raw)
To: linux-samsung-soc, wim
Cc: dianders, kgene.kim, t.figa, devicetree, linux-watchdog, cpgs,
linux
In Exynos5 series SoCs, PMU has registers to enable/disable mask/unmask
watchdog timer which is not the case with s3c series SoCs so, there is a
need to have different compatible names for watchdog to handle these pmu
registers access.
Hence this patch removes watchdog node from Exynos5.dtsi common file and
make it separate by updating existing node in Exynos5250 and adding new node
to Exynos5420. This patch also makes the watchdog node enabled by default
Signed-off-by: Leela Krishna Amudala <l.krishna@samsung.com>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Tested-by: Doug Anderson <dianders@chromium.org>
---
arch/arm/boot/dts/exynos5.dtsi | 7 -------
arch/arm/boot/dts/exynos5250.dtsi | 6 +++++-
arch/arm/boot/dts/exynos5420.dtsi | 9 +++++++++
3 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi
index 074739d..de6a606 100644
--- a/arch/arm/boot/dts/exynos5.dtsi
+++ b/arch/arm/boot/dts/exynos5.dtsi
@@ -102,13 +102,6 @@
status = "disabled";
};
- watchdog {
- compatible = "samsung,s3c2410-wdt";
- reg = <0x101D0000 0x100>;
- interrupts = <0 42 0>;
- status = "disabled";
- };
-
fimd@14400000 {
compatible = "samsung,exynos5250-fimd";
interrupt-parent = <&combiner>;
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 2f264ad..54df046 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -168,9 +168,13 @@
reg = <0x10040000 0x5000>;
};
- watchdog {
+ watchdog@101D0000 {
+ compatible = "samsung,exynos5250-wdt";
+ reg = <0x101D0000 0x100>;
+ interrupts = <0 42 0>;
clocks = <&clock 336>;
clock-names = "watchdog";
+ samsung,syscon-phandle = <&pmu_syscon>;
};
g2d@10850000 {
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index 06e97a7..f5a0076 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -315,4 +315,13 @@
compatible = "samsung,exynos5420-pmu", "syscon";
reg = <0x10040000 0x5000>;
};
+
+ watchdog@101D0000 {
+ compatible = "samsung,exynos5420-wdt";
+ reg = <0x101D0000 0x100>;
+ interrupts = <0 42 0>;
+ clocks = <&clock 316>;
+ clock-names = "watchdog";
+ samsung,syscon-phandle = <&pmu_syscon>;
+ };
};
--
1.7.10.4
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH V10 2/3] watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu register
2013-11-27 11:50 ` [PATCH V10 2/3] watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu register Leela Krishna Amudala
@ 2013-11-27 16:58 ` Guenter Roeck
0 siblings, 0 replies; 5+ messages in thread
From: Guenter Roeck @ 2013-11-27 16:58 UTC (permalink / raw)
To: Leela Krishna Amudala, linux-samsung-soc, wim
Cc: dianders, kgene.kim, t.figa, devicetree, linux-watchdog, cpgs
On 11/27/2013 03:50 AM, Leela Krishna Amudala wrote:
> Add device tree support for exynos5250 and 5420 SoCs and use syscon regmap interface
> to configure AUTOMATIC_WDT_RESET_DISABLE and MASK_WDT_RESET_REQUEST registers of PMU
> to mask/unmask enable/disable of watchdog in probe and s2r scenarios.
>
> Signed-off-by: Leela Krishna Amudala <l.krishna@samsung.com>
> ---
> .../devicetree/bindings/watchdog/samsung-wdt.txt | 21 ++-
> drivers/watchdog/Kconfig | 1 +
> drivers/watchdog/s3c2410_wdt.c | 164 ++++++++++++++++++--
> 3 files changed, 176 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
> index 2aa486c..cfff375 100644
> --- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
> +++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.txt
> @@ -5,10 +5,29 @@ after a preset amount of time during which the WDT reset event has not
> occurred.
>
> Required properties:
> -- compatible : should be "samsung,s3c2410-wdt"
> +- compatible : should be one among the following
> + (a) "samsung,s3c2410-wdt" for Exynos4 and previous SoCs
> + (b) "samsung,exynos5250-wdt" for Exynos5250
> + (c) "samsung,exynos5420-wdt" for Exynos5420
> +
> - reg : base physical address of the controller and length of memory mapped
> region.
> - interrupts : interrupt number to the cpu.
> +- samsung,syscon-phandle : reference to syscon node (This property required only
> + in case of compatible being "samsung,exynos5250-wdt" or "samsung,exynos5420-wdt".
> + In case of Exynos5250 and 5420 this property points to syscon node holding the PMU
> + base address)
>
> Optional properties:
> - timeout-sec : contains the watchdog timeout in seconds.
> +
> +Example:
> +
> +watchdog@101D0000 {
> + compatible = "samsung,exynos5250-wdt";
> + reg = <0x101D0000 0x100>;
> + interrupts = <0 42 0>;
> + clocks = <&clock 336>;
> + clock-names = "watchdog";
> + samsung,syscon-phandle = <&pmu_syscon>;
> +};
> diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
> index 5be6e91..24738c0 100644
> --- a/drivers/watchdog/Kconfig
> +++ b/drivers/watchdog/Kconfig
> @@ -188,6 +188,7 @@ config S3C2410_WATCHDOG
> tristate "S3C2410 Watchdog"
> depends on HAVE_S3C2410_WATCHDOG
> select WATCHDOG_CORE
> + select MFD_SYSCON if ARCH_EXYNOS5
> help
> Watchdog timer block in the Samsung SoCs. This will reboot
> the system when the timer expires with the watchdog enabled.
> diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
> index 7d8fd04..b00b535 100644
> --- a/drivers/watchdog/s3c2410_wdt.c
> +++ b/drivers/watchdog/s3c2410_wdt.c
> @@ -40,6 +40,8 @@
> #include <linux/slab.h>
> #include <linux/err.h>
> #include <linux/of.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/regmap.h>
>
> #define S3C2410_WTCON 0x00
> #define S3C2410_WTDAT 0x04
> @@ -60,6 +62,10 @@
> #define CONFIG_S3C2410_WATCHDOG_ATBOOT (0)
> #define CONFIG_S3C2410_WATCHDOG_DEFAULT_TIME (15)
>
> +#define WDT_DISABLE_REG_OFFSET 0x0408
> +#define WDT_MASK_RESET_REG_OFFSET 0x040c
> +#define QUIRK_NEEDS_PMU_CONFIG (1 << 0)
> +
> static bool nowayout = WATCHDOG_NOWAYOUT;
> static int tmr_margin;
> static int tmr_atboot = CONFIG_S3C2410_WATCHDOG_ATBOOT;
> @@ -83,6 +89,25 @@ MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, "
> "0 to reboot (default 0)");
> MODULE_PARM_DESC(debug, "Watchdog debug, set to >1 for debug (default 0)");
>
> +/**
> + * struct s3c2410_wdt_variant - Per-variant config data
> + *
> + * @disable_reg: Offset in pmureg for the register that disables the watchdog
> + * timer reset functionality.
> + * @mask_reset_reg: Offset in pmureg for the register that masks the watchdog
> + * timer reset functionality.
> + * @mask_bit: Bit number for the watchdog timer in the disable register and the
> + * mask reset register.
> + * @quirks: A bitfield of quirks.
> + */
> +
> +struct s3c2410_wdt_variant {
> + int disable_reg;
> + int mask_reset_reg;
> + int mask_bit;
> + u32 quirks;
> +};
> +
> struct s3c2410_wdt {
> struct device *dev;
> struct clk *clock;
> @@ -93,8 +118,50 @@ struct s3c2410_wdt {
> unsigned long wtdat_save;
> struct watchdog_device wdt_device;
> struct notifier_block freq_transition;
> + struct s3c2410_wdt_variant *drv_data;
> + struct regmap *pmureg;
> +};
> +
> +static const struct s3c2410_wdt_variant drv_data_s3c2410 = {
> + .quirks = 0
> +};
> +
> +#ifdef CONFIG_OF
> +static const struct s3c2410_wdt_variant drv_data_exynos5250 = {
> + .disable_reg = WDT_DISABLE_REG_OFFSET,
> + .mask_reset_reg = WDT_MASK_RESET_REG_OFFSET,
> + .mask_bit = 20,
> + .quirks = QUIRK_NEEDS_PMU_CONFIG
> +};
> +
> +static const struct s3c2410_wdt_variant drv_data_exynos5420 = {
> + .disable_reg = WDT_DISABLE_REG_OFFSET,
> + .mask_reset_reg = WDT_MASK_RESET_REG_OFFSET,
> + .mask_bit = 0,
> + .quirks = QUIRK_NEEDS_PMU_CONFIG
> };
>
> +static const struct of_device_id s3c2410_wdt_match[] = {
> + { .compatible = "samsung,s3c2410-wdt",
> + .data = &drv_data_s3c2410 },
> + { .compatible = "samsung,exynos5250-wdt",
> + .data = &drv_data_exynos5250 },
> + { .compatible = "samsung,exynos5420-wdt",
> + .data = &drv_data_exynos5420 },
> + {},
> +};
> +MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
> +#endif
> +
> +static const struct platform_device_id s3c2410_wdt_ids[] = {
> + {
> + .name = "s3c2410-wdt",
> + .driver_data = (unsigned long)&drv_data_s3c2410,
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(platform, s3c2410_wdt_ids);
> +
> /* watchdog control routines */
>
> #define DBG(fmt, ...) \
> @@ -110,6 +177,32 @@ 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)
> +{
> + int ret;
> + u32 mask_val = 1 << wdt->drv_data->mask_bit;
> + u32 val = 0;
> +
> + if (mask)
> + val = mask_val;
> +
> + 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);
> + return ret;
> + }
> +
Since you are now doing something in the error handler,
you might want to follow coding style rules:
if (ret < 0)
goto error;
> + ret = regmap_update_bits(wdt->pmureg,
> + wdt->drv_data->mask_reset_reg,
> + mask_val, val);
error:
> + if (ret < 0)
> + dev_err(wdt->dev, "failed to update reg(%d)\n", ret);
> +
> + return ret;
> +}
> +
> static int s3c2410wdt_keepalive(struct watchdog_device *wdd)
> {
> struct s3c2410_wdt *wdt = watchdog_get_drvdata(wdd);
> @@ -331,6 +424,20 @@ static inline void s3c2410wdt_cpufreq_deregister(struct s3c2410_wdt *wdt)
> }
> #endif
>
> +/* s3c2410_get_wdt_driver_data */
> +static inline struct s3c2410_wdt_variant *
> +get_wdt_drv_data(struct platform_device *pdev)
> +{
> + if (pdev->dev.of_node) {
> + const struct of_device_id *match;
> + match = of_match_node(s3c2410_wdt_match, pdev->dev.of_node);
> + return (struct s3c2410_wdt_variant *)match->data;
> + } else {
> + return (struct s3c2410_wdt_variant *)
> + platform_get_device_id(pdev)->driver_data;
> + }
> +}
> +
> static int s3c2410wdt_probe(struct platform_device *pdev)
> {
> struct device *dev;
> @@ -353,6 +460,16 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
> spin_lock_init(&wdt->lock);
> wdt->wdt_device = s3c2410_wdd;
>
> + wdt->drv_data = get_wdt_drv_data(pdev);
> + if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
> + wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node,
> + "samsung,syscon-phandle");
> + if (IS_ERR(wdt->pmureg)) {
> + dev_err(dev, "syscon regmap lookup failed.\n");
> + return PTR_ERR(wdt->pmureg);
> + }
> + }
> +
> wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> if (wdt_irq == NULL) {
> dev_err(dev, "no irq resource specified\n");
> @@ -421,6 +538,12 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
> goto err_cpufreq;
> }
>
> + if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
> + ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
> + if (ret < 0)
> + goto err_unregister;
> + }
> +
> if (tmr_atboot && started == 0) {
> dev_info(dev, "starting watchdog timer\n");
> s3c2410wdt_start(&wdt->wdt_device);
> @@ -445,6 +568,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
>
> return 0;
>
> + err_unregister:
> + watchdog_unregister_device(&wdt->wdt_device);
> +
> err_cpufreq:
> s3c2410wdt_cpufreq_deregister(wdt);
>
> @@ -458,8 +584,15 @@ static int s3c2410wdt_probe(struct platform_device *pdev)
>
> static int s3c2410wdt_remove(struct platform_device *dev)
> {
> + int ret;
> struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
>
> + if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
> + ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
> + if (ret < 0)
> + return ret;
> + }
> +
> watchdog_unregister_device(&wdt->wdt_device);
>
> s3c2410wdt_cpufreq_deregister(wdt);
> @@ -472,8 +605,15 @@ static int s3c2410wdt_remove(struct platform_device *dev)
>
> static void s3c2410wdt_shutdown(struct platform_device *dev)
> {
> + int ret;
> struct s3c2410_wdt *wdt = platform_get_drvdata(dev);
>
> + if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
> + ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
> + if (ret < 0)
> + dev_warn(wdt->dev, "failed to update pmu register");
Duplicate error message.
> + }
> +
> s3c2410wdt_stop(&wdt->wdt_device);
> }
>
> @@ -481,12 +621,19 @@ static void s3c2410wdt_shutdown(struct platform_device *dev)
>
> static int s3c2410wdt_suspend(struct device *dev)
> {
> + int ret;
> struct s3c2410_wdt *wdt = dev_get_drvdata(dev);
>
> /* Save watchdog state, and turn it off. */
> wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON);
> wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT);
>
> + if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
> + ret = s3c2410wdt_mask_and_disable_reset(wdt, true);
> + if (ret < 0)
> + return ret;
> + }
> +
> /* Note that WTCNT doesn't need to be saved. */
> s3c2410wdt_stop(&wdt->wdt_device);
>
> @@ -495,6 +642,7 @@ static int s3c2410wdt_suspend(struct device *dev)
>
> static int s3c2410wdt_resume(struct device *dev)
> {
> + int ret;
> struct s3c2410_wdt *wdt = dev_get_drvdata(dev);
>
> /* Restore watchdog state. */
> @@ -502,6 +650,12 @@ 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);
>
> + if (wdt->drv_data->quirks & QUIRK_NEEDS_PMU_CONFIG) {
> + ret = s3c2410wdt_mask_and_disable_reset(wdt, false);
> + if (ret < 0)
> + return ret;
> + }
> +
> dev_info(dev, "watchdog %sabled\n",
> (wdt->wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
>
> @@ -512,18 +666,11 @@ static int s3c2410wdt_resume(struct device *dev)
> static SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend,
> s3c2410wdt_resume);
>
> -#ifdef CONFIG_OF
> -static const struct of_device_id s3c2410_wdt_match[] = {
> - { .compatible = "samsung,s3c2410-wdt" },
> - {},
> -};
> -MODULE_DEVICE_TABLE(of, s3c2410_wdt_match);
> -#endif
> -
> static struct platform_driver s3c2410wdt_driver = {
> .probe = s3c2410wdt_probe,
> .remove = s3c2410wdt_remove,
> .shutdown = s3c2410wdt_shutdown,
> + .id_table = s3c2410_wdt_ids,
> .driver = {
> .owner = THIS_MODULE,
> .name = "s3c2410-wdt",
> @@ -538,4 +685,3 @@ MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, "
> "Dimitry Andric <dimitry.andric@tomtom.com>");
> MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver");
> MODULE_LICENSE("GPL");
> -MODULE_ALIAS("platform:s3c2410-wdt");
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2013-11-27 16:58 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-27 11:50 [PATCH V10 0/3] Add watchdog DT nodes and use syscon regmap interface to configure pmu registers Leela Krishna Amudala
[not found] ` <1385553010-30183-1-git-send-email-l.krishna-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
2013-11-27 11:50 ` [PATCH V10 1/3] ARM: dts: Add pmu sysreg node to exynos5250 and exynos5420 dtsi files Leela Krishna Amudala
2013-11-27 11:50 ` [PATCH V10 2/3] watchdog: s3c2410_wdt: use syscon regmap interface to configure pmu register Leela Krishna Amudala
2013-11-27 16:58 ` Guenter Roeck
2013-11-27 11:50 ` [PATCH V10 3/3] ARM: dts: update watchdog device nodes for Exynos5250 and Exynos5420 Leela Krishna Amudala
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).