aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-04 23:01:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-04 23:01:30 -0400
commit578f1ef91aa92beb571bfb9af8f4d18f405f3b9e (patch)
tree8ff59e772d09180b7e7f952a8c90a1bcf25e1d19 /drivers
parentecefbd94b834fa32559d854646d777c56749ef1c (diff)
parent74d8378159de16a0a1d1975d4778120d263d6000 (diff)
Merge tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFD changes from Samuel Ortiz: "MFD bits for the 3.7 merge window. As usual we have a few new drivers: - TI LP8788 - TI OMAP USB TLL - Maxim MAX8907 - SMSC ECE1099 - Dialog Semiconductor DA9055 - A simpler syscon driver that allow us to get rid of the anatop one. Drivers are also gradually getting Device Tree and IRQ domain support. The following drivers got DT support: - palmas, 88pm860x, tc3589x and twl4030-audio And those ones now use the IRQ domain APIs: - 88pm860x, tc3589x, db8500_prcmu Also some other interesting changes: - Intel's ICH LPC now supports Lynx Point - TI's twl4030-audio added a GPO child - tps6527 enabled its backlight subdevice - The twl6030 pwm driver moved to the new PWM subsystem And finally a bunch of cleanup and casual fixes for mc13xxx, 88pm860x, palmas, ab8500, wm8994, wm5110, max8907 and the tps65xxx family." Fix up various annoying conflicts: the DT and IRQ domain support came in twice and was already in 3.6. And then it was apparently rebased. Guys, DON'T REBASE! * tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (89 commits) ARM: dts: Enable 88pm860x pmic mfd: 88pm860x: Move gpadc init into touch mfd: 88pm860x: Device tree support mfd: 88pm860x: Use irqdomain mfd: smsc: Add support for smsc gpio io/keypad driver backlight: tps65217_bl: Add missing platform_set_drvdata in tps65217_bl_probe mfd: DA9055 core driver mfd: tps65910: Add alarm interrupt of TPS65910 RTC to mfd device list mfd: wm5110: Add register patches for revision B mfd: wm5110: Disable control interface error report for WM5110 rev B mfd: max8907: Remove regulator-compatible from DT docs backlight: Add TPS65217 WLED driver mfd: Add backlight as subdevice to the tps65217 mfd: Provide the PRCMU with its own IRQ domain mfd: Fix max8907 sparse warning mfd: Add lp8788 mfd driver mfd: dbx500: Provide a more accurate smp_twd clock mfd: rc5t583: Fix warning messages regulator: palmas: Add DT support mfd: palmas: Change regulator defns to better suite DT ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpio/Kconfig7
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/gpio-ich.c79
-rw-r--r--drivers/gpio/gpio-twl6040.c137
-rw-r--r--drivers/input/misc/twl4030-vibra.c18
-rw-r--r--drivers/input/touchscreen/88pm860x-ts.c127
-rw-r--r--drivers/leds/leds-88pm860x.c205
-rw-r--r--drivers/mfd/88pm860x-core.c805
-rw-r--r--drivers/mfd/88pm860x-i2c.c174
-rw-r--r--drivers/mfd/Kconfig75
-rw-r--r--drivers/mfd/Makefile12
-rw-r--r--drivers/mfd/ab3100-core.c1
-rw-r--r--drivers/mfd/ab8500-core.c37
-rw-r--r--drivers/mfd/anatop-mfd.c124
-rw-r--r--drivers/mfd/arizona-irq.c56
-rw-r--r--drivers/mfd/da9055-core.c423
-rw-r--r--drivers/mfd/da9055-i2c.c93
-rw-r--r--drivers/mfd/db8500-prcmu.c47
-rw-r--r--drivers/mfd/lp8788-irq.c198
-rw-r--r--drivers/mfd/lp8788.c245
-rw-r--r--drivers/mfd/lpc_ich.c43
-rw-r--r--drivers/mfd/max8907.c351
-rw-r--r--drivers/mfd/max8925-core.c427
-rw-r--r--drivers/mfd/mc13xxx-core.c1
-rw-r--r--drivers/mfd/omap-usb-host.c238
-rw-r--r--drivers/mfd/omap-usb-tll.c471
-rw-r--r--drivers/mfd/palmas.c149
-rw-r--r--drivers/mfd/rc5t583-irq.c2
-rw-r--r--drivers/mfd/rc5t583.c2
-rw-r--r--drivers/mfd/smsc-ece1099.c113
-rw-r--r--drivers/mfd/syscon.c176
-rw-r--r--drivers/mfd/tc3589x.c112
-rw-r--r--drivers/mfd/tps65090.c2
-rw-r--r--drivers/mfd/tps65217.c3
-rw-r--r--drivers/mfd/tps6586x.c19
-rw-r--r--drivers/mfd/tps65910.c32
-rw-r--r--drivers/mfd/twl-core.c156
-rw-r--r--drivers/mfd/twl4030-audio.c105
-rw-r--r--drivers/mfd/twl6040-core.c17
-rw-r--r--drivers/mfd/wm5110-tables.c96
-rw-r--r--drivers/mfd/wm831x-core.c66
-rw-r--r--drivers/mfd/wm8994-core.c2
-rw-r--r--drivers/mfd/wm8994-regmap.c2
-rw-r--r--drivers/pwm/Kconfig9
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/pwm-twl6030.c (renamed from drivers/mfd/twl6030-pwm.c)119
-rw-r--r--drivers/regulator/88pm8607.c136
-rw-r--r--drivers/regulator/Kconfig2
-rw-r--r--drivers/regulator/ab3100.c1
-rw-r--r--drivers/regulator/anatop-regulator.c31
-rw-r--r--drivers/regulator/max8925-regulator.c35
-rw-r--r--drivers/regulator/palmas-regulator.c127
-rw-r--r--drivers/regulator/wm831x-dcdc.c12
-rw-r--r--drivers/regulator/wm831x-isink.c4
-rw-r--r--drivers/regulator/wm831x-ldo.c12
-rw-r--r--drivers/rtc/rtc-88pm860x.c43
-rw-r--r--drivers/video/backlight/88pm860x_bl.c146
-rw-r--r--drivers/video/backlight/Kconfig7
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/max8925_bl.c79
-rw-r--r--drivers/video/backlight/tps65217_bl.c342
-rw-r--r--drivers/watchdog/iTCO_wdt.c1
62 files changed, 5008 insertions, 1549 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8382dc832929..aa73ef3233b8 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -409,6 +409,13 @@ config GPIO_TWL4030
409 Say yes here to access the GPIO signals of various multi-function 409 Say yes here to access the GPIO signals of various multi-function
410 power management chips from Texas Instruments. 410 power management chips from Texas Instruments.
411 411
412config GPIO_TWL6040
413 tristate "TWL6040 GPO"
414 depends on TWL6040_CORE
415 help
416 Say yes here to access the GPO signals of twl6040
417 audio chip from Texas Instruments.
418
412config GPIO_WM831X 419config GPIO_WM831X
413 tristate "WM831x GPIOs" 420 tristate "WM831x GPIOs"
414 depends on MFD_WM831X 421 depends on MFD_WM831X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 0ffaa8423e87..b2c109d1303d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_GPIO_TPS6586X) += gpio-tps6586x.o
68obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o 68obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o
69obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o 69obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o
70obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o 70obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o
71obj-$(CONFIG_GPIO_TWL6040) += gpio-twl6040.o
71obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o 72obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o
72obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o 73obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o
73obj-$(CONFIG_GPIO_VT8500) += gpio-vt8500.o 74obj-$(CONFIG_GPIO_VT8500) += gpio-vt8500.o
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c
index b7c06517403d..d4d617966696 100644
--- a/drivers/gpio/gpio-ich.c
+++ b/drivers/gpio/gpio-ich.c
@@ -49,6 +49,10 @@ static const u8 ichx_regs[3][3] = {
49 {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */ 49 {0x0c, 0x38, 0x48}, /* LVL[1-3] offsets */
50}; 50};
51 51
52static const u8 ichx_reglen[3] = {
53 0x30, 0x10, 0x10,
54};
55
52#define ICHX_WRITE(val, reg, base_res) outl(val, (reg) + (base_res)->start) 56#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) 57#define ICHX_READ(reg, base_res) inl((reg) + (base_res)->start)
54 58
@@ -75,6 +79,7 @@ static struct {
75 struct resource *pm_base; /* Power Mangagment IO base */ 79 struct resource *pm_base; /* Power Mangagment IO base */
76 struct ichx_desc *desc; /* Pointer to chipset-specific description */ 80 struct ichx_desc *desc; /* Pointer to chipset-specific description */
77 u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */ 81 u32 orig_gpio_ctrl; /* Orig CTRL value, used to restore on exit */
82 u8 use_gpio; /* Which GPIO groups are usable */
78} ichx_priv; 83} ichx_priv;
79 84
80static int modparam_gpiobase = -1; /* dynamic */ 85static int modparam_gpiobase = -1; /* dynamic */
@@ -123,8 +128,16 @@ static int ichx_read_bit(int reg, unsigned nr)
123 return data & (1 << bit) ? 1 : 0; 128 return data & (1 << bit) ? 1 : 0;
124} 129}
125 130
131static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
132{
133 return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO;
134}
135
126static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) 136static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
127{ 137{
138 if (!ichx_gpio_check_available(gpio, nr))
139 return -ENXIO;
140
128 /* 141 /*
129 * Try setting pin as an input and verify it worked since many pins 142 * Try setting pin as an input and verify it worked since many pins
130 * are output-only. 143 * are output-only.
@@ -138,6 +151,9 @@ static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
138static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, 151static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
139 int val) 152 int val)
140{ 153{
154 if (!ichx_gpio_check_available(gpio, nr))
155 return -ENXIO;
156
141 /* Set GPIO output value. */ 157 /* Set GPIO output value. */
142 ichx_write_bit(GPIO_LVL, nr, val, 0); 158 ichx_write_bit(GPIO_LVL, nr, val, 0);
143 159
@@ -153,6 +169,9 @@ static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
153 169
154static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr) 170static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
155{ 171{
172 if (!ichx_gpio_check_available(chip, nr))
173 return -ENXIO;
174
156 return ichx_read_bit(GPIO_LVL, nr); 175 return ichx_read_bit(GPIO_LVL, nr);
157} 176}
158 177
@@ -161,6 +180,9 @@ static int ich6_gpio_get(struct gpio_chip *chip, unsigned nr)
161 unsigned long flags; 180 unsigned long flags;
162 u32 data; 181 u32 data;
163 182
183 if (!ichx_gpio_check_available(chip, nr))
184 return -ENXIO;
185
164 /* 186 /*
165 * GPI 0 - 15 need to be read from the power management registers on 187 * GPI 0 - 15 need to be read from the power management registers on
166 * a ICH6/3100 bridge. 188 * a ICH6/3100 bridge.
@@ -291,6 +313,46 @@ static struct ichx_desc intel5_desc = {
291 .ngpio = 76, 313 .ngpio = 76,
292}; 314};
293 315
316static int __devinit ichx_gpio_request_regions(struct resource *res_base,
317 const char *name, u8 use_gpio)
318{
319 int i;
320
321 if (!res_base || !res_base->start || !res_base->end)
322 return -ENODEV;
323
324 for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
325 if (!(use_gpio & (1 << i)))
326 continue;
327 if (!request_region(res_base->start + ichx_regs[0][i],
328 ichx_reglen[i], name))
329 goto request_err;
330 }
331 return 0;
332
333request_err:
334 /* Clean up: release already requested regions, if any */
335 for (i--; i >= 0; i--) {
336 if (!(use_gpio & (1 << i)))
337 continue;
338 release_region(res_base->start + ichx_regs[0][i],
339 ichx_reglen[i]);
340 }
341 return -EBUSY;
342}
343
344static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
345{
346 int i;
347
348 for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
349 if (!(use_gpio & (1 << i)))
350 continue;
351 release_region(res_base->start + ichx_regs[0][i],
352 ichx_reglen[i]);
353 }
354}
355
294static int __devinit ichx_gpio_probe(struct platform_device *pdev) 356static int __devinit ichx_gpio_probe(struct platform_device *pdev)
295{ 357{
296 struct resource *res_base, *res_pm; 358 struct resource *res_base, *res_pm;
@@ -329,12 +391,11 @@ static int __devinit ichx_gpio_probe(struct platform_device *pdev)
329 } 391 }
330 392
331 res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO); 393 res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
332 if (!res_base || !res_base->start || !res_base->end) 394 ichx_priv.use_gpio = ich_info->use_gpio;
333 return -ENODEV; 395 err = ichx_gpio_request_regions(res_base, pdev->name,
334 396 ichx_priv.use_gpio);
335 if (!request_region(res_base->start, resource_size(res_base), 397 if (err)
336 pdev->name)) 398 return err;
337 return -EBUSY;
338 399
339 ichx_priv.gpio_base = res_base; 400 ichx_priv.gpio_base = res_base;
340 401
@@ -374,8 +435,7 @@ init:
374 return 0; 435 return 0;
375 436
376add_err: 437add_err:
377 release_region(ichx_priv.gpio_base->start, 438 ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
378 resource_size(ichx_priv.gpio_base));
379 if (ichx_priv.pm_base) 439 if (ichx_priv.pm_base)
380 release_region(ichx_priv.pm_base->start, 440 release_region(ichx_priv.pm_base->start,
381 resource_size(ichx_priv.pm_base)); 441 resource_size(ichx_priv.pm_base));
@@ -393,8 +453,7 @@ static int __devexit ichx_gpio_remove(struct platform_device *pdev)
393 return err; 453 return err;
394 } 454 }
395 455
396 release_region(ichx_priv.gpio_base->start, 456 ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
397 resource_size(ichx_priv.gpio_base));
398 if (ichx_priv.pm_base) 457 if (ichx_priv.pm_base)
399 release_region(ichx_priv.pm_base->start, 458 release_region(ichx_priv.pm_base->start,
400 resource_size(ichx_priv.pm_base)); 459 resource_size(ichx_priv.pm_base));
diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c
new file mode 100644
index 000000000000..dd58e8b25043
--- /dev/null
+++ b/drivers/gpio/gpio-twl6040.c
@@ -0,0 +1,137 @@
1/*
2 * Access to GPOs on TWL6040 chip
3 *
4 * Copyright (C) 2012 Texas Instruments, Inc.
5 *
6 * Authors:
7 * Sergio Aguirre <saaguirre@ti.com>
8 * Peter Ujfalusi <peter.ujfalusi@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/kthread.h>
28#include <linux/irq.h>
29#include <linux/gpio.h>
30#include <linux/platform_device.h>
31#include <linux/of.h>
32
33#include <linux/mfd/twl6040.h>
34
35static struct gpio_chip twl6040gpo_chip;
36
37static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset)
38{
39 struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
40 int ret = 0;
41
42 ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
43 if (ret < 0)
44 return ret;
45
46 return (ret >> offset) & 1;
47}
48
49static int twl6040gpo_direction_out(struct gpio_chip *chip, unsigned offset,
50 int value)
51{
52 /* This only drives GPOs, and can't change direction */
53 return 0;
54}
55
56static void twl6040gpo_set(struct gpio_chip *chip, unsigned offset, int value)
57{
58 struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
59 int ret;
60 u8 gpoctl;
61
62 ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
63 if (ret < 0)
64 return;
65
66 if (value)
67 gpoctl = ret | (1 << offset);
68 else
69 gpoctl = ret & ~(1 << offset);
70
71 twl6040_reg_write(twl6040, TWL6040_REG_GPOCTL, gpoctl);
72}
73
74static struct gpio_chip twl6040gpo_chip = {
75 .label = "twl6040",
76 .owner = THIS_MODULE,
77 .get = twl6040gpo_get,
78 .direction_output = twl6040gpo_direction_out,
79 .set = twl6040gpo_set,
80 .can_sleep = 1,
81};
82
83/*----------------------------------------------------------------------*/
84
85static int __devinit gpo_twl6040_probe(struct platform_device *pdev)
86{
87 struct twl6040_gpo_data *pdata = pdev->dev.platform_data;
88 struct device *twl6040_core_dev = pdev->dev.parent;
89 struct twl6040 *twl6040 = dev_get_drvdata(twl6040_core_dev);
90 int ret;
91
92 if (pdata)
93 twl6040gpo_chip.base = pdata->gpio_base;
94 else
95 twl6040gpo_chip.base = -1;
96
97 if (twl6040_get_revid(twl6040) < TWL6041_REV_ES2_0)
98 twl6040gpo_chip.ngpio = 3; /* twl6040 have 3 GPO */
99 else
100 twl6040gpo_chip.ngpio = 1; /* twl6041 have 1 GPO */
101
102 twl6040gpo_chip.dev = &pdev->dev;
103#ifdef CONFIG_OF_GPIO
104 twl6040gpo_chip.of_node = twl6040_core_dev->of_node;
105#endif
106
107 ret = gpiochip_add(&twl6040gpo_chip);
108 if (ret < 0) {
109 dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
110 twl6040gpo_chip.ngpio = 0;
111 }
112
113 return ret;
114}
115
116static int __devexit gpo_twl6040_remove(struct platform_device *pdev)
117{
118 return gpiochip_remove(&twl6040gpo_chip);
119}
120
121/* Note: this hardware lives inside an I2C-based multi-function device. */
122MODULE_ALIAS("platform:twl6040-gpo");
123
124static struct platform_driver gpo_twl6040_driver = {
125 .driver = {
126 .name = "twl6040-gpo",
127 .owner = THIS_MODULE,
128 },
129 .probe = gpo_twl6040_probe,
130 .remove = gpo_twl6040_remove,
131};
132
133module_platform_driver(gpo_twl6040_driver);
134
135MODULE_AUTHOR("Texas Instruments, Inc.");
136MODULE_DESCRIPTION("GPO interface for TWL6040");
137MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index fc0ed9b43424..2194a3c7236a 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -26,6 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/jiffies.h> 27#include <linux/jiffies.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/of.h>
29#include <linux/workqueue.h> 30#include <linux/workqueue.h>
30#include <linux/i2c/twl.h> 31#include <linux/i2c/twl.h>
31#include <linux/mfd/twl4030-audio.h> 32#include <linux/mfd/twl4030-audio.h>
@@ -194,13 +195,26 @@ static int twl4030_vibra_resume(struct device *dev)
194static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, 195static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
195 twl4030_vibra_suspend, twl4030_vibra_resume); 196 twl4030_vibra_suspend, twl4030_vibra_resume);
196 197
198static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
199 struct device_node *node)
200{
201 if (pdata && pdata->coexist)
202 return true;
203
204 if (of_find_node_by_name(node, "codec"))
205 return true;
206
207 return false;
208}
209
197static int __devinit twl4030_vibra_probe(struct platform_device *pdev) 210static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
198{ 211{
199 struct twl4030_vibra_data *pdata = pdev->dev.platform_data; 212 struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
213 struct device_node *twl4030_core_node = pdev->dev.parent->of_node;
200 struct vibra_info *info; 214 struct vibra_info *info;
201 int ret; 215 int ret;
202 216
203 if (!pdata) { 217 if (!pdata && !twl4030_core_node) {
204 dev_dbg(&pdev->dev, "platform_data not available\n"); 218 dev_dbg(&pdev->dev, "platform_data not available\n");
205 return -EINVAL; 219 return -EINVAL;
206 } 220 }
@@ -210,7 +224,7 @@ static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
210 return -ENOMEM; 224 return -ENOMEM;
211 225
212 info->dev = &pdev->dev; 226 info->dev = &pdev->dev;
213 info->coexist = pdata->coexist; 227 info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node);
214 INIT_WORK(&info->play_work, vibra_play_work); 228 INIT_WORK(&info->play_work, vibra_play_work);
215 229
216 info->input_dev = input_allocate_device(); 230 info->input_dev = input_allocate_device();
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 05f30b73c3c3..326218dbd6e6 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -10,6 +10,7 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of.h>
13#include <linux/platform_device.h> 14#include <linux/platform_device.h>
14#include <linux/i2c.h> 15#include <linux/i2c.h>
15#include <linux/input.h> 16#include <linux/input.h>
@@ -113,14 +114,69 @@ static void pm860x_touch_close(struct input_dev *dev)
113 pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0); 114 pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
114} 115}
115 116
117#ifdef CONFIG_OF
118static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
119 struct pm860x_chip *chip,
120 int *res_x)
121{
122 struct device_node *np = pdev->dev.parent->of_node;
123 struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
124 : chip->companion;
125 int data, n, ret;
126 if (!np)
127 return -ENODEV;
128 np = of_find_node_by_name(np, "touch");
129 if (!np) {
130 dev_err(&pdev->dev, "Can't find touch node\n");
131 return -EINVAL;
132 }
133 /* set GPADC MISC1 register */
134 data = 0;
135 if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n))
136 data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK;
137 if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n))
138 data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
139 if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n))
140 data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK;
141 if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n))
142 data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK;
143 if (data) {
144 ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
145 if (ret < 0)
146 return -EINVAL;
147 }
148 /* set tsi prebias time */
149 if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
150 ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
151 if (ret < 0)
152 return -EINVAL;
153 }
154 /* set prebias & prechg time of pen detect */
155 data = 0;
156 if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n))
157 data |= n & PM8607_PD_PREBIAS_MASK;
158 if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n))
159 data |= n & PM8607_PD_PRECHG_MASK;
160 if (data) {
161 ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
162 if (ret < 0)
163 return -EINVAL;
164 }
165 of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
166 return 0;
167}
168#else
169#define pm860x_touch_dt_init(x, y, z) (-1)
170#endif
171
116static int __devinit pm860x_touch_probe(struct platform_device *pdev) 172static int __devinit pm860x_touch_probe(struct platform_device *pdev)
117{ 173{
118 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 174 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
119 struct pm860x_platform_data *pm860x_pdata = \ 175 struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
120 pdev->dev.parent->platform_data;
121 struct pm860x_touch_pdata *pdata = NULL;
122 struct pm860x_touch *touch; 176 struct pm860x_touch *touch;
123 int irq, ret; 177 struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
178 : chip->companion;
179 int irq, ret, res_x = 0, data = 0;
124 180
125 irq = platform_get_irq(pdev, 0); 181 irq = platform_get_irq(pdev, 0);
126 if (irq < 0) { 182 if (irq < 0) {
@@ -128,16 +184,55 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
128 return -EINVAL; 184 return -EINVAL;
129 } 185 }
130 186
131 if (!pm860x_pdata) { 187 if (pm860x_touch_dt_init(pdev, chip, &res_x)) {
132 dev_err(&pdev->dev, "platform data is missing\n"); 188 if (pdata) {
133 return -EINVAL; 189 /* set GPADC MISC1 register */
134 } 190 data = 0;
135 191 data |= (pdata->gpadc_prebias << 1)
136 pdata = pm860x_pdata->touch; 192 & PM8607_GPADC_PREBIAS_MASK;
137 if (!pdata) { 193 data |= (pdata->slot_cycle << 3)
138 dev_err(&pdev->dev, "touchscreen data is missing\n"); 194 & PM8607_GPADC_SLOT_CYCLE_MASK;
139 return -EINVAL; 195 data |= (pdata->off_scale << 5)
196 & PM8607_GPADC_OFF_SCALE_MASK;
197 data |= (pdata->sw_cal << 7)
198 & PM8607_GPADC_SW_CAL_MASK;
199 if (data) {
200 ret = pm860x_reg_write(i2c,
201 PM8607_GPADC_MISC1, data);
202 if (ret < 0)
203 return -EINVAL;
204 }
205 /* set tsi prebias time */
206 if (pdata->tsi_prebias) {
207 data = pdata->tsi_prebias;
208 ret = pm860x_reg_write(i2c,
209 PM8607_TSI_PREBIAS, data);
210 if (ret < 0)
211 return -EINVAL;
212 }
213 /* set prebias & prechg time of pen detect */
214 data = 0;
215 data |= pdata->pen_prebias
216 & PM8607_PD_PREBIAS_MASK;
217 data |= (pdata->pen_prechg << 5)
218 & PM8607_PD_PRECHG_MASK;
219 if (data) {
220 ret = pm860x_reg_write(i2c,
221 PM8607_PD_PREBIAS, data);
222 if (ret < 0)
223 return -EINVAL;
224 }
225 res_x = pdata->res_x;
226 } else {
227 dev_err(&pdev->dev, "failed to get platform data\n");
228 return -EINVAL;
229 }
140 } 230 }
231 /* enable GPADC */
232 ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN,
233 PM8607_GPADC_EN);
234 if (ret)
235 return ret;
141 236
142 touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL); 237 touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
143 if (touch == NULL) 238 if (touch == NULL)
@@ -158,9 +253,9 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)
158 touch->idev->open = pm860x_touch_open; 253 touch->idev->open = pm860x_touch_open;
159 touch->idev->close = pm860x_touch_close; 254 touch->idev->close = pm860x_touch_close;
160 touch->chip = chip; 255 touch->chip = chip;
161 touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 256 touch->i2c = i2c;
162 touch->irq = irq + chip->irq_base; 257 touch->irq = irq;
163 touch->res_x = pdata->res_x; 258 touch->res_x = res_x;
164 input_set_drvdata(touch->idev, touch); 259 input_set_drvdata(touch->idev, touch);
165 260
166 ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler, 261 ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 61897cfeeda6..b7e8cc0957fc 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/of.h>
15#include <linux/platform_device.h> 16#include <linux/platform_device.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/leds.h> 18#include <linux/leds.h>
@@ -20,18 +21,12 @@
20#include <linux/mfd/88pm860x.h> 21#include <linux/mfd/88pm860x.h>
21#include <linux/module.h> 22#include <linux/module.h>
22 23
23#define LED_PWM_SHIFT (3)
24#define LED_PWM_MASK (0x1F) 24#define LED_PWM_MASK (0x1F)
25#define LED_CURRENT_MASK (0x07 << 5) 25#define LED_CURRENT_MASK (0x07 << 5)
26 26
27#define LED_BLINK_ON_MASK (0x07)
28#define LED_BLINK_MASK (0x7F) 27#define LED_BLINK_MASK (0x7F)
29 28
30#define LED_BLINK_ON(x) ((x & 0x7) * 66 + 66)
31#define LED_BLINK_ON_MIN LED_BLINK_ON(0)
32#define LED_BLINK_ON_MAX LED_BLINK_ON(0x7)
33#define LED_ON_CONTINUOUS (0x0F << 3) 29#define LED_ON_CONTINUOUS (0x0F << 3)
34#define LED_TO_ON(x) ((x - 66) / 66)
35 30
36#define LED1_BLINK_EN (1 << 1) 31#define LED1_BLINK_EN (1 << 1)
37#define LED2_BLINK_EN (1 << 2) 32#define LED2_BLINK_EN (1 << 2)
@@ -49,85 +44,25 @@ struct pm860x_led {
49 unsigned char brightness; 44 unsigned char brightness;
50 unsigned char current_brightness; 45 unsigned char current_brightness;
51 46
52 int blink_data; 47 int reg_control;
53 int blink_time; 48 int reg_blink;
54 int blink_on; 49 int blink_mask;
55 int blink_off;
56}; 50};
57 51
58/* return offset of color register */
59static inline int __led_off(int port)
60{
61 int ret = -EINVAL;
62
63 switch (port) {
64 case PM8606_LED1_RED:
65 case PM8606_LED1_GREEN:
66 case PM8606_LED1_BLUE:
67 ret = port - PM8606_LED1_RED + PM8606_RGB1B;
68 break;
69 case PM8606_LED2_RED:
70 case PM8606_LED2_GREEN:
71 case PM8606_LED2_BLUE:
72 ret = port - PM8606_LED2_RED + PM8606_RGB2B;
73 break;
74 }
75 return ret;
76}
77
78/* return offset of blink register */
79static inline int __blink_off(int port)
80{
81 int ret = -EINVAL;
82
83 switch (port) {
84 case PM8606_LED1_RED:
85 case PM8606_LED1_GREEN:
86 case PM8606_LED1_BLUE:
87 ret = PM8606_RGB1A;
88 break;
89 case PM8606_LED2_RED:
90 case PM8606_LED2_GREEN:
91 case PM8606_LED2_BLUE:
92 ret = PM8606_RGB2A;
93 break;
94 }
95 return ret;
96}
97
98static inline int __blink_ctl_mask(int port)
99{
100 int ret = -EINVAL;
101
102 switch (port) {
103 case PM8606_LED1_RED:
104 case PM8606_LED1_GREEN:
105 case PM8606_LED1_BLUE:
106 ret = LED1_BLINK_EN;
107 break;
108 case PM8606_LED2_RED:
109 case PM8606_LED2_GREEN:
110 case PM8606_LED2_BLUE:
111 ret = LED2_BLINK_EN;
112 break;
113 }
114 return ret;
115}
116
117static int led_power_set(struct pm860x_chip *chip, int port, int on) 52static int led_power_set(struct pm860x_chip *chip, int port, int on)
118{ 53{
119 int ret = -EINVAL; 54 int ret = -EINVAL;
120 55
121 switch (port) { 56 switch (port) {
122 case PM8606_LED1_RED: 57 case 0:
123 case PM8606_LED1_GREEN: 58 case 1:
124 case PM8606_LED1_BLUE: 59 case 2:
125 ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) : 60 ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) :
126 pm8606_osc_disable(chip, RGB1_ENABLE); 61 pm8606_osc_disable(chip, RGB1_ENABLE);
127 break; 62 break;
128 case PM8606_LED2_RED: 63 case 3:
129 case PM8606_LED2_GREEN: 64 case 4:
130 case PM8606_LED2_BLUE: 65 case 5:
131 ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) : 66 ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) :
132 pm8606_osc_disable(chip, RGB2_ENABLE); 67 pm8606_osc_disable(chip, RGB2_ENABLE);
133 break; 68 break;
@@ -141,7 +76,7 @@ static void pm860x_led_work(struct work_struct *work)
141 struct pm860x_led *led; 76 struct pm860x_led *led;
142 struct pm860x_chip *chip; 77 struct pm860x_chip *chip;
143 unsigned char buf[3]; 78 unsigned char buf[3];
144 int mask, ret; 79 int ret;
145 80
146 led = container_of(work, struct pm860x_led, work); 81 led = container_of(work, struct pm860x_led, work);
147 chip = led->chip; 82 chip = led->chip;
@@ -149,34 +84,34 @@ static void pm860x_led_work(struct work_struct *work)
149 if ((led->current_brightness == 0) && led->brightness) { 84 if ((led->current_brightness == 0) && led->brightness) {
150 led_power_set(chip, led->port, 1); 85 led_power_set(chip, led->port, 1);
151 if (led->iset) { 86 if (led->iset) {
152 pm860x_set_bits(led->i2c, __led_off(led->port), 87 pm860x_set_bits(led->i2c, led->reg_control,
153 LED_CURRENT_MASK, led->iset); 88 LED_CURRENT_MASK, led->iset);
154 } 89 }
155 pm860x_set_bits(led->i2c, __blink_off(led->port), 90 pm860x_set_bits(led->i2c, led->reg_blink,
156 LED_BLINK_MASK, LED_ON_CONTINUOUS); 91 LED_BLINK_MASK, LED_ON_CONTINUOUS);
157 mask = __blink_ctl_mask(led->port); 92 pm860x_set_bits(led->i2c, PM8606_WLED3B, led->blink_mask,
158 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask); 93 led->blink_mask);
159 } 94 }
160 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK, 95 pm860x_set_bits(led->i2c, led->reg_control, LED_PWM_MASK,
161 led->brightness); 96 led->brightness);
162 97
163 if (led->brightness == 0) { 98 if (led->brightness == 0) {
164 pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf); 99 pm860x_bulk_read(led->i2c, led->reg_control, 3, buf);
165 ret = buf[0] & LED_PWM_MASK; 100 ret = buf[0] & LED_PWM_MASK;
166 ret |= buf[1] & LED_PWM_MASK; 101 ret |= buf[1] & LED_PWM_MASK;
167 ret |= buf[2] & LED_PWM_MASK; 102 ret |= buf[2] & LED_PWM_MASK;
168 if (ret == 0) { 103 if (ret == 0) {
169 /* unset current since no led is lighting */ 104 /* unset current since no led is lighting */
170 pm860x_set_bits(led->i2c, __led_off(led->port), 105 pm860x_set_bits(led->i2c, led->reg_control,
171 LED_CURRENT_MASK, 0); 106 LED_CURRENT_MASK, 0);
172 mask = __blink_ctl_mask(led->port); 107 pm860x_set_bits(led->i2c, PM8606_WLED3B,
173 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0); 108 led->blink_mask, 0);
174 led_power_set(chip, led->port, 0); 109 led_power_set(chip, led->port, 0);
175 } 110 }
176 } 111 }
177 led->current_brightness = led->brightness; 112 led->current_brightness = led->brightness;
178 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 113 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
179 __led_off(led->port), led->brightness); 114 led->reg_control, led->brightness);
180 mutex_unlock(&led->lock); 115 mutex_unlock(&led->lock);
181} 116}
182 117
@@ -189,39 +124,92 @@ static void pm860x_led_set(struct led_classdev *cdev,
189 schedule_work(&data->work); 124 schedule_work(&data->work);
190} 125}
191 126
127#ifdef CONFIG_OF
128static int pm860x_led_dt_init(struct platform_device *pdev,
129 struct pm860x_led *data)
130{
131 struct device_node *nproot = pdev->dev.parent->of_node, *np;
132 int iset = 0;
133 if (!nproot)
134 return -ENODEV;
135 nproot = of_find_node_by_name(nproot, "leds");
136 if (!nproot) {
137 dev_err(&pdev->dev, "failed to find leds node\n");
138 return -ENODEV;
139 }
140 for_each_child_of_node(nproot, np) {
141 if (!of_node_cmp(np->name, data->name)) {
142 of_property_read_u32(np, "marvell,88pm860x-iset",
143 &iset);
144 data->iset = PM8606_LED_CURRENT(iset);
145 break;
146 }
147 }
148 return 0;
149}
150#else
151#define pm860x_led_dt_init(x, y) (-1)
152#endif
153
192static int pm860x_led_probe(struct platform_device *pdev) 154static int pm860x_led_probe(struct platform_device *pdev)
193{ 155{
194 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 156 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
195 struct pm860x_led_pdata *pdata; 157 struct pm860x_led_pdata *pdata = pdev->dev.platform_data;
196 struct pm860x_led *data; 158 struct pm860x_led *data;
197 struct resource *res; 159 struct resource *res;
198 int ret; 160 int ret = 0;
199
200 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
201 if (res == NULL) {
202 dev_err(&pdev->dev, "No I/O resource!\n");
203 return -EINVAL;
204 }
205
206 pdata = pdev->dev.platform_data;
207 if (pdata == NULL) {
208 dev_err(&pdev->dev, "No platform data!\n");
209 return -EINVAL;
210 }
211 161
212 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL); 162 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL);
213 if (data == NULL) 163 if (data == NULL)
214 return -ENOMEM; 164 return -ENOMEM;
215 strncpy(data->name, res->name, MFD_NAME_SIZE - 1); 165 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "control");
166 if (!res) {
167 dev_err(&pdev->dev, "No REG resource for control\n");
168 ret = -ENXIO;
169 goto out;
170 }
171 data->reg_control = res->start;
172 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "blink");
173 if (!res) {
174 dev_err(&pdev->dev, "No REG resource for blink\n");
175 ret = -ENXIO;
176 goto out;
177 }
178 data->reg_blink = res->start;
179 memset(data->name, 0, MFD_NAME_SIZE);
180 switch (pdev->id) {
181 case 0:
182 data->blink_mask = LED1_BLINK_EN;
183 sprintf(data->name, "led0-red");
184 break;
185 case 1:
186 data->blink_mask = LED1_BLINK_EN;
187 sprintf(data->name, "led0-green");
188 break;
189 case 2:
190 data->blink_mask = LED1_BLINK_EN;
191 sprintf(data->name, "led0-blue");
192 break;
193 case 3:
194 data->blink_mask = LED2_BLINK_EN;
195 sprintf(data->name, "led1-red");
196 break;
197 case 4:
198 data->blink_mask = LED2_BLINK_EN;
199 sprintf(data->name, "led1-green");
200 break;
201 case 5:
202 data->blink_mask = LED2_BLINK_EN;
203 sprintf(data->name, "led1-blue");
204 break;
205 }
216 dev_set_drvdata(&pdev->dev, data); 206 dev_set_drvdata(&pdev->dev, data);
217 data->chip = chip; 207 data->chip = chip;
218 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 208 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
219 data->iset = pdata->iset; 209 data->port = pdev->id;
220 data->port = pdata->flags; 210 if (pm860x_led_dt_init(pdev, data))
221 if (data->port < 0) { 211 if (pdata)
222 dev_err(&pdev->dev, "check device failed\n"); 212 data->iset = pdata->iset;
223 return -EINVAL;
224 }
225 213
226 data->current_brightness = 0; 214 data->current_brightness = 0;
227 data->cdev.name = data->name; 215 data->cdev.name = data->name;
@@ -236,6 +224,9 @@ static int pm860x_led_probe(struct platform_device *pdev)
236 } 224 }
237 pm860x_led_set(&data->cdev, 0); 225 pm860x_led_set(&data->cdev, 0);
238 return 0; 226 return 0;
227out:
228 devm_kfree(&pdev->dev, data);
229 return ret;
239} 230}
240 231
241static int pm860x_led_remove(struct platform_device *pdev) 232static int pm860x_led_remove(struct platform_device *pdev)
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index b73f033b2c60..59d117e9fa31 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -11,50 +11,116 @@
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/err.h>
14#include <linux/i2c.h> 15#include <linux/i2c.h>
15#include <linux/irq.h> 16#include <linux/irq.h>
16#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/irqdomain.h>
19#include <linux/of.h>
20#include <linux/of_platform.h>
17#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23#include <linux/slab.h>
18#include <linux/mfd/core.h> 24#include <linux/mfd/core.h>
19#include <linux/mfd/88pm860x.h> 25#include <linux/mfd/88pm860x.h>
20#include <linux/regulator/machine.h> 26#include <linux/regulator/machine.h>
21 27
22#define INT_STATUS_NUM 3 28#define INT_STATUS_NUM 3
23 29
24static struct resource bk_resources[] __devinitdata = { 30static struct resource bk0_resources[] __devinitdata = {
25 {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,}, 31 {2, 2, "duty cycle", IORESOURCE_REG, },
26 {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,}, 32 {3, 3, "always on", IORESOURCE_REG, },
27 {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,}, 33 {3, 3, "current", IORESOURCE_REG, },
28}; 34};
29 35static struct resource bk1_resources[] __devinitdata = {
30static struct resource led_resources[] __devinitdata = { 36 {4, 4, "duty cycle", IORESOURCE_REG, },
31 {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO,}, 37 {5, 5, "always on", IORESOURCE_REG, },
32 {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,}, 38 {5, 5, "current", IORESOURCE_REG, },
33 {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_IO,}, 39};
34 {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_IO,}, 40static struct resource bk2_resources[] __devinitdata = {
35 {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO,}, 41 {6, 6, "duty cycle", IORESOURCE_REG, },
36 {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,}, 42 {7, 7, "always on", IORESOURCE_REG, },
37}; 43 {5, 5, "current", IORESOURCE_REG, },
38 44};
39static struct resource regulator_resources[] __devinitdata = { 45
40 {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,}, 46static struct resource led0_resources[] __devinitdata = {
41 {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,}, 47 /* RGB1 Red LED */
42 {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,}, 48 {0xd, 0xd, "control", IORESOURCE_REG, },
43 {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,}, 49 {0xc, 0xc, "blink", IORESOURCE_REG, },
44 {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,}, 50};
45 {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,}, 51static struct resource led1_resources[] __devinitdata = {
46 {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,}, 52 /* RGB1 Green LED */
47 {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,}, 53 {0xe, 0xe, "control", IORESOURCE_REG, },
48 {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,}, 54 {0xc, 0xc, "blink", IORESOURCE_REG, },
49 {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,}, 55};
50 {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO,}, 56static struct resource led2_resources[] __devinitdata = {
51 {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO,}, 57 /* RGB1 Blue LED */
52 {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,}, 58 {0xf, 0xf, "control", IORESOURCE_REG, },
53 {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,}, 59 {0xc, 0xc, "blink", IORESOURCE_REG, },
54 {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,}, 60};
55 {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,}, 61static struct resource led3_resources[] __devinitdata = {
56 {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,}, 62 /* RGB2 Red LED */
57 {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,}, 63 {0x9, 0x9, "control", IORESOURCE_REG, },
64 {0x8, 0x8, "blink", IORESOURCE_REG, },
65};
66static struct resource led4_resources[] __devinitdata = {
67 /* RGB2 Green LED */
68 {0xa, 0xa, "control", IORESOURCE_REG, },
69 {0x8, 0x8, "blink", IORESOURCE_REG, },
70};
71static struct resource led5_resources[] __devinitdata = {
72 /* RGB2 Blue LED */
73 {0xb, 0xb, "control", IORESOURCE_REG, },
74 {0x8, 0x8, "blink", IORESOURCE_REG, },
75};
76
77static struct resource buck1_resources[] __devinitdata = {
78 {0x24, 0x24, "buck set", IORESOURCE_REG, },
79};
80static struct resource buck2_resources[] __devinitdata = {
81 {0x25, 0x25, "buck set", IORESOURCE_REG, },
82};
83static struct resource buck3_resources[] __devinitdata = {
84 {0x26, 0x26, "buck set", IORESOURCE_REG, },
85};
86static struct resource ldo1_resources[] __devinitdata = {
87 {0x10, 0x10, "ldo set", IORESOURCE_REG, },
88};
89static struct resource ldo2_resources[] __devinitdata = {
90 {0x11, 0x11, "ldo set", IORESOURCE_REG, },
91};
92static struct resource ldo3_resources[] __devinitdata = {
93 {0x12, 0x12, "ldo set", IORESOURCE_REG, },
94};
95static struct resource ldo4_resources[] __devinitdata = {
96 {0x13, 0x13, "ldo set", IORESOURCE_REG, },
97};
98static struct resource ldo5_resources[] __devinitdata = {
99 {0x14, 0x14, "ldo set", IORESOURCE_REG, },
100};
101static struct resource ldo6_resources[] __devinitdata = {
102 {0x15, 0x15, "ldo set", IORESOURCE_REG, },
103};
104static struct resource ldo7_resources[] __devinitdata = {
105 {0x16, 0x16, "ldo set", IORESOURCE_REG, },
106};
107static struct resource ldo8_resources[] __devinitdata = {
108 {0x17, 0x17, "ldo set", IORESOURCE_REG, },
109};
110static struct resource ldo9_resources[] __devinitdata = {
111 {0x18, 0x18, "ldo set", IORESOURCE_REG, },
112};
113static struct resource ldo10_resources[] __devinitdata = {
114 {0x19, 0x19, "ldo set", IORESOURCE_REG, },
115};
116static struct resource ldo12_resources[] __devinitdata = {
117 {0x1a, 0x1a, "ldo set", IORESOURCE_REG, },
118};
119static struct resource ldo_vibrator_resources[] __devinitdata = {
120 {0x28, 0x28, "ldo set", IORESOURCE_REG, },
121};
122static struct resource ldo14_resources[] __devinitdata = {
123 {0x1b, 0x1b, "ldo set", IORESOURCE_REG, },
58}; 124};
59 125
60static struct resource touch_resources[] __devinitdata = { 126static struct resource touch_resources[] __devinitdata = {
@@ -90,48 +156,145 @@ static struct resource charger_resources[] __devinitdata = {
90 {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, 156 {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
91}; 157};
92 158
93static struct resource preg_resources[] __devinitdata = {
94 {PM8606_ID_PREG, PM8606_ID_PREG, "preg", IORESOURCE_IO,},
95};
96
97static struct resource rtc_resources[] __devinitdata = { 159static struct resource rtc_resources[] __devinitdata = {
98 {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,}, 160 {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
99}; 161};
100 162
101static struct mfd_cell bk_devs[] = { 163static struct mfd_cell bk_devs[] __devinitdata = {
102 {"88pm860x-backlight", 0,}, 164 {
103 {"88pm860x-backlight", 1,}, 165 .name = "88pm860x-backlight",
104 {"88pm860x-backlight", 2,}, 166 .id = 0,
105}; 167 .num_resources = ARRAY_SIZE(bk0_resources),
106 168 .resources = bk0_resources,
107static struct mfd_cell led_devs[] = { 169 }, {
108 {"88pm860x-led", 0,}, 170 .name = "88pm860x-backlight",
109 {"88pm860x-led", 1,}, 171 .id = 1,
110 {"88pm860x-led", 2,}, 172 .num_resources = ARRAY_SIZE(bk1_resources),
111 {"88pm860x-led", 3,}, 173 .resources = bk1_resources,
112 {"88pm860x-led", 4,}, 174 }, {
113 {"88pm860x-led", 5,}, 175 .name = "88pm860x-backlight",
114}; 176 .id = 2,
115 177 .num_resources = ARRAY_SIZE(bk2_resources),
116static struct mfd_cell regulator_devs[] = { 178 .resources = bk2_resources,
117 {"88pm860x-regulator", 0,}, 179 },
118 {"88pm860x-regulator", 1,}, 180};
119 {"88pm860x-regulator", 2,}, 181
120 {"88pm860x-regulator", 3,}, 182static struct mfd_cell led_devs[] __devinitdata = {
121 {"88pm860x-regulator", 4,}, 183 {
122 {"88pm860x-regulator", 5,}, 184 .name = "88pm860x-led",
123 {"88pm860x-regulator", 6,}, 185 .id = 0,
124 {"88pm860x-regulator", 7,}, 186 .num_resources = ARRAY_SIZE(led0_resources),
125 {"88pm860x-regulator", 8,}, 187 .resources = led0_resources,
126 {"88pm860x-regulator", 9,}, 188 }, {
127 {"88pm860x-regulator", 10,}, 189 .name = "88pm860x-led",
128 {"88pm860x-regulator", 11,}, 190 .id = 1,
129 {"88pm860x-regulator", 12,}, 191 .num_resources = ARRAY_SIZE(led1_resources),
130 {"88pm860x-regulator", 13,}, 192 .resources = led1_resources,
131 {"88pm860x-regulator", 14,}, 193 }, {
132 {"88pm860x-regulator", 15,}, 194 .name = "88pm860x-led",
133 {"88pm860x-regulator", 16,}, 195 .id = 2,
134 {"88pm860x-regulator", 17,}, 196 .num_resources = ARRAY_SIZE(led2_resources),
197 .resources = led2_resources,
198 }, {
199 .name = "88pm860x-led",
200 .id = 3,
201 .num_resources = ARRAY_SIZE(led3_resources),
202 .resources = led3_resources,
203 }, {
204 .name = "88pm860x-led",
205 .id = 4,
206 .num_resources = ARRAY_SIZE(led4_resources),
207 .resources = led4_resources,
208 }, {
209 .name = "88pm860x-led",
210 .id = 5,
211 .num_resources = ARRAY_SIZE(led5_resources),
212 .resources = led5_resources,
213 },
214};
215
216static struct mfd_cell reg_devs[] __devinitdata = {
217 {
218 .name = "88pm860x-regulator",
219 .id = 0,
220 .num_resources = ARRAY_SIZE(buck1_resources),
221 .resources = buck1_resources,
222 }, {
223 .name = "88pm860x-regulator",
224 .id = 1,
225 .num_resources = ARRAY_SIZE(buck2_resources),
226 .resources = buck2_resources,
227 }, {
228 .name = "88pm860x-regulator",
229 .id = 2,
230 .num_resources = ARRAY_SIZE(buck3_resources),
231 .resources = buck3_resources,
232 }, {
233 .name = "88pm860x-regulator",
234 .id = 3,
235 .num_resources = ARRAY_SIZE(ldo1_resources),
236 .resources = ldo1_resources,
237 }, {
238 .name = "88pm860x-regulator",
239 .id = 4,
240 .num_resources = ARRAY_SIZE(ldo2_resources),
241 .resources = ldo2_resources,
242 }, {
243 .name = "88pm860x-regulator",
244 .id = 5,
245 .num_resources = ARRAY_SIZE(ldo3_resources),
246 .resources = ldo3_resources,
247 }, {
248 .name = "88pm860x-regulator",
249 .id = 6,
250 .num_resources = ARRAY_SIZE(ldo4_resources),
251 .resources = ldo4_resources,
252 }, {
253 .name = "88pm860x-regulator",
254 .id = 7,
255 .num_resources = ARRAY_SIZE(ldo5_resources),
256 .resources = ldo5_resources,
257 }, {
258 .name = "88pm860x-regulator",
259 .id = 8,
260 .num_resources = ARRAY_SIZE(ldo6_resources),
261 .resources = ldo6_resources,
262 }, {
263 .name = "88pm860x-regulator",
264 .id = 9,
265 .num_resources = ARRAY_SIZE(ldo7_resources),
266 .resources = ldo7_resources,
267 }, {
268 .name = "88pm860x-regulator",
269 .id = 10,
270 .num_resources = ARRAY_SIZE(ldo8_resources),
271 .resources = ldo8_resources,
272 }, {
273 .name = "88pm860x-regulator",
274 .id = 11,
275 .num_resources = ARRAY_SIZE(ldo9_resources),
276 .resources = ldo9_resources,
277 }, {
278 .name = "88pm860x-regulator",
279 .id = 12,
280 .num_resources = ARRAY_SIZE(ldo10_resources),
281 .resources = ldo10_resources,
282 }, {
283 .name = "88pm860x-regulator",
284 .id = 13,
285 .num_resources = ARRAY_SIZE(ldo12_resources),
286 .resources = ldo12_resources,
287 }, {
288 .name = "88pm860x-regulator",
289 .id = 14,
290 .num_resources = ARRAY_SIZE(ldo_vibrator_resources),
291 .resources = ldo_vibrator_resources,
292 }, {
293 .name = "88pm860x-regulator",
294 .id = 15,
295 .num_resources = ARRAY_SIZE(ldo14_resources),
296 .resources = ldo14_resources,
297 },
135}; 298};
136 299
137static struct mfd_cell touch_devs[] = { 300static struct mfd_cell touch_devs[] = {
@@ -360,15 +523,12 @@ static void pm860x_irq_sync_unlock(struct irq_data *data)
360 523
361static void pm860x_irq_enable(struct irq_data *data) 524static void pm860x_irq_enable(struct irq_data *data)
362{ 525{
363 struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); 526 pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
364 pm860x_irqs[data->irq - chip->irq_base].enable
365 = pm860x_irqs[data->irq - chip->irq_base].offs;
366} 527}
367 528
368static void pm860x_irq_disable(struct irq_data *data) 529static void pm860x_irq_disable(struct irq_data *data)
369{ 530{
370 struct pm860x_chip *chip = irq_data_get_irq_chip_data(data); 531 pm860x_irqs[data->hwirq].enable = 0;
371 pm860x_irqs[data->irq - chip->irq_base].enable = 0;
372} 532}
373 533
374static struct irq_chip pm860x_irq_chip = { 534static struct irq_chip pm860x_irq_chip = {
@@ -379,53 +539,25 @@ static struct irq_chip pm860x_irq_chip = {
379 .irq_disable = pm860x_irq_disable, 539 .irq_disable = pm860x_irq_disable,
380}; 540};
381 541
382static int __devinit device_gpadc_init(struct pm860x_chip *chip, 542static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
383 struct pm860x_platform_data *pdata) 543 irq_hw_number_t hw)
384{ 544{
385 struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ 545 irq_set_chip_data(virq, d->host_data);
386 : chip->companion; 546 irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
387 int data; 547 irq_set_nested_thread(virq, 1);
388 int ret; 548#ifdef CONFIG_ARM
389 549 set_irq_flags(virq, IRQF_VALID);
390 /* initialize GPADC without activating it */ 550#else
391 551 irq_set_noprobe(virq);
392 if (!pdata || !pdata->touch) 552#endif
393 return -EINVAL; 553 return 0;
394
395 /* set GPADC MISC1 register */
396 data = 0;
397 data |= (pdata->touch->gpadc_prebias << 1) & PM8607_GPADC_PREBIAS_MASK;
398 data |= (pdata->touch->slot_cycle << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
399 data |= (pdata->touch->off_scale << 5) & PM8607_GPADC_OFF_SCALE_MASK;
400 data |= (pdata->touch->sw_cal << 7) & PM8607_GPADC_SW_CAL_MASK;
401 if (data) {
402 ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
403 if (ret < 0)
404 goto out;
405 }
406 /* set tsi prebias time */
407 if (pdata->touch->tsi_prebias) {
408 data = pdata->touch->tsi_prebias;
409 ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
410 if (ret < 0)
411 goto out;
412 }
413 /* set prebias & prechg time of pen detect */
414 data = 0;
415 data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
416 data |= (pdata->touch->pen_prechg << 5) & PM8607_PD_PRECHG_MASK;
417 if (data) {
418 ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
419 if (ret < 0)
420 goto out;
421 }
422
423 ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
424 PM8607_GPADC_EN, PM8607_GPADC_EN);
425out:
426 return ret;
427} 554}
428 555
556static struct irq_domain_ops pm860x_irq_domain_ops = {
557 .map = pm860x_irq_domain_map,
558 .xlate = irq_domain_xlate_onetwocell,
559};
560
429static int __devinit device_irq_init(struct pm860x_chip *chip, 561static int __devinit device_irq_init(struct pm860x_chip *chip,
430 struct pm860x_platform_data *pdata) 562 struct pm860x_platform_data *pdata)
431{ 563{
@@ -433,13 +565,9 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
433 : chip->companion; 565 : chip->companion;
434 unsigned char status_buf[INT_STATUS_NUM]; 566 unsigned char status_buf[INT_STATUS_NUM];
435 unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; 567 unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
436 int i, data, mask, ret = -EINVAL; 568 int data, mask, ret = -EINVAL;
437 int __irq; 569 int nr_irqs, irq_base = -1;
438 570 struct device_node *node = i2c->dev.of_node;
439 if (!pdata || !pdata->irq_base) {
440 dev_warn(chip->dev, "No interrupt support on IRQ base\n");
441 return -EINVAL;
442 }
443 571
444 mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR 572 mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
445 | PM8607_B0_MISC1_INT_MASK; 573 | PM8607_B0_MISC1_INT_MASK;
@@ -479,26 +607,24 @@ static int __devinit device_irq_init(struct pm860x_chip *chip,
479 goto out; 607 goto out;
480 608
481 mutex_init(&chip->irq_lock); 609 mutex_init(&chip->irq_lock);
482 chip->irq_base = pdata->irq_base; 610
611 if (pdata && pdata->irq_base)
612 irq_base = pdata->irq_base;
613 nr_irqs = ARRAY_SIZE(pm860x_irqs);
614 chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
615 if (chip->irq_base < 0) {
616 dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
617 chip->irq_base);
618 ret = -EBUSY;
619 goto out;
620 }
621 irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
622 &pm860x_irq_domain_ops, chip);
483 chip->core_irq = i2c->irq; 623 chip->core_irq = i2c->irq;
484 if (!chip->core_irq) 624 if (!chip->core_irq)
485 goto out; 625 goto out;
486 626
487 /* register IRQ by genirq */ 627 ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
488 for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
489 __irq = i + chip->irq_base;
490 irq_set_chip_data(__irq, chip);
491 irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
492 handle_edge_irq);
493 irq_set_nested_thread(__irq, 1);
494#ifdef CONFIG_ARM
495 set_irq_flags(__irq, IRQF_VALID);
496#else
497 irq_set_noprobe(__irq);
498#endif
499 }
500
501 ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
502 "88pm860x", chip); 628 "88pm860x", chip);
503 if (ret) { 629 if (ret) {
504 dev_err(chip->dev, "Failed to request IRQ: %d\n", ret); 630 dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
@@ -615,108 +741,122 @@ static void __devinit device_osc_init(struct i2c_client *i2c)
615static void __devinit device_bk_init(struct pm860x_chip *chip, 741static void __devinit device_bk_init(struct pm860x_chip *chip,
616 struct pm860x_platform_data *pdata) 742 struct pm860x_platform_data *pdata)
617{ 743{
618 int ret; 744 int ret, i;
619 int i, j, id; 745
620 746 if (pdata && pdata->backlight) {
621 if ((pdata == NULL) || (pdata->backlight == NULL)) 747 if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
622 return; 748 pdata->num_backlights = ARRAY_SIZE(bk_devs);
623 749 for (i = 0; i < pdata->num_backlights; i++) {
624 if (pdata->num_backlights > ARRAY_SIZE(bk_devs)) 750 bk_devs[i].platform_data = &pdata->backlight[i];
625 pdata->num_backlights = ARRAY_SIZE(bk_devs); 751 bk_devs[i].pdata_size =
626 752 sizeof(struct pm860x_backlight_pdata);
627 for (i = 0; i < pdata->num_backlights; i++) {
628 bk_devs[i].platform_data = &pdata->backlight[i];
629 bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
630
631 for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
632 id = bk_resources[j].start;
633 if (pdata->backlight[i].flags != id)
634 continue;
635
636 bk_devs[i].num_resources = 1;
637 bk_devs[i].resources = &bk_resources[j];
638 ret = mfd_add_devices(chip->dev, 0,
639 &bk_devs[i], 1,
640 &bk_resources[j], 0, NULL);
641 if (ret < 0) {
642 dev_err(chip->dev, "Failed to add "
643 "backlight subdev\n");
644 return;
645 }
646 } 753 }
647 } 754 }
755 ret = mfd_add_devices(chip->dev, 0, bk_devs,
756 ARRAY_SIZE(bk_devs), NULL, 0, NULL);
757 if (ret < 0)
758 dev_err(chip->dev, "Failed to add backlight subdev\n");
648} 759}
649 760
650static void __devinit device_led_init(struct pm860x_chip *chip, 761static void __devinit device_led_init(struct pm860x_chip *chip,
651 struct pm860x_platform_data *pdata) 762 struct pm860x_platform_data *pdata)
652{ 763{
653 int ret; 764 int ret, i;
654 int i, j, id; 765
655 766 if (pdata && pdata->led) {
656 if ((pdata == NULL) || (pdata->led == NULL)) 767 if (pdata->num_leds > ARRAY_SIZE(led_devs))
657 return; 768 pdata->num_leds = ARRAY_SIZE(led_devs);
658 769 for (i = 0; i < pdata->num_leds; i++) {
659 if (pdata->num_leds > ARRAY_SIZE(led_devs)) 770 led_devs[i].platform_data = &pdata->led[i];
660 pdata->num_leds = ARRAY_SIZE(led_devs); 771 led_devs[i].pdata_size =
661 772 sizeof(struct pm860x_led_pdata);
662 for (i = 0; i < pdata->num_leds; i++) {
663 led_devs[i].platform_data = &pdata->led[i];
664 led_devs[i].pdata_size = sizeof(struct pm860x_led_pdata);
665
666 for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
667 id = led_resources[j].start;
668 if (pdata->led[i].flags != id)
669 continue;
670
671 led_devs[i].num_resources = 1;
672 led_devs[i].resources = &led_resources[j],
673 ret = mfd_add_devices(chip->dev, 0,
674 &led_devs[i], 1,
675 &led_resources[j], 0, NULL);
676 if (ret < 0) {
677 dev_err(chip->dev, "Failed to add "
678 "led subdev\n");
679 return;
680 }
681 } 773 }
682 } 774 }
775 ret = mfd_add_devices(chip->dev, 0, led_devs,
776 ARRAY_SIZE(led_devs), NULL, 0, NULL);
777 if (ret < 0) {
778 dev_err(chip->dev, "Failed to add led subdev\n");
779 return;
780 }
683} 781}
684 782
685static void __devinit device_regulator_init(struct pm860x_chip *chip, 783static void __devinit device_regulator_init(struct pm860x_chip *chip,
686 struct pm860x_platform_data *pdata) 784 struct pm860x_platform_data *pdata)
687{ 785{
688 struct regulator_init_data *initdata;
689 int ret; 786 int ret;
690 int i, seq;
691 787
692 if ((pdata == NULL) || (pdata->regulator == NULL)) 788 if (pdata == NULL)
789 return;
790 if (pdata->buck1) {
791 reg_devs[0].platform_data = pdata->buck1;
792 reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
793 }
794 if (pdata->buck2) {
795 reg_devs[1].platform_data = pdata->buck2;
796 reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
797 }
798 if (pdata->buck3) {
799 reg_devs[2].platform_data = pdata->buck3;
800 reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
801 }
802 if (pdata->ldo1) {
803 reg_devs[3].platform_data = pdata->ldo1;
804 reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
805 }
806 if (pdata->ldo2) {
807 reg_devs[4].platform_data = pdata->ldo2;
808 reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
809 }
810 if (pdata->ldo3) {
811 reg_devs[5].platform_data = pdata->ldo3;
812 reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
813 }
814 if (pdata->ldo4) {
815 reg_devs[6].platform_data = pdata->ldo4;
816 reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
817 }
818 if (pdata->ldo5) {
819 reg_devs[7].platform_data = pdata->ldo5;
820 reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
821 }
822 if (pdata->ldo6) {
823 reg_devs[8].platform_data = pdata->ldo6;
824 reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
825 }
826 if (pdata->ldo7) {
827 reg_devs[9].platform_data = pdata->ldo7;
828 reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
829 }
830 if (pdata->ldo8) {
831 reg_devs[10].platform_data = pdata->ldo8;
832 reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
833 }
834 if (pdata->ldo9) {
835 reg_devs[11].platform_data = pdata->ldo9;
836 reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
837 }
838 if (pdata->ldo10) {
839 reg_devs[12].platform_data = pdata->ldo10;
840 reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
841 }
842 if (pdata->ldo12) {
843 reg_devs[13].platform_data = pdata->ldo12;
844 reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
845 }
846 if (pdata->ldo_vibrator) {
847 reg_devs[14].platform_data = pdata->ldo_vibrator;
848 reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
849 }
850 if (pdata->ldo14) {
851 reg_devs[15].platform_data = pdata->ldo14;
852 reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
853 }
854 ret = mfd_add_devices(chip->dev, 0, reg_devs,
855 ARRAY_SIZE(reg_devs), NULL, 0, NULL);
856 if (ret < 0) {
857 dev_err(chip->dev, "Failed to add regulator subdev\n");
693 return; 858 return;
694
695 if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
696 pdata->num_regulators = ARRAY_SIZE(regulator_devs);
697
698 for (i = 0, seq = -1; i < pdata->num_regulators; i++) {
699 initdata = &pdata->regulator[i];
700 seq = *(unsigned int *)initdata->driver_data;
701 if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) {
702 dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n",
703 seq, initdata->constraints.name);
704 goto out;
705 }
706 regulator_devs[i].platform_data = &pdata->regulator[i];
707 regulator_devs[i].pdata_size = sizeof(struct regulator_init_data);
708 regulator_devs[i].num_resources = 1;
709 regulator_devs[i].resources = &regulator_resources[seq];
710
711 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
712 &regulator_resources[seq], 0, NULL);
713 if (ret < 0) {
714 dev_err(chip->dev, "Failed to add regulator subdev\n");
715 goto out;
716 }
717 } 859 }
718out:
719 return;
720} 860}
721 861
722static void __devinit device_rtc_init(struct pm860x_chip *chip, 862static void __devinit device_rtc_init(struct pm860x_chip *chip,
@@ -785,10 +925,8 @@ static void __devinit device_power_init(struct pm860x_chip *chip,
785 925
786 power_devs[2].platform_data = &preg_init_data; 926 power_devs[2].platform_data = &preg_init_data;
787 power_devs[2].pdata_size = sizeof(struct regulator_init_data); 927 power_devs[2].pdata_size = sizeof(struct regulator_init_data);
788 power_devs[2].num_resources = ARRAY_SIZE(preg_resources);
789 power_devs[2].resources = &preg_resources[0],
790 ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, 928 ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1,
791 &preg_resources[0], chip->irq_base, NULL); 929 NULL, chip->irq_base, NULL);
792 if (ret < 0) 930 if (ret < 0)
793 dev_err(chip->dev, "Failed to add preg subdev\n"); 931 dev_err(chip->dev, "Failed to add preg subdev\n");
794} 932}
@@ -868,10 +1006,6 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
868 goto out; 1006 goto out;
869 } 1007 }
870 1008
871 ret = device_gpadc_init(chip, pdata);
872 if (ret < 0)
873 goto out;
874
875 ret = device_irq_init(chip, pdata); 1009 ret = device_irq_init(chip, pdata);
876 if (ret < 0) 1010 if (ret < 0)
877 goto out; 1011 goto out;
@@ -895,8 +1029,8 @@ static void __devinit device_8606_init(struct pm860x_chip *chip,
895 device_led_init(chip, pdata); 1029 device_led_init(chip, pdata);
896} 1030}
897 1031
898int __devinit pm860x_device_init(struct pm860x_chip *chip, 1032static int __devinit pm860x_device_init(struct pm860x_chip *chip,
899 struct pm860x_platform_data *pdata) 1033 struct pm860x_platform_data *pdata)
900{ 1034{
901 chip->core_irq = 0; 1035 chip->core_irq = 0;
902 1036
@@ -923,12 +1057,207 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
923 return 0; 1057 return 0;
924} 1058}
925 1059
926void __devexit pm860x_device_exit(struct pm860x_chip *chip) 1060static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
927{ 1061{
928 device_irq_exit(chip); 1062 device_irq_exit(chip);
929 mfd_remove_devices(chip->dev); 1063 mfd_remove_devices(chip->dev);
930} 1064}
931 1065
1066static int verify_addr(struct i2c_client *i2c)
1067{
1068 unsigned short addr_8607[] = {0x30, 0x34};
1069 unsigned short addr_8606[] = {0x10, 0x11};
1070 int size, i;
1071
1072 if (i2c == NULL)
1073 return 0;
1074 size = ARRAY_SIZE(addr_8606);
1075 for (i = 0; i < size; i++) {
1076 if (i2c->addr == *(addr_8606 + i))
1077 return CHIP_PM8606;
1078 }
1079 size = ARRAY_SIZE(addr_8607);
1080 for (i = 0; i < size; i++) {
1081 if (i2c->addr == *(addr_8607 + i))
1082 return CHIP_PM8607;
1083 }
1084 return 0;
1085}
1086
1087static struct regmap_config pm860x_regmap_config = {
1088 .reg_bits = 8,
1089 .val_bits = 8,
1090};
1091
1092static int __devinit pm860x_dt_init(struct device_node *np,
1093 struct device *dev,
1094 struct pm860x_platform_data *pdata)
1095{
1096 int ret;
1097
1098 if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
1099 pdata->irq_mode = 1;
1100 ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
1101 &pdata->companion_addr);
1102 if (ret) {
1103 dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
1104 "property\n");
1105 pdata->companion_addr = 0;
1106 }
1107 return 0;
1108}
1109
1110static int __devinit pm860x_probe(struct i2c_client *client,
1111 const struct i2c_device_id *id)
1112{
1113 struct pm860x_platform_data *pdata = client->dev.platform_data;
1114 struct device_node *node = client->dev.of_node;
1115 struct pm860x_chip *chip;
1116 int ret;
1117
1118 if (node && !pdata) {
1119 /* parse DT to get platform data */
1120 pdata = devm_kzalloc(&client->dev,
1121 sizeof(struct pm860x_platform_data),
1122 GFP_KERNEL);
1123 if (!pdata)
1124 return -ENOMEM;
1125 ret = pm860x_dt_init(node, &client->dev, pdata);
1126 if (ret)
1127 goto err;
1128 } else if (!pdata) {
1129 pr_info("No platform data in %s!\n", __func__);
1130 return -EINVAL;
1131 }
1132
1133 chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
1134 if (chip == NULL) {
1135 ret = -ENOMEM;
1136 goto err;
1137 }
1138
1139 chip->id = verify_addr(client);
1140 chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
1141 if (IS_ERR(chip->regmap)) {
1142 ret = PTR_ERR(chip->regmap);
1143 dev_err(&client->dev, "Failed to allocate register map: %d\n",
1144 ret);
1145 kfree(chip);
1146 return ret;
1147 }
1148 chip->client = client;
1149 i2c_set_clientdata(client, chip);
1150 chip->dev = &client->dev;
1151 dev_set_drvdata(chip->dev, chip);
1152
1153 /*
1154 * Both client and companion client shares same platform driver.
1155 * Driver distinguishes them by pdata->companion_addr.
1156 * pdata->companion_addr is only assigned if companion chip exists.
1157 * At the same time, the companion_addr shouldn't equal to client
1158 * address.
1159 */
1160 if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
1161 chip->companion_addr = pdata->companion_addr;
1162 chip->companion = i2c_new_dummy(chip->client->adapter,
1163 chip->companion_addr);
1164 chip->regmap_companion = regmap_init_i2c(chip->companion,
1165 &pm860x_regmap_config);
1166 if (IS_ERR(chip->regmap_companion)) {
1167 ret = PTR_ERR(chip->regmap_companion);
1168 dev_err(&chip->companion->dev,
1169 "Failed to allocate register map: %d\n", ret);
1170 return ret;
1171 }
1172 i2c_set_clientdata(chip->companion, chip);
1173 }
1174
1175 pm860x_device_init(chip, pdata);
1176 return 0;
1177err:
1178 if (node)
1179 devm_kfree(&client->dev, pdata);
1180 return ret;
1181}
1182
1183static int __devexit pm860x_remove(struct i2c_client *client)
1184{
1185 struct pm860x_chip *chip = i2c_get_clientdata(client);
1186
1187 pm860x_device_exit(chip);
1188 if (chip->companion) {
1189 regmap_exit(chip->regmap_companion);
1190 i2c_unregister_device(chip->companion);
1191 }
1192 regmap_exit(chip->regmap);
1193 kfree(chip);
1194 return 0;
1195}
1196
1197#ifdef CONFIG_PM_SLEEP
1198static int pm860x_suspend(struct device *dev)
1199{
1200 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1201 struct pm860x_chip *chip = i2c_get_clientdata(client);
1202
1203 if (device_may_wakeup(dev) && chip->wakeup_flag)
1204 enable_irq_wake(chip->core_irq);
1205 return 0;
1206}
1207
1208static int pm860x_resume(struct device *dev)
1209{
1210 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
1211 struct pm860x_chip *chip = i2c_get_clientdata(client);
1212
1213 if (device_may_wakeup(dev) && chip->wakeup_flag)
1214 disable_irq_wake(chip->core_irq);
1215 return 0;
1216}
1217#endif
1218
1219static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
1220
1221static const struct i2c_device_id pm860x_id_table[] = {
1222 { "88PM860x", 0 },
1223 {}
1224};
1225MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
1226
1227static const struct of_device_id pm860x_dt_ids[] = {
1228 { .compatible = "marvell,88pm860x", },
1229 {},
1230};
1231MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
1232
1233static struct i2c_driver pm860x_driver = {
1234 .driver = {
1235 .name = "88PM860x",
1236 .owner = THIS_MODULE,
1237 .pm = &pm860x_pm_ops,
1238 .of_match_table = of_match_ptr(pm860x_dt_ids),
1239 },
1240 .probe = pm860x_probe,
1241 .remove = __devexit_p(pm860x_remove),
1242 .id_table = pm860x_id_table,
1243};
1244
1245static int __init pm860x_i2c_init(void)
1246{
1247 int ret;
1248 ret = i2c_add_driver(&pm860x_driver);
1249 if (ret != 0)
1250 pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
1251 return ret;
1252}
1253subsys_initcall(pm860x_i2c_init);
1254
1255static void __exit pm860x_i2c_exit(void)
1256{
1257 i2c_del_driver(&pm860x_driver);
1258}
1259module_exit(pm860x_i2c_exit);
1260
932MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x"); 1261MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
933MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 1262MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
934MODULE_LICENSE("GPL"); 1263MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index b2cfdc458561..ff8f803ce833 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -10,12 +10,9 @@
10 */ 10 */
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/platform_device.h>
14#include <linux/i2c.h> 13#include <linux/i2c.h>
15#include <linux/err.h>
16#include <linux/regmap.h> 14#include <linux/regmap.h>
17#include <linux/mfd/88pm860x.h> 15#include <linux/mfd/88pm860x.h>
18#include <linux/slab.h>
19 16
20int pm860x_reg_read(struct i2c_client *i2c, int reg) 17int pm860x_reg_read(struct i2c_client *i2c, int reg)
21{ 18{
@@ -91,8 +88,18 @@ static int read_device(struct i2c_client *i2c, int reg,
91 unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3]; 88 unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3];
92 unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2]; 89 unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2];
93 struct i2c_adapter *adap = i2c->adapter; 90 struct i2c_adapter *adap = i2c->adapter;
94 struct i2c_msg msg[2] = {{i2c->addr, 0, 1, msgbuf0}, 91 struct i2c_msg msg[2] = {
95 {i2c->addr, I2C_M_RD, 0, msgbuf1}, 92 {
93 .addr = i2c->addr,
94 .flags = 0,
95 .len = 1,
96 .buf = msgbuf0
97 },
98 { .addr = i2c->addr,
99 .flags = I2C_M_RD,
100 .len = 0,
101 .buf = msgbuf1
102 },
96 }; 103 };
97 int num = 1, ret = 0; 104 int num = 1, ret = 0;
98 105
@@ -231,160 +238,3 @@ out:
231 return ret; 238 return ret;
232} 239}
233EXPORT_SYMBOL(pm860x_page_set_bits); 240EXPORT_SYMBOL(pm860x_page_set_bits);
234
235static const struct i2c_device_id pm860x_id_table[] = {
236 { "88PM860x", 0 },
237 {}
238};
239MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
240
241static int verify_addr(struct i2c_client *i2c)
242{
243 unsigned short addr_8607[] = {0x30, 0x34};
244 unsigned short addr_8606[] = {0x10, 0x11};
245 int size, i;
246
247 if (i2c == NULL)
248 return 0;
249 size = ARRAY_SIZE(addr_8606);
250 for (i = 0; i < size; i++) {
251 if (i2c->addr == *(addr_8606 + i))
252 return CHIP_PM8606;
253 }
254 size = ARRAY_SIZE(addr_8607);
255 for (i = 0; i < size; i++) {
256 if (i2c->addr == *(addr_8607 + i))
257 return CHIP_PM8607;
258 }
259 return 0;
260}
261
262static struct regmap_config pm860x_regmap_config = {
263 .reg_bits = 8,
264 .val_bits = 8,
265};
266
267static int __devinit pm860x_probe(struct i2c_client *client,
268 const struct i2c_device_id *id)
269{
270 struct pm860x_platform_data *pdata = client->dev.platform_data;
271 struct pm860x_chip *chip;
272 int ret;
273
274 if (!pdata) {
275 pr_info("No platform data in %s!\n", __func__);
276 return -EINVAL;
277 }
278
279 chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
280 if (chip == NULL)
281 return -ENOMEM;
282
283 chip->id = verify_addr(client);
284 chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
285 if (IS_ERR(chip->regmap)) {
286 ret = PTR_ERR(chip->regmap);
287 dev_err(&client->dev, "Failed to allocate register map: %d\n",
288 ret);
289 kfree(chip);
290 return ret;
291 }
292 chip->client = client;
293 i2c_set_clientdata(client, chip);
294 chip->dev = &client->dev;
295 dev_set_drvdata(chip->dev, chip);
296
297 /*
298 * Both client and companion client shares same platform driver.
299 * Driver distinguishes them by pdata->companion_addr.
300 * pdata->companion_addr is only assigned if companion chip exists.
301 * At the same time, the companion_addr shouldn't equal to client
302 * address.
303 */
304 if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
305 chip->companion_addr = pdata->companion_addr;
306 chip->companion = i2c_new_dummy(chip->client->adapter,
307 chip->companion_addr);
308 chip->regmap_companion = regmap_init_i2c(chip->companion,
309 &pm860x_regmap_config);
310 if (IS_ERR(chip->regmap_companion)) {
311 ret = PTR_ERR(chip->regmap_companion);
312 dev_err(&chip->companion->dev,
313 "Failed to allocate register map: %d\n", ret);
314 return ret;
315 }
316 i2c_set_clientdata(chip->companion, chip);
317 }
318
319 pm860x_device_init(chip, pdata);
320 return 0;
321}
322
323static int __devexit pm860x_remove(struct i2c_client *client)
324{
325 struct pm860x_chip *chip = i2c_get_clientdata(client);
326
327 pm860x_device_exit(chip);
328 if (chip->companion) {
329 regmap_exit(chip->regmap_companion);
330 i2c_unregister_device(chip->companion);
331 }
332 regmap_exit(chip->regmap);
333 kfree(chip);
334 return 0;
335}
336
337#ifdef CONFIG_PM_SLEEP
338static int pm860x_suspend(struct device *dev)
339{
340 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
341 struct pm860x_chip *chip = i2c_get_clientdata(client);
342
343 if (device_may_wakeup(dev) && chip->wakeup_flag)
344 enable_irq_wake(chip->core_irq);
345 return 0;
346}
347
348static int pm860x_resume(struct device *dev)
349{
350 struct i2c_client *client = container_of(dev, struct i2c_client, dev);
351 struct pm860x_chip *chip = i2c_get_clientdata(client);
352
353 if (device_may_wakeup(dev) && chip->wakeup_flag)
354 disable_irq_wake(chip->core_irq);
355 return 0;
356}
357#endif
358
359static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
360
361static struct i2c_driver pm860x_driver = {
362 .driver = {
363 .name = "88PM860x",
364 .owner = THIS_MODULE,
365 .pm = &pm860x_pm_ops,
366 },
367 .probe = pm860x_probe,
368 .remove = __devexit_p(pm860x_remove),
369 .id_table = pm860x_id_table,
370};
371
372static int __init pm860x_i2c_init(void)
373{
374 int ret;
375 ret = i2c_add_driver(&pm860x_driver);
376 if (ret != 0)
377 pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
378 return ret;
379}
380subsys_initcall(pm860x_i2c_init);
381
382static void __exit pm860x_i2c_exit(void)
383{
384 i2c_del_driver(&pm860x_driver);
385}
386module_exit(pm860x_i2c_exit);
387
388MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
389MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
390MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b1a146205c08..acab3ef8a310 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -298,16 +298,6 @@ config MFD_TWL4030_AUDIO
298 select MFD_CORE 298 select MFD_CORE
299 default n 299 default n
300 300
301config TWL6030_PWM
302 tristate "TWL6030 PWM (Pulse Width Modulator) Support"
303 depends on TWL4030_CORE
304 select HAVE_PWM
305 depends on !PWM
306 default n
307 help
308 Say yes here if you want support for TWL6030 PWM.
309 This is used to control charging LED brightness.
310
311config TWL6040_CORE 301config TWL6040_CORE
312 bool "Support for TWL6040 audio codec" 302 bool "Support for TWL6040 audio codec"
313 depends on I2C=y && GENERIC_HARDIRQS 303 depends on I2C=y && GENERIC_HARDIRQS
@@ -385,6 +375,18 @@ config MFD_T7L66XB
385 help 375 help
386 Support for Toshiba Mobile IO Controller T7L66XB 376 Support for Toshiba Mobile IO Controller T7L66XB
387 377
378config MFD_SMSC
379 bool "Support for the SMSC ECE1099 series chips"
380 depends on I2C=y
381 select MFD_CORE
382 select REGMAP_I2C
383 help
384 If you say yes here you get support for the
385 ece1099 chips from SMSC.
386
387 To compile this driver as a module, choose M here: the
388 module will be called smsc.
389
388config MFD_TC6387XB 390config MFD_TC6387XB
389 bool "Support Toshiba TC6387XB" 391 bool "Support Toshiba TC6387XB"
390 depends on ARM && HAVE_CLK 392 depends on ARM && HAVE_CLK
@@ -441,6 +443,23 @@ config MFD_DA9052_I2C
441 for accessing the device, additional drivers must be enabled in 443 for accessing the device, additional drivers must be enabled in
442 order to use the functionality of the device. 444 order to use the functionality of the device.
443 445
446config MFD_DA9055
447 bool "Dialog Semiconductor DA9055 PMIC Support"
448 select REGMAP_I2C
449 select REGMAP_IRQ
450 select PMIC_DA9055
451 select MFD_CORE
452 depends on I2C=y
453 help
454 Say yes here for support of Dialog Semiconductor DA9055. This is
455 a Power Management IC. This driver provides common support for
456 accessing the device as well as the I2C interface to the chip itself.
457 Additional drivers must be enabled in order to use the functionality
458 of the device.
459
460 This driver can be built as a module. If built as a module it will be
461 called "da9055"
462
444config PMIC_ADP5520 463config PMIC_ADP5520
445 bool "Analog Devices ADP5520/01 MFD PMIC Core Support" 464 bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
446 depends on I2C=y 465 depends on I2C=y
@@ -451,6 +470,16 @@ config PMIC_ADP5520
451 individual components like LCD backlight, LEDs, GPIOs and Kepad 470 individual components like LCD backlight, LEDs, GPIOs and Kepad
452 under the corresponding menus. 471 under the corresponding menus.
453 472
473config MFD_LP8788
474 bool "Texas Instruments LP8788 Power Management Unit Driver"
475 depends on I2C=y
476 select MFD_CORE
477 select REGMAP_I2C
478 select IRQ_DOMAIN
479 help
480 TI LP8788 PMU supports regulators, battery charger, RTC,
481 ADC, backlight driver and current sinks.
482
454config MFD_MAX77686 483config MFD_MAX77686
455 bool "Maxim Semiconductor MAX77686 PMIC Support" 484 bool "Maxim Semiconductor MAX77686 PMIC Support"
456 depends on I2C=y && GENERIC_HARDIRQS 485 depends on I2C=y && GENERIC_HARDIRQS
@@ -477,6 +506,18 @@ config MFD_MAX77693
477 additional drivers must be enabled in order to use the functionality 506 additional drivers must be enabled in order to use the functionality
478 of the device. 507 of the device.
479 508
509config MFD_MAX8907
510 tristate "Maxim Semiconductor MAX8907 PMIC Support"
511 select MFD_CORE
512 depends on I2C=y && GENERIC_HARDIRQS
513 select REGMAP_I2C
514 select REGMAP_IRQ
515 help
516 Say yes here to support for Maxim Semiconductor MAX8907. This is
517 a Power Management IC. This driver provides common support for
518 accessing the device; additional drivers must be enabled in order
519 to use the functionality of the device.
520
480config MFD_MAX8925 521config MFD_MAX8925
481 bool "Maxim Semiconductor MAX8925 PMIC Support" 522 bool "Maxim Semiconductor MAX8925 PMIC Support"
482 depends on I2C=y && GENERIC_HARDIRQS 523 depends on I2C=y && GENERIC_HARDIRQS
@@ -896,7 +937,7 @@ config MFD_WL1273_CORE
896 audio codec. 937 audio codec.
897 938
898config MFD_OMAP_USB_HOST 939config MFD_OMAP_USB_HOST
899 bool "Support OMAP USBHS core driver" 940 bool "Support OMAP USBHS core and TLL driver"
900 depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3 941 depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
901 default y 942 default y
902 help 943 help
@@ -985,13 +1026,13 @@ config MFD_STA2X11
985 depends on STA2X11 1026 depends on STA2X11
986 select MFD_CORE 1027 select MFD_CORE
987 1028
988config MFD_ANATOP 1029config MFD_SYSCON
989 bool "Support for Freescale i.MX on-chip ANATOP controller" 1030 bool "System Controller Register R/W Based on Regmap"
990 depends on SOC_IMX6Q 1031 depends on OF
1032 select REGMAP_MMIO
991 help 1033 help
992 Select this option to enable Freescale i.MX on-chip ANATOP 1034 Select this option to enable accessing system control registers
993 MFD controller. This controller embeds regulator and 1035 via regmap.
994 thermal devices for Freescale i.MX platforms.
995 1036
996config MFD_PALMAS 1037config MFD_PALMAS
997 bool "Support for the TI Palmas series chips" 1038 bool "Support for the TI Palmas series chips"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 79dd22d1dc3d..d8ccb630ddb0 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -63,7 +63,6 @@ obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
63obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o 63obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
64obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o 64obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
65obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o 65obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o
66obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
67obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o 66obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o
68 67
69obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o 68obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
@@ -77,6 +76,7 @@ obj-$(CONFIG_EZX_PCAP) += ezx-pcap.o
77obj-$(CONFIG_MCP) += mcp-core.o 76obj-$(CONFIG_MCP) += mcp-core.o
78obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o 77obj-$(CONFIG_MCP_SA11X0) += mcp-sa11x0.o
79obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o 78obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
79obj-$(CONFIG_MFD_SMSC) += smsc-ece1099.o
80obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o 80obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
81 81
82ifeq ($(CONFIG_SA1100_ASSABET),y) 82ifeq ($(CONFIG_SA1100_ASSABET),y)
@@ -90,8 +90,14 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
90obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o 90obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
91obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o 91obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
92 92
93obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o
94
95da9055-objs := da9055-core.o da9055-i2c.o
96obj-$(CONFIG_MFD_DA9055) += da9055.o
97
93obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o 98obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
94obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o 99obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o
100obj-$(CONFIG_MFD_MAX8907) += max8907.o
95max8925-objs := max8925-core.o max8925-i2c.o 101max8925-objs := max8925-core.o max8925-i2c.o
96obj-$(CONFIG_MFD_MAX8925) += max8925.o 102obj-$(CONFIG_MFD_MAX8925) += max8925.o
97obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o 103obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
@@ -120,7 +126,7 @@ obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
120obj-$(CONFIG_MFD_VX855) += vx855.o 126obj-$(CONFIG_MFD_VX855) += vx855.o
121obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o 127obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
122obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o 128obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
123obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o 129obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
124obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o 130obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
125obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o 131obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
126obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o 132obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
@@ -130,5 +136,5 @@ obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
130obj-$(CONFIG_MFD_PALMAS) += palmas.o 136obj-$(CONFIG_MFD_PALMAS) += palmas.o
131obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o 137obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o
132obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o 138obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o
133obj-$(CONFIG_MFD_ANATOP) += anatop-mfd.o 139obj-$(CONFIG_MFD_SYSCON) += syscon.o
134obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o 140obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 01781ae5d0d7..2b3dde571a50 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -21,6 +21,7 @@
21#include <linux/seq_file.h> 21#include <linux/seq_file.h>
22#include <linux/uaccess.h> 22#include <linux/uaccess.h>
23#include <linux/mfd/core.h> 23#include <linux/mfd/core.h>
24#include <linux/mfd/ab3100.h>
24#include <linux/mfd/abx500.h> 25#include <linux/mfd/abx500.h>
25 26
26/* These are the only registers inside AB3100 used in this main file */ 27/* These are the only registers inside AB3100 used in this main file */
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 47adf800024e..1667c77b5cde 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -472,6 +472,22 @@ static irqreturn_t ab8500_hierarchical_irq(int irq, void *dev)
472 return IRQ_HANDLED; 472 return IRQ_HANDLED;
473} 473}
474 474
475/**
476 * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
477 *
478 * @ab8500: ab8500_irq controller to operate on.
479 * @irq: index of the interrupt requested in the chip IRQs
480 *
481 * Useful for drivers to request their own IRQs.
482 */
483static int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
484{
485 if (!ab8500)
486 return -EINVAL;
487
488 return irq_create_mapping(ab8500->domain, irq);
489}
490
475static irqreturn_t ab8500_irq(int irq, void *dev) 491static irqreturn_t ab8500_irq(int irq, void *dev)
476{ 492{
477 struct ab8500 *ab8500 = dev; 493 struct ab8500 *ab8500 = dev;
@@ -501,8 +517,9 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
501 do { 517 do {
502 int bit = __ffs(value); 518 int bit = __ffs(value);
503 int line = i * 8 + bit; 519 int line = i * 8 + bit;
520 int virq = ab8500_irq_get_virq(ab8500, line);
504 521
505 handle_nested_irq(ab8500->irq_base + line); 522 handle_nested_irq(virq);
506 value &= ~(1 << bit); 523 value &= ~(1 << bit);
507 524
508 } while (value); 525 } while (value);
@@ -511,23 +528,6 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
511 return IRQ_HANDLED; 528 return IRQ_HANDLED;
512} 529}
513 530
514/**
515 * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
516 *
517 * @ab8500: ab8500_irq controller to operate on.
518 * @irq: index of the interrupt requested in the chip IRQs
519 *
520 * Useful for drivers to request their own IRQs.
521 */
522int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
523{
524 if (!ab8500)
525 return -EINVAL;
526
527 return irq_create_mapping(ab8500->domain, irq);
528}
529EXPORT_SYMBOL_GPL(ab8500_irq_get_virq);
530
531static int ab8500_irq_map(struct irq_domain *d, unsigned int virq, 531static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
532 irq_hw_number_t hwirq) 532 irq_hw_number_t hwirq)
533{ 533{
@@ -1076,6 +1076,7 @@ static struct mfd_cell __devinitdata ab8500_devs[] = {
1076 }, 1076 },
1077 { 1077 {
1078 .name = "ab8500-codec", 1078 .name = "ab8500-codec",
1079 .of_compatible = "stericsson,ab8500-codec",
1079 }, 1080 },
1080}; 1081};
1081 1082
diff --git a/drivers/mfd/anatop-mfd.c b/drivers/mfd/anatop-mfd.c
deleted file mode 100644
index 5576e07576de..000000000000
--- a/drivers/mfd/anatop-mfd.c
+++ /dev/null
@@ -1,124 +0,0 @@
1/*
2 * Anatop MFD driver
3 *
4 * Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
5 * Copyright (C) 2012 Linaro
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
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. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 *
34 */
35
36#include <linux/io.h>
37#include <linux/module.h>
38#include <linux/platform_device.h>
39#include <linux/of.h>
40#include <linux/of_platform.h>
41#include <linux/of_address.h>
42#include <linux/mfd/anatop.h>
43
44u32 anatop_read_reg(struct anatop *adata, u32 addr)
45{
46 return readl(adata->ioreg + addr);
47}
48EXPORT_SYMBOL_GPL(anatop_read_reg);
49
50void anatop_write_reg(struct anatop *adata, u32 addr, u32 data, u32 mask)
51{
52 u32 val;
53
54 data &= mask;
55
56 spin_lock(&adata->reglock);
57 val = readl(adata->ioreg + addr);
58 val &= ~mask;
59 val |= data;
60 writel(val, adata->ioreg + addr);
61 spin_unlock(&adata->reglock);
62}
63EXPORT_SYMBOL_GPL(anatop_write_reg);
64
65static const struct of_device_id of_anatop_match[] = {
66 { .compatible = "fsl,imx6q-anatop", },
67 { },
68};
69
70static int __devinit of_anatop_probe(struct platform_device *pdev)
71{
72 struct device *dev = &pdev->dev;
73 struct device_node *np = dev->of_node;
74 void *ioreg;
75 struct anatop *drvdata;
76
77 ioreg = of_iomap(np, 0);
78 if (!ioreg)
79 return -EADDRNOTAVAIL;
80 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
81 if (!drvdata)
82 return -ENOMEM;
83 drvdata->ioreg = ioreg;
84 spin_lock_init(&drvdata->reglock);
85 platform_set_drvdata(pdev, drvdata);
86 of_platform_populate(np, NULL, NULL, dev);
87
88 return 0;
89}
90
91static int __devexit of_anatop_remove(struct platform_device *pdev)
92{
93 struct anatop *drvdata;
94 drvdata = platform_get_drvdata(pdev);
95 iounmap(drvdata->ioreg);
96
97 return 0;
98}
99
100static struct platform_driver anatop_of_driver = {
101 .driver = {
102 .name = "anatop-mfd",
103 .owner = THIS_MODULE,
104 .of_match_table = of_anatop_match,
105 },
106 .probe = of_anatop_probe,
107 .remove = of_anatop_remove,
108};
109
110static int __init anatop_init(void)
111{
112 return platform_driver_register(&anatop_of_driver);
113}
114postcore_initcall(anatop_init);
115
116static void __exit anatop_exit(void)
117{
118 platform_driver_unregister(&anatop_of_driver);
119}
120module_exit(anatop_exit);
121
122MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
123MODULE_DESCRIPTION("ANATOP MFD driver");
124MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 98ac345f468e..ef0f2d001df2 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -94,7 +94,8 @@ static irqreturn_t arizona_ctrlif_err(int irq, void *data)
94static irqreturn_t arizona_irq_thread(int irq, void *data) 94static irqreturn_t arizona_irq_thread(int irq, void *data)
95{ 95{
96 struct arizona *arizona = data; 96 struct arizona *arizona = data;
97 int i, ret; 97 unsigned int val;
98 int ret;
98 99
99 ret = pm_runtime_get_sync(arizona->dev); 100 ret = pm_runtime_get_sync(arizona->dev);
100 if (ret < 0) { 101 if (ret < 0) {
@@ -102,9 +103,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
102 return IRQ_NONE; 103 return IRQ_NONE;
103 } 104 }
104 105
105 /* Check both domains */ 106 /* Always handle the AoD domain */
106 for (i = 0; i < 2; i++) 107 handle_nested_irq(irq_find_mapping(arizona->virq, 0));
107 handle_nested_irq(irq_find_mapping(arizona->virq, i)); 108
109 /*
110 * Check if one of the main interrupts is asserted and only
111 * check that domain if it is.
112 */
113 ret = regmap_read(arizona->regmap, ARIZONA_IRQ_PIN_STATUS, &val);
114 if (ret == 0 && val & ARIZONA_IRQ1_STS) {
115 handle_nested_irq(irq_find_mapping(arizona->virq, 1));
116 } else if (ret != 0) {
117 dev_err(arizona->dev, "Failed to read main IRQ status: %d\n",
118 ret);
119 }
108 120
109 pm_runtime_mark_last_busy(arizona->dev); 121 pm_runtime_mark_last_busy(arizona->dev);
110 pm_runtime_put_autosuspend(arizona->dev); 122 pm_runtime_put_autosuspend(arizona->dev);
@@ -156,18 +168,36 @@ int arizona_irq_init(struct arizona *arizona)
156 int flags = IRQF_ONESHOT; 168 int flags = IRQF_ONESHOT;
157 int ret, i; 169 int ret, i;
158 const struct regmap_irq_chip *aod, *irq; 170 const struct regmap_irq_chip *aod, *irq;
171 bool ctrlif_error = true;
159 172
160 switch (arizona->type) { 173 switch (arizona->type) {
161#ifdef CONFIG_MFD_WM5102 174#ifdef CONFIG_MFD_WM5102
162 case WM5102: 175 case WM5102:
163 aod = &wm5102_aod; 176 aod = &wm5102_aod;
164 irq = &wm5102_irq; 177 irq = &wm5102_irq;
178
179 switch (arizona->rev) {
180 case 0:
181 ctrlif_error = false;
182 break;
183 default:
184 break;
185 }
165 break; 186 break;
166#endif 187#endif
167#ifdef CONFIG_MFD_WM5110 188#ifdef CONFIG_MFD_WM5110
168 case WM5110: 189 case WM5110:
169 aod = &wm5110_aod; 190 aod = &wm5110_aod;
170 irq = &wm5110_irq; 191 irq = &wm5110_irq;
192
193 switch (arizona->rev) {
194 case 0:
195 case 1:
196 ctrlif_error = false;
197 break;
198 default:
199 break;
200 }
171 break; 201 break;
172#endif 202#endif
173 default: 203 default:
@@ -226,13 +256,17 @@ int arizona_irq_init(struct arizona *arizona)
226 } 256 }
227 257
228 /* Handle control interface errors in the core */ 258 /* Handle control interface errors in the core */
229 i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); 259 if (ctrlif_error) {
230 ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT, 260 i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
231 "Control interface error", arizona); 261 ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
232 if (ret != 0) { 262 IRQF_ONESHOT,
233 dev_err(arizona->dev, "Failed to request boot done %d: %d\n", 263 "Control interface error", arizona);
234 arizona->irq, ret); 264 if (ret != 0) {
235 goto err_ctrlif; 265 dev_err(arizona->dev,
266 "Failed to request CTRLIF_ERR %d: %d\n",
267 arizona->irq, ret);
268 goto err_ctrlif;
269 }
236 } 270 }
237 271
238 ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, 272 ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread,
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
new file mode 100644
index 000000000000..ff6c77f392bd
--- /dev/null
+++ b/drivers/mfd/da9055-core.c
@@ -0,0 +1,423 @@
1/*
2 * Device access for Dialog DA9055 PMICs.
3 *
4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
5 *
6 * Author: David Dajun Chen <dchen@diasemi.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/device.h>
16#include <linux/input.h>
17#include <linux/irq.h>
18#include <linux/mutex.h>
19
20#include <linux/mfd/core.h>
21#include <linux/mfd/da9055/core.h>
22#include <linux/mfd/da9055/pdata.h>
23#include <linux/mfd/da9055/reg.h>
24
25#define DA9055_IRQ_NONKEY_MASK 0x01
26#define DA9055_IRQ_ALM_MASK 0x02
27#define DA9055_IRQ_TICK_MASK 0x04
28#define DA9055_IRQ_ADC_MASK 0x08
29#define DA9055_IRQ_BUCK_ILIM_MASK 0x08
30
31static bool da9055_register_readable(struct device *dev, unsigned int reg)
32{
33 switch (reg) {
34 case DA9055_REG_STATUS_A:
35 case DA9055_REG_STATUS_B:
36 case DA9055_REG_EVENT_A:
37 case DA9055_REG_EVENT_B:
38 case DA9055_REG_EVENT_C:
39 case DA9055_REG_IRQ_MASK_A:
40 case DA9055_REG_IRQ_MASK_B:
41 case DA9055_REG_IRQ_MASK_C:
42
43 case DA9055_REG_CONTROL_A:
44 case DA9055_REG_CONTROL_B:
45 case DA9055_REG_CONTROL_C:
46 case DA9055_REG_CONTROL_D:
47 case DA9055_REG_CONTROL_E:
48
49 case DA9055_REG_ADC_MAN:
50 case DA9055_REG_ADC_CONT:
51 case DA9055_REG_VSYS_MON:
52 case DA9055_REG_ADC_RES_L:
53 case DA9055_REG_ADC_RES_H:
54 case DA9055_REG_VSYS_RES:
55 case DA9055_REG_ADCIN1_RES:
56 case DA9055_REG_ADCIN2_RES:
57 case DA9055_REG_ADCIN3_RES:
58
59 case DA9055_REG_COUNT_S:
60 case DA9055_REG_COUNT_MI:
61 case DA9055_REG_COUNT_H:
62 case DA9055_REG_COUNT_D:
63 case DA9055_REG_COUNT_MO:
64 case DA9055_REG_COUNT_Y:
65 case DA9055_REG_ALARM_H:
66 case DA9055_REG_ALARM_D:
67 case DA9055_REG_ALARM_MI:
68 case DA9055_REG_ALARM_MO:
69 case DA9055_REG_ALARM_Y:
70
71 case DA9055_REG_GPIO0_1:
72 case DA9055_REG_GPIO2:
73 case DA9055_REG_GPIO_MODE0_2:
74
75 case DA9055_REG_BCORE_CONT:
76 case DA9055_REG_BMEM_CONT:
77 case DA9055_REG_LDO1_CONT:
78 case DA9055_REG_LDO2_CONT:
79 case DA9055_REG_LDO3_CONT:
80 case DA9055_REG_LDO4_CONT:
81 case DA9055_REG_LDO5_CONT:
82 case DA9055_REG_LDO6_CONT:
83 case DA9055_REG_BUCK_LIM:
84 case DA9055_REG_BCORE_MODE:
85 case DA9055_REG_VBCORE_A:
86 case DA9055_REG_VBMEM_A:
87 case DA9055_REG_VLDO1_A:
88 case DA9055_REG_VLDO2_A:
89 case DA9055_REG_VLDO3_A:
90 case DA9055_REG_VLDO4_A:
91 case DA9055_REG_VLDO5_A:
92 case DA9055_REG_VLDO6_A:
93 case DA9055_REG_VBCORE_B:
94 case DA9055_REG_VBMEM_B:
95 case DA9055_REG_VLDO1_B:
96 case DA9055_REG_VLDO2_B:
97 case DA9055_REG_VLDO3_B:
98 case DA9055_REG_VLDO4_B:
99 case DA9055_REG_VLDO5_B:
100 case DA9055_REG_VLDO6_B:
101 return true;
102 default:
103 return false;
104 }
105}
106
107static bool da9055_register_writeable(struct device *dev, unsigned int reg)
108{
109 switch (reg) {
110 case DA9055_REG_STATUS_A:
111 case DA9055_REG_STATUS_B:
112 case DA9055_REG_EVENT_A:
113 case DA9055_REG_EVENT_B:
114 case DA9055_REG_EVENT_C:
115 case DA9055_REG_IRQ_MASK_A:
116 case DA9055_REG_IRQ_MASK_B:
117 case DA9055_REG_IRQ_MASK_C:
118
119 case DA9055_REG_CONTROL_A:
120 case DA9055_REG_CONTROL_B:
121 case DA9055_REG_CONTROL_C:
122 case DA9055_REG_CONTROL_D:
123 case DA9055_REG_CONTROL_E:
124
125 case DA9055_REG_ADC_MAN:
126 case DA9055_REG_ADC_CONT:
127 case DA9055_REG_VSYS_MON:
128 case DA9055_REG_ADC_RES_L:
129 case DA9055_REG_ADC_RES_H:
130 case DA9055_REG_VSYS_RES:
131 case DA9055_REG_ADCIN1_RES:
132 case DA9055_REG_ADCIN2_RES:
133 case DA9055_REG_ADCIN3_RES:
134
135 case DA9055_REG_COUNT_S:
136 case DA9055_REG_COUNT_MI:
137 case DA9055_REG_COUNT_H:
138 case DA9055_REG_COUNT_D:
139 case DA9055_REG_COUNT_MO:
140 case DA9055_REG_COUNT_Y:
141 case DA9055_REG_ALARM_H:
142 case DA9055_REG_ALARM_D:
143 case DA9055_REG_ALARM_MI:
144 case DA9055_REG_ALARM_MO:
145 case DA9055_REG_ALARM_Y:
146
147 case DA9055_REG_GPIO0_1:
148 case DA9055_REG_GPIO2:
149 case DA9055_REG_GPIO_MODE0_2:
150
151 case DA9055_REG_BCORE_CONT:
152 case DA9055_REG_BMEM_CONT:
153 case DA9055_REG_LDO1_CONT:
154 case DA9055_REG_LDO2_CONT:
155 case DA9055_REG_LDO3_CONT:
156 case DA9055_REG_LDO4_CONT:
157 case DA9055_REG_LDO5_CONT:
158 case DA9055_REG_LDO6_CONT:
159 case DA9055_REG_BUCK_LIM:
160 case DA9055_REG_BCORE_MODE:
161 case DA9055_REG_VBCORE_A:
162 case DA9055_REG_VBMEM_A:
163 case DA9055_REG_VLDO1_A:
164 case DA9055_REG_VLDO2_A:
165 case DA9055_REG_VLDO3_A:
166 case DA9055_REG_VLDO4_A:
167 case DA9055_REG_VLDO5_A:
168 case DA9055_REG_VLDO6_A:
169 case DA9055_REG_VBCORE_B:
170 case DA9055_REG_VBMEM_B:
171 case DA9055_REG_VLDO1_B:
172 case DA9055_REG_VLDO2_B:
173 case DA9055_REG_VLDO3_B:
174 case DA9055_REG_VLDO4_B:
175 case DA9055_REG_VLDO5_B:
176 case DA9055_REG_VLDO6_B:
177 return true;
178 default:
179 return false;
180 }
181}
182
183static bool da9055_register_volatile(struct device *dev, unsigned int reg)
184{
185 switch (reg) {
186 case DA9055_REG_STATUS_A:
187 case DA9055_REG_STATUS_B:
188 case DA9055_REG_EVENT_A:
189 case DA9055_REG_EVENT_B:
190 case DA9055_REG_EVENT_C:
191
192 case DA9055_REG_CONTROL_A:
193 case DA9055_REG_CONTROL_E:
194
195 case DA9055_REG_ADC_MAN:
196 case DA9055_REG_ADC_RES_L:
197 case DA9055_REG_ADC_RES_H:
198 case DA9055_REG_VSYS_RES:
199 case DA9055_REG_ADCIN1_RES:
200 case DA9055_REG_ADCIN2_RES:
201 case DA9055_REG_ADCIN3_RES:
202
203 case DA9055_REG_COUNT_S:
204 case DA9055_REG_COUNT_MI:
205 case DA9055_REG_COUNT_H:
206 case DA9055_REG_COUNT_D:
207 case DA9055_REG_COUNT_MO:
208 case DA9055_REG_COUNT_Y:
209 case DA9055_REG_ALARM_MI:
210
211 case DA9055_REG_BCORE_CONT:
212 case DA9055_REG_BMEM_CONT:
213 case DA9055_REG_LDO1_CONT:
214 case DA9055_REG_LDO2_CONT:
215 case DA9055_REG_LDO3_CONT:
216 case DA9055_REG_LDO4_CONT:
217 case DA9055_REG_LDO5_CONT:
218 case DA9055_REG_LDO6_CONT:
219 return true;
220 default:
221 return false;
222 }
223}
224
225static struct regmap_irq da9055_irqs[] = {
226 [DA9055_IRQ_NONKEY] = {
227 .reg_offset = 0,
228 .mask = DA9055_IRQ_NONKEY_MASK,
229 },
230 [DA9055_IRQ_ALARM] = {
231 .reg_offset = 0,
232 .mask = DA9055_IRQ_ALM_MASK,
233 },
234 [DA9055_IRQ_TICK] = {
235 .reg_offset = 0,
236 .mask = DA9055_IRQ_TICK_MASK,
237 },
238 [DA9055_IRQ_HWMON] = {
239 .reg_offset = 0,
240 .mask = DA9055_IRQ_ADC_MASK,
241 },
242 [DA9055_IRQ_REGULATOR] = {
243 .reg_offset = 1,
244 .mask = DA9055_IRQ_BUCK_ILIM_MASK,
245 },
246};
247
248struct regmap_config da9055_regmap_config = {
249 .reg_bits = 8,
250 .val_bits = 8,
251
252 .cache_type = REGCACHE_RBTREE,
253
254 .max_register = DA9055_MAX_REGISTER_CNT,
255 .readable_reg = da9055_register_readable,
256 .writeable_reg = da9055_register_writeable,
257 .volatile_reg = da9055_register_volatile,
258};
259EXPORT_SYMBOL_GPL(da9055_regmap_config);
260
261static struct resource da9055_onkey_resource = {
262 .name = "ONKEY",
263 .start = DA9055_IRQ_NONKEY,
264 .end = DA9055_IRQ_NONKEY,
265 .flags = IORESOURCE_IRQ,
266};
267
268static struct resource da9055_rtc_resource[] = {
269 {
270 .name = "ALM",
271 .start = DA9055_IRQ_ALARM,
272 .end = DA9055_IRQ_ALARM,
273 .flags = IORESOURCE_IRQ,
274 },
275 {
276 .name = "TICK",
277 .start = DA9055_IRQ_TICK,
278 .end = DA9055_IRQ_TICK,
279 .flags = IORESOURCE_IRQ,
280 },
281};
282
283static struct resource da9055_hwmon_resource = {
284 .name = "HWMON",
285 .start = DA9055_IRQ_HWMON,
286 .end = DA9055_IRQ_HWMON,
287 .flags = IORESOURCE_IRQ,
288};
289
290static struct resource da9055_ld05_6_resource = {
291 .name = "REGULATOR",
292 .start = DA9055_IRQ_REGULATOR,
293 .end = DA9055_IRQ_REGULATOR,
294 .flags = IORESOURCE_IRQ,
295};
296
297static struct mfd_cell da9055_devs[] = {
298 {
299 .of_compatible = "dialog,da9055-gpio",
300 .name = "da9055-gpio",
301 },
302 {
303 .of_compatible = "dialog,da9055-regulator",
304 .name = "da9055-regulator",
305 .id = 1,
306 },
307 {
308 .of_compatible = "dialog,da9055-regulator",
309 .name = "da9055-regulator",
310 .id = 2,
311 },
312 {
313 .of_compatible = "dialog,da9055-regulator",
314 .name = "da9055-regulator",
315 .id = 3,
316 },
317 {
318 .of_compatible = "dialog,da9055-regulator",
319 .name = "da9055-regulator",
320 .id = 4,
321 },
322 {
323 .of_compatible = "dialog,da9055-regulator",
324 .name = "da9055-regulator",
325 .id = 5,
326 },
327 {
328 .of_compatible = "dialog,da9055-regulator",
329 .name = "da9055-regulator",
330 .id = 6,
331 },
332 {
333 .of_compatible = "dialog,da9055-regulator",
334 .name = "da9055-regulator",
335 .id = 7,
336 .resources = &da9055_ld05_6_resource,
337 .num_resources = 1,
338 },
339 {
340 .of_compatible = "dialog,da9055-regulator",
341 .name = "da9055-regulator",
342 .resources = &da9055_ld05_6_resource,
343 .num_resources = 1,
344 .id = 8,
345 },
346 {
347 .of_compatible = "dialog,da9055-onkey",
348 .name = "da9055-onkey",
349 .resources = &da9055_onkey_resource,
350 .num_resources = 1,
351 },
352 {
353 .of_compatible = "dialog,da9055-rtc",
354 .name = "da9055-rtc",
355 .resources = da9055_rtc_resource,
356 .num_resources = ARRAY_SIZE(da9055_rtc_resource),
357 },
358 {
359 .of_compatible = "dialog,da9055-hwmon",
360 .name = "da9055-hwmon",
361 .resources = &da9055_hwmon_resource,
362 .num_resources = 1,
363 },
364 {
365 .of_compatible = "dialog,da9055-watchdog",
366 .name = "da9055-watchdog",
367 },
368};
369
370static struct regmap_irq_chip da9055_regmap_irq_chip = {
371 .name = "da9055_irq",
372 .status_base = DA9055_REG_EVENT_A,
373 .mask_base = DA9055_REG_IRQ_MASK_A,
374 .ack_base = DA9055_REG_EVENT_A,
375 .num_regs = 3,
376 .irqs = da9055_irqs,
377 .num_irqs = ARRAY_SIZE(da9055_irqs),
378};
379
380int __devinit da9055_device_init(struct da9055 *da9055)
381{
382 struct da9055_pdata *pdata = da9055->dev->platform_data;
383 int ret;
384
385 if (pdata && pdata->init != NULL)
386 pdata->init(da9055);
387
388 if (!pdata || !pdata->irq_base)
389 da9055->irq_base = -1;
390 else
391 da9055->irq_base = pdata->irq_base;
392
393 ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
394 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
395 da9055->irq_base, &da9055_regmap_irq_chip,
396 &da9055->irq_data);
397 if (ret < 0)
398 return ret;
399
400 da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
401
402 ret = mfd_add_devices(da9055->dev, -1,
403 da9055_devs, ARRAY_SIZE(da9055_devs),
404 NULL, da9055->irq_base, NULL);
405 if (ret)
406 goto err;
407
408 return 0;
409
410err:
411 mfd_remove_devices(da9055->dev);
412 return ret;
413}
414
415void __devexit da9055_device_exit(struct da9055 *da9055)
416{
417 regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
418 mfd_remove_devices(da9055->dev);
419}
420
421MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
422MODULE_LICENSE("GPL");
423MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
new file mode 100644
index 000000000000..88f6dca53bac
--- /dev/null
+++ b/drivers/mfd/da9055-i2c.c
@@ -0,0 +1,93 @@
1 /* I2C access for DA9055 PMICs.
2 *
3 * Copyright(c) 2012 Dialog Semiconductor Ltd.
4 *
5 * Author: David Dajun Chen <dchen@diasemi.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/device.h>
16#include <linux/i2c.h>
17#include <linux/err.h>
18
19#include <linux/mfd/da9055/core.h>
20
21static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
22 const struct i2c_device_id *id)
23{
24 struct da9055 *da9055;
25 int ret;
26
27 da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055), GFP_KERNEL);
28 if (!da9055)
29 return -ENOMEM;
30
31 da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config);
32 if (IS_ERR(da9055->regmap)) {
33 ret = PTR_ERR(da9055->regmap);
34 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
35 ret);
36 return ret;
37 }
38
39 da9055->dev = &i2c->dev;
40 da9055->chip_irq = i2c->irq;
41
42 i2c_set_clientdata(i2c, da9055);
43
44 return da9055_device_init(da9055);
45}
46
47static int __devexit da9055_i2c_remove(struct i2c_client *i2c)
48{
49 struct da9055 *da9055 = i2c_get_clientdata(i2c);
50
51 da9055_device_exit(da9055);
52
53 return 0;
54}
55
56static struct i2c_device_id da9055_i2c_id[] = {
57 {"da9055-pmic", 0},
58 { }
59};
60
61static struct i2c_driver da9055_i2c_driver = {
62 .probe = da9055_i2c_probe,
63 .remove = __devexit_p(da9055_i2c_remove),
64 .id_table = da9055_i2c_id,
65 .driver = {
66 .name = "da9055",
67 .owner = THIS_MODULE,
68 },
69};
70
71static int __init da9055_i2c_init(void)
72{
73 int ret;
74
75 ret = i2c_add_driver(&da9055_i2c_driver);
76 if (ret != 0) {
77 pr_err("DA9055 I2C registration failed %d\n", ret);
78 return ret;
79 }
80
81 return 0;
82}
83subsys_initcall(da9055_i2c_init);
84
85static void __exit da9055_i2c_exit(void)
86{
87 i2c_del_driver(&da9055_i2c_driver);
88}
89module_exit(da9055_i2c_exit);
90
91MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
92MODULE_DESCRIPTION("I2C driver for Dialog DA9055 PMIC");
93MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 6b67edbdbd01..00b8b0f3dfb6 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -270,6 +270,8 @@ static struct {
270 struct prcmu_fw_version version; 270 struct prcmu_fw_version version;
271} fw_info; 271} fw_info;
272 272
273static struct irq_domain *db8500_irq_domain;
274
273/* 275/*
274 * This vector maps irq numbers to the bits in the bit field used in 276 * This vector maps irq numbers to the bits in the bit field used in
275 * communication with the PRCMU firmware. 277 * communication with the PRCMU firmware.
@@ -2624,7 +2626,7 @@ static void prcmu_irq_mask(struct irq_data *d)
2624 2626
2625 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); 2627 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
2626 2628
2627 mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; 2629 mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq];
2628 2630
2629 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); 2631 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
2630 2632
@@ -2638,7 +2640,7 @@ static void prcmu_irq_unmask(struct irq_data *d)
2638 2640
2639 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags); 2641 spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
2640 2642
2641 mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE]; 2643 mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq];
2642 2644
2643 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags); 2645 spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
2644 2646
@@ -2678,9 +2680,37 @@ static char *fw_project_name(u8 project)
2678 } 2680 }
2679} 2681}
2680 2682
2683static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
2684 irq_hw_number_t hwirq)
2685{
2686 irq_set_chip_and_handler(virq, &prcmu_irq_chip,
2687 handle_simple_irq);
2688 set_irq_flags(virq, IRQF_VALID);
2689
2690 return 0;
2691}
2692
2693static struct irq_domain_ops db8500_irq_ops = {
2694 .map = db8500_irq_map,
2695 .xlate = irq_domain_xlate_twocell,
2696};
2697
2698static int db8500_irq_init(struct device_node *np)
2699{
2700 db8500_irq_domain = irq_domain_add_legacy(
2701 np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
2702 0, &db8500_irq_ops, NULL);
2703
2704 if (!db8500_irq_domain) {
2705 pr_err("Failed to create irqdomain\n");
2706 return -ENOSYS;
2707 }
2708
2709 return 0;
2710}
2711
2681void __init db8500_prcmu_early_init(void) 2712void __init db8500_prcmu_early_init(void)
2682{ 2713{
2683 unsigned int i;
2684 if (cpu_is_u8500v2()) { 2714 if (cpu_is_u8500v2()) {
2685 void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); 2715 void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
2686 2716
@@ -2725,15 +2755,6 @@ void __init db8500_prcmu_early_init(void)
2725 2755
2726 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work); 2756 INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
2727 2757
2728 /* Initalize irqs. */
2729 for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) {
2730 unsigned int irq;
2731
2732 irq = IRQ_PRCMU_BASE + i;
2733 irq_set_chip_and_handler(irq, &prcmu_irq_chip,
2734 handle_simple_irq);
2735 set_irq_flags(irq, IRQF_VALID);
2736 }
2737 compute_armss_rate(); 2758 compute_armss_rate();
2738} 2759}
2739 2760
@@ -3041,6 +3062,8 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
3041 goto no_irq_return; 3062 goto no_irq_return;
3042 } 3063 }
3043 3064
3065 db8500_irq_init(np);
3066
3044 for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) { 3067 for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
3045 if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) { 3068 if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
3046 db8500_prcmu_devs[i].platform_data = ab8500_platdata; 3069 db8500_prcmu_devs[i].platform_data = ab8500_platdata;
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
new file mode 100644
index 000000000000..c84ded5f8ece
--- /dev/null
+++ b/drivers/mfd/lp8788-irq.c
@@ -0,0 +1,198 @@
1/*
2 * TI LP8788 MFD - interrupt handler
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
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 */
13
14#include <linux/delay.h>
15#include <linux/err.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/irqdomain.h>
19#include <linux/device.h>
20#include <linux/mfd/lp8788.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23
24/* register address */
25#define LP8788_INT_1 0x00
26#define LP8788_INTEN_1 0x03
27
28#define BASE_INTEN_ADDR LP8788_INTEN_1
29#define SIZE_REG 8
30#define NUM_REGS 3
31
32/*
33 * struct lp8788_irq_data
34 * @lp : used for accessing to lp8788 registers
35 * @irq_lock : mutex for enabling/disabling the interrupt
36 * @domain : IRQ domain for handling nested interrupt
37 * @enabled : status of enabled interrupt
38 */
39struct lp8788_irq_data {
40 struct lp8788 *lp;
41 struct mutex irq_lock;
42 struct irq_domain *domain;
43 int enabled[LP8788_INT_MAX];
44};
45
46static inline u8 _irq_to_addr(enum lp8788_int_id id)
47{
48 return id / SIZE_REG;
49}
50
51static inline u8 _irq_to_enable_addr(enum lp8788_int_id id)
52{
53 return _irq_to_addr(id) + BASE_INTEN_ADDR;
54}
55
56static inline u8 _irq_to_mask(enum lp8788_int_id id)
57{
58 return 1 << (id % SIZE_REG);
59}
60
61static inline u8 _irq_to_val(enum lp8788_int_id id, int enable)
62{
63 return enable << (id % SIZE_REG);
64}
65
66static void lp8788_irq_enable(struct irq_data *data)
67{
68 struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
69 irqd->enabled[data->hwirq] = 1;
70}
71
72static void lp8788_irq_disable(struct irq_data *data)
73{
74 struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
75 irqd->enabled[data->hwirq] = 0;
76}
77
78static void lp8788_irq_bus_lock(struct irq_data *data)
79{
80 struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
81
82 mutex_lock(&irqd->irq_lock);
83}
84
85static void lp8788_irq_bus_sync_unlock(struct irq_data *data)
86{
87 struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
88 enum lp8788_int_id irq = data->hwirq;
89 u8 addr, mask, val;
90
91 addr = _irq_to_enable_addr(irq);
92 mask = _irq_to_mask(irq);
93 val = _irq_to_val(irq, irqd->enabled[irq]);
94
95 lp8788_update_bits(irqd->lp, addr, mask, val);
96
97 mutex_unlock(&irqd->irq_lock);
98}
99
100static struct irq_chip lp8788_irq_chip = {
101 .name = "lp8788",
102 .irq_enable = lp8788_irq_enable,
103 .irq_disable = lp8788_irq_disable,
104 .irq_bus_lock = lp8788_irq_bus_lock,
105 .irq_bus_sync_unlock = lp8788_irq_bus_sync_unlock,
106};
107
108static irqreturn_t lp8788_irq_handler(int irq, void *ptr)
109{
110 struct lp8788_irq_data *irqd = ptr;
111 struct lp8788 *lp = irqd->lp;
112 u8 status[NUM_REGS], addr, mask;
113 bool handled;
114 int i;
115
116 if (lp8788_read_multi_bytes(lp, LP8788_INT_1, status, NUM_REGS))
117 return IRQ_NONE;
118
119 for (i = 0 ; i < LP8788_INT_MAX ; i++) {
120 addr = _irq_to_addr(i);
121 mask = _irq_to_mask(i);
122
123 /* reporting only if the irq is enabled */
124 if (status[addr] & mask) {
125 handle_nested_irq(irq_find_mapping(irqd->domain, i));
126 handled = true;
127 }
128 }
129
130 return handled ? IRQ_HANDLED : IRQ_NONE;
131}
132
133static int lp8788_irq_map(struct irq_domain *d, unsigned int virq,
134 irq_hw_number_t hwirq)
135{
136 struct lp8788_irq_data *irqd = d->host_data;
137 struct irq_chip *chip = &lp8788_irq_chip;
138
139 irq_set_chip_data(virq, irqd);
140 irq_set_chip_and_handler(virq, chip, handle_edge_irq);
141 irq_set_nested_thread(virq, 1);
142
143#ifdef CONFIG_ARM
144 set_irq_flags(virq, IRQF_VALID);
145#else
146 irq_set_noprobe(virq);
147#endif
148
149 return 0;
150}
151
152static struct irq_domain_ops lp8788_domain_ops = {
153 .map = lp8788_irq_map,
154};
155
156int lp8788_irq_init(struct lp8788 *lp, int irq)
157{
158 struct lp8788_irq_data *irqd;
159 int ret;
160
161 if (irq <= 0) {
162 dev_warn(lp->dev, "invalid irq number: %d\n", irq);
163 return 0;
164 }
165
166 irqd = devm_kzalloc(lp->dev, sizeof(*irqd), GFP_KERNEL);
167 if (!irqd)
168 return -ENOMEM;
169
170 irqd->lp = lp;
171 irqd->domain = irq_domain_add_linear(lp->dev->of_node, LP8788_INT_MAX,
172 &lp8788_domain_ops, irqd);
173 if (!irqd->domain) {
174 dev_err(lp->dev, "failed to add irq domain err\n");
175 return -EINVAL;
176 }
177
178 lp->irqdm = irqd->domain;
179 mutex_init(&irqd->irq_lock);
180
181 ret = request_threaded_irq(irq, NULL, lp8788_irq_handler,
182 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
183 "lp8788-irq", irqd);
184 if (ret) {
185 dev_err(lp->dev, "failed to create a thread for IRQ_N\n");
186 return ret;
187 }
188
189 lp->irq = irq;
190
191 return 0;
192}
193
194void lp8788_irq_exit(struct lp8788 *lp)
195{
196 if (lp->irq)
197 free_irq(lp->irq, lp->irqdm);
198}
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
new file mode 100644
index 000000000000..3e94a699833c
--- /dev/null
+++ b/drivers/mfd/lp8788.c
@@ -0,0 +1,245 @@
1/*
2 * TI LP8788 MFD - core interface
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
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 */
13
14#include <linux/err.h>
15#include <linux/i2c.h>
16#include <linux/mfd/core.h>
17#include <linux/mfd/lp8788.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20
21#define MAX_LP8788_REGISTERS 0xA2
22
23#define MFD_DEV_SIMPLE(_name) \
24{ \
25 .name = LP8788_DEV_##_name, \
26}
27
28#define MFD_DEV_WITH_ID(_name, _id) \
29{ \
30 .name = LP8788_DEV_##_name, \
31 .id = _id, \
32}
33
34#define MFD_DEV_WITH_RESOURCE(_name, _resource, num_resource) \
35{ \
36 .name = LP8788_DEV_##_name, \
37 .resources = _resource, \
38 .num_resources = num_resource, \
39}
40
41static struct resource chg_irqs[] = {
42 /* Charger Interrupts */
43 {
44 .start = LP8788_INT_CHG_INPUT_STATE,
45 .end = LP8788_INT_PRECHG_TIMEOUT,
46 .name = LP8788_CHG_IRQ,
47 .flags = IORESOURCE_IRQ,
48 },
49 /* Power Routing Switch Interrupts */
50 {
51 .start = LP8788_INT_ENTER_SYS_SUPPORT,
52 .end = LP8788_INT_EXIT_SYS_SUPPORT,
53 .name = LP8788_PRSW_IRQ,
54 .flags = IORESOURCE_IRQ,
55 },
56 /* Battery Interrupts */
57 {
58 .start = LP8788_INT_BATT_LOW,
59 .end = LP8788_INT_NO_BATT,
60 .name = LP8788_BATT_IRQ,
61 .flags = IORESOURCE_IRQ,
62 },
63};
64
65static struct resource rtc_irqs[] = {
66 {
67 .start = LP8788_INT_RTC_ALARM1,
68 .end = LP8788_INT_RTC_ALARM2,
69 .name = LP8788_ALM_IRQ,
70 .flags = IORESOURCE_IRQ,
71 },
72};
73
74static struct mfd_cell lp8788_devs[] = {
75 /* 4 bucks */
76 MFD_DEV_WITH_ID(BUCK, 1),
77 MFD_DEV_WITH_ID(BUCK, 2),
78 MFD_DEV_WITH_ID(BUCK, 3),
79 MFD_DEV_WITH_ID(BUCK, 4),
80
81 /* 12 digital ldos */
82 MFD_DEV_WITH_ID(DLDO, 1),
83 MFD_DEV_WITH_ID(DLDO, 2),
84 MFD_DEV_WITH_ID(DLDO, 3),
85 MFD_DEV_WITH_ID(DLDO, 4),
86 MFD_DEV_WITH_ID(DLDO, 5),
87 MFD_DEV_WITH_ID(DLDO, 6),
88 MFD_DEV_WITH_ID(DLDO, 7),
89 MFD_DEV_WITH_ID(DLDO, 8),
90 MFD_DEV_WITH_ID(DLDO, 9),
91 MFD_DEV_WITH_ID(DLDO, 10),
92 MFD_DEV_WITH_ID(DLDO, 11),
93 MFD_DEV_WITH_ID(DLDO, 12),
94
95 /* 10 analog ldos */
96 MFD_DEV_WITH_ID(ALDO, 1),
97 MFD_DEV_WITH_ID(ALDO, 2),
98 MFD_DEV_WITH_ID(ALDO, 3),
99 MFD_DEV_WITH_ID(ALDO, 4),
100 MFD_DEV_WITH_ID(ALDO, 5),
101 MFD_DEV_WITH_ID(ALDO, 6),
102 MFD_DEV_WITH_ID(ALDO, 7),
103 MFD_DEV_WITH_ID(ALDO, 8),
104 MFD_DEV_WITH_ID(ALDO, 9),
105 MFD_DEV_WITH_ID(ALDO, 10),
106
107 /* ADC */
108 MFD_DEV_SIMPLE(ADC),
109
110 /* battery charger */
111 MFD_DEV_WITH_RESOURCE(CHARGER, chg_irqs, ARRAY_SIZE(chg_irqs)),
112
113 /* rtc */
114 MFD_DEV_WITH_RESOURCE(RTC, rtc_irqs, ARRAY_SIZE(rtc_irqs)),
115
116 /* backlight */
117 MFD_DEV_SIMPLE(BACKLIGHT),
118
119 /* current sink for vibrator */
120 MFD_DEV_SIMPLE(VIBRATOR),
121
122 /* current sink for keypad LED */
123 MFD_DEV_SIMPLE(KEYLED),
124};
125
126int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data)
127{
128 int ret;
129 unsigned int val;
130
131 ret = regmap_read(lp->regmap, reg, &val);
132 if (ret < 0) {
133 dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
134 return ret;
135 }
136
137 *data = (u8)val;
138 return 0;
139}
140EXPORT_SYMBOL_GPL(lp8788_read_byte);
141
142int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count)
143{
144 return regmap_bulk_read(lp->regmap, reg, data, count);
145}
146EXPORT_SYMBOL_GPL(lp8788_read_multi_bytes);
147
148int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data)
149{
150 return regmap_write(lp->regmap, reg, data);
151}
152EXPORT_SYMBOL_GPL(lp8788_write_byte);
153
154int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data)
155{
156 return regmap_update_bits(lp->regmap, reg, mask, data);
157}
158EXPORT_SYMBOL_GPL(lp8788_update_bits);
159
160static int lp8788_platform_init(struct lp8788 *lp)
161{
162 struct lp8788_platform_data *pdata = lp->pdata;
163
164 return (pdata && pdata->init_func) ? pdata->init_func(lp) : 0;
165}
166
167static const struct regmap_config lp8788_regmap_config = {
168 .reg_bits = 8,
169 .val_bits = 8,
170 .max_register = MAX_LP8788_REGISTERS,
171};
172
173static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
174{
175 struct lp8788 *lp;
176 struct lp8788_platform_data *pdata = cl->dev.platform_data;
177 int ret;
178
179 lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
180 if (!lp)
181 return -ENOMEM;
182
183 lp->regmap = devm_regmap_init_i2c(cl, &lp8788_regmap_config);
184 if (IS_ERR(lp->regmap)) {
185 ret = PTR_ERR(lp->regmap);
186 dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
187 return ret;
188 }
189
190 lp->pdata = pdata;
191 lp->dev = &cl->dev;
192 i2c_set_clientdata(cl, lp);
193
194 ret = lp8788_platform_init(lp);
195 if (ret)
196 return ret;
197
198 ret = lp8788_irq_init(lp, cl->irq);
199 if (ret)
200 return ret;
201
202 return mfd_add_devices(lp->dev, -1, lp8788_devs,
203 ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
204}
205
206static int __devexit lp8788_remove(struct i2c_client *cl)
207{
208 struct lp8788 *lp = i2c_get_clientdata(cl);
209
210 mfd_remove_devices(lp->dev);
211 lp8788_irq_exit(lp);
212 return 0;
213}
214
215static const struct i2c_device_id lp8788_ids[] = {
216 {"lp8788", 0},
217 { }
218};
219MODULE_DEVICE_TABLE(i2c, lp8788_ids);
220
221static struct i2c_driver lp8788_driver = {
222 .driver = {
223 .name = "lp8788",
224 .owner = THIS_MODULE,
225 },
226 .probe = lp8788_probe,
227 .remove = __devexit_p(lp8788_remove),
228 .id_table = lp8788_ids,
229};
230
231static int __init lp8788_init(void)
232{
233 return i2c_add_driver(&lp8788_driver);
234}
235subsys_initcall(lp8788_init);
236
237static void __exit lp8788_exit(void)
238{
239 i2c_del_driver(&lp8788_driver);
240}
241module_exit(lp8788_exit);
242
243MODULE_DESCRIPTION("TI LP8788 MFD Driver");
244MODULE_AUTHOR("Milo Kim");
245MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 092ad4b44b6d..a22544fe5319 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -49,6 +49,7 @@
49 * document number TBD : DH89xxCC 49 * document number TBD : DH89xxCC
50 * document number TBD : Panther Point 50 * document number TBD : Panther Point
51 * document number TBD : Lynx Point 51 * document number TBD : Lynx Point
52 * document number TBD : Lynx Point-LP
52 */ 53 */
53 54
54#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 55#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -192,6 +193,7 @@ enum lpc_chipsets {
192 LPC_DH89XXCC, /* DH89xxCC */ 193 LPC_DH89XXCC, /* DH89xxCC */
193 LPC_PPT, /* Panther Point */ 194 LPC_PPT, /* Panther Point */
194 LPC_LPT, /* Lynx Point */ 195 LPC_LPT, /* Lynx Point */
196 LPC_LPT_LP, /* Lynx Point-LP */
195}; 197};
196 198
197struct lpc_ich_info lpc_chipset_info[] __devinitdata = { 199struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
@@ -468,6 +470,10 @@ struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
468 .name = "Lynx Point", 470 .name = "Lynx Point",
469 .iTCO_version = 2, 471 .iTCO_version = 2,
470 }, 472 },
473 [LPC_LPT_LP] = {
474 .name = "Lynx Point_LP",
475 .iTCO_version = 2,
476 },
471}; 477};
472 478
473/* 479/*
@@ -641,6 +647,14 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_ich_ids) = {
641 { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT}, 647 { PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT},
642 { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT}, 648 { PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT},
643 { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT}, 649 { PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT},
650 { PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP},
651 { PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP},
652 { PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP},
653 { PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP},
654 { PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP},
655 { PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP},
656 { PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP},
657 { PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP},
644 { 0, }, /* End of list */ 658 { 0, }, /* End of list */
645}; 659};
646MODULE_DEVICE_TABLE(pci, lpc_ich_ids); 660MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
@@ -683,6 +697,30 @@ static void __devinit lpc_ich_finalize_cell(struct mfd_cell *cell,
683 cell->pdata_size = sizeof(struct lpc_ich_info); 697 cell->pdata_size = sizeof(struct lpc_ich_info);
684} 698}
685 699
700/*
701 * We don't check for resource conflict globally. There are 2 or 3 independent
702 * GPIO groups and it's enough to have access to one of these to instantiate
703 * the device.
704 */
705static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
706{
707 int ret;
708 u8 use_gpio = 0;
709
710 if (resource_size(res) >= 0x50 &&
711 !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3"))
712 use_gpio |= 1 << 2;
713
714 if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2"))
715 use_gpio |= 1 << 1;
716
717 ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1");
718 if (!ret)
719 use_gpio |= 1 << 0;
720
721 return use_gpio ? use_gpio : ret;
722}
723
686static int __devinit lpc_ich_init_gpio(struct pci_dev *dev, 724static int __devinit lpc_ich_init_gpio(struct pci_dev *dev,
687 const struct pci_device_id *id) 725 const struct pci_device_id *id)
688{ 726{
@@ -740,12 +778,13 @@ gpe0_done:
740 break; 778 break;
741 } 779 }
742 780
743 ret = acpi_check_resource_conflict(res); 781 ret = lpc_ich_check_conflict_gpio(res);
744 if (ret) { 782 if (ret < 0) {
745 /* this isn't necessarily fatal for the GPIO */ 783 /* this isn't necessarily fatal for the GPIO */
746 acpi_conflict = true; 784 acpi_conflict = true;
747 goto gpio_done; 785 goto gpio_done;
748 } 786 }
787 lpc_chipset_info[id->driver_data].use_gpio = ret;
749 lpc_ich_enable_gpio_space(dev); 788 lpc_ich_enable_gpio_space(dev);
750 789
751 lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); 790 lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id);
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
new file mode 100644
index 000000000000..17f2593d82b8
--- /dev/null
+++ b/drivers/mfd/max8907.c
@@ -0,0 +1,351 @@
1/*
2 * max8907.c - mfd driver for MAX8907
3 *
4 * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
5 * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/err.h>
13#include <linux/i2c.h>
14#include <linux/init.h>
15#include <linux/interrupt.h>
16#include <linux/irq.h>
17#include <linux/mfd/core.h>
18#include <linux/mfd/max8907.h>
19#include <linux/module.h>
20#include <linux/of_device.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23
24static struct mfd_cell max8907_cells[] = {
25 { .name = "max8907-regulator", },
26 { .name = "max8907-rtc", },
27};
28
29static bool max8907_gen_is_volatile_reg(struct device *dev, unsigned int reg)
30{
31 switch (reg) {
32 case MAX8907_REG_ON_OFF_IRQ1:
33 case MAX8907_REG_ON_OFF_STAT:
34 case MAX8907_REG_ON_OFF_IRQ2:
35 case MAX8907_REG_CHG_IRQ1:
36 case MAX8907_REG_CHG_IRQ2:
37 case MAX8907_REG_CHG_STAT:
38 return true;
39 default:
40 return false;
41 }
42}
43
44static bool max8907_gen_is_precious_reg(struct device *dev, unsigned int reg)
45{
46 switch (reg) {
47 case MAX8907_REG_ON_OFF_IRQ1:
48 case MAX8907_REG_ON_OFF_IRQ2:
49 case MAX8907_REG_CHG_IRQ1:
50 case MAX8907_REG_CHG_IRQ2:
51 return true;
52 default:
53 return false;
54 }
55}
56
57static bool max8907_gen_is_writeable_reg(struct device *dev, unsigned int reg)
58{
59 return !max8907_gen_is_volatile_reg(dev, reg);
60}
61
62static const struct regmap_config max8907_regmap_gen_config = {
63 .reg_bits = 8,
64 .val_bits = 8,
65 .volatile_reg = max8907_gen_is_volatile_reg,
66 .precious_reg = max8907_gen_is_precious_reg,
67 .writeable_reg = max8907_gen_is_writeable_reg,
68 .max_register = MAX8907_REG_LDO20VOUT,
69 .cache_type = REGCACHE_RBTREE,
70};
71
72static bool max8907_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
73{
74 if (reg <= MAX8907_REG_RTC_YEAR2)
75 return true;
76
77 switch (reg) {
78 case MAX8907_REG_RTC_STATUS:
79 case MAX8907_REG_RTC_IRQ:
80 return true;
81 default:
82 return false;
83 }
84}
85
86static bool max8907_rtc_is_precious_reg(struct device *dev, unsigned int reg)
87{
88 switch (reg) {
89 case MAX8907_REG_RTC_IRQ:
90 return true;
91 default:
92 return false;
93 }
94}
95
96static bool max8907_rtc_is_writeable_reg(struct device *dev, unsigned int reg)
97{
98 switch (reg) {
99 case MAX8907_REG_RTC_STATUS:
100 case MAX8907_REG_RTC_IRQ:
101 return false;
102 default:
103 return true;
104 }
105}
106
107static const struct regmap_config max8907_regmap_rtc_config = {
108 .reg_bits = 8,
109 .val_bits = 8,
110 .volatile_reg = max8907_rtc_is_volatile_reg,
111 .precious_reg = max8907_rtc_is_precious_reg,
112 .writeable_reg = max8907_rtc_is_writeable_reg,
113 .max_register = MAX8907_REG_MPL_CNTL,
114 .cache_type = REGCACHE_RBTREE,
115};
116
117static const struct regmap_irq max8907_chg_irqs[] = {
118 { .reg_offset = 0, .mask = 1 << 0, },
119 { .reg_offset = 0, .mask = 1 << 1, },
120 { .reg_offset = 0, .mask = 1 << 2, },
121 { .reg_offset = 1, .mask = 1 << 0, },
122 { .reg_offset = 1, .mask = 1 << 1, },
123 { .reg_offset = 1, .mask = 1 << 2, },
124 { .reg_offset = 1, .mask = 1 << 3, },
125 { .reg_offset = 1, .mask = 1 << 4, },
126 { .reg_offset = 1, .mask = 1 << 5, },
127 { .reg_offset = 1, .mask = 1 << 6, },
128 { .reg_offset = 1, .mask = 1 << 7, },
129};
130
131static const struct regmap_irq_chip max8907_chg_irq_chip = {
132 .name = "max8907 chg",
133 .status_base = MAX8907_REG_CHG_IRQ1,
134 .mask_base = MAX8907_REG_CHG_IRQ1_MASK,
135 .wake_base = MAX8907_REG_CHG_IRQ1_MASK,
136 .irq_reg_stride = MAX8907_REG_CHG_IRQ2 - MAX8907_REG_CHG_IRQ1,
137 .num_regs = 2,
138 .irqs = max8907_chg_irqs,
139 .num_irqs = ARRAY_SIZE(max8907_chg_irqs),
140};
141
142static const struct regmap_irq max8907_on_off_irqs[] = {
143 { .reg_offset = 0, .mask = 1 << 0, },
144 { .reg_offset = 0, .mask = 1 << 1, },
145 { .reg_offset = 0, .mask = 1 << 2, },
146 { .reg_offset = 0, .mask = 1 << 3, },
147 { .reg_offset = 0, .mask = 1 << 4, },
148 { .reg_offset = 0, .mask = 1 << 5, },
149 { .reg_offset = 0, .mask = 1 << 6, },
150 { .reg_offset = 0, .mask = 1 << 7, },
151 { .reg_offset = 1, .mask = 1 << 0, },
152 { .reg_offset = 1, .mask = 1 << 1, },
153};
154
155static const struct regmap_irq_chip max8907_on_off_irq_chip = {
156 .name = "max8907 on_off",
157 .status_base = MAX8907_REG_ON_OFF_IRQ1,
158 .mask_base = MAX8907_REG_ON_OFF_IRQ1_MASK,
159 .irq_reg_stride = MAX8907_REG_ON_OFF_IRQ2 - MAX8907_REG_ON_OFF_IRQ1,
160 .num_regs = 2,
161 .irqs = max8907_on_off_irqs,
162 .num_irqs = ARRAY_SIZE(max8907_on_off_irqs),
163};
164
165static const struct regmap_irq max8907_rtc_irqs[] = {
166 { .reg_offset = 0, .mask = 1 << 2, },
167 { .reg_offset = 0, .mask = 1 << 3, },
168};
169
170static const struct regmap_irq_chip max8907_rtc_irq_chip = {
171 .name = "max8907 rtc",
172 .status_base = MAX8907_REG_RTC_IRQ,
173 .mask_base = MAX8907_REG_RTC_IRQ_MASK,
174 .num_regs = 1,
175 .irqs = max8907_rtc_irqs,
176 .num_irqs = ARRAY_SIZE(max8907_rtc_irqs),
177};
178
179static struct max8907 *max8907_pm_off;
180static void max8907_power_off(void)
181{
182 regmap_update_bits(max8907_pm_off->regmap_gen, MAX8907_REG_RESET_CNFG,
183 MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
184}
185
186static __devinit int max8907_i2c_probe(struct i2c_client *i2c,
187 const struct i2c_device_id *id)
188{
189 struct max8907 *max8907;
190 int ret;
191 struct max8907_platform_data *pdata = dev_get_platdata(&i2c->dev);
192 bool pm_off = false;
193
194 if (pdata)
195 pm_off = pdata->pm_off;
196 else if (i2c->dev.of_node)
197 pm_off = of_property_read_bool(i2c->dev.of_node,
198 "maxim,system-power-controller");
199
200 max8907 = devm_kzalloc(&i2c->dev, sizeof(struct max8907), GFP_KERNEL);
201 if (!max8907) {
202 ret = -ENOMEM;
203 goto err_alloc_drvdata;
204 }
205
206 max8907->dev = &i2c->dev;
207 dev_set_drvdata(max8907->dev, max8907);
208
209 max8907->i2c_gen = i2c;
210 i2c_set_clientdata(i2c, max8907);
211 max8907->regmap_gen = devm_regmap_init_i2c(i2c,
212 &max8907_regmap_gen_config);
213 if (IS_ERR(max8907->regmap_gen)) {
214 ret = PTR_ERR(max8907->regmap_gen);
215 dev_err(&i2c->dev, "gen regmap init failed: %d\n", ret);
216 goto err_regmap_gen;
217 }
218
219 max8907->i2c_rtc = i2c_new_dummy(i2c->adapter, MAX8907_RTC_I2C_ADDR);
220 if (!max8907->i2c_rtc) {
221 ret = -ENOMEM;
222 goto err_dummy_rtc;
223 }
224 i2c_set_clientdata(max8907->i2c_rtc, max8907);
225 max8907->regmap_rtc = devm_regmap_init_i2c(max8907->i2c_rtc,
226 &max8907_regmap_rtc_config);
227 if (IS_ERR(max8907->regmap_rtc)) {
228 ret = PTR_ERR(max8907->regmap_rtc);
229 dev_err(&i2c->dev, "rtc regmap init failed: %d\n", ret);
230 goto err_regmap_rtc;
231 }
232
233 irq_set_status_flags(max8907->i2c_gen->irq, IRQ_NOAUTOEN);
234
235 ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq,
236 IRQF_ONESHOT | IRQF_SHARED, -1,
237 &max8907_chg_irq_chip,
238 &max8907->irqc_chg);
239 if (ret != 0) {
240 dev_err(&i2c->dev, "failed to add chg irq chip: %d\n", ret);
241 goto err_irqc_chg;
242 }
243 ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq,
244 IRQF_ONESHOT | IRQF_SHARED, -1,
245 &max8907_on_off_irq_chip,
246 &max8907->irqc_on_off);
247 if (ret != 0) {
248 dev_err(&i2c->dev, "failed to add on off irq chip: %d\n", ret);
249 goto err_irqc_on_off;
250 }
251 ret = regmap_add_irq_chip(max8907->regmap_rtc, max8907->i2c_gen->irq,
252 IRQF_ONESHOT | IRQF_SHARED, -1,
253 &max8907_rtc_irq_chip,
254 &max8907->irqc_rtc);
255 if (ret != 0) {
256 dev_err(&i2c->dev, "failed to add rtc irq chip: %d\n", ret);
257 goto err_irqc_rtc;
258 }
259
260 enable_irq(max8907->i2c_gen->irq);
261
262 ret = mfd_add_devices(max8907->dev, -1, max8907_cells,
263 ARRAY_SIZE(max8907_cells), NULL, 0, NULL);
264 if (ret != 0) {
265 dev_err(&i2c->dev, "failed to add MFD devices %d\n", ret);
266 goto err_add_devices;
267 }
268
269 if (pm_off && !pm_power_off) {
270 max8907_pm_off = max8907;
271 pm_power_off = max8907_power_off;
272 }
273
274 return 0;
275
276err_add_devices:
277 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
278err_irqc_rtc:
279 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off);
280err_irqc_on_off:
281 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg);
282err_irqc_chg:
283err_regmap_rtc:
284 i2c_unregister_device(max8907->i2c_rtc);
285err_dummy_rtc:
286err_regmap_gen:
287err_alloc_drvdata:
288 return ret;
289}
290
291static __devexit int max8907_i2c_remove(struct i2c_client *i2c)
292{
293 struct max8907 *max8907 = i2c_get_clientdata(i2c);
294
295 mfd_remove_devices(max8907->dev);
296
297 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
298 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off);
299 regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg);
300
301 i2c_unregister_device(max8907->i2c_rtc);
302
303 return 0;
304}
305
306#ifdef CONFIG_OF
307static struct of_device_id max8907_of_match[] = {
308 { .compatible = "maxim,max8907" },
309 { },
310};
311MODULE_DEVICE_TABLE(of, max8907_of_match);
312#endif
313
314static const struct i2c_device_id max8907_i2c_id[] = {
315 {"max8907", 0},
316 {}
317};
318MODULE_DEVICE_TABLE(i2c, max8907_i2c_id);
319
320static struct i2c_driver max8907_i2c_driver = {
321 .driver = {
322 .name = "max8907",
323 .owner = THIS_MODULE,
324 .of_match_table = of_match_ptr(max8907_of_match),
325 },
326 .probe = max8907_i2c_probe,
327 .remove = max8907_i2c_remove,
328 .id_table = max8907_i2c_id,
329};
330
331static int __init max8907_i2c_init(void)
332{
333 int ret = -ENODEV;
334
335 ret = i2c_add_driver(&max8907_i2c_driver);
336 if (ret != 0)
337 pr_err("Failed to register I2C driver: %d\n", ret);
338
339 return ret;
340}
341subsys_initcall(max8907_i2c_init);
342
343static void __exit max8907_i2c_exit(void)
344{
345 i2c_del_driver(&max8907_i2c_driver);
346}
347module_exit(max8907_i2c_exit);
348
349MODULE_DESCRIPTION("MAX8907 multi-function core driver");
350MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
351MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index ee53757beca7..9f54c04912f2 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -15,23 +15,20 @@
15#include <linux/irq.h> 15#include <linux/irq.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/regulator/machine.h>
18#include <linux/mfd/core.h> 19#include <linux/mfd/core.h>
19#include <linux/mfd/max8925.h> 20#include <linux/mfd/max8925.h>
20 21
21static struct resource backlight_resources[] = { 22static struct resource bk_resources[] __devinitdata = {
22 { 23 { 0x84, 0x84, "mode control", IORESOURCE_REG, },
23 .name = "max8925-backlight", 24 { 0x85, 0x85, "control", IORESOURCE_REG, },
24 .start = MAX8925_WLED_MODE_CNTL,
25 .end = MAX8925_WLED_CNTL,
26 .flags = IORESOURCE_IO,
27 },
28}; 25};
29 26
30static struct mfd_cell backlight_devs[] = { 27static struct mfd_cell bk_devs[] __devinitdata = {
31 { 28 {
32 .name = "max8925-backlight", 29 .name = "max8925-backlight",
33 .num_resources = 1, 30 .num_resources = ARRAY_SIZE(bk_resources),
34 .resources = &backlight_resources[0], 31 .resources = &bk_resources[0],
35 .id = -1, 32 .id = -1,
36 }, 33 },
37}; 34};
@@ -41,7 +38,7 @@ static struct resource touch_resources[] = {
41 .name = "max8925-tsc", 38 .name = "max8925-tsc",
42 .start = MAX8925_TSC_IRQ, 39 .start = MAX8925_TSC_IRQ,
43 .end = MAX8925_ADC_RES_END, 40 .end = MAX8925_ADC_RES_END,
44 .flags = IORESOURCE_IO, 41 .flags = IORESOURCE_REG,
45 }, 42 },
46}; 43};
47 44
@@ -59,7 +56,7 @@ static struct resource power_supply_resources[] = {
59 .name = "max8925-power", 56 .name = "max8925-power",
60 .start = MAX8925_CHG_IRQ1, 57 .start = MAX8925_CHG_IRQ1,
61 .end = MAX8925_CHG_IRQ1_MASK, 58 .end = MAX8925_CHG_IRQ1_MASK,
62 .flags = IORESOURCE_IO, 59 .flags = IORESOURCE_REG,
63 }, 60 },
64}; 61};
65 62
@@ -113,71 +110,215 @@ static struct mfd_cell onkey_devs[] = {
113 }, 110 },
114}; 111};
115 112
116#define MAX8925_REG_RESOURCE(_start, _end) \ 113static struct resource sd1_resources[] __devinitdata = {
117{ \ 114 {0x06, 0x06, "sdv", IORESOURCE_REG, },
118 .start = MAX8925_##_start, \ 115};
119 .end = MAX8925_##_end, \
120 .flags = IORESOURCE_IO, \
121}
122 116
123static struct resource regulator_resources[] = { 117static struct resource sd2_resources[] __devinitdata = {
124 MAX8925_REG_RESOURCE(SDCTL1, SDCTL1), 118 {0x09, 0x09, "sdv", IORESOURCE_REG, },
125 MAX8925_REG_RESOURCE(SDCTL2, SDCTL2), 119};
126 MAX8925_REG_RESOURCE(SDCTL3, SDCTL3), 120
127 MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1), 121static struct resource sd3_resources[] __devinitdata = {
128 MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2), 122 {0x0c, 0x0c, "sdv", IORESOURCE_REG, },
129 MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3), 123};
130 MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4), 124
131 MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5), 125static struct resource ldo1_resources[] __devinitdata = {
132 MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6), 126 {0x1a, 0x1a, "ldov", IORESOURCE_REG, },
133 MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7), 127};
134 MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8), 128
135 MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9), 129static struct resource ldo2_resources[] __devinitdata = {
136 MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10), 130 {0x1e, 0x1e, "ldov", IORESOURCE_REG, },
137 MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11), 131};
138 MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12), 132
139 MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13), 133static struct resource ldo3_resources[] __devinitdata = {
140 MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14), 134 {0x22, 0x22, "ldov", IORESOURCE_REG, },
141 MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15), 135};
142 MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16), 136
143 MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17), 137static struct resource ldo4_resources[] __devinitdata = {
144 MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18), 138 {0x26, 0x26, "ldov", IORESOURCE_REG, },
145 MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19), 139};
146 MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20), 140
147}; 141static struct resource ldo5_resources[] __devinitdata = {
148 142 {0x2a, 0x2a, "ldov", IORESOURCE_REG, },
149#define MAX8925_REG_DEVS(_id) \ 143};
150{ \ 144
151 .name = "max8925-regulator", \ 145static struct resource ldo6_resources[] __devinitdata = {
152 .num_resources = 1, \ 146 {0x2e, 0x2e, "ldov", IORESOURCE_REG, },
153 .resources = &regulator_resources[MAX8925_ID_##_id], \ 147};
154 .id = MAX8925_ID_##_id, \ 148
155} 149static struct resource ldo7_resources[] __devinitdata = {
150 {0x32, 0x32, "ldov", IORESOURCE_REG, },
151};
152
153static struct resource ldo8_resources[] __devinitdata = {
154 {0x36, 0x36, "ldov", IORESOURCE_REG, },
155};
156
157static struct resource ldo9_resources[] __devinitdata = {
158 {0x3a, 0x3a, "ldov", IORESOURCE_REG, },
159};
160
161static struct resource ldo10_resources[] __devinitdata = {
162 {0x3e, 0x3e, "ldov", IORESOURCE_REG, },
163};
156 164
157static struct mfd_cell regulator_devs[] = { 165static struct resource ldo11_resources[] __devinitdata = {
158 MAX8925_REG_DEVS(SD1), 166 {0x42, 0x42, "ldov", IORESOURCE_REG, },
159 MAX8925_REG_DEVS(SD2), 167};
160 MAX8925_REG_DEVS(SD3), 168
161 MAX8925_REG_DEVS(LDO1), 169static struct resource ldo12_resources[] __devinitdata = {
162 MAX8925_REG_DEVS(LDO2), 170 {0x46, 0x46, "ldov", IORESOURCE_REG, },
163 MAX8925_REG_DEVS(LDO3), 171};
164 MAX8925_REG_DEVS(LDO4), 172
165 MAX8925_REG_DEVS(LDO5), 173static struct resource ldo13_resources[] __devinitdata = {
166 MAX8925_REG_DEVS(LDO6), 174 {0x4a, 0x4a, "ldov", IORESOURCE_REG, },
167 MAX8925_REG_DEVS(LDO7), 175};
168 MAX8925_REG_DEVS(LDO8), 176
169 MAX8925_REG_DEVS(LDO9), 177static struct resource ldo14_resources[] __devinitdata = {
170 MAX8925_REG_DEVS(LDO10), 178 {0x4e, 0x4e, "ldov", IORESOURCE_REG, },
171 MAX8925_REG_DEVS(LDO11), 179};
172 MAX8925_REG_DEVS(LDO12), 180
173 MAX8925_REG_DEVS(LDO13), 181static struct resource ldo15_resources[] __devinitdata = {
174 MAX8925_REG_DEVS(LDO14), 182 {0x52, 0x52, "ldov", IORESOURCE_REG, },
175 MAX8925_REG_DEVS(LDO15), 183};
176 MAX8925_REG_DEVS(LDO16), 184
177 MAX8925_REG_DEVS(LDO17), 185static struct resource ldo16_resources[] __devinitdata = {
178 MAX8925_REG_DEVS(LDO18), 186 {0x12, 0x12, "ldov", IORESOURCE_REG, },
179 MAX8925_REG_DEVS(LDO19), 187};
180 MAX8925_REG_DEVS(LDO20), 188
189static struct resource ldo17_resources[] __devinitdata = {
190 {0x16, 0x16, "ldov", IORESOURCE_REG, },
191};
192
193static struct resource ldo18_resources[] __devinitdata = {
194 {0x74, 0x74, "ldov", IORESOURCE_REG, },
195};
196
197static struct resource ldo19_resources[] __devinitdata = {
198 {0x5e, 0x5e, "ldov", IORESOURCE_REG, },
199};
200
201static struct resource ldo20_resources[] __devinitdata = {
202 {0x9e, 0x9e, "ldov", IORESOURCE_REG, },
203};
204
205static struct mfd_cell reg_devs[] __devinitdata = {
206 {
207 .name = "max8925-regulator",
208 .id = 0,
209 .num_resources = ARRAY_SIZE(sd1_resources),
210 .resources = sd1_resources,
211 }, {
212 .name = "max8925-regulator",
213 .id = 1,
214 .num_resources = ARRAY_SIZE(sd2_resources),
215 .resources = sd2_resources,
216 }, {
217 .name = "max8925-regulator",
218 .id = 2,
219 .num_resources = ARRAY_SIZE(sd3_resources),
220 .resources = sd3_resources,
221 }, {
222 .name = "max8925-regulator",
223 .id = 3,
224 .num_resources = ARRAY_SIZE(ldo1_resources),
225 .resources = ldo1_resources,
226 }, {
227 .name = "max8925-regulator",
228 .id = 4,
229 .num_resources = ARRAY_SIZE(ldo2_resources),
230 .resources = ldo2_resources,
231 }, {
232 .name = "max8925-regulator",
233 .id = 5,
234 .num_resources = ARRAY_SIZE(ldo3_resources),
235 .resources = ldo3_resources,
236 }, {
237 .name = "max8925-regulator",
238 .id = 6,
239 .num_resources = ARRAY_SIZE(ldo4_resources),
240 .resources = ldo4_resources,
241 }, {
242 .name = "max8925-regulator",
243 .id = 7,
244 .num_resources = ARRAY_SIZE(ldo5_resources),
245 .resources = ldo5_resources,
246 }, {
247 .name = "max8925-regulator",
248 .id = 8,
249 .num_resources = ARRAY_SIZE(ldo6_resources),
250 .resources = ldo6_resources,
251 }, {
252 .name = "max8925-regulator",
253 .id = 9,
254 .num_resources = ARRAY_SIZE(ldo7_resources),
255 .resources = ldo7_resources,
256 }, {
257 .name = "max8925-regulator",
258 .id = 10,
259 .num_resources = ARRAY_SIZE(ldo8_resources),
260 .resources = ldo8_resources,
261 }, {
262 .name = "max8925-regulator",
263 .id = 11,
264 .num_resources = ARRAY_SIZE(ldo9_resources),
265 .resources = ldo9_resources,
266 }, {
267 .name = "max8925-regulator",
268 .id = 12,
269 .num_resources = ARRAY_SIZE(ldo10_resources),
270 .resources = ldo10_resources,
271 }, {
272 .name = "max8925-regulator",
273 .id = 13,
274 .num_resources = ARRAY_SIZE(ldo11_resources),
275 .resources = ldo11_resources,
276 }, {
277 .name = "max8925-regulator",
278 .id = 14,
279 .num_resources = ARRAY_SIZE(ldo12_resources),
280 .resources = ldo12_resources,
281 }, {
282 .name = "max8925-regulator",
283 .id = 15,
284 .num_resources = ARRAY_SIZE(ldo13_resources),
285 .resources = ldo13_resources,
286 }, {
287 .name = "max8925-regulator",
288 .id = 16,
289 .num_resources = ARRAY_SIZE(ldo14_resources),
290 .resources = ldo14_resources,
291 }, {
292 .name = "max8925-regulator",
293 .id = 17,
294 .num_resources = ARRAY_SIZE(ldo15_resources),
295 .resources = ldo15_resources,
296 }, {
297 .name = "max8925-regulator",
298 .id = 18,
299 .num_resources = ARRAY_SIZE(ldo16_resources),
300 .resources = ldo16_resources,
301 }, {
302 .name = "max8925-regulator",
303 .id = 19,
304 .num_resources = ARRAY_SIZE(ldo17_resources),
305 .resources = ldo17_resources,
306 }, {
307 .name = "max8925-regulator",
308 .id = 20,
309 .num_resources = ARRAY_SIZE(ldo18_resources),
310 .resources = ldo18_resources,
311 }, {
312 .name = "max8925-regulator",
313 .id = 21,
314 .num_resources = ARRAY_SIZE(ldo19_resources),
315 .resources = ldo19_resources,
316 }, {
317 .name = "max8925-regulator",
318 .id = 22,
319 .num_resources = ARRAY_SIZE(ldo20_resources),
320 .resources = ldo20_resources,
321 },
181}; 322};
182 323
183enum { 324enum {
@@ -547,7 +688,7 @@ static int max8925_irq_init(struct max8925_chip *chip, int irq,
547 goto tsc_irq; 688 goto tsc_irq;
548 } 689 }
549 690
550 ret = request_threaded_irq(irq, NULL, max8925_irq, flags, 691 ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT,
551 "max8925", chip); 692 "max8925", chip);
552 if (ret) { 693 if (ret) {
553 dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret); 694 dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
@@ -565,7 +706,7 @@ tsc_irq:
565 chip->tsc_irq = pdata->tsc_irq; 706 chip->tsc_irq = pdata->tsc_irq;
566 707
567 ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq, 708 ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
568 flags, "max8925-tsc", chip); 709 flags | IRQF_ONESHOT, "max8925-tsc", chip);
569 if (ret) { 710 if (ret) {
570 dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret); 711 dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
571 chip->tsc_irq = 0; 712 chip->tsc_irq = 0;
@@ -573,6 +714,113 @@ tsc_irq:
573 return 0; 714 return 0;
574} 715}
575 716
717static void __devinit init_regulator(struct max8925_chip *chip,
718 struct max8925_platform_data *pdata)
719{
720 int ret;
721
722 if (!pdata)
723 return;
724 if (pdata->sd1) {
725 reg_devs[0].platform_data = pdata->sd1;
726 reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
727 }
728 if (pdata->sd2) {
729 reg_devs[1].platform_data = pdata->sd2;
730 reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
731 }
732 if (pdata->sd3) {
733 reg_devs[2].platform_data = pdata->sd3;
734 reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
735 }
736 if (pdata->ldo1) {
737 reg_devs[3].platform_data = pdata->ldo1;
738 reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
739 }
740 if (pdata->ldo2) {
741 reg_devs[4].platform_data = pdata->ldo2;
742 reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
743 }
744 if (pdata->ldo3) {
745 reg_devs[5].platform_data = pdata->ldo3;
746 reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
747 }
748 if (pdata->ldo4) {
749 reg_devs[6].platform_data = pdata->ldo4;
750 reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
751 }
752 if (pdata->ldo5) {
753 reg_devs[7].platform_data = pdata->ldo5;
754 reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
755 }
756 if (pdata->ldo6) {
757 reg_devs[8].platform_data = pdata->ldo6;
758 reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
759 }
760 if (pdata->ldo7) {
761 reg_devs[9].platform_data = pdata->ldo7;
762 reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
763 }
764 if (pdata->ldo8) {
765 reg_devs[10].platform_data = pdata->ldo8;
766 reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
767 }
768 if (pdata->ldo9) {
769 reg_devs[11].platform_data = pdata->ldo9;
770 reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
771 }
772 if (pdata->ldo10) {
773 reg_devs[12].platform_data = pdata->ldo10;
774 reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
775 }
776 if (pdata->ldo11) {
777 reg_devs[13].platform_data = pdata->ldo11;
778 reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
779 }
780 if (pdata->ldo12) {
781 reg_devs[14].platform_data = pdata->ldo12;
782 reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
783 }
784 if (pdata->ldo13) {
785 reg_devs[15].platform_data = pdata->ldo13;
786 reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
787 }
788 if (pdata->ldo14) {
789 reg_devs[16].platform_data = pdata->ldo14;
790 reg_devs[16].pdata_size = sizeof(struct regulator_init_data);
791 }
792 if (pdata->ldo15) {
793 reg_devs[17].platform_data = pdata->ldo15;
794 reg_devs[17].pdata_size = sizeof(struct regulator_init_data);
795 }
796 if (pdata->ldo16) {
797 reg_devs[18].platform_data = pdata->ldo16;
798 reg_devs[18].pdata_size = sizeof(struct regulator_init_data);
799 }
800 if (pdata->ldo17) {
801 reg_devs[19].platform_data = pdata->ldo17;
802 reg_devs[19].pdata_size = sizeof(struct regulator_init_data);
803 }
804 if (pdata->ldo18) {
805 reg_devs[20].platform_data = pdata->ldo18;
806 reg_devs[20].pdata_size = sizeof(struct regulator_init_data);
807 }
808 if (pdata->ldo19) {
809 reg_devs[21].platform_data = pdata->ldo19;
810 reg_devs[21].pdata_size = sizeof(struct regulator_init_data);
811 }
812 if (pdata->ldo20) {
813 reg_devs[22].platform_data = pdata->ldo20;
814 reg_devs[22].pdata_size = sizeof(struct regulator_init_data);
815 }
816 ret = mfd_add_devices(chip->dev, 0, reg_devs, ARRAY_SIZE(reg_devs),
817 NULL, 0, NULL);
818 if (ret < 0) {
819 dev_err(chip->dev, "Failed to add regulator subdev\n");
820 return;
821 }
822}
823
576int __devinit max8925_device_init(struct max8925_chip *chip, 824int __devinit max8925_device_init(struct max8925_chip *chip,
577 struct max8925_platform_data *pdata) 825 struct max8925_platform_data *pdata)
578{ 826{
@@ -612,24 +860,17 @@ int __devinit max8925_device_init(struct max8925_chip *chip,
612 goto out_dev; 860 goto out_dev;
613 } 861 }
614 862
615 if (pdata) { 863 init_regulator(chip, pdata);
616 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
617 ARRAY_SIZE(regulator_devs),
618 &regulator_resources[0], 0, NULL);
619 if (ret < 0) {
620 dev_err(chip->dev, "Failed to add regulator subdev\n");
621 goto out_dev;
622 }
623 }
624 864
625 if (pdata && pdata->backlight) { 865 if (pdata && pdata->backlight) {
626 ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], 866 bk_devs[0].platform_data = &pdata->backlight;
627 ARRAY_SIZE(backlight_devs), 867 bk_devs[0].pdata_size = sizeof(struct max8925_backlight_pdata);
628 &backlight_resources[0], 0, NULL); 868 }
629 if (ret < 0) { 869 ret = mfd_add_devices(chip->dev, 0, bk_devs, ARRAY_SIZE(bk_devs),
630 dev_err(chip->dev, "Failed to add backlight subdev\n"); 870 NULL, 0, NULL);
631 goto out_dev; 871 if (ret < 0) {
632 } 872 dev_err(chip->dev, "Failed to add backlight subdev\n");
873 goto out_dev;
633 } 874 }
634 875
635 if (pdata && pdata->power) { 876 if (pdata && pdata->power) {
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 1ec79b54bd2f..1aba0238f426 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -676,7 +676,6 @@ int mc13xxx_common_init(struct mc13xxx *mc13xxx,
676err_mask: 676err_mask:
677err_revision: 677err_revision:
678 mc13xxx_unlock(mc13xxx); 678 mc13xxx_unlock(mc13xxx);
679 kfree(mc13xxx);
680 return ret; 679 return ret;
681 } 680 }
682 681
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 41088ecbb2a9..23cec57c02ba 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -21,7 +21,6 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/platform_device.h>
25#include <linux/clk.h> 24#include <linux/clk.h>
26#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
27#include <linux/spinlock.h> 26#include <linux/spinlock.h>
@@ -36,63 +35,6 @@
36 35
37/* OMAP USBHOST Register addresses */ 36/* OMAP USBHOST Register addresses */
38 37
39/* TLL Register Set */
40#define OMAP_USBTLL_REVISION (0x00)
41#define OMAP_USBTLL_SYSCONFIG (0x10)
42#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8)
43#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3)
44#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2)
45#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1)
46#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0)
47
48#define OMAP_USBTLL_SYSSTATUS (0x14)
49#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0)
50
51#define OMAP_USBTLL_IRQSTATUS (0x18)
52#define OMAP_USBTLL_IRQENABLE (0x1C)
53
54#define OMAP_TLL_SHARED_CONF (0x30)
55#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6)
56#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5)
57#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2)
58#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1)
59#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0)
60
61#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
62#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
63#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
64#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
65#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
66#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
67#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
68#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
69
70#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0
71#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1
72#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2
73#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3
74#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4
75#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5
76#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6
77#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7
78#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA
79#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB
80
81#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num)
82#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num)
83#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num)
84#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num)
85#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num)
86#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num)
87#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num)
88#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num)
89#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num)
90
91#define OMAP_TLL_CHANNEL_COUNT 3
92#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0)
93#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1)
94#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2)
95
96/* UHH Register Set */ 38/* UHH Register Set */
97#define OMAP_UHH_REVISION (0x00) 39#define OMAP_UHH_REVISION (0x00)
98#define OMAP_UHH_SYSCONFIG (0x10) 40#define OMAP_UHH_SYSCONFIG (0x10)
@@ -132,8 +74,6 @@
132#define OMAP4_P2_MODE_TLL (1 << 18) 74#define OMAP4_P2_MODE_TLL (1 << 18)
133#define OMAP4_P2_MODE_HSIC (3 << 18) 75#define OMAP4_P2_MODE_HSIC (3 << 18)
134 76
135#define OMAP_REV2_TLL_CHANNEL_COUNT 2
136
137#define OMAP_UHH_DEBUG_CSR (0x44) 77#define OMAP_UHH_DEBUG_CSR (0x44)
138 78
139/* Values of UHH_REVISION - Note: these are not given in the TRM */ 79/* Values of UHH_REVISION - Note: these are not given in the TRM */
@@ -153,15 +93,12 @@ struct usbhs_hcd_omap {
153 struct clk *xclk60mhsp2_ck; 93 struct clk *xclk60mhsp2_ck;
154 struct clk *utmi_p1_fck; 94 struct clk *utmi_p1_fck;
155 struct clk *usbhost_p1_fck; 95 struct clk *usbhost_p1_fck;
156 struct clk *usbtll_p1_fck;
157 struct clk *utmi_p2_fck; 96 struct clk *utmi_p2_fck;
158 struct clk *usbhost_p2_fck; 97 struct clk *usbhost_p2_fck;
159 struct clk *usbtll_p2_fck;
160 struct clk *init_60m_fclk; 98 struct clk *init_60m_fclk;
161 struct clk *ehci_logic_fck; 99 struct clk *ehci_logic_fck;
162 100
163 void __iomem *uhh_base; 101 void __iomem *uhh_base;
164 void __iomem *tll_base;
165 102
166 struct usbhs_omap_platform_data platdata; 103 struct usbhs_omap_platform_data platdata;
167 104
@@ -336,93 +273,6 @@ static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
336 } 273 }
337} 274}
338 275
339/*
340 * convert the port-mode enum to a value we can use in the FSLSMODE
341 * field of USBTLL_CHANNEL_CONF
342 */
343static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
344{
345 switch (mode) {
346 case OMAP_USBHS_PORT_MODE_UNUSED:
347 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
348 return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
349
350 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
351 return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
352
353 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
354 return OMAP_TLL_FSLSMODE_3PIN_PHY;
355
356 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
357 return OMAP_TLL_FSLSMODE_4PIN_PHY;
358
359 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
360 return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
361
362 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
363 return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
364
365 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
366 return OMAP_TLL_FSLSMODE_3PIN_TLL;
367
368 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
369 return OMAP_TLL_FSLSMODE_4PIN_TLL;
370
371 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
372 return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
373
374 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
375 return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
376 default:
377 pr_warning("Invalid port mode, using default\n");
378 return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
379 }
380}
381
382static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
383{
384 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
385 struct usbhs_omap_platform_data *pdata = dev->platform_data;
386 unsigned reg;
387 int i;
388
389 /* Program Common TLL register */
390 reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF);
391 reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
392 | OMAP_TLL_SHARED_CONF_USB_DIVRATION);
393 reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
394 reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
395
396 usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
397
398 /* Enable channels now */
399 for (i = 0; i < tll_channel_count; i++) {
400 reg = usbhs_read(omap->tll_base,
401 OMAP_TLL_CHANNEL_CONF(i));
402
403 if (is_ohci_port(pdata->port_mode[i])) {
404 reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
405 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
406 reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
407 } else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) {
408
409 /* Disable AutoIdle, BitStuffing and use SDR Mode */
410 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
411 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
412 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
413
414 } else
415 continue;
416
417 reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
418 usbhs_write(omap->tll_base,
419 OMAP_TLL_CHANNEL_CONF(i), reg);
420
421 usbhs_writeb(omap->tll_base,
422 OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
423 }
424}
425
426static int usbhs_runtime_resume(struct device *dev) 276static int usbhs_runtime_resume(struct device *dev)
427{ 277{
428 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); 278 struct usbhs_hcd_omap *omap = dev_get_drvdata(dev);
@@ -436,19 +286,17 @@ static int usbhs_runtime_resume(struct device *dev)
436 return -ENODEV; 286 return -ENODEV;
437 } 287 }
438 288
289 omap_tll_enable();
439 spin_lock_irqsave(&omap->lock, flags); 290 spin_lock_irqsave(&omap->lock, flags);
440 291
441 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck)) 292 if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
442 clk_enable(omap->ehci_logic_fck); 293 clk_enable(omap->ehci_logic_fck);
443 294
444 if (is_ehci_tll_mode(pdata->port_mode[0])) { 295 if (is_ehci_tll_mode(pdata->port_mode[0]))
445 clk_enable(omap->usbhost_p1_fck); 296 clk_enable(omap->usbhost_p1_fck);
446 clk_enable(omap->usbtll_p1_fck); 297 if (is_ehci_tll_mode(pdata->port_mode[1]))
447 }
448 if (is_ehci_tll_mode(pdata->port_mode[1])) {
449 clk_enable(omap->usbhost_p2_fck); 298 clk_enable(omap->usbhost_p2_fck);
450 clk_enable(omap->usbtll_p2_fck); 299
451 }
452 clk_enable(omap->utmi_p1_fck); 300 clk_enable(omap->utmi_p1_fck);
453 clk_enable(omap->utmi_p2_fck); 301 clk_enable(omap->utmi_p2_fck);
454 302
@@ -472,14 +320,11 @@ static int usbhs_runtime_suspend(struct device *dev)
472 320
473 spin_lock_irqsave(&omap->lock, flags); 321 spin_lock_irqsave(&omap->lock, flags);
474 322
475 if (is_ehci_tll_mode(pdata->port_mode[0])) { 323 if (is_ehci_tll_mode(pdata->port_mode[0]))
476 clk_disable(omap->usbhost_p1_fck); 324 clk_disable(omap->usbhost_p1_fck);
477 clk_disable(omap->usbtll_p1_fck); 325 if (is_ehci_tll_mode(pdata->port_mode[1]))
478 }
479 if (is_ehci_tll_mode(pdata->port_mode[1])) {
480 clk_disable(omap->usbhost_p2_fck); 326 clk_disable(omap->usbhost_p2_fck);
481 clk_disable(omap->usbtll_p2_fck); 327
482 }
483 clk_disable(omap->utmi_p2_fck); 328 clk_disable(omap->utmi_p2_fck);
484 clk_disable(omap->utmi_p1_fck); 329 clk_disable(omap->utmi_p1_fck);
485 330
@@ -487,6 +332,7 @@ static int usbhs_runtime_suspend(struct device *dev)
487 clk_disable(omap->ehci_logic_fck); 332 clk_disable(omap->ehci_logic_fck);
488 333
489 spin_unlock_irqrestore(&omap->lock, flags); 334 spin_unlock_irqrestore(&omap->lock, flags);
335 omap_tll_disable();
490 336
491 return 0; 337 return 0;
492} 338}
@@ -500,8 +346,6 @@ static void omap_usbhs_init(struct device *dev)
500 346
501 dev_dbg(dev, "starting TI HSUSB Controller\n"); 347 dev_dbg(dev, "starting TI HSUSB Controller\n");
502 348
503 pm_runtime_get_sync(dev);
504
505 if (pdata->ehci_data->phy_reset) { 349 if (pdata->ehci_data->phy_reset) {
506 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) 350 if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
507 gpio_request_one(pdata->ehci_data->reset_gpio_port[0], 351 gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
@@ -515,6 +359,7 @@ static void omap_usbhs_init(struct device *dev)
515 udelay(10); 359 udelay(10);
516 } 360 }
517 361
362 pm_runtime_get_sync(dev);
518 spin_lock_irqsave(&omap->lock, flags); 363 spin_lock_irqsave(&omap->lock, flags);
519 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); 364 omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
520 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); 365 dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
@@ -580,22 +425,9 @@ static void omap_usbhs_init(struct device *dev)
580 usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg); 425 usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
581 dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg); 426 dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
582 427
583 if (is_ehci_tll_mode(pdata->port_mode[0]) ||
584 is_ehci_tll_mode(pdata->port_mode[1]) ||
585 is_ehci_tll_mode(pdata->port_mode[2]) ||
586 (is_ohci_port(pdata->port_mode[0])) ||
587 (is_ohci_port(pdata->port_mode[1])) ||
588 (is_ohci_port(pdata->port_mode[2]))) {
589
590 /* Enable UTMI mode for required TLL channels */
591 if (is_omap_usbhs_rev2(omap))
592 usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT);
593 else
594 usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
595 }
596
597 spin_unlock_irqrestore(&omap->lock, flags); 428 spin_unlock_irqrestore(&omap->lock, flags);
598 429
430 pm_runtime_put_sync(dev);
599 if (pdata->ehci_data->phy_reset) { 431 if (pdata->ehci_data->phy_reset) {
600 /* Hold the PHY in RESET for enough time till 432 /* Hold the PHY in RESET for enough time till
601 * PHY is settled and ready 433 * PHY is settled and ready
@@ -610,8 +442,6 @@ static void omap_usbhs_init(struct device *dev)
610 gpio_set_value_cansleep 442 gpio_set_value_cansleep
611 (pdata->ehci_data->reset_gpio_port[1], 1); 443 (pdata->ehci_data->reset_gpio_port[1], 1);
612 } 444 }
613
614 pm_runtime_put_sync(dev);
615} 445}
616 446
617static void omap_usbhs_deinit(struct device *dev) 447static void omap_usbhs_deinit(struct device *dev)
@@ -714,32 +544,18 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
714 goto err_xclk60mhsp2_ck; 544 goto err_xclk60mhsp2_ck;
715 } 545 }
716 546
717 omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
718 if (IS_ERR(omap->usbtll_p1_fck)) {
719 ret = PTR_ERR(omap->usbtll_p1_fck);
720 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
721 goto err_usbhost_p1_fck;
722 }
723
724 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); 547 omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
725 if (IS_ERR(omap->usbhost_p2_fck)) { 548 if (IS_ERR(omap->usbhost_p2_fck)) {
726 ret = PTR_ERR(omap->usbhost_p2_fck); 549 ret = PTR_ERR(omap->usbhost_p2_fck);
727 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); 550 dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
728 goto err_usbtll_p1_fck; 551 goto err_usbhost_p1_fck;
729 }
730
731 omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
732 if (IS_ERR(omap->usbtll_p2_fck)) {
733 ret = PTR_ERR(omap->usbtll_p2_fck);
734 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
735 goto err_usbhost_p2_fck;
736 } 552 }
737 553
738 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); 554 omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
739 if (IS_ERR(omap->init_60m_fclk)) { 555 if (IS_ERR(omap->init_60m_fclk)) {
740 ret = PTR_ERR(omap->init_60m_fclk); 556 ret = PTR_ERR(omap->init_60m_fclk);
741 dev_err(dev, "init_60m_fclk failed error:%d\n", ret); 557 dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
742 goto err_usbtll_p2_fck; 558 goto err_usbhost_p2_fck;
743 } 559 }
744 560
745 if (is_ehci_phy_mode(pdata->port_mode[0])) { 561 if (is_ehci_phy_mode(pdata->port_mode[0])) {
@@ -785,20 +601,6 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
785 goto err_init_60m_fclk; 601 goto err_init_60m_fclk;
786 } 602 }
787 603
788 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
789 if (!res) {
790 dev_err(dev, "UHH EHCI get resource failed\n");
791 ret = -ENODEV;
792 goto err_tll;
793 }
794
795 omap->tll_base = ioremap(res->start, resource_size(res));
796 if (!omap->tll_base) {
797 dev_err(dev, "TLL ioremap failed\n");
798 ret = -ENOMEM;
799 goto err_tll;
800 }
801
802 platform_set_drvdata(pdev, omap); 604 platform_set_drvdata(pdev, omap);
803 605
804 omap_usbhs_init(dev); 606 omap_usbhs_init(dev);
@@ -812,23 +614,14 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev)
812 614
813err_alloc: 615err_alloc:
814 omap_usbhs_deinit(&pdev->dev); 616 omap_usbhs_deinit(&pdev->dev);
815 iounmap(omap->tll_base);
816
817err_tll:
818 iounmap(omap->uhh_base); 617 iounmap(omap->uhh_base);
819 618
820err_init_60m_fclk: 619err_init_60m_fclk:
821 clk_put(omap->init_60m_fclk); 620 clk_put(omap->init_60m_fclk);
822 621
823err_usbtll_p2_fck:
824 clk_put(omap->usbtll_p2_fck);
825
826err_usbhost_p2_fck: 622err_usbhost_p2_fck:
827 clk_put(omap->usbhost_p2_fck); 623 clk_put(omap->usbhost_p2_fck);
828 624
829err_usbtll_p1_fck:
830 clk_put(omap->usbtll_p1_fck);
831
832err_usbhost_p1_fck: 625err_usbhost_p1_fck:
833 clk_put(omap->usbhost_p1_fck); 626 clk_put(omap->usbhost_p1_fck);
834 627
@@ -864,12 +657,9 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev)
864 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); 657 struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
865 658
866 omap_usbhs_deinit(&pdev->dev); 659 omap_usbhs_deinit(&pdev->dev);
867 iounmap(omap->tll_base);
868 iounmap(omap->uhh_base); 660 iounmap(omap->uhh_base);
869 clk_put(omap->init_60m_fclk); 661 clk_put(omap->init_60m_fclk);
870 clk_put(omap->usbtll_p2_fck);
871 clk_put(omap->usbhost_p2_fck); 662 clk_put(omap->usbhost_p2_fck);
872 clk_put(omap->usbtll_p1_fck);
873 clk_put(omap->usbhost_p1_fck); 663 clk_put(omap->usbhost_p1_fck);
874 clk_put(omap->xclk60mhsp2_ck); 664 clk_put(omap->xclk60mhsp2_ck);
875 clk_put(omap->utmi_p2_fck); 665 clk_put(omap->utmi_p2_fck);
@@ -910,8 +700,10 @@ static int __init omap_usbhs_drvinit(void)
910 * init before ehci and ohci drivers; 700 * init before ehci and ohci drivers;
911 * The usbhs core driver should be initialized much before 701 * The usbhs core driver should be initialized much before
912 * the omap ehci and ohci probe functions are called. 702 * the omap ehci and ohci probe functions are called.
703 * This usbhs core driver should be initialized after
704 * usb tll driver
913 */ 705 */
914fs_initcall(omap_usbhs_drvinit); 706fs_initcall_sync(omap_usbhs_drvinit);
915 707
916static void __exit omap_usbhs_drvexit(void) 708static void __exit omap_usbhs_drvexit(void)
917{ 709{
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
new file mode 100644
index 000000000000..4b7757b84301
--- /dev/null
+++ b/drivers/mfd/omap-usb-tll.c
@@ -0,0 +1,471 @@
1/**
2 * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 * Author: Keshava Munegowda <keshava_mgowda@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
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, see <http://www.gnu.org/licenses/>.
18 */
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/slab.h>
23#include <linux/spinlock.h>
24#include <linux/platform_device.h>
25#include <linux/clk.h>
26#include <linux/io.h>
27#include <linux/err.h>
28#include <plat/usb.h>
29#include <linux/pm_runtime.h>
30
31#define USBTLL_DRIVER_NAME "usbhs_tll"
32
33/* TLL Register Set */
34#define OMAP_USBTLL_REVISION (0x00)
35#define OMAP_USBTLL_SYSCONFIG (0x10)
36#define OMAP_USBTLL_SYSCONFIG_CACTIVITY (1 << 8)
37#define OMAP_USBTLL_SYSCONFIG_SIDLEMODE (1 << 3)
38#define OMAP_USBTLL_SYSCONFIG_ENAWAKEUP (1 << 2)
39#define OMAP_USBTLL_SYSCONFIG_SOFTRESET (1 << 1)
40#define OMAP_USBTLL_SYSCONFIG_AUTOIDLE (1 << 0)
41
42#define OMAP_USBTLL_SYSSTATUS (0x14)
43#define OMAP_USBTLL_SYSSTATUS_RESETDONE (1 << 0)
44
45#define OMAP_USBTLL_IRQSTATUS (0x18)
46#define OMAP_USBTLL_IRQENABLE (0x1C)
47
48#define OMAP_TLL_SHARED_CONF (0x30)
49#define OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN (1 << 6)
50#define OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN (1 << 5)
51#define OMAP_TLL_SHARED_CONF_USB_DIVRATION (1 << 2)
52#define OMAP_TLL_SHARED_CONF_FCLK_REQ (1 << 1)
53#define OMAP_TLL_SHARED_CONF_FCLK_IS_ON (1 << 0)
54
55#define OMAP_TLL_CHANNEL_CONF(num) (0x040 + 0x004 * num)
56#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT 24
57#define OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF (1 << 11)
58#define OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE (1 << 10)
59#define OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE (1 << 9)
60#define OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE (1 << 8)
61#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS (1 << 1)
62#define OMAP_TLL_CHANNEL_CONF_CHANEN (1 << 0)
63
64#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0 0x0
65#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM 0x1
66#define OMAP_TLL_FSLSMODE_3PIN_PHY 0x2
67#define OMAP_TLL_FSLSMODE_4PIN_PHY 0x3
68#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0 0x4
69#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM 0x5
70#define OMAP_TLL_FSLSMODE_3PIN_TLL 0x6
71#define OMAP_TLL_FSLSMODE_4PIN_TLL 0x7
72#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0 0xA
73#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM 0xB
74
75#define OMAP_TLL_ULPI_FUNCTION_CTRL(num) (0x804 + 0x100 * num)
76#define OMAP_TLL_ULPI_INTERFACE_CTRL(num) (0x807 + 0x100 * num)
77#define OMAP_TLL_ULPI_OTG_CTRL(num) (0x80A + 0x100 * num)
78#define OMAP_TLL_ULPI_INT_EN_RISE(num) (0x80D + 0x100 * num)
79#define OMAP_TLL_ULPI_INT_EN_FALL(num) (0x810 + 0x100 * num)
80#define OMAP_TLL_ULPI_INT_STATUS(num) (0x813 + 0x100 * num)
81#define OMAP_TLL_ULPI_INT_LATCH(num) (0x814 + 0x100 * num)
82#define OMAP_TLL_ULPI_DEBUG(num) (0x815 + 0x100 * num)
83#define OMAP_TLL_ULPI_SCRATCH_REGISTER(num) (0x816 + 0x100 * num)
84
85#define OMAP_REV2_TLL_CHANNEL_COUNT 2
86#define OMAP_TLL_CHANNEL_COUNT 3
87#define OMAP_TLL_CHANNEL_1_EN_MASK (1 << 0)
88#define OMAP_TLL_CHANNEL_2_EN_MASK (1 << 1)
89#define OMAP_TLL_CHANNEL_3_EN_MASK (1 << 2)
90
91/* Values of USBTLL_REVISION - Note: these are not given in the TRM */
92#define OMAP_USBTLL_REV1 0x00000015 /* OMAP3 */
93#define OMAP_USBTLL_REV2 0x00000018 /* OMAP 3630 */
94#define OMAP_USBTLL_REV3 0x00000004 /* OMAP4 */
95
96#define is_ehci_tll_mode(x) (x == OMAP_EHCI_PORT_MODE_TLL)
97
98struct usbtll_omap {
99 struct clk *usbtll_p1_fck;
100 struct clk *usbtll_p2_fck;
101 struct usbtll_omap_platform_data platdata;
102 /* secure the register updates */
103 spinlock_t lock;
104};
105
106/*-------------------------------------------------------------------------*/
107
108const char usbtll_driver_name[] = USBTLL_DRIVER_NAME;
109struct platform_device *tll_pdev;
110
111/*-------------------------------------------------------------------------*/
112
113static inline void usbtll_write(void __iomem *base, u32 reg, u32 val)
114{
115 __raw_writel(val, base + reg);
116}
117
118static inline u32 usbtll_read(void __iomem *base, u32 reg)
119{
120 return __raw_readl(base + reg);
121}
122
123static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
124{
125 __raw_writeb(val, base + reg);
126}
127
128static inline u8 usbtll_readb(void __iomem *base, u8 reg)
129{
130 return __raw_readb(base + reg);
131}
132
133/*-------------------------------------------------------------------------*/
134
135static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
136{
137 switch (pmode) {
138 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
139 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
140 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
141 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
142 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
143 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
144 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
145 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
146 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
147 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
148 return true;
149
150 default:
151 return false;
152 }
153}
154
155/*
156 * convert the port-mode enum to a value we can use in the FSLSMODE
157 * field of USBTLL_CHANNEL_CONF
158 */
159static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
160{
161 switch (mode) {
162 case OMAP_USBHS_PORT_MODE_UNUSED:
163 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
164 return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
165
166 case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
167 return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
168
169 case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
170 return OMAP_TLL_FSLSMODE_3PIN_PHY;
171
172 case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
173 return OMAP_TLL_FSLSMODE_4PIN_PHY;
174
175 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
176 return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
177
178 case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
179 return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
180
181 case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
182 return OMAP_TLL_FSLSMODE_3PIN_TLL;
183
184 case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
185 return OMAP_TLL_FSLSMODE_4PIN_TLL;
186
187 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
188 return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
189
190 case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
191 return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
192 default:
193 pr_warn("Invalid port mode, using default\n");
194 return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
195 }
196}
197
198/**
199 * usbtll_omap_probe - initialize TI-based HCDs
200 *
201 * Allocates basic resources for this USB host controller.
202 */
203static int __devinit usbtll_omap_probe(struct platform_device *pdev)
204{
205 struct device *dev = &pdev->dev;
206 struct usbtll_omap_platform_data *pdata = dev->platform_data;
207 void __iomem *base;
208 struct resource *res;
209 struct usbtll_omap *tll;
210 unsigned reg;
211 unsigned long flags;
212 int ret = 0;
213 int i, ver, count;
214
215 dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
216
217 tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL);
218 if (!tll) {
219 dev_err(dev, "Memory allocation failed\n");
220 ret = -ENOMEM;
221 goto end;
222 }
223
224 spin_lock_init(&tll->lock);
225
226 for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
227 tll->platdata.port_mode[i] = pdata->port_mode[i];
228
229 tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
230 if (IS_ERR(tll->usbtll_p1_fck)) {
231 ret = PTR_ERR(tll->usbtll_p1_fck);
232 dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
233 goto err_tll;
234 }
235
236 tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
237 if (IS_ERR(tll->usbtll_p2_fck)) {
238 ret = PTR_ERR(tll->usbtll_p2_fck);
239 dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
240 goto err_usbtll_p1_fck;
241 }
242
243 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
244 if (!res) {
245 dev_err(dev, "usb tll get resource failed\n");
246 ret = -ENODEV;
247 goto err_usbtll_p2_fck;
248 }
249
250 base = ioremap(res->start, resource_size(res));
251 if (!base) {
252 dev_err(dev, "TLL ioremap failed\n");
253 ret = -ENOMEM;
254 goto err_usbtll_p2_fck;
255 }
256
257 platform_set_drvdata(pdev, tll);
258 pm_runtime_enable(dev);
259 pm_runtime_get_sync(dev);
260
261 spin_lock_irqsave(&tll->lock, flags);
262
263 ver = usbtll_read(base, OMAP_USBTLL_REVISION);
264 switch (ver) {
265 case OMAP_USBTLL_REV1:
266 case OMAP_USBTLL_REV2:
267 count = OMAP_TLL_CHANNEL_COUNT;
268 break;
269 case OMAP_USBTLL_REV3:
270 count = OMAP_REV2_TLL_CHANNEL_COUNT;
271 break;
272 default:
273 dev_err(dev, "TLL version failed\n");
274 ret = -ENODEV;
275 goto err_ioremap;
276 }
277
278 if (is_ehci_tll_mode(pdata->port_mode[0]) ||
279 is_ehci_tll_mode(pdata->port_mode[1]) ||
280 is_ehci_tll_mode(pdata->port_mode[2]) ||
281 is_ohci_port(pdata->port_mode[0]) ||
282 is_ohci_port(pdata->port_mode[1]) ||
283 is_ohci_port(pdata->port_mode[2])) {
284
285 /* Program Common TLL register */
286 reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
287 reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
288 | OMAP_TLL_SHARED_CONF_USB_DIVRATION);
289 reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
290 reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
291
292 usbtll_write(base, OMAP_TLL_SHARED_CONF, reg);
293
294 /* Enable channels now */
295 for (i = 0; i < count; i++) {
296 reg = usbtll_read(base, OMAP_TLL_CHANNEL_CONF(i));
297
298 if (is_ohci_port(pdata->port_mode[i])) {
299 reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
300 << OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
301 reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
302 } else if (pdata->port_mode[i] ==
303 OMAP_EHCI_PORT_MODE_TLL) {
304 /*
305 * Disable AutoIdle, BitStuffing
306 * and use SDR Mode
307 */
308 reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
309 | OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
310 | OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
311 } else {
312 continue;
313 }
314 reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
315 usbtll_write(base, OMAP_TLL_CHANNEL_CONF(i), reg);
316
317 usbtll_writeb(base,
318 OMAP_TLL_ULPI_SCRATCH_REGISTER(i),
319 0xbe);
320 }
321 }
322
323err_ioremap:
324 spin_unlock_irqrestore(&tll->lock, flags);
325 iounmap(base);
326 pm_runtime_put_sync(dev);
327 tll_pdev = pdev;
328 if (!ret)
329 goto end;
330 pm_runtime_disable(dev);
331
332err_usbtll_p2_fck:
333 clk_put(tll->usbtll_p2_fck);
334
335err_usbtll_p1_fck:
336 clk_put(tll->usbtll_p1_fck);
337
338err_tll:
339 kfree(tll);
340
341end:
342 return ret;
343}
344
345/**
346 * usbtll_omap_remove - shutdown processing for UHH & TLL HCDs
347 * @pdev: USB Host Controller being removed
348 *
349 * Reverses the effect of usbtll_omap_probe().
350 */
351static int __devexit usbtll_omap_remove(struct platform_device *pdev)
352{
353 struct usbtll_omap *tll = platform_get_drvdata(pdev);
354
355 clk_put(tll->usbtll_p2_fck);
356 clk_put(tll->usbtll_p1_fck);
357 pm_runtime_disable(&pdev->dev);
358 kfree(tll);
359 return 0;
360}
361
362static int usbtll_runtime_resume(struct device *dev)
363{
364 struct usbtll_omap *tll = dev_get_drvdata(dev);
365 struct usbtll_omap_platform_data *pdata = &tll->platdata;
366 unsigned long flags;
367
368 dev_dbg(dev, "usbtll_runtime_resume\n");
369
370 if (!pdata) {
371 dev_dbg(dev, "missing platform_data\n");
372 return -ENODEV;
373 }
374
375 spin_lock_irqsave(&tll->lock, flags);
376
377 if (is_ehci_tll_mode(pdata->port_mode[0]))
378 clk_enable(tll->usbtll_p1_fck);
379
380 if (is_ehci_tll_mode(pdata->port_mode[1]))
381 clk_enable(tll->usbtll_p2_fck);
382
383 spin_unlock_irqrestore(&tll->lock, flags);
384
385 return 0;
386}
387
388static int usbtll_runtime_suspend(struct device *dev)
389{
390 struct usbtll_omap *tll = dev_get_drvdata(dev);
391 struct usbtll_omap_platform_data *pdata = &tll->platdata;
392 unsigned long flags;
393
394 dev_dbg(dev, "usbtll_runtime_suspend\n");
395
396 if (!pdata) {
397 dev_dbg(dev, "missing platform_data\n");
398 return -ENODEV;
399 }
400
401 spin_lock_irqsave(&tll->lock, flags);
402
403 if (is_ehci_tll_mode(pdata->port_mode[0]))
404 clk_disable(tll->usbtll_p1_fck);
405
406 if (is_ehci_tll_mode(pdata->port_mode[1]))
407 clk_disable(tll->usbtll_p2_fck);
408
409 spin_unlock_irqrestore(&tll->lock, flags);
410
411 return 0;
412}
413
414static const struct dev_pm_ops usbtllomap_dev_pm_ops = {
415 SET_RUNTIME_PM_OPS(usbtll_runtime_suspend,
416 usbtll_runtime_resume,
417 NULL)
418};
419
420static struct platform_driver usbtll_omap_driver = {
421 .driver = {
422 .name = (char *)usbtll_driver_name,
423 .owner = THIS_MODULE,
424 .pm = &usbtllomap_dev_pm_ops,
425 },
426 .probe = usbtll_omap_probe,
427 .remove = __devexit_p(usbtll_omap_remove),
428};
429
430int omap_tll_enable(void)
431{
432 if (!tll_pdev) {
433 pr_err("missing omap usbhs tll platform_data\n");
434 return -ENODEV;
435 }
436 return pm_runtime_get_sync(&tll_pdev->dev);
437}
438EXPORT_SYMBOL_GPL(omap_tll_enable);
439
440int omap_tll_disable(void)
441{
442 if (!tll_pdev) {
443 pr_err("missing omap usbhs tll platform_data\n");
444 return -ENODEV;
445 }
446 return pm_runtime_put_sync(&tll_pdev->dev);
447}
448EXPORT_SYMBOL_GPL(omap_tll_disable);
449
450MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
451MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
452MODULE_LICENSE("GPL v2");
453MODULE_DESCRIPTION("usb tll driver for TI OMAP EHCI and OHCI controllers");
454
455static int __init omap_usbtll_drvinit(void)
456{
457 return platform_driver_register(&usbtll_omap_driver);
458}
459
460/*
461 * init before usbhs core driver;
462 * The usbtll driver should be initialized before
463 * the usbhs core driver probe function is called.
464 */
465fs_initcall(omap_usbtll_drvinit);
466
467static void __exit omap_usbtll_drvexit(void)
468{
469 platform_driver_unregister(&usbtll_omap_driver);
470}
471module_exit(omap_usbtll_drvexit);
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index a345f9bb7b47..4f8d6e6b19aa 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -23,60 +23,7 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/mfd/core.h> 24#include <linux/mfd/core.h>
25#include <linux/mfd/palmas.h> 25#include <linux/mfd/palmas.h>
26 26#include <linux/of_platform.h>
27static const struct resource gpadc_resource[] = {
28 {
29 .name = "EOC_SW",
30 .start = PALMAS_GPADC_EOC_SW_IRQ,
31 .end = PALMAS_GPADC_EOC_SW_IRQ,
32 .flags = IORESOURCE_IRQ,
33 }
34};
35
36static const struct resource usb_resource[] = {
37 {
38 .name = "ID",
39 .start = PALMAS_ID_OTG_IRQ,
40 .end = PALMAS_ID_OTG_IRQ,
41 .flags = IORESOURCE_IRQ,
42 },
43 {
44 .name = "ID_WAKEUP",
45 .start = PALMAS_ID_IRQ,
46 .end = PALMAS_ID_IRQ,
47 .flags = IORESOURCE_IRQ,
48 },
49 {
50 .name = "VBUS",
51 .start = PALMAS_VBUS_OTG_IRQ,
52 .end = PALMAS_VBUS_OTG_IRQ,
53 .flags = IORESOURCE_IRQ,
54 },
55 {
56 .name = "VBUS_WAKEUP",
57 .start = PALMAS_VBUS_IRQ,
58 .end = PALMAS_VBUS_IRQ,
59 .flags = IORESOURCE_IRQ,
60 },
61};
62
63static const struct resource rtc_resource[] = {
64 {
65 .name = "RTC_ALARM",
66 .start = PALMAS_RTC_ALARM_IRQ,
67 .end = PALMAS_RTC_ALARM_IRQ,
68 .flags = IORESOURCE_IRQ,
69 },
70};
71
72static const struct resource pwron_resource[] = {
73 {
74 .name = "PWRON_BUTTON",
75 .start = PALMAS_PWRON_IRQ,
76 .end = PALMAS_PWRON_IRQ,
77 .flags = IORESOURCE_IRQ,
78 },
79};
80 27
81enum palmas_ids { 28enum palmas_ids {
82 PALMAS_PMIC_ID, 29 PALMAS_PMIC_ID,
@@ -111,20 +58,14 @@ static const struct mfd_cell palmas_children[] = {
111 }, 58 },
112 { 59 {
113 .name = "palmas-rtc", 60 .name = "palmas-rtc",
114 .num_resources = ARRAY_SIZE(rtc_resource),
115 .resources = rtc_resource,
116 .id = PALMAS_RTC_ID, 61 .id = PALMAS_RTC_ID,
117 }, 62 },
118 { 63 {
119 .name = "palmas-pwrbutton", 64 .name = "palmas-pwrbutton",
120 .num_resources = ARRAY_SIZE(pwron_resource),
121 .resources = pwron_resource,
122 .id = PALMAS_PWRBUTTON_ID, 65 .id = PALMAS_PWRBUTTON_ID,
123 }, 66 },
124 { 67 {
125 .name = "palmas-gpadc", 68 .name = "palmas-gpadc",
126 .num_resources = ARRAY_SIZE(gpadc_resource),
127 .resources = gpadc_resource,
128 .id = PALMAS_GPADC_ID, 69 .id = PALMAS_GPADC_ID,
129 }, 70 },
130 { 71 {
@@ -141,8 +82,6 @@ static const struct mfd_cell palmas_children[] = {
141 }, 82 },
142 { 83 {
143 .name = "palmas-usb", 84 .name = "palmas-usb",
144 .num_resources = ARRAY_SIZE(usb_resource),
145 .resources = usb_resource,
146 .id = PALMAS_USB_ID, 85 .id = PALMAS_USB_ID,
147 } 86 }
148}; 87};
@@ -308,17 +247,56 @@ static struct regmap_irq_chip palmas_irq_chip = {
308 PALMAS_INT1_MASK), 247 PALMAS_INT1_MASK),
309}; 248};
310 249
250static void __devinit palmas_dt_to_pdata(struct device_node *node,
251 struct palmas_platform_data *pdata)
252{
253 int ret;
254 u32 prop;
255
256 ret = of_property_read_u32(node, "ti,mux_pad1", &prop);
257 if (!ret) {
258 pdata->mux_from_pdata = 1;
259 pdata->pad1 = prop;
260 }
261
262 ret = of_property_read_u32(node, "ti,mux_pad2", &prop);
263 if (!ret) {
264 pdata->mux_from_pdata = 1;
265 pdata->pad2 = prop;
266 }
267
268 /* The default for this register is all masked */
269 ret = of_property_read_u32(node, "ti,power_ctrl", &prop);
270 if (!ret)
271 pdata->power_ctrl = prop;
272 else
273 pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
274 PALMAS_POWER_CTRL_ENABLE1_MASK |
275 PALMAS_POWER_CTRL_ENABLE2_MASK;
276}
277
311static int __devinit palmas_i2c_probe(struct i2c_client *i2c, 278static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
312 const struct i2c_device_id *id) 279 const struct i2c_device_id *id)
313{ 280{
314 struct palmas *palmas; 281 struct palmas *palmas;
315 struct palmas_platform_data *pdata; 282 struct palmas_platform_data *pdata;
283 struct device_node *node = i2c->dev.of_node;
316 int ret = 0, i; 284 int ret = 0, i;
317 unsigned int reg, addr; 285 unsigned int reg, addr;
318 int slave; 286 int slave;
319 struct mfd_cell *children; 287 struct mfd_cell *children;
320 288
321 pdata = dev_get_platdata(&i2c->dev); 289 pdata = dev_get_platdata(&i2c->dev);
290
291 if (node && !pdata) {
292 pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
293
294 if (!pdata)
295 return -ENOMEM;
296
297 palmas_dt_to_pdata(node, pdata);
298 }
299
322 if (!pdata) 300 if (!pdata)
323 return -EINVAL; 301 return -EINVAL;
324 302
@@ -364,7 +342,7 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
364 regmap_write(palmas->regmap[slave], addr, reg); 342 regmap_write(palmas->regmap[slave], addr, reg);
365 343
366 ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, 344 ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
367 IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip, 345 IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
368 &palmas->irq_data); 346 &palmas->irq_data);
369 if (ret < 0) 347 if (ret < 0)
370 goto err; 348 goto err;
@@ -377,11 +355,11 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
377 reg = pdata->pad1; 355 reg = pdata->pad1;
378 ret = regmap_write(palmas->regmap[slave], addr, reg); 356 ret = regmap_write(palmas->regmap[slave], addr, reg);
379 if (ret) 357 if (ret)
380 goto err; 358 goto err_irq;
381 } else { 359 } else {
382 ret = regmap_read(palmas->regmap[slave], addr, &reg); 360 ret = regmap_read(palmas->regmap[slave], addr, &reg);
383 if (ret) 361 if (ret)
384 goto err; 362 goto err_irq;
385 } 363 }
386 364
387 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) 365 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0))
@@ -412,11 +390,11 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
412 reg = pdata->pad2; 390 reg = pdata->pad2;
413 ret = regmap_write(palmas->regmap[slave], addr, reg); 391 ret = regmap_write(palmas->regmap[slave], addr, reg);
414 if (ret) 392 if (ret)
415 goto err; 393 goto err_irq;
416 } else { 394 } else {
417 ret = regmap_read(palmas->regmap[slave], addr, &reg); 395 ret = regmap_read(palmas->regmap[slave], addr, &reg);
418 if (ret) 396 if (ret)
419 goto err; 397 goto err_irq;
420 } 398 }
421 399
422 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) 400 if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4))
@@ -439,18 +417,43 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
439 417
440 ret = regmap_write(palmas->regmap[slave], addr, reg); 418 ret = regmap_write(palmas->regmap[slave], addr, reg);
441 if (ret) 419 if (ret)
442 goto err; 420 goto err_irq;
421
422 /*
423 * If we are probing with DT do this the DT way and return here
424 * otherwise continue and add devices using mfd helpers.
425 */
426 if (node) {
427 ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
428 if (ret < 0)
429 goto err_irq;
430 else
431 return ret;
432 }
443 433
444 children = kmemdup(palmas_children, sizeof(palmas_children), 434 children = kmemdup(palmas_children, sizeof(palmas_children),
445 GFP_KERNEL); 435 GFP_KERNEL);
446 if (!children) { 436 if (!children) {
447 ret = -ENOMEM; 437 ret = -ENOMEM;
448 goto err; 438 goto err_irq;
449 } 439 }
450 440
451 children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; 441 children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
452 children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); 442 children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);
453 443
444 children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata;
445 children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata);
446
447 children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata;
448 children[PALMAS_RESOURCE_ID].pdata_size =
449 sizeof(*pdata->resource_pdata);
450
451 children[PALMAS_USB_ID].platform_data = pdata->usb_pdata;
452 children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata);
453
454 children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata;
455 children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata);
456
454 ret = mfd_add_devices(palmas->dev, -1, 457 ret = mfd_add_devices(palmas->dev, -1,
455 children, ARRAY_SIZE(palmas_children), 458 children, ARRAY_SIZE(palmas_children),
456 NULL, regmap_irq_chip_get_base(palmas->irq_data), 459 NULL, regmap_irq_chip_get_base(palmas->irq_data),
@@ -458,13 +461,15 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
458 kfree(children); 461 kfree(children);
459 462
460 if (ret < 0) 463 if (ret < 0)
461 goto err; 464 goto err_devices;
462 465
463 return ret; 466 return ret;
464 467
465err: 468err_devices:
466 mfd_remove_devices(palmas->dev); 469 mfd_remove_devices(palmas->dev);
467 kfree(palmas); 470err_irq:
471 regmap_del_irq_chip(palmas->irq, palmas->irq_data);
472err:
468 return ret; 473 return ret;
469} 474}
470 475
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c
index fa6f80fad5f1..fe00cdd6f83d 100644
--- a/drivers/mfd/rc5t583-irq.c
+++ b/drivers/mfd/rc5t583-irq.c
@@ -255,7 +255,7 @@ static irqreturn_t rc5t583_irq(int irq, void *data)
255{ 255{
256 struct rc5t583 *rc5t583 = data; 256 struct rc5t583 *rc5t583 = data;
257 uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS]; 257 uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS];
258 uint8_t master_int; 258 uint8_t master_int = 0;
259 int i; 259 int i;
260 int ret; 260 int ret;
261 unsigned int rtc_int_sts = 0; 261 unsigned int rtc_int_sts = 0;
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index ff61efc76ce2..f1a024ecdb1e 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -85,7 +85,7 @@ static int __rc5t583_set_ext_pwrreq1_control(struct device *dev,
85 int id, int ext_pwr, int slots) 85 int id, int ext_pwr, int slots)
86{ 86{
87 int ret; 87 int ret;
88 uint8_t sleepseq_val; 88 uint8_t sleepseq_val = 0;
89 unsigned int en_bit; 89 unsigned int en_bit;
90 unsigned int slot_bit; 90 unsigned int slot_bit;
91 91
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c
new file mode 100644
index 000000000000..24ae3d8421c5
--- /dev/null
+++ b/drivers/mfd/smsc-ece1099.c
@@ -0,0 +1,113 @@
1/*
2 * TI SMSC MFD Driver
3 *
4 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
5 *
6 * Author: Sourav Poddar <sourav.poddar@ti.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; GPL v2.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/i2c.h>
19#include <linux/gpio.h>
20#include <linux/workqueue.h>
21#include <linux/irq.h>
22#include <linux/regmap.h>
23#include <linux/err.h>
24#include <linux/mfd/core.h>
25#include <linux/mfd/smsc.h>
26#include <linux/of_platform.h>
27
28static struct regmap_config smsc_regmap_config = {
29 .reg_bits = 8,
30 .val_bits = 8,
31 .max_register = SMSC_VEN_ID_H,
32 .cache_type = REGCACHE_RBTREE,
33};
34
35static int smsc_i2c_probe(struct i2c_client *i2c,
36 const struct i2c_device_id *id)
37{
38 struct smsc *smsc;
39 int devid, rev, venid_l, venid_h;
40 int ret = 0;
41
42 smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
43 GFP_KERNEL);
44 if (!smsc) {
45 dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n");
46 return -ENOMEM;
47 }
48
49 smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
50 if (IS_ERR(smsc->regmap)) {
51 ret = PTR_ERR(smsc->regmap);
52 goto err;
53 }
54
55 i2c_set_clientdata(i2c, smsc);
56 smsc->dev = &i2c->dev;
57
58#ifdef CONFIG_OF
59 of_property_read_u32(i2c->dev.of_node, "clock", &smsc->clk);
60#endif
61
62 regmap_read(smsc->regmap, SMSC_DEV_ID, &devid);
63 regmap_read(smsc->regmap, SMSC_DEV_REV, &rev);
64 regmap_read(smsc->regmap, SMSC_VEN_ID_L, &venid_l);
65 regmap_read(smsc->regmap, SMSC_VEN_ID_H, &venid_h);
66
67 dev_info(&i2c->dev, "SMSCxxx devid: %02x rev: %02x venid: %02x\n",
68 devid, rev, (venid_h << 8) | venid_l);
69
70 ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk);
71 if (ret)
72 goto err;
73
74#ifdef CONFIG_OF
75 if (i2c->dev.of_node)
76 ret = of_platform_populate(i2c->dev.of_node,
77 NULL, NULL, &i2c->dev);
78#endif
79
80err:
81 return ret;
82}
83
84static int smsc_i2c_remove(struct i2c_client *i2c)
85{
86 struct smsc *smsc = i2c_get_clientdata(i2c);
87
88 mfd_remove_devices(smsc->dev);
89
90 return 0;
91}
92
93static const struct i2c_device_id smsc_i2c_id[] = {
94 { "smscece1099", 0},
95 {},
96};
97MODULE_DEVICE_TABLE(i2c, smsc_i2c_id);
98
99static struct i2c_driver smsc_i2c_driver = {
100 .driver = {
101 .name = "smsc",
102 .owner = THIS_MODULE,
103 },
104 .probe = smsc_i2c_probe,
105 .remove = smsc_i2c_remove,
106 .id_table = smsc_i2c_id,
107};
108
109module_i2c_driver(smsc_i2c_driver);
110
111MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
112MODULE_DESCRIPTION("SMSC chip multi-function driver");
113MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
new file mode 100644
index 000000000000..65fe609026cc
--- /dev/null
+++ b/drivers/mfd/syscon.c
@@ -0,0 +1,176 @@
1/*
2 * System Control Driver
3 *
4 * Copyright (C) 2012 Freescale Semiconductor, Inc.
5 * Copyright (C) 2012 Linaro Ltd.
6 *
7 * Author: Dong Aisheng <dong.aisheng@linaro.org>
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
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/of_address.h>
20#include <linux/of_platform.h>
21#include <linux/platform_device.h>
22#include <linux/regmap.h>
23
24static struct platform_driver syscon_driver;
25
26struct syscon {
27 struct device *dev;
28 void __iomem *base;
29 struct regmap *regmap;
30};
31
32static int syscon_match(struct device *dev, void *data)
33{
34 struct syscon *syscon = dev_get_drvdata(dev);
35 struct device_node *dn = data;
36
37 return (syscon->dev->of_node == dn) ? 1 : 0;
38}
39
40struct regmap *syscon_node_to_regmap(struct device_node *np)
41{
42 struct syscon *syscon;
43 struct device *dev;
44
45 dev = driver_find_device(&syscon_driver.driver, NULL, np,
46 syscon_match);
47 if (!dev)
48 return ERR_PTR(-EPROBE_DEFER);
49
50 syscon = dev_get_drvdata(dev);
51
52 return syscon->regmap;
53}
54EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
55
56struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
57{
58 struct device_node *syscon_np;
59 struct regmap *regmap;
60
61 syscon_np = of_find_compatible_node(NULL, NULL, s);
62 if (!syscon_np)
63 return ERR_PTR(-ENODEV);
64
65 regmap = syscon_node_to_regmap(syscon_np);
66 of_node_put(syscon_np);
67
68 return regmap;
69}
70EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
71
72struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
73 const char *property)
74{
75 struct device_node *syscon_np;
76 struct regmap *regmap;
77
78 syscon_np = of_parse_phandle(np, property, 0);
79 if (!syscon_np)
80 return ERR_PTR(-ENODEV);
81
82 regmap = syscon_node_to_regmap(syscon_np);
83 of_node_put(syscon_np);
84
85 return regmap;
86}
87EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle);
88
89static const struct of_device_id of_syscon_match[] = {
90 { .compatible = "syscon", },
91 { },
92};
93
94static struct regmap_config syscon_regmap_config = {
95 .reg_bits = 32,
96 .val_bits = 32,
97 .reg_stride = 4,
98};
99
100static int __devinit syscon_probe(struct platform_device *pdev)
101{
102 struct device *dev = &pdev->dev;
103 struct device_node *np = dev->of_node;
104 struct syscon *syscon;
105 struct resource res;
106 int ret;
107
108 if (!np)
109 return -ENOENT;
110
111 syscon = devm_kzalloc(dev, sizeof(struct syscon),
112 GFP_KERNEL);
113 if (!syscon)
114 return -ENOMEM;
115
116 syscon->base = of_iomap(np, 0);
117 if (!syscon->base)
118 return -EADDRNOTAVAIL;
119
120 ret = of_address_to_resource(np, 0, &res);
121 if (ret)
122 return ret;
123
124 syscon_regmap_config.max_register = res.end - res.start - 3;
125 syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
126 &syscon_regmap_config);
127 if (IS_ERR(syscon->regmap)) {
128 dev_err(dev, "regmap init failed\n");
129 return PTR_ERR(syscon->regmap);
130 }
131
132 syscon->dev = dev;
133 platform_set_drvdata(pdev, syscon);
134
135 dev_info(dev, "syscon regmap start 0x%x end 0x%x registered\n",
136 res.start, res.end);
137
138 return 0;
139}
140
141static int __devexit syscon_remove(struct platform_device *pdev)
142{
143 struct syscon *syscon;
144
145 syscon = platform_get_drvdata(pdev);
146 iounmap(syscon->base);
147 platform_set_drvdata(pdev, NULL);
148
149 return 0;
150}
151
152static struct platform_driver syscon_driver = {
153 .driver = {
154 .name = "syscon",
155 .owner = THIS_MODULE,
156 .of_match_table = of_syscon_match,
157 },
158 .probe = syscon_probe,
159 .remove = __devexit_p(syscon_remove),
160};
161
162static int __init syscon_init(void)
163{
164 return platform_driver_register(&syscon_driver);
165}
166postcore_initcall(syscon_init);
167
168static void __exit syscon_exit(void)
169{
170 platform_driver_unregister(&syscon_driver);
171}
172module_exit(syscon_exit);
173
174MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
175MODULE_DESCRIPTION("System Control driver");
176MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index b56ba6b43294..8f4c853ca116 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -9,8 +9,10 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/interrupt.h> 10#include <linux/interrupt.h>
11#include <linux/irq.h> 11#include <linux/irq.h>
12#include <linux/irqdomain.h>
12#include <linux/slab.h> 13#include <linux/slab.h>
13#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/of.h>
14#include <linux/mfd/core.h> 16#include <linux/mfd/core.h>
15#include <linux/mfd/tc3589x.h> 17#include <linux/mfd/tc3589x.h>
16 18
@@ -145,6 +147,7 @@ static struct mfd_cell tc3589x_dev_gpio[] = {
145 .name = "tc3589x-gpio", 147 .name = "tc3589x-gpio",
146 .num_resources = ARRAY_SIZE(gpio_resources), 148 .num_resources = ARRAY_SIZE(gpio_resources),
147 .resources = &gpio_resources[0], 149 .resources = &gpio_resources[0],
150 .of_compatible = "tc3589x-gpio",
148 }, 151 },
149}; 152};
150 153
@@ -153,6 +156,7 @@ static struct mfd_cell tc3589x_dev_keypad[] = {
153 .name = "tc3589x-keypad", 156 .name = "tc3589x-keypad",
154 .num_resources = ARRAY_SIZE(keypad_resources), 157 .num_resources = ARRAY_SIZE(keypad_resources),
155 .resources = &keypad_resources[0], 158 .resources = &keypad_resources[0],
159 .of_compatible = "tc3589x-keypad",
156 }, 160 },
157}; 161};
158 162
@@ -168,8 +172,9 @@ again:
168 172
169 while (status) { 173 while (status) {
170 int bit = __ffs(status); 174 int bit = __ffs(status);
175 int virq = irq_create_mapping(tc3589x->domain, bit);
171 176
172 handle_nested_irq(tc3589x->irq_base + bit); 177 handle_nested_irq(virq);
173 status &= ~(1 << bit); 178 status &= ~(1 << bit);
174 } 179 }
175 180
@@ -186,38 +191,60 @@ again:
186 return IRQ_HANDLED; 191 return IRQ_HANDLED;
187} 192}
188 193
189static int tc3589x_irq_init(struct tc3589x *tc3589x) 194static int tc3589x_irq_map(struct irq_domain *d, unsigned int virq,
195 irq_hw_number_t hwirq)
190{ 196{
191 int base = tc3589x->irq_base; 197 struct tc3589x *tc3589x = d->host_data;
192 int irq;
193 198
194 for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) { 199 irq_set_chip_data(virq, tc3589x);
195 irq_set_chip_data(irq, tc3589x); 200 irq_set_chip_and_handler(virq, &dummy_irq_chip,
196 irq_set_chip_and_handler(irq, &dummy_irq_chip, 201 handle_edge_irq);
197 handle_edge_irq); 202 irq_set_nested_thread(virq, 1);
198 irq_set_nested_thread(irq, 1);
199#ifdef CONFIG_ARM 203#ifdef CONFIG_ARM
200 set_irq_flags(irq, IRQF_VALID); 204 set_irq_flags(virq, IRQF_VALID);
201#else 205#else
202 irq_set_noprobe(irq); 206 irq_set_noprobe(virq);
203#endif 207#endif
204 }
205 208
206 return 0; 209 return 0;
207} 210}
208 211
209static void tc3589x_irq_remove(struct tc3589x *tc3589x) 212static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
210{ 213{
211 int base = tc3589x->irq_base;
212 int irq;
213
214 for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
215#ifdef CONFIG_ARM 214#ifdef CONFIG_ARM
216 set_irq_flags(irq, 0); 215 set_irq_flags(virq, 0);
217#endif 216#endif
218 irq_set_chip_and_handler(irq, NULL, NULL); 217 irq_set_chip_and_handler(virq, NULL, NULL);
219 irq_set_chip_data(irq, NULL); 218 irq_set_chip_data(virq, NULL);
219}
220
221static struct irq_domain_ops tc3589x_irq_ops = {
222 .map = tc3589x_irq_map,
223 .unmap = tc3589x_irq_unmap,
224 .xlate = irq_domain_xlate_twocell,
225};
226
227static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
228{
229 int base = tc3589x->irq_base;
230
231 if (base) {
232 tc3589x->domain = irq_domain_add_legacy(
233 NULL, TC3589x_NR_INTERNAL_IRQS, base,
234 0, &tc3589x_irq_ops, tc3589x);
235 }
236 else {
237 tc3589x->domain = irq_domain_add_linear(
238 np, TC3589x_NR_INTERNAL_IRQS,
239 &tc3589x_irq_ops, tc3589x);
220 } 240 }
241
242 if (!tc3589x->domain) {
243 dev_err(tc3589x->dev, "Failed to create irqdomain\n");
244 return -ENOSYS;
245 }
246
247 return 0;
221} 248}
222 249
223static int tc3589x_chip_init(struct tc3589x *tc3589x) 250static int tc3589x_chip_init(struct tc3589x *tc3589x)
@@ -263,7 +290,7 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
263 if (blocks & TC3589x_BLOCK_GPIO) { 290 if (blocks & TC3589x_BLOCK_GPIO) {
264 ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, 291 ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio,
265 ARRAY_SIZE(tc3589x_dev_gpio), NULL, 292 ARRAY_SIZE(tc3589x_dev_gpio), NULL,
266 tc3589x->irq_base, NULL); 293 tc3589x->irq_base, tc3589x->domain);
267 if (ret) { 294 if (ret) {
268 dev_err(tc3589x->dev, "failed to add gpio child\n"); 295 dev_err(tc3589x->dev, "failed to add gpio child\n");
269 return ret; 296 return ret;
@@ -274,7 +301,7 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
274 if (blocks & TC3589x_BLOCK_KEYPAD) { 301 if (blocks & TC3589x_BLOCK_KEYPAD) {
275 ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, 302 ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad,
276 ARRAY_SIZE(tc3589x_dev_keypad), NULL, 303 ARRAY_SIZE(tc3589x_dev_keypad), NULL,
277 tc3589x->irq_base, NULL); 304 tc3589x->irq_base, tc3589x->domain);
278 if (ret) { 305 if (ret) {
279 dev_err(tc3589x->dev, "failed to keypad child\n"); 306 dev_err(tc3589x->dev, "failed to keypad child\n");
280 return ret; 307 return ret;
@@ -285,13 +312,47 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x)
285 return ret; 312 return ret;
286} 313}
287 314
315static int tc3589x_of_probe(struct device_node *np,
316 struct tc3589x_platform_data *pdata)
317{
318 struct device_node *child;
319
320 for_each_child_of_node(np, child) {
321 if (!strcmp(child->name, "tc3589x_gpio")) {
322 pdata->block |= TC3589x_BLOCK_GPIO;
323 }
324 if (!strcmp(child->name, "tc3589x_keypad")) {
325 pdata->block |= TC3589x_BLOCK_KEYPAD;
326 }
327 }
328
329 return 0;
330}
331
288static int __devinit tc3589x_probe(struct i2c_client *i2c, 332static int __devinit tc3589x_probe(struct i2c_client *i2c,
289 const struct i2c_device_id *id) 333 const struct i2c_device_id *id)
290{ 334{
291 struct tc3589x_platform_data *pdata = i2c->dev.platform_data; 335 struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
336 struct device_node *np = i2c->dev.of_node;
292 struct tc3589x *tc3589x; 337 struct tc3589x *tc3589x;
293 int ret; 338 int ret;
294 339
340 if (!pdata) {
341 if (np) {
342 pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
343 if (!pdata)
344 return -ENOMEM;
345
346 ret = tc3589x_of_probe(np, pdata);
347 if (ret)
348 return ret;
349 }
350 else {
351 dev_err(&i2c->dev, "No platform data or DT found\n");
352 return -EINVAL;
353 }
354 }
355
295 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA 356 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
296 | I2C_FUNC_SMBUS_I2C_BLOCK)) 357 | I2C_FUNC_SMBUS_I2C_BLOCK))
297 return -EIO; 358 return -EIO;
@@ -314,7 +375,7 @@ static int __devinit tc3589x_probe(struct i2c_client *i2c,
314 if (ret) 375 if (ret)
315 goto out_free; 376 goto out_free;
316 377
317 ret = tc3589x_irq_init(tc3589x); 378 ret = tc3589x_irq_init(tc3589x, np);
318 if (ret) 379 if (ret)
319 goto out_free; 380 goto out_free;
320 381
@@ -323,7 +384,7 @@ static int __devinit tc3589x_probe(struct i2c_client *i2c,
323 "tc3589x", tc3589x); 384 "tc3589x", tc3589x);
324 if (ret) { 385 if (ret) {
325 dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret); 386 dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
326 goto out_removeirq; 387 goto out_free;
327 } 388 }
328 389
329 ret = tc3589x_device_init(tc3589x); 390 ret = tc3589x_device_init(tc3589x);
@@ -336,8 +397,6 @@ static int __devinit tc3589x_probe(struct i2c_client *i2c,
336 397
337out_freeirq: 398out_freeirq:
338 free_irq(tc3589x->i2c->irq, tc3589x); 399 free_irq(tc3589x->i2c->irq, tc3589x);
339out_removeirq:
340 tc3589x_irq_remove(tc3589x);
341out_free: 400out_free:
342 kfree(tc3589x); 401 kfree(tc3589x);
343 return ret; 402 return ret;
@@ -350,7 +409,6 @@ static int __devexit tc3589x_remove(struct i2c_client *client)
350 mfd_remove_devices(tc3589x->dev); 409 mfd_remove_devices(tc3589x->dev);
351 410
352 free_irq(tc3589x->i2c->irq, tc3589x); 411 free_irq(tc3589x->i2c->irq, tc3589x);
353 tc3589x_irq_remove(tc3589x);
354 412
355 kfree(tc3589x); 413 kfree(tc3589x);
356 414
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 50fd87c87a1c..074ae32b0d2a 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -236,7 +236,7 @@ static int __devinit tps65090_irq_init(struct tps65090 *tps65090, int irq,
236 236
237static bool is_volatile_reg(struct device *dev, unsigned int reg) 237static bool is_volatile_reg(struct device *dev, unsigned int reg)
238{ 238{
239 if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS)) 239 if (reg == TPS65090_INT_STS)
240 return true; 240 return true;
241 else 241 else
242 return false; 242 return false;
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index a95e9421b735..3fb32e655254 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -34,6 +34,9 @@ static struct mfd_cell tps65217s[] = {
34 { 34 {
35 .name = "tps65217-pmic", 35 .name = "tps65217-pmic",
36 }, 36 },
37 {
38 .name = "tps65217-bl",
39 },
37}; 40};
38 41
39/** 42/**
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 345960ca2fd8..467464368773 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -30,6 +30,10 @@
30#include <linux/mfd/core.h> 30#include <linux/mfd/core.h>
31#include <linux/mfd/tps6586x.h> 31#include <linux/mfd/tps6586x.h>
32 32
33#define TPS6586X_SUPPLYENE 0x14
34#define EXITSLREQ_BIT BIT(1)
35#define SLEEP_MODE_BIT BIT(3)
36
33/* interrupt control registers */ 37/* interrupt control registers */
34#define TPS6586X_INT_ACK1 0xb5 38#define TPS6586X_INT_ACK1 0xb5
35#define TPS6586X_INT_ACK2 0xb6 39#define TPS6586X_INT_ACK2 0xb6
@@ -422,6 +426,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien
422 pdata->subdevs = devs; 426 pdata->subdevs = devs;
423 pdata->gpio_base = -1; 427 pdata->gpio_base = -1;
424 pdata->irq_base = -1; 428 pdata->irq_base = -1;
429 pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
425 430
426 return pdata; 431 return pdata;
427} 432}
@@ -454,6 +459,15 @@ static const struct regmap_config tps6586x_regmap_config = {
454 .cache_type = REGCACHE_RBTREE, 459 .cache_type = REGCACHE_RBTREE,
455}; 460};
456 461
462static struct device *tps6586x_dev;
463static void tps6586x_power_off(void)
464{
465 if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
466 return;
467
468 tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
469}
470
457static int __devinit tps6586x_i2c_probe(struct i2c_client *client, 471static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
458 const struct i2c_device_id *id) 472 const struct i2c_device_id *id)
459{ 473{
@@ -519,6 +533,11 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
519 goto err_add_devs; 533 goto err_add_devs;
520 } 534 }
521 535
536 if (pdata->pm_off && !pm_power_off) {
537 tps6586x_dev = &client->dev;
538 pm_power_off = tps6586x_power_off;
539 }
540
522 return 0; 541 return 0;
523 542
524err_add_devs: 543err_add_devs:
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index d3ce4d569deb..0d79ce2b5014 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -24,6 +24,14 @@
24#include <linux/mfd/tps65910.h> 24#include <linux/mfd/tps65910.h>
25#include <linux/of_device.h> 25#include <linux/of_device.h>
26 26
27static struct resource rtc_resources[] = {
28 {
29 .start = TPS65910_IRQ_RTC_ALARM,
30 .end = TPS65910_IRQ_RTC_ALARM,
31 .flags = IORESOURCE_IRQ,
32 }
33};
34
27static struct mfd_cell tps65910s[] = { 35static struct mfd_cell tps65910s[] = {
28 { 36 {
29 .name = "tps65910-gpio", 37 .name = "tps65910-gpio",
@@ -33,6 +41,8 @@ static struct mfd_cell tps65910s[] = {
33 }, 41 },
34 { 42 {
35 .name = "tps65910-rtc", 43 .name = "tps65910-rtc",
44 .num_resources = ARRAY_SIZE(rtc_resources),
45 .resources = &rtc_resources[0],
36 }, 46 },
37 { 47 {
38 .name = "tps65910-power", 48 .name = "tps65910-power",
@@ -198,6 +208,8 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
198 208
199 board_info->irq = client->irq; 209 board_info->irq = client->irq;
200 board_info->irq_base = -1; 210 board_info->irq_base = -1;
211 board_info->pm_off = of_property_read_bool(np,
212 "ti,system-power-controller");
201 213
202 return board_info; 214 return board_info;
203} 215}
@@ -210,6 +222,21 @@ struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
210} 222}
211#endif 223#endif
212 224
225static struct i2c_client *tps65910_i2c_client;
226static void tps65910_power_off(void)
227{
228 struct tps65910 *tps65910;
229
230 tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev);
231
232 if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
233 DEVCTRL_PWR_OFF_MASK) < 0)
234 return;
235
236 tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL,
237 DEVCTRL_DEV_ON_MASK);
238}
239
213static __devinit int tps65910_i2c_probe(struct i2c_client *i2c, 240static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
214 const struct i2c_device_id *id) 241 const struct i2c_device_id *id)
215{ 242{
@@ -267,6 +294,11 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
267 tps65910_ck32k_init(tps65910, pmic_plat_data); 294 tps65910_ck32k_init(tps65910, pmic_plat_data);
268 tps65910_sleepinit(tps65910, pmic_plat_data); 295 tps65910_sleepinit(tps65910, pmic_plat_data);
269 296
297 if (pmic_plat_data->pm_off && !pm_power_off) {
298 tps65910_i2c_client = i2c;
299 pm_power_off = tps65910_power_off;
300 }
301
270 return ret; 302 return ret;
271} 303}
272 304
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 9d3a0bc1a65f..4ae642320205 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -63,70 +63,6 @@
63 63
64#define DRIVER_NAME "twl" 64#define DRIVER_NAME "twl"
65 65
66#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
67#define twl_has_keypad() true
68#else
69#define twl_has_keypad() false
70#endif
71
72#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
73#define twl_has_gpio() true
74#else
75#define twl_has_gpio() false
76#endif
77
78#if defined(CONFIG_REGULATOR_TWL4030) \
79 || defined(CONFIG_REGULATOR_TWL4030_MODULE)
80#define twl_has_regulator() true
81#else
82#define twl_has_regulator() false
83#endif
84
85#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
86#define twl_has_madc() true
87#else
88#define twl_has_madc() false
89#endif
90
91#ifdef CONFIG_TWL4030_POWER
92#define twl_has_power() true
93#else
94#define twl_has_power() false
95#endif
96
97#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
98#define twl_has_rtc() true
99#else
100#define twl_has_rtc() false
101#endif
102
103#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\
104 defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE)
105#define twl_has_usb() true
106#else
107#define twl_has_usb() false
108#endif
109
110#if defined(CONFIG_TWL4030_WATCHDOG) || \
111 defined(CONFIG_TWL4030_WATCHDOG_MODULE)
112#define twl_has_watchdog() true
113#else
114#define twl_has_watchdog() false
115#endif
116
117#if defined(CONFIG_MFD_TWL4030_AUDIO) || \
118 defined(CONFIG_MFD_TWL4030_AUDIO_MODULE)
119#define twl_has_codec() true
120#else
121#define twl_has_codec() false
122#endif
123
124#if defined(CONFIG_CHARGER_TWL4030) || defined(CONFIG_CHARGER_TWL4030_MODULE)
125#define twl_has_bci() true
126#else
127#define twl_has_bci() false
128#endif
129
130/* Triton Core internal information (BEGIN) */ 66/* Triton Core internal information (BEGIN) */
131 67
132/* Last - for index max*/ 68/* Last - for index max*/
@@ -134,13 +70,6 @@
134 70
135#define TWL_NUM_SLAVES 4 71#define TWL_NUM_SLAVES 4
136 72
137#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
138 || defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE)
139#define twl_has_pwrbutton() true
140#else
141#define twl_has_pwrbutton() false
142#endif
143
144#define SUB_CHIP_ID0 0 73#define SUB_CHIP_ID0 0
145#define SUB_CHIP_ID1 1 74#define SUB_CHIP_ID1 1
146#define SUB_CHIP_ID2 2 75#define SUB_CHIP_ID2 2
@@ -552,6 +481,38 @@ int twl_get_version(void)
552} 481}
553EXPORT_SYMBOL_GPL(twl_get_version); 482EXPORT_SYMBOL_GPL(twl_get_version);
554 483
484/**
485 * twl_get_hfclk_rate - API to get TWL external HFCLK clock rate.
486 *
487 * Api to get the TWL HFCLK rate based on BOOT_CFG register.
488 */
489int twl_get_hfclk_rate(void)
490{
491 u8 ctrl;
492 int rate;
493
494 twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &ctrl, R_CFG_BOOT);
495
496 switch (ctrl & 0x3) {
497 case HFCLK_FREQ_19p2_MHZ:
498 rate = 19200000;
499 break;
500 case HFCLK_FREQ_26_MHZ:
501 rate = 26000000;
502 break;
503 case HFCLK_FREQ_38p4_MHZ:
504 rate = 38400000;
505 break;
506 default:
507 pr_err("TWL4030: HFCLK is not configured\n");
508 rate = -EINVAL;
509 break;
510 }
511
512 return rate;
513}
514EXPORT_SYMBOL_GPL(twl_get_hfclk_rate);
515
555static struct device * 516static struct device *
556add_numbered_child(unsigned chip, const char *name, int num, 517add_numbered_child(unsigned chip, const char *name, int num,
557 void *pdata, unsigned pdata_len, 518 void *pdata, unsigned pdata_len,
@@ -669,7 +630,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
669 struct device *child; 630 struct device *child;
670 unsigned sub_chip_id; 631 unsigned sub_chip_id;
671 632
672 if (twl_has_gpio() && pdata->gpio) { 633 if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) {
673 child = add_child(SUB_CHIP_ID1, "twl4030_gpio", 634 child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
674 pdata->gpio, sizeof(*pdata->gpio), 635 pdata->gpio, sizeof(*pdata->gpio),
675 false, irq_base + GPIO_INTR_OFFSET, 0); 636 false, irq_base + GPIO_INTR_OFFSET, 0);
@@ -677,7 +638,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
677 return PTR_ERR(child); 638 return PTR_ERR(child);
678 } 639 }
679 640
680 if (twl_has_keypad() && pdata->keypad) { 641 if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) {
681 child = add_child(SUB_CHIP_ID2, "twl4030_keypad", 642 child = add_child(SUB_CHIP_ID2, "twl4030_keypad",
682 pdata->keypad, sizeof(*pdata->keypad), 643 pdata->keypad, sizeof(*pdata->keypad),
683 true, irq_base + KEYPAD_INTR_OFFSET, 0); 644 true, irq_base + KEYPAD_INTR_OFFSET, 0);
@@ -685,7 +646,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
685 return PTR_ERR(child); 646 return PTR_ERR(child);
686 } 647 }
687 648
688 if (twl_has_madc() && pdata->madc) { 649 if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc) {
689 child = add_child(2, "twl4030_madc", 650 child = add_child(2, "twl4030_madc",
690 pdata->madc, sizeof(*pdata->madc), 651 pdata->madc, sizeof(*pdata->madc),
691 true, irq_base + MADC_INTR_OFFSET, 0); 652 true, irq_base + MADC_INTR_OFFSET, 0);
@@ -693,7 +654,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
693 return PTR_ERR(child); 654 return PTR_ERR(child);
694 } 655 }
695 656
696 if (twl_has_rtc()) { 657 if (IS_ENABLED(CONFIG_RTC_DRV_TWL4030)) {
697 /* 658 /*
698 * REVISIT platform_data here currently might expose the 659 * REVISIT platform_data here currently might expose the
699 * "msecure" line ... but for now we just expect board 660 * "msecure" line ... but for now we just expect board
@@ -709,7 +670,15 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
709 return PTR_ERR(child); 670 return PTR_ERR(child);
710 } 671 }
711 672
712 if (twl_has_usb() && pdata->usb && twl_class_is_4030()) { 673 if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
674 child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0,
675 false, 0, 0);
676 if (IS_ERR(child))
677 return PTR_ERR(child);
678 }
679
680 if (IS_ENABLED(CONFIG_TWL4030_USB) && pdata->usb &&
681 twl_class_is_4030()) {
713 682
714 static struct regulator_consumer_supply usb1v5 = { 683 static struct regulator_consumer_supply usb1v5 = {
715 .supply = "usb1v5", 684 .supply = "usb1v5",
@@ -723,7 +692,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
723 }; 692 };
724 693
725 /* First add the regulators so that they can be used by transceiver */ 694 /* First add the regulators so that they can be used by transceiver */
726 if (twl_has_regulator()) { 695 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
727 /* this is a template that gets copied */ 696 /* this is a template that gets copied */
728 struct regulator_init_data usb_fixed = { 697 struct regulator_init_data usb_fixed = {
729 .constraints.valid_modes_mask = 698 .constraints.valid_modes_mask =
@@ -765,18 +734,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
765 return PTR_ERR(child); 734 return PTR_ERR(child);
766 735
767 /* we need to connect regulators to this transceiver */ 736 /* we need to connect regulators to this transceiver */
768 if (twl_has_regulator() && child) { 737 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) {
769 usb1v5.dev_name = dev_name(child); 738 usb1v5.dev_name = dev_name(child);
770 usb1v8.dev_name = dev_name(child); 739 usb1v8.dev_name = dev_name(child);
771 usb3v1[0].dev_name = dev_name(child); 740 usb3v1[0].dev_name = dev_name(child);
772 } 741 }
773 } 742 }
774 if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { 743 if (IS_ENABLED(CONFIG_TWL6030_USB) && pdata->usb &&
744 twl_class_is_6030()) {
775 745
776 static struct regulator_consumer_supply usb3v3; 746 static struct regulator_consumer_supply usb3v3;
777 int regulator; 747 int regulator;
778 748
779 if (twl_has_regulator()) { 749 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
780 /* this is a template that gets copied */ 750 /* this is a template that gets copied */
781 struct regulator_init_data usb_fixed = { 751 struct regulator_init_data usb_fixed = {
782 .constraints.valid_modes_mask = 752 .constraints.valid_modes_mask =
@@ -813,9 +783,10 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
813 if (IS_ERR(child)) 783 if (IS_ERR(child))
814 return PTR_ERR(child); 784 return PTR_ERR(child);
815 /* we need to connect regulators to this transceiver */ 785 /* we need to connect regulators to this transceiver */
816 if (twl_has_regulator() && child) 786 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child)
817 usb3v3.dev_name = dev_name(child); 787 usb3v3.dev_name = dev_name(child);
818 } else if (twl_has_regulator() && twl_class_is_6030()) { 788 } else if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) &&
789 twl_class_is_6030()) {
819 if (features & TWL6025_SUBCLASS) 790 if (features & TWL6025_SUBCLASS)
820 child = add_regulator(TWL6025_REG_LDOUSB, 791 child = add_regulator(TWL6025_REG_LDOUSB,
821 pdata->ldousb, features); 792 pdata->ldousb, features);
@@ -827,20 +798,21 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
827 return PTR_ERR(child); 798 return PTR_ERR(child);
828 } 799 }
829 800
830 if (twl_has_watchdog() && twl_class_is_4030()) { 801 if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
831 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); 802 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
832 if (IS_ERR(child)) 803 if (IS_ERR(child))
833 return PTR_ERR(child); 804 return PTR_ERR(child);
834 } 805 }
835 806
836 if (twl_has_pwrbutton() && twl_class_is_4030()) { 807 if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) {
837 child = add_child(1, "twl4030_pwrbutton", 808 child = add_child(1, "twl4030_pwrbutton",
838 NULL, 0, true, irq_base + 8 + 0, 0); 809 NULL, 0, true, irq_base + 8 + 0, 0);
839 if (IS_ERR(child)) 810 if (IS_ERR(child))
840 return PTR_ERR(child); 811 return PTR_ERR(child);
841 } 812 }
842 813
843 if (twl_has_codec() && pdata->audio && twl_class_is_4030()) { 814 if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio &&
815 twl_class_is_4030()) {
844 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid; 816 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
845 child = add_child(sub_chip_id, "twl4030-audio", 817 child = add_child(sub_chip_id, "twl4030-audio",
846 pdata->audio, sizeof(*pdata->audio), 818 pdata->audio, sizeof(*pdata->audio),
@@ -850,7 +822,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
850 } 822 }
851 823
852 /* twl4030 regulators */ 824 /* twl4030 regulators */
853 if (twl_has_regulator() && twl_class_is_4030()) { 825 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_4030()) {
854 child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1, 826 child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
855 features); 827 features);
856 if (IS_ERR(child)) 828 if (IS_ERR(child))
@@ -905,7 +877,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
905 } 877 }
906 878
907 /* maybe add LDOs that are omitted on cost-reduced parts */ 879 /* maybe add LDOs that are omitted on cost-reduced parts */
908 if (twl_has_regulator() && !(features & TPS_SUBSET) 880 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && !(features & TPS_SUBSET)
909 && twl_class_is_4030()) { 881 && twl_class_is_4030()) {
910 child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2, 882 child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2,
911 features); 883 features);
@@ -939,7 +911,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
939 } 911 }
940 912
941 /* twl6030 regulators */ 913 /* twl6030 regulators */
942 if (twl_has_regulator() && twl_class_is_6030() && 914 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
943 !(features & TWL6025_SUBCLASS)) { 915 !(features & TWL6025_SUBCLASS)) {
944 child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1, 916 child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
945 features); 917 features);
@@ -1013,7 +985,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
1013 } 985 }
1014 986
1015 /* 6030 and 6025 share this regulator */ 987 /* 6030 and 6025 share this regulator */
1016 if (twl_has_regulator() && twl_class_is_6030()) { 988 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030()) {
1017 child = add_regulator(TWL6030_REG_VANA, pdata->vana, 989 child = add_regulator(TWL6030_REG_VANA, pdata->vana,
1018 features); 990 features);
1019 if (IS_ERR(child)) 991 if (IS_ERR(child))
@@ -1021,7 +993,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
1021 } 993 }
1022 994
1023 /* twl6025 regulators */ 995 /* twl6025 regulators */
1024 if (twl_has_regulator() && twl_class_is_6030() && 996 if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
1025 (features & TWL6025_SUBCLASS)) { 997 (features & TWL6025_SUBCLASS)) {
1026 child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5, 998 child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5,
1027 features); 999 features);
@@ -1080,7 +1052,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned irq_base,
1080 1052
1081 } 1053 }
1082 1054
1083 if (twl_has_bci() && pdata->bci && 1055 if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
1084 !(features & (TPS_SUBSET | TWL5031))) { 1056 !(features & (TPS_SUBSET | TWL5031))) {
1085 child = add_child(3, "twl4030_bci", 1057 child = add_child(3, "twl4030_bci",
1086 pdata->bci, sizeof(*pdata->bci), false, 1058 pdata->bci, sizeof(*pdata->bci), false,
@@ -1295,7 +1267,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
1295 } 1267 }
1296 1268
1297 /* load power event scripts */ 1269 /* load power event scripts */
1298 if (twl_has_power() && pdata->power) 1270 if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power)
1299 twl4030_power_init(pdata->power); 1271 twl4030_power_init(pdata->power);
1300 1272
1301 /* Maybe init the T2 Interrupt subsystem */ 1273 /* Maybe init the T2 Interrupt subsystem */
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 77c9acb14583..5c11acf9e0fd 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -28,6 +28,8 @@
28#include <linux/kernel.h> 28#include <linux/kernel.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/of.h>
32#include <linux/of_platform.h>
31#include <linux/i2c/twl.h> 33#include <linux/i2c/twl.h>
32#include <linux/mfd/core.h> 34#include <linux/mfd/core.h>
33#include <linux/mfd/twl4030-audio.h> 35#include <linux/mfd/twl4030-audio.h>
@@ -156,47 +158,70 @@ unsigned int twl4030_audio_get_mclk(void)
156} 158}
157EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk); 159EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
158 160
161static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
162 struct device_node *node)
163{
164 if (pdata && pdata->codec)
165 return true;
166
167 if (of_find_node_by_name(node, "codec"))
168 return true;
169
170 return false;
171}
172
173static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
174 struct device_node *node)
175{
176 int vibra;
177
178 if (pdata && pdata->vibra)
179 return true;
180
181 if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra)
182 return true;
183
184 return false;
185}
186
159static int __devinit twl4030_audio_probe(struct platform_device *pdev) 187static int __devinit twl4030_audio_probe(struct platform_device *pdev)
160{ 188{
161 struct twl4030_audio *audio; 189 struct twl4030_audio *audio;
162 struct twl4030_audio_data *pdata = pdev->dev.platform_data; 190 struct twl4030_audio_data *pdata = pdev->dev.platform_data;
191 struct device_node *node = pdev->dev.of_node;
163 struct mfd_cell *cell = NULL; 192 struct mfd_cell *cell = NULL;
164 int ret, childs = 0; 193 int ret, childs = 0;
165 u8 val; 194 u8 val;
166 195
167 if (!pdata) { 196 if (!pdata && !node) {
168 dev_err(&pdev->dev, "Platform data is missing\n"); 197 dev_err(&pdev->dev, "Platform data is missing\n");
169 return -EINVAL; 198 return -EINVAL;
170 } 199 }
171 200
201 audio = devm_kzalloc(&pdev->dev, sizeof(struct twl4030_audio),
202 GFP_KERNEL);
203 if (!audio)
204 return -ENOMEM;
205
206 mutex_init(&audio->mutex);
207 audio->audio_mclk = twl_get_hfclk_rate();
208
172 /* Configure APLL_INFREQ and disable APLL if enabled */ 209 /* Configure APLL_INFREQ and disable APLL if enabled */
173 val = 0; 210 switch (audio->audio_mclk) {
174 switch (pdata->audio_mclk) {
175 case 19200000: 211 case 19200000:
176 val |= TWL4030_APLL_INFREQ_19200KHZ; 212 val = TWL4030_APLL_INFREQ_19200KHZ;
177 break; 213 break;
178 case 26000000: 214 case 26000000:
179 val |= TWL4030_APLL_INFREQ_26000KHZ; 215 val = TWL4030_APLL_INFREQ_26000KHZ;
180 break; 216 break;
181 case 38400000: 217 case 38400000:
182 val |= TWL4030_APLL_INFREQ_38400KHZ; 218 val = TWL4030_APLL_INFREQ_38400KHZ;
183 break; 219 break;
184 default: 220 default:
185 dev_err(&pdev->dev, "Invalid audio_mclk\n"); 221 dev_err(&pdev->dev, "Invalid audio_mclk\n");
186 return -EINVAL; 222 return -EINVAL;
187 } 223 }
188 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 224 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, val, TWL4030_REG_APLL_CTL);
189 val, TWL4030_REG_APLL_CTL);
190
191 audio = kzalloc(sizeof(struct twl4030_audio), GFP_KERNEL);
192 if (!audio)
193 return -ENOMEM;
194
195 platform_set_drvdata(pdev, audio);
196
197 twl4030_audio_dev = pdev;
198 mutex_init(&audio->mutex);
199 audio->audio_mclk = pdata->audio_mclk;
200 225
201 /* Codec power */ 226 /* Codec power */
202 audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE; 227 audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
@@ -206,21 +231,28 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
206 audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL; 231 audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
207 audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN; 232 audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;
208 233
209 if (pdata->codec) { 234 if (twl4030_audio_has_codec(pdata, node)) {
210 cell = &audio->cells[childs]; 235 cell = &audio->cells[childs];
211 cell->name = "twl4030-codec"; 236 cell->name = "twl4030-codec";
212 cell->platform_data = pdata->codec; 237 if (pdata) {
213 cell->pdata_size = sizeof(*pdata->codec); 238 cell->platform_data = pdata->codec;
239 cell->pdata_size = sizeof(*pdata->codec);
240 }
214 childs++; 241 childs++;
215 } 242 }
216 if (pdata->vibra) { 243 if (twl4030_audio_has_vibra(pdata, node)) {
217 cell = &audio->cells[childs]; 244 cell = &audio->cells[childs];
218 cell->name = "twl4030-vibra"; 245 cell->name = "twl4030-vibra";
219 cell->platform_data = pdata->vibra; 246 if (pdata) {
220 cell->pdata_size = sizeof(*pdata->vibra); 247 cell->platform_data = pdata->vibra;
248 cell->pdata_size = sizeof(*pdata->vibra);
249 }
221 childs++; 250 childs++;
222 } 251 }
223 252
253 platform_set_drvdata(pdev, audio);
254 twl4030_audio_dev = pdev;
255
224 if (childs) 256 if (childs)
225 ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, 257 ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells,
226 childs, NULL, 0, NULL); 258 childs, NULL, 0, NULL);
@@ -229,39 +261,42 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev)
229 ret = -ENODEV; 261 ret = -ENODEV;
230 } 262 }
231 263
232 if (!ret) 264 if (ret) {
233 return 0; 265 platform_set_drvdata(pdev, NULL);
266 twl4030_audio_dev = NULL;
267 }
234 268
235 platform_set_drvdata(pdev, NULL);
236 kfree(audio);
237 twl4030_audio_dev = NULL;
238 return ret; 269 return ret;
239} 270}
240 271
241static int __devexit twl4030_audio_remove(struct platform_device *pdev) 272static int __devexit twl4030_audio_remove(struct platform_device *pdev)
242{ 273{
243 struct twl4030_audio *audio = platform_get_drvdata(pdev);
244
245 mfd_remove_devices(&pdev->dev); 274 mfd_remove_devices(&pdev->dev);
246 platform_set_drvdata(pdev, NULL); 275 platform_set_drvdata(pdev, NULL);
247 kfree(audio);
248 twl4030_audio_dev = NULL; 276 twl4030_audio_dev = NULL;
249 277
250 return 0; 278 return 0;
251} 279}
252 280
253MODULE_ALIAS("platform:twl4030-audio"); 281static const struct of_device_id twl4030_audio_of_match[] = {
282 {.compatible = "ti,twl4030-audio", },
283 { },
284};
285MODULE_DEVICE_TABLE(of, twl4030_audio_of_match);
254 286
255static struct platform_driver twl4030_audio_driver = { 287static struct platform_driver twl4030_audio_driver = {
256 .probe = twl4030_audio_probe,
257 .remove = __devexit_p(twl4030_audio_remove),
258 .driver = { 288 .driver = {
259 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
260 .name = "twl4030-audio", 290 .name = "twl4030-audio",
291 .of_match_table = twl4030_audio_of_match,
261 }, 292 },
293 .probe = twl4030_audio_probe,
294 .remove = __devexit_p(twl4030_audio_remove),
262}; 295};
263 296
264module_platform_driver(twl4030_audio_driver); 297module_platform_driver(twl4030_audio_driver);
265 298
266MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); 299MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
300MODULE_DESCRIPTION("TWL4030 audio block MFD driver");
267MODULE_LICENSE("GPL"); 301MODULE_LICENSE("GPL");
302MODULE_ALIAS("platform:twl4030-audio");
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index 3dca5c195a20..3f2a1cf02fc0 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -584,7 +584,7 @@ static int __devinit twl6040_probe(struct i2c_client *client,
584 goto irq_init_err; 584 goto irq_init_err;
585 585
586 ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY, 586 ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY,
587 NULL, twl6040_naudint_handler, 0, 587 NULL, twl6040_naudint_handler, IRQF_ONESHOT,
588 "twl6040_irq_ready", twl6040); 588 "twl6040_irq_ready", twl6040);
589 if (ret) { 589 if (ret) {
590 dev_err(twl6040->dev, "READY IRQ request failed: %d\n", 590 dev_err(twl6040->dev, "READY IRQ request failed: %d\n",
@@ -631,6 +631,21 @@ static int __devinit twl6040_probe(struct i2c_client *client,
631 children++; 631 children++;
632 } 632 }
633 633
634 /*
635 * Enable the GPO driver in the following cases:
636 * DT booted kernel or legacy boot with valid gpo platform_data
637 */
638 if (!pdata || (pdata && pdata->gpo)) {
639 cell = &twl6040->cells[children];
640 cell->name = "twl6040-gpo";
641
642 if (pdata) {
643 cell->platform_data = pdata->gpo;
644 cell->pdata_size = sizeof(*pdata->gpo);
645 }
646 children++;
647 }
648
634 ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, 649 ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
635 NULL, 0, NULL); 650 NULL, 0, NULL);
636 if (ret) 651 if (ret)
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index bd8782c8896b..adda6b10b90d 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -133,15 +133,109 @@ static const struct reg_default wm5110_reva_patch[] = {
133 { 0x209, 0x002A }, 133 { 0x209, 0x002A },
134}; 134};
135 135
136static const struct reg_default wm5110_revb_patch[] = {
137 { 0x80, 0x3 },
138 { 0x36e, 0x0210 },
139 { 0x370, 0x0210 },
140 { 0x372, 0x0210 },
141 { 0x374, 0x0210 },
142 { 0x376, 0x0210 },
143 { 0x378, 0x0210 },
144 { 0x36d, 0x0028 },
145 { 0x36f, 0x0028 },
146 { 0x371, 0x0028 },
147 { 0x373, 0x0028 },
148 { 0x375, 0x0028 },
149 { 0x377, 0x0028 },
150 { 0x280, 0x2002 },
151 { 0x44, 0x20 },
152 { 0x45, 0x40 },
153 { 0x46, 0x60 },
154 { 0x47, 0x80 },
155 { 0x48, 0xa0 },
156 { 0x51, 0x13 },
157 { 0x52, 0x33 },
158 { 0x53, 0x53 },
159 { 0x54, 0x73 },
160 { 0x55, 0x93 },
161 { 0x56, 0xb3 },
162 { 0xc30, 0x3e3e },
163 { 0xc31, 0x3e },
164 { 0xc32, 0x3e3e },
165 { 0xc33, 0x3e3e },
166 { 0xc34, 0x3e3e },
167 { 0xc35, 0x3e3e },
168 { 0xc36, 0x3e3e },
169 { 0xc37, 0x3e3e },
170 { 0xc38, 0x3e3e },
171 { 0xc39, 0x3e3e },
172 { 0xc3a, 0x3e3e },
173 { 0xc3b, 0x3e3e },
174 { 0xc3c, 0x3e },
175 { 0x201, 0x18a5 },
176 { 0x202, 0x4100 },
177 { 0x460, 0x0c40 },
178 { 0x461, 0x8000 },
179 { 0x462, 0x0c41 },
180 { 0x463, 0x4820 },
181 { 0x464, 0x0c41 },
182 { 0x465, 0x4040 },
183 { 0x466, 0x0841 },
184 { 0x467, 0x3940 },
185 { 0x468, 0x0841 },
186 { 0x469, 0x2030 },
187 { 0x46a, 0x0842 },
188 { 0x46b, 0x1990 },
189 { 0x46c, 0x08c2 },
190 { 0x46d, 0x1450 },
191 { 0x46e, 0x08c6 },
192 { 0x46f, 0x1020 },
193 { 0x470, 0x08c6 },
194 { 0x471, 0x0cd0 },
195 { 0x472, 0x08c6 },
196 { 0x473, 0x0a30 },
197 { 0x474, 0x0442 },
198 { 0x475, 0x0660 },
199 { 0x476, 0x0446 },
200 { 0x477, 0x0510 },
201 { 0x478, 0x04c6 },
202 { 0x479, 0x0400 },
203 { 0x47a, 0x04ce },
204 { 0x47b, 0x0330 },
205 { 0x47c, 0x05df },
206 { 0x47d, 0x0001 },
207 { 0x47e, 0x07ff },
208 { 0x2db, 0x0a00 },
209 { 0x2dd, 0x0023 },
210 { 0x2df, 0x0102 },
211 { 0x2ef, 0x924 },
212 { 0x2f0, 0x924 },
213 { 0x2f1, 0x924 },
214 { 0x2f2, 0x924 },
215 { 0x2f3, 0x924 },
216 { 0x2f4, 0x924 },
217 { 0x2eb, 0x60 },
218 { 0x2ec, 0x60 },
219 { 0x2ed, 0x60 },
220 { 0x4f2, 0x33e },
221 { 0x458, 0x0000 },
222 { 0x15a, 0x0003 },
223 { 0x80, 0x0 },
224};
225
136/* We use a function so we can use ARRAY_SIZE() */ 226/* We use a function so we can use ARRAY_SIZE() */
137int wm5110_patch(struct arizona *arizona) 227int wm5110_patch(struct arizona *arizona)
138{ 228{
139 switch (arizona->rev) { 229 switch (arizona->rev) {
140 case 0: 230 case 0:
141 case 1:
142 return regmap_register_patch(arizona->regmap, 231 return regmap_register_patch(arizona->regmap,
143 wm5110_reva_patch, 232 wm5110_reva_patch,
144 ARRAY_SIZE(wm5110_reva_patch)); 233 ARRAY_SIZE(wm5110_reva_patch));
234 case 1:
235 return regmap_register_patch(arizona->regmap,
236 wm5110_revb_patch,
237 ARRAY_SIZE(wm5110_revb_patch));
238
145 default: 239 default:
146 return 0; 240 return 0;
147 } 241 }
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 301731035940..521340a708d3 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -614,18 +614,11 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
614} 614}
615EXPORT_SYMBOL_GPL(wm831x_set_bits); 615EXPORT_SYMBOL_GPL(wm831x_set_bits);
616 616
617static struct resource wm831x_io_parent = {
618 .start = 0,
619 .end = 0xffffffff,
620 .flags = IORESOURCE_IO,
621};
622
623static struct resource wm831x_dcdc1_resources[] = { 617static struct resource wm831x_dcdc1_resources[] = {
624 { 618 {
625 .parent = &wm831x_io_parent,
626 .start = WM831X_DC1_CONTROL_1, 619 .start = WM831X_DC1_CONTROL_1,
627 .end = WM831X_DC1_DVS_CONTROL, 620 .end = WM831X_DC1_DVS_CONTROL,
628 .flags = IORESOURCE_IO, 621 .flags = IORESOURCE_REG,
629 }, 622 },
630 { 623 {
631 .name = "UV", 624 .name = "UV",
@@ -644,10 +637,9 @@ static struct resource wm831x_dcdc1_resources[] = {
644 637
645static struct resource wm831x_dcdc2_resources[] = { 638static struct resource wm831x_dcdc2_resources[] = {
646 { 639 {
647 .parent = &wm831x_io_parent,
648 .start = WM831X_DC2_CONTROL_1, 640 .start = WM831X_DC2_CONTROL_1,
649 .end = WM831X_DC2_DVS_CONTROL, 641 .end = WM831X_DC2_DVS_CONTROL,
650 .flags = IORESOURCE_IO, 642 .flags = IORESOURCE_REG,
651 }, 643 },
652 { 644 {
653 .name = "UV", 645 .name = "UV",
@@ -665,10 +657,9 @@ static struct resource wm831x_dcdc2_resources[] = {
665 657
666static struct resource wm831x_dcdc3_resources[] = { 658static struct resource wm831x_dcdc3_resources[] = {
667 { 659 {
668 .parent = &wm831x_io_parent,
669 .start = WM831X_DC3_CONTROL_1, 660 .start = WM831X_DC3_CONTROL_1,
670 .end = WM831X_DC3_SLEEP_CONTROL, 661 .end = WM831X_DC3_SLEEP_CONTROL,
671 .flags = IORESOURCE_IO, 662 .flags = IORESOURCE_REG,
672 }, 663 },
673 { 664 {
674 .name = "UV", 665 .name = "UV",
@@ -680,10 +671,9 @@ static struct resource wm831x_dcdc3_resources[] = {
680 671
681static struct resource wm831x_dcdc4_resources[] = { 672static struct resource wm831x_dcdc4_resources[] = {
682 { 673 {
683 .parent = &wm831x_io_parent,
684 .start = WM831X_DC4_CONTROL, 674 .start = WM831X_DC4_CONTROL,
685 .end = WM831X_DC4_SLEEP_CONTROL, 675 .end = WM831X_DC4_SLEEP_CONTROL,
686 .flags = IORESOURCE_IO, 676 .flags = IORESOURCE_REG,
687 }, 677 },
688 { 678 {
689 .name = "UV", 679 .name = "UV",
@@ -695,10 +685,9 @@ static struct resource wm831x_dcdc4_resources[] = {
695 685
696static struct resource wm8320_dcdc4_buck_resources[] = { 686static struct resource wm8320_dcdc4_buck_resources[] = {
697 { 687 {
698 .parent = &wm831x_io_parent,
699 .start = WM831X_DC4_CONTROL, 688 .start = WM831X_DC4_CONTROL,
700 .end = WM832X_DC4_SLEEP_CONTROL, 689 .end = WM832X_DC4_SLEEP_CONTROL,
701 .flags = IORESOURCE_IO, 690 .flags = IORESOURCE_REG,
702 }, 691 },
703 { 692 {
704 .name = "UV", 693 .name = "UV",
@@ -718,10 +707,9 @@ static struct resource wm831x_gpio_resources[] = {
718 707
719static struct resource wm831x_isink1_resources[] = { 708static struct resource wm831x_isink1_resources[] = {
720 { 709 {
721 .parent = &wm831x_io_parent,
722 .start = WM831X_CURRENT_SINK_1, 710 .start = WM831X_CURRENT_SINK_1,
723 .end = WM831X_CURRENT_SINK_1, 711 .end = WM831X_CURRENT_SINK_1,
724 .flags = IORESOURCE_IO, 712 .flags = IORESOURCE_REG,
725 }, 713 },
726 { 714 {
727 .start = WM831X_IRQ_CS1, 715 .start = WM831X_IRQ_CS1,
@@ -732,10 +720,9 @@ static struct resource wm831x_isink1_resources[] = {
732 720
733static struct resource wm831x_isink2_resources[] = { 721static struct resource wm831x_isink2_resources[] = {
734 { 722 {
735 .parent = &wm831x_io_parent,
736 .start = WM831X_CURRENT_SINK_2, 723 .start = WM831X_CURRENT_SINK_2,
737 .end = WM831X_CURRENT_SINK_2, 724 .end = WM831X_CURRENT_SINK_2,
738 .flags = IORESOURCE_IO, 725 .flags = IORESOURCE_REG,
739 }, 726 },
740 { 727 {
741 .start = WM831X_IRQ_CS2, 728 .start = WM831X_IRQ_CS2,
@@ -746,10 +733,9 @@ static struct resource wm831x_isink2_resources[] = {
746 733
747static struct resource wm831x_ldo1_resources[] = { 734static struct resource wm831x_ldo1_resources[] = {
748 { 735 {
749 .parent = &wm831x_io_parent,
750 .start = WM831X_LDO1_CONTROL, 736 .start = WM831X_LDO1_CONTROL,
751 .end = WM831X_LDO1_SLEEP_CONTROL, 737 .end = WM831X_LDO1_SLEEP_CONTROL,
752 .flags = IORESOURCE_IO, 738 .flags = IORESOURCE_REG,
753 }, 739 },
754 { 740 {
755 .name = "UV", 741 .name = "UV",
@@ -761,10 +747,9 @@ static struct resource wm831x_ldo1_resources[] = {
761 747
762static struct resource wm831x_ldo2_resources[] = { 748static struct resource wm831x_ldo2_resources[] = {
763 { 749 {
764 .parent = &wm831x_io_parent,
765 .start = WM831X_LDO2_CONTROL, 750 .start = WM831X_LDO2_CONTROL,
766 .end = WM831X_LDO2_SLEEP_CONTROL, 751 .end = WM831X_LDO2_SLEEP_CONTROL,
767 .flags = IORESOURCE_IO, 752 .flags = IORESOURCE_REG,
768 }, 753 },
769 { 754 {
770 .name = "UV", 755 .name = "UV",
@@ -776,10 +761,9 @@ static struct resource wm831x_ldo2_resources[] = {
776 761
777static struct resource wm831x_ldo3_resources[] = { 762static struct resource wm831x_ldo3_resources[] = {
778 { 763 {
779 .parent = &wm831x_io_parent,
780 .start = WM831X_LDO3_CONTROL, 764 .start = WM831X_LDO3_CONTROL,
781 .end = WM831X_LDO3_SLEEP_CONTROL, 765 .end = WM831X_LDO3_SLEEP_CONTROL,
782 .flags = IORESOURCE_IO, 766 .flags = IORESOURCE_REG,
783 }, 767 },
784 { 768 {
785 .name = "UV", 769 .name = "UV",
@@ -791,10 +775,9 @@ static struct resource wm831x_ldo3_resources[] = {
791 775
792static struct resource wm831x_ldo4_resources[] = { 776static struct resource wm831x_ldo4_resources[] = {
793 { 777 {
794 .parent = &wm831x_io_parent,
795 .start = WM831X_LDO4_CONTROL, 778 .start = WM831X_LDO4_CONTROL,
796 .end = WM831X_LDO4_SLEEP_CONTROL, 779 .end = WM831X_LDO4_SLEEP_CONTROL,
797 .flags = IORESOURCE_IO, 780 .flags = IORESOURCE_REG,
798 }, 781 },
799 { 782 {
800 .name = "UV", 783 .name = "UV",
@@ -806,10 +789,9 @@ static struct resource wm831x_ldo4_resources[] = {
806 789
807static struct resource wm831x_ldo5_resources[] = { 790static struct resource wm831x_ldo5_resources[] = {
808 { 791 {
809 .parent = &wm831x_io_parent,
810 .start = WM831X_LDO5_CONTROL, 792 .start = WM831X_LDO5_CONTROL,
811 .end = WM831X_LDO5_SLEEP_CONTROL, 793 .end = WM831X_LDO5_SLEEP_CONTROL,
812 .flags = IORESOURCE_IO, 794 .flags = IORESOURCE_REG,
813 }, 795 },
814 { 796 {
815 .name = "UV", 797 .name = "UV",
@@ -821,10 +803,9 @@ static struct resource wm831x_ldo5_resources[] = {
821 803
822static struct resource wm831x_ldo6_resources[] = { 804static struct resource wm831x_ldo6_resources[] = {
823 { 805 {
824 .parent = &wm831x_io_parent,
825 .start = WM831X_LDO6_CONTROL, 806 .start = WM831X_LDO6_CONTROL,
826 .end = WM831X_LDO6_SLEEP_CONTROL, 807 .end = WM831X_LDO6_SLEEP_CONTROL,
827 .flags = IORESOURCE_IO, 808 .flags = IORESOURCE_REG,
828 }, 809 },
829 { 810 {
830 .name = "UV", 811 .name = "UV",
@@ -836,10 +817,9 @@ static struct resource wm831x_ldo6_resources[] = {
836 817
837static struct resource wm831x_ldo7_resources[] = { 818static struct resource wm831x_ldo7_resources[] = {
838 { 819 {
839 .parent = &wm831x_io_parent,
840 .start = WM831X_LDO7_CONTROL, 820 .start = WM831X_LDO7_CONTROL,
841 .end = WM831X_LDO7_SLEEP_CONTROL, 821 .end = WM831X_LDO7_SLEEP_CONTROL,
842 .flags = IORESOURCE_IO, 822 .flags = IORESOURCE_REG,
843 }, 823 },
844 { 824 {
845 .name = "UV", 825 .name = "UV",
@@ -851,10 +831,9 @@ static struct resource wm831x_ldo7_resources[] = {
851 831
852static struct resource wm831x_ldo8_resources[] = { 832static struct resource wm831x_ldo8_resources[] = {
853 { 833 {
854 .parent = &wm831x_io_parent,
855 .start = WM831X_LDO8_CONTROL, 834 .start = WM831X_LDO8_CONTROL,
856 .end = WM831X_LDO8_SLEEP_CONTROL, 835 .end = WM831X_LDO8_SLEEP_CONTROL,
857 .flags = IORESOURCE_IO, 836 .flags = IORESOURCE_REG,
858 }, 837 },
859 { 838 {
860 .name = "UV", 839 .name = "UV",
@@ -866,10 +845,9 @@ static struct resource wm831x_ldo8_resources[] = {
866 845
867static struct resource wm831x_ldo9_resources[] = { 846static struct resource wm831x_ldo9_resources[] = {
868 { 847 {
869 .parent = &wm831x_io_parent,
870 .start = WM831X_LDO9_CONTROL, 848 .start = WM831X_LDO9_CONTROL,
871 .end = WM831X_LDO9_SLEEP_CONTROL, 849 .end = WM831X_LDO9_SLEEP_CONTROL,
872 .flags = IORESOURCE_IO, 850 .flags = IORESOURCE_REG,
873 }, 851 },
874 { 852 {
875 .name = "UV", 853 .name = "UV",
@@ -881,10 +859,9 @@ static struct resource wm831x_ldo9_resources[] = {
881 859
882static struct resource wm831x_ldo10_resources[] = { 860static struct resource wm831x_ldo10_resources[] = {
883 { 861 {
884 .parent = &wm831x_io_parent,
885 .start = WM831X_LDO10_CONTROL, 862 .start = WM831X_LDO10_CONTROL,
886 .end = WM831X_LDO10_SLEEP_CONTROL, 863 .end = WM831X_LDO10_SLEEP_CONTROL,
887 .flags = IORESOURCE_IO, 864 .flags = IORESOURCE_REG,
888 }, 865 },
889 { 866 {
890 .name = "UV", 867 .name = "UV",
@@ -896,10 +873,9 @@ static struct resource wm831x_ldo10_resources[] = {
896 873
897static struct resource wm831x_ldo11_resources[] = { 874static struct resource wm831x_ldo11_resources[] = {
898 { 875 {
899 .parent = &wm831x_io_parent,
900 .start = WM831X_LDO11_ON_CONTROL, 876 .start = WM831X_LDO11_ON_CONTROL,
901 .end = WM831X_LDO11_SLEEP_CONTROL, 877 .end = WM831X_LDO11_SLEEP_CONTROL,
902 .flags = IORESOURCE_IO, 878 .flags = IORESOURCE_REG,
903 }, 879 },
904}; 880};
905 881
@@ -998,19 +974,17 @@ static struct resource wm831x_rtc_resources[] = {
998 974
999static struct resource wm831x_status1_resources[] = { 975static struct resource wm831x_status1_resources[] = {
1000 { 976 {
1001 .parent = &wm831x_io_parent,
1002 .start = WM831X_STATUS_LED_1, 977 .start = WM831X_STATUS_LED_1,
1003 .end = WM831X_STATUS_LED_1, 978 .end = WM831X_STATUS_LED_1,
1004 .flags = IORESOURCE_IO, 979 .flags = IORESOURCE_REG,
1005 }, 980 },
1006}; 981};
1007 982
1008static struct resource wm831x_status2_resources[] = { 983static struct resource wm831x_status2_resources[] = {
1009 { 984 {
1010 .parent = &wm831x_io_parent,
1011 .start = WM831X_STATUS_LED_2, 985 .start = WM831X_STATUS_LED_2,
1012 .end = WM831X_STATUS_LED_2, 986 .end = WM831X_STATUS_LED_2,
1013 .flags = IORESOURCE_IO, 987 .flags = IORESOURCE_REG,
1014 }, 988 },
1015}; 989};
1016 990
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 2febf88cfce8..3d6d9beb18d4 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -390,7 +390,7 @@ static const __devinitdata struct reg_default wm8958_reva_patch[] = {
390 390
391static const __devinitdata struct reg_default wm1811_reva_patch[] = { 391static const __devinitdata struct reg_default wm1811_reva_patch[] = {
392 { 0x102, 0x3 }, 392 { 0x102, 0x3 },
393 { 0x56, 0x7 }, 393 { 0x56, 0xc07 },
394 { 0x5d, 0x7e }, 394 { 0x5d, 0x7e },
395 { 0x5e, 0x0 }, 395 { 0x5e, 0x0 },
396 { 0x102, 0x0 }, 396 { 0x102, 0x0 },
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index 52e9e2944940..2fbce9c5950b 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -1136,7 +1136,7 @@ static bool wm1811_volatile_register(struct device *dev, unsigned int reg)
1136 1136
1137 switch (reg) { 1137 switch (reg) {
1138 case WM8994_GPIO_6: 1138 case WM8994_GPIO_6:
1139 if (wm8994->revision > 1) 1139 if (wm8994->cust_id > 1 || wm8994->revision > 1)
1140 return true; 1140 return true;
1141 else 1141 else
1142 return false; 1142 return false;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 90c5c7357a50..d7c6b83097c1 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -115,6 +115,15 @@ config PWM_TIEHRPWM
115 To compile this driver as a module, choose M here: the module 115 To compile this driver as a module, choose M here: the module
116 will be called pwm-tiehrpwm. 116 will be called pwm-tiehrpwm.
117 117
118config PWM_TWL6030
119 tristate "TWL6030 PWM support"
120 depends on TWL4030_CORE
121 help
122 Generic PWM framework driver for TWL6030.
123
124 To compile this driver as a module, choose M here: the module
125 will be called pwm-twl6030.
126
118config PWM_VT8500 127config PWM_VT8500
119 tristate "vt8500 pwm support" 128 tristate "vt8500 pwm support"
120 depends on ARCH_VT8500 129 depends on ARCH_VT8500
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index e4b2c898964d..78f123dca30d 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
8obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o 8obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
9obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o 9obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o
10obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o 10obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o
11obj-$(CONFIG_PWM_TWL6030) += pwm-twl6030.o
11obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o 12obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
diff --git a/drivers/mfd/twl6030-pwm.c b/drivers/pwm/pwm-twl6030.c
index e8fee147678d..8e6387864ca2 100644
--- a/drivers/mfd/twl6030-pwm.c
+++ b/drivers/pwm/pwm-twl6030.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/pwm.h>
23#include <linux/i2c/twl.h> 24#include <linux/i2c/twl.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25 26
@@ -45,40 +46,54 @@
45 46
46#define PWM_CTRL2_MODE_MASK 0x3 47#define PWM_CTRL2_MODE_MASK 0x3
47 48
48struct pwm_device { 49struct twl6030_pwm_chip {
49 const char *label; 50 struct pwm_chip chip;
50 unsigned int pwm_id;
51}; 51};
52 52
53int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) 53static int twl6030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
54{ 54{
55 u8 duty_cycle;
56 int ret; 55 int ret;
56 u8 val;
57 57
58 if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) 58 /* Configure PWM */
59 return -EINVAL; 59 val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
60 PWM_CTRL2_MODE_HW;
60 61
61 duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns; 62 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
63 if (ret < 0) {
64 dev_err(chip->dev, "%s: Failed to configure PWM, Error %d\n",
65 pwm->label, ret);
66 return ret;
67 }
62 68
63 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1); 69 return 0;
70}
64 71
72static int twl6030_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
73 int duty_ns, int period_ns)
74{
75 u8 duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns;
76 int ret;
77
78 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1);
65 if (ret < 0) { 79 if (ret < 0) {
66 pr_err("%s: Failed to configure PWM, Error %d\n", 80 pr_err("%s: Failed to configure PWM, Error %d\n",
67 pwm->label, ret); 81 pwm->label, ret);
68 return ret; 82 return ret;
69 } 83 }
84
70 return 0; 85 return 0;
71} 86}
72EXPORT_SYMBOL(pwm_config);
73 87
74int pwm_enable(struct pwm_device *pwm) 88static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
75{ 89{
76 u8 val;
77 int ret; 90 int ret;
91 u8 val;
78 92
79 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); 93 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
80 if (ret < 0) { 94 if (ret < 0) {
81 pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret); 95 dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
96 pwm->label, ret);
82 return ret; 97 return ret;
83 } 98 }
84 99
@@ -88,23 +103,23 @@ int pwm_enable(struct pwm_device *pwm)
88 103
89 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); 104 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
90 if (ret < 0) { 105 if (ret < 0) {
91 pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret); 106 dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
107 pwm->label, ret);
92 return ret; 108 return ret;
93 } 109 }
94 110
95 twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); 111 twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
96 return 0; 112 return 0;
97} 113}
98EXPORT_SYMBOL(pwm_enable);
99 114
100void pwm_disable(struct pwm_device *pwm) 115static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
101{ 116{
102 u8 val;
103 int ret; 117 int ret;
118 u8 val;
104 119
105 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); 120 ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
106 if (ret < 0) { 121 if (ret < 0) {
107 pr_err("%s: Failed to disable PWM, Error %d\n", 122 dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
108 pwm->label, ret); 123 pwm->label, ret);
109 return; 124 return;
110 } 125 }
@@ -114,52 +129,56 @@ void pwm_disable(struct pwm_device *pwm)
114 129
115 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); 130 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
116 if (ret < 0) { 131 if (ret < 0) {
117 pr_err("%s: Failed to disable PWM, Error %d\n", 132 dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
118 pwm->label, ret); 133 pwm->label, ret);
119 return;
120 } 134 }
121 return;
122} 135}
123EXPORT_SYMBOL(pwm_disable);
124 136
125struct pwm_device *pwm_request(int pwm_id, const char *label) 137static const struct pwm_ops twl6030_pwm_ops = {
138 .request = twl6030_pwm_request,
139 .config = twl6030_pwm_config,
140 .enable = twl6030_pwm_enable,
141 .disable = twl6030_pwm_disable,
142};
143
144static int twl6030_pwm_probe(struct platform_device *pdev)
126{ 145{
127 u8 val; 146 struct twl6030_pwm_chip *twl6030;
128 int ret; 147 int ret;
129 struct pwm_device *pwm;
130
131 pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
132 if (pwm == NULL) {
133 pr_err("%s: failed to allocate memory\n", label);
134 return NULL;
135 }
136 148
137 pwm->label = label; 149 twl6030 = devm_kzalloc(&pdev->dev, sizeof(*twl6030), GFP_KERNEL);
138 pwm->pwm_id = pwm_id; 150 if (!twl6030)
139 151 return -ENOMEM;
140 /* Configure PWM */
141 val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
142 PWM_CTRL2_MODE_HW;
143 152
144 ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); 153 twl6030->chip.dev = &pdev->dev;
154 twl6030->chip.ops = &twl6030_pwm_ops;
155 twl6030->chip.base = -1;
156 twl6030->chip.npwm = 1;
145 157
146 if (ret < 0) { 158 ret = pwmchip_add(&twl6030->chip);
147 pr_err("%s: Failed to configure PWM, Error %d\n", 159 if (ret < 0)
148 pwm->label, ret); 160 return ret;
149 161
150 kfree(pwm); 162 platform_set_drvdata(pdev, twl6030);
151 return NULL;
152 }
153 163
154 return pwm; 164 return 0;
155} 165}
156EXPORT_SYMBOL(pwm_request);
157 166
158void pwm_free(struct pwm_device *pwm) 167static int twl6030_pwm_remove(struct platform_device *pdev)
159{ 168{
160 pwm_disable(pwm); 169 struct twl6030_pwm_chip *twl6030 = platform_get_drvdata(pdev);
161 kfree(pwm); 170
171 return pwmchip_remove(&twl6030->chip);
162} 172}
163EXPORT_SYMBOL(pwm_free);
164 173
174static struct platform_driver twl6030_pwm_driver = {
175 .driver = {
176 .name = "twl6030-pwm",
177 },
178 .probe = twl6030_pwm_probe,
179 .remove = __devexit_p(twl6030_pwm_remove),
180};
181module_platform_driver(twl6030_pwm_driver);
182
183MODULE_ALIAS("platform:twl6030-pwm");
165MODULE_LICENSE("GPL"); 184MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index c3482b954cb7..1c5ab0172ea2 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -12,6 +12,8 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/of.h>
16#include <linux/regulator/of_regulator.h>
15#include <linux/platform_device.h> 17#include <linux/platform_device.h>
16#include <linux/regulator/driver.h> 18#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h> 19#include <linux/regulator/machine.h>
@@ -23,6 +25,7 @@ struct pm8607_regulator_info {
23 struct pm860x_chip *chip; 25 struct pm860x_chip *chip;
24 struct regulator_dev *regulator; 26 struct regulator_dev *regulator;
25 struct i2c_client *i2c; 27 struct i2c_client *i2c;
28 struct i2c_client *i2c_8606;
26 29
27 unsigned int *vol_table; 30 unsigned int *vol_table;
28 unsigned int *vol_suspend; 31 unsigned int *vol_suspend;
@@ -242,6 +245,35 @@ static int pm8607_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
242 return ret; 245 return ret;
243} 246}
244 247
248static int pm8606_preg_enable(struct regulator_dev *rdev)
249{
250 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
251
252 return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
253 1 << rdev->desc->enable_mask, 0);
254}
255
256static int pm8606_preg_disable(struct regulator_dev *rdev)
257{
258 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
259
260 return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
261 1 << rdev->desc->enable_mask,
262 1 << rdev->desc->enable_mask);
263}
264
265static int pm8606_preg_is_enabled(struct regulator_dev *rdev)
266{
267 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
268 int ret;
269
270 ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg);
271 if (ret < 0)
272 return ret;
273
274 return !((unsigned char)ret & (1 << rdev->desc->enable_mask));
275}
276
245static struct regulator_ops pm8607_regulator_ops = { 277static struct regulator_ops pm8607_regulator_ops = {
246 .list_voltage = pm8607_list_voltage, 278 .list_voltage = pm8607_list_voltage,
247 .set_voltage_sel = pm8607_set_voltage_sel, 279 .set_voltage_sel = pm8607_set_voltage_sel,
@@ -251,6 +283,25 @@ static struct regulator_ops pm8607_regulator_ops = {
251 .is_enabled = regulator_is_enabled_regmap, 283 .is_enabled = regulator_is_enabled_regmap,
252}; 284};
253 285
286static struct regulator_ops pm8606_preg_ops = {
287 .enable = pm8606_preg_enable,
288 .disable = pm8606_preg_disable,
289 .is_enabled = pm8606_preg_is_enabled,
290};
291
292#define PM8606_PREG(ereg, ebit) \
293{ \
294 .desc = { \
295 .name = "PREG", \
296 .ops = &pm8606_preg_ops, \
297 .type = REGULATOR_CURRENT, \
298 .id = PM8606_ID_PREG, \
299 .owner = THIS_MODULE, \
300 .enable_reg = PM8606_##ereg, \
301 .enable_mask = (ebit), \
302 }, \
303}
304
254#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \ 305#define PM8607_DVC(vreg, ureg, ubit, ereg, ebit) \
255{ \ 306{ \
256 .desc = { \ 307 .desc = { \
@@ -311,6 +362,38 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
311 PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6), 362 PM8607_LDO(14, LDO14, 0, SUPPLIES_EN12, 6),
312}; 363};
313 364
365static struct pm8607_regulator_info pm8606_regulator_info[] = {
366 PM8606_PREG(PREREGULATORB, 5),
367};
368
369#ifdef CONFIG_OF
370static int pm8607_regulator_dt_init(struct platform_device *pdev,
371 struct pm8607_regulator_info *info,
372 struct regulator_config *config)
373{
374 struct device_node *nproot, *np;
375 nproot = pdev->dev.parent->of_node;
376 if (!nproot)
377 return -ENODEV;
378 nproot = of_find_node_by_name(nproot, "regulators");
379 if (!nproot) {
380 dev_err(&pdev->dev, "failed to find regulators node\n");
381 return -ENODEV;
382 }
383 for_each_child_of_node(nproot, np) {
384 if (!of_node_cmp(np->name, info->desc.name)) {
385 config->init_data =
386 of_get_regulator_init_data(&pdev->dev, np);
387 config->of_node = np;
388 break;
389 }
390 }
391 return 0;
392}
393#else
394#define pm8607_regulator_dt_init(x, y, z) (-1)
395#endif
396
314static int __devinit pm8607_regulator_probe(struct platform_device *pdev) 397static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
315{ 398{
316 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 399 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -320,22 +403,28 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
320 struct resource *res; 403 struct resource *res;
321 int i; 404 int i;
322 405
323 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 406 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
324 if (res == NULL) { 407 if (res) {
325 dev_err(&pdev->dev, "No I/O resource!\n"); 408 /* There're resources in 88PM8607 regulator driver */
326 return -EINVAL; 409 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
327 } 410 info = &pm8607_regulator_info[i];
328 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { 411 if (info->desc.vsel_reg == res->start)
329 info = &pm8607_regulator_info[i]; 412 break;
330 if (info->desc.id == res->start) 413 }
331 break; 414 if (i == ARRAY_SIZE(pm8607_regulator_info)) {
332 } 415 dev_err(&pdev->dev, "Failed to find regulator %llu\n",
333 if (i == ARRAY_SIZE(pm8607_regulator_info)) { 416 (unsigned long long)res->start);
334 dev_err(&pdev->dev, "Failed to find regulator %llu\n", 417 return -EINVAL;
335 (unsigned long long)res->start); 418 }
336 return -EINVAL; 419 } else {
420 /* There's no resource in 88PM8606 PREG regulator driver */
421 info = &pm8606_regulator_info[0];
422 /* i is used to check regulator ID */
423 i = -1;
337 } 424 }
338 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 425 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
426 info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion :
427 chip->client;
339 info->chip = chip; 428 info->chip = chip;
340 429
341 /* check DVC ramp slope double */ 430 /* check DVC ramp slope double */
@@ -343,15 +432,17 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
343 info->slope_double = 1; 432 info->slope_double = 1;
344 433
345 config.dev = &pdev->dev; 434 config.dev = &pdev->dev;
346 config.init_data = pdata;
347 config.driver_data = info; 435 config.driver_data = info;
348 436
437 if (pm8607_regulator_dt_init(pdev, info, &config))
438 if (pdata)
439 config.init_data = pdata;
440
349 if (chip->id == CHIP_PM8607) 441 if (chip->id == CHIP_PM8607)
350 config.regmap = chip->regmap; 442 config.regmap = chip->regmap;
351 else 443 else
352 config.regmap = chip->regmap_companion; 444 config.regmap = chip->regmap_companion;
353 445
354 /* replace driver_data with info */
355 info->regulator = regulator_register(&info->desc, &config); 446 info->regulator = regulator_register(&info->desc, &config);
356 if (IS_ERR(info->regulator)) { 447 if (IS_ERR(info->regulator)) {
357 dev_err(&pdev->dev, "failed to register regulator %s\n", 448 dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -372,6 +463,18 @@ static int __devexit pm8607_regulator_remove(struct platform_device *pdev)
372 return 0; 463 return 0;
373} 464}
374 465
466static struct platform_device_id pm8607_regulator_driver_ids[] = {
467 {
468 .name = "88pm860x-regulator",
469 .driver_data = 0,
470 }, {
471 .name = "88pm860x-preg",
472 .driver_data = 0,
473 },
474 { },
475};
476MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
477
375static struct platform_driver pm8607_regulator_driver = { 478static struct platform_driver pm8607_regulator_driver = {
376 .driver = { 479 .driver = {
377 .name = "88pm860x-regulator", 480 .name = "88pm860x-regulator",
@@ -379,6 +482,7 @@ static struct platform_driver pm8607_regulator_driver = {
379 }, 482 },
380 .probe = pm8607_regulator_probe, 483 .probe = pm8607_regulator_probe,
381 .remove = __devexit_p(pm8607_regulator_remove), 484 .remove = __devexit_p(pm8607_regulator_remove),
485 .id_table = pm8607_regulator_driver_ids,
382}; 486};
383 487
384static int __init pm8607_regulator_init(void) 488static int __init pm8607_regulator_init(void)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e98a5e7827df..67d47b59a66d 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -122,7 +122,7 @@ config REGULATOR_FAN53555
122 122
123config REGULATOR_ANATOP 123config REGULATOR_ANATOP
124 tristate "Freescale i.MX on-chip ANATOP LDO regulators" 124 tristate "Freescale i.MX on-chip ANATOP LDO regulators"
125 depends on MFD_ANATOP 125 depends on MFD_SYSCON
126 help 126 help
127 Say y here to support Freescale i.MX on-chip ANATOP LDOs 127 Say y here to support Freescale i.MX on-chip ANATOP LDOs
128 regulators. It is recommended that this option be 128 regulators. It is recommended that this option be
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 65ad2b36ce36..df4ad8927f0c 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -15,6 +15,7 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/regulator/driver.h> 17#include <linux/regulator/driver.h>
18#include <linux/mfd/ab3100.h>
18#include <linux/mfd/abx500.h> 19#include <linux/mfd/abx500.h>
19 20
20/* LDO registers and some handy masking definitions for AB3100 */ 21/* LDO registers and some handy masking definitions for AB3100 */
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index ce0fe72a428e..1af97686f444 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -21,19 +21,20 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/mfd/syscon.h>
24#include <linux/err.h> 25#include <linux/err.h>
25#include <linux/io.h> 26#include <linux/io.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
27#include <linux/of.h> 28#include <linux/of.h>
28#include <linux/of_address.h> 29#include <linux/of_address.h>
29#include <linux/mfd/anatop.h> 30#include <linux/regmap.h>
30#include <linux/regulator/driver.h> 31#include <linux/regulator/driver.h>
31#include <linux/regulator/of_regulator.h> 32#include <linux/regulator/of_regulator.h>
32 33
33struct anatop_regulator { 34struct anatop_regulator {
34 const char *name; 35 const char *name;
35 u32 control_reg; 36 u32 control_reg;
36 struct anatop *mfd; 37 struct regmap *anatop;
37 int vol_bit_shift; 38 int vol_bit_shift;
38 int vol_bit_width; 39 int vol_bit_width;
39 int min_bit_val; 40 int min_bit_val;
@@ -43,7 +44,8 @@ struct anatop_regulator {
43 struct regulator_init_data *initdata; 44 struct regulator_init_data *initdata;
44}; 45};
45 46
46static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) 47static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg,
48 unsigned selector)
47{ 49{
48 struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); 50 struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
49 u32 val, mask; 51 u32 val, mask;
@@ -56,12 +58,13 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector)
56 mask = ((1 << anatop_reg->vol_bit_width) - 1) << 58 mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
57 anatop_reg->vol_bit_shift; 59 anatop_reg->vol_bit_shift;
58 val <<= anatop_reg->vol_bit_shift; 60 val <<= anatop_reg->vol_bit_shift;
59 anatop_write_reg(anatop_reg->mfd, anatop_reg->control_reg, val, mask); 61 regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg,
62 mask, val);
60 63
61 return 0; 64 return 0;
62} 65}
63 66
64static int anatop_get_voltage_sel(struct regulator_dev *reg) 67static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
65{ 68{
66 struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); 69 struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
67 u32 val, mask; 70 u32 val, mask;
@@ -69,7 +72,7 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg)
69 if (!anatop_reg->control_reg) 72 if (!anatop_reg->control_reg)
70 return -ENOTSUPP; 73 return -ENOTSUPP;
71 74
72 val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); 75 regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
73 mask = ((1 << anatop_reg->vol_bit_width) - 1) << 76 mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
74 anatop_reg->vol_bit_shift; 77 anatop_reg->vol_bit_shift;
75 val = (val & mask) >> anatop_reg->vol_bit_shift; 78 val = (val & mask) >> anatop_reg->vol_bit_shift;
@@ -78,8 +81,8 @@ static int anatop_get_voltage_sel(struct regulator_dev *reg)
78} 81}
79 82
80static struct regulator_ops anatop_rops = { 83static struct regulator_ops anatop_rops = {
81 .set_voltage_sel = anatop_set_voltage_sel, 84 .set_voltage_sel = anatop_regmap_set_voltage_sel,
82 .get_voltage_sel = anatop_get_voltage_sel, 85 .get_voltage_sel = anatop_regmap_get_voltage_sel,
83 .list_voltage = regulator_list_voltage_linear, 86 .list_voltage = regulator_list_voltage_linear,
84 .map_voltage = regulator_map_voltage_linear, 87 .map_voltage = regulator_map_voltage_linear,
85}; 88};
@@ -88,11 +91,11 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
88{ 91{
89 struct device *dev = &pdev->dev; 92 struct device *dev = &pdev->dev;
90 struct device_node *np = dev->of_node; 93 struct device_node *np = dev->of_node;
94 struct device_node *anatop_np;
91 struct regulator_desc *rdesc; 95 struct regulator_desc *rdesc;
92 struct regulator_dev *rdev; 96 struct regulator_dev *rdev;
93 struct anatop_regulator *sreg; 97 struct anatop_regulator *sreg;
94 struct regulator_init_data *initdata; 98 struct regulator_init_data *initdata;
95 struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
96 struct regulator_config config = { }; 99 struct regulator_config config = { };
97 int ret = 0; 100 int ret = 0;
98 101
@@ -109,7 +112,15 @@ static int __devinit anatop_regulator_probe(struct platform_device *pdev)
109 rdesc->ops = &anatop_rops; 112 rdesc->ops = &anatop_rops;
110 rdesc->type = REGULATOR_VOLTAGE; 113 rdesc->type = REGULATOR_VOLTAGE;
111 rdesc->owner = THIS_MODULE; 114 rdesc->owner = THIS_MODULE;
112 sreg->mfd = anatopmfd; 115
116 anatop_np = of_get_parent(np);
117 if (!anatop_np)
118 return -ENODEV;
119 sreg->anatop = syscon_node_to_regmap(anatop_np);
120 of_node_put(anatop_np);
121 if (IS_ERR(sreg->anatop))
122 return PTR_ERR(sreg->anatop);
123
113 ret = of_property_read_u32(np, "anatop-reg-offset", 124 ret = of_property_read_u32(np, "anatop-reg-offset",
114 &sreg->control_reg); 125 &sreg->control_reg);
115 if (ret) { 126 if (ret) {
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index 43dc97ec3932..9bb0be37495f 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -214,37 +214,36 @@ static struct max8925_regulator_info max8925_regulator_info[] = {
214 MAX8925_LDO(20, 750, 3900, 50), 214 MAX8925_LDO(20, 750, 3900, 50),
215}; 215};
216 216
217static struct max8925_regulator_info * __devinit find_regulator_info(int id)
218{
219 struct max8925_regulator_info *ri;
220 int i;
221
222 for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
223 ri = &max8925_regulator_info[i];
224 if (ri->desc.id == id)
225 return ri;
226 }
227 return NULL;
228}
229
230static int __devinit max8925_regulator_probe(struct platform_device *pdev) 217static int __devinit max8925_regulator_probe(struct platform_device *pdev)
231{ 218{
232 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); 219 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
233 struct max8925_platform_data *pdata = chip->dev->platform_data; 220 struct regulator_init_data *pdata = pdev->dev.platform_data;
234 struct regulator_config config = { }; 221 struct regulator_config config = { };
235 struct max8925_regulator_info *ri; 222 struct max8925_regulator_info *ri;
223 struct resource *res;
236 struct regulator_dev *rdev; 224 struct regulator_dev *rdev;
225 int i;
237 226
238 ri = find_regulator_info(pdev->id); 227 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
239 if (ri == NULL) { 228 if (!res) {
240 dev_err(&pdev->dev, "invalid regulator ID specified\n"); 229 dev_err(&pdev->dev, "No REG resource!\n");
230 return -EINVAL;
231 }
232 for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
233 ri = &max8925_regulator_info[i];
234 if (ri->vol_reg == res->start)
235 break;
236 }
237 if (i == ARRAY_SIZE(max8925_regulator_info)) {
238 dev_err(&pdev->dev, "Failed to find regulator %llu\n",
239 (unsigned long long)res->start);
241 return -EINVAL; 240 return -EINVAL;
242 } 241 }
243 ri->i2c = chip->i2c; 242 ri->i2c = chip->i2c;
244 ri->chip = chip; 243 ri->chip = chip;
245 244
246 config.dev = &pdev->dev; 245 config.dev = &pdev->dev;
247 config.init_data = pdata->regulator[pdev->id]; 246 config.init_data = pdata;
248 config.driver_data = ri; 247 config.driver_data = ri;
249 248
250 rdev = regulator_register(&ri->desc, &config); 249 rdev = regulator_register(&ri->desc, &config);
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 2ba7502fa3b2..07aee694ba92 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -22,6 +22,9 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/regmap.h> 23#include <linux/regmap.h>
24#include <linux/mfd/palmas.h> 24#include <linux/mfd/palmas.h>
25#include <linux/of.h>
26#include <linux/of_platform.h>
27#include <linux/regulator/of_regulator.h>
25 28
26struct regs_info { 29struct regs_info {
27 char *name; 30 char *name;
@@ -568,10 +571,103 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
568 return 0; 571 return 0;
569} 572}
570 573
574static struct of_regulator_match palmas_matches[] = {
575 { .name = "smps12", },
576 { .name = "smps123", },
577 { .name = "smps3", },
578 { .name = "smps45", },
579 { .name = "smps457", },
580 { .name = "smps6", },
581 { .name = "smps7", },
582 { .name = "smps8", },
583 { .name = "smps9", },
584 { .name = "smps10", },
585 { .name = "ldo1", },
586 { .name = "ldo2", },
587 { .name = "ldo3", },
588 { .name = "ldo4", },
589 { .name = "ldo5", },
590 { .name = "ldo6", },
591 { .name = "ldo7", },
592 { .name = "ldo8", },
593 { .name = "ldo9", },
594 { .name = "ldoln", },
595 { .name = "ldousb", },
596};
597
598static void __devinit palmas_dt_to_pdata(struct device *dev,
599 struct device_node *node,
600 struct palmas_pmic_platform_data *pdata)
601{
602 struct device_node *regulators;
603 u32 prop;
604 int idx, ret;
605
606 regulators = of_find_node_by_name(node, "regulators");
607 if (!regulators) {
608 dev_info(dev, "regulator node not found\n");
609 return;
610 }
611
612 ret = of_regulator_match(dev, regulators, palmas_matches,
613 PALMAS_NUM_REGS);
614 if (ret < 0) {
615 dev_err(dev, "Error parsing regulator init data: %d\n", ret);
616 return;
617 }
618
619 for (idx = 0; idx < PALMAS_NUM_REGS; idx++) {
620 if (!palmas_matches[idx].init_data ||
621 !palmas_matches[idx].of_node)
622 continue;
623
624 pdata->reg_data[idx] = palmas_matches[idx].init_data;
625
626 pdata->reg_init[idx] = devm_kzalloc(dev,
627 sizeof(struct palmas_reg_init), GFP_KERNEL);
628
629 ret = of_property_read_u32(palmas_matches[idx].of_node,
630 "ti,warm_reset", &prop);
631 if (!ret)
632 pdata->reg_init[idx]->warm_reset = prop;
633
634 ret = of_property_read_u32(palmas_matches[idx].of_node,
635 "ti,roof_floor", &prop);
636 if (!ret)
637 pdata->reg_init[idx]->roof_floor = prop;
638
639 ret = of_property_read_u32(palmas_matches[idx].of_node,
640 "ti,mode_sleep", &prop);
641 if (!ret)
642 pdata->reg_init[idx]->mode_sleep = prop;
643
644 ret = of_property_read_u32(palmas_matches[idx].of_node,
645 "ti,warm_reset", &prop);
646 if (!ret)
647 pdata->reg_init[idx]->warm_reset = prop;
648
649 ret = of_property_read_u32(palmas_matches[idx].of_node,
650 "ti,tstep", &prop);
651 if (!ret)
652 pdata->reg_init[idx]->tstep = prop;
653
654 ret = of_property_read_u32(palmas_matches[idx].of_node,
655 "ti,vsel", &prop);
656 if (!ret)
657 pdata->reg_init[idx]->vsel = prop;
658 }
659
660 ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop);
661 if (!ret)
662 pdata->ldo6_vibrator = prop;
663}
664
665
571static __devinit int palmas_probe(struct platform_device *pdev) 666static __devinit int palmas_probe(struct platform_device *pdev)
572{ 667{
573 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); 668 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
574 struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; 669 struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data;
670 struct device_node *node = pdev->dev.of_node;
575 struct regulator_dev *rdev; 671 struct regulator_dev *rdev;
576 struct regulator_config config = { }; 672 struct regulator_config config = { };
577 struct palmas_pmic *pmic; 673 struct palmas_pmic *pmic;
@@ -579,10 +675,14 @@ static __devinit int palmas_probe(struct platform_device *pdev)
579 int id = 0, ret; 675 int id = 0, ret;
580 unsigned int addr, reg; 676 unsigned int addr, reg;
581 677
582 if (!pdata) 678 if (node && !pdata) {
583 return -EINVAL; 679 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
584 if (!pdata->reg_data) 680
585 return -EINVAL; 681 if (!pdata)
682 return -ENOMEM;
683
684 palmas_dt_to_pdata(&pdev->dev, node, pdata);
685 }
586 686
587 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); 687 pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
588 if (!pmic) 688 if (!pmic)
@@ -661,7 +761,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
661 pmic->desc[id].owner = THIS_MODULE; 761 pmic->desc[id].owner = THIS_MODULE;
662 762
663 /* Initialise sleep/init values from platform data */ 763 /* Initialise sleep/init values from platform data */
664 if (pdata && pdata->reg_init) { 764 if (pdata) {
665 reg_init = pdata->reg_init[id]; 765 reg_init = pdata->reg_init[id];
666 if (reg_init) { 766 if (reg_init) {
667 ret = palmas_smps_init(palmas, id, reg_init); 767 ret = palmas_smps_init(palmas, id, reg_init);
@@ -685,11 +785,13 @@ static __devinit int palmas_probe(struct platform_device *pdev)
685 pmic->range[id] = 1; 785 pmic->range[id] = 1;
686 } 786 }
687 787
688 if (pdata && pdata->reg_data) 788 if (pdata)
689 config.init_data = pdata->reg_data[id]; 789 config.init_data = pdata->reg_data[id];
690 else 790 else
691 config.init_data = NULL; 791 config.init_data = NULL;
692 792
793 config.of_node = palmas_matches[id].of_node;
794
693 rdev = regulator_register(&pmic->desc[id], &config); 795 rdev = regulator_register(&pmic->desc[id], &config);
694 if (IS_ERR(rdev)) { 796 if (IS_ERR(rdev)) {
695 dev_err(&pdev->dev, 797 dev_err(&pdev->dev,
@@ -726,11 +828,13 @@ static __devinit int palmas_probe(struct platform_device *pdev)
726 palmas_regs_info[id].ctrl_addr); 828 palmas_regs_info[id].ctrl_addr);
727 pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; 829 pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
728 830
729 if (pdata && pdata->reg_data) 831 if (pdata)
730 config.init_data = pdata->reg_data[id]; 832 config.init_data = pdata->reg_data[id];
731 else 833 else
732 config.init_data = NULL; 834 config.init_data = NULL;
733 835
836 config.of_node = palmas_matches[id].of_node;
837
734 rdev = regulator_register(&pmic->desc[id], &config); 838 rdev = regulator_register(&pmic->desc[id], &config);
735 if (IS_ERR(rdev)) { 839 if (IS_ERR(rdev)) {
736 dev_err(&pdev->dev, 840 dev_err(&pdev->dev,
@@ -744,7 +848,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
744 pmic->rdev[id] = rdev; 848 pmic->rdev[id] = rdev;
745 849
746 /* Initialise sleep/init values from platform data */ 850 /* Initialise sleep/init values from platform data */
747 if (pdata->reg_init) { 851 if (pdata) {
748 reg_init = pdata->reg_init[id]; 852 reg_init = pdata->reg_init[id];
749 if (reg_init) { 853 if (reg_init) {
750 ret = palmas_ldo_init(palmas, id, reg_init); 854 ret = palmas_ldo_init(palmas, id, reg_init);
@@ -774,9 +878,15 @@ static int __devexit palmas_remove(struct platform_device *pdev)
774 return 0; 878 return 0;
775} 879}
776 880
881static struct of_device_id __devinitdata of_palmas_match_tbl[] = {
882 { .compatible = "ti,palmas-pmic", },
883 { /* end */ }
884};
885
777static struct platform_driver palmas_driver = { 886static struct platform_driver palmas_driver = {
778 .driver = { 887 .driver = {
779 .name = "palmas-pmic", 888 .name = "palmas-pmic",
889 .of_match_table = of_palmas_match_tbl,
780 .owner = THIS_MODULE, 890 .owner = THIS_MODULE,
781 }, 891 },
782 .probe = palmas_probe, 892 .probe = palmas_probe,
@@ -799,3 +909,4 @@ MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
799MODULE_DESCRIPTION("Palmas voltage regulator driver"); 909MODULE_DESCRIPTION("Palmas voltage regulator driver");
800MODULE_LICENSE("GPL"); 910MODULE_LICENSE("GPL");
801MODULE_ALIAS("platform:palmas-pmic"); 911MODULE_ALIAS("platform:palmas-pmic");
912MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 90cbcc683704..782c228a19bd 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -475,9 +475,9 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
475 475
476 dcdc->wm831x = wm831x; 476 dcdc->wm831x = wm831x;
477 477
478 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 478 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
479 if (res == NULL) { 479 if (res == NULL) {
480 dev_err(&pdev->dev, "No I/O resource\n"); 480 dev_err(&pdev->dev, "No REG resource\n");
481 ret = -EINVAL; 481 ret = -EINVAL;
482 goto err; 482 goto err;
483 } 483 }
@@ -650,9 +650,9 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
650 650
651 dcdc->wm831x = wm831x; 651 dcdc->wm831x = wm831x;
652 652
653 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 653 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
654 if (res == NULL) { 654 if (res == NULL) {
655 dev_err(&pdev->dev, "No I/O resource\n"); 655 dev_err(&pdev->dev, "No REG resource\n");
656 ret = -EINVAL; 656 ret = -EINVAL;
657 goto err; 657 goto err;
658 } 658 }
@@ -794,9 +794,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
794 794
795 dcdc->wm831x = wm831x; 795 dcdc->wm831x = wm831x;
796 796
797 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 797 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
798 if (res == NULL) { 798 if (res == NULL) {
799 dev_err(&pdev->dev, "No I/O resource\n"); 799 dev_err(&pdev->dev, "No REG resource\n");
800 ret = -EINVAL; 800 ret = -EINVAL;
801 goto err; 801 goto err;
802 } 802 }
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 0d207c297714..2646a1902b33 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -172,9 +172,9 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
172 172
173 isink->wm831x = wm831x; 173 isink->wm831x = wm831x;
174 174
175 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 175 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
176 if (res == NULL) { 176 if (res == NULL) {
177 dev_err(&pdev->dev, "No I/O resource\n"); 177 dev_err(&pdev->dev, "No REG resource\n");
178 ret = -EINVAL; 178 ret = -EINVAL;
179 goto err; 179 goto err;
180 } 180 }
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 9af512672be1..c2dc03993dc7 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -273,9 +273,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
273 273
274 ldo->wm831x = wm831x; 274 ldo->wm831x = wm831x;
275 275
276 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 276 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
277 if (res == NULL) { 277 if (res == NULL) {
278 dev_err(&pdev->dev, "No I/O resource\n"); 278 dev_err(&pdev->dev, "No REG resource\n");
279 ret = -EINVAL; 279 ret = -EINVAL;
280 goto err; 280 goto err;
281 } 281 }
@@ -530,9 +530,9 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
530 530
531 ldo->wm831x = wm831x; 531 ldo->wm831x = wm831x;
532 532
533 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 533 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
534 if (res == NULL) { 534 if (res == NULL) {
535 dev_err(&pdev->dev, "No I/O resource\n"); 535 dev_err(&pdev->dev, "No REG resource\n");
536 ret = -EINVAL; 536 ret = -EINVAL;
537 goto err; 537 goto err;
538 } 538 }
@@ -687,9 +687,9 @@ static __devinit int wm831x_alive_ldo_probe(struct platform_device *pdev)
687 687
688 ldo->wm831x = wm831x; 688 ldo->wm831x = wm831x;
689 689
690 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 690 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
691 if (res == NULL) { 691 if (res == NULL) {
692 dev_err(&pdev->dev, "No I/O resource\n"); 692 dev_err(&pdev->dev, "No REG resource\n");
693 ret = -EINVAL; 693 ret = -EINVAL;
694 goto err; 694 goto err;
695 } 695 }
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index feddefc42109..de9e854b326a 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/of.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/mutex.h> 17#include <linux/mutex.h>
@@ -284,6 +285,28 @@ out:
284} 285}
285#endif 286#endif
286 287
288#ifdef CONFIG_OF
289static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev,
290 struct pm860x_rtc_info *info)
291{
292 struct device_node *np = pdev->dev.parent->of_node;
293 int ret;
294 if (!np)
295 return -ENODEV;
296 np = of_find_node_by_name(np, "rtc");
297 if (!np) {
298 dev_err(&pdev->dev, "failed to find rtc node\n");
299 return -ENODEV;
300 }
301 ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
302 if (ret)
303 info->vrtc = 0;
304 return 0;
305}
306#else
307#define pm860x_rtc_dt_init(x, y) (-1)
308#endif
309
287static int __devinit pm860x_rtc_probe(struct platform_device *pdev) 310static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
288{ 311{
289 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 312 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -294,8 +317,6 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
294 int ret; 317 int ret;
295 318
296 pdata = pdev->dev.platform_data; 319 pdata = pdev->dev.platform_data;
297 if (pdata == NULL)
298 dev_warn(&pdev->dev, "No platform data!\n");
299 320
300 info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL); 321 info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
301 if (!info) 322 if (!info)
@@ -345,9 +366,11 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
345 } 366 }
346 } 367 }
347 rtc_tm_to_time(&tm, &ticks); 368 rtc_tm_to_time(&tm, &ticks);
348 if (pdata && pdata->sync) { 369 if (pm860x_rtc_dt_init(pdev, info)) {
349 pdata->sync(ticks); 370 if (pdata && pdata->sync) {
350 info->sync = pdata->sync; 371 pdata->sync(ticks);
372 info->sync = pdata->sync;
373 }
351 } 374 }
352 375
353 info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev, 376 info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
@@ -366,10 +389,12 @@ static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
366 389
367#ifdef VRTC_CALIBRATION 390#ifdef VRTC_CALIBRATION
368 /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */ 391 /* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
369 if (pdata && pdata->vrtc) 392 if (pm860x_rtc_dt_init(pdev, info)) {
370 info->vrtc = pdata->vrtc & 0x3; 393 if (pdata && pdata->vrtc)
371 else 394 info->vrtc = pdata->vrtc & 0x3;
372 info->vrtc = 1; 395 else
396 info->vrtc = 1;
397 }
373 pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC); 398 pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
374 399
375 /* calibrate VRTC */ 400 /* calibrate VRTC */
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index f49181c73113..b7ec34c57f46 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/of.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/fb.h> 17#include <linux/fb.h>
@@ -31,57 +32,26 @@ struct pm860x_backlight_data {
31 int port; 32 int port;
32 int pwm; 33 int pwm;
33 int iset; 34 int iset;
35 int reg_duty_cycle;
36 int reg_always_on;
37 int reg_current;
34}; 38};
35 39
36static inline int wled_a(int port)
37{
38 int ret;
39
40 ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
41 return ret;
42}
43
44static inline int wled_b(int port)
45{
46 int ret;
47
48 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
49 return ret;
50}
51
52/* WLED2 & WLED3 share the same IDC */
53static inline int wled_idc(int port)
54{
55 int ret;
56
57 switch (port) {
58 case PM8606_BACKLIGHT1:
59 case PM8606_BACKLIGHT2:
60 ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
61 break;
62 case PM8606_BACKLIGHT3:
63 default:
64 ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
65 break;
66 }
67 return ret;
68}
69
70static int backlight_power_set(struct pm860x_chip *chip, int port, 40static int backlight_power_set(struct pm860x_chip *chip, int port,
71 int on) 41 int on)
72{ 42{
73 int ret = -EINVAL; 43 int ret = -EINVAL;
74 44
75 switch (port) { 45 switch (port) {
76 case PM8606_BACKLIGHT1: 46 case 0:
77 ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) : 47 ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
78 pm8606_osc_disable(chip, WLED1_DUTY); 48 pm8606_osc_disable(chip, WLED1_DUTY);
79 break; 49 break;
80 case PM8606_BACKLIGHT2: 50 case 1:
81 ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) : 51 ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
82 pm8606_osc_disable(chip, WLED2_DUTY); 52 pm8606_osc_disable(chip, WLED2_DUTY);
83 break; 53 break;
84 case PM8606_BACKLIGHT3: 54 case 2:
85 ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) : 55 ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
86 pm8606_osc_disable(chip, WLED3_DUTY); 56 pm8606_osc_disable(chip, WLED3_DUTY);
87 break; 57 break;
@@ -104,13 +74,13 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
104 if (brightness) 74 if (brightness)
105 backlight_power_set(chip, data->port, 1); 75 backlight_power_set(chip, data->port, 1);
106 76
107 ret = pm860x_reg_write(data->i2c, wled_a(data->port), value); 77 ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
108 if (ret < 0) 78 if (ret < 0)
109 goto out; 79 goto out;
110 80
111 if ((data->current_brightness == 0) && brightness) { 81 if ((data->current_brightness == 0) && brightness) {
112 if (data->iset) { 82 if (data->iset) {
113 ret = pm860x_set_bits(data->i2c, wled_idc(data->port), 83 ret = pm860x_set_bits(data->i2c, data->reg_current,
114 CURRENT_BITMASK, data->iset); 84 CURRENT_BITMASK, data->iset);
115 if (ret < 0) 85 if (ret < 0)
116 goto out; 86 goto out;
@@ -123,17 +93,17 @@ static int pm860x_backlight_set(struct backlight_device *bl, int brightness)
123 } 93 }
124 if (brightness == MAX_BRIGHTNESS) { 94 if (brightness == MAX_BRIGHTNESS) {
125 /* set WLED_ON bit as 100% */ 95 /* set WLED_ON bit as 100% */
126 ret = pm860x_set_bits(data->i2c, wled_b(data->port), 96 ret = pm860x_set_bits(data->i2c, data->reg_always_on,
127 PM8606_WLED_ON, PM8606_WLED_ON); 97 PM8606_WLED_ON, PM8606_WLED_ON);
128 } 98 }
129 } else { 99 } else {
130 if (brightness == MAX_BRIGHTNESS) { 100 if (brightness == MAX_BRIGHTNESS) {
131 /* set WLED_ON bit as 100% */ 101 /* set WLED_ON bit as 100% */
132 ret = pm860x_set_bits(data->i2c, wled_b(data->port), 102 ret = pm860x_set_bits(data->i2c, data->reg_always_on,
133 PM8606_WLED_ON, PM8606_WLED_ON); 103 PM8606_WLED_ON, PM8606_WLED_ON);
134 } else { 104 } else {
135 /* clear WLED_ON bit since it's not 100% */ 105 /* clear WLED_ON bit since it's not 100% */
136 ret = pm860x_set_bits(data->i2c, wled_b(data->port), 106 ret = pm860x_set_bits(data->i2c, data->reg_always_on,
137 PM8606_WLED_ON, 0); 107 PM8606_WLED_ON, 0);
138 } 108 }
139 } 109 }
@@ -174,7 +144,7 @@ static int pm860x_backlight_get_brightness(struct backlight_device *bl)
174 struct pm860x_chip *chip = data->chip; 144 struct pm860x_chip *chip = data->chip;
175 int ret; 145 int ret;
176 146
177 ret = pm860x_reg_read(data->i2c, wled_a(data->port)); 147 ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
178 if (ret < 0) 148 if (ret < 0)
179 goto out; 149 goto out;
180 data->current_brightness = ret; 150 data->current_brightness = ret;
@@ -190,45 +160,85 @@ static const struct backlight_ops pm860x_backlight_ops = {
190 .get_brightness = pm860x_backlight_get_brightness, 160 .get_brightness = pm860x_backlight_get_brightness,
191}; 161};
192 162
163#ifdef CONFIG_OF
164static int pm860x_backlight_dt_init(struct platform_device *pdev,
165 struct pm860x_backlight_data *data,
166 char *name)
167{
168 struct device_node *nproot = pdev->dev.parent->of_node, *np;
169 int iset = 0;
170 if (!nproot)
171 return -ENODEV;
172 nproot = of_find_node_by_name(nproot, "backlights");
173 if (!nproot) {
174 dev_err(&pdev->dev, "failed to find backlights node\n");
175 return -ENODEV;
176 }
177 for_each_child_of_node(nproot, np) {
178 if (!of_node_cmp(np->name, name)) {
179 of_property_read_u32(np, "marvell,88pm860x-iset",
180 &iset);
181 data->iset = PM8606_WLED_CURRENT(iset);
182 of_property_read_u32(np, "marvell,88pm860x-pwm",
183 &data->pwm);
184 break;
185 }
186 }
187 return 0;
188}
189#else
190#define pm860x_backlight_dt_init(x, y, z) (-1)
191#endif
192
193static int pm860x_backlight_probe(struct platform_device *pdev) 193static int pm860x_backlight_probe(struct platform_device *pdev)
194{ 194{
195 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 195 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
196 struct pm860x_backlight_pdata *pdata = NULL; 196 struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data;
197 struct pm860x_backlight_data *data; 197 struct pm860x_backlight_data *data;
198 struct backlight_device *bl; 198 struct backlight_device *bl;
199 struct resource *res; 199 struct resource *res;
200 struct backlight_properties props; 200 struct backlight_properties props;
201 char name[MFD_NAME_SIZE]; 201 char name[MFD_NAME_SIZE];
202 int ret; 202 int ret = 0;
203
204 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
205 if (res == NULL) {
206 dev_err(&pdev->dev, "No I/O resource!\n");
207 return -EINVAL;
208 }
209
210 pdata = pdev->dev.platform_data;
211 if (pdata == NULL) {
212 dev_err(&pdev->dev, "platform data isn't assigned to "
213 "backlight\n");
214 return -EINVAL;
215 }
216 203
217 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data), 204 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
218 GFP_KERNEL); 205 GFP_KERNEL);
219 if (data == NULL) 206 if (data == NULL)
220 return -ENOMEM; 207 return -ENOMEM;
221 strncpy(name, res->name, MFD_NAME_SIZE); 208 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
209 if (!res) {
210 dev_err(&pdev->dev, "No REG resource for duty cycle\n");
211 ret = -ENXIO;
212 goto out;
213 }
214 data->reg_duty_cycle = res->start;
215 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
216 if (!res) {
217 dev_err(&pdev->dev, "No REG resorce for always on\n");
218 ret = -ENXIO;
219 goto out;
220 }
221 data->reg_always_on = res->start;
222 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
223 if (!res) {
224 dev_err(&pdev->dev, "No REG resource for current\n");
225 ret = -ENXIO;
226 goto out;
227 }
228 data->reg_current = res->start;
229
230 memset(name, 0, MFD_NAME_SIZE);
231 sprintf(name, "backlight-%d", pdev->id);
232 data->port = pdev->id;
222 data->chip = chip; 233 data->chip = chip;
223 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \ 234 data->i2c = (chip->id == CHIP_PM8606) ? chip->client \
224 : chip->companion; 235 : chip->companion;
225 data->current_brightness = MAX_BRIGHTNESS; 236 data->current_brightness = MAX_BRIGHTNESS;
226 data->pwm = pdata->pwm; 237 if (pm860x_backlight_dt_init(pdev, data, name)) {
227 data->iset = pdata->iset; 238 if (pdata) {
228 data->port = pdata->flags; 239 data->pwm = pdata->pwm;
229 if (data->port < 0) { 240 data->iset = pdata->iset;
230 dev_err(&pdev->dev, "wrong platform data is assigned"); 241 }
231 return -EINVAL;
232 } 242 }
233 243
234 memset(&props, 0, sizeof(struct backlight_properties)); 244 memset(&props, 0, sizeof(struct backlight_properties));
@@ -247,12 +257,14 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
247 /* read current backlight */ 257 /* read current backlight */
248 ret = pm860x_backlight_get_brightness(bl); 258 ret = pm860x_backlight_get_brightness(bl);
249 if (ret < 0) 259 if (ret < 0)
250 goto out; 260 goto out_brt;
251 261
252 backlight_update_status(bl); 262 backlight_update_status(bl);
253 return 0; 263 return 0;
254out: 264out_brt:
255 backlight_device_unregister(bl); 265 backlight_device_unregister(bl);
266out:
267 devm_kfree(&pdev->dev, data);
256 return ret; 268 return ret;
257} 269}
258 270
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index cf282763a8dc..63cee2e9d622 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -373,6 +373,13 @@ config BACKLIGHT_PANDORA
373 If you have a Pandora console, say Y to enable the 373 If you have a Pandora console, say Y to enable the
374 backlight driver. 374 backlight driver.
375 375
376config BACKLIGHT_TPS65217
377 tristate "TPS65217 Backlight"
378 depends on BACKLIGHT_CLASS_DEVICE && MFD_TPS65217
379 help
380 If you have a Texas Instruments TPS65217 say Y to enable the
381 backlight driver.
382
376endif # BACKLIGHT_CLASS_DEVICE 383endif # BACKLIGHT_CLASS_DEVICE
377 384
378endif # BACKLIGHT_LCD_SUPPORT 385endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index a2ac9cfbaf6b..00223a62ec12 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -43,3 +43,4 @@ obj-$(CONFIG_BACKLIGHT_88PM860X) += 88pm860x_bl.o
43obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o 43obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
44obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o 44obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
45obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o 45obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
46obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index e833ac72e063..f72ba54f364e 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -27,7 +27,9 @@
27struct max8925_backlight_data { 27struct max8925_backlight_data {
28 struct max8925_chip *chip; 28 struct max8925_chip *chip;
29 29
30 int current_brightness; 30 int current_brightness;
31 int reg_mode_cntl;
32 int reg_cntl;
31}; 33};
32 34
33static int max8925_backlight_set(struct backlight_device *bl, int brightness) 35static int max8925_backlight_set(struct backlight_device *bl, int brightness)
@@ -42,16 +44,16 @@ static int max8925_backlight_set(struct backlight_device *bl, int brightness)
42 else 44 else
43 value = brightness; 45 value = brightness;
44 46
45 ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value); 47 ret = max8925_reg_write(chip->i2c, data->reg_cntl, value);
46 if (ret < 0) 48 if (ret < 0)
47 goto out; 49 goto out;
48 50
49 if (!data->current_brightness && brightness) 51 if (!data->current_brightness && brightness)
50 /* enable WLED output */ 52 /* enable WLED output */
51 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1); 53 ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 1);
52 else if (!brightness) 54 else if (!brightness)
53 /* disable WLED output */ 55 /* disable WLED output */
54 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0); 56 ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 0);
55 if (ret < 0) 57 if (ret < 0)
56 goto out; 58 goto out;
57 dev_dbg(chip->dev, "set brightness %d\n", value); 59 dev_dbg(chip->dev, "set brightness %d\n", value);
@@ -85,7 +87,7 @@ static int max8925_backlight_get_brightness(struct backlight_device *bl)
85 struct max8925_chip *chip = data->chip; 87 struct max8925_chip *chip = data->chip;
86 int ret; 88 int ret;
87 89
88 ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL); 90 ret = max8925_reg_read(chip->i2c, data->reg_cntl);
89 if (ret < 0) 91 if (ret < 0)
90 return -EINVAL; 92 return -EINVAL;
91 data->current_brightness = ret; 93 data->current_brightness = ret;
@@ -102,69 +104,70 @@ static const struct backlight_ops max8925_backlight_ops = {
102static int __devinit max8925_backlight_probe(struct platform_device *pdev) 104static int __devinit max8925_backlight_probe(struct platform_device *pdev)
103{ 105{
104 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); 106 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
105 struct max8925_platform_data *max8925_pdata; 107 struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
106 struct max8925_backlight_pdata *pdata = NULL;
107 struct max8925_backlight_data *data; 108 struct max8925_backlight_data *data;
108 struct backlight_device *bl; 109 struct backlight_device *bl;
109 struct backlight_properties props; 110 struct backlight_properties props;
110 struct resource *res; 111 struct resource *res;
111 char name[MAX8925_NAME_SIZE];
112 unsigned char value; 112 unsigned char value;
113 int ret; 113 int ret = 0;
114
115 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
116 if (res == NULL) {
117 dev_err(&pdev->dev, "No I/O resource!\n");
118 return -EINVAL;
119 }
120
121 if (pdev->dev.parent->platform_data) {
122 max8925_pdata = pdev->dev.parent->platform_data;
123 pdata = max8925_pdata->backlight;
124 }
125
126 if (!pdata) {
127 dev_err(&pdev->dev, "platform data isn't assigned to "
128 "backlight\n");
129 return -EINVAL;
130 }
131 114
132 data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data), 115 data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
133 GFP_KERNEL); 116 GFP_KERNEL);
134 if (data == NULL) 117 if (data == NULL)
135 return -ENOMEM; 118 return -ENOMEM;
136 strncpy(name, res->name, MAX8925_NAME_SIZE); 119
120 res = platform_get_resource(pdev, IORESOURCE_REG, 0);
121 if (!res) {
122 dev_err(&pdev->dev, "No REG resource for mode control!\n");
123 ret = -ENXIO;
124 goto out;
125 }
126 data->reg_mode_cntl = res->start;
127 res = platform_get_resource(pdev, IORESOURCE_REG, 1);
128 if (!res) {
129 dev_err(&pdev->dev, "No REG resource for control!\n");
130 ret = -ENXIO;
131 goto out;
132 }
133 data->reg_cntl = res->start;
134
137 data->chip = chip; 135 data->chip = chip;
138 data->current_brightness = 0; 136 data->current_brightness = 0;
139 137
140 memset(&props, 0, sizeof(struct backlight_properties)); 138 memset(&props, 0, sizeof(struct backlight_properties));
141 props.type = BACKLIGHT_RAW; 139 props.type = BACKLIGHT_RAW;
142 props.max_brightness = MAX_BRIGHTNESS; 140 props.max_brightness = MAX_BRIGHTNESS;
143 bl = backlight_device_register(name, &pdev->dev, data, 141 bl = backlight_device_register("max8925-backlight", &pdev->dev, data,
144 &max8925_backlight_ops, &props); 142 &max8925_backlight_ops, &props);
145 if (IS_ERR(bl)) { 143 if (IS_ERR(bl)) {
146 dev_err(&pdev->dev, "failed to register backlight\n"); 144 dev_err(&pdev->dev, "failed to register backlight\n");
147 return PTR_ERR(bl); 145 ret = PTR_ERR(bl);
146 goto out;
148 } 147 }
149 bl->props.brightness = MAX_BRIGHTNESS; 148 bl->props.brightness = MAX_BRIGHTNESS;
150 149
151 platform_set_drvdata(pdev, bl); 150 platform_set_drvdata(pdev, bl);
152 151
153 value = 0; 152 value = 0;
154 if (pdata->lxw_scl) 153 if (pdata) {
155 value |= (1 << 7); 154 if (pdata->lxw_scl)
156 if (pdata->lxw_freq) 155 value |= (1 << 7);
157 value |= (LWX_FREQ(pdata->lxw_freq) << 4); 156 if (pdata->lxw_freq)
158 if (pdata->dual_string) 157 value |= (LWX_FREQ(pdata->lxw_freq) << 4);
159 value |= (1 << 1); 158 if (pdata->dual_string)
160 ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value); 159 value |= (1 << 1);
160 }
161 ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);
161 if (ret < 0) 162 if (ret < 0)
162 goto out; 163 goto out_brt;
163 164
164 backlight_update_status(bl); 165 backlight_update_status(bl);
165 return 0; 166 return 0;
166out: 167out_brt:
167 backlight_device_unregister(bl); 168 backlight_device_unregister(bl);
169out:
170 devm_kfree(&pdev->dev, data);
168 return ret; 171 return ret;
169} 172}
170 173
diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c
new file mode 100644
index 000000000000..70881633b45a
--- /dev/null
+++ b/drivers/video/backlight/tps65217_bl.c
@@ -0,0 +1,342 @@
1/*
2 * tps65217_bl.c
3 *
4 * TPS65217 backlight driver
5 *
6 * Copyright (C) 2012 Matthias Kaehlcke
7 * Author: Matthias Kaehlcke <matthias@kaehlcke.net>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation version 2.
12 *
13 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
14 * kind, whether express or implied; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19#include <linux/kernel.h>
20#include <linux/backlight.h>
21#include <linux/err.h>
22#include <linux/fb.h>
23#include <linux/mfd/tps65217.h>
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27
28struct tps65217_bl {
29 struct tps65217 *tps;
30 struct device *dev;
31 struct backlight_device *bl;
32 bool is_enabled;
33};
34
35static int tps65217_bl_enable(struct tps65217_bl *tps65217_bl)
36{
37 int rc;
38
39 rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
40 TPS65217_WLEDCTRL1_ISINK_ENABLE,
41 TPS65217_WLEDCTRL1_ISINK_ENABLE, TPS65217_PROTECT_NONE);
42 if (rc) {
43 dev_err(tps65217_bl->dev,
44 "failed to enable backlight: %d\n", rc);
45 return rc;
46 }
47
48 tps65217_bl->is_enabled = true;
49
50 dev_dbg(tps65217_bl->dev, "backlight enabled\n");
51
52 return 0;
53}
54
55static int tps65217_bl_disable(struct tps65217_bl *tps65217_bl)
56{
57 int rc;
58
59 rc = tps65217_clear_bits(tps65217_bl->tps,
60 TPS65217_REG_WLEDCTRL1,
61 TPS65217_WLEDCTRL1_ISINK_ENABLE,
62 TPS65217_PROTECT_NONE);
63 if (rc) {
64 dev_err(tps65217_bl->dev,
65 "failed to disable backlight: %d\n", rc);
66 return rc;
67 }
68
69 tps65217_bl->is_enabled = false;
70
71 dev_dbg(tps65217_bl->dev, "backlight disabled\n");
72
73 return 0;
74}
75
76static int tps65217_bl_update_status(struct backlight_device *bl)
77{
78 struct tps65217_bl *tps65217_bl = bl_get_data(bl);
79 int rc;
80 int brightness = bl->props.brightness;
81
82 if (bl->props.state & BL_CORE_SUSPENDED)
83 brightness = 0;
84
85 if ((bl->props.power != FB_BLANK_UNBLANK) ||
86 (bl->props.fb_blank != FB_BLANK_UNBLANK))
87 /* framebuffer in low power mode or blanking active */
88 brightness = 0;
89
90 if (brightness > 0) {
91 rc = tps65217_reg_write(tps65217_bl->tps,
92 TPS65217_REG_WLEDCTRL2,
93 brightness - 1,
94 TPS65217_PROTECT_NONE);
95 if (rc) {
96 dev_err(tps65217_bl->dev,
97 "failed to set brightness level: %d\n", rc);
98 return rc;
99 }
100
101 dev_dbg(tps65217_bl->dev, "brightness set to %d\n", brightness);
102
103 if (!tps65217_bl->is_enabled)
104 rc = tps65217_bl_enable(tps65217_bl);
105 } else {
106 rc = tps65217_bl_disable(tps65217_bl);
107 }
108
109 return rc;
110}
111
112static int tps65217_bl_get_brightness(struct backlight_device *bl)
113{
114 return bl->props.brightness;
115}
116
117static const struct backlight_ops tps65217_bl_ops = {
118 .options = BL_CORE_SUSPENDRESUME,
119 .update_status = tps65217_bl_update_status,
120 .get_brightness = tps65217_bl_get_brightness
121};
122
123static int tps65217_bl_hw_init(struct tps65217_bl *tps65217_bl,
124 struct tps65217_bl_pdata *pdata)
125{
126 int rc;
127
128 rc = tps65217_bl_disable(tps65217_bl);
129 if (rc)
130 return rc;
131
132 switch (pdata->isel) {
133 case TPS65217_BL_ISET1:
134 /* select ISET_1 current level */
135 rc = tps65217_clear_bits(tps65217_bl->tps,
136 TPS65217_REG_WLEDCTRL1,
137 TPS65217_WLEDCTRL1_ISEL,
138 TPS65217_PROTECT_NONE);
139 if (rc) {
140 dev_err(tps65217_bl->dev,
141 "failed to select ISET1 current level: %d)\n",
142 rc);
143 return rc;
144 }
145
146 dev_dbg(tps65217_bl->dev, "selected ISET1 current level\n");
147
148 break;
149
150 case TPS65217_BL_ISET2:
151 /* select ISET2 current level */
152 rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
153 TPS65217_WLEDCTRL1_ISEL,
154 TPS65217_WLEDCTRL1_ISEL, TPS65217_PROTECT_NONE);
155 if (rc) {
156 dev_err(tps65217_bl->dev,
157 "failed to select ISET2 current level: %d\n",
158 rc);
159 return rc;
160 }
161
162 dev_dbg(tps65217_bl->dev, "selected ISET2 current level\n");
163
164 break;
165
166 default:
167 dev_err(tps65217_bl->dev,
168 "invalid value for current level: %d\n", pdata->isel);
169 return -EINVAL;
170 }
171
172 /* set PWM frequency */
173 rc = tps65217_set_bits(tps65217_bl->tps,
174 TPS65217_REG_WLEDCTRL1,
175 TPS65217_WLEDCTRL1_FDIM_MASK,
176 pdata->fdim,
177 TPS65217_PROTECT_NONE);
178 if (rc) {
179 dev_err(tps65217_bl->dev,
180 "failed to select PWM dimming frequency: %d\n",
181 rc);
182 return rc;
183 }
184
185 return 0;
186}
187
188#ifdef CONFIG_OF
189static struct tps65217_bl_pdata *
190tps65217_bl_parse_dt(struct platform_device *pdev)
191{
192 struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
193 struct device_node *node = of_node_get(tps->dev->of_node);
194 struct tps65217_bl_pdata *pdata, *err;
195 u32 val;
196
197 node = of_find_node_by_name(node, "backlight");
198 if (!node)
199 return ERR_PTR(-ENODEV);
200
201 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
202 if (!pdata) {
203 dev_err(&pdev->dev, "failed to allocate platform data\n");
204 err = ERR_PTR(-ENOMEM);
205 goto err;
206 }
207
208 pdata->isel = TPS65217_BL_ISET1;
209 if (!of_property_read_u32(node, "isel", &val)) {
210 if (val < TPS65217_BL_ISET1 ||
211 val > TPS65217_BL_ISET2) {
212 dev_err(&pdev->dev,
213 "invalid 'isel' value in the device tree\n");
214 err = ERR_PTR(-EINVAL);
215 goto err;
216 }
217
218 pdata->isel = val;
219 }
220
221 pdata->fdim = TPS65217_BL_FDIM_200HZ;
222 if (!of_property_read_u32(node, "fdim", &val)) {
223 switch (val) {
224 case 100:
225 pdata->fdim = TPS65217_BL_FDIM_100HZ;
226 break;
227
228 case 200:
229 pdata->fdim = TPS65217_BL_FDIM_200HZ;
230 break;
231
232 case 500:
233 pdata->fdim = TPS65217_BL_FDIM_500HZ;
234 break;
235
236 case 1000:
237 pdata->fdim = TPS65217_BL_FDIM_1000HZ;
238 break;
239
240 default:
241 dev_err(&pdev->dev,
242 "invalid 'fdim' value in the device tree\n");
243 err = ERR_PTR(-EINVAL);
244 goto err;
245 }
246 }
247
248 of_node_put(node);
249
250 return pdata;
251
252err:
253 of_node_put(node);
254
255 return err;
256}
257#else
258static struct tps65217_bl_pdata *
259tps65217_bl_parse_dt(struct platform_device *pdev)
260{
261 return NULL;
262}
263#endif
264
265static int tps65217_bl_probe(struct platform_device *pdev)
266{
267 int rc;
268 struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
269 struct tps65217_bl *tps65217_bl;
270 struct tps65217_bl_pdata *pdata;
271 struct backlight_properties bl_props;
272
273 if (tps->dev->of_node) {
274 pdata = tps65217_bl_parse_dt(pdev);
275 if (IS_ERR(pdata))
276 return PTR_ERR(pdata);
277 } else {
278 if (!pdev->dev.platform_data) {
279 dev_err(&pdev->dev, "no platform data provided\n");
280 return -EINVAL;
281 }
282
283 pdata = pdev->dev.platform_data;
284 }
285
286 tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl),
287 GFP_KERNEL);
288 if (tps65217_bl == NULL) {
289 dev_err(&pdev->dev, "allocation of struct tps65217_bl failed\n");
290 return -ENOMEM;
291 }
292
293 tps65217_bl->tps = tps;
294 tps65217_bl->dev = &pdev->dev;
295 tps65217_bl->is_enabled = false;
296
297 rc = tps65217_bl_hw_init(tps65217_bl, pdata);
298 if (rc)
299 return rc;
300
301 memset(&bl_props, 0, sizeof(struct backlight_properties));
302 bl_props.type = BACKLIGHT_RAW;
303 bl_props.max_brightness = 100;
304
305 tps65217_bl->bl = backlight_device_register(pdev->name,
306 tps65217_bl->dev, tps65217_bl,
307 &tps65217_bl_ops, &bl_props);
308 if (IS_ERR(tps65217_bl->bl)) {
309 dev_err(tps65217_bl->dev,
310 "registration of backlight device failed: %d\n", rc);
311 return PTR_ERR(tps65217_bl->bl);
312 }
313
314 tps65217_bl->bl->props.brightness = 0;
315 platform_set_drvdata(pdev, tps65217_bl);
316
317 return 0;
318}
319
320static int tps65217_bl_remove(struct platform_device *pdev)
321{
322 struct tps65217_bl *tps65217_bl = platform_get_drvdata(pdev);
323
324 backlight_device_unregister(tps65217_bl->bl);
325
326 return 0;
327}
328
329static struct platform_driver tps65217_bl_driver = {
330 .probe = tps65217_bl_probe,
331 .remove = tps65217_bl_remove,
332 .driver = {
333 .owner = THIS_MODULE,
334 .name = "tps65217-bl",
335 },
336};
337
338module_platform_driver(tps65217_bl_driver);
339
340MODULE_DESCRIPTION("TPS65217 Backlight driver");
341MODULE_LICENSE("GPL v2");
342MODULE_AUTHOR("Matthias Kaehlcke <matthias@kaehlcke.net>");
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index ceed39f26011..545d387de411 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -37,6 +37,7 @@
37 * document number TBD : DH89xxCC 37 * document number TBD : DH89xxCC
38 * document number TBD : Panther Point 38 * document number TBD : Panther Point
39 * document number TBD : Lynx Point 39 * document number TBD : Lynx Point
40 * document number TBD : Lynx Point-LP
40 */ 41 */
41 42
42/* 43/*