Skip to content

Commit e86bd43

Browse files
committed
watchdog: sa1100: use platform device registration
Rather than relying on machine specific headers to pass down the reboot status and the register locations, use resources and platform_data. Aside from this, keep the changes to a minimum. Cc: Wim Van Sebroeck <[email protected]> Cc: [email protected] Acked-by: Guenter Roeck <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]>
1 parent ee84cbd commit e86bd43

File tree

10 files changed

+83
-35
lines changed

10 files changed

+83
-35
lines changed

arch/arm/mach-pxa/devices.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <linux/platform_data/mmp_dma.h>
2525
#include <linux/platform_data/mtd-nand-pxa3xx.h>
2626

27+
#include <mach/regs-ost.h>
28+
#include <mach/reset.h>
2729
#include "devices.h"
2830
#include "generic.h"
2931

@@ -1118,3 +1120,12 @@ void __init pxa2xx_set_dmac_info(struct mmp_dma_platdata *dma_pdata)
11181120
{
11191121
pxa_register_device(&pxa2xx_pxa_dma, dma_pdata);
11201122
}
1123+
1124+
void __init pxa_register_wdt(unsigned int reset_status)
1125+
{
1126+
struct resource res = DEFINE_RES_MEM(OST_PHYS, OST_LEN);
1127+
1128+
reset_status &= RESET_STATUS_WATCHDOG;
1129+
platform_device_register_resndata(NULL, "sa1100_wdt", -1, &res, 1,
1130+
&reset_status, sizeof(reset_status));
1131+
}

arch/arm/mach-pxa/include/mach/regs-ost.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
/*
88
* OS Timer & Match Registers
99
*/
10+
#define OST_PHYS 0x40A00000
11+
#define OST_LEN 0x00000020
1012

1113
#define OSMR0 io_p2v(0x40A00000) /* */
1214
#define OSMR1 io_p2v(0x40A00004) /* */

arch/arm/mach-pxa/include/mach/reset.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
#define RESET_STATUS_GPIO (1 << 3) /* GPIO Reset */
99
#define RESET_STATUS_ALL (0xf)
1010

11-
extern unsigned int reset_status;
1211
extern void clear_reset_status(unsigned int mask);
12+
extern void pxa_register_wdt(unsigned int reset_status);
1313

1414
/**
1515
* init_gpio_reset() - register GPIO as reset generator

arch/arm/mach-pxa/pxa25x.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ static int __init pxa25x_init(void)
240240

241241
if (cpu_is_pxa25x()) {
242242

243-
reset_status = RCSR;
243+
pxa_register_wdt(RCSR);
244244

245245
pxa25x_init_pm();
246246

arch/arm/mach-pxa/pxa27x.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ static int __init pxa27x_init(void)
337337

338338
if (cpu_is_pxa27x()) {
339339

340-
reset_status = RCSR;
340+
pxa_register_wdt(RCSR);
341341

342342
pxa27x_init_pm();
343343

arch/arm/mach-pxa/pxa3xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ static int __init pxa3xx_init(void)
463463

464464
if (cpu_is_pxa3xx()) {
465465

466-
reset_status = ARSR;
466+
pxa_register_wdt(ARSR);
467467

468468
/*
469469
* clear RDH bit every time after reset

arch/arm/mach-pxa/reset.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
#include <mach/reset.h>
1212
#include <mach/smemc.h>
1313

14-
unsigned int reset_status;
15-
EXPORT_SYMBOL(reset_status);
16-
1714
static void do_hw_reset(void);
1815

1916
static int reset_gpio = -1;

arch/arm/mach-sa1100/generic.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,6 @@
3939
#include "generic.h"
4040
#include <clocksource/pxa.h>
4141

42-
unsigned int reset_status;
43-
EXPORT_SYMBOL(reset_status);
44-
4542
#define NR_FREQS 16
4643

4744
/*
@@ -319,10 +316,13 @@ static struct platform_device *sa11x0_devices[] __initdata = {
319316

320317
static int __init sa1100_init(void)
321318
{
319+
struct resource wdt_res = DEFINE_RES_MEM(0x90000000, 0x20);
322320
pm_power_off = sa1100_power_off;
323321

324322
regulator_has_full_constraints();
325323

324+
platform_device_register_simple("sa1100_wdt", -1, &wdt_res, 1);
325+
326326
return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
327327
}
328328

arch/arm/mach-sa1100/include/mach/reset.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#define RESET_STATUS_GPIO (1 << 3) /* GPIO Reset */
1111
#define RESET_STATUS_ALL (0xf)
1212

13-
extern unsigned int reset_status;
1413
static inline void clear_reset_status(unsigned int mask)
1514
{
1615
RCSR = mask;

drivers/watchdog/sa1100_wdt.c

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
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>
@@ -30,16 +31,42 @@
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

3955
static unsigned long oscr_freq;
4056
static unsigned long sa1100wdt_users;
4157
static unsigned int pre_margin;
4258
static 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
*/
6794
static 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 */
155182
static 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

209248
MODULE_AUTHOR("Oleg Drokin <[email protected]>");
210249
MODULE_DESCRIPTION("SA1100/PXA2xx Watchdog");

0 commit comments

Comments
 (0)