fix panic on boot due to invalid IORESOURCE for MFD cells, fix gpio value setting
[openwrt/staging/yousong.git] / target / linux / rdc / patches-2.6.32 / 003-rdc321x_watchdog_southbridge.patch
1 The RDC321x MFD southbridge driver will pass a reference to the southbridge
2 PCI device which should be used by the watchdog driver for its operations.
3 This patch converts the watchdog driver to use the pci_dev pointer and make use
4 of the base register resource which is passed along with the platform device.
5
6 Acked-by: Wim Van Sebroeck <wim@iguana.be>
7 Signed-off-by: Florian Fainelli <florian@openwrt.org>
8 ---
9 Changes from v2:
10 - replaced rdc321x_pci_{read,write}
11 - use the pci_dev pointer passed as platform_data
12
13 Index: linux-2.6.32.10/drivers/watchdog/rdc321x_wdt.c
14 ===================================================================
15 --- linux-2.6.32.10.orig/drivers/watchdog/rdc321x_wdt.c 2010-05-15 22:14:28.000000000 +0200
16 +++ linux-2.6.32.10/drivers/watchdog/rdc321x_wdt.c 2010-05-15 22:15:24.000000000 +0200
17 @@ -1,7 +1,7 @@
18 /*
19 * RDC321x watchdog driver
20 *
21 - * Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
22 + * Copyright (C) 2007-2010 Florian Fainelli <florian@openwrt.org>
23 *
24 * This driver is highly inspired from the cpu5_wdt driver
25 *
26 @@ -36,8 +36,7 @@
27 #include <linux/watchdog.h>
28 #include <linux/io.h>
29 #include <linux/uaccess.h>
30 -
31 -#include <asm/rdc321x_defs.h>
32 +#include <linux/mfd/rdc321x.h>
33
34 #define RDC_WDT_MASK 0x80000000 /* Mask */
35 #define RDC_WDT_EN 0x00800000 /* Enable bit */
36 @@ -63,6 +62,8 @@
37 int default_ticks;
38 unsigned long inuse;
39 spinlock_t lock;
40 + struct pci_dev *sb_pdev;
41 + int base_reg;
42 } rdc321x_wdt_device;
43
44 /* generic helper functions */
45 @@ -70,14 +71,18 @@
46 static void rdc321x_wdt_trigger(unsigned long unused)
47 {
48 unsigned long flags;
49 + u32 val;
50
51 if (rdc321x_wdt_device.running)
52 ticks--;
53
54 /* keep watchdog alive */
55 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
56 - outl(RDC_WDT_EN | inl(RDC3210_CFGREG_DATA),
57 - RDC3210_CFGREG_DATA);
58 + pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
59 + rdc321x_wdt_device.base_reg, &val);
60 + val |= RDC_WDT_EN;
61 + pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
62 + rdc321x_wdt_device.base_reg, val);
63 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
64
65 /* requeue?? */
66 @@ -105,10 +110,13 @@
67
68 /* Clear the timer */
69 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
70 - outl(RDC_CLS_TMR, RDC3210_CFGREG_ADDR);
71 + pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
72 + rdc321x_wdt_device.base_reg, RDC_CLS_TMR);
73
74 /* Enable watchdog and set the timeout to 81.92 us */
75 - outl(RDC_WDT_EN | RDC_WDT_CNT, RDC3210_CFGREG_DATA);
76 + pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
77 + rdc321x_wdt_device.base_reg,
78 + RDC_WDT_EN | RDC_WDT_CNT);
79 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
80
81 mod_timer(&rdc321x_wdt_device.timer,
82 @@ -148,7 +156,7 @@
83 unsigned long arg)
84 {
85 void __user *argp = (void __user *)arg;
86 - unsigned int value;
87 + u32 value;
88 static struct watchdog_info ident = {
89 .options = WDIOF_CARDRESET,
90 .identity = "RDC321x WDT",
91 @@ -162,9 +170,10 @@
92 case WDIOC_GETSTATUS:
93 /* Read the value from the DATA register */
94 spin_lock_irqsave(&rdc321x_wdt_device.lock, flags);
95 - value = inl(RDC3210_CFGREG_DATA);
96 + pci_read_config_dword(rdc321x_wdt_device.sb_pdev,
97 + rdc321x_wdt_device.base_reg, &value);
98 spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags);
99 - if (copy_to_user(argp, &value, sizeof(int)))
100 + if (copy_to_user(argp, &value, sizeof(u32)))
101 return -EFAULT;
102 break;
103 case WDIOC_GETSUPPORT:
104 @@ -219,17 +228,35 @@
105 static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
106 {
107 int err;
108 + struct resource *r;
109 + struct rdc321x_wdt_pdata *pdata;
110 +
111 + pdata = platform_get_drvdata(pdev);
112 + if (!pdata) {
113 + dev_err(&pdev->dev, "no platform data supplied\n");
114 + return -ENODEV;
115 + }
116 +
117 + r = platform_get_resource_byname(pdev, IORESOURCE_IO, "wdt-reg");
118 + if (!r) {
119 + dev_err(&pdev->dev, "failed to get wdt-reg resource\n");
120 + return -ENODEV;
121 + }
122 +
123 + rdc321x_wdt_device.sb_pdev = pdata->sb_pdev;
124 + rdc321x_wdt_device.base_reg = r->start;
125
126 err = misc_register(&rdc321x_wdt_misc);
127 if (err < 0) {
128 - printk(KERN_ERR PFX "watchdog misc_register failed\n");
129 + dev_err(&pdev->dev, "misc_register failed\n");
130 return err;
131 }
132
133 spin_lock_init(&rdc321x_wdt_device.lock);
134
135 /* Reset the watchdog */
136 - outl(RDC_WDT_RST, RDC3210_CFGREG_DATA);
137 + pci_write_config_dword(rdc321x_wdt_device.sb_pdev,
138 + rdc321x_wdt_device.base_reg, RDC_WDT_RST);
139
140 init_completion(&rdc321x_wdt_device.stop);
141 rdc321x_wdt_device.queue = 0;
142 @@ -240,7 +267,7 @@
143
144 rdc321x_wdt_device.default_ticks = ticks;
145
146 - printk(KERN_INFO PFX "watchdog init success\n");
147 + dev_info(&pdev->dev, "watchdog init success\n");
148
149 return 0;
150 }