diff options
| -rw-r--r-- | Documentation/devicetree/bindings/Makefile | 2 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/marvell,88pm886-a1.yaml | 2 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml | 1 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/syscon-common.yaml | 34 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/mfd/syscon.yaml | 116 | ||||
| -rw-r--r-- | MAINTAINERS | 11 | ||||
| -rw-r--r-- | drivers/mfd/88pm886.c | 21 | ||||
| -rw-r--r-- | drivers/mfd/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/mfd/axp20x.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/cs42l43-i2c.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/cs42l43-sdw.c | 7 | ||||
| -rw-r--r-- | drivers/mfd/cs42l43.c | 15 | ||||
| -rw-r--r-- | drivers/mfd/ipaq-micro.c | 2 | ||||
| -rw-r--r-- | drivers/mfd/mt6397-core.c | 3 | ||||
| -rw-r--r-- | drivers/mfd/rohm-bd71828.c | 125 | ||||
| -rw-r--r-- | drivers/mfd/rohm-bd718x7.c | 123 | ||||
| -rw-r--r-- | drivers/mfd/si476x-cmd.c | 1 | ||||
| -rw-r--r-- | drivers/mfd/si476x-i2c.c | 46 | ||||
| -rw-r--r-- | include/linux/mfd/88pm886.h | 5 | ||||
| -rw-r--r-- | include/linux/mfd/cs42l43.h | 2 | ||||
| -rw-r--r-- | include/linux/mfd/si476x-core.h | 5 | ||||
| -rw-r--r-- | include/linux/mfd/si476x-platform.h | 2 |
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; |
