diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-03 13:23:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-03-03 13:23:29 -0500 |
commit | 68b86a25225d03f134f306caffc46df80906c3f8 (patch) | |
tree | d5f6556e07e3fb376199c2ba70153c17d47b7607 /drivers/rtc/rtc-stmp3xxx.c | |
parent | 527c680f7c36ff17d49efc99632232dba3549c51 (diff) | |
parent | 41e9f3f71bc7a5d41a2b925cfdc0dc22a77f7d8c (diff) |
Merge git://www.linux-watchdog.org/linux-watchdog
Pull watchdog updates from Wim Van Sebroeck:
"This contains:
- fixes and improvements
- devicetree bindings
- conversion to watchdog generic framework of the following drivers:
- booke_wdt
- bcm47xx_wdt.c
- at91sam9_wdt
- Removal of old STMP3xxx driver
- Addition of following new drivers:
- new driver for STMP3xxx and i.MX23/28
- Retu watchdog driver"
* git://www.linux-watchdog.org/linux-watchdog: (30 commits)
watchdog: sp805_wdt depends on ARM
watchdog: davinci_wdt: update to devm_* API
watchdog: davinci_wdt: use devm managed clk get
watchdog: at91rm9200: add DT support
watchdog: add timeout-sec property binding
watchdog: at91sam9_wdt: Convert to use the watchdog framework
watchdog: omap_wdt: Add option nowayout
watchdog: core: dt: add support for the timeout-sec dt property
watchdog: bcm47xx_wdt.c: add hard timer
watchdog: bcm47xx_wdt.c: rename wdt_time to timeout
watchdog: bcm47xx_wdt.c: rename ops methods
watchdog: bcm47xx_wdt.c: use platform device
watchdog: bcm47xx_wdt.c: convert to watchdog core api
watchdog: Convert BookE watchdog driver to watchdog infrastructure
watchdog: s3c2410_wdt: Use devm_* functions
watchdog: remove old STMP3xxx driver
watchdog: add new driver for STMP3xxx and i.MX23/28
rtc: stmp3xxx: add wdt-accessor function
watchdog: introduce retu_wdt driver
watchdog: intel_scu_watchdog: fix Kconfig dependency
...
Diffstat (limited to 'drivers/rtc/rtc-stmp3xxx.c')
-rw-r--r-- | drivers/rtc/rtc-stmp3xxx.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/rtc/rtc-stmp3xxx.c b/drivers/rtc/rtc-stmp3xxx.c index b2a8ed99b2bf..98f0d3c30738 100644 --- a/drivers/rtc/rtc-stmp3xxx.c +++ b/drivers/rtc/rtc-stmp3xxx.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
29 | #include <linux/of.h> | 29 | #include <linux/of.h> |
30 | #include <linux/stmp_device.h> | ||
31 | #include <linux/stmp3xxx_rtc_wdt.h> | ||
30 | 32 | ||
31 | #include <mach/common.h> | 33 | #include <mach/common.h> |
32 | 34 | ||
@@ -36,6 +38,7 @@ | |||
36 | #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 | 38 | #define STMP3XXX_RTC_CTRL_ALARM_IRQ_EN 0x00000001 |
37 | #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 | 39 | #define STMP3XXX_RTC_CTRL_ONEMSEC_IRQ_EN 0x00000002 |
38 | #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 | 40 | #define STMP3XXX_RTC_CTRL_ALARM_IRQ 0x00000004 |
41 | #define STMP3XXX_RTC_CTRL_WATCHDOGEN 0x00000010 | ||
39 | 42 | ||
40 | #define STMP3XXX_RTC_STAT 0x10 | 43 | #define STMP3XXX_RTC_STAT 0x10 |
41 | #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 | 44 | #define STMP3XXX_RTC_STAT_STALE_SHIFT 16 |
@@ -45,6 +48,8 @@ | |||
45 | 48 | ||
46 | #define STMP3XXX_RTC_ALARM 0x40 | 49 | #define STMP3XXX_RTC_ALARM 0x40 |
47 | 50 | ||
51 | #define STMP3XXX_RTC_WATCHDOG 0x50 | ||
52 | |||
48 | #define STMP3XXX_RTC_PERSISTENT0 0x60 | 53 | #define STMP3XXX_RTC_PERSISTENT0 0x60 |
49 | #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 | 54 | #define STMP3XXX_RTC_PERSISTENT0_SET 0x64 |
50 | #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 | 55 | #define STMP3XXX_RTC_PERSISTENT0_CLR 0x68 |
@@ -52,12 +57,70 @@ | |||
52 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 | 57 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_EN 0x00000004 |
53 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 | 58 | #define STMP3XXX_RTC_PERSISTENT0_ALARM_WAKE 0x00000080 |
54 | 59 | ||
60 | #define STMP3XXX_RTC_PERSISTENT1 0x70 | ||
61 | /* missing bitmask in headers */ | ||
62 | #define STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER 0x80000000 | ||
63 | |||
55 | struct stmp3xxx_rtc_data { | 64 | struct stmp3xxx_rtc_data { |
56 | struct rtc_device *rtc; | 65 | struct rtc_device *rtc; |
57 | void __iomem *io; | 66 | void __iomem *io; |
58 | int irq_alarm; | 67 | int irq_alarm; |
59 | }; | 68 | }; |
60 | 69 | ||
70 | #if IS_ENABLED(CONFIG_STMP3XXX_RTC_WATCHDOG) | ||
71 | /** | ||
72 | * stmp3xxx_wdt_set_timeout - configure the watchdog inside the STMP3xxx RTC | ||
73 | * @dev: the parent device of the watchdog (= the RTC) | ||
74 | * @timeout: the desired value for the timeout register of the watchdog. | ||
75 | * 0 disables the watchdog | ||
76 | * | ||
77 | * The watchdog needs one register and two bits which are in the RTC domain. | ||
78 | * To handle the resource conflict, the RTC driver will create another | ||
79 | * platform_device for the watchdog driver as a child of the RTC device. | ||
80 | * The watchdog driver is passed the below accessor function via platform_data | ||
81 | * to configure the watchdog. Locking is not needed because accessing SET/CLR | ||
82 | * registers is atomic. | ||
83 | */ | ||
84 | |||
85 | static void stmp3xxx_wdt_set_timeout(struct device *dev, u32 timeout) | ||
86 | { | ||
87 | struct stmp3xxx_rtc_data *rtc_data = dev_get_drvdata(dev); | ||
88 | |||
89 | if (timeout) { | ||
90 | writel(timeout, rtc_data->io + STMP3XXX_RTC_WATCHDOG); | ||
91 | writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, | ||
92 | rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_SET); | ||
93 | writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, | ||
94 | rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_SET); | ||
95 | } else { | ||
96 | writel(STMP3XXX_RTC_CTRL_WATCHDOGEN, | ||
97 | rtc_data->io + STMP3XXX_RTC_CTRL + STMP_OFFSET_REG_CLR); | ||
98 | writel(STMP3XXX_RTC_PERSISTENT1_FORCE_UPDATER, | ||
99 | rtc_data->io + STMP3XXX_RTC_PERSISTENT1 + STMP_OFFSET_REG_CLR); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static struct stmp3xxx_wdt_pdata wdt_pdata = { | ||
104 | .wdt_set_timeout = stmp3xxx_wdt_set_timeout, | ||
105 | }; | ||
106 | |||
107 | static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) | ||
108 | { | ||
109 | struct platform_device *wdt_pdev = | ||
110 | platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id); | ||
111 | |||
112 | if (wdt_pdev) { | ||
113 | wdt_pdev->dev.parent = &rtc_pdev->dev; | ||
114 | wdt_pdev->dev.platform_data = &wdt_pdata; | ||
115 | platform_device_add(wdt_pdev); | ||
116 | } | ||
117 | } | ||
118 | #else | ||
119 | static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev) | ||
120 | { | ||
121 | } | ||
122 | #endif /* CONFIG_STMP3XXX_RTC_WATCHDOG */ | ||
123 | |||
61 | static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) | 124 | static void stmp3xxx_wait_time(struct stmp3xxx_rtc_data *rtc_data) |
62 | { | 125 | { |
63 | /* | 126 | /* |
@@ -233,6 +296,7 @@ static int stmp3xxx_rtc_probe(struct platform_device *pdev) | |||
233 | goto out_irq_alarm; | 296 | goto out_irq_alarm; |
234 | } | 297 | } |
235 | 298 | ||
299 | stmp3xxx_wdt_register(pdev); | ||
236 | return 0; | 300 | return 0; |
237 | 301 | ||
238 | out_irq_alarm: | 302 | out_irq_alarm: |