From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-dy1-f169.google.com (mail-dy1-f169.google.com [74.125.82.169]) (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 61BB33AF643 for ; Thu, 7 May 2026 15:05:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.169 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778166325; cv=none; b=D4s2r8Rq8e0+8MvQznGpRA1R6W+uaArj0JngHZ8BfBcFSCQvydSaEooKed5oMu20XOAmK6EIQBs0tdyLKHq5b7TbLKp+3MUZT/jq9fSBXfdC3buzIgg8MsX8Ygy5jKXqW+mvvfCAbzslL6iMXynJ/hB+XFo9f2wjJ9yR+wkURoc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778166325; c=relaxed/simple; bh=A8biyVqk4UHgasLSBEmtap+IkweZZCL4EgGujCVkkus=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=TmflJ9Tt8vj/hdNe1sz2lTXXmz2SUez984fpNwNUMzSekfQl3QKQDwwJi/4lDNW0mQ+TwHroiUf1Xbe9w0drwA09AHyvf5ppAFhFN3uFvmS+EgYmI9Qh0HBVWP0QVDrEOcmQjHsq/T0zDvOQOWaT1HHnCcW1XCCX+CVd+UN2n58= 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=rWzxxiG7; arc=none smtp.client-ip=74.125.82.169 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="rWzxxiG7" Received: by mail-dy1-f169.google.com with SMTP id 5a478bee46e88-2f7ca62a3c4so312455eec.0 for ; Thu, 07 May 2026 08:05:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1778166323; x=1778771123; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=6J/sUMDbx90Og7OYliAlAO1QbRODZfO/9jaJAVzV8aM=; b=rWzxxiG7u3szwUjxqhHP6DgPmJ4dtnRxUcqn8NPe/KQ9sIh2QOqZ8tz8ovsQxsiRra Fj7xvWRo0H/1czQHCsP4SxylKTMQLs5r83HtZWe5KQSytbkF7UwN8AcxWLrYSinalajN tDTfcaoI9uJAKBGI2a2LkYuMMteP9xIdfQNAq28vqcQv8ZjV59hf2Xng+JP9nhtVkzHZ vmbZ/gMxaxRbxmaeWpF2W+ISS7HvdY0GzZ0TDgpOJxux+95MIFGPmqRXsNzrtsD05Ww0 xRf+jAmJPepVB7irlbloR0qHl/DH94zEJMFwbSm0Syw/7v2hRQX+lPS9bSyc02V/coGe UafA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778166323; x=1778771123; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=6J/sUMDbx90Og7OYliAlAO1QbRODZfO/9jaJAVzV8aM=; b=i/u9lNDLw5Wdyxz2rACQX9qO+xdjGXRLdJCBPYi86W9UFalmcVQnaI7QDK70xHw0+q XcHNvFL3XNLKWtdqOCNbv8lSZgRALxPV1O+rQOahUu9Omtb+qorZS2La908MrNAfHmLY VLa2xg5zjOVToiTmn2QbbsW7lHK3NNZhQg2UunJe7VxF+j0wuU9cLMlQT1KfUv6W+lku ZP7iBIsj87xmCjbu+VrgBj16+eagKsE6ZAYgw6ut5796KWIFJ8emMG4E8r/OuEwMds7b /8IMnFS4F/uNTzCs1wUoPHZ1envyzBeH/yfevdBXgnX0VRTpYdiMPJ5BZAsIYN8NwY+l dhpg== X-Forwarded-Encrypted: i=1; AFNElJ86zK31ZXLLZC69BKa5A9ZHvIuOy7OLrIo41ICoofRnz2G8DzxP0PAdPvkxfSpToIBpQcQ5ahspFPU0zks=@vger.kernel.org X-Gm-Message-State: AOJu0Yz0PyvoRGyJ7di5yzxt03PJhY33MsITXAh7lLLeuwGz1tJMGgKn NNFyXiBD+VJ4TXaKmN1H9nLnrcngBMzReEiFFFGv6bkSnUj782eRUa23 X-Gm-Gg: AeBDiet0WqpXvLPPX9HnP0i6hdSGzjW9Rlyd7rj28oQoTIoWX7tYdEq3/q08x9qpB9t wIkyyPilh+zQaDu4vdg3a1W+HVrQciY5EtpaxXA5h32sSzHHZR3An/m6BOytT72KsqeI9Xd1+RE ZKqK0SL93zuaDHhLLK96/cidKKkF5l/eUsYG1GKZDVkNBuWFFpU/BN0F6qkZu9TUrof0SbOdztJ ZQ3nqtbkLxBSzjFrdK8ps/TGPsmWBVOFGUbupdYTNc8ZPLGpsp8HABc5JCcrtkNZ3zipNz4HdBs U7kWSXhi6dzM4tuuRSH7IsNAy0BMy74LazrFRgyTqiG0tcKeonnItIl+98cxvfCSV/xwIj2C8iA 1jz5Ox6sAW06UFfpjn3ow6c5lXSQXOvXrzL03k5mAhV1iRDbVoyPzcvpaBeVZR/9zeOQB1jc6ks UAuEi7IHYTi/AfQuauyvD6Rvm7h76z+aNSVw9vZs6rbXSfs0GsyEwY/WYtyyOvvBZOp62lOl5rx vw= X-Received: by 2002:a05:7301:7c12:b0:2f2:6dde:df50 with SMTP id 5a478bee46e88-2f54d79bc2dmr4259075eec.17.1778166322906; Thu, 07 May 2026 08:05:22 -0700 (PDT) Received: from google.com ([2a00:79e0:2ebe:8:6a50:9473:7750:56ef]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2f56d5c5027sm8219558eec.10.2026.05.07.08.05.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 May 2026 08:05:22 -0700 (PDT) Date: Thu, 7 May 2026 08:05:19 -0700 From: Dmitry Torokhov To: Lee Jones Cc: Matti Vaittinen , Arnd Bergmann , linux-kernel@vger.kernel.org Subject: Re: [PATCH v4 1/2] mfd: rohm-bd71828: Use software nodes for gpio-keys Message-ID: References: <20260427-rohm-software-nodes-v4-0-ffeb5b0c4774@gmail.com> <20260427-rohm-software-nodes-v4-1-ffeb5b0c4774@gmail.com> <20260507144247.GQ305027@google.com> 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 In-Reply-To: <20260507144247.GQ305027@google.com> On Thu, May 07, 2026 at 03:42:47PM +0100, Lee Jones wrote: > On Mon, 27 Apr 2026, Dmitry Torokhov wrote: > > > Refactor the rohm-bd71828 MFD driver to use software nodes for > > instantiating the gpio-keys child device, replacing the old > > platform_data mechanism. > > > > The power key's properties are now defined using software nodes and > > property entries. The IRQ is passed as a resource attached to the > > platform device. > > > > This will allow dropping support for using platform data for configuring > > gpio-keys in the future. > > > > Signed-off-by: Dmitry Torokhov > > --- > > drivers/mfd/rohm-bd71828.c | 122 +++++++++++++++++++++++++++++++++------------ > > 1 file changed, 90 insertions(+), 32 deletions(-) > > > > diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c > > index a79f354bf5cb..a8bdb9c955a4 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 > > +#include > > +#include > > #include > > #include > > #include > > @@ -18,6 +19,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > > > @@ -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,11 +163,8 @@ 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), > > }, > > + /* Power button is registered separately */ > > This happens a lot in MFD - no need to call it out. OK. > > > }; > > > > static const struct resource bd72720_power_irqs[] = { > > @@ -242,11 +228,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 +860,80 @@ static int set_clk_mode(struct device *dev, struct regmap *regmap, > > OUT32K_MODE_CMOS); > > } > > > > +static int bd71828_i2c_register_swnodes(const struct software_node *nodes) > > +{ > > + const struct software_node * const node_group[] = { > > + &nodes[0], &nodes[1], NULL > > + }; > > I only see handling like this in the testing infra. > > This is all very opaque and fiddly. > > Are you sure we can't do better with statically declared arrays? The nodes represent per-device data, so they can't be static/shared if we want to continue using the non-singleton approach in the driver. > > > + 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[0], &nodes[1], 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) > > +{ > > + 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"), > > + { } > > + }; > > + 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), > > + }; > > + > + > +Please break all 3 of these out of function context. > + > +We nearly always declare these externally unless they contain dynamic > +values and even then we try and avoid it. "button_irq" is not a constant, so we need to have "res[]" and therefore gpio_keys_cell as locals. I can move out the properties, but I believe there is a value in grouping them together. > + > > + struct software_node *nodes; > > + int error; > > + > > + nodes = devm_kcalloc(dev, 2, sizeof(*nodes), GFP_KERNEL); > > + if (!nodes) > > + return -ENOMEM; > > + > > + /* Node corresponding to gpio-keys device itself */ > > + nodes[0].name = devm_kasprintf(dev, GFP_KERNEL, "%s-power-key", dev_name(dev)); > > + if (!nodes[0].name) > > + return -ENOMEM; > > + > > + nodes[0].properties = bd71828_powerkey_parent_props; > > + > > + /* Node representing power button within gpio-keys device */ > > + nodes[1].parent = &nodes[0]; > > + nodes[1].properties = bd71828_powerkey_props; > > + > > + error = bd71828_i2c_register_swnodes(nodes); > > + if (error) > > + return error; > > + > > + error = devm_add_action_or_reset(dev, bd71828_i2c_unregister_swnodes, nodes); > > + if (error) > > + return error; > > + > > + gpio_keys_cell.swnode = &nodes[0]; > > + error = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, &gpio_keys_cell, 1, > > + NULL, 0, irq_domain); > > + if (error) > > + return dev_err_probe(dev, error, "Failed to create power button subdevice"); > > "Failed to register power-button" OK. > > > + > > + return 0; > > +} > > + > > static struct i2c_client *bd71828_dev; > > static void bd71828_power_off(void) > > { > > @@ -929,6 +986,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 +1080,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); > > This looks like an unrelated change? It is not. Both devm_mfd_add_devices() and bd71828_i2c_register_pwrbutton() use irq_domain argument o it makes sense to have a temporary here. Making a separate preparatory patch introducing a temporary just for one function call does not make sense: each patch has to make sense on its own. > > > + 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"); > > I can close my eyes to this one! > > > + 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) { > > > > -- 2.54.0.545.g6539524ca2-goog > > > Thanks. -- Dmitry