diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-05 22:10:34 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2021-07-05 22:10:34 +0300 |
commit | 463c09d09d426d4dfe1a83e1461e28d6b2d7f66a (patch) | |
tree | b1ee085006f743e2fcac4365286f26ebde05f54a /drivers/mfd | |
parent | 18ef082713ad1104c32cd17a15abdc3f43c9b28a (diff) | |
parent | 8a14ded5a8cb7d4146c12f984b5346bffde9b70f (diff) | |
download | linux-463c09d09d426d4dfe1a83e1461e28d6b2d7f66a.tar.xz |
Merge tag 'mfd-next-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull mfd updates from Lee Jones:
"Core Frameworks:
- Fix Software Node clean-up code
New Drivers:
- Add support for MediaTek MT6359 PMIC
- Add support for Qualcomm PM8008 PMIC
- Add support for Richtek RT4831
New Device Support:
- Add support for Audio CODECs to Rockchip RK817
- Add support for Alder Lake-M to Intel LPSS PCI
- Add support for Periph Device Charge to ChromeOS EC
New Functionality:
- Provide additional IRQs for wcd934x
- Add optional Reset functionality to lp87565
Fix-ups:
- Namespacing & visibility fixes to lp87565
- Differentiate between Power and Home key IRQs in mt6358
- Export I2C device tables in da9052-i2c, stmpe-i2c
- Adapt IRQ flags in max8907, rn5t61, max8907
- Make some functions/devices optional in axp20x, cros_ec_dev
- Explicitly include used header files in ioc3
- Remove superfluous lines in MAINTAINERS, sec-core, st,stm32-timers
- Resolve Kerneldoc issues in omap-usb-host, omap-usb-tll, si476x-cmd, si476x-i2c
- Convert arizona-core to a module
- Copyright changes in hi655x-pmic
- Drop support for board file initialisation in sec-core
- Trivial spelling, whitespace etc updates in lp87565, si476x-cmd,
mt6360-core, wm831x-core, twl-core, db8500-prcmu
- Simplify various implementations of wcd934x, mt6360-core, max8997,
max8998, da9052-i2c, da9062-core, sec-core,
- Device Tree binding changes in google,cros-ec,
richtek,rt4831-backlight, db8500-prcmu, qcom,pm8008, qcom,spmi-pmic
- Use provided APIs to simplify t7l66xb, as3722, da9055-core,
tps80031, 88pm800, 88pm805, asic3, sun6i-prcm, wm831x-core,
wm831x-otp, ucb1x00-assabet, timberdale, sm501, pcf50633-core,
kempld-core, janz-cmodio, intel_soc_pmic_bxtwc, ab8500-core
Bug Fixes:
- Fix unused variable warning in rk817_codec
- Fix regulator voltage configuration in rohm-bd71828
- Fix ongoing freeing of regmap_config 'name' issue in syscon
- Fix error handling path in da9063-i2c
- Fix Kconfig issues in MFD_MP2629
- Fix DMA mask warnings in motorola-cpcap"
* tag 'mfd-next-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (83 commits)
mfd: cros_ec: Add peripheral device charger
mfd: max8907: Remove IRQF_NO_AUTOEN flag
mfd: ab8500-core: Use DEVICE_ATTR_RO/RW macro
mfd: intel_soc_pmic_bxtwc: Use DEVICE_ATTR_ADMIN_RW macro
mfd: janz-cmodio: Use DEVICE_ATTR_RO macro
mfd: kempld-core: Use DEVICE_ATTR_RO macro
mfd: pcf50633: Use DEVICE_ATTR_ADMIN_RO macro
mfd: sm501: Use DEVICE_ATTR_RO macro
mfd: timberdale: Use DEVICE_ATTR_RO macro
mfd: ucb1x00-assabet: Use DEVICE_ATTR_RO macro
mfd: wm831x: Use DEVICE_ATTR_RO macro
mfd: wm831x: Use DEFINE_RES_IRQ_NAMED() and DEFINE_RES_IRQ() to simplify code
dt-bindings: mfd: stm32-timers: Remove #address/size cells from required properties
mfd: sun6i-prcm: Use DEFINE_RES_MEM() to simplify code
mfd: asic3: Use DEFINE_RES_MEM() and DEFINE_RES_IRQ() to simplify code
mfd: 88pm805: Use DEFINE_RES_IRQ_NAMED() to simplify code
mfd: 88pm800: Use DEFINE_RES_IRQ_NAMED() to simplify code
mfd: tps80031: Use DEFINE_RES_IRQ() to simplify code
mfd: da9055: Use DEFINE_RES_IRQ_NAMED() to simplify code
mfd: as3722: Use DEFINE_RES_IRQ_NAMED() to simplify code
...
Diffstat (limited to 'drivers/mfd')
50 files changed, 1099 insertions, 748 deletions
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index c7f964996a91..eaf9845633b4 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c @@ -122,12 +122,7 @@ static const struct i2c_device_id pm80x_id_table[] = { MODULE_DEVICE_TABLE(i2c, pm80x_id_table); static const struct resource rtc_resources[] = { - { - .name = "88pm80x-rtc", - .start = PM800_IRQ_RTC, - .end = PM800_IRQ_RTC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(PM800_IRQ_RTC, "88pm80x-rtc"), }; static struct mfd_cell rtc_devs[] = { @@ -140,12 +135,7 @@ static struct mfd_cell rtc_devs[] = { }; static struct resource onkey_resources[] = { - { - .name = "88pm80x-onkey", - .start = PM800_IRQ_ONKEY, - .end = PM800_IRQ_ONKEY, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(PM800_IRQ_ONKEY, "88pm80x-onkey"), }; static const struct mfd_cell onkey_devs[] = { diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 39f2302e137b..ada6c513302b 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c @@ -54,27 +54,14 @@ enum { }; static struct resource codec_resources[] = { - { - /* Headset microphone insertion or removal */ - .name = "micin", - .start = PM805_IRQ_MIC_DET, - .end = PM805_IRQ_MIC_DET, - .flags = IORESOURCE_IRQ, - }, - { - /* Audio short HP1 */ - .name = "audio-short1", - .start = PM805_IRQ_HP1_SHRT, - .end = PM805_IRQ_HP1_SHRT, - .flags = IORESOURCE_IRQ, - }, - { - /* Audio short HP2 */ - .name = "audio-short2", - .start = PM805_IRQ_HP2_SHRT, - .end = PM805_IRQ_HP2_SHRT, - .flags = IORESOURCE_IRQ, - }, + /* Headset microphone insertion or removal */ + DEFINE_RES_IRQ_NAMED(PM805_IRQ_MIC_DET, "micin"), + + /* Audio short HP1 */ + DEFINE_RES_IRQ_NAMED(PM805_IRQ_HP1_SHRT, "audio-short1"), + + /* Audio short HP2 */ + DEFINE_RES_IRQ_NAMED(PM805_IRQ_HP2_SHRT, "audio-short2"), }; static const struct mfd_cell codec_devs[] = { diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 99c4e1a80ae0..6a3fd2d75f96 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -465,6 +465,7 @@ config MFD_MP2629 tristate "Monolithic Power Systems MP2629 ADC and Battery charger" depends on I2C select REGMAP_I2C + select MFD_CORE help Select this option to enable support for Monolithic Power Systems battery charger. This provides ADC, thermal and battery charger power @@ -902,6 +903,7 @@ config MFD_MT6360 select MFD_CORE select REGMAP_I2C select REGMAP_IRQ + select CRC8 depends on I2C help Say Y here to enable MT6360 PMU/PMIC/LDO functional support. @@ -1076,6 +1078,16 @@ config MFD_RDC321X southbridge which provides access to GPIOs and Watchdog using the southbridge PCI device configuration space. +config MFD_RT4831 + tristate "Richtek RT4831 four channel WLED and Display Bias Voltage" + depends on I2C + select MFD_CORE + select REGMAP_I2C + help + This enables support for the Richtek RT4831 that includes 4 channel + WLED driving and Display Bias Voltage. It's commonly used to provide + power to the LCD display and LCD backlight. + config MFD_RT5033 tristate "Richtek RT5033 Power Management IC" depends on I2C @@ -1133,6 +1145,7 @@ config MFD_RN5T618 config MFD_SEC_CORE tristate "Samsung Electronics PMIC Series Support" depends on I2C=y + depends on OF || COMPILE_TEST select MFD_CORE select REGMAP_I2C select REGMAP_IRQ @@ -1770,7 +1783,7 @@ config MFD_ARIZONA select REGMAP select REGMAP_IRQ select MFD_CORE - bool + tristate config MFD_ARIZONA_I2C tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with I2C" @@ -2087,6 +2100,20 @@ config MFD_ACER_A500_EC The controller itself is ENE KB930, it is running firmware customized for the specific needs of the Acer A500 hardware. +config MFD_QCOM_PM8008 + tristate "QCOM PM8008 Power Management IC" + depends on I2C && OF + select REGMAP_I2C + select REGMAP_IRQ + help + Select this option to get support for the Qualcomm Technologies, Inc. + PM8008 PMIC chip. PM8008 is a dedicated camera PMIC that integrates + all the necessary power management, housekeeping, and interface + support functions into a single IC. This driver provides common + support for accessing the device by instantiating all the child nodes + under it in the device tree. Additional drivers must be enabled in + order to use the functionality of the device. + menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 8b322d89a0c5..8116c19d5fd4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -41,24 +41,24 @@ obj-$(CONFIG_MFD_TQMX86) += tqmx86.o obj-$(CONFIG_MFD_LOCHNAGAR) += lochnagar-i2c.o -obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o -obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o +arizona-objs := arizona-core.o arizona-irq.o +obj-$(CONFIG_MFD_ARIZONA) += arizona.o obj-$(CONFIG_MFD_ARIZONA_I2C) += arizona-i2c.o obj-$(CONFIG_MFD_ARIZONA_SPI) += arizona-spi.o ifeq ($(CONFIG_MFD_WM5102),y) -obj-$(CONFIG_MFD_ARIZONA) += wm5102-tables.o +arizona-objs += wm5102-tables.o endif ifeq ($(CONFIG_MFD_WM5110),y) -obj-$(CONFIG_MFD_ARIZONA) += wm5110-tables.o +arizona-objs += wm5110-tables.o endif ifeq ($(CONFIG_MFD_WM8997),y) -obj-$(CONFIG_MFD_ARIZONA) += wm8997-tables.o +arizona-objs += wm8997-tables.o endif ifeq ($(CONFIG_MFD_WM8998),y) -obj-$(CONFIG_MFD_ARIZONA) += wm8998-tables.o +arizona-objs += wm8998-tables.o endif ifeq ($(CONFIG_MFD_CS47L24),y) -obj-$(CONFIG_MFD_ARIZONA) += cs47l24-tables.o +arizona-objs += cs47l24-tables.o endif obj-$(CONFIG_MFD_WCD934X) += wcd934x.o obj-$(CONFIG_MFD_WM8400) += wm8400-core.o @@ -233,6 +233,7 @@ obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o obj-$(CONFIG_MFD_HI655X_PMIC) += hi655x-pmic.o obj-$(CONFIG_MFD_DLN2) += dln2.o +obj-$(CONFIG_MFD_RT4831) += rt4831.o obj-$(CONFIG_MFD_RT5033) += rt5033.o obj-$(CONFIG_MFD_SKY81452) += sky81452.o @@ -263,6 +264,7 @@ obj-$(CONFIG_MFD_ROHM_BD957XMUF) += rohm-bd9576.o obj-$(CONFIG_MFD_STMFX) += stmfx.o obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o obj-$(CONFIG_MFD_ACER_A500_EC) += acer-ec-a500.o +obj-$(CONFIG_MFD_QCOM_PM8008) += qcom-pm8008.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index c2ba498ad302..30489670ea52 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c @@ -827,8 +827,8 @@ static const struct mfd_cell ab8540_cut2_devs[] = { }, }; -static ssize_t show_chip_id(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t chip_id_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct ab8500 *ab8500; @@ -848,8 +848,8 @@ static ssize_t show_chip_id(struct device *dev, * 0x40 Power on key 1 pressed longer than 10 seconds * 0x80 DB8500 thermal shutdown */ -static ssize_t show_switch_off_status(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t switch_off_status_show(struct device *dev, + struct device_attribute *attr, char *buf) { int ret; u8 value; @@ -883,8 +883,8 @@ void ab8500_override_turn_on_stat(u8 mask, u8 set) * 0x40 UsbIDDetect * 0x80 Reserved */ -static ssize_t show_turn_on_status(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t turn_on_status_show(struct device *dev, + struct device_attribute *attr, char *buf) { int ret; u8 value; @@ -912,8 +912,8 @@ static ssize_t show_turn_on_status(struct device *dev, return sprintf(buf, "%#x\n", value); } -static ssize_t show_turn_on_status_2(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t turn_on_status_2_show(struct device *dev, + struct device_attribute *attr, char *buf) { int ret; u8 value; @@ -927,8 +927,8 @@ static ssize_t show_turn_on_status_2(struct device *dev, return sprintf(buf, "%#x\n", (value & 0x1)); } -static ssize_t show_ab9540_dbbrstn(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t dbbrstn_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct ab8500 *ab8500; int ret; @@ -945,7 +945,7 @@ static ssize_t show_ab9540_dbbrstn(struct device *dev, (value & AB9540_MODEM_CTRL2_SWDBBRSTN_BIT) ? 1 : 0); } -static ssize_t store_ab9540_dbbrstn(struct device *dev, +static ssize_t dbbrstn_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ab8500 *ab8500; @@ -980,12 +980,11 @@ exit: return ret; } -static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); -static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL); -static DEVICE_ATTR(turn_on_status, S_IRUGO, show_turn_on_status, NULL); -static DEVICE_ATTR(turn_on_status_2, S_IRUGO, show_turn_on_status_2, NULL); -static DEVICE_ATTR(dbbrstn, S_IRUGO | S_IWUSR, - show_ab9540_dbbrstn, store_ab9540_dbbrstn); +static DEVICE_ATTR_RO(chip_id); +static DEVICE_ATTR_RO(switch_off_status); +static DEVICE_ATTR_RO(turn_on_status); +static DEVICE_ATTR_RO(turn_on_status_2); +static DEVICE_ATTR_RW(dbbrstn); static struct attribute *ab8500_sysfs_entries[] = { &dev_attr_chip_id.attr, diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index ce6fe6de34f8..9323b1e3a69e 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -1447,3 +1447,5 @@ int arizona_dev_exit(struct arizona *arizona) return 0; } EXPORT_SYMBOL_GPL(arizona_dev_exit); + +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/as3722.c b/drivers/mfd/as3722.c index 59dfeff71592..38665efae4f0 100644 --- a/drivers/mfd/as3722.c +++ b/drivers/mfd/as3722.c @@ -24,21 +24,11 @@ #define AS3722_DEVICE_ID 0x0C static const struct resource as3722_rtc_resource[] = { - { - .name = "as3722-rtc-alarm", - .start = AS3722_IRQ_RTC_ALARM, - .end = AS3722_IRQ_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AS3722_IRQ_RTC_ALARM, "as3722-rtc-alarm"), }; static const struct resource as3722_adc_resource[] = { - { - .name = "as3722-adc", - .start = AS3722_IRQ_ADC, - .end = AS3722_IRQ_ADC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AS3722_IRQ_ADC, "as3722-adc"), }; static const struct mfd_cell as3722_devs[] = { diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index a6bd2134cea2..8d58c8df46cf 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -723,16 +723,8 @@ static struct tmio_mmc_data asic3_mmc_data = { }; static struct resource asic3_mmc_resources[] = { - { - .start = ASIC3_SD_CTRL_BASE, - .end = ASIC3_SD_CTRL_BASE + 0x3ff, - .flags = IORESOURCE_MEM, - }, - { - .start = 0, - .end = 0, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_MEM(ASIC3_SD_CTRL_BASE, 0x400), + DEFINE_RES_IRQ(0) }; static int asic3_mmc_enable(struct platform_device *pdev) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 3eae04e24ac8..4145a38b3890 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -884,8 +884,13 @@ int axp20x_match_device(struct axp20x_dev *axp20x) axp20x->regmap_irq_chip = &axp803_regmap_irq_chip; break; case AXP806_ID: + /* + * Don't register the power key part if in slave mode or + * if there is no interrupt line. + */ if (of_property_read_bool(axp20x->dev->of_node, - "x-powers,self-working-mode")) { + "x-powers,self-working-mode") && + axp20x->irq > 0) { axp20x->nr_cells = ARRAY_SIZE(axp806_self_working_cells); axp20x->cells = axp806_self_working_cells; } else { @@ -959,12 +964,17 @@ int axp20x_device_probe(struct axp20x_dev *axp20x) AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE); } - ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq, - IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags, - -1, axp20x->regmap_irq_chip, &axp20x->regmap_irqc); - if (ret) { - dev_err(axp20x->dev, "failed to add irq chip: %d\n", ret); - return ret; + /* Only if there is an interrupt line connected towards the CPU. */ + if (axp20x->irq > 0) { + ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq, + IRQF_ONESHOT | IRQF_SHARED | axp20x->irq_flags, + -1, axp20x->regmap_irq_chip, + &axp20x->regmap_irqc); + if (ret) { + dev_err(axp20x->dev, "failed to add irq chip: %d\n", + ret); + return ret; + } } ret = mfd_add_devices(axp20x->dev, -1, axp20x->cells, diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index d07b43d7c761..8c08d1c55726 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -5,6 +5,7 @@ * Copyright (C) 2014 Google, Inc. */ +#include <linux/dmi.h> #include <linux/kconfig.h> #include <linux/mfd/core.h> #include <linux/module.h> @@ -112,8 +113,12 @@ static const struct cros_feature_to_cells cros_subdevices[] = { static const struct mfd_cell cros_ec_platform_cells[] = { { .name = "cros-ec-chardev", }, { .name = "cros-ec-debugfs", }, - { .name = "cros-ec-lightbar", }, { .name = "cros-ec-sysfs", }, + { .name = "cros-ec-pchg", }, +}; + +static const struct mfd_cell cros_ec_lightbar_cells[] = { + { .name = "cros-ec-lightbar", } }; static const struct mfd_cell cros_ec_vbc_cells[] = { @@ -207,6 +212,20 @@ static int ec_device_probe(struct platform_device *pdev) } /* + * Lightbar is a special case. Newer devices support autodetection, + * but older ones do not. + */ + if (cros_ec_check_features(ec, EC_FEATURE_LIGHTBAR) || + dmi_match(DMI_PRODUCT_NAME, "Link")) { + retval = mfd_add_hotplug_devices(ec->dev, + cros_ec_lightbar_cells, + ARRAY_SIZE(cros_ec_lightbar_cells)); + if (retval) + dev_warn(ec->dev, "failed to add lightbar: %d\n", + retval); + } + + /* * The PD notifier driver cell is separate since it only needs to be * explicitly added on platforms that don't have the PD notifier ACPI * device entry defined. diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c index 47556d2d9abe..8de93db35f3a 100644 --- a/drivers/mfd/da9052-i2c.c +++ b/drivers/mfd/da9052-i2c.c @@ -113,6 +113,7 @@ static const struct i2c_device_id da9052_i2c_id[] = { {"da9053-bc", DA9053_BC}, {} }; +MODULE_DEVICE_TABLE(i2c, da9052_i2c_id); #ifdef CONFIG_OF static const struct of_device_id dialog_dt_ids[] = { @@ -154,13 +155,8 @@ static int da9052_i2c_probe(struct i2c_client *client, return ret; #ifdef CONFIG_OF - if (!id) { - struct device_node *np = client->dev.of_node; - const struct of_device_id *deviceid; - - deviceid = of_match_node(dialog_dt_ids, np); - id = deviceid->data; - } + if (!id) + id = of_device_get_match_data(&client->dev); #endif if (!id) { diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c index d074d213e661..c3bcbd8905c6 100644 --- a/drivers/mfd/da9055-core.c +++ b/drivers/mfd/da9055-core.c @@ -254,41 +254,19 @@ const struct regmap_config da9055_regmap_config = { }; EXPORT_SYMBOL_GPL(da9055_regmap_config); -static const struct resource da9055_onkey_resource = { - .name = "ONKEY", - .start = DA9055_IRQ_NONKEY, - .end = DA9055_IRQ_NONKEY, - .flags = IORESOURCE_IRQ, -}; +static const struct resource da9055_onkey_resource = + DEFINE_RES_IRQ_NAMED(DA9055_IRQ_NONKEY, "ONKEY"); static const struct resource da9055_rtc_resource[] = { - { - .name = "ALM", - .start = DA9055_IRQ_ALARM, - .end = DA9055_IRQ_ALARM, - .flags = IORESOURCE_IRQ, - }, - { - .name = "TICK", - .start = DA9055_IRQ_TICK, - .end = DA9055_IRQ_TICK, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(DA9055_IRQ_ALARM, "ALM"), + DEFINE_RES_IRQ_NAMED(DA9055_IRQ_TICK, "TICK"), }; -static const struct resource da9055_hwmon_resource = { - .name = "HWMON", - .start = DA9055_IRQ_HWMON, - .end = DA9055_IRQ_HWMON, - .flags = IORESOURCE_IRQ, -}; +static const struct resource da9055_hwmon_resource = + DEFINE_RES_IRQ_NAMED(DA9055_IRQ_HWMON, "HWMON"); -static const struct resource da9055_ld05_6_resource = { - .name = "REGULATOR", - .start = DA9055_IRQ_REGULATOR, - .end = DA9055_IRQ_REGULATOR, - .flags = IORESOURCE_IRQ, -}; +static const struct resource da9055_ld05_6_resource = + DEFINE_RES_IRQ_NAMED(DA9055_IRQ_REGULATOR, "REGULATOR"); static const struct mfd_cell da9055_devs[] = { { diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index 8d913375152d..01f8e10dfa55 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -9,6 +9,7 @@ #include <linux/init.h> #include <linux/device.h> #include <linux/interrupt.h> +#include <linux/of_device.h> #include <linux/regmap.h> #include <linux/irq.h> #include <linux/mfd/core.h> @@ -622,7 +623,6 @@ static int da9062_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct da9062 *chip; - const struct of_device_id *match; unsigned int irq_base; const struct mfd_cell *cell; const struct regmap_irq_chip *irq_chip; @@ -635,15 +635,10 @@ static int da9062_i2c_probe(struct i2c_client *i2c, if (!chip) return -ENOMEM; - if (i2c->dev.of_node) { - match = of_match_node(da9062_dt_ids, i2c->dev.of_node); - if (!match) - return -EINVAL; - - chip->chip_type = (uintptr_t)match->data; - } else { + if (i2c->dev.of_node) + chip->chip_type = (uintptr_t)of_device_get_match_data(&i2c->dev); + else chip->chip_type = id->driver_data; - } i2c_set_clientdata(i2c, chip); chip->dev = &i2c->dev; diff --git a/drivers/mfd/da9063-i2c.c b/drivers/mfd/da9063-i2c.c index 783a14af18e2..4b7f707b7952 100644 --- a/drivers/mfd/da9063-i2c.c +++ b/drivers/mfd/da9063-i2c.c @@ -448,7 +448,7 @@ static int da9063_i2c_probe(struct i2c_client *i2c, DA9063_TWOWIRE_TO); if (ret < 0) { dev_err(da9063->dev, "Failed to set Two-Wire Bus Mode.\n"); - return -EIO; + return ret; } } diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 167faac9b75b..3bde7fda755f 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -616,7 +616,7 @@ enum romcode_read prcmu_get_rc_p2a(void) } /** - * prcmu_get_current_mode - Return the current XP70 power mode + * prcmu_get_xp70_current_state - Return the current XP70 power mode * Returns: Returns the current AP(ARM) power mode: init, * apBoot, apExecute, apDeepSleep, apSleep, apIdle, apReset */ @@ -898,7 +898,7 @@ unlock_and_return: } /** - * db8500_set_ape_opp - set the appropriate APE OPP + * db8500_prcmu_set_ape_opp - set the appropriate APE OPP * @opp: The new APE operating point to which transition is to be made * Returns: 0 on success, non-zero on failure * @@ -2297,7 +2297,7 @@ u16 db8500_prcmu_get_reset_code(void) } /** - * db8500_prcmu_reset_modem - ask the PRCMU to reset modem + * db8500_prcmu_modem_reset - ask the PRCMU to reset modem */ void db8500_prcmu_modem_reset(void) { diff --git a/drivers/mfd/hi655x-pmic.c b/drivers/mfd/hi655x-pmic.c index d3c86a7a3805..6909d075d017 100644 --- a/drivers/mfd/hi655x-pmic.c +++ b/drivers/mfd/hi655x-pmic.c @@ -2,7 +2,7 @@ /* * Device driver for MFD hi655x PMIC * - * Copyright (c) 2016 Hisilicon. + * Copyright (c) 2016 HiSilicon Ltd. * * Authors: * Chen Feng <puck.chen@hisilicon.com> diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 79c53617489c..c54d19fb184c 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -310,6 +310,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x51ea), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x51eb), (kernel_ulong_t)&bxt_i2c_info }, { PCI_VDEVICE(INTEL, 0x51fb), (kernel_ulong_t)&bxt_info }, + /* ADL-M */ + { PCI_VDEVICE(INTEL, 0x54a8), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x54a9), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x54aa), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x54ab), (kernel_ulong_t)&bxt_info }, + { PCI_VDEVICE(INTEL, 0x54c5), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x54c6), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x54c7), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x54e8), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x54e9), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x54ea), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x54eb), (kernel_ulong_t)&bxt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x54fb), (kernel_ulong_t)&bxt_info }, /* APL */ { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info }, { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info }, diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c b/drivers/mfd/intel_soc_pmic_bxtwc.c index 47d0d3a69a58..bc069c4daa60 100644 --- a/drivers/mfd/intel_soc_pmic_bxtwc.c +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c @@ -330,14 +330,14 @@ static int regmap_ipc_byte_reg_write(void *context, unsigned int reg, /* sysfs interfaces to r/w PMIC registers, required by initial script */ static unsigned long bxtwc_reg_addr; -static ssize_t bxtwc_reg_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t addr_show(struct device *dev, + struct device_attribute *attr, char *buf) { return sprintf(buf, "0x%lx\n", bxtwc_reg_addr); } -static ssize_t bxtwc_reg_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t addr_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { if (kstrtoul(buf, 0, &bxtwc_reg_addr)) { dev_err(dev, "Invalid register address\n"); @@ -346,8 +346,8 @@ static ssize_t bxtwc_reg_store(struct device *dev, return (ssize_t)count; } -static ssize_t bxtwc_val_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t val_show(struct device *dev, + struct device_attribute *attr, char *buf) { int ret; unsigned int val; @@ -362,8 +362,8 @@ static ssize_t bxtwc_val_show(struct device *dev, return sprintf(buf, "0x%02x\n", val); } -static ssize_t bxtwc_val_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) +static ssize_t val_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) { int ret; unsigned int val; @@ -382,8 +382,8 @@ static ssize_t bxtwc_val_store(struct device *dev, return count; } -static DEVICE_ATTR(addr, S_IWUSR | S_IRUSR, bxtwc_reg_show, bxtwc_reg_store); -static DEVICE_ATTR(val, S_IWUSR | S_IRUSR, bxtwc_val_show, bxtwc_val_store); +static DEVICE_ATTR_ADMIN_RW(addr); +static DEVICE_ATTR_ADMIN_RW(val); static struct attribute *bxtwc_attrs[] = { &dev_attr_addr.attr, &dev_attr_val.attr, diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 3df4e9a2998f..70eba4ce496f 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c @@ -149,15 +149,15 @@ static int cmodio_probe_submodules(struct cmodio_device *priv) * SYSFS Attributes */ -static ssize_t mbus_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t modulbus_number_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct cmodio_device *priv = dev_get_drvdata(dev); return snprintf(buf, PAGE_SIZE, "%x\n", priv->hex); } -static DEVICE_ATTR(modulbus_number, S_IRUGO, mbus_show, NULL); +static DEVICE_ATTR_RO(modulbus_number); static struct attribute *cmodio_sysfs_attrs[] = { &dev_attr_modulbus_number.attr, diff --git a/drivers/mfd/kempld-core.c b/drivers/mfd/kempld-core.c index 9166075c1f32..bb26241c73bd 100644 --- a/drivers/mfd/kempld-core.c +++ b/drivers/mfd/kempld-core.c @@ -344,16 +344,16 @@ static const char *kempld_get_type_string(struct kempld_device_data *pld) return version_type; } -static ssize_t kempld_version_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t pld_version_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct kempld_device_data *pld = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%s\n", pld->info.version); } -static ssize_t kempld_specification_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t pld_specification_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct kempld_device_data *pld = dev_get_drvdata(dev); @@ -361,18 +361,17 @@ static ssize_t kempld_specification_show(struct device *dev, pld->info.spec_minor); } -static ssize_t kempld_type_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t pld_type_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct kempld_device_data *pld = dev_get_drvdata(dev); return scnprintf(buf, PAGE_SIZE, "%s\n", kempld_get_type_string(pld)); } -static DEVICE_ATTR(pld_version, S_IRUGO, kempld_version_show, NULL); -static DEVICE_ATTR(pld_specification, S_IRUGO, kempld_specification_show, - NULL); -static DEVICE_ATTR(pld_type, S_IRUGO, kempld_type_show, NULL); +static DEVICE_ATTR_RO(pld_version); +static DEVICE_ATTR_RO(pld_specification); +static DEVICE_ATTR_RO(pld_type); static struct attribute *pld_attributes[] = { &dev_attr_pld_version.attr, diff --git a/drivers/mfd/lp87565.c b/drivers/mfd/lp87565.c index 9c21483d9653..a52ab76febb3 100644 --- a/drivers/mfd/lp87565.c +++ b/drivers/mfd/lp87565.c @@ -5,6 +5,7 @@ * Author: Keerthy <j-keerthy@ti.com> */ +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/mfd/core.h> #include <linux/module.h> @@ -64,6 +65,24 @@ static int lp87565_probe(struct i2c_client *client, return ret; } + lp87565->reset_gpio = devm_gpiod_get_optional(lp87565->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(lp87565->reset_gpio)) { + ret = PTR_ERR(lp87565->reset_gpio); + if (ret == -EPROBE_DEFER) + return ret; + } + + if (lp87565->reset_gpio) { + gpiod_set_value_cansleep(lp87565->reset_gpio, 1); + /* The minimum assertion time is undocumented, just guess */ + usleep_range(2000, 4000); + + gpiod_set_value_cansleep(lp87565->reset_gpio, 0); + /* Min 1.2 ms before first I2C transaction */ + usleep_range(1500, 3000); + } + ret = regmap_read(lp87565->regmap, LP87565_REG_OTP_REV, &otpid); if (ret) { dev_err(lp87565->dev, "Failed to read OTP ID\n"); @@ -83,6 +102,13 @@ static int lp87565_probe(struct i2c_client *client, NULL, 0, NULL); } +static void lp87565_shutdown(struct i2c_client *client) +{ + struct lp87565 *lp87565 = i2c_get_clientdata(client); + + gpiod_set_value_cansleep(lp87565->reset_gpio, 1); +} + static const struct i2c_device_id lp87565_id_table[] = { { "lp87565-q1", 0 }, { }, @@ -95,6 +121,7 @@ static struct i2c_driver lp87565_driver = { .of_match_table = of_lp87565_match_table, }, .probe = lp87565_probe, + .shutdown = lp87565_shutdown, .id_table = lp87565_id_table, }; module_i2c_driver(lp87565_driver); diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c index d44baafd9d14..41f566e6a096 100644 --- a/drivers/mfd/max8907.c +++ b/drivers/mfd/max8907.c @@ -228,11 +228,9 @@ static int max8907_i2c_probe(struct i2c_client *i2c, goto err_regmap_rtc; } - irq_set_status_flags(max8907->i2c_gen->irq, IRQ_NOAUTOEN); - ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq, - IRQF_ONESHOT | IRQF_SHARED, -1, - &max8907_chg_irq_chip, + IRQF_ONESHOT | IRQF_SHARED, + -1, &max8907_chg_irq_chip, &max8907->irqc_chg); if (ret != 0) { dev_err(&i2c->dev, "failed to add chg irq chip: %d\n", ret); @@ -255,8 +253,6 @@ static int max8907_i2c_probe(struct i2c_client *i2c, goto err_irqc_rtc; } - enable_irq(max8907->i2c_gen->irq); - ret = mfd_add_devices(max8907->dev, -1, max8907_cells, ARRAY_SIZE(max8907_cells), NULL, 0, NULL); if (ret != 0) { diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 68d8f2b95287..2141de78115d 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -11,6 +11,7 @@ #include <linux/slab.h> #include <linux/i2c.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/pm_runtime.h> @@ -145,11 +146,9 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( static inline unsigned long max8997_i2c_get_driver_data(struct i2c_client *i2c, const struct i2c_device_id *id) { - if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { - const struct of_device_id *match; - match = of_match_node(max8997_pmic_dt_match, i2c->dev.of_node); - return (unsigned long)match->data; - } + if (i2c->dev.of_node) + return (unsigned long)of_device_get_match_data(&i2c->dev); + return id->driver_data; } diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 785f8e9841b7..0eb15e611b67 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -12,6 +12,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/pm_runtime.h> #include <linux/mutex.h> @@ -155,11 +156,8 @@ static struct max8998_platform_data *max8998_i2c_parse_dt_pdata( static inline unsigned long max8998_i2c_get_driver_data(struct i2c_client *i2c, const struct i2c_device_id *id) { - if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { - const struct of_device_id *match; - match = of_match_node(max8998_dt_match, i2c->dev.of_node); - return (unsigned long)match->data; - } + if (i2c->dev.of_node) + return (unsigned long)of_device_get_match_data(&i2c->dev); return id->driver_data; } diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 6f02b8022c6d..79f5c6a18815 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -266,18 +266,18 @@ static int mfd_add_device(struct device *parent, int id, if (has_acpi_companion(&pdev->dev)) { ret = acpi_check_resource_conflict(&res[r]); if (ret) - goto fail_of_entry; + goto fail_res_conflict; } } } ret = platform_device_add_resources(pdev, res, cell->num_resources); if (ret) - goto fail_of_entry; + goto fail_res_conflict; ret = platform_device_add(pdev); if (ret) - goto fail_of_entry; + goto fail_res_conflict; if (cell->pm_runtime_no_callbacks) pm_runtime_no_callbacks(&pdev->dev); @@ -286,13 +286,15 @@ static int mfd_add_device(struct device *parent, int id, return 0; +fail_res_conflict: + if (cell->swnode) + device_remove_software_node(&pdev->dev); fail_of_entry: list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) if (of_entry->dev == &pdev->dev) { list_del(&of_entry->list); kfree(of_entry); } - device_remove_software_node(&pdev->dev); fail_alias: regulator_bulk_unregister_supply_alias(&pdev->dev, cell->parent_supplies, @@ -358,11 +360,12 @@ static int mfd_remove_devices_fn(struct device *dev, void *data) if (level && cell->level > *level) return 0; + if (cell->swnode) + device_remove_software_node(&pdev->dev); + regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, cell->num_parent_supplies); - device_remove_software_node(&pdev->dev); - platform_device_unregister(pdev); return 0; } diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c index 30d82bfe5b02..6fb206da2729 100644 --- a/drivers/mfd/motorola-cpcap.c +++ b/drivers/mfd/motorola-cpcap.c @@ -327,6 +327,10 @@ static int cpcap_probe(struct spi_device *spi) if (ret) return ret; + /* Parent SPI controller uses DMA, CPCAP and child devices do not */ + spi->dev.coherent_dma_mask = 0; + spi->dev.dma_mask = &spi->dev.coherent_dma_mask; + return devm_mfd_add_devices(&spi->dev, 0, cpcap_mfd_devices, ARRAY_SIZE(cpcap_mfd_devices), NULL, 0, NULL); } diff --git a/drivers/mfd/mt6360-core.c b/drivers/mfd/mt6360-core.c index 480722acf706..e628953548ce 100644 --- a/drivers/mfd/mt6360-core.c +++ b/drivers/mfd/mt6360-core.c @@ -5,121 +5,180 @@ * Author: Gene Chen <gene_chen@richtek.com> */ +#include <linux/crc8.h> #include <linux/i2c.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/mfd/core.h> #include <linux/module.h> -#include <linux/of_irq.h> -#include <linux/of_platform.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +enum { + MT6360_SLAVE_TCPC = 0, + MT6360_SLAVE_PMIC, + MT6360_SLAVE_LDO, + MT6360_SLAVE_PMU, + MT6360_SLAVE_MAX, +}; + +struct mt6360_ddata { + struct i2c_client *i2c[MT6360_SLAVE_MAX]; + struct device *dev; + struct regmap *regmap; + struct regmap_irq_chip_data *irq_data; + unsigned int chip_rev; + u8 crc8_tbl[CRC8_TABLE_SIZE]; +}; -#include <linux/mfd/mt6360.h> +#define MT6360_TCPC_SLAVEID 0x4E +#define MT6360_PMIC_SLAVEID 0x1A +#define MT6360_LDO_SLAVEID 0x64 +#define MT6360_PMU_SLAVEID 0x34 + +#define MT6360_REG_TCPCSTART 0x00 +#define MT6360_REG_TCPCEND 0xFF +#define MT6360_REG_PMICSTART 0x100 +#define MT6360_REG_PMICEND 0x13B +#define MT6360_REG_LDOSTART 0x200 +#define MT6360_REG_LDOEND 0x21C +#define MT6360_REG_PMUSTART 0x300 +#define MT6360_PMU_DEV_INFO 0x300 +#define MT6360_PMU_CHG_IRQ1 0x3D0 +#define MT6360_PMU_CHG_MASK1 0x3F0 +#define MT6360_REG_PMUEND 0x3FF + +#define MT6360_PMU_IRQ_REGNUM 16 + +#define CHIP_VEN_MASK 0xF0 +#define CHIP_VEN_MT6360 0x50 +#define CHIP_REV_MASK 0x0F + +#define MT6360_ADDRESS_MASK 0x3F +#define MT6360_DATA_SIZE_1_BYTE 0x00 +#define MT6360_DATA_SIZE_2_BYTES 0x40 +#define MT6360_DATA_SIZE_3_BYTES 0x80 +#define MT6360_DATA_SIZE_4_BYTES 0xC0 + +#define MT6360_CRC8_POLYNOMIAL 0x7 + +#define MT6360_CRC_I2C_ADDR_SIZE 1 +#define MT6360_CRC_REG_ADDR_SIZE 1 +/* prealloca read size = i2c device addr + i2c reg addr + val ... + crc8 */ +#define MT6360_ALLOC_READ_SIZE(_size) (_size + 3) +/* prealloca write size = i2c device addr + i2c reg addr + val ... + crc8 + dummy byte */ +#define MT6360_ALLOC_WRITE_SIZE(_size) (_size + 4) +#define MT6360_CRC_PREDATA_OFFSET (MT6360_CRC_I2C_ADDR_SIZE + MT6360_CRC_REG_ADDR_SIZE) +#define MT6360_CRC_CRC8_SIZE 1 +#define MT6360_CRC_DUMMY_BYTE_SIZE 1 +#define MT6360_REGMAP_REG_BYTE_SIZE 2 +#define I2C_ADDR_XLATE_8BIT(_addr, _rw) (((_addr & 0x7F) << 1) + _rw) /* reg 0 -> 0 ~ 7 */ -#define MT6360_CHG_TREG_EVT (4) -#define MT6360_CHG_AICR_EVT (5) -#define MT6360_CHG_MIVR_EVT (6) -#define MT6360_PWR_RDY_EVT (7) +#define MT6360_CHG_TREG_EVT 4 +#define MT6360_CHG_AICR_EVT 5 +#define MT6360_CHG_MIVR_EVT 6 +#define MT6360_PWR_RDY_EVT 7 /* REG 1 -> 8 ~ 15 */ -#define MT6360_CHG_BATSYSUV_EVT (9) -#define MT6360_FLED_CHG_VINOVP_EVT (11) -#define MT6360_CHG_VSYSUV_EVT (12) -#define MT6360_CHG_VSYSOV_EVT (13) -#define MT6360_CHG_VBATOV_EVT (14) -#define MT6360_CHG_VBUSOV_EVT (15) +#define MT6360_CHG_BATSYSUV_EVT 9 +#define MT6360_FLED_CHG_VINOVP_EVT 11 +#define MT6360_CHG_VSYSUV_EVT 12 +#define MT6360_CHG_VSYSOV_EVT 13 +#define MT6360_CHG_VBATOV_EVT 14 +#define MT6360_CHG_VBUSOV_EVT 15 /* REG 2 -> 16 ~ 23 */ /* REG 3 -> 24 ~ 31 */ -#define MT6360_WD_PMU_DET (25) -#define MT6360_WD_PMU_DONE (26) -#define MT6360_CHG_TMRI (27) -#define MT6360_CHG_ADPBADI (29) -#define MT6360_CHG_RVPI (30) -#define MT6360_OTPI (31) +#define MT6360_WD_PMU_DET 25 +#define MT6360_WD_PMU_DONE 26 +#define MT6360_CHG_TMRI 27 +#define MT6360_CHG_ADPBADI 29 +#define MT6360_CHG_RVPI 30 +#define MT6360_OTPI 31 /* REG 4 -> 32 ~ 39 */ -#define MT6360_CHG_AICCMEASL (32) -#define MT6360_CHGDET_DONEI (34) -#define MT6360_WDTMRI (35) -#define MT6360_SSFINISHI (36) -#define MT6360_CHG_RECHGI (37) -#define MT6360_CHG_TERMI (38) -#define MT6360_CHG_IEOCI (39) +#define MT6360_CHG_AICCMEASL 32 +#define MT6360_CHGDET_DONEI 34 +#define MT6360_WDTMRI 35 +#define MT6360_SSFINISHI 36 +#define MT6360_CHG_RECHGI 37 +#define MT6360_CHG_TERMI 38 +#define MT6360_CHG_IEOCI 39 /* REG 5 -> 40 ~ 47 */ -#define MT6360_PUMPX_DONEI (40) -#define MT6360_BAT_OVP_ADC_EVT (41) -#define MT6360_TYPEC_OTP_EVT (42) -#define MT6360_ADC_WAKEUP_EVT (43) -#define MT6360_ADC_DONEI (44) -#define MT6360_BST_BATUVI (45) -#define MT6360_BST_VBUSOVI (46) -#define MT6360_BST_OLPI (47) +#define MT6360_PUMPX_DONEI 40 +#define MT6360_BAT_OVP_ADC_EVT 41 +#define MT6360_TYPEC_OTP_EVT 42 +#define MT6360_ADC_WAKEUP_EVT 43 +#define MT6360_ADC_DONEI 44 +#define MT6360_BST_BATUVI 45 +#define MT6360_BST_VBUSOVI 46 +#define MT6360_BST_OLPI 47 /* REG 6 -> 48 ~ 55 */ -#define MT6360_ATTACH_I (48) -#define MT6360_DETACH_I (49) -#define MT6360_QC30_STPDONE (51) -#define MT6360_QC_VBUSDET_DONE (52) -#define MT6360_HVDCP_DET (53) -#define MT6360_CHGDETI (54) -#define MT6360_DCDTI (55) +#define MT6360_ATTACH_I 48 +#define MT6360_DETACH_I 49 +#define MT6360_QC30_STPDONE 51 +#define MT6360_QC_VBUSDET_DONE 52 +#define MT6360_HVDCP_DET 53 +#define MT6360_CHGDETI 54 +#define MT6360_DCDTI 55 /* REG 7 -> 56 ~ 63 */ -#define MT6360_FOD_DONE_EVT (56) -#define MT6360_FOD_OV_EVT (57) -#define MT6360_CHRDET_UVP_EVT (58) -#define MT6360_CHRDET_OVP_EVT (59) -#define MT6360_CHRDET_EXT_EVT (60) -#define MT6360_FOD_LR_EVT (61) -#define MT6360_FOD_HR_EVT (62) -#define MT6360_FOD_DISCHG_FAIL_EVT (63) +#define MT6360_FOD_DONE_EVT 56 +#define MT6360_FOD_OV_EVT 57 +#define MT6360_CHRDET_UVP_EVT 58 +#define MT6360_CHRDET_OVP_EVT 59 +#define MT6360_CHRDET_EXT_EVT 60 +#define MT6360_FOD_LR_EVT 61 +#define MT6360_FOD_HR_EVT 62 +#define MT6360_FOD_DISCHG_FAIL_EVT 63 /* REG 8 -> 64 ~ 71 */ -#define MT6360_USBID_EVT (64) -#define MT6360_APWDTRST_EVT (65) -#define MT6360_EN_EVT (66) -#define MT6360_QONB_RST_EVT (67) -#define MT6360_MRSTB_EVT (68) -#define MT6360_OTP_EVT (69) -#define MT6360_VDDAOV_EVT (70) -#define MT6360_SYSUV_EVT (71) +#define MT6360_USBID_EVT 64 +#define MT6360_APWDTRST_EVT 65 +#define MT6360_EN_EVT 66 +#define MT6360_QONB_RST_EVT 67 +#define MT6360_MRSTB_EVT 68 +#define MT6360_OTP_EVT 69 +#define MT6360_VDDAOV_EVT 70 +#define MT6360_SYSUV_EVT 71 /* REG 9 -> 72 ~ 79 */ -#define MT6360_FLED_STRBPIN_EVT (72) -#define MT6360_FLED_TORPIN_EVT (73) -#define MT6360_FLED_TX_EVT (74) -#define MT6360_FLED_LVF_EVT (75) -#define MT6360_FLED2_SHORT_EVT (78) -#define MT6360_FLED1_SHORT_EVT (79) +#define MT6360_FLED_STRBPIN_EVT 72 +#define MT6360_FLED_TORPIN_EVT 73 +#define MT6360_FLED_TX_EVT 74 +#define MT6360_FLED_LVF_EVT 75 +#define MT6360_FLED2_SHORT_EVT 78 +#define MT6360_FLED1_SHORT_EVT 79 /* REG 10 -> 80 ~ 87 */ -#define MT6360_FLED2_STRB_EVT (80) -#define MT6360_FLED1_STRB_EVT (81) -#define MT6360_FLED2_STRB_TO_EVT (82) -#define MT6360_FLED1_STRB_TO_EVT (83) -#define MT6360_FLED2_TOR_EVT (84) -#define MT6360_FLED1_TOR_EVT (85) +#define MT6360_FLED2_STRB_EVT 80 +#define MT6360_FLED1_STRB_EVT 81 +#define MT6360_FLED2_STRB_TO_EVT 82 +#define MT6360_FLED1_STRB_TO_EVT 83 +#define MT6360_FLED2_TOR_EVT 84 +#define MT6360_FLED1_TOR_EVT 85 /* REG 11 -> 88 ~ 95 */ /* REG 12 -> 96 ~ 103 */ -#define MT6360_BUCK1_PGB_EVT (96) -#define MT6360_BUCK1_OC_EVT (100) -#define MT6360_BUCK1_OV_EVT (101) -#define MT6360_BUCK1_UV_EVT (102) +#define MT6360_BUCK1_PGB_EVT 96 +#define MT6360_BUCK1_OC_EVT 100 +#define MT6360_BUCK1_OV_EVT 101 +#define MT6360_BUCK1_UV_EVT 102 /* REG 13 -> 104 ~ 111 */ -#define MT6360_BUCK2_PGB_EVT (104) -#define MT6360_BUCK2_OC_EVT (108) -#define MT6360_BUCK2_OV_EVT (109) -#define MT6360_BUCK2_UV_EVT (110) +#define MT6360_BUCK2_PGB_EVT 104 +#define MT6360_BUCK2_OC_EVT 108 +#define MT6360_BUCK2_OV_EVT 109 +#define MT6360_BUCK2_UV_EVT 110 /* REG 14 -> 112 ~ 119 */ -#define MT6360_LDO1_OC_EVT (113) -#define MT6360_LDO2_OC_EVT (114) -#define MT6360_LDO3_OC_EVT (115) -#define MT6360_LDO5_OC_EVT (117) -#define MT6360_LDO6_OC_EVT (118) -#define MT6360_LDO7_OC_EVT (119) +#define MT6360_LDO1_OC_EVT 113 +#define MT6360_LDO2_OC_EVT 114 +#define MT6360_LDO3_OC_EVT 115 +#define MT6360_LDO5_OC_EVT 117 +#define MT6360_LDO6_OC_EVT 118 +#define MT6360_LDO7_OC_EVT 119 /* REG 15 -> 120 ~ 127 */ -#define MT6360_LDO1_PGB_EVT (121) -#define MT6360_LDO2_PGB_EVT (122) -#define MT6360_LDO3_PGB_EVT (123) -#define MT6360_LDO5_PGB_EVT (125) -#define MT6360_LDO6_PGB_EVT (126) -#define MT6360_LDO7_PGB_EVT (127) - -static const struct regmap_irq mt6360_pmu_irqs[] = { +#define MT6360_LDO1_PGB_EVT 121 +#define MT6360_LDO2_PGB_EVT 122 +#define MT6360_LDO3_PGB_EVT 123 +#define MT6360_LDO5_PGB_EVT 125 +#define MT6360_LDO6_PGB_EVT 126 +#define MT6360_LDO7_PGB_EVT 127 + +static const struct regmap_irq mt6360_irqs[] = { REGMAP_IRQ_REG_LINE(MT6360_CHG_TREG_EVT, 8), REGMAP_IRQ_REG_LINE(MT6360_CHG_AICR_EVT, 8), REGMAP_IRQ_REG_LINE(MT6360_CHG_MIVR_EVT, 8), @@ -208,30 +267,16 @@ static const struct regmap_irq mt6360_pmu_irqs[] = { REGMAP_IRQ_REG_LINE(MT6360_LDO7_PGB_EVT, 8), }; -static int mt6360_pmu_handle_post_irq(void *irq_drv_data) -{ - struct mt6360_pmu_data *mpd = irq_drv_data; - - return regmap_update_bits(mpd->regmap, - MT6360_PMU_IRQ_SET, MT6360_IRQ_RETRIG, MT6360_IRQ_RETRIG); -} - -static struct regmap_irq_chip mt6360_pmu_irq_chip = { - .irqs = mt6360_pmu_irqs, - .num_irqs = ARRAY_SIZE(mt6360_pmu_irqs), +static const struct regmap_irq_chip mt6360_irq_chip = { + .name = "mt6360_irqs", + .irqs = mt6360_irqs, + .num_irqs = ARRAY_SIZE(mt6360_irqs), .num_regs = MT6360_PMU_IRQ_REGNUM, .mask_base = MT6360_PMU_CHG_MASK1, .status_base = MT6360_PMU_CHG_IRQ1, .ack_base = MT6360_PMU_CHG_IRQ1, .init_ack_masked = true, .use_ack = true, - .handle_post_irq = mt6360_pmu_handle_post_irq, -}; - -static const struct regmap_config mt6360_pmu_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = MT6360_PMU_MAXREG, }; static const struct resource mt6360_adc_resources[] = { @@ -265,7 +310,7 @@ static const struct resource mt6360_led_resources[] = { DEFINE_RES_IRQ_NAMED(MT6360_FLED1_STRB_TO_EVT, "fled1_strb_to_evt"), }; -static const struct resource mt6360_pmic_resources[] = { +static const struct resource mt6360_regulator_resources[] = { DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_PGB_EVT, "buck1_pgb_evt"), DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OC_EVT, "buck1_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_BUCK1_OV_EVT, "buck1_ov_evt"), @@ -278,9 +323,6 @@ static const struct resource mt6360_pmic_resources[] = { DEFINE_RES_IRQ_NAMED(MT6360_LDO7_OC_EVT, "ldo7_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO6_PGB_EVT, "ldo6_pgb_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO7_PGB_EVT, "ldo7_pgb_evt"), -}; - -static const struct resource mt6360_ldo_resources[] = { DEFINE_RES_IRQ_NAMED(MT6360_LDO1_OC_EVT, "ldo1_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO2_OC_EVT, "ldo2_oc_evt"), DEFINE_RES_IRQ_NAMED(MT6360_LDO3_OC_EVT, "ldo3_oc_evt"), @@ -292,84 +334,241 @@ static const struct resource mt6360_ldo_resources[] = { }; static const struct mfd_cell mt6360_devs[] = { - MFD_CELL_OF("mt6360_adc", mt6360_adc_resources, - NULL, 0, 0, "mediatek,mt6360_adc"), - MFD_CELL_OF("mt6360_chg", mt6360_chg_resources, - NULL, 0, 0, "mediatek,mt6360_chg"), - MFD_CELL_OF("mt6360_led", mt6360_led_resources, - NULL, 0, 0, "mediatek,mt6360_led"), - MFD_CELL_OF("mt6360_pmic", mt6360_pmic_resources, - NULL, 0, 0, "mediatek,mt6360_pmic"), - MFD_CELL_OF("mt6360_ldo", mt6360_ldo_resources, - NULL, 0, 0, "mediatek,mt6360_ldo"), - MFD_CELL_OF("mt6360_tcpc", NULL, - NULL, 0, 0, "mediatek,mt6360_tcpc"), + MFD_CELL_OF("mt6360-adc", mt6360_adc_resources, + NULL, 0, 0, "mediatek,mt6360-adc"), + MFD_CELL_OF("mt6360-chg", mt6360_chg_resources, + NULL, 0, 0, "mediatek,mt6360-chg"), + MFD_CELL_OF("mt6360-led", mt6360_led_resources, + NULL, 0, 0, "mediatek,mt6360-led"), + MFD_CELL_RES("mt6360-regulator", mt6360_regulator_resources), + MFD_CELL_OF("mt6360-tcpc", NULL, + NULL, 0, 0, "mediatek,mt6360-tcpc"), }; +static int mt6360_check_vendor_info(struct mt6360_ddata *ddata) +{ + u32 info; + int ret; + + ret = regmap_read(ddata->regmap, MT6360_PMU_DEV_INFO, &info); + if (ret < 0) + return ret; + + if ((info & CHIP_VEN_MASK) != CHIP_VEN_MT6360) { + dev_err(ddata->dev, "Device not supported\n"); + return -ENODEV; + } + + ddata->chip_rev = info & CHIP_REV_MASK; + + return 0; +} + static const unsigned short mt6360_slave_addr[MT6360_SLAVE_MAX] = { - MT6360_PMU_SLAVEID, + MT6360_TCPC_SLAVEID, MT6360_PMIC_SLAVEID, MT6360_LDO_SLAVEID, - MT6360_TCPC_SLAVEID, + MT6360_PMU_SLAVEID, }; -static int mt6360_pmu_probe(struct i2c_client *client) +static int mt6360_xlate_pmicldo_addr(u8 *addr, int rw_size) { - struct mt6360_pmu_data *mpd; - unsigned int reg_data; - int i, ret; + /* Address is already in encoded [5:0] */ + *addr &= MT6360_ADDRESS_MASK; + + switch (rw_size) { + case 1: + *addr |= MT6360_DATA_SIZE_1_BYTE; + break; + case 2: + *addr |= MT6360_DATA_SIZE_2_BYTES; + break; + case 3: + *addr |= MT6360_DATA_SIZE_3_BYTES; + break; + case 4: + *addr |= MT6360_DATA_SIZE_4_BYTES; + break; + default: + return -EINVAL; + } - mpd = devm_kzalloc(&client->dev, sizeof(*mpd), GFP_KERNEL); - if (!mpd) + return 0; +} + +static int mt6360_regmap_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct mt6360_ddata *ddata = context; + u8 bank = *(u8 *)reg; + u8 reg_addr = *(u8 *)(reg + 1); + struct i2c_client *i2c = ddata->i2c[bank]; + bool crc_needed = false; + u8 *buf; + int buf_len = MT6360_ALLOC_READ_SIZE(val_size); + int read_size = val_size; + u8 crc; + int ret; + + if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) { + crc_needed = true; + ret = mt6360_xlate_pmicldo_addr(®_addr, val_size); + if (ret < 0) + return ret; + read_size += MT6360_CRC_CRC8_SIZE; + } + + buf = kzalloc(buf_len, GFP_KERNEL); + if (!buf) return -ENOMEM; - mpd->dev = &client->dev; - i2c_set_clientdata(client, mpd); + buf[0] = I2C_ADDR_XLATE_8BIT(i2c->addr, I2C_SMBUS_READ); + buf[1] = reg_addr; - mpd->regmap = devm_regmap_init_i2c(client, &mt6360_pmu_regmap_config); - if (IS_ERR(mpd->regmap)) { - dev_err(&client->dev, "Failed to register regmap\n"); - return PTR_ERR(mpd->regmap); + ret = i2c_smbus_read_i2c_block_data(i2c, reg_addr, read_size, + buf + MT6360_CRC_PREDATA_OFFSET); + if (ret < 0) + goto out; + else if (ret != read_size) { + ret = -EIO; + goto out; } - ret = regmap_read(mpd->regmap, MT6360_PMU_DEV_INFO, ®_data); - if (ret) { - dev_err(&client->dev, "Device not found\n"); - return ret; + if (crc_needed) { + crc = crc8(ddata->crc8_tbl, buf, val_size + MT6360_CRC_PREDATA_OFFSET, 0); + if (crc != buf[val_size + MT6360_CRC_PREDATA_OFFSET]) { + ret = -EIO; + goto out; + } } - mpd->chip_rev = reg_data & CHIP_REV_MASK; - if (mpd->chip_rev != CHIP_VEN_MT6360) { - dev_err(&client->dev, "Device not supported\n"); - return -ENODEV; + memcpy(val, buf + MT6360_CRC_PREDATA_OFFSET, val_size); +out: + kfree(buf); + return (ret < 0) ? ret : 0; +} + +static int mt6360_regmap_write(void *context, const void *val, size_t val_size) +{ + struct mt6360_ddata *ddata = context; + u8 bank = *(u8 *)val; + u8 reg_addr = *(u8 *)(val + 1); + struct i2c_client *i2c = ddata->i2c[bank]; + bool crc_needed = false; + u8 *buf; + int buf_len = MT6360_ALLOC_WRITE_SIZE(val_size); + int write_size = val_size - MT6360_REGMAP_REG_BYTE_SIZE; + int ret; + + if (bank == MT6360_SLAVE_PMIC || bank == MT6360_SLAVE_LDO) { + crc_needed = true; + ret = mt6360_xlate_pmicldo_addr(®_addr, val_size - MT6360_REGMAP_REG_BYTE_SIZE); + if (ret < 0) + return ret; } - mt6360_pmu_irq_chip.irq_drv_data = mpd; - ret = devm_regmap_add_irq_chip(&client->dev, mpd->regmap, client->irq, - IRQF_TRIGGER_FALLING, 0, - &mt6360_pmu_irq_chip, &mpd->irq_data); - if (ret) { - dev_err(&client->dev, "Failed to add Regmap IRQ Chip\n"); - return ret; + buf = kzalloc(buf_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + buf[0] = I2C_ADDR_XLATE_8BIT(i2c->addr, I2C_SMBUS_WRITE); + buf[1] = reg_addr; + memcpy(buf + MT6360_CRC_PREDATA_OFFSET, val + MT6360_REGMAP_REG_BYTE_SIZE, write_size); + + if (crc_needed) { + buf[val_size] = crc8(ddata->crc8_tbl, buf, val_size, 0); + write_size += (MT6360_CRC_CRC8_SIZE + MT6360_CRC_DUMMY_BYTE_SIZE); } - mpd->i2c[0] = client; - for (i = 1; i < MT6360_SLAVE_MAX; i++) { - mpd->i2c[i] = devm_i2c_new_dummy_device(&client->dev, - client->adapter, - mt6360_slave_addr[i]); - if (IS_ERR(mpd->i2c[i])) { + ret = i2c_smbus_write_i2c_block_data(i2c, reg_addr, write_size, + buf + MT6360_CRC_PREDATA_OFFSET); + + kfree(buf); + return ret; +} + +static const struct regmap_bus mt6360_regmap_bus = { + .read = mt6360_regmap_read, + .write = mt6360_regmap_write, + + /* Due to PMIC and LDO CRC access size limit */ + .max_raw_read = 4, + .max_raw_write = 4, +}; + +static bool mt6360_is_readwrite_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MT6360_REG_TCPCSTART ... MT6360_REG_TCPCEND: + fallthrough; + case MT6360_REG_PMICSTART ... MT6360_REG_PMICEND: + fallthrough; + case MT6360_REG_LDOSTART ... MT6360_REG_LDOEND: + fallthrough; + case MT6360_REG_PMUSTART ... MT6360_REG_PMUEND: + return true; + } + + return false; +} + +static const struct regmap_config mt6360_regmap_config = { + .reg_bits = 16, + .val_bits = 8, + .reg_format_endian = REGMAP_ENDIAN_BIG, + .max_register = MT6360_REG_PMUEND, + .writeable_reg = mt6360_is_readwrite_reg, + .readable_reg = mt6360_is_readwrite_reg, +}; + +static int mt6360_probe(struct i2c_client *client) +{ + struct mt6360_ddata *ddata; + int i, ret; + + ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + ddata->dev = &client->dev; + i2c_set_clientdata(client, ddata); + + for (i = 0; i < MT6360_SLAVE_MAX - 1; i++) { + ddata->i2c[i] = devm_i2c_new_dummy_device(&client->dev, + client->adapter, + mt6360_slave_addr[i]); + if (IS_ERR(ddata->i2c[i])) { dev_err(&client->dev, "Failed to get new dummy I2C device for address 0x%x", mt6360_slave_addr[i]); - return PTR_ERR(mpd->i2c[i]); + return PTR_ERR(ddata->i2c[i]); } - i2c_set_clientdata(mpd->i2c[i], mpd); + } + ddata->i2c[MT6360_SLAVE_MAX - 1] = client; + + crc8_populate_msb(ddata->crc8_tbl, MT6360_CRC8_POLYNOMIAL); + ddata->regmap = devm_regmap_init(ddata->dev, &mt6360_regmap_bus, ddata, + &mt6360_regmap_config); + if (IS_ERR(ddata->regmap)) { + dev_err(&client->dev, "Failed to register regmap\n"); + return PTR_ERR(ddata->regmap); + } + + ret = mt6360_check_vendor_info(ddata); + if (ret) + return ret; + + ret = devm_regmap_add_irq_chip(&client->dev, ddata->regmap, client->irq, + 0, 0, &mt6360_irq_chip, + &ddata->irq_data); + if (ret) { + dev_err(&client->dev, "Failed to add Regmap IRQ Chip\n"); + return ret; } ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, mt6360_devs, ARRAY_SIZE(mt6360_devs), NULL, - 0, regmap_irq_get_domain(mpd->irq_data)); + 0, regmap_irq_get_domain(ddata->irq_data)); if (ret) { dev_err(&client->dev, "Failed to register subordinate devices\n"); @@ -379,7 +578,7 @@ static int mt6360_pmu_probe(struct i2c_client *client) return 0; } -static int __maybe_unused mt6360_pmu_suspend(struct device *dev) +static int __maybe_unused mt6360_suspend(struct device *dev) { struct i2c_client *i2c = to_i2c_client(dev); @@ -389,7 +588,7 @@ static int __maybe_unused mt6360_pmu_suspend(struct device *dev) return 0; } -static int __maybe_unused mt6360_pmu_resume(struct device *dev) +static int __maybe_unused mt6360_resume(struct device *dev) { struct i2c_client *i2c = to_i2c_client(dev); @@ -400,25 +599,24 @@ static int __maybe_unused mt6360_pmu_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(mt6360_pmu_pm_ops, - mt6360_pmu_suspend, mt6360_pmu_resume); +static SIMPLE_DEV_PM_OPS(mt6360_pm_ops, mt6360_suspend, mt6360_resume); -static const struct of_device_id __maybe_unused mt6360_pmu_of_id[] = { - { .compatible = "mediatek,mt6360_pmu", }, +static const struct of_device_id __maybe_unused mt6360_of_id[] = { + { .compatible = "mediatek,mt6360", }, {}, }; -MODULE_DEVICE_TABLE(of, mt6360_pmu_of_id); +MODULE_DEVICE_TABLE(of, mt6360_of_id); -static struct i2c_driver mt6360_pmu_driver = { +static struct i2c_driver mt6360_driver = { .driver = { - .name = "mt6360_pmu", - .pm = &mt6360_pmu_pm_ops, - .of_match_table = of_match_ptr(mt6360_pmu_of_id), + .name = "mt6360", + .pm = &mt6360_pm_ops, + .of_match_table = of_match_ptr(mt6360_of_id), }, - .probe_new = mt6360_pmu_probe, + .probe_new = mt6360_probe, }; -module_i2c_driver(mt6360_pmu_driver); +module_i2c_driver(mt6360_driver); MODULE_AUTHOR("Gene Chen <gene_chen@richtek.com>"); -MODULE_DESCRIPTION("MT6360 PMU I2C Driver"); +MODULE_DESCRIPTION("MT6360 I2C Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index 9a615f75fbde..bddb40054b9e 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -47,14 +47,21 @@ static const struct resource mt6397_rtc_resources[] = { DEFINE_RES_IRQ(MT6397_IRQ_RTC), }; +static const struct resource mt6358_keys_resources[] = { + DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY, "powerkey"), + DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY, "homekey"), + DEFINE_RES_IRQ_NAMED(MT6358_IRQ_PWRKEY_R, "powerkey_r"), + DEFINE_RES_IRQ_NAMED(MT6358_IRQ_HOMEKEY_R, "homekey_r"), +}; + static const struct resource mt6323_keys_resources[] = { - DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY), - DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY), + DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_PWRKEY, "powerkey"), + DEFINE_RES_IRQ_NAMED(MT6323_IRQ_STATUS_FCHRKEY, "homekey"), }; static const struct resource mt6397_keys_resources[] = { - DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY), - DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY), + DEFINE_RES_IRQ_NAMED(MT6397_IRQ_PWRKEY, "powerkey"), + DEFINE_RES_IRQ_NAMED(MT6397_IRQ_HOMEKEY, "homekey"), }; static const struct resource mt6323_pwrc_resources[] = { @@ -98,6 +105,11 @@ static const struct mfd_cell mt6358_devs[] = { }, { .name = "mt6358-sound", .of_compatible = "mediatek,mt6358-sound" + }, { + .name = "mt6358-keys", + .num_resources = ARRAY_SIZE(mt6358_keys_resources), + .resources = mt6358_keys_resources, + .of_compatible = "mediatek,mt6358-keys" }, }; diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 2a3a240b4619..787d2ae86375 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI * * Copyright (C) 2011-2013 Texas Instruments Incorporated - https://www.ti.com diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 16fad79c73f1..080d7970a377 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI * * Copyright (C) 2012-2013 Texas Instruments Incorporated - https://www.ti.com diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index 148bcd6120f4..e9c565cf0f54 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -77,8 +77,8 @@ int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val) EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits); /* sysfs attributes */ -static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t dump_regs_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct pcf50633 *pcf = dev_get_drvdata(dev); u8 dump[16]; @@ -106,10 +106,10 @@ static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr, return buf1 - buf; } -static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL); +static DEVICE_ATTR_ADMIN_RO(dump_regs); -static ssize_t show_resume_reason(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t resume_reason_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct pcf50633 *pcf = dev_get_drvdata(dev); int n; @@ -123,7 +123,7 @@ static ssize_t show_resume_reason(struct device *dev, return n; } -static DEVICE_ATTR(resume_reason, 0400, show_resume_reason, NULL); +static DEVICE_ATTR_ADMIN_RO(resume_reason); static struct attribute *pcf_sysfs_entries[] = { &dev_attr_dump_regs.attr, diff --git a/drivers/mfd/qcom-pm8008.c b/drivers/mfd/qcom-pm8008.c new file mode 100644 index 000000000000..c472d7f8103c --- /dev/null +++ b/drivers/mfd/qcom-pm8008.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/bitops.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/irqdomain.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/of_platform.h> +#include <linux/pinctrl/consumer.h> +#include <linux/regmap.h> +#include <linux/slab.h> + +#include <dt-bindings/mfd/qcom-pm8008.h> + +#define I2C_INTR_STATUS_BASE 0x0550 +#define INT_RT_STS_OFFSET 0x10 +#define INT_SET_TYPE_OFFSET 0x11 +#define INT_POL_HIGH_OFFSET 0x12 +#define INT_POL_LOW_OFFSET 0x13 +#define INT_LATCHED_CLR_OFFSET 0x14 +#define INT_EN_SET_OFFSET 0x15 +#define INT_EN_CLR_OFFSET 0x16 +#define INT_LATCHED_STS_OFFSET 0x18 + +enum { + PM8008_MISC, + PM8008_TEMP_ALARM, + PM8008_GPIO1, + PM8008_GPIO2, + PM8008_NUM_PERIPHS, +}; + +#define PM8008_PERIPH_0_BASE 0x900 +#define PM8008_PERIPH_1_BASE 0x2400 +#define PM8008_PERIPH_2_BASE 0xC000 +#define PM8008_PERIPH_3_BASE 0xC100 + +#define PM8008_TEMP_ALARM_ADDR PM8008_PERIPH_1_BASE +#define PM8008_GPIO1_ADDR PM8008_PERIPH_2_BASE +#define PM8008_GPIO2_ADDR PM8008_PERIPH_3_BASE + +#define PM8008_STATUS_BASE (PM8008_PERIPH_0_BASE | INT_LATCHED_STS_OFFSET) +#define PM8008_MASK_BASE (PM8008_PERIPH_0_BASE | INT_EN_SET_OFFSET) +#define PM8008_UNMASK_BASE (PM8008_PERIPH_0_BASE | INT_EN_CLR_OFFSET) +#define PM8008_TYPE_BASE (PM8008_PERIPH_0_BASE | INT_SET_TYPE_OFFSET) +#define PM8008_ACK_BASE (PM8008_PERIPH_0_BASE | INT_LATCHED_CLR_OFFSET) +#define PM8008_POLARITY_HI_BASE (PM8008_PERIPH_0_BASE | INT_POL_HIGH_OFFSET) +#define PM8008_POLARITY_LO_BASE (PM8008_PERIPH_0_BASE | INT_POL_LOW_OFFSET) + +#define PM8008_PERIPH_OFFSET(paddr) (paddr - PM8008_PERIPH_0_BASE) + +struct pm8008_data { + struct device *dev; + struct regmap *regmap; + int irq; + struct regmap_irq_chip_data *irq_data; +}; + +static unsigned int p0_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_0_BASE)}; +static unsigned int p1_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_1_BASE)}; +static unsigned int p2_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_2_BASE)}; +static unsigned int p3_offs[] = {PM8008_PERIPH_OFFSET(PM8008_PERIPH_3_BASE)}; + +static struct regmap_irq_sub_irq_map pm8008_sub_reg_offsets[] = { + REGMAP_IRQ_MAIN_REG_OFFSET(p0_offs), + REGMAP_IRQ_MAIN_REG_OFFSET(p1_offs), + REGMAP_IRQ_MAIN_REG_OFFSET(p2_offs), + REGMAP_IRQ_MAIN_REG_OFFSET(p3_offs), +}; + +static unsigned int pm8008_virt_regs[] = { + PM8008_POLARITY_HI_BASE, + PM8008_POLARITY_LO_BASE, +}; + +enum { + POLARITY_HI_INDEX, + POLARITY_LO_INDEX, + PM8008_NUM_VIRT_REGS, +}; + +static struct regmap_irq pm8008_irqs[] = { + REGMAP_IRQ_REG(PM8008_IRQ_MISC_UVLO, PM8008_MISC, BIT(0)), + REGMAP_IRQ_REG(PM8008_IRQ_MISC_OVLO, PM8008_MISC, BIT(1)), + REGMAP_IRQ_REG(PM8008_IRQ_MISC_OTST2, PM8008_MISC, BIT(2)), + REGMAP_IRQ_REG(PM8008_IRQ_MISC_OTST3, PM8008_MISC, BIT(3)), + REGMAP_IRQ_REG(PM8008_IRQ_MISC_LDO_OCP, PM8008_MISC, BIT(4)), + REGMAP_IRQ_REG(PM8008_IRQ_TEMP_ALARM, PM8008_TEMP_ALARM, BIT(0)), + REGMAP_IRQ_REG(PM8008_IRQ_GPIO1, PM8008_GPIO1, BIT(0)), + REGMAP_IRQ_REG(PM8008_IRQ_GPIO2, PM8008_GPIO2, BIT(0)), +}; + +static int pm8008_set_type_virt(unsigned int **virt_buf, + unsigned int type, unsigned long hwirq, + int reg) +{ + switch (type) { + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_LEVEL_LOW: + virt_buf[POLARITY_HI_INDEX][reg] &= ~pm8008_irqs[hwirq].mask; + virt_buf[POLARITY_LO_INDEX][reg] |= pm8008_irqs[hwirq].mask; + break; + + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_LEVEL_HIGH: + virt_buf[POLARITY_HI_INDEX][reg] |= pm8008_irqs[hwirq].mask; + virt_buf[POLARITY_LO_INDEX][reg] &= ~pm8008_irqs[hwirq].mask; + break; + + case IRQ_TYPE_EDGE_BOTH: + virt_buf[POLARITY_HI_INDEX][reg] |= pm8008_irqs[hwirq].mask; + virt_buf[POLARITY_LO_INDEX][reg] |= pm8008_irqs[hwirq].mask; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static struct regmap_irq_chip pm8008_irq_chip = { + .name = "pm8008_irq", + .main_status = I2C_INTR_STATUS_BASE, + .num_main_regs = 1, + .num_virt_regs = PM8008_NUM_VIRT_REGS, + .irqs = pm8008_irqs, + .num_irqs = ARRAY_SIZE(pm8008_irqs), + .num_regs = PM8008_NUM_PERIPHS, + .not_fixed_stride = true, + .sub_reg_offsets = pm8008_sub_reg_offsets, + .set_type_virt = pm8008_set_type_virt, + .status_base = PM8008_STATUS_BASE, + .mask_base = PM8008_MASK_BASE, + .unmask_base = PM8008_UNMASK_BASE, + .type_base = PM8008_TYPE_BASE, + .ack_base = PM8008_ACK_BASE, + .virt_reg_base = pm8008_virt_regs, + .num_type_reg = PM8008_NUM_PERIPHS, +}; + +static struct regmap_config qcom_mfd_regmap_cfg = { + .reg_bits = 16, + .val_bits = 8, + .max_register = 0xFFFF, +}; + +static int pm8008_init(struct pm8008_data *chip) +{ + int rc; + + /* + * Set TEMP_ALARM peripheral's TYPE so that the regmap-irq framework + * reads this as the default value instead of zero, the HW default. + * This is required to enable the writing of TYPE registers in + * regmap_irq_sync_unlock(). + */ + rc = regmap_write(chip->regmap, + (PM8008_TEMP_ALARM_ADDR | INT_SET_TYPE_OFFSET), + BIT(0)); + if (rc) + return rc; + + /* Do the same for GPIO1 and GPIO2 peripherals */ + rc = regmap_write(chip->regmap, + (PM8008_GPIO1_ADDR | INT_SET_TYPE_OFFSET), BIT(0)); + if (rc) + return rc; + + rc = regmap_write(chip->regmap, + (PM8008_GPIO2_ADDR | INT_SET_TYPE_OFFSET), BIT(0)); + + return rc; +} + +static int pm8008_probe_irq_peripherals(struct pm8008_data *chip, + int client_irq) +{ + int rc, i; + struct regmap_irq_type *type; + struct regmap_irq_chip_data *irq_data; + + rc = pm8008_init(chip); + if (rc) { + dev_err(chip->dev, "Init failed: %d\n", rc); + return rc; + } + + for (i = 0; i < ARRAY_SIZE(pm8008_irqs); i++) { + type = &pm8008_irqs[i].type; + + type->type_reg_offset = pm8008_irqs[i].reg_offset; + type->type_rising_val = pm8008_irqs[i].mask; + type->type_falling_val = pm8008_irqs[i].mask; + type->type_level_high_val = 0; + type->type_level_low_val = 0; + + if (type->type_reg_offset == PM8008_MISC) + type->types_supported = IRQ_TYPE_EDGE_RISING; + else + type->types_supported = (IRQ_TYPE_EDGE_BOTH | + IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW); + } + + rc = devm_regmap_add_irq_chip(chip->dev, chip->regmap, client_irq, + IRQF_SHARED, 0, &pm8008_irq_chip, &irq_data); + if (rc) { + dev_err(chip->dev, "Failed to add IRQ chip: %d\n", rc); + return rc; + } + + return 0; +} + +static int pm8008_probe(struct i2c_client *client) +{ + int rc; + struct pm8008_data *chip; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->dev = &client->dev; + chip->regmap = devm_regmap_init_i2c(client, &qcom_mfd_regmap_cfg); + if (!chip->regmap) + return -ENODEV; + + i2c_set_clientdata(client, chip); + + if (of_property_read_bool(chip->dev->of_node, "interrupt-controller")) { + rc = pm8008_probe_irq_peripherals(chip, client->irq); + if (rc) + dev_err(chip->dev, "Failed to probe irq periphs: %d\n", rc); + } + + return devm_of_platform_populate(chip->dev); +} + +static const struct of_device_id pm8008_match[] = { + { .compatible = "qcom,pm8008", }, + { }, +}; + +static struct i2c_driver pm8008_mfd_driver = { + .driver = { + .name = "pm8008", + .of_match_table = pm8008_match, + }, + .probe_new = pm8008_probe, +}; +module_i2c_driver(pm8008_mfd_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("i2c:qcom-pm8008"); diff --git a/drivers/mfd/rn5t618.c b/drivers/mfd/rn5t618.c index 6ed04e6dbc78..384acb459427 100644 --- a/drivers/mfd/rn5t618.c +++ b/drivers/mfd/rn5t618.c @@ -107,7 +107,7 @@ static int rn5t618_irq_init(struct rn5t618 *rn5t618) ret = devm_regmap_add_irq_chip(rn5t618->dev, rn5t618->regmap, rn5t618->irq, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_LOW | IRQF_ONESHOT, 0, irq_chip, &rn5t618->irq_data); if (ret) dev_err(rn5t618->dev, "Failed to register IRQ chip\n"); diff --git a/drivers/mfd/rt4831.c b/drivers/mfd/rt4831.c new file mode 100644 index 000000000000..b169781ac675 --- /dev/null +++ b/drivers/mfd/rt4831.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Richtek Technology Corp. + * + * Author: ChiYuan Huang <cy_huang@richtek.com> + */ + +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/kernel.h> +#include <linux/mfd/core.h> +#include <linux/module.h> +#include <linux/regmap.h> + +#define RT4831_REG_REVISION 0x01 +#define RT4831_REG_ENABLE 0x08 +#define RT4831_REG_I2CPROT 0x15 + +#define RICHTEK_VENDOR_ID 0x03 +#define RT4831_VID_MASK GENMASK(1, 0) +#define RT4831_RESET_MASK BIT(7) +#define RT4831_I2CSAFETMR_MASK BIT(0) + +static const struct mfd_cell rt4831_subdevs[] = { + MFD_CELL_OF("rt4831-backlight", NULL, NULL, 0, 0, "richtek,rt4831-backlight"), + MFD_CELL_NAME("rt4831-regulator") +}; + +static bool rt4831_is_accessible_reg(struct device *dev, unsigned int reg) +{ + if (reg >= RT4831_REG_REVISION && reg <= RT4831_REG_I2CPROT) + return true; + return false; +} + +static const struct regmap_config rt4831_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = RT4831_REG_I2CPROT, + + .readable_reg = rt4831_is_accessible_reg, + .writeable_reg = rt4831_is_accessible_reg, +}; + +static int rt4831_probe(struct i2c_client *client) +{ + struct gpio_desc *enable_gpio; + struct regmap *regmap; + unsigned int chip_id; + int ret; + + enable_gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(enable_gpio)) { + dev_err(&client->dev, "Failed to get 'enable' GPIO\n"); + return PTR_ERR(enable_gpio); + } + + regmap = devm_regmap_init_i2c(client, &rt4831_regmap_config); + if (IS_ERR(regmap)) { + dev_err(&client->dev, "Failed to initialize regmap\n"); + return PTR_ERR(regmap); + } + + ret = regmap_read(regmap, RT4831_REG_REVISION, &chip_id); + if (ret) { + dev_err(&client->dev, "Failed to get H/W revision\n"); + return ret; + } + + if ((chip_id & RT4831_VID_MASK) != RICHTEK_VENDOR_ID) { + dev_err(&client->dev, "Chip vendor ID 0x%02x not matched\n", chip_id); + return -ENODEV; + } + + /* + * Used to prevent the abnormal shutdown. + * If SCL/SDA both keep low for one second to reset HW. + */ + ret = regmap_update_bits(regmap, RT4831_REG_I2CPROT, RT4831_I2CSAFETMR_MASK, + RT4831_I2CSAFETMR_MASK); + if (ret) { + dev_err(&client->dev, "Failed to enable I2C safety timer\n"); + return ret; + } + + return devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, rt4831_subdevs, + ARRAY_SIZE(rt4831_subdevs), NULL, 0, NULL); +} + +static int rt4831_remove(struct i2c_client *client) +{ + struct regmap *regmap = dev_get_regmap(&client->dev, NULL); + + /* Disable WLED and DSV outputs */ + return regmap_update_bits(regmap, RT4831_REG_ENABLE, RT4831_RESET_MASK, RT4831_RESET_MASK); +} + +static const struct of_device_id __maybe_unused rt4831_of_match[] = { + { .compatible = "richtek,rt4831", }, + {} +}; +MODULE_DEVICE_TABLE(of, rt4831_of_match); + +static struct i2c_driver rt4831_driver = { + .driver = { + .name = "rt4831", + .of_match_table = rt4831_of_match, + }, + .probe_new = rt4831_probe, + .remove = rt4831_remove, +}; +module_i2c_driver(rt4831_driver); + +MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 8d55992da19e..1fb29c45f5cf 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c @@ -10,6 +10,7 @@ #include <linux/slab.h> #include <linux/i2c.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/interrupt.h> #include <linux/pm_runtime.h> @@ -93,7 +94,6 @@ static const struct mfd_cell s2mpu02_devs[] = { { .name = "s2mpu02-regulator", }, }; -#ifdef CONFIG_OF static const struct of_device_id sec_dt_match[] = { { .compatible = "samsung,s5m8767-pmic", @@ -121,7 +121,6 @@ static const struct of_device_id sec_dt_match[] = { }, }; MODULE_DEVICE_TABLE(of, sec_dt_match); -#endif static bool s2mpa01_volatile(struct device *dev, unsigned int reg) { @@ -281,7 +280,6 @@ static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic) } } -#ifdef CONFIG_OF /* * Only the common platform data elements for s5m8767 are parsed here from the * device tree. Other sub-modules of s5m8767 such as pmic, rtc , charger and @@ -300,48 +298,20 @@ sec_pmic_i2c_parse_dt_pdata(struct device *dev) if (!pd) return ERR_PTR(-ENOMEM); - /* - * 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. - */ - pd->manual_poweroff = of_property_read_bool(dev->of_node, "samsung,s2mps11-acokb-ground"); pd->disable_wrstbi = of_property_read_bool(dev->of_node, "samsung,s2mps11-wrstbi-ground"); return pd; } -#else -static struct sec_platform_data * -sec_pmic_i2c_parse_dt_pdata(struct device *dev) -{ - return NULL; -} -#endif - -static inline unsigned long sec_i2c_get_driver_data(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ -#ifdef CONFIG_OF - if (i2c->dev.of_node) { - const struct of_device_id *match; - - match = of_match_node(sec_dt_match, i2c->dev.of_node); - return (unsigned long)match->data; - } -#endif - return id->driver_data; -} static int sec_pmic_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { - struct sec_platform_data *pdata = dev_get_platdata(&i2c->dev); const struct regmap_config *regmap; + struct sec_platform_data *pdata; const struct mfd_cell *sec_devs; struct sec_pmic_dev *sec_pmic; - unsigned long device_type; int ret, num_sec_devs; sec_pmic = devm_kzalloc(&i2c->dev, sizeof(struct sec_pmic_dev), @@ -353,23 +323,16 @@ static int sec_pmic_probe(struct i2c_client *i2c, sec_pmic->dev = &i2c->dev; sec_pmic->i2c = i2c; sec_pmic->irq = i2c->irq; - device_type = sec_i2c_get_driver_data(i2c, id); - - if (sec_pmic->dev->of_node) { - pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); - if (IS_ERR(pdata)) { - ret = PTR_ERR(pdata); - return ret; - } - pdata->device_type = device_type; - } - if (pdata) { - sec_pmic->device_type = pdata->device_type; - sec_pmic->irq_base = pdata->irq_base; - sec_pmic->wakeup = pdata->wakeup; - sec_pmic->pdata = pdata; + + pdata = sec_pmic_i2c_parse_dt_pdata(sec_pmic->dev); + if (IS_ERR(pdata)) { + ret = PTR_ERR(pdata); + return ret; } + sec_pmic->device_type = (unsigned long)of_device_get_match_data(sec_pmic->dev); + sec_pmic->pdata = pdata; + switch (sec_pmic->device_type) { case S2MPA01: regmap = &s2mpa01_regmap_config; @@ -408,9 +371,6 @@ static int sec_pmic_probe(struct i2c_client *i2c, return ret; } - if (pdata && pdata->cfg_pmic_irq) - pdata->cfg_pmic_irq(); - sec_irq_init(sec_pmic); pm_runtime_set_active(sec_pmic->dev); @@ -462,7 +422,6 @@ static int sec_pmic_probe(struct i2c_client *i2c, if (ret) return ret; - device_init_wakeup(sec_pmic->dev, sec_pmic->wakeup); sec_pmic_configure(sec_pmic); sec_pmic_dump_rev(sec_pmic); @@ -533,21 +492,14 @@ static int sec_pmic_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(sec_pmic_pm_ops, sec_pmic_suspend, sec_pmic_resume); -static const struct i2c_device_id sec_pmic_id[] = { - { "sec_pmic", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, sec_pmic_id); - static struct i2c_driver sec_pmic_driver = { .driver = { .name = "sec_pmic", .pm = &sec_pmic_pm_ops, - .of_match_table = of_match_ptr(sec_dt_match), + .of_match_table = sec_dt_match, }, .probe = sec_pmic_probe, .shutdown = sec_pmic_shutdown, - .id_table = sec_pmic_id, }; module_i2c_driver(sec_pmic_driver); diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index a98c5d165039..e473c2fb42d5 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c @@ -444,7 +444,6 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) if (!sec_pmic->irq) { dev_warn(sec_pmic->dev, "No interrupt specified, no interrupts\n"); - sec_pmic->irq_base = 0; return 0; } @@ -482,8 +481,7 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic) ret = devm_regmap_add_irq_chip(sec_pmic->dev, sec_pmic->regmap_pmic, sec_pmic->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - sec_pmic->irq_base, sec_irq_chip, - &sec_pmic->irq_data); + 0, sec_irq_chip, &sec_pmic->irq_data); if (ret != 0) { dev_err(sec_pmic->dev, "Failed to register IRQ chip: %d\n", ret); return ret; diff --git a/drivers/mfd/si476x-cmd.c b/drivers/mfd/si476x-cmd.c index d15b3e783369..f32f1fb93e37 100644 --- a/drivers/mfd/si476x-cmd.c +++ b/drivers/mfd/si476x-cmd.c @@ -390,7 +390,7 @@ static int si476x_cmd_tune_seek_freq(struct si476x_core *core, } /** - * si476x_cmd_func_info() - send 'FUNC_INFO' command to the device + * si476x_core_cmd_func_info() - send 'FUNC_INFO' command to the device * @core: device to send the command to * @info: struct si476x_func_info to fill all the information * returned by the command @@ -424,7 +424,7 @@ int si476x_core_cmd_func_info(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_cmd_func_info); /** - * si476x_cmd_set_property() - send 'SET_PROPERTY' command to the device + * si476x_core_cmd_set_property() - send 'SET_PROPERTY' command to the device * @core: device to send the command to * @property: property address * @value: property value @@ -452,7 +452,7 @@ int si476x_core_cmd_set_property(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_cmd_set_property); /** - * si476x_cmd_get_property() - send 'GET_PROPERTY' command to the device + * si476x_core_cmd_get_property() - send 'GET_PROPERTY' command to the device * @core: device to send the command to * @property: property address * @@ -481,7 +481,7 @@ int si476x_core_cmd_get_property(struct si476x_core *core, u16 property) EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property); /** - * si476x_cmd_dig_audio_pin_cfg() - send 'DIG_AUDIO_PIN_CFG' command to + * si476x_core_cmd_dig_audio_pin_cfg() - send 'DIG_AUDIO_PIN_CFG' command to * the device * @core: device to send the command to * @dclk: DCLK pin function configuration: @@ -539,7 +539,7 @@ int si476x_core_cmd_dig_audio_pin_cfg(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_cmd_dig_audio_pin_cfg); /** - * si476x_cmd_zif_pin_cfg - send 'ZIF_PIN_CFG_COMMAND' + * si476x_core_cmd_zif_pin_cfg - send 'ZIF_PIN_CFG_COMMAND' * @core: - device to send the command to * @iqclk: - IQCL pin function configuration: * SI476X_IQCLK_NOOP - do not modify the behaviour @@ -588,7 +588,7 @@ int si476x_core_cmd_zif_pin_cfg(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_cmd_zif_pin_cfg); /** - * si476x_cmd_ic_link_gpo_ctl_pin_cfg - send + * si476x_core_cmd_ic_link_gpo_ctl_pin_cfg - send * 'IC_LINK_GPIO_CTL_PIN_CFG' comand to the device * @core: - device to send the command to * @icin: - ICIN pin function configuration: @@ -645,7 +645,7 @@ int si476x_core_cmd_ic_link_gpo_ctl_pin_cfg(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_cmd_ic_link_gpo_ctl_pin_cfg); /** - * si476x_cmd_ana_audio_pin_cfg - send 'ANA_AUDIO_PIN_CFG' to the + * si476x_core_cmd_ana_audio_pin_cfg - send 'ANA_AUDIO_PIN_CFG' to the * device * @core: - device to send the command to * @lrout: - LROUT pin function configuration: @@ -674,7 +674,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_ana_audio_pin_cfg); /** - * si476x_cmd_intb_pin_cfg - send 'INTB_PIN_CFG' command to the device + * si476x_core_cmd_intb_pin_cfg_a10 - send 'INTB_PIN_CFG' command to the device * @core: - device to send the command to * @intb: - INTB pin function configuration: * SI476X_INTB_NOOP - do not modify the behaviour @@ -726,12 +726,12 @@ static int si476x_core_cmd_intb_pin_cfg_a20(struct si476x_core *core, /** - * si476x_cmd_am_rsq_status - send 'AM_RSQ_STATUS' command to the + * si476x_core_cmd_am_rsq_status - send 'AM_RSQ_STATUS' command to the * device * @core: - device to send the command to * @rsqargs: - pointer to a structure containing a group of sub-args * relevant to sending the RSQ status command - * @report: - all signal quality information retured by the command + * @report: - all signal quality information returned by the command * (if NULL then the output of the command is ignored) * * Function returns 0 on success and negative error code on failure @@ -856,7 +856,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_am_acf_status); /** - * si476x_cmd_fm_seek_start - send 'FM_SEEK_START' command to the + * si476x_core_cmd_fm_seek_start - send 'FM_SEEK_START' command to the * device * @core: - device to send the command to * @seekup: - if set the direction of the search is 'up' @@ -884,7 +884,7 @@ int si476x_core_cmd_fm_seek_start(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_seek_start); /** - * si476x_cmd_fm_rds_status - send 'FM_RDS_STATUS' command to the + * si476x_core_cmd_fm_rds_status - send 'FM_RDS_STATUS' command to the * device * @core: - device to send the command to * @status_only: - if set the data is not removed from RDSFIFO, @@ -892,7 +892,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_seek_start); * rest RDS data contains the last valid info received * @mtfifo: if set the command clears RDS receive FIFO * @intack: if set the command clards the RDSINT bit. - * @report: - all signal quality information retured by the command + * @report: - all signal quality information returned by the command * (if NULL then the output of the command is ignored) * * Function returns 0 on success and negative error code on failure @@ -1032,7 +1032,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_div_status); /** - * si476x_cmd_am_seek_start - send 'FM_SEEK_START' command to the + * si476x_core_cmd_am_seek_start - send 'FM_SEEK_START' command to the * device * @core: - device to send the command to * @seekup: - if set the direction of the search is 'up' diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c index c1d7b845244e..a2635c2d9d1a 100644 --- a/drivers/mfd/si476x-i2c.c +++ b/drivers/mfd/si476x-i2c.c @@ -350,7 +350,7 @@ static inline void si476x_core_start_rds_drainer_once(struct si476x_core *core) mutex_unlock(&core->rds_drainer_status_lock); } /** - * si476x_drain_rds_fifo() - RDS buffer drainer. + * si476x_core_drain_rds_fifo() - RDS buffer drainer. * @work: struct work_struct being ppassed to the function by the * kernel. * @@ -454,7 +454,7 @@ int si476x_core_i2c_xfer(struct si476x_core *core, EXPORT_SYMBOL_GPL(si476x_core_i2c_xfer); /** - * si476x_get_status() + * si476x_core_get_status() * @core: Core device structure * * Get the status byte of the core device by berforming one byte I2C @@ -473,7 +473,7 @@ static int si476x_core_get_status(struct si476x_core *core) } /** - * si476x_get_and_signal_status() - IRQ dispatcher + * si476x_core_get_and_signal_status() - IRQ dispatcher * @core: Core device structure * * Dispatch the arrived interrupt request based on the value of the @@ -532,7 +532,7 @@ static irqreturn_t si476x_core_interrupt(int irq, void *dev) } /** - * si476x_firmware_version_to_revision() + * si476x_core_fwver_to_revision() * @core: Core device structure * @func: Selects the boot function of the device: * *_BOOTLOADER - Boot loader @@ -603,7 +603,7 @@ unknown_revision: } /** - * si476x_get_revision_info() + * si476x_core_get_revision_info() * @core: Core device structure * * Get the firmware version number of the device. It is done in diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 6d2f4a0a901d..bc0a2c38653e 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1190,13 +1190,13 @@ static int sm501_register_gpio_i2c(struct sm501_devdata *sm, return 0; } -/* sm501_dbg_regs +/* dbg_regs_show * * Debug attribute to attach to parent device to show core registers */ -static ssize_t sm501_dbg_regs(struct device *dev, - struct device_attribute *attr, char *buff) +static ssize_t dbg_regs_show(struct device *dev, + struct device_attribute *attr, char *buff) { struct sm501_devdata *sm = dev_get_drvdata(dev) ; unsigned int reg; @@ -1213,7 +1213,7 @@ static ssize_t sm501_dbg_regs(struct device *dev, } -static DEVICE_ATTR(dbg_regs, 0444, sm501_dbg_regs, NULL); +static DEVICE_ATTR_RO(dbg_regs); /* sm501_init_reg * diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 61aa020199f5..cd2f45257dc1 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -109,7 +109,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe2403", STMPE2403 }, { } }; -MODULE_DEVICE_TABLE(i2c, stmpe_id); +MODULE_DEVICE_TABLE(i2c, stmpe_i2c_id); static struct i2c_driver stmpe_i2c_driver = { .driver = { diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c index c31927d4bbbe..ee03db0b8485 100644 --- a/drivers/mfd/sun6i-prcm.c +++ b/drivers/mfd/sun6i-prcm.c @@ -20,43 +20,23 @@ struct prcm_data { }; static const struct resource sun6i_a31_ar100_clk_res[] = { - { - .start = 0x0, - .end = 0x3, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0x0, 4) }; static const struct resource sun6i_a31_apb0_clk_res[] = { - { - .start = 0xc, - .end = 0xf, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0xc, 4) }; static const struct resource sun6i_a31_apb0_gates_clk_res[] = { - { - .start = 0x28, - .end = 0x2b, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0x28, 4) }; static const struct resource sun6i_a31_ir_clk_res[] = { - { - .start = 0x54, - .end = 0x57, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0x54, 4) }; static const struct resource sun6i_a31_apb0_rstc_res[] = { - { - .start = 0xb0, - .end = 0xb3, - .flags = IORESOURCE_MEM, - }, + DEFINE_RES_MEM(0xb0, 4) }; static const struct resource sun8i_codec_analog_res[] = { diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index c6f139b2e0c0..765c0210cb52 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -108,6 +108,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) syscon_config.max_register = resource_size(&res) - reg_io_width; regmap = regmap_init_mmio(NULL, base, &syscon_config); + kfree(syscon_config.name); if (IS_ERR(regmap)) { pr_err("regmap init failed\n"); ret = PTR_ERR(regmap); @@ -144,7 +145,6 @@ err_clk: regmap_exit(regmap); err_regmap: iounmap(base); - kfree(syscon_config.name); err_map: kfree(syscon); return ERR_PTR(ret); diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 70da0c4ae457..5369c67e3280 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c @@ -37,16 +37,8 @@ enum { }; static const struct resource t7l66xb_mmc_resources[] = { - { - .start = 0x800, - .end = 0x9ff, - .flags = IORESOURCE_MEM, - }, - { - .start = IRQ_T7L66XB_MMC, - .end = IRQ_T7L66XB_MMC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_MEM(0x800, 0x200), + DEFINE_RES_IRQ(IRQ_T7L66XB_MMC) }; #define SCR_REVID 0x08 /* b Revision ID */ diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index faecbca6dba3..9393ee60a656 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -623,8 +623,8 @@ static const struct mfd_cell timberdale_cells_bar2[] = { }, }; -static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t fw_ver_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct timberdale_device *priv = dev_get_drvdata(dev); @@ -632,7 +632,7 @@ static ssize_t show_fw_ver(struct device *dev, struct device_attribute *attr, priv->fw.config); } -static DEVICE_ATTR(fw_ver, S_IRUGO, show_fw_ver, NULL); +static DEVICE_ATTR_RO(fw_ver); /*--------------------------------------------------------------------------*/ diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index 902e33548dd0..3c4e62c3406a 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c @@ -35,11 +35,7 @@ #include <linux/slab.h> static const struct resource tps80031_rtc_resources[] = { - { - .start = TPS80031_INT_RTC_ALARM, - .end = TPS80031_INT_RTC_ALARM, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(TPS80031_INT_RTC_ALARM), }; /* TPS80031 sub mfd devices */ diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 20cf8cfe4f3b..289b556dede2 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -485,7 +485,7 @@ int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes) EXPORT_SYMBOL(twl_i2c_read); /** - * twl_regcache_bypass - Configure the regcache bypass for the regmap associated + * twl_set_regcache_bypass - Configure the regcache bypass for the regmap associated * with the module * @mod_no: module number * @enable: Regcache bypass state diff --git a/drivers/mfd/ucb1x00-assabet.c b/drivers/mfd/ucb1x00-assabet.c index ecc9e9fc331d..6a389737c615 100644 --- a/drivers/mfd/ucb1x00-assabet.c +++ b/drivers/mfd/ucb1x00-assabet.c @@ -28,7 +28,7 @@ static ssize_t name##_show(struct device *dev, struct device_attribute *attr, \ ucb1x00_adc_disable(ucb); \ return sprintf(buf, "%d\n", val); \ } \ -static DEVICE_ATTR(name,0444,name##_show,NULL) +static DEVICE_ATTR_RO(name) UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1); UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0); diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c index c274d733b656..aa19a6a4fdbf 100644 --- a/drivers/mfd/wcd934x.c +++ b/drivers/mfd/wcd934x.c @@ -17,6 +17,21 @@ #include <linux/regulator/consumer.h> #include <linux/slimbus.h> +#define WCD934X_REGMAP_IRQ_REG(_irq, _off, _mask) \ + [_irq] = { \ + .reg_offset = (_off), \ + .mask = (_mask), \ + .type = { \ + .type_reg_offset = (_off), \ + .types_supported = IRQ_TYPE_EDGE_BOTH, \ + .type_reg_mask = (_mask), \ + .type_level_low_val = (_mask), \ + .type_level_high_val = (_mask), \ + .type_falling_val = 0, \ + .type_rising_val = 0, \ + }, \ + } + static const struct mfd_cell wcd934x_devices[] = { { .name = "wcd934x-codec", @@ -30,32 +45,15 @@ static const struct mfd_cell wcd934x_devices[] = { }; static const struct regmap_irq wcd934x_irqs[] = { - [WCD934X_IRQ_SLIMBUS] = { - .reg_offset = 0, - .mask = BIT(0), - .type = { - .type_reg_offset = 0, - .types_supported = IRQ_TYPE_EDGE_BOTH, - .type_reg_mask = BIT(0), - .type_level_low_val = BIT(0), - .type_level_high_val = BIT(0), - .type_falling_val = 0, - .type_rising_val = 0, - }, - }, - [WCD934X_IRQ_SOUNDWIRE] = { - .reg_offset = 2, - .mask = BIT(4), - .type = { - .type_reg_offset = 2, - .types_supported = IRQ_TYPE_EDGE_BOTH, - .type_reg_mask = BIT(4), - .type_level_low_val = BIT(4), - .type_level_high_val = BIT(4), - .type_falling_val = 0, - .type_rising_val = 0, - }, - }, + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_SLIMBUS, 0, BIT(0)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_HPH_PA_OCPL_FAULT, 0, BIT(2)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_HPH_PA_OCPR_FAULT, 0, BIT(3)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_MBHC_SW_DET, 1, BIT(0)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_MBHC_ELECT_INS_REM_DET, 1, BIT(1)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_MBHC_BUTTON_PRESS_DET, 1, BIT(2)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_MBHC_BUTTON_RELEASE_DET, 1, BIT(3)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 1, BIT(4)), + WCD934X_REGMAP_IRQ_REG(WCD934X_IRQ_SOUNDWIRE, 2, BIT(4)), }; static const struct regmap_irq_chip wcd934x_regmap_irq_chip = { diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index bcef08f58fb3..d2f444d2ae78 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -109,7 +109,7 @@ static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg) } /** - * wm831x_reg_unlock: Unlock user keyed registers + * wm831x_reg_lock: Unlock user keyed registers * * The WM831x has a user key preventing writes to particularly * critical registers. This function locks those registers, @@ -622,18 +622,8 @@ static const struct resource wm831x_dcdc1_resources[] = { .end = WM831X_DC1_DVS_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC1, - .end = WM831X_IRQ_UV_DC1, - .flags = IORESOURCE_IRQ, - }, - { - .name = "HC", - .start = WM831X_IRQ_HC_DC1, - .end = WM831X_IRQ_HC_DC1, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC1, "UV"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_HC_DC1, "HC"), }; @@ -643,18 +633,8 @@ static const struct resource wm831x_dcdc2_resources[] = { .end = WM831X_DC2_DVS_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC2, - .end = WM831X_IRQ_UV_DC2, - .flags = IORESOURCE_IRQ, - }, - { - .name = "HC", - .start = WM831X_IRQ_HC_DC2, - .end = WM831X_IRQ_HC_DC2, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC2, "UV"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_HC_DC2, "HC"), }; static const struct resource wm831x_dcdc3_resources[] = { @@ -663,12 +643,7 @@ static const struct resource wm831x_dcdc3_resources[] = { .end = WM831X_DC3_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC3, - .end = WM831X_IRQ_UV_DC3, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC3, "UV"), }; static const struct resource wm831x_dcdc4_resources[] = { @@ -677,12 +652,7 @@ static const struct resource wm831x_dcdc4_resources[] = { .end = WM831X_DC4_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC4, - .end = WM831X_IRQ_UV_DC4, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC4, "UV"), }; static const struct resource wm8320_dcdc4_buck_resources[] = { @@ -691,12 +661,7 @@ static const struct resource wm8320_dcdc4_buck_resources[] = { .end = WM832X_DC4_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_DC4, - .end = WM831X_IRQ_UV_DC4, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_DC4, "UV"), }; static const struct resource wm831x_gpio_resources[] = { @@ -713,11 +678,7 @@ static const struct resource wm831x_isink1_resources[] = { .end = WM831X_CURRENT_SINK_1, .flags = IORESOURCE_REG, }, - { - .start = WM831X_IRQ_CS1, - .end = WM831X_IRQ_CS1, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(WM831X_IRQ_CS1), }; static const struct resource wm831x_isink2_resources[] = { @@ -726,11 +687,7 @@ static const struct resource wm831x_isink2_resources[] = { .end = WM831X_CURRENT_SINK_2, .flags = IORESOURCE_REG, }, - { - .start = WM831X_IRQ_CS2, - .end = WM831X_IRQ_CS2, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(WM831X_IRQ_CS2), }; static const struct resource wm831x_ldo1_resources[] = { @@ -739,12 +696,7 @@ static const struct resource wm831x_ldo1_resources[] = { .end = WM831X_LDO1_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO1, - .end = WM831X_IRQ_UV_LDO1, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO1, "UV"), }; static const struct resource wm831x_ldo2_resources[] = { @@ -753,12 +705,7 @@ static const struct resource wm831x_ldo2_resources[] = { .end = WM831X_LDO2_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO2, - .end = WM831X_IRQ_UV_LDO2, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO2, "UV"), }; static const struct resource wm831x_ldo3_resources[] = { @@ -767,12 +714,7 @@ static const struct resource wm831x_ldo3_resources[] = { .end = WM831X_LDO3_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO3, - .end = WM831X_IRQ_UV_LDO3, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO3, "UV"), }; static const struct resource wm831x_ldo4_resources[] = { @@ -781,12 +723,7 @@ static const struct resource wm831x_ldo4_resources[] = { .end = WM831X_LDO4_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO4, - .end = WM831X_IRQ_UV_LDO4, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO4, "UV"), }; static const struct resource wm831x_ldo5_resources[] = { @@ -795,12 +732,7 @@ static const struct resource wm831x_ldo5_resources[] = { .end = WM831X_LDO5_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO5, - .end = WM831X_IRQ_UV_LDO5, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO5, "UV"), }; static const struct resource wm831x_ldo6_resources[] = { @@ -809,12 +741,7 @@ static const struct resource wm831x_ldo6_resources[] = { .end = WM831X_LDO6_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO6, - .end = WM831X_IRQ_UV_LDO6, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO6, "UV"), }; static const struct resource wm831x_ldo7_resources[] = { @@ -823,12 +750,7 @@ static const struct resource wm831x_ldo7_resources[] = { .end = WM831X_LDO7_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO7, - .end = WM831X_IRQ_UV_LDO7, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO7, "UV"), }; static const struct resource wm831x_ldo8_resources[] = { @@ -837,12 +759,7 @@ static const struct resource wm831x_ldo8_resources[] = { .end = WM831X_LDO8_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO8, - .end = WM831X_IRQ_UV_LDO8, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO8, "UV"), }; static const struct resource wm831x_ldo9_resources[] = { @@ -851,12 +768,7 @@ static const struct resource wm831x_ldo9_resources[] = { .end = WM831X_LDO9_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO9, - .end = WM831X_IRQ_UV_LDO9, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO9, "UV"), }; static const struct resource wm831x_ldo10_resources[] = { @@ -865,12 +777,7 @@ static const struct resource wm831x_ldo10_resources[] = { .end = WM831X_LDO10_SLEEP_CONTROL, .flags = IORESOURCE_REG, }, - { - .name = "UV", - .start = WM831X_IRQ_UV_LDO10, - .end = WM831X_IRQ_UV_LDO10, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_UV_LDO10, "UV"), }; static const struct resource wm831x_ldo11_resources[] = { @@ -882,96 +789,27 @@ static const struct resource wm831x_ldo11_resources[] = { }; static const struct resource wm831x_on_resources[] = { - { - .start = WM831X_IRQ_ON, - .end = WM831X_IRQ_ON, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(WM831X_IRQ_ON), }; static const struct resource wm831x_power_resources[] = { - { - .name = "SYSLO", - .start = WM831X_IRQ_PPM_SYSLO, - .end = WM831X_IRQ_PPM_SYSLO, - .flags = IORESOURCE_IRQ, - }, - { - .name = "PWR SRC", - .start = WM831X_IRQ_PPM_PWR_SRC, - .end = WM831X_IRQ_PPM_PWR_SRC, - .flags = IORESOURCE_IRQ, - }, - { - .name = "USB CURR", - .start = WM831X_IRQ_PPM_USB_CURR, - .end = WM831X_IRQ_PPM_USB_CURR, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT HOT", - .start = WM831X_IRQ_CHG_BATT_HOT, - .end = WM831X_IRQ_CHG_BATT_HOT, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT COLD", - .start = WM831X_IRQ_CHG_BATT_COLD, - .end = WM831X_IRQ_CHG_BATT_COLD, - .flags = IORESOURCE_IRQ, - }, - { - .name = "BATT FAIL", - .start = WM831X_IRQ_CHG_BATT_FAIL, - .end = WM831X_IRQ_CHG_BATT_FAIL, - .flags = IORESOURCE_IRQ, - }, - { - .name = "OV", - .start = WM831X_IRQ_CHG_OV, - .end = WM831X_IRQ_CHG_OV, - .flags = IORESOURCE_IRQ, - }, - { - .name = "END", - .start = WM831X_IRQ_CHG_END, - .end = WM831X_IRQ_CHG_END, - .flags = IORESOURCE_IRQ, - }, - { - .name = "TO", - .start = WM831X_IRQ_CHG_TO, - .end = WM831X_IRQ_CHG_TO, - .flags = IORESOURCE_IRQ, - }, - { - .name = "MODE", - .start = WM831X_IRQ_CHG_MODE, - .end = WM831X_IRQ_CHG_MODE, - .flags = IORESOURCE_IRQ, - }, - { - .name = "START", - .start = WM831X_IRQ_CHG_START, - .end = WM831X_IRQ_CHG_START, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_PPM_SYSLO, "SYSLO"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_PPM_PWR_SRC, "PWR SRC"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_PPM_USB_CURR, "USB CURR"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_BATT_HOT, "BATT HOT"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_BATT_COLD, "BATT COLD"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_BATT_FAIL, "BATT FAIL"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_OV, "OV"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_END, "END"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_TO, "TO"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_MODE, "MODE"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_CHG_START, "START"), }; static const struct resource wm831x_rtc_resources[] = { - { - .name = "PER", - .start = WM831X_IRQ_RTC_PER, - .end = WM831X_IRQ_RTC_PER, - .flags = IORESOURCE_IRQ, - }, - { - .name = "ALM", - .start = WM831X_IRQ_RTC_ALM, - .end = WM831X_IRQ_RTC_ALM, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_RTC_PER, "PER"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_RTC_ALM, "ALM"), }; static const struct resource wm831x_status1_resources[] = { @@ -991,26 +829,12 @@ static const struct resource wm831x_status2_resources[] = { }; static const struct resource wm831x_touch_resources[] = { - { - .name = "TCHPD", - .start = WM831X_IRQ_TCHPD, - .end = WM831X_IRQ_TCHPD, - .flags = IORESOURCE_IRQ, - }, - { - .name = "TCHDATA", - .start = WM831X_IRQ_TCHDATA, - .end = WM831X_IRQ_TCHDATA, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_TCHPD, "TCHPD"), + DEFINE_RES_IRQ_NAMED(WM831X_IRQ_TCHDATA, "TCHDATA"), }; static const struct resource wm831x_wdt_resources[] = { - { - .start = WM831X_IRQ_WDOG_TO, - .end = WM831X_IRQ_WDOG_TO, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(WM831X_IRQ_WDOG_TO), }; static const struct mfd_cell wm8310_devs[] = { diff --git a/drivers/mfd/wm831x-otp.c b/drivers/mfd/wm831x-otp.c index afe59d52dd74..25f5d9fe33a1 100644 --- a/drivers/mfd/wm831x-otp.c +++ b/drivers/mfd/wm831x-otp.c @@ -38,8 +38,8 @@ static int wm831x_unique_id_read(struct wm831x *wm831x, char *id) return 0; } -static ssize_t wm831x_unique_id_show(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t unique_id_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct wm831x *wm831x = dev_get_drvdata(dev); int rval; @@ -52,7 +52,7 @@ static ssize_t wm831x_unique_id_show(struct device *dev, return sprintf(buf, "%*phN\n", WM831X_UNIQUE_ID_LEN, id); } -static DEVICE_ATTR(unique_id, 0444, wm831x_unique_id_show, NULL); +static DEVICE_ATTR_RO(unique_id); int wm831x_otp_init(struct wm831x *wm831x) { |