Message ID | 20211107202943.8859-13-semen.protsenko@linaro.org (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | watchdog: s3c2410: Add Exynos850 support | expand |
On 07/11/2021 21:29, Sam Protsenko wrote: > Exynos850 is a bit different from SoCs already supported in WDT driver: > - AUTOMATIC_WDT_RESET_DISABLE register is removed, so its value is > always 0; .disable_auto_reset callback is not set for that reason > - MASK_WDT_RESET_REQUEST register is replaced with > CLUSTERx_NONCPU_IN_EN register; instead of masking (disabling) WDT > reset interrupt it's now enabled with the same value; .mask_reset > callback is reused for that functionality though > - To make WDT functional, WDT counter needs to be enabled in > CLUSTERx_NONCPU_OUT register; it's done using .enable_counter > callback > > Also Exynos850 has two CPU clusters, each has its own dedicated WDT > instance. Different PMU registers and bits are used for each cluster. So > driver data is now modified in probe, adding needed info depending on > cluster index passed from device tree. > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> > --- > Changes in v3: > - Renamed "samsung,index" property to more descriptive > "samsung,cluster-index" > - Used pre-defined and completely set driver data for cluster0 and > cluster1 > > Changes in v2: > - Used single compatible for Exynos850, populating missing driver data > in probe > - Added "index" property to specify CPU cluster index > > drivers/watchdog/s3c2410_wdt.c | 62 +++++++++++++++++++++++++++++++++- > 1 file changed, 61 insertions(+), 1 deletion(-) > Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> Best regards, Krzysztof
On Sun, Nov 07, 2021 at 10:29:43PM +0200, Sam Protsenko wrote: > Exynos850 is a bit different from SoCs already supported in WDT driver: > - AUTOMATIC_WDT_RESET_DISABLE register is removed, so its value is > always 0; .disable_auto_reset callback is not set for that reason > - MASK_WDT_RESET_REQUEST register is replaced with > CLUSTERx_NONCPU_IN_EN register; instead of masking (disabling) WDT > reset interrupt it's now enabled with the same value; .mask_reset > callback is reused for that functionality though > - To make WDT functional, WDT counter needs to be enabled in > CLUSTERx_NONCPU_OUT register; it's done using .enable_counter > callback > > Also Exynos850 has two CPU clusters, each has its own dedicated WDT > instance. Different PMU registers and bits are used for each cluster. So > driver data is now modified in probe, adding needed info depending on > cluster index passed from device tree. > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > Changes in v3: > - Renamed "samsung,index" property to more descriptive > "samsung,cluster-index" > - Used pre-defined and completely set driver data for cluster0 and > cluster1 > > Changes in v2: > - Used single compatible for Exynos850, populating missing driver data > in probe > - Added "index" property to specify CPU cluster index > > drivers/watchdog/s3c2410_wdt.c | 62 +++++++++++++++++++++++++++++++++- > 1 file changed, 61 insertions(+), 1 deletion(-) > > diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c > index 96aa5d9c6ed4..1456201f27de 100644 > --- a/drivers/watchdog/s3c2410_wdt.c > +++ b/drivers/watchdog/s3c2410_wdt.c > @@ -56,6 +56,13 @@ > #define EXYNOS5_RST_STAT_REG_OFFSET 0x0404 > #define EXYNOS5_WDT_DISABLE_REG_OFFSET 0x0408 > #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c > +#define EXYNOS850_CLUSTER0_NONCPU_OUT 0x1220 > +#define EXYNOS850_CLUSTER0_NONCPU_INT_EN 0x1244 > +#define EXYNOS850_CLUSTER1_NONCPU_OUT 0x1620 > +#define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 > + > +#define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 > +#define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 > > /** > * Quirk flags for different Samsung watchdog IP-cores. > @@ -205,6 +212,30 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { > QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_AUTO_DISABLE, > }; > > +static const struct s3c2410_wdt_variant drv_data_exynos850_cl0 = { > + .mask_reset_reg = EXYNOS850_CLUSTER0_NONCPU_INT_EN, > + .mask_bit = 2, > + .mask_reset_inv = true, > + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, > + .rst_stat_bit = EXYNOS850_CLUSTER0_WDTRESET_BIT, > + .cnt_en_reg = EXYNOS850_CLUSTER0_NONCPU_OUT, > + .cnt_en_bit = 7, > + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ > + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, > +}; > + > +static const struct s3c2410_wdt_variant drv_data_exynos850_cl1 = { > + .mask_reset_reg = EXYNOS850_CLUSTER1_NONCPU_INT_EN, > + .mask_bit = 2, > + .mask_reset_inv = true, > + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, > + .rst_stat_bit = EXYNOS850_CLUSTER1_WDTRESET_BIT, > + .cnt_en_reg = EXYNOS850_CLUSTER1_NONCPU_OUT, > + .cnt_en_bit = 7, > + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ > + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, > +}; > + > static const struct of_device_id s3c2410_wdt_match[] = { > { .compatible = "samsung,s3c2410-wdt", > .data = &drv_data_s3c2410 }, > @@ -216,6 +247,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { > .data = &drv_data_exynos5420 }, > { .compatible = "samsung,exynos7-wdt", > .data = &drv_data_exynos7 }, > + { .compatible = "samsung,exynos850-wdt", > + .data = &drv_data_exynos850_cl0 }, > {}, > }; > MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); > @@ -587,14 +620,38 @@ static inline const struct s3c2410_wdt_variant * > s3c2410_get_wdt_drv_data(struct platform_device *pdev) > { > const struct s3c2410_wdt_variant *variant; > + struct device *dev = &pdev->dev; > > - variant = of_device_get_match_data(&pdev->dev); > + variant = of_device_get_match_data(dev); > if (!variant) { > /* Device matched by platform_device_id */ > variant = (struct s3c2410_wdt_variant *) > platform_get_device_id(pdev)->driver_data; > } > > + /* Choose Exynos850 driver data w.r.t. cluster index */ > + if (variant == &drv_data_exynos850_cl0) { > + u32 index; > + int err; > + > + err = of_property_read_u32(dev->of_node, > + "samsung,cluster-index", &index); > + if (err) { > + dev_err(dev, "failed to get cluster index\n"); > + return NULL; > + } > + > + switch (index) { > + case 0: > + return &drv_data_exynos850_cl0; > + case 1: > + return &drv_data_exynos850_cl1; > + default: > + dev_err(dev, "wrong cluster index: %u\n", index); > + return NULL; > + } > + } > + > return variant; > } > > @@ -615,6 +672,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev) > wdt->wdt_device = s3c2410_wdd; > > wdt->drv_data = s3c2410_get_wdt_drv_data(pdev); > + if (!wdt->drv_data) > + return -EINVAL; > + > if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { > wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, > "samsung,syscon-phandle"); > -- > 2.30.2 >
On 11/7/21 12:29 PM, Sam Protsenko wrote: > Exynos850 is a bit different from SoCs already supported in WDT driver: > - AUTOMATIC_WDT_RESET_DISABLE register is removed, so its value is > always 0; .disable_auto_reset callback is not set for that reason > - MASK_WDT_RESET_REQUEST register is replaced with > CLUSTERx_NONCPU_IN_EN register; instead of masking (disabling) WDT > reset interrupt it's now enabled with the same value; .mask_reset > callback is reused for that functionality though > - To make WDT functional, WDT counter needs to be enabled in > CLUSTERx_NONCPU_OUT register; it's done using .enable_counter > callback > > Also Exynos850 has two CPU clusters, each has its own dedicated WDT > instance. Different PMU registers and bits are used for each cluster. So > driver data is now modified in probe, adding needed info depending on > cluster index passed from device tree. > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> > --- > Changes in v3: > - Renamed "samsung,index" property to more descriptive > "samsung,cluster-index" > - Used pre-defined and completely set driver data for cluster0 and > cluster1 > > Changes in v2: > - Used single compatible for Exynos850, populating missing driver data > in probe > - Added "index" property to specify CPU cluster index > > drivers/watchdog/s3c2410_wdt.c | 62 +++++++++++++++++++++++++++++++++- > 1 file changed, 61 insertions(+), 1 deletion(-) > > diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c > index 96aa5d9c6ed4..1456201f27de 100644 > --- a/drivers/watchdog/s3c2410_wdt.c > +++ b/drivers/watchdog/s3c2410_wdt.c > @@ -56,6 +56,13 @@ > #define EXYNOS5_RST_STAT_REG_OFFSET 0x0404 > #define EXYNOS5_WDT_DISABLE_REG_OFFSET 0x0408 > #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c > +#define EXYNOS850_CLUSTER0_NONCPU_OUT 0x1220 > +#define EXYNOS850_CLUSTER0_NONCPU_INT_EN 0x1244 > +#define EXYNOS850_CLUSTER1_NONCPU_OUT 0x1620 > +#define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 > + > +#define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 > +#define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 > > /** > * Quirk flags for different Samsung watchdog IP-cores. > @@ -205,6 +212,30 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { > QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_AUTO_DISABLE, > }; > > +static const struct s3c2410_wdt_variant drv_data_exynos850_cl0 = { > + .mask_reset_reg = EXYNOS850_CLUSTER0_NONCPU_INT_EN, > + .mask_bit = 2, > + .mask_reset_inv = true, > + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, > + .rst_stat_bit = EXYNOS850_CLUSTER0_WDTRESET_BIT, > + .cnt_en_reg = EXYNOS850_CLUSTER0_NONCPU_OUT, > + .cnt_en_bit = 7, > + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ > + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, > +}; > + > +static const struct s3c2410_wdt_variant drv_data_exynos850_cl1 = { > + .mask_reset_reg = EXYNOS850_CLUSTER1_NONCPU_INT_EN, > + .mask_bit = 2, > + .mask_reset_inv = true, > + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, > + .rst_stat_bit = EXYNOS850_CLUSTER1_WDTRESET_BIT, > + .cnt_en_reg = EXYNOS850_CLUSTER1_NONCPU_OUT, > + .cnt_en_bit = 7, > + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ > + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, > +}; > + > static const struct of_device_id s3c2410_wdt_match[] = { > { .compatible = "samsung,s3c2410-wdt", > .data = &drv_data_s3c2410 }, > @@ -216,6 +247,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { > .data = &drv_data_exynos5420 }, > { .compatible = "samsung,exynos7-wdt", > .data = &drv_data_exynos7 }, > + { .compatible = "samsung,exynos850-wdt", > + .data = &drv_data_exynos850_cl0 }, > {}, > }; > MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); > @@ -587,14 +620,38 @@ static inline const struct s3c2410_wdt_variant * > s3c2410_get_wdt_drv_data(struct platform_device *pdev) > { > const struct s3c2410_wdt_variant *variant; > + struct device *dev = &pdev->dev; > > - variant = of_device_get_match_data(&pdev->dev); > + variant = of_device_get_match_data(dev); > if (!variant) { > /* Device matched by platform_device_id */ > variant = (struct s3c2410_wdt_variant *) > platform_get_device_id(pdev)->driver_data; > } > > + /* Choose Exynos850 driver data w.r.t. cluster index */ > + if (variant == &drv_data_exynos850_cl0) { 0-day has a point here. drv_data_exynos850_cl0 is declared inside a CONFIG_OF conditional, causing compile failure if CONFIG_OF is not enabled. Please fix and resubmit. Guenter
On Sat, 20 Nov 2021 at 22:29, Guenter Roeck <linux@roeck-us.net> wrote: > > On 11/7/21 12:29 PM, Sam Protsenko wrote: > > Exynos850 is a bit different from SoCs already supported in WDT driver: > > - AUTOMATIC_WDT_RESET_DISABLE register is removed, so its value is > > always 0; .disable_auto_reset callback is not set for that reason > > - MASK_WDT_RESET_REQUEST register is replaced with > > CLUSTERx_NONCPU_IN_EN register; instead of masking (disabling) WDT > > reset interrupt it's now enabled with the same value; .mask_reset > > callback is reused for that functionality though > > - To make WDT functional, WDT counter needs to be enabled in > > CLUSTERx_NONCPU_OUT register; it's done using .enable_counter > > callback > > > > Also Exynos850 has two CPU clusters, each has its own dedicated WDT > > instance. Different PMU registers and bits are used for each cluster. So > > driver data is now modified in probe, adding needed info depending on > > cluster index passed from device tree. > > > > Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> > > --- > > Changes in v3: > > - Renamed "samsung,index" property to more descriptive > > "samsung,cluster-index" > > - Used pre-defined and completely set driver data for cluster0 and > > cluster1 > > > > Changes in v2: > > - Used single compatible for Exynos850, populating missing driver data > > in probe > > - Added "index" property to specify CPU cluster index > > > > drivers/watchdog/s3c2410_wdt.c | 62 +++++++++++++++++++++++++++++++++- > > 1 file changed, 61 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c > > index 96aa5d9c6ed4..1456201f27de 100644 > > --- a/drivers/watchdog/s3c2410_wdt.c > > +++ b/drivers/watchdog/s3c2410_wdt.c > > @@ -56,6 +56,13 @@ > > #define EXYNOS5_RST_STAT_REG_OFFSET 0x0404 > > #define EXYNOS5_WDT_DISABLE_REG_OFFSET 0x0408 > > #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c > > +#define EXYNOS850_CLUSTER0_NONCPU_OUT 0x1220 > > +#define EXYNOS850_CLUSTER0_NONCPU_INT_EN 0x1244 > > +#define EXYNOS850_CLUSTER1_NONCPU_OUT 0x1620 > > +#define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 > > + > > +#define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 > > +#define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 > > > > /** > > * Quirk flags for different Samsung watchdog IP-cores. > > @@ -205,6 +212,30 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { > > QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_AUTO_DISABLE, > > }; > > > > +static const struct s3c2410_wdt_variant drv_data_exynos850_cl0 = { > > + .mask_reset_reg = EXYNOS850_CLUSTER0_NONCPU_INT_EN, > > + .mask_bit = 2, > > + .mask_reset_inv = true, > > + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, > > + .rst_stat_bit = EXYNOS850_CLUSTER0_WDTRESET_BIT, > > + .cnt_en_reg = EXYNOS850_CLUSTER0_NONCPU_OUT, > > + .cnt_en_bit = 7, > > + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ > > + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, > > +}; > > + > > +static const struct s3c2410_wdt_variant drv_data_exynos850_cl1 = { > > + .mask_reset_reg = EXYNOS850_CLUSTER1_NONCPU_INT_EN, > > + .mask_bit = 2, > > + .mask_reset_inv = true, > > + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, > > + .rst_stat_bit = EXYNOS850_CLUSTER1_WDTRESET_BIT, > > + .cnt_en_reg = EXYNOS850_CLUSTER1_NONCPU_OUT, > > + .cnt_en_bit = 7, > > + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ > > + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, > > +}; > > + > > static const struct of_device_id s3c2410_wdt_match[] = { > > { .compatible = "samsung,s3c2410-wdt", > > .data = &drv_data_s3c2410 }, > > @@ -216,6 +247,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { > > .data = &drv_data_exynos5420 }, > > { .compatible = "samsung,exynos7-wdt", > > .data = &drv_data_exynos7 }, > > + { .compatible = "samsung,exynos850-wdt", > > + .data = &drv_data_exynos850_cl0 }, > > {}, > > }; > > MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); > > @@ -587,14 +620,38 @@ static inline const struct s3c2410_wdt_variant * > > s3c2410_get_wdt_drv_data(struct platform_device *pdev) > > { > > const struct s3c2410_wdt_variant *variant; > > + struct device *dev = &pdev->dev; > > > > - variant = of_device_get_match_data(&pdev->dev); > > + variant = of_device_get_match_data(dev); > > if (!variant) { > > /* Device matched by platform_device_id */ > > variant = (struct s3c2410_wdt_variant *) > > platform_get_device_id(pdev)->driver_data; > > } > > > > + /* Choose Exynos850 driver data w.r.t. cluster index */ > > + if (variant == &drv_data_exynos850_cl0) { > > 0-day has a point here. drv_data_exynos850_cl0 is declared inside a CONFIG_OF > conditional, causing compile failure if CONFIG_OF is not enabled. > > Please fix and resubmit. > Right. I missed that this driver has also platform device table. Will send v4 soon. > Guenter
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 96aa5d9c6ed4..1456201f27de 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -56,6 +56,13 @@ #define EXYNOS5_RST_STAT_REG_OFFSET 0x0404 #define EXYNOS5_WDT_DISABLE_REG_OFFSET 0x0408 #define EXYNOS5_WDT_MASK_RESET_REG_OFFSET 0x040c +#define EXYNOS850_CLUSTER0_NONCPU_OUT 0x1220 +#define EXYNOS850_CLUSTER0_NONCPU_INT_EN 0x1244 +#define EXYNOS850_CLUSTER1_NONCPU_OUT 0x1620 +#define EXYNOS850_CLUSTER1_NONCPU_INT_EN 0x1644 + +#define EXYNOS850_CLUSTER0_WDTRESET_BIT 24 +#define EXYNOS850_CLUSTER1_WDTRESET_BIT 23 /** * Quirk flags for different Samsung watchdog IP-cores. @@ -205,6 +212,30 @@ static const struct s3c2410_wdt_variant drv_data_exynos7 = { QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_AUTO_DISABLE, }; +static const struct s3c2410_wdt_variant drv_data_exynos850_cl0 = { + .mask_reset_reg = EXYNOS850_CLUSTER0_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = EXYNOS850_CLUSTER0_WDTRESET_BIT, + .cnt_en_reg = EXYNOS850_CLUSTER0_NONCPU_OUT, + .cnt_en_bit = 7, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, +}; + +static const struct s3c2410_wdt_variant drv_data_exynos850_cl1 = { + .mask_reset_reg = EXYNOS850_CLUSTER1_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = EXYNOS850_CLUSTER1_WDTRESET_BIT, + .cnt_en_reg = EXYNOS850_CLUSTER1_NONCPU_OUT, + .cnt_en_bit = 7, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_CNT_EN, +}; + static const struct of_device_id s3c2410_wdt_match[] = { { .compatible = "samsung,s3c2410-wdt", .data = &drv_data_s3c2410 }, @@ -216,6 +247,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { .data = &drv_data_exynos5420 }, { .compatible = "samsung,exynos7-wdt", .data = &drv_data_exynos7 }, + { .compatible = "samsung,exynos850-wdt", + .data = &drv_data_exynos850_cl0 }, {}, }; MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); @@ -587,14 +620,38 @@ static inline const struct s3c2410_wdt_variant * s3c2410_get_wdt_drv_data(struct platform_device *pdev) { const struct s3c2410_wdt_variant *variant; + struct device *dev = &pdev->dev; - variant = of_device_get_match_data(&pdev->dev); + variant = of_device_get_match_data(dev); if (!variant) { /* Device matched by platform_device_id */ variant = (struct s3c2410_wdt_variant *) platform_get_device_id(pdev)->driver_data; } + /* Choose Exynos850 driver data w.r.t. cluster index */ + if (variant == &drv_data_exynos850_cl0) { + u32 index; + int err; + + err = of_property_read_u32(dev->of_node, + "samsung,cluster-index", &index); + if (err) { + dev_err(dev, "failed to get cluster index\n"); + return NULL; + } + + switch (index) { + case 0: + return &drv_data_exynos850_cl0; + case 1: + return &drv_data_exynos850_cl1; + default: + dev_err(dev, "wrong cluster index: %u\n", index); + return NULL; + } + } + return variant; } @@ -615,6 +672,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev) wdt->wdt_device = s3c2410_wdd; wdt->drv_data = s3c2410_get_wdt_drv_data(pdev); + if (!wdt->drv_data) + return -EINVAL; + if (wdt->drv_data->quirks & QUIRKS_HAVE_PMUREG) { wdt->pmureg = syscon_regmap_lookup_by_phandle(dev->of_node, "samsung,syscon-phandle");
Exynos850 is a bit different from SoCs already supported in WDT driver: - AUTOMATIC_WDT_RESET_DISABLE register is removed, so its value is always 0; .disable_auto_reset callback is not set for that reason - MASK_WDT_RESET_REQUEST register is replaced with CLUSTERx_NONCPU_IN_EN register; instead of masking (disabling) WDT reset interrupt it's now enabled with the same value; .mask_reset callback is reused for that functionality though - To make WDT functional, WDT counter needs to be enabled in CLUSTERx_NONCPU_OUT register; it's done using .enable_counter callback Also Exynos850 has two CPU clusters, each has its own dedicated WDT instance. Different PMU registers and bits are used for each cluster. So driver data is now modified in probe, adding needed info depending on cluster index passed from device tree. Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org> --- Changes in v3: - Renamed "samsung,index" property to more descriptive "samsung,cluster-index" - Used pre-defined and completely set driver data for cluster0 and cluster1 Changes in v2: - Used single compatible for Exynos850, populating missing driver data in probe - Added "index" property to specify CPU cluster index drivers/watchdog/s3c2410_wdt.c | 62 +++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-)