[PATCH v3 07/10] mfd: wm831x: support software nodes for DCDC regulators
Dmitry Torokhov <[email protected]> Sat, 11 Jul 2026 19:12:48 -0700
| Newsgroups | org.kernel.vger.linux-samsung-soc,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-input,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
Allow passing software nodes to wm831x DCDC regulators via PMIC platform data. This is useful for non-DT/non-ACPI platforms that want to associate device properties (like DVS GPIOs) with the regulator devices using software nodes. We add 'dcdc_swnodes' to the PMIC platform data 'struct wm831x_pdata' and have the MFD core assign these software nodes to the buckv cells. Assisted-by: Antigravity:gemini-3.5-flash Signed-off-by: Dmitry Torokhov <[email protected]> --- drivers/mfd/wm831x-core.c | 47 ++++++++++++++++++++++++++++++---------- include/linux/mfd/wm831x/pdata.h | 2 ++ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index df8e76e000cc..c4793be419ba 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -14,6 +14,7 @@ #include <linux/delay.h> #include <linux/mfd/core.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/err.h> #include <linux/mfd/wm831x/core.h> @@ -1449,6 +1450,32 @@ const struct of_device_id wm831x_of_match[] = { }; EXPORT_SYMBOL_GPL(wm831x_of_match); +static int wm831x_add_devices(struct wm831x *wm831x, int wm831x_num, + const struct mfd_cell *cells, int num_cells) +{ + struct wm831x_pdata *pdata = &wm831x->pdata; + int i; + + struct mfd_cell *local_cells __free(kfree) = + kmemdup_array(cells, num_cells, sizeof(*cells), GFP_KERNEL); + if (!local_cells) + return -ENOMEM; + + for (i = 0; i < num_cells; i++) { + struct mfd_cell *cell = &local_cells[i]; + + if (strcmp(cell->name, "wm831x-buckv") == 0) { + int id = cell->id - 1; + + if (id >= 0 && id < WM831X_MAX_DCDC) + cell->swnode = pdata->dcdc_swnodes[id]; + } + } + + return mfd_add_devices(wm831x->dev, wm831x_num, local_cells, num_cells, + NULL, 0, NULL); +} + /* * Instantiate the generic non-control parts of the device. */ @@ -1620,15 +1647,13 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) /* The core device is up, instantiate the subdevices. */ switch (parent) { case WM8310: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8310_devs, ARRAY_SIZE(wm8310_devs), - NULL, 0, NULL); + ret = wm831x_add_devices(wm831x, wm831x_num, + wm8310_devs, ARRAY_SIZE(wm8310_devs)); break; case WM8311: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8311_devs, ARRAY_SIZE(wm8311_devs), - NULL, 0, NULL); + ret = wm831x_add_devices(wm831x, wm831x_num, + wm8311_devs, ARRAY_SIZE(wm8311_devs)); if (!pdata->disable_touch) mfd_add_devices(wm831x->dev, wm831x_num, touch_devs, ARRAY_SIZE(touch_devs), @@ -1636,9 +1661,8 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) break; case WM8312: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8312_devs, ARRAY_SIZE(wm8312_devs), - NULL, 0, NULL); + ret = wm831x_add_devices(wm831x, wm831x_num, + wm8312_devs, ARRAY_SIZE(wm8312_devs)); if (!pdata->disable_touch) mfd_add_devices(wm831x->dev, wm831x_num, touch_devs, ARRAY_SIZE(touch_devs), @@ -1649,9 +1673,8 @@ int wm831x_device_init(struct wm831x *wm831x, int irq) case WM8321: case WM8325: case WM8326: - ret = mfd_add_devices(wm831x->dev, wm831x_num, - wm8320_devs, ARRAY_SIZE(wm8320_devs), - NULL, 0, NULL); + ret = wm831x_add_devices(wm831x, wm831x_num, + wm8320_devs, ARRAY_SIZE(wm8320_devs)); break; default: diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h index 75aa94dadf1c..d5d9d9600756 100644 --- a/include/linux/mfd/wm831x/pdata.h +++ b/include/linux/mfd/wm831x/pdata.h @@ -12,6 +12,7 @@ struct wm831x; struct regulator_init_data; +struct software_node; struct wm831x_backlight_pdata { int isink; /** ISINK to use, 1 or 2 */ @@ -132,6 +133,7 @@ struct wm831x_pdata { struct wm831x_status_pdata *status[WM831X_MAX_STATUS]; /** DCDC1 = 0 and so on */ struct regulator_init_data *dcdc[WM831X_MAX_DCDC]; + const struct software_node *dcdc_swnodes[WM831X_MAX_DCDC]; /** EPE1 = 0 and so on */ struct regulator_init_data *epe[WM831X_MAX_EPE]; /** LDO1 = 0 and so on */ -- 2.55.0.795.g602f6c329a-goog