summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-23 19:37:49 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-23 19:37:49 -0700
commit4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc (patch)
tree531c3121c4d1502c98d5a18903bac50b6d5be1b3
parentd0b3cfee333eb7eecb6ce72f06f5a02d249b9bdf (diff)
parent8391c6cb2414d9a75bbe247a838d28cb0cee77ee (diff)
downloadlinux-4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc.tar.gz
linux-4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc.tar.bz2
linux-4c07e2ddab5b6b57dbcb09aedbda1f484d5940cc.zip
Merge tag 'mfd-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "New Drivers: - Add support for Merrifield Basin Cove PMIC New Device Support: - Add support for Intel Tiger Lake to Intel LPSS PCI - Add support for Intel Sky Lake to Intel LPSS PCI - Add support for ST-Ericsson DB8520 to DB8500 PRCMU New Functionality: - Add RTC and PWRC support to MT6323 Fix-ups: - Clean-up include files; davinci_voicecodec, asic3, sm501, mt6397 - Ignore return values from debugfs_create*(); ab3100-*, ab8500-debugfs, aat2870-core - Device Tree changes; rn5t618, mt6397 - Use new I2C API; tps80031, 88pm860x-core, ab3100-core, bcm590xx, da9150-core, max14577, max77693, max77843, max8907, max8925-i2c, max8997, max8998, palmas, twl-core, - Remove obsolete code; da9063, jz4740-adc - Simplify semantics; timberdale, htc-i2cpld - Add 'fall-through' tags; omap-usb-host, db8500-prcmu - Remove superfluous prints; ab8500-debugfs, db8500-prcmu, fsl-imx25-tsadc, intel_soc_pmic_bxtwc, qcom_rpm, sm501 - Trivial rename/whitespace/typo fixes; mt6397-core, MAINTAINERS - Reorganise code structure; mt6397-* - Improve code consistency; intel-lpss - Use MODULE_SOFTDEP() helper; intel-lpss - Use DEFINE_RES_*() helpers; mt6397-core Bug Fixes: - Clean-up resources; max77620 - Prevent input events being dropped on resume; intel-lpss-pci - Prevent sleeping in IRQ context; ezx-pcap" * tag 'mfd-next-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (48 commits) mfd: mt6323: Add MT6323 RTC and PWRC mfd: mt6323: Replace boilerplate resource code with DEFINE_RES_* macros mfd: mt6397: Add mutex include dt-bindings: mfd: mediatek: Add MT6323 Power Controller dt-bindings: mfd: mediatek: Update RTC to include MT6323 dt-bindings: mfd: mediatek: mt6397: Change to relative paths mfd: db8500-prcmu: Support the higher DB8520 ARMSS mfd: intel-lpss: Use MODULE_SOFTDEP() instead of implicit request mfd: htc-i2cpld: Drop check because i2c_unregister_device() is NULL safe mfd: sm501: Include the GPIO driver header mfd: intel-lpss: Add Intel Skylake ACPI IDs mfd: intel-lpss: Consistently use GENMASK() mfd: Add support for Merrifield Basin Cove PMIC mfd: ezx-pcap: Replace mutex_lock with spin_lock mfd: asic3: Include the right header MAINTAINERS: altera-sysmgr: Fix typo in a filepath mfd: mt6397: Extract IRQ related code from core driver mfd: mt6397: Rename macros to something more readable mfd: Remove dev_err() usage after platform_get_irq() mfd: db8500-prcmu: Mark expected switch fall-throughs ...
-rw-r--r--Documentation/devicetree/bindings/mfd/mt6397.txt20
-rw-r--r--Documentation/devicetree/bindings/mfd/rn5t618.txt5
-rw-r--r--Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt20
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/mfd/88pm800.c12
-rw-r--r--drivers/mfd/88pm860x-core.c6
-rw-r--r--drivers/mfd/Kconfig20
-rw-r--r--drivers/mfd/Makefile5
-rw-r--r--drivers/mfd/ab3100-core.c6
-rw-r--r--drivers/mfd/ab8500-debugfs.c8
-rw-r--r--drivers/mfd/asic3.c2
-rw-r--r--drivers/mfd/bcm590xx.c6
-rw-r--r--drivers/mfd/da9150-core.c6
-rw-r--r--drivers/mfd/davinci_voicecodec.c9
-rw-r--r--drivers/mfd/db8500-prcmu.c44
-rw-r--r--drivers/mfd/ezx-pcap.c53
-rw-r--r--drivers/mfd/fsl-imx25-tsadc.c4
-rw-r--r--drivers/mfd/htc-i2cpld.c3
-rw-r--r--drivers/mfd/intel-lpss-acpi.c26
-rw-r--r--drivers/mfd/intel-lpss-pci.c25
-rw-r--r--drivers/mfd/intel-lpss.c39
-rw-r--r--drivers/mfd/intel_soc_pmic_bxtwc.c4
-rw-r--r--drivers/mfd/intel_soc_pmic_mrfld.c157
-rw-r--r--drivers/mfd/jz4740-adc.c324
-rw-r--r--drivers/mfd/max14577.c6
-rw-r--r--drivers/mfd/max77620.c4
-rw-r--r--drivers/mfd/max77693.c12
-rw-r--r--drivers/mfd/max77843.c6
-rw-r--r--drivers/mfd/max8907.c6
-rw-r--r--drivers/mfd/max8925-i2c.c12
-rw-r--r--drivers/mfd/max8997.c18
-rw-r--r--drivers/mfd/max8998.c6
-rw-r--r--drivers/mfd/mt6397-core.c192
-rw-r--r--drivers/mfd/mt6397-irq.c181
-rw-r--r--drivers/mfd/palmas.c6
-rw-r--r--drivers/mfd/qcom_rpm.c12
-rw-r--r--drivers/mfd/sm501.c5
-rw-r--r--drivers/mfd/timberdale.c3
-rw-r--r--drivers/mfd/tps80031.c23
-rw-r--r--drivers/mfd/twl-core.c6
-rw-r--r--include/Kbuild1
-rw-r--r--include/linux/mfd/da9063/pdata.h60
-rw-r--r--include/linux/mfd/intel_soc_pmic_mrfld.h81
-rw-r--r--include/linux/mfd/mt6397/core.h11
-rw-r--r--include/linux/platform_data/cros_ec_commands.h12
45 files changed, 742 insertions, 727 deletions
diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt
index 0ebd08af777d..a9b105ac00a8 100644
--- a/Documentation/devicetree/bindings/mfd/mt6397.txt
+++ b/Documentation/devicetree/bindings/mfd/mt6397.txt
@@ -8,11 +8,12 @@ MT6397/MT6323 is a multifunction device with the following sub modules:
- Clock
- LED
- Keys
+- Power controller
It is interfaced to host controller using SPI interface by a proprietary hardware
called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap.
See the following for pwarp node definitions:
-Documentation/devicetree/bindings/soc/mediatek/pwrap.txt
+../soc/mediatek/pwrap.txt
This document describes the binding for MFD device and its sub module.
@@ -22,14 +23,16 @@ compatible: "mediatek,mt6397" or "mediatek,mt6323"
Optional subnodes:
- rtc
- Required properties:
+ Required properties: Should be one of follows
+ - compatible: "mediatek,mt6323-rtc"
- compatible: "mediatek,mt6397-rtc"
+ For details, see ../rtc/rtc-mt6397.txt
- regulators
Required properties:
- compatible: "mediatek,mt6397-regulator"
- see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
+ see ../regulator/mt6397-regulator.txt
- compatible: "mediatek,mt6323-regulator"
- see Documentation/devicetree/bindings/regulator/mt6323-regulator.txt
+ see ../regulator/mt6323-regulator.txt
- codec
Required properties:
- compatible: "mediatek,mt6397-codec"
@@ -39,12 +42,17 @@ Optional subnodes:
- led
Required properties:
- compatible: "mediatek,mt6323-led"
- see Documentation/devicetree/bindings/leds/leds-mt6323.txt
+ see ../leds/leds-mt6323.txt
- keys
Required properties:
- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
- see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
+ see ../input/mtk-pmic-keys.txt
+
+- power-controller
+ Required properties:
+ - compatible: "mediatek,mt6323-pwrc"
+ For details, see ../power/reset/mt6323-poweroff.txt
Example:
pwrap: pwrap@1000f000 {
diff --git a/Documentation/devicetree/bindings/mfd/rn5t618.txt b/Documentation/devicetree/bindings/mfd/rn5t618.txt
index 65c23263cc54..b74e5e94d1cb 100644
--- a/Documentation/devicetree/bindings/mfd/rn5t618.txt
+++ b/Documentation/devicetree/bindings/mfd/rn5t618.txt
@@ -14,6 +14,10 @@ Required properties:
"ricoh,rc5t619"
- reg: the I2C slave address of the device
+Optional properties:
+ - system-power-controller:
+ See Documentation/devicetree/bindings/power/power-controller.txt
+
Sub-nodes:
- regulators: the node is required if the regulator functionality is
needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4
@@ -28,6 +32,7 @@ Example:
pmic@32 {
compatible = "ricoh,rn5t618";
reg = <0x32>;
+ system-power-controller;
regulators {
DCDC1 {
diff --git a/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
new file mode 100644
index 000000000000..933f0c48e887
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/reset/mt6323-poweroff.txt
@@ -0,0 +1,20 @@
+Device Tree Bindings for Power Controller on MediaTek PMIC
+
+The power controller which could be found on PMIC is responsible for externally
+powering off or on the remote MediaTek SoC through the circuit BBPU.
+
+Required properties:
+- compatible: Should be one of follows
+ "mediatek,mt6323-pwrc": for MT6323 PMIC
+
+Example:
+
+ pmic {
+ compatible = "mediatek,mt6323";
+
+ ...
+
+ power-controller {
+ compatible = "mediatek,mt6323-pwrc";
+ };
+ }
diff --git a/MAINTAINERS b/MAINTAINERS
index 1360243a7ff3..54f1286087e9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -728,7 +728,7 @@ ALTERA SYSTEM MANAGER DRIVER
M: Thor Thayer <thor.thayer@linux.intel.com>
S: Maintained
F: drivers/mfd/altera-sysmgr.c
-F: include/linux/mfd/altera-sysgmr.h
+F: include/linux/mfd/altera-sysmgr.h
ALTERA SYSTEM RESOURCE DRIVER FOR ARRIA10 DEVKIT
M: Thor Thayer <thor.thayer@linux.intel.com>
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c
index f2d9fb4c4e8e..4e8d0d6b9b5c 100644
--- a/drivers/mfd/88pm800.c
+++ b/drivers/mfd/88pm800.c
@@ -425,10 +425,10 @@ static int pm800_pages_init(struct pm80x_chip *chip)
return -ENODEV;
/* PM800 block power page */
- subchip->power_page = i2c_new_dummy(client->adapter,
+ subchip->power_page = i2c_new_dummy_device(client->adapter,
subchip->power_page_addr);
- if (subchip->power_page == NULL) {
- ret = -ENODEV;
+ if (IS_ERR(subchip->power_page)) {
+ ret = PTR_ERR(subchip->power_page);
goto out;
}
@@ -444,10 +444,10 @@ static int pm800_pages_init(struct pm80x_chip *chip)
i2c_set_clientdata(subchip->power_page, chip);
/* PM800 block GPADC */
- subchip->gpadc_page = i2c_new_dummy(client->adapter,
+ subchip->gpadc_page = i2c_new_dummy_device(client->adapter,
subchip->gpadc_page_addr);
- if (subchip->gpadc_page == NULL) {
- ret = -ENODEV;
+ if (IS_ERR(subchip->gpadc_page)) {
+ ret = PTR_ERR(subchip->gpadc_page);
goto out;
}
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 9e0bd135730f..c9bae71f643a 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -1178,12 +1178,12 @@ static int pm860x_probe(struct i2c_client *client)
*/
if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
chip->companion_addr = pdata->companion_addr;
- chip->companion = i2c_new_dummy(chip->client->adapter,
+ chip->companion = i2c_new_dummy_device(chip->client->adapter,
chip->companion_addr);
- if (!chip->companion) {
+ if (IS_ERR(chip->companion)) {
dev_err(&client->dev,
"Failed to allocate I2C companion device\n");
- return -ENODEV;
+ return PTR_ERR(chip->companion);
}
chip->regmap_companion = regmap_init_i2c(chip->companion,
&pm860x_regmap_config);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c9c49da42446..ae24d3ea68ea 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -589,6 +589,17 @@ config INTEL_SOC_PMIC_CHTDC_TI
Select this option for supporting Dollar Cove (TI version) PMIC
device that is found on some Intel Cherry Trail systems.
+config INTEL_SOC_PMIC_MRFLD
+ tristate "Support for Intel Merrifield Basin Cove PMIC"
+ depends on GPIOLIB
+ depends on ACPI
+ depends on INTEL_SCU_IPC
+ select MFD_CORE
+ select REGMAP_IRQ
+ help
+ Select this option for supporting Basin Cove PMIC device
+ that is found on Intel Merrifield systems.
+
config MFD_INTEL_LPSS
tristate
select COMMON_CLK
@@ -641,15 +652,6 @@ config MFD_JANZ_CMODIO
host many different types of MODULbus daughterboards, including
CAN and GPIO controllers.
-config MFD_JZ4740_ADC
- bool "Janz JZ4740 ADC core"
- select MFD_CORE
- select GENERIC_IRQ_CHIP
- depends on MACH_JZ4740
- help
- Say yes here if you want support for the ADC unit in the JZ4740 SoC.
- This driver is necessary for jz4740-battery and jz4740-hwmon driver.
-
config MFD_KEMPLD
tristate "Kontron module PLD device"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 0c0a848e62df..c1067ea46204 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -189,7 +189,6 @@ obj-$(CONFIG_LPC_SCH) += lpc_sch.o
obj-$(CONFIG_LPC_ICH) += lpc_ich.o
obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
-obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o
obj-$(CONFIG_MFD_TPS6586X) += tps6586x.o
obj-$(CONFIG_MFD_VX855) += vx855.o
obj-$(CONFIG_MFD_WL1273_CORE) += wl1273-core.o
@@ -239,7 +238,9 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o
-obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
+mt6397-objs := mt6397-core.o mt6397-irq.o
+obj-$(CONFIG_MFD_MT6397) += mt6397.o
+obj-$(CONFIG_INTEL_SOC_PMIC_MRFLD) += intel_soc_pmic_mrfld.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 9f3dbc31d3e9..57723f116bb5 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -865,10 +865,10 @@ static int ab3100_probe(struct i2c_client *client,
&ab3100->chip_name[0]);
/* Attach a second dummy i2c_client to the test register address */
- ab3100->testreg_client = i2c_new_dummy(client->adapter,
+ ab3100->testreg_client = i2c_new_dummy_device(client->adapter,
client->addr + 1);
- if (!ab3100->testreg_client) {
- err = -ENOMEM;
+ if (IS_ERR(ab3100->testreg_client)) {
+ err = PTR_ERR(ab3100->testreg_client);
goto exit_no_testreg_client;
}
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 567a34b073dd..f4e26b6e5362 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -2680,16 +2680,12 @@ static int ab8500_debug_probe(struct platform_device *plf)
irq_ab8500 = res->start;
irq_first = platform_get_irq_byname(plf, "IRQ_FIRST");
- if (irq_first < 0) {
- dev_err(&plf->dev, "First irq not found, err %d\n", irq_first);
+ if (irq_first < 0)
return irq_first;
- }
irq_last = platform_get_irq_byname(plf, "IRQ_LAST");
- if (irq_last < 0) {
- dev_err(&plf->dev, "Last irq not found, err %d\n", irq_last);
+ if (irq_last < 0)
return irq_last;
- }
ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL);
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index 83b18c998d6f..a6bd2134cea2 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -15,7 +15,7 @@
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/slab.h>
diff --git a/drivers/mfd/bcm590xx.c b/drivers/mfd/bcm590xx.c
index 1aeb5e498d91..bfac5dc091ca 100644
--- a/drivers/mfd/bcm590xx.c
+++ b/drivers/mfd/bcm590xx.c
@@ -61,11 +61,11 @@ static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
}
/* Secondary I2C slave address is the base address with A(2) asserted */
- bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter,
+ bcm590xx->i2c_sec = i2c_new_dummy_device(i2c_pri->adapter,
i2c_pri->addr | BIT(2));
- if (!bcm590xx->i2c_sec) {
+ if (IS_ERR(bcm590xx->i2c_sec)) {
dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n");
- return -ENODEV;
+ return PTR_ERR(bcm590xx->i2c_sec);
}
i2c_set_clientdata(bcm590xx->i2c_sec, bcm590xx);
diff --git a/drivers/mfd/da9150-core.c b/drivers/mfd/da9150-core.c
index 13033068721a..7f0aa1e8db96 100644
--- a/drivers/mfd/da9150-core.c
+++ b/drivers/mfd/da9150-core.c
@@ -420,10 +420,10 @@ static int da9150_probe(struct i2c_client *client,
qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A);
qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1;
qif_addr |= DA9150_QIF_I2C_ADDR_LSB;
- da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr);
- if (!da9150->core_qif) {
+ da9150->core_qif = i2c_new_dummy_device(client->adapter, qif_addr);
+ if (IS_ERR(da9150->core_qif)) {
dev_err(da9150->dev, "Failed to attach QIF client\n");
- return -ENODEV;
+ return PTR_ERR(da9150->core_qif);
}
i2c_set_clientdata(da9150->core_qif, da9150);
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
index 13ca7203e193..e5c8bc998eb4 100644
--- a/drivers/mfd/davinci_voicecodec.c
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -19,7 +19,6 @@
#include <sound/pcm.h>
#include <linux/mfd/davinci_voicecodec.h>
-#include <mach/hardware.h>
static const struct regmap_config davinci_vc_regmap = {
.reg_bits = 32,
@@ -31,6 +30,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
struct davinci_vc *davinci_vc;
struct resource *res;
struct mfd_cell *cell = NULL;
+ dma_addr_t fifo_base;
int ret;
davinci_vc = devm_kzalloc(&pdev->dev,
@@ -48,6 +48,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ fifo_base = (dma_addr_t)res->start;
davinci_vc->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(davinci_vc->base)) {
ret = PTR_ERR(davinci_vc->base);
@@ -70,8 +71,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
}
davinci_vc->davinci_vcif.dma_tx_channel = res->start;
- davinci_vc->davinci_vcif.dma_tx_addr =
- (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO);
+ davinci_vc->davinci_vcif.dma_tx_addr = fifo_base + DAVINCI_VC_WFIFO;
res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
if (!res) {
@@ -81,8 +81,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
}
davinci_vc->davinci_vcif.dma_rx_channel = res->start;
- davinci_vc->davinci_vcif.dma_rx_addr =
- (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO);
+ davinci_vc->davinci_vcif.dma_rx_addr = fifo_base + DAVINCI_VC_RFIFO;
davinci_vc->dev = &pdev->dev;
davinci_vc->pdev = pdev;
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 90e0f21bc49c..0e019cc5da42 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -1695,21 +1695,41 @@ static long round_clock_rate(u8 clock, unsigned long rate)
return rounded_rate;
}
-static const unsigned long armss_freqs[] = {
+static const unsigned long db8500_armss_freqs[] = {
200000000,
400000000,
800000000,
998400000
};
+/* The DB8520 has slightly higher ARMSS max frequency */
+static const unsigned long db8520_armss_freqs[] = {
+ 200000000,
+ 400000000,
+ 800000000,
+ 1152000000
+};
+
+
+
static long round_armss_rate(unsigned long rate)
{
unsigned long freq = 0;
+ const unsigned long *freqs;
+ int nfreqs;
int i;
+ if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) {
+ freqs = db8520_armss_freqs;
+ nfreqs = ARRAY_SIZE(db8520_armss_freqs);
+ } else {
+ freqs = db8500_armss_freqs;
+ nfreqs = ARRAY_SIZE(db8500_armss_freqs);
+ }
+
/* Find the corresponding arm opp from the cpufreq table. */
- for (i = 0; i < ARRAY_SIZE(armss_freqs); i++) {
- freq = armss_freqs[i];
+ for (i = 0; i < nfreqs; i++) {
+ freq = freqs[i];
if (rate <= freq)
break;
}
@@ -1854,11 +1874,21 @@ static int set_armss_rate(unsigned long rate)
{
unsigned long freq;
u8 opps[] = { ARM_EXTCLK, ARM_50_OPP, ARM_100_OPP, ARM_MAX_OPP };
+ const unsigned long *freqs;
+ int nfreqs;
int i;
+ if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) {
+ freqs = db8520_armss_freqs;
+ nfreqs = ARRAY_SIZE(db8520_armss_freqs);
+ } else {
+ freqs = db8500_armss_freqs;
+ nfreqs = ARRAY_SIZE(db8500_armss_freqs);
+ }
+
/* Find the corresponding arm opp from the cpufreq table. */
- for (i = 0; i < ARRAY_SIZE(armss_freqs); i++) {
- freq = armss_freqs[i];
+ for (i = 0; i < nfreqs; i++) {
+ freq = freqs[i];
if (rate == freq)
break;
}
@@ -3130,10 +3160,8 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
irq = platform_get_irq(pdev, 0);
- if (irq <= 0) {
- dev_err(&pdev->dev, "no prcmu irq provided\n");
+ if (irq <= 0)
return irq;
- }
err = request_threaded_irq(irq, prcmu_irq_handler,
prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL);
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c
index f505e3e1274b..70fa18b04ad2 100644
--- a/drivers/mfd/ezx-pcap.c
+++ b/drivers/mfd/ezx-pcap.c
@@ -35,7 +35,7 @@ struct pcap_chip {
/* IO */
u32 buf;
- struct mutex io_mutex;
+ spinlock_t io_lock;
/* IRQ */
unsigned int irq_base;
@@ -48,7 +48,7 @@ struct pcap_chip {
struct pcap_adc_request *adc_queue[PCAP_ADC_MAXQ];
u8 adc_head;
u8 adc_tail;
- struct mutex adc_mutex;
+ spinlock_t adc_lock;
};
/* IO */
@@ -76,14 +76,15 @@ static int ezx_pcap_putget(struct pcap_chip *pcap, u32 *data)
int ezx_pcap_write(struct pcap_chip *pcap, u8 reg_num, u32 value)
{
+ unsigned long flags;
int ret;
- mutex_lock(&pcap->io_mutex);
+ spin_lock_irqsave(&pcap->io_lock, flags);
value &= PCAP_REGISTER_VALUE_MASK;
value |= PCAP_REGISTER_WRITE_OP_BIT
| (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
ret = ezx_pcap_putget(pcap, &value);
- mutex_unlock(&pcap->io_mutex);
+ spin_unlock_irqrestore(&pcap->io_lock, flags);
return ret;
}
@@ -91,14 +92,15 @@ EXPORT_SYMBOL_GPL(ezx_pcap_write);
int ezx_pcap_read(struct pcap_chip *pcap, u8 reg_num, u32 *value)
{
+ unsigned long flags;
int ret;
- mutex_lock(&pcap->io_mutex);
+ spin_lock_irqsave(&pcap->io_lock, flags);
*value = PCAP_REGISTER_READ_OP_BIT
| (reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
ret = ezx_pcap_putget(pcap, value);
- mutex_unlock(&pcap->io_mutex);
+ spin_unlock_irqrestore(&pcap->io_lock, flags);
return ret;
}
@@ -106,11 +108,12 @@ EXPORT_SYMBOL_GPL(ezx_pcap_read);
int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
{
+ unsigned long flags;
int ret;
u32 tmp = PCAP_REGISTER_READ_OP_BIT |
(reg_num << PCAP_REGISTER_ADDRESS_SHIFT);
- mutex_lock(&pcap->io_mutex);
+ spin_lock_irqsave(&pcap->io_lock, flags);
ret = ezx_pcap_putget(pcap, &tmp);
if (ret)
goto out_unlock;
@@ -121,7 +124,7 @@ int ezx_pcap_set_bits(struct pcap_chip *pcap, u8 reg_num, u32 mask, u32 val)
ret = ezx_pcap_putget(pcap, &tmp);
out_unlock:
- mutex_unlock(&pcap->io_mutex);
+ spin_unlock_irqrestore(&pcap->io_lock, flags);
return ret;
}
@@ -212,14 +215,15 @@ static void pcap_irq_handler(struct irq_desc *desc)
/* ADC */
void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
{
+ unsigned long flags;
u32 tmp;
- mutex_lock(&pcap->adc_mutex);
+ spin_lock_irqsave(&pcap->adc_lock, flags);
ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
- mutex_unlock(&pcap->adc_mutex);
+ spin_unlock_irqrestore(&pcap->adc_lock, flags);
}
EXPORT_SYMBOL_GPL(pcap_set_ts_bits);
@@ -234,15 +238,16 @@ static void pcap_disable_adc(struct pcap_chip *pcap)
static void pcap_adc_trigger(struct pcap_chip *pcap)
{
+ unsigned long flags;
u32 tmp;
u8 head;
- mutex_lock(&pcap->adc_mutex);
+ spin_lock_irqsave(&pcap->adc_lock, flags);
head = pcap->adc_head;
if (!pcap->adc_queue[head]) {
/* queue is empty, save power */
pcap_disable_adc(pcap);
- mutex_unlock(&pcap->adc_mutex);
+ spin_unlock_irqrestore(&pcap->adc_lock, flags);
return;
}
/* start conversion on requested bank, save TS_M bits */
@@ -254,7 +259,7 @@ static void pcap_adc_trigger(struct pcap_chip *pcap)
tmp |= PCAP_ADC_AD_SEL1;
ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
- mutex_unlock(&pcap->adc_mutex);
+ spin_unlock_irqrestore(&pcap->adc_lock, flags);
ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
}
@@ -265,11 +270,11 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
u16 res[2];
u32 tmp;
- mutex_lock(&pcap->adc_mutex);
+ spin_lock(&pcap->adc_lock);
req = pcap->adc_queue[pcap->adc_head];
if (WARN(!req, "adc irq without pending request\n")) {
- mutex_unlock(&pcap->adc_mutex);
+ spin_unlock(&pcap->adc_lock);
return IRQ_HANDLED;
}
@@ -285,7 +290,7 @@ static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
pcap->adc_queue[pcap->adc_head] = NULL;
pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
- mutex_unlock(&pcap->adc_mutex);
+ spin_unlock(&pcap->adc_lock);
/* pass the results and release memory */
req->callback(req->data, res);
@@ -301,6 +306,7 @@ int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[],
void *callback, void *data)
{
struct pcap_adc_request *req;
+ unsigned long irq_flags;
/* This will be freed after we have a result *