diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 14:53:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-29 14:53:11 -0400 |
commit | 4b781474682434e7881f20e9dfbe6687ea619795 (patch) | |
tree | bdd976645ead7f04900e60017502e6a41b03e601 /drivers | |
parent | 53f2c4a8fd882009a2a75c5b72d6898c0808616e (diff) | |
parent | 29f772d41c01ad6b72c3de705e79779857badcde (diff) |
Merge tag 'mfd-3.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFD changes from Samuel Ortiz:
"Besides the usual cleanups, this one brings:
* Support for 5 new chipsets: Intel's ICH LPC and SCH Centerton,
ST-E's STAX211, Samsung's MAX77693 and TI's LM3533.
* Device tree support for the twl6040, tps65910, da9502 and ab8500
drivers.
* Fairly big tps56910, ab8500 and db8500 updates.
* i2c support for mc13xxx.
* Our regular update for the wm8xxx driver from Mark."
Fix up various conflicts with other trees, largely due to ab5500 removal
etc.
* tag 'mfd-3.5-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (106 commits)
mfd: Fix build break of max77693 by adding REGMAP_I2C option
mfd: Fix twl6040 build failure
mfd: Fix max77693 build failure
mfd: ab8500-core should depend on MFD_DB8500_PRCMU
gpio: tps65910: dt: process gpio specific device node info
mfd: Remove the parsing of dt info for tps65910 gpio
mfd: Save device node parsed platform data for tps65910 sub devices
mfd: Add r_select to lm3533 platform data
gpio: Add Intel Centerton support to gpio-sch
mfd: Emulate active low IRQs as well as active high IRQs for wm831x
mfd: Mark two lm3533 zone registers as volatile
mfd: Fix return type of lm533 attribute is_visible
mfd: Enable Device Tree support in the ab8500-pwm driver
mfd: Enable Device Tree support in the ab8500-sysctrl driver
mfd: Add support for Device Tree to twl6040
mfd: Register the twl6040 child for the ASoC codec unconditionally
mfd: Allocate twl6040 IRQ numbers dynamically
mfd: twl6040 code cleanup in interrupt initialization part
mfd: Enable ab8500-gpadc driver for Device Tree
mfd: Prevent unassigned pointer from being used in ab8500-gpadc driver
...
Diffstat (limited to 'drivers')
69 files changed, 5664 insertions, 1720 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index aa3642cb8209..0356099ae040 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -167,6 +167,14 @@ config GPIO_PXA | |||
167 | help | 167 | help |
168 | Say yes here to support the PXA GPIO device | 168 | Say yes here to support the PXA GPIO device |
169 | 169 | ||
170 | config GPIO_STA2X11 | ||
171 | bool "STA2x11/ConneXt GPIO support" | ||
172 | depends on MFD_STA2X11 | ||
173 | select GENERIC_IRQ_CHIP | ||
174 | help | ||
175 | Say yes here to support the STA2x11/ConneXt GPIO device. | ||
176 | The GPIO module has 128 GPIO pins with alternate functions. | ||
177 | |||
170 | config GPIO_XILINX | 178 | config GPIO_XILINX |
171 | bool "Xilinx GPIO support" | 179 | bool "Xilinx GPIO support" |
172 | depends on PPC_OF || MICROBLAZE | 180 | depends on PPC_OF || MICROBLAZE |
@@ -180,13 +188,13 @@ config GPIO_VR41XX | |||
180 | Say yes here to support the NEC VR4100 series General-purpose I/O Uint | 188 | Say yes here to support the NEC VR4100 series General-purpose I/O Uint |
181 | 189 | ||
182 | config GPIO_SCH | 190 | config GPIO_SCH |
183 | tristate "Intel SCH/TunnelCreek GPIO" | 191 | tristate "Intel SCH/TunnelCreek/Centerton GPIO" |
184 | depends on PCI && X86 | 192 | depends on PCI && X86 |
185 | select MFD_CORE | 193 | select MFD_CORE |
186 | select LPC_SCH | 194 | select LPC_SCH |
187 | help | 195 | help |
188 | Say yes here to support GPIO interface on Intel Poulsbo SCH | 196 | Say yes here to support GPIO interface on Intel Poulsbo SCH, |
189 | or Intel Tunnel Creek processor. | 197 | Intel Tunnel Creek processor or Intel Centerton processor. |
190 | The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are | 198 | The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are |
191 | powered by the core power rail and are turned off during sleep | 199 | powered by the core power rail and are turned off during sleep |
192 | modes (S3 and higher). The remaining four GPIOs are powered by | 200 | modes (S3 and higher). The remaining four GPIOs are powered by |
@@ -195,6 +203,22 @@ config GPIO_SCH | |||
195 | system from the Suspend-to-RAM state. | 203 | system from the Suspend-to-RAM state. |
196 | The Intel Tunnel Creek processor has 5 GPIOs powered by the | 204 | The Intel Tunnel Creek processor has 5 GPIOs powered by the |
197 | core power rail and 9 from suspend power supply. | 205 | core power rail and 9 from suspend power supply. |
206 | The Intel Centerton processor has a total of 30 GPIO pins. | ||
207 | Twenty-one are powered by the core power rail and 9 from the | ||
208 | suspend power supply. | ||
209 | |||
210 | config GPIO_ICH | ||
211 | tristate "Intel ICH GPIO" | ||
212 | depends on PCI && X86 | ||
213 | select MFD_CORE | ||
214 | select LPC_ICH | ||
215 | help | ||
216 | Say yes here to support the GPIO functionality of a number of Intel | ||
217 | ICH-based chipsets. Currently supported devices: ICH6, ICH7, ICH8 | ||
218 | ICH9, ICH10, Series 5/3400 (eg Ibex Peak), Series 6/C200 (eg | ||
219 | Cougar Point), NM10 (Tiger Point), and 3100 (Whitmore Lake). | ||
220 | |||
221 | If unsure, say N. | ||
198 | 222 | ||
199 | config GPIO_VX855 | 223 | config GPIO_VX855 |
200 | tristate "VIA VX855/VX875 GPIO" | 224 | tristate "VIA VX855/VX875 GPIO" |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 07a79e245407..fde36e5e3537 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o | |||
19 | obj-$(CONFIG_GPIO_EM) += gpio-em.o | 19 | obj-$(CONFIG_GPIO_EM) += gpio-em.o |
20 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o | 20 | obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o |
21 | obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o | 21 | obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o |
22 | obj-$(CONFIG_GPIO_ICH) += gpio-ich.o | ||
22 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o | 23 | obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o |
23 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o | 24 | obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o |
24 | obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o | 25 | obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o |
@@ -51,6 +52,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o | |||
51 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | 52 | obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o |
52 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o | 53 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
53 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o | 54 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o |
55 | obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o | ||
54 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 56 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
55 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o | 57 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o |
56 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o | 58 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o |
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c new file mode 100644 index 000000000000..b7c06517403d --- /dev/null +++ b/drivers/gpio/gpio-ich.c | |||
@@ -0,0 +1,419 @@ | |||
1 | /* | ||
2 | * Intel ICH6-10, Series 5 and 6 GPIO driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Extreme Engineering Solutions. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/gpio.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/mfd/lpc_ich.h> | ||
28 | |||
29 | #define DRV_NAME "gpio_ich" | ||
30 | |||
31 | /* | ||
32 | * GPIO register offsets in GPIO I/O space. | ||
33 | * Each chunk of 32 GPIOs is manipulated via its own USE_SELx, IO_SELx, and | ||
34 | * LVLx registers. Logic in the read/write functions takes a register and | ||
35 | * an absolute bit number and determines the proper register offset and bit | ||
36 | * number in that register. For example, to read the value of GPIO bit 50 | ||
37 | * the code would access offset ichx_regs[2(=GPIO_LVL)][1(=50/32)], | ||
38 | * bit 18 (50%32). | ||
39 | */ | ||
40 | enum GPIO_REG { | ||
41 | GPIO_USE_SEL = 0, | ||
42 | GPIO_IO_SEL, | ||
43 | GPIO_LVL, | ||
44 | }; | ||
45 | |||
46 | static const u8 ichx_regs[3][3] = { | ||
47 | {0x00, 0x30, 0x40}, /* USE_SEL[1-3] offsets */ | ||
48 | {0x04, 0x34, 0x44}, /* IO_SEL[1-3] offsets */ | ||
49 | {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ | ||
50 | }; | ||
51 | |||
52 | #define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) | ||
53 | #define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start) | ||
54 | |||
55 | struct ichx_desc { | ||
56 | /* Max GPIO pins the chipset can have */ | ||
57 | uint ngpio; | ||
58 | |||
59 | /* Whether the chipset has GPIO in GPE0_STS in the PM IO region */ | ||
60 | bool uses_gpe0; | ||
61 | |||
62 | /* USE_SEL is bogus on some chipsets, eg 3100 */ | ||
63 | u32 use_sel_ignore[3]; | ||
64 | |||
65 | /* Some chipsets have quirks, let these use their own request/get */ | ||
66 | int (*request)(struct gpio_chip *chip, unsigned offset); | ||
67 | int (*get)(struct gpio_chip *chip, unsigned offset); | ||
68 | }; | ||
69 | |||
70 | static struct { | ||
71 | spinlock_t lock; | ||
72 | struct platform_device *dev; | ||
73 | struct gpio_chip chip; | ||
74 | struct resource *gpio_base; /* GPIO IO base */ | ||
75 | struct resource *pm_base; /* Power Mangagment IO base */ | ||
76 | struct ichx_desc *desc; /* Pointer to chipset-specific description */ | ||
77 | u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ | ||
78 | } ichx_priv; | ||
79 | |||
80 | static int modparam_gpiobase = -1; /* dynamic */ | ||
81 | module_param_named(gpiobase, modparam_gpiobase, int, 0444); | ||
82 | MODULE_PARM_DESC(gpiobase, "The GPIO number base. -1 means dynamic, " | ||
83 | "which is the default."); | ||
84 | |||
85 | static int ichx_write_bit(int reg, unsigned nr, int val, int verify) | ||
86 | { | ||
87 | unsigned long flags; | ||
88 | u32 data, tmp; | ||
89 | int reg_nr = nr / 32; | ||
90 | int bit = nr & 0x1f; | ||
91 | int ret = 0; | ||
92 | |||
93 | spin_lock_irqsave(&ichx_priv.lock, flags); | ||
94 | |||
95 | data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
96 | if (val) | ||
97 | data |= 1 << bit; | ||
98 | else | ||
99 | data &= ~(1 << bit); | ||
100 | ICHX_WRITE(data, ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
101 | tmp = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
102 | if (verify && data != tmp) | ||
103 | ret = -EPERM; | ||
104 | |||
105 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | ||
106 | |||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static int ichx_read_bit(int reg, unsigned nr) | ||
111 | { | ||
112 | unsigned long flags; | ||
113 | u32 data; | ||
114 | int reg_nr = nr / 32; | ||
115 | int bit = nr & 0x1f; | ||
116 | |||
117 | spin_lock_irqsave(&ichx_priv.lock, flags); | ||
118 | |||
119 | data = ICHX_READ(ichx_regs[reg][reg_nr], ichx_priv.gpio_base); | ||
120 | |||
121 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | ||
122 | |||
123 | return data & (1 << bit) ? 1 : 0; | ||
124 | } | ||
125 | |||
126 | static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | ||
127 | { | ||
128 | /* | ||
129 | * Try setting pin as an input and verify it worked since many pins | ||
130 | * are output-only. | ||
131 | */ | ||
132 | if (ichx_write_bit(GPIO_IO_SEL, nr, 1, 1)) | ||
133 | return -EINVAL; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | ||
139 | int val) | ||
140 | { | ||
141 | /* Set GPIO output value. */ | ||
142 | ichx_write_bit(GPIO_LVL, nr, val, 0); | ||
143 | |||
144 | /* | ||
145 | * Try setting pin as an output and verify it worked since many pins | ||
146 | * are input-only. | ||
147 | */ | ||
148 | if (ichx_write_bit(GPIO_IO_SEL, nr, 0, 1)) | ||
149 | return -EINVAL; | ||
150 | |||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) | ||
155 | { | ||
156 | return ichx_read_bit(GPIO_LVL, nr); | ||
157 | } | ||
158 | |||
159 | static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr) | ||
160 | { | ||
161 | unsigned long flags; | ||
162 | u32 data; | ||
163 | |||
164 | /* | ||
165 | * GPI 0 - 15 need to be read from the power management registers on | ||
166 | * a ICH6/3100 bridge. | ||
167 | */ | ||
168 | if (nr < 16) { | ||
169 | if (!ichx_priv.pm_base) | ||
170 | return -ENXIO; | ||
171 | |||
172 | spin_lock_irqsave(&ichx_priv.lock, flags); | ||
173 | |||
174 | /* GPI 0 - 15 are latched, write 1 to clear*/ | ||
175 | ICHX_WRITE(1 << (16 + nr), 0, ichx_priv.pm_base); | ||
176 | data = ICHX_READ(0, ichx_priv.pm_base); | ||
177 | |||
178 | spin_unlock_irqrestore(&ichx_priv.lock, flags); | ||
179 | |||
180 | return (data >> 16) & (1 << nr) ? 1 : 0; | ||
181 | } else { | ||
182 | return ichx_gpio_get(chip, nr); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) | ||
187 | { | ||
188 | /* | ||
189 | * Note we assume the BIOS properly set a bridge's USE value. Some | ||
190 | * chips (eg Intel 3100) have bogus USE values though, so first see if | ||
191 | * the chipset's USE value can be trusted for this specific bit. | ||
192 | * If it can't be trusted, assume that the pin can be used as a GPIO. | ||
193 | */ | ||
194 | if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) | ||
195 | return 1; | ||
196 | |||
197 | return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; | ||
198 | } | ||
199 | |||
200 | static int ich6_gpio_request(struct gpio_chip *chip, unsigned nr) | ||
201 | { | ||
202 | /* | ||
203 | * Fixups for bits 16 and 17 are necessary on the Intel ICH6/3100 | ||
204 | * bridge as they are controlled by USE register bits 0 and 1. See | ||
205 | * "Table 704 GPIO_USE_SEL1 register" in the i3100 datasheet for | ||
206 | * additional info. | ||
207 | */ | ||
208 | if (nr == 16 || nr == 17) | ||
209 | nr -= 16; | ||
210 | |||
211 | return ichx_gpio_request(chip, nr); | ||
212 | } | ||
213 | |||
214 | static void ichx_gpio_set(struct gpio_chip *chip, unsigned nr, int val) | ||
215 | { | ||
216 | ichx_write_bit(GPIO_LVL, nr, val, 0); | ||
217 | } | ||
218 | |||
219 | static void __devinit ichx_gpiolib_setup(struct gpio_chip *chip) | ||
220 | { | ||
221 | chip->owner = THIS_MODULE; | ||
222 | chip->label = DRV_NAME; | ||
223 | chip->dev = &ichx_priv.dev->dev; | ||
224 | |||
225 | /* Allow chip-specific overrides of request()/get() */ | ||
226 | chip->request = ichx_priv.desc->request ? | ||
227 | ichx_priv.desc->request : ichx_gpio_request; | ||
228 | chip->get = ichx_priv.desc->get ? | ||
229 | ichx_priv.desc->get : ichx_gpio_get; | ||
230 | |||
231 | chip->set = ichx_gpio_set; | ||
232 | chip->direction_input = ichx_gpio_direction_input; | ||
233 | chip->direction_output = ichx_gpio_direction_output; | ||
234 | chip->base = modparam_gpiobase; | ||
235 | chip->ngpio = ichx_priv.desc->ngpio; | ||
236 | chip->can_sleep = 0; | ||
237 | chip->dbg_show = NULL; | ||
238 | } | ||
239 | |||
240 | /* ICH6-based, 631xesb-based */ | ||
241 | static struct ichx_desc ich6_desc = { | ||
242 | /* Bridges using the ICH6 controller need fixups for GPIO 0 - 17 */ | ||
243 | .request = ich6_gpio_request, | ||
244 | .get = ich6_gpio_get, | ||
245 | |||
246 | /* GPIO 0-15 are read in the GPE0_STS PM register */ | ||
247 | .uses_gpe0 = true, | ||
248 | |||
249 | .ngpio = 50, | ||
250 | }; | ||
251 | |||
252 | /* Intel 3100 */ | ||
253 | static struct ichx_desc i3100_desc = { | ||
254 | /* | ||
255 | * Bits 16,17, 20 of USE_SEL and bit 16 of USE_SEL2 always read 0 on | ||
256 | * the Intel 3100. See "Table 712. GPIO Summary Table" of 3100 | ||
257 | * Datasheet for more info. | ||
258 | */ | ||
259 | .use_sel_ignore = {0x00130000, 0x00010000, 0x0}, | ||
260 | |||
261 | /* The 3100 needs fixups for GPIO 0 - 17 */ | ||
262 | .request = ich6_gpio_request, | ||
263 | .get = ich6_gpio_get, | ||
264 | |||
265 | /* GPIO 0-15 are read in the GPE0_STS PM register */ | ||
266 | .uses_gpe0 = true, | ||
267 | |||
268 | .ngpio = 50, | ||
269 | }; | ||
270 | |||
271 | /* ICH7 and ICH8-based */ | ||
272 | static struct ichx_desc ich7_desc = { | ||
273 | .ngpio = 50, | ||
274 | }; | ||
275 | |||
276 | /* ICH9-based */ | ||
277 | static struct ichx_desc ich9_desc = { | ||
278 | .ngpio = 61, | ||
279 | }; | ||
280 | |||
281 | /* ICH10-based - Consumer/corporate versions have different amount of GPIO */ | ||
282 | static struct ichx_desc ich10_cons_desc = { | ||
283 | .ngpio = 61, | ||
284 | }; | ||
285 | static struct ichx_desc ich10_corp_desc = { | ||
286 | .ngpio = 72, | ||
287 | }; | ||
288 | |||
289 | /* Intel 5 series, 6 series, 3400 series, and C200 series */ | ||
290 | static struct ichx_desc intel5_desc = { | ||
291 | .ngpio = 76, | ||
292 | }; | ||
293 | |||
294 | static int __devinit ichx_gpio_probe(struct platform_device *pdev) | ||
295 | { | ||
296 | struct resource *res_base, *res_pm; | ||
297 | int err; | ||
298 | struct lpc_ich_info *ich_info = pdev->dev.platform_data; | ||
299 | |||
300 | if (!ich_info) | ||
301 | return -ENODEV; | ||
302 | |||
303 | ichx_priv.dev = pdev; | ||
304 | |||
305 | switch (ich_info->gpio_version) { | ||
306 | case ICH_I3100_GPIO: | ||
307 | ichx_priv.desc = &i3100_desc; | ||
308 | break; | ||
309 | case ICH_V5_GPIO: | ||
310 | ichx_priv.desc = &intel5_desc; | ||
311 | break; | ||
312 | case ICH_V6_GPIO: | ||
313 | ichx_priv.desc = &ich6_desc; | ||
314 | break; | ||
315 | case ICH_V7_GPIO: | ||
316 | ichx_priv.desc = &ich7_desc; | ||
317 | break; | ||
318 | case ICH_V9_GPIO: | ||
319 | ichx_priv.desc = &ich9_desc; | ||
320 | break; | ||
321 | case ICH_V10CORP_GPIO: | ||
322 | ichx_priv.desc = &ich10_corp_desc; | ||
323 | break; | ||
324 | case ICH_V10CONS_GPIO: | ||
325 | ichx_priv.desc = &ich10_cons_desc; | ||
326 | break; | ||
327 | default: | ||
328 | return -ENODEV; | ||
329 | } | ||
330 | |||
331 | res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); | ||
332 | if (!res_base || !res_base->start || !res_base->end) | ||
333 | return -ENODEV; | ||
334 | |||
335 | if (!request_region(res_base->start, resource_size(res_base), | ||
336 | pdev->name)) | ||
337 | return -EBUSY; | ||
338 | |||
339 | ichx_priv.gpio_base = res_base; | ||
340 | |||
341 | /* | ||
342 | * If necessary, determine the I/O address of ACPI/power management | ||
343 | * registers which are needed to read the the GPE0 register for GPI pins | ||
344 | * 0 - 15 on some chipsets. | ||
345 | */ | ||
346 | if (!ichx_priv.desc->uses_gpe0) | ||
347 | goto init; | ||
348 | |||
349 | res_pm = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPE0); | ||
350 | if (!res_pm) { | ||
351 | pr_warn("ACPI BAR is unavailable, GPI 0 - 15 unavailable\n"); | ||
352 | goto init; | ||
353 | } | ||
354 | |||
355 | if (!request_region(res_pm->start, resource_size(res_pm), | ||
356 | pdev->name)) { | ||
357 | pr_warn("ACPI BAR is busy, GPI 0 - 15 unavailable\n"); | ||
358 | goto init; | ||
359 | } | ||
360 | |||
361 | ichx_priv.pm_base = res_pm; | ||
362 | |||
363 | init: | ||
364 | ichx_gpiolib_setup(&ichx_priv.chip); | ||
365 | err = gpiochip_add(&ichx_priv.chip); | ||
366 | if (err) { | ||
367 | pr_err("Failed to register GPIOs\n"); | ||
368 | goto add_err; | ||
369 | } | ||
370 | |||
371 | pr_info("GPIO from %d to %d on %s\n", ichx_priv.chip.base, | ||
372 | ichx_priv.chip.base + ichx_priv.chip.ngpio - 1, DRV_NAME); | ||
373 | |||
374 | return 0; | ||
375 | |||
376 | add_err: | ||
377 | release_region(ichx_priv.gpio_base->start, | ||
378 | resource_size(ichx_priv.gpio_base)); | ||
379 | if (ichx_priv.pm_base) | ||
380 | release_region(ichx_priv.pm_base->start, | ||
381 | resource_size(ichx_priv.pm_base)); | ||
382 | return err; | ||
383 | } | ||
384 | |||
385 | static int __devexit ichx_gpio_remove(struct platform_device *pdev) | ||
386 | { | ||
387 | int err; | ||
388 | |||
389 | err = gpiochip_remove(&ichx_priv.chip); | ||
390 | if (err) { | ||
391 | dev_err(&pdev->dev, "%s failed, %d\n", | ||
392 | "gpiochip_remove()", err); | ||
393 | return err; | ||
394 | } | ||
395 | |||
396 | release_region(ichx_priv.gpio_base->start, | ||
397 | resource_size(ichx_priv.gpio_base)); | ||
398 | if (ichx_priv.pm_base) | ||
399 | release_region(ichx_priv.pm_base->start, | ||
400 | resource_size(ichx_priv.pm_base)); | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | static struct platform_driver ichx_gpio_driver = { | ||
406 | .driver = { | ||
407 | .owner = THIS_MODULE, | ||
408 | .name = DRV_NAME, | ||
409 | }, | ||
410 | .probe = ichx_gpio_probe, | ||
411 | .remove = __devexit_p(ichx_gpio_remove), | ||
412 | }; | ||
413 | |||
414 | module_platform_driver(ichx_gpio_driver); | ||
415 | |||
416 | MODULE_AUTHOR("Peter Tyser <ptyser@xes-inc.com>"); | ||
417 | MODULE_DESCRIPTION("GPIO interface for Intel ICH series"); | ||
418 | MODULE_LICENSE("GPL"); | ||
419 | MODULE_ALIAS("platform:"DRV_NAME); | ||
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 8cadf4d683a8..424dce8e3f30 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -232,6 +232,14 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) | |||
232 | sch_gpio_resume.ngpio = 9; | 232 | sch_gpio_resume.ngpio = 9; |
233 | break; | 233 | break; |
234 | 234 | ||
235 | case PCI_DEVICE_ID_INTEL_CENTERTON_ILB: | ||
236 | sch_gpio_core.base = 0; | ||
237 | sch_gpio_core.ngpio = 21; | ||
238 | |||
239 | sch_gpio_resume.base = 21; | ||
240 | sch_gpio_resume.ngpio = 9; | ||
241 | break; | ||
242 | |||
235 | default: | 243 | default: |
236 | return -ENODEV; | 244 | return -ENODEV; |
237 | } | 245 | } |
diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c new file mode 100644 index 000000000000..38416be8ba11 --- /dev/null +++ b/drivers/gpio/gpio-sta2x11.c | |||
@@ -0,0 +1,435 @@ | |||
1 | /* | ||
2 | * STMicroelectronics ConneXt (STA2X11) GPIO driver | ||
3 | * | ||
4 | * Copyright 2012 ST Microelectronics (Alessandro Rubini) | ||
5 | * Based on gpio-ml-ioh.c, Copyright 2010 OKI Semiconductors Ltd. | ||
6 | * Also based on previous sta2x11 work, Copyright 2011 Wind River Systems, Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
15 | * See the GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/irq.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/mfd/sta2x11-mfd.h> | ||
32 | |||
33 | struct gsta_regs { | ||
34 | u32 dat; /* 0x00 */ | ||
35 | u32 dats; | ||
36 | u32 datc; | ||
37 | u32 pdis; | ||
38 | u32 dir; /* 0x10 */ | ||
39 | u32 dirs; | ||
40 | u32 dirc; | ||
41 | u32 unused_1c; | ||
42 | u32 afsela; /* 0x20 */ | ||
43 | u32 unused_24[7]; | ||
44 | u32 rimsc; /* 0x40 */ | ||
45 | u32 fimsc; | ||
46 | u32 is; | ||
47 | u32 ic; | ||
48 | }; | ||
49 | |||
50 | struct gsta_gpio { | ||
51 | spinlock_t lock; | ||
52 | struct device *dev; | ||
53 | void __iomem *reg_base; | ||
54 | struct gsta_regs __iomem *regs[GSTA_NR_BLOCKS]; | ||
55 | struct gpio_chip gpio; | ||
56 | int irq_base; | ||
57 | /* FIXME: save the whole config here (AF, ...) */ | ||
58 | unsigned irq_type[GSTA_NR_GPIO]; | ||
59 | }; | ||
60 | |||
61 | static inline struct gsta_regs __iomem *__regs(struct gsta_gpio *chip, int nr) | ||
62 | { | ||
63 | return chip->regs[nr / GSTA_GPIO_PER_BLOCK]; | ||
64 | } | ||
65 | |||
66 | static inline u32 __bit(int nr) | ||
67 | { | ||
68 | return 1U << (nr % GSTA_GPIO_PER_BLOCK); | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * gpio methods | ||
73 | */ | ||
74 | |||
75 | static void gsta_gpio_set(struct gpio_chip *gpio, unsigned nr, int val) | ||
76 | { | ||
77 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
78 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
79 | u32 bit = __bit(nr); | ||
80 | |||
81 | if (val) | ||
82 | writel(bit, ®s->dats); | ||
83 | else | ||
84 | writel(bit, ®s->datc); | ||
85 | } | ||
86 | |||
87 | static int gsta_gpio_get(struct gpio_chip *gpio, unsigned nr) | ||
88 | { | ||
89 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
90 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
91 | u32 bit = __bit(nr); | ||
92 | |||
93 | return readl(®s->dat) & bit; | ||
94 | } | ||
95 | |||
96 | static int gsta_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | ||
97 | int val) | ||
98 | { | ||
99 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
100 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
101 | u32 bit = __bit(nr); | ||
102 | |||
103 | writel(bit, ®s->dirs); | ||
104 | /* Data register after direction, otherwise pullup/down is selected */ | ||
105 | if (val) | ||
106 | writel(bit, ®s->dats); | ||
107 | else | ||
108 | writel(bit, ®s->datc); | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static int gsta_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) | ||
113 | { | ||
114 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
115 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
116 | u32 bit = __bit(nr); | ||
117 | |||
118 | writel(bit, ®s->dirc); | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static int gsta_gpio_to_irq(struct gpio_chip *gpio, unsigned offset) | ||
123 | { | ||
124 | struct gsta_gpio *chip = container_of(gpio, struct gsta_gpio, gpio); | ||
125 | return chip->irq_base + offset; | ||
126 | } | ||
127 | |||
128 | static void gsta_gpio_setup(struct gsta_gpio *chip) /* called from probe */ | ||
129 | { | ||
130 | struct gpio_chip *gpio = &chip->gpio; | ||
131 | |||
132 | /* | ||
133 | * ARCH_NR_GPIOS is currently 256 and dynamic allocation starts | ||
134 | * from the end. However, for compatibility, we need the first | ||
135 | * ConneXt device to start from gpio 0: it's the main chipset | ||
136 | * on most boards so documents and drivers assume gpio0..gpio127 | ||
137 | */ | ||
138 | static int gpio_base; | ||
139 | |||
140 | gpio->label = dev_name(chip->dev); | ||
141 | gpio->owner = THIS_MODULE; | ||
142 | gpio->direction_input = gsta_gpio_direction_input; | ||
143 | gpio->get = gsta_gpio_get; | ||
144 | gpio->direction_output = gsta_gpio_direction_output; | ||
145 | gpio->set = gsta_gpio_set; | ||
146 | gpio->dbg_show = NULL; | ||
147 | gpio->base = gpio_base; | ||
148 | gpio->ngpio = GSTA_NR_GPIO; | ||
149 | gpio->can_sleep = 0; | ||
150 | gpio->to_irq = gsta_gpio_to_irq; | ||
151 | |||
152 | /* | ||
153 | * After the first device, turn to dynamic gpio numbers. | ||
154 | * For example, with ARCH_NR_GPIOS = 256 we can fit two cards | ||
155 | */ | ||
156 | if (!gpio_base) | ||
157 | gpio_base = -1; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Special method: alternate functions and pullup/pulldown. This is only | ||
162 | * invoked on startup to configure gpio's according to platform data. | ||
163 | * FIXME : this functionality shall be managed (and exported to other drivers) | ||
164 | * via the pin control subsystem. | ||
165 | */ | ||
166 | static void gsta_set_config(struct gsta_gpio *chip, int nr, unsigned cfg) | ||
167 | { | ||
168 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
169 | unsigned long flags; | ||
170 | u32 bit = __bit(nr); | ||
171 | u32 val; | ||
172 | int err = 0; | ||
173 | |||
174 | pr_info("%s: %p %i %i\n", __func__, chip, nr, cfg); | ||
175 | |||
176 | if (cfg == PINMUX_TYPE_NONE) | ||
177 | return; | ||
178 | |||
179 | /* Alternate function or not? */ | ||
180 | spin_lock_irqsave(&chip->lock, flags); | ||
181 | val = readl(®s->afsela); | ||
182 | if (cfg == PINMUX_TYPE_FUNCTION) | ||
183 | val |= bit; | ||
184 | else | ||
185 | val &= ~bit; | ||
186 | writel(val | bit, ®s->afsela); | ||
187 | if (cfg == PINMUX_TYPE_FUNCTION) { | ||
188 | spin_unlock_irqrestore(&chip->lock, flags); | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | /* not alternate function: set details */ | ||
193 | switch (cfg) { | ||
194 | case PINMUX_TYPE_OUTPUT_LOW: | ||
195 | writel(bit, ®s->dirs); | ||
196 | writel(bit, ®s->datc); | ||
197 | break; | ||
198 | case PINMUX_TYPE_OUTPUT_HIGH: | ||
199 | writel(bit, ®s->dirs); | ||
200 | writel(bit, ®s->dats); | ||
201 | break; | ||
202 | case PINMUX_TYPE_INPUT: | ||
203 | writel(bit, ®s->dirc); | ||
204 | val = readl(®s->pdis) | bit; | ||
205 | writel(val, ®s->pdis); | ||
206 | break; | ||
207 | case PINMUX_TYPE_INPUT_PULLUP: | ||
208 | writel(bit, ®s->dirc); | ||
209 | val = readl(®s->pdis) & ~bit; | ||
210 | writel(val, ®s->pdis); | ||
211 | writel(bit, ®s->dats); | ||
212 | break; | ||
213 | case PINMUX_TYPE_INPUT_PULLDOWN: | ||
214 | writel(bit, ®s->dirc); | ||
215 | val = readl(®s->pdis) & ~bit; | ||
216 | writel(val, ®s->pdis); | ||
217 | writel(bit, ®s->datc); | ||
218 | break; | ||
219 | default: | ||
220 | err = 1; | ||
221 | } | ||
222 | spin_unlock_irqrestore(&chip->lock, flags); | ||
223 | if (err) | ||
224 | pr_err("%s: chip %p, pin %i, cfg %i is invalid\n", | ||
225 | __func__, chip, nr, cfg); | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * Irq methods | ||
230 | */ | ||
231 | |||
232 | static void gsta_irq_disable(struct irq_data *data) | ||
233 | { | ||
234 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | ||
235 | struct gsta_gpio *chip = gc->private; | ||
236 | int nr = data->irq - chip->irq_base; | ||
237 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
238 | u32 bit = __bit(nr); | ||
239 | u32 val; | ||
240 | unsigned long flags; | ||
241 | |||
242 | spin_lock_irqsave(&chip->lock, flags); | ||
243 | if (chip->irq_type[nr] & IRQ_TYPE_EDGE_RISING) { | ||
244 | val = readl(®s->rimsc) & ~bit; | ||
245 | writel(val, ®s->rimsc); | ||
246 | } | ||
247 | if (chip->irq_type[nr] & IRQ_TYPE_EDGE_FALLING) { | ||
248 | val = readl(®s->fimsc) & ~bit; | ||
249 | writel(val, ®s->fimsc); | ||
250 | } | ||
251 | spin_unlock_irqrestore(&chip->lock, flags); | ||
252 | return; | ||
253 | } | ||
254 | |||
255 | static void gsta_irq_enable(struct irq_data *data) | ||
256 | { | ||
257 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); | ||
258 | struct gsta_gpio *chip = gc->private; | ||
259 | int nr = data->irq - chip->irq_base; | ||
260 | struct gsta_regs __iomem *regs = __regs(chip, nr); | ||
261 | u32 bit = __bit(nr); | ||
262 | u32 val; | ||
263 | int type; | ||
264 | unsigned long flags; | ||
265 | |||
266 | type = chip->irq_type[nr]; | ||
267 | |||
268 | spin_lock_irqsave(&chip->lock, flags); | ||
269 | val = readl(®s->rimsc); | ||
270 | if (type & IRQ_TYPE_EDGE_RISING) | ||
271 | writel(val | bit, ®s->rimsc); | ||
272 | else | ||
273 | writel(val & ~bit, ®s->rimsc); | ||
274 | val = readl(®s->rimsc); | ||
275 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
276 | writel(val | bit, ®s->fimsc); | ||
277 | else | ||
278 | writel(val & ~bit, ®s->fimsc); | ||
279 | spin_unlock_irqrestore(&chip->lock, flags); | ||
280 | return; | ||
281 | } | ||
282 | |||
283 | static int gsta_irq_type(struct irq_data *d, unsigned int type) | ||
284 | { | ||
285 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
286 | struct gsta_gpio *chip = gc->private; | ||
287 | int nr = d->irq - chip->irq_base; | ||
288 | |||
289 | /* We only support edge interrupts */ | ||
290 | if (!(type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))) { | ||
291 | pr_debug("%s: unsupported type 0x%x\n", __func__, type); | ||
292 | return -EINVAL; | ||
293 | } | ||
294 | |||
295 | chip->irq_type[nr] = type; /* used for enable/disable */ | ||
296 | |||
297 | gsta_irq_enable(d); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static irqreturn_t gsta_gpio_handler(int irq, void *dev_id) | ||
302 | { | ||
303 | struct gsta_gpio *chip = dev_id; | ||
304 | struct gsta_regs __iomem *regs; | ||
305 | u32 is; | ||
306 | int i, nr, base; | ||
307 | irqreturn_t ret = IRQ_NONE; | ||
308 | |||
309 | for (i = 0; i < GSTA_NR_BLOCKS; i++) { | ||
310 | regs = chip->regs[i]; | ||
311 | base = chip->irq_base + i * GSTA_GPIO_PER_BLOCK; | ||
312 | while ((is = readl(®s->is))) { | ||
313 | nr = __ffs(is); | ||
314 | irq = base + nr; | ||
315 | generic_handle_irq(irq); | ||
316 | writel(1 << nr, ®s->ic); | ||
317 | ret = IRQ_HANDLED; | ||
318 | } | ||
319 | } | ||
320 | return ret; | ||
321 | } | ||
322 | |||
323 | static __devinit void gsta_alloc_irq_chip(struct gsta_gpio *chip) | ||
324 | { | ||
325 | struct irq_chip_generic *gc; | ||
326 | struct irq_chip_type *ct; | ||
327 | |||
328 | gc = irq_alloc_generic_chip(KBUILD_MODNAME, 1, chip->irq_base, | ||
329 | chip->reg_base, handle_simple_irq); | ||
330 | gc->private = chip; | ||
331 | ct = gc->chip_types; | ||
332 | |||
333 | ct->chip.irq_set_type = gsta_irq_type; | ||
334 | ct->chip.irq_disable = gsta_irq_disable; | ||
335 | ct->chip.irq_enable = gsta_irq_enable; | ||
336 | |||
337 | /* FIXME: this makes at most 32 interrupts. Request 0 by now */ | ||
338 | irq_setup_generic_chip(gc, 0 /* IRQ_MSK(GSTA_GPIO_PER_BLOCK) */, 0, | ||
339 | IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
340 | |||
341 | /* Set up all all 128 interrupts: code from setup_generic_chip */ | ||
342 | { | ||
343 | struct irq_chip_type *ct = gc->chip_types; | ||
344 | int i, j; | ||
345 | for (j = 0; j < GSTA_NR_GPIO; j++) { | ||
346 | i = chip->irq_base + j; | ||
347 | irq_set_chip_and_handler(i, &ct->chip, ct->handler); | ||
348 | irq_set_chip_data(i, gc); | ||
349 | irq_modify_status(i, IRQ_NOREQUEST | IRQ_NOPROBE, 0); | ||
350 | } | ||
351 | gc->irq_cnt = i - gc->irq_base; | ||
352 | } | ||
353 | } | ||
354 | |||
355 | /* The platform device used here is instantiated by the MFD device */ | ||
356 | static int __devinit gsta_probe(struct platform_device *dev) | ||
357 | { | ||
358 | int i, err; | ||
359 | struct pci_dev *pdev; | ||
360 | struct sta2x11_gpio_pdata *gpio_pdata; | ||
361 | struct gsta_gpio *chip; | ||
362 | struct resource *res; | ||
363 | |||
364 | pdev = *(struct pci_dev **)(dev->dev.platform_data); | ||
365 | gpio_pdata = dev_get_platdata(&pdev->dev); | ||
366 | |||
367 | if (gpio_pdata == NULL) | ||
368 | dev_err(&dev->dev, "no gpio config\n"); | ||
369 | pr_debug("gpio config: %p\n", gpio_pdata); | ||
370 | |||
371 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
372 | |||
373 | chip = devm_kzalloc(&dev->dev, sizeof(*chip), GFP_KERNEL); | ||
374 | chip->dev = &dev->dev; | ||
375 | chip->reg_base = devm_request_and_ioremap(&dev->dev, res); | ||
376 | |||
377 | for (i = 0; i < GSTA_NR_BLOCKS; i++) { | ||
378 | chip->regs[i] = chip->reg_base + i * 4096; | ||
379 | /* disable all irqs */ | ||
380 | writel(0, &chip->regs[i]->rimsc); | ||
381 | writel(0, &chip->regs[i]->fimsc); | ||
382 | writel(~0, &chip->regs[i]->ic); | ||
383 | } | ||
384 | spin_lock_init(&chip->lock); | ||
385 | gsta_gpio_setup(chip); | ||
386 | for (i = 0; i < GSTA_NR_GPIO; i++) | ||
387 | gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); | ||
388 | |||
389 | /* 384 was used in previous code: be compatible for other drivers */ | ||
390 | err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); | ||
391 | if (err < 0) { | ||
392 | dev_warn(&dev->dev, "sta2x11 gpio: Can't get irq base (%i)\n", | ||
393 | -err); | ||
394 | return err; | ||
395 | } | ||
396 | chip->irq_base = err; | ||
397 | gsta_alloc_irq_chip(chip); | ||
398 | |||
399 | err = request_irq(pdev->irq, gsta_gpio_handler, | ||
400 | IRQF_SHARED, KBUILD_MODNAME, chip); | ||
401 | if (err < 0) { | ||
402 | dev_err(&dev->dev, "sta2x11 gpio: Can't request irq (%i)\n", | ||
403 | -err); | ||
404 | goto err_free_descs; | ||
405 | } | ||
406 | |||
407 | err = gpiochip_add(&chip->gpio); | ||
408 | if (err < 0) { | ||
409 | dev_err(&dev->dev, "sta2x11 gpio: Can't register (%i)\n", | ||
410 | -err); | ||
411 | goto err_free_irq; | ||
412 | } | ||
413 | |||
414 | platform_set_drvdata(dev, chip); | ||
415 | return 0; | ||
416 | |||
417 | err_free_irq: | ||
418 | free_irq(pdev->irq, chip); | ||
419 | err_free_descs: | ||
420 | irq_free_descs(chip->irq_base, GSTA_NR_GPIO); | ||
421 | return err; | ||
422 | } | ||
423 | |||
424 | static struct platform_driver sta2x11_gpio_platform_driver = { | ||
425 | .driver = { | ||
426 | .name = "sta2x11-gpio", | ||
427 | .owner = THIS_MODULE, | ||
428 | }, | ||
429 | .probe = gsta_probe, | ||
430 | }; | ||
431 | |||
432 | module_platform_driver(sta2x11_gpio_platform_driver); | ||
433 | |||
434 | MODULE_LICENSE("GPL v2"); | ||
435 | MODULE_DESCRIPTION("sta2x11_gpio GPIO driver"); | ||
diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index 7eef648a3351..c1ad2884f2ed 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c | |||
@@ -18,14 +18,27 @@ | |||
18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/platform_device.h> | ||
21 | #include <linux/mfd/tps65910.h> | 22 | #include <linux/mfd/tps65910.h> |
23 | #include <linux/of_device.h> | ||
24 | |||
25 | struct tps65910_gpio { | ||
26 | struct gpio_chip gpio_chip; | ||
27 | struct tps65910 *tps65910; | ||
28 | }; | ||
29 | |||
30 | static inline struct tps65910_gpio *to_tps65910_gpio(struct gpio_chip *chip) | ||
31 | { | ||
32 | return container_of(chip, struct tps65910_gpio, gpio_chip); | ||
33 | } | ||
22 | 34 | ||
23 | static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) | 35 | static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) |
24 | { | 36 | { |
25 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 37 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
26 | uint8_t val; | 38 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; |
39 | unsigned int val; | ||
27 | 40 | ||
28 | tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val); | 41 | tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val); |
29 | 42 | ||
30 | if (val & GPIO_STS_MASK) | 43 | if (val & GPIO_STS_MASK) |
31 | return 1; | 44 | return 1; |
@@ -36,83 +49,170 @@ static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) | |||
36 | static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, | 49 | static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, |
37 | int value) | 50 | int value) |
38 | { | 51 | { |
39 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 52 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
53 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; | ||
40 | 54 | ||
41 | if (value) | 55 | if (value) |
42 | tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, | 56 | tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset, |
43 | GPIO_SET_MASK); | 57 | GPIO_SET_MASK); |
44 | else | 58 | else |
45 | tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, | 59 | tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset, |
46 | GPIO_SET_MASK); | 60 | GPIO_SET_MASK); |
47 | } | 61 | } |
48 | 62 | ||
49 | static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, | 63 | static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, |
50 | int value) | 64 | int value) |
51 | { | 65 | { |
52 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 66 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
67 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; | ||
53 | 68 | ||
54 | /* Set the initial value */ | 69 | /* Set the initial value */ |
55 | tps65910_gpio_set(gc, offset, value); | 70 | tps65910_gpio_set(gc, offset, value); |
56 | 71 | ||
57 | return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, | 72 | return tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset, |
58 | GPIO_CFG_MASK); | 73 | GPIO_CFG_MASK); |
59 | } | 74 | } |
60 | 75 | ||
61 | static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) | 76 | static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) |
62 | { | 77 | { |
63 | struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); | 78 | struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc); |
79 | struct tps65910 *tps65910 = tps65910_gpio->tps65910; | ||
64 | 80 | ||
65 | return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, | 81 | return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset, |
66 | GPIO_CFG_MASK); | 82 | GPIO_CFG_MASK); |
67 | } | 83 | } |
68 | 84 | ||
69 | void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) | 85 | #ifdef CONFIG_OF |
86 | static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, | ||
87 | struct tps65910 *tps65910, int chip_ngpio) | ||
70 | { | 88 | { |
89 | struct tps65910_board *tps65910_board = tps65910->of_plat_data; | ||
90 | unsigned int prop_array[TPS6591X_MAX_NUM_GPIO]; | ||
91 | int ngpio = min(chip_ngpio, TPS6591X_MAX_NUM_GPIO); | ||
71 | int ret; | 92 | int ret; |
72 | struct tps65910_board *board_data; | 93 | int idx; |
94 | |||
95 | tps65910_board->gpio_base = -1; | ||
96 | ret = of_property_read_u32_array(tps65910->dev->of_node, | ||
97 | "ti,en-gpio-sleep", prop_array, ngpio); | ||
98 | if (ret < 0) { | ||
99 | dev_dbg(dev, "ti,en-gpio-sleep not specified\n"); | ||
100 | return tps65910_board; | ||
101 | } | ||
73 | 102 | ||
74 | if (!gpio_base) | 103 | for (idx = 0; idx < ngpio; idx++) |
75 | return; | 104 | tps65910_board->en_gpio_sleep[idx] = (prop_array[idx] != 0); |
76 | 105 | ||
77 | tps65910->gpio.owner = THIS_MODULE; | 106 | return tps65910_board; |
78 | tps65910->gpio.label = tps65910->i2c_client->name; | 107 | } |
79 | tps65910->gpio.dev = tps65910->dev; | 108 | #else |
80 | tps65910->gpio.base = gpio_base; | 109 | static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev, |
110 | struct tps65910 *tps65910, int chip_ngpio) | ||
111 | { | ||
112 | return NULL; | ||
113 | } | ||
114 | #endif | ||
115 | |||
116 | static int __devinit tps65910_gpio_probe(struct platform_device *pdev) | ||
117 | { | ||
118 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | ||
119 | struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); | ||
120 | struct tps65910_gpio *tps65910_gpio; | ||
121 | int ret; | ||
122 | int i; | ||
123 | |||
124 | tps65910_gpio = devm_kzalloc(&pdev->dev, | ||
125 | sizeof(*tps65910_gpio), GFP_KERNEL); | ||
126 | if (!tps65910_gpio) { | ||
127 | dev_err(&pdev->dev, "Could not allocate tps65910_gpio\n"); | ||
128 | return -ENOMEM; | ||
129 | } | ||
130 | |||
131 | tps65910_gpio->tps65910 = tps65910; | ||
132 | |||
133 | tps65910_gpio->gpio_chip.owner = THIS_MODULE; | ||
134 | tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name; | ||
81 | 135 | ||
82 | switch(tps65910_chip_id(tps65910)) { | 136 | switch(tps65910_chip_id(tps65910)) { |
83 | case TPS65910: | 137 | case TPS65910: |
84 | tps65910->gpio.ngpio = TPS65910_NUM_GPIO; | 138 | tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO; |
85 | break; | 139 | break; |
86 | case TPS65911: | 140 | case TPS65911: |
87 | tps65910->gpio.ngpio = TPS65911_NUM_GPIO; | 141 | tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO; |
88 | break; | 142 | break; |
89 | default: | 143 | default: |
90 | return; | 144 | return -EINVAL; |
145 | } | ||
146 | tps65910_gpio->gpio_chip.can_sleep = 1; | ||
147 | tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input; | ||
148 | tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output; | ||
149 | tps65910_gpio->gpio_chip.set = tps65910_gpio_set; | ||
150 | tps65910_gpio->gpio_chip.get = tps65910_gpio_get; | ||
151 | tps65910_gpio->gpio_chip.dev = &pdev->dev; | ||
152 | if (pdata && pdata->gpio_base) | ||
153 | tps65910_gpio->gpio_chip.base = pdata->gpio_base; | ||
154 | else | ||
155 | tps65910_gpio->gpio_chip.base = -1; | ||
156 | |||
157 | if (!pdata && tps65910->dev->of_node) | ||
158 | pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910, | ||
159 | tps65910_gpio->gpio_chip.ngpio); | ||
160 | |||
161 | if (!pdata) | ||
162 | goto skip_init; | ||
163 | |||
164 | /* Configure sleep control for gpios if provided */ | ||
165 | for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) { | ||
166 | if (!pdata->en_gpio_sleep[i]) | ||
167 | continue; | ||
168 | |||
169 | ret = tps65910_reg_set_bits(tps65910, | ||
170 | TPS65910_GPIO0 + i, GPIO_SLEEP_MASK); | ||
171 | if (ret < 0) | ||
172 | dev_warn(tps65910->dev, | ||
173 | "GPIO Sleep setting failed with err %d\n", ret); | ||
91 | } | 174 | } |
92 | tps65910->gpio.can_sleep = 1; | 175 | |
93 | 176 | skip_init: | |
94 | tps65910->gpio.direction_input = tps65910_gpio_input; | 177 | ret = gpiochip_add(&tps65910_gpio->gpio_chip); |
95 | tps65910->gpio.direction_output = tps65910_gpio_output; | 178 | if (ret < 0) { |
96 | tps65910->gpio.set = tps65910_gpio_set; | 179 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); |
97 | tps65910->gpio.get = tps65910_gpio_get; | 180 | return ret; |
98 | |||
99 | /* Configure sleep control for gpios */ | ||
100 | board_data = dev_get_platdata(tps65910->dev); | ||
101 | if (board_data) { | ||
102 | int i; | ||
103 | for (i = 0; i < tps65910->gpio.ngpio; ++i) { | ||
104 | if (board_data->en_gpio_sleep[i]) { | ||
105 | ret = tps65910_set_bits(tps65910, | ||
106 | TPS65910_GPIO0 + i, GPIO_SLEEP_MASK); | ||
107 | if (ret < 0) | ||
108 | dev_warn(tps65910->dev, | ||
109 | "GPIO Sleep setting failed\n"); | ||
110 | } | ||
111 | } | ||
112 | } | 181 | } |
113 | 182 | ||
114 | ret = gpiochip_add(&tps65910->gpio); | 183 | platform_set_drvdata(pdev, tps65910_gpio); |
184 | |||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static int __devexit tps65910_gpio_remove(struct platform_device *pdev) | ||
189 | { | ||
190 | struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev); | ||
115 | 191 | ||
116 | if (ret) | 192 | return gpiochip_remove(&tps65910_gpio->gpio_chip); |
117 | dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret); | ||
118 | } | 193 | } |
194 | |||
195 | static struct platform_driver tps65910_gpio_driver = { | ||
196 | .driver.name = "tps65910-gpio", | ||
197 | .driver.owner = THIS_MODULE, | ||
198 | .probe = tps65910_gpio_probe, | ||
199 | .remove = __devexit_p(tps65910_gpio_remove), | ||
200 | }; | ||
201 | |||
202 | static int __init tps65910_gpio_init(void) | ||
203 | { | ||
204 | return platform_driver_register(&tps65910_gpio_driver); | ||
205 | } | ||
206 | subsys_initcall(tps65910_gpio_init); | ||
207 | |||
208 | static void __exit tps65910_gpio_exit(void) | ||
209 | { | ||
210 | platform_driver_unregister(&tps65910_gpio_driver); | ||
211 | } | ||
212 | module_exit(tps65910_gpio_exit); | ||
213 | |||
214 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | ||
215 | MODULE_AUTHOR("Jorge Eduardo Candelaria jedu@slimlogic.co.uk>"); | ||
216 | MODULE_DESCRIPTION("GPIO interface for TPS65910/TPS6511 PMICs"); | ||
217 | MODULE_LICENSE("GPL v2"); | ||
218 | MODULE_ALIAS("platform:tps65910-gpio"); | ||
diff --git a/drivers/gpio/gpio-wm831x.c b/drivers/gpio/gpio-wm831x.c index deb949e75ec1..e56a2165641c 100644 --- a/drivers/gpio/gpio-wm831x.c +++ b/drivers/gpio/gpio-wm831x.c | |||
@@ -102,10 +102,8 @@ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
102 | struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); | 102 | struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); |
103 | struct wm831x *wm831x = wm831x_gpio->wm831x; | 103 | struct wm831x *wm831x = wm831x_gpio->wm831x; |
104 | 104 | ||
105 | if (!wm831x->irq_base) | 105 | return irq_create_mapping(wm831x->irq_domain, |
106 | return -EINVAL; | 106 | WM831X_IRQ_GPIO_1 + offset); |
107 | |||
108 | return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset; | ||
109 | } | 107 | } |
110 | 108 | ||
111 | static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, | 109 | static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, |
diff --git a/drivers/input/misc/wm831x-on.c b/drivers/input/misc/wm831x-on.c index 47f18d6bce46..6790a812a1db 100644 --- a/drivers/input/misc/wm831x-on.c +++ b/drivers/input/misc/wm831x-on.c | |||
@@ -73,7 +73,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) | |||
73 | { | 73 | { |
74 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 74 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
75 | struct wm831x_on *wm831x_on; | 75 | struct wm831x_on *wm831x_on; |
76 | int irq = platform_get_irq(pdev, 0); | 76 | int irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0)); |
77 | int ret; | 77 | int ret; |
78 | 78 | ||
79 | wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL); | 79 | wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL); |
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index 4bc851a9dc3d..e83410721e38 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c | |||
@@ -260,15 +260,16 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) | |||
260 | * If we have a direct IRQ use it, otherwise use the interrupt | 260 | * If we have a direct IRQ use it, otherwise use the interrupt |
261 | * from the WM831x IRQ controller. | 261 | * from the WM831x IRQ controller. |
262 | */ | 262 | */ |
263 | wm831x_ts->data_irq = wm831x_irq(wm831x, | ||
264 | platform_get_irq_byname(pdev, | ||
265 | "TCHDATA")); | ||
263 | if (pdata && pdata->data_irq) | 266 | if (pdata && pdata->data_irq) |
264 | wm831x_ts->data_irq = pdata->data_irq; | 267 | wm831x_ts->data_irq = pdata->data_irq; |
265 | else | ||
266 | wm831x_ts->data_irq = platform_get_irq_byname(pdev, "TCHDATA"); | ||
267 | 268 | ||
269 | wm831x_ts->pd_irq = wm831x_irq(wm831x, | ||
270 | platform_get_irq_byname(pdev, "TCHPD")); | ||
268 | if (pdata && pdata->pd_irq) | 271 | if (pdata && pdata->pd_irq) |
269 | wm831x_ts->pd_irq = pdata->pd_irq; | 272 | wm831x_ts->pd_irq = pdata->pd_irq; |
270 | else | ||
271 | wm831x_ts->pd_irq = platform_get_irq_byname(pdev, "TCHPD"); | ||
272 | 273 | ||
273 | if (pdata) | 274 | if (pdata) |
274 | wm831x_ts->pressure = pdata->pressure; | 275 | wm831x_ts->pressure = pdata->pressure; |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index f4b4dad77391..e129c820df7d 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -106,6 +106,19 @@ config UCB1400_CORE | |||
106 | To compile this driver as a module, choose M here: the | 106 | To compile this driver as a module, choose M here: the |
107 | module will be called ucb1400_core. | 107 | module will be called ucb1400_core. |
108 | 108 | ||
109 | config MFD_LM3533 | ||
110 | tristate "LM3533 Lighting Power chip" | ||
111 | depends on I2C | ||
112 | select MFD_CORE | ||
113 | select REGMAP_I2C | ||
114 | help | ||
115 | Say yes here to enable support for National Semiconductor / TI | ||
116 | LM3533 Lighting Power chips. | ||
117 | |||
118 | This driver provides common support for accessing the device; | ||
119 | additional drivers must be enabled in order to use the LED, | ||
120 | backlight or ambient-light-sensor functionality of the device. | ||
121 | |||
109 | config TPS6105X | 122 | config TPS6105X |
110 | tristate "TPS61050/61052 Boost Converters" | 123 | tristate "TPS61050/61052 Boost Converters" |
111 | depends on I2C | 124 | depends on I2C |
@@ -177,8 +190,8 @@ config MFD_TPS65910 | |||
177 | bool "TPS65910 Power Management chip" | 190 | bool "TPS65910 Power Management chip" |
178 | depends on I2C=y && GPIOLIB | 191 | depends on I2C=y && GPIOLIB |
179 | select MFD_CORE | 192 | select MFD_CORE |
180 | select GPIO_TPS65910 | ||
181 | select REGMAP_I2C | 193 | select REGMAP_I2C |
194 | select IRQ_DOMAIN | ||
182 | help | 195 | help |
183 | if you say yes here you get support for the TPS65910 series of | 196 | if you say yes here you get support for the TPS65910 series of |
184 | Power Management chips. | 197 | Power Management chips. |
@@ -409,6 +422,19 @@ config PMIC_ADP5520 | |||
409 | individual components like LCD backlight, LEDs, GPIOs and Kepad | 422 | individual components like LCD backlight, LEDs, GPIOs and Kepad |
410 | under the corresponding menus. | 423 | under the corresponding menus. |
411 | 424 | ||
425 | config MFD_MAX77693 | ||
426 | bool "Maxim Semiconductor MAX77693 PMIC Support" | ||
427 | depends on I2C=y && GENERIC_HARDIRQS | ||
428 | select MFD_CORE | ||
429 | select REGMAP_I2C | ||
430 | help | ||
431 | Say yes here to support for Maxim Semiconductor MAX77693. | ||
432 | This is a companion Power Management IC with Flash, Haptic, Charger, | ||
433 | and MUIC(Micro USB Interface Controller) controls on chip. | ||
434 | This driver provides common support for accessing the device; | ||
435 | additional drivers must be enabled in order to use the functionality | ||
436 | of the device. | ||
437 | |||
412 | config MFD_MAX8925 | 438 | config MFD_MAX8925 |
413 | bool "Maxim Semiconductor MAX8925 PMIC Support" | 439 | bool "Maxim Semiconductor MAX8925 PMIC Support" |
414 | depends on I2C=y && GENERIC_HARDIRQS | 440 | depends on I2C=y && GENERIC_HARDIRQS |
@@ -454,9 +480,9 @@ config MFD_S5M_CORE | |||
454 | of the device | 480 | of the device |
455 | 481 | ||
456 | config MFD_WM8400 | 482 | config MFD_WM8400 |
457 | tristate "Support Wolfson Microelectronics WM8400" | 483 | bool "Support Wolfson Microelectronics WM8400" |
458 | select MFD_CORE | 484 | select MFD_CORE |
459 | depends on I2C | 485 | depends on I2C=y |
460 | select REGMAP_I2C | 486 | select REGMAP_I2C |
461 | help | 487 | help |
462 | Support for the Wolfson Microelecronics WM8400 PMIC and audio | 488 | Support for the Wolfson Microelecronics WM8400 PMIC and audio |
@@ -473,6 +499,7 @@ config MFD_WM831X_I2C | |||
473 | select MFD_CORE | 499 | select MFD_CORE |
474 | select MFD_WM831X | 500 | select MFD_WM831X |
475 | select REGMAP_I2C | 501 | select REGMAP_I2C |
502 | select IRQ_DOMAIN | ||
476 | depends on I2C=y && GENERIC_HARDIRQS | 503 | depends on I2C=y && GENERIC_HARDIRQS |
477 | help | 504 | help |
478 | Support for the Wolfson Microelecronics WM831x and WM832x PMICs | 505 | Support for the Wolfson Microelecronics WM831x and WM832x PMICs |
@@ -485,6 +512,7 @@ config MFD_WM831X_SPI | |||
485 | select MFD_CORE | 512 | select MFD_CORE |
486 | select MFD_WM831X | 513 | select MFD_WM831X |
487 | select REGMAP_SPI | 514 | select REGMAP_SPI |
515 | select IRQ_DOMAIN | ||
488 | depends on SPI_MASTER && GENERIC_HARDIRQS | 516 | depends on SPI_MASTER && GENERIC_HARDIRQS |
489 | help | 517 | help |
490 | Support for the Wolfson Microelecronics WM831x and WM832x PMICs | 518 | Support for the Wolfson Microelecronics WM831x and WM832x PMICs |
@@ -597,17 +625,32 @@ config MFD_MC13783 | |||
597 | tristate | 625 | tristate |
598 | 626 | ||
599 | config MFD_MC13XXX | 627 | config MFD_MC13XXX |
600 | tristate "Support Freescale MC13783 and MC13892" | 628 | tristate |
601 | depends on SPI_MASTER | 629 | depends on SPI_MASTER || I2C |
602 | select MFD_CORE | 630 | select MFD_CORE |
603 | select MFD_MC13783 | 631 | select MFD_MC13783 |
604 | help | 632 | help |
605 | Support for the Freescale (Atlas) PMIC and audio CODECs | 633 | Enable support for the Freescale MC13783 and MC13892 PMICs. |
606 | MC13783 and MC13892. | 634 | This driver provides common support for accessing the device, |
607 | This driver provides common support for accessing the device, | ||
608 | additional drivers must be enabled in order to use the | 635 | additional drivers must be enabled in order to use the |
609 | functionality of the device. | 636 | functionality of the device. |
610 | 637 | ||
638 | config MFD_MC13XXX_SPI | ||
639 | tristate "Freescale MC13783 and MC13892 SPI interface" | ||
640 | depends on SPI_MASTER | ||
641 | select REGMAP_SPI | ||
642 | select MFD_MC13XXX | ||
643 | help | ||
644 | Select this if your MC13xxx is connected via an SPI bus. | ||
645 | |||
646 | config MFD_MC13XXX_I2C | ||
647 | tristate "Freescale MC13892 I2C interface" | ||
648 | depends on I2C | ||
649 | select REGMAP_I2C | ||
650 | select MFD_MC13XXX | ||
651 | help | ||
652 | Select this if your MC13xxx is connected via an I2C bus. | ||
653 | |||
611 | config ABX500_CORE | 654 | config ABX500_CORE |
612 | bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" | 655 | bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" |
613 | default y if ARCH_U300 || ARCH_U8500 | 656 | default y if ARCH_U300 || ARCH_U8500 |
@@ -651,7 +694,7 @@ config EZX_PCAP | |||
651 | 694 | ||
652 | config AB8500_CORE | 695 | config AB8500_CORE |
653 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" | 696 | bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" |
654 | depends on GENERIC_HARDIRQS && ABX500_CORE | 697 | depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU |
655 | select MFD_CORE | 698 | select MFD_CORE |
656 | help | 699 | help |
657 | Select this option to enable access to AB8500 power management | 700 | Select this option to enable access to AB8500 power management |
@@ -722,6 +765,16 @@ config LPC_SCH | |||
722 | LPC bridge function of the Intel SCH provides support for | 765 | LPC bridge function of the Intel SCH provides support for |
723 | System Management Bus and General Purpose I/O. | 766 | System Management Bus and General Purpose I/O. |
724 | 767 | ||
768 | config LPC_ICH | ||
769 | tristate "Intel ICH LPC" | ||
770 | depends on PCI | ||
771 | select MFD_CORE | ||
772 | help | ||
773 | The LPC bridge function of the Intel ICH provides support for | ||
774 | many functional units. This driver provides needed support for | ||
775 | other drivers to control these functions, currently GPIO and | ||
776 | watchdog. | ||
777 | |||
725 | config MFD_RDC321X | 778 | config MFD_RDC321X |
726 | tristate "Support for RDC-R321x southbridge" | 779 | tristate "Support for RDC-R321x southbridge" |
727 | select MFD_CORE | 780 | select MFD_CORE |
@@ -854,6 +907,11 @@ config MFD_RC5T583 | |||
854 | Additional drivers must be enabled in order to use the | 907 | Additional drivers must be enabled in order to use the |
855 | different functionality of the device. | 908 | different functionality of the device. |
856 | 909 | ||
910 | config MFD_STA2X11 | ||
911 | bool "STA2X11 multi function device support" | ||
912 | depends on STA2X11 | ||
913 | select MFD_CORE | ||
914 | |||
857 | config MFD_ANATOP | 915 | config MFD_ANATOP |
858 | bool "Support for Freescale i.MX on-chip ANATOP controller" | 916 | bool "Support for Freescale i.MX on-chip ANATOP controller" |
859 | depends on SOC_IMX6Q | 917 | depends on SOC_IMX6Q |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 43672b87805a..75f6ed68a4b9 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o | |||
15 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o | 15 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o |
16 | obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o | 16 | obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o |
17 | 17 | ||
18 | obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o | ||
18 | obj-$(CONFIG_MFD_STMPE) += stmpe.o | 19 | obj-$(CONFIG_MFD_STMPE) += stmpe.o |
19 | obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o | 20 | obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o |
20 | obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o | 21 | obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o |
@@ -54,6 +55,8 @@ obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o | |||
54 | obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o | 55 | obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o |
55 | 56 | ||
56 | obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o | 57 | obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o |
58 | obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o | ||
59 | obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o | ||
57 | 60 | ||
58 | obj-$(CONFIG_MFD_CORE) += mfd-core.o | 61 | obj-$(CONFIG_MFD_CORE) += mfd-core.o |
59 | 62 | ||
@@ -75,6 +78,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o | |||
75 | obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o | 78 | obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o |
76 | obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o | 79 | obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o |
77 | 80 | ||
81 | obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o | ||
78 | max8925-objs := max8925-core.o max8925-i2c.o | 82 | max8925-objs := max8925-core.o max8925-i2c.o |
79 | obj-$(CONFIG_MFD_MAX8925) += max8925.o | 83 | obj-$(CONFIG_MFD_MAX8925) += max8925.o |
80 | obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o | 84 | obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o |
@@ -87,15 +91,15 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o | |||
87 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o | 91 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o |
88 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o | 92 | obj-$(CONFIG_AB3100_CORE) += ab3100-core.o |
89 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o | 93 | obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o |
90 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o | ||
91 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o | 94 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o |
92 | obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o | 95 | obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o |
93 | obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o | 96 | obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o |
94 | # ab8500-i2c need to come after db8500-prcmu (which provides the channel) | 97 | # ab8500-core need to come after db8500-prcmu (which provides the channel) |
95 | obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o | 98 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o |
96 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o | 99 | obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o |
97 | obj-$(CONFIG_PMIC_ADP5520) += adp5520.o | 100 | obj-$(CONFIG_PMIC_ADP5520) += adp5520.o |
98 | obj-$(CONFIG_LPC_SCH) += lpc_sch.o | 101 | obj-$(CONFIG_LPC_SCH) += lpc_sch.o |
102 | obj-$(CONFIG_LPC_ICH) += lpc_ich.o | ||
99 | obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o | 103 | obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o |
100 | obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o | 104 | obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o |
101 | obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o | 105 | obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 1f08704f7ae8..dac0e2998603 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -18,7 +18,10 @@ | |||
18 | #include <linux/mfd/core.h> | 18 | #include <linux/mfd/core.h> |
19 | #include <linux/mfd/abx500.h> | 19 | #include <linux/mfd/abx500.h> |
20 | #include <linux/mfd/abx500/ab8500.h> | 20 | #include <linux/mfd/abx500/ab8500.h> |
21 | #include <linux/mfd/dbx500-prcmu.h> | ||
21 | #include <linux/regulator/ab8500.h> | 22 | #include <linux/regulator/ab8500.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_device.h> | ||
22 | 25 | ||
23 | /* | 26 | /* |
24 | * Interrupt register offsets | 27 | * Interrupt register offsets |
@@ -91,12 +94,24 @@ | |||
91 | #define AB8500_IT_MASK23_REG 0x56 | 94 | #define AB8500_IT_MASK23_REG 0x56 |
92 | #define AB8500_IT_MASK24_REG 0x57 | 95 | #define AB8500_IT_MASK24_REG 0x57 |
93 | 96 | ||
97 | /* | ||
98 | * latch hierarchy registers | ||
99 | */ | ||
100 | #define AB8500_IT_LATCHHIER1_REG 0x60 | ||
101 | #define AB8500_IT_LATCHHIER2_REG 0x61 | ||
102 | #define AB8500_IT_LATCHHIER3_REG 0x62 | ||
103 | |||
104 | #define AB8500_IT_LATCHHIER_NUM 3 | ||
105 | |||
94 | #define AB8500_REV_REG 0x80 | 106 | #define AB8500_REV_REG 0x80 |
95 | #define AB8500_IC_NAME_REG 0x82 | 107 | #define AB8500_IC_NAME_REG 0x82 |
96 | #define AB8500_SWITCH_OFF_STATUS 0x00 | 108 | #define AB8500_SWITCH_OFF_STATUS 0x00 |
97 | 109 | ||
98 | #define AB8500_TURN_ON_STATUS 0x00 | 110 | #define AB8500_TURN_ON_STATUS 0x00 |
99 | 111 | ||
112 | static bool no_bm; /* No battery management */ | ||
113 | module_param(no_bm, bool, S_IRUGO); | ||
114 | |||
100 | #define AB9540_MODEM_CTRL2_REG 0x23 | 115 | #define AB9540_MODEM_CTRL2_REG 0x23 |
101 | #define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT BIT(2) | 116 | #define AB9540_MODEM_CTRL2_SWDBBRSTN_BIT BIT(2) |
102 | 117 | ||
@@ -125,6 +140,41 @@ static const char ab8500_version_str[][7] = { | |||
125 | [AB8500_VERSION_AB8540] = "AB8540", | 140 | [AB8500_VERSION_AB8540] = "AB8540", |
126 | }; | 141 | }; |
127 | 142 | ||
143 | static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) | ||
144 | { | ||
145 | int ret; | ||
146 | |||
147 | ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1); | ||
148 | if (ret < 0) | ||
149 | dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); | ||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask, | ||
154 | u8 data) | ||
155 | { | ||
156 | int ret; | ||
157 | |||
158 | ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data, | ||
159 | &mask, 1); | ||
160 | if (ret < 0) | ||
161 | dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr) | ||
166 | { | ||
167 | int ret; | ||
168 | u8 data; | ||
169 | |||
170 | ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1); | ||
171 | if (ret < 0) { | ||
172 | dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); | ||
173 | return ret; | ||
174 | } | ||
175 | return (int)data; | ||
176 | } | ||
177 | |||
128 | static int ab8500_get_chip_id(struct device *dev) | 178 | static int ab8500_get_chip_id(struct device *dev) |
129 | { | 179 | { |
130 | struct ab8500 *ab8500; | 180 | struct ab8500 *ab8500; |
@@ -161,9 +211,13 @@ static int set_register_interruptible(struct ab8500 *ab8500, u8 bank, | |||
161 | static int ab8500_set_register(struct device *dev, u8 bank, | 211 | static int ab8500_set_register(struct device *dev, u8 bank, |
162 | u8 reg, u8 value) | 212 | u8 reg, u8 value) |
163 | { | 213 | { |
214 | int ret; | ||
164 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 215 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); |
165 | 216 | ||
166 | return set_register_interruptible(ab8500, bank, reg, value); | 217 | atomic_inc(&ab8500->transfer_ongoing); |
218 | ret = set_register_interruptible(ab8500, bank, reg, value); | ||
219 | atomic_dec(&ab8500->transfer_ongoing); | ||
220 | return ret; | ||
167 | } | 221 | } |
168 | 222 | ||
169 | static int get_register_interruptible(struct ab8500 *ab8500, u8 bank, | 223 | static int get_register_interruptible(struct ab8500 *ab8500, u8 bank, |
@@ -192,9 +246,13 @@ static int get_register_interruptible(struct ab8500 *ab8500, u8 bank, | |||
192 | static int ab8500_get_register(struct device *dev, u8 bank, | 246 | static int ab8500_get_register(struct device *dev, u8 bank, |
193 | u8 reg, u8 *value) | 247 | u8 reg, u8 *value) |
194 | { | 248 | { |
249 | int ret; | ||
195 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 250 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); |
196 | 251 | ||
197 | return get_register_interruptible(ab8500, bank, reg, value); | 252 | atomic_inc(&ab8500->transfer_ongoing); |
253 | ret = get_register_interruptible(ab8500, bank, reg, value); | ||
254 | atomic_dec(&ab8500->transfer_ongoing); | ||
255 | return ret; | ||
198 | } | 256 | } |
199 | 257 | ||
200 | static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank, | 258 | static int mask_and_set_register_interruptible(struct ab8500 *ab8500, u8 bank, |
@@ -241,11 +299,14 @@ out: | |||
241 | static int ab8500_mask_and_set_register(struct device *dev, | 299 | static int ab8500_mask_and_set_register(struct device *dev, |
242 | u8 bank, u8 reg, u8 bitmask, u8 bitvalues) | 300 | u8 bank, u8 reg, u8 bitmask, u8 bitvalues) |
243 | { | 301 | { |
302 | int ret; | ||
244 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 303 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); |
245 | 304 | ||
246 | return mask_and_set_register_interruptible(ab8500, bank, reg, | 305 | atomic_inc(&ab8500->transfer_ongoing); |
247 | bitmask, bitvalues); | 306 | ret= mask_and_set_register_interruptible(ab8500, bank, reg, |
248 | 307 | bitmask, bitvalues); | |
308 | atomic_dec(&ab8500->transfer_ongoing); | ||
309 | return ret; | ||
249 | } | 310 | } |
250 | 311 | ||
251 | static struct abx500_ops ab8500_ops = { | 312 | static struct abx500_ops ab8500_ops = { |
@@ -264,6 +325,7 @@ static void ab8500_irq_lock(struct irq_data *data) | |||
264 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); | 325 | struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data); |
265 | 326 | ||
266 | mutex_lock(&ab8500->irq_lock); | 327 | mutex_lock(&ab8500->irq_lock); |
328 | atomic_inc(&ab8500->transfer_ongoing); | ||
267 | } | 329 | } |
268 | 330 | ||
269 | static void ab8500_irq_sync_unlock(struct irq_data *data) | 331 | static void ab8500_irq_sync_unlock(struct irq_data *data) |
@@ -292,7 +354,7 @@ static void ab8500_irq_sync_unlock(struct irq_data *data) | |||
292 | reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i]; | 354 | reg = AB8500_IT_MASK1_REG + ab8500->irq_reg_offset[i]; |
293 | set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new); | 355 | set_register_interruptible(ab8500, AB8500_INTERRUPT, reg, new); |
294 | } | 356 | } |
295 | 357 | atomic_dec(&ab8500->transfer_ongoing); | |
296 | mutex_unlock(&ab8500->irq_lock); | 358 | mutex_unlock(&ab8500->irq_lock); |
297 | } | 359 | } |
298 | 360 | ||
@@ -325,6 +387,90 @@ static struct irq_chip ab8500_irq_chip = { | |||
325 | .irq_unmask = ab8500_irq_unmask, | 387 | .irq_unmask = ab8500_irq_unmask, |
326 | }; | 388 | }; |
327 | 389 | ||
390 | static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500, | ||
391 | int latch_offset, u8 latch_val) | ||
392 | { | ||
393 | int int_bit = __ffs(latch_val); | ||
394 | int line, i; | ||
395 | |||
396 | do { | ||
397 | int_bit = __ffs(latch_val); | ||
398 | |||
399 | for (i = 0; i < ab8500->mask_size; i++) | ||
400 | if (ab8500->irq_reg_offset[i] == latch_offset) | ||
401 | break; | ||
402 | |||
403 | if (i >= ab8500->mask_size) { | ||
404 | dev_err(ab8500->dev, "Register offset 0x%2x not declared\n", | ||
405 | latch_offset); | ||
406 | return -ENXIO; | ||
407 | } | ||
408 | |||
409 | line = (i << 3) + int_bit; | ||
410 | latch_val &= ~(1 << int_bit); | ||
411 | |||
412 | handle_nested_irq(ab8500->irq_base + line); | ||
413 | } while (latch_val); | ||
414 | |||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static int ab8500_handle_hierarchical_latch(struct ab8500 *ab8500, | ||
419 | int hier_offset, u8 hier_val) | ||
420 | { | ||
421 | int latch_bit, status; | ||
422 | u8 latch_offset, latch_val; | ||
423 | |||
424 | do { | ||
425 | latch_bit = __ffs(hier_val); | ||
426 | latch_offset = (hier_offset << 3) + latch_bit; | ||
427 | |||
428 | /* Fix inconsistent ITFromLatch25 bit mapping... */ | ||
429 | if (unlikely(latch_offset == 17)) | ||
430 | latch_offset = 24; | ||
431 | |||
432 | status = get_register_interruptible(ab8500, | ||
433 | AB8500_INTERRUPT, | ||
434 | AB8500_IT_LATCH1_REG + latch_offset, | ||
435 | &latch_val); | ||
436 | if (status < 0 || latch_val == 0) | ||
437 | goto discard; | ||
438 | |||
439 | status = ab8500_handle_hierarchical_line(ab8500, | ||
440 | latch_offset, latch_val); | ||
441 | if (status < 0) | ||
442 | return status; | ||
443 | discard: | ||
444 | hier_val &= ~(1 << latch_bit); | ||
445 | } while (hier_val); | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev) | ||
451 | { | ||
452 | struct ab8500 *ab8500 = dev; | ||
453 | u8 i; | ||
454 | |||
455 | dev_vdbg(ab8500->dev, "interrupt\n"); | ||
456 | |||
457 | /* Hierarchical interrupt version */ | ||
458 | for (i = 0; i < AB8500_IT_LATCHHIER_NUM; i++) { | ||
459 | int status; | ||
460 | u8 hier_val; | ||
461 | |||
462 | status = get_register_interruptible(ab8500, AB8500_INTERRUPT, | ||
463 | AB8500_IT_LATCHHIER1_REG + i, &hier_val); | ||
464 | if (status < 0 || hier_val == 0) | ||
465 | continue; | ||
466 | |||
467 | status = ab8500_handle_hierarchical_latch(ab8500, i, hier_val); | ||
468 | if (status < 0) | ||
469 | break; | ||
470 | } | ||
471 | return IRQ_HANDLED; | ||
472 | } | ||
473 | |||
328 | static irqreturn_t ab8500_irq(int irq, void *dev) | 474 | static irqreturn_t ab8500_irq(int irq, void *dev) |
329 | { | 475 | { |
330 | struct ab8500 *ab8500 = dev; | 476 | struct ab8500 *ab8500 = dev; |
@@ -332,6 +478,8 @@ static irqreturn_t ab8500_irq(int irq, void *dev) | |||
332 | 478 | ||
333 | dev_vdbg(ab8500->dev, "interrupt\n"); | 479 | dev_vdbg(ab8500->dev, "interrupt\n"); |
334 | 480 | ||
481 | atomic_inc(&ab8500->transfer_ongoing); | ||
482 | |||
335 | for (i = 0; i < ab8500->mask_size; i++) { | 483 | for (i = 0; i < ab8500->mask_size; i++) { |
336 | int regoffset = ab8500->irq_reg_offset[i]; | 484 | int regoffset = ab8500->irq_reg_offset[i]; |
337 | int status; | 485 | int status; |
@@ -355,9 +503,10 @@ static irqreturn_t ab8500_irq(int irq, void *dev) | |||
355 | 503 | ||
356 | handle_nested_irq(ab8500->irq_base + line); | 504 | handle_nested_irq(ab8500->irq_base + line); |
357 | value &= ~(1 << bit); | 505 | value &= ~(1 << bit); |
506 | |||
358 | } while (value); | 507 | } while (value); |
359 | } | 508 | } |
360 | 509 | atomic_dec(&ab8500->transfer_ongoing); | |
361 | return IRQ_HANDLED; | 510 | return IRQ_HANDLED; |
362 | } | 511 | } |
363 | 512 | ||
@@ -411,6 +560,14 @@ static void ab8500_irq_remove(struct ab8500 *ab8500) | |||
411 | } | 560 | } |
412 | } | 561 | } |
413 | 562 | ||
563 | int ab8500_suspend(struct ab8500 *ab8500) | ||
564 | { | ||
565 | if (atomic_read(&ab8500->transfer_ongoing)) | ||
566 | return -EINVAL; | ||
567 | else | ||
568 | return 0; | ||
569 | } | ||
570 | |||
414 | /* AB8500 GPIO Resources */ | 571 | /* AB8500 GPIO Resources */ |
415 | static struct resource __devinitdata ab8500_gpio_resources[] = { | 572 | static struct resource __devinitdata ab8500_gpio_resources[] = { |
416 | { | 573 | { |
@@ -744,6 +901,39 @@ static struct resource __devinitdata ab8500_usb_resources[] = { | |||
744 | }, | 901 | }, |
745 | }; | 902 | }; |
746 | 903 | ||
904 | static struct resource __devinitdata ab8505_iddet_resources[] = { | ||
905 | { | ||
906 | .name = "KeyDeglitch", | ||
907 | .start = AB8505_INT_KEYDEGLITCH, | ||
908 | .end = AB8505_INT_KEYDEGLITCH, | ||
909 | .flags = IORESOURCE_IRQ, | ||
910 | }, | ||
911 | { | ||
912 | .name = "KP", | ||
913 | .start = AB8505_INT_KP, | ||
914 | .end = AB8505_INT_KP, | ||
915 | .flags = IORESOURCE_IRQ, | ||
916 | }, | ||
917 | { | ||
918 | .name = "IKP", | ||
919 | .start = AB8505_INT_IKP, | ||
920 | .end = AB8505_INT_IKP, | ||
921 | .flags = IORESOURCE_IRQ, | ||
922 | }, | ||
923 | { | ||
924 | .name = "IKR", | ||
925 | .start = AB8505_INT_IKR, | ||
926 | .end = AB8505_INT_IKR, | ||
927 | .flags = IORESOURCE_IRQ, | ||
928 | }, | ||
929 | { | ||
930 | .name = "KeyStuck", | ||
931 | .start = AB8505_INT_KEYSTUCK, | ||
932 | .end = AB8505_INT_KEYSTUCK, | ||
933 | .flags = IORESOURCE_IRQ, | ||
934 | }, | ||
935 | }; | ||
936 | |||
747 | static struct resource __devinitdata ab8500_temp_resources[] = { | 937 | static struct resource __devinitdata ab8500_temp_resources[] = { |
748 | { | 938 | { |
749 | .name = "AB8500_TEMP_WARM", | 939 | .name = "AB8500_TEMP_WARM", |
@@ -778,35 +968,11 @@ static struct mfd_cell __devinitdata abx500_common_devs[] = { | |||
778 | .resources = ab8500_rtc_resources, | 968 | .resources = ab8500_rtc_resources, |
779 | }, | 969 | }, |
780 | { | 970 | { |
781 | .name = "ab8500-charger", | ||
782 | .num_resources = ARRAY_SIZE(ab8500_charger_resources), | ||
783 | .resources = ab8500_charger_resources, | ||
784 | }, | ||
785 | { | ||
786 | .name = "ab8500-btemp", | ||
787 | .num_resources = ARRAY_SIZE(ab8500_btemp_resources), | ||
788 | .resources = ab8500_btemp_resources, | ||
789 | }, | ||
790 | { | ||
791 | .name = "ab8500-fg", | ||
792 | .num_resources = ARRAY_SIZE(ab8500_fg_resources), | ||
793 | .resources = ab8500_fg_resources, | ||
794 | }, | ||
795 | { | ||
796 | .name = "ab8500-chargalg", | ||
797 | .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), | ||
798 | .resources = ab8500_chargalg_resources, | ||
799 | }, | ||
800 | { | ||
801 | .name = "ab8500-acc-det", | 971 | .name = "ab8500-acc-det", |
802 | .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), | 972 | .num_resources = ARRAY_SIZE(ab8500_av_acc_detect_resources), |
803 | .resources = ab8500_av_acc_detect_resources, | 973 | .resources = ab8500_av_acc_detect_resources, |
804 | }, | 974 | }, |
805 | { | 975 | { |
806 | .name = "ab8500-codec", | ||
807 | }, | ||
808 | |||
809 | { | ||
810 | .name = "ab8500-poweron-key", | 976 | .name = "ab8500-poweron-key", |
811 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), | 977 | .num_resources = ARRAY_SIZE(ab8500_poweronkey_db_resources), |
812 | .resources = ab8500_poweronkey_db_resources, | 978 | .resources = ab8500_poweronkey_db_resources, |
@@ -834,6 +1000,29 @@ static struct mfd_cell __devinitdata abx500_common_devs[] = { | |||
834 | }, | 1000 | }, |
835 | }; | 1001 | }; |
836 | 1002 | ||
1003 | static struct mfd_cell __devinitdata ab8500_bm_devs[] = { | ||
1004 | { | ||
1005 | .name = "ab8500-charger", | ||
1006 | .num_resources = ARRAY_SIZE(ab8500_charger_resources), | ||
1007 | .resources = ab8500_charger_resources, | ||
1008 | }, | ||
1009 | { | ||
1010 | .name = "ab8500-btemp", | ||
1011 | .num_resources = ARRAY_SIZE(ab8500_btemp_resources), | ||
1012 | .resources = ab8500_btemp_resources, | ||
1013 | }, | ||
1014 | { | ||
1015 | .name = "ab8500-fg", | ||
1016 | .num_resources = ARRAY_SIZE(ab8500_fg_resources), | ||
1017 | .resources = ab8500_fg_resources, | ||
1018 | }, | ||
1019 | { | ||
1020 | .name = "ab8500-chargalg", | ||
1021 | .num_resources = ARRAY_SIZE(ab8500_chargalg_resources), | ||
1022 | .resources = ab8500_chargalg_resources, | ||
1023 | }, | ||
1024 | }; | ||
1025 | |||
837 | static struct mfd_cell __devinitdata ab8500_devs[] = { | 1026 | static struct mfd_cell __devinitdata ab8500_devs[] = { |
838 | { | 1027 | { |
839 | .name = "ab8500-gpio", | 1028 | .name = "ab8500-gpio", |
@@ -845,6 +1034,9 @@ static struct mfd_cell __devinitdata ab8500_devs[] = { | |||
845 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), | 1034 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), |
846 | .resources = ab8500_usb_resources, | 1035 | .resources = ab8500_usb_resources, |
847 | }, | 1036 | }, |
1037 | { | ||
1038 | .name = "ab8500-codec", | ||
1039 | }, | ||
848 | }; | 1040 | }; |
849 | 1041 | ||
850 | static struct mfd_cell __devinitdata ab9540_devs[] = { | 1042 | static struct mfd_cell __devinitdata ab9540_devs[] = { |
@@ -858,6 +1050,18 @@ static struct mfd_cell __devinitdata ab9540_devs[] = { | |||
858 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), | 1050 | .num_resources = ARRAY_SIZE(ab8500_usb_resources), |
859 | .resources = ab8500_usb_resources, | 1051 | .resources = ab8500_usb_resources, |
860 | }, | 1052 | }, |
1053 | { | ||
1054 | .name = "ab9540-codec", | ||
1055 | }, | ||
1056 | }; | ||
1057 | |||
1058 | /* Device list common to ab9540 and ab8505 */ | ||
1059 | static struct mfd_cell __devinitdata ab9540_ab8505_devs[] = { | ||
1060 | { | ||
1061 | .name = "ab-iddet", | ||
1062 | .num_resources = ARRAY_SIZE(ab8505_iddet_resources), | ||
1063 | .resources = ab8505_iddet_resources, | ||
1064 | }, | ||
861 | }; | 1065 | }; |
862 | 1066 | ||
863 | static ssize_t show_chip_id(struct device *dev, | 1067 | static ssize_t show_chip_id(struct device *dev, |
@@ -1003,18 +1207,66 @@ static struct attribute_group ab9540_attr_group = { | |||
1003 | .attrs = ab9540_sysfs_entries, | 1207 | .attrs = ab9540_sysfs_entries, |
1004 | }; | 1208 | }; |
1005 | 1209 | ||
1006 | int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) | 1210 | static const struct of_device_id ab8500_match[] = { |
1211 | { | ||
1212 | .compatible = "stericsson,ab8500", | ||
1213 | .data = (void *)AB8500_VERSION_AB8500, | ||
1214 | }, | ||
1215 | {}, | ||
1216 | }; | ||
1217 | |||
1218 | static int __devinit ab8500_probe(struct platform_device *pdev) | ||
1007 | { | 1219 | { |
1008 | struct ab8500_platform_data *plat = dev_get_platdata(ab8500->dev); | 1220 | struct ab8500_platform_data *plat = dev_get_platdata(&pdev->dev); |
1221 | const struct platform_device_id *platid = platform_get_device_id(pdev); | ||
1222 | enum ab8500_version version = AB8500_VERSION_UNDEFINED; | ||
1223 | struct device_node *np = pdev->dev.of_node; | ||
1224 | struct ab8500 *ab8500; | ||
1225 | struct resource *resource; | ||
1009 | int ret; | 1226 | int ret; |
1010 | int i; | 1227 | int i; |
1011 | u8 value; | 1228 | u8 value; |
1012 | 1229 | ||
1230 | ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); | ||
1231 | if (!ab8500) | ||
1232 | return -ENOMEM; | ||
1233 | |||
1013 | if (plat) | 1234 | if (plat) |
1014 | ab8500->irq_base = plat->irq_base; | 1235 | ab8500->irq_base = plat->irq_base; |
1236 | else if (np) | ||
1237 | ret = of_property_read_u32(np, "stericsson,irq-base", &ab8500->irq_base); | ||
1238 | |||
1239 | if (!ab8500->irq_base) { | ||
1240 | dev_info(&pdev->dev, "couldn't find irq-base\n"); | ||
1241 | ret = -EINVAL; | ||
1242 | goto out_free_ab8500; | ||
1243 | } | ||
1244 | |||
1245 | ab8500->dev = &pdev->dev; | ||
1246 | |||
1247 | resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
1248 | if (!resource) { | ||
1249 | ret = -ENODEV; | ||
1250 | goto out_free_ab8500; | ||
1251 | } | ||
1252 | |||
1253 | ab8500->irq = resource->start; | ||
1254 | |||
1255 | ab8500->read = ab8500_i2c_read; | ||
1256 | ab8500->write = ab8500_i2c_write; | ||
1257 | ab8500->write_masked = ab8500_i2c_write_masked; | ||
1015 | 1258 | ||
1016 | mutex_init(&ab8500->lock); | 1259 | mutex_init(&ab8500->lock); |
1017 | mutex_init(&ab8500->irq_lock); | 1260 | mutex_init(&ab8500->irq_lock); |
1261 | atomic_set(&ab8500->transfer_ongoing, 0); | ||
1262 | |||
1263 | platform_set_drvdata(pdev, ab8500); | ||
1264 | |||
1265 | if (platid) | ||
1266 | version = platid->driver_data; | ||
1267 | else if (np) | ||
1268 | version = (unsigned int) | ||
1269 | of_match_device(ab8500_match, &pdev->dev)->data; | ||
1018 | 1270 | ||
1019 | if (version != AB8500_VERSION_UNDEFINED) | 1271 | if (version != AB8500_VERSION_UNDEFINED) |
1020 | ab8500->version = version; | 1272 | ab8500->version = version; |
@@ -1022,7 +1274,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) | |||
1022 | ret = get_register_interruptible(ab8500, AB8500_MISC, | 1274 | ret = get_register_interruptible(ab8500, AB8500_MISC, |
1023 | AB8500_IC_NAME_REG, &value); | 1275 | AB8500_IC_NAME_REG, &value); |
1024 | if (ret < 0) | 1276 | if (ret < 0) |
1025 | return ret; | 1277 | goto out_free_ab8500; |
1026 | 1278 | ||
1027 | ab8500->version = value; | 1279 | ab8500->version = value; |
1028 | } | 1280 | } |
@@ -1030,7 +1282,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) | |||
1030 | ret = get_register_interruptible(ab8500, AB8500_MISC, | 1282 | ret = get_register_interruptible(ab8500, AB8500_MISC, |
1031 | AB8500_REV_REG, &value); | 1283 | AB8500_REV_REG, &value); |
1032 | if (ret < 0) | 1284 | if (ret < 0) |
1033 | return ret; | 1285 | goto out_free_ab8500; |
1034 | 1286 | ||
1035 | ab8500->chip_id = value; | 1287 | ab8500->chip_id = value; |
1036 | 1288 | ||
@@ -1105,30 +1357,57 @@ int __devinit ab8500_init(struct ab8500 *ab8500, enum ab8500_version version) | |||
1105 | if (ret) | 1357 | if (ret) |
1106 | goto out_freeoldmask; | 1358 | goto out_freeoldmask; |
1107 | 1359 | ||
1108 | ret = request_threaded_irq(ab8500->irq, NULL, ab8500_irq, | 1360 | /* Activate this feature only in ab9540 */ |
1109 | IRQF_ONESHOT | IRQF_NO_SUSPEND, | 1361 | /* till tests are done on ab8500 1p2 or later*/ |
1110 | "ab8500", ab8500); | 1362 | if (is_ab9540(ab8500)) |
1363 | ret = request_threaded_irq(ab8500->irq, NULL, | ||
1364 | ab8500_hierarchical_irq, | ||
1365 | IRQF_ONESHOT | IRQF_NO_SUSPEND, | ||
1366 | "ab8500", ab8500); | ||
1367 | else | ||
1368 | ret = request_threaded_irq(ab8500->irq, NULL, | ||
1369 | ab8500_irq, | ||
1370 | IRQF_ONESHOT | IRQF_NO_SUSPEND, | ||
1371 | "ab8500", ab8500); | ||
1111 | if (ret) | 1372 | if (ret) |
1112 | goto out_removeirq; | 1373 | goto out_removeirq; |
1113 | } | 1374 | } |
1114 | 1375 | ||
1115 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, | 1376 | if (!np) { |
1116 | ARRAY_SIZE(abx500_common_devs), NULL, | 1377 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, |
1117 | ab8500->irq_base); | 1378 | ARRAY_SIZE(abx500_common_devs), NULL, |
1379 | ab8500->irq_base); | ||
1118 | 1380 | ||
1119 | if (ret) | 1381 | if (ret) |
1120 | goto out_freeirq; | 1382 | goto out_freeirq; |
1383 | |||
1384 | if (is_ab9540(ab8500)) | ||
1385 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, | ||
1386 | ARRAY_SIZE(ab9540_devs), NULL, | ||
1387 | ab8500->irq_base); | ||
1388 | else | ||
1389 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, | ||
1390 | ARRAY_SIZE(ab8500_devs), NULL, | ||
1391 | ab8500->irq_base); | ||
1392 | if (ret) | ||
1393 | goto out_freeirq; | ||
1121 | 1394 | ||
1122 | if (is_ab9540(ab8500)) | 1395 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) |
1123 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, | 1396 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, |
1124 | ARRAY_SIZE(ab9540_devs), NULL, | 1397 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, |
1125 | ab8500->irq_base); | 1398 | ab8500->irq_base); |
1126 | else | 1399 | if (ret) |
1127 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, | 1400 | goto out_freeirq; |
1128 | ARRAY_SIZE(ab9540_devs), NULL, | 1401 | } |
1129 | ab8500->irq_base); | 1402 | |
1130 | if (ret) | 1403 | if (!no_bm) { |
1131 | goto out_freeirq; | 1404 | /* Add battery management devices */ |
1405 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, | ||
1406 | ARRAY_SIZE(ab8500_bm_devs), NULL, | ||
1407 | ab8500->irq_base); | ||
1408 | if (ret) | ||
1409 | dev_err(ab8500->dev, "error adding bm devices\n"); | ||
1410 | } | ||
1132 | 1411 | ||
1133 | if (is_ab9540(ab8500)) | 1412 | if (is_ab9540(ab8500)) |
1134 | ret = sysfs_create_group(&ab8500->dev->kobj, | 1413 | ret = sysfs_create_group(&ab8500->dev->kobj, |
@@ -1151,12 +1430,16 @@ out_freeoldmask: | |||
1151 | kfree(ab8500->oldmask); | 1430 | kfree(ab8500->oldmask); |
1152 | out_freemask: | 1431 | out_freemask: |
1153 | kfree(ab8500->mask); | 1432 | kfree(ab8500->mask); |
1433 | out_free_ab8500: | ||
1434 | kfree(ab8500); | ||
1154 | 1435 | ||
1155 | return ret; | 1436 | return ret; |
1156 | } | 1437 | } |
1157 | 1438 | ||
1158 | int __devexit ab8500_exit(struct ab8500 *ab8500) | 1439 | static int __devexit ab8500_remove(struct platform_device *pdev) |
1159 | { | 1440 | { |
1441 | struct ab8500 *ab8500 = platform_get_drvdata(pdev); | ||
1442 | |||
1160 | if (is_ab9540(ab8500)) | 1443 | if (is_ab9540(ab8500)) |
1161 | sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group); | 1444 | sysfs_remove_group(&ab8500->dev->kobj, &ab9540_attr_group); |
1162 | else | 1445 | else |
@@ -1168,10 +1451,42 @@ int __devexit ab8500_exit(struct ab8500 *ab8500) | |||
1168 | } | 1451 | } |
1169 | kfree(ab8500->oldmask); | 1452 | kfree(ab8500->oldmask); |
1170 | kfree(ab8500->mask); | 1453 | kfree(ab8500->mask); |
1454 | kfree(ab8500); | ||
1171 | 1455 | ||
1172 | return 0; | 1456 | return 0; |
1173 | } | 1457 | } |
1174 | 1458 | ||
1459 | static const struct platform_device_id ab8500_id[] = { | ||
1460 | { "ab8500-core", AB8500_VERSION_AB8500 }, | ||
1461 | { "ab8505-i2c", AB8500_VERSION_AB8505 }, | ||
1462 | { "ab9540-i2c", AB8500_VERSION_AB9540 }, | ||
1463 | { "ab8540-i2c", AB8500_VERSION_AB8540 }, | ||
1464 | { } | ||
1465 | }; | ||
1466 | |||
1467 | static struct platform_driver ab8500_core_driver = { | ||
1468 | .driver = { | ||
1469 | .name = "ab8500-core", | ||
1470 | .owner = THIS_MODULE, | ||
1471 | .of_match_table = ab8500_match, | ||
1472 | }, | ||
1473 | .probe = ab8500_probe, | ||
1474 | .remove = __devexit_p(ab8500_remove), | ||
1475 | .id_table = ab8500_id, | ||
1476 | }; | ||
1477 | |||
1478 | static int __init ab8500_core_init(void) | ||
1479 | { | ||
1480 | return platform_driver_register(&ab8500_core_driver); | ||
1481 | } | ||
1482 | |||
1483 | static void __exit ab8500_core_exit(void) | ||
1484 | { | ||
1485 | platform_driver_unregister(&ab8500_core_driver); | ||
1486 | } | ||
1487 | arch_initcall(ab8500_core_init); | ||
1488 | module_exit(ab8500_core_exit); | ||
1489 | |||
1175 | MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent"); | 1490 | MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent"); |
1176 | MODULE_DESCRIPTION("AB8500 MFD core"); | 1491 | MODULE_DESCRIPTION("AB8500 MFD core"); |
1177 | MODULE_LICENSE("GPL v2"); | 1492 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 9a0211aa8897..50c4c89ab220 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c | |||
@@ -608,10 +608,16 @@ static int __devexit ab8500_debug_remove(struct platform_device *plf) | |||
608 | return 0; | 608 | return 0; |
609 | } | 609 | } |
610 | 610 | ||
611 | static const struct of_device_id ab8500_debug_match[] = { | ||
612 | { .compatible = "stericsson,ab8500-debug", }, | ||
613 | {} | ||
614 | }; | ||
615 | |||
611 | static struct platform_driver ab8500_debug_driver = { | 616 | static struct platform_driver ab8500_debug_driver = { |
612 | .driver = { | 617 | .driver = { |
613 | .name = "ab8500-debug", | 618 | .name = "ab8500-debug", |
614 | .owner = THIS_MODULE, | 619 | .owner = THIS_MODULE, |
620 | .of_match_table = ab8500_debug_match, | ||
615 | }, | 621 | }, |
616 | .probe = ab8500_debug_probe, | 622 | .probe = ab8500_debug_probe, |
617 | .remove = __devexit_p(ab8500_debug_remove) | 623 | .remove = __devexit_p(ab8500_debug_remove) |
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index c39fc716e1dc..b86fd8e1ec3f 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c | |||
@@ -584,7 +584,7 @@ static int __devinit ab8500_gpadc_probe(struct platform_device *pdev) | |||
584 | 584 | ||
585 | gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END"); | 585 | gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END"); |
586 | if (gpadc->irq < 0) { | 586 | if (gpadc->irq < 0) { |
587 | dev_err(gpadc->dev, "failed to get platform irq-%d\n", | 587 | dev_err(&pdev->dev, "failed to get platform irq-%d\n", |
588 | gpadc->irq); | 588 | gpadc->irq); |
589 | ret = gpadc->irq; | 589 | ret = gpadc->irq; |
590 | goto fail; | 590 | goto fail; |
@@ -648,12 +648,18 @@ static int __devexit ab8500_gpadc_remove(struct platform_device *pdev) | |||
648 | return 0; | 648 | return 0; |
649 | } | 649 | } |
650 | 650 | ||
651 | static const struct of_device_id ab8500_gpadc_match[] = { | ||
652 | { .compatible = "stericsson,ab8500-gpadc", }, | ||
653 | {} | ||
654 | }; | ||
655 | |||
651 | static struct platform_driver ab8500_gpadc_driver = { | 656 | static struct platform_driver ab8500_gpadc_driver = { |
652 | .probe = ab8500_gpadc_probe, | 657 | .probe = ab8500_gpadc_probe, |
653 | .remove = __devexit_p(ab8500_gpadc_remove), | 658 | .remove = __devexit_p(ab8500_gpadc_remove), |
654 | .driver = { | 659 | .driver = { |
655 | .name = "ab8500-gpadc", | 660 | .name = "ab8500-gpadc", |
656 | .owner = THIS_MODULE, | 661 | .owner = THIS_MODULE, |
662 | .of_match_table = ab8500_gpadc_match, | ||
657 | }, | 663 | }, |
658 | }; | 664 | }; |
659 | 665 | ||
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c deleted file mode 100644 index b83045f102be..000000000000 --- a/drivers/mfd/ab8500-i2c.c +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson. | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * This file was based on drivers/mfd/ab8500-spi.c | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/slab.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mfd/abx500/ab8500.h> | ||
14 | #include <linux/mfd/dbx500-prcmu.h> | ||
15 | |||
16 | static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) | ||
17 | { | ||
18 | int ret; | ||
19 | |||
20 | ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1); | ||
21 | if (ret < 0) | ||
22 | dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); | ||
23 | return ret; | ||
24 | } | ||
25 | |||
26 | static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask, | ||
27 | u8 data) | ||
28 | { | ||
29 | int ret; | ||
30 | |||
31 | ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data, | ||
32 | &mask, 1); | ||
33 | if (ret < 0) | ||
34 | dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); | ||
35 | return ret; | ||
36 | } | ||
37 | |||
38 | static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr) | ||
39 | { | ||
40 | int ret; | ||
41 | u8 data; | ||
42 | |||
43 | ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1); | ||
44 | if (ret < 0) { | ||
45 | dev_err(ab8500->dev, "prcmu i2c error %d\n", ret); | ||
46 | return ret; | ||
47 | } | ||
48 | return (int)data; | ||
49 | } | ||
50 | |||
51 | static int __devinit ab8500_i2c_probe(struct platform_device *plf) | ||
52 | { | ||
53 | const struct platform_device_id *platid = platform_get_device_id(plf); | ||
54 | struct ab8500 *ab8500; | ||
55 | struct resource *resource; | ||
56 | int ret; | ||
57 | |||
58 | ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL); | ||
59 | if (!ab8500) | ||
60 | return -ENOMEM; | ||
61 | |||
62 | ab8500->dev = &plf->dev; | ||
63 | |||
64 | resource = platform_get_resource(plf, IORESOURCE_IRQ, 0); | ||
65 | if (!resource) { | ||
66 | kfree(ab8500); | ||
67 | return -ENODEV; | ||
68 | } | ||
69 | |||
70 | ab8500->irq = resource->start; | ||
71 | |||
72 | ab8500->read = ab8500_i2c_read; | ||
73 | ab8500->write = ab8500_i2c_write; | ||
74 | ab8500->write_masked = ab8500_i2c_write_masked; | ||
75 | |||
76 | platform_set_drvdata(plf, ab8500); | ||
77 | |||
78 | ret = ab8500_init(ab8500, platid->driver_data); | ||
79 | if (ret) | ||
80 | kfree(ab8500); | ||
81 | |||
82 | |||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | static int __devexit ab8500_i2c_remove(struct platform_device *plf) | ||
87 | { | ||
88 | struct ab8500 *ab8500 = platform_get_drvdata(plf); | ||
89 | |||
90 | ab8500_exit(ab8500); | ||
91 | kfree(ab8500); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static const struct platform_device_id ab8500_id[] = { | ||
97 | { "ab8500-i2c", AB8500_VERSION_AB8500 }, | ||
98 | { "ab8505-i2c", AB8500_VERSION_AB8505 }, | ||
99 | { "ab9540-i2c", AB8500_VERSION_AB9540 }, | ||
100 | { "ab8540-i2c", AB8500_VERSION_AB8540 }, | ||
101 | { } | ||
102 | }; | ||
103 | |||
104 | static struct platform_driver ab8500_i2c_driver = { | ||
105 | .driver = { | ||
106 | .name = "ab8500-i2c", | ||
107 | .owner = THIS_MODULE, | ||
108 | }, | ||
109 | .probe = ab8500_i2c_probe, | ||
110 | .remove = __devexit_p(ab8500_i2c_remove), | ||
111 | .id_table = ab8500_id, | ||
112 | }; | ||
113 | |||
114 | static int __init ab8500_i2c_init(void) | ||
115 | { | ||
116 | return platform_driver_register(&ab8500_i2c_driver); | ||
117 | } | ||
118 | |||
119 | static void __exit ab8500_i2c_exit(void) | ||
120 | { | ||
121 | platform_driver_unregister(&ab8500_i2c_driver); | ||
122 | } | ||
123 | arch_initcall(ab8500_i2c_init); | ||
124 | module_exit(ab8500_i2c_exit); | ||
125 | |||
126 | MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com"); | ||
127 | MODULE_DESCRIPTION("AB8500 Core access via PRCMU I2C"); | ||
128 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index c28d4eb1eff0..5a3e51ccf258 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c | |||
@@ -61,10 +61,16 @@ static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev) | |||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | 63 | ||
64 | static const struct of_device_id ab8500_sysctrl_match[] = { | ||
65 | { .compatible = "stericsson,ab8500-sysctrl", }, | ||
66 | {} | ||
67 | }; | ||
68 | |||
64 | static struct platform_driver ab8500_sysctrl_driver = { | 69 | static struct platform_driver ab8500_sysctrl_driver = { |
65 | .driver = { | 70 | .driver = { |
66 | .name = "ab8500-sysctrl", | 71 | .name = "ab8500-sysctrl", |
67 | .owner = THIS_MODULE, | 72 | .owner = THIS_MODULE, |
73 | .of_match_table = ab8500_sysctrl_match, | ||
68 | }, | 74 | }, |
69 | .probe = ab8500_sysctrl_probe, | 75 | .probe = ab8500_sysctrl_probe, |
70 | .remove = __devexit_p(ab8500_sysctrl_remove), | 76 | .remove = __devexit_p(ab8500_sysctrl_remove), |
diff --git a/drivers/mfd/anatop-mfd.c b/drivers/mfd/anatop-mfd.c index 2af42480635e..6da06341f6c9 100644 --- a/drivers/mfd/anatop-mfd.c +++ b/drivers/mfd/anatop-mfd.c | |||
@@ -41,39 +41,26 @@ | |||
41 | #include <linux/of_address.h> | 41 | #include <linux/of_address.h> |
42 | #include <linux/mfd/anatop.h> | 42 | #include <linux/mfd/anatop.h> |
43 | 43 | ||
44 | u32 anatop_get_bits(struct anatop *adata, u32 addr, int bit_shift, | 44 | u32 anatop_read_reg(struct anatop *adata, u32 addr) |
45 | int bit_width) | ||
46 | { | 45 | { |
47 | u32 val, mask; | 46 | return readl(adata->ioreg + addr); |
48 | |||
49 | if (bit_width == 32) | ||
50 | mask = ~0; | ||
51 | else | ||
52 | mask = (1 << bit_width) - 1; | ||
53 | |||
54 | val = readl(adata->ioreg + addr); | ||
55 | val = (val >> bit_shift) & mask; | ||
56 | |||
57 | return val; | ||
58 | } | 47 | } |
59 | EXPORT_SYMBOL_GPL(anatop_get_bits); | 48 | EXPORT_SYMBOL_GPL(anatop_read_reg); |
60 | 49 | ||
61 | void anatop_set_bits(struct anatop *adata, u32 addr, int bit_shift, | 50 | void anatop_write_reg(struct anatop *adata, u32 addr, u32 data, u32 mask) |
62 | int bit_width, u32 data) | ||
63 | { | 51 | { |
64 | u32 val, mask; | 52 | u32 val; |
65 | 53 | ||
66 | if (bit_width == 32) | 54 | data &= mask; |
67 | mask = ~0; | ||
68 | else | ||
69 | mask = (1 << bit_width) - 1; | ||
70 | 55 | ||
71 | spin_lock(&adata->reglock); | 56 | spin_lock(&adata->reglock); |
72 | val = readl(adata->ioreg + addr) & ~(mask << bit_shift); | 57 | val = readl(adata->ioreg + addr); |
73 | writel((data << bit_shift) | val, adata->ioreg + addr); | 58 | val &= ~mask; |
59 | val |= data; | ||
60 | writel(val, adata->ioreg + addr); | ||
74 | spin_unlock(&adata->reglock); | 61 | spin_unlock(&adata->reglock); |
75 | } | 62 | } |
76 | EXPORT_SYMBOL_GPL(anatop_set_bits); | 63 | EXPORT_SYMBOL_GPL(anatop_write_reg); |
77 | 64 | ||
78 | static const struct of_device_id of_anatop_match[] = { | 65 | static const struct of_device_id of_anatop_match[] = { |
79 | { .compatible = "fsl,imx6q-anatop", }, | 66 | { .compatible = "fsl,imx6q-anatop", }, |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 1582c3d95257..383421bf5760 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -353,12 +353,28 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) | |||
353 | return 0; | 353 | return 0; |
354 | } | 354 | } |
355 | 355 | ||
356 | static int asic3_gpio_irq_set_wake(struct irq_data *data, unsigned int on) | ||
357 | { | ||
358 | struct asic3 *asic = irq_data_get_irq_chip_data(data); | ||
359 | u32 bank, index; | ||
360 | u16 bit; | ||
361 | |||
362 | bank = asic3_irq_to_bank(asic, data->irq); | ||
363 | index = asic3_irq_to_index(asic, data->irq); | ||
364 | bit = 1<<index; | ||
365 | |||
366 | asic3_set_register(asic, bank + ASIC3_GPIO_SLEEP_MASK, bit, !on); | ||
367 | |||
368 | return 0; | ||
369 | } | ||
370 | |||
356 | static struct irq_chip asic3_gpio_irq_chip = { | 371 | static struct irq_chip asic3_gpio_irq_chip = { |
357 | .name = "ASIC3-GPIO", | 372 | .name = "ASIC3-GPIO", |
358 | .irq_ack = asic3_mask_gpio_irq, | 373 | .irq_ack = asic3_mask_gpio_irq, |
359 | .irq_mask = asic3_mask_gpio_irq, | 374 | .irq_mask = asic3_mask_gpio_irq, |
360 | .irq_unmask = asic3_unmask_gpio_irq, | 375 | .irq_unmask = asic3_unmask_gpio_irq, |
361 | .irq_set_type = asic3_gpio_irq_type, | 376 | .irq_set_type = asic3_gpio_irq_type, |
377 | .irq_set_wake = asic3_gpio_irq_set_wake, | ||
362 | }; | 378 | }; |
363 | 379 | ||
364 | static struct irq_chip asic3_irq_chip = { | 380 | static struct irq_chip asic3_irq_chip = { |
@@ -529,7 +545,7 @@ static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
529 | { | 545 | { |
530 | struct asic3 *asic = container_of(chip, struct asic3, gpio); | 546 | struct asic3 *asic = container_of(chip, struct asic3, gpio); |
531 | 547 | ||
532 | return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; | 548 | return asic->irq_base + offset; |
533 | } | 549 | } |
534 | 550 | ||
535 | static __init int asic3_gpio_probe(struct platform_device *pdev, | 551 | static __init int asic3_gpio_probe(struct platform_device *pdev, |
@@ -894,10 +910,13 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
894 | asic3_mmc_resources[0].start >>= asic->bus_shift; | 910 | asic3_mmc_resources[0].start >>= asic->bus_shift; |
895 | asic3_mmc_resources[0].end >>= asic->bus_shift; | 911 | asic3_mmc_resources[0].end >>= asic->bus_shift; |
896 | 912 | ||
897 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 913 | if (pdata->clock_rate) { |
914 | ds1wm_pdata.clock_rate = pdata->clock_rate; | ||
915 | ret = mfd_add_devices(&pdev->dev, pdev->id, | ||
898 | &asic3_cell_ds1wm, 1, mem, asic->irq_base); | 916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base); |
899 | if (ret < 0) | 917 | if (ret < 0) |
900 | goto out; | 918 | goto out; |
919 | } | ||
901 | 920 | ||
902 | if (mem_sdio && (irq >= 0)) { | 921 | if (mem_sdio && (irq >= 0)) { |
903 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 922 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
@@ -1000,6 +1019,9 @@ static int __init asic3_probe(struct platform_device *pdev) | |||
1000 | 1019 | ||
1001 | asic3_mfd_probe(pdev, pdata, mem); | 1020 | asic3_mfd_probe(pdev, pdata, mem); |
1002 | 1021 | ||
1022 | asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), | ||
1023 | (ASIC3_EXTCF_CF0_BUF_EN|ASIC3_EXTCF_CF0_PWAIT_EN), 1); | ||
1024 | |||
1003 | dev_info(asic->dev, "ASIC3 Core driver\n"); | 1025 | dev_info(asic->dev, "ASIC3 Core driver\n"); |
1004 | 1026 | ||
1005 | return 0; | 1027 | return 0; |
@@ -1021,6 +1043,9 @@ static int __devexit asic3_remove(struct platform_device *pdev) | |||
1021 | int ret; | 1043 | int ret; |
1022 | struct asic3 *asic = platform_get_drvdata(pdev); | 1044 | struct asic3 *asic = platform_get_drvdata(pdev); |
1023 | 1045 | ||
1046 | asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT), | ||
1047 | (ASIC3_EXTCF_CF0_BUF_EN|ASIC3_EXTCF_CF0_PWAIT_EN), 0); | ||
1048 | |||
1024 | asic3_mfd_remove(pdev); | 1049 | asic3_mfd_remove(pdev); |
1025 | 1050 | ||
1026 | ret = asic3_gpio_remove(pdev); | 1051 | ret = asic3_gpio_remove(pdev); |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 315fef5d466a..3419e726de47 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -186,18 +186,7 @@ static struct pci_driver cs5535_mfd_driver = { | |||
186 | .remove = __devexit_p(cs5535_mfd_remove), | 186 | .remove = __devexit_p(cs5535_mfd_remove), |
187 | }; | 187 | }; |
188 | 188 | ||
189 | static int __init cs5535_mfd_init(void) | 189 | module_pci_driver(cs5535_mfd_driver); |
190 | { | ||
191 | return pci_register_driver(&cs5535_mfd_driver); | ||
192 | } | ||
193 | |||
194 | static void __exit cs5535_mfd_exit(void) | ||
195 | { | ||
196 | pci_unregister_driver(&cs5535_mfd_driver); | ||
197 | } | ||
198 | |||
199 | module_init(cs5535_mfd_init); | ||
200 | module_exit(cs5535_mfd_exit); | ||
201 | 190 | ||
202 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | 191 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); |
203 | MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); | 192 | MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); |
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 7776aff46269..1f1313c90573 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c | |||
@@ -318,6 +318,135 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg) | |||
318 | } | 318 | } |
319 | } | 319 | } |
320 | 320 | ||
321 | /* | ||
322 | * TBAT look-up table is computed from the R90 reg (8 bit register) | ||
323 | * reading as below. The battery temperature is in milliCentigrade | ||
324 | * TBAT = (1/(t1+1/298) - 273) * 1000 mC | ||
325 | * where t1 = (1/B)* ln(( ADCval * 2.5)/(R25*ITBAT*255)) | ||
326 | * Default values are R25 = 10e3, B = 3380, ITBAT = 50e-6 | ||
327 | * Example: | ||
328 | * R25=10E3, B=3380, ITBAT=50e-6, ADCVAL=62d calculates | ||
329 | * TBAT = 20015 mili degrees Centrigrade | ||
330 | * | ||
331 | */ | ||
332 | static const int32_t tbat_lookup[255] = { | ||
333 | 183258, 144221, 124334, 111336, 101826, 94397, 88343, 83257, | ||
334 | 78889, 75071, 71688, 68656, 65914, 63414, 61120, 59001, | ||
335 | 570366, 55204, 53490, 51881, 50364, 48931, 47574, 46285, | ||
336 | 45059, 43889, 42772, 41703, 40678, 39694, 38748, 37838, | ||
337 | 36961, 36115, 35297, 34507, 33743, 33002, 32284, 31588, | ||
338 | 30911, 30254, 29615, 28994, 28389, 27799, 27225, 26664, | ||
339 | 26117, 25584, 25062, 24553, 24054, 23567, 23091, 22624, | ||
340 | 22167, 21719, 21281, 20851, 20429, 20015, 19610, 19211, | ||
341 | 18820, 18436, 18058, 17688, 17323, 16965, 16612, 16266, | ||
342 | 15925, 15589, 15259, 14933, 14613, 14298, 13987, 13681, | ||
343 | 13379, 13082, 12788, 12499, 12214, 11933, 11655, 11382, | ||
344 | 11112, 10845, 10582, 10322, 10066, 9812, 9562, 9315, | ||
345 | 9071, 8830, 8591, 8356, 8123, 7893, 7665, 7440, | ||
346 | 7218, 6998, 6780, 6565, 6352, 6141, 5933, 5726, | ||
347 | 5522, 5320, 5120, 4922, 4726, 4532, 4340, 4149, | ||
348 | 3961, 3774, 3589, 3406, 3225, 3045, 2867, 2690, | ||
349 | 2516, 2342, 2170, 2000, 1831, 1664, 1498, 1334, | ||
350 | 1171, 1009, 849, 690, 532, 376, 221, 67, | ||
351 | -84, -236, -386, -535, -683, -830, -975, -1119, | ||
352 | -1263, -1405, -1546, -1686, -1825, -1964, -2101, -2237, | ||
353 | -2372, -2506, -2639, -2771, -2902, -3033, -3162, -3291, | ||
354 | -3418, -3545, -3671, -3796, -3920, -4044, -4166, -4288, | ||
355 | -4409, -4529, -4649, -4767, -4885, -5002, -5119, -5235, | ||
356 | -5349, -5464, -5577, -5690, -5802, -5913, -6024, -6134, | ||
357 | -6244, -6352, -6461, -6568, -6675, -6781, -6887, -6992, | ||
358 | -7096, -7200, -7303, -7406, -7508, -7609, -7710, -7810, | ||
359 | -7910, -8009, -8108, -8206, -8304, -8401, -8497, -8593, | ||
360 | -8689, -8784, -8878, -8972, -9066, -9159, -9251, -9343, | ||
361 | -9435, -9526, -9617, -9707, -9796, -9886, -9975, -10063, | ||
362 | -10151, -10238, -10325, -10412, -10839, -10923, -11007, -11090, | ||
363 | -11173, -11256, -11338, -11420, -11501, -11583, -11663, -11744, | ||
364 | -11823, -11903, -11982 | ||
365 | }; | ||
366 | |||
367 | static const u8 chan_mux[DA9052_ADC_VBBAT + 1] = { | ||
368 | [DA9052_ADC_VDDOUT] = DA9052_ADC_MAN_MUXSEL_VDDOUT, | ||
369 | [DA9052_ADC_ICH] = DA9052_ADC_MAN_MUXSEL_ICH, | ||
370 | [DA9052_ADC_TBAT] = DA9052_ADC_MAN_MUXSEL_TBAT, | ||
371 | [DA9052_ADC_VBAT] = DA9052_ADC_MAN_MUXSEL_VBAT, | ||
372 | [DA9052_ADC_IN4] = DA9052_ADC_MAN_MUXSEL_AD4, | ||
373 | [DA9052_ADC_IN5] = DA9052_ADC_MAN_MUXSEL_AD5, | ||
374 | [DA9052_ADC_IN6] = DA9052_ADC_MAN_MUXSEL_AD6, | ||
375 | [DA9052_ADC_VBBAT] = DA9052_ADC_MAN_MUXSEL_VBBAT | ||
376 | }; | ||
377 | |||
378 | int da9052_adc_manual_read(struct da9052 *da9052, unsigned char channel) | ||
379 | { | ||
380 | int ret; | ||
381 | unsigned short calc_data; | ||
382 | unsigned short data; | ||
383 | unsigned char mux_sel; | ||
384 | |||
385 | if (channel > DA9052_ADC_VBBAT) | ||
386 | return -EINVAL; | ||
387 | |||
388 | mutex_lock(&da9052->auxadc_lock); | ||
389 | |||
390 | /* Channel gets activated on enabling the Conversion bit */ | ||
391 | mux_sel = chan_mux[channel] | DA9052_ADC_MAN_MAN_CONV; | ||
392 | |||
393 | ret = da9052_reg_write(da9052, DA9052_ADC_MAN_REG, mux_sel); | ||
394 | if (ret < 0) | ||
395 | goto err; | ||
396 | |||
397 | /* Wait for an interrupt */ | ||
398 | if (!wait_for_completion_timeout(&da9052->done, | ||
399 | msecs_to_jiffies(500))) { | ||
400 | dev_err(da9052->dev, | ||
401 | "timeout waiting for ADC conversion interrupt\n"); | ||
402 | ret = -ETIMEDOUT; | ||
403 | goto err; | ||
404 | } | ||
405 | |||
406 | ret = da9052_reg_read(da9052, DA9052_ADC_RES_H_REG); | ||
407 | if (ret < 0) | ||
408 | goto err; | ||
409 | |||
410 | calc_data = (unsigned short)ret; | ||
411 | data = calc_data << 2; | ||
412 | |||
413 | ret = da9052_reg_read(da9052, DA9052_ADC_RES_L_REG); | ||
414 | if (ret < 0) | ||
415 | goto err; | ||
416 | |||
417 | calc_data = (unsigned short)(ret & DA9052_ADC_RES_LSB); | ||
418 | data |= calc_data; | ||
419 | |||
420 | ret = data; | ||
421 | |||
422 | err: | ||
423 | mutex_unlock(&da9052->auxadc_lock); | ||
424 | return ret; | ||
425 | } | ||
426 | EXPORT_SYMBOL_GPL(da9052_adc_manual_read); | ||
427 | |||
428 | static irqreturn_t da9052_auxadc_irq(int irq, void *irq_data) | ||
429 | { | ||
430 | struct da9052 *da9052 = irq_data; | ||
431 | |||
432 | complete(&da9052->done); | ||
433 | |||
434 | return IRQ_HANDLED; | ||
435 | } | ||
436 | |||
437 | int da9052_adc_read_temp(struct da9052 *da9052) | ||
438 | { | ||
439 | int tbat; | ||
440 | |||
441 | tbat = da9052_reg_read(da9052, DA9052_TBAT_RES_REG); | ||
442 | if (tbat <= 0) | ||
443 | return tbat; | ||
444 | |||
445 | /* ARRAY_SIZE check is not needed since TBAT is a 8-bit register */ | ||
446 | return tbat_lookup[tbat - 1]; | ||
447 | } | ||
448 | EXPORT_SYMBOL_GPL(da9052_adc_read_temp); | ||
449 | |||
321 | static struct resource da9052_rtc_resource = { | 450 | static struct resource da9052_rtc_resource = { |
322 | .name = "ALM", | 451 | .name = "ALM", |
323 | .start = DA9052_IRQ_ALARM, | 452 | .start = DA9052_IRQ_ALARM, |
@@ -646,6 +775,9 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
646 | struct irq_desc *desc; | 775 | struct irq_desc *desc; |
647 | int ret; | 776 | int ret; |
648 | 777 | ||
778 | mutex_init(&da9052->auxadc_lock); | ||
779 | init_completion(&da9052->done); | ||
780 | |||
649 | if (pdata && pdata->init != NULL) | 781 | if (pdata && pdata->init != NULL) |
650 | pdata->init(da9052); | 782 | pdata->init(da9052); |
651 | 783 | ||
@@ -665,6 +797,12 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
665 | 797 | ||
666 | da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data); | 798 | da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data); |
667 | 799 | ||
800 | ret = request_threaded_irq(DA9052_IRQ_ADC_EOM, NULL, da9052_auxadc_irq, | ||
801 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
802 | "adc irq", da9052); | ||
803 | if (ret != 0) | ||
804 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); | ||
805 | |||
668 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, | 806 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, |
669 | ARRAY_SIZE(da9052_subdev_info), NULL, 0); | 807 | ARRAY_SIZE(da9052_subdev_info), NULL, 0); |
670 | if (ret) | 808 | if (ret) |
@@ -673,6 +811,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
673 | return 0; | 811 | return 0; |
674 | 812 | ||
675 | err: | 813 | err: |
814 | free_irq(DA9052_IRQ_ADC_EOM, da9052); | ||
676 | mfd_remove_devices(da9052->dev); | 815 | mfd_remove_devices(da9052->dev); |
677 | regmap_err: | 816 | regmap_err: |
678 | return ret; | 817 | return ret; |
@@ -680,6 +819,7 @@ regmap_err: | |||
680 | 819 | ||
681 | void da9052_device_exit(struct da9052 *da9052) | 820 | void da9052_device_exit(struct da9052 *da9052) |
682 | { | 821 | { |
822 | free_irq(DA9052_IRQ_ADC_EOM, da9052); | ||
683 | regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data); | 823 | regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data); |
684 | mfd_remove_devices(da9052->dev); | 824 | mfd_remove_devices(da9052->dev); |
685 | } | 825 | } |
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 36b88e395499..82c9d6450286 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c | |||
@@ -22,6 +22,11 @@ | |||
22 | #include <linux/mfd/da9052/da9052.h> | 22 | #include <linux/mfd/da9052/da9052.h> |
23 | #include <linux/mfd/da9052/reg.h> | 23 | #include <linux/mfd/da9052/reg.h> |
24 | 24 | ||
25 | #ifdef CONFIG_OF | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #endif | ||
29 | |||
25 | static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) | 30 | static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) |
26 | { | 31 | { |
27 | int reg_val, ret; | 32 | int reg_val, ret; |
@@ -41,13 +46,31 @@ static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) | |||
41 | return 0; | 46 | return 0; |
42 | } | 47 | } |
43 | 48 | ||
49 | static struct i2c_device_id da9052_i2c_id[] = { | ||
50 | {"da9052", DA9052}, | ||
51 | {"da9053-aa", DA9053_AA}, | ||
52 | {"da9053-ba", DA9053_BA}, | ||
53 | {"da9053-bb", DA9053_BB}, | ||
54 | {} | ||
55 | }; | ||
56 | |||
57 | #ifdef CONFIG_OF | ||
58 | static const struct of_device_id dialog_dt_ids[] = { | ||
59 | { .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] }, | ||
60 | { .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] }, | ||
61 | { .compatible = "dlg,da9053-ab", .data = &da9052_i2c_id[2] }, | ||
62 | { .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] }, | ||
63 | { /* sentinel */ } | ||
64 | }; | ||
65 | #endif | ||
66 | |||
44 | static int __devinit da9052_i2c_probe(struct i2c_client *client, | 67 | static int __devinit da9052_i2c_probe(struct i2c_client *client, |
45 | const struct i2c_device_id *id) | 68 | const struct i2c_device_id *id) |
46 | { | 69 | { |
47 | struct da9052 *da9052; | 70 | struct da9052 *da9052; |
48 | int ret; | 71 | int ret; |
49 | 72 | ||
50 | da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); | 73 | da9052 = devm_kzalloc(&client->dev, sizeof(struct da9052), GFP_KERNEL); |
51 | if (!da9052) | 74 | if (!da9052) |
52 | return -ENOMEM; | 75 | return -ENOMEM; |
53 | 76 | ||
@@ -55,8 +78,7 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client, | |||
55 | I2C_FUNC_SMBUS_BYTE_DATA)) { | 78 | I2C_FUNC_SMBUS_BYTE_DATA)) { |
56 | dev_info(&client->dev, "Error in %s:i2c_check_functionality\n", | 79 | dev_info(&client->dev, "Error in %s:i2c_check_functionality\n", |
57 | __func__); | 80 | __func__); |
58 | ret = -ENODEV; | 81 | return -ENODEV; |
59 | goto err; | ||
60 | } | 82 | } |
61 | 83 | ||
62 | da9052->dev = &client->dev; | 84 | da9052->dev = &client->dev; |
@@ -64,29 +86,39 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client, | |||
64 | 86 | ||
65 | i2c_set_clientdata(client, da9052); | 87 | i2c_set_clientdata(client, da9052); |
66 | 88 | ||
67 | da9052->regmap = regmap_init_i2c(client, &da9052_regmap_config); | 89 | da9052->regmap = devm_regmap_init_i2c(client, &da9052_regmap_config); |
68 | if (IS_ERR(da9052->regmap)) { | 90 | if (IS_ERR(da9052->regmap)) { |
69 | ret = PTR_ERR(da9052->regmap); | 91 | ret = PTR_ERR(da9052->regmap); |
70 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | 92 | dev_err(&client->dev, "Failed to allocate register map: %d\n", |
71 | ret); | 93 | ret); |
72 | goto err; | 94 | return ret; |
73 | } | 95 | } |
74 | 96 | ||
75 | ret = da9052_i2c_enable_multiwrite(da9052); | 97 | ret = da9052_i2c_enable_multiwrite(da9052); |
76 | if (ret < 0) | 98 | if (ret < 0) |
77 | goto err_regmap; | 99 | return ret; |
100 | |||
101 | #ifdef CONFIG_OF | ||
102 | if (!id) { | ||
103 | struct device_node *np = client->dev.of_node; | ||
104 | const struct of_device_id *deviceid; | ||
105 | |||
106 | deviceid = of_match_node(dialog_dt_ids, np); | ||
107 | id = (const struct i2c_device_id *)deviceid->data; | ||
108 | } | ||
109 | #endif | ||
110 | |||
111 | if (!id) { | ||
112 | ret = -ENODEV; | ||
113 | dev_err(&client->dev, "id is null.\n"); | ||
114 | return ret; | ||
115 | } | ||
78 | 116 | ||
79 | ret = da9052_device_init(da9052, id->driver_data); | 117 | ret = da9052_device_init(da9052, id->driver_data); |
80 | if (ret != 0) | 118 | if (ret != 0) |
81 | goto err_regmap; | 119 | return ret; |
82 | 120 | ||
83 | return 0; | 121 | return 0; |
84 | |||
85 | err_regmap: | ||
86 | regmap_exit(da9052->regmap); | ||
87 | err: | ||
88 | kfree(da9052); | ||
89 | return ret; | ||
90 | } | 122 | } |
91 | 123 | ||
92 | static int __devexit da9052_i2c_remove(struct i2c_client *client) | 124 | static int __devexit da9052_i2c_remove(struct i2c_client *client) |
@@ -94,20 +126,9 @@ static int __devexit da9052_i2c_remove(struct i2c_client *client) | |||
94 | struct da9052 *da9052 = i2c_get_clientdata(client); | 126 | struct da9052 *da9052 = i2c_get_clientdata(client); |
95 | 127 | ||
96 | da9052_device_exit(da9052); | 128 | da9052_device_exit(da9052); |
97 | regmap_exit(da9052->regmap); | ||
98 | kfree(da9052); | ||
99 | |||
100 | return 0; | 129 | return 0; |
101 | } | 130 | } |
102 | 131 | ||
103 | static struct i2c_device_id da9052_i2c_id[] = { | ||
104 | {"da9052", DA9052}, | ||
105 | {"da9053-aa", DA9053_AA}, | ||
106 | {"da9053-ba", DA9053_BA}, | ||
107 | {"da9053-bb", DA9053_BB}, | ||
108 | {} | ||
109 | }; | ||
110 | |||
111 | static struct i2c_driver da9052_i2c_driver = { | 132 | static struct i2c_driver da9052_i2c_driver = { |
112 | .probe = da9052_i2c_probe, | 133 | .probe = da9052_i2c_probe, |
113 | .remove = __devexit_p(da9052_i2c_remove), | 134 | .remove = __devexit_p(da9052_i2c_remove), |
@@ -115,6 +136,9 @@ static struct i2c_driver da9052_i2c_driver = { | |||
115 | .driver = { | 136 | .driver = { |
116 | .name = "da9052", | 137 | .name = "da9052", |
117 | .owner = THIS_MODULE, | 138 | .owner = THIS_MODULE, |
139 | #ifdef CONFIG_OF | ||
140 | .of_match_table = dialog_dt_ids, | ||
141 | #endif | ||
118 | }, | 142 | }, |
119 | }; | 143 | }; |
120 | 144 | ||
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c index 6faf149e8d94..dbeadc5a6436 100644 --- a/drivers/mfd/da9052-spi.c +++ b/drivers/mfd/da9052-spi.c | |||
@@ -25,8 +25,9 @@ static int __devinit da9052_spi_probe(struct spi_device *spi) | |||
25 | { | 25 | { |
26 | int ret; | 26 | int ret; |
27 | const struct spi_device_id *id = spi_get_device_id(spi); | 27 | const struct spi_device_id *id = spi_get_device_id(spi); |
28 | struct da9052 *da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); | 28 | struct da9052 *da9052; |
29 | 29 | ||
30 | da9052 = devm_kzalloc(&spi->dev, sizeof(struct da9052), GFP_KERNEL); | ||
30 | if (!da9052) | 31 | if (!da9052) |
31 | return -ENOMEM; | 32 | return -ENOMEM; |
32 | 33 | ||
@@ -42,25 +43,19 @@ static int __devinit da9052_spi_probe(struct spi_device *spi) | |||
42 | da9052_regmap_config.read_flag_mask = 1; | 43 | da9052_regmap_config.read_flag_mask = 1; |
43 | da9052_regmap_config.write_flag_mask = 0; | 44 | da9052_regmap_config.write_flag_mask = 0; |
44 | 45 | ||
45 | da9052->regmap = regmap_init_spi(spi, &da9052_regmap_config); | 46 | da9052->regmap = devm_regmap_init_spi(spi, &da9052_regmap_config); |
46 | if (IS_ERR(da9052->regmap)) { | 47 | if (IS_ERR(da9052->regmap)) { |
47 | ret = PTR_ERR(da9052->regmap); | 48 | ret = PTR_ERR(da9052->regmap); |
48 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", | 49 | dev_err(&spi->dev, "Failed to allocate register map: %d\n", |
49 | ret); | 50 | ret); |
50 | goto err; | 51 | return ret; |
51 | } | 52 | } |
52 | 53 | ||
53 | ret = da9052_device_init(da9052, id->driver_data); | 54 | ret = da9052_device_init(da9052, id->driver_data); |
54 | if (ret != 0) | 55 | if (ret != 0) |
55 | goto err_regmap; | 56 | return ret; |
56 | 57 | ||
57 | return 0; | 58 | return 0; |
58 | |||
59 | err_regmap: | ||
60 | regmap_exit(da9052->regmap); | ||
61 | err: | ||
62 | kfree(da9052); | ||
63 | return ret; | ||
64 | } | 59 | } |
65 | 60 | ||
66 | static int __devexit da9052_spi_remove(struct spi_device *spi) | 61 | static int __devexit da9052_spi_remove(struct spi_device *spi) |
@@ -68,9 +63,6 @@ static int __devexit da9052_spi_remove(struct spi_device *spi) | |||
68 | struct da9052 *da9052 = dev_get_drvdata(&spi->dev); | 63 | struct da9052 *da9052 = dev_get_drvdata(&spi->dev); |
69 | 64 | ||
70 | da9052_device_exit(da9052); | 65 | da9052_device_exit(da9052); |
71 | regmap_exit(da9052->regmap); | ||
72 | kfree(da9052); | ||
73 | |||
74 | return 0; | 66 | return 0; |
75 | } | 67 | } |
76 | 68 | ||
@@ -88,7 +80,6 @@ static struct spi_driver da9052_spi_driver = { | |||
88 | .id_table = da9052_spi_id, | 80 | .id_table = da9052_spi_id, |
89 | .driver = { | 81 | .driver = { |
90 | .name = "da9052", | 82 | .name = "da9052", |
91 | .bus = &spi_bus_type, | ||
92 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
93 | }, | 84 | }, |
94 | }; | 85 | }; |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 5be32489714f..671c8bc14bbc 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -2720,6 +2720,7 @@ static struct regulator_consumer_supply db8500_vape_consumers[] = { | |||
2720 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), | 2720 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), |
2721 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), | 2721 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), |
2722 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), | 2722 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), |
2723 | REGULATOR_SUPPLY("v-i2c", "nmk-i2c.4"), | ||
2723 | /* "v-mmc" changed to "vcore" in the mainline kernel */ | 2724 | /* "v-mmc" changed to "vcore" in the mainline kernel */ |
2724 | REGULATOR_SUPPLY("vcore", "sdi0"), | 2725 | REGULATOR_SUPPLY("vcore", "sdi0"), |
2725 | REGULATOR_SUPPLY("vcore", "sdi1"), | 2726 | REGULATOR_SUPPLY("vcore", "sdi1"), |
@@ -2958,9 +2959,10 @@ static struct mfd_cell db8500_prcmu_devs[] = { | |||
2958 | * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic | 2959 | * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic |
2959 | * | 2960 | * |
2960 | */ | 2961 | */ |
2961 | static int __init db8500_prcmu_probe(struct platform_device *pdev) | 2962 | static int __devinit db8500_prcmu_probe(struct platform_device *pdev) |
2962 | { | 2963 | { |
2963 | int err = 0; | 2964 | struct device_node *np = pdev->dev.of_node; |
2965 | int irq = 0, err = 0; | ||
2964 | 2966 | ||
2965 | if (ux500_is_svp()) | 2967 | if (ux500_is_svp()) |
2966 | return -ENODEV; | 2968 | return -ENODEV; |
@@ -2970,8 +2972,14 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev) | |||
2970 | /* Clean up the mailbox interrupts after pre-kernel code. */ | 2972 | /* Clean up the mailbox interrupts after pre-kernel code. */ |
2971 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); | 2973 | writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); |
2972 | 2974 | ||
2973 | err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, | 2975 | if (np) |
2974 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); | 2976 | irq = platform_get_irq(pdev, 0); |
2977 | |||
2978 | if (!np || irq <= 0) | ||
2979 | irq = IRQ_DB8500_PRCMU1; | ||
2980 | |||
2981 | err = request_threaded_irq(irq, prcmu_irq_handler, | ||
2982 | prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); | ||
2975 | if (err < 0) { | 2983 | if (err < 0) { |
2976 | pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); | 2984 | pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); |
2977 | err = -EBUSY; | 2985 | err = -EBUSY; |
@@ -2981,14 +2989,16 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev) | |||
2981 | if (cpu_is_u8500v20_or_later()) | 2989 | if (cpu_is_u8500v20_or_later()) |
2982 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); | 2990 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); |
2983 | 2991 | ||
2984 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, | 2992 | if (!np) { |
2985 | ARRAY_SIZE(db8500_prcmu_devs), NULL, | 2993 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, |
2986 | 0); | 2994 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0); |
2995 | if (err) { | ||
2996 | pr_err("prcmu: Failed to add subdevices\n"); | ||
2997 | return err; | ||
2998 | } | ||
2999 | } | ||
2987 | 3000 | ||
2988 | if (err) | 3001 | pr_info("DB8500 PRCMU initialized\n"); |
2989 | pr_err("prcmu: Failed to add subdevices\n"); | ||
2990 | else | ||
2991 | pr_info("DB8500 PRCMU initialized\n"); | ||
2992 | 3002 | ||
2993 | no_irq_return: | 3003 | no_irq_return: |
2994 | return err; | 3004 | return err; |
@@ -2999,11 +3009,12 @@ static struct platform_driver db8500_prcmu_driver = { | |||
2999 | .name = "db8500-prcmu", | 3009 | .name = "db8500-prcmu", |
3000 | .owner = THIS_MODULE, | 3010 | .owner = THIS_MODULE, |
3001 | }, | 3011 | }, |
3012 | .probe = db8500_prcmu_probe, | ||
3002 | }; | 3013 | }; |
3003 | 3014 | ||
3004 | static int __init db8500_prcmu_init(void) | 3015 | static int __init db8500_prcmu_init(void) |
3005 | { | 3016 | { |
3006 | return platform_driver_probe(&db8500_prcmu_driver, db8500_prcmu_probe); | 3017 | return platform_driver_register(&db8500_prcmu_driver); |
3007 | } | 3018 | } |
3008 | 3019 | ||
3009 | arch_initcall(db8500_prcmu_init); | 3020 | arch_initcall(db8500_prcmu_init); |
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index b76657eb0c51..59df5584cb58 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c | |||
@@ -406,7 +406,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) | |||
406 | return -ENXIO; | 406 | return -ENXIO; |
407 | } | 407 | } |
408 | 408 | ||
409 | msic = kzalloc(sizeof(*msic), GFP_KERNEL); | 409 | msic = devm_kzalloc(&pdev->dev, sizeof(*msic), GFP_KERNEL); |
410 | if (!msic) | 410 | if (!msic) |
411 | return -ENOMEM; | 411 | return -ENOMEM; |
412 | 412 | ||
@@ -421,21 +421,13 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) | |||
421 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 421 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
422 | if (!res) { | 422 | if (!res) { |
423 | dev_err(&pdev->dev, "failed to get SRAM iomem resource\n"); | 423 | dev_err(&pdev->dev, "failed to get SRAM iomem resource\n"); |
424 | ret = -ENODEV; | 424 | return -ENODEV; |
425 | goto fail_free_msic; | ||
426 | } | 425 | } |
427 | 426 | ||
428 | res = request_mem_region(res->start, resource_size(res), pdev->name); | 427 | msic->irq_base = devm_request_and_ioremap(&pdev->dev, res); |
429 | if (!res) { | ||
430 | ret = -EBUSY; | ||
431 | goto fail_free_msic; | ||
432 | } | ||
433 | |||
434 | msic->irq_base = ioremap_nocache(res->start, resource_size(res)); | ||
435 | if (!msic->irq_base) { | 428 | if (!msic->irq_base) { |
436 | dev_err(&pdev->dev, "failed to map SRAM memory\n"); | 429 | dev_err(&pdev->dev, "failed to map SRAM memory\n"); |
437 | ret = -ENOMEM; | 430 | return -ENOMEM; |
438 | goto fail_release_region; | ||
439 | } | 431 | } |
440 | 432 | ||
441 | platform_set_drvdata(pdev, msic); | 433 | platform_set_drvdata(pdev, msic); |
@@ -443,7 +435,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) | |||
443 | ret = intel_msic_init_devices(msic); | 435 | ret = intel_msic_init_devices(msic); |
444 | if (ret) { | 436 | if (ret) { |
445 | dev_err(&pdev->dev, "failed to initialize MSIC devices\n"); | 437 | dev_err(&pdev->dev, "failed to initialize MSIC devices\n"); |
446 | goto fail_unmap_mem; | 438 | return ret; |
447 | } | 439 | } |
448 | 440 | ||
449 | dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n", | 441 | dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n", |
@@ -451,27 +443,14 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) | |||
451 | msic->vendor); | 443 | msic->vendor); |
452 | 444 | ||
453 | return 0; | 445 | return 0; |
454 | |||
455 | fail_unmap_mem: | ||
456 | iounmap(msic->irq_base); | ||
457 | fail_release_region: | ||
458 | release_mem_region(res->start, resource_size(res)); | ||
459 | fail_free_msic: | ||
460 | kfree(msic); | ||
461 | |||
462 | return ret; | ||
463 | } | 446 | } |
464 | 447 | ||
465 | static int __devexit intel_msic_remove(struct platform_device *pdev) | 448 | static int __devexit intel_msic_remove(struct platform_device *pdev) |
466 | { | 449 | { |
467 | struct intel_msic *msic = platform_get_drvdata(pdev); | 450 | struct intel_msic *msic = platform_get_drvdata(pdev); |
468 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
469 | 451 | ||
470 | intel_msic_remove_devices(msic); | 452 | intel_msic_remove_devices(msic); |
471 | platform_set_drvdata(pdev, NULL); | 453 | platform_set_drvdata(pdev, NULL); |
472 | iounmap(msic->irq_base); | ||
473 | release_mem_region(res->start, resource_size(res)); | ||
474 | kfree(msic); | ||
475 | 454 | ||
476 | return 0; | 455 | return 0; |
477 | } | 456 | } |
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index a9223ed1b7c5..2ea99989551a 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c | |||
@@ -283,23 +283,8 @@ static struct pci_driver cmodio_pci_driver = { | |||
283 | .remove = __devexit_p(cmodio_pci_remove), | 283 | .remove = __devexit_p(cmodio_pci_remove), |
284 | }; | 284 | }; |
285 | 285 | ||
286 | /* | 286 | module_pci_driver(cmodio_pci_driver); |
287 | * Module Init / Exit | ||
288 | */ | ||
289 | |||
290 | static int __init cmodio_init(void) | ||
291 | { | ||
292 | return pci_register_driver(&cmodio_pci_driver); | ||
293 | } | ||
294 | |||
295 | static void __exit cmodio_exit(void) | ||
296 | { | ||
297 | pci_unregister_driver(&cmodio_pci_driver); | ||
298 | } | ||
299 | 287 | ||
300 | MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); | 288 | MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); |
301 | MODULE_DESCRIPTION("Janz CMOD-IO PCI MODULbus Carrier Board Driver"); | 289 | MODULE_DESCRIPTION("Janz CMOD-IO PCI MODULbus Carrier Board Driver"); |
302 | MODULE_LICENSE("GPL"); | 290 | MODULE_LICENSE("GPL"); |
303 | |||
304 | module_init(cmodio_init); | ||
305 | module_exit(cmodio_exit); | ||
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c new file mode 100644 index 000000000000..0b2879b87fd9 --- /dev/null +++ b/drivers/mfd/lm3533-core.c | |||
@@ -0,0 +1,667 @@ | |||
1 | /* | ||
2 | * lm3533-core.c -- LM3533 Core | ||
3 | * | ||
4 | * Copyright (C) 2011-2012 Texas Instruments | ||
5 | * | ||
6 | * Author: Johan Hovold <jhovold@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/gpio.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/mfd/core.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/seq_file.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/uaccess.h> | ||
25 | |||
26 | #include <linux/mfd/lm3533.h> | ||
27 | |||
28 | |||
29 | #define LM3533_BOOST_OVP_MASK 0x06 | ||
30 | #define LM3533_BOOST_OVP_SHIFT 1 | ||
31 | |||
32 | #define LM3533_BOOST_FREQ_MASK 0x01 | ||
33 | #define LM3533_BOOST_FREQ_SHIFT 0 | ||
34 | |||
35 | #define LM3533_BL_ID_MASK 1 | ||
36 | #define LM3533_LED_ID_MASK 3 | ||
37 | #define LM3533_BL_ID_MAX 1 | ||
38 | #define LM3533_LED_ID_MAX 3 | ||
39 | |||
40 | #define LM3533_HVLED_ID_MAX 2 | ||
41 | #define LM3533_LVLED_ID_MAX 5 | ||
42 | |||
43 | #define LM3533_REG_OUTPUT_CONF1 0x10 | ||
44 | #define LM3533_REG_OUTPUT_CONF2 0x11 | ||
45 | #define LM3533_REG_BOOST_PWM 0x2c | ||
46 | |||
47 | #define LM3533_REG_MAX 0xb2 | ||
48 | |||
49 | |||
50 | static struct mfd_cell lm3533_als_devs[] = { | ||
51 | { | ||
52 | .name = "lm3533-als", | ||
53 | .id = -1, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static struct mfd_cell lm3533_bl_devs[] = { | ||
58 | { | ||
59 | .name = "lm3533-backlight", | ||
60 | .id = 0, | ||
61 | }, | ||
62 | { | ||
63 | .name = "lm3533-backlight", | ||
64 | .id = 1, | ||
65 | }, | ||
66 | }; | ||
67 | |||
68 | static struct mfd_cell lm3533_led_devs[] = { | ||
69 | { | ||
70 | .name = "lm3533-leds", | ||
71 | .id = 0, | ||
72 | }, | ||
73 | { | ||
74 | .name = "lm3533-leds", | ||
75 | .id = 1, | ||
76 | }, | ||
77 | { | ||
78 | .name = "lm3533-leds", | ||
79 | .id = 2, | ||
80 | }, | ||
81 | { | ||
82 | .name = "lm3533-leds", | ||
83 | .id = 3, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val) | ||
88 | { | ||
89 | int tmp; | ||
90 | int ret; | ||
91 | |||
92 | ret = regmap_read(lm3533->regmap, reg, &tmp); | ||
93 | if (ret < 0) { | ||
94 | dev_err(lm3533->dev, "failed to read register %02x: %d\n", | ||
95 | reg, ret); | ||
96 | return ret; | ||
97 | } | ||
98 | |||
99 | *val = tmp; | ||
100 | |||
101 | dev_dbg(lm3533->dev, "read [%02x]: %02x\n", reg, *val); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | EXPORT_SYMBOL_GPL(lm3533_read); | ||
106 | |||
107 | int lm3533_write(struct lm3533 *lm3533, u8 reg, u8 val) | ||
108 | { | ||
109 | int ret; | ||
110 | |||
111 | dev_dbg(lm3533->dev, "write [%02x]: %02x\n", reg, val); | ||
112 | |||
113 | ret = regmap_write(lm3533->regmap, reg, val); | ||
114 | if (ret < 0) { | ||
115 | dev_err(lm3533->dev, "failed to write register %02x: %d\n", | ||
116 | reg, ret); | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | EXPORT_SYMBOL_GPL(lm3533_write); | ||
122 | |||
123 | int lm3533_update(struct lm3533 *lm3533, u8 reg, u8 val, u8 mask) | ||
124 | { | ||
125 | int ret; | ||
126 | |||
127 | dev_dbg(lm3533->dev, "update [%02x]: %02x/%02x\n", reg, val, mask); | ||
128 | |||
129 | ret = regmap_update_bits(lm3533->regmap, reg, mask, val); | ||
130 | if (ret < 0) { | ||
131 | dev_err(lm3533->dev, "failed to update register %02x: %d\n", | ||
132 | reg, ret); | ||
133 | } | ||
134 | |||
135 | return ret; | ||
136 | } | ||
137 | EXPORT_SYMBOL_GPL(lm3533_update); | ||
138 | |||
139 | static int lm3533_set_boost_freq(struct lm3533 *lm3533, | ||
140 | enum lm3533_boost_freq freq) | ||
141 | { | ||
142 | int ret; | ||
143 | |||
144 | ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM, | ||
145 | freq << LM3533_BOOST_FREQ_SHIFT, | ||
146 | LM3533_BOOST_FREQ_MASK); | ||
147 | if (ret) | ||
148 | dev_err(lm3533->dev, "failed to set boost frequency\n"); | ||
149 | |||
150 | return ret; | ||
151 | } | ||
152 | |||
153 | |||
154 | static int lm3533_set_boost_ovp(struct lm3533 *lm3533, | ||
155 | enum lm3533_boost_ovp ovp) | ||
156 | { | ||
157 | int ret; | ||
158 | |||
159 | ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM, | ||
160 | ovp << LM3533_BOOST_OVP_SHIFT, | ||
161 | LM3533_BOOST_OVP_MASK); | ||
162 | if (ret) | ||
163 | dev_err(lm3533->dev, "failed to set boost ovp\n"); | ||
164 | |||
165 | return ret; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * HVLED output config -- output hvled controlled by backlight bl | ||
170 | */ | ||
171 | static int lm3533_set_hvled_config(struct lm3533 *lm3533, u8 hvled, u8 bl) | ||
172 | { | ||
173 | u8 val; | ||
174 | u8 mask; | ||
175 | int shift; | ||
176 | int ret; | ||
177 | |||
178 | if (hvled == 0 || hvled > LM3533_HVLED_ID_MAX) | ||
179 | return -EINVAL; | ||
180 | |||
181 | if (bl > LM3533_BL_ID_MAX) | ||
182 | return -EINVAL; | ||
183 | |||
184 | shift = hvled - 1; | ||
185 | mask = LM3533_BL_ID_MASK << shift; | ||
186 | val = bl << shift; | ||
187 | |||
188 | ret = lm3533_update(lm3533, LM3533_REG_OUTPUT_CONF1, val, mask); | ||
189 | if (ret) | ||
190 | dev_err(lm3533->dev, "failed to set hvled config\n"); | ||
191 | |||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * LVLED output config -- output lvled controlled by LED led | ||
197 | */ | ||
198 | static int lm3533_set_lvled_config(struct lm3533 *lm3533, u8 lvled, u8 led) | ||
199 | { | ||
200 | u8 reg; | ||
201 | u8 val; | ||
202 | u8 mask; | ||
203 | int shift; | ||
204 | int ret; | ||
205 | |||
206 | if (lvled == 0 || lvled > LM3533_LVLED_ID_MAX) | ||
207 | return -EINVAL; | ||
208 | |||
209 | if (led > LM3533_LED_ID_MAX) | ||
210 | return -EINVAL; | ||
211 | |||
212 | if (lvled < 4) { | ||
213 | reg = LM3533_REG_OUTPUT_CONF1; | ||
214 | shift = 2 * lvled; | ||
215 | } else { | ||
216 | reg = LM3533_REG_OUTPUT_CONF2; | ||
217 | shift = 2 * (lvled - 4); | ||
218 | } | ||
219 | |||
220 | mask = LM3533_LED_ID_MASK << shift; | ||
221 | val = led << shift; | ||
222 | |||
223 | ret = lm3533_update(lm3533, reg, val, mask); | ||
224 | if (ret) | ||
225 | dev_err(lm3533->dev, "failed to set lvled config\n"); | ||
226 | |||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static void lm3533_enable(struct lm3533 *lm3533) | ||
231 | { | ||
232 | if (gpio_is_valid(lm3533->gpio_hwen)) | ||
233 | gpio_set_value(lm3533->gpio_hwen, 1); | ||
234 | } | ||
235 | |||
236 | static void lm3533_disable(struct lm3533 *lm3533) | ||
237 | { | ||
238 | if (gpio_is_valid(lm3533->gpio_hwen)) | ||
239 | gpio_set_value(lm3533->gpio_hwen, 0); | ||
240 | } | ||
241 | |||
242 | enum lm3533_attribute_type { | ||
243 | LM3533_ATTR_TYPE_BACKLIGHT, | ||
244 | LM3533_ATTR_TYPE_LED, | ||
245 | }; | ||
246 | |||
247 | struct lm3533_device_attribute { | ||
248 | struct device_attribute dev_attr; | ||
249 | enum lm3533_attribute_type type; | ||
250 | union { | ||
251 | struct { | ||
252 | u8 id; | ||
253 | } output; | ||
254 | } u; | ||
255 | }; | ||
256 | |||
257 | #define to_lm3533_dev_attr(_attr) \ | ||
258 | container_of(_attr, struct lm3533_device_attribute, dev_attr) | ||
259 | |||
260 | static ssize_t show_output(struct device *dev, | ||
261 | struct device_attribute *attr, char *buf) | ||
262 | { | ||
263 | struct lm3533 *lm3533 = dev_get_drvdata(dev); | ||
264 | struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr); | ||
265 | int id = lattr->u.output.id; | ||
266 | u8 reg; | ||
267 | u8 val; | ||
268 | u8 mask; | ||
269 | int shift; | ||
270 | int ret; | ||
271 | |||
272 | if (lattr->type == LM3533_ATTR_TYPE_BACKLIGHT) { | ||
273 | reg = LM3533_REG_OUTPUT_CONF1; | ||
274 | shift = id - 1; | ||
275 | mask = LM3533_BL_ID_MASK << shift; | ||
276 | } else { | ||
277 | if (id < 4) { | ||
278 | reg = LM3533_REG_OUTPUT_CONF1; | ||
279 | shift = 2 * id; | ||
280 | } else { | ||
281 | reg = LM3533_REG_OUTPUT_CONF2; | ||
282 | shift = 2 * (id - 4); | ||
283 | } | ||
284 | mask = LM3533_LED_ID_MASK << shift; | ||
285 | } | ||
286 | |||
287 | ret = lm3533_read(lm3533, reg, &val); | ||
288 | if (ret) | ||
289 | return ret; | ||
290 | |||
291 | val = (val & mask) >> shift; | ||
292 | |||
293 | return scnprintf(buf, PAGE_SIZE, "%u\n", val); | ||
294 | } | ||
295 | |||
296 | static ssize_t store_output(struct device *dev, | ||
297 | struct device_attribute *attr, | ||
298 | const char *buf, size_t len) | ||
299 | { | ||
300 | struct lm3533 *lm3533 = dev_get_drvdata(dev); | ||
301 | struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr); | ||
302 | int id = lattr->u.output.id; | ||
303 | u8 val; | ||
304 | int ret; | ||
305 | |||
306 | if (kstrtou8(buf, 0, &val)) | ||
307 | return -EINVAL; | ||
308 | |||
309 | if (lattr->type == LM3533_ATTR_TYPE_BACKLIGHT) | ||
310 | ret = lm3533_set_hvled_config(lm3533, id, val); | ||
311 | else | ||
312 | ret = lm3533_set_lvled_config(lm3533, id, val); | ||
313 | |||
314 | if (ret) | ||
315 | return ret; | ||
316 | |||
317 | return len; | ||
318 | } | ||
319 | |||
320 | #define LM3533_OUTPUT_ATTR(_name, _mode, _show, _store, _type, _id) \ | ||
321 | struct lm3533_device_attribute lm3533_dev_attr_##_name = \ | ||
322 | { .dev_attr = __ATTR(_name, _mode, _show, _store), \ | ||
323 | .type = _type, \ | ||
324 | .u.output = { .id = _id }, } | ||
325 | |||
326 | #define LM3533_OUTPUT_ATTR_RW(_name, _type, _id) \ | ||
327 | LM3533_OUTPUT_ATTR(output_##_name, S_IRUGO | S_IWUSR, \ | ||
328 | show_output, store_output, _type, _id) | ||
329 | |||
330 | #define LM3533_OUTPUT_HVLED_ATTR_RW(_nr) \ | ||
331 | LM3533_OUTPUT_ATTR_RW(hvled##_nr, LM3533_ATTR_TYPE_BACKLIGHT, _nr) | ||
332 | #define LM3533_OUTPUT_LVLED_ATTR_RW(_nr) \ | ||
333 | LM3533_OUTPUT_ATTR_RW(lvled##_nr, LM3533_ATTR_TYPE_LED, _nr) | ||
334 | /* | ||
335 | * Output config: | ||
336 | * | ||
337 | * output_hvled<nr> 0-1 | ||
338 | * output_lvled<nr> 0-3 | ||
339 | */ | ||
340 | static LM3533_OUTPUT_HVLED_ATTR_RW(1); | ||
341 | static LM3533_OUTPUT_HVLED_ATTR_RW(2); | ||
342 | static LM3533_OUTPUT_LVLED_ATTR_RW(1); | ||
343 | static LM3533_OUTPUT_LVLED_ATTR_RW(2); | ||
344 | static LM3533_OUTPUT_LVLED_ATTR_RW(3); | ||
345 | static LM3533_OUTPUT_LVLED_ATTR_RW(4); | ||
346 | static LM3533_OUTPUT_LVLED_ATTR_RW(5); | ||
347 | |||
348 | static struct attribute *lm3533_attributes[] = { | ||
349 | &lm3533_dev_attr_output_hvled1.dev_attr.attr, | ||
350 | &lm3533_dev_attr_output_hvled2.dev_attr.attr, | ||
351 | &lm3533_dev_attr_output_lvled1.dev_attr.attr, | ||
352 | &lm3533_dev_attr_output_lvled2.dev_attr.attr, | ||
353 | &lm3533_dev_attr_output_lvled3.dev_attr.attr, | ||
354 | &lm3533_dev_attr_output_lvled4.dev_attr.attr, | ||
355 | &lm3533_dev_attr_output_lvled5.dev_attr.attr, | ||
356 | NULL, | ||
357 | }; | ||
358 | |||
359 | #define to_dev_attr(_attr) \ | ||
360 | container_of(_attr, struct device_attribute, attr) | ||
361 | |||
362 | static umode_t lm3533_attr_is_visible(struct kobject *kobj, | ||
363 | struct attribute *attr, int n) | ||
364 | { | ||
365 | struct device *dev = container_of(kobj, struct device, kobj); | ||
366 | struct lm3533 *lm3533 = dev_get_drvdata(dev); | ||
367 | struct device_attribute *dattr = to_dev_attr(attr); | ||
368 | struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(dattr); | ||
369 | enum lm3533_attribute_type type = lattr->type; | ||
370 | umode_t mode = attr->mode; | ||
371 | |||
372 | if (!lm3533->have_backlights && type == LM3533_ATTR_TYPE_BACKLIGHT) | ||
373 | mode = 0; | ||
374 | else if (!lm3533->have_leds && type == LM3533_ATTR_TYPE_LED) | ||
375 | mode = 0; | ||
376 | |||
377 | return mode; | ||
378 | }; | ||
379 | |||
380 | static struct attribute_group lm3533_attribute_group = { | ||
381 | .is_visible = lm3533_attr_is_visible, | ||
382 | .attrs = lm3533_attributes | ||
383 | }; | ||
384 | |||
385 | static int __devinit lm3533_device_als_init(struct lm3533 *lm3533) | ||
386 | { | ||
387 | struct lm3533_platform_data *pdata = lm3533->dev->platform_data; | ||
388 | int ret; | ||
389 | |||
390 | if (!pdata->als) | ||
391 | return 0; | ||
392 | |||
393 | lm3533_als_devs[0].platform_data = pdata->als; | ||
394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); | ||
395 | |||
396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0); | ||
397 | if (ret) { | ||
398 | dev_err(lm3533->dev, "failed to add ALS device\n"); | ||
399 | return ret; | ||
400 | } | ||
401 | |||
402 | lm3533->have_als = 1; | ||
403 | |||
404 | return 0; | ||
405 | } | ||
406 | |||
407 | static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533) | ||
408 | { | ||
409 | struct lm3533_platform_data *pdata = lm3533->dev->platform_data; | ||
410 | int i; | ||
411 | int ret; | ||
412 | |||
413 | if (!pdata->backlights || pdata->num_backlights == 0) | ||
414 | return 0; | ||
415 | |||
416 | if (pdata->num_backlights > ARRAY_SIZE(lm3533_bl_devs)) | ||
417 | pdata->num_backlights = ARRAY_SIZE(lm3533_bl_devs); | ||
418 | |||
419 | for (i = 0; i < pdata->num_backlights; ++i) { | ||
420 | lm3533_bl_devs[i].platform_data = &pdata->backlights[i]; | ||
421 | lm3533_bl_devs[i].pdata_size = sizeof(pdata->backlights[i]); | ||
422 | } | ||
423 | |||
424 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, | ||
425 | pdata->num_backlights, NULL, 0); | ||
426 | if (ret) { | ||
427 | dev_err(lm3533->dev, "failed to add backlight devices\n"); | ||
428 | return ret; | ||
429 | } | ||
430 | |||
431 | lm3533->have_backlights = 1; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int __devinit lm3533_device_led_init(struct lm3533 *lm3533) | ||
437 | { | ||
438 | struct lm3533_platform_data *pdata = lm3533->dev->platform_data; | ||
439 | int i; | ||
440 | int ret; | ||
441 | |||
442 | if (!pdata->leds || pdata->num_leds == 0) | ||
443 | return 0; | ||
444 | |||
445 | if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs)) | ||
446 | pdata->num_leds = ARRAY_SIZE(lm3533_led_devs); | ||
447 | |||
448 | for (i = 0; i < pdata->num_leds; ++i) { | ||
449 | lm3533_led_devs[i].platform_data = &pdata->leds[i]; | ||
450 | lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]); | ||
451 | } | ||
452 | |||
453 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, | ||
454 | pdata->num_leds, NULL, 0); | ||
455 | if (ret) { | ||
456 | dev_err(lm3533->dev, "failed to add LED devices\n"); | ||
457 | return ret; | ||
458 | } | ||
459 | |||
460 | lm3533->have_leds = 1; | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static int __devinit lm3533_device_setup(struct lm3533 *lm3533, | ||
466 | struct lm3533_platform_data *pdata) | ||
467 | { | ||
468 | int ret; | ||
469 | |||
470 | ret = lm3533_set_boost_freq(lm3533, pdata->boost_freq); | ||
471 | if (ret) | ||
472 | return ret; | ||
473 | |||
474 | ret = lm3533_set_boost_ovp(lm3533, pdata->boost_ovp); | ||
475 | if (ret) | ||
476 | return ret; | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | static int __devinit lm3533_device_init(struct lm3533 *lm3533) | ||
482 | { | ||
483 | struct lm3533_platform_data *pdata = lm3533->dev->platform_data; | ||
484 | int ret; | ||
485 | |||
486 | dev_dbg(lm3533->dev, "%s\n", __func__); | ||
487 | |||
488 | if (!pdata) { | ||
489 | dev_err(lm3533->dev, "no platform data\n"); | ||
490 | return -EINVAL; | ||
491 | } | ||
492 | |||
493 | lm3533->gpio_hwen = pdata->gpio_hwen; | ||
494 | |||
495 | dev_set_drvdata(lm3533->dev, lm3533); | ||
496 | |||
497 | if (gpio_is_valid(lm3533->gpio_hwen)) { | ||
498 | ret = gpio_request_one(lm3533->gpio_hwen, GPIOF_OUT_INIT_LOW, | ||
499 | "lm3533-hwen"); | ||
500 | if (ret < 0) { | ||
501 | dev_err(lm3533->dev, | ||
502 | "failed to request HWEN GPIO %d\n", | ||
503 | lm3533->gpio_hwen); | ||
504 | return ret; | ||
505 | } | ||
506 | } | ||
507 | |||
508 | lm3533_enable(lm3533); | ||
509 | |||
510 | ret = lm3533_device_setup(lm3533, pdata); | ||
511 | if (ret) | ||
512 | goto err_disable; | ||
513 | |||
514 | lm3533_device_als_init(lm3533); | ||
515 | lm3533_device_bl_init(lm3533); | ||
516 | lm3533_device_led_init(lm3533); | ||
517 | |||
518 | ret = sysfs_create_group(&lm3533->dev->kobj, &lm3533_attribute_group); | ||
519 | if (ret < 0) { | ||
520 | dev_err(lm3533->dev, "failed to create sysfs attributes\n"); | ||
521 | goto err_unregister; | ||
522 | } | ||
523 | |||
524 | return 0; | ||
525 | |||
526 | err_unregister: | ||
527 | mfd_remove_devices(lm3533->dev); | ||
528 | err_disable: | ||
529 | lm3533_disable(lm3533); | ||
530 | if (gpio_is_valid(lm3533->gpio_hwen)) | ||
531 | gpio_free(lm3533->gpio_hwen); | ||
532 | |||
533 | return ret; | ||
534 | } | ||
535 | |||
536 | static void __devexit lm3533_device_exit(struct lm3533 *lm3533) | ||
537 | { | ||
538 | dev_dbg(lm3533->dev, "%s\n", __func__); | ||
539 | |||
540 | sysfs_remove_group(&lm3533->dev->kobj, &lm3533_attribute_group); | ||
541 | |||
542 | mfd_remove_devices(lm3533->dev); | ||
543 | lm3533_disable(lm3533); | ||
544 | if (gpio_is_valid(lm3533->gpio_hwen)) | ||
545 | gpio_free(lm3533->gpio_hwen); | ||
546 | } | ||
547 | |||
548 | static bool lm3533_readable_register(struct device *dev, unsigned int reg) | ||
549 | { | ||
550 | switch (reg) { | ||
551 | case 0x10 ... 0x2c: | ||
552 | case 0x30 ... 0x38: | ||
553 | case 0x40 ... 0x45: | ||
554 | case 0x50 ... 0x57: | ||
555 | case 0x60 ... 0x6e: | ||
556 | case 0x70 ... 0x75: | ||
557 | case 0x80 ... 0x85: | ||
558 | case 0x90 ... 0x95: | ||
559 | case 0xa0 ... 0xa5: | ||
560 | case 0xb0 ... 0xb2: | ||
561 | return true; | ||
562 | default: | ||
563 | return false; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | static bool lm3533_volatile_register(struct device *dev, unsigned int reg) | ||
568 | { | ||
569 | switch (reg) { | ||
570 | case 0x34 ... 0x36: /* zone */ | ||
571 | case 0x37 ... 0x38: /* adc */ | ||
572 | case 0xb0 ... 0xb1: /* fault */ | ||
573 | return true; | ||
574 | default: | ||
575 | return false; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | static bool lm3533_precious_register(struct device *dev, unsigned int reg) | ||
580 | { | ||
581 | switch (reg) { | ||
582 | case 0x34: /* zone */ | ||
583 | return true; | ||
584 | default: | ||
585 | return false; | ||
586 | } | ||
587 | } | ||
588 | |||
589 | static struct regmap_config regmap_config = { | ||
590 | .reg_bits = 8, | ||
591 | .val_bits = 8, | ||
592 | .max_register = LM3533_REG_MAX, | ||
593 | .readable_reg = lm3533_readable_register, | ||
594 | .volatile_reg = lm3533_volatile_register, | ||
595 | .precious_reg = lm3533_precious_register, | ||
596 | }; | ||
597 | |||
598 | static int __devinit lm3533_i2c_probe(struct i2c_client *i2c, | ||
599 | const struct i2c_device_id *id) | ||
600 | { | ||
601 | struct lm3533 *lm3533; | ||
602 | int ret; | ||
603 | |||
604 | dev_dbg(&i2c->dev, "%s\n", __func__); | ||
605 | |||
606 | lm3533 = devm_kzalloc(&i2c->dev, sizeof(*lm3533), GFP_KERNEL); | ||
607 | if (!lm3533) | ||
608 | return -ENOMEM; | ||
609 | |||
610 | i2c_set_clientdata(i2c, lm3533); | ||
611 | |||
612 | lm3533->regmap = devm_regmap_init_i2c(i2c, ®map_config); | ||
613 | if (IS_ERR(lm3533->regmap)) | ||
614 | return PTR_ERR(lm3533->regmap); | ||
615 | |||
616 | lm3533->dev = &i2c->dev; | ||
617 | lm3533->irq = i2c->irq; | ||
618 | |||
619 | ret = lm3533_device_init(lm3533); | ||
620 | if (ret) | ||
621 | return ret; | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int __devexit lm3533_i2c_remove(struct i2c_client *i2c) | ||
627 | { | ||
628 | struct lm3533 *lm3533 = i2c_get_clientdata(i2c); | ||
629 | |||
630 | dev_dbg(&i2c->dev, "%s\n", __func__); | ||
631 | |||
632 | lm3533_device_exit(lm3533); | ||
633 | |||
634 | return 0; | ||
635 | } | ||
636 | |||
637 | static const struct i2c_device_id lm3533_i2c_ids[] = { | ||
638 | { "lm3533", 0 }, | ||
639 | { }, | ||
640 | }; | ||
641 | MODULE_DEVICE_TABLE(i2c, lm3533_i2c_ids); | ||
642 | |||
643 | static struct i2c_driver lm3533_i2c_driver = { | ||
644 | .driver = { | ||
645 | .name = "lm3533", | ||
646 | .owner = THIS_MODULE, | ||
647 | }, | ||
648 | .id_table = lm3533_i2c_ids, | ||
649 | .probe = lm3533_i2c_probe, | ||
650 | .remove = __devexit_p(lm3533_i2c_remove), | ||
651 | }; | ||
652 | |||
653 | static int __init lm3533_i2c_init(void) | ||
654 | { | ||
655 | return i2c_add_driver(&lm3533_i2c_driver); | ||
656 | } | ||
657 | subsys_initcall(lm3533_i2c_init); | ||
658 | |||
659 | static void __exit lm3533_i2c_exit(void) | ||
660 | { | ||
661 | i2c_del_driver(&lm3533_i2c_driver); | ||
662 | } | ||
663 | module_exit(lm3533_i2c_exit); | ||
664 | |||
665 | MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>"); | ||
666 | MODULE_DESCRIPTION("LM3533 Core"); | ||
667 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/lm3533-ctrlbank.c b/drivers/mfd/lm3533-ctrlbank.c new file mode 100644 index 000000000000..a4cb7a5220a7 --- /dev/null +++ b/drivers/mfd/lm3533-ctrlbank.c | |||
@@ -0,0 +1,148 @@ | |||
1 | /* | ||
2 | * lm3533-ctrlbank.c -- LM3533 Generic Control Bank interface | ||
3 | * | ||
4 | * Copyright (C) 2011-2012 Texas Instruments | ||
5 | * | ||
6 | * Author: Johan Hovold <jhovold@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/module.h> | ||
16 | |||
17 | #include <linux/mfd/lm3533.h> | ||
18 | |||
19 | |||
20 | #define LM3533_MAX_CURRENT_MIN 5000 | ||
21 | #define LM3533_MAX_CURRENT_MAX 29800 | ||
22 | #define LM3533_MAX_CURRENT_STEP 800 | ||
23 | |||
24 | #define LM3533_BRIGHTNESS_MAX 255 | ||
25 | #define LM3533_PWM_MAX 0x3f | ||
26 | |||
27 | #define LM3533_REG_PWM_BASE 0x14 | ||
28 | #define LM3533_REG_MAX_CURRENT_BASE 0x1f | ||
29 | #define LM3533_REG_CTRLBANK_ENABLE 0x27 | ||
30 | #define LM3533_REG_BRIGHTNESS_BASE 0x40 | ||
31 | |||
32 | |||
33 | static inline u8 lm3533_ctrlbank_get_reg(struct lm3533_ctrlbank *cb, u8 base) | ||
34 | { | ||
35 | return base + cb->id; | ||
36 | } | ||
37 | |||
38 | int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb) | ||
39 | { | ||
40 | u8 mask; | ||
41 | int ret; | ||
42 | |||
43 | dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id); | ||
44 | |||
45 | mask = 1 << cb->id; | ||
46 | ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, | ||
47 | mask, mask); | ||
48 | if (ret) | ||
49 | dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id); | ||
50 | |||
51 | return ret; | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_enable); | ||
54 | |||
55 | int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb) | ||
56 | { | ||
57 | u8 mask; | ||
58 | int ret; | ||
59 | |||
60 | dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id); | ||
61 | |||
62 | mask = 1 << cb->id; | ||
63 | ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask); | ||
64 | if (ret) | ||
65 | dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id); | ||
66 | |||
67 | return ret; | ||
68 | } | ||
69 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable); | ||
70 | |||
71 | /* | ||
72 | * Full-scale current. | ||
73 | * | ||
74 | * imax 5000 - 29800 uA (800 uA step) | ||
75 | */ | ||
76 | int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax) | ||
77 | { | ||
78 | u8 reg; | ||
79 | u8 val; | ||
80 | int ret; | ||
81 | |||
82 | if (imax < LM3533_MAX_CURRENT_MIN || imax > LM3533_MAX_CURRENT_MAX) | ||
83 | return -EINVAL; | ||
84 | |||
85 | val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP; | ||
86 | |||
87 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE); | ||
88 | ret = lm3533_write(cb->lm3533, reg, val); | ||
89 | if (ret) | ||
90 | dev_err(cb->dev, "failed to set max current\n"); | ||
91 | |||
92 | return ret; | ||
93 | } | ||
94 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current); | ||
95 | |||
96 | #define lm3533_ctrlbank_set(_name, _NAME) \ | ||
97 | int lm3533_ctrlbank_set_##_name(struct lm3533_ctrlbank *cb, u8 val) \ | ||
98 | { \ | ||
99 | u8 reg; \ | ||
100 | int ret; \ | ||
101 | \ | ||
102 | if (val > LM3533_##_NAME##_MAX) \ | ||
103 | return -EINVAL; \ | ||
104 | \ | ||
105 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE); \ | ||
106 | ret = lm3533_write(cb->lm3533, reg, val); \ | ||
107 | if (ret) \ | ||
108 | dev_err(cb->dev, "failed to set " #_name "\n"); \ | ||
109 | \ | ||
110 | return ret; \ | ||
111 | } \ | ||
112 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_##_name); | ||
113 | |||
114 | #define lm3533_ctrlbank_get(_name, _NAME) \ | ||
115 | int lm3533_ctrlbank_get_##_name(struct lm3533_ctrlbank *cb, u8 *val) \ | ||
116 | { \ | ||
117 | u8 reg; \ | ||
118 | int ret; \ | ||
119 | \ | ||
120 | reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE); \ | ||
121 | ret = lm3533_read(cb->lm3533, reg, val); \ | ||
122 | if (ret) \ | ||
123 | dev_err(cb->dev, "failed to get " #_name "\n"); \ | ||
124 | \ | ||
125 | return ret; \ | ||
126 | } \ | ||
127 | EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_##_name); | ||
128 | |||
129 | lm3533_ctrlbank_set(brightness, BRIGHTNESS); | ||
130 | lm3533_ctrlbank_get(brightness, BRIGHTNESS); | ||
131 | |||
132 | /* | ||
133 | * PWM-input control mask: | ||
134 | * | ||
135 | * bit 5 - PWM-input enabled in Zone 4 | ||
136 | * bit 4 - PWM-input enabled in Zone 3 | ||
137 | * bit 3 - PWM-input enabled in Zone 2 | ||
138 | * bit 2 - PWM-input enabled in Zone 1 | ||
139 | * bit 1 - PWM-input enabled in Zone 0 | ||
140 | * bit 0 - PWM-input enabled | ||
141 | */ | ||
142 | lm3533_ctrlbank_set(pwm, PWM); | ||
143 | lm3533_ctrlbank_get(pwm, PWM); | ||
144 | |||
145 | |||
146 | MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>"); | ||
147 | MODULE_DESCRIPTION("LM3533 Control Bank interface"); | ||
148 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c new file mode 100644 index 000000000000..027cc8f86132 --- /dev/null +++ b/drivers/mfd/lpc_ich.c | |||
@@ -0,0 +1,888 @@ | |||
1 | /* | ||
2 | * lpc_ich.c - LPC interface for Intel ICH | ||
3 | * | ||
4 | * LPC bridge function of the Intel ICH contains many other | ||
5 | * functional units, such as Interrupt controllers, Timers, | ||
6 | * Power Management, System Management, GPIO, RTC, and LPC | ||
7 | * Configuration Registers. | ||
8 | * | ||
9 | * This driver is derived from lpc_sch. | ||
10 | |||
11 | * Copyright (c) 2011 Extreme Engineering Solution, Inc. | ||
12 | * Author: Aaron Sierra <asierra@xes-inc.com> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License 2 as published | ||
16 | * by the Free Software Foundation. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; see the file COPYING. If not, write to | ||
25 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | * | ||
27 | * This driver supports the following I/O Controller hubs: | ||
28 | * (See the intel documentation on http://developer.intel.com.) | ||
29 | * document number 290655-003, 290677-014: 82801AA (ICH), 82801AB (ICHO) | ||
30 | * document number 290687-002, 298242-027: 82801BA (ICH2) | ||
31 | * document number 290733-003, 290739-013: 82801CA (ICH3-S) | ||
32 | * document number 290716-001, 290718-007: 82801CAM (ICH3-M) | ||
33 | * document number 290744-001, 290745-025: 82801DB (ICH4) | ||
34 | * document number 252337-001, 252663-008: 82801DBM (ICH4-M) | ||
35 | * document number 273599-001, 273645-002: 82801E (C-ICH) | ||
36 | * document number 252516-001, 252517-028: 82801EB (ICH5), 82801ER (ICH5R) | ||
37 | * document number 300641-004, 300884-013: 6300ESB | ||
38 | * document number 301473-002, 301474-026: 82801F (ICH6) | ||
39 | * document number 313082-001, 313075-006: 631xESB, 632xESB | ||
40 | * document number 307013-003, 307014-024: 82801G (ICH7) | ||
41 | * document number 322896-001, 322897-001: NM10 | ||
42 | * document number 313056-003, 313057-017: 82801H (ICH8) | ||
43 | * document number 316972-004, 316973-012: 82801I (ICH9) | ||
44 | * document number 319973-002, 319974-002: 82801J (ICH10) | ||
45 | * document number 322169-001, 322170-003: 5 Series, 3400 Series (PCH) | ||
46 | * document number 320066-003, 320257-008: EP80597 (IICH) | ||
47 | * document number 324645-001, 324646-001: Cougar Point (CPT) | ||
48 | * document number TBD : Patsburg (PBG) | ||
49 | * document number TBD : DH89xxCC | ||
50 | * document number TBD : Panther Point | ||
51 | * document number TBD : Lynx Point | ||
52 | */ | ||
53 | |||
54 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
55 | |||
56 | #include <linux/init.h> | ||
57 | #include <linux/kernel.h> | ||
58 | #include <linux/module.h> | ||
59 | #include <linux/errno.h> | ||
60 | #include <linux/acpi.h> | ||
61 | #include <linux/pci.h> | ||
62 | #include <linux/mfd/core.h> | ||
63 | #include <linux/mfd/lpc_ich.h> | ||
64 | |||
65 | #define ACPIBASE 0x40 | ||
66 | #define ACPIBASE_GPE_OFF 0x28 | ||
67 | #define ACPIBASE_GPE_END 0x2f | ||
68 | #define ACPIBASE_SMI_OFF 0x30 | ||
69 | #define ACPIBASE_SMI_END 0x33 | ||
70 | #define ACPIBASE_TCO_OFF 0x60 | ||
71 | #define ACPIBASE_TCO_END 0x7f | ||
72 | #define ACPICTRL 0x44 | ||
73 | |||
74 | #define ACPIBASE_GCS_OFF 0x3410 | ||
75 | #define ACPIBASE_GCS_END 0x3414 | ||
76 | |||
77 | #define GPIOBASE 0x48 | ||
78 | #define GPIOCTRL 0x4C | ||
79 | |||
80 | #define RCBABASE 0xf0 | ||
81 | |||
82 | #define wdt_io_res(i) wdt_res(0, i) | ||
83 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) | ||
84 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) | ||
85 | |||
86 | static int lpc_ich_acpi_save = -1; | ||
87 | static int lpc_ich_gpio_save = -1; | ||
88 | |||
89 | static struct resource wdt_ich_res[] = { | ||
90 | /* ACPI - TCO */ | ||
91 | { | ||
92 | .flags = IORESOURCE_IO, | ||
93 | }, | ||
94 | /* ACPI - SMI */ | ||
95 | { | ||
96 | .flags = IORESOURCE_IO, | ||
97 | }, | ||
98 | /* GCS */ | ||
99 | { | ||
100 | .flags = IORESOURCE_MEM, | ||
101 | }, | ||
102 | }; | ||
103 | |||
104 | static struct resource gpio_ich_res[] = { | ||
105 | /* GPIO */ | ||
106 | { | ||
107 | .flags = IORESOURCE_IO, | ||
108 | }, | ||
109 | /* ACPI - GPE0 */ | ||
110 | { | ||
111 | .flags = IORESOURCE_IO, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | enum lpc_cells { | ||
116 | LPC_WDT = 0, | ||
117 | LPC_GPIO, | ||
118 | }; | ||
119 | |||
120 | static struct mfd_cell lpc_ich_cells[] = { | ||
121 | [LPC_WDT] = { | ||
122 | .name = "iTCO_wdt", | ||
123 | .num_resources = ARRAY_SIZE(wdt_ich_res), | ||
124 | .resources = wdt_ich_res, | ||
125 | .ignore_resource_conflicts = true, | ||
126 | }, | ||
127 | [LPC_GPIO] = { | ||
128 | .name = "gpio_ich", | ||
129 | .num_resources = ARRAY_SIZE(gpio_ich_res), | ||
130 | .resources = gpio_ich_res, | ||
131 | .ignore_resource_conflicts = true, | ||
132 | }, | ||
133 | }; | ||
134 | |||
135 | /* chipset related info */ | ||
136 | enum lpc_chipsets { | ||
137 | LPC_ICH = 0, /* ICH */ | ||
138 | LPC_ICH0, /* ICH0 */ | ||
139 | LPC_ICH2, /* ICH2 */ | ||
140 | LPC_ICH2M, /* ICH2-M */ | ||
141 | LPC_ICH3, /* ICH3-S */ | ||
142 | LPC_ICH3M, /* ICH3-M */ | ||
143 | LPC_ICH4, /* ICH4 */ | ||
144 | LPC_ICH4M, /* ICH4-M */ | ||
145 | LPC_CICH, /* C-ICH */ | ||
146 | LPC_ICH5, /* ICH5 & ICH5R */ | ||
147 | LPC_6300ESB, /* 6300ESB */ | ||
148 | LPC_ICH6, /* ICH6 & ICH6R */ | ||
149 | LPC_ICH6M, /* ICH6-M */ | ||
150 | LPC_ICH6W, /* ICH6W & ICH6RW */ | ||
151 | LPC_631XESB, /* 631xESB/632xESB */ | ||
152 | LPC_ICH7, /* ICH7 & ICH7R */ | ||
153 | LPC_ICH7DH, /* ICH7DH */ | ||
154 | LPC_ICH7M, /* ICH7-M & ICH7-U */ | ||
155 | LPC_ICH7MDH, /* ICH7-M DH */ | ||
156 | LPC_NM10, /* NM10 */ | ||
157 | LPC_ICH8, /* ICH8 & ICH8R */ | ||
158 | LPC_ICH8DH, /* ICH8DH */ | ||
159 | LPC_ICH8DO, /* ICH8DO */ | ||
160 | LPC_ICH8M, /* ICH8M */ | ||
161 | LPC_ICH8ME, /* ICH8M-E */ | ||
162 | LPC_ICH9, /* ICH9 */ | ||
163 | LPC_ICH9R, /* ICH9R */ | ||
164 | LPC_ICH9DH, /* ICH9DH */ | ||
165 | LPC_ICH9DO, /* ICH9DO */ | ||
166 | LPC_ICH9M, /* ICH9M */ | ||
167 | LPC_ICH9ME, /* ICH9M-E */ | ||
168 | LPC_ICH10, /* ICH10 */ | ||
169 | LPC_ICH10R, /* ICH10R */ | ||
170 | LPC_ICH10D, /* ICH10D */ | ||
171 | LPC_ICH10DO, /* ICH10DO */ | ||
172 | LPC_PCH, /* PCH Desktop Full Featured */ | ||
173 | LPC_PCHM, /* PCH Mobile Full Featured */ | ||
174 | LPC_P55, /* P55 */ | ||
175 | LPC_PM55, /* PM55 */ | ||
176 | LPC_H55, /* H55 */ | ||
177 | LPC_QM57, /* QM57 */ | ||
178 | LPC_H57, /* H57 */ | ||
179 | LPC_HM55, /* HM55 */ | ||
180 | LPC_Q57, /* Q57 */ | ||
181 | LPC_HM57, /* HM57 */ | ||
182 | LPC_PCHMSFF, /* PCH Mobile SFF Full Featured */ | ||
183 | LPC_QS57, /* QS57 */ | ||
184 | LPC_3400, /* 3400 */ | ||
185 | LPC_3420, /* 3420 */ | ||
186 | LPC_3450, /* 3450 */ | ||
187 | LPC_EP80579, /* EP80579 */ | ||
188 | LPC_CPT, /* Cougar Point */ | ||
189 | LPC_CPTD, /* Cougar Point Desktop */ | ||
190 | LPC_CPTM, /* Cougar Point Mobile */ | ||
191 | LPC_PBG, /* Patsburg */ | ||
192 | LPC_DH89XXCC, /* DH89xxCC */ | ||
193 | LPC_PPT, /* Panther Point */ | ||
194 | LPC_LPT, /* Lynx Point */ | ||
195 | }; | ||
196 | |||
197 | struct lpc_ich_info lpc_chipset_info[] __devinitdata = { | ||
198 | [LPC_ICH] = { | ||
199 | .name = "ICH", | ||
200 | .iTCO_version = 1, | ||
201 | }, | ||
202 | [LPC_ICH0] = { | ||
203 | .name = "ICH0", | ||
204 | .iTCO_version = 1, | ||
205 | }, | ||
206 | [LPC_ICH2] = { | ||
207 | .name = "ICH2", | ||
208 | .iTCO_version = 1, | ||
209 | }, | ||
210 | [LPC_ICH2M] = { | ||
211 | .name = "ICH2-M", | ||
212 | .iTCO_version = 1, | ||
213 | }, | ||
214 | [LPC_ICH3] = { | ||
215 | .name = "ICH3-S", | ||
216 | .iTCO_version = 1, | ||
217 | }, | ||
218 | [LPC_ICH3M] = { | ||
219 | .name = "ICH3-M", | ||
220 | .iTCO_version = 1, | ||
221 | }, | ||
222 | [LPC_ICH4] = { | ||
223 | .name = "ICH4", | ||
224 | .iTCO_version = 1, | ||
225 | }, | ||
226 | [LPC_ICH4M] = { | ||
227 | .name = "ICH4-M", | ||
228 | .iTCO_version = 1, | ||
229 | }, | ||
230 | [LPC_CICH] = { | ||
231 | .name = "C-ICH", | ||
232 | .iTCO_version = 1, | ||
233 | }, | ||
234 | [LPC_ICH5] = { | ||
235 | .name = "ICH5 or ICH5R", | ||
236 | .iTCO_version = 1, | ||
237 | }, | ||
238 | [LPC_6300ESB] = { | ||
239 | .name = "6300ESB", | ||
240 | .iTCO_version = 1, | ||
241 | }, | ||
242 | [LPC_ICH6] = { | ||
243 | .name = "ICH6 or ICH6R", | ||
244 | .iTCO_version = 2, | ||
245 | .gpio_version = ICH_V6_GPIO, | ||
246 | }, | ||
247 | [LPC_ICH6M] = { | ||
248 | .name = "ICH6-M", | ||
249 | .iTCO_version = 2, | ||
250 | .gpio_version = ICH_V6_GPIO, | ||
251 | }, | ||
252 | [LPC_ICH6W] = { | ||
253 | .name = "ICH6W or ICH6RW", | ||
254 | .iTCO_version = 2, | ||
255 | .gpio_version = ICH_V6_GPIO, | ||
256 | }, | ||
257 | [LPC_631XESB] = { | ||
258 | .name = "631xESB/632xESB", | ||
259 | .iTCO_version = 2, | ||
260 | .gpio_version = ICH_V6_GPIO, | ||
261 | }, | ||
262 | [LPC_ICH7] = { | ||
263 | .name = "ICH7 or ICH7R", | ||
264 | .iTCO_version = 2, | ||
265 | .gpio_version = ICH_V7_GPIO, | ||
266 | }, | ||
267 | [LPC_ICH7DH] = { | ||
268 | .name = "ICH7DH", | ||
269 | .iTCO_version = 2, | ||
270 | .gpio_version = ICH_V7_GPIO, | ||
271 | }, | ||
272 | [LPC_ICH7M] = { | ||
273 | .name = "ICH7-M or ICH7-U", | ||
274 | .iTCO_version = 2, | ||
275 | .gpio_version = ICH_V7_GPIO, | ||
276 | }, | ||
277 | [LPC_ICH7MDH] = { | ||
278 | .name = "ICH7-M DH", | ||
279 | .iTCO_version = 2, | ||
280 | .gpio_version = ICH_V7_GPIO, | ||
281 | }, | ||
282 | [LPC_NM10] = { | ||
283 | .name = "NM10", | ||
284 | .iTCO_version = 2, | ||
285 | }, | ||
286 | [LPC_ICH8] = { | ||
287 | .name = "ICH8 or ICH8R", | ||
288 | .iTCO_version = 2, | ||
289 | .gpio_version = ICH_V7_GPIO, | ||
290 | }, | ||
291 | [LPC_ICH8DH] = { | ||
292 | .name = "ICH8DH", | ||
293 | .iTCO_version = 2, | ||
294 | .gpio_version = ICH_V7_GPIO, | ||
295 | }, | ||
296 | [LPC_ICH8DO] = { | ||
297 | .name = "ICH8DO", | ||
298 | .iTCO_version = 2, | ||
299 | .gpio_version = ICH_V7_GPIO, | ||
300 | }, | ||
301 | [LPC_ICH8M] = { | ||
302 | .name = "ICH8M", | ||
303 | .iTCO_version = 2, | ||
304 | .gpio_version = ICH_V7_GPIO, | ||
305 | }, | ||
306 | [LPC_ICH8ME] = { | ||
307 | .name = "ICH8M-E", | ||
308 | .iTCO_version = 2, | ||
309 | .gpio_version = ICH_V7_GPIO, | ||
310 | }, | ||
311 | [LPC_ICH9] = { | ||
312 | .name = "ICH9", | ||
313 | .iTCO_version = 2, | ||
314 | .gpio_version = ICH_V9_GPIO, | ||
315 | }, | ||
316 | [LPC_ICH9R] = { | ||
317 | .name = "ICH9R", | ||
318 | .iTCO_version = 2, | ||
319 | .gpio_version = ICH_V9_GPIO, | ||
320 | }, | ||
321 | [LPC_ICH9DH] = { | ||
322 | .name = "ICH9DH", | ||
323 | .iTCO_version = 2, | ||
324 | .gpio_version = ICH_V9_GPIO, | ||
325 | }, | ||
326 | [LPC_ICH9DO] = { | ||
327 | .name = "ICH9DO", | ||
328 | .iTCO_version = 2, | ||
329 | .gpio_version = ICH_V9_GPIO, | ||
330 | }, | ||
331 | [LPC_ICH9M] = { | ||
332 | .name = "ICH9M", | ||
333 | .iTCO_version = 2, | ||
334 | .gpio_version = ICH_V9_GPIO, | ||
335 | }, | ||
336 | [LPC_ICH9ME] = { | ||
337 | .name = "ICH9M-E", | ||
338 | .iTCO_version = 2, | ||
339 | .gpio_version = ICH_V9_GPIO, | ||
340 | }, | ||
341 | [LPC_ICH10] = { | ||
342 | .name = "ICH10", | ||
343 | .iTCO_version = 2, | ||
344 | .gpio_version = ICH_V10CONS_GPIO, | ||
345 | }, | ||
346 | [LPC_ICH10R] = { | ||
347 | .name = "ICH10R", | ||
348 | .iTCO_version = 2, | ||
349 | .gpio_version = ICH_V10CONS_GPIO, | ||
350 | }, | ||
351 | [LPC_ICH10D] = { | ||
352 | .name = "ICH10D", | ||
353 | .iTCO_version = 2, | ||
354 | .gpio_version = ICH_V10CORP_GPIO, | ||
355 | }, | ||
356 | [LPC_ICH10DO] = { | ||
357 | .name = "ICH10DO", | ||
358 | .iTCO_version = 2, | ||
359 | .gpio_version = ICH_V10CORP_GPIO, | ||
360 | }, | ||
361 | [LPC_PCH] = { | ||
362 | .name = "PCH Desktop Full Featured", | ||
363 | .iTCO_version = 2, | ||
364 | .gpio_version = ICH_V5_GPIO, | ||
365 | }, | ||
366 | [LPC_PCHM] = { | ||
367 | .name = "PCH Mobile Full Featured", | ||
368 | .iTCO_version = 2, | ||
369 | .gpio_version = ICH_V5_GPIO, | ||
370 | }, | ||
371 | [LPC_P55] = { | ||
372 | .name = "P55", | ||
373 | .iTCO_version = 2, | ||
374 | .gpio_version = ICH_V5_GPIO, | ||
375 | }, | ||
376 | [LPC_PM55] = { | ||
377 | .name = "PM55", | ||
378 | .iTCO_version = 2, | ||
379 | .gpio_version = ICH_V5_GPIO, | ||
380 | }, | ||
381 | [LPC_H55] = { | ||
382 | .name = "H55", | ||
383 | .iTCO_version = 2, | ||
384 | .gpio_version = ICH_V5_GPIO, | ||
385 | }, | ||
386 | [LPC_QM57] = { | ||
387 | .name = "QM57", | ||
388 | .iTCO_version = 2, | ||
389 | .gpio_version = ICH_V5_GPIO, | ||
390 | }, | ||
391 | [LPC_H57] = { | ||
392 | .name = "H57", | ||
393 | .iTCO_version = 2, | ||
394 | .gpio_version = ICH_V5_GPIO, | ||
395 | }, | ||
396 | [LPC_HM55] = { | ||
397 | .name = "HM55", | ||
398 | .iTCO_version = 2, | ||
399 | .gpio_version = ICH_V5_GPIO, | ||
400 | }, | ||
401 | [LPC_Q57] = { | ||
402 | .name = "Q57", | ||
403 | .iTCO_version = 2, | ||
404 | .gpio_version = ICH_V5_GPIO, | ||
405 | }, | ||
406 | [LPC_HM57] = { | ||
407 | .name = "HM57", | ||
408 | .iTCO_version = 2, | ||
409 | .gpio_version = ICH_V5_GPIO, | ||
410 | }, | ||
411 | [LPC_PCHMSFF] = { | ||
412 | .name = "PCH Mobile SFF Full Featured", | ||
413 | .iTCO_version = 2, | ||
414 | .gpio_version = ICH_V5_GPIO, | ||
415 | }, | ||
416 | [LPC_QS57] = { | ||
417 | .name = "QS57", | ||
418 | .iTCO_version = 2, | ||
419 | .gpio_version = ICH_V5_GPIO, | ||
420 | }, | ||
421 | [LPC_3400] = { | ||
422 | .name = "3400", | ||
423 | .iTCO_version = 2, | ||
424 | .gpio_version = ICH_V5_GPIO, | ||
425 | }, | ||
426 | [LPC_3420] = { | ||
427 | .name = "3420", | ||
428 | .iTCO_version = 2, | ||
429 | .gpio_version = ICH_V5_GPIO, | ||
430 | }, | ||
431 | [LPC_3450] = { | ||
432 | .name = "3450", | ||
433 | .iTCO_version = 2, | ||
434 | .gpio_version = ICH_V5_GPIO, | ||
435 | }, | ||
436 | [LPC_EP80579] = { | ||
437 | .name = "EP80579", | ||
438 | .iTCO_version = 2, | ||
439 | }, | ||
440 | [LPC_CPT] = { | ||
441 | .name = "Cougar Point", | ||
442 | .iTCO_version = 2, | ||
443 | .gpio_version = ICH_V5_GPIO, | ||
444 | }, | ||
445 | [LPC_CPTD] = { | ||
446 | .name = "Cougar Point Desktop", | ||
447 | .iTCO_version = 2, | ||
448 | .gpio_version = ICH_V5_GPIO, | ||
449 | }, | ||
450 | [LPC_CPTM] = { | ||
451 | .name = "Cougar Point Mobile", | ||
452 | .iTCO_version = 2, | ||
453 | .gpio_version = ICH_V5_GPIO, | ||
454 | }, | ||
455 | [LPC_PBG] = { | ||
456 | .name = "Patsburg", | ||
457 | .iTCO_version = 2, | ||
458 | }, | ||
459 | [LPC_DH89XXCC] = { | ||
460 | .name = "DH89xxCC", | ||
461 | .iTCO_version = 2, | ||
462 | }, | ||
463 | [LPC_PPT] = { | ||
464 | .name = "Panther Point", | ||
465 | .iTCO_version = 2, | ||
466 | }, | ||
467 | [LPC_LPT] = { | ||
468 | .name = "Lynx Point", | ||
469 | .iTCO_version = 2, | ||
470 | }, | ||
471 | }; | ||
472 | |||
473 | /* | ||
474 | * This data only exists for exporting the supported PCI ids | ||
475 | * via MODULE_DEVICE_TABLE. We do not actually register a | ||
476 | * pci_driver, because the I/O Controller Hub has also other | ||
477 | * functions that probably will be registered by other drivers. | ||
478 | */ | ||
479 | static DEFINE_PCI_DEVICE_TABLE(lpc_ich_ids) = { | ||
480 | { PCI_VDEVICE(INTEL, 0x2410), LPC_ICH}, | ||
481 | { PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0}, | ||
482 | { PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2}, | ||
483 | { PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M}, | ||
484 | { PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3}, | ||
485 | { PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M}, | ||
486 | { PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4}, | ||
487 | { PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M}, | ||
488 | { PCI_VDEVICE(INTEL, 0x2450), LPC_CICH}, | ||
489 | { PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5}, | ||
490 | { PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB}, | ||
491 | { PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6}, | ||
492 | { PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M}, | ||
493 | { PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W}, | ||
494 | { PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB}, | ||
495 | { PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB}, | ||
496 | { PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB}, | ||
497 | { PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB}, | ||
498 | { PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB}, | ||
499 | { PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB}, | ||
500 | { PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB}, | ||
501 | { PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB}, | ||
502 | { PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB}, | ||
503 | { PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB}, | ||
504 | { PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB}, | ||
505 | { PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB}, | ||
506 | { PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB}, | ||
507 | { PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB}, | ||
508 | { PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB}, | ||
509 | { PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB}, | ||
510 | { PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7}, | ||
511 | { PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH}, | ||
512 | { PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M}, | ||
513 | { PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH}, | ||
514 | { PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10}, | ||
515 | { PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8}, | ||
516 | { PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH}, | ||
517 | { PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO}, | ||
518 | { PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M}, | ||
519 | { PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME}, | ||
520 | { PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9}, | ||
521 | { PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R}, | ||
522 | { PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH}, | ||
523 | { PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO}, | ||
524 | { PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M}, | ||
525 | { PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME}, | ||
526 | { PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10}, | ||
527 | { PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R}, | ||
528 | { PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D}, | ||
529 | { PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO}, | ||
530 | { PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH}, | ||
531 | { PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM}, | ||
532 | { PCI_VDEVICE(INTEL, 0x3b02), LPC_P55}, | ||
533 | { PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55}, | ||
534 | { PCI_VDEVICE(INTEL, 0x3b06), LPC_H55}, | ||
535 | { PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57}, | ||
536 | { PCI_VDEVICE(INTEL, 0x3b08), LPC_H57}, | ||
537 | { PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55}, | ||
538 | { PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57}, | ||
539 | { PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57}, | ||
540 | { PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF}, | ||
541 | { PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57}, | ||
542 | { PCI_VDEVICE(INTEL, 0x3b12), LPC_3400}, | ||
543 | { PCI_VDEVICE(INTEL, 0x3b14), LPC_3420}, | ||
544 | { PCI_VDEVICE(INTEL, 0x3b16), LPC_3450}, | ||
545 | { PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579}, | ||
546 | { PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT}, | ||
547 | { PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD}, | ||
548 | { PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM}, | ||
549 | { PCI_VDEVICE(INTEL, 0x1c44), LPC_CPT}, | ||
550 | { PCI_VDEVICE(INTEL, 0x1c45), LPC_CPT}, | ||
551 | { PCI_VDEVICE(INTEL, 0x1c46), LPC_CPT}, | ||
552 | { PCI_VDEVICE(INTEL, 0x1c47), LPC_CPT}, | ||
553 | { PCI_VDEVICE(INTEL, 0x1c48), LPC_CPT}, | ||
554 | { PCI_VDEVICE(INTEL, 0x1c49), LPC_CPT}, | ||
555 | { PCI_VDEVICE(INTEL, 0x1c4a), LPC_CPT}, | ||
556 | { PCI_VDEVICE(INTEL, 0x1c4b), LPC_CPT}, | ||
557 | { PCI_VDEVICE(INTEL, 0x1c4c), LPC_CPT}, | ||
558 | { PCI_VDEVICE(INTEL, 0x1c4d), LPC_CPT}, | ||
559 | { PCI_VDEVICE(INTEL, 0x1c4e), LPC_CPT}, | ||
560 | { PCI_VDEVICE(INTEL, 0x1c4f), LPC_CPT}, | ||
561 | { PCI_VDEVICE(INTEL, 0x1c50), LPC_CPT}, | ||
562 | { PCI_VDEVICE(INTEL, 0x1c51), LPC_CPT}, | ||
563 | { PCI_VDEVICE(INTEL, 0x1c52), LPC_CPT}, | ||
564 | { PCI_VDEVICE(INTEL, 0x1c53), LPC_CPT}, | ||
565 | { PCI_VDEVICE(INTEL, 0x1c54), LPC_CPT}, | ||
566 | { PCI_VDEVICE(INTEL, 0x1c55), LPC_CPT}, | ||
567 | { PCI_VDEVICE(INTEL, 0x1c56), LPC_CPT}, | ||
568 | { PCI_VDEVICE(INTEL, 0x1c57), LPC_CPT}, | ||
569 | { PCI_VDEVICE(INTEL, 0x1c58), LPC_CPT}, | ||
570 | { PCI_VDEVICE(INTEL, 0x1c59), LPC_CPT}, | ||
571 | { PCI_VDEVICE(INTEL, 0x1c5a), LPC_CPT}, | ||
572 | { PCI_VDEVICE(INTEL, 0x1c5b), LPC_CPT}, | ||
573 | { PCI_VDEVICE(INTEL, 0x1c5c), LPC_CPT}, | ||
574 | { PCI_VDEVICE(INTEL, 0x1c5d), LPC_CPT}, | ||
575 | { PCI_VDEVICE(INTEL, 0x1c5e), LPC_CPT}, | ||
576 | { PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT}, | ||
577 | { PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG}, | ||
578 | { PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG}, | ||
579 | { PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC}, | ||
580 | { PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT}, | ||
581 | { PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT}, | ||
582 | { PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT}, | ||
583 | { PCI_VDEVICE(INTEL, 0x1e43), LPC_PPT}, | ||
584 | { PCI_VDEVICE(INTEL, 0x1e44), LPC_PPT}, | ||
585 | { PCI_VDEVICE(INTEL, 0x1e45), LPC_PPT}, | ||
586 | { PCI_VDEVICE(INTEL, 0x1e46), LPC_PPT}, | ||
587 | { PCI_VDEVICE(INTEL, 0x1e47), LPC_PPT}, | ||
588 | { PCI_VDEVICE(INTEL, 0x1e48), LPC_PPT}, | ||
589 | { PCI_VDEVICE(INTEL, 0x1e49), LPC_PPT}, | ||
590 | { PCI_VDEVICE(INTEL, 0x1e4a), LPC_PPT}, | ||
591 | { PCI_VDEVICE(INTEL, 0x1e4b), LPC_PPT}, | ||
592 | { PCI_VDEVICE(INTEL, 0x1e4c), LPC_PPT}, | ||
593 | { PCI_VDEVICE(INTEL, 0x1e4d), LPC_PPT}, | ||
594 | { PCI_VDEVICE(INTEL, 0x1e4e), LPC_PPT}, | ||
595 | { PCI_VDEVICE(INTEL, 0x1e4f), LPC_PPT}, | ||
596 | { PCI_VDEVICE(INTEL, 0x1e50), LPC_PPT}, | ||
597 | { PCI_VDEVICE(INTEL, 0x1e51), LPC_PPT}, | ||
598 | { PCI_VDEVICE(INTEL, 0x1e52), LPC_PPT}, | ||
599 | { PCI_VDEVICE(INTEL, 0x1e53), LPC_PPT}, | ||
600 | { PCI_VDEVICE(INTEL, 0x1e54), LPC_PPT}, | ||
601 | { PCI_VDEVICE(INTEL, 0x1e55), LPC_PPT}, | ||
602 | { PCI_VDEVICE(INTEL, 0x1e56), LPC_PPT}, | ||
603 | { PCI_VDEVICE(INTEL, 0x1e57), LPC_PPT}, | ||
604 | { PCI_VDEVICE(INTEL, 0x1e58), LPC_PPT}, | ||
605 | { PCI_VDEVICE(INTEL, 0x1e59), LPC_PPT}, | ||
606 | { PCI_VDEVICE(INTEL, 0x1e5a), LPC_PPT}, | ||
607 | { PCI_VDEVICE(INTEL, 0x1e5b), LPC_PPT}, | ||
608 | { PCI_VDEVICE(INTEL, 0x1e5c), LPC_PPT}, | ||
609 | { PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT}, | ||
610 | { PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT}, | ||
611 | { PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT}, | ||
612 | { PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT}, | ||
613 | { PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT}, | ||
614 | { PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT}, | ||
615 | { PCI_VDEVICE(INTEL, 0x8c43), LPC_LPT}, | ||
616 | { PCI_VDEVICE(INTEL, 0x8c44), LPC_LPT}, | ||
617 | { PCI_VDEVICE(INTEL, 0x8c45), LPC_LPT}, | ||
618 | { PCI_VDEVICE(INTEL, 0x8c46), LPC_LPT}, | ||
619 | { PCI_VDEVICE(INTEL, 0x8c47), LPC_LPT}, | ||
620 | { PCI_VDEVICE(INTEL, 0x8c48), LPC_LPT}, | ||
621 | { PCI_VDEVICE(INTEL, 0x8c49), LPC_LPT}, | ||
622 | { PCI_VDEVICE(INTEL, 0x8c4a), LPC_LPT}, | ||
623 | { PCI_VDEVICE(INTEL, 0x8c4b), LPC_LPT}, | ||
624 | { PCI_VDEVICE(INTEL, 0x8c4c), LPC_LPT}, | ||
625 | { PCI_VDEVICE(INTEL, 0x8c4d), LPC_LPT}, | ||
626 | { PCI_VDEVICE(INTEL, 0x8c4e), LPC_LPT}, | ||
627 | { PCI_VDEVICE(INTEL, 0x8c4f), LPC_LPT}, | ||
628 | { PCI_VDEVICE(INTEL, 0x8c50), LPC_LPT}, | ||
629 | { PCI_VDEVICE(INTEL, 0x8c51), LPC_LPT}, | ||
630 | { PCI_VDEVICE(INTEL, 0x8c52), LPC_LPT}, | ||
631 | { PCI_VDEVICE(INTEL, 0x8c53), LPC_LPT}, | ||
632 | { PCI_VDEVICE(INTEL, 0x8c54), LPC_LPT}, | ||
633 | { PCI_VDEVICE(INTEL, 0x8c55), LPC_LPT}, | ||
634 | { PCI_VDEVICE(INTEL, 0x8c56), LPC_LPT}, | ||
635 | { PCI_VDEVICE(INTEL, 0x8c57), LPC_LPT}, | ||
636 | { PCI_VDEVICE(INTEL, 0x8c58), LPC_LPT}, | ||
637 | { PCI_VDEVICE(INTEL, 0x8c59), LPC_LPT}, | ||
638 | { PCI_VDEVICE(INTEL, 0x8c5a), LPC_LPT}, | ||
639 | { PCI_VDEVICE(INTEL, 0x8c5b), LPC_LPT}, | ||
640 | { PCI_VDEVICE(INTEL, 0x8c5c), LPC_LPT}, | ||
641 | { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, | ||
642 | { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, | ||
643 | { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, | ||
644 | { 0, }, /* End of list */ | ||
645 | }; | ||
646 | MODULE_DEVICE_TABLE(pci, lpc_ich_ids); | ||
647 | |||
648 | static void lpc_ich_restore_config_space(struct pci_dev *dev) | ||
649 | { | ||
650 | if (lpc_ich_acpi_save >= 0) { | ||
651 | pci_write_config_byte(dev, ACPICTRL, lpc_ich_acpi_save); | ||
652 | lpc_ich_acpi_save = -1; | ||
653 | } | ||
654 | |||
655 | if (lpc_ich_gpio_save >= 0) { | ||
656 | pci_write_config_byte(dev, GPIOCTRL, lpc_ich_gpio_save); | ||
657 | lpc_ich_gpio_save = -1; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | static void __devinit lpc_ich_enable_acpi_space(struct pci_dev *dev) | ||
662 | { | ||
663 | u8 reg_save; | ||
664 | |||
665 | pci_read_config_byte(dev, ACPICTRL, ®_save); | ||
666 | pci_write_config_byte(dev, ACPICTRL, reg_save | 0x10); | ||
667 | lpc_ich_acpi_save = reg_save; | ||
668 | } | ||
669 | |||
670 | static void __devinit lpc_ich_enable_gpio_space(struct pci_dev *dev) | ||
671 | { | ||
672 | u8 reg_save; | ||
673 | |||
674 | pci_read_config_byte(dev, GPIOCTRL, ®_save); | ||
675 | pci_write_config_byte(dev, GPIOCTRL, reg_save | 0x10); | ||
676 | lpc_ich_gpio_save = reg_save; | ||
677 | } | ||
678 | |||
679 | static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell, | ||
680 | const struct pci_device_id *id) | ||
681 | { | ||
682 | cell->platform_data = &lpc_chipset_info[id->driver_data]; | ||
683 | cell->pdata_size = sizeof(struct lpc_ich_info); | ||
684 | } | ||
685 | |||
686 | static int __devinit lpc_ich_init_gpio(struct pci_dev *dev, | ||
687 | const struct pci_device_id *id) | ||
688 | { | ||
689 | u32 base_addr_cfg; | ||
690 | u32 base_addr; | ||
691 | int ret; | ||
692 | bool acpi_conflict = false; | ||
693 | struct resource *res; | ||
694 | |||
695 | /* Setup power management base register */ | ||
696 | pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg); | ||
697 | base_addr = base_addr_cfg & 0x0000ff80; | ||
698 | if (!base_addr) { | ||
699 | dev_err(&dev->dev, "I/O space for ACPI uninitialized\n"); | ||
700 | lpc_ich_cells[LPC_GPIO].num_resources--; | ||
701 | goto gpe0_done; | ||
702 | } | ||
703 | |||
704 | res = &gpio_ich_res[ICH_RES_GPE0]; | ||
705 | res->start = base_addr + ACPIBASE_GPE_OFF; | ||
706 | res->end = base_addr + ACPIBASE_GPE_END; | ||
707 | ret = acpi_check_resource_conflict(res); | ||
708 | if (ret) { | ||
709 | /* | ||
710 | * This isn't fatal for the GPIO, but we have to make sure that | ||
711 | * the platform_device subsystem doesn't see this resource | ||
712 | * or it will register an invalid region. | ||
713 | */ | ||
714 | lpc_ich_cells[LPC_GPIO].num_resources--; | ||
715 | acpi_conflict = true; | ||
716 | } else { | ||
717 | lpc_ich_enable_acpi_space(dev); | ||
718 | } | ||
719 | |||
720 | gpe0_done: | ||
721 | /* Setup GPIO base register */ | ||
722 | pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); | ||
723 | base_addr = base_addr_cfg & 0x0000ff80; | ||
724 | if (!base_addr) { | ||
725 | dev_err(&dev->dev, "I/O space for GPIO uninitialized\n"); | ||
726 | ret = -ENODEV; | ||
727 | goto gpio_done; | ||
728 | } | ||
729 | |||
730 | /* Older devices provide fewer GPIO and have a smaller resource size. */ | ||
731 | res = &gpio_ich_res[ICH_RES_GPIO]; | ||
732 | res->start = base_addr; | ||
733 | switch (lpc_chipset_info[id->driver_data].gpio_version) { | ||
734 | case ICH_V5_GPIO: | ||
735 | case ICH_V10CORP_GPIO: | ||
736 | res->end = res->start + 128 - 1; | ||
737 | break; | ||
738 | default: | ||
739 | res->end = res->start + 64 - 1; | ||
740 | break; | ||
741 | } | ||
742 | |||
743 | ret = acpi_check_resource_conflict(res); | ||
744 | if (ret) { | ||
745 | /* this isn't necessarily fatal for the GPIO */ | ||
746 | acpi_conflict = true; | ||
747 | goto gpio_done; | ||
748 | } | ||
749 | lpc_ich_enable_gpio_space(dev); | ||
750 | |||
751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); | ||
752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], | ||
753 | 1, NULL, 0); | ||
754 | |||
755 | gpio_done: | ||
756 | if (acpi_conflict) | ||
757 | pr_warn("Resource conflict(s) found affecting %s\n", | ||
758 | lpc_ich_cells[LPC_GPIO].name); | ||
759 | return ret; | ||
760 | } | ||
761 | |||
762 | static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | ||
763 | const struct pci_device_id *id) | ||
764 | { | ||
765 | u32 base_addr_cfg; | ||
766 | u32 base_addr; | ||
767 | int ret; | ||
768 | bool acpi_conflict = false; | ||
769 | struct resource *res; | ||
770 | |||
771 | /* Setup power management base register */ | ||
772 | pci_read_config_dword(dev, ACPIBASE, &base_addr_cfg); | ||
773 | base_addr = base_addr_cfg & 0x0000ff80; | ||
774 | if (!base_addr) { | ||
775 | dev_err(&dev->dev, "I/O space for ACPI uninitialized\n"); | ||
776 | ret = -ENODEV; | ||
777 | goto wdt_done; | ||
778 | } | ||
779 | |||
780 | res = wdt_io_res(ICH_RES_IO_TCO); | ||
781 | res->start = base_addr + ACPIBASE_TCO_OFF; | ||
782 | res->end = base_addr + ACPIBASE_TCO_END; | ||
783 | ret = acpi_check_resource_conflict(res); | ||
784 | if (ret) { | ||
785 | acpi_conflict = true; | ||
786 | goto wdt_done; | ||
787 | } | ||
788 | |||
789 | res = wdt_io_res(ICH_RES_IO_SMI); | ||
790 | res->start = base_addr + ACPIBASE_SMI_OFF; | ||
791 | res->end = base_addr + ACPIBASE_SMI_END; | ||
792 | ret = acpi_check_resource_conflict(res); | ||
793 | if (ret) { | ||
794 | acpi_conflict = true; | ||
795 | goto wdt_done; | ||
796 | } | ||
797 | lpc_ich_enable_acpi_space(dev); | ||
798 | |||
799 | /* | ||
800 | * Get the Memory-Mapped GCS register. To get access to it | ||
801 | * we have to read RCBA from PCI Config space 0xf0 and use | ||
802 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). | ||
803 | */ | ||
804 | if (lpc_chipset_info[id->driver_data].iTCO_version == 2) { | ||
805 | pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); | ||
806 | base_addr = base_addr_cfg & 0xffffc000; | ||
807 | if (!(base_addr_cfg & 1)) { | ||
808 | pr_err("RCBA is disabled by hardware/BIOS, " | ||
809 | "device disabled\n"); | ||
810 | ret = -ENODEV; | ||
811 | goto wdt_done; | ||
812 | } | ||
813 | res = wdt_mem_res(ICH_RES_MEM_GCS); | ||
814 | res->start = base_addr + ACPIBASE_GCS_OFF; | ||
815 | res->end = base_addr + ACPIBASE_GCS_END; | ||
816 | ret = acpi_check_resource_conflict(res); | ||
817 | if (ret) { | ||
818 | acpi_conflict = true; | ||
819 | goto wdt_done; | ||
820 | } | ||
821 | } | ||
822 | |||
823 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); | ||
824 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], | ||
825 | 1, NULL, 0); | ||
826 | |||
827 | wdt_done: | ||
828 | if (acpi_conflict) | ||
829 | pr_warn("Resource conflict(s) found affecting %s\n", | ||
830 | lpc_ich_cells[LPC_WDT].name); | ||
831 | return ret; | ||
832 | } | ||
833 | |||
834 | static int __devinit lpc_ich_probe(struct pci_dev *dev, | ||
835 | const struct pci_device_id *id) | ||
836 | { | ||
837 | int ret; | ||
838 | bool cell_added = false; | ||
839 | |||
840 | ret = lpc_ich_init_wdt(dev, id); | ||
841 | if (!ret) | ||
842 | cell_added = true; | ||
843 | |||
844 | ret = lpc_ich_init_gpio(dev, id); | ||
845 | if (!ret) | ||
846 | cell_added = true; | ||
847 | |||
848 | /* | ||
849 | * We only care if at least one or none of the cells registered | ||
850 | * successfully. | ||
851 | */ | ||
852 | if (!cell_added) { | ||
853 | lpc_ich_restore_config_space(dev); | ||
854 | return -ENODEV; | ||
855 | } | ||
856 | |||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | static void __devexit lpc_ich_remove(struct pci_dev *dev) | ||
861 | { | ||
862 | mfd_remove_devices(&dev->dev); | ||
863 | lpc_ich_restore_config_space(dev); | ||
864 | } | ||
865 | |||
866 | static struct pci_driver lpc_ich_driver = { | ||
867 | .name = "lpc_ich", | ||
868 | .id_table = lpc_ich_ids, | ||
869 | .probe = lpc_ich_probe, | ||
870 | .remove = __devexit_p(lpc_ich_remove), | ||
871 | }; | ||
872 | |||
873 | static int __init lpc_ich_init(void) | ||
874 | { | ||
875 | return pci_register_driver(&lpc_ich_driver); | ||
876 | } | ||
877 | |||
878 | static void __exit lpc_ich_exit(void) | ||
879 | { | ||
880 | pci_unregister_driver(&lpc_ich_driver); | ||
881 | } | ||
882 | |||
883 | module_init(lpc_ich_init); | ||
884 | module_exit(lpc_ich_exit); | ||
885 | |||
886 | MODULE_AUTHOR("Aaron Sierra <asierra@xes-inc.com>"); | ||
887 | MODULE_DESCRIPTION("LPC interface for Intel ICH"); | ||
888 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index abc421364a45..9f20abc5e393 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -36,6 +36,7 @@ | |||
36 | 36 | ||
37 | #define GPIOBASE 0x44 | 37 | #define GPIOBASE 0x44 |
38 | #define GPIO_IO_SIZE 64 | 38 | #define GPIO_IO_SIZE 64 |
39 | #define GPIO_IO_SIZE_CENTERTON 128 | ||
39 | 40 | ||
40 | #define WDTBASE 0x84 | 41 | #define WDTBASE 0x84 |
41 | #define WDT_IO_SIZE 64 | 42 | #define WDT_IO_SIZE 64 |
@@ -68,7 +69,7 @@ static struct resource wdt_sch_resource = { | |||
68 | 69 | ||
69 | static struct mfd_cell tunnelcreek_cells[] = { | 70 | static struct mfd_cell tunnelcreek_cells[] = { |
70 | { | 71 | { |
71 | .name = "tunnelcreek_wdt", | 72 | .name = "ie6xx_wdt", |
72 | .num_resources = 1, | 73 | .num_resources = 1, |
73 | .resources = &wdt_sch_resource, | 74 | .resources = &wdt_sch_resource, |
74 | }, | 75 | }, |
@@ -77,6 +78,7 @@ static struct mfd_cell tunnelcreek_cells[] = { | |||
77 | static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { | 78 | static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { |
78 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, |
79 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, | 80 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, |
81 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB) }, | ||
80 | { 0, } | 82 | { 0, } |
81 | }; | 83 | }; |
82 | MODULE_DEVICE_TABLE(pci, lpc_sch_ids); | 84 | MODULE_DEVICE_TABLE(pci, lpc_sch_ids); |
@@ -115,7 +117,11 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
115 | } | 117 | } |
116 | 118 | ||
117 | gpio_sch_resource.start = base_addr; | 119 | gpio_sch_resource.start = base_addr; |
118 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; | 120 | |
121 | if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) | ||
122 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1; | ||
123 | else | ||
124 | gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; | ||
119 | 125 | ||
120 | for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) | 126 | for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) |
121 | lpc_sch_cells[i].id = id->device; | 127 | lpc_sch_cells[i].id = id->device; |
@@ -125,7 +131,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
125 | if (ret) | 131 | if (ret) |
126 | goto out_dev; | 132 | goto out_dev; |
127 | 133 | ||
128 | if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC) { | 134 | if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC |
135 | || id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) { | ||
129 | pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); | 136 | pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); |
130 | if (!(base_addr_cfg & (1 << 31))) { | 137 | if (!(base_addr_cfg & (1 << 31))) { |
131 | dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); | 138 | dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); |
@@ -167,18 +174,7 @@ static struct pci_driver lpc_sch_driver = { | |||
167 | .remove = __devexit_p(lpc_sch_remove), | 174 | .remove = __devexit_p(lpc_sch_remove), |
168 | }; | 175 | }; |
169 | 176 | ||
170 | static int __init lpc_sch_init(void) | 177 | module_pci_driver(lpc_sch_driver); |
171 | { | ||
172 | return pci_register_driver(&lpc_sch_driver); | ||
173 | } | ||
174 | |||
175 | static void __exit lpc_sch_exit(void) | ||
176 | { | ||
177 | pci_unregister_driver(&lpc_sch_driver); | ||
178 | } | ||
179 | |||
180 | module_init(lpc_sch_init); | ||
181 | module_exit(lpc_sch_exit); | ||
182 | 178 | ||
183 | MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); | 179 | MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); |
184 | MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH"); | 180 | MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH"); |
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c new file mode 100644 index 000000000000..2b403569e0a6 --- /dev/null +++ b/drivers/mfd/max77693-irq.c | |||
@@ -0,0 +1,309 @@ | |||
1 | /* | ||
2 | * max77693-irq.c - Interrupt controller support for MAX77693 | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
5 | * SangYoung Son <hello.son@samsung.com> | ||
6 | * | ||
7 | * This program is not provided / owned by Maxim Integrated Products. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | * This driver is based on max8997-irq.c | ||
24 | */ | ||
25 | |||
26 | #include <linux/err.h> | ||
27 | #include <linux/irq.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/module.h> | ||
30 | #include <linux/irqdomain.h> | ||
31 | #include <linux/mfd/max77693.h> | ||
32 | #include <linux/mfd/max77693-private.h> | ||
33 | |||
34 | static const u8 max77693_mask_reg[] = { | ||
35 | [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK, | ||
36 | [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK, | ||
37 | [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK, | ||
38 | [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1, | ||
39 | [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2, | ||
40 | [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3, | ||
41 | }; | ||
42 | |||
43 | static struct regmap *max77693_get_regmap(struct max77693_dev *max77693, | ||
44 | enum max77693_irq_source src) | ||
45 | { | ||
46 | switch (src) { | ||
47 | case LED_INT ... CHG_INT: | ||
48 | return max77693->regmap; | ||
49 | case MUIC_INT1 ... MUIC_INT3: | ||
50 | return max77693->regmap_muic; | ||
51 | default: | ||
52 | return ERR_PTR(-EINVAL); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | struct max77693_irq_data { | ||
57 | int mask; | ||
58 | enum max77693_irq_source group; | ||
59 | }; | ||
60 | |||
61 | #define DECLARE_IRQ(idx, _group, _mask) \ | ||
62 | [(idx)] = { .group = (_group), .mask = (_mask) } | ||
63 | static const struct max77693_irq_data max77693_irqs[] = { | ||
64 | DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0), | ||
65 | DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1), | ||
66 | DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2), | ||
67 | DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3), | ||
68 | DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4), | ||
69 | |||
70 | DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0), | ||
71 | DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1), | ||
72 | DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3), | ||
73 | |||
74 | DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0), | ||
75 | DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2), | ||
76 | DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3), | ||
77 | DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4), | ||
78 | DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6), | ||
79 | |||
80 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0), | ||
81 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1), | ||
82 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2), | ||
83 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3), | ||
84 | |||
85 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0), | ||
86 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1), | ||
87 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2), | ||
88 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3), | ||
89 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4), | ||
90 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5), | ||
91 | |||
92 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0), | ||
93 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1), | ||
94 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2), | ||
95 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3), | ||
96 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4), | ||
97 | DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5), | ||
98 | }; | ||
99 | |||
100 | static void max77693_irq_lock(struct irq_data *data) | ||
101 | { | ||
102 | struct max77693_dev *max77693 = irq_get_chip_data(data->irq); | ||
103 | |||
104 | mutex_lock(&max77693->irqlock); | ||
105 | } | ||
106 | |||
107 | static void max77693_irq_sync_unlock(struct irq_data *data) | ||
108 | { | ||
109 | struct max77693_dev *max77693 = irq_get_chip_data(data->irq); | ||
110 | int i; | ||
111 | |||
112 | for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { | ||
113 | u8 mask_reg = max77693_mask_reg[i]; | ||
114 | struct regmap *map = max77693_get_regmap(max77693, i); | ||
115 | |||
116 | if (mask_reg == MAX77693_REG_INVALID || | ||
117 | IS_ERR_OR_NULL(map)) | ||
118 | continue; | ||
119 | max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i]; | ||
120 | |||
121 | max77693_write_reg(map, max77693_mask_reg[i], | ||
122 | max77693->irq_masks_cur[i]); | ||
123 | } | ||
124 | |||
125 | mutex_unlock(&max77693->irqlock); | ||
126 | } | ||
127 | |||
128 | static const inline struct max77693_irq_data * | ||
129 | irq_to_max77693_irq(struct max77693_dev *max77693, int irq) | ||
130 | { | ||
131 | return &max77693_irqs[irq]; | ||
132 | } | ||
133 | |||
134 | static void max77693_irq_mask(struct irq_data *data) | ||
135 | { | ||
136 | struct max77693_dev *max77693 = irq_get_chip_data(data->irq); | ||
137 | const struct max77693_irq_data *irq_data = | ||
138 | irq_to_max77693_irq(max77693, data->irq); | ||
139 | |||
140 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | ||
141 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | ||
142 | else | ||
143 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; | ||
144 | } | ||
145 | |||
146 | static void max77693_irq_unmask(struct irq_data *data) | ||
147 | { | ||
148 | struct max77693_dev *max77693 = irq_get_chip_data(data->irq); | ||
149 | const struct max77693_irq_data *irq_data = | ||
150 | irq_to_max77693_irq(max77693, data->irq); | ||
151 | |||
152 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | ||
153 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; | ||
154 | else | ||
155 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | ||
156 | } | ||
157 | |||
158 | static struct irq_chip max77693_irq_chip = { | ||
159 | .name = "max77693", | ||
160 | .irq_bus_lock = max77693_irq_lock, | ||
161 | .irq_bus_sync_unlock = max77693_irq_sync_unlock, | ||
162 | .irq_mask = max77693_irq_mask, | ||
163 | .irq_unmask = max77693_irq_unmask, | ||
164 | }; | ||
165 | |||
166 | #define MAX77693_IRQSRC_CHG (1 << 0) | ||
167 | #define MAX77693_IRQSRC_TOP (1 << 1) | ||
168 | #define MAX77693_IRQSRC_FLASH (1 << 2) | ||
169 | #define MAX77693_IRQSRC_MUIC (1 << 3) | ||
170 | static irqreturn_t max77693_irq_thread(int irq, void *data) | ||
171 | { | ||
172 | struct max77693_dev *max77693 = data; | ||
173 | u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {}; | ||
174 | u8 irq_src; | ||
175 | int ret; | ||
176 | int i, cur_irq; | ||
177 | |||
178 | ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_INTSRC, | ||
179 | &irq_src); | ||
180 | if (ret < 0) { | ||
181 | dev_err(max77693->dev, "Failed to read interrupt source: %d\n", | ||
182 | ret); | ||
183 | return IRQ_NONE; | ||
184 | } | ||
185 | |||
186 | if (irq_src & MAX77693_IRQSRC_CHG) | ||
187 | /* CHG_INT */ | ||
188 | ret = max77693_read_reg(max77693->regmap, MAX77693_CHG_REG_CHG_INT, | ||
189 | &irq_reg[CHG_INT]); | ||
190 | |||
191 | if (irq_src & MAX77693_IRQSRC_TOP) | ||
192 | /* TOPSYS_INT */ | ||
193 | ret = max77693_read_reg(max77693->regmap, | ||
194 | MAX77693_PMIC_REG_TOPSYS_INT, &irq_reg[TOPSYS_INT]); | ||
195 | |||
196 | if (irq_src & MAX77693_IRQSRC_FLASH) | ||
197 | /* LED_INT */ | ||
198 | ret = max77693_read_reg(max77693->regmap, | ||
199 | MAX77693_LED_REG_FLASH_INT, &irq_reg[LED_INT]); | ||
200 | |||
201 | if (irq_src & MAX77693_IRQSRC_MUIC) | ||
202 | /* MUIC INT1 ~ INT3 */ | ||
203 | max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1, | ||
204 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); | ||
205 | |||
206 | /* Apply masking */ | ||
207 | for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { | ||
208 | if (i >= MUIC_INT1 && i <= MUIC_INT3) | ||
209 | irq_reg[i] &= max77693->irq_masks_cur[i]; | ||
210 | else | ||
211 | irq_reg[i] &= ~max77693->irq_masks_cur[i]; | ||
212 | } | ||
213 | |||
214 | /* Report */ | ||
215 | for (i = 0; i < MAX77693_IRQ_NR; i++) { | ||
216 | if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) { | ||
217 | cur_irq = irq_find_mapping(max77693->irq_domain, i); | ||
218 | if (cur_irq) | ||
219 | handle_nested_irq(cur_irq); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | return IRQ_HANDLED; | ||
224 | } | ||
225 | |||
226 | int max77693_irq_resume(struct max77693_dev *max77693) | ||
227 | { | ||
228 | if (max77693->irq) | ||
229 | max77693_irq_thread(0, max77693); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
235 | irq_hw_number_t hw) | ||
236 | { | ||
237 | struct max77693_dev *max77693 = d->host_data; | ||
238 | |||
239 | irq_set_chip_data(irq, max77693); | ||
240 | irq_set_chip_and_handler(irq, &max77693_irq_chip, handle_edge_irq); | ||
241 | irq_set_nested_thread(irq, 1); | ||
242 | #ifdef CONFIG_ARM | ||
243 | set_irq_flags(irq, IRQF_VALID); | ||
244 | #else | ||
245 | irq_set_noprobe(irq); | ||
246 | #endif | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static struct irq_domain_ops max77693_irq_domain_ops = { | ||
251 | .map = max77693_irq_domain_map, | ||
252 | }; | ||
253 | |||
254 | int max77693_irq_init(struct max77693_dev *max77693) | ||
255 | { | ||
256 | struct irq_domain *domain; | ||
257 | int i; | ||
258 | int ret; | ||
259 | |||
260 | mutex_init(&max77693->irqlock); | ||
261 | |||
262 | /* Mask individual interrupt sources */ | ||
263 | for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) { | ||
264 | struct regmap *map; | ||
265 | /* MUIC IRQ 0:MASK 1:NOT MASK */ | ||
266 | /* Other IRQ 1:MASK 0:NOT MASK */ | ||
267 | if (i >= MUIC_INT1 && i <= MUIC_INT3) { | ||
268 | max77693->irq_masks_cur[i] = 0x00; | ||
269 | max77693->irq_masks_cache[i] = 0x00; | ||
270 | } else { | ||
271 | max77693->irq_masks_cur[i] = 0xff; | ||
272 | max77693->irq_masks_cache[i] = 0xff; | ||
273 | } | ||
274 | map = max77693_get_regmap(max77693, i); | ||
275 | |||
276 | if (IS_ERR_OR_NULL(map)) | ||
277 | continue; | ||
278 | if (max77693_mask_reg[i] == MAX77693_REG_INVALID) | ||
279 | continue; | ||
280 | if (i >= MUIC_INT1 && i <= MUIC_INT3) | ||
281 | max77693_write_reg(map, max77693_mask_reg[i], 0x00); | ||
282 | else | ||
283 | max77693_write_reg(map, max77693_mask_reg[i], 0xff); | ||
284 | } | ||
285 | |||
286 | domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR, | ||
287 | &max77693_irq_domain_ops, max77693); | ||
288 | if (!domain) { | ||
289 | dev_err(max77693->dev, "could not create irq domain\n"); | ||
290 | return -ENODEV; | ||
291 | } | ||
292 | max77693->irq_domain = domain; | ||
293 | |||
294 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, | ||
295 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
296 | "max77693-irq", max77693); | ||
297 | |||
298 | if (ret) | ||
299 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", | ||
300 | max77693->irq, ret); | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | void max77693_irq_exit(struct max77693_dev *max77693) | ||
306 | { | ||
307 | if (max77693->irq) | ||
308 | free_irq(max77693->irq, max77693); | ||
309 | } | ||
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c new file mode 100644 index 000000000000..e9e4278722f3 --- /dev/null +++ b/drivers/mfd/max77693.c | |||
@@ -0,0 +1,249 @@ | |||
1 | /* | ||
2 | * max77693.c - mfd core driver for the MAX 77693 | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics | ||
5 | * SangYoung Son <hello.son@smasung.com> | ||
6 | * | ||
7 | * This program is not provided / owned by Maxim Integrated Products. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | * | ||
23 | * This driver is based on max8997.c | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/err.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | #include <linux/pm_runtime.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/mfd/core.h> | ||
34 | #include <linux/mfd/max77693.h> | ||
35 | #include <linux/mfd/max77693-private.h> | ||
36 | #include <linux/regulator/machine.h> | ||
37 | #include <linux/regmap.h> | ||
38 | |||
39 | #define I2C_ADDR_PMIC (0xCC >> 1) /* Charger, Flash LED */ | ||
40 | #define I2C_ADDR_MUIC (0x4A >> 1) | ||
41 | #define I2C_ADDR_HAPTIC (0x90 >> 1) | ||
42 | |||
43 | static struct mfd_cell max77693_devs[] = { | ||
44 | { .name = "max77693-pmic", }, | ||
45 | { .name = "max77693-charger", }, | ||
46 | { .name = "max77693-flash", }, | ||
47 | { .name = "max77693-muic", }, | ||
48 | { .name = "max77693-haptic", }, | ||
49 | }; | ||
50 | |||
51 | int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest) | ||
52 | { | ||
53 | unsigned int val; | ||
54 | int ret; | ||
55 | |||
56 | ret = regmap_read(map, reg, &val); | ||
57 | *dest = val; | ||
58 | |||
59 | return ret; | ||
60 | } | ||
61 | EXPORT_SYMBOL_GPL(max77693_read_reg); | ||
62 | |||
63 | int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf) | ||
64 | { | ||
65 | int ret; | ||
66 | |||
67 | ret = regmap_bulk_read(map, reg, buf, count); | ||
68 | |||
69 | return ret; | ||
70 | } | ||
71 | EXPORT_SYMBOL_GPL(max77693_bulk_read); | ||
72 | |||
73 | int max77693_write_reg(struct regmap *map, u8 reg, u8 value) | ||
74 | { | ||
75 | int ret; | ||
76 | |||
77 | ret = regmap_write(map, reg, value); | ||
78 | |||
79 | return ret; | ||
80 | } | ||
81 | EXPORT_SYMBOL_GPL(max77693_write_reg); | ||
82 | |||
83 | int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf) | ||
84 | { | ||
85 | int ret; | ||
86 | |||
87 | ret = regmap_bulk_write(map, reg, buf, count); | ||
88 | |||
89 | return ret; | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(max77693_bulk_write); | ||
92 | |||
93 | int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask) | ||
94 | { | ||
95 | int ret; | ||
96 | |||
97 | ret = regmap_update_bits(map, reg, mask, val); | ||
98 | |||
99 | return ret; | ||
100 | } | ||
101 | EXPORT_SYMBOL_GPL(max77693_update_reg); | ||
102 | |||
103 | static const struct regmap_config max77693_regmap_config = { | ||
104 | .reg_bits = 8, | ||
105 | .val_bits = 8, | ||
106 | .max_register = MAX77693_PMIC_REG_END, | ||
107 | }; | ||
108 | |||
109 | static int max77693_i2c_probe(struct i2c_client *i2c, | ||
110 | const struct i2c_device_id *id) | ||
111 | { | ||
112 | struct max77693_dev *max77693; | ||
113 | struct max77693_platform_data *pdata = i2c->dev.platform_data; | ||
114 | u8 reg_data; | ||
115 | int ret = 0; | ||
116 | |||
117 | max77693 = devm_kzalloc(&i2c->dev, | ||
118 | sizeof(struct max77693_dev), GFP_KERNEL); | ||
119 | if (max77693 == NULL) | ||
120 | return -ENOMEM; | ||
121 | |||
122 | max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); | ||
123 | if (IS_ERR(max77693->regmap)) { | ||
124 | ret = PTR_ERR(max77693->regmap); | ||
125 | dev_err(max77693->dev,"failed to allocate register map: %d\n", | ||
126 | ret); | ||
127 | goto err_regmap; | ||
128 | } | ||
129 | |||
130 | i2c_set_clientdata(i2c, max77693); | ||
131 | max77693->dev = &i2c->dev; | ||
132 | max77693->i2c = i2c; | ||
133 | max77693->irq = i2c->irq; | ||
134 | max77693->type = id->driver_data; | ||
135 | |||
136 | if (!pdata) | ||
137 | goto err_regmap; | ||
138 | |||
139 | max77693->wakeup = pdata->wakeup; | ||
140 | |||
141 | mutex_init(&max77693->iolock); | ||
142 | |||
143 | if (max77693_read_reg(max77693->regmap, | ||
144 | MAX77693_PMIC_REG_PMIC_ID2, ®_data) < 0) { | ||
145 | dev_err(max77693->dev, "device not found on this channel\n"); | ||
146 | ret = -ENODEV; | ||
147 | goto err_regmap; | ||
148 | } else | ||
149 | dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); | ||
150 | |||
151 | max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); | ||
152 | i2c_set_clientdata(max77693->muic, max77693); | ||
153 | |||
154 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); | ||
155 | i2c_set_clientdata(max77693->haptic, max77693); | ||
156 | |||
157 | ret = max77693_irq_init(max77693); | ||
158 | if (ret < 0) | ||
159 | goto err_mfd; | ||
160 | |||
161 | pm_runtime_set_active(max77693->dev); | ||
162 | |||
163 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, | ||
164 | ARRAY_SIZE(max77693_devs), NULL, 0); | ||
165 | if (ret < 0) | ||
166 | goto err_mfd; | ||
167 | |||
168 | device_init_wakeup(max77693->dev, pdata->wakeup); | ||
169 | |||
170 | return ret; | ||
171 | |||
172 | err_mfd: | ||
173 | i2c_unregister_device(max77693->muic); | ||
174 | i2c_unregister_device(max77693->haptic); | ||
175 | err_regmap: | ||
176 | kfree(max77693); | ||
177 | |||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static int max77693_i2c_remove(struct i2c_client *i2c) | ||
182 | { | ||
183 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); | ||
184 | |||
185 | mfd_remove_devices(max77693->dev); | ||
186 | i2c_unregister_device(max77693->muic); | ||
187 | i2c_unregister_device(max77693->haptic); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static const struct i2c_device_id max77693_i2c_id[] = { | ||
193 | { "max77693", TYPE_MAX77693 }, | ||
194 | { } | ||
195 | }; | ||
196 | MODULE_DEVICE_TABLE(i2c, max77693_i2c_id); | ||
197 | |||
198 | static int max77693_suspend(struct device *dev) | ||
199 | { | ||
200 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
201 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); | ||
202 | |||
203 | if (device_may_wakeup(dev)) | ||
204 | irq_set_irq_wake(max77693->irq, 1); | ||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | static int max77693_resume(struct device *dev) | ||
209 | { | ||
210 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
211 | struct max77693_dev *max77693 = i2c_get_clientdata(i2c); | ||
212 | |||
213 | if (device_may_wakeup(dev)) | ||
214 | irq_set_irq_wake(max77693->irq, 0); | ||
215 | return max77693_irq_resume(max77693); | ||
216 | } | ||
217 | |||
218 | const struct dev_pm_ops max77693_pm = { | ||
219 | .suspend = max77693_suspend, | ||
220 | .resume = max77693_resume, | ||
221 | }; | ||
222 | |||
223 | static struct i2c_driver max77693_i2c_driver = { | ||
224 | .driver = { | ||
225 | .name = "max77693", | ||
226 | .owner = THIS_MODULE, | ||
227 | .pm = &max77693_pm, | ||
228 | }, | ||
229 | .probe = max77693_i2c_probe, | ||
230 | .remove = max77693_i2c_remove, | ||
231 | .id_table = max77693_i2c_id, | ||
232 | }; | ||
233 | |||
234 | static int __init max77693_i2c_init(void) | ||
235 | { | ||
236 | return i2c_add_driver(&max77693_i2c_driver); | ||
237 | } | ||
238 | /* init early so consumer devices can complete system boot */ | ||
239 | subsys_initcall(max77693_i2c_init); | ||
240 | |||
241 | static void __exit max77693_i2c_exit(void) | ||
242 | { | ||
243 | i2c_del_driver(&max77693_i2c_driver); | ||
244 | } | ||
245 | module_exit(max77693_i2c_exit); | ||
246 | |||
247 | MODULE_DESCRIPTION("MAXIM 77693 multi-function core driver"); | ||
248 | MODULE_AUTHOR("SangYoung, Son <hello.son@samsung.com>"); | ||
249 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 738722cdecaa..f0ea3b8b3e4a 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -15,24 +15,13 @@ | |||
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/spi/spi.h> | ||
19 | #include <linux/mfd/core.h> | 18 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/mc13xxx.h> | 19 | #include <linux/mfd/mc13xxx.h> |
21 | #include <linux/of.h> | 20 | #include <linux/of.h> |
22 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
23 | #include <linux/of_gpio.h> | 22 | #include <linux/of_gpio.h> |
24 | 23 | ||
25 | struct mc13xxx { | 24 | #include "mc13xxx.h" |
26 | struct spi_device *spidev; | ||
27 | struct mutex lock; | ||
28 | int irq; | ||
29 | int flags; | ||
30 | |||
31 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; | ||
32 | void *irqdata[MC13XXX_NUM_IRQ]; | ||
33 | |||
34 | int adcflags; | ||
35 | }; | ||
36 | 25 | ||
37 | #define MC13XXX_IRQSTAT0 0 | 26 | #define MC13XXX_IRQSTAT0 0 |
38 | #define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) | 27 | #define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) |
@@ -139,34 +128,29 @@ struct mc13xxx { | |||
139 | 128 | ||
140 | #define MC13XXX_ADC2 45 | 129 | #define MC13XXX_ADC2 45 |
141 | 130 | ||
142 | #define MC13XXX_NUMREGS 0x3f | ||
143 | |||
144 | void mc13xxx_lock(struct mc13xxx *mc13xxx) | 131 | void mc13xxx_lock(struct mc13xxx *mc13xxx) |
145 | { | 132 | { |
146 | if (!mutex_trylock(&mc13xxx->lock)) { | 133 | if (!mutex_trylock(&mc13xxx->lock)) { |
147 | dev_dbg(&mc13xxx->spidev->dev, "wait for %s from %pf\n", | 134 | dev_dbg(mc13xxx->dev, "wait for %s from %pf\n", |
148 | __func__, __builtin_return_address(0)); | 135 | __func__, __builtin_return_address(0)); |
149 | 136 | ||
150 | mutex_lock(&mc13xxx->lock); | 137 | mutex_lock(&mc13xxx->lock); |
151 | } | 138 | } |
152 | dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n", | 139 | dev_dbg(mc13xxx->dev, "%s from %pf\n", |
153 | __func__, __builtin_return_address(0)); | 140 | __func__, __builtin_return_address(0)); |
154 | } | 141 | } |
155 | EXPORT_SYMBOL(mc13xxx_lock); | 142 | EXPORT_SYMBOL(mc13xxx_lock); |
156 | 143 | ||
157 | void mc13xxx_unlock(struct mc13xxx *mc13xxx) | 144 | void mc13xxx_unlock(struct mc13xxx *mc13xxx) |
158 | { | 145 | { |
159 | dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n", | 146 | dev_dbg(mc13xxx->dev, "%s from %pf\n", |
160 | __func__, __builtin_return_address(0)); | 147 | __func__, __builtin_return_address(0)); |
161 | mutex_unlock(&mc13xxx->lock); | 148 | mutex_unlock(&mc13xxx->lock); |
162 | } | 149 | } |
163 | EXPORT_SYMBOL(mc13xxx_unlock); | 150 | EXPORT_SYMBOL(mc13xxx_unlock); |
164 | 151 | ||
165 | #define MC13XXX_REGOFFSET_SHIFT 25 | ||
166 | int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) | 152 | int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) |
167 | { | 153 | { |
168 | struct spi_transfer t; | ||
169 | struct spi_message m; | ||
170 | int ret; | 154 | int ret; |
171 | 155 | ||
172 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | 156 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); |
@@ -174,84 +158,35 @@ int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) | |||
174 | if (offset > MC13XXX_NUMREGS) | 158 | if (offset > MC13XXX_NUMREGS) |
175 | return -EINVAL; | 159 | return -EINVAL; |
176 | 160 | ||
177 | *val = offset << MC13XXX_REGOFFSET_SHIFT; | 161 | ret = regmap_read(mc13xxx->regmap, offset, val); |
178 | 162 | dev_vdbg(mc13xxx->dev, "[0x%02x] -> 0x%06x\n", offset, *val); | |
179 | memset(&t, 0, sizeof(t)); | ||
180 | |||
181 | t.tx_buf = val; | ||
182 | t.rx_buf = val; | ||
183 | t.len = sizeof(u32); | ||
184 | |||
185 | spi_message_init(&m); | ||
186 | spi_message_add_tail(&t, &m); | ||
187 | |||
188 | ret = spi_sync(mc13xxx->spidev, &m); | ||
189 | |||
190 | /* error in message.status implies error return from spi_sync */ | ||
191 | BUG_ON(!ret && m.status); | ||
192 | 163 | ||
193 | if (ret) | 164 | return ret; |
194 | return ret; | ||
195 | |||
196 | *val &= 0xffffff; | ||
197 | |||
198 | dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val); | ||
199 | |||
200 | return 0; | ||
201 | } | 165 | } |
202 | EXPORT_SYMBOL(mc13xxx_reg_read); | 166 | EXPORT_SYMBOL(mc13xxx_reg_read); |
203 | 167 | ||
204 | int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) | 168 | int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) |
205 | { | 169 | { |
206 | u32 buf; | ||
207 | struct spi_transfer t; | ||
208 | struct spi_message m; | ||
209 | int ret; | ||
210 | |||
211 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | 170 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); |
212 | 171 | ||
213 | dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val); | 172 | dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x\n", offset, val); |
214 | 173 | ||
215 | if (offset > MC13XXX_NUMREGS || val > 0xffffff) | 174 | if (offset > MC13XXX_NUMREGS || val > 0xffffff) |
216 | return -EINVAL; | 175 | return -EINVAL; |
217 | 176 | ||
218 | buf = 1 << 31 | offset << MC13XXX_REGOFFSET_SHIFT | val; | 177 | return regmap_write(mc13xxx->regmap, offset, val); |
219 | |||
220 | memset(&t, 0, sizeof(t)); | ||
221 | |||
222 | t.tx_buf = &buf; | ||
223 | t.rx_buf = &buf; | ||
224 | t.len = sizeof(u32); | ||
225 | |||
226 | spi_message_init(&m); | ||
227 | spi_message_add_tail(&t, &m); | ||
228 | |||
229 | ret = spi_sync(mc13xxx->spidev, &m); | ||
230 | |||
231 | BUG_ON(!ret && m.status); | ||
232 | |||
233 | if (ret) | ||
234 | return ret; | ||
235 | |||
236 | return 0; | ||
237 | } | 178 | } |
238 | EXPORT_SYMBOL(mc13xxx_reg_write); | 179 | EXPORT_SYMBOL(mc13xxx_reg_write); |
239 | 180 | ||
240 | int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset, | 181 | int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset, |
241 | u32 mask, u32 val) | 182 | u32 mask, u32 val) |
242 | { | 183 | { |
243 | int ret; | 184 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); |
244 | u32 valread; | ||
245 | |||
246 | BUG_ON(val & ~mask); | 185 | BUG_ON(val & ~mask); |
186 | dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x (mask: 0x%06x)\n", | ||
187 | offset, val, mask); | ||
247 | 188 | ||
248 | ret = mc13xxx_reg_read(mc13xxx, offset, &valread); | 189 | return regmap_update_bits(mc13xxx->regmap, offset, mask, val); |
249 | if (ret) | ||
250 | return ret; | ||
251 | |||
252 | valread = (valread & ~mask) | val; | ||
253 | |||
254 | return mc13xxx_reg_write(mc13xxx, offset, valread); | ||
255 | } | 190 | } |
256 | EXPORT_SYMBOL(mc13xxx_reg_rmw); | 191 | EXPORT_SYMBOL(mc13xxx_reg_rmw); |
257 | 192 | ||
@@ -439,7 +374,7 @@ static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx, | |||
439 | if (handled == IRQ_HANDLED) | 374 | if (handled == IRQ_HANDLED) |
440 | num_handled++; | 375 | num_handled++; |
441 | } else { | 376 | } else { |
442 | dev_err(&mc13xxx->spidev->dev, | 377 | dev_err(mc13xxx->dev, |
443 | "BUG: irq %u but no handler\n", | 378 | "BUG: irq %u but no handler\n", |
444 | baseirq + irq); | 379 | baseirq + irq); |
445 | 380 | ||
@@ -475,25 +410,23 @@ static irqreturn_t mc13xxx_irq_thread(int irq, void *data) | |||
475 | return IRQ_RETVAL(handled); | 410 | return IRQ_RETVAL(handled); |
476 | } | 411 | } |
477 | 412 | ||
478 | enum mc13xxx_id { | ||
479 | MC13XXX_ID_MC13783, | ||
480 | MC13XXX_ID_MC13892, | ||
481 | MC13XXX_ID_INVALID, | ||
482 | }; | ||
483 | |||
484 | static const char *mc13xxx_chipname[] = { | 413 | static const char *mc13xxx_chipname[] = { |
485 | [MC13XXX_ID_MC13783] = "mc13783", | 414 | [MC13XXX_ID_MC13783] = "mc13783", |
486 | [MC13XXX_ID_MC13892] = "mc13892", | 415 | [MC13XXX_ID_MC13892] = "mc13892", |
487 | }; | 416 | }; |
488 | 417 | ||
489 | #define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) | 418 | #define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) |
490 | static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) | 419 | static int mc13xxx_identify(struct mc13xxx *mc13xxx) |
491 | { | 420 | { |
492 | u32 icid; | 421 | u32 icid; |
493 | u32 revision; | 422 | u32 revision; |
494 | const char *name; | ||
495 | int ret; | 423 | int ret; |
496 | 424 | ||
425 | /* | ||
426 | * Get the generation ID from register 46, as apparently some older | ||
427 | * IC revisions only have this info at this location. Newer ICs seem to | ||
428 | * have both. | ||
429 | */ | ||
497 | ret = mc13xxx_reg_read(mc13xxx, 46, &icid); | 430 | ret = mc13xxx_reg_read(mc13xxx, 46, &icid); |
498 | if (ret) | 431 | if (ret) |
499 | return ret; | 432 | return ret; |
@@ -502,26 +435,23 @@ static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) | |||
502 | 435 | ||
503 | switch (icid) { | 436 | switch (icid) { |
504 | case 2: | 437 | case 2: |
505 | *id = MC13XXX_ID_MC13783; | 438 | mc13xxx->ictype = MC13XXX_ID_MC13783; |
506 | name = "mc13783"; | ||
507 | break; | 439 | break; |
508 | case 7: | 440 | case 7: |
509 | *id = MC13XXX_ID_MC13892; | 441 | mc13xxx->ictype = MC13XXX_ID_MC13892; |
510 | name = "mc13892"; | ||
511 | break; | 442 | break; |
512 | default: | 443 | default: |
513 | *id = MC13XXX_ID_INVALID; | 444 | mc13xxx->ictype = MC13XXX_ID_INVALID; |
514 | break; | 445 | break; |
515 | } | 446 | } |
516 | 447 | ||
517 | if (*id == MC13XXX_ID_MC13783 || *id == MC13XXX_ID_MC13892) { | 448 | if (mc13xxx->ictype == MC13XXX_ID_MC13783 || |
449 | mc13xxx->ictype == MC13XXX_ID_MC13892) { | ||
518 | ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); | 450 | ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); |
519 | if (ret) | ||
520 | return ret; | ||
521 | 451 | ||
522 | dev_info(&mc13xxx->spidev->dev, "%s: rev: %d.%d, " | 452 | dev_info(mc13xxx->dev, "%s: rev: %d.%d, " |
523 | "fin: %d, fab: %d, icid: %d/%d\n", | 453 | "fin: %d, fab: %d, icid: %d/%d\n", |
524 | mc13xxx_chipname[*id], | 454 | mc13xxx_chipname[mc13xxx->ictype], |
525 | maskval(revision, MC13XXX_REVISION_REVFULL), | 455 | maskval(revision, MC13XXX_REVISION_REVFULL), |
526 | maskval(revision, MC13XXX_REVISION_REVMETAL), | 456 | maskval(revision, MC13XXX_REVISION_REVMETAL), |
527 | maskval(revision, MC13XXX_REVISION_FIN), | 457 | maskval(revision, MC13XXX_REVISION_FIN), |
@@ -530,26 +460,12 @@ static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) | |||
530 | maskval(revision, MC13XXX_REVISION_ICIDCODE)); | 460 | maskval(revision, MC13XXX_REVISION_ICIDCODE)); |
531 | } | 461 | } |
532 | 462 | ||
533 | if (*id != MC13XXX_ID_INVALID) { | 463 | return (mc13xxx->ictype == MC13XXX_ID_INVALID) ? -ENODEV : 0; |
534 | const struct spi_device_id *devid = | ||
535 | spi_get_device_id(mc13xxx->spidev); | ||
536 | if (!devid || devid->driver_data != *id) | ||
537 | dev_warn(&mc13xxx->spidev->dev, "device id doesn't " | ||
538 | "match auto detection!\n"); | ||
539 | } | ||
540 | |||
541 | return 0; | ||
542 | } | 464 | } |
543 | 465 | ||
544 | static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) | 466 | static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) |
545 | { | 467 | { |
546 | const struct spi_device_id *devid = | 468 | return mc13xxx_chipname[mc13xxx->ictype]; |
547 | spi_get_device_id(mc13xxx->spidev); | ||
548 | |||
549 | if (!devid) | ||
550 | return NULL; | ||
551 | |||
552 | return mc13xxx_chipname[devid->driver_data]; | ||
553 | } | 469 | } |
554 | 470 | ||
555 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) | 471 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) |
@@ -592,7 +508,7 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, | |||
592 | }; | 508 | }; |
593 | init_completion(&adcdone_data.done); | 509 | init_completion(&adcdone_data.done); |
594 | 510 | ||
595 | dev_dbg(&mc13xxx->spidev->dev, "%s\n", __func__); | 511 | dev_dbg(mc13xxx->dev, "%s\n", __func__); |
596 | 512 | ||
597 | mc13xxx_lock(mc13xxx); | 513 | mc13xxx_lock(mc13xxx); |
598 | 514 | ||
@@ -637,7 +553,8 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, | |||
637 | adc1 |= ato << MC13783_ADC1_ATO_SHIFT; | 553 | adc1 |= ato << MC13783_ADC1_ATO_SHIFT; |
638 | if (atox) | 554 | if (atox) |
639 | adc1 |= MC13783_ADC1_ATOX; | 555 | adc1 |= MC13783_ADC1_ATOX; |
640 | dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__); | 556 | |
557 | dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); | ||
641 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, | 558 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, |
642 | mc13xxx_handler_adcdone, __func__, &adcdone_data); | 559 | mc13xxx_handler_adcdone, __func__, &adcdone_data); |
643 | mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); | 560 | mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); |
@@ -695,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | |||
695 | if (!cell.name) | 612 | if (!cell.name) |
696 | return -ENOMEM; | 613 | return -ENOMEM; |
697 | 614 | ||
698 | return mfd_add_devices(&mc13xxx->spidev->dev, -1, &cell, 1, NULL, 0); | 615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); |
699 | } | 616 | } |
700 | 617 | ||
701 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | 618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) |
@@ -706,7 +623,7 @@ static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | |||
706 | #ifdef CONFIG_OF | 623 | #ifdef CONFIG_OF |
707 | static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | 624 | static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) |
708 | { | 625 | { |
709 | struct device_node *np = mc13xxx->spidev->dev.of_node; | 626 | struct device_node *np = mc13xxx->dev->of_node; |
710 | 627 | ||
711 | if (!np) | 628 | if (!np) |
712 | return -ENODEV; | 629 | return -ENODEV; |
@@ -732,55 +649,15 @@ static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | |||
732 | } | 649 | } |
733 | #endif | 650 | #endif |
734 | 651 | ||
735 | static const struct spi_device_id mc13xxx_device_id[] = { | 652 | int mc13xxx_common_init(struct mc13xxx *mc13xxx, |
736 | { | 653 | struct mc13xxx_platform_data *pdata, int irq) |
737 | .name = "mc13783", | ||
738 | .driver_data = MC13XXX_ID_MC13783, | ||
739 | }, { | ||
740 | .name = "mc13892", | ||
741 | .driver_data = MC13XXX_ID_MC13892, | ||
742 | }, { | ||
743 | /* sentinel */ | ||
744 | } | ||
745 | }; | ||
746 | MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); | ||
747 | |||
748 | static const struct of_device_id mc13xxx_dt_ids[] = { | ||
749 | { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, }, | ||
750 | { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, }, | ||
751 | { /* sentinel */ } | ||
752 | }; | ||
753 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); | ||
754 | |||
755 | static int mc13xxx_probe(struct spi_device *spi) | ||
756 | { | 654 | { |
757 | const struct of_device_id *of_id; | ||
758 | struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); | ||
759 | struct mc13xxx *mc13xxx; | ||
760 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); | ||
761 | enum mc13xxx_id id; | ||
762 | int ret; | 655 | int ret; |
763 | 656 | ||
764 | of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); | ||
765 | if (of_id) | ||
766 | sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; | ||
767 | |||
768 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); | ||
769 | if (!mc13xxx) | ||
770 | return -ENOMEM; | ||
771 | |||
772 | dev_set_drvdata(&spi->dev, mc13xxx); | ||
773 | spi->mode = SPI_MODE_0 | SPI_CS_HIGH; | ||
774 | spi->bits_per_word = 32; | ||
775 | spi_setup(spi); | ||
776 | |||
777 | mc13xxx->spidev = spi; | ||
778 | |||
779 | mutex_init(&mc13xxx->lock); | ||
780 | mc13xxx_lock(mc13xxx); | 657 | mc13xxx_lock(mc13xxx); |
781 | 658 | ||
782 | ret = mc13xxx_identify(mc13xxx, &id); | 659 | ret = mc13xxx_identify(mc13xxx); |
783 | if (ret || id == MC13XXX_ID_INVALID) | 660 | if (ret) |
784 | goto err_revision; | 661 | goto err_revision; |
785 | 662 | ||
786 | /* mask all irqs */ | 663 | /* mask all irqs */ |
@@ -792,18 +669,19 @@ static int mc13xxx_probe(struct spi_device *spi) | |||
792 | if (ret) | 669 | if (ret) |
793 | goto err_mask; | 670 | goto err_mask; |
794 | 671 | ||
795 | ret = request_threaded_irq(spi->irq, NULL, mc13xxx_irq_thread, | 672 | ret = request_threaded_irq(irq, NULL, mc13xxx_irq_thread, |
796 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); | 673 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); |
797 | 674 | ||
798 | if (ret) { | 675 | if (ret) { |
799 | err_mask: | 676 | err_mask: |
800 | err_revision: | 677 | err_revision: |
801 | mc13xxx_unlock(mc13xxx); | 678 | mc13xxx_unlock(mc13xxx); |
802 | dev_set_drvdata(&spi->dev, NULL); | ||
803 | kfree(mc13xxx); | 679 | kfree(mc13xxx); |
804 | return ret; | 680 | return ret; |
805 | } | 681 | } |
806 | 682 | ||
683 | mc13xxx->irq = irq; | ||
684 | |||
807 | mc13xxx_unlock(mc13xxx); | 685 | mc13xxx_unlock(mc13xxx); |
808 | 686 | ||
809 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) | 687 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) |
@@ -838,42 +716,19 @@ err_revision: | |||
838 | 716 | ||
839 | return 0; | 717 | return 0; |
840 | } | 718 | } |
719 | EXPORT_SYMBOL_GPL(mc13xxx_common_init); | ||
841 | 720 | ||
842 | static int __devexit mc13xxx_remove(struct spi_device *spi) | 721 | void mc13xxx_common_cleanup(struct mc13xxx *mc13xxx) |
843 | { | 722 | { |
844 | struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); | 723 | free_irq(mc13xxx->irq, mc13xxx); |
845 | 724 | ||
846 | free_irq(mc13xxx->spidev->irq, mc13xxx); | 725 | mfd_remove_devices(mc13xxx->dev); |
847 | 726 | ||
848 | mfd_remove_devices(&spi->dev); | 727 | regmap_exit(mc13xxx->regmap); |
849 | 728 | ||
850 | kfree(mc13xxx); | 729 | kfree(mc13xxx); |
851 | |||
852 | return 0; | ||
853 | } | ||
854 | |||
855 | static struct spi_driver mc13xxx_driver = { | ||
856 | .id_table = mc13xxx_device_id, | ||
857 | .driver = { | ||
858 | .name = "mc13xxx", | ||
859 | .owner = THIS_MODULE, | ||
860 | .of_match_table = mc13xxx_dt_ids, | ||
861 | }, | ||
862 | .probe = mc13xxx_probe, | ||
863 | .remove = __devexit_p(mc13xxx_remove), | ||
864 | }; | ||
865 | |||
866 | static int __init mc13xxx_init(void) | ||
867 | { | ||
868 | return spi_register_driver(&mc13xxx_driver); | ||
869 | } | ||
870 | subsys_initcall(mc13xxx_init); | ||
871 | |||
872 | static void __exit mc13xxx_exit(void) | ||
873 | { | ||
874 | spi_unregister_driver(&mc13xxx_driver); | ||
875 | } | 730 | } |
876 | module_exit(mc13xxx_exit); | 731 | EXPORT_SYMBOL_GPL(mc13xxx_common_cleanup); |
877 | 732 | ||
878 | MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC"); | 733 | MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC"); |
879 | MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); | 734 | MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); |
diff --git a/drivers/mfd/mc13xxx-i2c.c b/drivers/mfd/mc13xxx-i2c.c new file mode 100644 index 000000000000..d22501dad6a6 --- /dev/null +++ b/drivers/mfd/mc13xxx-i2c.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Copyright 2009-2010 Creative Product Design | ||
3 | * Marc Reilly marc@cpdesign.com.au | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | ||
6 | * the terms of the GNU General Public License version 2 as published by the | ||
7 | * Free Software Foundation. | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/mfd/core.h> | ||
15 | #include <linux/mfd/mc13xxx.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/of_gpio.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/err.h> | ||
21 | |||
22 | #include "mc13xxx.h" | ||
23 | |||
24 | static const struct i2c_device_id mc13xxx_i2c_device_id[] = { | ||
25 | { | ||
26 | .name = "mc13892", | ||
27 | .driver_data = MC13XXX_ID_MC13892, | ||
28 | }, { | ||
29 | /* sentinel */ | ||
30 | } | ||
31 | }; | ||
32 | MODULE_DEVICE_TABLE(i2c, mc13xxx_i2c_device_id); | ||
33 | |||
34 | static const struct of_device_id mc13xxx_dt_ids[] = { | ||
35 | { | ||
36 | .compatible = "fsl,mc13892", | ||
37 | .data = (void *) &mc13xxx_i2c_device_id[0], | ||
38 | }, { | ||
39 | /* sentinel */ | ||
40 | } | ||
41 | }; | ||
42 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); | ||
43 | |||
44 | static struct regmap_config mc13xxx_regmap_i2c_config = { | ||
45 | .reg_bits = 8, | ||
46 | .val_bits = 24, | ||
47 | |||
48 | .max_register = MC13XXX_NUMREGS, | ||
49 | |||
50 | .cache_type = REGCACHE_NONE, | ||
51 | }; | ||
52 | |||
53 | static int mc13xxx_i2c_probe(struct i2c_client *client, | ||
54 | const struct i2c_device_id *id) | ||
55 | { | ||
56 | const struct of_device_id *of_id; | ||
57 | struct i2c_driver *idrv = to_i2c_driver(client->dev.driver); | ||
58 | struct mc13xxx *mc13xxx; | ||
59 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&client->dev); | ||
60 | int ret; | ||
61 | |||
62 | of_id = of_match_device(mc13xxx_dt_ids, &client->dev); | ||
63 | if (of_id) | ||
64 | idrv->id_table = (const struct i2c_device_id*) of_id->data; | ||
65 | |||
66 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); | ||
67 | if (!mc13xxx) | ||
68 | return -ENOMEM; | ||
69 | |||
70 | dev_set_drvdata(&client->dev, mc13xxx); | ||
71 | |||
72 | mc13xxx->dev = &client->dev; | ||
73 | mutex_init(&mc13xxx->lock); | ||
74 | |||
75 | mc13xxx->regmap = regmap_init_i2c(client, &mc13xxx_regmap_i2c_config); | ||
76 | if (IS_ERR(mc13xxx->regmap)) { | ||
77 | ret = PTR_ERR(mc13xxx->regmap); | ||
78 | dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", | ||
79 | ret); | ||
80 | dev_set_drvdata(&client->dev, NULL); | ||
81 | kfree(mc13xxx); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | ret = mc13xxx_common_init(mc13xxx, pdata, client->irq); | ||
86 | |||
87 | if (ret == 0 && (id->driver_data != mc13xxx->ictype)) | ||
88 | dev_warn(mc13xxx->dev, | ||
89 | "device id doesn't match auto detection!\n"); | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | static int __devexit mc13xxx_i2c_remove(struct i2c_client *client) | ||
95 | { | ||
96 | struct mc13xxx *mc13xxx = dev_get_drvdata(&client->dev); | ||
97 | |||
98 | mc13xxx_common_cleanup(mc13xxx); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static struct i2c_driver mc13xxx_i2c_driver = { | ||
104 | .id_table = mc13xxx_i2c_device_id, | ||
105 | .driver = { | ||
106 | .owner = THIS_MODULE, | ||
107 | .name = "mc13xxx", | ||
108 | .of_match_table = mc13xxx_dt_ids, | ||
109 | }, | ||
110 | .probe = mc13xxx_i2c_probe, | ||
111 | .remove = __devexit_p(mc13xxx_i2c_remove), | ||
112 | }; | ||
113 | |||
114 | static int __init mc13xxx_i2c_init(void) | ||
115 | { | ||
116 | return i2c_add_driver(&mc13xxx_i2c_driver); | ||
117 | } | ||
118 | subsys_initcall(mc13xxx_i2c_init); | ||
119 | |||
120 | static void __exit mc13xxx_i2c_exit(void) | ||
121 | { | ||
122 | i2c_del_driver(&mc13xxx_i2c_driver); | ||
123 | } | ||
124 | module_exit(mc13xxx_i2c_exit); | ||
125 | |||
126 | MODULE_DESCRIPTION("i2c driver for Freescale MC13XXX PMIC"); | ||
127 | MODULE_AUTHOR("Marc Reilly <marc@cpdesign.com.au"); | ||
128 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c new file mode 100644 index 000000000000..3fcdab3eb8eb --- /dev/null +++ b/drivers/mfd/mc13xxx-spi.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * Copyright 2009-2010 Pengutronix | ||
3 | * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de> | ||
4 | * | ||
5 | * loosely based on an earlier driver that has | ||
6 | * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it under | ||
9 | * the terms of the GNU General Public License version 2 as published by the | ||
10 | * Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mutex.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/mfd/core.h> | ||
19 | #include <linux/mfd/mc13xxx.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_device.h> | ||
22 | #include <linux/of_gpio.h> | ||
23 | #include <linux/err.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | |||
26 | #include "mc13xxx.h" | ||
27 | |||
28 | static const struct spi_device_id mc13xxx_device_id[] = { | ||
29 | { | ||
30 | .name = "mc13783", | ||
31 | .driver_data = MC13XXX_ID_MC13783, | ||
32 | }, { | ||
33 | .name = "mc13892", | ||
34 | .driver_data = MC13XXX_ID_MC13892, | ||
35 | }, { | ||
36 | /* sentinel */ | ||
37 | } | ||
38 | }; | ||
39 | MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); | ||
40 | |||
41 | static const struct of_device_id mc13xxx_dt_ids[] = { | ||
42 | { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, }, | ||
43 | { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, }, | ||
44 | { /* sentinel */ } | ||
45 | }; | ||
46 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); | ||
47 | |||
48 | static struct regmap_config mc13xxx_regmap_spi_config = { | ||
49 | .reg_bits = 7, | ||
50 | .pad_bits = 1, | ||
51 | .val_bits = 24, | ||
52 | |||
53 | .max_register = MC13XXX_NUMREGS, | ||
54 | |||
55 | .cache_type = REGCACHE_NONE, | ||
56 | }; | ||
57 | |||
58 | static int mc13xxx_spi_probe(struct spi_device *spi) | ||
59 | { | ||
60 | const struct of_device_id *of_id; | ||
61 | struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); | ||
62 | struct mc13xxx *mc13xxx; | ||
63 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); | ||
64 | int ret; | ||
65 | |||
66 | of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); | ||
67 | if (of_id) | ||
68 | sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; | ||
69 | |||
70 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); | ||
71 | if (!mc13xxx) | ||
72 | return -ENOMEM; | ||
73 | |||
74 | dev_set_drvdata(&spi->dev, mc13xxx); | ||
75 | spi->mode = SPI_MODE_0 | SPI_CS_HIGH; | ||
76 | spi->bits_per_word = 32; | ||
77 | |||
78 | mc13xxx->dev = &spi->dev; | ||
79 | mutex_init(&mc13xxx->lock); | ||
80 | |||
81 | mc13xxx->regmap = regmap_init_spi(spi, &mc13xxx_regmap_spi_config); | ||
82 | if (IS_ERR(mc13xxx->regmap)) { | ||
83 | ret = PTR_ERR(mc13xxx->regmap); | ||
84 | dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", | ||
85 | ret); | ||
86 | dev_set_drvdata(&spi->dev, NULL); | ||
87 | kfree(mc13xxx); | ||
88 | return ret; | ||
89 | } | ||
90 | |||
91 | ret = mc13xxx_common_init(mc13xxx, pdata, spi->irq); | ||
92 | |||
93 | if (ret) { | ||
94 | dev_set_drvdata(&spi->dev, NULL); | ||
95 | } else { | ||
96 | const struct spi_device_id *devid = | ||
97 | spi_get_device_id(spi); | ||
98 | if (!devid || devid->driver_data != mc13xxx->ictype) | ||
99 | dev_warn(mc13xxx->dev, | ||
100 | "device id doesn't match auto detection!\n"); | ||
101 | } | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | static int __devexit mc13xxx_spi_remove(struct spi_device *spi) | ||
107 | { | ||
108 | struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); | ||
109 | |||
110 | mc13xxx_common_cleanup(mc13xxx); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static struct spi_driver mc13xxx_spi_driver = { | ||
116 | .id_table = mc13xxx_device_id, | ||
117 | .driver = { | ||
118 | .name = "mc13xxx", | ||
119 | .owner = THIS_MODULE, | ||
120 | .of_match_table = mc13xxx_dt_ids, | ||
121 | }, | ||
122 | .probe = mc13xxx_spi_probe, | ||
123 | .remove = __devexit_p(mc13xxx_spi_remove), | ||
124 | }; | ||
125 | |||
126 | static int __init mc13xxx_init(void) | ||
127 | { | ||
128 | return spi_register_driver(&mc13xxx_spi_driver); | ||
129 | } | ||
130 | subsys_initcall(mc13xxx_init); | ||
131 | |||
132 | static void __exit mc13xxx_exit(void) | ||
133 | { | ||
134 | spi_unregister_driver(&mc13xxx_spi_driver); | ||
135 | } | ||
136 | module_exit(mc13xxx_exit); | ||
137 | |||
138 | MODULE_DESCRIPTION("Core driver for Freescale MC13XXX PMIC"); | ||
139 | MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>"); | ||
140 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/mc13xxx.h b/drivers/mfd/mc13xxx.h new file mode 100644 index 000000000000..bbba06feea06 --- /dev/null +++ b/drivers/mfd/mc13xxx.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Creative Product Design | ||
3 | * Marc Reilly <marc@cpdesign.com.au> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it under | ||
6 | * the terms of the GNU General Public License version 2 as published by the | ||
7 | * Free Software Foundation. | ||
8 | */ | ||
9 | #ifndef __DRIVERS_MFD_MC13XXX_H | ||
10 | #define __DRIVERS_MFD_MC13XXX_H | ||
11 | |||
12 | #include <linux/mutex.h> | ||
13 | #include <linux/regmap.h> | ||
14 | #include <linux/mfd/mc13xxx.h> | ||
15 | |||
16 | enum mc13xxx_id { | ||
17 | MC13XXX_ID_MC13783, | ||
18 | MC13XXX_ID_MC13892, | ||
19 | MC13XXX_ID_INVALID, | ||
20 | }; | ||
21 | |||
22 | #define MC13XXX_NUMREGS 0x3f | ||
23 | |||
24 | struct mc13xxx { | ||
25 | struct regmap *regmap; | ||
26 | |||
27 | struct device *dev; | ||
28 | enum mc13xxx_id ictype; | ||
29 | |||
30 | struct mutex lock; | ||
31 | int irq; | ||
32 | int flags; | ||
33 | |||
34 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; | ||
35 | void *irqdata[MC13XXX_NUM_IRQ]; | ||
36 | |||
37 | int adcflags; | ||
38 | }; | ||
39 | |||
40 | int mc13xxx_common_init(struct mc13xxx *mc13xxx, | ||
41 | struct mc13xxx_platform_data *pdata, int irq); | ||
42 | |||
43 | void mc13xxx_common_cleanup(struct mc13xxx *mc13xxx); | ||
44 | |||
45 | #endif /* __DRIVERS_MFD_MC13XXX_H */ | ||
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 189c2f07b83f..29c122bf28ea 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c | |||
@@ -204,7 +204,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
204 | return -ENOENT; | 204 | return -ENOENT; |
205 | } | 205 | } |
206 | 206 | ||
207 | pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); | 207 | pcf = devm_kzalloc(&client->dev, sizeof(*pcf), GFP_KERNEL); |
208 | if (!pcf) | 208 | if (!pcf) |
209 | return -ENOMEM; | 209 | return -ENOMEM; |
210 | 210 | ||
@@ -212,12 +212,11 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
212 | 212 | ||
213 | mutex_init(&pcf->lock); | 213 | mutex_init(&pcf->lock); |
214 | 214 | ||
215 | pcf->regmap = regmap_init_i2c(client, &pcf50633_regmap_config); | 215 | pcf->regmap = devm_regmap_init_i2c(client, &pcf50633_regmap_config); |
216 | if (IS_ERR(pcf->regmap)) { | 216 | if (IS_ERR(pcf->regmap)) { |
217 | ret = PTR_ERR(pcf->regmap); | 217 | ret = PTR_ERR(pcf->regmap); |
218 | dev_err(pcf->dev, "Failed to allocate register map: %d\n", | 218 | dev_err(pcf->dev, "Failed to allocate register map: %d\n", ret); |
219 | ret); | 219 | return ret; |
220 | goto err_free; | ||
221 | } | 220 | } |
222 | 221 | ||
223 | i2c_set_clientdata(client, pcf); | 222 | i2c_set_clientdata(client, pcf); |
@@ -228,7 +227,7 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
228 | if (version < 0 || variant < 0) { | 227 | if (version < 0 || variant < 0) { |
229 | dev_err(pcf->dev, "Unable to probe pcf50633\n"); | 228 | dev_err(pcf->dev, "Unable to probe pcf50633\n"); |
230 | ret = -ENODEV; | 229 | ret = -ENODEV; |
231 | goto err_regmap; | 230 | return ret; |
232 | } | 231 | } |
233 | 232 | ||
234 | dev_info(pcf->dev, "Probed device version %d variant %d\n", | 233 | dev_info(pcf->dev, "Probed device version %d variant %d\n", |
@@ -237,16 +236,11 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
237 | pcf50633_irq_init(pcf, client->irq); | 236 | pcf50633_irq_init(pcf, client->irq); |
238 | 237 | ||
239 | /* Create sub devices */ | 238 | /* Create sub devices */ |
240 | pcf50633_client_dev_register(pcf, "pcf50633-input", | 239 | pcf50633_client_dev_register(pcf, "pcf50633-input", &pcf->input_pdev); |
241 | &pcf->input_pdev); | 240 | pcf50633_client_dev_register(pcf, "pcf50633-rtc", &pcf->rtc_pdev); |
242 | pcf50633_client_dev_register(pcf, "pcf50633-rtc", | 241 | pcf50633_client_dev_register(pcf, "pcf50633-mbc", &pcf->mbc_pdev); |
243 | &pcf->rtc_pdev); | 242 | pcf50633_client_dev_register(pcf, "pcf50633-adc", &pcf->adc_pdev); |
244 | pcf50633_client_dev_register(pcf, "pcf50633-mbc", | 243 | pcf50633_client_dev_register(pcf, "pcf50633-backlight", &pcf->bl_pdev); |
245 | &pcf->mbc_pdev); | ||
246 | pcf50633_client_dev_register(pcf, "pcf50633-adc", | ||
247 | &pcf->adc_pdev); | ||
248 | pcf50633_client_dev_register(pcf, "pcf50633-backlight", | ||
249 | &pcf->bl_pdev); | ||
250 | 244 | ||
251 | 245 | ||
252 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { | 246 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { |
@@ -274,13 +268,6 @@ static int __devinit pcf50633_probe(struct i2c_client *client, | |||
274 | pdata->probe_done(pcf); | 268 | pdata->probe_done(pcf); |
275 | 269 | ||
276 | return 0; | 270 | return 0; |
277 | |||
278 | err_regmap: | ||
279 | regmap_exit(pcf->regmap); | ||
280 | err_free: | ||
281 | kfree(pcf); | ||
282 | |||
283 | return ret; | ||
284 | } | 271 | } |
285 | 272 | ||
286 | static int __devexit pcf50633_remove(struct i2c_client *client) | 273 | static int __devexit pcf50633_remove(struct i2c_client *client) |
@@ -300,9 +287,6 @@ static int __devexit pcf50633_remove(struct i2c_client *client) | |||
300 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) | 287 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) |
301 | platform_device_unregister(pcf->regulator_pdev[i]); | 288 | platform_device_unregister(pcf->regulator_pdev[i]); |
302 | 289 | ||
303 | regmap_exit(pcf->regmap); | ||
304 | kfree(pcf); | ||
305 | |||
306 | return 0; | 290 | return 0; |
307 | } | 291 | } |
308 | 292 | ||
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index 44afae0a69ce..cdc1df7fa0e9 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c | |||
@@ -75,6 +75,7 @@ static struct deepsleep_control_data deepsleep_data[] = { | |||
75 | (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL) | 75 | (RC5T583_EXT_PWRREQ1_CONTROL | RC5T583_EXT_PWRREQ2_CONTROL) |
76 | 76 | ||
77 | static struct mfd_cell rc5t583_subdevs[] = { | 77 | static struct mfd_cell rc5t583_subdevs[] = { |
78 | {.name = "rc5t583-gpio",}, | ||
78 | {.name = "rc5t583-regulator",}, | 79 | {.name = "rc5t583-regulator",}, |
79 | {.name = "rc5t583-rtc", }, | 80 | {.name = "rc5t583-rtc", }, |
80 | {.name = "rc5t583-key", } | 81 | {.name = "rc5t583-key", } |
@@ -267,7 +268,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, | |||
267 | rc5t583->dev = &i2c->dev; | 268 | rc5t583->dev = &i2c->dev; |
268 | i2c_set_clientdata(i2c, rc5t583); | 269 | i2c_set_clientdata(i2c, rc5t583); |
269 | 270 | ||
270 | rc5t583->regmap = regmap_init_i2c(i2c, &rc5t583_regmap_config); | 271 | rc5t583->regmap = devm_regmap_init_i2c(i2c, &rc5t583_regmap_config); |
271 | if (IS_ERR(rc5t583->regmap)) { | 272 | if (IS_ERR(rc5t583->regmap)) { |
272 | ret = PTR_ERR(rc5t583->regmap); | 273 | ret = PTR_ERR(rc5t583->regmap); |
273 | dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); | 274 | dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); |
@@ -276,7 +277,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, | |||
276 | 277 | ||
277 | ret = rc5t583_clear_ext_power_req(rc5t583, pdata); | 278 | ret = rc5t583_clear_ext_power_req(rc5t583, pdata); |
278 | if (ret < 0) | 279 | if (ret < 0) |
279 | goto err_irq_init; | 280 | return ret; |
280 | 281 | ||
281 | if (i2c->irq) { | 282 | if (i2c->irq) { |
282 | ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base); | 283 | ret = rc5t583_irq_init(rc5t583, i2c->irq, pdata->irq_base); |
@@ -299,8 +300,6 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, | |||
299 | err_add_devs: | 300 | err_add_devs: |
300 | if (irq_init_success) | 301 | if (irq_init_success) |
301 | rc5t583_irq_exit(rc5t583); | 302 | rc5t583_irq_exit(rc5t583); |
302 | err_irq_init: | ||
303 | regmap_exit(rc5t583->regmap); | ||
304 | return ret; | 303 | return ret; |
305 | } | 304 | } |
306 | 305 | ||
@@ -310,7 +309,6 @@ static int __devexit rc5t583_i2c_remove(struct i2c_client *i2c) | |||
310 | 309 | ||
311 | mfd_remove_devices(rc5t583->dev); | 310 | mfd_remove_devices(rc5t583->dev); |
312 | rc5t583_irq_exit(rc5t583); | 311 | rc5t583_irq_exit(rc5t583); |
313 | regmap_exit(rc5t583->regmap); | ||
314 | return 0; | 312 | return 0; |
315 | } | 313 | } |
316 | 314 | ||
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 809bd4a61089..685d61e431ad 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -108,18 +108,7 @@ static struct pci_driver rdc321x_sb_driver = { | |||
108 | .remove = __devexit_p(rdc321x_sb_remove), | 108 | .remove = __devexit_p(rdc321x_sb_remove), |
109 | }; | 109 | }; |
110 | 110 | ||
111 | static int __init rdc321x_sb_init(void) | 111 | module_pci_driver(rdc321x_sb_driver); |
112 | { | ||
113 | return pci_register_driver(&rdc321x_sb_driver); | ||
114 | } | ||
115 | |||
116 | static void __exit rdc321x_sb_exit(void) | ||
117 | { | ||
118 | pci_unregister_driver(&rdc321x_sb_driver); | ||
119 | } | ||
120 | |||
121 | module_init(rdc321x_sb_init); | ||
122 | module_exit(rdc321x_sb_exit); | ||
123 | 112 | ||
124 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); | 113 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); |
125 | MODULE_LICENSE("GPL"); | 114 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c index 48949d998d10..dd170307e60e 100644 --- a/drivers/mfd/s5m-core.c +++ b/drivers/mfd/s5m-core.c | |||
@@ -114,12 +114,12 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c, | |||
114 | s5m87xx->wakeup = pdata->wakeup; | 114 | s5m87xx->wakeup = pdata->wakeup; |
115 | } | 115 | } |
116 | 116 | ||
117 | s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config); | 117 | s5m87xx->regmap = devm_regmap_init_i2c(i2c, &s5m_regmap_config); |
118 | if (IS_ERR(s5m87xx->regmap)) { | 118 | if (IS_ERR(s5m87xx->regmap)) { |
119 | ret = PTR_ERR(s5m87xx->regmap); | 119 | ret = PTR_ERR(s5m87xx->regmap); |
120 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 120 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
121 | ret); | 121 | ret); |
122 | goto err; | 122 | return ret; |
123 | } | 123 | } |
124 | 124 | ||
125 | s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); | 125 | s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); |
@@ -159,7 +159,6 @@ err: | |||
159 | mfd_remove_devices(s5m87xx->dev); | 159 | mfd_remove_devices(s5m87xx->dev); |
160 | s5m_irq_exit(s5m87xx); | 160 | s5m_irq_exit(s5m87xx); |
161 | i2c_unregister_device(s5m87xx->rtc); | 161 | i2c_unregister_device(s5m87xx->rtc); |
162 | regmap_exit(s5m87xx->regmap); | ||
163 | return ret; | 162 | return ret; |
164 | } | 163 | } |
165 | 164 | ||
@@ -170,7 +169,6 @@ static int s5m87xx_i2c_remove(struct i2c_client *i2c) | |||
170 | mfd_remove_devices(s5m87xx->dev); | 169 | mfd_remove_devices(s5m87xx->dev); |
171 | s5m_irq_exit(s5m87xx); | 170 | s5m_irq_exit(s5m87xx); |
172 | i2c_unregister_device(s5m87xx->rtc); | 171 | i2c_unregister_device(s5m87xx->rtc); |
173 | regmap_exit(s5m87xx->regmap); | ||
174 | return 0; | 172 | return 0; |
175 | } | 173 | } |
176 | 174 | ||
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c new file mode 100644 index 000000000000..d31fed07aefb --- /dev/null +++ b/drivers/mfd/sta2x11-mfd.c | |||
@@ -0,0 +1,467 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009-2011 Wind River Systems, Inc. | ||
3 | * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini) | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
12 | * See the GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/spinlock.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/device.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/pci.h> | ||
30 | #include <linux/debugfs.h> | ||
31 | #include <linux/seq_file.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/mfd/core.h> | ||
34 | #include <linux/mfd/sta2x11-mfd.h> | ||
35 | |||
36 | #include <asm/sta2x11.h> | ||
37 | |||
38 | /* This describes STA2X11 MFD chip for us, we may have several */ | ||
39 | struct sta2x11_mfd { | ||
40 | struct sta2x11_instance *instance; | ||
41 | spinlock_t lock; | ||
42 | struct list_head list; | ||
43 | void __iomem *sctl_regs; | ||
44 | void __iomem *apbreg_regs; | ||
45 | }; | ||
46 | |||
47 | static LIST_HEAD(sta2x11_mfd_list); | ||
48 | |||
49 | /* Three functions to act on the list */ | ||
50 | static struct sta2x11_mfd *sta2x11_mfd_find(struct pci_dev *pdev) | ||
51 | { | ||
52 | struct sta2x11_instance *instance; | ||
53 | struct sta2x11_mfd *mfd; | ||
54 | |||
55 | if (!pdev && !list_empty(&sta2x11_mfd_list)) { | ||
56 | pr_warning("%s: Unspecified device, " | ||
57 | "using first instance\n", __func__); | ||
58 | return list_entry(sta2x11_mfd_list.next, | ||
59 | struct sta2x11_mfd, list); | ||
60 | } | ||
61 | |||
62 | instance = sta2x11_get_instance(pdev); | ||
63 | if (!instance) | ||
64 | return NULL; | ||
65 | list_for_each_entry(mfd, &sta2x11_mfd_list, list) { | ||
66 | if (mfd->instance == instance) | ||
67 | return mfd; | ||
68 | } | ||
69 | return NULL; | ||
70 | } | ||
71 | |||
72 | static int __devinit sta2x11_mfd_add(struct pci_dev *pdev, gfp_t flags) | ||
73 | { | ||
74 | struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); | ||
75 | struct sta2x11_instance *instance; | ||
76 | |||
77 | if (mfd) | ||
78 | return -EBUSY; | ||
79 | instance = sta2x11_get_instance(pdev); | ||
80 | if (!instance) | ||
81 | return -EINVAL; | ||
82 | mfd = kzalloc(sizeof(*mfd), flags); | ||
83 | if (!mfd) | ||
84 | return -ENOMEM; | ||
85 | INIT_LIST_HEAD(&mfd->list); | ||
86 | spin_lock_init(&mfd->lock); | ||
87 | mfd->instance = instance; | ||
88 | list_add(&mfd->list, &sta2x11_mfd_list); | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int __devexit mfd_remove(struct pci_dev *pdev) | ||
93 | { | ||
94 | struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); | ||
95 | |||
96 | if (!mfd) | ||
97 | return -ENODEV; | ||
98 | list_del(&mfd->list); | ||
99 | kfree(mfd); | ||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | /* These two functions are exported and are not expected to fail */ | ||
104 | u32 sta2x11_sctl_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val) | ||
105 | { | ||
106 | struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); | ||
107 | u32 r; | ||
108 | unsigned long flags; | ||
109 | |||
110 | if (!mfd) { | ||
111 | dev_warn(&pdev->dev, ": can't access sctl regs\n"); | ||
112 | return 0; | ||
113 | } | ||
114 | if (!mfd->sctl_regs) { | ||
115 | dev_warn(&pdev->dev, ": system ctl not initialized\n"); | ||
116 | return 0; | ||
117 | } | ||
118 | spin_lock_irqsave(&mfd->lock, flags); | ||
119 | r = readl(mfd->sctl_regs + reg); | ||
120 | r &= ~mask; | ||
121 | r |= val; | ||
122 | if (mask) | ||
123 | writel(r, mfd->sctl_regs + reg); | ||
124 | spin_unlock_irqrestore(&mfd->lock, flags); | ||
125 | return r; | ||
126 | } | ||
127 | EXPORT_SYMBOL(sta2x11_sctl_mask); | ||
128 | |||
129 | u32 sta2x11_apbreg_mask(struct pci_dev *pdev, u32 reg, u32 mask, u32 val) | ||
130 | { | ||
131 | struct sta2x11_mfd *mfd = sta2x11_mfd_find(pdev); | ||
132 | u32 r; | ||
133 | unsigned long flags; | ||
134 | |||
135 | if (!mfd) { | ||
136 | dev_warn(&pdev->dev, ": can't access apb regs\n"); | ||
137 | return 0; | ||
138 | } | ||
139 | if (!mfd->apbreg_regs) { | ||
140 | dev_warn(&pdev->dev, ": apb bridge not initialized\n"); | ||
141 | return 0; | ||
142 | } | ||
143 | spin_lock_irqsave(&mfd->lock, flags); | ||
144 | r = readl(mfd->apbreg_regs + reg); | ||
145 | r &= ~mask; | ||
146 | r |= val; | ||
147 | if (mask) | ||
148 | writel(r, mfd->apbreg_regs + reg); | ||
149 | spin_unlock_irqrestore(&mfd->lock, flags); | ||
150 | return r; | ||
151 | } | ||
152 | EXPORT_SYMBOL(sta2x11_apbreg_mask); | ||
153 | |||
154 | /* Two debugfs files, for our registers (FIXME: one instance only) */ | ||
155 | #define REG(regname) {.name = #regname, .offset = SCTL_ ## regname} | ||
156 | static struct debugfs_reg32 sta2x11_sctl_regs[] = { | ||
157 | REG(SCCTL), REG(ARMCFG), REG(SCPLLCTL), REG(SCPLLFCTRL), | ||
158 | REG(SCRESFRACT), REG(SCRESCTRL1), REG(SCRESXTRL2), REG(SCPEREN0), | ||
159 | REG(SCPEREN1), REG(SCPEREN2), REG(SCGRST), REG(SCPCIPMCR1), | ||
160 | REG(SCPCIPMCR2), REG(SCPCIPMSR1), REG(SCPCIPMSR2), REG(SCPCIPMSR3), | ||
161 | REG(SCINTREN), REG(SCRISR), REG(SCCLKSTAT0), REG(SCCLKSTAT1), | ||
162 | REG(SCCLKSTAT2), REG(SCRSTSTA), | ||
163 | }; | ||
164 | #undef REG | ||
165 | |||
166 | static struct debugfs_regset32 sctl_regset = { | ||
167 | .regs = sta2x11_sctl_regs, | ||
168 | .nregs = ARRAY_SIZE(sta2x11_sctl_regs), | ||
169 | }; | ||
170 | |||
171 | #define REG(regname) {.name = #regname, .offset = regname} | ||
172 | static struct debugfs_reg32 sta2x11_apbreg_regs[] = { | ||
173 | REG(APBREG_BSR), REG(APBREG_PAER), REG(APBREG_PWAC), REG(APBREG_PRAC), | ||
174 | REG(APBREG_PCG), REG(APBREG_PUR), REG(APBREG_EMU_PCG), | ||
175 | }; | ||
176 | #undef REG | ||
177 | |||
178 | static struct debugfs_regset32 apbreg_regset = { | ||
179 | .regs = sta2x11_apbreg_regs, | ||
180 | .nregs = ARRAY_SIZE(sta2x11_apbreg_regs), | ||
181 | }; | ||
182 | |||
183 | static struct dentry *sta2x11_sctl_debugfs; | ||
184 | static struct dentry *sta2x11_apbreg_debugfs; | ||
185 | |||
186 | /* Probe for the two platform devices */ | ||
187 | static int sta2x11_sctl_probe(struct platform_device *dev) | ||
188 | { | ||
189 | struct pci_dev **pdev; | ||
190 | struct sta2x11_mfd *mfd; | ||
191 | struct resource *res; | ||
192 | |||
193 | pdev = dev->dev.platform_data; | ||
194 | mfd = sta2x11_mfd_find(*pdev); | ||
195 | if (!mfd) | ||
196 | return -ENODEV; | ||
197 | |||
198 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
199 | if (!res) | ||
200 | return -ENOMEM; | ||
201 | |||
202 | if (!request_mem_region(res->start, resource_size(res), | ||
203 | "sta2x11-sctl")) | ||
204 | return -EBUSY; | ||
205 | |||
206 | mfd->sctl_regs = ioremap(res->start, resource_size(res)); | ||
207 | if (!mfd->sctl_regs) { | ||
208 | release_mem_region(res->start, resource_size(res)); | ||
209 | return -ENOMEM; | ||
210 | } | ||
211 | sctl_regset.base = mfd->sctl_regs; | ||
212 | sta2x11_sctl_debugfs = debugfs_create_regset32("sta2x11-sctl", | ||
213 | S_IFREG | S_IRUGO, | ||
214 | NULL, &sctl_regset); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int sta2x11_apbreg_probe(struct platform_device *dev) | ||
219 | { | ||
220 | struct pci_dev **pdev; | ||
221 | struct sta2x11_mfd *mfd; | ||
222 | struct resource *res; | ||
223 | |||
224 | pdev = dev->dev.platform_data; | ||
225 | dev_dbg(&dev->dev, "%s: pdata is %p\n", __func__, pdev); | ||
226 | dev_dbg(&dev->dev, "%s: *pdata is %p\n", __func__, *pdev); | ||
227 | |||
228 | mfd = sta2x11_mfd_find(*pdev); | ||
229 | if (!mfd) | ||
230 | return -ENODEV; | ||
231 | |||
232 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
233 | if (!res) | ||
234 | return -ENOMEM; | ||
235 | |||
236 | if (!request_mem_region(res->start, resource_size(res), | ||
237 | "sta2x11-apbreg")) | ||
238 | return -EBUSY; | ||
239 | |||
240 | mfd->apbreg_regs = ioremap(res->start, resource_size(res)); | ||
241 | if (!mfd->apbreg_regs) { | ||
242 | release_mem_region(res->start, resource_size(res)); | ||
243 | return -ENOMEM; | ||
244 | } | ||
245 | dev_dbg(&dev->dev, "%s: regbase %p\n", __func__, mfd->apbreg_regs); | ||
246 | |||
247 | apbreg_regset.base = mfd->apbreg_regs; | ||
248 | sta2x11_apbreg_debugfs = debugfs_create_regset32("sta2x11-apbreg", | ||
249 | S_IFREG | S_IRUGO, | ||
250 | NULL, &apbreg_regset); | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | /* The two platform drivers */ | ||
255 | static struct platform_driver sta2x11_sctl_platform_driver = { | ||
256 | .driver = { | ||
257 | .name = "sta2x11-sctl", | ||
258 | .owner = THIS_MODULE, | ||
259 | }, | ||
260 | .probe = sta2x11_sctl_probe, | ||
261 | }; | ||
262 | |||
263 | static int __init sta2x11_sctl_init(void) | ||
264 | { | ||
265 | pr_info("%s\n", __func__); | ||
266 | return platform_driver_register(&sta2x11_sctl_platform_driver); | ||
267 | } | ||
268 | |||
269 | static struct platform_driver sta2x11_platform_driver = { | ||
270 | .driver = { | ||
271 | .name = "sta2x11-apbreg", | ||
272 | .owner = THIS_MODULE, | ||
273 | }, | ||
274 | .probe = sta2x11_apbreg_probe, | ||
275 | }; | ||
276 | |||
277 | static int __init sta2x11_apbreg_init(void) | ||
278 | { | ||
279 | pr_info("%s\n", __func__); | ||
280 | return platform_driver_register(&sta2x11_platform_driver); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * What follows is the PCI device that hosts the above two pdevs. | ||
285 | * Each logic block is 4kB and they are all consecutive: we use this info. | ||
286 | */ | ||
287 | |||
288 | /* Bar 0 */ | ||
289 | enum bar0_cells { | ||
290 | STA2X11_GPIO_0 = 0, | ||
291 | STA2X11_GPIO_1, | ||
292 | STA2X11_GPIO_2, | ||
293 | STA2X11_GPIO_3, | ||
294 | STA2X11_SCTL, | ||
295 | STA2X11_SCR, | ||
296 | STA2X11_TIME, | ||
297 | }; | ||
298 | /* Bar 1 */ | ||
299 | enum bar1_cells { | ||
300 | STA2X11_APBREG = 0, | ||
301 | }; | ||
302 | #define CELL_4K(_name, _cell) { \ | ||
303 | .name = _name, \ | ||
304 | .start = _cell * 4096, .end = _cell * 4096 + 4095, \ | ||
305 | .flags = IORESOURCE_MEM, \ | ||
306 | } | ||
307 | |||
308 | static const __devinitconst struct resource gpio_resources[] = { | ||
309 | { | ||
310 | .name = "sta2x11_gpio", /* 4 consecutive cells, 1 driver */ | ||
311 | .start = 0, | ||
312 | .end = (4 * 4096) - 1, | ||
313 | .flags = IORESOURCE_MEM, | ||
314 | } | ||
315 | }; | ||
316 | static const __devinitconst struct resource sctl_resources[] = { | ||
317 | CELL_4K("sta2x11-sctl", STA2X11_SCTL), | ||
318 | }; | ||
319 | static const __devinitconst struct resource scr_resources[] = { | ||
320 | CELL_4K("sta2x11-scr", STA2X11_SCR), | ||
321 | }; | ||
322 | static const __devinitconst struct resource time_resources[] = { | ||
323 | CELL_4K("sta2x11-time", STA2X11_TIME), | ||
324 | }; | ||
325 | |||
326 | static const __devinitconst struct resource apbreg_resources[] = { | ||
327 | CELL_4K("sta2x11-apbreg", STA2X11_APBREG), | ||
328 | }; | ||
329 | |||
330 | #define DEV(_name, _r) \ | ||
331 | { .name = _name, .num_resources = ARRAY_SIZE(_r), .resources = _r, } | ||
332 | |||
333 | static __devinitdata struct mfd_cell sta2x11_mfd_bar0[] = { | ||
334 | DEV("sta2x11-gpio", gpio_resources), /* offset 0: we add pdata later */ | ||
335 | DEV("sta2x11-sctl", sctl_resources), | ||
336 | DEV("sta2x11-scr", scr_resources), | ||
337 | DEV("sta2x11-time", time_resources), | ||
338 | }; | ||
339 | |||
340 | static __devinitdata struct mfd_cell sta2x11_mfd_bar1[] = { | ||
341 | DEV("sta2x11-apbreg", apbreg_resources), | ||
342 | }; | ||
343 | |||
344 | static int sta2x11_mfd_suspend(struct pci_dev *pdev, pm_message_t state) | ||
345 | { | ||
346 | pci_save_state(pdev); | ||
347 | pci_disable_device(pdev); | ||
348 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int sta2x11_mfd_resume(struct pci_dev *pdev) | ||
354 | { | ||
355 | int err; | ||
356 | |||
357 | pci_set_power_state(pdev, 0); | ||
358 | err = pci_enable_device(pdev); | ||
359 | if (err) | ||
360 | return err; | ||
361 | pci_restore_state(pdev); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | ||
367 | const struct pci_device_id *pci_id) | ||
368 | { | ||
369 | int err, i; | ||
370 | struct sta2x11_gpio_pdata *gpio_data; | ||
371 | |||
372 | dev_info(&pdev->dev, "%s\n", __func__); | ||
373 | |||
374 | err = pci_enable_device(pdev); | ||
375 | if (err) { | ||
376 | dev_err(&pdev->dev, "Can't enable device.\n"); | ||
377 | return err; | ||
378 | } | ||
379 | |||
380 | err = pci_enable_msi(pdev); | ||
381 | if (err) | ||
382 | dev_info(&pdev->dev, "Enable msi failed\n"); | ||
383 | |||
384 | /* Read gpio config data as pci device's platform data */ | ||
385 | gpio_data = dev_get_platdata(&pdev->dev); | ||
386 | if (!gpio_data) | ||
387 | dev_warn(&pdev->dev, "no gpio configuration\n"); | ||
388 | |||
389 | dev_dbg(&pdev->dev, "%s, gpio_data = %p (%p)\n", __func__, | ||
390 | gpio_data, &gpio_data); | ||
391 | dev_dbg(&pdev->dev, "%s, pdev = %p (%p)\n", __func__, | ||
392 | pdev, &pdev); | ||
393 | |||
394 | /* platform data is the pci device for all of them */ | ||
395 | for (i = 0; i < ARRAY_SIZE(sta2x11_mfd_bar0); i++) { | ||
396 | sta2x11_mfd_bar0[i].pdata_size = sizeof(pdev); | ||
397 | sta2x11_mfd_bar0[i].platform_data = &pdev; | ||
398 | } | ||
399 | sta2x11_mfd_bar1[0].pdata_size = sizeof(pdev); | ||
400 | sta2x11_mfd_bar1[0].platform_data = &pdev; | ||
401 | |||
402 | /* Record this pdev before mfd_add_devices: their probe looks for it */ | ||
403 | sta2x11_mfd_add(pdev, GFP_ATOMIC); | ||
404 | |||
405 | |||
406 | err = mfd_add_devices(&pdev->dev, -1, | ||
407 | sta2x11_mfd_bar0, | ||
408 | ARRAY_SIZE(sta2x11_mfd_bar0), | ||
409 | &pdev->resource[0], | ||
410 | 0); | ||
411 | if (err) { | ||
412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); | ||
413 | goto err_disable; | ||
414 | } | ||
415 | |||
416 | err = mfd_add_devices(&pdev->dev, -1, | ||
417 | sta2x11_mfd_bar1, | ||
418 | ARRAY_SIZE(sta2x11_mfd_bar1), | ||
419 | &pdev->resource[1], | ||
420 | 0); | ||
421 | if (err) { | ||
422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); | ||
423 | goto err_disable; | ||
424 | } | ||
425 | |||
426 | return 0; | ||
427 | |||
428 | err_disable: | ||
429 | mfd_remove_devices(&pdev->dev); | ||
430 | pci_disable_device(pdev); | ||
431 | pci_disable_msi(pdev); | ||
432 | return err; | ||
433 | } | ||
434 | |||
435 | static DEFINE_PCI_DEVICE_TABLE(sta2x11_mfd_tbl) = { | ||
436 | {PCI_DEVICE(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_GPIO)}, | ||
437 | {0,}, | ||
438 | }; | ||
439 | |||
440 | static struct pci_driver sta2x11_mfd_driver = { | ||
441 | .name = "sta2x11-mfd", | ||
442 | .id_table = sta2x11_mfd_tbl, | ||
443 | .probe = sta2x11_mfd_probe, | ||
444 | .suspend = sta2x11_mfd_suspend, | ||
445 | .resume = sta2x11_mfd_resume, | ||
446 | }; | ||
447 | |||
448 | static int __init sta2x11_mfd_init(void) | ||
449 | { | ||
450 | pr_info("%s\n", __func__); | ||
451 | return pci_register_driver(&sta2x11_mfd_driver); | ||
452 | } | ||
453 | |||
454 | /* | ||
455 | * All of this must be ready before "normal" devices like MMCI appear. | ||
456 | * But MFD (the pci device) can't be too early. The following choice | ||
457 | * prepares platform drivers very early and probe the PCI device later, | ||
458 | * but before other PCI devices. | ||
459 | */ | ||
460 | subsys_initcall(sta2x11_apbreg_init); | ||
461 | subsys_initcall(sta2x11_sctl_init); | ||
462 | rootfs_initcall(sta2x11_mfd_init); | ||
463 | |||
464 | MODULE_LICENSE("GPL v2"); | ||
465 | MODULE_AUTHOR("Wind River"); | ||
466 | MODULE_DESCRIPTION("STA2x11 mfd for GPIO, SCTL and APBREG"); | ||
467 | MODULE_DEVICE_TABLE(pci, sta2x11_mfd_tbl); | ||
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index b58c43c7ea93..afd459013ecb 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c | |||
@@ -122,7 +122,6 @@ MODULE_DEVICE_TABLE(spi, stmpe_id); | |||
122 | static struct spi_driver stmpe_spi_driver = { | 122 | static struct spi_driver stmpe_spi_driver = { |
123 | .driver = { | 123 | .driver = { |
124 | .name = "stmpe-spi", | 124 | .name = "stmpe-spi", |
125 | .bus = &spi_bus_type, | ||
126 | .owner = THIS_MODULE, | 125 | .owner = THIS_MODULE, |
127 | #ifdef CONFIG_PM | 126 | #ifdef CONFIG_PM |
128 | .pm = &stmpe_dev_pm_ops, | 127 | .pm = &stmpe_dev_pm_ops, |
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 47f802bf1848..396b9d1b6bd6 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -283,27 +283,24 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client, | |||
283 | } | 283 | } |
284 | } | 284 | } |
285 | 285 | ||
286 | tps65090->rmap = regmap_init_i2c(tps65090->client, | 286 | tps65090->rmap = devm_regmap_init_i2c(tps65090->client, |
287 | &tps65090_regmap_config); | 287 | &tps65090_regmap_config); |
288 | if (IS_ERR(tps65090->rmap)) { | 288 | if (IS_ERR(tps65090->rmap)) { |
289 | dev_err(&client->dev, "regmap_init failed with err: %ld\n", | 289 | ret = PTR_ERR(tps65090->rmap); |
290 | PTR_ERR(tps65090->rmap)); | 290 | dev_err(&client->dev, "regmap_init failed with err: %d\n", ret); |
291 | goto err_irq_exit; | 291 | goto err_irq_exit; |
292 | }; | 292 | } |
293 | 293 | ||
294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, | 294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, |
295 | ARRAY_SIZE(tps65090s), NULL, 0); | 295 | ARRAY_SIZE(tps65090s), NULL, 0); |
296 | if (ret) { | 296 | if (ret) { |
297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", | 297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", |
298 | ret); | 298 | ret); |
299 | goto err_regmap_exit; | 299 | goto err_irq_exit; |
300 | } | 300 | } |
301 | 301 | ||
302 | return 0; | 302 | return 0; |
303 | 303 | ||
304 | err_regmap_exit: | ||
305 | regmap_exit(tps65090->rmap); | ||
306 | |||
307 | err_irq_exit: | 304 | err_irq_exit: |
308 | if (client->irq) | 305 | if (client->irq) |
309 | free_irq(client->irq, tps65090); | 306 | free_irq(client->irq, tps65090); |
@@ -316,29 +313,34 @@ static int __devexit tps65090_i2c_remove(struct i2c_client *client) | |||
316 | struct tps65090 *tps65090 = i2c_get_clientdata(client); | 313 | struct tps65090 *tps65090 = i2c_get_clientdata(client); |
317 | 314 | ||
318 | mfd_remove_devices(tps65090->dev); | 315 | mfd_remove_devices(tps65090->dev); |
319 | regmap_exit(tps65090->rmap); | ||
320 | if (client->irq) | 316 | if (client->irq) |
321 | free_irq(client->irq, tps65090); | 317 | free_irq(client->irq, tps65090); |
322 | 318 | ||
323 | return 0; | 319 | return 0; |
324 | } | 320 | } |
325 | 321 | ||
326 | #ifdef CONFIG_PM | 322 | #ifdef CONFIG_PM_SLEEP |
327 | static int tps65090_i2c_suspend(struct i2c_client *client, pm_message_t state) | 323 | static int tps65090_suspend(struct device *dev) |
328 | { | 324 | { |
325 | struct i2c_client *client = to_i2c_client(dev); | ||
329 | if (client->irq) | 326 | if (client->irq) |
330 | disable_irq(client->irq); | 327 | disable_irq(client->irq); |
331 | return 0; | 328 | return 0; |
332 | } | 329 | } |
333 | 330 | ||
334 | static int tps65090_i2c_resume(struct i2c_client *client) | 331 | static int tps65090_resume(struct device *dev) |
335 | { | 332 | { |
333 | struct i2c_client *client = to_i2c_client(dev); | ||
336 | if (client->irq) | 334 | if (client->irq) |
337 | enable_irq(client->irq); | 335 | enable_irq(client->irq); |
338 | return 0; | 336 | return 0; |
339 | } | 337 | } |
340 | #endif | 338 | #endif |
341 | 339 | ||
340 | static const struct dev_pm_ops tps65090_pm_ops = { | ||
341 | SET_SYSTEM_SLEEP_PM_OPS(tps65090_suspend, tps65090_resume) | ||
342 | }; | ||
343 | |||
342 | static const struct i2c_device_id tps65090_id_table[] = { | 344 | static const struct i2c_device_id tps65090_id_table[] = { |
343 | { "tps65090", 0 }, | 345 | { "tps65090", 0 }, |
344 | { }, | 346 | { }, |
@@ -349,13 +351,10 @@ static struct i2c_driver tps65090_driver = { | |||
349 | .driver = { | 351 | .driver = { |
350 | .name = "tps65090", | 352 | .name = "tps65090", |
351 | .owner = THIS_MODULE, | 353 | .owner = THIS_MODULE, |
354 | .pm = &tps65090_pm_ops, | ||
352 | }, | 355 | }, |
353 | .probe = tps65090_i2c_probe, | 356 | .probe = tps65090_i2c_probe, |
354 | .remove = __devexit_p(tps65090_i2c_remove), | 357 | .remove = __devexit_p(tps65090_i2c_remove), |
355 | #ifdef CONFIG_PM | ||
356 | .suspend = tps65090_i2c_suspend, | ||
357 | .resume = tps65090_i2c_resume, | ||
358 | #endif | ||
359 | .id_table = tps65090_id_table, | 358 | .id_table = tps65090_id_table, |
360 | }; | 359 | }; |
361 | 360 | ||
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index f7d854e4cc62..db194e433c08 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -96,7 +96,7 @@ EXPORT_SYMBOL_GPL(tps65217_reg_write); | |||
96 | * @val: Value to write. | 96 | * @val: Value to write. |
97 | * @level: Password protected level | 97 | * @level: Password protected level |
98 | */ | 98 | */ |
99 | int tps65217_update_bits(struct tps65217 *tps, unsigned int reg, | 99 | static int tps65217_update_bits(struct tps65217 *tps, unsigned int reg, |
100 | unsigned int mask, unsigned int val, unsigned int level) | 100 | unsigned int mask, unsigned int val, unsigned int level) |
101 | { | 101 | { |
102 | int ret; | 102 | int ret; |
@@ -150,7 +150,7 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
150 | return -ENOMEM; | 150 | return -ENOMEM; |
151 | 151 | ||
152 | tps->pdata = pdata; | 152 | tps->pdata = pdata; |
153 | tps->regmap = regmap_init_i2c(client, &tps65217_regmap_config); | 153 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); |
154 | if (IS_ERR(tps->regmap)) { | 154 | if (IS_ERR(tps->regmap)) { |
155 | ret = PTR_ERR(tps->regmap); | 155 | ret = PTR_ERR(tps->regmap); |
156 | dev_err(tps->dev, "Failed to allocate register map: %d\n", | 156 | dev_err(tps->dev, "Failed to allocate register map: %d\n", |
@@ -163,9 +163,9 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
163 | 163 | ||
164 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); | 164 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); |
165 | if (ret < 0) { | 165 | if (ret < 0) { |
166 | dev_err(tps->dev, "Failed to read revision" | 166 | dev_err(tps->dev, "Failed to read revision register: %d\n", |
167 | " register: %d\n", ret); | 167 | ret); |
168 | goto err_regmap; | 168 | return ret; |
169 | } | 169 | } |
170 | 170 | ||
171 | dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n", | 171 | dev_info(tps->dev, "TPS65217 ID %#x version 1.%d\n", |
@@ -190,11 +190,6 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
190 | } | 190 | } |
191 | 191 | ||
192 | return 0; | 192 | return 0; |
193 | |||
194 | err_regmap: | ||
195 | regmap_exit(tps->regmap); | ||
196 | |||
197 | return ret; | ||
198 | } | 193 | } |
199 | 194 | ||
200 | static int __devexit tps65217_remove(struct i2c_client *client) | 195 | static int __devexit tps65217_remove(struct i2c_client *client) |
@@ -205,8 +200,6 @@ static int __devexit tps65217_remove(struct i2c_client *client) | |||
205 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | 200 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) |
206 | platform_device_unregister(tps->regulator_pdev[i]); | 201 | platform_device_unregister(tps->regulator_pdev[i]); |
207 | 202 | ||
208 | regmap_exit(tps->regmap); | ||
209 | |||
210 | return 0; | 203 | return 0; |
211 | } | 204 | } |
212 | 205 | ||
diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c index c9ed5c00a621..09aab3e4776d 100644 --- a/drivers/mfd/tps65910-irq.c +++ b/drivers/mfd/tps65910-irq.c | |||
@@ -20,15 +20,10 @@ | |||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/irqdomain.h> | ||
23 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
24 | #include <linux/mfd/tps65910.h> | 25 | #include <linux/mfd/tps65910.h> |
25 | 26 | ||
26 | static inline int irq_to_tps65910_irq(struct tps65910 *tps65910, | ||
27 | int irq) | ||
28 | { | ||
29 | return (irq - tps65910->irq_base); | ||
30 | } | ||
31 | |||
32 | /* | 27 | /* |
33 | * This is a threaded IRQ handler so can access I2C/SPI. Since all | 28 | * This is a threaded IRQ handler so can access I2C/SPI. Since all |
34 | * interrupts are clear on read the IRQ line will be reasserted and | 29 | * interrupts are clear on read the IRQ line will be reasserted and |
@@ -41,28 +36,28 @@ static inline int irq_to_tps65910_irq(struct tps65910 *tps65910, | |||
41 | static irqreturn_t tps65910_irq(int irq, void *irq_data) | 36 | static irqreturn_t tps65910_irq(int irq, void *irq_data) |
42 | { | 37 | { |
43 | struct tps65910 *tps65910 = irq_data; | 38 | struct tps65910 *tps65910 = irq_data; |
39 | unsigned int reg; | ||
44 | u32 irq_sts; | 40 | u32 irq_sts; |
45 | u32 irq_mask; | 41 | u32 irq_mask; |
46 | u8 reg; | ||
47 | int i; | 42 | int i; |
48 | 43 | ||
49 | tps65910->read(tps65910, TPS65910_INT_STS, 1, ®); | 44 | tps65910_reg_read(tps65910, TPS65910_INT_STS, ®); |
50 | irq_sts = reg; | 45 | irq_sts = reg; |
51 | tps65910->read(tps65910, TPS65910_INT_STS2, 1, ®); | 46 | tps65910_reg_read(tps65910, TPS65910_INT_STS2, ®); |
52 | irq_sts |= reg << 8; | 47 | irq_sts |= reg << 8; |
53 | switch (tps65910_chip_id(tps65910)) { | 48 | switch (tps65910_chip_id(tps65910)) { |
54 | case TPS65911: | 49 | case TPS65911: |
55 | tps65910->read(tps65910, TPS65910_INT_STS3, 1, ®); | 50 | tps65910_reg_read(tps65910, TPS65910_INT_STS3, ®); |
56 | irq_sts |= reg << 16; | 51 | irq_sts |= reg << 16; |
57 | } | 52 | } |
58 | 53 | ||
59 | tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); | 54 | tps65910_reg_read(tps65910, TPS65910_INT_MSK, ®); |
60 | irq_mask = reg; | 55 | irq_mask = reg; |
61 | tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); | 56 | tps65910_reg_read(tps65910, TPS65910_INT_MSK2, ®); |
62 | irq_mask |= reg << 8; | 57 | irq_mask |= reg << 8; |
63 | switch (tps65910_chip_id(tps65910)) { | 58 | switch (tps65910_chip_id(tps65910)) { |
64 | case TPS65911: | 59 | case TPS65911: |
65 | tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®); | 60 | tps65910_reg_read(tps65910, TPS65910_INT_MSK3, ®); |
66 | irq_mask |= reg << 16; | 61 | irq_mask |= reg << 16; |
67 | } | 62 | } |
68 | 63 | ||
@@ -76,19 +71,19 @@ static irqreturn_t tps65910_irq(int irq, void *irq_data) | |||
76 | if (!(irq_sts & (1 << i))) | 71 | if (!(irq_sts & (1 << i))) |
77 | continue; | 72 | continue; |
78 | 73 | ||
79 | handle_nested_irq(tps65910->irq_base + i); | 74 | handle_nested_irq(irq_find_mapping(tps65910->domain, i)); |
80 | } | 75 | } |
81 | 76 | ||
82 | /* Write the STS register back to clear IRQs we handled */ | 77 | /* Write the STS register back to clear IRQs we handled */ |
83 | reg = irq_sts & 0xFF; | 78 | reg = irq_sts & 0xFF; |
84 | irq_sts >>= 8; | 79 | irq_sts >>= 8; |
85 | tps65910->write(tps65910, TPS65910_INT_STS, 1, ®); | 80 | tps65910_reg_write(tps65910, TPS65910_INT_STS, reg); |
86 | reg = irq_sts & 0xFF; | 81 | reg = irq_sts & 0xFF; |
87 | tps65910->write(tps65910, TPS65910_INT_STS2, 1, ®); | 82 | tps65910_reg_write(tps65910, TPS65910_INT_STS2, reg); |
88 | switch (tps65910_chip_id(tps65910)) { | 83 | switch (tps65910_chip_id(tps65910)) { |
89 | case TPS65911: | 84 | case TPS65911: |
90 | reg = irq_sts >> 8; | 85 | reg = irq_sts >> 8; |
91 | tps65910->write(tps65910, TPS65910_INT_STS3, 1, ®); | 86 | tps65910_reg_write(tps65910, TPS65910_INT_STS3, reg); |
92 | } | 87 | } |
93 | 88 | ||
94 | return IRQ_HANDLED; | 89 | return IRQ_HANDLED; |
@@ -105,27 +100,27 @@ static void tps65910_irq_sync_unlock(struct irq_data *data) | |||
105 | { | 100 | { |
106 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); | 101 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); |
107 | u32 reg_mask; | 102 | u32 reg_mask; |
108 | u8 reg; | 103 | unsigned int reg; |
109 | 104 | ||
110 | tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®); | 105 | tps65910_reg_read(tps65910, TPS65910_INT_MSK, ®); |
111 | reg_mask = reg; | 106 | reg_mask = reg; |
112 | tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®); | 107 | tps65910_reg_read(tps65910, TPS65910_INT_MSK2, ®); |
113 | reg_mask |= reg << 8; | 108 | reg_mask |= reg << 8; |
114 | switch (tps65910_chip_id(tps65910)) { | 109 | switch (tps65910_chip_id(tps65910)) { |
115 | case TPS65911: | 110 | case TPS65911: |
116 | tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®); | 111 | tps65910_reg_read(tps65910, TPS65910_INT_MSK3, ®); |
117 | reg_mask |= reg << 16; | 112 | reg_mask |= reg << 16; |
118 | } | 113 | } |
119 | 114 | ||
120 | if (tps65910->irq_mask != reg_mask) { | 115 | if (tps65910->irq_mask != reg_mask) { |
121 | reg = tps65910->irq_mask & 0xFF; | 116 | reg = tps65910->irq_mask & 0xFF; |
122 | tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®); | 117 | tps65910_reg_write(tps65910, TPS65910_INT_MSK, reg); |
123 | reg = tps65910->irq_mask >> 8 & 0xFF; | 118 | reg = tps65910->irq_mask >> 8 & 0xFF; |
124 | tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®); | 119 | tps65910_reg_write(tps65910, TPS65910_INT_MSK2, reg); |
125 | switch (tps65910_chip_id(tps65910)) { | 120 | switch (tps65910_chip_id(tps65910)) { |
126 | case TPS65911: | 121 | case TPS65911: |
127 | reg = tps65910->irq_mask >> 16; | 122 | reg = tps65910->irq_mask >> 16; |
128 | tps65910->write(tps65910, TPS65910_INT_MSK3, 1, ®); | 123 | tps65910_reg_write(tps65910, TPS65910_INT_MSK3, reg); |
129 | } | 124 | } |
130 | } | 125 | } |
131 | mutex_unlock(&tps65910->irq_lock); | 126 | mutex_unlock(&tps65910->irq_lock); |
@@ -135,14 +130,14 @@ static void tps65910_irq_enable(struct irq_data *data) | |||
135 | { | 130 | { |
136 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); | 131 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); |
137 | 132 | ||
138 | tps65910->irq_mask &= ~( 1 << irq_to_tps65910_irq(tps65910, data->irq)); | 133 | tps65910->irq_mask &= ~(1 << data->hwirq); |
139 | } | 134 | } |
140 | 135 | ||
141 | static void tps65910_irq_disable(struct irq_data *data) | 136 | static void tps65910_irq_disable(struct irq_data *data) |
142 | { | 137 | { |
143 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); | 138 | struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data); |
144 | 139 | ||
145 | tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq)); | 140 | tps65910->irq_mask |= (1 << data->hwirq); |
146 | } | 141 | } |
147 | 142 | ||
148 | #ifdef CONFIG_PM_SLEEP | 143 | #ifdef CONFIG_PM_SLEEP |
@@ -164,10 +159,35 @@ static struct irq_chip tps65910_irq_chip = { | |||
164 | .irq_set_wake = tps65910_irq_set_wake, | 159 | .irq_set_wake = tps65910_irq_set_wake, |
165 | }; | 160 | }; |
166 | 161 | ||
162 | static int tps65910_irq_map(struct irq_domain *h, unsigned int virq, | ||
163 | irq_hw_number_t hw) | ||
164 | { | ||
165 | struct tps65910 *tps65910 = h->host_data; | ||
166 | |||
167 | irq_set_chip_data(virq, tps65910); | ||
168 | irq_set_chip_and_handler(virq, &tps65910_irq_chip, handle_edge_irq); | ||
169 | irq_set_nested_thread(virq, 1); | ||
170 | |||
171 | /* ARM needs us to explicitly flag the IRQ as valid | ||
172 | * and will set them noprobe when we do so. */ | ||
173 | #ifdef CONFIG_ARM | ||
174 | set_irq_flags(virq, IRQF_VALID); | ||
175 | #else | ||
176 | irq_set_noprobe(virq); | ||
177 | #endif | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct irq_domain_ops tps65910_domain_ops = { | ||
183 | .map = tps65910_irq_map, | ||
184 | .xlate = irq_domain_xlate_twocell, | ||
185 | }; | ||
186 | |||
167 | int tps65910_irq_init(struct tps65910 *tps65910, int irq, | 187 | int tps65910_irq_init(struct tps65910 *tps65910, int irq, |
168 | struct tps65910_platform_data *pdata) | 188 | struct tps65910_platform_data *pdata) |
169 | { | 189 | { |
170 | int ret, cur_irq; | 190 | int ret; |
171 | int flags = IRQF_ONESHOT; | 191 | int flags = IRQF_ONESHOT; |
172 | 192 | ||
173 | if (!irq) { | 193 | if (!irq) { |
@@ -175,17 +195,11 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, | |||
175 | return -EINVAL; | 195 | return -EINVAL; |
176 | } | 196 | } |
177 | 197 | ||
178 | if (!pdata || !pdata->irq_base) { | 198 | if (!pdata) { |
179 | dev_warn(tps65910->dev, "No interrupt support, no IRQ base\n"); | 199 | dev_warn(tps65910->dev, "No interrupt support, no pdata\n"); |
180 | return -EINVAL; | 200 | return -EINVAL; |
181 | } | 201 | } |
182 | 202 | ||
183 | tps65910->irq_mask = 0xFFFFFF; | ||
184 | |||
185 | mutex_init(&tps65910->irq_lock); | ||
186 | tps65910->chip_irq = irq; | ||
187 | tps65910->irq_base = pdata->irq_base; | ||
188 | |||
189 | switch (tps65910_chip_id(tps65910)) { | 203 | switch (tps65910_chip_id(tps65910)) { |
190 | case TPS65910: | 204 | case TPS65910: |
191 | tps65910->irq_num = TPS65910_NUM_IRQ; | 205 | tps65910->irq_num = TPS65910_NUM_IRQ; |
@@ -195,22 +209,36 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, | |||
195 | break; | 209 | break; |
196 | } | 210 | } |
197 | 211 | ||
198 | /* Register with genirq */ | 212 | if (pdata->irq_base > 0) { |
199 | for (cur_irq = tps65910->irq_base; | 213 | pdata->irq_base = irq_alloc_descs(pdata->irq_base, 0, |
200 | cur_irq < tps65910->irq_num + tps65910->irq_base; | 214 | tps65910->irq_num, -1); |
201 | cur_irq++) { | 215 | if (pdata->irq_base < 0) { |
202 | irq_set_chip_data(cur_irq, tps65910); | 216 | dev_warn(tps65910->dev, "Failed to alloc IRQs: %d\n", |
203 | irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip, | 217 | pdata->irq_base); |
204 | handle_edge_irq); | 218 | return pdata->irq_base; |
205 | irq_set_nested_thread(cur_irq, 1); | 219 | } |
206 | 220 | } | |
207 | /* ARM needs us to explicitly flag the IRQ as valid | 221 | |
208 | * and will set them noprobe when we do so. */ | 222 | tps65910->irq_mask = 0xFFFFFF; |
209 | #ifdef CONFIG_ARM | 223 | |
210 | set_irq_flags(cur_irq, IRQF_VALID); | 224 | mutex_init(&tps65910->irq_lock); |
211 | #else | 225 | tps65910->chip_irq = irq; |
212 | irq_set_noprobe(cur_irq); | 226 | tps65910->irq_base = pdata->irq_base; |
213 | #endif | 227 | |
228 | if (pdata->irq_base > 0) | ||
229 | tps65910->domain = irq_domain_add_legacy(tps65910->dev->of_node, | ||
230 | tps65910->irq_num, | ||
231 | pdata->irq_base, | ||
232 | 0, | ||
233 | &tps65910_domain_ops, tps65910); | ||
234 | else | ||
235 | tps65910->domain = irq_domain_add_linear(tps65910->dev->of_node, | ||
236 | tps65910->irq_num, | ||
237 | &tps65910_domain_ops, tps65910); | ||
238 | |||
239 | if (!tps65910->domain) { | ||
240 | dev_err(tps65910->dev, "Failed to create IRQ domain\n"); | ||
241 | return -ENOMEM; | ||
214 | } | 242 | } |
215 | 243 | ||
216 | ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, | 244 | ret = request_threaded_irq(irq, NULL, tps65910_irq, flags, |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index bf2b25ebf2ca..be9e07b77325 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -19,13 +19,16 @@ | |||
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/i2c.h> | 21 | #include <linux/i2c.h> |
22 | #include <linux/gpio.h> | ||
23 | #include <linux/mfd/core.h> | 22 | #include <linux/mfd/core.h> |
24 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
25 | #include <linux/mfd/tps65910.h> | 24 | #include <linux/mfd/tps65910.h> |
25 | #include <linux/of_device.h> | ||
26 | 26 | ||
27 | static struct mfd_cell tps65910s[] = { | 27 | static struct mfd_cell tps65910s[] = { |
28 | { | 28 | { |
29 | .name = "tps65910-gpio", | ||
30 | }, | ||
31 | { | ||
29 | .name = "tps65910-pmic", | 32 | .name = "tps65910-pmic", |
30 | }, | 33 | }, |
31 | { | 34 | { |
@@ -37,30 +40,6 @@ static struct mfd_cell tps65910s[] = { | |||
37 | }; | 40 | }; |
38 | 41 | ||
39 | 42 | ||
40 | static int tps65910_i2c_read(struct tps65910 *tps65910, u8 reg, | ||
41 | int bytes, void *dest) | ||
42 | { | ||
43 | return regmap_bulk_read(tps65910->regmap, reg, dest, bytes); | ||
44 | } | ||
45 | |||
46 | static int tps65910_i2c_write(struct tps65910 *tps65910, u8 reg, | ||
47 | int bytes, void *src) | ||
48 | { | ||
49 | return regmap_bulk_write(tps65910->regmap, reg, src, bytes); | ||
50 | } | ||
51 | |||
52 | int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask) | ||
53 | { | ||
54 | return regmap_update_bits(tps65910->regmap, reg, mask, mask); | ||
55 | } | ||
56 | EXPORT_SYMBOL_GPL(tps65910_set_bits); | ||
57 | |||
58 | int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask) | ||
59 | { | ||
60 | return regmap_update_bits(tps65910->regmap, reg, mask, 0); | ||
61 | } | ||
62 | EXPORT_SYMBOL_GPL(tps65910_clear_bits); | ||
63 | |||
64 | static bool is_volatile_reg(struct device *dev, unsigned int reg) | 43 | static bool is_volatile_reg(struct device *dev, unsigned int reg) |
65 | { | 44 | { |
66 | struct tps65910 *tps65910 = dev_get_drvdata(dev); | 45 | struct tps65910 *tps65910 = dev_get_drvdata(dev); |
@@ -85,80 +64,197 @@ static const struct regmap_config tps65910_regmap_config = { | |||
85 | .reg_bits = 8, | 64 | .reg_bits = 8, |
86 | .val_bits = 8, | 65 | .val_bits = 8, |
87 | .volatile_reg = is_volatile_reg, | 66 | .volatile_reg = is_volatile_reg, |
88 | .max_register = TPS65910_MAX_REGISTER, | 67 | .max_register = TPS65910_MAX_REGISTER - 1, |
89 | .num_reg_defaults_raw = TPS65910_MAX_REGISTER, | ||
90 | .cache_type = REGCACHE_RBTREE, | 68 | .cache_type = REGCACHE_RBTREE, |
91 | }; | 69 | }; |
92 | 70 | ||
93 | static int tps65910_i2c_probe(struct i2c_client *i2c, | 71 | static int __devinit tps65910_sleepinit(struct tps65910 *tps65910, |
94 | const struct i2c_device_id *id) | 72 | struct tps65910_board *pmic_pdata) |
73 | { | ||
74 | struct device *dev = NULL; | ||
75 | int ret = 0; | ||
76 | |||
77 | dev = tps65910->dev; | ||
78 | |||
79 | if (!pmic_pdata->en_dev_slp) | ||
80 | return 0; | ||
81 | |||
82 | /* enabling SLEEP device state */ | ||
83 | ret = tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL, | ||
84 | DEVCTRL_DEV_SLP_MASK); | ||
85 | if (ret < 0) { | ||
86 | dev_err(dev, "set dev_slp failed: %d\n", ret); | ||
87 | goto err_sleep_init; | ||
88 | } | ||
89 | |||
90 | /* Return if there is no sleep keepon data. */ | ||
91 | if (!pmic_pdata->slp_keepon) | ||
92 | return 0; | ||
93 | |||
94 | if (pmic_pdata->slp_keepon->therm_keepon) { | ||
95 | ret = tps65910_reg_set_bits(tps65910, | ||
96 | TPS65910_SLEEP_KEEP_RES_ON, | ||
97 | SLEEP_KEEP_RES_ON_THERM_KEEPON_MASK); | ||
98 | if (ret < 0) { | ||
99 | dev_err(dev, "set therm_keepon failed: %d\n", ret); | ||
100 | goto disable_dev_slp; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | if (pmic_pdata->slp_keepon->clkout32k_keepon) { | ||
105 | ret = tps65910_reg_set_bits(tps65910, | ||
106 | TPS65910_SLEEP_KEEP_RES_ON, | ||
107 | SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK); | ||
108 | if (ret < 0) { | ||
109 | dev_err(dev, "set clkout32k_keepon failed: %d\n", ret); | ||
110 | goto disable_dev_slp; | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (pmic_pdata->slp_keepon->i2chs_keepon) { | ||
115 | ret = tps65910_reg_set_bits(tps65910, | ||
116 | TPS65910_SLEEP_KEEP_RES_ON, | ||
117 | SLEEP_KEEP_RES_ON_I2CHS_KEEPON_MASK); | ||
118 | if (ret < 0) { | ||
119 | dev_err(dev, "set i2chs_keepon failed: %d\n", ret); | ||
120 | goto disable_dev_slp; | ||
121 | } | ||
122 | } | ||
123 | |||
124 | return 0; | ||
125 | |||
126 | disable_dev_slp: | ||
127 | tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL, | ||
128 | DEVCTRL_DEV_SLP_MASK); | ||
129 | |||
130 | err_sleep_init: | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_OF | ||
135 | static struct of_device_id tps65910_of_match[] = { | ||
136 | { .compatible = "ti,tps65910", .data = (void *)TPS65910}, | ||
137 | { .compatible = "ti,tps65911", .data = (void *)TPS65911}, | ||
138 | { }, | ||
139 | }; | ||
140 | MODULE_DEVICE_TABLE(of, tps65910_of_match); | ||
141 | |||
142 | static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | ||
143 | int *chip_id) | ||
144 | { | ||
145 | struct device_node *np = client->dev.of_node; | ||
146 | struct tps65910_board *board_info; | ||
147 | unsigned int prop; | ||
148 | const struct of_device_id *match; | ||
149 | int ret = 0; | ||
150 | |||
151 | match = of_match_device(tps65910_of_match, &client->dev); | ||
152 | if (!match) { | ||
153 | dev_err(&client->dev, "Failed to find matching dt id\n"); | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
157 | *chip_id = (int)match->data; | ||
158 | |||
159 | board_info = devm_kzalloc(&client->dev, sizeof(*board_info), | ||
160 | GFP_KERNEL); | ||
161 | if (!board_info) { | ||
162 | dev_err(&client->dev, "Failed to allocate pdata\n"); | ||
163 | return NULL; | ||
164 | } | ||
165 | |||
166 | ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop); | ||
167 | if (!ret) | ||
168 | board_info->vmbch_threshold = prop; | ||
169 | else if (*chip_id == TPS65911) | ||
170 | dev_warn(&client->dev, "VMBCH-Threshold not specified"); | ||
171 | |||
172 | ret = of_property_read_u32(np, "ti,vmbch2-threshold", &prop); | ||
173 | if (!ret) | ||
174 | board_info->vmbch2_threshold = prop; | ||
175 | else if (*chip_id == TPS65911) | ||
176 | dev_warn(&client->dev, "VMBCH2-Threshold not specified"); | ||
177 | |||
178 | board_info->irq = client->irq; | ||
179 | board_info->irq_base = -1; | ||
180 | |||
181 | return board_info; | ||
182 | } | ||
183 | #else | ||
184 | static inline | ||
185 | struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | ||
186 | int *chip_id) | ||
187 | { | ||
188 | return NULL; | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | static __devinit int tps65910_i2c_probe(struct i2c_client *i2c, | ||
193 | const struct i2c_device_id *id) | ||
95 | { | 194 | { |
96 | struct tps65910 *tps65910; | 195 | struct tps65910 *tps65910; |
97 | struct tps65910_board *pmic_plat_data; | 196 | struct tps65910_board *pmic_plat_data; |
197 | struct tps65910_board *of_pmic_plat_data = NULL; | ||
98 | struct tps65910_platform_data *init_data; | 198 | struct tps65910_platform_data *init_data; |
99 | int ret = 0; | 199 | int ret = 0; |
200 | int chip_id = id->driver_data; | ||
100 | 201 | ||
101 | pmic_plat_data = dev_get_platdata(&i2c->dev); | 202 | pmic_plat_data = dev_get_platdata(&i2c->dev); |
203 | |||
204 | if (!pmic_plat_data && i2c->dev.of_node) { | ||
205 | pmic_plat_data = tps65910_parse_dt(i2c, &chip_id); | ||
206 | of_pmic_plat_data = pmic_plat_data; | ||
207 | } | ||
208 | |||
102 | if (!pmic_plat_data) | 209 | if (!pmic_plat_data) |
103 | return -EINVAL; | 210 | return -EINVAL; |
104 | 211 | ||
105 | init_data = kzalloc(sizeof(struct tps65910_platform_data), GFP_KERNEL); | 212 | init_data = devm_kzalloc(&i2c->dev, sizeof(*init_data), GFP_KERNEL); |
106 | if (init_data == NULL) | 213 | if (init_data == NULL) |
107 | return -ENOMEM; | 214 | return -ENOMEM; |
108 | 215 | ||
109 | tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL); | 216 | tps65910 = devm_kzalloc(&i2c->dev, sizeof(*tps65910), GFP_KERNEL); |
110 | if (tps65910 == NULL) { | 217 | if (tps65910 == NULL) |
111 | kfree(init_data); | ||
112 | return -ENOMEM; | 218 | return -ENOMEM; |
113 | } | ||
114 | 219 | ||
220 | tps65910->of_plat_data = of_pmic_plat_data; | ||
115 | i2c_set_clientdata(i2c, tps65910); | 221 | i2c_set_clientdata(i2c, tps65910); |
116 | tps65910->dev = &i2c->dev; | 222 | tps65910->dev = &i2c->dev; |
117 | tps65910->i2c_client = i2c; | 223 | tps65910->i2c_client = i2c; |
118 | tps65910->id = id->driver_data; | 224 | tps65910->id = chip_id; |
119 | tps65910->read = tps65910_i2c_read; | ||
120 | tps65910->write = tps65910_i2c_write; | ||
121 | mutex_init(&tps65910->io_mutex); | 225 | mutex_init(&tps65910->io_mutex); |
122 | 226 | ||
123 | tps65910->regmap = regmap_init_i2c(i2c, &tps65910_regmap_config); | 227 | tps65910->regmap = devm_regmap_init_i2c(i2c, &tps65910_regmap_config); |
124 | if (IS_ERR(tps65910->regmap)) { | 228 | if (IS_ERR(tps65910->regmap)) { |
125 | ret = PTR_ERR(tps65910->regmap); | 229 | ret = PTR_ERR(tps65910->regmap); |
126 | dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); | 230 | dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); |
127 | goto regmap_err; | 231 | return ret; |
128 | } | 232 | } |
129 | 233 | ||
130 | ret = mfd_add_devices(tps65910->dev, -1, | 234 | ret = mfd_add_devices(tps65910->dev, -1, |
131 | tps65910s, ARRAY_SIZE(tps65910s), | 235 | tps65910s, ARRAY_SIZE(tps65910s), |
132 | NULL, 0); | 236 | NULL, 0); |
133 | if (ret < 0) | 237 | if (ret < 0) { |
134 | goto err; | 238 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); |
239 | return ret; | ||
240 | } | ||
135 | 241 | ||
136 | init_data->irq = pmic_plat_data->irq; | 242 | init_data->irq = pmic_plat_data->irq; |
137 | init_data->irq_base = pmic_plat_data->irq_base; | 243 | init_data->irq_base = pmic_plat_data->irq_base; |
138 | 244 | ||
139 | tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); | ||
140 | |||
141 | tps65910_irq_init(tps65910, init_data->irq, init_data); | 245 | tps65910_irq_init(tps65910, init_data->irq, init_data); |
142 | 246 | ||
143 | kfree(init_data); | 247 | tps65910_sleepinit(tps65910, pmic_plat_data); |
144 | return ret; | ||
145 | 248 | ||
146 | err: | ||
147 | regmap_exit(tps65910->regmap); | ||
148 | regmap_err: | ||
149 | kfree(tps65910); | ||
150 | kfree(init_data); | ||
151 | return ret; | 249 | return ret; |
152 | } | 250 | } |
153 | 251 | ||
154 | static int tps65910_i2c_remove(struct i2c_client *i2c) | 252 | static __devexit int tps65910_i2c_remove(struct i2c_client *i2c) |
155 | { | 253 | { |
156 | struct tps65910 *tps65910 = i2c_get_clientdata(i2c); | 254 | struct tps65910 *tps65910 = i2c_get_clientdata(i2c); |
157 | 255 | ||
158 | tps65910_irq_exit(tps65910); | 256 | tps65910_irq_exit(tps65910); |
159 | mfd_remove_devices(tps65910->dev); | 257 | mfd_remove_devices(tps65910->dev); |
160 | regmap_exit(tps65910->regmap); | ||
161 | kfree(tps65910); | ||
162 | 258 | ||
163 | return 0; | 259 | return 0; |
164 | } | 260 | } |
@@ -175,9 +271,10 @@ static struct i2c_driver tps65910_i2c_driver = { | |||
175 | .driver = { | 271 | .driver = { |
176 | .name = "tps65910", | 272 | .name = "tps65910", |
177 | .owner = THIS_MODULE, | 273 | .owner = THIS_MODULE, |
274 | .of_match_table = of_match_ptr(tps65910_of_match), | ||
178 | }, | 275 | }, |
179 | .probe = tps65910_i2c_probe, | 276 | .probe = tps65910_i2c_probe, |
180 | .remove = tps65910_i2c_remove, | 277 | .remove = __devexit_p(tps65910_i2c_remove), |
181 | .id_table = tps65910_i2c_id, | 278 | .id_table = tps65910_i2c_id, |
182 | }; | 279 | }; |
183 | 280 | ||
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 5d656e814358..ad733d76207a 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -757,6 +757,7 @@ int twl4030_init_irq(struct device *dev, int irq_num) | |||
757 | dev_err(dev, "could not claim irq%d: %d\n", irq_num, status); | 757 | dev_err(dev, "could not claim irq%d: %d\n", irq_num, status); |
758 | goto fail_rqirq; | 758 | goto fail_rqirq; |
759 | } | 759 | } |
760 | enable_irq_wake(irq_num); | ||
760 | 761 | ||
761 | return irq_base; | 762 | return irq_base; |
762 | fail_rqirq: | 763 | fail_rqirq: |
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index 2d6bedadca09..4ded9e7aa246 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c | |||
@@ -27,7 +27,12 @@ | |||
27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/err.h> | ||
30 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/of.h> | ||
33 | #include <linux/of_irq.h> | ||
34 | #include <linux/of_gpio.h> | ||
35 | #include <linux/of_platform.h> | ||
31 | #include <linux/gpio.h> | 36 | #include <linux/gpio.h> |
32 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
33 | #include <linux/i2c.h> | 38 | #include <linux/i2c.h> |
@@ -35,8 +40,24 @@ | |||
35 | #include <linux/err.h> | 40 | #include <linux/err.h> |
36 | #include <linux/mfd/core.h> | 41 | #include <linux/mfd/core.h> |
37 | #include <linux/mfd/twl6040.h> | 42 | #include <linux/mfd/twl6040.h> |
43 | #include <linux/regulator/consumer.h> | ||
38 | 44 | ||
39 | #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) | 45 | #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) |
46 | #define TWL6040_NUM_SUPPLIES (2) | ||
47 | |||
48 | static bool twl6040_has_vibra(struct twl6040_platform_data *pdata, | ||
49 | struct device_node *node) | ||
50 | { | ||
51 | if (pdata && pdata->vibra) | ||
52 | return true; | ||
53 | |||
54 | #ifdef CONFIG_OF | ||
55 | if (of_find_node_by_name(node, "vibra")) | ||
56 | return true; | ||
57 | #endif | ||
58 | |||
59 | return false; | ||
60 | } | ||
40 | 61 | ||
41 | int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) | 62 | int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) |
42 | { | 63 | { |
@@ -502,17 +523,18 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
502 | const struct i2c_device_id *id) | 523 | const struct i2c_device_id *id) |
503 | { | 524 | { |
504 | struct twl6040_platform_data *pdata = client->dev.platform_data; | 525 | struct twl6040_platform_data *pdata = client->dev.platform_data; |
526 | struct device_node *node = client->dev.of_node; | ||
505 | struct twl6040 *twl6040; | 527 | struct twl6040 *twl6040; |
506 | struct mfd_cell *cell = NULL; | 528 | struct mfd_cell *cell = NULL; |
507 | int ret, children = 0; | 529 | int irq, ret, children = 0; |
508 | 530 | ||
509 | if (!pdata) { | 531 | if (!pdata && !node) { |
510 | dev_err(&client->dev, "Platform data is missing\n"); | 532 | dev_err(&client->dev, "Platform data is missing\n"); |
511 | return -EINVAL; | 533 | return -EINVAL; |
512 | } | 534 | } |
513 | 535 | ||
514 | /* In order to operate correctly we need valid interrupt config */ | 536 | /* In order to operate correctly we need valid interrupt config */ |
515 | if (!client->irq || !pdata->irq_base) { | 537 | if (!client->irq) { |
516 | dev_err(&client->dev, "Invalid IRQ configuration\n"); | 538 | dev_err(&client->dev, "Invalid IRQ configuration\n"); |
517 | return -EINVAL; | 539 | return -EINVAL; |
518 | } | 540 | } |
@@ -524,7 +546,7 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
524 | goto err; | 546 | goto err; |
525 | } | 547 | } |
526 | 548 | ||
527 | twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); | 549 | twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); |
528 | if (IS_ERR(twl6040->regmap)) { | 550 | if (IS_ERR(twl6040->regmap)) { |
529 | ret = PTR_ERR(twl6040->regmap); | 551 | ret = PTR_ERR(twl6040->regmap); |
530 | goto err; | 552 | goto err; |
@@ -532,9 +554,23 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
532 | 554 | ||
533 | i2c_set_clientdata(client, twl6040); | 555 | i2c_set_clientdata(client, twl6040); |
534 | 556 | ||
557 | twl6040->supplies[0].supply = "vio"; | ||
558 | twl6040->supplies[1].supply = "v2v1"; | ||
559 | ret = regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, | ||
560 | twl6040->supplies); | ||
561 | if (ret != 0) { | ||
562 | dev_err(&client->dev, "Failed to get supplies: %d\n", ret); | ||
563 | goto regulator_get_err; | ||
564 | } | ||
565 | |||
566 | ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies); | ||
567 | if (ret != 0) { | ||
568 | dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); | ||
569 | goto power_err; | ||
570 | } | ||
571 | |||
535 | twl6040->dev = &client->dev; | 572 | twl6040->dev = &client->dev; |
536 | twl6040->irq = client->irq; | 573 | twl6040->irq = client->irq; |
537 | twl6040->irq_base = pdata->irq_base; | ||
538 | 574 | ||
539 | mutex_init(&twl6040->mutex); | 575 | mutex_init(&twl6040->mutex); |
540 | mutex_init(&twl6040->io_mutex); | 576 | mutex_init(&twl6040->io_mutex); |
@@ -543,22 +579,26 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
543 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); | 579 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); |
544 | 580 | ||
545 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ | 581 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ |
546 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) | 582 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) { |
547 | twl6040->audpwron = pdata->audpwron_gpio; | 583 | if (pdata) |
548 | else | 584 | twl6040->audpwron = pdata->audpwron_gpio; |
585 | else | ||
586 | twl6040->audpwron = of_get_named_gpio(node, | ||
587 | "ti,audpwron-gpio", 0); | ||
588 | } else | ||
549 | twl6040->audpwron = -EINVAL; | 589 | twl6040->audpwron = -EINVAL; |
550 | 590 | ||
551 | if (gpio_is_valid(twl6040->audpwron)) { | 591 | if (gpio_is_valid(twl6040->audpwron)) { |
552 | ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW, | 592 | ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW, |
553 | "audpwron"); | 593 | "audpwron"); |
554 | if (ret) | 594 | if (ret) |
555 | goto gpio1_err; | 595 | goto gpio_err; |
556 | } | 596 | } |
557 | 597 | ||
558 | /* codec interrupt */ | 598 | /* codec interrupt */ |
559 | ret = twl6040_irq_init(twl6040); | 599 | ret = twl6040_irq_init(twl6040); |
560 | if (ret) | 600 | if (ret) |
561 | goto gpio2_err; | 601 | goto irq_init_err; |
562 | 602 | ||
563 | ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY, | 603 | ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY, |
564 | NULL, twl6040_naudint_handler, 0, | 604 | NULL, twl6040_naudint_handler, 0, |
@@ -572,22 +612,27 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
572 | /* dual-access registers controlled by I2C only */ | 612 | /* dual-access registers controlled by I2C only */ |
573 | twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL); | 613 | twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL); |
574 | 614 | ||
575 | if (pdata->codec) { | 615 | /* |
576 | int irq = twl6040->irq_base + TWL6040_IRQ_PLUG; | 616 | * The main functionality of twl6040 to provide audio on OMAP4+ systems. |
577 | 617 | * We can add the ASoC codec child whenever this driver has been loaded. | |
578 | cell = &twl6040->cells[children]; | 618 | * The ASoC codec can work without pdata, pass the platform_data only if |
579 | cell->name = "twl6040-codec"; | 619 | * it has been provided. |
580 | twl6040_codec_rsrc[0].start = irq; | 620 | */ |
581 | twl6040_codec_rsrc[0].end = irq; | 621 | irq = twl6040->irq_base + TWL6040_IRQ_PLUG; |
582 | cell->resources = twl6040_codec_rsrc; | 622 | cell = &twl6040->cells[children]; |
583 | cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); | 623 | cell->name = "twl6040-codec"; |
624 | twl6040_codec_rsrc[0].start = irq; | ||
625 | twl6040_codec_rsrc[0].end = irq; | ||
626 | cell->resources = twl6040_codec_rsrc; | ||
627 | cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); | ||
628 | if (pdata && pdata->codec) { | ||
584 | cell->platform_data = pdata->codec; | 629 | cell->platform_data = pdata->codec; |
585 | cell->pdata_size = sizeof(*pdata->codec); | 630 | cell->pdata_size = sizeof(*pdata->codec); |
586 | children++; | ||
587 | } | 631 | } |
632 | children++; | ||
588 | 633 | ||
589 | if (pdata->vibra) { | 634 | if (twl6040_has_vibra(pdata, node)) { |
590 | int irq = twl6040->irq_base + TWL6040_IRQ_VIB; | 635 | irq = twl6040->irq_base + TWL6040_IRQ_VIB; |
591 | 636 | ||
592 | cell = &twl6040->cells[children]; | 637 | cell = &twl6040->cells[children]; |
593 | cell->name = "twl6040-vibra"; | 638 | cell->name = "twl6040-vibra"; |
@@ -596,21 +641,17 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
596 | cell->resources = twl6040_vibra_rsrc; | 641 | cell->resources = twl6040_vibra_rsrc; |
597 | cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); | 642 | cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); |
598 | 643 | ||
599 | cell->platform_data = pdata->vibra; | 644 | if (pdata && pdata->vibra) { |
600 | cell->pdata_size = sizeof(*pdata->vibra); | 645 | cell->platform_data = pdata->vibra; |
646 | cell->pdata_size = sizeof(*pdata->vibra); | ||
647 | } | ||
601 | children++; | 648 | children++; |
602 | } | 649 | } |
603 | 650 | ||
604 | if (children) { | 651 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, |
605 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, | 652 | NULL, 0); |
606 | children, NULL, 0); | 653 | if (ret) |
607 | if (ret) | ||
608 | goto mfd_err; | ||
609 | } else { | ||
610 | dev_err(&client->dev, "No platform data found for children\n"); | ||
611 | ret = -ENODEV; | ||
612 | goto mfd_err; | 654 | goto mfd_err; |
613 | } | ||
614 | 655 | ||
615 | return 0; | 656 | return 0; |
616 | 657 | ||
@@ -618,12 +659,15 @@ mfd_err: | |||
618 | free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); | 659 | free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); |
619 | irq_err: | 660 | irq_err: |
620 | twl6040_irq_exit(twl6040); | 661 | twl6040_irq_exit(twl6040); |
621 | gpio2_err: | 662 | irq_init_err: |
622 | if (gpio_is_valid(twl6040->audpwron)) | 663 | if (gpio_is_valid(twl6040->audpwron)) |
623 | gpio_free(twl6040->audpwron); | 664 | gpio_free(twl6040->audpwron); |
624 | gpio1_err: | 665 | gpio_err: |
666 | regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); | ||
667 | power_err: | ||
668 | regulator_bulk_free(TWL6040_NUM_SUPPLIES, twl6040->supplies); | ||
669 | regulator_get_err: | ||
625 | i2c_set_clientdata(client, NULL); | 670 | i2c_set_clientdata(client, NULL); |
626 | regmap_exit(twl6040->regmap); | ||
627 | err: | 671 | err: |
628 | return ret; | 672 | return ret; |
629 | } | 673 | } |
@@ -643,7 +687,9 @@ static int __devexit twl6040_remove(struct i2c_client *client) | |||
643 | 687 | ||
644 | mfd_remove_devices(&client->dev); | 688 | mfd_remove_devices(&client->dev); |
645 | i2c_set_clientdata(client, NULL); | 689 | i2c_set_clientdata(client, NULL); |
646 | regmap_exit(twl6040->regmap); | 690 | |
691 | regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); | ||
692 | regulator_bulk_free(TWL6040_NUM_SUPPLIES, twl6040->supplies); | ||
647 | 693 | ||
648 | return 0; | 694 | return 0; |
649 | } | 695 | } |
diff --git a/drivers/mfd/twl6040-irq.c b/drivers/mfd/twl6040-irq.c index b3f8ddaa28a8..4b42543da228 100644 --- a/drivers/mfd/twl6040-irq.c +++ b/drivers/mfd/twl6040-irq.c | |||
@@ -23,7 +23,10 @@ | |||
23 | 23 | ||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/err.h> | ||
26 | #include <linux/irq.h> | 27 | #include <linux/irq.h> |
28 | #include <linux/of.h> | ||
29 | #include <linux/irqdomain.h> | ||
27 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
28 | #include <linux/mfd/core.h> | 31 | #include <linux/mfd/core.h> |
29 | #include <linux/mfd/twl6040.h> | 32 | #include <linux/mfd/twl6040.h> |
@@ -138,7 +141,8 @@ static irqreturn_t twl6040_irq_thread(int irq, void *data) | |||
138 | 141 | ||
139 | int twl6040_irq_init(struct twl6040 *twl6040) | 142 | int twl6040_irq_init(struct twl6040 *twl6040) |
140 | { | 143 | { |
141 | int cur_irq, ret; | 144 | struct device_node *node = twl6040->dev->of_node; |
145 | int i, nr_irqs, irq_base, ret; | ||
142 | u8 val; | 146 | u8 val; |
143 | 147 | ||
144 | mutex_init(&twl6040->irq_mutex); | 148 | mutex_init(&twl6040->irq_mutex); |
@@ -148,21 +152,31 @@ int twl6040_irq_init(struct twl6040 *twl6040) | |||
148 | twl6040->irq_masks_cache = TWL6040_ALLINT_MSK; | 152 | twl6040->irq_masks_cache = TWL6040_ALLINT_MSK; |
149 | twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK); | 153 | twl6040_reg_write(twl6040, TWL6040_REG_INTMR, TWL6040_ALLINT_MSK); |
150 | 154 | ||
155 | nr_irqs = ARRAY_SIZE(twl6040_irqs); | ||
156 | |||
157 | irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0); | ||
158 | if (IS_ERR_VALUE(irq_base)) { | ||
159 | dev_err(twl6040->dev, "Fail to allocate IRQ descs\n"); | ||
160 | return irq_base; | ||
161 | } | ||
162 | twl6040->irq_base = irq_base; | ||
163 | |||
164 | irq_domain_add_legacy(node, ARRAY_SIZE(twl6040_irqs), irq_base, 0, | ||
165 | &irq_domain_simple_ops, NULL); | ||
166 | |||
151 | /* Register them with genirq */ | 167 | /* Register them with genirq */ |
152 | for (cur_irq = twl6040->irq_base; | 168 | for (i = irq_base; i < irq_base + nr_irqs; i++) { |
153 | cur_irq < twl6040->irq_base + ARRAY_SIZE(twl6040_irqs); | 169 | irq_set_chip_data(i, twl6040); |
154 | cur_irq++) { | 170 | irq_set_chip_and_handler(i, &twl6040_irq_chip, |
155 | irq_set_chip_data(cur_irq, twl6040); | ||
156 | irq_set_chip_and_handler(cur_irq, &twl6040_irq_chip, | ||
157 | handle_level_irq); | 171 | handle_level_irq); |
158 | irq_set_nested_thread(cur_irq, 1); | 172 | irq_set_nested_thread(i, 1); |
159 | 173 | ||
160 | /* ARM needs us to explicitly flag the IRQ as valid | 174 | /* ARM needs us to explicitly flag the IRQ as valid |
161 | * and will set them noprobe when we do so. */ | 175 | * and will set them noprobe when we do so. */ |
162 | #ifdef CONFIG_ARM | 176 | #ifdef CONFIG_ARM |
163 | set_irq_flags(cur_irq, IRQF_VALID); | 177 | set_irq_flags(i, IRQF_VALID); |
164 | #else | 178 | #else |
165 | irq_set_noprobe(cur_irq); | 179 | irq_set_noprobe(i); |
166 | #endif | 180 | #endif |
167 | } | 181 | } |
168 | 182 | ||
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index b73cc15e0081..872aff21e4be 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
@@ -131,17 +131,7 @@ static struct pci_driver vx855_pci_driver = { | |||
131 | .remove = __devexit_p(vx855_remove), | 131 | .remove = __devexit_p(vx855_remove), |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static int vx855_init(void) | 134 | module_pci_driver(vx855_pci_driver); |
135 | { | ||
136 | return pci_register_driver(&vx855_pci_driver); | ||
137 | } | ||
138 | module_init(vx855_init); | ||
139 | |||
140 | static void vx855_exit(void) | ||
141 | { | ||
142 | pci_unregister_driver(&vx855_pci_driver); | ||
143 | } | ||
144 | module_exit(vx855_exit); | ||
145 | 135 | ||
146 | MODULE_LICENSE("GPL"); | 136 | MODULE_LICENSE("GPL"); |
147 | MODULE_AUTHOR("Harald Welte <HaraldWelte@viatech.com>"); | 137 | MODULE_AUTHOR("Harald Welte <HaraldWelte@viatech.com>"); |
diff --git a/drivers/mfd/wm831x-auxadc.c b/drivers/mfd/wm831x-auxadc.c index 87210954a066..6ee3018d8653 100644 --- a/drivers/mfd/wm831x-auxadc.c +++ b/drivers/mfd/wm831x-auxadc.c | |||
@@ -280,11 +280,11 @@ void wm831x_auxadc_init(struct wm831x *wm831x) | |||
280 | mutex_init(&wm831x->auxadc_lock); | 280 | mutex_init(&wm831x->auxadc_lock); |
281 | INIT_LIST_HEAD(&wm831x->auxadc_pending); | 281 | INIT_LIST_HEAD(&wm831x->auxadc_pending); |
282 | 282 | ||
283 | if (wm831x->irq && wm831x->irq_base) { | 283 | if (wm831x->irq) { |
284 | wm831x->auxadc_read = wm831x_auxadc_read_irq; | 284 | wm831x->auxadc_read = wm831x_auxadc_read_irq; |
285 | 285 | ||
286 | ret = request_threaded_irq(wm831x->irq_base + | 286 | ret = request_threaded_irq(wm831x_irq(wm831x, |
287 | WM831X_IRQ_AUXADC_DATA, | 287 | WM831X_IRQ_AUXADC_DATA), |
288 | NULL, wm831x_auxadc_irq, 0, | 288 | NULL, wm831x_auxadc_irq, 0, |
289 | "auxadc", wm831x); | 289 | "auxadc", wm831x); |
290 | if (ret < 0) { | 290 | if (ret < 0) { |
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 838056c3493a..946698fd2dc6 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -614,8 +614,15 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg, | |||
614 | } | 614 | } |
615 | EXPORT_SYMBOL_GPL(wm831x_set_bits); | 615 | EXPORT_SYMBOL_GPL(wm831x_set_bits); |
616 | 616 | ||
617 | static struct resource wm831x_io_parent = { | ||
618 | .start = 0, | ||
619 | .end = 0xffffffff, | ||
620 | .flags = IORESOURCE_IO, | ||
621 | }; | ||
622 | |||
617 | static struct resource wm831x_dcdc1_resources[] = { | 623 | static struct resource wm831x_dcdc1_resources[] = { |
618 | { | 624 | { |
625 | .parent = &wm831x_io_parent, | ||
619 | .start = WM831X_DC1_CONTROL_1, | 626 | .start = WM831X_DC1_CONTROL_1, |
620 | .end = WM831X_DC1_DVS_CONTROL, | 627 | .end = WM831X_DC1_DVS_CONTROL, |
621 | .flags = IORESOURCE_IO, | 628 | .flags = IORESOURCE_IO, |
@@ -637,6 +644,7 @@ static struct resource wm831x_dcdc1_resources[] = { | |||
637 | 644 | ||
638 | static struct resource wm831x_dcdc2_resources[] = { | 645 | static struct resource wm831x_dcdc2_resources[] = { |
639 | { | 646 | { |
647 | .parent = &wm831x_io_parent, | ||
640 | .start = WM831X_DC2_CONTROL_1, | 648 | .start = WM831X_DC2_CONTROL_1, |
641 | .end = WM831X_DC2_DVS_CONTROL, | 649 | .end = WM831X_DC2_DVS_CONTROL, |
642 | .flags = IORESOURCE_IO, | 650 | .flags = IORESOURCE_IO, |
@@ -657,6 +665,7 @@ static struct resource wm831x_dcdc2_resources[] = { | |||
657 | 665 | ||
658 | static struct resource wm831x_dcdc3_resources[] = { | 666 | static struct resource wm831x_dcdc3_resources[] = { |
659 | { | 667 | { |
668 | .parent = &wm831x_io_parent, | ||
660 | .start = WM831X_DC3_CONTROL_1, | 669 | .start = WM831X_DC3_CONTROL_1, |
661 | .end = WM831X_DC3_SLEEP_CONTROL, | 670 | .end = WM831X_DC3_SLEEP_CONTROL, |
662 | .flags = IORESOURCE_IO, | 671 | .flags = IORESOURCE_IO, |
@@ -671,6 +680,7 @@ static struct resource wm831x_dcdc3_resources[] = { | |||
671 | 680 | ||
672 | static struct resource wm831x_dcdc4_resources[] = { | 681 | static struct resource wm831x_dcdc4_resources[] = { |
673 | { | 682 | { |
683 | .parent = &wm831x_io_parent, | ||
674 | .start = WM831X_DC4_CONTROL, | 684 | .start = WM831X_DC4_CONTROL, |
675 | .end = WM831X_DC4_SLEEP_CONTROL, | 685 | .end = WM831X_DC4_SLEEP_CONTROL, |
676 | .flags = IORESOURCE_IO, | 686 | .flags = IORESOURCE_IO, |
@@ -685,6 +695,7 @@ static struct resource wm831x_dcdc4_resources[] = { | |||
685 | 695 | ||
686 | static struct resource wm8320_dcdc4_buck_resources[] = { | 696 | static struct resource wm8320_dcdc4_buck_resources[] = { |
687 | { | 697 | { |
698 | .parent = &wm831x_io_parent, | ||
688 | .start = WM831X_DC4_CONTROL, | 699 | .start = WM831X_DC4_CONTROL, |
689 | .end = WM832X_DC4_SLEEP_CONTROL, | 700 | .end = WM832X_DC4_SLEEP_CONTROL, |
690 | .flags = IORESOURCE_IO, | 701 | .flags = IORESOURCE_IO, |
@@ -707,6 +718,7 @@ static struct resource wm831x_gpio_resources[] = { | |||
707 | 718 | ||
708 | static struct resource wm831x_isink1_resources[] = { | 719 | static struct resource wm831x_isink1_resources[] = { |
709 | { | 720 | { |
721 | .parent = &wm831x_io_parent, | ||
710 | .start = WM831X_CURRENT_SINK_1, | 722 | .start = WM831X_CURRENT_SINK_1, |
711 | .end = WM831X_CURRENT_SINK_1, | 723 | .end = WM831X_CURRENT_SINK_1, |
712 | .flags = IORESOURCE_IO, | 724 | .flags = IORESOURCE_IO, |
@@ -720,6 +732,7 @@ static struct resource wm831x_isink1_resources[] = { | |||
720 | 732 | ||
721 | static struct resource wm831x_isink2_resources[] = { | 733 | static struct resource wm831x_isink2_resources[] = { |
722 | { | 734 | { |
735 | .parent = &wm831x_io_parent, | ||
723 | .start = WM831X_CURRENT_SINK_2, | 736 | .start = WM831X_CURRENT_SINK_2, |
724 | .end = WM831X_CURRENT_SINK_2, | 737 | .end = WM831X_CURRENT_SINK_2, |
725 | .flags = IORESOURCE_IO, | 738 | .flags = IORESOURCE_IO, |
@@ -733,6 +746,7 @@ static struct resource wm831x_isink2_resources[] = { | |||
733 | 746 | ||
734 | static struct resource wm831x_ldo1_resources[] = { | 747 | static struct resource wm831x_ldo1_resources[] = { |
735 | { | 748 | { |
749 | .parent = &wm831x_io_parent, | ||
736 | .start = WM831X_LDO1_CONTROL, | 750 | .start = WM831X_LDO1_CONTROL, |
737 | .end = WM831X_LDO1_SLEEP_CONTROL, | 751 | .end = WM831X_LDO1_SLEEP_CONTROL, |
738 | .flags = IORESOURCE_IO, | 752 | .flags = IORESOURCE_IO, |
@@ -747,6 +761,7 @@ static struct resource wm831x_ldo1_resources[] = { | |||
747 | 761 | ||
748 | static struct resource wm831x_ldo2_resources[] = { | 762 | static struct resource wm831x_ldo2_resources[] = { |
749 | { | 763 | { |
764 | .parent = &wm831x_io_parent, | ||
750 | .start = WM831X_LDO2_CONTROL, | 765 | .start = WM831X_LDO2_CONTROL, |
751 | .end = WM831X_LDO2_SLEEP_CONTROL, | 766 | .end = WM831X_LDO2_SLEEP_CONTROL, |
752 | .flags = IORESOURCE_IO, | 767 | .flags = IORESOURCE_IO, |
@@ -761,6 +776,7 @@ static struct resource wm831x_ldo2_resources[] = { | |||
761 | 776 | ||
762 | static struct resource wm831x_ldo3_resources[] = { | 777 | static struct resource wm831x_ldo3_resources[] = { |
763 | { | 778 | { |
779 | .parent = &wm831x_io_parent, | ||
764 | .start = WM831X_LDO3_CONTROL, | 780 | .start = WM831X_LDO3_CONTROL, |
765 | .end = WM831X_LDO3_SLEEP_CONTROL, | 781 | .end = WM831X_LDO3_SLEEP_CONTROL, |
766 | .flags = IORESOURCE_IO, | 782 | .flags = IORESOURCE_IO, |
@@ -775,6 +791,7 @@ static struct resource wm831x_ldo3_resources[] = { | |||
775 | 791 | ||
776 | static struct resource wm831x_ldo4_resources[] = { | 792 | static struct resource wm831x_ldo4_resources[] = { |
777 | { | 793 | { |
794 | .parent = &wm831x_io_parent, | ||
778 | .start = WM831X_LDO4_CONTROL, | 795 | .start = WM831X_LDO4_CONTROL, |
779 | .end = WM831X_LDO4_SLEEP_CONTROL, | 796 | .end = WM831X_LDO4_SLEEP_CONTROL, |
780 | .flags = IORESOURCE_IO, | 797 | .flags = IORESOURCE_IO, |
@@ -789,6 +806,7 @@ static struct resource wm831x_ldo4_resources[] = { | |||
789 | 806 | ||
790 | static struct resource wm831x_ldo5_resources[] = { | 807 | static struct resource wm831x_ldo5_resources[] = { |
791 | { | 808 | { |
809 | .parent = &wm831x_io_parent, | ||
792 | .start = WM831X_LDO5_CONTROL, | 810 | .start = WM831X_LDO5_CONTROL, |
793 | .end = WM831X_LDO5_SLEEP_CONTROL, | 811 | .end = WM831X_LDO5_SLEEP_CONTROL, |
794 | .flags = IORESOURCE_IO, | 812 | .flags = IORESOURCE_IO, |
@@ -803,6 +821,7 @@ static struct resource wm831x_ldo5_resources[] = { | |||
803 | 821 | ||
804 | static struct resource wm831x_ldo6_resources[] = { | 822 | static struct resource wm831x_ldo6_resources[] = { |
805 | { | 823 | { |
824 | .parent = &wm831x_io_parent, | ||
806 | .start = WM831X_LDO6_CONTROL, | 825 | .start = WM831X_LDO6_CONTROL, |
807 | .end = WM831X_LDO6_SLEEP_CONTROL, | 826 | .end = WM831X_LDO6_SLEEP_CONTROL, |
808 | .flags = IORESOURCE_IO, | 827 | .flags = IORESOURCE_IO, |
@@ -817,6 +836,7 @@ static struct resource wm831x_ldo6_resources[] = { | |||
817 | 836 | ||
818 | static struct resource wm831x_ldo7_resources[] = { | 837 | static struct resource wm831x_ldo7_resources[] = { |
819 | { | 838 | { |
839 | .parent = &wm831x_io_parent, | ||
820 | .start = WM831X_LDO7_CONTROL, | 840 | .start = WM831X_LDO7_CONTROL, |
821 | .end = WM831X_LDO7_SLEEP_CONTROL, | 841 | .end = WM831X_LDO7_SLEEP_CONTROL, |
822 | .flags = IORESOURCE_IO, | 842 | .flags = IORESOURCE_IO, |
@@ -831,6 +851,7 @@ static struct resource wm831x_ldo7_resources[] = { | |||
831 | 851 | ||
832 | static struct resource wm831x_ldo8_resources[] = { | 852 | static struct resource wm831x_ldo8_resources[] = { |
833 | { | 853 | { |
854 | .parent = &wm831x_io_parent, | ||
834 | .start = WM831X_LDO8_CONTROL, | 855 | .start = WM831X_LDO8_CONTROL, |
835 | .end = WM831X_LDO8_SLEEP_CONTROL, | 856 | .end = WM831X_LDO8_SLEEP_CONTROL, |
836 | .flags = IORESOURCE_IO, | 857 | .flags = IORESOURCE_IO, |
@@ -845,6 +866,7 @@ static struct resource wm831x_ldo8_resources[] = { | |||
845 | 866 | ||
846 | static struct resource wm831x_ldo9_resources[] = { | 867 | static struct resource wm831x_ldo9_resources[] = { |
847 | { | 868 | { |
869 | .parent = &wm831x_io_parent, | ||
848 | .start = WM831X_LDO9_CONTROL, | 870 | .start = WM831X_LDO9_CONTROL, |
849 | .end = WM831X_LDO9_SLEEP_CONTROL, | 871 | .end = WM831X_LDO9_SLEEP_CONTROL, |
850 | .flags = IORESOURCE_IO, | 872 | .flags = IORESOURCE_IO, |
@@ -859,6 +881,7 @@ static struct resource wm831x_ldo9_resources[] = { | |||
859 | 881 | ||
860 | static struct resource wm831x_ldo10_resources[] = { | 882 | static struct resource wm831x_ldo10_resources[] = { |
861 | { | 883 | { |
884 | .parent = &wm831x_io_parent, | ||
862 | .start = WM831X_LDO10_CONTROL, | 885 | .start = WM831X_LDO10_CONTROL, |
863 | .end = WM831X_LDO10_SLEEP_CONTROL, | 886 | .end = WM831X_LDO10_SLEEP_CONTROL, |
864 | .flags = IORESOURCE_IO, | 887 | .flags = IORESOURCE_IO, |
@@ -873,6 +896,7 @@ static struct resource wm831x_ldo10_resources[] = { | |||
873 | 896 | ||
874 | static struct resource wm831x_ldo11_resources[] = { | 897 | static struct resource wm831x_ldo11_resources[] = { |
875 | { | 898 | { |
899 | .parent = &wm831x_io_parent, | ||
876 | .start = WM831X_LDO11_ON_CONTROL, | 900 | .start = WM831X_LDO11_ON_CONTROL, |
877 | .end = WM831X_LDO11_SLEEP_CONTROL, | 901 | .end = WM831X_LDO11_SLEEP_CONTROL, |
878 | .flags = IORESOURCE_IO, | 902 | .flags = IORESOURCE_IO, |
@@ -974,6 +998,7 @@ static struct resource wm831x_rtc_resources[] = { | |||
974 | 998 | ||
975 | static struct resource wm831x_status1_resources[] = { | 999 | static struct resource wm831x_status1_resources[] = { |
976 | { | 1000 | { |
1001 | .parent = &wm831x_io_parent, | ||
977 | .start = WM831X_STATUS_LED_1, | 1002 | .start = WM831X_STATUS_LED_1, |
978 | .end = WM831X_STATUS_LED_1, | 1003 | .end = WM831X_STATUS_LED_1, |
979 | .flags = IORESOURCE_IO, | 1004 | .flags = IORESOURCE_IO, |
@@ -982,6 +1007,7 @@ static struct resource wm831x_status1_resources[] = { | |||
982 | 1007 | ||
983 | static struct resource wm831x_status2_resources[] = { | 1008 | static struct resource wm831x_status2_resources[] = { |
984 | { | 1009 | { |
1010 | .parent = &wm831x_io_parent, | ||
985 | .start = WM831X_STATUS_LED_2, | 1011 | .start = WM831X_STATUS_LED_2, |
986 | .end = WM831X_STATUS_LED_2, | 1012 | .end = WM831X_STATUS_LED_2, |
987 | .flags = IORESOURCE_IO, | 1013 | .flags = IORESOURCE_IO, |
@@ -1787,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1787 | case WM8310: | 1813 | case WM8310: |
1788 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1789 | wm8310_devs, ARRAY_SIZE(wm8310_devs), | 1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), |
1790 | NULL, wm831x->irq_base); | 1816 | NULL, 0); |
1791 | break; | 1817 | break; |
1792 | 1818 | ||
1793 | case WM8311: | 1819 | case WM8311: |
1794 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1795 | wm8311_devs, ARRAY_SIZE(wm8311_devs), | 1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), |
1796 | NULL, wm831x->irq_base); | 1822 | NULL, 0); |
1797 | if (!pdata || !pdata->disable_touch) | 1823 | if (!pdata || !pdata->disable_touch) |
1798 | mfd_add_devices(wm831x->dev, wm831x_num, | 1824 | mfd_add_devices(wm831x->dev, wm831x_num, |
1799 | touch_devs, ARRAY_SIZE(touch_devs), | 1825 | touch_devs, ARRAY_SIZE(touch_devs), |
1800 | NULL, wm831x->irq_base); | 1826 | NULL, 0); |
1801 | break; | 1827 | break; |
1802 | 1828 | ||
1803 | case WM8312: | 1829 | case WM8312: |
1804 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1805 | wm8312_devs, ARRAY_SIZE(wm8312_devs), | 1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), |
1806 | NULL, wm831x->irq_base); | 1832 | NULL, 0); |
1807 | if (!pdata || !pdata->disable_touch) | 1833 | if (!pdata || !pdata->disable_touch) |
1808 | mfd_add_devices(wm831x->dev, wm831x_num, | 1834 | mfd_add_devices(wm831x->dev, wm831x_num, |
1809 | touch_devs, ARRAY_SIZE(touch_devs), | 1835 | touch_devs, ARRAY_SIZE(touch_devs), |
1810 | NULL, wm831x->irq_base); | 1836 | NULL, 0); |
1811 | break; | 1837 | break; |
1812 | 1838 | ||
1813 | case WM8320: | 1839 | case WM8320: |
@@ -1816,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1816 | case WM8326: | 1842 | case WM8326: |
1817 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1818 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
1819 | NULL, wm831x->irq_base); | 1845 | NULL, 0); |
1820 | break; | 1846 | break; |
1821 | 1847 | ||
1822 | default: | 1848 | default: |
@@ -1841,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1841 | if (ret & WM831X_XTAL_ENA) { | 1867 | if (ret & WM831X_XTAL_ENA) { |
1842 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1843 | rtc_devs, ARRAY_SIZE(rtc_devs), | 1869 | rtc_devs, ARRAY_SIZE(rtc_devs), |
1844 | NULL, wm831x->irq_base); | 1870 | NULL, 0); |
1845 | if (ret != 0) { | 1871 | if (ret != 0) { |
1846 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); | 1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); |
1847 | goto err_irq; | 1873 | goto err_irq; |
@@ -1854,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1854 | /* Treat errors as non-critical */ | 1880 | /* Treat errors as non-critical */ |
1855 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, | 1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, |
1856 | ARRAY_SIZE(backlight_devs), NULL, | 1882 | ARRAY_SIZE(backlight_devs), NULL, |
1857 | wm831x->irq_base); | 1883 | 0); |
1858 | if (ret < 0) | 1884 | if (ret < 0) |
1859 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", | 1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", |
1860 | ret); | 1886 | ret); |
@@ -1883,8 +1909,7 @@ void wm831x_device_exit(struct wm831x *wm831x) | |||
1883 | { | 1909 | { |
1884 | wm831x_otp_exit(wm831x); | 1910 | wm831x_otp_exit(wm831x); |
1885 | mfd_remove_devices(wm831x->dev); | 1911 | mfd_remove_devices(wm831x->dev); |
1886 | if (wm831x->irq_base) | 1912 | free_irq(wm831x_irq(wm831x, WM831X_IRQ_AUXADC_DATA), wm831x); |
1887 | free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); | ||
1888 | wm831x_irq_exit(wm831x); | 1913 | wm831x_irq_exit(wm831x); |
1889 | } | 1914 | } |
1890 | 1915 | ||
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index bec4d0539160..804e56ec99eb 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
21 | #include <linux/irqdomain.h> | ||
21 | 22 | ||
22 | #include <linux/mfd/wm831x/core.h> | 23 | #include <linux/mfd/wm831x/core.h> |
23 | #include <linux/mfd/wm831x/pdata.h> | 24 | #include <linux/mfd/wm831x/pdata.h> |
@@ -328,7 +329,7 @@ static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data) | |||
328 | static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, | 329 | static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, |
329 | int irq) | 330 | int irq) |
330 | { | 331 | { |
331 | return &wm831x_irqs[irq - wm831x->irq_base]; | 332 | return &wm831x_irqs[irq]; |
332 | } | 333 | } |
333 | 334 | ||
334 | static void wm831x_irq_lock(struct irq_data *data) | 335 | static void wm831x_irq_lock(struct irq_data *data) |
@@ -374,7 +375,7 @@ static void wm831x_irq_enable(struct irq_data *data) | |||
374 | { | 375 | { |
375 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); | 376 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
376 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, | 377 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, |
377 | data->irq); | 378 | data->hwirq); |
378 | 379 | ||
379 | wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | 380 | wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; |
380 | } | 381 | } |
@@ -383,7 +384,7 @@ static void wm831x_irq_disable(struct irq_data *data) | |||
383 | { | 384 | { |
384 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); | 385 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
385 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, | 386 | struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, |
386 | data->irq); | 387 | data->hwirq); |
387 | 388 | ||
388 | wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | 389 | wm831x->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; |
389 | } | 390 | } |
@@ -393,7 +394,7 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) | |||
393 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); | 394 | struct wm831x *wm831x = irq_data_get_irq_chip_data(data); |
394 | int irq; | 395 | int irq; |
395 | 396 | ||
396 | irq = data->irq - wm831x->irq_base; | 397 | irq = data->hwirq; |
397 | 398 | ||
398 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { | 399 | if (irq < WM831X_IRQ_GPIO_1 || irq > WM831X_IRQ_GPIO_11) { |
399 | /* Ignore internal-only IRQs */ | 400 | /* Ignore internal-only IRQs */ |
@@ -412,22 +413,25 @@ static int wm831x_irq_set_type(struct irq_data *data, unsigned int type) | |||
412 | * do the update here as we can be called with the bus lock | 413 | * do the update here as we can be called with the bus lock |
413 | * held. | 414 | * held. |
414 | */ | 415 | */ |
416 | wm831x->gpio_level_low[irq] = false; | ||
417 | wm831x->gpio_level_high[irq] = false; | ||
415 | switch (type) { | 418 | switch (type) { |
416 | case IRQ_TYPE_EDGE_BOTH: | 419 | case IRQ_TYPE_EDGE_BOTH: |
417 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; | 420 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_INT_MODE; |
418 | wm831x->gpio_level[irq] = false; | ||
419 | break; | 421 | break; |
420 | case IRQ_TYPE_EDGE_RISING: | 422 | case IRQ_TYPE_EDGE_RISING: |
421 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; | 423 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; |
422 | wm831x->gpio_level[irq] = false; | ||
423 | break; | 424 | break; |
424 | case IRQ_TYPE_EDGE_FALLING: | 425 | case IRQ_TYPE_EDGE_FALLING: |
425 | wm831x->gpio_update[irq] = 0x10000; | 426 | wm831x->gpio_update[irq] = 0x10000; |
426 | wm831x->gpio_level[irq] = false; | ||
427 | break; | 427 | break; |
428 | case IRQ_TYPE_LEVEL_HIGH: | 428 | case IRQ_TYPE_LEVEL_HIGH: |
429 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; | 429 | wm831x->gpio_update[irq] = 0x10000 | WM831X_GPN_POL; |
430 | wm831x->gpio_level[irq] = true; | 430 | wm831x->gpio_level_high[irq] = true; |
431 | break; | ||
432 | case IRQ_TYPE_LEVEL_LOW: | ||
433 | wm831x->gpio_update[irq] = 0x10000; | ||
434 | wm831x->gpio_level_low[irq] = true; | ||
431 | break; | 435 | break; |
432 | default: | 436 | default: |
433 | return -EINVAL; | 437 | return -EINVAL; |
@@ -469,9 +473,11 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
469 | * descriptors. | 473 | * descriptors. |
470 | */ | 474 | */ |
471 | if (primary & WM831X_TCHPD_INT) | 475 | if (primary & WM831X_TCHPD_INT) |
472 | handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD); | 476 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, |
477 | WM831X_IRQ_TCHPD)); | ||
473 | if (primary & WM831X_TCHDATA_INT) | 478 | if (primary & WM831X_TCHDATA_INT) |
474 | handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA); | 479 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, |
480 | WM831X_IRQ_TCHDATA)); | ||
475 | primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); | 481 | primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); |
476 | 482 | ||
477 | for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { | 483 | for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { |
@@ -507,16 +513,29 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
507 | } | 513 | } |
508 | 514 | ||
509 | if (*status & wm831x_irqs[i].mask) | 515 | if (*status & wm831x_irqs[i].mask) |
510 | handle_nested_irq(wm831x->irq_base + i); | 516 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, |
517 | i)); | ||
511 | 518 | ||
512 | /* Simulate an edge triggered IRQ by polling the input | 519 | /* Simulate an edge triggered IRQ by polling the input |
513 | * status. This is sucky but improves interoperability. | 520 | * status. This is sucky but improves interoperability. |
514 | */ | 521 | */ |
515 | if (primary == WM831X_GP_INT && | 522 | if (primary == WM831X_GP_INT && |
516 | wm831x->gpio_level[i - WM831X_IRQ_GPIO_1]) { | 523 | wm831x->gpio_level_high[i - WM831X_IRQ_GPIO_1]) { |
517 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); | 524 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); |
518 | while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { | 525 | while (ret & 1 << (i - WM831X_IRQ_GPIO_1)) { |
519 | handle_nested_irq(wm831x->irq_base + i); | 526 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, |
527 | i)); | ||
528 | ret = wm831x_reg_read(wm831x, | ||
529 | WM831X_GPIO_LEVEL); | ||
530 | } | ||
531 | } | ||
532 | |||
533 | if (primary == WM831X_GP_INT && | ||
534 | wm831x->gpio_level_low[i - WM831X_IRQ_GPIO_1]) { | ||
535 | ret = wm831x_reg_read(wm831x, WM831X_GPIO_LEVEL); | ||
536 | while (!(ret & 1 << (i - WM831X_IRQ_GPIO_1))) { | ||
537 | handle_nested_irq(irq_find_mapping(wm831x->irq_domain, | ||
538 | i)); | ||
520 | ret = wm831x_reg_read(wm831x, | 539 | ret = wm831x_reg_read(wm831x, |
521 | WM831X_GPIO_LEVEL); | 540 | WM831X_GPIO_LEVEL); |
522 | } | 541 | } |
@@ -527,10 +546,34 @@ out: | |||
527 | return IRQ_HANDLED; | 546 | return IRQ_HANDLED; |
528 | } | 547 | } |
529 | 548 | ||
549 | static int wm831x_irq_map(struct irq_domain *h, unsigned int virq, | ||
550 | irq_hw_number_t hw) | ||
551 | { | ||
552 | irq_set_chip_data(virq, h->host_data); | ||
553 | irq_set_chip_and_handler(virq, &wm831x_irq_chip, handle_edge_irq); | ||
554 | irq_set_nested_thread(virq, 1); | ||
555 | |||
556 | /* ARM needs us to explicitly flag the IRQ as valid | ||
557 | * and will set them noprobe when we do so. */ | ||
558 | #ifdef CONFIG_ARM | ||
559 | set_irq_flags(virq, IRQF_VALID); | ||
560 | #else | ||
561 | irq_set_noprobe(virq); | ||
562 | #endif | ||
563 | |||
564 | return 0; | ||
565 | } | ||
566 | |||
567 | static struct irq_domain_ops wm831x_irq_domain_ops = { | ||
568 | .map = wm831x_irq_map, | ||
569 | .xlate = irq_domain_xlate_twocell, | ||
570 | }; | ||
571 | |||
530 | int wm831x_irq_init(struct wm831x *wm831x, int irq) | 572 | int wm831x_irq_init(struct wm831x *wm831x, int irq) |
531 | { | 573 | { |
532 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; | 574 | struct wm831x_pdata *pdata = wm831x->dev->platform_data; |
533 | int i, cur_irq, ret; | 575 | struct irq_domain *domain; |
576 | int i, ret, irq_base; | ||
534 | 577 | ||
535 | mutex_init(&wm831x->irq_lock); | 578 | mutex_init(&wm831x->irq_lock); |
536 | 579 | ||
@@ -543,18 +586,33 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) | |||
543 | } | 586 | } |
544 | 587 | ||
545 | /* Try to dynamically allocate IRQs if no base is specified */ | 588 | /* Try to dynamically allocate IRQs if no base is specified */ |
546 | if (!pdata || !pdata->irq_base) | 589 | if (pdata && pdata->irq_base) { |
547 | wm831x->irq_base = -1; | 590 | irq_base = irq_alloc_descs(pdata->irq_base, 0, |
591 | WM831X_NUM_IRQS, 0); | ||
592 | if (irq_base < 0) { | ||
593 | dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n", | ||
594 | irq_base); | ||
595 | irq_base = 0; | ||
596 | } | ||
597 | } else { | ||
598 | irq_base = 0; | ||
599 | } | ||
600 | |||
601 | if (irq_base) | ||
602 | domain = irq_domain_add_legacy(wm831x->dev->of_node, | ||
603 | ARRAY_SIZE(wm831x_irqs), | ||
604 | irq_base, 0, | ||
605 | &wm831x_irq_domain_ops, | ||
606 | wm831x); | ||
548 | else | 607 | else |
549 | wm831x->irq_base = pdata->irq_base; | 608 | domain = irq_domain_add_linear(wm831x->dev->of_node, |
609 | ARRAY_SIZE(wm831x_irqs), | ||
610 | &wm831x_irq_domain_ops, | ||
611 | wm831x); | ||
550 | 612 | ||
551 | wm831x->irq_base = irq_alloc_descs(wm831x->irq_base, 0, | 613 | if (!domain) { |
552 | WM831X_NUM_IRQS, 0); | 614 | dev_warn(wm831x->dev, "Failed to allocate IRQ domain\n"); |
553 | if (wm831x->irq_base < 0) { | 615 | return -EINVAL; |
554 | dev_warn(wm831x->dev, "Failed to allocate IRQs: %d\n", | ||
555 | wm831x->irq_base); | ||
556 | wm831x->irq_base = 0; | ||
557 | return 0; | ||
558 | } | 616 | } |
559 | 617 | ||
560 | if (pdata && pdata->irq_cmos) | 618 | if (pdata && pdata->irq_cmos) |
@@ -565,38 +623,22 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq) | |||
565 | wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG, | 623 | wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG, |
566 | WM831X_IRQ_OD, i); | 624 | WM831X_IRQ_OD, i); |
567 | 625 | ||
568 | /* Try to flag /IRQ as a wake source; there are a number of | ||
569 | * unconditional wake sources in the PMIC so this isn't | ||
570 | * conditional but we don't actually care *too* much if it | ||
571 | * fails. | ||
572 | */ | ||
573 | ret = enable_irq_wake(irq); | ||
574 | if (ret != 0) { | ||
575 | dev_warn(wm831x->dev, "Can't enable IRQ as wake source: %d\n", | ||
576 | ret); | ||
577 | } | ||
578 | |||
579 | wm831x->irq = irq; | 626 | wm831x->irq = irq; |
580 | 627 | wm831x->irq_domain = domain; | |
581 | /* Register them with genirq */ | ||
582 | for (cur_irq = wm831x->irq_base; | ||
583 | cur_irq < ARRAY_SIZE(wm831x_irqs) + wm831x->irq_base; | ||
584 | cur_irq++) { | ||
585 | irq_set_chip_data(cur_irq, wm831x); | ||
586 | irq_set_chip_and_handler(cur_irq, &wm831x_irq_chip, | ||
587 | handle_edge_irq); | ||
588 | irq_set_nested_thread(cur_irq, 1); | ||
589 | |||
590 | /* ARM needs us to explicitly flag the IRQ as valid | ||
591 | * and will set them noprobe when we do so. */ | ||
592 | #ifdef CONFIG_ARM | ||
593 | set_irq_flags(cur_irq, IRQF_VALID); | ||
594 | #else | ||
595 | irq_set_noprobe(cur_irq); | ||
596 | #endif | ||
597 | } | ||
598 | 628 | ||
599 | if (irq) { | 629 | if (irq) { |
630 | /* Try to flag /IRQ as a wake source; there are a number of | ||
631 | * unconditional wake sources in the PMIC so this isn't | ||
632 | * conditional but we don't actually care *too* much if it | ||
633 | * fails. | ||
634 | */ | ||
635 | ret = enable_irq_wake(irq); | ||
636 | if (ret != 0) { | ||
637 | dev_warn(wm831x->dev, | ||
638 | "Can't enable IRQ as wake source: %d\n", | ||
639 | ret); | ||
640 | } | ||
641 | |||
600 | ret = request_threaded_irq(irq, NULL, wm831x_irq_thread, | 642 | ret = request_threaded_irq(irq, NULL, wm831x_irq_thread, |
601 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | 643 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, |
602 | "wm831x", wm831x); | 644 | "wm831x", wm831x); |
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index dd1caaac55e4..8a9b11ca076a 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/regmap.h> | ||
23 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
24 | 25 | ||
25 | #include <linux/mfd/wm8350/core.h> | 26 | #include <linux/mfd/wm8350/core.h> |
@@ -74,7 +75,7 @@ static int wm8350_phys_read(struct wm8350 *wm8350, u8 reg, int num_regs, | |||
74 | int bytes = num_regs * 2; | 75 | int bytes = num_regs * 2; |
75 | 76 | ||
76 | dev_dbg(wm8350->dev, "volatile read\n"); | 77 | dev_dbg(wm8350->dev, "volatile read\n"); |
77 | ret = wm8350->read_dev(wm8350, reg, bytes, (char *)dest); | 78 | ret = regmap_raw_read(wm8350->regmap, reg, dest, bytes); |
78 | 79 | ||
79 | for (i = reg; i < reg + num_regs; i++) { | 80 | for (i = reg; i < reg + num_regs; i++) { |
80 | /* Cache is CPU endian */ | 81 | /* Cache is CPU endian */ |
@@ -96,9 +97,6 @@ static int wm8350_read(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *dest) | |||
96 | int ret = 0; | 97 | int ret = 0; |
97 | int bytes = num_regs * 2; | 98 | int bytes = num_regs * 2; |
98 | 99 | ||
99 | if (wm8350->read_dev == NULL) | ||
100 | return -ENODEV; | ||
101 | |||
102 | if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { | 100 | if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { |
103 | dev_err(wm8350->dev, "invalid reg %x\n", | 101 | dev_err(wm8350->dev, "invalid reg %x\n", |
104 | reg + num_regs - 1); | 102 | reg + num_regs - 1); |
@@ -149,9 +147,6 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src) | |||
149 | int end = reg + num_regs; | 147 | int end = reg + num_regs; |
150 | int bytes = num_regs * 2; | 148 | int bytes = num_regs * 2; |
151 | 149 | ||
152 | if (wm8350->write_dev == NULL) | ||
153 | return -ENODEV; | ||
154 | |||
155 | if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { | 150 | if ((reg + num_regs - 1) > WM8350_MAX_REGISTER) { |
156 | dev_err(wm8350->dev, "invalid reg %x\n", | 151 | dev_err(wm8350->dev, "invalid reg %x\n", |
157 | reg + num_regs - 1); | 152 | reg + num_regs - 1); |
@@ -182,7 +177,7 @@ static int wm8350_write(struct wm8350 *wm8350, u8 reg, int num_regs, u16 *src) | |||
182 | } | 177 | } |
183 | 178 | ||
184 | /* Actually write it out */ | 179 | /* Actually write it out */ |
185 | return wm8350->write_dev(wm8350, reg, bytes, (char *)src); | 180 | return regmap_raw_write(wm8350->regmap, reg, src, bytes); |
186 | } | 181 | } |
187 | 182 | ||
188 | /* | 183 | /* |
@@ -515,9 +510,8 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode) | |||
515 | * a PMIC so the device many not be in a virgin state and we | 510 | * a PMIC so the device many not be in a virgin state and we |
516 | * can't rely on the silicon values. | 511 | * can't rely on the silicon values. |
517 | */ | 512 | */ |
518 | ret = wm8350->read_dev(wm8350, 0, | 513 | ret = regmap_raw_read(wm8350->regmap, 0, wm8350->reg_cache, |
519 | sizeof(u16) * (WM8350_MAX_REGISTER + 1), | 514 | sizeof(u16) * (WM8350_MAX_REGISTER + 1)); |
520 | wm8350->reg_cache); | ||
521 | if (ret < 0) { | 515 | if (ret < 0) { |
522 | dev_err(wm8350->dev, | 516 | dev_err(wm8350->dev, |
523 | "failed to read initial cache values\n"); | 517 | "failed to read initial cache values\n"); |
@@ -570,35 +564,30 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, | |||
570 | struct wm8350_platform_data *pdata) | 564 | struct wm8350_platform_data *pdata) |
571 | { | 565 | { |
572 | int ret; | 566 | int ret; |
573 | u16 id1, id2, mask_rev; | 567 | unsigned int id1, id2, mask_rev; |
574 | u16 cust_id, mode, chip_rev; | 568 | unsigned int cust_id, mode, chip_rev; |
575 | 569 | ||
576 | dev_set_drvdata(wm8350->dev, wm8350); | 570 | dev_set_drvdata(wm8350->dev, wm8350); |
577 | 571 | ||
578 | /* get WM8350 revision and config mode */ | 572 | /* get WM8350 revision and config mode */ |
579 | ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); | 573 | ret = regmap_read(wm8350->regmap, WM8350_RESET_ID, &id1); |
580 | if (ret != 0) { | 574 | if (ret != 0) { |
581 | dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); | 575 | dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); |
582 | goto err; | 576 | goto err; |
583 | } | 577 | } |
584 | 578 | ||
585 | ret = wm8350->read_dev(wm8350, WM8350_ID, sizeof(id2), &id2); | 579 | ret = regmap_read(wm8350->regmap, WM8350_ID, &id2); |
586 | if (ret != 0) { | 580 | if (ret != 0) { |
587 | dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); | 581 | dev_err(wm8350->dev, "Failed to read ID: %d\n", ret); |
588 | goto err; | 582 | goto err; |
589 | } | 583 | } |
590 | 584 | ||
591 | ret = wm8350->read_dev(wm8350, WM8350_REVISION, sizeof(mask_rev), | 585 | ret = regmap_read(wm8350->regmap, WM8350_REVISION, &mask_rev); |
592 | &mask_rev); | ||
593 | if (ret != 0) { | 586 | if (ret != 0) { |
594 | dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); | 587 | dev_err(wm8350->dev, "Failed to read revision: %d\n", ret); |
595 | goto err; | 588 | goto err; |
596 | } | 589 | } |
597 | 590 | ||
598 | id1 = be16_to_cpu(id1); | ||
599 | id2 = be16_to_cpu(id2); | ||
600 | mask_rev = be16_to_cpu(mask_rev); | ||
601 | |||
602 | if (id1 != 0x6143) { | 591 | if (id1 != 0x6143) { |
603 | dev_err(wm8350->dev, | 592 | dev_err(wm8350->dev, |
604 | "Device with ID %x is not a WM8350\n", id1); | 593 | "Device with ID %x is not a WM8350\n", id1); |
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index d955faaf27c4..a68aceb4e48c 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c | |||
@@ -15,47 +15,18 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/err.h> | ||
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | #include <linux/mfd/wm8350/core.h> | 22 | #include <linux/mfd/wm8350/core.h> |
23 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
23 | 25 | ||
24 | static int wm8350_i2c_read_device(struct wm8350 *wm8350, char reg, | 26 | static const struct regmap_config wm8350_regmap = { |
25 | int bytes, void *dest) | 27 | .reg_bits = 8, |
26 | { | 28 | .val_bits = 16, |
27 | int ret; | 29 | }; |
28 | |||
29 | ret = i2c_master_send(wm8350->i2c_client, ®, 1); | ||
30 | if (ret < 0) | ||
31 | return ret; | ||
32 | ret = i2c_master_recv(wm8350->i2c_client, dest, bytes); | ||
33 | if (ret < 0) | ||
34 | return ret; | ||
35 | if (ret != bytes) | ||
36 | return -EIO; | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static int wm8350_i2c_write_device(struct wm8350 *wm8350, char reg, | ||
41 | int bytes, void *src) | ||
42 | { | ||
43 | /* we add 1 byte for device register */ | ||
44 | u8 msg[(WM8350_MAX_REGISTER << 1) + 1]; | ||
45 | int ret; | ||
46 | |||
47 | if (bytes > ((WM8350_MAX_REGISTER << 1) + 1)) | ||
48 | return -EINVAL; | ||
49 | |||
50 | msg[0] = reg; | ||
51 | memcpy(&msg[1], src, bytes); | ||
52 | ret = i2c_master_send(wm8350->i2c_client, msg, bytes + 1); | ||
53 | if (ret < 0) | ||
54 | return ret; | ||
55 | if (ret != bytes + 1) | ||
56 | return -EIO; | ||
57 | return 0; | ||
58 | } | ||
59 | 30 | ||
60 | static int wm8350_i2c_probe(struct i2c_client *i2c, | 31 | static int wm8350_i2c_probe(struct i2c_client *i2c, |
61 | const struct i2c_device_id *id) | 32 | const struct i2c_device_id *id) |
@@ -67,20 +38,18 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, | |||
67 | if (wm8350 == NULL) | 38 | if (wm8350 == NULL) |
68 | return -ENOMEM; | 39 | return -ENOMEM; |
69 | 40 | ||
41 | wm8350->regmap = devm_regmap_init_i2c(i2c, &wm8350_regmap); | ||
42 | if (IS_ERR(wm8350->regmap)) { | ||
43 | ret = PTR_ERR(wm8350->regmap); | ||
44 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
45 | ret); | ||
46 | return ret; | ||
47 | } | ||
48 | |||
70 | i2c_set_clientdata(i2c, wm8350); | 49 | i2c_set_clientdata(i2c, wm8350); |
71 | wm8350->dev = &i2c->dev; | 50 | wm8350->dev = &i2c->dev; |
72 | wm8350->i2c_client = i2c; | ||
73 | wm8350->read_dev = wm8350_i2c_read_device; | ||
74 | wm8350->write_dev = wm8350_i2c_write_device; | ||
75 | |||
76 | ret = wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data); | ||
77 | if (ret < 0) | ||
78 | goto err; | ||
79 | |||
80 | return ret; | ||
81 | 51 | ||
82 | err: | 52 | return wm8350_device_init(wm8350, i2c->irq, i2c->dev.platform_data); |
83 | return ret; | ||
84 | } | 53 | } |
85 | 54 | ||
86 | static int wm8350_i2c_remove(struct i2c_client *i2c) | 55 | static int wm8350_i2c_remove(struct i2c_client *i2c) |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 1189a17f0f25..4b7d378551d5 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -23,136 +23,16 @@ | |||
23 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | static struct { | 26 | static bool wm8400_volatile(struct device *dev, unsigned int reg) |
27 | u16 readable; /* Mask of readable bits */ | ||
28 | u16 writable; /* Mask of writable bits */ | ||
29 | u16 vol; /* Mask of volatile bits */ | ||
30 | int is_codec; /* Register controlled by codec reset */ | ||
31 | u16 default_val; /* Value on reset */ | ||
32 | } reg_data[] = { | ||
33 | { 0xFFFF, 0xFFFF, 0x0000, 0, 0x6172 }, /* R0 */ | ||
34 | { 0x7000, 0x0000, 0x8000, 0, 0x0000 }, /* R1 */ | ||
35 | { 0xFF17, 0xFF17, 0x0000, 0, 0x0000 }, /* R2 */ | ||
36 | { 0xEBF3, 0xEBF3, 0x0000, 1, 0x6000 }, /* R3 */ | ||
37 | { 0x3CF3, 0x3CF3, 0x0000, 1, 0x0000 }, /* R4 */ | ||
38 | { 0xF1F8, 0xF1F8, 0x0000, 1, 0x4050 }, /* R5 */ | ||
39 | { 0xFC1F, 0xFC1F, 0x0000, 1, 0x4000 }, /* R6 */ | ||
40 | { 0xDFDE, 0xDFDE, 0x0000, 1, 0x01C8 }, /* R7 */ | ||
41 | { 0xFCFC, 0xFCFC, 0x0000, 1, 0x0000 }, /* R8 */ | ||
42 | { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R9 */ | ||
43 | { 0xEFFF, 0xEFFF, 0x0000, 1, 0x0040 }, /* R10 */ | ||
44 | { 0x27F7, 0x27F7, 0x0000, 1, 0x0004 }, /* R11 */ | ||
45 | { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R12 */ | ||
46 | { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R13 */ | ||
47 | { 0x1FEF, 0x1FEF, 0x0000, 1, 0x0000 }, /* R14 */ | ||
48 | { 0x0163, 0x0163, 0x0000, 1, 0x0100 }, /* R15 */ | ||
49 | { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R16 */ | ||
50 | { 0x01FF, 0x01FF, 0x0000, 1, 0x00C0 }, /* R17 */ | ||
51 | { 0x1FFF, 0x0FFF, 0x0000, 1, 0x0000 }, /* R18 */ | ||
52 | { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1000 }, /* R19 */ | ||
53 | { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R20 */ | ||
54 | { 0xFFFF, 0xFFFF, 0x0000, 1, 0x1010 }, /* R21 */ | ||
55 | { 0x0FDD, 0x0FDD, 0x0000, 1, 0x8000 }, /* R22 */ | ||
56 | { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0800 }, /* R23 */ | ||
57 | { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R24 */ | ||
58 | { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R25 */ | ||
59 | { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R26 */ | ||
60 | { 0x0000, 0x01DF, 0x0000, 1, 0x008B }, /* R27 */ | ||
61 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R28 */ | ||
62 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R29 */ | ||
63 | { 0x0000, 0x0077, 0x0000, 1, 0x0066 }, /* R30 */ | ||
64 | { 0x0000, 0x0033, 0x0000, 1, 0x0022 }, /* R31 */ | ||
65 | { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R32 */ | ||
66 | { 0x0000, 0x01FF, 0x0000, 1, 0x0079 }, /* R33 */ | ||
67 | { 0x0000, 0x0003, 0x0000, 1, 0x0003 }, /* R34 */ | ||
68 | { 0x0000, 0x01FF, 0x0000, 1, 0x0003 }, /* R35 */ | ||
69 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R36 */ | ||
70 | { 0x0000, 0x003F, 0x0000, 1, 0x0100 }, /* R37 */ | ||
71 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R38 */ | ||
72 | { 0x0000, 0x000F, 0x0000, 0, 0x0000 }, /* R39 */ | ||
73 | { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R40 */ | ||
74 | { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R41 */ | ||
75 | { 0x0000, 0x01B7, 0x0000, 1, 0x0000 }, /* R42 */ | ||
76 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R43 */ | ||
77 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R44 */ | ||
78 | { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R45 */ | ||
79 | { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R46 */ | ||
80 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R47 */ | ||
81 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R48 */ | ||
82 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R49 */ | ||
83 | { 0x0000, 0x01FF, 0x0000, 1, 0x0000 }, /* R50 */ | ||
84 | { 0x0000, 0x01B3, 0x0000, 1, 0x0180 }, /* R51 */ | ||
85 | { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R52 */ | ||
86 | { 0x0000, 0x0077, 0x0000, 1, 0x0000 }, /* R53 */ | ||
87 | { 0x0000, 0x00FF, 0x0000, 1, 0x0000 }, /* R54 */ | ||
88 | { 0x0000, 0x0001, 0x0000, 1, 0x0000 }, /* R55 */ | ||
89 | { 0x0000, 0x003F, 0x0000, 1, 0x0000 }, /* R56 */ | ||
90 | { 0x0000, 0x004F, 0x0000, 1, 0x0000 }, /* R57 */ | ||
91 | { 0x0000, 0x00FD, 0x0000, 1, 0x0000 }, /* R58 */ | ||
92 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R59 */ | ||
93 | { 0x1FFF, 0x1FFF, 0x0000, 1, 0x0000 }, /* R60 */ | ||
94 | { 0xFFFF, 0xFFFF, 0x0000, 1, 0x0000 }, /* R61 */ | ||
95 | { 0x03FF, 0x03FF, 0x0000, 1, 0x0000 }, /* R62 */ | ||
96 | { 0x007F, 0x007F, 0x0000, 1, 0x0000 }, /* R63 */ | ||
97 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R64 */ | ||
98 | { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R65 */ | ||
99 | { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R66 */ | ||
100 | { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R67 */ | ||
101 | { 0xDFFF, 0xDFFF, 0x0000, 0, 0x0000 }, /* R68 */ | ||
102 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R69 */ | ||
103 | { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R70 */ | ||
104 | { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R71 */ | ||
105 | { 0xFFFF, 0xFFFF, 0x0000, 0, 0x4400 }, /* R72 */ | ||
106 | { 0x23FF, 0x23FF, 0x0000, 0, 0x0000 }, /* R73 */ | ||
107 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R74 */ | ||
108 | { 0x000E, 0x000E, 0x0000, 0, 0x0008 }, /* R75 */ | ||
109 | { 0xE00F, 0xE00F, 0x0000, 0, 0x0000 }, /* R76 */ | ||
110 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R77 */ | ||
111 | { 0x03C0, 0x03C0, 0x0000, 0, 0x02C0 }, /* R78 */ | ||
112 | { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R79 */ | ||
113 | { 0xFFFF, 0xFFFF, 0x0000, 0, 0x0000 }, /* R80 */ | ||
114 | { 0xFFFF, 0x0000, 0xffff, 0, 0x0000 }, /* R81 */ | ||
115 | { 0x2BFF, 0x0000, 0xffff, 0, 0x0000 }, /* R82 */ | ||
116 | { 0x0000, 0x0000, 0x0000, 0, 0x0000 }, /* R83 */ | ||
117 | { 0x80FF, 0x80FF, 0x0000, 0, 0x00ff }, /* R84 */ | ||
118 | }; | ||
119 | |||
120 | static int wm8400_read(struct wm8400 *wm8400, u8 reg, int num_regs, u16 *dest) | ||
121 | { | 27 | { |
122 | int i, ret = 0; | 28 | switch (reg) { |
123 | 29 | case WM8400_INTERRUPT_STATUS_1: | |
124 | BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); | 30 | case WM8400_INTERRUPT_LEVELS: |
125 | 31 | case WM8400_SHUTDOWN_REASON: | |
126 | /* If there are any volatile reads then read back the entire block */ | 32 | return true; |
127 | for (i = reg; i < reg + num_regs; i++) | 33 | default: |
128 | if (reg_data[i].vol) { | 34 | return false; |
129 | ret = regmap_bulk_read(wm8400->regmap, reg, dest, | ||
130 | num_regs); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | /* Otherwise use the cache */ | ||
135 | memcpy(dest, &wm8400->reg_cache[reg], num_regs * sizeof(u16)); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs, | ||
141 | u16 *src) | ||
142 | { | ||
143 | int ret, i; | ||
144 | |||
145 | BUG_ON(reg + num_regs > ARRAY_SIZE(wm8400->reg_cache)); | ||
146 | |||
147 | for (i = 0; i < num_regs; i++) { | ||
148 | BUG_ON(!reg_data[reg + i].writable); | ||
149 | wm8400->reg_cache[reg + i] = src[i]; | ||
150 | ret = regmap_write(wm8400->regmap, reg, src[i]); | ||
151 | if (ret != 0) | ||
152 | return ret; | ||
153 | } | 35 | } |
154 | |||
155 | return 0; | ||
156 | } | 36 | } |
157 | 37 | ||
158 | /** | 38 | /** |
@@ -165,13 +45,12 @@ static int wm8400_write(struct wm8400 *wm8400, u8 reg, int num_regs, | |||
165 | */ | 45 | */ |
166 | u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg) | 46 | u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg) |
167 | { | 47 | { |
168 | u16 val; | 48 | unsigned int val; |
169 | 49 | int ret; | |
170 | mutex_lock(&wm8400->io_lock); | ||
171 | |||
172 | wm8400_read(wm8400, reg, 1, &val); | ||
173 | 50 | ||
174 | mutex_unlock(&wm8400->io_lock); | 51 | ret = regmap_read(wm8400->regmap, reg, &val); |
52 | if (ret < 0) | ||
53 | return ret; | ||
175 | 54 | ||
176 | return val; | 55 | return val; |
177 | } | 56 | } |
@@ -179,63 +58,10 @@ EXPORT_SYMBOL_GPL(wm8400_reg_read); | |||
179 | 58 | ||
180 | int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data) | 59 | int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data) |
181 | { | 60 | { |
182 | int ret; | 61 | return regmap_bulk_read(wm8400->regmap, reg, data, count); |
183 | |||
184 | mutex_lock(&wm8400->io_lock); | ||
185 | |||
186 | ret = wm8400_read(wm8400, reg, count, data); | ||
187 | |||
188 | mutex_unlock(&wm8400->io_lock); | ||
189 | |||
190 | return ret; | ||
191 | } | 62 | } |
192 | EXPORT_SYMBOL_GPL(wm8400_block_read); | 63 | EXPORT_SYMBOL_GPL(wm8400_block_read); |
193 | 64 | ||
194 | /** | ||
195 | * wm8400_set_bits - Bitmask write | ||
196 | * | ||
197 | * @wm8400: Pointer to wm8400 control structure | ||
198 | * @reg: Register to access | ||
199 | * @mask: Mask of bits to change | ||
200 | * @val: Value to set for masked bits | ||
201 | */ | ||
202 | int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val) | ||
203 | { | ||
204 | u16 tmp; | ||
205 | int ret; | ||
206 | |||
207 | mutex_lock(&wm8400->io_lock); | ||
208 | |||
209 | ret = wm8400_read(wm8400, reg, 1, &tmp); | ||
210 | tmp = (tmp & ~mask) | val; | ||
211 | if (ret == 0) | ||
212 | ret = wm8400_write(wm8400, reg, 1, &tmp); | ||
213 | |||
214 | mutex_unlock(&wm8400->io_lock); | ||
215 | |||
216 | return ret; | ||
217 | } | ||
218 | EXPORT_SYMBOL_GPL(wm8400_set_bits); | ||
219 | |||
220 | /** | ||
221 | * wm8400_reset_codec_reg_cache - Reset cached codec registers to | ||
222 | * their default values. | ||
223 | */ | ||
224 | void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) | ||
225 | { | ||
226 | int i; | ||
227 | |||
228 | mutex_lock(&wm8400->io_lock); | ||
229 | |||
230 | /* Reset all codec registers to their initial value */ | ||
231 | for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) | ||
232 | if (reg_data[i].is_codec) | ||
233 | wm8400->reg_cache[i] = reg_data[i].default_val; | ||
234 | |||
235 | mutex_unlock(&wm8400->io_lock); | ||
236 | } | ||
237 | EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); | ||
238 | |||
239 | static int wm8400_register_codec(struct wm8400 *wm8400) | 65 | static int wm8400_register_codec(struct wm8400 *wm8400) |
240 | { | 66 | { |
241 | struct mfd_cell cell = { | 67 | struct mfd_cell cell = { |
@@ -257,44 +83,24 @@ static int wm8400_register_codec(struct wm8400 *wm8400) | |||
257 | static int wm8400_init(struct wm8400 *wm8400, | 83 | static int wm8400_init(struct wm8400 *wm8400, |
258 | struct wm8400_platform_data *pdata) | 84 | struct wm8400_platform_data *pdata) |
259 | { | 85 | { |
260 | u16 reg; | 86 | unsigned int reg; |
261 | int ret, i; | 87 | int ret; |
262 | |||
263 | mutex_init(&wm8400->io_lock); | ||
264 | 88 | ||
265 | dev_set_drvdata(wm8400->dev, wm8400); | 89 | dev_set_drvdata(wm8400->dev, wm8400); |
266 | 90 | ||
267 | /* Check that this is actually a WM8400 */ | 91 | /* Check that this is actually a WM8400 */ |
268 | ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, &i); | 92 | ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, ®); |
269 | if (ret != 0) { | 93 | if (ret != 0) { |
270 | dev_err(wm8400->dev, "Chip ID register read failed\n"); | 94 | dev_err(wm8400->dev, "Chip ID register read failed\n"); |
271 | return -EIO; | 95 | return -EIO; |
272 | } | 96 | } |
273 | if (i != reg_data[WM8400_RESET_ID].default_val) { | 97 | if (reg != 0x6172) { |
274 | dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", i); | 98 | dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n", |
99 | reg); | ||
275 | return -ENODEV; | 100 | return -ENODEV; |
276 | } | 101 | } |
277 | 102 | ||
278 | /* We don't know what state the hardware is in and since this | 103 | ret = regmap_read(wm8400->regmap, WM8400_ID, ®); |
279 | * is a PMIC we can't reset it safely so initialise the register | ||
280 | * cache from the hardware. | ||
281 | */ | ||
282 | ret = regmap_raw_read(wm8400->regmap, 0, wm8400->reg_cache, | ||
283 | ARRAY_SIZE(wm8400->reg_cache)); | ||
284 | if (ret != 0) { | ||
285 | dev_err(wm8400->dev, "Register cache read failed\n"); | ||
286 | return -EIO; | ||
287 | } | ||
288 | for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) | ||
289 | wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]); | ||
290 | |||
291 | /* If the codec is in reset use hard coded values */ | ||
292 | if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA)) | ||
293 | for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) | ||
294 | if (reg_data[i].is_codec) | ||
295 | wm8400->reg_cache[i] = reg_data[i].default_val; | ||
296 | |||
297 | ret = wm8400_read(wm8400, WM8400_ID, 1, ®); | ||
298 | if (ret != 0) { | 104 | if (ret != 0) { |
299 | dev_err(wm8400->dev, "ID register read failed: %d\n", ret); | 105 | dev_err(wm8400->dev, "ID register read failed: %d\n", ret); |
300 | return ret; | 106 | return ret; |
@@ -334,8 +140,22 @@ static const struct regmap_config wm8400_regmap_config = { | |||
334 | .reg_bits = 8, | 140 | .reg_bits = 8, |
335 | .val_bits = 16, | 141 | .val_bits = 16, |
336 | .max_register = WM8400_REGISTER_COUNT - 1, | 142 | .max_register = WM8400_REGISTER_COUNT - 1, |
143 | |||
144 | .volatile_reg = wm8400_volatile, | ||
145 | |||
146 | .cache_type = REGCACHE_RBTREE, | ||
337 | }; | 147 | }; |
338 | 148 | ||
149 | /** | ||
150 | * wm8400_reset_codec_reg_cache - Reset cached codec registers to | ||
151 | * their default values. | ||
152 | */ | ||
153 | void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400) | ||
154 | { | ||
155 | regmap_reinit_cache(wm8400->regmap, &wm8400_regmap_config); | ||
156 | } | ||
157 | EXPORT_SYMBOL_GPL(wm8400_reset_codec_reg_cache); | ||
158 | |||
339 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 159 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
340 | static int wm8400_i2c_probe(struct i2c_client *i2c, | 160 | static int wm8400_i2c_probe(struct i2c_client *i2c, |
341 | const struct i2c_device_id *id) | 161 | const struct i2c_device_id *id) |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index 9d7ca1e978fa..1e321d349777 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -500,7 +500,8 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
500 | ret); | 500 | ret); |
501 | goto err_enable; | 501 | goto err_enable; |
502 | } | 502 | } |
503 | wm8994->revision = ret; | 503 | wm8994->revision = ret & WM8994_CHIP_REV_MASK; |
504 | wm8994->cust_id = (ret & WM8994_CUST_ID_MASK) >> WM8994_CUST_ID_SHIFT; | ||
504 | 505 | ||
505 | switch (wm8994->type) { | 506 | switch (wm8994->type) { |
506 | case WM8994: | 507 | case WM8994: |
@@ -553,8 +554,8 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
553 | break; | 554 | break; |
554 | } | 555 | } |
555 | 556 | ||
556 | dev_info(wm8994->dev, "%s revision %c\n", devname, | 557 | dev_info(wm8994->dev, "%s revision %c CUST_ID %02x\n", devname, |
557 | 'A' + wm8994->revision); | 558 | 'A' + wm8994->revision, wm8994->cust_id); |
558 | 559 | ||
559 | switch (wm8994->type) { | 560 | switch (wm8994->type) { |
560 | case WM1811: | 561 | case WM1811: |
@@ -732,23 +733,7 @@ static struct i2c_driver wm8994_i2c_driver = { | |||
732 | .id_table = wm8994_i2c_id, | 733 | .id_table = wm8994_i2c_id, |
733 | }; | 734 | }; |
734 | 735 | ||
735 | static int __init wm8994_i2c_init(void) | 736 | module_i2c_driver(wm8994_i2c_driver); |
736 | { | ||
737 | int ret; | ||
738 | |||
739 | ret = i2c_add_driver(&wm8994_i2c_driver); | ||
740 | if (ret != 0) | ||
741 | pr_err("Failed to register wm8994 I2C driver: %d\n", ret); | ||
742 | |||
743 | return ret; | ||
744 | } | ||
745 | module_init(wm8994_i2c_init); | ||
746 | |||
747 | static void __exit wm8994_i2c_exit(void) | ||
748 | { | ||
749 | i2c_del_driver(&wm8994_i2c_driver); | ||
750 | } | ||
751 | module_exit(wm8994_i2c_exit); | ||
752 | 737 | ||
753 | MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); | 738 | MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC"); |
754 | MODULE_LICENSE("GPL"); | 739 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c index bfd25af6ecb1..52e9e2944940 100644 --- a/drivers/mfd/wm8994-regmap.c +++ b/drivers/mfd/wm8994-regmap.c | |||
@@ -1122,7 +1122,6 @@ static bool wm8994_volatile_register(struct device *dev, unsigned int reg) | |||
1122 | case WM8994_RATE_STATUS: | 1122 | case WM8994_RATE_STATUS: |
1123 | case WM8958_MIC_DETECT_3: | 1123 | case WM8958_MIC_DETECT_3: |
1124 | case WM8994_DC_SERVO_4E: | 1124 | case WM8994_DC_SERVO_4E: |
1125 | case WM8994_CHIP_REVISION: | ||
1126 | case WM8994_INTERRUPT_STATUS_1: | 1125 | case WM8994_INTERRUPT_STATUS_1: |
1127 | case WM8994_INTERRUPT_STATUS_2: | 1126 | case WM8994_INTERRUPT_STATUS_2: |
1128 | return true; | 1127 | return true; |
diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c index d7a9aa14e5d5..042a8fe4efaa 100644 --- a/drivers/misc/ab8500-pwm.c +++ b/drivers/misc/ab8500-pwm.c | |||
@@ -142,10 +142,16 @@ static int __devexit ab8500_pwm_remove(struct platform_device *pdev) | |||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | static const struct of_device_id ab8500_pwm_match[] = { | ||
146 | { .compatible = "stericsson,ab8500-pwm", }, | ||
147 | {} | ||
148 | }; | ||
149 | |||
145 | static struct platform_driver ab8500_pwm_driver = { | 150 | static struct platform_driver ab8500_pwm_driver = { |
146 | .driver = { | 151 | .driver = { |
147 | .name = "ab8500-pwm", | 152 | .name = "ab8500-pwm", |
148 | .owner = THIS_MODULE, | 153 | .owner = THIS_MODULE, |
154 | .of_match_table = ab8500_pwm_match, | ||
149 | }, | 155 | }, |
150 | .probe = ab8500_pwm_probe, | 156 | .probe = ab8500_pwm_probe, |
151 | .remove = __devexit_p(ab8500_pwm_remove), | 157 | .remove = __devexit_p(ab8500_pwm_remove), |
diff --git a/drivers/power/wm831x_power.c b/drivers/power/wm831x_power.c index 987332b71d8d..fc1ad9551182 100644 --- a/drivers/power/wm831x_power.c +++ b/drivers/power/wm831x_power.c | |||
@@ -565,7 +565,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) | |||
565 | goto err_usb; | 565 | goto err_usb; |
566 | } | 566 | } |
567 | 567 | ||
568 | irq = platform_get_irq_byname(pdev, "SYSLO"); | 568 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO")); |
569 | ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq, | 569 | ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq, |
570 | IRQF_TRIGGER_RISING, "System power low", | 570 | IRQF_TRIGGER_RISING, "System power low", |
571 | power); | 571 | power); |
@@ -575,7 +575,7 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) | |||
575 | goto err_battery; | 575 | goto err_battery; |
576 | } | 576 | } |
577 | 577 | ||
578 | irq = platform_get_irq_byname(pdev, "PWR SRC"); | 578 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC")); |
579 | ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq, | 579 | ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq, |
580 | IRQF_TRIGGER_RISING, "Power source", | 580 | IRQF_TRIGGER_RISING, "Power source", |
581 | power); | 581 | power); |
@@ -586,7 +586,9 @@ static __devinit int wm831x_power_probe(struct platform_device *pdev) | |||
586 | } | 586 | } |
587 | 587 | ||
588 | for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { | 588 | for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { |
589 | irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); | 589 | irq = wm831x_irq(wm831x, |
590 | platform_get_irq_byname(pdev, | ||
591 | wm831x_bat_irqs[i])); | ||
590 | ret = request_threaded_irq(irq, NULL, wm831x_bat_irq, | 592 | ret = request_threaded_irq(irq, NULL, wm831x_bat_irq, |
591 | IRQF_TRIGGER_RISING, | 593 | IRQF_TRIGGER_RISING, |
592 | wm831x_bat_irqs[i], | 594 | wm831x_bat_irqs[i], |
@@ -606,10 +608,10 @@ err_bat_irq: | |||
606 | irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); | 608 | irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); |
607 | free_irq(irq, power); | 609 | free_irq(irq, power); |
608 | } | 610 | } |
609 | irq = platform_get_irq_byname(pdev, "PWR SRC"); | 611 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC")); |
610 | free_irq(irq, power); | 612 | free_irq(irq, power); |
611 | err_syslo: | 613 | err_syslo: |
612 | irq = platform_get_irq_byname(pdev, "SYSLO"); | 614 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO")); |
613 | free_irq(irq, power); | 615 | free_irq(irq, power); |
614 | err_battery: | 616 | err_battery: |
615 | if (power->have_battery) | 617 | if (power->have_battery) |
@@ -626,17 +628,20 @@ err_kmalloc: | |||
626 | static __devexit int wm831x_power_remove(struct platform_device *pdev) | 628 | static __devexit int wm831x_power_remove(struct platform_device *pdev) |
627 | { | 629 | { |
628 | struct wm831x_power *wm831x_power = platform_get_drvdata(pdev); | 630 | struct wm831x_power *wm831x_power = platform_get_drvdata(pdev); |
631 | struct wm831x *wm831x = wm831x_power->wm831x; | ||
629 | int irq, i; | 632 | int irq, i; |
630 | 633 | ||
631 | for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { | 634 | for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) { |
632 | irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]); | 635 | irq = wm831x_irq(wm831x, |
636 | platform_get_irq_byname(pdev, | ||
637 | wm831x_bat_irqs[i])); | ||
633 | free_irq(irq, wm831x_power); | 638 | free_irq(irq, wm831x_power); |
634 | } | 639 | } |
635 | 640 | ||
636 | irq = platform_get_irq_byname(pdev, "PWR SRC"); | 641 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "PWR SRC")); |
637 | free_irq(irq, wm831x_power); | 642 | free_irq(irq, wm831x_power); |
638 | 643 | ||
639 | irq = platform_get_irq_byname(pdev, "SYSLO"); | 644 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "SYSLO")); |
640 | free_irq(irq, wm831x_power); | 645 | free_irq(irq, wm831x_power); |
641 | 646 | ||
642 | if (wm831x_power->have_battery) | 647 | if (wm831x_power->have_battery) |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index 49b2112b0486..3660bace123c 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -47,7 +47,7 @@ static int anatop_set_voltage(struct regulator_dev *reg, int min_uV, | |||
47 | int max_uV, unsigned *selector) | 47 | int max_uV, unsigned *selector) |
48 | { | 48 | { |
49 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 49 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
50 | u32 val, sel; | 50 | u32 val, sel, mask; |
51 | int uv; | 51 | int uv; |
52 | 52 | ||
53 | uv = min_uV; | 53 | uv = min_uV; |
@@ -71,11 +71,10 @@ static int anatop_set_voltage(struct regulator_dev *reg, int min_uV, | |||
71 | val = anatop_reg->min_bit_val + sel; | 71 | val = anatop_reg->min_bit_val + sel; |
72 | *selector = sel; | 72 | *selector = sel; |
73 | dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); | 73 | dev_dbg(®->dev, "%s: calculated val %d\n", __func__, val); |
74 | anatop_set_bits(anatop_reg->mfd, | 74 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << |
75 | anatop_reg->control_reg, | 75 | anatop_reg->vol_bit_shift; |
76 | anatop_reg->vol_bit_shift, | 76 | val <<= anatop_reg->vol_bit_shift; |
77 | anatop_reg->vol_bit_width, | 77 | anatop_write_reg(anatop_reg->mfd, anatop_reg->control_reg, val, mask); |
78 | val); | ||
79 | 78 | ||
80 | return 0; | 79 | return 0; |
81 | } | 80 | } |
@@ -88,10 +87,9 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg) | |||
88 | if (!anatop_reg->control_reg) | 87 | if (!anatop_reg->control_reg) |
89 | return -ENOTSUPP; | 88 | return -ENOTSUPP; |
90 | 89 | ||
91 | val = anatop_get_bits(anatop_reg->mfd, | 90 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); |
92 | anatop_reg->control_reg, | 91 | val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >> |
93 | anatop_reg->vol_bit_shift, | 92 | anatop_reg->vol_bit_shift; |
94 | anatop_reg->vol_bit_width); | ||
95 | 93 | ||
96 | return val - anatop_reg->min_bit_val; | 94 | return val - anatop_reg->min_bit_val; |
97 | } | 95 | } |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 4e01a423471b..6bf864b4bdf6 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -331,21 +331,16 @@ struct tps65910_reg { | |||
331 | 331 | ||
332 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) | 332 | static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) |
333 | { | 333 | { |
334 | u8 val; | 334 | unsigned int val; |
335 | int err; | 335 | int err; |
336 | 336 | ||
337 | err = pmic->mfd->read(pmic->mfd, reg, 1, &val); | 337 | err = tps65910_reg_read(pmic->mfd, reg, &val); |
338 | if (err) | 338 | if (err) |
339 | return err; | 339 | return err; |
340 | 340 | ||
341 | return val; | 341 | return val; |
342 | } | 342 | } |
343 | 343 | ||
344 | static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val) | ||
345 | { | ||
346 | return pmic->mfd->write(pmic->mfd, reg, 1, &val); | ||
347 | } | ||
348 | |||
349 | static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, | 344 | static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, |
350 | u8 set_mask, u8 clear_mask) | 345 | u8 set_mask, u8 clear_mask) |
351 | { | 346 | { |
@@ -362,7 +357,7 @@ static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg, | |||
362 | 357 | ||
363 | data &= ~clear_mask; | 358 | data &= ~clear_mask; |
364 | data |= set_mask; | 359 | data |= set_mask; |
365 | err = tps65910_write(pmic, reg, data); | 360 | err = tps65910_reg_write(pmic->mfd, reg, data); |
366 | if (err) | 361 | if (err) |
367 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); | 362 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); |
368 | 363 | ||
@@ -371,7 +366,7 @@ out: | |||
371 | return err; | 366 | return err; |
372 | } | 367 | } |
373 | 368 | ||
374 | static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg) | 369 | static int tps65910_reg_read_locked(struct tps65910_reg *pmic, u8 reg) |
375 | { | 370 | { |
376 | int data; | 371 | int data; |
377 | 372 | ||
@@ -385,13 +380,13 @@ static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg) | |||
385 | return data; | 380 | return data; |
386 | } | 381 | } |
387 | 382 | ||
388 | static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val) | 383 | static int tps65910_reg_write_locked(struct tps65910_reg *pmic, u8 reg, u8 val) |
389 | { | 384 | { |
390 | int err; | 385 | int err; |
391 | 386 | ||
392 | mutex_lock(&pmic->mutex); | 387 | mutex_lock(&pmic->mutex); |
393 | 388 | ||
394 | err = tps65910_write(pmic, reg, val); | 389 | err = tps65910_reg_write(pmic->mfd, reg, val); |
395 | if (err < 0) | 390 | if (err < 0) |
396 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); | 391 | dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg); |
397 | 392 | ||
@@ -490,9 +485,9 @@ static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode) | |||
490 | LDO_ST_MODE_BIT); | 485 | LDO_ST_MODE_BIT); |
491 | case REGULATOR_MODE_IDLE: | 486 | case REGULATOR_MODE_IDLE: |
492 | value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; | 487 | value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT; |
493 | return tps65910_set_bits(mfd, reg, value); | 488 | return tps65910_reg_set_bits(mfd, reg, value); |
494 | case REGULATOR_MODE_STANDBY: | 489 | case REGULATOR_MODE_STANDBY: |
495 | return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT); | 490 | return tps65910_reg_clear_bits(mfd, reg, LDO_ST_ON_BIT); |
496 | } | 491 | } |
497 | 492 | ||
498 | return -EINVAL; | 493 | return -EINVAL; |
@@ -507,7 +502,7 @@ static unsigned int tps65910_get_mode(struct regulator_dev *dev) | |||
507 | if (reg < 0) | 502 | if (reg < 0) |
508 | return reg; | 503 | return reg; |
509 | 504 | ||
510 | value = tps65910_reg_read(pmic, reg); | 505 | value = tps65910_reg_read_locked(pmic, reg); |
511 | if (value < 0) | 506 | if (value < 0) |
512 | return value; | 507 | return value; |
513 | 508 | ||
@@ -527,28 +522,28 @@ static int tps65910_get_voltage_dcdc_sel(struct regulator_dev *dev) | |||
527 | 522 | ||
528 | switch (id) { | 523 | switch (id) { |
529 | case TPS65910_REG_VDD1: | 524 | case TPS65910_REG_VDD1: |
530 | opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP); | 525 | opvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD1_OP); |
531 | mult = tps65910_reg_read(pmic, TPS65910_VDD1); | 526 | mult = tps65910_reg_read_locked(pmic, TPS65910_VDD1); |
532 | mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; | 527 | mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT; |
533 | srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR); | 528 | srvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD1_SR); |
534 | sr = opvsel & VDD1_OP_CMD_MASK; | 529 | sr = opvsel & VDD1_OP_CMD_MASK; |
535 | opvsel &= VDD1_OP_SEL_MASK; | 530 | opvsel &= VDD1_OP_SEL_MASK; |
536 | srvsel &= VDD1_SR_SEL_MASK; | 531 | srvsel &= VDD1_SR_SEL_MASK; |
537 | vselmax = 75; | 532 | vselmax = 75; |
538 | break; | 533 | break; |
539 | case TPS65910_REG_VDD2: | 534 | case TPS65910_REG_VDD2: |
540 | opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP); | 535 | opvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD2_OP); |
541 | mult = tps65910_reg_read(pmic, TPS65910_VDD2); | 536 | mult = tps65910_reg_read_locked(pmic, TPS65910_VDD2); |
542 | mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; | 537 | mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT; |
543 | srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR); | 538 | srvsel = tps65910_reg_read_locked(pmic, TPS65910_VDD2_SR); |
544 | sr = opvsel & VDD2_OP_CMD_MASK; | 539 | sr = opvsel & VDD2_OP_CMD_MASK; |
545 | opvsel &= VDD2_OP_SEL_MASK; | 540 | opvsel &= VDD2_OP_SEL_MASK; |
546 | srvsel &= VDD2_SR_SEL_MASK; | 541 | srvsel &= VDD2_SR_SEL_MASK; |
547 | vselmax = 75; | 542 | vselmax = 75; |
548 | break; | 543 | break; |
549 | case TPS65911_REG_VDDCTRL: | 544 | case TPS65911_REG_VDDCTRL: |
550 | opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP); | 545 | opvsel = tps65910_reg_read_locked(pmic, TPS65911_VDDCTRL_OP); |
551 | srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR); | 546 | srvsel = tps65910_reg_read_locked(pmic, TPS65911_VDDCTRL_SR); |
552 | sr = opvsel & VDDCTRL_OP_CMD_MASK; | 547 | sr = opvsel & VDDCTRL_OP_CMD_MASK; |
553 | opvsel &= VDDCTRL_OP_SEL_MASK; | 548 | opvsel &= VDDCTRL_OP_SEL_MASK; |
554 | srvsel &= VDDCTRL_SR_SEL_MASK; | 549 | srvsel &= VDDCTRL_SR_SEL_MASK; |
@@ -588,7 +583,7 @@ static int tps65910_get_voltage_sel(struct regulator_dev *dev) | |||
588 | if (reg < 0) | 583 | if (reg < 0) |
589 | return reg; | 584 | return reg; |
590 | 585 | ||
591 | value = tps65910_reg_read(pmic, reg); | 586 | value = tps65910_reg_read_locked(pmic, reg); |
592 | if (value < 0) | 587 | if (value < 0) |
593 | return value; | 588 | return value; |
594 | 589 | ||
@@ -625,7 +620,7 @@ static int tps65911_get_voltage_sel(struct regulator_dev *dev) | |||
625 | 620 | ||
626 | reg = pmic->get_ctrl_reg(id); | 621 | reg = pmic->get_ctrl_reg(id); |
627 | 622 | ||
628 | value = tps65910_reg_read(pmic, reg); | 623 | value = tps65910_reg_read_locked(pmic, reg); |
629 | 624 | ||
630 | switch (id) { | 625 | switch (id) { |
631 | case TPS65911_REG_LDO1: | 626 | case TPS65911_REG_LDO1: |
@@ -670,7 +665,7 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, | |||
670 | tps65910_modify_bits(pmic, TPS65910_VDD1, | 665 | tps65910_modify_bits(pmic, TPS65910_VDD1, |
671 | (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), | 666 | (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), |
672 | VDD1_VGAIN_SEL_MASK); | 667 | VDD1_VGAIN_SEL_MASK); |
673 | tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); | 668 | tps65910_reg_write_locked(pmic, TPS65910_VDD1_OP, vsel); |
674 | break; | 669 | break; |
675 | case TPS65910_REG_VDD2: | 670 | case TPS65910_REG_VDD2: |
676 | dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; | 671 | dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; |
@@ -681,11 +676,11 @@ static int tps65910_set_voltage_dcdc_sel(struct regulator_dev *dev, | |||
681 | tps65910_modify_bits(pmic, TPS65910_VDD2, | 676 | tps65910_modify_bits(pmic, TPS65910_VDD2, |
682 | (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), | 677 | (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), |
683 | VDD1_VGAIN_SEL_MASK); | 678 | VDD1_VGAIN_SEL_MASK); |
684 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); | 679 | tps65910_reg_write_locked(pmic, TPS65910_VDD2_OP, vsel); |
685 | break; | 680 | break; |
686 | case TPS65911_REG_VDDCTRL: | 681 | case TPS65911_REG_VDDCTRL: |
687 | vsel = selector + 3; | 682 | vsel = selector + 3; |
688 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); | 683 | tps65910_reg_write_locked(pmic, TPS65911_VDDCTRL_OP, vsel); |
689 | } | 684 | } |
690 | 685 | ||
691 | return 0; | 686 | return 0; |
@@ -936,10 +931,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | |||
936 | 931 | ||
937 | /* External EN1 control */ | 932 | /* External EN1 control */ |
938 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) | 933 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) |
939 | ret = tps65910_set_bits(mfd, | 934 | ret = tps65910_reg_set_bits(mfd, |
940 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); | 935 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); |
941 | else | 936 | else |
942 | ret = tps65910_clear_bits(mfd, | 937 | ret = tps65910_reg_clear_bits(mfd, |
943 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); | 938 | TPS65910_EN1_LDO_ASS + regoffs, bit_pos); |
944 | if (ret < 0) { | 939 | if (ret < 0) { |
945 | dev_err(mfd->dev, | 940 | dev_err(mfd->dev, |
@@ -949,10 +944,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | |||
949 | 944 | ||
950 | /* External EN2 control */ | 945 | /* External EN2 control */ |
951 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) | 946 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) |
952 | ret = tps65910_set_bits(mfd, | 947 | ret = tps65910_reg_set_bits(mfd, |
953 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); | 948 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); |
954 | else | 949 | else |
955 | ret = tps65910_clear_bits(mfd, | 950 | ret = tps65910_reg_clear_bits(mfd, |
956 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); | 951 | TPS65910_EN2_LDO_ASS + regoffs, bit_pos); |
957 | if (ret < 0) { | 952 | if (ret < 0) { |
958 | dev_err(mfd->dev, | 953 | dev_err(mfd->dev, |
@@ -964,10 +959,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | |||
964 | if ((tps65910_chip_id(mfd) == TPS65910) && | 959 | if ((tps65910_chip_id(mfd) == TPS65910) && |
965 | (id >= TPS65910_REG_VDIG1)) { | 960 | (id >= TPS65910_REG_VDIG1)) { |
966 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) | 961 | if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) |
967 | ret = tps65910_set_bits(mfd, | 962 | ret = tps65910_reg_set_bits(mfd, |
968 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); | 963 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); |
969 | else | 964 | else |
970 | ret = tps65910_clear_bits(mfd, | 965 | ret = tps65910_reg_clear_bits(mfd, |
971 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); | 966 | TPS65910_EN3_LDO_ASS + regoffs, bit_pos); |
972 | if (ret < 0) { | 967 | if (ret < 0) { |
973 | dev_err(mfd->dev, | 968 | dev_err(mfd->dev, |
@@ -979,10 +974,10 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | |||
979 | /* Return if no external control is selected */ | 974 | /* Return if no external control is selected */ |
980 | if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { | 975 | if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { |
981 | /* Clear all sleep controls */ | 976 | /* Clear all sleep controls */ |
982 | ret = tps65910_clear_bits(mfd, | 977 | ret = tps65910_reg_clear_bits(mfd, |
983 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); | 978 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); |
984 | if (!ret) | 979 | if (!ret) |
985 | ret = tps65910_clear_bits(mfd, | 980 | ret = tps65910_reg_clear_bits(mfd, |
986 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | 981 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); |
987 | if (ret < 0) | 982 | if (ret < 0) |
988 | dev_err(mfd->dev, | 983 | dev_err(mfd->dev, |
@@ -1001,32 +996,33 @@ static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, | |||
1001 | (tps65910_chip_id(mfd) == TPS65911))) { | 996 | (tps65910_chip_id(mfd) == TPS65911))) { |
1002 | int op_reg_add = pmic->get_ctrl_reg(id) + 1; | 997 | int op_reg_add = pmic->get_ctrl_reg(id) + 1; |
1003 | int sr_reg_add = pmic->get_ctrl_reg(id) + 2; | 998 | int sr_reg_add = pmic->get_ctrl_reg(id) + 2; |
1004 | int opvsel = tps65910_reg_read(pmic, op_reg_add); | 999 | int opvsel = tps65910_reg_read_locked(pmic, op_reg_add); |
1005 | int srvsel = tps65910_reg_read(pmic, sr_reg_add); | 1000 | int srvsel = tps65910_reg_read_locked(pmic, sr_reg_add); |
1006 | if (opvsel & VDD1_OP_CMD_MASK) { | 1001 | if (opvsel & VDD1_OP_CMD_MASK) { |
1007 | u8 reg_val = srvsel & VDD1_OP_SEL_MASK; | 1002 | u8 reg_val = srvsel & VDD1_OP_SEL_MASK; |
1008 | ret = tps65910_reg_write(pmic, op_reg_add, reg_val); | 1003 | ret = tps65910_reg_write_locked(pmic, op_reg_add, |
1004 | reg_val); | ||
1009 | if (ret < 0) { | 1005 | if (ret < 0) { |
1010 | dev_err(mfd->dev, | 1006 | dev_err(mfd->dev, |
1011 | "Error in configuring op register\n"); | 1007 | "Error in configuring op register\n"); |
1012 | return ret; | 1008 | return ret; |
1013 | } | 1009 | } |
1014 | } | 1010 | } |
1015 | ret = tps65910_reg_write(pmic, sr_reg_add, 0); | 1011 | ret = tps65910_reg_write_locked(pmic, sr_reg_add, 0); |
1016 | if (ret < 0) { | 1012 | if (ret < 0) { |
1017 | dev_err(mfd->dev, "Error in settting sr register\n"); | 1013 | dev_err(mfd->dev, "Error in settting sr register\n"); |
1018 | return ret; | 1014 | return ret; |
1019 | } | 1015 | } |
1020 | } | 1016 | } |
1021 | 1017 | ||
1022 | ret = tps65910_clear_bits(mfd, | 1018 | ret = tps65910_reg_clear_bits(mfd, |
1023 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); | 1019 | TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); |
1024 | if (!ret) { | 1020 | if (!ret) { |
1025 | if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) | 1021 | if (ext_sleep_config & TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP) |
1026 | ret = tps65910_set_bits(mfd, | 1022 | ret = tps65910_reg_set_bits(mfd, |
1027 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | 1023 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); |
1028 | else | 1024 | else |
1029 | ret = tps65910_clear_bits(mfd, | 1025 | ret = tps65910_reg_clear_bits(mfd, |
1030 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); | 1026 | TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); |
1031 | } | 1027 | } |
1032 | if (ret < 0) | 1028 | if (ret < 0) |
@@ -1177,7 +1173,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) | |||
1177 | platform_set_drvdata(pdev, pmic); | 1173 | platform_set_drvdata(pdev, pmic); |
1178 | 1174 | ||
1179 | /* Give control of all register to control port */ | 1175 | /* Give control of all register to control port */ |
1180 | tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL, | 1176 | tps65910_reg_set_bits(pmic->mfd, TPS65910_DEVCTRL, |
1181 | DEVCTRL_SR_CTL_I2C_SEL_MASK); | 1177 | DEVCTRL_SR_CTL_I2C_SEL_MASK); |
1182 | 1178 | ||
1183 | switch(tps65910_chip_id(tps65910)) { | 1179 | switch(tps65910_chip_id(tps65910)) { |
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c index a885911bb5fc..099da11e989f 100644 --- a/drivers/regulator/wm831x-dcdc.c +++ b/drivers/regulator/wm831x-dcdc.c | |||
@@ -535,7 +535,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
535 | goto err; | 535 | goto err; |
536 | } | 536 | } |
537 | 537 | ||
538 | irq = platform_get_irq_byname(pdev, "UV"); | 538 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")); |
539 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, | 539 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, |
540 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); | 540 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); |
541 | if (ret != 0) { | 541 | if (ret != 0) { |
@@ -544,7 +544,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
544 | goto err_regulator; | 544 | goto err_regulator; |
545 | } | 545 | } |
546 | 546 | ||
547 | irq = platform_get_irq_byname(pdev, "HC"); | 547 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC")); |
548 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq, | 548 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq, |
549 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); | 549 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); |
550 | if (ret != 0) { | 550 | if (ret != 0) { |
@@ -558,7 +558,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) | |||
558 | return 0; | 558 | return 0; |
559 | 559 | ||
560 | err_uv: | 560 | err_uv: |
561 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); | 561 | free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")), |
562 | dcdc); | ||
562 | err_regulator: | 563 | err_regulator: |
563 | regulator_unregister(dcdc->regulator); | 564 | regulator_unregister(dcdc->regulator); |
564 | err: | 565 | err: |
@@ -570,11 +571,14 @@ err: | |||
570 | static __devexit int wm831x_buckv_remove(struct platform_device *pdev) | 571 | static __devexit int wm831x_buckv_remove(struct platform_device *pdev) |
571 | { | 572 | { |
572 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); | 573 | struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); |
574 | struct wm831x *wm831x = dcdc->wm831x; | ||
573 | 575 | ||
574 | platform_set_drvdata(pdev, NULL); | 576 | platform_set_drvdata(pdev, NULL); |
575 | 577 | ||
576 | free_irq(platform_get_irq_byname(pdev, "HC"), dcdc); | 578 | free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "HC")), |
577 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); | 579 | dcdc); |
580 | free_irq(wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")), | ||
581 | dcdc); | ||
578 | regulator_unregister(dcdc->regulator); | 582 | regulator_unregister(dcdc->regulator); |
579 | if (dcdc->dvs_gpio) | 583 | if (dcdc->dvs_gpio) |
580 | gpio_free(dcdc->dvs_gpio); | 584 | gpio_free(dcdc->dvs_gpio); |
@@ -726,7 +730,7 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) | |||
726 | goto err; | 730 | goto err; |
727 | } | 731 | } |
728 | 732 | ||
729 | irq = platform_get_irq_byname(pdev, "UV"); | 733 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")); |
730 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, | 734 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, |
731 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); | 735 | IRQF_TRIGGER_RISING, dcdc->name, dcdc); |
732 | if (ret != 0) { | 736 | if (ret != 0) { |
@@ -751,7 +755,8 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev) | |||
751 | 755 | ||
752 | platform_set_drvdata(pdev, NULL); | 756 | platform_set_drvdata(pdev, NULL); |
753 | 757 | ||
754 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); | 758 | free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")), |
759 | dcdc); | ||
755 | regulator_unregister(dcdc->regulator); | 760 | regulator_unregister(dcdc->regulator); |
756 | 761 | ||
757 | return 0; | 762 | return 0; |
@@ -859,7 +864,7 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev) | |||
859 | goto err; | 864 | goto err; |
860 | } | 865 | } |
861 | 866 | ||
862 | irq = platform_get_irq_byname(pdev, "UV"); | 867 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")); |
863 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, | 868 | ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq, |
864 | IRQF_TRIGGER_RISING, dcdc->name, | 869 | IRQF_TRIGGER_RISING, dcdc->name, |
865 | dcdc); | 870 | dcdc); |
@@ -885,7 +890,8 @@ static __devexit int wm831x_boostp_remove(struct platform_device *pdev) | |||
885 | 890 | ||
886 | platform_set_drvdata(pdev, NULL); | 891 | platform_set_drvdata(pdev, NULL); |
887 | 892 | ||
888 | free_irq(platform_get_irq_byname(pdev, "UV"), dcdc); | 893 | free_irq(wm831x_irq(dcdc->wm831x, platform_get_irq_byname(pdev, "UV")), |
894 | dcdc); | ||
889 | regulator_unregister(dcdc->regulator); | 895 | regulator_unregister(dcdc->regulator); |
890 | 896 | ||
891 | return 0; | 897 | return 0; |
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c index b50ab778b098..0d207c297714 100644 --- a/drivers/regulator/wm831x-isink.c +++ b/drivers/regulator/wm831x-isink.c | |||
@@ -202,7 +202,7 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev) | |||
202 | goto err; | 202 | goto err; |
203 | } | 203 | } |
204 | 204 | ||
205 | irq = platform_get_irq(pdev, 0); | 205 | irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0)); |
206 | ret = request_threaded_irq(irq, NULL, wm831x_isink_irq, | 206 | ret = request_threaded_irq(irq, NULL, wm831x_isink_irq, |
207 | IRQF_TRIGGER_RISING, isink->name, isink); | 207 | IRQF_TRIGGER_RISING, isink->name, isink); |
208 | if (ret != 0) { | 208 | if (ret != 0) { |
@@ -227,7 +227,7 @@ static __devexit int wm831x_isink_remove(struct platform_device *pdev) | |||
227 | 227 | ||
228 | platform_set_drvdata(pdev, NULL); | 228 | platform_set_drvdata(pdev, NULL); |
229 | 229 | ||
230 | free_irq(platform_get_irq(pdev, 0), isink); | 230 | free_irq(wm831x_irq(isink->wm831x, platform_get_irq(pdev, 0)), isink); |
231 | 231 | ||
232 | regulator_unregister(isink->regulator); | 232 | regulator_unregister(isink->regulator); |
233 | 233 | ||
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c index aa1f8b3fbe16..a9a28d8ac185 100644 --- a/drivers/regulator/wm831x-ldo.c +++ b/drivers/regulator/wm831x-ldo.c | |||
@@ -321,7 +321,7 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev) | |||
321 | goto err; | 321 | goto err; |
322 | } | 322 | } |
323 | 323 | ||
324 | irq = platform_get_irq_byname(pdev, "UV"); | 324 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")); |
325 | ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, | 325 | ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, |
326 | IRQF_TRIGGER_RISING, ldo->name, | 326 | IRQF_TRIGGER_RISING, ldo->name, |
327 | ldo); | 327 | ldo); |
@@ -347,7 +347,8 @@ static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev) | |||
347 | 347 | ||
348 | platform_set_drvdata(pdev, NULL); | 348 | platform_set_drvdata(pdev, NULL); |
349 | 349 | ||
350 | free_irq(platform_get_irq_byname(pdev, "UV"), ldo); | 350 | free_irq(wm831x_irq(ldo->wm831x, |
351 | platform_get_irq_byname(pdev, "UV")), ldo); | ||
351 | regulator_unregister(ldo->regulator); | 352 | regulator_unregister(ldo->regulator); |
352 | 353 | ||
353 | return 0; | 354 | return 0; |
@@ -582,7 +583,7 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev) | |||
582 | goto err; | 583 | goto err; |
583 | } | 584 | } |
584 | 585 | ||
585 | irq = platform_get_irq_byname(pdev, "UV"); | 586 | irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")); |
586 | ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, | 587 | ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq, |
587 | IRQF_TRIGGER_RISING, ldo->name, ldo); | 588 | IRQF_TRIGGER_RISING, ldo->name, ldo); |
588 | if (ret != 0) { | 589 | if (ret != 0) { |
@@ -605,7 +606,8 @@ static __devexit int wm831x_aldo_remove(struct platform_device *pdev) | |||
605 | { | 606 | { |
606 | struct wm831x_ldo *ldo = platform_get_drvdata(pdev); | 607 | struct wm831x_ldo *ldo = platform_get_drvdata(pdev); |
607 | 608 | ||
608 | free_irq(platform_get_irq_byname(pdev, "UV"), ldo); | 609 | free_irq(wm831x_irq(ldo->wm831x, platform_get_irq_byname(pdev, "UV")), |
610 | ldo); | ||
609 | regulator_unregister(ldo->regulator); | 611 | regulator_unregister(ldo->regulator); |
610 | 612 | ||
611 | return 0; | 613 | return 0; |
diff --git a/drivers/rtc/rtc-wm831x.c b/drivers/rtc/rtc-wm831x.c index 3b6e6a67e765..59c6245e0421 100644 --- a/drivers/rtc/rtc-wm831x.c +++ b/drivers/rtc/rtc-wm831x.c | |||
@@ -396,7 +396,7 @@ static int wm831x_rtc_probe(struct platform_device *pdev) | |||
396 | { | 396 | { |
397 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); | 397 | struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); |
398 | struct wm831x_rtc *wm831x_rtc; | 398 | struct wm831x_rtc *wm831x_rtc; |
399 | int alm_irq = platform_get_irq_byname(pdev, "ALM"); | 399 | int alm_irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "ALM")); |
400 | int ret = 0; | 400 | int ret = 0; |
401 | 401 | ||
402 | wm831x_rtc = devm_kzalloc(&pdev->dev, sizeof(*wm831x_rtc), GFP_KERNEL); | 402 | wm831x_rtc = devm_kzalloc(&pdev->dev, sizeof(*wm831x_rtc), GFP_KERNEL); |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index a18bf6358eb8..d92d7488be16 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -565,6 +565,7 @@ config INTEL_SCU_WATCHDOG | |||
565 | config ITCO_WDT | 565 | config ITCO_WDT |
566 | tristate "Intel TCO Timer/Watchdog" | 566 | tristate "Intel TCO Timer/Watchdog" |
567 | depends on (X86 || IA64) && PCI | 567 | depends on (X86 || IA64) && PCI |
568 | select LPC_ICH | ||
568 | ---help--- | 569 | ---help--- |
569 | Hardware driver for the intel TCO timer based watchdog devices. | 570 | Hardware driver for the intel TCO timer based watchdog devices. |
570 | These drivers are included in the Intel 82801 I/O Controller | 571 | These drivers are included in the Intel 82801 I/O Controller |
diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h index 9e27e6422f66..3c57b45537a2 100644 --- a/drivers/watchdog/iTCO_vendor.h +++ b/drivers/watchdog/iTCO_vendor.h | |||
@@ -1,8 +1,8 @@ | |||
1 | /* iTCO Vendor Specific Support hooks */ | 1 | /* iTCO Vendor Specific Support hooks */ |
2 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT | 2 | #ifdef CONFIG_ITCO_VENDOR_SUPPORT |
3 | extern void iTCO_vendor_pre_start(unsigned long, unsigned int); | 3 | extern void iTCO_vendor_pre_start(struct resource *, unsigned int); |
4 | extern void iTCO_vendor_pre_stop(unsigned long); | 4 | extern void iTCO_vendor_pre_stop(struct resource *); |
5 | extern void iTCO_vendor_pre_keepalive(unsigned long, unsigned int); | 5 | extern void iTCO_vendor_pre_keepalive(struct resource *, unsigned int); |
6 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); | 6 | extern void iTCO_vendor_pre_set_heartbeat(unsigned int); |
7 | extern int iTCO_vendor_check_noreboot_on(void); | 7 | extern int iTCO_vendor_check_noreboot_on(void); |
8 | #else | 8 | #else |
diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c index 2721d29ce243..b6b2f90b5d44 100644 --- a/drivers/watchdog/iTCO_vendor_support.c +++ b/drivers/watchdog/iTCO_vendor_support.c | |||
@@ -35,11 +35,6 @@ | |||
35 | 35 | ||
36 | #include "iTCO_vendor.h" | 36 | #include "iTCO_vendor.h" |
37 | 37 | ||
38 | /* iTCO defines */ | ||
39 | #define SMI_EN (acpibase + 0x30) /* SMI Control and Enable Register */ | ||
40 | #define TCOBASE (acpibase + 0x60) /* TCO base address */ | ||
41 | #define TCO1_STS (TCOBASE + 0x04) /* TCO1 Status Register */ | ||
42 | |||
43 | /* List of vendor support modes */ | 38 | /* List of vendor support modes */ |
44 | /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ | 39 | /* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ |
45 | #define SUPERMICRO_OLD_BOARD 1 | 40 | #define SUPERMICRO_OLD_BOARD 1 |
@@ -82,24 +77,24 @@ MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" | |||
82 | * 20.6 seconds. | 77 | * 20.6 seconds. |
83 | */ | 78 | */ |
84 | 79 | ||
85 | static void supermicro_old_pre_start(unsigned long acpibase) | 80 | static void supermicro_old_pre_start(struct resource *smires) |
86 | { | 81 | { |
87 | unsigned long val32; | 82 | unsigned long val32; |
88 | 83 | ||
89 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ | 84 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ |
90 | val32 = inl(SMI_EN); | 85 | val32 = inl(smires->start); |
91 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ | 86 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ |
92 | outl(val32, SMI_EN); /* Needed to activate watchdog */ | 87 | outl(val32, smires->start); /* Needed to activate watchdog */ |
93 | } | 88 | } |
94 | 89 | ||
95 | static void supermicro_old_pre_stop(unsigned long acpibase) | 90 | static void supermicro_old_pre_stop(struct resource *smires) |
96 | { | 91 | { |
97 | unsigned long val32; | 92 | unsigned long val32; |
98 | 93 | ||
99 | /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ | 94 | /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ |
100 | val32 = inl(SMI_EN); | 95 | val32 = inl(smires->start); |
101 | val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ | 96 | val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ |
102 | outl(val32, SMI_EN); /* Needed to deactivate watchdog */ | 97 | outl(val32, smires->start); /* Needed to deactivate watchdog */ |
103 | } | 98 | } |
104 | 99 | ||
105 | /* | 100 | /* |
@@ -270,66 +265,66 @@ static void supermicro_new_pre_set_heartbeat(unsigned int heartbeat) | |||
270 | * Don't use this fix if you don't need to!!! | 265 | * Don't use this fix if you don't need to!!! |
271 | */ | 266 | */ |
272 | 267 | ||
273 | static void broken_bios_start(unsigned long acpibase) | 268 | static void broken_bios_start(struct resource *smires) |
274 | { | 269 | { |
275 | unsigned long val32; | 270 | unsigned long val32; |
276 | 271 | ||
277 | val32 = inl(SMI_EN); | 272 | val32 = inl(smires->start); |
278 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# | 273 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# |
279 | Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */ | 274 | Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */ |
280 | val32 &= 0xffffdffe; | 275 | val32 &= 0xffffdffe; |
281 | outl(val32, SMI_EN); | 276 | outl(val32, smires->start); |
282 | } | 277 | } |
283 | 278 | ||
284 | static void broken_bios_stop(unsigned long acpibase) | 279 | static void broken_bios_stop(struct resource *smires) |
285 | { | 280 | { |
286 | unsigned long val32; | 281 | unsigned long val32; |
287 | 282 | ||
288 | val32 = inl(SMI_EN); | 283 | val32 = inl(smires->start); |
289 | /* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI# | 284 | /* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI# |
290 | Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */ | 285 | Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */ |
291 | val32 |= 0x00002001; | 286 | val32 |= 0x00002001; |
292 | outl(val32, SMI_EN); | 287 | outl(val32, smires->start); |
293 | } | 288 | } |
294 | 289 | ||
295 | /* | 290 | /* |
296 | * Generic Support Functions | 291 | * Generic Support Functions |
297 | */ | 292 | */ |
298 | 293 | ||
299 | void iTCO_vendor_pre_start(unsigned long acpibase, | 294 | void iTCO_vendor_pre_start(struct resource *smires, |
300 | unsigned int heartbeat) | 295 | unsigned int heartbeat) |
301 | { | 296 | { |
302 | switch (vendorsupport) { | 297 | switch (vendorsupport) { |
303 | case SUPERMICRO_OLD_BOARD: | 298 | case SUPERMICRO_OLD_BOARD: |
304 | supermicro_old_pre_start(acpibase); | 299 | supermicro_old_pre_start(smires); |
305 | break; | 300 | break; |
306 | case SUPERMICRO_NEW_BOARD: | 301 | case SUPERMICRO_NEW_BOARD: |
307 | supermicro_new_pre_start(heartbeat); | 302 | supermicro_new_pre_start(heartbeat); |
308 | break; | 303 | break; |
309 | case BROKEN_BIOS: | 304 | case BROKEN_BIOS: |
310 | broken_bios_start(acpibase); | 305 | broken_bios_start(smires); |
311 | break; | 306 | break; |
312 | } | 307 | } |
313 | } | 308 | } |
314 | EXPORT_SYMBOL(iTCO_vendor_pre_start); | 309 | EXPORT_SYMBOL(iTCO_vendor_pre_start); |
315 | 310 | ||
316 | void iTCO_vendor_pre_stop(unsigned long acpibase) | 311 | void iTCO_vendor_pre_stop(struct resource *smires) |
317 | { | 312 | { |
318 | switch (vendorsupport) { | 313 | switch (vendorsupport) { |
319 | case SUPERMICRO_OLD_BOARD: | 314 | case SUPERMICRO_OLD_BOARD: |
320 | supermicro_old_pre_stop(acpibase); | 315 | supermicro_old_pre_stop(smires); |
321 | break; | 316 | break; |
322 | case SUPERMICRO_NEW_BOARD: | 317 | case SUPERMICRO_NEW_BOARD: |
323 | supermicro_new_pre_stop(); | 318 | supermicro_new_pre_stop(); |
324 | break; | 319 | break; |
325 | case BROKEN_BIOS: | 320 | case BROKEN_BIOS: |
326 | broken_bios_stop(acpibase); | 321 | broken_bios_stop(smires); |
327 | break; | 322 | break; |
328 | } | 323 | } |
329 | } | 324 | } |
330 | EXPORT_SYMBOL(iTCO_vendor_pre_stop); | 325 | EXPORT_SYMBOL(iTCO_vendor_pre_stop); |
331 | 326 | ||
332 | void iTCO_vendor_pre_keepalive(unsigned long acpibase, unsigned int heartbeat) | 327 | void iTCO_vendor_pre_keepalive(struct resource *smires, unsigned int heartbeat) |
333 | { | 328 | { |
334 | if (vendorsupport == SUPERMICRO_NEW_BOARD) | 329 | if (vendorsupport == SUPERMICRO_NEW_BOARD) |
335 | supermicro_new_pre_set_heartbeat(heartbeat); | 330 | supermicro_new_pre_set_heartbeat(heartbeat); |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 9fecb95645a3..741528b032e2 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -66,316 +66,16 @@ | |||
66 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ | 66 | #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ |
67 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ | 67 | #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ |
68 | #include <linux/io.h> /* For inb/outb/... */ | 68 | #include <linux/io.h> /* For inb/outb/... */ |
69 | #include <linux/mfd/core.h> | ||
70 | #include <linux/mfd/lpc_ich.h> | ||
69 | 71 | ||
70 | #include "iTCO_vendor.h" | 72 | #include "iTCO_vendor.h" |
71 | 73 | ||
72 | /* TCO related info */ | ||
73 | enum iTCO_chipsets { | ||
74 | TCO_ICH = 0, /* ICH */ | ||
75 | TCO_ICH0, /* ICH0 */ | ||
76 | TCO_ICH2, /* ICH2 */ | ||
77 | TCO_ICH2M, /* ICH2-M */ | ||
78 | TCO_ICH3, /* ICH3-S */ | ||
79 | TCO_ICH3M, /* ICH3-M */ | ||
80 | TCO_ICH4, /* ICH4 */ | ||
81 | TCO_ICH4M, /* ICH4-M */ | ||
82 | TCO_CICH, /* C-ICH */ | ||
83 | TCO_ICH5, /* ICH5 & ICH5R */ | ||
84 | TCO_6300ESB, /* 6300ESB */ | ||
85 | TCO_ICH6, /* ICH6 & ICH6R */ | ||
86 | TCO_ICH6M, /* ICH6-M */ | ||
87 | TCO_ICH6W, /* ICH6W & ICH6RW */ | ||
88 | TCO_631XESB, /* 631xESB/632xESB */ | ||
89 | TCO_ICH7, /* ICH7 & ICH7R */ | ||
90 | TCO_ICH7DH, /* ICH7DH */ | ||
91 | TCO_ICH7M, /* ICH7-M & ICH7-U */ | ||
92 | TCO_ICH7MDH, /* ICH7-M DH */ | ||
93 | TCO_NM10, /* NM10 */ | ||
94 | TCO_ICH8, /* ICH8 & ICH8R */ | ||
95 | TCO_ICH8DH, /* ICH8DH */ | ||
96 | TCO_ICH8DO, /* ICH8DO */ | ||
97 | TCO_ICH8M, /* ICH8M */ | ||
98 | TCO_ICH8ME, /* ICH8M-E */ | ||
99 | TCO_ICH9, /* ICH9 */ | ||
100 | TCO_ICH9R, /* ICH9R */ | ||
101 | TCO_ICH9DH, /* ICH9DH */ | ||
102 | TCO_ICH9DO, /* ICH9DO */ | ||
103 | TCO_ICH9M, /* ICH9M */ | ||
104 | TCO_ICH9ME, /* ICH9M-E */ | ||
105 | TCO_ICH10, /* ICH10 */ | ||
106 | TCO_ICH10R, /* ICH10R */ | ||
107 | TCO_ICH10D, /* ICH10D */ | ||
108 | TCO_ICH10DO, /* ICH10DO */ | ||
109 | TCO_PCH, /* PCH Desktop Full Featured */ | ||
110 | TCO_PCHM, /* PCH Mobile Full Featured */ | ||
111 | TCO_P55, /* P55 */ | ||
112 | TCO_PM55, /* PM55 */ | ||
113 | TCO_H55, /* H55 */ | ||
114 | TCO_QM57, /* QM57 */ | ||
115 | TCO_H57, /* H57 */ | ||
116 | TCO_HM55, /* HM55 */ | ||
117 | TCO_Q57, /* Q57 */ | ||
118 | TCO_HM57, /* HM57 */ | ||
119 | TCO_PCHMSFF, /* PCH Mobile SFF Full Featured */ | ||
120 | TCO_QS57, /* QS57 */ | ||
121 | TCO_3400, /* 3400 */ | ||
122 | TCO_3420, /* 3420 */ | ||
123 | TCO_3450, /* 3450 */ | ||
124 | TCO_EP80579, /* EP80579 */ | ||
125 | TCO_CPT, /* Cougar Point */ | ||
126 | TCO_CPTD, /* Cougar Point Desktop */ | ||
127 | TCO_CPTM, /* Cougar Point Mobile */ | ||
128 | TCO_PBG, /* Patsburg */ | ||
129 | TCO_DH89XXCC, /* DH89xxCC */ | ||
130 | TCO_PPT, /* Panther Point */ | ||
131 | TCO_LPT, /* Lynx Point */ | ||
132 | }; | ||
133 | |||
134 | static struct { | ||
135 | char *name; | ||
136 | unsigned int iTCO_version; | ||
137 | } iTCO_chipset_info[] __devinitdata = { | ||
138 | {"ICH", 1}, | ||
139 | {"ICH0", 1}, | ||
140 | {"ICH2", 1}, | ||
141 | {"ICH2-M", 1}, | ||
142 | {"ICH3-S", 1}, | ||
143 | {"ICH3-M", 1}, | ||
144 | {"ICH4", 1}, | ||
145 | {"ICH4-M", 1}, | ||
146 | {"C-ICH", 1}, | ||
147 | {"ICH5 or ICH5R", 1}, | ||
148 | {"6300ESB", 1}, | ||
149 | {"ICH6 or ICH6R", 2}, | ||
150 | {"ICH6-M", 2}, | ||
151 | {"ICH6W or ICH6RW", 2}, | ||
152 | {"631xESB/632xESB", 2}, | ||
153 | {"ICH7 or ICH7R", 2}, | ||
154 | {"ICH7DH", 2}, | ||
155 | {"ICH7-M or ICH7-U", 2}, | ||
156 | {"ICH7-M DH", 2}, | ||
157 | {"NM10", 2}, | ||
158 | {"ICH8 or ICH8R", 2}, | ||
159 | {"ICH8DH", 2}, | ||
160 | {"ICH8DO", 2}, | ||
161 | {"ICH8M", 2}, | ||
162 | {"ICH8M-E", 2}, | ||
163 | {"ICH9", 2}, | ||
164 | {"ICH9R", 2}, | ||
165 | {"ICH9DH", 2}, | ||
166 | {"ICH9DO", 2}, | ||
167 | {"ICH9M", 2}, | ||
168 | {"ICH9M-E", 2}, | ||
169 | {"ICH10", 2}, | ||
170 | {"ICH10R", 2}, | ||
171 | {"ICH10D", 2}, | ||
172 | {"ICH10DO", 2}, | ||
173 | {"PCH Desktop Full Featured", 2}, | ||
174 | {"PCH Mobile Full Featured", 2}, | ||
175 | {"P55", 2}, | ||
176 | {"PM55", 2}, | ||
177 | {"H55", 2}, | ||
178 | {"QM57", 2}, | ||
179 | {"H57", 2}, | ||
180 | {"HM55", 2}, | ||
181 | {"Q57", 2}, | ||
182 | {"HM57", 2}, | ||
183 | {"PCH Mobile SFF Full Featured", 2}, | ||
184 | {"QS57", 2}, | ||
185 | {"3400", 2}, | ||
186 | {"3420", 2}, | ||
187 | {"3450", 2}, | ||
188 | {"EP80579", 2}, | ||
189 | {"Cougar Point", 2}, | ||
190 | {"Cougar Point Desktop", 2}, | ||
191 | {"Cougar Point Mobile", 2}, | ||
192 | {"Patsburg", 2}, | ||
193 | {"DH89xxCC", 2}, | ||
194 | {"Panther Point", 2}, | ||
195 | {"Lynx Point", 2}, | ||
196 | {NULL, 0} | ||
197 | }; | ||
198 | |||
199 | /* | ||
200 | * This data only exists for exporting the supported PCI ids | ||
201 | * via MODULE_DEVICE_TABLE. We do not actually register a | ||
202 | * pci_driver, because the I/O Controller Hub has also other | ||
203 | * functions that probably will be registered by other drivers. | ||
204 | */ | ||
205 | static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { | ||
206 | { PCI_VDEVICE(INTEL, 0x2410), TCO_ICH}, | ||
207 | { PCI_VDEVICE(INTEL, 0x2420), TCO_ICH0}, | ||
208 | { PCI_VDEVICE(INTEL, 0x2440), TCO_ICH2}, | ||
209 | { PCI_VDEVICE(INTEL, 0x244c), TCO_ICH2M}, | ||
210 | { PCI_VDEVICE(INTEL, 0x2480), TCO_ICH3}, | ||
211 | { PCI_VDEVICE(INTEL, 0x248c), TCO_ICH3M}, | ||
212 | { PCI_VDEVICE(INTEL, 0x24c0), TCO_ICH4}, | ||
213 | { PCI_VDEVICE(INTEL, 0x24cc), TCO_ICH4M}, | ||
214 | { PCI_VDEVICE(INTEL, 0x2450), TCO_CICH}, | ||
215 | { PCI_VDEVICE(INTEL, 0x24d0), TCO_ICH5}, | ||
216 | { PCI_VDEVICE(INTEL, 0x25a1), TCO_6300ESB}, | ||
217 | { PCI_VDEVICE(INTEL, 0x2640), TCO_ICH6}, | ||
218 | { PCI_VDEVICE(INTEL, 0x2641), TCO_ICH6M}, | ||
219 | { PCI_VDEVICE(INTEL, 0x2642), TCO_ICH6W}, | ||
220 | { PCI_VDEVICE(INTEL, 0x2670), TCO_631XESB}, | ||
221 | { PCI_VDEVICE(INTEL, 0x2671), TCO_631XESB}, | ||
222 | { PCI_VDEVICE(INTEL, 0x2672), TCO_631XESB}, | ||
223 | { PCI_VDEVICE(INTEL, 0x2673), TCO_631XESB}, | ||
224 | { PCI_VDEVICE(INTEL, 0x2674), TCO_631XESB}, | ||
225 | { PCI_VDEVICE(INTEL, 0x2675), TCO_631XESB}, | ||
226 | { PCI_VDEVICE(INTEL, 0x2676), TCO_631XESB}, | ||
227 | { PCI_VDEVICE(INTEL, 0x2677), TCO_631XESB}, | ||
228 | { PCI_VDEVICE(INTEL, 0x2678), TCO_631XESB}, | ||
229 | { PCI_VDEVICE(INTEL, 0x2679), TCO_631XESB}, | ||
230 | { PCI_VDEVICE(INTEL, 0x267a), TCO_631XESB}, | ||
231 | { PCI_VDEVICE(INTEL, 0x267b), TCO_631XESB}, | ||
232 | { PCI_VDEVICE(INTEL, 0x267c), TCO_631XESB}, | ||
233 | { PCI_VDEVICE(INTEL, 0x267d), TCO_631XESB}, | ||
234 | { PCI_VDEVICE(INTEL, 0x267e), TCO_631XESB}, | ||
235 | { PCI_VDEVICE(INTEL, 0x267f), TCO_631XESB}, | ||
236 | { PCI_VDEVICE(INTEL, 0x27b8), TCO_ICH7}, | ||
237 | { PCI_VDEVICE(INTEL, 0x27b0), TCO_ICH7DH}, | ||
238 | { PCI_VDEVICE(INTEL, 0x27b9), TCO_ICH7M}, | ||
239 | { PCI_VDEVICE(INTEL, 0x27bd), TCO_ICH7MDH}, | ||
240 | { PCI_VDEVICE(INTEL, 0x27bc), TCO_NM10}, | ||
241 | { PCI_VDEVICE(INTEL, 0x2810), TCO_ICH8}, | ||
242 | { PCI_VDEVICE(INTEL, 0x2812), TCO_ICH8DH}, | ||
243 | { PCI_VDEVICE(INTEL, 0x2814), TCO_ICH8DO}, | ||
244 | { PCI_VDEVICE(INTEL, 0x2815), TCO_ICH8M}, | ||
245 | { PCI_VDEVICE(INTEL, 0x2811), TCO_ICH8ME}, | ||
246 | { PCI_VDEVICE(INTEL, 0x2918), TCO_ICH9}, | ||
247 | { PCI_VDEVICE(INTEL, 0x2916), TCO_ICH9R}, | ||
248 | { PCI_VDEVICE(INTEL, 0x2912), TCO_ICH9DH}, | ||
249 | { PCI_VDEVICE(INTEL, 0x2914), TCO_ICH9DO}, | ||
250 | { PCI_VDEVICE(INTEL, 0x2919), TCO_ICH9M}, | ||
251 | { PCI_VDEVICE(INTEL, 0x2917), TCO_ICH9ME}, | ||
252 | { PCI_VDEVICE(INTEL, 0x3a18), TCO_ICH10}, | ||
253 | { PCI_VDEVICE(INTEL, 0x3a16), TCO_ICH10R}, | ||
254 | { PCI_VDEVICE(INTEL, 0x3a1a), TCO_ICH10D}, | ||
255 | { PCI_VDEVICE(INTEL, 0x3a14), TCO_ICH10DO}, | ||
256 | { PCI_VDEVICE(INTEL, 0x3b00), TCO_PCH}, | ||
257 | { PCI_VDEVICE(INTEL, 0x3b01), TCO_PCHM}, | ||
258 | { PCI_VDEVICE(INTEL, 0x3b02), TCO_P55}, | ||
259 | { PCI_VDEVICE(INTEL, 0x3b03), TCO_PM55}, | ||
260 | { PCI_VDEVICE(INTEL, 0x3b06), TCO_H55}, | ||
261 | { PCI_VDEVICE(INTEL, 0x3b07), TCO_QM57}, | ||
262 | { PCI_VDEVICE(INTEL, 0x3b08), TCO_H57}, | ||
263 | { PCI_VDEVICE(INTEL, 0x3b09), TCO_HM55}, | ||
264 | { PCI_VDEVICE(INTEL, 0x3b0a), TCO_Q57}, | ||
265 | { PCI_VDEVICE(INTEL, 0x3b0b), TCO_HM57}, | ||
266 | { PCI_VDEVICE(INTEL, 0x3b0d), TCO_PCHMSFF}, | ||
267 | { PCI_VDEVICE(INTEL, 0x3b0f), TCO_QS57}, | ||
268 | { PCI_VDEVICE(INTEL, 0x3b12), TCO_3400}, | ||
269 | { PCI_VDEVICE(INTEL, 0x3b14), TCO_3420}, | ||
270 | { PCI_VDEVICE(INTEL, 0x3b16), TCO_3450}, | ||
271 | { PCI_VDEVICE(INTEL, 0x5031), TCO_EP80579}, | ||
272 | { PCI_VDEVICE(INTEL, 0x1c41), TCO_CPT}, | ||
273 | { PCI_VDEVICE(INTEL, 0x1c42), TCO_CPTD}, | ||
274 | { PCI_VDEVICE(INTEL, 0x1c43), TCO_CPTM}, | ||
275 | { PCI_VDEVICE(INTEL, 0x1c44), TCO_CPT}, | ||
276 | { PCI_VDEVICE(INTEL, 0x1c45), TCO_CPT}, | ||
277 | { PCI_VDEVICE(INTEL, 0x1c46), TCO_CPT}, | ||
278 | { PCI_VDEVICE(INTEL, 0x1c47), TCO_CPT}, | ||
279 | { PCI_VDEVICE(INTEL, 0x1c48), TCO_CPT}, | ||
280 | { PCI_VDEVICE(INTEL, 0x1c49), TCO_CPT}, | ||
281 | { PCI_VDEVICE(INTEL, 0x1c4a), TCO_CPT}, | ||
282 | { PCI_VDEVICE(INTEL, 0x1c4b), TCO_CPT}, | ||
283 | { PCI_VDEVICE(INTEL, 0x1c4c), TCO_CPT}, | ||
284 | { PCI_VDEVICE(INTEL, 0x1c4d), TCO_CPT}, | ||
285 | { PCI_VDEVICE(INTEL, 0x1c4e), TCO_CPT}, | ||
286 | { PCI_VDEVICE(INTEL, 0x1c4f), TCO_CPT}, | ||
287 | { PCI_VDEVICE(INTEL, 0x1c50), TCO_CPT}, | ||
288 | { PCI_VDEVICE(INTEL, 0x1c51), TCO_CPT}, | ||
289 | { PCI_VDEVICE(INTEL, 0x1c52), TCO_CPT}, | ||
290 | { PCI_VDEVICE(INTEL, 0x1c53), TCO_CPT}, | ||
291 | { PCI_VDEVICE(INTEL, 0x1c54), TCO_CPT}, | ||
292 | { PCI_VDEVICE(INTEL, 0x1c55), TCO_CPT}, | ||
293 | { PCI_VDEVICE(INTEL, 0x1c56), TCO_CPT}, | ||
294 | { PCI_VDEVICE(INTEL, 0x1c57), TCO_CPT}, | ||
295 | { PCI_VDEVICE(INTEL, 0x1c58), TCO_CPT}, | ||
296 | { PCI_VDEVICE(INTEL, 0x1c59), TCO_CPT}, | ||
297 | { PCI_VDEVICE(INTEL, 0x1c5a), TCO_CPT}, | ||
298 | { PCI_VDEVICE(INTEL, 0x1c5b), TCO_CPT}, | ||
299 | { PCI_VDEVICE(INTEL, 0x1c5c), TCO_CPT}, | ||
300 | { PCI_VDEVICE(INTEL, 0x1c5d), TCO_CPT}, | ||
301 | { PCI_VDEVICE(INTEL, 0x1c5e), TCO_CPT}, | ||
302 | { PCI_VDEVICE(INTEL, 0x1c5f), TCO_CPT}, | ||
303 | { PCI_VDEVICE(INTEL, 0x1d40), TCO_PBG}, | ||
304 | { PCI_VDEVICE(INTEL, 0x1d41), TCO_PBG}, | ||
305 | { PCI_VDEVICE(INTEL, 0x2310), TCO_DH89XXCC}, | ||
306 | { PCI_VDEVICE(INTEL, 0x1e40), TCO_PPT}, | ||
307 | { PCI_VDEVICE(INTEL, 0x1e41), TCO_PPT}, | ||
308 | { PCI_VDEVICE(INTEL, 0x1e42), TCO_PPT}, | ||
309 | { PCI_VDEVICE(INTEL, 0x1e43), TCO_PPT}, | ||
310 | { PCI_VDEVICE(INTEL, 0x1e44), TCO_PPT}, | ||
311 | { PCI_VDEVICE(INTEL, 0x1e45), TCO_PPT}, | ||
312 | { PCI_VDEVICE(INTEL, 0x1e46), TCO_PPT}, | ||
313 | { PCI_VDEVICE(INTEL, 0x1e47), TCO_PPT}, | ||
314 | { PCI_VDEVICE(INTEL, 0x1e48), TCO_PPT}, | ||
315 | { PCI_VDEVICE(INTEL, 0x1e49), TCO_PPT}, | ||
316 | { PCI_VDEVICE(INTEL, 0x1e4a), TCO_PPT}, | ||
317 | { PCI_VDEVICE(INTEL, 0x1e4b), TCO_PPT}, | ||
318 | { PCI_VDEVICE(INTEL, 0x1e4c), TCO_PPT}, | ||
319 | { PCI_VDEVICE(INTEL, 0x1e4d), TCO_PPT}, | ||
320 | { PCI_VDEVICE(INTEL, 0x1e4e), TCO_PPT}, | ||
321 | { PCI_VDEVICE(INTEL, 0x1e4f), TCO_PPT}, | ||
322 | { PCI_VDEVICE(INTEL, 0x1e50), TCO_PPT}, | ||
323 | { PCI_VDEVICE(INTEL, 0x1e51), TCO_PPT}, | ||
324 | { PCI_VDEVICE(INTEL, 0x1e52), TCO_PPT}, | ||
325 | { PCI_VDEVICE(INTEL, 0x1e53), TCO_PPT}, | ||
326 | { PCI_VDEVICE(INTEL, 0x1e54), TCO_PPT}, | ||
327 | { PCI_VDEVICE(INTEL, 0x1e55), TCO_PPT}, | ||
328 | { PCI_VDEVICE(INTEL, 0x1e56), TCO_PPT}, | ||
329 | { PCI_VDEVICE(INTEL, 0x1e57), TCO_PPT}, | ||
330 | { PCI_VDEVICE(INTEL, 0x1e58), TCO_PPT}, | ||
331 | { PCI_VDEVICE(INTEL, 0x1e59), TCO_PPT}, | ||
332 | { PCI_VDEVICE(INTEL, 0x1e5a), TCO_PPT}, | ||
333 | { PCI_VDEVICE(INTEL, 0x1e5b), TCO_PPT}, | ||
334 | { PCI_VDEVICE(INTEL, 0x1e5c), TCO_PPT}, | ||
335 | { PCI_VDEVICE(INTEL, 0x1e5d), TCO_PPT}, | ||
336 | { PCI_VDEVICE(INTEL, 0x1e5e), TCO_PPT}, | ||
337 | { PCI_VDEVICE(INTEL, 0x1e5f), TCO_PPT}, | ||
338 | { PCI_VDEVICE(INTEL, 0x8c40), TCO_LPT}, | ||
339 | { PCI_VDEVICE(INTEL, 0x8c41), TCO_LPT}, | ||
340 | { PCI_VDEVICE(INTEL, 0x8c42), TCO_LPT}, | ||
341 | { PCI_VDEVICE(INTEL, 0x8c43), TCO_LPT}, | ||
342 | { PCI_VDEVICE(INTEL, 0x8c44), TCO_LPT}, | ||
343 | { PCI_VDEVICE(INTEL, 0x8c45), TCO_LPT}, | ||
344 | { PCI_VDEVICE(INTEL, 0x8c46), TCO_LPT}, | ||
345 | { PCI_VDEVICE(INTEL, 0x8c47), TCO_LPT}, | ||
346 | { PCI_VDEVICE(INTEL, 0x8c48), TCO_LPT}, | ||
347 | { PCI_VDEVICE(INTEL, 0x8c49), TCO_LPT}, | ||
348 | { PCI_VDEVICE(INTEL, 0x8c4a), TCO_LPT}, | ||
349 | { PCI_VDEVICE(INTEL, 0x8c4b), TCO_LPT}, | ||
350 | { PCI_VDEVICE(INTEL, 0x8c4c), TCO_LPT}, | ||
351 | { PCI_VDEVICE(INTEL, 0x8c4d), TCO_LPT}, | ||
352 | { PCI_VDEVICE(INTEL, 0x8c4e), TCO_LPT}, | ||
353 | { PCI_VDEVICE(INTEL, 0x8c4f), TCO_LPT}, | ||
354 | { PCI_VDEVICE(INTEL, 0x8c50), TCO_LPT}, | ||
355 | { PCI_VDEVICE(INTEL, 0x8c51), TCO_LPT}, | ||
356 | { PCI_VDEVICE(INTEL, 0x8c52), TCO_LPT}, | ||
357 | { PCI_VDEVICE(INTEL, 0x8c53), TCO_LPT}, | ||
358 | { PCI_VDEVICE(INTEL, 0x8c54), TCO_LPT}, | ||
359 | { PCI_VDEVICE(INTEL, 0x8c55), TCO_LPT}, | ||
360 | { PCI_VDEVICE(INTEL, 0x8c56), TCO_LPT}, | ||
361 | { PCI_VDEVICE(INTEL, 0x8c57), TCO_LPT}, | ||
362 | { PCI_VDEVICE(INTEL, 0x8c58), TCO_LPT}, | ||
363 | { PCI_VDEVICE(INTEL, 0x8c59), TCO_LPT}, | ||
364 | { PCI_VDEVICE(INTEL, 0x8c5a), TCO_LPT}, | ||
365 | { PCI_VDEVICE(INTEL, 0x8c5b), TCO_LPT}, | ||
366 | { PCI_VDEVICE(INTEL, 0x8c5c), TCO_LPT}, | ||
367 | { PCI_VDEVICE(INTEL, 0x8c5d), TCO_LPT}, | ||
368 | { PCI_VDEVICE(INTEL, 0x8c5e), TCO_LPT}, | ||
369 | { PCI_VDEVICE(INTEL, 0x8c5f), TCO_LPT}, | ||
370 | { 0, }, /* End of list */ | ||
371 | }; | ||
372 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | ||
373 | |||
374 | /* Address definitions for the TCO */ | 74 | /* Address definitions for the TCO */ |
375 | /* TCO base address */ | 75 | /* TCO base address */ |
376 | #define TCOBASE (iTCO_wdt_private.ACPIBASE + 0x60) | 76 | #define TCOBASE (iTCO_wdt_private.tco_res->start) |
377 | /* SMI Control and Enable Register */ | 77 | /* SMI Control and Enable Register */ |
378 | #define SMI_EN (iTCO_wdt_private.ACPIBASE + 0x30) | 78 | #define SMI_EN (iTCO_wdt_private.smi_res->start) |
379 | 79 | ||
380 | #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ | 80 | #define TCO_RLD (TCOBASE + 0x00) /* TCO Timer Reload and Curr. Value */ |
381 | #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ | 81 | #define TCOv1_TMR (TCOBASE + 0x01) /* TCOv1 Timer Initial Value */ |
@@ -393,19 +93,18 @@ static char expect_release; | |||
393 | static struct { /* this is private data for the iTCO_wdt device */ | 93 | static struct { /* this is private data for the iTCO_wdt device */ |
394 | /* TCO version/generation */ | 94 | /* TCO version/generation */ |
395 | unsigned int iTCO_version; | 95 | unsigned int iTCO_version; |
396 | /* The device's ACPIBASE address (TCOBASE = ACPIBASE+0x60) */ | 96 | struct resource *tco_res; |
397 | unsigned long ACPIBASE; | 97 | struct resource *smi_res; |
98 | struct resource *gcs_res; | ||
398 | /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ | 99 | /* NO_REBOOT flag is Memory-Mapped GCS register bit 5 (TCO version 2)*/ |
399 | unsigned long __iomem *gcs; | 100 | unsigned long __iomem *gcs; |
400 | /* the lock for io operations */ | 101 | /* the lock for io operations */ |
401 | spinlock_t io_lock; | 102 | spinlock_t io_lock; |
103 | struct platform_device *dev; | ||
402 | /* the PCI-device */ | 104 | /* the PCI-device */ |
403 | struct pci_dev *pdev; | 105 | struct pci_dev *pdev; |
404 | } iTCO_wdt_private; | 106 | } iTCO_wdt_private; |
405 | 107 | ||
406 | /* the watchdog platform device */ | ||
407 | static struct platform_device *iTCO_wdt_platform_device; | ||
408 | |||
409 | /* module parameters */ | 108 | /* module parameters */ |
410 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ | 109 | #define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ |
411 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ | 110 | static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ |
@@ -485,7 +184,7 @@ static int iTCO_wdt_start(void) | |||
485 | 184 | ||
486 | spin_lock(&iTCO_wdt_private.io_lock); | 185 | spin_lock(&iTCO_wdt_private.io_lock); |
487 | 186 | ||
488 | iTCO_vendor_pre_start(iTCO_wdt_private.ACPIBASE, heartbeat); | 187 | iTCO_vendor_pre_start(iTCO_wdt_private.smi_res, heartbeat); |
489 | 188 | ||
490 | /* disable chipset's NO_REBOOT bit */ | 189 | /* disable chipset's NO_REBOOT bit */ |
491 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { | 190 | if (iTCO_wdt_unset_NO_REBOOT_bit()) { |
@@ -519,7 +218,7 @@ static int iTCO_wdt_stop(void) | |||
519 | 218 | ||
520 | spin_lock(&iTCO_wdt_private.io_lock); | 219 | spin_lock(&iTCO_wdt_private.io_lock); |
521 | 220 | ||
522 | iTCO_vendor_pre_stop(iTCO_wdt_private.ACPIBASE); | 221 | iTCO_vendor_pre_stop(iTCO_wdt_private.smi_res); |
523 | 222 | ||
524 | /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ | 223 | /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ |
525 | val = inw(TCO1_CNT); | 224 | val = inw(TCO1_CNT); |
@@ -541,7 +240,7 @@ static int iTCO_wdt_keepalive(void) | |||
541 | { | 240 | { |
542 | spin_lock(&iTCO_wdt_private.io_lock); | 241 | spin_lock(&iTCO_wdt_private.io_lock); |
543 | 242 | ||
544 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.ACPIBASE, heartbeat); | 243 | iTCO_vendor_pre_keepalive(iTCO_wdt_private.smi_res, heartbeat); |
545 | 244 | ||
546 | /* Reload the timer by writing to the TCO Timer Counter register */ | 245 | /* Reload the timer by writing to the TCO Timer Counter register */ |
547 | if (iTCO_wdt_private.iTCO_version == 2) | 246 | if (iTCO_wdt_private.iTCO_version == 2) |
@@ -786,83 +485,120 @@ static struct miscdevice iTCO_wdt_miscdev = { | |||
786 | * Init & exit routines | 485 | * Init & exit routines |
787 | */ | 486 | */ |
788 | 487 | ||
789 | static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | 488 | static void __devexit iTCO_wdt_cleanup(void) |
790 | const struct pci_device_id *ent, struct platform_device *dev) | 489 | { |
490 | /* Stop the timer before we leave */ | ||
491 | if (!nowayout) | ||
492 | iTCO_wdt_stop(); | ||
493 | |||
494 | /* Deregister */ | ||
495 | misc_deregister(&iTCO_wdt_miscdev); | ||
496 | |||
497 | /* release resources */ | ||
498 | release_region(iTCO_wdt_private.tco_res->start, | ||
499 | resource_size(iTCO_wdt_private.tco_res)); | ||
500 | release_region(iTCO_wdt_private.smi_res->start, | ||
501 | resource_size(iTCO_wdt_private.smi_res)); | ||
502 | if (iTCO_wdt_private.iTCO_version == 2) { | ||
503 | iounmap(iTCO_wdt_private.gcs); | ||
504 | release_mem_region(iTCO_wdt_private.gcs_res->start, | ||
505 | resource_size(iTCO_wdt_private.gcs_res)); | ||
506 | } | ||
507 | |||
508 | iTCO_wdt_private.tco_res = NULL; | ||
509 | iTCO_wdt_private.smi_res = NULL; | ||
510 | iTCO_wdt_private.gcs_res = NULL; | ||
511 | iTCO_wdt_private.gcs = NULL; | ||
512 | } | ||
513 | |||
514 | static int __devinit iTCO_wdt_probe(struct platform_device *dev) | ||
791 | { | 515 | { |
792 | int ret; | 516 | int ret = -ENODEV; |
793 | u32 base_address; | ||
794 | unsigned long RCBA; | ||
795 | unsigned long val32; | 517 | unsigned long val32; |
518 | struct lpc_ich_info *ich_info = dev->dev.platform_data; | ||
519 | |||
520 | if (!ich_info) | ||
521 | goto out; | ||
522 | |||
523 | spin_lock_init(&iTCO_wdt_private.io_lock); | ||
524 | |||
525 | iTCO_wdt_private.tco_res = | ||
526 | platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_TCO); | ||
527 | if (!iTCO_wdt_private.tco_res) | ||
528 | goto out; | ||
529 | |||
530 | iTCO_wdt_private.smi_res = | ||
531 | platform_get_resource(dev, IORESOURCE_IO, ICH_RES_IO_SMI); | ||
532 | if (!iTCO_wdt_private.smi_res) | ||
533 | goto out; | ||
534 | |||
535 | iTCO_wdt_private.iTCO_version = ich_info->iTCO_version; | ||
536 | iTCO_wdt_private.dev = dev; | ||
537 | iTCO_wdt_private.pdev = to_pci_dev(dev->dev.parent); | ||
796 | 538 | ||
797 | /* | 539 | /* |
798 | * Find the ACPI/PM base I/O address which is the base | 540 | * Get the Memory-Mapped GCS register, we need it for the |
799 | * for the TCO registers (TCOBASE=ACPIBASE + 0x60) | 541 | * NO_REBOOT flag (TCO v2). |
800 | * ACPIBASE is bits [15:7] from 0x40-0x43 | ||
801 | */ | 542 | */ |
802 | pci_read_config_dword(pdev, 0x40, &base_address); | ||
803 | base_address &= 0x0000ff80; | ||
804 | if (base_address == 0x00000000) { | ||
805 | /* Something's wrong here, ACPIBASE has to be set */ | ||
806 | pr_err("failed to get TCOBASE address, device disabled by hardware/BIOS\n"); | ||
807 | return -ENODEV; | ||
808 | } | ||
809 | iTCO_wdt_private.iTCO_version = | ||
810 | iTCO_chipset_info[ent->driver_data].iTCO_version; | ||
811 | iTCO_wdt_private.ACPIBASE = base_address; | ||
812 | iTCO_wdt_private.pdev = pdev; | ||
813 | |||
814 | /* Get the Memory-Mapped GCS register, we need it for the | ||
815 | NO_REBOOT flag (TCO v2). To get access to it you have to | ||
816 | read RCBA from PCI Config space 0xf0 and use it as base. | ||
817 | GCS = RCBA + ICH6_GCS(0x3410). */ | ||
818 | if (iTCO_wdt_private.iTCO_version == 2) { | 543 | if (iTCO_wdt_private.iTCO_version == 2) { |
819 | pci_read_config_dword(pdev, 0xf0, &base_address); | 544 | iTCO_wdt_private.gcs_res = platform_get_resource(dev, |
820 | if ((base_address & 1) == 0) { | 545 | IORESOURCE_MEM, |
821 | pr_err("RCBA is disabled by hardware/BIOS, device disabled\n"); | 546 | ICH_RES_MEM_GCS); |
822 | ret = -ENODEV; | 547 | |
548 | if (!iTCO_wdt_private.gcs_res) | ||
549 | goto out; | ||
550 | |||
551 | if (!request_mem_region(iTCO_wdt_private.gcs_res->start, | ||
552 | resource_size(iTCO_wdt_private.gcs_res), dev->name)) { | ||
553 | ret = -EBUSY; | ||
823 | goto out; | 554 | goto out; |
824 | } | 555 | } |
825 | RCBA = base_address & 0xffffc000; | 556 | iTCO_wdt_private.gcs = ioremap(iTCO_wdt_private.gcs_res->start, |
826 | iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); | 557 | resource_size(iTCO_wdt_private.gcs_res)); |
558 | if (!iTCO_wdt_private.gcs) { | ||
559 | ret = -EIO; | ||
560 | goto unreg_gcs; | ||
561 | } | ||
827 | } | 562 | } |
828 | 563 | ||
829 | /* Check chipset's NO_REBOOT bit */ | 564 | /* Check chipset's NO_REBOOT bit */ |
830 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { | 565 | if (iTCO_wdt_unset_NO_REBOOT_bit() && iTCO_vendor_check_noreboot_on()) { |
831 | pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); | 566 | pr_info("unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); |
832 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ | 567 | ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ |
833 | goto out_unmap; | 568 | goto unmap_gcs; |
834 | } | 569 | } |
835 | 570 | ||
836 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | 571 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ |
837 | iTCO_wdt_set_NO_REBOOT_bit(); | 572 | iTCO_wdt_set_NO_REBOOT_bit(); |
838 | 573 | ||
839 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ | 574 | /* The TCO logic uses the TCO_EN bit in the SMI_EN register */ |
840 | if (!request_region(SMI_EN, 4, "iTCO_wdt")) { | 575 | if (!request_region(iTCO_wdt_private.smi_res->start, |
841 | pr_err("I/O address 0x%04lx already in use, device disabled\n", | 576 | resource_size(iTCO_wdt_private.smi_res), dev->name)) { |
577 | pr_err("I/O address 0x%04llx already in use, device disabled\n", | ||
842 | SMI_EN); | 578 | SMI_EN); |
843 | ret = -EIO; | 579 | ret = -EBUSY; |
844 | goto out_unmap; | 580 | goto unmap_gcs; |
845 | } | 581 | } |
846 | if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) { | 582 | if (turn_SMI_watchdog_clear_off >= iTCO_wdt_private.iTCO_version) { |
847 | /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ | 583 | /* |
584 | * Bit 13: TCO_EN -> 0 | ||
585 | * Disables TCO logic generating an SMI# | ||
586 | */ | ||
848 | val32 = inl(SMI_EN); | 587 | val32 = inl(SMI_EN); |
849 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ | 588 | val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ |
850 | outl(val32, SMI_EN); | 589 | outl(val32, SMI_EN); |
851 | } | 590 | } |
852 | 591 | ||
853 | /* The TCO I/O registers reside in a 32-byte range pointed to | 592 | if (!request_region(iTCO_wdt_private.tco_res->start, |
854 | by the TCOBASE value */ | 593 | resource_size(iTCO_wdt_private.tco_res), dev->name)) { |
855 | if (!request_region(TCOBASE, 0x20, "iTCO_wdt")) { | 594 | pr_err("I/O address 0x%04llx already in use, device disabled\n", |
856 | pr_err("I/O address 0x%04lx already in use, device disabled\n", | ||
857 | TCOBASE); | 595 | TCOBASE); |
858 | ret = -EIO; | 596 | ret = -EBUSY; |
859 | goto unreg_smi_en; | 597 | goto unreg_smi; |
860 | } | 598 | } |
861 | 599 | ||
862 | pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04lx)\n", | 600 | pr_info("Found a %s TCO device (Version=%d, TCOBASE=0x%04llx)\n", |
863 | iTCO_chipset_info[ent->driver_data].name, | 601 | ich_info->name, ich_info->iTCO_version, TCOBASE); |
864 | iTCO_chipset_info[ent->driver_data].iTCO_version, | ||
865 | TCOBASE); | ||
866 | 602 | ||
867 | /* Clear out the (probably old) status */ | 603 | /* Clear out the (probably old) status */ |
868 | outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */ | 604 | outw(0x0008, TCO1_STS); /* Clear the Time Out Status bit */ |
@@ -883,7 +619,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
883 | if (ret != 0) { | 619 | if (ret != 0) { |
884 | pr_err("cannot register miscdev on minor=%d (err=%d)\n", | 620 | pr_err("cannot register miscdev on minor=%d (err=%d)\n", |
885 | WATCHDOG_MINOR, ret); | 621 | WATCHDOG_MINOR, ret); |
886 | goto unreg_region; | 622 | goto unreg_tco; |
887 | } | 623 | } |
888 | 624 | ||
889 | pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n", | 625 | pr_info("initialized. heartbeat=%d sec (nowayout=%d)\n", |
@@ -891,62 +627,31 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, | |||
891 | 627 | ||
892 | return 0; | 628 | return 0; |
893 | 629 | ||
894 | unreg_region: | 630 | unreg_tco: |
895 | release_region(TCOBASE, 0x20); | 631 | release_region(iTCO_wdt_private.tco_res->start, |
896 | unreg_smi_en: | 632 | resource_size(iTCO_wdt_private.tco_res)); |
897 | release_region(SMI_EN, 4); | 633 | unreg_smi: |
898 | out_unmap: | 634 | release_region(iTCO_wdt_private.smi_res->start, |
635 | resource_size(iTCO_wdt_private.smi_res)); | ||
636 | unmap_gcs: | ||
899 | if (iTCO_wdt_private.iTCO_version == 2) | 637 | if (iTCO_wdt_private.iTCO_version == 2) |
900 | iounmap(iTCO_wdt_private.gcs); | 638 | iounmap(iTCO_wdt_private.gcs); |
901 | out: | 639 | unreg_gcs: |
902 | iTCO_wdt_private.ACPIBASE = 0; | ||
903 | return ret; | ||
904 | } | ||
905 | |||
906 | static void __devexit iTCO_wdt_cleanup(void) | ||
907 | { | ||
908 | /* Stop the timer before we leave */ | ||
909 | if (!nowayout) | ||
910 | iTCO_wdt_stop(); | ||
911 | |||
912 | /* Deregister */ | ||
913 | misc_deregister(&iTCO_wdt_miscdev); | ||
914 | release_region(TCOBASE, 0x20); | ||
915 | release_region(SMI_EN, 4); | ||
916 | if (iTCO_wdt_private.iTCO_version == 2) | 640 | if (iTCO_wdt_private.iTCO_version == 2) |
917 | iounmap(iTCO_wdt_private.gcs); | 641 | release_mem_region(iTCO_wdt_private.gcs_res->start, |
918 | pci_dev_put(iTCO_wdt_private.pdev); | 642 | resource_size(iTCO_wdt_private.gcs_res)); |
919 | iTCO_wdt_private.ACPIBASE = 0; | 643 | out: |
920 | } | 644 | iTCO_wdt_private.tco_res = NULL; |
921 | 645 | iTCO_wdt_private.smi_res = NULL; | |
922 | static int __devinit iTCO_wdt_probe(struct platform_device *dev) | 646 | iTCO_wdt_private.gcs_res = NULL; |
923 | { | 647 | iTCO_wdt_private.gcs = NULL; |
924 | int ret = -ENODEV; | ||
925 | int found = 0; | ||
926 | struct pci_dev *pdev = NULL; | ||
927 | const struct pci_device_id *ent; | ||
928 | |||
929 | spin_lock_init(&iTCO_wdt_private.io_lock); | ||
930 | |||
931 | for_each_pci_dev(pdev) { | ||
932 | ent = pci_match_id(iTCO_wdt_pci_tbl, pdev); | ||
933 | if (ent) { | ||
934 | found++; | ||
935 | ret = iTCO_wdt_init(pdev, ent, dev); | ||
936 | if (!ret) | ||
937 | break; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | if (!found) | ||
942 | pr_info("No device detected\n"); | ||
943 | 648 | ||
944 | return ret; | 649 | return ret; |
945 | } | 650 | } |
946 | 651 | ||
947 | static int __devexit iTCO_wdt_remove(struct platform_device *dev) | 652 | static int __devexit iTCO_wdt_remove(struct platform_device *dev) |
948 | { | 653 | { |
949 | if (iTCO_wdt_private.ACPIBASE) | 654 | if (iTCO_wdt_private.tco_res || iTCO_wdt_private.smi_res) |
950 | iTCO_wdt_cleanup(); | 655 | iTCO_wdt_cleanup(); |
951 | 656 | ||
952 | return 0; | 657 | return 0; |
@@ -977,23 +682,11 @@ static int __init iTCO_wdt_init_module(void) | |||
977 | if (err) | 682 | if (err) |
978 | return err; | 683 | return err; |
979 | 684 | ||
980 | iTCO_wdt_platform_device = platform_device_register_simple(DRV_NAME, | ||
981 | -1, NULL, 0); | ||
982 | if (IS_ERR(iTCO_wdt_platform_device)) { | ||
983 | err = PTR_ERR(iTCO_wdt_platform_device); | ||
984 | goto unreg_platform_driver; | ||
985 | } | ||
986 | |||
987 | return 0; | 685 | return 0; |
988 | |||
989 | unreg_platform_driver: | ||
990 | platform_driver_unregister(&iTCO_wdt_driver); | ||
991 | return err; | ||
992 | } | 686 | } |
993 | 687 | ||
994 | static void __exit iTCO_wdt_cleanup_module(void) | 688 | static void __exit iTCO_wdt_cleanup_module(void) |
995 | { | 689 | { |
996 | platform_device_unregister(iTCO_wdt_platform_device); | ||
997 | platform_driver_unregister(&iTCO_wdt_driver); | 690 | platform_driver_unregister(&iTCO_wdt_driver); |
998 | pr_info("Watchdog Module Unloaded\n"); | 691 | pr_info("Watchdog Module Unloaded\n"); |
999 | } | 692 | } |