[PATCH v2 1/1] watchdog: mtk_wdt: Remove mtk_wdt_stop() in probe() to prevent the system freeze and it doesn't reboot by watchdog problem

2020-12-30 Thread Freddy Hsin
From: "freddy.hsin" 

Before user space daemon start to access the watchdog device,
there is a time interval that watchdog is disabled in the
original flow. If the system freezing at this interval, it
cannot be rebooted by watchdog hardware automatically.

In order to solve this problem, the watchdog hardware should be
kept working, and start hrtimer in framework to ping it by
setting max_hw_heartbeat_ms and HW_RUNNING used in
watchdog_need_worker to determine whether the worker should be
started or not. Besides the redundant setting of max_timeout is
also removed.

Signed-off-by: freddy.hsin 
---
 drivers/watchdog/mtk_wdt.c |   17 +++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index d6a6393..0c869b7 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -195,6 +195,19 @@ static int mtk_wdt_set_timeout(struct watchdog_device 
*wdt_dev,
return 0;
 }
 
+static void mtk_wdt_init(struct watchdog_device *wdt_dev)
+{
+   struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+   void __iomem *wdt_base;
+
+   wdt_base = mtk_wdt->wdt_base;
+
+   if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN) {
+   set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
+   mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
+   }
+}
+
 static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
 {
struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
@@ -264,7 +277,7 @@ static int mtk_wdt_probe(struct platform_device *pdev)
mtk_wdt->wdt_dev.info = &mtk_wdt_info;
mtk_wdt->wdt_dev.ops = &mtk_wdt_ops;
mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
-   mtk_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT;
+   mtk_wdt->wdt_dev.max_hw_heartbeat_ms = WDT_MAX_TIMEOUT * 1000;
mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT;
mtk_wdt->wdt_dev.parent = dev;
 
@@ -274,7 +287,7 @@ static int mtk_wdt_probe(struct platform_device *pdev)
 
watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
 
-   mtk_wdt_stop(&mtk_wdt->wdt_dev);
+   mtk_wdt_init(&mtk_wdt->wdt_dev);
 
watchdog_stop_on_reboot(&mtk_wdt->wdt_dev);
err = devm_watchdog_register_device(dev, &mtk_wdt->wdt_dev);
-- 
1.7.9.5



driver: watchdog: Remove mtk_wdt_stop() in probe() to prevent the system freeze and it doesn't reboot by watchdog problem

2020-12-24 Thread Freddy Hsin
Before user space daemon start to access the watchdog device,
there is a time interval that watchdog is disabled in the
original flow. If the system freezing at this interval, it
cannot be rebooted by watchdog hardware automatically.

In order to solve this problem, the watchdog hardware should be
kept working, and start hrtimer in framework to ping it by
setting max_hw_heartbeat_ms and HW_RUNNING used in
watchdog_need_worker to determine whether the worker should be
started or not



[PATCH v1 1/1] driver: watchdog: Remove mtk_wdt_stop() in probe() to prevent the system freeze and it doesn't reboot by watchdog problem

2020-12-24 Thread Freddy Hsin
From: "freddy.hsin" 

Before user space daemon start to access the watchdog device,
there is a time interval that watchdog is disabled in the
original flow. If the system freezing at this interval, it
cannot be rebooted by watchdog hardware automatically.

In order to solve this problem, the watchdog hardware should be
kept working, and start hrtimer in framework to ping it by
setting max_hw_heartbeat_ms and HW_RUNNING used in
watchdog_need_worker to determine whether the worker should be
started or not

Change-Id: I6a041b0922888a90011d7538ee804d80bc8d15ea
Signed-off-by: freddy.hsin 
---
 drivers/watchdog/mtk_wdt.c |   22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index d6a6393..62f08cd 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -195,6 +195,19 @@ static int mtk_wdt_set_timeout(struct watchdog_device 
*wdt_dev,
return 0;
 }
 
+static void mtk_wdt_init(struct watchdog_device *wdt_dev)
+{
+   struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+   void __iomem *wdt_base;
+
+   wdt_base = mtk_wdt->wdt_base;
+
+   if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN) {
+   set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
+   mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout);
+   }
+}
+
 static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
 {
struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
@@ -266,16 +279,17 @@ static int mtk_wdt_probe(struct platform_device *pdev)
mtk_wdt->wdt_dev.timeout = WDT_MAX_TIMEOUT;
mtk_wdt->wdt_dev.max_timeout = WDT_MAX_TIMEOUT;
mtk_wdt->wdt_dev.min_timeout = WDT_MIN_TIMEOUT;
+   mtk_wdt->wdt_dev.max_hw_heartbeat_ms = (WDT_MAX_TIMEOUT - 1) * 1000;
mtk_wdt->wdt_dev.parent = dev;
 
+   watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
+
+   mtk_wdt_init(&mtk_wdt->wdt_dev);
+
watchdog_init_timeout(&mtk_wdt->wdt_dev, timeout, dev);
watchdog_set_nowayout(&mtk_wdt->wdt_dev, nowayout);
watchdog_set_restart_priority(&mtk_wdt->wdt_dev, 128);
 
-   watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
-
-   mtk_wdt_stop(&mtk_wdt->wdt_dev);
-
watchdog_stop_on_reboot(&mtk_wdt->wdt_dev);
err = devm_watchdog_register_device(dev, &mtk_wdt->wdt_dev);
if (unlikely(err))
-- 
1.7.9.5



[PATCH v1 1/1] timer: mt6873: remove COMPILE_TEST condition for MTK timer

2020-08-27 Thread Freddy Hsin
MTK timer driver can work on MTK platform normally, so remove
the redundant condition for MTK_TIMER

Signed-off-by: Freddy Hsin 
---
 drivers/clocksource/Kconfig |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9141838..1ec5d94 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -472,7 +472,7 @@ config SYS_SUPPORTS_SH_CMT
bool
 
 config MTK_TIMER
-   bool "Mediatek timer driver" if COMPILE_TEST
+   bool "Mediatek timer driver"
depends on HAS_IOMEM
select TIMER_OF
select CLKSRC_MMIO
-- 
1.7.9.5


[PATCH 0/1] Remove redundant condition for MTK_TIMER

2020-08-27 Thread Freddy Hsin
Remove the redundant condition of MTK_TIMER because the driver
can work on MTK platform normally, so COMPILE_TEST is no longer
needed for development purpose

Freddy Hsin (1):
  timer: mt6873: remove COMPILE_TEST condition for MTK timer

 drivers/clocksource/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[PATCH 0/1] Refine mtk wdt driver init flow

2020-08-28 Thread Freddy Hsin
Add mtk_wdt_init() functin in probe flow to determine
enable/disable the hw watchdog by its original setting

Freddy Hsin (1):
  driver: watchdog: Add mtk_wdt_init for mediatek watchdog hw init

 drivers/watchdog/mtk_wdt.c |   22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)


[PATCH v1 1/1] driver: watchdog: Add mtk_wdt_init for mediatek watchdog hw init

2020-08-28 Thread Freddy Hsin
1. add a hw initialization function
2. enable/disable the watchdog depends on the original hw setting
3. set WDOD_HW_RUNNING in start function in order to start
   kicker after driver probe and clear the bit in stop function

Change-Id: I25aa797f3b88288f26984455e499e599e27f09fa
Signed-off-by: Freddy Hsin 
---
 drivers/watchdog/mtk_wdt.c |   22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c
index d6a6393..59b5061 100644
--- a/drivers/watchdog/mtk_wdt.c
+++ b/drivers/watchdog/mtk_wdt.c
@@ -57,6 +57,9 @@
 static bool nowayout = WATCHDOG_NOWAYOUT;
 static unsigned int timeout;
 
+static int mtk_wdt_start(struct watchdog_device *wdt_dev);
+static int mtk_wdt_stop(struct watchdog_device *wdt_dev);
+
 struct mtk_wdt_dev {
struct watchdog_device wdt_dev;
void __iomem *wdt_base;
@@ -148,6 +151,19 @@ static int toprgu_register_reset_controller(struct 
platform_device *pdev,
return ret;
 }
 
+static int mtk_wdt_init(struct watchdog_device *wdt_dev)
+{
+   struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev);
+   void __iomem *wdt_base;
+
+   wdt_base = mtk_wdt->wdt_base;
+
+   if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN)
+   mtk_wdt_start(wdt_dev);
+   else
+   mtk_wdt_stop(wdt_dev);
+}
+
 static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
   unsigned long action, void *data)
 {
@@ -206,6 +222,8 @@ static int mtk_wdt_stop(struct watchdog_device *wdt_dev)
reg |= WDT_MODE_KEY;
iowrite32(reg, wdt_base + WDT_MODE);
 
+   clear_bit(WDOG_HW_RUNNING, &wdt_dev->status);
+
return 0;
 }
 
@@ -225,6 +243,8 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev)
reg |= (WDT_MODE_EN | WDT_MODE_KEY);
iowrite32(reg, wdt_base + WDT_MODE);
 
+   set_bit(WDOG_HW_RUNNING, &wdt_dev->status);
+
return 0;
 }
 
@@ -274,7 +294,7 @@ static int mtk_wdt_probe(struct platform_device *pdev)
 
watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt);
 
-   mtk_wdt_stop(&mtk_wdt->wdt_dev);
+   mtk_wdt_init(&mtk_wdt->wdt_dev);
 
watchdog_stop_on_reboot(&mtk_wdt->wdt_dev);
err = devm_watchdog_register_device(dev, &mtk_wdt->wdt_dev);
-- 
1.7.9.5


[PATCH v1 1/2] kernel: time: export sched_clock_register function

2020-07-28 Thread Freddy Hsin
export sched_clock_register function, because the Mediatek timer
loadable module depends on this function

Signed-off-by: Freddy Hsin 
---
 kernel/time/sched_clock.c |1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/time/sched_clock.c b/kernel/time/sched_clock.c
index fa3f800..e1d5afe 100644
--- a/kernel/time/sched_clock.c
+++ b/kernel/time/sched_clock.c
@@ -239,6 +239,7 @@ static enum hrtimer_restart sched_clock_poll(struct hrtimer 
*hrt)
 
pr_debug("Registered %pS as sched_clock source\n", read);
 }
+EXPORT_SYMBOL(sched_clock_register);
 
 void __init generic_sched_clock_init(void)
 {
-- 
1.7.9.5


[PATCH v1] Porting Mediatek timer driver to kernel module

2020-07-28 Thread Freddy Hsin
Porting Mediatek timer driver to kernel module for GKI
(Generic Kernel Image). Clocksource mmio functions are
exported for Mediatek timer init function.

This patch depends on the timer-of patch submitted by Baolin Wang
https://lkml.org/lkml/2020/3/24/72


Freddy Hsin (2):
  kernel: time: remove init section label of sched_clock_register
  timer: mt6873: porting timer driver to loadable module

 drivers/clocksource/Kconfig  |2 +-
 drivers/clocksource/mmio.c   |4 +++-
 drivers/clocksource/timer-mediatek.c |   39 ++
 kernel/time/sched_clock.c|1 +

[PATCH v1 2/2] timer: mt6873: porting Mediatek timer driver to loadable module

2020-07-28 Thread Freddy Hsin
porting Mediatek timer driver to loadable module

Signed-off-by: Freddy Hsin 
---
 drivers/clocksource/Kconfig  |2 +-
 drivers/clocksource/mmio.c   |4 +++-
 drivers/clocksource/timer-mediatek.c |   39 ++
 3 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9141838..538351a 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -472,7 +472,7 @@ config SYS_SUPPORTS_SH_CMT
bool
 
 config MTK_TIMER
-   bool "Mediatek timer driver" if COMPILE_TEST
+   tristate "Mediatek timer driver"
depends on HAS_IOMEM
select TIMER_OF
select CLKSRC_MMIO
diff --git a/drivers/clocksource/mmio.c b/drivers/clocksource/mmio.c
index 9de7515..5504569 100644
--- a/drivers/clocksource/mmio.c
+++ b/drivers/clocksource/mmio.c
@@ -21,6 +21,7 @@ u64 clocksource_mmio_readl_up(struct clocksource *c)
 {
return (u64)readl_relaxed(to_mmio_clksrc(c)->reg);
 }
+EXPORT_SYMBOL(clocksource_mmio_readl_up);
 
 u64 clocksource_mmio_readl_down(struct clocksource *c)
 {
@@ -46,7 +47,7 @@ u64 clocksource_mmio_readw_down(struct clocksource *c)
  * @bits:  Number of valid bits
  * @read:  One of clocksource_mmio_read*() above
  */
-int __init clocksource_mmio_init(void __iomem *base, const char *name,
+int clocksource_mmio_init(void __iomem *base, const char *name,
unsigned long hz, int rating, unsigned bits,
u64 (*read)(struct clocksource *))
 {
@@ -68,3 +69,4 @@ int __init clocksource_mmio_init(void __iomem *base, const 
char *name,
 
return clocksource_register_hz(&cs->clksrc, hz);
 }
+EXPORT_SYMBOL(clocksource_mmio_init);
diff --git a/drivers/clocksource/timer-mediatek.c 
b/drivers/clocksource/timer-mediatek.c
index 9318edc..5c89b6b 100644
--- a/drivers/clocksource/timer-mediatek.c
+++ b/drivers/clocksource/timer-mediatek.c
@@ -13,6 +13,9 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include "timer-of.h"
@@ -309,5 +312,41 @@ static int __init mtk_gpt_init(struct device_node *node)
 
return 0;
 }
+
+#ifdef MODULE
+static int mtk_timer_probe(struct platform_device *pdev)
+{
+   int (*timer_init)(struct device_node *node);
+   struct device_node *np = pdev->dev.of_node;
+
+   timer_init = of_device_get_match_data(&pdev->dev);
+   return timer_init(np);
+}
+
+static const struct of_device_id mtk_timer_match_table[] = {
+   {
+   .compatible = "mediatek,mt6577-timer",
+   .data = mtk_gpt_init,
+   },
+   {
+   .compatible = "mediatek,mt6765-timer",
+   .data = mtk_syst_init,
+   },
+   {}
+};
+
+static struct platform_driver mtk_timer_driver = {
+   .probe = mtk_timer_probe,
+   .driver = {
+   .name = "mtk-timer",
+   .of_match_table = mtk_timer_match_table,
+   },
+};
+MODULE_DESCRIPTION("MEDIATEK Module timer driver");
+MODULE_LICENSE("GPL v2");
+
+module_platform_driver(mtk_timer_driver);
+#else
 TIMER_OF_DECLARE(mtk_mt6577, "mediatek,mt6577-timer", mtk_gpt_init);
 TIMER_OF_DECLARE(mtk_mt6765, "mediatek,mt6765-timer", mtk_syst_init);
+#endif
-- 
1.7.9.5