From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-dl1-f43.google.com (mail-dl1-f43.google.com [74.125.82.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 822083C197C for ; Thu, 18 Jun 2026 18:58:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.43 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781809141; cv=none; b=tBNPCsXGtcPmh0wAJkaQaPobWooyH1HKwhlE3PRYcfId2SuFsPQsl9cKDOWaKn6A9BQ/mw0ZlSuCixAliDNDUXB6FsJgLUPsy8Tj8d6mEoq2FQ2oud0ALM4IlldSqlIOWWn/oV9e2eDXmDARLyUubORCO5GSjfXdJB9vc8WFQz8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781809141; c=relaxed/simple; bh=eiBIyASSpFGQS6Vuac8e2lrbLE1kyADiIPdv+8+izCw=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=Jq5TId3MYMlOVBf0eyIpwo0qjDjaOHFoeWNePrZLglzvRImTZsaaLCQedAycsRaf7DyhXWH9/SBd1Zuc09szL4/I1awGYYgO8F8zqWSzbosv4zbcCnL+k03leAzRRI3AZh9c0RVzIJMdTJzAs8N0+c+UQsDzDNusfftupbJNbuM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RiABhDw5; arc=none smtp.client-ip=74.125.82.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RiABhDw5" Received: by mail-dl1-f43.google.com with SMTP id a92af1059eb24-137dd4cc208so1113006c88.1 for ; Thu, 18 Jun 2026 11:58:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1781809139; x=1782413939; darn=vger.kernel.org; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :from:to:cc:subject:date:message-id:reply-to; bh=SBklG0rfcoSR2RwcRYCJp2M0Jd/k8780w0i+nl/6haw=; b=RiABhDw5i9piQznmAomSrA6IqTqKMr7KWhsveTTt/Adxcv1sh1OGQWCULLckuj38aK xIxyF8wo0F7rDZ4TU8ZZCYxsRP/dIq+vmInTunRrjJkXATpJJ7l/idg0qRGp53XV2f4F W2FD6/YpjmNxj2uPoMdTnGFLcVh/nxmca/7FaIWrSHMfcfInzjqvpwlgEQ/peDwe2RzS NiCBKzEHm2CAhgQC0hvOpZVHbMB4aOuyXEH3jN/ZZdo33iuJ7A8DI52RUccRK9dEHo6S ICNp9Nokk40HJkuMaHIgzVn90IbYulOGqmM0YKOWqlY3KJMQIntNCwUgfBrLWBJLYERt JeZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781809139; x=1782413939; h=content-disposition:mime-version:message-id:subject:cc:to:from:date :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=SBklG0rfcoSR2RwcRYCJp2M0Jd/k8780w0i+nl/6haw=; b=lufIQ2ldZ/FBeHYmpmNftIddujPUwjQcsLHF3BadfrdB/Awao1gXSshqdWLV11wQIC amitU3mTbQLQ1HFOWceNfnqHc44uM82E8dvfkzn32k3lZklvwWSngA8ucnHSExtpicfF EXUOoWTAzzLae9p5mmq9FP/XHOMX6o5gt5HiqgR1pLTxxVYMNrh6sGEDnH8vzQ/ILEj9 NNZpZlpioGnr+3GbcEZkOOY08+kkNzJtgQaPDKrUHss0ZlXILlfOg7Tv7ZHyKD7oGC61 H9oHIijOR/60//tb8UsIIuX43v6izpo9jHofuciyyOFUwpuCYd97MxjN/Wy7znao8zUO oO3g== X-Forwarded-Encrypted: i=1; AFNElJ+LNxdunsfNQKWzK22H4vDwkyCk74IPGAlrowUK2dNDu8+varS3ri+mLi2pCmIPsDCLJqZzwzX1i2D5kaA=@vger.kernel.org X-Gm-Message-State: AOJu0YynwCfJRRQ/8fXHi6S4r57RT7OnH+k8PcPmYwvMn2pNY/3XTh/7 EUQmEVictT5Q/V5A9ucitNLI9BAgq6KvoKRRPaAd3Xy4zLQfiKcPP50hAcmSew== X-Gm-Gg: AfdE7ck3WVAng+1pQxhGinnm8lVkqxk6qn6lx8j/pEWbK8V5LnTfmzYShQkHoib5WpW QPbqFUT0bfQBSoL6tW/DohrULeUEFrjD8bWCNkwPfeYGIr7nHWImdTfoYw2rnOiMFq6G1/yQESt wdOXD2Qxf86MILG8Kmx6YL/K3NuDPBfNrAs8pA9ZQOUokIYwIDcUppgRr7j+DRkcJZfNHcjCRF9 tmWb1Ac31K1WJp5/3RBvINtH7Q+E25R3z+PHLTbmcsZLZ5Il0/xlwnt97HQI6BYpLFWhq1JiQg4 oT+HQUulWD/FOl8BNOgoqs2A7dl+YZKazm30USquvUnU/d2EeJaGR8aPpFSxgTwHQPclurWCc7w XcT3lPLKtVrFIAEsDuR3mmh3gxkpTAGGYZ1O0oGVaENXqkqYiDQrf2vwj3nb+qdcOGyTNKbBoyL fzejq4pGfW14PPXSYaWZHlJNpcmzYhQTELK5xHad4CDOsTBnCZkb+FbA== X-Received: by 2002:a05:7022:f8c:b0:139:a256:9533 with SMTP id a92af1059eb24-139a3100c31mr223875c88.14.1781809138359; Thu, 18 Jun 2026 11:58:58 -0700 (PDT) Received: from google.com ([2a00:79e0:2ebe:8:7e11:7ed7:3f9b:d1b3]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30c06d5bec5sm287732eec.26.2026.06.18.11.58.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 11:58:57 -0700 (PDT) Date: Thu, 18 Jun 2026 11:58:55 -0700 From: Dmitry Torokhov To: Lee Jones Cc: Matti Vaittinen , linux-kernel@vger.kernel.org Subject: [PATCH] mfd: rohm: Factor out power button registration Message-ID: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Factor out the power button registration logic using software nodes from rohm-bd718x7 and rohm-bd71828 drivers into a shared module rohm-pwrbutton. This reduces duplication and makes it easier to support other ROHM PMICs with similar power button configurations. Suggested-by: Lee Jones Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Dmitry Torokhov --- MAINTAINERS | 2 + drivers/mfd/Kconfig | 6 ++ drivers/mfd/Makefile | 1 + drivers/mfd/rohm-bd71828.c | 84 ++------------------------ drivers/mfd/rohm-bd718x7.c | 84 ++------------------------ drivers/mfd/rohm-pwrbutton.c | 112 +++++++++++++++++++++++++++++++++++ drivers/mfd/rohm-pwrbutton.h | 12 ++++ 7 files changed, 141 insertions(+), 160 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index f1caa6e5198b..40c46a7363fb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -23524,6 +23524,8 @@ F: drivers/mfd/rohm-bd71828.c F: drivers/mfd/rohm-bd718x7.c F: drivers/mfd/rohm-bd9576.c F: drivers/mfd/rohm-bd96801.c +F: drivers/mfd/rohm-pwrbutton.c +F: drivers/mfd/rohm-pwrbutton.h F: drivers/regulator/bd71815-regulator.c F: drivers/regulator/bd71828-regulator.c F: drivers/regulator/bd718x7-regulator.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 763ce6a34782..8d04e1b1f8c8 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2208,6 +2208,10 @@ config MFD_STW481X in various ST Microelectronics and ST-Ericsson embedded Nomadik series. +config MFD_ROHM_PWRBUTTON + tristate + select MFD_CORE + config MFD_ROHM_BD718XX tristate "ROHM BD71837 Power Management IC" depends on I2C=y @@ -2215,6 +2219,7 @@ config MFD_ROHM_BD718XX select REGMAP_I2C select REGMAP_IRQ select MFD_CORE + select MFD_ROHM_PWRBUTTON help Select this option to get support for the ROHM BD71837 Power Management ICs. BD71837 is designed to power processors like @@ -2228,6 +2233,7 @@ config MFD_ROHM_BD71828 select REGMAP_I2C select REGMAP_IRQ select MFD_CORE + select MFD_ROHM_PWRBUTTON help Select this option to get support for the ROHM BD71815, BD71828, BD71879, BD72720 and BD73900 Power Management ICs (PMICs). These are diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index dd4bb7e77c33..72d3944b0ad8 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -273,6 +273,7 @@ obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o obj-$(CONFIG_MFD_SC27XX_PMIC) += sprd-sc27xx-spi.o obj-$(CONFIG_RAVE_SP_CORE) += rave-sp.o +obj-$(CONFIG_MFD_ROHM_PWRBUTTON) += rohm-pwrbutton.o obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_ROHM_BD957XMUF) += rohm-bd9576.o diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c index 5fb6142cf087..dfc23cd13ef2 100644 --- a/drivers/mfd/rohm-bd71828.c +++ b/drivers/mfd/rohm-bd71828.c @@ -5,8 +5,6 @@ * ROHM BD718[15/28/79] and BD72720 PMIC driver */ -#include -#include #include #include #include @@ -19,10 +17,11 @@ #include #include #include -#include #include #include +#include "rohm-pwrbutton.h" + #define BD72720_TYPED_IRQ_REG(_irq, _stat_offset, _mask, _type_offset) \ [_irq] = { \ .reg_offset = (_stat_offset), \ @@ -859,83 +858,7 @@ 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) @@ -1096,7 +1019,8 @@ static int bd71828_i2c_probe(struct i2c_client *i2c) 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); + ret = rohm_mfd_register_pwrbutton(&i2c->dev, button_irq, + "bd71828-pwrkey", true, irq_domain); if (ret) return ret; } diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c index be2acc429fe3..bab3b1c2445b 100644 --- a/drivers/mfd/rohm-bd718x7.c +++ b/drivers/mfd/rohm-bd718x7.c @@ -7,8 +7,6 @@ // Datasheet for BD71837MWV available from // https://www.rohm.com/datasheet/BD71837MWV/bd71837mwv-e -#include -#include #include #include #include @@ -16,10 +14,11 @@ #include #include #include -#include #include #include +#include "rohm-pwrbutton.h" + static struct mfd_cell bd71837_mfd_cells[] = { { .name = "bd71837-clk", }, { .name = "bd71837-pmic", }, @@ -105,83 +104,7 @@ 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) { @@ -235,7 +158,8 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c) if (ret) return dev_err_probe(&i2c->dev, ret, "Failed to create subdevices\n"); - ret = bd718xx_i2c_register_pwrbutton(&i2c->dev, irq_domain); + ret = rohm_mfd_register_pwrbutton(&i2c->dev, BD718XX_INT_PWRBTN_S, + "bd718xx-pwrkey", false, irq_domain); if (ret) return ret; diff --git a/drivers/mfd/rohm-pwrbutton.c b/drivers/mfd/rohm-pwrbutton.c new file mode 100644 index 000000000000..e0cb74fdd73c --- /dev/null +++ b/drivers/mfd/rohm-pwrbutton.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Shared helper for ROHM PMIC power button registration + * + * Copyright 2018, 2019 ROHM Semiconductors + * Copyright 2026 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rohm-pwrbutton.h" + +#define GPIO_KEYS 0 /* Node corresponding to gpio-keys device itself */ +#define PWRON_KEY 1 /* Node describing power button in gpio-keys */ + +static int rohm_mfd_pwrbutton_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 rohm_mfd_pwrbutton_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); +} + +int rohm_mfd_register_pwrbutton(struct device *dev, int irq, const char *name, + bool wakeup, struct irq_domain *irq_domain) +{ + const struct resource res[] = { + DEFINE_RES_IRQ_NAMED(irq, name), + }; + struct mfd_cell gpio_keys_cell = { + .name = "gpio-keys", + .resources = res, + .num_resources = ARRAY_SIZE(res), + }; + struct property_entry *parent_props; + struct property_entry *child_props; + struct software_node *nodes; + int n_props; + int ret; + + if (irq <= 0) + return -EINVAL; + + 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; + + parent_props = devm_kcalloc(dev, 2, sizeof(*parent_props), GFP_KERNEL); + if (!parent_props) + return -ENOMEM; + + parent_props[0] = PROPERTY_ENTRY_STRING("label", name); + nodes[GPIO_KEYS].properties = parent_props; + + n_props = 2; /* linux,code and terminator */ + if (wakeup) + n_props++; + + child_props = devm_kcalloc(dev, n_props, sizeof(*child_props), GFP_KERNEL); + if (!child_props) + return -ENOMEM; + + child_props[0] = PROPERTY_ENTRY_U32("linux,code", KEY_POWER); + if (wakeup) + child_props[1] = PROPERTY_ENTRY_BOOL("wakeup-source"); + + nodes[PWRON_KEY].parent = &nodes[GPIO_KEYS]; + nodes[PWRON_KEY].properties = child_props; + + ret = rohm_mfd_pwrbutton_register_swnodes(nodes); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, rohm_mfd_pwrbutton_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; +} +EXPORT_SYMBOL_GPL(rohm_mfd_register_pwrbutton); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dmitry Torokhov "); +MODULE_DESCRIPTION("Shared helper for ROHM PMIC power button registration"); diff --git a/drivers/mfd/rohm-pwrbutton.h b/drivers/mfd/rohm-pwrbutton.h new file mode 100644 index 000000000000..985bd37a4ad0 --- /dev/null +++ b/drivers/mfd/rohm-pwrbutton.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __LINUX_MFD_ROHM_PWRBUTTON_H__ +#define __LINUX_MFD_ROHM_PWRBUTTON_H__ + +struct device; +struct irq_domain; + +int rohm_mfd_register_pwrbutton(struct device *dev, int irq, const char *name, + bool wakeup, struct irq_domain *irq_domain); + +#endif /* __LINUX_MFD_ROHM_PWRBUTTON_H__ */ -- 2.55.0.rc0.738.g0c8ab3ebcc-goog -- Dmitry