diff options
Diffstat (limited to 'drivers/mfd')
31 files changed, 396 insertions, 425 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/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/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/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/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; |