diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-06 15:08:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-06 15:08:39 -0400 |
commit | 1fe9eb184721132c7254d76d9ef31c96edad8870 (patch) | |
tree | c055ffb7f201bc2370714ebe186a922d0eb39d0d /drivers/mfd | |
parent | 0bb464624140bfdd8389d4c5464ba134b2856049 (diff) | |
parent | 89abd4df28c6f85645e32f37ffab6426f800e4a1 (diff) |
Merge tag 'mfd-for-linus-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into next
Pull MFD updates from Lee Jones:
"Changes to existing drivers:
- increase DT coverage: arizona, mc13xxx, stmpe-i2c, syscon,
sun6i-prcm
- regmap use of and/or clean-up: tps65090, twl6040
- basic renaming: max14577
- use new cpufreq helpers: db8500-prcmu
- increase regulator support: stmpe, arizona, wm5102
- reduce legacy GPIO overhead: stmpe
- provide necessary remove path: bcm590xx
- expand sysfs presence: kempld
- move driver specific code out to drivers: rtc-s5m, arizona
- clk handling: twl6040
- use managed (devm_*) resources: ipaq-micro
- clean-up/remove unused/duplicated code: tps65218, sec, pm8921,
abx500-core, db8500-prcmu, menelaus
- build/boot/sematic bug fixes: rtsx_usb, stmpe, bcm590xx, abx500,
mc13xxx, rdc321x-southbridge, mfd-core, sec, max14577, syscon,
cros_ec_spi
- constify stuff: sm501, tps65910, tps6507x, tps6586x, max77686,
max8997, kempld, max77693, max8907, rtsx_usb, db8500-prcmu,
max8998, wm8400, sec, lp3943, max14577, as3711, omap-usb-host,
ipaq-micro
Support for new devices:
- add support for max77836 into max14577
- add support for tps658640 into tps6586x
- add support for cros-ec-i2c-tunnel into cros_ec
- add new driver for rtsx_usb_sdmmc and rtsx_usb_ms
- add new driver for axp20x
- add new driver for sun6i-prcm
- add new driver for ipaq-micro"
* tag 'mfd-for-linus-3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (77 commits)
mfd: wm5102: Correct default for LDO Control 2 register
mfd: menelaus: Use module_i2c_driver
mfd: tps65218: Terminate of match table
mfd: db8500-prcmu: Remove check for CONFIG_DBX500_PRCMU_DEBUG
mfd: ti-keystone-devctrl: Add bindings for device state control
mfd: palmas: Format the header file
mfd: abx500-core: Remove unused function abx500_dump_all_banks()
mfd: arizona: Correct addresses of always-on trigger registers
mfd: max14577: Cast to architecture agnostic data type
i2c: ChromeOS EC tunnel driver
mfd: cros_ec: Sync to the latest cros_ec_commands.h from EC sources
mfd: cros_ec: spi: Increase cros_ec_spi deadline from 5ms to 100ms
mfd: cros_ec: spi: Make the cros_ec_spi timeout more reliable
mfd: cros_ec: spi: Add mutex to cros_ec_spi
mfd: cros_ec: spi: Calculate delay between transfers correctly
mfd: arizona: Correct error message for addition of main IRQ chip
mfd: wm8997: Add registers for high power mode
mfd: arizona: Add MICVDD to mapped regulators
mfd: ipaq-micro: Make mfd_cell array const
mfd: ipaq-micro: Use devm_ioremap_resource()
...
Diffstat (limited to 'drivers/mfd')
45 files changed, 1284 insertions, 367 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 6deb8a11c12f..ee8204cc31e9 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -67,6 +67,18 @@ config MFD_BCM590XX | |||
67 | help | 67 | help |
68 | Support for the BCM590xx PMUs from Broadcom | 68 | Support for the BCM590xx PMUs from Broadcom |
69 | 69 | ||
70 | config MFD_AXP20X | ||
71 | bool "X-Powers AXP20X" | ||
72 | select MFD_CORE | ||
73 | select REGMAP_I2C | ||
74 | select REGMAP_IRQ | ||
75 | depends on I2C=y | ||
76 | help | ||
77 | If you say Y here you get support for the X-Powers AXP202 and AXP209. | ||
78 | This driver include only the core APIs. You have to select individual | ||
79 | components like regulators or the PEK (Power Enable Key) under the | ||
80 | corresponding menus. | ||
81 | |||
70 | config MFD_CROS_EC | 82 | config MFD_CROS_EC |
71 | tristate "ChromeOS Embedded Controller" | 83 | tristate "ChromeOS Embedded Controller" |
72 | select MFD_CORE | 84 | select MFD_CORE |
@@ -250,6 +262,16 @@ config MFD_INTEL_MSIC | |||
250 | Passage) chip. This chip embeds audio, battery, GPIO, etc. | 262 | Passage) chip. This chip embeds audio, battery, GPIO, etc. |
251 | devices used in Intel Medfield platforms. | 263 | devices used in Intel Medfield platforms. |
252 | 264 | ||
265 | config MFD_IPAQ_MICRO | ||
266 | bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" | ||
267 | depends on SA1100_H3100 || SA1100_H3600 | ||
268 | select MFD_CORE | ||
269 | help | ||
270 | Select this to get support for the Microcontroller found in | ||
271 | the Compaq iPAQ handheld computers. This is an Atmel | ||
272 | AT90LS8535 microcontroller flashed with a special iPAQ | ||
273 | firmware using the custom protocol implemented in this driver. | ||
274 | |||
253 | config MFD_JANZ_CMODIO | 275 | config MFD_JANZ_CMODIO |
254 | tristate "Janz CMOD-IO PCI MODULbus Carrier Board" | 276 | tristate "Janz CMOD-IO PCI MODULbus Carrier Board" |
255 | select MFD_CORE | 277 | select MFD_CORE |
@@ -675,6 +697,7 @@ config MFD_DB8500_PRCMU | |||
675 | config MFD_STMPE | 697 | config MFD_STMPE |
676 | bool "STMicroelectronics STMPE" | 698 | bool "STMicroelectronics STMPE" |
677 | depends on (I2C=y || SPI_MASTER=y) | 699 | depends on (I2C=y || SPI_MASTER=y) |
700 | depends on OF | ||
678 | select MFD_CORE | 701 | select MFD_CORE |
679 | help | 702 | help |
680 | Support for the STMPE family of I/O Expanders from | 703 | Support for the STMPE family of I/O Expanders from |
@@ -719,6 +742,14 @@ config MFD_STA2X11 | |||
719 | select MFD_CORE | 742 | select MFD_CORE |
720 | select REGMAP_MMIO | 743 | select REGMAP_MMIO |
721 | 744 | ||
745 | config MFD_SUN6I_PRCM | ||
746 | bool "Allwinner A31 PRCM controller" | ||
747 | depends on ARCH_SUNXI | ||
748 | select MFD_CORE | ||
749 | help | ||
750 | Support for the PRCM (Power/Reset/Clock Management) unit available | ||
751 | in A31 SoC. | ||
752 | |||
722 | config MFD_SYSCON | 753 | config MFD_SYSCON |
723 | bool "System Controller Register R/W Based on Regmap" | 754 | bool "System Controller Register R/W Based on Regmap" |
724 | select REGMAP_MMIO | 755 | select REGMAP_MMIO |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index cec3487b539e..8afedba535c7 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -29,6 +29,7 @@ obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o | |||
29 | obj-$(CONFIG_MFD_STMPE) += stmpe.o | 29 | obj-$(CONFIG_MFD_STMPE) += stmpe.o |
30 | obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o | 30 | obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o |
31 | obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o | 31 | obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o |
32 | obj-$(CONFIG_MFD_SUN6I_PRCM) += sun6i-prcm.o | ||
32 | obj-$(CONFIG_MFD_TC3589X) += tc3589x.o | 33 | obj-$(CONFIG_MFD_TC3589X) += tc3589x.o |
33 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o | 34 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o |
34 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o | 35 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o |
@@ -102,6 +103,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-irq.o | |||
102 | obj-$(CONFIG_PMIC_DA9052) += da9052-core.o | 103 | obj-$(CONFIG_PMIC_DA9052) += da9052-core.o |
103 | obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o | 104 | obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o |
104 | obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o | 105 | obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o |
106 | obj-$(CONFIG_MFD_AXP20X) += axp20x.o | ||
105 | 107 | ||
106 | obj-$(CONFIG_MFD_LP3943) += lp3943.o | 108 | obj-$(CONFIG_MFD_LP3943) += lp3943.o |
107 | obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o | 109 | obj-$(CONFIG_MFD_LP8788) += lp8788.o lp8788-irq.o |
@@ -166,3 +168,4 @@ obj-$(CONFIG_MFD_RETU) += retu-mfd.o | |||
166 | obj-$(CONFIG_MFD_AS3711) += as3711.o | 168 | obj-$(CONFIG_MFD_AS3711) += as3711.o |
167 | obj-$(CONFIG_MFD_AS3722) += as3722.o | 169 | obj-$(CONFIG_MFD_AS3722) += as3722.o |
168 | obj-$(CONFIG_MFD_STW481X) += stw481x.o | 170 | obj-$(CONFIG_MFD_STW481X) += stw481x.o |
171 | obj-$(CONFIG_MFD_IPAQ_MICRO) += ipaq-micro.o | ||
diff --git a/drivers/mfd/abx500-core.c b/drivers/mfd/abx500-core.c index f3a15aa54d7b..fe418995108c 100644 --- a/drivers/mfd/abx500-core.c +++ b/drivers/mfd/abx500-core.c | |||
@@ -151,22 +151,6 @@ int abx500_startup_irq_enabled(struct device *dev, unsigned int irq) | |||
151 | } | 151 | } |
152 | EXPORT_SYMBOL(abx500_startup_irq_enabled); | 152 | EXPORT_SYMBOL(abx500_startup_irq_enabled); |
153 | 153 | ||
154 | void abx500_dump_all_banks(void) | ||
155 | { | ||
156 | struct abx500_ops *ops; | ||
157 | struct device dummy_child = {NULL}; | ||
158 | struct abx500_device_entry *dev_entry; | ||
159 | |||
160 | list_for_each_entry(dev_entry, &abx500_list, list) { | ||
161 | dummy_child.parent = dev_entry->dev; | ||
162 | ops = &dev_entry->ops; | ||
163 | |||
164 | if ((ops != NULL) && (ops->dump_all_banks != NULL)) | ||
165 | ops->dump_all_banks(&dummy_child); | ||
166 | } | ||
167 | } | ||
168 | EXPORT_SYMBOL(abx500_dump_all_banks); | ||
169 | |||
170 | MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); | 154 | MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>"); |
171 | MODULE_DESCRIPTION("ABX500 core driver"); | 155 | MODULE_DESCRIPTION("ABX500 core driver"); |
172 | MODULE_LICENSE("GPL"); | 156 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 07e6e27be23c..cfc191abae4a 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -583,6 +583,7 @@ static const char *wm5102_supplies[] = { | |||
583 | "CPVDD", | 583 | "CPVDD", |
584 | "SPKVDDL", | 584 | "SPKVDDL", |
585 | "SPKVDDR", | 585 | "SPKVDDR", |
586 | "MICVDD", | ||
586 | }; | 587 | }; |
587 | 588 | ||
588 | static const struct mfd_cell wm5102_devs[] = { | 589 | static const struct mfd_cell wm5102_devs[] = { |
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c index 88758ab9402b..17102f589100 100644 --- a/drivers/mfd/arizona-irq.c +++ b/drivers/mfd/arizona-irq.c | |||
@@ -285,7 +285,7 @@ int arizona_irq_init(struct arizona *arizona) | |||
285 | IRQF_ONESHOT, -1, irq, | 285 | IRQF_ONESHOT, -1, irq, |
286 | &arizona->irq_chip); | 286 | &arizona->irq_chip); |
287 | if (ret != 0) { | 287 | if (ret != 0) { |
288 | dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); | 288 | dev_err(arizona->dev, "Failed to add main IRQs: %d\n", ret); |
289 | goto err_aod; | 289 | goto err_aod; |
290 | } | 290 | } |
291 | 291 | ||
diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c index ec684fcedb42..d9706ede8d39 100644 --- a/drivers/mfd/as3711.c +++ b/drivers/mfd/as3711.c | |||
@@ -114,7 +114,7 @@ static const struct regmap_config as3711_regmap_config = { | |||
114 | }; | 114 | }; |
115 | 115 | ||
116 | #ifdef CONFIG_OF | 116 | #ifdef CONFIG_OF |
117 | static struct of_device_id as3711_of_match[] = { | 117 | static const struct of_device_id as3711_of_match[] = { |
118 | {.compatible = "ams,as3711",}, | 118 | {.compatible = "ams,as3711",}, |
119 | {} | 119 | {} |
120 | }; | 120 | }; |
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c new file mode 100644 index 000000000000..dee653989e3a --- /dev/null +++ b/drivers/mfd/axp20x.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * axp20x.c - MFD core driver for the X-Powers AXP202 and AXP209 | ||
3 | * | ||
4 | * AXP20x comprises an adaptive USB-Compatible PWM charger, 2 BUCK DC-DC | ||
5 | * converters, 5 LDOs, multiple 12-bit ADCs of voltage, current and temperature | ||
6 | * as well as 4 configurable GPIOs. | ||
7 | * | ||
8 | * Author: Carlo Caione <carlo@caione.org> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/err.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/pm_runtime.h> | ||
21 | #include <linux/regmap.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/regulator/consumer.h> | ||
24 | #include <linux/mfd/axp20x.h> | ||
25 | #include <linux/mfd/core.h> | ||
26 | #include <linux/of_device.h> | ||
27 | #include <linux/of_irq.h> | ||
28 | |||
29 | #define AXP20X_OFF 0x80 | ||
30 | |||
31 | static const struct regmap_range axp20x_writeable_ranges[] = { | ||
32 | regmap_reg_range(AXP20X_DATACACHE(0), AXP20X_IRQ5_STATE), | ||
33 | regmap_reg_range(AXP20X_DCDC_MODE, AXP20X_FG_RES), | ||
34 | }; | ||
35 | |||
36 | static const struct regmap_range axp20x_volatile_ranges[] = { | ||
37 | regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE), | ||
38 | }; | ||
39 | |||
40 | static const struct regmap_access_table axp20x_writeable_table = { | ||
41 | .yes_ranges = axp20x_writeable_ranges, | ||
42 | .n_yes_ranges = ARRAY_SIZE(axp20x_writeable_ranges), | ||
43 | }; | ||
44 | |||
45 | static const struct regmap_access_table axp20x_volatile_table = { | ||
46 | .yes_ranges = axp20x_volatile_ranges, | ||
47 | .n_yes_ranges = ARRAY_SIZE(axp20x_volatile_ranges), | ||
48 | }; | ||
49 | |||
50 | static struct resource axp20x_pek_resources[] = { | ||
51 | { | ||
52 | .name = "PEK_DBR", | ||
53 | .start = AXP20X_IRQ_PEK_RIS_EDGE, | ||
54 | .end = AXP20X_IRQ_PEK_RIS_EDGE, | ||
55 | .flags = IORESOURCE_IRQ, | ||
56 | }, { | ||
57 | .name = "PEK_DBF", | ||
58 | .start = AXP20X_IRQ_PEK_FAL_EDGE, | ||
59 | .end = AXP20X_IRQ_PEK_FAL_EDGE, | ||
60 | .flags = IORESOURCE_IRQ, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | static const struct regmap_config axp20x_regmap_config = { | ||
65 | .reg_bits = 8, | ||
66 | .val_bits = 8, | ||
67 | .wr_table = &axp20x_writeable_table, | ||
68 | .volatile_table = &axp20x_volatile_table, | ||
69 | .max_register = AXP20X_FG_RES, | ||
70 | .cache_type = REGCACHE_RBTREE, | ||
71 | }; | ||
72 | |||
73 | #define AXP20X_IRQ(_irq, _off, _mask) \ | ||
74 | [AXP20X_IRQ_##_irq] = { .reg_offset = (_off), .mask = BIT(_mask) } | ||
75 | |||
76 | static const struct regmap_irq axp20x_regmap_irqs[] = { | ||
77 | AXP20X_IRQ(ACIN_OVER_V, 0, 7), | ||
78 | AXP20X_IRQ(ACIN_PLUGIN, 0, 6), | ||
79 | AXP20X_IRQ(ACIN_REMOVAL, 0, 5), | ||
80 | AXP20X_IRQ(VBUS_OVER_V, 0, 4), | ||
81 | AXP20X_IRQ(VBUS_PLUGIN, 0, 3), | ||
82 | AXP20X_IRQ(VBUS_REMOVAL, 0, 2), | ||
83 | AXP20X_IRQ(VBUS_V_LOW, 0, 1), | ||
84 | AXP20X_IRQ(BATT_PLUGIN, 1, 7), | ||
85 | AXP20X_IRQ(BATT_REMOVAL, 1, 6), | ||
86 | AXP20X_IRQ(BATT_ENT_ACT_MODE, 1, 5), | ||
87 | AXP20X_IRQ(BATT_EXIT_ACT_MODE, 1, 4), | ||
88 | AXP20X_IRQ(CHARG, 1, 3), | ||
89 | AXP20X_IRQ(CHARG_DONE, 1, 2), | ||
90 | AXP20X_IRQ(BATT_TEMP_HIGH, 1, 1), | ||
91 | AXP20X_IRQ(BATT_TEMP_LOW, 1, 0), | ||
92 | AXP20X_IRQ(DIE_TEMP_HIGH, 2, 7), | ||
93 | AXP20X_IRQ(CHARG_I_LOW, 2, 6), | ||
94 | AXP20X_IRQ(DCDC1_V_LONG, 2, 5), | ||
95 | AXP20X_IRQ(DCDC2_V_LONG, 2, 4), | ||
96 | AXP20X_IRQ(DCDC3_V_LONG, 2, 3), | ||
97 | AXP20X_IRQ(PEK_SHORT, 2, 1), | ||
98 | AXP20X_IRQ(PEK_LONG, 2, 0), | ||
99 | AXP20X_IRQ(N_OE_PWR_ON, 3, 7), | ||
100 | AXP20X_IRQ(N_OE_PWR_OFF, 3, 6), | ||
101 | AXP20X_IRQ(VBUS_VALID, 3, 5), | ||
102 | AXP20X_IRQ(VBUS_NOT_VALID, 3, 4), | ||
103 | AXP20X_IRQ(VBUS_SESS_VALID, 3, 3), | ||
104 | AXP20X_IRQ(VBUS_SESS_END, 3, 2), | ||
105 | AXP20X_IRQ(LOW_PWR_LVL1, 3, 1), | ||
106 | AXP20X_IRQ(LOW_PWR_LVL2, 3, 0), | ||
107 | AXP20X_IRQ(TIMER, 4, 7), | ||
108 | AXP20X_IRQ(PEK_RIS_EDGE, 4, 6), | ||
109 | AXP20X_IRQ(PEK_FAL_EDGE, 4, 5), | ||
110 | AXP20X_IRQ(GPIO3_INPUT, 4, 3), | ||
111 | AXP20X_IRQ(GPIO2_INPUT, 4, 2), | ||
112 | AXP20X_IRQ(GPIO1_INPUT, 4, 1), | ||
113 | AXP20X_IRQ(GPIO0_INPUT, 4, 0), | ||
114 | }; | ||
115 | |||
116 | static const struct of_device_id axp20x_of_match[] = { | ||
117 | { .compatible = "x-powers,axp202", .data = (void *) AXP202_ID }, | ||
118 | { .compatible = "x-powers,axp209", .data = (void *) AXP209_ID }, | ||
119 | { }, | ||
120 | }; | ||
121 | MODULE_DEVICE_TABLE(of, axp20x_of_match); | ||
122 | |||
123 | /* | ||
124 | * This is useless for OF-enabled devices, but it is needed by I2C subsystem | ||
125 | */ | ||
126 | static const struct i2c_device_id axp20x_i2c_id[] = { | ||
127 | { }, | ||
128 | }; | ||
129 | MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id); | ||
130 | |||
131 | static const struct regmap_irq_chip axp20x_regmap_irq_chip = { | ||
132 | .name = "axp20x_irq_chip", | ||
133 | .status_base = AXP20X_IRQ1_STATE, | ||
134 | .ack_base = AXP20X_IRQ1_STATE, | ||
135 | .mask_base = AXP20X_IRQ1_EN, | ||
136 | .num_regs = 5, | ||
137 | .irqs = axp20x_regmap_irqs, | ||
138 | .num_irqs = ARRAY_SIZE(axp20x_regmap_irqs), | ||
139 | .mask_invert = true, | ||
140 | .init_ack_masked = true, | ||
141 | }; | ||
142 | |||
143 | static const char * const axp20x_supplies[] = { | ||
144 | "acin", | ||
145 | "vin2", | ||
146 | "vin3", | ||
147 | "ldo24in", | ||
148 | "ldo3in", | ||
149 | "ldo5in", | ||
150 | }; | ||
151 | |||
152 | static struct mfd_cell axp20x_cells[] = { | ||
153 | { | ||
154 | .name = "axp20x-pek", | ||
155 | .num_resources = ARRAY_SIZE(axp20x_pek_resources), | ||
156 | .resources = axp20x_pek_resources, | ||
157 | }, { | ||
158 | .name = "axp20x-regulator", | ||
159 | .parent_supplies = axp20x_supplies, | ||
160 | .num_parent_supplies = ARRAY_SIZE(axp20x_supplies), | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | static struct axp20x_dev *axp20x_pm_power_off; | ||
165 | static void axp20x_power_off(void) | ||
166 | { | ||
167 | regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL, | ||
168 | AXP20X_OFF); | ||
169 | } | ||
170 | |||
171 | static int axp20x_i2c_probe(struct i2c_client *i2c, | ||
172 | const struct i2c_device_id *id) | ||
173 | { | ||
174 | struct axp20x_dev *axp20x; | ||
175 | const struct of_device_id *of_id; | ||
176 | int ret; | ||
177 | |||
178 | axp20x = devm_kzalloc(&i2c->dev, sizeof(*axp20x), GFP_KERNEL); | ||
179 | if (!axp20x) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | of_id = of_match_device(axp20x_of_match, &i2c->dev); | ||
183 | if (!of_id) { | ||
184 | dev_err(&i2c->dev, "Unable to setup AXP20X data\n"); | ||
185 | return -ENODEV; | ||
186 | } | ||
187 | axp20x->variant = (long) of_id->data; | ||
188 | |||
189 | axp20x->i2c_client = i2c; | ||
190 | axp20x->dev = &i2c->dev; | ||
191 | dev_set_drvdata(axp20x->dev, axp20x); | ||
192 | |||
193 | axp20x->regmap = devm_regmap_init_i2c(i2c, &axp20x_regmap_config); | ||
194 | if (IS_ERR(axp20x->regmap)) { | ||
195 | ret = PTR_ERR(axp20x->regmap); | ||
196 | dev_err(&i2c->dev, "regmap init failed: %d\n", ret); | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | ret = regmap_add_irq_chip(axp20x->regmap, i2c->irq, | ||
201 | IRQF_ONESHOT | IRQF_SHARED, -1, | ||
202 | &axp20x_regmap_irq_chip, | ||
203 | &axp20x->regmap_irqc); | ||
204 | if (ret) { | ||
205 | dev_err(&i2c->dev, "failed to add irq chip: %d\n", ret); | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | ret = mfd_add_devices(axp20x->dev, -1, axp20x_cells, | ||
210 | ARRAY_SIZE(axp20x_cells), NULL, 0, NULL); | ||
211 | |||
212 | if (ret) { | ||
213 | dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); | ||
214 | regmap_del_irq_chip(i2c->irq, axp20x->regmap_irqc); | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | if (!pm_power_off) { | ||
219 | axp20x_pm_power_off = axp20x; | ||
220 | pm_power_off = axp20x_power_off; | ||
221 | } | ||
222 | |||
223 | dev_info(&i2c->dev, "AXP20X driver loaded\n"); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int axp20x_i2c_remove(struct i2c_client *i2c) | ||
229 | { | ||
230 | struct axp20x_dev *axp20x = i2c_get_clientdata(i2c); | ||
231 | |||
232 | if (axp20x == axp20x_pm_power_off) { | ||
233 | axp20x_pm_power_off = NULL; | ||
234 | pm_power_off = NULL; | ||
235 | } | ||
236 | |||
237 | mfd_remove_devices(axp20x->dev); | ||
238 | regmap_del_irq_chip(axp20x->i2c_client->irq, axp20x->regmap_irqc); | ||
239 | |||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | static struct i2c_driver axp20x_i2c_driver = { | ||
244 | .driver = { | ||
245 | .name = "axp20x", | ||
246 | .owner = THIS_MODULE, | ||
247 | .of_match_table = of_match_ptr(axp20x_of_match), | ||
248 | }, | ||
249 | .probe = axp20x_i2c_probe, | ||
250 | .remove = axp20x_i2c_remove, | ||
251 | .id_table = axp20x_i2c_id, | ||
252 | }; | ||
253 | |||
254 | module_i2c_driver(axp20x_i2c_driver); | ||
255 | |||
256 | MODULE_DESCRIPTION("PMIC MFD core driver for AXP20X"); | ||
257 | MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); | ||
258 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c index 43cba1a1973c..e334de000e8c 100644 --- a/drivers/mfd/bcm590xx.c +++ b/drivers/mfd/bcm590xx.c | |||
@@ -96,6 +96,12 @@ err: | |||
96 | return ret; | 96 | return ret; |
97 | } | 97 | } |
98 | 98 | ||
99 | static int bcm590xx_i2c_remove(struct i2c_client *i2c) | ||
100 | { | ||
101 | mfd_remove_devices(&i2c->dev); | ||
102 | return 0; | ||
103 | } | ||
104 | |||
99 | static const struct of_device_id bcm590xx_of_match[] = { | 105 | static const struct of_device_id bcm590xx_of_match[] = { |
100 | { .compatible = "brcm,bcm59056" }, | 106 | { .compatible = "brcm,bcm59056" }, |
101 | { } | 107 | { } |
@@ -115,6 +121,7 @@ static struct i2c_driver bcm590xx_i2c_driver = { | |||
115 | .of_match_table = of_match_ptr(bcm590xx_of_match), | 121 | .of_match_table = of_match_ptr(bcm590xx_of_match), |
116 | }, | 122 | }, |
117 | .probe = bcm590xx_i2c_probe, | 123 | .probe = bcm590xx_i2c_probe, |
124 | .remove = bcm590xx_i2c_remove, | ||
118 | .id_table = bcm590xx_i2c_id, | 125 | .id_table = bcm590xx_i2c_id, |
119 | }; | 126 | }; |
120 | module_i2c_driver(bcm590xx_i2c_driver); | 127 | module_i2c_driver(bcm590xx_i2c_driver); |
@@ -122,4 +129,4 @@ module_i2c_driver(bcm590xx_i2c_driver); | |||
122 | MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); | 129 | MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); |
123 | MODULE_DESCRIPTION("BCM590xx multi-function driver"); | 130 | MODULE_DESCRIPTION("BCM590xx multi-function driver"); |
124 | MODULE_LICENSE("GPL v2"); | 131 | MODULE_LICENSE("GPL v2"); |
125 | MODULE_ALIAS("platform:bcm590xx"); | 132 | MODULE_ALIAS("i2c:bcm590xx"); |
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index 783fe2e73e1e..38fe9bf0d169 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c | |||
@@ -30,7 +30,7 @@ int cros_ec_prepare_tx(struct cros_ec_device *ec_dev, | |||
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_HOST_PARAM_SIZE); | 33 | BUG_ON(msg->out_len > 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->cmd; |
@@ -90,6 +90,11 @@ static const struct mfd_cell cros_devs[] = { | |||
90 | .id = 1, | 90 | .id = 1, |
91 | .of_compatible = "google,cros-ec-keyb", | 91 | .of_compatible = "google,cros-ec-keyb", |
92 | }, | 92 | }, |
93 | { | ||
94 | .name = "cros-ec-i2c-tunnel", | ||
95 | .id = 2, | ||
96 | .of_compatible = "google,cros-ec-i2c-tunnel", | ||
97 | }, | ||
93 | }; | 98 | }; |
94 | 99 | ||
95 | int cros_ec_register(struct cros_ec_device *ec_dev) | 100 | int cros_ec_register(struct cros_ec_device *ec_dev) |
@@ -184,3 +189,6 @@ int cros_ec_resume(struct cros_ec_device *ec_dev) | |||
184 | EXPORT_SYMBOL(cros_ec_resume); | 189 | EXPORT_SYMBOL(cros_ec_resume); |
185 | 190 | ||
186 | #endif | 191 | #endif |
192 | |||
193 | MODULE_LICENSE("GPL"); | ||
194 | MODULE_DESCRIPTION("ChromeOS EC core driver"); | ||
diff --git a/drivers/mfd/cros_ec_spi.c b/drivers/mfd/cros_ec_spi.c index 84af8d7a4295..0b8d32829166 100644 --- a/drivers/mfd/cros_ec_spi.c +++ b/drivers/mfd/cros_ec_spi.c | |||
@@ -39,14 +39,22 @@ | |||
39 | #define EC_MSG_PREAMBLE_COUNT 32 | 39 | #define EC_MSG_PREAMBLE_COUNT 32 |
40 | 40 | ||
41 | /* | 41 | /* |
42 | * We must get a response from the EC in 5ms. This is a very long | 42 | * Allow for a long time for the EC to respond. We support i2c |
43 | * time, but the flash write command can take 2-3ms. The EC command | 43 | * tunneling and support fairly long messages for the tunnel (249 |
44 | * processing is currently not very fast (about 500us). We could | 44 | * bytes long at the moment). If we're talking to a 100 kHz device |
45 | * look at speeding this up and making the flash write command a | 45 | * on the other end and need to transfer ~256 bytes, then we need: |
46 | * 'slow' command, requiring a GET_STATUS wait loop, like flash | 46 | * 10 us/bit * ~10 bits/byte * ~256 bytes = ~25ms |
47 | * erase. | 47 | * |
48 | */ | 48 | * We'll wait 4 times that to handle clock stretching and other |
49 | #define EC_MSG_DEADLINE_MS 5 | 49 | * paranoia. |
50 | * | ||
51 | * It's pretty unlikely that we'll really see a 249 byte tunnel in | ||
52 | * anything other than testing. If this was more common we might | ||
53 | * consider having slow commands like this require a GET_STATUS | ||
54 | * wait loop. The 'flash write' command would be another candidate | ||
55 | * for this, clocking in at 2-3ms. | ||
56 | */ | ||
57 | #define EC_MSG_DEADLINE_MS 100 | ||
50 | 58 | ||
51 | /* | 59 | /* |
52 | * Time between raising the SPI chip select (for the end of a | 60 | * Time between raising the SPI chip select (for the end of a |
@@ -65,11 +73,13 @@ | |||
65 | * if no record | 73 | * if no record |
66 | * @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 |
67 | * 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 | ||
68 | */ | 77 | */ |
69 | struct cros_ec_spi { | 78 | struct cros_ec_spi { |
70 | struct spi_device *spi; | 79 | struct spi_device *spi; |
71 | s64 last_transfer_ns; | 80 | s64 last_transfer_ns; |
72 | unsigned int end_of_msg_delay; | 81 | unsigned int end_of_msg_delay; |
82 | struct mutex lock; | ||
73 | }; | 83 | }; |
74 | 84 | ||
75 | static void debug_packet(struct device *dev, const char *name, u8 *ptr, | 85 | static void debug_packet(struct device *dev, const char *name, u8 *ptr, |
@@ -111,7 +121,9 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, | |||
111 | 121 | ||
112 | /* Receive data until we see the header byte */ | 122 | /* Receive data until we see the header byte */ |
113 | deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); | 123 | deadline = jiffies + msecs_to_jiffies(EC_MSG_DEADLINE_MS); |
114 | do { | 124 | while (true) { |
125 | unsigned long start_jiffies = jiffies; | ||
126 | |||
115 | memset(&trans, 0, sizeof(trans)); | 127 | memset(&trans, 0, sizeof(trans)); |
116 | trans.cs_change = 1; | 128 | trans.cs_change = 1; |
117 | trans.rx_buf = ptr = ec_dev->din; | 129 | trans.rx_buf = ptr = ec_dev->din; |
@@ -132,12 +144,19 @@ static int cros_ec_spi_receive_response(struct cros_ec_device *ec_dev, | |||
132 | break; | 144 | break; |
133 | } | 145 | } |
134 | } | 146 | } |
147 | if (ptr != end) | ||
148 | break; | ||
135 | 149 | ||
136 | if (time_after(jiffies, deadline)) { | 150 | /* |
151 | * Use the time at the start of the loop as a timeout. This | ||
152 | * gives us one last shot at getting the transfer and is useful | ||
153 | * in case we got context switched out for a while. | ||
154 | */ | ||
155 | if (time_after(start_jiffies, deadline)) { | ||
137 | dev_warn(ec_dev->dev, "EC failed to respond in time\n"); | 156 | dev_warn(ec_dev->dev, "EC failed to respond in time\n"); |
138 | return -ETIMEDOUT; | 157 | return -ETIMEDOUT; |
139 | } | 158 | } |
140 | } while (ptr == end); | 159 | } |
141 | 160 | ||
142 | /* | 161 | /* |
143 | * ptr now points to the header byte. Copy any valid data to the | 162 | * ptr now points to the header byte. Copy any valid data to the |
@@ -208,6 +227,13 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
208 | int ret = 0, final_ret; | 227 | int ret = 0, final_ret; |
209 | struct timespec ts; | 228 | struct timespec ts; |
210 | 229 | ||
230 | /* | ||
231 | * We have the shared ec_dev buffer plus we do lots of separate spi_sync | ||
232 | * calls, so we need to make sure only one person is using this at a | ||
233 | * time. | ||
234 | */ | ||
235 | mutex_lock(&ec_spi->lock); | ||
236 | |||
211 | len = cros_ec_prepare_tx(ec_dev, ec_msg); | 237 | len = cros_ec_prepare_tx(ec_dev, ec_msg); |
212 | dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); | 238 | dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); |
213 | 239 | ||
@@ -219,7 +245,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
219 | ktime_get_ts(&ts); | 245 | ktime_get_ts(&ts); |
220 | delay = timespec_to_ns(&ts) - ec_spi->last_transfer_ns; | 246 | delay = timespec_to_ns(&ts) - ec_spi->last_transfer_ns; |
221 | if (delay < EC_SPI_RECOVERY_TIME_NS) | 247 | if (delay < EC_SPI_RECOVERY_TIME_NS) |
222 | ndelay(delay); | 248 | ndelay(EC_SPI_RECOVERY_TIME_NS - delay); |
223 | } | 249 | } |
224 | 250 | ||
225 | /* Transmit phase - send our message */ | 251 | /* Transmit phase - send our message */ |
@@ -260,7 +286,7 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
260 | ret = final_ret; | 286 | ret = final_ret; |
261 | if (ret < 0) { | 287 | if (ret < 0) { |
262 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); | 288 | dev_err(ec_dev->dev, "spi transfer failed: %d\n", ret); |
263 | return ret; | 289 | goto exit; |
264 | } | 290 | } |
265 | 291 | ||
266 | /* check response error code */ | 292 | /* check response error code */ |
@@ -269,14 +295,16 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
269 | dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n", | 295 | dev_warn(ec_dev->dev, "command 0x%02x returned an error %d\n", |
270 | ec_msg->cmd, ptr[0]); | 296 | ec_msg->cmd, ptr[0]); |
271 | debug_packet(ec_dev->dev, "in_err", ptr, len); | 297 | debug_packet(ec_dev->dev, "in_err", ptr, len); |
272 | return -EINVAL; | 298 | ret = -EINVAL; |
299 | goto exit; | ||
273 | } | 300 | } |
274 | len = ptr[1]; | 301 | len = ptr[1]; |
275 | sum = ptr[0] + ptr[1]; | 302 | sum = ptr[0] + ptr[1]; |
276 | if (len > ec_msg->in_len) { | 303 | if (len > ec_msg->in_len) { |
277 | dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", | 304 | dev_err(ec_dev->dev, "packet too long (%d bytes, expected %d)", |
278 | len, ec_msg->in_len); | 305 | len, ec_msg->in_len); |
279 | return -ENOSPC; | 306 | ret = -ENOSPC; |
307 | goto exit; | ||
280 | } | 308 | } |
281 | 309 | ||
282 | /* copy response packet payload and compute checksum */ | 310 | /* copy response packet payload and compute checksum */ |
@@ -293,10 +321,14 @@ static int cros_ec_command_spi_xfer(struct cros_ec_device *ec_dev, | |||
293 | dev_err(ec_dev->dev, | 321 | dev_err(ec_dev->dev, |
294 | "bad packet checksum, expected %02x, got %02x\n", | 322 | "bad packet checksum, expected %02x, got %02x\n", |
295 | sum, ptr[len + 2]); | 323 | sum, ptr[len + 2]); |
296 | return -EBADMSG; | 324 | ret = -EBADMSG; |
325 | goto exit; | ||
297 | } | 326 | } |
298 | 327 | ||
299 | return 0; | 328 | ret = 0; |
329 | exit: | ||
330 | mutex_unlock(&ec_spi->lock); | ||
331 | return ret; | ||
300 | } | 332 | } |
301 | 333 | ||
302 | static void cros_ec_spi_dt_probe(struct cros_ec_spi *ec_spi, struct device *dev) | 334 | static void cros_ec_spi_dt_probe(struct cros_ec_spi *ec_spi, struct device *dev) |
@@ -327,6 +359,7 @@ static int cros_ec_spi_probe(struct spi_device *spi) | |||
327 | if (ec_spi == NULL) | 359 | if (ec_spi == NULL) |
328 | return -ENOMEM; | 360 | return -ENOMEM; |
329 | ec_spi->spi = spi; | 361 | ec_spi->spi = spi; |
362 | mutex_init(&ec_spi->lock); | ||
330 | ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); | 363 | ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); |
331 | if (!ec_dev) | 364 | if (!ec_dev) |
332 | return -ENOMEM; | 365 | return -ENOMEM; |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index b11fdd63eecd..193cf168ba84 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -2300,9 +2300,6 @@ int prcmu_ac_wake_req(void) | |||
2300 | 2300 | ||
2301 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, | 2301 | if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work, |
2302 | msecs_to_jiffies(5000))) { | 2302 | msecs_to_jiffies(5000))) { |
2303 | #if defined(CONFIG_DBX500_PRCMU_DEBUG) | ||
2304 | db8500_prcmu_debug_dump(__func__, true, true); | ||
2305 | #endif | ||
2306 | pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", | 2303 | pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n", |
2307 | __func__); | 2304 | __func__); |
2308 | ret = -EFAULT; | 2305 | ret = -EFAULT; |
@@ -3112,7 +3109,7 @@ static int db8500_prcmu_register_ab8500(struct device *parent, | |||
3112 | { | 3109 | { |
3113 | struct device_node *np; | 3110 | struct device_node *np; |
3114 | struct resource ab8500_resource; | 3111 | struct resource ab8500_resource; |
3115 | struct mfd_cell ab8500_cell = { | 3112 | const struct mfd_cell ab8500_cell = { |
3116 | .name = "ab8500-core", | 3113 | .name = "ab8500-core", |
3117 | .of_compatible = "stericsson,ab8500", | 3114 | .of_compatible = "stericsson,ab8500", |
3118 | .id = AB8500_VERSION_AB8500, | 3115 | .id = AB8500_VERSION_AB8500, |
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c new file mode 100644 index 000000000000..7e50fe0118e3 --- /dev/null +++ b/drivers/mfd/ipaq-micro.c | |||
@@ -0,0 +1,482 @@ | |||
1 | /* | ||
2 | * Compaq iPAQ h3xxx Atmel microcontroller companion support | ||
3 | * | ||
4 | * This is an Atmel AT90LS8535 with a special flashed-in firmware that | ||
5 | * implements the special protocol used by this driver. | ||
6 | * | ||
7 | * based on previous kernel 2.4 version by Andrew Christian | ||
8 | * Author : Alessandro Gardich <gremlin@gremlin.it> | ||
9 | * Author : Dmitry Artamonow <mad_soft@inbox.ru> | ||
10 | * Author : Linus Walleij <linus.walleij@linaro.org> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License version 2 as | ||
14 | * published by the Free Software Foundation. | ||
15 | */ | ||
16 | |||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/pm.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/mfd/core.h> | ||
26 | #include <linux/mfd/ipaq-micro.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/random.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/list.h> | ||
31 | |||
32 | #include <mach/hardware.h> | ||
33 | |||
34 | static void ipaq_micro_trigger_tx(struct ipaq_micro *micro) | ||
35 | { | ||
36 | struct ipaq_micro_txdev *tx = µ->tx; | ||
37 | struct ipaq_micro_msg *msg = micro->msg; | ||
38 | int i, bp; | ||
39 | u8 checksum; | ||
40 | u32 val; | ||
41 | |||
42 | bp = 0; | ||
43 | tx->buf[bp++] = CHAR_SOF; | ||
44 | |||
45 | checksum = ((msg->id & 0x0f) << 4) | (msg->tx_len & 0x0f); | ||
46 | tx->buf[bp++] = checksum; | ||
47 | |||
48 | for (i = 0; i < msg->tx_len; i++) { | ||
49 | tx->buf[bp++] = msg->tx_data[i]; | ||
50 | checksum += msg->tx_data[i]; | ||
51 | } | ||
52 | |||
53 | tx->buf[bp++] = checksum; | ||
54 | tx->len = bp; | ||
55 | tx->index = 0; | ||
56 | print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
57 | tx->buf, tx->len, true); | ||
58 | |||
59 | /* Enable interrupt */ | ||
60 | val = readl(micro->base + UTCR3); | ||
61 | val |= UTCR3_TIE; | ||
62 | writel(val, micro->base + UTCR3); | ||
63 | } | ||
64 | |||
65 | int ipaq_micro_tx_msg(struct ipaq_micro *micro, struct ipaq_micro_msg *msg) | ||
66 | { | ||
67 | unsigned long flags; | ||
68 | |||
69 | dev_dbg(micro->dev, "TX msg: %02x, %d bytes\n", msg->id, msg->tx_len); | ||
70 | |||
71 | spin_lock_irqsave(µ->lock, flags); | ||
72 | if (micro->msg) { | ||
73 | list_add_tail(&msg->node, µ->queue); | ||
74 | spin_unlock_irqrestore(µ->lock, flags); | ||
75 | return 0; | ||
76 | } | ||
77 | micro->msg = msg; | ||
78 | ipaq_micro_trigger_tx(micro); | ||
79 | spin_unlock_irqrestore(µ->lock, flags); | ||
80 | return 0; | ||
81 | } | ||
82 | EXPORT_SYMBOL(ipaq_micro_tx_msg); | ||
83 | |||
84 | static void micro_rx_msg(struct ipaq_micro *micro, u8 id, int len, u8 *data) | ||
85 | { | ||
86 | int i; | ||
87 | |||
88 | dev_dbg(micro->dev, "RX msg: %02x, %d bytes\n", id, len); | ||
89 | |||
90 | spin_lock(µ->lock); | ||
91 | switch (id) { | ||
92 | case MSG_VERSION: | ||
93 | case MSG_EEPROM_READ: | ||
94 | case MSG_EEPROM_WRITE: | ||
95 | case MSG_BACKLIGHT: | ||
96 | case MSG_NOTIFY_LED: | ||
97 | case MSG_THERMAL_SENSOR: | ||
98 | case MSG_BATTERY: | ||
99 | /* Handle synchronous messages */ | ||
100 | if (micro->msg && micro->msg->id == id) { | ||
101 | struct ipaq_micro_msg *msg = micro->msg; | ||
102 | |||
103 | memcpy(msg->rx_data, data, len); | ||
104 | msg->rx_len = len; | ||
105 | complete(µ->msg->ack); | ||
106 | if (!list_empty(µ->queue)) { | ||
107 | micro->msg = list_entry(micro->queue.next, | ||
108 | struct ipaq_micro_msg, | ||
109 | node); | ||
110 | list_del_init(µ->msg->node); | ||
111 | ipaq_micro_trigger_tx(micro); | ||
112 | } else | ||
113 | micro->msg = NULL; | ||
114 | dev_dbg(micro->dev, "OK RX message 0x%02x\n", id); | ||
115 | } else { | ||
116 | dev_err(micro->dev, | ||
117 | "out of band RX message 0x%02x\n", id); | ||
118 | if(!micro->msg) | ||
119 | dev_info(micro->dev, "no message queued\n"); | ||
120 | else | ||
121 | dev_info(micro->dev, "expected message %02x\n", | ||
122 | micro->msg->id); | ||
123 | } | ||
124 | break; | ||
125 | case MSG_KEYBOARD: | ||
126 | if (micro->key) | ||
127 | micro->key(micro->key_data, len, data); | ||
128 | else | ||
129 | dev_dbg(micro->dev, "key message ignored, no handle \n"); | ||
130 | break; | ||
131 | case MSG_TOUCHSCREEN: | ||
132 | if (micro->ts) | ||
133 | micro->ts(micro->ts_data, len, data); | ||
134 | else | ||
135 | dev_dbg(micro->dev, "touchscreen message ignored, no handle \n"); | ||
136 | break; | ||
137 | default: | ||
138 | dev_err(micro->dev, | ||
139 | "unknown msg %d [%d] ", id, len); | ||
140 | for (i = 0; i < len; ++i) | ||
141 | pr_cont("0x%02x ", data[i]); | ||
142 | pr_cont("\n"); | ||
143 | } | ||
144 | spin_unlock(µ->lock); | ||
145 | } | ||
146 | |||
147 | static void micro_process_char(struct ipaq_micro *micro, u8 ch) | ||
148 | { | ||
149 | struct ipaq_micro_rxdev *rx = µ->rx; | ||
150 | |||
151 | switch (rx->state) { | ||
152 | case STATE_SOF: /* Looking for SOF */ | ||
153 | if (ch == CHAR_SOF) | ||
154 | rx->state = STATE_ID; /* Next byte is the id and len */ | ||
155 | break; | ||
156 | case STATE_ID: /* Looking for id and len byte */ | ||
157 | rx->id = (ch & 0xf0) >> 4 ; | ||
158 | rx->len = (ch & 0x0f); | ||
159 | rx->index = 0; | ||
160 | rx->chksum = ch; | ||
161 | rx->state = (rx->len > 0) ? STATE_DATA : STATE_CHKSUM; | ||
162 | break; | ||
163 | case STATE_DATA: /* Looking for 'len' data bytes */ | ||
164 | rx->chksum += ch; | ||
165 | rx->buf[rx->index] = ch; | ||
166 | if (++rx->index == rx->len) | ||
167 | rx->state = STATE_CHKSUM; | ||
168 | break; | ||
169 | case STATE_CHKSUM: /* Looking for the checksum */ | ||
170 | if (ch == rx->chksum) | ||
171 | micro_rx_msg(micro, rx->id, rx->len, rx->buf); | ||
172 | rx->state = STATE_SOF; | ||
173 | break; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | static void micro_rx_chars(struct ipaq_micro *micro) | ||
178 | { | ||
179 | u32 status, ch; | ||
180 | |||
181 | while ((status = readl(micro->base + UTSR1)) & UTSR1_RNE) { | ||
182 | ch = readl(micro->base + UTDR); | ||
183 | if (status & UTSR1_PRE) | ||
184 | dev_err(micro->dev, "rx: parity error\n"); | ||
185 | else if (status & UTSR1_FRE) | ||
186 | dev_err(micro->dev, "rx: framing error\n"); | ||
187 | else if (status & UTSR1_ROR) | ||
188 | dev_err(micro->dev, "rx: overrun error\n"); | ||
189 | micro_process_char(micro, ch); | ||
190 | } | ||
191 | } | ||
192 | |||
193 | static void ipaq_micro_get_version(struct ipaq_micro *micro) | ||
194 | { | ||
195 | struct ipaq_micro_msg msg = { | ||
196 | .id = MSG_VERSION, | ||
197 | }; | ||
198 | |||
199 | ipaq_micro_tx_msg_sync(micro, &msg); | ||
200 | if (msg.rx_len == 4) { | ||
201 | memcpy(micro->version, msg.rx_data, 4); | ||
202 | micro->version[4] = '\0'; | ||
203 | } else if (msg.rx_len == 9) { | ||
204 | memcpy(micro->version, msg.rx_data, 4); | ||
205 | micro->version[4] = '\0'; | ||
206 | /* Bytes 4-7 are "pack", byte 8 is "boot type" */ | ||
207 | } else { | ||
208 | dev_err(micro->dev, | ||
209 | "illegal version message %d bytes\n", msg.rx_len); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | static void ipaq_micro_eeprom_read(struct ipaq_micro *micro, | ||
214 | u8 address, u8 len, u8 *data) | ||
215 | { | ||
216 | struct ipaq_micro_msg msg = { | ||
217 | .id = MSG_EEPROM_READ, | ||
218 | }; | ||
219 | u8 i; | ||
220 | |||
221 | for (i = 0; i < len; i++) { | ||
222 | msg.tx_data[0] = address + i; | ||
223 | msg.tx_data[1] = 1; | ||
224 | msg.tx_len = 2; | ||
225 | ipaq_micro_tx_msg_sync(micro, &msg); | ||
226 | memcpy(data + (i * 2), msg.rx_data, 2); | ||
227 | } | ||
228 | } | ||
229 | |||
230 | static char *ipaq_micro_str(u8 *wchar, u8 len) | ||
231 | { | ||
232 | char retstr[256]; | ||
233 | u8 i; | ||
234 | |||
235 | for (i = 0; i < len / 2; i++) | ||
236 | retstr[i] = wchar[i * 2]; | ||
237 | return kstrdup(retstr, GFP_KERNEL); | ||
238 | } | ||
239 | |||
240 | static u16 ipaq_micro_to_u16(u8 *data) | ||
241 | { | ||
242 | return data[1] << 8 | data[0]; | ||
243 | } | ||
244 | |||
245 | static void ipaq_micro_eeprom_dump(struct ipaq_micro *micro) | ||
246 | { | ||
247 | u8 dump[256]; | ||
248 | char *str; | ||
249 | |||
250 | ipaq_micro_eeprom_read(micro, 0, 128, dump); | ||
251 | str = ipaq_micro_str(dump, 10); | ||
252 | if (str) { | ||
253 | dev_info(micro->dev, "HM version %s\n", str); | ||
254 | kfree(str); | ||
255 | } | ||
256 | str = ipaq_micro_str(dump+10, 40); | ||
257 | if (str) { | ||
258 | dev_info(micro->dev, "serial number: %s\n", str); | ||
259 | /* Feed the random pool with this */ | ||
260 | add_device_randomness(str, strlen(str)); | ||
261 | kfree(str); | ||
262 | } | ||
263 | str = ipaq_micro_str(dump+50, 20); | ||
264 | if (str) { | ||
265 | dev_info(micro->dev, "module ID: %s\n", str); | ||
266 | kfree(str); | ||
267 | } | ||
268 | str = ipaq_micro_str(dump+70, 10); | ||
269 | if (str) { | ||
270 | dev_info(micro->dev, "product revision: %s\n", str); | ||
271 | kfree(str); | ||
272 | } | ||
273 | dev_info(micro->dev, "product ID: %u\n", ipaq_micro_to_u16(dump+80)); | ||
274 | dev_info(micro->dev, "frame rate: %u fps\n", | ||
275 | ipaq_micro_to_u16(dump+82)); | ||
276 | dev_info(micro->dev, "page mode: %u\n", ipaq_micro_to_u16(dump+84)); | ||
277 | dev_info(micro->dev, "country ID: %u\n", ipaq_micro_to_u16(dump+86)); | ||
278 | dev_info(micro->dev, "color display: %s\n", | ||
279 | ipaq_micro_to_u16(dump+88) ? "yes" : "no"); | ||
280 | dev_info(micro->dev, "ROM size: %u MiB\n", ipaq_micro_to_u16(dump+90)); | ||
281 | dev_info(micro->dev, "RAM size: %u KiB\n", ipaq_micro_to_u16(dump+92)); | ||
282 | dev_info(micro->dev, "screen: %u x %u\n", | ||
283 | ipaq_micro_to_u16(dump+94), ipaq_micro_to_u16(dump+96)); | ||
284 | print_hex_dump(KERN_DEBUG, "eeprom: ", DUMP_PREFIX_OFFSET, 16, 1, | ||
285 | dump, 256, true); | ||
286 | |||
287 | } | ||
288 | |||
289 | static void micro_tx_chars(struct ipaq_micro *micro) | ||
290 | { | ||
291 | struct ipaq_micro_txdev *tx = µ->tx; | ||
292 | u32 val; | ||
293 | |||
294 | while ((tx->index < tx->len) && | ||
295 | (readl(micro->base + UTSR1) & UTSR1_TNF)) { | ||
296 | writel(tx->buf[tx->index], micro->base + UTDR); | ||
297 | tx->index++; | ||
298 | } | ||
299 | |||
300 | /* Stop interrupts */ | ||
301 | val = readl(micro->base + UTCR3); | ||
302 | val &= ~UTCR3_TIE; | ||
303 | writel(val, micro->base + UTCR3); | ||
304 | } | ||
305 | |||
306 | static void micro_reset_comm(struct ipaq_micro *micro) | ||
307 | { | ||
308 | struct ipaq_micro_rxdev *rx = µ->rx; | ||
309 | u32 val; | ||
310 | |||
311 | if (micro->msg) | ||
312 | complete(µ->msg->ack); | ||
313 | |||
314 | /* Initialize Serial channel protocol frame */ | ||
315 | rx->state = STATE_SOF; /* Reset the state machine */ | ||
316 | |||
317 | /* Set up interrupts */ | ||
318 | writel(0x01, micro->sdlc + 0x0); /* Select UART mode */ | ||
319 | |||
320 | /* Clean up CR3 */ | ||
321 | writel(0x0, micro->base + UTCR3); | ||
322 | |||
323 | /* Format: 8N1 */ | ||
324 | writel(UTCR0_8BitData | UTCR0_1StpBit, micro->base + UTCR0); | ||
325 | |||
326 | /* Baud rate: 115200 */ | ||
327 | writel(0x0, micro->base + UTCR1); | ||
328 | writel(0x1, micro->base + UTCR2); | ||
329 | |||
330 | /* Clear SR0 */ | ||
331 | writel(0xff, micro->base + UTSR0); | ||
332 | |||
333 | /* Enable RX int, disable TX int */ | ||
334 | writel(UTCR3_TXE | UTCR3_RXE | UTCR3_RIE, micro->base + UTCR3); | ||
335 | val = readl(micro->base + UTCR3); | ||
336 | val &= ~UTCR3_TIE; | ||
337 | writel(val, micro->base + UTCR3); | ||
338 | } | ||
339 | |||
340 | static irqreturn_t micro_serial_isr(int irq, void *dev_id) | ||
341 | { | ||
342 | struct ipaq_micro *micro = dev_id; | ||
343 | struct ipaq_micro_txdev *tx = µ->tx; | ||
344 | u32 status; | ||
345 | |||
346 | status = readl(micro->base + UTSR0); | ||
347 | do { | ||
348 | if (status & (UTSR0_RID | UTSR0_RFS)) { | ||
349 | if (status & UTSR0_RID) | ||
350 | /* Clear the Receiver IDLE bit */ | ||
351 | writel(UTSR0_RID, micro->base + UTSR0); | ||
352 | micro_rx_chars(micro); | ||
353 | } | ||
354 | |||
355 | /* Clear break bits */ | ||
356 | if (status & (UTSR0_RBB | UTSR0_REB)) | ||
357 | writel(status & (UTSR0_RBB | UTSR0_REB), | ||
358 | micro->base + UTSR0); | ||
359 | |||
360 | if (status & UTSR0_TFS) | ||
361 | micro_tx_chars(micro); | ||
362 | |||
363 | status = readl(micro->base + UTSR0); | ||
364 | |||
365 | } while (((tx->index < tx->len) && (status & UTSR0_TFS)) || | ||
366 | (status & (UTSR0_RFS | UTSR0_RID))); | ||
367 | |||
368 | return IRQ_HANDLED; | ||
369 | } | ||
370 | |||
371 | static const struct mfd_cell micro_cells[] = { | ||
372 | { .name = "ipaq-micro-backlight", }, | ||
373 | { .name = "ipaq-micro-battery", }, | ||
374 | { .name = "ipaq-micro-keys", }, | ||
375 | { .name = "ipaq-micro-ts", }, | ||
376 | { .name = "ipaq-micro-leds", }, | ||
377 | }; | ||
378 | |||
379 | static int micro_resume(struct device *dev) | ||
380 | { | ||
381 | struct ipaq_micro *micro = dev_get_drvdata(dev); | ||
382 | |||
383 | micro_reset_comm(micro); | ||
384 | mdelay(10); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int micro_probe(struct platform_device *pdev) | ||
390 | { | ||
391 | struct ipaq_micro *micro; | ||
392 | struct resource *res; | ||
393 | int ret; | ||
394 | int irq; | ||
395 | |||
396 | micro = devm_kzalloc(&pdev->dev, sizeof(*micro), GFP_KERNEL); | ||
397 | if (!micro) | ||
398 | return -ENOMEM; | ||
399 | |||
400 | micro->dev = &pdev->dev; | ||
401 | |||
402 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
403 | if (!res) | ||
404 | return -EINVAL; | ||
405 | |||
406 | micro->base = devm_ioremap_resource(&pdev->dev, res); | ||
407 | if (IS_ERR(micro->base)) | ||
408 | return PTR_ERR(micro->base); | ||
409 | |||
410 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
411 | if (!res) | ||
412 | return -EINVAL; | ||
413 | |||
414 | micro->sdlc = devm_ioremap_resource(&pdev->dev, res); | ||
415 | if (IS_ERR(micro->sdlc)) | ||
416 | return PTR_ERR(micro->sdlc); | ||
417 | |||
418 | micro_reset_comm(micro); | ||
419 | |||
420 | irq = platform_get_irq(pdev, 0); | ||
421 | if (!irq) | ||
422 | return -EINVAL; | ||
423 | ret = devm_request_irq(&pdev->dev, irq, micro_serial_isr, | ||
424 | IRQF_SHARED, "ipaq-micro", | ||
425 | micro); | ||
426 | if (ret) { | ||
427 | dev_err(&pdev->dev, "unable to grab serial port IRQ\n"); | ||
428 | return ret; | ||
429 | } else | ||
430 | dev_info(&pdev->dev, "grabbed serial port IRQ\n"); | ||
431 | |||
432 | spin_lock_init(µ->lock); | ||
433 | INIT_LIST_HEAD(µ->queue); | ||
434 | platform_set_drvdata(pdev, micro); | ||
435 | |||
436 | ret = mfd_add_devices(&pdev->dev, pdev->id, micro_cells, | ||
437 | ARRAY_SIZE(micro_cells), NULL, 0, NULL); | ||
438 | if (ret) { | ||
439 | dev_err(&pdev->dev, "error adding MFD cells"); | ||
440 | return ret; | ||
441 | } | ||
442 | |||
443 | /* Check version */ | ||
444 | ipaq_micro_get_version(micro); | ||
445 | dev_info(&pdev->dev, "Atmel micro ASIC version %s\n", micro->version); | ||
446 | ipaq_micro_eeprom_dump(micro); | ||
447 | |||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int micro_remove(struct platform_device *pdev) | ||
452 | { | ||
453 | struct ipaq_micro *micro = platform_get_drvdata(pdev); | ||
454 | u32 val; | ||
455 | |||
456 | mfd_remove_devices(&pdev->dev); | ||
457 | |||
458 | val = readl(micro->base + UTCR3); | ||
459 | val &= ~(UTCR3_RXE | UTCR3_RIE); /* disable receive interrupt */ | ||
460 | val &= ~(UTCR3_TXE | UTCR3_TIE); /* disable transmit interrupt */ | ||
461 | writel(val, micro->base + UTCR3); | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static const struct dev_pm_ops micro_dev_pm_ops = { | ||
467 | SET_SYSTEM_SLEEP_PM_OPS(NULL, micro_resume) | ||
468 | }; | ||
469 | |||
470 | static struct platform_driver micro_device_driver = { | ||
471 | .driver = { | ||
472 | .name = "ipaq-h3xxx-micro", | ||
473 | .pm = µ_dev_pm_ops, | ||
474 | }, | ||
475 | .probe = micro_probe, | ||
476 | .remove = micro_remove, | ||
477 | /* .shutdown = micro_suspend, // FIXME */ | ||
478 | }; | ||
479 | module_platform_driver(micro_device_driver); | ||
480 | |||
481 | MODULE_LICENSE("GPL"); | ||
482 | MODULE_DESCRIPTION("driver for iPAQ Atmel micro core and backlight"); | ||
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index 07692604e119..f7ff0188603d 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c | |||
@@ -86,7 +86,7 @@ enum kempld_cells { | |||
86 | KEMPLD_UART, | 86 | KEMPLD_UART, |
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct mfd_cell kempld_devs[] = { | 89 | static const struct mfd_cell kempld_devs[] = { |
90 | [KEMPLD_I2C] = { | 90 | [KEMPLD_I2C] = { |
91 | .name = "kempld-i2c", | 91 | .name = "kempld-i2c", |
92 | }, | 92 | }, |
@@ -288,9 +288,38 @@ EXPORT_SYMBOL_GPL(kempld_release_mutex); | |||
288 | */ | 288 | */ |
289 | static int kempld_get_info(struct kempld_device_data *pld) | 289 | static int kempld_get_info(struct kempld_device_data *pld) |
290 | { | 290 | { |
291 | int ret; | ||
291 | struct kempld_platform_data *pdata = dev_get_platdata(pld->dev); | 292 | struct kempld_platform_data *pdata = dev_get_platdata(pld->dev); |
293 | char major, minor; | ||
294 | |||
295 | ret = pdata->get_info(pld); | ||
296 | if (ret) | ||
297 | return ret; | ||
298 | |||
299 | /* The Kontron PLD firmware version string has the following format: | ||
300 | * Pwxy.zzzz | ||
301 | * P: Fixed | ||
302 | * w: PLD number - 1 hex digit | ||
303 | * x: Major version - 1 alphanumerical digit (0-9A-V) | ||
304 | * y: Minor version - 1 alphanumerical digit (0-9A-V) | ||
305 | * zzzz: Build number - 4 zero padded hex digits */ | ||
292 | 306 | ||
293 | return pdata->get_info(pld); | 307 | if (pld->info.major < 10) |
308 | major = pld->info.major + '0'; | ||
309 | else | ||
310 | major = (pld->info.major - 10) + 'A'; | ||
311 | if (pld->info.minor < 10) | ||
312 | minor = pld->info.minor + '0'; | ||
313 | else | ||
314 | minor = (pld->info.minor - 10) + 'A'; | ||
315 | |||
316 | ret = scnprintf(pld->info.version, sizeof(pld->info.version), | ||
317 | "P%X%c%c.%04X", pld->info.number, major, minor, | ||
318 | pld->info.buildnr); | ||
319 | if (ret < 0) | ||
320 | return ret; | ||
321 | |||
322 | return 0; | ||
294 | } | 323 | } |
295 | 324 | ||
296 | /* | 325 | /* |
@@ -307,9 +336,71 @@ static int kempld_register_cells(struct kempld_device_data *pld) | |||
307 | return pdata->register_cells(pld); | 336 | return pdata->register_cells(pld); |
308 | } | 337 | } |
309 | 338 | ||
339 | static const char *kempld_get_type_string(struct kempld_device_data *pld) | ||
340 | { | ||
341 | const char *version_type; | ||
342 | |||
343 | switch (pld->info.type) { | ||
344 | case 0: | ||
345 | version_type = "release"; | ||
346 | break; | ||
347 | case 1: | ||
348 | version_type = "debug"; | ||
349 | break; | ||
350 | case 2: | ||
351 | version_type = "custom"; | ||
352 | break; | ||
353 | default: | ||
354 | version_type = "unspecified"; | ||
355 | break; | ||
356 | } | ||
357 | |||
358 | return version_type; | ||
359 | } | ||
360 | |||
361 | static ssize_t kempld_version_show(struct device *dev, | ||
362 | struct device_attribute *attr, char *buf) | ||
363 | { | ||
364 | struct kempld_device_data *pld = dev_get_drvdata(dev); | ||
365 | |||
366 | return scnprintf(buf, PAGE_SIZE, "%s\n", pld->info.version); | ||
367 | } | ||
368 | |||
369 | static ssize_t kempld_specification_show(struct device *dev, | ||
370 | struct device_attribute *attr, char *buf) | ||
371 | { | ||
372 | struct kempld_device_data *pld = dev_get_drvdata(dev); | ||
373 | |||
374 | return scnprintf(buf, PAGE_SIZE, "%d.%d\n", pld->info.spec_major, | ||
375 | pld->info.spec_minor); | ||
376 | } | ||
377 | |||
378 | static ssize_t kempld_type_show(struct device *dev, | ||
379 | struct device_attribute *attr, char *buf) | ||
380 | { | ||
381 | struct kempld_device_data *pld = dev_get_drvdata(dev); | ||
382 | |||
383 | return scnprintf(buf, PAGE_SIZE, "%s\n", kempld_get_type_string(pld)); | ||
384 | } | ||
385 | |||
386 | static DEVICE_ATTR(pld_version, S_IRUGO, kempld_version_show, NULL); | ||
387 | static DEVICE_ATTR(pld_specification, S_IRUGO, kempld_specification_show, | ||
388 | NULL); | ||
389 | static DEVICE_ATTR(pld_type, S_IRUGO, kempld_type_show, NULL); | ||
390 | |||
391 | static struct attribute *pld_attributes[] = { | ||
392 | &dev_attr_pld_version.attr, | ||
393 | &dev_attr_pld_specification.attr, | ||
394 | &dev_attr_pld_type.attr, | ||
395 | NULL | ||
396 | }; | ||
397 | |||
398 | static const struct attribute_group pld_attr_group = { | ||
399 | .attrs = pld_attributes, | ||
400 | }; | ||
401 | |||
310 | static int kempld_detect_device(struct kempld_device_data *pld) | 402 | static int kempld_detect_device(struct kempld_device_data *pld) |
311 | { | 403 | { |
312 | char *version_type; | ||
313 | u8 index_reg; | 404 | u8 index_reg; |
314 | int ret; | 405 | int ret; |
315 | 406 | ||
@@ -335,27 +426,19 @@ static int kempld_detect_device(struct kempld_device_data *pld) | |||
335 | if (ret) | 426 | if (ret) |
336 | return ret; | 427 | return ret; |
337 | 428 | ||
338 | switch (pld->info.type) { | 429 | dev_info(pld->dev, "Found Kontron PLD - %s (%s), spec %d.%d\n", |
339 | case 0: | 430 | pld->info.version, kempld_get_type_string(pld), |
340 | version_type = "release"; | 431 | pld->info.spec_major, pld->info.spec_minor); |
341 | break; | 432 | |
342 | case 1: | 433 | ret = sysfs_create_group(&pld->dev->kobj, &pld_attr_group); |
343 | version_type = "debug"; | 434 | if (ret) |
344 | break; | 435 | return ret; |
345 | case 2: | ||
346 | version_type = "custom"; | ||
347 | break; | ||
348 | default: | ||
349 | version_type = "unspecified"; | ||
350 | } | ||
351 | 436 | ||
352 | dev_info(pld->dev, "Found Kontron PLD %d\n", pld->info.number); | 437 | ret = kempld_register_cells(pld); |
353 | dev_info(pld->dev, "%s version %d.%d build %d, specification %d.%d\n", | 438 | if (ret) |
354 | version_type, pld->info.major, pld->info.minor, | 439 | sysfs_remove_group(&pld->dev->kobj, &pld_attr_group); |
355 | pld->info.buildnr, pld->info.spec_major, | ||
356 | pld->info.spec_minor); | ||
357 | 440 | ||
358 | return kempld_register_cells(pld); | 441 | return ret; |
359 | } | 442 | } |
360 | 443 | ||
361 | static int kempld_probe(struct platform_device *pdev) | 444 | static int kempld_probe(struct platform_device *pdev) |
@@ -399,6 +482,8 @@ static int kempld_remove(struct platform_device *pdev) | |||
399 | struct kempld_device_data *pld = platform_get_drvdata(pdev); | 482 | struct kempld_device_data *pld = platform_get_drvdata(pdev); |
400 | struct kempld_platform_data *pdata = dev_get_platdata(pld->dev); | 483 | struct kempld_platform_data *pdata = dev_get_platdata(pld->dev); |
401 | 484 | ||
485 | sysfs_remove_group(&pld->dev->kobj, &pld_attr_group); | ||
486 | |||
402 | mfd_remove_devices(&pdev->dev); | 487 | mfd_remove_devices(&pdev->dev); |
403 | pdata->release_hardware_mutex(pld); | 488 | pdata->release_hardware_mutex(pld); |
404 | 489 | ||
diff --git a/drivers/mfd/lp3943.c b/drivers/mfd/lp3943.c index e32226836fb4..335b930112b2 100644 --- a/drivers/mfd/lp3943.c +++ b/drivers/mfd/lp3943.c | |||
@@ -62,7 +62,7 @@ static const struct lp3943_reg_cfg lp3943_mux_cfg[] = { | |||
62 | { LP3943_REG_MUX3, 0xC0, 6 }, | 62 | { LP3943_REG_MUX3, 0xC0, 6 }, |
63 | }; | 63 | }; |
64 | 64 | ||
65 | static struct mfd_cell lp3943_devs[] = { | 65 | static const struct mfd_cell lp3943_devs[] = { |
66 | { | 66 | { |
67 | .name = "lp3943-pwm", | 67 | .name = "lp3943-pwm", |
68 | .of_compatible = "ti,lp3943-pwm", | 68 | .of_compatible = "ti,lp3943-pwm", |
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 3f10ea3f45d1..7d8482ff5868 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -488,6 +488,7 @@ static struct lpc_ich_info lpc_chipset_info[] = { | |||
488 | [LPC_PPT] = { | 488 | [LPC_PPT] = { |
489 | .name = "Panther Point", | 489 | .name = "Panther Point", |
490 | .iTCO_version = 2, | 490 | .iTCO_version = 2, |
491 | .gpio_version = ICH_V5_GPIO, | ||
491 | }, | 492 | }, |
492 | [LPC_LPT] = { | 493 | [LPC_LPT] = { |
493 | .name = "Lynx Point", | 494 | .name = "Lynx Point", |
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 484d372a4892..4a5e885383f8 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/mfd/max14577.h> | 26 | #include <linux/mfd/max14577.h> |
27 | #include <linux/mfd/max14577-private.h> | 27 | #include <linux/mfd/max14577-private.h> |
28 | 28 | ||
29 | static struct mfd_cell max14577_devs[] = { | 29 | static const struct mfd_cell max14577_devs[] = { |
30 | { | 30 | { |
31 | .name = "max14577-muic", | 31 | .name = "max14577-muic", |
32 | .of_compatible = "maxim,max14577-muic", | 32 | .of_compatible = "maxim,max14577-muic", |
@@ -38,7 +38,7 @@ static struct mfd_cell max14577_devs[] = { | |||
38 | { .name = "max14577-charger", }, | 38 | { .name = "max14577-charger", }, |
39 | }; | 39 | }; |
40 | 40 | ||
41 | static struct mfd_cell max77836_devs[] = { | 41 | static const struct mfd_cell max77836_devs[] = { |
42 | { | 42 | { |
43 | .name = "max77836-muic", | 43 | .name = "max77836-muic", |
44 | .of_compatible = "maxim,max77836-muic", | 44 | .of_compatible = "maxim,max77836-muic", |
@@ -57,7 +57,7 @@ static struct mfd_cell max77836_devs[] = { | |||
57 | }, | 57 | }, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | static struct of_device_id max14577_dt_match[] = { | 60 | static const struct of_device_id max14577_dt_match[] = { |
61 | { | 61 | { |
62 | .compatible = "maxim,max14577", | 62 | .compatible = "maxim,max14577", |
63 | .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, | 63 | .data = (void *)MAXIM_DEVICE_TYPE_MAX14577, |
@@ -292,7 +292,7 @@ static int max14577_i2c_probe(struct i2c_client *i2c, | |||
292 | struct device_node *np = i2c->dev.of_node; | 292 | struct device_node *np = i2c->dev.of_node; |
293 | int ret = 0; | 293 | int ret = 0; |
294 | const struct regmap_irq_chip *irq_chip; | 294 | const struct regmap_irq_chip *irq_chip; |
295 | struct mfd_cell *mfd_devs; | 295 | const struct mfd_cell *mfd_devs; |
296 | unsigned int mfd_devs_size; | 296 | unsigned int mfd_devs_size; |
297 | int irq_flags; | 297 | int irq_flags; |
298 | 298 | ||
@@ -331,7 +331,8 @@ static int max14577_i2c_probe(struct i2c_client *i2c, | |||
331 | 331 | ||
332 | of_id = of_match_device(max14577_dt_match, &i2c->dev); | 332 | of_id = of_match_device(max14577_dt_match, &i2c->dev); |
333 | if (of_id) | 333 | if (of_id) |
334 | max14577->dev_type = (unsigned int)of_id->data; | 334 | max14577->dev_type = |
335 | (enum maxim_device_type)of_id->data; | ||
335 | } else { | 336 | } else { |
336 | max14577->dev_type = id->driver_data; | 337 | max14577->dev_type = id->driver_data; |
337 | } | 338 | } |
@@ -414,20 +415,18 @@ static int max14577_suspend(struct device *dev) | |||
414 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 415 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
415 | struct max14577 *max14577 = i2c_get_clientdata(i2c); | 416 | struct max14577 *max14577 = i2c_get_clientdata(i2c); |
416 | 417 | ||
417 | if (device_may_wakeup(dev)) { | 418 | if (device_may_wakeup(dev)) |
418 | enable_irq_wake(max14577->irq); | 419 | enable_irq_wake(max14577->irq); |
419 | /* | 420 | /* |
420 | * MUIC IRQ must be disabled during suspend if this is | 421 | * MUIC IRQ must be disabled during suspend because if it happens |
421 | * a wake up source because it will be handled before | 422 | * while suspended it will be handled before resuming I2C. |
422 | * resuming I2C. | 423 | * |
423 | * | 424 | * When device is woken up from suspend (e.g. by ADC change), |
424 | * When device is woken up from suspend (e.g. by ADC change), | 425 | * an interrupt occurs before resuming I2C bus controller. |
425 | * an interrupt occurs before resuming I2C bus controller. | 426 | * Interrupt handler tries to read registers but this read |
426 | * Interrupt handler tries to read registers but this read | 427 | * will fail because I2C is still suspended. |
427 | * will fail because I2C is still suspended. | 428 | */ |
428 | */ | 429 | disable_irq(max14577->irq); |
429 | disable_irq(max14577->irq); | ||
430 | } | ||
431 | 430 | ||
432 | return 0; | 431 | return 0; |
433 | } | 432 | } |
@@ -437,10 +436,9 @@ static int max14577_resume(struct device *dev) | |||
437 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 436 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
438 | struct max14577 *max14577 = i2c_get_clientdata(i2c); | 437 | struct max14577 *max14577 = i2c_get_clientdata(i2c); |
439 | 438 | ||
440 | if (device_may_wakeup(dev)) { | 439 | if (device_may_wakeup(dev)) |
441 | disable_irq_wake(max14577->irq); | 440 | disable_irq_wake(max14577->irq); |
442 | enable_irq(max14577->irq); | 441 | enable_irq(max14577->irq); |
443 | } | ||
444 | 442 | ||
445 | return 0; | 443 | return 0; |
446 | } | 444 | } |
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index e5fce765accb..ce869acf27ae 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -47,7 +47,7 @@ static struct regmap_config max77686_regmap_config = { | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | #ifdef CONFIG_OF | 49 | #ifdef CONFIG_OF |
50 | static struct of_device_id max77686_pmic_dt_match[] = { | 50 | static const struct of_device_id max77686_pmic_dt_match[] = { |
51 | {.compatible = "maxim,max77686", .data = NULL}, | 51 | {.compatible = "maxim,max77686", .data = NULL}, |
52 | {}, | 52 | {}, |
53 | }; | 53 | }; |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index c5535f018466..7e05428c756d 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -243,7 +243,7 @@ static const struct dev_pm_ops max77693_pm = { | |||
243 | }; | 243 | }; |
244 | 244 | ||
245 | #ifdef CONFIG_OF | 245 | #ifdef CONFIG_OF |
246 | static struct of_device_id max77693_dt_match[] = { | 246 | static const struct of_device_id max77693_dt_match[] = { |
247 | { .compatible = "maxim,max77693" }, | 247 | { .compatible = "maxim,max77693" }, |
248 | {}, | 248 | {}, |
249 | }; | 249 | }; |
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c index 07740314b29d..232749c8813d 100644 --- a/drivers/mfd/max8907.c +++ b/drivers/mfd/max8907.c | |||
@@ -305,7 +305,7 @@ static int max8907_i2c_remove(struct i2c_client *i2c) | |||
305 | } | 305 | } |
306 | 306 | ||
307 | #ifdef CONFIG_OF | 307 | #ifdef CONFIG_OF |
308 | static struct of_device_id max8907_of_match[] = { | 308 | static const struct of_device_id max8907_of_match[] = { |
309 | { .compatible = "maxim,max8907" }, | 309 | { .compatible = "maxim,max8907" }, |
310 | { }, | 310 | { }, |
311 | }; | 311 | }; |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 8cf7a015cfe5..595364ee178a 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -51,7 +51,7 @@ static const struct mfd_cell max8997_devs[] = { | |||
51 | }; | 51 | }; |
52 | 52 | ||
53 | #ifdef CONFIG_OF | 53 | #ifdef CONFIG_OF |
54 | static struct of_device_id max8997_pmic_dt_match[] = { | 54 | static const struct of_device_id max8997_pmic_dt_match[] = { |
55 | { .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 }, | 55 | { .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 }, |
56 | {}, | 56 | {}, |
57 | }; | 57 | }; |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 592db06098e6..a37cb7444b6e 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -132,7 +132,7 @@ int max8998_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask) | |||
132 | EXPORT_SYMBOL(max8998_update_reg); | 132 | EXPORT_SYMBOL(max8998_update_reg); |
133 | 133 | ||
134 | #ifdef CONFIG_OF | 134 | #ifdef CONFIG_OF |
135 | static struct of_device_id max8998_dt_match[] = { | 135 | static const struct of_device_id max8998_dt_match[] = { |
136 | { .compatible = "maxim,max8998", .data = (void *)TYPE_MAX8998 }, | 136 | { .compatible = "maxim,max8998", .data = (void *)TYPE_MAX8998 }, |
137 | { .compatible = "national,lp3974", .data = (void *)TYPE_LP3974 }, | 137 | { .compatible = "national,lp3974", .data = (void *)TYPE_LP3974 }, |
138 | { .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 }, | 138 | { .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 }, |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 0c6c21c5b1a8..acf5dd712eb2 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -660,34 +660,22 @@ int mc13xxx_common_init(struct device *dev) | |||
660 | if (ret) | 660 | if (ret) |
661 | return ret; | 661 | return ret; |
662 | 662 | ||
663 | mutex_init(&mc13xxx->lock); | ||
664 | |||
663 | ret = request_threaded_irq(mc13xxx->irq, NULL, mc13xxx_irq_thread, | 665 | ret = request_threaded_irq(mc13xxx->irq, NULL, mc13xxx_irq_thread, |
664 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); | 666 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); |
665 | if (ret) | 667 | if (ret) |
666 | return ret; | 668 | return ret; |
667 | 669 | ||
668 | mutex_init(&mc13xxx->lock); | ||
669 | |||
670 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) | 670 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) |
671 | mc13xxx->flags = pdata->flags; | 671 | mc13xxx->flags = pdata->flags; |
672 | 672 | ||
673 | if (mc13xxx->flags & MC13XXX_USE_ADC) | 673 | if (mc13xxx->flags & MC13XXX_USE_ADC) |
674 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); | 674 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); |
675 | 675 | ||
676 | if (mc13xxx->flags & MC13XXX_USE_CODEC) { | ||
677 | if (pdata) | ||
678 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", | ||
679 | pdata->codec, sizeof(*pdata->codec)); | ||
680 | else | ||
681 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); | ||
682 | } | ||
683 | |||
684 | if (mc13xxx->flags & MC13XXX_USE_RTC) | 676 | if (mc13xxx->flags & MC13XXX_USE_RTC) |
685 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | 677 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); |
686 | 678 | ||
687 | if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) | ||
688 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts", | ||
689 | &pdata->touch, sizeof(pdata->touch)); | ||
690 | |||
691 | if (pdata) { | 679 | if (pdata) { |
692 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | 680 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", |
693 | &pdata->regulators, sizeof(pdata->regulators)); | 681 | &pdata->regulators, sizeof(pdata->regulators)); |
@@ -695,10 +683,20 @@ int mc13xxx_common_init(struct device *dev) | |||
695 | pdata->leds, sizeof(*pdata->leds)); | 683 | pdata->leds, sizeof(*pdata->leds)); |
696 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", | 684 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", |
697 | pdata->buttons, sizeof(*pdata->buttons)); | 685 | pdata->buttons, sizeof(*pdata->buttons)); |
686 | if (mc13xxx->flags & MC13XXX_USE_CODEC) | ||
687 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", | ||
688 | pdata->codec, sizeof(*pdata->codec)); | ||
689 | if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) | ||
690 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts", | ||
691 | &pdata->touch, sizeof(pdata->touch)); | ||
698 | } else { | 692 | } else { |
699 | mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); | 693 | mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); |
700 | mc13xxx_add_subdevice(mc13xxx, "%s-led"); | 694 | mc13xxx_add_subdevice(mc13xxx, "%s-led"); |
701 | mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); | 695 | mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); |
696 | if (mc13xxx->flags & MC13XXX_USE_CODEC) | ||
697 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); | ||
698 | if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) | ||
699 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); | ||
702 | } | 700 | } |
703 | 701 | ||
704 | return 0; | 702 | return 0; |
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index ad25bfa3fb02..5e2667afe2bc 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c | |||
@@ -1287,29 +1287,8 @@ static struct i2c_driver menelaus_i2c_driver = { | |||
1287 | .id_table = menelaus_id, | 1287 | .id_table = menelaus_id, |
1288 | }; | 1288 | }; |
1289 | 1289 | ||
1290 | static int __init menelaus_init(void) | 1290 | module_i2c_driver(menelaus_i2c_driver); |
1291 | { | ||
1292 | int res; | ||
1293 | |||
1294 | res = i2c_add_driver(&menelaus_i2c_driver); | ||
1295 | if (res < 0) { | ||
1296 | pr_err(DRIVER_NAME ": driver registration failed\n"); | ||
1297 | return res; | ||
1298 | } | ||
1299 | |||
1300 | return 0; | ||
1301 | } | ||
1302 | |||
1303 | static void __exit menelaus_exit(void) | ||
1304 | { | ||
1305 | i2c_del_driver(&menelaus_i2c_driver); | ||
1306 | |||
1307 | /* FIXME: Shutdown menelaus parts that can be shut down */ | ||
1308 | } | ||
1309 | 1291 | ||
1310 | MODULE_AUTHOR("Texas Instruments, Inc. (and others)"); | 1292 | MODULE_AUTHOR("Texas Instruments, Inc. (and others)"); |
1311 | MODULE_DESCRIPTION("I2C interface for Menelaus."); | 1293 | MODULE_DESCRIPTION("I2C interface for Menelaus."); |
1312 | MODULE_LICENSE("GPL"); | 1294 | MODULE_LICENSE("GPL"); |
1313 | |||
1314 | module_init(menelaus_init); | ||
1315 | module_exit(menelaus_exit); | ||
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 267649244737..892d343193ad 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -102,7 +102,7 @@ static int mfd_add_device(struct device *parent, int id, | |||
102 | pdev->dev.dma_mask = parent->dma_mask; | 102 | pdev->dev.dma_mask = parent->dma_mask; |
103 | pdev->dev.dma_parms = parent->dma_parms; | 103 | pdev->dev.dma_parms = parent->dma_parms; |
104 | 104 | ||
105 | ret = devm_regulator_bulk_register_supply_alias( | 105 | ret = regulator_bulk_register_supply_alias( |
106 | &pdev->dev, cell->parent_supplies, | 106 | &pdev->dev, cell->parent_supplies, |
107 | parent, cell->parent_supplies, | 107 | parent, cell->parent_supplies, |
108 | cell->num_parent_supplies); | 108 | cell->num_parent_supplies); |
@@ -182,9 +182,9 @@ static int mfd_add_device(struct device *parent, int id, | |||
182 | return 0; | 182 | return 0; |
183 | 183 | ||
184 | fail_alias: | 184 | fail_alias: |
185 | devm_regulator_bulk_unregister_supply_alias(&pdev->dev, | 185 | regulator_bulk_unregister_supply_alias(&pdev->dev, |
186 | cell->parent_supplies, | 186 | cell->parent_supplies, |
187 | cell->num_parent_supplies); | 187 | cell->num_parent_supplies); |
188 | fail_res: | 188 | fail_res: |
189 | kfree(res); | 189 | kfree(res); |
190 | fail_device: | 190 | fail_device: |
@@ -238,6 +238,9 @@ static int mfd_remove_devices_fn(struct device *dev, void *c) | |||
238 | pdev = to_platform_device(dev); | 238 | pdev = to_platform_device(dev); |
239 | cell = mfd_get_cell(pdev); | 239 | cell = mfd_get_cell(pdev); |
240 | 240 | ||
241 | regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, | ||
242 | cell->num_parent_supplies); | ||
243 | |||
241 | /* find the base address of usage_count pointers (for freeing) */ | 244 | /* find the base address of usage_count pointers (for freeing) */ |
242 | if (!*usage_count || (cell->usage_count < *usage_count)) | 245 | if (!*usage_count || (cell->usage_count < *usage_count)) |
243 | *usage_count = cell->usage_count; | 246 | *usage_count = cell->usage_count; |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 651e249287dc..b48d80c367f9 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -557,7 +557,7 @@ static int usbhs_omap_get_dt_pdata(struct device *dev, | |||
557 | return 0; | 557 | return 0; |
558 | } | 558 | } |
559 | 559 | ||
560 | static struct of_device_id usbhs_child_match_table[] = { | 560 | static const struct of_device_id usbhs_child_match_table[] = { |
561 | { .compatible = "ti,omap-ehci", }, | 561 | { .compatible = "ti,omap-ehci", }, |
562 | { .compatible = "ti,omap-ohci", }, | 562 | { .compatible = "ti,omap-ohci", }, |
563 | { } | 563 | { } |
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index b97a97187ae9..959513803542 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/regmap.h> | 26 | #include <linux/regmap.h> |
27 | #include <linux/of_platform.h> | 27 | #include <linux/of_platform.h> |
28 | #include <linux/mfd/core.h> | 28 | #include <linux/mfd/core.h> |
29 | #include <linux/mfd/pm8xxx/core.h> | ||
30 | 29 | ||
31 | #define SSBI_REG_ADDR_IRQ_BASE 0x1BB | 30 | #define SSBI_REG_ADDR_IRQ_BASE 0x1BB |
32 | 31 | ||
@@ -57,7 +56,6 @@ | |||
57 | #define PM8921_NR_IRQS 256 | 56 | #define PM8921_NR_IRQS 256 |
58 | 57 | ||
59 | struct pm_irq_chip { | 58 | struct pm_irq_chip { |
60 | struct device *dev; | ||
61 | struct regmap *regmap; | 59 | struct regmap *regmap; |
62 | spinlock_t pm_irq_lock; | 60 | spinlock_t pm_irq_lock; |
63 | struct irq_domain *irqdomain; | 61 | struct irq_domain *irqdomain; |
@@ -67,11 +65,6 @@ struct pm_irq_chip { | |||
67 | u8 config[0]; | 65 | u8 config[0]; |
68 | }; | 66 | }; |
69 | 67 | ||
70 | struct pm8921 { | ||
71 | struct device *dev; | ||
72 | struct pm_irq_chip *irq_chip; | ||
73 | }; | ||
74 | |||
75 | static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp, | 68 | static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp, |
76 | unsigned int *ip) | 69 | unsigned int *ip) |
77 | { | 70 | { |
@@ -255,55 +248,6 @@ static struct irq_chip pm8xxx_irq_chip = { | |||
255 | .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, | 248 | .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, |
256 | }; | 249 | }; |
257 | 250 | ||
258 | /** | ||
259 | * pm8xxx_get_irq_stat - get the status of the irq line | ||
260 | * @chip: pointer to identify a pmic irq controller | ||
261 | * @irq: the irq number | ||
262 | * | ||
263 | * The pm8xxx gpio and mpp rely on the interrupt block to read | ||
264 | * the values on their pins. This function is to facilitate reading | ||
265 | * the status of a gpio or an mpp line. The caller has to convert the | ||
266 | * gpio number to irq number. | ||
267 | * | ||
268 | * RETURNS: | ||
269 | * an int indicating the value read on that line | ||
270 | */ | ||
271 | static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) | ||
272 | { | ||
273 | int pmirq, rc; | ||
274 | unsigned int block, bits, bit; | ||
275 | unsigned long flags; | ||
276 | struct irq_data *irq_data = irq_get_irq_data(irq); | ||
277 | |||
278 | pmirq = irq_data->hwirq; | ||
279 | |||
280 | block = pmirq / 8; | ||
281 | bit = pmirq % 8; | ||
282 | |||
283 | spin_lock_irqsave(&chip->pm_irq_lock, flags); | ||
284 | |||
285 | rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block); | ||
286 | if (rc) { | ||
287 | pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n", | ||
288 | irq, pmirq, block, rc); | ||
289 | goto bail_out; | ||
290 | } | ||
291 | |||
292 | rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits); | ||
293 | if (rc) { | ||
294 | pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", | ||
295 | irq, pmirq, block, rc); | ||
296 | goto bail_out; | ||
297 | } | ||
298 | |||
299 | rc = (bits & (1 << bit)) ? 1 : 0; | ||
300 | |||
301 | bail_out: | ||
302 | spin_unlock_irqrestore(&chip->pm_irq_lock, flags); | ||
303 | |||
304 | return rc; | ||
305 | } | ||
306 | |||
307 | static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq, | 251 | static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq, |
308 | irq_hw_number_t hwirq) | 252 | irq_hw_number_t hwirq) |
309 | { | 253 | { |
@@ -324,56 +268,6 @@ static const struct irq_domain_ops pm8xxx_irq_domain_ops = { | |||
324 | .map = pm8xxx_irq_domain_map, | 268 | .map = pm8xxx_irq_domain_map, |
325 | }; | 269 | }; |
326 | 270 | ||
327 | static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) | ||
328 | { | ||
329 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); | ||
330 | const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; | ||
331 | |||
332 | return ssbi_read(pmic->dev->parent, addr, val, 1); | ||
333 | } | ||
334 | |||
335 | static int pm8921_writeb(const struct device *dev, u16 addr, u8 val) | ||
336 | { | ||
337 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); | ||
338 | const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; | ||
339 | |||
340 | return ssbi_write(pmic->dev->parent, addr, &val, 1); | ||
341 | } | ||
342 | |||
343 | static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf, | ||
344 | int cnt) | ||
345 | { | ||
346 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); | ||
347 | const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; | ||
348 | |||
349 | return ssbi_read(pmic->dev->parent, addr, buf, cnt); | ||
350 | } | ||
351 | |||
352 | static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, | ||
353 | int cnt) | ||
354 | { | ||
355 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); | ||
356 | const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; | ||
357 | |||
358 | return ssbi_write(pmic->dev->parent, addr, buf, cnt); | ||
359 | } | ||
360 | |||
361 | static int pm8921_read_irq_stat(const struct device *dev, int irq) | ||
362 | { | ||
363 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); | ||
364 | const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; | ||
365 | |||
366 | return pm8xxx_get_irq_stat(pmic->irq_chip, irq); | ||
367 | } | ||
368 | |||
369 | static struct pm8xxx_drvdata pm8921_drvdata = { | ||
370 | .pmic_readb = pm8921_readb, | ||
371 | .pmic_writeb = pm8921_writeb, | ||
372 | .pmic_read_buf = pm8921_read_buf, | ||
373 | .pmic_write_buf = pm8921_write_buf, | ||
374 | .pmic_read_irq_stat = pm8921_read_irq_stat, | ||
375 | }; | ||
376 | |||
377 | static const struct regmap_config ssbi_regmap_config = { | 271 | static const struct regmap_config ssbi_regmap_config = { |
378 | .reg_bits = 16, | 272 | .reg_bits = 16, |
379 | .val_bits = 8, | 273 | .val_bits = 8, |
@@ -392,7 +286,6 @@ MODULE_DEVICE_TABLE(of, pm8921_id_table); | |||
392 | 286 | ||
393 | static int pm8921_probe(struct platform_device *pdev) | 287 | static int pm8921_probe(struct platform_device *pdev) |
394 | { | 288 | { |
395 | struct pm8921 *pmic; | ||
396 | struct regmap *regmap; | 289 | struct regmap *regmap; |
397 | int irq, rc; | 290 | int irq, rc; |
398 | unsigned int val; | 291 | unsigned int val; |
@@ -404,12 +297,6 @@ static int pm8921_probe(struct platform_device *pdev) | |||
404 | if (irq < 0) | 297 | if (irq < 0) |
405 | return irq; | 298 | return irq; |
406 | 299 | ||
407 | pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL); | ||
408 | if (!pmic) { | ||
409 | pr_err("Cannot alloc pm8921 struct\n"); | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | |||
413 | regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent, | 300 | regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent, |
414 | &ssbi_regmap_config); | 301 | &ssbi_regmap_config); |
415 | if (IS_ERR(regmap)) | 302 | if (IS_ERR(regmap)) |
@@ -434,18 +321,13 @@ static int pm8921_probe(struct platform_device *pdev) | |||
434 | pr_info("PMIC revision 2: %02X\n", val); | 321 | pr_info("PMIC revision 2: %02X\n", val); |
435 | rev |= val << BITS_PER_BYTE; | 322 | rev |= val << BITS_PER_BYTE; |
436 | 323 | ||
437 | pmic->dev = &pdev->dev; | ||
438 | pm8921_drvdata.pm_chip_data = pmic; | ||
439 | platform_set_drvdata(pdev, &pm8921_drvdata); | ||
440 | |||
441 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip) + | 324 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip) + |
442 | sizeof(chip->config[0]) * nirqs, | 325 | sizeof(chip->config[0]) * nirqs, |
443 | GFP_KERNEL); | 326 | GFP_KERNEL); |
444 | if (!chip) | 327 | if (!chip) |
445 | return -ENOMEM; | 328 | return -ENOMEM; |
446 | 329 | ||
447 | pmic->irq_chip = chip; | 330 | platform_set_drvdata(pdev, chip); |
448 | chip->dev = &pdev->dev; | ||
449 | chip->regmap = regmap; | 331 | chip->regmap = regmap; |
450 | chip->num_irqs = nirqs; | 332 | chip->num_irqs = nirqs; |
451 | chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); | 333 | chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); |
@@ -481,8 +363,7 @@ static int pm8921_remove_child(struct device *dev, void *unused) | |||
481 | static int pm8921_remove(struct platform_device *pdev) | 363 | static int pm8921_remove(struct platform_device *pdev) |
482 | { | 364 | { |
483 | int irq = platform_get_irq(pdev, 0); | 365 | int irq = platform_get_irq(pdev, 0); |
484 | struct pm8921 *pmic = pm8921_drvdata.pm_chip_data; | 366 | struct pm_irq_chip *chip = platform_get_drvdata(pdev); |
485 | struct pm_irq_chip *chip = pmic->irq_chip; | ||
486 | 367 | ||
487 | device_for_each_child(&pdev->dev, NULL, pm8921_remove_child); | 368 | device_for_each_child(&pdev->dev, NULL, pm8921_remove_child); |
488 | irq_set_chained_handler(irq, NULL); | 369 | irq_set_chained_handler(irq, NULL); |
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index c79569750be9..6575585f1d1f 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -38,7 +38,7 @@ static struct resource rdc321x_wdt_resource[] = { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = { | 40 | static struct rdc321x_gpio_pdata rdc321x_gpio_pdata = { |
41 | .max_gpios = RDC321X_MAX_GPIO, | 41 | .max_gpios = RDC321X_NUM_GPIO, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static struct resource rdc321x_gpio_resources[] = { | 44 | static struct resource rdc321x_gpio_resources[] = { |
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c index b53b9d46cc45..6352bec8419a 100644 --- a/drivers/mfd/rtsx_usb.c +++ b/drivers/mfd/rtsx_usb.c | |||
@@ -29,7 +29,7 @@ static int polling_pipe = 1; | |||
29 | module_param(polling_pipe, int, S_IRUGO | S_IWUSR); | 29 | module_param(polling_pipe, int, S_IRUGO | S_IWUSR); |
30 | MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)"); | 30 | MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)"); |
31 | 31 | ||
32 | static struct mfd_cell rtsx_usb_cells[] = { | 32 | static const struct mfd_cell rtsx_usb_cells[] = { |
33 | [RTSX_USB_SD_CARD] = { | 33 | [RTSX_USB_SD_CARD] = { |
34 | .name = "rtsx_usb_sdmmc", | 34 | .name = "rtsx_usb_sdmmc", |
35 | .pdata_size = 0, | 35 | .pdata_size = 0, |
@@ -67,7 +67,7 @@ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr, | |||
67 | ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout); | 67 | ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout); |
68 | add_timer(&ucr->sg_timer); | 68 | add_timer(&ucr->sg_timer); |
69 | usb_sg_wait(&ucr->current_sg); | 69 | usb_sg_wait(&ucr->current_sg); |
70 | del_timer(&ucr->sg_timer); | 70 | del_timer_sync(&ucr->sg_timer); |
71 | 71 | ||
72 | if (act_len) | 72 | if (act_len) |
73 | *act_len = ucr->current_sg.bytes; | 73 | *act_len = ucr->current_sg.bytes; |
@@ -644,14 +644,14 @@ static int rtsx_usb_probe(struct usb_interface *intf, | |||
644 | if (ret) | 644 | if (ret) |
645 | goto out_init_fail; | 645 | goto out_init_fail; |
646 | 646 | ||
647 | /* initialize USB SG transfer timer */ | ||
648 | setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr); | ||
649 | |||
647 | ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells, | 650 | ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells, |
648 | ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL); | 651 | ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL); |
649 | if (ret) | 652 | if (ret) |
650 | goto out_init_fail; | 653 | goto out_init_fail; |
651 | 654 | ||
652 | /* initialize USB SG transfer timer */ | ||
653 | init_timer(&ucr->sg_timer); | ||
654 | setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr); | ||
655 | #ifdef CONFIG_PM | 655 | #ifdef CONFIG_PM |
656 | intf->needs_remote_wakeup = 1; | 656 | intf->needs_remote_wakeup = 1; |
657 | usb_enable_autosuspend(usb_dev); | 657 | usb_enable_autosuspend(usb_dev); |
@@ -687,9 +687,15 @@ static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) | |||
687 | dev_dbg(&intf->dev, "%s called with pm message 0x%04u\n", | 687 | dev_dbg(&intf->dev, "%s called with pm message 0x%04u\n", |
688 | __func__, message.event); | 688 | __func__, message.event); |
689 | 689 | ||
690 | /* | ||
691 | * Call to make sure LED is off during suspend to save more power. | ||
692 | * It is NOT a permanent state and could be turned on anytime later. | ||
693 | * Thus no need to call turn_on when resunming. | ||
694 | */ | ||
690 | mutex_lock(&ucr->dev_mutex); | 695 | mutex_lock(&ucr->dev_mutex); |
691 | rtsx_usb_turn_off_led(ucr); | 696 | rtsx_usb_turn_off_led(ucr); |
692 | mutex_unlock(&ucr->dev_mutex); | 697 | mutex_unlock(&ucr->dev_mutex); |
698 | |||
693 | return 0; | 699 | return 0; |
694 | } | 700 | } |
695 | 701 | ||
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 1cf27521fff4..be06d0abbf19 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/mfd/core.h> | 25 | #include <linux/mfd/core.h> |
26 | #include <linux/mfd/samsung/core.h> | 26 | #include <linux/mfd/samsung/core.h> |
27 | #include <linux/mfd/samsung/irq.h> | 27 | #include <linux/mfd/samsung/irq.h> |
28 | #include <linux/mfd/samsung/rtc.h> | ||
29 | #include <linux/mfd/samsung/s2mpa01.h> | 28 | #include <linux/mfd/samsung/s2mpa01.h> |
30 | #include <linux/mfd/samsung/s2mps11.h> | 29 | #include <linux/mfd/samsung/s2mps11.h> |
31 | #include <linux/mfd/samsung/s2mps14.h> | 30 | #include <linux/mfd/samsung/s2mps14.h> |
@@ -91,7 +90,7 @@ static const struct mfd_cell s2mpa01_devs[] = { | |||
91 | }; | 90 | }; |
92 | 91 | ||
93 | #ifdef CONFIG_OF | 92 | #ifdef CONFIG_OF |
94 | static struct of_device_id sec_dt_match[] = { | 93 | static const struct of_device_id sec_dt_match[] = { |
95 | { .compatible = "samsung,s5m8767-pmic", | 94 | { .compatible = "samsung,s5m8767-pmic", |
96 | .data = (void *)S5M8767X, | 95 | .data = (void *)S5M8767X, |
97 | }, { | 96 | }, { |
@@ -196,20 +195,6 @@ static const struct regmap_config s5m8767_regmap_config = { | |||
196 | .cache_type = REGCACHE_FLAT, | 195 | .cache_type = REGCACHE_FLAT, |
197 | }; | 196 | }; |
198 | 197 | ||
199 | static const struct regmap_config s5m_rtc_regmap_config = { | ||
200 | .reg_bits = 8, | ||
201 | .val_bits = 8, | ||
202 | |||
203 | .max_register = SEC_RTC_REG_MAX, | ||
204 | }; | ||
205 | |||
206 | static const struct regmap_config s2mps14_rtc_regmap_config = { | ||
207 | .reg_bits = 8, | ||
208 | .val_bits = 8, | ||
209 | |||
210 | .max_register = S2MPS_RTC_REG_MAX, | ||
211 | }; | ||
212 | |||
213 | #ifdef CONFIG_OF | 198 | #ifdef CONFIG_OF |
214 | /* | 199 | /* |
215 | * Only the common platform data elements for s5m8767 are parsed here from the | 200 | * Only the common platform data elements for s5m8767 are parsed here from the |
@@ -264,8 +249,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
264 | const struct i2c_device_id *id) | 249 | const struct i2c_device_id *id) |
265 | { | 250 | { |
266 | struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); | 251 | struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); |
267 | const struct regmap_config *regmap, *regmap_rtc; | 252 | const struct regmap_config *regmap; |
268 | struct sec_pmic_dev *sec_pmic; | 253 | struct sec_pmic_dev *sec_pmic; |
254 | unsigned long device_type; | ||
269 | int ret; | 255 | int ret; |
270 | 256 | ||
271 | sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), | 257 | sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), |
@@ -277,7 +263,7 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
277 | sec_pmic->dev = &i2c->dev; | 263 | sec_pmic->dev = &i2c->dev; |
278 | sec_pmic->i2c = i2c; | 264 | sec_pmic->i2c = i2c; |
279 | sec_pmic->irq = i2c->irq; | 265 | sec_pmic->irq = i2c->irq; |
280 | sec_pmic->type = sec_i2c_get_driver_data(i2c, id); | 266 | device_type = sec_i2c_get_driver_data(i2c, id); |
281 | 267 | ||
282 | if (sec_pmic->dev->of_node) { | 268 | if (sec_pmic->dev->of_node) { |
283 | pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); | 269 | pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); |
@@ -285,7 +271,7 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
285 | ret = PTR_ERR(pdata); | 271 | ret = PTR_ERR(pdata); |
286 | return ret; | 272 | return ret; |
287 | } | 273 | } |
288 | pdata->device_type = sec_pmic->type; | 274 | pdata->device_type = device_type; |
289 | } | 275 | } |
290 | if (pdata) { | 276 | if (pdata) { |
291 | sec_pmic->device_type = pdata->device_type; | 277 | sec_pmic->device_type = pdata->device_type; |
@@ -298,39 +284,21 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
298 | switch (sec_pmic->device_type) { | 284 | switch (sec_pmic->device_type) { |
299 | case S2MPA01: | 285 | case S2MPA01: |
300 | regmap = &s2mpa01_regmap_config; | 286 | regmap = &s2mpa01_regmap_config; |
301 | /* | ||
302 | * The rtc-s5m driver does not support S2MPA01 and there | ||
303 | * is no mfd_cell for S2MPA01 RTC device. | ||
304 | * However we must pass something to devm_regmap_init_i2c() | ||
305 | * so use S5M-like regmap config even though it wouldn't work. | ||
306 | */ | ||
307 | regmap_rtc = &s5m_rtc_regmap_config; | ||
308 | break; | 287 | break; |
309 | case S2MPS11X: | 288 | case S2MPS11X: |
310 | regmap = &s2mps11_regmap_config; | 289 | regmap = &s2mps11_regmap_config; |
311 | /* | ||
312 | * The rtc-s5m driver does not support S2MPS11 and there | ||
313 | * is no mfd_cell for S2MPS11 RTC device. | ||
314 | * However we must pass something to devm_regmap_init_i2c() | ||
315 | * so use S5M-like regmap config even though it wouldn't work. | ||
316 | */ | ||
317 | regmap_rtc = &s5m_rtc_regmap_config; | ||
318 | break; | 290 | break; |
319 | case S2MPS14X: | 291 | case S2MPS14X: |
320 | regmap = &s2mps14_regmap_config; | 292 | regmap = &s2mps14_regmap_config; |
321 | regmap_rtc = &s2mps14_rtc_regmap_config; | ||
322 | break; | 293 | break; |
323 | case S5M8763X: | 294 | case S5M8763X: |
324 | regmap = &s5m8763_regmap_config; | 295 | regmap = &s5m8763_regmap_config; |
325 | regmap_rtc = &s5m_rtc_regmap_config; | ||
326 | break; | 296 | break; |
327 | case S5M8767X: | 297 | case S5M8767X: |
328 | regmap = &s5m8767_regmap_config; | 298 | regmap = &s5m8767_regmap_config; |
329 | regmap_rtc = &s5m_rtc_regmap_config; | ||
330 | break; | 299 | break; |
331 | default: | 300 | default: |
332 | regmap = &sec_regmap_config; | 301 | regmap = &sec_regmap_config; |
333 | regmap_rtc = &s5m_rtc_regmap_config; | ||
334 | break; | 302 | break; |
335 | } | 303 | } |
336 | 304 | ||
@@ -342,21 +310,6 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
342 | return ret; | 310 | return ret; |
343 | } | 311 | } |
344 | 312 | ||
345 | sec_pmic->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); | ||
346 | if (!sec_pmic->rtc) { | ||
347 | dev_err(&i2c->dev, "Failed to allocate I2C for RTC\n"); | ||
348 | return -ENODEV; | ||
349 | } | ||
350 | i2c_set_clientdata(sec_pmic->rtc, sec_pmic); | ||
351 | |||
352 | sec_pmic->regmap_rtc = devm_regmap_init_i2c(sec_pmic->rtc, regmap_rtc); | ||
353 | if (IS_ERR(sec_pmic->regmap_rtc)) { | ||
354 | ret = PTR_ERR(sec_pmic->regmap_rtc); | ||
355 | dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n", | ||
356 | ret); | ||
357 | goto err_regmap_rtc; | ||
358 | } | ||
359 | |||
360 | if (pdata && pdata->cfg_pmic_irq) | 313 | if (pdata && pdata->cfg_pmic_irq) |
361 | pdata->cfg_pmic_irq(); | 314 | pdata->cfg_pmic_irq(); |
362 | 315 | ||
@@ -403,8 +356,6 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
403 | 356 | ||
404 | err_mfd: | 357 | err_mfd: |
405 | sec_irq_exit(sec_pmic); | 358 | sec_irq_exit(sec_pmic); |
406 | err_regmap_rtc: | ||
407 | i2c_unregister_device(sec_pmic->rtc); | ||
408 | return ret; | 359 | return ret; |
409 | } | 360 | } |
410 | 361 | ||
@@ -414,7 +365,6 @@ static int sec_pmic_remove(struct i2c_client *i2c) | |||
414 | 365 | ||
415 | mfd_remove_devices(sec_pmic->dev); | 366 | mfd_remove_devices(sec_pmic->dev); |
416 | sec_irq_exit(sec_pmic); | 367 | sec_irq_exit(sec_pmic); |
417 | i2c_unregister_device(sec_pmic->rtc); | ||
418 | return 0; | 368 | return 0; |
419 | } | 369 | } |
420 | 370 | ||
@@ -424,19 +374,18 @@ static int sec_pmic_suspend(struct device *dev) | |||
424 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 374 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
425 | struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); | 375 | struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); |
426 | 376 | ||
427 | if (device_may_wakeup(dev)) { | 377 | if (device_may_wakeup(dev)) |
428 | enable_irq_wake(sec_pmic->irq); | 378 | enable_irq_wake(sec_pmic->irq); |
429 | /* | 379 | /* |
430 | * PMIC IRQ must be disabled during suspend for RTC alarm | 380 | * PMIC IRQ must be disabled during suspend for RTC alarm |
431 | * to work properly. | 381 | * to work properly. |
432 | * When device is woken up from suspend by RTC Alarm, an | 382 | * When device is woken up from suspend, an |
433 | * interrupt occurs before resuming I2C bus controller. | 383 | * interrupt occurs before resuming I2C bus controller. |
434 | * The interrupt is handled by regmap_irq_thread which tries | 384 | * The interrupt is handled by regmap_irq_thread which tries |
435 | * to read RTC registers. This read fails (I2C is still | 385 | * to read RTC registers. This read fails (I2C is still |
436 | * suspended) and RTC Alarm interrupt is disabled. | 386 | * suspended) and RTC Alarm interrupt is disabled. |
437 | */ | 387 | */ |
438 | disable_irq(sec_pmic->irq); | 388 | disable_irq(sec_pmic->irq); |
439 | } | ||
440 | 389 | ||
441 | return 0; | 390 | return 0; |
442 | } | 391 | } |
@@ -446,10 +395,9 @@ static int sec_pmic_resume(struct device *dev) | |||
446 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 395 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
447 | struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); | 396 | struct sec_pmic_dev *sec_pmic = i2c_get_clientdata(i2c); |
448 | 397 | ||
449 | if (device_may_wakeup(dev)) { | 398 | if (device_may_wakeup(dev)) |
450 | disable_irq_wake(sec_pmic->irq); | 399 | disable_irq_wake(sec_pmic->irq); |
451 | enable_irq(sec_pmic->irq); | 400 | enable_irq(sec_pmic->irq); |
452 | } | ||
453 | 401 | ||
454 | return 0; | 402 | return 0; |
455 | } | 403 | } |
diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 64e7913aadc6..654e2c1dbf7a 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c | |||
@@ -385,7 +385,7 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) | |||
385 | &sec_pmic->irq_data); | 385 | &sec_pmic->irq_data); |
386 | break; | 386 | break; |
387 | default: | 387 | default: |
388 | dev_err(sec_pmic->dev, "Unknown device type %d\n", | 388 | dev_err(sec_pmic->dev, "Unknown device type %lu\n", |
389 | sec_pmic->device_type); | 389 | sec_pmic->device_type); |
390 | return -EINVAL; | 390 | return -EINVAL; |
391 | } | 391 | } |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index e7dc441a8f8a..81e6d0932bf0 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -1726,7 +1726,7 @@ static struct pci_driver sm501_pci_driver = { | |||
1726 | 1726 | ||
1727 | MODULE_ALIAS("platform:sm501"); | 1727 | MODULE_ALIAS("platform:sm501"); |
1728 | 1728 | ||
1729 | static struct of_device_id of_sm501_match_tbl[] = { | 1729 | static const struct of_device_id of_sm501_match_tbl[] = { |
1730 | { .compatible = "smi,sm501", }, | 1730 | { .compatible = "smi,sm501", }, |
1731 | { /* end */ } | 1731 | { /* end */ } |
1732 | }; | 1732 | }; |
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 0da02e11d58e..a45f9c0a330a 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/of_device.h> | ||
17 | #include "stmpe.h" | 18 | #include "stmpe.h" |
18 | 19 | ||
19 | static int i2c_reg_read(struct stmpe *stmpe, u8 reg) | 20 | static int i2c_reg_read(struct stmpe *stmpe, u8 reg) |
@@ -52,15 +53,41 @@ static struct stmpe_client_info i2c_ci = { | |||
52 | .write_block = i2c_block_write, | 53 | .write_block = i2c_block_write, |
53 | }; | 54 | }; |
54 | 55 | ||
56 | static const struct of_device_id stmpe_of_match[] = { | ||
57 | { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, | ||
58 | { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, | ||
59 | { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, | ||
60 | { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, | ||
61 | { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, | ||
62 | { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, }, | ||
63 | { .compatible = "st,stmpe2403", .data = (void *)STMPE2403, }, | ||
64 | {}, | ||
65 | }; | ||
66 | MODULE_DEVICE_TABLE(of, stmpe_of_match); | ||
67 | |||
55 | static int | 68 | static int |
56 | 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) |
57 | { | 70 | { |
71 | int partnum; | ||
72 | const struct of_device_id *of_id; | ||
73 | |||
58 | i2c_ci.data = (void *)id; | 74 | i2c_ci.data = (void *)id; |
59 | i2c_ci.irq = i2c->irq; | 75 | i2c_ci.irq = i2c->irq; |
60 | i2c_ci.client = i2c; | 76 | i2c_ci.client = i2c; |
61 | i2c_ci.dev = &i2c->dev; | 77 | i2c_ci.dev = &i2c->dev; |
62 | 78 | ||
63 | return stmpe_probe(&i2c_ci, id->driver_data); | 79 | of_id = of_match_device(stmpe_of_match, &i2c->dev); |
80 | if (!of_id) { | ||
81 | /* | ||
82 | * This happens when the I2C ID matches the node name | ||
83 | * but no real compatible string has been given. | ||
84 | */ | ||
85 | dev_info(&i2c->dev, "matching on node name, compatible is preferred\n"); | ||
86 | partnum = id->driver_data; | ||
87 | } else | ||
88 | partnum = (int)of_id->data; | ||
89 | |||
90 | return stmpe_probe(&i2c_ci, partnum); | ||
64 | } | 91 | } |
65 | 92 | ||
66 | static int stmpe_i2c_remove(struct i2c_client *i2c) | 93 | static int stmpe_i2c_remove(struct i2c_client *i2c) |
@@ -89,6 +116,7 @@ static struct i2c_driver stmpe_i2c_driver = { | |||
89 | #ifdef CONFIG_PM | 116 | #ifdef CONFIG_PM |
90 | .pm = &stmpe_dev_pm_ops, | 117 | .pm = &stmpe_dev_pm_ops, |
91 | #endif | 118 | #endif |
119 | .of_match_table = stmpe_of_match, | ||
92 | }, | 120 | }, |
93 | .probe = stmpe_i2c_probe, | 121 | .probe = stmpe_i2c_probe, |
94 | .remove = stmpe_i2c_remove, | 122 | .remove = stmpe_i2c_remove, |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 4a91f6771fb8..3b6bfa7184ad 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/mfd/core.h> | 21 | #include <linux/mfd/core.h> |
22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/regulator/consumer.h> | ||
23 | #include "stmpe.h" | 24 | #include "stmpe.h" |
24 | 25 | ||
25 | static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) | 26 | static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) |
@@ -605,9 +606,18 @@ static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, | |||
605 | 606 | ||
606 | if (blocks & STMPE_BLOCK_GPIO) | 607 | if (blocks & STMPE_BLOCK_GPIO) |
607 | mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO; | 608 | mask |= STMPE1601_SYS_CTRL_ENABLE_GPIO; |
609 | else | ||
610 | mask &= ~STMPE1601_SYS_CTRL_ENABLE_GPIO; | ||
608 | 611 | ||
609 | if (blocks & STMPE_BLOCK_KEYPAD) | 612 | if (blocks & STMPE_BLOCK_KEYPAD) |
610 | mask |= STMPE1601_SYS_CTRL_ENABLE_KPC; | 613 | mask |= STMPE1601_SYS_CTRL_ENABLE_KPC; |
614 | else | ||
615 | mask &= ~STMPE1601_SYS_CTRL_ENABLE_KPC; | ||
616 | |||
617 | if (blocks & STMPE_BLOCK_PWM) | ||
618 | mask |= STMPE1601_SYS_CTRL_ENABLE_SPWM; | ||
619 | else | ||
620 | mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM; | ||
611 | 621 | ||
612 | return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask, | 622 | return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask, |
613 | enable ? mask : 0); | 623 | enable ? mask : 0); |
@@ -986,9 +996,6 @@ static int stmpe_irq_init(struct stmpe *stmpe, struct device_node *np) | |||
986 | int base = 0; | 996 | int base = 0; |
987 | int num_irqs = stmpe->variant->num_irqs; | 997 | int num_irqs = stmpe->variant->num_irqs; |
988 | 998 | ||
989 | if (!np) | ||
990 | base = stmpe->irq_base; | ||
991 | |||
992 | stmpe->domain = irq_domain_add_simple(np, num_irqs, base, | 999 | stmpe->domain = irq_domain_add_simple(np, num_irqs, base, |
993 | &stmpe_irq_ops, stmpe); | 1000 | &stmpe_irq_ops, stmpe); |
994 | if (!stmpe->domain) { | 1001 | if (!stmpe->domain) { |
@@ -1067,7 +1074,7 @@ static int stmpe_chip_init(struct stmpe *stmpe) | |||
1067 | static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell) | 1074 | static int stmpe_add_device(struct stmpe *stmpe, const struct mfd_cell *cell) |
1068 | { | 1075 | { |
1069 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, | 1076 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, |
1070 | NULL, stmpe->irq_base, stmpe->domain); | 1077 | NULL, 0, stmpe->domain); |
1071 | } | 1078 | } |
1072 | 1079 | ||
1073 | static int stmpe_devices_init(struct stmpe *stmpe) | 1080 | static int stmpe_devices_init(struct stmpe *stmpe) |
@@ -1171,12 +1178,23 @@ int stmpe_probe(struct stmpe_client_info *ci, int partnum) | |||
1171 | stmpe->dev = ci->dev; | 1178 | stmpe->dev = ci->dev; |
1172 | stmpe->client = ci->client; | 1179 | stmpe->client = ci->client; |
1173 | stmpe->pdata = pdata; | 1180 | stmpe->pdata = pdata; |
1174 | stmpe->irq_base = pdata->irq_base; | ||
1175 | stmpe->ci = ci; | 1181 | stmpe->ci = ci; |
1176 | stmpe->partnum = partnum; | 1182 | stmpe->partnum = partnum; |
1177 | stmpe->variant = stmpe_variant_info[partnum]; | 1183 | stmpe->variant = stmpe_variant_info[partnum]; |
1178 | stmpe->regs = stmpe->variant->regs; | 1184 | stmpe->regs = stmpe->variant->regs; |
1179 | stmpe->num_gpios = stmpe->variant->num_gpios; | 1185 | stmpe->num_gpios = stmpe->variant->num_gpios; |
1186 | stmpe->vcc = devm_regulator_get_optional(ci->dev, "vcc"); | ||
1187 | if (!IS_ERR(stmpe->vcc)) { | ||
1188 | ret = regulator_enable(stmpe->vcc); | ||
1189 | if (ret) | ||
1190 | dev_warn(ci->dev, "failed to enable VCC supply\n"); | ||
1191 | } | ||
1192 | stmpe->vio = devm_regulator_get_optional(ci->dev, "vio"); | ||
1193 | if (!IS_ERR(stmpe->vio)) { | ||
1194 | ret = regulator_enable(stmpe->vio); | ||
1195 | if (ret) | ||
1196 | dev_warn(ci->dev, "failed to enable VIO supply\n"); | ||
1197 | } | ||
1180 | dev_set_drvdata(stmpe->dev, stmpe); | 1198 | dev_set_drvdata(stmpe->dev, stmpe); |
1181 | 1199 | ||
1182 | if (ci->init) | 1200 | if (ci->init) |
@@ -1243,6 +1261,11 @@ int stmpe_probe(struct stmpe_client_info *ci, int partnum) | |||
1243 | 1261 | ||
1244 | int stmpe_remove(struct stmpe *stmpe) | 1262 | int stmpe_remove(struct stmpe *stmpe) |
1245 | { | 1263 | { |
1264 | if (!IS_ERR(stmpe->vio)) | ||
1265 | regulator_disable(stmpe->vio); | ||
1266 | if (!IS_ERR(stmpe->vcc)) | ||
1267 | regulator_disable(stmpe->vcc); | ||
1268 | |||
1246 | mfd_remove_devices(stmpe->dev); | 1269 | mfd_remove_devices(stmpe->dev); |
1247 | 1270 | ||
1248 | return 0; | 1271 | return 0; |
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index 6639f1b0fef5..9e4d21d37a11 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h | |||
@@ -192,7 +192,7 @@ int stmpe_remove(struct stmpe *stmpe); | |||
192 | 192 | ||
193 | #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) | 193 | #define STMPE1601_SYS_CTRL_ENABLE_GPIO (1 << 3) |
194 | #define STMPE1601_SYS_CTRL_ENABLE_KPC (1 << 1) | 194 | #define STMPE1601_SYS_CTRL_ENABLE_KPC (1 << 1) |
195 | #define STMPE1601_SYSCON_ENABLE_SPWM (1 << 0) | 195 | #define STMPE1601_SYS_CTRL_ENABLE_SPWM (1 << 0) |
196 | 196 | ||
197 | /* The 1601/2403 share the same masks */ | 197 | /* The 1601/2403 share the same masks */ |
198 | #define STMPE1601_AUTOSLEEP_TIMEOUT_MASK (0x7) | 198 | #define STMPE1601_AUTOSLEEP_TIMEOUT_MASK (0x7) |
diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c new file mode 100644 index 000000000000..718fc4d2adc0 --- /dev/null +++ b/drivers/mfd/sun6i-prcm.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Free Electrons | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * Author: Boris BREZILLON <boris.brezillon@free-electrons.com> | ||
6 | * | ||
7 | * Allwinner PRCM (Power/Reset/Clock Management) driver | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/mfd/core.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/of.h> | ||
14 | |||
15 | struct prcm_data { | ||
16 | int nsubdevs; | ||
17 | const struct mfd_cell *subdevs; | ||
18 | }; | ||
19 | |||
20 | static const struct resource sun6i_a31_ar100_clk_res[] = { | ||
21 | { | ||
22 | .start = 0x0, | ||
23 | .end = 0x3, | ||
24 | .flags = IORESOURCE_MEM, | ||
25 | }, | ||
26 | }; | ||
27 | |||
28 | static const struct resource sun6i_a31_apb0_clk_res[] = { | ||
29 | { | ||
30 | .start = 0xc, | ||
31 | .end = 0xf, | ||
32 | .flags = IORESOURCE_MEM, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static const struct resource sun6i_a31_apb0_gates_clk_res[] = { | ||
37 | { | ||
38 | .start = 0x28, | ||
39 | .end = 0x2b, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | static const struct resource sun6i_a31_apb0_rstc_res[] = { | ||
45 | { | ||
46 | .start = 0xb0, | ||
47 | .end = 0xb3, | ||
48 | .flags = IORESOURCE_MEM, | ||
49 | }, | ||
50 | }; | ||
51 | |||
52 | static const struct mfd_cell sun6i_a31_prcm_subdevs[] = { | ||
53 | { | ||
54 | .name = "sun6i-a31-ar100-clk", | ||
55 | .of_compatible = "allwinner,sun6i-a31-ar100-clk", | ||
56 | .num_resources = ARRAY_SIZE(sun6i_a31_ar100_clk_res), | ||
57 | .resources = sun6i_a31_ar100_clk_res, | ||
58 | }, | ||
59 | { | ||
60 | .name = "sun6i-a31-apb0-clk", | ||
61 | .of_compatible = "allwinner,sun6i-a31-apb0-clk", | ||
62 | .num_resources = ARRAY_SIZE(sun6i_a31_apb0_clk_res), | ||
63 | .resources = sun6i_a31_apb0_clk_res, | ||
64 | }, | ||
65 | { | ||
66 | .name = "sun6i-a31-apb0-gates-clk", | ||
67 | .of_compatible = "allwinner,sun6i-a31-apb0-gates-clk", | ||
68 | .num_resources = ARRAY_SIZE(sun6i_a31_apb0_gates_clk_res), | ||
69 | .resources = sun6i_a31_apb0_gates_clk_res, | ||
70 | }, | ||
71 | { | ||
72 | .name = "sun6i-a31-apb0-clock-reset", | ||
73 | .of_compatible = "allwinner,sun6i-a31-clock-reset", | ||
74 | .num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res), | ||
75 | .resources = sun6i_a31_apb0_rstc_res, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static const struct prcm_data sun6i_a31_prcm_data = { | ||
80 | .nsubdevs = ARRAY_SIZE(sun6i_a31_prcm_subdevs), | ||
81 | .subdevs = sun6i_a31_prcm_subdevs, | ||
82 | }; | ||
83 | |||
84 | static const struct of_device_id sun6i_prcm_dt_ids[] = { | ||
85 | { | ||
86 | .compatible = "allwinner,sun6i-a31-prcm", | ||
87 | .data = &sun6i_a31_prcm_data, | ||
88 | }, | ||
89 | { /* sentinel */ }, | ||
90 | }; | ||
91 | |||
92 | static int sun6i_prcm_probe(struct platform_device *pdev) | ||
93 | { | ||
94 | struct device_node *np = pdev->dev.of_node; | ||
95 | const struct of_device_id *match; | ||
96 | const struct prcm_data *data; | ||
97 | struct resource *res; | ||
98 | int ret; | ||
99 | |||
100 | match = of_match_node(sun6i_prcm_dt_ids, np); | ||
101 | if (!match) | ||
102 | return -EINVAL; | ||
103 | |||
104 | data = match->data; | ||
105 | |||
106 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
107 | if (!res) { | ||
108 | dev_err(&pdev->dev, "no prcm memory region provided\n"); | ||
109 | return -ENOENT; | ||
110 | } | ||
111 | |||
112 | ret = mfd_add_devices(&pdev->dev, 0, data->subdevs, data->nsubdevs, | ||
113 | res, -1, NULL); | ||
114 | if (ret) { | ||
115 | dev_err(&pdev->dev, "failed to add subdevices\n"); | ||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static struct platform_driver sun6i_prcm_driver = { | ||
123 | .driver = { | ||
124 | .name = "sun6i-prcm", | ||
125 | .owner = THIS_MODULE, | ||
126 | .of_match_table = sun6i_prcm_dt_ids, | ||
127 | }, | ||
128 | .probe = sun6i_prcm_probe, | ||
129 | }; | ||
130 | module_platform_driver(sun6i_prcm_driver); | ||
131 | |||
132 | MODULE_AUTHOR("Boris BREZILLON <boris.brezillon@free-electrons.com>"); | ||
133 | MODULE_DESCRIPTION("Allwinner sun6i PRCM driver"); | ||
134 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index e2a04bb8bc1e..ca15878ce5c0 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c | |||
@@ -95,7 +95,11 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np, | |||
95 | struct device_node *syscon_np; | 95 | struct device_node *syscon_np; |
96 | struct regmap *regmap; | 96 | struct regmap *regmap; |
97 | 97 | ||
98 | syscon_np = of_parse_phandle(np, property, 0); | 98 | if (property) |
99 | syscon_np = of_parse_phandle(np, property, 0); | ||
100 | else | ||
101 | syscon_np = np; | ||
102 | |||
99 | if (!syscon_np) | 103 | if (!syscon_np) |
100 | return ERR_PTR(-ENODEV); | 104 | return ERR_PTR(-ENODEV); |
101 | 105 | ||
diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 3b27482a174f..a2e1990c9de7 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c | |||
@@ -119,7 +119,7 @@ static const struct i2c_device_id tps6507x_i2c_id[] = { | |||
119 | MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); | 119 | MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); |
120 | 120 | ||
121 | #ifdef CONFIG_OF | 121 | #ifdef CONFIG_OF |
122 | static struct of_device_id tps6507x_of_match[] = { | 122 | static const struct of_device_id tps6507x_of_match[] = { |
123 | {.compatible = "ti,tps6507x", }, | 123 | {.compatible = "ti,tps6507x", }, |
124 | {}, | 124 | {}, |
125 | }; | 125 | }; |
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index a74bfb59f18f..0d256cb002eb 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c | |||
@@ -197,6 +197,7 @@ static struct regmap_irq_chip tps65218_irq_chip = { | |||
197 | 197 | ||
198 | static const struct of_device_id of_tps65218_match_table[] = { | 198 | static const struct of_device_id of_tps65218_match_table[] = { |
199 | { .compatible = "ti,tps65218", }, | 199 | { .compatible = "ti,tps65218", }, |
200 | {} | ||
200 | }; | 201 | }; |
201 | 202 | ||
202 | static int tps65218_probe(struct i2c_client *client, | 203 | static int tps65218_probe(struct i2c_client *client, |
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 835e5549ecdd..8e1dbc469580 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -444,7 +444,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien | |||
444 | return pdata; | 444 | return pdata; |
445 | } | 445 | } |
446 | 446 | ||
447 | static struct of_device_id tps6586x_of_match[] = { | 447 | static const struct of_device_id tps6586x_of_match[] = { |
448 | { .compatible = "ti,tps6586x", }, | 448 | { .compatible = "ti,tps6586x", }, |
449 | { }, | 449 | { }, |
450 | }; | 450 | }; |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 460a014ca629..f9e42ea1cb1a 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -379,7 +379,7 @@ err_sleep_init: | |||
379 | } | 379 | } |
380 | 380 | ||
381 | #ifdef CONFIG_OF | 381 | #ifdef CONFIG_OF |
382 | static struct of_device_id tps65910_of_match[] = { | 382 | static const struct of_device_id tps65910_of_match[] = { |
383 | { .compatible = "ti,tps65910", .data = (void *)TPS65910}, | 383 | { .compatible = "ti,tps65910", .data = (void *)TPS65910}, |
384 | { .compatible = "ti,tps65911", .data = (void *)TPS65911}, | 384 | { .compatible = "ti,tps65911", .data = (void *)TPS65911}, |
385 | { }, | 385 | { }, |
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index 6e88f25832fb..ae26d84b3a59 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c | |||
@@ -87,8 +87,13 @@ static struct reg_default twl6040_defaults[] = { | |||
87 | }; | 87 | }; |
88 | 88 | ||
89 | static struct reg_default twl6040_patch[] = { | 89 | static struct reg_default twl6040_patch[] = { |
90 | /* Select I2C bus access to dual access registers */ | 90 | /* |
91 | { TWL6040_REG_ACCCTL, 0x09 }, | 91 | * Select I2C bus access to dual access registers |
92 | * Interrupt register is cleared on read | ||
93 | * Select fast mode for i2c (400KHz) | ||
94 | */ | ||
95 | { TWL6040_REG_ACCCTL, | ||
96 | TWL6040_I2CSEL | TWL6040_INTCLRMODE | TWL6040_I2CMODE(1) }, | ||
92 | }; | 97 | }; |
93 | 98 | ||
94 | 99 | ||
@@ -286,6 +291,8 @@ int twl6040_power(struct twl6040 *twl6040, int on) | |||
286 | if (twl6040->power_count++) | 291 | if (twl6040->power_count++) |
287 | goto out; | 292 | goto out; |
288 | 293 | ||
294 | clk_prepare_enable(twl6040->clk32k); | ||
295 | |||
289 | /* Allow writes to the chip */ | 296 | /* Allow writes to the chip */ |
290 | regcache_cache_only(twl6040->regmap, false); | 297 | regcache_cache_only(twl6040->regmap, false); |
291 | 298 | ||
@@ -341,6 +348,8 @@ int twl6040_power(struct twl6040 *twl6040, int on) | |||
341 | 348 | ||
342 | twl6040->sysclk = 0; | 349 | twl6040->sysclk = 0; |
343 | twl6040->mclk = 0; | 350 | twl6040->mclk = 0; |
351 | |||
352 | clk_disable_unprepare(twl6040->clk32k); | ||
344 | } | 353 | } |
345 | 354 | ||
346 | out: | 355 | out: |
@@ -432,12 +441,9 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
432 | TWL6040_HPLLENA; | 441 | TWL6040_HPLLENA; |
433 | break; | 442 | break; |
434 | case 19200000: | 443 | case 19200000: |
435 | /* | 444 | /* PLL enabled, bypass mode */ |
436 | * PLL disabled | 445 | hppllctl |= TWL6040_MCLK_19200KHZ | |
437 | * (enable PLL if MCLK jitter quality | 446 | TWL6040_HPLLBP | TWL6040_HPLLENA; |
438 | * doesn't meet specification) | ||
439 | */ | ||
440 | hppllctl |= TWL6040_MCLK_19200KHZ; | ||
441 | break; | 447 | break; |
442 | case 26000000: | 448 | case 26000000: |
443 | /* PLL enabled, active mode */ | 449 | /* PLL enabled, active mode */ |
@@ -445,9 +451,9 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
445 | TWL6040_HPLLENA; | 451 | TWL6040_HPLLENA; |
446 | break; | 452 | break; |
447 | case 38400000: | 453 | case 38400000: |
448 | /* PLL enabled, active mode */ | 454 | /* PLL enabled, bypass mode */ |
449 | hppllctl |= TWL6040_MCLK_38400KHZ | | 455 | hppllctl |= TWL6040_MCLK_38400KHZ | |
450 | TWL6040_HPLLENA; | 456 | TWL6040_HPLLBP | TWL6040_HPLLENA; |
451 | break; | 457 | break; |
452 | default: | 458 | default: |
453 | dev_err(twl6040->dev, | 459 | dev_err(twl6040->dev, |
@@ -639,6 +645,12 @@ static int twl6040_probe(struct i2c_client *client, | |||
639 | 645 | ||
640 | i2c_set_clientdata(client, twl6040); | 646 | i2c_set_clientdata(client, twl6040); |
641 | 647 | ||
648 | twl6040->clk32k = devm_clk_get(&client->dev, "clk32k"); | ||
649 | if (IS_ERR(twl6040->clk32k)) { | ||
650 | dev_info(&client->dev, "clk32k is not handled\n"); | ||
651 | twl6040->clk32k = NULL; | ||
652 | } | ||
653 | |||
642 | twl6040->supplies[0].supply = "vio"; | 654 | twl6040->supplies[0].supply = "vio"; |
643 | twl6040->supplies[1].supply = "v2v1"; | 655 | twl6040->supplies[1].supply = "v2v1"; |
644 | ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, | 656 | ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, |
@@ -660,6 +672,9 @@ static int twl6040_probe(struct i2c_client *client, | |||
660 | mutex_init(&twl6040->mutex); | 672 | mutex_init(&twl6040->mutex); |
661 | init_completion(&twl6040->ready); | 673 | init_completion(&twl6040->ready); |
662 | 674 | ||
675 | regmap_register_patch(twl6040->regmap, twl6040_patch, | ||
676 | ARRAY_SIZE(twl6040_patch)); | ||
677 | |||
663 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); | 678 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); |
664 | if (twl6040->rev < 0) { | 679 | if (twl6040->rev < 0) { |
665 | dev_err(&client->dev, "Failed to read revision register: %d\n", | 680 | dev_err(&client->dev, "Failed to read revision register: %d\n", |
@@ -679,6 +694,9 @@ static int twl6040_probe(struct i2c_client *client, | |||
679 | GPIOF_OUT_INIT_LOW, "audpwron"); | 694 | GPIOF_OUT_INIT_LOW, "audpwron"); |
680 | if (ret) | 695 | if (ret) |
681 | goto gpio_err; | 696 | goto gpio_err; |
697 | |||
698 | /* Clear any pending interrupt */ | ||
699 | twl6040_reg_read(twl6040, TWL6040_REG_INTID); | ||
682 | } | 700 | } |
683 | 701 | ||
684 | ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, | 702 | ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, |
@@ -707,10 +725,6 @@ static int twl6040_probe(struct i2c_client *client, | |||
707 | goto readyirq_err; | 725 | goto readyirq_err; |
708 | } | 726 | } |
709 | 727 | ||
710 | /* dual-access registers controlled by I2C only */ | ||
711 | regmap_register_patch(twl6040->regmap, twl6040_patch, | ||
712 | ARRAY_SIZE(twl6040_patch)); | ||
713 | |||
714 | /* | 728 | /* |
715 | * The main functionality of twl6040 to provide audio on OMAP4+ systems. | 729 | * The main functionality of twl6040 to provide audio on OMAP4+ systems. |
716 | * We can add the ASoC codec child whenever this driver has been loaded. | 730 | * We can add the ASoC codec child whenever this driver has been loaded. |
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index 070f8cfbbd7a..c8a993bd17ae 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
@@ -333,7 +333,7 @@ static const struct reg_default wm5102_reg_default[] = { | |||
333 | { 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */ | 333 | { 0x000001AA, 0x0004 }, /* R426 - FLL2 GPIO Clock */ |
334 | { 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */ | 334 | { 0x00000200, 0x0006 }, /* R512 - Mic Charge Pump 1 */ |
335 | { 0x00000210, 0x00D4 }, /* R528 - LDO1 Control 1 */ | 335 | { 0x00000210, 0x00D4 }, /* R528 - LDO1 Control 1 */ |
336 | { 0x00000212, 0x0001 }, /* R530 - LDO1 Control 2 */ | 336 | { 0x00000212, 0x0000 }, /* R530 - LDO1 Control 2 */ |
337 | { 0x00000213, 0x0344 }, /* R531 - LDO2 Control 1 */ | 337 | { 0x00000213, 0x0344 }, /* R531 - LDO2 Control 1 */ |
338 | { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ | 338 | { 0x00000218, 0x01A6 }, /* R536 - Mic Bias Ctrl 1 */ |
339 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ | 339 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ |
@@ -1037,6 +1037,8 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
1037 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4: | 1037 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4: |
1038 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_5: | 1038 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_5: |
1039 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_6: | 1039 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_6: |
1040 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_7: | ||
1041 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_8: | ||
1040 | case ARIZONA_COMFORT_NOISE_GENERATOR: | 1042 | case ARIZONA_COMFORT_NOISE_GENERATOR: |
1041 | case ARIZONA_HAPTICS_CONTROL_1: | 1043 | case ARIZONA_HAPTICS_CONTROL_1: |
1042 | case ARIZONA_HAPTICS_CONTROL_2: | 1044 | case ARIZONA_HAPTICS_CONTROL_2: |
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index 1942b6f231da..41a7f6fb7802 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c | |||
@@ -468,10 +468,12 @@ static const struct reg_default wm5110_reg_default[] = { | |||
468 | { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ | 468 | { 0x00000062, 0x01FF }, /* R98 - Sample Rate Sequence Select 2 */ |
469 | { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ | 469 | { 0x00000063, 0x01FF }, /* R99 - Sample Rate Sequence Select 3 */ |
470 | { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ | 470 | { 0x00000064, 0x01FF }, /* R100 - Sample Rate Sequence Select 4 */ |
471 | { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 1 */ | 471 | { 0x00000066, 0x01FF }, /* R102 - Always On Triggers Sequence Select 1 */ |
472 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 2 */ | 472 | { 0x00000067, 0x01FF }, /* R103 - Always On Triggers Sequence Select 2 */ |
473 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 3 */ | 473 | { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 3 */ |
474 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 4 */ | 474 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */ |
475 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */ | ||
476 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 6 */ | ||
475 | { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ | 477 | { 0x00000070, 0x0000 }, /* R112 - Comfort Noise Generator */ |
476 | { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ | 478 | { 0x00000090, 0x0000 }, /* R144 - Haptics Control 1 */ |
477 | { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ | 479 | { 0x00000091, 0x7FFF }, /* R145 - Haptics Control 2 */ |
@@ -549,6 +551,7 @@ static const struct reg_default wm5110_reg_default[] = { | |||
549 | { 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */ | 551 | { 0x000002A8, 0x1422 }, /* R680 - Mic Detect Level 3 */ |
550 | { 0x000002A9, 0x300A }, /* R681 - Mic Detect Level 4 */ | 552 | { 0x000002A9, 0x300A }, /* R681 - Mic Detect Level 4 */ |
551 | { 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */ | 553 | { 0x000002C3, 0x0000 }, /* R707 - Mic noise mix control 1 */ |
554 | { 0x000002CB, 0x0000 }, /* R715 - Isolation control */ | ||
552 | { 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */ | 555 | { 0x000002D3, 0x0000 }, /* R723 - Jack detect analogue */ |
553 | { 0x00000300, 0x0000 }, /* R768 - Input Enables */ | 556 | { 0x00000300, 0x0000 }, /* R768 - Input Enables */ |
554 | { 0x00000308, 0x0000 }, /* R776 - Input Rate */ | 557 | { 0x00000308, 0x0000 }, /* R776 - Input Rate */ |
@@ -1498,6 +1501,8 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
1498 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2: | 1501 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2: |
1499 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_3: | 1502 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_3: |
1500 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4: | 1503 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4: |
1504 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_5: | ||
1505 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_6: | ||
1501 | case ARIZONA_COMFORT_NOISE_GENERATOR: | 1506 | case ARIZONA_COMFORT_NOISE_GENERATOR: |
1502 | case ARIZONA_HAPTICS_CONTROL_1: | 1507 | case ARIZONA_HAPTICS_CONTROL_1: |
1503 | case ARIZONA_HAPTICS_CONTROL_2: | 1508 | case ARIZONA_HAPTICS_CONTROL_2: |
@@ -1580,6 +1585,7 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
1580 | case ARIZONA_MIC_DETECT_LEVEL_3: | 1585 | case ARIZONA_MIC_DETECT_LEVEL_3: |
1581 | case ARIZONA_MIC_DETECT_LEVEL_4: | 1586 | case ARIZONA_MIC_DETECT_LEVEL_4: |
1582 | case ARIZONA_MIC_NOISE_MIX_CONTROL_1: | 1587 | case ARIZONA_MIC_NOISE_MIX_CONTROL_1: |
1588 | case ARIZONA_ISOLATION_CONTROL: | ||
1583 | case ARIZONA_JACK_DETECT_ANALOGUE: | 1589 | case ARIZONA_JACK_DETECT_ANALOGUE: |
1584 | case ARIZONA_INPUT_ENABLES: | 1590 | case ARIZONA_INPUT_ENABLES: |
1585 | case ARIZONA_INPUT_ENABLES_STATUS: | 1591 | case ARIZONA_INPUT_ENABLES_STATUS: |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index e5eae751aa1b..c6fb5d16ca09 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -64,7 +64,7 @@ EXPORT_SYMBOL_GPL(wm8400_block_read); | |||
64 | 64 | ||
65 | static int wm8400_register_codec(struct wm8400 *wm8400) | 65 | static int wm8400_register_codec(struct wm8400 *wm8400) |
66 | { | 66 | { |
67 | struct mfd_cell cell = { | 67 | const struct mfd_cell cell = { |
68 | .name = "wm8400-codec", | 68 | .name = "wm8400-codec", |
69 | .platform_data = wm8400, | 69 | .platform_data = wm8400, |
70 | .pdata_size = sizeof(*wm8400), | 70 | .pdata_size = sizeof(*wm8400), |
diff --git a/drivers/mfd/wm8997-tables.c b/drivers/mfd/wm8997-tables.c index 5aa807687777..c7a81da64ee1 100644 --- a/drivers/mfd/wm8997-tables.c +++ b/drivers/mfd/wm8997-tables.c | |||
@@ -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 1 */ | 177 | { 0x00000068, 0x01FF }, /* R104 - Always On Triggers Sequence Select 3 */ |
178 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 2 */ | 178 | { 0x00000069, 0x01FF }, /* R105 - Always On Triggers Sequence Select 4 */ |
179 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 3 */ | 179 | { 0x0000006A, 0x01FF }, /* R106 - Always On Triggers Sequence Select 5 */ |
180 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence Select 4 */ | 180 | { 0x0000006B, 0x01FF }, /* R107 - Always On Triggers Sequence 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 */ |
@@ -814,10 +814,10 @@ static bool wm8997_readable_register(struct device *dev, unsigned int reg) | |||
814 | case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_2: | 814 | case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_2: |
815 | case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_3: | 815 | case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_3: |
816 | case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_4: | 816 | case ARIZONA_SAMPLE_RATE_SEQUENCE_SELECT_4: |
817 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_1: | ||
818 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_2: | ||
819 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_3: | 817 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_3: |
820 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4: | 818 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_4: |
819 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_5: | ||
820 | case ARIZONA_ALWAYS_ON_TRIGGERS_SEQUENCE_SELECT_6: | ||
821 | case ARIZONA_COMFORT_NOISE_GENERATOR: | 821 | case ARIZONA_COMFORT_NOISE_GENERATOR: |
822 | case ARIZONA_HAPTICS_CONTROL_1: | 822 | case ARIZONA_HAPTICS_CONTROL_1: |
823 | case ARIZONA_HAPTICS_CONTROL_2: | 823 | case ARIZONA_HAPTICS_CONTROL_2: |
@@ -846,6 +846,7 @@ static bool wm8997_readable_register(struct device *dev, unsigned int reg) | |||
846 | case ARIZONA_RATE_ESTIMATOR_3: | 846 | case ARIZONA_RATE_ESTIMATOR_3: |
847 | case ARIZONA_RATE_ESTIMATOR_4: | 847 | case ARIZONA_RATE_ESTIMATOR_4: |
848 | case ARIZONA_RATE_ESTIMATOR_5: | 848 | case ARIZONA_RATE_ESTIMATOR_5: |
849 | case ARIZONA_DYNAMIC_FREQUENCY_SCALING_1: | ||
849 | case ARIZONA_FLL1_CONTROL_1: | 850 | case ARIZONA_FLL1_CONTROL_1: |
850 | case ARIZONA_FLL1_CONTROL_2: | 851 | case ARIZONA_FLL1_CONTROL_2: |
851 | case ARIZONA_FLL1_CONTROL_3: | 852 | case ARIZONA_FLL1_CONTROL_3: |
@@ -880,6 +881,7 @@ static bool wm8997_readable_register(struct device *dev, unsigned int reg) | |||
880 | case ARIZONA_FLL2_GPIO_CLOCK: | 881 | case ARIZONA_FLL2_GPIO_CLOCK: |
881 | case ARIZONA_MIC_CHARGE_PUMP_1: | 882 | case ARIZONA_MIC_CHARGE_PUMP_1: |
882 | case ARIZONA_LDO1_CONTROL_1: | 883 | case ARIZONA_LDO1_CONTROL_1: |
884 | case ARIZONA_LDO1_CONTROL_2: | ||
883 | case ARIZONA_LDO2_CONTROL_1: | 885 | case ARIZONA_LDO2_CONTROL_1: |
884 | case ARIZONA_MIC_BIAS_CTRL_1: | 886 | case ARIZONA_MIC_BIAS_CTRL_1: |
885 | case ARIZONA_MIC_BIAS_CTRL_2: | 887 | case ARIZONA_MIC_BIAS_CTRL_2: |