2222#include <linux/types.h>
2323#include <linux/kernel.h>
2424#include <linux/fs.h>
25+ #include <linux/platform_device.h>
2526#include <linux/miscdevice.h>
2627#include <linux/watchdog.h>
2728#include <linux/init.h>
3031#include <linux/uaccess.h>
3132#include <linux/timex.h>
3233
33- #ifdef CONFIG_ARCH_PXA
34- #include <mach/regs-ost.h>
35- #endif
34+ #define REG_OSMR0 0x0000 /* OS timer Match Reg. 0 */
35+ #define REG_OSMR1 0x0004 /* OS timer Match Reg. 1 */
36+ #define REG_OSMR2 0x0008 /* OS timer Match Reg. 2 */
37+ #define REG_OSMR3 0x000c /* OS timer Match Reg. 3 */
38+ #define REG_OSCR 0x0010 /* OS timer Counter Reg. */
39+ #define REG_OSSR 0x0014 /* OS timer Status Reg. */
40+ #define REG_OWER 0x0018 /* OS timer Watch-dog Enable Reg. */
41+ #define REG_OIER 0x001C /* OS timer Interrupt Enable Reg. */
3642
37- #include <mach/reset.h>
43+ #define OSSR_M3 (1 << 3) /* Match status channel 3 */
44+ #define OSSR_M2 (1 << 2) /* Match status channel 2 */
45+ #define OSSR_M1 (1 << 1) /* Match status channel 1 */
46+ #define OSSR_M0 (1 << 0) /* Match status channel 0 */
47+
48+ #define OWER_WME (1 << 0) /* Watchdog Match Enable */
49+
50+ #define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
51+ #define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
52+ #define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
53+ #define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
3854
3955static unsigned long oscr_freq ;
4056static unsigned long sa1100wdt_users ;
4157static unsigned int pre_margin ;
4258static int boot_status ;
59+ static void __iomem * reg_base ;
60+
61+ static inline void sa1100_wr (u32 val , u32 offset )
62+ {
63+ writel_relaxed (val , reg_base + offset );
64+ }
65+
66+ static inline u32 sa1100_rd (u32 offset )
67+ {
68+ return readl_relaxed (reg_base + offset );
69+ }
4370
4471/*
4572 * Allow only one person to hold it open
@@ -50,18 +77,18 @@ static int sa1100dog_open(struct inode *inode, struct file *file)
5077 return - EBUSY ;
5178
5279 /* Activate SA1100 Watchdog timer */
53- writel_relaxed ( readl_relaxed ( OSCR ) + pre_margin , OSMR3 );
54- writel_relaxed (OSSR_M3 , OSSR );
55- writel_relaxed (OWER_WME , OWER );
56- writel_relaxed ( readl_relaxed ( OIER ) | OIER_E3 , OIER );
80+ sa1100_wr ( sa1100_rd ( REG_OSCR ) + pre_margin , REG_OSMR3 );
81+ sa1100_wr (OSSR_M3 , REG_OSSR );
82+ sa1100_wr (OWER_WME , REG_OWER );
83+ sa1100_wr ( sa1100_rd ( REG_OIER ) | OIER_E3 , REG_OIER );
5784 return stream_open (inode , file );
5885}
5986
6087/*
6188 * The watchdog cannot be disabled.
6289 *
6390 * Previous comments suggested that turning off the interrupt by
64- * clearing OIER [E3] would prevent the watchdog timing out but this
91+ * clearing REG_OIER [E3] would prevent the watchdog timing out but this
6592 * does not appear to be true (at least on the PXA255).
6693 */
6794static int sa1100dog_release (struct inode * inode , struct file * file )
@@ -76,7 +103,7 @@ static ssize_t sa1100dog_write(struct file *file, const char __user *data,
76103{
77104 if (len )
78105 /* Refresh OSMR3 timer. */
79- writel_relaxed ( readl_relaxed ( OSCR ) + pre_margin , OSMR3 );
106+ sa1100_wr ( sa1100_rd ( REG_OSCR ) + pre_margin , REG_OSMR3 );
80107 return len ;
81108}
82109
@@ -110,7 +137,7 @@ static long sa1100dog_ioctl(struct file *file, unsigned int cmd,
110137 break ;
111138
112139 case WDIOC_KEEPALIVE :
113- writel_relaxed ( readl_relaxed ( OSCR ) + pre_margin , OSMR3 );
140+ sa1100_wr ( sa1100_rd ( REG_OSCR ) + pre_margin , REG_OSMR3 );
114141 ret = 0 ;
115142 break ;
116143
@@ -125,7 +152,7 @@ static long sa1100dog_ioctl(struct file *file, unsigned int cmd,
125152 }
126153
127154 pre_margin = oscr_freq * time ;
128- writel_relaxed ( readl_relaxed ( OSCR ) + pre_margin , OSMR3 );
155+ sa1100_wr ( sa1100_rd ( REG_OSCR ) + pre_margin , REG_OSMR3 );
129156 fallthrough ;
130157
131158 case WDIOC_GETTIMEOUT :
@@ -151,12 +178,22 @@ static struct miscdevice sa1100dog_miscdev = {
151178 .fops = & sa1100dog_fops ,
152179};
153180
154- static int margin __initdata = 60 ; /* (secs) Default is 1 minute */
181+ static int margin = 60 ; /* (secs) Default is 1 minute */
155182static struct clk * clk ;
156183
157- static int __init sa1100dog_init ( void )
184+ static int sa1100dog_probe ( struct platform_device * pdev )
158185{
159186 int ret ;
187+ int * platform_data ;
188+ struct resource * res ;
189+
190+ res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
191+ if (!res )
192+ return - ENXIO ;
193+ reg_base = devm_ioremap (& pdev -> dev , res -> start , resource_size (res ));
194+ ret = PTR_ERR_OR_ZERO (reg_base );
195+ if (ret )
196+ return ret ;
160197
161198 clk = clk_get (NULL , "OSTIMER0" );
162199 if (IS_ERR (clk )) {
@@ -174,13 +211,9 @@ static int __init sa1100dog_init(void)
174211
175212 oscr_freq = clk_get_rate (clk );
176213
177- /*
178- * Read the reset status, and save it for later. If
179- * we suspend, RCSR will be cleared, and the watchdog
180- * reset reason will be lost.
181- */
182- boot_status = (reset_status & RESET_STATUS_WATCHDOG ) ?
183- WDIOF_CARDRESET : 0 ;
214+ platform_data = pdev -> dev .platform_data ;
215+ if (platform_data && * platform_data )
216+ boot_status = WDIOF_CARDRESET ;
184217 pre_margin = oscr_freq * margin ;
185218
186219 ret = misc_register (& sa1100dog_miscdev );
@@ -196,15 +229,21 @@ static int __init sa1100dog_init(void)
196229 return ret ;
197230}
198231
199- static void __exit sa1100dog_exit ( void )
232+ static int sa1100dog_remove ( struct platform_device * pdev )
200233{
201234 misc_deregister (& sa1100dog_miscdev );
202235 clk_disable_unprepare (clk );
203236 clk_put (clk );
237+
238+ return 0 ;
204239}
205240
206- module_init (sa1100dog_init );
207- module_exit (sa1100dog_exit );
241+ struct platform_driver sa1100dog_driver = {
242+ .driver .name = "sa1100_wdt" ,
243+ .probe = sa1100dog_probe ,
244+ .remove = sa1100dog_remove ,
245+ };
246+ module_platform_driver (sa1100dog_driver );
208247
209248MODULE_AUTHOR (
"Oleg Drokin <[email protected] >" );
210249MODULE_DESCRIPTION ("SA1100/PXA2xx Watchdog" );
0 commit comments