* Re: [PATCH 0/4] ASoC: Add support for GPIOs driven amplifiers
From: Mark Brown @ 2026-03-30 15:48 UTC (permalink / raw)
To: Herve Codina
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Saravana Kannan, Jaroslav Kysela, Takashi Iwai, linux-sound,
devicetree, linux-kernel, Christophe Leroy, Thomas Petazzoni
In-Reply-To: <20260330173944.3fdc27ec@bootlin.com>
[-- Attachment #1: Type: text/plain, Size: 590 bytes --]
On Mon, Mar 30, 2026 at 05:39:44PM +0200, Herve Codina wrote:
> Mark Brown <broonie@kernel.org> wrote:
> > This sounds a lot like simple-amplifier.c?
> The gpio driven amplifier proposed is more generic and can handle
> more complex design. I.e. op-amp + resistor and/or line (mute,
> bypass) switching. Hardwares handled by this driver are a superset
> of just dio2125 and so simple-amplifier.c.
> IMHO, it makes sense to have a specific driver for those kind
> of hardware design.
Right, and if it's a superset it feels like it should all be one driver
rather than two separate ones.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH 7/8] drm/bridge: imx8mp-hdmi-tx: add an hdmi-connector when missing using a DT overlay at boot time
From: Luca Ceresoli @ 2026-03-30 15:47 UTC (permalink / raw)
To: Liu Ying, Marek Vasut, Stefan Agner, Maarten Lankhorst,
Maxime Ripard, Thomas Zimmermann, David Airlie, Simona Vetter,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Andrzej Hajda, Neil Armstrong, Robert Foss, Laurent Pinchart,
Jonas Karlman, Jernej Skrabec, Rob Herring, Saravana Kannan
Cc: Kory Maincent (TI.com), Hervé Codina, Hui Pu, Ian Ray,
Thomas Petazzoni, dri-devel, imx, linux-arm-kernel, linux-kernel,
devicetree, Adam Ford, Alexander Stein, Anson Huang,
Christopher Obbard, Daniel Scally, Emanuele Ghidoli,
Fabio Estevam, Francesco Dolcini, Frieder Schrempf, Gilles Talis,
Goran Rađenović, Heiko Schocher, Joao Paulo Goncalves,
Josua Mayer, Kieran Bingham, Marco Felsch, Martyn Welch,
Oleksij Rempel, Peng Fan, Philippe Schenker, Richard Hu,
Shengjiu Wang, Stefan Eichenberger, Vitor Soares
In-Reply-To: <5f06ea5a-5388-440f-91d6-cebb0bee0a88@nxp.com>
Hello Liu,
On Mon Mar 30, 2026 at 5:02 AM CEST, Liu Ying wrote:
>>>> --- a/drivers/gpu/drm/bridge/imx/Kconfig
>>>> +++ b/drivers/gpu/drm/bridge/imx/Kconfig
>>>> @@ -25,6 +25,23 @@ config DRM_IMX8MP_DW_HDMI_BRIDGE
>>>> Choose this to enable support for the internal HDMI encoder found
>>>> on the i.MX8MP SoC.
>>>>
>>>> +config DRM_IMX8MP_DW_HDMI_BRIDGE_CONNECTOR_FIXUP
>>>> + bool "Support device tree blobs without an hdmi-connector node"
>>>> + default y
>>>
>>> depends on DRM_IMX_LCDIF ?
>>
>> If the imx hdmi-tx is not enabled then HDMI won't work anyway, so users are
>> not affected and the overlay is not needed. Am I missing something?
>
> I meant I'm fine with "default y" and think that this could also depend on
> DRM_IMX_LCDIF, because no display controller driver other than the LCDIF
> driver needs the fixup.
Ah, I see your point. OK, I'll add 'depends on DRM_IMX_LCDIF'.
>>> I see build warnings(W=1):
>>> drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx-connector-fixup.dtso:25.8-37.4: Warning (unit_address_vs_reg): /fragment@0/__overlay__/soc@0: node has a unit name, but no reg or ranges property
>>> drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx-connector-fixup.dtso:26.16-36.5: Warning (unit_address_vs_reg): /fragment@0/__overlay__/soc@0/bus@32c00000: node has a unit name, but no reg or ranges property
>>> drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx-connector-fixup.dtso:27.18-35.6: Warning (unit_address_vs_reg): /fragment@0/__overlay__/soc@0/bus@32c00000/hdmi@32fd8000: node has a unit name, but no reg or ranges property
>>> drivers/gpu/drm/bridge/imx/imx8mp-hdmi-tx-connector-fixup.dtso:29.13-33.8: Warning (unit_address_vs_reg): /fragment@0/__overlay__/soc@0/bus@32c00000/hdmi@32fd8000/ports/port@1: node has a unit name, but no reg or ranges property
>>
>> AFAIK the device tree checkes just can't work on overlays. The tools just
>> cannot know on which base tree the overlay can be applied, so they cannot
>> know the existing properties. That might change in the future, but for now
>> my understanding is that it is OK to have overlays which produce such
>> harmless warnings, at least for driver-specific overlays like the tilcdc
>> one [0] which is already in linux-next since a few weeks.
>
> Hmm, not sure a few weeks in linux-next is long enough ;)
> I'd say, I saw the warnings, so simply reported along with a fix to suppress
> them. TBH, build warnings make me nervous, especially this DT overlay is
> under the "DRM DRIVERS FOR FREESCALE IMX BRIDGE" umbrella.
That's fine, I'll add the lines needed to suppress the warnings then.
>>>> + fixup-hdmi-connector {
>>>> + compatible = "hdmi-connector";
>>>> + label = "HDMI";
>>>> + type = "a";
>>>
>>> What if a board uses another type?
>>
>> For boards affected by this patch, currently the connector is created by
>> dw_hdmi_connector_create() which hardcodes type A [0], so there would be no
>> difference.
>
> Yes, that's from driver's PoV. However, userspace may get the type
> from /sys/firmware/devicetree/base/fixup-hdmi-connector/type and use it
> to do something.
I'd say this is incorrect, the device tree is not an API for that. The
connector type might be known to the driver by other means (ACPI, DP MST,
whatever). So I think this is a non-problem.
If userspace needs to know the connector type, that should come from the
ioctl (DRM_IOCTL_MODE_GETCONNECTOR perhaps).
> Maybe, that's trivial.
Not sure I got what you mean here, sorry. What are you referring to?
>> OTOH how can a common module know the specific connector?
>
> Hmm, maybe add a module parameter or let users set the type through Kconfig
I'm afraid none of this would work for distribution kernels, where who
configures the distribution has no idea on how many different hardware it
will run.
> or even define an unknown type to honestly tell users that we don't know it?
This sounds like a potentially valid idea, even though I'm not fully
convinced. Also I suspect it would be a pretty large change, and also
adding "unknown type" in the device tree seems not compliant with the rule
that DT describes the hardware (not the lack of info about the hardware).
But definitely it's not needed for this specific case, because:
* with current code, every imx8mp-hdmi-tx usage adds a type-A connector [0]
* with this patch the correct type will be created when described in DT,
and type-A will be used only as a fallback when the DT is lacking
So after the patch we'd do sometimes better, never worse in this respect.
Based on the above I'm sending v2 soon, but don't hesitate in following up
in case I may be missing something (this topic is tricky).
[0] https://elixir.bootlin.com/linux/v7.0-rc5/source/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c#L2601
>> Boards with a different connector should describe the connector in the
>> device tree, if they need to instantiate the exact type.
I think this is the only valid solution. It's very easy to do, nothing new
to invent.
Maybe on top of that we could add a warning when the overlay is applied,
e.g. "imx8mp-hdmi-tx used without a connector described in device tree;
adding a type A connector as a fallback; please add a valid description to
your device tree". Maybe pointing to a TODO entry in the documentation.
What do you think about this?
Thanks again for your careful review!
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH v8 2/3] hwmon: ltc4283: Add support for the LTC4283 Swap Controller
From: Guenter Roeck @ 2026-03-30 15:47 UTC (permalink / raw)
To: Nuno Sá, Nuno Sá
Cc: linux-gpio, linux-hwmon, devicetree, linux-doc, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet, Linus Walleij,
Bartosz Golaszewski
In-Reply-To: <aco5L_6SZIB2DdpF@nsa>
On 3/30/26 02:28, Nuno Sá wrote:
> Hi Guenter, Regarding AI review, I think most of the points were
> discussed in previous revisions, but there are two valid.
>
> On Fri, Mar 27, 2026 at 05:26:15PM +0000, Nuno Sá wrote:
>> Support the LTC4283 Hot Swap Controller. The device features programmable
>> current limit with foldback and independently adjustable inrush current to
>> optimize the MOSFET safe operating area (SOA). The SOA timer limits MOSFET
>> temperature rise for reliable protection against overstresses.
>>
>> An I2C interface and onboard ADC allow monitoring of board current,
>> voltage, power, energy, and fault status.
>>
>> Signed-off-by: Nuno Sá <nuno.sa@analog.com>
>> ---
>> Documentation/hwmon/index.rst | 1 +
>> Documentation/hwmon/ltc4283.rst | 266 ++++++
>> MAINTAINERS | 1 +
>> drivers/hwmon/Kconfig | 12 +
>> drivers/hwmon/Makefile | 1 +
>> drivers/hwmon/ltc4283.c | 1796 +++++++++++++++++++++++++++++++++++++++
>> 6 files changed, 2077 insertions(+)
>>
>
> ...
>
>> +static int ltc4283_read_in_alarm(struct ltc4283_hwmon *st, u32 channel,
>> + bool max_alm, long *val)
>> +{
>> + if (channel == LTC4283_VPWR)
>> + return ltc4283_read_alarm(st, LTC4283_ADC_ALM_LOG_1,
>> + BIT(2 + max_alm), val);
>> +
>> + if (channel >= LTC4283_CHAN_ADI_1 && channel <= LTC4283_CHAN_ADI_4) {
>> + u32 bit = (channel - LTC4283_CHAN_ADI_1) * 2;
>> + /*
>> + * Lower channels go to higher bits. We also want to go +1 down
>> + * in the min_alarm case.
>> + */
>> + return ltc4283_read_alarm(st, LTC4283_ADC_ALM_LOG_2,
>> + BIT(7 - bit - !max_alm), val);
>> + }
>> +
>> + if (channel >= LTC4283_CHAN_ADIO_1 && channel <= LTC4283_CHAN_ADIO_4) {
>> + u32 bit = (channel - LTC4283_CHAN_ADIO_1) * 2;
>> +
>> + return ltc4283_read_alarm(st, LTC4283_ADC_ALM_LOG_3,
>> + BIT(7 - bit - !max_alm), val);
>> + }
>> +
>> + if (channel >= LTC4283_CHAN_ADIN12 && channel <= LTC4283_CHAN_ADIN34) {
>> + u32 bit = (channel - LTC4283_CHAN_ADIN12) * 2;
>> +
>> + return ltc4283_read_alarm(st, LTC4283_ADC_ALM_LOG_5,
>> + BIT(7 - bit - !max_alm), val);
>> + }
>
> "Will this condition handle the ADIO12 and ADIO34 differential channels?
> It looks like channels 14 and 15 fall through to the default return intended
> for the DRAIN channel. Since reading the alarm implicitly clears the register
> bits, could reading these ADIO alarms unintentionally clear actual DRAIN
> alarms? Should the upper bound be LTC4283_CHAN_ADIO34?"
>
> Good catch and should be:
>
> - if (channel >= LTC4283_CHAN_ADIN12 && channel <= LTC4283_CHAN_ADIN34) {
> + if (channel >= LTC4283_CHAN_ADIN12 && channel <= LTC4283_CHAN_ADIO34) {
>
>> +
>> + if (channel == LTC4283_CHAN_DRNS)
>> + return ltc4283_read_alarm(st, LTC4283_ADC_ALM_LOG_4,
>> + BIT(6 + max_alm), val);
>> +
>> + return ltc4283_read_alarm(st, LTC4283_ADC_ALM_LOG_4, BIT(4 + max_alm),
>> + val);
>> +}
>
> ...
>
>> +
>> +static int ltc4283_probe(struct i2c_client *client)
>> +{
>> + struct device *dev = &client->dev, *hwmon;
>> + struct auxiliary_device *adev;
>> + struct ltc4283_hwmon *st;
>> + int ret;
>> +
>> + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL);
>> + if (!st)
>> + return -ENOMEM;
>> +
>> + if (!i2c_check_functionality(client->adapter,
>> + I2C_FUNC_SMBUS_BYTE_DATA |
>> + I2C_FUNC_SMBUS_WORD_DATA |
>> + I2C_FUNC_SMBUS_READ_I2C_BLOCK))
>> + return -EOPNOTSUPP;
>> +
>> + st->client = client;
>> + st->map = devm_regmap_init(dev, <c4283_regmap_bus, client,
>> + <c4283_regmap_config);
>> + if (IS_ERR(st->map))
>> + return dev_err_probe(dev, PTR_ERR(st->map),
>> + "Failed to create regmap\n");
>> +
>> + ret = ltc4283_setup(st, dev);
>> + if (ret)
>> + return ret;
>> +
>> + hwmon = devm_hwmon_device_register_with_info(dev, "ltc4283", st,
>> + <c4283_chip_info, NULL);
>> +
>> + if (IS_ERR(hwmon))
>> + return PTR_ERR(hwmon);
>> +
>> + ltc4283_debugfs_init(st, client);
>> +
>> + if (!st->gpio_mask)
>> + return 0;
>> +
>> + adev = devm_auxiliary_device_create(dev, "gpio", &st->gpio_mask);
>> + if (!adev)
>> + return dev_err_probe(dev, -ENODEV, "Failed to add GPIO device\n");
>
> "Does this allow multiple LTC4283 chips to probe successfully?
> Without allocating a unique ID per I2C instance, it seems the first probed
> chip takes the generic name. If a second chip is present, it might attempt
> to register with the exact same name, resulting in a failure in device_add()
> and aborting the probe."
>
> Also looks valid and I suspect is one of those that a quick look will
> find more "offenders". I would purpose:
>
> - adev = devm_auxiliary_device_create(dev, "gpio", &st->gpio_mask);
> + adev = __devm_auxiliary_device_create(dev, KBUILD_MODNAME, "gpio",
> + &st->gpio_mask, client->addr);
>
That would still fail if there are multiple chips at the same I2C address
on multiple I2C busses. Check drivers/gpu/drm/bridge/ti-sn65dsi86.c which has
the same problem.
> If there's nothing else and you agree with the above, is this something
> you can tweak while applying or should I spin a new version?
>
Please respin. Also, regarding the other concerns:
Can BIT(8) * st->rsense wrap to zero on 32-bit architectures?
BIT(8) is a 32-bit unsigned long and st->rsense is a u32. If a user sets a
very large sense resistor value via the device tree, the multiplication could
wrap to 0, causing a division-by-zero kernel panic. Should the divisor use
BIT_ULL(8)?
Unless I am missing something, this _can_ overflow. Try to provide a sense
resistor value of 1677721600. Yes, it is unreasonable to specify such large
rsense values, but why not just limit it such that it does not overflow ?
Also, for the overflow concerns, if you are sure they can not happen, I'll
really need to write the unit test code to make sure that this is indeed
the case.
Thanks,
Guenter
^ permalink raw reply
* Re: [PATCH V2 1/5] dmaengine: xilinx_dma: Fix MCDMA descriptor fields for MM2S vs S2MM
From: Frank Li @ 2026-03-30 15:46 UTC (permalink / raw)
To: Srinivas Neeli
Cc: Vinod Koul, git, Frank Li, Michal Simek, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Suraj Gupta,
Radhey Shyam Pandey, Thomas Gessler, Folker Schwesinger,
Tomi Valkeinen, Kees Cook, Abin Joseph, dmaengine, devicetree,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260313062533.421249-2-srinivas.neeli@amd.com>
On Fri, Mar 13, 2026 at 11:55:29AM +0530, Srinivas Neeli wrote:
> The MCDMA BD format differs between MM2S and S2MM directions, but the
Can you use DMA_DEV_TO_MEM and DMA_MEM_TO_DEV instead of MM2S and S2MM?
or memory to slave, at least first place need extend term MM2S(memory to
slave).
> driver was using generic 'status' and 'sideband_status' fields for both.
> This could lead to incorrect residue calculations when the hardware
> updates direction-specific fields.
driver was using generic 'status' and 'sideband_status' fields for both,
which lead ... (use Affirmative Tone)
>
> Refactor the descriptor structure to use unions with direction-specific
> field names (mm2s_status/s2mm_status, etc.). This ensures the driver
Ensure .. (needn't this)
Frank
> accesses the correct hardware fields based on channel direction and
> matches the hardware documentation.
>
> Fixes: 6ccd692bfb7f ("dmaengine: xilinx_dma: Add Xilinx AXI MCDMA Engine driver support")
> Signed-off-by: Srinivas Neeli <srinivas.neeli@amd.com>
> ---
> drivers/dma/xilinx/xilinx_dma.c | 29 ++++++++++++++++++++++-------
> 1 file changed, 22 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index b53292e02448..4a83492f2435 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -275,8 +275,10 @@ struct xilinx_axidma_desc_hw {
> * @buf_addr_msb: MSB of Buffer address @0x0C
> * @rsvd: Reserved field @0x10
> * @control: Control Information field @0x14
> - * @status: Status field @0x18
> - * @sideband_status: Status of sideband signals @0x1C
> + * @mm2s_ctrl_sideband: Sideband control info for mm2s @0x18
> + * @s2mm_status: Status field for s2mm @0x18
> + * @mm2s_status: Status field for mm2s @0x1C
> + * @s2mm_sideband_status: Sideband status for s2mm @0x1C
> * @app: APP Fields @0x20 - 0x30
> */
> struct xilinx_aximcdma_desc_hw {
> @@ -286,8 +288,14 @@ struct xilinx_aximcdma_desc_hw {
> u32 buf_addr_msb;
> u32 rsvd;
> u32 control;
> - u32 status;
> - u32 sideband_status;
> + union {
> + u32 mm2s_ctrl_sideband;
> + u32 s2mm_status;
> + };
> + union {
> + u32 mm2s_status;
> + u32 s2mm_sideband_status;
> + };
> u32 app[XILINX_DMA_NUM_APP_WORDS];
> } __aligned(64);
>
> @@ -1013,9 +1021,16 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan,
> struct xilinx_aximcdma_tx_segment,
> node);
> aximcdma_hw = &aximcdma_seg->hw;
> - residue +=
> - (aximcdma_hw->control - aximcdma_hw->status) &
> - chan->xdev->max_buffer_len;
> + if (chan->direction == DMA_DEV_TO_MEM)
> + residue +=
> + (aximcdma_hw->control -
> + aximcdma_hw->s2mm_status) &
> + chan->xdev->max_buffer_len;
> + else
> + residue +=
> + (aximcdma_hw->control -
> + aximcdma_hw->mm2s_status) &
> + chan->xdev->max_buffer_len;
> }
> }
>
> --
> 2.43.0
>
^ permalink raw reply
* RE: [PATCH 07/22] ASoC: dt-bindings: renesas,rsnd: Add RZ/G3E support
From: John Madieu @ 2026-03-30 15:39 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Geert Uytterhoeven, Kuninori Morimoto, Vinod Koul, Mark Brown,
Rob Herring, Krzysztof Kozlowski, Michael Turquette, Stephen Boyd,
Conor Dooley, Frank Li, Liam Girdwood, magnus.damm,
Thomas Gleixner, Jaroslav Kysela, Takashi Iwai, Philipp Zabel,
Claudiu.Beznea, Biju Das, Fabrizio Castro, Prabhakar Mahadev Lad,
John Madieu, linux-renesas-soc@vger.kernel.org,
linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,
linux-sound@vger.kernel.org
In-Reply-To: <20260320-peculiar-cat-of-acumen-c6f6b3@quoll>
Hi Krzysztof,
Thanks for the review.
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: Friday, March 20, 2026 10:30 AM
> To: John Madieu <john.madieu.xa@bp.renesas.com>
> Subject: Re: [PATCH 07/22] ASoC: dt-bindings: renesas,rsnd: Add RZ/G3E
> support
>
> On Thu, Mar 19, 2026 at 04:53:19PM +0100, John Madieu wrote:
> > Add support for the RZ/G3E (R9A09G047) SoC audio subsystem.
> >
> > RZ/G3E has a different audio architecture from R-Car Gen2/Gen3/Gen4,
> > with additional clocks and resets:
> > - Per-SSI ADG clocks (adg.ssi.0-9)
> > - SCU related clocks (scu, scu_x2, scu_supply)
> > - SSIF supply clock
> > - AUDMAC peri-peri clock
> > - ADG clock
> > - Additional resets for SCU, ADG, and AUDMAC peri-peri
> >
> > RZ/G3E has 5 DMA controllers that can all be used by audio peripherals.
> > To allow the DMA core to distribute channels across all available
> > controllers, increase the maximum number of DMA entries in DVC, SRC,
> > and SSIU sub-nodes so that multiple providers can be listed with
> > repeated channel names.
> >
> > Signed-off-by: John Madieu <john.madieu.xa@bp.renesas.com>
> > ---
> > .../bindings/sound/renesas,rsnd.yaml | 169 +++++++++++++++---
> > 1 file changed, 148 insertions(+), 21 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > index e8a2acb92646..bc8885c4fa24 100644
> > --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.yaml
> > @@ -58,6 +58,7 @@ properties:
> > - renesas,rcar_sound-gen2
> > - renesas,rcar_sound-gen3
> > - renesas,rcar_sound-gen4
> > + - renesas,rcar_sound-r9a09g047 # RZ/G3E
>
> Do not use underscores in compatibles. Previously used wrong style is not
> the excuse here, just like previously poor code, mistakes, bugs,
> unreadable approches is not justification to repeat the same.
>
Got it.
> >
> > reg:
> > minItems: 1
> > @@ -97,20 +98,22 @@ properties:
> >
> > resets:
> > minItems: 1
> > - maxItems: 11
> > + maxItems: 14
> >
> > reset-names:
> > minItems: 1
> > - maxItems: 11
> > + maxItems: 14
> >
> > clocks:
> > description: References to SSI/SRC/MIX/CTU/DVC/AUDIO_CLK clocks.
> > minItems: 1
> > - maxItems: 31
> > + maxItems: 47
> >
> > clock-names:
> > description: List of necessary clock names.
> > # details are defined below
> > + minItems: 1
> > + maxItems: 47
> >
> > # ports is below
> > port:
> > @@ -136,9 +139,17 @@ properties:
> >
> > properties:
> > dmas:
> > - maxItems: 1
> > + description:
> > + Must contain unique DMA specifiers, one per available
> > + DMAC. On RZ/G3E, up to 5 for transmission.
> > + minItems: 1
> > + maxItems: 5
> > dma-names:
> > - const: tx
> > + minItems: 1
> > + maxItems: 5
> > + items:
> > + enum:
> > + - tx
>
> Multiple levels, multiple if:then: (further) - I don't find this binding
> manageable/readable. You should split it, with common binding defining
> common part of hardware or interface if there is such.
I as you suggested, I'll split it. Just to double check, should I fix
any bug found in there (like existing compatible strings having underscore
separators) ? Or should I just split and make sure only new SoC support is
bug free ?
Regards,
John
>
> Best regards,
> Krzysztof
^ permalink raw reply
* Re: [PATCH 0/4] ASoC: Add support for GPIOs driven amplifiers
From: Herve Codina @ 2026-03-30 15:39 UTC (permalink / raw)
To: Mark Brown
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Saravana Kannan, Jaroslav Kysela, Takashi Iwai, linux-sound,
devicetree, linux-kernel, Christophe Leroy, Thomas Petazzoni
In-Reply-To: <4daaa17d-5673-4efa-92ce-4f2ce87eb812@sirena.org.uk>
On Mon, 30 Mar 2026 16:08:47 +0100
Mark Brown <broonie@kernel.org> wrote:
> On Mon, Mar 30, 2026 at 12:16:04PM +0200, Herve Codina wrote:
> > On some embedded system boards, audio amplifiers are designed using
> > discrete components such as op-amp, several resistors and switches to
> > either adjust the gain (switching resistors) or fully switch the
> > audio signal path (mute and/or bypass features).
> >
> > Those switches are usually driven by simple GPIOs.
>
> This sounds a lot like simple-amplifier.c?
simple-amplifier.c doesn't handle amplifier driven by GPIOs.
The only used GPIO in simple-amplifier.c is used to handle the
enable pin the component.
simple-amplifier.c handles component such as dio2125 alone.
Here, we have op-amp but also several components around such as
switches.
The gpio driven amplifier proposed is more generic and can handle
more complex design. I.e. op-amp + resistor and/or line (mute,
bypass) switching. Hardwares handled by this driver are a superset
of just dio2125 and so simple-amplifier.c.
IMHO, it makes sense to have a specific driver for those kind
of hardware design.
Best regards,
Hervé
^ permalink raw reply
* Re: [PATCH v5 3/7] pinctrl: extract pinctrl_generic_to_map() from pinctrl_generic_pins_function_dt_node_to_map()
From: Conor Dooley @ 2026-03-30 15:33 UTC (permalink / raw)
To: Frank Li
Cc: Peter Rosin, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Rafał Miłecki, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-kernel, linux-gpio,
devicetree, imx, linux-arm-kernel, Haibo Chen, Conor Dooley
In-Reply-To: <20260327-pinctrl-mux-v5-3-d4aec9d62c62@nxp.com>
[-- Attachment #1: Type: text/plain, Size: 932 bytes --]
On Fri, Mar 27, 2026 at 05:34:00PM -0400, Frank Li wrote:
> Refactor pinctrl_generic_pins_function_dt_subnode_to_map() by separating DT
> parsing logic from map creation. Introduce a new helper
> pinctrl_generic_to_map() to handle mapping to kernel data structures, while
> keeping DT property parsing in the subnode function.
>
> Improve code structure and enables easier reuse for platforms using
> different DT properties (e.g. pinmux) without modifying the
> dt_node_to_map-style callback API. Avoid unnecessary coupling to
> pinctrl_generic_pins_function_dt_node_to_map(), which provides
> functionality not needed when the phandle target is unambiguous.
>
> Maximize code reuse and provide a cleaner extension point for future
> pinctrl drivers.
>
> Suggested-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 5/7] dt-bindings: cache: ax45mp-cache: rename ax45mp-cache to llcache
From: Conor Dooley @ 2026-03-30 15:29 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Hui Min Mina Chou, pjw, palmer, aou, alex, geert+renesas,
prabhakar.mahadev-lad.rj, magnus.damm, ben717, robh, krzk+dt,
conor+dt, jonathan.cameron, devicetree, linux-riscv, linux-kernel,
linux-renesas-soc, tim609, alex749, az70021
In-Reply-To: <c2a135eb-c8fa-47d6-b774-430ccc4fbda4@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 738 bytes --]
On Mon, Mar 30, 2026 at 03:00:41PM +0200, Krzysztof Kozlowski wrote:
> On 30/03/2026 12:27, Hui Min Mina Chou wrote:
> > The AX45MP-specific cache binding is renamed to a generic Last Level
> > Cache (LLC) schema, as the driver now supports more Andes CPU cores
> > beyond just AX45MP.
> >
> > Updated compatible strings:
> > andestech,qilai-ax45mp-cache -> andestech,qilai-llcache
> > renesas,r9a07g043f-ax45mp-cache -> renesas,r9a07g043f-llcache
> > andestech,ax45mp-cache -> andestech,llcache
>
> Why? No explanations and that is clear ABI break.
Ye, I am not going to accept any compatible string renames for this
hardware. The break is too significant, since the devices *need* this to
function.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 5/7] dt-bindings: cache: ax45mp-cache: rename ax45mp-cache to llcache
From: Conor Dooley @ 2026-03-30 15:28 UTC (permalink / raw)
To: Hui Min Mina Chou
Cc: pjw, palmer, aou, alex, geert+renesas, prabhakar.mahadev-lad.rj,
magnus.damm, ben717, robh, krzk+dt, conor+dt, jonathan.cameron,
devicetree, linux-riscv, linux-kernel, linux-renesas-soc, tim609,
alex749, az70021
In-Reply-To: <20260330102724.1012470-6-minachou@andestech.com>
[-- Attachment #1: Type: text/plain, Size: 3103 bytes --]
On Mon, Mar 30, 2026 at 06:27:22PM +0800, Hui Min Mina Chou wrote:
> The AX45MP-specific cache binding is renamed to a generic Last Level
> Cache (LLC) schema, as the driver now supports more Andes CPU cores
> beyond just AX45MP.
>
> Updated compatible strings:
> andestech,qilai-ax45mp-cache -> andestech,qilai-llcache
> renesas,r9a07g043f-ax45mp-cache -> renesas,r9a07g043f-llcache
> andestech,ax45mp-cache -> andestech,llcache
>
> Signed-off-by: Hui Min Mina Chou <minachou@andestech.com>
> ---
> ...ache.yaml => andestech,andes-llcache.yaml} | 20 +++++++++----------
> 1 file changed, 10 insertions(+), 10 deletions(-)
> rename Documentation/devicetree/bindings/cache/{andestech,ax45mp-cache.yaml => andestech,andes-llcache.yaml} (76%)
>
> diff --git a/Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml b/Documentation/devicetree/bindings/cache/andestech,andes-llcache.yaml
> similarity index 76%
> rename from Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml
> rename to Documentation/devicetree/bindings/cache/andestech,andes-llcache.yaml
> index b135ffa4ab6b..5b97625edd37 100644
> --- a/Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml
> +++ b/Documentation/devicetree/bindings/cache/andestech,andes-llcache.yaml
> @@ -2,17 +2,17 @@
> # Copyright (C) 2023 Renesas Electronics Corp.
> %YAML 1.2
> ---
> -$id: http://devicetree.org/schemas/cache/andestech,ax45mp-cache.yaml#
> +$id: http://devicetree.org/schemas/cache/andestech,llcache.yaml#
> $schema: http://devicetree.org/meta-schemas/core.yaml#
>
> -title: Andestech AX45MP L2 Cache Controller
> +title: Andestech Last Level Cache Controller
>
> maintainers:
> - Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
>
> description:
> - A level-2 cache (L2C) is used to improve the system performance by providing
> - a large amount of cache line entries and reasonable access delays. The L2C
> + A last level cache (LLC) is used to improve the system performance by providing
> + a large amount of cache line entries and reasonable access delays. The LLC
> is shared between cores, and a non-inclusive non-exclusive policy is used.
>
> select:
> @@ -20,7 +20,7 @@ select:
> compatible:
> contains:
> enum:
> - - andestech,ax45mp-cache
> + - andestech,llcache
>
> required:
> - compatible
> @@ -29,9 +29,9 @@ properties:
> compatible:
> items:
> - enum:
> - - andestech,qilai-ax45mp-cache
> - - renesas,r9a07g043f-ax45mp-cache
> - - const: andestech,ax45mp-cache
> + - andestech,qilai-llcache
> + - renesas,r9a07g043f-llcache
> + - const: andestech,llcache
> - const: cache
If you want to add a more generalied compatible to use as a fallback,
insert it underneath andestech,ax45mp-cache. andestech,llcache is far
too generic though, and there appears to be no user that isn't an ax45mp
now anyway, so not sure what this even gives us right now?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH 2/2] arm64: dts: marvell: armada-37xx: swap PHYs' order in USB3 controller node
From: Gabor Juhos @ 2026-03-30 15:25 UTC (permalink / raw)
To: Gregory Clement, Andrew Lunn, Sebastian Hesselbarth, Robert Marko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Greg Kroah-Hartman, Stanley Chang
Cc: linux-arm-kernel, devicetree, linux-kernel, Gabor Juhos
In-Reply-To: <20260330-armada-37xx-usb3-phy-cleanup-v1-0-34d77f1a1784@gmail.com>
It seems that the Armada 3700 is the only platform where the USB3 specific
PHY is defined before the USB2 specific one in the device tree:
$ git grep -E 'phy-names[ \t]*=[ \t]*"usb3-phy"[ \t]*,' next-20260327 -- *.dts *.dtsi | tr '\t' ' '
next-20260327:arch/arm64/boot/dts/marvell/armada-37xx.dtsi: phy-names = "usb3-phy", "usb2-utmi-otg-phy";
In contrary to this, there are 93 other platforms/boards where 'usb2-phy'
is defined first:
$ git grep -E 'phy-names[ \t]*=[ \t]*"usb2-phy"[ \t]*,' next-20260327 -- *.dts *.dtsi | wc -l
93
Swap the order of the USB3 and USB2 PHYs to follow the common pattern
used on other platforms.
No functional changes intended.
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
---
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 7470d504a41081b32bee45368028189a13ea7087..360fc24fdde2204540ac415852146d3020be87c0 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -371,8 +371,8 @@ usb3: usb@58000 {
reg = <0x58000 0x4000>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sb_periph_clk 12>;
- phys = <&comphy0 0>, <&usb2_utmi_otg_phy>;
- phy-names = "usb3-phy", "usb2-phy";
+ phys = <&usb2_utmi_otg_phy>, <&comphy0 0>;
+ phy-names = "usb2-phy", "usb3-phy";
status = "disabled";
};
--
2.53.0
^ permalink raw reply related
* [PATCH 1/2] arm64: dts: marvell: armada-37xx: use 'usb2-phy' in USB3 controller's phy-names
From: Gabor Juhos @ 2026-03-30 15:25 UTC (permalink / raw)
To: Gregory Clement, Andrew Lunn, Sebastian Hesselbarth, Robert Marko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Greg Kroah-Hartman, Stanley Chang
Cc: linux-arm-kernel, devicetree, linux-kernel, Gabor Juhos
In-Reply-To: <20260330-armada-37xx-usb3-phy-cleanup-v1-0-34d77f1a1784@gmail.com>
Instead of the generic 'usb2-phy' name, the Armada 37xx device trees
are using a custom 'usb2-utmi-otg-phy' name for the USB2 PHY in the USB3
controller node. Since commit 53a2d95df836 ("usb: core: add phy notify
connect and disconnect"), this triggers a bug [1] in the USB core which
causes double use of the USB3 PHY.
Change the PHY name to 'usb2-phy' in the SoC and in the uDPU specific
dtsi files in order to avoid triggering the bug and also to keep the
names in line with the ones used by other platforms.
Link: https://lore.kernel.org/r/20260330-usb-avoid-usb3-phy-double-use-v1-1-d2113aecb535@gmail.com # [1]
Fixes: 53a2d95df836 ("usb: core: add phy notify connect and disconnect")
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
---
arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi | 2 +-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
index cd856c0aba71e6f6fd3db8fb386ad607912e7577..12deacb741ccbea684d905f246f26a4399fc8cd8 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
@@ -161,7 +161,7 @@ ð1 {
&usb3 {
status = "okay";
phys = <&usb2_utmi_otg_phy>;
- phy-names = "usb2-utmi-otg-phy";
+ phy-names = "usb2-phy";
};
&uart0 {
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 44c47409f8793ae1266303607812ef481edbfbc5..7470d504a41081b32bee45368028189a13ea7087 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -372,7 +372,7 @@ usb3: usb@58000 {
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&sb_periph_clk 12>;
phys = <&comphy0 0>, <&usb2_utmi_otg_phy>;
- phy-names = "usb3-phy", "usb2-utmi-otg-phy";
+ phy-names = "usb3-phy", "usb2-phy";
status = "disabled";
};
--
2.53.0
^ permalink raw reply related
* [PATCH 0/2] arm64: dts: marvell: armada-37xx: USB3 PHY cleanup
From: Gabor Juhos @ 2026-03-30 15:25 UTC (permalink / raw)
To: Gregory Clement, Andrew Lunn, Sebastian Hesselbarth, Robert Marko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Greg Kroah-Hartman, Stanley Chang
Cc: linux-arm-kernel, devicetree, linux-kernel, Gabor Juhos
There are two small patches in the series. The first helps to avoid
triggering a bug in the USB core code, whereas the second one is a
small cleanup to align PHY definitions of the USB3 node with other
platforms.
Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
---
Gabor Juhos (2):
arm64: dts: marvell: armada-37xx: use 'usb2-phy' in USB3 controller's phy-names
arm64: dts: marvell: armada-37xx: swap PHYs' order in USB3 controller node
arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi | 2 +-
arch/arm64/boot/dts/marvell/armada-37xx.dtsi | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
---
base-commit: 2ff6cc999a04bcb094b8cbba68a9251f03a5c876
change-id: 20260330-armada-37xx-usb3-phy-cleanup-922a5472794a
Best regards,
--
Gabor Juhos <j4g8y7@gmail.com>
^ permalink raw reply
* Re: [PATCH 2/7] cache: andes_llcache: refactor initialization and cache operations
From: Conor Dooley @ 2026-03-30 15:23 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Hui Min Mina Chou, pjw, palmer, aou, alex, geert+renesas,
prabhakar.mahadev-lad.rj, magnus.damm, ben717, robh, krzk+dt,
conor+dt, jonathan.cameron, devicetree, linux-riscv, linux-kernel,
linux-renesas-soc, tim609, alex749, az70021
In-Reply-To: <8c01c910-21b4-4a16-98e4-197c20883d23@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 754 bytes --]
On Mon, Mar 30, 2026 at 03:02:11PM +0200, Krzysztof Kozlowski wrote:
> On 30/03/2026 12:27, Hui Min Mina Chou wrote:
> > This patch cleans up the Andes LLC cache driver:
> > - improved error handling in andes_cache_init() by using goto labels
> > - updated andes_dma_cache_inv/wback() to check for !size instead of
> > start == end
> > - cache-line-size mismatch from an error to a warning
> > - Use ALIGN and ALIGN_DOWN helpers instead of the alignment logic in
> > andes_dma_cache_inv() and andes_dma_cache_wback().
>
> Please read submitting patches document. One thing per commit with
> proper rationale WHY you are doing this.
Applies to multiple patches too. Anything here with a bullet list needs
to be several patches.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 10/16] clk: Add support for clock nexus dt bindings
From: Brian Masney @ 2026-03-30 15:16 UTC (permalink / raw)
To: Miquel Raynal (Schneider Electric)
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Olivia Mackall, Herbert Xu,
Jayesh Choudhary, David S. Miller, Christian Marangi,
Antoine Tenart, Geert Uytterhoeven, Magnus Damm, Thomas Petazzoni,
Pascal EBERHARD, Wolfram Sang, linux-clk, devicetree,
linux-kernel, linux-crypto, linux-renesas-soc, Herve Codina
In-Reply-To: <20260327-schneider-v7-0-rc1-crypto-v1-10-5e6ff7853994@bootlin.com>
On Fri, Mar 27, 2026 at 09:09:32PM +0100, Miquel Raynal (Schneider Electric) wrote:
> A nexus node is some kind of parent device abstracting the outer
> connections. They are particularly useful for describing connectors-like
> interfaces but not only. Certain IP blocks will typically include inner
> blocks and distribute resources to them.
>
> In the case of clocks, there is already the concept of clock controller,
> but this usually indicates some kind of control over the said clock,
> ie. gate or rate control. When there is none of this, an existing
> approach is to reference the upper clock, which is wrong from a hardware
> point of view.
>
> Nexus nodes are already part of the device-tree specification and clocks
> are already mentioned:
> https://github.com/devicetree-org/devicetree-specification/blob/v0.4/source/chapter2-devicetree-basics.rst#nexus-nodes-and-specifier-mapping
>
> Following the introductions of nexus nodes support for interrupts, gpios
> and pwms, here is the same logic applied again to the clk subsystem,
> just by transitioning from of_parse_phandle_with_args() to
> of_parse_phandle_with_args_map():
>
> * Nexus OF support:
> commit bd6f2fd5a1d5 ("of: Support parsing phandle argument lists through a nexus node")
> * GPIO adoption:
> commit c11e6f0f04db ("gpio: Support gpio nexus dt bindings")
> * PWM adoption:
> commit e71e46a6f19c ("pwm: Add support for pwm nexus dt bindings")
>
> Expected Nexus properties supported:
> - clock-map: maps inner clocks to inlet clocks,
> - clock-map-mask: specifier cell(s) which will be remapped,
> - clock-map-pass-thru: specifier cell(s) not used for remapping,
> forwarded as-is.
>
> In my own usage I had to deal with controllers where clock-map-mask and
> clock-map-pass-thru were not relevant, but here is a made up example
> showing how all these properties could go together:
>
> Example:
> soc_clk: clock-controller {
> #clock-cells = <2>;
> };
>
> container: container {
> #clock-cells = <2>;
> clock-map = <0 0 &soc_clk 2 0>,
> <1 0 &soc_clk 6 0>;
> clock-map-mask = <0xffffffff 0x0>;
> clock-map-pass-thru = <0x0 0xffffffff>;
>
> child-device {
> clocks = <&container 1 0>;
> /* This is equivalent to <&soc_clk 6 0> */
> };
> };
>
> The child device does not need to know about the outer implementation,
> and only knows about what the nexus provides. The nexus acts as a
> pass-through, with no extra control.
>
> Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
> Reviewed-by: Herve Codina <herve.codina@bootlin.com>
> ---
> drivers/clk/clk.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 93e33ff30f3a..196ba727e84b 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -5218,8 +5218,8 @@ static int of_parse_clkspec(const struct device_node *np, int index,
> */
> if (name)
> index = of_property_match_string(np, "clock-names", name);
> - ret = of_parse_phandle_with_args(np, "clocks", "#clock-cells",
> - index, out_args);
> + ret = of_parse_phandle_with_args_map(np, "clocks", "clock",
> + index, out_args);
Before I left my Reviewed-by, I should have double checked Sashiko. It
has several questions about this patch. The first is:
Are there other places in the clock framework that need to transition to the
new map API to ensure assigned clocks work?
For instance, assigned-clocks and assigned-clock-parents are parsed in
drivers/clk/clk-conf.c using of_parse_phandle_with_args(). If a device
specifies an assigned clock that routes through a nexus node, will it fail
to configure because the map is not traversed?
https://sashiko.dev/#/patchset/20260327-schneider-v7-0-rc1-crypto-v1-0-5e6ff7853994%40bootlin.com?patch=12563
Brian
^ permalink raw reply
* [PATCH v5 2/2] hwmon: Add support for TI INA4230 power monitor
From: Alexey Charkov @ 2026-03-30 15:14 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, devicetree, linux-kernel, Alexey Charkov
In-Reply-To: <20260330-ina4230-v5-0-eeb322d95b3a@flipper.net>
Add a driver for the TI INA4230, a 4-channel power monitor with I2C
interface.
The driver supports voltage, current, power and energy measurements, but
skips the alert functionality in this initial implementation.
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
MAINTAINERS | 1 +
drivers/hwmon/Kconfig | 11 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/ina4230.c | 986 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 999 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index acfa0b0585a5..9fc627b809a4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12579,6 +12579,7 @@ M: Alexey Charkov <alchark@flipper.net>
L: linux-hwmon@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/hwmon/ti,ina4230.yaml
+F: drivers/hwmon/ina4230.c
INDEX OF FURTHER KERNEL DOCUMENTATION
M: Carlos Bilbao <carlos.bilbao@kernel.org>
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 9d49cfd4ef3d..4649f00f24ca 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -2296,6 +2296,17 @@ config SENSORS_INA3221
This driver can also be built as a module. If so, the module
will be called ina3221.
+config SENSORS_INA4230
+ tristate "Texas Instruments INA4230 Quad Current/Voltage Monitor"
+ depends on I2C
+ select REGMAP_I2C
+ help
+ If you say yes here you get support for the TI INA4230 Quad
+ Current/Voltage Monitor.
+
+ This driver can also be built as a module. If so, the module
+ will be called ina4230.
+
config SENSORS_SPD5118
tristate "SPD5118 Compliant Temperature Sensors"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 556e86d277b1..3d83eba94bec 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_SENSORS_INA209) += ina209.o
obj-$(CONFIG_SENSORS_INA2XX) += ina2xx.o
obj-$(CONFIG_SENSORS_INA238) += ina238.o
obj-$(CONFIG_SENSORS_INA3221) += ina3221.o
+obj-$(CONFIG_SENSORS_INA4230) += ina4230.o
obj-$(CONFIG_SENSORS_INTEL_M10_BMC_HWMON) += intel-m10-bmc-hwmon.o
obj-$(CONFIG_SENSORS_ISL28022) += isl28022.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
diff --git a/drivers/hwmon/ina4230.c b/drivers/hwmon/ina4230.c
new file mode 100644
index 000000000000..a31a3f995afc
--- /dev/null
+++ b/drivers/hwmon/ina4230.c
@@ -0,0 +1,986 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * INA4230 Quad Current/Voltage Monitor
+ *
+ * Based on INA3221 driver by Texas Instruments Incorporated - https://www.ti.com/
+ * Adapted for INA4230 by Alexey Charkov <alchark@flipper.net>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/byteorder/generic.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/i2c.h>
+#include <linux/math.h>
+#include <linux/math64.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/util_macros.h>
+
+#define INA4230_DRIVER_NAME "ina4230"
+
+#define INA4230_SHUNT_VOLTAGE_CH1 0x00
+#define INA4230_BUS_VOLTAGE_CH1 0x01
+#define INA4230_CURRENT_CH1 0x02
+#define INA4230_POWER_CH1 0x03
+#define INA4230_ENERGY_CH1 0x04
+#define INA4230_CALIBRATION_CH1 0x05
+#define INA4230_ALERT_LIMIT1 0x06
+#define INA4230_ALERT_CONFIG1 0x07
+#define INA4230_SHUNT_VOLTAGE_CH2 0x08
+#define INA4230_BUS_VOLTAGE_CH2 0x09
+#define INA4230_CURRENT_CH2 0x0A
+#define INA4230_POWER_CH2 0x0B
+#define INA4230_ENERGY_CH2 0x0C
+#define INA4230_CALIBRATION_CH2 0x0D
+#define INA4230_ALERT_LIMIT2 0x0E
+#define INA4230_ALERT_CONFIG2 0x0F
+#define INA4230_SHUNT_VOLTAGE_CH3 0x10
+#define INA4230_BUS_VOLTAGE_CH3 0x11
+#define INA4230_CURRENT_CH3 0x12
+#define INA4230_POWER_CH3 0x13
+#define INA4230_ENERGY_CH3 0x14
+#define INA4230_CALIBRATION_CH3 0x15
+#define INA4230_ALERT_LIMIT3 0x16
+#define INA4230_ALERT_CONFIG3 0x17
+#define INA4230_SHUNT_VOLTAGE_CH4 0x18
+#define INA4230_BUS_VOLTAGE_CH4 0x19
+#define INA4230_CURRENT_CH4 0x1A
+#define INA4230_POWER_CH4 0x1B
+#define INA4230_ENERGY_CH4 0x1C
+#define INA4230_CALIBRATION_CH4 0x1D
+#define INA4230_ALERT_LIMIT4 0x1E
+#define INA4230_ALERT_CONFIG4 0x1F
+#define INA4230_CONFIG1 0x20
+#define INA4230_CONFIG2 0x21
+#define INA4230_FLAGS 0x22
+#define INA4230_MANUFACTURER_ID 0x7E
+
+#define INA4230_CALIBRATION_MASK GENMASK(14, 0)
+
+#define INA4230_ALERT_CHANNEL_MASK GENMASK(4, 3)
+#define INA4230_ALERT_MASK GENMASK(2, 0)
+/* Shunt voltage over limit */
+#define INA4230_ALERT_MASK_SOL 0x1
+/* Shunt voltage under limit */
+#define INA4230_ALERT_MASK_SUL 0x2
+/* Bus voltage over limit */
+#define INA4230_ALERT_MASK_BOL 0x3
+/* Bus voltage under limit */
+#define INA4230_ALERT_MASK_BUL 0x4
+/* Power over limit */
+#define INA4230_ALERT_MASK_POL 0x5
+
+#define INA4230_CONFIG1_ACTIVE_CHANNEL_MASK GENMASK(15, 12)
+#define INA4230_CONFIG1_AVG_MASK GENMASK(11, 9)
+#define INA4230_CONFIG1_VBUSCT_MASK GENMASK(8, 6)
+#define INA4230_CONFIG1_VSHCT_MASK GENMASK(5, 3)
+#define INA4230_CONFIG1_MODE_MASK GENMASK(2, 0)
+#define INA4230_MODE_POWERDOWN 0
+#define INA4230_MODE_SHUNT_SINGLE 1
+#define INA4230_MODE_BUS_SINGLE 2
+#define INA4230_MODE_BUS_SHUNT_SINGLE 3
+#define INA4230_MODE_POWERDOWN1 4
+#define INA4230_MODE_SHUNT_CONTINUOUS 5
+#define INA4230_MODE_BUS_CONTINUOUS 6
+#define INA4230_MODE_BUS_SHUNT_CONTINUOUS 7
+
+#define INA4230_CONFIG2_RST BIT(15)
+#define INA4230_CONFIG2_ACC_RST_MASK GENMASK(11, 8)
+#define INA4230_CONFIG2_CNVR_MASK BIT(7)
+#define INA4230_CONFIG2_ENOF_MASK BIT(6)
+#define INA4230_CONFIG2_ALERT_LATCH BIT(5)
+#define INA4230_CONFIG2_ALERT_POL BIT(4)
+#define INA4230_CONFIG2_RANGE_MASK GENMASK(3, 0)
+#define INA4230_CONFIG2_RANGE_CH(x) \
+ FIELD_PREP(INA4230_CONFIG2_RANGE_MASK, BIT((x)))
+
+#define INA4230_FLAGS_LIMIT4_ALERT BIT(15)
+#define INA4230_FLAGS_LIMIT3_ALERT BIT(14)
+#define INA4230_FLAGS_LIMIT2_ALERT BIT(13)
+#define INA4230_FLAGS_LIMIT1_ALERT BIT(12)
+#define INA4230_FLAGS_ENERGY_OVERFLOW_CH4 BIT(11)
+#define INA4230_FLAGS_ENERGY_OVERFLOW_CH3 BIT(10)
+#define INA4230_FLAGS_ENERGY_OVERFLOW_CH2 BIT(9)
+#define INA4230_FLAGS_ENERGY_OVERFLOW_CH1 BIT(8)
+#define INA4230_FLAGS_CVRF BIT(7)
+#define INA4230_FLAGS_MATH_OVERFLOW BIT(6)
+
+#define INA4230_RSHUNT_DEFAULT 10000
+#define INA4230_CONFIG_DEFAULT \
+ (FIELD_PREP(INA4230_CONFIG1_ACTIVE_CHANNEL_MASK, 0xF) | \
+ FIELD_PREP(INA4230_CONFIG1_AVG_MASK, 0x1) | \
+ FIELD_PREP(INA4230_CONFIG1_VBUSCT_MASK, 0x4) | \
+ FIELD_PREP(INA4230_CONFIG1_VSHCT_MASK, 0x4) | \
+ FIELD_PREP(INA4230_CONFIG1_MODE_MASK, 0x7))
+#define INA4230_CONFIG_CHx_EN(x) \
+ FIELD_PREP(INA4230_CONFIG1_ACTIVE_CHANNEL_MASK, BIT((x)))
+
+enum ina4230_fields {
+ /* Alert configuration settings: channel masks */
+ F_ALERT1_CH, F_ALERT2_CH, F_ALERT3_CH, F_ALERT4_CH,
+ /* Alert configuration settings: alert masks */
+ F_ALERT1_TYPE, F_ALERT2_TYPE, F_ALERT3_TYPE, F_ALERT4_TYPE,
+ /* Configuration registers */
+ F_CH_EN, F_AVG, F_VBUSCT, F_VSHCT, F_MODE,
+ F_RST, F_ACC_RST, F_CNV_ALERT, F_ENOF, F_ALERT_LATCH, F_ALERT_POL, F_RANGE,
+ /* Status flags */
+ F_LIMIT1_ALERT, F_LIMIT2_ALERT, F_LIMIT3_ALERT, F_LIMIT4_ALERT,
+ F_ENERGY_OVERFLOW_CH1, F_ENERGY_OVERFLOW_CH2, F_ENERGY_OVERFLOW_CH3, F_ENERGY_OVERFLOW_CH4,
+ F_CVRF, F_MATH_OVERFLOW,
+ /* sentinel */
+ F_MAX_FIELDS
+};
+
+static const struct reg_field ina4230_reg_fields[] = {
+ [F_ALERT1_CH] = REG_FIELD(INA4230_ALERT_CONFIG1, 3, 4),
+ [F_ALERT2_CH] = REG_FIELD(INA4230_ALERT_CONFIG2, 3, 4),
+ [F_ALERT3_CH] = REG_FIELD(INA4230_ALERT_CONFIG3, 3, 4),
+ [F_ALERT4_CH] = REG_FIELD(INA4230_ALERT_CONFIG4, 3, 4),
+
+ [F_ALERT1_TYPE] = REG_FIELD(INA4230_ALERT_CONFIG1, 0, 2),
+ [F_ALERT2_TYPE] = REG_FIELD(INA4230_ALERT_CONFIG2, 0, 2),
+ [F_ALERT3_TYPE] = REG_FIELD(INA4230_ALERT_CONFIG3, 0, 2),
+ [F_ALERT4_TYPE] = REG_FIELD(INA4230_ALERT_CONFIG4, 0, 2),
+
+ [F_CH_EN] = REG_FIELD(INA4230_CONFIG1, 12, 15),
+ [F_AVG] = REG_FIELD(INA4230_CONFIG1, 9, 11),
+ [F_VBUSCT] = REG_FIELD(INA4230_CONFIG1, 6, 8),
+ [F_VSHCT] = REG_FIELD(INA4230_CONFIG1, 3, 5),
+ [F_MODE] = REG_FIELD(INA4230_CONFIG1, 0, 2),
+ [F_RST] = REG_FIELD(INA4230_CONFIG2, 15, 15),
+ [F_ACC_RST] = REG_FIELD(INA4230_CONFIG2, 8, 11),
+ [F_CNV_ALERT] = REG_FIELD(INA4230_CONFIG2, 7, 7),
+ [F_ENOF] = REG_FIELD(INA4230_CONFIG2, 6, 6),
+ [F_ALERT_LATCH] = REG_FIELD(INA4230_CONFIG2, 5, 5),
+ [F_ALERT_POL] = REG_FIELD(INA4230_CONFIG2, 4, 4),
+ [F_RANGE] = REG_FIELD(INA4230_CONFIG2, 0, 3),
+
+ [F_LIMIT1_ALERT] = REG_FIELD(INA4230_FLAGS, 12, 12),
+ [F_LIMIT2_ALERT] = REG_FIELD(INA4230_FLAGS, 13, 13),
+ [F_LIMIT3_ALERT] = REG_FIELD(INA4230_FLAGS, 14, 14),
+ [F_LIMIT4_ALERT] = REG_FIELD(INA4230_FLAGS, 15, 15),
+ [F_ENERGY_OVERFLOW_CH1] = REG_FIELD(INA4230_FLAGS, 8, 8),
+ [F_ENERGY_OVERFLOW_CH2] = REG_FIELD(INA4230_FLAGS, 9, 9),
+ [F_ENERGY_OVERFLOW_CH3] = REG_FIELD(INA4230_FLAGS, 10, 10),
+ [F_ENERGY_OVERFLOW_CH4] = REG_FIELD(INA4230_FLAGS, 11, 11),
+ [F_CVRF] = REG_FIELD(INA4230_FLAGS, 7, 7),
+ [F_MATH_OVERFLOW] = REG_FIELD(INA4230_FLAGS, 6, 6),
+};
+
+enum ina4230_channels {
+ INA4230_CHANNEL1,
+ INA4230_CHANNEL2,
+ INA4230_CHANNEL3,
+ INA4230_CHANNEL4,
+ INA4230_NUM_CHANNELS
+};
+
+/**
+ * struct ina4230_input - channel input source specific information
+ * @label: label of channel input source
+ * @shunt_resistor: shunt resistor value of channel input source
+ * @shunt_gain: gain of shunt voltage for current calculation
+ * @max_expected_current: maximum expected current in micro-Ampere for ADC
+ * calibration
+ * @current_lsb_uA: current LSB in micro-Amperes
+ * @disconnected: connection status of channel input source
+ */
+struct ina4230_input {
+ const char *label;
+ int shunt_resistor;
+ int shunt_gain;
+ int max_expected_current;
+ int current_lsb_uA;
+ bool disconnected;
+};
+
+/**
+ * struct ina4230_data - device specific information
+ * @pm_dev: Device pointer for pm runtime
+ * @regmap: Register map of the device
+ * @fields: Register fields of the device
+ * @inputs: Array of channel input source specific structures
+ * @reg_config1: cached value of CONFIG1 register
+ * @reg_config2: cached value of CONFIG2 register
+ * @alert_active_high: flag indicating alert polarity is active high
+ */
+struct ina4230_data {
+ struct device *pm_dev;
+ struct regmap *regmap;
+ struct regmap_field *fields[F_MAX_FIELDS];
+ struct ina4230_input inputs[INA4230_NUM_CHANNELS];
+ unsigned int reg_config1;
+ unsigned int reg_config2;
+ bool alert_active_high;
+};
+
+static inline bool ina4230_is_enabled(struct ina4230_data *ina, int channel)
+{
+ return pm_runtime_active(ina->pm_dev) &&
+ !ina->inputs[channel].disconnected &&
+ ina->reg_config1 & INA4230_CONFIG_CHx_EN(channel);
+}
+
+/* Lookup table for Bus and Shunt conversion times in usec */
+static const u16 ina4230_conv_time[] = {
+ 140, 204, 332, 588, 1100, 2116, 4156, 8244,
+};
+
+/* Lookup table for number of samples used in averaging mode */
+static const int ina4230_avg_samples[] = {
+ 1, 4, 16, 64, 128, 256, 512, 1024,
+};
+
+/* Converting update_interval in msec to conversion time in usec */
+static inline u32 ina4230_interval_ms_to_conv_time(u16 config, int interval)
+{
+ u32 channels = hweight16(config & INA4230_CONFIG1_ACTIVE_CHANNEL_MASK);
+ u32 samples_idx = FIELD_GET(INA4230_CONFIG1_AVG_MASK, config);
+ u32 samples = ina4230_avg_samples[samples_idx];
+
+ if (!channels)
+ return U32_MAX;
+
+ /* Bisect the result to Bus and Shunt conversion times */
+ return DIV_ROUND_CLOSEST(interval * 1000 / 2, channels * samples);
+}
+
+/* Converting CONFIG register value to update_interval in usec */
+static inline u32 ina4230_reg_to_interval_us(u16 config)
+{
+ u32 channels = hweight16(config & INA4230_CONFIG1_ACTIVE_CHANNEL_MASK);
+ u32 vbus_ct_idx = FIELD_GET(INA4230_CONFIG1_VBUSCT_MASK, config);
+ u32 vsh_ct_idx = FIELD_GET(INA4230_CONFIG1_VSHCT_MASK, config);
+ u32 vbus_ct = ina4230_conv_time[vbus_ct_idx];
+ u32 vsh_ct = ina4230_conv_time[vsh_ct_idx];
+
+ /* Calculate total conversion time */
+ return channels * (vbus_ct + vsh_ct);
+}
+
+static const u8 ina4230_calibration_reg[] = {
+ INA4230_CALIBRATION_CH1,
+ INA4230_CALIBRATION_CH2,
+ INA4230_CALIBRATION_CH3,
+ INA4230_CALIBRATION_CH4,
+};
+
+static int ina4230_set_calibration(struct ina4230_data *ina, int channel)
+{
+ struct ina4230_input *input = &ina->inputs[channel];
+ u8 reg = ina4230_calibration_reg[channel];
+ int shunt_range_uV, ret;
+ u32 calibration;
+ u64 n, d;
+
+ shunt_range_uV = mult_frac(input->max_expected_current,
+ input->shunt_resistor,
+ 1000000);
+ input->shunt_gain = shunt_range_uV > 20480 ? 1 : 4;
+ ina->reg_config2 &= ~INA4230_CONFIG2_RANGE_CH(channel);
+ if (input->shunt_gain == 4)
+ ina->reg_config2 |= INA4230_CONFIG2_RANGE_CH(channel);
+
+ ret = regmap_write(ina->regmap, INA4230_CONFIG2, ina->reg_config2);
+ if (ret)
+ return ret;
+
+ input->current_lsb_uA = DIV_ROUND_UP(input->max_expected_current, 32768);
+ n = 5120000000ULL;
+ d = (u64)input->current_lsb_uA * input->shunt_resistor * input->shunt_gain;
+ /* Ensure rounding to the closest integer */
+ n += d / 2;
+ n = div64_u64(n, d);
+ if (n > INA4230_CALIBRATION_MASK) {
+ dev_err(ina->pm_dev,
+ "Shunt %duOhm too low for expected current %duA, cannot calibrate channel %d\n",
+ input->shunt_resistor, input->max_expected_current, channel + 1);
+ return -ERANGE;
+ }
+
+ calibration = n & INA4230_CALIBRATION_MASK;
+
+ return regmap_write(ina->regmap, reg, calibration);
+}
+
+static const u8 ina4230_in_reg[] = {
+ INA4230_BUS_VOLTAGE_CH1,
+ INA4230_BUS_VOLTAGE_CH2,
+ INA4230_BUS_VOLTAGE_CH3,
+ INA4230_BUS_VOLTAGE_CH4,
+ INA4230_SHUNT_VOLTAGE_CH1,
+ INA4230_SHUNT_VOLTAGE_CH2,
+ INA4230_SHUNT_VOLTAGE_CH3,
+ INA4230_SHUNT_VOLTAGE_CH4,
+};
+
+static const u8 ina4230_curr_reg[][INA4230_NUM_CHANNELS] = {
+ [hwmon_curr_input] = { INA4230_CURRENT_CH1, INA4230_CURRENT_CH2,
+ INA4230_CURRENT_CH3, INA4230_CURRENT_CH4 },
+};
+
+static const u8 ina4230_power_reg[] = {
+ INA4230_POWER_CH1, INA4230_POWER_CH2, INA4230_POWER_CH3, INA4230_POWER_CH4
+};
+
+static const u8 ina4230_energy_reg[] = {
+ INA4230_ENERGY_CH1, INA4230_ENERGY_CH2,
+ INA4230_ENERGY_CH3, INA4230_ENERGY_CH4
+};
+
+static int ina4230_read_chip(struct device *dev, u32 attr, long *val)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ int regval;
+
+ switch (attr) {
+ case hwmon_chip_samples:
+ regval = FIELD_GET(INA4230_CONFIG1_AVG_MASK, ina->reg_config1);
+ *val = ina4230_avg_samples[regval];
+ return 0;
+ case hwmon_chip_update_interval:
+ /* Return in msec */
+ *val = ina4230_reg_to_interval_us(ina->reg_config1);
+ *val = DIV_ROUND_CLOSEST(*val, 1000);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ina4230_read_in(struct device *dev, u32 attr, int channel, long *val)
+{
+ const bool is_shunt = channel > INA4230_CHANNEL4;
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ u8 reg = ina4230_in_reg[channel];
+ int regval, ret;
+
+ /*
+ * Translate shunt channel index to sensor channel index
+ */
+ channel %= INA4230_NUM_CHANNELS;
+
+ switch (attr) {
+ case hwmon_in_input:
+ if (!ina4230_is_enabled(ina, channel))
+ return -ENODATA;
+
+ ret = regmap_read(ina->regmap, reg, ®val);
+ if (ret)
+ return ret;
+
+ /*
+ * Scale of shunt voltage (uV): LSB is 2.5uV or 625nV
+ * depending on gain setting
+ * Scale of bus voltage (mV): LSB is 1.6mV
+ */
+ if (is_shunt)
+ *val = mult_frac((long)(int16_t)regval,
+ 2500 / ina->inputs[channel].shunt_gain,
+ 1000000);
+ else
+ *val = mult_frac((long)(int16_t)regval,
+ 1600,
+ 1000);
+ return 0;
+ case hwmon_in_enable:
+ *val = ina4230_is_enabled(ina, channel);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ina4230_read_power(struct device *dev, u32 attr, int channel, long *val)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ u8 reg = ina4230_power_reg[channel];
+ int regval, ret;
+
+ switch (attr) {
+ case hwmon_power_input:
+ if (!ina4230_is_enabled(ina, channel))
+ return -ENODATA;
+
+ ret = regmap_read(ina->regmap, reg, ®val);
+ if (ret)
+ return ret;
+
+ *val = (int16_t)regval *
+ (long)ina->inputs[channel].current_lsb_uA * 32;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ina4230_read_energy(struct device *dev, u32 attr, int channel, long *val)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ u8 reg = ina4230_energy_reg[channel];
+ int ret;
+ __be32 regval;
+
+ switch (attr) {
+ case hwmon_energy_input:
+ if (!ina4230_is_enabled(ina, channel))
+ return -ENODATA;
+
+ ret = regmap_noinc_read(ina->regmap, reg, ®val, sizeof(regval));
+ if (ret)
+ return ret;
+
+ *val = be32_to_cpu(regval) *
+ (long)ina->inputs[channel].current_lsb_uA * 32;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ina4230_read_curr(struct device *dev, u32 attr,
+ int channel, long *val)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ u8 reg = ina4230_curr_reg[attr][channel];
+ int regval, ret;
+
+ switch (attr) {
+ case hwmon_curr_input:
+ if (!ina4230_is_enabled(ina, channel))
+ return -ENODATA;
+
+ ret = regmap_read(ina->regmap, reg, ®val);
+ if (ret)
+ return ret;
+
+ *val = (int16_t)regval *
+ (long)ina->inputs[channel].current_lsb_uA / 1000;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ina4230_write_chip(struct device *dev, u32 attr, long val)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ int idx;
+ u32 tmp;
+
+ switch (attr) {
+ case hwmon_chip_samples:
+ idx = find_closest(val, ina4230_avg_samples,
+ ARRAY_SIZE(ina4230_avg_samples));
+
+ FIELD_MODIFY(INA4230_CONFIG1_AVG_MASK, &ina->reg_config1, idx);
+ return regmap_write(ina->regmap, INA4230_CONFIG1, ina->reg_config1);
+ case hwmon_chip_update_interval:
+ tmp = ina4230_interval_ms_to_conv_time(ina->reg_config1, val);
+ idx = find_closest(tmp, ina4230_conv_time,
+ ARRAY_SIZE(ina4230_conv_time));
+
+ FIELD_MODIFY(INA4230_CONFIG1_VBUSCT_MASK, &ina->reg_config1, idx);
+ FIELD_MODIFY(INA4230_CONFIG1_VSHCT_MASK, &ina->reg_config1, idx);
+ return regmap_write(ina->regmap, INA4230_CONFIG1, ina->reg_config1);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int ina4230_write_enable(struct device *dev, int channel, bool enable)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ u16 config, mask = INA4230_CONFIG_CHx_EN(channel);
+ u16 config_old = ina->reg_config1 & mask;
+ u32 tmp;
+ int ret;
+
+ config = enable ? mask : 0;
+
+ /* Bypass if enable status is not being changed */
+ if (config_old == config)
+ return 0;
+
+ /* For enabling routine, increase refcount and resume() at first */
+ if (enable) {
+ ret = pm_runtime_resume_and_get(ina->pm_dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to get PM runtime\n");
+ return ret;
+ }
+ }
+
+ /* Enable or disable the channel */
+ tmp = (ina->reg_config1 & ~mask) | (config & mask);
+ ret = regmap_write(ina->regmap, INA4230_CONFIG1, tmp);
+ if (ret)
+ goto fail;
+
+ /* Cache the latest config register value */
+ ina->reg_config1 = tmp;
+
+ /* For disabling routine, decrease refcount or suspend() at last */
+ if (!enable)
+ pm_runtime_put_sync(ina->pm_dev);
+
+ return 0;
+
+fail:
+ if (enable) {
+ dev_err(dev, "Failed to enable channel %d: error %d\n",
+ channel, ret);
+ pm_runtime_put_sync(ina->pm_dev);
+ }
+
+ return ret;
+}
+
+static int ina4230_read(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long *val)
+{
+ int ret;
+
+ switch (type) {
+ case hwmon_chip:
+ ret = ina4230_read_chip(dev, attr, val);
+ break;
+ case hwmon_in:
+ /* 0-align channel ID */
+ ret = ina4230_read_in(dev, attr, channel - 1, val);
+ break;
+ case hwmon_curr:
+ ret = ina4230_read_curr(dev, attr, channel, val);
+ break;
+ case hwmon_power:
+ ret = ina4230_read_power(dev, attr, channel, val);
+ break;
+ case hwmon_energy:
+ ret = ina4230_read_energy(dev, attr, channel, val);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ return ret;
+}
+
+static int ina4230_write(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, long val)
+{
+ int ret;
+
+ switch (type) {
+ case hwmon_chip:
+ ret = ina4230_write_chip(dev, attr, val);
+ break;
+ case hwmon_in:
+ /* 0-align channel ID */
+ ret = ina4230_write_enable(dev, channel - 1, val);
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ return ret;
+}
+
+static int ina4230_read_string(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel, const char **str)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ int index = channel - 1;
+
+ *str = ina->inputs[index].label;
+
+ return 0;
+}
+
+static umode_t ina4230_is_visible(const void *drvdata,
+ enum hwmon_sensor_types type,
+ u32 attr, int channel)
+{
+ const struct ina4230_data *ina = drvdata;
+ const struct ina4230_input *input = NULL;
+
+ switch (type) {
+ case hwmon_chip:
+ switch (attr) {
+ case hwmon_chip_samples:
+ case hwmon_chip_update_interval:
+ return 0644;
+ default:
+ return 0;
+ }
+ case hwmon_in:
+ /* Ignore in0_ */
+ if (channel == 0)
+ return 0;
+
+ switch (attr) {
+ case hwmon_in_label:
+ if (channel - 1 <= INA4230_CHANNEL4)
+ input = &ina->inputs[channel - 1];
+ /* Hide label node if label is not provided */
+ return (input && input->label) ? 0444 : 0;
+ case hwmon_in_input:
+ return 0444;
+ case hwmon_in_enable:
+ return 0644;
+ default:
+ return 0;
+ }
+ case hwmon_curr:
+ switch (attr) {
+ case hwmon_curr_input:
+ return 0444;
+ default:
+ return 0;
+ }
+ case hwmon_power:
+ switch (attr) {
+ case hwmon_power_input:
+ return 0444;
+ default:
+ return 0;
+ }
+ case hwmon_energy:
+ switch (attr) {
+ case hwmon_energy_input:
+ return 0444;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
+static const struct hwmon_channel_info * const ina4230_info[] = {
+ HWMON_CHANNEL_INFO(chip,
+ HWMON_C_SAMPLES,
+ HWMON_C_UPDATE_INTERVAL),
+ HWMON_CHANNEL_INFO(in,
+ /* 0: dummy, skipped in is_visible */
+ HWMON_I_INPUT,
+ /* 1-4: input voltage Channels */
+ HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
+ HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
+ HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
+ HWMON_I_INPUT | HWMON_I_ENABLE | HWMON_I_LABEL,
+ /* 5-8: shunt voltage Channels */
+ HWMON_I_INPUT,
+ HWMON_I_INPUT,
+ HWMON_I_INPUT,
+ HWMON_I_INPUT),
+ HWMON_CHANNEL_INFO(curr,
+ /* 1-4: current channels*/
+ HWMON_C_INPUT,
+ HWMON_C_INPUT,
+ HWMON_C_INPUT,
+ HWMON_C_INPUT),
+ HWMON_CHANNEL_INFO(power,
+ /* 1-4: power channels*/
+ HWMON_P_INPUT,
+ HWMON_P_INPUT,
+ HWMON_P_INPUT,
+ HWMON_P_INPUT),
+ HWMON_CHANNEL_INFO(energy,
+ /* 1-4: energy channels*/
+ HWMON_E_INPUT,
+ HWMON_E_INPUT,
+ HWMON_E_INPUT,
+ HWMON_E_INPUT),
+ NULL
+};
+
+static const struct hwmon_ops ina4230_hwmon_ops = {
+ .is_visible = ina4230_is_visible,
+ .read_string = ina4230_read_string,
+ .read = ina4230_read,
+ .write = ina4230_write,
+};
+
+static const struct hwmon_chip_info ina4230_chip_info = {
+ .ops = &ina4230_hwmon_ops,
+ .info = ina4230_info,
+};
+
+static const struct regmap_range ina4230_vol_ranges[] = {
+ regmap_reg_range(INA4230_SHUNT_VOLTAGE_CH1, INA4230_ENERGY_CH1),
+ regmap_reg_range(INA4230_SHUNT_VOLTAGE_CH2, INA4230_ENERGY_CH2),
+ regmap_reg_range(INA4230_SHUNT_VOLTAGE_CH3, INA4230_ENERGY_CH3),
+ regmap_reg_range(INA4230_SHUNT_VOLTAGE_CH4, INA4230_ENERGY_CH4),
+ regmap_reg_range(INA4230_CONFIG2, INA4230_CONFIG2),
+ regmap_reg_range(INA4230_FLAGS, INA4230_FLAGS),
+};
+
+static const struct regmap_access_table ina4230_volatile_table = {
+ .yes_ranges = ina4230_vol_ranges,
+ .n_yes_ranges = ARRAY_SIZE(ina4230_vol_ranges),
+};
+
+static const struct regmap_config ina4230_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .cache_type = REGCACHE_MAPLE,
+ .volatile_table = &ina4230_volatile_table,
+};
+
+static int ina4230_probe_child_from_dt(struct device *dev,
+ struct device_node *child,
+ struct ina4230_data *ina)
+{
+ struct ina4230_input *input;
+ u32 val;
+ int ret;
+
+ ret = of_property_read_u32(child, "reg", &val);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "missing reg property of %pOFn\n", child);
+ else if (val > INA4230_CHANNEL4)
+ return dev_err_probe(dev, -EINVAL,
+ "invalid reg %d of %pOFn\n", val, child);
+
+ input = &ina->inputs[val];
+
+ /* Log the disconnected channel input */
+ if (!of_device_is_available(child)) {
+ input->disconnected = true;
+ return 0;
+ }
+
+ /* Save the connected input label if available */
+ of_property_read_string(child, "label", &input->label);
+
+ /* Overwrite default shunt resistor value optionally */
+ if (!of_property_read_u32(child, "shunt-resistor-micro-ohms", &val)) {
+ if (val < 1 || val > INT_MAX)
+ return dev_err_probe(dev, -EINVAL,
+ "invalid shunt resistor value %u of %pOFn\n",
+ val, child);
+
+ input->shunt_resistor = val;
+ }
+
+ /* Save the expected maxcurrent */
+ if (!of_property_read_u32(child, "ti,maximum-expected-current-microamp", &val)) {
+ if (val < 32768 || val > INT_MAX)
+ return dev_err_probe(dev, -EINVAL,
+ "invalid max current value %u of %pOFn\n",
+ val, child);
+
+ input->max_expected_current = val;
+ }
+
+ return 0;
+}
+
+static int ina4230_probe_from_dt(struct device *dev, struct ina4230_data *ina)
+{
+ const struct device_node *np = dev->of_node;
+ int ret;
+
+ /* Compatible with non-DT platforms */
+ if (!np)
+ return 0;
+
+ ina->alert_active_high = of_property_read_bool(np, "ti,alert-polarity-active-high");
+
+ for_each_child_of_node_scoped(np, child) {
+ ret = ina4230_probe_child_from_dt(dev, child, ina);
+ if (ret)
+ return ret;
+ }
+
+ ret = devm_regulator_get_enable_optional(dev, "vs");
+ if (ret && ret != -ENODEV)
+ return dev_err_probe(dev, ret, "Failed to get regulator\n");
+
+ return 0;
+}
+
+static int ina4230_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct ina4230_data *ina;
+ struct device *hwmon_dev;
+ int i, ret;
+
+ ina = devm_kzalloc(dev, sizeof(*ina), GFP_KERNEL);
+ if (!ina)
+ return -ENOMEM;
+
+ ina->regmap = devm_regmap_init_i2c(client, &ina4230_regmap_config);
+ if (IS_ERR(ina->regmap))
+ return PTR_ERR(ina->regmap);
+
+ ret = devm_regmap_field_bulk_alloc(dev, ina->regmap, ina->fields,
+ ina4230_reg_fields,
+ ARRAY_SIZE(ina4230_reg_fields));
+ if (ret)
+ return ret;
+
+ for (i = 0; i < INA4230_NUM_CHANNELS; i++) {
+ ina->inputs[i].shunt_resistor = INA4230_RSHUNT_DEFAULT;
+ /* Default for 1mA LSB current measurements */
+ ina->inputs[i].max_expected_current = 32768000;
+ }
+
+ ret = ina4230_probe_from_dt(dev, ina);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "Unable to probe from device tree\n");
+
+ /* The driver will be reset, so use reset value */
+ ina->reg_config1 = INA4230_CONFIG_DEFAULT;
+ ina->reg_config2 = 0;
+
+ if (ina->alert_active_high)
+ FIELD_MODIFY(INA4230_CONFIG2_ALERT_POL, &ina->reg_config2, 1);
+
+ /* Disable channels if their inputs are disconnected */
+ for (i = 0; i < INA4230_NUM_CHANNELS; i++) {
+ if (ina->inputs[i].disconnected)
+ ina->reg_config1 &= ~INA4230_CONFIG_CHx_EN(i);
+ }
+
+ ina->pm_dev = dev;
+ dev_set_drvdata(dev, ina);
+
+ /* Enable PM runtime -- status is suspended by default */
+ pm_runtime_enable(ina->pm_dev);
+
+ /* Initialize (resume) the device */
+ for (i = 0; i < INA4230_NUM_CHANNELS; i++) {
+ if (ina->inputs[i].disconnected)
+ continue;
+
+ /* Match the refcount with number of enabled channels */
+ ret = pm_runtime_get_sync(ina->pm_dev);
+ if (ret < 0)
+ goto fail;
+ }
+
+ /* Set calibration values after device resume/reset */
+ for (i = 0; i < INA4230_NUM_CHANNELS; i++) {
+ if (!ina->inputs[i].disconnected) {
+ ret = ina4230_set_calibration(ina, i);
+ if (ret)
+ goto fail;
+ }
+ }
+
+ hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, ina,
+ &ina4230_chip_info,
+ NULL);
+ if (IS_ERR(hwmon_dev)) {
+ ret = dev_err_probe(dev, PTR_ERR(hwmon_dev),
+ "Unable to register hwmon device\n");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ pm_runtime_disable(ina->pm_dev);
+ pm_runtime_set_suspended(ina->pm_dev);
+ /* pm_runtime_put_noidle() for connected channels to balance get_sync */
+ for (i = 0; i < INA4230_NUM_CHANNELS; i++) {
+ if (!ina->inputs[i].disconnected &&
+ ina->reg_config1 & INA4230_CONFIG_CHx_EN(i))
+ pm_runtime_put_noidle(ina->pm_dev);
+ }
+
+ return ret;
+}
+
+static void ina4230_remove(struct i2c_client *client)
+{
+ struct ina4230_data *ina = dev_get_drvdata(&client->dev);
+ int i;
+
+ pm_runtime_disable(ina->pm_dev);
+ pm_runtime_set_suspended(ina->pm_dev);
+
+ /* pm_runtime_put_noidle() for connected channels to balance get_sync */
+ for (i = 0; i < INA4230_NUM_CHANNELS; i++) {
+ if (!ina->inputs[i].disconnected &&
+ ina->reg_config1 & INA4230_CONFIG_CHx_EN(i))
+ pm_runtime_put_noidle(ina->pm_dev);
+ }
+}
+
+static int ina4230_suspend(struct device *dev)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ int ret;
+
+ /* Save config register value and enable cache-only */
+ ret = regmap_read(ina->regmap, INA4230_CONFIG1, &ina->reg_config1);
+ if (ret)
+ return ret;
+
+ regcache_cache_only(ina->regmap, true);
+ regcache_mark_dirty(ina->regmap);
+
+ return 0;
+}
+
+static int ina4230_resume(struct device *dev)
+{
+ struct ina4230_data *ina = dev_get_drvdata(dev);
+ int ret;
+
+ regcache_cache_only(ina->regmap, false);
+
+ /* Software reset the chip */
+ ret = regmap_field_write(ina->fields[F_RST], true);
+ if (ret) {
+ dev_err(dev, "Unable to reset device\n");
+ return ret;
+ }
+
+ /* Restore cached register values to hardware */
+ ret = regcache_sync(ina->regmap);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(ina4230_pm, ina4230_suspend, ina4230_resume,
+ NULL);
+
+static const struct of_device_id ina4230_of_match_table[] = {
+ { .compatible = "ti,ina4230", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, ina4230_of_match_table);
+
+static const struct i2c_device_id ina4230_ids[] = {
+ { "ina4230" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(i2c, ina4230_ids);
+
+static struct i2c_driver ina4230_i2c_driver = {
+ .probe = ina4230_probe,
+ .remove = ina4230_remove,
+ .driver = {
+ .name = INA4230_DRIVER_NAME,
+ .of_match_table = ina4230_of_match_table,
+ .pm = pm_ptr(&ina4230_pm),
+ },
+ .id_table = ina4230_ids,
+};
+module_i2c_driver(ina4230_i2c_driver);
+
+MODULE_AUTHOR("Alexey Charkov <alchark@flipper.net>");
+MODULE_DESCRIPTION("Texas Instruments INA4230 HWMon Driver");
+MODULE_LICENSE("GPL");
--
2.52.0
^ permalink raw reply related
* [PATCH v5 1/2] dt-bindings: hwmon: Add TI INA4230 4-channel I2C power monitor
From: Alexey Charkov @ 2026-03-30 15:14 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, devicetree, linux-kernel, Alexey Charkov,
Krzysztof Kozlowski
In-Reply-To: <20260330-ina4230-v5-0-eeb322d95b3a@flipper.net>
Add TI INA4230, which is a 48V 4-channel 16-bit I2C-based
current/voltage/power/energy monitor with alert function.
Link: https://www.ti.com/product/INA4230
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
.../devicetree/bindings/hwmon/ti,ina4230.yaml | 134 +++++++++++++++++++++
MAINTAINERS | 6 +
2 files changed, 140 insertions(+)
diff --git a/Documentation/devicetree/bindings/hwmon/ti,ina4230.yaml b/Documentation/devicetree/bindings/hwmon/ti,ina4230.yaml
new file mode 100644
index 000000000000..d9b5f9857249
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/ti,ina4230.yaml
@@ -0,0 +1,134 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/ti,ina4230.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments INA4230 quad-channel power monitors
+
+maintainers:
+ - Alexey Charkov <alchark@flipper.net>
+
+description: |
+ The INA4230 is a 48V quad-channel 16-bit current, voltage, power and energy
+ monitor with an I2C interface.
+
+ Datasheet:
+ https://www.ti.com/product/INA4230
+
+properties:
+ compatible:
+ enum:
+ - ti,ina4230
+
+ reg:
+ maxItems: 1
+
+ "#address-cells":
+ description: Required only if a child node is present.
+ const: 1
+
+ "#size-cells":
+ description: Required only if a child node is present.
+ const: 0
+
+ vs-supply:
+ description: phandle to the regulator that provides the VS supply typically
+ in range from 1.7 V to 5.5 V.
+
+ ti,alert-polarity-active-high:
+ description: Alert pin is asserted based on the value of Alert polarity Bit
+ of the CONFIG2 register. Default value is 0, for which the alert pin
+ toggles from high to low during faults. When this property is set, the
+ corresponding register bit is set to 1, and the alert pin toggles from
+ low to high during faults.
+ $ref: /schemas/types.yaml#/definitions/flag
+
+patternProperties:
+ "^input@[0-3]$":
+ description: Optional subnodes for four input channels. Each subnode
+ describes one input channel. Input channels default to enabled in the
+ chip. Unless channels are explicitly disabled in device-tree, input
+ channels will be enabled.
+ type: object
+ additionalProperties: false
+ properties:
+ reg:
+ description: Must be 0, 1, 2 or 3, corresponding to the IN1, IN2, IN3
+ or IN4 ports of the INA4230, respectively.
+ enum: [ 0, 1, 2, 3 ]
+
+ label:
+ description: name of the input source
+
+ shunt-resistor-micro-ohms:
+ description: shunt resistor value in micro-Ohm
+
+ ti,maximum-expected-current-microamp:
+ description: |
+ This value indicates the maximum current in microamps that you can
+ expect to measure with ina4230 in your circuit.
+
+ This value will be used to calculate the Current_LSB to maximize the
+ available precision while ensuring your expected maximum current fits
+ within the chip's ADC range. It will also enable built-in shunt gain
+ to increase ADC granularity by a factor of 4 if the provided maximum
+ current / shunt resistance combination does not produce more than
+ 20.48 mV drop at the shunt.
+ minimum: 32768
+ maximum: 2147483647
+ default: 32768000
+
+ required:
+ - reg
+
+required:
+ - compatible
+ - reg
+
+allOf:
+ - $ref: hwmon-common.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ power-sensor@44 {
+ compatible = "ti,ina4230";
+ reg = <0x44>;
+ vs-supply = <&vdd_3v0>;
+ ti,alert-polarity-active-high;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ input@0 {
+ reg = <0x0>;
+ /*
+ * Input channels are enabled by default in the device and so
+ * to disable, must be explicitly disabled in device-tree.
+ */
+ status = "disabled";
+ };
+
+ input@1 {
+ reg = <0x1>;
+ shunt-resistor-micro-ohms = <50000>;
+ ti,maximum-expected-current-microamp = <300000>;
+ };
+
+ input@2 {
+ reg = <0x2>;
+ label = "VDD_5V";
+ shunt-resistor-micro-ohms = <10000>;
+ ti,maximum-expected-current-microamp = <5000000>;
+ };
+
+ input@3 {
+ reg = <0x3>;
+ };
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index ff935e197c21..acfa0b0585a5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12574,6 +12574,12 @@ S: Maintained
F: Documentation/hwmon/ina233.rst
F: drivers/hwmon/pmbus/ina233.c
+INA4230 HWMON DRIVER
+M: Alexey Charkov <alchark@flipper.net>
+L: linux-hwmon@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/hwmon/ti,ina4230.yaml
+
INDEX OF FURTHER KERNEL DOCUMENTATION
M: Carlos Bilbao <carlos.bilbao@kernel.org>
S: Maintained
--
2.52.0
^ permalink raw reply related
* [PATCH v5 0/2] Add support for Texas Instruments INA4230 power monitor
From: Alexey Charkov @ 2026-03-30 15:14 UTC (permalink / raw)
To: Guenter Roeck, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, devicetree, linux-kernel, Alexey Charkov,
Krzysztof Kozlowski
TI INA4230 is a 4-channel power monitor with I2C interface, similar in
operation to INA3221 (3-channel) and INA219 (single-channel) but with
a different register layout, different alerting mechanism and slightly
different support for directly reading calculated current/power/energy
values (pre-multiplied by the device itself and needing only to be scaled
by the driver depending on its selected LSB unit values).
In this initial implementation, the driver supports reading voltage,
current, power and energy values, but does not yet support alerts, which
can be added separately if needed. Also the overflows during hardware
calculations are not yet handled, nor is the support for the device's
internal 32-bit energy counter reset.
An example device tree using this binding and driver is available at [1]
(not currently upstreamed, as the device in question is in engineering
phase and not yet publicly available)
[1] https://github.com/flipperdevices/flipper-linux-kernel/blob/flipper-devel/arch/arm64/boot/dts/rockchip/rk3576-flipper-one-rev-f0b0c1.dts
Signed-off-by: Alexey Charkov <alchark@flipper.net>
---
Changes in v5:
- Reworded per-channel subnodes description in the binding for clarity (Sashiko)
- NB: Sashiko's suggestion to allow interrupts in the binding sounds premature,
as the alerts mechanism is not implemented yet and there are no known users
to test it. If anyone has hardware with the alert pins wired to an interrupt
line - please shout and we can test/extend it together
- Avoid division by zero when setting the conversion time with all inputs
disabled (Sashiko)
- Added the missed HWMON_I_ENABLE bits (Sashiko)
- Dropped extra sysfs attributes for reading/writing shunt values, as the
implementation was potentially racy and it's unlikely anyone would resolder
the shunts on a running system (Sashiko)
- Skip pm_runtime_put_noidle() for disabled (not just disconnected) channels
in remove and probe error path to avoid refcount underflow (Sashiko)
- Mark CONFIG2 register as volatile, as the reset bits in it are self-clearing
- NB: Sashiko's inquiry about the update interval being underreported due to
not accounting for the number of averaging samples: no, the hardware still
reports updates after each channels * (vbus_ct + vsh_ct), but the reported
value changes slowly due to the averaging
- NB: Sashiko's inquiry about regmap_noinc_read(): same as Guenter's AI
feedback. No, it doesn't break the byte order, as it uses byte-sized reads
- NB: Sashiko's inquiry about potential falling of ina->reg_config1 out of sync
with the hardware upon failed regmap_write() calls: yes, but it will be
written at the next successful write call, so the worst that can happen is
the averaging / conversion time can be wrong for a while. And it will return
a failed status for the failed write call too, so no big deal.
- NB: Sashiko's inquiry about reg_config1 not being written out during probe:
it is written out when the device is runtime-resumed as the refcount gets
incremented during the probe function
- Link to v4: https://lore.kernel.org/r/20260326-ina4230-v4-0-c1e312c09de7@flipper.net
Changes in v4:
- Aligned the maximum value of ti,maximum-expected-current-microamp property
in the binding with the one expected by the driver (Guenter Roeck)
"2147A ought to be enough for anybody (c)"
- Actually requested the optional vs-supply regulator in the driver (Guenter Roeck)
- Program the ALERT_POL bit according to the value of ti,alert-polarity-active-high
even though the alerts themselves are not yet implemented (Guenter Roeck)
- Added a check for manually disabled channels in the is_enabled() function to
avoid reading invalid data from them (Guenter Roeck)
- Dropped support for the single-shot mode as its operation is not clearly
documented in the datasheet and there is no pressing need to support it (Guenter Roeck)
- NB: AI feedback regarding regmap_noinc_read() producing incorrect byte order on LE
hosts is incorrect, as its implementation does a byte-wise read and doesn't care
about the regmap value width or endianness flags, so it produces a 4-byte output
buffer in the same byte order as the device returns, which is BE in this case
- NB: AI feedback regarding fail-path pm_runtime_put_noidle() potentially being
unbalanced if the probe loop failed early is technically correct but practically
irrelevant, as the driver will simply fail to load, and the usage count won't
decrease beyond zero anyway. The alternatives are cumbersome for no real benefit
- Link to v3: https://lore.kernel.org/r/20260310-ina4230-v3-0-06ab3a77c570@flipper.net
Changes in v3:
- Updated the description of the ti,maximum-expected-current-microamp property
in the binding to clarify how it is used, and drop the irrelevant mention of
the PMbus (Guenter Roeck)
- Use div64_u64() instead of do_div() for the final division in the calibration value
calculation to avoid overflows in the denominator (Guenter Roeck)
- Avoid overflow while scaling the voltage values on 32-bit platforms (Guenter Roeck)
- Use regmap_noinc_read() instead of regmap_raw_read() for reading the energy values
to ensure that the regmap / bus driver don't wander off to adjacent registers
during the read operation (on INA4230 the whole 32 bits should be read from
the same register offset) (Guenter Roeck)
- Remove redundant call to ina4230_set_calibration() in the current read path,
as the calibration value is already set when enabling the channel and restored
across PM changes via regcache_sync() (Guenter Roeck)
- Add missing write_enable() function to make hwmon_in_enable writes work as
advertised in is_visible() (Guenter Roeck)
- Add a check for disabled channels before calling pm_runtime_put_noidle() on them
to avoid refcount underflow due to imbalanced get_sync/put_noidle calls (Guenter Roeck)
- Dropped unused include of linux/debugfs.h
- Add missing return checks on regmap_write() calls
- uO -> uOhm in the error message to avoid confusion
- Move probe-time calibration after enabling runtime PM to avoid it being reverted
by the PM sync
- Link to v2: https://lore.kernel.org/r/20260302-ina4230-v2-0-55b49d19d2ab@flipper.net
Changes in v2:
- Replace u64/u64 division with do_div() (kernel test robot)
- Add an example with ti,maximum-expected-current-microamp property in
bindings (Krzysztof Kozlowski)
- Include the newly added binding in MAINTAINERS file (Krzysztof Kozlowski)
- Use dev_err_probe() where appropriate in the driver (Krzysztof Kozlowski)
- Switch to devm_regmap_field_bulk_alloc() instead of an open-coded loop
- Add a bounds check for the calculated calibration value,
and a corresponding error message
- Link to v1: https://lore.kernel.org/r/20260225-ina4230-v1-0-92b1de981d46@flipper.net
---
Alexey Charkov (2):
dt-bindings: hwmon: Add TI INA4230 4-channel I2C power monitor
hwmon: Add support for TI INA4230 power monitor
.../devicetree/bindings/hwmon/ti,ina4230.yaml | 134 +++
MAINTAINERS | 7 +
drivers/hwmon/Kconfig | 11 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/ina4230.c | 986 +++++++++++++++++++++
5 files changed, 1139 insertions(+)
---
base-commit: 3b058d1aeeeff27a7289529c4944291613b364e9
change-id: 20260219-ina4230-74a02409153d
Best regards,
--
Alexey Charkov <alchark@flipper.net>
^ permalink raw reply
* Re: [PATCH 4/8] drm/bridge: dw-hdmi: document the output_port field
From: Luca Ceresoli @ 2026-03-30 15:10 UTC (permalink / raw)
To: Damon Ding, Liu Ying, Marek Vasut, Stefan Agner,
Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, David Airlie,
Simona Vetter, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Rob Herring,
Saravana Kannan
Cc: Kory Maincent (TI.com), Hervé Codina, Hui Pu, Ian Ray,
Thomas Petazzoni, dri-devel, imx, linux-arm-kernel, linux-kernel,
devicetree, Adam Ford, Alexander Stein, Anson Huang,
Christopher Obbard, Daniel Scally, Emanuele Ghidoli,
Fabio Estevam, Francesco Dolcini, Frieder Schrempf, Gilles Talis,
Goran Rađenović, Heiko Schocher, Joao Paulo Goncalves,
Josua Mayer, Kieran Bingham, Marco Felsch, Martyn Welch,
Oleksij Rempel, Peng Fan, Philippe Schenker, Richard Hu,
Shengjiu Wang, Stefan Eichenberger, Vitor Soares
In-Reply-To: <4396e94d-7b88-4599-a938-3c1932a2f9cb@rock-chips.com>
Hello Damon,
On Mon Mar 30, 2026 at 3:13 AM CEST, Damon Ding wrote:
>>>>> diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
>>>>> index 336f062e1f9d..45f6ba1a8ee1 100644
>>>>> --- a/include/drm/bridge/dw_hdmi.h
>>>>> +++ b/include/drm/bridge/dw_hdmi.h
>>>>> @@ -126,6 +126,11 @@ struct dw_hdmi_phy_ops {
>>>>> struct dw_hdmi_plat_data {
>>>>> struct regmap *regm;
>>>>>
>>>>> + /*
>>>>> + * The HDMI output port number (which must be 1) if it is described
>>>>
>>>> I'd rephrase:
>>>> The HDMI output port number must be 1 ...
>>>>
>>>
>>> Yes, the output port number should be 1, but I found that the output
>>> port number in the Rockchip-side dw-hdmi driver remains 0.
>>
>> Really? I checked all the bindings in
>> Documentation/devicetree/bindings/display/rockchip/*hdmi* and all mention
>> port@1 as the output port number. Can you point to code using port@0 as the
>> output port?
>>
>> Should it be true, that would be unfortunate because the output_port
>> variable does not handle this case. It's used as a sort of bool-or-int
>> variable:
>>
>> * as a bool [0] to find out whether the DT is supposed to describe the
>> output port
>> * as an integer to tell the port number to parse in DT [1]
>>
>> So saying "please parse port 0" is impossible.
>>
>> [0] https://elixir.bootlin.com/linux/v7.0-rc5/source/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c#L3310
>> [1] https://elixir.bootlin.com/linux/v7.0-rc5/source/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c#L3315
>>
>
> Aha, my description might be a little misleading. The
> &dw_hdmi_plat_data.output_port is 0 on the Rockchip side, so the next
> bridge will not be parsed for it.
>
> Then I think the &dw_hdmi_plat_data.output_port should be 1, as this
> helps support the hdmi-connector and other bridge chips.
Ah, OK, that's all clear now.
> BTW: The Rockchip side dw-hdmi patches for bridge connector support will
> be updated as a follow-up to your patch series. :-)
Great! Don't forget to Cc me.
Luca
--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: [PATCH 10/16] clk: Add support for clock nexus dt bindings
From: Brian Masney @ 2026-03-30 15:09 UTC (permalink / raw)
To: Miquel Raynal (Schneider Electric)
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Olivia Mackall, Herbert Xu,
Jayesh Choudhary, David S. Miller, Christian Marangi,
Antoine Tenart, Geert Uytterhoeven, Magnus Damm, Thomas Petazzoni,
Pascal EBERHARD, Wolfram Sang, linux-clk, devicetree,
linux-kernel, linux-crypto, linux-renesas-soc, Herve Codina
In-Reply-To: <20260327-schneider-v7-0-rc1-crypto-v1-10-5e6ff7853994@bootlin.com>
On Fri, Mar 27, 2026 at 09:09:32PM +0100, Miquel Raynal (Schneider Electric) wrote:
> A nexus node is some kind of parent device abstracting the outer
> connections. They are particularly useful for describing connectors-like
> interfaces but not only. Certain IP blocks will typically include inner
> blocks and distribute resources to them.
>
> In the case of clocks, there is already the concept of clock controller,
> but this usually indicates some kind of control over the said clock,
> ie. gate or rate control. When there is none of this, an existing
> approach is to reference the upper clock, which is wrong from a hardware
> point of view.
>
> Nexus nodes are already part of the device-tree specification and clocks
> are already mentioned:
> https://github.com/devicetree-org/devicetree-specification/blob/v0.4/source/chapter2-devicetree-basics.rst#nexus-nodes-and-specifier-mapping
>
> Following the introductions of nexus nodes support for interrupts, gpios
> and pwms, here is the same logic applied again to the clk subsystem,
> just by transitioning from of_parse_phandle_with_args() to
> of_parse_phandle_with_args_map():
>
> * Nexus OF support:
> commit bd6f2fd5a1d5 ("of: Support parsing phandle argument lists through a nexus node")
> * GPIO adoption:
> commit c11e6f0f04db ("gpio: Support gpio nexus dt bindings")
> * PWM adoption:
> commit e71e46a6f19c ("pwm: Add support for pwm nexus dt bindings")
>
> Expected Nexus properties supported:
> - clock-map: maps inner clocks to inlet clocks,
> - clock-map-mask: specifier cell(s) which will be remapped,
> - clock-map-pass-thru: specifier cell(s) not used for remapping,
> forwarded as-is.
>
> In my own usage I had to deal with controllers where clock-map-mask and
> clock-map-pass-thru were not relevant, but here is a made up example
> showing how all these properties could go together:
>
> Example:
> soc_clk: clock-controller {
> #clock-cells = <2>;
> };
>
> container: container {
> #clock-cells = <2>;
> clock-map = <0 0 &soc_clk 2 0>,
> <1 0 &soc_clk 6 0>;
> clock-map-mask = <0xffffffff 0x0>;
> clock-map-pass-thru = <0x0 0xffffffff>;
>
> child-device {
> clocks = <&container 1 0>;
> /* This is equivalent to <&soc_clk 6 0> */
> };
> };
>
> The child device does not need to know about the outer implementation,
> and only knows about what the nexus provides. The nexus acts as a
> pass-through, with no extra control.
>
> Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
> Reviewed-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
^ permalink raw reply
* Re: [PATCH 0/4] ASoC: Add support for GPIOs driven amplifiers
From: Mark Brown @ 2026-03-30 15:08 UTC (permalink / raw)
To: Herve Codina
Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Saravana Kannan, Jaroslav Kysela, Takashi Iwai, linux-sound,
devicetree, linux-kernel, Christophe Leroy, Thomas Petazzoni
In-Reply-To: <20260330101610.57942-1-herve.codina@bootlin.com>
[-- Attachment #1: Type: text/plain, Size: 431 bytes --]
On Mon, Mar 30, 2026 at 12:16:04PM +0200, Herve Codina wrote:
> On some embedded system boards, audio amplifiers are designed using
> discrete components such as op-amp, several resistors and switches to
> either adjust the gain (switching resistors) or fully switch the
> audio signal path (mute and/or bypass features).
>
> Those switches are usually driven by simple GPIOs.
This sounds a lot like simple-amplifier.c?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: qcom: Add Motorola edge 30 (dubai) DTS
From: Val Packett @ 2026-03-30 15:03 UTC (permalink / raw)
To: Konrad Dybcio, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Kees Cook, Tony Luck,
Guilherme G. Piccoli
Cc: linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <5c0747dc-f0de-4b78-b0fd-8f6a6690e86c@oss.qualcomm.com>
On 3/30/26 7:03 AM, Konrad Dybcio wrote:
> On 3/29/26 12:16 PM, Val Packett wrote:
>> The Motorola edge 30 is a smartphone released in 2022.
>>
>> This commit has the following features working:
>> - Display (simplefb)
>> - Touchscreen
>> - Power and volume buttons
>> - Storage (UFS 3.1)
>> - Battery (ADSP battmgr)
>> - USB (Type-C, 2.0, dual-role)
>> - Wi-Fi and Bluetooth (WCN6750 hw1.0)
>>
>> Signed-off-by: Val Packett <val@packett.cool>
>> ---
> [...]
>
>> +/ {
>> + model = "Motorola edge 30";
> nit: Google tells me the 'e' in 'Edge' is uppercase
They do the lowercase thing a lot in the marketing materials but not
consistently. I guess it would make sense to ignore that and make it
uppercase, sure.
> [...]
>
>> + framebuffer0: framebuffer@e1000000 {
>> + compatible = "simple-framebuffer";
>> + reg = <0x0 0xe1000000 0x0 (1080 * 2400 * 4)>;
> Let's drop reg and use the memory-region binding (also drop unit address)
How come no one told be about memory-region for simplefb before? :D Ack
> [...]
>> + ports {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + port@0 {
>> + reg = <0>;
>> +
>> + pmic_glink_hs_in: endpoint {
>> + remote-endpoint = <&usb_1_dwc3_hs>;
>> + };
>> + };
>> +
>> + port@1 {
>> + reg = <1>;
> SBU would be @2
I was wondering about this, now I see it is specified in the bindings..
Looks like many other dts should be fixed too.
>> + cont-splash@e1000000 {
> framebuffer@
>
> [...]
>
>> + thermal-zones {
>> + cam-flash-thermal {
>> + polling-delay-passive = <0>;
> that's the default setting, you may drop all polling-delay(-passive) = <0>
ack
> [...]
>
>> +&usb_1 {
>> + /* USB 2.0 only */
>> + qcom,select-utmi-as-pipe-clk;
>> + maximum-speed = "high-speed";
>> +
>> + /* Remove USB3 phy */
>> + phys = <&usb_1_hsphy>;
>> + phy-names = "usb2-phy";
> Is it really not wired up in hw, or do you perhaps have a fake cable?
I didn't even try testing it myself since not even all flagships have
USB3 routed these days (hello oneplus) and this is a cheaper
upper-mid-range phone.
USB0_{SS_*,DP_*} are actually NC on the schematic,
and in downstream dts there is maximum-speed = "high-speed" and usb-phy
= hsphy + nop.
~val
^ permalink raw reply
* Re: [PATCH 09/16] clk: Use the generic OF phandle parsing in only one place
From: Brian Masney @ 2026-03-30 15:01 UTC (permalink / raw)
To: Miquel Raynal (Schneider Electric)
Cc: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Thomas Gleixner, Olivia Mackall, Herbert Xu,
Jayesh Choudhary, David S. Miller, Christian Marangi,
Antoine Tenart, Geert Uytterhoeven, Magnus Damm, Thomas Petazzoni,
Pascal EBERHARD, Wolfram Sang, linux-clk, devicetree,
linux-kernel, linux-crypto, linux-renesas-soc
In-Reply-To: <20260327-schneider-v7-0-rc1-crypto-v1-9-5e6ff7853994@bootlin.com>
On Fri, Mar 27, 2026 at 09:09:31PM +0100, Miquel Raynal (Schneider Electric) wrote:
> There should be one single entry in the OF world, so that the way we
> parse the DT is always the same. make sure this is the case by avoid
> calling of_parse_phandle_with_args() from of_clk_get_parent_name(). This
> is even more relevant as we currently fail to parse clock-ranges. As a
> result, it seems to be safer to directly call of_parse_clkspec() there.
>
> Suggested-by: Stephen Boyd <sboyd@kernel.org>
> Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>
> ---
> drivers/clk/clk.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 591c0780b61e..93e33ff30f3a 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -5375,8 +5375,7 @@ const char *of_clk_get_parent_name(const struct device_node *np, int index)
> int count;
> struct clk *clk;
>
> - rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
> - &clkspec);
> + rc = of_parse_clkspec(np, index, NULL, &clkspec);
> if (rc)
> return NULL;
Reviewed-by: Brian Masney <bmasney@redhat.com>
In case a Fixes tag is warranted, it's not exactly clear what should be
used. This was introduced in commit 766e6a4ec602 ("clk: add DT clock
binding support") in 2012. However of_parse_clkspec was introduced in
commit 4472287a3b2f5 ("clk: Introduce of_clk_get_hw_from_clkspec()") in
2018.
^ permalink raw reply
* Re: [PATCH v3 1/3] dt-bindings: arm: hpe,gxp: Add HPE GSC platform compatible
From: Krzysztof Kozlowski @ 2026-03-30 14:57 UTC (permalink / raw)
To: Hawkins, Nick
Cc: catalin.marinas@arm.com, will@kernel.org, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <DM4PR84MB192724F4949F614E3965E60A8852A@DM4PR84MB1927.NAMPRD84.PROD.OUTLOOK.COM>
On 30/03/2026 16:53, Hawkins, Nick wrote:
> Hi Krzysztof Kozlowski,
>
>>> maintainers:
>>> - Nick Hawkins <nick.hawkins@hpe.com>
>>> @@ -18,6 +18,11 @@ properties:
>>> - enum:
>>> - hpe,gxp-dl360gen10
>>> - const: hpe,gxp
>>> + - description: GSC Based Boards
>>> + items:
>>> + - enum:
>>> + - hpe,gsc-dl340gen12
>>> + - const: hpe,gsc
>
>> What sort of ordering are you going to use in this file? Usual choice is
>> the fallback compatible, but I see you have chosen something else. That
>> is fine, just keep that else sorting in the future instead of adding to
>> the end.
>
> Thank you for the feedback, just to confirm are you looking for me
> to do something like this?:
>
> - description: GSC Based Boards
> items:
> - enum:
> - hpe,gsc-dl340gen12
> - const: hpe,gsc
> - description: GXP Based Boards
> items:
> - enum:
> - hpe,gxp-dl360gen10
> - const: hpe,gxp
Yes, that's the typical/usual way.
>
> That way we have the newest first and going forward if there is
Usual order is the alphanumerical.
> something newer we add it to the top of the list rather than
> the bottom?
If you want to order by date of release of the SoC, that's fine. I think
Allwinner does it. It's pretty non obvious because the chips are
upstreamed different time than released, so it is difficult for people
knot knowing the release dates. Just don't use the rule of "add at the
beginning" or "at the end".
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v3 0/7] arm64: dts: ti: k3-am62a7-sk: Split r5f memory region
From: Mathieu Poirier @ 2026-03-30 14:56 UTC (permalink / raw)
To: Markus Schneider-Pargmann (TI)
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Suman Anna, Nishanth Menon, Vignesh Raghavendra, Tero Kristo,
Vishal Mahaveer, Kevin Hilman, Dhruva Gole, Sebin Francis,
Kendall Willis, Akashdeep Kaur, linux-remoteproc, devicetree,
linux-kernel, linux-arm-kernel
In-Reply-To: <20260318-topic-am62a-ioddr-dt-v6-19-v3-0-c41473cb23c3@baylibre.com>
On Wed, Mar 18, 2026 at 04:13:06PM +0100, Markus Schneider-Pargmann (TI) wrote:
> Hi,
>
> Split the firmware memory region in more specific parts so it is better
> described where which information is stored. Specifically the LPM metadata
> region is important as bootloader software like U-Boot has to know where
> that data is to be able to read that data and resume from RAM.
>
> IO+DDR is a deep sleep state in which a few pins are set to be sensitive
> for wakeup while the DDR is kept in self refresh. Everything else is
> powered off.
>
> The changes in this series were suggested as part of the IO+DDR u-boot series:
> https://lore.kernel.org/r/814c211f-a9eb-4311-bb84-165b1a69755f@ti.com
>
> There are currently no real users of the memory-region that is split in
> this series. The size of the memory-region in total stays the same.
> The new layout is derived from the software running on the r5f
> processor:
> https://github.com/TexasInstruments/mcupsdk-core-k3/blob/k3_main/examples/drivers/ipc/ipc_rpmsg_echo_linux/am62ax-sk/r5fss0-0_freertos/ti-arm-clang/linker.cmd#L172
> https://github.com/TexasInstruments/mcupsdk-core-k3/blob/k3_main/source/drivers/device_manager/sciclient.h#L459
>
> Additionally the two important devicetree nodes for resuming from IO+DDR
> have the bootph-pre-ram flag added as this data needs to be read before
> the RAM is in use.
>
> Best
> Markus
>
> Signed-off-by: Markus Schneider-Pargmann (TI) <msp@baylibre.com>
> ---
> Changes in v3:
> - Squash the enforcement of the memory-region-names requirement in the
> patch adding the memory-region-names, as suggested.
> - Link to v2: https://lore.kernel.org/r/20260312-topic-am62a-ioddr-dt-v6-19-v2-0-37cb7ceec658@baylibre.com
>
> Changes in v2:
> - Make memory-region-names required if memory-region is present
> - Fixup memory-region and memory-region-names conditions. Require either
> 2 or 6 regions for memory-region and memory-region-names
> - Reword and restructure the binding documentation for memory-region and
> memory-region-names
> - Add memory-region-names to all uses of memory-region
> - Link to v1: https://lore.kernel.org/r/20260303-topic-am62a-ioddr-dt-v6-19-v1-0-12fe72bb40d2@baylibre.com
>
> ---
> Markus Schneider-Pargmann (TI) (7):
> dt-bindings: remoteproc: k3-r5f: Split up memory regions
> dt-bindings: remoteproc: k3-r5f: Add memory-region-names
I have picked-up the above two. The .dtsi files need to go through the TI
tree.
Thanks,
Mathieu
> arm64: dts: ti: k3: Use memory-region-names for r5f
> arm64: dts: ti: k3-am62a7-sk: Split r5f memory region
> arm64: dts: ti: k3-am62p5-sk: Split r5f memory region
> arm64: dts: ti: k3-am62a7-sk: Add r5f nodes to pre-ram bootphase
> arm64: dts: ti: k3-am62p5-sk: Add r5f nodes to pre-ram bootphase
>
> .../bindings/remoteproc/ti,k3-r5f-rproc.yaml | 55 ++++++++++++++++++----
> .../arm64/boot/dts/ti/k3-am62-ti-ipc-firmware.dtsi | 1 +
> .../boot/dts/ti/k3-am62a-ti-ipc-firmware.dtsi | 2 +
> arch/arm64/boot/dts/ti/k3-am62a7-sk.dts | 42 ++++++++++++++++-
> .../boot/dts/ti/k3-am62p-ti-ipc-firmware.dtsi | 2 +
> arch/arm64/boot/dts/ti/k3-am62p5-sk.dts | 42 ++++++++++++++++-
> .../arm64/boot/dts/ti/k3-am64-ti-ipc-firmware.dtsi | 4 ++
> .../arm64/boot/dts/ti/k3-am65-ti-ipc-firmware.dtsi | 2 +
> .../boot/dts/ti/k3-j7200-ti-ipc-firmware.dtsi | 4 ++
> .../boot/dts/ti/k3-j721e-ti-ipc-firmware.dtsi | 6 +++
> .../boot/dts/ti/k3-j721s2-ti-ipc-firmware.dtsi | 6 +++
> .../boot/dts/ti/k3-j722s-ti-ipc-firmware.dtsi | 3 ++
> .../k3-j784s4-j742s2-ti-ipc-firmware-common.dtsi | 8 ++++
> 13 files changed, 163 insertions(+), 14 deletions(-)
> ---
> base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
> change-id: 20260210-topic-am62a-ioddr-dt-v6-19-0da7712081d7
>
> Best regards,
> --
> Markus Schneider-Pargmann (TI) <msp@baylibre.com>
>
^ permalink raw reply
* Re: [PATCH 2/5] dt-bindings: clock: qcom,milos-camcc: Document interconnect path
From: Luca Weiss @ 2026-03-30 14:55 UTC (permalink / raw)
To: Mike Tipton, Konrad Dybcio
Cc: Krzysztof Kozlowski, Luca Weiss, Taniya Das, Georgi Djakov,
Bjorn Andersson, Michael Turquette, Stephen Boyd, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, ~postmarketos/upstreaming,
phone-devel, linux-pm, linux-kernel, linux-arm-msm, linux-clk,
devicetree
In-Reply-To: <acH7aEBvSbiNwhBz@hu-mdtipton-lv.qualcomm.com>
Hi Mike,
On Tue Mar 24, 2026 at 3:48 AM CET, Mike Tipton wrote:
> On Mon, Jan 19, 2026 at 11:28:07AM +0100, Konrad Dybcio wrote:
>>
>>
>> On 1/19/26 11:20 AM, Konrad Dybcio wrote:
>> > On 1/17/26 12:46 PM, Krzysztof Kozlowski wrote:
>> >> On Fri, Jan 16, 2026 at 02:17:21PM +0100, Luca Weiss wrote:
>> >>> Document an interconnect path for camcc that's required to enable
>> >>> the CAMSS_TOP_GDSC power domain.
>> >>
>> >> I find it confusing. Enabling GDSC power domains is done via power
>> >> domains, not via interconnects. Do not represent power domains as
>> >> interconnects, it's something completely different.
>> >
>> > The name of the power domains is CAMSS_TOP_GDSC (seems you misread)
>> >
>> > For the power domain to successfully turn on, the MNoC needs to be
>> > turned on (empirical evidence). The way to do it is to request a
>> > nonzero vote on this interconnect path
>> >
>> > (presumably because the GDSC or its invisible providers require
>> > something connected over that bus to carry out their enable sequences).
>
> The GDSC itself shouldn't depend on MMNOC in order to turn on properly.
> It should turn on just fine without it. There *is* a dependency between
> CAM_TOP_GDSC and MMNOC, but it's in the opposite direction.
I can personally just write from practical experience, as Qualcomm
doesn't share any relevant documentation with OEMs.
Without this patch the GDSC refuses to turn on.
[ 291.055839] ------------[ cut here ]------------
[ 291.055860] cam_cc_camss_top_gdsc status stuck at 'off'
[ 291.055878] WARNING: drivers/clk/qcom/gdsc.c:178 at gdsc_toggle_logic+0x138/0x144, CPU#4: hexdump/1995
With the patch it turns on just fine, no issues seen.
As Konrad has written, originally I didn't see any issue because that
interconnect was being kept alive by simple-framebuffer where I've added
'interconnects' to keep the framebuffer alive. However when testing
without this, the GDSC would refuse to turn on, which led me to this
patch series.
Additionally you can see in downstream devicetree you can also see an
interconnect defined for the "cam_cc_camss_top_gdsc" node:
https://gerrit-public.fairphone.software/plugins/gitiles/platform/vendor/qcom/proprietary/devicetree/+/refs/heads/odm/rc/target/15/fp6/fps_overlay/volcano.dtsi#2943
Regards
Luca
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox