[rdc] resync 2.6.32 support with changes in 2.6.30
[openwrt/svn-archive/archive.git] / target / linux / rdc / patches-2.6.32 / 003-rdc321x_watchdog_southbridge.patch
diff --git a/target/linux/rdc/patches-2.6.32/003-rdc321x_watchdog_southbridge.patch b/target/linux/rdc/patches-2.6.32/003-rdc321x_watchdog_southbridge.patch
new file mode 100644 (file)
index 0000000..1031999
--- /dev/null
@@ -0,0 +1,150 @@
+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.
+
+Acked-by: Wim Van Sebroeck <wim@iguana.be>
+Signed-off-by: Florian Fainelli <florian@openwrt.org>
+---
+Changes from v2:
+- replaced rdc321x_pci_{read,write}
+- use the pci_dev pointer passed as platform_data
+
+Index: linux-2.6.30.10/drivers/watchdog/rdc321x_wdt.c
+===================================================================
+--- linux-2.6.30.10.orig/drivers/watchdog/rdc321x_wdt.c        2009-12-04 07:00:07.000000000 +0100
++++ linux-2.6.30.10/drivers/watchdog/rdc321x_wdt.c     2010-04-28 10:17:46.000000000 +0200
+@@ -1,7 +1,7 @@
+ /*
+  * RDC321x watchdog driver
+  *
+- * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
++ * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
+  *
+  * This driver is highly inspired from the cpu5_wdt driver
+  *
+@@ -36,8 +36,7 @@
+ #include <linux/watchdog.h>
+ #include <linux/io.h>
+ #include <linux/uaccess.h>
+-
+-#include <asm/rdc321x_defs.h>
++#include <linux/mfd/rdc321x.h>
+ #define RDC_WDT_MASK  0x80000000 /* Mask */
+ #define RDC_WDT_EN    0x00800000 /* Enable bit */
+@@ -63,6 +62,8 @@
+       int default_ticks;
+       unsigned long inuse;
+       spinlock_t lock;
++      struct pci_dev *sb_pdev;
++      int base_reg;
+ } rdc321x_wdt_device;
+ /* generic helper functions */
+@@ -70,14 +71,18 @@
+ static void rdc321x_wdt_trigger(unsigned long unused)
+ {
+       unsigned long flags;
++      u32 val;
+       if (rdc321x_wdt_device.running)
+               ticks--;
+       /* keep watchdog alive */
+       spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
+-      outl(RDC_WDT_EN | inl(RDC3210_CFGREG_DATA),
+-              RDC3210_CFGREG_DATA);
++      pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
++                                      rdc321x_wdt_device.base_reg, &val);
++      val |= RDC_WDT_EN;
++      pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
++                                      rdc321x_wdt_device.base_reg, val);
+       spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
+       /* requeue?? */
+@@ -105,10 +110,13 @@
+               /* Clear the timer */
+               spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
+-              outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR);
++              pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
++                              rdc321x_wdt_device.base_reg, RDC_CLS_TMR);
+               /* Enable watchdog and set the timeout to 81.92 us */
+-              outl(RDC_WDT_EN | RDC_WDT_CNT, RDC3210_CFGREG_DATA);
++              pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
++                                      rdc321x_wdt_device.base_reg,
++                                      RDC_WDT_EN | RDC_WDT_CNT);
+               spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
+               mod_timer(&rdc321x_wdt_device.timer,
+@@ -148,7 +156,7 @@
+                               unsigned long arg)
+ {
+       void __user *argp = (void __user *)arg;
+-      unsigned int value;
++      u32 value;
+       static struct watchdog_info ident = {
+               .options = WDIOF_CARDRESET,
+               .identity = "RDC321x WDT",
+@@ -162,9 +170,10 @@
+       case WDIOC_GETSTATUS:
+               /* Read the value from the DATA register */
+               spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
+-              value = inl(RDC3210_CFGREG_DATA);
++              pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
++                                      rdc321x_wdt_device.base_reg, &value);
+               spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
+-              if (copy_to_user(argp, &value, sizeof(int)))
++              if (copy_to_user(argp, &value, sizeof(u32)))
+                       return -EFAULT;
+               break;
+       case WDIOC_GETSUPPORT:
+@@ -219,17 +228,35 @@
+ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
+ {
+       int err;
++      struct resource *r;
++      struct rdc321x_wdt_pdata *pdata;
++
++      pdata = pdev->dev.platform_data;
++      if (!pdata) {
++              dev_err(&pdev->dev, "no platform data supplied\n");
++              return -ENODEV;
++      }
++
++      r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wdt-reg");
++      if (!r) {
++              dev_err(&pdev->dev, "failed to get wdt-reg resource\n");
++              return -ENODEV;
++      }
++
++      rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
++      rdc321x_wdt_device.base_reg = r->start;
+       err = misc_register(&rdc321x_wdt_misc);
+       if (err < 0) {
+-              printk(KERN_ERR PFX "watchdog misc_register failed\n");
++              dev_err(&pdev->dev, "misc_register failed\n");
+               return err;
+       }
+       spin_lock_init(&rdc321x_wdt_device.lock);
+       /* Reset the watchdog */
+-      outl(RDC_WDT_RST, RDC3210_CFGREG_DATA);
++      pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
++                              rdc321x_wdt_device.base_reg, RDC_WDT_RST);
+       init_completion(&rdc321x_wdt_device.stop);
+       rdc321x_wdt_device.queue = 0;
+@@ -240,7 +267,7 @@
+       rdc321x_wdt_device.default_ticks = ticks;
+-      printk(KERN_INFO PFX "watchdog init success\n");
++      dev_info(&pdev->dev, "watchdog init success\n");
+       return 0;
+ }