summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/Makefile2
-rw-r--r--Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml2
-rw-r--r--Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml1
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon-common.yaml34
-rw-r--r--Documentation/devicetree/bindings/mfd/syscon.yaml116
-rw-r--r--MAINTAINERS11
-rw-r--r--drivers/mfd/88pm886.c21
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/axp20x.c2
-rw-r--r--drivers/mfd/cs42l43-i2c.c2
-rw-r--r--drivers/mfd/cs42l43-sdw.c7
-rw-r--r--drivers/mfd/cs42l43.c15
-rw-r--r--drivers/mfd/ipaq-micro.c2
-rw-r--r--drivers/mfd/mt6397-core.c3
-rw-r--r--drivers/mfd/rohm-bd71828.c125
-rw-r--r--drivers/mfd/rohm-bd718x7.c123
-rw-r--r--drivers/mfd/si476x-cmd.c1
-rw-r--r--drivers/mfd/si476x-i2c.c46
-rw-r--r--include/linux/mfd/88pm886.h5
-rw-r--r--include/linux/mfd/cs42l43.h2
-rw-r--r--include/linux/mfd/si476x-core.h5
-rw-r--r--include/linux/mfd/si476x-platform.h2
22 files changed, 286 insertions, 242 deletions
diff --git a/Documentation/devicetree/bindings/Makefile b/Documentation/devicetree/bindings/Makefile
index 00149e824261..6b4b4f51c371 100644
--- a/Documentation/devicetree/bindings/Makefile
+++ b/Documentation/devicetree/bindings/Makefile
@@ -6,7 +6,7 @@ DT_MK_SCHEMA ?= dt-mk-schema
DT_SCHEMA_LINT = $(shell which yamllint || \
echo "warning: python package 'yamllint' not installed, skipping" >&2)
-DT_SCHEMA_MIN_VERSION = 2023.9
+DT_SCHEMA_MIN_VERSION = 2024.4
PHONY += check_dtschema_version
check_dtschema_version:
diff --git a/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml b/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml
index 92a72a99fd79..940262898353 100644
--- a/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml
+++ b/Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml
@@ -29,7 +29,7 @@ properties:
type: object
additionalProperties: false
patternProperties:
- "^(ldo(1[0-6]|[1-9])|buck[1-5])$":
+ "^(ldo(1[0-6]|[1-9])|buck[1-5]|vbus)$":
type: object
$ref: /schemas/regulator/regulator.yaml#
description: LDO or buck regulator.
diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index 644c42b5e2e5..809be2756a0c 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -80,6 +80,7 @@ properties:
- qcom,pmcx0102
- qcom,pmd8028
- qcom,pmd9635
+ - qcom,pmg1110
- qcom,pmh0101
- qcom,pmh0104
- qcom,pmh0110
diff --git a/Documentation/devicetree/bindings/mfd/syscon-common.yaml b/Documentation/devicetree/bindings/mfd/syscon-common.yaml
index 14a08e7bc8bd..2d5eef5add54 100644
--- a/Documentation/devicetree/bindings/mfd/syscon-common.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon-common.yaml
@@ -32,6 +32,7 @@ properties:
compatible:
contains:
const: syscon
+ # Always require a specific compatible for syscon
minItems: 2
maxItems: 5 # Should be enough
@@ -52,11 +53,44 @@ allOf:
contains:
const: simple-mfd
then:
+ # Always require a specific compatible for syscon with simple-mfd
properties:
compatible:
minItems: 3
maxItems: 5
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: simple-bus
+ then:
+ # simple-bus conflicts with syscon - if a device is a system controller
+ # with miscellaneous registers, then it has at least one dedicated
+ # function thus it is not a simple bus. Allow existing exceptions.
+ if:
+ properties:
+ compatible:
+ not:
+ contains:
+ # This list CANNOT grow
+ enum:
+ - cznic,turris1x-cpld
+ - img,pistachio-cr-periph
+ - ti,am3352-scm-conf
+ - ti,am4372-scm-conf
+ - ti,dm814-scm-conf
+ - ti,dm8168-scm-conf
+ - ti,dra7-scm-conf
+ - ti,omap2-scm-conf
+ - ti,omap3-scm-conf
+ - ti,omap4-sysc-padconf-global
+ - ti,omap5-scm-wkup-conf
+ - ti,omap5-sysc-padconf-global
+ then:
+ required:
+ - incorrect-usage-of-simple-bus-and-syscon
+
additionalProperties: true
examples:
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index e22867088063..fe882d3f828b 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -19,122 +19,6 @@ description: |
maintainers:
- Lee Jones <lee@kernel.org>
-# Need a select with all compatibles listed for compatibility with older
-# dtschema (<2024.02), so this will not be selected for other schemas having
-# syscon fallback.
-select:
- properties:
- compatible:
- contains:
- enum:
- - airoha,en7581-pbus-csr
- - al,alpine-sysfabric-service
- - allwinner,sun8i-a83t-system-controller
- - allwinner,sun8i-h3-system-controller
- - allwinner,sun8i-v3s-system-controller
- - allwinner,sun50i-a64-system-controller
- - altr,l3regs
- - altr,sdr-ctl
- - amd,pensando-elba-syscon
- - amlogic,meson-mx-assist
- - amlogic,meson-mx-bootrom
- - amlogic,meson8-analog-top
- - amlogic,meson8b-analog-top
- - amlogic,meson8-pmu
- - amlogic,meson8b-pmu
- - apm,merlin-poweroff-mailbox
- - apm,mustang-poweroff-mailbox
- - apm,xgene-csw
- - apm,xgene-efuse
- - apm,xgene-mcb
- - apm,xgene-rb
- - apm,xgene-scu
- - atmel,sama5d2-sfrbu
- - atmel,sama5d3-nfc-io
- - atmel,sama5d3-sfrbu
- - atmel,sama5d4-sfrbu
- - axis,artpec6-syscon
- - brcm,cru-clkset
- - brcm,sr-cdru
- - brcm,sr-mhb
- - cirrus,ep7209-syscon1
- - cirrus,ep7209-syscon2
- - cirrus,ep7209-syscon3
- - cnxt,cx92755-uc
- - econet,en751221-chip-scu
- - freecom,fsg-cs2-system-controller
- - fsl,imx93-aonmix-ns-syscfg
- - fsl,imx93-wakeupmix-syscfg
- - fsl,ls1088a-reset
- - fsl,vf610-anatop
- - fsl,vf610-mscm-cpucfg
- - hisilicon,dsa-subctrl
- - hisilicon,hi6220-sramctrl
- - hisilicon,hip04-ppe
- - hisilicon,pcie-sas-subctrl
- - hisilicon,peri-subctrl
- - hpe,gxp-sysreg
- - loongson,ls1b-syscon
- - loongson,ls1c-syscon
- - lsi,axxia-syscon
- - marvell,armada-3700-cpu-misc
- - marvell,armada-3700-nb-pm
- - marvell,armada-3700-avs
- - marvell,armada-3700-usb2-host-device-misc
- - marvell,armada-3700-usb2-host-misc
- - marvell,dove-global-config
- - mediatek,mt2701-pctl-a-syscfg
- - mediatek,mt2712-pctl-a-syscfg
- - mediatek,mt6397-pctl-pmic-syscfg
- - mediatek,mt7981-topmisc
- - mediatek,mt7988-topmisc
- - mediatek,mt8135-pctl-a-syscfg
- - mediatek,mt8135-pctl-b-syscfg
- - mediatek,mt8173-pctl-a-syscfg
- - mediatek,mt8365-syscfg
- - microchip,lan966x-cpu-syscon
- - microchip,mpfs-control-scb
- - microchip,mpfs-sysreg-scb
- - microchip,sam9x60-sfr
- - microchip,sama7d65-ddr3phy
- - microchip,sama7d65-sfrbu
- - microchip,sama7g5-ddr3phy
- - mscc,ocelot-cpu-syscon
- - mstar,msc313-pmsleep
- - nuvoton,ma35d1-sys
- - nuvoton,wpcm450-shm
- - nxp,s32g2-gpr
- - nxp,s32g3-gpr
- - qcom,apq8064-mmss-sfpb
- - qcom,apq8064-sps-sic
- - rockchip,px30-qos
- - rockchip,rk3036-qos
- - rockchip,rk3066-qos
- - rockchip,rk3128-qos
- - rockchip,rk3228-qos
- - rockchip,rk3288-qos
- - rockchip,rk3368-qos
- - rockchip,rk3399-qos
- - rockchip,rk3528-qos
- - rockchip,rk3562-qos
- - rockchip,rk3568-qos
- - rockchip,rk3576-qos
- - rockchip,rk3588-qos
- - rockchip,rv1126-qos
- - st,spear1340-misc
- - stericsson,nomadik-pmu
- - starfive,jh7100-sysmain
- - ti,am62-opp-efuse-table
- - ti,am62-usb-phy-ctrl
- - ti,am625-dss-oldi-io-ctrl
- - ti,am62p-cpsw-mac-efuse
- - ti,am654-dss-oldi-io-ctrl
- - ti,j784s4-acspcie-proxy-ctrl
- - ti,j784s4-pcie-ctrl
- - ti,keystone-pllctrl
- required:
- - compatible
-
properties:
compatible:
oneOf:
diff --git a/MAINTAINERS b/MAINTAINERS
index 5f1cfb757d3b..64cf4f7cac86 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13230,6 +13230,17 @@ F: drivers/spi/spi-ljca.c
F: drivers/usb/misc/usb-ljca.c
F: include/linux/usb/ljca.h
+INTEL LPSS (Low Power SubSystem) DRIVERS
+R: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+S: Supported
+F: drivers/dma/idma64*
+F: drivers/i2c/busses/i2c-designware-*
+F: drivers/mfd/intel-lpss*
+F: drivers/pwm/pwm-lpss*
+F: drivers/tty/serial/8250/8250_dw.c
+F: drivers/tty/serial/8250/8250_dwlib.*
+F: drivers/spi/spi-pxa2xx*
+
INTEL MANAGEMENT ENGINE (mei)
M: Alexander Usyskin <alexander.usyskin@intel.com>
L: linux-kernel@vger.kernel.org
diff --git a/drivers/mfd/88pm886.c b/drivers/mfd/88pm886.c
index e411d8dee554..f8401d5e6dbe 100644
--- a/drivers/mfd/88pm886.c
+++ b/drivers/mfd/88pm886.c
@@ -16,6 +16,12 @@ static const struct regmap_config pm886_regmap_config = {
.max_register = PM886_REG_RTC_SPARE6,
};
+static const struct regmap_config pm886_regmap_battery_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = PM886_REG_CLS_CONFIG1,
+};
+
static const struct regmap_irq pm886_regmap_irqs[] = {
REGMAP_IRQ_REG(PM886_IRQ_ONKEY, 0, PM886_INT_ENA1_ONKEY),
};
@@ -85,10 +91,11 @@ static int pm886_setup_irq(struct pm886_chip *chip,
static int pm886_probe(struct i2c_client *client)
{
+ struct regmap *regmap, *regmap_battery;
struct regmap_irq_chip_data *irq_data;
struct device *dev = &client->dev;
+ struct i2c_client *battery_page;
struct pm886_chip *chip;
- struct regmap *regmap;
unsigned int chip_id;
int err;
@@ -112,6 +119,18 @@ static int pm886_probe(struct i2c_client *client)
if (chip->chip_id != chip_id)
return dev_err_probe(dev, -EINVAL, "Unsupported chip: 0x%x\n", chip_id);
+ battery_page = devm_i2c_new_dummy_device(dev, client->adapter,
+ client->addr + PM886_PAGE_OFFSET_BATTERY);
+ if (IS_ERR(battery_page))
+ return dev_err_probe(dev, PTR_ERR(battery_page),
+ "Failed to initialize battery page\n");
+
+ regmap_battery = devm_regmap_init_i2c(battery_page, &pm886_regmap_battery_config);
+ if (IS_ERR(regmap_battery))
+ return dev_err_probe(dev, PTR_ERR(regmap_battery),
+ "Failed to initialize battery regmap\n");
+ chip->regmap_battery = regmap_battery;
+
err = pm886_setup_irq(chip, &irq_data);
if (err)
return err;
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 763ce6a34782..35f6e9b76d05 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1461,7 +1461,6 @@ config MFD_SEC_I2C
config MFD_SI476X_CORE
tristate "Silicon Laboratories 4761/64/68 AM/FM radio."
depends on I2C
- depends on GPIOLIB_LEGACY
select MFD_CORE
select REGMAP_I2C
help
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 679364189ea5..50df66de24e0 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -1253,7 +1253,7 @@ static int axp20x_power_off(struct sys_off_data *data)
break;
}
- regmap_write(axp20x->regmap, shutdown_reg, AXP20X_OFF);
+ regmap_set_bits(axp20x->regmap, shutdown_reg, AXP20X_OFF);
/* Give capacitors etc. time to drain to avoid kernel panic msg. */
mdelay(500);
diff --git a/drivers/mfd/cs42l43-i2c.c b/drivers/mfd/cs42l43-i2c.c
index 44ad63129b3f..cbe05c3ea910 100644
--- a/drivers/mfd/cs42l43-i2c.c
+++ b/drivers/mfd/cs42l43-i2c.c
@@ -44,8 +44,6 @@ static int cs42l43_i2c_probe(struct i2c_client *i2c)
cs42l43->dev = &i2c->dev;
cs42l43->irq = i2c->irq;
- /* A device on an I2C is always attached by definition. */
- cs42l43->attached = true;
cs42l43->variant_id = (long)device_get_match_data(cs42l43->dev);
cs42l43->regmap = devm_regmap_init_i2c(i2c, &cs42l43_i2c_regmap);
diff --git a/drivers/mfd/cs42l43-sdw.c b/drivers/mfd/cs42l43-sdw.c
index 1804b942bdb5..7f0c8d370662 100644
--- a/drivers/mfd/cs42l43-sdw.c
+++ b/drivers/mfd/cs42l43-sdw.c
@@ -99,17 +99,10 @@ static int cs42l43_sdw_update_status(struct sdw_slave *sdw, enum sdw_slave_statu
sdw_write_no_pm(sdw, CS42L43_GEN_INT_MASK_1,
CS42L43_INT_STAT_GEN1_MASK);
-
- cs42l43->attached = true;
-
- complete(&cs42l43->device_attach);
break;
case SDW_SLAVE_UNATTACHED:
dev_dbg(cs42l43->dev, "Device detach\n");
- cs42l43->attached = false;
-
- reinit_completion(&cs42l43->device_attach);
complete(&cs42l43->device_detach);
break;
default:
diff --git a/drivers/mfd/cs42l43.c b/drivers/mfd/cs42l43.c
index ed6d93893de0..d2bbd2f18af7 100644
--- a/drivers/mfd/cs42l43.c
+++ b/drivers/mfd/cs42l43.c
@@ -586,15 +586,13 @@ static int cs42l43_soft_reset(struct cs42l43 *cs42l43)
*/
static int cs42l43_wait_for_attach(struct cs42l43 *cs42l43)
{
- if (!cs42l43->attached) {
- unsigned long timeout = msecs_to_jiffies(CS42L43_SDW_ATTACH_TIMEOUT_MS);
- unsigned long time;
+ int ret;
- time = wait_for_completion_timeout(&cs42l43->device_attach, timeout);
- if (!time) {
- dev_err(cs42l43->dev, "Timed out waiting for device re-attach\n");
- return -ETIMEDOUT;
- }
+ if (cs42l43->sdw) {
+ ret = sdw_slave_wait_for_init(cs42l43->sdw,
+ CS42L43_SDW_ATTACH_TIMEOUT_MS);
+ if (ret)
+ return ret;
}
regcache_cache_only(cs42l43->regmap, false);
@@ -1120,7 +1118,6 @@ int cs42l43_dev_probe(struct cs42l43 *cs42l43)
dev_set_drvdata(cs42l43->dev, cs42l43);
mutex_init(&cs42l43->pll_lock);
- init_completion(&cs42l43->device_attach);
init_completion(&cs42l43->device_detach);
init_completion(&cs42l43->firmware_download);
INIT_WORK(&cs42l43->boot_work, cs42l43_boot_work);
diff --git a/drivers/mfd/ipaq-micro.c b/drivers/mfd/ipaq-micro.c
index 4b757d847282..5146a6eb0e5a 100644
--- a/drivers/mfd/ipaq-micro.c
+++ b/drivers/mfd/ipaq-micro.c
@@ -221,7 +221,7 @@ static void ipaq_micro_eeprom_read(struct ipaq_micro *micro,
static char *ipaq_micro_str(u8 *wchar, u8 len)
{
- char retstr[256];
+ char retstr[256] = { 0 };
u8 i;
for (i = 0; i < len / 2; i++)
diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c
index 1bdacda9a933..ea1d039477e3 100644
--- a/drivers/mfd/mt6397-core.c
+++ b/drivers/mfd/mt6397-core.c
@@ -125,6 +125,9 @@ static const struct resource mt6323_pwrc_resources[] = {
static const struct mfd_cell mt6323_devs[] = {
{
+ .name = "mt6323-efuse",
+ .of_compatible = "mediatek,mt6323-efuse",
+ }, {
.name = "mt6323-rtc",
.num_resources = ARRAY_SIZE(mt6323_rtc_resources),
.resources = mt6323_rtc_resources,
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index a79f354bf5cb..5fb6142cf087 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -5,7 +5,8 @@
* ROHM BD718[15/28/79] and BD72720 PMIC driver
*/
-#include <linux/gpio_keys.h>
+#include <linux/device/devres.h>
+#include <linux/gfp_types.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -18,6 +19,7 @@
#include <linux/mfd/rohm-generic.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/types.h>
@@ -37,19 +39,6 @@
}, \
}
-static struct gpio_keys_button button = {
- .code = KEY_POWER,
- .gpio = -1,
- .type = EV_KEY,
- .wakeup = 1,
-};
-
-static const struct gpio_keys_platform_data bd71828_powerkey_data = {
- .buttons = &button,
- .nbuttons = 1,
- .name = "bd71828-pwrkey",
-};
-
static const struct resource bd71815_rtc_irqs[] = {
DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC0, "bd70528-rtc-alm-0"),
DEFINE_RES_IRQ_NAMED(BD71815_INT_RTC1, "bd70528-rtc-alm-1"),
@@ -174,10 +163,6 @@ static struct mfd_cell bd71828_mfd_cells[] = {
.name = "bd71828-rtc",
.resources = bd71828_rtc_irqs,
.num_resources = ARRAY_SIZE(bd71828_rtc_irqs),
- }, {
- .name = "gpio-keys",
- .platform_data = &bd71828_powerkey_data,
- .pdata_size = sizeof(bd71828_powerkey_data),
},
};
@@ -242,11 +227,8 @@ static const struct mfd_cell bd72720_mfd_cells[] = {
.name = "bd72720-rtc",
.resources = bd72720_rtc_irqs,
.num_resources = ARRAY_SIZE(bd72720_rtc_irqs),
- }, {
- .name = "gpio-keys",
- .platform_data = &bd71828_powerkey_data,
- .pdata_size = sizeof(bd71828_powerkey_data),
},
+ /* Power button is registered separately */
};
static const struct regmap_range bd71815_volatile_ranges[] = {
@@ -877,6 +859,84 @@ static int set_clk_mode(struct device *dev, struct regmap *regmap,
OUT32K_MODE_CMOS);
}
+static const struct property_entry bd71828_powerkey_parent_props[] = {
+ PROPERTY_ENTRY_STRING("label", "bd71828-pwrkey"),
+ { }
+};
+
+static const struct property_entry bd71828_powerkey_props[] = {
+ PROPERTY_ENTRY_U32("linux,code", KEY_POWER),
+ PROPERTY_ENTRY_BOOL("wakeup-source"),
+ { }
+};
+
+#define GPIO_KEYS 0 /* Node corresponding to gpio-keys device itself */
+#define PWRON_KEY 1 /* Node describing power button in gpio-keys */
+
+static int bd71828_i2c_register_swnodes(const struct software_node *nodes)
+{
+ const struct software_node * const node_group[] = {
+ &nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
+ };
+
+ return software_node_register_node_group(node_group);
+}
+
+static void bd71828_i2c_unregister_swnodes(void *data)
+{
+ const struct software_node *nodes = data;
+ const struct software_node * const node_group[] = {
+ &nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
+ };
+
+ software_node_unregister_node_group(node_group);
+}
+
+static int bd71828_i2c_register_pwrbutton(struct device *dev, int button_irq,
+ struct irq_domain *irq_domain)
+{
+ const struct resource res[] = {
+ DEFINE_RES_IRQ_NAMED(button_irq, "bd71828-pwrkey"),
+ };
+ struct mfd_cell gpio_keys_cell = {
+ .name = "gpio-keys",
+ .resources = res,
+ .num_resources = ARRAY_SIZE(res),
+ };
+ struct software_node *nodes;
+ int ret;
+
+ nodes = devm_kcalloc(dev, 2, sizeof(*nodes), GFP_KERNEL);
+ if (!nodes)
+ return -ENOMEM;
+
+ nodes[GPIO_KEYS].name = devm_kasprintf(dev, GFP_KERNEL, "%s-power-key", dev_name(dev));
+ if (!nodes[GPIO_KEYS].name)
+ return -ENOMEM;
+
+ nodes[GPIO_KEYS].properties = bd71828_powerkey_parent_props;
+
+ nodes[PWRON_KEY].parent = &nodes[GPIO_KEYS];
+ nodes[PWRON_KEY].properties = bd71828_powerkey_props;
+
+ ret = bd71828_i2c_register_swnodes(nodes);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, bd71828_i2c_unregister_swnodes, nodes);
+ if (ret)
+ return ret;
+
+ gpio_keys_cell.swnode = &nodes[GPIO_KEYS];
+
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, &gpio_keys_cell, 1,
+ NULL, 0, irq_domain);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to register power-button");
+
+ return 0;
+}
+
static struct i2c_client *bd71828_dev;
static void bd71828_power_off(void)
{
@@ -929,6 +989,7 @@ static struct regmap *bd72720_do_regmaps(struct i2c_client *i2c)
static int bd71828_i2c_probe(struct i2c_client *i2c)
{
struct regmap_irq_chip_data *irq_data;
+ struct irq_domain *irq_domain;
int ret;
struct regmap *regmap = NULL;
const struct regmap_config *regmap_config;
@@ -1022,23 +1083,23 @@ static int bd71828_i2c_probe(struct i2c_client *i2c)
"Failed to enable main level IRQs\n");
}
}
- if (button_irq) {
- ret = regmap_irq_get_virq(irq_data, button_irq);
- if (ret < 0)
- return dev_err_probe(&i2c->dev, ret,
- "Failed to get the power-key IRQ\n");
-
- button.irq = ret;
- }
ret = set_clk_mode(&i2c->dev, regmap, clkmode_reg);
if (ret)
return ret;
+ irq_domain = regmap_irq_get_domain(irq_data);
+
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO, mfd, cells,
- NULL, 0, regmap_irq_get_domain(irq_data));
+ NULL, 0, irq_domain);
if (ret)
- return dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
+ return dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
+
+ if (button_irq) {
+ ret = bd71828_i2c_register_pwrbutton(&i2c->dev, button_irq, irq_domain);
+ if (ret)
+ return ret;
+ }
if (of_device_is_system_power_controller(i2c->dev.of_node) &&
chip_type == ROHM_CHIP_TYPE_BD71828) {
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index ff714fd4f54d..be2acc429fe3 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -7,7 +7,8 @@
// Datasheet for BD71837MWV available from
// https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e
-#include <linux/gpio_keys.h>
+#include <linux/device/devres.h>
+#include <linux/gfp_types.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
@@ -15,37 +16,16 @@
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/types.h>
-static struct gpio_keys_button button = {
- .code = KEY_POWER,
- .gpio = -1,
- .type = EV_KEY,
-};
-
-static struct gpio_keys_platform_data bd718xx_powerkey_data = {
- .buttons = &button,
- .nbuttons = 1,
- .name = "bd718xx-pwrkey",
-};
-
static struct mfd_cell bd71837_mfd_cells[] = {
- {
- .name = "gpio-keys",
- .platform_data = &bd718xx_powerkey_data,
- .pdata_size = sizeof(bd718xx_powerkey_data),
- },
{ .name = "bd71837-clk", },
{ .name = "bd71837-pmic", },
};
static struct mfd_cell bd71847_mfd_cells[] = {
- {
- .name = "gpio-keys",
- .platform_data = &bd718xx_powerkey_data,
- .pdata_size = sizeof(bd718xx_powerkey_data),
- },
{ .name = "bd71847-clk", },
{ .name = "bd71847-pmic", },
};
@@ -125,10 +105,89 @@ static int bd718xx_init_press_duration(struct regmap *regmap,
return 0;
}
+static const struct property_entry bd718xx_powerkey_parent_props[] = {
+ PROPERTY_ENTRY_STRING("label", "bd718xx-pwrkey"),
+ { }
+};
+
+static const struct property_entry bd718xx_powerkey_props[] = {
+ PROPERTY_ENTRY_U32("linux,code", KEY_POWER),
+ { }
+};
+
+static const struct resource bd718xx_powerkey_resources[] = {
+ DEFINE_RES_IRQ_NAMED(BD718XX_INT_PWRBTN_S, "bd718xx-pwrkey"),
+};
+
+#define GPIO_KEYS 0 /* Node corresponding to gpio-keys device itself */
+#define PWRON_KEY 1 /* Node describing power button in gpio-keys */
+
+static int bd718xx_i2c_register_swnodes(const struct software_node *nodes)
+{
+ const struct software_node * const node_group[] = {
+ &nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
+ };
+
+ return software_node_register_node_group(node_group);
+}
+
+static void bd718xx_i2c_unregister_swnodes(void *data)
+{
+ const struct software_node *nodes = data;
+ const struct software_node * const node_group[] = {
+ &nodes[GPIO_KEYS], &nodes[PWRON_KEY], NULL
+ };
+
+ software_node_unregister_node_group(node_group);
+}
+
+static int bd718xx_i2c_register_pwrbutton(struct device *dev,
+ struct irq_domain *irq_domain)
+{
+ struct mfd_cell gpio_keys_cell = {
+ .name = "gpio-keys",
+ .resources = bd718xx_powerkey_resources,
+ .num_resources = ARRAY_SIZE(bd718xx_powerkey_resources),
+ };
+ struct software_node *nodes;
+ int ret;
+
+ nodes = devm_kcalloc(dev, 2, sizeof(*nodes), GFP_KERNEL);
+ if (!nodes)
+ return -ENOMEM;
+
+ nodes[GPIO_KEYS].name = devm_kasprintf(dev, GFP_KERNEL, "%s-power-key", dev_name(dev));
+ if (!nodes[GPIO_KEYS].name)
+ return -ENOMEM;
+
+ nodes[GPIO_KEYS].properties = bd718xx_powerkey_parent_props;
+
+ nodes[PWRON_KEY].parent = &nodes[GPIO_KEYS];
+ nodes[PWRON_KEY].properties = bd718xx_powerkey_props;
+
+ ret = bd718xx_i2c_register_swnodes(nodes);
+ if (ret)
+ return ret;
+
+ ret = devm_add_action_or_reset(dev, bd718xx_i2c_unregister_swnodes, nodes);
+ if (ret)
+ return ret;
+
+ gpio_keys_cell.swnode = &nodes[GPIO_KEYS];
+
+ ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, &gpio_keys_cell, 1,
+ NULL, 0, irq_domain);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to register power-button");
+
+ return 0;
+}
+
static int bd718xx_i2c_probe(struct i2c_client *i2c)
{
struct regmap *regmap;
struct regmap_irq_chip_data *irq_data;
+ struct irq_domain *irq_domain;
int ret;
unsigned int chip_type;
struct mfd_cell *mfd;
@@ -169,20 +228,18 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c)
if (ret)
return ret;
- ret = regmap_irq_get_virq(irq_data, BD718XX_INT_PWRBTN_S);
-
- if (ret < 0)
- return dev_err_probe(&i2c->dev, ret, "Failed to get the IRQ\n");
-
- button.irq = ret;
+ irq_domain = regmap_irq_get_domain(irq_data);
ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
- mfd, cells, NULL, 0,
- regmap_irq_get_domain(irq_data));
+ mfd, cells, NULL, 0, irq_domain);
+ if (ret)
+ return dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
+
+ ret = bd718xx_i2c_register_pwrbutton(&i2c->dev, irq_domain);
if (ret)
- dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n");
+ return ret;
- return ret;
+ return 0;
}
static const struct of_device_id bd718xx_of_match[] = {
diff --git a/drivers/mfd/si476x-cmd.c b/drivers/mfd/si476x-cmd.c
index 3bb2decfebd3..58e9bea7e90a 100644
--- a/drivers/mfd/si476x-cmd.c
+++ b/drivers/mfd/si476x-cmd.c
@@ -15,7 +15,6 @@
#include <linux/atomic.h>
#include <linux/i2c.h>
#include <linux/device.h>
-#include <linux/gpio.h>
#include <linux/videodev2.h>
#include <linux/mfd/si476x-core.h>
diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c
index 7ddc97dfc940..55700ce711f4 100644
--- a/drivers/mfd/si476x-i2c.c
+++ b/drivers/mfd/si476x-i2c.c
@@ -13,7 +13,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/regulator/consumer.h>
#include <linux/i2c.h>
#include <linux/err.h>
@@ -130,8 +130,8 @@ int si476x_core_start(struct si476x_core *core, bool soft)
int err;
if (!soft) {
- if (gpio_is_valid(core->gpio_reset))
- gpio_set_value_cansleep(core->gpio_reset, 1);
+ if (core->reset)
+ gpiod_set_value_cansleep(core->reset, 0);
if (client->irq)
enable_irq(client->irq);
@@ -197,8 +197,8 @@ disable_irq:
else
cancel_delayed_work_sync(&core->status_monitor);
- if (gpio_is_valid(core->gpio_reset))
- gpio_set_value_cansleep(core->gpio_reset, 0);
+ if (core->reset)
+ gpiod_set_value_cansleep(core->reset, 1);
return err;
}
@@ -243,8 +243,8 @@ int si476x_core_stop(struct si476x_core *core, bool soft)
cancel_delayed_work_sync(&core->status_monitor);
if (!soft) {
- if (gpio_is_valid(core->gpio_reset))
- gpio_set_value_cansleep(core->gpio_reset, 0);
+ if (core->reset)
+ gpiod_set_value_cansleep(core->reset, 1);
}
return err;
}
@@ -712,24 +712,18 @@ static int si476x_core_probe(struct i2c_client *client)
atomic_set(&core->is_alive, 0);
core->power_state = SI476X_POWER_DOWN;
+ core->reset = devm_gpiod_get_optional(&client->dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(core->reset))
+ return dev_err_probe(&client->dev, PTR_ERR(core->reset),
+ "error getting reset GPIO\n");
+ gpiod_set_consumer_name(core->reset, "si476x reset");
+
pdata = dev_get_platdata(&client->dev);
if (pdata) {
memcpy(&core->power_up_parameters,
&pdata->power_up_parameters,
sizeof(core->power_up_parameters));
-
- core->gpio_reset = -1;
- if (gpio_is_valid(pdata->gpio_reset)) {
- rval = gpio_request(pdata->gpio_reset, "si476x reset");
- if (rval) {
- dev_err(&client->dev,
- "Failed to request gpio: %d\n", rval);
- return rval;
- }
- core->gpio_reset = pdata->gpio_reset;
- gpio_direction_output(core->gpio_reset, 0);
- }
-
core->diversity_mode = pdata->diversity_mode;
memcpy(&core->pinmux, &pdata->pinmux,
sizeof(struct si476x_pinmux));
@@ -748,7 +742,7 @@ static int si476x_core_probe(struct i2c_client *client)
core->supplies);
if (rval) {
dev_err(&client->dev, "Failed to get all of the regulators\n");
- goto free_gpio;
+ return rval;
}
mutex_init(&core->cmd_lock);
@@ -761,7 +755,7 @@ static int si476x_core_probe(struct i2c_client *client)
GFP_KERNEL);
if (rval) {
dev_err(&client->dev, "Could not allocate the FIFO\n");
- goto free_gpio;
+ return rval;
}
mutex_init(&core->rds_drainer_status_lock);
init_waitqueue_head(&core->rds_read_queue);
@@ -827,11 +821,6 @@ static int si476x_core_probe(struct i2c_client *client)
free_kfifo:
kfifo_free(&core->rds_fifo);
-
-free_gpio:
- if (gpio_is_valid(core->gpio_reset))
- gpio_free(core->gpio_reset);
-
return rval;
}
@@ -848,9 +837,6 @@ static void si476x_core_remove(struct i2c_client *client)
cancel_delayed_work_sync(&core->status_monitor);
kfifo_free(&core->rds_fifo);
-
- if (gpio_is_valid(core->gpio_reset))
- gpio_free(core->gpio_reset);
}
diff --git a/include/linux/mfd/88pm886.h b/include/linux/mfd/88pm886.h
index 38892ba7b8a4..2c24dd3032ab 100644
--- a/include/linux/mfd/88pm886.h
+++ b/include/linux/mfd/88pm886.h
@@ -11,6 +11,7 @@
#define PM886_PAGE_OFFSET_REGULATORS 1
#define PM886_PAGE_OFFSET_GPADC 2
+#define PM886_PAGE_OFFSET_BATTERY 3
#define PM886_REG_ID 0x00
@@ -128,9 +129,13 @@
#define PM886_GPADC_BIAS_LEVELS 16
#define PM886_GPADC_INDEX_TO_BIAS_uA(i) (1 + (i) * 5)
+/* Battery block register definitions */
+#define PM886_REG_CLS_CONFIG1 0x71
+
struct pm886_chip {
struct i2c_client *client;
unsigned int chip_id;
struct regmap *regmap;
+ struct regmap *regmap_battery;
};
#endif /* __MFD_88PM886_H */
diff --git a/include/linux/mfd/cs42l43.h b/include/linux/mfd/cs42l43.h
index ff0f7e365a19..8e993fb535e6 100644
--- a/include/linux/mfd/cs42l43.h
+++ b/include/linux/mfd/cs42l43.h
@@ -86,7 +86,6 @@ struct cs42l43 {
struct regmap_irq_chip_data *irq_data;
struct work_struct boot_work;
- struct completion device_attach;
struct completion device_detach;
struct completion firmware_download;
int firmware_error;
@@ -96,7 +95,6 @@ struct cs42l43 {
struct mutex pll_lock;
bool sdw_pll_active;
- bool attached;
bool hw_lock;
long variant_id;
};
diff --git a/include/linux/mfd/si476x-core.h b/include/linux/mfd/si476x-core.h
index e913b2cdf77d..d9e3a322134c 100644
--- a/include/linux/mfd/si476x-core.h
+++ b/include/linux/mfd/si476x-core.h
@@ -14,6 +14,7 @@
#include <linux/kfifo.h>
#include <linux/atomic.h>
+#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/mutex.h>
@@ -104,7 +105,7 @@ enum si476x_power_state {
* @power_state: Current power state of the device.
* @supplies: Structure containing handles to all power supplies used
* by the device (NULL ones are ignored).
- * @gpio_reset: GPIO pin connectet to the RSTB pin of the chip.
+ * @reset: GPIO connected to the RSTB pin of the chip.
* @pinmux: Chip's configurable pins configuration.
* @diversity_mode: Chips role when functioning in diversity mode.
* @is_alive: Chip is initialized and active.
@@ -142,7 +143,7 @@ struct si476x_core {
struct regulator_bulk_data supplies[4];
- int gpio_reset;
+ struct gpio_desc *reset;
struct si476x_pinmux pinmux;
enum si476x_phase_diversity_mode diversity_mode;
diff --git a/include/linux/mfd/si476x-platform.h b/include/linux/mfd/si476x-platform.h
index cb99e16ca947..f9e1f6b27277 100644
--- a/include/linux/mfd/si476x-platform.h
+++ b/include/linux/mfd/si476x-platform.h
@@ -246,8 +246,6 @@ enum si476x_phase_diversity_mode {
* Platform dependent definition
*/
struct si476x_platform_data {
- int gpio_reset; /* < 0 if not used */
-
struct si476x_power_up_args power_up_parameters;
enum si476x_phase_diversity_mode diversity_mode;