diff options
| author | Florian Fainelli <florian@openwrt.org> | 2010-03-22 22:56:24 -0400 |
|---|---|---|
| committer | Samuel Ortiz <sameo@linux.intel.com> | 2010-05-27 19:37:29 -0400 |
| commit | 842102f35a8da589486fac497885b7bd6053af2f (patch) | |
| tree | faf87e5b75e4b510bcf43b54895adf3ad09e1e91 | |
| parent | 9956d02d6e60f0c50632ba5699bc6238defb496b (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>
| -rw-r--r-- | drivers/watchdog/rdc321x_wdt.c | 53 |
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 { | |||
| 70 | static void rdc321x_wdt_trigger(unsigned long unused) | 71 | static 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 = { | |||
| 219 | static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) | 228 | static 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 | } |
