aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 12:23:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 12:23:24 -0400
commit9bc747bea5fad819e0c0ad96e6a67ea0640dfe2b (patch)
treed500225e7a1c90a6bd17d3e63e2f6e781810db2b /drivers
parent32b908eea9e5ecd1049008e134eadbfcd0da5e38 (diff)
parent0e896b1ddc1905df904df98c204bacf028219729 (diff)
Merge tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull first batch of arm-soc cleanups from Olof Johansson: "These cleanups are basically all over the place. The idea is to collect changes with minimal impact but large number of changes so we can avoid them from distracting in the diffstat in the other series. A significant number of lines get removed here, in particular because the ixp2000 and ixp23xx platforms get removed. These have never been extremely popular and have fallen into disuse over time with no active maintainer taking care of them. The u5500 soc never made it into a product, so we are removing it from the ux500 platform. Many good cleanups also went into the at91 and omap platforms, as has been the case for a number of releases." Trivial modify-delete conflicts in arch/arm/mach-{ixp2000,ixp23xx} * tag 'cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (152 commits) ARM: clps711x: Cleanup IRQ handling ARM clps711x: Removed unused header mach/time.h ARM: clps711x: Added note about support EP731x CPU to Kconfig ARM: clps711x: Added missing register definitions ARM: clps711x: Used own subarch directory for store header file Dove: Fix Section mismatch warnings ARM: orion5x: ts78xx debugging changes ARM: orion5x: remove PM dependency from ts78xx ARM: orion5x: ts78xx fix NAND resource off by one ARM: orion5x: ts78xx whitespace cleanups Orion5x: Fix Section mismatch warnings Orion5x: Fix warning: struct pci_dev declared inside paramter list ARM: clps711x: Combine header files into one for clps711x-targets ARM: S3C24XX: Use common macro to define resources on mach-qt2410.c ARM: S3C24XX: Use common macro to define resources on mach-osiris.c ARM: EXYNOS: Adapt to cpuidle core time keeping and irq enable ARM: S5PV210: Use common macro to define resources on mach-smdkv210.c ARM: S5PV210: Use common macro to define resources on dev-audio.c ARM: S5PC100: Use common macro to define resources on dev-audio.c ARM: S5P64X0: Use common macro to define resources on dev-audio.c ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/hw_random/Kconfig2
-rw-r--r--drivers/clocksource/Kconfig2
-rw-r--r--drivers/input/touchscreen/Kconfig4
-rw-r--r--drivers/mfd/Kconfig27
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/ab5500-core.c1439
-rw-r--r--drivers/mfd/ab5500-debugfs.c807
-rw-r--r--drivers/mfd/ab5500-debugfs.h22
-rw-r--r--drivers/mfd/db5500-prcmu.c451
-rw-r--r--drivers/mtd/nand/autcpu12.c10
-rw-r--r--drivers/mtd/nand/h1910.c2
-rw-r--r--drivers/net/irda/Kconfig4
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/tty/serial/clps711x.c1
-rw-r--r--drivers/usb/host/ohci-omap.c5
-rw-r--r--drivers/video/clps711xfb.c1
-rw-r--r--drivers/video/omap2/displays/Kconfig8
-rw-r--r--drivers/video/omap2/displays/Makefile2
-rw-r--r--drivers/video/omap2/displays/panel-taal.c22
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c (renamed from drivers/video/omap2/displays/panel-dvi.c)134
-rw-r--r--drivers/video/omap2/dss/dsi.c133
21 files changed, 186 insertions, 2895 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 0689bf6b0183..b2402eb076c7 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -62,7 +62,7 @@ config HW_RANDOM_AMD
62 62
63config HW_RANDOM_ATMEL 63config HW_RANDOM_ATMEL
64 tristate "Atmel Random Number Generator support" 64 tristate "Atmel Random Number Generator support"
65 depends on HW_RANDOM && ARCH_AT91SAM9G45 65 depends on HW_RANDOM && HAVE_CLK
66 default HW_RANDOM 66 default HW_RANDOM
67 ---help--- 67 ---help---
68 This driver provides kernel-side support for the Random Number 68 This driver provides kernel-side support for the Random Number
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 5138927a416c..99c6b203e6cd 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -18,7 +18,7 @@ config DW_APB_TIMER
18 18
19config CLKSRC_DBX500_PRCMU 19config CLKSRC_DBX500_PRCMU
20 bool "Clocksource PRCMU Timer" 20 bool "Clocksource PRCMU Timer"
21 depends on UX500_SOC_DB5500 || UX500_SOC_DB8500 21 depends on UX500_SOC_DB8500
22 default y 22 default y
23 help 23 help
24 Use the always on PRCMU Timer as clocksource 24 Use the always on PRCMU Timer as clocksource
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 2a2141915aa0..75838d7710ce 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -489,10 +489,10 @@ config TOUCHSCREEN_TI_TSCADC
489 489
490config TOUCHSCREEN_ATMEL_TSADCC 490config TOUCHSCREEN_ATMEL_TSADCC
491 tristate "Atmel Touchscreen Interface" 491 tristate "Atmel Touchscreen Interface"
492 depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 492 depends on ARCH_AT91
493 help 493 help
494 Say Y here if you have a 4-wire touchscreen connected to the 494 Say Y here if you have a 4-wire touchscreen connected to the
495 ADC Controller on your Atmel SoC (such as the AT91SAM9RL). 495 ADC Controller on your Atmel SoC.
496 496
497 If unsure, say N. 497 If unsure, say N.
498 498
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b5a0032f616e..49ef8b0794ae 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -652,23 +652,6 @@ config EZX_PCAP
652 This enables the PCAP ASIC present on EZX Phones. This is 652 This enables the PCAP ASIC present on EZX Phones. This is
653 needed for MMC, TouchScreen, Sound, USB, etc.. 653 needed for MMC, TouchScreen, Sound, USB, etc..
654 654
655config AB5500_CORE
656 bool "ST-Ericsson AB5500 Mixed Signal Power Management chip"
657 depends on ABX500_CORE && MFD_DB5500_PRCMU
658 select MFD_CORE
659 help
660 Select this option to enable access to AB5500 power management
661 chip. This connects to the db5500 chip via the I2C bus via PRCMU.
662 This chip embeds various other multimedia funtionalities as well.
663
664config AB5500_DEBUG
665 bool "Enable debug info via debugfs"
666 depends on AB5500_CORE && DEBUG_FS
667 default y if DEBUG_FS
668 help
669 Select this option if you want debug information from the AB5500
670 using the debug filesystem, debugfs.
671
672config AB8500_CORE 655config AB8500_CORE
673 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" 656 bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
674 depends on GENERIC_HARDIRQS && ABX500_CORE 657 depends on GENERIC_HARDIRQS && ABX500_CORE
@@ -715,16 +698,6 @@ config MFD_DB8500_PRCMU
715 system controller running an XP70 microprocessor, which is accessed 698 system controller running an XP70 microprocessor, which is accessed
716 through a register map. 699 through a register map.
717 700
718config MFD_DB5500_PRCMU
719 bool "ST-Ericsson DB5500 Power Reset Control Management Unit"
720 depends on UX500_SOC_DB5500
721 select MFD_CORE
722 help
723 Select this option to enable support for the DB5500 Power Reset
724 and Control Management Unit. This is basically an autonomous
725 system controller running an XP70 microprocessor, which is accessed
726 through a register map.
727
728config MFD_CS5535 701config MFD_CS5535
729 tristate "Support for CS5535 and CS5536 southbridge core functions" 702 tristate "Support for CS5535 and CS5536 southbridge core functions"
730 select MFD_CORE 703 select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 77293e150239..43672b87805a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -87,15 +87,12 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
87obj-$(CONFIG_ABX500_CORE) += abx500-core.o 87obj-$(CONFIG_ABX500_CORE) += abx500-core.o
88obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 88obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
89obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 89obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
90obj-$(CONFIG_AB5500_CORE) += ab5500-core.o
91obj-$(CONFIG_AB5500_DEBUG) += ab5500-debugfs.o
92obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 90obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
93obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 91obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
94obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o 92obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
95obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o 93obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
96# ab8500-i2c need to come after db8500-prcmu (which provides the channel) 94# ab8500-i2c need to come after db8500-prcmu (which provides the channel)
97obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o 95obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o
98obj-$(CONFIG_MFD_DB5500_PRCMU) += db5500-prcmu.o
99obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 96obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
100obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 97obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
101obj-$(CONFIG_LPC_SCH) += lpc_sch.o 98obj-$(CONFIG_LPC_SCH) += lpc_sch.o
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c
deleted file mode 100644
index 54d0fe40845f..000000000000
--- a/drivers/mfd/ab5500-core.c
+++ /dev/null
@@ -1,1439 +0,0 @@
1/*
2 * Copyright (C) 2007-2011 ST-Ericsson
3 * License terms: GNU General Public License (GPL) version 2
4 * Low-level core for exclusive access to the AB5500 IC on the I2C bus
5 * and some basic chip-configuration.
6 * Author: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
7 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
8 * Author: Mattias Wallin <mattias.wallin@stericsson.com>
9 * Author: Rickard Andersson <rickard.andersson@stericsson.com>
10 * Author: Karl Komierowski <karl.komierowski@stericsson.com>
11 * Author: Bibek Basu <bibek.basu@stericsson.com>
12 *
13 * TODO: Event handling with irq_chip. Waiting for PRCMU fw support.
14 */
15
16#include <linux/module.h>
17#include <linux/mutex.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/device.h>
22#include <linux/irq.h>
23#include <linux/interrupt.h>
24#include <linux/random.h>
25#include <linux/mfd/abx500.h>
26#include <linux/mfd/abx500/ab5500.h>
27#include <linux/list.h>
28#include <linux/bitops.h>
29#include <linux/spinlock.h>
30#include <linux/mfd/core.h>
31#include <linux/mfd/db5500-prcmu.h>
32
33#include "ab5500-core.h"
34#include "ab5500-debugfs.h"
35
36#define AB5500_NUM_EVENT_REG 23
37#define AB5500_IT_LATCH0_REG 0x40
38#define AB5500_IT_MASK0_REG 0x60
39
40/*
41 * Permissible register ranges for reading and writing per device and bank.
42 *
43 * The ranges must be listed in increasing address order, and no overlaps are
44 * allowed. It is assumed that write permission implies read permission
45 * (i.e. only RO and RW permissions should be used). Ranges with write
46 * permission must not be split up.
47 */
48
49#define NO_RANGE {.count = 0, .range = NULL,}
50static struct ab5500_i2c_banks ab5500_bank_ranges[AB5500_NUM_DEVICES] = {
51 [AB5500_DEVID_USB] = {
52 .nbanks = 1,
53 .bank = (struct ab5500_i2c_ranges []) {
54 {
55 .bankid = AB5500_BANK_USB,
56 .nranges = 12,
57 .range = (struct ab5500_reg_range[]) {
58 {
59 .first = 0x01,
60 .last = 0x01,
61 .perm = AB5500_PERM_RW,
62 },
63 {
64 .first = 0x80,
65 .last = 0x83,
66 .perm = AB5500_PERM_RW,
67 },
68 {
69 .first = 0x87,
70 .last = 0x8A,
71 .perm = AB5500_PERM_RW,
72 },
73 {
74 .first = 0x8B,
75 .last = 0x8B,
76 .perm = AB5500_PERM_RO,
77 },
78 {
79 .first = 0x91,
80 .last = 0x92,
81 .perm = AB5500_PERM_RO,
82 },
83 {
84 .first = 0x93,
85 .last = 0x93,
86 .perm = AB5500_PERM_RW,
87 },
88 {
89 .first = 0x94,
90 .last = 0x94,
91 .perm = AB5500_PERM_RO,
92 },
93 {
94 .first = 0xA8,
95 .last = 0xB0,
96 .perm = AB5500_PERM_RO,
97 },
98 {
99 .first = 0xB2,
100 .last = 0xB2,
101 .perm = AB5500_PERM_RO,
102 },
103 {
104 .first = 0xB4,
105 .last = 0xBC,
106 .perm = AB5500_PERM_RO,
107 },
108 {
109 .first = 0xBF,
110 .last = 0xBF,
111 .perm = AB5500_PERM_RO,
112 },
113 {
114 .first = 0xC1,
115 .last = 0xC5,
116 .perm = AB5500_PERM_RO,
117 },
118 },
119 },
120 },
121 },
122 [AB5500_DEVID_ADC] = {
123 .nbanks = 1,
124 .bank = (struct ab5500_i2c_ranges []) {
125 {
126 .bankid = AB5500_BANK_ADC,
127 .nranges = 6,
128 .range = (struct ab5500_reg_range[]) {
129 {
130 .first = 0x1F,
131 .last = 0x22,
132 .perm = AB5500_PERM_RO,
133 },
134 {
135 .first = 0x23,
136 .last = 0x24,
137 .perm = AB5500_PERM_RW,
138 },
139 {
140 .first = 0x26,
141 .last = 0x2D,
142 .perm = AB5500_PERM_RO,
143 },
144 {
145 .first = 0x2F,
146 .last = 0x34,
147 .perm = AB5500_PERM_RW,
148 },
149 {
150 .first = 0x37,
151 .last = 0x57,
152 .perm = AB5500_PERM_RW,
153 },
154 {
155 .first = 0x58,
156 .last = 0x58,
157 .perm = AB5500_PERM_RO,
158 },
159 },
160 },
161 },
162 },
163 [AB5500_DEVID_LEDS] = {
164 .nbanks = 1,
165 .bank = (struct ab5500_i2c_ranges []) {
166 {
167 .bankid = AB5500_BANK_LED,
168 .nranges = 1,
169 .range = (struct ab5500_reg_range[]) {
170 {
171 .first = 0x00,
172 .last = 0x0C,
173 .perm = AB5500_PERM_RW,
174 },
175 },
176 },
177 },
178 },
179 [AB5500_DEVID_VIDEO] = {
180 .nbanks = 1,
181 .bank = (struct ab5500_i2c_ranges []) {
182 {
183 .bankid = AB5500_BANK_VDENC,
184 .nranges = 12,
185 .range = (struct ab5500_reg_range[]) {
186 {
187 .first = 0x00,
188 .last = 0x08,
189 .perm = AB5500_PERM_RW,
190 },
191 {
192 .first = 0x09,
193 .last = 0x09,
194 .perm = AB5500_PERM_RO,
195 },
196 {
197 .first = 0x0A,
198 .last = 0x12,
199 .perm = AB5500_PERM_RW,
200 },
201 {
202 .first = 0x15,
203 .last = 0x19,
204 .perm = AB5500_PERM_RW,
205 },
206 {
207 .first = 0x1B,
208 .last = 0x21,
209 .perm = AB5500_PERM_RW,
210 },
211 {
212 .first = 0x27,
213 .last = 0x2C,
214 .perm = AB5500_PERM_RW,
215 },
216 {
217 .first = 0x41,
218 .last = 0x41,
219 .perm = AB5500_PERM_RW,
220 },
221 {
222 .first = 0x45,
223 .last = 0x5B,
224 .perm = AB5500_PERM_RW,
225 },
226 {
227 .first = 0x5D,
228 .last = 0x5D,
229 .perm = AB5500_PERM_RW,
230 },
231 {
232 .first = 0x69,
233 .last = 0x69,
234 .perm = AB5500_PERM_RW,
235 },
236 {
237 .first = 0x6C,
238 .last = 0x6D,
239 .perm = AB5500_PERM_RW,
240 },
241 {
242 .first = 0x80,
243 .last = 0x81,
244 .perm = AB5500_PERM_RW,
245 },
246 },
247 },
248 },
249 },
250 [AB5500_DEVID_REGULATORS] = {
251 .nbanks = 2,
252 .bank = (struct ab5500_i2c_ranges []) {
253 {
254 .bankid = AB5500_BANK_STARTUP,
255 .nranges = 12,
256 .range = (struct ab5500_reg_range[]) {
257 {
258 .first = 0x00,
259 .last = 0x01,
260 .perm = AB5500_PERM_RW,
261 },
262 {
263 .first = 0x1F,
264 .last = 0x1F,
265 .perm = AB5500_PERM_RW,
266 },
267 {
268 .first = 0x2E,
269 .last = 0x2E,
270 .perm = AB5500_PERM_RO,
271 },
272 {
273 .first = 0x2F,
274 .last = 0x30,
275 .perm = AB5500_PERM_RW,
276 },
277 {
278 .first = 0x50,
279 .last = 0x51,
280 .perm = AB5500_PERM_RW,
281 },
282 {
283 .first = 0x60,
284 .last = 0x61,
285 .perm = AB5500_PERM_RW,
286 },
287 {
288 .first = 0x66,
289 .last = 0x8A,
290 .perm = AB5500_PERM_RW,
291 },
292 {
293 .first = 0x8C,
294 .last = 0x96,
295 .perm = AB5500_PERM_RW,
296 },
297 {
298 .first = 0xAA,
299 .last = 0xB4,
300 .perm = AB5500_PERM_RW,
301 },
302 {
303 .first = 0xB7,
304 .last = 0xBF,
305 .perm = AB5500_PERM_RW,
306 },
307 {
308 .first = 0xC1,
309 .last = 0xCA,
310 .perm = AB5500_PERM_RW,
311 },
312 {
313 .first = 0xD3,
314 .last = 0xE0,
315 .perm = AB5500_PERM_RW,
316 },
317 },
318 },
319 {
320 .bankid = AB5500_BANK_SIM_USBSIM,
321 .nranges = 1,
322 .range = (struct ab5500_reg_range[]) {
323 {
324 .first = 0x13,
325 .last = 0x19,
326 .perm = AB5500_PERM_RW,
327 },
328 },
329 },
330 },
331 },
332 [AB5500_DEVID_SIM] = {
333 .nbanks = 1,
334 .bank = (struct ab5500_i2c_ranges []) {
335 {
336 .bankid = AB5500_BANK_SIM_USBSIM,
337 .nranges = 1,
338 .range = (struct ab5500_reg_range[]) {
339 {
340 .first = 0x13,
341 .last = 0x19,
342 .perm = AB5500_PERM_RW,
343 },
344 },
345 },
346 },
347 },
348 [AB5500_DEVID_RTC] = {
349 .nbanks = 1,
350 .bank = (struct ab5500_i2c_ranges []) {
351 {
352 .bankid = AB5500_BANK_RTC,
353 .nranges = 2,
354 .range = (struct ab5500_reg_range[]) {
355 {
356 .first = 0x00,
357 .last = 0x04,
358 .perm = AB5500_PERM_RW,
359 },
360 {
361 .first = 0x06,
362 .last = 0x0C,
363 .perm = AB5500_PERM_RW,
364 },
365 },
366 },
367 },
368 },
369 [AB5500_DEVID_CHARGER] = {
370 .nbanks = 1,
371 .bank = (struct ab5500_i2c_ranges []) {
372 {
373 .bankid = AB5500_BANK_CHG,
374 .nranges = 2,
375 .range = (struct ab5500_reg_range[]) {
376 {
377 .first = 0x11,
378 .last = 0x11,
379 .perm = AB5500_PERM_RO,
380 },
381 {
382 .first = 0x12,
383 .last = 0x1B,
384 .perm = AB5500_PERM_RW,
385 },
386 },
387 },
388 },
389 },
390 [AB5500_DEVID_FUELGAUGE] = {
391 .nbanks = 1,
392 .bank = (struct ab5500_i2c_ranges []) {
393 {
394 .bankid = AB5500_BANK_FG_BATTCOM_ACC,
395 .nranges = 2,
396 .range = (struct ab5500_reg_range[]) {
397 {
398 .first = 0x00,
399 .last = 0x0B,
400 .perm = AB5500_PERM_RO,
401 },
402 {
403 .first = 0x0C,
404 .last = 0x10,
405 .perm = AB5500_PERM_RW,
406 },
407 },
408 },
409 },
410 },
411 [AB5500_DEVID_VIBRATOR] = {
412 .nbanks = 1,
413 .bank = (struct ab5500_i2c_ranges []) {
414 {
415 .bankid = AB5500_BANK_VIBRA,
416 .nranges = 2,
417 .range = (struct ab5500_reg_range[]) {
418 {
419 .first = 0x10,
420 .last = 0x13,
421 .perm = AB5500_PERM_RW,
422 },
423 {
424 .first = 0xFE,
425 .last = 0xFE,
426 .perm = AB5500_PERM_RW,
427 },
428 },
429 },
430 },
431 },
432 [AB5500_DEVID_CODEC] = {
433 .nbanks = 1,
434 .bank = (struct ab5500_i2c_ranges []) {
435 {
436 .bankid = AB5500_BANK_AUDIO_HEADSETUSB,
437 .nranges = 2,
438 .range = (struct ab5500_reg_range[]) {
439 {
440 .first = 0x00,
441 .last = 0x48,
442 .perm = AB5500_PERM_RW,
443 },
444 {
445 .first = 0xEB,
446 .last = 0xFB,
447 .perm = AB5500_PERM_RW,
448 },
449 },
450 },
451 },
452 },
453 [AB5500_DEVID_POWER] = {
454 .nbanks = 2,
455 .bank = (struct ab5500_i2c_ranges []) {
456 {
457 .bankid = AB5500_BANK_STARTUP,
458 .nranges = 1,
459 .range = (struct ab5500_reg_range[]) {
460 {
461 .first = 0x30,
462 .last = 0x30,
463 .perm = AB5500_PERM_RW,
464 },
465 },
466 },
467 {
468 .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
469 .nranges = 1,
470 .range = (struct ab5500_reg_range[]) {
471 {
472 .first = 0x01,
473 .last = 0x01,
474 .perm = AB5500_PERM_RW,
475 },
476 },
477 },
478 },
479 },
480};
481
482#define AB5500_IRQ(bank, bit) ((bank) * 8 + (bit))
483
484/* I appologize for the resource names beeing a mix of upper case
485 * and lower case but I want them to be exact as the documentation */
486static struct mfd_cell ab5500_devs[AB5500_NUM_DEVICES] = {
487 [AB5500_DEVID_LEDS] = {
488 .name = "ab5500-leds",
489 .id = AB5500_DEVID_LEDS,
490 },
491 [AB5500_DEVID_POWER] = {
492 .name = "ab5500-power",
493 .id = AB5500_DEVID_POWER,
494 },
495 [AB5500_DEVID_REGULATORS] = {
496 .name = "ab5500-regulator",
497 .id = AB5500_DEVID_REGULATORS,
498 },
499 [AB5500_DEVID_SIM] = {
500 .name = "ab5500-sim",
501 .id = AB5500_DEVID_SIM,
502 .num_resources = 1,
503 .resources = (struct resource[]) {
504 {
505 .name = "SIMOFF",
506 .flags = IORESOURCE_IRQ,
507 .start = AB5500_IRQ(2, 0), /*rising*/
508 .end = AB5500_IRQ(2, 1), /*falling*/
509 },
510 },
511 },
512 [AB5500_DEVID_RTC] = {
513 .name = "ab5500-rtc",
514 .id = AB5500_DEVID_RTC,
515 .num_resources = 1,
516 .resources = (struct resource[]) {
517 {
518 .name = "RTC_Alarm",
519 .flags = IORESOURCE_IRQ,
520 .start = AB5500_IRQ(1, 7),
521 .end = AB5500_IRQ(1, 7),
522 }
523 },
524 },
525 [AB5500_DEVID_CHARGER] = {
526 .name = "ab5500-charger",
527 .id = AB5500_DEVID_CHARGER,
528 },
529 [AB5500_DEVID_ADC] = {
530 .name = "ab5500-adc",
531 .id = AB5500_DEVID_ADC,
532 .num_resources = 10,
533 .resources = (struct resource[]) {
534 {
535 .name = "TRIGGER-0",
536 .flags = IORESOURCE_IRQ,
537 .start = AB5500_IRQ(0, 0),
538 .end = AB5500_IRQ(0, 0),
539 },
540 {
541 .name = "TRIGGER-1",
542 .flags = IORESOURCE_IRQ,
543 .start = AB5500_IRQ(0, 1),
544 .end = AB5500_IRQ(0, 1),
545 },
546 {
547 .name = "TRIGGER-2",
548 .flags = IORESOURCE_IRQ,
549 .start = AB5500_IRQ(0, 2),
550 .end = AB5500_IRQ(0, 2),
551 },
552 {
553 .name = "TRIGGER-3",
554 .flags = IORESOURCE_IRQ,
555 .start = AB5500_IRQ(0, 3),
556 .end = AB5500_IRQ(0, 3),
557 },
558 {
559 .name = "TRIGGER-4",
560 .flags = IORESOURCE_IRQ,
561 .start = AB5500_IRQ(0, 4),
562 .end = AB5500_IRQ(0, 4),
563 },
564 {
565 .name = "TRIGGER-5",
566 .flags = IORESOURCE_IRQ,
567 .start = AB5500_IRQ(0, 5),
568 .end = AB5500_IRQ(0, 5),
569 },
570 {
571 .name = "TRIGGER-6",
572 .flags = IORESOURCE_IRQ,
573 .start = AB5500_IRQ(0, 6),
574 .end = AB5500_IRQ(0, 6),
575 },
576 {
577 .name = "TRIGGER-7",
578 .flags = IORESOURCE_IRQ,
579 .start = AB5500_IRQ(0, 7),
580 .end = AB5500_IRQ(0, 7),
581 },
582 {
583 .name = "TRIGGER-VBAT",
584 .flags = IORESOURCE_IRQ,
585 .start = AB5500_IRQ(0, 8),
586 .end = AB5500_IRQ(0, 8),
587 },
588 {
589 .name = "TRIGGER-VBAT-TXON",
590 .flags = IORESOURCE_IRQ,
591 .start = AB5500_IRQ(0, 9),
592 .end = AB5500_IRQ(0, 9),
593 },
594 },
595 },
596 [AB5500_DEVID_FUELGAUGE] = {
597 .name = "ab5500-fuelgauge",
598 .id = AB5500_DEVID_FUELGAUGE,
599 .num_resources = 6,
600 .resources = (struct resource[]) {
601 {
602 .name = "Batt_attach",
603 .flags = IORESOURCE_IRQ,
604 .start = AB5500_IRQ(7, 5),
605 .end = AB5500_IRQ(7, 5),
606 },
607 {
608 .name = "Batt_removal",
609 .flags = IORESOURCE_IRQ,
610 .start = AB5500_IRQ(7, 6),
611 .end = AB5500_IRQ(7, 6),
612 },
613 {
614 .name = "UART_framing",
615 .flags = IORESOURCE_IRQ,
616 .start = AB5500_IRQ(7, 7),
617 .end = AB5500_IRQ(7, 7),
618 },
619 {
620 .name = "UART_overrun",
621 .flags = IORESOURCE_IRQ,
622 .start = AB5500_IRQ(8, 0),
623 .end = AB5500_IRQ(8, 0),
624 },
625 {
626 .name = "UART_Rdy_RX",
627 .flags = IORESOURCE_IRQ,
628 .start = AB5500_IRQ(8, 1),
629 .end = AB5500_IRQ(8, 1),
630 },
631 {
632 .name = "UART_Rdy_TX",
633 .flags = IORESOURCE_IRQ,
634 .start = AB5500_IRQ(8, 2),
635 .end = AB5500_IRQ(8, 2),
636 },
637 },
638 },
639 [AB5500_DEVID_VIBRATOR] = {
640 .name = "ab5500-vibrator",
641 .id = AB5500_DEVID_VIBRATOR,
642 },
643 [AB5500_DEVID_CODEC] = {
644 .name = "ab5500-codec",
645 .id = AB5500_DEVID_CODEC,
646 .num_resources = 3,
647 .resources = (struct resource[]) {
648 {
649 .name = "audio_spkr1_ovc",
650 .flags = IORESOURCE_IRQ,
651 .start = AB5500_IRQ(9, 5),
652 .end = AB5500_IRQ(9, 5),
653 },
654 {
655 .name = "audio_plllocked",
656 .flags = IORESOURCE_IRQ,
657 .start = AB5500_IRQ(9, 6),
658 .end = AB5500_IRQ(9, 6),
659 },
660 {
661 .name = "audio_spkr2_ovc",
662 .flags = IORESOURCE_IRQ,
663 .start = AB5500_IRQ(17, 4),
664 .end = AB5500_IRQ(17, 4),
665 },
666 },
667 },
668 [AB5500_DEVID_USB] = {
669 .name = "ab5500-usb",
670 .id = AB5500_DEVID_USB,
671 .num_resources = 36,
672 .resources = (struct resource[]) {
673 {
674 .name = "Link_Update",
675 .flags = IORESOURCE_IRQ,
676 .start = AB5500_IRQ(22, 1),
677 .end = AB5500_IRQ(22, 1),
678 },
679 {
680 .name = "DCIO",
681 .flags = IORESOURCE_IRQ,
682 .start = AB5500_IRQ(8, 3),
683 .end = AB5500_IRQ(8, 4),
684 },
685 {
686 .name = "VBUS_R",
687 .flags = IORESOURCE_IRQ,
688 .start = AB5500_IRQ(8, 5),
689 .end = AB5500_IRQ(8, 5),
690 },
691 {
692 .name = "VBUS_F",
693 .flags = IORESOURCE_IRQ,
694 .start = AB5500_IRQ(8, 6),
695 .end = AB5500_IRQ(8, 6),
696 },
697 {
698 .name = "CHGstate_10_PCVBUSchg",
699 .flags = IORESOURCE_IRQ,
700 .start = AB5500_IRQ(8, 7),
701 .end = AB5500_IRQ(8, 7),
702 },
703 {
704 .name = "DCIOreverse_ovc",
705 .flags = IORESOURCE_IRQ,
706 .start = AB5500_IRQ(9, 0),
707 .end = AB5500_IRQ(9, 0),
708 },
709 {
710 .name = "USBCharDetDone",
711 .flags = IORESOURCE_IRQ,
712 .start = AB5500_IRQ(9, 1),
713 .end = AB5500_IRQ(9, 1),
714 },
715 {
716 .name = "DCIO_no_limit",
717 .flags = IORESOURCE_IRQ,
718 .start = AB5500_IRQ(9, 2),
719 .end = AB5500_IRQ(9, 2),
720 },
721 {
722 .name = "USB_suspend",
723 .flags = IORESOURCE_IRQ,
724 .start = AB5500_IRQ(9, 3),
725 .end = AB5500_IRQ(9, 3),
726 },
727 {
728 .name = "DCIOreverse_fwdcurrent",
729 .flags = IORESOURCE_IRQ,
730 .start = AB5500_IRQ(9, 4),
731 .end = AB5500_IRQ(9, 4),
732 },
733 {
734 .name = "Vbus_Imeasmax_change",
735 .flags = IORESOURCE_IRQ,
736 .start = AB5500_IRQ(9, 5),
737 .end = AB5500_IRQ(9, 6),
738 },
739 {
740 .name = "OVV",
741 .flags = IORESOURCE_IRQ,
742 .start = AB5500_IRQ(14, 5),
743 .end = AB5500_IRQ(14, 5),
744 },
745 {
746 .name = "USBcharging_NOTok",
747 .flags = IORESOURCE_IRQ,
748 .start = AB5500_IRQ(15, 3),
749 .end = AB5500_IRQ(15, 3),
750 },
751 {
752 .name = "usb_adp_sensoroff",
753 .flags = IORESOURCE_IRQ,
754 .start = AB5500_IRQ(15, 6),
755 .end = AB5500_IRQ(15, 6),
756 },
757 {
758 .name = "usb_adp_probeplug",
759 .flags = IORESOURCE_IRQ,
760 .start = AB5500_IRQ(15, 7),
761 .end = AB5500_IRQ(15, 7),
762 },
763 {
764 .name = "usb_adp_sinkerror",
765 .flags = IORESOURCE_IRQ,
766 .start = AB5500_IRQ(16, 0),
767 .end = AB5500_IRQ(16, 6),
768 },
769 {
770 .name = "usb_adp_sourceerror",
771 .flags = IORESOURCE_IRQ,
772 .start = AB5500_IRQ(16, 1),
773 .end = AB5500_IRQ(16, 1),
774 },
775 {
776 .name = "usb_idgnd_r",
777 .flags = IORESOURCE_IRQ,
778 .start = AB5500_IRQ(16, 2),
779 .end = AB5500_IRQ(16, 2),
780 },
781 {
782 .name = "usb_idgnd_f",
783 .flags = IORESOURCE_IRQ,
784 .start = AB5500_IRQ(16, 3),
785 .end = AB5500_IRQ(16, 3),
786 },
787 {
788 .name = "usb_iddetR1",
789 .flags = IORESOURCE_IRQ,
790 .start = AB5500_IRQ(16, 4),
791 .end = AB5500_IRQ(16, 5),
792 },
793 {
794 .name = "usb_iddetR2",
795 .flags = IORESOURCE_IRQ,
796 .start = AB5500_IRQ(16, 6),
797 .end = AB5500_IRQ(16, 7),
798 },
799 {
800 .name = "usb_iddetR3",
801 .flags = IORESOURCE_IRQ,
802 .start = AB5500_IRQ(17, 0),
803 .end = AB5500_IRQ(17, 1),
804 },
805 {
806 .name = "usb_iddetR4",
807 .flags = IORESOURCE_IRQ,
808 .start = AB5500_IRQ(17, 2),
809 .end = AB5500_IRQ(17, 3),
810 },
811 {
812 .name = "CharTempWindowOk",
813 .flags = IORESOURCE_IRQ,
814 .start = AB5500_IRQ(17, 7),
815 .end = AB5500_IRQ(18, 0),
816 },
817 {
818 .name = "USB_SprDetect",
819 .flags = IORESOURCE_IRQ,
820 .start = AB5500_IRQ(18, 1),
821 .end = AB5500_IRQ(18, 1),
822 },
823 {
824 .name = "usb_adp_probe_unplug",
825 .flags = IORESOURCE_IRQ,
826 .start = AB5500_IRQ(18, 2),
827 .end = AB5500_IRQ(18, 2),
828 },
829 {
830 .name = "VBUSChDrop",
831 .flags = IORESOURCE_IRQ,
832 .start = AB5500_IRQ(18, 3),
833 .end = AB5500_IRQ(18, 4),
834 },
835 {
836 .name = "dcio_char_rec_done",
837 .flags = IORESOURCE_IRQ,
838 .start = AB5500_IRQ(18, 5),
839 .end = AB5500_IRQ(18, 5),
840 },
841 {
842 .name = "Charging_stopped_by_temp",
843 .flags = IORESOURCE_IRQ,
844 .start = AB5500_IRQ(18, 6),
845 .end = AB5500_IRQ(18, 6),
846 },
847 {
848 .name = "CHGstate_11_SafeModeVBUS",
849 .flags = IORESOURCE_IRQ,
850 .start = AB5500_IRQ(21, 1),
851 .end = AB5500_IRQ(21, 2),
852 },
853 {
854 .name = "CHGstate_12_comletedVBUS",
855 .flags = IORESOURCE_IRQ,
856 .start = AB5500_IRQ(21, 2),
857 .end = AB5500_IRQ(21, 2),
858 },
859 {
860 .name = "CHGstate_13_completedVBUS",
861 .flags = IORESOURCE_IRQ,
862 .start = AB5500_IRQ(21, 3),
863 .end = AB5500_IRQ(21, 3),
864 },
865 {
866 .name = "CHGstate_14_FullChgDCIO",
867 .flags = IORESOURCE_IRQ,
868 .start = AB5500_IRQ(21, 4),
869 .end = AB5500_IRQ(21, 4),
870 },
871 {
872 .name = "CHGstate_15_SafeModeDCIO",
873 .flags = IORESOURCE_IRQ,
874 .start = AB5500_IRQ(21, 5),
875 .end = AB5500_IRQ(21, 5),
876 },
877 {
878 .name = "CHGstate_16_OFFsuspendDCIO",
879 .flags = IORESOURCE_IRQ,
880 .start = AB5500_IRQ(21, 6),
881 .end = AB5500_IRQ(21, 6),
882 },
883 {
884 .name = "CHGstate_17_completedDCIO",
885 .flags = IORESOURCE_IRQ,
886 .start = AB5500_IRQ(21, 7),
887 .end = AB5500_IRQ(21, 7),
888 },
889 },
890 },
891 [AB5500_DEVID_OTP] = {
892 .name = "ab5500-otp",
893 .id = AB5500_DEVID_OTP,
894 },
895 [AB5500_DEVID_VIDEO] = {
896 .name = "ab5500-video",
897 .id = AB5500_DEVID_VIDEO,
898 .num_resources = 1,
899 .resources = (struct resource[]) {
900 {
901 .name = "plugTVdet",
902 .flags = IORESOURCE_IRQ,
903 .start = AB5500_IRQ(22, 2),
904 .end = AB5500_IRQ(22, 2),
905 },
906 },
907 },
908 [AB5500_DEVID_DBIECI] = {
909 .name = "ab5500-dbieci",
910 .id = AB5500_DEVID_DBIECI,
911 .num_resources = 10,
912 .resources = (struct resource[]) {
913 {
914 .name = "COLL",
915 .flags = IORESOURCE_IRQ,
916 .start = AB5500_IRQ(14, 0),
917 .end = AB5500_IRQ(14, 0),
918 },
919 {
920 .name = "RESERR",
921 .flags = IORESOURCE_IRQ,
922 .start = AB5500_IRQ(14, 1),
923 .end = AB5500_IRQ(14, 1),
924 },
925 {
926 .name = "FRAERR",
927 .flags = IORESOURCE_IRQ,
928 .start = AB5500_IRQ(14, 2),
929 .end = AB5500_IRQ(14, 2),
930 },
931 {
932 .name = "COMERR",
933 .flags = IORESOURCE_IRQ,
934 .start = AB5500_IRQ(14, 3),
935 .end = AB5500_IRQ(14, 3),
936 },
937 {
938 .name = "BSI_indicator",
939 .flags = IORESOURCE_IRQ,
940 .start = AB5500_IRQ(14, 4),
941 .end = AB5500_IRQ(14, 4),
942 },
943 {
944 .name = "SPDSET",
945 .flags = IORESOURCE_IRQ,
946 .start = AB5500_IRQ(14, 6),
947 .end = AB5500_IRQ(14, 6),
948 },
949 {
950 .name = "DSENT",
951 .flags = IORESOURCE_IRQ,
952 .start = AB5500_IRQ(14, 7),
953 .end = AB5500_IRQ(14, 7),
954 },
955 {
956 .name = "DREC",
957 .flags = IORESOURCE_IRQ,
958 .start = AB5500_IRQ(15, 0),
959 .end = AB5500_IRQ(15, 0),
960 },
961 {
962 .name = "ACCINT",
963 .flags = IORESOURCE_IRQ,
964 .start = AB5500_IRQ(15, 1),
965 .end = AB5500_IRQ(15, 1),
966 },
967 {
968 .name = "NOPINT",
969 .flags = IORESOURCE_IRQ,
970 .start = AB5500_IRQ(15, 2),
971 .end = AB5500_IRQ(15, 2),
972 },
973 },
974 },
975 [AB5500_DEVID_ONSWA] = {
976 .name = "ab5500-onswa",
977 .id = AB5500_DEVID_ONSWA,
978 .num_resources = 2,
979 .resources = (struct resource[]) {
980 {
981 .name = "ONSWAn_rising",
982 .flags = IORESOURCE_IRQ,
983 .start = AB5500_IRQ(1, 3),
984 .end = AB5500_IRQ(1, 3),
985 },
986 {
987 .name = "ONSWAn_falling",
988 .flags = IORESOURCE_IRQ,
989 .start = AB5500_IRQ(1, 4),
990 .end = AB5500_IRQ(1, 4),
991 },
992 },
993 },
994};
995
996/*
997 * Functionality for getting/setting register values.
998 */
999int ab5500_get_register_interruptible_raw(struct ab5500 *ab,
1000 u8 bank, u8 reg,
1001 u8 *value)
1002{
1003 int err;
1004
1005 if (bank >= AB5500_NUM_BANKS)
1006 return -EINVAL;
1007
1008 err = mutex_lock_interruptible(&ab->access_mutex);
1009 if (err)
1010 return err;
1011 err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr, reg, value, 1);
1012
1013 mutex_unlock(&ab->access_mutex);
1014 return err;
1015}
1016
1017static int get_register_page_interruptible(struct ab5500 *ab, u8 bank,
1018 u8 first_reg, u8 *regvals, u8 numregs)
1019{
1020 int err;
1021
1022 if (bank >= AB5500_NUM_BANKS)
1023 return -EINVAL;
1024
1025 err = mutex_lock_interruptible(&ab->access_mutex);
1026 if (err)
1027 return err;
1028
1029 while (numregs) {
1030 /* The hardware limit for get page is 4 */
1031 u8 curnum = min_t(u8, numregs, 4u);
1032
1033 err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr,
1034 first_reg, regvals, curnum);
1035 if (err)
1036 goto out;
1037
1038 numregs -= curnum;
1039 first_reg += curnum;
1040 regvals += curnum;
1041 }
1042
1043out:
1044 mutex_unlock(&ab->access_mutex);
1045 return err;
1046}
1047
1048int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank,
1049 u8 reg, u8 bitmask, u8 bitvalues)
1050{
1051 int err = 0;
1052
1053 if (bank >= AB5500_NUM_BANKS)
1054 return -EINVAL;
1055
1056 if (bitmask) {
1057 u8 buf;
1058
1059 err = mutex_lock_interruptible(&ab->access_mutex);
1060 if (err)
1061 return err;
1062
1063 if (bitmask == 0xFF) /* No need to read in this case. */
1064 buf = bitvalues;
1065 else { /* Read and modify the register value. */
1066 err = db5500_prcmu_abb_read(bankinfo[bank].slave_addr,
1067 reg, &buf, 1);
1068 if (err)
1069 return err;
1070
1071 buf = ((~bitmask & buf) | (bitmask & bitvalues));
1072 }
1073 /* Write the new value. */
1074 err = db5500_prcmu_abb_write(bankinfo[bank].slave_addr, reg,
1075 &buf, 1);
1076
1077 mutex_unlock(&ab->access_mutex);
1078 }
1079 return err;
1080}
1081
1082static int
1083set_register_interruptible(struct ab5500 *ab, u8 bank, u8 reg, u8 value)
1084{
1085 return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg,
1086 0xff, value);
1087}
1088
1089/*
1090 * Read/write permission checking functions.
1091 */
1092static const struct ab5500_i2c_ranges *get_bankref(u8 devid, u8 bank)
1093{
1094 u8 i;
1095
1096 if (devid < AB5500_NUM_DEVICES) {
1097 for (i = 0; i < ab5500_bank_ranges[devid].nbanks; i++) {
1098 if (ab5500_bank_ranges[devid].bank[i].bankid == bank)
1099 return &ab5500_bank_ranges[devid].bank[i];
1100 }
1101 }
1102 return NULL;
1103}
1104
1105static bool page_write_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg)
1106{
1107 u8 i; /* range loop index */
1108 const struct ab5500_i2c_ranges *bankref;
1109
1110 bankref = get_bankref(devid, bank);
1111 if (bankref == NULL || last_reg < first_reg)
1112 return false;
1113
1114 for (i = 0; i < bankref->nranges; i++) {
1115 if (first_reg < bankref->range[i].first)
1116 break;
1117 if ((last_reg <= bankref->range[i].last) &&
1118 (bankref->range[i].perm & AB5500_PERM_WR))
1119 return true;
1120 }
1121 return false;
1122}
1123
1124static bool reg_write_allowed(u8 devid, u8 bank, u8 reg)
1125{
1126 return page_write_allowed(devid, bank, reg, reg);
1127}
1128
1129static bool page_read_allowed(u8 devid, u8 bank, u8 first_reg, u8 last_reg)
1130{
1131 u8 i;
1132 const struct ab5500_i2c_ranges *bankref;
1133
1134 bankref = get_bankref(devid, bank);
1135 if (bankref == NULL || last_reg < first_reg)
1136 return false;
1137
1138
1139 /* Find the range (if it exists in the list) that includes first_reg. */
1140 for (i = 0; i < bankref->nranges; i++) {
1141 if (first_reg < bankref->range[i].first)
1142 return false;
1143 if (first_reg <= bankref->range[i].last)
1144 break;
1145 }
1146 /* Make sure that the entire range up to and including last_reg is
1147 * readable. This may span several of the ranges in the list.
1148 */
1149 while ((i < bankref->nranges) &&
1150 (bankref->range[i].perm & AB5500_PERM_RD)) {
1151 if (last_reg <= bankref->range[i].last)
1152 return true;
1153 if ((++i >= bankref->nranges) ||
1154 (bankref->range[i].first !=
1155 (bankref->range[i - 1].last + 1))) {
1156 break;
1157 }
1158 }
1159 return false;
1160}
1161
1162static bool reg_read_allowed(u8 devid, u8 bank, u8 reg)
1163{
1164 return page_read_allowed(devid, bank, reg, reg);
1165}
1166
1167
1168/*
1169 * The exported register access functionality.
1170 */
1171static int ab5500_get_chip_id(struct device *dev)
1172{
1173 struct ab5500 *ab = dev_get_drvdata(dev->parent);
1174
1175 return (int)ab->chip_id;
1176}
1177
1178static int ab5500_mask_and_set_register_interruptible(struct device *dev,
1179 u8 bank, u8 reg, u8 bitmask, u8 bitvalues)
1180{
1181 struct ab5500 *ab;
1182 struct platform_device *pdev = to_platform_device(dev);
1183
1184 if ((AB5500_NUM_BANKS <= bank) ||
1185 !reg_write_allowed(pdev->id, bank, reg))
1186 return -EINVAL;
1187
1188 ab = dev_get_drvdata(dev->parent);
1189 return ab5500_mask_and_set_register_interruptible_raw(ab, bank, reg,
1190 bitmask, bitvalues);
1191}
1192
1193static int ab5500_set_register_interruptible(struct device *dev, u8 bank,
1194 u8 reg, u8 value)
1195{
1196 return ab5500_mask_and_set_register_interruptible(dev, bank, reg, 0xFF,
1197 value);
1198}
1199
1200static int ab5500_get_register_interruptible(struct device *dev, u8 bank,
1201 u8 reg, u8 *value)
1202{
1203 struct ab5500 *ab;
1204 struct platform_device *pdev = to_platform_device(dev);
1205
1206 if ((AB5500_NUM_BANKS <= bank) ||
1207 !reg_read_allowed(pdev->id, bank, reg))
1208 return -EINVAL;
1209
1210 ab = dev_get_drvdata(dev->parent);
1211 return ab5500_get_register_interruptible_raw(ab, bank, reg, value);
1212}
1213
1214static int ab5500_get_register_page_interruptible(struct device *dev, u8 bank,
1215 u8 first_reg, u8 *regvals, u8 numregs)
1216{
1217 struct ab5500 *ab;
1218 struct platform_device *pdev = to_platform_device(dev);
1219
1220 if ((AB5500_NUM_BANKS <= bank) ||
1221 !page_read_allowed(pdev->id, bank,
1222 first_reg, (first_reg + numregs - 1)))
1223 return -EINVAL;
1224
1225 ab = dev_get_drvdata(dev->parent);
1226 return get_register_page_interruptible(ab, bank, first_reg, regvals,
1227 numregs);
1228}
1229
1230static int
1231ab5500_event_registers_startup_state_get(struct device *dev, u8 *event)
1232{
1233 struct ab5500 *ab;
1234
1235 ab = dev_get_drvdata(dev->parent);
1236 if (!ab->startup_events_read)
1237 return -EAGAIN; /* Try again later */
1238
1239 memcpy(event, ab->startup_events, AB5500_NUM_EVENT_REG);
1240 return 0;
1241}
1242
1243static struct abx500_ops ab5500_ops = {
1244 .get_chip_id = ab5500_get_chip_id,
1245 .get_register = ab5500_get_register_interruptible,
1246 .set_register = ab5500_set_register_interruptible,
1247 .get_register_page = ab5500_get_register_page_interruptible,
1248 .set_register_page = NULL,
1249 .mask_and_set_register = ab5500_mask_and_set_register_interruptible,
1250 .event_registers_startup_state_get =
1251 ab5500_event_registers_startup_state_get,
1252 .startup_irq_enabled = NULL,
1253};
1254
1255/*
1256 * ab5500_setup : Basic set-up, datastructure creation/destruction
1257 * and I2C interface.This sets up a default config
1258 * in the AB5500 chip so that it will work as expected.
1259 * @ab : Pointer to ab5500 structure
1260 * @settings : Pointer to struct abx500_init_settings
1261 * @size : Size of init data
1262 */
1263static int __init ab5500_setup(struct ab5500 *ab,
1264 struct abx500_init_settings *settings, unsigned int size)
1265{
1266 int err = 0;
1267 int i;
1268
1269 for (i = 0; i < size; i++) {
1270 err = ab5500_mask_and_set_register_interruptible_raw(ab,
1271 settings[i].bank,
1272 settings[i].reg,
1273 0xFF, settings[i].setting);
1274 if (err)
1275 goto exit_no_setup;
1276
1277 /* If event mask register update the event mask in ab5500 */
1278 if ((settings[i].bank == AB5500_BANK_IT) &&
1279 (AB5500_MASK_BASE <= settings[i].reg) &&
1280 (settings[i].reg <= AB5500_MASK_END)) {
1281 ab->mask[settings[i].reg - AB5500_MASK_BASE] =
1282 settings[i].setting;
1283 }
1284 }
1285exit_no_setup:
1286 return err;
1287}
1288
1289struct ab_family_id {
1290 u8 id;
1291 char *name;
1292};
1293
1294static const struct ab_family_id ids[] __initdata = {
1295 /* AB5500 */
1296 {
1297 .id = AB5500_1_0,
1298 .name = "1.0"
1299 },
1300 {
1301 .id = AB5500_1_1,
1302 .name = "1.1"
1303 },
1304 /* Terminator */
1305 {
1306 .id = 0x00,
1307 }
1308};
1309
1310static int __init ab5500_probe(struct platform_device *pdev)
1311{
1312 struct ab5500 *ab;
1313 struct ab5500_platform_data *ab5500_plf_data =
1314 pdev->dev.platform_data;
1315 int err;
1316 int i;
1317
1318 ab = kzalloc(sizeof(struct ab5500), GFP_KERNEL);
1319 if (!ab) {
1320 dev_err(&pdev->dev,
1321 "could not allocate ab5500 device\n");
1322 return -ENOMEM;
1323 }
1324
1325 /* Initialize data structure */
1326 mutex_init(&ab->access_mutex);
1327 mutex_init(&ab->irq_lock);
1328 ab->dev = &pdev->dev;
1329
1330 platform_set_drvdata(pdev, ab);
1331
1332 /* Read chip ID register */
1333 err = ab5500_get_register_interruptible_raw(ab,
1334 AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
1335 AB5500_CHIP_ID, &ab->chip_id);
1336 if (err) {
1337 dev_err(&pdev->dev, "could not communicate with the analog "
1338 "baseband chip\n");
1339 goto exit_no_detect;
1340 }
1341
1342 for (i = 0; ids[i].id != 0x0; i++) {
1343 if (ids[i].id == ab->chip_id) {
1344 snprintf(&ab->chip_name[0], sizeof(ab->chip_name) - 1,
1345 "AB5500 %s", ids[i].name);
1346 break;
1347 }
1348 }
1349 if (ids[i].id == 0x0) {
1350 dev_err(&pdev->dev, "unknown analog baseband chip id: 0x%x\n",
1351 ab->chip_id);
1352 dev_err(&pdev->dev, "driver not started!\n");
1353 goto exit_no_detect;
1354 }
1355
1356 /* Clear and mask all interrupts */
1357 for (i = 0; i < AB5500_NUM_IRQ_REGS; i++) {
1358 u8 latchreg = AB5500_IT_LATCH0_REG + i;
1359 u8 maskreg = AB5500_IT_MASK0_REG + i;
1360 u8 val;
1361
1362 ab5500_get_register_interruptible_raw(ab, AB5500_BANK_IT,
1363 latchreg, &val);
1364 set_register_interruptible(ab, AB5500_BANK_IT, maskreg, 0xff);
1365 ab->mask[i] = ab->oldmask[i] = 0xff;
1366 }
1367
1368 err = abx500_register_ops(&pdev->dev, &ab5500_ops);
1369 if (err) {
1370 dev_err(&pdev->dev, "ab5500_register ops error\n");
1371 goto exit_no_detect;
1372 }
1373
1374 /* Set up and register the platform devices. */
1375 for (i = 0; i < AB5500_NUM_DEVICES; i++) {
1376 ab5500_devs[i].platform_data = ab5500_plf_data->dev_data[i];
1377 ab5500_devs[i].pdata_size =
1378 sizeof(ab5500_plf_data->dev_data[i]);
1379 }
1380
1381 err = mfd_add_devices(&pdev->dev, 0, ab5500_devs,
1382 ARRAY_SIZE(ab5500_devs), NULL,
1383 ab5500_plf_data->irq.base);
1384 if (err) {
1385 dev_err(&pdev->dev, "ab5500_mfd_add_device error\n");
1386 goto exit_no_detect;
1387 }
1388
1389 err = ab5500_setup(ab, ab5500_plf_data->init_settings,
1390 ab5500_plf_data->init_settings_sz);
1391 if (err) {
1392 dev_err(&pdev->dev, "ab5500_setup error\n");
1393 goto exit_no_detect;
1394 }
1395
1396 ab5500_setup_debugfs(ab);
1397
1398 dev_info(&pdev->dev, "detected AB chip: %s\n", &ab->chip_name[0]);
1399 return 0;
1400
1401exit_no_detect:
1402 kfree(ab);
1403 return err;
1404}
1405
1406static int __exit ab5500_remove(struct platform_device *pdev)
1407{
1408 struct ab5500 *ab = platform_get_drvdata(pdev);
1409
1410 ab5500_remove_debugfs();
1411 mfd_remove_devices(&pdev->dev);
1412 kfree(ab);
1413 return 0;
1414}
1415
1416static struct platform_driver ab5500_driver = {
1417 .driver = {
1418 .name = "ab5500-core",
1419 .owner = THIS_MODULE,
1420 },
1421 .remove = __exit_p(ab5500_remove),
1422};
1423
1424static int __init ab5500_core_init(void)
1425{
1426 return platform_driver_probe(&ab5500_driver, ab5500_probe);
1427}
1428
1429static void __exit ab5500_core_exit(void)
1430{
1431 platform_driver_unregister(&ab5500_driver);
1432}
1433
1434subsys_initcall(ab5500_core_init);
1435module_exit(ab5500_core_exit);
1436
1437MODULE_AUTHOR("Mattias Wallin <mattias.wallin@stericsson.com>");
1438MODULE_DESCRIPTION("AB5500 core driver");
1439MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c
deleted file mode 100644
index 72006940937a..000000000000
--- a/drivers/mfd/ab5500-debugfs.c
+++ /dev/null
@@ -1,807 +0,0 @@
1/*
2 * Copyright (C) 2011 ST-Ericsson
3 * License terms: GNU General Public License (GPL) version 2
4 * Debugfs support for the AB5500 MFD driver
5 */
6
7#include <linux/module.h>
8#include <linux/debugfs.h>
9#include <linux/seq_file.h>
10#include <linux/mfd/abx500.h>
11#include <linux/mfd/abx500/ab5500.h>
12#include <linux/uaccess.h>
13
14#include "ab5500-core.h"
15#include "ab5500-debugfs.h"
16
17static struct ab5500_i2c_ranges ab5500_reg_ranges[AB5500_NUM_BANKS] = {
18 [AB5500_BANK_LED] = {
19 .bankid = AB5500_BANK_LED,
20 .nranges = 1,
21 .range = (struct ab5500_reg_range[]) {
22 {
23 .first = 0x00,
24 .last = 0x0C,
25 .perm = AB5500_PERM_RW,
26 },
27 },
28 },
29 [AB5500_BANK_ADC] = {
30 .bankid = AB5500_BANK_ADC,
31 .nranges = 6,
32 .range = (struct ab5500_reg_range[]) {
33 {
34 .first = 0x1F,
35 .last = 0x22,
36 .perm = AB5500_PERM_RO,
37 },
38 {
39 .first = 0x23,
40 .last = 0x24,
41 .perm = AB5500_PERM_RW,
42 },
43 {
44 .first = 0x26,
45 .last = 0x2D,
46 .perm = AB5500_PERM_RO,
47 },
48 {
49 .first = 0x2F,
50 .last = 0x34,
51 .perm = AB5500_PERM_RW,
52 },
53 {
54 .first = 0x37,
55 .last = 0x57,
56 .perm = AB5500_PERM_RW,
57 },
58 {
59 .first = 0x58,
60 .last = 0x58,
61 .perm = AB5500_PERM_RO,
62 },
63 },
64 },
65 [AB5500_BANK_RTC] = {
66 .bankid = AB5500_BANK_RTC,
67 .nranges = 2,
68 .range = (struct ab5500_reg_range[]) {
69 {
70 .first = 0x00,
71 .last = 0x04,
72 .perm = AB5500_PERM_RW,
73 },
74 {
75 .first = 0x06,
76 .last = 0x0C,
77 .perm = AB5500_PERM_RW,
78 },
79 },
80 },
81 [AB5500_BANK_STARTUP] = {
82 .bankid = AB5500_BANK_STARTUP,
83 .nranges = 12,
84 .range = (struct ab5500_reg_range[]) {
85 {
86 .first = 0x00,
87 .last = 0x01,
88 .perm = AB5500_PERM_RW,
89 },
90 {
91 .first = 0x1F,
92 .last = 0x1F,
93 .perm = AB5500_PERM_RW,
94 },
95 {
96 .first = 0x2E,
97 .last = 0x2E,
98 .perm = AB5500_PERM_RO,
99 },
100 {
101 .first = 0x2F,
102 .last = 0x30,
103 .perm = AB5500_PERM_RW,
104 },
105 {
106 .first = 0x50,
107 .last = 0x51,
108 .perm = AB5500_PERM_RW,
109 },
110 {
111 .first = 0x60,
112 .last = 0x61,
113 .perm = AB5500_PERM_RW,
114 },
115 {
116 .first = 0x66,
117 .last = 0x8A,
118 .perm = AB5500_PERM_RW,
119 },
120 {
121 .first = 0x8C,
122 .last = 0x96,
123 .perm = AB5500_PERM_RW,
124 },
125 {
126 .first = 0xAA,
127 .last = 0xB4,
128 .perm = AB5500_PERM_RW,
129 },
130 {
131 .first = 0xB7,
132 .last = 0xBF,
133 .perm = AB5500_PERM_RW,
134 },
135 {
136 .first = 0xC1,
137 .last = 0xCA,
138 .perm = AB5500_PERM_RW,
139 },
140 {
141 .first = 0xD3,
142 .last = 0xE0,
143 .perm = AB5500_PERM_RW,
144 },
145 },
146 },
147 [AB5500_BANK_DBI_ECI] = {
148 .bankid = AB5500_BANK_DBI_ECI,
149 .nranges = 3,
150 .range = (struct ab5500_reg_range[]) {
151 {
152 .first = 0x00,
153 .last = 0x07,
154 .perm = AB5500_PERM_RW,
155 },
156 {
157 .first = 0x10,
158 .last = 0x10,
159 .perm = AB5500_PERM_RW,
160 },
161 {
162 .first = 0x13,
163 .last = 0x13,
164 .perm = AB5500_PERM_RW,
165 },
166 },
167 },
168 [AB5500_BANK_CHG] = {
169 .bankid = AB5500_BANK_CHG,
170 .nranges = 2,
171 .range = (struct ab5500_reg_range[]) {
172 {
173 .first = 0x11,
174 .last = 0x11,
175 .perm = AB5500_PERM_RO,
176 },
177 {
178 .first = 0x12,
179 .last = 0x1B,
180 .perm = AB5500_PERM_RW,
181 },
182 },
183 },
184 [AB5500_BANK_FG_BATTCOM_ACC] = {
185 .bankid = AB5500_BANK_FG_BATTCOM_ACC,
186 .nranges = 2,
187 .range = (struct ab5500_reg_range[]) {
188 {
189 .first = 0x00,
190 .last = 0x0B,
191 .perm = AB5500_PERM_RO,
192 },
193 {
194 .first = 0x0C,
195 .last = 0x10,
196 .perm = AB5500_PERM_RW,
197 },
198 },
199 },
200 [AB5500_BANK_USB] = {
201 .bankid = AB5500_BANK_USB,
202 .nranges = 12,
203 .range = (struct ab5500_reg_range[]) {
204 {
205 .first = 0x01,
206 .last = 0x01,
207 .perm = AB5500_PERM_RW,
208 },
209 {
210 .first = 0x80,
211 .last = 0x83,
212 .perm = AB5500_PERM_RW,
213 },
214 {
215 .first = 0x87,
216 .last = 0x8A,
217 .perm = AB5500_PERM_RW,
218 },
219 {
220 .first = 0x8B,
221 .last = 0x8B,
222 .perm = AB5500_PERM_RO,
223 },
224 {
225 .first = 0x91,
226 .last = 0x92,
227 .perm = AB5500_PERM_RO,
228 },
229 {
230 .first = 0x93,
231 .last = 0x93,
232 .perm = AB5500_PERM_RW,
233 },
234 {
235 .first = 0x94,
236 .last = 0x94,
237 .perm = AB5500_PERM_RO,
238 },
239 {
240 .first = 0xA8,
241 .last = 0xB0,
242 .perm = AB5500_PERM_RO,
243 },
244 {
245 .first = 0xB2,
246 .last = 0xB2,
247 .perm = AB5500_PERM_RO,
248 },
249 {
250 .first = 0xB4,
251 .last = 0xBC,
252 .perm = AB5500_PERM_RO,
253 },
254 {
255 .first = 0xBF,
256 .last = 0xBF,
257 .perm = AB5500_PERM_RO,
258 },
259 {
260 .first = 0xC1,
261 .last = 0xC5,
262 .perm = AB5500_PERM_RO,
263 },
264 },
265 },
266 [AB5500_BANK_IT] = {
267 .bankid = AB5500_BANK_IT,
268 .nranges = 4,
269 .range = (struct ab5500_reg_range[]) {
270 {
271 .first = 0x00,
272 .last = 0x02,
273 .perm = AB5500_PERM_RO,
274 },
275 {
276 .first = 0x20,
277 .last = 0x36,
278 .perm = AB5500_PERM_RO,
279 },
280 {
281 .first = 0x40,
282 .last = 0x56,
283 .perm = AB5500_PERM_RO,
284 },
285 {
286 .first = 0x60,
287 .last = 0x76,
288 .perm = AB5500_PERM_RO,
289 },
290 },
291 },
292 [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = {
293 .bankid = AB5500_BANK_VDDDIG_IO_I2C_CLK_TST,
294 .nranges = 7,
295 .range = (struct ab5500_reg_range[]) {
296 {
297 .first = 0x02,
298 .last = 0x02,
299 .perm = AB5500_PERM_RW,
300 },
301 {
302 .first = 0x12,
303 .last = 0x12,
304 .perm = AB5500_PERM_RW,
305 },
306 {
307 .first = 0x30,
308 .last = 0x34,
309 .perm = AB5500_PERM_RW,
310 },
311 {
312 .first = 0x40,
313 .last = 0x44,
314 .perm = AB5500_PERM_RW,
315 },
316 {
317 .first = 0x50,
318 .last = 0x54,
319 .perm = AB5500_PERM_RW,
320 },
321 {
322 .first = 0x60,
323 .last = 0x64,
324 .perm = AB5500_PERM_RW,
325 },
326 {
327 .first = 0x70,
328 .last = 0x74,
329 .perm = AB5500_PERM_RW,
330 },
331 },
332 },
333 [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = {
334 .bankid = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP,
335 .nranges = 13,
336 .range = (struct ab5500_reg_range[]) {
337 {
338 .first = 0x01,
339 .last = 0x01,
340 .perm = AB5500_PERM_RW,
341 },
342 {
343 .first = 0x02,
344 .last = 0x02,
345 .perm = AB5500_PERM_RO,
346 },
347 {
348 .first = 0x0D,
349 .last = 0x0F,
350 .perm = AB5500_PERM_RW,
351 },
352 {
353 .first = 0x1C,
354 .last = 0x1C,
355 .perm = AB5500_PERM_RW,
356 },
357 {
358 .first = 0x1E,
359 .last = 0x1E,
360 .perm = AB5500_PERM_RW,
361 },
362 {
363 .first = 0x20,
364 .last = 0x21,
365 .perm = AB5500_PERM_RW,
366 },
367 {
368 .first = 0x25,
369 .last = 0x25,
370 .perm = AB5500_PERM_RW,
371 },
372 {
373 .first = 0x28,
374 .last = 0x2A,
375 .perm = AB5500_PERM_RW,
376 },
377 {
378 .first = 0x30,
379 .last = 0x33,
380 .perm = AB5500_PERM_RW,
381 },
382 {
383 .first = 0x40,
384 .last = 0x43,
385 .perm = AB5500_PERM_RW,
386 },
387 {
388 .first = 0x50,
389 .last = 0x53,
390 .perm = AB5500_PERM_RW,
391 },
392 {
393 .first = 0x60,
394 .last = 0x63,
395 .perm = AB5500_PERM_RW,
396 },
397 {
398 .first = 0x70,
399 .last = 0x73,
400 .perm = AB5500_PERM_RW,
401 },
402 },
403 },
404 [AB5500_BANK_VIBRA] = {
405 .bankid = AB5500_BANK_VIBRA,
406 .nranges = 2,
407 .range = (struct ab5500_reg_range[]) {
408 {
409 .first = 0x10,
410 .last = 0x13,
411 .perm = AB5500_PERM_RW,
412 },
413 {
414 .first = 0xFE,
415 .last = 0xFE,
416 .perm = AB5500_PERM_RW,
417 },
418 },
419 },
420 [AB5500_BANK_AUDIO_HEADSETUSB] = {
421 .bankid = AB5500_BANK_AUDIO_HEADSETUSB,
422 .nranges = 2,
423 .range = (struct ab5500_reg_range[]) {
424 {
425 .first = 0x00,
426 .last = 0x48,
427 .perm = AB5500_PERM_RW,
428 },
429 {
430 .first = 0xEB,
431 .last = 0xFB,
432 .perm = AB5500_PERM_RW,
433 },
434 },
435 },
436 [AB5500_BANK_SIM_USBSIM] = {
437 .bankid = AB5500_BANK_SIM_USBSIM,
438 .nranges = 1,
439 .range = (struct ab5500_reg_range[]) {
440 {
441 .first = 0x13,
442 .last = 0x19,
443 .perm = AB5500_PERM_RW,
444 },
445 },
446 },
447 [AB5500_BANK_VDENC] = {
448 .bankid = AB5500_BANK_VDENC,
449 .nranges = 12,
450 .range = (struct ab5500_reg_range[]) {
451 {
452 .first = 0x00,
453 .last = 0x08,
454 .perm = AB5500_PERM_RW,
455 },
456 {
457 .first = 0x09,
458 .last = 0x09,
459 .perm = AB5500_PERM_RO,
460 },
461 {
462 .first = 0x0A,
463 .last = 0x12,
464 .perm = AB5500_PERM_RW,
465 },
466 {
467 .first = 0x15,
468 .last = 0x19,
469 .perm = AB5500_PERM_RW,
470 },
471 {
472 .first = 0x1B,
473 .last = 0x21,
474 .perm = AB5500_PERM_RW,
475 },
476 {
477 .first = 0x27,
478 .last = 0x2C,
479 .perm = AB5500_PERM_RW,
480 },
481 {
482 .first = 0x41,
483 .last = 0x41,
484 .perm = AB5500_PERM_RW,
485 },
486 {
487 .first = 0x45,
488 .last = 0x5B,
489 .perm = AB5500_PERM_RW,
490 },
491 {
492 .first = 0x5D,
493 .last = 0x5D,
494 .perm = AB5500_PERM_RW,
495 },
496 {
497 .first = 0x69,
498 .last = 0x69,
499 .perm = AB5500_PERM_RW,
500 },
501 {
502 .first = 0x6C,
503 .last = 0x6D,
504 .perm = AB5500_PERM_RW,
505 },
506 {
507 .first = 0x80,
508 .last = 0x81,
509 .perm = AB5500_PERM_RW,
510 },
511 },
512 },
513};
514
515static int ab5500_registers_print(struct seq_file *s, void *p)
516{
517 struct ab5500 *ab = s->private;
518 unsigned int i;
519 u8 bank = (u8)ab->debug_bank;
520
521 seq_printf(s, "ab5500 register values:\n");
522 for (bank = 0; bank < AB5500_NUM_BANKS; bank++) {
523 seq_printf(s, " bank %u, %s (0x%x):\n", bank,
524 bankinfo[bank].name,
525 bankinfo[bank].slave_addr);
526 for (i = 0; i < ab5500_reg_ranges[bank].nranges; i++) {
527 u8 reg;
528 int err;
529
530 for (reg = ab5500_reg_ranges[bank].range[i].first;
531 reg <= ab5500_reg_ranges[bank].range[i].last;
532 reg++) {
533 u8 value;
534
535 err = ab5500_get_register_interruptible_raw(ab,
536 bank, reg,
537 &value);
538 if (err < 0) {
539 dev_err(ab->dev, "get_reg failed %d"
540 "bank 0x%x reg 0x%x\n",
541 err, bank, reg);
542 return err;
543 }
544
545 err = seq_printf(s, "[%d/0x%02X]: 0x%02X\n",
546 bank, reg, value);
547 if (err < 0) {
548 dev_err(ab->dev,
549 "seq_printf overflow\n");
550 /*
551 * Error is not returned here since
552 * the output is wanted in any case
553 */
554 return 0;
555 }
556 }
557 }
558 }
559 return 0;
560}
561
562static int ab5500_registers_open(struct inode *inode, struct file *file)
563{
564 return single_open(file, ab5500_registers_print, inode->i_private);
565}
566
567static const struct file_operations ab5500_registers_fops = {
568 .open = ab5500_registers_open,
569 .read = seq_read,
570 .llseek = seq_lseek,
571 .release = single_release,
572 .owner = THIS_MODULE,
573};
574
575static int ab5500_bank_print(struct seq_file *s, void *p)
576{
577 struct ab5500 *ab = s->private;
578
579 seq_printf(s, "%d\n", ab->debug_bank);
580 return 0;
581}
582
583static int ab5500_bank_open(struct inode *inode, struct file *file)
584{
585 return single_open(file, ab5500_bank_print, inode->i_private);
586}
587
588static ssize_t ab5500_bank_write(struct file *file,
589 const char __user *user_buf,
590 size_t count, loff_t *ppos)
591{
592 struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
593 char buf[32];
594 int buf_size;
595 unsigned long user_bank;
596 int err;
597
598 /* Get userspace string and assure termination */
599 buf_size = min(count, (sizeof(buf) - 1));
600 if (copy_from_user(buf, user_buf, buf_size))
601 return -EFAULT;
602 buf[buf_size] = 0;
603
604 err = strict_strtoul(buf, 0, &user_bank);
605 if (err)
606 return -EINVAL;
607
608 if (user_bank >= AB5500_NUM_BANKS) {
609 dev_err(ab->dev,
610 "debugfs error input > number of banks\n");
611 return -EINVAL;
612 }
613
614 ab->debug_bank = user_bank;
615
616 return buf_size;
617}
618
619static int ab5500_address_print(struct seq_file *s, void *p)
620{
621 struct ab5500 *ab = s->private;
622
623 seq_printf(s, "0x%02X\n", ab->debug_address);
624 return 0;
625}
626
627static int ab5500_address_open(struct inode *inode, struct file *file)
628{
629 return single_open(file, ab5500_address_print, inode->i_private);
630}
631
632static ssize_t ab5500_address_write(struct file *file,
633 const char __user *user_buf,
634 size_t count, loff_t *ppos)
635{
636 struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
637 char buf[32];
638 int buf_size;
639 unsigned long user_address;
640 int err;
641
642 /* Get userspace string and assure termination */
643 buf_size = min(count, (sizeof(buf) - 1));
644 if (copy_from_user(buf, user_buf, buf_size))
645 return -EFAULT;
646 buf[buf_size] = 0;
647
648 err = strict_strtoul(buf, 0, &user_address);
649 if (err)
650 return -EINVAL;
651 if (user_address > 0xff) {
652 dev_err(ab->dev,
653 "debugfs error input > 0xff\n");
654 return -EINVAL;
655 }
656 ab->debug_address = user_address;
657 return buf_size;
658}
659
660static int ab5500_val_print(struct seq_file *s, void *p)
661{
662 struct ab5500 *ab = s->private;
663 int err;
664 u8 regvalue;
665
666 err = ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
667 (u8)ab->debug_address, &regvalue);
668 if (err) {
669 dev_err(ab->dev, "get_reg failed %d, bank 0x%x"
670 ", reg 0x%x\n", err, ab->debug_bank,
671 ab->debug_address);
672 return -EINVAL;
673 }
674 seq_printf(s, "0x%02X\n", regvalue);
675
676 return 0;
677}
678
679static int ab5500_val_open(struct inode *inode, struct file *file)
680{
681 return single_open(file, ab5500_val_print, inode->i_private);
682}
683
684static ssize_t ab5500_val_write(struct file *file,
685 const char __user *user_buf,
686 size_t count, loff_t *ppos)
687{
688 struct ab5500 *ab = ((struct seq_file *)(file->private_data))->private;
689 char buf[32];
690 int buf_size;
691 unsigned long user_val;
692 int err;
693 u8 regvalue;
694
695 /* Get userspace string and assure termination */
696 buf_size = min(count, (sizeof(buf)-1));
697 if (copy_from_user(buf, user_buf, buf_size))
698 return -EFAULT;
699 buf[buf_size] = 0;
700
701 err = strict_strtoul(buf, 0, &user_val);
702 if (err)
703 return -EINVAL;
704 if (user_val > 0xff) {
705 dev_err(ab->dev,
706 "debugfs error input > 0xff\n");
707 return -EINVAL;
708 }
709 err = ab5500_mask_and_set_register_interruptible_raw(
710 ab, (u8)ab->debug_bank,
711 (u8)ab->debug_address, 0xFF, (u8)user_val);
712 if (err)
713 return -EINVAL;
714
715 ab5500_get_register_interruptible_raw(ab, (u8)ab->debug_bank,
716 (u8)ab->debug_address, &regvalue);
717 if (err)
718 return -EINVAL;
719
720 return buf_size;
721}
722
723static const struct file_operations ab5500_bank_fops = {
724 .open = ab5500_bank_open,
725 .write = ab5500_bank_write,
726 .read = seq_read,
727 .llseek = seq_lseek,
728 .release = single_release,
729 .owner = THIS_MODULE,
730};
731
732static const struct file_operations ab5500_address_fops = {
733 .open = ab5500_address_open,
734 .write = ab5500_address_write,
735 .read = seq_read,
736 .llseek = seq_lseek,
737 .release = single_release,
738 .owner = THIS_MODULE,
739};
740
741static const struct file_operations ab5500_val_fops = {
742 .open = ab5500_val_open,
743 .write = ab5500_val_write,
744 .read = seq_read,
745 .llseek = seq_lseek,
746 .release = single_release,
747 .owner = THIS_MODULE,
748};
749
750static struct dentry *ab5500_dir;
751static struct dentry *ab5500_reg_file;
752static struct dentry *ab5500_bank_file;
753static struct dentry *ab5500_address_file;
754static struct dentry *ab5500_val_file;
755
756void __init ab5500_setup_debugfs(struct ab5500 *ab)
757{
758 ab->debug_bank = AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP;
759 ab->debug_address = AB5500_CHIP_ID;
760
761 ab5500_dir = debugfs_create_dir("ab5500", NULL);
762 if (!ab5500_dir)
763 goto exit_no_debugfs;
764
765 ab5500_reg_file = debugfs_create_file("all-bank-registers",
766 S_IRUGO, ab5500_dir, ab, &ab5500_registers_fops);
767 if (!ab5500_reg_file)
768 goto exit_destroy_dir;
769
770 ab5500_bank_file = debugfs_create_file("register-bank",
771 (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_bank_fops);
772 if (!ab5500_bank_file)
773 goto exit_destroy_reg;
774
775 ab5500_address_file = debugfs_create_file("register-address",
776 (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_address_fops);
777 if (!ab5500_address_file)
778 goto exit_destroy_bank;
779
780 ab5500_val_file = debugfs_create_file("register-value",
781 (S_IRUGO | S_IWUGO), ab5500_dir, ab, &ab5500_val_fops);
782 if (!ab5500_val_file)
783 goto exit_destroy_address;
784
785 return;
786
787exit_destroy_address:
788 debugfs_remove(ab5500_address_file);
789exit_destroy_bank:
790 debugfs_remove(ab5500_bank_file);
791exit_destroy_reg:
792 debugfs_remove(ab5500_reg_file);
793exit_destroy_dir:
794 debugfs_remove(ab5500_dir);
795exit_no_debugfs:
796 dev_err(ab->dev, "failed to create debugfs entries.\n");
797 return;
798}
799
800void __exit ab5500_remove_debugfs(void)
801{
802 debugfs_remove(ab5500_val_file);
803 debugfs_remove(ab5500_address_file);
804 debugfs_remove(ab5500_bank_file);
805 debugfs_remove(ab5500_reg_file);
806 debugfs_remove(ab5500_dir);
807}
diff --git a/drivers/mfd/ab5500-debugfs.h b/drivers/mfd/ab5500-debugfs.h
deleted file mode 100644
index 7330a9b6afa6..000000000000
--- a/drivers/mfd/ab5500-debugfs.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2011 ST-Ericsson
3 * License terms: GNU General Public License (GPL) version 2
4 * Debugfs interface to the AB5500 core driver
5 */
6
7#ifdef CONFIG_DEBUG_FS
8
9void ab5500_setup_debugfs(struct ab5500 *ab);
10void ab5500_remove_debugfs(void);
11
12#else /* !CONFIG_DEBUG_FS */
13
14static inline void ab5500_setup_debugfs(struct ab5500 *ab)
15{
16}
17
18static inline void ab5500_remove_debugfs(void)
19{
20}
21
22#endif
diff --git a/drivers/mfd/db5500-prcmu.c b/drivers/mfd/db5500-prcmu.c
deleted file mode 100644
index bb115b2f04e9..000000000000
--- a/drivers/mfd/db5500-prcmu.c
+++ /dev/null
@@ -1,451 +0,0 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * License Terms: GNU General Public License v2
5 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
6 *
7 * U5500 PRCM Unit interface driver
8 */
9#include <linux/module.h>
10#include <linux/kernel.h>
11#include <linux/delay.h>
12#include <linux/errno.h>
13#include <linux/err.h>
14#include <linux/spinlock.h>
15#include <linux/io.h>
16#include <linux/slab.h>
17#include <linux/mutex.h>
18#include <linux/completion.h>
19#include <linux/irq.h>
20#include <linux/jiffies.h>
21#include <linux/bitops.h>
22#include <linux/interrupt.h>
23#include <linux/mfd/dbx500-prcmu.h>
24#include <mach/hardware.h>
25#include <mach/irqs.h>
26#include <mach/db5500-regs.h>
27#include "dbx500-prcmu-regs.h"
28
29#define _PRCM_MB_HEADER (tcdm_base + 0xFE8)
30#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0)
31#define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1)
32#define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2)
33#define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3)
34#define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4)
35#define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5)
36#define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6)
37#define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7)
38#define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8)
39#define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9)
40#define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa)
41#define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb)
42#define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc)
43#define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd)
44#define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe)
45#define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf)
46
47/* Req Mailboxes */
48#define PRCM_REQ_MB0 (tcdm_base + 0xFD8)
49#define PRCM_REQ_MB1 (tcdm_base + 0xFCC)
50#define PRCM_REQ_MB2 (tcdm_base + 0xFC4)
51#define PRCM_REQ_MB3 (tcdm_base + 0xFC0)
52#define PRCM_REQ_MB4 (tcdm_base + 0xF98)
53#define PRCM_REQ_MB5 (tcdm_base + 0xF90)
54#define PRCM_REQ_MB6 (tcdm_base + 0xF8C)
55#define PRCM_REQ_MB7 (tcdm_base + 0xF84)
56
57/* Ack Mailboxes */
58#define PRCM_ACK_MB0 (tcdm_base + 0xF38)
59#define PRCM_ACK_MB1 (tcdm_base + 0xF30)
60#define PRCM_ACK_MB2 (tcdm_base + 0xF24)
61#define PRCM_ACK_MB3 (tcdm_base + 0xF20)
62#define PRCM_ACK_MB4 (tcdm_base + 0xF1C)
63#define PRCM_ACK_MB5 (tcdm_base + 0xF14)
64#define PRCM_ACK_MB6 (tcdm_base + 0xF0C)
65#define PRCM_ACK_MB7 (tcdm_base + 0xF08)
66
67enum mb_return_code {
68 RC_SUCCESS,
69 RC_FAIL,
70};
71
72/* Mailbox 0 headers. */
73enum mb0_header {
74 /* request */
75 RMB0H_PWR_STATE_TRANS = 1,
76 RMB0H_WAKE_UP_CFG,
77 RMB0H_RD_WAKE_UP_ACK,
78 /* acknowledge */
79 AMB0H_WAKE_UP = 1,
80};
81
82/* Mailbox 5 headers. */
83enum mb5_header {
84 MB5H_I2C_WRITE = 1,
85 MB5H_I2C_READ,
86};
87
88/* Request mailbox 5 fields. */
89#define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0)
90#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1)
91#define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2)
92#define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4)
93
94/* Acknowledge mailbox 5 fields. */
95#define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0)
96#define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4)
97
98#define NUM_MB 8
99#define MBOX_BIT BIT
100#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1)
101
102/*
103* Used by MCDE to setup all necessary PRCMU registers
104*/
105#define PRCMU_RESET_DSIPLL 0x00004000
106#define PRCMU_UNCLAMP_DSIPLL 0x00400800
107
108/* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/
109#define PRCMU_DSI_CLOCK_SETTING 0x00000128
110/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */
111#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000135
112#define PRCMU_PLLDSI_FREQ_SETTING 0x00020121
113#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000002
114#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV 0x03000201
115#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00000101
116
117#define PRCMU_ENABLE_PLLDSI 0x00000001
118#define PRCMU_DISABLE_PLLDSI 0x00000000
119
120#define PRCMU_DSI_RESET_SW 0x00000003
121#define PRCMU_RESOUTN0_PIN 0x00000001
122#define PRCMU_RESOUTN1_PIN 0x00000002
123#define PRCMU_RESOUTN2_PIN 0x00000004
124
125#define PRCMU_PLLDSI_LOCKP_LOCKED 0x3
126
127/*
128 * mb0_transfer - state needed for mailbox 0 communication.
129 * @lock: The transaction lock.
130 */
131static struct {
132 spinlock_t lock;
133} mb0_transfer;
134
135/*
136 * mb5_transfer - state needed for mailbox 5 communication.
137 * @lock: The transaction lock.
138 * @work: The transaction completion structure.
139 * @ack: Reply ("acknowledge") data.
140 */
141static struct {
142 struct mutex lock;
143 struct completion work;
144 struct {
145 u8 header;
146 u8 status;
147 u8 value[4];
148 } ack;
149} mb5_transfer;
150
151/* PRCMU TCDM base IO address. */
152static __iomem void *tcdm_base;
153
154/**
155 * db5500_prcmu_abb_read() - Read register value(s) from the ABB.
156 * @slave: The I2C slave address.
157 * @reg: The (start) register address.
158 * @value: The read out value(s).
159 * @size: The number of registers to read.
160 *
161 * Reads register value(s) from the ABB.
162 * @size has to be <= 4.
163 */
164int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
165{
166 int r;
167
168 if ((size < 1) || (4 < size))
169 return -EINVAL;
170
171 mutex_lock(&mb5_transfer.lock);
172
173 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
174 cpu_relax();
175 writeb(slave, PRCM_REQ_MB5_I2C_SLAVE);
176 writeb(reg, PRCM_REQ_MB5_I2C_REG);
177 writeb(size, PRCM_REQ_MB5_I2C_SIZE);
178 writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER);
179
180 writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
181 wait_for_completion(&mb5_transfer.work);
182
183 r = 0;
184 if ((mb5_transfer.ack.header == MB5H_I2C_READ) &&
185 (mb5_transfer.ack.status == RC_SUCCESS))
186 memcpy(value, mb5_transfer.ack.value, (size_t)size);
187 else
188 r = -EIO;
189
190 mutex_unlock(&mb5_transfer.lock);
191
192 return r;
193}
194
195/**
196 * db5500_prcmu_abb_write() - Write register value(s) to the ABB.
197 * @slave: The I2C slave address.
198 * @reg: The (start) register address.
199 * @value: The value(s) to write.
200 * @size: The number of registers to write.
201 *
202 * Writes register value(s) to the ABB.
203 * @size has to be <= 4.
204 */
205int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
206{
207 int r;
208
209 if ((size < 1) || (4 < size))
210 return -EINVAL;
211
212 mutex_lock(&mb5_transfer.lock);
213
214 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
215 cpu_relax();
216 writeb(slave, PRCM_REQ_MB5_I2C_SLAVE);
217 writeb(reg, PRCM_REQ_MB5_I2C_REG);
218 writeb(size, PRCM_REQ_MB5_I2C_SIZE);
219 memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size);
220 writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER);
221
222 writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
223 wait_for_completion(&mb5_transfer.work);
224
225 if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) &&
226 (mb5_transfer.ack.status == RC_SUCCESS))
227 r = 0;
228 else
229 r = -EIO;
230
231 mutex_unlock(&mb5_transfer.lock);
232
233 return r;
234}
235
236int db5500_prcmu_enable_dsipll(void)
237{
238 int i;
239
240 /* Enable DSIPLL_RESETN resets */
241 writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR);
242 /* Unclamp DSIPLL in/out */
243 writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR);
244 /* Set DSI PLL FREQ */
245 writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ);
246 writel(PRCMU_DSI_PLLOUT_SEL_SETTING,
247 PRCM_DSI_PLLOUT_SEL);
248 /* Enable Escape clocks */
249 writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
250
251 /* Start DSI PLL */
252 writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
253 /* Reset DSI PLL */
254 writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET);
255 for (i = 0; i < 10; i++) {
256 if ((readl(PRCM_PLLDSI_LOCKP) &
257 PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED)
258 break;
259 udelay(100);
260 }
261 /* Release DSIPLL_RESETN */
262 writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET);
263 return 0;
264}
265
266int db5500_prcmu_disable_dsipll(void)
267{
268 /* Disable dsi pll */
269 writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
270 /* Disable escapeclock */
271 writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
272 return 0;
273}
274
275int db5500_prcmu_set_display_clocks(void)
276{
277 /* HDMI and TVCLK Should be handled somewhere else */
278 /* PLLDIV=8, PLLSW=2, CLKEN=1 */
279 writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT);
280 /* PLLDIV=14, PLLSW=2, CLKEN=1 */
281 writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT);
282 return 0;
283}
284
285static void ack_dbb_wakeup(void)
286{
287 unsigned long flags;
288
289 spin_lock_irqsave(&mb0_transfer.lock, flags);
290
291 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))
292 cpu_relax();
293
294 writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER);
295 writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET);
296
297 spin_unlock_irqrestore(&mb0_transfer.lock, flags);
298}
299
300static inline void print_unknown_header_warning(u8 n, u8 header)
301{
302 pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n",
303 header, n);
304}
305
306static bool read_mailbox_0(void)
307{
308 bool r;
309 u8 header;
310
311 header = readb(PRCM_ACK_MB0_HEADER);
312 switch (header) {
313 case AMB0H_WAKE_UP:
314 r = true;
315 break;
316 default:
317 print_unknown_header_warning(0, header);
318 r = false;
319 break;
320 }
321 writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR);
322 return r;
323}
324
325static bool read_mailbox_1(void)
326{
327 writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR);
328 return false;
329}
330
331static bool read_mailbox_2(void)
332{
333 writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR);
334 return false;
335}
336
337static bool read_mailbox_3(void)
338{
339 writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR);
340 return false;
341}
342
343static bool read_mailbox_4(void)
344{
345 writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR);
346 return false;
347}
348
349static bool read_mailbox_5(void)
350{
351 u8 header;
352
353 header = readb(PRCM_ACK_MB5_HEADER);
354 switch (header) {
355 case MB5H_I2C_READ:
356 memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4);
357 case MB5H_I2C_WRITE:
358 mb5_transfer.ack.header = header;
359 mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE);
360 complete(&mb5_transfer.work);
361 break;
362 default:
363 print_unknown_header_warning(5, header);
364 break;
365 }
366 writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR);
367 return false;
368}
369
370static bool read_mailbox_6(void)
371{
372 writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR);
373 return false;
374}
375
376static bool read_mailbox_7(void)
377{
378 writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR);
379 return false;
380}
381
382static bool (* const read_mailbox[NUM_MB])(void) = {
383 read_mailbox_0,
384 read_mailbox_1,
385 read_mailbox_2,
386 read_mailbox_3,
387 read_mailbox_4,
388 read_mailbox_5,
389 read_mailbox_6,
390 read_mailbox_7
391};
392
393static irqreturn_t prcmu_irq_handler(int irq, void *data)
394{
395 u32 bits;
396 u8 n;
397 irqreturn_t r;
398
399 bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS);
400 if (unlikely(!bits))
401 return IRQ_NONE;
402
403 r = IRQ_HANDLED;
404 for (n = 0; bits; n++) {
405 if (bits & MBOX_BIT(n)) {
406 bits -= MBOX_BIT(n);
407 if (read_mailbox[n]())
408 r = IRQ_WAKE_THREAD;
409 }
410 }
411 return r;
412}
413
414static irqreturn_t prcmu_irq_thread_fn(int irq, void *data)
415{
416 ack_dbb_wakeup();
417 return IRQ_HANDLED;
418}
419
420void __init db5500_prcmu_early_init(void)
421{
422 tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE);
423 spin_lock_init(&mb0_transfer.lock);
424 mutex_init(&mb5_transfer.lock);
425 init_completion(&mb5_transfer.work);
426}
427
428/**
429 * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
430 *
431 */
432int __init db5500_prcmu_init(void)
433{
434 int r = 0;
435
436 if (ux500_is_svp() || !cpu_is_u5500())
437 return -ENODEV;
438
439 /* Clean up the mailbox interrupts after pre-kernel code. */
440 writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
441
442 r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler,
443 prcmu_irq_thread_fn, 0, "prcmu", NULL);
444 if (r < 0) {
445 pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n");
446 return -EBUSY;
447 }
448 return 0;
449}
450
451arch_initcall(db5500_prcmu_init);
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c
index 2e42ec2e8ff4..04769a49a7cb 100644
--- a/drivers/mtd/nand/autcpu12.c
+++ b/drivers/mtd/nand/autcpu12.c
@@ -102,10 +102,10 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
102 void __iomem *addr; 102 void __iomem *addr;
103 unsigned char bits; 103 unsigned char bits;
104 104
105 addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET; 105 bits = clps_readb(AUTCPU12_SMC_PORT_OFFSET) & ~0x30;
106 bits = (ctrl & NAND_CLE) << 4; 106 bits |= (ctrl & NAND_CLE) << 4;
107 bits |= (ctrl & NAND_ALE) << 2; 107 bits |= (ctrl & NAND_ALE) << 2;
108 writeb((readb(addr) & ~0x30) | bits, addr); 108 clps_writeb(bits, AUTCPU12_SMC_PORT_OFFSET);
109 109
110 addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET; 110 addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET;
111 writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr); 111 writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr);
@@ -120,9 +120,7 @@ static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd,
120 */ 120 */
121int autcpu12_device_ready(struct mtd_info *mtd) 121int autcpu12_device_ready(struct mtd_info *mtd)
122{ 122{
123 void __iomem *addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET; 123 return clps_readb(AUTCPU12_SMC_PORT_OFFSET) & AUTCPU12_SMC_RDY;
124
125 return readb(addr) & AUTCPU12_SMC_RDY;
126} 124}
127 125
128/* 126/*
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c
index 11e487813428..9bf5ce5fa22d 100644
--- a/drivers/mtd/nand/h1910.c
+++ b/drivers/mtd/nand/h1910.c
@@ -24,7 +24,7 @@
24#include <linux/mtd/nand.h> 24#include <linux/mtd/nand.h>
25#include <linux/mtd/partitions.h> 25#include <linux/mtd/partitions.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <mach/hardware.h> /* for CLPS7111_VIRT_BASE */ 27#include <mach/hardware.h>
28#include <asm/sizes.h> 28#include <asm/sizes.h>
29#include <mach/h1900-gpio.h> 29#include <mach/h1900-gpio.h>
30#include <mach/ipaq.h> 30#include <mach/ipaq.h>
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index 35758445297e..031d8e8ed1ad 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -211,8 +211,8 @@ config KINGSUN_DONGLE
211 kingsun-sir. 211 kingsun-sir.
212 212
213config EP7211_DONGLE 213config EP7211_DONGLE
214 tristate "EP7211 I/R support" 214 tristate "Cirrus Logic clps711x I/R support"
215 depends on IRTTY_SIR && ARCH_EP7211 && IRDA && EXPERIMENTAL 215 depends on IRTTY_SIR && ARCH_CLPS711X && IRDA && EXPERIMENTAL
216 help 216 help
217 Say Y here if you want to build support for the Cirrus logic 217 Say Y here if you want to build support for the Cirrus logic
218 EP7211 chipset's infrared module. 218 EP7211 chipset's infrared module.
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 8c8377d50c4c..4161bfe462cd 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -838,7 +838,7 @@ config RTC_DRV_AT32AP700X
838 838
839config RTC_DRV_AT91RM9200 839config RTC_DRV_AT91RM9200
840 tristate "AT91RM9200 or some AT91SAM9 RTC" 840 tristate "AT91RM9200 or some AT91SAM9 RTC"
841 depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 841 depends on ARCH_AT91
842 help 842 help
843 Driver for the internal RTC (Realtime Clock) module found on 843 Driver for the internal RTC (Realtime Clock) module found on
844 Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips 844 Atmel AT91RM9200's and some AT91SAM9 chips. On AT91SAM9 chips
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index 836fe2731234..d0f719fafc84 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -40,7 +40,6 @@
40 40
41#include <mach/hardware.h> 41#include <mach/hardware.h>
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/hardware/clps7111.h>
44 43
45#define UART_NR 2 44#define UART_NR 2
46 45
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 96451e41ee8a..71229cb97e3e 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -205,8 +205,9 @@ static int ohci_omap_init(struct usb_hcd *hcd)
205 need_transceiver = need_transceiver 205 need_transceiver = need_transceiver
206 || machine_is_omap_h2() || machine_is_omap_h3(); 206 || machine_is_omap_h2() || machine_is_omap_h3();
207 207
208 if (cpu_is_omap16xx()) 208 /* XXX OMAP16xx only */
209 ocpi_enable(); 209 if (config->ocpi_enable)
210 config->ocpi_enable();
210 211
211#ifdef CONFIG_USB_OTG 212#ifdef CONFIG_USB_OTG
212 if (need_transceiver) { 213 if (need_transceiver) {
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index 99b354b8e257..f994c8b8f10a 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -33,7 +33,6 @@
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35 35
36#include <asm/hardware/clps7111.h>
37#include <mach/syspld.h> 36#include <mach/syspld.h>
38 37
39struct fb_info *cfb; 38struct fb_info *cfb;
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 408a9927be92..c3853c92279b 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -10,12 +10,12 @@ config PANEL_GENERIC_DPI
10 Supports LCD Panel used in TI SDP3430 and EVM boards, 10 Supports LCD Panel used in TI SDP3430 and EVM boards,
11 OMAP3517 EVM boards and CM-T35. 11 OMAP3517 EVM boards and CM-T35.
12 12
13config PANEL_DVI 13config PANEL_TFP410
14 tristate "DVI output" 14 tristate "TFP410 DPI-to-DVI chip"
15 depends on OMAP2_DSS_DPI && I2C 15 depends on OMAP2_DSS_DPI && I2C
16 help 16 help
17 Driver for external monitors, connected via DVI. The driver uses i2c 17 Driver for TFP410 DPI-to-DVI chip. The driver uses i2c to read EDID
18 to read EDID information from the monitor. 18 information from the monitor.
19 19
20config PANEL_LGPHILIPS_LB035Q02 20config PANEL_LGPHILIPS_LB035Q02
21 tristate "LG.Philips LB035Q02 LCD Panel" 21 tristate "LG.Philips LB035Q02 LCD Panel"
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index fbfafc6eebb4..58a5176b07b0 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o 1obj-$(CONFIG_PANEL_GENERIC_DPI) += panel-generic-dpi.o
2obj-$(CONFIG_PANEL_DVI) += panel-dvi.o 2obj-$(CONFIG_PANEL_TFP410) += panel-tfp410.o
3obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o 3obj-$(CONFIG_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
4obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o 4obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
5obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o 5obj-$(CONFIG_PANEL_NEC_NL8048HL11_01B) += panel-nec-nl8048hl11-01b.o
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 0f21fa5a16ae..b2dd88b48420 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -993,6 +993,15 @@ static int taal_probe(struct omap_dss_device *dssdev)
993 993
994 dev_set_drvdata(&dssdev->dev, td); 994 dev_set_drvdata(&dssdev->dev, td);
995 995
996 if (gpio_is_valid(panel_data->reset_gpio)) {
997 r = gpio_request_one(panel_data->reset_gpio, GPIOF_OUT_INIT_LOW,
998 "taal rst");
999 if (r) {
1000 dev_err(&dssdev->dev, "failed to request reset gpio\n");
1001 goto err_rst_gpio;
1002 }
1003 }
1004
996 taal_hw_reset(dssdev); 1005 taal_hw_reset(dssdev);
997 1006
998 if (panel_data->use_dsi_backlight) { 1007 if (panel_data->use_dsi_backlight) {
@@ -1073,6 +1082,9 @@ err_gpio:
1073 if (bldev != NULL) 1082 if (bldev != NULL)
1074 backlight_device_unregister(bldev); 1083 backlight_device_unregister(bldev);
1075err_bl: 1084err_bl:
1085 if (gpio_is_valid(panel_data->reset_gpio))
1086 gpio_free(panel_data->reset_gpio);
1087err_rst_gpio:
1076 destroy_workqueue(td->workqueue); 1088 destroy_workqueue(td->workqueue);
1077err_wq: 1089err_wq:
1078 free_regulators(panel_config->regulators, panel_config->num_regulators); 1090 free_regulators(panel_config->regulators, panel_config->num_regulators);
@@ -1116,15 +1128,25 @@ static void __exit taal_remove(struct omap_dss_device *dssdev)
1116 free_regulators(td->panel_config->regulators, 1128 free_regulators(td->panel_config->regulators,
1117 td->panel_config->num_regulators); 1129 td->panel_config->num_regulators);
1118 1130
1131 if (gpio_is_valid(panel_data->reset_gpio))
1132 gpio_free(panel_data->reset_gpio);
1133
1119 kfree(td); 1134 kfree(td);
1120} 1135}
1121 1136
1122static int taal_power_on(struct omap_dss_device *dssdev) 1137static int taal_power_on(struct omap_dss_device *dssdev)
1123{ 1138{
1124 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1139 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1140 struct nokia_dsi_panel_data *panel_data = get_panel_data(dssdev);
1125 u8 id1, id2, id3; 1141 u8 id1, id2, id3;
1126 int r; 1142 int r;
1127 1143
1144 r = omapdss_dsi_configure_pins(dssdev, &panel_data->pin_config);
1145 if (r) {
1146 dev_err(&dssdev->dev, "failed to configure DSI pins\n");
1147 goto err0;
1148 };
1149
1128 r = omapdss_dsi_display_enable(dssdev); 1150 r = omapdss_dsi_display_enable(dssdev);
1129 if (r) { 1151 if (r) {
1130 dev_err(&dssdev->dev, "failed to enable DSI\n"); 1152 dev_err(&dssdev->dev, "failed to enable DSI\n");
diff --git a/drivers/video/omap2/displays/panel-dvi.c b/drivers/video/omap2/displays/panel-tfp410.c
index 03eb14af33e0..52637fa8fda8 100644
--- a/drivers/video/omap2/displays/panel-dvi.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * DVI output support 2 * TFP410 DPI-to-DVI chip
3 * 3 *
4 * Copyright (C) 2011 Texas Instruments Inc 4 * Copyright (C) 2011 Texas Instruments Inc
5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> 5 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
@@ -21,11 +21,12 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <video/omapdss.h> 22#include <video/omapdss.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/gpio.h>
24#include <drm/drm_edid.h> 25#include <drm/drm_edid.h>
25 26
26#include <video/omap-panel-dvi.h> 27#include <video/omap-panel-tfp410.h>
27 28
28static const struct omap_video_timings panel_dvi_default_timings = { 29static const struct omap_video_timings tfp410_default_timings = {
29 .x_res = 640, 30 .x_res = 640,
30 .y_res = 480, 31 .y_res = 480,
31 32
@@ -44,17 +45,19 @@ struct panel_drv_data {
44 struct omap_dss_device *dssdev; 45 struct omap_dss_device *dssdev;
45 46
46 struct mutex lock; 47 struct mutex lock;
48
49 int pd_gpio;
47}; 50};
48 51
49static inline struct panel_dvi_platform_data 52static inline struct tfp410_platform_data
50*get_pdata(const struct omap_dss_device *dssdev) 53*get_pdata(const struct omap_dss_device *dssdev)
51{ 54{
52 return dssdev->data; 55 return dssdev->data;
53} 56}
54 57
55static int panel_dvi_power_on(struct omap_dss_device *dssdev) 58static int tfp410_power_on(struct omap_dss_device *dssdev)
56{ 59{
57 struct panel_dvi_platform_data *pdata = get_pdata(dssdev); 60 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
58 int r; 61 int r;
59 62
60 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 63 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@@ -64,57 +67,72 @@ static int panel_dvi_power_on(struct omap_dss_device *dssdev)
64 if (r) 67 if (r)
65 goto err0; 68 goto err0;
66 69
67 if (pdata->platform_enable) { 70 if (gpio_is_valid(ddata->pd_gpio))
68 r = pdata->platform_enable(dssdev); 71 gpio_set_value(ddata->pd_gpio, 1);
69 if (r)
70 goto err1;
71 }
72 72
73 return 0; 73 return 0;
74err1:
75 omapdss_dpi_display_disable(dssdev);
76err0: 74err0:
77 return r; 75 return r;
78} 76}
79 77
80static void panel_dvi_power_off(struct omap_dss_device *dssdev) 78static void tfp410_power_off(struct omap_dss_device *dssdev)
81{ 79{
82 struct panel_dvi_platform_data *pdata = get_pdata(dssdev); 80 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
83 81
84 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 82 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
85 return; 83 return;
86 84
87 if (pdata->platform_disable) 85 if (gpio_is_valid(ddata->pd_gpio))
88 pdata->platform_disable(dssdev); 86 gpio_set_value(ddata->pd_gpio, 0);
89 87
90 omapdss_dpi_display_disable(dssdev); 88 omapdss_dpi_display_disable(dssdev);
91} 89}
92 90
93static int panel_dvi_probe(struct omap_dss_device *dssdev) 91static int tfp410_probe(struct omap_dss_device *dssdev)
94{ 92{
93 struct tfp410_platform_data *pdata = get_pdata(dssdev);
95 struct panel_drv_data *ddata; 94 struct panel_drv_data *ddata;
95 int r;
96 96
97 ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); 97 ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
98 if (!ddata) 98 if (!ddata)
99 return -ENOMEM; 99 return -ENOMEM;
100 100
101 dssdev->panel.timings = panel_dvi_default_timings; 101 dssdev->panel.timings = tfp410_default_timings;
102 dssdev->panel.config = OMAP_DSS_LCD_TFT; 102 dssdev->panel.config = OMAP_DSS_LCD_TFT;
103 103
104 ddata->dssdev = dssdev; 104 ddata->dssdev = dssdev;
105 mutex_init(&ddata->lock); 105 mutex_init(&ddata->lock);
106 106
107 if (pdata)
108 ddata->pd_gpio = pdata->power_down_gpio;
109 else
110 ddata->pd_gpio = -1;
111
112 if (gpio_is_valid(ddata->pd_gpio)) {
113 r = gpio_request_one(ddata->pd_gpio, GPIOF_OUT_INIT_LOW,
114 "tfp410 pd");
115 if (r) {
116 dev_err(&dssdev->dev, "Failed to request PD GPIO %d\n",
117 ddata->pd_gpio);
118 ddata->pd_gpio = -1;
119 }
120 }
121
107 dev_set_drvdata(&dssdev->dev, ddata); 122 dev_set_drvdata(&dssdev->dev, ddata);
108 123
109 return 0; 124 return 0;
110} 125}
111 126
112static void __exit panel_dvi_remove(struct omap_dss_device *dssdev) 127static void __exit tfp410_remove(struct omap_dss_device *dssdev)
113{ 128{
114 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 129 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
115 130
116 mutex_lock(&ddata->lock); 131 mutex_lock(&ddata->lock);
117 132
133 if (gpio_is_valid(ddata->pd_gpio))
134 gpio_free(ddata->pd_gpio);
135
118 dev_set_drvdata(&dssdev->dev, NULL); 136 dev_set_drvdata(&dssdev->dev, NULL);
119 137
120 mutex_unlock(&ddata->lock); 138 mutex_unlock(&ddata->lock);
@@ -122,14 +140,14 @@ static void __exit panel_dvi_remove(struct omap_dss_device *dssdev)
122 kfree(ddata); 140 kfree(ddata);
123} 141}
124 142
125static int panel_dvi_enable(struct omap_dss_device *dssdev) 143static int tfp410_enable(struct omap_dss_device *dssdev)
126{ 144{
127 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 145 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
128 int r; 146 int r;
129 147
130 mutex_lock(&ddata->lock); 148 mutex_lock(&ddata->lock);
131 149
132 r = panel_dvi_power_on(dssdev); 150 r = tfp410_power_on(dssdev);
133 if (r == 0) 151 if (r == 0)
134 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 152 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
135 153
@@ -138,26 +156,26 @@ static int panel_dvi_enable(struct omap_dss_device *dssdev)
138 return r; 156 return r;
139} 157}
140 158
141static void panel_dvi_disable(struct omap_dss_device *dssdev) 159static void tfp410_disable(struct omap_dss_device *dssdev)
142{ 160{
143 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 161 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
144 162
145 mutex_lock(&ddata->lock); 163 mutex_lock(&ddata->lock);
146 164
147 panel_dvi_power_off(dssdev); 165 tfp410_power_off(dssdev);
148 166
149 dssdev->state = OMAP_DSS_DISPLAY_DISABLED; 167 dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
150 168
151 mutex_unlock(&ddata->lock); 169 mutex_unlock(&ddata->lock);
152} 170}
153 171
154static int panel_dvi_suspend(struct omap_dss_device *dssdev) 172static int tfp410_suspend(struct omap_dss_device *dssdev)
155{ 173{
156 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 174 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
157 175
158 mutex_lock(&ddata->lock); 176 mutex_lock(&ddata->lock);
159 177
160 panel_dvi_power_off(dssdev); 178 tfp410_power_off(dssdev);
161 179
162 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; 180 dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
163 181
@@ -166,14 +184,14 @@ static int panel_dvi_suspend(struct omap_dss_device *dssdev)
166 return 0; 184 return 0;
167} 185}
168 186
169static int panel_dvi_resume(struct omap_dss_device *dssdev) 187static int tfp410_resume(struct omap_dss_device *dssdev)
170{ 188{
171 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 189 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
172 int r; 190 int r;
173 191
174 mutex_lock(&ddata->lock); 192 mutex_lock(&ddata->lock);
175 193
176 r = panel_dvi_power_on(dssdev); 194 r = tfp410_power_on(dssdev);
177 if (r == 0) 195 if (r == 0)
178 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; 196 dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
179 197
@@ -182,7 +200,7 @@ static int panel_dvi_resume(struct omap_dss_device *dssdev)
182 return r; 200 return r;
183} 201}
184 202
185static void panel_dvi_set_timings(struct omap_dss_device *dssdev, 203static void tfp410_set_timings(struct omap_dss_device *dssdev,
186 struct omap_video_timings *timings) 204 struct omap_video_timings *timings)
187{ 205{
188 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 206 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
@@ -192,7 +210,7 @@ static void panel_dvi_set_timings(struct omap_dss_device *dssdev,
192 mutex_unlock(&ddata->lock); 210 mutex_unlock(&ddata->lock);
193} 211}
194 212
195static void panel_dvi_get_timings(struct omap_dss_device *dssdev, 213static void tfp410_get_timings(struct omap_dss_device *dssdev,
196 struct omap_video_timings *timings) 214 struct omap_video_timings *timings)
197{ 215{
198 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 216 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
@@ -202,7 +220,7 @@ static void panel_dvi_get_timings(struct omap_dss_device *dssdev,
202 mutex_unlock(&ddata->lock); 220 mutex_unlock(&ddata->lock);
203} 221}
204 222
205static int panel_dvi_check_timings(struct omap_dss_device *dssdev, 223static int tfp410_check_timings(struct omap_dss_device *dssdev,
206 struct omap_video_timings *timings) 224 struct omap_video_timings *timings)
207{ 225{
208 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 226 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
@@ -216,7 +234,7 @@ static int panel_dvi_check_timings(struct omap_dss_device *dssdev,
216} 234}
217 235
218 236
219static int panel_dvi_ddc_read(struct i2c_adapter *adapter, 237static int tfp410_ddc_read(struct i2c_adapter *adapter,
220 unsigned char *buf, u16 count, u8 offset) 238 unsigned char *buf, u16 count, u8 offset)
221{ 239{
222 int r, retries; 240 int r, retries;
@@ -247,11 +265,11 @@ static int panel_dvi_ddc_read(struct i2c_adapter *adapter,
247 return r < 0 ? r : -EIO; 265 return r < 0 ? r : -EIO;
248} 266}
249 267
250static int panel_dvi_read_edid(struct omap_dss_device *dssdev, 268static int tfp410_read_edid(struct omap_dss_device *dssdev,
251 u8 *edid, int len) 269 u8 *edid, int len)
252{ 270{
253 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 271 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
254 struct panel_dvi_platform_data *pdata = get_pdata(dssdev); 272 struct tfp410_platform_data *pdata = get_pdata(dssdev);
255 struct i2c_adapter *adapter; 273 struct i2c_adapter *adapter;
256 int r, l, bytes_read; 274 int r, l, bytes_read;
257 275
@@ -271,7 +289,7 @@ static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
271 } 289 }
272 290
273 l = min(EDID_LENGTH, len); 291 l = min(EDID_LENGTH, len);
274 r = panel_dvi_ddc_read(adapter, edid, l, 0); 292 r = tfp410_ddc_read(adapter, edid, l, 0);
275 if (r) 293 if (r)
276 goto err; 294 goto err;
277 295
@@ -281,7 +299,7 @@ static int panel_dvi_read_edid(struct omap_dss_device *dssdev,
281 if (len > EDID_LENGTH && edid[0x7e] > 0) { 299 if (len > EDID_LENGTH && edid[0x7e] > 0) {
282 l = min(EDID_LENGTH, len - EDID_LENGTH); 300 l = min(EDID_LENGTH, len - EDID_LENGTH);
283 301
284 r = panel_dvi_ddc_read(adapter, edid + EDID_LENGTH, 302 r = tfp410_ddc_read(adapter, edid + EDID_LENGTH,
285 l, EDID_LENGTH); 303 l, EDID_LENGTH);
286 if (r) 304 if (r)
287 goto err; 305 goto err;
@@ -298,10 +316,10 @@ err:
298 return r; 316 return r;
299} 317}
300 318
301static bool panel_dvi_detect(struct omap_dss_device *dssdev) 319static bool tfp410_detect(struct omap_dss_device *dssdev)
302{ 320{
303 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); 321 struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev);
304 struct panel_dvi_platform_data *pdata = get_pdata(dssdev); 322 struct tfp410_platform_data *pdata = get_pdata(dssdev);
305 struct i2c_adapter *adapter; 323 struct i2c_adapter *adapter;
306 unsigned char out; 324 unsigned char out;
307 int r; 325 int r;
@@ -315,7 +333,7 @@ static bool panel_dvi_detect(struct omap_dss_device *dssdev)
315 if (!adapter) 333 if (!adapter)
316 goto out; 334 goto out;
317 335
318 r = panel_dvi_ddc_read(adapter, &out, 1, 0); 336 r = tfp410_ddc_read(adapter, &out, 1, 0);
319 337
320 mutex_unlock(&ddata->lock); 338 mutex_unlock(&ddata->lock);
321 339
@@ -326,38 +344,38 @@ out:
326 return true; 344 return true;
327} 345}
328 346
329static struct omap_dss_driver panel_dvi_driver = { 347static struct omap_dss_driver tfp410_driver = {
330 .probe = panel_dvi_probe, 348 .probe = tfp410_probe,
331 .remove = __exit_p(panel_dvi_remove), 349 .remove = __exit_p(tfp410_remove),
332 350
333 .enable = panel_dvi_enable, 351 .enable = tfp410_enable,
334 .disable = panel_dvi_disable, 352 .disable = tfp410_disable,
335 .suspend = panel_dvi_suspend, 353 .suspend = tfp410_suspend,
336 .resume = panel_dvi_resume, 354 .resume = tfp410_resume,
337 355
338 .set_timings = panel_dvi_set_timings, 356 .set_timings = tfp410_set_timings,
339 .get_timings = panel_dvi_get_timings, 357 .get_timings = tfp410_get_timings,
340 .check_timings = panel_dvi_check_timings, 358 .check_timings = tfp410_check_timings,
341 359
342 .read_edid = panel_dvi_read_edid, 360 .read_edid = tfp410_read_edid,
343 .detect = panel_dvi_detect, 361 .detect = tfp410_detect,
344 362
345 .driver = { 363 .driver = {
346 .name = "dvi", 364 .name = "tfp410",
347 .owner = THIS_MODULE, 365 .owner = THIS_MODULE,
348 }, 366 },
349}; 367};
350 368
351static int __init panel_dvi_init(void) 369static int __init tfp410_init(void)
352{ 370{
353 return omap_dss_register_driver(&panel_dvi_driver); 371 return omap_dss_register_driver(&tfp410_driver);
354} 372}
355 373
356static void __exit panel_dvi_exit(void) 374static void __exit tfp410_exit(void)
357{ 375{
358 omap_dss_unregister_driver(&panel_dvi_driver); 376 omap_dss_unregister_driver(&tfp410_driver);
359} 377}
360 378
361module_init(panel_dvi_init); 379module_init(tfp410_init);
362module_exit(panel_dvi_exit); 380module_exit(tfp410_exit);
363MODULE_LICENSE("GPL"); 381MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 662d14f8c2c3..210a3c4f6150 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2076,65 +2076,6 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
2076 } 2076 }
2077} 2077}
2078 2078
2079static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
2080{
2081 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
2082 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2083 u8 lanes[DSI_MAX_NR_LANES];
2084 u8 polarities[DSI_MAX_NR_LANES];
2085 int num_lanes, i;
2086
2087 static const enum dsi_lane_function functions[] = {
2088 DSI_LANE_CLK,
2089 DSI_LANE_DATA1,
2090 DSI_LANE_DATA2,
2091 DSI_LANE_DATA3,
2092 DSI_LANE_DATA4,
2093 };
2094
2095 lanes[0] = dssdev->phy.dsi.clk_lane;
2096 lanes[1] = dssdev->phy.dsi.data1_lane;
2097 lanes[2] = dssdev->phy.dsi.data2_lane;
2098 lanes[3] = dssdev->phy.dsi.data3_lane;
2099 lanes[4] = dssdev->phy.dsi.data4_lane;
2100 polarities[0] = dssdev->phy.dsi.clk_pol;
2101 polarities[1] = dssdev->phy.dsi.data1_pol;
2102 polarities[2] = dssdev->phy.dsi.data2_pol;
2103 polarities[3] = dssdev->phy.dsi.data3_pol;
2104 polarities[4] = dssdev->phy.dsi.data4_pol;
2105
2106 num_lanes = 0;
2107
2108 for (i = 0; i < dsi->num_lanes_supported; ++i)
2109 dsi->lanes[i].function = DSI_LANE_UNUSED;
2110
2111 for (i = 0; i < dsi->num_lanes_supported; ++i) {
2112 int num;
2113
2114 if (lanes[i] == DSI_LANE_UNUSED)
2115 break;
2116
2117 num = lanes[i] - 1;
2118
2119 if (num >= dsi->num_lanes_supported)
2120 return -EINVAL;
2121
2122 if (dsi->lanes[num].function != DSI_LANE_UNUSED)
2123 return -EINVAL;
2124
2125 dsi->lanes[num].function = functions[i];
2126 dsi->lanes[num].polarity = polarities[i];
2127 num_lanes++;
2128 }
2129
2130 if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported)
2131 return -EINVAL;
2132
2133 dsi->num_lanes_used = num_lanes;
2134
2135 return 0;
2136}
2137
2138static int dsi_set_lane_config(struct omap_dss_device *dssdev) 2079static int dsi_set_lane_config(struct omap_dss_device *dssdev)
2139{ 2080{
2140 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 2081 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -3975,6 +3916,74 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
3975 } 3916 }
3976} 3917}
3977 3918
3919int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
3920 const struct omap_dsi_pin_config *pin_cfg)
3921{
3922 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3923 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3924 int num_pins;
3925 const int *pins;
3926 struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
3927 int num_lanes;
3928 int i;
3929
3930 static const enum dsi_lane_function functions[] = {
3931 DSI_LANE_CLK,
3932 DSI_LANE_DATA1,
3933 DSI_LANE_DATA2,
3934 DSI_LANE_DATA3,
3935 DSI_LANE_DATA4,
3936 };
3937
3938 num_pins = pin_cfg->num_pins;
3939 pins = pin_cfg->pins;
3940
3941 if (num_pins < 4 || num_pins > dsi->num_lanes_supported * 2
3942 || num_pins % 2 != 0)
3943 return -EINVAL;
3944
3945 for (i = 0; i < DSI_MAX_NR_LANES; ++i)
3946 lanes[i].function = DSI_LANE_UNUSED;
3947
3948 num_lanes = 0;
3949
3950 for (i = 0; i < num_pins; i += 2) {
3951 u8 lane, pol;
3952 int dx, dy;
3953
3954 dx = pins[i];
3955 dy = pins[i + 1];
3956
3957 if (dx < 0 || dx >= dsi->num_lanes_supported * 2)
3958 return -EINVAL;
3959
3960 if (dy < 0 || dy >= dsi->num_lanes_supported * 2)
3961 return -EINVAL;
3962
3963 if (dx & 1) {
3964 if (dy != dx - 1)
3965 return -EINVAL;
3966 pol = 1;
3967 } else {
3968 if (dy != dx + 1)
3969 return -EINVAL;
3970 pol = 0;
3971 }
3972
3973 lane = dx / 2;
3974
3975 lanes[lane].function = functions[i / 2];
3976 lanes[lane].polarity = pol;
3977 num_lanes++;
3978 }
3979
3980 memcpy(dsi->lanes, lanes, sizeof(dsi->lanes));
3981 dsi->num_lanes_used = num_lanes;
3982
3983 return 0;
3984}
3985EXPORT_SYMBOL(omapdss_dsi_configure_pins);
3986
3978int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) 3987int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
3979{ 3988{
3980 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 3989 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
@@ -4339,12 +4348,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4339 int dsi_module = dsi_get_dsidev_id(dsidev); 4348 int dsi_module = dsi_get_dsidev_id(dsidev);
4340 int r; 4349 int r;
4341 4350
4342 r = dsi_parse_lane_config(dssdev);
4343 if (r) {
4344 DSSERR("illegal lane config");
4345 goto err0;
4346 }
4347
4348 r = dsi_pll_init(dsidev, true, true); 4351 r = dsi_pll_init(dsidev, true, true);
4349 if (r) 4352 if (r)
4350 goto err0; 4353 goto err0;