summaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-24 20:00:58 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-24 20:00:58 -0800
commitab7826595e9ec51a51f622c5fc91e2f59440481a (patch)
tree34241b399fa7a12c260e06e6c1c31bc69d46e1e3 /drivers/mfd
parent21fbd5809ad126b949206d78e0a0e07ec872ea11 (diff)
parentff7109fa632654eaef657186f2942f5b679023d6 (diff)
Merge tag 'mfd-3.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
Pull MFS updates from Samuel Ortiz: "This is the MFD pull request for the 3.9 merge window. No new drivers this time, but a bunch of fairly big cleanups: - Roger Quadros worked on a OMAP USBHS and TLL platform data consolidation, OMAP5 support and clock management code cleanup. - The first step of a major sync for the ab8500 driver from Lee Jones. In particular, the debugfs and the sysct interfaces got extended and improved. - Peter Ujfalusi sent a nice patchset for cleaning and fixing the twl-core driver, with a much needed module id lookup code improvement. - The regular wm5102 and arizona cleanups and fixes from Mark Brown. - Laxman Dewangan extended the palmas APIs in order to implement the palmas GPIO and rt drivers. - Laxman also added DT support for the tps65090 driver. - The Intel SCH and ICH drivers got a couple fixes from Aaron Sierra and Darren Hart. - Linus Walleij patchset for the ab8500 driver allowed ab8500 and ab9540 based devices to switch to the new abx500 pin-ctrl driver. - The max8925 now has device tree and irqdomain support thanks to Qing Xu. - The recently added rtsx driver got a few cleanups and fixes for a better card detection code path and now also supports the RTS5227 chipset, thanks to Wei Wang and Roger Tseng." * tag 'mfd-3.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (109 commits) mfd: lpc_ich: Use devres API to allocate private data mfd: lpc_ich: Add Device IDs for Intel Wellsburg PCH mfd: lpc_sch: Accomodate partial population of the MFD devices mfd: da9052-i2c: Staticize da9052_i2c_fix() mfd: syscon: Fix sparse warning mfd: twl-core: Fix kernel panic on boot mfd: rtsx: Fix issue that booting OS with SD card inserted mfd: ab8500: Fix compile error mfd: Add missing GENERIC_HARDIRQS dependecies Documentation: Add docs for max8925 dt mfd: max8925: Add dts mfd: max8925: Support dt for backlight mfd: max8925: Fix onkey driver irq base mfd: max8925: Fix mfd device register failure mfd: max8925: Add irqdomain for dt mfd: vexpress: Allow vexpress-sysreg to self-initialise mfd: rtsx: Support RTS5227 mfd: rtsx: Implement driving adjustment to device-dependent callbacks mfd: vexpress: Add pseudo-GPIO based LEDs mfd: ab8500: Rename ab8500 to abx500 for hwmon driver ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/88pm800.c10
-rw-r--r--drivers/mfd/88pm805.c4
-rw-r--r--drivers/mfd/88pm80x.c22
-rw-r--r--drivers/mfd/Kconfig72
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/ab8500-core.c61
-rw-r--r--drivers/mfd/ab8500-debugfs.c1248
-rw-r--r--drivers/mfd/ab8500-gpadc.c90
-rw-r--r--drivers/mfd/ab8500-sysctrl.c92
-rw-r--r--drivers/mfd/abx500-core.c16
-rw-r--r--drivers/mfd/arizona-core.c55
-rw-r--r--drivers/mfd/da9052-i2c.c3
-rw-r--r--drivers/mfd/db8500-prcmu.c17
-rw-r--r--drivers/mfd/lpc_ich.c144
-rw-r--r--drivers/mfd/lpc_sch.c147
-rw-r--r--drivers/mfd/max8925-core.c89
-rw-r--r--drivers/mfd/max8925-i2c.c36
-rw-r--r--drivers/mfd/omap-usb-host.c558
-rw-r--r--drivers/mfd/omap-usb-tll.c243
-rw-r--r--drivers/mfd/palmas.c14
-rw-r--r--drivers/mfd/rtl8411.c16
-rw-r--r--drivers/mfd/rts5209.c8
-rw-r--r--drivers/mfd/rts5227.c234
-rw-r--r--drivers/mfd/rts5229.c8
-rw-r--r--drivers/mfd/rtsx_pcr.c98
-rw-r--r--drivers/mfd/rtsx_pcr.h4
-rw-r--r--drivers/mfd/syscon.c1
-rw-r--r--drivers/mfd/tps6507x.c9
-rw-r--r--drivers/mfd/tps65090.c47
-rw-r--r--drivers/mfd/twl-core.c370
-rw-r--r--drivers/mfd/vexpress-sysreg.c83
-rw-r--r--drivers/mfd/wm5102-tables.c130
-rw-r--r--drivers/mfd/wm8994-core.c7
33 files changed, 2941 insertions, 997 deletions
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index 391e23e6a647..582bda543520 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -531,7 +531,7 @@ static int pm800_probe(struct i2c_client *client,
ret = device_800_init(chip, pdata);
if (ret) {
dev_err(chip->dev, "%s id 0x%x failed!\n", __func__, chip->id);
- goto err_800_init;
+ goto err_subchip_alloc;
}
ret = pm800_pages_init(chip);
@@ -546,10 +546,8 @@ static int pm800_probe(struct i2c_client *client,
err_page_init:
mfd_remove_devices(chip->dev);
device_irq_exit_800(chip);
-err_800_init:
- devm_kfree(&client->dev, subchip);
err_subchip_alloc:
- pm80x_deinit(client);
+ pm80x_deinit();
out_init:
return ret;
}
@@ -562,9 +560,7 @@ static int pm800_remove(struct i2c_client *client)
device_irq_exit_800(chip);
pm800_pages_exit(chip);
- devm_kfree(&client->dev, chip->subchip);
-
- pm80x_deinit(client);
+ pm80x_deinit();
return 0;
}
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c
index e671230be2b1..65d7ac099b20 100644
--- a/drivers/mfd/88pm805.c
+++ b/drivers/mfd/88pm805.c
@@ -257,7 +257,7 @@ static int pm805_probe(struct i2c_client *client,
pdata->plat_config(chip, pdata);
err_805_init:
- pm80x_deinit(client);
+ pm80x_deinit();
out_init:
return ret;
}
@@ -269,7 +269,7 @@ static int pm805_remove(struct i2c_client *client)
mfd_remove_devices(chip->dev);
device_irq_exit_805(chip);
- pm80x_deinit(client);
+ pm80x_deinit();
return 0;
}
diff --git a/drivers/mfd/88pm80x.c b/drivers/mfd/88pm80x.c
index 1adb355d86d1..f736a46eb8c0 100644
--- a/drivers/mfd/88pm80x.c
+++ b/drivers/mfd/88pm80x.c
@@ -48,14 +48,12 @@ int pm80x_init(struct i2c_client *client,
ret = PTR_ERR(map);
dev_err(&client->dev, "Failed to allocate register map: %d\n",
ret);
- goto err_regmap_init;
+ return ret;
}
chip->id = id->driver_data;
- if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805) {
- ret = -EINVAL;
- goto err_chip_id;
- }
+ if (chip->id < CHIP_PM800 || chip->id > CHIP_PM805)
+ return -EINVAL;
chip->client = client;
chip->regmap = map;
@@ -82,19 +80,11 @@ int pm80x_init(struct i2c_client *client,
}
return 0;
-
-err_chip_id:
- regmap_exit(map);
-err_regmap_init:
- devm_kfree(&client->dev, chip);
- return ret;
}
EXPORT_SYMBOL_GPL(pm80x_init);
-int pm80x_deinit(struct i2c_client *client)
+int pm80x_deinit(void)
{
- struct pm80x_chip *chip = i2c_get_clientdata(client);
-
/*
* workaround: clear the dependency between pm800 and pm805.
* would remove it after HW chip fixes the issue.
@@ -103,10 +93,6 @@ int pm80x_deinit(struct i2c_client *client)
g_pm80x_chip->companion = NULL;
else
g_pm80x_chip = NULL;
-
- regmap_exit(chip->regmap);
- devm_kfree(&client->dev, chip);
-
return 0;
}
EXPORT_SYMBOL_GPL(pm80x_deinit);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ff553babf455..671f5b171c73 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -65,7 +65,7 @@ config MFD_SM501_GPIO
config MFD_RTSX_PCI
tristate "Support for Realtek PCI-E card reader"
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
select MFD_CORE
help
This supports for Realtek PCI-Express card reader including rts5209,
@@ -95,7 +95,7 @@ config MFD_DM355EVM_MSP
config MFD_TI_SSP
tristate "TI Sequencer Serial Port support"
- depends on ARCH_DAVINCI_TNETV107X
+ depends on ARCH_DAVINCI_TNETV107X && GENERIC_HARDIRQS
select MFD_CORE
---help---
Say Y here if you want support for the Sequencer Serial Port
@@ -109,6 +109,7 @@ config MFD_TI_AM335X_TSCADC
select MFD_CORE
select REGMAP
select REGMAP_MMIO
+ depends on GENERIC_HARDIRQS
help
If you say yes here you get support for Texas Instruments series
of Touch Screen /ADC chips.
@@ -126,6 +127,7 @@ config HTC_EGPIO
config HTC_PASIC3
tristate "HTC PASIC3 LED/DS1WM chip support"
select MFD_CORE
+ depends on GENERIC_HARDIRQS
help
This core driver provides register access for the LED/DS1WM
chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
@@ -157,6 +159,7 @@ config MFD_LM3533
depends on I2C
select MFD_CORE
select REGMAP_I2C
+ depends on GENERIC_HARDIRQS
help
Say yes here to enable support for National Semiconductor / TI
LM3533 Lighting Power chips.
@@ -171,6 +174,7 @@ config TPS6105X
select REGULATOR
select MFD_CORE
select REGULATOR_FIXED_VOLTAGE
+ depends on GENERIC_HARDIRQS
help
This option enables a driver for the TP61050/TPS61052
high-power "white LED driver". This boost converter is
@@ -193,7 +197,7 @@ config TPS65010
config TPS6507X
tristate "TPS6507x Power Management / Touch Screen chips"
select MFD_CORE
- depends on I2C
+ depends on I2C && GENERIC_HARDIRQS
help
If you say yes here you get support for the TPS6507x series of
Power Management / Touch Screen chips. These include voltage
@@ -204,7 +208,7 @@ config TPS6507X
config MFD_TPS65217
tristate "TPS65217 Power Management / White LED chips"
- depends on I2C
+ depends on I2C && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
help
@@ -234,7 +238,7 @@ config MFD_TPS6586X
config MFD_TPS65910
bool "TPS65910 Power Management chip"
- depends on I2C=y && GPIOLIB
+ depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -251,7 +255,7 @@ config MFD_TPS65912_I2C
bool "TPS65912 Power Management chip with I2C"
select MFD_CORE
select MFD_TPS65912
- depends on I2C=y && GPIOLIB
+ depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
help
If you say yes here you get support for the TPS65912 series of
PM chips with I2C interface.
@@ -260,7 +264,7 @@ config MFD_TPS65912_SPI
bool "TPS65912 Power Management chip with SPI"
select MFD_CORE
select MFD_TPS65912
- depends on SPI_MASTER && GPIOLIB
+ depends on SPI_MASTER && GPIOLIB && GENERIC_HARDIRQS
help
If you say yes here you get support for the TPS65912 series of
PM chips with SPI interface.
@@ -330,13 +334,13 @@ config TWL4030_POWER
config MFD_TWL4030_AUDIO
bool
- depends on TWL4030_CORE
+ depends on TWL4030_CORE && GENERIC_HARDIRQS
select MFD_CORE
default n
config TWL6040_CORE
bool "Support for TWL6040 audio codec"
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
@@ -405,7 +409,7 @@ config MFD_TMIO
config MFD_T7L66XB
bool "Support Toshiba T7L66XB"
- depends on ARM && HAVE_CLK
+ depends on ARM && HAVE_CLK && GENERIC_HARDIRQS
select MFD_CORE
select MFD_TMIO
help
@@ -413,7 +417,7 @@ config MFD_T7L66XB
config MFD_SMSC
bool "Support for the SMSC ECE1099 series chips"
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
help
@@ -460,7 +464,7 @@ config MFD_DA9052_SPI
select REGMAP_SPI
select REGMAP_IRQ
select PMIC_DA9052
- depends on SPI_MASTER=y
+ depends on SPI_MASTER=y && GENERIC_HARDIRQS
help
Support for the Dialog Semiconductor DA9052 PMIC
when controlled using SPI. This driver provides common support
@@ -472,7 +476,7 @@ config MFD_DA9052_I2C
select REGMAP_I2C
select REGMAP_IRQ
select PMIC_DA9052
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
help
Support for the Dialog Semiconductor DA9052 PMIC
when controlled using I2C. This driver provides common support
@@ -485,7 +489,7 @@ config MFD_DA9055
select REGMAP_IRQ
select PMIC_DA9055
select MFD_CORE
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
help
Say yes here for support of Dialog Semiconductor DA9055. This is
a Power Management IC. This driver provides common support for
@@ -508,7 +512,7 @@ config PMIC_ADP5520
config MFD_LP8788
bool "Texas Instruments LP8788 Power Management Unit Driver"
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
select IRQ_DOMAIN
@@ -611,7 +615,7 @@ config MFD_ARIZONA_I2C
select MFD_ARIZONA
select MFD_CORE
select REGMAP_I2C
- depends on I2C
+ depends on I2C && GENERIC_HARDIRQS
help
Support for the Wolfson Microelectronics Arizona platform audio SoC
core functionality controlled via I2C.
@@ -621,7 +625,7 @@ config MFD_ARIZONA_SPI
select MFD_ARIZONA
select MFD_CORE
select REGMAP_SPI
- depends on SPI_MASTER
+ depends on SPI_MASTER && GENERIC_HARDIRQS
help
Support for the Wolfson Microelectronics Arizona platform audio SoC
core functionality controlled via I2C.
@@ -641,7 +645,7 @@ config MFD_WM5110
config MFD_WM8400
bool "Support Wolfson Microelectronics WM8400"
select MFD_CORE
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
select REGMAP_I2C
help
Support for the Wolfson Microelecronics WM8400 PMIC and audio
@@ -785,7 +789,7 @@ config MFD_MC13783
config MFD_MC13XXX
tristate
- depends on SPI_MASTER || I2C
+ depends on (SPI_MASTER || I2C) && GENERIC_HARDIRQS
select MFD_CORE
select MFD_MC13783
help
@@ -796,7 +800,7 @@ config MFD_MC13XXX
config MFD_MC13XXX_SPI
tristate "Freescale MC13783 and MC13892 SPI interface"
- depends on SPI_MASTER
+ depends on SPI_MASTER && GENERIC_HARDIRQS
select REGMAP_SPI
select MFD_MC13XXX
help
@@ -804,7 +808,7 @@ config MFD_MC13XXX_SPI
config MFD_MC13XXX_I2C
tristate "Freescale MC13892 I2C interface"
- depends on I2C
+ depends on I2C && GENERIC_HARDIRQS
select REGMAP_I2C
select MFD_MC13XXX
help
@@ -822,7 +826,7 @@ config ABX500_CORE
config AB3100_CORE
bool "ST-Ericsson AB3100 Mixed Signal Circuit core functions"
- depends on I2C=y && ABX500_CORE
+ depends on I2C=y && ABX500_CORE && GENERIC_HARDIRQS
select MFD_CORE
default y if ARCH_U300
help
@@ -909,7 +913,7 @@ config MFD_TIMBERDALE
config LPC_SCH
tristate "Intel SCH LPC"
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
select MFD_CORE
help
LPC bridge function of the Intel SCH provides support for
@@ -917,7 +921,7 @@ config LPC_SCH
config LPC_ICH
tristate "Intel ICH LPC"
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
select MFD_CORE
help
The LPC bridge function of the Intel ICH provides support for
@@ -928,7 +932,7 @@ config LPC_ICH
config MFD_RDC321X
tristate "Support for RDC-R321x southbridge"
select MFD_CORE
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
help
Say yes here if you want to have support for the RDC R-321x SoC
southbridge which provides access to GPIOs and Watchdog using the
@@ -937,7 +941,7 @@ config MFD_RDC321X
config MFD_JANZ_CMODIO
tristate "Support for Janz CMOD-IO PCI MODULbus Carrier Board"
select MFD_CORE
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
help
This is the core driver for the Janz CMOD-IO PCI MODULbus
carrier board. This device is a PCI to MODULbus bridge which may
@@ -955,7 +959,7 @@ config MFD_JZ4740_ADC
config MFD_VX855
tristate "Support for VIA VX855/VX875 integrated south bridge"
- depends on PCI
+ depends on PCI && GENERIC_HARDIRQS
select MFD_CORE
help
Say yes here to enable support for various functions of the
@@ -964,7 +968,7 @@ config MFD_VX855
config MFD_WL1273_CORE
tristate "Support for TI WL1273 FM radio."
- depends on I2C
+ depends on I2C && GENERIC_HARDIRQS
select MFD_CORE
default n
help
@@ -1028,7 +1032,7 @@ config MFD_TPS65090
config MFD_AAT2870_CORE
bool "Support for the AnalogicTech AAT2870"
select MFD_CORE
- depends on I2C=y && GPIOLIB
+ depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
help
If you say yes here you get support for the AAT2870.
This driver provides common support for accessing the device,
@@ -1060,7 +1064,7 @@ config MFD_RC5T583
config MFD_STA2X11
bool "STA2X11 multi function device support"
- depends on STA2X11
+ depends on STA2X11 && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_MMIO
@@ -1077,7 +1081,7 @@ config MFD_PALMAS
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
help
If you say yes here you get support for the Palmas
series of PMIC chips from Texas Instruments.
@@ -1085,7 +1089,7 @@ config MFD_PALMAS
config MFD_VIPERBOARD
tristate "Support for Nano River Technologies Viperboard"
select MFD_CORE
- depends on USB
+ depends on USB && GENERIC_HARDIRQS
default n
help
Say yes here if you want support for Nano River Technologies
@@ -1099,7 +1103,7 @@ config MFD_VIPERBOARD
config MFD_RETU
tristate "Support for Retu multi-function device"
select MFD_CORE
- depends on I2C
+ depends on I2C && GENERIC_HARDIRQS
select REGMAP_IRQ
help
Retu is a multi-function device found on Nokia Internet Tablets
@@ -1110,7 +1114,7 @@ config MFD_AS3711
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
- depends on I2C=y
+ depends on I2C=y && GENERIC_HARDIRQS
help
Support for the AS3711 PMIC from AMS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8b977f8045ae..b90409c23664 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_MFD_88PM805) += 88pm805.o 88pm80x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
-rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o
+rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 8b5d685ab980..7c84ced2e01b 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -320,6 +320,7 @@ static struct abx500_ops ab8500_ops = {
.mask_and_set_register = ab8500_mask_and_set_register,
.event_registers_startup_state_get = NULL,
.startup_irq_enabled = NULL,
+ .dump_all_banks = ab8500_dump_all_banks,
};
static void ab8500_irq_lock(struct irq_data *data)
@@ -368,16 +369,48 @@ static void ab8500_irq_mask(struct irq_data *data)
int mask = 1 << (offset % 8);
ab8500->mask[index] |= mask;
+
+ /* The AB8500 GPIOs have two interrupts each (rising & falling). */
+ if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
+ ab8500->mask[index + 2] |= mask;
+ if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
+ ab8500->mask[index + 1] |= mask;
+ if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
+ /* Here the falling IRQ is one bit lower */
+ ab8500->mask[index] |= (mask << 1);
}
static void ab8500_irq_unmask(struct irq_data *data)
{
struct ab8500 *ab8500 = irq_data_get_irq_chip_data(data);
+ unsigned int type = irqd_get_trigger_type(data);
int offset = data->hwirq;
int index = offset / 8;
int mask = 1 << (offset % 8);
- ab8500->mask[index] &= ~mask;
+ if (type & IRQ_TYPE_EDGE_RISING)
+ ab8500->mask[index] &= ~mask;
+
+ /* The AB8500 GPIOs have two interrupts each (rising & falling). */
+ if (type & IRQ_TYPE_EDGE_FALLING) {
+ if (offset >= AB8500_INT_GPIO6R && offset <= AB8500_INT_GPIO41R)
+ ab8500->mask[index + 2] &= ~mask;
+ else if (offset >= AB9540_INT_GPIO50R && offset <= AB9540_INT_GPIO54R)
+ ab8500->mask[index + 1] &= ~mask;
+ else if (offset == AB8540_INT_GPIO43R || offset == AB8540_INT_GPIO44R)
+ /* Here the falling IRQ is one bit lower */
+ ab8500->mask[index] &= ~(mask << 1);
+ else
+ ab8500->mask[index] &= ~mask;
+ } else {
+ /* Satisfies the case where type is not set. */
+ ab8500->mask[index] &= ~mask;
+ }
+}
+
+static int ab8500_irq_set_type(struct irq_data *data, unsigned int type)
+{
+ return 0;
}
static struct irq_chip ab8500_irq_chip = {
@@ -387,6 +420,7 @@ static struct irq_chip ab8500_irq_chip = {
.irq_mask = ab8500_irq_mask,
.irq_disable = ab8500_irq_mask,
.irq_unmask = ab8500_irq_unmask,
+ .irq_set_type = ab8500_irq_set_type,
};
static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
@@ -411,6 +445,19 @@ static int ab8500_handle_hierarchical_line(struct ab8500 *ab8500,
line = (i << 3) + int_bit;
latch_val &= ~(1 << int_bit);
+ /*
+ * This handles the falling edge hwirqs from the GPIO
+ * lines. Route them back to the line registered for the
+ * rising IRQ, as this is merely a flag for the same IRQ
+ * in linux terms.
+ */
+ if (line >= AB8500_INT_GPIO6F && line <= AB8500_INT_GPIO41F)
+ line -= 16;
+ if (line >= AB9540_INT_GPIO50F && line <= AB9540_INT_GPIO54F)
+ line -= 8;
+ if (line == AB8540_INT_GPIO43F || line == AB8540_INT_GPIO44F)
+ line += 1;
+
handle_nested_irq(ab8500->irq_base + line);
} while (latch_val);
@@ -521,6 +568,7 @@ static irqreturn_t ab8500_irq(int irq, void *dev)
int virq = ab8500_irq_get_virq(ab8500, line);
handle_nested_irq(virq);
+ ab8500_debug_register_interrupt(line);
value &= ~(1 << bit);
} while (value);
@@ -929,7 +977,7 @@ static struct resource ab8505_iddet_resources[] = {
static struct resource ab8500_temp_resources[] = {
{
- .name = "AB8500_TEMP_WARM",
+ .name = "ABX500_TEMP_WARM",
.start = AB8500_INT_TEMP_WARM,
.end = AB8500_INT_TEMP_WARM,
.flags = IORESOURCE_IRQ,
@@ -1005,8 +1053,8 @@ static struct mfd_cell abx500_common_devs[] = {
.of_compatible = "stericsson,ab8500-denc",
},
{
- .name = "ab8500-temp",
- .of_compatible = "stericsson,ab8500-temp",
+ .name = "abx500-temp",
+ .of_compatible = "stericsson,abx500-temp",
.num_resources = ARRAY_SIZE(ab8500_temp_resources),
.resources = ab8500_temp_resources,
},
@@ -1049,7 +1097,7 @@ static struct mfd_cell ab8500_bm_devs[] = {
static struct mfd_cell ab8500_devs[] = {
{
- .name = "ab8500-gpio",
+ .name = "pinctrl-ab8500",
.of_compatible = "stericsson,ab8500-gpio",
},
{
@@ -1066,7 +1114,8 @@ static struct mfd_cell ab8500_devs[] = {
static struct mfd_cell ab9540_devs[] = {
{
- .name = "ab8500-gpio",
+ .name = "pinctrl-ab9540",
+ .of_compatible = "stericsson,ab9540-gpio",
},
{
.name = "ab9540-usb",
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 5a8e707bc038..45fe3c50eb03 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -4,6 +4,72 @@
* Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson.
* License Terms: GNU General Public License v2
*/
+/*
+ * AB8500 register access
+ * ======================
+ *
+ * read:
+ * # echo BANK > <debugfs>/ab8500/register-bank
+ * # echo ADDR > <debugfs>/ab8500/register-address
+ * # cat <debugfs>/ab8500/register-value
+ *
+ * write:
+ * # echo BANK > <debugfs>/ab8500/register-bank
+ * # echo ADDR > <debugfs>/ab8500/register-address
+ * # echo VALUE > <debugfs>/ab8500/register-value
+ *
+ * read all registers from a bank:
+ * # echo BANK > <debugfs>/ab8500/register-bank
+ * # cat <debugfs>/ab8500/all-bank-register
+ *
+ * BANK target AB8500 register bank
+ * ADDR target AB8500 register address
+ * VALUE decimal or 0x-prefixed hexadecimal
+ *
+ *
+ * User Space notification on AB8500 IRQ
+ * =====================================
+ *
+ * Allows user space entity to be notified when target AB8500 IRQ occurs.
+ * When subscribed, a sysfs entry is created in ab8500.i2c platform device.
+ * One can pool this file to get target IRQ occurence information.
+ *
+ * subscribe to an AB8500 IRQ:
+ * # echo IRQ > <debugfs>/ab8500/irq-subscribe
+ *
+ * unsubscribe from an AB8500 IRQ:
+ * # echo IRQ > <debugfs>/ab8500/irq-unsubscribe
+ *
+ *
+ * AB8500 register formated read/write access
+ * ==========================================
+ *
+ * Read: read data, data>>SHIFT, data&=MASK, output data
+ * [0xABCDEF98] shift=12 mask=0xFFF => 0x00000CDE
+ * Write: read data, data &= ~(MASK<<SHIFT), data |= (VALUE<<SHIFT), write data
+ * [0xABCDEF98] shift=12 mask=0xFFF value=0x123 => [0xAB123F98]
+ *
+ * Usage:
+ * # echo "CMD [OPTIONS] BANK ADRESS [VALUE]" > $debugfs/ab8500/hwreg
+ *
+ * CMD read read access
+ * write write access
+ *
+ * BANK target reg bank
+ * ADDRESS target reg address
+ * VALUE (write) value to be updated
+ *
+ * OPTIONS
+ * -d|-dec (read) output in decimal
+ * -h|-hexa (read) output in 0x-hexa (default)
+ * -l|-w|-b 32bit (default), 16bit or 8bit reg access
+ * -m|-mask MASK 0x-hexa mask (default 0xFFFFFFFF)
+ * -s|-shift SHIFT bit shift value (read:left, write:right)
+ * -o|-offset OFFSET address offset to add to ADDRESS value
+ *
+ * Warning: bit shift operation is applied to bit-mask.
+ * Warning: bit shift direction depends on read or right command.
+ */
#include <linux/seq_file.h>
#include <linux/uaccess.h>
@@ -11,13 +77,30 @@
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/kobject.h>
+#include <linux/slab.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-gpadc.h>
+
+#ifdef CONFIG_DEBUG_FS
+#include <linux/string.h>
+#include <linux/ctype.h>
+#endif
static u32 debug_bank;
static u32 debug_address;
+static int irq_first;
+static int irq_last;
+static u32 *irq_count;
+static int num_irqs;
+
+static struct device_attribute **dev_attr;
+static char **event_name;
+
/**
* struct ab8500_reg_range
* @first: the first address of the range
@@ -42,15 +125,35 @@ struct ab8500_prcmu_ranges {
const struct ab8500_reg_range *range;
};
+/* hwreg- "mask" and "shift" entries ressources */
+struct hwreg_cfg {
+ u32 bank; /* target bank */
+ u32 addr; /* target address */
+ uint fmt; /* format */
+ uint mask; /* read/write mask, applied before any bit shift */
+ int shift; /* bit shift (read:right shift, write:left shift */
+};
+/* fmt bit #0: 0=hexa, 1=dec */
+#define REG_FMT_DEC(c) ((c)->fmt & 0x1)
+#define REG_FMT_HEX(c) (!REG_FMT_DEC(c))
+
+static struct hwreg_cfg hwreg_cfg = {
+ .addr = 0, /* default: invalid phys addr */
+ .fmt = 0, /* default: 32bit access, hex output */
+ .mask = 0xFFFFFFFF, /* default: no mask */
+ .shift = 0, /* default: no bit shift */
+};
+
#define AB8500_NAME_STRING "ab8500"
-#define AB8500_NUM_BANKS 22
+#define AB8500_ADC_NAME_STRING "gpadc"
+#define AB8500_NUM_BANKS 24
#define AB8500_REV_REG 0x80
static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = {
[0x0] = {
.num_ranges = 0,
- .range = 0,
+ .range = NULL,
},
[AB8500_SYS_CTRL1_BLOCK] = {
.num_ranges = 3,
@@ -215,7 +318,7 @@ static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = {
},
},
[AB8500_CHARGER] = {
- .num_ranges = 8,
+ .num_ranges = 9,
.range = (struct ab8500_reg_range[]) {
{
.first = 0x00,
@@ -249,6 +352,10 @@ static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = {
.first = 0xC0,
.last = 0xC2,
},
+ {
+ .first = 0xf5,
+ .last = 0xf6,
+ },
},
},
[AB8500_GAS_GAUGE] = {
@@ -268,6 +375,24 @@ static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = {
},
},
},
+ [AB8500_DEVELOPMENT] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x00,
+ .last = 0x00,
+ },
+ },
+ },
+ [AB8500_DEBUG] = {
+ .num_ranges = 1,
+ .range = (struct ab8500_reg_range[]) {
+ {
+ .first = 0x05,
+ .last = 0x07,
+ },
+ },
+ },
[AB8500_AUDIO] = {
.num_ranges = 1,
.range = (struct ab8500_reg_range[]) {
@@ -354,15 +479,30 @@ static struct ab8500_prcmu_ranges debug_ranges[AB8500_NUM_BANKS] = {
},
};
-static int ab8500_registers_print(struct seq_file *s, void *p)
+static irqreturn_t ab8500_debug_handler(int irq, void *data)
{
- struct device *dev = s->private;
- unsigned int i;
- u32 bank = debug_bank;
+ char buf[16];
+ struct kobject *kobj = (struct kobject *)data;
+ unsigned int irq_abb = irq - irq_first;
- seq_printf(s, AB8500_NAME_STRING " register values:\n");