diff options
Diffstat (limited to 'drivers/mfd')
36 files changed, 479 insertions, 516 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 11841f4b7b2b..8c5dfdce4326 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -99,6 +99,15 @@ config MFD_AAT2870_CORE additional drivers must be enabled in order to use the functionality of the device. +config MFD_AT91_USART + tristate "AT91 USART Driver" + select MFD_CORE + help + Select this to get support for AT91 USART IP. This is a wrapper + over at91-usart-serial driver and usart-spi-driver. Only one function + can be used at a time. The choice is done at boot time by the probe + function of this MFD driver according to a device tree property. + config MFD_ATMEL_FLEXCOM tristate "Atmel Flexcom (Flexible Serial Communication Unit)" select MFD_CORE @@ -1023,16 +1032,23 @@ config MFD_RN5T618 functionality of the device. config MFD_SEC_CORE - bool "SAMSUNG Electronics PMIC Series Support" + tristate "SAMSUNG Electronics PMIC Series Support" depends on I2C=y select MFD_CORE select REGMAP_I2C select REGMAP_IRQ help - Support for the Samsung Electronics MFD series. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the functionality - of the device + Support for the Samsung Electronics PMIC devices coming + usually along with Samsung Exynos SoC chipset. + This driver provides common support for accessing the device, + additional drivers must be enabled in order to use the functionality + of the device + + To compile this driver as a module, choose M here: the + module will be called sec-core. + Have in mind that important core drivers (like regulators) depend + on this driver so building this as a module might require proper + initial ramdisk or might not boot up as well in certain scenarios. config MFD_SI476X_CORE tristate "Silicon Laboratories 4761/64/68 AM/FM radio." diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 5856a9489cbd..12980a4ad460 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -196,6 +196,7 @@ obj-$(CONFIG_MFD_SPMI_PMIC) += qcom-spmi-pmic.o obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o obj-$(CONFIG_MFD_TPS65090) += tps65090.o obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o +obj-$(CONFIG_MFD_AT91_USART) += at91-usart.o obj-$(CONFIG_MFD_ATMEL_FLEXCOM) += atmel-flexcom.o obj-$(CONFIG_MFD_ATMEL_HLCDC) += atmel-hlcdc.o obj-$(CONFIG_MFD_ATMEL_SMC) += atmel-smc.o diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index d817f202da5b..be0497b96720 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -360,6 +360,6 @@ static struct i2c_driver adp5520_driver = { module_i2c_driver(adp5520_driver); -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); +MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/altera-a10sr.c b/drivers/mfd/altera-a10sr.c index 96e7d2cb7b89..400e0b51844b 100644 --- a/drivers/mfd/altera-a10sr.c +++ b/drivers/mfd/altera-a10sr.c @@ -108,7 +108,8 @@ static const struct regmap_config altr_a10sr_regmap_config = { .cache_type = REGCACHE_NONE, - .use_single_rw = true, + .use_single_read = true, + .use_single_write = true, .read_flag_mask = 1, .write_flag_mask = 0, diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 5f1e37d23943..27b61639cdc7 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -52,8 +52,10 @@ int arizona_clk32k_enable(struct arizona *arizona) if (ret != 0) goto err_ref; ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK1]); - if (ret != 0) - goto err_pm; + if (ret != 0) { + pm_runtime_put_sync(arizona->dev); + goto err_ref; + } break; case ARIZONA_32KZ_MCLK2: ret = clk_prepare_enable(arizona->mclk[ARIZONA_MCLK2]); @@ -67,8 +69,6 @@ int arizona_clk32k_enable(struct arizona *arizona) ARIZONA_CLK_32K_ENA); } -err_pm: - pm_runtime_put_sync(arizona->dev); err_ref: if (ret != 0) arizona->clk32k_ref--; @@ -990,7 +990,7 @@ static const struct mfd_cell wm8998_devs[] = { int arizona_dev_init(struct arizona *arizona) { - const char * const mclk_name[] = { "mclk1", "mclk2" }; + static const char * const mclk_name[] = { "mclk1", "mclk2" }; struct device *dev = arizona->dev; const char *type_name = NULL; unsigned int reg, val; diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c new file mode 100644 index 000000000000..d20747f612c1 --- /dev/null +++ b/drivers/mfd/at91-usart.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Driver for AT91 USART + * + * Copyright (C) 2018 Microchip Technology + * + * Author: Radu Pirea <radu.pirea@microchip.com> + * + */ + +#include <dt-bindings/mfd/at91-usart.h> + +#include <linux/module.h> +#include <linux/mfd/core.h> +#include <linux/of.h> +#include <linux/property.h> + +static struct mfd_cell at91_usart_spi_subdev = { + .name = "at91_usart_spi", + .of_compatible = "microchip,at91sam9g45-usart-spi", + }; + +static struct mfd_cell at91_usart_serial_subdev = { + .name = "atmel_usart_serial", + .of_compatible = "atmel,at91rm9200-usart-serial", + }; + +static int at91_usart_mode_probe(struct platform_device *pdev) +{ + struct mfd_cell cell; + u32 opmode = AT91_USART_MODE_SERIAL; + + device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode); + + switch (opmode) { + case AT91_USART_MODE_SPI: + cell = at91_usart_spi_subdev; + break; + case AT91_USART_MODE_SERIAL: + cell = at91_usart_serial_subdev; + break; + default: + dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n", + opmode); + return -EINVAL; + } + + return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1, + NULL, 0, NULL); +} + +static const struct of_device_id at91_usart_mode_of_match[] = { + { .compatible = "atmel,at91rm9200-usart" }, + { .compatible = "atmel,at91sam9260-usart" }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, at91_usart_mode_of_match); + +static struct platform_driver at91_usart_mfd = { + .probe = at91_usart_mode_probe, + .driver = { + .name = "at91_usart_mode", + .of_match_table = at91_usart_mode_of_match, + }, +}; + +module_platform_driver(at91_usart_mfd); + +MODULE_AUTHOR("Radu Pirea <radu.pirea@microchip.com>"); +MODULE_DESCRIPTION("AT91 USART MFD driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index 65a9757a6d21..fe6f83766144 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -218,7 +218,8 @@ EXPORT_SYMBOL(cros_ec_suspend); static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev) { - while (cros_ec_get_next_event(ec_dev, NULL) > 0) + while (ec_dev->mkbp_event_supported && + cros_ec_get_next_event(ec_dev, NULL) > 0) blocking_notifier_call_chain(&ec_dev->event_notifier, 1, ec_dev); } diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 999dac752bcc..8f9d6964173e 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -546,6 +546,7 @@ static struct platform_driver cros_ec_dev_driver = { .name = DRV_NAME, .pm = &cros_ec_dev_pm_ops, }, + .id_table = cros_ec_id, .probe = ec_device_probe, .remove = ec_device_remove, .shutdown = ec_device_shutdown, diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c index abfb11818fdc..fdae1288bc6d 100644 --- a/drivers/mfd/da9052-spi.c +++ b/drivers/mfd/da9052-spi.c @@ -46,7 +46,8 @@ static int da9052_spi_probe(struct spi_device *spi) config.reg_bits = 7; config.pad_bits = 1; config.val_bits = 8; - config.use_single_rw = 1; + config.use_single_read = true; + config.use_single_write = true; da9052->regmap = devm_regmap_init_spi(spi, &config); if (IS_ERR(da9052->regmap)) { diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 2017446c5b4b..bb24c2a07900 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Driver for Intel MSIC * * Copyright (C) 2011, Intel Corporation * Author: Mika Westerberg <mika.westerberg@linux.intel.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/err.h> @@ -54,68 +51,44 @@ struct intel_msic { }; static struct resource msic_touch_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_adc_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_battery_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_gpio_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_audio_resources[] = { - { - .name = "IRQ", - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(0, "IRQ"), /* * We will pass IRQ_BASE to the driver now but this can be removed * when/if the driver starts to use intel_msic_irq_read(). */ - { - .name = "IRQ_BASE", - .flags = IORESOURCE_MEM, - .start = MSIC_IRQ_STATUS_ACCDET, - .end = MSIC_IRQ_STATUS_ACCDET, - }, + DEFINE_RES_MEM_NAMED(MSIC_IRQ_STATUS_ACCDET, 1, "IRQ_BASE"), }; static struct resource msic_hdmi_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_thermal_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_power_btn_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; static struct resource msic_ocd_resources[] = { - { - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(0), }; /* diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c index 15bc052704a6..6310c3bdb991 100644 --- a/drivers/mfd/intel_soc_pmic_bxtwc.c +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -1,27 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MFD core driver for Intel Broxton Whiskey Cove PMIC * * Copyright (C) 2015 Intel Corporation. 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. */ -#include <linux/module.h> #include <linux/acpi.h> -#include <linux/err.h> #include <linux/delay.h> +#include <linux/err.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/mfd/core.h> #include <linux/mfd/intel_soc_pmic.h> #include <linux/mfd/intel_soc_pmic_bxtwc.h> +#include <linux/module.h> + #include <asm/intel_pmc_ipc.h> /* PMIC device registers */ @@ -31,8 +24,8 @@ /* Interrupt Status Registers */ #define BXTWC_IRQLVL1 0x4E02 -#define BXTWC_PWRBTNIRQ 0x4E03 +#define BXTWC_PWRBTNIRQ 0x4E03 #define BXTWC_THRM0IRQ 0x4E04 #define BXTWC_THRM1IRQ 0x4E05 #define BXTWC_THRM2IRQ 0x4E06 @@ -47,10 +40,9 @@ /* Interrupt MASK Registers */ #define BXTWC_MIRQLVL1 0x4E0E -#define BXTWC_MPWRTNIRQ 0x4E0F - #define BXTWC_MIRQLVL1_MCHGR BIT(5) +#define BXTWC_MPWRBTNIRQ 0x4E0F #define BXTWC_MTHRM0IRQ 0x4E12 #define BXTWC_MTHRM1IRQ 0x4E13 #define BXTWC_MTHRM2IRQ 0x4E14 @@ -66,9 +58,7 @@ /* Whiskey Cove PMIC share same ACPI ID between different platforms */ #define BROXTON_PMIC_WC_HRV 4 -/* Manage in two IRQ chips since mask registers are not consecutive */ enum bxtwc_irqs { - /* Level 1 */ BXTWC_PWRBTN_LVL1_IRQ = 0, BXTWC_TMU_LVL1_IRQ, BXTWC_THRM_LVL1_IRQ, @@ -77,9 +67,11 @@ enum bxtwc_irqs { BXTWC_CHGR_LVL1_IRQ, BXTWC_GPIO_LVL1_IRQ, BXTWC_CRIT_LVL1_IRQ, +}; - /* Level 2 */ - BXTWC_PWRBTN_IRQ, +enum bxtwc_irqs_pwrbtn { + BXTWC_PWRBTN_IRQ = 0, + BXTWC_UIBTN_IRQ, }; enum bxtwc_irqs_bcu { @@ -113,7 +105,10 @@ static const struct regmap_irq bxtwc_regmap_irqs[] = { REGMAP_IRQ_REG(BXTWC_CHGR_LVL1_IRQ, 0, BIT(5)), REGMAP_IRQ_REG(BXTWC_GPIO_LVL1_IRQ, 0, BIT(6)), REGMAP_IRQ_REG(BXTWC_CRIT_LVL1_IRQ, 0, BIT(7)), - REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 1, 0x03), +}; + +static const struct regmap_irq bxtwc_regmap_irqs_pwrbtn[] = { + REGMAP_IRQ_REG(BXTWC_PWRBTN_IRQ, 0, 0x01), }; static const struct regmap_irq bxtwc_regmap_irqs_bcu[] = { @@ -125,7 +120,7 @@ static const struct regmap_irq bxtwc_regmap_irqs_adc[] = { }; static const struct regmap_irq bxtwc_regmap_irqs_chgr[] = { - REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, BIT(5)), + REGMAP_IRQ_REG(BXTWC_USBC_IRQ, 0, 0x20), REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 0, 0x1f), REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 1, 0x1f), }; @@ -144,7 +139,16 @@ static struct regmap_irq_chip bxtwc_regmap_irq_chip = { .mask_base = BXTWC_MIRQLVL1, .irqs = bxtwc_regmap_irqs, .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs), - .num_regs = 2, + .num_regs = 1, +}; + +static struct regmap_irq_chip bxtwc_regmap_irq_chip_pwrbtn = { + .name = "bxtwc_irq_chip_pwrbtn", + .status_base = BXTWC_PWRBTNIRQ, + .mask_base = BXTWC_MPWRBTNIRQ, + .irqs = bxtwc_regmap_irqs_pwrbtn, + .num_irqs = ARRAY_SIZE(bxtwc_regmap_irqs_pwrbtn), + .num_regs = 1, }; static struct regmap_irq_chip bxtwc_regmap_irq_chip_tmu = { @@ -473,6 +477,16 @@ static int bxtwc_probe(struct platform_device *pdev) } ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, + BXTWC_PWRBTN_LVL1_IRQ, + IRQF_ONESHOT, + &bxtwc_regmap_irq_chip_pwrbtn, + &pmic->irq_chip_data_pwrbtn); + if (ret) { + dev_err(&pdev->dev, "Failed to add PWRBTN IRQ chip\n"); + return ret; + } + + ret = bxtwc_add_chained_irq_chip(pmic, pmic->irq_chip_data, BXTWC_TMU_LVL1_IRQ, IRQF_ONESHOT, &bxtwc_regmap_irq_chip_tmu, diff --git a/drivers/mfd/intel_soc_pmic_chtdc_ti.c b/drivers/mfd/intel_soc_pmic_chtdc_ti.c index 861277c6580a..64b5c3cc30e7 100644 --- a/drivers/mfd/intel_soc_pmic_chtdc_ti.c +++ b/drivers/mfd/intel_soc_pmic_chtdc_ti.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Device access for Dollar Cove TI PMIC * @@ -6,10 +7,6 @@ * * Cleanup and forward-ported * Copyright (c) 2017 Takashi Iwai <tiwai@suse.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/mfd/intel_soc_pmic_chtwc.c b/drivers/mfd/intel_soc_pmic_chtwc.c index b35da01d5bcf..64a3aece9c5e 100644 --- a/drivers/mfd/intel_soc_pmic_chtwc.c +++ b/drivers/mfd/intel_soc_pmic_chtwc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * MFD core driver for Intel Cherrytrail Whiskey Cove PMIC * @@ -5,10 +6,6 @@ * * Based on various non upstream patches to support the CHT Whiskey Cove PMIC: * Copyright (C) 2013-2015 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/acpi.h> diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c index 274306d98ac1..c9f35378d391 100644 --- a/drivers/mfd/intel_soc_pmic_core.c +++ b/drivers/mfd/intel_soc_pmic_core.c @@ -1,31 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_soc_pmic_core.c - Intel SoC PMIC MFD Driver + * Intel SoC PMIC MFD Driver * * Copyright (C) 2013, 2014 Intel Corporation. All rights reserved. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that 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. - * * Author: Yang, Bin <bin.yang@intel.com> * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> */ -#include <linux/module.h> -#include <linux/mfd/core.h> +#include <linux/acpi.h> +#include <linux/gpio/consumer.h> +#include <linux/gpio/machine.h> #include <linux/i2c.h> #include <linux/interrupt.h> -#include <linux/gpio/consumer.h> -#include <linux/acpi.h> -#include <linux/regmap.h> +#include <linux/module.h> +#include <linux/mfd/core.h> #include <linux/mfd/intel_soc_pmic.h> -#include <linux/gpio/machine.h> #include <linux/pwm.h> +#include <linux/regmap.h> + #include "intel_soc_pmic_core.h" /* Crystal Cove PMIC shares same ACPI ID between different platforms */ diff --git a/drivers/mfd/intel_soc_pmic_core.h b/drivers/mfd/intel_soc_pmic_core.h index 90a1416d4dac..d490685845eb 100644 --- a/drivers/mfd/intel_soc_pmic_core.h +++ b/drivers/mfd/intel_soc_pmic_core.h @@ -1,17 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* - * intel_soc_pmic_core.h - Intel SoC PMIC MFD Driver + * Intel SoC PMIC MFD Driver * * Copyright (C) 2012-2014 Intel Corporation. All rights reserved. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that 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. - * * Author: Yang, Bin <bin.yang@intel.com> * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> */ diff --git a/drivers/mfd/intel_soc_pmic_crc.c b/drivers/mfd/intel_soc_pmic_crc.c index 6d19a6d0fb97..b6ab72fa0569 100644 --- a/drivers/mfd/intel_soc_pmic_crc.c +++ b/drivers/mfd/intel_soc_pmic_crc.c @@ -1,25 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * intel_soc_pmic_crc.c - Device access for Crystal Cove PMIC + * Device access for Crystal Cove PMIC * * Copyright (C) 2013, 2014 Intel Corporation. All rights reserved. * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that 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. - * * Author: Yang, Bin <bin.yang@intel.com> * Author: Zhu, Lejun <lejun.zhu@linux.intel.com> */ -#include <linux/mfd/core.h> #include <linux/interrupt.h> #include <linux/regmap.h> +#include <linux/mfd/core.h> #include <linux/mfd/intel_soc_pmic.h> + #include "intel_soc_pmic_core.h" #define CRYSTAL_COVE_MAX_REGISTER 0xC6 @@ -36,48 +29,23 @@ #define CRYSTAL_COVE_IRQ_VHDMIOCP 6 static struct resource gpio_resources[] = { - { - .name = "GPIO", - .start = CRYSTAL_COVE_IRQ_GPIO, - .end = CRYSTAL_COVE_IRQ_GPIO, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"), }; static struct resource pwrsrc_resources[] = { - { - .name = "PWRSRC", - .start = CRYSTAL_COVE_IRQ_PWRSRC, - .end = CRYSTAL_COVE_IRQ_PWRSRC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_PWRSRC, "PWRSRC"), }; static struct resource adc_resources[] = { - { - .name = "ADC", - .start = CRYSTAL_COVE_IRQ_ADC, - .end = CRYSTAL_COVE_IRQ_ADC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"), }; static struct resource thermal_resources[] = { - { - .name = "THERMAL", - .start = CRYSTAL_COVE_IRQ_THRM, - .end = CRYSTAL_COVE_IRQ_THRM, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_THRM, "THERMAL"), }; static struct resource bcu_resources[] = { - { - .name = "BCU", - .start = CRYSTAL_COVE_IRQ_BCU, - .end = CRYSTAL_COVE_IRQ_BCU, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_BCU, "BCU"), }; static struct mfd_cell crystal_cove_byt_dev[] = { @@ -134,27 +102,13 @@ static const struct regmap_config crystal_cove_regmap_config = { }; static const struct regmap_irq crystal_cove_irqs[] = { - [CRYSTAL_COVE_IRQ_PWRSRC] = { - .mask = BIT(CRYSTAL_COVE_IRQ_PWRSRC), - }, - [CRYSTAL_COVE_IRQ_THRM] = { - .mask = BIT(CRYSTAL_COVE_IRQ_THRM), - }, - [CRYSTAL_COVE_IRQ_BCU] = { - .mask = BIT(CRYSTAL_COVE_IRQ_BCU), - }, - [CRYSTAL_COVE_IRQ_ADC] = { - .mask = BIT(CRYSTAL_COVE_IRQ_ADC), - }, - [CRYSTAL_COVE_IRQ_CHGR] = { - .mask = BIT(CRYSTAL_COVE_IRQ_CHGR), - }, - [CRYSTAL_COVE_IRQ_GPIO] = { - .mask = BIT(CRYSTAL_COVE_IRQ_GPIO), - }, - [CRYSTAL_COVE_IRQ_VHDMIOCP] = { - .mask = BIT(CRYSTAL_COVE_IRQ_VHDMIOCP), - }, + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_PWRSRC, 0, BIT(CRYSTAL_COVE_IRQ_PWRSRC)), + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_THRM, 0, BIT(CRYSTAL_COVE_IRQ_THRM)), + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_BCU, 0, BIT(CRYSTAL_COVE_IRQ_BCU)), + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_ADC, 0, BIT(CRYSTAL_COVE_IRQ_ADC)), + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_CHGR, 0, BIT(CRYSTAL_COVE_IRQ_CHGR)), + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_GPIO, 0, BIT(CRYSTAL_COVE_IRQ_GPIO)), + REGMAP_IRQ_REG(CRYSTAL_COVE_IRQ_VHDMIOCP, 0, BIT(CRYSTAL_COVE_IRQ_VHDMIOCP)), }; static const struct regmap_irq_chip crystal_cove_irq_chip = { diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c index 8cfea969b060..440030cecbbd 100644 --- a/drivers/mfd/madera-core.c +++ b/drivers/mfd/madera-core.c @@ -132,32 +132,39 @@ const char *madera_name_from_type(enum madera_type type) } EXPORT_SYMBOL_GPL(madera_name_from_type); -#define MADERA_BOOT_POLL_MAX_INTERVAL_US 5000 -#define MADERA_BOOT_POLL_TIMEOUT_US 25000 +#define MADERA_BOOT_POLL_INTERVAL_USEC 5000 +#define MADERA_BOOT_POLL_TIMEOUT_USEC 25000 static int madera_wait_for_boot(struct madera *madera) { + ktime_t timeout; unsigned int val; - int ret; + int ret = 0; /* * We can't use an interrupt as we need to runtime resume to do so, * so we poll the status bit. This won't race with the interrupt * handler because it will be blocked on runtime resume. + * The chip could NAK a read request while it is booting so ignore + * errors from regmap_read. */ - ret = regmap_read_poll_timeout(madera->regmap, - MADERA_IRQ1_RAW_STATUS_1, - val, - (val & MADERA_BOOT_DONE_STS1), - MADERA_BOOT_POLL_MAX_INTERVAL_US, - MADERA_BOOT_POLL_TIMEOUT_US); - - if (ret) - dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret); + timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC); + regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val); + while (!(val & MADERA_BOOT_DONE_STS1) && + !ktime_after(ktime_get(), timeout)) { + usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2, + MADERA_BOOT_POLL_INTERVAL_USEC); + regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val); + }; + + if (!(val & MADERA_BOOT_DONE_STS1)) { + dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n"); + ret = -ETIMEDOUT; + } /* * BOOT_DONE defaults to unmasked on boot so we must ack it. - * Do this unconditionally to avoid interrupt storms. + * Do this even after a timeout to avoid interrupt storms. */ regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1, MADERA_BOOT_DONE_EINT1); diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 6cbe96b28f42..ebb13d5de530 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c @@ -1,22 +1,12 @@ -/* - * max14577.c - mfd core driver for the Maxim 14577/77836 - * - * Copyright (C) 2014 Samsung Electronics - * Chanwoo Choi <cw00.choi@samsung.com> - * Krzysztof Kozlowski <krzk@kernel.org> - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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. - * - * This driver is based on max8997.c - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// max14577.c - mfd core driver for the Maxim 14577/77836 +// +// Copyright (C) 2014 Samsung Electronics +// Chanwoo Choi <cw00.choi@samsung.com> +// Krzysztof Kozlowski <krzk@kernel.org> +// +// This driver is based on max8997.c #include <linux/err.h> #include <linux/module.h> diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c index b1700b5fa640..d8217366ed36 100644 --- a/drivers/mfd/max77620.c +++ b/drivers/mfd/max77620.c @@ -285,7 +285,7 @@ static int max77620_config_fps(struct max77620_chip *chip, } if (fps_id == MAX77620_FPS_COUNT) { - dev_err(dev, "FPS node name %s is not valid\n", fps_np->name); + dev_err(dev, "FPS node name %pOFn is not valid\n", fps_np); return -EINVAL; } diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index b0e8e13c0049..71faf503844b 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c @@ -1,26 +1,12 @@ -/* - * max77686.c - mfd core driver for the Maxim 77686/802 - * - * Copyright (C) 2012 Samsung Electronics - * Chiwoong Byun <woong.byun@samsung.com> - * Jonghwa Lee <jonghwa3.lee@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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8997.c - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// max77686.c - mfd core driver for the Maxim 77686/802 +// +// Copyright (C) 2012 Samsung Electronics +// Chiwoong Byun <woong.byun@samsung.com> +// Jonghwa Lee <jonghwa3.lee@samsung.com> +// +//This driver is based on max8997.c #include <linux/export.h> #include <linux/slab.h> diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index 1c05ea0cba61..901d99d65924 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c @@ -1,27 +1,13 @@ -/* - * max77693.c - mfd core driver for the MAX 77693 - * - * Copyright (C) 2012 Samsung Electronics - * SangYoung Son <hello.son@samsung.com> - * - * This program is not provided / owned by Maxim Integrated Products. - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8997.c - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// max77693.c - mfd core driver for the MAX 77693 +// +// Copyright (C) 2012 Samsung Electronics +// SangYoung Son <hello.son@samsung.com> +// +// This program is not provided / owned by Maxim Integrated Products. +// +// This driver is based on max8997.c #include <linux/module.h> #include <linux/slab.h> diff --git a/drivers/mfd/max77843.c b/drivers/mfd/max77843.c index da9612dbb222..25cbb2242b26 100644 --- a/drivers/mfd/max77843.c +++ b/drivers/mfd/max77843.c @@ -1,15 +1,10 @@ -/* - * MFD core driver for the Maxim MAX77843 - * - * Copyright (C) 2015 Samsung Electronics - * Author: Jaewon Kim <jaewon02.kim@samsung.com> - * Author: Beomho Seo <beomho.seo@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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// MFD core driver for the Maxim MAX77843 +// +// Copyright (C) 2015 Samsung Electronics +// Author: Jaewon Kim <jaewon02.kim@samsung.com> +// Author: Beomho Seo <beomho.seo@samsung.com> #include <linux/err.h> #include <linux/i2c.h> diff --git a/drivers/mfd/max8997-irq.c b/drivers/mfd/max8997-irq.c index 326f17b632a7..93a3b1698d9c 100644 --- a/drivers/mfd/max8997-irq.c +++ b/drivers/mfd/max8997-irq.c @@ -1,25 +1,11 @@ -/* - * max8997-irq.c - Interrupt controller support for MAX8997 - * - * Copyright (C) 2011 Samsung Electronics Co.Ltd - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8998-irq.c - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// max8997-irq.c - Interrupt controller support for MAX8997 +// +// Copyright (C) 2011 Samsung Electronics Co.Ltd +// MyungJoo Ham <myungjoo.ham@samsung.com> +// +// This driver is based on max8998-irq.c #include <linux/err.h> #include <linux/irq.h> diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 3f554c447521..8c06c09e36d1 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -1,25 +1,11 @@ -/* - * max8997.c - mfd core driver for the Maxim 8966 and 8997 - * - * Copyright (C) 2011 Samsung Electronics - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This driver is based on max8998.c - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// max8997.c - mfd core driver for the Maxim 8966 and 8997 +// +// Copyright (C) 2011 Samsung Electronics +// MyungJoo Ham <myungjoo.ham@samsung.com> +// +// This driver is based on max8998.c #include <linux/err.h> #include <linux/slab.h> @@ -153,12 +139,6 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( pd->ono = irq_of_parse_and_map(dev->of_node, 1); - /* - * ToDo: the 'wakeup' member in the platform data is more of a linux - * specfic information. Hence, there is no binding for that yet and - * not parsed here. - */ - return pd; } @@ -246,7 +226,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c, */ /* MAX8997 has a power button input. */ - device_init_wakeup(max8997->dev, pdata->wakeup); + device_init_wakeup(max8997->dev, true); return ret; @@ -468,6 +448,7 @@ static int max8997_suspend(struct device *dev) struct i2c_client *i2c = to_i2c_client(dev); struct max8997_dev *max8997 = i2c_get_clientdata(i2c); + disable_irq(max8997->irq); if (device_may_wakeup(dev)) irq_set_irq_wake(max8997->irq, 1); return 0; @@ -480,6 +461,7 @@ static int max8997_resume(struct device *dev) if (device_may_wakeup(dev)) irq_set_irq_wake(max8997->irq, 0); + enable_irq(max8997->irq); return max8997_irq_resume(max8997); } diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c index 90bad9ffa7e2..83b6f510bc05 100644 --- a/drivers/mfd/max8998-irq.c +++ b/drivers/mfd/max8998-irq.c @@ -1,15 +1,9 @@ -/* - * Interrupt controller support for MAX8998 - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Joonyoung Shim <jy0922.shim@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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Interrupt controller support for MAX8998 +// +// Copyright (C) 2010 Samsung Electronics Co.Ltd +// Author: Joonyoung Shim <jy0922.shim@samsung.com> #include <linux/device.h> #include <linux/interrupt.h> diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index b1d3f70782d9..56409df120f8 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -1,24 +1,10 @@ -/* - * max8998.c - mfd core driver for the Maxim 8998 - * - * Copyright (C) 2009-2010 Samsung Electronics - * Kyungmin Park <kyungmin.park@samsung.com> - * Marek Szyprowski <m.szyprowski@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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// max8998.c - mfd core driver for the Maxim 8998 +// +// Copyright (C) 2009-2010 Samsung Electronics +// Kyungmin Park <kyungmin.park@samsung.com> +// Marek Szyprowski <m.szyprowski@samsung.com> #include <linux/err.h> #include <linux/init.h> diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index c63e331738c1..f475e848252f 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c @@ -276,7 +276,8 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0); - adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2; + adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2 | + MC13XXX_ADC0_CHRGRAWDIV; adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC; /* diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c index cbc1e5ed599c..ee3411cc5ce4 100644 --- a/drivers/mfd/mc13xxx-spi.c +++ b/drivers/mfd/mc13xxx-spi.c @@ -57,7 +57,8 @@ static const struct regmap_config mc13xxx_regmap_spi_config = { .max_register = MC13XXX_NUMREGS, .cache_type = REGCACHE_NONE, - .use_single_rw = 1, + .use_single_read = true, + .use_single_write = true, }; static int mc13xxx_spi_read(void *context, const void *reg, size_t reg_size, diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index 29b7164a823b..d28ebe7ecd21 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c @@ -1094,6 +1094,7 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m) static inline void menelaus_rtc_init(struct menelaus_chip *m) { int alarm = (m->client->irq > 0); + int err; /* assume 32KDETEN pin is pulled high */ if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) { @@ -1101,6 +1102,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m) return; } + m->rtc = devm_rtc_allocate_device(&m->client->dev); + if (IS_ERR(m->rtc)) + return; + + m->rtc->ops = &menelaus_rtc_ops; + /* support RTC alarm; it can issue wakeups */ if (alarm) { if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ, @@ -1125,10 +1132,8 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m) menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control); } - m->rtc = rtc_device_register(DRIVER_NAME, - &m->client->dev, - &menelaus_rtc_ops, THIS_MODULE); - if (IS_ERR(m->rtc)) { + err = rtc_register_device(m->rtc); + if (err) { if (alarm) { menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ); device_init_wakeup(&m->client->dev, 0); diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index 5276911caaec..20d9692640e1 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -18,6 +18,7 @@ #include <linux/regmap.h> #include <linux/sysfs.h> +#include <linux/mfd/core.h> #include <linux/mfd/motorola-cpcap.h> #include <linux/spi/spi.h> @@ -216,6 +217,53 @@ static const struct regmap_config cpcap_regmap_config = { .val_format_endian = REGMAP_ENDIAN_LITTLE, }; +static const struct mfd_cell cpcap_mfd_devices[] = { + { + .name = "cpcap_adc", + .of_compatible = "motorola,mapphone-cpcap-adc", + }, { + .name = "cpcap_battery", + .of_compatible = "motorola,cpcap-battery", + }, { + .name = "cpcap-charger", + .of_compatible = "motorola,mapphone-cpcap-charger", + }, { + .name = "cpcap-regulator", + .of_compatible = "motorola,mapphone-cpcap-regulator", + }, { + .name = "cpcap-rtc", + .of_compatible = "motorola,cpcap-rtc", + }, { + .name = "cpcap-pwrbutton", + .of_compatible = "motorola,cpcap-pwrbutton", + }, { + .name = "cpcap-usb-phy", + .of_compatible = "motorola,mapphone-cpcap-usb-phy", + }, { + .name = "cpcap-led", + .id = 0, + .of_compatible = "motorola,cpcap-led-red", + }, { + .name = "cpcap-led", + .id = 1, + .of_compatible = "motorola,cpcap-led-green", + }, { + .name = "cpcap-led", + .id = 2, + .of_compatible = "motorola,cpcap-led-blue", + }, { + .name = "cpcap-led", + .id = 3, + .of_compatible = "motorola,cpcap-led-adl", + }, { + .name = "cpcap-led", + .id = 4, + .of_compatible = "motorola,cpcap-led-cp", + }, { + .name = "cpcap-codec", + } +}; + static int cpcap_probe(struct spi_device *spi) { const struct of_device_id *match; @@ -260,7 +308,8 @@ static int cpcap_probe(struct spi_device *spi) if (ret) return ret; - return devm_of_platform_populate(&cpcap->spi->dev); + return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, + ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL); } static struct spi_driver cpcap_driver = { diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c index 75c8ec659547..a29d529a96f4 100644 --- a/drivers/mfd/rohm-bd718x7.c +++ b/drivers/mfd/rohm-bd718x7.c @@ -2,26 +2,21 @@ // // Copyright (C) 2018 ROHM Semiconductors // -// ROHM BD71837MWV PMIC driver +// ROHM BD71837MWV and BD71847MWV PMIC driver // -// Datasheet available from +// Datasheet for BD71837MWV available from // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e +#include <linux/gpio_keys.h> #include <linux/i2c.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/mfd/rohm-bd718x7.h> #include <linux/mfd/core.h> #include <linux/module.h> +#include <linux/of_device.h> #include <linux/regmap.h> - -/* - * gpio_keys.h requires definiton of bool. It is brought in - * by above includes. Keep this as last until gpio_keys.h gets fixed. - */ -#include <linux/gpio_keys.h> - -static const u8 supported_revisions[] = { 0xA2 /* BD71837 */ }; +#include <linux/types.h> static struct gpio_keys_button button = { .code = KEY_POWER, @@ -35,42 +30,42 @@ static struct gpio_keys_platform_data bd718xx_powerkey_data = { .name = "bd718xx-pwrkey", }; -static struct mfd_cell bd71837_mfd_cells[] = { +static struct mfd_cell bd718xx_mfd_cells[] = { { .name = "gpio-keys", .platform_data = &bd718xx_powerkey_data, .pdata_size = sizeof(bd718xx_powerkey_data), }, - { .name = "bd71837-clk", }, - { .name = "bd71837-pmic", }, + { .name = "bd718xx-clk", }, + { .name = "bd718xx-pmic", }, }; -static const struct regmap_irq bd71837_irqs[] = { - REGMAP_IRQ_REG(BD71837_INT_SWRST, 0, BD71837_INT_SWRST_MASK), - REGMAP_IRQ_REG(BD71837_INT_PWRBTN_S, 0, BD71837_INT_PWRBTN_S_MASK), - REGMAP_IRQ_REG(BD71837_INT_PWRBTN_L, 0, BD71837_INT_PWRBTN_L_MASK), - REGMAP_IRQ_REG(BD71837_INT_PWRBTN, 0, BD71837_INT_PWRBTN_MASK), - REGMAP_IRQ_REG(BD71837_INT_WDOG, 0, BD71837_INT_WDOG_MASK), - REGMAP_IRQ_REG(BD71837_INT_ON_REQ, 0, BD71837_INT_ON_REQ_MASK), - REGMAP_IRQ_REG(BD71837_INT_STBY_REQ, 0, BD71837_INT_STBY_REQ_MASK), +static const struct regmap_irq bd718xx_irqs[] = { + REGMAP_IRQ_REG(BD718XX_INT_SWRST, 0, BD718XX_INT_SWRST_MASK), + REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_S, 0, BD718XX_INT_PWRBTN_S_MASK), + REGMAP_IRQ_REG(BD718XX_INT_PWRBTN_L, 0, BD718XX_INT_PWRBTN_L_MASK), + REGMAP_IRQ_REG(BD718XX_INT_PWRBTN, 0, BD718XX_INT_PWRBTN_MASK), + REGMAP_IRQ_REG(BD718XX_INT_WDOG, 0, BD718XX_INT_WDOG_MASK), + REGMAP_IRQ_REG(BD718XX_INT_ON_REQ, 0, BD718XX_INT_ON_REQ_MASK), + REGMAP_IRQ_REG(BD718XX_INT_STBY_REQ, 0, BD718XX_INT_STBY_REQ_MASK), }; -static struct regmap_irq_chip bd71837_irq_chip = { - .name = "bd71837-irq", - .irqs = bd71837_irqs, - .num_irqs = ARRAY_SIZE(bd71837_irqs), +static struct regmap_irq_chip bd718xx_irq_chip = { + .name = "bd718xx-irq", + .irqs = bd718xx_irqs, + .num_irqs = ARRAY_SIZE(bd718xx_irqs), .num_regs = 1, .irq_reg_stride = 1, - .status_base = BD71837_REG_IRQ, - .mask_base = BD71837_REG_MIRQ, - .ack_base = BD71837_REG_IRQ, + .status_base = BD718XX_REG_IRQ, + .mask_base = BD718XX_REG_MIRQ, + .ack_base = BD718XX_REG_IRQ, .init_ack_masked = true, .mask_invert = false, }; static const struct regmap_range pmic_status_range = { - .range_min = BD71837_REG_IRQ, - .range_max = BD71837_REG_POW_STATE, + .range_min = BD718XX_REG_IRQ, + .range_max = BD718XX_REG_POW_STATE, }; static const struct regmap_access_table volatile_regs = { @@ -78,67 +73,53 @@ static const struct regmap_access_table volatile_regs = { .n_yes_ranges = 1, }; -static const struct regmap_config bd71837_regmap_config = { +static const struct regmap_config bd718xx_regmap_config = { .reg_bits = 8, .val_bits = 8, .volatile_table = &volatile_regs, - .max_register = BD71837_MAX_REGISTER - 1, + .max_register = BD718XX_MAX_REGISTER - 1, .cache_type = REGCACHE_RBTREE, }; -static int bd71837_i2c_probe(struct i2c_client *i2c, +static int bd718xx_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct bd71837 *bd71837; - int ret, i; - unsigned int val; - - bd71837 = devm_kzalloc(&i2c->dev, sizeof(struct bd71837), GFP_KERNEL); + struct bd718xx *bd718xx; + int ret; - if (!bd71837) - return -ENOMEM; - - bd71837->chip_irq = i2c->irq; - - if (!bd71837->chip_irq) { + if (!i2c->irq) { dev_err(&i2c->dev, "No IRQ configured\n"); return -EINVAL; } - bd71837->dev = &i2c->dev; - dev_set_drvdata(&i2c->dev, bd71837); + bd718xx = devm_kzalloc(&i2c->dev, sizeof(struct bd718xx), GFP_KERNEL); - bd71837->regmap = devm_regmap_init_i2c(i2c, &bd71837_regmap_config); - if (IS_ERR(bd71837->regmap)) { - dev_err(&i2c->dev, "regmap initialization failed\n"); - return PTR_ERR(bd71837->regmap); - } + if (!bd718xx) + return -ENOMEM; - ret = regmap_read(bd71837->regmap, BD71837_REG_REV, &val); - if (ret) { - dev_err(&i2c->dev, "Read BD71837_REG_DEVICE failed\n"); - return ret; - } - for (i = 0; i < ARRAY_SIZE(supported_revisions); i++) - if (supported_revisions[i] == val) - break; + bd718xx->chip_irq = i2c->irq; + bd718xx->chip_type = (unsigned int)(uintptr_t) + of_device_get_match_data(&i2c->dev); + bd718xx->dev = &i2c->dev; + dev_set_drvdata(&i2c->dev, bd718xx); - if (i == ARRAY_SIZE(supported_revisions)) { - dev_err(&i2c->dev, "Unsupported chip revision\n"); - return -ENODEV; + bd718xx->regmap = devm_regmap_init_i2c(i2c, &bd718xx_regmap_config); + if (IS_ERR(bd718xx->regmap)) { + dev_err(&i2c->dev, "regmap initialization failed\n"); + return PTR_ERR(bd718xx->regmap); } - ret = devm_regmap_add_irq_chip(&i2c->dev, bd71837->regmap, - bd71837->chip_irq, IRQF_ONESHOT, 0, - &bd71837_irq_chip, &bd71837->irq_data); + ret = devm_regmap_add_irq_chip(&i2c->dev, bd718xx->regmap, + bd718xx->chip_irq, IRQF_ONESHOT, 0, + &bd718xx_irq_chip, &bd718xx->irq_data); if (ret) { dev_err(&i2c->dev, "Failed to add irq_chip\n"); return ret; } /* Configure short press to 10 milliseconds */ - ret = regmap_update_bits(bd71837->regmap, - BD71837_REG_PWRONCONFIG0, + ret = regmap_update_bits(bd718xx->regmap, + BD718XX_REG_PWRONCONFIG0, BD718XX_PWRBTN_PRESS_DURATION_MASK, BD718XX_PWRBTN_SHORT_PRESS_10MS); if (ret) { @@ -148,8 +129,8 @@ static int bd71837_i2c_probe(struct i2c_client *i2c, } /* Configure long press to 10 seconds */ - ret = regmap_update_bits(bd71837->regmap, - BD71837_REG_PWRONCONFIG1, + ret = regmap_update_bits(bd718xx->regmap, + BD718XX_REG_PWRONCONFIG1, BD718XX_PWRBTN_PRESS_DURATION_MASK, BD718XX_PWRBTN_LONG_PRESS_10S); @@ -159,7 +140,7 @@ static int bd71837_i2c_probe(struct i2c_client *i2c, return ret; } - ret = regmap_irq_get_virq(bd71837->irq_data, BD71837_INT_PWRBTN_S); + ret = regmap_irq_get_virq(bd718xx->irq_data, BD718XX_INT_PWRBTN_S); if (ret < 0) { dev_err(&i2c->dev, "Failed to get the IRQ\n"); @@ -168,44 +149,51 @@ static int bd71837_i2c_probe(struct i2c_client *i2c, button.irq = ret; - ret = devm_mfd_add_devices(bd71837->dev, PLATFORM_DEVID_AUTO, - bd71837_mfd_cells, - ARRAY_SIZE(bd71837_mfd_cells), NULL, 0, - regmap_irq_get_domain(bd71837->irq_data)); + ret = devm_mfd_add_devices(bd718xx->dev, PLATFORM_DEVID_AUTO, + bd718xx_mfd_cells, + ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0, + regmap_irq_get_domain(bd718xx->irq_data)); if (ret) dev_err(&i2c->dev, "Failed to create subdevices\n"); return ret; } -static const struct of_device_id bd71837_of_match[] = { - { .compatible = "rohm,bd71837", }, +static const struct of_device_id bd718xx_of_match[] = { + { + .compatible = "rohm,bd71837", + .data = (void *)BD718XX_TYPE_BD71837, + }, + { + .compatible = "rohm,bd71847", + .data = (void *)BD718XX_TYPE_BD71847, + }, { } }; -MODULE_DEVICE_TABLE(of, bd71837_of_match); +MODULE_DEVICE_TABLE(of, bd718xx_of_match); -static struct i2c_driver bd71837_i2c_driver = { +static struct i2c_driver bd718xx_i2c_driver = { .driver = { .name = "rohm-bd718x7", - .of_match_table = bd71837_of_match, + .of_match_table = bd718xx_of_match, }, - .probe = bd71837_i2c_probe, + .probe = bd718xx_i2c_probe, }; -static int __init bd71837_i2c_init(void) +static int __init bd718xx_i2c_init(void) { - return i2c_add_driver(&bd71837_i2c_driver); + return i2c_add_driver(&bd718xx_i2c_driver); } /* Initialise early so consumer devices can complete system boot */ -subsys_initcall(bd71837_i2c_init); +subsys_initcall(bd718xx_i2c_init); -static void __exit bd71837_i2c_exit(void) +static void __exit bd718xx_i2c_exit(void) { - i2c_del_driver(&bd71837_i2c_driver); + i2c_del_driver(&bd718xx_i2c_driver); } -module_exit(bd71837_i2c_exit); +module_exit(bd718xx_i2c_exit); MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); -MODULE_DESCRIPTION("ROHM BD71837 Power Management IC driver"); +MODULE_DESCRIPTION("ROHM BD71837/BD71847 Power Management IC driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 9613b4257302..e0835c9df7a1 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -1,15 +1,7 @@ -/* - * sec-core.c - * - * Copyright (c) 2012 Samsung Electronics Co., Ltd - * http://www.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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (c) 2012 Samsung Electronics Co., Ltd +// http://www.samsung.com #include <linux/module.h> #include <linux/moduleparam.h> diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index 5eb59c233d52..ad0099077e7e 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c @@ -1,19 +1,12 @@ -/* - * sec-irq.c - * - * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd - * http://www.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 the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Copyright (c) 2011-2014 Samsung Electronics Co., Ltd +// http://www.samsung.com #include <linux/device.h> #include <linux/interrupt.h> #include <linux/irq.h> +#include <linux/module.h> #include <linux/regmap.h> #include <linux/mfd/samsung/core.h> @@ -501,3 +494,10 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) return 0; } +EXPORT_SYMBOL_GPL(sec_irq_init); + +MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); +MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); +MODULE_AUTHOR("Krzysztof Kozlowski <krzk@kernel.org>"); +MODULE_DESCRIPTION("Interrupt support for the S5M MFD"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/ti-lmu.c b/drivers/mfd/ti-lmu.c index cfb411cde51c..37d0bdb291c3 100644 --- a/drivers/mfd/ti-lmu.c +++ b/drivers/mfd/ti-lmu.c @@ -12,7 +12,7 @@ #include <linux/delay.h> #include <linux/err.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> #include <linux/i2c.h> #include <linux/kernel.h> #include <linux/mfd/core.h> @@ -21,28 +21,18 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> -#include <linux/of_gpio.h> #include <linux/slab.h> struct ti_lmu_data { - struct mfd_cell *cells; + const struct mfd_cell *cells; int num_cells; unsigned int max_register; }; static int ti_lmu_enable_hw(struct ti_lmu *lmu, enum ti_lmu_id id) { - int ret; - - if (gpio_is_valid(lmu->en_gpio)) { - ret = devm_gpio_request_one(lmu->dev, lmu->en_gpio, - GPIOF_OUT_INIT_HIGH, "lmu_hwen"); - if (ret) { - dev_err(lmu->dev, "Can not request enable GPIO: %d\n", - ret); - return ret; - } - } + if (lmu->en_gpio) + gpiod_set_value(lmu->en_gpio, 1); /* Delay about 1ms after HW enable pin control */ usleep_range(1000, 1500); @@ -57,13 +47,14 @@ static int ti_lmu_enable_hw(struct ti_lmu *lmu, enum ti_lmu_id id) return 0; } -static void ti_lmu_disable_hw(struct ti_lmu *lmu) +static void ti_lmu_disable_hw(void *data) { - if (gpio_is_valid(lmu->en_gpio)) - gpio_set_value(lmu->en_gpio, 0); + struct ti_lmu *lmu = data; + if (lmu->en_gpio) + gpiod_set_value(lmu->en_gpio, 0); } -static struct mfd_cell lm3532_devices[] = { +static const struct mfd_cell lm3532_devices[] = { { .name = "ti-lmu-backlight", .id = LM3532, @@ -78,7 +69,7 @@ static struct mfd_cell lm3532_devices[] = { .of_compatible = "ti,lm363x-regulator", \ } \ -static struct mfd_cell lm3631_devices[] = { +static const struct mfd_cell lm3631_devices[] = { LM363X_REGULATOR(LM3631_BOOST), LM363X_REGULATOR(LM3631_LDO_CONT), LM363X_REGULATOR(LM3631_LDO_OREF), @@ -91,7 +82,7 @@ static struct mfd_cell lm3631_devices[] = { }, }; -static struct mfd_cell lm3632_devices[] = { +static const struct mfd_cell lm3632_devices[] = { LM363X_REGULATOR(LM3632_BOOST), LM363X_REGULATOR(LM3632_LDO_POS), LM363X_REGULATOR(LM3632_LDO_NEG), @@ -102,7 +93,7 @@ static struct mfd_cell lm3632_devices[] = { }, }; -static struct mfd_cell lm3633_devices[] = { +static const struct mfd_cell lm3633_devices[] = { { .name = "ti-lmu-backlight", .id = LM3633, @@ -120,7 +111,7 @@ static struct mfd_cell lm3633_devices[] = { }, }; -static struct mfd_cell lm3695_devices[] = { +static const struct mfd_cell lm3695_devices[] = { { .name = "ti-lmu-backlight", .id = LM3695, @@ -128,7 +119,7 @@ static struct mfd_cell lm3695_devices[] = { }, }; -static struct mfd_cell lm3697_devices[] = { +static const struct mfd_cell lm3697_devices[] = { { .name = "ti-lmu-backlight", .id = LM3697, @@ -157,34 +148,21 @@ TI_LMU_DATA(lm3633, LM3633_MAX_REG); TI_LMU_DATA(lm3695, LM3695_MAX_REG); TI_LMU_DATA(lm3697, LM3697_MAX_REG); -static const struct of_device_id ti_lmu_of_match[] = { - { .compatible = "ti,lm3532", .data = &lm3532_data }, - { .compatible = "ti,lm3631", .data = &lm3631_data }, - { .compatible = "ti,lm3632", .data = &lm3632_data }, - { .compatible = "ti,lm3633", .data = &lm3633_data }, - { .compatible = "ti,lm3695", .data = &lm3695_data }, - { .compatible = "ti,lm3697", .data = &lm3697_data }, - { } -}; -MODULE_DEVICE_TABLE(of, ti_lmu_of_match); - static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id) { struct device *dev = &cl->dev; - const struct of_device_id *match; const struct ti_lmu_data *data; struct regmap_config regmap_cfg; struct ti_lmu *lmu; int ret; - match = of_match_device(ti_lmu_of_match, dev); - if (!match) - return -ENODEV; /* * Get device specific data from of_match table. * This data is defined by using TI_LMU_DATA() macro. */ - data = (struct ti_lmu_data *)match->data; + data = of_device_get_match_data(dev); + if (!data) + return -ENODEV; lmu = devm_kzalloc(dev, sizeof(*lmu), GFP_KERNEL); if (!lmu) @@ -204,11 +182,21 @@ static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id) return PTR_ERR(lmu->regmap); /* HW enable pin control and additional power up sequence if required */ - lmu->en_gpio = of_get_named_gpio(dev->of_node, "enable-gpios", 0); + lmu->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(lmu->en_gpio)) { + ret = PTR_ERR(lmu->en_gpio); + dev_err(dev, "Can not request enable GPIO: %d\n", ret); + return ret; + } + ret = ti_lmu_enable_hw(lmu, id->driver_data); if (ret) return ret; + ret = devm_add_action_or_reset(dev, ti_lmu_disable_hw, lmu); + if (ret) + return ret; + /* * Fault circuit(open/short) can be detected by ti-lmu-fault-monitor. * After fault detection is done, some devices should re-initialize @@ -218,18 +206,20 @@ static int ti_lmu_probe(struct i2c_client *cl, const struct i2c_device_id *id) i2c_set_clientdata(cl, lmu); - return mfd_add_devices(lmu->dev, 0, data->cells, - data->num_cells, NULL, 0, NULL); + return devm_mfd_add_devices(lmu->dev, 0, data->cells, + data->num_cells, NULL, 0, NULL); } -static int ti_lmu_remove(struct i2c_client *cl) -{ - struct ti_lmu *lmu = i2c_get_clientdata(cl); - - ti_lmu_disable_hw(lmu); - mfd_remove_devices(lmu->dev); - return 0; -} +static const struct of_device_id ti_lmu_of_match[] = { + { .compatible = "ti,lm3532", .data = &lm3532_data }, + { .compatible = "ti,lm3631", .data = &lm3631_data }, + { .compatible = "ti,lm3632", .data = &lm3632_data }, + { .compatible = "ti,lm3633", .data = &lm3633_data }, + { .compatible = "ti,lm3695", .data = &lm3695_data }, + { .compatible = "ti,lm3697", .data = &lm3697_data }, + { } +}; +MODULE_DEVICE_TABLE(of, ti_lmu_of_match); static const struct i2c_device_id ti_lmu_ids[] = { { "lm3532", LM3532 }, @@ -244,7 +234,6 @@ MODULE_DEVICE_TABLE(i2c, ti_lmu_ids); static struct i2c_driver ti_lmu_driver = { .probe = ti_lmu_probe, - .remove = ti_lmu_remove, .driver = { .name = "ti-lmu", .of_match_table = ti_lmu_of_match, diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c index 7a30546880a4..c2d47d78705b 100644 --- a/drivers/mfd/ti_am335x_tscadc.c +++ b/drivers/mfd/ti_am335x_tscadc.c @@ -269,7 +269,6 @@ static int ti_tscadc_probe(struct platform_device *pdev) if (err < 0) goto err_disable_clk; - device_init_wakeup(&pdev->dev, true); platform_set_drvdata(pdev, tscadc); return 0; @@ -294,11 +293,24 @@ static int ti_tscadc_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused ti_tscadc_can_wakeup(struct device *dev, void *data) +{ + return device_may_wakeup(dev); +} + static int __maybe_unused tscadc_suspend(struct device *dev) { struct ti_tscadc_dev *tscadc = dev_get_drvdata(dev); regmap_write(tscadc->regmap, REG_SE, 0x00); + if (device_for_each_child(dev, NULL, ti_tscadc_can_wakeup)) { + u32 ctrl; + + regmap_read(tscadc->regmap, REG_CTRL, &ctrl); + ctrl &= ~(CNTRLREG_POWERDOWN); + ctrl |= CNTRLREG_TSCSSENB; + regmap_write(tscadc->regmap, REG_CTRL, ctrl); + } pm_runtime_put_sync(dev); return 0; diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index dd19f17a1b63..7c3c5fd5fcd0 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c @@ -613,7 +613,8 @@ static const struct regmap_config twl6040_regmap_config = { .writeable_reg = twl6040_writeable_reg, .cache_type = REGCACHE_RBTREE, - .use_single_rw = true, + .use_single_read = true, + .use_single_write = true, }; static const struct regmap_irq twl6040_irqs[] = { |