diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 13:24:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-07 13:24:18 -0400 |
commit | e5744abb2fa3629aa5a94e21ca1eae32ff2fe00b (patch) | |
tree | ef90c96390256b073f5255d224aecb2fc1f6ee84 /drivers/mfd | |
parent | c29aa153ef0469cddf0146d41ce6494bd76be78b (diff) | |
parent | 2d28ca731b9bb6262f7711241628c7844b0cf7dc (diff) |
Merge tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"Changes to existing drivers:
- Use of managed resources - omap, twl4030, ti_am335x_tscadc
- Advanced error handling - omap
- Rework clk management - omap
- Device Tree (re-)work - tc3589x, pm8921, da9055, sec
- IRC management overhaul and !BROKEN - pm8921
- Convert to regmap - ssbi, pm8921
- Use simple power-management ops - ucb1x00
- Include file clean-up - adp5520, cs5535, janz, lpc_ich,
- lpc_sch, max14577, mcp-sa11x0, pcf50633-adc, rc5t583,
rdc321x-southbridge, retu, smsc-ece1099, ti-ssp, ti_am335x_tscadc,
tps65912, vexpress-config, wm8350, ywm8350
- Various bug fixes across the subsystem
- NULL/invalid pointer dereference prevention
- Resource leak mitigation,
- Variable used initialised
- Staticise various containers
- Enforce return value checks
New drivers/supported devices:
- Add support for s2mps14 and s2mpa01 to sec
- Add support for da9063 (v5) to da9063
- Add support for atom-c2000 to gpio-ich
- Add support for come-{mbt10,cbt6,chl6} to kempld
- Add support for da9053 to da9052
- Add support for itco-wdt (v3) and baytrail to lpc_ich
- Add new drivers for tps65218, rtsx_usb, bcm590xx
(Re-)moved drivers:
- twl4030 ==> drivers/iio
- ti-ssp ==> /dev/null"
* tag 'mfd-for-linus-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (103 commits)
mfd: wm5110: Correct default for HEADPHONE_DETECT_1
mfd: arizona: Correct small errors in the DT binding documentation
mfd: arizona: Mark DSP clocking register as volatile
mfd: devicetree: bindings: Add pm8xxx RTC description
mfd: kempld-core: Fix potential hang-up during boot
mfd: sec-core: Fix uninitialized 'regmap_rtc' on S2MPA01
mfd: tps65910: Fix regmap_irq_chip_data leak on mfd_add_devices fail
mfd: tps65910: Fix possible invalid pointer dereference on regmap_add_irq_chip fail
mfd: sec-core: Fix I2C dummy device resource leak on probe failure
mfd: sec-core: Add of_compatible strings for clock MFD cells
mfd: Remove obsolete ti-ssp driver
Documentation: mfd: s2mps11: Describe S5M8767 and S2MPS14 clocks
mfd: bcm590xx: Fix type argument for module device table
mfd: lpc_ich: Add support for Intel Bay Trail SoC
mfd: lpc_ich: Add support for NM10 GPIO
mfd: lpc_ich: Change Avoton to iTCO v3
watchdog: iTCO_wdt: Add support for v3 silicon
mfd: lpc_ich: Add support for iTCO v3
mfd: lpc_ich: Remove lpc_ich_cfg struct use
mfd: lpc_ich: Only configure watchdog or GPIO when present
...
Diffstat (limited to 'drivers/mfd')
60 files changed, 2197 insertions, 2022 deletions
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index 7dca1e640970..841717a2842c 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c | |||
@@ -571,7 +571,7 @@ static int pm800_probe(struct i2c_client *client, | |||
571 | ret = pm800_pages_init(chip); | 571 | ret = pm800_pages_init(chip); |
572 | if (ret) { | 572 | if (ret) { |
573 | dev_err(&client->dev, "pm800_pages_init failed!\n"); | 573 | dev_err(&client->dev, "pm800_pages_init failed!\n"); |
574 | goto err_page_init; | 574 | goto err_device_init; |
575 | } | 575 | } |
576 | 576 | ||
577 | ret = device_800_init(chip, pdata); | 577 | ret = device_800_init(chip, pdata); |
@@ -587,7 +587,6 @@ static int pm800_probe(struct i2c_client *client, | |||
587 | 587 | ||
588 | err_device_init: | 588 | err_device_init: |
589 | pm800_pages_exit(chip); | 589 | pm800_pages_exit(chip); |
590 | err_page_init: | ||
591 | err_subchip_alloc: | 590 | err_subchip_alloc: |
592 | pm80x_deinit(); | 591 | pm80x_deinit(); |
593 | out_init: | 592 | out_init: |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index c9b1f6422941..bcfc9e85b4a0 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -1179,12 +1179,18 @@ static int pm860x_probe(struct i2c_client *client, | |||
1179 | chip->companion_addr = pdata->companion_addr; | 1179 | chip->companion_addr = pdata->companion_addr; |
1180 | chip->companion = i2c_new_dummy(chip->client->adapter, | 1180 | chip->companion = i2c_new_dummy(chip->client->adapter, |
1181 | chip->companion_addr); | 1181 | chip->companion_addr); |
1182 | if (!chip->companion) { | ||
1183 | dev_err(&client->dev, | ||
1184 | "Failed to allocate I2C companion device\n"); | ||
1185 | return -ENODEV; | ||
1186 | } | ||
1182 | chip->regmap_companion = regmap_init_i2c(chip->companion, | 1187 | chip->regmap_companion = regmap_init_i2c(chip->companion, |
1183 | &pm860x_regmap_config); | 1188 | &pm860x_regmap_config); |
1184 | if (IS_ERR(chip->regmap_companion)) { | 1189 | if (IS_ERR(chip->regmap_companion)) { |
1185 | ret = PTR_ERR(chip->regmap_companion); | 1190 | ret = PTR_ERR(chip->regmap_companion); |
1186 | dev_err(&chip->companion->dev, | 1191 | dev_err(&chip->companion->dev, |
1187 | "Failed to allocate register map: %d\n", ret); | 1192 | "Failed to allocate register map: %d\n", ret); |
1193 | i2c_unregister_device(chip->companion); | ||
1188 | return ret; | 1194 | return ret; |
1189 | } | 1195 | } |
1190 | i2c_set_clientdata(chip->companion, chip); | 1196 | i2c_set_clientdata(chip->companion, chip); |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 49bb445d846a..33834120d057 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -59,6 +59,14 @@ config MFD_AAT2870_CORE | |||
59 | additional drivers must be enabled in order to use the | 59 | additional drivers must be enabled in order to use the |
60 | functionality of the device. | 60 | functionality of the device. |
61 | 61 | ||
62 | config MFD_BCM590XX | ||
63 | tristate "Broadcom BCM590xx PMUs" | ||
64 | select MFD_CORE | ||
65 | select REGMAP_I2C | ||
66 | depends on I2C | ||
67 | help | ||
68 | Support for the BCM590xx PMUs from Broadcom | ||
69 | |||
62 | config MFD_CROS_EC | 70 | config MFD_CROS_EC |
63 | tristate "ChromeOS Embedded Controller" | 71 | tristate "ChromeOS Embedded Controller" |
64 | select MFD_CORE | 72 | select MFD_CORE |
@@ -100,7 +108,7 @@ config PMIC_DA903X | |||
100 | bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" | 108 | bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" |
101 | depends on I2C=y | 109 | depends on I2C=y |
102 | help | 110 | help |
103 | Say yes here to support for Dialog Semiconductor DA9030 (a.k.a | 111 | Say yes here to add support for Dialog Semiconductor DA9030 (a.k.a |
104 | ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC | 112 | ARAVA) and DA9034 (a.k.a MICCO), these are Power Management IC |
105 | usually found on PXA processors-based platforms. This includes | 113 | usually found on PXA processors-based platforms. This includes |
106 | the I2C driver and the core APIs _only_, you have to select | 114 | the I2C driver and the core APIs _only_, you have to select |
@@ -270,13 +278,18 @@ config MFD_KEMPLD | |||
270 | device may provide functions like watchdog, GPIO, UART and I2C bus. | 278 | device may provide functions like watchdog, GPIO, UART and I2C bus. |
271 | 279 | ||
272 | The following modules are supported: | 280 | The following modules are supported: |
281 | * COMe-bHL6 | ||
273 | * COMe-bIP# | 282 | * COMe-bIP# |
274 | * COMe-bPC2 (ETXexpress-PC) | 283 | * COMe-bPC2 (ETXexpress-PC) |
275 | * COMe-bSC# (ETXexpress-SC T#) | 284 | * COMe-bSC# (ETXexpress-SC T#) |
285 | * COMe-cBT6 | ||
276 | * COMe-cCT6 | 286 | * COMe-cCT6 |
277 | * COMe-cDC2 (microETXexpress-DC) | 287 | * COMe-cDC2 (microETXexpress-DC) |
288 | * COMe-cHL6 | ||
278 | * COMe-cPC2 (microETXexpress-PC) | 289 | * COMe-cPC2 (microETXexpress-PC) |
290 | * COMe-mBT10 | ||
279 | * COMe-mCT10 | 291 | * COMe-mCT10 |
292 | * COMe-mTT10 (nanoETXexpress-TT) | ||
280 | * ETX-OH | 293 | * ETX-OH |
281 | 294 | ||
282 | This driver can also be built as a module. If so, the module | 295 | This driver can also be built as a module. If so, the module |
@@ -322,9 +335,10 @@ config MFD_MAX14577 | |||
322 | depends on I2C=y | 335 | depends on I2C=y |
323 | select MFD_CORE | 336 | select MFD_CORE |
324 | select REGMAP_I2C | 337 | select REGMAP_I2C |
338 | select REGMAP_IRQ | ||
325 | select IRQ_DOMAIN | 339 | select IRQ_DOMAIN |
326 | help | 340 | help |
327 | Say yes here to support for Maxim Semiconductor MAX14577. | 341 | Say yes here to add support for Maxim Semiconductor MAX14577. |
328 | This is a Micro-USB IC with Charger controls on chip. | 342 | This is a Micro-USB IC with Charger controls on chip. |
329 | This driver provides common support for accessing the device; | 343 | This driver provides common support for accessing the device; |
330 | additional drivers must be enabled in order to use the functionality | 344 | additional drivers must be enabled in order to use the functionality |
@@ -337,7 +351,7 @@ config MFD_MAX77686 | |||
337 | select REGMAP_I2C | 351 | select REGMAP_I2C |
338 | select IRQ_DOMAIN | 352 | select IRQ_DOMAIN |
339 | help | 353 | help |
340 | Say yes here to support for Maxim Semiconductor MAX77686. | 354 | Say yes here to add support for Maxim Semiconductor MAX77686. |
341 | This is a Power Management IC with RTC on chip. | 355 | This is a Power Management IC with RTC on chip. |
342 | This driver provides common support for accessing the device; | 356 | This driver provides common support for accessing the device; |
343 | additional drivers must be enabled in order to use the functionality | 357 | additional drivers must be enabled in order to use the functionality |
@@ -349,7 +363,7 @@ config MFD_MAX77693 | |||
349 | select MFD_CORE | 363 | select MFD_CORE |
350 | select REGMAP_I2C | 364 | select REGMAP_I2C |
351 | help | 365 | help |
352 | Say yes here to support for Maxim Semiconductor MAX77693. | 366 | Say yes here to add support for Maxim Semiconductor MAX77693. |
353 | This is a companion Power Management IC with Flash, Haptic, Charger, | 367 | This is a companion Power Management IC with Flash, Haptic, Charger, |
354 | and MUIC(Micro USB Interface Controller) controls on chip. | 368 | and MUIC(Micro USB Interface Controller) controls on chip. |
355 | This driver provides common support for accessing the device; | 369 | This driver provides common support for accessing the device; |
@@ -363,7 +377,7 @@ config MFD_MAX8907 | |||
363 | select REGMAP_I2C | 377 | select REGMAP_I2C |
364 | select REGMAP_IRQ | 378 | select REGMAP_IRQ |
365 | help | 379 | help |
366 | Say yes here to support for Maxim Semiconductor MAX8907. This is | 380 | Say yes here to add support for Maxim Semiconductor MAX8907. This is |
367 | a Power Management IC. This driver provides common support for | 381 | a Power Management IC. This driver provides common support for |
368 | accessing the device; additional drivers must be enabled in order | 382 | accessing the device; additional drivers must be enabled in order |
369 | to use the functionality of the device. | 383 | to use the functionality of the device. |
@@ -373,7 +387,7 @@ config MFD_MAX8925 | |||
373 | depends on I2C=y | 387 | depends on I2C=y |
374 | select MFD_CORE | 388 | select MFD_CORE |
375 | help | 389 | help |
376 | Say yes here to support for Maxim Semiconductor MAX8925. This is | 390 | Say yes here to add support for Maxim Semiconductor MAX8925. This is |
377 | a Power Management IC. This driver provides common support for | 391 | a Power Management IC. This driver provides common support for |
378 | accessing the device, additional drivers must be enabled in order | 392 | accessing the device, additional drivers must be enabled in order |
379 | to use the functionality of the device. | 393 | to use the functionality of the device. |
@@ -384,7 +398,7 @@ config MFD_MAX8997 | |||
384 | select MFD_CORE | 398 | select MFD_CORE |
385 | select IRQ_DOMAIN | 399 | select IRQ_DOMAIN |
386 | help | 400 | help |
387 | Say yes here to support for Maxim Semiconductor MAX8997/8966. | 401 | Say yes here to add support for Maxim Semiconductor MAX8997/8966. |
388 | This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic, | 402 | This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic, |
389 | MUIC controls on chip. | 403 | MUIC controls on chip. |
390 | This driver provides common support for accessing the device; | 404 | This driver provides common support for accessing the device; |
@@ -397,7 +411,7 @@ config MFD_MAX8998 | |||
397 | select MFD_CORE | 411 | select MFD_CORE |
398 | select IRQ_DOMAIN | 412 | select IRQ_DOMAIN |
399 | help | 413 | help |
400 | Say yes here to support for Maxim Semiconductor MAX8998 and | 414 | Say yes here to add support for Maxim Semiconductor MAX8998 and |
401 | National Semiconductor LP3974. This is a Power Management IC. | 415 | National Semiconductor LP3974. This is a Power Management IC. |
402 | This driver provides common support for accessing the device, | 416 | This driver provides common support for accessing the device, |
403 | additional drivers must be enabled in order to use the functionality | 417 | additional drivers must be enabled in order to use the functionality |
@@ -473,10 +487,11 @@ config MFD_PM8XXX | |||
473 | 487 | ||
474 | config MFD_PM8921_CORE | 488 | config MFD_PM8921_CORE |
475 | tristate "Qualcomm PM8921 PMIC chip" | 489 | tristate "Qualcomm PM8921 PMIC chip" |
476 | depends on (ARCH_MSM || HEXAGON) | 490 | depends on (ARM || HEXAGON) |
477 | depends on BROKEN | 491 | select IRQ_DOMAIN |
478 | select MFD_CORE | 492 | select MFD_CORE |
479 | select MFD_PM8XXX | 493 | select MFD_PM8XXX |
494 | select REGMAP | ||
480 | help | 495 | help |
481 | If you say yes to this option, support will be included for the | 496 | If you say yes to this option, support will be included for the |
482 | built-in PM8921 PMIC chip. | 497 | built-in PM8921 PMIC chip. |
@@ -487,16 +502,6 @@ config MFD_PM8921_CORE | |||
487 | Say M here if you want to include support for PM8921 chip as a module. | 502 | Say M here if you want to include support for PM8921 chip as a module. |
488 | This will build a module called "pm8921-core". | 503 | This will build a module called "pm8921-core". |
489 | 504 | ||
490 | config MFD_PM8XXX_IRQ | ||
491 | bool "Qualcomm PM8xxx IRQ features" | ||
492 | depends on MFD_PM8XXX | ||
493 | default y if MFD_PM8XXX | ||
494 | help | ||
495 | This is the IRQ driver for Qualcomm PM 8xxx PMIC chips. | ||
496 | |||
497 | This is required to use certain other PM 8xxx features, such as GPIO | ||
498 | and MPP. | ||
499 | |||
500 | config MFD_RDC321X | 505 | config MFD_RDC321X |
501 | tristate "RDC R-321x southbridge" | 506 | tristate "RDC R-321x southbridge" |
502 | select MFD_CORE | 507 | select MFD_CORE |
@@ -516,6 +521,16 @@ config MFD_RTSX_PCI | |||
516 | types of memory cards, such as Memory Stick, Memory Stick Pro, | 521 | types of memory cards, such as Memory Stick, Memory Stick Pro, |
517 | Secure Digital and MultiMediaCard. | 522 | Secure Digital and MultiMediaCard. |
518 | 523 | ||
524 | config MFD_RTSX_USB | ||
525 | tristate "Realtek USB card reader" | ||
526 | depends on USB | ||
527 | select MFD_CORE | ||
528 | help | ||
529 | Select this option to get support for Realtek USB 2.0 card readers | ||
530 | including RTS5129, RTS5139, RTS5179 and RTS5170. | ||
531 | Realtek card reader supports access to many types of memory cards, | ||
532 | such as Memory Stick Pro, Secure Digital and MultiMediaCard. | ||
533 | |||
519 | config MFD_RC5T583 | 534 | config MFD_RC5T583 |
520 | bool "Ricoh RC5T583 Power Management system device" | 535 | bool "Ricoh RC5T583 Power Management system device" |
521 | depends on I2C=y | 536 | depends on I2C=y |
@@ -774,17 +789,6 @@ config MFD_PALMAS | |||
774 | If you say yes here you get support for the Palmas | 789 | If you say yes here you get support for the Palmas |
775 | series of PMIC chips from Texas Instruments. | 790 | series of PMIC chips from Texas Instruments. |
776 | 791 | ||
777 | config MFD_TI_SSP | ||
778 | tristate "TI Sequencer Serial Port support" | ||
779 | depends on ARCH_DAVINCI_TNETV107X | ||
780 | select MFD_CORE | ||
781 | ---help--- | ||
782 | Say Y here if you want support for the Sequencer Serial Port | ||
783 | in a Texas Instruments TNETV107X SoC. | ||
784 | |||
785 | To compile this driver as a module, choose M here: the | ||
786 | module will be called ti-ssp. | ||
787 | |||
788 | config TPS6105X | 792 | config TPS6105X |
789 | tristate "TI TPS61050/61052 Boost Converters" | 793 | tristate "TI TPS61050/61052 Boost Converters" |
790 | depends on I2C | 794 | depends on I2C |
@@ -853,6 +857,22 @@ config MFD_TPS65217 | |||
853 | This driver can also be built as a module. If so, the module | 857 | This driver can also be built as a module. If so, the module |
854 | will be called tps65217. | 858 | will be called tps65217. |
855 | 859 | ||
860 | config MFD_TPS65218 | ||
861 | tristate "TI TPS65218 Power Management chips" | ||
862 | depends on I2C | ||
863 | select MFD_CORE | ||
864 | select REGMAP_I2C | ||
865 | select REGMAP_IRQ | ||
866 | help | ||
867 | If you say yes here you get support for the TPS65218 series of | ||
868 | Power Management chips. | ||
869 | These include voltage regulators, gpio and other features | ||
870 | that are often used in portable devices. Only regulator | ||
871 | component is currently supported. | ||
872 | |||
873 | This driver can also be built as a module. If so, the module | ||
874 | will be called tps65218. | ||
875 | |||
856 | config MFD_TPS6586X | 876 | config MFD_TPS6586X |
857 | bool "TI TPS6586x Power Management chips" | 877 | bool "TI TPS6586x Power Management chips" |
858 | depends on I2C=y | 878 | depends on I2C=y |
@@ -935,16 +955,6 @@ config TWL4030_CORE | |||
935 | high speed USB OTG transceiver, an audio codec (on most | 955 | high speed USB OTG transceiver, an audio codec (on most |
936 | versions) and many other features. | 956 | versions) and many other features. |
937 | 957 | ||
938 | config TWL4030_MADC | ||
939 | tristate "TI TWL4030 MADC" | ||
940 | depends on TWL4030_CORE | ||
941 | help | ||
942 | This driver provides support for triton TWL4030-MADC. The | ||
943 | driver supports both RT and SW conversion methods. | ||
944 | |||
945 | This driver can be built as a module. If so it will be | ||
946 | named twl4030-madc | ||
947 | |||
948 | config TWL4030_POWER | 958 | config TWL4030_POWER |
949 | bool "TI TWL4030 power resources" | 959 | bool "TI TWL4030 power resources" |
950 | depends on TWL4030_CORE && ARM | 960 | depends on TWL4030_CORE && ARM |
@@ -1193,9 +1203,6 @@ config MFD_STW481X | |||
1193 | in various ST Microelectronics and ST-Ericsson embedded | 1203 | in various ST Microelectronics and ST-Ericsson embedded |
1194 | Nomadik series. | 1204 | Nomadik series. |
1195 | 1205 | ||
1196 | endmenu | ||
1197 | endif | ||
1198 | |||
1199 | menu "Multimedia Capabilities Port drivers" | 1206 | menu "Multimedia Capabilities Port drivers" |
1200 | depends on ARCH_SA1100 | 1207 | depends on ARCH_SA1100 |
1201 | 1208 | ||
@@ -1226,3 +1233,6 @@ config VEXPRESS_CONFIG | |||
1226 | help | 1233 | help |
1227 | Platform configuration infrastructure for the ARM Ltd. | 1234 | Platform configuration infrastructure for the ARM Ltd. |
1228 | Versatile Express. | 1235 | Versatile Express. |
1236 | |||
1237 | endmenu | ||
1238 | endif | ||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 5aea5ef0a62f..2851275e2656 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -8,12 +8,14 @@ obj-$(CONFIG_MFD_88PM800) += 88pm800.o 88pm80x.o | |||
8 | obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o | 8 | obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o |
9 | obj-$(CONFIG_MFD_SM501) += sm501.o | 9 | obj-$(CONFIG_MFD_SM501) += sm501.o |
10 | obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o | 10 | obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o |
11 | obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o | ||
11 | obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o | 12 | obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o |
12 | obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o | 13 | obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o |
13 | obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o | 14 | obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o |
14 | 15 | ||
15 | rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o | 16 | rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o |
16 | obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o | 17 | obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o |
18 | obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o | ||
17 | 19 | ||
18 | obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o | 20 | obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o |
19 | obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o | 21 | obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o |
@@ -21,7 +23,6 @@ obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o | |||
21 | 23 | ||
22 | obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o | 24 | obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o |
23 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o | 25 | obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o |
24 | obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o | ||
25 | obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o | 26 | obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o |
26 | 27 | ||
27 | obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o | 28 | obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o |
@@ -62,6 +63,7 @@ obj-$(CONFIG_TPS6105X) += tps6105x.o | |||
62 | obj-$(CONFIG_TPS65010) += tps65010.o | 63 | obj-$(CONFIG_TPS65010) += tps65010.o |
63 | obj-$(CONFIG_TPS6507X) += tps6507x.o | 64 | obj-$(CONFIG_TPS6507X) += tps6507x.o |
64 | obj-$(CONFIG_MFD_TPS65217) += tps65217.o | 65 | obj-$(CONFIG_MFD_TPS65217) += tps65217.o |
66 | obj-$(CONFIG_MFD_TPS65218) += tps65218.o | ||
65 | obj-$(CONFIG_MFD_TPS65910) += tps65910.o | 67 | obj-$(CONFIG_MFD_TPS65910) += tps65910.o |
66 | tps65912-objs := tps65912-core.o tps65912-irq.o | 68 | tps65912-objs := tps65912-core.o tps65912-irq.o |
67 | obj-$(CONFIG_MFD_TPS65912) += tps65912.o | 69 | obj-$(CONFIG_MFD_TPS65912) += tps65912.o |
@@ -71,7 +73,6 @@ obj-$(CONFIG_MFD_TPS80031) += tps80031.o | |||
71 | obj-$(CONFIG_MENELAUS) += menelaus.o | 73 | obj-$(CONFIG_MENELAUS) += menelaus.o |
72 | 74 | ||
73 | obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o | 75 | obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o |
74 | obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o | ||
75 | obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o | 76 | obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o |
76 | obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o | 77 | obj-$(CONFIG_MFD_TWL4030_AUDIO) += twl4030-audio.o |
77 | obj-$(CONFIG_TWL6040_CORE) += twl6040.o | 78 | obj-$(CONFIG_TWL6040_CORE) += twl6040.o |
@@ -150,7 +151,6 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o | |||
150 | obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o | 151 | obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o |
151 | obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o | 152 | obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o |
152 | obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o | 153 | obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o |
153 | obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o | ||
154 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o | 154 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o |
155 | obj-$(CONFIG_MFD_TPS65090) += tps65090.o | 155 | obj-$(CONFIG_MFD_TPS65090) += tps65090.o |
156 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o | 156 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o |
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index 62501553d63c..f495b8b57dd7 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/init.h> | ||
24 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
25 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
26 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c index c71ff0af1547..39fa554f13bb 100644 --- a/drivers/mfd/as3722.c +++ b/drivers/mfd/as3722.c | |||
@@ -277,6 +277,7 @@ static const struct regmap_range as3722_readable_ranges[] = { | |||
277 | regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG), | 277 | regmap_reg_range(AS3722_ADC0_CONTROL_REG, AS3722_ADC_CONFIGURATION_REG), |
278 | regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG), | 278 | regmap_reg_range(AS3722_ASIC_ID1_REG, AS3722_ASIC_ID2_REG), |
279 | regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG), | 279 | regmap_reg_range(AS3722_LOCK_REG, AS3722_LOCK_REG), |
280 | regmap_reg_range(AS3722_FUSE7_REG, AS3722_FUSE7_REG), | ||
280 | }; | 281 | }; |
281 | 282 | ||
282 | static const struct regmap_access_table as3722_readable_table = { | 283 | static const struct regmap_access_table as3722_readable_table = { |
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c new file mode 100644 index 000000000000..e9a33c79431b --- /dev/null +++ b/drivers/mfd/bcm590xx.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * Broadcom BCM590xx PMU | ||
3 | * | ||
4 | * Copyright 2014 Linaro Limited | ||
5 | * Author: Matt Porter <mporter@linaro.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/err.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/mfd/bcm590xx.h> | ||
17 | #include <linux/mfd/core.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/moduleparam.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_device.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | static const struct mfd_cell bcm590xx_devs[] = { | ||
26 | { | ||
27 | .name = "bcm590xx-vregs", | ||
28 | }, | ||
29 | }; | ||
30 | |||
31 | static const struct regmap_config bcm590xx_regmap_config = { | ||
32 | .reg_bits = 8, | ||
33 | .val_bits = 8, | ||
34 | .max_register = BCM590XX_MAX_REGISTER, | ||
35 | .cache_type = REGCACHE_RBTREE, | ||
36 | }; | ||
37 | |||
38 | static int bcm590xx_i2c_probe(struct i2c_client *i2c, | ||
39 | const struct i2c_device_id *id) | ||
40 | { | ||
41 | struct bcm590xx *bcm590xx; | ||
42 | int ret; | ||
43 | |||
44 | bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL); | ||
45 | if (!bcm590xx) | ||
46 | return -ENOMEM; | ||
47 | |||
48 | i2c_set_clientdata(i2c, bcm590xx); | ||
49 | bcm590xx->dev = &i2c->dev; | ||
50 | bcm590xx->i2c_client = i2c; | ||
51 | |||
52 | bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config); | ||
53 | if (IS_ERR(bcm590xx->regmap)) { | ||
54 | ret = PTR_ERR(bcm590xx->regmap); | ||
55 | dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret); | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs, | ||
60 | ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL); | ||
61 | if (ret < 0) | ||
62 | dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | static const struct of_device_id bcm590xx_of_match[] = { | ||
68 | { .compatible = "brcm,bcm59056" }, | ||
69 | { } | ||
70 | }; | ||
71 | MODULE_DEVICE_TABLE(of, bcm590xx_of_match); | ||
72 | |||
73 | static const struct i2c_device_id bcm590xx_i2c_id[] = { | ||
74 | { "bcm59056" }, | ||
75 | { } | ||
76 | }; | ||
77 | MODULE_DEVICE_TABLE(i2c, bcm590xx_i2c_id); | ||
78 | |||
79 | static struct i2c_driver bcm590xx_i2c_driver = { | ||
80 | .driver = { | ||
81 | .name = "bcm590xx", | ||
82 | .owner = THIS_MODULE, | ||
83 | .of_match_table = of_match_ptr(bcm590xx_of_match), | ||
84 | }, | ||
85 | .probe = bcm590xx_i2c_probe, | ||
86 | .id_table = bcm590xx_i2c_id, | ||
87 | }; | ||
88 | module_i2c_driver(bcm590xx_i2c_driver); | ||
89 | |||
90 | MODULE_AUTHOR("Matt Porter <mporter@linaro.org>"); | ||
91 | MODULE_DESCRIPTION("BCM590xx multi-function driver"); | ||
92 | MODULE_LICENSE("GPL v2"); | ||
93 | MODULE_ALIAS("platform:bcm590xx"); | ||
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 17c13012686a..be91cb5d6e78 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -23,7 +23,6 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/init.h> | ||
27 | #include <linux/mfd/core.h> | 26 | #include <linux/mfd/core.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 25838f10b35b..e8af816d73a9 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c | |||
@@ -279,6 +279,9 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg) | |||
279 | case DA9052_EVENT_B_REG: | 279 | case DA9052_EVENT_B_REG: |
280 | case DA9052_EVENT_C_REG: | 280 | case DA9052_EVENT_C_REG: |
281 | case DA9052_EVENT_D_REG: | 281 | case DA9052_EVENT_D_REG: |
282 | case DA9052_CONTROL_B_REG: | ||
283 | case DA9052_CONTROL_D_REG: | ||
284 | case DA9052_SUPPLY_REG: | ||
282 | case DA9052_FAULTLOG_REG: | 285 | case DA9052_FAULTLOG_REG: |
283 | case DA9052_CHG_TIME_REG: | 286 | case DA9052_CHG_TIME_REG: |
284 | case DA9052_ADC_RES_L_REG: | 287 | case DA9052_ADC_RES_L_REG: |
diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index c319c4ef5d49..6da8ec8ff800 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c | |||
@@ -75,6 +75,7 @@ static int da9052_i2c_fix(struct da9052 *da9052, unsigned char reg) | |||
75 | DA9052_PARK_REGISTER, | 75 | DA9052_PARK_REGISTER, |
76 | &val); | 76 | &val); |
77 | break; | 77 | break; |
78 | case DA9053_BC: | ||
78 | default: | 79 | default: |
79 | /* | 80 | /* |
80 | * For other chips parking of I2C register | 81 | * For other chips parking of I2C register |
@@ -114,6 +115,7 @@ static const struct i2c_device_id da9052_i2c_id[] = { | |||
114 | {"da9053-aa", DA9053_AA}, | 115 | {"da9053-aa", DA9053_AA}, |
115 | {"da9053-ba", DA9053_BA}, | 116 | {"da9053-ba", DA9053_BA}, |
116 | {"da9053-bb", DA9053_BB}, | 117 | {"da9053-bb", DA9053_BB}, |
118 | {"da9053-bc", DA9053_BC}, | ||
117 | {} | 119 | {} |
118 | }; | 120 | }; |
119 | 121 | ||
@@ -121,8 +123,9 @@ static const struct i2c_device_id da9052_i2c_id[] = { | |||
121 | static const struct of_device_id dialog_dt_ids[] = { | 123 | static const struct of_device_id dialog_dt_ids[] = { |
122 | { .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] }, | 124 | { .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] }, |
123 | { .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] }, | 125 | { .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] }, |
124 | { .compatible = "dlg,da9053-ab", .data = &da9052_i2c_id[2] }, | 126 | { .compatible = "dlg,da9053-ba", .data = &da9052_i2c_id[2] }, |
125 | { .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] }, | 127 | { .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] }, |
128 | { .compatible = "dlg,da9053-bc", .data = &da9052_i2c_id[4] }, | ||
126 | { /* sentinel */ } | 129 | { /* sentinel */ } |
127 | }; | 130 | }; |
128 | #endif | 131 | #endif |
diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c index 0680bcbc53de..17666b40b70c 100644 --- a/drivers/mfd/da9052-spi.c +++ b/drivers/mfd/da9052-spi.c | |||
@@ -71,6 +71,7 @@ static struct spi_device_id da9052_spi_id[] = { | |||
71 | {"da9053-aa", DA9053_AA}, | 71 | {"da9053-aa", DA9053_AA}, |
72 | {"da9053-ba", DA9053_BA}, | 72 | {"da9053-ba", DA9053_BA}, |
73 | {"da9053-bb", DA9053_BB}, | 73 | {"da9053-bb", DA9053_BB}, |
74 | {"da9053-bc", DA9053_BC}, | ||
74 | {} | 75 | {} |
75 | }; | 76 | }; |
76 | 77 | ||
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c index 8103e4362132..d4d4c165eb95 100644 --- a/drivers/mfd/da9055-i2c.c +++ b/drivers/mfd/da9055-i2c.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
18 | 20 | ||
19 | #include <linux/mfd/da9055/core.h> | 21 | #include <linux/mfd/da9055/core.h> |
20 | 22 | ||
@@ -66,6 +68,11 @@ static struct i2c_device_id da9055_i2c_id[] = { | |||
66 | }; | 68 | }; |
67 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); | 69 | MODULE_DEVICE_TABLE(i2c, da9055_i2c_id); |
68 | 70 | ||
71 | static const struct of_device_id da9055_of_match[] = { | ||
72 | { .compatible = "dlg,da9055-pmic", }, | ||
73 | { } | ||
74 | }; | ||
75 | |||
69 | static struct i2c_driver da9055_i2c_driver = { | 76 | static struct i2c_driver da9055_i2c_driver = { |
70 | .probe = da9055_i2c_probe, | 77 | .probe = da9055_i2c_probe, |
71 | .remove = da9055_i2c_remove, | 78 | .remove = da9055_i2c_remove, |
@@ -73,6 +80,7 @@ static struct i2c_driver da9055_i2c_driver = { | |||
73 | .driver = { | 80 | .driver = { |
74 | .name = "da9055-pmic", | 81 | .name = "da9055-pmic", |
75 | .owner = THIS_MODULE, | 82 | .owner = THIS_MODULE, |
83 | .of_match_table = of_match_ptr(da9055_of_match), | ||
76 | }, | 84 | }, |
77 | }; | 85 | }; |
78 | 86 | ||
diff --git a/drivers/mfd/da9063-core.c b/drivers/mfd/da9063-core.c index 26937cd01071..e70ae315abc7 100644 --- a/drivers/mfd/da9063-core.c +++ b/drivers/mfd/da9063-core.c | |||
@@ -110,7 +110,7 @@ static const struct mfd_cell da9063_devs[] = { | |||
110 | int da9063_device_init(struct da9063 *da9063, unsigned int irq) | 110 | int da9063_device_init(struct da9063 *da9063, unsigned int irq) |
111 | { | 111 | { |
112 | struct da9063_pdata *pdata = da9063->dev->platform_data; | 112 | struct da9063_pdata *pdata = da9063->dev->platform_data; |
113 | int model, revision; | 113 | int model, variant_id, variant_code; |
114 | int ret; | 114 | int ret; |
115 | 115 | ||
116 | if (pdata) { | 116 | if (pdata) { |
@@ -141,23 +141,26 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq) | |||
141 | return -ENODEV; | 141 | return -ENODEV; |
142 | } | 142 | } |
143 | 143 | ||
144 | ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision); | 144 | ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &variant_id); |
145 | if (ret < 0) { | 145 | if (ret < 0) { |
146 | dev_err(da9063->dev, "Cannot read chip revision id.\n"); | 146 | dev_err(da9063->dev, "Cannot read chip variant id.\n"); |
147 | return -EIO; | 147 | return -EIO; |
148 | } | 148 | } |
149 | revision >>= DA9063_CHIP_VARIANT_SHIFT; | 149 | |
150 | if (revision != 3) { | 150 | variant_code = variant_id >> DA9063_CHIP_VARIANT_SHIFT; |
151 | dev_err(da9063->dev, "Unknown chip revision: %d\n", revision); | 151 | |
152 | dev_info(da9063->dev, | ||
153 | "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n", | ||
154 | model, variant_id); | ||
155 | |||
156 | if (variant_code != PMIC_DA9063_BB) { | ||
157 | dev_err(da9063->dev, "Unknown chip variant code: 0x%02X\n", | ||
158 | variant_code); | ||
152 | return -ENODEV; | 159 | return -ENODEV; |
153 | } | 160 | } |
154 | 161 | ||
155 | da9063->model = model; | 162 | da9063->model = model; |
156 | da9063->revision = revision; | 163 | da9063->variant_code = variant_code; |
157 | |||
158 | dev_info(da9063->dev, | ||
159 | "Device detected (model-ID: 0x%02X rev-ID: 0x%02X)\n", | ||
160 | model, revision); | ||
161 | 164 | ||
162 | ret = da9063_irq_init(da9063); | 165 | ret = da9063_irq_init(da9063); |
163 | if (ret) { | 166 | if (ret) { |
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 81b7d88af313..433f823037dd 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
18 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
19 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index d3e23278d299..07692604e119 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c | |||
@@ -322,9 +322,12 @@ static int kempld_detect_device(struct kempld_device_data *pld) | |||
322 | return -ENODEV; | 322 | return -ENODEV; |
323 | } | 323 | } |
324 | 324 | ||
325 | /* Release hardware mutex if aquired */ | 325 | /* Release hardware mutex if acquired */ |
326 | if (!(index_reg & KEMPLD_MUTEX_KEY)) | 326 | if (!(index_reg & KEMPLD_MUTEX_KEY)) { |
327 | iowrite8(KEMPLD_MUTEX_KEY, pld->io_index); | 327 | iowrite8(KEMPLD_MUTEX_KEY, pld->io_index); |
328 | /* PXT and COMe-cPC2 boards may require a second release */ | ||
329 | iowrite8(KEMPLD_MUTEX_KEY, pld->io_index); | ||
330 | } | ||
328 | 331 | ||
329 | mutex_unlock(&pld->lock); | 332 | mutex_unlock(&pld->lock); |
330 | 333 | ||
@@ -438,6 +441,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = { | |||
438 | .driver_data = (void *)&kempld_platform_data_generic, | 441 | .driver_data = (void *)&kempld_platform_data_generic, |
439 | .callback = kempld_create_platform_device, | 442 | .callback = kempld_create_platform_device, |
440 | }, { | 443 | }, { |
444 | .ident = "CHL6", | ||
445 | .matches = { | ||
446 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), | ||
447 | DMI_MATCH(DMI_BOARD_NAME, "COMe-cHL6"), | ||
448 | }, | ||
449 | .driver_data = (void *)&kempld_platform_data_generic, | ||
450 | .callback = kempld_create_platform_device, | ||
451 | }, { | ||
441 | .ident = "CHR2", | 452 | .ident = "CHR2", |
442 | .matches = { | 453 | .matches = { |
443 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), | 454 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), |
@@ -510,6 +521,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = { | |||
510 | .driver_data = (void *)&kempld_platform_data_generic, | 521 | .driver_data = (void *)&kempld_platform_data_generic, |
511 | .callback = kempld_create_platform_device, | 522 | .callback = kempld_create_platform_device, |
512 | }, { | 523 | }, { |
524 | .ident = "CVV6", | ||
525 | .matches = { | ||
526 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), | ||
527 | DMI_MATCH(DMI_BOARD_NAME, "COMe-cBT"), | ||
528 | }, | ||
529 | .driver_data = (void *)&kempld_platform_data_generic, | ||
530 | .callback = kempld_create_platform_device, | ||
531 | }, { | ||
513 | .ident = "FRI2", | 532 | .ident = "FRI2", |
514 | .matches = { | 533 | .matches = { |
515 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), | 534 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), |
@@ -533,6 +552,14 @@ static struct dmi_system_id __initdata kempld_dmi_table[] = { | |||
533 | .driver_data = (void *)&kempld_platform_data_generic, | 552 | .driver_data = (void *)&kempld_platform_data_generic, |
534 | .callback = kempld_create_platform_device, | 553 | .callback = kempld_create_platform_device, |
535 | }, { | 554 | }, { |
555 | .ident = "MVV1", | ||
556 | .matches = { | ||
557 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), | ||
558 | DMI_MATCH(DMI_BOARD_NAME, "COMe-mBT"), | ||
559 | }, | ||
560 | .driver_data = (void *)&kempld_platform_data_generic, | ||
561 | .callback = kempld_create_platform_device, | ||
562 | }, { | ||
536 | .ident = "NTC1", | 563 | .ident = "NTC1", |
537 | .matches = { | 564 | .matches = { |
538 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), | 565 | DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"), |
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index be93fa261ded..3f10ea3f45d1 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -58,7 +58,6 @@ | |||
58 | 58 | ||
59 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 59 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
60 | 60 | ||
61 | #include <linux/init.h> | ||
62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
63 | #include <linux/module.h> | 62 | #include <linux/module.h> |
64 | #include <linux/errno.h> | 63 | #include <linux/errno.h> |
@@ -72,9 +71,11 @@ | |||
72 | #define ACPIBASE_GPE_END 0x2f | 71 | #define ACPIBASE_GPE_END 0x2f |
73 | #define ACPIBASE_SMI_OFF 0x30 | 72 | #define ACPIBASE_SMI_OFF 0x30 |
74 | #define ACPIBASE_SMI_END 0x33 | 73 | #define ACPIBASE_SMI_END 0x33 |
74 | #define ACPIBASE_PMC_OFF 0x08 | ||
75 | #define ACPIBASE_PMC_END 0x0c | ||
75 | #define ACPIBASE_TCO_OFF 0x60 | 76 | #define ACPIBASE_TCO_OFF 0x60 |
76 | #define ACPIBASE_TCO_END 0x7f | 77 | #define ACPIBASE_TCO_END 0x7f |
77 | #define ACPICTRL 0x44 | 78 | #define ACPICTRL_PMCBASE 0x44 |
78 | 79 | ||
79 | #define ACPIBASE_GCS_OFF 0x3410 | 80 | #define ACPIBASE_GCS_OFF 0x3410 |
80 | #define ACPIBASE_GCS_END 0x3414 | 81 | #define ACPIBASE_GCS_END 0x3414 |
@@ -90,16 +91,17 @@ | |||
90 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) | 91 | #define wdt_mem_res(i) wdt_res(ICH_RES_MEM_OFF, i) |
91 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) | 92 | #define wdt_res(b, i) (&wdt_ich_res[(b) + (i)]) |
92 | 93 | ||
93 | struct lpc_ich_cfg { | ||
94 | int base; | ||
95 | int ctrl; | ||
96 | int save; | ||
97 | }; | ||
98 | |||
99 | struct lpc_ich_priv { | 94 | struct lpc_ich_priv { |
100 | int chipset; | 95 | int chipset; |
101 | struct lpc_ich_cfg acpi; | 96 | |
102 | struct lpc_ich_cfg gpio; | 97 | int abase; /* ACPI base */ |
98 | int actrl_pbase; /* ACPI control or PMC base */ | ||
99 | int gbase; /* GPIO base */ | ||
100 | int gctrl; /* GPIO control */ | ||
101 | |||
102 | int abase_save; /* Cached ACPI base value */ | ||
103 | int actrl_pbase_save; /* Cached ACPI control or PMC base value */ | ||
104 | int gctrl_save; /* Cached GPIO control value */ | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | static struct resource wdt_ich_res[] = { | 107 | static struct resource wdt_ich_res[] = { |
@@ -111,7 +113,7 @@ static struct resource wdt_ich_res[] = { | |||
111 | { | 113 | { |
112 | .flags = IORESOURCE_IO, | 114 | .flags = IORESOURCE_IO, |
113 | }, | 115 | }, |
114 | /* GCS */ | 116 | /* GCS or PMC */ |
115 | { | 117 | { |
116 | .flags = IORESOURCE_MEM, | 118 | .flags = IORESOURCE_MEM, |
117 | }, | 119 | }, |
@@ -211,6 +213,7 @@ enum lpc_chipsets { | |||
211 | LPC_LPT_LP, /* Lynx Point-LP */ | 213 | LPC_LPT_LP, /* Lynx Point-LP */ |
212 | LPC_WBG, /* Wellsburg */ | 214 | LPC_WBG, /* Wellsburg */ |
213 | LPC_AVN, /* Avoton SoC */ | 215 | LPC_AVN, /* Avoton SoC */ |
216 | LPC_BAYTRAIL, /* Bay Trail SoC */ | ||
214 | LPC_COLETO, /* Coleto Creek */ | 217 | LPC_COLETO, /* Coleto Creek */ |
215 | LPC_WPT_LP, /* Wildcat Point-LP */ | 218 | LPC_WPT_LP, /* Wildcat Point-LP */ |
216 | }; | 219 | }; |
@@ -303,6 +306,7 @@ static struct lpc_ich_info lpc_chipset_info[] = { | |||
303 | [LPC_NM10] = { | 306 | [LPC_NM10] = { |
304 | .name = "NM10", | 307 | .name = "NM10", |
305 | .iTCO_version = 2, | 308 | .iTCO_version = 2, |
309 | .gpio_version = ICH_V7_GPIO, | ||
306 | }, | 310 | }, |
307 | [LPC_ICH8] = { | 311 | [LPC_ICH8] = { |
308 | .name = "ICH8 or ICH8R", | 312 | .name = "ICH8 or ICH8R", |
@@ -499,7 +503,12 @@ static struct lpc_ich_info lpc_chipset_info[] = { | |||
499 | }, | 503 | }, |
500 | [LPC_AVN] = { | 504 | [LPC_AVN] = { |
501 | .name = "Avoton SoC", | 505 | .name = "Avoton SoC", |
502 | .iTCO_version = 1, | 506 | .iTCO_version = 3, |
507 | .gpio_version = AVOTON_GPIO, | ||
508 | }, | ||
509 | [LPC_BAYTRAIL] = { | ||
510 | .name = "Bay Trail SoC", | ||
511 | .iTCO_version = 3, | ||
503 | }, | 512 | }, |
504 | [LPC_COLETO] = { | 513 | [LPC_COLETO] = { |
505 | .name = "Coleto Creek", | 514 | .name = "Coleto Creek", |
@@ -726,6 +735,7 @@ static const struct pci_device_id lpc_ich_ids[] = { | |||
726 | { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, | 735 | { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN}, |
727 | { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, | 736 | { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN}, |
728 | { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, | 737 | { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN}, |
738 | { PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL}, | ||
729 | { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, | 739 | { PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO}, |
730 | { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, | 740 | { PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP}, |
731 | { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, | 741 | { PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP}, |
@@ -742,14 +752,20 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev) | |||
742 | { | 752 | { |
743 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 753 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
744 | 754 | ||
745 | if (priv->acpi.save >= 0) { | 755 | if (priv->abase_save >= 0) { |
746 | pci_write_config_byte(dev, priv->acpi.ctrl, priv->acpi.save); | 756 | pci_write_config_byte(dev, priv->abase, priv->abase_save); |
747 | priv->acpi.save = -1; | 757 | priv->abase_save = -1; |
758 | } | ||
759 | |||
760 | if (priv->actrl_pbase_save >= 0) { | ||
761 | pci_write_config_byte(dev, priv->actrl_pbase, | ||
762 | priv->actrl_pbase_save); | ||
763 | priv->actrl_pbase_save = -1; | ||
748 | } | 764 | } |
749 | 765 | ||
750 | if (priv->gpio.save >= 0) { | 766 | if (priv->gctrl_save >= 0) { |
751 | pci_write_config_byte(dev, priv->gpio.ctrl, priv->gpio.save); | 767 | pci_write_config_byte(dev, priv->gctrl, priv->gctrl_save); |
752 | priv->gpio.save = -1; | 768 | priv->gctrl_save = -1; |
753 | } | 769 | } |
754 | } | 770 | } |
755 | 771 | ||
@@ -758,9 +774,26 @@ static void lpc_ich_enable_acpi_space(struct pci_dev *dev) | |||
758 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 774 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
759 | u8 reg_save; | 775 | u8 reg_save; |
760 | 776 | ||
761 | pci_read_config_byte(dev, priv->acpi.ctrl, ®_save); | 777 | switch (lpc_chipset_info[priv->chipset].iTCO_version) { |
762 | pci_write_config_byte(dev, priv->acpi.ctrl, reg_save | 0x10); | 778 | case 3: |
763 | priv->acpi.save = reg_save; | 779 | /* |
780 | * Some chipsets (eg Avoton) enable the ACPI space in the | ||
781 | * ACPI BASE register. | ||
782 | */ | ||
783 | pci_read_config_byte(dev, priv->abase, ®_save); | ||
784 | pci_write_config_byte(dev, priv->abase, reg_save | 0x2); | ||
785 | priv->abase_save = reg_save; | ||
786 | break; | ||
787 | default: | ||
788 | /* | ||
789 | * Most chipsets enable the ACPI space in the ACPI control | ||
790 | * register. | ||
791 | */ | ||
792 | pci_read_config_byte(dev, priv->actrl_pbase, ®_save); | ||
793 | pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80); | ||
794 | priv->actrl_pbase_save = reg_save; | ||
795 | break; | ||
796 | } | ||
764 | } | 797 | } |
765 | 798 | ||
766 | static void lpc_ich_enable_gpio_space(struct pci_dev *dev) | 799 | static void lpc_ich_enable_gpio_space(struct pci_dev *dev) |
@@ -768,9 +801,20 @@ static void lpc_ich_enable_gpio_space(struct pci_dev *dev) | |||
768 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | 801 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); |
769 | u8 reg_save; | 802 | u8 reg_save; |
770 | 803 | ||
771 | pci_read_config_byte(dev, priv->gpio.ctrl, ®_save); | 804 | pci_read_config_byte(dev, priv->gctrl, ®_save); |
772 | pci_write_config_byte(dev, priv->gpio.ctrl, reg_save | 0x10); | 805 | pci_write_config_byte(dev, priv->gctrl, reg_save | 0x10); |
773 | priv->gpio.save = reg_save; | 806 | priv->gctrl_save = reg_save; |
807 | } | ||
808 | |||
809 | static void lpc_ich_enable_pmc_space(struct pci_dev *dev) | ||
810 | { | ||
811 | struct lpc_ich_priv *priv = pci_get_drvdata(dev); | ||
812 | u8 reg_save; | ||
813 | |||
814 | pci_read_config_byte(dev, priv->actrl_pbase, ®_save); | ||
815 | pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2); | ||
816 | |||
817 | priv->actrl_pbase_save = reg_save; | ||
774 | } | 818 | } |
775 | 819 | ||
776 | static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) | 820 | static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) |
@@ -815,7 +859,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev) | |||
815 | struct resource *res; | 859 | struct resource *res; |
816 | 860 | ||
817 | /* Setup power management base register */ | 861 | /* Setup power management base register */ |
818 | pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg); | 862 | pci_read_config_dword(dev, priv->abase, &base_addr_cfg); |
819 | base_addr = base_addr_cfg & 0x0000ff80; | 863 | base_addr = base_addr_cfg & 0x0000ff80; |
820 | if (!base_addr) { | 864 | if (!base_addr) { |
821 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); | 865 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); |
@@ -841,7 +885,7 @@ static int lpc_ich_init_gpio(struct pci_dev *dev) | |||
841 | 885 | ||
842 | gpe0_done: | 886 | gpe0_done: |
843 | /* Setup GPIO base register */ | 887 | /* Setup GPIO base register */ |
844 | pci_read_config_dword(dev, priv->gpio.base, &base_addr_cfg); | 888 | pci_read_config_dword(dev, priv->gbase, &base_addr_cfg); |
845 | base_addr = base_addr_cfg & 0x0000ff80; | 889 | base_addr = base_addr_cfg & 0x0000ff80; |
846 | if (!base_addr) { | 890 | if (!base_addr) { |
847 | dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); | 891 | dev_notice(&dev->dev, "I/O space for GPIO uninitialized\n"); |
@@ -891,7 +935,7 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
891 | struct resource *res; | 935 | struct resource *res; |
892 | 936 | ||
893 | /* Setup power management base register */ | 937 | /* Setup power management base register */ |
894 | pci_read_config_dword(dev, priv->acpi.base, &base_addr_cfg); | 938 | pci_read_config_dword(dev, priv->abase, &base_addr_cfg); |
895 | base_addr = base_addr_cfg & 0x0000ff80; | 939 | base_addr = base_addr_cfg & 0x0000ff80; |
896 | if (!base_addr) { | 940 | if (!base_addr) { |
897 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); | 941 | dev_notice(&dev->dev, "I/O space for ACPI uninitialized\n"); |
@@ -910,14 +954,20 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
910 | lpc_ich_enable_acpi_space(dev); | 954 | lpc_ich_enable_acpi_space(dev); |
911 | 955 | ||
912 | /* | 956 | /* |
957 | * iTCO v2: | ||
913 | * Get the Memory-Mapped GCS register. To get access to it | 958 | * Get the Memory-Mapped GCS register. To get access to it |
914 | * we have to read RCBA from PCI Config space 0xf0 and use | 959 | * we have to read RCBA from PCI Config space 0xf0 and use |
915 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). | 960 | * it as base. GCS = RCBA + ICH6_GCS(0x3410). |
961 | * | ||
962 | * iTCO v3: | ||
963 | * Get the Power Management Configuration register. To get access | ||
964 | * to it we have to read the PMC BASE from config space and address | ||
965 | * the register at offset 0x8. | ||
916 | */ | 966 | */ |
917 | if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { | 967 | if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { |
918 | /* Don't register iomem for TCO ver 1 */ | 968 | /* Don't register iomem for TCO ver 1 */ |
919 | lpc_ich_cells[LPC_WDT].num_resources--; | 969 | lpc_ich_cells[LPC_WDT].num_resources--; |
920 | } else { | 970 | } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) { |
921 | pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); | 971 | pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); |
922 | base_addr = base_addr_cfg & 0xffffc000; | 972 | base_addr = base_addr_cfg & 0xffffc000; |
923 | if (!(base_addr_cfg & 1)) { | 973 | if (!(base_addr_cfg & 1)) { |
@@ -926,9 +976,17 @@ static int lpc_ich_init_wdt(struct pci_dev *dev) | |||
926 | ret = -ENODEV; | 976 | ret = -ENODEV; |
927 | goto wdt_done; | 977 | goto wdt_done; |
928 | } | 978 | } |
929 | res = wdt_mem_res(ICH_RES_MEM_GCS); | 979 | res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); |
930 | res->start = base_addr + ACPIBASE_GCS_OFF; | 980 | res->start = base_addr + ACPIBASE_GCS_OFF; |
931 | res->end = base_addr + ACPIBASE_GCS_END; | 981 | res->end = base_addr + ACPIBASE_GCS_END; |
982 | } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) { | ||
983 | lpc_ich_enable_pmc_space(dev); | ||
984 | pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg); | ||
985 | base_addr = base_addr_cfg & 0xfffffe00; | ||
986 | |||
987 | res = wdt_mem_res(ICH_RES_MEM_GCS_PMC); | ||
988 | res->start = base_addr + ACPIBASE_PMC_OFF; | ||
989 | res->end = base_addr + ACPIBASE_PMC_END; | ||
932 | } | 990 | } |
933 | 991 | ||
934 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); | 992 | lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); |
@@ -952,28 +1010,35 @@ static int lpc_ich_probe(struct pci_dev *dev, | |||
952 | return -ENOMEM; | 1010 | return -ENOMEM; |
953 | 1011 | ||
954 | priv->chipset = id->driver_data; | 1012 | priv->chipset = id->driver_data; |
955 | priv->acpi.save = -1; | ||
956 | priv->acpi.base = ACPIBASE; | ||
957 | priv->acpi.ctrl = ACPICTRL; | ||
958 | 1013 | ||
959 | priv->gpio.save = -1; | 1014 | priv->actrl_pbase_save = -1; |
1015 | priv->abase_save = -1; | ||
1016 | |||
1017 | priv->abase = ACPIBASE; | ||
1018 | priv->actrl_pbase = ACPICTRL_PMCBASE; | ||
1019 | |||
1020 | priv->gctrl_save = -1; | ||
960 | if (priv->chipset <= LPC_ICH5) { | 1021 | if (priv->chipset <= LPC_ICH5) { |
961 | priv->gpio.base = GPIOBASE_ICH0; | 1022 | priv->gbase = GPIOBASE_ICH0; |
962 | priv->gpio.ctrl = GPIOCTRL_ICH0; | 1023 | priv->gctrl = GPIOCTRL_ICH0; |
963 | } else { | 1024 | } else { |
964 | priv->gpio.base = GPIOBASE_ICH6; | 1025 | priv->gbase = GPIOBASE_ICH6; |
965 | priv->gpio.ctrl = GPIOCTRL_ICH6; | 1026 | priv->gctrl = GPIOCTRL_ICH6; |
966 | } | 1027 | } |
967 | 1028 | ||
968 | pci_set_drvdata(dev, priv); | 1029 | pci_set_drvdata(dev, priv); |
969 | 1030 | ||
970 | ret = lpc_ich_init_wdt(dev); | 1031 | if (lpc_chipset_info[priv->chipset].iTCO_version) { |
971 | if (!ret) | 1032 | ret = lpc_ich_init_wdt(dev); |
972 | cell_added = true; | 1033 | if (!ret) |
1034 | cell_added = true; | ||
1035 | } | ||
973 | 1036 | ||
974 | ret = lpc_ich_init_gpio(dev); | 1037 | if (lpc_chipset_info[priv->chipset].gpio_version) { |
975 | if (!ret) | 1038 | ret = lpc_ich_init_gpio(dev); |
976 | cell_added = true; | 1039 | if (!ret) |
1040 | cell_added = true; | ||
1041 | } | ||
977 | 1042 | ||
978 | /* | 1043 | /* |
979 | * We only care if at least one or none of the cells registered | 1044 | * We only care if at least one or none of the cells registered |
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 3bb05c03c68d..4ee755034f3b 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -23,7 +23,6 @@ | |||
23 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/module.h> | 27 | #include <linux/module.h> |
29 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 71aa14a6bfbb..5f13cefe8def 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * This driver is based on max8997.c | 18 | * This driver is based on max8997.c |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/err.h> | ||
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
22 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
23 | #include <linux/mfd/core.h> | 24 | #include <linux/mfd/core.h> |
@@ -25,7 +26,10 @@ | |||
25 | #include <linux/mfd/max14577-private.h> | 26 | #include <linux/mfd/max14577-private.h> |
26 | 27 | ||
27 | static struct mfd_cell max14577_devs[] = { | 28 | static struct mfd_cell max14577_devs[] = { |
28 | { .name = "max14577-muic", }, | 29 | { |
30 | .name = "max14577-muic", | ||
31 | .of_compatible = "maxim,max14577-muic", | ||
32 | }, | ||
29 | { | 33 | { |
30 | .name = "max14577-regulator", | 34 | .name = "max14577-regulator", |
31 | .of_compatible = "maxim,max14577-regulator", | 35 | .of_compatible = "maxim,max14577-regulator", |
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index f53d5823a3f7..e5fce765accb 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -121,6 +121,10 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
121 | dev_info(max77686->dev, "device found\n"); | 121 | dev_info(max77686->dev, "device found\n"); |
122 | 122 | ||
123 | max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); | 123 | max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); |
124 | if (!max77686->rtc) { | ||
125 | dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n"); | ||
126 | return -ENODEV; | ||
127 | } | ||
124 | i2c_set_clientdata(max77686->rtc, max77686); | 128 | i2c_set_clientdata(max77686->rtc, max77686); |
125 | 129 | ||
126 | max77686_irq_init(max77686); | 130 | max77686_irq_init(max77686); |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index e0859987ab6b..c5535f018466 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -148,9 +148,18 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
148 | dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); | 148 | dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); |
149 | 149 | ||
150 | max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); | 150 | max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); |
151 | if (!max77693->muic) { | ||
152 | dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n"); | ||
153 | return -ENODEV; | ||
154 | } | ||
151 | i2c_set_clientdata(max77693->muic, max77693); | 155 | i2c_set_clientdata(max77693->muic, max77693); |
152 | 156 | ||
153 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); | 157 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); |
158 | if (!max77693->haptic) { | ||
159 | dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n"); | ||
160 | ret = -ENODEV; | ||
161 | goto err_i2c_haptic; | ||
162 | } | ||
154 | i2c_set_clientdata(max77693->haptic, max77693); | 163 | i2c_set_clientdata(max77693->haptic, max77693); |
155 | 164 | ||
156 | /* | 165 | /* |
@@ -184,8 +193,9 @@ err_mfd: | |||
184 | max77693_irq_exit(max77693); | 193 | max77693_irq_exit(max77693); |
185 | err_irq: | 194 | err_irq: |
186 | err_regmap_muic: | 195 | err_regmap_muic: |
187 | i2c_unregister_device(max77693->muic); | ||
188 | i2c_unregister_device(max77693->haptic); | 196 | i2c_unregister_device(max77693->haptic); |
197 | err_i2c_haptic: | ||
198 | i2c_unregister_device(max77693->muic); | ||
189 | return ret; | 199 | return ret; |
190 | } | 200 | } |
191 | 201 | ||
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 176aa26fc787..a83eed5c15ca 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c | |||
@@ -181,9 +181,18 @@ static int max8925_probe(struct i2c_client *client, | |||
181 | mutex_init(&chip->io_lock); | 181 | mutex_init(&chip->io_lock); |
182 | 182 | ||
183 | chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR); | 183 | chip->rtc = i2c_new_dummy(chip->i2c->adapter, RTC_I2C_ADDR); |
184 | if (!chip->rtc) { | ||
185 | dev_err(chip->dev, "Failed to allocate I2C device for RTC\n"); | ||
186 | return -ENODEV; | ||
187 | } | ||
184 | i2c_set_clientdata(chip->rtc, chip); | 188 | i2c_set_clientdata(chip->rtc, chip); |
185 | 189 | ||
186 | chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); | 190 | chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); |
191 | if (!chip->adc) { | ||
192 | dev_err(chip->dev, "Failed to allocate I2C device for ADC\n"); | ||
193 | i2c_unregister_device(chip->rtc); | ||
194 | return -ENODEV; | ||
195 | } | ||
187 | i2c_set_clientdata(chip->adc, chip); | 196 | i2c_set_clientdata(chip->adc, chip); |
188 | 197 | ||
189 | device_init_wakeup(&client->dev, 1); | 198 | device_init_wakeup(&client->dev, 1); |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 5adede0fb04c..8cf7a015cfe5 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -208,10 +208,26 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
208 | mutex_init(&max8997->iolock); | 208 | mutex_init(&max8997->iolock); |
209 | 209 | ||
210 | max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); | 210 | max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); |
211 | if (!max8997->rtc) { | ||
212 | dev_err(max8997->dev, "Failed to allocate I2C device for RTC\n"); | ||
213 | return -ENODEV; | ||
214 | } | ||
211 | i2c_set_clientdata(max8997->rtc, max8997); | 215 | i2c_set_clientdata(max8997->rtc, max8997); |
216 | |||
212 | max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); | 217 | max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); |
218 | if (!max8997->haptic) { | ||
219 | dev_err(max8997->dev, "Failed to allocate I2C device for Haptic\n"); | ||
220 | ret = -ENODEV; | ||
221 | goto err_i2c_haptic; | ||
222 | } | ||
213 | i2c_set_clientdata(max8997->haptic, max8997); | 223 | i2c_set_clientdata(max8997->haptic, max8997); |
224 | |||
214 | max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); | 225 | max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); |
226 | if (!max8997->muic) { | ||
227 | dev_err(max8997->dev, "Failed to allocate I2C device for MUIC\n"); | ||
228 | ret = -ENODEV; | ||
229 | goto err_i2c_muic; | ||
230 | } | ||
215 | i2c_set_clientdata(max8997->muic, max8997); | 231 | i2c_set_clientdata(max8997->muic, max8997); |
216 | 232 | ||
217 | pm_runtime_set_active(max8997->dev); | 233 | pm_runtime_set_active(max8997->dev); |
@@ -239,7 +255,9 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
239 | err_mfd: | 255 | err_mfd: |
240 | mfd_remove_devices(max8997->dev); | 256 | mfd_remove_devices(max8997->dev); |
241 | i2c_unregister_device(max8997->muic); | 257 | i2c_unregister_device(max8997->muic); |
258 | err_i2c_muic: | ||
242 | i2c_unregister_device(max8997->haptic); | 259 | i2c_unregister_device(max8997->haptic); |
260 | err_i2c_haptic: | ||
243 | i2c_unregister_device(max8997->rtc); | 261 | i2c_unregister_device(max8997->rtc); |
244 | return ret; | 262 | return ret; |
245 | } | 263 | } |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 5d5e186b5d8b..592db06098e6 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -215,6 +215,10 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
215 | mutex_init(&max8998->iolock); | 215 | mutex_init(&max8998->iolock); |
216 | 216 | ||
217 | max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); | 217 | max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); |
218 | if (!max8998->rtc) { | ||
219 | dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n"); | ||
220 | return -ENODEV; | ||
221 | } | ||
218 | i2c_set_clientdata(max8998->rtc, max8998); | 222 | i2c_set_clientdata(max8998->rtc, max8998); |
219 | 223 | ||
220 | max8998_irq_init(max8998); | 224 | max8998_irq_init(max8998); |
diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c index 38ab67829791..702925e242c9 100644 --- a/drivers/mfd/mc13xxx-spi.c +++ b/drivers/mfd/mc13xxx-spi.c | |||
@@ -140,6 +140,11 @@ static int mc13xxx_spi_probe(struct spi_device *spi) | |||
140 | 140 | ||
141 | mc13xxx->irq = spi->irq; | 141 | mc13xxx->irq = spi->irq; |
142 | 142 | ||
143 | spi->max_speed_hz = spi->max_speed_hz ? : 26000000; | ||
144 | ret = spi_setup(spi); | ||
145 | if (ret) | ||
146 | return ret; | ||
147 | |||
143 | mc13xxx->regmap = devm_regmap_init(&spi->dev, ®map_mc13xxx_bus, | 148 | mc13xxx->regmap = devm_regmap_init(&spi->dev, ®map_mc13xxx_bus, |
144 | &spi->dev, | 149 | &spi->dev, |
145 | &mc13xxx_regmap_spi_config); | 150 | &mc13xxx_regmap_spi_config); |
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 41c31b3ac940..29d76986b40b 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c | |||
@@ -12,7 +12,6 @@ | |||
12 | * MCP read/write timeouts from Jordi Colomer, rehacked by rmk. | 12 | * MCP read/write timeouts from Jordi Colomer, rehacked by rmk. |
13 | */ | 13 | */ |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/init.h> | ||
16 | #include <linux/io.h> | 15 | #include <linux/io.h> |
17 | #include <linux/errno.h> | 16 | #include <linux/errno.h> |
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 90b630ccc8bc..651e249287dc 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -665,55 +665,78 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
665 | goto err_mem; | 665 | goto err_mem; |
666 | } | 666 | } |
667 | 667 | ||
668 | need_logic_fck = false; | 668 | /* Set all clocks as invalid to begin with */ |
669 | omap->ehci_logic_fck = ERR_PTR(-ENODEV); | ||
670 | omap->init_60m_fclk = ERR_PTR(-ENODEV); | ||
671 | omap->utmi_p1_gfclk = ERR_PTR(-ENODEV); | ||
672 | omap->utmi_p2_gfclk = ERR_PTR(-ENODEV); | ||
673 | omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV); | ||
674 | omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV); | ||
675 | |||
669 | for (i = 0; i < omap->nports; i++) { | 676 | for (i = 0; i < omap->nports; i++) { |
670 | if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) || | 677 | omap->utmi_clk[i] = ERR_PTR(-ENODEV); |
671 | is_ehci_hsic_mode(i)) | 678 | omap->hsic480m_clk[i] = ERR_PTR(-ENODEV); |
672 | need_logic_fck |= true; | 679 | omap->hsic60m_clk[i] = ERR_PTR(-ENODEV); |
673 | } | 680 | } |
674 | 681 | ||
675 | omap->ehci_logic_fck = ERR_PTR(-EINVAL); | 682 | /* for OMAP3 i.e. USBHS REV1 */ |
676 | if (need_logic_fck) { | 683 | if (omap->usbhs_rev == OMAP_USBHS_REV1) { |
677 | omap->ehci_logic_fck = clk_get(dev, "ehci_logic_fck"); | 684 | need_logic_fck = false; |
678 | if (IS_ERR(omap->ehci_logic_fck)) { | 685 | for (i = 0; i < omap->nports; i++) { |
679 | ret = PTR_ERR(omap->ehci_logic_fck); | 686 | if (is_ehci_phy_mode(pdata->port_mode[i]) || |
680 | dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret); | 687 | is_ehci_tll_mode(pdata->port_mode[i]) || |
688 | is_ehci_hsic_mode(pdata->port_mode[i])) | ||
689 | |||
690 | need_logic_fck |= true; | ||
681 | } | 691 | } |
692 | |||
693 | if (need_logic_fck) { | ||
694 | omap->ehci_logic_fck = devm_clk_get(dev, | ||
695 | "usbhost_120m_fck"); | ||
696 | if (IS_ERR(omap->ehci_logic_fck)) { | ||
697 | ret = PTR_ERR(omap->ehci_logic_fck); | ||
698 | dev_err(dev, "usbhost_120m_fck failed:%d\n", | ||
699 | ret); | ||
700 | goto err_mem; | ||
701 | } | ||
702 | } | ||
703 | goto initialize; | ||
682 | } | 704 | } |
683 | 705 | ||
684 | omap->utmi_p1_gfclk = clk_get(dev, "utmi_p1_gfclk"); | 706 | /* for OMAP4+ i.e. USBHS REV2+ */ |
707 | omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk"); | ||
685 | if (IS_ERR(omap->utmi_p1_gfclk)) { | 708 | if (IS_ERR(omap->utmi_p1_gfclk)) { |
686 | ret = PTR_ERR(omap->utmi_p1_gfclk); | 709 | ret = PTR_ERR(omap->utmi_p1_gfclk); |
687 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | 710 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); |
688 | goto err_p1_gfclk; | 711 | goto err_mem; |
689 | } | 712 | } |
690 | 713 | ||
691 | omap->utmi_p2_gfclk = clk_get(dev, "utmi_p2_gfclk"); | 714 | omap->utmi_p2_gfclk = devm_clk_get(dev, "utmi_p2_gfclk"); |
692 | if (IS_ERR(omap->utmi_p2_gfclk)) { | 715 | if (IS_ERR(omap->utmi_p2_gfclk)) { |
693 | ret = PTR_ERR(omap->utmi_p2_gfclk); | 716 | ret = PTR_ERR(omap->utmi_p2_gfclk); |
694 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | 717 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); |
695 | goto err_p2_gfclk; | 718 | goto err_mem; |
696 | } | 719 | } |
697 | 720 | ||
698 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | 721 | omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1"); |
699 | if (IS_ERR(omap->xclk60mhsp1_ck)) { | 722 | if (IS_ERR(omap->xclk60mhsp1_ck)) { |
700 | ret = PTR_ERR(omap->xclk60mhsp1_ck); | 723 | ret = PTR_ERR(omap->xclk60mhsp1_ck); |
701 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | 724 | dev_err(dev, "refclk_60m_ext_p1 failed error:%d\n", ret); |
702 | goto err_xclk60mhsp1; | 725 | goto err_mem; |
703 | } | 726 | } |
704 | 727 | ||
705 | omap->xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | 728 | omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2"); |
706 | if (IS_ERR(omap->xclk60mhsp2_ck)) { | 729 | if (IS_ERR(omap->xclk60mhsp2_ck)) { |
707 | ret = PTR_ERR(omap->xclk60mhsp2_ck); | 730 | ret = PTR_ERR(omap->xclk60mhsp2_ck); |
708 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | 731 | dev_err(dev, "refclk_60m_ext_p2 failed error:%d\n", ret); |
709 | goto err_xclk60mhsp2; | 732 | goto err_mem; |
710 | } | 733 | } |
711 | 734 | ||
712 | omap->init_60m_fclk = clk_get(dev, "init_60m_fclk"); | 735 | omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int"); |
713 | if (IS_ERR(omap->init_60m_fclk)) { | 736 | if (IS_ERR(omap->init_60m_fclk)) { |
714 | ret = PTR_ERR(omap->init_60m_fclk); | 737 | ret = PTR_ERR(omap->init_60m_fclk); |
715 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | 738 | dev_err(dev, "refclk_60m_int failed error:%d\n", ret); |
716 | goto err_init60m; | 739 | goto err_mem; |
717 | } | 740 | } |
718 | 741 | ||
719 | for (i = 0; i < omap->nports; i++) { | 742 | for (i = 0; i < omap->nports; i++) { |
@@ -727,55 +750,72 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
727 | * platforms have all clocks and we can function without | 750 | * platforms have all clocks and we can function without |
728 | * them | 751 | * them |
729 | */ | 752 | */ |
730 | omap->utmi_clk[i] = clk_get(dev, clkname); | 753 | omap->utmi_clk[i] = devm_clk_get(dev, clkname); |
731 | if (IS_ERR(omap->utmi_clk[i])) | 754 | if (IS_ERR(omap->utmi_clk[i])) { |
732 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 755 | ret = PTR_ERR(omap->utmi_clk[i]); |
733 | clkname, PTR_ERR(omap->utmi_clk[i])); | 756 | dev_err(dev, "Failed to get clock : %s : %d\n", |
757 | clkname, ret); | ||
758 | goto err_mem; | ||
759 | } | ||
734 | 760 | ||
735 | snprintf(clkname, sizeof(clkname), | 761 | snprintf(clkname, sizeof(clkname), |
736 | "usb_host_hs_hsic480m_p%d_clk", i + 1); | 762 | "usb_host_hs_hsic480m_p%d_clk", i + 1); |
737 | omap->hsic480m_clk[i] = clk_get(dev, clkname); | 763 | omap->hsic480m_clk[i] = devm_clk_get(dev, clkname); |
738 | if (IS_ERR(omap->hsic480m_clk[i])) | 764 | if (IS_ERR(omap->hsic480m_clk[i])) { |
739 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 765 | ret = PTR_ERR(omap->hsic480m_clk[i]); |
740 | clkname, PTR_ERR(omap->hsic480m_clk[i])); | 766 | dev_err(dev, "Failed to get clock : %s : %d\n", |
767 | clkname, ret); | ||
768 | goto err_mem; | ||
769 | } | ||
741 | 770 | ||
742 | snprintf(clkname, sizeof(clkname), | 771 | snprintf(clkname, sizeof(clkname), |
743 | "usb_host_hs_hsic60m_p%d_clk", i + 1); | 772 | "usb_host_hs_hsic60m_p%d_clk", i + 1); |
744 | omap->hsic60m_clk[i] = clk_get(dev, clkname); | 773 | omap->hsic60m_clk[i] = devm_clk_get(dev, clkname); |
745 | if (IS_ERR(omap->hsic60m_clk[i])) | 774 | if (IS_ERR(omap->hsic60m_clk[i])) { |
746 | dev_dbg(dev, "Failed to get clock : %s : %ld\n", | 775 | ret = PTR_ERR(omap->hsic60m_clk[i]); |
747 | clkname, PTR_ERR(omap->hsic60m_clk[i])); | 776 | dev_err(dev, "Failed to get clock : %s : %d\n", |
777 | clkname, ret); | ||
778 | goto err_mem; | ||
779 | } | ||
748 | } | 780 | } |
749 | 781 | ||
750 | if (is_ehci_phy_mode(pdata->port_mode[0])) { | 782 | if (is_ehci_phy_mode(pdata->port_mode[0])) { |
751 | /* for OMAP3, clk_set_parent fails */ | ||
752 | ret = clk_set_parent(omap->utmi_p1_gfclk, | 783 | ret = clk_set_parent(omap->utmi_p1_gfclk, |
753 | omap->xclk60mhsp1_ck); | 784 | omap->xclk60mhsp1_ck); |
754 | if (ret != 0) | 785 | if (ret != 0) { |
755 | dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n", | 786 | dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n", |
756 | ret); | 787 | ret); |
788 | goto err_mem; | ||
789 | } | ||
757 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { | 790 | } else if (is_ehci_tll_mode(pdata->port_mode[0])) { |
758 | ret = clk_set_parent(omap->utmi_p1_gfclk, | 791 | ret = clk_set_parent(omap->utmi_p1_gfclk, |
759 | omap->init_60m_fclk); | 792 | omap->init_60m_fclk); |
760 | if (ret != 0) | 793 | if (ret != 0) { |
761 | dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n", | 794 | dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n", |
762 | ret); | 795 | ret); |
796 | goto err_mem; | ||
797 | } | ||
763 | } | 798 | } |
764 | 799 | ||
765 | if (is_ehci_phy_mode(pdata->port_mode[1])) { | 800 | if (is_ehci_phy_mode(pdata->port_mode[1])) { |
766 | ret = clk_set_parent(omap->utmi_p2_gfclk, | 801 | ret = clk_set_parent(omap->utmi_p2_gfclk, |
767 | omap->xclk60mhsp2_ck); | 802 | omap->xclk60mhsp2_ck); |
768 | if (ret != 0) | 803 | if (ret != 0) { |
769 | dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n", | 804 | dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n", |
770 | ret); | 805 | ret); |
806 | goto err_mem; | ||
807 | } | ||
771 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { | 808 | } else if (is_ehci_tll_mode(pdata->port_mode[1])) { |
772 | ret = clk_set_parent(omap->utmi_p2_gfclk, | 809 | ret = clk_set_parent(omap->utmi_p2_gfclk, |
773 | omap->init_60m_fclk); | 810 | omap->init_60m_fclk); |
774 | if (ret != 0) | 811 | if (ret != 0) { |
775 | dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n", | 812 | dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n", |
776 | ret); | 813 | ret); |
814 | goto err_mem; | ||
815 | } | ||
777 | } | 816 | } |
778 | 817 | ||
818 | initialize: | ||
779 | omap_usbhs_init(dev); | 819 | omap_usbhs_init(dev); |
780 | 820 | ||
781 | if (dev->of_node) { | 821 | if (dev->of_node) { |
@@ -784,7 +824,7 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
784 | 824 | ||
785 | if (ret) { | 825 | if (ret) { |
786 | dev_err(dev, "Failed to create DT children: %d\n", ret); | 826 | dev_err(dev, "Failed to create DT children: %d\n", ret); |
787 | goto err_alloc; | 827 | goto err_mem; |
788 | } | 828 | } |
789 | 829 | ||
790 | } else { | 830 | } else { |
@@ -792,40 +832,12 @@ static int usbhs_omap_probe(struct platform_device *pdev) | |||
792 | if (ret) { | 832 | if (ret) { |
793 | dev_err(dev, "omap_usbhs_alloc_children failed: %d\n", | 833 | dev_err(dev, "omap_usbhs_alloc_children failed: %d\n", |
794 | ret); | 834 | ret); |
795 | goto err_alloc; | 835 | goto err_mem; |
796 | } | 836 | } |
797 | } | 837 | } |
798 | 838 | ||
799 | return 0; | 839 | return 0; |
800 | 840 | ||
801 | err_alloc: | ||
802 | for (i = 0; i < omap->nports; i++) { | ||
803 | if (!IS_ERR(omap->utmi_clk[i])) | ||
804 | clk_put(omap->utmi_clk[i]); | ||
805 | if (!IS_ERR(omap->hsic60m_clk[i])) | ||
806 | clk_put(omap->hsic60m_clk[i]); | ||
807 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
808 | clk_put(omap->hsic480m_clk[i]); | ||
809 | } | ||
810 | |||
811 | clk_put(omap->init_60m_fclk); | ||
812 | |||
813 | err_init60m: | ||
814 | clk_put(omap->xclk60mhsp2_ck); | ||
815 | |||
816 | err_xclk60mhsp2: | ||
817 | clk_put(omap->xclk60mhsp1_ck); | ||
818 | |||
819 | err_xclk60mhsp1: | ||
820 | clk_put(omap->utmi_p2_gfclk); | ||
821 | |||
822 | err_p2_gfclk: | ||
823 | clk_put(omap->utmi_p1_gfclk); | ||
824 | |||
825 | err_p1_gfclk: | ||
826 | if (!IS_ERR(omap->ehci_logic_fck)) | ||
827 | clk_put(omap->ehci_logic_fck); | ||
828 | |||
829 | err_mem: | 841 | err_mem: |
830 | pm_runtime_disable(dev); | 842 | pm_runtime_disable(dev); |
831 | 843 | ||
@@ -847,27 +859,6 @@ static int usbhs_omap_remove_child(struct device *dev, void *data) | |||
847 | */ | 859 | */ |
848 | static int usbhs_omap_remove(struct platform_device *pdev) | 860 | static int usbhs_omap_remove(struct platform_device *pdev) |
849 | { | 861 | { |
850 | struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); | ||
851 | int i; | ||
852 | |||
853 | for (i = 0; i < omap->nports; i++) { | ||
854 | if (!IS_ERR(omap->utmi_clk[i])) | ||
855 | clk_put(omap->utmi_clk[i]); | ||
856 | if (!IS_ERR(omap->hsic60m_clk[i])) | ||
857 | clk_put(omap->hsic60m_clk[i]); | ||
858 | if (!IS_ERR(omap->hsic480m_clk[i])) | ||
859 | clk_put(omap->hsic480m_clk[i]); | ||
860 | } | ||
861 | |||
862 | clk_put(omap->init_60m_fclk); | ||
863 | clk_put(omap->utmi_p1_gfclk); | ||
864 | clk_put(omap->utmi_p2_gfclk); | ||
865 | clk_put(omap->xclk60mhsp2_ck); | ||
866 | clk_put(omap->xclk60mhsp1_ck); | ||
867 | |||
868 | if (!IS_ERR(omap->ehci_logic_fck)) | ||
869 | clk_put(omap->ehci_logic_fck); | ||
870 | |||
871 | pm_runtime_disable(&pdev->dev); | 862 | pm_runtime_disable(&pdev->dev); |
872 | 863 | ||
873 | /* remove children */ | 864 | /* remove children */ |
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 5ee50f779ef6..532eacab6b46 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c | |||
@@ -252,7 +252,7 @@ static int usbtll_omap_probe(struct platform_device *pdev) | |||
252 | break; | 252 | break; |
253 | } | 253 | } |
254 | 254 | ||
255 | tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk * [tll->nch]), | 255 | tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch, |
256 | GFP_KERNEL); | 256 | GFP_KERNEL); |
257 | if (!tll->ch_clk) { | 257 | if (!tll->ch_clk) { |
258 | ret = -ENOMEM; | 258 | ret = -ENOMEM; |
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c index b8941a556d71..c1984b0d1b65 100644 --- a/drivers/mfd/pcf50633-adc.c +++ b/drivers/mfd/pcf50633-adc.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
24 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
25 | #include <linux/completion.h> | 24 | #include <linux/completion.h> |
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c index 484fe66e6c88..b97a97187ae9 100644 --- a/drivers/mfd/pm8921-core.c +++ b/drivers/mfd/pm8921-core.c | |||
@@ -14,23 +14,316 @@ | |||
14 | #define pr_fmt(fmt) "%s: " fmt, __func__ | 14 | #define pr_fmt(fmt) "%s: " fmt, __func__ |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/irqchip/chained_irq.h> | ||
19 | #include <linux/irq.h> | ||
20 | #include <linux/irqdomain.h> | ||
17 | #include <linux/module.h> | 21 | #include <linux/module.h> |
18 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
20 | #include <linux/err.h> | 24 | #include <linux/err.h> |
21 | #include <linux/ssbi.h> | 25 | #include <linux/ssbi.h> |
26 | #include <linux/regmap.h> | ||
27 | #include <linux/of_platform.h> | ||
22 | #include <linux/mfd/core.h> | 28 | #include <linux/mfd/core.h> |
23 | #include <linux/mfd/pm8xxx/pm8921.h> | ||
24 | #include <linux/mfd/pm8xxx/core.h> | 29 | #include <linux/mfd/pm8xxx/core.h> |
25 | 30 | ||
31 | #define SSBI_REG_ADDR_IRQ_BASE 0x1BB | ||
32 | |||
33 | #define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0) | ||
34 | #define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1) | ||
35 | #define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2) | ||
36 | #define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3) | ||
37 | #define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4) | ||
38 | #define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5) | ||
39 | #define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6) | ||
40 | #define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7) | ||
41 | #define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8) | ||
42 | |||
43 | #define PM_IRQF_LVL_SEL 0x01 /* level select */ | ||
44 | #define PM_IRQF_MASK_FE 0x02 /* mask falling edge */ | ||
45 | #define PM_IRQF_MASK_RE 0x04 /* mask rising edge */ | ||
46 | #define PM_IRQF_CLR 0x08 /* clear interrupt */ | ||
47 | #define PM_IRQF_BITS_MASK 0x70 | ||
48 | #define PM_IRQF_BITS_SHIFT 4 | ||
49 | #define PM_IRQF_WRITE 0x80 | ||
50 | |||
51 | #define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \ | ||
52 | PM_IRQF_MASK_RE) | ||
53 | |||
26 | #define REG_HWREV 0x002 /* PMIC4 revision */ | 54 | #define REG_HWREV 0x002 /* PMIC4 revision */ |
27 | #define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */ | 55 | #define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */ |
28 | 56 | ||
57 | #define PM8921_NR_IRQS 256 | ||
58 | |||
59 | struct pm_irq_chip { | ||
60 | struct device *dev; | ||
61 | struct regmap *regmap; | ||
62 | spinlock_t pm_irq_lock; | ||
63 | struct irq_domain *irqdomain; | ||
64 | unsigned int num_irqs; | ||
65 | unsigned int num_blocks; | ||
66 | unsigned int num_masters; | ||
67 | u8 config[0]; | ||
68 | }; | ||
69 | |||
29 | struct pm8921 { | 70 | struct pm8921 { |
30 | struct device *dev; | 71 | struct device *dev; |
31 | struct pm_irq_chip *irq_chip; | 72 | struct pm_irq_chip *irq_chip; |
32 | }; | 73 | }; |
33 | 74 | ||
75 | static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, unsigned int bp, | ||
76 | unsigned int *ip) | ||
77 | { | ||
78 | int rc; | ||
79 | |||
80 | spin_lock(&chip->pm_irq_lock); | ||
81 | rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); | ||
82 | if (rc) { | ||
83 | pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); | ||
84 | goto bail; | ||
85 | } | ||
86 | |||
87 | rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_IT_STATUS, ip); | ||
88 | if (rc) | ||
89 | pr_err("Failed Reading Status rc=%d\n", rc); | ||
90 | bail: | ||
91 | spin_unlock(&chip->pm_irq_lock); | ||
92 | return rc; | ||
93 | } | ||
94 | |||
95 | static int | ||
96 | pm8xxx_config_irq(struct pm_irq_chip *chip, unsigned int bp, unsigned int cp) | ||
97 | { | ||
98 | int rc; | ||
99 | |||
100 | spin_lock(&chip->pm_irq_lock); | ||
101 | rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); | ||
102 | if (rc) { | ||
103 | pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); | ||
104 | goto bail; | ||
105 | } | ||
106 | |||
107 | cp |= PM_IRQF_WRITE; | ||
108 | rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_CONFIG, cp); | ||
109 | if (rc) | ||
110 | pr_err("Failed Configuring IRQ rc=%d\n", rc); | ||
111 | bail: | ||
112 | spin_unlock(&chip->pm_irq_lock); | ||
113 | return rc; | ||
114 | } | ||
115 | |||
116 | static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) | ||
117 | { | ||
118 | int pmirq, irq, i, ret = 0; | ||
119 | unsigned int bits; | ||
120 | |||
121 | ret = pm8xxx_read_block_irq(chip, block, &bits); | ||
122 | if (ret) { | ||
123 | pr_err("Failed reading %d block ret=%d", block, ret); | ||
124 | return ret; | ||
125 | } | ||
126 | if (!bits) { | ||
127 | pr_err("block bit set in master but no irqs: %d", block); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* Check IRQ bits */ | ||
132 | for (i = 0; i < 8; i++) { | ||
133 | if (bits & (1 << i)) { | ||
134 | pmirq = block * 8 + i; | ||
135 | irq = irq_find_mapping(chip->irqdomain, pmirq); | ||
136 | generic_handle_irq(irq); | ||
137 | } | ||
138 | } | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master) | ||
143 | { | ||
144 | unsigned int blockbits; | ||
145 | int block_number, i, ret = 0; | ||
146 | |||
147 | ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_M_STATUS1 + master, | ||
148 | &blockbits); | ||
149 | if (ret) { | ||
150 | pr_err("Failed to read master %d ret=%d\n", master, ret); | ||
151 | return ret; | ||
152 | } | ||
153 | if (!blockbits) { | ||
154 | pr_err("master bit set in root but no blocks: %d", master); | ||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | for (i = 0; i < 8; i++) | ||
159 | if (blockbits & (1 << i)) { | ||
160 | block_number = master * 8 + i; /* block # */ | ||
161 | ret |= pm8xxx_irq_block_handler(chip, block_number); | ||
162 | } | ||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
167 | { | ||
168 | struct pm_irq_chip *chip = irq_desc_get_handler_data(desc); | ||
169 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); | ||
170 | unsigned int root; | ||
171 | int i, ret, masters = 0; | ||
172 | |||
173 | chained_irq_enter(irq_chip, desc); | ||
174 | |||
175 | ret = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_ROOT, &root); | ||
176 | if (ret) { | ||
177 | pr_err("Can't read root status ret=%d\n", ret); | ||
178 | return; | ||
179 | } | ||
180 | |||
181 | /* on pm8xxx series masters start from bit 1 of the root */ | ||
182 | masters = root >> 1; | ||
183 | |||
184 | /* Read allowed masters for blocks. */ | ||
185 | for (i = 0; i < chip->num_masters; i++) | ||
186 | if (masters & (1 << i)) | ||
187 | pm8xxx_irq_master_handler(chip, i); | ||
188 | |||
189 | chained_irq_exit(irq_chip, desc); | ||
190 | } | ||
191 | |||
192 | static void pm8xxx_irq_mask_ack(struct irq_data *d) | ||
193 | { | ||
194 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | ||
195 | unsigned int pmirq = irqd_to_hwirq(d); | ||
196 | int irq_bit; | ||
197 | u8 block, config; | ||
198 | |||
199 | block = pmirq / 8; | ||
200 | irq_bit = pmirq % 8; | ||
201 | |||
202 | config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; | ||
203 | pm8xxx_config_irq(chip, block, config); | ||
204 | } | ||
205 | |||
206 | static void pm8xxx_irq_unmask(struct irq_data *d) | ||
207 | { | ||
208 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | ||
209 | unsigned int pmirq = irqd_to_hwirq(d); | ||
210 | int irq_bit; | ||
211 | u8 block, config; | ||
212 | |||
213 | block = pmirq / 8; | ||
214 | irq_bit = pmirq % 8; | ||
215 | |||
216 | config = chip->config[pmirq]; | ||
217 | pm8xxx_config_irq(chip, block, config); | ||
218 | } | ||
219 | |||
220 | static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
221 | { | ||
222 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | ||
223 | unsigned int pmirq = irqd_to_hwirq(d); | ||
224 | int irq_bit; | ||
225 | u8 block, config; | ||
226 | |||
227 | block = pmirq / 8; | ||
228 | irq_bit = pmirq % 8; | ||
229 | |||
230 | chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT) | ||
231 | | PM_IRQF_MASK_ALL; | ||
232 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { | ||
233 | if (flow_type & IRQF_TRIGGER_RISING) | ||
234 | chip->config[pmirq] &= ~PM_IRQF_MASK_RE; | ||
235 | if (flow_type & IRQF_TRIGGER_FALLING) | ||
236 | chip->config[pmirq] &= ~PM_IRQF_MASK_FE; | ||
237 | } else { | ||
238 | chip->config[pmirq] |= PM_IRQF_LVL_SEL; | ||
239 | |||
240 | if (flow_type & IRQF_TRIGGER_HIGH) | ||
241 | chip->config[pmirq] &= ~PM_IRQF_MASK_RE; | ||
242 | else | ||
243 | chip->config[pmirq] &= ~PM_IRQF_MASK_FE; | ||
244 | } | ||
245 | |||
246 | config = chip->config[pmirq] | PM_IRQF_CLR; | ||
247 | return pm8xxx_config_irq(chip, block, config); | ||
248 | } | ||
249 | |||
250 | static struct irq_chip pm8xxx_irq_chip = { | ||
251 | .name = "pm8xxx", | ||
252 | .irq_mask_ack = pm8xxx_irq_mask_ack, | ||
253 | .irq_unmask = pm8xxx_irq_unmask, | ||
254 | .irq_set_type = pm8xxx_irq_set_type, | ||
255 | .flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE, | ||
256 | }; | ||
257 | |||
258 | /** | ||
259 | * pm8xxx_get_irq_stat - get the status of the irq line | ||
260 | * @chip: pointer to identify a pmic irq controller | ||
261 | * @irq: the irq number | ||
262 | * | ||
263 | * The pm8xxx gpio and mpp rely on the interrupt block to read | ||
264 | * the values on their pins. This function is to facilitate reading | ||
265 | * the status of a gpio or an mpp line. The caller has to convert the | ||
266 | * gpio number to irq number. | ||
267 | * | ||
268 | * RETURNS: | ||
269 | * an int indicating the value read on that line | ||
270 | */ | ||
271 | static int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) | ||
272 | { | ||
273 | int pmirq, rc; | ||
274 | unsigned int block, bits, bit; | ||
275 | unsigned long flags; | ||
276 | struct irq_data *irq_data = irq_get_irq_data(irq); | ||
277 | |||
278 | pmirq = irq_data->hwirq; | ||
279 | |||
280 | block = pmirq / 8; | ||
281 | bit = pmirq % 8; | ||
282 | |||
283 | spin_lock_irqsave(&chip->pm_irq_lock, flags); | ||
284 | |||
285 | rc = regmap_write(chip->regmap, SSBI_REG_ADDR_IRQ_BLK_SEL, block); | ||
286 | if (rc) { | ||
287 | pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n", | ||
288 | irq, pmirq, block, rc); | ||
289 | goto bail_out; | ||
290 | } | ||
291 | |||
292 | rc = regmap_read(chip->regmap, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits); | ||
293 | if (rc) { | ||
294 | pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", | ||
295 | irq, pmirq, block, rc); | ||
296 | goto bail_out; | ||
297 | } | ||
298 | |||
299 | rc = (bits & (1 << bit)) ? 1 : 0; | ||
300 | |||
301 | bail_out: | ||
302 | spin_unlock_irqrestore(&chip->pm_irq_lock, flags); | ||
303 | |||
304 | return rc; | ||
305 | } | ||
306 | |||
307 | static int pm8xxx_irq_domain_map(struct irq_domain *d, unsigned int irq, | ||
308 | irq_hw_number_t hwirq) | ||
309 | { | ||
310 | struct pm_irq_chip *chip = d->host_data; | ||
311 | |||
312 | irq_set_chip_and_handler(irq, &pm8xxx_irq_chip, handle_level_irq); | ||
313 | irq_set_chip_data(irq, chip); | ||
314 | #ifdef CONFIG_ARM | ||
315 | set_irq_flags(irq, IRQF_VALID); | ||
316 | #else | ||
317 | irq_set_noprobe(irq); | ||
318 | #endif | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static const struct irq_domain_ops pm8xxx_irq_domain_ops = { | ||
323 | .xlate = irq_domain_xlate_twocell, | ||
324 | .map = pm8xxx_irq_domain_map, | ||
325 | }; | ||
326 | |||
34 | static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) | 327 | static int pm8921_readb(const struct device *dev, u16 addr, u8 *val) |
35 | { | 328 | { |
36 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); | 329 | const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); |
@@ -81,42 +374,35 @@ static struct pm8xxx_drvdata pm8921_drvdata = { | |||
81 | .pmic_read_irq_stat = pm8921_read_irq_stat, | 374 | .pmic_read_irq_stat = pm8921_read_irq_stat, |
82 | }; | 375 | }; |
83 | 376 | ||
84 | static int pm8921_add_subdevices(const struct pm8921_platform_data | 377 | static const struct regmap_config ssbi_regmap_config = { |
85 | *pdata, | 378 | .reg_bits = 16, |
86 | struct pm8921 *pmic, | 379 | .val_bits = 8, |
87 | u32 rev) | 380 | .max_register = 0x3ff, |
88 | { | 381 | .fast_io = true, |
89 | int ret = 0, irq_base = 0; | 382 | .reg_read = ssbi_reg_read, |
90 | struct pm_irq_chip *irq_chip; | 383 | .reg_write = ssbi_reg_write |
91 | 384 | }; | |
92 | if (pdata->irq_pdata) { | ||
93 | pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS; | ||
94 | pdata->irq_pdata->irq_cdata.rev = rev; | ||
95 | irq_base = pdata->irq_pdata->irq_base; | ||
96 | irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); | ||
97 | 385 | ||
98 | if (IS_ERR(irq_chip)) { | 386 | static const struct of_device_id pm8921_id_table[] = { |
99 | pr_err("Failed to init interrupts ret=%ld\n", | 387 | { .compatible = "qcom,pm8058", }, |
100 | PTR_ERR(irq_chip)); | 388 | { .compatible = "qcom,pm8921", }, |
101 | return PTR_ERR(irq_chip); | 389 | { } |
102 | } | 390 | }; |
103 | pmic->irq_chip = irq_chip; | 391 | MODULE_DEVICE_TABLE(of, pm8921_id_table); |
104 | } | ||
105 | return ret; | ||
106 | } | ||
107 | 392 | ||
108 | static int pm8921_probe(struct platform_device *pdev) | 393 | static int pm8921_probe(struct platform_device *pdev) |
109 | { | 394 | { |
110 | const struct pm8921_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
111 | struct pm8921 *pmic; | 395 | struct pm8921 *pmic; |
112 | int rc; | 396 | struct regmap *regmap; |
113 | u8 val; | 397 | int irq, rc; |
398 | unsigned int val; | ||
114 | u32 rev; | 399 | u32 rev; |
400 | struct pm_irq_chip *chip; | ||
401 | unsigned int nirqs = PM8921_NR_IRQS; | ||
115 | 402 | ||
116 | if (!pdata) { | 403 | irq = platform_get_irq(pdev, 0); |
117 | pr_err("missing platform data\n"); | 404 | if (irq < 0) |
118 | return -EINVAL; | 405 | return irq; |
119 | } | ||
120 | 406 | ||
121 | pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL); | 407 | pmic = devm_kzalloc(&pdev->dev, sizeof(struct pm8921), GFP_KERNEL); |
122 | if (!pmic) { | 408 | if (!pmic) { |
@@ -124,8 +410,13 @@ static int pm8921_probe(struct platform_device *pdev) | |||
124 | return -ENOMEM; | 410 | return -ENOMEM; |
125 | } | 411 | } |
126 | 412 | ||
413 | regmap = devm_regmap_init(&pdev->dev, NULL, pdev->dev.parent, | ||
414 | &ssbi_regmap_config); | ||
415 | if (IS_ERR(regmap)) | ||
416 | return PTR_ERR(regmap); | ||
417 | |||
127 | /* Read PMIC chip revision */ | 418 | /* Read PMIC chip revision */ |
128 | rc = ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val)); | 419 | rc = regmap_read(regmap, REG_HWREV, &val); |
129 | if (rc) { | 420 | if (rc) { |
130 | pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc); | 421 | pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc); |
131 | return rc; | 422 | return rc; |
@@ -134,7 +425,7 @@ static int pm8921_probe(struct platform_device *pdev) | |||
134 | rev = val; | 425 | rev = val; |
135 | 426 | ||
136 | /* Read PMIC chip revision 2 */ | 427 | /* Read PMIC chip revision 2 */ |
137 | rc = ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val)); | 428 | rc = regmap_read(regmap, REG_HWREV_2, &val); |
138 | if (rc) { | 429 | if (rc) { |
139 | pr_err("Failed to read hw rev 2 reg %d:rc=%d\n", | 430 | pr_err("Failed to read hw rev 2 reg %d:rc=%d\n", |
140 | REG_HWREV_2, rc); | 431 | REG_HWREV_2, rc); |
@@ -147,37 +438,56 @@ static int pm8921_probe(struct platform_device *pdev) | |||
147 | pm8921_drvdata.pm_chip_data = pmic; | 438 | pm8921_drvdata.pm_chip_data = pmic; |
148 | platform_set_drvdata(pdev, &pm8921_drvdata); | 439 | platform_set_drvdata(pdev, &pm8921_drvdata); |
149 | 440 | ||
150 | rc = pm8921_add_subdevices(pdata, pmic, rev); | 441 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip) + |
442 | sizeof(chip->config[0]) * nirqs, | ||
443 | GFP_KERNEL); | ||
444 | if (!chip) | ||
445 | return -ENOMEM; | ||
446 | |||
447 | pmic->irq_chip = chip; | ||
448 | chip->dev = &pdev->dev; | ||
449 | chip->regmap = regmap; | ||
450 | chip->num_irqs = nirqs; | ||
451 | chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); | ||
452 | chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); | ||
453 | spin_lock_init(&chip->pm_irq_lock); | ||
454 | |||
455 | chip->irqdomain = irq_domain_add_linear(pdev->dev.of_node, nirqs, | ||
456 | &pm8xxx_irq_domain_ops, | ||
457 | chip); | ||
458 | if (!chip->irqdomain) | ||
459 | return -ENODEV; | ||
460 | |||
461 | irq_set_handler_data(irq, chip); | ||
462 | irq_set_chained_handler(irq, pm8xxx_irq_handler); | ||
463 | irq_set_irq_wake(irq, 1); | ||
464 | |||
465 | rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); | ||
151 | if (rc) { | 466 | if (rc) { |
152 | pr_err("Cannot add subdevices rc=%d\n", rc); | 467 | irq_set_chained_handler(irq, NULL); |
153 | goto err; | 468 | irq_set_handler_data(irq, NULL); |
469 | irq_domain_remove(chip->irqdomain); | ||
154 | } | 470 | } |
155 | 471 | ||
156 | /* gpio might not work if no irq device is found */ | 472 | return rc; |
157 | WARN_ON(pmic->irq_chip == NULL); | 473 | } |
158 | 474 | ||
475 | static int pm8921_remove_child(struct device *dev, void *unused) | ||
476 | { | ||
477 | platform_device_unregister(to_platform_device(dev)); | ||
159 | return 0; | 478 | return 0; |
160 | |||
161 | err: | ||
162 | mfd_remove_devices(pmic->dev); | ||
163 | return rc; | ||
164 | } | 479 | } |
165 | 480 | ||
166 | static int pm8921_remove(struct platform_device *pdev) | 481 | static int pm8921_remove(struct platform_device *pdev) |
167 | { | 482 | { |
168 | struct pm8xxx_drvdata *drvdata; | 483 | int irq = platform_get_irq(pdev, 0); |
169 | struct pm8921 *pmic = NULL; | 484 | struct pm8921 *pmic = pm8921_drvdata.pm_chip_data; |
170 | 485 | struct pm_irq_chip *chip = pmic->irq_chip; | |
171 | drvdata = platform_get_drvdata(pdev); | 486 | |
172 | if (drvdata) | 487 | device_for_each_child(&pdev->dev, NULL, pm8921_remove_child); |
173 | pmic = drvdata->pm_chip_data; | 488 | irq_set_chained_handler(irq, NULL); |
174 | if (pmic) { | 489 | irq_set_handler_data(irq, NULL); |
175 | mfd_remove_devices(pmic->dev); | 490 | irq_domain_remove(chip->irqdomain); |
176 | if (pmic->irq_chip) { | ||
177 | pm8xxx_irq_exit(pmic->irq_chip); | ||
178 | pmic->irq_chip = NULL; | ||
179 | } | ||
180 | } | ||
181 | 491 | ||
182 | return 0; | 492 | return 0; |
183 | } | 493 | } |
@@ -188,6 +498,7 @@ static struct platform_driver pm8921_driver = { | |||
188 | .driver = { | 498 | .driver = { |
189 | .name = "pm8921-core", | 499 | .name = "pm8921-core", |
190 | .owner = THIS_MODULE, | 500 | .owner = THIS_MODULE, |
501 | .of_match_table = pm8921_id_table, | ||
191 | }, | 502 | }, |
192 | }; | 503 | }; |
193 | 504 | ||
diff --git a/drivers/mfd/pm8xxx-irq.c b/drivers/mfd/pm8xxx-irq.c deleted file mode 100644 index 1360e20adf11..000000000000 --- a/drivers/mfd/pm8xxx-irq.c +++ /dev/null | |||
@@ -1,371 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 and | ||
6 | * only version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "%s: " fmt, __func__ | ||
15 | |||
16 | #include <linux/err.h> | ||
17 | #include <linux/interrupt.h> | ||
18 | #include <linux/irq.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/mfd/pm8xxx/core.h> | ||
21 | #include <linux/mfd/pm8xxx/irq.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | /* PMIC8xxx IRQ */ | ||
26 | |||
27 | #define SSBI_REG_ADDR_IRQ_BASE 0x1BB | ||
28 | |||
29 | #define SSBI_REG_ADDR_IRQ_ROOT (SSBI_REG_ADDR_IRQ_BASE + 0) | ||
30 | #define SSBI_REG_ADDR_IRQ_M_STATUS1 (SSBI_REG_ADDR_IRQ_BASE + 1) | ||
31 | #define SSBI_REG_ADDR_IRQ_M_STATUS2 (SSBI_REG_ADDR_IRQ_BASE + 2) | ||
32 | #define SSBI_REG_ADDR_IRQ_M_STATUS3 (SSBI_REG_ADDR_IRQ_BASE + 3) | ||
33 | #define SSBI_REG_ADDR_IRQ_M_STATUS4 (SSBI_REG_ADDR_IRQ_BASE + 4) | ||
34 | #define SSBI_REG_ADDR_IRQ_BLK_SEL (SSBI_REG_ADDR_IRQ_BASE + 5) | ||
35 | #define SSBI_REG_ADDR_IRQ_IT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 6) | ||
36 | #define SSBI_REG_ADDR_IRQ_CONFIG (SSBI_REG_ADDR_IRQ_BASE + 7) | ||
37 | #define SSBI_REG_ADDR_IRQ_RT_STATUS (SSBI_REG_ADDR_IRQ_BASE + 8) | ||
38 | |||
39 | #define PM_IRQF_LVL_SEL 0x01 /* level select */ | ||
40 | #define PM_IRQF_MASK_FE 0x02 /* mask falling edge */ | ||
41 | #define PM_IRQF_MASK_RE 0x04 /* mask rising edge */ | ||
42 | #define PM_IRQF_CLR 0x08 /* clear interrupt */ | ||
43 | #define PM_IRQF_BITS_MASK 0x70 | ||
44 | #define PM_IRQF_BITS_SHIFT 4 | ||
45 | #define PM_IRQF_WRITE 0x80 | ||
46 | |||
47 | #define PM_IRQF_MASK_ALL (PM_IRQF_MASK_FE | \ | ||
48 | PM_IRQF_MASK_RE) | ||
49 | |||
50 | struct pm_irq_chip { | ||
51 | struct device *dev; | ||
52 | spinlock_t pm_irq_lock; | ||
53 | unsigned int devirq; | ||
54 | unsigned int irq_base; | ||
55 | unsigned int num_irqs; | ||
56 | unsigned int num_blocks; | ||
57 | unsigned int num_masters; | ||
58 | u8 config[0]; | ||
59 | }; | ||
60 | |||
61 | static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp) | ||
62 | { | ||
63 | return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp); | ||
64 | } | ||
65 | |||
66 | static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp) | ||
67 | { | ||
68 | return pm8xxx_readb(chip->dev, | ||
69 | SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp); | ||
70 | } | ||
71 | |||
72 | static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip) | ||
73 | { | ||
74 | int rc; | ||
75 | |||
76 | spin_lock(&chip->pm_irq_lock); | ||
77 | rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); | ||
78 | if (rc) { | ||
79 | pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); | ||
80 | goto bail; | ||
81 | } | ||
82 | |||
83 | rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip); | ||
84 | if (rc) | ||
85 | pr_err("Failed Reading Status rc=%d\n", rc); | ||
86 | bail: | ||
87 | spin_unlock(&chip->pm_irq_lock); | ||
88 | return rc; | ||
89 | } | ||
90 | |||
91 | static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp) | ||
92 | { | ||
93 | int rc; | ||
94 | |||
95 | spin_lock(&chip->pm_irq_lock); | ||
96 | rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp); | ||
97 | if (rc) { | ||
98 | pr_err("Failed Selecting Block %d rc=%d\n", bp, rc); | ||
99 | goto bail; | ||
100 | } | ||
101 | |||
102 | cp |= PM_IRQF_WRITE; | ||
103 | rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp); | ||
104 | if (rc) | ||
105 | pr_err("Failed Configuring IRQ rc=%d\n", rc); | ||
106 | bail: | ||
107 | spin_unlock(&chip->pm_irq_lock); | ||
108 | return rc; | ||
109 | } | ||
110 | |||
111 | static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block) | ||
112 | { | ||
113 | int pmirq, irq, i, ret = 0; | ||
114 | u8 bits; | ||
115 | |||
116 | ret = pm8xxx_read_block_irq(chip, block, &bits); | ||
117 | if (ret) { | ||
118 | pr_err("Failed reading %d block ret=%d", block, ret); | ||
119 | return ret; | ||
120 | } | ||
121 | if (!bits) { | ||
122 | pr_err("block bit set in master but no irqs: %d", block); | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | /* Check IRQ bits */ | ||
127 | for (i = 0; i < 8; i++) { | ||
128 | if (bits & (1 << i)) { | ||
129 | pmirq = block * 8 + i; | ||
130 | irq = pmirq + chip->irq_base; | ||
131 | generic_handle_irq(irq); | ||
132 | } | ||
133 | } | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master) | ||
138 | { | ||
139 | u8 blockbits; | ||
140 | int block_number, i, ret = 0; | ||
141 | |||
142 | ret = pm8xxx_read_master_irq(chip, master, &blockbits); | ||
143 | if (ret) { | ||
144 | pr_err("Failed to read master %d ret=%d\n", master, ret); | ||
145 | return ret; | ||
146 | } | ||
147 | if (!blockbits) { | ||
148 | pr_err("master bit set in root but no blocks: %d", master); | ||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | for (i = 0; i < 8; i++) | ||
153 | if (blockbits & (1 << i)) { | ||
154 | block_number = master * 8 + i; /* block # */ | ||
155 | ret |= pm8xxx_irq_block_handler(chip, block_number); | ||
156 | } | ||
157 | return ret; | ||
158 | } | ||
159 | |||
160 | static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
161 | { | ||
162 | struct pm_irq_chip *chip = irq_desc_get_handler_data(desc); | ||
163 | struct irq_chip *irq_chip = irq_desc_get_chip(desc); | ||
164 | u8 root; | ||
165 | int i, ret, masters = 0; | ||
166 | |||
167 | ret = pm8xxx_read_root_irq(chip, &root); | ||
168 | if (ret) { | ||
169 | pr_err("Can't read root status ret=%d\n", ret); | ||
170 | return; | ||
171 | } | ||
172 | |||
173 | /* on pm8xxx series masters start from bit 1 of the root */ | ||
174 | masters = root >> 1; | ||
175 | |||
176 | /* Read allowed masters for blocks. */ | ||
177 | for (i = 0; i < chip->num_masters; i++) | ||
178 | if (masters & (1 << i)) | ||
179 | pm8xxx_irq_master_handler(chip, i); | ||
180 | |||
181 | irq_chip->irq_ack(&desc->irq_data); | ||
182 | } | ||
183 | |||
184 | static void pm8xxx_irq_mask_ack(struct irq_data *d) | ||
185 | { | ||
186 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | ||
187 | unsigned int pmirq = d->irq - chip->irq_base; | ||
188 | int master, irq_bit; | ||
189 | u8 block, config; | ||
190 | |||
191 | block = pmirq / 8; | ||
192 | master = block / 8; | ||
193 | irq_bit = pmirq % 8; | ||
194 | |||
195 | config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR; | ||
196 | pm8xxx_config_irq(chip, block, config); | ||
197 | } | ||
198 | |||
199 | static void pm8xxx_irq_unmask(struct irq_data *d) | ||
200 | { | ||
201 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | ||
202 | unsigned int pmirq = d->irq - chip->irq_base; | ||
203 | int master, irq_bit; | ||
204 | u8 block, config; | ||
205 | |||
206 | block = pmirq / 8; | ||
207 | master = block / 8; | ||
208 | irq_bit = pmirq % 8; | ||
209 | |||
210 | config = chip->config[pmirq]; | ||
211 | pm8xxx_config_irq(chip, block, config); | ||
212 | } | ||
213 | |||
214 | static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type) | ||
215 | { | ||
216 | struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d); | ||
217 | unsigned int pmirq = d->irq - chip->irq_base; | ||
218 | int master, irq_bit; | ||
219 | u8 block, config; | ||
220 | |||
221 | block = pmirq / 8; | ||
222 | master = block / 8; | ||
223 | irq_bit = pmirq % 8; | ||
224 | |||
225 | chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT) | ||
226 | | PM_IRQF_MASK_ALL; | ||
227 | if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { | ||
228 | if (flow_type & IRQF_TRIGGER_RISING) | ||
229 | chip->config[pmirq] &= ~PM_IRQF_MASK_RE; | ||
230 | if (flow_type & IRQF_TRIGGER_FALLING) | ||
231 | chip->config[pmirq] &= ~PM_IRQF_MASK_FE; | ||
232 | } else { | ||
233 | chip->config[pmirq] |= PM_IRQF_LVL_SEL; | ||
234 | |||
235 | if (flow_type & IRQF_TRIGGER_HIGH) | ||
236 | chip->config[pmirq] &= ~PM_IRQF_MASK_RE; | ||
237 | else | ||
238 | chip->config[pmirq] &= ~PM_IRQF_MASK_FE; | ||
239 | } | ||
240 | |||
241 | config = chip->config[pmirq] | PM_IRQF_CLR; | ||
242 | return pm8xxx_config_irq(chip, block, config); | ||
243 | } | ||
244 | |||
245 | static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on) | ||
246 | { | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static struct irq_chip pm8xxx_irq_chip = { | ||
251 | .name = "pm8xxx", | ||
252 | .irq_mask_ack = pm8xxx_irq_mask_ack, | ||
253 | .irq_unmask = pm8xxx_irq_unmask, | ||
254 | .irq_set_type = pm8xxx_irq_set_type, | ||
255 | .irq_set_wake = pm8xxx_irq_set_wake, | ||
256 | .flags = IRQCHIP_MASK_ON_SUSPEND, | ||
257 | }; | ||
258 | |||
259 | /** | ||
260 | * pm8xxx_get_irq_stat - get the status of the irq line | ||
261 | * @chip: pointer to identify a pmic irq controller | ||
262 | * @irq: the irq number | ||
263 | * | ||
264 | * The pm8xxx gpio and mpp rely on the interrupt block to read | ||
265 | * the values on their pins. This function is to facilitate reading | ||
266 | * the status of a gpio or an mpp line. The caller has to convert the | ||
267 | * gpio number to irq number. | ||
268 | * | ||
269 | * RETURNS: | ||
270 | * an int indicating the value read on that line | ||
271 | */ | ||
272 | int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq) | ||
273 | { | ||
274 | int pmirq, rc; | ||
275 | u8 block, bits, bit; | ||
276 | unsigned long flags; | ||
277 | |||
278 | if (chip == NULL || irq < chip->irq_base || | ||
279 | irq >= chip->irq_base + chip->num_irqs) | ||
280 | return -EINVAL; | ||
281 | |||
282 | pmirq = irq - chip->irq_base; | ||
283 | |||
284 | block = pmirq / 8; | ||
285 | bit = pmirq % 8; | ||
286 | |||
287 | spin_lock_irqsave(&chip->pm_irq_lock, flags); | ||
288 | |||
289 | rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block); | ||
290 | if (rc) { | ||
291 | pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n", | ||
292 | irq, pmirq, block, rc); | ||
293 | goto bail_out; | ||
294 | } | ||
295 | |||
296 | rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits); | ||
297 | if (rc) { | ||
298 | pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n", | ||
299 | irq, pmirq, block, rc); | ||
300 | goto bail_out; | ||
301 | } | ||
302 | |||
303 | rc = (bits & (1 << bit)) ? 1 : 0; | ||
304 | |||
305 | bail_out: | ||
306 | spin_unlock_irqrestore(&chip->pm_irq_lock, flags); | ||
307 | |||
308 | return rc; | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat); | ||
311 | |||
312 | struct pm_irq_chip * pm8xxx_irq_init(struct device *dev, | ||
313 | const struct pm8xxx_irq_platform_data *pdata) | ||
314 | { | ||
315 | struct pm_irq_chip *chip; | ||
316 | int devirq, rc; | ||
317 | unsigned int pmirq; | ||
318 | |||
319 | if (!pdata) { | ||
320 | pr_err("No platform data\n"); | ||
321 | return ERR_PTR(-EINVAL); | ||
322 | } | ||
323 | |||
324 | devirq = pdata->devirq; | ||
325 | if (devirq < 0) { | ||
326 | pr_err("missing devirq\n"); | ||
327 | rc = devirq; | ||
328 | return ERR_PTR(-EINVAL); | ||
329 | } | ||
330 | |||
331 | chip = kzalloc(sizeof(struct pm_irq_chip) | ||
332 | + sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL); | ||
333 | if (!chip) { | ||
334 | pr_err("Cannot alloc pm_irq_chip struct\n"); | ||
335 | return ERR_PTR(-EINVAL); | ||
336 | } | ||
337 | |||
338 | chip->dev = dev; | ||
339 | chip->devirq = devirq; | ||
340 | chip->irq_base = pdata->irq_base; | ||
341 | chip->num_irqs = pdata->irq_cdata.nirqs; | ||
342 | chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8); | ||
343 | chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8); | ||
344 | spin_lock_init(&chip->pm_irq_lock); | ||
345 | |||
346 | for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) { | ||
347 | irq_set_chip_and_handler(chip->irq_base + pmirq, | ||
348 | &pm8xxx_irq_chip, | ||
349 | handle_level_irq); | ||
350 | irq_set_chip_data(chip->irq_base + pmirq, chip); | ||
351 | #ifdef CONFIG_ARM | ||
352 | set_irq_flags(chip->irq_base + pmirq, IRQF_VALID); | ||
353 | #else | ||
354 | irq_set_noprobe(chip->irq_base + pmirq); | ||
355 | #endif | ||
356 | } | ||
357 | |||
358 | irq_set_irq_type(devirq, pdata->irq_trigger_flag); | ||
359 | irq_set_handler_data(devirq, chip); | ||
360 | irq_set_chained_handler(devirq, pm8xxx_irq_handler); | ||
361 | set_irq_wake(devirq, 1); | ||
362 | |||
363 | return chip; | ||
364 | } | ||
365 | |||
366 | int pm8xxx_irq_exit(struct pm_irq_chip *chip) | ||
367 | { | ||
368 | irq_set_chained_handler(chip->devirq, NULL); | ||
369 | kfree(chip); | ||
370 | return 0; | ||
371 | } | ||
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c index b41db5968706..bb8502020274 100644 --- a/drivers/mfd/rc5t583-irq.c +++ b/drivers/mfd/rc5t583-irq.c | |||
@@ -22,7 +22,6 @@ | |||
22 | */ | 22 | */ |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/init.h> | ||
26 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
27 | #include <linux/mfd/rc5t583.h> | 26 | #include <linux/mfd/rc5t583.h> |
28 | 27 | ||
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index d346146249a2..c79569750be9 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -19,7 +19,6 @@ | |||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | #include <linux/init.h> | ||
23 | #include <linux/module.h> | 22 | #include <linux/module.h> |
24 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
25 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c index c8f345f7e9a2..663f8a37aa6b 100644 --- a/drivers/mfd/retu-mfd.c +++ b/drivers/mfd/retu-mfd.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
21 | #include <linux/irq.h> | 21 | #include <linux/irq.h> |
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
24 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
25 | #include <linux/module.h> | 24 | #include <linux/module.h> |
diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c new file mode 100644 index 000000000000..b53b9d46cc45 --- /dev/null +++ b/drivers/mfd/rtsx_usb.c | |||
@@ -0,0 +1,760 @@ | |||
1 | /* Driver for Realtek USB card reader | ||
2 | * | ||
3 | * Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License version 2 | ||
7 | * as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, see <http://www.gnu.org/licenses/>. | ||
16 | * | ||
17 | * Author: | ||
18 | * Roger Tseng <rogerable@realtek.com> | ||
19 | */ | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/mfd/core.h> | ||
26 | #include <linux/mfd/rtsx_usb.h> | ||
27 | |||
28 | static int polling_pipe = 1; | ||
29 | module_param(polling_pipe, int, S_IRUGO | S_IWUSR); | ||
30 | MODULE_PARM_DESC(polling_pipe, "polling pipe (0: ctl, 1: bulk)"); | ||
31 | |||
32 | static struct mfd_cell rtsx_usb_cells[] = { | ||
33 | [RTSX_USB_SD_CARD] = { | ||
34 | .name = "rtsx_usb_sdmmc", | ||
35 | .pdata_size = 0, | ||
36 | }, | ||
37 | [RTSX_USB_MS_CARD] = { | ||
38 | .name = "rtsx_usb_ms", | ||
39 | .pdata_size = 0, | ||
40 | }, | ||
41 | }; | ||
42 | |||
43 | static void rtsx_usb_sg_timed_out(unsigned long data) | ||
44 | { | ||
45 | struct rtsx_ucr *ucr = (struct rtsx_ucr *)data; | ||
46 | |||
47 | dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__); | ||
48 | usb_sg_cancel(&ucr->current_sg); | ||
49 | |||
50 | /* we know the cancellation is caused by time-out */ | ||
51 | ucr->current_sg.status = -ETIMEDOUT; | ||
52 | } | ||
53 | |||
54 | static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr, | ||
55 | unsigned int pipe, struct scatterlist *sg, int num_sg, | ||
56 | unsigned int length, unsigned int *act_len, int timeout) | ||
57 | { | ||
58 | int ret; | ||
59 | |||
60 | dev_dbg(&ucr->pusb_intf->dev, "%s: xfer %u bytes, %d entries\n", | ||
61 | __func__, length, num_sg); | ||
62 | ret = usb_sg_init(&ucr->current_sg, ucr->pusb_dev, pipe, 0, | ||
63 | sg, num_sg, length, GFP_NOIO); | ||
64 | if (ret) | ||
65 | return ret; | ||
66 | |||
67 | ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout); | ||
68 | add_timer(&ucr->sg_timer); | ||
69 | usb_sg_wait(&ucr->current_sg); | ||
70 | del_timer(&ucr->sg_timer); | ||
71 | |||
72 | if (act_len) | ||
73 | *act_len = ucr->current_sg.bytes; | ||
74 | |||
75 | return ucr->current_sg.status; | ||
76 | } | ||
77 | |||
78 | int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe, | ||
79 | void *buf, unsigned int len, int num_sg, | ||
80 | unsigned int *act_len, int timeout) | ||
81 | { | ||
82 | if (timeout < 600) | ||
83 | timeout = 600; | ||
84 | |||
85 | if (num_sg) | ||
86 | return rtsx_usb_bulk_transfer_sglist(ucr, pipe, | ||
87 | (struct scatterlist *)buf, num_sg, len, act_len, | ||
88 | timeout); | ||
89 | else | ||
90 | return usb_bulk_msg(ucr->pusb_dev, pipe, buf, len, act_len, | ||
91 | timeout); | ||
92 | } | ||
93 | EXPORT_SYMBOL_GPL(rtsx_usb_transfer_data); | ||
94 | |||
95 | static inline void rtsx_usb_seq_cmd_hdr(struct rtsx_ucr *ucr, | ||
96 | u16 addr, u16 len, u8 seq_type) | ||
97 | { | ||
98 | rtsx_usb_cmd_hdr_tag(ucr); | ||
99 | |||
100 | ucr->cmd_buf[PACKET_TYPE] = seq_type; | ||
101 | ucr->cmd_buf[5] = (u8)(len >> 8); | ||
102 | ucr->cmd_buf[6] = (u8)len; | ||
103 | ucr->cmd_buf[8] = (u8)(addr >> 8); | ||
104 | ucr->cmd_buf[9] = (u8)addr; | ||
105 | |||
106 | if (seq_type == SEQ_WRITE) | ||
107 | ucr->cmd_buf[STAGE_FLAG] = 0; | ||
108 | else | ||
109 | ucr->cmd_buf[STAGE_FLAG] = STAGE_R; | ||
110 | } | ||
111 | |||
112 | static int rtsx_usb_seq_write_register(struct rtsx_ucr *ucr, | ||
113 | u16 addr, u16 len, u8 *data) | ||
114 | { | ||
115 | u16 cmd_len = ALIGN(SEQ_WRITE_DATA_OFFSET + len, 4); | ||
116 | |||
117 | if (!data) | ||
118 | return -EINVAL; | ||
119 | |||
120 | if (cmd_len > IOBUF_SIZE) | ||
121 | return -EINVAL; | ||
122 | |||
123 | rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_WRITE); | ||
124 | memcpy(ucr->cmd_buf + SEQ_WRITE_DATA_OFFSET, data, len); | ||
125 | |||
126 | return rtsx_usb_transfer_data(ucr, | ||
127 | usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT), | ||
128 | ucr->cmd_buf, cmd_len, 0, NULL, 100); | ||
129 | } | ||
130 | |||
131 | static int rtsx_usb_seq_read_register(struct rtsx_ucr *ucr, | ||
132 | u16 addr, u16 len, u8 *data) | ||
133 | { | ||
134 | int i, ret; | ||
135 | u16 rsp_len = round_down(len, 4); | ||
136 | u16 res_len = len - rsp_len; | ||
137 | |||
138 | if (!data) | ||
139 | return -EINVAL; | ||
140 | |||
141 | /* 4-byte aligned part */ | ||
142 | if (rsp_len) { | ||
143 | rtsx_usb_seq_cmd_hdr(ucr, addr, len, SEQ_READ); | ||
144 | ret = rtsx_usb_transfer_data(ucr, | ||
145 | usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT), | ||
146 | ucr->cmd_buf, 12, 0, NULL, 100); | ||
147 | if (ret) | ||
148 | return ret; | ||
149 | |||
150 | ret = rtsx_usb_transfer_data(ucr, | ||
151 | usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN), | ||
152 | data, rsp_len, 0, NULL, 100); | ||
153 | if (ret) | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | /* unaligned part */ | ||
158 | for (i = 0; i < res_len; i++) { | ||
159 | ret = rtsx_usb_read_register(ucr, addr + rsp_len + i, | ||
160 | data + rsp_len + i); | ||
161 | if (ret) | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | int rtsx_usb_read_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len) | ||
169 | { | ||
170 | return rtsx_usb_seq_read_register(ucr, PPBUF_BASE2, (u16)buf_len, buf); | ||
171 | } | ||
172 | EXPORT_SYMBOL_GPL(rtsx_usb_read_ppbuf); | ||
173 | |||
174 | int rtsx_usb_write_ppbuf(struct rtsx_ucr *ucr, u8 *buf, int buf_len) | ||
175 | { | ||
176 | return rtsx_usb_seq_write_register(ucr, PPBUF_BASE2, (u16)buf_len, buf); | ||
177 | } | ||
178 | EXPORT_SYMBOL_GPL(rtsx_usb_write_ppbuf); | ||
179 | |||
180 | int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr, | ||
181 | u8 mask, u8 data) | ||
182 | { | ||
183 | u16 value, index; | ||
184 | |||
185 | addr |= EP0_WRITE_REG_CMD << EP0_OP_SHIFT; | ||
186 | value = swab16(addr); | ||
187 | index = mask | data << 8; | ||
188 | |||
189 | return usb_control_msg(ucr->pusb_dev, | ||
190 | usb_sndctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP, | ||
191 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
192 | value, index, NULL, 0, 100); | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register); | ||
195 | |||
196 | int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data) | ||
197 | { | ||
198 | u16 value; | ||
199 | |||
200 | if (!data) | ||
201 | return -EINVAL; | ||
202 | *data = 0; | ||
203 | |||
204 | addr |= EP0_READ_REG_CMD << EP0_OP_SHIFT; | ||
205 | value = swab16(addr); | ||
206 | |||
207 | return usb_control_msg(ucr->pusb_dev, | ||
208 | usb_rcvctrlpipe(ucr->pusb_dev, 0), RTSX_USB_REQ_REG_OP, | ||
209 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
210 | value, 0, data, 1, 100); | ||
211 | } | ||
212 | EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register); | ||
213 | |||
214 | void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, u8 cmd_type, u16 reg_addr, | ||
215 | u8 mask, u8 data) | ||
216 | { | ||
217 | int i; | ||
218 | |||
219 | if (ucr->cmd_idx < (IOBUF_SIZE - CMD_OFFSET) / 4) { | ||
220 | i = CMD_OFFSET + ucr->cmd_idx * 4; | ||
221 | |||
222 | ucr->cmd_buf[i++] = ((cmd_type & 0x03) << 6) | | ||
223 | (u8)((reg_addr >> 8) & 0x3F); | ||
224 | ucr->cmd_buf[i++] = (u8)reg_addr; | ||
225 | ucr->cmd_buf[i++] = mask; | ||
226 | ucr->cmd_buf[i++] = data; | ||
227 | |||
228 | ucr->cmd_idx++; | ||
229 | } | ||
230 | } | ||
231 | EXPORT_SYMBOL_GPL(rtsx_usb_add_cmd); | ||
232 | |||
233 | int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout) | ||
234 | { | ||
235 | int ret; | ||
236 | |||
237 | ucr->cmd_buf[CNT_H] = (u8)(ucr->cmd_idx >> 8); | ||
238 | ucr->cmd_buf[CNT_L] = (u8)(ucr->cmd_idx); | ||
239 | ucr->cmd_buf[STAGE_FLAG] = flag; | ||
240 | |||
241 | ret = rtsx_usb_transfer_data(ucr, | ||
242 | usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT), | ||
243 | ucr->cmd_buf, ucr->cmd_idx * 4 + CMD_OFFSET, | ||
244 | 0, NULL, timeout); | ||
245 | if (ret) { | ||
246 | rtsx_usb_clear_fsm_err(ucr); | ||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | return 0; | ||
251 | } | ||
252 | EXPORT_SYMBOL_GPL(rtsx_usb_send_cmd); | ||
253 | |||
254 | int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout) | ||
255 | { | ||
256 | if (rsp_len <= 0) | ||
257 | return -EINVAL; | ||
258 | |||
259 | rsp_len = ALIGN(rsp_len, 4); | ||
260 | |||
261 | return rtsx_usb_transfer_data(ucr, | ||
262 | usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN), | ||
263 | ucr->rsp_buf, rsp_len, 0, NULL, timeout); | ||
264 | } | ||
265 | EXPORT_SYMBOL_GPL(rtsx_usb_get_rsp); | ||
266 | |||
267 | static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr *ucr, u16 *status) | ||
268 | { | ||
269 | int ret; | ||
270 | |||
271 | rtsx_usb_init_cmd(ucr); | ||
272 | rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_EXIST, 0x00, 0x00); | ||
273 | rtsx_usb_add_cmd(ucr, READ_REG_CMD, OCPSTAT, 0x00, 0x00); | ||
274 | ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100); | ||
275 | if (ret) | ||
276 | return ret; | ||
277 | |||
278 | ret = rtsx_usb_get_rsp(ucr, 2, 100); | ||
279 | if (ret) | ||
280 | return ret; | ||
281 | |||
282 | *status = ((ucr->rsp_buf[0] >> 2) & 0x0f) | | ||
283 | ((ucr->rsp_buf[1] & 0x03) << 4); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | int rtsx_usb_get_card_status(struct rtsx_ucr *ucr, u16 *status) | ||
289 | { | ||
290 | int ret; | ||
291 | |||
292 | if (!status) | ||
293 | return -EINVAL; | ||
294 | |||
295 | if (polling_pipe == 0) | ||
296 | ret = usb_control_msg(ucr->pusb_dev, | ||
297 | usb_rcvctrlpipe(ucr->pusb_dev, 0), | ||
298 | RTSX_USB_REQ_POLL, | ||
299 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
300 | 0, 0, status, 2, 100); | ||
301 | else | ||
302 | ret = rtsx_usb_get_status_with_bulk(ucr, status); | ||
303 | |||
304 | /* usb_control_msg may return positive when success */ | ||
305 | if (ret < 0) | ||
306 | return ret; | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | EXPORT_SYMBOL_GPL(rtsx_usb_get_card_status); | ||
311 | |||
312 | static int rtsx_usb_write_phy_register(struct rtsx_ucr *ucr, u8 addr, u8 val) | ||
313 | { | ||
314 | dev_dbg(&ucr->pusb_intf->dev, "Write 0x%x to phy register 0x%x\n", | ||
315 | val, addr); | ||
316 | |||
317 | rtsx_usb_init_cmd(ucr); | ||
318 | |||
319 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VSTAIN, 0xFF, val); | ||
320 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F); | ||
321 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); | ||
322 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); | ||
323 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); | ||
324 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VCONTROL, | ||
325 | 0xFF, (addr >> 4) & 0x0F); | ||
326 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); | ||
327 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); | ||
328 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); | ||
329 | |||
330 | return rtsx_usb_send_cmd(ucr, MODE_C, 100); | ||
331 | } | ||
332 | |||
333 | int rtsx_usb_write_register(struct rtsx_ucr *ucr, u16 addr, u8 mask, u8 data) | ||
334 | { | ||
335 | rtsx_usb_init_cmd(ucr); | ||
336 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, addr, mask, data); | ||
337 | return rtsx_usb_send_cmd(ucr, MODE_C, 100); | ||
338 | } | ||
339 | EXPORT_SYMBOL_GPL(rtsx_usb_write_register); | ||
340 | |||
341 | int rtsx_usb_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data) | ||
342 | { | ||
343 | int ret; | ||
344 | |||
345 | if (data != NULL) | ||
346 | *data = 0; | ||
347 | |||
348 | rtsx_usb_init_cmd(ucr); | ||
349 | rtsx_usb_add_cmd(ucr, READ_REG_CMD, addr, 0, 0); | ||
350 | ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100); | ||
351 | if (ret) | ||
352 | return ret; | ||
353 | |||
354 | ret = rtsx_usb_get_rsp(ucr, 1, 100); | ||
355 | if (ret) | ||
356 | return ret; | ||
357 | |||
358 | if (data != NULL) | ||
359 | *data = ucr->rsp_buf[0]; | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | EXPORT_SYMBOL_GPL(rtsx_usb_read_register); | ||
364 | |||
365 | static inline u8 double_ssc_depth(u8 depth) | ||
366 | { | ||
367 | return (depth > 1) ? (depth - 1) : depth; | ||
368 | } | ||
369 | |||
370 | static u8 revise_ssc_depth(u8 ssc_depth, u8 div) | ||
371 | { | ||
372 | if (div > CLK_DIV_1) { | ||
373 | if (ssc_depth > div - 1) | ||
374 | ssc_depth -= (div - 1); | ||
375 | else | ||
376 | ssc_depth = SSC_DEPTH_2M; | ||
377 | } | ||
378 | |||
379 | return ssc_depth; | ||
380 | } | ||
381 | |||
382 | int rtsx_usb_switch_clock(struct rtsx_ucr *ucr, unsigned int card_clock, | ||
383 | u8 ssc_depth, bool initial_mode, bool double_clk, bool vpclk) | ||
384 | { | ||
385 | int ret; | ||
386 | u8 n, clk_divider, mcu_cnt, div; | ||
387 | |||
388 | if (!card_clock) { | ||
389 | ucr->cur_clk = 0; | ||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | if (initial_mode) { | ||
394 | /* We use 250k(around) here, in initial stage */ | ||
395 | clk_divider = SD_CLK_DIVIDE_128; | ||
396 | card_clock = 30000000; | ||
397 | } else { | ||
398 | clk_divider = SD_CLK_DIVIDE_0; | ||
399 | } | ||
400 | |||
401 | ret = rtsx_usb_write_register(ucr, SD_CFG1, | ||
402 | SD_CLK_DIVIDE_MASK, clk_divider); | ||
403 | if (ret < 0) | ||
404 | return ret; | ||
405 | |||
406 | card_clock /= 1000000; | ||
407 | dev_dbg(&ucr->pusb_intf->dev, | ||
408 | "Switch card clock to %dMHz\n", card_clock); | ||
409 | |||
410 | if (!initial_mode && double_clk) | ||
411 | card_clock *= 2; | ||
412 | dev_dbg(&ucr->pusb_intf->dev, | ||
413 | "Internal SSC clock: %dMHz (cur_clk = %d)\n", | ||
414 | card_clock, ucr->cur_clk); | ||
415 | |||
416 | if (card_clock == ucr->cur_clk) | ||
417 | return 0; | ||
418 | |||
419 | /* Converting clock value into internal settings: n and div */ | ||
420 | n = card_clock - 2; | ||
421 | if ((card_clock <= 2) || (n > MAX_DIV_N)) | ||
422 | return -EINVAL; | ||
423 | |||
424 | mcu_cnt = 60/card_clock + 3; | ||
425 | if (mcu_cnt > 15) | ||
426 | mcu_cnt = 15; | ||
427 | |||
428 | /* Make sure that the SSC clock div_n is not less than MIN_DIV_N */ | ||
429 | |||
430 | div = CLK_DIV_1; | ||
431 | while (n < MIN_DIV_N && div < CLK_DIV_4) { | ||
432 | n = (n + 2) * 2 - 2; | ||
433 | div++; | ||
434 | } | ||
435 | dev_dbg(&ucr->pusb_intf->dev, "n = %d, div = %d\n", n, div); | ||
436 | |||
437 | if (double_clk) | ||
438 | ssc_depth = double_ssc_depth(ssc_depth); | ||
439 | |||
440 | ssc_depth = revise_ssc_depth(ssc_depth, div); | ||
441 | dev_dbg(&ucr->pusb_intf->dev, "ssc_depth = %d\n", ssc_depth); | ||
442 | |||
443 | rtsx_usb_init_cmd(ucr); | ||
444 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE); | ||
445 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CLK_DIV, | ||
446 | 0x3F, (div << 4) | mcu_cnt); | ||
447 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); | ||
448 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL2, | ||
449 | SSC_DEPTH_MASK, ssc_depth); | ||
450 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, n); | ||
451 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, SSC_RSTB); | ||
452 | if (vpclk) { | ||
453 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL, | ||
454 | PHASE_NOT_RESET, 0); | ||
455 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_VPCLK0_CTL, | ||
456 | PHASE_NOT_RESET, PHASE_NOT_RESET); | ||
457 | } | ||
458 | |||
459 | ret = rtsx_usb_send_cmd(ucr, MODE_C, 2000); | ||
460 | if (ret < 0) | ||
461 | return ret; | ||
462 | |||
463 | ret = rtsx_usb_write_register(ucr, SSC_CTL1, 0xff, | ||
464 | SSC_RSTB | SSC_8X_EN | SSC_SEL_4M); | ||
465 | if (ret < 0) | ||
466 | return ret; | ||
467 | |||
468 | /* Wait SSC clock stable */ | ||
469 | usleep_range(100, 1000); | ||
470 | |||
471 | ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0); | ||
472 | if (ret < 0) | ||
473 | return ret; | ||
474 | |||
475 | ucr->cur_clk = card_clock; | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | EXPORT_SYMBOL_GPL(rtsx_usb_switch_clock); | ||
480 | |||
481 | int rtsx_usb_card_exclusive_check(struct rtsx_ucr *ucr, int card) | ||
482 | { | ||
483 | int ret; | ||
484 | u16 val; | ||
485 | u16 cd_mask[] = { | ||
486 | [RTSX_USB_SD_CARD] = (CD_MASK & ~SD_CD), | ||
487 | [RTSX_USB_MS_CARD] = (CD_MASK & ~MS_CD) | ||
488 | }; | ||
489 | |||
490 | ret = rtsx_usb_get_card_status(ucr, &val); | ||
491 | /* | ||
492 | * If get status fails, return 0 (ok) for the exclusive check | ||
493 | * and let the flow fail at somewhere else. | ||
494 | */ | ||
495 | if (ret) | ||
496 | return 0; | ||
497 | |||
498 | if (val & cd_mask[card]) | ||
499 | return -EIO; | ||
500 | |||
501 | return 0; | ||
502 | } | ||
503 | EXPORT_SYMBOL_GPL(rtsx_usb_card_exclusive_check); | ||
504 | |||
505 | static int rtsx_usb_reset_chip(struct rtsx_ucr *ucr) | ||
506 | { | ||
507 | int ret; | ||
508 | u8 val; | ||
509 | |||
510 | rtsx_usb_init_cmd(ucr); | ||
511 | |||
512 | if (CHECK_PKG(ucr, LQFP48)) { | ||
513 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL, | ||
514 | LDO3318_PWR_MASK, LDO_SUSPEND); | ||
515 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PWR_CTL, | ||
516 | FORCE_LDO_POWERB, FORCE_LDO_POWERB); | ||
517 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL1, | ||
518 | 0x30, 0x10); | ||
519 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL5, | ||
520 | 0x03, 0x01); | ||
521 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_PULL_CTL6, | ||
522 | 0x0C, 0x04); | ||
523 | } | ||
524 | |||
525 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SYS_DUMMY0, NYET_MSAK, NYET_EN); | ||
526 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CD_DEGLITCH_WIDTH, 0xFF, 0x08); | ||
527 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, | ||
528 | CD_DEGLITCH_EN, XD_CD_DEGLITCH_EN, 0x0); | ||
529 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD30_DRIVE_SEL, | ||
530 | SD30_DRIVE_MASK, DRIVER_TYPE_D); | ||
531 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, | ||
532 | CARD_DRIVE_SEL, SD20_DRIVE_MASK, 0x0); | ||
533 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG, 0xE0, 0x0); | ||
534 | |||
535 | if (ucr->is_rts5179) | ||
536 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, | ||
537 | CARD_PULL_CTL5, 0x03, 0x01); | ||
538 | |||
539 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_DMA1_CTL, | ||
540 | EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL); | ||
541 | rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_INT_PEND, | ||
542 | XD_INT | MS_INT | SD_INT, | ||
543 | XD_INT | MS_INT | SD_INT); | ||
544 | |||
545 | ret = rtsx_usb_send_cmd(ucr, MODE_C, 100); | ||
546 | if (ret) | ||
547 | return ret; | ||
548 | |||
549 | /* config non-crystal mode */ | ||
550 | rtsx_usb_read_register(ucr, CFG_MODE, &val); | ||
551 | if ((val & XTAL_FREE) || ((val & CLK_MODE_MASK) == CLK_MODE_NON_XTAL)) { | ||
552 | ret = rtsx_usb_write_phy_register(ucr, 0xC2, 0x7C); | ||
553 | if (ret) | ||
554 | return ret; | ||
555 | } | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static int rtsx_usb_init_chip(struct rtsx_ucr *ucr) | ||
561 | { | ||
562 | int ret; | ||
563 | u8 val; | ||
564 | |||
565 | rtsx_usb_clear_fsm_err(ucr); | ||
566 | |||
567 | /* power on SSC */ | ||
568 | ret = rtsx_usb_write_register(ucr, | ||
569 | FPDCTL, SSC_POWER_MASK, SSC_POWER_ON); | ||
570 | if (ret) | ||
571 | return ret; | ||
572 | |||
573 | usleep_range(100, 1000); | ||
574 | ret = rtsx_usb_write_register(ucr, CLK_DIV, CLK_CHANGE, 0x00); | ||
575 | if (ret) | ||
576 | return ret; | ||
577 | |||
578 | /* determine IC version */ | ||
579 | ret = rtsx_usb_read_register(ucr, HW_VERSION, &val); | ||
580 | if (ret) | ||
581 | return ret; | ||
582 | |||
583 | ucr->ic_version = val & HW_VER_MASK; | ||
584 | |||
585 | /* determine package */ | ||
586 | ret = rtsx_usb_read_register(ucr, CARD_SHARE_MODE, &val); | ||
587 | if (ret) | ||
588 | return ret; | ||
589 | |||
590 | if (val & CARD_SHARE_LQFP_SEL) { | ||
591 | ucr->package = LQFP48; | ||
592 | dev_dbg(&ucr->pusb_intf->dev, "Package: LQFP48\n"); | ||
593 | } else { | ||
594 | ucr->package = QFN24; | ||
595 | dev_dbg(&ucr->pusb_intf->dev, "Package: QFN24\n"); | ||
596 | } | ||
597 | |||
598 | /* determine IC variations */ | ||
599 | rtsx_usb_read_register(ucr, CFG_MODE_1, &val); | ||
600 | if (val & RTS5179) { | ||
601 | ucr->is_rts5179 = true; | ||
602 | dev_dbg(&ucr->pusb_intf->dev, "Device is rts5179\n"); | ||
603 | } else { | ||
604 | ucr->is_rts5179 = false; | ||
605 | } | ||
606 | |||
607 | return rtsx_usb_reset_chip(ucr); | ||
608 | } | ||
609 | |||
610 | static int rtsx_usb_probe(struct usb_interface *intf, | ||
611 | const struct usb_device_id *id) | ||
612 | { | ||
613 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
614 | struct rtsx_ucr *ucr; | ||
615 | int ret; | ||
616 | |||
617 | dev_dbg(&intf->dev, | ||
618 | ": Realtek USB Card Reader found at bus %03d address %03d\n", | ||
619 | usb_dev->bus->busnum, usb_dev->devnum); | ||
620 | |||
621 | ucr = devm_kzalloc(&intf->dev, sizeof(*ucr), GFP_KERNEL); | ||
622 | if (!ucr) | ||
623 | return -ENOMEM; | ||
624 | |||
625 | ucr->pusb_dev = usb_dev; | ||
626 | |||
627 | ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE, | ||
628 | GFP_KERNEL, &ucr->iobuf_dma); | ||
629 | if (!ucr->iobuf) | ||
630 | return -ENOMEM; | ||
631 | |||
632 | usb_set_intfdata(intf, ucr); | ||
633 | |||
634 | ucr->vendor_id = id->idVendor; | ||
635 | ucr->product_id = id->idProduct; | ||
636 | ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf; | ||
637 | |||
638 | mutex_init(&ucr->dev_mutex); | ||
639 | |||
640 | ucr->pusb_intf = intf; | ||
641 | |||
642 | /* initialize */ | ||
643 | ret = rtsx_usb_init_chip(ucr); | ||
644 | if (ret) | ||
645 | goto out_init_fail; | ||
646 | |||
647 | ret = mfd_add_devices(&intf->dev, usb_dev->devnum, rtsx_usb_cells, | ||
648 | ARRAY_SIZE(rtsx_usb_cells), NULL, 0, NULL); | ||
649 | if (ret) | ||
650 | goto out_init_fail; | ||
651 | |||
652 | /* initialize USB SG transfer timer */ | ||
653 | init_timer(&ucr->sg_timer); | ||
654 | setup_timer(&ucr->sg_timer, rtsx_usb_sg_timed_out, (unsigned long) ucr); | ||
655 | #ifdef CONFIG_PM | ||
656 | intf->needs_remote_wakeup = 1; | ||
657 | usb_enable_autosuspend(usb_dev); | ||
658 | #endif | ||
659 | |||
660 | return 0; | ||
661 | |||
662 | out_init_fail: | ||
663 | usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, | ||
664 | ucr->iobuf_dma); | ||
665 | return ret; | ||
666 | } | ||
667 | |||
668 | static void rtsx_usb_disconnect(struct usb_interface *intf) | ||
669 | { | ||
670 | struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf); | ||
671 | |||
672 | dev_dbg(&intf->dev, "%s called\n", __func__); | ||
673 | |||
674 | mfd_remove_devices(&intf->dev); | ||
675 | |||
676 | usb_set_intfdata(ucr->pusb_intf, NULL); | ||
677 | usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf, | ||
678 | ucr->iobuf_dma); | ||
679 | } | ||
680 | |||
681 | #ifdef CONFIG_PM | ||
682 | static int rtsx_usb_suspend(struct usb_interface *intf, pm_message_t message) | ||
683 | { | ||
684 | struct rtsx_ucr *ucr = | ||
685 | (struct rtsx_ucr *)usb_get_intfdata(intf); | ||
686 | |||
687 | dev_dbg(&intf->dev, "%s called with pm message 0x%04u\n", | ||
688 | __func__, message.event); | ||
689 | |||
690 | mutex_lock(&ucr->dev_mutex); | ||
691 | rtsx_usb_turn_off_led(ucr); | ||
692 | mutex_unlock(&ucr->dev_mutex); | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | static int rtsx_usb_resume(struct usb_interface *intf) | ||
697 | { | ||
698 | return 0; | ||
699 | } | ||
700 | |||
701 | static int rtsx_usb_reset_resume(struct usb_interface *intf) | ||
702 | { | ||
703 | struct rtsx_ucr *ucr = | ||
704 | (struct rtsx_ucr *)usb_get_intfdata(intf); | ||
705 | |||
706 | rtsx_usb_reset_chip(ucr); | ||
707 | return 0; | ||
708 | } | ||
709 | |||
710 | #else /* CONFIG_PM */ | ||
711 | |||
712 | #define rtsx_usb_suspend NULL | ||
713 | #define rtsx_usb_resume NULL | ||
714 | #define rtsx_usb_reset_resume NULL | ||
715 | |||
716 | #endif /* CONFIG_PM */ | ||
717 | |||
718 | |||
719 | static int rtsx_usb_pre_reset(struct usb_interface *intf) | ||
720 | { | ||
721 | struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf); | ||
722 | |||
723 | mutex_lock(&ucr->dev_mutex); | ||
724 | return 0; | ||
725 | } | ||
726 | |||
727 | static int rtsx_usb_post_reset(struct usb_interface *intf) | ||
728 | { | ||
729 | struct rtsx_ucr *ucr = (struct rtsx_ucr *)usb_get_intfdata(intf); | ||
730 | |||
731 | mutex_unlock(&ucr->dev_mutex); | ||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static struct usb_device_id rtsx_usb_usb_ids[] = { | ||
736 | { USB_DEVICE(0x0BDA, 0x0129) }, | ||
737 | { USB_DEVICE(0x0BDA, 0x0139) }, | ||
738 | { USB_DEVICE(0x0BDA, 0x0140) }, | ||
739 | { } | ||
740 | }; | ||
741 | |||
742 | static struct usb_driver rtsx_usb_driver = { | ||
743 | .name = "rtsx_usb", | ||
744 | .probe = rtsx_usb_probe, | ||
745 | .disconnect = rtsx_usb_disconnect, | ||
746 | .suspend = rtsx_usb_suspend, | ||
747 | .resume = rtsx_usb_resume, | ||
748 | .reset_resume = rtsx_usb_reset_resume, | ||
749 | .pre_reset = rtsx_usb_pre_reset, | ||
750 | .post_reset = rtsx_usb_post_reset, | ||
751 | .id_table = rtsx_usb_usb_ids, | ||
752 | .supports_autosuspend = 1, | ||
753 | .soft_unbind = 1, | ||
754 | }; | ||
755 | |||
756 | module_usb_driver(rtsx_usb_driver); | ||
757 | |||
758 | MODULE_LICENSE("GPL v2"); | ||
759 | MODULE_AUTHOR("Roger Tseng <rogerable@realtek.com>"); | ||
760 | MODULE_DESCRIPTION("Realtek USB Card Reader Driver"); | ||
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 281a82747275..1cf27521fff4 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -60,6 +60,7 @@ static const struct mfd_cell s5m8767_devs[] = { | |||
60 | .name = "s5m-rtc", | 60 | .name = "s5m-rtc", |
61 | }, { | 61 | }, { |
62 | .name = "s5m8767-clk", | 62 | .name = "s5m8767-clk", |
63 | .of_compatible = "samsung,s5m8767-clk", | ||
63 | } | 64 | } |
64 | }; | 65 | }; |
65 | 66 | ||
@@ -68,6 +69,7 @@ static const struct mfd_cell s2mps11_devs[] = { | |||
68 | .name = "s2mps11-pmic", | 69 | .name = "s2mps11-pmic", |
69 | }, { | 70 | }, { |
70 | .name = "s2mps11-clk", | 71 | .name = "s2mps11-clk", |
72 | .of_compatible = "samsung,s2mps11-clk", | ||
71 | } | 73 | } |
72 | }; | 74 | }; |
73 | 75 | ||
@@ -78,6 +80,7 @@ static const struct mfd_cell s2mps14_devs[] = { | |||
78 | .name = "s2mps14-rtc", | 80 | .name = "s2mps14-rtc", |
79 | }, { | 81 | }, { |
80 | .name = "s2mps14-clk", | 82 | .name = "s2mps14-clk", |
83 | .of_compatible = "samsung,s2mps14-clk", | ||
81 | } | 84 | } |
82 | }; | 85 | }; |
83 | 86 | ||
@@ -295,6 +298,13 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
295 | switch (sec_pmic->device_type) { | 298 | switch (sec_pmic->device_type) { |
296 | case S2MPA01: | 299 | case S2MPA01: |
297 | regmap = &s2mpa01_regmap_config; | 300 | regmap = &s2mpa01_regmap_config; |
301 | /* | ||
302 | * The rtc-s5m driver does not support S2MPA01 and there | ||
303 | * is no mfd_cell for S2MPA01 RTC device. | ||
304 | * However we must pass something to devm_regmap_init_i2c() | ||
305 | * so use S5M-like regmap config even though it wouldn't work. | ||
306 | */ | ||
307 | regmap_rtc = &s5m_rtc_regmap_config; | ||
298 | break; | 308 | break; |
299 | case S2MPS11X: | 309 | case S2MPS11X: |
300 | regmap = &s2mps11_regmap_config; | 310 | regmap = &s2mps11_regmap_config; |
@@ -344,7 +354,7 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
344 | ret = PTR_ERR(sec_pmic->regmap_rtc); | 354 | ret = PTR_ERR(sec_pmic->regmap_rtc); |
345 | dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n", | 355 | dev_err(&i2c->dev, "Failed to allocate RTC register map: %d\n", |
346 | ret); | 356 | ret); |
347 | return ret; | 357 | goto err_regmap_rtc; |
348 | } | 358 | } |
349 | 359 | ||
350 | if (pdata && pdata->cfg_pmic_irq) | 360 | if (pdata && pdata->cfg_pmic_irq) |
@@ -385,14 +395,15 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
385 | } | 395 | } |
386 | 396 | ||
387 | if (ret) | 397 | if (ret) |
388 | goto err; | 398 | goto err_mfd; |
389 | 399 | ||
390 | device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup); | 400 | device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup); |
391 | 401 | ||
392 | return ret; | 402 | return ret; |
393 | 403 | ||
394 | err: | 404 | err_mfd: |
395 | sec_irq_exit(sec_pmic); | 405 | sec_irq_exit(sec_pmic); |
406 | err_regmap_rtc: | ||
396 | i2c_unregister_device(sec_pmic->rtc); | 407 | i2c_unregister_device(sec_pmic->rtc); |
397 | return ret; | 408 | return ret; |
398 | } | 409 | } |
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c index 24ae3d8421c5..90112d4cc905 100644 --- a/drivers/mfd/smsc-ece1099.c +++ b/drivers/mfd/smsc-ece1099.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> | 15 | #include <linux/moduleparam.h> |
16 | #include <linux/init.h> | ||
17 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
18 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
19 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 42ccd0544513..4a91f6771fb8 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -706,7 +706,7 @@ static int stmpe1801_reset(struct stmpe *stmpe) | |||
706 | if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET)) | 706 | if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET)) |
707 | return 0; | 707 | return 0; |
708 | usleep_range(100, 200); | 708 | usleep_range(100, 200); |
709 | }; | 709 | } |
710 | return -EIO; | 710 | return -EIO; |
711 | } | 711 | } |
712 | 712 | ||
diff --git a/drivers/mfd/stw481x.c b/drivers/mfd/stw481x.c index 1243d5c6a448..7ceb3df09e25 100644 --- a/drivers/mfd/stw481x.c +++ b/drivers/mfd/stw481x.c | |||
@@ -167,7 +167,7 @@ static struct mfd_cell stw481x_cells[] = { | |||
167 | }, | 167 | }, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | const struct regmap_config stw481x_regmap_config = { | 170 | static const struct regmap_config stw481x_regmap_config = { |
171 | .reg_bits = 8, | 171 | .reg_bits = 8, |
172 | .val_bits = 8, | 172 | .val_bits = 8, |
173 | }; | 173 | }; |
@@ -186,6 +186,12 @@ static int stw481x_probe(struct i2c_client *client, | |||
186 | i2c_set_clientdata(client, stw481x); | 186 | i2c_set_clientdata(client, stw481x); |
187 | stw481x->client = client; | 187 | stw481x->client = client; |
188 | stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config); | 188 | stw481x->map = devm_regmap_init_i2c(client, &stw481x_regmap_config); |
189 | if (IS_ERR(stw481x->map)) { | ||
190 | ret = PTR_ERR(stw481x->map); | ||
191 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | ||
192 | ret); | ||
193 | return ret; | ||
194 | } | ||
189 | 195 | ||
190 | ret = stw481x_startup(stw481x); | 196 | ret = stw481x_startup(stw481x); |
191 | if (ret) { | 197 | if (ret) { |
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 71841f9181bd..dbea55de4397 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c | |||
@@ -69,13 +69,6 @@ EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible); | |||
69 | 69 | ||
70 | static int syscon_match_pdevname(struct device *dev, void *data) | 70 | static int syscon_match_pdevname(struct device *dev, void *data) |
71 | { | 71 | { |
72 | struct platform_device *pdev = to_platform_device(dev); | ||
73 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
74 | |||
75 | if (id) | ||
76 | if (!strcmp(id->name, (const char *)data)) | ||
77 | return 1; | ||
78 | |||
79 | return !strcmp(dev_name(dev), (const char *)data); | 72 | return !strcmp(dev_name(dev), (const char *)data); |
80 | } | 73 | } |
81 | 74 | ||
@@ -152,7 +145,7 @@ static int syscon_probe(struct platform_device *pdev) | |||
152 | 145 | ||
153 | platform_set_drvdata(pdev, syscon); | 146 | platform_set_drvdata(pdev, syscon); |
154 | 147 | ||
155 | dev_info(dev, "regmap %pR registered\n", res); | 148 | dev_dbg(dev, "regmap %pR registered\n", res); |
156 | 149 | ||
157 | return 0; | 150 | return 0; |
158 | } | 151 | } |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 2cf636c267d9..bd83accc0f6d 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -13,8 +13,10 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/of_device.h> | ||
16 | #include <linux/mfd/core.h> | 17 | #include <linux/mfd/core.h> |
17 | #include <linux/mfd/tc3589x.h> | 18 | #include <linux/mfd/tc3589x.h> |
19 | #include <linux/err.h> | ||
18 | 20 | ||
19 | /** | 21 | /** |
20 | * enum tc3589x_version - indicates the TC3589x version | 22 | * enum tc3589x_version - indicates the TC3589x version |
@@ -160,7 +162,7 @@ static const struct mfd_cell tc3589x_dev_gpio[] = { | |||
160 | .name = "tc3589x-gpio", | 162 | .name = "tc3589x-gpio", |
161 | .num_resources = ARRAY_SIZE(gpio_resources), | 163 | .num_resources = ARRAY_SIZE(gpio_resources), |
162 | .resources = &gpio_resources[0], | 164 | .resources = &gpio_resources[0], |
163 | .of_compatible = "tc3589x-gpio", | 165 | .of_compatible = "toshiba,tc3589x-gpio", |
164 | }, | 166 | }, |
165 | }; | 167 | }; |
166 | 168 | ||
@@ -169,7 +171,7 @@ static const struct mfd_cell tc3589x_dev_keypad[] = { | |||
169 | .name = "tc3589x-keypad", | 171 | .name = "tc3589x-keypad", |
170 | .num_resources = ARRAY_SIZE(keypad_resources), | 172 | .num_resources = ARRAY_SIZE(keypad_resources), |
171 | .resources = &keypad_resources[0], | 173 | .resources = &keypad_resources[0], |
172 | .of_compatible = "tc3589x-keypad", | 174 | .of_compatible = "toshiba,tc3589x-keypad", |
173 | }, | 175 | }, |
174 | }; | 176 | }; |
175 | 177 | ||
@@ -318,45 +320,74 @@ static int tc3589x_device_init(struct tc3589x *tc3589x) | |||
318 | return ret; | 320 | return ret; |
319 | } | 321 | } |
320 | 322 | ||
321 | static int tc3589x_of_probe(struct device_node *np, | 323 | #ifdef CONFIG_OF |
322 | struct tc3589x_platform_data *pdata) | 324 | static const struct of_device_id tc3589x_match[] = { |
325 | /* Legacy compatible string */ | ||
326 | { .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN }, | ||
327 | { .compatible = "toshiba,tc35890", .data = (void *) TC3589X_TC35890 }, | ||
328 | { .compatible = "toshiba,tc35892", .data = (void *) TC3589X_TC35892 }, | ||
329 | { .compatible = "toshiba,tc35893", .data = (void *) TC3589X_TC35893 }, | ||
330 | { .compatible = "toshiba,tc35894", .data = (void *) TC3589X_TC35894 }, | ||
331 | { .compatible = "toshiba,tc35895", .data = (void *) TC3589X_TC35895 }, | ||
332 | { .compatible = "toshiba,tc35896", .data = (void *) TC3589X_TC35896 }, | ||
333 | { } | ||
334 | }; | ||
335 | |||
336 | MODULE_DEVICE_TABLE(of, tc3589x_match); | ||
337 | |||
338 | static struct tc3589x_platform_data * | ||
339 | tc3589x_of_probe(struct device *dev, enum tc3589x_version *version) | ||
323 | { | 340 | { |
341 | struct device_node *np = dev->of_node; | ||
342 | struct tc3589x_platform_data *pdata; | ||
324 | struct device_node *child; | 343 | struct device_node *child; |
344 | const struct of_device_id *of_id; | ||
345 | |||
346 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
347 | if (!pdata) | ||
348 | return ERR_PTR(-ENOMEM); | ||
349 | |||
350 | of_id = of_match_device(tc3589x_match, dev); | ||
351 | if (!of_id) | ||
352 | return ERR_PTR(-ENODEV); | ||
353 | *version = (enum tc3589x_version) of_id->data; | ||
325 | 354 | ||
326 | for_each_child_of_node(np, child) { | 355 | for_each_child_of_node(np, child) { |
327 | if (!strcmp(child->name, "tc3589x_gpio")) { | 356 | if (of_device_is_compatible(child, "toshiba,tc3589x-gpio")) |
328 | pdata->block |= TC3589x_BLOCK_GPIO; | 357 | pdata->block |= TC3589x_BLOCK_GPIO; |
329 | } | 358 | if (of_device_is_compatible(child, "toshiba,tc3589x-keypad")) |
330 | if (!strcmp(child->name, "tc3589x_keypad")) { | ||
331 | pdata->block |= TC3589x_BLOCK_KEYPAD; | 359 | pdata->block |= TC3589x_BLOCK_KEYPAD; |
332 | } | ||
333 | } | 360 | } |
334 | 361 | ||
335 | return 0; | 362 | return pdata; |
336 | } | 363 | } |
364 | #else | ||
365 | static inline struct tc3589x_platform_data * | ||
366 | tc3589x_of_probe(struct device *dev, enum tc3589x_version *version) | ||
367 | { | ||
368 | dev_err(dev, "no device tree support\n"); | ||
369 | return ERR_PTR(-ENODEV); | ||
370 | } | ||
371 | #endif | ||
337 | 372 | ||
338 | static int tc3589x_probe(struct i2c_client *i2c, | 373 | static int tc3589x_probe(struct i2c_client *i2c, |
339 | const struct i2c_device_id *id) | 374 | const struct i2c_device_id *id) |
340 | { | 375 | { |
341 | struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
342 | struct device_node *np = i2c->dev.of_node; | 376 | struct device_node *np = i2c->dev.of_node; |
377 | struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
343 | struct tc3589x *tc3589x; | 378 | struct tc3589x *tc3589x; |
379 | enum tc3589x_version version; | ||
344 | int ret; | 380 | int ret; |
345 | 381 | ||
346 | if (!pdata) { | 382 | if (!pdata) { |
347 | if (np) { | 383 | pdata = tc3589x_of_probe(&i2c->dev, &version); |
348 | pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); | 384 | if (IS_ERR(pdata)) { |
349 | if (!pdata) | ||
350 | return -ENOMEM; | ||
351 | |||
352 | ret = tc3589x_of_probe(np, pdata); | ||
353 | if (ret) | ||
354 | return ret; | ||
355 | } | ||
356 | else { | ||
357 | dev_err(&i2c->dev, "No platform data or DT found\n"); | 385 | dev_err(&i2c->dev, "No platform data or DT found\n"); |
358 | return -EINVAL; | 386 | return PTR_ERR(pdata); |
359 | } | 387 | } |
388 | } else { | ||
389 | /* When not probing from device tree we have this ID */ | ||
390 | version = id->driver_data; | ||
360 | } | 391 | } |
361 | 392 | ||
362 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA | 393 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
@@ -375,7 +406,7 @@ static int tc3589x_probe(struct i2c_client *i2c, | |||
375 | tc3589x->pdata = pdata; | 406 | tc3589x->pdata = pdata; |
376 | tc3589x->irq_base = pdata->irq_base; | 407 | tc3589x->irq_base = pdata->irq_base; |
377 | 408 | ||
378 | switch (id->driver_data) { | 409 | switch (version) { |
379 | case TC3589X_TC35893: | 410 | case TC3589X_TC35893: |
380 | case TC3589X_TC35895: | 411 | case TC3589X_TC35895: |
381 | case TC3589X_TC35896: | 412 | case TC3589X_TC35896: |
@@ -471,9 +502,12 @@ static const struct i2c_device_id tc3589x_id[] = { | |||
471 | MODULE_DEVICE_TABLE(i2c, tc3589x_id); | 502 | MODULE_DEVICE_TABLE(i2c, tc3589x_id); |
472 | 503 | ||
473 | static struct i2c_driver tc3589x_driver = { | 504 | static struct i2c_driver tc3589x_driver = { |
474 | .driver.name = "tc3589x", | 505 | .driver = { |
475 | .driver.owner = THIS_MODULE, | 506 | .name = "tc3589x", |
476 | .driver.pm = &tc3589x_dev_pm_ops, | 507 | .owner = THIS_MODULE, |
508 | .pm = &tc3589x_dev_pm_ops, | ||
509 | .of_match_table = of_match_ptr(tc3589x_match), | ||
510 | }, | ||
477 | .probe = tc3589x_probe, | 511 | .probe = tc3589x_probe, |
478 | .remove = tc3589x_remove, | 512 | .remove = tc3589x_remove, |
479 | .id_table = tc3589x_id, | 513 | .id_table = tc3589x_id, |
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c deleted file mode 100644 index a5424579679c..000000000000 --- a/drivers/mfd/ti-ssp.c +++ /dev/null | |||
@@ -1,465 +0,0 @@ | |||
1 | /* | ||
2 | * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs | ||
3 | * | ||
4 | * Copyright (C) 2010 Texas Instruments Inc | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/errno.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/wait.h> | ||
28 | #include <linux/clk.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/device.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/io.h> | ||
35 | #include <linux/sched.h> | ||
36 | #include <linux/mfd/core.h> | ||
37 | #include <linux/mfd/ti_ssp.h> | ||
38 | |||
39 | /* Register Offsets */ | ||
40 | #define REG_REV 0x00 | ||
41 | #define REG_IOSEL_1 0x04 | ||
42 | #define REG_IOSEL_2 0x08 | ||
43 | #define REG_PREDIV 0x0c | ||
44 | #define REG_INTR_ST 0x10 | ||
45 | #define REG_INTR_EN 0x14 | ||
46 | #define REG_TEST_CTRL 0x18 | ||
47 | |||
48 | /* Per port registers */ | ||
49 | #define PORT_CFG_2 0x00 | ||
50 | #define PORT_ADDR 0x04 | ||
51 | #define PORT_DATA 0x08 | ||
52 | #define PORT_CFG_1 0x0c | ||
53 | #define PORT_STATE 0x10 | ||
54 | |||
55 | #define SSP_PORT_CONFIG_MASK (SSP_EARLY_DIN | SSP_DELAY_DOUT) | ||
56 | #define SSP_PORT_CLKRATE_MASK 0x0f | ||
57 | |||
58 | #define SSP_SEQRAM_WR_EN BIT(4) | ||
59 | #define SSP_SEQRAM_RD_EN BIT(5) | ||
60 | #define SSP_START BIT(15) | ||
61 | #define SSP_BUSY BIT(10) | ||
62 | #define SSP_PORT_ASL BIT(7) | ||
63 | #define SSP_PORT_CFO1 BIT(6) | ||
64 | |||
65 | #define SSP_PORT_SEQRAM_SIZE 32 | ||
66 | |||
67 | static const int ssp_port_base[] = {0x040, 0x080}; | ||
68 | static const int ssp_port_seqram[] = {0x100, 0x180}; | ||
69 | |||
70 | struct ti_ssp { | ||
71 | struct resource *res; | ||
72 | struct device *dev; | ||
73 | void __iomem *regs; | ||
74 | spinlock_t lock; | ||
75 | struct clk *clk; | ||
76 | int irq; | ||
77 | wait_queue_head_t wqh; | ||
78 | |||
79 | /* | ||
80 | * Some of the iosel2 register bits always read-back as 0, we need to | ||
81 | * remember these values so that we don't clobber previously set | ||
82 | * values. | ||
83 | */ | ||
84 | u32 iosel2; | ||
85 | }; | ||
86 | |||
87 | static inline struct ti_ssp *dev_to_ssp(struct device *dev) | ||
88 | { | ||
89 | return dev_get_drvdata(dev->parent); | ||
90 | } | ||
91 | |||
92 | static inline int dev_to_port(struct device *dev) | ||
93 | { | ||
94 | return to_platform_device(dev)->id; | ||
95 | } | ||
96 | |||
97 | /* Register Access Helpers, rmw() functions need to run locked */ | ||
98 | static inline u32 ssp_read(struct ti_ssp *ssp, int reg) | ||
99 | { | ||
100 | return __raw_readl(ssp->regs + reg); | ||
101 | } | ||
102 | |||
103 | static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val) | ||
104 | { | ||
105 | __raw_writel(val, ssp->regs + reg); | ||
106 | } | ||
107 | |||
108 | static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits) | ||
109 | { | ||
110 | ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~mask) | bits); | ||
111 | } | ||
112 | |||
113 | static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg) | ||
114 | { | ||
115 | return ssp_read(ssp, ssp_port_base[port] + reg); | ||
116 | } | ||
117 | |||
118 | static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg, | ||
119 | u32 val) | ||
120 | { | ||
121 | ssp_write(ssp, ssp_port_base[port] + reg, val); | ||
122 | } | ||
123 | |||
124 | static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg, | ||
125 | u32 mask, u32 bits) | ||
126 | { | ||
127 | ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits); | ||
128 | } | ||
129 | |||
130 | static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg, | ||
131 | u32 bits) | ||
132 | { | ||
133 | ssp_port_rmw(ssp, port, reg, bits, 0); | ||
134 | } | ||
135 | |||
136 | static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg, | ||
137 | u32 bits) | ||
138 | { | ||
139 | ssp_port_rmw(ssp, port, reg, 0, bits); | ||
140 | } | ||
141 | |||
142 | /* Called to setup port clock mode, caller must hold ssp->lock */ | ||
143 | static int __set_mode(struct ti_ssp *ssp, int port, int mode) | ||
144 | { | ||
145 | mode &= SSP_PORT_CONFIG_MASK; | ||
146 | ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | int ti_ssp_set_mode(struct device *dev, int mode) | ||
152 | { | ||
153 | struct ti_ssp *ssp = dev_to_ssp(dev); | ||
154 | int port = dev_to_port(dev); | ||
155 | int ret; | ||
156 | |||
157 | spin_lock(&ssp->lock); | ||
158 | ret = __set_mode(ssp, port, mode); | ||
159 | spin_unlock(&ssp->lock); | ||
160 | |||
161 | return ret; | ||
162 | } | ||
163 | EXPORT_SYMBOL(ti_ssp_set_mode); | ||
164 | |||
165 | /* Called to setup iosel2, caller must hold ssp->lock */ | ||
166 | static void __set_iosel2(struct ti_ssp *ssp, u32 mask, u32 val) | ||
167 | { | ||
168 | ssp->iosel2 = (ssp->iosel2 & ~mask) | val; | ||
169 | ssp_write(ssp, REG_IOSEL_2, ssp->iosel2); | ||
170 | } | ||
171 | |||
172 | /* Called to setup port iosel, caller must hold ssp->lock */ | ||
173 | static void __set_iosel(struct ti_ssp *ssp, int port, u32 iosel) | ||
174 | { | ||
175 | unsigned val, shift = port ? 16 : 0; | ||
176 | |||
177 | /* IOSEL1 gets the least significant 16 bits */ | ||
178 | val = ssp_read(ssp, REG_IOSEL_1); | ||
179 | val &= 0xffff << (port ? 0 : 16); | ||
180 | val |= (iosel & 0xffff) << (port ? 16 : 0); | ||
181 | ssp_write(ssp, REG_IOSEL_1, val); | ||
182 | |||
183 | /* IOSEL2 gets the most significant 16 bits */ | ||
184 | val = (iosel >> 16) & 0x7; | ||
185 | __set_iosel2(ssp, 0x7 << shift, val << shift); | ||
186 | } | ||
187 | |||
188 | int ti_ssp_set_iosel(struct device *dev, u32 iosel) | ||
189 | { | ||
190 | struct ti_ssp *ssp = dev_to_ssp(dev); | ||
191 | int port = dev_to_port(dev); | ||
192 | |||
193 | spin_lock(&ssp->lock); | ||
194 | __set_iosel(ssp, port, iosel); | ||
195 | spin_unlock(&ssp->lock); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | EXPORT_SYMBOL(ti_ssp_set_iosel); | ||
200 | |||
201 | int ti_ssp_load(struct device *dev, int offs, u32* prog, int len) | ||
202 | { | ||
203 | struct ti_ssp *ssp = dev_to_ssp(dev); | ||
204 | int port = dev_to_port(dev); | ||
205 | int i; | ||
206 | |||
207 | if (len > SSP_PORT_SEQRAM_SIZE) | ||
208 | return -ENOSPC; | ||
209 | |||
210 | spin_lock(&ssp->lock); | ||
211 | |||
212 | /* Enable SeqRAM access */ | ||
213 | ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); | ||
214 | |||
215 | /* Copy code */ | ||
216 | for (i = 0; i < len; i++) { | ||
217 | __raw_writel(prog[i], ssp->regs + offs + 4*i + | ||
218 | ssp_port_seqram[port]); | ||
219 | } | ||
220 | |||
221 | /* Disable SeqRAM access */ | ||
222 | ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN); | ||
223 | |||
224 | spin_unlock(&ssp->lock); | ||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | EXPORT_SYMBOL(ti_ssp_load); | ||
229 | |||
230 | int ti_ssp_raw_read(struct device *dev) | ||
231 | { | ||
232 | struct ti_ssp *ssp = dev_to_ssp(dev); | ||
233 | int port = dev_to_port(dev); | ||
234 | int shift = port ? 27 : 11; | ||
235 | |||
236 | return (ssp_read(ssp, REG_IOSEL_2) >> shift) & 0xf; | ||
237 | } | ||
238 | EXPORT_SYMBOL(ti_ssp_raw_read); | ||
239 | |||
240 | int ti_ssp_raw_write(struct device *dev, u32 val) | ||
241 | { | ||
242 | struct ti_ssp *ssp = dev_to_ssp(dev); | ||
243 | int port = dev_to_port(dev), shift; | ||
244 | |||
245 | spin_lock(&ssp->lock); | ||
246 | |||
247 | shift = port ? 22 : 6; | ||
248 | val &= 0xf; | ||
249 | __set_iosel2(ssp, 0xf << shift, val << shift); | ||
250 | |||
251 | spin_unlock(&ssp->lock); | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | EXPORT_SYMBOL(ti_ssp_raw_write); | ||
256 | |||
257 | static inline int __xfer_done(struct ti_ssp *ssp, int port) | ||
258 | { | ||
259 | return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY); | ||
260 | } | ||
261 | |||
262 | int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output) | ||
263 | { | ||
264 | struct ti_ssp *ssp = dev_to_ssp(dev); | ||
265 | int port = dev_to_port(dev); | ||
266 | int ret; | ||
267 | |||
268 | if (pc & ~(0x3f)) | ||
269 | return -EINVAL; | ||
270 | |||
271 | /* Grab ssp->lock to serialize rmw on ssp registers */ | ||
272 | spin_lock(&ssp->lock); | ||
273 | |||
274 | ssp_port_write(ssp, port, PORT_ADDR, input >> 16); | ||
275 | ssp_port_write(ssp, port, PORT_DATA, input & 0xffff); | ||
276 | ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc); | ||
277 | |||
278 | /* grab wait queue head lock to avoid race with the isr */ | ||
279 | spin_lock_irq(&ssp->wqh.lock); | ||
280 | |||
281 | /* kick off sequence execution in hardware */ | ||
282 | ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START); | ||
283 | |||
284 | /* drop ssp lock; no register writes beyond this */ | ||
285 | spin_unlock(&ssp->lock); | ||
286 | |||
287 | ret = wait_event_interruptible_locked_irq(ssp->wqh, | ||
288 | __xfer_done(ssp, port)); | ||
289 | spin_unlock_irq(&ssp->wqh.lock); | ||
290 | |||
291 | if (ret < 0) | ||
292 | return ret; | ||
293 | |||
294 | if (output) { | ||
295 | *output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) | | ||
296 | (ssp_port_read(ssp, port, PORT_DATA) & 0xffff); | ||
297 | } | ||
298 | |||
299 | ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */ | ||
300 | |||
301 | return ret; | ||
302 | } | ||
303 | EXPORT_SYMBOL(ti_ssp_run); | ||
304 | |||
305 | static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data) | ||
306 | { | ||
307 | struct ti_ssp *ssp = dev_data; | ||
308 | |||
309 | spin_lock(&ssp->wqh.lock); | ||
310 | |||
311 | ssp_write(ssp, REG_INTR_ST, 0x3); | ||
312 | wake_up_locked(&ssp->wqh); | ||
313 | |||
314 | spin_unlock(&ssp->wqh.lock); | ||
315 | |||
316 | return IRQ_HANDLED; | ||
317 | } | ||
318 | |||
319 | static int ti_ssp_probe(struct platform_device *pdev) | ||
320 | { | ||
321 | static struct ti_ssp *ssp; | ||
322 | const struct ti_ssp_data *pdata = dev_get_platdata(&pdev->dev); | ||
323 | int error = 0, prediv = 0xff, id; | ||
324 | unsigned long sysclk; | ||
325 | struct device *dev = &pdev->dev; | ||
326 | struct mfd_cell cells[2]; | ||
327 | |||
328 | ssp = kzalloc(sizeof(*ssp), GFP_KERNEL); | ||
329 | if (!ssp) { | ||
330 | dev_err(dev, "cannot allocate device info\n"); | ||
331 | return -ENOMEM; | ||
332 | } | ||
333 | |||
334 | ssp->dev = dev; | ||
335 | dev_set_drvdata(dev, ssp); | ||
336 | |||
337 | ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
338 | if (!ssp->res) { | ||
339 | error = -ENODEV; | ||
340 | dev_err(dev, "cannot determine register area\n"); | ||
341 | goto error_res; | ||
342 | } | ||
343 | |||
344 | if (!request_mem_region(ssp->res->start, resource_size(ssp->res), | ||
345 | pdev->name)) { | ||
346 | error = -ENOMEM; | ||
347 | dev_err(dev, "cannot claim register memory\n"); | ||
348 | goto error_res; | ||
349 | } | ||
350 | |||
351 | ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res)); | ||
352 | if (!ssp->regs) { | ||
353 | error = -ENOMEM; | ||
354 | dev_err(dev, "cannot map register memory\n"); | ||
355 | goto error_map; | ||
356 | } | ||
357 | |||
358 | ssp->clk = clk_get(dev, NULL); | ||
359 | if (IS_ERR(ssp->clk)) { | ||
360 | error = PTR_ERR(ssp->clk); | ||
361 | dev_err(dev, "cannot claim device clock\n"); | ||
362 | goto error_clk; | ||
363 | } | ||
364 | |||
365 | ssp->irq = platform_get_irq(pdev, 0); | ||
366 | if (ssp->irq < 0) { | ||
367 | error = -ENODEV; | ||
368 | dev_err(dev, "unknown irq\n"); | ||
369 | goto error_irq; | ||
370 | } | ||
371 | |||
372 | error = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0, | ||
373 | dev_name(dev), ssp); | ||
374 | if (error < 0) { | ||
375 | dev_err(dev, "cannot acquire irq\n"); | ||
376 | goto error_irq; | ||
377 | } | ||
378 | |||
379 | spin_lock_init(&ssp->lock); | ||
380 | init_waitqueue_head(&ssp->wqh); | ||
381 | |||
382 | /* Power on and initialize SSP */ | ||
383 | error = clk_enable(ssp->clk); | ||
384 | if (error) { | ||
385 | dev_err(dev, "cannot enable device clock\n"); | ||
386 | goto error_enable; | ||
387 | } | ||
388 | |||
389 | /* Reset registers to a sensible known state */ | ||
390 | ssp_write(ssp, REG_IOSEL_1, 0); | ||
391 | ssp_write(ssp, REG_IOSEL_2, 0); | ||
392 | ssp_write(ssp, REG_INTR_EN, 0x3); | ||
393 | ssp_write(ssp, REG_INTR_ST, 0x3); | ||
394 | ssp_write(ssp, REG_TEST_CTRL, 0); | ||
395 | ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL); | ||
396 | ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL); | ||
397 | ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1); | ||
398 | ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1); | ||
399 | |||
400 | sysclk = clk_get_rate(ssp->clk); | ||
401 | if (pdata && pdata->out_clock) | ||
402 | prediv = (sysclk / pdata->out_clock) - 1; | ||
403 | prediv = clamp(prediv, 0, 0xff); | ||
404 | ssp_rmw(ssp, REG_PREDIV, 0xff, prediv); | ||
405 | |||
406 | memset(cells, 0, sizeof(cells)); | ||
407 | for (id = 0; id < 2; id++) { | ||
408 | const struct ti_ssp_dev_data *data = &pdata->dev_data[id]; | ||
409 | |||
410 | cells[id].id = id; | ||
411 | cells[id].name = data->dev_name; | ||
412 | cells[id].platform_data = data->pdata; | ||
413 | } | ||
414 | |||
415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL); | ||
416 | if (error < 0) { | ||
417 | dev_err(dev, "cannot add mfd cells\n"); | ||
418 | goto error_enable; | ||
419 | } | ||
420 | |||
421 | return 0; | ||
422 | |||
423 | error_enable: | ||
424 | free_irq(ssp->irq, ssp); | ||
425 | error_irq: | ||
426 | clk_put(ssp->clk); | ||
427 | error_clk: | ||
428 | iounmap(ssp->regs); | ||
429 | error_map: | ||
430 | release_mem_region(ssp->res->start, resource_size(ssp->res)); | ||
431 | error_res: | ||
432 | kfree(ssp); | ||
433 | return error; | ||
434 | } | ||
435 | |||
436 | static int ti_ssp_remove(struct platform_device *pdev) | ||
437 | { | ||
438 | struct device *dev = &pdev->dev; | ||
439 | struct ti_ssp *ssp = dev_get_drvdata(dev); | ||
440 | |||
441 | mfd_remove_devices(dev); | ||
442 | clk_disable(ssp->clk); | ||
443 | free_irq(ssp->irq, ssp); | ||
444 | clk_put(ssp->clk); | ||
445 | iounmap(ssp->regs); | ||
446 | release_mem_region(ssp->res->start, resource_size(ssp->res)); | ||
447 | kfree(ssp); | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static struct platform_driver ti_ssp_driver = { | ||
452 | .probe = ti_ssp_probe, | ||
453 | .remove = ti_ssp_remove, | ||
454 | .driver = { | ||
455 | .name = "ti-ssp", | ||
456 | .owner = THIS_MODULE, | ||
457 | } | ||
458 | }; | ||
459 | |||
460 | module_platform_driver(ti_ssp_driver); | ||
461 | |||
462 | MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); | ||
463 | MODULE_AUTHOR("Cyril Chemparathy"); | ||
464 | MODULE_LICENSE("GPL"); | ||
465 | MODULE_ALIAS("platform:ti-ssp"); | ||
diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c index d4e860413bb5..dd4bf5816221 100644 --- a/drivers/mfd/ti_am335x_tscadc.c +++ b/drivers/mfd/ti_am335x_tscadc.c | |||
@@ -14,7 +14,6 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
19 | #include <linux/err.h> | 18 | #include <linux/err.h> |
20 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -184,12 +183,6 @@ static int ti_tscadc_probe(struct platform_device *pdev) | |||
184 | return -EINVAL; | 183 | return -EINVAL; |
185 | } | 184 | } |
186 | 185 | ||
187 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
188 | if (!res) { | ||
189 | dev_err(&pdev->dev, "no memory resource defined.\n"); | ||
190 | return -EINVAL; | ||
191 | } | ||
192 | |||
193 | /* Allocate memory for device */ | 186 | /* Allocate memory for device */ |
194 | tscadc = devm_kzalloc(&pdev->dev, | 187 | tscadc = devm_kzalloc(&pdev->dev, |
195 | sizeof(struct ti_tscadc_dev), GFP_KERNEL); | 188 | sizeof(struct ti_tscadc_dev), GFP_KERNEL); |
@@ -206,19 +199,10 @@ static int ti_tscadc_probe(struct platform_device *pdev) | |||
206 | } else | 199 | } else |
207 | tscadc->irq = err; | 200 | tscadc->irq = err; |
208 | 201 | ||
209 | res = devm_request_mem_region(&pdev->dev, | 202 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
210 | res->start, resource_size(res), pdev->name); | 203 | tscadc->tscadc_base = devm_ioremap_resource(&pdev->dev, res); |
211 | if (!res) { | 204 | if (IS_ERR(tscadc->tscadc_base)) |
212 | dev_err(&pdev->dev, "failed to reserve registers.\n"); | 205 | return PTR_ERR(tscadc->tscadc_base); |
213 | return -EBUSY; | ||
214 | } | ||
215 | |||
216 | tscadc->tscadc_base = devm_ioremap(&pdev->dev, | ||
217 | res->start, resource_size(res)); | ||
218 | if (!tscadc->tscadc_base) { | ||
219 | dev_err(&pdev->dev, "failed to map registers.\n"); | ||
220 | return -ENOMEM; | ||
221 | } | ||
222 | 206 | ||
223 | tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev, | 207 | tscadc->regmap_tscadc = devm_regmap_init_mmio(&pdev->dev, |
224 | tscadc->tscadc_base, &tscadc_regmap_config); | 208 | tscadc->tscadc_base, &tscadc_regmap_config); |
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 2bc5cfb85204..6ce36d6970a4 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c | |||
@@ -715,7 +715,7 @@ static int timb_probe(struct pci_dev *dev, | |||
715 | for (i = 0; i < TIMBERDALE_NR_IRQS; i++) | 715 | for (i = 0; i < TIMBERDALE_NR_IRQS; i++) |
716 | msix_entries[i].entry = i; | 716 | msix_entries[i].entry = i; |
717 | 717 | ||
718 | err = pci_enable_msix(dev, msix_entries, TIMBERDALE_NR_IRQS); | 718 | err = pci_enable_msix_exact(dev, msix_entries, TIMBERDALE_NR_IRQS); |
719 | if (err) { | 719 | if (err) { |
720 | dev_err(&dev->dev, | 720 | dev_err(&dev->dev, |
721 | "MSI-X init failed: %d, expected entries: %d\n", | 721 | "MSI-X init failed: %d, expected entries: %d\n", |
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c new file mode 100644 index 000000000000..a74bfb59f18f --- /dev/null +++ b/drivers/mfd/tps65218.c | |||
@@ -0,0 +1,282 @@ | |||
1 | /* | ||
2 | * Driver for TPS65218 Integrated power management chipsets | ||
3 | * | ||
4 | * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
11 | * kind, whether expressed or implied; without even the implied warranty | ||
12 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License version 2 for more details. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/regmap.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/of.h> | ||
26 | #include <linux/of_device.h> | ||
27 | #include <linux/irq.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/mutex.h> | ||
30 | |||
31 | #include <linux/mfd/core.h> | ||
32 | #include <linux/mfd/tps65218.h> | ||
33 | |||
34 | #define TPS65218_PASSWORD_REGS_UNLOCK 0x7D | ||
35 | |||
36 | /** | ||
37 | * tps65218_reg_read: Read a single tps65218 register. | ||
38 | * | ||
39 | * @tps: Device to read from. | ||
40 | * @reg: Register to read. | ||
41 | * @val: Contians the value | ||
42 | */ | ||
43 | int tps65218_reg_read(struct tps65218 *tps, unsigned int reg, | ||
44 | unsigned int *val) | ||
45 | { | ||
46 | return regmap_read(tps->regmap, reg, val); | ||
47 | } | ||
48 | EXPORT_SYMBOL_GPL(tps65218_reg_read); | ||
49 | |||
50 | /** | ||
51 | * tps65218_reg_write: Write a single tps65218 register. | ||
52 | * | ||
53 | * @tps65218: Device to write to. | ||
54 | * @reg: Register to write to. | ||
55 | * @val: Value to write. | ||
56 | * @level: Password protected level | ||
57 | */ | ||
58 | int tps65218_reg_write(struct tps65218 *tps, unsigned int reg, | ||
59 | unsigned int val, unsigned int level) | ||
60 | { | ||
61 | int ret; | ||
62 | unsigned int xor_reg_val; | ||
63 | |||
64 | switch (level) { | ||
65 | case TPS65218_PROTECT_NONE: | ||
66 | return regmap_write(tps->regmap, reg, val); | ||
67 | case TPS65218_PROTECT_L1: | ||
68 | xor_reg_val = reg ^ TPS65218_PASSWORD_REGS_UNLOCK; | ||
69 | ret = regmap_write(tps->regmap, TPS65218_REG_PASSWORD, | ||
70 | xor_reg_val); | ||
71 | if (ret < 0) | ||
72 | return ret; | ||
73 | |||
74 | return regmap_write(tps->regmap, reg, val); | ||
75 | default: | ||
76 | return -EINVAL; | ||
77 | } | ||
78 | } | ||
79 | EXPORT_SYMBOL_GPL(tps65218_reg_write); | ||
80 | |||
81 | /** | ||
82 | * tps65218_update_bits: Modify bits w.r.t mask, val and level. | ||
83 | * | ||
84 | * @tps65218: Device to write to. | ||
85 | * @reg: Register to read-write to. | ||
86 | * @mask: Mask. | ||
87 | * @val: Value to write. | ||
88 | * @level: Password protected level | ||
89 | */ | ||
90 | static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg, | ||
91 | unsigned int mask, unsigned int val, unsigned int level) | ||
92 | { | ||
93 | int ret; | ||
94 | unsigned int data; | ||
95 | |||
96 | ret = tps65218_reg_read(tps, reg, &data); | ||
97 | if (ret) { | ||
98 | dev_err(tps->dev, "Read from reg 0x%x failed\n", reg); | ||
99 | return ret; | ||
100 | } | ||
101 | |||
102 | data &= ~mask; | ||
103 | data |= val & mask; | ||
104 | |||
105 | mutex_lock(&tps->tps_lock); | ||
106 | ret = tps65218_reg_write(tps, reg, data, level); | ||
107 | if (ret) | ||
108 | dev_err(tps->dev, "Write for reg 0x%x failed\n", reg); | ||
109 | mutex_unlock(&tps->tps_lock); | ||
110 | |||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | int tps65218_set_bits(struct tps65218 *tps, unsigned int reg, | ||
115 | unsigned int mask, unsigned int val, unsigned int level) | ||
116 | { | ||
117 | return tps65218_update_bits(tps, reg, mask, val, level); | ||
118 | } | ||
119 | EXPORT_SYMBOL_GPL(tps65218_set_bits); | ||
120 | |||
121 | int tps65218_clear_bits(struct tps65218 *tps, unsigned int reg, | ||
122 | unsigned int mask, unsigned int level) | ||
123 | { | ||
124 | return tps65218_update_bits(tps, reg, mask, 0, level); | ||
125 | } | ||
126 | EXPORT_SYMBOL_GPL(tps65218_clear_bits); | ||
127 | |||
128 | static struct regmap_config tps65218_regmap_config = { | ||
129 | .reg_bits = 8, | ||
130 | .val_bits = 8, | ||
131 | .cache_type = REGCACHE_RBTREE, | ||
132 | }; | ||
133 | |||
134 | static const struct regmap_irq tps65218_irqs[] = { | ||
135 | /* INT1 IRQs */ | ||
136 | [TPS65218_PRGC_IRQ] = { | ||
137 | .mask = TPS65218_INT1_PRGC, | ||
138 | }, | ||
139 | [TPS65218_CC_AQC_IRQ] = { | ||
140 | .mask = TPS65218_INT1_CC_AQC, | ||
141 | }, | ||
142 | [TPS65218_HOT_IRQ] = { | ||
143 | .mask = TPS65218_INT1_HOT, | ||
144 | }, | ||
145 | [TPS65218_PB_IRQ] = { | ||
146 | .mask = TPS65218_INT1_PB, | ||
147 | }, | ||
148 | [TPS65218_AC_IRQ] = { | ||
149 | .mask = TPS65218_INT1_AC, | ||
150 | }, | ||
151 | [TPS65218_VPRG_IRQ] = { | ||
152 | .mask = TPS65218_INT1_VPRG, | ||
153 | }, | ||
154 | [TPS65218_INVALID1_IRQ] = { | ||
155 | }, | ||
156 | [TPS65218_INVALID2_IRQ] = { | ||
157 | }, | ||
158 | /* INT2 IRQs*/ | ||
159 | [TPS65218_LS1_I_IRQ] = { | ||
160 | .mask = TPS65218_INT2_LS1_I, | ||
161 | .reg_offset = 1, | ||
162 | }, | ||
163 | [TPS65218_LS2_I_IRQ] = { | ||
164 | .mask = TPS65218_INT2_LS2_I, | ||
165 | .reg_offset = 1, | ||
166 | }, | ||
167 | [TPS65218_LS3_I_IRQ] = { | ||
168 | .mask = TPS65218_INT2_LS3_I, | ||
169 | .reg_offset = 1, | ||
170 | }, | ||
171 | [TPS65218_LS1_F_IRQ] = { | ||
172 | .mask = TPS65218_INT2_LS1_F, | ||
173 | .reg_offset = 1, | ||
174 | }, | ||
175 | [TPS65218_LS2_F_IRQ] = { | ||
176 | .mask = TPS65218_INT2_LS2_F, | ||
177 | .reg_offset = 1, | ||
178 | }, | ||
179 | [TPS65218_LS3_F_IRQ] = { | ||
180 | .mask = TPS65218_INT2_LS3_F, | ||
181 | .reg_offset = 1, | ||
182 | }, | ||
183 | [TPS65218_INVALID3_IRQ] = { | ||
184 | }, | ||
185 | [TPS65218_INVALID4_IRQ] = { | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static struct regmap_irq_chip tps65218_irq_chip = { | ||
190 | .name = "tps65218", | ||
191 | .irqs = tps65218_irqs, | ||
192 | .num_irqs = ARRAY_SIZE(tps65218_irqs), | ||
193 | |||
194 | .num_regs = 2, | ||
195 | .mask_base = TPS65218_REG_INT_MASK1, | ||
196 | }; | ||
197 | |||
198 | static const struct of_device_id of_tps65218_match_table[] = { | ||
199 | { .compatible = "ti,tps65218", }, | ||
200 | }; | ||
201 | |||
202 | static int tps65218_probe(struct i2c_client *client, | ||
203 | const struct i2c_device_id *ids) | ||
204 | { | ||
205 | struct tps65218 *tps; | ||
206 | const struct of_device_id *match; | ||
207 | int ret; | ||
208 | |||
209 | match = of_match_device(of_tps65218_match_table, &client->dev); | ||
210 | if (!match) { | ||
211 | dev_err(&client->dev, | ||
212 | "Failed to find matching dt id\n"); | ||
213 | return -EINVAL; | ||
214 | } | ||
215 | |||
216 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | ||
217 | if (!tps) | ||
218 | return -ENOMEM; | ||
219 | |||
220 | i2c_set_clientdata(client, tps); | ||
221 | tps->dev = &client->dev; | ||
222 | tps->irq = client->irq; | ||
223 | tps->regmap = devm_regmap_init_i2c(client, &tps65218_regmap_config); | ||
224 | if (IS_ERR(tps->regmap)) { | ||
225 | ret = PTR_ERR(tps->regmap); | ||
226 | dev_err(tps->dev, "Failed to allocate register map: %d\n", | ||
227 | ret); | ||
228 | return ret; | ||
229 | } | ||
230 | |||
231 | mutex_init(&tps->tps_lock); | ||
232 | |||
233 | ret = regmap_add_irq_chip(tps->regmap, tps->irq, | ||
234 | IRQF_ONESHOT, 0, &tps65218_irq_chip, | ||
235 | &tps->irq_data); | ||
236 | if (ret < 0) | ||
237 | return ret; | ||
238 | |||
239 | ret = of_platform_populate(client->dev.of_node, NULL, NULL, | ||
240 | &client->dev); | ||
241 | if (ret < 0) | ||
242 | goto err_irq; | ||
243 | |||
244 | return 0; | ||
245 | |||
246 | err_irq: | ||
247 | regmap_del_irq_chip(tps->irq, tps->irq_data); | ||
248 | |||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | static int tps65218_remove(struct i2c_client *client) | ||
253 | { | ||
254 | struct tps65218 *tps = i2c_get_clientdata(client); | ||
255 | |||
256 | regmap_del_irq_chip(tps->irq, tps->irq_data); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static const struct i2c_device_id tps65218_id_table[] = { | ||
262 | { "tps65218", TPS65218 }, | ||
263 | { }, | ||
264 | }; | ||
265 | MODULE_DEVICE_TABLE(i2c, tps65218_id_table); | ||
266 | |||
267 | static struct i2c_driver tps65218_driver = { | ||
268 | .driver = { | ||
269 | .name = "tps65218", | ||
270 | .owner = THIS_MODULE, | ||
271 | .of_match_table = of_tps65218_match_table, | ||
272 | }, | ||
273 | .probe = tps65218_probe, | ||
274 | .remove = tps65218_remove, | ||
275 | .id_table = tps65218_id_table, | ||
276 | }; | ||
277 | |||
278 | module_i2c_driver(tps65218_driver); | ||
279 | |||
280 | MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); | ||
281 | MODULE_DESCRIPTION("TPS65218 chip family multi-function driver"); | ||
282 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1f142d76cbbc..460a014ca629 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -255,8 +255,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq, | |||
255 | ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq, | 255 | ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq, |
256 | IRQF_ONESHOT, pdata->irq_base, | 256 | IRQF_ONESHOT, pdata->irq_base, |
257 | tps6591x_irqs_chip, &tps65910->irq_data); | 257 | tps6591x_irqs_chip, &tps65910->irq_data); |
258 | if (ret < 0) | 258 | if (ret < 0) { |
259 | dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret); | 259 | dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret); |
260 | tps65910->chip_irq = 0; | ||
261 | } | ||
260 | return ret; | 262 | return ret; |
261 | } | 263 | } |
262 | 264 | ||
@@ -509,6 +511,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, | |||
509 | regmap_irq_get_domain(tps65910->irq_data)); | 511 | regmap_irq_get_domain(tps65910->irq_data)); |
510 | if (ret < 0) { | 512 | if (ret < 0) { |
511 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); | 513 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); |
514 | tps65910_irq_exit(tps65910); | ||
512 | return ret; | 515 | return ret; |
513 | } | 516 | } |
514 | 517 | ||
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 27a518e0eec6..1f82d60b1d0f 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
20 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
21 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
diff --git a/drivers/mfd/tps65912-irq.c b/drivers/mfd/tps65912-irq.c index d360a83a2738..fbecec7f1e3d 100644 --- a/drivers/mfd/tps65912-irq.c +++ b/drivers/mfd/tps65912-irq.c | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/init.h> | ||
19 | #include <linux/bug.h> | 18 | #include <linux/bug.h> |
20 | #include <linux/device.h> | 19 | #include <linux/device.h> |
21 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index ed718328eff1..e87140bef667 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -282,11 +282,11 @@ static struct reg_default twl4030_49_defaults[] = { | |||
282 | static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg) | 282 | static bool twl4030_49_nop_reg(struct device *dev, unsigned int reg) |
283 | { | 283 | { |
284 | switch (reg) { | 284 | switch (reg) { |
285 | case 0: | 285 | case 0x00: |
286 | case 3: | 286 | case 0x03: |
287 | case 40: | 287 | case 0x40: |
288 | case 41: | 288 | case 0x41: |
289 | case 42: | 289 | case 0x42: |
290 | return false; | 290 | return false; |
291 | default: | 291 | default: |
292 | return true; | 292 | return true; |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 9aa6d1efa241..596b1f657e21 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -27,7 +27,6 @@ | |||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/export.h> | 30 | #include <linux/export.h> |
32 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
33 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c deleted file mode 100644 index 4c583e471339..000000000000 --- a/drivers/mfd/twl4030-madc.c +++ /dev/null | |||
@@ -1,818 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * TWL4030 MADC module driver-This driver monitors the real time | ||
4 | * conversion of analog signals like battery temperature, | ||
5 | * battery type, battery level etc. | ||
6 | * | ||
7 | * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ | ||
8 | * J Keerthy <j-keerthy@ti.com> | ||
9 | * | ||
10 | * Based on twl4030-madc.c | ||
11 | * Copyright (C) 2008 Nokia Corporation | ||
12 | * Mikko Ylinen <mikko.k.ylinen@nokia.com> | ||
13 | * | ||
14 | * Amit Kucheria <amit.kucheria@canonical.com> | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or | ||
17 | * modify it under the terms of the GNU General Public License | ||
18 | * version 2 as published by the Free Software Foundation. | ||
19 | * | ||
20 | * This program is distributed in the hope that it will be useful, but | ||
21 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
23 | * General Public License for more details. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License | ||
26 | * along with this program; if not, write to the Free Software | ||
27 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
28 | * 02110-1301 USA | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/init.h> | ||
33 | #include <linux/device.h> | ||
34 | #include <linux/interrupt.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/slab.h> | ||
39 | #include <linux/i2c/twl.h> | ||
40 | #include <linux/i2c/twl4030-madc.h> | ||
41 | #include <linux/module.h> | ||
42 | #include <linux/stddef.h> | ||
43 | #include <linux/mutex.h> | ||
44 | #include <linux/bitops.h> | ||
45 | #include <linux/jiffies.h> | ||
46 | #include <linux/types.h> | ||
47 | #include <linux/gfp.h> | ||
48 | #include <linux/err.h> | ||
49 | |||
50 | /* | ||
51 | * struct twl4030_madc_data - a container for madc info | ||
52 | * @dev - pointer to device structure for madc | ||
53 | * @lock - mutex protecting this data structure | ||
54 | * @requests - Array of request struct corresponding to SW1, SW2 and RT | ||
55 | * @imr - Interrupt mask register of MADC | ||
56 | * @isr - Interrupt status register of MADC | ||
57 | */ | ||
58 | struct twl4030_madc_data { | ||
59 | struct device *dev; | ||
60 | struct mutex lock; /* mutex protecting this data structure */ | ||
61 | struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS]; | ||
62 | int imr; | ||
63 | int isr; | ||
64 | }; | ||
65 | |||
66 | static struct twl4030_madc_data *twl4030_madc; | ||
67 | |||
68 | struct twl4030_prescale_divider_ratios { | ||
69 | s16 numerator; | ||
70 | s16 denominator; | ||
71 | }; | ||
72 | |||
73 | static const struct twl4030_prescale_divider_ratios | ||
74 | twl4030_divider_ratios[16] = { | ||
75 | {1, 1}, /* CHANNEL 0 No Prescaler */ | ||
76 | {1, 1}, /* CHANNEL 1 No Prescaler */ | ||
77 | {6, 10}, /* CHANNEL 2 */ | ||
78 | {6, 10}, /* CHANNEL 3 */ | ||
79 | {6, 10}, /* CHANNEL 4 */ | ||
80 | {6, 10}, /* CHANNEL 5 */ | ||
81 | {6, 10}, /* CHANNEL 6 */ | ||
82 | {6, 10}, /* CHANNEL 7 */ | ||
83 | {3, 14}, /* CHANNEL 8 */ | ||
84 | {1, 3}, /* CHANNEL 9 */ | ||
85 | {1, 1}, /* CHANNEL 10 No Prescaler */ | ||
86 | {15, 100}, /* CHANNEL 11 */ | ||
87 | {1, 4}, /* CHANNEL 12 */ | ||
88 | {1, 1}, /* CHANNEL 13 Reserved channels */ | ||
89 | {1, 1}, /* CHANNEL 14 Reseved channels */ | ||
90 | {5, 11}, /* CHANNEL 15 */ | ||
91 | }; | ||
92 | |||
93 | |||
94 | /* | ||
95 | * Conversion table from -3 to 55 degree Celcius | ||
96 | */ | ||
97 | static int therm_tbl[] = { | ||
98 | 30800, 29500, 28300, 27100, | ||
99 | 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900, | ||
100 | 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100, | ||
101 | 11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310, | ||
102 | 8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830, | ||
103 | 5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170, | ||
104 | 4040, 3910, 3790, 3670, 3550 | ||
105 | }; | ||
106 | |||
107 | /* | ||
108 | * Structure containing the registers | ||
109 | * of different conversion methods supported by MADC. | ||
110 | * Hardware or RT real time conversion request initiated by external host | ||
111 | * processor for RT Signal conversions. | ||
112 | * External host processors can also request for non RT conversions | ||
113 | * SW1 and SW2 software conversions also called asynchronous or GPC request. | ||
114 | */ | ||
115 | static | ||
116 | const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = { | ||
117 | [TWL4030_MADC_RT] = { | ||
118 | .sel = TWL4030_MADC_RTSELECT_LSB, | ||
119 | .avg = TWL4030_MADC_RTAVERAGE_LSB, | ||
120 | .rbase = TWL4030_MADC_RTCH0_LSB, | ||
121 | }, | ||
122 | [TWL4030_MADC_SW1] = { | ||
123 | .sel = TWL4030_MADC_SW1SELECT_LSB, | ||
124 | .avg = TWL4030_MADC_SW1AVERAGE_LSB, | ||
125 | .rbase = TWL4030_MADC_GPCH0_LSB, | ||
126 | .ctrl = TWL4030_MADC_CTRL_SW1, | ||
127 | }, | ||
128 | [TWL4030_MADC_SW2] = { | ||
129 | .sel = TWL4030_MADC_SW2SELECT_LSB, | ||
130 | .avg = TWL4030_MADC_SW2AVERAGE_LSB, | ||
131 | .rbase = TWL4030_MADC_GPCH0_LSB, | ||
132 | .ctrl = TWL4030_MADC_CTRL_SW2, | ||
133 | }, | ||
134 | }; | ||
135 | |||
136 | /* | ||
137 | * Function to read a particular channel value. | ||
138 | * @madc - pointer to struct twl4030_madc_data | ||
139 | * @reg - lsb of ADC Channel | ||
140 | * If the i2c read fails it returns an error else returns 0. | ||
141 | */ | ||
142 | static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg) | ||
143 | { | ||
144 | u8 msb, lsb; | ||
145 | int ret; | ||
146 | /* | ||
147 | * For each ADC channel, we have MSB and LSB register pair. MSB address | ||
148 | * is always LSB address+1. reg parameter is the address of LSB register | ||
149 | */ | ||
150 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1); | ||
151 | if (ret) { | ||
152 | dev_err(madc->dev, "unable to read MSB register 0x%X\n", | ||
153 | reg + 1); | ||
154 | return ret; | ||
155 | } | ||
156 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg); | ||
157 | if (ret) { | ||
158 | dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | return (int)(((msb << 8) | lsb) >> 6); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Return battery temperature | ||
167 | * Or < 0 on failure. | ||
168 | */ | ||
169 | static int twl4030battery_temperature(int raw_volt) | ||
170 | { | ||
171 | u8 val; | ||
172 | int temp, curr, volt, res, ret; | ||
173 | |||
174 | volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R; | ||
175 | /* Getting and calculating the supply current in micro ampers */ | ||
176 | ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, | ||
177 | REG_BCICTL2); | ||
178 | if (ret < 0) | ||
179 | return ret; | ||
180 | curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10; | ||
181 | /* Getting and calculating the thermistor resistance in ohms */ | ||
182 | res = volt * 1000 / curr; | ||
183 | /* calculating temperature */ | ||
184 | for (temp = 58; temp >= 0; temp--) { | ||
185 | int actual = therm_tbl[temp]; | ||
186 | |||
187 | if ((actual - res) >= 0) | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | return temp + 1; | ||
192 | } | ||
193 | |||
194 | static int twl4030battery_current(int raw_volt) | ||
195 | { | ||
196 | int ret; | ||
197 | u8 val; | ||
198 | |||
199 | ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, | ||
200 | TWL4030_BCI_BCICTL1); | ||
201 | if (ret) | ||
202 | return ret; | ||
203 | if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */ | ||
204 | return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1; | ||
205 | else /* slope of 0.88 mV/mA */ | ||
206 | return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2; | ||
207 | } | ||
208 | /* | ||
209 | * Function to read channel values | ||
210 | * @madc - pointer to twl4030_madc_data struct | ||
211 | * @reg_base - Base address of the first channel | ||
212 | * @Channels - 16 bit bitmap. If the bit is set, channel value is read | ||
213 | * @buf - The channel values are stored here. if read fails error | ||
214 | * @raw - Return raw values without conversion | ||
215 | * value is stored | ||
216 | * Returns the number of successfully read channels. | ||
217 | */ | ||
218 | static int twl4030_madc_read_channels(struct twl4030_madc_data *madc, | ||
219 | u8 reg_base, unsigned | ||
220 | long channels, int *buf, | ||
221 | bool raw) | ||
222 | { | ||
223 | int count = 0, count_req = 0, i; | ||
224 | u8 reg; | ||
225 | |||
226 | for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) { | ||
227 | reg = reg_base + 2 * i; | ||
228 | buf[i] = twl4030_madc_channel_raw_read(madc, reg); | ||
229 | if (buf[i] < 0) { | ||
230 | dev_err(madc->dev, | ||
231 | "Unable to read register 0x%X\n", reg); | ||
232 | count_req++; | ||
233 | continue; | ||
234 | } | ||
235 | if (raw) { | ||
236 | count++; | ||
237 | continue; | ||
238 | } | ||
239 | switch (i) { | ||
240 | case 10: | ||
241 | buf[i] = twl4030battery_current(buf[i]); | ||
242 | if (buf[i] < 0) { | ||
243 | dev_err(madc->dev, "err reading current\n"); | ||
244 | count_req++; | ||
245 | } else { | ||
246 | count++; | ||
247 | buf[i] = buf[i] - 750; | ||
248 | } | ||
249 | break; | ||
250 | case 1: | ||
251 | buf[i] = twl4030battery_temperature(buf[i]); | ||
252 | if (buf[i] < 0) { | ||
253 | dev_err(madc->dev, "err reading temperature\n"); | ||
254 | count_req++; | ||
255 | } else { | ||
256 | buf[i] -= 3; | ||
257 | count++; | ||
258 | } | ||
259 | break; | ||
260 | default: | ||
261 | count++; | ||
262 | /* Analog Input (V) = conv_result * step_size / R | ||
263 | * conv_result = decimal value of 10-bit conversion | ||
264 | * result | ||
265 | * step size = 1.5 / (2 ^ 10 -1) | ||
266 | * R = Prescaler ratio for input channels. | ||
267 | * Result given in mV hence multiplied by 1000. | ||
268 | */ | ||
269 | buf[i] = (buf[i] * 3 * 1000 * | ||
270 | twl4030_divider_ratios[i].denominator) | ||
271 | / (2 * 1023 * | ||
272 | twl4030_divider_ratios[i].numerator); | ||
273 | } | ||
274 | } | ||
275 | if (count_req) | ||
276 | dev_err(madc->dev, "%d channel conversion failed\n", count_req); | ||
277 | |||
278 | return count; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Enables irq. | ||
283 | * @madc - pointer to twl4030_madc_data struct | ||
284 | * @id - irq number to be enabled | ||
285 | * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2 | ||
286 | * corresponding to RT, SW1, SW2 conversion requests. | ||
287 | * If the i2c read fails it returns an error else returns 0. | ||
288 | */ | ||
289 | static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id) | ||
290 | { | ||
291 | u8 val; | ||
292 | int ret; | ||
293 | |||
294 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr); | ||
295 | if (ret) { | ||
296 | dev_err(madc->dev, "unable to read imr register 0x%X\n", | ||
297 | madc->imr); | ||
298 | return ret; | ||
299 | } | ||
300 | val &= ~(1 << id); | ||
301 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr); | ||
302 | if (ret) { | ||
303 | dev_err(madc->dev, | ||
304 | "unable to write imr register 0x%X\n", madc->imr); | ||
305 | return ret; | ||
306 | |||
307 | } | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | /* | ||
313 | * Disables irq. | ||
314 | * @madc - pointer to twl4030_madc_data struct | ||
315 | * @id - irq number to be disabled | ||
316 | * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2 | ||
317 | * corresponding to RT, SW1, SW2 conversion requests. | ||
318 | * Returns error if i2c read/write fails. | ||
319 | */ | ||
320 | static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id) | ||
321 | { | ||
322 | u8 val; | ||
323 | int ret; | ||
324 | |||
325 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr); | ||
326 | if (ret) { | ||
327 | dev_err(madc->dev, "unable to read imr register 0x%X\n", | ||
328 | madc->imr); | ||
329 | return ret; | ||
330 | } | ||
331 | val |= (1 << id); | ||
332 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr); | ||
333 | if (ret) { | ||
334 | dev_err(madc->dev, | ||
335 | "unable to write imr register 0x%X\n", madc->imr); | ||
336 | return ret; | ||
337 | } | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc) | ||
343 | { | ||
344 | struct twl4030_madc_data *madc = _madc; | ||
345 | const struct twl4030_madc_conversion_method *method; | ||
346 | u8 isr_val, imr_val; | ||
347 | int i, len, ret; | ||
348 | struct twl4030_madc_request *r; | ||
349 | |||
350 | mutex_lock(&madc->lock); | ||
351 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr); | ||
352 | if (ret) { | ||
353 | dev_err(madc->dev, "unable to read isr register 0x%X\n", | ||
354 | madc->isr); | ||
355 | goto err_i2c; | ||
356 | } | ||
357 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr); | ||
358 | if (ret) { | ||
359 | dev_err(madc->dev, "unable to read imr register 0x%X\n", | ||
360 | madc->imr); | ||
361 | goto err_i2c; | ||
362 | } | ||
363 | isr_val &= ~imr_val; | ||
364 | for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { | ||
365 | if (!(isr_val & (1 << i))) | ||
366 | continue; | ||
367 | ret = twl4030_madc_disable_irq(madc, i); | ||
368 | if (ret < 0) | ||
369 | dev_dbg(madc->dev, "Disable interrupt failed%d\n", i); | ||
370 | madc->requests[i].result_pending = 1; | ||
371 | } | ||
372 | for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { | ||
373 | r = &madc->requests[i]; | ||
374 | /* No pending results for this method, move to next one */ | ||
375 | if (!r->result_pending) | ||
376 | continue; | ||
377 | method = &twl4030_conversion_methods[r->method]; | ||
378 | /* Read results */ | ||
379 | len = twl4030_madc_read_channels(madc, method->rbase, | ||
380 | r->channels, r->rbuf, r->raw); | ||
381 | /* Return results to caller */ | ||
382 | if (r->func_cb != NULL) { | ||
383 | r->func_cb(len, r->channels, r->rbuf); | ||
384 | r->func_cb = NULL; | ||
385 | } | ||
386 | /* Free request */ | ||
387 | r->result_pending = 0; | ||
388 | r->active = 0; | ||
389 | } | ||
390 | mutex_unlock(&madc->lock); | ||
391 | |||
392 | return IRQ_HANDLED; | ||
393 | |||
394 | err_i2c: | ||
395 | /* | ||
396 | * In case of error check whichever request is active | ||
397 | * and service the same. | ||
398 | */ | ||
399 | for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) { | ||
400 | r = &madc->requests[i]; | ||
401 | if (r->active == 0) | ||
402 | continue; | ||
403 | method = &twl4030_conversion_methods[r->method]; | ||
404 | /* Read results */ | ||
405 | len = twl4030_madc_read_channels(madc, method->rbase, | ||
406 | r->channels, r->rbuf, r->raw); | ||
407 | /* Return results to caller */ | ||
408 | if (r->func_cb != NULL) { | ||
409 | r->func_cb(len, r->channels, r->rbuf); | ||
410 | r->func_cb = NULL; | ||
411 | } | ||
412 | /* Free request */ | ||
413 | r->result_pending = 0; | ||
414 | r->active = 0; | ||
415 | } | ||
416 | mutex_unlock(&madc->lock); | ||
417 | |||
418 | return IRQ_HANDLED; | ||
419 | } | ||
420 | |||
421 | static int twl4030_madc_set_irq(struct twl4030_madc_data *madc, | ||
422 | struct twl4030_madc_request *req) | ||
423 | { | ||
424 | struct twl4030_madc_request *p; | ||
425 | int ret; | ||
426 | |||
427 | p = &madc->requests[req->method]; | ||
428 | memcpy(p, req, sizeof(*req)); | ||
429 | ret = twl4030_madc_enable_irq(madc, req->method); | ||
430 | if (ret < 0) { | ||
431 | dev_err(madc->dev, "enable irq failed!!\n"); | ||
432 | return ret; | ||
433 | } | ||
434 | |||
435 | return 0; | ||
436 | } | ||
437 | |||
438 | /* | ||
439 | * Function which enables the madc conversion | ||
440 | * by writing to the control register. | ||
441 | * @madc - pointer to twl4030_madc_data struct | ||
442 | * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1 | ||
443 | * corresponding to RT SW1 or SW2 conversion methods. | ||
444 | * Returns 0 if succeeds else a negative error value | ||
445 | */ | ||
446 | static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc, | ||
447 | int conv_method) | ||
448 | { | ||
449 | const struct twl4030_madc_conversion_method *method; | ||
450 | int ret = 0; | ||
451 | method = &twl4030_conversion_methods[conv_method]; | ||
452 | switch (conv_method) { | ||
453 | case TWL4030_MADC_SW1: | ||
454 | case TWL4030_MADC_SW2: | ||
455 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, | ||
456 | TWL4030_MADC_SW_START, method->ctrl); | ||
457 | if (ret) { | ||
458 | dev_err(madc->dev, | ||
459 | "unable to write ctrl register 0x%X\n", | ||
460 | method->ctrl); | ||
461 | return ret; | ||
462 | } | ||
463 | break; | ||
464 | default: | ||
465 | break; | ||
466 | } | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Function that waits for conversion to be ready | ||
473 | * @madc - pointer to twl4030_madc_data struct | ||
474 | * @timeout_ms - timeout value in milliseconds | ||
475 | * @status_reg - ctrl register | ||
476 | * returns 0 if succeeds else a negative error value | ||
477 | */ | ||
478 | static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc, | ||
479 | unsigned int timeout_ms, | ||
480 | u8 status_reg) | ||
481 | { | ||
482 | unsigned long timeout; | ||
483 | int ret; | ||
484 | |||
485 | timeout = jiffies + msecs_to_jiffies(timeout_ms); | ||
486 | do { | ||
487 | u8 reg; | ||
488 | |||
489 | ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, ®, status_reg); | ||
490 | if (ret) { | ||
491 | dev_err(madc->dev, | ||
492 | "unable to read status register 0x%X\n", | ||
493 | status_reg); | ||
494 | return ret; | ||
495 | } | ||
496 | if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW)) | ||
497 | return 0; | ||
498 | usleep_range(500, 2000); | ||
499 | } while (!time_after(jiffies, timeout)); | ||
500 | dev_err(madc->dev, "conversion timeout!\n"); | ||
501 | |||
502 | return -EAGAIN; | ||
503 | } | ||
504 | |||
505 | /* | ||
506 | * An exported function which can be called from other kernel drivers. | ||
507 | * @req twl4030_madc_request structure | ||
508 | * req->rbuf will be filled with read values of channels based on the | ||
509 | * channel index. If a particular channel reading fails there will | ||
510 | * be a negative error value in the corresponding array element. | ||
511 | * returns 0 if succeeds else error value | ||
512 | */ | ||
513 | int twl4030_madc_conversion(struct twl4030_madc_request *req) | ||
514 | { | ||
515 | const struct twl4030_madc_conversion_method *method; | ||
516 | u8 ch_msb, ch_lsb; | ||
517 | int ret; | ||
518 | |||
519 | if (!req || !twl4030_madc) | ||
520 | return -EINVAL; | ||
521 | |||
522 | mutex_lock(&twl4030_madc->lock); | ||
523 | if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) { | ||
524 | ret = -EINVAL; | ||
525 | goto out; | ||
526 | } | ||
527 | /* Do we have a conversion request ongoing */ | ||
528 | if (twl4030_madc->requests[req->method].active) { | ||
529 | ret = -EBUSY; | ||
530 | goto out; | ||
531 | } | ||
532 | ch_msb = (req->channels >> 8) & 0xff; | ||
533 | ch_lsb = req->channels & 0xff; | ||
534 | method = &twl4030_conversion_methods[req->method]; | ||
535 | /* Select channels to be converted */ | ||
536 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1); | ||
537 | if (ret) { | ||
538 | dev_err(twl4030_madc->dev, | ||
539 | "unable to write sel register 0x%X\n", method->sel + 1); | ||
540 | goto out; | ||
541 | } | ||
542 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel); | ||
543 | if (ret) { | ||
544 | dev_err(twl4030_madc->dev, | ||
545 | "unable to write sel register 0x%X\n", method->sel + 1); | ||
546 | goto out; | ||
547 | } | ||
548 | /* Select averaging for all channels if do_avg is set */ | ||
549 | if (req->do_avg) { | ||
550 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, | ||
551 | ch_msb, method->avg + 1); | ||
552 | if (ret) { | ||
553 | dev_err(twl4030_madc->dev, | ||
554 | "unable to write avg register 0x%X\n", | ||
555 | method->avg + 1); | ||
556 | goto out; | ||
557 | } | ||
558 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, | ||
559 | ch_lsb, method->avg); | ||
560 | if (ret) { | ||
561 | dev_err(twl4030_madc->dev, | ||
562 | "unable to write sel reg 0x%X\n", | ||
563 | method->sel + 1); | ||
564 | goto out; | ||
565 | } | ||
566 | } | ||
567 | if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) { | ||
568 | ret = twl4030_madc_set_irq(twl4030_madc, req); | ||
569 | if (ret < 0) | ||
570 | goto out; | ||
571 | ret = twl4030_madc_start_conversion(twl4030_madc, req->method); | ||
572 | if (ret < 0) | ||
573 | goto out; | ||
574 | twl4030_madc->requests[req->method].active = 1; | ||
575 | ret = 0; | ||
576 | goto out; | ||
577 | } | ||
578 | /* With RT method we should not be here anymore */ | ||
579 | if (req->method == TWL4030_MADC_RT) { | ||
580 | ret = -EINVAL; | ||
581 | goto out; | ||
582 | } | ||
583 | ret = twl4030_madc_start_conversion(twl4030_madc, req->method); | ||
584 | if (ret < 0) | ||
585 | goto out; | ||
586 | twl4030_madc->requests[req->method].active = 1; | ||
587 | /* Wait until conversion is ready (ctrl register returns EOC) */ | ||
588 | ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl); | ||
589 | if (ret) { | ||
590 | twl4030_madc->requests[req->method].active = 0; | ||
591 | goto out; | ||
592 | } | ||
593 | ret = twl4030_madc_read_channels(twl4030_madc, method->rbase, | ||
594 | req->channels, req->rbuf, req->raw); | ||
595 | twl4030_madc->requests[req->method].active = 0; | ||
596 | |||
597 | out: | ||
598 | mutex_unlock(&twl4030_madc->lock); | ||
599 | |||
600 | return ret; | ||
601 | } | ||
602 | EXPORT_SYMBOL_GPL(twl4030_madc_conversion); | ||
603 | |||
604 | /* | ||
605 | * Return channel value | ||
606 | * Or < 0 on failure. | ||
607 | */ | ||
608 | int twl4030_get_madc_conversion(int channel_no) | ||
609 | { | ||
610 | struct twl4030_madc_request req; | ||
611 | int temp = 0; | ||
612 | int ret; | ||
613 | |||
614 | req.channels = (1 << channel_no); | ||
615 | req.method = TWL4030_MADC_SW2; | ||
616 | req.active = 0; | ||
617 | req.func_cb = NULL; | ||
618 | ret = twl4030_madc_conversion(&req); | ||
619 | if (ret < 0) | ||
620 | return ret; | ||
621 | if (req.rbuf[channel_no] > 0) | ||
622 | temp = req.rbuf[channel_no]; | ||
623 | |||
624 | return temp; | ||
625 | } | ||
626 | EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion); | ||
627 | |||
628 | /* | ||
629 | * Function to enable or disable bias current for | ||
630 | * main battery type reading or temperature sensing | ||
631 | * @madc - pointer to twl4030_madc_data struct | ||
632 | * @chan - can be one of the two values | ||
633 | * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading | ||
634 | * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature | ||
635 | * sensing | ||
636 | * @on - enable or disable chan. | ||
637 | */ | ||
638 | static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc, | ||
639 | int chan, int on) | ||
640 | { | ||
641 | int ret; | ||
642 | u8 regval; | ||
643 | |||
644 | ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, | ||
645 | ®val, TWL4030_BCI_BCICTL1); | ||
646 | if (ret) { | ||
647 | dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X", | ||
648 | TWL4030_BCI_BCICTL1); | ||
649 | return ret; | ||
650 | } | ||
651 | if (on) | ||
652 | regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN; | ||
653 | else | ||
654 | regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN; | ||
655 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
656 | regval, TWL4030_BCI_BCICTL1); | ||
657 | if (ret) { | ||
658 | dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n", | ||
659 | TWL4030_BCI_BCICTL1); | ||
660 | return ret; | ||
661 | } | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | /* | ||
667 | * Function that sets MADC software power on bit to enable MADC | ||
668 | * @madc - pointer to twl4030_madc_data struct | ||
669 | * @on - Enable or disable MADC software powen on bit. | ||
670 | * returns error if i2c read/write fails else 0 | ||
671 | */ | ||
672 | static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on) | ||
673 | { | ||
674 | u8 regval; | ||
675 | int ret; | ||
676 | |||
677 | ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, | ||
678 | ®val, TWL4030_MADC_CTRL1); | ||
679 | if (ret) { | ||
680 | dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n", | ||
681 | TWL4030_MADC_CTRL1); | ||
682 | return ret; | ||
683 | } | ||
684 | if (on) | ||
685 | regval |= TWL4030_MADC_MADCON; | ||
686 | else | ||
687 | regval &= ~TWL4030_MADC_MADCON; | ||
688 | ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1); | ||
689 | if (ret) { | ||
690 | dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n", | ||
691 | TWL4030_MADC_CTRL1); | ||
692 | return ret; | ||
693 | } | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Initialize MADC and request for threaded irq | ||
700 | */ | ||
701 | static int twl4030_madc_probe(struct platform_device *pdev) | ||
702 | { | ||
703 | struct twl4030_madc_data *madc; | ||
704 | struct twl4030_madc_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
705 | int ret; | ||
706 | u8 regval; | ||
707 | |||
708 | if (!pdata) { | ||
709 | dev_err(&pdev->dev, "platform_data not available\n"); | ||
710 | return -EINVAL; | ||
711 | } | ||
712 | madc = kzalloc(sizeof(*madc), GFP_KERNEL); | ||
713 | if (!madc) | ||
714 | return -ENOMEM; | ||
715 | |||
716 | madc->dev = &pdev->dev; | ||
717 | |||
718 | /* | ||
719 | * Phoenix provides 2 interrupt lines. The first one is connected to | ||
720 | * the OMAP. The other one can be connected to the other processor such | ||
721 | * as modem. Hence two separate ISR and IMR registers. | ||
722 | */ | ||
723 | madc->imr = (pdata->irq_line == 1) ? | ||
724 | TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2; | ||
725 | madc->isr = (pdata->irq_line == 1) ? | ||
726 | TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2; | ||
727 | ret = twl4030_madc_set_power(madc, 1); | ||
728 | if (ret < 0) | ||
729 | goto err_power; | ||
730 | ret = twl4030_madc_set_current_generator(madc, 0, 1); | ||
731 | if (ret < 0) | ||
732 | goto err_current_generator; | ||
733 | |||
734 | ret = twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, | ||
735 | ®val, TWL4030_BCI_BCICTL1); | ||
736 | if (ret) { | ||
737 | dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n", | ||
738 | TWL4030_BCI_BCICTL1); | ||
739 | goto err_i2c; | ||
740 | } | ||
741 | regval |= TWL4030_BCI_MESBAT; | ||
742 | ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, | ||
743 | regval, TWL4030_BCI_BCICTL1); | ||
744 | if (ret) { | ||
745 | dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n", | ||
746 | TWL4030_BCI_BCICTL1); | ||
747 | goto err_i2c; | ||
748 | } | ||
749 | |||
750 | /* Check that MADC clock is on */ | ||
751 | ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, ®val, TWL4030_REG_GPBR1); | ||
752 | if (ret) { | ||
753 | dev_err(&pdev->dev, "unable to read reg GPBR1 0x%X\n", | ||
754 | TWL4030_REG_GPBR1); | ||
755 | goto err_i2c; | ||
756 | } | ||
757 | |||
758 | /* If MADC clk is not on, turn it on */ | ||
759 | if (!(regval & TWL4030_GPBR1_MADC_HFCLK_EN)) { | ||
760 | dev_info(&pdev->dev, "clk disabled, enabling\n"); | ||
761 | regval |= TWL4030_GPBR1_MADC_HFCLK_EN; | ||
762 | ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, regval, | ||
763 | TWL4030_REG_GPBR1); | ||
764 | if (ret) { | ||
765 | dev_err(&pdev->dev, "unable to write reg GPBR1 0x%X\n", | ||
766 | TWL4030_REG_GPBR1); | ||
767 | goto err_i2c; | ||
768 | } | ||
769 | } | ||
770 | |||
771 | platform_set_drvdata(pdev, madc); | ||
772 | mutex_init(&madc->lock); | ||
773 | ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL, | ||
774 | twl4030_madc_threaded_irq_handler, | ||
775 | IRQF_TRIGGER_RISING, "twl4030_madc", madc); | ||
776 | if (ret) { | ||
777 | dev_dbg(&pdev->dev, "could not request irq\n"); | ||
778 | goto err_i2c; | ||
779 | } | ||
780 | twl4030_madc = madc; | ||
781 | return 0; | ||
782 | err_i2c: | ||
783 | twl4030_madc_set_current_generator(madc, 0, 0); | ||
784 | err_current_generator: | ||
785 | twl4030_madc_set_power(madc, 0); | ||
786 | err_power: | ||
787 | kfree(madc); | ||
788 | |||
789 | return ret; | ||
790 | } | ||
791 | |||
792 | static int twl4030_madc_remove(struct platform_device *pdev) | ||
793 | { | ||
794 | struct twl4030_madc_data *madc = platform_get_drvdata(pdev); | ||
795 | |||
796 | free_irq(platform_get_irq(pdev, 0), madc); | ||
797 | twl4030_madc_set_current_generator(madc, 0, 0); | ||
798 | twl4030_madc_set_power(madc, 0); | ||
799 | kfree(madc); | ||
800 | |||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static struct platform_driver twl4030_madc_driver = { | ||
805 | .probe = twl4030_madc_probe, | ||
806 | .remove = twl4030_madc_remove, | ||
807 | .driver = { | ||
808 | .name = "twl4030_madc", | ||
809 | .owner = THIS_MODULE, | ||
810 | }, | ||
811 | }; | ||
812 | |||
813 | module_platform_driver(twl4030_madc_driver); | ||
814 | |||
815 | MODULE_DESCRIPTION("TWL4030 ADC driver"); | ||
816 | MODULE_LICENSE("GPL"); | ||
817 | MODULE_AUTHOR("J Keerthy"); | ||
818 | MODULE_ALIAS("platform:twl4030_madc"); | ||
diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 18a607e2ca06..a6bb17d908b8 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c | |||
@@ -31,7 +31,6 @@ | |||
31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 31 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/export.h> | 34 | #include <linux/export.h> |
36 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
37 | #include <linux/irq.h> | 36 | #include <linux/irq.h> |
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index 75316fb33448..6e88f25832fb 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c | |||
@@ -661,6 +661,11 @@ static int twl6040_probe(struct i2c_client *client, | |||
661 | init_completion(&twl6040->ready); | 661 | init_completion(&twl6040->ready); |
662 | 662 | ||
663 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); | 663 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); |
664 | if (twl6040->rev < 0) { | ||
665 | dev_err(&client->dev, "Failed to read revision register: %d\n", | ||
666 | twl6040->rev); | ||
667 | goto gpio_err; | ||
668 | } | ||
664 | 669 | ||
665 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ | 670 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ |
666 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) | 671 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) |
@@ -703,7 +708,6 @@ static int twl6040_probe(struct i2c_client *client, | |||
703 | } | 708 | } |
704 | 709 | ||
705 | /* dual-access registers controlled by I2C only */ | 710 | /* dual-access registers controlled by I2C only */ |
706 | twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL); | ||
707 | regmap_register_patch(twl6040->regmap, twl6040_patch, | 711 | regmap_register_patch(twl6040->regmap, twl6040_patch, |
708 | ARRAY_SIZE(twl6040_patch)); | 712 | ARRAY_SIZE(twl6040_patch)); |
709 | 713 | ||
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 0313f839e8fa..153d595afaac 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
@@ -742,9 +742,7 @@ static int ucb1x00_resume(struct device *dev) | |||
742 | } | 742 | } |
743 | #endif | 743 | #endif |
744 | 744 | ||
745 | static const struct dev_pm_ops ucb1x00_pm_ops = { | 745 | static SIMPLE_DEV_PM_OPS(ucb1x00_pm_ops, ucb1x00_suspend, ucb1x00_resume); |
746 | SET_SYSTEM_SLEEP_PM_OPS(ucb1x00_suspend, ucb1x00_resume) | ||
747 | }; | ||
748 | 746 | ||
749 | static struct mcp_driver ucb1x00_driver = { | 747 | static struct mcp_driver ucb1x00_driver = { |
750 | .drv = { | 748 | .drv = { |
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c index 84ce6b9daa3d..d0db89d13e01 100644 --- a/drivers/mfd/vexpress-config.c +++ b/drivers/mfd/vexpress-config.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/bitops.h> | 16 | #include <linux/bitops.h> |
17 | #include <linux/completion.h> | 17 | #include <linux/completion.h> |
18 | #include <linux/export.h> | 18 | #include <linux/export.h> |
19 | #include <linux/init.h> | ||
20 | #include <linux/list.h> | 19 | #include <linux/list.h> |
21 | #include <linux/of.h> | 20 | #include <linux/of.h> |
22 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
@@ -27,7 +26,7 @@ | |||
27 | 26 | ||
28 | #define VEXPRESS_CONFIG_MAX_BRIDGES 2 | 27 | #define VEXPRESS_CONFIG_MAX_BRIDGES 2 |
29 | 28 | ||
30 | struct vexpress_config_bridge { | 29 | static struct vexpress_config_bridge { |
31 | struct device_node *node; | 30 | struct device_node *node; |
32 | struct vexpress_config_bridge_info *info; | 31 | struct vexpress_config_bridge_info *info; |
33 | struct list_head transactions; | 32 | struct list_head transactions; |
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 981bef4b7ebc..35281e804e7e 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c | |||
@@ -168,7 +168,7 @@ static void *vexpress_sysreg_config_func_get(struct device *dev, | |||
168 | struct device_node *node) | 168 | struct device_node *node) |
169 | { | 169 | { |
170 | struct vexpress_sysreg_config_func *config_func; | 170 | struct vexpress_sysreg_config_func *config_func; |
171 | u32 site; | 171 | u32 site = 0; |
172 | u32 position = 0; | 172 | u32 position = 0; |
173 | u32 dcc = 0; | 173 | u32 dcc = 0; |
174 | u32 func_device[2]; | 174 | u32 func_device[2]; |
diff --git a/drivers/mfd/wm5102-tables.c b/drivers/mfd/wm5102-tables.c index bffc584e4a43..070f8cfbbd7a 100644 --- a/drivers/mfd/wm5102-tables.c +++ b/drivers/mfd/wm5102-tables.c | |||
@@ -73,6 +73,7 @@ static const struct reg_default wm5102_revb_patch[] = { | |||
73 | { 0x171, 0x0000 }, | 73 | { 0x171, 0x0000 }, |
74 | { 0x35E, 0x000C }, | 74 | { 0x35E, 0x000C }, |
75 | { 0x2D4, 0x0000 }, | 75 | { 0x2D4, 0x0000 }, |
76 | { 0x4DC, 0x0900 }, | ||
76 | { 0x80, 0x0000 }, | 77 | { 0x80, 0x0000 }, |
77 | }; | 78 | }; |
78 | 79 | ||
@@ -1839,6 +1840,23 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg) | |||
1839 | case ARIZONA_DSP1_STATUS_1: | 1840 | case ARIZONA_DSP1_STATUS_1: |
1840 | case ARIZONA_DSP1_STATUS_2: | 1841 | case ARIZONA_DSP1_STATUS_2: |
1841 | case ARIZONA_DSP1_STATUS_3: | 1842 | case ARIZONA_DSP1_STATUS_3: |
1843 | case ARIZONA_DSP1_WDMA_BUFFER_1: | ||
1844 | case ARIZONA_DSP1_WDMA_BUFFER_2: | ||
1845 | case ARIZONA_DSP1_WDMA_BUFFER_3: | ||
1846 | case ARIZONA_DSP1_WDMA_BUFFER_4: | ||
1847 | case ARIZONA_DSP1_WDMA_BUFFER_5: | ||
1848 | case ARIZONA_DSP1_WDMA_BUFFER_6: | ||
1849 | case ARIZONA_DSP1_WDMA_BUFFER_7: | ||
1850 | case ARIZONA_DSP1_WDMA_BUFFER_8: | ||
1851 | case ARIZONA_DSP1_RDMA_BUFFER_1: | ||
1852 | case ARIZONA_DSP1_RDMA_BUFFER_2: | ||
1853 | case ARIZONA_DSP1_RDMA_BUFFER_3: | ||
1854 | case ARIZONA_DSP1_RDMA_BUFFER_4: | ||
1855 | case ARIZONA_DSP1_RDMA_BUFFER_5: | ||
1856 | case ARIZONA_DSP1_RDMA_BUFFER_6: | ||
1857 | case ARIZONA_DSP1_WDMA_CONFIG_1: | ||
1858 | case ARIZONA_DSP1_WDMA_CONFIG_2: | ||
1859 | case ARIZONA_DSP1_RDMA_CONFIG_1: | ||
1842 | case ARIZONA_DSP1_SCRATCH_0: | 1860 | case ARIZONA_DSP1_SCRATCH_0: |
1843 | case ARIZONA_DSP1_SCRATCH_1: | 1861 | case ARIZONA_DSP1_SCRATCH_1: |
1844 | case ARIZONA_DSP1_SCRATCH_2: | 1862 | case ARIZONA_DSP1_SCRATCH_2: |
@@ -1894,9 +1912,27 @@ static bool wm5102_volatile_register(struct device *dev, unsigned int reg) | |||
1894 | case ARIZONA_AOD_IRQ1: | 1912 | case ARIZONA_AOD_IRQ1: |
1895 | case ARIZONA_AOD_IRQ2: | 1913 | case ARIZONA_AOD_IRQ2: |
1896 | case ARIZONA_AOD_IRQ_RAW_STATUS: | 1914 | case ARIZONA_AOD_IRQ_RAW_STATUS: |
1915 | case ARIZONA_DSP1_CLOCKING_1: | ||
1897 | case ARIZONA_DSP1_STATUS_1: | 1916 | case ARIZONA_DSP1_STATUS_1: |
1898 | case ARIZONA_DSP1_STATUS_2: | 1917 | case ARIZONA_DSP1_STATUS_2: |
1899 | case ARIZONA_DSP1_STATUS_3: | 1918 | case ARIZONA_DSP1_STATUS_3: |
1919 | case ARIZONA_DSP1_WDMA_BUFFER_1: | ||
1920 | case ARIZONA_DSP1_WDMA_BUFFER_2: | ||
1921 | case ARIZONA_DSP1_WDMA_BUFFER_3: | ||
1922 | case ARIZONA_DSP1_WDMA_BUFFER_4: | ||
1923 | case ARIZONA_DSP1_WDMA_BUFFER_5: | ||
1924 | case ARIZONA_DSP1_WDMA_BUFFER_6: | ||
1925 | case ARIZONA_DSP1_WDMA_BUFFER_7: | ||
1926 | case ARIZONA_DSP1_WDMA_BUFFER_8: | ||
1927 | case ARIZONA_DSP1_RDMA_BUFFER_1: | ||
1928 | case ARIZONA_DSP1_RDMA_BUFFER_2: | ||
1929 | case ARIZONA_DSP1_RDMA_BUFFER_3: | ||
1930 | case ARIZONA_DSP1_RDMA_BUFFER_4: | ||
1931 | case ARIZONA_DSP1_RDMA_BUFFER_5: | ||
1932 | case ARIZONA_DSP1_RDMA_BUFFER_6: | ||
1933 | case ARIZONA_DSP1_WDMA_CONFIG_1: | ||
1934 | case ARIZONA_DSP1_WDMA_CONFIG_2: | ||
1935 | case ARIZONA_DSP1_RDMA_CONFIG_1: | ||
1900 | case ARIZONA_DSP1_SCRATCH_0: | 1936 | case ARIZONA_DSP1_SCRATCH_0: |
1901 | case ARIZONA_DSP1_SCRATCH_1: | 1937 | case ARIZONA_DSP1_SCRATCH_1: |
1902 | case ARIZONA_DSP1_SCRATCH_2: | 1938 | case ARIZONA_DSP1_SCRATCH_2: |
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c index 11632f135e8c..1942b6f231da 100644 --- a/drivers/mfd/wm5110-tables.c +++ b/drivers/mfd/wm5110-tables.c | |||
@@ -538,7 +538,7 @@ static const struct reg_default wm5110_reg_default[] = { | |||
538 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ | 538 | { 0x00000219, 0x01A6 }, /* R537 - Mic Bias Ctrl 2 */ |
539 | { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ | 539 | { 0x0000021A, 0x01A6 }, /* R538 - Mic Bias Ctrl 3 */ |
540 | { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ | 540 | { 0x00000293, 0x0000 }, /* R659 - Accessory Detect Mode 1 */ |
541 | { 0x0000029B, 0x0020 }, /* R667 - Headphone Detect 1 */ | 541 | { 0x0000029B, 0x0028 }, /* R667 - Headphone Detect 1 */ |
542 | { 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */ | 542 | { 0x0000029C, 0x0000 }, /* R668 - Headphone Detect 2 */ |
543 | { 0x000002A2, 0x0000 }, /* R674 - Micd clamp control */ | 543 | { 0x000002A2, 0x0000 }, /* R674 - Micd clamp control */ |
544 | { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ | 544 | { 0x000002A3, 0x1102 }, /* R675 - Mic Detect 1 */ |
@@ -2461,6 +2461,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
2461 | case ARIZONA_DSP1_STATUS_1: | 2461 | case ARIZONA_DSP1_STATUS_1: |
2462 | case ARIZONA_DSP1_STATUS_2: | 2462 | case ARIZONA_DSP1_STATUS_2: |
2463 | case ARIZONA_DSP1_STATUS_3: | 2463 | case ARIZONA_DSP1_STATUS_3: |
2464 | case ARIZONA_DSP1_STATUS_4: | ||
2465 | case ARIZONA_DSP1_WDMA_BUFFER_1: | ||
2466 | case ARIZONA_DSP1_WDMA_BUFFER_2: | ||
2467 | case ARIZONA_DSP1_WDMA_BUFFER_3: | ||
2468 | case ARIZONA_DSP1_WDMA_BUFFER_4: | ||
2469 | case ARIZONA_DSP1_WDMA_BUFFER_5: | ||
2470 | case ARIZONA_DSP1_WDMA_BUFFER_6: | ||
2471 | case ARIZONA_DSP1_WDMA_BUFFER_7: | ||
2472 | case ARIZONA_DSP1_WDMA_BUFFER_8: | ||
2473 | case ARIZONA_DSP1_RDMA_BUFFER_1: | ||
2474 | case ARIZONA_DSP1_RDMA_BUFFER_2: | ||
2475 | case ARIZONA_DSP1_RDMA_BUFFER_3: | ||
2476 | case ARIZONA_DSP1_RDMA_BUFFER_4: | ||
2477 | case ARIZONA_DSP1_RDMA_BUFFER_5: | ||
2478 | case ARIZONA_DSP1_RDMA_BUFFER_6: | ||
2479 | case ARIZONA_DSP1_WDMA_CONFIG_1: | ||
2480 | case ARIZONA_DSP1_WDMA_CONFIG_2: | ||
2481 | case ARIZONA_DSP1_WDMA_OFFSET_1: | ||
2482 | case ARIZONA_DSP1_RDMA_CONFIG_1: | ||
2483 | case ARIZONA_DSP1_RDMA_OFFSET_1: | ||
2484 | case ARIZONA_DSP1_EXTERNAL_START_SELECT_1: | ||
2464 | case ARIZONA_DSP1_SCRATCH_0: | 2485 | case ARIZONA_DSP1_SCRATCH_0: |
2465 | case ARIZONA_DSP1_SCRATCH_1: | 2486 | case ARIZONA_DSP1_SCRATCH_1: |
2466 | case ARIZONA_DSP1_SCRATCH_2: | 2487 | case ARIZONA_DSP1_SCRATCH_2: |
@@ -2470,6 +2491,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
2470 | case ARIZONA_DSP2_STATUS_1: | 2491 | case ARIZONA_DSP2_STATUS_1: |
2471 | case ARIZONA_DSP2_STATUS_2: | 2492 | case ARIZONA_DSP2_STATUS_2: |
2472 | case ARIZONA_DSP2_STATUS_3: | 2493 | case ARIZONA_DSP2_STATUS_3: |
2494 | case ARIZONA_DSP2_STATUS_4: | ||
2495 | case ARIZONA_DSP2_WDMA_BUFFER_1: | ||
2496 | case ARIZONA_DSP2_WDMA_BUFFER_2: | ||
2497 | case ARIZONA_DSP2_WDMA_BUFFER_3: | ||
2498 | case ARIZONA_DSP2_WDMA_BUFFER_4: | ||
2499 | case ARIZONA_DSP2_WDMA_BUFFER_5: | ||
2500 | case ARIZONA_DSP2_WDMA_BUFFER_6: | ||
2501 | case ARIZONA_DSP2_WDMA_BUFFER_7: | ||
2502 | case ARIZONA_DSP2_WDMA_BUFFER_8: | ||
2503 | case ARIZONA_DSP2_RDMA_BUFFER_1: | ||
2504 | case ARIZONA_DSP2_RDMA_BUFFER_2: | ||
2505 | case ARIZONA_DSP2_RDMA_BUFFER_3: | ||
2506 | case ARIZONA_DSP2_RDMA_BUFFER_4: | ||
2507 | case ARIZONA_DSP2_RDMA_BUFFER_5: | ||
2508 | case ARIZONA_DSP2_RDMA_BUFFER_6: | ||
2509 | case ARIZONA_DSP2_WDMA_CONFIG_1: | ||
2510 | case ARIZONA_DSP2_WDMA_CONFIG_2: | ||
2511 | case ARIZONA_DSP2_WDMA_OFFSET_1: | ||
2512 | case ARIZONA_DSP2_RDMA_CONFIG_1: | ||
2513 | case ARIZONA_DSP2_RDMA_OFFSET_1: | ||
2514 | case ARIZONA_DSP2_EXTERNAL_START_SELECT_1: | ||
2473 | case ARIZONA_DSP2_SCRATCH_0: | 2515 | case ARIZONA_DSP2_SCRATCH_0: |
2474 | case ARIZONA_DSP2_SCRATCH_1: | 2516 | case ARIZONA_DSP2_SCRATCH_1: |
2475 | case ARIZONA_DSP2_SCRATCH_2: | 2517 | case ARIZONA_DSP2_SCRATCH_2: |
@@ -2479,6 +2521,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
2479 | case ARIZONA_DSP3_STATUS_1: | 2521 | case ARIZONA_DSP3_STATUS_1: |
2480 | case ARIZONA_DSP3_STATUS_2: | 2522 | case ARIZONA_DSP3_STATUS_2: |
2481 | case ARIZONA_DSP3_STATUS_3: | 2523 | case ARIZONA_DSP3_STATUS_3: |
2524 | case ARIZONA_DSP3_STATUS_4: | ||
2525 | case ARIZONA_DSP3_WDMA_BUFFER_1: | ||
2526 | case ARIZONA_DSP3_WDMA_BUFFER_2: | ||
2527 | case ARIZONA_DSP3_WDMA_BUFFER_3: | ||
2528 | case ARIZONA_DSP3_WDMA_BUFFER_4: | ||
2529 | case ARIZONA_DSP3_WDMA_BUFFER_5: | ||
2530 | case ARIZONA_DSP3_WDMA_BUFFER_6: | ||
2531 | case ARIZONA_DSP3_WDMA_BUFFER_7: | ||
2532 | case ARIZONA_DSP3_WDMA_BUFFER_8: | ||
2533 | case ARIZONA_DSP3_RDMA_BUFFER_1: | ||
2534 | case ARIZONA_DSP3_RDMA_BUFFER_2: | ||
2535 | case ARIZONA_DSP3_RDMA_BUFFER_3: | ||
2536 | case ARIZONA_DSP3_RDMA_BUFFER_4: | ||
2537 | case ARIZONA_DSP3_RDMA_BUFFER_5: | ||
2538 | case ARIZONA_DSP3_RDMA_BUFFER_6: | ||
2539 | case ARIZONA_DSP3_WDMA_CONFIG_1: | ||
2540 | case ARIZONA_DSP3_WDMA_CONFIG_2: | ||
2541 | case ARIZONA_DSP3_WDMA_OFFSET_1: | ||
2542 | case ARIZONA_DSP3_RDMA_CONFIG_1: | ||
2543 | case ARIZONA_DSP3_RDMA_OFFSET_1: | ||
2544 | case ARIZONA_DSP3_EXTERNAL_START_SELECT_1: | ||
2482 | case ARIZONA_DSP3_SCRATCH_0: | 2545 | case ARIZONA_DSP3_SCRATCH_0: |
2483 | case ARIZONA_DSP3_SCRATCH_1: | 2546 | case ARIZONA_DSP3_SCRATCH_1: |
2484 | case ARIZONA_DSP3_SCRATCH_2: | 2547 | case ARIZONA_DSP3_SCRATCH_2: |
@@ -2488,6 +2551,27 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg) | |||
2488 | case ARIZONA_DSP4_STATUS_1: | 2551 | case ARIZONA_DSP4_STATUS_1: |
2489 | case ARIZONA_DSP4_STATUS_2: | 2552 | case ARIZONA_DSP4_STATUS_2: |
2490 | case ARIZONA_DSP4_STATUS_3: | 2553 | case ARIZONA_DSP4_STATUS_3: |
2554 | case ARIZONA_DSP4_STATUS_4: | ||
2555 | case ARIZONA_DSP4_WDMA_BUFFER_1: | ||
2556 | case ARIZONA_DSP4_WDMA_BUFFER_2: | ||
2557 | case ARIZONA_DSP4_WDMA_BUFFER_3: | ||
2558 | case ARIZONA_DSP4_WDMA_BUFFER_4: | ||
2559 | case ARIZONA_DSP4_WDMA_BUFFER_5: | ||
2560 | case ARIZONA_DSP4_WDMA_BUFFER_6: | ||
2561 | case ARIZONA_DSP4_WDMA_BUFFER_7: | ||
2562 | case ARIZONA_DSP4_WDMA_BUFFER_8: | ||
2563 | case ARIZONA_DSP4_RDMA_BUFFER_1: | ||
2564 | case ARIZONA_DSP4_RDMA_BUFFER_2: | ||
2565 | case ARIZONA_DSP4_RDMA_BUFFER_3: | ||
2566 | case ARIZONA_DSP4_RDMA_BUFFER_4: | ||
2567 | case ARIZONA_DSP4_RDMA_BUFFER_5: | ||
2568 | case ARIZONA_DSP4_RDMA_BUFFER_6: | ||
2569 | case ARIZONA_DSP4_WDMA_CONFIG_1: | ||
2570 | case ARIZONA_DSP4_WDMA_CONFIG_2: | ||
2571 | case ARIZONA_DSP4_WDMA_OFFSET_1: | ||
2572 | case ARIZONA_DSP4_RDMA_CONFIG_1: | ||
2573 | case ARIZONA_DSP4_RDMA_OFFSET_1: | ||
2574 | case ARIZONA_DSP4_EXTERNAL_START_SELECT_1: | ||
2491 | case ARIZONA_DSP4_SCRATCH_0: | 2575 | case ARIZONA_DSP4_SCRATCH_0: |
2492 | case ARIZONA_DSP4_SCRATCH_1: | 2576 | case ARIZONA_DSP4_SCRATCH_1: |
2493 | case ARIZONA_DSP4_SCRATCH_2: | 2577 | case ARIZONA_DSP4_SCRATCH_2: |
@@ -2543,31 +2627,119 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg) | |||
2543 | case ARIZONA_DSP1_STATUS_1: | 2627 | case ARIZONA_DSP1_STATUS_1: |
2544 | case ARIZONA_DSP1_STATUS_2: | 2628 | case ARIZONA_DSP1_STATUS_2: |
2545 | case ARIZONA_DSP1_STATUS_3: | 2629 | case ARIZONA_DSP1_STATUS_3: |
2630 | case ARIZONA_DSP1_STATUS_4: | ||
2631 | case ARIZONA_DSP1_WDMA_BUFFER_1: | ||
2632 | case ARIZONA_DSP1_WDMA_BUFFER_2: | ||
2633 | case ARIZONA_DSP1_WDMA_BUFFER_3: | ||
2634 | case ARIZONA_DSP1_WDMA_BUFFER_4: | ||
2635 | case ARIZONA_DSP1_WDMA_BUFFER_5: | ||
2636 | case ARIZONA_DSP1_WDMA_BUFFER_6: | ||
2637 | case ARIZONA_DSP1_WDMA_BUFFER_7: | ||
2638 | case ARIZONA_DSP1_WDMA_BUFFER_8: | ||
2639 | case ARIZONA_DSP1_RDMA_BUFFER_1: | ||
2640 | case ARIZONA_DSP1_RDMA_BUFFER_2: | ||
2641 | case ARIZONA_DSP1_RDMA_BUFFER_3: | ||
2642 | case ARIZONA_DSP1_RDMA_BUFFER_4: | ||
2643 | case ARIZONA_DSP1_RDMA_BUFFER_5: | ||
2644 | case ARIZONA_DSP1_RDMA_BUFFER_6: | ||
2645 | case ARIZONA_DSP1_WDMA_CONFIG_1: | ||
2646 | case ARIZONA_DSP1_WDMA_CONFIG_2: | ||
2647 | case ARIZONA_DSP1_WDMA_OFFSET_1: | ||
2648 | case ARIZONA_DSP1_RDMA_CONFIG_1: | ||
2649 | case ARIZONA_DSP1_RDMA_OFFSET_1: | ||
2650 | case ARIZONA_DSP1_EXTERNAL_START_SELECT_1: | ||
2546 | case ARIZONA_DSP1_SCRATCH_0: | 2651 | case ARIZONA_DSP1_SCRATCH_0: |
2547 | case ARIZONA_DSP1_SCRATCH_1: | 2652 | case ARIZONA_DSP1_SCRATCH_1: |
2548 | case ARIZONA_DSP1_SCRATCH_2: | 2653 | case ARIZONA_DSP1_SCRATCH_2: |
2549 | case ARIZONA_DSP1_SCRATCH_3: | 2654 | case ARIZONA_DSP1_SCRATCH_3: |
2655 | case ARIZONA_DSP1_CLOCKING_1: | ||
2550 | case ARIZONA_DSP2_STATUS_1: | 2656 | case ARIZONA_DSP2_STATUS_1: |
2551 | case ARIZONA_DSP2_STATUS_2: | 2657 | case ARIZONA_DSP2_STATUS_2: |
2552 | case ARIZONA_DSP2_STATUS_3: | 2658 | case ARIZONA_DSP2_STATUS_3: |
2659 | case ARIZONA_DSP2_STATUS_4: | ||
2660 | case ARIZONA_DSP2_WDMA_BUFFER_1: | ||
2661 | case ARIZONA_DSP2_WDMA_BUFFER_2: | ||
2662 | case ARIZONA_DSP2_WDMA_BUFFER_3: | ||
2663 | case ARIZONA_DSP2_WDMA_BUFFER_4: | ||
2664 | case ARIZONA_DSP2_WDMA_BUFFER_5: | ||
2665 | case ARIZONA_DSP2_WDMA_BUFFER_6: | ||
2666 | case ARIZONA_DSP2_WDMA_BUFFER_7: | ||
2667 | case ARIZONA_DSP2_WDMA_BUFFER_8: | ||
2668 | case ARIZONA_DSP2_RDMA_BUFFER_1: | ||
2669 | case ARIZONA_DSP2_RDMA_BUFFER_2: | ||
2670 | case ARIZONA_DSP2_RDMA_BUFFER_3: | ||
2671 | case ARIZONA_DSP2_RDMA_BUFFER_4: | ||
2672 | case ARIZONA_DSP2_RDMA_BUFFER_5: | ||
2673 | case ARIZONA_DSP2_RDMA_BUFFER_6: | ||
2674 | case ARIZONA_DSP2_WDMA_CONFIG_1: | ||
2675 | case ARIZONA_DSP2_WDMA_CONFIG_2: | ||
2676 | case ARIZONA_DSP2_WDMA_OFFSET_1: | ||
2677 | case ARIZONA_DSP2_RDMA_CONFIG_1: | ||
2678 | case ARIZONA_DSP2_RDMA_OFFSET_1: | ||
2679 | case ARIZONA_DSP2_EXTERNAL_START_SELECT_1: | ||
2553 | case ARIZONA_DSP2_SCRATCH_0: | 2680 | case ARIZONA_DSP2_SCRATCH_0: |
2554 | case ARIZONA_DSP2_SCRATCH_1: | 2681 | case ARIZONA_DSP2_SCRATCH_1: |
2555 | case ARIZONA_DSP2_SCRATCH_2: | 2682 | case ARIZONA_DSP2_SCRATCH_2: |
2556 | case ARIZONA_DSP2_SCRATCH_3: | 2683 | case ARIZONA_DSP2_SCRATCH_3: |
2684 | case ARIZONA_DSP2_CLOCKING_1: | ||
2557 | case ARIZONA_DSP3_STATUS_1: | 2685 | case ARIZONA_DSP3_STATUS_1: |
2558 | case ARIZONA_DSP3_STATUS_2: | 2686 | case ARIZONA_DSP3_STATUS_2: |
2559 | case ARIZONA_DSP3_STATUS_3: | 2687 | case ARIZONA_DSP3_STATUS_3: |
2688 | case ARIZONA_DSP3_STATUS_4: | ||
2689 | case ARIZONA_DSP3_WDMA_BUFFER_1: | ||
2690 | case ARIZONA_DSP3_WDMA_BUFFER_2: | ||
2691 | case ARIZONA_DSP3_WDMA_BUFFER_3: | ||
2692 | case ARIZONA_DSP3_WDMA_BUFFER_4: | ||
2693 | case ARIZONA_DSP3_WDMA_BUFFER_5: | ||
2694 | case ARIZONA_DSP3_WDMA_BUFFER_6: | ||
2695 | case ARIZONA_DSP3_WDMA_BUFFER_7: | ||
2696 | case ARIZONA_DSP3_WDMA_BUFFER_8: | ||
2697 | case ARIZONA_DSP3_RDMA_BUFFER_1: | ||
2698 | case ARIZONA_DSP3_RDMA_BUFFER_2: | ||
2699 | case ARIZONA_DSP3_RDMA_BUFFER_3: | ||
2700 | case ARIZONA_DSP3_RDMA_BUFFER_4: | ||
2701 | case ARIZONA_DSP3_RDMA_BUFFER_5: | ||
2702 | case ARIZONA_DSP3_RDMA_BUFFER_6: | ||
2703 | case ARIZONA_DSP3_WDMA_CONFIG_1: | ||
2704 | case ARIZONA_DSP3_WDMA_CONFIG_2: | ||
2705 | case ARIZONA_DSP3_WDMA_OFFSET_1: | ||
2706 | case ARIZONA_DSP3_RDMA_CONFIG_1: | ||
2707 | case ARIZONA_DSP3_RDMA_OFFSET_1: | ||
2708 | case ARIZONA_DSP3_EXTERNAL_START_SELECT_1: | ||
2560 | case ARIZONA_DSP3_SCRATCH_0: | 2709 | case ARIZONA_DSP3_SCRATCH_0: |
2561 | case ARIZONA_DSP3_SCRATCH_1: | 2710 | case ARIZONA_DSP3_SCRATCH_1: |
2562 | case ARIZONA_DSP3_SCRATCH_2: | 2711 | case ARIZONA_DSP3_SCRATCH_2: |
2563 | case ARIZONA_DSP3_SCRATCH_3: | 2712 | case ARIZONA_DSP3_SCRATCH_3: |
2713 | case ARIZONA_DSP3_CLOCKING_1: | ||
2564 | case ARIZONA_DSP4_STATUS_1: | 2714 | case ARIZONA_DSP4_STATUS_1: |
2565 | case ARIZONA_DSP4_STATUS_2: | 2715 | case ARIZONA_DSP4_STATUS_2: |
2566 | case ARIZONA_DSP4_STATUS_3: | 2716 | case ARIZONA_DSP4_STATUS_3: |
2717 | case ARIZONA_DSP4_STATUS_4: | ||
2718 | case ARIZONA_DSP4_WDMA_BUFFER_1: | ||
2719 | case ARIZONA_DSP4_WDMA_BUFFER_2: | ||
2720 | case ARIZONA_DSP4_WDMA_BUFFER_3: | ||
2721 | case ARIZONA_DSP4_WDMA_BUFFER_4: | ||
2722 | case ARIZONA_DSP4_WDMA_BUFFER_5: | ||
2723 | case ARIZONA_DSP4_WDMA_BUFFER_6: | ||
2724 | case ARIZONA_DSP4_WDMA_BUFFER_7: | ||
2725 | case ARIZONA_DSP4_WDMA_BUFFER_8: | ||
2726 | case ARIZONA_DSP4_RDMA_BUFFER_1: | ||
2727 | case ARIZONA_DSP4_RDMA_BUFFER_2: | ||
2728 | case ARIZONA_DSP4_RDMA_BUFFER_3: | ||
2729 | case ARIZONA_DSP4_RDMA_BUFFER_4: | ||
2730 | case ARIZONA_DSP4_RDMA_BUFFER_5: | ||
2731 | case ARIZONA_DSP4_RDMA_BUFFER_6: | ||
2732 | case ARIZONA_DSP4_WDMA_CONFIG_1: | ||
2733 | case ARIZONA_DSP4_WDMA_CONFIG_2: | ||
2734 | case ARIZONA_DSP4_WDMA_OFFSET_1: | ||
2735 | case ARIZONA_DSP4_RDMA_CONFIG_1: | ||
2736 | case ARIZONA_DSP4_RDMA_OFFSET_1: | ||
2737 | case ARIZONA_DSP4_EXTERNAL_START_SELECT_1: | ||
2567 | case ARIZONA_DSP4_SCRATCH_0: | 2738 | case ARIZONA_DSP4_SCRATCH_0: |
2568 | case ARIZONA_DSP4_SCRATCH_1: | 2739 | case ARIZONA_DSP4_SCRATCH_1: |
2569 | case ARIZONA_DSP4_SCRATCH_2: | 2740 | case ARIZONA_DSP4_SCRATCH_2: |
2570 | case ARIZONA_DSP4_SCRATCH_3: | 2741 | case ARIZONA_DSP4_SCRATCH_3: |
2742 | case ARIZONA_DSP4_CLOCKING_1: | ||
2571 | return true; | 2743 | return true; |
2572 | default: | 2744 | default: |
2573 | return wm5110_is_adsp_memory(dev, reg); | 2745 | return wm5110_is_adsp_memory(dev, reg); |
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 7c1ae24605d9..4ab527f5c53b 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
19 | #include <linux/bug.h> | 18 | #include <linux/bug.h> |
20 | #include <linux/device.h> | 19 | #include <linux/device.h> |
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index 624ff90501cd..cd01f7962dfd 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
@@ -14,7 +14,6 @@ | |||
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | ||
18 | #include <linux/bug.h> | 17 | #include <linux/bug.h> |
19 | #include <linux/device.h> | 18 | #include <linux/device.h> |
20 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index d66d256551fb..e5eae751aa1b 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -161,31 +161,19 @@ static int wm8400_i2c_probe(struct i2c_client *i2c, | |||
161 | const struct i2c_device_id *id) | 161 | const struct i2c_device_id *id) |
162 | { | 162 | { |
163 | struct wm8400 *wm8400; | 163 | struct wm8400 *wm8400; |
164 | int ret; | ||
165 | 164 | ||
166 | wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL); | 165 | wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL); |
167 | if (wm8400 == NULL) { | 166 | if (!wm8400) |
168 | ret = -ENOMEM; | 167 | return -ENOMEM; |
169 | goto err; | ||
170 | } | ||
171 | 168 | ||
172 | wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config); | 169 | wm8400->regmap = devm_regmap_init_i2c(i2c, &wm8400_regmap_config); |
173 | if (IS_ERR(wm8400->regmap)) { | 170 | if (IS_ERR(wm8400->regmap)) |
174 | ret = PTR_ERR(wm8400->regmap); | 171 | return PTR_ERR(wm8400->regmap); |
175 | goto err; | ||
176 | } | ||
177 | 172 | ||
178 | wm8400->dev = &i2c->dev; | 173 | wm8400->dev = &i2c->dev; |
179 | i2c_set_clientdata(i2c, wm8400); | 174 | i2c_set_clientdata(i2c, wm8400); |
180 | 175 | ||
181 | ret = wm8400_init(wm8400, dev_get_platdata(&i2c->dev)); | 176 | return wm8400_init(wm8400, dev_get_platdata(&i2c->dev)); |
182 | if (ret != 0) | ||
183 | goto err; | ||
184 | |||
185 | return 0; | ||
186 | |||
187 | err: | ||
188 | return ret; | ||
189 | } | 177 | } |
190 | 178 | ||
191 | static int wm8400_i2c_remove(struct i2c_client *i2c) | 179 | static int wm8400_i2c_remove(struct i2c_client *i2c) |