aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mfd/arizona.txt62
-rw-r--r--MAINTAINERS4
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/mfd/Kconfig5
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/arizona-core.c234
-rw-r--r--drivers/mfd/arizona-i2c.c10
-rw-r--r--drivers/mfd/arizona-spi.c10
-rw-r--r--drivers/mfd/arizona.h12
-rw-r--r--drivers/mfd/intel_msic.c1
-rw-r--r--drivers/mfd/jz4740-adc.c7
-rw-r--r--drivers/mfd/lpc_ich.c10
-rw-r--r--drivers/mfd/max77686.c1
-rw-r--r--drivers/mfd/mcp-sa11x0.c3
-rw-r--r--drivers/mfd/rtl8411.c132
-rw-r--r--drivers/mfd/rtsx_pcr.c5
-rw-r--r--drivers/mfd/rtsx_pcr.h1
-rw-r--r--drivers/mfd/sec-core.c3
-rw-r--r--drivers/mfd/ssbi.c (renamed from drivers/ssbi/ssbi.c)0
-rw-r--r--drivers/mfd/t7l66xb.c1
-rw-r--r--drivers/mfd/tc6387xb.c1
-rw-r--r--drivers/mfd/tc6393xb.c1
-rw-r--r--drivers/mfd/twl-core.c12
-rw-r--r--drivers/mfd/twl4030-audio.c5
-rw-r--r--drivers/mfd/twl4030-madc.c5
-rw-r--r--drivers/mfd/wm5110-tables.c8
-rw-r--r--drivers/mfd/wm8994-irq.c100
-rw-r--r--drivers/ssbi/Kconfig16
-rw-r--r--drivers/ssbi/Makefile1
-rw-r--r--include/linux/mfd/arizona/core.h2
-rw-r--r--include/linux/mfd/arizona/pdata.h2
-rw-r--r--include/linux/mfd/arizona/registers.h3
-rw-r--r--include/linux/mfd/rtsx_pci.h1
-rw-r--r--include/linux/mfd/wm8994/core.h2
-rw-r--r--include/linux/mfd/wm8994/pdata.h5
36 files changed, 571 insertions, 99 deletions
diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt
new file mode 100644
index 000000000000..0e295c9d8937
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -0,0 +1,62 @@
+Wolfson Arizona class audio SoCs
+
+These devices are audio SoCs with extensive digital capabilites and a range
+of analogue I/O.
+
+Required properties:
+
+ - compatible : one of the following chip-specific strings:
+ "wlf,wm5102"
+ "wlf,wm5110"
+ - reg : I2C slave address when connected using I2C, chip select number when
+ using SPI.
+
+ - interrupts : The interrupt line the /IRQ signal for the device is
+ connected to.
+ - interrupt-controller : Arizona class devices contain interrupt controllers
+ and may provide interrupt services to other devices.
+ - interrupt-parent : The parent interrupt controller.
+ - #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
+ The first cell is the IRQ number.
+ The second cell is the flags, encoded as the trigger masks from
+ Documentation/devicetree/bindings/interrupts.txt
+
+ - gpio-controller : Indicates this device is a GPIO controller.
+ - #gpio-cells : Must be 2. The first cell is the pin number and the
+ second cell is used to specify optional parameters (currently unused).
+
+ - AVDD1-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply, CPVDD-supply,
+ SPKVDDL-supply, SPKVDDR-supply : power supplies for the device, as covered
+ in Documentation/devicetree/bindings/regulator/regulator.txt
+
+Optional properties:
+
+ - wlf,reset : GPIO specifier for the GPIO controlling /RESET
+ - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
+
+ - wlf,gpio-defaults : A list of GPIO configuration register values. If
+ absent, no configuration of these registers is performed. If any
+ entry has a value that is out of range for a 16 bit register then
+ the chip default will be used. If present exactly five values must
+ be specified.
+
+Example:
+
+codec: wm5102@1a {
+ compatible = "wlf,wm5102";
+ reg = <0x1a>;
+ interrupts = <347>;
+ #interrupt-cells = <2>;
+ interrupt-parent = <&gic>;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ wlf,gpio-defaults = <
+ 0x00000000, /* AIF1TXLRCLK */
+ 0xffffffff,
+ 0xffffffff,
+ 0xffffffff,
+ 0xffffffff,
+ >;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 250dc970c62d..39fd4e794b1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5432,7 +5432,9 @@ F: include/media/mt9v032.h
MULTIFUNCTION DEVICES (MFD)
M: Samuel Ortiz <[email protected]>
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git
+M: Lee Jones <[email protected]>
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-next.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-fixes.git
S: Supported
F: drivers/mfd/
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 9953a42809ec..b8ec9cf1cfb2 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -52,8 +52,6 @@ source "drivers/i2c/Kconfig"
source "drivers/spi/Kconfig"
-source "drivers/ssbi/Kconfig"
-
source "drivers/hsi/Kconfig"
source "drivers/pps/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 130abc1dfd65..bbf3810d0d49 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -117,7 +117,6 @@ obj-y += firmware/
obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
obj-$(CONFIG_ARCH_SHMOBILE) += sh/
-obj-$(CONFIG_SSBI) += ssbi/
ifndef CONFIG_ARCH_USES_GETTIMEOFFSET
obj-y += clocksource/
endif
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index d54e985748b7..c6eb930fb54d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -53,7 +53,7 @@ config MFD_CROS_EC
help
If you say Y here you get support for the ChromeOS Embedded
Controller (EC) providing keyboard, battery and power services.
- You also ned to enable the driver for the bus you are using. The
+ You also need to enable the driver for the bus you are using. The
protocol for talking to the EC is defined by the bus driver.
config MFD_CROS_EC_I2C
@@ -419,7 +419,8 @@ config MFD_PM8XXX
config MFD_PM8921_CORE
tristate "Qualcomm PM8921 PMIC chip"
- depends on SSBI && BROKEN
+ depends on (ARCH_MSM || HEXAGON)
+ depends on BROKEN
select MFD_CORE
select MFD_PM8XXX
help
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 718e94a2a9a7..31d0f97d6e50 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -140,7 +140,7 @@ obj-$(CONFIG_MFD_SI476X_CORE) += si476x-core.o
obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o omap-usb-tll.o
-obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
+obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o ssbi.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 6ab03043fd60..74b4481754fd 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -16,9 +16,13 @@
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
#include <linux/slab.h>
#include <linux/mfd/arizona/core.h>
@@ -344,6 +348,17 @@ static int arizona_runtime_resume(struct device *dev)
switch (arizona->type) {
case WM5102:
+ if (arizona->external_dcvdd) {
+ ret = regmap_update_bits(arizona->regmap,
+ ARIZONA_ISOLATION_CONTROL,
+ ARIZONA_ISOLATE_DCVDD1, 0);
+ if (ret != 0) {
+ dev_err(arizona->dev,
+ "Failed to connect DCVDD: %d\n", ret);
+ goto err;
+ }
+ }
+
ret = wm5102_patch(arizona);
if (ret != 0) {
dev_err(arizona->dev, "Failed to apply patch: %d\n",
@@ -365,6 +380,28 @@ static int arizona_runtime_resume(struct device *dev)
goto err;
}
+ if (arizona->external_dcvdd) {
+ ret = regmap_update_bits(arizona->regmap,
+ ARIZONA_ISOLATION_CONTROL,
+ ARIZONA_ISOLATE_DCVDD1, 0);
+ if (ret != 0) {
+ dev_err(arizona->dev,
+ "Failed to connect DCVDD: %d\n", ret);
+ goto err;
+ }
+ }
+ break;
+ }
+
+ switch (arizona->type) {
+ case WM5102:
+ ret = wm5102_patch(arizona);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to apply patch: %d\n",
+ ret);
+ goto err;
+ }
+ default:
break;
}
@@ -385,9 +422,22 @@ err:
static int arizona_runtime_suspend(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
+ int ret;
dev_dbg(arizona->dev, "Entering AoD mode\n");
+ if (arizona->external_dcvdd) {
+ ret = regmap_update_bits(arizona->regmap,
+ ARIZONA_ISOLATION_CONTROL,
+ ARIZONA_ISOLATE_DCVDD1,
+ ARIZONA_ISOLATE_DCVDD1);
+ if (ret != 0) {
+ dev_err(arizona->dev, "Failed to isolate DCVDD: %d\n",
+ ret);
+ return ret;
+ }
+ }
+
regulator_disable(arizona->dcvdd);
regcache_cache_only(arizona->regmap, true);
regcache_mark_dirty(arizona->regmap);
@@ -397,6 +447,26 @@ static int arizona_runtime_suspend(struct device *dev)
#endif
#ifdef CONFIG_PM_SLEEP
+static int arizona_suspend(struct device *dev)
+{
+ struct arizona *arizona = dev_get_drvdata(dev);
+
+ dev_dbg(arizona->dev, "Suspend, disabling IRQ\n");
+ disable_irq(arizona->irq);
+
+ return 0;
+}
+
+static int arizona_suspend_late(struct device *dev)
+{
+ struct arizona *arizona = dev_get_drvdata(dev);
+
+ dev_dbg(arizona->dev, "Late suspend, reenabling IRQ\n");
+ enable_irq(arizona->irq);
+
+ return 0;
+}
+
static int arizona_resume_noirq(struct device *dev)
{
struct arizona *arizona = dev_get_drvdata(dev);
@@ -422,13 +492,78 @@ const struct dev_pm_ops arizona_pm_ops = {
SET_RUNTIME_PM_OPS(arizona_runtime_suspend,
arizona_runtime_resume,
NULL)
- SET_SYSTEM_SLEEP_PM_OPS(NULL, arizona_resume)
+ SET_SYSTEM_SLEEP_PM_OPS(arizona_suspend, arizona_resume)
#ifdef CONFIG_PM_SLEEP
+ .suspend_late = arizona_suspend_late,
.resume_noirq = arizona_resume_noirq,
#endif
};
EXPORT_SYMBOL_GPL(arizona_pm_ops);
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev)
+{
+ const struct of_device_id *id = of_match_device(arizona_of_match, dev);
+
+ if (id)
+ return (int)id->data;
+ else
+ return 0;
+}
+EXPORT_SYMBOL_GPL(arizona_of_get_type);
+
+static int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+ int ret, i;
+
+ arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
+ "wlf,reset", 0);
+ if (arizona->pdata.reset < 0)
+ arizona->pdata.reset = 0;
+
+ arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
+ "wlf,ldoena", 0);
+ if (arizona->pdata.ldoena < 0)
+ arizona->pdata.ldoena = 0;
+
+ ret = of_property_read_u32_array(arizona->dev->of_node,
+ "wlf,gpio-defaults",
+ arizona->pdata.gpio_defaults,
+ ARRAY_SIZE(arizona->pdata.gpio_defaults));
+ if (ret >= 0) {
+ /*
+ * All values are literal except out of range values
+ * which are chip default, translate into platform
+ * data which uses 0 as chip default and out of range
+ * as zero.
+ */
+ for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) {
+ if (arizona->pdata.gpio_defaults[i] > 0xffff)
+ arizona->pdata.gpio_defaults[i] = 0;
+ if (arizona->pdata.gpio_defaults[i] == 0)
+ arizona->pdata.gpio_defaults[i] = 0x10000;
+ }
+ } else {
+ dev_err(arizona->dev, "Failed to parse GPIO defaults: %d\n",
+ ret);
+ }
+
+ return 0;
+}
+
+const struct of_device_id arizona_of_match[] = {
+ { .compatible = "wlf,wm5102", .data = (void *)WM5102 },
+ { .compatible = "wlf,wm5110", .data = (void *)WM5110 },
+ {},
+};
+EXPORT_SYMBOL_GPL(arizona_of_match);
+#else
+static inline int arizona_of_get_core_pdata(struct arizona *arizona)
+{
+ return 0;
+}
+#endif
+
static struct mfd_cell early_devs[] = {
{ .name = "arizona-ldo1" },
};
@@ -462,6 +597,8 @@ int arizona_dev_init(struct arizona *arizona)
dev_set_drvdata(arizona->dev, arizona);
mutex_init(&arizona->clk_lock);
+ arizona_of_get_core_pdata(arizona);
+
if (dev_get_platdata(arizona->dev))
memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
sizeof(arizona->pdata));
@@ -536,51 +673,22 @@ int arizona_dev_init(struct arizona *arizona)
regcache_cache_only(arizona->regmap, false);
+ /* Verify that this is a chip we know about */
ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
if (ret != 0) {
dev_err(dev, "Failed to read ID register: %d\n", ret);
goto err_reset;
}
- ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
- &arizona->rev);
- if (ret != 0) {
- dev_err(dev, "Failed to read revision register: %d\n", ret);
- goto err_reset;
- }
- arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
-
switch (reg) {
-#ifdef CONFIG_MFD_WM5102
case 0x5102:
- type_name = "WM5102";
- if (arizona->type != WM5102) {
- dev_err(arizona->dev, "WM5102 registered as %d\n",
- arizona->type);
- arizona->type = WM5102;
- }
- apply_patch = wm5102_patch;
- arizona->rev &= 0x7;
- break;
-#endif
-#ifdef CONFIG_MFD_WM5110
case 0x5110:
- type_name = "WM5110";
- if (arizona->type != WM5110) {
- dev_err(arizona->dev, "WM5110 registered as %d\n",
- arizona->type);
- arizona->type = WM5110;
- }
- apply_patch = wm5110_patch;
break;
-#endif
default:
- dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+ dev_err(arizona->dev, "Unknown device ID: %x\n", reg);
goto err_reset;
}
- dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
-
/* If we have a /RESET GPIO we'll already be reset */
if (!arizona->pdata.reset) {
regcache_mark_dirty(arizona->regmap);
@@ -600,6 +708,7 @@ int arizona_dev_init(struct arizona *arizona)
}
}
+ /* Ensure device startup is complete */
switch (arizona->type) {
case WM5102:
ret = regmap_read(arizona->regmap, 0x19, &val);
@@ -620,6 +729,52 @@ int arizona_dev_init(struct arizona *arizona)
break;
}
+ /* Read the device ID information & do device specific stuff */
+ ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, &reg);
+ if (ret != 0) {
+ dev_err(dev, "Failed to read ID register: %d\n", ret);
+ goto err_reset;
+ }
+
+ ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION,
+ &arizona->rev);
+ if (ret != 0) {
+ dev_err(dev, "Failed to read revision register: %d\n", ret);
+ goto err_reset;
+ }
+ arizona->rev &= ARIZONA_DEVICE_REVISION_MASK;
+
+ switch (reg) {
+#ifdef CONFIG_MFD_WM5102
+ case 0x5102:
+ type_name = "WM5102";
+ if (arizona->type != WM5102) {
+ dev_err(arizona->dev, "WM5102 registered as %d\n",
+ arizona->type);
+ arizona->type = WM5102;
+ }
+ apply_patch = wm5102_patch;
+ arizona->rev &= 0x7;
+ break;
+#endif
+#ifdef CONFIG_MFD_WM5110
+ case 0x5110:
+ type_name = "WM5110";
+ if (arizona->type != WM5110) {
+ dev_err(arizona->dev, "WM5110 registered as %d\n",
+ arizona->type);
+ arizona->type = WM5110;
+ }
+ apply_patch = wm5110_patch;
+ break;
+#endif
+ default:
+ dev_err(arizona->dev, "Unknown device ID %x\n", reg);
+ goto err_reset;
+ }
+
+ dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A');
+
if (apply_patch) {
ret = apply_patch(arizona);
if (ret != 0) {
@@ -651,6 +806,14 @@ int arizona_dev_init(struct arizona *arizona)
arizona->pdata.gpio_defaults[i]);
}
+ /*
+ * LDO1 can only be used to supply DCVDD so if it has no
+ * consumers then DCVDD is supplied externally.
+ */
+ if (arizona->pdata.ldo1 &&
+ arizona->pdata.ldo1->num_consumer_supplies == 0)
+ arizona->external_dcvdd = true;
+
pm_runtime_set_autosuspend_delay(arizona->dev, 100);
pm_runtime_use_autosuspend(arizona->dev);
pm_runtime_enable(arizona->dev);
@@ -697,7 +860,7 @@ int arizona_dev_init(struct arizona *arizona)
if (arizona->pdata.micbias[i].discharge)
val |= ARIZONA_MICB1_DISCH;
- if (arizona->pdata.micbias[i].fast_start)
+ if (arizona->pdata.micbias[i].soft_start)
val |= ARIZONA_MICB1_RATE;
if (arizona->pdata.micbias[i].bypass)
@@ -809,6 +972,11 @@ int arizona_dev_exit(struct arizona *arizona)
arizona_free_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, arizona);
pm_runtime_disable(arizona->dev);
arizona_irq_exit(arizona);
+ if (arizona->pdata.reset)
+ gpio_set_value_cansleep(arizona->pdata.reset, 0);
+ regulator_disable(arizona->dcvdd);
+ regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies),
+ arizona->core_supplies);
return 0;
}
EXPORT_SYMBOL_GPL(arizona_dev_exit);
diff --git a/drivers/mfd/arizona-i2c.c b/drivers/mfd/arizona-i2c.c
index 44a1bb969841..deb267ebf84e 100644
--- a/drivers/mfd/arizona-i2c.c
+++ b/drivers/mfd/arizona-i2c.c
@@ -27,9 +27,14 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
{
struct arizona *arizona;
const struct regmap_config *regmap_config;
- int ret;
+ int ret, type;
- switch (id->driver_data) {
+ if (i2c->dev.of_node)
+ type = arizona_of_get_type(&i2c->dev);
+ else
+ type = id->driver_data;
+
+ switch (type) {
#ifdef CONFIG_MFD_WM5102
case WM5102:
regmap_config = &wm5102_i2c_regmap;
@@ -84,6 +89,7 @@ static struct i2c_driver arizona_i2c_driver = {
.name = "arizona",
.owner = THIS_MODULE,
.pm = &arizona_pm_ops,
+ .of_match_table = of_match_ptr(arizona_of_match),
},
.probe = arizona_i2c_probe,
.remove = arizona_i2c_remove,
diff --git a/drivers/mfd/arizona-spi.c b/drivers/mfd/arizona-spi.c
index b57e642d2b4a..47be7b35b5c5 100644
--- a/drivers/mfd/arizona-spi.c
+++ b/drivers/mfd/arizona-spi.c
@@ -27,9 +27,14 @@ static int arizona_spi_probe(struct spi_device *spi)
const struct spi_device_id *id = spi_get_device_id(spi);
struct arizona *arizona;
const struct regmap_config *regmap_config;
- int ret;
+ int ret, type;
- switch (id->driver_data) {
+ if (spi->dev.of_node)
+ type = arizona_of_get_type(&spi->dev);
+ else
+ type = id->driver_data;
+
+ switch (type) {
#ifdef CONFIG_MFD_WM5102
case WM5102:
regmap_config = &wm5102_spi_regmap;
@@ -84,6 +89,7 @@ static struct spi_driver arizona_spi_driver = {
.name = "arizona",
.owner = THIS_MODULE,
.pm = &arizona_pm_ops,
+ .of_match_table = of_match_ptr(arizona_of_match),
},
.probe = arizona_spi_probe,
.remove = arizona_spi_remove,
diff --git a/drivers/mfd/arizona.h b/drivers/mfd/arizona.h
index 9798ae5da67b..db55d9854a55 100644
--- a/drivers/mfd/arizona.h
+++ b/drivers/mfd/arizona.h
@@ -13,6 +13,7 @@
#ifndef _WM5102_H
#define _WM5102_H
+#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/pm.h>
@@ -26,6 +27,8 @@ extern const struct regmap_config wm5110_spi_regmap;
extern const struct dev_pm_ops arizona_pm_ops;
+extern const struct of_device_id arizona_of_match[];
+
extern const struct regmap_irq_chip wm5102_aod;
extern const struct regmap_irq_chip wm5102_irq;
@@ -37,4 +40,13 @@ int arizona_dev_exit(struct arizona *arizona);
int arizona_irq_init(struct arizona *arizona);
int arizona_irq_exit(struct arizona *arizona);
+#ifdef CONFIG_OF
+int arizona_of_get_type(struct device *dev);
+#else
+static inline int arizona_of_get_type(struct device *dev)
+{
+ return 0;
+}
+#endif
+
#endif
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c
index d8d5137f9717..4f2462f0963e 100644
--- a/drivers/mfd/intel_msic.c
+++ b/drivers/mfd/intel_msic.c
@@ -438,7 +438,6 @@ static int intel_msic_remove(struct platform_device *pdev)
struct intel_msic *msic = platform_get_drvdata(pdev);
intel_msic_remove_devices(msic);
- platform_set_drvdata(pdev, NULL);
return 0;
}
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index e80587f1a792..3c0e8cf6916b 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -86,13 +86,13 @@ static void jz4740_adc_irq_demux(unsigned int irq, struct irq_desc *desc)
static inline void jz4740_adc_clk_enable(struct jz4740_adc *adc)
{
if (atomic_inc_return(&adc->clk_ref) == 1)
- clk_enable(adc->clk);
+ clk_prepare_enable(adc->clk);
}
static inline void jz4740_adc_clk_disable(struct jz4740_adc *adc)
{
if (atomic_dec_return(&adc->clk_ref) == 0)
- clk_disable(adc->clk);
+ clk_disable_unprepare(adc->clk);
}
static inline void jz4740_adc_set_enabled(struct jz4740_adc *adc, int engine,
@@ -294,7 +294,6 @@ static int jz4740_adc_probe(struct platform_device *pdev)
err_clk_put:
clk_put(adc->clk);
err_iounmap:
- platform_set_drvdata(pdev, NULL);
iounmap(adc->base);
err_release_mem_region:
release_mem_region(adc->mem->start, resource_size(adc->mem));
@@ -317,8 +316,6 @@ static int jz4740_adc_remove(struct platform_device *pdev)
clk_put(adc->clk);
- platform_set_drvdata(pdev, NULL);
-
return 0;
}
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 9f12f91d6296..330cd44771be 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -51,6 +51,7 @@
* document number TBD : Lynx Point
* document number TBD : Lynx Point-LP
* document number TBD : Wellsburg
+ * document number TBD : Avoton SoC
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -207,6 +208,7 @@ enum lpc_chipsets {
LPC_LPT, /* Lynx Point */
LPC_LPT_LP, /* Lynx Point-LP */
LPC_WBG, /* Wellsburg */
+ LPC_AVN, /* Avoton SoC */
};
struct lpc_ich_info lpc_chipset_info[] = {
@@ -491,6 +493,10 @@ struct lpc_ich_info lpc_chipset_info[] = {
.name = "Wellsburg",
.iTCO_version = 2,
},
+ [LPC_AVN] = {
+ .name = "Avoton SoC",
+ .iTCO_version = 1,
+ },
};
/*
@@ -704,6 +710,10 @@ static DEFINE_PCI_DEVICE_TABLE(lpc_ich_ids) = {
{ PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG},
+ { PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN},
+ { PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
+ { PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
+ { PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c
index 1cbb17609c8b..5bd24670e1b6 100644
--- a/drivers/mfd/max77686.c
+++ b/drivers/mfd/max77686.c
@@ -37,6 +37,7 @@
static struct mfd_cell max77686_devs[] = {
{ .name = "max77686-pmic", },
{ .name = "max77686-rtc", },
+ { .name = "max77686-clk", },
};
static struct regmap_config max77686_regmap_config = {
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index f99d6299ec24..13198d937e36 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -225,8 +225,6 @@ static int mcp_sa11x0_probe(struct platform_device *dev)
if (ret == 0)
return 0;
- platform_set_drvdata(dev, NULL);
-
err_ioremap:
iounmap(m->base1);
iounmap(m->base0);
@@ -252,7 +250,6 @@ static int mcp_sa11x0_remove(struct platform_device *dev)
mem0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
mem1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
- platform_set_drvdata(dev, NULL);
mcp_host_del(mcp);
iounmap(m->base1);
iounmap(m->base0);
diff --git a/drivers/mfd/rtl8411.c b/drivers/mfd/rtl8411.c
index 2a2d31687b72..c436bf27e78d 100644
--- a/drivers/mfd/rtl8411.c
+++ b/drivers/mfd/rtl8411.c
@@ -35,12 +35,33 @@ static u8 rtl8411_get_ic_version(struct rtsx_pcr *pcr)
return val & 0x0F;
}
+static int rtl8411b_is_qfn48(struct rtsx_pcr *pcr)
+{
+ u8 val = 0;
+
+ rtsx_pci_read_register(pcr, RTL8411B_PACKAGE_MODE, &val);
+
+ if (val & 0x2)
+ return 1;
+ else
+ return 0;
+}
+
static int rtl8411_extra_init_hw(struct rtsx_pcr *pcr)
{
return rtsx_pci_write_register(pcr, CD_PAD_CTL,
CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
}
+static int rtl8411b_extra_init_hw(struct rtsx_pcr *pcr)
+{
+ if (rtl8411b_is_qfn48(pcr))
+ rtsx_pci_write_register(pcr, CARD_PULL_CTL3, 0xFF, 0xF5);
+
+ return rtsx_pci_write_register(pcr, CD_PAD_CTL,
+ CD_DISABLE_MASK | CD_AUTO_DISABLE, CD_ENABLE);
+}
+
static int rtl8411_turn_on_led(struct rtsx_pcr *pcr)
{
return rtsx_pci_write_register(pcr, CARD_GPIO, 0x01, 0x00);
@@ -214,6 +235,20 @@ static const struct pcr_ops rtl8411_pcr_ops = {
.conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
};
+static const struct pcr_ops rtl8411b_pcr_ops = {
+ .extra_init_hw = rtl8411b_extra_init_hw,
+ .optimize_phy = NULL,
+ .turn_on_led = rtl8411_turn_on_led,
+ .turn_off_led = rtl8411_turn_off_led,
+ .enable_auto_blink = rtl8411_enable_auto_blink,
+ .disable_auto_blink = rtl8411_disable_auto_blink,
+ .card_power_on = rtl8411_card_power_on,
+ .card_power_off = rtl8411_card_power_off,
+ .switch_output_voltage = rtl8411_switch_output_voltage,
+ .cd_deglitch = rtl8411_cd_deglitch,
+ .conv_clk_and_div_n = rtl8411_conv_clk_and_div_n,
+};
+
/* SD Pull Control Enable:
* SD_DAT[3:0] ==> pull up
* SD_CD ==> pull up
@@ -276,6 +311,74 @@ static const u32 rtl8411_ms_pull_ctl_disable_tbl[] = {
0,
};
+static const u32 rtl8411b_qfn64_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x09 | 0xD0),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn48_sd_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0xAA),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x69 | 0x90),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x08 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn64_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn48_sd_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn64_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x05 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn48_ms_pull_ctl_enable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn64_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL1, 0x65),
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x05 | 0xD0),
+ RTSX_REG_PAIR(CARD_PULL_CTL4, 0x09 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL5, 0x05 | 0x50),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
+static const u32 rtl8411b_qfn48_ms_pull_ctl_disable_tbl[] = {
+ RTSX_REG_PAIR(CARD_PULL_CTL2, 0x55),
+ RTSX_REG_PAIR(CARD_PULL_CTL3, 0x65 | 0x90),
+ RTSX_REG_PAIR(CARD_PULL_CTL6, 0x04 | 0x11),
+ 0,
+};
+
void rtl8411_init_params(struct rtsx_pcr *pcr)
{
pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
@@ -288,3 +391,32 @@ void rtl8411_init_params(struct rtsx_pcr *pcr)
pcr->ms_pull_ctl_enable_tbl = rtl8411_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rtl8411_ms_pull_ctl_disable_tbl;
}
+
+void rtl8411b_init_params(struct rtsx_pcr *pcr)
+{
+ pcr->extra_caps = EXTRA_CAPS_SD_SDR50 | EXTRA_CAPS_SD_SDR104;
+ pcr->num_slots = 2;
+ pcr->ops = &rtl8411b_pcr_ops;
+
+ pcr->ic_version = rtl8411_get_ic_version(pcr);
+
+ if (rtl8411b_is_qfn48(pcr)) {
+ pcr->sd_pull_ctl_enable_tbl =
+ rtl8411b_qfn48_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl =
+ rtl8411b_qfn48_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl =
+ rtl8411b_qfn48_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl =
+ rtl8411b_qfn48_ms_pull_ctl_disable_tbl;
+ } else {
+ pcr->sd_pull_ctl_enable_tbl =
+ rtl8411b_qfn64_sd_pull_ctl_enable_tbl;
+ pcr->sd_pull_ctl_disable_tbl =
+ rtl8411b_qfn64_sd_pull_ctl_disable_tbl;
+ pcr->ms_pull_ctl_enable_tbl =
+ rtl8411b_qfn64_ms_pull_ctl_enable_tbl;
+ pcr->ms_pull_ctl_disable_tbl =
+ rtl8411b_qfn64_ms_pull_ctl_disable_tbl;
+ }
+}
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index e968c01ca2ac..dd186c4103c1 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -57,6 +57,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtsx_pci_ids) = {
{ PCI_DEVICE(0x10EC, 0x5289), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5227), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 },
+ { PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ 0, }
};
@@ -1038,6 +1039,10 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
case 0x5249:
rts5249_init_params(pcr);
break;
+
+ case 0x5287:
+ rtl8411b_init_params(pcr);
+ break;
}
dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n",
diff --git a/drivers/mfd/rtsx_pcr.h b/drivers/mfd/rtsx_pcr.h
index 55fcfc25c4e4..c0cac7e8972f 100644
--- a/drivers/mfd/rtsx_pcr.h
+++ b/drivers/mfd/rtsx_pcr.h
@@ -33,5 +33,6 @@ void rts5229_init_params(struct rtsx_pcr *pcr);
void rtl8411_init_params(struct rtsx_pcr *pcr);
void rts5227_init_params(struct rtsx_pcr *pcr);
void rts5249_init_params(struct rtsx_pcr *pcr);
+void rtl8411b_init_params(struct rtsx_pcr *pcr);
#endif
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c
index 77ee26ef5941..cc896d1c1cdd 100644
--- a/drivers/mfd/sec-core.c
+++ b/drivers/mfd/sec-core.c
@@ -230,13 +230,12 @@ static int sec_pmic_probe(struct i2c_client *i2c,
BUG();
}
- if (ret < 0)
+ if (ret)
goto err;
return ret;
err:
- mfd_remove_devices(sec_pmic->dev);
sec_irq_exit(sec_pmic);
i2c_unregister_device(sec_pmic->rtc);
return ret;
diff --git a/drivers/ssbi/ssbi.c b/drivers/mfd/ssbi.c
index f32da0258a8e..f32da0258a8e 100644
--- a/drivers/ssbi/ssbi.c
+++ b/drivers/mfd/ssbi.c
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index b32940ec9034..a21bff283a98 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -422,7 +422,6 @@ static int t7l66xb_remove(struct platform_device *dev)
iounmap(t7l66xb->scr);
release_resource(&t7l66xb->rscr);
mfd_remove_devices(&dev->dev);
- platform_set_drvdata(dev, NULL);
kfree(t7l66xb);
return ret;
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 366f7b906278..65c425a517c5 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -217,7 +217,6 @@ static int tc6387xb_remove(struct platform_device *dev)
release_resource(&tc6387xb->rscr);
clk_disable(tc6387xb->clk32k);
clk_put(tc6387xb->clk32k);
- platform_set_drvdata(dev, NULL);
kfree(tc6387xb);
return 0;
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 15e1463e5e13..a563dfa3cf87 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -756,7 +756,6 @@ static int tc6393xb_remove(struct platform_device *dev)
clk_disable(tc6393xb->clk);
iounmap(tc6393xb->scr);
release_resource(&tc6393xb->rscr);
- platform_set_drvdata(dev, NULL);
clk_put(tc6393xb->clk);
kfree(tc6393xb);
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 89ab4d970643..8d9bc10c5312 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -1305,17 +1305,7 @@ static struct i2c_driver twl_driver = {
.remove = twl_remove,
};
-static int __init twl_init(void)
-{
- return i2c_add_driver(&twl_driver);
-}
-subsys_initcall(twl_init);
-
-static void __exit twl_exit(void)
-{
- i2c_del_driver(&twl_driver);
-}
-module_exit(twl_exit);
+module_i2c_driver(twl_driver);
MODULE_AUTHOR("Texas Instruments, Inc.");
MODULE_DESCRIPTION("I2C Core interface for TWL");
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index d2ab222138c2..a31fba96ef43 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -261,10 +261,8 @@ static int twl4030_audio_probe(struct platform_device *pdev)
ret = -ENODEV;
}
- if (ret) {
- platform_set_drvdata(pdev, NULL);
+ if (ret)
twl4030_audio_dev = NULL;
- }
return ret;
}
@@ -272,7 +270,6 @@ static int twl4030_audio_probe(struct platform_device *pdev)
static int twl4030_audio_remove(struct platform_device *pdev)
{
mfd_remove_devices(&pdev->dev);
- platform_set_drvdata(pdev, NULL);
twl4030_audio_dev = NULL;
return 0;
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
index 42bd3ea5df3c..1ea54d4d003a 100644
--- a/drivers/mfd/twl4030-madc.c
+++ b/drivers/mfd/twl4030-madc.c
@@ -775,12 +775,10 @@ static int twl4030_madc_probe(struct platform_device *pdev)
IRQF_TRIGGER_RISING, "twl4030_madc", madc);
if (ret) {
dev_dbg(&pdev->dev, "could not request irq\n");
- goto err_irq;
+ goto err_i2c;
}
twl4030_madc = madc;
return 0;
-err_irq:
- platform_set_drvdata(pdev, NULL);
err_i2c:
twl4030_madc_set_current_generator(madc, 0, 0);
err_current_generator:
@@ -796,7 +794,6 @@ static int twl4030_madc_remove(struct platform_device *pdev)
struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
free_irq(platform_get_irq(pdev, 0), madc);
- platform_set_drvdata(pdev, NULL);
twl4030_madc_set_current_generator(madc, 0, 0);
twl4030_madc_set_power(madc, 0);
kfree(madc);
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index c41599815299..2a7972349159 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -2273,18 +2273,22 @@ static bool wm5110_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_DSP1_CLOCKING_1:
case ARIZONA_DSP1_STATUS_1:
case ARIZONA_DSP1_STATUS_2:
+ case ARIZONA_DSP1_STATUS_3:
case ARIZONA_DSP2_CONTROL_1:
case ARIZONA_DSP2_CLOCKING_1:
case ARIZONA_DSP2_STATUS_1:
case ARIZONA_DSP2_STATUS_2:
+ case ARIZONA_DSP2_STATUS_3:
case ARIZONA_DSP3_CONTROL_1:
case ARIZONA_DSP3_CLOCKING_1:
case ARIZONA_DSP3_STATUS_1:
case ARIZONA_DSP3_STATUS_2:
+ case ARIZONA_DSP3_STATUS_3:
case ARIZONA_DSP4_CONTROL_1:
case ARIZONA_DSP4_CLOCKING_1:
case ARIZONA_DSP4_STATUS_1:
case ARIZONA_DSP4_STATUS_2:
+ case ARIZONA_DSP4_STATUS_3:
return true;
default:
return false;
@@ -2334,12 +2338,16 @@ static bool wm5110_volatile_register(struct device *dev, unsigned int reg)
case ARIZONA_DSP1_CLOCKING_1:
case ARIZONA_DSP1_STATUS_1:
case ARIZONA_DSP1_STATUS_2:
+ case ARIZONA_DSP1_STATUS_3:
case ARIZONA_DSP2_STATUS_1:
case ARIZONA_DSP2_STATUS_2:
+ case ARIZONA_DSP2_STATUS_3:
case ARIZONA_DSP3_STATUS_1:
case ARIZONA_DSP3_STATUS_2:
+ case ARIZONA_DSP3_STATUS_3:
case ARIZONA_DSP4_STATUS_1:
case ARIZONA_DSP4_STATUS_2:
+ case ARIZONA_DSP4_STATUS_3:
return true;
default:
return false;
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
index a050e56a9bbd..d3a184a240f5 100644
--- a/drivers/mfd/wm8994-irq.c
+++ b/drivers/mfd/wm8994-irq.c
@@ -14,10 +14,12 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/regmap.h>
#include <linux/mfd/wm8994/core.h>
@@ -138,6 +140,55 @@ static struct regmap_irq_chip wm8994_irq_chip = {
.runtime_pm = true,
};
+static void wm8994_edge_irq_enable(struct irq_data *data)
+{
+}
+
+static void wm8994_edge_irq_disable(struct irq_data *data)
+{
+}
+
+static struct irq_chip wm8994_edge_irq_chip = {
+ .name = "wm8994_edge",
+ .irq_disable = wm8994_edge_irq_disable,
+ .irq_enable = wm8994_edge_irq_enable,
+};
+
+static irqreturn_t wm8994_edge_irq(int irq, void *data)
+{
+ struct wm8994 *wm8994 = data;
+
+ while (gpio_get_value_cansleep(wm8994->pdata.irq_gpio))
+ handle_nested_irq(irq_create_mapping(wm8994->edge_irq, 0));
+
+ return IRQ_HANDLED;
+}
+
+static int wm8994_edge_irq_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct wm8994 *wm8994 = h->host_data;
+
+ irq_set_chip_data(virq, wm8994);
+ irq_set_chip_and_handler(virq, &wm8994_edge_irq_chip, handle_edge_irq);
+ irq_set_nested_thread(virq, 1);
+
+ /* ARM needs us to explicitly flag the IRQ as valid
+ * and will set them noprobe when we do so. */
+#ifdef CONFIG_ARM
+ set_irq_flags(virq, IRQF_VALID);
+#else
+ irq_set_noprobe(virq);
+#endif
+
+ return 0;
+}
+
+static struct irq_domain_ops wm8994_edge_irq_ops = {
+ .map = wm8994_edge_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
int wm8994_irq_init(struct wm8994 *wm8994)
{
int ret;
@@ -156,10 +207,51 @@ int wm8994_irq_init(struct wm8994 *wm8994)
if (pdata->irq_flags)
irqflags = pdata->irq_flags;
- ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq,
- irqflags,
- wm8994->irq_base, &wm8994_irq_chip,
- &wm8994->irq_data);
+ /* use a GPIO for edge triggered controllers */
+ if (irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+ if (gpio_to_irq(pdata->irq_gpio) != wm8994->irq) {
+ dev_warn(wm8994->dev, "IRQ %d is not GPIO %d (%d)\n",
+ wm8994->irq, pdata->irq_gpio,
+ gpio_to_irq(pdata->irq_gpio));
+ wm8994->irq = gpio_to_irq(pdata->irq_gpio);
+ }
+
+ ret = devm_gpio_request_one(wm8994->dev, pdata->irq_gpio,
+ GPIOF_IN, "WM8994 IRQ");
+
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to get IRQ GPIO: %d\n",
+ ret);
+ return ret;
+ }
+
+ wm8994->edge_irq = irq_domain_add_linear(NULL, 1,
+ &wm8994_edge_irq_ops,
+ wm8994);
+
+ ret = regmap_add_irq_chip(wm8994->regmap,
+ irq_create_mapping(wm8994->edge_irq,
+ 0),
+ IRQF_ONESHOT,
+ wm8994->irq_base, &wm8994_irq_chip,
+ &wm8994->irq_data);
+ if (ret != 0) {
+ dev_err(wm8994->dev, "Failed to get IRQ: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = request_threaded_irq(wm8994->irq,
+ NULL, wm8994_edge_irq,
+ irqflags,
+ "WM8994 edge", wm8994);
+ } else {
+ ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq,
+ irqflags,
+ wm8994->irq_base, &wm8994_irq_chip,
+ &wm8994->irq_data);
+ }
+
if (ret != 0) {
dev_err(wm8994->dev, "Failed to register IRQ chip: %d\n", ret);
return ret;
diff --git a/drivers/ssbi/Kconfig b/drivers/ssbi/Kconfig
deleted file mode 100644
index 1ae4040afedd..000000000000
--- a/drivers/ssbi/Kconfig
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# SSBI bus support
-#
-
-menu "Qualcomm MSM SSBI bus support"
-
-config SSBI
- tristate "Qualcomm Single-wire Serial Bus Interface (SSBI)"
- help
- If you say yes to this option, support will be included for the
- built-in SSBI interface on Qualcomm MSM family processors.
-
- This is required for communicating with Qualcomm PMICs and
- other devices that have the SSBI interface.
-
-endmenu
diff --git a/drivers/ssbi/Makefile b/drivers/ssbi/Makefile
deleted file mode 100644
index 38fb70c31caf..000000000000
--- a/drivers/ssbi/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_SSBI) += ssbi.o
diff --git a/include/linux/mfd/arizona/core.h b/include/linux/mfd/arizona/core.h
index cc281368dc55..f797bb9b8b56 100644
--- a/include/linux/mfd/arizona/core.h
+++ b/include/linux/mfd/arizona/core.h
@@ -95,6 +95,8 @@ struct arizona {
struct arizona_pdata pdata;
+ unsigned int external_dcvdd:1;
+
int irq;
struct irq_domain *virq;
struct regmap_irq_chip_data *aod_irq_chip;
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 80dead1f7100..12a5c135c746 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -77,7 +77,7 @@ struct arizona_micbias {
int mV; /** Regulated voltage */
unsigned int ext_cap:1; /** External capacitor fitted */
unsigned int discharge:1; /** Actively discharge */
- unsigned int fast_start:1; /** Enable aggressive startup ramp rate */
+ unsigned int soft_start:1; /** Disable aggressive startup ramp rate */
unsigned int bypass:1; /** Use bypass mode */
};
diff --git a/include/linux/mfd/arizona/registers.h b/include/linux/mfd/arizona/registers.h
index 715b6ba3d52a..4730b5c576e2 100644
--- a/include/linux/mfd/arizona/registers.h
+++ b/include/linux/mfd/arizona/registers.h
@@ -1002,6 +1002,7 @@
#define ARIZONA_DSP2_CLOCKING_1 0x1201
#define ARIZONA_DSP2_STATUS_1 0x1204
#define ARIZONA_DSP2_STATUS_2 0x1205
+#define ARIZONA_DSP2_STATUS_3 0x1206
#define ARIZONA_DSP2_SCRATCH_0 0x1240
#define ARIZONA_DSP2_SCRATCH_1 0x1241
#define ARIZONA_DSP2_SCRATCH_2 0x1242
@@ -1010,6 +1011,7 @@
#define ARIZONA_DSP3_CLOCKING_1 0x1301
#define ARIZONA_DSP3_STATUS_1 0x1304
#define ARIZONA_DSP3_STATUS_2 0x1305
+#define ARIZONA_DSP3_STATUS_3 0x1306
#define ARIZONA_DSP3_SCRATCH_0 0x1340
#define ARIZONA_DSP3_SCRATCH_1 0x1341
#define ARIZONA_DSP3_SCRATCH_2 0x1342
@@ -1018,6 +1020,7 @@
#define ARIZONA_DSP4_CLOCKING_1 0x1401
#define ARIZONA_DSP4_STATUS_1 0x1404
#define ARIZONA_DSP4_STATUS_2 0x1405
+#define ARIZONA_DSP4_STATUS_3 0x1406
#define ARIZONA_DSP4_SCRATCH_0 0x1440
#define ARIZONA_DSP4_SCRATCH_1 0x1441
#define ARIZONA_DSP4_SCRATCH_2 0x1442
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h
index 86bc635f8385..7a9f7089435d 100644
--- a/include/linux/mfd/rtsx_pci.h
+++ b/include/linux/mfd/rtsx_pci.h
@@ -575,6 +575,7 @@
#define CARD_PWR_CTL 0xFD50
#define CARD_CLK_SWITCH 0xFD51
+#define RTL8411B_PACKAGE_MODE 0xFD51
#define CARD_SHARE_MODE 0xFD52
#define CARD_DRIVE_SEL 0xFD53
#define CARD_STOP 0xFD54
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index ae5c249530b4..40854ac0ba3d 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -29,6 +29,7 @@ enum wm8994_type {
struct regulator_dev;
struct regulator_bulk_data;
+struct irq_domain;
#define WM8994_NUM_GPIO_REGS 11
#define WM8994_NUM_LDO_REGS 2
@@ -73,6 +74,7 @@ struct wm8994 {
int irq;
struct regmap_irq_chip_data *irq_data;
+ struct irq_domain *edge_irq;
/* Used over suspend/resume */
bool suspended;
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h
index 68e776594889..90e9bf86e643 100644
--- a/include/linux/mfd/wm8994/pdata.h
+++ b/include/linux/mfd/wm8994/pdata.h
@@ -223,6 +223,11 @@ struct wm8994_pdata {
* lines is mastered.
*/
int max_channels_clocked[WM8994_NUM_AIF];
+
+ /**
+ * GPIO for the IRQ pin if host only supports edge triggering
+ */
+ int irq_gpio;
};
#endif