The MOXA ART and Aspeed watchdogs are clearly based on the
Faraday Technology FTWDT010 IP block.
This series consolidates the drivers into one by extending
the Gemini driver to be as generic as possible, renaming it
to ftwdt010_wdt and merging the two other drivers into it.
As similar approach was used for the FTTMR010 driver in the
past.
The series ends with two patches that will be applied to
the ARM SoC tree to fix up the PCLK annotations, but these
are not needed to make the consolidation, patches 1-9 can
be applied directly to the watchdog tree to perform the
consolidation.
Obviously I would like the MOXA ART and Aspeed maintainers
to test the series to see that it still works as expected for
them afterwards.
The patch series is available at:
git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
Branch ftwdt010
Linus Walleij (11):
watchdog: gemini/ftwdt010: rename DT bindings
watchdog: gemini/ftwdt010: rename driver and symbols
watchdog: ftwdt010: Make interrupt optional
watchdog: ftwdt010: Add clock support
watchdog: ftwdt010: Add restart support
watchdog: ftwdt010: Extend DT bindings to derivatives
watchdog: ftwdt010: Delete surplus bindings
watchdog: ftwdt010/moxart: Merge MOXA ART into FTWDT010
watchdog: ftwdt010/aspeed: Merge Aspeed into FTWDT010
ARM: dts: fix PCLK name on Gemini and MOXA ART
ARM: dts: Add PCLK to the Aspeed watchdogs
.../devicetree/bindings/watchdog/aspeed-wdt.txt | 16 -
.../bindings/watchdog/cortina,gemin-watchdog.txt | 17 --
.../bindings/watchdog/cortina,gemini-watchdog.txt | 17 --
.../bindings/watchdog/faraday,ftwdt010.txt | 34 +++
.../bindings/watchdog/moxa,moxart-watchdog.txt | 15 -
arch/arm/boot/dts/aspeed-g4.dtsi | 7 +-
arch/arm/boot/dts/aspeed-g5.dtsi | 12 +-
arch/arm/boot/dts/gemini.dtsi | 3 +-
arch/arm/boot/dts/moxart.dtsi | 3 +-
drivers/watchdog/Kconfig | 39 +--
drivers/watchdog/Makefile | 4 +-
drivers/watchdog/aspeed_wdt.c | 200 ------------
drivers/watchdog/ftwdt010_wdt.c | 338 +++++++++++++++++++++
drivers/watchdog/gemini_wdt.c | 229 --------------
drivers/watchdog/moxart_wdt.c | 178 -----------
15 files changed, 401 insertions(+), 711 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
delete mode 100644 Documentation/devicetree/bindings/watchdog/cortina,gemin-watchdog.txt
delete mode 100644 Documentation/devicetree/bindings/watchdog/cortina,gemini-watchdog.txt
create mode 100644 Documentation/devicetree/bindings/watchdog/faraday,ftwdt010.txt
delete mode 100644 Documentation/devicetree/bindings/watchdog/moxa,moxart-watchdog.txt
delete mode 100644 drivers/watchdog/aspeed_wdt.c
create mode 100644 drivers/watchdog/ftwdt010_wdt.c
delete mode 100644 drivers/watchdog/gemini_wdt.c
delete mode 100644 drivers/watchdog/moxart_wdt.c
--
2.13.4
This renames all the driver files and symbols for the Gemini
watchdog to FTWDT010 as it has been revealed that this IP block
is a generic watchdog timer from Faraday Technology used in
several SoC designs.
Select thid driver by default for the Gemini, it is a sensible
driver to always have enabled.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/Kconfig | 14 +--
drivers/watchdog/Makefile | 2 +-
drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} | 117 +++++++++++-----------
3 files changed, 68 insertions(+), 65 deletions(-)
rename drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} (50%)
diff --git a/drivers/watchdog/gemini_wdt.c b/drivers/watchdog/ftwdt010_wdt.csimilarity index 50%rename from drivers/watchdog/gemini_wdt.crename to drivers/watchdog/ftwdt010_wdt.cindex 8155aa619e4c..637ffd812f0b 100644--- a/drivers/watchdog/gemini_wdt.c+++ b/drivers/watchdog/ftwdt010_wdt.c
@@ -138,8 +138,8 @@ static int gemini_wdt_probe(struct platform_device *pdev)return-EINVAL;gwdt->dev=dev;-gwdt->wdd.info=&gemini_wdt_info;-gwdt->wdd.ops=&gemini_wdt_ops;+gwdt->wdd.info=&ftwdt010_wdt_info;+gwdt->wdd.ops=&ftwdt010_wdt_ops;gwdt->wdd.min_timeout=1;gwdt->wdd.max_timeout=0xFFFFFFFF/WDT_CLOCK;gwdt->wdd.parent=dev;
@@ -151,14 +151,14 @@ static int gemini_wdt_probe(struct platform_device *pdev)gwdt->wdd.timeout=13U;watchdog_init_timeout(&gwdt->wdd,0,dev);-reg=readw(gwdt->base+GEMINI_WDCR);+reg=readw(gwdt->base+FTWDT010_WDCR);if(reg&WDCR_ENABLE){/* Watchdog was enabled by the bootloader, disable it. */reg&=~WDCR_ENABLE;-writel(reg,gwdt->base+GEMINI_WDCR);+writel(reg,gwdt->base+FTWDT010_WDCR);}-ret=devm_request_irq(dev,irq,gemini_wdt_interrupt,0,+ret=devm_request_irq(dev,irq,ftwdt010_wdt_interrupt,0,"watchdog bark",gwdt);if(ret)returnret;
@@ -171,59 +171,60 @@ static int gemini_wdt_probe(struct platform_device *pdev)/* Set up platform driver data */platform_set_drvdata(pdev,gwdt);-dev_info(dev,"Gemini watchdog driver enabled\n");+dev_info(dev,"FTWDT010 watchdog driver enabled\n");return0;}-staticint__maybe_unusedgemini_wdt_suspend(structdevice*dev)+staticint__maybe_unusedftwdt010_wdt_suspend(structdevice*dev){-structgemini_wdt*gwdt=dev_get_drvdata(dev);+structftwdt010_wdt*gwdt=dev_get_drvdata(dev);unsignedintreg;-reg=readw(gwdt->base+GEMINI_WDCR);+reg=readw(gwdt->base+FTWDT010_WDCR);reg&=~WDCR_ENABLE;-writel(reg,gwdt->base+GEMINI_WDCR);+writel(reg,gwdt->base+FTWDT010_WDCR);return0;}-staticint__maybe_unusedgemini_wdt_resume(structdevice*dev)+staticint__maybe_unusedftwdt010_wdt_resume(structdevice*dev){-structgemini_wdt*gwdt=dev_get_drvdata(dev);+structftwdt010_wdt*gwdt=dev_get_drvdata(dev);unsignedintreg;if(watchdog_active(&gwdt->wdd)){-reg=readw(gwdt->base+GEMINI_WDCR);+reg=readw(gwdt->base+FTWDT010_WDCR);reg|=WDCR_ENABLE;-writel(reg,gwdt->base+GEMINI_WDCR);+writel(reg,gwdt->base+FTWDT010_WDCR);}return0;}-staticconststructdev_pm_opsgemini_wdt_dev_pm_ops={-SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend,-gemini_wdt_resume)+staticconststructdev_pm_opsftwdt010_wdt_dev_pm_ops={+SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend,+ftwdt010_wdt_resume)};#ifdef CONFIG_OF-staticconststructof_device_idgemini_wdt_match[]={+staticconststructof_device_idftwdt010_wdt_match[]={+{.compatible="faraday,ftwdt010"},{.compatible="cortina,gemini-watchdog"},{},};-MODULE_DEVICE_TABLE(of,gemini_wdt_match);+MODULE_DEVICE_TABLE(of,ftwdt010_wdt_match);#endif-staticstructplatform_drivergemini_wdt_driver={-.probe=gemini_wdt_probe,+staticstructplatform_driverftwdt010_wdt_driver={+.probe=ftwdt010_wdt_probe,.driver={-.name="gemini-wdt",-.of_match_table=of_match_ptr(gemini_wdt_match),-.pm=&gemini_wdt_dev_pm_ops,+.name="ftwdt010-wdt",+.of_match_table=of_match_ptr(ftwdt010_wdt_match),+.pm=&ftwdt010_wdt_dev_pm_ops,},};-module_platform_driver(gemini_wdt_driver);+module_platform_driver(ftwdt010_wdt_driver);MODULE_AUTHOR("Linus Walleij");-MODULE_DESCRIPTION("Watchdog driver for Gemini");+MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010");MODULE_LICENSE("GPL");
The Moxart does not appear to be using the interrupt from the
watchdog timer, maybe it's not even routed, so as to support
more architectures with this driver, make the interrupt
optional.
While we are at it: actually enable the use of the interrupt
if present by setting the right bit in the control register
and define the missing control register bits.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/ftwdt010_wdt.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
The Gemini platform now provides a proper clock look-up for this
and other IPs, so add clock support to the driver. This also aids
in using the same driver with other platforms such as MOXA ART.
The IP has two clock inputs: PCLK (the IP peripheral clock) and
EXTCLK (an external clock). We are a bit elaborate around this:
on Gemini the EXTCLK is used by default today and it's 5MHz, and
on MOXA ART the PCLK is used. On Aspeed the EXTCLK is used and
it's 1MHz. So add some clever code to fall back to platform
defaults if PCLK or EXTCLK is not provided by the device tree.
Take this opportnity to implement .remove() for the driver that
stops the watchdog and disables the clocks.
Add credits that this code is inspired by MOXA ART.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/ftwdt010_wdt.c | 79 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 8 deletions(-)
@@ -55,12 +61,13 @@ static int ftwdt010_wdt_start(struct watchdog_device *wdd)structftwdt010_wdt*gwdt=to_ftwdt010_wdt(wdd);u32enable;-writel(wdd->timeout*WDT_CLOCK,gwdt->base+FTWDT010_WDLOAD);+writel(wdd->timeout*gwdt->clk_freq,gwdt->base+FTWDT010_WDLOAD);writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);/* set clock before enabling */-enable=WDCR_CLOCK_5MHZ|WDCR_SYS_RST;+enable=WDCR_SYS_RST;+if(gwdt->use_extclk)+enable|=WDCR_EXTCLK;writel(enable,gwdt->base+FTWDT010_WDCR);-enable|=WDCR_CLOCK_5MHZ;if(gwdt->has_irq)enable|=WDCR_WDINTR;enable|=WDCR_ENABLE;
@@ -140,11 +148,51 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)if(IS_ERR(gwdt->base))returnPTR_ERR(gwdt->base);+gwdt->use_extclk=of_property_read_bool(np,"faraday,use-extclk");++gwdt->pclk=devm_clk_get(dev,"PCLK");+if(!IS_ERR(gwdt->pclk)){+ret=clk_prepare_enable(gwdt->pclk);+if(ret){+dev_err(&pdev->dev,"unable to enable PCLK\n");+returnret;+}+if(!gwdt->use_extclk)+gwdt->clk_freq=clk_get_rate(gwdt->pclk);+}else{+dev_info(dev,"PCLK clock not found assume always-on\n");+}++gwdt->extclk=devm_clk_get(dev,"EXTCLK");+if(!IS_ERR(gwdt->extclk)){+/* Only enable and get frequency from EXTCLK if it's in use */+if(gwdt->use_extclk){+ret=clk_prepare_enable(gwdt->extclk);+if(ret){+dev_err(&pdev->dev,+"unable to enable EXTCLK\n");+returnret;+}+gwdt->clk_freq=clk_get_rate(gwdt->extclk);+}+}else{+if(of_device_is_compatible(np,"cortina,gemini-watchdog")){+gwdt->clk_freq=5000000;+gwdt->use_extclk=true;+dev_info(dev,"assume 5MHz EXTCLK on Gemini\n");+}+}++if(gwdt->clk_freq==0){+dev_err(dev,"no clocking available\n");+return-EINVAL;+}+gwdt->dev=dev;gwdt->wdd.info=&ftwdt010_wdt_info;gwdt->wdd.ops=&ftwdt010_wdt_ops;gwdt->wdd.min_timeout=1;-gwdt->wdd.max_timeout=0xFFFFFFFF/WDT_CLOCK;+gwdt->wdd.max_timeout=UINT_MAX/gwdt->clk_freq;gwdt->wdd.parent=dev;/*
@@ -178,7 +226,21 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)/* Set up platform driver data */platform_set_drvdata(pdev,gwdt);-dev_info(dev,"FTWDT010 watchdog driver enabled\n");+dev_info(dev,"FTWDT010 watchdog driver @%uHz\n",+gwdt->clk_freq);++return0;+}++staticintftwdt010_wdt_remove(structplatform_device*pdev)+{+structftwdt010_wdt*gwdt=platform_get_drvdata(pdev);++writel(0,gwdt->base+FTWDT010_WDCR);+if(!IS_ERR(gwdt->pclk))+clk_disable_unprepare(gwdt->pclk);+if(!IS_ERR(gwdt->extclk)&&gwdt->use_extclk)+clk_disable_unprepare(gwdt->extclk);return0;}
This enables the Faraday FTWDT010 to restart the system,
if need be. Set the restart priority for the watchdog to
128.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/ftwdt010_wdt.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
With the MOXA ART and Aspeed DT bindings covered by the
FTWDT010 binding, these surplus bindings can be deleted.
Signed-off-by: Linus Walleij <redacted>
---
.../devicetree/bindings/watchdog/aspeed-wdt.txt | 16 ----------------
.../bindings/watchdog/moxa,moxart-watchdog.txt | 15 ---------------
2 files changed, 31 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
delete mode 100644 Documentation/devicetree/bindings/watchdog/moxa,moxart-watchdog.txt
@@ -1,16 +0,0 @@-Aspeed Watchdog Timer--Required properties:- - compatible: must be one of:- - "aspeed,ast2400-wdt"- - "aspeed,ast2500-wdt"-- - reg: physical base address of the controller and length of memory mapped- region--Example:-- wdt1: watchdog at 1e785000 {- compatible = "aspeed,ast2400-wdt";- reg = <0x1e785000 0x1c>;- };
@@ -1,15 +0,0 @@-MOXA ART Watchdog timer--Required properties:--- compatible : Must be "moxa,moxart-watchdog"-- reg : Should contain registers location and length-- clocks : Should contain phandle for the clock that drives the counter--Example:-- watchdog: watchdog at 98500000 {- compatible = "moxa,moxart-watchdog";- reg = <0x98500000 0x10>;- clocks = <&coreclk>;- };
These two drivers is for the same hardware, the only difference
is that Gemini uses the EXTCLK @5MHz by default (it also works
fine using PCLK) while the MOXA ART is using the PCLK to clock
the watchdog.
Delete the old MOXA ART driver and augment the FTWDT010 to
probe on this platform too, fetching the operating frequency
from the PCLK. Select the driver by default for ARCH_MOXART
to make a smooth transition of the platform.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/Kconfig | 11 +--
drivers/watchdog/Makefile | 1 -
drivers/watchdog/ftwdt010_wdt.c | 1 +
drivers/watchdog/moxart_wdt.c | 178 ----------------------------------------
4 files changed, 2 insertions(+), 189 deletions(-)
delete mode 100644 drivers/watchdog/moxart_wdt.c
These two drivers is for the almost the same hardware,
the only differences are:
- The Aspeed IP block has been hacked to use a different
magic value.
- The Aspeed has hard-wired 1MHz to the EXTCLK and
apparently even disabled the use of PCLK for clocking
the block on AST2500.
Delete the old Aspeed driver and augment the FTWDT010 to
probe on this platform too. Select the driver by default
for ARCH_ASPEED to make a smooth transition of the platform.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/Kconfig | 18 +---
drivers/watchdog/Makefile | 1 -
drivers/watchdog/aspeed_wdt.c | 200 ----------------------------------------
drivers/watchdog/ftwdt010_wdt.c | 25 ++++-
4 files changed, 25 insertions(+), 219 deletions(-)
delete mode 100644 drivers/watchdog/aspeed_wdt.c
@@ -63,7 +68,7 @@ static int ftwdt010_wdt_restart(struct watchdog_device *wdd,u32enable;writel(1,gwdt->base+FTWDT010_WDLOAD);-writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);+writel(gwdt->magic,gwdt->base+FTWDT010_WDRESTART);enable=WDCR_SYS_RST|WDCR_ENABLE;if(gwdt->use_extclk)enable|=WDCR_EXTCLK;
@@ -78,7 +83,7 @@ static int ftwdt010_wdt_start(struct watchdog_device *wdd)u32enable;writel(wdd->timeout*gwdt->clk_freq,gwdt->base+FTWDT010_WDLOAD);-writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);+writel(gwdt->magic,gwdt->base+FTWDT010_WDRESTART);/* set clock before enabling */enable=WDCR_SYS_RST;if(gwdt->use_extclk)
@@ -105,7 +110,7 @@ static int ftwdt010_wdt_ping(struct watchdog_device *wdd){structftwdt010_wdt*gwdt=to_ftwdt010_wdt(wdd);-writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);+writel(gwdt->magic,gwdt->base+FTWDT010_WDRESTART);return0;}
@@ -153,6 +158,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)structresource*res;structftwdt010_wdt*gwdt;unsignedintreg;+boolis_aspeed;intirq;intret;
@@ -167,6 +173,10 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)gwdt->use_extclk=of_property_read_bool(np,"faraday,use-extclk");+/* We want to know if we are aspeed */+is_aspeed=of_device_is_compatible(np,"aspeed,ast2400-wdt")||+of_device_is_compatible(np,"aspeed,ast2500-wdt");+gwdt->pclk=devm_clk_get(dev,"PCLK");if(!IS_ERR(gwdt->pclk)){ret=clk_prepare_enable(gwdt->pclk);
@@ -198,6 +208,11 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)gwdt->use_extclk=true;dev_info(dev,"assume 5MHz EXTCLK on Gemini\n");}+if(is_aspeed){+gwdt->clk_freq=1000000;+gwdt->use_extclk=true;+dev_info(dev,"assume 1MHz EXTCLK on Aspeed\n");+}}if(gwdt->clk_freq==0){
@@ -211,6 +226,10 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)gwdt->wdd.min_timeout=1;gwdt->wdd.max_timeout=UINT_MAX/gwdt->clk_freq;gwdt->wdd.parent=dev;+if(is_aspeed)+gwdt->magic=ASPEED_MAGIC;+else+gwdt->magic=WDRESTART_MAGIC;/**If'timeout-sec'unspecifiedindevicetree,assumea13second
These platforms provide a clock to their watchdog, in each
case this is the peripheral clock (PCLK), so explicitly
name the clock in the device tree.
Take this opportunity to add the "faraday,ftwdt010"
compatible as fallback to the watchdog IP blocks.
Signed-off-by: Linus Walleij <redacted>
---
arch/arm/boot/dts/gemini.dtsi | 3 ++-
arch/arm/boot/dts/moxart.dtsi | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
This adds the PCLK clock to the Aspeed watchdog blocks.
I am not directly familiar with the Aspeed clocking, but
since the IP is derived from Faraday FTWDT010 it probably
has the ability to run the watchdog on the PCLK if
desired so to obtain the frequency from it, it needs to
be present in the device tree, and for completeness the
PCLK should also be referenced and enabled anyways.
Take this opportunity to add the "faraday,ftwdt010"
compatible as fallback to the watchdog IP blocks.
Signed-off-by: Linus Walleij <redacted>
---
arch/arm/boot/dts/aspeed-g4.dtsi | 7 +++++--
arch/arm/boot/dts/aspeed-g5.dtsi | 12 +++++++++---
2 files changed, 14 insertions(+), 5 deletions(-)
Hi Linus,
On Sun, Aug 13, 2017 at 4:13 AM, Linus Walleij [off-list ref] wrote:
The MOXA ART and Aspeed watchdogs are clearly based on the
Faraday Technology FTWDT010 IP block.
They have a similar register interface, but I'm told they are not the same IP.
We've got some patches on the list that add some extra registers to
the driver for the ast2500. If we decide to merge the drivers, that
support will need to be included.
Andrew was working on that, I'll let him follow up on the details.
This series consolidates the drivers into one by extending
the Gemini driver to be as generic as possible, renaming it
to ftwdt010_wdt and merging the two other drivers into it.
As similar approach was used for the FTTMR010 driver in the
past.
The series ends with two patches that will be applied to
the ARM SoC tree to fix up the PCLK annotations, but these
are not needed to make the consolidation, patches 1-9 can
be applied directly to the watchdog tree to perform the
consolidation.
The clock isn't called PCLK in the Aspeed documentation (similarly for
the timer, but I was too slow to speak up in that case).
I'm trying to find some time to write a proper clock driver so it's
clear how the clocks are set out in the Aspeed.
Cheers,
Joel
From: Andrew Jeffery <hidden> Date: 2017-08-14 03:08:16
On Mon, 2017-08-14 at 10:54 +0930, Joel Stanley wrote:
Hi Linus,
?
On Sun, Aug 13, 2017 at 4:13 AM, Linus Walleij [off-list ref] wrote:
quoted
The MOXA ART and Aspeed watchdogs are clearly based on the
Faraday Technology FTWDT010 IP block.
?
They have a similar register interface, but I'm told they are not the same IP.
?
We've got some patches on the list that add some extra registers to
the driver for the ast2500. If we decide to merge the drivers, that
support will need to be included.
?
Andrew was working on that, I'll let him follow up on the details.
There are two series on the lists expanding driver support for the Aspeed
watchdog, one from Chris Bostic and another from myself:
1. [PATCH v5 0/2] Add ASPEED watchdog device tree properties:
https://lkml.org/lkml/2017/7/17/777?
2. [PATCH 0/2] watchdog: aspeed: External reset signal properties:
https://www.spinics.net/lists/kernel/msg2570666.html?
I don't have the datasheets for either the Moxa or Faraday SoCs, so I can't
assess how the support I've added for the external pulse properties on Aspeed
hardware impacts/is impacted by the merge. Chris' changes on the otherhand look
like they could be generalised. At least, the vendor prefix on the devicetree
properties he defined could perhaps be changed from aspeed to faraday.
Cheers,
Andrew
PS: Patch 10/11 failed to apply for me against several trees, failing on the
hunk for arch/arm/boot/dts/gemini.dtsi. Is there an unmentioned dependency?
?
quoted
This series consolidates the drivers into one by extending
the Gemini driver to be as generic as possible, renaming it
to ftwdt010_wdt and merging the two other drivers into it.
?
As similar approach was used for the FTTMR010 driver in the
past.
?
The series ends with two patches that will be applied to
the ARM SoC tree to fix up the PCLK annotations, but these
are not needed to make the consolidation, patches 1-9 can
be applied directly to the watchdog tree to perform the
consolidation.
?
The clock isn't called PCLK in the Aspeed documentation (similarly for
the timer, but I was too slow to speak up in that case).
?
I'm trying to find some time to write a proper clock driver so it's
clear how the clocks are set out in the Aspeed.
?
Cheers,
?
Joel
On Mon, Aug 14, 2017 at 3:24 AM, Joel Stanley [off-list ref] wrote:
On Sun, Aug 13, 2017 at 4:13 AM, Linus Walleij [off-list ref] wrote:
quoted
The MOXA ART and Aspeed watchdogs are clearly based on the
Faraday Technology FTWDT010 IP block.
They have a similar register interface, but I'm told they are not the same IP.
They are too similar to not be related somehow.
I guess it is one of those Shanzhai-mindset things where IP VHDL
or Verilog code is being copied around at silicon foundries in Asia
and turn up in different chips "independently" of each other.
It doesn't really matter if they "are" the same (as in: silicon vendor
admits that they are), if it walks like a duck, act and talks like a duck,
it is a duck. And we use the same driver.
We've got some patches on the list that add some extra registers to
the driver for the ast2500. If we decide to merge the drivers, that
support will need to be included.
Hm I was not aware, need to read up on it.
Andrew was working on that, I'll let him follow up on the details.
The clock isn't called PCLK in the Aspeed documentation (similarly for
the timer, but I was too slow to speak up in that case).
"PCLK" is just short for "peripheral block", just like other such
shorthands like "APB" (AMBA peripheral bridge clock). It's
a generic term.
Preferrably it should use the name from the IP vendor, but when in
conflict about names, it's too much trouble to use different names
IMO so I think "PCLK" is just fine.
Yours,
Linus Walleij
On Mon, Aug 14, 2017 at 5:08 AM, Andrew Jeffery [off-list ref] wrote:
There are two series on the lists expanding driver support for the Aspeed
watchdog, one from Chris Bostic and another from myself:
1. [PATCH v5 0/2] Add ASPEED watchdog device tree properties:
https://lkml.org/lkml/2017/7/17/777
Looks all right. The SoC vs whole chip reset signal big is an
Aspeed-specific extension AFAICT.
The external reset exists also in the Faraday FTWDT010 block, in the
same bit. (No coincidence...) but neither the Gemini or the MOXA ART
is using it as far as I know.
I don't have the datasheets for either the Moxa or Faraday SoCs, so I can't
assess how the support I've added for the external pulse properties on Aspeed
hardware impacts/is impacted by the merge.
It's no big deal, I can rewrite the patches in the end of the series on top
of that stuff also adding this functionality.
Chris' changes on the otherhand look
like they could be generalised. At least, the vendor prefix on the devicetree
properties he defined could perhaps be changed from aspeed to faraday.
The "aspeed,reset-type" is fine since it is Aspeed-only.
External reset is part of the Faraday IP block so it should be
"faraday,external-reset-signal" or so.
I will try to see if I can find the patches and comment directly.
Yours,
Linus Walleij
On Sat, Aug 12, 2017 at 8:43 PM, Linus Walleij [off-list ref] wrote:
The MOXA ART and Aspeed watchdogs are clearly based on the
Faraday Technology FTWDT010 IP block.
Wim/Guenther: it is perfectly fine to just stop merging the series after
the say top 3 or top 4 ones etc. The do not need to be applied on an
all-or-nothing basis.
Yours,
Linus Walleij
On Sat, Aug 12, 2017 at 08:43:09PM +0200, Linus Walleij wrote:
quoted hunk
This renames all the driver files and symbols for the Gemini
watchdog to FTWDT010 as it has been revealed that this IP block
is a generic watchdog timer from Faraday Technology used in
several SoC designs.
Select thid driver by default for the Gemini, it is a sensible
driver to always have enabled.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/Kconfig | 14 +--
drivers/watchdog/Makefile | 2 +-
drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} | 117 +++++++++++-----------
3 files changed, 68 insertions(+), 65 deletions(-)
rename drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} (50%)
Did you test this ? I am kind of wary about COMPILE_TEST in watchdog drivers.
I tried to enable that a while ago, and we had to spend a couple of releases
fixing the fallout (even though I had tried to make sure that everything
builds).
quoted hunk
select WATCHDOG_CORE
+ default ARCH_GEMINI
help
- Say Y here if to include support for the watchdog timer
- embedded in the Cortina Systems Gemini family of devices.
+ Say Y here if to include support for the Faraday Technology
+ FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
+ family of devices.
To compile this driver as a module, choose M here: the
- module will be called gemini_wdt.
+ module will be called ftwdt010_wdt.
config IXP4XX_WATCHDOG
tristate "IXP4xx Watchdog"
diff --git a/drivers/watchdog/gemini_wdt.c b/drivers/watchdog/ftwdt010_wdt.csimilarity index 50%rename from drivers/watchdog/gemini_wdt.crename to drivers/watchdog/ftwdt010_wdt.cindex 8155aa619e4c..637ffd812f0b 100644--- a/drivers/watchdog/gemini_wdt.c+++ b/drivers/watchdog/ftwdt010_wdt.c
@@ -138,8 +138,8 @@ static int gemini_wdt_probe(struct platform_device *pdev)return-EINVAL;gwdt->dev=dev;-gwdt->wdd.info=&gemini_wdt_info;-gwdt->wdd.ops=&gemini_wdt_ops;+gwdt->wdd.info=&ftwdt010_wdt_info;+gwdt->wdd.ops=&ftwdt010_wdt_ops;gwdt->wdd.min_timeout=1;gwdt->wdd.max_timeout=0xFFFFFFFF/WDT_CLOCK;gwdt->wdd.parent=dev;
@@ -151,14 +151,14 @@ static int gemini_wdt_probe(struct platform_device *pdev)gwdt->wdd.timeout=13U;watchdog_init_timeout(&gwdt->wdd,0,dev);-reg=readw(gwdt->base+GEMINI_WDCR);+reg=readw(gwdt->base+FTWDT010_WDCR);if(reg&WDCR_ENABLE){/* Watchdog was enabled by the bootloader, disable it. */reg&=~WDCR_ENABLE;-writel(reg,gwdt->base+GEMINI_WDCR);+writel(reg,gwdt->base+FTWDT010_WDCR);}-ret=devm_request_irq(dev,irq,gemini_wdt_interrupt,0,+ret=devm_request_irq(dev,irq,ftwdt010_wdt_interrupt,0,"watchdog bark",gwdt);if(ret)returnret;
@@ -171,59 +171,60 @@ static int gemini_wdt_probe(struct platform_device *pdev)/* Set up platform driver data */platform_set_drvdata(pdev,gwdt);-dev_info(dev,"Gemini watchdog driver enabled\n");+dev_info(dev,"FTWDT010 watchdog driver enabled\n");return0;}-staticint__maybe_unusedgemini_wdt_suspend(structdevice*dev)+staticint__maybe_unusedftwdt010_wdt_suspend(structdevice*dev){-structgemini_wdt*gwdt=dev_get_drvdata(dev);+structftwdt010_wdt*gwdt=dev_get_drvdata(dev);unsignedintreg;-reg=readw(gwdt->base+GEMINI_WDCR);+reg=readw(gwdt->base+FTWDT010_WDCR);reg&=~WDCR_ENABLE;-writel(reg,gwdt->base+GEMINI_WDCR);+writel(reg,gwdt->base+FTWDT010_WDCR);return0;}-staticint__maybe_unusedgemini_wdt_resume(structdevice*dev)+staticint__maybe_unusedftwdt010_wdt_resume(structdevice*dev){-structgemini_wdt*gwdt=dev_get_drvdata(dev);+structftwdt010_wdt*gwdt=dev_get_drvdata(dev);unsignedintreg;if(watchdog_active(&gwdt->wdd)){-reg=readw(gwdt->base+GEMINI_WDCR);+reg=readw(gwdt->base+FTWDT010_WDCR);reg|=WDCR_ENABLE;-writel(reg,gwdt->base+GEMINI_WDCR);+writel(reg,gwdt->base+FTWDT010_WDCR);}return0;}-staticconststructdev_pm_opsgemini_wdt_dev_pm_ops={-SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend,-gemini_wdt_resume)+staticconststructdev_pm_opsftwdt010_wdt_dev_pm_ops={+SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend,+ftwdt010_wdt_resume)};#ifdef CONFIG_OF-staticconststructof_device_idgemini_wdt_match[]={+staticconststructof_device_idftwdt010_wdt_match[]={+{.compatible="faraday,ftwdt010"},{.compatible="cortina,gemini-watchdog"},{},};-MODULE_DEVICE_TABLE(of,gemini_wdt_match);+MODULE_DEVICE_TABLE(of,ftwdt010_wdt_match);#endif-staticstructplatform_drivergemini_wdt_driver={-.probe=gemini_wdt_probe,+staticstructplatform_driverftwdt010_wdt_driver={+.probe=ftwdt010_wdt_probe,.driver={-.name="gemini-wdt",-.of_match_table=of_match_ptr(gemini_wdt_match),-.pm=&gemini_wdt_dev_pm_ops,+.name="ftwdt010-wdt",+.of_match_table=of_match_ptr(ftwdt010_wdt_match),+.pm=&ftwdt010_wdt_dev_pm_ops,},};-module_platform_driver(gemini_wdt_driver);+module_platform_driver(ftwdt010_wdt_driver);MODULE_AUTHOR("Linus Walleij");-MODULE_DESCRIPTION("Watchdog driver for Gemini");+MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010");MODULE_LICENSE("GPL");
--
2.13.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Aug 12, 2017 at 08:43:16PM +0200, Linus Walleij wrote:
These two drivers is for the almost the same hardware,
the only differences are:
- The Aspeed IP block has been hacked to use a different
magic value.
- The Aspeed has hard-wired 1MHz to the EXTCLK and
apparently even disabled the use of PCLK for clocking
the block on AST2500.
Confused. I thought the ast2500 is an EC. Am I missing something ?
Guenter
quoted hunk
Delete the old Aspeed driver and augment the FTWDT010 to
probe on this platform too. Select the driver by default
for ARCH_ASPEED to make a smooth transition of the platform.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/Kconfig | 18 +---
drivers/watchdog/Makefile | 1 -
drivers/watchdog/aspeed_wdt.c | 200 ----------------------------------------
drivers/watchdog/ftwdt010_wdt.c | 25 ++++-
4 files changed, 25 insertions(+), 219 deletions(-)
delete mode 100644 drivers/watchdog/aspeed_wdt.c
@@ -63,7 +68,7 @@ static int ftwdt010_wdt_restart(struct watchdog_device *wdd,u32enable;writel(1,gwdt->base+FTWDT010_WDLOAD);-writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);+writel(gwdt->magic,gwdt->base+FTWDT010_WDRESTART);enable=WDCR_SYS_RST|WDCR_ENABLE;if(gwdt->use_extclk)enable|=WDCR_EXTCLK;
@@ -78,7 +83,7 @@ static int ftwdt010_wdt_start(struct watchdog_device *wdd)u32enable;writel(wdd->timeout*gwdt->clk_freq,gwdt->base+FTWDT010_WDLOAD);-writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);+writel(gwdt->magic,gwdt->base+FTWDT010_WDRESTART);/* set clock before enabling */enable=WDCR_SYS_RST;if(gwdt->use_extclk)
@@ -105,7 +110,7 @@ static int ftwdt010_wdt_ping(struct watchdog_device *wdd){structftwdt010_wdt*gwdt=to_ftwdt010_wdt(wdd);-writel(WDRESTART_MAGIC,gwdt->base+FTWDT010_WDRESTART);+writel(gwdt->magic,gwdt->base+FTWDT010_WDRESTART);return0;}
@@ -153,6 +158,7 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)structresource*res;structftwdt010_wdt*gwdt;unsignedintreg;+boolis_aspeed;intirq;intret;
@@ -167,6 +173,10 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)gwdt->use_extclk=of_property_read_bool(np,"faraday,use-extclk");+/* We want to know if we are aspeed */+is_aspeed=of_device_is_compatible(np,"aspeed,ast2400-wdt")||+of_device_is_compatible(np,"aspeed,ast2500-wdt");+gwdt->pclk=devm_clk_get(dev,"PCLK");if(!IS_ERR(gwdt->pclk)){ret=clk_prepare_enable(gwdt->pclk);
@@ -198,6 +208,11 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)gwdt->use_extclk=true;dev_info(dev,"assume 5MHz EXTCLK on Gemini\n");}+if(is_aspeed){+gwdt->clk_freq=1000000;+gwdt->use_extclk=true;+dev_info(dev,"assume 1MHz EXTCLK on Aspeed\n");+}}if(gwdt->clk_freq==0){
@@ -211,6 +226,10 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev)gwdt->wdd.min_timeout=1;gwdt->wdd.max_timeout=UINT_MAX/gwdt->clk_freq;gwdt->wdd.parent=dev;+if(is_aspeed)+gwdt->magic=ASPEED_MAGIC;+else+gwdt->magic=WDRESTART_MAGIC;/**If'timeout-sec'unspecifiedindevicetree,assumea13second
--
2.13.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Aug 12, 2017 at 08:43:10PM +0200, Linus Walleij wrote:
quoted hunk
The Moxart does not appear to be using the interrupt from the
watchdog timer, maybe it's not even routed, so as to support
more architectures with this driver, make the interrupt
optional.
While we are at it: actually enable the use of the interrupt
if present by setting the right bit in the control register
and define the missing control register bits.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/ftwdt010_wdt.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
@@ -133,10 +140,6 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev) if (IS_ERR(gwdt->base)) return PTR_ERR(gwdt->base);- irq = platform_get_irq(pdev, 0);- if (!irq)- return -EINVAL;- gwdt->dev = dev; gwdt->wdd.info = &ftwdt010_wdt_info; gwdt->wdd.ops = &ftwdt010_wdt_ops;
@@ -158,10 +161,14 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev) writel(reg, gwdt->base + FTWDT010_WDCR); }- ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0,- "watchdog bark", gwdt);- if (ret)- return ret;+ irq = platform_get_irq(pdev, 0);+ if (irq) {+ ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0,+ "watchdog bark", gwdt);+ if (ret)+ return ret;+ gwdt->has_irq = true;+ } ret = devm_watchdog_register_device(dev, &gwdt->wdd); if (ret) {
--
2.13.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Aug 12, 2017 at 08:43:11PM +0200, Linus Walleij wrote:
The Gemini platform now provides a proper clock look-up for this
and other IPs, so add clock support to the driver. This also aids
in using the same driver with other platforms such as MOXA ART.
The IP has two clock inputs: PCLK (the IP peripheral clock) and
EXTCLK (an external clock). We are a bit elaborate around this:
on Gemini the EXTCLK is used by default today and it's 5MHz, and
on MOXA ART the PCLK is used. On Aspeed the EXTCLK is used and
it's 1MHz. So add some clever code to fall back to platform
defaults if PCLK or EXTCLK is not provided by the device tree.
Take this opportnity to implement .remove() for the driver that
opportunity
quoted hunk
stops the watchdog and disables the clocks.
Add credits that this code is inspired by MOXA ART.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/ftwdt010_wdt.c | 79 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 71 insertions(+), 8 deletions(-)
+ /* Only enable and get frequency from EXTCLK if it's in use */
+ if (gwdt->use_extclk) {
+ ret = clk_prepare_enable(gwdt->extclk);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "unable to enable EXTCLK\n");
+ return ret;
+ }
+ gwdt->clk_freq = clk_get_rate(gwdt->extclk);
+ }
+ } else {
+ if (of_device_is_compatible(np, "cortina,gemini-watchdog")) {
+ gwdt->clk_freq = 5000000;
+ gwdt->use_extclk = true;
+ dev_info(dev, "assume 5MHz EXTCLK on Gemini\n");
+ }
+ }
+
+ if (gwdt->clk_freq == 0) {
+ dev_err(dev, "no clocking available\n");
+ return -EINVAL;
So far this situation defaulted to 5 MHz (as there was nothing else).
Is this a new restriction or did it just not happen ?
Also, this can at least in theory happen if clk_get_rate() returns 0,
which would leave the clock enabled (although that would be an odd
situation).
devm_watchdog_register_device() can fail, which would leave the clocks
enabled. Also see below.
quoted hunk
/*
@@ -178,7 +226,21 @@ static int ftwdt010_wdt_probe(struct platform_device *pdev) /* Set up platform driver data */ platform_set_drvdata(pdev, gwdt);- dev_info(dev, "FTWDT010 watchdog driver enabled\n");+ dev_info(dev, "FTWDT010 watchdog driver @%uHz\n",+ gwdt->clk_freq);++ return 0;+}++static int ftwdt010_wdt_remove(struct platform_device *pdev)+{+ struct ftwdt010_wdt *gwdt = platform_get_drvdata(pdev);++ writel(0, gwdt->base + FTWDT010_WDCR);+ if (!IS_ERR(gwdt->pclk))+ clk_disable_unprepare(gwdt->pclk);+ if (!IS_ERR(gwdt->extclk) && gwdt->use_extclk)+ clk_disable_unprepare(gwdt->extclk);
One of those many situations where devm_clk_prepare_enable() would have
been very useful :-(. This disables the clocks while the watchdog itself
as well as its interrupt handler is still registered. I don't know if this
will have adverse affects, but it makes me quite concerned. Please consider
adding devm_add_action() calls to clean up the clocks. Note that I would
resist replacing all the devm_ functions with non-devm equivalents just
because the clock subsystem doesn't provide the necessary API functions.
Side note: Maybe we _should_ introduce devm_watchdog_clk_prepare_enable()
since this problem affects several watchdog drivers.
Guenter
--
2.13.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sat, Aug 12, 2017 at 08:43:15PM +0200, Linus Walleij wrote:
quoted hunk
These two drivers is for the same hardware, the only difference
is that Gemini uses the EXTCLK @5MHz by default (it also works
fine using PCLK) while the MOXA ART is using the PCLK to clock
the watchdog.
Delete the old MOXA ART driver and augment the FTWDT010 to
probe on this platform too, fetching the operating frequency
from the PCLK. Select the driver by default for ARCH_MOXART
to make a smooth transition of the platform.
Signed-off-by: Linus Walleij <redacted>
---
drivers/watchdog/Kconfig | 11 +--
drivers/watchdog/Makefile | 1 -
drivers/watchdog/ftwdt010_wdt.c | 1 +
drivers/watchdog/moxart_wdt.c | 178 ----------------------------------------
4 files changed, 2 insertions(+), 189 deletions(-)
delete mode 100644 drivers/watchdog/moxart_wdt.c
Can one have more than one default statement ? What is the semantics ?
Just making sure that it isn't "last one wins".
quoted hunk
help
Say Y here if to include support for the Faraday Technology
FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
@@ -609,16 +610,6 @@ config RETU_WATCHDOG To compile this driver as a module, choose M here: the module will be called retu_wdt.-config MOXART_WDT- tristate "MOXART watchdog"- depends on ARCH_MOXART || COMPILE_TEST- help- Say Y here to include Watchdog timer support for the watchdog- existing on the MOXA ART SoC series platforms.-- To compile this driver as a module, choose M here: the- module will be called moxart_wdt.- config SIRFSOC_WATCHDOG tristate "SiRFSOC watchdog" depends on ARCH_SIRF || COMPILE_TEST
--
2.13.4
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
+ gwdt->pclk = devm_clk_get(dev, "PCLK");
+ if (!IS_ERR(gwdt->pclk)) {
devm_clk_get() can return NULL (if the clock subsystem is not enabled).
That is fine I think? Because if the clock subsysten is not enabled
all the clk_prepare() etc becomes stubs as well and the driver
is happy. I think this is intended.
quoted
+ ret = clk_prepare_enable(gwdt->pclk);
Why enable pclk if extclk is used ?
It is used to clock the silicon in the IP block (so one can access the
registers etc) even if the timer per se uses EXTCLK.
So it must always be enabled.
quoted
+ if (ret) {
+ dev_err(&pdev->dev, "unable to enable PCLK\n");
+ return ret;
+ }
+ if (!gwdt->use_extclk)
+ gwdt->clk_freq = clk_get_rate(gwdt->pclk);
+ } else {
+ dev_info(dev, "PCLK clock not found assume always-on\n");
Those info messages seem more like debug messages to me. Is this and the message
below about 5MHz clock on Gemini really necessary ?
Depends on whether one is pr_info()/dev_info() minimalist or
maximalist or something. I guess the extreme minimalist would be
happiest of their dmesg was 0 lines if all is fine. Maybe it could
just say the Linux version.
I even had the idea to add the subsystem maintainers preference
for this to MAINTAINERS.
I tend to like a bit of blather about the state of things in dmesg,
(as in *info has a purpose) but I'm happy to do whatever the
subsystem maintainer likes.
So I can surely cut a whole slew of them if that is your preference?
quoted
+ gwdt->extclk = devm_clk_get(dev, "EXTCLK");
+ if (!IS_ERR(gwdt->extclk)) {
devm_clk_get() can return NULL.
Same answer: should be fine.
quoted
+ if (gwdt->clk_freq == 0) {
+ dev_err(dev, "no clocking available\n");
+ return -EINVAL;
So far this situation defaulted to 5 MHz (as there was nothing else).
Is this a new restriction or did it just not happen ?
This comes from Jonas' Moxart driver.
I guess this only happens if someone compiles out the
clk subsystem so they get frequency 0 from the stub.
The driver strictly needs this frequency
so we cannot really work without it and it needs to fail
over here.
Also, this can at least in theory happen if clk_get_rate() returns 0,
which would leave the clock enabled (although that would be an odd
situation).
Yeah I should clk_disable_unprepare() on the error path,
thanks. Fixing it.
devm_watchdog_register_device() can fail, which would leave the clocks
enabled. Also see below.
Fixed it.
quoted
+ if (!IS_ERR(gwdt->pclk))
+ clk_disable_unprepare(gwdt->pclk);
+ if (!IS_ERR(gwdt->extclk) && gwdt->use_extclk)
+ clk_disable_unprepare(gwdt->extclk);
One of those many situations where devm_clk_prepare_enable() would have
been very useful :-(. This disables the clocks while the watchdog itself
as well as its interrupt handler is still registered.
Oh hm yeah. I ran into this thing with the IRQs still being
enabled while the clocking get shut off. It is a problem in the
entire kernel. I don't even have a good intuition for what
order the devm_* things get cleaned up, I guess in the
inverse order that one use them in probe()?
I don't know if this
will have adverse affects, but it makes me quite concerned. Please consider
adding devm_add_action() calls to clean up the clocks.
I don't know if that is a very good idea. If we later get proper
devm_* clock disabling functions then that gets messy
to clean up.
Stephen/Mike: what's your opinion?
Note that I would
resist replacing all the devm_ functions with non-devm equivalents just
because the clock subsystem doesn't provide the necessary API functions.
I've seen people do this for this reason though :/
Side note: Maybe we _should_ introduce devm_watchdog_clk_prepare_enable()
since this problem affects several watchdog drivers.
Hmmmmmmmmm a special watchdog primitive may be apropriate.
Dunno what the clk maintainers think?
Stephen/Mike: do you like that or would you rather see a primitive
inside the clock subsystem for this?
Yours,
Linus Walleij
On Mon, Aug 14, 2017 at 5:04 PM, Guenter Roeck [off-list ref] wrote:
On Sat, Aug 12, 2017 at 08:43:16PM +0200, Linus Walleij wrote:
quoted
These two drivers is for the almost the same hardware,
the only differences are:
- The Aspeed IP block has been hacked to use a different
magic value.
- The Aspeed has hard-wired 1MHz to the EXTCLK and
apparently even disabled the use of PCLK for clocking
the block on AST2500.
Confused. I thought the ast2500 is an EC. Am I missing something ?
Sorry I'm confused too now... What is EC?
Can you spell out that acronym, I never heard
it, or forgot it.
Yours,
Linus Walleij
On Mon, Aug 14, 2017 at 5:01 PM, Guenter Roeck [off-list ref] wrote:
On Sat, Aug 12, 2017 at 08:43:09PM +0200, Linus Walleij wrote:
quoted
-config GEMINI_WATCHDOG
- tristate "Gemini watchdog"
- depends on ARCH_GEMINI
+config FTWDT010_WATCHDOG
+ tristate "Faraday Technology FTWDT010 watchdog"
+ depends on ARM || COMPILE_TEST
Did you test this ? I am kind of wary about COMPILE_TEST in watchdog drivers.
I tried to enable that a while ago, and we had to spend a couple of releases
fixing the fallout (even though I had tried to make sure that everything
builds).
Incidentally, yes!
I push my tree to kernelorg where the zeroday autobuilders pick it up
and compile all kind of archs.
I'm pushing the updated patches too.
The big culprit used to be um linux, since it doesn't do MMIO.
But I think that has been solved recently because I don't see
complaints about it anymore.
Yours,
Linus Walleij
From: Stephen Boyd <hidden> Date: 2017-08-25 23:28:46
On 08/24, Linus Walleij wrote:
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
Side note: Maybe we _should_ introduce devm_watchdog_clk_prepare_enable()
since this problem affects several watchdog drivers.
Hmmmmmmmmm a special watchdog primitive may be apropriate.
Dunno what the clk maintainers think?
Stephen/Mike: do you like that or would you rather see a primitive
inside the clock subsystem for this?
devm_clk_prepare_enable() was already proposed and then the
thread went quiet. Re-kickstart it?
I'd still prefer we just disable clks on clk_put(), but Russell
said we needed to fix all non-common clk implementations of the
clk API to do that and then I forgot about the topic (so
anti-climatic). I'm pretty much OK with us merging the temporary
solution. We can churn again later and remove it all once we
convert everything into one CCF.
I'd prefer we also change common clk framework to actually do the
disable on put though so we flush out any issues early. If the
two things are packaged together I would be ultra happy. It's not
like people are going to convert to CCF just so they can get clk
disable on clk_put() as a feature, but at least we can have it as
a feature.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On Thu, Aug 24, 2017 at 10:32:22PM +0200, Linus Walleij wrote:
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
quoted
+ gwdt->pclk = devm_clk_get(dev, "PCLK");
+ if (!IS_ERR(gwdt->pclk)) {
devm_clk_get() can return NULL (if the clock subsystem is not enabled).
That is fine I think? Because if the clock subsysten is not enabled
all the clk_prepare() etc becomes stubs as well and the driver
is happy. I think this is intended.
If I understand your comment below correctly, the driver won't work
without clock subsystem because the clock frequency would in that case
be 0. Why not catch that situation here, or even better make the driver
depends on the clock subsystem ?
quoted
quoted
+ ret = clk_prepare_enable(gwdt->pclk);
Why enable pclk if extclk is used ?
It is used to clock the silicon in the IP block (so one can access the
registers etc) even if the timer per se uses EXTCLK.
So it must always be enabled.
quoted
quoted
+ if (ret) {
+ dev_err(&pdev->dev, "unable to enable PCLK\n");
+ return ret;
+ }
+ if (!gwdt->use_extclk)
+ gwdt->clk_freq = clk_get_rate(gwdt->pclk);
+ } else {
+ dev_info(dev, "PCLK clock not found assume always-on\n");
Those info messages seem more like debug messages to me. Is this and the message
below about 5MHz clock on Gemini really necessary ?
Depends on whether one is pr_info()/dev_info() minimalist or
maximalist or something. I guess the extreme minimalist would be
happiest of their dmesg was 0 lines if all is fine. Maybe it could
just say the Linux version.
I even had the idea to add the subsystem maintainers preference
for this to MAINTAINERS.
I tend to like a bit of blather about the state of things in dmesg,
(as in *info has a purpose) but I'm happy to do whatever the
subsystem maintainer likes.
So I can surely cut a whole slew of them if that is your preference?
Minimalist.
quoted
quoted
+ gwdt->extclk = devm_clk_get(dev, "EXTCLK");
+ if (!IS_ERR(gwdt->extclk)) {
devm_clk_get() can return NULL.
Same answer: should be fine.
quoted
quoted
+ if (gwdt->clk_freq == 0) {
+ dev_err(dev, "no clocking available\n");
+ return -EINVAL;
So far this situation defaulted to 5 MHz (as there was nothing else).
Is this a new restriction or did it just not happen ?
This comes from Jonas' Moxart driver.
I guess this only happens if someone compiles out the
clk subsystem so they get frequency 0 from the stub.
The driver strictly needs this frequency
so we cannot really work without it and it needs to fail
over here.
Repeating from above, doesn't that mean that the driver depends
on the clock subsystem ? Or am I missong some context ?
quoted
Also, this can at least in theory happen if clk_get_rate() returns 0,
which would leave the clock enabled (although that would be an odd
situation).
Yeah I should clk_disable_unprepare() on the error path,
thanks. Fixing it.
quoted
devm_watchdog_register_device() can fail, which would leave the clocks
enabled. Also see below.
Fixed it.
quoted
quoted
+ if (!IS_ERR(gwdt->pclk))
+ clk_disable_unprepare(gwdt->pclk);
+ if (!IS_ERR(gwdt->extclk) && gwdt->use_extclk)
+ clk_disable_unprepare(gwdt->extclk);
One of those many situations where devm_clk_prepare_enable() would have
been very useful :-(. This disables the clocks while the watchdog itself
as well as its interrupt handler is still registered.
Oh hm yeah. I ran into this thing with the IRQs still being
enabled while the clocking get shut off. It is a problem in the
entire kernel. I don't even have a good intuition for what
order the devm_* things get cleaned up, I guess in the
inverse order that one use them in probe()?
Correct.
quoted
I don't know if this
will have adverse affects, but it makes me quite concerned. Please consider
adding devm_add_action() calls to clean up the clocks.
I don't know if that is a very good idea. If we later get proper
devm_* clock disabling functions then that gets messy
to clean up.
No, it is equivalent.
Stephen/Mike: what's your opinion?
quoted
Note that I would
resist replacing all the devm_ functions with non-devm equivalents just
because the clock subsystem doesn't provide the necessary API functions.
I've seen people do this for this reason though :/
Yes, but that doesn't make it better.
Guenter
quoted
Side note: Maybe we _should_ introduce devm_watchdog_clk_prepare_enable()
since this problem affects several watchdog drivers.
Hmmmmmmmmm a special watchdog primitive may be apropriate.
Dunno what the clk maintainers think?
Stephen/Mike: do you like that or would you rather see a primitive
inside the clock subsystem for this?
Yours,
Linus Walleij
On Fri, Aug 25, 2017 at 04:28:46PM -0700, Stephen Boyd wrote:
On 08/24, Linus Walleij wrote:
quoted
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
Side note: Maybe we _should_ introduce devm_watchdog_clk_prepare_enable()
since this problem affects several watchdog drivers.
Hmmmmmmmmm a special watchdog primitive may be apropriate.
Dunno what the clk maintainers think?
Stephen/Mike: do you like that or would you rather see a primitive
inside the clock subsystem for this?
devm_clk_prepare_enable() was already proposed and then the
thread went quiet. Re-kickstart it?
It was propsed several times, and each time it went nowhere.
I got the impression that it won't be accepted, presumably because
it can be misused. I have all but given up on it, and I have it on
my task list to replace pretty much each pair of clk_prepare_enable() /
clk_prepare_disable() calls in the watchdog subsystem with
devm_add_action(). Not that I like that "solution", but life
isn't perfect.
Guenter
I'd still prefer we just disable clks on clk_put(), but Russell
said we needed to fix all non-common clk implementations of the
clk API to do that and then I forgot about the topic (so
anti-climatic). I'm pretty much OK with us merging the temporary
solution. We can churn again later and remove it all once we
convert everything into one CCF.
I'd prefer we also change common clk framework to actually do the
disable on put though so we flush out any issues early. If the
two things are packaged together I would be ultra happy. It's not
like people are going to convert to CCF just so they can get clk
disable on clk_put() as a feature, but at least we can have it as
a feature.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
On Thu, Aug 24, 2017 at 10:41:56PM +0200, Linus Walleij wrote:
On Mon, Aug 14, 2017 at 5:04 PM, Guenter Roeck [off-list ref] wrote:
quoted
On Sat, Aug 12, 2017 at 08:43:16PM +0200, Linus Walleij wrote:
quoted
These two drivers is for the almost the same hardware,
the only differences are:
- The Aspeed IP block has been hacked to use a different
magic value.
- The Aspeed has hard-wired 1MHz to the EXTCLK and
apparently even disabled the use of PCLK for clocking
the block on AST2500.
Confused. I thought the ast2500 is an EC. Am I missing something ?
Sorry I'm confused too now... What is EC?
Can you spell out that acronym, I never heard
it, or forgot it.
Embedded Controller
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Aug 24, 2017 at 10:45:27PM +0200, Linus Walleij wrote:
On Mon, Aug 14, 2017 at 5:01 PM, Guenter Roeck [off-list ref] wrote:
quoted
On Sat, Aug 12, 2017 at 08:43:09PM +0200, Linus Walleij wrote:
quoted
quoted
-config GEMINI_WATCHDOG
- tristate "Gemini watchdog"
- depends on ARCH_GEMINI
+config FTWDT010_WATCHDOG
+ tristate "Faraday Technology FTWDT010 watchdog"
+ depends on ARM || COMPILE_TEST
Did you test this ? I am kind of wary about COMPILE_TEST in watchdog drivers.
I tried to enable that a while ago, and we had to spend a couple of releases
fixing the fallout (even though I had tried to make sure that everything
builds).
Incidentally, yes!
Ok. Note that I though that too, only 0day didn't pick up all corner cases.
Guenter
I push my tree to kernelorg where the zeroday autobuilders pick it up
and compile all kind of archs.
I'm pushing the updated patches too.
The big culprit used to be um linux, since it doesn't do MMIO.
But I think that has been solved recently because I don't see
complaints about it anymore.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-watchdog" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, Aug 27, 2017 at 7:06 PM, Guenter Roeck [off-list ref] wrote:
On Thu, Aug 24, 2017 at 10:32:22PM +0200, Linus Walleij wrote:
quoted
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
quoted
+ gwdt->pclk = devm_clk_get(dev, "PCLK");
+ if (!IS_ERR(gwdt->pclk)) {
devm_clk_get() can return NULL (if the clock subsystem is not enabled).
That is fine I think? Because if the clock subsysten is not enabled
all the clk_prepare() etc becomes stubs as well and the driver
is happy. I think this is intended.
If I understand your comment below correctly, the driver won't work
without clock subsystem because the clock frequency would in that case
be 0. Why not catch that situation here, or even better make the driver
depends on the clock subsystem ?
OK fair enough I can do that.
I think Aspeed is merging its clock driver this kernel cycle
so all variant SoCs actually have clocks.
quoted
The driver strictly needs this frequency
so we cannot really work without it and it needs to fail
over here.
Repeating from above, doesn't that mean that the driver depends
on the clock subsystem ? Or am I missong some context ?
Usually in the kernel, it is acceptable to let stub clocks
kick in when compiling out the clock subsystem.
I think people assume that in this state, all clocks are simply
turned on and at nominal speed, all over the place. So it
usually doesn't matter that it gets compiled out.
But in a sense that is simplistic and as this driver shows
we really do depend on the clocks to run some business
like timers, so in practice it is a bad idea. Clocksources
definately cannot live without their clocks for example.
So I think strictly requireing it is OK.
quoted
quoted
Note that I would
resist replacing all the devm_ functions with non-devm equivalents just
because the clock subsystem doesn't provide the necessary API functions.
I've seen people do this for this reason though :/
Yes, but that doesn't make it better.
Stephen Boyd [off-list ref] wrote:
I'd still prefer we just disable clks on clk_put(),
Which means that devm_clk_get() will do the job
implicitly already.
but Russell
said we needed to fix all non-common clk implementations of the
clk API to do that and then I forgot about the topic (so
anti-climatic). I'm pretty much OK with us merging the temporary
solution.
I guess that means the watchdog-local hack that
Guenther suggested.
But I'm not in any hurry. Instead of solving the simple problem,
why not solve the supercomplicated problem.
So the task is to look over all non generic clock implementations
and make them conform to disabling the clocks on clk_put().
No big deal. (Famous last words.)
How many local clock implementations can there be?
I will look into it.
Yours,
Linus Walleij
So need info from Joel Stanley here:
On Tue, Oct 10, 2017 at 9:51 PM, Linus Walleij [off-list ref] wrote:
On Sun, Aug 27, 2017 at 7:06 PM, Guenter Roeck [off-list ref] wrote:
quoted
On Thu, Aug 24, 2017 at 10:32:22PM +0200, Linus Walleij wrote:
quoted
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
If I understand your comment below correctly, the driver won't work
without clock subsystem because the clock frequency would in that case
be 0. Why not catch that situation here, or even better make the driver
depends on the clock subsystem ?
OK fair enough I can do that.
I think Aspeed is merging its clock driver this kernel cycle
so all variant SoCs actually have clocks.
So when I later in the patch series convert Aspeed to use this driver
we get a problem because Joel is currently working on the clock
driver for Aspeed and it's not ready for merge yet as it looks.
I can of course wait with the Aspeed conversion to use the common
driver.
Also I can slap in a fixed-rate clock in the device tree @1 MHz.
But that is cheating.
So I guess I rest the Aspeed conversion.
Joel: does your clock patch set cover the 1MHz used by
the watchdog EXTCLK?
Yours,
Linus Walleij
On Sat, Aug 12, 2017 at 8:43 PM, Linus Walleij [off-list ref] wrote:
This adds the PCLK clock to the Aspeed watchdog blocks.
I am not directly familiar with the Aspeed clocking, but
since the IP is derived from Faraday FTWDT010 it probably
has the ability to run the watchdog on the PCLK if
desired so to obtain the frequency from it, it needs to
be present in the device tree, and for completeness the
PCLK should also be referenced and enabled anyways.
Take this opportunity to add the "faraday,ftwdt010"
compatible as fallback to the watchdog IP blocks.
Signed-off-by: Linus Walleij <redacted>
Joel could you merge this through the Aspeed tree? I think
the compatible string is completely uncontroversial
(binding ACKed) to add and all should just work fine so we
can slap in "EXTCLK" later as well.
Yours,
Linus Walleij
From: Andrew Jeffery <hidden> Date: 2017-10-11 03:48:06
On Sat, 2017-08-12 at 20:43 +0200, Linus Walleij wrote:
This adds the PCLK clock to the Aspeed watchdog blocks.
I am not directly familiar with the Aspeed clocking, but
since the IP is derived from Faraday FTWDT010 it probably
has the ability to run the watchdog on the PCLK if
desired
This is true for the AST2400, but not the AST2500 where the only option
is EXTCLK (1MHz).
quoted hunk
so to obtain the frequency from it, it needs to
be present in the device tree, and for completeness the
PCLK should also be referenced and enabled anyways.
Take this opportunity to add the "faraday,ftwdt010"
compatible as fallback to the watchdog IP blocks.
Given the comment above, shouldn't we be doing something like the
following instead for each of the watchdogs?
+ faraday,use-extclk;
+ clock-names = "EXTCLK";
Andrew
On Wed, Oct 11, 2017 at 5:48 AM, Andrew Jeffery [off-list ref] wrote:
On Sat, 2017-08-12 at 20:43 +0200, Linus Walleij wrote:
quoted
This adds the PCLK clock to the Aspeed watchdog blocks.
I am not directly familiar with the Aspeed clocking, but
since the IP is derived from Faraday FTWDT010 it probably
has the ability to run the watchdog on the PCLK if
desired
This is true for the AST2400, but not the AST2500 where the only option
is EXTCLK (1MHz).
The IP block/cell certainly has a PCLK even if it cannot be used
to drive the watchdog timer. It is necessary to interface the
SoC interconnect.
quoted
quoted
+ clocks = <&clk_apb>;
+ clock-names = "PCLK";
Given the comment above, shouldn't we be doing something like the
following instead for each of the watchdogs?
+ faraday,use-extclk;
+ clock-names = "EXTCLK";
So that will be added too, later, when there is a 1MHz clock
to reference in the device tree. I guess after Joel's patches.
Yours,
Linus Walleij
From: Andrew Jeffery <hidden> Date: 2017-10-11 07:14:54
On Wed, 2017-10-11 at 08:32 +0200, Linus Walleij wrote:
quoted
On Wed, Oct 11, 2017 at 5:48 AM, Andrew Jeffery [off-list ref] wrote:
On Sat, 2017-08-12 at 20:43 +0200, Linus Walleij wrote:
quoted
This adds the PCLK clock to the Aspeed watchdog blocks.
I am not directly familiar with the Aspeed clocking, but
since the IP is derived from Faraday FTWDT010 it probably
has the ability to run the watchdog on the PCLK if
desired
This is true for the AST2400, but not the AST2500 where the only option
is EXTCLK (1MHz).
The IP block/cell certainly has a PCLK even if it cannot be used
to drive the watchdog timer. It is necessary to interface the
SoC interconnect.
Given the comment above, shouldn't we be doing something like the
following instead for each of the watchdogs?
+???????????????????????????????faraday,use-extclk;
+???????????????????????????????clock-names = "EXTCLK";
So that will be added too, later, when there is a 1MHz clock
to reference in the device tree. I guess after Joel's patches.
Yours,
Linus Walleij
On Wed, Oct 11, 2017 at 4:09 AM, Linus Walleij [off-list ref] wrote:
On Sat, Aug 12, 2017 at 8:43 PM, Linus Walleij [off-list ref] wrote:
quoted
This adds the PCLK clock to the Aspeed watchdog blocks.
I am not directly familiar with the Aspeed clocking, but
since the IP is derived from Faraday FTWDT010 it probably
has the ability to run the watchdog on the PCLK if
desired so to obtain the frequency from it, it needs to
be present in the device tree, and for completeness the
PCLK should also be referenced and enabled anyways.
Take this opportunity to add the "faraday,ftwdt010"
compatible as fallback to the watchdog IP blocks.
Signed-off-by: Linus Walleij <redacted>
Joel could you merge this through the Aspeed tree? I think
the compatible string is completely uncontroversial
(binding ACKed) to add and all should just work fine so we
can slap in "EXTCLK" later as well.
How do the clock-names work? I have been writing the aspeed clk driver
and updating the bindings without clock names, and instead using a
identifier in phandle to reference which clock the device wants.
eg:
clocks = <&syscon 10>;
(I'm travelling over the next few weeks so my replies might be delayed)
Cheers,
Joel
On Wed, Oct 11, 2017 at 4:06 AM, Linus Walleij [off-list ref] wrote:
So need info from Joel Stanley here:
On Tue, Oct 10, 2017 at 9:51 PM, Linus Walleij [off-list ref] wrote:
quoted
On Sun, Aug 27, 2017 at 7:06 PM, Guenter Roeck [off-list ref] wrote:
quoted
On Thu, Aug 24, 2017 at 10:32:22PM +0200, Linus Walleij wrote:
quoted
On Mon, Aug 14, 2017 at 6:05 PM, Guenter Roeck [off-list ref] wrote:
quoted
quoted
If I understand your comment below correctly, the driver won't work
without clock subsystem because the clock frequency would in that case
be 0. Why not catch that situation here, or even better make the driver
depends on the clock subsystem ?
OK fair enough I can do that.
I think Aspeed is merging its clock driver this kernel cycle
so all variant SoCs actually have clocks.
So when I later in the patch series convert Aspeed to use this driver
we get a problem because Joel is currently working on the clock
driver for Aspeed and it's not ready for merge yet as it looks.
I can of course wait with the Aspeed conversion to use the common
driver.
Also I can slap in a fixed-rate clock in the device tree @1 MHz.
But that is cheating.
All of our clocks in the device tree are cheating at the moment :)
So I guess I rest the Aspeed conversion.
Joel: does your clock patch set cover the 1MHz used by
the watchdog EXTCLK?
It doesn't; none of the documentation I have describes where it comes
from. I will add something in the next iteration.
Cheers,
Joel
On Thu, Oct 12, 2017 at 5:37 AM, Joel Stanley [off-list ref] wrote:
On Wed, Oct 11, 2017 at 4:09 AM, Linus Walleij [off-list ref] wrote:
quoted
Joel could you merge this through the Aspeed tree? I think
the compatible string is completely uncontroversial
(binding ACKed) to add and all should just work fine so we
can slap in "EXTCLK" later as well.
How do the clock-names work? I have been writing the aspeed clk driver
and updating the bindings without clock names, and instead using a
identifier in phandle to reference which clock the device wants.
eg:
clocks = <&syscon 10>;
This works fine as long as there is just one clock.
clocks = <&syscon 10>, <&syscon 11>, <&syscon 12>;
becomes a problem, right?
clk_get() has this signature:
struct clk *clk_get(struct device *dev, const char *id);
So clk_get(dev, NULL); will return <&syscon 10>;
How to get the rest?
clocks = <&syscon 10>, <&syscon 11>, <&syscon 12>;
clock-names = "FOO", "BAR", "BAZ";
clk_get(dev, "BAR");
gets the second clock.
Yours,
Linus Walleij