diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 20:17:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 20:17:39 -0400 |
commit | 54c72d5987ff9f3cf59529d5d4f5cf19eae3f695 (patch) | |
tree | 3fee972d54926627895aa07684ddb2e2388e4614 /drivers | |
parent | 66bb0aa077978dbb76e6283531eb3cc7a878de38 (diff) | |
parent | 7caa79917ad4c1f91366b11f18e48623554aaa52 (diff) |
Merge tag 'mfd-for-linus-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD update from Lee Jones:
"Changes to existing drivers:
- checkpatch fixes throughout the subsystem
- use Regmap to handle IRQs in max77686, extcon-max77693 and
mc13xxx-core
- use DMA in rtsx_pcr
- restrict building on unsupported architectures on timberdale,
cs5535
- SPI hardening in cros_ec_spi
- more robust error handing in asic3, cros_ec, ab8500-debugfs,
max77686 and pcf50633-core
- reorder PM runtime and regulator handing during shutdown in arizona
- enable wakeup in cros_ec_spi
- unused variable/code clean-up in pm8921-core, cros_ec, htc-i2cpld,
tps65912-spi, wm5110-tables and ab8500-debugfs
- add regulator handing into suspend() in sec-core
- remove pointless wrapper functions in extcon-max77693 and
i2c-cros-ec-tunnel
- use cross-architecture friendly data sizes in stmpe-i2c, arizona,
max77686 and tps65910
- devicetree documentation updates throughout
- provide power management support in max77686
- few OF clean-ups in max77686
- use manged resources in tps6105x
New drivers/supported devices:
- add support for s2mpu02 to sec-core
- add support for Allwinner A32 to sun6i-prcm
- add support for Maxim 77802 in max77686
- add support for DA9063 AD in da9063
- new driver for Intel PMICs (generic) and specifically Crystal Cove
(Re-)moved drivers ==
- move out keyboard functionality cros_ec ==> input/keyboard/cros_ec_keyb"
* tag 'mfd-for-linus-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (101 commits)
MAINTAINERS: Update MFD repo location
mfd: omap-usb-host: Fix improper mask use.
mfd: arizona: Only free the CTRLIF_ERR IRQ if we requested it
mfd: arizona: Add missing handling for ISRC3 under/overclocked
mfd: wm5110: Add new interrupt register definitions
mfd: arizona: Rename thermal shutdown interrupt
mfd: wm5110: Add in the output done interrupts
mfd: wm5110: Remove non-existant interrupts
mfd: tps65912-spi: Remove unused variable
mfd: htc-i2cpld: Remove unused code
mfd: da9063: Add support for AD silicon variant
mfd: arizona: Map MICVDD from extcon device to the Arizona core
mfd: arizona: Add MICVDD to mapped regulators for wm8997
mfd: max77686: Ensure device type IDs are architecture agnostic
mfd: max77686: Add Maxim 77802 PMIC support
mfd: tps6105x: Use managed resources when allocating memory
mfd: wm8997-tables: Suppress 'line over 80 chars' warnings
mfd: kempld-core: Correct a variety of checkpatch warnings
mfd: ipaq-micro: Fix coding style errors/warnings reported by checkpatch
mfd: si476x-cmd: Remedy checkpatch style complains
...
Diffstat (limited to 'drivers')
70 files changed, 2790 insertions, 1259 deletions
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 4a1b5113e527..4a065b45330f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -450,6 +450,19 @@ config GPIO_ARIZONA | |||
450 | help | 450 | help |
451 | Support for GPIOs on Wolfson Arizona class devices. | 451 | Support for GPIOs on Wolfson Arizona class devices. |
452 | 452 | ||
453 | config GPIO_CRYSTAL_COVE | ||
454 | tristate "GPIO support for Crystal Cove PMIC" | ||
455 | depends on INTEL_SOC_PMIC | ||
456 | select GPIOLIB_IRQCHIP | ||
457 | help | ||
458 | Support for GPIO pins on Crystal Cove PMIC. | ||
459 | |||
460 | Say Yes if you have a Intel SoC based tablet with Crystal Cove PMIC | ||
461 | inside. | ||
462 | |||
463 | This driver can also be built as a module. If so, the module will be | ||
464 | called gpio-crystalcove. | ||
465 | |||
453 | config GPIO_LP3943 | 466 | config GPIO_LP3943 |
454 | tristate "TI/National Semiconductor LP3943 GPIO expander" | 467 | tristate "TI/National Semiconductor LP3943 GPIO expander" |
455 | depends on MFD_LP3943 | 468 | depends on MFD_LP3943 |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index d10f6a9d875a..e18e9564b073 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o | |||
20 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o | 20 | obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o |
21 | obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o | 21 | obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o |
22 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o | 22 | obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o |
23 | obj-$(CONFIG_GPIO_CRYSTAL_COVE) += gpio-crystalcove.o | ||
23 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o | 24 | obj-$(CONFIG_GPIO_DA9052) += gpio-da9052.o |
24 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o | 25 | obj-$(CONFIG_GPIO_DA9055) += gpio-da9055.o |
25 | obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o | 26 | obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o |
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c new file mode 100644 index 000000000000..934462f5bd22 --- /dev/null +++ b/drivers/gpio/gpio-crystalcove.c | |||
@@ -0,0 +1,380 @@ | |||
1 | /* | ||
2 | * gpio-crystalcove.c - Intel Crystal Cove GPIO Driver | ||
3 | * | ||
4 | * Copyright (C) 2012, 2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * Author: Yang, Bin <bin.yang@intel.com> | ||
16 | */ | ||
17 | |||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/gpio.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/bitops.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/mfd/intel_soc_pmic.h> | ||
25 | |||
26 | #define CRYSTALCOVE_GPIO_NUM 16 | ||
27 | |||
28 | #define UPDATE_IRQ_TYPE BIT(0) | ||
29 | #define UPDATE_IRQ_MASK BIT(1) | ||
30 | |||
31 | #define GPIO0IRQ 0x0b | ||
32 | #define GPIO1IRQ 0x0c | ||
33 | #define MGPIO0IRQS0 0x19 | ||
34 | #define MGPIO1IRQS0 0x1a | ||
35 | #define MGPIO0IRQSX 0x1b | ||
36 | #define MGPIO1IRQSX 0x1c | ||
37 | #define GPIO0P0CTLO 0x2b | ||
38 | #define GPIO0P0CTLI 0x33 | ||
39 | #define GPIO1P0CTLO 0x3b | ||
40 | #define GPIO1P0CTLI 0x43 | ||
41 | |||
42 | #define CTLI_INTCNT_DIS (0) | ||
43 | #define CTLI_INTCNT_NE (1 << 1) | ||
44 | #define CTLI_INTCNT_PE (2 << 1) | ||
45 | #define CTLI_INTCNT_BE (3 << 1) | ||
46 | |||
47 | #define CTLO_DIR_IN (0) | ||
48 | #define CTLO_DIR_OUT (1 << 5) | ||
49 | |||
50 | #define CTLO_DRV_CMOS (0) | ||
51 | #define CTLO_DRV_OD (1 << 4) | ||
52 | |||
53 | #define CTLO_DRV_REN (1 << 3) | ||
54 | |||
55 | #define CTLO_RVAL_2KDW (0) | ||
56 | #define CTLO_RVAL_2KUP (1 << 1) | ||
57 | #define CTLO_RVAL_50KDW (2 << 1) | ||
58 | #define CTLO_RVAL_50KUP (3 << 1) | ||
59 | |||
60 | #define CTLO_INPUT_SET (CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP) | ||
61 | #define CTLO_OUTPUT_SET (CTLO_DIR_OUT | CTLO_INPUT_SET) | ||
62 | |||
63 | enum ctrl_register { | ||
64 | CTRL_IN, | ||
65 | CTRL_OUT, | ||
66 | }; | ||
67 | |||
68 | /** | ||
69 | * struct crystalcove_gpio - Crystal Cove GPIO controller | ||
70 | * @buslock: for bus lock/sync and unlock. | ||
71 | * @chip: the abstract gpio_chip structure. | ||
72 | * @regmap: the regmap from the parent device. | ||
73 | * @update: pending IRQ setting update, to be written to the chip upon unlock. | ||
74 | * @intcnt_value: the Interrupt Detect value to be written. | ||
75 | * @set_irq_mask: true if the IRQ mask needs to be set, false to clear. | ||
76 | */ | ||
77 | struct crystalcove_gpio { | ||
78 | struct mutex buslock; /* irq_bus_lock */ | ||
79 | struct gpio_chip chip; | ||
80 | struct regmap *regmap; | ||
81 | int update; | ||
82 | int intcnt_value; | ||
83 | bool set_irq_mask; | ||
84 | }; | ||
85 | |||
86 | static inline struct crystalcove_gpio *to_cg(struct gpio_chip *gc) | ||
87 | { | ||
88 | return container_of(gc, struct crystalcove_gpio, chip); | ||
89 | } | ||
90 | |||
91 | static inline int to_reg(int gpio, enum ctrl_register reg_type) | ||
92 | { | ||
93 | int reg; | ||
94 | |||
95 | if (reg_type == CTRL_IN) { | ||
96 | if (gpio < 8) | ||
97 | reg = GPIO0P0CTLI; | ||
98 | else | ||
99 | reg = GPIO1P0CTLI; | ||
100 | } else { | ||
101 | if (gpio < 8) | ||
102 | reg = GPIO0P0CTLO; | ||
103 | else | ||
104 | reg = GPIO1P0CTLO; | ||
105 | } | ||
106 | |||
107 | return reg + gpio % 8; | ||
108 | } | ||
109 | |||
110 | static void crystalcove_update_irq_mask(struct crystalcove_gpio *cg, | ||
111 | int gpio) | ||
112 | { | ||
113 | u8 mirqs0 = gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0; | ||
114 | int mask = BIT(gpio % 8); | ||
115 | |||
116 | if (cg->set_irq_mask) | ||
117 | regmap_update_bits(cg->regmap, mirqs0, mask, mask); | ||
118 | else | ||
119 | regmap_update_bits(cg->regmap, mirqs0, mask, 0); | ||
120 | } | ||
121 | |||
122 | static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio) | ||
123 | { | ||
124 | int reg = to_reg(gpio, CTRL_IN); | ||
125 | |||
126 | regmap_update_bits(cg->regmap, reg, CTLI_INTCNT_BE, cg->intcnt_value); | ||
127 | } | ||
128 | |||
129 | static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio) | ||
130 | { | ||
131 | struct crystalcove_gpio *cg = to_cg(chip); | ||
132 | |||
133 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), | ||
134 | CTLO_INPUT_SET); | ||
135 | } | ||
136 | |||
137 | static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, | ||
138 | int value) | ||
139 | { | ||
140 | struct crystalcove_gpio *cg = to_cg(chip); | ||
141 | |||
142 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), | ||
143 | CTLO_OUTPUT_SET | value); | ||
144 | } | ||
145 | |||
146 | static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio) | ||
147 | { | ||
148 | struct crystalcove_gpio *cg = to_cg(chip); | ||
149 | int ret; | ||
150 | unsigned int val; | ||
151 | |||
152 | ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | |||
156 | return val & 0x1; | ||
157 | } | ||
158 | |||
159 | static void crystalcove_gpio_set(struct gpio_chip *chip, | ||
160 | unsigned gpio, int value) | ||
161 | { | ||
162 | struct crystalcove_gpio *cg = to_cg(chip); | ||
163 | |||
164 | if (value) | ||
165 | regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); | ||
166 | else | ||
167 | regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 0); | ||
168 | } | ||
169 | |||
170 | static int crystalcove_irq_type(struct irq_data *data, unsigned type) | ||
171 | { | ||
172 | struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data)); | ||
173 | |||
174 | switch (type) { | ||
175 | case IRQ_TYPE_NONE: | ||
176 | cg->intcnt_value = CTLI_INTCNT_DIS; | ||
177 | break; | ||
178 | case IRQ_TYPE_EDGE_BOTH: | ||
179 | cg->intcnt_value = CTLI_INTCNT_BE; | ||
180 | break; | ||
181 | case IRQ_TYPE_EDGE_RISING: | ||
182 | cg->intcnt_value = CTLI_INTCNT_PE; | ||
183 | break; | ||
184 | case IRQ_TYPE_EDGE_FALLING: | ||
185 | cg->intcnt_value = CTLI_INTCNT_NE; | ||
186 | break; | ||
187 | default: | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | cg->update |= UPDATE_IRQ_TYPE; | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static void crystalcove_bus_lock(struct irq_data *data) | ||
197 | { | ||
198 | struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data)); | ||
199 | |||
200 | mutex_lock(&cg->buslock); | ||
201 | } | ||
202 | |||
203 | static void crystalcove_bus_sync_unlock(struct irq_data *data) | ||
204 | { | ||
205 | struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data)); | ||
206 | int gpio = data->hwirq; | ||
207 | |||
208 | if (cg->update & UPDATE_IRQ_TYPE) | ||
209 | crystalcove_update_irq_ctrl(cg, gpio); | ||
210 | if (cg->update & UPDATE_IRQ_MASK) | ||
211 | crystalcove_update_irq_mask(cg, gpio); | ||
212 | cg->update = 0; | ||
213 | |||
214 | mutex_unlock(&cg->buslock); | ||
215 | } | ||
216 | |||
217 | static void crystalcove_irq_unmask(struct irq_data *data) | ||
218 | { | ||
219 | struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data)); | ||
220 | |||
221 | cg->set_irq_mask = false; | ||
222 | cg->update |= UPDATE_IRQ_MASK; | ||
223 | } | ||
224 | |||
225 | static void crystalcove_irq_mask(struct irq_data *data) | ||
226 | { | ||
227 | struct crystalcove_gpio *cg = to_cg(irq_data_get_irq_chip_data(data)); | ||
228 | |||
229 | cg->set_irq_mask = true; | ||
230 | cg->update |= UPDATE_IRQ_MASK; | ||
231 | } | ||
232 | |||
233 | static struct irq_chip crystalcove_irqchip = { | ||
234 | .name = "Crystal Cove", | ||
235 | .irq_mask = crystalcove_irq_mask, | ||
236 | .irq_unmask = crystalcove_irq_unmask, | ||
237 | .irq_set_type = crystalcove_irq_type, | ||
238 | .irq_bus_lock = crystalcove_bus_lock, | ||
239 | .irq_bus_sync_unlock = crystalcove_bus_sync_unlock, | ||
240 | }; | ||
241 | |||
242 | static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) | ||
243 | { | ||
244 | struct crystalcove_gpio *cg = data; | ||
245 | unsigned int p0, p1; | ||
246 | int pending; | ||
247 | int gpio; | ||
248 | unsigned int virq; | ||
249 | |||
250 | if (regmap_read(cg->regmap, GPIO0IRQ, &p0) || | ||
251 | regmap_read(cg->regmap, GPIO1IRQ, &p1)) | ||
252 | return IRQ_NONE; | ||
253 | |||
254 | regmap_write(cg->regmap, GPIO0IRQ, p0); | ||
255 | regmap_write(cg->regmap, GPIO1IRQ, p1); | ||
256 | |||
257 | pending = p0 | p1 << 8; | ||
258 | |||
259 | for (gpio = 0; gpio < cg->chip.ngpio; gpio++) { | ||
260 | if (pending & BIT(gpio)) { | ||
261 | virq = irq_find_mapping(cg->chip.irqdomain, gpio); | ||
262 | generic_handle_irq(virq); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | return IRQ_HANDLED; | ||
267 | } | ||
268 | |||
269 | static void crystalcove_gpio_dbg_show(struct seq_file *s, | ||
270 | struct gpio_chip *chip) | ||
271 | { | ||
272 | struct crystalcove_gpio *cg = to_cg(chip); | ||
273 | int gpio, offset; | ||
274 | unsigned int ctlo, ctli, mirqs0, mirqsx, irq; | ||
275 | |||
276 | for (gpio = 0; gpio < cg->chip.ngpio; gpio++) { | ||
277 | regmap_read(cg->regmap, to_reg(gpio, CTRL_OUT), &ctlo); | ||
278 | regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &ctli); | ||
279 | regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQS0 : MGPIO1IRQS0, | ||
280 | &mirqs0); | ||
281 | regmap_read(cg->regmap, gpio < 8 ? MGPIO0IRQSX : MGPIO1IRQSX, | ||
282 | &mirqsx); | ||
283 | regmap_read(cg->regmap, gpio < 8 ? GPIO0IRQ : GPIO1IRQ, | ||
284 | &irq); | ||
285 | |||
286 | offset = gpio % 8; | ||
287 | seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s %s\n", | ||
288 | gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ", | ||
289 | ctli & 0x1 ? "hi" : "lo", | ||
290 | ctli & CTLI_INTCNT_NE ? "fall" : " ", | ||
291 | ctli & CTLI_INTCNT_PE ? "rise" : " ", | ||
292 | ctlo, | ||
293 | mirqs0 & BIT(offset) ? "s0 mask " : "s0 unmask", | ||
294 | mirqsx & BIT(offset) ? "sx mask " : "sx unmask", | ||
295 | irq & BIT(offset) ? "pending" : " "); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | static int crystalcove_gpio_probe(struct platform_device *pdev) | ||
300 | { | ||
301 | int irq = platform_get_irq(pdev, 0); | ||
302 | struct crystalcove_gpio *cg; | ||
303 | int retval; | ||
304 | struct device *dev = pdev->dev.parent; | ||
305 | struct intel_soc_pmic *pmic = dev_get_drvdata(dev); | ||
306 | |||
307 | if (irq < 0) | ||
308 | return irq; | ||
309 | |||
310 | cg = devm_kzalloc(&pdev->dev, sizeof(*cg), GFP_KERNEL); | ||
311 | if (!cg) | ||
312 | return -ENOMEM; | ||
313 | |||
314 | platform_set_drvdata(pdev, cg); | ||
315 | |||
316 | mutex_init(&cg->buslock); | ||
317 | cg->chip.label = KBUILD_MODNAME; | ||
318 | cg->chip.direction_input = crystalcove_gpio_dir_in; | ||
319 | cg->chip.direction_output = crystalcove_gpio_dir_out; | ||
320 | cg->chip.get = crystalcove_gpio_get; | ||
321 | cg->chip.set = crystalcove_gpio_set; | ||
322 | cg->chip.base = -1; | ||
323 | cg->chip.ngpio = CRYSTALCOVE_GPIO_NUM; | ||
324 | cg->chip.can_sleep = true; | ||
325 | cg->chip.dev = dev; | ||
326 | cg->chip.dbg_show = crystalcove_gpio_dbg_show; | ||
327 | cg->regmap = pmic->regmap; | ||
328 | |||
329 | retval = gpiochip_add(&cg->chip); | ||
330 | if (retval) { | ||
331 | dev_warn(&pdev->dev, "add gpio chip error: %d\n", retval); | ||
332 | return retval; | ||
333 | } | ||
334 | |||
335 | gpiochip_irqchip_add(&cg->chip, &crystalcove_irqchip, 0, | ||
336 | handle_simple_irq, IRQ_TYPE_NONE); | ||
337 | |||
338 | retval = request_threaded_irq(irq, NULL, crystalcove_gpio_irq_handler, | ||
339 | IRQF_ONESHOT, KBUILD_MODNAME, cg); | ||
340 | |||
341 | if (retval) { | ||
342 | dev_warn(&pdev->dev, "request irq failed: %d\n", retval); | ||
343 | goto out_remove_gpio; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | |||
348 | out_remove_gpio: | ||
349 | WARN_ON(gpiochip_remove(&cg->chip)); | ||
350 | return retval; | ||
351 | } | ||
352 | |||
353 | static int crystalcove_gpio_remove(struct platform_device *pdev) | ||
354 | { | ||
355 | struct crystalcove_gpio *cg = platform_get_drvdata(pdev); | ||
356 | int irq = platform_get_irq(pdev, 0); | ||
357 | int err; | ||
358 | |||
359 | err = gpiochip_remove(&cg->chip); | ||
360 | |||
361 | if (irq >= 0) | ||
362 | free_irq(irq, cg); | ||
363 | |||
364 | return err; | ||
365 | } | ||
366 | |||
367 | static struct platform_driver crystalcove_gpio_driver = { | ||
368 | .probe = crystalcove_gpio_probe, | ||
369 | .remove = crystalcove_gpio_remove, | ||
370 | .driver = { | ||
371 | .name = "crystal_cove_gpio", | ||
372 | .owner = THIS_MODULE, | ||
373 | }, | ||
374 | }; | ||
375 | |||
376 | module_platform_driver(crystalcove_gpio_driver); | ||
377 | |||
378 | MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>"); | ||
379 | MODULE_DESCRIPTION("Intel Crystal Cove GPIO Driver"); | ||
380 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index 8e7a71487bb1..05e033c98115 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c | |||
@@ -183,6 +183,7 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[], | |||
183 | u8 *request = NULL; | 183 | u8 *request = NULL; |
184 | u8 *response = NULL; | 184 | u8 *response = NULL; |
185 | int result; | 185 | int result; |
186 | struct cros_ec_command msg; | ||
186 | 187 | ||
187 | request_len = ec_i2c_count_message(i2c_msgs, num); | 188 | request_len = ec_i2c_count_message(i2c_msgs, num); |
188 | if (request_len < 0) { | 189 | if (request_len < 0) { |
@@ -218,10 +219,16 @@ static int ec_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg i2c_msgs[], | |||
218 | } | 219 | } |
219 | 220 | ||
220 | ec_i2c_construct_message(request, i2c_msgs, num, bus_num); | 221 | ec_i2c_construct_message(request, i2c_msgs, num, bus_num); |
221 | result = bus->ec->command_sendrecv(bus->ec, EC_CMD_I2C_PASSTHRU, | 222 | |
222 | request, request_len, | 223 | msg.version = 0; |
223 | response, response_len); | 224 | msg.command = EC_CMD_I2C_PASSTHRU; |
224 | if (result) | 225 | msg.outdata = request; |
226 | msg.outsize = request_len; | ||
227 | msg.indata = response; | ||
228 | msg.insize = response_len; | ||
229 | |||
230 | result = bus->ec->cmd_xfer(bus->ec, &msg); | ||
231 | if (result < 0) | ||
225 | goto exit; | 232 | goto exit; |
226 | 233 | ||
227 | result = ec_i2c_parse_response(response, i2c_msgs, &num); | 234 | result = ec_i2c_parse_response(response, i2c_msgs, &num); |
@@ -258,7 +265,7 @@ static int ec_i2c_probe(struct platform_device *pdev) | |||
258 | u32 remote_bus; | 265 | u32 remote_bus; |
259 | int err; | 266 | int err; |
260 | 267 | ||
261 | if (!ec->command_sendrecv) { | 268 | if (!ec->cmd_xfer) { |
262 | dev_err(dev, "Missing sendrecv\n"); | 269 | dev_err(dev, "Missing sendrecv\n"); |
263 | return -EINVAL; | 270 | return -EINVAL; |
264 | } | 271 | } |
diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 408379669d3c..791781ade4e7 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c | |||
@@ -24,8 +24,8 @@ | |||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/interrupt.h> | ||
27 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
28 | #include <linux/notifier.h> | ||
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
31 | #include <linux/input/matrix_keypad.h> | 31 | #include <linux/input/matrix_keypad.h> |
@@ -42,7 +42,6 @@ | |||
42 | * @dev: Device pointer | 42 | * @dev: Device pointer |
43 | * @idev: Input device | 43 | * @idev: Input device |
44 | * @ec: Top level ChromeOS device to use to talk to EC | 44 | * @ec: Top level ChromeOS device to use to talk to EC |
45 | * @event_notifier: interrupt event notifier for transport devices | ||
46 | */ | 45 | */ |
47 | struct cros_ec_keyb { | 46 | struct cros_ec_keyb { |
48 | unsigned int rows; | 47 | unsigned int rows; |
@@ -55,7 +54,6 @@ struct cros_ec_keyb { | |||
55 | struct device *dev; | 54 | struct device *dev; |
56 | struct input_dev *idev; | 55 | struct input_dev *idev; |
57 | struct cros_ec_device *ec; | 56 | struct cros_ec_device *ec; |
58 | struct notifier_block notifier; | ||
59 | }; | 57 | }; |
60 | 58 | ||
61 | 59 | ||
@@ -173,41 +171,55 @@ static void cros_ec_keyb_process(struct cros_ec_keyb *ckdev, | |||
173 | input_sync(ckdev->idev); | 171 | input_sync(ckdev->idev); |
174 | } | 172 | } |
175 | 173 | ||
176 | static int cros_ec_keyb_open(struct input_dev *dev) | ||
177 | { | ||
178 | struct cros_ec_keyb *ckdev = input_get_drvdata(dev); | ||
179 | |||
180 | return blocking_notifier_chain_register(&ckdev->ec->event_notifier, | ||
181 | &ckdev->notifier); | ||
182 | } | ||
183 | |||
184 | static void cros_ec_keyb_close(struct input_dev *dev) | ||
185 | { | ||
186 | struct cros_ec_keyb *ckdev = input_get_drvdata(dev); | ||
187 | |||
188 | blocking_notifier_chain_unregister(&ckdev->ec->event_notifier, | ||
189 | &ckdev->notifier); | ||
190 | } | ||
191 | |||
192 | static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) | 174 | static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) |
193 | { | 175 | { |
194 | return ckdev->ec->command_recv(ckdev->ec, EC_CMD_MKBP_STATE, | 176 | struct cros_ec_command msg = { |
195 | kb_state, ckdev->cols); | 177 | .version = 0, |
178 | .command = EC_CMD_MKBP_STATE, | ||
179 | .outdata = NULL, | ||
180 | .outsize = 0, | ||
181 | .indata = kb_state, | ||
182 | .insize = ckdev->cols, | ||
183 | }; | ||
184 | |||
185 | return ckdev->ec->cmd_xfer(ckdev->ec, &msg); | ||
196 | } | 186 | } |
197 | 187 | ||
198 | static int cros_ec_keyb_work(struct notifier_block *nb, | 188 | static irqreturn_t cros_ec_keyb_irq(int irq, void *data) |
199 | unsigned long state, void *_notify) | ||
200 | { | 189 | { |
190 | struct cros_ec_keyb *ckdev = data; | ||
191 | struct cros_ec_device *ec = ckdev->ec; | ||
201 | int ret; | 192 | int ret; |
202 | struct cros_ec_keyb *ckdev = container_of(nb, struct cros_ec_keyb, | ||
203 | notifier); | ||
204 | uint8_t kb_state[ckdev->cols]; | 193 | uint8_t kb_state[ckdev->cols]; |
205 | 194 | ||
195 | if (device_may_wakeup(ec->dev)) | ||
196 | pm_wakeup_event(ec->dev, 0); | ||
197 | |||
206 | ret = cros_ec_keyb_get_state(ckdev, kb_state); | 198 | ret = cros_ec_keyb_get_state(ckdev, kb_state); |
207 | if (ret >= 0) | 199 | if (ret >= 0) |
208 | cros_ec_keyb_process(ckdev, kb_state, ret); | 200 | cros_ec_keyb_process(ckdev, kb_state, ret); |
201 | else | ||
202 | dev_err(ec->dev, "failed to get keyboard state: %d\n", ret); | ||
209 | 203 | ||
210 | return NOTIFY_DONE; | 204 | return IRQ_HANDLED; |
205 | } | ||
206 | |||
207 | static int cros_ec_keyb_open(struct input_dev *dev) | ||
208 | { | ||
209 | struct cros_ec_keyb *ckdev = input_get_drvdata(dev); | ||
210 | struct cros_ec_device *ec = ckdev->ec; | ||
211 | |||
212 | return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, | ||
213 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
214 | "cros_ec_keyb", ckdev); | ||
215 | } | ||
216 | |||
217 | static void cros_ec_keyb_close(struct input_dev *dev) | ||
218 | { | ||
219 | struct cros_ec_keyb *ckdev = input_get_drvdata(dev); | ||
220 | struct cros_ec_device *ec = ckdev->ec; | ||
221 | |||
222 | free_irq(ec->irq, ckdev); | ||
211 | } | 223 | } |
212 | 224 | ||
213 | static int cros_ec_keyb_probe(struct platform_device *pdev) | 225 | static int cros_ec_keyb_probe(struct platform_device *pdev) |
@@ -238,8 +250,12 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) | |||
238 | if (!idev) | 250 | if (!idev) |
239 | return -ENOMEM; | 251 | return -ENOMEM; |
240 | 252 | ||
253 | if (!ec->irq) { | ||
254 | dev_err(dev, "no EC IRQ specified\n"); | ||
255 | return -EINVAL; | ||
256 | } | ||
257 | |||
241 | ckdev->ec = ec; | 258 | ckdev->ec = ec; |
242 | ckdev->notifier.notifier_call = cros_ec_keyb_work; | ||
243 | ckdev->dev = dev; | 259 | ckdev->dev = dev; |
244 | dev_set_drvdata(&pdev->dev, ckdev); | 260 | dev_set_drvdata(&pdev->dev, ckdev); |
245 | 261 | ||
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 64751c2a1ace..e9d50644660c 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c | |||
@@ -158,7 +158,7 @@ static int device_irq_init_805(struct pm80x_chip *chip) | |||
158 | * PM805_INT_STATUS is under 32K clock domain, so need to | 158 | * PM805_INT_STATUS is under 32K clock domain, so need to |
159 | * add proper delay before the next I2C register access. | 159 | * add proper delay before the next I2C register access. |
160 | */ | 160 | */ |
161 | msleep(1); | 161 | usleep_range(1000, 3000); |
162 | 162 | ||
163 | if (ret < 0) | 163 | if (ret < 0) |
164 | goto out; | 164 | goto out; |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index bcfc9e85b4a0..3a2604580164 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * Base driver for Marvell 88PM8607 | 2 | * Base driver for Marvell 88PM8607 |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Marvell International Ltd. | 4 | * Copyright (C) 2009 Marvell International Ltd. |
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | 5 | * |
6 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * 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 | * it under the terms of the GNU General Public License version 2 as |
@@ -140,7 +141,8 @@ static struct resource codec_resources[] = { | |||
140 | /* Headset insertion or removal */ | 141 | /* Headset insertion or removal */ |
141 | {PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,}, | 142 | {PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,}, |
142 | /* Audio short */ | 143 | /* Audio short */ |
143 | {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,}, | 144 | {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", |
145 | IORESOURCE_IRQ,}, | ||
144 | }; | 146 | }; |
145 | 147 | ||
146 | static struct resource battery_resources[] = { | 148 | static struct resource battery_resources[] = { |
@@ -150,10 +152,14 @@ static struct resource battery_resources[] = { | |||
150 | 152 | ||
151 | static struct resource charger_resources[] = { | 153 | static struct resource charger_resources[] = { |
152 | {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,}, | 154 | {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,}, |
153 | {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,}, | 155 | {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", |
154 | {PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", IORESOURCE_IRQ,}, | 156 | IORESOURCE_IRQ,}, |
155 | {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault", IORESOURCE_IRQ,}, | 157 | {PM8607_IRQ_CHG_FAIL, PM8607_IRQ_CHG_FAIL, "charging timeout", |
156 | {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,}, | 158 | IORESOURCE_IRQ,}, |
159 | {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging fault", | ||
160 | IORESOURCE_IRQ,}, | ||
161 | {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", | ||
162 | IORESOURCE_IRQ,}, | ||
157 | {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,}, | 163 | {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,}, |
158 | {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, | 164 | {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, |
159 | }; | 165 | }; |
@@ -568,8 +574,8 @@ static struct irq_domain_ops pm860x_irq_domain_ops = { | |||
568 | static int device_irq_init(struct pm860x_chip *chip, | 574 | static int device_irq_init(struct pm860x_chip *chip, |
569 | struct pm860x_platform_data *pdata) | 575 | struct pm860x_platform_data *pdata) |
570 | { | 576 | { |
571 | struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \ | 577 | struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? |
572 | : chip->companion; | 578 | chip->client : chip->companion; |
573 | unsigned char status_buf[INT_STATUS_NUM]; | 579 | unsigned char status_buf[INT_STATUS_NUM]; |
574 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; | 580 | unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; |
575 | int data, mask, ret = -EINVAL; | 581 | int data, mask, ret = -EINVAL; |
@@ -631,8 +637,8 @@ static int device_irq_init(struct pm860x_chip *chip, | |||
631 | if (!chip->core_irq) | 637 | if (!chip->core_irq) |
632 | goto out; | 638 | goto out; |
633 | 639 | ||
634 | ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT, | 640 | ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, |
635 | "88pm860x", chip); | 641 | flags | IRQF_ONESHOT, "88pm860x", chip); |
636 | if (ret) { | 642 | if (ret) { |
637 | dev_err(chip->dev, "Failed to request IRQ: %d\n", ret); | 643 | dev_err(chip->dev, "Failed to request IRQ: %d\n", ret); |
638 | chip->core_irq = 0; | 644 | chip->core_irq = 0; |
@@ -871,7 +877,7 @@ static void device_rtc_init(struct pm860x_chip *chip, | |||
871 | { | 877 | { |
872 | int ret; | 878 | int ret; |
873 | 879 | ||
874 | if ((pdata == NULL)) | 880 | if (!pdata) |
875 | return; | 881 | return; |
876 | 882 | ||
877 | rtc_devs[0].platform_data = pdata->rtc; | 883 | rtc_devs[0].platform_data = pdata->rtc; |
@@ -997,8 +1003,9 @@ static void device_8607_init(struct pm860x_chip *chip, | |||
997 | ret); | 1003 | ret); |
998 | break; | 1004 | break; |
999 | default: | 1005 | default: |
1000 | dev_err(chip->dev, "Failed to detect Marvell 88PM8607. " | 1006 | dev_err(chip->dev, |
1001 | "Chip ID: %02x\n", ret); | 1007 | "Failed to detect Marvell 88PM8607. Chip ID: %02x\n", |
1008 | ret); | ||
1002 | goto out; | 1009 | goto out; |
1003 | } | 1010 | } |
1004 | 1011 | ||
@@ -1120,8 +1127,8 @@ static int pm860x_dt_init(struct device_node *np, | |||
1120 | ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr", | 1127 | ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr", |
1121 | &pdata->companion_addr); | 1128 | &pdata->companion_addr); |
1122 | if (ret) { | 1129 | if (ret) { |
1123 | dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" " | 1130 | dev_err(dev, |
1124 | "property\n"); | 1131 | "Not found \"marvell,88pm860x-slave-addr\" property\n"); |
1125 | pdata->companion_addr = 0; | 1132 | pdata->companion_addr = 0; |
1126 | } | 1133 | } |
1127 | return 0; | 1134 | return 0; |
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index ff8f803ce833..a93b4d0134a2 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * I2C driver for Marvell 88PM860x | 2 | * I2C driver for Marvell 88PM860x |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Marvell International Ltd. | 4 | * Copyright (C) 2009 Marvell International Ltd. |
5 | * Haojian Zhuang <haojian.zhuang@marvell.com> | 5 | * |
6 | * Author: Haojian Zhuang <haojian.zhuang@marvell.com> | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * 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 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index fb824f501197..de5abf244746 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -13,7 +13,7 @@ config MFD_CORE | |||
13 | config MFD_CS5535 | 13 | config MFD_CS5535 |
14 | tristate "AMD CS5535 and CS5536 southbridge core functions" | 14 | tristate "AMD CS5535 and CS5536 southbridge core functions" |
15 | select MFD_CORE | 15 | select MFD_CORE |
16 | depends on PCI && X86 | 16 | depends on PCI && (X86_32 || (X86 && COMPILE_TEST)) |
17 | ---help--- | 17 | ---help--- |
18 | This is the core driver for CS5535/CS5536 MFD functions. This is | 18 | This is the core driver for CS5535/CS5536 MFD functions. This is |
19 | necessary for using the board's GPIO and MFGPT functionality. | 19 | necessary for using the board's GPIO and MFGPT functionality. |
@@ -187,6 +187,7 @@ config MFD_MC13XXX | |||
187 | tristate | 187 | tristate |
188 | depends on (SPI_MASTER || I2C) | 188 | depends on (SPI_MASTER || I2C) |
189 | select MFD_CORE | 189 | select MFD_CORE |
190 | select REGMAP_IRQ | ||
190 | help | 191 | help |
191 | Enable support for the Freescale MC13783 and MC13892 PMICs. | 192 | Enable support for the Freescale MC13783 and MC13892 PMICs. |
192 | This driver provides common support for accessing the device, | 193 | This driver provides common support for accessing the device, |
@@ -253,6 +254,18 @@ config LPC_SCH | |||
253 | LPC bridge function of the Intel SCH provides support for | 254 | LPC bridge function of the Intel SCH provides support for |
254 | System Management Bus and General Purpose I/O. | 255 | System Management Bus and General Purpose I/O. |
255 | 256 | ||
257 | config INTEL_SOC_PMIC | ||
258 | bool "Support for Intel Atom SoC PMIC" | ||
259 | depends on I2C=y | ||
260 | select MFD_CORE | ||
261 | select REGMAP_I2C | ||
262 | select REGMAP_IRQ | ||
263 | help | ||
264 | Select this option to enable support for the PMIC device | ||
265 | on some Intel SoC systems. The PMIC provides ADC, GPIO, | ||
266 | thermal, charger and related power management functions | ||
267 | on these systems. | ||
268 | |||
256 | config MFD_INTEL_MSIC | 269 | config MFD_INTEL_MSIC |
257 | bool "Intel MSIC" | 270 | bool "Intel MSIC" |
258 | depends on INTEL_SCU_IPC | 271 | depends on INTEL_SCU_IPC |
@@ -367,14 +380,15 @@ config MFD_MAX14577 | |||
367 | of the device. | 380 | of the device. |
368 | 381 | ||
369 | config MFD_MAX77686 | 382 | config MFD_MAX77686 |
370 | bool "Maxim Semiconductor MAX77686 PMIC Support" | 383 | bool "Maxim Semiconductor MAX77686/802 PMIC Support" |
371 | depends on I2C=y | 384 | depends on I2C=y |
372 | select MFD_CORE | 385 | select MFD_CORE |
373 | select REGMAP_I2C | 386 | select REGMAP_I2C |
387 | select REGMAP_IRQ | ||
374 | select IRQ_DOMAIN | 388 | select IRQ_DOMAIN |
375 | help | 389 | help |
376 | Say yes here to add support for Maxim Semiconductor MAX77686. | 390 | Say yes here to add support for Maxim Semiconductor MAX77686 and |
377 | This is a Power Management IC with RTC on chip. | 391 | MAX77802 which are Power Management IC with an RTC on chip. |
378 | This driver provides common support for accessing the device; | 392 | This driver provides common support for accessing the device; |
379 | additional drivers must be enabled in order to use the functionality | 393 | additional drivers must be enabled in order to use the functionality |
380 | of the device. | 394 | of the device. |
@@ -574,6 +588,7 @@ config MFD_SEC_CORE | |||
574 | select MFD_CORE | 588 | select MFD_CORE |
575 | select REGMAP_I2C | 589 | select REGMAP_I2C |
576 | select REGMAP_IRQ | 590 | select REGMAP_IRQ |
591 | select REGULATOR | ||
577 | help | 592 | help |
578 | Support for the Samsung Electronics MFD series. | 593 | Support for the Samsung Electronics MFD series. |
579 | This driver provides common support for accessing the device, | 594 | This driver provides common support for accessing the device, |
@@ -1057,7 +1072,7 @@ config MFD_LM3533 | |||
1057 | config MFD_TIMBERDALE | 1072 | config MFD_TIMBERDALE |
1058 | tristate "Timberdale FPGA" | 1073 | tristate "Timberdale FPGA" |
1059 | select MFD_CORE | 1074 | select MFD_CORE |
1060 | depends on PCI && GPIOLIB | 1075 | depends on PCI && GPIOLIB && (X86_32 || COMPILE_TEST) |
1061 | ---help--- | 1076 | ---help--- |
1062 | This is the core driver for the timberdale FPGA. This device is a | 1077 | This is the core driver for the timberdale FPGA. This device is a |
1063 | multifunction device which exposes numerous platform devices. | 1078 | multifunction device which exposes numerous platform devices. |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 8c6e7bba4660..f00148782d9b 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -115,7 +115,7 @@ da9063-objs := da9063-core.o da9063-irq.o da9063-i2c.o | |||
115 | obj-$(CONFIG_MFD_DA9063) += da9063.o | 115 | obj-$(CONFIG_MFD_DA9063) += da9063.o |
116 | 116 | ||
117 | obj-$(CONFIG_MFD_MAX14577) += max14577.o | 117 | obj-$(CONFIG_MFD_MAX14577) += max14577.o |
118 | obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o | 118 | obj-$(CONFIG_MFD_MAX77686) += max77686.o |
119 | obj-$(CONFIG_MFD_MAX77693) += max77693.o | 119 | obj-$(CONFIG_MFD_MAX77693) += max77693.o |
120 | obj-$(CONFIG_MFD_MAX8907) += max8907.o | 120 | obj-$(CONFIG_MFD_MAX8907) += max8907.o |
121 | max8925-objs := max8925-core.o max8925-i2c.o | 121 | max8925-objs := max8925-core.o max8925-i2c.o |
@@ -169,3 +169,6 @@ obj-$(CONFIG_MFD_AS3711) += as3711.o | |||
169 | obj-$(CONFIG_MFD_AS3722) += as3722.o | 169 | obj-$(CONFIG_MFD_AS3722) += as3722.o |
170 | obj-$(CONFIG_MFD_STW481X) += stw481x.o | 170 | obj-$(CONFIG_MFD_STW481X) += stw481x.o |
171 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o | 171 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o |
172 | |||
173 | intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o | ||
174 | obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o | ||
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 14d9542a4eed..4e6e03d63e12 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -303,7 +303,10 @@ static ssize_t aat2870_reg_write_file(struct file *file, | |||
303 | while (*start == ' ') | 303 | while (*start == ' ') |
304 | start++; | 304 | start++; |
305 | 305 | ||
306 | addr = simple_strtoul(start, &start, 16); | 306 | ret = kstrtoul(start, 16, &addr); |
307 | if (ret) | ||
308 | return ret; | ||
309 | |||
307 | if (addr >= AAT2870_REG_NUM) { | 310 | if (addr >= AAT2870_REG_NUM) { |
308 | dev_err(aat2870->dev, "Invalid address, 0x%lx\n", addr); | 311 | dev_err(aat2870->dev, "Invalid address, 0x%lx\n", addr); |
309 | return -EINVAL; | 312 | return -EINVAL; |
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index b348ae520629..4659ac1db039 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -91,8 +91,8 @@ static int ab3100_set_register_interruptible(struct ab3100 *ab3100, | |||
91 | err); | 91 | err); |
92 | } else if (err != 2) { | 92 | } else if (err != 2) { |
93 | dev_err(ab3100->dev, | 93 | dev_err(ab3100->dev, |
94 | "write error (write register) " | 94 | "write error (write register)\n" |
95 | "%d bytes transferred (expected 2)\n", | 95 | " %d bytes transferred (expected 2)\n", |
96 | err); | 96 | err); |
97 | err = -EIO; | 97 | err = -EIO; |
98 | } else { | 98 | } else { |
@@ -135,8 +135,8 @@ static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100, | |||
135 | err); | 135 | err); |
136 | } else if (err != 2) { | 136 | } else if (err != 2) { |
137 | dev_err(ab3100->dev, | 137 | dev_err(ab3100->dev, |
138 | "write error (write test register) " | 138 | "write error (write test register)\n" |
139 | "%d bytes transferred (expected 2)\n", | 139 | " %d bytes transferred (expected 2)\n", |
140 | err); | 140 | err); |
141 | err = -EIO; | 141 | err = -EIO; |
142 | } else { | 142 | } else { |
@@ -171,8 +171,8 @@ static int ab3100_get_register_interruptible(struct ab3100 *ab3100, | |||
171 | goto get_reg_out_unlock; | 171 | goto get_reg_out_unlock; |
172 | } else if (err != 1) { | 172 | } else if (err != 1) { |
173 | dev_err(ab3100->dev, | 173 | dev_err(ab3100->dev, |
174 | "write error (send register address) " | 174 | "write error (send register address)\n" |
175 | "%d bytes transferred (expected 1)\n", | 175 | " %d bytes transferred (expected 1)\n", |
176 | err); | 176 | err); |
177 | err = -EIO; | 177 | err = -EIO; |
178 | goto get_reg_out_unlock; | 178 | goto get_reg_out_unlock; |
@@ -189,8 +189,8 @@ static int ab3100_get_register_interruptible(struct ab3100 *ab3100, | |||
189 | goto get_reg_out_unlock; | 189 | goto get_reg_out_unlock; |
190 | } else if (err != 1) { | 190 | } else if (err != 1) { |
191 | dev_err(ab3100->dev, | 191 | dev_err(ab3100->dev, |
192 | "write error (read register) " | 192 | "write error (read register)\n" |
193 | "%d bytes transferred (expected 1)\n", | 193 | " %d bytes transferred (expected 1)\n", |
194 | err); | 194 | err); |
195 | err = -EIO; | 195 | err = -EIO; |
196 | goto get_reg_out_unlock; | 196 | goto get_reg_out_unlock; |
@@ -237,8 +237,8 @@ static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, | |||
237 | goto get_reg_page_out_unlock; | 237 | goto get_reg_page_out_unlock; |
238 | } else if (err != 1) { | 238 | } else if (err != 1) { |
239 | dev_err(ab3100->dev, | 239 | dev_err(ab3100->dev, |
240 | "write error (send first register address) " | 240 | "write error (send first register address)\n" |
241 | "%d bytes transferred (expected 1)\n", | 241 | " %d bytes transferred (expected 1)\n", |
242 | err); | 242 | err); |
243 | err = -EIO; | 243 | err = -EIO; |
244 | goto get_reg_page_out_unlock; | 244 | goto get_reg_page_out_unlock; |
@@ -252,8 +252,8 @@ static int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, | |||
252 | goto get_reg_page_out_unlock; | 252 | goto get_reg_page_out_unlock; |
253 | } else if (err != numregs) { | 253 | } else if (err != numregs) { |
254 | dev_err(ab3100->dev, | 254 | dev_err(ab3100->dev, |
255 | "write error (read register page) " | 255 | "write error (read register page)\n" |
256 | "%d bytes transferred (expected %d)\n", | 256 | " %d bytes transferred (expected %d)\n", |
257 | err, numregs); | 257 | err, numregs); |
258 | err = -EIO; | 258 | err = -EIO; |
259 | goto get_reg_page_out_unlock; | 259 | goto get_reg_page_out_unlock; |
@@ -295,8 +295,8 @@ static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, | |||
295 | goto get_maskset_unlock; | 295 | goto get_maskset_unlock; |
296 | } else if (err != 1) { | 296 | } else if (err != 1) { |
297 | dev_err(ab3100->dev, | 297 | dev_err(ab3100->dev, |
298 | "write error (maskset send address) " | 298 | "write error (maskset send address)\n" |
299 | "%d bytes transferred (expected 1)\n", | 299 | " %d bytes transferred (expected 1)\n", |
300 | err); | 300 | err); |
301 | err = -EIO; | 301 | err = -EIO; |
302 | goto get_maskset_unlock; | 302 | goto get_maskset_unlock; |
@@ -310,8 +310,8 @@ static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, | |||
310 | goto get_maskset_unlock; | 310 | goto get_maskset_unlock; |
311 | } else if (err != 1) { | 311 | } else if (err != 1) { |
312 | dev_err(ab3100->dev, | 312 | dev_err(ab3100->dev, |
313 | "write error (maskset read register) " | 313 | "write error (maskset read register)\n" |
314 | "%d bytes transferred (expected 1)\n", | 314 | " %d bytes transferred (expected 1)\n", |
315 | err); | 315 | err); |
316 | err = -EIO; | 316 | err = -EIO; |
317 | goto get_maskset_unlock; | 317 | goto get_maskset_unlock; |
@@ -330,8 +330,8 @@ static int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, | |||
330 | goto get_maskset_unlock; | 330 | goto get_maskset_unlock; |
331 | } else if (err != 2) { | 331 | } else if (err != 2) { |
332 | dev_err(ab3100->dev, | 332 | dev_err(ab3100->dev, |
333 | "write error (write register) " | 333 | "write error (write register)\n" |
334 | "%d bytes transferred (expected 2)\n", | 334 | " %d bytes transferred (expected 2)\n", |
335 | err); | 335 | err); |
336 | err = -EIO; | 336 | err = -EIO; |
337 | goto get_maskset_unlock; | 337 | goto get_maskset_unlock; |
@@ -371,7 +371,7 @@ EXPORT_SYMBOL(ab3100_event_register); | |||
371 | int ab3100_event_unregister(struct ab3100 *ab3100, | 371 | int ab3100_event_unregister(struct ab3100 *ab3100, |
372 | struct notifier_block *nb) | 372 | struct notifier_block *nb) |
373 | { | 373 | { |
374 | return blocking_notifier_chain_unregister(&ab3100->event_subscribers, | 374 | return blocking_notifier_chain_unregister(&ab3100->event_subscribers, |
375 | nb); | 375 | nb); |
376 | } | 376 | } |
377 | EXPORT_SYMBOL(ab3100_event_unregister); | 377 | EXPORT_SYMBOL(ab3100_event_unregister); |
@@ -455,7 +455,7 @@ static int ab3100_registers_print(struct seq_file *s, void *p) | |||
455 | u8 value; | 455 | u8 value; |
456 | u8 reg; | 456 | u8 reg; |
457 | 457 | ||
458 | seq_printf(s, "AB3100 registers:\n"); | 458 | seq_puts(s, "AB3100 registers:\n"); |
459 | 459 | ||
460 | for (reg = 0; reg < 0xff; reg++) { | 460 | for (reg = 0; reg < 0xff; reg++) { |
461 | ab3100_get_register_interruptible(ab3100, reg, &value); | 461 | ab3100_get_register_interruptible(ab3100, reg, &value); |
@@ -560,8 +560,8 @@ static ssize_t ab3100_get_set_reg(struct file *file, | |||
560 | ab3100_get_register_interruptible(ab3100, user_reg, ®value); | 560 | ab3100_get_register_interruptible(ab3100, user_reg, ®value); |
561 | 561 | ||
562 | dev_info(ab3100->dev, | 562 | dev_info(ab3100->dev, |
563 | "debug write reg[0x%02x] with 0x%02x, " | 563 | "debug write reg[0x%02x]\n" |
564 | "after readback: 0x%02x\n", | 564 | " with 0x%02x, after readback: 0x%02x\n", |
565 | user_reg, user_value, regvalue); | 565 | user_reg, user_value, regvalue); |
566 | } | 566 | } |
567 | return buf_size; | 567 | return buf_size; |
@@ -719,8 +719,7 @@ static int ab3100_setup(struct ab3100 *ab3100) | |||
719 | */ | 719 | */ |
720 | if (ab3100->chip_id == 0xc4) { | 720 | if (ab3100->chip_id == 0xc4) { |
721 | dev_warn(ab3100->dev, | 721 | dev_warn(ab3100->dev, |
722 | "AB3100 P1E variant detected, " | 722 | "AB3100 P1E variant detected forcing chip to 32KHz\n"); |
723 | "forcing chip to 32KHz\n"); | ||
724 | err = ab3100_set_test_register_interruptible(ab3100, | 723 | err = ab3100_set_test_register_interruptible(ab3100, |
725 | 0x02, 0x08); | 724 | 0x02, 0x08); |
726 | } | 725 | } |
@@ -878,8 +877,7 @@ static int ab3100_probe(struct i2c_client *client, | |||
878 | &ab3100->chip_id); | 877 | &ab3100->chip_id); |
879 | if (err) { | 878 | if (err) { |
880 | dev_err(&client->dev, | 879 | dev_err(&client->dev, |
881 | "could not communicate with the AB3100 analog " | 880 | "failed to communicate with AB3100 chip\n"); |
882 | "baseband chip\n"); | ||
883 | goto exit_no_detect; | 881 | goto exit_no_detect; |
884 | } | 882 | } |
885 | 883 | ||
@@ -902,8 +900,8 @@ static int ab3100_probe(struct i2c_client *client, | |||
902 | if (ids[i].id == 0x0) { | 900 | if (ids[i].id == 0x0) { |
903 | dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", | 901 | dev_err(&client->dev, "unknown analog baseband chip id: 0x%x\n", |
904 | ab3100->chip_id); | 902 | ab3100->chip_id); |
905 | dev_err(&client->dev, "accepting it anyway. Please update " | 903 | dev_err(&client->dev, |
906 | "the driver.\n"); | 904 | "accepting it anyway. Please update the driver.\n"); |
907 | goto exit_no_detect; | 905 | goto exit_no_detect; |
908 | } | 906 | } |
909 | 907 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index cf2e6a198c6b..ce48aa72bb42 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -148,8 +148,8 @@ static const int ab9540_irq_regoffset[AB9540_NUM_IRQ_REGS] = { | |||
148 | 148 | ||
149 | /* AB8540 support */ | 149 | /* AB8540 support */ |
150 | static const int ab8540_irq_regoffset[AB8540_NUM_IRQ_REGS] = { | 150 | static const int ab8540_irq_regoffset[AB8540_NUM_IRQ_REGS] = { |
151 | 0, 1, 2, 3, 4, -1, -1, -1, -1, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, 23, | 151 | 0, 1, 2, 3, 4, -1, -1, -1, -1, 11, 18, 19, 20, 21, 12, 13, 24, 5, 22, |
152 | 25, 26, 27, 28, 29, 30, 31, | 152 | 23, 25, 26, 27, 28, 29, 30, 31, |
153 | }; | 153 | }; |
154 | 154 | ||
155 | static const char ab8500_version_str[][7] = { | 155 | static const char ab8500_version_str[][7] = { |
@@ -322,7 +322,7 @@ static int ab8500_mask_and_set_register(struct device *dev, | |||
322 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); | 322 | struct ab8500 *ab8500 = dev_get_drvdata(dev->parent); |
323 | 323 | ||
324 | atomic_inc(&ab8500->transfer_ongoing); | 324 | atomic_inc(&ab8500->transfer_ongoing); |
325 | ret= mask_and_set_register_interruptible(ab8500, bank, reg, | 325 | ret = mask_and_set_register_interruptible(ab8500, bank, reg, |
326 | bitmask, bitvalues); | 326 | bitmask, bitvalues); |
327 | atomic_dec(&ab8500->transfer_ongoing); | 327 | atomic_dec(&ab8500->transfer_ongoing); |
328 | return ret; | 328 | return ret; |
@@ -415,9 +415,11 @@ static void ab8500_irq_unmask(struct irq_data *data) | |||
415 | if (type & IRQ_TYPE_EDGE_FALLING) { | 415 | if (type & IRQ_TYPE_EDGE_FALLING) { |
416 | if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) | 416 | if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R) |
417 | ab8500->mask[index + 2] &= ~mask; | 417 | ab8500->mask[index + 2] &= ~mask; |
418 | else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R) | 418 | else if (offset >= AB9540_INT_GPIO50R && |
419 | offset <= AB9540_INT_GPIO54R) | ||
419 | ab8500->mask[index + 1] &= ~mask; | 420 | ab8500->mask[index + 1] &= ~mask; |
420 | else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R) | 421 | else if (offset == AB8540_INT_GPIO43R || |
422 | offset == AB8540_INT_GPIO44R) | ||
421 | /* Here the falling IRQ is one bit lower */ | 423 | /* Here the falling IRQ is one bit lower */ |
422 | ab8500->mask[index] &= ~(mask << 1); | 424 | ab8500->mask[index] &= ~(mask << 1); |
423 | else | 425 | else |
@@ -451,7 +453,7 @@ static void update_latch_offset(u8 *offset, int i) | |||
451 | /* Fix inconsistent ab8540 bit mapping... */ | 453 | /* Fix inconsistent ab8540 bit mapping... */ |
452 | if (unlikely(*offset == 16)) | 454 | if (unlikely(*offset == 16)) |
453 | *offset = 25; | 455 | *offset = 25; |
454 | if ((i==3) && (*offset >= 24)) | 456 | if ((i == 3) && (*offset >= 24)) |
455 | *offset += 2; | 457 | *offset += 2; |
456 | } | 458 | } |
457 | 459 | ||
@@ -573,8 +575,8 @@ static int ab8500_irq_map(struct irq_domain *d, unsigned int virq, | |||
573 | } | 575 | } |
574 | 576 | ||
575 | static struct irq_domain_ops ab8500_irq_ops = { | 577 | static struct irq_domain_ops ab8500_irq_ops = { |
576 | .map = ab8500_irq_map, | 578 | .map = ab8500_irq_map, |
577 | .xlate = irq_domain_xlate_twocell, | 579 | .xlate = irq_domain_xlate_twocell, |
578 | }; | 580 | }; |
579 | 581 | ||
580 | static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np) | 582 | static int ab8500_irq_init(struct ab8500 *ab8500, struct device_node *np) |
@@ -607,8 +609,8 @@ int ab8500_suspend(struct ab8500 *ab8500) | |||
607 | { | 609 | { |
608 | if (atomic_read(&ab8500->transfer_ongoing)) | 610 | if (atomic_read(&ab8500->transfer_ongoing)) |
609 | return -EINVAL; | 611 | return -EINVAL; |
610 | else | 612 | |
611 | return 0; | 613 | return 0; |
612 | } | 614 | } |
613 | 615 | ||
614 | static struct resource ab8500_gpadc_resources[] = { | 616 | static struct resource ab8500_gpadc_resources[] = { |
@@ -1551,7 +1553,7 @@ static struct attribute_group ab9540_attr_group = { | |||
1551 | 1553 | ||
1552 | static int ab8500_probe(struct platform_device *pdev) | 1554 | static int ab8500_probe(struct platform_device *pdev) |
1553 | { | 1555 | { |
1554 | static char *switch_off_status[] = { | 1556 | static const char *switch_off_status[] = { |
1555 | "Swoff bit programming", | 1557 | "Swoff bit programming", |
1556 | "Thermal protection activation", | 1558 | "Thermal protection activation", |
1557 | "Vbat lower then BattOk falling threshold", | 1559 | "Vbat lower then BattOk falling threshold", |
@@ -1560,7 +1562,7 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1560 | "Battery level lower than power on reset threshold", | 1562 | "Battery level lower than power on reset threshold", |
1561 | "Power on key 1 pressed longer than 10 seconds", | 1563 | "Power on key 1 pressed longer than 10 seconds", |
1562 | "DB8500 thermal shutdown"}; | 1564 | "DB8500 thermal shutdown"}; |
1563 | static char *turn_on_status[] = { | 1565 | static const char *turn_on_status[] = { |
1564 | "Battery rising (Vbat)", | 1566 | "Battery rising (Vbat)", |
1565 | "Power On Key 1 dbF", | 1567 | "Power On Key 1 dbF", |
1566 | "Power On Key 2 dbF", | 1568 | "Power On Key 2 dbF", |
@@ -1579,7 +1581,7 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1579 | int i; | 1581 | int i; |
1580 | u8 value; | 1582 | u8 value; |
1581 | 1583 | ||
1582 | ab8500 = devm_kzalloc(&pdev->dev, sizeof *ab8500, GFP_KERNEL); | 1584 | ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); |
1583 | if (!ab8500) | 1585 | if (!ab8500) |
1584 | return -ENOMEM; | 1586 | return -ENOMEM; |
1585 | 1587 | ||
@@ -1636,7 +1638,7 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1636 | ab8500->mask_size = AB8540_NUM_IRQ_REGS; | 1638 | ab8500->mask_size = AB8540_NUM_IRQ_REGS; |
1637 | ab8500->irq_reg_offset = ab8540_irq_regoffset; | 1639 | ab8500->irq_reg_offset = ab8540_irq_regoffset; |
1638 | ab8500->it_latchhier_num = AB8540_IT_LATCHHIER_NUM; | 1640 | ab8500->it_latchhier_num = AB8540_IT_LATCHHIER_NUM; |
1639 | }/* Configure AB8500 or AB9540 IRQ */ | 1641 | } /* Configure AB8500 or AB9540 IRQ */ |
1640 | else if (is_ab9540(ab8500) || is_ab8505(ab8500)) { | 1642 | else if (is_ab9540(ab8500) || is_ab8505(ab8500)) { |
1641 | ab8500->mask_size = AB9540_NUM_IRQ_REGS; | 1643 | ab8500->mask_size = AB9540_NUM_IRQ_REGS; |
1642 | ab8500->irq_reg_offset = ab9540_irq_regoffset; | 1644 | ab8500->irq_reg_offset = ab9540_irq_regoffset; |
@@ -1646,10 +1648,12 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1646 | ab8500->irq_reg_offset = ab8500_irq_regoffset; | 1648 | ab8500->irq_reg_offset = ab8500_irq_regoffset; |
1647 | ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM; | 1649 | ab8500->it_latchhier_num = AB8500_IT_LATCHHIER_NUM; |
1648 | } | 1650 | } |
1649 | ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL); | 1651 | ab8500->mask = devm_kzalloc(&pdev->dev, ab8500->mask_size, |
1652 | GFP_KERNEL); | ||
1650 | if (!ab8500->mask) | 1653 | if (!ab8500->mask) |
1651 | return -ENOMEM; | 1654 | return -ENOMEM; |
1652 | ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size, GFP_KERNEL); | 1655 | ab8500->oldmask = devm_kzalloc(&pdev->dev, ab8500->mask_size, |
1656 | GFP_KERNEL); | ||
1653 | if (!ab8500->oldmask) | 1657 | if (!ab8500->oldmask) |
1654 | return -ENOMEM; | 1658 | return -ENOMEM; |
1655 | 1659 | ||
@@ -1674,14 +1678,13 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1674 | if (value) { | 1678 | if (value) { |
1675 | for (i = 0; i < ARRAY_SIZE(switch_off_status); i++) { | 1679 | for (i = 0; i < ARRAY_SIZE(switch_off_status); i++) { |
1676 | if (value & 1) | 1680 | if (value & 1) |
1677 | printk(KERN_CONT " \"%s\"", | 1681 | pr_cont(" \"%s\"", switch_off_status[i]); |
1678 | switch_off_status[i]); | ||
1679 | value = value >> 1; | 1682 | value = value >> 1; |
1680 | 1683 | ||
1681 | } | 1684 | } |
1682 | printk(KERN_CONT "\n"); | 1685 | pr_cont("\n"); |
1683 | } else { | 1686 | } else { |
1684 | printk(KERN_CONT " None\n"); | 1687 | pr_cont(" None\n"); |
1685 | } | 1688 | } |
1686 | ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK, | 1689 | ret = get_register_interruptible(ab8500, AB8500_SYS_CTRL1_BLOCK, |
1687 | AB8500_TURN_ON_STATUS, &value); | 1690 | AB8500_TURN_ON_STATUS, &value); |
@@ -1692,12 +1695,12 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1692 | if (value) { | 1695 | if (value) { |
1693 | for (i = 0; i < ARRAY_SIZE(turn_on_status); i++) { | 1696 | for (i = 0; i < ARRAY_SIZE(turn_on_status); i++) { |
1694 | if (value & 1) | 1697 | if (value & 1) |
1695 | printk("\"%s\" ", turn_on_status[i]); | 1698 | pr_cont("\"%s\" ", turn_on_status[i]); |
1696 | value = value >> 1; | 1699 | value = value >> 1; |
1697 | } | 1700 | } |
1698 | printk("\n"); | 1701 | pr_cont("\n"); |
1699 | } else { | 1702 | } else { |
1700 | printk("None\n"); | 1703 | pr_cont("None\n"); |
1701 | } | 1704 | } |
1702 | 1705 | ||
1703 | if (plat && plat->init) | 1706 | if (plat && plat->init) |
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index d1a22aae2df5..b2c7e3b1edfa 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c | |||
@@ -135,10 +135,10 @@ struct ab8500_prcmu_ranges { | |||
135 | /* hwreg- "mask" and "shift" entries ressources */ | 135 | /* hwreg- "mask" and "shift" entries ressources */ |
136 | struct hwreg_cfg { | 136 | struct hwreg_cfg { |
137 | u32 bank; /* target bank */ | 137 | u32 bank; /* target bank */ |
138 | u32 addr; /* target address */ | 138 | unsigned long addr; /* target address */ |
139 | uint fmt; /* format */ | 139 | uint fmt; /* format */ |
140 | uint mask; /* read/write mask, applied before any bit shift */ | 140 | unsigned long mask; /* read/write mask, applied before any bit shift */ |
141 | int shift; /* bit shift (read:right shift, write:left shift */ | 141 | long shift; /* bit shift (read:right shift, write:left shift */ |
142 | }; | 142 | }; |
143 | /* fmt bit #0: 0=hexa, 1=dec */ | 143 | /* fmt bit #0: 0=hexa, 1=dec */ |
144 | #define REG_FMT_DEC(c) ((c)->fmt & 0x1) | 144 | #define REG_FMT_DEC(c) ((c)->fmt & 0x1) |
@@ -1304,16 +1304,17 @@ static int ab8500_registers_print(struct device *dev, u32 bank, | |||
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | if (s) { | 1306 | if (s) { |
1307 | err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", | 1307 | err = seq_printf(s, |
1308 | bank, reg, value); | 1308 | " [0x%02X/0x%02X]: 0x%02X\n", |
1309 | bank, reg, value); | ||
1309 | if (err < 0) { | 1310 | if (err < 0) { |
1310 | /* Error is not returned here since | 1311 | /* Error is not returned here since |
1311 | * the output is wanted in any case */ | 1312 | * the output is wanted in any case */ |
1312 | return 0; | 1313 | return 0; |
1313 | } | 1314 | } |
1314 | } else { | 1315 | } else { |
1315 | printk(KERN_INFO" [0x%02X/0x%02X]: 0x%02X\n", | 1316 | dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n", |
1316 | bank, reg, value); | 1317 | bank, reg, value); |
1317 | } | 1318 | } |
1318 | } | 1319 | } |
1319 | } | 1320 | } |
@@ -1325,7 +1326,7 @@ static int ab8500_print_bank_registers(struct seq_file *s, void *p) | |||
1325 | struct device *dev = s->private; | 1326 | struct device *dev = s->private; |
1326 | u32 bank = debug_bank; | 1327 | u32 bank = debug_bank; |
1327 | 1328 | ||
1328 | seq_printf(s, AB8500_NAME_STRING " register values:\n"); | 1329 | seq_puts(s, AB8500_NAME_STRING " register values:\n"); |
1329 | 1330 | ||
1330 | seq_printf(s, " bank 0x%02X:\n", bank); | 1331 | seq_printf(s, " bank 0x%02X:\n", bank); |
1331 | 1332 | ||
@@ -1350,12 +1351,11 @@ static int ab8500_print_all_banks(struct seq_file *s, void *p) | |||
1350 | { | 1351 | { |
1351 | struct device *dev = s->private; | 1352 | struct device *dev = s->private; |
1352 | unsigned int i; | 1353 | unsigned int i; |
1353 | int err; | ||
1354 | 1354 | ||
1355 | seq_printf(s, AB8500_NAME_STRING " register values:\n"); | 1355 | seq_puts(s, AB8500_NAME_STRING " register values:\n"); |
1356 | 1356 | ||
1357 | for (i = 0; i < AB8500_NUM_BANKS; i++) { | 1357 | for (i = 0; i < AB8500_NUM_BANKS; i++) { |
1358 | err = seq_printf(s, " bank 0x%02X:\n", i); | 1358 | seq_printf(s, " bank 0x%02X:\n", i); |
1359 | 1359 | ||
1360 | ab8500_registers_print(dev, i, s); | 1360 | ab8500_registers_print(dev, i, s); |
1361 | } | 1361 | } |
@@ -1367,10 +1367,10 @@ void ab8500_dump_all_banks(struct device *dev) | |||
1367 | { | 1367 | { |
1368 | unsigned int i; | 1368 | unsigned int i; |
1369 | 1369 | ||
1370 | printk(KERN_INFO"ab8500 register values:\n"); | 1370 | dev_info(dev, "ab8500 register values:\n"); |
1371 | 1371 | ||
1372 | for (i = 1; i < AB8500_NUM_BANKS; i++) { | 1372 | for (i = 1; i < AB8500_NUM_BANKS; i++) { |
1373 | printk(KERN_INFO" bank 0x%02X:\n", i); | 1373 | dev_info(dev, " bank 0x%02X:\n", i); |
1374 | ab8500_registers_print(dev, i, NULL); | 1374 | ab8500_registers_print(dev, i, NULL); |
1375 | } | 1375 | } |
1376 | } | 1376 | } |
@@ -1384,8 +1384,6 @@ static struct ab8500_register_dump | |||
1384 | u8 value; | 1384 | u8 value; |
1385 | } ab8500_complete_register_dump[DUMP_MAX_REGS]; | 1385 | } ab8500_complete_register_dump[DUMP_MAX_REGS]; |
1386 | 1386 | ||
1387 | extern int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); | ||
1388 | |||
1389 | /* This shall only be called upon kernel panic! */ | 1387 | /* This shall only be called upon kernel panic! */ |
1390 | void ab8500_dump_all_banks_to_mem(void) | 1388 | void ab8500_dump_all_banks_to_mem(void) |
1391 | { | 1389 | { |
@@ -1393,8 +1391,7 @@ void ab8500_dump_all_banks_to_mem(void) | |||
1393 | u8 bank; | 1391 | u8 bank; |
1394 | int err = 0; | 1392 | int err = 0; |
1395 | 1393 | ||
1396 | pr_info("Saving all ABB registers at \"ab8500_complete_register_dump\" " | 1394 | pr_info("Saving all ABB registers for crash analysis.\n"); |
1397 | "for crash analyze.\n"); | ||
1398 | 1395 | ||
1399 | for (bank = 0; bank < AB8500_NUM_BANKS; bank++) { | 1396 | for (bank = 0; bank < AB8500_NUM_BANKS; bank++) { |
1400 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { | 1397 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { |
@@ -1564,7 +1561,7 @@ static ssize_t ab8500_val_write(struct file *file, | |||
1564 | err = abx500_set_register_interruptible(dev, | 1561 | err = abx500_set_register_interruptible(dev, |
1565 | (u8)debug_bank, debug_address, (u8)user_val); | 1562 | (u8)debug_bank, debug_address, (u8)user_val); |
1566 | if (err < 0) { | 1563 | if (err < 0) { |
1567 | printk(KERN_ERR "abx500_set_reg failed %d, %d", err, __LINE__); | 1564 | pr_err("abx500_set_reg failed %d, %d", err, __LINE__); |
1568 | return -EINVAL; | 1565 | return -EINVAL; |
1569 | } | 1566 | } |
1570 | 1567 | ||
@@ -1596,7 +1593,7 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p) | |||
1596 | { | 1593 | { |
1597 | int line; | 1594 | int line; |
1598 | 1595 | ||
1599 | seq_printf(s, "name: number: number of: wake:\n"); | 1596 | seq_puts(s, "name: number: number of: wake:\n"); |
1600 | 1597 | ||
1601 | for (line = 0; line < num_interrupt_lines; line++) { | 1598 | for (line = 0; line < num_interrupt_lines; line++) { |
1602 | struct irq_desc *desc = irq_to_desc(line + irq_first); | 1599 | struct irq_desc *desc = irq_to_desc(line + irq_first); |
@@ -1722,7 +1719,8 @@ static int ab8500_print_modem_registers(struct seq_file *s, void *p) | |||
1722 | 1719 | ||
1723 | static int ab8500_modem_open(struct inode *inode, struct file *file) | 1720 | static int ab8500_modem_open(struct inode *inode, struct file *file) |
1724 | { | 1721 | { |
1725 | return single_open(file, ab8500_print_modem_registers, inode->i_private); | 1722 | return single_open(file, ab8500_print_modem_registers, |
1723 | inode->i_private); | ||
1726 | } | 1724 | } |
1727 | 1725 | ||
1728 | static const struct file_operations ab8500_modem_fops = { | 1726 | static const struct file_operations ab8500_modem_fops = { |
@@ -1751,7 +1749,8 @@ static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p) | |||
1751 | 1749 | ||
1752 | static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file) | 1750 | static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file) |
1753 | { | 1751 | { |
1754 | return single_open(file, ab8500_gpadc_bat_ctrl_print, inode->i_private); | 1752 | return single_open(file, ab8500_gpadc_bat_ctrl_print, |
1753 | inode->i_private); | ||
1755 | } | 1754 | } |
1756 | 1755 | ||
1757 | static const struct file_operations ab8500_gpadc_bat_ctrl_fops = { | 1756 | static const struct file_operations ab8500_gpadc_bat_ctrl_fops = { |
@@ -1781,7 +1780,8 @@ static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p) | |||
1781 | static int ab8500_gpadc_btemp_ball_open(struct inode *inode, | 1780 | static int ab8500_gpadc_btemp_ball_open(struct inode *inode, |
1782 | struct file *file) | 1781 | struct file *file) |
1783 | { | 1782 | { |
1784 | return single_open(file, ab8500_gpadc_btemp_ball_print, inode->i_private); | 1783 | return single_open(file, ab8500_gpadc_btemp_ball_print, |
1784 | inode->i_private); | ||
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | static const struct file_operations ab8500_gpadc_btemp_ball_fops = { | 1787 | static const struct file_operations ab8500_gpadc_btemp_ball_fops = { |
@@ -1962,7 +1962,8 @@ static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p) | |||
1962 | static int ab8500_gpadc_main_bat_v_open(struct inode *inode, | 1962 | static int ab8500_gpadc_main_bat_v_open(struct inode *inode, |
1963 | struct file *file) | 1963 | struct file *file) |
1964 | { | 1964 | { |
1965 | return single_open(file, ab8500_gpadc_main_bat_v_print, inode->i_private); | 1965 | return single_open(file, ab8500_gpadc_main_bat_v_print, |
1966 | inode->i_private); | ||
1966 | } | 1967 | } |
1967 | 1968 | ||
1968 | static const struct file_operations ab8500_gpadc_main_bat_v_fops = { | 1969 | static const struct file_operations ab8500_gpadc_main_bat_v_fops = { |
@@ -2082,7 +2083,8 @@ static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p) | |||
2082 | 2083 | ||
2083 | static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file) | 2084 | static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file) |
2084 | { | 2085 | { |
2085 | return single_open(file, ab8500_gpadc_bk_bat_v_print, inode->i_private); | 2086 | return single_open(file, ab8500_gpadc_bk_bat_v_print, |
2087 | inode->i_private); | ||
2086 | } | 2088 | } |
2087 | 2089 | ||
2088 | static const struct file_operations ab8500_gpadc_bk_bat_v_fops = { | 2090 | static const struct file_operations ab8500_gpadc_bk_bat_v_fops = { |
@@ -2111,7 +2113,8 @@ static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p) | |||
2111 | 2113 | ||
2112 | static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file) | 2114 | static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file) |
2113 | { | 2115 | { |
2114 | return single_open(file, ab8500_gpadc_die_temp_print, inode->i_private); | 2116 | return single_open(file, ab8500_gpadc_die_temp_print, |
2117 | inode->i_private); | ||
2115 | } | 2118 | } |
2116 | 2119 | ||
2117 | static const struct file_operations ab8500_gpadc_die_temp_fops = { | 2120 | static const struct file_operations ab8500_gpadc_die_temp_fops = { |
@@ -2190,8 +2193,9 @@ static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p) | |||
2190 | gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); | 2193 | gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); |
2191 | vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS, | 2194 | vbat_true_meas_raw = ab8500_gpadc_read_raw(gpadc, VBAT_TRUE_MEAS, |
2192 | avg_sample, trig_edge, trig_timer, conv_type); | 2195 | avg_sample, trig_edge, trig_timer, conv_type); |
2193 | vbat_true_meas_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS, | 2196 | vbat_true_meas_convert = |
2194 | vbat_true_meas_raw); | 2197 | ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS, |
2198 | vbat_true_meas_raw); | ||
2195 | 2199 | ||
2196 | return seq_printf(s, "%d,0x%X\n", | 2200 | return seq_printf(s, "%d,0x%X\n", |
2197 | vbat_true_meas_convert, vbat_true_meas_raw); | 2201 | vbat_true_meas_convert, vbat_true_meas_raw); |
@@ -2285,7 +2289,8 @@ static const struct file_operations ab8540_gpadc_vbat_meas_and_ibat_fops = { | |||
2285 | .owner = THIS_MODULE, | 2289 | .owner = THIS_MODULE, |
2286 | }; | 2290 | }; |
2287 | 2291 | ||
2288 | static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, void *p) | 2292 | static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s, |
2293 | void *p) | ||
2289 | { | 2294 | { |
2290 | int vbat_true_meas_raw; | 2295 | int vbat_true_meas_raw; |
2291 | int vbat_true_meas_convert; | 2296 | int vbat_true_meas_convert; |
@@ -2314,7 +2319,8 @@ static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode, | |||
2314 | inode->i_private); | 2319 | inode->i_private); |
2315 | } | 2320 | } |
2316 | 2321 | ||
2317 | static const struct file_operations ab8540_gpadc_vbat_true_meas_and_ibat_fops = { | 2322 | static const struct file_operations |
2323 | ab8540_gpadc_vbat_true_meas_and_ibat_fops = { | ||
2318 | .open = ab8540_gpadc_vbat_true_meas_and_ibat_open, | 2324 | .open = ab8540_gpadc_vbat_true_meas_and_ibat_open, |
2319 | .read = seq_read, | 2325 | .read = seq_read, |
2320 | .llseek = seq_lseek, | 2326 | .llseek = seq_lseek, |
@@ -2368,14 +2374,15 @@ static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p) | |||
2368 | ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h, | 2374 | ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h, |
2369 | &vbat_l, &vbat_h, &ibat_l, &ibat_h); | 2375 | &vbat_l, &vbat_h, &ibat_l, &ibat_h); |
2370 | return seq_printf(s, "VMAIN_L:0x%X\n" | 2376 | return seq_printf(s, "VMAIN_L:0x%X\n" |
2371 | "VMAIN_H:0x%X\n" | 2377 | "VMAIN_H:0x%X\n" |
2372 | "BTEMP_L:0x%X\n" | 2378 | "BTEMP_L:0x%X\n" |
2373 | "BTEMP_H:0x%X\n" | 2379 | "BTEMP_H:0x%X\n" |
2374 | "VBAT_L:0x%X\n" | 2380 | "VBAT_L:0x%X\n" |
2375 | "VBAT_H:0x%X\n" | 2381 | "VBAT_H:0x%X\n" |
2376 | "IBAT_L:0x%X\n" | 2382 | "IBAT_L:0x%X\n" |
2377 | "IBAT_H:0x%X\n", | 2383 | "IBAT_H:0x%X\n", |
2378 | vmain_l, vmain_h, btemp_l, btemp_h, vbat_l, vbat_h, ibat_l, ibat_h); | 2384 | vmain_l, vmain_h, btemp_l, btemp_h, |
2385 | vbat_l, vbat_h, ibat_l, ibat_h); | ||
2379 | } | 2386 | } |
2380 | 2387 | ||
2381 | static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file) | 2388 | static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file) |
@@ -2419,8 +2426,8 @@ static ssize_t ab8500_gpadc_avg_sample_write(struct file *file, | |||
2419 | || (user_avg_sample == SAMPLE_16)) { | 2426 | || (user_avg_sample == SAMPLE_16)) { |
2420 | avg_sample = (u8) user_avg_sample; | 2427 | avg_sample = (u8) user_avg_sample; |
2421 | } else { | 2428 | } else { |
2422 | dev_err(dev, "debugfs error input: " | 2429 | dev_err(dev, |
2423 | "should be egal to 1, 4, 8 or 16\n"); | 2430 | "debugfs err input: should be egal to 1, 4, 8 or 16\n"); |
2424 | return -EINVAL; | 2431 | return -EINVAL; |
2425 | } | 2432 | } |
2426 | 2433 | ||
@@ -2504,14 +2511,14 @@ static ssize_t ab8500_gpadc_trig_timer_write(struct file *file, | |||
2504 | if (err) | 2511 | if (err) |
2505 | return err; | 2512 | return err; |
2506 | 2513 | ||
2507 | if ((user_trig_timer >= 0) && (user_trig_timer <= 255)) { | 2514 | if (user_trig_timer & ~0xFF) { |
2508 | trig_timer = (u8) user_trig_timer; | 2515 | dev_err(dev, |
2509 | } else { | 2516 | "debugfs error input: should be beetween 0 to 255\n"); |
2510 | dev_err(dev, "debugfs error input: " | ||
2511 | "should be beetween 0 to 255\n"); | ||
2512 | return -EINVAL; | 2517 | return -EINVAL; |
2513 | } | 2518 | } |
2514 | 2519 | ||
2520 | trig_timer = (u8) user_trig_timer; | ||
2521 | |||
2515 | return count; | 2522 | return count; |
2516 | } | 2523 | } |
2517 | 2524 | ||
@@ -2579,6 +2586,7 @@ static const struct file_operations ab8500_gpadc_conv_type_fops = { | |||
2579 | static int strval_len(char *b) | 2586 | static int strval_len(char *b) |
2580 | { | 2587 | { |
2581 | char *s = b; | 2588 | char *s = b; |
2589 | |||
2582 | if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) { | 2590 | if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) { |
2583 | s += 2; | 2591 | s += 2; |
2584 | for (; *s && (*s != ' ') && (*s != '\n'); s++) { | 2592 | for (; *s && (*s != ' ') && (*s != '\n'); s++) { |
@@ -2643,13 +2651,17 @@ static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg, | |||
2643 | b += (*(b+2) == ' ') ? 3 : 6; | 2651 | b += (*(b+2) == ' ') ? 3 : 6; |
2644 | if (strval_len(b) == 0) | 2652 | if (strval_len(b) == 0) |
2645 | return -EINVAL; | 2653 | return -EINVAL; |
2646 | loc.mask = simple_strtoul(b, &b, 0); | 2654 | ret = kstrtoul(b, 0, &loc.mask); |
2655 | if (ret) | ||
2656 | return ret; | ||
2647 | } else if ((!strncmp(b, "-s ", 3)) || | 2657 | } else if ((!strncmp(b, "-s ", 3)) || |
2648 | (!strncmp(b, "-shift ", 7))) { | 2658 | (!strncmp(b, "-shift ", 7))) { |
2649 | b += (*(b+2) == ' ') ? 3 : 7; | 2659 | b += (*(b+2) == ' ') ? 3 : 7; |
2650 | if (strval_len(b) == 0) | 2660 | if (strval_len(b) == 0) |
2651 | return -EINVAL; | 2661 | return -EINVAL; |
2652 | loc.shift = simple_strtol(b, &b, 0); | 2662 | ret = kstrtol(b, 0, &loc.shift); |
2663 | if (ret) | ||
2664 | return ret; | ||
2653 | } else { | 2665 | } else { |
2654 | return -EINVAL; | 2666 | return -EINVAL; |
2655 | } | 2667 | } |
@@ -2657,29 +2669,36 @@ static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg, | |||
2657 | /* get arg BANK and ADDRESS */ | 2669 | /* get arg BANK and ADDRESS */ |
2658 | if (strval_len(b) == 0) | 2670 | if (strval_len(b) == 0) |
2659 | return -EINVAL; | 2671 | return -EINVAL; |
2660 | loc.bank = simple_strtoul(b, &b, 0); | 2672 | ret = kstrtouint(b, 0, &loc.bank); |
2673 | if (ret) | ||
2674 | return ret; | ||
2661 | while (*b == ' ') | 2675 | while (*b == ' ') |
2662 | b++; | 2676 | b++; |
2663 | if (strval_len(b) == 0) | 2677 | if (strval_len(b) == 0) |
2664 | return -EINVAL; | 2678 | return -EINVAL; |
2665 | loc.addr = simple_strtoul(b, &b, 0); | 2679 | ret = kstrtoul(b, 0, &loc.addr); |
2680 | if (ret) | ||
2681 | return ret; | ||
2666 | 2682 | ||
2667 | if (write) { | 2683 | if (write) { |
2668 | while (*b == ' ') | 2684 | while (*b == ' ') |
2669 | b++; | 2685 | b++; |
2670 | if (strval_len(b) == 0) | 2686 | if (strval_len(b) == 0) |
2671 | return -EINVAL; | 2687 | return -EINVAL; |
2672 | val = simple_strtoul(b, &b, 0); | 2688 | ret = kstrtouint(b, 0, &val); |
2689 | if (ret) | ||
2690 | return ret; | ||
2673 | } | 2691 | } |
2674 | 2692 | ||
2675 | /* args are ok, update target cfg (mainly for read) */ | 2693 | /* args are ok, update target cfg (mainly for read) */ |
2676 | *cfg = loc; | 2694 | *cfg = loc; |
2677 | 2695 | ||
2678 | #ifdef ABB_HWREG_DEBUG | 2696 | #ifdef ABB_HWREG_DEBUG |
2679 | pr_warn("HWREG request: %s, %s, addr=0x%08X, mask=0x%X, shift=%d" | 2697 | pr_warn("HWREG request: %s, %s,\n" |
2680 | "value=0x%X\n", (write) ? "write" : "read", | 2698 | " addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n", |
2681 | REG_FMT_DEC(cfg) ? "decimal" : "hexa", | 2699 | (write) ? "write" : "read", |
2682 | cfg->addr, cfg->mask, cfg->shift, val); | 2700 | REG_FMT_DEC(cfg) ? "decimal" : "hexa", |
2701 | cfg->addr, cfg->mask, cfg->shift, val); | ||
2683 | #endif | 2702 | #endif |
2684 | 2703 | ||
2685 | if (!write) | 2704 | if (!write) |
@@ -2765,8 +2784,8 @@ static ssize_t show_irq(struct device *dev, | |||
2765 | irq_index = name - irq_first; | 2784 | irq_index = name - irq_first; |
2766 | if (irq_index >= num_irqs) | 2785 | if (irq_index >= num_irqs) |
2767 | return -EINVAL; | 2786 | return -EINVAL; |
2768 | else | 2787 | |
2769 | return sprintf(buf, "%u\n", irq_count[irq_index]); | 2788 | return sprintf(buf, "%u\n", irq_count[irq_index]); |
2770 | } | 2789 | } |
2771 | 2790 | ||
2772 | static ssize_t ab8500_subscribe_write(struct file *file, | 2791 | static ssize_t ab8500_subscribe_write(struct file *file, |
@@ -2815,7 +2834,7 @@ static ssize_t ab8500_subscribe_write(struct file *file, | |||
2815 | dev_attr[irq_index]->attr.mode = S_IRUGO; | 2834 | dev_attr[irq_index]->attr.mode = S_IRUGO; |
2816 | err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr); | 2835 | err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr); |
2817 | if (err < 0) { | 2836 | if (err < 0) { |
2818 | printk(KERN_ERR "sysfs_create_file failed %d\n", err); | 2837 | pr_info("sysfs_create_file failed %d\n", err); |
2819 | return err; | 2838 | return err; |
2820 | } | 2839 | } |
2821 | 2840 | ||
@@ -2823,8 +2842,8 @@ static ssize_t ab8500_subscribe_write(struct file *file, | |||
2823 | IRQF_SHARED | IRQF_NO_SUSPEND, | 2842 | IRQF_SHARED | IRQF_NO_SUSPEND, |
2824 | "ab8500-debug", &dev->kobj); | 2843 | "ab8500-debug", &dev->kobj); |
2825 | if (err < 0) { | 2844 | if (err < 0) { |
2826 | printk(KERN_ERR "request_threaded_irq failed %d, %lu\n", | 2845 | pr_info("request_threaded_irq failed %d, %lu\n", |
2827 | err, user_val); | 2846 | err, user_val); |
2828 | sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr); | 2847 | sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr); |
2829 | return err; | 2848 | return err; |
2830 | } | 2849 | } |
@@ -2946,6 +2965,7 @@ static int ab8500_debug_probe(struct platform_device *plf) | |||
2946 | struct dentry *file; | 2965 | struct dentry *file; |
2947 | struct ab8500 *ab8500; | 2966 | struct ab8500 *ab8500; |
2948 | struct resource *res; | 2967 | struct resource *res; |
2968 | |||
2949 | debug_bank = AB8500_MISC; | 2969 | debug_bank = AB8500_MISC; |
2950 | debug_address = AB8500_REV_REG & 0x00FF; | 2970 | debug_address = AB8500_REV_REG & 0x00FF; |
2951 | 2971 | ||
@@ -2958,7 +2978,7 @@ static int ab8500_debug_probe(struct platform_device *plf) | |||
2958 | return -ENOMEM; | 2978 | return -ENOMEM; |
2959 | 2979 | ||
2960 | dev_attr = devm_kzalloc(&plf->dev, | 2980 | dev_attr = devm_kzalloc(&plf->dev, |
2961 | sizeof(*dev_attr)*num_irqs,GFP_KERNEL); | 2981 | sizeof(*dev_attr)*num_irqs, GFP_KERNEL); |
2962 | if (!dev_attr) | 2982 | if (!dev_attr) |
2963 | return -ENOMEM; | 2983 | return -ENOMEM; |
2964 | 2984 | ||
@@ -2969,23 +2989,20 @@ static int ab8500_debug_probe(struct platform_device *plf) | |||
2969 | 2989 | ||
2970 | res = platform_get_resource_byname(plf, 0, "IRQ_AB8500"); | 2990 | res = platform_get_resource_byname(plf, 0, "IRQ_AB8500"); |
2971 | if (!res) { | 2991 | if (!res) { |
2972 | dev_err(&plf->dev, "AB8500 irq not found, err %d\n", | 2992 | dev_err(&plf->dev, "AB8500 irq not found, err %d\n", irq_first); |
2973 | irq_first); | 2993 | return -ENXIO; |
2974 | return ENXIO; | ||
2975 | } | 2994 | } |
2976 | irq_ab8500 = res->start; | 2995 | irq_ab8500 = res->start; |
2977 | 2996 | ||
2978 | irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); | 2997 | irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); |
2979 | if (irq_first < 0) { | 2998 | if (irq_first < 0) { |
2980 | dev_err(&plf->dev, "First irq not found, err %d\n", | 2999 | dev_err(&plf->dev, "First irq not found, err %d\n", irq_first); |
2981 | irq_first); | ||
2982 | return irq_first; | 3000 | return irq_first; |
2983 | } | 3001 | } |
2984 | 3002 | ||
2985 | irq_last = platform_get_irq_byname(plf, "IRQ_LAST"); | 3003 | irq_last = platform_get_irq_byname(plf, "IRQ_LAST"); |
2986 | if (irq_last < 0) { | 3004 | if (irq_last < 0) { |
2987 | dev_err(&plf->dev, "Last irq not found, err %d\n", | 3005 | dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last); |
2988 | irq_last); | ||
2989 | return irq_last; | 3006 | return irq_last; |
2990 | } | 3007 | } |
2991 | 3008 | ||
@@ -2994,37 +3011,41 @@ static int ab8500_debug_probe(struct platform_device *plf) | |||
2994 | goto err; | 3011 | goto err; |
2995 | 3012 | ||
2996 | ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING, | 3013 | ab8500_gpadc_dir = debugfs_create_dir(AB8500_ADC_NAME_STRING, |
2997 | ab8500_dir); | 3014 | ab8500_dir); |
2998 | if (!ab8500_gpadc_dir) | 3015 | if (!ab8500_gpadc_dir) |
2999 | goto err; | 3016 | goto err; |
3000 | 3017 | ||
3001 | file = debugfs_create_file("all-bank-registers", S_IRUGO, | 3018 | file = debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir, |
3002 | ab8500_dir, &plf->dev, &ab8500_registers_fops); | 3019 | &plf->dev, &ab8500_registers_fops); |
3003 | if (!file) | 3020 | if (!file) |
3004 | goto err; | 3021 | goto err; |
3005 | 3022 | ||
3006 | file = debugfs_create_file("all-banks", S_IRUGO, | 3023 | file = debugfs_create_file("all-banks", S_IRUGO, ab8500_dir, |
3007 | ab8500_dir, &plf->dev, &ab8500_all_banks_fops); | 3024 | &plf->dev, &ab8500_all_banks_fops); |
3008 | if (!file) | 3025 | if (!file) |
3009 | goto err; | 3026 | goto err; |
3010 | 3027 | ||
3011 | file = debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP), | 3028 | file = debugfs_create_file("register-bank", |
3012 | ab8500_dir, &plf->dev, &ab8500_bank_fops); | 3029 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3030 | ab8500_dir, &plf->dev, &ab8500_bank_fops); | ||
3013 | if (!file) | 3031 | if (!file) |
3014 | goto err; | 3032 | goto err; |
3015 | 3033 | ||
3016 | file = debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP), | 3034 | file = debugfs_create_file("register-address", |
3017 | ab8500_dir, &plf->dev, &ab8500_address_fops); | 3035 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3036 | ab8500_dir, &plf->dev, &ab8500_address_fops); | ||
3018 | if (!file) | 3037 | if (!file) |
3019 | goto err; | 3038 | goto err; |
3020 | 3039 | ||
3021 | file = debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP), | 3040 | file = debugfs_create_file("register-value", |
3022 | ab8500_dir, &plf->dev, &ab8500_val_fops); | 3041 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3042 | ab8500_dir, &plf->dev, &ab8500_val_fops); | ||
3023 | if (!file) | 3043 | if (!file) |
3024 | goto err; | 3044 | goto err; |
3025 | 3045 | ||
3026 | file = debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP), | 3046 | file = debugfs_create_file("irq-subscribe", |
3027 | ab8500_dir, &plf->dev, &ab8500_subscribe_fops); | 3047 | (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, |
3048 | &plf->dev, &ab8500_subscribe_fops); | ||
3028 | if (!file) | 3049 | if (!file) |
3029 | goto err; | 3050 | goto err; |
3030 | 3051 | ||
@@ -3042,158 +3063,191 @@ static int ab8500_debug_probe(struct platform_device *plf) | |||
3042 | num_interrupt_lines = AB8540_NR_IRQS; | 3063 | num_interrupt_lines = AB8540_NR_IRQS; |
3043 | } | 3064 | } |
3044 | 3065 | ||
3045 | file = debugfs_create_file("interrupts", (S_IRUGO), | 3066 | file = debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, |
3046 | ab8500_dir, &plf->dev, &ab8500_interrupts_fops); | 3067 | &plf->dev, &ab8500_interrupts_fops); |
3047 | if (!file) | 3068 | if (!file) |
3048 | goto err; | 3069 | goto err; |
3049 | 3070 | ||
3050 | file = debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP), | 3071 | file = debugfs_create_file("irq-unsubscribe", |
3051 | ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops); | 3072 | (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, |
3073 | &plf->dev, &ab8500_unsubscribe_fops); | ||
3052 | if (!file) | 3074 | if (!file) |
3053 | goto err; | 3075 | goto err; |
3054 | 3076 | ||
3055 | file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), | 3077 | file = debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), |
3056 | ab8500_dir, &plf->dev, &ab8500_hwreg_fops); | 3078 | ab8500_dir, &plf->dev, &ab8500_hwreg_fops); |
3057 | if (!file) | 3079 | if (!file) |
3058 | goto err; | 3080 | goto err; |
3059 | 3081 | ||
3060 | file = debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP), | 3082 | file = debugfs_create_file("all-modem-registers", |
3061 | ab8500_dir, &plf->dev, &ab8500_modem_fops); | 3083 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3084 | ab8500_dir, &plf->dev, &ab8500_modem_fops); | ||
3062 | if (!file) | 3085 | if (!file) |
3063 | goto err; | 3086 | goto err; |
3064 | 3087 | ||
3065 | file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP), | 3088 | file = debugfs_create_file("bat_ctrl", (S_IRUGO | S_IWUSR | S_IWGRP), |
3066 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bat_ctrl_fops); | 3089 | ab8500_gpadc_dir, &plf->dev, |
3090 | &ab8500_gpadc_bat_ctrl_fops); | ||
3067 | if (!file) | 3091 | if (!file) |
3068 | goto err; | 3092 | goto err; |
3069 | 3093 | ||
3070 | file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP), | 3094 | file = debugfs_create_file("btemp_ball", (S_IRUGO | S_IWUSR | S_IWGRP), |
3071 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_btemp_ball_fops); | 3095 | ab8500_gpadc_dir, |
3096 | &plf->dev, &ab8500_gpadc_btemp_ball_fops); | ||
3072 | if (!file) | 3097 | if (!file) |
3073 | goto err; | 3098 | goto err; |
3074 | 3099 | ||
3075 | file = debugfs_create_file("main_charger_v", (S_IRUGO | S_IWUSR | S_IWGRP), | 3100 | file = debugfs_create_file("main_charger_v", |
3076 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_v_fops); | 3101 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3102 | ab8500_gpadc_dir, &plf->dev, | ||
3103 | &ab8500_gpadc_main_charger_v_fops); | ||
3077 | if (!file) | 3104 | if (!file) |
3078 | goto err; | 3105 | goto err; |
3079 | 3106 | ||
3080 | file = debugfs_create_file("acc_detect1", (S_IRUGO | S_IWUSR | S_IWGRP), | 3107 | file = debugfs_create_file("acc_detect1", |
3081 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect1_fops); | 3108 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3109 | ab8500_gpadc_dir, &plf->dev, | ||
3110 | &ab8500_gpadc_acc_detect1_fops); | ||
3082 | if (!file) | 3111 | if (!file) |
3083 | goto err; | 3112 | goto err; |
3084 | 3113 | ||
3085 | file = debugfs_create_file("acc_detect2", (S_IRUGO | S_IWUSR | S_IWGRP), | 3114 | file = debugfs_create_file("acc_detect2", |
3086 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_acc_detect2_fops); | 3115 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3116 | ab8500_gpadc_dir, &plf->dev, | ||
3117 | &ab8500_gpadc_acc_detect2_fops); | ||
3087 | if (!file) | 3118 | if (!file) |
3088 | goto err; | 3119 | goto err; |
3089 | 3120 | ||
3090 | file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP), | 3121 | file = debugfs_create_file("adc_aux1", (S_IRUGO | S_IWUSR | S_IWGRP), |
3091 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux1_fops); | 3122 | ab8500_gpadc_dir, &plf->dev, |
3123 | &ab8500_gpadc_aux1_fops); | ||
3092 | if (!file) | 3124 | if (!file) |
3093 | goto err; | 3125 | goto err; |
3094 | 3126 | ||
3095 | file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP), | 3127 | file = debugfs_create_file("adc_aux2", (S_IRUGO | S_IWUSR | S_IWGRP), |
3096 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_aux2_fops); | 3128 | ab8500_gpadc_dir, &plf->dev, |
3129 | &ab8500_gpadc_aux2_fops); | ||
3097 | if (!file) | 3130 | if (!file) |
3098 | goto err; | 3131 | goto err; |
3099 | 3132 | ||
3100 | file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), | 3133 | file = debugfs_create_file("main_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), |
3101 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_bat_v_fops); | 3134 | ab8500_gpadc_dir, &plf->dev, |
3135 | &ab8500_gpadc_main_bat_v_fops); | ||
3102 | if (!file) | 3136 | if (!file) |
3103 | goto err; | 3137 | goto err; |
3104 | 3138 | ||
3105 | file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP), | 3139 | file = debugfs_create_file("vbus_v", (S_IRUGO | S_IWUSR | S_IWGRP), |
3106 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_vbus_v_fops); | 3140 | ab8500_gpadc_dir, &plf->dev, |
3141 | &ab8500_gpadc_vbus_v_fops); | ||
3107 | if (!file) | 3142 | if (!file) |
3108 | goto err; | 3143 | goto err; |
3109 | 3144 | ||
3110 | file = debugfs_create_file("main_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP), | 3145 | file = debugfs_create_file("main_charger_c", |
3111 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_main_charger_c_fops); | 3146 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3147 | ab8500_gpadc_dir, &plf->dev, | ||
3148 | &ab8500_gpadc_main_charger_c_fops); | ||
3112 | if (!file) | 3149 | if (!file) |
3113 | goto err; | 3150 | goto err; |
3114 | 3151 | ||
3115 | file = debugfs_create_file("usb_charger_c", (S_IRUGO | S_IWUSR | S_IWGRP), | 3152 | file = debugfs_create_file("usb_charger_c", |
3116 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_charger_c_fops); | 3153 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3154 | ab8500_gpadc_dir, | ||
3155 | &plf->dev, &ab8500_gpadc_usb_charger_c_fops); | ||
3117 | if (!file) | 3156 | if (!file) |
3118 | goto err; | 3157 | goto err; |
3119 | 3158 | ||
3120 | file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), | 3159 | file = debugfs_create_file("bk_bat_v", (S_IRUGO | S_IWUSR | S_IWGRP), |
3121 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_bk_bat_v_fops); | 3160 | ab8500_gpadc_dir, &plf->dev, |
3161 | &ab8500_gpadc_bk_bat_v_fops); | ||
3122 | if (!file) | 3162 | if (!file) |
3123 | goto err; | 3163 | goto err; |
3124 | 3164 | ||
3125 | file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP), | 3165 | file = debugfs_create_file("die_temp", (S_IRUGO | S_IWUSR | S_IWGRP), |
3126 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_die_temp_fops); | 3166 | ab8500_gpadc_dir, &plf->dev, |
3167 | &ab8500_gpadc_die_temp_fops); | ||
3127 | if (!file) | 3168 | if (!file) |
3128 | goto err; | 3169 | goto err; |
3129 | 3170 | ||
3130 | file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP), | 3171 | file = debugfs_create_file("usb_id", (S_IRUGO | S_IWUSR | S_IWGRP), |
3131 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_usb_id_fops); | 3172 | ab8500_gpadc_dir, &plf->dev, |
3173 | &ab8500_gpadc_usb_id_fops); | ||
3132 | if (!file) | 3174 | if (!file) |
3133 | goto err; | 3175 | goto err; |
3134 | 3176 | ||
3135 | if (is_ab8540(ab8500)) { | 3177 | if (is_ab8540(ab8500)) { |
3136 | file = debugfs_create_file("xtal_temp", (S_IRUGO | S_IWUSR | S_IWGRP), | 3178 | file = debugfs_create_file("xtal_temp", |
3137 | ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_xtal_temp_fops); | 3179 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3180 | ab8500_gpadc_dir, &plf->dev, | ||
3181 | &ab8540_gpadc_xtal_temp_fops); | ||
3138 | if (!file) | 3182 | if (!file) |
3139 | goto err; | 3183 | goto err; |
3140 | file = debugfs_create_file("vbattruemeas", (S_IRUGO | S_IWUSR | S_IWGRP), | 3184 | file = debugfs_create_file("vbattruemeas", |
3141 | ab8500_gpadc_dir, &plf->dev, | 3185 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3142 | &ab8540_gpadc_vbat_true_meas_fops); | 3186 | ab8500_gpadc_dir, &plf->dev, |
3187 | &ab8540_gpadc_vbat_true_meas_fops); | ||
3143 | if (!file) | 3188 | if (!file) |
3144 | goto err; | 3189 | goto err; |
3145 | file = debugfs_create_file("batctrl_and_ibat", | 3190 | file = debugfs_create_file("batctrl_and_ibat", |
3146 | (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, | 3191 | (S_IRUGO | S_IWUGO), |
3147 | &plf->dev, &ab8540_gpadc_bat_ctrl_and_ibat_fops); | 3192 | ab8500_gpadc_dir, |
3193 | &plf->dev, | ||
3194 | &ab8540_gpadc_bat_ctrl_and_ibat_fops); | ||
3148 | if (!file) | 3195 | if (!file) |
3149 | goto err; | 3196 | goto err; |
3150 | file = debugfs_create_file("vbatmeas_and_ibat", | 3197 | file = debugfs_create_file("vbatmeas_and_ibat", |
3151 | (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, | 3198 | (S_IRUGO | S_IWUGO), |
3152 | &plf->dev, | 3199 | ab8500_gpadc_dir, &plf->dev, |
3153 | &ab8540_gpadc_vbat_meas_and_ibat_fops); | 3200 | &ab8540_gpadc_vbat_meas_and_ibat_fops); |
3154 | if (!file) | 3201 | if (!file) |
3155 | goto err; | 3202 | goto err; |
3156 | file = debugfs_create_file("vbattruemeas_and_ibat", | 3203 | file = debugfs_create_file("vbattruemeas_and_ibat", |
3157 | (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, | 3204 | (S_IRUGO | S_IWUGO), |
3158 | &plf->dev, | 3205 | ab8500_gpadc_dir, |
3159 | &ab8540_gpadc_vbat_true_meas_and_ibat_fops); | 3206 | &plf->dev, |
3207 | &ab8540_gpadc_vbat_true_meas_and_ibat_fops); | ||
3160 | if (!file) | 3208 | if (!file) |
3161 | goto err; | 3209 | goto err; |
3162 | file = debugfs_create_file("battemp_and_ibat", | 3210 | file = debugfs_create_file("battemp_and_ibat", |
3163 | (S_IRUGO | S_IWUGO), ab8500_gpadc_dir, | 3211 | (S_IRUGO | S_IWUGO), |
3212 | ab8500_gpadc_dir, | ||
3164 | &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); | 3213 | &plf->dev, &ab8540_gpadc_bat_temp_and_ibat_fops); |
3165 | if (!file) | 3214 | if (!file) |
3166 | goto err; | 3215 | goto err; |
3167 | file = debugfs_create_file("otp_calib", (S_IRUGO | S_IWUSR | S_IWGRP), | 3216 | file = debugfs_create_file("otp_calib", |
3168 | ab8500_gpadc_dir, &plf->dev, &ab8540_gpadc_otp_calib_fops); | 3217 | (S_IRUGO | S_IWUSR | S_IWGRP), |
3218 | ab8500_gpadc_dir, | ||
3219 | &plf->dev, &ab8540_gpadc_otp_calib_fops); | ||
3169 | if (!file) | 3220 | if (!file) |
3170 | goto err; | 3221 | goto err; |
3171 | } | 3222 | } |
3172 | file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP), | 3223 | file = debugfs_create_file("avg_sample", (S_IRUGO | S_IWUSR | S_IWGRP), |
3173 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_avg_sample_fops); | 3224 | ab8500_gpadc_dir, &plf->dev, |
3225 | &ab8500_gpadc_avg_sample_fops); | ||
3174 | if (!file) | 3226 | if (!file) |
3175 | goto err; | 3227 | goto err; |
3176 | 3228 | ||
3177 | file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP), | 3229 | file = debugfs_create_file("trig_edge", (S_IRUGO | S_IWUSR | S_IWGRP), |
3178 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_edge_fops); | 3230 | ab8500_gpadc_dir, &plf->dev, |
3231 | &ab8500_gpadc_trig_edge_fops); | ||
3179 | if (!file) | 3232 | if (!file) |
3180 | goto err; | 3233 | goto err; |
3181 | 3234 | ||
3182 | file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP), | 3235 | file = debugfs_create_file("trig_timer", (S_IRUGO | S_IWUSR | S_IWGRP), |
3183 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_trig_timer_fops); | 3236 | ab8500_gpadc_dir, &plf->dev, |
3237 | &ab8500_gpadc_trig_timer_fops); | ||
3184 | if (!file) | 3238 | if (!file) |
3185 | goto err; | 3239 | goto err; |
3186 | 3240 | ||
3187 | file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP), | 3241 | file = debugfs_create_file("conv_type", (S_IRUGO | S_IWUSR | S_IWGRP), |
3188 | ab8500_gpadc_dir, &plf->dev, &ab8500_gpadc_conv_type_fops); | 3242 | ab8500_gpadc_dir, &plf->dev, |
3243 | &ab8500_gpadc_conv_type_fops); | ||
3189 | if (!file) | 3244 | if (!file) |
3190 | goto err; | 3245 | goto err; |
3191 | 3246 | ||
3192 | return 0; | 3247 | return 0; |
3193 | 3248 | ||
3194 | err: | 3249 | err: |
3195 | if (ab8500_dir) | 3250 | debugfs_remove_recursive(ab8500_dir); |
3196 | debugfs_remove_recursive(ab8500_dir); | ||
3197 | dev_err(&plf->dev, "failed to create debugfs entries.\n"); | 3251 | dev_err(&plf->dev, "failed to create debugfs entries.\n"); |
3198 | 3252 | ||
3199 | return -ENOMEM; | 3253 | return -ENOMEM; |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index cfc191abae4a..10a0cb90619a 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -123,6 +123,8 @@ static irqreturn_t arizona_underclocked(int irq, void *data) | |||
123 | dev_err(arizona->dev, "AIF2 underclocked\n"); | 123 | dev_err(arizona->dev, "AIF2 underclocked\n"); |
124 | if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) | 124 | if (val & ARIZONA_AIF1_UNDERCLOCKED_STS) |
125 | dev_err(arizona->dev, "AIF1 underclocked\n"); | 125 | dev_err(arizona->dev, "AIF1 underclocked\n"); |
126 | if (val & ARIZONA_ISRC3_UNDERCLOCKED_STS) | ||
127 | dev_err(arizona->dev, "ISRC3 underclocked\n"); | ||
126 | if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) | 128 | if (val & ARIZONA_ISRC2_UNDERCLOCKED_STS) |
127 | dev_err(arizona->dev, "ISRC2 underclocked\n"); | 129 | dev_err(arizona->dev, "ISRC2 underclocked\n"); |
128 | if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS) | 130 | if (val & ARIZONA_ISRC1_UNDERCLOCKED_STS) |
@@ -192,6 +194,8 @@ static irqreturn_t arizona_overclocked(int irq, void *data) | |||
192 | dev_err(arizona->dev, "ASRC sync WARP overclocked\n"); | 194 | dev_err(arizona->dev, "ASRC sync WARP overclocked\n"); |
193 | if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS) | 195 | if (val[1] & ARIZONA_ADSP2_1_OVERCLOCKED_STS) |
194 | dev_err(arizona->dev, "DSP1 overclocked\n"); | 196 | dev_err(arizona->dev, "DSP1 overclocked\n"); |
197 | if (val[1] & ARIZONA_ISRC3_OVERCLOCKED_STS) | ||
198 | dev_err(arizona->dev, "ISRC3 overclocked\n"); | ||
195 | if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS) | 199 | if (val[1] & ARIZONA_ISRC2_OVERCLOCKED_STS) |
196 | dev_err(arizona->dev, "ISRC2 overclocked\n"); | 200 | dev_err(arizona->dev, "ISRC2 overclocked\n"); |
197 | if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS) | 201 | if (val[1] & ARIZONA_ISRC1_OVERCLOCKED_STS) |
@@ -497,12 +501,12 @@ const struct dev_pm_ops arizona_pm_ops = { | |||
497 | EXPORT_SYMBOL_GPL(arizona_pm_ops); | 501 | EXPORT_SYMBOL_GPL(arizona_pm_ops); |
498 | 502 | ||
499 | #ifdef CONFIG_OF | 503 | #ifdef CONFIG_OF |
500 | int arizona_of_get_type(struct device *dev) | 504 | unsigned long arizona_of_get_type(struct device *dev) |
501 | { | 505 | { |
502 | const struct of_device_id *id = of_match_device(arizona_of_match, dev); | 506 | const struct of_device_id *id = of_match_device(arizona_of_match, dev); |
503 | 507 | ||
504 | if (id) | 508 | if (id) |
505 | return (int)id->data; | 509 | return (unsigned long)id->data; |
506 | else | 510 | else |
507 | return 0; | 511 | return 0; |
508 | } | 512 | } |
@@ -578,17 +582,21 @@ static const struct mfd_cell early_devs[] = { | |||
578 | }; | 582 | }; |
579 | 583 | ||
580 | static const char *wm5102_supplies[] = { | 584 | static const char *wm5102_supplies[] = { |
585 | "MICVDD", | ||
581 | "DBVDD2", | 586 | "DBVDD2", |
582 | "DBVDD3", | 587 | "DBVDD3", |
583 | "CPVDD", | 588 | "CPVDD", |
584 | "SPKVDDL", | 589 | "SPKVDDL", |
585 | "SPKVDDR", | 590 | "SPKVDDR", |
586 | "MICVDD", | ||
587 | }; | 591 | }; |
588 | 592 | ||
589 | static const struct mfd_cell wm5102_devs[] = { | 593 | static const struct mfd_cell wm5102_devs[] = { |
590 | { .name = "arizona-micsupp" }, | 594 | { .name = "arizona-micsupp" }, |
591 | { .name = "arizona-extcon" }, | 595 | { |
596 | .name = "arizona-extcon", | ||
597 | .parent_supplies = wm5102_supplies, | ||
598 | .num_parent_supplies = 1, /* We only need MICVDD */ | ||
599 | }, | ||
592 | { .name = "arizona-gpio" }, | 600 | { .name = "arizona-gpio" }, |
593 | { .name = "arizona-haptics" }, | 601 | { .name = "arizona-haptics" }, |
594 | { .name = "arizona-pwm" }, | 602 | { .name = "arizona-pwm" }, |
@@ -601,7 +609,11 @@ static const struct mfd_cell wm5102_devs[] = { | |||
601 | 609 | ||
602 | static const struct mfd_cell wm5110_devs[] = { | 610 | static const struct mfd_cell wm5110_devs[] = { |
603 | { .name = "arizona-micsupp" }, | 611 | { .name = "arizona-micsupp" }, |
604 | { .name = "arizona-extcon" }, | 612 | { |
613 | .name = "arizona-extcon", | ||
614 | .parent_supplies = wm5102_supplies, | ||
615 | .num_parent_supplies = 1, /* We only need MICVDD */ | ||
616 | }, | ||
605 | { .name = "arizona-gpio" }, | 617 | { .name = "arizona-gpio" }, |
606 | { .name = "arizona-haptics" }, | 618 | { .name = "arizona-haptics" }, |
607 | { .name = "arizona-pwm" }, | 619 | { .name = "arizona-pwm" }, |
@@ -613,6 +625,7 @@ static const struct mfd_cell wm5110_devs[] = { | |||
613 | }; | 625 | }; |
614 | 626 | ||
615 | static const char *wm8997_supplies[] = { | 627 | static const char *wm8997_supplies[] = { |
628 | "MICVDD", | ||
616 | "DBVDD2", | 629 | "DBVDD2", |
617 | "CPVDD", | 630 | "CPVDD", |
618 | "SPKVDD", | 631 | "SPKVDD", |
@@ -620,7 +633,11 @@ static const char *wm8997_supplies[] = { | |||
620 | 633 | ||
621 | static const struct mfd_cell wm8997_devs[] = { | 634 | static const struct mfd_cell wm8997_devs[] = { |
622 | { .name = "arizona-micsupp" }, | 635 | { .name = "arizona-micsupp" }, |
623 | { .name = "arizona-extcon" }, | 636 | { |
637 | .name = "arizona-extcon", | ||
638 | .parent_supplies = wm8997_supplies, | ||
639 | .num_parent_supplies = 1, /* We only need MICVDD */ | ||
640 | }, | ||
624 | { .name = "arizona-gpio" }, | 641 | { .name = "arizona-gpio" }, |
625 | { .name = "arizona-haptics" }, | 642 | { .name = "arizona-haptics" }, |
626 | { .name = "arizona-pwm" }, | 643 | { .name = "arizona-pwm" }, |
@@ -683,7 +700,13 @@ int arizona_dev_init(struct arizona *arizona) | |||
683 | goto err_early; | 700 | goto err_early; |
684 | } | 701 | } |
685 | 702 | ||
686 | arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD"); | 703 | /** |
704 | * Don't use devres here because the only device we have to get | ||
705 | * against is the MFD device and DCVDD will likely be supplied by | ||
706 | * one of its children. Meaning that the regulator will be | ||
707 | * destroyed by the time devres calls regulator put. | ||
708 | */ | ||
709 | arizona->dcvdd = regulator_get(arizona->dev, "DCVDD"); | ||
687 | if (IS_ERR(arizona->dcvdd)) { | 710 | if (IS_ERR(arizona->dcvdd)) { |
688 | ret = PTR_ERR(arizona->dcvdd); | 711 | ret = PTR_ERR(arizona->dcvdd); |
689 | dev_err(dev, "Failed to request DCVDD: %d\n", ret); | 712 | dev_err(dev, "Failed to request DCVDD: %d\n", ret); |
@@ -697,7 +720,7 @@ int arizona_dev_init(struct arizona *arizona) | |||
697 | "arizona /RESET"); | 720 | "arizona /RESET"); |
698 | if (ret != 0) { | 721 | if (ret != 0) { |
699 | dev_err(dev, "Failed to request /RESET: %d\n", ret); | 722 | dev_err(dev, "Failed to request /RESET: %d\n", ret); |
700 | goto err_early; | 723 | goto err_dcvdd; |
701 | } | 724 | } |
702 | } | 725 | } |
703 | 726 | ||
@@ -706,7 +729,7 @@ int arizona_dev_init(struct arizona *arizona) | |||
706 | if (ret != 0) { | 729 | if (ret != 0) { |
707 | dev_err(dev, "Failed to enable core supplies: %d\n", | 730 | dev_err(dev, "Failed to enable core supplies: %d\n", |
708 | ret); | 731 | ret); |
709 | goto err_early; | 732 | goto err_dcvdd; |
710 | } | 733 | } |
711 | 734 | ||
712 | ret = regulator_enable(arizona->dcvdd); | 735 | ret = regulator_enable(arizona->dcvdd); |
@@ -1015,6 +1038,8 @@ err_reset: | |||
1015 | err_enable: | 1038 | err_enable: |
1016 | regulator_bulk_disable(arizona->num_core_supplies, | 1039 | regulator_bulk_disable(arizona->num_core_supplies, |
1017 | arizona->core_supplies); | 1040 | arizona->core_supplies); |
1041 | err_dcvdd: | ||
1042 | regulator_put(arizona->dcvdd); | ||
1018 | err_early: | 1043 | err_early: |
1019 | mfd_remove_devices(dev); | 1044 | mfd_remove_devices(dev); |
1020 | return ret; | 1045 | return ret; |
@@ -1023,16 +1048,20 @@ EXPORT_SYMBOL_GPL(arizona_dev_init); | |||
1023 | 1048 | ||
1024 | int arizona_dev_exit(struct arizona *arizona) | 1049 | int arizona_dev_exit(struct arizona *arizona) |
1025 | { | 1050 | { |
1051 | pm_runtime_disable(arizona->dev); | ||
1052 | |||
1053 | regulator_disable(arizona->dcvdd); | ||
1054 | regulator_put(arizona->dcvdd); | ||
1055 | |||
1026 | mfd_remove_devices(arizona->dev); | 1056 | mfd_remove_devices(arizona->dev); |
1027 | arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona); | 1057 | arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona); |
1028 | arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona); | 1058 | arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona); |
1029 | arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona); | 1059 | arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona); |
1030 | pm_runtime_disable(arizona->dev); | ||
1031 | arizona_irq_exit(arizona); | 1060 | arizona_irq_exit(arizona); |
1032 | if (arizona->pdata.reset) | 1061 | if (arizona->pdata.reset) |
1033 | gpio_set_value_cansleep(arizona->pdata.reset, 0); | 1062 | gpio_set_value_cansleep(arizona->pdata.reset, 0); |
1034 | regulator_disable(arizona->dcvdd); | 1063 | |
1035 | regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies), | 1064 | regulator_bulk_disable(arizona->num_core_supplies, |
1036 | arizona->core_supplies); | 1065 | arizona->core_supplies); |
1037 | return 0; | 1066 | return 0; |
1038 | } | 1067 | } |
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c index beccb790c9ba..9d4156fb082a 100644 --- a/drivers/mfd/arizona-i2c.c +++ b/drivers/mfd/arizona-i2c.c | |||
@@ -24,11 +24,12 @@ | |||
24 | #include "arizona.h" | 24 | #include "arizona.h" |
25 | 25 | ||
26 | static int arizona_i2c_probe(struct i2c_client *i2c, | 26 | static int arizona_i2c_probe(struct i2c_client *i2c, |
27 | const struct i2c_device_id *id) | 27 | const struct i2c_device_id *id) |
28 | { | 28 | { |
29 | struct arizona *arizona; | 29 | struct arizona *arizona; |
30 | const struct regmap_config *regmap_config; | 30 | const struct regmap_config *regmap_config; |
31 | int ret, type; | 31 | unsigned long type; |
32 | int ret; | ||
32 | 33 | ||
33 | if (i2c->dev.of_node) | 34 | if (i2c->dev.of_node) |
34 | type = arizona_of_get_type(&i2c->dev); | 35 | type = arizona_of_get_type(&i2c->dev); |
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 17102f589100..d420dbc0e2b0 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c | |||
@@ -188,24 +188,33 @@ int arizona_irq_init(struct arizona *arizona) | |||
188 | int flags = IRQF_ONESHOT; | 188 | int flags = IRQF_ONESHOT; |
189 | int ret, i; | 189 | int ret, i; |
190 | const struct regmap_irq_chip *aod, *irq; | 190 | const struct regmap_irq_chip *aod, *irq; |
191 | bool ctrlif_error = true; | ||
192 | struct irq_data *irq_data; | 191 | struct irq_data *irq_data; |
193 | 192 | ||
193 | arizona->ctrlif_error = true; | ||
194 | |||
194 | switch (arizona->type) { | 195 | switch (arizona->type) { |
195 | #ifdef CONFIG_MFD_WM5102 | 196 | #ifdef CONFIG_MFD_WM5102 |
196 | case WM5102: | 197 | case WM5102: |
197 | aod = &wm5102_aod; | 198 | aod = &wm5102_aod; |
198 | irq = &wm5102_irq; | 199 | irq = &wm5102_irq; |
199 | 200 | ||
200 | ctrlif_error = false; | 201 | arizona->ctrlif_error = false; |
201 | break; | 202 | break; |
202 | #endif | 203 | #endif |
203 | #ifdef CONFIG_MFD_WM5110 | 204 | #ifdef CONFIG_MFD_WM5110 |
204 | case WM5110: | 205 | case WM5110: |
205 | aod = &wm5110_aod; | 206 | aod = &wm5110_aod; |
206 | irq = &wm5110_irq; | ||
207 | 207 | ||
208 | ctrlif_error = false; | 208 | switch (arizona->rev) { |
209 | case 0 ... 2: | ||
210 | irq = &wm5110_irq; | ||
211 | break; | ||
212 | default: | ||
213 | irq = &wm5110_revd_irq; | ||
214 | break; | ||
215 | } | ||
216 | |||
217 | arizona->ctrlif_error = false; | ||
209 | break; | 218 | break; |
210 | #endif | 219 | #endif |
211 | #ifdef CONFIG_MFD_WM8997 | 220 | #ifdef CONFIG_MFD_WM8997 |
@@ -213,7 +222,7 @@ int arizona_irq_init(struct arizona *arizona) | |||
213 | aod = &wm8997_aod; | 222 | aod = &wm8997_aod; |
214 | irq = &wm8997_irq; | 223 | irq = &wm8997_irq; |
215 | 224 | ||
216 | ctrlif_error = false; | 225 | arizona->ctrlif_error = false; |
217 | break; | 226 | break; |
218 | #endif | 227 | #endif |
219 | default: | 228 | default: |
@@ -300,7 +309,7 @@ int arizona_irq_init(struct arizona *arizona) | |||
300 | } | 309 | } |
301 | 310 | ||
302 | /* Handle control interface errors in the core */ | 311 | /* Handle control interface errors in the core */ |
303 | if (ctrlif_error) { | 312 | if (arizona->ctrlif_error) { |
304 | i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); | 313 | i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); |
305 | ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, | 314 | ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, |
306 | IRQF_ONESHOT, | 315 | IRQF_ONESHOT, |
@@ -345,7 +354,9 @@ int arizona_irq_init(struct arizona *arizona) | |||
345 | return 0; | 354 | return 0; |
346 | 355 | ||
347 | err_main_irq: | 356 | err_main_irq: |
348 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona); | 357 | if (arizona->ctrlif_error) |
358 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), | ||
359 | arizona); | ||
349 | err_ctrlif: | 360 | err_ctrlif: |
350 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); | 361 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); |
351 | err_boot_done: | 362 | err_boot_done: |
@@ -361,7 +372,9 @@ err: | |||
361 | 372 | ||
362 | int arizona_irq_exit(struct arizona *arizona) | 373 | int arizona_irq_exit(struct arizona *arizona) |
363 | { | 374 | { |
364 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona); | 375 | if (arizona->ctrlif_error) |
376 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), | ||
377 | arizona); | ||
365 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); | 378 | free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); |
366 | regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1), | 379 | regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1), |
367 | arizona->irq_chip); | 380 | arizona->irq_chip); |
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c index 1ca554b18bef..5145d78bf07e 100644 --- a/drivers/mfd/arizona-spi.c +++ b/drivers/mfd/arizona-spi.c | |||
@@ -28,7 +28,8 @@ static int arizona_spi_probe(struct spi_device *spi) | |||
28 | const struct spi_device_id *id = spi_get_device_id(spi); | 28 | const struct spi_device_id *id = spi_get_device_id(spi); |
29 | struct arizona *arizona; | 29 | struct arizona *arizona; |
30 | const struct regmap_config *regmap_config; | 30 | const struct regmap_config *regmap_config; |
31 | int ret, type; | 31 | unsigned long type; |
32 | int ret; | ||
32 | 33 | ||
33 | if (spi->dev.of_node) | 34 | if (spi->dev.of_node) |
34 | type = arizona_of_get_type(&spi->dev); | 35 | type = arizona_of_get_type(&spi->dev); |
diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h index b4cef777df73..fbe2843271c5 100644 --- a/drivers/mfd/arizona.h +++ b/drivers/mfd/arizona.h | |||
@@ -36,6 +36,7 @@ extern const struct regmap_irq_chip wm5102_irq; | |||
36 | 36 | ||
37 | extern const struct regmap_irq_chip wm5110_aod; | 37 | extern const struct regmap_irq_chip wm5110_aod; |
38 | extern const struct regmap_irq_chip wm5110_irq; | 38 | extern const struct regmap_irq_chip wm5110_irq; |
39 | extern const struct regmap_irq_chip wm5110_revd_irq; | ||
39 | 40 | ||
40 | extern const struct regmap_irq_chip wm8997_aod; | 41 | extern const struct regmap_irq_chip wm8997_aod; |
41 | extern const struct regmap_irq_chip wm8997_irq; | 42 | extern const struct regmap_irq_chip wm8997_irq; |
@@ -46,9 +47,9 @@ int arizona_irq_init(struct arizona *arizona); | |||
46 | int arizona_irq_exit(struct arizona *arizona); | 47 | int arizona_irq_exit(struct arizona *arizona); |
47 | 48 | ||
48 | #ifdef CONFIG_OF | 49 | #ifdef CONFIG_OF |
49 | int arizona_of_get_type(struct device *dev); | 50 | unsigned long arizona_of_get_type(struct device *dev); |
50 | #else | 51 | #else |
51 | static inline int arizona_of_get_type(struct device *dev) | 52 | static inline unsigned long arizona_of_get_type(struct device *dev) |
52 | { | 53 | { |
53 | return 0; | 54 | return 0; |
54 | } | 55 | } |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 9f6294f2a070..9fc4186d4132 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -899,13 +899,15 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
899 | ds1wm_resources[0].end >>= asic->bus_shift; | 899 | ds1wm_resources[0].end >>= asic->bus_shift; |
900 | 900 | ||
901 | /* MMC */ | 901 | /* MMC */ |
902 | asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + | 902 | if (mem_sdio) { |
903 | asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + | ||
903 | mem_sdio->start, | 904 | mem_sdio->start, |
904 | ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); | 905 | ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); |
905 | if (!asic->tmio_cnf) { | 906 | if (!asic->tmio_cnf) { |
906 | ret = -ENOMEM; | 907 | ret = -ENOMEM; |
907 | dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); | 908 | dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); |
908 | goto out; | 909 | goto out; |
910 | } | ||
909 | } | 911 | } |
910 | asic3_mmc_resources[0].start >>= asic->bus_shift; | 912 | asic3_mmc_resources[0].start >>= asic->bus_shift; |
911 | asic3_mmc_resources[0].end >>= asic->bus_shift; | 913 | asic3_mmc_resources[0].end >>= asic->bus_shift; |
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index 38fe9bf0d169..4873f9c50452 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c | |||
@@ -25,64 +25,42 @@ | |||
25 | #include <linux/mfd/cros_ec_commands.h> | 25 | #include <linux/mfd/cros_ec_commands.h> |
26 | 26 | ||
27 | int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, | 27 | int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, |
28 | struct cros_ec_msg *msg) | 28 | struct cros_ec_command *msg) |
29 | { | 29 | { |
30 | uint8_t *out; | 30 | uint8_t *out; |
31 | int csum, i; | 31 | int csum, i; |
32 | 32 | ||
33 | BUG_ON(msg->out_len > EC_PROTO2_MAX_PARAM_SIZE); | 33 | BUG_ON(msg->outsize > EC_PROTO2_MAX_PARAM_SIZE); |
34 | out = ec_dev->dout; | 34 | out = ec_dev->dout; |
35 | out[0] = EC_CMD_VERSION0 + msg->version; | 35 | out[0] = EC_CMD_VERSION0 + msg->version; |
36 | out[1] = msg->cmd; | 36 | out[1] = msg->command; |
37 | out[2] = msg->out_len; | 37 | out[2] = msg->outsize; |
38 | csum = out[0] + out[1] + out[2]; | 38 | csum = out[0] + out[1] + out[2]; |
39 | for (i = 0; i < msg->out_len; i++) | 39 | for (i = 0; i < msg->outsize; i++) |
40 | csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->out_buf[i]; | 40 | csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->outdata[i]; |
41 | out[EC_MSG_TX_HEADER_BYTES + msg->out_len] = (uint8_t)(csum & 0xff); | 41 | out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = (uint8_t)(csum & 0xff); |
42 | 42 | ||
43 | return EC_MSG_TX_PROTO_BYTES + msg->out_len; | 43 | return EC_MSG_TX_PROTO_BYTES + msg->outsize; |
44 | } | 44 | } |
45 | EXPORT_SYMBOL(cros_ec_prepare_tx); | 45 | EXPORT_SYMBOL(cros_ec_prepare_tx); |
46 | 46 | ||
47 | static int cros_ec_command_sendrecv(struct cros_ec_device *ec_dev, | 47 | int cros_ec_check_result(struct cros_ec_device *ec_dev, |
48 | uint16_t cmd, void *out_buf, int out_len, | 48 | struct cros_ec_command *msg) |
49 | void *in_buf, int in_len) | ||
50 | { | 49 | { |
51 | struct cros_ec_msg msg; | 50 | switch (msg->result) { |
52 | 51 | case EC_RES_SUCCESS: | |
53 | msg.version = cmd >> 8; | 52 | return 0; |
54 | msg.cmd = cmd & 0xff; | 53 | case EC_RES_IN_PROGRESS: |
55 | msg.out_buf = out_buf; | 54 | dev_dbg(ec_dev->dev, "command 0x%02x in progress\n", |
56 | msg.out_len = out_len; | 55 | msg->command); |
57 | msg.in_buf = in_buf; | 56 | return -EAGAIN; |
58 | msg.in_len = in_len; | 57 | default: |
59 | 58 | dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n", | |
60 | return ec_dev->command_xfer(ec_dev, &msg); | 59 | msg->command, msg->result); |
61 | } | 60 | return 0; |
62 | 61 | } | |
63 | static int cros_ec_command_recv(struct cros_ec_device *ec_dev, | ||
64 | uint16_t cmd, void *buf, int buf_len) | ||
65 | { | ||
66 | return cros_ec_command_sendrecv(ec_dev, cmd, NULL, 0, buf, buf_len); | ||
67 | } | ||
68 | |||
69 | static int cros_ec_command_send(struct cros_ec_device *ec_dev, | ||
70 | uint16_t cmd, void *buf, int buf_len) | ||
71 | { | ||
72 | return cros_ec_command_sendrecv(ec_dev, cmd, buf, buf_len, NULL, 0); | ||
73 | } | ||
74 | |||
75 | static irqreturn_t ec_irq_thread(int irq, void *data) | ||
76 | { | ||
77 | struct cros_ec_device *ec_dev = data; | ||
78 | |||
79 | if (device_may_wakeup(ec_dev->dev)) | ||
80 | pm_wakeup_event(ec_dev->dev, 0); | ||
81 | |||
82 | blocking_notifier_call_chain(&ec_dev->event_notifier, 1, ec_dev); | ||
83 | |||
84 | return IRQ_HANDLED; | ||
85 | } | 62 | } |
63 | EXPORT_SYMBOL(cros_ec_check_result); | ||
86 | 64 | ||
87 | static const struct mfd_cell cros_devs[] = { | 65 | static const struct mfd_cell cros_devs[] = { |
88 | { | 66 | { |
@@ -102,12 +80,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev) | |||
102 | struct device *dev = ec_dev->dev; | 80 | struct device *dev = ec_dev->dev; |
103 | int err = 0; | 81 | int err = 0; |
104 | 82 | ||
105 | BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier); | ||
106 | |||
107 | ec_dev->command_send = cros_ec_command_send; | ||
108 | ec_dev->command_recv = cros_ec_command_recv; | ||
109 | ec_dev->command_sendrecv = cros_ec_command_sendrecv; | ||
110 | |||
111 | if (ec_dev->din_size) { | 83 | if (ec_dev->din_size) { |
112 | ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL); | 84 | ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL); |
113 | if (!ec_dev->din) | 85 | if (!ec_dev->din) |
@@ -119,42 +91,23 @@ int cros_ec_register(struct cros_ec_device *ec_dev) | |||
119 | return -ENOMEM; | 91 | return -ENOMEM; |
120 | } | 92 | } |
121 | 93 | ||
122 | if (!ec_dev->irq) { | ||
123 | dev_dbg(dev, "no valid IRQ: %d\n", ec_dev->irq); | ||
124 | return err; | ||
125 | } | ||
126 | |||
127 | err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread, | ||
128 | IRQF_TRIGGER_LOW | IRQF_ONESHOT, | ||
129 | "chromeos-ec", ec_dev); | ||
130 | if (err) { | ||
131 | dev_err(dev, "request irq %d: error %d\n", ec_dev->irq, err); | ||
132 | return err; | ||
133 | } | ||
134 | |||
135 | err = mfd_add_devices(dev, 0, cros_devs, | 94 | err = mfd_add_devices(dev, 0, cros_devs, |
136 | ARRAY_SIZE(cros_devs), | 95 | ARRAY_SIZE(cros_devs), |
137 | NULL, ec_dev->irq, NULL); | 96 | NULL, ec_dev->irq, NULL); |
138 | if (err) { | 97 | if (err) { |
139 | dev_err(dev, "failed to add mfd devices\n"); | 98 | dev_err(dev, "failed to add mfd devices\n"); |
140 | goto fail_mfd; | 99 | return err; |
141 | } | 100 | } |
142 | 101 | ||
143 | dev_info(dev, "Chrome EC (%s)\n", ec_dev->name); | 102 | dev_info(dev, "Chrome EC device registered\n"); |
144 | 103 | ||
145 | return 0; | 104 | return 0; |
146 | |||
147 | fail_mfd: | ||
148 | free_irq(ec_dev->irq, ec_dev); | ||
149 | |||
150 | return err; | ||
151 | } | 105 | } |
152 | EXPORT_SYMBOL(cros_ec_register); | 106 | EXPORT_SYMBOL(cros_ec_register); |
153 | 107 | ||
154 | int cros_ec_remove(struct cros_ec_device *ec_dev) | 108 | int cros_ec_remove(struct cros_ec_device *ec_dev) |
155 | { | 109 | { |
156 | mfd_remove_devices(ec_dev->dev); | 110 | mfd_remove_devices(ec_dev->dev); |
157 | free_irq(ec_dev->irq, ec_dev); | ||
158 | 111 | ||
159 | return 0; | 112 | return 0; |
160 | } | 113 | } |
diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c index 4f71be99a183..c0c30f4f946f 100644 --- a/drivers/mfd/cros_ec_i2c.c +++ b/drivers/mfd/cros_ec_i2c.c | |||
@@ -29,12 +29,13 @@ static inline struct cros_ec_device *to_ec_dev(struct device *dev) | |||
29 | return i2c_get_clientdata(client); | 29 | return i2c_get_clientdata(client); |
30 | } | 30 | } |
31 | 31 | ||
32 | static int cros_ec_command_xfer(struct cros_ec_device *ec_dev, | 32 | static int cros_ec_cmd_xfer_i2c(struct cros_ec_device *ec_dev, |
33 | struct cros_ec_msg *msg) | 33 | struct cros_ec_command *msg) |
34 | { | 34 | { |
35 | struct i2c_client *client = ec_dev->priv; | 35 | struct i2c_client *client = ec_dev->priv; |
36 | int ret = -ENOMEM; | 36 | int ret = -ENOMEM; |
37 | int i; | 37 | int i; |
38 | int len; | ||
38 | int packet_len; | 39 | int packet_len; |
39 | u8 *out_buf = NULL; | 40 | u8 *out_buf = NULL; |
40 | u8 *in_buf = NULL; | 41 | u8 *in_buf = NULL; |
@@ -50,7 +51,7 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev, | |||
50 | * allocate larger packet (one byte for checksum, one byte for | 51 | * allocate larger packet (one byte for checksum, one byte for |
51 | * length, and one for result code) | 52 | * length, and one for result code) |
52 | */ | 53 | */ |
53 | packet_len = msg->in_len + 3; | 54 | packet_len = msg->insize + 3; |
54 | in_buf = kzalloc(packet_len, GFP_KERNEL); | 55 | in_buf = kzalloc(packet_len, GFP_KERNEL); |
55 | if (!in_buf) | 56 | if (!in_buf) |
56 | goto done; | 57 | goto done; |
@@ -61,7 +62,7 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev, | |||
61 | * allocate larger packet (one byte for checksum, one for | 62 | * allocate larger packet (one byte for checksum, one for |
62 | * command code, one for length, and one for command version) | 63 | * command code, one for length, and one for command version) |
63 | */ | 64 | */ |
64 | packet_len = msg->out_len + 4; | 65 | packet_len = msg->outsize + 4; |
65 | out_buf = kzalloc(packet_len, GFP_KERNEL); | 66 | out_buf = kzalloc(packet_len, GFP_KERNEL); |
66 | if (!out_buf) | 67 | if (!out_buf) |
67 | goto done; | 68 | goto done; |
@@ -69,16 +70,16 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev, | |||
69 | i2c_msg[0].buf = (char *)out_buf; | 70 | i2c_msg[0].buf = (char *)out_buf; |
70 | 71 | ||
71 | out_buf[0] = EC_CMD_VERSION0 + msg->version; | 72 | out_buf[0] = EC_CMD_VERSION0 + msg->version; |
72 | out_buf[1] = msg->cmd; | 73 | out_buf[1] = msg->command; |
73 | out_buf[2] = msg->out_len; | 74 | out_buf[2] = msg->outsize; |
74 | 75 | ||
75 | /* copy message payload and compute checksum */ | 76 | /* copy message payload and compute checksum */ |
76 | sum = out_buf[0] + out_buf[1] + out_buf[2]; | 77 | sum = out_buf[0] + out_buf[1] + out_buf[2]; |
77 | for (i = 0; i < msg->out_len; i++) { | 78 | for (i = 0; i < msg->outsize; i++) { |
78 | out_buf[3 + i] = msg->out_buf[i]; | 79 | out_buf[3 + i] = msg->outdata[i]; |
79 | sum += out_buf[3 + i]; | 80 | sum += out_buf[3 + i]; |
80 | } | 81 | } |
81 | out_buf[3 + msg->out_len] = sum; | 82 | out_buf[3 + msg->outsize] = sum; |
82 | 83 | ||
83 | /* send command to EC and read answer */ | 84 | /* send command to EC and read answer */ |
84 | ret = i2c_transfer(client->adapter, i2c_msg, 2); | 85 | ret = i2c_transfer(client->adapter, i2c_msg, 2); |
@@ -92,28 +93,34 @@ static int cros_ec_command_xfer(struct cros_ec_device *ec_dev, | |||
92 | } | 93 | } |
93 | 94 | ||
94 | /* check response error code */ | 95 | /* check response error code */ |
95 | if (i2c_msg[1].buf[0]) { | 96 | msg->result = i2c_msg[1].buf[0]; |
96 | dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n", | 97 | ret = cros_ec_check_result(ec_dev, msg); |
97 | msg->cmd, i2c_msg[1].buf[0]); | 98 | if (ret) |
98 | ret = -EINVAL; | 99 | goto done; |
100 | |||
101 | len = in_buf[1]; | ||
102 | if (len > msg->insize) { | ||
103 | dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", | ||
104 | len, msg->insize); | ||
105 | ret = -ENOSPC; | ||
99 | goto done; | 106 | goto done; |
100 | } | 107 | } |
101 | 108 | ||
102 | /* copy response packet payload and compute checksum */ | 109 | /* copy response packet payload and compute checksum */ |
103 | sum = in_buf[0] + in_buf[1]; | 110 | sum = in_buf[0] + in_buf[1]; |
104 | for (i = 0; i < msg->in_len; i++) { | 111 | for (i = 0; i < len; i++) { |
105 | msg->in_buf[i] = in_buf[2 + i]; | 112 | msg->indata[i] = in_buf[2 + i]; |
106 | sum += in_buf[2 + i]; | 113 | sum += in_buf[2 + i]; |
107 | } | 114 | } |
108 | dev_dbg(ec_dev->dev, "packet: %*ph, sum = %02x\n", | 115 | dev_dbg(ec_dev->dev, "packet: %*ph, sum = %02x\n", |
109 | i2c_msg[1].len, in_buf, sum); | 116 | i2c_msg[1].len, in_buf, sum); |
110 | if (sum != in_buf[2 + msg->in_len]) { | 117 | if (sum != in_buf[2 + len]) { |
111 | dev_err(ec_dev->dev, "bad packet checksum\n"); | 118 | dev_err(ec_dev->dev, "bad packet checksum\n"); |
112 | ret = -EBADMSG; | 119 | ret = -EBADMSG; |
113 | goto done; | 120 | goto done; |
114 | } | 121 | } |
115 | 122 | ||
116 | ret = 0; | 123 | ret = len; |
117 | done: | 124 | done: |
118 | kfree(in_buf); | 125 | kfree(in_buf); |
119 | kfree(out_buf); | 126 | kfree(out_buf); |
@@ -132,11 +139,10 @@ static int cros_ec_i2c_probe(struct i2c_client *client, | |||
132 | return -ENOMEM; | 139 | return -ENOMEM; |
133 | 140 | ||
134 | i2c_set_clientdata(client, ec_dev); | 141 | i2c_set_clientdata(client, ec_dev); |
135 | ec_dev->name = "I2C"; | ||
136 | ec_dev->dev = dev; | 142 | ec_dev->dev = dev; |
137 | ec_dev->priv = client; | 143 | ec_dev->priv = client; |
138 | ec_dev->irq = client->irq; | 144 | ec_dev->irq = client->irq; |
139 | ec_dev->command_xfer = cros_ec_command_xfer; | 145 | ec_dev->cmd_xfer = cros_ec_cmd_xfer_i2c; |
140 | ec_dev->ec_name = client->name; | 146 | ec_dev->ec_name = client->name; |
141 | ec_dev->phys_name = client->adapter->name; | 147 | ec_dev->phys_name = client->adapter->name; |
142 | ec_dev->parent = &client->dev; | 148 | ec_dev->parent = &client->dev; |
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index 8c1c7cc373f8..588c700af39c 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c | |||
@@ -73,7 +73,7 @@ | |||
73 | * if no record | 73 | * if no record |
74 | * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that | 74 | * @end_of_msg_delay: used to set the delay_usecs on the spi_transfer that |
75 | * is sent when we want to turn off CS at the end of a transaction. | 75 | * is sent when we want to turn off CS at the end of a transaction. |
76 | * @lock: mutex to ensure only one user of cros_ec_command_spi_xfer at a time | 76 | * @lock: mutex to ensure only one user of cros_ec_cmd_xfer_spi at a time |
77 | */ | 77 | */ |
78 | struct cros_ec_spi { | 78 | struct cros_ec_spi { |
79 | struct spi_device *spi; | 79 | struct spi_device *spi; |
@@ -210,13 +210,13 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, | |||
210 | } | 210 | } |
211 | 211 | ||
212 | /** | 212 | /** |
213 | * cros_ec_command_spi_xfer - Transfer a message over SPI and receive the reply | 213 | * cros_ec_cmd_xfer_spi - Transfer a message over SPI and receive the reply |
214 | * | 214 | * |
215 | * @ec_dev: ChromeOS EC device | 215 | * @ec_dev: ChromeOS EC device |
216 | * @ec_msg: Message to transfer | 216 | * @ec_msg: Message to transfer |
217 | */ | 217 | */ |
218 | static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | 218 | static int cros_ec_cmd_xfer_spi(struct cros_ec_device *ec_dev, |
219 | struct cros_ec_msg *ec_msg) | 219 | struct cros_ec_command *ec_msg) |
220 | { | 220 | { |
221 | struct cros_ec_spi *ec_spi = ec_dev->priv; | 221 | struct cros_ec_spi *ec_spi = ec_dev->priv; |
222 | struct spi_transfer trans; | 222 | struct spi_transfer trans; |
@@ -258,23 +258,19 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
258 | /* Get the response */ | 258 | /* Get the response */ |
259 | if (!ret) { | 259 | if (!ret) { |
260 | ret = cros_ec_spi_receive_response(ec_dev, | 260 | ret = cros_ec_spi_receive_response(ec_dev, |
261 | ec_msg->in_len + EC_MSG_TX_PROTO_BYTES); | 261 | ec_msg->insize + EC_MSG_TX_PROTO_BYTES); |
262 | } else { | 262 | } else { |
263 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | 263 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); |
264 | } | 264 | } |
265 | 265 | ||
266 | /* turn off CS */ | 266 | /* |
267 | * Turn off CS, possibly adding a delay to ensure the rising edge | ||
268 | * doesn't come too soon after the end of the data. | ||
269 | */ | ||
267 | spi_message_init(&msg); | 270 | spi_message_init(&msg); |
268 | 271 | memset(&trans, 0, sizeof(trans)); | |
269 | if (ec_spi->end_of_msg_delay) { | 272 | trans.delay_usecs = ec_spi->end_of_msg_delay; |
270 | /* | 273 | spi_message_add_tail(&trans, &msg); |
271 | * Add delay for last transaction, to ensure the rising edge | ||
272 | * doesn't come too soon after the end of the data. | ||
273 | */ | ||
274 | memset(&trans, 0, sizeof(trans)); | ||
275 | trans.delay_usecs = ec_spi->end_of_msg_delay; | ||
276 | spi_message_add_tail(&trans, &msg); | ||
277 | } | ||
278 | 274 | ||
279 | final_ret = spi_sync(ec_spi->spi, &msg); | 275 | final_ret = spi_sync(ec_spi->spi, &msg); |
280 | ec_spi->last_transfer_ns = ktime_get_ns(); | 276 | ec_spi->last_transfer_ns = ktime_get_ns(); |
@@ -285,20 +281,19 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
285 | goto exit; | 281 | goto exit; |
286 | } | 282 | } |
287 | 283 | ||
288 | /* check response error code */ | ||
289 | ptr = ec_dev->din; | 284 | ptr = ec_dev->din; |
290 | if (ptr[0]) { | 285 | |
291 | dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n", | 286 | /* check response error code */ |
292 | ec_msg->cmd, ptr[0]); | 287 | ec_msg->result = ptr[0]; |
293 | debug_packet(ec_dev->dev, "in_err", ptr, len); | 288 | ret = cros_ec_check_result(ec_dev, ec_msg); |
294 | ret = -EINVAL; | 289 | if (ret) |
295 | goto exit; | 290 | goto exit; |
296 | } | 291 | |
297 | len = ptr[1]; | 292 | len = ptr[1]; |
298 | sum = ptr[0] + ptr[1]; | 293 | sum = ptr[0] + ptr[1]; |
299 | if (len > ec_msg->in_len) { | 294 | if (len > ec_msg->insize) { |
300 | dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", | 295 | dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", |
301 | len, ec_msg->in_len); | 296 | len, ec_msg->insize); |
302 | ret = -ENOSPC; | 297 | ret = -ENOSPC; |
303 | goto exit; | 298 | goto exit; |
304 | } | 299 | } |
@@ -306,8 +301,8 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
306 | /* copy response packet payload and compute checksum */ | 301 | /* copy response packet payload and compute checksum */ |
307 | for (i = 0; i < len; i++) { | 302 | for (i = 0; i < len; i++) { |
308 | sum += ptr[i + 2]; | 303 | sum += ptr[i + 2]; |
309 | if (ec_msg->in_len) | 304 | if (ec_msg->insize) |
310 | ec_msg->in_buf[i] = ptr[i + 2]; | 305 | ec_msg->indata[i] = ptr[i + 2]; |
311 | } | 306 | } |
312 | sum &= 0xff; | 307 | sum &= 0xff; |
313 | 308 | ||
@@ -321,7 +316,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
321 | goto exit; | 316 | goto exit; |
322 | } | 317 | } |
323 | 318 | ||
324 | ret = 0; | 319 | ret = len; |
325 | exit: | 320 | exit: |
326 | mutex_unlock(&ec_spi->lock); | 321 | mutex_unlock(&ec_spi->lock); |
327 | return ret; | 322 | return ret; |
@@ -364,11 +359,10 @@ static int cros_ec_spi_probe(struct spi_device *spi) | |||
364 | cros_ec_spi_dt_probe(ec_spi, dev); | 359 | cros_ec_spi_dt_probe(ec_spi, dev); |
365 | 360 | ||
366 | spi_set_drvdata(spi, ec_dev); | 361 | spi_set_drvdata(spi, ec_dev); |
367 | ec_dev->name = "SPI"; | ||
368 | ec_dev->dev = dev; | 362 | ec_dev->dev = dev; |
369 | ec_dev->priv = ec_spi; | 363 | ec_dev->priv = ec_spi; |
370 | ec_dev->irq = spi->irq; | 364 | ec_dev->irq = spi->irq; |
371 | ec_dev->command_xfer = cros_ec_command_spi_xfer; | 365 | ec_dev->cmd_xfer = cros_ec_cmd_xfer_spi; |
372 | ec_dev->ec_name = ec_spi->spi->modalias; | 366 | ec_dev->ec_name = ec_spi->spi->modalias; |
373 | ec_dev->phys_name = dev_name(&ec_spi->spi->dev); | 367 | ec_dev->phys_name = dev_name(&ec_spi->spi->dev); |
374 | ec_dev->parent = &ec_spi->spi->dev; | 368 | ec_dev->parent = &ec_spi->spi->dev; |
@@ -381,6 +375,8 @@ static int cros_ec_spi_probe(struct spi_device *spi) | |||
381 | return err; | 375 | return err; |
382 | } | 376 | } |
383 | 377 | ||
378 | device_init_wakeup(&spi->dev, true); | ||
379 | |||
384 | return 0; | 380 | return 0; |
385 | } | 381 | } |
386 | 382 | ||
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c index e70ae315abc7..93db8bb8c8f0 100644 --- a/drivers/mfd/da9063-core.c +++ b/drivers/mfd/da9063-core.c | |||
@@ -153,9 +153,9 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) | |||
153 | "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n", | 153 | "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n", |
154 | model, variant_id); | 154 | model, variant_id); |
155 | 155 | ||
156 | if (variant_code != PMIC_DA9063_BB) { | 156 | if (variant_code < PMIC_DA9063_BB && variant_code != PMIC_DA9063_AD) { |
157 | dev_err(da9063->dev, "Unknown chip variant code: 0x%02X\n", | 157 | dev_err(da9063->dev, |
158 | variant_code); | 158 | "Cannot support variant code: 0x%02X\n", variant_code); |
159 | return -ENODEV; | 159 | return -ENODEV; |
160 | } | 160 | } |
161 | 161 | ||
diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c index 8db5c805c64f..21fd8d9a217b 100644 --- a/drivers/mfd/da9063-i2c.c +++ b/drivers/mfd/da9063-i2c.c | |||
@@ -25,10 +25,10 @@ | |||
25 | #include <linux/mfd/da9063/pdata.h> | 25 | #include <linux/mfd/da9063/pdata.h> |
26 | #include <linux/mfd/da9063/registers.h> | 26 | #include <linux/mfd/da9063/registers.h> |
27 | 27 | ||
28 | static const struct regmap_range da9063_readable_ranges[] = { | 28 | static const struct regmap_range da9063_ad_readable_ranges[] = { |
29 | { | 29 | { |
30 | .range_min = DA9063_REG_PAGE_CON, | 30 | .range_min = DA9063_REG_PAGE_CON, |
31 | .range_max = DA9063_REG_SECOND_D, | 31 | .range_max = DA9063_AD_REG_SECOND_D, |
32 | }, { | 32 | }, { |
33 | .range_min = DA9063_REG_SEQ, | 33 | .range_min = DA9063_REG_SEQ, |
34 | .range_max = DA9063_REG_ID_32_31, | 34 | .range_max = DA9063_REG_ID_32_31, |
@@ -37,14 +37,14 @@ static const struct regmap_range da9063_readable_ranges[] = { | |||
37 | .range_max = DA9063_REG_AUTO3_LOW, | 37 | .range_max = DA9063_REG_AUTO3_LOW, |
38 | }, { | 38 | }, { |
39 | .range_min = DA9063_REG_T_OFFSET, | 39 | .range_min = DA9063_REG_T_OFFSET, |
40 | .range_max = DA9063_REG_GP_ID_19, | 40 | .range_max = DA9063_AD_REG_GP_ID_19, |
41 | }, { | 41 | }, { |
42 | .range_min = DA9063_REG_CHIP_ID, | 42 | .range_min = DA9063_REG_CHIP_ID, |
43 | .range_max = DA9063_REG_CHIP_VARIANT, | 43 | .range_max = DA9063_REG_CHIP_VARIANT, |
44 | }, | 44 | }, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static const struct regmap_range da9063_writeable_ranges[] = { | 47 | static const struct regmap_range da9063_ad_writeable_ranges[] = { |
48 | { | 48 | { |
49 | .range_min = DA9063_REG_PAGE_CON, | 49 | .range_min = DA9063_REG_PAGE_CON, |
50 | .range_max = DA9063_REG_PAGE_CON, | 50 | .range_max = DA9063_REG_PAGE_CON, |
@@ -53,7 +53,7 @@ static const struct regmap_range da9063_writeable_ranges[] = { | |||
53 | .range_max = DA9063_REG_VSYS_MON, | 53 | .range_max = DA9063_REG_VSYS_MON, |
54 | }, { | 54 | }, { |
55 | .range_min = DA9063_REG_COUNT_S, | 55 | .range_min = DA9063_REG_COUNT_S, |
56 | .range_max = DA9063_REG_ALARM_Y, | 56 | .range_max = DA9063_AD_REG_ALARM_Y, |
57 | }, { | 57 | }, { |
58 | .range_min = DA9063_REG_SEQ, | 58 | .range_min = DA9063_REG_SEQ, |
59 | .range_max = DA9063_REG_ID_32_31, | 59 | .range_max = DA9063_REG_ID_32_31, |
@@ -62,14 +62,14 @@ static const struct regmap_range da9063_writeable_ranges[] = { | |||
62 | .range_max = DA9063_REG_AUTO3_LOW, | 62 | .range_max = DA9063_REG_AUTO3_LOW, |
63 | }, { | 63 | }, { |
64 | .range_min = DA9063_REG_CONFIG_I, | 64 | .range_min = DA9063_REG_CONFIG_I, |
65 | .range_max = DA9063_REG_MON_REG_4, | 65 | .range_max = DA9063_AD_REG_MON_REG_4, |
66 | }, { | 66 | }, { |
67 | .range_min = DA9063_REG_GP_ID_0, | 67 | .range_min = DA9063_AD_REG_GP_ID_0, |
68 | .range_max = DA9063_REG_GP_ID_19, | 68 | .range_max = DA9063_AD_REG_GP_ID_19, |
69 | }, | 69 | }, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | static const struct regmap_range da9063_volatile_ranges[] = { | 72 | static const struct regmap_range da9063_ad_volatile_ranges[] = { |
73 | { | 73 | { |
74 | .range_min = DA9063_REG_STATUS_A, | 74 | .range_min = DA9063_REG_STATUS_A, |
75 | .range_max = DA9063_REG_EVENT_D, | 75 | .range_max = DA9063_REG_EVENT_D, |
@@ -81,26 +81,104 @@ static const struct regmap_range da9063_volatile_ranges[] = { | |||
81 | .range_max = DA9063_REG_ADC_MAN, | 81 | .range_max = DA9063_REG_ADC_MAN, |
82 | }, { | 82 | }, { |
83 | .range_min = DA9063_REG_ADC_RES_L, | 83 | .range_min = DA9063_REG_ADC_RES_L, |
84 | .range_max = DA9063_REG_SECOND_D, | 84 | .range_max = DA9063_AD_REG_SECOND_D, |
85 | }, { | 85 | }, { |
86 | .range_min = DA9063_REG_MON_REG_5, | 86 | .range_min = DA9063_AD_REG_MON_REG_5, |
87 | .range_max = DA9063_REG_MON_REG_6, | 87 | .range_max = DA9063_AD_REG_MON_REG_6, |
88 | }, | 88 | }, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static const struct regmap_access_table da9063_readable_table = { | 91 | static const struct regmap_access_table da9063_ad_readable_table = { |
92 | .yes_ranges = da9063_readable_ranges, | 92 | .yes_ranges = da9063_ad_readable_ranges, |
93 | .n_yes_ranges = ARRAY_SIZE(da9063_readable_ranges), | 93 | .n_yes_ranges = ARRAY_SIZE(da9063_ad_readable_ranges), |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static const struct regmap_access_table da9063_writeable_table = { | 96 | static const struct regmap_access_table da9063_ad_writeable_table = { |
97 | .yes_ranges = da9063_writeable_ranges, | 97 | .yes_ranges = da9063_ad_writeable_ranges, |
98 | .n_yes_ranges = ARRAY_SIZE(da9063_writeable_ranges), | 98 | .n_yes_ranges = ARRAY_SIZE(da9063_ad_writeable_ranges), |
99 | }; | 99 | }; |
100 | 100 | ||
101 | static const struct regmap_access_table da9063_volatile_table = { | 101 | static const struct regmap_access_table da9063_ad_volatile_table = { |
102 | .yes_ranges = da9063_volatile_ranges, | 102 | .yes_ranges = da9063_ad_volatile_ranges, |
103 | .n_yes_ranges = ARRAY_SIZE(da9063_volatile_ranges), | 103 | .n_yes_ranges = ARRAY_SIZE(da9063_ad_volatile_ranges), |
104 | }; | ||
105 | |||
106 | static const struct regmap_range da9063_bb_readable_ranges[] = { | ||
107 | { | ||
108 | .range_min = DA9063_REG_PAGE_CON, | ||
109 | .range_max = DA9063_BB_REG_SECOND_D, | ||
110 | }, { | ||
111 | .range_min = DA9063_REG_SEQ, | ||
112 | .range_max = DA9063_REG_ID_32_31, | ||
113 | }, { | ||
114 | .range_min = DA9063_REG_SEQ_A, | ||
115 | .range_max = DA9063_REG_AUTO3_LOW, | ||
116 | }, { | ||
117 | .range_min = DA9063_REG_T_OFFSET, | ||
118 | .range_max = DA9063_BB_REG_GP_ID_19, | ||
119 | }, { | ||
120 | .range_min = DA9063_REG_CHIP_ID, | ||
121 | .range_max = DA9063_REG_CHIP_VARIANT, | ||
122 | }, | ||
123 | }; | ||
124 | |||
125 | static const struct regmap_range da9063_bb_writeable_ranges[] = { | ||
126 | { | ||
127 | .range_min = DA9063_REG_PAGE_CON, | ||
128 | .range_max = DA9063_REG_PAGE_CON, | ||
129 | }, { | ||
130 | .range_min = DA9063_REG_FAULT_LOG, | ||
131 | .range_max = DA9063_REG_VSYS_MON, | ||
132 | }, { | ||
133 | .range_min = DA9063_REG_COUNT_S, | ||
134 | .range_max = DA9063_BB_REG_ALARM_Y, | ||
135 | }, { | ||
136 | .range_min = DA9063_REG_SEQ, | ||
137 | .range_max = DA9063_REG_ID_32_31, | ||
138 | }, { | ||
139 | .range_min = DA9063_REG_SEQ_A, | ||
140 | .range_max = DA9063_REG_AUTO3_LOW, | ||
141 | }, { | ||
142 | .range_min = DA9063_REG_CONFIG_I, | ||
143 | .range_max = DA9063_BB_REG_MON_REG_4, | ||
144 | }, { | ||
145 | .range_min = DA9063_BB_REG_GP_ID_0, | ||
146 | .range_max = DA9063_BB_REG_GP_ID_19, | ||
147 | }, | ||
148 | }; | ||
149 | |||
150 | static const struct regmap_range da9063_bb_volatile_ranges[] = { | ||
151 | { | ||
152 | .range_min = DA9063_REG_STATUS_A, | ||
153 | .range_max = DA9063_REG_EVENT_D, | ||
154 | }, { | ||
155 | .range_min = DA9063_REG_CONTROL_F, | ||
156 | .range_max = DA9063_REG_CONTROL_F, | ||
157 | }, { | ||
158 | .range_min = DA9063_REG_ADC_MAN, | ||
159 | .range_max = DA9063_REG_ADC_MAN, | ||
160 | }, { | ||
161 | .range_min = DA9063_REG_ADC_RES_L, | ||
162 | .range_max = DA9063_BB_REG_SECOND_D, | ||
163 | }, { | ||
164 | .range_min = DA9063_BB_REG_MON_REG_5, | ||
165 | .range_max = DA9063_BB_REG_MON_REG_6, | ||
166 | }, | ||
167 | }; | ||
168 | |||
169 | static const struct regmap_access_table da9063_bb_readable_table = { | ||
170 | .yes_ranges = da9063_bb_readable_ranges, | ||
171 | .n_yes_ranges = ARRAY_SIZE(da9063_bb_readable_ranges), | ||
172 | }; | ||
173 | |||
174 | static const struct regmap_access_table da9063_bb_writeable_table = { | ||
175 | .yes_ranges = da9063_bb_writeable_ranges, | ||
176 | .n_yes_ranges = ARRAY_SIZE(da9063_bb_writeable_ranges), | ||
177 | }; | ||
178 | |||
179 | static const struct regmap_access_table da9063_bb_volatile_table = { | ||
180 | .yes_ranges = da9063_bb_volatile_ranges, | ||
181 | .n_yes_ranges = ARRAY_SIZE(da9063_bb_volatile_ranges), | ||
104 | }; | 182 | }; |
105 | 183 | ||
106 | static const struct regmap_range_cfg da9063_range_cfg[] = { | 184 | static const struct regmap_range_cfg da9063_range_cfg[] = { |
@@ -123,10 +201,6 @@ static struct regmap_config da9063_regmap_config = { | |||
123 | .max_register = DA9063_REG_CHIP_VARIANT, | 201 | .max_register = DA9063_REG_CHIP_VARIANT, |
124 | 202 | ||
125 | .cache_type = REGCACHE_RBTREE, | 203 | .cache_type = REGCACHE_RBTREE, |
126 | |||
127 | .rd_table = &da9063_readable_table, | ||
128 | .wr_table = &da9063_writeable_table, | ||
129 | .volatile_table = &da9063_volatile_table, | ||
130 | }; | 204 | }; |
131 | 205 | ||
132 | static int da9063_i2c_probe(struct i2c_client *i2c, | 206 | static int da9063_i2c_probe(struct i2c_client *i2c, |
@@ -143,6 +217,16 @@ static int da9063_i2c_probe(struct i2c_client *i2c, | |||
143 | da9063->dev = &i2c->dev; | 217 | da9063->dev = &i2c->dev; |
144 | da9063->chip_irq = i2c->irq; | 218 | da9063->chip_irq = i2c->irq; |
145 | 219 | ||
220 | if (da9063->variant_code == PMIC_DA9063_AD) { | ||
221 | da9063_regmap_config.rd_table = &da9063_ad_readable_table; | ||
222 | da9063_regmap_config.wr_table = &da9063_ad_writeable_table; | ||
223 | da9063_regmap_config.volatile_table = &da9063_ad_volatile_table; | ||
224 | } else { | ||
225 | da9063_regmap_config.rd_table = &da9063_bb_readable_table; | ||
226 | da9063_regmap_config.wr_table = &da9063_bb_writeable_table; | ||
227 | da9063_regmap_config.volatile_table = &da9063_bb_volatile_table; | ||
228 | } | ||
229 | |||
146 | da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config); | 230 | da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config); |
147 | if (IS_ERR(da9063->regmap)) { | 231 | if (IS_ERR(da9063->regmap)) { |
148 | ret = PTR_ERR(da9063->regmap); | 232 | ret = PTR_ERR(da9063->regmap); |
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c index 7a55c0071fa8..4c826f78acd0 100644 --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c | |||
@@ -95,7 +95,7 @@ EXPORT_SYMBOL(dm355evm_msp_read); | |||
95 | * Many of the msp430 pins are just used as fixed-direction GPIOs. | 95 | * Many of the msp430 pins are just used as fixed-direction GPIOs. |
96 | * We could export a few more of them this way, if we wanted. | 96 | * We could export a few more of them this way, if we wanted. |
97 | */ | 97 | */ |
98 | #define MSP_GPIO(bit,reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit)) | 98 | #define MSP_GPIO(bit, reg) ((DM355EVM_MSP_ ## reg) << 3 | (bit)) |
99 | 99 | ||
100 | static const u8 msp_gpios[] = { | 100 | static const u8 msp_gpios[] = { |
101 | /* eight leds */ | 101 | /* eight leds */ |
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index 2ed774e7d342..5991faddd3c6 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
@@ -62,7 +62,7 @@ static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data) | |||
62 | struct spi_message m; | 62 | struct spi_message m; |
63 | int status; | 63 | int status; |
64 | 64 | ||
65 | memset(&t, 0, sizeof t); | 65 | memset(&t, 0, sizeof(t)); |
66 | spi_message_init(&m); | 66 | spi_message_init(&m); |
67 | t.len = sizeof(u32); | 67 | t.len = sizeof(u32); |
68 | spi_message_add_tail(&t, &m); | 68 | spi_message_add_tail(&t, &m); |
@@ -211,7 +211,6 @@ static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
211 | 211 | ||
212 | desc->irq_data.chip->irq_ack(&desc->irq_data); | 212 | desc->irq_data.chip->irq_ack(&desc->irq_data); |
213 | queue_work(pcap->workqueue, &pcap->isr_work); | 213 | queue_work(pcap->workqueue, &pcap->isr_work); |
214 | return; | ||
215 | } | 214 | } |
216 | 215 | ||
217 | /* ADC */ | 216 | /* ADC */ |
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index d7b2a75aca3e..b44f0203983b 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
@@ -332,18 +332,13 @@ static int htcpld_setup_chip_irq( | |||
332 | int chip_index) | 332 | int chip_index) |
333 | { | 333 | { |
334 | struct htcpld_data *htcpld; | 334 | struct htcpld_data *htcpld; |
335 | struct device *dev = &pdev->dev; | ||
336 | struct htcpld_core_platform_data *pdata; | ||
337 | struct htcpld_chip *chip; | 335 | struct htcpld_chip *chip; |
338 | struct htcpld_chip_platform_data *plat_chip_data; | ||
339 | unsigned int irq, irq_end; | 336 | unsigned int irq, irq_end; |
340 | int ret = 0; | 337 | int ret = 0; |
341 | 338 | ||
342 | /* Get the platform and driver data */ | 339 | /* Get the platform and driver data */ |
343 | pdata = dev_get_platdata(dev); | ||
344 | htcpld = platform_get_drvdata(pdev); | 340 | htcpld = platform_get_drvdata(pdev); |
345 | chip = &htcpld->chip[chip_index]; | 341 | chip = &htcpld->chip[chip_index]; |
346 | plat_chip_data = &pdata->chip[chip_index]; | ||
347 | 342 | ||
348 | /* Setup irq handlers */ | 343 | /* Setup irq handlers */ |
349 | irq_end = chip->irq_start + chip->nirqs; | 344 | irq_end = chip->irq_start + chip->nirqs; |
diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c new file mode 100644 index 000000000000..2720922f90b4 --- /dev/null +++ b/drivers/mfd/intel_soc_pmic_core.c | |||
@@ -0,0 +1,170 @@ | |||
1 | /* | ||
2 | * intel_soc_pmic_core.c - Intel SoC PMIC MFD Driver | ||
3 | * | ||
4 | * Copyright (C) 2013, 2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * Author: Yang, Bin <bin.yang@intel.com> | ||
16 | * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> | ||
17 | */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/mfd/core.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/gpio/consumer.h> | ||
24 | #include <linux/acpi.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/mfd/intel_soc_pmic.h> | ||
27 | #include "intel_soc_pmic_core.h" | ||
28 | |||
29 | /* | ||
30 | * On some boards the PMIC interrupt may come from a GPIO line. | ||
31 | * Try to lookup the ACPI table and see if such connection exists. If not, | ||
32 | * return -ENOENT and use the IRQ provided by I2C. | ||
33 | */ | ||
34 | static int intel_soc_pmic_find_gpio_irq(struct device *dev) | ||
35 | { | ||
36 | struct gpio_desc *desc; | ||
37 | int irq; | ||
38 | |||
39 | desc = devm_gpiod_get_index(dev, "intel_soc_pmic", 0); | ||
40 | if (IS_ERR(desc)) | ||
41 | return -ENOENT; | ||
42 | |||
43 | irq = gpiod_to_irq(desc); | ||
44 | if (irq < 0) | ||
45 | dev_warn(dev, "Can't get irq: %d\n", irq); | ||
46 | |||
47 | return irq; | ||
48 | } | ||
49 | |||
50 | static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, | ||
51 | const struct i2c_device_id *i2c_id) | ||
52 | { | ||
53 | struct device *dev = &i2c->dev; | ||
54 | const struct acpi_device_id *id; | ||
55 | struct intel_soc_pmic_config *config; | ||
56 | struct intel_soc_pmic *pmic; | ||
57 | int ret; | ||
58 | int irq; | ||
59 | |||
60 | id = acpi_match_device(dev->driver->acpi_match_table, dev); | ||
61 | if (!id || !id->driver_data) | ||
62 | return -ENODEV; | ||
63 | |||
64 | config = (struct intel_soc_pmic_config *)id->driver_data; | ||
65 | |||
66 | pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); | ||
67 | dev_set_drvdata(dev, pmic); | ||
68 | |||
69 | pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config); | ||
70 | |||
71 | irq = intel_soc_pmic_find_gpio_irq(dev); | ||
72 | pmic->irq = (irq < 0) ? i2c->irq : irq; | ||
73 | |||
74 | ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, | ||
75 | config->irq_flags | IRQF_ONESHOT, | ||
76 | 0, config->irq_chip, | ||
77 | &pmic->irq_chip_data); | ||
78 | if (ret) | ||
79 | return ret; | ||
80 | |||
81 | ret = enable_irq_wake(pmic->irq); | ||
82 | if (ret) | ||
83 | dev_warn(dev, "Can't enable IRQ as wake source: %d\n", ret); | ||
84 | |||
85 | ret = mfd_add_devices(dev, -1, config->cell_dev, | ||
86 | config->n_cell_devs, NULL, 0, | ||
87 | regmap_irq_get_domain(pmic->irq_chip_data)); | ||
88 | if (ret) | ||
89 | goto err_del_irq_chip; | ||
90 | |||
91 | return 0; | ||
92 | |||
93 | err_del_irq_chip: | ||
94 | regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | static int intel_soc_pmic_i2c_remove(struct i2c_client *i2c) | ||
99 | { | ||
100 | struct intel_soc_pmic *pmic = dev_get_drvdata(&i2c->dev); | ||
101 | |||
102 | regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); | ||
103 | |||
104 | mfd_remove_devices(&i2c->dev); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void intel_soc_pmic_shutdown(struct i2c_client *i2c) | ||
110 | { | ||
111 | struct intel_soc_pmic *pmic = dev_get_drvdata(&i2c->dev); | ||
112 | |||
113 | disable_irq(pmic->irq); | ||
114 | |||
115 | return; | ||
116 | } | ||
117 | |||
118 | static int intel_soc_pmic_suspend(struct device *dev) | ||
119 | { | ||
120 | struct intel_soc_pmic *pmic = dev_get_drvdata(dev); | ||
121 | |||
122 | disable_irq(pmic->irq); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static int intel_soc_pmic_resume(struct device *dev) | ||
128 | { | ||
129 | struct intel_soc_pmic *pmic = dev_get_drvdata(dev); | ||
130 | |||
131 | enable_irq(pmic->irq); | ||
132 | |||
133 | return 0; | ||
134 | } | ||
135 | |||
136 | static SIMPLE_DEV_PM_OPS(intel_soc_pmic_pm_ops, intel_soc_pmic_suspend, | ||
137 | intel_soc_pmic_resume); | ||
138 | |||
139 | static const struct i2c_device_id intel_soc_pmic_i2c_id[] = { | ||
140 | { } | ||
141 | }; | ||
142 | MODULE_DEVICE_TABLE(i2c, intel_soc_pmic_i2c_id); | ||
143 | |||
144 | #if defined(CONFIG_ACPI) | ||
145 | static struct acpi_device_id intel_soc_pmic_acpi_match[] = { | ||
146 | {"INT33FD", (kernel_ulong_t)&intel_soc_pmic_config_crc}, | ||
147 | { }, | ||
148 | }; | ||
149 | MODULE_DEVICE_TABLE(acpi, intel_soc_pmic_acpi_match); | ||
150 | #endif | ||
151 | |||
152 | static struct i2c_driver intel_soc_pmic_i2c_driver = { | ||
153 | .driver = { | ||
154 | .name = "intel_soc_pmic_i2c", | ||
155 | .owner = THIS_MODULE, | ||
156 | .pm = &intel_soc_pmic_pm_ops, | ||
157 | .acpi_match_table = ACPI_PTR(intel_soc_pmic_acpi_match), | ||
158 | }, | ||
159 | .probe = intel_soc_pmic_i2c_probe, | ||
160 | .remove = intel_soc_pmic_i2c_remove, | ||
161 | .id_table = intel_soc_pmic_i2c_id, | ||
162 | .shutdown = intel_soc_pmic_shutdown, | ||
163 | }; | ||
164 | |||
165 | module_i2c_driver(intel_soc_pmic_i2c_driver); | ||
166 | |||
167 | MODULE_DESCRIPTION("I2C driver for Intel SoC PMIC"); | ||
168 | MODULE_LICENSE("GPL v2"); | ||
169 | MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>"); | ||
170 | MODULE_AUTHOR("Zhu, Lejun <lejun.zhu@linux.intel.com>"); | ||
diff --git a/drivers/mfd/intel_soc_pmic_core.h b/drivers/mfd/intel_soc_pmic_core.h new file mode 100644 index 000000000000..33aacd9baddc --- /dev/null +++ b/drivers/mfd/intel_soc_pmic_core.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * intel_soc_pmic_core.h - Intel SoC PMIC MFD Driver | ||
3 | * | ||
4 | * Copyright (C) 2012-2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * Author: Yang, Bin <bin.yang@intel.com> | ||
16 | * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> | ||
17 | */ | ||
18 | |||
19 | #ifndef __INTEL_SOC_PMIC_CORE_H__ | ||
20 | #define __INTEL_SOC_PMIC_CORE_H__ | ||
21 | |||
22 | struct intel_soc_pmic_config { | ||
23 | unsigned long irq_flags; | ||
24 | struct mfd_cell *cell_dev; | ||
25 | int n_cell_devs; | ||
26 | struct regmap_config *regmap_config; | ||
27 | struct regmap_irq_chip *irq_chip; | ||
28 | }; | ||
29 | |||
30 | extern struct intel_soc_pmic_config intel_soc_pmic_config_crc; | ||
31 | |||
32 | #endif /* __INTEL_SOC_PMIC_CORE_H__ */ | ||
diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c new file mode 100644 index 000000000000..7107cab832e6 --- /dev/null +++ b/drivers/mfd/intel_soc_pmic_crc.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * intel_soc_pmic_crc.c - Device access for Crystal Cove PMIC | ||
3 | * | ||
4 | * Copyright (C) 2013, 2014 Intel Corporation. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version | ||
8 | * 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * Author: Yang, Bin <bin.yang@intel.com> | ||
16 | * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> | ||
17 | */ | ||
18 | |||
19 | #include <linux/mfd/core.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/mfd/intel_soc_pmic.h> | ||
23 | #include "intel_soc_pmic_core.h" | ||
24 | |||
25 | #define CRYSTAL_COVE_MAX_REGISTER 0xC6 | ||
26 | |||
27 | #define CRYSTAL_COVE_REG_IRQLVL1 0x02 | ||
28 | #define CRYSTAL_COVE_REG_MIRQLVL1 0x0E | ||
29 | |||
30 | #define CRYSTAL_COVE_IRQ_PWRSRC 0 | ||
31 | #define CRYSTAL_COVE_IRQ_THRM 1 | ||
32 | #define CRYSTAL_COVE_IRQ_BCU 2 | ||
33 | #define CRYSTAL_COVE_IRQ_ADC 3 | ||
34 | #define CRYSTAL_COVE_IRQ_CHGR 4 | ||
35 | #define CRYSTAL_COVE_IRQ_GPIO 5 | ||
36 | #define CRYSTAL_COVE_IRQ_VHDMIOCP 6 | ||
37 | |||
38 | static struct resource gpio_resources[] = { | ||
39 | { | ||
40 | .name = "GPIO", | ||
41 | .start = CRYSTAL_COVE_IRQ_GPIO, | ||
42 | .end = CRYSTAL_COVE_IRQ_GPIO, | ||
43 | .flags = IORESOURCE_IRQ, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | static struct resource pwrsrc_resources[] = { | ||
48 | { | ||
49 | .name = "PWRSRC", | ||
50 | .start = CRYSTAL_COVE_IRQ_PWRSRC, | ||
51 | .end = CRYSTAL_COVE_IRQ_PWRSRC, | ||
52 | .flags = IORESOURCE_IRQ, | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | static struct resource adc_resources[] = { | ||
57 | { | ||
58 | .name = "ADC", | ||
59 | .start = CRYSTAL_COVE_IRQ_ADC, | ||
60 | .end = CRYSTAL_COVE_IRQ_ADC, | ||
61 | .flags = IORESOURCE_IRQ, | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | static struct resource thermal_resources[] = { | ||
66 | { | ||
67 | .name = "THERMAL", | ||
68 | .start = CRYSTAL_COVE_IRQ_THRM, | ||
69 | .end = CRYSTAL_COVE_IRQ_THRM, | ||
70 | .flags = IORESOURCE_IRQ, | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static struct resource bcu_resources[] = { | ||
75 | { | ||
76 | .name = "BCU", | ||
77 | .start = CRYSTAL_COVE_IRQ_BCU, | ||
78 | .end = CRYSTAL_COVE_IRQ_BCU, | ||
79 | .flags = IORESOURCE_IRQ, | ||
80 | }, | ||
81 | }; | ||
82 | |||
83 | static struct mfd_cell crystal_cove_dev[] = { | ||
84 | { | ||
85 | .name = "crystal_cove_pwrsrc", | ||
86 | .num_resources = ARRAY_SIZE(pwrsrc_resources), | ||
87 | .resources = pwrsrc_resources, | ||
88 | }, | ||
89 | { | ||
90 | .name = "crystal_cove_adc", | ||
91 | .num_resources = ARRAY_SIZE(adc_resources), | ||
92 | .resources = adc_resources, | ||
93 | }, | ||
94 | { | ||
95 | .name = "crystal_cove_thermal", | ||
96 | .num_resources = ARRAY_SIZE(thermal_resources), | ||
97 | .resources = thermal_resources, | ||
98 | }, | ||
99 | { | ||
100 | .name = "crystal_cove_bcu", | ||
101 | .num_resources = ARRAY_SIZE(bcu_resources), | ||
102 | .resources = bcu_resources, | ||
103 | }, | ||
104 | { | ||
105 | .name = "crystal_cove_gpio", | ||
106 | .num_resources = ARRAY_SIZE(gpio_resources), | ||
107 | .resources = gpio_resources, | ||
108 | }, | ||
109 | }; | ||
110 | |||
111 | static struct regmap_config crystal_cove_regmap_config = { | ||
112 | .reg_bits = 8, | ||
113 | .val_bits = 8, | ||
114 | |||
115 | .max_register = CRYSTAL_COVE_MAX_REGISTER, | ||
116 | .cache_type = REGCACHE_NONE, | ||
117 | }; | ||
118 | |||
119 | static const struct regmap_irq crystal_cove_irqs[] = { | ||
120 | [CRYSTAL_COVE_IRQ_PWRSRC] = { | ||
121 | .mask = BIT(CRYSTAL_COVE_IRQ_PWRSRC), | ||
122 | }, | ||
123 | [CRYSTAL_COVE_IRQ_THRM] = { | ||
124 | .mask = BIT(CRYSTAL_COVE_IRQ_THRM), | ||
125 | }, | ||
126 | [CRYSTAL_COVE_IRQ_BCU] = { | ||
127 | .mask = BIT(CRYSTAL_COVE_IRQ_BCU), | ||
128 | }, | ||
129 | [CRYSTAL_COVE_IRQ_ADC] = { | ||
130 | .mask = BIT(CRYSTAL_COVE_IRQ_ADC), | ||
131 | }, | ||
132 | [CRYSTAL_COVE_IRQ_CHGR] = { | ||
133 | .mask = BIT(CRYSTAL_COVE_IRQ_CHGR), | ||
134 | }, | ||
135 | [CRYSTAL_COVE_IRQ_GPIO] = { | ||
136 | .mask = BIT(CRYSTAL_COVE_IRQ_GPIO), | ||
137 | }, | ||
138 | [CRYSTAL_COVE_IRQ_VHDMIOCP] = { | ||
139 | .mask = BIT(CRYSTAL_COVE_IRQ_VHDMIOCP), | ||
140 | }, | ||
141 | }; | ||
142 | |||
143 | static struct regmap_irq_chip crystal_cove_irq_chip = { | ||
144 | .name = "Crystal Cove", | ||
145 | .irqs = crystal_cove_irqs, | ||
146 | .num_irqs = ARRAY_SIZE(crystal_cove_irqs), | ||
147 | .num_regs = 1, | ||
148 | .status_base = CRYSTAL_COVE_REG_IRQLVL1, | ||
149 | .mask_base = CRYSTAL_COVE_REG_MIRQLVL1, | ||
150 | }; | ||
151 | |||
152 | struct intel_soc_pmic_config intel_soc_pmic_config_crc = { | ||
153 | .irq_flags = IRQF_TRIGGER_RISING, | ||
154 | .cell_dev = crystal_cove_dev, | ||
155 | .n_cell_devs = ARRAY_SIZE(crystal_cove_dev), | ||
156 | .regmap_config = &crystal_cove_regmap_config, | ||
157 | .irq_chip = &crystal_cove_irq_chip, | ||
158 | }; | ||
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c index 7e50fe0118e3..8df3266064e4 100644 --- a/drivers/mfd/ipaq-micro.c +++ b/drivers/mfd/ipaq-micro.c | |||
@@ -115,7 +115,7 @@ static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data) | |||
115 | } else { | 115 | } else { |
116 | dev_err(micro->dev, | 116 | dev_err(micro->dev, |
117 | "out of band RX message 0x%02x\n", id); | 117 | "out of band RX message 0x%02x\n", id); |
118 | if(!micro->msg) | 118 | if (!micro->msg) |
119 | dev_info(micro->dev, "no message queued\n"); | 119 | dev_info(micro->dev, "no message queued\n"); |
120 | else | 120 | else |
121 | dev_info(micro->dev, "expected message %02x\n", | 121 | dev_info(micro->dev, "expected message %02x\n", |
@@ -126,13 +126,13 @@ static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data) | |||
126 | if (micro->key) | 126 | if (micro->key) |
127 | micro->key(micro->key_data, len, data); | 127 | micro->key(micro->key_data, len, data); |
128 | else | 128 | else |
129 | dev_dbg(micro->dev, "key message ignored, no handle \n"); | 129 | dev_dbg(micro->dev, "key message ignored, no handle\n"); |
130 | break; | 130 | break; |
131 | case MSG_TOUCHSCREEN: | 131 | case MSG_TOUCHSCREEN: |
132 | if (micro->ts) | 132 | if (micro->ts) |
133 | micro->ts(micro->ts_data, len, data); | 133 | micro->ts(micro->ts_data, len, data); |
134 | else | 134 | else |
135 | dev_dbg(micro->dev, "touchscreen message ignored, no handle \n"); | 135 | dev_dbg(micro->dev, "touchscreen message ignored, no handle\n"); |
136 | break; | 136 | break; |
137 | default: | 137 | default: |
138 | dev_err(micro->dev, | 138 | dev_err(micro->dev, |
@@ -154,7 +154,7 @@ static void micro_process_char(struct ipaq_micro *micro, u8 ch) | |||
154 | rx->state = STATE_ID; /* Next byte is the id and len */ | 154 | rx->state = STATE_ID; /* Next byte is the id and len */ |
155 | break; | 155 | break; |
156 | case STATE_ID: /* Looking for id and len byte */ | 156 | case STATE_ID: /* Looking for id and len byte */ |
157 | rx->id = (ch & 0xf0) >> 4 ; | 157 | rx->id = (ch & 0xf0) >> 4; |
158 | rx->len = (ch & 0x0f); | 158 | rx->len = (ch & 0x0f); |
159 | rx->index = 0; | 159 | rx->index = 0; |
160 | rx->chksum = ch; | 160 | rx->chksum = ch; |
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index f7ff0188603d..bd2696136eee 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c | |||
@@ -24,7 +24,8 @@ | |||
24 | 24 | ||
25 | #define MAX_ID_LEN 4 | 25 | #define MAX_ID_LEN 4 |
26 | static char force_device_id[MAX_ID_LEN + 1] = ""; | 26 | static char force_device_id[MAX_ID_LEN + 1] = ""; |
27 | module_param_string(force_device_id, force_device_id, sizeof(force_device_id), 0); | 27 | module_param_string(force_device_id, force_device_id, |
28 | sizeof(force_device_id), 0); | ||
28 | MODULE_PARM_DESC(force_device_id, "Override detected product"); | 29 | MODULE_PARM_DESC(force_device_id, "Override detected product"); |
29 | 30 | ||
30 | /* | 31 | /* |
@@ -36,7 +37,7 @@ static void kempld_get_hardware_mutex(struct kempld_device_data *pld) | |||
36 | { | 37 | { |
37 | /* The mutex bit will read 1 until access has been granted */ | 38 | /* The mutex bit will read 1 until access has been granted */ |
38 | while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY) | 39 | while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY) |
39 | msleep(1); | 40 | usleep_range(1000, 3000); |
40 | } | 41 | } |
41 | 42 | ||
42 | static void kempld_release_hardware_mutex(struct kempld_device_data *pld) | 43 | static void kempld_release_hardware_mutex(struct kempld_device_data *pld) |
@@ -499,7 +500,7 @@ static struct platform_driver kempld_driver = { | |||
499 | .remove = kempld_remove, | 500 | .remove = kempld_remove, |
500 | }; | 501 | }; |
501 | 502 | ||
502 | static struct dmi_system_id __initdata kempld_dmi_table[] = { | 503 | static struct dmi_system_id kempld_dmi_table[] __initdata = { |
503 | { | 504 | { |
504 | .ident = "BHL6", | 505 | .ident = "BHL6", |
505 | .matches = { | 506 | .matches = { |
@@ -736,7 +737,8 @@ static int __init kempld_init(void) | |||
736 | int ret; | 737 | int ret; |
737 | 738 | ||
738 | if (force_device_id[0]) { | 739 | if (force_device_id[0]) { |
739 | for (id = kempld_dmi_table; id->matches[0].slot != DMI_NONE; id++) | 740 | for (id = kempld_dmi_table; |
741 | id->matches[0].slot != DMI_NONE; id++) | ||
740 | if (strstr(id->ident, force_device_id)) | 742 | if (strstr(id->ident, force_device_id)) |
741 | if (id->callback && id->callback(id)) | 743 | if (id->callback && id->callback(id)) |
742 | break; | 744 | break; |
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c index c84ded5f8ece..23982dbf014d 100644 --- a/drivers/mfd/lp8788-irq.c +++ b/drivers/mfd/lp8788-irq.c | |||
@@ -66,12 +66,14 @@ static inline u8 _irq_to_val(enum lp8788_int_id id, int enable) | |||
66 | static void lp8788_irq_enable(struct irq_data *data) | 66 | static void lp8788_irq_enable(struct irq_data *data) |
67 | { | 67 | { |
68 | struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data); | 68 | struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data); |
69 | |||
69 | irqd->enabled[data->hwirq] = 1; | 70 | irqd->enabled[data->hwirq] = 1; |
70 | } | 71 | } |
71 | 72 | ||
72 | static void lp8788_irq_disable(struct irq_data *data) | 73 | static void lp8788_irq_disable(struct irq_data *data) |
73 | { | 74 | { |
74 | struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data); | 75 | struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data); |
76 | |||
75 | irqd->enabled[data->hwirq] = 0; | 77 | irqd->enabled[data->hwirq] = 0; |
76 | } | 78 | } |
77 | 79 | ||
diff --git a/drivers/mfd/max77686-irq.c b/drivers/mfd/max77686-irq.c deleted file mode 100644 index cdc3280e2ec7..000000000000 --- a/drivers/mfd/max77686-irq.c +++ /dev/null | |||
@@ -1,319 +0,0 @@ | |||
1 | /* | ||
2 | * max77686-irq.c - Interrupt controller support for MAX77686 | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electronics Co.Ltd | ||
5 | * Chiwoong Byun <woong.byun@samsung.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 | * 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 | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | * This driver is based on max8997-irq.c | ||
22 | */ | ||
23 | |||
24 | #include <linux/err.h> | ||
25 | #include <linux/irq.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/mfd/max77686.h> | ||
29 | #include <linux/mfd/max77686-private.h> | ||
30 | #include <linux/irqdomain.h> | ||
31 | #include <linux/regmap.h> | ||
32 | |||
33 | enum { | ||
34 | MAX77686_DEBUG_IRQ_INFO = 1 << 0, | ||
35 | MAX77686_DEBUG_IRQ_MASK = 1 << 1, | ||
36 | MAX77686_DEBUG_IRQ_INT = 1 << 2, | ||
37 | }; | ||
38 | |||
39 | static int debug_mask = 0; | ||
40 | module_param(debug_mask, int, 0); | ||
41 | MODULE_PARM_DESC(debug_mask, "Set debug_mask : 0x0=off 0x1=IRQ_INFO 0x2=IRQ_MASK 0x4=IRQ_INI)"); | ||
42 | |||
43 | static const u8 max77686_mask_reg[] = { | ||
44 | [PMIC_INT1] = MAX77686_REG_INT1MSK, | ||
45 | [PMIC_INT2] = MAX77686_REG_INT2MSK, | ||
46 | [RTC_INT] = MAX77686_RTC_INTM, | ||
47 | }; | ||
48 | |||
49 | static struct regmap *max77686_get_regmap(struct max77686_dev *max77686, | ||
50 | enum max77686_irq_source src) | ||
51 | { | ||
52 | switch (src) { | ||
53 | case PMIC_INT1 ... PMIC_INT2: | ||
54 | return max77686->regmap; | ||
55 | case RTC_INT: | ||
56 | return max77686->rtc_regmap; | ||
57 | default: | ||
58 | return ERR_PTR(-EINVAL); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | struct max77686_irq_data { | ||
63 | int mask; | ||
64 | enum max77686_irq_source group; | ||
65 | }; | ||
66 | |||
67 | #define DECLARE_IRQ(idx, _group, _mask) \ | ||
68 | [(idx)] = { .group = (_group), .mask = (_mask) } | ||
69 | static const struct max77686_irq_data max77686_irqs[] = { | ||
70 | DECLARE_IRQ(MAX77686_PMICIRQ_PWRONF, PMIC_INT1, 1 << 0), | ||
71 | DECLARE_IRQ(MAX77686_PMICIRQ_PWRONR, PMIC_INT1, 1 << 1), | ||
72 | DECLARE_IRQ(MAX77686_PMICIRQ_JIGONBF, PMIC_INT1, 1 << 2), | ||
73 | DECLARE_IRQ(MAX77686_PMICIRQ_JIGONBR, PMIC_INT1, 1 << 3), | ||
74 | DECLARE_IRQ(MAX77686_PMICIRQ_ACOKBF, PMIC_INT1, 1 << 4), | ||
75 | DECLARE_IRQ(MAX77686_PMICIRQ_ACOKBR, PMIC_INT1, 1 << 5), | ||
76 | DECLARE_IRQ(MAX77686_PMICIRQ_ONKEY1S, PMIC_INT1, 1 << 6), | ||
77 | DECLARE_IRQ(MAX77686_PMICIRQ_MRSTB, PMIC_INT1, 1 << 7), | ||
78 | DECLARE_IRQ(MAX77686_PMICIRQ_140C, PMIC_INT2, 1 << 0), | ||
79 | DECLARE_IRQ(MAX77686_PMICIRQ_120C, PMIC_INT2, 1 << 1), | ||
80 | DECLARE_IRQ(MAX77686_RTCIRQ_RTC60S, RTC_INT, 1 << 0), | ||
81 | DECLARE_IRQ(MAX77686_RTCIRQ_RTCA1, RTC_INT, 1 << 1), | ||
82 | DECLARE_IRQ(MAX77686_RTCIRQ_RTCA2, RTC_INT, 1 << 2), | ||
83 | DECLARE_IRQ(MAX77686_RTCIRQ_SMPL, RTC_INT, 1 << 3), | ||
84 | DECLARE_IRQ(MAX77686_RTCIRQ_RTC1S, RTC_INT, 1 << 4), | ||
85 | DECLARE_IRQ(MAX77686_RTCIRQ_WTSR, RTC_INT, 1 << 5), | ||
86 | }; | ||
87 | |||
88 | static void max77686_irq_lock(struct irq_data *data) | ||
89 | { | ||
90 | struct max77686_dev *max77686 = irq_get_chip_data(data->irq); | ||
91 | |||
92 | if (debug_mask & MAX77686_DEBUG_IRQ_MASK) | ||
93 | pr_info("%s\n", __func__); | ||
94 | |||
95 | mutex_lock(&max77686->irqlock); | ||
96 | } | ||
97 | |||
98 | static void max77686_irq_sync_unlock(struct irq_data *data) | ||
99 | { | ||
100 | struct max77686_dev *max77686 = irq_get_chip_data(data->irq); | ||
101 | int i; | ||
102 | |||
103 | for (i = 0; i < MAX77686_IRQ_GROUP_NR; i++) { | ||
104 | u8 mask_reg = max77686_mask_reg[i]; | ||
105 | struct regmap *map = max77686_get_regmap(max77686, i); | ||
106 | |||
107 | if (debug_mask & MAX77686_DEBUG_IRQ_MASK) | ||
108 | pr_debug("%s: mask_reg[%d]=0x%x, cur=0x%x\n", | ||
109 | __func__, i, mask_reg, max77686->irq_masks_cur[i]); | ||
110 | |||
111 | if (mask_reg == MAX77686_REG_INVALID || | ||
112 | IS_ERR_OR_NULL(map)) | ||
113 | continue; | ||
114 | |||
115 | max77686->irq_masks_cache[i] = max77686->irq_masks_cur[i]; | ||
116 | |||
117 | regmap_write(map, max77686_mask_reg[i], | ||
118 | max77686->irq_masks_cur[i]); | ||
119 | } | ||
120 | |||
121 | mutex_unlock(&max77686->irqlock); | ||
122 | } | ||
123 | |||
124 | static const inline struct max77686_irq_data *to_max77686_irq(int irq) | ||
125 | { | ||
126 | struct irq_data *data = irq_get_irq_data(irq); | ||
127 | return &max77686_irqs[data->hwirq]; | ||
128 | } | ||
129 | |||
130 | static void max77686_irq_mask(struct irq_data *data) | ||
131 | { | ||
132 | struct max77686_dev *max77686 = irq_get_chip_data(data->irq); | ||
133 | const struct max77686_irq_data *irq_data = to_max77686_irq(data->irq); | ||
134 | |||
135 | max77686->irq_masks_cur[irq_data->group] |= irq_data->mask; | ||
136 | |||
137 | if (debug_mask & MAX77686_DEBUG_IRQ_MASK) | ||
138 | pr_info("%s: group=%d, cur=0x%x\n", | ||
139 | __func__, irq_data->group, | ||
140 | max77686->irq_masks_cur[irq_data->group]); | ||
141 | } | ||
142 | |||
143 | static void max77686_irq_unmask(struct irq_data *data) | ||
144 | { | ||
145 | struct max77686_dev *max77686 = irq_get_chip_data(data->irq); | ||
146 | const struct max77686_irq_data *irq_data = to_max77686_irq(data->irq); | ||
147 | |||
148 | max77686->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | ||
149 | |||
150 | if (debug_mask & MAX77686_DEBUG_IRQ_MASK) | ||
151 | pr_info("%s: group=%d, cur=0x%x\n", | ||
152 | __func__, irq_data->group, | ||
153 | max77686->irq_masks_cur[irq_data->group]); | ||
154 | } | ||
155 | |||
156 | static struct irq_chip max77686_irq_chip = { | ||
157 | .name = "max77686", | ||
158 | .irq_bus_lock = max77686_irq_lock, | ||
159 | .irq_bus_sync_unlock = max77686_irq_sync_unlock, | ||
160 | .irq_mask = max77686_irq_mask, | ||
161 | .irq_unmask = max77686_irq_unmask, | ||
162 | }; | ||
163 | |||
164 | static irqreturn_t max77686_irq_thread(int irq, void *data) | ||
165 | { | ||
166 | struct max77686_dev *max77686 = data; | ||
167 | unsigned int irq_reg[MAX77686_IRQ_GROUP_NR] = {}; | ||
168 | unsigned int irq_src; | ||
169 | int ret; | ||
170 | int i, cur_irq; | ||
171 | |||
172 | ret = regmap_read(max77686->regmap, MAX77686_REG_INTSRC, &irq_src); | ||
173 | if (ret < 0) { | ||
174 | dev_err(max77686->dev, "Failed to read interrupt source: %d\n", | ||
175 | ret); | ||
176 | return IRQ_NONE; | ||
177 | } | ||
178 | |||
179 | if (debug_mask & MAX77686_DEBUG_IRQ_INT) | ||
180 | pr_info("%s: irq_src=0x%x\n", __func__, irq_src); | ||
181 | |||
182 | if (irq_src == MAX77686_IRQSRC_PMIC) { | ||
183 | ret = regmap_bulk_read(max77686->regmap, | ||
184 | MAX77686_REG_INT1, irq_reg, 2); | ||
185 | if (ret < 0) { | ||
186 | dev_err(max77686->dev, "Failed to read interrupt source: %d\n", | ||
187 | ret); | ||
188 | return IRQ_NONE; | ||
189 | } | ||
190 | |||
191 | if (debug_mask & MAX77686_DEBUG_IRQ_INT) | ||
192 | pr_info("%s: int1=0x%x, int2=0x%x\n", __func__, | ||
193 | irq_reg[PMIC_INT1], irq_reg[PMIC_INT2]); | ||
194 | } | ||
195 | |||
196 | if (irq_src & MAX77686_IRQSRC_RTC) { | ||
197 | ret = regmap_read(max77686->rtc_regmap, | ||
198 | MAX77686_RTC_INT, &irq_reg[RTC_INT]); | ||
199 | if (ret < 0) { | ||
200 | dev_err(max77686->dev, "Failed to read interrupt source: %d\n", | ||
201 | ret); | ||
202 | return IRQ_NONE; | ||
203 | } | ||
204 | |||
205 | if (debug_mask & MAX77686_DEBUG_IRQ_INT) | ||
206 | pr_info("%s: rtc int=0x%x\n", __func__, | ||
207 | irq_reg[RTC_INT]); | ||
208 | |||
209 | } | ||
210 | |||
211 | for (i = 0; i < MAX77686_IRQ_GROUP_NR; i++) | ||
212 | irq_reg[i] &= ~max77686->irq_masks_cur[i]; | ||
213 | |||
214 | for (i = 0; i < MAX77686_IRQ_NR; i++) { | ||
215 | if (irq_reg[max77686_irqs[i].group] & max77686_irqs[i].mask) { | ||
216 | cur_irq = irq_find_mapping(max77686->irq_domain, i); | ||
217 | if (cur_irq) | ||
218 | handle_nested_irq(cur_irq); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | return IRQ_HANDLED; | ||
223 | } | ||
224 | |||
225 | static int max77686_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
226 | irq_hw_number_t hw) | ||
227 | { | ||
228 | struct max77686_dev *max77686 = d->host_data; | ||
229 | |||
230 | irq_set_chip_data(irq, max77686); | ||
231 | irq_set_chip_and_handler(irq, &max77686_irq_chip, handle_edge_irq); | ||
232 | irq_set_nested_thread(irq, 1); | ||
233 | #ifdef CONFIG_ARM | ||
234 | set_irq_flags(irq, IRQF_VALID); | ||
235 | #else | ||
236 | irq_set_noprobe(irq); | ||
237 | #endif | ||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static struct irq_domain_ops max77686_irq_domain_ops = { | ||
242 | .map = max77686_irq_domain_map, | ||
243 | }; | ||
244 | |||
245 | int max77686_irq_init(struct max77686_dev *max77686) | ||
246 | { | ||
247 | struct irq_domain *domain; | ||
248 | int i; | ||
249 | int ret; | ||
250 | int val; | ||
251 | struct regmap *map; | ||
252 | |||
253 | mutex_init(&max77686->irqlock); | ||
254 | |||
255 | if (max77686->irq_gpio && !max77686->irq) { | ||
256 | max77686->irq = gpio_to_irq(max77686->irq_gpio); | ||
257 | |||
258 | if (debug_mask & MAX77686_DEBUG_IRQ_INT) { | ||
259 | ret = gpio_request(max77686->irq_gpio, "pmic_irq"); | ||
260 | if (ret < 0) { | ||
261 | dev_err(max77686->dev, | ||
262 | "Failed to request gpio %d with ret:" | ||
263 | "%d\n", max77686->irq_gpio, ret); | ||
264 | return IRQ_NONE; | ||
265 | } | ||
266 | |||
267 | gpio_direction_input(max77686->irq_gpio); | ||
268 | val = gpio_get_value(max77686->irq_gpio); | ||
269 | gpio_free(max77686->irq_gpio); | ||
270 | pr_info("%s: gpio_irq=%x\n", __func__, val); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | if (!max77686->irq) { | ||
275 | dev_err(max77686->dev, "irq is not specified\n"); | ||
276 | return -ENODEV; | ||
277 | } | ||
278 | |||
279 | /* Mask individual interrupt sources */ | ||
280 | for (i = 0; i < MAX77686_IRQ_GROUP_NR; i++) { | ||
281 | max77686->irq_masks_cur[i] = 0xff; | ||
282 | max77686->irq_masks_cache[i] = 0xff; | ||
283 | map = max77686_get_regmap(max77686, i); | ||
284 | |||
285 | if (IS_ERR_OR_NULL(map)) | ||
286 | continue; | ||
287 | if (max77686_mask_reg[i] == MAX77686_REG_INVALID) | ||
288 | continue; | ||
289 | |||
290 | regmap_write(map, max77686_mask_reg[i], 0xff); | ||
291 | } | ||
292 | domain = irq_domain_add_linear(NULL, MAX77686_IRQ_NR, | ||
293 | &max77686_irq_domain_ops, max77686); | ||
294 | if (!domain) { | ||
295 | dev_err(max77686->dev, "could not create irq domain\n"); | ||
296 | return -ENODEV; | ||
297 | } | ||
298 | max77686->irq_domain = domain; | ||
299 | |||
300 | ret = request_threaded_irq(max77686->irq, NULL, max77686_irq_thread, | ||
301 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
302 | "max77686-irq", max77686); | ||
303 | |||
304 | if (ret) | ||
305 | dev_err(max77686->dev, "Failed to request IRQ %d: %d\n", | ||
306 | max77686->irq, ret); | ||
307 | |||
308 | |||
309 | if (debug_mask & MAX77686_DEBUG_IRQ_INFO) | ||
310 | pr_info("%s-\n", __func__); | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | void max77686_irq_exit(struct max77686_dev *max77686) | ||
316 | { | ||
317 | if (max77686->irq) | ||
318 | free_irq(max77686->irq, max77686); | ||
319 | } | ||
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index ce869acf27ae..86e552348db4 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * max77686.c - mfd core driver for the Maxim 77686 | 2 | * max77686.c - mfd core driver for the Maxim 77686/802 |
3 | * | 3 | * |
4 | * Copyright (C) 2012 Samsung Electronics | 4 | * Copyright (C) 2012 Samsung Electronics |
5 | * Chiwoong Byun <woong.byun@smasung.com> | 5 | * Chiwoong Byun <woong.byun@smasung.com> |
@@ -25,6 +25,8 @@ | |||
25 | #include <linux/export.h> | 25 | #include <linux/export.h> |
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/irq.h> | ||
29 | #include <linux/interrupt.h> | ||
28 | #include <linux/pm_runtime.h> | 30 | #include <linux/pm_runtime.h> |
29 | #include <linux/module.h> | 31 | #include <linux/module.h> |
30 | #include <linux/mfd/core.h> | 32 | #include <linux/mfd/core.h> |
@@ -41,15 +43,166 @@ static const struct mfd_cell max77686_devs[] = { | |||
41 | { .name = "max77686-clk", }, | 43 | { .name = "max77686-clk", }, |
42 | }; | 44 | }; |
43 | 45 | ||
46 | static const struct mfd_cell max77802_devs[] = { | ||
47 | { .name = "max77802-pmic", }, | ||
48 | { .name = "max77802-clk", }, | ||
49 | { .name = "max77802-rtc", }, | ||
50 | }; | ||
51 | |||
52 | static bool max77802_pmic_is_accessible_reg(struct device *dev, | ||
53 | unsigned int reg) | ||
54 | { | ||
55 | return (reg >= MAX77802_REG_DEVICE_ID && reg < MAX77802_REG_PMIC_END); | ||
56 | } | ||
57 | |||
58 | static bool max77802_rtc_is_accessible_reg(struct device *dev, | ||
59 | unsigned int reg) | ||
60 | { | ||
61 | return (reg >= MAX77802_RTC_INT && reg < MAX77802_RTC_END); | ||
62 | } | ||
63 | |||
64 | static bool max77802_is_accessible_reg(struct device *dev, unsigned int reg) | ||
65 | { | ||
66 | return (max77802_pmic_is_accessible_reg(dev, reg) || | ||
67 | max77802_rtc_is_accessible_reg(dev, reg)); | ||
68 | } | ||
69 | |||
70 | static bool max77802_pmic_is_precious_reg(struct device *dev, unsigned int reg) | ||
71 | { | ||
72 | return (reg == MAX77802_REG_INTSRC || reg == MAX77802_REG_INT1 || | ||
73 | reg == MAX77802_REG_INT2); | ||
74 | } | ||
75 | |||
76 | static bool max77802_rtc_is_precious_reg(struct device *dev, unsigned int reg) | ||
77 | { | ||
78 | return (reg == MAX77802_RTC_INT || | ||
79 | reg == MAX77802_RTC_UPDATE0 || | ||
80 | reg == MAX77802_RTC_UPDATE1); | ||
81 | } | ||
82 | |||
83 | static bool max77802_is_precious_reg(struct device *dev, unsigned int reg) | ||
84 | { | ||
85 | return (max77802_pmic_is_precious_reg(dev, reg) || | ||
86 | max77802_rtc_is_precious_reg(dev, reg)); | ||
87 | } | ||
88 | |||
89 | static bool max77802_pmic_is_volatile_reg(struct device *dev, unsigned int reg) | ||
90 | { | ||
91 | return (max77802_is_precious_reg(dev, reg) || | ||
92 | reg == MAX77802_REG_STATUS1 || reg == MAX77802_REG_STATUS2 || | ||
93 | reg == MAX77802_REG_PWRON); | ||
94 | } | ||
95 | |||
96 | static bool max77802_rtc_is_volatile_reg(struct device *dev, unsigned int reg) | ||
97 | { | ||
98 | return (max77802_rtc_is_precious_reg(dev, reg) || | ||
99 | reg == MAX77802_RTC_SEC || | ||
100 | reg == MAX77802_RTC_MIN || | ||
101 | reg == MAX77802_RTC_HOUR || | ||
102 | reg == MAX77802_RTC_WEEKDAY || | ||
103 | reg == MAX77802_RTC_MONTH || | ||
104 | reg == MAX77802_RTC_YEAR || | ||
105 | reg == MAX77802_RTC_DATE); | ||
106 | } | ||
107 | |||
108 | static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg) | ||
109 | { | ||
110 | return (max77802_pmic_is_volatile_reg(dev, reg) || | ||
111 | max77802_rtc_is_volatile_reg(dev, reg)); | ||
112 | } | ||
113 | |||
44 | static struct regmap_config max77686_regmap_config = { | 114 | static struct regmap_config max77686_regmap_config = { |
45 | .reg_bits = 8, | 115 | .reg_bits = 8, |
46 | .val_bits = 8, | 116 | .val_bits = 8, |
47 | }; | 117 | }; |
48 | 118 | ||
49 | #ifdef CONFIG_OF | 119 | static struct regmap_config max77686_rtc_regmap_config = { |
120 | .reg_bits = 8, | ||
121 | .val_bits = 8, | ||
122 | }; | ||
123 | |||
124 | static struct regmap_config max77802_regmap_config = { | ||
125 | .reg_bits = 8, | ||
126 | .val_bits = 8, | ||
127 | .writeable_reg = max77802_is_accessible_reg, | ||
128 | .readable_reg = max77802_is_accessible_reg, | ||
129 | .precious_reg = max77802_is_precious_reg, | ||
130 | .volatile_reg = max77802_is_volatile_reg, | ||
131 | .name = "max77802-pmic", | ||
132 | .cache_type = REGCACHE_RBTREE, | ||
133 | }; | ||
134 | |||
135 | static const struct regmap_irq max77686_irqs[] = { | ||
136 | /* INT1 interrupts */ | ||
137 | { .reg_offset = 0, .mask = MAX77686_INT1_PWRONF_MSK, }, | ||
138 | { .reg_offset = 0, .mask = MAX77686_INT1_PWRONR_MSK, }, | ||
139 | { .reg_offset = 0, .mask = MAX77686_INT1_JIGONBF_MSK, }, | ||
140 | { .reg_offset = 0, .mask = MAX77686_INT1_JIGONBR_MSK, }, | ||
141 | { .reg_offset = 0, .mask = MAX77686_INT1_ACOKBF_MSK, }, | ||
142 | { .reg_offset = 0, .mask = MAX77686_INT1_ACOKBR_MSK, }, | ||
143 | { .reg_offset = 0, .mask = MAX77686_INT1_ONKEY1S_MSK, }, | ||
144 | { .reg_offset = 0, .mask = MAX77686_INT1_MRSTB_MSK, }, | ||
145 | /* INT2 interrupts */ | ||
146 | { .reg_offset = 1, .mask = MAX77686_INT2_140C_MSK, }, | ||
147 | { .reg_offset = 1, .mask = MAX77686_INT2_120C_MSK, }, | ||
148 | }; | ||
149 | |||
150 | static const struct regmap_irq_chip max77686_irq_chip = { | ||
151 | .name = "max77686-pmic", | ||
152 | .status_base = MAX77686_REG_INT1, | ||
153 | .mask_base = MAX77686_REG_INT1MSK, | ||
154 | .num_regs = 2, | ||
155 | .irqs = max77686_irqs, | ||
156 | .num_irqs = ARRAY_SIZE(max77686_irqs), | ||
157 | }; | ||
158 | |||
159 | static const struct regmap_irq max77686_rtc_irqs[] = { | ||
160 | /* RTC interrupts */ | ||
161 | { .reg_offset = 0, .mask = MAX77686_RTCINT_RTC60S_MSK, }, | ||
162 | { .reg_offset = 0, .mask = MAX77686_RTCINT_RTCA1_MSK, }, | ||
163 | { .reg_offset = 0, .mask = MAX77686_RTCINT_RTCA2_MSK, }, | ||
164 | { .reg_offset = 0, .mask = MAX77686_RTCINT_SMPL_MSK, }, | ||
165 | { .reg_offset = 0, .mask = MAX77686_RTCINT_RTC1S_MSK, }, | ||
166 | { .reg_offset = 0, .mask = MAX77686_RTCINT_WTSR_MSK, }, | ||
167 | }; | ||
168 | |||
169 | static const struct regmap_irq_chip max77686_rtc_irq_chip = { | ||
170 | .name = "max77686-rtc", | ||
171 | .status_base = MAX77686_RTC_INT, | ||
172 | .mask_base = MAX77686_RTC_INTM, | ||
173 | .num_regs = 1, | ||
174 | .irqs = max77686_rtc_irqs, | ||
175 | .num_irqs = ARRAY_SIZE(max77686_rtc_irqs), | ||
176 | }; | ||
177 | |||
178 | static const struct regmap_irq_chip max77802_irq_chip = { | ||
179 | .name = "max77802-pmic", | ||
180 | .status_base = MAX77802_REG_INT1, | ||
181 | .mask_base = MAX77802_REG_INT1MSK, | ||
182 | .num_regs = 2, | ||
183 | .irqs = max77686_irqs, /* same masks as 77686 */ | ||
184 | .num_irqs = ARRAY_SIZE(max77686_irqs), | ||
185 | }; | ||
186 | |||
187 | static const struct regmap_irq_chip max77802_rtc_irq_chip = { | ||
188 | .name = "max77802-rtc", | ||
189 | .status_base = MAX77802_RTC_INT, | ||
190 | .mask_base = MAX77802_RTC_INTM, | ||
191 | .num_regs = 1, | ||
192 | .irqs = max77686_rtc_irqs, /* same masks as 77686 */ | ||
193 | .num_irqs = ARRAY_SIZE(max77686_rtc_irqs), | ||
194 | }; | ||
195 | |||
50 | static const struct of_device_id max77686_pmic_dt_match[] = { | 196 | static const struct of_device_id max77686_pmic_dt_match[] = { |
51 | {.compatible = "maxim,max77686", .data = NULL}, | 197 | { |
52 | {}, | 198 | .compatible = "maxim,max77686", |
199 | .data = (void *)TYPE_MAX77686, | ||
200 | }, | ||
201 | { | ||
202 | .compatible = "maxim,max77802", | ||
203 | .data = (void *)TYPE_MAX77802, | ||
204 | }, | ||
205 | { }, | ||
53 | }; | 206 | }; |
54 | 207 | ||
55 | static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device | 208 | static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device |
@@ -58,53 +211,74 @@ static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device | |||
58 | struct max77686_platform_data *pd; | 211 | struct max77686_platform_data *pd; |
59 | 212 | ||
60 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); | 213 | pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); |
61 | if (!pd) { | 214 | if (!pd) |
62 | dev_err(dev, "could not allocate memory for pdata\n"); | ||
63 | return NULL; | 215 | return NULL; |
64 | } | ||
65 | 216 | ||
66 | dev->platform_data = pd; | 217 | dev->platform_data = pd; |
67 | return pd; | 218 | return pd; |
68 | } | 219 | } |
69 | #else | ||
70 | static struct max77686_platform_data *max77686_i2c_parse_dt_pdata(struct device | ||
71 | *dev) | ||
72 | { | ||
73 | return 0; | ||
74 | } | ||
75 | #endif | ||
76 | 220 | ||
77 | static int max77686_i2c_probe(struct i2c_client *i2c, | 221 | static int max77686_i2c_probe(struct i2c_client *i2c, |
78 | const struct i2c_device_id *id) | 222 | const struct i2c_device_id *id) |
79 | { | 223 | { |
80 | struct max77686_dev *max77686 = NULL; | 224 | struct max77686_dev *max77686 = NULL; |
81 | struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev); | 225 | struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev); |
226 | const struct of_device_id *match; | ||
82 | unsigned int data; | 227 | unsigned int data; |
83 | int ret = 0; | 228 | int ret = 0; |
229 | const struct regmap_config *config; | ||
230 | const struct regmap_irq_chip *irq_chip; | ||
231 | const struct regmap_irq_chip *rtc_irq_chip; | ||
232 | struct regmap **rtc_regmap; | ||
233 | const struct mfd_cell *cells; | ||
234 | int n_devs; | ||
84 | 235 | ||
85 | if (i2c->dev.of_node) | 236 | if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node && !pdata) |
86 | pdata = max77686_i2c_parse_dt_pdata(&i2c->dev); | 237 | pdata = max77686_i2c_parse_dt_pdata(&i2c->dev); |
87 | 238 | ||
88 | if (!pdata) { | 239 | if (!pdata) { |
89 | dev_err(&i2c->dev, "No platform data found.\n"); | 240 | dev_err(&i2c->dev, "No platform data found.\n"); |
90 | return -EIO; | 241 | return -EINVAL; |
91 | } | 242 | } |
92 | 243 | ||
93 | max77686 = devm_kzalloc(&i2c->dev, | 244 | max77686 = devm_kzalloc(&i2c->dev, |
94 | sizeof(struct max77686_dev), GFP_KERNEL); | 245 | sizeof(struct max77686_dev), GFP_KERNEL); |
95 | if (max77686 == NULL) | 246 | if (!max77686) |
96 | return -ENOMEM; | 247 | return -ENOMEM; |
97 | 248 | ||
249 | if (i2c->dev.of_node) { | ||
250 | match = of_match_node(max77686_pmic_dt_match, i2c->dev.of_node); | ||
251 | if (!match) | ||
252 | return -EINVAL; | ||
253 | |||
254 | max77686->type = (unsigned long)match->data; | ||
255 | } else | ||
256 | max77686->type = id->driver_data; | ||
257 | |||
98 | i2c_set_clientdata(i2c, max77686); | 258 | i2c_set_clientdata(i2c, max77686); |
99 | max77686->dev = &i2c->dev; | 259 | max77686->dev = &i2c->dev; |
100 | max77686->i2c = i2c; | 260 | max77686->i2c = i2c; |
101 | max77686->type = id->driver_data; | ||
102 | 261 | ||
103 | max77686->wakeup = pdata->wakeup; | 262 | max77686->wakeup = pdata->wakeup; |
104 | max77686->irq_gpio = pdata->irq_gpio; | ||
105 | max77686->irq = i2c->irq; | 263 | max77686->irq = i2c->irq; |
106 | 264 | ||
107 | max77686->regmap = devm_regmap_init_i2c(i2c, &max77686_regmap_config); | 265 | if (max77686->type == TYPE_MAX77686) { |
266 | config = &max77686_regmap_config; | ||
267 | irq_chip = &max77686_irq_chip; | ||
268 | rtc_irq_chip = &max77686_rtc_irq_chip; | ||
269 | rtc_regmap = &max77686->rtc_regmap; | ||
270 | cells = max77686_devs; | ||
271 | n_devs = ARRAY_SIZE(max77686_devs); | ||
272 | } else { | ||
273 | config = &max77802_regmap_config; | ||
274 | irq_chip = &max77802_irq_chip; | ||
275 | rtc_irq_chip = &max77802_rtc_irq_chip; | ||
276 | rtc_regmap = &max77686->regmap; | ||
277 | cells = max77802_devs; | ||
278 | n_devs = ARRAY_SIZE(max77802_devs); | ||
279 | } | ||
280 | |||
281 | max77686->regmap = devm_regmap_init_i2c(i2c, config); | ||
108 | if (IS_ERR(max77686->regmap)) { | 282 | if (IS_ERR(max77686->regmap)) { |
109 | ret = PTR_ERR(max77686->regmap); | 283 | ret = PTR_ERR(max77686->regmap); |
110 | dev_err(max77686->dev, "Failed to allocate register map: %d\n", | 284 | dev_err(max77686->dev, "Failed to allocate register map: %d\n", |
@@ -112,30 +286,68 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
112 | return ret; | 286 | return ret; |
113 | } | 287 | } |
114 | 288 | ||
115 | if (regmap_read(max77686->regmap, | 289 | ret = regmap_read(max77686->regmap, MAX77686_REG_DEVICE_ID, &data); |
116 | MAX77686_REG_DEVICE_ID, &data) < 0) { | 290 | if (ret < 0) { |
117 | dev_err(max77686->dev, | 291 | dev_err(max77686->dev, |
118 | "device not found on this channel (this is not an error)\n"); | 292 | "device not found on this channel (this is not an error)\n"); |
119 | return -ENODEV; | 293 | return -ENODEV; |
120 | } else | 294 | } |
121 | dev_info(max77686->dev, "device found\n"); | ||
122 | 295 | ||
123 | max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); | 296 | if (max77686->type == TYPE_MAX77686) { |
124 | if (!max77686->rtc) { | 297 | max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); |
125 | dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n"); | 298 | if (!max77686->rtc) { |
126 | return -ENODEV; | 299 | dev_err(max77686->dev, |
300 | "Failed to allocate I2C device for RTC\n"); | ||
301 | return -ENODEV; | ||
302 | } | ||
303 | i2c_set_clientdata(max77686->rtc, max77686); | ||
304 | |||
305 | max77686->rtc_regmap = | ||
306 | devm_regmap_init_i2c(max77686->rtc, | ||
307 | &max77686_rtc_regmap_config); | ||
308 | if (IS_ERR(max77686->rtc_regmap)) { | ||
309 | ret = PTR_ERR(max77686->rtc_regmap); | ||
310 | dev_err(max77686->dev, | ||
311 | "failed to allocate RTC regmap: %d\n", | ||
312 | ret); | ||
313 | goto err_unregister_i2c; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | ret = regmap_add_irq_chip(max77686->regmap, max77686->irq, | ||
318 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT | | ||
319 | IRQF_SHARED, 0, irq_chip, | ||
320 | &max77686->irq_data); | ||
321 | if (ret) { | ||
322 | dev_err(&i2c->dev, "failed to add PMIC irq chip: %d\n", ret); | ||
323 | goto err_unregister_i2c; | ||
127 | } | 324 | } |
128 | i2c_set_clientdata(max77686->rtc, max77686); | ||
129 | 325 | ||
130 | max77686_irq_init(max77686); | 326 | ret = regmap_add_irq_chip(*rtc_regmap, max77686->irq, |
327 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT | | ||
328 | IRQF_SHARED, 0, rtc_irq_chip, | ||
329 | &max77686->rtc_irq_data); | ||
330 | if (ret) { | ||
331 | dev_err(&i2c->dev, "failed to add RTC irq chip: %d\n", ret); | ||
332 | goto err_del_irqc; | ||
333 | } | ||
131 | 334 | ||
132 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, | 335 | ret = mfd_add_devices(max77686->dev, -1, cells, n_devs, NULL, 0, NULL); |
133 | ARRAY_SIZE(max77686_devs), NULL, 0, NULL); | ||
134 | if (ret < 0) { | 336 | if (ret < 0) { |
135 | mfd_remove_devices(max77686->dev); | 337 | dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); |
136 | i2c_unregister_device(max77686->rtc); | 338 | goto err_del_rtc_irqc; |
137 | } | 339 | } |
138 | 340 | ||
341 | return 0; | ||
342 | |||
343 | err_del_rtc_irqc: | ||
344 | regmap_del_irq_chip(max77686->irq, max77686->rtc_irq_data); | ||
345 | err_del_irqc: | ||
346 | regmap_del_irq_chip(max77686->irq, max77686->irq_data); | ||
347 | err_unregister_i2c: | ||
348 | if (max77686->type == TYPE_MAX77686) | ||
349 | i2c_unregister_device(max77686->rtc); | ||
350 | |||
139 | return ret; | 351 | return ret; |
140 | } | 352 | } |
141 | 353 | ||
@@ -144,7 +356,12 @@ static int max77686_i2c_remove(struct i2c_client *i2c) | |||
144 | struct max77686_dev *max77686 = i2c_get_clientdata(i2c); | 356 | struct max77686_dev *max77686 = i2c_get_clientdata(i2c); |
145 | 357 | ||
146 | mfd_remove_devices(max77686->dev); | 358 | mfd_remove_devices(max77686->dev); |
147 | i2c_unregister_device(max77686->rtc); | 359 | |
360 | regmap_del_irq_chip(max77686->irq, max77686->rtc_irq_data); | ||
361 | regmap_del_irq_chip(max77686->irq, max77686->irq_data); | ||
362 | |||
363 | if (max77686->type == TYPE_MAX77686) | ||
364 | i2c_unregister_device(max77686->rtc); | ||
148 | 365 | ||
149 | return 0; | 366 | return 0; |
150 | } | 367 | } |
@@ -155,10 +372,50 @@ static const struct i2c_device_id max77686_i2c_id[] = { | |||
155 | }; | 372 | }; |
156 | MODULE_DEVICE_TABLE(i2c, max77686_i2c_id); | 373 | MODULE_DEVICE_TABLE(i2c, max77686_i2c_id); |
157 | 374 | ||
375 | #ifdef CONFIG_PM_SLEEP | ||
376 | static int max77686_suspend(struct device *dev) | ||
377 | { | ||
378 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
379 | struct max77686_dev *max77686 = i2c_get_clientdata(i2c); | ||
380 | |||
381 | if (device_may_wakeup(dev)) | ||
382 | enable_irq_wake(max77686->irq); | ||
383 | |||
384 | /* | ||
385 | * IRQ must be disabled during suspend because if it happens | ||
386 | * while suspended it will be handled before resuming I2C. | ||
387 | * | ||
388 | * When device is woken up from suspend (e.g. by RTC wake alarm), | ||
389 | * an interrupt occurs before resuming I2C bus controller. | ||
390 | * Interrupt handler tries to read registers but this read | ||
391 | * will fail because I2C is still suspended. | ||
392 | */ | ||
393 | disable_irq(max77686->irq); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static int max77686_resume(struct device *dev) | ||
399 | { | ||
400 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | ||
401 | struct max77686_dev *max77686 = i2c_get_clientdata(i2c); | ||
402 | |||
403 | if (device_may_wakeup(dev)) | ||
404 | disable_irq_wake(max77686->irq); | ||
405 | |||
406 | enable_irq(max77686->irq); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | #endif /* CONFIG_PM_SLEEP */ | ||
411 | |||
412 | static SIMPLE_DEV_PM_OPS(max77686_pm, max77686_suspend, max77686_resume); | ||
413 | |||
158 | static struct i2c_driver max77686_i2c_driver = { | 414 | static struct i2c_driver max77686_i2c_driver = { |
159 | .driver = { | 415 | .driver = { |
160 | .name = "max77686", | 416 | .name = "max77686", |
161 | .owner = THIS_MODULE, | 417 | .owner = THIS_MODULE, |
418 | .pm = &max77686_pm, | ||
162 | .of_match_table = of_match_ptr(max77686_pmic_dt_match), | 419 | .of_match_table = of_match_ptr(max77686_pmic_dt_match), |
163 | }, | 420 | }, |
164 | .probe = max77686_i2c_probe, | 421 | .probe = max77686_i2c_probe, |
@@ -179,6 +436,6 @@ static void __exit max77686_i2c_exit(void) | |||
179 | } | 436 | } |
180 | module_exit(max77686_i2c_exit); | 437 | module_exit(max77686_i2c_exit); |
181 | 438 | ||
182 | MODULE_DESCRIPTION("MAXIM 77686 multi-function core driver"); | 439 | MODULE_DESCRIPTION("MAXIM 77686/802 multi-function core driver"); |
183 | MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>"); | 440 | MODULE_AUTHOR("Chiwoong Byun <woong.byun@samsung.com>"); |
184 | MODULE_LICENSE("GPL"); | 441 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index f3faf0c45ddd..97a787ab3d51 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -624,6 +624,7 @@ static void max8925_irq_sync_unlock(struct irq_data *data) | |||
624 | static void max8925_irq_enable(struct irq_data *data) | 624 | static void max8925_irq_enable(struct irq_data *data) |
625 | { | 625 | { |
626 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); | 626 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
627 | |||
627 | max8925_irqs[data->irq - chip->irq_base].enable | 628 | max8925_irqs[data->irq - chip->irq_base].enable |
628 | = max8925_irqs[data->irq - chip->irq_base].offs; | 629 | = max8925_irqs[data->irq - chip->irq_base].offs; |
629 | } | 630 | } |
@@ -631,6 +632,7 @@ static void max8925_irq_enable(struct irq_data *data) | |||
631 | static void max8925_irq_disable(struct irq_data *data) | 632 | static void max8925_irq_disable(struct irq_data *data) |
632 | { | 633 | { |
633 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); | 634 | struct max8925_chip *chip = irq_data_get_irq_chip_data(data); |
635 | |||
634 | max8925_irqs[data->irq - chip->irq_base].enable = 0; | 636 | max8925_irqs[data->irq - chip->irq_base].enable = 0; |
635 | } | 637 | } |
636 | 638 | ||
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index a83eed5c15ca..ecbe78ead3b6 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c | |||
@@ -257,9 +257,11 @@ static struct i2c_driver max8925_driver = { | |||
257 | static int __init max8925_i2c_init(void) | 257 | static int __init max8925_i2c_init(void) |
258 | { | 258 | { |
259 | int ret; | 259 | int ret; |
260 | |||
260 | ret = i2c_add_driver(&max8925_driver); | 261 | ret = i2c_add_driver(&max8925_driver); |
261 | if (ret != 0) | 262 | if (ret != 0) |
262 | pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); | 263 | pr_err("Failed to register MAX8925 I2C driver: %d\n", ret); |
264 | |||
263 | return ret; | 265 | return ret; |
264 | } | 266 | } |
265 | subsys_initcall(max8925_i2c_init); | 267 | subsys_initcall(max8925_i2c_init); |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index acf5dd712eb2..2b6bc868cd3d 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -10,106 +10,18 @@ | |||
10 | * Free Software Foundation. | 10 | * Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/module.h> | 13 | #include <linux/module.h> |
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/mutex.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/mfd/core.h> | ||
19 | #include <linux/mfd/mc13xxx.h> | ||
20 | #include <linux/of.h> | 14 | #include <linux/of.h> |
21 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
22 | #include <linux/of_gpio.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mfd/core.h> | ||
23 | 18 | ||
24 | #include "mc13xxx.h" | 19 | #include "mc13xxx.h" |
25 | 20 | ||
26 | #define MC13XXX_IRQSTAT0 0 | 21 | #define MC13XXX_IRQSTAT0 0 |
27 | #define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) | ||
28 | #define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1) | ||
29 | #define MC13XXX_IRQSTAT0_TSI (1 << 2) | ||
30 | #define MC13783_IRQSTAT0_WHIGHI (1 << 3) | ||
31 | #define MC13783_IRQSTAT0_WLOWI (1 << 4) | ||
32 | #define MC13XXX_IRQSTAT0_CHGDETI (1 << 6) | ||
33 | #define MC13783_IRQSTAT0_CHGOVI (1 << 7) | ||
34 | #define MC13XXX_IRQSTAT0_CHGREVI (1 << 8) | ||
35 | #define MC13XXX_IRQSTAT0_CHGSHORTI (1 << 9) | ||
36 | #define MC13XXX_IRQSTAT0_CCCVI (1 << 10) | ||
37 | #define MC13XXX_IRQSTAT0_CHGCURRI (1 << 11) | ||
38 | #define MC13XXX_IRQSTAT0_BPONI (1 << 12) | ||
39 | #define MC13XXX_IRQSTAT0_LOBATLI (1 << 13) | ||
40 | #define MC13XXX_IRQSTAT0_LOBATHI (1 << 14) | ||
41 | #define MC13783_IRQSTAT0_UDPI (1 << 15) | ||
42 | #define MC13783_IRQSTAT0_USBI (1 << 16) | ||
43 | #define MC13783_IRQSTAT0_IDI (1 << 19) | ||
44 | #define MC13783_IRQSTAT0_SE1I (1 << 21) | ||
45 | #define MC13783_IRQSTAT0_CKDETI (1 << 22) | ||
46 | #define MC13783_IRQSTAT0_UDMI (1 << 23) | ||
47 | |||
48 | #define MC13XXX_IRQMASK0 1 | 22 | #define MC13XXX_IRQMASK0 1 |
49 | #define MC13XXX_IRQMASK0_ADCDONEM MC13XXX_IRQSTAT0_ADCDONEI | ||
50 | #define MC13XXX_IRQMASK0_ADCBISDONEM MC13XXX_IRQSTAT0_ADCBISDONEI | ||
51 | #define MC13XXX_IRQMASK0_TSM MC13XXX_IRQSTAT0_TSI | ||
52 | #define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI | ||
53 | #define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI | ||
54 | #define MC13XXX_IRQMASK0_CHGDETM MC13XXX_IRQSTAT0_CHGDETI | ||
55 | #define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI | ||
56 | #define MC13XXX_IRQMASK0_CHGREVM MC13XXX_IRQSTAT0_CHGREVI | ||
57 | #define MC13XXX_IRQMASK0_CHGSHORTM MC13XXX_IRQSTAT0_CHGSHORTI | ||
58 | #define MC13XXX_IRQMASK0_CCCVM MC13XXX_IRQSTAT0_CCCVI | ||
59 | #define MC13XXX_IRQMASK0_CHGCURRM MC13XXX_IRQSTAT0_CHGCURRI | ||
60 | #define MC13XXX_IRQMASK0_BPONM MC13XXX_IRQSTAT0_BPONI | ||
61 | #define MC13XXX_IRQMASK0_LOBATLM MC13XXX_IRQSTAT0_LOBATLI | ||
62 | #define MC13XXX_IRQMASK0_LOBATHM MC13XXX_IRQSTAT0_LOBATHI | ||
63 | #define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI | ||
64 | #define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI | ||
65 | #define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI | ||
66 | #define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I | ||
67 | #define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI | ||
68 | #define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI | ||
69 | |||
70 | #define MC13XXX_IRQSTAT1 3 | 23 | #define MC13XXX_IRQSTAT1 3 |
71 | #define MC13XXX_IRQSTAT1_1HZI (1 << 0) | ||
72 | #define MC13XXX_IRQSTAT1_TODAI (1 << 1) | ||
73 | #define MC13783_IRQSTAT1_ONOFD1I (1 << 3) | ||
74 | #define MC13783_IRQSTAT1_ONOFD2I (1 << 4) | ||
75 | #define MC13783_IRQSTAT1_ONOFD3I (1 << 5) | ||
76 | #define MC13XXX_IRQSTAT1_SYSRSTI (1 << 6) | ||
77 | #define MC13XXX_IRQSTAT1_RTCRSTI (1 << 7) | ||
78 | #define MC13XXX_IRQSTAT1_PCI (1 << 8) | ||
79 | #define MC13XXX_IRQSTAT1_WARMI (1 << 9) | ||
80 | #define MC13XXX_IRQSTAT1_MEMHLDI (1 << 10) | ||
81 | #define MC13783_IRQSTAT1_PWRRDYI (1 << 11) | ||
82 | #define MC13XXX_IRQSTAT1_THWARNLI (1 << 12) | ||
83 | #define MC13XXX_IRQSTAT1_THWARNHI (1 << 13) | ||
84 | #define MC13XXX_IRQSTAT1_CLKI (1 << 14) | ||
85 | #define MC13783_IRQSTAT1_SEMAFI (1 << 15) | ||
86 | #define MC13783_IRQSTAT1_MC2BI (1 << 17) | ||
87 | #define MC13783_IRQSTAT1_HSDETI (1 << 18) | ||
88 | #define MC13783_IRQSTAT1_HSLI (1 << 19) | ||
89 | #define MC13783_IRQSTAT1_ALSPTHI (1 << 20) | ||
90 | #define MC13783_IRQSTAT1_AHSSHORTI (1 << 21) | ||
91 | |||
92 | #define MC13XXX_IRQMASK1 4 | 24 | #define MC13XXX_IRQMASK1 4 |
93 | #define MC13XXX_IRQMASK1_1HZM MC13XXX_IRQSTAT1_1HZI | ||
94 | #define MC13XXX_IRQMASK1_TODAM MC13XXX_IRQSTAT1_TODAI | ||
95 | #define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I | ||
96 | #define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I | ||
97 | #define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I | ||
98 | #define MC13XXX_IRQMASK1_SYSRSTM MC13XXX_IRQSTAT1_SYSRSTI | ||
99 | #define MC13XXX_IRQMASK1_RTCRSTM MC13XXX_IRQSTAT1_RTCRSTI | ||
100 | #define MC13XXX_IRQMASK1_PCM MC13XXX_IRQSTAT1_PCI | ||
101 | #define MC13XXX_IRQMASK1_WARMM MC13XXX_IRQSTAT1_WARMI | ||
102 | #define MC13XXX_IRQMASK1_MEMHLDM MC13XXX_IRQSTAT1_MEMHLDI | ||
103 | #define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI | ||
104 | #define MC13XXX_IRQMASK1_THWARNLM MC13XXX_IRQSTAT1_THWARNLI | ||
105 | #define MC13XXX_IRQMASK1_THWARNHM MC13XXX_IRQSTAT1_THWARNHI | ||
106 | #define MC13XXX_IRQMASK1_CLKM MC13XXX_IRQSTAT1_CLKI | ||
107 | #define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI | ||
108 | #define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI | ||
109 | #define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI | ||
110 | #define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI | ||
111 | #define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI | ||
112 | #define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI | ||
113 | 25 | ||
114 | #define MC13XXX_REVISION 7 | 26 | #define MC13XXX_REVISION 7 |
115 | #define MC13XXX_REVISION_REVMETAL (0x07 << 0) | 27 | #define MC13XXX_REVISION_REVMETAL (0x07 << 0) |
@@ -189,45 +101,21 @@ EXPORT_SYMBOL(mc13xxx_reg_rmw); | |||
189 | 101 | ||
190 | int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq) | 102 | int mc13xxx_irq_mask(struct mc13xxx *mc13xxx, int irq) |
191 | { | 103 | { |
192 | int ret; | 104 | int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq); |
193 | unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; | ||
194 | u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); | ||
195 | u32 mask; | ||
196 | |||
197 | if (irq < 0 || irq >= MC13XXX_NUM_IRQ) | ||
198 | return -EINVAL; | ||
199 | |||
200 | ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); | ||
201 | if (ret) | ||
202 | return ret; | ||
203 | 105 | ||
204 | if (mask & irqbit) | 106 | disable_irq_nosync(virq); |
205 | /* already masked */ | ||
206 | return 0; | ||
207 | 107 | ||
208 | return mc13xxx_reg_write(mc13xxx, offmask, mask | irqbit); | 108 | return 0; |
209 | } | 109 | } |
210 | EXPORT_SYMBOL(mc13xxx_irq_mask); | 110 | EXPORT_SYMBOL(mc13xxx_irq_mask); |
211 | 111 | ||
212 | int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq) | 112 | int mc13xxx_irq_unmask(struct mc13xxx *mc13xxx, int irq) |
213 | { | 113 | { |
214 | int ret; | 114 | int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq); |
215 | unsigned int offmask = irq < 24 ? MC13XXX_IRQMASK0 : MC13XXX_IRQMASK1; | ||
216 | u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); | ||
217 | u32 mask; | ||
218 | |||
219 | if (irq < 0 || irq >= MC13XXX_NUM_IRQ) | ||
220 | return -EINVAL; | ||
221 | 115 | ||
222 | ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); | 116 | enable_irq(virq); |
223 | if (ret) | ||
224 | return ret; | ||
225 | 117 | ||
226 | if (!(mask & irqbit)) | 118 | return 0; |
227 | /* already unmasked */ | ||
228 | return 0; | ||
229 | |||
230 | return mc13xxx_reg_write(mc13xxx, offmask, mask & ~irqbit); | ||
231 | } | 119 | } |
232 | EXPORT_SYMBOL(mc13xxx_irq_unmask); | 120 | EXPORT_SYMBOL(mc13xxx_irq_unmask); |
233 | 121 | ||
@@ -239,7 +127,7 @@ int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq, | |||
239 | unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; | 127 | unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; |
240 | u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); | 128 | u32 irqbit = 1 << (irq < 24 ? irq : irq - 24); |
241 | 129 | ||
242 | if (irq < 0 || irq >= MC13XXX_NUM_IRQ) | 130 | if (irq < 0 || irq >= ARRAY_SIZE(mc13xxx->irqs)) |
243 | return -EINVAL; | 131 | return -EINVAL; |
244 | 132 | ||
245 | if (enabled) { | 133 | if (enabled) { |
@@ -266,147 +154,26 @@ int mc13xxx_irq_status(struct mc13xxx *mc13xxx, int irq, | |||
266 | } | 154 | } |
267 | EXPORT_SYMBOL(mc13xxx_irq_status); | 155 | EXPORT_SYMBOL(mc13xxx_irq_status); |
268 | 156 | ||
269 | int mc13xxx_irq_ack(struct mc13xxx *mc13xxx, int irq) | ||
270 | { | ||
271 | unsigned int offstat = irq < 24 ? MC13XXX_IRQSTAT0 : MC13XXX_IRQSTAT1; | ||
272 | unsigned int val = 1 << (irq < 24 ? irq : irq - 24); | ||
273 | |||
274 | BUG_ON(irq < 0 || irq >= MC13XXX_NUM_IRQ); | ||
275 | |||
276 | return mc13xxx_reg_write(mc13xxx, offstat, val); | ||
277 | } | ||
278 | EXPORT_SYMBOL(mc13xxx_irq_ack); | ||
279 | |||
280 | int mc13xxx_irq_request_nounmask(struct mc13xxx *mc13xxx, int irq, | ||
281 | irq_handler_t handler, const char *name, void *dev) | ||
282 | { | ||
283 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | ||
284 | BUG_ON(!handler); | ||
285 | |||
286 | if (irq < 0 || irq >= MC13XXX_NUM_IRQ) | ||
287 | return -EINVAL; | ||
288 | |||
289 | if (mc13xxx->irqhandler[irq]) | ||
290 | return -EBUSY; | ||
291 | |||
292 | mc13xxx->irqhandler[irq] = handler; | ||
293 | mc13xxx->irqdata[irq] = dev; | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | EXPORT_SYMBOL(mc13xxx_irq_request_nounmask); | ||
298 | |||
299 | int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq, | 157 | int mc13xxx_irq_request(struct mc13xxx *mc13xxx, int irq, |
300 | irq_handler_t handler, const char *name, void *dev) | 158 | irq_handler_t handler, const char *name, void *dev) |
301 | { | 159 | { |
302 | int ret; | 160 | int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq); |
303 | 161 | ||
304 | ret = mc13xxx_irq_request_nounmask(mc13xxx, irq, handler, name, dev); | 162 | return devm_request_threaded_irq(mc13xxx->dev, virq, NULL, handler, |
305 | if (ret) | 163 | 0, name, dev); |
306 | return ret; | ||
307 | |||
308 | ret = mc13xxx_irq_unmask(mc13xxx, irq); | ||
309 | if (ret) { | ||
310 | mc13xxx->irqhandler[irq] = NULL; | ||
311 | mc13xxx->irqdata[irq] = NULL; | ||
312 | return ret; | ||
313 | } | ||
314 | |||
315 | return 0; | ||
316 | } | 164 | } |
317 | EXPORT_SYMBOL(mc13xxx_irq_request); | 165 | EXPORT_SYMBOL(mc13xxx_irq_request); |
318 | 166 | ||
319 | int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev) | 167 | int mc13xxx_irq_free(struct mc13xxx *mc13xxx, int irq, void *dev) |
320 | { | 168 | { |
321 | int ret; | 169 | int virq = regmap_irq_get_virq(mc13xxx->irq_data, irq); |
322 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | ||
323 | 170 | ||
324 | if (irq < 0 || irq >= MC13XXX_NUM_IRQ || !mc13xxx->irqhandler[irq] || | 171 | devm_free_irq(mc13xxx->dev, virq, dev); |
325 | mc13xxx->irqdata[irq] != dev) | ||
326 | return -EINVAL; | ||
327 | |||
328 | ret = mc13xxx_irq_mask(mc13xxx, irq); | ||
329 | if (ret) | ||
330 | return ret; | ||
331 | |||
332 | mc13xxx->irqhandler[irq] = NULL; | ||
333 | mc13xxx->irqdata[irq] = NULL; | ||
334 | 172 | ||
335 | return 0; | 173 | return 0; |
336 | } | 174 | } |
337 | EXPORT_SYMBOL(mc13xxx_irq_free); | 175 | EXPORT_SYMBOL(mc13xxx_irq_free); |
338 | 176 | ||
339 | static inline irqreturn_t mc13xxx_irqhandler(struct mc13xxx *mc13xxx, int irq) | ||
340 | { | ||
341 | return mc13xxx->irqhandler[irq](irq, mc13xxx->irqdata[irq]); | ||
342 | } | ||
343 | |||
344 | /* | ||
345 | * returns: number of handled irqs or negative error | ||
346 | * locking: holds mc13xxx->lock | ||
347 | */ | ||
348 | static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx, | ||
349 | unsigned int offstat, unsigned int offmask, int baseirq) | ||
350 | { | ||
351 | u32 stat, mask; | ||
352 | int ret = mc13xxx_reg_read(mc13xxx, offstat, &stat); | ||
353 | int num_handled = 0; | ||
354 | |||
355 | if (ret) | ||
356 | return ret; | ||
357 | |||
358 | ret = mc13xxx_reg_read(mc13xxx, offmask, &mask); | ||
359 | if (ret) | ||
360 | return ret; | ||
361 | |||
362 | while (stat & ~mask) { | ||
363 | int irq = __ffs(stat & ~mask); | ||
364 | |||
365 | stat &= ~(1 << irq); | ||
366 | |||
367 | if (likely(mc13xxx->irqhandler[baseirq + irq])) { | ||
368 | irqreturn_t handled; | ||
369 | |||
370 | handled = mc13xxx_irqhandler(mc13xxx, baseirq + irq); | ||
371 | if (handled == IRQ_HANDLED) | ||
372 | num_handled++; | ||
373 | } else { | ||
374 | dev_err(mc13xxx->dev, | ||
375 | "BUG: irq %u but no handler\n", | ||
376 | baseirq + irq); | ||
377 | |||
378 | mask |= 1 << irq; | ||
379 | |||
380 | ret = mc13xxx_reg_write(mc13xxx, offmask, mask); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | return num_handled; | ||
385 | } | ||
386 | |||
387 | static irqreturn_t mc13xxx_irq_thread(int irq, void *data) | ||
388 | { | ||
389 | struct mc13xxx *mc13xxx = data; | ||
390 | irqreturn_t ret; | ||
391 | int handled = 0; | ||
392 | |||
393 | mc13xxx_lock(mc13xxx); | ||
394 | |||
395 | ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT0, | ||
396 | MC13XXX_IRQMASK0, 0); | ||
397 | if (ret > 0) | ||
398 | handled = 1; | ||
399 | |||
400 | ret = mc13xxx_irq_handle(mc13xxx, MC13XXX_IRQSTAT1, | ||
401 | MC13XXX_IRQMASK1, 24); | ||
402 | if (ret > 0) | ||
403 | handled = 1; | ||
404 | |||
405 | mc13xxx_unlock(mc13xxx); | ||
406 | |||
407 | return IRQ_RETVAL(handled); | ||
408 | } | ||
409 | |||
410 | #define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) | 177 | #define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) |
411 | static void mc13xxx_print_revision(struct mc13xxx *mc13xxx, u32 revision) | 178 | static void mc13xxx_print_revision(struct mc13xxx *mc13xxx, u32 revision) |
412 | { | 179 | { |
@@ -475,8 +242,6 @@ static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data) | |||
475 | { | 242 | { |
476 | struct mc13xxx_adcdone_data *adcdone_data = data; | 243 | struct mc13xxx_adcdone_data *adcdone_data = data; |
477 | 244 | ||
478 | mc13xxx_irq_ack(adcdone_data->mc13xxx, irq); | ||
479 | |||
480 | complete_all(&adcdone_data->done); | 245 | complete_all(&adcdone_data->done); |
481 | 246 | ||
482 | return IRQ_HANDLED; | 247 | return IRQ_HANDLED; |
@@ -544,7 +309,6 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, | |||
544 | dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); | 309 | dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); |
545 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, | 310 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, |
546 | mc13xxx_handler_adcdone, __func__, &adcdone_data); | 311 | mc13xxx_handler_adcdone, __func__, &adcdone_data); |
547 | mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); | ||
548 | 312 | ||
549 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); | 313 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); |
550 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); | 314 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); |
@@ -599,7 +363,8 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | |||
599 | if (!cell.name) | 363 | if (!cell.name) |
600 | return -ENOMEM; | 364 | return -ENOMEM; |
601 | 365 | ||
602 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL); | 366 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, |
367 | regmap_irq_get_domain(mc13xxx->irq_data)); | ||
603 | } | 368 | } |
604 | 369 | ||
605 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | 370 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) |
@@ -640,8 +405,8 @@ int mc13xxx_common_init(struct device *dev) | |||
640 | { | 405 | { |
641 | struct mc13xxx_platform_data *pdata = dev_get_platdata(dev); | 406 | struct mc13xxx_platform_data *pdata = dev_get_platdata(dev); |
642 | struct mc13xxx *mc13xxx = dev_get_drvdata(dev); | 407 | struct mc13xxx *mc13xxx = dev_get_drvdata(dev); |
643 | int ret; | ||
644 | u32 revision; | 408 | u32 revision; |
409 | int i, ret; | ||
645 | 410 | ||
646 | mc13xxx->dev = dev; | 411 | mc13xxx->dev = dev; |
647 | 412 | ||
@@ -651,31 +416,32 @@ int mc13xxx_common_init(struct device *dev) | |||
651 | 416 | ||
652 | mc13xxx->variant->print_revision(mc13xxx, revision); | 417 | mc13xxx->variant->print_revision(mc13xxx, revision); |
653 | 418 | ||
654 | /* mask all irqs */ | 419 | for (i = 0; i < ARRAY_SIZE(mc13xxx->irqs); i++) { |
655 | ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK0, 0x00ffffff); | 420 | mc13xxx->irqs[i].reg_offset = i / MC13XXX_IRQ_PER_REG; |
656 | if (ret) | 421 | mc13xxx->irqs[i].mask = BIT(i % MC13XXX_IRQ_PER_REG); |
657 | return ret; | 422 | } |
658 | 423 | ||
659 | ret = mc13xxx_reg_write(mc13xxx, MC13XXX_IRQMASK1, 0x00ffffff); | 424 | mc13xxx->irq_chip.name = dev_name(dev); |
425 | mc13xxx->irq_chip.status_base = MC13XXX_IRQSTAT0; | ||
426 | mc13xxx->irq_chip.mask_base = MC13XXX_IRQMASK0; | ||
427 | mc13xxx->irq_chip.ack_base = MC13XXX_IRQSTAT0; | ||
428 | mc13xxx->irq_chip.irq_reg_stride = MC13XXX_IRQSTAT1 - MC13XXX_IRQSTAT0; | ||
429 | mc13xxx->irq_chip.init_ack_masked = true; | ||
430 | mc13xxx->irq_chip.use_ack = true; | ||
431 | mc13xxx->irq_chip.num_regs = MC13XXX_IRQ_REG_CNT; | ||
432 | mc13xxx->irq_chip.irqs = mc13xxx->irqs; | ||
433 | mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs); | ||
434 | |||
435 | ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT, | ||
436 | 0, &mc13xxx->irq_chip, &mc13xxx->irq_data); | ||
660 | if (ret) | 437 | if (ret) |
661 | return ret; | 438 | return ret; |
662 | 439 | ||
663 | mutex_init(&mc13xxx->lock); | 440 | mutex_init(&mc13xxx->lock); |
664 | 441 | ||
665 | ret = request_threaded_irq(mc13xxx->irq, NULL, mc13xxx_irq_thread, | ||
666 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); | ||
667 | if (ret) | ||
668 | return ret; | ||
669 | |||
670 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) | 442 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) |
671 | mc13xxx->flags = pdata->flags; | 443 | mc13xxx->flags = pdata->flags; |
672 | 444 | ||
673 | if (mc13xxx->flags & MC13XXX_USE_ADC) | ||
674 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); | ||
675 | |||
676 | if (mc13xxx->flags & MC13XXX_USE_RTC) | ||
677 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | ||
678 | |||
679 | if (pdata) { | 445 | if (pdata) { |
680 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | 446 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", |
681 | &pdata->regulators, sizeof(pdata->regulators)); | 447 | &pdata->regulators, sizeof(pdata->regulators)); |
@@ -699,6 +465,12 @@ int mc13xxx_common_init(struct device *dev) | |||
699 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); | 465 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); |
700 | } | 466 | } |
701 | 467 | ||
468 | if (mc13xxx->flags & MC13XXX_USE_ADC) | ||
469 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); | ||
470 | |||
471 | if (mc13xxx->flags & MC13XXX_USE_RTC) | ||
472 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | ||
473 | |||
702 | return 0; | 474 | return 0; |
703 | } | 475 | } |
704 | EXPORT_SYMBOL_GPL(mc13xxx_common_init); | 476 | EXPORT_SYMBOL_GPL(mc13xxx_common_init); |
@@ -707,8 +479,8 @@ int mc13xxx_common_exit(struct device *dev) | |||
707 | { | 479 | { |
708 | struct mc13xxx *mc13xxx = dev_get_drvdata(dev); | 480 | struct mc13xxx *mc13xxx = dev_get_drvdata(dev); |
709 | 481 | ||
710 | free_irq(mc13xxx->irq, mc13xxx); | ||
711 | mfd_remove_devices(dev); | 482 | mfd_remove_devices(dev); |
483 | regmap_del_irq_chip(mc13xxx->irq, mc13xxx->irq_data); | ||
712 | mutex_destroy(&mc13xxx->lock); | 484 | mutex_destroy(&mc13xxx->lock); |
713 | 485 | ||
714 | return 0; | 486 | return 0; |
diff --git a/drivers/mfd/mc13xxx.h b/drivers/mfd/mc13xxx.h index ae7f1659f5d1..33677d1dcf66 100644 --- a/drivers/mfd/mc13xxx.h +++ b/drivers/mfd/mc13xxx.h | |||
@@ -13,7 +13,9 @@ | |||
13 | #include <linux/regmap.h> | 13 | #include <linux/regmap.h> |
14 | #include <linux/mfd/mc13xxx.h> | 14 | #include <linux/mfd/mc13xxx.h> |
15 | 15 | ||
16 | #define MC13XXX_NUMREGS 0x3f | 16 | #define MC13XXX_NUMREGS 0x3f |
17 | #define MC13XXX_IRQ_REG_CNT 2 | ||
18 | #define MC13XXX_IRQ_PER_REG 24 | ||
17 | 19 | ||
18 | struct mc13xxx; | 20 | struct mc13xxx; |
19 | 21 | ||
@@ -33,13 +35,14 @@ struct mc13xxx { | |||
33 | struct device *dev; | 35 | struct device *dev; |
34 | const struct mc13xxx_variant *variant; | 36 | const struct mc13xxx_variant *variant; |
35 | 37 | ||
38 | struct regmap_irq irqs[MC13XXX_IRQ_PER_REG * MC13XXX_IRQ_REG_CNT]; | ||
39 | struct regmap_irq_chip irq_chip; | ||
40 | struct regmap_irq_chip_data *irq_data; | ||
41 | |||
36 | struct mutex lock; | 42 | struct mutex lock; |
37 | int irq; | 43 | int irq; |
38 | int flags; | 44 | int flags; |
39 | 45 | ||
40 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; | ||
41 | void *irqdata[MC13XXX_NUM_IRQ]; | ||
42 | |||
43 | int adcflags; | 46 | int adcflags; |
44 | }; | 47 | }; |
45 | 48 | ||
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 62e5e3617eb0..7f5066e39752 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c | |||
@@ -137,6 +137,7 @@ EXPORT_SYMBOL(mcp_reg_read); | |||
137 | void mcp_enable(struct mcp *mcp) | 137 | void mcp_enable(struct mcp *mcp) |
138 | { | 138 | { |
139 | unsigned long flags; | 139 | unsigned long flags; |
140 | |||
140 | spin_lock_irqsave(&mcp->lock, flags); | 141 | spin_lock_irqsave(&mcp->lock, flags); |
141 | if (mcp->use_count++ == 0) | 142 | if (mcp->use_count++ == 0) |
142 | mcp->ops->enable(mcp); | 143 | mcp->ops->enable(mcp); |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index b48d80c367f9..33a9234b701c 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -445,7 +445,7 @@ static unsigned omap_usbhs_rev1_hostconfig(struct usbhs_hcd_omap *omap, | |||
445 | 445 | ||
446 | for (i = 0; i < omap->nports; i++) { | 446 | for (i = 0; i < omap->nports; i++) { |
447 | if (is_ehci_phy_mode(pdata->port_mode[i])) { | 447 | if (is_ehci_phy_mode(pdata->port_mode[i])) { |
448 | reg &= OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; | 448 | reg &= ~OMAP_UHH_HOSTCONFIG_ULPI_BYPASS; |
449 | break; | 449 | break; |
450 | } | 450 | } |
451 | } | 451 | } |
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 41ab5e34d2ac..c87f7a0a53f8 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c | |||
@@ -244,20 +244,20 @@ static int pcf50633_probe(struct i2c_client *client, | |||
244 | 244 | ||
245 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { | 245 | for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { |
246 | struct platform_device *pdev; | 246 | struct platform_device *pdev; |
247 | int j; | ||
247 | 248 | ||
248 | pdev = platform_device_alloc("pcf50633-regulator", i); | 249 | pdev = platform_device_alloc("pcf50633-regulator", i); |
249 | if (!pdev) { | 250 | if (!pdev) |
250 | dev_err(pcf->dev, "Cannot create regulator %d\n", i); | 251 | return -ENOMEM; |
251 | continue; | ||
252 | } | ||
253 | 252 | ||
254 | pdev->dev.parent = pcf->dev; | 253 | pdev->dev.parent = pcf->dev; |
255 | if (platform_device_add_data(pdev, &pdata->reg_init_data[i], | 254 | ret = platform_device_add_data(pdev, &pdata->reg_init_data[i], |
256 | sizeof(pdata->reg_init_data[i])) < 0) { | 255 | sizeof(pdata->reg_init_data[i])); |
256 | if (ret) { | ||
257 | platform_device_put(pdev); | 257 | platform_device_put(pdev); |
258 | dev_err(pcf->dev, "Out of memory for regulator parameters %d\n", | 258 | for (j = 0; j < i; j++) |
259 | i); | 259 | platform_device_put(pcf->regulator_pdev[j]); |
260 | continue; | 260 | return ret; |
261 | } | 261 | } |
262 | pcf->regulator_pdev[i] = pdev; | 262 | pcf->regulator_pdev[i] = pdev; |
263 | 263 | ||
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index 959513803542..39904f77c049 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c | |||
@@ -186,11 +186,9 @@ static void pm8xxx_irq_mask_ack(struct irq_data *d) | |||
186 | { | 186 | { |
187 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | 187 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); |
188 | unsigned int pmirq = irqd_to_hwirq(d); | 188 | unsigned int pmirq = irqd_to_hwirq(d); |
189 | int irq_bit; | ||
190 | u8 block, config; | 189 | u8 block, config; |
191 | 190 | ||
192 | block = pmirq / 8; | 191 | block = pmirq / 8; |
193 | irq_bit = pmirq % 8; | ||
194 | 192 | ||
195 | config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; | 193 | config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; |
196 | pm8xxx_config_irq(chip, block, config); | 194 | pm8xxx_config_irq(chip, block, config); |
@@ -200,11 +198,9 @@ static void pm8xxx_irq_unmask(struct irq_data *d) | |||
200 | { | 198 | { |
201 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | 199 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); |
202 | unsigned int pmirq = irqd_to_hwirq(d); | 200 | unsigned int pmirq = irqd_to_hwirq(d); |
203 | int irq_bit; | ||
204 | u8 block, config; | 201 | u8 block, config; |
205 | 202 | ||
206 | block = pmirq / 8; | 203 | block = pmirq / 8; |
207 | irq_bit = pmirq % 8; | ||
208 | 204 | ||
209 | config = chip->config[pmirq]; | 205 | config = chip->config[pmirq]; |
210 | pm8xxx_config_irq(chip, block, config); | 206 | pm8xxx_config_irq(chip, block, config); |
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index 1d15735f9ef9..d01b8c249231 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -337,40 +337,64 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr, | |||
337 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | 337 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
338 | int num_sg, bool read, int timeout) | 338 | int num_sg, bool read, int timeout) |
339 | { | 339 | { |
340 | struct completion trans_done; | 340 | int err = 0, count; |
341 | u8 dir; | ||
342 | int err = 0, i, count; | ||
343 | long timeleft; | ||
344 | unsigned long flags; | ||
345 | struct scatterlist *sg; | ||
346 | enum dma_data_direction dma_dir; | ||
347 | u32 val; | ||
348 | dma_addr_t addr; | ||
349 | unsigned int len; | ||
350 | 341 | ||
351 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); | 342 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); |
343 | count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read); | ||
344 | if (count < 1) | ||
345 | return -EINVAL; | ||
346 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | ||
347 | |||
348 | err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout); | ||
349 | |||
350 | rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read); | ||
351 | |||
352 | return err; | ||
353 | } | ||
354 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | ||
355 | |||
356 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
357 | int num_sg, bool read) | ||
358 | { | ||
359 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
352 | 360 | ||
353 | /* don't transfer data during abort processing */ | ||
354 | if (pcr->remove_pci) | 361 | if (pcr->remove_pci) |
355 | return -EINVAL; | 362 | return -EINVAL; |
356 | 363 | ||
357 | if ((sglist == NULL) || (num_sg <= 0)) | 364 | if ((sglist == NULL) || (num_sg <= 0)) |
358 | return -EINVAL; | 365 | return -EINVAL; |
359 | 366 | ||
360 | if (read) { | 367 | return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir); |
361 | dir = DEVICE_TO_HOST; | 368 | } |
362 | dma_dir = DMA_FROM_DEVICE; | 369 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg); |
363 | } else { | ||
364 | dir = HOST_TO_DEVICE; | ||
365 | dma_dir = DMA_TO_DEVICE; | ||
366 | } | ||
367 | 370 | ||
368 | count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | 371 | void rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
369 | if (count < 1) { | 372 | int num_sg, bool read) |
370 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); | 373 | { |
374 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
375 | |||
376 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
377 | } | ||
378 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg); | ||
379 | |||
380 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
381 | int count, bool read, int timeout) | ||
382 | { | ||
383 | struct completion trans_done; | ||
384 | struct scatterlist *sg; | ||
385 | dma_addr_t addr; | ||
386 | long timeleft; | ||
387 | unsigned long flags; | ||
388 | unsigned int len; | ||
389 | int i, err = 0; | ||
390 | u32 val; | ||
391 | u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; | ||
392 | |||
393 | if (pcr->remove_pci) | ||
394 | return -ENODEV; | ||
395 | |||
396 | if ((sglist == NULL) || (count < 1)) | ||
371 | return -EINVAL; | 397 | return -EINVAL; |
372 | } | ||
373 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | ||
374 | 398 | ||
375 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | 399 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; |
376 | pcr->sgi = 0; | 400 | pcr->sgi = 0; |
@@ -400,12 +424,10 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | |||
400 | } | 424 | } |
401 | 425 | ||
402 | spin_lock_irqsave(&pcr->lock, flags); | 426 | spin_lock_irqsave(&pcr->lock, flags); |
403 | |||
404 | if (pcr->trans_result == TRANS_RESULT_FAIL) | 427 | if (pcr->trans_result == TRANS_RESULT_FAIL) |
405 | err = -EINVAL; | 428 | err = -EINVAL; |
406 | else if (pcr->trans_result == TRANS_NO_DEVICE) | 429 | else if (pcr->trans_result == TRANS_NO_DEVICE) |
407 | err = -ENODEV; | 430 | err = -ENODEV; |
408 | |||
409 | spin_unlock_irqrestore(&pcr->lock, flags); | 431 | spin_unlock_irqrestore(&pcr->lock, flags); |
410 | 432 | ||
411 | out: | 433 | out: |
@@ -413,8 +435,6 @@ out: | |||
413 | pcr->done = NULL; | 435 | pcr->done = NULL; |
414 | spin_unlock_irqrestore(&pcr->lock, flags); | 436 | spin_unlock_irqrestore(&pcr->lock, flags); |
415 | 437 | ||
416 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | ||
417 | |||
418 | if ((err < 0) && (err != -ENODEV)) | 438 | if ((err < 0) && (err != -ENODEV)) |
419 | rtsx_pci_stop_cmd(pcr); | 439 | rtsx_pci_stop_cmd(pcr); |
420 | 440 | ||
@@ -423,7 +443,7 @@ out: | |||
423 | 443 | ||
424 | return err; | 444 | return err; |
425 | } | 445 | } |
426 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | 446 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer); |
427 | 447 | ||
428 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) | 448 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) |
429 | { | 449 | { |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index be06d0abbf19..dba7e2b6f8e9 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -28,8 +28,10 @@ | |||
28 | #include <linux/mfd/samsung/s2mpa01.h> | 28 | #include <linux/mfd/samsung/s2mpa01.h> |
29 | #include <linux/mfd/samsung/s2mps11.h> | 29 | #include <linux/mfd/samsung/s2mps11.h> |
30 | #include <linux/mfd/samsung/s2mps14.h> | 30 | #include <linux/mfd/samsung/s2mps14.h> |
31 | #include <linux/mfd/samsung/s2mpu02.h> | ||
31 | #include <linux/mfd/samsung/s5m8763.h> | 32 | #include <linux/mfd/samsung/s5m8763.h> |
32 | #include <linux/mfd/samsung/s5m8767.h> | 33 | #include <linux/mfd/samsung/s5m8767.h> |
34 | #include <linux/regulator/machine.h> | ||
33 | #include <linux/regmap.h> | 35 | #include <linux/regmap.h> |
34 | 36 | ||
35 | static const struct mfd_cell s5m8751_devs[] = { | 37 | static const struct mfd_cell s5m8751_devs[] = { |
@@ -89,6 +91,15 @@ static const struct mfd_cell s2mpa01_devs[] = { | |||
89 | }, | 91 | }, |
90 | }; | 92 | }; |
91 | 93 | ||
94 | static const struct mfd_cell s2mpu02_devs[] = { | ||
95 | { .name = "s2mpu02-pmic", }, | ||
96 | { .name = "s2mpu02-rtc", }, | ||
97 | { | ||
98 | .name = "s2mpu02-clk", | ||
99 | .of_compatible = "samsung,s2mpu02-clk", | ||
100 | } | ||
101 | }; | ||
102 | |||
92 | #ifdef CONFIG_OF | 103 | #ifdef CONFIG_OF |
93 | static const struct of_device_id sec_dt_match[] = { | 104 | static const struct of_device_id sec_dt_match[] = { |
94 | { .compatible = "samsung,s5m8767-pmic", | 105 | { .compatible = "samsung,s5m8767-pmic", |
@@ -103,6 +114,9 @@ static const struct of_device_id sec_dt_match[] = { | |||
103 | .compatible = "samsung,s2mpa01-pmic", | 114 | .compatible = "samsung,s2mpa01-pmic", |
104 | .data = (void *)S2MPA01, | 115 | .data = (void *)S2MPA01, |
105 | }, { | 116 | }, { |
117 | .compatible = "samsung,s2mpu02-pmic", | ||
118 | .data = (void *)S2MPU02, | ||
119 | }, { | ||
106 | /* Sentinel */ | 120 | /* Sentinel */ |
107 | }, | 121 | }, |
108 | }; | 122 | }; |
@@ -132,6 +146,18 @@ static bool s2mps11_volatile(struct device *dev, unsigned int reg) | |||
132 | } | 146 | } |
133 | } | 147 | } |
134 | 148 | ||
149 | static bool s2mpu02_volatile(struct device *dev, unsigned int reg) | ||
150 | { | ||
151 | switch (reg) { | ||
152 | case S2MPU02_REG_INT1M: | ||
153 | case S2MPU02_REG_INT2M: | ||
154 | case S2MPU02_REG_INT3M: | ||
155 | return false; | ||
156 | default: | ||
157 | return true; | ||
158 | } | ||
159 | } | ||
160 | |||
135 | static bool s5m8763_volatile(struct device *dev, unsigned int reg) | 161 | static bool s5m8763_volatile(struct device *dev, unsigned int reg) |
136 | { | 162 | { |
137 | switch (reg) { | 163 | switch (reg) { |
@@ -177,6 +203,15 @@ static const struct regmap_config s2mps14_regmap_config = { | |||
177 | .cache_type = REGCACHE_FLAT, | 203 | .cache_type = REGCACHE_FLAT, |
178 | }; | 204 | }; |
179 | 205 | ||
206 | static const struct regmap_config s2mpu02_regmap_config = { | ||
207 | .reg_bits = 8, | ||
208 | .val_bits = 8, | ||
209 | |||
210 | .max_register = S2MPU02_REG_DVSDATA, | ||
211 | .volatile_reg = s2mpu02_volatile, | ||
212 | .cache_type = REGCACHE_FLAT, | ||
213 | }; | ||
214 | |||
180 | static const struct regmap_config s5m8763_regmap_config = { | 215 | static const struct regmap_config s5m8763_regmap_config = { |
181 | .reg_bits = 8, | 216 | .reg_bits = 8, |
182 | .val_bits = 8, | 217 | .val_bits = 8, |
@@ -238,6 +273,7 @@ static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c, | |||
238 | #ifdef CONFIG_OF | 273 | #ifdef CONFIG_OF |
239 | if (i2c->dev.of_node) { | 274 | if (i2c->dev.of_node) { |
240 | const struct of_device_id *match; | 275 | const struct of_device_id *match; |
276 | |||
241 | match = of_match_node(sec_dt_match, i2c->dev.of_node); | 277 | match = of_match_node(sec_dt_match, i2c->dev.of_node); |
242 | return (unsigned long)match->data; | 278 | return (unsigned long)match->data; |
243 | } | 279 | } |
@@ -250,9 +286,10 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
250 | { | 286 | { |
251 | struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); | 287 | struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); |
252 | const struct regmap_config *regmap; | 288 | const struct regmap_config *regmap; |
289 | const struct mfd_cell *sec_devs; | ||
253 | struct sec_pmic_dev *sec_pmic; | 290 | struct sec_pmic_dev *sec_pmic; |
254 | unsigned long device_type; | 291 | unsigned long device_type; |
255 | int ret; | 292 | int ret, num_sec_devs; |
256 | 293 | ||
257 | sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), | 294 | sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), |
258 | GFP_KERNEL); | 295 | GFP_KERNEL); |
@@ -297,6 +334,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
297 | case S5M8767X: | 334 | case S5M8767X: |
298 | regmap = &s5m8767_regmap_config; | 335 | regmap = &s5m8767_regmap_config; |
299 | break; | 336 | break; |
337 | case S2MPU02: | ||
338 | regmap = &s2mpu02_regmap_config; | ||
339 | break; | ||
300 | default: | 340 | default: |
301 | regmap = &sec_regmap_config; | 341 | regmap = &sec_regmap_config; |
302 | break; | 342 | break; |
@@ -319,34 +359,39 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
319 | 359 | ||
320 | switch (sec_pmic->device_type) { | 360 | switch (sec_pmic->device_type) { |
321 | case S5M8751X: | 361 | case S5M8751X: |
322 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, | 362 | sec_devs = s5m8751_devs; |
323 | ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL); | 363 | num_sec_devs = ARRAY_SIZE(s5m8751_devs); |
324 | break; | 364 | break; |
325 | case S5M8763X: | 365 | case S5M8763X: |
326 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, | 366 | sec_devs = s5m8763_devs; |
327 | ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL); | 367 | num_sec_devs = ARRAY_SIZE(s5m8763_devs); |
328 | break; | 368 | break; |
329 | case S5M8767X: | 369 | case S5M8767X: |
330 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, | 370 | sec_devs = s5m8767_devs; |
331 | ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); | 371 | num_sec_devs = ARRAY_SIZE(s5m8767_devs); |
332 | break; | 372 | break; |
333 | case S2MPA01: | 373 | case S2MPA01: |
334 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mpa01_devs, | 374 | sec_devs = s2mpa01_devs; |
335 | ARRAY_SIZE(s2mpa01_devs), NULL, 0, NULL); | 375 | num_sec_devs = ARRAY_SIZE(s2mpa01_devs); |
336 | break; | 376 | break; |
337 | case S2MPS11X: | 377 | case S2MPS11X: |
338 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, | 378 | sec_devs = s2mps11_devs; |
339 | ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); | 379 | num_sec_devs = ARRAY_SIZE(s2mps11_devs); |
340 | break; | 380 | break; |
341 | case S2MPS14X: | 381 | case S2MPS14X: |
342 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps14_devs, | 382 | sec_devs = s2mps14_devs; |
343 | ARRAY_SIZE(s2mps14_devs), NULL, 0, NULL); | 383 | num_sec_devs = ARRAY_SIZE(s2mps14_devs); |
384 | break; | ||
385 | case S2MPU02: | ||
386 | sec_devs = s2mpu02_devs; | ||
387 | num_sec_devs = ARRAY_SIZE(s2mpu02_devs); | ||
344 | break; | 388 | break; |
345 | default: | 389 | default: |
346 | /* If this happens the probe function is problem */ | 390 | /* If this happens the probe function is problem */ |
347 | BUG(); | 391 | BUG(); |
348 | } | 392 | } |
349 | 393 | ret = mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, NULL, | |
394 | 0, NULL); | ||
350 | if (ret) | 395 | if (ret) |
351 | goto err_mfd; | 396 | goto err_mfd; |
352 | 397 | ||
@@ -387,6 +432,15 @@ static int sec_pmic_suspend(struct device *dev) | |||
387 | */ | 432 | */ |
388 | disable_irq(sec_pmic->irq); | 433 | disable_irq(sec_pmic->irq); |
389 | 434 | ||
435 | switch (sec_pmic->device_type) { | ||
436 | case S2MPS14X: | ||
437 | case S2MPU02: | ||
438 | regulator_suspend_prepare(PM_SUSPEND_MEM); | ||
439 | break; | ||
440 | default: | ||
441 | break; | ||
442 | } | ||
443 | |||
390 | return 0; | 444 | return 0; |
391 | } | 445 | } |
392 | 446 | ||
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 654e2c1dbf7a..f9a57869e3ec 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mfd/samsung/irq.h> | 20 | #include <linux/mfd/samsung/irq.h> |
21 | #include <linux/mfd/samsung/s2mps11.h> | 21 | #include <linux/mfd/samsung/s2mps11.h> |
22 | #include <linux/mfd/samsung/s2mps14.h> | 22 | #include <linux/mfd/samsung/s2mps14.h> |
23 | #include <linux/mfd/samsung/s2mpu02.h> | ||
23 | #include <linux/mfd/samsung/s5m8763.h> | 24 | #include <linux/mfd/samsung/s5m8763.h> |
24 | #include <linux/mfd/samsung/s5m8767.h> | 25 | #include <linux/mfd/samsung/s5m8767.h> |
25 | 26 | ||
@@ -161,6 +162,77 @@ static const struct regmap_irq s2mps14_irqs[] = { | |||
161 | }, | 162 | }, |
162 | }; | 163 | }; |
163 | 164 | ||
165 | static const struct regmap_irq s2mpu02_irqs[] = { | ||
166 | [S2MPU02_IRQ_PWRONF] = { | ||
167 | .reg_offset = 0, | ||
168 | .mask = S2MPS11_IRQ_PWRONF_MASK, | ||
169 | }, | ||
170 | [S2MPU02_IRQ_PWRONR] = { | ||
171 | .reg_offset = 0, | ||
172 | .mask = S2MPS11_IRQ_PWRONR_MASK, | ||
173 | }, | ||
174 | [S2MPU02_IRQ_JIGONBF] = { | ||
175 | .reg_offset = 0, | ||
176 | .mask = S2MPS11_IRQ_JIGONBF_MASK, | ||
177 | }, | ||
178 | [S2MPU02_IRQ_JIGONBR] = { | ||
179 | .reg_offset = 0, | ||
180 | .mask = S2MPS11_IRQ_JIGONBR_MASK, | ||
181 | }, | ||
182 | [S2MPU02_IRQ_ACOKBF] = { | ||
183 | .reg_offset = 0, | ||
184 | .mask = S2MPS11_IRQ_ACOKBF_MASK, | ||
185 | }, | ||
186 | [S2MPU02_IRQ_ACOKBR] = { | ||
187 | .reg_offset = 0, | ||
188 | .mask = S2MPS11_IRQ_ACOKBR_MASK, | ||
189 | }, | ||
190 | [S2MPU02_IRQ_PWRON1S] = { | ||
191 | .reg_offset = 0, | ||
192 | .mask = S2MPS11_IRQ_PWRON1S_MASK, | ||
193 | }, | ||
194 | [S2MPU02_IRQ_MRB] = { | ||
195 | .reg_offset = 0, | ||
196 | .mask = S2MPS11_IRQ_MRB_MASK, | ||
197 | }, | ||
198 | [S2MPU02_IRQ_RTC60S] = { | ||
199 | .reg_offset = 1, | ||
200 | .mask = S2MPS11_IRQ_RTC60S_MASK, | ||
201 | }, | ||
202 | [S2MPU02_IRQ_RTCA1] = { | ||
203 | .reg_offset = 1, | ||
204 | .mask = S2MPS11_IRQ_RTCA1_MASK, | ||
205 | }, | ||
206 | [S2MPU02_IRQ_RTCA0] = { | ||
207 | .reg_offset = 1, | ||
208 | .mask = S2MPS11_IRQ_RTCA0_MASK, | ||
209 | }, | ||
210 | [S2MPU02_IRQ_SMPL] = { | ||
211 | .reg_offset = 1, | ||
212 | .mask = S2MPS11_IRQ_SMPL_MASK, | ||
213 | }, | ||
214 | [S2MPU02_IRQ_RTC1S] = { | ||
215 | .reg_offset = 1, | ||
216 | .mask = S2MPS11_IRQ_RTC1S_MASK, | ||
217 | }, | ||
218 | [S2MPU02_IRQ_WTSR] = { | ||
219 | .reg_offset = 1, | ||
220 | .mask = S2MPS11_IRQ_WTSR_MASK, | ||
221 | }, | ||
222 | [S2MPU02_IRQ_INT120C] = { | ||
223 | .reg_offset = 2, | ||
224 | .mask = S2MPS11_IRQ_INT120C_MASK, | ||
225 | }, | ||
226 | [S2MPU02_IRQ_INT140C] = { | ||
227 | .reg_offset = 2, | ||
228 | .mask = S2MPS11_IRQ_INT140C_MASK, | ||
229 | }, | ||
230 | [S2MPU02_IRQ_TSD] = { | ||
231 | .reg_offset = 2, | ||
232 | .mask = S2MPS14_IRQ_TSD_MASK, | ||
233 | }, | ||
234 | }; | ||
235 | |||
164 | static const struct regmap_irq s5m8767_irqs[] = { | 236 | static const struct regmap_irq s5m8767_irqs[] = { |
165 | [S5M8767_IRQ_PWRR] = { | 237 | [S5M8767_IRQ_PWRR] = { |
166 | .reg_offset = 0, | 238 | .reg_offset = 0, |
@@ -327,6 +399,16 @@ static const struct regmap_irq_chip s2mps14_irq_chip = { | |||
327 | .ack_base = S2MPS14_REG_INT1, | 399 | .ack_base = S2MPS14_REG_INT1, |
328 | }; | 400 | }; |
329 | 401 | ||
402 | static const struct regmap_irq_chip s2mpu02_irq_chip = { | ||
403 | .name = "s2mpu02", | ||
404 | .irqs = s2mpu02_irqs, | ||
405 | .num_irqs = ARRAY_SIZE(s2mpu02_irqs), | ||
406 | .num_regs = 3, | ||
407 | .status_base = S2MPU02_REG_INT1, | ||
408 | .mask_base = S2MPU02_REG_INT1M, | ||
409 | .ack_base = S2MPU02_REG_INT1, | ||
410 | }; | ||
411 | |||
330 | static const struct regmap_irq_chip s5m8767_irq_chip = { | 412 | static const struct regmap_irq_chip s5m8767_irq_chip = { |
331 | .name = "s5m8767", | 413 | .name = "s5m8767", |
332 | .irqs = s5m8767_irqs, | 414 | .irqs = s5m8767_irqs, |
@@ -351,6 +433,7 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) | |||
351 | { | 433 | { |
352 | int ret = 0; | 434 | int ret = 0; |
353 | int type = sec_pmic->device_type; | 435 | int type = sec_pmic->device_type; |
436 | const struct regmap_irq_chip *sec_irq_chip; | ||
354 | 437 | ||
355 | if (!sec_pmic->irq) { | 438 | if (!sec_pmic->irq) { |
356 | dev_warn(sec_pmic->dev, | 439 | dev_warn(sec_pmic->dev, |
@@ -361,28 +444,19 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) | |||
361 | 444 | ||
362 | switch (type) { | 445 | switch (type) { |
363 | case S5M8763X: | 446 | case S5M8763X: |
364 | ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, | 447 | sec_irq_chip = &s5m8763_irq_chip; |
365 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
366 | sec_pmic->irq_base, &s5m8763_irq_chip, | ||
367 | &sec_pmic->irq_data); | ||
368 | break; | 448 | break; |
369 | case S5M8767X: | 449 | case S5M8767X: |
370 | ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, | 450 | sec_irq_chip = &s5m8767_irq_chip; |
371 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
372 | sec_pmic->irq_base, &s5m8767_irq_chip, | ||
373 | &sec_pmic->irq_data); | ||
374 | break; | 451 | break; |
375 | case S2MPS11X: | 452 | case S2MPS11X: |
376 | ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, | 453 | sec_irq_chip = &s2mps11_irq_chip; |
377 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
378 | sec_pmic->irq_base, &s2mps11_irq_chip, | ||
379 | &sec_pmic->irq_data); | ||
380 | break; | 454 | break; |
381 | case S2MPS14X: | 455 | case S2MPS14X: |
382 | ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, | 456 | sec_irq_chip = &s2mps14_irq_chip; |
383 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 457 | break; |
384 | sec_pmic->irq_base, &s2mps14_irq_chip, | 458 | case S2MPU02: |
385 | &sec_pmic->irq_data); | 459 | sec_irq_chip = &s2mpu02_irq_chip; |
386 | break; | 460 | break; |
387 | default: | 461 | default: |
388 | dev_err(sec_pmic->dev, "Unknown device type %lu\n", | 462 | dev_err(sec_pmic->dev, "Unknown device type %lu\n", |
@@ -390,6 +464,10 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) | |||
390 | return -EINVAL; | 464 | return -EINVAL; |
391 | } | 465 | } |
392 | 466 | ||
467 | ret = regmap_add_irq_chip(sec_pmic->regmap_pmic, sec_pmic->irq, | ||
468 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
469 | sec_pmic->irq_base, sec_irq_chip, | ||
470 | &sec_pmic->irq_data); | ||
393 | if (ret != 0) { | 471 | if (ret != 0) { |
394 | dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret); | 472 | dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret); |
395 | return ret; | 473 | return ret; |
diff --git a/drivers/mfd/si476x-cmd.c b/drivers/mfd/si476x-cmd.c index 6f1ef63086c9..2086b4665288 100644 --- a/drivers/mfd/si476x-cmd.c +++ b/drivers/mfd/si476x-cmd.c | |||
@@ -1228,8 +1228,8 @@ static int si476x_core_cmd_fm_rsq_status_a10(struct si476x_core *core, | |||
1228 | } | 1228 | } |
1229 | 1229 | ||
1230 | static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core, | 1230 | static int si476x_core_cmd_fm_rsq_status_a20(struct si476x_core *core, |
1231 | struct si476x_rsq_status_args *rsqargs, | 1231 | struct si476x_rsq_status_args *rsqargs, |
1232 | struct si476x_rsq_status_report *report) | 1232 | struct si476x_rsq_status_report *report) |
1233 | { | 1233 | { |
1234 | int err; | 1234 | int err; |
1235 | u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP]; | 1235 | u8 resp[CMD_FM_RSQ_STATUS_A10_NRESP]; |
@@ -1434,10 +1434,10 @@ typedef int (*tune_freq_func_t) (struct si476x_core *core, | |||
1434 | struct si476x_tune_freq_args *tuneargs); | 1434 | struct si476x_tune_freq_args *tuneargs); |
1435 | 1435 | ||
1436 | static struct { | 1436 | static struct { |
1437 | int (*power_up) (struct si476x_core *, | 1437 | int (*power_up)(struct si476x_core *, |
1438 | struct si476x_power_up_args *); | 1438 | struct si476x_power_up_args *); |
1439 | int (*power_down) (struct si476x_core *, | 1439 | int (*power_down)(struct si476x_core *, |
1440 | struct si476x_power_down_args *); | 1440 | struct si476x_power_down_args *); |
1441 | 1441 | ||
1442 | tune_freq_func_t fm_tune_freq; | 1442 | tune_freq_func_t fm_tune_freq; |
1443 | tune_freq_func_t am_tune_freq; | 1443 | tune_freq_func_t am_tune_freq; |
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index a45f9c0a330a..5c054031c3f8 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c | |||
@@ -68,7 +68,7 @@ MODULE_DEVICE_TABLE(of, stmpe_of_match); | |||
68 | static int | 68 | static int |
69 | stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | 69 | stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) |
70 | { | 70 | { |
71 | int partnum; | 71 | enum stmpe_partnum partnum; |
72 | const struct of_device_id *of_id; | 72 | const struct of_device_id *of_id; |
73 | 73 | ||
74 | i2c_ci.data = (void *)id; | 74 | i2c_ci.data = (void *)id; |
@@ -85,7 +85,7 @@ stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | |||
85 | dev_info(&i2c->dev, "matching on node name, compatible is preferred\n"); | 85 | dev_info(&i2c->dev, "matching on node name, compatible is preferred\n"); |
86 | partnum = id->driver_data; | 86 | partnum = id->driver_data; |
87 | } else | 87 | } else |
88 | partnum = (int)of_id->data; | 88 | partnum = (enum stmpe_partnum)of_id->data; |
89 | 89 | ||
90 | return stmpe_probe(&i2c_ci, partnum); | 90 | return stmpe_probe(&i2c_ci, partnum); |
91 | } | 91 | } |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 3b6bfa7184ad..02a17c388e87 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -1147,7 +1147,7 @@ static void stmpe_of_probe(struct stmpe_platform_data *pdata, | |||
1147 | } | 1147 | } |
1148 | 1148 | ||
1149 | /* Called from client specific probe routines */ | 1149 | /* Called from client specific probe routines */ |
1150 | int stmpe_probe(struct stmpe_client_info *ci, int partnum) | 1150 | int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) |
1151 | { | 1151 | { |
1152 | struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev); | 1152 | struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev); |
1153 | struct device_node *np = ci->dev->of_node; | 1153 | struct device_node *np = ci->dev->of_node; |
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index 9e4d21d37a11..2d045f26f193 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h | |||
@@ -97,7 +97,7 @@ struct stmpe_client_info { | |||
97 | void (*init)(struct stmpe *stmpe); | 97 | void (*init)(struct stmpe *stmpe); |
98 | }; | 98 | }; |
99 | 99 | ||
100 | int stmpe_probe(struct stmpe_client_info *ci, int partnum); | 100 | int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum); |
101 | int stmpe_remove(struct stmpe *stmpe); | 101 | int stmpe_remove(struct stmpe *stmpe); |
102 | 102 | ||
103 | #define STMPE_ICR_LSB_HIGH (1 << 2) | 103 | #define STMPE_ICR_LSB_HIGH (1 << 2) |
diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c index 718fc4d2adc0..283ab8d197e4 100644 --- a/drivers/mfd/sun6i-prcm.c +++ b/drivers/mfd/sun6i-prcm.c | |||
@@ -76,16 +76,46 @@ static const struct mfd_cell sun6i_a31_prcm_subdevs[] = { | |||
76 | }, | 76 | }, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static const struct mfd_cell sun8i_a23_prcm_subdevs[] = { | ||
80 | { | ||
81 | .name = "sun8i-a23-apb0-clk", | ||
82 | .of_compatible = "allwinner,sun8i-a23-apb0-clk", | ||
83 | .num_resources = ARRAY_SIZE(sun6i_a31_apb0_clk_res), | ||
84 | .resources = sun6i_a31_apb0_clk_res, | ||
85 | }, | ||
86 | { | ||
87 | .name = "sun6i-a31-apb0-gates-clk", | ||
88 | .of_compatible = "allwinner,sun8i-a23-apb0-gates-clk", | ||
89 | .num_resources = ARRAY_SIZE(sun6i_a31_apb0_gates_clk_res), | ||
90 | .resources = sun6i_a31_apb0_gates_clk_res, | ||
91 | }, | ||
92 | { | ||
93 | .name = "sun6i-a31-apb0-clock-reset", | ||
94 | .of_compatible = "allwinner,sun6i-a31-clock-reset", | ||
95 | .num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res), | ||
96 | .resources = sun6i_a31_apb0_rstc_res, | ||
97 | }, | ||
98 | }; | ||
99 | |||
79 | static const struct prcm_data sun6i_a31_prcm_data = { | 100 | static const struct prcm_data sun6i_a31_prcm_data = { |
80 | .nsubdevs = ARRAY_SIZE(sun6i_a31_prcm_subdevs), | 101 | .nsubdevs = ARRAY_SIZE(sun6i_a31_prcm_subdevs), |
81 | .subdevs = sun6i_a31_prcm_subdevs, | 102 | .subdevs = sun6i_a31_prcm_subdevs, |
82 | }; | 103 | }; |
83 | 104 | ||
105 | static const struct prcm_data sun8i_a23_prcm_data = { | ||
106 | .nsubdevs = ARRAY_SIZE(sun8i_a23_prcm_subdevs), | ||
107 | .subdevs = sun8i_a23_prcm_subdevs, | ||
108 | }; | ||
109 | |||
84 | static const struct of_device_id sun6i_prcm_dt_ids[] = { | 110 | static const struct of_device_id sun6i_prcm_dt_ids[] = { |
85 | { | 111 | { |
86 | .compatible = "allwinner,sun6i-a31-prcm", | 112 | .compatible = "allwinner,sun6i-a31-prcm", |
87 | .data = &sun6i_a31_prcm_data, | 113 | .data = &sun6i_a31_prcm_data, |
88 | }, | 114 | }, |
115 | { | ||
116 | .compatible = "allwinner,sun8i-a23-prcm", | ||
117 | .data = &sun8i_a23_prcm_data, | ||
118 | }, | ||
89 | { /* sentinel */ }, | 119 | { /* sentinel */ }, |
90 | }; | 120 | }; |
91 | 121 | ||
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index bd83accc0f6d..0072e668c208 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -236,7 +236,7 @@ static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq) | |||
236 | static struct irq_domain_ops tc3589x_irq_ops = { | 236 | static struct irq_domain_ops tc3589x_irq_ops = { |
237 | .map = tc3589x_irq_map, | 237 | .map = tc3589x_irq_map, |
238 | .unmap = tc3589x_irq_unmap, | 238 | .unmap = tc3589x_irq_unmap, |
239 | .xlate = irq_domain_xlate_twocell, | 239 | .xlate = irq_domain_xlate_onecell, |
240 | }; | 240 | }; |
241 | 241 | ||
242 | static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) | 242 | static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np) |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index 591a331d8d83..e71f88000ae5 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -147,11 +147,10 @@ static int tc6387xb_probe(struct platform_device *dev) | |||
147 | int irq, ret; | 147 | int irq, ret; |
148 | 148 | ||
149 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); | 149 | iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); |
150 | if (!iomem) { | 150 | if (!iomem) |
151 | return -EINVAL; | 151 | return -EINVAL; |
152 | } | ||
153 | 152 | ||
154 | tc6387xb = kzalloc(sizeof *tc6387xb, GFP_KERNEL); | 153 | tc6387xb = kzalloc(sizeof(*tc6387xb), GFP_KERNEL); |
155 | if (!tc6387xb) | 154 | if (!tc6387xb) |
156 | return -ENOMEM; | 155 | return -ENOMEM; |
157 | 156 | ||
@@ -189,7 +188,7 @@ static int tc6387xb_probe(struct platform_device *dev) | |||
189 | if (pdata && pdata->enable) | 188 | if (pdata && pdata->enable) |
190 | pdata->enable(dev); | 189 | pdata->enable(dev); |
191 | 190 | ||
192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); | 191 | dev_info(&dev->dev, "Toshiba tc6387xb initialised\n"); |
193 | 192 | ||
194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, | 193 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, |
195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL); | 194 | ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL); |
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index b5dfa6e4e692..5de95c265c1a 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c | |||
@@ -141,7 +141,7 @@ static int tps6105x_probe(struct i2c_client *client, | |||
141 | int ret; | 141 | int ret; |
142 | int i; | 142 | int i; |
143 | 143 | ||
144 | tps6105x = kmalloc(sizeof(*tps6105x), GFP_KERNEL); | 144 | tps6105x = devm_kmalloc(&client->dev, sizeof(*tps6105x), GFP_KERNEL); |
145 | if (!tps6105x) | 145 | if (!tps6105x) |
146 | return -ENOMEM; | 146 | return -ENOMEM; |
147 | 147 | ||
@@ -154,7 +154,7 @@ static int tps6105x_probe(struct i2c_client *client, | |||
154 | ret = tps6105x_startup(tps6105x); | 154 | ret = tps6105x_startup(tps6105x); |
155 | if (ret) { | 155 | if (ret) { |
156 | dev_err(&client->dev, "chip initialization failed\n"); | 156 | dev_err(&client->dev, "chip initialization failed\n"); |
157 | goto fail; | 157 | return ret; |
158 | } | 158 | } |
159 | 159 | ||
160 | /* Remove warning texts when you implement new cell drivers */ | 160 | /* Remove warning texts when you implement new cell drivers */ |
@@ -187,16 +187,8 @@ static int tps6105x_probe(struct i2c_client *client, | |||
187 | tps6105x_cells[i].pdata_size = sizeof(*tps6105x); | 187 | tps6105x_cells[i].pdata_size = sizeof(*tps6105x); |
188 | } | 188 | } |
189 | 189 | ||
190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, | 190 | return mfd_add_devices(&client->dev, 0, tps6105x_cells, |
191 | ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); | 191 | ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); |
192 | if (ret) | ||
193 | goto fail; | ||
194 | |||
195 | return 0; | ||
196 | |||
197 | fail: | ||
198 | kfree(tps6105x); | ||
199 | return ret; | ||
200 | } | 192 | } |
201 | 193 | ||
202 | static int tps6105x_remove(struct i2c_client *client) | 194 | static int tps6105x_remove(struct i2c_client *client) |
@@ -210,7 +202,6 @@ static int tps6105x_remove(struct i2c_client *client) | |||
210 | TPS6105X_REG0_MODE_MASK, | 202 | TPS6105X_REG0_MODE_MASK, |
211 | TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); | 203 | TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT); |
212 | 204 | ||
213 | kfree(tps6105x); | ||
214 | return 0; | 205 | return 0; |
215 | } | 206 | } |
216 | 207 | ||
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index f9e42ea1cb1a..f243e75d28f3 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -387,7 +387,7 @@ static const struct of_device_id tps65910_of_match[] = { | |||
387 | MODULE_DEVICE_TABLE(of, tps65910_of_match); | 387 | MODULE_DEVICE_TABLE(of, tps65910_of_match); |
388 | 388 | ||
389 | static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | 389 | static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, |
390 | int *chip_id) | 390 | unsigned long *chip_id) |
391 | { | 391 | { |
392 | struct device_node *np = client->dev.of_node; | 392 | struct device_node *np = client->dev.of_node; |
393 | struct tps65910_board *board_info; | 393 | struct tps65910_board *board_info; |
@@ -401,7 +401,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | |||
401 | return NULL; | 401 | return NULL; |
402 | } | 402 | } |
403 | 403 | ||
404 | *chip_id = (int)match->data; | 404 | *chip_id = (unsigned long)match->data; |
405 | 405 | ||
406 | board_info = devm_kzalloc(&client->dev, sizeof(*board_info), | 406 | board_info = devm_kzalloc(&client->dev, sizeof(*board_info), |
407 | GFP_KERNEL); | 407 | GFP_KERNEL); |
@@ -431,7 +431,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | |||
431 | #else | 431 | #else |
432 | static inline | 432 | static inline |
433 | struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | 433 | struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, |
434 | int *chip_id) | 434 | unsigned long *chip_id) |
435 | { | 435 | { |
436 | return NULL; | 436 | return NULL; |
437 | } | 437 | } |
@@ -453,14 +453,14 @@ static void tps65910_power_off(void) | |||
453 | } | 453 | } |
454 | 454 | ||
455 | static int tps65910_i2c_probe(struct i2c_client *i2c, | 455 | static int tps65910_i2c_probe(struct i2c_client *i2c, |
456 | const struct i2c_device_id *id) | 456 | const struct i2c_device_id *id) |
457 | { | 457 | { |
458 | struct tps65910 *tps65910; | 458 | struct tps65910 *tps65910; |
459 | struct tps65910_board *pmic_plat_data; | 459 | struct tps65910_board *pmic_plat_data; |
460 | struct tps65910_board *of_pmic_plat_data = NULL; | 460 | struct tps65910_board *of_pmic_plat_data = NULL; |
461 | struct tps65910_platform_data *init_data; | 461 | struct tps65910_platform_data *init_data; |
462 | unsigned long chip_id = id->driver_data; | ||
462 | int ret = 0; | 463 | int ret = 0; |
463 | int chip_id = id->driver_data; | ||
464 | 464 | ||
465 | pmic_plat_data = dev_get_platdata(&i2c->dev); | 465 | pmic_plat_data = dev_get_platdata(&i2c->dev); |
466 | 466 | ||
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c index 69a5178bf152..de60ad98bd9f 100644 --- a/drivers/mfd/tps65912-spi.c +++ b/drivers/mfd/tps65912-spi.c | |||
@@ -32,10 +32,9 @@ static int tps65912_spi_write(struct tps65912 *tps65912, u8 addr, | |||
32 | unsigned long spi_data = 1 << 23 | addr << 15 | *data; | 32 | unsigned long spi_data = 1 << 23 | addr << 15 | *data; |
33 | struct spi_transfer xfer; | 33 | struct spi_transfer xfer; |
34 | struct spi_message msg; | 34 | struct spi_message msg; |
35 | u32 tx_buf, rx_buf; | 35 | u32 tx_buf; |
36 | 36 | ||
37 | tx_buf = spi_data; | 37 | tx_buf = spi_data; |
38 | rx_buf = 0; | ||
39 | 38 | ||
40 | xfer.tx_buf = &tx_buf; | 39 | xfer.tx_buf = &tx_buf; |
41 | xfer.rx_buf = NULL; | 40 | xfer.rx_buf = NULL; |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 596b1f657e21..b1dabba763cf 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -297,7 +297,7 @@ static irqreturn_t handle_twl4030_pih(int irq, void *devid) | |||
297 | ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr, | 297 | ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr, |
298 | REG_PIH_ISR_P1); | 298 | REG_PIH_ISR_P1); |
299 | if (ret) { | 299 | if (ret) { |
300 | pr_warning("twl4030: I2C error %d reading PIH ISR\n", ret); | 300 | pr_warn("twl4030: I2C error %d reading PIH ISR\n", ret); |
301 | return IRQ_NONE; | 301 | return IRQ_NONE; |
302 | } | 302 | } |
303 | 303 | ||
@@ -338,7 +338,7 @@ static int twl4030_init_sih_modules(unsigned line) | |||
338 | irq_line = line; | 338 | irq_line = line; |
339 | 339 | ||
340 | /* disable all interrupts on our line */ | 340 | /* disable all interrupts on our line */ |
341 | memset(buf, 0xff, sizeof buf); | 341 | memset(buf, 0xff, sizeof(buf)); |
342 | sih = sih_modules; | 342 | sih = sih_modules; |
343 | for (i = 0; i < nr_sih_modules; i++, sih++) { | 343 | for (i = 0; i < nr_sih_modules; i++, sih++) { |
344 | /* skip USB -- it's funky */ | 344 | /* skip USB -- it's funky */ |
@@ -646,7 +646,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) | |||
646 | if (status < 0) | 646 | if (status < 0) |
647 | return status; | 647 | return status; |
648 | 648 | ||
649 | agent = kzalloc(sizeof *agent, GFP_KERNEL); | 649 | agent = kzalloc(sizeof(*agent), GFP_KERNEL); |
650 | if (!agent) | 650 | if (!agent) |
651 | return -ENOMEM; | 651 | return -ENOMEM; |
652 | 652 | ||
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index a6bb17d908b8..2807e1a95663 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -70,7 +70,7 @@ static int twl6030_interrupt_mapping[24] = { | |||
70 | BATDETECT_INTR_OFFSET, /* Bit 9 BAT */ | 70 | BATDETECT_INTR_OFFSET, /* Bit 9 BAT */ |
71 | SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */ | 71 | SIMDETECT_INTR_OFFSET, /* Bit 10 SIM */ |
72 | MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */ | 72 | MMCDETECT_INTR_OFFSET, /* Bit 11 MMC */ |
73 | RSV_INTR_OFFSET, /* Bit 12 Reserved */ | 73 | RSV_INTR_OFFSET, /* Bit 12 Reserved */ |
74 | MADC_INTR_OFFSET, /* Bit 13 GPADC_RT_EOC */ | 74 | MADC_INTR_OFFSET, /* Bit 13 GPADC_RT_EOC */ |
75 | MADC_INTR_OFFSET, /* Bit 14 GPADC_SW_EOC */ | 75 | MADC_INTR_OFFSET, /* Bit 14 GPADC_SW_EOC */ |
76 | GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */ | 76 | GASGAUGE_INTR_OFFSET, /* Bit 15 CC_AUTOCAL */ |
@@ -245,6 +245,7 @@ int twl6030_interrupt_unmask(u8 bit_mask, u8 offset) | |||
245 | { | 245 | { |
246 | int ret; | 246 | int ret; |
247 | u8 unmask_value; | 247 | u8 unmask_value; |
248 | |||
248 | ret = twl_i2c_read_u8(TWL_MODULE_PIH, &unmask_value, | 249 | ret = twl_i2c_read_u8(TWL_MODULE_PIH, &unmask_value, |
249 | REG_INT_STS_A + offset); | 250 | REG_INT_STS_A + offset); |
250 | unmask_value &= (~(bit_mask)); | 251 | unmask_value &= (~(bit_mask)); |
@@ -258,6 +259,7 @@ int twl6030_interrupt_mask(u8 bit_mask, u8 offset) | |||
258 | { | 259 | { |
259 | int ret; | 260 | int ret; |
260 | u8 mask_value; | 261 | u8 mask_value; |
262 | |||
261 | ret = twl_i2c_read_u8(TWL_MODULE_PIH, &mask_value, | 263 | ret = twl_i2c_read_u8(TWL_MODULE_PIH, &mask_value, |
262 | REG_INT_STS_A + offset); | 264 | REG_INT_STS_A + offset); |
263 | mask_value |= (bit_mask); | 265 | mask_value |= (bit_mask); |
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index ae26d84b3a59..f9c06c542a41 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c | |||
@@ -700,7 +700,7 @@ static int twl6040_probe(struct i2c_client *client, | |||
700 | } | 700 | } |
701 | 701 | ||
702 | ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, | 702 | ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, |
703 | 0, &twl6040_irq_chip,&twl6040->irq_data); | 703 | 0, &twl6040_irq_chip, &twl6040->irq_data); |
704 | if (ret < 0) | 704 | if (ret < 0) |
705 | goto gpio_err; | 705 | goto gpio_err; |
706 | 706 | ||
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index c8a993bd17ae..fb4d4bb0f47d 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
@@ -138,11 +138,11 @@ static const struct regmap_irq wm5102_irqs[ARIZONA_NUM_IRQ] = { | |||
138 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1 | 138 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1 |
139 | }, | 139 | }, |
140 | 140 | ||
141 | [ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = { | 141 | [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = { |
142 | .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1 | 142 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1 |
143 | }, | 143 | }, |
144 | [ARIZONA_IRQ_SPK_SHUTDOWN] = { | 144 | [ARIZONA_IRQ_SPK_OVERHEAT] = { |
145 | .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1 | 145 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1 |
146 | }, | 146 | }, |
147 | [ARIZONA_IRQ_HPDET] = { | 147 | [ARIZONA_IRQ_HPDET] = { |
148 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 | 148 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 |
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index 41a7f6fb7802..9b98ee559188 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c | |||
@@ -340,11 +340,11 @@ static const struct regmap_irq wm5110_irqs[ARIZONA_NUM_IRQ] = { | |||
340 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1 | 340 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1 |
341 | }, | 341 | }, |
342 | 342 | ||
343 | [ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = { | 343 | [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = { |
344 | .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1 | 344 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1 |
345 | }, | 345 | }, |
346 | [ARIZONA_IRQ_SPK_SHUTDOWN] = { | 346 | [ARIZONA_IRQ_SPK_OVERHEAT] = { |
347 | .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1 | 347 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1 |
348 | }, | 348 | }, |
349 | [ARIZONA_IRQ_HPDET] = { | 349 | [ARIZONA_IRQ_HPDET] = { |
350 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 | 350 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 |
@@ -416,16 +416,28 @@ static const struct regmap_irq wm5110_irqs[ARIZONA_NUM_IRQ] = { | |||
416 | [ARIZONA_IRQ_ISRC2_CFG_ERR] = { | 416 | [ARIZONA_IRQ_ISRC2_CFG_ERR] = { |
417 | .reg_offset = 3, .mask = ARIZONA_ISRC2_CFG_ERR_EINT1 | 417 | .reg_offset = 3, .mask = ARIZONA_ISRC2_CFG_ERR_EINT1 |
418 | }, | 418 | }, |
419 | [ARIZONA_IRQ_HP3R_DONE] = { | ||
420 | .reg_offset = 3, .mask = ARIZONA_HP3R_DONE_EINT1 | ||
421 | }, | ||
422 | [ARIZONA_IRQ_HP3L_DONE] = { | ||
423 | .reg_offset = 3, .mask = ARIZONA_HP3L_DONE_EINT1 | ||
424 | }, | ||
425 | [ARIZONA_IRQ_HP2R_DONE] = { | ||
426 | .reg_offset = 3, .mask = ARIZONA_HP2R_DONE_EINT1 | ||
427 | }, | ||
428 | [ARIZONA_IRQ_HP2L_DONE] = { | ||
429 | .reg_offset = 3, .mask = ARIZONA_HP2L_DONE_EINT1 | ||
430 | }, | ||
431 | [ARIZONA_IRQ_HP1R_DONE] = { | ||
432 | .reg_offset = 3, .mask = ARIZONA_HP1R_DONE_EINT1 | ||
433 | }, | ||
434 | [ARIZONA_IRQ_HP1L_DONE] = { | ||
435 | .reg_offset = 3, .mask = ARIZONA_HP1L_DONE_EINT1 | ||
436 | }, | ||
419 | 437 | ||
420 | [ARIZONA_IRQ_BOOT_DONE] = { | 438 | [ARIZONA_IRQ_BOOT_DONE] = { |
421 | .reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1 | 439 | .reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1 |
422 | }, | 440 | }, |
423 | [ARIZONA_IRQ_DCS_DAC_DONE] = { | ||
424 | .reg_offset = 4, .mask = ARIZONA_DCS_DAC_DONE_EINT1 | ||
425 | }, | ||
426 | [ARIZONA_IRQ_DCS_HP_DONE] = { | ||
427 | .reg_offset = 4, .mask = ARIZONA_DCS_HP_DONE_EINT1 | ||
428 | }, | ||
429 | [ARIZONA_IRQ_FLL2_CLOCK_OK] = { | 441 | [ARIZONA_IRQ_FLL2_CLOCK_OK] = { |
430 | .reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1 | 442 | .reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1 |
431 | }, | 443 | }, |
@@ -445,6 +457,209 @@ const struct regmap_irq_chip wm5110_irq = { | |||
445 | }; | 457 | }; |
446 | EXPORT_SYMBOL_GPL(wm5110_irq); | 458 | EXPORT_SYMBOL_GPL(wm5110_irq); |
447 | 459 | ||
460 | static const struct regmap_irq wm5110_revd_irqs[ARIZONA_NUM_IRQ] = { | ||
461 | [ARIZONA_IRQ_GP4] = { .reg_offset = 0, .mask = ARIZONA_GP4_EINT1 }, | ||
462 | [ARIZONA_IRQ_GP3] = { .reg_offset = 0, .mask = ARIZONA_GP3_EINT1 }, | ||
463 | [ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 }, | ||
464 | [ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 }, | ||
465 | |||
466 | [ARIZONA_IRQ_DSP4_RAM_RDY] = { | ||
467 | .reg_offset = 1, .mask = ARIZONA_DSP4_RAM_RDY_EINT1 | ||
468 | }, | ||
469 | [ARIZONA_IRQ_DSP3_RAM_RDY] = { | ||
470 | .reg_offset = 1, .mask = ARIZONA_DSP3_RAM_RDY_EINT1 | ||
471 | }, | ||
472 | [ARIZONA_IRQ_DSP2_RAM_RDY] = { | ||
473 | .reg_offset = 1, .mask = ARIZONA_DSP2_RAM_RDY_EINT1 | ||
474 | }, | ||
475 | [ARIZONA_IRQ_DSP1_RAM_RDY] = { | ||
476 | .reg_offset = 1, .mask = ARIZONA_DSP1_RAM_RDY_EINT1 | ||
477 | }, | ||
478 | [ARIZONA_IRQ_DSP_IRQ8] = { | ||
479 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ8_EINT1 | ||
480 | }, | ||
481 | [ARIZONA_IRQ_DSP_IRQ7] = { | ||
482 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ7_EINT1 | ||
483 | }, | ||
484 | [ARIZONA_IRQ_DSP_IRQ6] = { | ||
485 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ6_EINT1 | ||
486 | }, | ||
487 | [ARIZONA_IRQ_DSP_IRQ5] = { | ||
488 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ5_EINT1 | ||
489 | }, | ||
490 | [ARIZONA_IRQ_DSP_IRQ4] = { | ||
491 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ4_EINT1 | ||
492 | }, | ||
493 | [ARIZONA_IRQ_DSP_IRQ3] = { | ||
494 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ3_EINT1 | ||
495 | }, | ||
496 | [ARIZONA_IRQ_DSP_IRQ2] = { | ||
497 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ2_EINT1 | ||
498 | }, | ||
499 | [ARIZONA_IRQ_DSP_IRQ1] = { | ||
500 | .reg_offset = 1, .mask = ARIZONA_DSP_IRQ1_EINT1 | ||
501 | }, | ||
502 | |||
503 | [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = { | ||
504 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1 | ||
505 | }, | ||
506 | [ARIZONA_IRQ_SPK_OVERHEAT] = { | ||
507 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1 | ||
508 | }, | ||
509 | [ARIZONA_IRQ_HPDET] = { | ||
510 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 | ||
511 | }, | ||
512 | [ARIZONA_IRQ_MICDET] = { | ||
513 | .reg_offset = 2, .mask = ARIZONA_MICDET_EINT1 | ||
514 | }, | ||
515 | [ARIZONA_IRQ_WSEQ_DONE] = { | ||
516 | .reg_offset = 2, .mask = ARIZONA_WSEQ_DONE_EINT1 | ||
517 | }, | ||
518 | [ARIZONA_IRQ_DRC2_SIG_DET] = { | ||
519 | .reg_offset = 2, .mask = ARIZONA_DRC2_SIG_DET_EINT1 | ||
520 | }, | ||
521 | [ARIZONA_IRQ_DRC1_SIG_DET] = { | ||
522 | .reg_offset = 2, .mask = ARIZONA_DRC1_SIG_DET_EINT1 | ||
523 | }, | ||
524 | [ARIZONA_IRQ_ASRC2_LOCK] = { | ||
525 | .reg_offset = 2, .mask = ARIZONA_ASRC2_LOCK_EINT1 | ||
526 | }, | ||
527 | [ARIZONA_IRQ_ASRC1_LOCK] = { | ||
528 | .reg_offset = 2, .mask = ARIZONA_ASRC1_LOCK_EINT1 | ||
529 | }, | ||
530 | [ARIZONA_IRQ_UNDERCLOCKED] = { | ||
531 | .reg_offset = 2, .mask = ARIZONA_UNDERCLOCKED_EINT1 | ||
532 | }, | ||
533 | [ARIZONA_IRQ_OVERCLOCKED] = { | ||
534 | .reg_offset = 2, .mask = ARIZONA_OVERCLOCKED_EINT1 | ||
535 | }, | ||
536 | [ARIZONA_IRQ_FLL2_LOCK] = { | ||
537 | .reg_offset = 2, .mask = ARIZONA_FLL2_LOCK_EINT1 | ||
538 | }, | ||
539 | [ARIZONA_IRQ_FLL1_LOCK] = { | ||
540 | .reg_offset = 2, .mask = ARIZONA_FLL1_LOCK_EINT1 | ||
541 | }, | ||
542 | [ARIZONA_IRQ_CLKGEN_ERR] = { | ||
543 | .reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_EINT1 | ||
544 | }, | ||
545 | [ARIZONA_IRQ_CLKGEN_ERR_ASYNC] = { | ||
546 | .reg_offset = 2, .mask = ARIZONA_CLKGEN_ERR_ASYNC_EINT1 | ||
547 | }, | ||
548 | |||
549 | [ARIZONA_IRQ_CTRLIF_ERR] = { | ||
550 | .reg_offset = 3, .mask = ARIZONA_V2_CTRLIF_ERR_EINT1 | ||
551 | }, | ||
552 | [ARIZONA_IRQ_MIXER_DROPPED_SAMPLES] = { | ||
553 | .reg_offset = 3, .mask = ARIZONA_V2_MIXER_DROPPED_SAMPLE_EINT1 | ||
554 | }, | ||
555 | [ARIZONA_IRQ_ASYNC_CLK_ENA_LOW] = { | ||
556 | .reg_offset = 3, .mask = ARIZONA_V2_ASYNC_CLK_ENA_LOW_EINT1 | ||
557 | }, | ||
558 | [ARIZONA_IRQ_SYSCLK_ENA_LOW] = { | ||
559 | .reg_offset = 3, .mask = ARIZONA_V2_SYSCLK_ENA_LOW_EINT1 | ||
560 | }, | ||
561 | [ARIZONA_IRQ_ISRC1_CFG_ERR] = { | ||
562 | .reg_offset = 3, .mask = ARIZONA_V2_ISRC1_CFG_ERR_EINT1 | ||
563 | }, | ||
564 | [ARIZONA_IRQ_ISRC2_CFG_ERR] = { | ||
565 | .reg_offset = 3, .mask = ARIZONA_V2_ISRC2_CFG_ERR_EINT1 | ||
566 | }, | ||
567 | [ARIZONA_IRQ_ISRC3_CFG_ERR] = { | ||
568 | .reg_offset = 3, .mask = ARIZONA_V2_ISRC3_CFG_ERR_EINT1 | ||
569 | }, | ||
570 | [ARIZONA_IRQ_HP3R_DONE] = { | ||
571 | .reg_offset = 3, .mask = ARIZONA_HP3R_DONE_EINT1 | ||
572 | }, | ||
573 | [ARIZONA_IRQ_HP3L_DONE] = { | ||
574 | .reg_offset = 3, .mask = ARIZONA_HP3L_DONE_EINT1 | ||
575 | }, | ||
576 | [ARIZONA_IRQ_HP2R_DONE] = { | ||
577 | .reg_offset = 3, .mask = ARIZONA_HP2R_DONE_EINT1 | ||
578 | }, | ||
579 | [ARIZONA_IRQ_HP2L_DONE] = { | ||
580 | .reg_offset = 3, .mask = ARIZONA_HP2L_DONE_EINT1 | ||
581 | }, | ||
582 | [ARIZONA_IRQ_HP1R_DONE] = { | ||
583 | .reg_offset = 3, .mask = ARIZONA_HP1R_DONE_EINT1 | ||
584 | }, | ||
585 | [ARIZONA_IRQ_HP1L_DONE] = { | ||
586 | .reg_offset = 3, .mask = ARIZONA_HP1L_DONE_EINT1 | ||
587 | }, | ||
588 | |||
589 | [ARIZONA_IRQ_BOOT_DONE] = { | ||
590 | .reg_offset = 4, .mask = ARIZONA_BOOT_DONE_EINT1 | ||
591 | }, | ||
592 | [ARIZONA_IRQ_ASRC_CFG_ERR] = { | ||
593 | .reg_offset = 4, .mask = ARIZONA_V2_ASRC_CFG_ERR_EINT1 | ||
594 | }, | ||
595 | [ARIZONA_IRQ_FLL2_CLOCK_OK] = { | ||
596 | .reg_offset = 4, .mask = ARIZONA_FLL2_CLOCK_OK_EINT1 | ||
597 | }, | ||
598 | [ARIZONA_IRQ_FLL1_CLOCK_OK] = { | ||
599 | .reg_offset = 4, .mask = ARIZONA_FLL1_CLOCK_OK_EINT1 | ||
600 | }, | ||
601 | |||
602 | [ARIZONA_IRQ_DSP_SHARED_WR_COLL] = { | ||
603 | .reg_offset = 5, .mask = ARIZONA_DSP_SHARED_WR_COLL_EINT1 | ||
604 | }, | ||
605 | [ARIZONA_IRQ_SPK_SHUTDOWN] = { | ||
606 | .reg_offset = 5, .mask = ARIZONA_SPK_SHUTDOWN_EINT1 | ||
607 | }, | ||
608 | [ARIZONA_IRQ_SPK1R_SHORT] = { | ||
609 | .reg_offset = 5, .mask = ARIZONA_SPK1R_SHORT_EINT1 | ||
610 | }, | ||
611 | [ARIZONA_IRQ_SPK1L_SHORT] = { | ||
612 | .reg_offset = 5, .mask = ARIZONA_SPK1L_SHORT_EINT1 | ||
613 | }, | ||
614 | [ARIZONA_IRQ_HP3R_SC_NEG] = { | ||
615 | .reg_offset = 5, .mask = ARIZONA_HP3R_SC_NEG_EINT1 | ||
616 | }, | ||
617 | [ARIZONA_IRQ_HP3R_SC_POS] = { | ||
618 | .reg_offset = 5, .mask = ARIZONA_HP3R_SC_POS_EINT1 | ||
619 | }, | ||
620 | [ARIZONA_IRQ_HP3L_SC_NEG] = { | ||
621 | .reg_offset = 5, .mask = ARIZONA_HP3L_SC_NEG_EINT1 | ||
622 | }, | ||
623 | [ARIZONA_IRQ_HP3L_SC_POS] = { | ||
624 | .reg_offset = 5, .mask = ARIZONA_HP3L_SC_POS_EINT1 | ||
625 | }, | ||
626 | [ARIZONA_IRQ_HP2R_SC_NEG] = { | ||
627 | .reg_offset = 5, .mask = ARIZONA_HP2R_SC_NEG_EINT1 | ||
628 | }, | ||
629 | [ARIZONA_IRQ_HP2R_SC_POS] = { | ||
630 | .reg_offset = 5, .mask = ARIZONA_HP2R_SC_POS_EINT1 | ||
631 | }, | ||
632 | [ARIZONA_IRQ_HP2L_SC_NEG] = { | ||
633 | .reg_offset = 5, .mask = ARIZONA_HP2L_SC_NEG_EINT1 | ||
634 | }, | ||
635 | [ARIZONA_IRQ_HP2L_SC_POS] = { | ||
636 | .reg_offset = 5, .mask = ARIZONA_HP2L_SC_POS_EINT1 | ||
637 | }, | ||
638 | [ARIZONA_IRQ_HP1R_SC_NEG] = { | ||
639 | .reg_offset = 5, .mask = ARIZONA_HP1R_SC_NEG_EINT1 | ||
640 | }, | ||
641 | [ARIZONA_IRQ_HP1R_SC_POS] = { | ||
642 | .reg_offset = 5, .mask = ARIZONA_HP1R_SC_POS_EINT1 | ||
643 | }, | ||
644 | [ARIZONA_IRQ_HP1L_SC_NEG] = { | ||
645 | .reg_offset = 5, .mask = ARIZONA_HP1L_SC_NEG_EINT1 | ||
646 | }, | ||
647 | [ARIZONA_IRQ_HP1L_SC_POS] = { | ||
648 | .reg_offset = 5, .mask = ARIZONA_HP1L_SC_POS_EINT1 | ||
649 | }, | ||
650 | }; | ||
651 | |||
652 | const struct regmap_irq_chip wm5110_revd_irq = { | ||
653 | .name = "wm5110 IRQ", | ||
654 | .status_base = ARIZONA_INTERRUPT_STATUS_1, | ||
655 | .mask_base = ARIZONA_INTERRUPT_STATUS_1_MASK, | ||
656 | .ack_base = ARIZONA_INTERRUPT_STATUS_1, | ||
657 | .num_regs = 6, | ||
658 | .irqs = wm5110_revd_irqs, | ||
659 | .num_irqs = ARRAY_SIZE(wm5110_revd_irqs), | ||
660 | }; | ||
661 | EXPORT_SYMBOL_GPL(wm5110_revd_irq); | ||
662 | |||
448 | static const struct reg_default wm5110_reg_default[] = { | 663 | static const struct reg_default wm5110_reg_default[] = { |
449 | { 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */ | 664 | { 0x00000008, 0x0019 }, /* R8 - Ctrl IF SPI CFG 1 */ |
450 | { 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */ | 665 | { 0x00000009, 0x0001 }, /* R9 - Ctrl IF I2C1 CFG 1 */ |
@@ -1274,12 +1489,14 @@ static const struct reg_default wm5110_reg_default[] = { | |||
1274 | { 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */ | 1489 | { 0x00000D0A, 0xFFFF }, /* R3338 - Interrupt Status 3 Mask */ |
1275 | { 0x00000D0B, 0xFFFF }, /* R3339 - Interrupt Status 4 Mask */ | 1490 | { 0x00000D0B, 0xFFFF }, /* R3339 - Interrupt Status 4 Mask */ |
1276 | { 0x00000D0C, 0xFEFF }, /* R3340 - Interrupt Status 5 Mask */ | 1491 | { 0x00000D0C, 0xFEFF }, /* R3340 - Interrupt Status 5 Mask */ |
1492 | { 0x00000D0D, 0xFFFF }, /* R3341 - Interrupt Status 6 Mask */ | ||
1277 | { 0x00000D0F, 0x0000 }, /* R3343 - Interrupt Control */ | 1493 | { 0x00000D0F, 0x0000 }, /* R3343 - Interrupt Control */ |
1278 | { 0x00000D18, 0xFFFF }, /* R3352 - IRQ2 Status 1 Mask */ | 1494 | { 0x00000D18, 0xFFFF }, /* R3352 - IRQ2 Status 1 Mask */ |
1279 | { 0x00000D19, 0xFFFF }, /* R3353 - IRQ2 Status 2 Mask */ | 1495 | { 0x00000D19, 0xFFFF }, /* R3353 - IRQ2 Status 2 Mask */ |
1280 | { 0x00000D1A, 0xFFFF }, /* R3354 - IRQ2 Status 3 Mask */ | 1496 | { 0x00000D1A, 0xFFFF }, /* R3354 - IRQ2 Status 3 Mask */ |
1281 | { 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */ | 1497 | { 0x00000D1B, 0xFFFF }, /* R3355 - IRQ2 Status 4 Mask */ |
1282 | { 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */ | 1498 | { 0x00000D1C, 0xFFFF }, /* R3356 - IRQ2 Status 5 Mask */ |
1499 | { 0x00000D1D, 0xFFFF }, /* R3357 - IRQ2 Status 6 Mask */ | ||
1283 | { 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */ | 1500 | { 0x00000D1F, 0x0000 }, /* R3359 - IRQ2 Control */ |
1284 | { 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */ | 1501 | { 0x00000D53, 0xFFFF }, /* R3411 - AOD IRQ Mask IRQ1 */ |
1285 | { 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */ | 1502 | { 0x00000D54, 0xFFFF }, /* R3412 - AOD IRQ Mask IRQ2 */ |
@@ -2311,22 +2528,26 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
2311 | case ARIZONA_INTERRUPT_STATUS_3: | 2528 | case ARIZONA_INTERRUPT_STATUS_3: |
2312 | case ARIZONA_INTERRUPT_STATUS_4: | 2529 | case ARIZONA_INTERRUPT_STATUS_4: |
2313 | case ARIZONA_INTERRUPT_STATUS_5: | 2530 | case ARIZONA_INTERRUPT_STATUS_5: |
2531 | case ARIZONA_INTERRUPT_STATUS_6: | ||
2314 | case ARIZONA_INTERRUPT_STATUS_1_MASK: | 2532 | case ARIZONA_INTERRUPT_STATUS_1_MASK: |
2315 | case ARIZONA_INTERRUPT_STATUS_2_MASK: | 2533 | case ARIZONA_INTERRUPT_STATUS_2_MASK: |
2316 | case ARIZONA_INTERRUPT_STATUS_3_MASK: | 2534 | case ARIZONA_INTERRUPT_STATUS_3_MASK: |
2317 | case ARIZONA_INTERRUPT_STATUS_4_MASK: | 2535 | case ARIZONA_INTERRUPT_STATUS_4_MASK: |
2318 | case ARIZONA_INTERRUPT_STATUS_5_MASK: | 2536 | case ARIZONA_INTERRUPT_STATUS_5_MASK: |
2537 | case ARIZONA_INTERRUPT_STATUS_6_MASK: | ||
2319 | case ARIZONA_INTERRUPT_CONTROL: | 2538 | case ARIZONA_INTERRUPT_CONTROL: |
2320 | case ARIZONA_IRQ2_STATUS_1: | 2539 | case ARIZONA_IRQ2_STATUS_1: |
2321 | case ARIZONA_IRQ2_STATUS_2: | 2540 | case ARIZONA_IRQ2_STATUS_2: |
2322 | case ARIZONA_IRQ2_STATUS_3: | 2541 | case ARIZONA_IRQ2_STATUS_3: |
2323 | case ARIZONA_IRQ2_STATUS_4: | 2542 | case ARIZONA_IRQ2_STATUS_4: |
2324 | case ARIZONA_IRQ2_STATUS_5: | 2543 | case ARIZONA_IRQ2_STATUS_5: |
2544 | case ARIZONA_IRQ2_STATUS_6: | ||
2325 | case ARIZONA_IRQ2_STATUS_1_MASK: | 2545 | case ARIZONA_IRQ2_STATUS_1_MASK: |
2326 | case ARIZONA_IRQ2_STATUS_2_MASK: | 2546 | case ARIZONA_IRQ2_STATUS_2_MASK: |
2327 | case ARIZONA_IRQ2_STATUS_3_MASK: | 2547 | case ARIZONA_IRQ2_STATUS_3_MASK: |
2328 | case ARIZONA_IRQ2_STATUS_4_MASK: | 2548 | case ARIZONA_IRQ2_STATUS_4_MASK: |
2329 | case ARIZONA_IRQ2_STATUS_5_MASK: | 2549 | case ARIZONA_IRQ2_STATUS_5_MASK: |
2550 | case ARIZONA_IRQ2_STATUS_6_MASK: | ||
2330 | case ARIZONA_IRQ2_CONTROL: | 2551 | case ARIZONA_IRQ2_CONTROL: |
2331 | case ARIZONA_INTERRUPT_RAW_STATUS_2: | 2552 | case ARIZONA_INTERRUPT_RAW_STATUS_2: |
2332 | case ARIZONA_INTERRUPT_RAW_STATUS_3: | 2553 | case ARIZONA_INTERRUPT_RAW_STATUS_3: |
@@ -2335,6 +2556,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
2335 | case ARIZONA_INTERRUPT_RAW_STATUS_6: | 2556 | case ARIZONA_INTERRUPT_RAW_STATUS_6: |
2336 | case ARIZONA_INTERRUPT_RAW_STATUS_7: | 2557 | case ARIZONA_INTERRUPT_RAW_STATUS_7: |
2337 | case ARIZONA_INTERRUPT_RAW_STATUS_8: | 2558 | case ARIZONA_INTERRUPT_RAW_STATUS_8: |
2559 | case ARIZONA_INTERRUPT_RAW_STATUS_9: | ||
2338 | case ARIZONA_IRQ_PIN_STATUS: | 2560 | case ARIZONA_IRQ_PIN_STATUS: |
2339 | case ARIZONA_AOD_WKUP_AND_TRIG: | 2561 | case ARIZONA_AOD_WKUP_AND_TRIG: |
2340 | case ARIZONA_AOD_IRQ1: | 2562 | case ARIZONA_AOD_IRQ1: |
@@ -2610,11 +2832,13 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) | |||
2610 | case ARIZONA_INTERRUPT_STATUS_3: | 2832 | case ARIZONA_INTERRUPT_STATUS_3: |
2611 | case ARIZONA_INTERRUPT_STATUS_4: | 2833 | case ARIZONA_INTERRUPT_STATUS_4: |
2612 | case ARIZONA_INTERRUPT_STATUS_5: | 2834 | case ARIZONA_INTERRUPT_STATUS_5: |
2835 | case ARIZONA_INTERRUPT_STATUS_6: | ||
2613 | case ARIZONA_IRQ2_STATUS_1: | 2836 | case ARIZONA_IRQ2_STATUS_1: |
2614 | case ARIZONA_IRQ2_STATUS_2: | 2837 | case ARIZONA_IRQ2_STATUS_2: |
2615 | case ARIZONA_IRQ2_STATUS_3: | 2838 | case ARIZONA_IRQ2_STATUS_3: |
2616 | case ARIZONA_IRQ2_STATUS_4: | 2839 | case ARIZONA_IRQ2_STATUS_4: |
2617 | case ARIZONA_IRQ2_STATUS_5: | 2840 | case ARIZONA_IRQ2_STATUS_5: |
2841 | case ARIZONA_IRQ2_STATUS_6: | ||
2618 | case ARIZONA_INTERRUPT_RAW_STATUS_2: | 2842 | case ARIZONA_INTERRUPT_RAW_STATUS_2: |
2619 | case ARIZONA_INTERRUPT_RAW_STATUS_3: | 2843 | case ARIZONA_INTERRUPT_RAW_STATUS_3: |
2620 | case ARIZONA_INTERRUPT_RAW_STATUS_4: | 2844 | case ARIZONA_INTERRUPT_RAW_STATUS_4: |
@@ -2622,6 +2846,7 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) | |||
2622 | case ARIZONA_INTERRUPT_RAW_STATUS_6: | 2846 | case ARIZONA_INTERRUPT_RAW_STATUS_6: |
2623 | case ARIZONA_INTERRUPT_RAW_STATUS_7: | 2847 | case ARIZONA_INTERRUPT_RAW_STATUS_7: |
2624 | case ARIZONA_INTERRUPT_RAW_STATUS_8: | 2848 | case ARIZONA_INTERRUPT_RAW_STATUS_8: |
2849 | case ARIZONA_INTERRUPT_RAW_STATUS_9: | ||
2625 | case ARIZONA_IRQ_PIN_STATUS: | 2850 | case ARIZONA_IRQ_PIN_STATUS: |
2626 | case ARIZONA_AOD_WKUP_AND_TRIG: | 2851 | case ARIZONA_AOD_WKUP_AND_TRIG: |
2627 | case ARIZONA_AOD_IRQ1: | 2852 | case ARIZONA_AOD_IRQ1: |
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index f919def05e24..6a16a8a6f9fa 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c | |||
@@ -58,10 +58,10 @@ static int wm8350_i2c_remove(struct i2c_client *i2c) | |||
58 | } | 58 | } |
59 | 59 | ||
60 | static const struct i2c_device_id wm8350_i2c_id[] = { | 60 | static const struct i2c_device_id wm8350_i2c_id[] = { |
61 | { "wm8350", 0 }, | 61 | { "wm8350", 0 }, |
62 | { "wm8351", 0 }, | 62 | { "wm8351", 0 }, |
63 | { "wm8352", 0 }, | 63 | { "wm8352", 0 }, |
64 | { } | 64 | { } |
65 | }; | 65 | }; |
66 | MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id); | 66 | MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id); |
67 | 67 | ||
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index cd01f7962dfd..813ff50f95b6 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
@@ -497,7 +497,8 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq, | |||
497 | if (pdata && pdata->irq_base > 0) | 497 | if (pdata && pdata->irq_base > 0) |
498 | irq_base = pdata->irq_base; | 498 | irq_base = pdata->irq_base; |
499 | 499 | ||
500 | wm8350->irq_base = irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0); | 500 | wm8350->irq_base = |
501 | irq_alloc_descs(irq_base, 0, ARRAY_SIZE(wm8350_irqs), 0); | ||
501 | if (wm8350->irq_base < 0) { | 502 | if (wm8350->irq_base < 0) { |
502 | dev_warn(wm8350->dev, "Allocating irqs failed with %d\n", | 503 | dev_warn(wm8350->dev, "Allocating irqs failed with %d\n", |
503 | wm8350->irq_base); | 504 | wm8350->irq_base); |
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c index 2fbce9c5950b..770a25696468 100644 --- a/drivers/mfd/wm8994-regmap.c +++ b/drivers/mfd/wm8994-regmap.c | |||
@@ -123,14 +123,23 @@ static struct reg_default wm1811_defaults[] = { | |||
123 | { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */ | 123 | { 0x0402, 0x00C0 }, /* R1026 - AIF1 DAC1 Left Volume */ |
124 | { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */ | 124 | { 0x0403, 0x00C0 }, /* R1027 - AIF1 DAC1 Right Volume */ |
125 | { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */ | 125 | { 0x0410, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */ |
126 | { 0x0411, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */ | ||
126 | { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */ | 127 | { 0x0420, 0x0200 }, /* R1056 - AIF1 DAC1 Filters (1) */ |
127 | { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */ | 128 | { 0x0421, 0x0010 }, /* R1057 - AIF1 DAC1 Filters (2) */ |
129 | { 0x0422, 0x0200 }, /* R1058 - AIF1 DAC2 Filters (1) */ | ||
130 | { 0x0423, 0x0010 }, /* R1059 - AIF1 DAC2 Filters (2) */ | ||
128 | { 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */ | 131 | { 0x0430, 0x0068 }, /* R1072 - AIF1 DAC1 Noise Gate */ |
132 | { 0x0431, 0x0068 }, /* R1073 - AIF1 DAC2 Noise Gate */ | ||
129 | { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */ | 133 | { 0x0440, 0x0098 }, /* R1088 - AIF1 DRC1 (1) */ |
130 | { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */ | 134 | { 0x0441, 0x0845 }, /* R1089 - AIF1 DRC1 (2) */ |
131 | { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */ | 135 | { 0x0442, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */ |
132 | { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */ | 136 | { 0x0443, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */ |
133 | { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */ | 137 | { 0x0444, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */ |
138 | { 0x0450, 0x0098 }, /* R1104 - AIF1 DRC2 (1) */ | ||
139 | { 0x0451, 0x0845 }, /* R1105 - AIF1 DRC2 (2) */ | ||
140 | { 0x0452, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */ | ||
141 | { 0x0453, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */ | ||
142 | { 0x0454, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */ | ||
134 | { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ | 143 | { 0x0480, 0x6318 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ |
135 | { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ | 144 | { 0x0481, 0x6300 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ |
136 | { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ | 145 | { 0x0482, 0x0FCA }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ |
@@ -152,6 +161,27 @@ static struct reg_default wm1811_defaults[] = { | |||
152 | { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ | 161 | { 0x0492, 0x0559 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ |
153 | { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ | 162 | { 0x0493, 0x4000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ |
154 | { 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */ | 163 | { 0x0494, 0x0000 }, /* R1172 - AIF1 DAC1 EQ Band 1 C */ |
164 | { 0x04A0, 0x6318 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ | ||
165 | { 0x04A1, 0x6300 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ | ||
166 | { 0x04A2, 0x0FCA }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ | ||
167 | { 0x04A3, 0x0400 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ | ||
168 | { 0x04A4, 0x00D8 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ | ||
169 | { 0x04A5, 0x1EB5 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ | ||
170 | { 0x04A6, 0xF145 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ | ||
171 | { 0x04A7, 0x0B75 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ | ||
172 | { 0x04A8, 0x01C5 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ | ||
173 | { 0x04A9, 0x1C58 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ | ||
174 | { 0x04AA, 0xF373 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ | ||
175 | { 0x04AB, 0x0A54 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ | ||
176 | { 0x04AC, 0x0558 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ | ||
177 | { 0x04AD, 0x168E }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ | ||
178 | { 0x04AE, 0xF829 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ | ||
179 | { 0x04AF, 0x07AD }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ | ||
180 | { 0x04B0, 0x1103 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ | ||
181 | { 0x04B1, 0x0564 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ | ||
182 | { 0x04B2, 0x0559 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ | ||
183 | { 0x04B3, 0x4000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ | ||
184 | { 0x04B4, 0x0000 }, /* R1204 - AIF1 DAC2 EQ Band 1 C */ | ||
155 | { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */ | 185 | { 0x0500, 0x00C0 }, /* R1280 - AIF2 ADC Left Volume */ |
156 | { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */ | 186 | { 0x0501, 0x00C0 }, /* R1281 - AIF2 ADC Right Volume */ |
157 | { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */ | 187 | { 0x0502, 0x00C0 }, /* R1282 - AIF2 DAC Left Volume */ |
@@ -194,6 +224,8 @@ static struct reg_default wm1811_defaults[] = { | |||
194 | { 0x0605, 0x0000 }, /* R1541 - AIF2ADC Right Mixer Routing */ | 224 | { 0x0605, 0x0000 }, /* R1541 - AIF2ADC Right Mixer Routing */ |
195 | { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ | 225 | { 0x0606, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ |
196 | { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ | 226 | { 0x0607, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ |
227 | { 0x0608, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ | ||
228 | { 0x0609, 0x0000 }, /* R1545 - AIF1 ADC2 Right Mixer Routing */ | ||
197 | { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */ | 229 | { 0x0610, 0x02C0 }, /* R1552 - DAC1 Left Volume */ |
198 | { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */ | 230 | { 0x0611, 0x02C0 }, /* R1553 - DAC1 Right Volume */ |
199 | { 0x0612, 0x02C0 }, /* R1554 - AIF2TX Left Volume */ | 231 | { 0x0612, 0x02C0 }, /* R1554 - AIF2TX Left Volume */ |
@@ -846,14 +878,23 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg) | |||
846 | case WM8994_AIF1_DAC1_LEFT_VOLUME: | 878 | case WM8994_AIF1_DAC1_LEFT_VOLUME: |
847 | case WM8994_AIF1_DAC1_RIGHT_VOLUME: | 879 | case WM8994_AIF1_DAC1_RIGHT_VOLUME: |
848 | case WM8994_AIF1_ADC1_FILTERS: | 880 | case WM8994_AIF1_ADC1_FILTERS: |
881 | case WM8994_AIF1_ADC2_FILTERS: | ||
849 | case WM8994_AIF1_DAC1_FILTERS_1: | 882 | case WM8994_AIF1_DAC1_FILTERS_1: |
850 | case WM8994_AIF1_DAC1_FILTERS_2: | 883 | case WM8994_AIF1_DAC1_FILTERS_2: |
884 | case WM8994_AIF1_DAC2_FILTERS_1: | ||
885 | case WM8994_AIF1_DAC2_FILTERS_2: | ||
851 | case WM8958_AIF1_DAC1_NOISE_GATE: | 886 | case WM8958_AIF1_DAC1_NOISE_GATE: |
887 | case WM8958_AIF1_DAC2_NOISE_GATE: | ||
852 | case WM8994_AIF1_DRC1_1: | 888 | case WM8994_AIF1_DRC1_1: |
853 | case WM8994_AIF1_DRC1_2: | 889 | case WM8994_AIF1_DRC1_2: |
854 | case WM8994_AIF1_DRC1_3: | 890 | case WM8994_AIF1_DRC1_3: |
855 | case WM8994_AIF1_DRC1_4: | 891 | case WM8994_AIF1_DRC1_4: |
856 | case WM8994_AIF1_DRC1_5: | 892 | case WM8994_AIF1_DRC1_5: |
893 | case WM8994_AIF1_DRC2_1: | ||
894 | case WM8994_AIF1_DRC2_2: | ||
895 | case WM8994_AIF1_DRC2_3: | ||
896 | case WM8994_AIF1_DRC2_4: | ||
897 | case WM8994_AIF1_DRC2_5: | ||
857 | case WM8994_AIF1_DAC1_EQ_GAINS_1: | 898 | case WM8994_AIF1_DAC1_EQ_GAINS_1: |
858 | case WM8994_AIF1_DAC1_EQ_GAINS_2: | 899 | case WM8994_AIF1_DAC1_EQ_GAINS_2: |
859 | case WM8994_AIF1_DAC1_EQ_BAND_1_A: | 900 | case WM8994_AIF1_DAC1_EQ_BAND_1_A: |
@@ -875,6 +916,27 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg) | |||
875 | case WM8994_AIF1_DAC1_EQ_BAND_5_B: | 916 | case WM8994_AIF1_DAC1_EQ_BAND_5_B: |
876 | case WM8994_AIF1_DAC1_EQ_BAND_5_PG: | 917 | case WM8994_AIF1_DAC1_EQ_BAND_5_PG: |
877 | case WM8994_AIF1_DAC1_EQ_BAND_1_C: | 918 | case WM8994_AIF1_DAC1_EQ_BAND_1_C: |
919 | case WM8994_AIF1_DAC2_EQ_GAINS_1: | ||
920 | case WM8994_AIF1_DAC2_EQ_GAINS_2: | ||
921 | case WM8994_AIF1_DAC2_EQ_BAND_1_A: | ||
922 | case WM8994_AIF1_DAC2_EQ_BAND_1_B: | ||
923 | case WM8994_AIF1_DAC2_EQ_BAND_1_PG: | ||
924 | case WM8994_AIF1_DAC2_EQ_BAND_2_A: | ||
925 | case WM8994_AIF1_DAC2_EQ_BAND_2_B: | ||
926 | case WM8994_AIF1_DAC2_EQ_BAND_2_C: | ||
927 | case WM8994_AIF1_DAC2_EQ_BAND_2_PG: | ||
928 | case WM8994_AIF1_DAC2_EQ_BAND_3_A: | ||
929 | case WM8994_AIF1_DAC2_EQ_BAND_3_B: | ||
930 | case WM8994_AIF1_DAC2_EQ_BAND_3_C: | ||
931 | case WM8994_AIF1_DAC2_EQ_BAND_3_PG: | ||
932 | case WM8994_AIF1_DAC2_EQ_BAND_4_A: | ||
933 | case WM8994_AIF1_DAC2_EQ_BAND_4_B: | ||
934 | case WM8994_AIF1_DAC2_EQ_BAND_4_C: | ||
935 | case WM8994_AIF1_DAC2_EQ_BAND_4_PG: | ||
936 | case WM8994_AIF1_DAC2_EQ_BAND_5_A: | ||
937 | case WM8994_AIF1_DAC2_EQ_BAND_5_B: | ||
938 | case WM8994_AIF1_DAC2_EQ_BAND_5_PG: | ||
939 | case WM8994_AIF1_DAC2_EQ_BAND_1_C: | ||
878 | case WM8994_AIF2_ADC_LEFT_VOLUME: | 940 | case WM8994_AIF2_ADC_LEFT_VOLUME: |
879 | case WM8994_AIF2_ADC_RIGHT_VOLUME: | 941 | case WM8994_AIF2_ADC_RIGHT_VOLUME: |
880 | case WM8994_AIF2_DAC_LEFT_VOLUME: | 942 | case WM8994_AIF2_DAC_LEFT_VOLUME: |
@@ -917,6 +979,8 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg) | |||
917 | case WM8994_DAC2_RIGHT_MIXER_ROUTING: | 979 | case WM8994_DAC2_RIGHT_MIXER_ROUTING: |
918 | case WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING: | 980 | case WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING: |
919 | case WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING: | 981 | case WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING: |
982 | case WM8994_AIF1_ADC2_LEFT_MIXER_ROUTING: | ||
983 | case WM8994_AIF1_ADC2_RIGHT_MIXER_ROUTING: | ||
920 | case WM8994_DAC1_LEFT_VOLUME: | 984 | case WM8994_DAC1_LEFT_VOLUME: |
921 | case WM8994_DAC1_RIGHT_VOLUME: | 985 | case WM8994_DAC1_RIGHT_VOLUME: |
922 | case WM8994_DAC2_LEFT_VOLUME: | 986 | case WM8994_DAC2_LEFT_VOLUME: |
diff --git a/drivers/mfd/wm8997-tables.c b/drivers/mfd/wm8997-tables.c index c7a81da64ee1..510da3b52324 100644 --- a/drivers/mfd/wm8997-tables.c +++ b/drivers/mfd/wm8997-tables.c | |||
@@ -65,11 +65,11 @@ static const struct regmap_irq wm8997_irqs[ARIZONA_NUM_IRQ] = { | |||
65 | [ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 }, | 65 | [ARIZONA_IRQ_GP2] = { .reg_offset = 0, .mask = ARIZONA_GP2_EINT1 }, |
66 | [ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 }, | 66 | [ARIZONA_IRQ_GP1] = { .reg_offset = 0, .mask = ARIZONA_GP1_EINT1 }, |
67 | 67 | ||
68 | [ARIZONA_IRQ_SPK_SHUTDOWN_WARN] = { | 68 | [ARIZONA_IRQ_SPK_OVERHEAT_WARN] = { |
69 | .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_WARN_EINT1 | 69 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_WARN_EINT1 |
70 | }, | 70 | }, |
71 | [ARIZONA_IRQ_SPK_SHUTDOWN] = { | 71 | [ARIZONA_IRQ_SPK_OVERHEAT] = { |
72 | .reg_offset = 2, .mask = ARIZONA_SPK_SHUTDOWN_EINT1 | 72 | .reg_offset = 2, .mask = ARIZONA_SPK_OVERHEAT_EINT1 |
73 | }, | 73 | }, |
74 | [ARIZONA_IRQ_HPDET] = { | 74 | [ARIZONA_IRQ_HPDET] = { |
75 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 | 75 | .reg_offset = 2, .mask = ARIZONA_HPDET_EINT1 |
@@ -174,10 +174,10 @@ static const struct reg_default wm8997_reg_default[] = { | |||
174 | { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ | 174 | { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ |
175 | { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ | 175 | { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ |
176 | { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ | 176 | { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ |
177 | { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 3 */ | 177 | { 0x00000068, 0x01FF }, /* R104 - AlwaysOn Triggers Seq Select 3 */ |
178 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */ | 178 | { 0x00000069, 0x01FF }, /* R105 - AlwaysOn Triggers Seq Select 4 */ |
179 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */ | 179 | { 0x0000006A, 0x01FF }, /* R106 - AlwaysOn Triggers Seq Select 5 */ |
180 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 6 */ | 180 | { 0x0000006B, 0x01FF }, /* R107 - AlwaysOn Triggers Seq Select 6 */ |
181 | { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ | 181 | { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ |
182 | { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ | 182 | { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ |
183 | { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ | 183 | { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ |
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 0d519649b575..dfde4a210238 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/highmem.h> | 24 | #include <linux/highmem.h> |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/workqueue.h> | ||
27 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
28 | #include <linux/mmc/mmc.h> | 29 | #include <linux/mmc/mmc.h> |
29 | #include <linux/mmc/sd.h> | 30 | #include <linux/mmc/sd.h> |
@@ -36,7 +37,10 @@ struct realtek_pci_sdmmc { | |||
36 | struct rtsx_pcr *pcr; | 37 | struct rtsx_pcr *pcr; |
37 | struct mmc_host *mmc; | 38 | struct mmc_host *mmc; |
38 | struct mmc_request *mrq; | 39 | struct mmc_request *mrq; |
40 | struct workqueue_struct *workq; | ||
41 | #define SDMMC_WORKQ_NAME "rtsx_pci_sdmmc_workq" | ||
39 | 42 | ||
43 | struct work_struct work; | ||
40 | struct mutex host_mutex; | 44 | struct mutex host_mutex; |
41 | 45 | ||
42 | u8 ssc_depth; | 46 | u8 ssc_depth; |
@@ -48,6 +52,11 @@ struct realtek_pci_sdmmc { | |||
48 | int power_state; | 52 | int power_state; |
49 | #define SDMMC_POWER_ON 1 | 53 | #define SDMMC_POWER_ON 1 |
50 | #define SDMMC_POWER_OFF 0 | 54 | #define SDMMC_POWER_OFF 0 |
55 | |||
56 | unsigned int sg_count; | ||
57 | s32 cookie; | ||
58 | unsigned int cookie_sg_count; | ||
59 | bool using_cookie; | ||
51 | }; | 60 | }; |
52 | 61 | ||
53 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) | 62 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) |
@@ -86,6 +95,77 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) | |||
86 | #define sd_print_debug_regs(host) | 95 | #define sd_print_debug_regs(host) |
87 | #endif /* DEBUG */ | 96 | #endif /* DEBUG */ |
88 | 97 | ||
98 | /* | ||
99 | * sd_pre_dma_transfer - do dma_map_sg() or using cookie | ||
100 | * | ||
101 | * @pre: if called in pre_req() | ||
102 | * return: | ||
103 | * 0 - do dma_map_sg() | ||
104 | * 1 - using cookie | ||
105 | */ | ||
106 | static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host, | ||
107 | struct mmc_data *data, bool pre) | ||
108 | { | ||
109 | struct rtsx_pcr *pcr = host->pcr; | ||
110 | int read = data->flags & MMC_DATA_READ; | ||
111 | int count = 0; | ||
112 | int using_cookie = 0; | ||
113 | |||
114 | if (!pre && data->host_cookie && data->host_cookie != host->cookie) { | ||
115 | dev_err(sdmmc_dev(host), | ||
116 | "error: data->host_cookie = %d, host->cookie = %d\n", | ||
117 | data->host_cookie, host->cookie); | ||
118 | data->host_cookie = 0; | ||
119 | } | ||
120 | |||
121 | if (pre || data->host_cookie != host->cookie) { | ||
122 | count = rtsx_pci_dma_map_sg(pcr, data->sg, data->sg_len, read); | ||
123 | } else { | ||
124 | count = host->cookie_sg_count; | ||
125 | using_cookie = 1; | ||
126 | } | ||
127 | |||
128 | if (pre) { | ||
129 | host->cookie_sg_count = count; | ||
130 | if (++host->cookie < 0) | ||
131 | host->cookie = 1; | ||
132 | data->host_cookie = host->cookie; | ||
133 | } else { | ||
134 | host->sg_count = count; | ||
135 | } | ||
136 | |||
137 | return using_cookie; | ||
138 | } | ||
139 | |||
140 | static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
141 | bool is_first_req) | ||
142 | { | ||
143 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
144 | struct mmc_data *data = mrq->data; | ||
145 | |||
146 | if (data->host_cookie) { | ||
147 | dev_err(sdmmc_dev(host), | ||
148 | "error: reset data->host_cookie = %d\n", | ||
149 | data->host_cookie); | ||
150 | data->host_cookie = 0; | ||
151 | } | ||
152 | |||
153 | sd_pre_dma_transfer(host, data, true); | ||
154 | dev_dbg(sdmmc_dev(host), "pre dma sg: %d\n", host->cookie_sg_count); | ||
155 | } | ||
156 | |||
157 | static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
158 | int err) | ||
159 | { | ||
160 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
161 | struct rtsx_pcr *pcr = host->pcr; | ||
162 | struct mmc_data *data = mrq->data; | ||
163 | int read = data->flags & MMC_DATA_READ; | ||
164 | |||
165 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read); | ||
166 | data->host_cookie = 0; | ||
167 | } | ||
168 | |||
89 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | 169 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, |
90 | u8 *buf, int buf_len, int timeout) | 170 | u8 *buf, int buf_len, int timeout) |
91 | { | 171 | { |
@@ -415,7 +495,7 @@ static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) | |||
415 | 495 | ||
416 | rtsx_pci_send_cmd_no_wait(pcr); | 496 | rtsx_pci_send_cmd_no_wait(pcr); |
417 | 497 | ||
418 | err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000); | 498 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read, 10000); |
419 | if (err < 0) { | 499 | if (err < 0) { |
420 | sd_clear_error(host); | 500 | sd_clear_error(host); |
421 | return err; | 501 | return err; |
@@ -640,12 +720,24 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
640 | return 0; | 720 | return 0; |
641 | } | 721 | } |
642 | 722 | ||
643 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | 723 | static inline int sd_rw_cmd(struct mmc_command *cmd) |
644 | { | 724 | { |
645 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | 725 | return mmc_op_multi(cmd->opcode) || |
726 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || | ||
727 | (cmd->opcode == MMC_WRITE_BLOCK); | ||
728 | } | ||
729 | |||
730 | static void sd_request(struct work_struct *work) | ||
731 | { | ||
732 | struct realtek_pci_sdmmc *host = container_of(work, | ||
733 | struct realtek_pci_sdmmc, work); | ||
646 | struct rtsx_pcr *pcr = host->pcr; | 734 | struct rtsx_pcr *pcr = host->pcr; |
735 | |||
736 | struct mmc_host *mmc = host->mmc; | ||
737 | struct mmc_request *mrq = host->mrq; | ||
647 | struct mmc_command *cmd = mrq->cmd; | 738 | struct mmc_command *cmd = mrq->cmd; |
648 | struct mmc_data *data = mrq->data; | 739 | struct mmc_data *data = mrq->data; |
740 | |||
649 | unsigned int data_size = 0; | 741 | unsigned int data_size = 0; |
650 | int err; | 742 | int err; |
651 | 743 | ||
@@ -677,13 +769,13 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
677 | if (mrq->data) | 769 | if (mrq->data) |
678 | data_size = data->blocks * data->blksz; | 770 | data_size = data->blocks * data->blksz; |
679 | 771 | ||
680 | if (!data_size || mmc_op_multi(cmd->opcode) || | 772 | if (!data_size || sd_rw_cmd(cmd)) { |
681 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || | ||
682 | (cmd->opcode == MMC_WRITE_BLOCK)) { | ||
683 | sd_send_cmd_get_rsp(host, cmd); | 773 | sd_send_cmd_get_rsp(host, cmd); |
684 | 774 | ||
685 | if (!cmd->error && data_size) { | 775 | if (!cmd->error && data_size) { |
686 | sd_rw_multi(host, mrq); | 776 | sd_rw_multi(host, mrq); |
777 | if (!host->using_cookie) | ||
778 | sdmmc_post_req(host->mmc, host->mrq, 0); | ||
687 | 779 | ||
688 | if (mmc_op_multi(cmd->opcode) && mrq->stop) | 780 | if (mmc_op_multi(cmd->opcode) && mrq->stop) |
689 | sd_send_cmd_get_rsp(host, mrq->stop); | 781 | sd_send_cmd_get_rsp(host, mrq->stop); |
@@ -712,6 +804,21 @@ finish: | |||
712 | mmc_request_done(mmc, mrq); | 804 | mmc_request_done(mmc, mrq); |
713 | } | 805 | } |
714 | 806 | ||
807 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | ||
808 | { | ||
809 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
810 | struct mmc_data *data = mrq->data; | ||
811 | |||
812 | mutex_lock(&host->host_mutex); | ||
813 | host->mrq = mrq; | ||
814 | mutex_unlock(&host->host_mutex); | ||
815 | |||
816 | if (sd_rw_cmd(mrq->cmd)) | ||
817 | host->using_cookie = sd_pre_dma_transfer(host, data, false); | ||
818 | |||
819 | queue_work(host->workq, &host->work); | ||
820 | } | ||
821 | |||
715 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, | 822 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, |
716 | unsigned char bus_width) | 823 | unsigned char bus_width) |
717 | { | 824 | { |
@@ -1146,6 +1253,8 @@ out: | |||
1146 | } | 1253 | } |
1147 | 1254 | ||
1148 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { | 1255 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { |
1256 | .pre_req = sdmmc_pre_req, | ||
1257 | .post_req = sdmmc_post_req, | ||
1149 | .request = sdmmc_request, | 1258 | .request = sdmmc_request, |
1150 | .set_ios = sdmmc_set_ios, | 1259 | .set_ios = sdmmc_set_ios, |
1151 | .get_ro = sdmmc_get_ro, | 1260 | .get_ro = sdmmc_get_ro, |
@@ -1224,10 +1333,16 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1224 | return -ENOMEM; | 1333 | return -ENOMEM; |
1225 | 1334 | ||
1226 | host = mmc_priv(mmc); | 1335 | host = mmc_priv(mmc); |
1336 | host->workq = create_singlethread_workqueue(SDMMC_WORKQ_NAME); | ||
1337 | if (!host->workq) { | ||
1338 | mmc_free_host(mmc); | ||
1339 | return -ENOMEM; | ||
1340 | } | ||
1227 | host->pcr = pcr; | 1341 | host->pcr = pcr; |
1228 | host->mmc = mmc; | 1342 | host->mmc = mmc; |
1229 | host->pdev = pdev; | 1343 | host->pdev = pdev; |
1230 | host->power_state = SDMMC_POWER_OFF; | 1344 | host->power_state = SDMMC_POWER_OFF; |
1345 | INIT_WORK(&host->work, sd_request); | ||
1231 | platform_set_drvdata(pdev, host); | 1346 | platform_set_drvdata(pdev, host); |
1232 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; | 1347 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; |
1233 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; | 1348 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; |
@@ -1255,6 +1370,8 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
1255 | pcr->slots[RTSX_SD_CARD].card_event = NULL; | 1370 | pcr->slots[RTSX_SD_CARD].card_event = NULL; |
1256 | mmc = host->mmc; | 1371 | mmc = host->mmc; |
1257 | 1372 | ||
1373 | cancel_work_sync(&host->work); | ||
1374 | |||
1258 | mutex_lock(&host->host_mutex); | 1375 | mutex_lock(&host->host_mutex); |
1259 | if (host->mrq) { | 1376 | if (host->mrq) { |
1260 | dev_dbg(&(pdev->dev), | 1377 | dev_dbg(&(pdev->dev), |
@@ -1273,6 +1390,10 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
1273 | mmc_remove_host(mmc); | 1390 | mmc_remove_host(mmc); |
1274 | host->eject = true; | 1391 | host->eject = true; |
1275 | 1392 | ||
1393 | flush_workqueue(host->workq); | ||
1394 | destroy_workqueue(host->workq); | ||
1395 | host->workq = NULL; | ||
1396 | |||
1276 | mmc_free_host(mmc); | 1397 | mmc_free_host(mmc); |
1277 | 1398 | ||
1278 | dev_dbg(&(pdev->dev), | 1399 | dev_dbg(&(pdev->dev), |
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 2b7e9e220497..b16c53a8272f 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/mfd/samsung/core.h> | 31 | #include <linux/mfd/samsung/core.h> |
32 | #include <linux/mfd/samsung/s2mps11.h> | 32 | #include <linux/mfd/samsung/s2mps11.h> |
33 | #include <linux/mfd/samsung/s2mps14.h> | 33 | #include <linux/mfd/samsung/s2mps14.h> |
34 | #include <linux/mfd/samsung/s2mpu02.h> | ||
34 | 35 | ||
35 | struct s2mps11_info { | 36 | struct s2mps11_info { |
36 | unsigned int rdev_num; | 37 | unsigned int rdev_num; |
@@ -40,11 +41,15 @@ struct s2mps11_info { | |||
40 | int ramp_delay16; | 41 | int ramp_delay16; |
41 | int ramp_delay7810; | 42 | int ramp_delay7810; |
42 | int ramp_delay9; | 43 | int ramp_delay9; |
44 | |||
45 | enum sec_device_type dev_type; | ||
46 | |||
43 | /* | 47 | /* |
44 | * One bit for each S2MPS14 regulator whether the suspend mode | 48 | * One bit for each S2MPS14/S2MPU02 regulator whether the suspend mode |
45 | * was enabled. | 49 | * was enabled. |
46 | */ | 50 | */ |
47 | unsigned int s2mps14_suspend_state:30; | 51 | unsigned long long s2mps14_suspend_state:35; |
52 | |||
48 | /* Array of size rdev_num with GPIO-s for external sleep control */ | 53 | /* Array of size rdev_num with GPIO-s for external sleep control */ |
49 | int *ext_control_gpio; | 54 | int *ext_control_gpio; |
50 | }; | 55 | }; |
@@ -415,12 +420,24 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) | |||
415 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | 420 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); |
416 | unsigned int val; | 421 | unsigned int val; |
417 | 422 | ||
418 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | 423 | switch (s2mps11->dev_type) { |
419 | val = S2MPS14_ENABLE_SUSPEND; | 424 | case S2MPS14X: |
420 | else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) | 425 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) |
421 | val = S2MPS14_ENABLE_EXT_CONTROL; | 426 | val = S2MPS14_ENABLE_SUSPEND; |
422 | else | 427 | else if (gpio_is_valid(s2mps11->ext_control_gpio[rdev_get_id(rdev)])) |
423 | val = rdev->desc->enable_mask; | 428 | val = S2MPS14_ENABLE_EXT_CONTROL; |
429 | else | ||
430 | val = rdev->desc->enable_mask; | ||
431 | break; | ||
432 | case S2MPU02: | ||
433 | if (s2mps11->s2mps14_suspend_state & (1 << rdev_get_id(rdev))) | ||
434 | val = S2MPU02_ENABLE_SUSPEND; | ||
435 | else | ||
436 | val = rdev->desc->enable_mask; | ||
437 | break; | ||
438 | default: | ||
439 | return -EINVAL; | ||
440 | }; | ||
424 | 441 | ||
425 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 442 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
426 | rdev->desc->enable_mask, val); | 443 | rdev->desc->enable_mask, val); |
@@ -429,12 +446,38 @@ static int s2mps14_regulator_enable(struct regulator_dev *rdev) | |||
429 | static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | 446 | static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) |
430 | { | 447 | { |
431 | int ret; | 448 | int ret; |
432 | unsigned int val; | 449 | unsigned int val, state; |
433 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); | 450 | struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); |
451 | int rdev_id = rdev_get_id(rdev); | ||
434 | 452 | ||
435 | /* LDO3 should be always on and does not support suspend mode */ | 453 | /* Below LDO should be always on or does not support suspend mode. */ |
436 | if (rdev_get_id(rdev) == S2MPS14_LDO3) | 454 | switch (s2mps11->dev_type) { |
437 | return 0; | 455 | case S2MPS14X: |
456 | switch (rdev_id) { | ||
457 | case S2MPS14_LDO3: | ||
458 | return 0; | ||
459 | default: | ||
460 | state = S2MPS14_ENABLE_SUSPEND; | ||
461 | break; | ||
462 | }; | ||
463 | break; | ||
464 | case S2MPU02: | ||
465 | switch (rdev_id) { | ||
466 | case S2MPU02_LDO13: | ||
467 | case S2MPU02_LDO14: | ||
468 | case S2MPU02_LDO15: | ||
469 | case S2MPU02_LDO17: | ||
470 | case S2MPU02_BUCK7: | ||
471 | state = S2MPU02_DISABLE_SUSPEND; | ||
472 | break; | ||
473 | default: | ||
474 | state = S2MPU02_ENABLE_SUSPEND; | ||
475 | break; | ||
476 | }; | ||
477 | break; | ||
478 | default: | ||
479 | return -EINVAL; | ||
480 | }; | ||
438 | 481 | ||
439 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); | 482 | ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); |
440 | if (ret < 0) | 483 | if (ret < 0) |
@@ -452,7 +495,7 @@ static int s2mps14_regulator_set_suspend_disable(struct regulator_dev *rdev) | |||
452 | return 0; | 495 | return 0; |
453 | 496 | ||
454 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, | 497 | return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, |
455 | rdev->desc->enable_mask, S2MPS14_ENABLE_SUSPEND); | 498 | rdev->desc->enable_mask, state); |
456 | } | 499 | } |
457 | 500 | ||
458 | static struct regulator_ops s2mps14_reg_ops = { | 501 | static struct regulator_ops s2mps14_reg_ops = { |
@@ -605,8 +648,7 @@ static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev, | |||
605 | } | 648 | } |
606 | 649 | ||
607 | static int s2mps11_pmic_dt_parse(struct platform_device *pdev, | 650 | static int s2mps11_pmic_dt_parse(struct platform_device *pdev, |
608 | struct of_regulator_match *rdata, struct s2mps11_info *s2mps11, | 651 | struct of_regulator_match *rdata, struct s2mps11_info *s2mps11) |
609 | enum sec_device_type dev_type) | ||
610 | { | 652 | { |
611 | struct device_node *reg_np; | 653 | struct device_node *reg_np; |
612 | 654 | ||
@@ -617,7 +659,7 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, | |||
617 | } | 659 | } |
618 | 660 | ||
619 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); | 661 | of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); |
620 | if (dev_type == S2MPS14X) | 662 | if (s2mps11->dev_type == S2MPS14X) |
621 | s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); | 663 | s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); |
622 | 664 | ||
623 | of_node_put(reg_np); | 665 | of_node_put(reg_np); |
@@ -625,6 +667,238 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, | |||
625 | return 0; | 667 | return 0; |
626 | } | 668 | } |
627 | 669 | ||
670 | static int s2mpu02_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) | ||
671 | { | ||
672 | unsigned int ramp_val, ramp_shift, ramp_reg; | ||
673 | |||
674 | switch (rdev_get_id(rdev)) { | ||
675 | case S2MPU02_BUCK1: | ||
676 | ramp_shift = S2MPU02_BUCK1_RAMP_SHIFT; | ||
677 | break; | ||
678 | case S2MPU02_BUCK2: | ||
679 | ramp_shift = S2MPU02_BUCK2_RAMP_SHIFT; | ||
680 | break; | ||
681 | case S2MPU02_BUCK3: | ||
682 | ramp_shift = S2MPU02_BUCK3_RAMP_SHIFT; | ||
683 | break; | ||
684 | case S2MPU02_BUCK4: | ||
685 | ramp_shift = S2MPU02_BUCK4_RAMP_SHIFT; | ||
686 | break; | ||
687 | default: | ||
688 | return 0; | ||
689 | } | ||
690 | ramp_reg = S2MPU02_REG_RAMP1; | ||
691 | ramp_val = get_ramp_delay(ramp_delay); | ||
692 | |||
693 | return regmap_update_bits(rdev->regmap, ramp_reg, | ||
694 | S2MPU02_BUCK1234_RAMP_MASK << ramp_shift, | ||
695 | ramp_val << ramp_shift); | ||
696 | } | ||
697 | |||
698 | static struct regulator_ops s2mpu02_ldo_ops = { | ||
699 | .list_voltage = regulator_list_voltage_linear, | ||
700 | .map_voltage = regulator_map_voltage_linear, | ||
701 | .is_enabled = regulator_is_enabled_regmap, | ||
702 | .enable = s2mps14_regulator_enable, | ||
703 | .disable = regulator_disable_regmap, | ||
704 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
705 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
706 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
707 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | ||
708 | }; | ||
709 | |||
710 | static struct regulator_ops s2mpu02_buck_ops = { | ||
711 | .list_voltage = regulator_list_voltage_linear, | ||
712 | .map_voltage = regulator_map_voltage_linear, | ||
713 | .is_enabled = regulator_is_enabled_regmap, | ||
714 | .enable = s2mps14_regulator_enable, | ||
715 | .disable = regulator_disable_regmap, | ||
716 | .get_voltage_sel = regulator_get_voltage_sel_regmap, | ||
717 | .set_voltage_sel = regulator_set_voltage_sel_regmap, | ||
718 | .set_voltage_time_sel = regulator_set_voltage_time_sel, | ||
719 | .set_suspend_disable = s2mps14_regulator_set_suspend_disable, | ||
720 | .set_ramp_delay = s2mpu02_set_ramp_delay, | ||
721 | }; | ||
722 | |||
723 | #define regulator_desc_s2mpu02_ldo1(num) { \ | ||
724 | .name = "LDO"#num, \ | ||
725 | .id = S2MPU02_LDO##num, \ | ||
726 | .ops = &s2mpu02_ldo_ops, \ | ||
727 | .type = REGULATOR_VOLTAGE, \ | ||
728 | .owner = THIS_MODULE, \ | ||
729 | .min_uV = S2MPU02_LDO_MIN_900MV, \ | ||
730 | .uV_step = S2MPU02_LDO_STEP_12_5MV, \ | ||
731 | .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \ | ||
732 | .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ | ||
733 | .vsel_reg = S2MPU02_REG_L1CTRL, \ | ||
734 | .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ | ||
735 | .enable_reg = S2MPU02_REG_L1CTRL, \ | ||
736 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
737 | } | ||
738 | #define regulator_desc_s2mpu02_ldo2(num) { \ | ||
739 | .name = "LDO"#num, \ | ||
740 | .id = S2MPU02_LDO##num, \ | ||
741 | .ops = &s2mpu02_ldo_ops, \ | ||
742 | .type = REGULATOR_VOLTAGE, \ | ||
743 | .owner = THIS_MODULE, \ | ||
744 | .min_uV = S2MPU02_LDO_MIN_1050MV, \ | ||
745 | .uV_step = S2MPU02_LDO_STEP_25MV, \ | ||
746 | .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \ | ||
747 | .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ | ||
748 | .vsel_reg = S2MPU02_REG_L2CTRL1, \ | ||
749 | .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ | ||
750 | .enable_reg = S2MPU02_REG_L2CTRL1, \ | ||
751 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
752 | } | ||
753 | #define regulator_desc_s2mpu02_ldo3(num) { \ | ||
754 | .name = "LDO"#num, \ | ||
755 | .id = S2MPU02_LDO##num, \ | ||
756 | .ops = &s2mpu02_ldo_ops, \ | ||
757 | .type = REGULATOR_VOLTAGE, \ | ||
758 | .owner = THIS_MODULE, \ | ||
759 | .min_uV = S2MPU02_LDO_MIN_900MV, \ | ||
760 | .uV_step = S2MPU02_LDO_STEP_12_5MV, \ | ||
761 | .linear_min_sel = S2MPU02_LDO_GROUP1_START_SEL, \ | ||
762 | .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ | ||
763 | .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ | ||
764 | .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ | ||
765 | .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ | ||
766 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
767 | } | ||
768 | #define regulator_desc_s2mpu02_ldo4(num) { \ | ||
769 | .name = "LDO"#num, \ | ||
770 | .id = S2MPU02_LDO##num, \ | ||
771 | .ops = &s2mpu02_ldo_ops, \ | ||
772 | .type = REGULATOR_VOLTAGE, \ | ||
773 | .owner = THIS_MODULE, \ | ||
774 | .min_uV = S2MPU02_LDO_MIN_1050MV, \ | ||
775 | .uV_step = S2MPU02_LDO_STEP_25MV, \ | ||
776 | .linear_min_sel = S2MPU02_LDO_GROUP2_START_SEL, \ | ||
777 | .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ | ||
778 | .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ | ||
779 | .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ | ||
780 | .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ | ||
781 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
782 | } | ||
783 | #define regulator_desc_s2mpu02_ldo5(num) { \ | ||
784 | .name = "LDO"#num, \ | ||
785 | .id = S2MPU02_LDO##num, \ | ||
786 | .ops = &s2mpu02_ldo_ops, \ | ||
787 | .type = REGULATOR_VOLTAGE, \ | ||
788 | .owner = THIS_MODULE, \ | ||
789 | .min_uV = S2MPU02_LDO_MIN_1600MV, \ | ||
790 | .uV_step = S2MPU02_LDO_STEP_50MV, \ | ||
791 | .linear_min_sel = S2MPU02_LDO_GROUP3_START_SEL, \ | ||
792 | .n_voltages = S2MPU02_LDO_N_VOLTAGES, \ | ||
793 | .vsel_reg = S2MPU02_REG_L3CTRL + num - 3, \ | ||
794 | .vsel_mask = S2MPU02_LDO_VSEL_MASK, \ | ||
795 | .enable_reg = S2MPU02_REG_L3CTRL + num - 3, \ | ||
796 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
797 | } | ||
798 | |||
799 | #define regulator_desc_s2mpu02_buck1234(num) { \ | ||
800 | .name = "BUCK"#num, \ | ||
801 | .id = S2MPU02_BUCK##num, \ | ||
802 | .ops = &s2mpu02_buck_ops, \ | ||
803 | .type = REGULATOR_VOLTAGE, \ | ||
804 | .owner = THIS_MODULE, \ | ||
805 | .min_uV = S2MPU02_BUCK1234_MIN_600MV, \ | ||
806 | .uV_step = S2MPU02_BUCK1234_STEP_6_25MV, \ | ||
807 | .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ | ||
808 | .linear_min_sel = S2MPU02_BUCK1234_START_SEL, \ | ||
809 | .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ | ||
810 | .vsel_reg = S2MPU02_REG_B1CTRL2 + (num - 1) * 2, \ | ||
811 | .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ | ||
812 | .enable_reg = S2MPU02_REG_B1CTRL1 + (num - 1) * 2, \ | ||
813 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
814 | } | ||
815 | #define regulator_desc_s2mpu02_buck5(num) { \ | ||
816 | .name = "BUCK"#num, \ | ||
817 | .id = S2MPU02_BUCK##num, \ | ||
818 | .ops = &s2mpu02_ldo_ops, \ | ||
819 | .type = REGULATOR_VOLTAGE, \ | ||
820 | .owner = THIS_MODULE, \ | ||
821 | .min_uV = S2MPU02_BUCK5_MIN_1081_25MV, \ | ||
822 | .uV_step = S2MPU02_BUCK5_STEP_6_25MV, \ | ||
823 | .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ | ||
824 | .linear_min_sel = S2MPU02_BUCK5_START_SEL, \ | ||
825 | .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ | ||
826 | .vsel_reg = S2MPU02_REG_B5CTRL2, \ | ||
827 | .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ | ||
828 | .enable_reg = S2MPU02_REG_B5CTRL1, \ | ||
829 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
830 | } | ||
831 | #define regulator_desc_s2mpu02_buck6(num) { \ | ||
832 | .name = "BUCK"#num, \ | ||
833 | .id = S2MPU02_BUCK##num, \ | ||
834 | .ops = &s2mpu02_ldo_ops, \ | ||
835 | .type = REGULATOR_VOLTAGE, \ | ||
836 | .owner = THIS_MODULE, \ | ||
837 | .min_uV = S2MPU02_BUCK6_MIN_1700MV, \ | ||
838 | .uV_step = S2MPU02_BUCK6_STEP_2_50MV, \ | ||
839 | .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ | ||
840 | .linear_min_sel = S2MPU02_BUCK6_START_SEL, \ | ||
841 | .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ | ||
842 | .vsel_reg = S2MPU02_REG_B6CTRL2, \ | ||
843 | .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ | ||
844 | .enable_reg = S2MPU02_REG_B6CTRL1, \ | ||
845 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
846 | } | ||
847 | #define regulator_desc_s2mpu02_buck7(num) { \ | ||
848 | .name = "BUCK"#num, \ | ||
849 | .id = S2MPU02_BUCK##num, \ | ||
850 | .ops = &s2mpu02_ldo_ops, \ | ||
851 | .type = REGULATOR_VOLTAGE, \ | ||
852 | .owner = THIS_MODULE, \ | ||
853 | .min_uV = S2MPU02_BUCK7_MIN_900MV, \ | ||
854 | .uV_step = S2MPU02_BUCK7_STEP_6_25MV, \ | ||
855 | .n_voltages = S2MPU02_BUCK_N_VOLTAGES, \ | ||
856 | .linear_min_sel = S2MPU02_BUCK7_START_SEL, \ | ||
857 | .ramp_delay = S2MPU02_BUCK_RAMP_DELAY, \ | ||
858 | .vsel_reg = S2MPU02_REG_B7CTRL2, \ | ||
859 | .vsel_mask = S2MPU02_BUCK_VSEL_MASK, \ | ||
860 | .enable_reg = S2MPU02_REG_B7CTRL1, \ | ||
861 | .enable_mask = S2MPU02_ENABLE_MASK \ | ||
862 | } | ||
863 | |||
864 | static const struct regulator_desc s2mpu02_regulators[] = { | ||
865 | regulator_desc_s2mpu02_ldo1(1), | ||
866 | regulator_desc_s2mpu02_ldo2(2), | ||
867 | regulator_desc_s2mpu02_ldo4(3), | ||
868 | regulator_desc_s2mpu02_ldo5(4), | ||
869 | regulator_desc_s2mpu02_ldo4(5), | ||
870 | regulator_desc_s2mpu02_ldo3(6), | ||
871 | regulator_desc_s2mpu02_ldo3(7), | ||
872 | regulator_desc_s2mpu02_ldo4(8), | ||
873 | regulator_desc_s2mpu02_ldo5(9), | ||
874 | regulator_desc_s2mpu02_ldo3(10), | ||
875 | regulator_desc_s2mpu02_ldo4(11), | ||
876 | regulator_desc_s2mpu02_ldo5(12), | ||
877 | regulator_desc_s2mpu02_ldo5(13), | ||
878 | regulator_desc_s2mpu02_ldo5(14), | ||
879 | regulator_desc_s2mpu02_ldo5(15), | ||
880 | regulator_desc_s2mpu02_ldo5(16), | ||
881 | regulator_desc_s2mpu02_ldo4(17), | ||
882 | regulator_desc_s2mpu02_ldo5(18), | ||
883 | regulator_desc_s2mpu02_ldo3(19), | ||
884 | regulator_desc_s2mpu02_ldo4(20), | ||
885 | regulator_desc_s2mpu02_ldo5(21), | ||
886 | regulator_desc_s2mpu02_ldo5(22), | ||
887 | regulator_desc_s2mpu02_ldo5(23), | ||
888 | regulator_desc_s2mpu02_ldo4(24), | ||
889 | regulator_desc_s2mpu02_ldo5(25), | ||
890 | regulator_desc_s2mpu02_ldo4(26), | ||
891 | regulator_desc_s2mpu02_ldo5(27), | ||
892 | regulator_desc_s2mpu02_ldo5(28), | ||
893 | regulator_desc_s2mpu02_buck1234(1), | ||
894 | regulator_desc_s2mpu02_buck1234(2), | ||
895 | regulator_desc_s2mpu02_buck1234(3), | ||
896 | regulator_desc_s2mpu02_buck1234(4), | ||
897 | regulator_desc_s2mpu02_buck5(5), | ||
898 | regulator_desc_s2mpu02_buck6(6), | ||
899 | regulator_desc_s2mpu02_buck7(7), | ||
900 | }; | ||
901 | |||
628 | static int s2mps11_pmic_probe(struct platform_device *pdev) | 902 | static int s2mps11_pmic_probe(struct platform_device *pdev) |
629 | { | 903 | { |
630 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); | 904 | struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent); |
@@ -634,15 +908,14 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
634 | struct s2mps11_info *s2mps11; | 908 | struct s2mps11_info *s2mps11; |
635 | int i, ret = 0; | 909 | int i, ret = 0; |
636 | const struct regulator_desc *regulators; | 910 | const struct regulator_desc *regulators; |
637 | enum sec_device_type dev_type; | ||
638 | 911 | ||
639 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), | 912 | s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), |
640 | GFP_KERNEL); | 913 | GFP_KERNEL); |
641 | if (!s2mps11) | 914 | if (!s2mps11) |
642 | return -ENOMEM; | 915 | return -ENOMEM; |
643 | 916 | ||
644 | dev_type = platform_get_device_id(pdev)->driver_data; | 917 | s2mps11->dev_type = platform_get_device_id(pdev)->driver_data; |
645 | switch (dev_type) { | 918 | switch (s2mps11->dev_type) { |
646 | case S2MPS11X: | 919 | case S2MPS11X: |
647 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); | 920 | s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); |
648 | regulators = s2mps11_regulators; | 921 | regulators = s2mps11_regulators; |
@@ -651,8 +924,13 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
651 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); | 924 | s2mps11->rdev_num = ARRAY_SIZE(s2mps14_regulators); |
652 | regulators = s2mps14_regulators; | 925 | regulators = s2mps14_regulators; |
653 | break; | 926 | break; |
927 | case S2MPU02: | ||
928 | s2mps11->rdev_num = ARRAY_SIZE(s2mpu02_regulators); | ||
929 | regulators = s2mpu02_regulators; | ||
930 | break; | ||
654 | default: | 931 | default: |
655 | dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); | 932 | dev_err(&pdev->dev, "Invalid device type: %u\n", |
933 | s2mps11->dev_type); | ||
656 | return -EINVAL; | 934 | return -EINVAL; |
657 | }; | 935 | }; |
658 | 936 | ||
@@ -686,7 +964,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) | |||
686 | for (i = 0; i < s2mps11->rdev_num; i++) | 964 | for (i = 0; i < s2mps11->rdev_num; i++) |
687 | rdata[i].name = regulators[i].name; | 965 | rdata[i].name = regulators[i].name; |
688 | 966 | ||
689 | ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type); | 967 | ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11); |
690 | if (ret) | 968 | if (ret) |
691 | goto out; | 969 | goto out; |
692 | 970 | ||
@@ -739,6 +1017,7 @@ out: | |||
739 | static const struct platform_device_id s2mps11_pmic_id[] = { | 1017 | static const struct platform_device_id s2mps11_pmic_id[] = { |
740 | { "s2mps11-pmic", S2MPS11X}, | 1018 | { "s2mps11-pmic", S2MPS11X}, |
741 | { "s2mps14-pmic", S2MPS14X}, | 1019 | { "s2mps14-pmic", S2MPS14X}, |
1020 | { "s2mpu02-pmic", S2MPU02}, | ||
742 | { }, | 1021 | { }, |
743 | }; | 1022 | }; |
744 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); | 1023 | MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id); |
diff --git a/drivers/rtc/rtc-da9063.c b/drivers/rtc/rtc-da9063.c index 595393098b09..731ed1a97f59 100644 --- a/drivers/rtc/rtc-da9063.c +++ b/drivers/rtc/rtc-da9063.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #define YEARS_FROM_DA9063(year) ((year) + 100) | 29 | #define YEARS_FROM_DA9063(year) ((year) + 100) |
30 | #define MONTHS_FROM_DA9063(month) ((month) - 1) | 30 | #define MONTHS_FROM_DA9063(month) ((month) - 1) |
31 | 31 | ||
32 | #define RTC_ALARM_DATA_LEN (DA9063_AD_REG_ALARM_Y - DA9063_AD_REG_ALARM_MI + 1) | ||
33 | |||
32 | #define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) | 34 | #define RTC_DATA_LEN (DA9063_REG_COUNT_Y - DA9063_REG_COUNT_S + 1) |
33 | #define RTC_SEC 0 | 35 | #define RTC_SEC 0 |
34 | #define RTC_MIN 1 | 36 | #define RTC_MIN 1 |
@@ -42,6 +44,10 @@ struct da9063_rtc { | |||
42 | struct da9063 *hw; | 44 | struct da9063 *hw; |
43 | struct rtc_time alarm_time; | 45 | struct rtc_time alarm_time; |
44 | bool rtc_sync; | 46 | bool rtc_sync; |
47 | int alarm_year; | ||
48 | int alarm_start; | ||
49 | int alarm_len; | ||
50 | int data_start; | ||
45 | }; | 51 | }; |
46 | 52 | ||
47 | static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) | 53 | static void da9063_data_to_tm(u8 *data, struct rtc_time *tm) |
@@ -83,7 +89,7 @@ static int da9063_rtc_stop_alarm(struct device *dev) | |||
83 | { | 89 | { |
84 | struct da9063_rtc *rtc = dev_get_drvdata(dev); | 90 | struct da9063_rtc *rtc = dev_get_drvdata(dev); |
85 | 91 | ||
86 | return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y, | 92 | return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, |
87 | DA9063_ALARM_ON, 0); | 93 | DA9063_ALARM_ON, 0); |
88 | } | 94 | } |
89 | 95 | ||
@@ -91,7 +97,7 @@ static int da9063_rtc_start_alarm(struct device *dev) | |||
91 | { | 97 | { |
92 | struct da9063_rtc *rtc = dev_get_drvdata(dev); | 98 | struct da9063_rtc *rtc = dev_get_drvdata(dev); |
93 | 99 | ||
94 | return regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y, | 100 | return regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, |
95 | DA9063_ALARM_ON, DA9063_ALARM_ON); | 101 | DA9063_ALARM_ON, DA9063_ALARM_ON); |
96 | } | 102 | } |
97 | 103 | ||
@@ -151,8 +157,9 @@ static int da9063_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
151 | int ret; | 157 | int ret; |
152 | unsigned int val; | 158 | unsigned int val; |
153 | 159 | ||
154 | ret = regmap_bulk_read(rtc->hw->regmap, DA9063_REG_ALARM_S, | 160 | data[RTC_SEC] = 0; |
155 | &data[RTC_SEC], RTC_DATA_LEN); | 161 | ret = regmap_bulk_read(rtc->hw->regmap, rtc->alarm_start, |
162 | &data[rtc->data_start], rtc->alarm_len); | ||
156 | if (ret < 0) | 163 | if (ret < 0) |
157 | return ret; | 164 | return ret; |
158 | 165 | ||
@@ -186,14 +193,14 @@ static int da9063_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
186 | return ret; | 193 | return ret; |
187 | } | 194 | } |
188 | 195 | ||
189 | ret = regmap_bulk_write(rtc->hw->regmap, DA9063_REG_ALARM_S, | 196 | ret = regmap_bulk_write(rtc->hw->regmap, rtc->alarm_start, |
190 | data, RTC_DATA_LEN); | 197 | &data[rtc->data_start], rtc->alarm_len); |
191 | if (ret < 0) { | 198 | if (ret < 0) { |
192 | dev_err(dev, "Failed to write alarm: %d\n", ret); | 199 | dev_err(dev, "Failed to write alarm: %d\n", ret); |
193 | return ret; | 200 | return ret; |
194 | } | 201 | } |
195 | 202 | ||
196 | rtc->alarm_time = alrm->time; | 203 | da9063_data_to_tm(data, &rtc->alarm_time); |
197 | 204 | ||
198 | if (alrm->enabled) { | 205 | if (alrm->enabled) { |
199 | ret = da9063_rtc_start_alarm(dev); | 206 | ret = da9063_rtc_start_alarm(dev); |
@@ -218,7 +225,7 @@ static irqreturn_t da9063_alarm_event(int irq, void *data) | |||
218 | { | 225 | { |
219 | struct da9063_rtc *rtc = data; | 226 | struct da9063_rtc *rtc = data; |
220 | 227 | ||
221 | regmap_update_bits(rtc->hw->regmap, DA9063_REG_ALARM_Y, | 228 | regmap_update_bits(rtc->hw->regmap, rtc->alarm_year, |
222 | DA9063_ALARM_ON, 0); | 229 | DA9063_ALARM_ON, 0); |
223 | 230 | ||
224 | rtc->rtc_sync = true; | 231 | rtc->rtc_sync = true; |
@@ -257,7 +264,23 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
257 | goto err; | 264 | goto err; |
258 | } | 265 | } |
259 | 266 | ||
260 | ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S, | 267 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); |
268 | if (!rtc) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | if (da9063->variant_code == PMIC_DA9063_AD) { | ||
272 | rtc->alarm_year = DA9063_AD_REG_ALARM_Y; | ||
273 | rtc->alarm_start = DA9063_AD_REG_ALARM_MI; | ||
274 | rtc->alarm_len = RTC_ALARM_DATA_LEN; | ||
275 | rtc->data_start = RTC_MIN; | ||
276 | } else { | ||
277 | rtc->alarm_year = DA9063_BB_REG_ALARM_Y; | ||
278 | rtc->alarm_start = DA9063_BB_REG_ALARM_S; | ||
279 | rtc->alarm_len = RTC_DATA_LEN; | ||
280 | rtc->data_start = RTC_SEC; | ||
281 | } | ||
282 | |||
283 | ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, | ||
261 | DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM, | 284 | DA9063_ALARM_STATUS_TICK | DA9063_ALARM_STATUS_ALARM, |
262 | 0); | 285 | 0); |
263 | if (ret < 0) { | 286 | if (ret < 0) { |
@@ -265,7 +288,7 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
265 | goto err; | 288 | goto err; |
266 | } | 289 | } |
267 | 290 | ||
268 | ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_S, | 291 | ret = regmap_update_bits(da9063->regmap, rtc->alarm_start, |
269 | DA9063_ALARM_STATUS_ALARM, | 292 | DA9063_ALARM_STATUS_ALARM, |
270 | DA9063_ALARM_STATUS_ALARM); | 293 | DA9063_ALARM_STATUS_ALARM); |
271 | if (ret < 0) { | 294 | if (ret < 0) { |
@@ -273,25 +296,22 @@ static int da9063_rtc_probe(struct platform_device *pdev) | |||
273 | goto err; | 296 | goto err; |
274 | } | 297 | } |
275 | 298 | ||
276 | ret = regmap_update_bits(da9063->regmap, DA9063_REG_ALARM_Y, | 299 | ret = regmap_update_bits(da9063->regmap, rtc->alarm_year, |
277 | DA9063_TICK_ON, 0); | 300 | DA9063_TICK_ON, 0); |
278 | if (ret < 0) { | 301 | if (ret < 0) { |
279 | dev_err(&pdev->dev, "Failed to disable TICKs\n"); | 302 | dev_err(&pdev->dev, "Failed to disable TICKs\n"); |
280 | goto err; | 303 | goto err; |
281 | } | 304 | } |
282 | 305 | ||
283 | ret = regmap_bulk_read(da9063->regmap, DA9063_REG_ALARM_S, | 306 | data[RTC_SEC] = 0; |
284 | data, RTC_DATA_LEN); | 307 | ret = regmap_bulk_read(da9063->regmap, rtc->alarm_start, |
308 | &data[rtc->data_start], rtc->alarm_len); | ||
285 | if (ret < 0) { | 309 | if (ret < 0) { |
286 | dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n", | 310 | dev_err(&pdev->dev, "Failed to read initial alarm data: %d\n", |
287 | ret); | 311 | ret); |
288 | goto err; | 312 | goto err; |
289 | } | 313 | } |
290 | 314 | ||
291 | rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); | ||
292 | if (!rtc) | ||
293 | return -ENOMEM; | ||
294 | |||
295 | platform_set_drvdata(pdev, rtc); | 315 | platform_set_drvdata(pdev, rtc); |
296 | 316 | ||
297 | irq_alarm = platform_get_irq_byname(pdev, "ALARM"); | 317 | irq_alarm = platform_get_irq_byname(pdev, "ALARM"); |
diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 9efe118a28ba..d20a7f0786eb 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c | |||
@@ -492,16 +492,11 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info) | |||
492 | return ret; | 492 | return ret; |
493 | } | 493 | } |
494 | 494 | ||
495 | static struct regmap_config max77686_rtc_regmap_config = { | ||
496 | .reg_bits = 8, | ||
497 | .val_bits = 8, | ||
498 | }; | ||
499 | |||
500 | static int max77686_rtc_probe(struct platform_device *pdev) | 495 | static int max77686_rtc_probe(struct platform_device *pdev) |
501 | { | 496 | { |
502 | struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent); | 497 | struct max77686_dev *max77686 = dev_get_drvdata(pdev->dev.parent); |
503 | struct max77686_rtc_info *info; | 498 | struct max77686_rtc_info *info; |
504 | int ret, virq; | 499 | int ret; |
505 | 500 | ||
506 | dev_info(&pdev->dev, "%s\n", __func__); | 501 | dev_info(&pdev->dev, "%s\n", __func__); |
507 | 502 | ||
@@ -514,14 +509,7 @@ static int max77686_rtc_probe(struct platform_device *pdev) | |||
514 | info->dev = &pdev->dev; | 509 | info->dev = &pdev->dev; |
515 | info->max77686 = max77686; | 510 | info->max77686 = max77686; |
516 | info->rtc = max77686->rtc; | 511 | info->rtc = max77686->rtc; |
517 | info->max77686->rtc_regmap = devm_regmap_init_i2c(info->max77686->rtc, | 512 | |
518 | &max77686_rtc_regmap_config); | ||
519 | if (IS_ERR(info->max77686->rtc_regmap)) { | ||
520 | ret = PTR_ERR(info->max77686->rtc_regmap); | ||
521 | dev_err(info->max77686->dev, "Failed to allocate register map: %d\n", | ||
522 | ret); | ||
523 | return ret; | ||
524 | } | ||
525 | platform_set_drvdata(pdev, info); | 513 | platform_set_drvdata(pdev, info); |
526 | 514 | ||
527 | ret = max77686_rtc_init_reg(info); | 515 | ret = max77686_rtc_init_reg(info); |
@@ -550,15 +538,16 @@ static int max77686_rtc_probe(struct platform_device *pdev) | |||
550 | ret = -EINVAL; | 538 | ret = -EINVAL; |
551 | goto err_rtc; | 539 | goto err_rtc; |
552 | } | 540 | } |
553 | virq = irq_create_mapping(max77686->irq_domain, MAX77686_RTCIRQ_RTCA1); | 541 | |
554 | if (!virq) { | 542 | info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, |
543 | MAX77686_RTCIRQ_RTCA1); | ||
544 | if (!info->virq) { | ||
555 | ret = -ENXIO; | 545 | ret = -ENXIO; |
556 | goto err_rtc; | 546 | goto err_rtc; |
557 | } | 547 | } |
558 | info->virq = virq; | ||
559 | 548 | ||
560 | ret = devm_request_threaded_irq(&pdev->dev, virq, NULL, | 549 | ret = devm_request_threaded_irq(&pdev->dev, info->virq, NULL, |
561 | max77686_rtc_alarm_irq, 0, "rtc-alarm0", info); | 550 | max77686_rtc_alarm_irq, 0, "rtc-alarm1", info); |
562 | if (ret < 0) | 551 | if (ret < 0) |
563 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", | 552 | dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", |
564 | info->virq, ret); | 553 | info->virq, ret); |