* Re: [PATCH 3/3] hwmon: (pmbus/fd5121): Add support FD5121, FD5123 and FD5125
From: sashiko-bot @ 2026-06-23 6:07 UTC (permalink / raw)
To: Selvamani Rajagopal via B4 Relay; +Cc: conor+dt, linux-hwmon, devicetree, robh
In-Reply-To: <20260622-support-fd5121-from-onsemi-v1-3-b31767689c65@onsemi.com>
Thank you for your contribution! Sashiko AI review found 10 potential issue(s) to consider:
- [High] Directly exposing PMBUS_PAGE and paged PMBus registers via custom lockless sysfs attributes bypasses PMBus core locking and page caching, causing race conditions and hardware state corruption.
- [High] Incorrect mathematical conversion of READ_VOUT to AMD 6.25mV VIDs causes voltage read failures > 1.55V and applies dangerously incorrect voltages on writes.
- [High] The `svr_go` sysfs attribute ignores its mapped register index, allowing userspace to execute arbitrary PMBus/I2C Send Byte commands.
- [High] The I2C block read fallback in `fd5121_read_block_data` corrupts the payload by reading one byte too few and shifting uninitialized memory into the result.
- [High] The I2C block write fallback in `fd5121_write_block_data` omits the required PMBus length byte, corrupting write transactions.
- [Medium] Attempting to read 164/165 bytes for OTP/RAM using standard SMBus/I2C block read functions results in silent truncation to 32 bytes.
- [Medium] `fd5121_word_store` parses user input as a signed 16-bit integer, preventing valid unsigned PMBus values from being written.
- [Medium] The custom `clear_faults` sysfs attribute sends an invalid data payload for a standard PMBus Send Byte command.
- [Medium] The driver violates the hwmon subsystem ABI by exposing over 80 standard PMBus registers as custom raw sysfs attributes.
- [Medium] `fd5121_probe` enforces an overly restrictive `I2C_FUNC_I2C` check, breaking compatibility with standard SMBus controllers.
--
commit 1e218fd27c0a9b6bb8fade016af8d29cbdb6daa5
Author: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
hwmon: (pmbus/fd5121): Add support FD5121, FD5123 and FD5125
FD5121 is a dual-rail, multi-phase, digital controller that offers
full telemtry options including input/output voltage, current as
well as fault handling and identifications.
These controllers are compliant with PMBus specification.
> diff --git a/drivers/hwmon/pmbus/fd5121.c b/drivers/hwmon/pmbus/fd5121.c
> new file mode 100644
> index 0000000000000..e68c6d6cabbd9
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/fd5121.c
[ ... ]
> +static s32 fd5121_read_block_data(const struct i2c_client *client,
> + u8 cmd_code, u8 len, u8 *pbuf)
> +{
> + s32 ret = 0;
> +
> + if (!i2c_check_functionality(client->adapter,
> + I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
> +
> + /* Payload length is in the first byte. */
> + ret = i2c_smbus_read_i2c_block_data(client, cmd_code,
> + len, pbuf);
> + if (ret < 0)
> + return ret;
> + ret = pbuf[0];
> + if (ret > len)
> + ret = len;
> + for (int idx = 0; idx < ret; idx++)
> + pbuf[idx] = pbuf[idx + 1];
> + return ret;
[Severity: High]
Does this fallback logic corrupt the payload by reading one byte too few?
Since the device replies with an SMBus block read format (a length byte
followed by the payload), requesting exactly len bytes retrieves the length
byte and only len - 1 data bytes.
This means the last byte of the payload is dropped, and the subsequent
left-shift copies a trailing uninitialized byte into the final payload
position. Should it request len + 1 bytes instead?
[ ... ]
> +static ssize_t fd5121_send_byte_store(struct device *dev,
> + struct device_attribute *da,
> + const char *buf, size_t count)
> +{
> + struct i2c_client *client = to_i2c_client(dev->parent);
> + u8 val = 0;
> + int ret;
> +
> + ret = kstrtou8(buf, 10, &val);
> + if (ret < 0)
> + return ret;
> + ret = i2c_smbus_write_byte(client, val);
[Severity: High]
Does this allow userspace command injection?
This attribute is mapped to PMBUS_REG_MFR_SVR_GO, but it parses the
user-provided string into val and directly sends that as the SMBus command
code, completely ignoring attr->index. This allows any arbitrary command
code to be broadcast instead of SVR_GO.
[ ... ]
> +static ssize_t fd5121_byte_store(struct device *dev,
> + struct device_attribute *da,
> + const char *buf, size_t count)
> +{
> + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> + struct i2c_client *client = to_i2c_client(dev->parent);
> + u8 reg = attr->index;
> + int ret = 0;
> + u8 val = 0;
> +
> + switch (reg) {
> + case PMBUS_REG_MFR_CONFIG_ACTIVATE:
> + ret = fd5121_config_activate(client);
> + if (ret < 0)
> + return ret;
> + return count;
> + default:
> + ret = kstrtou8(buf, 10, &val);
> + if (ret < 0)
> + return ret;
> + break;
> + }
> + if (reg == PMBUS_PAGE && ((val != 0 && val != 1 &&
> + val != GENMASK(7, 0))))
> + return -EINVAL;
> + ret = i2c_smbus_write_byte_data(client, reg, val);
[Severity: High]
Can writing to the PMBUS_PAGE attribute directly corrupt the PMBus core's
page tracking?
By modifying the physical hardware's page using raw i2c_smbus_write_byte_data
instead of the PMBus core accessors, the core's cached data->currpage
becomes out of sync. Subsequent accesses by the PMBus core could execute
on the wrong hardware rail.
[Severity: Medium]
Additionally, if this is used to send PMBUS_CLEAR_FAULTS, does it violate
the PMBus specification?
CLEAR_FAULTS is strictly a Send Byte command with no data payload, but
i2c_smbus_write_byte_data() transmits an extra data byte.
[ ... ]
> +static ssize_t fd5121_word_store(struct device *dev,
> + struct device_attribute *da,
> + const char *buf, size_t count)
> +{
> + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> + struct i2c_client *client = to_i2c_client(dev->parent);
> + u8 reg = attr->index;
> + s16 val = 0;
> + int ret = 0;
> +
> + switch (reg) {
> + case PMBUS_REG_MFR_PWD_PROGRAM_RAM:
> + val = 0xC93F;
> + break;
> + default:
> + ret = kstrtos16(buf, 10, &val);
[Severity: Medium]
Does using kstrtos16() prevent configuring valid unsigned PMBus word values?
PMBus word registers represent 16-bit unsigned integers, but parsing
them as a signed s16 causes any valid input between 32768 and 65535 to
be rejected with an -ERANGE error.
[ ... ]
> +static ssize_t fd5121_word_show(struct device *dev,
> + struct device_attribute *da, char *buf)
> +{
> + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> + struct i2c_client *client = to_i2c_client(dev->parent);
> + u8 data[I2C_SMBUS_BLOCK_MAX] = { 0 };
> + u8 reg = attr->index;
> + s32 ret = 0;
> +
> + if (fd5121_blk_rd_reg(reg)) {
> + ret = fd5121_read_block_data(client, reg, 2, data);
> + if (ret >= 0)
> + ret = get_unaligned_le16(data);
> + } else
> + ret = i2c_smbus_read_word_data(client, reg);
[Severity: High]
Does this direct sysfs read lead to a race condition with the PMBus core?
Since these paged registers are read directly via i2c_smbus_read_word_data
without acquiring data->update_lock or ensuring the correct page is active,
concurrent PMBus operations could cause this to read from the wrong rail.
[ ... ]
> +static s32 fd5121_write_block_data(const struct i2c_client *client,
> + u8 cmd_code, u8 len, u8 *pbuf)
> +{
> + s32 ret = 0;
> +
> + if (!i2c_check_functionality(client->adapter,
> + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
> + ret = i2c_smbus_write_i2c_block_data(client, cmd_code,
> + len, pbuf);
[Severity: High]
Does this I2C block write fallback omit the mandatory PMBus length byte?
Unlike the SMBus equivalent, the I2C block write API does not prepend
a length byte on the wire. Without this length byte, the hardware will
misinterpret the first data byte (pbuf[0]) as the length, corrupting
the data payload.
[ ... ]
> +static ssize_t fd5121_block_show(struct device *dev,
> + struct device_attribute *da, char *buf)
> +{
> + struct i2c_client *client = to_i2c_client(dev->parent);
> + struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
> + u8 buffer[I2C_SMBUS_BLOCK_MAX] = { 0 };
> + u8 reg = attr->index;
> + int printed = 0;
> + s32 ret = 0;
> + u8 len = 0;
> + int i = 0;
> +
> + if (reg == PMBUS_REG_MFR_FAULTY_SPS) {
> + int to_print = 0;
> +
> + len = 7;
> + ret = fd5121_read_block_data(client, reg, len, buffer);
> + if (ret < 0)
> + return ret;
> + printed = 0;
> + to_print = (ret < len) ? ret : len;
> + for (i = 0; i < to_print; i++)
> + printed += scnprintf(buf + printed,
> + PAGE_SIZE - printed,
> + "%02x", buffer[i]);
> + printed += scnprintf(buf + printed,
> + PAGE_SIZE - printed, "\n");
> + return printed;
> + } else if (reg == PMBUS_REG_BBR_RAM ||
> + reg == PMBUS_REG_BBR_OTP) {
> + u32 len = (reg == PMBUS_REG_BBR_OTP) ? 165 : 164;
> +
> + /* Extra byte may be needed in case we need to store
> + * the length of the data
> + */
> + u8 *tmp_in = kcalloc(len+1, sizeof(u8), GFP_KERNEL);
> +
> + if (tmp_in == NULL)
> + return -ENOMEM;
> + ret = fd5121_read_block_data(client, reg, len, tmp_in);
[Severity: Medium]
Will this operation silently truncate the read to 32 bytes?
The requested lengths are 164 and 165, but the underlying I2C/SMBus
block read functions (i2c_smbus_read_block_data and its I2C fallback)
are strictly capped at I2C_SMBUS_BLOCK_MAX (32 bytes).
[ ... ]
> +static struct attribute *fd5121_paged_attrs[] = {
> + &sensor_dev_attr_operation.dev_attr.attr,
> + &sensor_dev_attr_vout_raw.dev_attr.attr,
> + &sensor_dev_attr_on_off_config.dev_attr.attr,
> + &sensor_dev_attr_clear_faults.dev_attr.attr,
> + &sensor_dev_attr_write_protect.dev_attr.attr,
> + &sensor_dev_attr_smbalert_mask.dev_attr.attr,
> + &sensor_dev_attr_vout_mode.dev_attr.attr,
> + &sensor_dev_attr_vout_command.dev_attr.attr,
[Severity: Medium]
Is it intentional to expose standard PMBus registers as raw custom sysfs
files here?
Defining over 80 standard PMBus commands (like vout_command, operation,
clear_faults) as custom attributes bypasses the standardized hwmon ABI
(e.g., in1_input). The PMBus core framework automatically translates
these standard features into the required ABI format.
[ ... ]
> +static int fd5121_read_word_data(struct i2c_client *client, int page,
> + int phase, int reg)
> +{
> + int ret;
> +
> + ret = fd5121_valid_reg(client, reg);
> + if (ret < 0)
> + return ret;
> +
> + ret = pmbus_read_word_data(client, page, phase, reg);
> + if (ret < 0)
> + return ret;
> +
> + /* Chip reports VOUT_MODE as vid. But gives raw value 1mV per bit.
> + * So, encode the READ_VOUT value so that it gets decoded and
> + * reported correctly.
> + */
> + if (reg == PMBUS_READ_VOUT)
> + ret = DIV_ROUND_CLOSEST(155000 - ret * 100, 625);
> + return ret;
> +}
[Severity: High]
Does this calculation fail for voltages above 1.55V?
Since the raw VOUT is 1mV per bit, if ret is greater than 1550, the
numerator (155000 - ret * 100) evaluates to a negative number. The PMBus
core will interpret this negative value as an error code (e.g., -72),
causing sysfs reads to fail.
> +static int fd5121_write_word_data(struct i2c_client *client, int page,
> + int reg, u16 word)
> +{
> + int ret;
> +
> + ret = fd5121_valid_reg(client, reg);
> + if (ret < 0)
> + return ret;
> + ret = pmbus_write_word_data(client, page, reg, word);
> + return ret;
> +}
[Severity: High]
Is there a missing reverse translation for PMBUS_VOUT_COMMAND?
Because info->vrm_version[idx] = amd625mv is declared, the PMBus core
translates requested voltages into AMD VIDs and sends them here. Without
an inverse translation to the hardware's native 1mV/bit format, a VID
like 88 would be written directly, severely undervolting the hardware
to 88mV.
[ ... ]
> +static int fd5121_probe(struct i2c_client *client)
> +{
> + struct pmbus_driver_info *info;
> + struct fd5121_data *pdata;
> + u32 id;
> +
> + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
> + return -EOPNOTSUPP;
[Severity: Medium]
Does this unconditionally break compatibility with pure SMBus controllers?
Many standard PC and server host controllers only support SMBus operations
and do not set the I2C_FUNC_I2C flag. Since the driver heavily utilizes
SMBus commands, checking for full I2C functionality might prevent the driver
from probing on common hardware.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-support-fd5121-from-onsemi-v1-0-b31767689c65@onsemi.com?part=3
^ permalink raw reply
* Re: [PATCH 2/3] dt-bindings: hwmon: pmbus: Support for onsemi's FD5121
From: sashiko-bot @ 2026-06-23 6:05 UTC (permalink / raw)
To: Selvamani Rajagopal via B4 Relay; +Cc: conor+dt, robh, devicetree, linux-hwmon
In-Reply-To: <20260622-support-fd5121-from-onsemi-v1-2-b31767689c65@onsemi.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] The binding lacks a `regulators` node definition, preventing it from functioning as a voltage regulator provider in devicetree.
- [Low] The devicetree example uses a specific model name for the node instead of a generic name.
--
commit 52162fef263cc41ea7598b089db89b70bb4f6ebb
Author: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
dt-bindings: hwmon: pmbus: Support for onsemi's FD5121
This commit adds the devicetree schema for onsemi FD5121, FD5123, and FD5125
dual rail, multi-phase digital controllers.
> diff --git a/Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml b/Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml
> new file mode 100644
> index 0000000000000..b0453b0634f0d
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml
> @@ -0,0 +1,41 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
[ ... ]
> +required:
> + - compatible
> + - reg
> +
> +additionalProperties: false
[Severity: Medium]
Since this device is a multi-phase digital controller, should it have a
regulators subnode pattern?
The additionalProperties: false constraint strictly prohibits developers from
defining regulator constraints in their device trees. As the PMBus core
framework looks for the regulators child node, would it be better to add an
explicit pattern here to allow consumers to reference the device's voltage
rails?
> +
> +examples:
> + - |
> + i2c {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + fd5121@50 {
[Severity: Low]
Is it possible to use a generic node name here like regulator@50, pmic@50, or
sensor@50 instead of the specific model name fd5121@50?
The Devicetree specification recommends generic node names to ensure standard
patterns are used in examples.
> + compatible = "onnn,fd5121";
> + reg = <0x50>;
> + };
> + };
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-support-fd5121-from-onsemi-v1-0-b31767689c65@onsemi.com?part=2
^ permalink raw reply
* Re: [PATCH v3 3/3] arm64: dts: amlogic: meson-axg: Disable pcie_phy node by default
From: Jun Yan @ 2026-06-23 6:05 UTC (permalink / raw)
To: sashiko-bot
Cc: conor+dt, devicetree, jerrysteve1101, linux-amlogic,
neil.armstrong, robh, sashiko-reviews
In-Reply-To: <20260617083401.8777A1F000E9@smtp.kernel.org>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] Enabling `pcie_phy` on `meson-axg-s400.dts` is insufficient to support PCIe functionality because its hardware dependency `mipi_pcie_analog_dphy` remains disabled.
> --
>
> commit cd94d06969e9f9a23ea319f406b8e86e8ed9ec44
> Author: Jun Yan <jerrysteve1101@gmail.com>
>
> arm64: dts: amlogic: meson-axg: Disable pcie_phy node by default
>
> This patch disables the pcie_phy node by default in the meson-axg dtsi file
> to suppress deferred probe warnings on boards that do not use it. It then
> explicitly enables pcie_phy in the meson-axg-s400 board device tree to
> preserve its PCIe functionality.
>
> > diff --git a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> > index 285c6ac1dd613..7ba249cc3d569 100644
> > --- a/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
> > +++ b/arch/arm64/boot/dts/amlogic/meson-axg-s400.dts
>
> [ ... ]
>
> > @@ -448,6 +448,10 @@ &pcieB {
> > status = "okay";
> > };
> >
> > +&pcie_phy {
> > + status = "okay";
> > +};
>
> [Severity: High]
> This is a pre-existing issue, but is it sufficient to only enable pcie_phy
> to restore PCIe functionality on the s400 board?
>
> The pcie_phy node depends on the mipi_pcie_analog_dphy analog PHY via its
> phys property. Looking at meson-axg.dtsi, mipi_pcie_analog_dphy is disabled
> by default:
>
> arch/arm64/boot/dts/amlogic/meson-axg.dtsi:
> mipi_pcie_analog_dphy: phy {
> compatible = "amlogic,axg-mipi-pcie-analog-phy";
> #phy-cells = <0>;
> status = "disabled";
> };
>
> If the analog PHY is not also overridden to "okay" here in meson-axg-s400.dts,
> will the analog PHY driver fail to probe, causing devm_phy_get(dev, "analog")
> in the pcie_phy driver to continually return -EPROBE_DEFER?
>
I'd like to add an additional patch to resolve this pre-existing issue reported by Sashiko.
Unfortunately I don't have S400 hardware available for testing.
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260617082239.645562-1-jerrysteve1101@gmail.com?part=3
^ permalink raw reply
* Re: [PATCH v4 2/4] PCI: rzg3s-host: Use shared reset controls for power domain resets
From: Manivannan Sadhasivam @ 2026-06-23 6:04 UTC (permalink / raw)
To: Lad, Prabhakar
Cc: Philipp Zabel, Claudiu Beznea, Lorenzo Pieralisi,
Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas,
Krzysztof Kozlowski, Conor Dooley, Geert Uytterhoeven,
Magnus Damm, linux-pci, linux-renesas-soc, devicetree,
linux-kernel, Biju Das, Fabrizio Castro, Lad Prabhakar
In-Reply-To: <CA+V-a8sRxoR96TRM2V3cFXS5NPiQUVrUJCWwkh7o10cGYPU9_w@mail.gmail.com>
On Mon, Jun 22, 2026 at 03:53:57PM +0100, Lad, Prabhakar wrote:
> Hi Manivannan,
>
> On Mon, Jun 22, 2026 at 3:30 PM Manivannan Sadhasivam <mani@kernel.org> wrote:
> >
> > On Fri, Jun 05, 2026 at 12:54:46PM +0100, Lad, Prabhakar wrote:
> > > Hi Philipp,
> > >
> > > Thank you for the review.
> > >
> > > On Wed, Jun 3, 2026 at 9:16 AM Philipp Zabel <p.zabel@pengutronix.de> wrote:
> > > >
> > > > On Di, 2026-06-02 at 20:50 +0100, Prabhakar wrote:
> > > > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> > > > >
> > > > > Switch to shared reset controls for PCIe power resets to prepare for
> > > > > RZ/V2H(P) support. On this platform, multiple PCIe controllers share
> > > > > the same reset line, requiring shared ownership of the reset control.
> > > > >
> > > > > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
> > > > > Reviewed-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> > > > > Tested-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
> > > > > ---
> > > > > v3->v4:
> > > > > - Added RB/TB tags.
> > > > >
> > > > > v2->v3:
> > > > > - No change.
> > > > >
> > > > > v1->v2:
> > > > > - Updated commit message.
> > > > > ---
> > > > > drivers/pci/controller/pcie-rzg3s-host.c | 6 +++---
> > > > > 1 file changed, 3 insertions(+), 3 deletions(-)
> > > > >
> > > > > diff --git a/drivers/pci/controller/pcie-rzg3s-host.c b/drivers/pci/controller/pcie-rzg3s-host.c
> > > > > index d86e7516dcc2..a5192e4b58df 100644
> > > > > --- a/drivers/pci/controller/pcie-rzg3s-host.c
> > > > > +++ b/drivers/pci/controller/pcie-rzg3s-host.c
> > > > > @@ -1276,9 +1276,9 @@ static int rzg3s_pcie_resets_prepare_and_get(struct rzg3s_pcie_host *host)
> > > > > for (i = 0; i < data->num_cfg_resets; i++)
> > > > > host->cfg_resets[i].id = data->cfg_resets[i];
> > > > >
> > > > > - ret = devm_reset_control_bulk_get_exclusive(host->dev,
> > > > > - data->num_power_resets,
> > > > > - host->power_resets);
> > > > > + ret = devm_reset_control_bulk_get_shared(host->dev,
> > > > > + data->num_power_resets,
> > > > > + host->power_resets);
> > > > > if (ret)
> > > > > return ret;
> > > > >
> > > >
> > > > I have a few questions about this.
> > > >
> > > > Can you move rzg3s_pcie_resets_prepare_and_get() and
> > > > rzg3s_pcie_power_resets_deassert() up before setting
> > > > RZG3S_SYSC_FUNC_ID_MODE and RZG3S_SYSC_FUNC_ID_RST_RSM_B in
> > > > rzg3s_pcie_probe() without ill effect?
> > > >
> > > > Can you move rzg3s_pcie_power_resets_deassert() up before setting
> > > > RZG3S_SYSC_FUNC_ID_MODE and RZG3S_SYSC_FUNC_ID_RST_RSM_B
> > > > rzg3s_pcie_resume_noirq()?
> > > >
> > > > Those would have the same effect as the reset already being deasserted
> > > > by the other controller.
> > > >
> > > Yes to both. I have reordered the sequences as suggested, and it works
> > > perfectly without any ill effects.
> > >
> >
> > Are you going to respin the patches incorporating the review comments?
> >
> If I have not mistaken, no code changes were requested; it was just
> that Philipp wanted to ensure the shared reset worked correctly after
> shuffling the code around.
>
Ah, I was mistaken.
> I can respin the series if it fails to apply on top of pci/next.
>
Sure. Please respin once v7.2-rc1 is released.
- Mani
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH 1/3] Documentation/hwmon: Add onsemi's FD5121 controllers' documentation
From: sashiko-bot @ 2026-06-23 5:59 UTC (permalink / raw)
To: Selvamani Rajagopal via B4 Relay; +Cc: robh, devicetree, conor+dt, linux-hwmon
In-Reply-To: <20260622-support-fd5121-from-onsemi-v1-1-b31767689c65@onsemi.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Low] Sysfs attribute descriptions contain mismatched input/output semantics due to copy-paste errors.
- [Low] Incomplete sentence missing a trailing period.
--
commit 10fc2806e78d641ce1fc7f05d01f0cec8dcccbe0
Author: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Documentation/hwmon: Add onsemi's FD5121 controllers' documentation
This commit documents the hardware monitoring support for FD5121, FD5123,
and FD5125 devices. It describes the supported telemetry data exposed via
sysfs, including voltage, current, power, and temperature measurements.
> diff --git a/Documentation/hwmon/fd5121.rst b/Documentation/hwmon/fd5121.rst
> new file mode 100644
> index 0000000000000..c279db4641e4a
> --- /dev/null
> +++ b/Documentation/hwmon/fd5121.rst
[ ... ]
> +Usage Notes
> +-----------
> +
> +This driver does not probe for PMBus devices. You will have
> +to instantiate devices explicitly.
> +
> +Example: the following commands will load the driver for the
> +controller at address 0x50 on I2C bus #1::
> +
> + # modprobe fd5121
> + # echo fd5121 0x50 > /sys/bus/i2c/devices/i2c-1/new_device
> +
> +It can also be instantiated by declaring in device tree
[Severity: Low]
This isn't a bug, but this sentence ends abruptly without a trailing period.
> +Sysfs attributes
> +----------------
> +
> +The following attributes are supported:
> +
> +====================== ====================================
> +curr[1-2]_label "iin[1-2]"
> +curr[3-4]_label "iout[1-2]"
> +curr[1-2]_input Measured input current.
> +curr[3-4]_input Measured output current.
> +curr[1-4]_crit_alarm Output current critical high alarm.
> +curr[1-4]_max_alarm Output current high alarm.
[Severity: Low]
Are the alarm descriptions for curr[1-2] accurate? Since curr[1-2] are labeled
as input current, should their alarms be described as input current alarms
instead of output current alarms?
> +
> +in[1-2]_label "vin[1-2]"
> +in[3-4]_label "vout[1-2]"
> +in[1-4]_lcrit_alarm Input voltage critical low alarm.
> +in[1-4]_crit_alarm Input voltage critical high alarm.
[Severity: Low]
Similarly, are the alarm descriptions for in[3-4] correct? They are labeled as
output voltage, but their alarms are described as input voltage alarms.
> +in[1-2]_max_alarm Input voltage high alarm.
> +in[1-2]_input Measured input voltage.
> +in[3-4]_input Measured output voltage.
> +
> +power[1-2]_label "pin[1-2]"
> +power[3-4]_label "pout[1-2]"
> +power[3-4]_crit_alarm Output power critical high alarm.
> +power[1-2]_max_alarm Output power high alarm.
[Severity: Low]
Should power[1-2]_max_alarm be described as an input power high alarm, given
that power[1-2] represents input power?
> +power[1-4]_max Power limit.
> +power[1-4]_input Measured input power.
[Severity: Low]
Does power[3-4]_input actually measure input power? Given that power[3-4] is
labeled as output power, shouldn't this be described as measured output power?
> +power[3-4]_crit Critical maximum output power.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260622-support-fd5121-from-onsemi-v1-0-b31767689c65@onsemi.com?part=1
^ permalink raw reply
* [PATCH] dt-bindings: clock: Replace bouncing emails
From: Krzysztof Kozlowski @ 2026-06-23 5:56 UTC (permalink / raw)
To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sylwester Nawrocki, Chanwoo Choi, Peter Griffin, Alim Akhtar,
Barnabas Czeman, Tomasz Figa, linux-arm-msm, linux-clk,
devicetree, linux-kernel, linux-samsung-soc, linux-arm-kernel
Cc: Krzysztof Kozlowski
Replace permanently bouncing email addresses (550 5.1.1 Recipient address
rejected) of Adam Skladowski, Sireesh Kodali and Chanho Park. There are
no new messages from them via other email addresses, so drop them
permanently. Add Alim Akhtar to Samsung ExynosAutov9 SoC clocks,
because he looks at other Samsung clock hardware and drivers.
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
Stephen, can you take this directly?
---
Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml | 2 --
.../devicetree/bindings/clock/samsung,exynosautov9-clock.yaml | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml
index fc0360554f68..9f2b970bfb48 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml
@@ -7,8 +7,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on MSM8937, MSM8940, MSM8953 and SDM439
maintainers:
- - Adam Skladowski <a_skl39@protonmail.com>
- - Sireesh Kodali <sireeshkodali@protonmail.com>
- Barnabas Czeman <barnabas.czeman@mainlining.org>
description: |
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
index e9d17d48b4f3..3dcdfa7a8792 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Samsung Exynos Auto v9 SoC clock controller
maintainers:
- - Chanho Park <chanho61.park@samsung.com>
+ - Alim Akhtar <alim.akhtar@samsung.com>
- Chanwoo Choi <cw00.choi@samsung.com>
- Krzysztof Kozlowski <krzk@kernel.org>
- Sylwester Nawrocki <s.nawrocki@samsung.com>
--
2.53.0
^ permalink raw reply related
* [PATCH 1/3] Documentation/hwmon: Add onsemi's FD5121 controllers' documentation
From: Selvamani Rajagopal via B4 Relay @ 2026-06-23 5:55 UTC (permalink / raw)
To: Guenter Roeck, Jonathan Corbet, Shuah Khan, Selva Rajagopal,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, linux-doc, linux-kernel, devicetree,
Selvamani Rajagopal
In-Reply-To: <20260622-support-fd5121-from-onsemi-v1-0-b31767689c65@onsemi.com>
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Document the hardware monitoring support for the FD5121, FD5123, and
FD5125 devices.
Documentation describes the supported telemetry data exposed via
the sysfs for the hwmon subsystem, including voltage, current,
power and temperature measurements.
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
Documentation/hwmon/fd5121.rst | 93 ++++++++++++++++++++++++++++++++++++++++++
Documentation/hwmon/index.rst | 1 +
2 files changed, 94 insertions(+)
diff --git a/Documentation/hwmon/fd5121.rst b/Documentation/hwmon/fd5121.rst
new file mode 100644
index 000000000000..c279db4641e4
--- /dev/null
+++ b/Documentation/hwmon/fd5121.rst
@@ -0,0 +1,93 @@
+.. SPDX-License-Identifier: GPL-2.0-only
+
+Kernel driver fd5121
+=====================
+
+Supported chips:
+
+ * onsemi FD5121
+
+ Prefix: 'fd5121'
+
+ Datasheet: Datasheet is not publicly available.
+
+ * onsemi FD5123
+
+ Prefix: 'fd5121'
+
+ Datasheet: Datasheet is not publicly available.
+
+ * onsemi FD5125
+
+ Prefix: 'fd5121'
+
+ Datasheet: Datasheet is not publicly available.
+
+Author: Selva Rajagopal <selvamani.rajagopal@onsemi.com>
+
+Description
+-----------
+
+FD5121, FD5123, FD5125 are dual-rail, multi-phase controllers
+and compliant to
+
+ - AVS and AMD proprietary SVI3 protocol.
+ - PMBus rev 1.4.1 interface.
+
+Used as multi-phase voltage regulators for CPUs, high performance
+ASICs, SoCs or graphic cores.
+
+Gives full telemetry options including input/output voltage
+and current, as well as fault handling and identifications.
+
+Usage Notes
+-----------
+
+This driver does not probe for PMBus devices. You will have
+to instantiate devices explicitly.
+
+Example: the following commands will load the driver for the
+controller at address 0x50 on I2C bus #1::
+
+ # modprobe fd5121
+ # echo fd5121 0x50 > /sys/bus/i2c/devices/i2c-1/new_device
+
+It can also be instantiated by declaring in device tree
+
+Sysfs attributes
+----------------
+
+The following attributes are supported:
+
+====================== ====================================
+curr[1-2]_label "iin[1-2]"
+curr[3-4]_label "iout[1-2]"
+curr[1-2]_input Measured input current.
+curr[3-4]_input Measured output current.
+curr[1-4]_crit_alarm Output current critical high alarm.
+curr[1-4]_max_alarm Output current high alarm.
+
+in[1-2]_label "vin[1-2]"
+in[3-4]_label "vout[1-2]"
+in[1-4]_lcrit_alarm Input voltage critical low alarm.
+in[1-4]_crit_alarm Input voltage critical high alarm.
+in[1-2]_max_alarm Input voltage high alarm.
+in[1-2]_input Measured input voltage.
+in[3-4]_input Measured output voltage.
+
+power[1-2]_label "pin[1-2]"
+power[3-4]_label "pout[1-2]"
+power[3-4]_crit_alarm Output power critical high alarm.
+power[1-2]_max_alarm Output power high alarm.
+power[1-4]_max Power limit.
+power[1-4]_input Measured input power.
+power[3-4]_crit Critical maximum output power.
+
+temp[1-2]_crit_alarm Chip temperature critical high alarm.
+temp[1-2]_max_alarm Chip temperature high alarm.
+temp[1-2]_input Measured temperature.
+temp[1-2]_max Maximum temperature.
+temp[1-2]_crit Critical high temperature.
+
+====================== ====================================
+
diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 4aa910569c31..451f5433fa60 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -79,6 +79,7 @@ Hardware Monitoring Kernel Drivers
f71805f
f71882fg
fam15h_power
+ fd5121
fsp-3y
ftsteutates
g760a
--
2.43.0
^ permalink raw reply related
* [PATCH 2/3] dt-bindings: hwmon: pmbus: Support for onsemi's FD5121
From: Selvamani Rajagopal via B4 Relay @ 2026-06-23 5:55 UTC (permalink / raw)
To: Guenter Roeck, Jonathan Corbet, Shuah Khan, Selva Rajagopal,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, linux-doc, linux-kernel, devicetree,
Selvamani Rajagopal
In-Reply-To: <20260622-support-fd5121-from-onsemi-v1-0-b31767689c65@onsemi.com>
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Add devicetree schema for onsemi FD5121, FD5123, and
FD5125 dual rail, multi-phase digital controllers.
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
.../bindings/hwmon/pmbus/onnn,fd5121.yaml | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml b/Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml
new file mode 100644
index 000000000000..b0453b0634f0
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/pmbus/onnn,fd5121.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: onsemi's multi-phase digital controllers
+
+maintainers:
+ - Selvamani Rajagopal <selvamani.rajagopal@onsemi.com>
+
+description:
+ onsemi multi-phase digital controllers with PMBus.
+
+properties:
+ compatible:
+ enum:
+ - onnn,fd5121
+ - onnn,fd5123
+ - onnn,fd5125
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ fd5121@50 {
+ compatible = "onnn,fd5121";
+ reg = <0x50>;
+ };
+ };
--
2.43.0
^ permalink raw reply related
* [PATCH 3/3] hwmon: (pmbus/fd5121): Add support FD5121, FD5123 and FD5125
From: Selvamani Rajagopal via B4 Relay @ 2026-06-23 5:55 UTC (permalink / raw)
To: Guenter Roeck, Jonathan Corbet, Shuah Khan, Selva Rajagopal,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, linux-doc, linux-kernel, devicetree,
Selvamani Rajagopal
In-Reply-To: <20260622-support-fd5121-from-onsemi-v1-0-b31767689c65@onsemi.com>
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
FD5121 is a dual-rail, multi-phase, digital controller that offers
full telemtry options including input/output voltage, current as
well as fault handling and identifications.
These controllers are compliant with PMBus specification.
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
MAINTAINERS | 8 +
drivers/hwmon/pmbus/Kconfig | 9 +
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/fd5121.c | 1004 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1022 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index d95d3ef77773..c0664c33324a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20135,6 +20135,14 @@ L: linux-mips@vger.kernel.org
S: Maintained
F: arch/mips/boot/dts/ralink/omega2p.dts
+ONSEMI HARDWARE MONITOR DRIVER
+M: Selva Rajagopal <selvamani.rajagopal@onsemi.com>
+L: linux-hwmon@vger.kernel.org
+S: Supported
+W: https://www.onsemi.com
+F: Documentation/devicetree/bindings/hwmon/pmbus/onnn,fd5121.yaml
+F: drivers/hwmon/pmbus/fd5121.c
+
ONSEMI ETHERNET PHY DRIVERS
M: Piergiorgio Beruto <piergiorgio.beruto@gmail.com>
L: netdev@vger.kernel.org
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index c8cda160b5f8..3a06ed83539e 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -179,6 +179,15 @@ config SENSORS_E50SN12051
This driver can also be built as a module. If so, the module will
be called e50sn12051.
+config SENSORS_FD5121
+ tristate "FD5121/FD5123/FD5125 controllers from onsemi"
+ help
+ If you say yes here, you get support for onsemi
+ controllers FD5121, FD5123, FD5125.
+
+ This driver can also be built as a module. If so, the module will
+ be called fd5121.
+
config SENSORS_INA233
tristate "Texas Instruments INA233 and compatibles"
help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index ffc05f493213..70f4afb41fe0 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_SENSORS_APS_379) += aps-379.o
obj-$(CONFIG_SENSORS_BEL_PFE) += bel-pfe.o
obj-$(CONFIG_SENSORS_BPA_RS600) += bpa-rs600.o
obj-$(CONFIG_SENSORS_DELTA_AHE50DC_FAN) += delta-ahe50dc-fan.o
+obj-$(CONFIG_SENSORS_FD5121) += fd5121.o
obj-$(CONFIG_SENSORS_FSP_3Y) += fsp-3y.o
obj-$(CONFIG_SENSORS_HAC300S) += hac300s.o
obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o
diff --git a/drivers/hwmon/pmbus/fd5121.c b/drivers/hwmon/pmbus/fd5121.c
new file mode 100644
index 000000000000..e68c6d6cabbd
--- /dev/null
+++ b/drivers/hwmon/pmbus/fd5121.c
@@ -0,0 +1,1004 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2026 Semiconductor Components Industries, LLC ("onsemi").
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/unaligned.h>
+
+#include "pmbus.h"
+
+enum chips { chip_fd5121, chip_fd5123, chip_fd5125 };
+
+#define CTLR_ID_UNKNOWN 0
+#define CTLR_ID_FD5121 0xFD5121
+#define CTLR_ID_FD5123 0xFD5123
+#define CTLR_ID_FD5125 0xFD5125
+
+#define FD5121_NUM_PAGES 2
+
+/* Custom PMBUS commands */
+#define PMBUS_REG_VOUT_MIN 0x2B
+#define PMBUS_REG_POWER_MODE 0x34
+#define PMBUS_REG_VIN_ON 0x35
+#define PMBUS_REG_VIN_OFF 0x36
+#define PMBUS_REG_VIN_UV_FAULT_RESPONSE 0x5A
+#define PMBUS_REG_IIN_OC_FAULT_RESPONSE 0x5C
+#define PMBUS_REG_TON_DELAY 0x60
+#define PMBUS_REG_POUT_OP_FAULT_RESPONSE 0x69
+#define PMBUS_REG_READ_VAUX 0x85
+
+#define PMBUS_REG_IKNEE_SET 0x2D
+#define PMBUS_REG_PIN_COUNTER 0x2E
+#define PMBUS_REG_VMIN_AWARE 0x2F
+#define PMBUS_REG_VAUX_UV_FAULT_LIMIT 0x6C
+#define PMBUS_REG_VAUX_OV_FAULT_LIMIT 0x6D
+#define PMBUS_REG_VAUX_UV_FAULT_RESPONSE 0x6E
+#define PMBUS_REG_VAUX_OV_FAULT_RESPONSE 0x6F
+#define PMBUS_REG_VAUX_UV_WARNING 0x75
+#define PMBUS_REG_VAUX_OV_WARNING 0x76
+#define PMBUS_REG_MFR_FREE_USER_CONFIG_TABLES 0xCF
+#define PMBUS_REG_MFR_ADDRESS_TABLE 0xD0
+#define PMBUS_REG_MFR_STATUS_ONSEMI 0xD1
+#define PMBUS_REG_MFR_UNLOCK 0xD2
+#define PMBUS_REG_MFR_FAULTY_SPS 0xD3
+#define PMBUS_REG_TLVR_FAULTS 0xD4
+#define PMBUS_REG_MFR_USER_STORE_CONFIG_TAB 0xD5
+#define PMBUS_REG_MFR_USER_CONFIG_INDEX 0xD6
+#define PMBUS_REG_MFR_PWM_DISCONNECTION 0xD7
+#define PMBUS_REG_MFR_VR_DISCONNECTION 0xD8
+#define PMBUS_REG_MFR_TON_SLEW 0xD9
+#define PMBUS_REG_MFR_TOFF_SLEW 0xDA
+#define PMBUS_REG_MFR_RAIL_NAME 0xDB
+#define PMBUS_REG_MFR_VOUT_DROOP 0xDC
+#define PMBUS_REG_MFR_USER_RESTORE_CONFIG_TAB 0xDD
+#define PMBUS_REG_MFR_SVR_GO 0xDE
+#define PMBUS_REG_MFR_SET_PWD 0xDF
+#define PMBUS_REG_MFR_CONFIG_ACTIVATE 0xE0
+#define PMBUS_REG_MFR_CONFIG_RECOVER 0xE1
+#define PMBUS_REG_MFR_OTP_DUMP 0xE2
+#define PMBUS_REG_MFR_BBR_EN 0xE3
+#define PMBUS_REG_MFR_DPM_MIN 0xE4
+#define PMBUS_REG_MFR_VBOOT 0xE5
+#define PMBUS_REG_MFR_PRECLAMP_OFFSET 0xE6
+#define PMBUS_REG_MFR_TLVR_DIAGN 0xE7
+#define PMBUS_REG_MFR_READ_VSYS 0xE8
+#define PMBUS_REG_MFR_SPECIFIC_E9 0xE9
+#define PMBUS_REG_MFR_SPECIFIC_EA 0xEA
+#define PMBUS_REG_MFR_SS_CBC 0xEB
+#define PMBUS_REG_MFR_AMD_STATUS 0xEC
+#define PMBUS_REG_MFR_CHECKSUM 0xEE
+#define PMBUS_REG_CSE_INDEX 0xF0
+#define PMBUS_REG_COUT_MEASURE 0xF1
+#define PMBUS_REG_VR_COUT 0xF2
+#define PMBUS_REG_BBR_RAM 0xF3
+#define PMBUS_REG_BBR_OTP 0xF4
+#define PMBUS_REG_READ_PSYS 0xF5
+#define PMBUS_REG_POSTCLAMP_OFFSET 0xF6
+#define PMBUS_REG_PGOOD_DELAY 0xF7
+#define PMBUS_REG_MFR_SPECIFIC_F8 0xF8
+#define PMBUS_REG_MFR_SPECIFIC_F9 0xF9
+#define PMBUS_REG_MFR_PWD_PROGRAM_RAM 0xFA
+#define PMBUS_REG_MFR_PWD_PROGRAM_I2C 0xFB
+#define PMBUS_REG_MFR_PWD_ENABLE_OTP_STORE 0xFC
+
+/* List of recognized commands */
+static const u8 cc_list[] = {
+ PMBUS_PAGE,
+ PMBUS_OPERATION,
+ PMBUS_ON_OFF_CONFIG,
+ PMBUS_CLEAR_FAULTS,
+ PMBUS_WRITE_PROTECT,
+ PMBUS_CAPABILITY,
+ PMBUS_VOUT_MODE,
+ PMBUS_VOUT_COMMAND,
+ PMBUS_VOUT_MAX,
+ PMBUS_VOUT_MARGIN_HIGH,
+ PMBUS_VOUT_MARGIN_LOW,
+ PMBUS_VOUT_TRANSITION_RATE,
+ PMBUS_REG_VOUT_MIN,
+ PMBUS_REG_IKNEE_SET,
+ PMBUS_REG_PIN_COUNTER,
+ PMBUS_REG_VMIN_AWARE,
+ PMBUS_REG_POWER_MODE,
+ PMBUS_REG_VIN_ON,
+ PMBUS_REG_VIN_OFF,
+ PMBUS_VOUT_OV_FAULT_LIMIT,
+ PMBUS_VOUT_OV_FAULT_RESPONSE,
+ PMBUS_VOUT_UV_FAULT_LIMIT,
+ PMBUS_VOUT_UV_FAULT_RESPONSE,
+ PMBUS_IOUT_OC_FAULT_LIMIT,
+ PMBUS_IOUT_OC_FAULT_RESPONSE,
+ PMBUS_IOUT_OC_WARN_LIMIT,
+ PMBUS_OT_FAULT_LIMIT,
+ PMBUS_OT_FAULT_RESPONSE,
+ PMBUS_OT_WARN_LIMIT,
+ PMBUS_VIN_OV_FAULT_LIMIT,
+ PMBUS_VIN_OV_FAULT_RESPONSE,
+ PMBUS_VIN_OV_WARN_LIMIT,
+ PMBUS_VIN_UV_WARN_LIMIT,
+ PMBUS_VIN_UV_FAULT_LIMIT,
+ PMBUS_REG_VIN_UV_FAULT_RESPONSE,
+ PMBUS_IIN_OC_FAULT_LIMIT,
+ PMBUS_REG_IIN_OC_FAULT_RESPONSE,
+ PMBUS_IIN_OC_WARN_LIMIT,
+ PMBUS_REG_TON_DELAY,
+ PMBUS_POUT_OP_FAULT_LIMIT,
+ PMBUS_REG_POUT_OP_FAULT_RESPONSE,
+ PMBUS_POUT_OP_WARN_LIMIT,
+ PMBUS_PIN_OP_WARN_LIMIT,
+ PMBUS_REG_VAUX_UV_FAULT_LIMIT,
+ PMBUS_REG_VAUX_OV_FAULT_LIMIT,
+ PMBUS_REG_VAUX_UV_FAULT_RESPONSE,
+ PMBUS_REG_VAUX_OV_FAULT_RESPONSE,
+ PMBUS_REG_VAUX_UV_WARNING,
+ PMBUS_REG_VAUX_OV_WARNING,
+ PMBUS_STATUS_BYTE,
+ PMBUS_STATUS_WORD,
+ PMBUS_STATUS_VOUT,
+ PMBUS_STATUS_IOUT,
+ PMBUS_STATUS_INPUT,
+ PMBUS_STATUS_TEMPERATURE,
+ PMBUS_STATUS_CML,
+ PMBUS_STATUS_OTHER,
+ PMBUS_STATUS_MFR_SPECIFIC,
+ PMBUS_REG_READ_VAUX,
+ PMBUS_READ_VIN,
+ PMBUS_READ_IIN,
+ PMBUS_READ_VOUT,
+ PMBUS_READ_IOUT,
+ PMBUS_READ_TEMPERATURE_1,
+ PMBUS_READ_POUT,
+ PMBUS_READ_PIN,
+ PMBUS_REVISION,
+ PMBUS_MFR_ID,
+ PMBUS_MFR_MODEL,
+ PMBUS_MFR_REVISION,
+ PMBUS_IC_DEVICE_ID,
+ PMBUS_REG_MFR_FREE_USER_CONFIG_TABLES,
+ PMBUS_REG_MFR_ADDRESS_TABLE,
+ PMBUS_REG_MFR_STATUS_ONSEMI,
+ PMBUS_REG_MFR_UNLOCK,
+ PMBUS_REG_MFR_FAULTY_SPS,
+ PMBUS_REG_TLVR_FAULTS,
+ PMBUS_REG_MFR_USER_STORE_CONFIG_TAB,
+ PMBUS_REG_MFR_USER_CONFIG_INDEX,
+ PMBUS_REG_MFR_PWM_DISCONNECTION,
+ PMBUS_REG_MFR_VR_DISCONNECTION,
+ PMBUS_REG_MFR_TON_SLEW,
+ PMBUS_REG_MFR_TOFF_SLEW,
+ PMBUS_REG_MFR_RAIL_NAME,
+ PMBUS_REG_MFR_VOUT_DROOP,
+ PMBUS_REG_MFR_USER_RESTORE_CONFIG_TAB,
+ PMBUS_REG_MFR_SVR_GO,
+ PMBUS_REG_MFR_SET_PWD,
+ PMBUS_REG_MFR_CONFIG_ACTIVATE,
+ PMBUS_REG_MFR_CONFIG_RECOVER,
+ PMBUS_REG_MFR_OTP_DUMP,
+ PMBUS_REG_MFR_BBR_EN,
+ PMBUS_REG_MFR_DPM_MIN,
+ PMBUS_REG_MFR_VBOOT,
+ PMBUS_REG_MFR_PRECLAMP_OFFSET,
+ PMBUS_REG_MFR_TLVR_DIAGN,
+ PMBUS_REG_MFR_READ_VSYS,
+ PMBUS_REG_MFR_SPECIFIC_E9,
+ PMBUS_REG_MFR_SPECIFIC_EA,
+ PMBUS_REG_MFR_SS_CBC,
+ PMBUS_REG_MFR_AMD_STATUS,
+ PMBUS_REG_MFR_CHECKSUM,
+ PMBUS_REG_CSE_INDEX,
+ PMBUS_REG_COUT_MEASURE,
+ PMBUS_REG_VR_COUT,
+ PMBUS_REG_BBR_RAM,
+ PMBUS_REG_BBR_OTP,
+ PMBUS_REG_READ_PSYS,
+ PMBUS_REG_POSTCLAMP_OFFSET,
+ PMBUS_REG_PGOOD_DELAY,
+ PMBUS_REG_MFR_SPECIFIC_F8,
+ PMBUS_REG_MFR_SPECIFIC_F9,
+ PMBUS_REG_MFR_PWD_PROGRAM_RAM,
+ PMBUS_REG_MFR_PWD_PROGRAM_I2C,
+ PMBUS_REG_MFR_PWD_ENABLE_OTP_STORE,
+};
+
+/* Following registers expect block read */
+static const u8 blk_rd_cc[] = {
+ PMBUS_SMBALERT_MASK,
+ PMBUS_MFR_DATE,
+ PMBUS_IC_DEVICE_REV,
+};
+
+struct fd5121_data {
+ struct attribute_group *groups[3];
+ struct pmbus_driver_info info;
+ struct device *dev;
+ u32 id;
+};
+
+static s32 fd5121_read_block_data(const struct i2c_client *client,
+ u8 cmd_code, u8 len, u8 *pbuf)
+{
+ s32 ret = 0;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
+
+ /* Payload length is in the first byte. */
+ ret = i2c_smbus_read_i2c_block_data(client, cmd_code,
+ len, pbuf);
+ if (ret < 0)
+ return ret;
+ ret = pbuf[0];
+ if (ret > len)
+ ret = len;
+ for (int idx = 0; idx < ret; idx++)
+ pbuf[idx] = pbuf[idx + 1];
+ return ret;
+ }
+ ret = i2c_smbus_read_block_data(client, cmd_code, pbuf);
+ if (ret < 0)
+ return ret;
+ return min_t(s32, ret, len);
+}
+
+/* Command code that expects block read, not word read */
+static bool fd5121_blk_rd_reg(u8 cmd_code)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(blk_rd_cc); i++) {
+ if (cmd_code == blk_rd_cc[i])
+ return true;
+ }
+ return false;
+}
+
+static ssize_t fd5121_send_byte_store(struct device *dev,
+ struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 val = 0;
+ int ret;
+
+ ret = kstrtou8(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+ ret = i2c_smbus_write_byte(client, val);
+ if (ret < 0)
+ return ret;
+ return count;
+}
+
+static int fd5121_config_activate(struct i2c_client *client)
+{
+ return i2c_smbus_write_byte_data(client,
+ PMBUS_REG_MFR_CONFIG_ACTIVATE, 0xAA);
+}
+
+static ssize_t fd5121_byte_store(struct device *dev,
+ struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 reg = attr->index;
+ int ret = 0;
+ u8 val = 0;
+
+ switch (reg) {
+ case PMBUS_REG_MFR_CONFIG_ACTIVATE:
+ ret = fd5121_config_activate(client);
+ if (ret < 0)
+ return ret;
+ return count;
+ default:
+ ret = kstrtou8(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+ break;
+ }
+ if (reg == PMBUS_PAGE && ((val != 0 && val != 1 &&
+ val != GENMASK(7, 0))))
+ return -EINVAL;
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret < 0)
+ return ret;
+ return count;
+}
+
+static ssize_t fd5121_byte_show(struct device *dev,
+ struct device_attribute *da, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 reg = attr->index;
+ s32 ret;
+
+ ret = i2c_smbus_read_byte_data(client, reg);
+ if (ret < 0)
+ return ret;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", ret & 0xFF);
+}
+
+static ssize_t fd5121_word_store(struct device *dev,
+ struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 reg = attr->index;
+ s16 val = 0;
+ int ret = 0;
+
+ switch (reg) {
+ case PMBUS_REG_MFR_PWD_PROGRAM_RAM:
+ val = 0xC93F;
+ break;
+ default:
+ ret = kstrtos16(buf, 10, &val);
+ if (ret)
+ return ret;
+ break;
+ }
+ ret = i2c_smbus_write_word_data(client, reg, val);
+ if (ret < 0)
+ return ret;
+ return count;
+}
+
+static ssize_t fd5121_word_show(struct device *dev,
+ struct device_attribute *da, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 data[I2C_SMBUS_BLOCK_MAX] = { 0 };
+ u8 reg = attr->index;
+ s32 ret = 0;
+
+ if (fd5121_blk_rd_reg(reg)) {
+ ret = fd5121_read_block_data(client, reg, 2, data);
+ if (ret >= 0)
+ ret = get_unaligned_le16(data);
+ } else
+ ret = i2c_smbus_read_word_data(client, reg);
+ if (ret < 0)
+ return ret;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", ret & 0xFFFF);
+}
+
+static s32 fd5121_write_block_data(const struct i2c_client *client,
+ u8 cmd_code, u8 len, u8 *pbuf)
+{
+ s32 ret = 0;
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_BLOCK_DATA))
+ ret = i2c_smbus_write_i2c_block_data(client, cmd_code,
+ len, pbuf);
+ else
+ ret = i2c_smbus_write_block_data(client, cmd_code,
+ len, pbuf);
+ return ret;
+}
+
+static s32 fd5121_read_long(struct i2c_client *client, u8 cmd_code, u32 *pval)
+{
+ u8 buffer[I2C_SMBUS_BLOCK_MAX] = { 0 };
+ s32 ret;
+
+ ret = fd5121_read_block_data(client, cmd_code, 4, buffer);
+ if (ret < 0)
+ return ret;
+ if (ret < 4)
+ return -EIO;
+
+ *pval = get_unaligned_le32(buffer);
+ return 0;
+}
+
+static ssize_t fd5121_long_store(struct device *dev,
+ struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 reg = attr->index;
+ u8 buffer[4];
+ u32 val = 0;
+ int ret = 0;
+ u8 len;
+
+ ret = kstrtou32(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ len = (u8) sizeof(buffer);
+ for (u8 i = 0; i < len; i++) {
+ buffer[i] = val & 0xFF;
+ val >>= 8;
+ }
+ ret = fd5121_write_block_data(client, reg, len, buffer);
+ if (ret < 0)
+ return ret;
+ return count;
+}
+
+static ssize_t fd5121_long_show(struct device *dev,
+ struct device_attribute *da, char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ u8 reg = attr->index;
+ u32 val = 0;
+ s32 ret = 0;
+
+ ret = fd5121_read_long(client, reg, &val);
+ if (ret < 0)
+ return ret;
+ return scnprintf(buf, PAGE_SIZE, "%d\n", val);
+}
+
+static ssize_t fd5121_block_show(struct device *dev,
+ struct device_attribute *da, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev->parent);
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ u8 buffer[I2C_SMBUS_BLOCK_MAX] = { 0 };
+ u8 reg = attr->index;
+ int printed = 0;
+ s32 ret = 0;
+ u8 len = 0;
+ int i = 0;
+
+ if (reg == PMBUS_REG_MFR_FAULTY_SPS) {
+ int to_print = 0;
+
+ len = 7;
+ ret = fd5121_read_block_data(client, reg, len, buffer);
+ if (ret < 0)
+ return ret;
+ printed = 0;
+ to_print = (ret < len) ? ret : len;
+ for (i = 0; i < to_print; i++)
+ printed += scnprintf(buf + printed,
+ PAGE_SIZE - printed,
+ "%02x", buffer[i]);
+ printed += scnprintf(buf + printed,
+ PAGE_SIZE - printed, "\n");
+ return printed;
+ } else if (reg == PMBUS_REG_BBR_RAM ||
+ reg == PMBUS_REG_BBR_OTP) {
+ u32 len = (reg == PMBUS_REG_BBR_OTP) ? 165 : 164;
+
+ /* Extra byte may be needed in case we need to store
+ * the length of the data
+ */
+ u8 *tmp_in = kcalloc(len+1, sizeof(u8), GFP_KERNEL);
+
+ if (tmp_in == NULL)
+ return -ENOMEM;
+ ret = fd5121_read_block_data(client, reg, len, tmp_in);
+ if (ret < 0) {
+ kfree(tmp_in);
+ return ret;
+ }
+
+ printed = 0;
+ for (i = 0; i < ret; i++)
+ printed += scnprintf(buf + printed,
+ PAGE_SIZE - printed, "%02x",
+ tmp_in[i]);
+ printed += scnprintf(buf + printed,
+ PAGE_SIZE - printed, "\n");
+
+ kfree(tmp_in);
+ return printed;
+ } else
+ return -ENODATA;
+}
+
+static SENSOR_DEVICE_ATTR_RW(page, fd5121_byte,
+ PMBUS_PAGE);
+static SENSOR_DEVICE_ATTR_RO(vout_raw, fd5121_word,
+ PMBUS_READ_VOUT);
+static SENSOR_DEVICE_ATTR_RW(operation, fd5121_byte,
+ PMBUS_OPERATION);
+static SENSOR_DEVICE_ATTR_RW(on_off_config, fd5121_byte,
+ PMBUS_ON_OFF_CONFIG);
+static SENSOR_DEVICE_ATTR_WO(clear_faults, fd5121_byte,
+ PMBUS_CLEAR_FAULTS);
+static SENSOR_DEVICE_ATTR_RW(write_protect, fd5121_byte,
+ PMBUS_WRITE_PROTECT);
+static SENSOR_DEVICE_ATTR_RO(capability, fd5121_byte,
+ PMBUS_CAPABILITY);
+static SENSOR_DEVICE_ATTR_RW(smbalert_mask, fd5121_word,
+ PMBUS_SMBALERT_MASK);
+static SENSOR_DEVICE_ATTR_RO(vout_mode, fd5121_byte,
+ PMBUS_VOUT_MODE);
+static SENSOR_DEVICE_ATTR_RW(vout_command, fd5121_word,
+ PMBUS_VOUT_COMMAND);
+static SENSOR_DEVICE_ATTR_RW(vout_max, fd5121_word,
+ PMBUS_VOUT_MAX);
+static SENSOR_DEVICE_ATTR_RW(vout_margin_high, fd5121_word,
+ PMBUS_VOUT_MARGIN_HIGH);
+static SENSOR_DEVICE_ATTR_RW(vout_margin_low, fd5121_word,
+ PMBUS_VOUT_MARGIN_LOW);
+static SENSOR_DEVICE_ATTR_RW(vout_transition_rate, fd5121_word,
+ PMBUS_VOUT_TRANSITION_RATE);
+static SENSOR_DEVICE_ATTR_RW(vout_min, fd5121_word,
+ PMBUS_REG_VOUT_MIN);
+static SENSOR_DEVICE_ATTR_RW(power_mode, fd5121_byte,
+ PMBUS_REG_POWER_MODE);
+static SENSOR_DEVICE_ATTR_RW(vin_on, fd5121_word,
+ PMBUS_REG_VIN_ON);
+static SENSOR_DEVICE_ATTR_RW(vin_off, fd5121_word,
+ PMBUS_REG_VIN_OFF);
+static SENSOR_DEVICE_ATTR_RW(vin_uv_fault_response, fd5121_byte,
+ PMBUS_REG_VIN_UV_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(iin_oc_fault_response, fd5121_byte,
+ PMBUS_REG_IIN_OC_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(ton_delay, fd5121_word,
+ PMBUS_REG_TON_DELAY);
+static SENSOR_DEVICE_ATTR_RW(pout_op_fault_response, fd5121_byte,
+ PMBUS_REG_POUT_OP_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RO(read_vaux, fd5121_word,
+ PMBUS_REG_READ_VAUX);
+static SENSOR_DEVICE_ATTR_RW(iknee_set, fd5121_word,
+ PMBUS_REG_IKNEE_SET);
+static SENSOR_DEVICE_ATTR_RW(pin_counter, fd5121_byte,
+ PMBUS_REG_PIN_COUNTER);
+static SENSOR_DEVICE_ATTR_RW(vmin_aware, fd5121_word,
+ PMBUS_REG_VMIN_AWARE);
+static SENSOR_DEVICE_ATTR_RW(vout_ov_fault_response, fd5121_byte,
+ PMBUS_VOUT_OV_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(vout_uv_fault_response, fd5121_byte,
+ PMBUS_VOUT_UV_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(iout_oc_fault_response, fd5121_byte,
+ PMBUS_IOUT_OC_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(ot_fault_response, fd5121_byte,
+ PMBUS_OT_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(vin_ov_fault_response, fd5121_byte,
+ PMBUS_VIN_OV_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(vaux_uv_fault_limit, fd5121_word,
+ PMBUS_REG_VAUX_UV_FAULT_LIMIT);
+static SENSOR_DEVICE_ATTR_RW(vaux_ov_fault_limit, fd5121_word,
+ PMBUS_REG_VAUX_OV_FAULT_LIMIT);
+static SENSOR_DEVICE_ATTR_RW(vaux_uv_fault_response, fd5121_byte,
+ PMBUS_REG_VAUX_UV_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(vaux_ov_fault_response, fd5121_byte,
+ PMBUS_REG_VAUX_OV_FAULT_RESPONSE);
+static SENSOR_DEVICE_ATTR_RW(vaux_uv_warning, fd5121_word,
+ PMBUS_REG_VAUX_UV_WARNING);
+static SENSOR_DEVICE_ATTR_RW(vaux_ov_warning, fd5121_word,
+ PMBUS_REG_VAUX_OV_WARNING);
+static SENSOR_DEVICE_ATTR_RO(free_user_config_tables, fd5121_byte,
+ PMBUS_REG_MFR_FREE_USER_CONFIG_TABLES);
+static SENSOR_DEVICE_ATTR_RW(address_table, fd5121_byte,
+ PMBUS_REG_MFR_ADDRESS_TABLE);
+static SENSOR_DEVICE_ATTR_RW(status_onsemi, fd5121_word,
+ PMBUS_REG_MFR_STATUS_ONSEMI);
+static SENSOR_DEVICE_ATTR_RO(status_byte, fd5121_byte,
+ PMBUS_STATUS_BYTE);
+static SENSOR_DEVICE_ATTR_RO(status_cml, fd5121_byte,
+ PMBUS_STATUS_CML);
+static SENSOR_DEVICE_ATTR_RO(status_other, fd5121_byte,
+ PMBUS_STATUS_OTHER);
+static SENSOR_DEVICE_ATTR_RO(status_mfr_specific, fd5121_byte,
+ PMBUS_STATUS_MFR_SPECIFIC);
+static SENSOR_DEVICE_ATTR_RO(revision, fd5121_byte,
+ PMBUS_REVISION);
+static SENSOR_DEVICE_ATTR_RO(id, fd5121_long,
+ PMBUS_MFR_ID);
+static SENSOR_DEVICE_ATTR_RO(model, fd5121_long,
+ PMBUS_MFR_MODEL);
+static SENSOR_DEVICE_ATTR_RO(mfr_revision, fd5121_long,
+ PMBUS_MFR_REVISION);
+static SENSOR_DEVICE_ATTR_RW(date, fd5121_word,
+ PMBUS_MFR_DATE);
+static SENSOR_DEVICE_ATTR_RO(ic_device_id, fd5121_long,
+ PMBUS_IC_DEVICE_ID);
+static SENSOR_DEVICE_ATTR_RO(ic_device_rev, fd5121_word,
+ PMBUS_IC_DEVICE_REV);
+static SENSOR_DEVICE_ATTR_WO(unlock, fd5121_byte,
+ PMBUS_REG_MFR_UNLOCK);
+static SENSOR_DEVICE_ATTR_RO(faulty_sps, fd5121_block,
+ PMBUS_REG_MFR_FAULTY_SPS);
+static SENSOR_DEVICE_ATTR_RO(tlvr_faults, fd5121_word,
+ PMBUS_REG_TLVR_FAULTS);
+static SENSOR_DEVICE_ATTR_RW(user_store_config_tab, fd5121_byte,
+ PMBUS_REG_MFR_USER_STORE_CONFIG_TAB);
+static SENSOR_DEVICE_ATTR_RO(user_config_index, fd5121_byte,
+ PMBUS_REG_MFR_USER_CONFIG_INDEX);
+static SENSOR_DEVICE_ATTR_RO(pwm_disconnection, fd5121_word,
+ PMBUS_REG_MFR_PWM_DISCONNECTION);
+static SENSOR_DEVICE_ATTR_RO(vr_disconnection, fd5121_byte,
+ PMBUS_REG_MFR_VR_DISCONNECTION);
+static SENSOR_DEVICE_ATTR_RW(ton_slew, fd5121_byte,
+ PMBUS_REG_MFR_TON_SLEW);
+static SENSOR_DEVICE_ATTR_RW(toff_slew, fd5121_byte,
+ PMBUS_REG_MFR_TOFF_SLEW);
+static SENSOR_DEVICE_ATTR_RW(rail_name, fd5121_word,
+ PMBUS_REG_MFR_RAIL_NAME);
+static SENSOR_DEVICE_ATTR_RW(vout_droop, fd5121_byte,
+ PMBUS_REG_MFR_VOUT_DROOP);
+static SENSOR_DEVICE_ATTR_WO(svr_go, fd5121_send_byte,
+ PMBUS_REG_MFR_SVR_GO);
+static SENSOR_DEVICE_ATTR_RW(user_restore_config_tab, fd5121_byte,
+ PMBUS_REG_MFR_USER_RESTORE_CONFIG_TAB);
+static SENSOR_DEVICE_ATTR_WO(set_pwd, fd5121_byte,
+ PMBUS_REG_MFR_SET_PWD);
+static SENSOR_DEVICE_ATTR_RW(config_activate, fd5121_byte,
+ PMBUS_REG_MFR_CONFIG_ACTIVATE);
+static SENSOR_DEVICE_ATTR_RW(config_recover, fd5121_byte,
+ PMBUS_REG_MFR_CONFIG_RECOVER);
+static SENSOR_DEVICE_ATTR_RW(otp_dump, fd5121_byte,
+ PMBUS_REG_MFR_OTP_DUMP);
+static SENSOR_DEVICE_ATTR_RW(bbr_en, fd5121_byte,
+ PMBUS_REG_MFR_BBR_EN);
+static SENSOR_DEVICE_ATTR_RW(dpm_min, fd5121_byte,
+ PMBUS_REG_MFR_DPM_MIN);
+static SENSOR_DEVICE_ATTR_RW(vboot, fd5121_word,
+ PMBUS_REG_MFR_VBOOT);
+static SENSOR_DEVICE_ATTR_RW(preclamp_offset, fd5121_word,
+ PMBUS_REG_MFR_PRECLAMP_OFFSET);
+static SENSOR_DEVICE_ATTR_RW(tlvr_diagn, fd5121_word,
+ PMBUS_REG_MFR_TLVR_DIAGN);
+static SENSOR_DEVICE_ATTR_RO(vsys, fd5121_word,
+ PMBUS_REG_MFR_READ_VSYS);
+static SENSOR_DEVICE_ATTR_RW(specific_e9, fd5121_word,
+ PMBUS_REG_MFR_SPECIFIC_E9);
+static SENSOR_DEVICE_ATTR_RW(specific_ea, fd5121_long,
+ PMBUS_REG_MFR_SPECIFIC_EA);
+static SENSOR_DEVICE_ATTR_RO(ss_cbc, fd5121_word,
+ PMBUS_REG_MFR_SS_CBC);
+static SENSOR_DEVICE_ATTR_RO(amd_status, fd5121_byte,
+ PMBUS_REG_MFR_AMD_STATUS);
+static SENSOR_DEVICE_ATTR_RO(checksum, fd5121_word,
+ PMBUS_REG_MFR_CHECKSUM);
+static SENSOR_DEVICE_ATTR_RO(cse_index, fd5121_word,
+ PMBUS_REG_CSE_INDEX);
+static SENSOR_DEVICE_ATTR_RW(cout_measure, fd5121_word,
+ PMBUS_REG_COUT_MEASURE);
+static SENSOR_DEVICE_ATTR_RO(vr_cout, fd5121_word,
+ PMBUS_REG_VR_COUT);
+static SENSOR_DEVICE_ATTR_RO(bbr_ram, fd5121_block,
+ PMBUS_REG_BBR_RAM);
+static SENSOR_DEVICE_ATTR_RO(bbr_otp, fd5121_block,
+ PMBUS_REG_BBR_OTP);
+static SENSOR_DEVICE_ATTR_RO(psys, fd5121_word,
+ PMBUS_REG_READ_PSYS);
+static SENSOR_DEVICE_ATTR_RW(postclamp_offset, fd5121_word,
+ PMBUS_REG_POSTCLAMP_OFFSET);
+static SENSOR_DEVICE_ATTR_RW(pgood_delay, fd5121_byte,
+ PMBUS_REG_PGOOD_DELAY);
+static SENSOR_DEVICE_ATTR_RW(specific_f8, fd5121_word,
+ PMBUS_REG_MFR_SPECIFIC_F8);
+static SENSOR_DEVICE_ATTR_RW(specific_f9, fd5121_long,
+ PMBUS_REG_MFR_SPECIFIC_F9);
+static SENSOR_DEVICE_ATTR_RW(pwd_program_ram, fd5121_word,
+ PMBUS_REG_MFR_PWD_PROGRAM_RAM);
+static SENSOR_DEVICE_ATTR_RW(pwd_program_i2c, fd5121_word,
+ PMBUS_REG_MFR_PWD_PROGRAM_I2C);
+static SENSOR_DEVICE_ATTR_RW(pwd_enable_otp_store, fd5121_word,
+ PMBUS_REG_MFR_PWD_ENABLE_OTP_STORE);
+
+static struct attribute *fd5121_non_paged_attrs[] = {
+ &sensor_dev_attr_page.dev_attr.attr,
+ &sensor_dev_attr_capability.dev_attr.attr,
+ &sensor_dev_attr_pin_counter.dev_attr.attr,
+ &sensor_dev_attr_vaux_uv_fault_limit.dev_attr.attr,
+ &sensor_dev_attr_vaux_ov_fault_limit.dev_attr.attr,
+ &sensor_dev_attr_vaux_uv_warning.dev_attr.attr,
+ &sensor_dev_attr_vaux_ov_warning.dev_attr.attr,
+ &sensor_dev_attr_free_user_config_tables.dev_attr.attr,
+ &sensor_dev_attr_address_table.dev_attr.attr,
+ &sensor_dev_attr_unlock.dev_attr.attr,
+ &sensor_dev_attr_faulty_sps.dev_attr.attr,
+ &sensor_dev_attr_tlvr_faults.dev_attr.attr,
+ &sensor_dev_attr_user_store_config_tab.dev_attr.attr,
+ &sensor_dev_attr_user_config_index.dev_attr.attr,
+ &sensor_dev_attr_pwm_disconnection.dev_attr.attr,
+ &sensor_dev_attr_vr_disconnection.dev_attr.attr,
+ &sensor_dev_attr_user_restore_config_tab.dev_attr.attr,
+ &sensor_dev_attr_svr_go.dev_attr.attr,
+ &sensor_dev_attr_set_pwd.dev_attr.attr,
+ &sensor_dev_attr_config_activate.dev_attr.attr,
+ &sensor_dev_attr_config_recover.dev_attr.attr,
+ &sensor_dev_attr_otp_dump.dev_attr.attr,
+ &sensor_dev_attr_bbr_en.dev_attr.attr,
+ &sensor_dev_attr_vboot.dev_attr.attr,
+ &sensor_dev_attr_vsys.dev_attr.attr,
+ &sensor_dev_attr_specific_e9.dev_attr.attr,
+ &sensor_dev_attr_specific_ea.dev_attr.attr,
+ &sensor_dev_attr_ss_cbc.dev_attr.attr,
+ &sensor_dev_attr_checksum.dev_attr.attr,
+ &sensor_dev_attr_cse_index.dev_attr.attr,
+ &sensor_dev_attr_cout_measure.dev_attr.attr,
+ &sensor_dev_attr_vr_cout.dev_attr.attr,
+ &sensor_dev_attr_bbr_ram.dev_attr.attr,
+ &sensor_dev_attr_bbr_otp.dev_attr.attr,
+ &sensor_dev_attr_psys.dev_attr.attr,
+ &sensor_dev_attr_specific_f8.dev_attr.attr,
+ &sensor_dev_attr_specific_f9.dev_attr.attr,
+ &sensor_dev_attr_pwd_program_ram.dev_attr.attr,
+ &sensor_dev_attr_pwd_program_i2c.dev_attr.attr,
+ &sensor_dev_attr_pwd_enable_otp_store.dev_attr.attr,
+ &sensor_dev_attr_revision.dev_attr.attr,
+ &sensor_dev_attr_id.dev_attr.attr,
+ &sensor_dev_attr_model.dev_attr.attr,
+ &sensor_dev_attr_mfr_revision.dev_attr.attr,
+ &sensor_dev_attr_date.dev_attr.attr,
+ &sensor_dev_attr_ic_device_id.dev_attr.attr,
+ &sensor_dev_attr_ic_device_rev.dev_attr.attr,
+ NULL
+};
+
+static struct attribute *fd5121_paged_attrs[] = {
+ &sensor_dev_attr_operation.dev_attr.attr,
+ &sensor_dev_attr_vout_raw.dev_attr.attr,
+ &sensor_dev_attr_on_off_config.dev_attr.attr,
+ &sensor_dev_attr_clear_faults.dev_attr.attr,
+ &sensor_dev_attr_write_protect.dev_attr.attr,
+ &sensor_dev_attr_smbalert_mask.dev_attr.attr,
+ &sensor_dev_attr_vout_mode.dev_attr.attr,
+ &sensor_dev_attr_vout_command.dev_attr.attr,
+ &sensor_dev_attr_vout_margin_high.dev_attr.attr,
+ &sensor_dev_attr_vout_margin_low.dev_attr.attr,
+ &sensor_dev_attr_vout_min.dev_attr.attr,
+ &sensor_dev_attr_vin_on.dev_attr.attr,
+ &sensor_dev_attr_vin_off.dev_attr.attr,
+ &sensor_dev_attr_vout_ov_fault_response.dev_attr.attr,
+ &sensor_dev_attr_vout_uv_fault_response.dev_attr.attr,
+ &sensor_dev_attr_iout_oc_fault_response.dev_attr.attr,
+ &sensor_dev_attr_ot_fault_response.dev_attr.attr,
+ &sensor_dev_attr_vin_ov_fault_response.dev_attr.attr,
+ &sensor_dev_attr_status_byte.dev_attr.attr,
+ &sensor_dev_attr_iknee_set.dev_attr.attr,
+ &sensor_dev_attr_vmin_aware.dev_attr.attr,
+ &sensor_dev_attr_power_mode.dev_attr.attr,
+ &sensor_dev_attr_vin_uv_fault_response.dev_attr.attr,
+ &sensor_dev_attr_iin_oc_fault_response.dev_attr.attr,
+ &sensor_dev_attr_ton_delay.dev_attr.attr,
+ &sensor_dev_attr_pout_op_fault_response.dev_attr.attr,
+ &sensor_dev_attr_vaux_uv_fault_response.dev_attr.attr,
+ &sensor_dev_attr_vaux_ov_fault_response.dev_attr.attr,
+ &sensor_dev_attr_status_onsemi.dev_attr.attr,
+ &sensor_dev_attr_status_cml.dev_attr.attr,
+ &sensor_dev_attr_status_other.dev_attr.attr,
+ &sensor_dev_attr_status_mfr_specific.dev_attr.attr,
+ &sensor_dev_attr_read_vaux.dev_attr.attr,
+ &sensor_dev_attr_ton_slew.dev_attr.attr,
+ &sensor_dev_attr_toff_slew.dev_attr.attr,
+ &sensor_dev_attr_rail_name.dev_attr.attr,
+ &sensor_dev_attr_vout_droop.dev_attr.attr,
+ &sensor_dev_attr_dpm_min.dev_attr.attr,
+ &sensor_dev_attr_preclamp_offset.dev_attr.attr,
+ &sensor_dev_attr_tlvr_diagn.dev_attr.attr,
+ &sensor_dev_attr_amd_status.dev_attr.attr,
+ &sensor_dev_attr_postclamp_offset.dev_attr.attr,
+ &sensor_dev_attr_pgood_delay.dev_attr.attr,
+ &sensor_dev_attr_vout_max.dev_attr.attr,
+ &sensor_dev_attr_vout_transition_rate.dev_attr.attr,
+ NULL
+};
+
+static struct attribute_group fd5121_groups[2] = {
+ { .name = "global", .attrs = fd5121_non_paged_attrs },
+ { .name = "paged", .attrs = fd5121_paged_attrs }
+};
+
+/* Regulator descriptors for VOUT rails (VID encoded) */
+static struct regulator_desc fd5121_reg_desc[] = {
+ PMBUS_REGULATOR_STEP_ONE("vout1", 3001, 1000, 200000),
+ PMBUS_REGULATOR_STEP_ONE("vout2", 3001, 1000, 200000),
+};
+
+static int fd5121_valid_reg(struct i2c_client *client, int reg)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cc_list); i++) {
+ if (reg == cc_list[i])
+ return 0;
+ }
+
+ if (fd5121_blk_rd_reg(reg))
+ return 0;
+ return -ENXIO;
+}
+
+static int fd5121_read_word_data(struct i2c_client *client, int page,
+ int phase, int reg)
+{
+ int ret;
+
+ ret = fd5121_valid_reg(client, reg);
+ if (ret < 0)
+ return ret;
+
+ ret = pmbus_read_word_data(client, page, phase, reg);
+ if (ret < 0)
+ return ret;
+
+ /* Chip reports VOUT_MODE as vid. But gives raw value 1mV per bit.
+ * So, encode the READ_VOUT value so that it gets decoded and
+ * reported correctly.
+ */
+ if (reg == PMBUS_READ_VOUT)
+ ret = DIV_ROUND_CLOSEST(155000 - ret * 100, 625);
+ return ret;
+}
+
+static int fd5121_read_byte_data(struct i2c_client *client, int page, int reg)
+{
+ int ret;
+
+ ret = fd5121_valid_reg(client, reg);
+ if (ret < 0)
+ return ret;
+
+ return pmbus_read_byte_data(client, page, reg);
+}
+
+static int fd5121_write_byte_data(struct i2c_client *client, int page,
+ int reg, u8 value)
+{
+ int ret;
+
+ ret = fd5121_valid_reg(client, reg);
+ if (ret < 0)
+ return ret;
+ return pmbus_write_byte_data(client, page, reg, value);
+}
+
+static int fd5121_write_byte(struct i2c_client *client, int page, u8 byte)
+{
+ return pmbus_write_byte(client, page, byte);
+}
+
+static int fd5121_write_word_data(struct i2c_client *client, int page,
+ int reg, u16 word)
+{
+ int ret;
+
+ ret = fd5121_valid_reg(client, reg);
+ if (ret < 0)
+ return ret;
+ ret = pmbus_write_word_data(client, page, reg, word);
+ return ret;
+}
+
+static u32 fd5121_get_dev_id(struct i2c_client *client)
+{
+ u32 dev_id = 0;
+ s32 ret = 0;
+
+ ret = fd5121_read_long(client, PMBUS_IC_DEVICE_ID, &dev_id);
+ if (ret < 0)
+ return CTLR_ID_UNKNOWN;
+
+ switch (dev_id) {
+ case CTLR_ID_FD5121:
+ case CTLR_ID_FD5123:
+ case CTLR_ID_FD5125:
+ break;
+ default:
+ if (dev_id != 0)
+ dev_err(&client->dev, "Unknown device 0x%x",
+ dev_id);
+ return CTLR_ID_UNKNOWN;
+ }
+ return dev_id;
+}
+
+static int fd5121_probe(struct i2c_client *client)
+{
+ struct pmbus_driver_info *info;
+ struct fd5121_data *pdata;
+ u32 id;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -EOPNOTSUPP;
+
+ pdata = devm_kzalloc(&client->dev, sizeof(struct fd5121_data),
+ GFP_KERNEL);
+ if (pdata == NULL)
+ return -ENOMEM;
+
+ pdata->dev = &client->dev;
+ pdata->groups[0] = &fd5121_groups[0];
+ pdata->groups[1] = &fd5121_groups[1];
+
+ id = fd5121_get_dev_id(client);
+ if (id == CTLR_ID_UNKNOWN)
+ return -ENODEV;
+
+ pdata->id = id;
+
+ switch (id) {
+ case CTLR_ID_FD5121:
+ case CTLR_ID_FD5123:
+ case CTLR_ID_FD5125:
+ break;
+ default:
+ dev_err(&client->dev, "Failed to read device ID");
+ return -ENODEV;
+ }
+
+ info = &pdata->info;
+ info->groups = (const struct attribute_group **)&pdata->groups[0];
+ info->write_word_data = fd5121_write_word_data;
+ info->write_byte = fd5121_write_byte;
+ info->write_byte_data = fd5121_write_byte_data;
+ info->read_word_data = fd5121_read_word_data;
+ info->read_byte_data = fd5121_read_byte_data;
+
+ info->pages = FD5121_NUM_PAGES;
+ info->format[PSC_VOLTAGE_IN] = linear;
+ info->format[PSC_VOLTAGE_OUT] = vid;
+
+ fd5121_reg_desc[0].id = 0;
+ fd5121_reg_desc[1].id = 1;
+
+ /* Device implements VID coding with 1 mV steps from 0.200 V
+ * up to 3.200 V
+ */
+ info->num_regulators = FD5121_NUM_PAGES;
+ info->reg_desc = fd5121_reg_desc;
+ info->format[PSC_CURRENT_IN] = linear;
+ info->format[PSC_CURRENT_OUT] = linear;
+ info->format[PSC_POWER] = linear;
+ info->format[PSC_TEMPERATURE] = linear;
+ for (u8 idx = 0; idx < info->pages; idx++) {
+ info->func[idx] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
+ info->func[idx] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
+ info->func[idx] |= PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP;
+ info->func[idx] |= PMBUS_HAVE_PIN | PMBUS_HAVE_POUT;
+ info->func[idx] |= PMBUS_HAVE_VIN | PMBUS_HAVE_IIN;
+ info->func[idx] |= PMBUS_HAVE_STATUS_INPUT;
+ info->vrm_version[idx] = amd625mv;
+ }
+ return pmbus_do_probe(client, info);
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id fd5121_of_match[] = {
+ { .compatible = "onnn,fd5121" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, fd5121_of_match);
+#endif
+
+static const struct i2c_device_id fd5121_id[] = {
+ { "fd5121", chip_fd5121 },
+ { "fd5123", chip_fd5123 },
+ { "fd5125", chip_fd5125 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, fd5121_id);
+
+static struct i2c_driver fd5121_driver = {
+ .driver = {
+ .name = "fd5121",
+ .of_match_table = of_match_ptr(fd5121_of_match),
+ },
+ .probe = fd5121_probe,
+ .id_table = fd5121_id,
+};
+
+module_i2c_driver(fd5121_driver);
+
+MODULE_AUTHOR("Selva Rajagopal <selvamani.rajagopal@onsemi.com>");
+MODULE_DESCRIPTION("PMBus driver for FD5121");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");
+
--
2.43.0
^ permalink raw reply related
* [PATCH 0/3] Support onsemi's FD5121 multiphase digital controller
From: Selvamani Rajagopal via B4 Relay @ 2026-06-23 5:55 UTC (permalink / raw)
To: Guenter Roeck, Jonathan Corbet, Shuah Khan, Selva Rajagopal,
Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: linux-hwmon, linux-doc, linux-kernel, devicetree,
Selvamani Rajagopal
FD5121 is a dual rail, multi-phase controller designed to
power CPU, ASIC or SoC with fully configurable rails.
This driver adds support for FD5121, FD5123 and FD5125. These
controllers configurability through PMBus 1.4.1.
Added documents for these controllers.
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
---
Selvamani Rajagopal (3):
Documentation/hwmon: Add onsemi's FD5121 controllers' documentation
dt-bindings: hwmon: pmbus: Support for onsemi's FD5121
hwmon: (pmbus/fd5121): Add support FD5121, FD5123 and FD5125
.../bindings/hwmon/pmbus/onnn,fd5121.yaml | 41 +
Documentation/hwmon/fd5121.rst | 93 ++
Documentation/hwmon/index.rst | 1 +
MAINTAINERS | 8 +
drivers/hwmon/pmbus/Kconfig | 9 +
drivers/hwmon/pmbus/Makefile | 1 +
drivers/hwmon/pmbus/fd5121.c | 1004 ++++++++++++++++++++
7 files changed, 1157 insertions(+)
---
base-commit: 1a3746ccbb0a97bed3c06ccde6b880013b1dddc1
change-id: 20260622-support-fd5121-from-onsemi-6fa9f98b5bf0
Best regards,
--
Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
^ permalink raw reply
* [PATCH v2 2/2] dt-bindings: Drop incorrect usage of double '::'
From: Krzysztof Kozlowski @ 2026-06-23 5:48 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Peter Griffin, Alim Akhtar, Michael Turquette,
Stephen Boyd, Brian Masney, Sylwester Nawrocki, Chanwoo Choi,
Sam Protsenko, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Inki Dae, Seung-Woo Kim, Kyungmin Park,
Andi Shyti, Georgi Djakov, Lee Jones, Pavel Machek, Hans Verkuil,
Mauro Carvalho Chehab, Ulf Hansson, Vinod Koul, Neil Armstrong,
Linus Walleij, Geert Uytterhoeven, Magnus Damm, Sebastian Reichel,
Javier Martinez Canillas, Liam Girdwood, Mark Brown,
Greg Kroah-Hartman, Jiri Slaby, Srinivas Kandagatla,
Bartlomiej Zolnierkiewicz, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Jonathan Marek, Taniya Das, Robert Marko,
Christian Marangi, Stephan Gerhold, Adam Skladowski,
Sireesh Kodali, Barnabas Czeman, Imran Shaik,
Sricharan Ramabadhran, Anusha Rao, Luo Jie, Tomasz Figa,
Chanho Park, Sunyeal Hong, Shin Son, Krishna Manikandan,
Jacek Anaszewski, Jaehoon Chung, Marek Szyprowski, Alina Yu,
Andy Gross, Niklas Söderlund, Wesley Cheng, linux-arm-msm,
devicetree, linux-kernel, linux-arm-kernel, linux-samsung-soc,
linux-clk, dri-devel, freedreno, linux-i2c, linux-pm, linux-leds,
linux-media, linux-mmc, linux-phy, linux-gpio, linux-renesas-soc,
linux-serial, linux-sound, linux-usb
Cc: Krzysztof Kozlowski, Conor Dooley, Sebastian Reichel,
Niklas Söderlund
In-Reply-To: <20260623054842.21831-3-krzysztof.kozlowski@oss.qualcomm.com>
There is no use of double colon '::' in YAML. OTOH, the literal style
block, e.g. using '|' treats all characters as content [1] therefore
single use of ':' in descriptions is perfectly fine, whenever '|' is
used.
Cleanup existing code, so the confusing style won't be re-used in new
contributions.
Link: https://yaml.org/spec/1.2.2/#literal-style [1]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Acked-by: Alim Akhtar <alim.akhtar@samsung.com>
Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Acked-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> # renesas
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
Intention for this patch is to go via Rob's tree.
Changes in v2:
1. Add tags (partial Reviews as Acks, as that's the meaning of Ack)
2. Do not replace ::= in mux.
---
.../devicetree/bindings/arm/qcom-soc.yaml | 4 ++--
.../devicetree/bindings/arm/qcom.yaml | 4 ++--
.../bindings/arm/samsung/samsung-soc.yaml | 4 ++--
.../display/msm/dsi-controller-main.yaml | 20 +++++++++----------
.../display/samsung/samsung,fimd.yaml | 4 ++--
.../bindings/i2c/samsung,s3c2410-i2c.yaml | 2 +-
.../interconnect/qcom,msm8998-bwmon.yaml | 2 +-
.../interconnect/samsung,exynos-bus.yaml | 14 ++++++-------
.../bindings/leds/qcom,pm8058-led.yaml | 4 ++--
.../bindings/leds/skyworks,aat1290.yaml | 6 +++---
.../bindings/media/cec/cec-gpio.yaml | 2 +-
.../bindings/mmc/samsung,exynos-dw-mshc.yaml | 2 +-
.../bindings/phy/samsung,mipi-video-phy.yaml | 4 ++--
.../bindings/phy/samsung,usb2-phy.yaml | 2 +-
.../bindings/phy/samsung,usb3-drd-phy.yaml | 2 +-
.../bindings/pinctrl/samsung,pinctrl.yaml | 2 +-
.../bindings/power/renesas,rcar-sysc.yaml | 2 +-
.../bindings/power/reset/restart-handler.yaml | 8 ++++----
.../bindings/regulator/maxim,max77802.yaml | 4 ++--
.../bindings/regulator/richtek,rtq2208.yaml | 2 +-
.../bindings/serial/qcom,msm-uartdm.yaml | 2 +-
.../devicetree/bindings/slimbus/slimbus.yaml | 4 ++--
.../bindings/soc/qcom/qcom,apr-services.yaml | 2 +-
.../bindings/soc/qcom/qcom,rpmh-rsc.yaml | 8 ++++----
.../bindings/soc/qcom/qcom,wcnss.yaml | 2 +-
.../bindings/soc/renesas/renesas-soc.yaml | 4 ++--
.../bindings/sound/qcom,q6asm-dais.yaml | 2 +-
.../thermal/samsung,exynos-thermal.yaml | 4 ++--
.../devicetree/bindings/usb/qcom,dwc3.yaml | 12 +++++------
.../bindings/usb/qcom,snps-dwc3.yaml | 12 +++++------
30 files changed, 73 insertions(+), 73 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/qcom-soc.yaml b/Documentation/devicetree/bindings/arm/qcom-soc.yaml
index 27261039d56f..37fdd5a080b7 100644
--- a/Documentation/devicetree/bindings/arm/qcom-soc.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom-soc.yaml
@@ -11,10 +11,10 @@ maintainers:
description: |
Guidelines for new compatibles for SoC blocks/components.
- When adding new compatibles in new bindings, use the format::
+ When adding new compatibles in new bindings, use the format:
qcom,SoC-IP
- For example::
+ For example:
qcom,sdm845-llcc-bwmon
When adding new compatibles to existing bindings, use the format in the
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml
index 50cc18a6ec5e..667607ae2c32 100644
--- a/Documentation/devicetree/bindings/arm/qcom.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -1215,7 +1215,7 @@ properties:
items:
items:
- description: |
- MSM chipset ID - an exact match value consisting of two bitfields::
+ MSM chipset ID - an exact match value consisting of two bitfields:
- bits 0-15 - The unique MSM chipset ID
- bits 16-31 - Reserved; should be 0
- description: |
@@ -1241,7 +1241,7 @@ properties:
- items:
- items:
- description: |
- Board ID consisting of three bitfields::
+ Board ID consisting of three bitfields:
- bits 31-24 - Unused
- bits 23-16 - Platform Version Major
- bits 15-8 - Platform Version Minor
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-soc.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-soc.yaml
index 653f85997643..ab000befe76d 100644
--- a/Documentation/devicetree/bindings/arm/samsung/samsung-soc.yaml
+++ b/Documentation/devicetree/bindings/arm/samsung/samsung-soc.yaml
@@ -11,10 +11,10 @@ maintainers:
description: |
Guidelines for new compatibles for SoC blocks/components.
- When adding new compatibles in new bindings, use the format::
+ When adding new compatibles in new bindings, use the format:
samsung,SoC-IP
- For example::
+ For example:
samsung,exynos5433-cmu-isp
select:
diff --git a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index dbc0613e427e..395425a70db8 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -73,16 +73,16 @@ properties:
clocks:
description: |
- Several clocks are used, depending on the variant. Typical ones are::
- - bus:: Display AHB clock.
- - byte:: Display byte clock.
- - byte_intf:: Display byte interface clock.
- - core:: Display core clock.
- - core_mss:: Core MultiMedia SubSystem clock.
- - iface:: Display AXI clock.
- - mdp_core:: MDP Core clock.
- - mnoc:: MNOC clock
- - pixel:: Display pixel clock.
+ Several clocks are used, depending on the variant. Typical ones are:
+ - bus: Display AHB clock.
+ - byte: Display byte clock.
+ - byte_intf: Display byte interface clock.
+ - core: Display core clock.
+ - core_mss: Core MultiMedia SubSystem clock.
+ - iface: Display AXI clock.
+ - mdp_core: MDP Core clock.
+ - mnoc: MNOC clock
+ - pixel: Display pixel clock.
minItems: 3
maxItems: 12
diff --git a/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml b/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml
index ff685031bb2c..729705f419bb 100644
--- a/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml
+++ b/Documentation/devicetree/bindings/display/samsung/samsung,fimd.yaml
@@ -41,7 +41,7 @@ properties:
additionalProperties: false
description: |
Timing configuration for lcd i80 interface support.
- The parameters are defined as::
+ The parameters are defined as:
VCLK(internal) __|??????|_____|??????|_____|??????|_____|??????|_____|??
: : : : :
Address Output --:<XXXXXXXXXXX:XXXXXXXXXXXX:XXXXXXXXXXXX:XXXXXXXXXXXX:XX
@@ -132,7 +132,7 @@ patternProperties:
"^port@[0-4]+$":
$ref: /schemas/graph.yaml#/properties/port
description: |
- Contains ports with port with index::
+ Contains ports with port with index:
0 - for CAMIF0 input,
1 - for CAMIF1 input,
2 - for CAMIF2 input,
diff --git a/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml b/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml
index a2ddc6803617..07600b49f2f9 100644
--- a/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/samsung,s3c2410-i2c.yaml
@@ -35,7 +35,7 @@ properties:
gpios:
description: |
- The order of the GPIOs should be the following:: <SDA, SCL>. The GPIO
+ The order of the GPIOs should be the following: <SDA, SCL>. The GPIO
specifier depends on the gpio controller. Required in all cases except
for "samsung,s3c2440-hdmiphy-i2c" whose input/output lines are
permanently wired to the respective client.
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
index ff64225e8281..e002e70580f9 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
@@ -13,7 +13,7 @@ description: |
Bandwidth Monitor measures current throughput on buses between various NoC
fabrics and provides information when it crosses configured thresholds.
- Certain SoCs might have more than one Bandwidth Monitors, for example on SDM845::
+ Certain SoCs might have more than one Bandwidth Monitors, for example on SDM845:
- Measuring the bandwidth between CPUs and Last Level Cache Controller -
called just BWMON,
- Measuring the bandwidth between Last Level Cache Controller and memory
diff --git a/Documentation/devicetree/bindings/interconnect/samsung,exynos-bus.yaml b/Documentation/devicetree/bindings/interconnect/samsung,exynos-bus.yaml
index 5e26e48c7217..0203959c8995 100644
--- a/Documentation/devicetree/bindings/interconnect/samsung,exynos-bus.yaml
+++ b/Documentation/devicetree/bindings/interconnect/samsung,exynos-bus.yaml
@@ -23,7 +23,7 @@ description: |
The each AXI bus has the owned source clock but, has not the only owned power
line. The power line might be shared among one more sub-blocks. So, we can
divide into two type of device as the role of each sub-block. There are two
- type of bus devices as following::
+ type of bus devices as following:
- parent bus device
- passive bus device
@@ -44,8 +44,8 @@ description: |
able to support the bus frequency for all Exynos SoCs.
Detailed correlation between sub-blocks and power line according
- to Exynos SoC::
- - In case of Exynos3250, there are two power line as following::
+ to Exynos SoC:
+ - In case of Exynos3250, there are two power line as following:
VDD_MIF |--- DMC (Dynamic Memory Controller)
VDD_INT |--- LEFTBUS (parent device)
@@ -89,7 +89,7 @@ description: |
|L5 |200000 |200000 |400000 |300000 | ||1000000 |
----------------------------------------------------------
- - In case of Exynos4210, there is one power line as following::
+ - In case of Exynos4210, there is one power line as following:
VDD_INT |--- DMC (parent device, Dynamic Memory Controller)
|--- LEFTBUS
|--- PERIL
@@ -106,7 +106,7 @@ description: |
|--- LCD0
|--- LCD1
- - In case of Exynos4x12, there are two power line as following::
+ - In case of Exynos4x12, there are two power line as following:
VDD_MIF |--- DMC (Dynamic Memory Controller)
VDD_INT |--- LEFTBUS (parent device)
@@ -124,7 +124,7 @@ description: |
|--- LCD0
|--- ISP
- - In case of Exynos5422, there are two power line as following::
+ - In case of Exynos5422, there are two power line as following:
VDD_MIF |--- DREX 0 (parent device, DRAM EXpress controller)
|--- DREX 1
@@ -143,7 +143,7 @@ description: |
|--- FSYS
|--- FSYS2
- - In case of Exynos5433, there is VDD_INT power line as following::
+ - In case of Exynos5433, there is VDD_INT power line as following:
VDD_INT |--- G2D (parent device)
|--- MSCL
|--- GSCL
diff --git a/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml b/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml
index b409b2a8b5c5..5165bfddcd54 100644
--- a/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml
+++ b/Documentation/devicetree/bindings/leds/qcom,pm8058-led.yaml
@@ -10,10 +10,10 @@ maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
description: |
- The Qualcomm PM8058 contains an LED block for up to six LEDs:: three normal
+ The Qualcomm PM8058 contains an LED block for up to six LEDs: three normal
LEDs, two "flash" LEDs and one "keypad backlight" LED. The names are quoted
because sometimes these LED drivers are used for wildly different things than
- flash or keypad backlight:: their names are more of a suggestion than a
+ flash or keypad backlight: their names are more of a suggestion than a
hard-wired usecase.
Hardware-wise the different LEDs support slightly different output currents.
diff --git a/Documentation/devicetree/bindings/leds/skyworks,aat1290.yaml b/Documentation/devicetree/bindings/leds/skyworks,aat1290.yaml
index a6aaa92dbccd..65576dfdca11 100644
--- a/Documentation/devicetree/bindings/leds/skyworks,aat1290.yaml
+++ b/Documentation/devicetree/bindings/leds/skyworks,aat1290.yaml
@@ -11,7 +11,7 @@ maintainers:
- Krzysztof Kozlowski <krzk@kernel.org>
description: |
- The device is controlled through two pins:: FL_EN and EN_SET. The pins when,
+ The device is controlled through two pins: FL_EN and EN_SET. The pins when,
asserted high, enable flash strobe and movie mode (max 1/2 of flash current)
respectively. In order to add a capability of selecting the strobe signal
source (e.g. CPU or camera sensor) there is an additional switch required,
@@ -39,11 +39,11 @@ properties:
flash-max-microamp:
description: |
Maximum flash LED supply current can be calculated using following
- formula:: I = 1A * 162 kOhm / Rset.
+ formula: I = 1A * 162 kOhm / Rset.
flash-max-timeout-us:
description: |
- Maximum flash timeout can be calculated using following formula::
+ Maximum flash timeout can be calculated using following formula:
T = 8.82 * 10^9 * Ct.
required:
diff --git a/Documentation/devicetree/bindings/media/cec/cec-gpio.yaml b/Documentation/devicetree/bindings/media/cec/cec-gpio.yaml
index 582c6c9cae48..21118e4bae0f 100644
--- a/Documentation/devicetree/bindings/media/cec/cec-gpio.yaml
+++ b/Documentation/devicetree/bindings/media/cec/cec-gpio.yaml
@@ -14,7 +14,7 @@ description: |
hooked up to a pull-up GPIO line and - optionally - the HPD line is hooked up
to another GPIO line.
- Please note:: the maximum voltage for the CEC line is 3.63V, for the HPD and
+ Please note: the maximum voltage for the CEC line is 3.63V, for the HPD and
5V lines it is 5.3V. So you may need some sort of level conversion
circuitry when connecting them to a GPIO line.
diff --git a/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml b/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
index 27c4060f2f91..223fcc9f651f 100644
--- a/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
+++ b/Documentation/devicetree/bindings/mmc/samsung,exynos-dw-mshc.yaml
@@ -85,7 +85,7 @@ properties:
description: |
The value of CIU TX and RX clock phase shift value for HS400 mode
operation.
- Valid values for SDR and DDR CIU clock timing::
+ Valid values for SDR and DDR CIU clock timing:
- valid value for tx phase shift and rx phase shift is 0 to 7.
- when CIU clock divider value is set to 3, all possible 8 phase shift
values can be used.
diff --git a/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml
index 16967ef8e9ec..87b6a35b2626 100644
--- a/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,mipi-video-phy.yaml
@@ -13,14 +13,14 @@ maintainers:
description: |
For samsung,s5pv210-mipi-video-phy compatible PHYs the second cell in the
- PHY specifier identifies the PHY and its meaning is as follows::
+ PHY specifier identifies the PHY and its meaning is as follows:
0 - MIPI CSIS 0,
1 - MIPI DSIM 0,
2 - MIPI CSIS 1,
3 - MIPI DSIM 1.
samsung,exynos5420-mipi-video-phy and samsung,exynos5433-mipi-video-phy
- support additional fifth PHY::
+ support additional fifth PHY:
4 - MIPI CSIS 2.
properties:
diff --git a/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml
index d9f22a801cbf..7db7605a82e2 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb2-phy.yaml
@@ -14,7 +14,7 @@ maintainers:
description: |
The first phandle argument in the PHY specifier identifies the PHY, its
meaning is compatible dependent. For the currently supported SoCs (Exynos4210
- and Exynos4212) it is as follows::
+ and Exynos4212) it is as follows:
0 - USB device ("device"),
1 - USB host ("host"),
2 - HSIC0 ("hsic0"),
diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
index 4562e0468f4f..a1b3d9e6a094 100644
--- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
+++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml
@@ -14,7 +14,7 @@ maintainers:
description: |
For samsung,exynos5250-usbdrd-phy and samsung,exynos5420-usbdrd-phy
compatible PHYs, the second cell in the PHY specifier identifies the
- PHY id, which is interpreted as follows::
+ PHY id, which is interpreted as follows:
0 - UTMI+ type phy,
1 - PIPE3 type phy.
diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
index 7b006009ca0e..5e35686eeed3 100644
--- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml
@@ -18,7 +18,7 @@ description: |
All the pin controller nodes should be represented in the aliases node using
the following format 'pinctrl{n}' where n is a unique number for the alias.
- The controller supports three types of interrupts::
+ The controller supports three types of interrupts:
- External GPIO interrupts (see interrupts property in pin controller node);
- External wake-up interrupts - multiplexed (capable of waking up the system
diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml
index 347571e2545a..b67aa170b2c1 100644
--- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml
+++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml
@@ -13,7 +13,7 @@ maintainers:
description: |
The R-Car (RZ/G) System Controller provides power management for the CPU
cores and various coprocessors.
- The power domain IDs for consumers are defined in header files::
+ The power domain IDs for consumers are defined in header files:
include/dt-bindings/power/r8*-sysc.h
properties:
diff --git a/Documentation/devicetree/bindings/power/reset/restart-handler.yaml b/Documentation/devicetree/bindings/power/reset/restart-handler.yaml
index 965a834a3dbe..00c00ec5ec81 100644
--- a/Documentation/devicetree/bindings/power/reset/restart-handler.yaml
+++ b/Documentation/devicetree/bindings/power/reset/restart-handler.yaml
@@ -18,12 +18,12 @@ properties:
priority:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
- A priority ranging from 0 to 255 according to the following guidelines::
- 0:: Restart handler of last resort, with limited restart capabilities.
- 128:: Typical, default restart handler; use if no other restart handler
+ A priority ranging from 0 to 255 according to the following guidelines:
+ 0: Restart handler of last resort, with limited restart capabilities.
+ 128: Typical, default restart handler; use if no other restart handler
is expected to be available, and/or if restart functionality is
sufficient to restart the entire system.
- 255:: Highest priority restart handler, will preempt all other restart handlers.
+ 255: Highest priority restart handler, will preempt all other restart handlers.
minimum: 0
maximum: 255
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
index b704f05ea454..b886495c1396 100644
--- a/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
+++ b/Documentation/devicetree/bindings/regulator/maxim,max77802.yaml
@@ -22,13 +22,13 @@ description: |
Certain regulators support "regulator-initial-mode" and "regulator-mode".
The valid modes list is defined in the dt-bindings/regulator/maxim,max77802.h
- and their meaning is::
+ and their meaning is:
1 - Normal regulator voltage output mode.
3 - Low Power which reduces the quiescent current down to only 1uA
The standard "regulator-mode" property can only be used for regulators that
support changing their mode to Low Power Mode during suspend. These
- regulators are:: bucks 2-4 and LDOs 1-35. Also, it only takes effect if the
+ regulators are: bucks 2-4 and LDOs 1-35. Also, it only takes effect if the
regulator has been enabled for the given suspend state using
"regulator-on-in-suspend" and has not been disabled for that state using
"regulator-off-in-suspend".
diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
index 022c1f197364..b0aa38edf8c2 100644
--- a/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
+++ b/Documentation/devicetree/bindings/regulator/richtek,rtq2208.yaml
@@ -21,7 +21,7 @@ description: |
conduction mode (FCCM).
The definition of modes is in the datasheet which is available in below link
- and their meaning is::
+ and their meaning is:
0 - Auto mode for power saving, which reducing the switching frequency at light load condition
to maintain high frequency.
1 - FCCM to meet the strict voltage regulation accuracy, which keeping constant switching frequency.
diff --git a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml
index 788ef5c1c446..bc967ead2350 100644
--- a/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml
+++ b/Documentation/devicetree/bindings/serial/qcom,msm-uartdm.yaml
@@ -17,7 +17,7 @@ description: |
software perspective it's mostly compatible with the MSM serial UART except
that it supports reading and writing multiple characters at a time.
- Note:: Aliases may be defined to ensure the correct ordering of the UARTs.
+ Note: Aliases may be defined to ensure the correct ordering of the UARTs.
The alias serialN will result in the UART being assigned port N. If any
serialN alias exists, then an alias must exist for each enabled UART. The
serialN aliases should be in a .dts file instead of in a .dtsi file.
diff --git a/Documentation/devicetree/bindings/slimbus/slimbus.yaml b/Documentation/devicetree/bindings/slimbus/slimbus.yaml
index 5a941610ce4e..3910327c8ded 100644
--- a/Documentation/devicetree/bindings/slimbus/slimbus.yaml
+++ b/Documentation/devicetree/bindings/slimbus/slimbus.yaml
@@ -29,7 +29,7 @@ patternProperties:
description: |
Every SLIMbus controller node can contain zero or more child nodes
representing slave devices on the bus. Every SLIMbus slave device is
- uniquely determined by the enumeration address containing 4 fields::
+ uniquely determined by the enumeration address containing 4 fields:
Manufacturer ID, Product code, Device index, and Instance value for the
device.
@@ -48,7 +48,7 @@ patternProperties:
reg:
maxItems: 1
description: |
- Pair of (device index, instande ID), where::
+ Pair of (device index, instande ID), where:
- Device index, which uniquely identifies multiple devices within a
single component.
- Instance ID, can be used for the cases where multiple devices of
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml
index bdf482db32aa..b663be3ea5a1 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml
@@ -40,7 +40,7 @@ properties:
$ref: /schemas/types.yaml#/definitions/string-array
description: |
Protection domain service name and path for APR service (if supported).
- Possible values are::
+ Possible values are:
"avs/audio", "msm/adsp/audio_pd".
"kernel/elf_loader", "msm/modem/wlan_pd".
"tms/servreg", "msm/adsp/audio_pd".
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
index 26d9bc773ec5..1889139a3f7a 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,rpmh-rsc.yaml
@@ -23,7 +23,7 @@ description: |
with a few variations that are captured by the properties here.
A TCS may be triggered from Linux or triggered by the F/W after all the CPUs
- have powered off to facilitate idle power saving. TCS could be classified as::
+ have powered off to facilitate idle power saving. TCS could be classified as:
ACTIVE - Triggered by Linux
SLEEP - Triggered by F/W
WAKE - Triggered by F/W
@@ -76,7 +76,7 @@ properties:
items:
items:
- description: |
- TCS type::
+ TCS type:
- ACTIVE_TCS
- SLEEP_TCS
- WAKE_TCS
@@ -152,7 +152,7 @@ examples:
- |
// For a TCS whose RSC base address is 0x179C0000 and is at a DRV id of
// 2, the register offsets for DRV2 start at 0D00, the register
- // calculations are like this::
+ // calculations are like this:
// DRV0: 0x179C0000
// DRV2: 0x179C0000 + 0x10000 = 0x179D0000
// DRV2: 0x179C0000 + 0x10000 * 2 = 0x179E0000
@@ -182,7 +182,7 @@ examples:
- |
// For a TCS whose RSC base address is 0xAF20000 and is at DRV id of 0, the
// register offsets for DRV0 start at 01C00, the register calculations are
- // like this::
+ // like this:
// DRV0: 0xAF20000
// TCS-OFFSET: 0x1C00
#include <dt-bindings/interrupt-controller/arm-gic.h>
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml
index 4fcae6bedfff..72a7f8cb09ba 100644
--- a/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml
+++ b/Documentation/devicetree/bindings/soc/qcom/qcom,wcnss.yaml
@@ -28,7 +28,7 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle
description: |
Reference to a node specifying the wcnss "ccu" and "dxe" register blocks.
- The node must be compatible with one of the following::
+ The node must be compatible with one of the following:
- qcom,riva"
- qcom,pronto"
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas-soc.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas-soc.yaml
index 5ddd31f30f26..57c9d3c57021 100644
--- a/Documentation/devicetree/bindings/soc/renesas/renesas-soc.yaml
+++ b/Documentation/devicetree/bindings/soc/renesas/renesas-soc.yaml
@@ -12,10 +12,10 @@ maintainers:
description: |
Guidelines for new compatibles for SoC blocks/components.
- When adding new compatibles in new bindings, use the format::
+ When adding new compatibles in new bindings, use the format:
renesas,SoC-IP
- For example::
+ For example:
renesas,r8a77965-csi2
When adding new compatibles to existing bindings, use the format in the
diff --git a/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml b/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml
index 47a105a97ecf..bc8c8ba24f9c 100644
--- a/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,q6asm-dais.yaml
@@ -45,7 +45,7 @@ patternProperties:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [0, 1, 2]
description: |
- The direction of the dai stream::
+ The direction of the dai stream:
- Q6ASM_DAI_TX_RX (0) for both tx and rx
- Q6ASM_DAI_TX (1) for only tx (Capture/Encode)
- Q6ASM_DAI_RX (2) for only rx (Playback/Decode)
diff --git a/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
index 29a08b0729ee..3f333db72a71 100644
--- a/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
+++ b/Documentation/devicetree/bindings/thermal/samsung,exynos-thermal.yaml
@@ -40,7 +40,7 @@ properties:
description: |
The Exynos TMU supports generating interrupts when reaching given
temperature thresholds. Number of supported thermal trip points depends
- on the SoC (only first trip points defined in DT will be configured)::
+ on the SoC (only first trip points defined in DT will be configured):
- most of SoC: 4
- samsung,exynos5433-tmu: 8
- samsung,exynos7-tmu: 8
@@ -52,7 +52,7 @@ properties:
- description: |
Shared TMU registers.
- Note:: On Exynos5420, the TRIMINFO register is misplaced for TMU
+ Note: On Exynos5420, the TRIMINFO register is misplaced for TMU
channels 2, 3 and 4 Use "samsung,exynos5420-tmu-ext-triminfo" in
cases, there is a misplaced register, also provide clock to access
that base.
diff --git a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
index a7f58114c02e..90daee616880 100644
--- a/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,dwc3.yaml
@@ -92,14 +92,14 @@ properties:
clocks:
description: |
- Several clocks are used, depending on the variant. Typical ones are::
- - cfg_noc:: System Config NOC clock.
- - core:: Master/Core clock, has to be >= 125 MHz for SS operation and >=
+ Several clocks are used, depending on the variant. Typical ones are:
+ - cfg_noc: System Config NOC clock.
+ - core: Master/Core clock, has to be >= 125 MHz for SS operation and >=
60MHz for HS operation.
- - iface:: System bus AXI clock.
- - sleep:: Sleep clock, used for wakeup when USB3 core goes into low
+ - iface: System bus AXI clock.
+ - sleep: Sleep clock, used for wakeup when USB3 core goes into low
power mode (U3).
- - mock_utmi:: Mock utmi clock needed for ITP/SOF generation in host
+ - mock_utmi: Mock utmi clock needed for ITP/SOF generation in host
mode. Its frequency should be 19.2MHz.
minItems: 1
maxItems: 9
diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
index 8201656b41ed..d99af9f413d0 100644
--- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
@@ -87,14 +87,14 @@ properties:
clocks:
description: |
- Several clocks are used, depending on the variant. Typical ones are::
- - cfg_noc:: System Config NOC clock.
- - core:: Master/Core clock, has to be >= 125 MHz for SS operation and >=
+ Several clocks are used, depending on the variant. Typical ones are:
+ - cfg_noc: System Config NOC clock.
+ - core: Master/Core clock, has to be >= 125 MHz for SS operation and >=
60MHz for HS operation.
- - iface:: System bus AXI clock.
- - sleep:: Sleep clock, used for wakeup when USB3 core goes into low
+ - iface: System bus AXI clock.
+ - sleep: Sleep clock, used for wakeup when USB3 core goes into low
power mode (U3).
- - mock_utmi:: Mock utmi clock needed for ITP/SOF generation in host
+ - mock_utmi: Mock utmi clock needed for ITP/SOF generation in host
mode. Its frequency should be 19.2MHz.
minItems: 1
maxItems: 9
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: clock: Drop incorrect usage of double '::'
From: Krzysztof Kozlowski @ 2026-06-23 5:48 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Peter Griffin, Alim Akhtar, Michael Turquette,
Stephen Boyd, Brian Masney, Sylwester Nawrocki, Chanwoo Choi,
Sam Protsenko, Rob Clark, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Sean Paul, Marijn Suijten, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Inki Dae, Seung-Woo Kim, Kyungmin Park,
Andi Shyti, Georgi Djakov, Lee Jones, Pavel Machek, Hans Verkuil,
Mauro Carvalho Chehab, Ulf Hansson, Vinod Koul, Neil Armstrong,
Linus Walleij, Geert Uytterhoeven, Magnus Damm, Sebastian Reichel,
Javier Martinez Canillas, Liam Girdwood, Mark Brown,
Greg Kroah-Hartman, Jiri Slaby, Srinivas Kandagatla,
Bartlomiej Zolnierkiewicz, Rafael J. Wysocki, Daniel Lezcano,
Zhang Rui, Lukasz Luba, Jonathan Marek, Taniya Das, Robert Marko,
Christian Marangi, Stephan Gerhold, Adam Skladowski,
Sireesh Kodali, Barnabas Czeman, Imran Shaik,
Sricharan Ramabadhran, Anusha Rao, Luo Jie, Tomasz Figa,
Chanho Park, Sunyeal Hong, Shin Son, Krishna Manikandan,
Jacek Anaszewski, Jaehoon Chung, Marek Szyprowski, Alina Yu,
Andy Gross, Niklas Söderlund, Wesley Cheng, linux-arm-msm,
devicetree, linux-kernel, linux-arm-kernel, linux-samsung-soc,
linux-clk, dri-devel, freedreno, linux-i2c, linux-pm, linux-leds,
linux-media, linux-mmc, linux-phy, linux-gpio, linux-renesas-soc,
linux-serial, linux-sound, linux-usb
Cc: Krzysztof Kozlowski, Conor Dooley
There is no use of double colon '::' in YAML. OTOH, the literal style
block, e.g. using '|' treats all characters as content [1] therefore
single use of ':' in descriptions is perfectly fine, whenever '|' is
used.
Cleanup existing code, so the confusing style won't be re-used in new
contributions.
Link: https://yaml.org/spec/1.2.2/#literal-style [1]
Acked-by: Alim Akhtar <alim.akhtar@samsung.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
I split the patches to avoid bounces from mailing list due to email size.
This can go via clock tree (no dependencies)... or both could go via
Rob's tree.
Changes in v2:
1. Add tags (partial Reviews as Acks, as that's the meaning of Ack)
---
.../devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-apq8064.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-apq8084.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-ipq6018.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-ipq8064.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-mdm9607.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-mdm9615.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-msm8660.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-msm8909.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-msm8916.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-msm8953.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-msm8974.yaml | 2 +-
.../devicetree/bindings/clock/qcom,gcc-sdm660.yaml | 2 +-
Documentation/devicetree/bindings/clock/qcom,gpucc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,ipq5018-gcc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,ipq9574-gcc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,qca8k-nsscc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml | 2 +-
Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,sc8280xp-lpasscc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml | 2 +-
.../devicetree/bindings/clock/qcom,sm8350-videocc.yaml | 2 +-
Documentation/devicetree/bindings/clock/qcom,videocc.yaml | 2 +-
.../devicetree/bindings/clock/samsung,exynos5260-clock.yaml | 6 +++---
.../devicetree/bindings/clock/samsung,exynos5410-clock.yaml | 2 +-
.../devicetree/bindings/clock/samsung,exynos5433-clock.yaml | 2 +-
.../devicetree/bindings/clock/samsung,exynos7-clock.yaml | 2 +-
.../devicetree/bindings/clock/samsung,exynos850-clock.yaml | 2 +-
.../bindings/clock/samsung,exynosautov9-clock.yaml | 2 +-
.../bindings/clock/samsung,exynosautov920-clock.yaml | 2 +-
.../devicetree/bindings/clock/samsung,s5pv210-clock.yaml | 2 +-
32 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml
index 53a5ab319159..6863db9bd092 100644
--- a/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,dispcc-sm8x50.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm display clock control module provides the clocks, resets and power
domains on SM8150/SM8250/SM8350.
- See also::
+ See also:
include/dt-bindings/clock/qcom,dispcc-sm8150.h
include/dt-bindings/clock/qcom,dispcc-sm8250.h
include/dt-bindings/clock/qcom,dispcc-sm8350.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml
index 27df7e3e5bf3..68532244901e 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on APQ8064.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-msm8960.h
include/dt-bindings/reset/qcom,gcc-msm8960.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-apq8084.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-apq8084.yaml
index 0a0a26d9beab..1c022e75fd71 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-apq8084.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-apq8084.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on APQ8084.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-apq8084.h
include/dt-bindings/reset/qcom,gcc-apq8084.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-ipq6018.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-ipq6018.yaml
index 4d2614d4f368..c7fb84438db7 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-ipq6018.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-ipq6018.yaml
@@ -15,7 +15,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on IPQ6018.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-ipq6018.h
include/dt-bindings/reset/qcom,gcc-ipq6018.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-ipq8064.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-ipq8064.yaml
index a71557395c01..b4d3175780bc 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-ipq8064.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-ipq8064.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on IPQ8064.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
include/dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml
index d7da30b0e7ee..0a7be7583bdd 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9607.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-mdm9607.h
allOf:
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9615.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9615.yaml
index 418dea31eb62..0656d5ee448d 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9615.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-mdm9615.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-mdm9615.h
allOf:
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml
index e03b6d0acdb6..70c9da1f35c2 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8660.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks and resets on
MSM8660
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-msm8660.h
include/dt-bindings/reset/qcom,gcc-msm8660.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml
index ce1f5a60bd8c..2edb6c251d99 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8909.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on MSM8909, MSM8917 or QM215.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-msm8909.h
include/dt-bindings/clock/qcom,gcc-msm8917.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml
index 258b6b93deca..af4b639ea8c3 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8916.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on MSM8916 or MSM8939.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-msm8916.h
include/dt-bindings/clock/qcom,gcc-msm8939.h
include/dt-bindings/reset/qcom,gcc-msm8916.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml
index ced3118c8580..fc0360554f68 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml
@@ -15,7 +15,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on MSM8937, MSM8940, MSM8953 or SDM439.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-msm8917.h
include/dt-bindings/clock/qcom,gcc-msm8953.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8974.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8974.yaml
index 929fafc84c19..378dfe7854ac 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8974.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8974.yaml
@@ -15,7 +15,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on MSM8974 (all variants) and MSM8226.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
include/dt-bindings/reset/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sdm660.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sdm660.yaml
index 724ce0491118..72aaf699cf70 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gcc-sdm660.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gcc-sdm660.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on SDM630, SDM636 and SDM660
- See also::
+ See also:
include/dt-bindings/clock/qcom,gcc-sdm660.h (qcom,gcc-sdm630 and qcom,gcc-sdm660)
$ref: qcom,gcc.yaml#
diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
index 4cdff6161bf0..3ac4419009a9 100644
--- a/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,gpucc.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm graphics clock control module provides the clocks, resets and power
domains on Qualcomm SoCs.
- See also::
+ See also:
include/dt-bindings/clock/qcom,gpucc-sdm845.h
include/dt-bindings/clock/qcom,gpucc-sa8775p.h
include/dt-bindings/clock/qcom,gpucc-sc7180.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq5018-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq5018-gcc.yaml
index 489d0fc5607c..9925b931ecad 100644
--- a/Documentation/devicetree/bindings/clock/qcom,ipq5018-gcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,ipq5018-gcc.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on IPQ5018
- See also::
+ See also:
include/dt-bindings/clock/qcom,ipq5018-gcc.h
include/dt-bindings/reset/qcom,ipq5018-gcc.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml
index 27ae9938febc..5b128fa841aa 100644
--- a/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-gcc.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on IPQ9574
- See also::
+ See also:
include/dt-bindings/clock/qcom,ipq9574-gcc.h
include/dt-bindings/reset/qcom,ipq9574-gcc.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml b/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml
index 61473385da2d..3da10c364a85 100644
--- a/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,qca8k-nsscc.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm NSS clock control module provides the clocks and resets
on QCA8386(switch mode)/QCA8084(PHY mode)
- See also::
+ See also:
include/dt-bindings/clock/qcom,qca8k-nsscc.h
include/dt-bindings/reset/qcom,qca8k-nsscc.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
index 734880805c1b..bedbdabef672 100644
--- a/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,qcm2290-gpucc.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm graphics clock control module provides the clocks, resets and power
domains on Qualcomm SoCs.
- See also::
+ See also:
include/dt-bindings/clock/qcom,qcm2290-gpucc.h
properties:
diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml
index ab97d4b7dba8..b6c835bfd0d9 100644
--- a/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml
@@ -12,7 +12,7 @@ maintainers:
description: |
The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h> and
- come in pairs:: FOO_CLK followed by FOO_A_CLK. The latter clock is
+ come in pairs: FOO_CLK followed by FOO_A_CLK. The latter clock is
an "active" clock, which means that the consumer only care that the clock is
available when the apps CPU subsystem is active, i.e. not suspended or in
deep idle. If it is important that the clock keeps running during system
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
index 99ab9106009f..fd06ac9bceb9 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sc7280-lpasscorecc.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm LPASS core and audio clock control module provides the clocks and
power domains on SC7280.
- See also::
+ See also:
include/dt-bindings/clock/qcom,lpasscorecc-sc7280.h
include/dt-bindings/clock/qcom,lpassaudiocc-sc7280.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc8280xp-lpasscc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc8280xp-lpasscc.yaml
index 273d66e245c5..f235b4e24cc7 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sc8280xp-lpasscc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sc8280xp-lpasscc.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm LPASS core and audio clock control module provides the clocks,
and reset on SC8280XP.
- See also::
+ See also:
include/dt-bindings/clock/qcom,lpasscc-sc8280xp.h
properties:
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml
index 8cbab3fbb660..d7e1938b5e1b 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sm6115-lpasscc.yaml
@@ -14,7 +14,7 @@ description: |
Qualcomm LPASS core and audio clock controllers provide audio-related resets
on SM6115 and its derivatives.
- See also::
+ See also:
include/dt-bindings/clock/qcom,sm6115-lpasscc.h
properties:
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8350-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8350-videocc.yaml
index 5c2ecec0624e..a986ab4ce7c7 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sm8350-videocc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sm8350-videocc.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm video clock control module provides the clocks, resets and power
domains on Qualcomm SoCs.
- See also::
+ See also:
include/dt-bindings/clock/qcom,videocc-sm8350.h
include/dt-bindings/reset/qcom,videocc-sm8350.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml
index f4ff9acef9d5..124d259fc85e 100644
--- a/Documentation/devicetree/bindings/clock/qcom,videocc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,videocc.yaml
@@ -13,7 +13,7 @@ description: |
Qualcomm video clock control module provides the clocks, resets and power
domains on Qualcomm SoCs.
- See also::
+ See also:
include/dt-bindings/clock/qcom,sm6350-videocc.h
include/dt-bindings/clock/qcom,videocc-sc7180.h
include/dt-bindings/clock/qcom,videocc-sc7280.h
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml
index b05f83533e3d..56ab972c3da5 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5260-clock.yaml
@@ -14,17 +14,17 @@ maintainers:
description: |
Expected external clocks, defined in DTS as fixed-rate clocks with a matching
- name::
+ name:
- "fin_pll" - PLL input clock from XXTI
- "xrtcxti" - input clock from XRTCXTI
- "ioclk_pcm_extclk" - pcm external operation clock
- "ioclk_spdif_extclk" - spdif external operation clock
- "ioclk_i2s_cdclk" - i2s0 codec clock
- Phy clocks::
+ Phy clocks:
There are several clocks which are generated by specific PHYs. These clocks
are fed into the clock controller and then routed to the hardware blocks.
- These clocks are defined as fixed clocks in the driver with following names::
+ These clocks are defined as fixed clocks in the driver with following names:
- "phyclk_dptx_phy_ch3_txd_clk" - dp phy clock for channel 3
- "phyclk_dptx_phy_ch2_txd_clk" - dp phy clock for channel 2
- "phyclk_dptx_phy_ch1_txd_clk" - dp phy clock for channel 1
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml
index b737c9d35a1c..1d907dd8fbf1 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5410-clock.yaml
@@ -14,7 +14,7 @@ maintainers:
description: |
Expected external clocks, defined in DTS as fixed-rate clocks with a matching
- name::
+ name:
- "fin_pll" - PLL input clock from XXTI
All available clocks are defined as preprocessor macros in
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml
index 3f9326e09f79..8a289f1e2ace 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos5433-clock.yaml
@@ -14,7 +14,7 @@ maintainers:
description: |
Expected external clocks, defined in DTS as fixed-rate clocks with a matching
- name::
+ name:
- "oscclk" - PLL input clock from XXTI
All available clocks are defined as preprocessor macros in
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
index c137c6744ef9..a51cd4fafb41 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos7-clock.yaml
@@ -14,7 +14,7 @@ maintainers:
description: |
Expected external clocks, defined in DTS as fixed-rate clocks with a matching
- name::
+ name:
- "fin_pll" - PLL input clock from XXTI
All available clocks are defined as preprocessor macros in
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
index cdc5ded59fe5..68c2fd318765 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml
@@ -17,7 +17,7 @@ description: |
Exynos850 clock controller is comprised of several CMU units, generating
clocks for different domains. Those CMU units are modeled as separate device
tree nodes, and might depend on each other. Root clocks in that clock tree are
- two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external
+ two external clocks: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external
clocks must be defined as fixed-rate clocks in dts.
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
index 32f39e543b36..e9d17d48b4f3 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov9-clock.yaml
@@ -17,7 +17,7 @@ description: |
Exynos Auto v9 clock controller is comprised of several CMU units, generating
clocks for different domains. Those CMU units are modeled as separate device
tree nodes, and might depend on each other. Root clocks in that clock tree are
- two external clocks:: OSCCLK/XTCXO (26 MHz) and RTCCLK/XrtcXTI (32768 Hz).
+ two external clocks: OSCCLK/XTCXO (26 MHz) and RTCCLK/XrtcXTI (32768 Hz).
The external OSCCLK must be defined as fixed-rate clock in dts.
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml
index 6b1fc61a2ff9..475db824d4d3 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml
@@ -17,7 +17,7 @@ description: |
ExynosAuto v920 clock controller is comprised of several CMU units, generating
clocks for different domains. Those CMU units are modeled as separate device
tree nodes, and might depend on each other. Root clocks in that clock tree are
- two external clocks:: OSCCLK/XTCXO (38.4 MHz) and RTCCLK/XrtcXTI (32768 Hz).
+ two external clocks: OSCCLK/XTCXO (38.4 MHz) and RTCCLK/XrtcXTI (32768 Hz).
The external OSCCLK must be defined as fixed-rate clock in dts.
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
diff --git a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml
index 67a33665cf00..b1617d96d3fb 100644
--- a/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,s5pv210-clock.yaml
@@ -14,7 +14,7 @@ maintainers:
description: |
Expected external clocks, defined in DTS as fixed-rate clocks with a matching
- name::
+ name:
- "xxti" - external crystal oscillator connected to XXTI and XXTO pins of
the SoC,
- "xusbxti" - external crystal oscillator connected to XUSBXTI and XUSBXTO
--
2.53.0
^ permalink raw reply related
* RE: [PATCH net v5 1/4] net: ethernet: oa_tc6: Interrupt is active low, level triggered.
From: Selvamani Rajagopal @ 2026-06-23 5:48 UTC (permalink / raw)
To: Parthiban.Veerasooran@microchip.com, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, Piergiorgio Beruto
Cc: andrew@lunn.ch, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, Conor.Dooley@microchip.com,
devicetree@vger.kernel.org
In-Reply-To: <64f4f30e-a987-4289-b36a-1acc977a6764@microchip.com>
> -----Original Message-----
> From: Parthiban.Veerasooran@microchip.com <Parthiban.Veerasooran@microchip.com>
> Subject: Re: [PATCH net v5 1/4] net: ethernet: oa_tc6: Interrupt is active low, level
> triggered.
>
>
> I will find some time this week to test and share my feedback. In the
> meantime, would it be possible for you to test using two instances (Test
> Case 2)? I did not encounter many issues when testing with a single
> instance.
>
> I believe that testing with two instances increases the likelihood of
> reproducing the issue in your setup as well.
Parthiban,
Thanks.
Our EVB design allows only one board to be connected to one Raspberry Pi.
So, I don't think I can have a setup like yours. We did test with three Raspberry Pi boards with
multi-drop connection. Couldn't see your "NULL pointer" crash. Will keep trying though.
But I could see assert in skb_put immediately quickly.
>
> Best regards,
> Parthiban V
> >
> >>
^ permalink raw reply
* Re: [PATCH v11 2/3] dt-bindings: clock: imx95-blk-ctl: Define formatter child node schema
From: Krzysztof Kozlowski @ 2026-06-23 5:41 UTC (permalink / raw)
To: guoniu.zhou
Cc: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd, imx, linux-media, devicetree,
linux-arm-kernel, linux-kernel, linux-clk, Guoniu Zhou
In-Reply-To: <20260623-csi_formatter-v11-2-a792fe9c1502@oss.nxp.com>
On Tue, Jun 23, 2026 at 11:56:32AM +0800, guoniu.zhou@oss.nxp.com wrote:
> From: Guoniu Zhou <guoniu.zhou@nxp.com>
>
> The Camera CSR contains control registers for multiple CSI formatter IPs
> at different register offsets. Each formatter is an independent hardware
> block with its own clock input and media pipeline connection.
>
> Define schema to allow formatter child nodes under nxp,imx95-camera-csr,
> with 'reg' property specifying the formatter's register offset within the
> CSR address space.
>
> Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
> ---
> Changes in v11:
> - Move properties to top-level and use if:then:else (Krzysztof/Frank)
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 8/8] arm64: defconfig: Add SM8450 camcc
From: Krzysztof Kozlowski @ 2026-06-23 5:38 UTC (permalink / raw)
To: esteuwu, Bjorn Andersson, Michael Turquette, Stephen Boyd,
Brian Masney, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Rob Clark, Will Deacon, Robin Murphy,
Joerg Roedel (AMD), Vinod Koul, Neil Armstrong
Cc: linux-arm-msm, linux-clk, linux-kernel, devicetree, iommu,
linux-arm-kernel, linux-phy
In-Reply-To: <20260622-sm8450-qol-v1-8-37e2ee8df9da@proton.me>
On 23/06/2026 02:54, Esteban Urrutia via B4 Relay wrote:
> From: Esteban Urrutia <esteuwu@proton.me>
>
> Add SM8450 camcc as a module since it's enabled in SM8450 dtsi.
This is not needed. I already sent such patch.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v5 2/3] counter: add GPIO-based counter driver
From: William Breathitt Gray @ 2026-06-23 5:37 UTC (permalink / raw)
To: Wadim Mueller
Cc: William Breathitt Gray, Oleksij Rempel, kernel, conor+dt, krzk+dt,
robh, linux-iio, devicetree, linux-kernel
In-Reply-To: <20260622205210.10317-1-wafgo01@gmail.com>
On Mon, Jun 22, 2026 at 10:51:40PM +0200, Wadim Mueller wrote:
> On Wed, 17 Jun 2026 16:49:25 +0900
> William Breathitt Gray <wbg@kernel.org> wrote:
>
> Hi William,
>
> thanks for the review. Three things before I spin v6.
>
> > One change I consider is whether to make Signal B optional. [...]
> > I wonder whether this is substantially different enough from
> > simply using the interrupt-cnt module on the respective IRQ?
> > I'm CCing Oleksij and the Pengutronix team in case they wish to
> > comment.
>
> I want to keep signal-b mandatory in v6 (if no concerns from Oleksij). The single-line case is
> already covered by interrupt-cnt.
All right, let's keep it required for v6. If for some reason we
determine it should be optional, we can address that after v6.
> > In such a configuration, we would have two Counts: Count 1 [...]
> > Count 2 supports only increase/decrease modes with a Synapse for
> > Signal B.
>
> Just to confirm, plan for v6 is:
>
> Count 0 "AB Count": A + B + optional index0, all 8 functions
> Count 1 "B Count": B + optional index1, increase/decrease only
>
> One counter_ops, dispatch on count->id. Per-count state in
> struct gpio_counter_count_priv (value, ceiling, preset, preset_enabled,
> enabled, function, direction), held in priv->count_priv[2] as you
> suggested. prev_a/prev_b stay on priv (they describe the wire, not
> the count).
Yes, that is correct. However, I would not name the Counts "AB Count"
and "B Count" -- it's possible that relationship will change in the
future if we add support for more function modes to Count 2. Naming them
"Count 1" and "Count 2" is adequate enough because the Signal
relationship is apparent via the Synapses.
> For the second Index in DT I would just let index-gpios take 1..2
> entries (first = count0, second = count1), no new property. Ok for
> you and Conor?
That seems okay to me. I'm generally indifferent to the DT so I'll leave
it up to what you and Conor decide.
> > Hmm, is it a problem that priv->enabled is changed to a false state
> > before the IRQs are actually disabled? Do any issues arise if an IRQ
> > is handled during that brief period of time?
>
> I guess it is a race. In v6 I will reorder:
>
> enable=1: enable_irq(); lock; enabled = true; unlock;
> enable=0: lock; enabled = false; unlock; disable_irq();
>
> Plus a mutex around enable_write so two writers can not interleave
> (disable_irq() can not run under the spinlock).
I think the race conditions still exist despite your reorder: after
enable_irq() an interrupt could fire before you take the lock to set
priv->enabled to true; similarly, after setting priv->enabled to false
and unlocking, an interrupt could fire before you call disable_irq().
We need some atomic way to update priv->enabled and enable/disable the
IRQ at the same time, but I'm not sure how to accomplish that off the
top of my head. I don't want to delay your v6, and I'm not even sure
this race is actually a problem in practice, so let's discuss this again
after your v6 submission.
William Breathitt Gray
^ permalink raw reply
* Re: [PATCH v6 1/3] regulator: dt-bindings: Add Unisoc SC2730 PMIC
From: Krzysztof Kozlowski @ 2026-06-23 5:25 UTC (permalink / raw)
To: Otto Pflüger, Krzysztof Kozlowski
Cc: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Orson Zhai, Baolin Wang, Chunyan Zhang, Lee Jones,
linux-kernel, devicetree
In-Reply-To: <ajl8YparXoIXL0wm@abscue.de>
On 22/06/2026 20:18, Otto Pflüger wrote:
> On Mon, Jun 22, 2026 at 09:29:20AM +0200, Krzysztof Kozlowski wrote:
>> On Sat, Jun 20, 2026 at 10:54:00AM +0200, Otto Pflüger wrote:
>>> Add bindings for the regulators found in the Spreadtrum/Unisoc SC2730
>>> PMIC, used e.g. with the UMS512 and UMS9230 SoCs.
>>>
>>> Signed-off-by: Otto Pflüger <otto.pflueger@abscue.de>
>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
>>> ---
>>> .../bindings/regulator/sprd,sc2730-regulator.yaml | 44 ++++++++++++++++++++++
>>> 1 file changed, 44 insertions(+)
>>>
>>
>> Sashiko has good point - where is any user of this binding (through
>> reference)? Without $ref, this won't match thus is a noop for validation.
>
> For some reason, the patch adding the binding references from v3 of
> this series was merged by Lee Jones. This means that a user exists now:
> Documentation/devicetree/bindings/mfd/sprd,sc2731.yaml includes this
> binding as one of the options.
Explain that in the cover letter, if you ever send something like this
(or v7).
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v5 2/3] counter: add GPIO-based counter driver
From: Oleksij Rempel @ 2026-06-23 5:20 UTC (permalink / raw)
To: Wadim Mueller
Cc: William Breathitt Gray, robh, conor+dt, devicetree, linux-iio,
linux-kernel, kernel, krzk+dt
In-Reply-To: <20260622205210.10317-1-wafgo01@gmail.com>
Hi,
On Mon, Jun 22, 2026 at 10:51:40PM +0200, Wadim Mueller wrote:
> On Wed, 17 Jun 2026 16:49:25 +0900
> William Breathitt Gray <wbg@kernel.org> wrote:
>
> Hi William,
>
> thanks for the review. Three things before I spin v6.
>
> > One change I consider is whether to make Signal B optional. [...]
> > I wonder whether this is substantially different enough from
> > simply using the interrupt-cnt module on the respective IRQ?
> > I'm CCing Oleksij and the Pengutronix team in case they wish to
> > comment.
>
> I want to keep signal-b mandatory in v6 (if no concerns from Oleksij).
> The single-line case is already covered by interrupt-cnt.
Hm, I have nothing against extending the existing driver.
If you wont to enforce and validate multi line concept, additional
compatible will be needed. May be interrupt-counter-multiline ?
Please add separate interrupt handler, interrupt_cnt_isr is already
"over optimized". Adding more code to this hot path, will break existing
configurations.
Best Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCH net v5 1/4] net: ethernet: oa_tc6: Interrupt is active low, level triggered.
From: Parthiban.Veerasooran @ 2026-06-23 5:19 UTC (permalink / raw)
To: Selvamani.Rajagopal, andrew+netdev, davem, edumazet, kuba, pabeni,
robh, krzk+dt, conor+dt, Pier.Beruto
Cc: andrew, netdev, linux-kernel, Conor.Dooley, devicetree
In-Reply-To: <CYYPR02MB9828A1434E6339A6CFCCA74283EF2@CYYPR02MB9828.namprd02.prod.outlook.com>
Hi Selvamani,
On 22/06/26 10:44 am, Selvamani Rajagopal wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>>
>> AI review bot Sashiko suggested one potential issue where skb pointers aren't protected.
>> But those
>> concerns are in transmit path. This crash seems to be in receive path. If you think that
>> might help,
>> I can generate a patch for that.
>
>
> Parthiban,
>
> I just submitted a patch for "net" tree. I was able to see one crash though. Crash signature
> was different from yours. As I remember, yours is NULL pointer access. Mine was due to
> trying to place the data beyond the "end" point.
>
> Anyway, if you have time to spare and want to try and see if it fixes your crash, I would appreciate
> the feedback..
>
> https://patchwork.kernel.org/project/netdevbpf/list/?series=1114495
Thank you for the update, and I appreciate your efforts.
I will find some time this week to test and share my feedback. In the
meantime, would it be possible for you to test using two instances (Test
Case 2)? I did not encounter many issues when testing with a single
instance.
I believe that testing with two instances increases the likelihood of
reproducing the issue in your setup as well.
Best regards,
Parthiban V
>
>>
>> What do you suggest? Since you are able to see the crash, would you have time to
>> investigate?
>>
>> Sincerely
>> Selva
^ permalink raw reply
* Re: [PATCH net v5 1/4] net: ethernet: oa_tc6: Interrupt is active low, level triggered.
From: Parthiban.Veerasooran @ 2026-06-23 5:19 UTC (permalink / raw)
To: Selvamani.Rajagopal, andrew+netdev, davem, edumazet, kuba, pabeni,
robh, krzk+dt, conor+dt, Pier.Beruto
Cc: andrew, netdev, linux-kernel, Conor.Dooley, devicetree
In-Reply-To: <CYYPR02MB9828A1434E6339A6CFCCA74283EF2@CYYPR02MB9828.namprd02.prod.outlook.com>
Hi Selvamani,
On 22/06/26 10:44 am, Selvamani Rajagopal wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
>>
>> AI review bot Sashiko suggested one potential issue where skb pointers aren't protected.
>> But those
>> concerns are in transmit path. This crash seems to be in receive path. If you think that
>> might help,
>> I can generate a patch for that.
>
>
> Parthiban,
>
> I just submitted a patch for "net" tree. I was able to see one crash though. Crash signature
> was different from yours. As I remember, yours is NULL pointer access. Mine was due to
> trying to place the data beyond the "end" point.
>
> Anyway, if you have time to spare and want to try and see if it fixes your crash, I would appreciate
> the feedback..
>
> https://patchwork.kernel.org/project/netdevbpf/list/?series=1114495
Thank you for the update, and I appreciate your efforts.
I will find some time this week to test and share my feedback. In the
meantime, would it be possible for you to test using two instances (Test
Case 2)? I did not encounter many issues when testing with a single
instance.
I believe that testing with two instances increases the likelihood of
reproducing the issue in your setup as well.
Best regards,
Parthiban V
>
>>
>> What do you suggest? Since you are able to see the crash, would you have time to
>> investigate?
>>
>> Sincerely
>> Selva
^ permalink raw reply
* Re: [PATCH 1/9] dt-bindings: nvmem: imx-ocotp: Add support for secure-enclave
From: Peng Fan @ 2026-06-23 4:18 UTC (permalink / raw)
To: Frank Li
Cc: Frieder Schrempf, Krzysztof Kozlowski, Frieder Schrempf,
Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Shawn Guo, devicetree, imx, linux-arm-kernel,
linux-kernel
In-Reply-To: <ajlDU6FVl8XIjCWW@SMW015318>
On Mon, Jun 22, 2026 at 09:14:43AM -0500, Frank Li wrote:
>On Wed, Jun 17, 2026 at 01:36:30PM +0200, Frieder Schrempf wrote:
>> On 17.06.26 12:49, Krzysztof Kozlowski wrote:
>> > On Tue, Jun 16, 2026 at 01:52:16PM +0200, Frieder Schrempf wrote:
>> >> From: Frieder Schrempf <frieder.schrempf@kontron.de>
>> >>
>> >> Some SoCs like the i.MX9 family allow full access to the fuses only
>> >> through the secure enclave firmware API. Add a property to reference
>> >> the secure enclave node and let the driver use the API.
>> >>
>> >> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
>> >> ---
>> >> Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml | 4 ++++
>> >> 1 file changed, 4 insertions(+)
>> >>
>> >> diff --git a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
>> >> index a8076d0e2737..14a6429f4a4c 100644
>> >> --- a/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
>> >> +++ b/Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
>> >> @@ -53,6 +53,10 @@ properties:
>> >> reg:
>> >> maxItems: 1
>> >>
>> >> + secure-enclave:
>> >> + $ref: /schemas/types.yaml#/definitions/phandle
>> >> + description: A phandle to the secure enclave node
>> >
>> > Two things here:
>> > 1. Here you describe what for is that phandle, how it is used by the
>> > hardware. Currently the description repeats the property name and type,
>> > so not much useful.
>>
>> Ok, agree.
>>
>> >
>> > 2. If you access OTP via firmware, then this is completely different
>> > interface than MMIO, thus:
>> > A. reg is not appropriate
>> > B. Device is very different thus it has different compatible and I even
>> > claim should be in different binding. Devices having completely
>> > different SW interface should not be in the same binding, at least
>> > usually.
>> >
>> > If any of above is not accurate, then your commit msg should answer why
>> > and give some background.
>>
>> Thanks for the feedback!
>>
>> The driver currently uses the limited MMIO (FSB) interface to access the
>> OTPs. The intention is to support the firmware interface alongside the
>> MMIO interface so the driver can pick the interface that is available
>> (firmware might not be loaded) and fallback to MMIO.
>
>Does ELE and MMIO access the same bank of fuse? If access the same bank,
Some fuse banks are only accessible through ELE firmware. Some fuse banks
are accessible using MMIO. In theory, ELE firmware are able to access all
fuse banks.
Regards
Peng
>why not always use MMIO. Any beneafit from ELE firmware?
>
>Frank
>>
>> Following your argument would mean a driver deciding by itself which
>> interface to use at runtime is not something we want to have in general,
>> right?
>>
>> In turn this would mean we need two drivers, or at least two
>> compatibles/bindings for something that is effectively the same hardware.
>>
>> Actually, my first RFC approach [1] was to create a separate driver. But
>> in the end it seemed very weird to have two drivers and two DT nodes for
>> the same hardware block. Also I have no idea what happens if both
>> interfaces are used at the same time.
>>
>> The other idea from back then was to replace the MMIO (FSB) interface
>> with ELE, but this would mean that we rely on the proprietary ELE
>> firmware to be available for simple things like reading a MAC address,
>> which is not desirable either, I guess.
>>
>> In which direction should I move on with this?
>>
>> [1]
>> https://patchwork.kernel.org/project/linux-arm-kernel/patch/20250416142715.1042363-1-frieder@fris.de/
>>
^ permalink raw reply
* Re: [PATCH v11 3/3] media: nxp: Add i.MX95 CSI pixel formatter v4l2 driver
From: sashiko-bot @ 2026-06-23 4:05 UTC (permalink / raw)
To: guoniu.zhou; +Cc: robh, imx, devicetree, Frank.Li, conor+dt
In-Reply-To: <20260623-csi_formatter-v11-3-a792fe9c1502@oss.nxp.com>
Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
- [High] Missing NULL check for the return value of v4l2_subdev_state_get_format() in pad operations, causing a NULL pointer dereference.
- [High] The driver incorrectly assumes source stream IDs match sink stream IDs during stream start, leading to a NULL pointer dereference.
- [High] Unbalanced PM runtime put in `csi_formatter_subdev_disable_streams` due to state desynchronization on failure.
- [High] Dangling `csi_sd` pointer leading to Use-After-Free if the remote subdevice is unbound.
- [Medium] The driver fails to validate stream ID bounds, silently ignoring stream IDs >= 8.
- [Medium] Overwriting the Virtual Channel Data Type register breaks multiplexed streams sharing the same VC.
- [Medium] Mixing `goto`-based error handling with scope-based cleanup helpers (`__free` and `guard`) in the same function.
- [Medium] Setting the format on an unrouted sink stream incorrectly fails with `-EINVAL`.
--
commit cca7db4730915ca13295d8053b3569d5e6266e0d
Author: Guoniu Zhou <guoniu.zhou@nxp.com>
Subject: media: nxp: Add i.MX95 CSI pixel formatter v4l2 driver
This commit introduces the i.MX95 CSI pixel formatter v4l2 driver,
adding data formatting support to match Pixel Link (PL) definitions.
diff --git a/drivers/media/platform/nxp/imx95-csi-formatter.c b/drivers/media/platform/nxp/imx95-csi-formatter.c
new file mode 100644
index 0000000000000..cfe448fedd37e
--- /dev/null
+++ b/drivers/media/platform/nxp/imx95-csi-formatter.c
@@ -0,0 +1,775 @@
[ ... ]
> +static int csi_formatter_subdev_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_mbus_code_enum *code)
> +{
> + if (code->pad == CSI_FORMATTER_PAD_SOURCE) {
> + struct v4l2_mbus_framefmt *fmt;
> +
> + if (code->index > 0)
> + return -EINVAL;
> +
> + fmt = v4l2_subdev_state_get_format(sd_state, code->pad,
> + code->stream);
> + code->code = fmt->code;
[Severity: High]
Is there a missing NULL check here?
If the requested stream is not found in the state,
v4l2_subdev_state_get_format() returns NULL, which would cause a crash when
dereferencing fmt->code.
Userspace might trigger this by passing an invalid stream ID.
> + return 0;
> + }
[ ... ]
> +static int csi_formatter_subdev_set_fmt(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_format *sdformat)
> +{
> + struct csi_formatter_pix_format const *format;
> + struct v4l2_mbus_framefmt *fmt;
[ ... ]
> + v4l_bound_align_image(&sdformat->format.width, 1, 0xffff, 2,
> + &sdformat->format.height, 1, 0xffff, 0, 0);
> +
> + fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad,
> + sdformat->stream);
> + *fmt = sdformat->format;
[Severity: High]
Can this result in a NULL pointer dereference?
Similar to the enum_mbus_code operation above, v4l2_subdev_state_get_format()
can return NULL if the stream is invalid.
> +
> + /* Set default code if user set an invalid value */
> + fmt->code = format->code;
> +
> + /* Propagate the format from sink stream to source stream */
> + fmt = v4l2_subdev_state_get_opposite_stream_format(sd_state, sdformat->pad,
> + sdformat->stream);
> + if (!fmt)
> + return -EINVAL;
[Severity: Medium]
Should this return -EINVAL when there is no internal route configured?
Valid requests to set the format on an unrouted sink stream will fail here,
which seems to violate V4L2 semantics where the format on the local sink pad
should still be accepted even without an active route.
> +
> + *fmt = sdformat->format;
> +
> + return 0;
> +}
[ ... ]
> +static int csi_formatter_start_stream(struct csi_formatter *formatter,
> + struct v4l2_subdev_state *state,
> + u64 stream_mask)
> +{
[ ... ]
> + for (i = 0; i < CSI_FORMATTER_VC_NUM; ++i) {
> + if (!(stream_mask & BIT(i)))
> + continue;
[Severity: Medium]
Does this fail to configure stream IDs higher than 7?
The loop terminates at CSI_FORMATTER_VC_NUM (which is 8), silently skipping
any higher stream IDs present in the stream_mask.
V4L2 subdev routing allows stream IDs up to 63.
> +
> + fmt = v4l2_subdev_state_get_format(state,
> + CSI_FORMATTER_PAD_SINK, i);
> +
> + pix_fmt = csi_formatter_find_format(fmt->code);
[Severity: High]
Could this crash if the source stream ID does not match the sink stream ID?
The index i iterates over the source pad's stream_mask, but it is used here
to query the format of CSI_FORMATTER_PAD_SINK.
If userspace configures a route where the sink stream ID differs from the
source stream ID, get_format() will return NULL, leading to a crash when
accessing fmt->code.
> +
> + val = BIT(csi_formatter_get_index_by_dt(pix_fmt->data_type));
[ ... ]
> + /* Store the stream to VC mapping for stop_stream */
> + formatter->stream_to_vc[i] = vc;
> +
> + csi_formatter_write(formatter, CSI_VC_PIXEL_DATA_TYPE(vc), val);
[Severity: Medium]
Will this break multiplexed streams sharing the same virtual channel?
Writing directly to the register completely overwrites the configuration
with the new single bit, which would destroy any existing active data type
bindings for that virtual channel.
Would a read-modify-write operation be more appropriate here?
> + configured_streams |= BIT(i);
> + }
> +
> + return 0;
> +
> +err_cleanup:
> + csi_formatter_stop_stream(formatter, configured_streams);
> + return ret;
> +}
[ ... ]
> +static int csi_formatter_subdev_enable_streams(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + u32 pad, u64 streams_mask)
> +{
[ ... ]
> + sink_streams = v4l2_subdev_state_xlate_streams(state,
> + CSI_FORMATTER_PAD_SOURCE,
> + CSI_FORMATTER_PAD_SINK,
> + &streams_mask);
> + if (!sink_streams || !streams_mask)
> + return -EINVAL;
> +
> + guard(mutex)(&formatter->lock);
> +
> + if (!formatter->enabled_streams) {
[ ... ]
> + ret = csi_formatter_start_stream(formatter, state, streams_mask);
[Severity: High]
Is the wrong mask passed to csi_formatter_start_stream here?
It passes the source pad's streams_mask instead of the translated
sink_streams mask.
> + if (ret)
> + goto err_runtime_put;
> +
> + ret = v4l2_subdev_enable_streams(formatter->csi_sd,
> + formatter->remote_pad,
> + sink_streams);
> + if (ret)
> + goto err_stop_stream;
> +
> + formatter->enabled_streams |= streams_mask;
> +
> + return 0;
> +
> +err_stop_stream:
> + csi_formatter_stop_stream(formatter, streams_mask);
> +err_runtime_put:
> + if (!formatter->enabled_streams)
> + pm_runtime_put(formatter->dev);
> + return ret;
> +}
[Severity: Medium]
Is it safe to mix goto-based error handling with scope-based cleanup helpers
in this function?
This function uses guard(mutex) for lock management but also contains goto
labels for error unwinding. Mixing these approaches can create confusing
resource ownership semantics.
> +
> +static int csi_formatter_subdev_disable_streams(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *state,
> + u32 pad, u64 streams_mask)
> +{
[ ... ]
> + ret = v4l2_subdev_disable_streams(formatter->csi_sd, formatter->remote_pad,
> + sink_streams);
> + if (ret)
> + dev_err(formatter->dev, "Failed to disable streams: %d\n", ret);
> +
> + csi_formatter_stop_stream(formatter, streams_mask);
> +
> + formatter->enabled_streams &= ~streams_mask;
> +
> + if (!formatter->enabled_streams)
> + pm_runtime_put(formatter->dev);
> +
> + return ret;
> +}
[Severity: High]
Can this cause an unbalanced pm_runtime_put() if disable streams fails?
If the upstream v4l2_subdev_disable_streams() call fails, the function
still clears the bit in enabled_streams and calls pm_runtime_put().
If userspace later retries stopping the stream, this code will run again.
Because enabled_streams is already zero, the condition
!formatter->enabled_streams evaluates to true, causing a second
pm_runtime_put() call.
[ ... ]
> +static const struct v4l2_async_notifier_operations formatter_notify_ops = {
> + .bound = csi_formatter_notify_bound,
> +};
[Severity: High]
Does this missing unbind callback lead to a use-after-free?
The driver stores the remote subdevice pointer in csi_sd during the bound
callback, but does not provide an unbind callback to clear it.
If the remote sensor module is unloaded, the dangling csi_sd pointer could be
dereferenced by subsequent stream ioctls.
[ ... ]
> +static int csi_formatter_async_register(struct csi_formatter *formatter)
> +{
[ ... ]
> + struct fwnode_handle *ep __free(fwnode_handle) =
> + fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
> + FWNODE_GRAPH_ENDPOINT_NEXT);
> + if (!ep)
> + return -ENOTCONN;
[ ... ]
> + ret = v4l2_async_nf_register(&formatter->notifier);
> + if (ret)
> + goto err_cleanup_notifier;
[ ... ]
> +err_unregister_notifier:
> + v4l2_async_nf_unregister(&formatter->notifier);
> +err_cleanup_notifier:
> + v4l2_async_nf_cleanup(&formatter->notifier);
> + return ret;
> +}
[Severity: Medium]
Is it safe to mix goto-based error handling with scope-based cleanup helpers
in this function?
This function declares a __free() variable but also uses standard goto
unwinding labels, which can lead to double-free issues or confusing
resource semantics.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260623-csi_formatter-v11-0-a792fe9c1502@oss.nxp.com?part=3
^ permalink raw reply related
* [PATCH v11 3/3] media: nxp: Add i.MX95 CSI pixel formatter v4l2 driver
From: guoniu.zhou @ 2026-06-23 3:56 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
linux-clk, Guoniu Zhou, Frank Li
In-Reply-To: <20260623-csi_formatter-v11-0-a792fe9c1502@oss.nxp.com>
From: Guoniu Zhou <guoniu.zhou@nxp.com>
The CSI pixel formatter is a module found on i.MX95 used to reformat
packet info, pixel and non-pixel data from CSI-2 host controller to
match Pixel Link(PL) definition.
Add data formatting support.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
Changes in v10:
- Use u8 for vc in csi_formatter_get_vc() and drop vc < 0 check
- Add MFD_SYSCON dependency to Kconfig
- Fix stream/VC mapping potential mismatch in start/stop_stream functions
Changes in v8:
- Remove fmt field and look up format from subdev state instead
- Unify function and structure naming to use csi_formatter_ prefix
- Remove misleading alignment comment from set_fmt function
- Optimize get_frame_desc to call once per start_stream
- Replace V4L2_FRAME_DESC_ENTRY_MAX with CSI_FORMATTER_VC_NUM in loops
- Remove redundant debug message in enable_streams
- Use MEDIA_PAD_FL_MUST_CONNECT flag instead of manual link check
- Fix typo: Formater -> Formatter in Kconfig help text
- Improve grammar in data type index mapping comment
Changes in v7:
- Update references from imx9 to imx95 for consistency with dt-bindings
- Enable PM runtime before async registration
Changes in v6:
- Remove unused header includes
- Unify macro naming: VCx/VCX -> VC and parameter x -> vc
- Remove unused format field from csi_formatter struct
- Use compact initialization for formats array
- Make find_csi_format() return NULL instead of default format
- Use unsigned int for array index in find_csi_format()
- Add err_ prefix to error handling labels
- Add v4l2_subdev_cleanup() and reorder cleanup sequence
- Update enable_streams debug output format
- Rename VC_MAX to VC_NUM and fix boundary check
- Update CSI formatter Kconfig description
- Use v4l2_subdev_get_frame_desc_passthrough() helper
- Fix error paths in async registration and probe
- Add mutex to protect enabled_streams
- Switch to devm_pm_runtime_enable()
- Remove redundant num_routes check in set_routing
- Optimize get_index_by_dt() and add warning for unsupported type
- csi_formatter_start/stop_stream: Process all streams in mask
---
MAINTAINERS | 8 +
drivers/media/platform/nxp/Kconfig | 15 +
drivers/media/platform/nxp/Makefile | 1 +
drivers/media/platform/nxp/imx95-csi-formatter.c | 775 +++++++++++++++++++++++
4 files changed, 799 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index efbf808063e5..05009228b162 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19275,6 +19275,14 @@ S: Maintained
F: Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
F: drivers/media/platform/nxp/imx-jpeg
+NXP i.MX 95 CSI PIXEL FORMATTER V4L2 DRIVER
+M: Guoniu Zhou <guoniu.zhou@nxp.com>
+L: imx@lists.linux.dev
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
+F: drivers/media/platform/nxp/imx95-csi-formatter.c
+
NXP i.MX CLOCK DRIVERS
M: Abel Vesa <abelvesa@kernel.org>
R: Peng Fan <peng.fan@nxp.com>
diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
index 40e3436669e2..8f49908b0022 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -28,6 +28,21 @@ config VIDEO_IMX8MQ_MIPI_CSI2
Video4Linux2 driver for the MIPI CSI-2 receiver found on the i.MX8MQ
SoC.
+config VIDEO_IMX95_CSI_FORMATTER
+ tristate "NXP i.MX95 CSI Pixel Formatter driver"
+ depends on ARCH_MXC || COMPILE_TEST
+ depends on MFD_SYSCON
+ depends on VIDEO_DEV
+ select MEDIA_CONTROLLER
+ select V4L2_FWNODE
+ select VIDEO_V4L2_SUBDEV_API
+ help
+ This driver provides support for the CSI Pixel Formatter found on
+ i.MX95 series SoCs. This module unpacks the pixels received from the
+ CSI-2 interface and reformats them to meet pixel link requirements.
+
+ Say Y here to enable CSI Pixel Formatter module for i.MX95 SoC.
+
config VIDEO_IMX_MIPI_CSIS
tristate "NXP MIPI CSI-2 CSIS receiver found on i.MX7 and i.MX8 models"
depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile
index 4d90eb713652..6410115d870e 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -6,6 +6,7 @@ obj-y += imx8-isi/
obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-media-csi.o
obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
+obj-$(CONFIG_VIDEO_IMX95_CSI_FORMATTER) += imx95-csi-formatter.o
obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
diff --git a/drivers/media/platform/nxp/imx95-csi-formatter.c b/drivers/media/platform/nxp/imx95-csi-formatter.c
new file mode 100644
index 000000000000..cfe448fedd37
--- /dev/null
+++ b/drivers/media/platform/nxp/imx95-csi-formatter.c
@@ -0,0 +1,775 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2025 NXP
+ */
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <media/mipi-csi2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+/* CSI Pixel Formatter registers map */
+
+#define CSI_VC_INTERLACED_LINE_CNT(vc) (0x00 + (vc) * 0x04)
+#define INTERLACED_ODD_LINE_CNT_SET(x) FIELD_PREP(GENMASK(13, 0), (x))
+#define INTERLACED_EVEN_LINE_CNT_SET(x) FIELD_PREP(GENMASK(29, 16), (x))
+
+#define CSI_VC_INTERLACED_CTRL 0x20
+
+#define CSI_VC_INTERLACED_ERR 0x24
+#define CSI_VC_ERR_MASK GENMASK(7, 0)
+#define CSI_VC_ERR(vc) BIT((vc))
+
+#define CSI_VC_YUV420_FIRST_LINE_EVEN 0x28
+#define YUV420_FIRST_LINE_EVEN(vc) BIT((vc))
+
+#define CSI_RAW32_CTRL 0x30
+#define CSI_VC_RAW32_MODE(vc) BIT((vc))
+#define CSI_VC_RAW32_SWAP_MODE(vc) BIT((vc) + 8)
+
+#define CSI_STREAM_FENCING_CTRL 0x34
+#define CSI_VC_STREAM_FENCING(vc) BIT((vc))
+#define CSI_VC_STREAM_FENCING_RST(vc) BIT((vc) + 8)
+
+#define CSI_STREAM_FENCING_STS 0x38
+#define CSI_STREAM_FENCING_STS_MASK GENMASK(7, 0)
+
+#define CSI_VC_NON_PIXEL_DATA_TYPE(vc) (0x40 + (vc) * 0x04)
+
+#define CSI_VC_PIXEL_DATA_CTRL(vc) (0x60 + (vc) * 0x04)
+#define NEW_VC(vc) FIELD_PREP(GENMASK(3, 1), vc)
+#define REROUTE_VC_ENABLE BIT(0)
+
+#define CSI_VC_ROUTE_PIXEL_DATA_TYPE(vc) (0x80 + (vc) * 0x04)
+
+#define CSI_VC_NON_PIXEL_DATA_CTRL(vc) (0xa0 + (vc) * 0x04)
+
+#define CSI_VC_PIXEL_DATA_TYPE(vc) (0xc0 + (vc) * 0x04)
+
+#define CSI_VC_PIXEL_DATA_TYPE_ERR(vc) (0xe0 + (vc) * 0x04)
+
+#define CSI_FORMATTER_PAD_SINK 0
+#define CSI_FORMATTER_PAD_SOURCE 1
+#define CSI_FORMATTER_PAD_NUM 2
+
+#define CSI_FORMATTER_VC_NUM 8 /* Number of virtual channels */
+
+struct csi_formatter_pix_format {
+ u32 code;
+ u32 data_type;
+};
+
+struct csi_formatter {
+ struct device *dev;
+ struct regmap *regs;
+ struct clk *clk;
+
+ struct v4l2_subdev sd;
+ struct v4l2_subdev *csi_sd;
+ struct v4l2_async_notifier notifier;
+ struct media_pad pads[CSI_FORMATTER_PAD_NUM];
+
+ u32 remote_pad;
+ u32 reg_offset;
+
+ /* Protects enabled_streams */
+ struct mutex lock;
+ u64 enabled_streams;
+
+ u8 stream_to_vc[CSI_FORMATTER_VC_NUM];
+};
+
+struct csi_formatter_dt_index {
+ u8 dtype;
+ u8 index;
+};
+
+/*
+ * The index corresponds to the bit index in the register that enables
+ * the data type of pixel data transported by the Formatter.
+ */
+static const struct csi_formatter_dt_index formatter_dt_to_index_map[] = {
+ { .dtype = MIPI_CSI2_DT_YUV420_8B, .index = 0 },
+ { .dtype = MIPI_CSI2_DT_YUV420_8B_LEGACY, .index = 2 },
+ { .dtype = MIPI_CSI2_DT_YUV422_8B, .index = 6 },
+ { .dtype = MIPI_CSI2_DT_RGB444, .index = 8 },
+ { .dtype = MIPI_CSI2_DT_RGB555, .index = 9 },
+ { .dtype = MIPI_CSI2_DT_RGB565, .index = 10 },
+ { .dtype = MIPI_CSI2_DT_RGB666, .index = 11 },
+ { .dtype = MIPI_CSI2_DT_RGB888, .index = 12 },
+ { .dtype = MIPI_CSI2_DT_RAW6, .index = 16 },
+ { .dtype = MIPI_CSI2_DT_RAW7, .index = 17 },
+ { .dtype = MIPI_CSI2_DT_RAW8, .index = 18 },
+ { .dtype = MIPI_CSI2_DT_RAW10, .index = 19 },
+ { .dtype = MIPI_CSI2_DT_RAW12, .index = 20 },
+ { .dtype = MIPI_CSI2_DT_RAW14, .index = 21 },
+ { .dtype = MIPI_CSI2_DT_RAW16, .index = 22 },
+};
+
+static const struct csi_formatter_pix_format formats[] = {
+ /* YUV formats */
+ { MEDIA_BUS_FMT_UYVY8_1X16, MIPI_CSI2_DT_YUV422_8B },
+ /* RGB formats */
+ { MEDIA_BUS_FMT_RGB565_1X16, MIPI_CSI2_DT_RGB565 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MIPI_CSI2_DT_RGB888 },
+ /* RAW (Bayer and greyscale) formats */
+ { MEDIA_BUS_FMT_SBGGR8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SGBRG8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SGRBG8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SRGGB8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_Y8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SBGGR10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SGBRG10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SRGGB10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_Y10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SBGGR12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SGBRG12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SGRBG12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SRGGB12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_Y12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SBGGR14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SGBRG14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SGRBG14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SRGGB14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SBGGR16_1X16, MIPI_CSI2_DT_RAW16 },
+ { MEDIA_BUS_FMT_SGBRG16_1X16, MIPI_CSI2_DT_RAW16 },
+ { MEDIA_BUS_FMT_SGRBG16_1X16, MIPI_CSI2_DT_RAW16 },
+ { MEDIA_BUS_FMT_SRGGB16_1X16, MIPI_CSI2_DT_RAW16 },
+};
+
+static const struct v4l2_mbus_framefmt formatter_default_fmt = {
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .width = 1920U,
+ .height = 1080U,
+ .field = V4L2_FIELD_NONE,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
+ .xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+ .ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+ .quantization = V4L2_QUANTIZATION_LIM_RANGE,
+};
+
+static const struct csi_formatter_pix_format *csi_formatter_find_format(u32 code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++)
+ if (code == formats[i].code)
+ return &formats[i];
+
+ return NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev operations
+ */
+
+static inline struct csi_formatter *sd_to_formatter(struct v4l2_subdev *sdev)
+{
+ return container_of(sdev, struct csi_formatter, sd);
+}
+
+static int __csi_formatter_subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_krouting *routing)
+{
+ int ret;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ return v4l2_subdev_set_routing_with_fmt(sd, state, routing,
+ &formatter_default_fmt);
+}
+
+static int csi_formatter_subdev_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+{
+ struct v4l2_subdev_route routes[] = {
+ {
+ .sink_pad = CSI_FORMATTER_PAD_SINK,
+ .sink_stream = 0,
+ .source_pad = CSI_FORMATTER_PAD_SOURCE,
+ .source_stream = 0,
+ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+ },
+ };
+
+ struct v4l2_subdev_krouting routing = {
+ .num_routes = ARRAY_SIZE(routes),
+ .routes = routes,
+ };
+
+ return __csi_formatter_subdev_set_routing(sd, sd_state, &routing);
+}
+
+static int csi_formatter_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad == CSI_FORMATTER_PAD_SOURCE) {
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (code->index > 0)
+ return -EINVAL;
+
+ fmt = v4l2_subdev_state_get_format(sd_state, code->pad,
+ code->stream);
+ code->code = fmt->code;
+ return 0;
+ }
+
+ if (code->index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+ code->code = formats[code->index].code;
+
+ return 0;
+}
+
+static int csi_formatter_subdev_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *sdformat)
+{
+ struct csi_formatter_pix_format const *format;
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (sdformat->pad == CSI_FORMATTER_PAD_SOURCE)
+ return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
+
+ format = csi_formatter_find_format(sdformat->format.code);
+ if (!format)
+ format = &formats[0];
+
+ v4l_bound_align_image(&sdformat->format.width, 1, 0xffff, 2,
+ &sdformat->format.height, 1, 0xffff, 0, 0);
+
+ fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad,
+ sdformat->stream);
+ *fmt = sdformat->format;
+
+ /* Set default code if user set an invalid value */
+ fmt->code = format->code;
+
+ /* Propagate the format from sink stream to source stream */
+ fmt = v4l2_subdev_state_get_opposite_stream_format(sd_state, sdformat->pad,
+ sdformat->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = sdformat->format;
+
+ return 0;
+}
+
+static int csi_formatter_subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE &&
+ media_entity_is_streaming(&sd->entity))
+ return -EBUSY;
+
+ return __csi_formatter_subdev_set_routing(sd, state, routing);
+}
+
+static inline void csi_formatter_write(struct csi_formatter *formatter,
+ unsigned int reg, unsigned int value)
+{
+ u32 offset = formatter->reg_offset;
+
+ regmap_write(formatter->regs, reg + offset, value);
+}
+
+static u8 csi_formatter_get_index_by_dt(u8 data_type)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formatter_dt_to_index_map); ++i) {
+ const struct csi_formatter_dt_index *entry =
+ &formatter_dt_to_index_map[i];
+
+ if (data_type == entry->dtype)
+ return entry->index;
+ }
+
+ pr_warn_once("Unsupported data type 0x%x, using default\n", data_type);
+
+ return formatter_dt_to_index_map[0].index;
+}
+
+static int csi_formatter_get_vc(struct csi_formatter *formatter,
+ struct v4l2_mbus_frame_desc *fd,
+ unsigned int stream)
+{
+ struct v4l2_mbus_frame_desc_entry *entry = NULL;
+ unsigned int i;
+ u8 vc;
+
+ for (i = 0; i < fd->num_entries; ++i) {
+ if (fd->entry[i].stream == stream) {
+ entry = &fd->entry[i];
+ break;
+ }
+ }
+
+ if (!entry) {
+ dev_err(formatter->dev,
+ "No frame desc entry for stream %u\n", stream);
+ return -EPIPE;
+ }
+
+ vc = entry->bus.csi2.vc;
+
+ if (vc >= CSI_FORMATTER_VC_NUM) {
+ dev_err(formatter->dev, "Invalid virtual channel %u\n", vc);
+ return -EINVAL;
+ }
+
+ return vc;
+}
+
+static void csi_formatter_stop_stream(struct csi_formatter *formatter,
+ u64 stream_mask)
+{
+ unsigned int i;
+ u8 vc;
+
+ for (i = 0; i < CSI_FORMATTER_VC_NUM; ++i) {
+ if (!(stream_mask & BIT(i)))
+ continue;
+
+ /* Use the VC that was configured in start_stream */
+ vc = formatter->stream_to_vc[i];
+ if (vc >= CSI_FORMATTER_VC_NUM)
+ continue;
+
+ csi_formatter_write(formatter, CSI_VC_PIXEL_DATA_TYPE(vc), 0);
+
+ /* Clear after use */
+ formatter->stream_to_vc[i] = 0xff;
+ }
+}
+
+static int csi_formatter_start_stream(struct csi_formatter *formatter,
+ struct v4l2_subdev_state *state,
+ u64 stream_mask)
+{
+ const struct csi_formatter_pix_format *pix_fmt;
+ struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_mbus_frame_desc fd = {};
+ u64 configured_streams = 0;
+ unsigned int i;
+ u32 val;
+ int vc;
+ int ret;
+
+ ret = v4l2_subdev_call(formatter->csi_sd, pad, get_frame_desc,
+ formatter->remote_pad, &fd);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ dev_err(formatter->dev, "Failed to get frame desc: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < CSI_FORMATTER_VC_NUM; ++i) {
+ if (!(stream_mask & BIT(i)))
+ continue;
+
+ fmt = v4l2_subdev_state_get_format(state,
+ CSI_FORMATTER_PAD_SINK, i);
+
+ pix_fmt = csi_formatter_find_format(fmt->code);
+
+ val = BIT(csi_formatter_get_index_by_dt(pix_fmt->data_type));
+
+ if (ret == -ENOIOCTLCMD) {
+ /*
+ * Source doesn't implement get_frame_desc, use
+ * default VC 0
+ */
+ vc = 0;
+ } else {
+ vc = csi_formatter_get_vc(formatter, &fd, i);
+ if (vc < 0) {
+ ret = vc;
+ goto err_cleanup;
+ }
+ }
+
+ /* Store the stream to VC mapping for stop_stream */
+ formatter->stream_to_vc[i] = vc;
+
+ csi_formatter_write(formatter, CSI_VC_PIXEL_DATA_TYPE(vc), val);
+ configured_streams |= BIT(i);
+ }
+
+ return 0;
+
+err_cleanup:
+ csi_formatter_stop_stream(formatter, configured_streams);
+ return ret;
+}
+
+static int csi_formatter_subdev_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+ struct device *dev = formatter->dev;
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ CSI_FORMATTER_PAD_SOURCE,
+ CSI_FORMATTER_PAD_SINK,
+ &streams_mask);
+ if (!sink_streams || !streams_mask)
+ return -EINVAL;
+
+ guard(mutex)(&formatter->lock);
+
+ if (!formatter->enabled_streams) {
+ ret = pm_runtime_resume_and_get(formatter->dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to resume runtime PM: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = csi_formatter_start_stream(formatter, state, streams_mask);
+ if (ret)
+ goto err_runtime_put;
+
+ ret = v4l2_subdev_enable_streams(formatter->csi_sd,
+ formatter->remote_pad,
+ sink_streams);
+ if (ret)
+ goto err_stop_stream;
+
+ formatter->enabled_streams |= streams_mask;
+
+ return 0;
+
+err_stop_stream:
+ csi_formatter_stop_stream(formatter, streams_mask);
+err_runtime_put:
+ if (!formatter->enabled_streams)
+ pm_runtime_put(formatter->dev);
+ return ret;
+}
+
+static int csi_formatter_subdev_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ CSI_FORMATTER_PAD_SOURCE,
+ CSI_FORMATTER_PAD_SINK,
+ &streams_mask);
+ if (!sink_streams || !streams_mask)
+ return -EINVAL;
+
+ guard(mutex)(&formatter->lock);
+
+ ret = v4l2_subdev_disable_streams(formatter->csi_sd, formatter->remote_pad,
+ sink_streams);
+ if (ret)
+ dev_err(formatter->dev, "Failed to disable streams: %d\n", ret);
+
+ csi_formatter_stop_stream(formatter, streams_mask);
+
+ formatter->enabled_streams &= ~streams_mask;
+
+ if (!formatter->enabled_streams)
+ pm_runtime_put(formatter->dev);
+
+ return ret;
+}
+
+static const struct v4l2_subdev_pad_ops formatter_subdev_pad_ops = {
+ .enum_mbus_code = csi_formatter_subdev_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = csi_formatter_subdev_set_fmt,
+ .get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
+ .set_routing = csi_formatter_subdev_set_routing,
+ .enable_streams = csi_formatter_subdev_enable_streams,
+ .disable_streams = csi_formatter_subdev_disable_streams,
+};
+
+static const struct v4l2_subdev_ops formatter_subdev_ops = {
+ .pad = &formatter_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops formatter_internal_ops = {
+ .init_state = csi_formatter_subdev_init_state,
+};
+
+/* -----------------------------------------------------------------------------
+ * Media entity operations
+ */
+
+static const struct media_entity_operations formatter_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+ .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
+};
+
+static int csi_formatter_subdev_init(struct csi_formatter *formatter)
+{
+ struct v4l2_subdev *sd = &formatter->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &formatter_subdev_ops);
+
+ snprintf(sd->name, sizeof(sd->name), "%s", dev_name(formatter->dev));
+ sd->internal_ops = &formatter_internal_ops;
+
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+ V4L2_SUBDEV_FL_HAS_EVENTS |
+ V4L2_SUBDEV_FL_STREAMS;
+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
+ sd->entity.ops = &formatter_entity_ops;
+ sd->dev = formatter->dev;
+
+ formatter->pads[CSI_FORMATTER_PAD_SINK].flags = MEDIA_PAD_FL_SINK
+ | MEDIA_PAD_FL_MUST_CONNECT;
+ formatter->pads[CSI_FORMATTER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, CSI_FORMATTER_PAD_NUM,
+ formatter->pads);
+ if (ret) {
+ dev_err(formatter->dev, "Failed to init pads\n");
+ return ret;
+ }
+
+ ret = v4l2_subdev_init_finalize(sd);
+ if (ret)
+ media_entity_cleanup(&sd->entity);
+
+ return ret;
+}
+
+static inline struct csi_formatter *
+notifier_to_csi_formatter(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct csi_formatter, notifier);
+}
+
+static int csi_formatter_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_connection *asc)
+{
+ const unsigned int link_flags = MEDIA_LNK_FL_IMMUTABLE
+ | MEDIA_LNK_FL_ENABLED;
+ struct csi_formatter *formatter = notifier_to_csi_formatter(notifier);
+ struct v4l2_subdev *sdev = &formatter->sd;
+ struct media_pad *sink = &sdev->entity.pads[CSI_FORMATTER_PAD_SINK];
+ struct media_pad *remote_pad;
+ int ret;
+
+ formatter->csi_sd = sd;
+
+ dev_dbg(formatter->dev, "Bound subdev: %s pad\n", sd->name);
+
+ ret = v4l2_create_fwnode_links_to_pad(sd, sink, link_flags);
+ if (ret < 0)
+ return ret;
+
+ remote_pad = media_pad_remote_pad_first(sink);
+ if (!remote_pad) {
+ dev_err(formatter->dev, "Pipe not setup correctly\n");
+ return -EPIPE;
+ }
+ formatter->remote_pad = remote_pad->index;
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations formatter_notify_ops = {
+ .bound = csi_formatter_notify_bound,
+};
+
+static int csi_formatter_async_register(struct csi_formatter *formatter)
+{
+ struct device *dev = formatter->dev;
+ struct v4l2_async_connection *asc;
+ int ret;
+
+ struct fwnode_handle *ep __free(fwnode_handle) =
+ fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
+ FWNODE_GRAPH_ENDPOINT_NEXT);
+ if (!ep)
+ return -ENOTCONN;
+
+ v4l2_async_subdev_nf_init(&formatter->notifier, &formatter->sd);
+
+ asc = v4l2_async_nf_add_fwnode_remote(&formatter->notifier, ep,
+ struct v4l2_async_connection);
+ if (IS_ERR(asc)) {
+ ret = PTR_ERR(asc);
+ goto err_cleanup_notifier;
+ }
+
+ formatter->notifier.ops = &formatter_notify_ops;
+
+ ret = v4l2_async_nf_register(&formatter->notifier);
+ if (ret)
+ goto err_cleanup_notifier;
+
+ ret = v4l2_async_register_subdev(&formatter->sd);
+ if (ret)
+ goto err_unregister_notifier;
+
+ return 0;
+
+err_unregister_notifier:
+ v4l2_async_nf_unregister(&formatter->notifier);
+err_cleanup_notifier:
+ v4l2_async_nf_cleanup(&formatter->notifier);
+ return ret;
+}
+
+static void csi_formatter_async_unregister(struct csi_formatter *formatter)
+{
+ v4l2_async_unregister_subdev(&formatter->sd);
+ v4l2_async_nf_unregister(&formatter->notifier);
+ v4l2_async_nf_cleanup(&formatter->notifier);
+}
+
+/* -----------------------------------------------------------------------------
+ * Suspend/resume
+ */
+
+static int csi_formatter_runtime_suspend(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+
+ clk_disable_unprepare(formatter->clk);
+
+ return 0;
+}
+
+static int csi_formatter_runtime_resume(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+
+ return clk_prepare_enable(formatter->clk);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(csi_formatter_pm_ops,
+ csi_formatter_runtime_suspend,
+ csi_formatter_runtime_resume, NULL);
+
+static int csi_formatter_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct csi_formatter *formatter;
+ u32 val;
+ int ret;
+
+ formatter = devm_kzalloc(dev, sizeof(*formatter), GFP_KERNEL);
+ if (!formatter)
+ return -ENOMEM;
+
+ /* Initialize stream to VC mapping to invalid */
+ memset(formatter->stream_to_vc, 0xff, sizeof(formatter->stream_to_vc));
+
+ formatter->dev = dev;
+
+ ret = devm_mutex_init(dev, &formatter->lock);
+ if (ret)
+ return ret;
+
+ formatter->regs = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(formatter->regs))
+ return dev_err_probe(dev, PTR_ERR(formatter->regs),
+ "Failed to get csi formatter regmap\n");
+
+ ret = of_property_read_u32(dev->of_node, "reg", &val);
+ if (ret < 0)
+ return dev_err_probe(dev, ret,
+ "Failed to get csi formatter reg property\n");
+
+ formatter->reg_offset = val;
+
+ formatter->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(formatter->clk))
+ return dev_err_probe(dev, PTR_ERR(formatter->clk),
+ "Failed to get pixel clock\n");
+
+ ret = csi_formatter_subdev_init(formatter);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to initialize formatter subdev\n");
+
+ platform_set_drvdata(pdev, &formatter->sd);
+
+ /* Enable runtime PM. */
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ goto err_cleanup_subdev;
+
+ ret = csi_formatter_async_register(formatter);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "Failed to register async subdevice\n");
+ goto err_cleanup_subdev;
+ }
+
+ return 0;
+
+err_cleanup_subdev:
+ v4l2_subdev_cleanup(&formatter->sd);
+ media_entity_cleanup(&formatter->sd.entity);
+ return ret;
+}
+
+static void csi_formatter_remove(struct platform_device *pdev)
+{
+ struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+
+ csi_formatter_async_unregister(formatter);
+
+ v4l2_subdev_cleanup(&formatter->sd);
+ media_entity_cleanup(&formatter->sd.entity);
+}
+
+static const struct of_device_id csi_formatter_of_match[] = {
+ { .compatible = "fsl,imx95-csi-formatter" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, csi_formatter_of_match);
+
+static struct platform_driver csi_formatter_device_driver = {
+ .driver = {
+ .name = "csi-pixel-formatter",
+ .of_match_table = csi_formatter_of_match,
+ .pm = pm_ptr(&csi_formatter_pm_ops),
+ },
+ .probe = csi_formatter_probe,
+ .remove = csi_formatter_remove,
+};
+
+module_platform_driver(csi_formatter_device_driver);
+
+MODULE_AUTHOR("NXP Semiconductor, Inc.");
+MODULE_DESCRIPTION("NXP i.MX95 CSI Pixel Formatter driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
* [PATCH v11 2/3] dt-bindings: clock: imx95-blk-ctl: Define formatter child node schema
From: guoniu.zhou @ 2026-06-23 3:56 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
linux-clk, Guoniu Zhou
In-Reply-To: <20260623-csi_formatter-v11-0-a792fe9c1502@oss.nxp.com>
From: Guoniu Zhou <guoniu.zhou@nxp.com>
The Camera CSR contains control registers for multiple CSI formatter IPs
at different register offsets. Each formatter is an independent hardware
block with its own clock input and media pipeline connection.
Define schema to allow formatter child nodes under nxp,imx95-camera-csr,
with 'reg' property specifying the formatter's register offset within the
CSR address space.
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
Changes in v11:
- Move properties to top-level and use if:then:else (Krzysztof/Frank)
Changes in v10:
- Use single quotes for regex pattern to be consistent (Krzysztof Kozlowski)
- Add formatter subnode binding and camera-csr syscon example
- Update commit title and message
Changes in v9:
- New patch to address the issue of formatter acting as a child node of syscon
---
.../bindings/clock/nxp,imx95-blk-ctl.yaml | 71 ++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
index 27403b4c52d6..fbbf1b3f1790 100644
--- a/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
+++ b/Documentation/devicetree/bindings/clock/nxp,imx95-blk-ctl.yaml
@@ -39,6 +39,18 @@ properties:
ID in its "clocks" phandle cell. See
include/dt-bindings/clock/nxp,imx95-clock.h
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 1
+
+patternProperties:
+ '^formatter@[0-9a-f]+$':
+ type: object
+ $ref: /schemas/media/fsl,imx95-csi-formatter.yaml#
+ unevaluatedProperties: false
+
required:
- compatible
- reg
@@ -46,6 +58,23 @@ required:
- power-domains
- clocks
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: nxp,imx95-camera-csr
+ then:
+ required:
+ - '#address-cells'
+ - '#size-cells'
+ else:
+ properties:
+ '#address-cells': false
+ '#size-cells': false
+ patternProperties:
+ '^formatter@[0-9a-f]+$': false
+
additionalProperties: false
examples:
@@ -57,4 +86,46 @@ examples:
clocks = <&scmi_clk 114>;
power-domains = <&scmi_devpd 21>;
};
+
+ - |
+ #include <dt-bindings/clock/nxp,imx95-clock.h>
+
+ syscon@4ac10000 {
+ compatible = "nxp,imx95-camera-csr", "syscon";
+ reg = <0x4ac10000 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ clocks = <&scmi_clk 62>;
+ power-domains = <&scmi_devpd 3>;
+
+ formatter@20 {
+ compatible = "fsl,imx95-csi-formatter";
+ reg = <0x20 0x100>;
+ clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
+ power-domains = <&scmi_devpd 3>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ remote-endpoint = <&mipi_csi_0_out>;
+ };
+
+ };
+
+ port@1 {
+ reg = <1>;
+
+ endpoint {
+ remote-endpoint = <&isi_in_2>;
+ };
+ };
+ };
+ };
+ };
...
--
2.34.1
^ permalink raw reply related
* [PATCH v11 1/3] media: dt-bindings: Add CSI Pixel Formatter DT bindings
From: guoniu.zhou @ 2026-06-23 3:56 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li, Abel Vesa, Peng Fan,
Michael Turquette, Stephen Boyd
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
linux-clk, Guoniu Zhou, Frank Li, Krzysztof Kozlowski
In-Reply-To: <20260623-csi_formatter-v11-0-a792fe9c1502@oss.nxp.com>
From: Guoniu Zhou <guoniu.zhou@nxp.com>
The i.MX95 CSI pixel formatting module uses packet info, pixel and
non-pixel data from the CSI-2 host controller and reformat them to
match Pixel Link(PL) definition.
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
Changes in v11:
- Add Rb tags from Frank Li and Krzysztof Kozlowski
Changes in v10:
- Drop syscon parent node from example
- Drop Reviewed-by tags from Frank and Krzysztof due to binding changes
- Add description for reg property
- Add space after formatter@20 before opening brace in example
- Enhance the port description with more detailed information
- Delete the blank line immediately following the endpoint in example
Changes in v9:
- Use direct node instead of syscon wrapper in example
Changes in v8:
- Use standard port reference instead of video-interfaces.yaml
- Add parent syscon node in example to show device integration
- Add required constraints for port@0 and port@1 in ports node
Changes in v7:
- Change compatible to imx95-csi-formatter as IP is i.MX95 specific per Marco's suggestion
Link: https://lore.kernel.org/linux-media/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com/T/#mcd135b3de179b3cb69daa1fd6e0e8e27c85b3332
---
.../bindings/media/fsl,imx95-csi-formatter.yaml | 88 ++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml b/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
new file mode 100644
index 000000000000..58c4e1cc056b
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/fsl,imx95-csi-formatter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX95 CSI Pixel Formatter
+
+maintainers:
+ - Guoniu Zhou <guoniu.zhou@nxp.com>
+
+description:
+ The CSI pixel formatting module found on i.MX95 uses packet info, pixel
+ and non-pixel data from the CSI-2 host controller and reformat them to
+ match Pixel Link(PL) definition.
+
+properties:
+ compatible:
+ const: fsl,imx95-csi-formatter
+
+ reg:
+ maxItems: 1
+ description: Register offset and size within the parent syscon
+
+ clocks:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Input port, connects to MIPI CSI-2 receiver output (IDI interface)
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description:
+ Output port, connects to ISI input via Pixel Link (PL)
+
+ required:
+ - port@0
+ - port@1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - power-domains
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/nxp,imx95-clock.h>
+
+ formatter@20 {
+ compatible = "fsl,imx95-csi-formatter";
+ reg = <0x20 0x100>;
+ clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
+ power-domains = <&scmi_devpd 3>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ remote-endpoint = <&mipi_csi_0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ endpoint {
+ remote-endpoint = <&isi_in_2>;
+ };
+ };
+ };
+ };
--
2.34.1
^ permalink raw reply related
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