summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 07:28:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-08-01 07:28:14 -0400
commit06e23d51151fd06c225c80ace26675532bdf406d (patch)
tree25d869bed6c4bdfd9addb799c72941e08c162ac2 /drivers
parentdd9671172a06830071c8edb31fb2176f222a2c6e (diff)
parentf37be01e6dc606f2fcc5e95c9933d948ce19bd35 (diff)
Merge tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "Core Framework: - New API to call bespoke pre/post IRQ handlers; Regmap New Device Support: - Add support for RN5T567 to rn5t618 - Add support for COMe-cSL6 and COMe-mAL10 to kempld-core New Functionality: - Add support for USB Power Supply to axp20x - Add support for Power Key to hi655x-pmic Fix-ups: - Update MAINTAINERS; Dialog, Altera - Remove module support; max77843, max77620, max8998, max8997, max8925-i2c - Add module support; max14577 - Constifying; max77620 - Allow bespoke IRQ masking/unmasking; max77620 - Remove superfluous code; arizona, qcom_rpm, smsc-ece1099 - Power Management fixups; arizona-core - Error-path improvement; twl-core, dm355evm_msp, smsc-ece1099, hi655x - Clocking fixups; twl6040 - Trivial (spelling, headers, coding-style, whitespace, (re)naming); si476x-i2c, omap-usb-tll, ti_am335x_tscadc, tps6507, hi655x-pmic Bug Fixes: - Fix offset error for MSM8660; qcom_rpm - Fix possible spurious IRQs; arizona, hi655x-pmic" * tag 'mfd-for-linus-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (42 commits) mfd: qcom_rpm: Parametrize also ack selector size mfd: twl6040: Handle mclk used for HPPLL and optional internal clock source mfd: Add support for COMe-cSL6 and COMe-mAL10 to Kontron PLD driver mfd: hi655x: Fix return value check in hi655x_pmic_probe() mfd: smsc-ece1099: Return directly after a function failure in smsc_i2c_probe() mfd: smsc-ece1099: Delete an unnecessary variable initialisation in smsc_i2c_probe() mfd: dm355evm_msp: Return directly after a failed platform_device_alloc() in add_child() mfd: twl-core: Refactoring for add_numbered_child() mfd: twl-core: Return directly after a failed platform_device_alloc() in add_numbered_child() mfd: arizona: Add missing disable of PM runtime on probe error path mfd: stmpe: Move platform data into MFD driver mfd: max14577: Allow driver to be built as a module mfd: max14577: Use module_init() instead of subsys_initcall() mfd: arizona: Remove some duplicate defines mfd: qcom_rpm: Remove unused define mfd: hi655x-pmic: Add powerkey device to hi655x PMIC driver mfd: hi655x-pmic: Rename some interrupt macro names mfd: hi655x-pmic: Fixup issue with un-acked interrupts mfd: arizona: Check if AOD interrupts are pending before dispatching mfd: qcom_rpm: Fix offset error for msm8660 ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mfd/Kconfig17
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/altera-a10sr.c169
-rw-r--r--drivers/mfd/arizona-core.c4
-rw-r--r--drivers/mfd/arizona-irq.c16
-rw-r--r--drivers/mfd/axp20x.c17
-rw-r--r--drivers/mfd/dm355evm_msp.c7
-rw-r--r--drivers/mfd/hi655x-pmic.c59
-rw-r--r--drivers/mfd/kempld-core.c16
-rw-r--r--drivers/mfd/max14577.c2
-rw-r--r--drivers/mfd/max77620.c75
-rw-r--r--drivers/mfd/max77843.c24
-rw-r--r--drivers/mfd/max8925-i2c.c14
-rw-r--r--drivers/mfd/max8997.c30
-rw-r--r--drivers/mfd/max8998.c27
-rw-r--r--drivers/mfd/omap-usb-tll.c2
-rw-r--r--drivers/mfd/qcom_rpm.c57
-rw-r--r--drivers/mfd/si476x-i2c.c2
-rw-r--r--drivers/mfd/smsc-ece1099.c11
-rw-r--r--drivers/mfd/stmpe.c40
-rw-r--r--drivers/mfd/ti_am335x_tscadc.c135
-rw-r--r--drivers/mfd/tps6507x.c4
-rw-r--r--drivers/mfd/twl-core.c28
-rw-r--r--drivers/mfd/twl6040.c41
24 files changed, 515 insertions, 284 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index ff031a7735a5..2d1fb6420592 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -18,6 +18,17 @@ config MFD_CS5535
This is the core driver for CS5535/CS5536 MFD functions. This is
necessary for using the board's GPIO and MFGPT functionality.
+config MFD_ALTERA_A10SR
+ bool "Altera Arria10 DevKit System Resource chip"
+ depends on ARCH_SOCFPGA && SPI_MASTER=y && OF
+ select REGMAP_SPI
+ select MFD_CORE
+ help
+ Support for the Altera Arria10 DevKit MAX5 System Resource chip
+ using the SPI interface. This driver provides common support for
+ accessing the external gpio extender (LEDs & buttons) and
+ power supply alarms (hwmon).
+
config MFD_ACT8945A
tristate "Active-semi ACT8945A"
select MFD_CORE
@@ -480,6 +491,8 @@ config MFD_KEMPLD
* COMe-cDC2 (microETXexpress-DC)
* COMe-cHL6
* COMe-cPC2 (microETXexpress-PC)
+ * COMe-cSL6
+ * COMe-mAL10
* COMe-mBT10
* COMe-mCT10
* COMe-mTT10 (nanoETXexpress-TT)
@@ -524,8 +537,8 @@ config MFD_88PM860X
battery-charger under the corresponding menus.
config MFD_MAX14577
- bool "Maxim Semiconductor MAX14577/77836 MUIC + Charger Support"
- depends on I2C=y
+ tristate "Maxim Semiconductor MAX14577/77836 MUIC + Charger Support"
+ depends on I2C
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 42a66e19e191..2ba3ba35f745 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -205,3 +205,5 @@ intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
intel-soc-pmic-$(CONFIG_INTEL_PMC_IPC) += intel_soc_pmic_bxtwc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
+
+obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
diff --git a/drivers/mfd/altera-a10sr.c b/drivers/mfd/altera-a10sr.c
new file mode 100644
index 000000000000..c05aa4ff57fd
--- /dev/null
+++ b/drivers/mfd/altera-a10sr.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPI access for Altera Arria10 MAX5 System Resource Chip
+ *
+ * Adapted from DA9052
+ */
+
+#include <linux/mfd/altera-a10sr.h>
+#include <linux/mfd/core.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/spi/spi.h>
+
+static const struct mfd_cell altr_a10sr_subdev_info[] = {
+ {
+ .name = "altr_a10sr_gpio",
+ .of_compatible = "altr,a10sr-gpio",
+ },
+};
+
+static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ALTR_A10SR_VERSION_READ:
+ case ALTR_A10SR_LED_REG:
+ case ALTR_A10SR_PBDSW_REG:
+ case ALTR_A10SR_PBDSW_IRQ_REG:
+ case ALTR_A10SR_PWR_GOOD1_REG:
+ case ALTR_A10SR_PWR_GOOD2_REG:
+ case ALTR_A10SR_PWR_GOOD3_REG:
+ case ALTR_A10SR_FMCAB_REG:
+ case ALTR_A10SR_HPS_RST_REG:
+ case ALTR_A10SR_USB_QSPI_REG:
+ case ALTR_A10SR_SFPA_REG:
+ case ALTR_A10SR_SFPB_REG:
+ case ALTR_A10SR_I2C_M_REG:
+ case ALTR_A10SR_WARM_RST_REG:
+ case ALTR_A10SR_WR_KEY_REG:
+ case ALTR_A10SR_PMBUS_REG:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ALTR_A10SR_LED_REG:
+ case ALTR_A10SR_PBDSW_IRQ_REG:
+ case ALTR_A10SR_FMCAB_REG:
+ case ALTR_A10SR_HPS_RST_REG:
+ case ALTR_A10SR_USB_QSPI_REG:
+ case ALTR_A10SR_SFPA_REG:
+ case ALTR_A10SR_SFPB_REG:
+ case ALTR_A10SR_WARM_RST_REG:
+ case ALTR_A10SR_WR_KEY_REG:
+ case ALTR_A10SR_PMBUS_REG:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
+{
+ switch (reg) {
+ case ALTR_A10SR_PBDSW_REG:
+ case ALTR_A10SR_PBDSW_IRQ_REG:
+ case ALTR_A10SR_PWR_GOOD1_REG:
+ case ALTR_A10SR_PWR_GOOD2_REG:
+ case ALTR_A10SR_PWR_GOOD3_REG:
+ case ALTR_A10SR_HPS_RST_REG:
+ case ALTR_A10SR_I2C_M_REG:
+ case ALTR_A10SR_WARM_RST_REG:
+ case ALTR_A10SR_WR_KEY_REG:
+ case ALTR_A10SR_PMBUS_REG:
+ return true;
+ default:
+ return false;
+ }
+}
+
+const struct regmap_config altr_a10sr_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+
+ .cache_type = REGCACHE_NONE,
+
+ .use_single_rw = true,
+ .read_flag_mask = 1,
+ .write_flag_mask = 0,
+
+ .max_register = ALTR_A10SR_WR_KEY_REG,
+ .readable_reg = altr_a10sr_reg_readable,
+ .writeable_reg = altr_a10sr_reg_writeable,
+ .volatile_reg = altr_a10sr_reg_volatile,
+
+};
+
+static int altr_a10sr_spi_probe(struct spi_device *spi)
+{
+ int ret;
+ struct altr_a10sr *a10sr;
+
+ a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
+ GFP_KERNEL);
+ if (!a10sr)
+ return -ENOMEM;
+
+ spi->mode = SPI_MODE_3;
+ spi->bits_per_word = 8;
+ spi_setup(spi);
+
+ a10sr->dev = &spi->dev;
+
+ spi_set_drvdata(spi, a10sr);
+
+ a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
+ if (IS_ERR(a10sr->regmap)) {
+ ret = PTR_ERR(a10sr->regmap);
+ dev_err(&spi->dev, "Failed to allocate register map: %d\n",
+ ret);
+ return ret;
+ }
+
+ ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
+ altr_a10sr_subdev_info,
+ ARRAY_SIZE(altr_a10sr_subdev_info),
+ NULL, 0, NULL);
+ if (ret)
+ dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
+ ret);
+
+ return ret;
+}
+
+static const struct of_device_id altr_a10sr_spi_of_match[] = {
+ { .compatible = "altr,a10sr" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
+
+static struct spi_driver altr_a10sr_spi_driver = {
+ .probe = altr_a10sr_spi_probe,
+ .driver = {
+ .name = "altr_a10sr",
+ .of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
+ },
+};
+
+module_spi_driver(altr_a10sr_spi_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>");
+MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver");
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index bf2717967597..e4f97b3c824b 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -1462,7 +1462,7 @@ int arizona_dev_init(struct arizona *arizona)
/* Set up for interrupts */
ret = arizona_irq_init(arizona);
if (ret != 0)
- goto err_reset;
+ goto err_pm;
pm_runtime_set_autosuspend_delay(arizona->dev, 100);
pm_runtime_use_autosuspend(arizona->dev);
@@ -1486,6 +1486,8 @@ int arizona_dev_init(struct arizona *arizona)
err_irq:
arizona_irq_exit(arizona);
+err_pm:
+ pm_runtime_disable(arizona->dev);
err_reset:
arizona_enable_reset(arizona);
regulator_disable(arizona->dcvdd);
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index edeb4951366a..5e18d3c77582 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -109,8 +109,20 @@ static irqreturn_t arizona_irq_thread(int irq, void *data)
do {
poll = false;
- if (arizona->aod_irq_chip)
- handle_nested_irq(irq_find_mapping(arizona->virq, 0));
+ if (arizona->aod_irq_chip) {
+ /*
+ * Check the AOD status register to determine whether
+ * the nested IRQ handler should be called.
+ */
+ ret = regmap_read(arizona->regmap,
+ ARIZONA_AOD_IRQ1, &val);
+ if (ret)
+ dev_warn(arizona->dev,
+ "Failed to read AOD IRQ1 %d\n", ret);
+ else if (val)
+ handle_nested_irq(
+ irq_find_mapping(arizona->virq, 0));
+ }
/*
* Check if one of the main interrupts is asserted and only
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index e4e32978c377..fd80b0981f0f 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -17,6 +17,7 @@
*/
#include <linux/err.h>
+#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -93,7 +94,10 @@ static const struct regmap_range axp22x_writeable_ranges[] = {
};
static const struct regmap_range axp22x_volatile_ranges[] = {
+ regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP20X_PWR_OP_MODE),
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ5_STATE),
+ regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
+ regmap_reg_range(AXP20X_FG_RES, AXP20X_FG_RES),
};
static const struct regmap_access_table axp22x_writeable_table = {
@@ -157,6 +161,11 @@ static struct resource axp20x_usb_power_supply_resources[] = {
DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"),
};
+static struct resource axp22x_usb_power_supply_resources[] = {
+ DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
+ DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
+};
+
static struct resource axp22x_pek_resources[] = {
{
.name = "PEK_DBR",
@@ -524,6 +533,11 @@ static struct mfd_cell axp22x_cells[] = {
.resources = axp22x_pek_resources,
}, {
.name = "axp20x-regulator",
+ }, {
+ .name = "axp20x-usb-power-supply",
+ .of_compatible = "x-powers,axp221-usb-power-supply",
+ .num_resources = ARRAY_SIZE(axp22x_usb_power_supply_resources),
+ .resources = axp22x_usb_power_supply_resources,
},
};
@@ -664,6 +678,9 @@ static void axp20x_power_off(void)
regmap_write(axp20x_pm_power_off->regmap, AXP20X_OFF_CTRL,
AXP20X_OFF);
+
+ /* Give capacitors etc. time to drain to avoid kernel panic msg. */
+ msleep(500);
}
int axp20x_match_device(struct axp20x_dev *axp20x)
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 14661ec5ef7f..270e19c0bba1 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -199,11 +199,8 @@ static struct device *add_child(struct i2c_client *client, const char *name,
int status;
pdev = platform_device_alloc(name, -1);
- if (!pdev) {
- dev_dbg(&client->dev, "can't alloc dev\n");
- status = -ENOMEM;
- goto err;
- }
+ if (!pdev)
+ return ERR_PTR(-ENOMEM);
device_init_wakeup(&pdev->dev, can_wakeup);
pdev->dev.parent = &client->dev;
diff --git a/drivers/mfd/hi655x-pmic.c b/drivers/mfd/hi655x-pmic.c
index 05ddc7882362..0fc62995695b 100644
--- a/drivers/mfd/hi655x-pmic.c
+++ b/drivers/mfd/hi655x-pmic.c
@@ -24,19 +24,15 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
-static const struct mfd_cell hi655x_pmic_devs[] = {
- { .name = "hi655x-regulator", },
-};
-
static const struct regmap_irq hi655x_irqs[] = {
- { .reg_offset = 0, .mask = OTMP_D1R_INT },
- { .reg_offset = 0, .mask = VSYS_2P5_R_INT },
- { .reg_offset = 0, .mask = VSYS_UV_D3R_INT },
- { .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT },
- { .reg_offset = 0, .mask = PWRON_D4SR_INT },
- { .reg_offset = 0, .mask = PWRON_D20F_INT },
- { .reg_offset = 0, .mask = PWRON_D20R_INT },
- { .reg_offset = 0, .mask = RESERVE_INT },
+ { .reg_offset = 0, .mask = OTMP_D1R_INT_MASK },
+ { .reg_offset = 0, .mask = VSYS_2P5_R_INT_MASK },
+ { .reg_offset = 0, .mask = VSYS_UV_D3R_INT_MASK },
+ { .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT_MASK },
+ { .reg_offset = 0, .mask = PWRON_D4SR_INT_MASK },
+ { .reg_offset = 0, .mask = PWRON_D20F_INT_MASK },
+ { .reg_offset = 0, .mask = PWRON_D20R_INT_MASK },
+ { .reg_offset = 0, .mask = RESERVE_INT_MASK },
};
static const struct regmap_irq_chip hi655x_irq_chip = {
@@ -45,6 +41,7 @@ static const struct regmap_irq_chip hi655x_irq_chip = {
.num_regs = 1,
.num_irqs = ARRAY_SIZE(hi655x_irqs),
.status_base = HI655X_IRQ_STAT_BASE,
+ .ack_base = HI655X_IRQ_STAT_BASE,
.mask_base = HI655X_IRQ_MASK_BASE,
};
@@ -55,6 +52,34 @@ static struct regmap_config hi655x_regmap_config = {
.max_register = HI655X_BUS_ADDR(0xFFF),
};
+static struct resource pwrkey_resources[] = {
+ {
+ .name = "down",
+ .start = PWRON_D20R_INT,
+ .end = PWRON_D20R_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "up",
+ .start = PWRON_D20F_INT,
+ .end = PWRON_D20F_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .name = "hold 4s",
+ .start = PWRON_D4SR_INT,
+ .end = PWRON_D4SR_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static const struct mfd_cell hi655x_pmic_devs[] = {
+ {
+ .name = "hi65xx-powerkey",
+ .num_resources = ARRAY_SIZE(pwrkey_resources),
+ .resources = &pwrkey_resources[0],
+ },
+ { .name = "hi655x-regulator", },
+};
+
static void hi655x_local_irq_clear(struct regmap *map)
{
int i;
@@ -80,12 +105,9 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
pmic->dev = dev;
pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!pmic->res)
- return -ENOENT;
-
base = devm_ioremap_resource(dev, pmic->res);
- if (!base)
- return -ENOMEM;
+ if (IS_ERR(base))
+ return PTR_ERR(base);
pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
&hi655x_regmap_config);
@@ -123,7 +145,8 @@ static int hi655x_pmic_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pmic);
ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
- ARRAY_SIZE(hi655x_pmic_devs), NULL, 0, NULL);
+ ARRAY_SIZE(hi655x_pmic_devs), NULL, 0,
+ regmap_irq_get_domain(pmic->irq_data));
if (ret) {
dev_err(dev, "Failed to register device %d\n", ret);
regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data);
diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c
index 05b924542ee2..da5722d7c540 100644
--- a/drivers/mfd/kempld-core.c
+++ b/drivers/mfd/kempld-core.c
@@ -624,6 +624,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
+ .ident = "CSL6",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+ DMI_MATCH(DMI_BOARD_NAME, "COMe-cSL6"),
+ },
+ .driver_data = (void *)&kempld_platform_data_generic,
+ .callback = kempld_create_platform_device,
+ }, {
.ident = "CVV6",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
@@ -647,6 +655,14 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
+ .ident = "MAL1",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
+ DMI_MATCH(DMI_BOARD_NAME, "COMe-mAL10"),
+ },
+ .driver_data = (void *)&kempld_platform_data_generic,
+ .callback = kempld_create_platform_device,
+ }, {
.ident = "MBR1",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c
index 2280b3fdcf68..6c245128ab2e 100644
--- a/drivers/mfd/max14577.c
+++ b/drivers/mfd/max14577.c
@@ -561,7 +561,7 @@ static int __init max14577_i2c_init(void)
return i2c_add_driver(&max14577_i2c_driver);
}
-subsys_initcall(max14577_i2c_init);
+module_init(max14577_i2c_init);
static void __exit max14577_i2c_exit(void)
{
diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c
index f32fbb8e8129..258757e216c4 100644
--- a/drivers/mfd/max77620.c
+++ b/drivers/mfd/max77620.c
@@ -31,25 +31,25 @@
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77620.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
-static struct resource gpio_resources[] = {
+static const struct resource gpio_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_GPIO),
};
-static struct resource power_resources[] = {
+static const struct resource power_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_MBATLOW),
};
-static struct resource rtc_resources[] = {
+static const struct resource rtc_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_TOP_RTC),
};
-static struct resource thermal_resources[] = {
+static const struct resource thermal_resources[] = {
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM1),
DEFINE_RES_IRQ(MAX77620_IRQ_LBT_TJALRM2),
};
@@ -111,15 +111,6 @@ static const struct mfd_cell max20024_children[] = {
},
};
-static struct regmap_irq_chip max77620_top_irq_chip = {
- .name = "max77620-top",
- .irqs = max77620_top_irqs,
- .num_irqs = ARRAY_SIZE(max77620_top_irqs),
- .num_regs = 2,
- .status_base = MAX77620_REG_IRQTOP,
- .mask_base = MAX77620_REG_IRQTOPM,
-};
-
static const struct regmap_range max77620_readable_ranges[] = {
regmap_reg_range(MAX77620_REG_CNFGGLBL1, MAX77620_REG_DVSSD4),
};
@@ -180,6 +171,51 @@ static const struct regmap_config max20024_regmap_config = {
.volatile_table = &max77620_volatile_table,
};
+/*
+ * MAX77620 and MAX20024 has the following steps of the interrupt handling
+ * for TOP interrupts:
+ * 1. When interrupt occurs from PMIC, mask the PMIC interrupt by setting GLBLM.
+ * 2. Read IRQTOP and service the interrupt.
+ * 3. Once all interrupts has been checked and serviced, the interrupt service
+ * routine un-masks the hardware interrupt line by clearing GLBLM.
+ */
+static int max77620_irq_global_mask(void *irq_drv_data)
+{
+ struct max77620_chip *chip = irq_drv_data;
+ int ret;
+
+ ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
+ MAX77620_GLBLM_MASK, MAX77620_GLBLM_MASK);
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to set GLBLM: %d\n", ret);
+
+ return ret;
+}
+
+static int max77620_irq_global_unmask(void *irq_drv_data)
+{
+ struct max77620_chip *chip = irq_drv_data;
+ int ret;
+
+ ret = regmap_update_bits(chip->rmap, MAX77620_REG_INTENLBT,
+ MAX77620_GLBLM_MASK, 0);
+ if (ret < 0)
+ dev_err(chip->dev, "Failed to reset GLBLM: %d\n", ret);
+
+ return ret;
+}
+
+static struct regmap_irq_chip max77620_top_irq_chip = {
+ .name = "max77620-top",
+ .irqs = max77620_top_irqs,
+ .num_irqs = ARRAY_SIZE(max77620_top_irqs),
+ .num_regs = 2,
+ .status_base = MAX77620_REG_IRQTOP,
+ .mask_base = MAX77620_REG_IRQTOPM,
+ .handle_pre_irq = max77620_irq_global_mask,
+ .handle_post_irq = max77620_irq_global_unmask,
+};
+
/* max77620_get_fps_period_reg_value: Get FPS bit field value from
* requested periods.
* MAX77620 supports the FPS period of 40, 80, 160, 320, 540, 1280, 2560
@@ -433,6 +469,7 @@ static int max77620_probe(struct i2c_client *client,
if (ret < 0)
return ret;
+ max77620_top_irq_chip.irq_drv_data = chip;
ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq,
IRQF_ONESHOT | IRQF_SHARED,
chip->irq_base, &max77620_top_irq_chip,
@@ -568,7 +605,6 @@ static const struct i2c_device_id max77620_id[] = {
{"max20024", MAX20024},
{},
};
-MODULE_DEVICE_TABLE(i2c, max77620_id);
static const struct dev_pm_ops max77620_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(max77620_i2c_suspend, max77620_i2c_resume)
@@ -582,11 +618,4 @@ static struct i2c_driver max77620_driver = {
.probe = max77620_probe,
.id_table = max77620_id,
};
-
-module_i2c_driver(max77620_driver);
-
-MODULE_DESCRIPTION("MAX77620/MAX20024 Multi Function Device Core Driver");
-MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
-MODULE_AUTHOR("Chaitanya Bandi <bandik@nvidia.com>");
-MODULE_AUTHOR("Mallikarjun Kasoju <mkasoju@nvidia.com>");
-MODULE_LICENSE("GPL v2");
+builtin_i2c_driver(max77620_driver);
diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c
index 7cfc95b49c5d..dc5caeaaa6a1 100644
--- a/drivers/mfd/max77843.c
+++ b/drivers/mfd/max77843.c
@@ -15,7 +15,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77693-common.h>
#include <linux/mfd/max77843-private.h>
@@ -171,19 +171,6 @@ err_pmic_id:
return ret;
}
-static int max77843_remove(struct i2c_client *i2c)
-{
- struct max77693_dev *max77843 = i2c_get_clientdata(i2c);
-
- mfd_remove_devices(max77843->dev);
-
- regmap_del_irq_chip(max77843->irq, max77843->irq_data_topsys);
-
- i2c_unregister_device(max77843->i2c_chg);
-
- return 0;
-}
-
static const struct of_device_id max77843_dt_match[] = {
{ .compatible = "maxim,max77843", },
{ },
@@ -193,7 +180,6 @@ static const struct i2c_device_id max77843_id[] = {
{ "max77843", TYPE_MAX77843, },
{ },
};
-MODULE_DEVICE_TABLE(i2c, max77843_id);
static int __maybe_unused max77843_suspend(struct device *dev)
{
@@ -226,9 +212,9 @@ static struct i2c_driver max77843_i2c_driver = {
.name = "max77843",
.pm = &max77843_pm,
.of_match_table = max77843_dt_match,
+ .suppress_bind_attrs = true,
},
.probe = max77843_probe,
- .remove = max77843_remove,
.id_table = max77843_id,
};
@@ -237,9 +223,3 @@ static int __init max77843_i2c_init(void)
return i2c_add_driver(&max77843_i2c_driver);
}
subsys_initcall(max77843_i2c_init);
-
-static void __exit max77843_i2c_exit(void)
-{
- i2c_del_driver(&max77843_i2c_driver);
-}
-module_exit(max77843_i2c_exit);
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index 70443b161a5b..5c80aea3211f 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -9,7 +9,7 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/mfd/max8925.h>
@@ -133,7 +133,6 @@ static const struct i2c_device_id max8925_id_table[] = {
{ "max8925", 0 },
{ },
};
-MODULE_DEVICE_TABLE(i2c, max8925_id_table);
static int max8925_dt_init(struct device_node *np, struct device *dev,
struct max8925_platform_data *pdata)
@@ -240,7 +239,6 @@ static const struct of_device_id max8925_dt_ids[] = {
{ .compatible = "maxim,max8925", },
{},
};
-MODULE_DEVICE_TABLE(of, max8925_dt_ids);
static struct i2c_driver max8925_driver = {
.driver = {
@@ -264,13 +262,3 @@ static int __init max8925_i2c_init(void)
return ret;
}
subsys_initcall(max8925_i2c_init);
-
-static void __exit max8925_i2c_exit(void)
-{
- i2c_del_driver(&max8925_driver);
-}
-module_exit(max8925_i2c_exit);
-
-MODULE_DESCRIPTION("I2C Driver for Maxim 8925");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index f316348e3d98..2d6e2c392786 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -2,7 +2,7 @@
* max8997.c - mfd core driver for the Maxim 8966 and 8997
*
* Copyright (C) 2011 Samsung Electronics
- * MyungJoo Ham <myungjoo.ham@smasung.com>
+ * MyungJoo Ham <myungjoo.ham@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,7 +28,7 @@
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
-#include <linux/module.h>
+#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max8997.h>
@@ -55,7 +55,6 @@ static const struct of_device_id max8997_pmic_dt_match[] = {
{ .compatible = "maxim,max8997-pmic", .data = (void *)TYPE_MAX8997 },
{},
};
-MODULE_DEVICE_TABLE(of, max8997_pmic_dt_match);
#endif
int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
@@ -263,24 +262,11 @@ err_i2c_haptic:
return ret;
}
-static int max8997_i2c_remove(struct i2c_client *i2c)
-{
- struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
-
- mfd_remove_devices(max8997->dev);
- i2c_unregister_device(max8997->muic);
- i2c_unregister_device(max8997->haptic);
- i2c_unregister_device(max8997->rtc);
-
- return 0;
-}
-
static const struct i2c_device_id max8997_i2c_id[] = {
{ "max8997", TYPE_MAX8997 },
{ "max8966", TYPE_MAX8966 },
{ }
};
-MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
static u8 max8997_dumpaddr_pmic[] = {
MAX8997_REG_INT1MSK,
@@ -510,10 +496,10 @@ static struct i2c_driver max8997_i2c_driver = {
.driver = {
.name = "max8997",
.pm = &max8997_pm,
+ .suppress_bind_attrs = true,
.of_match_table = of_match_ptr(max8997_pmic_dt_match),
},
.probe = max8997_i2c_probe,
- .remove = max8997_i2c_remove,
.id_table = max8997_i2c_id,
};
@@ -523,13 +509,3 @@ static int __init max8997_i2c_init(void)
}
/* init early so consumer devices can complete system boot */
subsys_initcall(max8997_i2c_init);
-
-static void __exit max8997_i2c_exit(void)
-{
- i2c_del_driver(&max8997_i2c_driver);
-}
-module_exit(max8997_i2c_exit);
-
-MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver");
-MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index ab28b29400f6..4c33b8063bc3 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -21,8 +21,6 @@
*/
#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
@@ -138,7 +136,6 @@ static const struct of_device_id max8998_dt_match[] = {
{ .compatible = "ti,lp3974", .data = (void *)TYPE_LP3974 },
{},
};
-MODULE_DEVICE_TABLE(of, max8998_dt_match);
#endif
/*
@@ -254,23 +251,11 @@ err:
return ret;
}
-static int max8998_i2c_remove(struct i2c_client *i2c)
-{
- struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
-
- mfd_remove_devices(max8998->dev);
- max8998_irq_exit(max8998);
- i2c_unregister_device(max8998->rtc);
-
- return 0;
-}
-
static const struct i2c_device_id max8998_i2c_id[] = {
{ "max8998", TYPE_MAX8998 },
{ "lp3974", TYPE_LP3974},
{ }
};
-MODULE_DEVICE_TABLE(i2c,