* [PATCH v7 01/10] spmi: Print error status with %pe format
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 02/10] spmi: Remove redundant dev_name() print in spmi_device_add() AngeloGioacchino Del Regno
` (8 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel
Instead of printing just a number, use the %pe format for error
status, increasing readability of error prints.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spmi/spmi.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 3cf8d9bd4566..bcb71f25194f 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -68,8 +68,8 @@ int spmi_device_add(struct spmi_device *sdev)
err = device_add(&sdev->dev);
if (err < 0) {
- dev_err(&sdev->dev, "Can't add %s, status %d\n",
- dev_name(&sdev->dev), err);
+ dev_err(&sdev->dev, "Can't add %s, status %pe\n",
+ dev_name(&sdev->dev), ERR_PTR(err));
goto err_device_add;
}
@@ -494,8 +494,8 @@ static void of_spmi_register_devices(struct spmi_controller *ctrl)
err = of_property_read_u32_array(node, "reg", reg, 2);
if (err) {
dev_err(&ctrl->dev,
- "node %pOF err (%d) does not have 'reg' property\n",
- node, err);
+ "node %pOF err (%pe) does not have 'reg' property\n",
+ node, ERR_PTR(err));
continue;
}
@@ -523,7 +523,7 @@ static void of_spmi_register_devices(struct spmi_controller *ctrl)
err = spmi_device_add(sdev);
if (err) {
dev_err(&sdev->dev,
- "failure adding device. status %d\n", err);
+ "failure adding device. status %pe\n", ERR_PTR(err));
spmi_device_put(sdev);
}
}
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v7 02/10] spmi: Remove redundant dev_name() print in spmi_device_add()
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 01/10] spmi: Print error status with %pe format AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:46 ` Andy Shevchenko
2026-01-14 8:39 ` [PATCH v7 03/10] spmi: Remove unneeded goto in spmi_device_add() error path AngeloGioacchino Del Regno
` (7 subsequent siblings)
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel
Function spmi_device_add() uses dev_{dbg,err}() for respectively
debug and error prints, and passes the same device pointer as both
the dev_{dbg,err}() parameters and to a dev_name() that is part of
the actual message.
This means that the device name gets printed twice!
Remove the redundant dev_name() from the messages.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spmi/spmi.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index bcb71f25194f..c21789c6b59f 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -68,12 +68,11 @@ int spmi_device_add(struct spmi_device *sdev)
err = device_add(&sdev->dev);
if (err < 0) {
- dev_err(&sdev->dev, "Can't add %s, status %pe\n",
- dev_name(&sdev->dev), ERR_PTR(err));
+ dev_err(&sdev->dev, "Can't add device, status %pe\n", ERR_PTR(err));
goto err_device_add;
}
- dev_dbg(&sdev->dev, "device %s registered\n", dev_name(&sdev->dev));
+ dev_dbg(&sdev->dev, "device registered\n");
err_device_add:
return err;
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 02/10] spmi: Remove redundant dev_name() print in spmi_device_add()
2026-01-14 8:39 ` [PATCH v7 02/10] spmi: Remove redundant dev_name() print in spmi_device_add() AngeloGioacchino Del Regno
@ 2026-01-14 8:46 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 8:46 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
On Wed, Jan 14, 2026 at 09:39:49AM +0100, AngeloGioacchino Del Regno wrote:
> Function spmi_device_add() uses dev_{dbg,err}() for respectively
> debug and error prints, and passes the same device pointer as both
> the dev_{dbg,err}() parameters and to a dev_name() that is part of
> the actual message.
> This means that the device name gets printed twice!
>
> Remove the redundant dev_name() from the messages.
This should be the first patch in the series, then in the second you will have
less churn.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 03/10] spmi: Remove unneeded goto in spmi_device_add() error path
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 01/10] spmi: Print error status with %pe format AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 02/10] spmi: Remove redundant dev_name() print in spmi_device_add() AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 04/10] spmi: Implement spmi_subdevice_alloc_and_add() and devm variant AngeloGioacchino Del Regno
` (6 subsequent siblings)
9 siblings, 0 replies; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel
If any error happens during device_add() just return inside of the
conditional, as the goto path doesn't do anything else if not just
returning.
While at it, to improve readability, also change this function to
explicitly return 0 (for success) at the end.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spmi/spmi.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index c21789c6b59f..29567c0620ae 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -69,13 +69,11 @@ int spmi_device_add(struct spmi_device *sdev)
err = device_add(&sdev->dev);
if (err < 0) {
dev_err(&sdev->dev, "Can't add device, status %pe\n", ERR_PTR(err));
- goto err_device_add;
+ return err;
}
dev_dbg(&sdev->dev, "device registered\n");
-
-err_device_add:
- return err;
+ return 0;
}
EXPORT_SYMBOL_GPL(spmi_device_add);
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v7 04/10] spmi: Implement spmi_subdevice_alloc_and_add() and devm variant
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (2 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 03/10] spmi: Remove unneeded goto in spmi_device_add() error path AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:51 ` Andy Shevchenko
2026-01-14 8:39 ` [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add() AngeloGioacchino Del Regno
` (5 subsequent siblings)
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel, Jonathan Cameron
Some devices connected over the SPMI bus may be big, in the sense
that those may be a complex of devices managed by a single chip
over the SPMI bus, reachable through a single SID.
Add new functions aimed at managing sub-devices of a SPMI device
spmi_subdevice_alloc_and_add() and a spmi_subdevice_put_and_remove()
for adding a new subdevice and removing it respectively, and also
add their devm_* variants.
The need for such functions comes from the existence of those
complex Power Management ICs (PMICs), which feature one or many
sub-devices, in some cases with these being even addressable on
the chip in form of SPMI register ranges.
Examples of those devices can be found in both Qualcomm platforms
with their PMICs having PON, RTC, SDAM, GPIO controller, and other
sub-devices, and in newer MediaTek platforms showing similar HW
features and a similar layout with those also having many subdevs.
Also, instead of generally exporting symbols, export them with a
new "SPMI" namespace: all users will have to import this namespace
to make use of the newly introduced exports.
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/spmi/spmi-devres.c | 24 ++++++++++++
drivers/spmi/spmi.c | 78 ++++++++++++++++++++++++++++++++++++++
include/linux/spmi.h | 16 ++++++++
3 files changed, 118 insertions(+)
diff --git a/drivers/spmi/spmi-devres.c b/drivers/spmi/spmi-devres.c
index 62c4b3f24d06..8feebab0365b 100644
--- a/drivers/spmi/spmi-devres.c
+++ b/drivers/spmi/spmi-devres.c
@@ -60,5 +60,29 @@ int devm_spmi_controller_add(struct device *parent, struct spmi_controller *ctrl
}
EXPORT_SYMBOL_GPL(devm_spmi_controller_add);
+static void devm_spmi_subdevice_remove(void *res)
+{
+ spmi_subdevice_remove(res);
+}
+
+struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *dev,
+ struct spmi_device *sparent)
+{
+ struct spmi_subdevice *sub_sdev;
+ int ret;
+
+ sub_sdev = spmi_subdevice_alloc_and_add(sparent);
+ if (IS_ERR(sub_sdev))
+ return sub_sdev;
+
+ ret = devm_add_action_or_reset(dev, devm_spmi_subdevice_remove, sub_sdev);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return sub_sdev;
+}
+EXPORT_SYMBOL_NS_GPL(devm_spmi_subdevice_alloc_and_add, "SPMI");
+
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SPMI devres helpers");
+MODULE_IMPORT_NS("SPMI");
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 29567c0620ae..6644c0f065f1 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -19,6 +19,7 @@
static bool is_registered;
static DEFINE_IDA(ctrl_ida);
+static DEFINE_IDA(spmi_subdevice_ida);
static void spmi_dev_release(struct device *dev)
{
@@ -31,6 +32,19 @@ static const struct device_type spmi_dev_type = {
.release = spmi_dev_release,
};
+static void spmi_subdev_release(struct device *dev)
+{
+ struct spmi_device *sdev = to_spmi_device(dev);
+ struct spmi_subdevice *sub_sdev = container_of(sdev, struct spmi_subdevice, sdev);
+
+ ida_free(&spmi_subdevice_ida, sub_sdev->devid);
+ kfree(sub_sdev);
+}
+
+static const struct device_type spmi_subdev_type = {
+ .release = spmi_subdev_release,
+};
+
static void spmi_ctrl_release(struct device *dev)
{
struct spmi_controller *ctrl = to_spmi_controller(dev);
@@ -87,6 +101,18 @@ void spmi_device_remove(struct spmi_device *sdev)
}
EXPORT_SYMBOL_GPL(spmi_device_remove);
+/**
+ * spmi_subdevice_remove() - Remove an SPMI subdevice
+ * @sub_sdev: spmi_device to be removed
+ */
+void spmi_subdevice_remove(struct spmi_subdevice *sub_sdev)
+{
+ struct spmi_device *sdev = &sub_sdev->sdev;
+
+ device_unregister(&sdev->dev);
+}
+EXPORT_SYMBOL_NS_GPL(spmi_subdevice_remove, "SPMI");
+
static inline int
spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
{
@@ -428,6 +454,58 @@ struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl)
}
EXPORT_SYMBOL_GPL(spmi_device_alloc);
+/**
+ * spmi_subdevice_alloc_and_add(): Allocate and add a new SPMI sub-device
+ * @sparent: SPMI parent device with previously registered SPMI controller
+ *
+ * Returns:
+ * Pointer to newly allocated SPMI sub-device for success or negative ERR_PTR.
+ */
+struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sparent)
+{
+ struct spmi_subdevice *sub_sdev;
+ struct spmi_device *sdev;
+ int ret;
+
+ sub_sdev = kzalloc(sizeof(*sub_sdev), GFP_KERNEL);
+ if (!sub_sdev)
+ return ERR_PTR(-ENOMEM);
+
+ ret = ida_alloc(&spmi_subdevice_ida, GFP_KERNEL);
+ if (ret < 0) {
+ kfree(sub_sdev);
+ return ERR_PTR(ret);
+ }
+
+ sdev = &sub_sdev->sdev;
+ sdev->ctrl = sparent->ctrl;
+ device_initialize(&sdev->dev);
+ sdev->dev.parent = &sparent->dev;
+ sdev->dev.bus = &spmi_bus_type;
+ sdev->dev.type = &spmi_subdev_type;
+
+ sub_sdev->devid = ret;
+ sdev->usid = sparent->usid;
+
+ ret = dev_set_name(&sdev->dev, "%d-%02x.%d.auto",
+ sdev->ctrl->nr, sdev->usid, sub_sdev->devid);
+ if (ret)
+ goto err_put_dev;
+
+ ret = device_add(&sdev->dev);
+ if (ret) {
+ dev_err(&sdev->dev, "Can't add device, status %pe\n", ERR_PTR(ret));
+ goto err_put_dev;
+ }
+
+ return sub_sdev;
+
+err_put_dev:
+ put_device(&sdev->dev);
+ return ERR_PTR(ret);
+}
+EXPORT_SYMBOL_NS_GPL(spmi_subdevice_alloc_and_add, "SPMI");
+
/**
* spmi_controller_alloc() - Allocate a new SPMI controller
* @parent: parent device
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
index 28e8c8bd3944..7cea0a5b034b 100644
--- a/include/linux/spmi.h
+++ b/include/linux/spmi.h
@@ -69,6 +69,22 @@ int spmi_device_add(struct spmi_device *sdev);
void spmi_device_remove(struct spmi_device *sdev);
+/**
+ * struct spmi_subdevice - Basic representation of an SPMI sub-device
+ * @sdev: Sub-device representation of an SPMI device
+ * @devid: Platform Device ID of an SPMI sub-device
+ */
+struct spmi_subdevice {
+ struct spmi_device sdev;
+ unsigned int devid;
+};
+
+struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sparent);
+void spmi_subdevice_remove(struct spmi_subdevice *sdev);
+
+struct spmi_subdevice *devm_spmi_subdevice_alloc_and_add(struct device *dev,
+ struct spmi_device *sparent);
+
/**
* struct spmi_controller - interface to the SPMI master controller
* @dev: Driver model representation of the device.
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 04/10] spmi: Implement spmi_subdevice_alloc_and_add() and devm variant
2026-01-14 8:39 ` [PATCH v7 04/10] spmi: Implement spmi_subdevice_alloc_and_add() and devm variant AngeloGioacchino Del Regno
@ 2026-01-14 8:51 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 8:51 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Jonathan Cameron
On Wed, Jan 14, 2026 at 09:39:51AM +0100, AngeloGioacchino Del Regno wrote:
> Some devices connected over the SPMI bus may be big, in the sense
> that those may be a complex of devices managed by a single chip
> over the SPMI bus, reachable through a single SID.
>
> Add new functions aimed at managing sub-devices of a SPMI device
> spmi_subdevice_alloc_and_add() and a spmi_subdevice_put_and_remove()
> for adding a new subdevice and removing it respectively, and also
> add their devm_* variants.
>
> The need for such functions comes from the existence of those
> complex Power Management ICs (PMICs), which feature one or many
> sub-devices, in some cases with these being even addressable on
> the chip in form of SPMI register ranges.
>
> Examples of those devices can be found in both Qualcomm platforms
> with their PMICs having PON, RTC, SDAM, GPIO controller, and other
> sub-devices, and in newer MediaTek platforms showing similar HW
> features and a similar layout with those also having many subdevs.
>
> Also, instead of generally exporting symbols, export them with a
> new "SPMI" namespace: all users will have to import this namespace
> to make use of the newly introduced exports.
...
> +static void devm_spmi_subdevice_remove(void *res)
For better readability we usually call the variable with a meaningful name, and
sub_sdev here seems the best.
> +{
> + spmi_subdevice_remove(res);
> +}
...
> + * Pointer to newly allocated SPMI sub-device for success or negative ERR_PTR.
This is "negative ERR_PTR" nonsense. Either "negative errno" or "error pointer".
Or something alike.
> +struct spmi_subdevice *spmi_subdevice_alloc_and_add(struct spmi_device *sparent)
> +{
> + struct spmi_subdevice *sub_sdev;
> + struct spmi_device *sdev;
> + int ret;
> +
> + sub_sdev = kzalloc(sizeof(*sub_sdev), GFP_KERNEL);
> + if (!sub_sdev)
> + return ERR_PTR(-ENOMEM);
> +
> + ret = ida_alloc(&spmi_subdevice_ida, GFP_KERNEL);
> + if (ret < 0) {
> + kfree(sub_sdev);
> + return ERR_PTR(ret);
> + }
> +
> + sdev = &sub_sdev->sdev;
> + sdev->ctrl = sparent->ctrl;
> + device_initialize(&sdev->dev);
> + sdev->dev.parent = &sparent->dev;
> + sdev->dev.bus = &spmi_bus_type;
> + sdev->dev.type = &spmi_subdev_type;
> + sub_sdev->devid = ret;
Too far, may be prone to mistakes in the future. The rewritten one would look
like
sub_sdev = kzalloc(sizeof(*sub_sdev), GFP_KERNEL);
if (!sub_sdev)
return ERR_PTR(-ENOMEM);
sdev = &sub_sdev->sdev;
sdev->ctrl = sparent->ctrl;
ret = ida_alloc(&spmi_subdevice_ida, GFP_KERNEL);
if (ret < 0) {
kfree(sub_sdev);
return ERR_PTR(ret);
}
sub_sdev->devid = ret;
device_initialize(&sdev->dev);
sdev->dev.parent = &sparent->dev;
sdev->dev.bus = &spmi_bus_type;
sdev->dev.type = &spmi_subdev_type;
> + sdev->usid = sparent->usid;
> +
> + ret = dev_set_name(&sdev->dev, "%d-%02x.%d.auto",
> + sdev->ctrl->nr, sdev->usid, sub_sdev->devid);
> + if (ret)
> + goto err_put_dev;
> +
> + ret = device_add(&sdev->dev);
> + if (ret) {
> + dev_err(&sdev->dev, "Can't add device, status %pe\n", ERR_PTR(ret));
> + goto err_put_dev;
> + }
> +
> + return sub_sdev;
> +
> +err_put_dev:
> + put_device(&sdev->dev);
> + return ERR_PTR(ret);
> +}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (3 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 04/10] spmi: Implement spmi_subdevice_alloc_and_add() and devm variant AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:56 ` Andy Shevchenko
2026-01-14 8:39 ` [PATCH v7 06/10] power: reset: qcom-pon: " AngeloGioacchino Del Regno
` (4 subsequent siblings)
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel
Some Qualcomm PMICs integrate a SDAM device, internally located in
a specific address range reachable through SPMI communication.
Instead of using the parent SPMI device (the main PMIC) as a kind
of syscon in this driver, register a new SPMI sub-device for SDAM
and initialize its own regmap with this sub-device's specific base
address, retrieved from the devicetree.
This allows to stop manually adding the register base address to
every R/W call in this driver, as this can be, and is now, handled
by the regmap API instead.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/nvmem/Kconfig | 1 +
drivers/nvmem/qcom-spmi-sdam.c | 36 +++++++++++++++++++++++-----------
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index bf47a982cf62..5e924c869e77 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -368,6 +368,7 @@ config NVMEM_SNVS_LPGPR
config NVMEM_SPMI_SDAM
tristate "SPMI SDAM Support"
depends on SPMI
+ select REGMAP_SPMI
help
This driver supports the Shared Direct Access Memory Module on
Qualcomm Technologies, Inc. PMICs. It provides the clients
diff --git a/drivers/nvmem/qcom-spmi-sdam.c b/drivers/nvmem/qcom-spmi-sdam.c
index 4f1cca6eab71..2bb7b3bc497e 100644
--- a/drivers/nvmem/qcom-spmi-sdam.c
+++ b/drivers/nvmem/qcom-spmi-sdam.c
@@ -9,6 +9,7 @@
#include <linux/nvmem-provider.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
+#include <linux/spmi.h>
#define SDAM_MEM_START 0x40
#define REGISTER_MAP_ID 0x40
@@ -20,7 +21,6 @@
struct sdam_chip {
struct regmap *regmap;
struct nvmem_config sdam_config;
- unsigned int base;
unsigned int size;
};
@@ -73,7 +73,7 @@ static int sdam_read(void *priv, unsigned int offset, void *val,
return -EINVAL;
}
- rc = regmap_bulk_read(sdam->regmap, sdam->base + offset, val, bytes);
+ rc = regmap_bulk_read(sdam->regmap, offset, val, bytes);
if (rc < 0)
dev_err(dev, "Failed to read SDAM offset %#x len=%zd, rc=%d\n",
offset, bytes, rc);
@@ -100,7 +100,7 @@ static int sdam_write(void *priv, unsigned int offset, void *val,
return -EINVAL;
}
- rc = regmap_bulk_write(sdam->regmap, sdam->base + offset, val, bytes);
+ rc = regmap_bulk_write(sdam->regmap, offset, val, bytes);
if (rc < 0)
dev_err(dev, "Failed to write SDAM offset %#x len=%zd, rc=%d\n",
offset, bytes, rc);
@@ -110,8 +110,17 @@ static int sdam_write(void *priv, unsigned int offset, void *val,
static int sdam_probe(struct platform_device *pdev)
{
+ struct regmap_config sdam_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x100,
+ .fast_io = true,
+ };
struct sdam_chip *sdam;
struct nvmem_device *nvmem;
+ struct spmi_device *sparent;
+ struct spmi_subdevice *sub_sdev;
+ struct device *dev = &pdev->dev;
unsigned int val;
int rc;
@@ -119,19 +128,23 @@ static int sdam_probe(struct platform_device *pdev)
if (!sdam)
return -ENOMEM;
- sdam->regmap = dev_get_regmap(pdev->dev.parent, NULL);
- if (!sdam->regmap) {
- dev_err(&pdev->dev, "Failed to get regmap handle\n");
- return -ENXIO;
- }
+ sparent = to_spmi_device(dev->parent);
+ sub_sdev = devm_spmi_subdevice_alloc_and_add(dev, sparent);
+ if (IS_ERR(sub_sdev))
+ return PTR_ERR(sub_sdev);
- rc = of_property_read_u32(pdev->dev.of_node, "reg", &sdam->base);
+ rc = of_property_read_u32(dev->of_node, "reg", &sdam_regmap_config.reg_base);
if (rc < 0) {
dev_err(&pdev->dev, "Failed to get SDAM base, rc=%d\n", rc);
return -EINVAL;
}
- rc = regmap_read(sdam->regmap, sdam->base + SDAM_SIZE, &val);
+ sdam->regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev, &sdam_regmap_config);
+ if (IS_ERR(sdam->regmap))
+ return dev_err_probe(&pdev->dev, PTR_ERR(sdam->regmap),
+ "Failed to get regmap handle\n");
+
+ rc = regmap_read(sdam->regmap, SDAM_SIZE, &val);
if (rc < 0) {
dev_err(&pdev->dev, "Failed to read SDAM_SIZE rc=%d\n", rc);
return -EINVAL;
@@ -159,7 +172,7 @@ static int sdam_probe(struct platform_device *pdev)
}
dev_dbg(&pdev->dev,
"SDAM base=%#x size=%u registered successfully\n",
- sdam->base, sdam->size);
+ sdam_regmap_config.reg_base, sdam->size);
return 0;
}
@@ -181,3 +194,4 @@ module_platform_driver(sdam_driver);
MODULE_DESCRIPTION("QCOM SPMI SDAM driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("SPMI");
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 ` [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add() AngeloGioacchino Del Regno
@ 2026-01-14 8:56 ` Andy Shevchenko
2026-01-14 8:59 ` AngeloGioacchino Del Regno
0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 8:56 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
> Some Qualcomm PMICs integrate a SDAM device, internally located in
> a specific address range reachable through SPMI communication.
>
> Instead of using the parent SPMI device (the main PMIC) as a kind
> of syscon in this driver, register a new SPMI sub-device for SDAM
> and initialize its own regmap with this sub-device's specific base
> address, retrieved from the devicetree.
>
> This allows to stop manually adding the register base address to
> every R/W call in this driver, as this can be, and is now, handled
> by the regmap API instead.
...
> + struct regmap_config sdam_regmap_config = {
> + .reg_bits = 16,
> + .val_bits = 8,
> + .max_register = 0x100,
Are you sure? This might be a bad naming, but here max == the last accessible.
I bet it has to be 0xff (but since the address is 16-bit it might be actually
257 registers, but sounds very weird).
> + .fast_io = true,
> + };
...
> + rc = of_property_read_u32(dev->of_node, "reg", &sdam_regmap_config.reg_base);
Why not device_property_read_u32(dev, ...) ?
...
> + sdam->regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev, &sdam_regmap_config);
> + if (IS_ERR(sdam->regmap))
> + return dev_err_probe(&pdev->dev, PTR_ERR(sdam->regmap),
You have "dev".
> + "Failed to get regmap handle\n");
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:56 ` Andy Shevchenko
@ 2026-01-14 8:59 ` AngeloGioacchino Del Regno
2026-01-14 9:00 ` Andy Shevchenko
0 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:59 UTC (permalink / raw)
To: Andy Shevchenko
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
>> Some Qualcomm PMICs integrate a SDAM device, internally located in
>> a specific address range reachable through SPMI communication.
>>
>> Instead of using the parent SPMI device (the main PMIC) as a kind
>> of syscon in this driver, register a new SPMI sub-device for SDAM
>> and initialize its own regmap with this sub-device's specific base
>> address, retrieved from the devicetree.
>>
>> This allows to stop manually adding the register base address to
>> every R/W call in this driver, as this can be, and is now, handled
>> by the regmap API instead.
>
> ...
>
>> + struct regmap_config sdam_regmap_config = {
>> + .reg_bits = 16,
>> + .val_bits = 8,
>
>> + .max_register = 0x100,
>
> Are you sure? This might be a bad naming, but here max == the last accessible.
> I bet it has to be 0xff (but since the address is 16-bit it might be actually
> 257 registers, but sounds very weird).
>
Yes, I'm sure.
>> + .fast_io = true,
>> + };
>
> ...
>
>> + rc = of_property_read_u32(dev->of_node, "reg", &sdam_regmap_config.reg_base);
>
> Why not device_property_read_u32(dev, ...) ?
>
> ...
>
>> + sdam->regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev, &sdam_regmap_config);
>> + if (IS_ERR(sdam->regmap))
>> + return dev_err_probe(&pdev->dev, PTR_ERR(sdam->regmap),
>
> You have "dev".
>
>> + "Failed to get regmap handle\n");
>
For the other comments: Done in v8.
Cheers,
Angelo
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:59 ` AngeloGioacchino Del Regno
@ 2026-01-14 9:00 ` Andy Shevchenko
2026-01-14 9:03 ` AngeloGioacchino Del Regno
0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:00 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> > On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
> > > Some Qualcomm PMICs integrate a SDAM device, internally located in
> > > a specific address range reachable through SPMI communication.
> > >
> > > Instead of using the parent SPMI device (the main PMIC) as a kind
> > > of syscon in this driver, register a new SPMI sub-device for SDAM
> > > and initialize its own regmap with this sub-device's specific base
> > > address, retrieved from the devicetree.
> > >
> > > This allows to stop manually adding the register base address to
> > > every R/W call in this driver, as this can be, and is now, handled
> > > by the regmap API instead.
...
> > > + struct regmap_config sdam_regmap_config = {
> > > + .reg_bits = 16,
> > > + .val_bits = 8,
> >
> > > + .max_register = 0x100,
> >
> > Are you sure? This might be a bad naming, but here max == the last accessible.
> > I bet it has to be 0xff (but since the address is 16-bit it might be actually
> > 257 registers, but sounds very weird).
>
> Yes, I'm sure.
So, what is resided on address 0x100 ?
> > > + .fast_io = true,
> > > + };
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:00 ` Andy Shevchenko
@ 2026-01-14 9:03 ` AngeloGioacchino Del Regno
2026-01-14 9:07 ` Andy Shevchenko
0 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 9:03 UTC (permalink / raw)
To: Andy Shevchenko
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
Il 14/01/26 10:00, Andy Shevchenko ha scritto:
> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
>>>> Some Qualcomm PMICs integrate a SDAM device, internally located in
>>>> a specific address range reachable through SPMI communication.
>>>>
>>>> Instead of using the parent SPMI device (the main PMIC) as a kind
>>>> of syscon in this driver, register a new SPMI sub-device for SDAM
>>>> and initialize its own regmap with this sub-device's specific base
>>>> address, retrieved from the devicetree.
>>>>
>>>> This allows to stop manually adding the register base address to
>>>> every R/W call in this driver, as this can be, and is now, handled
>>>> by the regmap API instead.
>
> ...
>
>>>> + struct regmap_config sdam_regmap_config = {
>>>> + .reg_bits = 16,
>>>> + .val_bits = 8,
>>>
>>>> + .max_register = 0x100,
>>>
>>> Are you sure? This might be a bad naming, but here max == the last accessible.
>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
>>> 257 registers, but sounds very weird).
>>
>> Yes, I'm sure.
>
> So, what is resided on address 0x100 ?
>
I don't remember, this is research from around 5 months ago, when I've sent
the v1 of this.
If you really want though, I can incorrectly set max_register to 0xff.
Cheers,
Angelo
>>>> + .fast_io = true,
>>>> + };
>
>
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:03 ` AngeloGioacchino Del Regno
@ 2026-01-14 9:07 ` Andy Shevchenko
2026-01-14 9:09 ` AngeloGioacchino Del Regno
0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:07 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
> > On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
> > > Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> > > > On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
...
> > > > > + struct regmap_config sdam_regmap_config = {
> > > > > + .reg_bits = 16,
> > > > > + .val_bits = 8,
> > > >
> > > > > + .max_register = 0x100,
> > > >
> > > > Are you sure? This might be a bad naming, but here max == the last accessible.
> > > > I bet it has to be 0xff (but since the address is 16-bit it might be actually
> > > > 257 registers, but sounds very weird).
> > >
> > > Yes, I'm sure.
> >
> > So, what is resided on address 0x100 ?
>
> I don't remember, this is research from around 5 months ago, when I've sent
> the v1 of this.
>
> If you really want though, I can incorrectly set max_register to 0xff.
Why incorrectly? Can you dig into the datasheet and check, please? We don't
know what is the 0x100 address means.
> > > > > + .fast_io = true,
> > > > > + };
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:07 ` Andy Shevchenko
@ 2026-01-14 9:09 ` AngeloGioacchino Del Regno
2026-01-14 9:42 ` Andy Shevchenko
0 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 9:09 UTC (permalink / raw)
To: Andy Shevchenko
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
Il 14/01/26 10:07, Andy Shevchenko ha scritto:
> On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
>> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
>>> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
>>>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
>>>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
>
> ...
>
>>>>>> + struct regmap_config sdam_regmap_config = {
>>>>>> + .reg_bits = 16,
>>>>>> + .val_bits = 8,
>>>>>
>>>>>> + .max_register = 0x100,
>>>>>
>>>>> Are you sure? This might be a bad naming, but here max == the last accessible.
>>>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
>>>>> 257 registers, but sounds very weird).
>>>>
>>>> Yes, I'm sure.
>>>
>>> So, what is resided on address 0x100 ?
>>
>> I don't remember, this is research from around 5 months ago, when I've sent
>> the v1 of this.
>>
>> If you really want though, I can incorrectly set max_register to 0xff.
>
> Why incorrectly? Can you dig into the datasheet and check, please? We don't
> know what is the 0x100 address means.
>
I don't have any datasheets for Qualcomm IPs.
Cheers,
Angelo
>>>>>> + .fast_io = true,
>>>>>> + };
>
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:09 ` AngeloGioacchino Del Regno
@ 2026-01-14 9:42 ` Andy Shevchenko
2026-01-14 9:47 ` Konrad Dybcio
0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:42 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel
On Wed, Jan 14, 2026 at 10:09:45AM +0100, AngeloGioacchino Del Regno wrote:
> Il 14/01/26 10:07, Andy Shevchenko ha scritto:
> > On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
> > > Il 14/01/26 10:00, Andy Shevchenko ha scritto:
> > > > On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
> > > > > Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> > > > > > On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
...
> > > > > > > + struct regmap_config sdam_regmap_config = {
> > > > > > > + .reg_bits = 16,
> > > > > > > + .val_bits = 8,
> > > > > >
> > > > > > > + .max_register = 0x100,
> > > > > >
> > > > > > Are you sure? This might be a bad naming, but here max == the last accessible.
> > > > > > I bet it has to be 0xff (but since the address is 16-bit it might be actually
> > > > > > 257 registers, but sounds very weird).
> > > > >
> > > > > Yes, I'm sure.
> > > >
> > > > So, what is resided on address 0x100 ?
> > >
> > > I don't remember, this is research from around 5 months ago, when I've sent
> > > the v1 of this.
> > >
> > > If you really want though, I can incorrectly set max_register to 0xff.
> >
> > Why incorrectly? Can you dig into the datasheet and check, please? We don't
> > know what is the 0x100 address means.
>
> I don't have any datasheets for Qualcomm IPs.
Hmm... Can we have somebody from QC to check on this?
Perhaps Dmitry?
> > > > > > > + .fast_io = true,
> > > > > > > + };
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:42 ` Andy Shevchenko
@ 2026-01-14 9:47 ` Konrad Dybcio
2026-01-14 9:55 ` Andy Shevchenko
0 siblings, 1 reply; 32+ messages in thread
From: Konrad Dybcio @ 2026-01-14 9:47 UTC (permalink / raw)
To: Andy Shevchenko, AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, mitltlatltl, krishna.kurapati, linux-arm-msm,
linux-iio, linux-kernel, linux-phy, linux-pm, kernel
On 1/14/26 10:42 AM, Andy Shevchenko wrote:
> On Wed, Jan 14, 2026 at 10:09:45AM +0100, AngeloGioacchino Del Regno wrote:
>> Il 14/01/26 10:07, Andy Shevchenko ha scritto:
>>> On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
>>>> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
>>>>> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
>>>>>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
>>>>>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
>
> ...
>
>>>>>>>> + struct regmap_config sdam_regmap_config = {
>>>>>>>> + .reg_bits = 16,
>>>>>>>> + .val_bits = 8,
>>>>>>>
>>>>>>>> + .max_register = 0x100,
>>>>>>>
>>>>>>> Are you sure? This might be a bad naming, but here max == the last accessible.
>>>>>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
>>>>>>> 257 registers, but sounds very weird).
>>>>>>
>>>>>> Yes, I'm sure.
>>>>>
>>>>> So, what is resided on address 0x100 ?
>>>>
>>>> I don't remember, this is research from around 5 months ago, when I've sent
>>>> the v1 of this.
>>>>
>>>> If you really want though, I can incorrectly set max_register to 0xff.
>>>
>>> Why incorrectly? Can you dig into the datasheet and check, please? We don't
>>> know what is the 0x100 address means.
>>
>> I don't have any datasheets for Qualcomm IPs.
>
> Hmm... Can we have somebody from QC to check on this?
> Perhaps Dmitry?
0xe6 is the last usable register today
But I wouldn't mind either 0xff or 0x100 because I don't want
anyone to pull their hair out if a regmap access is dropped some day..
Konrad
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:47 ` Konrad Dybcio
@ 2026-01-14 9:55 ` Andy Shevchenko
2026-01-14 9:58 ` Andy Shevchenko
2026-01-14 10:04 ` Konrad Dybcio
0 siblings, 2 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:55 UTC (permalink / raw)
To: Konrad Dybcio
Cc: AngeloGioacchino Del Regno, jic23, dlechner, nuno.sa, andy, arnd,
gregkh, srini, vkoul, neil.armstrong, sre, sboyd, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, mitltlatltl,
krishna.kurapati, linux-arm-msm, linux-iio, linux-kernel,
linux-phy, linux-pm, kernel
On Wed, Jan 14, 2026 at 10:47:20AM +0100, Konrad Dybcio wrote:
> On 1/14/26 10:42 AM, Andy Shevchenko wrote:
> > On Wed, Jan 14, 2026 at 10:09:45AM +0100, AngeloGioacchino Del Regno wrote:
> >> Il 14/01/26 10:07, Andy Shevchenko ha scritto:
> >>> On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
> >>>> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
> >>>>> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
> >>>>>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> >>>>>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
...
> >>>>>>>> + struct regmap_config sdam_regmap_config = {
> >>>>>>>> + .reg_bits = 16,
> >>>>>>>> + .val_bits = 8,
> >>>>>>>
> >>>>>>>> + .max_register = 0x100,
> >>>>>>>
> >>>>>>> Are you sure? This might be a bad naming, but here max == the last accessible.
> >>>>>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
> >>>>>>> 257 registers, but sounds very weird).
> >>>>>>
> >>>>>> Yes, I'm sure.
> >>>>>
> >>>>> So, what is resided on address 0x100 ?
> >>>>
> >>>> I don't remember, this is research from around 5 months ago, when I've sent
> >>>> the v1 of this.
> >>>>
> >>>> If you really want though, I can incorrectly set max_register to 0xff.
> >>>
> >>> Why incorrectly? Can you dig into the datasheet and check, please? We don't
> >>> know what is the 0x100 address means.
> >>
> >> I don't have any datasheets for Qualcomm IPs.
> >
> > Hmm... Can we have somebody from QC to check on this?
> > Perhaps Dmitry?
>
> 0xe6 is the last usable register today
Thanks for checking!
> But I wouldn't mind either 0xff or 0x100 because I don't want
> anyone to pull their hair out if a regmap access is dropped some day..
There is actually about the exact window size where registers are belong to the
same entity (subdevice). As in the HW world most of the things are stuck with
power-of-two numbers, and taking into account the naming of the field, I do not
believe one provides a 257 (256 + 1 = 2⁸ + 1) register _windows_ ("s" is also
important here, as it points out to the pattern) for the subdevices. I bet the
0xff, i.e. 256, is the *correct* window from the HW perspective.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:55 ` Andy Shevchenko
@ 2026-01-14 9:58 ` Andy Shevchenko
2026-01-14 10:04 ` Konrad Dybcio
1 sibling, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:58 UTC (permalink / raw)
To: Konrad Dybcio
Cc: AngeloGioacchino Del Regno, jic23, dlechner, nuno.sa, andy, arnd,
gregkh, srini, vkoul, neil.armstrong, sre, sboyd, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, mitltlatltl,
krishna.kurapati, linux-arm-msm, linux-iio, linux-kernel,
linux-phy, linux-pm, kernel
On Wed, Jan 14, 2026 at 11:55:18AM +0200, Andy Shevchenko wrote:
> On Wed, Jan 14, 2026 at 10:47:20AM +0100, Konrad Dybcio wrote:
> > On 1/14/26 10:42 AM, Andy Shevchenko wrote:
> > > On Wed, Jan 14, 2026 at 10:09:45AM +0100, AngeloGioacchino Del Regno wrote:
> > >> Il 14/01/26 10:07, Andy Shevchenko ha scritto:
> > >>> On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
> > >>>> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
> > >>>>> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
> > >>>>>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> > >>>>>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
...
> > >>>>>>>> + struct regmap_config sdam_regmap_config = {
> > >>>>>>>> + .reg_bits = 16,
> > >>>>>>>> + .val_bits = 8,
> > >>>>>>>
> > >>>>>>>> + .max_register = 0x100,
> > >>>>>>>
> > >>>>>>> Are you sure? This might be a bad naming, but here max == the last accessible.
> > >>>>>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
> > >>>>>>> 257 registers, but sounds very weird).
> > >>>>>>
> > >>>>>> Yes, I'm sure.
> > >>>>>
> > >>>>> So, what is resided on address 0x100 ?
> > >>>>
> > >>>> I don't remember, this is research from around 5 months ago, when I've sent
> > >>>> the v1 of this.
> > >>>>
> > >>>> If you really want though, I can incorrectly set max_register to 0xff.
> > >>>
> > >>> Why incorrectly? Can you dig into the datasheet and check, please? We don't
> > >>> know what is the 0x100 address means.
> > >>
> > >> I don't have any datasheets for Qualcomm IPs.
> > >
> > > Hmm... Can we have somebody from QC to check on this?
> > > Perhaps Dmitry?
> >
> > 0xe6 is the last usable register today
>
> Thanks for checking!
>
> > But I wouldn't mind either 0xff or 0x100 because I don't want
> > anyone to pull their hair out if a regmap access is dropped some day..
>
> There is actually about the exact window size where registers are belong to the
> same entity (subdevice). As in the HW world most of the things are stuck with
> power-of-two numbers, and taking into account the naming of the field, I do not
> believe one provides a 257 (256 + 1 = 2⁸ + 1) register _windows_ ("s" is also
> important here, as it points out to the pattern) for the subdevices. I bet the
> 0xff, i.e. 256, is the *correct* window from the HW perspective.
Even more, since these devices are described in DT, the presence of any two
sequential windows will support my version for 100% correctness, as otherwise
it will mean overlapping in the addresses for two devices, i.e. 0x100 in one
is actually 0x00 in the other.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:55 ` Andy Shevchenko
2026-01-14 9:58 ` Andy Shevchenko
@ 2026-01-14 10:04 ` Konrad Dybcio
2026-01-14 10:09 ` Andy Shevchenko
1 sibling, 1 reply; 32+ messages in thread
From: Konrad Dybcio @ 2026-01-14 10:04 UTC (permalink / raw)
To: Andy Shevchenko
Cc: AngeloGioacchino Del Regno, jic23, dlechner, nuno.sa, andy, arnd,
gregkh, srini, vkoul, neil.armstrong, sre, sboyd, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, mitltlatltl,
krishna.kurapati, linux-arm-msm, linux-iio, linux-kernel,
linux-phy, linux-pm, kernel
On 1/14/26 10:55 AM, Andy Shevchenko wrote:
> On Wed, Jan 14, 2026 at 10:47:20AM +0100, Konrad Dybcio wrote:
>> On 1/14/26 10:42 AM, Andy Shevchenko wrote:
>>> On Wed, Jan 14, 2026 at 10:09:45AM +0100, AngeloGioacchino Del Regno wrote:
>>>> Il 14/01/26 10:07, Andy Shevchenko ha scritto:
>>>>> On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
>>>>>> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
>>>>>>> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
>>>>>>>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
>>>>>>>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
>
> ...
>
>>>>>>>>>> + struct regmap_config sdam_regmap_config = {
>>>>>>>>>> + .reg_bits = 16,
>>>>>>>>>> + .val_bits = 8,
>>>>>>>>>
>>>>>>>>>> + .max_register = 0x100,
>>>>>>>>>
>>>>>>>>> Are you sure? This might be a bad naming, but here max == the last accessible.
>>>>>>>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
>>>>>>>>> 257 registers, but sounds very weird).
>>>>>>>>
>>>>>>>> Yes, I'm sure.
>>>>>>>
>>>>>>> So, what is resided on address 0x100 ?
>>>>>>
>>>>>> I don't remember, this is research from around 5 months ago, when I've sent
>>>>>> the v1 of this.
>>>>>>
>>>>>> If you really want though, I can incorrectly set max_register to 0xff.
>>>>>
>>>>> Why incorrectly? Can you dig into the datasheet and check, please? We don't
>>>>> know what is the 0x100 address means.
>>>>
>>>> I don't have any datasheets for Qualcomm IPs.
>>>
>>> Hmm... Can we have somebody from QC to check on this?
>>> Perhaps Dmitry?
>>
>> 0xe6 is the last usable register today
>
> Thanks for checking!
>
>> But I wouldn't mind either 0xff or 0x100 because I don't want
>> anyone to pull their hair out if a regmap access is dropped some day..
>
> There is actually about the exact window size where registers are belong to the
> same entity (subdevice). As in the HW world most of the things are stuck with
> power-of-two numbers, and taking into account the naming of the field, I do not
> believe one provides a 257 (256 + 1 = 2⁸ + 1) register _windows_ ("s" is also
> important here, as it points out to the pattern) for the subdevices. I bet the
> 0xff, i.e. 256, is the *correct* window from the HW perspective.
Right, [0x100n, 0x100n + 0xff] inclusive is the reserved register window
for all Qualcomm PMIC peripherals, so I guess 0xff is the correct choice
here
If a peripheral is more complex, it's split into a couple of these
same-sized blocks
Konrad
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 10:04 ` Konrad Dybcio
@ 2026-01-14 10:09 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 10:09 UTC (permalink / raw)
To: Konrad Dybcio
Cc: AngeloGioacchino Del Regno, jic23, dlechner, nuno.sa, andy, arnd,
gregkh, srini, vkoul, neil.armstrong, sre, sboyd, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, mitltlatltl,
krishna.kurapati, linux-arm-msm, linux-iio, linux-kernel,
linux-phy, linux-pm, kernel
On Wed, Jan 14, 2026 at 11:04:30AM +0100, Konrad Dybcio wrote:
> On 1/14/26 10:55 AM, Andy Shevchenko wrote:
> > On Wed, Jan 14, 2026 at 10:47:20AM +0100, Konrad Dybcio wrote:
> >> On 1/14/26 10:42 AM, Andy Shevchenko wrote:
> >>> On Wed, Jan 14, 2026 at 10:09:45AM +0100, AngeloGioacchino Del Regno wrote:
> >>>> Il 14/01/26 10:07, Andy Shevchenko ha scritto:
> >>>>> On Wed, Jan 14, 2026 at 10:03:57AM +0100, AngeloGioacchino Del Regno wrote:
> >>>>>> Il 14/01/26 10:00, Andy Shevchenko ha scritto:
> >>>>>>> On Wed, Jan 14, 2026 at 09:59:40AM +0100, AngeloGioacchino Del Regno wrote:
> >>>>>>>> Il 14/01/26 09:56, Andy Shevchenko ha scritto:
> >>>>>>>>> On Wed, Jan 14, 2026 at 09:39:52AM +0100, AngeloGioacchino Del Regno wrote:
...
> >>>>>>>>>> + struct regmap_config sdam_regmap_config = {
> >>>>>>>>>> + .reg_bits = 16,
> >>>>>>>>>> + .val_bits = 8,
> >>>>>>>>>
> >>>>>>>>>> + .max_register = 0x100,
> >>>>>>>>>
> >>>>>>>>> Are you sure? This might be a bad naming, but here max == the last accessible.
> >>>>>>>>> I bet it has to be 0xff (but since the address is 16-bit it might be actually
> >>>>>>>>> 257 registers, but sounds very weird).
> >>>>>>>>
> >>>>>>>> Yes, I'm sure.
> >>>>>>>
> >>>>>>> So, what is resided on address 0x100 ?
> >>>>>>
> >>>>>> I don't remember, this is research from around 5 months ago, when I've sent
> >>>>>> the v1 of this.
> >>>>>>
> >>>>>> If you really want though, I can incorrectly set max_register to 0xff.
> >>>>>
> >>>>> Why incorrectly? Can you dig into the datasheet and check, please? We don't
> >>>>> know what is the 0x100 address means.
> >>>>
> >>>> I don't have any datasheets for Qualcomm IPs.
> >>>
> >>> Hmm... Can we have somebody from QC to check on this?
> >>> Perhaps Dmitry?
> >>
> >> 0xe6 is the last usable register today
> >
> > Thanks for checking!
> >
> >> But I wouldn't mind either 0xff or 0x100 because I don't want
> >> anyone to pull their hair out if a regmap access is dropped some day..
> >
> > There is actually about the exact window size where registers are belong to the
> > same entity (subdevice). As in the HW world most of the things are stuck with
> > power-of-two numbers, and taking into account the naming of the field, I do not
> > believe one provides a 257 (256 + 1 = 2⁸ + 1) register _windows_ ("s" is also
> > important here, as it points out to the pattern) for the subdevices. I bet the
> > 0xff, i.e. 256, is the *correct* window from the HW perspective.
>
> Right, [0x100n, 0x100n + 0xff] inclusive is the reserved register window
> for all Qualcomm PMIC peripherals, so I guess 0xff is the correct choice
> here
Thanks for the clarification, v8 addresses that, so seems to me good to go.
> If a peripheral is more complex, it's split into a couple of these
> same-sized blocks
Right.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 06/10] power: reset: qcom-pon: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (4 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 05/10] nvmem: qcom-spmi-sdam: Migrate to devm_spmi_subdevice_alloc_and_add() AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:57 ` Andy Shevchenko
2026-01-14 8:39 ` [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: " AngeloGioacchino Del Regno
` (3 subsequent siblings)
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel, Sebastian Reichel
Some Qualcomm PMICs integrates a Power On device supporting pwrkey
and resin along with the Android reboot reason action identifier.
Instead of using the parent SPMI device (the main PMIC) as a kind
of syscon in this driver, register a new SPMI sub-device for PON
and initialize its own regmap with this sub-device's specific base
address, retrieved from the devicetree.
This allows to stop manually adding the register base address to
every R/W call in this driver, as this can be, and is now, handled
by the regmap API instead.
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/power/reset/qcom-pon.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/power/reset/qcom-pon.c b/drivers/power/reset/qcom-pon.c
index 7e108982a582..0e075a2e5e48 100644
--- a/drivers/power/reset/qcom-pon.c
+++ b/drivers/power/reset/qcom-pon.c
@@ -11,6 +11,7 @@
#include <linux/reboot.h>
#include <linux/reboot-mode.h>
#include <linux/regmap.h>
+#include <linux/spmi.h>
#define PON_SOFT_RB_SPARE 0x8f
@@ -22,7 +23,6 @@
struct qcom_pon {
struct device *dev;
struct regmap *regmap;
- u32 baseaddr;
struct reboot_mode_driver reboot_mode;
long reason_shift;
};
@@ -35,7 +35,7 @@ static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot,
int ret;
ret = regmap_update_bits(pon->regmap,
- pon->baseaddr + PON_SOFT_RB_SPARE,
+ PON_SOFT_RB_SPARE,
GENMASK(7, pon->reason_shift),
magic << pon->reason_shift);
if (ret < 0)
@@ -46,27 +46,42 @@ static int qcom_pon_reboot_mode_write(struct reboot_mode_driver *reboot,
static int qcom_pon_probe(struct platform_device *pdev)
{
+ struct regmap_config qcom_pon_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x100,
+ .fast_io = true,
+ };
+ struct device *dev = &pdev->dev;
+ struct spmi_subdevice *sub_sdev;
+ struct spmi_device *sparent;
struct qcom_pon *pon;
long reason_shift;
int error;
+ if (!dev->parent)
+ return -ENODEV;
+
pon = devm_kzalloc(&pdev->dev, sizeof(*pon), GFP_KERNEL);
if (!pon)
return -ENOMEM;
pon->dev = &pdev->dev;
- pon->regmap = dev_get_regmap(pdev->dev.parent, NULL);
- if (!pon->regmap) {
- dev_err(&pdev->dev, "failed to locate regmap\n");
- return -ENODEV;
- }
+ sparent = to_spmi_device(dev->parent);
+ sub_sdev = devm_spmi_subdevice_alloc_and_add(dev, sparent);
+ if (IS_ERR(sub_sdev))
+ return PTR_ERR(sub_sdev);
- error = of_property_read_u32(pdev->dev.of_node, "reg",
- &pon->baseaddr);
+ error = of_property_read_u32(dev->of_node, "reg",
+ &qcom_pon_regmap_config.reg_base);
if (error)
return error;
+ pon->regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev, &qcom_pon_regmap_config);
+ if (IS_ERR(pon->regmap))
+ return PTR_ERR(pon->regmap);
+
reason_shift = (long)of_device_get_match_data(&pdev->dev);
if (reason_shift != NO_REASON_SHIFT) {
@@ -106,3 +121,4 @@ module_platform_driver(qcom_pon_driver);
MODULE_DESCRIPTION("Qualcomm Power On driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("SPMI");
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 06/10] power: reset: qcom-pon: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 ` [PATCH v7 06/10] power: reset: qcom-pon: " AngeloGioacchino Del Regno
@ 2026-01-14 8:57 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 8:57 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Sebastian Reichel
On Wed, Jan 14, 2026 at 09:39:53AM +0100, AngeloGioacchino Del Regno wrote:
> Some Qualcomm PMICs integrates a Power On device supporting pwrkey
> and resin along with the Android reboot reason action identifier.
>
> Instead of using the parent SPMI device (the main PMIC) as a kind
> of syscon in this driver, register a new SPMI sub-device for PON
> and initialize its own regmap with this sub-device's specific base
> address, retrieved from the devicetree.
>
> This allows to stop manually adding the register base address to
> every R/W call in this driver, as this can be, and is now, handled
> by the regmap API instead.
Same comments as per previous patch.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (5 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 06/10] power: reset: qcom-pon: " AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:59 ` Andy Shevchenko
2026-01-14 8:39 ` [PATCH v7 08/10] misc: qcom-coincell: " AngeloGioacchino Del Regno
` (2 subsequent siblings)
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel, Abel Vesa
Some Qualcomm PMICs integrate an USB Repeater device, used to
convert between eUSB2 and USB 2.0 signaling levels, reachable
in a specific address range over SPMI.
Instead of using the parent SPMI device (the main PMIC) as a kind
of syscon in this driver, register a new SPMI sub-device for EUSB2
and initialize its own regmap with this sub-device's specific base
address, retrieved from the devicetree.
This allows to stop manually adding the register base address to
every R/W call in this driver, as this can be, and is now, handled
by the regmap API instead.
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Reviewed-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/phy/qualcomm/Kconfig | 2 +
.../phy/qualcomm/phy-qcom-eusb2-repeater.c | 55 ++++++++++++-------
2 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig
index 60a0ead127fa..902a788f35f1 100644
--- a/drivers/phy/qualcomm/Kconfig
+++ b/drivers/phy/qualcomm/Kconfig
@@ -128,7 +128,9 @@ config PHY_QCOM_QUSB2
config PHY_QCOM_EUSB2_REPEATER
tristate "Qualcomm PMIC eUSB2 Repeater Driver"
depends on OF && (ARCH_QCOM || COMPILE_TEST)
+ depends on SPMI
select GENERIC_PHY
+ select REGMAP_SPMI
help
Enable support for the USB high-speed eUSB2 repeater on Qualcomm
PMICs. The repeater is paired with a Synopsys or M31 eUSB2 Phy
diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
index efeec4709a15..88e10020f958 100644
--- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
+++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c
@@ -9,6 +9,7 @@
#include <linux/regmap.h>
#include <linux/of.h>
#include <linux/phy/phy.h>
+#include <linux/spmi.h>
/* eUSB2 status registers */
#define EUSB2_RPTR_STATUS 0x08
@@ -66,7 +67,6 @@ struct eusb2_repeater {
struct phy *phy;
struct regulator_bulk_data *vregs;
const struct eusb2_repeater_cfg *cfg;
- u32 base;
enum phy_mode mode;
};
@@ -143,7 +143,6 @@ static int eusb2_repeater_init(struct phy *phy)
struct eusb2_repeater *rptr = phy_get_drvdata(phy);
struct device_node *np = rptr->dev->of_node;
struct regmap *regmap = rptr->regmap;
- u32 base = rptr->base;
u32 poll_val;
s32 dt_val;
int ret;
@@ -154,37 +153,37 @@ static int eusb2_repeater_init(struct phy *phy)
if (ret)
return ret;
- regmap_write(regmap, base + EUSB2_EN_CTL1, EUSB2_RPTR_EN);
+ regmap_write(regmap, EUSB2_EN_CTL1, EUSB2_RPTR_EN);
/* Write registers from init table */
for (int i = 0; i < rptr->cfg->init_tbl_num; i++)
- regmap_write(regmap, base + rptr->cfg->init_tbl[i].reg,
+ regmap_write(regmap, rptr->cfg->init_tbl[i].reg,
rptr->cfg->init_tbl[i].value);
/* Override registers from devicetree values */
if (!of_property_read_u8(np, "qcom,tune-usb2-preem", &val))
- regmap_write(regmap, base + EUSB2_TUNE_USB2_PREEM, val);
+ regmap_write(regmap, EUSB2_TUNE_USB2_PREEM, val);
if (!of_property_read_u8(np, "qcom,tune-usb2-disc-thres", &val))
- regmap_write(regmap, base + EUSB2_TUNE_HSDISC, val);
+ regmap_write(regmap, EUSB2_TUNE_HSDISC, val);
if (!of_property_read_u8(np, "qcom,tune-usb2-amplitude", &val))
- regmap_write(regmap, base + EUSB2_TUNE_IUSB2, val);
+ regmap_write(regmap, EUSB2_TUNE_IUSB2, val);
if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val))
- regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val);
+ regmap_write(regmap, EUSB2_TUNE_RES_FSDIF, val);
if (!of_property_read_s32(np, "qcom,squelch-detector-bp", &dt_val)) {
for (i = 0; i < ARRAY_SIZE(squelch_detector); i++) {
if (squelch_detector[i] == dt_val) {
- regmap_write(regmap, base + EUSB2_TUNE_SQUELCH_U, i);
+ regmap_write(regmap, EUSB2_TUNE_SQUELCH_U, i);
break;
}
}
}
/* Wait for status OK */
- ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val,
+ ret = regmap_read_poll_timeout(regmap, EUSB2_RPTR_STATUS, poll_val,
poll_val & RPTR_OK, 10, 5);
if (ret)
dev_err(rptr->dev, "initialization timed-out\n");
@@ -197,7 +196,6 @@ static int eusb2_repeater_set_mode(struct phy *phy,
{
struct eusb2_repeater *rptr = phy_get_drvdata(phy);
struct regmap *regmap = rptr->regmap;
- u32 base = rptr->base;
switch (mode) {
case PHY_MODE_USB_HOST:
@@ -206,8 +204,8 @@ static int eusb2_repeater_set_mode(struct phy *phy,
* per eUSB 1.2 Spec. Below implement software workaround until
* PHY and controller is fixing seen observation.
*/
- regmap_write(regmap, base + EUSB2_FORCE_EN_5, F_CLK_19P2M_EN);
- regmap_write(regmap, base + EUSB2_FORCE_VAL_5, V_CLK_19P2M_EN);
+ regmap_write(regmap, EUSB2_FORCE_EN_5, F_CLK_19P2M_EN);
+ regmap_write(regmap, EUSB2_FORCE_VAL_5, V_CLK_19P2M_EN);
break;
case PHY_MODE_USB_DEVICE:
/*
@@ -216,8 +214,8 @@ static int eusb2_repeater_set_mode(struct phy *phy,
* repeater doesn't clear previous value due to shared
* regulators (say host <-> device mode switch).
*/
- regmap_write(regmap, base + EUSB2_FORCE_EN_5, 0);
- regmap_write(regmap, base + EUSB2_FORCE_VAL_5, 0);
+ regmap_write(regmap, EUSB2_FORCE_EN_5, 0);
+ regmap_write(regmap, EUSB2_FORCE_VAL_5, 0);
break;
default:
return -EINVAL;
@@ -242,13 +240,23 @@ static const struct phy_ops eusb2_repeater_ops = {
static int eusb2_repeater_probe(struct platform_device *pdev)
{
+ struct regmap_config eusb2_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x100,
+ .fast_io = true,
+ };
+ struct spmi_device *sparent;
struct eusb2_repeater *rptr;
+ struct spmi_subdevice *sub_sdev;
struct device *dev = &pdev->dev;
struct phy_provider *phy_provider;
struct device_node *np = dev->of_node;
- u32 res;
int ret;
+ if (!dev->parent)
+ return -ENODEV;
+
rptr = devm_kzalloc(dev, sizeof(*rptr), GFP_KERNEL);
if (!rptr)
return -ENOMEM;
@@ -260,15 +268,21 @@ static int eusb2_repeater_probe(struct platform_device *pdev)
if (!rptr->cfg)
return -EINVAL;
- rptr->regmap = dev_get_regmap(dev->parent, NULL);
- if (!rptr->regmap)
+ sparent = to_spmi_device(dev->parent);
+ if (!sparent)
return -ENODEV;
- ret = of_property_read_u32(np, "reg", &res);
+ sub_sdev = devm_spmi_subdevice_alloc_and_add(dev, sparent);
+ if (IS_ERR(sub_sdev))
+ return PTR_ERR(sub_sdev);
+
+ ret = of_property_read_u32(np, "reg", &eusb2_regmap_config.reg_base);
if (ret < 0)
return ret;
- rptr->base = res;
+ rptr->regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev, &eusb2_regmap_config);
+ if (IS_ERR(rptr->regmap))
+ return -ENODEV;
ret = eusb2_repeater_init_vregs(rptr);
if (ret < 0) {
@@ -335,3 +349,4 @@ module_platform_driver(eusb2_repeater_driver);
MODULE_DESCRIPTION("Qualcomm PMIC eUSB2 Repeater driver");
MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("SPMI");
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 ` [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: " AngeloGioacchino Del Regno
@ 2026-01-14 8:59 ` Andy Shevchenko
2026-01-14 9:26 ` AngeloGioacchino Del Regno
0 siblings, 1 reply; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 8:59 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Abel Vesa
On Wed, Jan 14, 2026 at 09:39:54AM +0100, AngeloGioacchino Del Regno wrote:
> Some Qualcomm PMICs integrate an USB Repeater device, used to
> convert between eUSB2 and USB 2.0 signaling levels, reachable
> in a specific address range over SPMI.
>
> Instead of using the parent SPMI device (the main PMIC) as a kind
> of syscon in this driver, register a new SPMI sub-device for EUSB2
> and initialize its own regmap with this sub-device's specific base
> address, retrieved from the devicetree.
>
> This allows to stop manually adding the register base address to
> every R/W call in this driver, as this can be, and is now, handled
> by the regmap API instead.
Same comments and actually one more.
...
> + struct regmap_config eusb2_regmap_config = {
> + .reg_bits = 16,
> + .val_bits = 8,
> + .max_register = 0x100,
> + .fast_io = true,
> + };
This is third time of the same. Make it part of SPMI core and export to
the users. Or are they semantically different like different slices?
In that case you can export it under generic name like
spmi_default_slice_regmap_config
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:59 ` Andy Shevchenko
@ 2026-01-14 9:26 ` AngeloGioacchino Del Regno
2026-01-14 9:40 ` Andy Shevchenko
0 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 9:26 UTC (permalink / raw)
To: Andy Shevchenko
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Abel Vesa
Il 14/01/26 09:59, Andy Shevchenko ha scritto:
> On Wed, Jan 14, 2026 at 09:39:54AM +0100, AngeloGioacchino Del Regno wrote:
>> Some Qualcomm PMICs integrate an USB Repeater device, used to
>> convert between eUSB2 and USB 2.0 signaling levels, reachable
>> in a specific address range over SPMI.
>>
>> Instead of using the parent SPMI device (the main PMIC) as a kind
>> of syscon in this driver, register a new SPMI sub-device for EUSB2
>> and initialize its own regmap with this sub-device's specific base
>> address, retrieved from the devicetree.
>>
>> This allows to stop manually adding the register base address to
>> every R/W call in this driver, as this can be, and is now, handled
>> by the regmap API instead.
>
> Same comments and actually one more.
>
> ...
>
>> + struct regmap_config eusb2_regmap_config = {
>> + .reg_bits = 16,
>> + .val_bits = 8,
>> + .max_register = 0x100,
>> + .fast_io = true,
>> + };
>
> This is third time of the same. Make it part of SPMI core and export to
> the users. Or are they semantically different like different slices?
> In that case you can export it under generic name like
>
> spmi_default_slice_regmap_config
>
There are more complicated devices around that I didn't port to the new
spmi subdevices, and I really don't want to make a default for now.
At least some of those need different params (including some MediaTek ones
that are not upstream yet).
Can we please let this in and *then* see how much can be commonized after
the majority of more complicated drivers are migrated in the future?
Regards,
Angelo
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 9:26 ` AngeloGioacchino Del Regno
@ 2026-01-14 9:40 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:40 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Abel Vesa
On Wed, Jan 14, 2026 at 10:26:42AM +0100, AngeloGioacchino Del Regno wrote:
> Il 14/01/26 09:59, Andy Shevchenko ha scritto:
> > On Wed, Jan 14, 2026 at 09:39:54AM +0100, AngeloGioacchino Del Regno wrote:
...
> > > + struct regmap_config eusb2_regmap_config = {
> > > + .reg_bits = 16,
> > > + .val_bits = 8,
> > > + .max_register = 0x100,
> > > + .fast_io = true,
> > > + };
> >
> > This is third time of the same. Make it part of SPMI core and export to
> > the users. Or are they semantically different like different slices?
> > In that case you can export it under generic name like
> >
> > spmi_default_slice_regmap_config
>
> There are more complicated devices around that I didn't port to the new
> spmi subdevices, and I really don't want to make a default for now.
>
> At least some of those need different params (including some MediaTek ones
> that are not upstream yet).
>
> Can we please let this in and *then* see how much can be commonized after
> the majority of more complicated drivers are migrated in the future?
Sure, but it looks like a pattern currently...
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 08/10] misc: qcom-coincell: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (6 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 07/10] phy: qualcomm: eusb2-repeater: " AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 09/10] iio: adc: qcom-spmi-iadc: " AngeloGioacchino Del Regno
2026-01-14 8:39 ` [PATCH v7 10/10] iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions AngeloGioacchino Del Regno
9 siblings, 0 replies; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel
Some Qualcomm PMICs integrate a charger for coincells, usually
powering an RTC when external (or main battery) power is missing.
Instead of using the parent SPMI device (the main PMIC) as a kind
of syscon in this driver, register a new SPMI sub-device and
initialize its own regmap with this sub-device's specific base
address, retrieved from the devicetree.
This allows to stop manually adding the register base address to
every R/W call in this driver, as this can be, and is now, handled
by the regmap API instead.
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/misc/Kconfig | 2 ++
drivers/misc/qcom-coincell.c | 38 +++++++++++++++++++++++++-----------
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index d7d41b054b98..bd4fe4ec893c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -290,6 +290,8 @@ config HP_ILO
config QCOM_COINCELL
tristate "Qualcomm coincell charger support"
depends on MFD_SPMI_PMIC || COMPILE_TEST
+ depends on SPMI
+ select REGMAP_SPMI
help
This driver supports the coincell block found inside of
Qualcomm PMICs. The coincell charger provides a means to
diff --git a/drivers/misc/qcom-coincell.c b/drivers/misc/qcom-coincell.c
index 3c57f7429147..49e38442b289 100644
--- a/drivers/misc/qcom-coincell.c
+++ b/drivers/misc/qcom-coincell.c
@@ -9,11 +9,11 @@
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/platform_device.h>
+#include <linux/spmi.h>
struct qcom_coincell {
struct device *dev;
struct regmap *regmap;
- u32 base_addr;
};
#define QCOM_COINCELL_REG_RSET 0x44
@@ -35,7 +35,7 @@ static int qcom_coincell_chgr_config(struct qcom_coincell *chgr, int rset,
/* if disabling, just do that and skip other operations */
if (!enable)
return regmap_write(chgr->regmap,
- chgr->base_addr + QCOM_COINCELL_REG_ENABLE, 0);
+ QCOM_COINCELL_REG_ENABLE, 0);
/* find index for current-limiting resistor */
for (i = 0; i < ARRAY_SIZE(qcom_rset_map); i++)
@@ -58,7 +58,7 @@ static int qcom_coincell_chgr_config(struct qcom_coincell *chgr, int rset,
}
rc = regmap_write(chgr->regmap,
- chgr->base_addr + QCOM_COINCELL_REG_RSET, i);
+ QCOM_COINCELL_REG_RSET, i);
if (rc) {
/*
* This is mainly to flag a bad base_addr (reg) from dts.
@@ -71,19 +71,28 @@ static int qcom_coincell_chgr_config(struct qcom_coincell *chgr, int rset,
}
rc = regmap_write(chgr->regmap,
- chgr->base_addr + QCOM_COINCELL_REG_VSET, j);
+ QCOM_COINCELL_REG_VSET, j);
if (rc)
return rc;
/* set 'enable' register */
return regmap_write(chgr->regmap,
- chgr->base_addr + QCOM_COINCELL_REG_ENABLE,
+ QCOM_COINCELL_REG_ENABLE,
QCOM_COINCELL_ENABLE);
}
static int qcom_coincell_probe(struct platform_device *pdev)
{
- struct device_node *node = pdev->dev.of_node;
+ struct regmap_config qcom_coincell_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x100,
+ .fast_io = true,
+ };
+ struct device *dev = &pdev->dev;
+ struct device_node *node = dev->of_node;
+ struct spmi_subdevice *sub_sdev;
+ struct spmi_device *sparent;
struct qcom_coincell chgr;
u32 rset = 0;
u32 vset = 0;
@@ -92,16 +101,22 @@ static int qcom_coincell_probe(struct platform_device *pdev)
chgr.dev = &pdev->dev;
- chgr.regmap = dev_get_regmap(pdev->dev.parent, NULL);
+ rc = of_property_read_u32(node, "reg", &qcom_coincell_regmap_config.reg_base);
+ if (rc)
+ return rc;
+
+ sparent = to_spmi_device(dev->parent);
+ sub_sdev = devm_spmi_subdevice_alloc_and_add(dev, sparent);
+ if (IS_ERR(sub_sdev))
+ return PTR_ERR(sub_sdev);
+
+ chgr.regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev,
+ &qcom_coincell_regmap_config);
if (!chgr.regmap) {
dev_err(chgr.dev, "Unable to get regmap\n");
return -EINVAL;
}
- rc = of_property_read_u32(node, "reg", &chgr.base_addr);
- if (rc)
- return rc;
-
enable = !of_property_read_bool(node, "qcom,charger-disable");
if (enable) {
@@ -142,3 +157,4 @@ module_platform_driver(qcom_coincell_driver);
MODULE_DESCRIPTION("Qualcomm PMIC coincell charger driver");
MODULE_LICENSE("GPL v2");
+MODULE_IMPORT_NS("SPMI");
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v7 09/10] iio: adc: qcom-spmi-iadc: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (7 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 08/10] misc: qcom-coincell: " AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 9:05 ` Andy Shevchenko
2026-01-14 8:39 ` [PATCH v7 10/10] iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions AngeloGioacchino Del Regno
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel, Jonathan Cameron
Some Qualcomm PMICs integrate an Current ADC device, reachable
in a specific address range over SPMI.
Instead of using the parent SPMI device (the main PMIC) as a kind
of syscon in this driver, register a new SPMI sub-device and
initialize its own regmap with this sub-device's specific base
address, retrieved from the devicetree.
This allows to stop manually adding the register base address to
every R/W call in this driver, as this can be, and is now, handled
by the regmap API instead.
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/iio/adc/qcom-spmi-iadc.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c
index b64a8a407168..67096952b229 100644
--- a/drivers/iio/adc/qcom-spmi-iadc.c
+++ b/drivers/iio/adc/qcom-spmi-iadc.c
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
+#include <linux/spmi.h>
/* IADC register and bit definition */
#define IADC_REVISION2 0x1
@@ -94,7 +95,6 @@
* struct iadc_chip - IADC Current ADC device structure.
* @regmap: regmap for register read/write.
* @dev: This device pointer.
- * @base: base offset for the ADC peripheral.
* @rsense: Values of the internal and external sense resister in micro Ohms.
* @poll_eoc: Poll for end of conversion instead of waiting for IRQ.
* @offset: Raw offset values for the internal and external channels.
@@ -105,7 +105,6 @@
struct iadc_chip {
struct regmap *regmap;
struct device *dev;
- u16 base;
bool poll_eoc;
u32 rsense[2];
u16 offset[2];
@@ -119,7 +118,7 @@ static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data)
unsigned int val;
int ret;
- ret = regmap_read(iadc->regmap, iadc->base + offset, &val);
+ ret = regmap_read(iadc->regmap, offset, &val);
if (ret < 0)
return ret;
@@ -129,7 +128,7 @@ static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data)
static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data)
{
- return regmap_write(iadc->regmap, iadc->base + offset, data);
+ return regmap_write(iadc->regmap, offset, data);
}
static int iadc_reset(struct iadc_chip *iadc)
@@ -270,7 +269,7 @@ static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us)
static int iadc_read_result(struct iadc_chip *iadc, u16 *data)
{
- return regmap_bulk_read(iadc->regmap, iadc->base + IADC_DATA, data, 2);
+ return regmap_bulk_read(iadc->regmap, IADC_DATA, data, 2);
}
static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data)
@@ -483,12 +482,19 @@ static const struct iio_chan_spec iadc_channels[] = {
static int iadc_probe(struct platform_device *pdev)
{
+ struct regmap_config iadc_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .max_register = 0x100,
+ .fast_io = true,
+ };
struct device_node *node = pdev->dev.of_node;
struct device *dev = &pdev->dev;
+ struct spmi_subdevice *sub_sdev;
+ struct spmi_device *sparent;
struct iio_dev *indio_dev;
struct iadc_chip *iadc;
int ret, irq_eoc;
- u32 res;
indio_dev = devm_iio_device_alloc(dev, sizeof(*iadc));
if (!indio_dev)
@@ -497,18 +503,21 @@ static int iadc_probe(struct platform_device *pdev)
iadc = iio_priv(indio_dev);
iadc->dev = dev;
- iadc->regmap = dev_get_regmap(dev->parent, NULL);
- if (!iadc->regmap)
- return -ENODEV;
+ sparent = to_spmi_device(dev->parent);
+ sub_sdev = devm_spmi_subdevice_alloc_and_add(dev, sparent);
+ if (IS_ERR(sub_sdev))
+ return PTR_ERR(sub_sdev);
init_completion(&iadc->complete);
mutex_init(&iadc->lock);
- ret = of_property_read_u32(node, "reg", &res);
+ ret = of_property_read_u32(node, "reg", &iadc_regmap_config.reg_base);
if (ret < 0)
return -ENODEV;
- iadc->base = res;
+ iadc->regmap = devm_regmap_init_spmi_ext(&sub_sdev->sdev, &iadc_regmap_config);
+ if (IS_ERR(iadc->regmap))
+ return PTR_ERR(iadc->regmap);
ret = iadc_version_check(iadc);
if (ret < 0)
@@ -584,3 +593,4 @@ MODULE_ALIAS("platform:qcom-spmi-iadc");
MODULE_DESCRIPTION("Qualcomm SPMI PMIC current ADC driver");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Ivan T. Ivanov <iivanov@mm-sol.com>");
+MODULE_IMPORT_NS("SPMI");
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 09/10] iio: adc: qcom-spmi-iadc: Migrate to devm_spmi_subdevice_alloc_and_add()
2026-01-14 8:39 ` [PATCH v7 09/10] iio: adc: qcom-spmi-iadc: " AngeloGioacchino Del Regno
@ 2026-01-14 9:05 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:05 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Jonathan Cameron
On Wed, Jan 14, 2026 at 09:39:56AM +0100, AngeloGioacchino Del Regno wrote:
> Some Qualcomm PMICs integrate an Current ADC device, reachable
> in a specific address range over SPMI.
>
> Instead of using the parent SPMI device (the main PMIC) as a kind
> of syscon in this driver, register a new SPMI sub-device and
> initialize its own regmap with this sub-device's specific base
> address, retrieved from the devicetree.
>
> This allows to stop manually adding the register base address to
> every R/W call in this driver, as this can be, and is now, handled
> by the regmap API instead.
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
> Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
I see these tags, but just again pointing out that max_register in regmap !=
MAX! It's MAX - 1, i.e. the last *accessible* register. So, I find personally
weird the configurations which has 257 registers instead of 256.
This can be easily checked when dumping register contents via debugfs.
Plus the same comments applies here as I gave previously.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 10/10] iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions
2026-01-14 8:39 [PATCH RESEND v7 00/10] SPMI: Implement sub-devices and migrate drivers AngeloGioacchino Del Regno
` (8 preceding siblings ...)
2026-01-14 8:39 ` [PATCH v7 09/10] iio: adc: qcom-spmi-iadc: " AngeloGioacchino Del Regno
@ 2026-01-14 8:39 ` AngeloGioacchino Del Regno
2026-01-14 9:03 ` Andy Shevchenko
9 siblings, 1 reply; 32+ messages in thread
From: AngeloGioacchino Del Regno @ 2026-01-14 8:39 UTC (permalink / raw)
To: jic23
Cc: dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, angelogioacchino.delregno, krzk,
dmitry.baryshkov, quic_wcheng, melody.olvera, quic_nsekar,
ivo.ivanov.ivanov1, abelvesa, luca.weiss, konrad.dybcio,
mitltlatltl, krishna.kurapati, linux-arm-msm, linux-iio,
linux-kernel, linux-phy, linux-pm, kernel, Jonathan Cameron
This driver doesn't need to add any register base address to any
regmap call anymore since it was migrated to register as a SPMI
subdevice with its own regmap reg_base, which makes the regmap
API to automatically add such base address internally.
Since the iadc_{read,write,read_result}() functions now only do
call regmap_{read,write,bulk_read}() and nothing else, simplify
the driver by removing them and by calling regmap APIs directly.
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
drivers/iio/adc/qcom-spmi-iadc.c | 83 ++++++++++++--------------------
1 file changed, 30 insertions(+), 53 deletions(-)
diff --git a/drivers/iio/adc/qcom-spmi-iadc.c b/drivers/iio/adc/qcom-spmi-iadc.c
index 67096952b229..7d46ec2d1a30 100644
--- a/drivers/iio/adc/qcom-spmi-iadc.c
+++ b/drivers/iio/adc/qcom-spmi-iadc.c
@@ -113,77 +113,59 @@ struct iadc_chip {
struct completion complete;
};
-static int iadc_read(struct iadc_chip *iadc, u16 offset, u8 *data)
-{
- unsigned int val;
- int ret;
-
- ret = regmap_read(iadc->regmap, offset, &val);
- if (ret < 0)
- return ret;
-
- *data = val;
- return 0;
-}
-
-static int iadc_write(struct iadc_chip *iadc, u16 offset, u8 data)
-{
- return regmap_write(iadc->regmap, offset, data);
-}
-
static int iadc_reset(struct iadc_chip *iadc)
{
- u8 data;
+ u32 data;
int ret;
- ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
+ ret = regmap_write(iadc->regmap, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
if (ret < 0)
return ret;
- ret = iadc_read(iadc, IADC_PERH_RESET_CTL3, &data);
+ ret = regmap_read(iadc->regmap, IADC_PERH_RESET_CTL3, &data);
if (ret < 0)
return ret;
- ret = iadc_write(iadc, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
+ ret = regmap_write(iadc->regmap, IADC_SEC_ACCESS, IADC_SEC_ACCESS_DATA);
if (ret < 0)
return ret;
data |= IADC_FOLLOW_WARM_RB;
- return iadc_write(iadc, IADC_PERH_RESET_CTL3, data);
+ return regmap_write(iadc->regmap, IADC_PERH_RESET_CTL3, data);
}
static int iadc_set_state(struct iadc_chip *iadc, bool state)
{
- return iadc_write(iadc, IADC_EN_CTL1, state ? IADC_EN_CTL1_SET : 0);
+ return regmap_write(iadc->regmap, IADC_EN_CTL1, state ? IADC_EN_CTL1_SET : 0);
}
static void iadc_status_show(struct iadc_chip *iadc)
{
- u8 mode, sta1, chan, dig, en, req;
+ u32 mode, sta1, chan, dig, en, req;
int ret;
- ret = iadc_read(iadc, IADC_MODE_CTL, &mode);
+ ret = regmap_read(iadc->regmap, IADC_MODE_CTL, &mode);
if (ret < 0)
return;
- ret = iadc_read(iadc, IADC_DIG_PARAM, &dig);
+ ret = regmap_read(iadc->regmap, IADC_DIG_PARAM, &dig);
if (ret < 0)
return;
- ret = iadc_read(iadc, IADC_CH_SEL_CTL, &chan);
+ ret = regmap_read(iadc->regmap, IADC_CH_SEL_CTL, &chan);
if (ret < 0)
return;
- ret = iadc_read(iadc, IADC_CONV_REQ, &req);
+ ret = regmap_read(iadc->regmap, IADC_CONV_REQ, &req);
if (ret < 0)
return;
- ret = iadc_read(iadc, IADC_STATUS1, &sta1);
+ ret = regmap_read(iadc->regmap, IADC_STATUS1, &sta1);
if (ret < 0)
return;
- ret = iadc_read(iadc, IADC_EN_CTL1, &en);
+ ret = regmap_read(iadc->regmap, IADC_EN_CTL1, &en);
if (ret < 0)
return;
@@ -199,34 +181,34 @@ static int iadc_configure(struct iadc_chip *iadc, int channel)
/* Mode selection */
mode = (IADC_OP_MODE_NORMAL << IADC_OP_MODE_SHIFT) | IADC_TRIM_EN;
- ret = iadc_write(iadc, IADC_MODE_CTL, mode);
+ ret = regmap_write(iadc->regmap, IADC_MODE_CTL, mode);
if (ret < 0)
return ret;
/* Channel selection */
- ret = iadc_write(iadc, IADC_CH_SEL_CTL, channel);
+ ret = regmap_write(iadc->regmap, IADC_CH_SEL_CTL, channel);
if (ret < 0)
return ret;
/* Digital parameter setup */
decim = IADC_DEF_DECIMATION << IADC_DIG_DEC_RATIO_SEL_SHIFT;
- ret = iadc_write(iadc, IADC_DIG_PARAM, decim);
+ ret = regmap_write(iadc->regmap, IADC_DIG_PARAM, decim);
if (ret < 0)
return ret;
/* HW settle time delay */
- ret = iadc_write(iadc, IADC_HW_SETTLE_DELAY, IADC_DEF_HW_SETTLE_TIME);
+ ret = regmap_write(iadc->regmap, IADC_HW_SETTLE_DELAY, IADC_DEF_HW_SETTLE_TIME);
if (ret < 0)
return ret;
- ret = iadc_write(iadc, IADC_FAST_AVG_CTL, IADC_DEF_AVG_SAMPLES);
+ ret = regmap_write(iadc->regmap, IADC_FAST_AVG_CTL, IADC_DEF_AVG_SAMPLES);
if (ret < 0)
return ret;
if (IADC_DEF_AVG_SAMPLES)
- ret = iadc_write(iadc, IADC_FAST_AVG_EN, IADC_FAST_AVG_EN_SET);
+ ret = regmap_write(iadc->regmap, IADC_FAST_AVG_EN, IADC_FAST_AVG_EN_SET);
else
- ret = iadc_write(iadc, IADC_FAST_AVG_EN, 0);
+ ret = regmap_write(iadc->regmap, IADC_FAST_AVG_EN, 0);
if (ret < 0)
return ret;
@@ -239,19 +221,19 @@ static int iadc_configure(struct iadc_chip *iadc, int channel)
return ret;
/* Request conversion */
- return iadc_write(iadc, IADC_CONV_REQ, IADC_CONV_REQ_SET);
+ return regmap_write(iadc->regmap, IADC_CONV_REQ, IADC_CONV_REQ_SET);
}
static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us)
{
unsigned int count, retry;
int ret;
- u8 sta1;
+ u32 sta1;
retry = interval_us / IADC_CONV_TIME_MIN_US;
for (count = 0; count < retry; count++) {
- ret = iadc_read(iadc, IADC_STATUS1, &sta1);
+ ret = regmap_read(iadc->regmap, IADC_STATUS1, &sta1);
if (ret < 0)
return ret;
@@ -267,11 +249,6 @@ static int iadc_poll_wait_eoc(struct iadc_chip *iadc, unsigned int interval_us)
return -ETIMEDOUT;
}
-static int iadc_read_result(struct iadc_chip *iadc, u16 *data)
-{
- return regmap_bulk_read(iadc->regmap, IADC_DATA, data, 2);
-}
-
static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data)
{
unsigned int wait;
@@ -296,7 +273,7 @@ static int iadc_do_conversion(struct iadc_chip *iadc, int chan, u16 *data)
}
if (!ret)
- ret = iadc_read_result(iadc, data);
+ ret = regmap_bulk_read(iadc->regmap, IADC_DATA, data, sizeof(*data));
exit:
iadc_set_state(iadc, false);
if (ret < 0)
@@ -392,10 +369,10 @@ static int iadc_update_offset(struct iadc_chip *iadc)
static int iadc_version_check(struct iadc_chip *iadc)
{
- u8 val;
+ u32 val;
int ret;
- ret = iadc_read(iadc, IADC_PERPH_TYPE, &val);
+ ret = regmap_read(iadc->regmap, IADC_PERPH_TYPE, &val);
if (ret < 0)
return ret;
@@ -404,7 +381,7 @@ static int iadc_version_check(struct iadc_chip *iadc)
return -EINVAL;
}
- ret = iadc_read(iadc, IADC_PERPH_SUBTYPE, &val);
+ ret = regmap_read(iadc->regmap, IADC_PERPH_SUBTYPE, &val);
if (ret < 0)
return ret;
@@ -413,7 +390,7 @@ static int iadc_version_check(struct iadc_chip *iadc)
return -EINVAL;
}
- ret = iadc_read(iadc, IADC_REVISION2, &val);
+ ret = regmap_read(iadc->regmap, IADC_REVISION2, &val);
if (ret < 0)
return ret;
@@ -428,7 +405,7 @@ static int iadc_version_check(struct iadc_chip *iadc)
static int iadc_rsense_read(struct iadc_chip *iadc, struct device_node *node)
{
int ret, sign, int_sense;
- u8 deviation;
+ u32 deviation;
ret = of_property_read_u32(node, "qcom,external-resistor-micro-ohms",
&iadc->rsense[IADC_EXT_RSENSE]);
@@ -440,7 +417,7 @@ static int iadc_rsense_read(struct iadc_chip *iadc, struct device_node *node)
return -EINVAL;
}
- ret = iadc_read(iadc, IADC_NOMINAL_RSENSE, &deviation);
+ ret = regmap_read(iadc->regmap, IADC_NOMINAL_RSENSE, &deviation);
if (ret < 0)
return ret;
--
2.52.0
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 10/10] iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions
2026-01-14 8:39 ` [PATCH v7 10/10] iio: adc: qcom-spmi-iadc: Remove regmap R/W wrapper functions AngeloGioacchino Del Regno
@ 2026-01-14 9:03 ` Andy Shevchenko
0 siblings, 0 replies; 32+ messages in thread
From: Andy Shevchenko @ 2026-01-14 9:03 UTC (permalink / raw)
To: AngeloGioacchino Del Regno
Cc: jic23, dlechner, nuno.sa, andy, arnd, gregkh, srini, vkoul,
neil.armstrong, sre, sboyd, krzk, dmitry.baryshkov, quic_wcheng,
melody.olvera, quic_nsekar, ivo.ivanov.ivanov1, abelvesa,
luca.weiss, konrad.dybcio, mitltlatltl, krishna.kurapati,
linux-arm-msm, linux-iio, linux-kernel, linux-phy, linux-pm,
kernel, Jonathan Cameron
On Wed, Jan 14, 2026 at 09:39:57AM +0100, AngeloGioacchino Del Regno wrote:
> This driver doesn't need to add any register base address to any
> regmap call anymore since it was migrated to register as a SPMI
> subdevice with its own regmap reg_base, which makes the regmap
> API to automatically add such base address internally.
>
> Since the iadc_{read,write,read_result}() functions now only do
> call regmap_{read,write,bulk_read}() and nothing else, simplify
> the driver by removing them and by calling regmap APIs directly.
...
> {
> unsigned int count, retry;
> int ret;
> - u8 sta1;
> + u32 sta1;
Keep it in reversed xmas tree order.
> retry = interval_us / IADC_CONV_TIME_MIN_US;
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 32+ messages in thread