aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog/rdc321x_wdt.c
diff options
context:
space:
mode:
authorFlorian Fainelli <florian@openwrt.org>2010-03-22 22:56:24 -0400
committerSamuel Ortiz <sameo@linux.intel.com>2010-05-27 19:37:29 -0400
commit842102f35a8da589486fac497885b7bd6053af2f (patch)
treefaf87e5b75e4b510bcf43b54895adf3ad09e1e91 /drivers/watchdog/rdc321x_wdt.c
parent9956d02d6e60f0c50632ba5699bc6238defb496b (diff)
watchdog: Convert rdc321x_wdt to use southbridge pci device
The RDC321x MFD southbridge driver will pass a reference to the southbridge PCI device which should be used by the watchdog driver for its operations. This patch converts the watchdog driver to use the pci_dev pointer and make use of the base register resource which is passed along with the platform device. Signed-off-by: Florian Fainelli <florian@openwrt.org> Acked-by: Wim Van Sebroeck <wim@iguana.be> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/watchdog/rdc321x_wdt.c')
-rw-r--r--drivers/watchdog/rdc321x_wdt.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 69c6adbd8205..4733a99955dd 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * RDC321x watchdog driver 2 * RDC321x watchdog driver
3 * 3 *
4 * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org> 4 * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
5 * 5 *
6 * This driver is highly inspired from the cpu5_wdt driver 6 * This driver is highly inspired from the cpu5_wdt driver
7 * 7 *
@@ -36,8 +36,7 @@
36#include <linux/watchdog.h> 36#include <linux/watchdog.h>
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39 39#include <linux/mfd/rdc321x.h>
40#include <asm/rdc321x_defs.h>
41 40
42#define RDC_WDT_MASK 0x80000000 /* Mask */ 41#define RDC_WDT_MASK 0x80000000 /* Mask */
43#define RDC_WDT_EN 0x00800000 /* Enable bit */ 42#define RDC_WDT_EN 0x00800000 /* Enable bit */
@@ -63,6 +62,8 @@ static struct {
63 int default_ticks; 62 int default_ticks;
64 unsigned long inuse; 63 unsigned long inuse;
65 spinlock_t lock; 64 spinlock_t lock;
65 struct pci_dev *sb_pdev;
66 int base_reg;
66} rdc321x_wdt_device; 67} rdc321x_wdt_device;
67 68
68/* generic helper functions */ 69/* generic helper functions */
@@ -70,14 +71,18 @@ static struct {
70static void rdc321x_wdt_trigger(unsigned long unused) 71static void rdc321x_wdt_trigger(unsigned long unused)
71{ 72{
72 unsigned long flags; 73 unsigned long flags;
74 u32 val;
73 75
74 if (rdc321x_wdt_device.running) 76 if (rdc321x_wdt_device.running)
75 ticks--; 77 ticks--;
76 78
77 /* keep watchdog alive */ 79 /* keep watchdog alive */
78 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); 80 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
79 outl(RDC_WDT_EN | inl(RDC3210_CFGREG_DATA), 81 pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
80 RDC3210_CFGREG_DATA); 82 rdc321x_wdt_device.base_reg, &val);
83 val |= RDC_WDT_EN;
84 pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
85 rdc321x_wdt_device.base_reg, val);
81 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); 86 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
82 87
83 /* requeue?? */ 88 /* requeue?? */
@@ -105,10 +110,13 @@ static void rdc321x_wdt_start(void)
105 110
106 /* Clear the timer */ 111 /* Clear the timer */
107 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); 112 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
108 outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR); 113 pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
114 rdc321x_wdt_device.base_reg, RDC_CLS_TMR);
109 115
110 /* Enable watchdog and set the timeout to 81.92 us */ 116 /* Enable watchdog and set the timeout to 81.92 us */
111 outl(RDC_WDT_EN | RDC_WDT_CNT, RDC3210_CFGREG_DATA); 117 pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
118 rdc321x_wdt_device.base_reg,
119 RDC_WDT_EN | RDC_WDT_CNT);
112 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); 120 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
113 121
114 mod_timer(&rdc321x_wdt_device.timer, 122 mod_timer(&rdc321x_wdt_device.timer,
@@ -148,7 +156,7 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
148 unsigned long arg) 156 unsigned long arg)
149{ 157{
150 void __user *argp = (void __user *)arg; 158 void __user *argp = (void __user *)arg;
151 unsigned int value; 159 u32 value;
152 static const struct watchdog_info ident = { 160 static const struct watchdog_info ident = {
153 .options = WDIOF_CARDRESET, 161 .options = WDIOF_CARDRESET,
154 .identity = "RDC321x WDT", 162 .identity = "RDC321x WDT",
@@ -162,9 +170,10 @@ static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
162 case WDIOC_GETSTATUS: 170 case WDIOC_GETSTATUS:
163 /* Read the value from the DATA register */ 171 /* Read the value from the DATA register */
164 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); 172 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
165 value = inl(RDC3210_CFGREG_DATA); 173 pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
174 rdc321x_wdt_device.base_reg, &value);
166 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); 175 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
167 if (copy_to_user(argp, &value, sizeof(int))) 176 if (copy_to_user(argp, &value, sizeof(u32)))
168 return -EFAULT; 177 return -EFAULT;
169 break; 178 break;
170 case WDIOC_GETSUPPORT: 179 case WDIOC_GETSUPPORT:
@@ -219,17 +228,35 @@ static struct miscdevice rdc321x_wdt_misc = {
219static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) 228static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
220{ 229{
221 int err; 230 int err;
231 struct resource *r;
232 struct rdc321x_wdt_pdata *pdata;
233
234 pdata = pdev->dev.platform_data;
235 if (!pdata) {
236 dev_err(&pdev->dev, "no platform data supplied\n");
237 return -ENODEV;
238 }
239
240 r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wdt-reg");
241 if (!r) {
242 dev_err(&pdev->dev, "failed to get wdt-reg resource\n");
243 return -ENODEV;
244 }
245
246 rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
247 rdc321x_wdt_device.base_reg = r->start;
222 248
223 err = misc_register(&rdc321x_wdt_misc); 249 err = misc_register(&rdc321x_wdt_misc);
224 if (err < 0) { 250 if (err < 0) {
225 printk(KERN_ERR PFX "watchdog misc_register failed\n"); 251 dev_err(&pdev->dev, "misc_register failed\n");
226 return err; 252 return err;
227 } 253 }
228 254
229 spin_lock_init(&rdc321x_wdt_device.lock); 255 spin_lock_init(&rdc321x_wdt_device.lock);
230 256
231 /* Reset the watchdog */ 257 /* Reset the watchdog */
232 outl(RDC_WDT_RST, RDC3210_CFGREG_DATA); 258 pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
259 rdc321x_wdt_device.base_reg, RDC_WDT_RST);
233 260
234 init_completion(&rdc321x_wdt_device.stop); 261 init_completion(&rdc321x_wdt_device.stop);
235 rdc321x_wdt_device.queue = 0; 262 rdc321x_wdt_device.queue = 0;
@@ -240,7 +267,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
240 267
241 rdc321x_wdt_device.default_ticks = ticks; 268 rdc321x_wdt_device.default_ticks = ticks;
242 269
243 printk(KERN_INFO PFX "watchdog init success\n"); 270 dev_info(&pdev->dev, "watchdog init success\n");
244 271
245 return 0; 272 return 0;
246} 273}