Devicetree
 help / color / mirror / Atom feed
* Re: [PATCH v3 2/2] hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: Guenter Roeck @ 2026-07-24 17:53 UTC (permalink / raw)
  To: Pradhan, Sanman, linux-hwmon@vger.kernel.org
  Cc: robh@kernel.org, krzk+dt@kernel.org, krzk@kernel.org,
	conor+dt@kernel.org, corbet@lwn.net, skhan@linuxfoundation.org,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, Sanman Pradhan, Debjit Ghosh,
	Jawahar Balaji Thirumalaisamy, Santhanakrishnan Balraj, Brian Mak
In-Reply-To: <20260724164919.247162-3-sanman.pradhan@hpe.com>

Hi,

On 7/24/26 09:50, Pradhan, Sanman wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add a PMBus driver for the Analog Devices MAX16545 and MAX16550, and the
> Volterra VT7505 controllers. The driver reports input/output voltage,
> input/output current, input power and temperature over PMBus. All values
> use the direct data format. Peak input voltage, output voltage, output
> current, input power and temperature readings are exposed and can be
> reset.
> 
> The reported current and power depend on the external current-report
> resistor connected to the ILOAD pin, which can be provided through the
> "adi,rload-ohms" device tree property.
> 
> On the MAX16550 and VT7505, the severe-OCP deglitch time can optionally
> be configured with the "adi,ocp-severe-filter-us" device tree property.
> When omitted, the existing hardware setting is left unchanged.
> 
> Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
> Co-developed-by: Dhruva Devineni <ddevineni@juniper.net>
> Signed-off-by: Dhruva Devineni <ddevineni@juniper.net>
> Co-developed-by: Debjit Ghosh <dghosh@juniper.net>
> Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
> Co-developed-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
> Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
> Co-developed-by: Avadhut Naik <avadhutn@juniper.net>
> Signed-off-by: Avadhut Naik <avadhutn@juniper.net>
> Co-developed-by: Santhanakrishnan Balraj <sbalraj@juniper.net>
> Signed-off-by: Santhanakrishnan Balraj <sbalraj@juniper.net>
> Co-developed-by: Brian Mak <makb@juniper.net>
> Signed-off-by: Brian Mak <makb@juniper.net>
> Signed-off-by: Sanman Pradhan <psanman@juniper.net>
> ---

I get delivery errors for the following addresses.
     ddevineni@juniper.net
     gvlaev@juniper.net
     avadhutn@juniper.net

meaning they are quite obviously _not_ involved in the patch approval path.
Please drop those addresses. Also, per Documentation/process/submitting-patches.rst:

  Any further SoBs (Signed-off-by:'s) following the author's SoB are from
  people handling and transporting the patch, but were not involved in its
  development. SoB chains should reflect the **real** route a patch took
  as it was propagated to the maintainers and ultimately to Linus, with
  the first SoB entry signalling primary authorship of a single author.

Does the above SoB sequence really reflect the approval patch for this
patch ?

Thanks,
Guenter


^ permalink raw reply

* Re: [PATCH v18 2/2] platform: Add initial synology microp driver
From: Markus Probst @ 2026-07-24 17:35 UTC (permalink / raw)
  To: sashiko-reviews; +Cc: conor+dt, devicetree, robh, ojeda, linux-leds, lee
In-Reply-To: <20260724172159.C43981F000E9@smtp.kernel.org>

[-- Attachment #1: Type: text/plain, Size: 11414 bytes --]

On Fri, 2026-07-24 at 17:21 +0000, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
> - [High] The dynamically formatted `name` CString for the alert LED is dropped immediately after initialization, leaving a dangling pointer in the LED subsystem.
> - [High] The serdev device is never opened, causing subsequent LED operations to hang the kernel worker thread indefinitely.
> - [High] The `blink_set` callback sleeps by acquiring a Mutex and waiting for synchronous serial I/O, but it is called from an RCU read-side critical section.
> - [High] Incorrect struct field declaration order causes `power_name` to be freed before the `power` LED device is unregistered.
> - [Medium] Hardware blinking is not disabled when setting a solid brightness level, preventing the LED from turning on solidly.
> - [Medium] The driver lacks a device-level lock to serialize commands sent to the microcontroller over the shared serdev bus, allowing concurrent LED updates to interleave.
> --
> 
> --- Patch [2]: [PATCH v18 2/2] platform: Add initial synology microp driver ---
> commit 7eb4c67aa911615ee8b6562c3f14a129d9b90280
> Author: Markus Probst <markus.probst@posteo.de>
> 
> platform: Add initial synology microp driver
>     
> Add a initial synology microp driver, written in Rust.
> The driver targets a microcontroller found in Synology NAS devices. It
> currently only supports controlling of the power led, status led, alert
> led and usb led. Other components such as fan control or handling
> on-device buttons will be added once the required rust abstractions are
> there.
> 
> > diff --git a/drivers/platform/synology_microp/command.rs b/drivers/platform/synology_microp/command.rs
> > new file mode 100644
> > index 0000000000000..490719490391c
> > --- /dev/null
> > +++ b/drivers/platform/synology_microp/command.rs
> > @@ -0,0 +1,54 @@
> [ ... ]
> > +impl Command {
> > +    pub(crate) fn write(self, dev: &serdev::Device<Bound>) -> Result {
> > +        dev.write_all(
> 
> [Severity: Medium]
> Since multiple LEDs can be updated concurrently, does this write_all() call
> need a device-level lock to prevent interleaving commands on the shared serdev
> bus?
> 
> > +            match self {
> [ ... ]
> > +            },
> > +            0,
> > +        )?;
> > +        dev.wait_until_sent(0);
> 
> [Severity: High]
> Could this code cause a BUG by sleeping in an atomic context?
> 
> When the LED core invokes blink_set() (for instance, via a timer trigger),
> it holds an rwlock and executes in an RCU read-side critical section. The
> wait_until_sent() call performs a sleeping wait, which could cause a panic
> or instability when called from that atomic context.
BLOCKING = true is set in every LedOps implementation. Therefore
sleeping is allowed.
> 
> Additionally, could this block indefinitely if dev.open() hasn't been called?
This function does not exist. The serdev rust abstraction opens it
automatically before probe.

Also if it isn't open, it would cause a null pointer dereference
instead of blocking indefinitely.
> 
> > +        Ok(())
> > +    }
> > +}
> > diff --git a/drivers/platform/synology_microp/led.rs b/drivers/platform/synology_microp/led.rs
> > new file mode 100644
> > index 0000000000000..01cad98616fdf
> > --- /dev/null
> > +++ b/drivers/platform/synology_microp/led.rs
> > @@ -0,0 +1,304 @@
> [ ... ]
> > +#[pin_data]
> > +pub(crate) struct Data<'bound> {
> > +    #[pin]
> > +    status: led::MultiColorDevice<'bound, StatusLedHandler>,
> > +    power_name: CString,
> > +    #[pin]
> > +    power: led::Device<'bound, LedHandler>,
> 
> [Severity: High]
> Does this struct field declaration order cause a use-after-free during
> device unbinding?
> 
> In Rust, struct fields are dropped in the order they are declared. Because
> power_name is declared before power, the CString buffer for the name is freed
> first. The kernel would be left with a dangling pointer in led_cdev->name while
> the power LED device is still registered and active, which could lead to memory
> corruption if read concurrently before unregistration completes.
`power_name` only needs to outlive the initialization. It is copied by
the led subsystem on register.
> 
> > +    alert: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
> > +    usb_copy: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
> > +    esata: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
> > +}
> > +
> > +impl<'bound> Data<'bound> {
> > +    pub(super) fn register<'a>(
> > +        dev: &'bound serdev::Device<Bound>,
> > +        model: &'a Model,
> > +    ) -> impl PinInit<Self, Error> + 'a
> > +    where
> > +        'bound: 'a,
> > +    {
> > +        pin_init_scope(move || {
> > +            Ok(try_pin_init!(Self {
> [ ... ]
> > +                alert: {
> > +                    if let Some(color) = model.led_alert {
> > +                        let name = CString::try_from_fmt(fmt!(
> > +                            "synology:{}:alarm",
> > +                            color.as_c_str().to_str()?
> > +                        ))?;
> > +                        Some(KBox::pin_init(
> > +                            led::DeviceBuilder::new().color(color).name(&name).build(
> 
> [Severity: High]
> Is the dynamically formatted name CString dropped immediately after this
> initialization block?
Yes.
> 
> The local CString variable is passed as a reference to the builder but is
> dropped at the end of the `if let` block. The LED classdev will retain a
> dangling pointer to its freed buffer, leading to a use-after-free when the LED
> subsystem accesses the name.
No, it will not retain a pointer. It copies the string in the
initialization.

> 
> > +                                dev,
> > +                                try_pin_init!(LedHandler {
> > +                                    blink <- new_mutex!(false),
> > +                                    command: Command::AlertLed,
> > +                                }),
> > +                            ),
> > +                            GFP_KERNEL,
> > +                        )?)
> > +                    } else {
> > +                        None
> > +                    }
> > +                },
> [ ... ]
> > +    fn brightness_set<'bound>(
> > +        &self,
> > +        dev: &'bound Self::Bus,
> > +        _classdev: &led::Device<'bound, Self>,
> > +        brightness: u32,
> > +    ) -> Result<()> {
> > +        let mut blink = self.blink.lock();
> > +        (self.command)(if brightness == 0 {
> > +            *blink = false;
> > +            State::Off
> > +        } else if *blink {
> > +            State::Blink
> > +        } else {
> > +            State::On
> > +        })
> 
> [Severity: Medium]
> If the LED is currently blinking, does this logic prevent it from turning on
> solidly?
> 
> When a solid brightness is requested and the blink state is true, the state
> remains State::Blink. The blink state needs to be reset so the hardware can
> stop blinking and remain solidly on.
Led Subsystem documentation explicitly says
- "passing LED_OFF stops blinking"
- "passing LED_OFF stops hardware blinking"
- "To turn off blinking, use the API function led_brightness_set() with
brightness value LED_OFF, which should stop any software timers that
may have been required for blinking."

It is intended to continue blinking if a non-0 brightness is set.

See https://docs.kernel.org/leds/leds-class.html

> 
> > +        .write(dev)?;
> > +
> > +        Ok(())
> > +    }
> > +
> > +    fn blink_set<'bound>(
> > +        &self,
> > +        dev: &'bound Self::Bus,
> > +        _classdev: &led::Device<'bound, Self>,
> > +        delay_on: &mut usize,
> > +        delay_off: &mut usize,
> > +    ) -> Result<()> {
> > +        let mut blink = self.blink.lock();
> 
> [Severity: High]
> Is it safe to acquire this sleeping Mutex here?
> 
> Since the blink_set() callback can be called from an RCU read-side critical
> section by the LED core, acquiring a Mutex here could lead to a kernel panic.
BLOCKING = true is set in every LedOps implementation. Therefore
sleeping is allowed.

> 
> > +
> > +        (self.command)(if *delay_on == 0 && *delay_off != 0 {
> [ ... ]
> > +    fn brightness_set<'bound>(
> > +        &self,
> > +        dev: &'bound Self::Bus,
> > +        classdev: &led::MultiColorDevice<'bound, Self>,
> > +        brightness: u32,
> > +    ) -> Result<()> {
> > +        let mut blink = self.blink.lock();
> > +        if brightness == 0 {
> > +            *blink = false;
> > +        }
> > +
> > +        let amber_brightness = classdev.subleds()[1].brightness();
> > +
> > +        let (color, subled_brightness) = if amber_brightness == 0 {
> > +            (StatusLedColor::Green, classdev.subleds()[0].brightness())
> > +        } else {
> > +            (StatusLedColor::Amber, amber_brightness)
> > +        };
> > +
> > +        Command::StatusLed(
> > +            color,
> > +            if subled_brightness == 0 {
> > +                State::Off
> > +            } else if *blink {
> > +                State::Blink
> > +            } else {
> > +                State::On
> > +            },
> 
> [Severity: Medium]
> Does the multi-color status LED suffer from the same logic flaw as
> LedHandler::brightness_set(), where the LED stays blinking instead of turning
> solid when a solid brightness level is requested?
As explained above, it is not a flaw.
> 
> > +        )
> > +        .write(dev)
> > +    }
> > +
> > +    fn blink_set<'bound>(
> > +        &self,
> [ ... ]
> > diff --git a/drivers/platform/synology_microp/synology_microp.rs b/drivers/platform/synology_microp/synology_microp.rs
> > new file mode 100644
> > index 0000000000000..f7168309e6116
> > --- /dev/null
> > +++ b/drivers/platform/synology_microp/synology_microp.rs
> > @@ -0,0 +1,91 @@
> [ ... ]
> > +    fn probe<'bound>(
> > +        dev: &'bound serdev::Device<device::Core<'_>>,
> > +        model: Option<&'bound Model>,
> > +    ) -> impl PinInit<Self::Data<'bound>, kernel::error::Error> + 'bound {
> > +        pin_init_scope(move || {
> > +            let model = model.ok_or(EINVAL)?;
> > +
> > +            dev.set_baudrate(9600).map_err(|_| EINVAL)?;
> > +            dev.set_flow_control(false);
> > +            dev.set_parity(serdev::Parity::None)?;
> > +
> > +            Ok(try_pin_init!(SynologyMicropDriver {
> 
> [Severity: High]
> Is a call to dev.open() missing during this setup?
This function does not exist. The serdev rust abstraction automatically
opens the device before probe.
> 
> The probe function configures the serdev device but doesn't seem to open it.
> When subsequent operations try to write to the bus, the closed tty port will
> accept 0 bytes and cause the driver's write logic to hang forever.
Writing to a closed serdev device would case a null pointer
dereference, which does not happen in testing.
> 
> > +                led <- led::Data::register(dev, model),
> > +            }))
> > +        })
> > +    }
> > +}

This review does not contain a single issue. All false positives.


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 870 bytes --]

^ permalink raw reply

* Re: [PATCH v3 2/2] hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: Guenter Roeck @ 2026-07-24 17:27 UTC (permalink / raw)
  To: Pradhan, Sanman
  Cc: linux-hwmon@vger.kernel.org, robh@kernel.org, krzk+dt@kernel.org,
	krzk@kernel.org, conor+dt@kernel.org, corbet@lwn.net,
	skhan@linuxfoundation.org, devicetree@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Sanman Pradhan, Georgi Vlaev, Dhruva Devineni, Debjit Ghosh,
	Jawahar Balaji Thirumalaisamy, Avadhut Naik,
	Santhanakrishnan Balraj, Brian Mak
In-Reply-To: <20260724164919.247162-3-sanman.pradhan@hpe.com>

On Fri, Jul 24, 2026 at 04:50:00PM +0000, Pradhan, Sanman wrote:
> From: Georgi Vlaev <gvlaev@juniper.net>
> 
> Add a PMBus driver for the Analog Devices MAX16545 and MAX16550, and the
> Volterra VT7505 controllers. The driver reports input/output voltage,
> input/output current, input power and temperature over PMBus. All values
> use the direct data format. Peak input voltage, output voltage, output
> current, input power and temperature readings are exposed and can be
> reset.
> 
> The reported current and power depend on the external current-report
> resistor connected to the ILOAD pin, which can be provided through the
> "adi,rload-ohms" device tree property.
> 
> On the MAX16550 and VT7505, the severe-OCP deglitch time can optionally
> be configured with the "adi,ocp-severe-filter-us" device tree property.
> When omitted, the existing hardware setting is left unchanged.
> 
...
> +static void vt7505_set_m(int *m, u32 rload)
> +{
> +	u64 val = (u64)*m * rload;
> +
> +	/* Make sure m fits the s32 type */
> +	*m = DIV_ROUND_CLOSEST_ULL(val, 1000);

The largest possible value of m is 7578. That means that this _will_
overflow if rload >= 283383960 because 283383960 * 7578 / 1000 =
2147483648.88, rounded up to to 2147483649 == 0x80000001.

Please add a range check in the probe function.

Thanks,
Guenter

^ permalink raw reply

* Re: [PATCH v4 3/3] arm64: dts: qcom: shikra: Add support for AudioCoreCC and AudioCoreCSR nodes
From: sashiko-bot @ 2026-07-24 17:24 UTC (permalink / raw)
  To: Imran Shaik; +Cc: robh, conor+dt, devicetree
In-Reply-To: <20260724-shikra-audiocorecc-v4-3-0a89bb13d817@oss.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Unclocked MMIO regmap exposure on IQS variant leads to synchronous external abort.
--

--- Patch [3]: [PATCH v4 3/3] arm64: dts: qcom: shikra: Add support for AudioCoreCC and AudioCoreCSR nodes ---
commit a056f645f45682f1008b321f5e639505f22bb979
Author: Imran Shaik <imran.shaik@oss.qualcomm.com>

arm64: dts: qcom: shikra: Add support for AudioCoreCC and AudioCoreCSR nodes

This commit adds support for the Audio Core Clock Controller and Audio Core
CSR nodes for the Qualcomm Shikra SoC. It describes different enablement
requirements based on the SoC variant (CQM, CQS, IQS).

> diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
> index 4e5bc9e17c8ed..b744534572d63 100644
> --- a/arch/arm64/boot/dts/qcom/shikra.dtsi
> +++ b/arch/arm64/boot/dts/qcom/shikra.dtsi

[ ... ]

> @@ -640,6 +641,22 @@ &clk_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
>  			};
>  		};
>  
> +		audiocorecc: clock-controller@a0a0000 {
> +			compatible = "qcom,shikra-audiocorecc";
> +			reg = <0x0 0x0a0a0000 0x0 0x10000>;
> +			clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
> +				 <&sleep_clk>,
> +				 <0>;
> +			#clock-cells = <1>;
> +			status = "reserved"; /* Owned by Modem firmware */
> +		};
> +
> +		audiocore_csr: reset-controller@a0b4000 {
> +			compatible = "qcom,shikra-audiocore-csr";
> +			reg = <0x0 0x0a0b4000 0x0 0x1000>;
> +			#reset-cells = <1>;
> +		};

[Severity: High]
Will this node probe by default on the IQS variant?

The commit message mentions that on the IQS variant, no clocks or resets are
needed. Since this node lacks a status = "disabled" property, it appears it
will be left enabled and probed on all variants, including IQS. 

If the audiocore-csr driver registers an MMIO regmap without clock management,
could reading from the regmap debugfs file on an IQS device attempt an 
unclocked register access and trigger a synchronous external abort?

>  		sram@c11e000 {
>  			compatible = "qcom,shikra-imem", "mmio-sram";
>  			reg = <0x0 0x0c11e000 0x0 0x1000>;

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724-shikra-audiocorecc-v4-0-0a89bb13d817@oss.qualcomm.com?part=3

^ permalink raw reply

* Re: [PATCH v18 2/2] platform: Add initial synology microp driver
From: sashiko-bot @ 2026-07-24 17:21 UTC (permalink / raw)
  To: Markus Probst; +Cc: conor+dt, devicetree, robh, ojeda, linux-leds, lee
In-Reply-To: <20260724-synology_microp_initial-v18-2-fb2f49f10e77@posteo.de>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [High] The dynamically formatted `name` CString for the alert LED is dropped immediately after initialization, leaving a dangling pointer in the LED subsystem.
- [High] The serdev device is never opened, causing subsequent LED operations to hang the kernel worker thread indefinitely.
- [High] The `blink_set` callback sleeps by acquiring a Mutex and waiting for synchronous serial I/O, but it is called from an RCU read-side critical section.
- [High] Incorrect struct field declaration order causes `power_name` to be freed before the `power` LED device is unregistered.
- [Medium] Hardware blinking is not disabled when setting a solid brightness level, preventing the LED from turning on solidly.
- [Medium] The driver lacks a device-level lock to serialize commands sent to the microcontroller over the shared serdev bus, allowing concurrent LED updates to interleave.
--

--- Patch [2]: [PATCH v18 2/2] platform: Add initial synology microp driver ---
commit 7eb4c67aa911615ee8b6562c3f14a129d9b90280
Author: Markus Probst <markus.probst@posteo.de>

platform: Add initial synology microp driver
    
Add a initial synology microp driver, written in Rust.
The driver targets a microcontroller found in Synology NAS devices. It
currently only supports controlling of the power led, status led, alert
led and usb led. Other components such as fan control or handling
on-device buttons will be added once the required rust abstractions are
there.

> diff --git a/drivers/platform/synology_microp/command.rs b/drivers/platform/synology_microp/command.rs
> new file mode 100644
> index 0000000000000..490719490391c
> --- /dev/null
> +++ b/drivers/platform/synology_microp/command.rs
> @@ -0,0 +1,54 @@
[ ... ]
> +impl Command {
> +    pub(crate) fn write(self, dev: &serdev::Device<Bound>) -> Result {
> +        dev.write_all(

[Severity: Medium]
Since multiple LEDs can be updated concurrently, does this write_all() call
need a device-level lock to prevent interleaving commands on the shared serdev
bus?

> +            match self {
[ ... ]
> +            },
> +            0,
> +        )?;
> +        dev.wait_until_sent(0);

[Severity: High]
Could this code cause a BUG by sleeping in an atomic context?

When the LED core invokes blink_set() (for instance, via a timer trigger),
it holds an rwlock and executes in an RCU read-side critical section. The
wait_until_sent() call performs a sleeping wait, which could cause a panic
or instability when called from that atomic context.

Additionally, could this block indefinitely if dev.open() hasn't been called?

> +        Ok(())
> +    }
> +}
> diff --git a/drivers/platform/synology_microp/led.rs b/drivers/platform/synology_microp/led.rs
> new file mode 100644
> index 0000000000000..01cad98616fdf
> --- /dev/null
> +++ b/drivers/platform/synology_microp/led.rs
> @@ -0,0 +1,304 @@
[ ... ]
> +#[pin_data]
> +pub(crate) struct Data<'bound> {
> +    #[pin]
> +    status: led::MultiColorDevice<'bound, StatusLedHandler>,
> +    power_name: CString,
> +    #[pin]
> +    power: led::Device<'bound, LedHandler>,

[Severity: High]
Does this struct field declaration order cause a use-after-free during
device unbinding?

In Rust, struct fields are dropped in the order they are declared. Because
power_name is declared before power, the CString buffer for the name is freed
first. The kernel would be left with a dangling pointer in led_cdev->name while
the power LED device is still registered and active, which could lead to memory
corruption if read concurrently before unregistration completes.

> +    alert: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
> +    usb_copy: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
> +    esata: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
> +}
> +
> +impl<'bound> Data<'bound> {
> +    pub(super) fn register<'a>(
> +        dev: &'bound serdev::Device<Bound>,
> +        model: &'a Model,
> +    ) -> impl PinInit<Self, Error> + 'a
> +    where
> +        'bound: 'a,
> +    {
> +        pin_init_scope(move || {
> +            Ok(try_pin_init!(Self {
[ ... ]
> +                alert: {
> +                    if let Some(color) = model.led_alert {
> +                        let name = CString::try_from_fmt(fmt!(
> +                            "synology:{}:alarm",
> +                            color.as_c_str().to_str()?
> +                        ))?;
> +                        Some(KBox::pin_init(
> +                            led::DeviceBuilder::new().color(color).name(&name).build(

[Severity: High]
Is the dynamically formatted name CString dropped immediately after this
initialization block?

The local CString variable is passed as a reference to the builder but is
dropped at the end of the `if let` block. The LED classdev will retain a
dangling pointer to its freed buffer, leading to a use-after-free when the LED
subsystem accesses the name.

> +                                dev,
> +                                try_pin_init!(LedHandler {
> +                                    blink <- new_mutex!(false),
> +                                    command: Command::AlertLed,
> +                                }),
> +                            ),
> +                            GFP_KERNEL,
> +                        )?)
> +                    } else {
> +                        None
> +                    }
> +                },
[ ... ]
> +    fn brightness_set<'bound>(
> +        &self,
> +        dev: &'bound Self::Bus,
> +        _classdev: &led::Device<'bound, Self>,
> +        brightness: u32,
> +    ) -> Result<()> {
> +        let mut blink = self.blink.lock();
> +        (self.command)(if brightness == 0 {
> +            *blink = false;
> +            State::Off
> +        } else if *blink {
> +            State::Blink
> +        } else {
> +            State::On
> +        })

[Severity: Medium]
If the LED is currently blinking, does this logic prevent it from turning on
solidly?

When a solid brightness is requested and the blink state is true, the state
remains State::Blink. The blink state needs to be reset so the hardware can
stop blinking and remain solidly on.

> +        .write(dev)?;
> +
> +        Ok(())
> +    }
> +
> +    fn blink_set<'bound>(
> +        &self,
> +        dev: &'bound Self::Bus,
> +        _classdev: &led::Device<'bound, Self>,
> +        delay_on: &mut usize,
> +        delay_off: &mut usize,
> +    ) -> Result<()> {
> +        let mut blink = self.blink.lock();

[Severity: High]
Is it safe to acquire this sleeping Mutex here?

Since the blink_set() callback can be called from an RCU read-side critical
section by the LED core, acquiring a Mutex here could lead to a kernel panic.

> +
> +        (self.command)(if *delay_on == 0 && *delay_off != 0 {
[ ... ]
> +    fn brightness_set<'bound>(
> +        &self,
> +        dev: &'bound Self::Bus,
> +        classdev: &led::MultiColorDevice<'bound, Self>,
> +        brightness: u32,
> +    ) -> Result<()> {
> +        let mut blink = self.blink.lock();
> +        if brightness == 0 {
> +            *blink = false;
> +        }
> +
> +        let amber_brightness = classdev.subleds()[1].brightness();
> +
> +        let (color, subled_brightness) = if amber_brightness == 0 {
> +            (StatusLedColor::Green, classdev.subleds()[0].brightness())
> +        } else {
> +            (StatusLedColor::Amber, amber_brightness)
> +        };
> +
> +        Command::StatusLed(
> +            color,
> +            if subled_brightness == 0 {
> +                State::Off
> +            } else if *blink {
> +                State::Blink
> +            } else {
> +                State::On
> +            },

[Severity: Medium]
Does the multi-color status LED suffer from the same logic flaw as
LedHandler::brightness_set(), where the LED stays blinking instead of turning
solid when a solid brightness level is requested?

> +        )
> +        .write(dev)
> +    }
> +
> +    fn blink_set<'bound>(
> +        &self,
[ ... ]
> diff --git a/drivers/platform/synology_microp/synology_microp.rs b/drivers/platform/synology_microp/synology_microp.rs
> new file mode 100644
> index 0000000000000..f7168309e6116
> --- /dev/null
> +++ b/drivers/platform/synology_microp/synology_microp.rs
> @@ -0,0 +1,91 @@
[ ... ]
> +    fn probe<'bound>(
> +        dev: &'bound serdev::Device<device::Core<'_>>,
> +        model: Option<&'bound Model>,
> +    ) -> impl PinInit<Self::Data<'bound>, kernel::error::Error> + 'bound {
> +        pin_init_scope(move || {
> +            let model = model.ok_or(EINVAL)?;
> +
> +            dev.set_baudrate(9600).map_err(|_| EINVAL)?;
> +            dev.set_flow_control(false);
> +            dev.set_parity(serdev::Parity::None)?;
> +
> +            Ok(try_pin_init!(SynologyMicropDriver {

[Severity: High]
Is a call to dev.open() missing during this setup?

The probe function configures the serdev device but doesn't seem to open it.
When subsequent operations try to write to the bus, the closed tty port will
accept 0 bytes and cause the driver's write logic to hang forever.

> +                led <- led::Data::register(dev, model),
> +            }))
> +        })
> +    }
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724-synology_microp_initial-v18-0-fb2f49f10e77@posteo.de?part=2

^ permalink raw reply

* [PATCH v4 3/3] arm64: dts: qcom: shikra: Add support for AudioCoreCC and AudioCoreCSR nodes
From: Imran Shaik @ 2026-07-24 17:15 UTC (permalink / raw)
  To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
	Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Konrad Dybcio
  Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
	linux-kernel, devicetree, Imran Shaik, Konrad Dybcio
In-Reply-To: <20260724-shikra-audiocorecc-v4-0-0a89bb13d817@oss.qualcomm.com>

Add support for Audio Core Clock Controller (AudioCoreCC) and Audio Core
CSR nodes on Qualcomm Shikra SoC. The Audio Core Clocks and Resets support
differs across Shikra variants based on Audio subsystem enablement as
follows:
- CQM variant: The QAIF driver runs on HLOS, hence both clocks and resets
are required to be supported on HLOS.
- CQS variant: The QAIF driver runs on the Modem, and required clocks are
handled on Modem, so from HLOS only resets are needed.
- IQS variant: no soundwire codes, hence no clocks/resets are needed.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts |  4 ++++
 arch/arm64/boot/dts/qcom/shikra.dtsi        | 17 +++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
index 0a52ab9b7a4c34d371f5ac23efe59d1c9d2723f4..0883c480bfbc80d7bead966b9ba932dee8a77bbf 100644
--- a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
+++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
@@ -23,6 +23,10 @@ chosen {
 	};
 };
 
+&audiocorecc {
+	status = "okay";
+};
+
 &sdhc_1 {
 	vmmc-supply = <&pm4125_l20>;
 	vqmmc-supply = <&pm4125_l14>;
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi
index 4e5bc9e17c8ed8914733ac9fdc9b69128b40216e..b744534572d63349c4274ffbe5cacbb8fdb4197d 100644
--- a/arch/arm64/boot/dts/qcom/shikra.dtsi
+++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/qcom,rpmcc.h>
+#include <dt-bindings/clock/qcom,shikra-audiocorecc.h>
 #include <dt-bindings/clock/qcom,shikra-gcc.h>
 #include <dt-bindings/interconnect/qcom,icc.h>
 #include <dt-bindings/interconnect/qcom,rpm-icc.h>
@@ -640,6 +641,22 @@ &clk_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>,
 			};
 		};
 
+		audiocorecc: clock-controller@a0a0000 {
+			compatible = "qcom,shikra-audiocorecc";
+			reg = <0x0 0x0a0a0000 0x0 0x10000>;
+			clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+				 <&sleep_clk>,
+				 <0>;
+			#clock-cells = <1>;
+			status = "reserved"; /* Owned by Modem firmware */
+		};
+
+		audiocore_csr: reset-controller@a0b4000 {
+			compatible = "qcom,shikra-audiocore-csr";
+			reg = <0x0 0x0a0b4000 0x0 0x1000>;
+			#reset-cells = <1>;
+		};
+
 		sram@c11e000 {
 			compatible = "qcom,shikra-imem", "mmio-sram";
 			reg = <0x0 0x0c11e000 0x0 0x1000>;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 2/3] clk: qcom: Add Audio Core clock controller support on Qualcomm Shikra SoC
From: Imran Shaik @ 2026-07-24 17:15 UTC (permalink / raw)
  To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
	Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Konrad Dybcio
  Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
	linux-kernel, devicetree, Imran Shaik, Konrad Dybcio,
	Dmitry Baryshkov
In-Reply-To: <20260724-shikra-audiocorecc-v4-0-0a89bb13d817@oss.qualcomm.com>

Add support for Audio Core Clock Controller (AUDIOCORECC) and Audio Core
CSR resets on Qualcomm Shikra SoC.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
 drivers/clk/qcom/Kconfig              |  10 +
 drivers/clk/qcom/Makefile             |   1 +
 drivers/clk/qcom/audiocorecc-shikra.c | 810 ++++++++++++++++++++++++++++++++++
 3 files changed, 821 insertions(+)

diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index 63f271aff1771bea0885fb753dd28d02fd7d4ab6..29ae37ece3141438d6fb8162cc7ad3a361c5323c 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -192,6 +192,16 @@ config CLK_NORD_GCC
 	  SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination
 	  of GCC, SE_GCC, NE_GCC and NW_GCC.
 
+config CLK_SHIKRA_AUDIOCORECC
+	tristate "Shikra Audio Core Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_SHIKRA_GCC
+	default m if ARCH_QCOM
+	help
+	  Support for the Audio Core clock controller on Qualcomm Shikra devices.
+	  Say Y if you want to use AudioCoreCC clocks required to support audio
+	  devices and it's functionality.
+
 config CLK_SHIKRA_GCC
 	tristate "Shikra Global Clock Controller"
 	depends on ARM64 || COMPILE_TEST
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index db7689ee5dc63bc8b7d12b8222188bc1e1ff78ba..f26a79658bb88c957f990d76d295a5a9a09bb7ee 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o
 obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o
 obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o
 obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.o
+obj-$(CONFIG_CLK_SHIKRA_AUDIOCORECC) += audiocorecc-shikra.o
 obj-$(CONFIG_CLK_SHIKRA_GCC) += gcc-shikra.o
 obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o
 obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o
diff --git a/drivers/clk/qcom/audiocorecc-shikra.c b/drivers/clk/qcom/audiocorecc-shikra.c
new file mode 100644
index 0000000000000000000000000000000000000000..19f67b50d6234655ebb8cbc242a8d7efbb0a6039
--- /dev/null
+++ b/drivers/clk/qcom/audiocorecc-shikra.c
@@ -0,0 +1,810 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,shikra-audiocorecc.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "common.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_SLEEP_CLK,
+	DT_AUD_REF_CLK_SRC,
+};
+
+enum {
+	P_AUD_REF_CLK_SRC,
+	P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX,
+	P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2,
+	P_BI_TCXO,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco spark_vco[] = {
+	{ 500000000, 1000000000, 2 },
+};
+
+/* 614.4 MHz Configuration */
+static const struct alpha_pll_config audio_core_cc_dig_pll_config = {
+	.l = 0x20,
+	.alpha = 0x0,
+	.vco_val = BIT(21),
+	.post_div_val = 0x28100,
+	.post_div_mask = GENMASK(17, 8),
+	.vco_mask = GENMASK(21, 20),
+	.main_output_mask = BIT(0),
+	.aux_output_mask = BIT(1),
+	.aux2_output_mask = BIT(2),
+	.config_ctl_val = 0x4001055b,
+	.test_ctl_hi_val = 0x1,
+	.test_ctl_hi_mask = 0x1,
+};
+
+static struct clk_alpha_pll audio_core_cc_dig_pll = {
+	.offset = 0x0,
+	.config = &audio_core_cc_dig_pll_config,
+	.vco_table = spark_vco,
+	.num_vco = ARRAY_SIZE(spark_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_dig_pll",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux = {
+	.mult = 1,
+	.div = 5,
+	.hw.init = &(struct clk_init_data) {
+		.name = "audio_core_cc_dig_pll_out_aux",
+		.parent_data = &(const struct clk_parent_data) {
+			.hw = &audio_core_cc_dig_pll.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_fixed_factor audio_core_cc_dig_pll_out_aux2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(struct clk_init_data) {
+		.name = "audio_core_cc_dig_pll_out_aux2",
+		.parent_data = &(const struct clk_parent_data) {
+			.hw = &audio_core_cc_dig_pll.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static const struct parent_map audio_core_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_AUD_REF_CLK_SRC, 1 },
+	{ P_SLEEP_CLK, 2 },
+	{ P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4 },
+	{ P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 6 },
+};
+
+static const struct clk_parent_data audio_core_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_AUD_REF_CLK_SRC },
+	{ .index = DT_SLEEP_CLK },
+	{ .hw = &audio_core_cc_dig_pll_out_aux.hw },
+	{ .hw = &audio_core_cc_dig_pll_out_aux2.hw },
+};
+
+static const struct freq_tbl ftbl_audio_core_cc_aif_if0_clk_src[] = {
+	F(240000, P_BI_TCXO, 10, 1, 8),
+	F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32),
+	F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16),
+	F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16),
+	F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8),
+	F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8),
+	F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4),
+	F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4),
+	F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2),
+	F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2),
+	F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0),
+	F(9600000, P_BI_TCXO, 2, 0, 0),
+	F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 audio_core_cc_aif_if0_clk_src = {
+	.cmd_rcgr = 0x104c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_aif_if0_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 audio_core_cc_aif_if1_clk_src = {
+	.cmd_rcgr = 0x10b0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_aif_if1_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 audio_core_cc_aif_if2_clk_src = {
+	.cmd_rcgr = 0x1114,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_aif_if2_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_audio_core_cc_aif_if3_clk_src[] = {
+	F(240000, P_BI_TCXO, 10, 1, 8),
+	F(256000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 32),
+	F(512000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 16),
+	F(768000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 16),
+	F(1024000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 8),
+	F(1536000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 8),
+	F(2048000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 4),
+	F(3072000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 4),
+	F(4096000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 1, 2),
+	F(6144000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 1, 2),
+	F(8192000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 15, 0, 0),
+	F(9600000, P_BI_TCXO, 2, 0, 0),
+	F(12288000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 10, 0, 0),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0),
+	F(49152000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 audio_core_cc_aif_if3_clk_src = {
+	.cmd_rcgr = 0x1178,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aif_if3_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_aif_if3_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_audio_core_cc_aud_dma_clk_src[] = {
+	F(38400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 8, 0, 0),
+	F(102400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 3, 0, 0),
+	F(153600000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 2, 0, 0),
+	F(307200000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 audio_core_cc_aud_dma_clk_src = {
+	.cmd_rcgr = 0x1028,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aud_dma_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_aud_dma_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_audio_core_cc_bus_clk_src[] = {
+	F(38400000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 8, 0, 0),
+	F(76800000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX2, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 audio_core_cc_bus_clk_src = {
+	.cmd_rcgr = 0x1008,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_bus_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_bus_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 audio_core_cc_ext_mclka_clk_src = {
+	.cmd_rcgr = 0x123c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_ext_mclka_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 audio_core_cc_ext_mclkb_clk_src = {
+	.cmd_rcgr = 0x125c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_aif_if0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_ext_mclkb_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_audio_core_cc_lpaif_pcmoe_clk_src[] = {
+	F(9600000, P_BI_TCXO, 2, 0, 0),
+	F(15360000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 8, 0, 0),
+	F(30720000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 4, 0, 0),
+	F(61440000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 audio_core_cc_lpaif_pcmoe_clk_src = {
+	.cmd_rcgr = 0x12ac,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_lpaif_pcmoe_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_lpaif_pcmoe_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_audio_core_cc_tx_mclk_rcg_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(24576000, P_AUDIO_CORE_CC_DIG_PLL_OUT_AUX, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 audio_core_cc_tx_mclk_rcg_clk_src = {
+	.cmd_rcgr = 0x127c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = audio_core_cc_parent_map_0,
+	.freq_tbl = ftbl_audio_core_cc_tx_mclk_rcg_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_tx_mclk_rcg_clk_src",
+		.parent_data = audio_core_cc_parent_data_0,
+		.num_parents = ARRAY_SIZE(audio_core_cc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div audio_core_cc_cdiv_tx_mclk_div_clk_src = {
+	.reg = 0x129c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "audio_core_cc_cdiv_tx_mclk_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if0_ebit_clk = {
+	.halt_reg = 0x1068,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if0_ebit_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if0_ibit_clk = {
+	.halt_reg = 0x1064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if0_ibit_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_aif_if0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if1_ebit_clk = {
+	.halt_reg = 0x10cc,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x10cc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if1_ebit_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if1_ibit_clk = {
+	.halt_reg = 0x10c8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x10c8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if1_ibit_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_aif_if1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if2_ebit_clk = {
+	.halt_reg = 0x1130,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1130,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if2_ebit_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if2_ibit_clk = {
+	.halt_reg = 0x112c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x112c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if2_ibit_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_aif_if2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if3_ebit_clk = {
+	.halt_reg = 0x1194,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x1194,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if3_ebit_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aif_if3_ibit_clk = {
+	.halt_reg = 0x1190,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1190,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aif_if3_ibit_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_aif_if3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aud_dma_clk = {
+	.halt_reg = 0x1040,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x1040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aud_dma_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_aud_dma_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_aud_dma_mem_clk = {
+	.halt_reg = 0x1044,
+	.halt_check = BRANCH_HALT,
+	.hwcg_reg = 0x1044,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_aud_dma_mem_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_aud_dma_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_bus_clk = {
+	.halt_reg = 0x1020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x1020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_bus_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_bus_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_ext_mclka_out_clk = {
+	.halt_reg = 0x1254,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1254,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_ext_mclka_out_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_ext_mclka_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_ext_mclkb_out_clk = {
+	.halt_reg = 0x1274,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1274,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_ext_mclkb_out_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_ext_mclkb_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_im_sleep_clk = {
+	.halt_reg = 0x12cc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12cc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_im_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_lpaif_pcmoe_clk = {
+	.halt_reg = 0x12c4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12c4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_lpaif_pcmoe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_lpaif_pcmoe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_rx_mclk_2x_clk = {
+	.halt_reg = 0x1298,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1298,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_rx_mclk_2x_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_rx_mclk_clk = {
+	.halt_reg = 0x12a4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_rx_mclk_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_sampling_clk = {
+	.halt_reg = 0x1000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_sampling_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_tx_mclk_2x_clk = {
+	.halt_reg = 0x1294,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1294,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_tx_mclk_2x_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_tx_mclk_rcg_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch audio_core_cc_tx_mclk_clk = {
+	.halt_reg = 0x12a0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x12a0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "audio_core_cc_tx_mclk_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_hw *audio_core_cc_shikra_hws[] = {
+	[AUDIO_CORE_CC_DIG_PLL_OUT_AUX] = &audio_core_cc_dig_pll_out_aux.hw,
+	[AUDIO_CORE_CC_DIG_PLL_OUT_AUX2] = &audio_core_cc_dig_pll_out_aux2.hw,
+};
+
+static struct clk_regmap *audio_core_cc_shikra_clocks[] = {
+	[AUDIO_CORE_CC_AIF_IF0_CLK_SRC] = &audio_core_cc_aif_if0_clk_src.clkr,
+	[AUDIO_CORE_CC_AIF_IF0_EBIT_CLK] = &audio_core_cc_aif_if0_ebit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF0_IBIT_CLK] = &audio_core_cc_aif_if0_ibit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF1_CLK_SRC] = &audio_core_cc_aif_if1_clk_src.clkr,
+	[AUDIO_CORE_CC_AIF_IF1_EBIT_CLK] = &audio_core_cc_aif_if1_ebit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF1_IBIT_CLK] = &audio_core_cc_aif_if1_ibit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF2_CLK_SRC] = &audio_core_cc_aif_if2_clk_src.clkr,
+	[AUDIO_CORE_CC_AIF_IF2_EBIT_CLK] = &audio_core_cc_aif_if2_ebit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF2_IBIT_CLK] = &audio_core_cc_aif_if2_ibit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF3_CLK_SRC] = &audio_core_cc_aif_if3_clk_src.clkr,
+	[AUDIO_CORE_CC_AIF_IF3_EBIT_CLK] = &audio_core_cc_aif_if3_ebit_clk.clkr,
+	[AUDIO_CORE_CC_AIF_IF3_IBIT_CLK] = &audio_core_cc_aif_if3_ibit_clk.clkr,
+	[AUDIO_CORE_CC_AUD_DMA_CLK] = &audio_core_cc_aud_dma_clk.clkr,
+	[AUDIO_CORE_CC_AUD_DMA_CLK_SRC] = &audio_core_cc_aud_dma_clk_src.clkr,
+	[AUDIO_CORE_CC_AUD_DMA_MEM_CLK] = &audio_core_cc_aud_dma_mem_clk.clkr,
+	[AUDIO_CORE_CC_BUS_CLK] = &audio_core_cc_bus_clk.clkr,
+	[AUDIO_CORE_CC_BUS_CLK_SRC] = &audio_core_cc_bus_clk_src.clkr,
+	[AUDIO_CORE_CC_CDIV_TX_MCLK_DIV_CLK_SRC] = &audio_core_cc_cdiv_tx_mclk_div_clk_src.clkr,
+	[AUDIO_CORE_CC_DIG_PLL] = &audio_core_cc_dig_pll.clkr,
+	[AUDIO_CORE_CC_EXT_MCLKA_CLK_SRC] = &audio_core_cc_ext_mclka_clk_src.clkr,
+	[AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK] = &audio_core_cc_ext_mclka_out_clk.clkr,
+	[AUDIO_CORE_CC_EXT_MCLKB_CLK_SRC] = &audio_core_cc_ext_mclkb_clk_src.clkr,
+	[AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK] = &audio_core_cc_ext_mclkb_out_clk.clkr,
+	[AUDIO_CORE_CC_IM_SLEEP_CLK] = &audio_core_cc_im_sleep_clk.clkr,
+	[AUDIO_CORE_CC_LPAIF_PCMOE_CLK] = &audio_core_cc_lpaif_pcmoe_clk.clkr,
+	[AUDIO_CORE_CC_LPAIF_PCMOE_CLK_SRC] = &audio_core_cc_lpaif_pcmoe_clk_src.clkr,
+	[AUDIO_CORE_CC_RX_MCLK_2X_CLK] = &audio_core_cc_rx_mclk_2x_clk.clkr,
+	[AUDIO_CORE_CC_RX_MCLK_CLK] = &audio_core_cc_rx_mclk_clk.clkr,
+	[AUDIO_CORE_CC_SAMPLING_CLK] = &audio_core_cc_sampling_clk.clkr,
+	[AUDIO_CORE_CC_TX_MCLK_2X_CLK] = &audio_core_cc_tx_mclk_2x_clk.clkr,
+	[AUDIO_CORE_CC_TX_MCLK_CLK] = &audio_core_cc_tx_mclk_clk.clkr,
+	[AUDIO_CORE_CC_TX_MCLK_RCG_CLK_SRC] = &audio_core_cc_tx_mclk_rcg_clk_src.clkr,
+};
+
+static struct clk_alpha_pll *audio_core_cc_shikra_plls[] = {
+	&audio_core_cc_dig_pll,
+};
+
+static const struct qcom_cc_driver_data audio_core_cc_shikra_driver_data = {
+	.alpha_plls = audio_core_cc_shikra_plls,
+	.num_alpha_plls = ARRAY_SIZE(audio_core_cc_shikra_plls),
+};
+
+static const struct regmap_config audio_core_cc_shikra_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x305c,
+	.fast_io = true,
+};
+
+static const struct qcom_reset_map audio_core_csr_shikra_resets[] = {
+	[AUDIO_CORE_CSR_RX_SWR_CGCR] = { 0x1c, 1 },
+	[AUDIO_CORE_CSR_TX_SWR_CGCR] = { 0x30, 1 },
+};
+
+static const struct regmap_config audio_core_csr_shikra_regmap_config = {
+	.name = "audio_core_cc_shikra_reset",
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.fast_io = true,
+	.max_register = 0x34,
+};
+
+static const struct qcom_cc_desc audio_core_csr_shikra_desc = {
+	.config = &audio_core_csr_shikra_regmap_config,
+	.resets = audio_core_csr_shikra_resets,
+	.num_resets = ARRAY_SIZE(audio_core_csr_shikra_resets),
+};
+
+static const struct qcom_cc_desc audio_core_cc_shikra_desc = {
+	.config = &audio_core_cc_shikra_regmap_config,
+	.clk_hws = audio_core_cc_shikra_hws,
+	.num_clk_hws = ARRAY_SIZE(audio_core_cc_shikra_hws),
+	.clks = audio_core_cc_shikra_clocks,
+	.num_clks = ARRAY_SIZE(audio_core_cc_shikra_clocks),
+	.driver_data = &audio_core_cc_shikra_driver_data,
+};
+
+static const struct of_device_id audio_core_cc_shikra_match_table[] = {
+	{ .compatible = "qcom,shikra-audiocorecc", .data = &audio_core_cc_shikra_desc },
+	{ .compatible = "qcom,shikra-audiocore-csr", .data = &audio_core_csr_shikra_desc },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, audio_core_cc_shikra_match_table);
+
+static int audio_core_cc_shikra_probe(struct platform_device *pdev)
+{
+	const struct qcom_cc_desc *desc;
+
+	desc = device_get_match_data(&pdev->dev);
+	if (!desc)
+		return -EINVAL;
+
+	return qcom_cc_probe(pdev, desc);
+}
+
+static struct platform_driver audio_core_cc_shikra_driver = {
+	.probe = audio_core_cc_shikra_probe,
+	.driver = {
+		.name = "audiocorecc-shikra",
+		.of_match_table = audio_core_cc_shikra_match_table,
+	},
+};
+
+module_platform_driver(audio_core_cc_shikra_driver);
+
+MODULE_DESCRIPTION("QTI AUDIOCORECC Shikra Driver");
+MODULE_LICENSE("GPL");

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 1/3] dt-bindings: clock: qcom: Add Qualcomm Shikra AudioCoreCC and AudioCoreCSR
From: Imran Shaik @ 2026-07-24 17:15 UTC (permalink / raw)
  To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
	Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Konrad Dybcio
  Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
	linux-kernel, devicetree, Imran Shaik, Krzysztof Kozlowski
In-Reply-To: <20260724-shikra-audiocorecc-v4-0-0a89bb13d817@oss.qualcomm.com>

Add device tree bindings for the Audio Core Clock Controller (AudioCoreCC)
that provides clocks and Audio Core CSR that provides resets on Qualcomm
Shikra SoC.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
 .../bindings/clock/qcom,shikra-audiocorecc.yaml    | 55 ++++++++++++++++++++++
 .../bindings/reset/qcom,shikra-audiocore-csr.yaml  | 42 +++++++++++++++++
 .../dt-bindings/clock/qcom,shikra-audiocorecc.h    | 49 +++++++++++++++++++
 3 files changed, 146 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml b/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..d59f7e47a0d7d9ee9def49be9954038e43785e91
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,shikra-audiocorecc.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,shikra-audiocorecc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Audio Core Clock Controller for Qualcomm Shikra SoC
+
+maintainers:
+  - Imran Shaik <imran.shaik@oss.qualcomm.com>
+
+description: |
+  Audio core clock control module provides the clocks on Qualcomm Shikra
+  SoC platform.
+
+  See also:
+  - include/dt-bindings/clock/qcom,shikra-audiocorecc.h
+
+properties:
+  compatible:
+    const: qcom,shikra-audiocorecc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board sleep clock
+      - description: Audio ref clock source
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    #include <dt-bindings/clock/qcom,shikra-gcc.h>
+    clock-controller@a0a0000 {
+      compatible = "qcom,shikra-audiocorecc";
+      reg = <0x0a0a0000 0x10000>;
+      clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+               <&sleep_clk>,
+               <&aud_ref_clk_src>;
+      #clock-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/reset/qcom,shikra-audiocore-csr.yaml b/Documentation/devicetree/bindings/reset/qcom,shikra-audiocore-csr.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bfad1d20e7cd1281c4c182d5f9f887d8c4c86125
--- /dev/null
+++ b/Documentation/devicetree/bindings/reset/qcom,shikra-audiocore-csr.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/qcom,shikra-audiocore-csr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Audio Core CSR for Qualcomm Shikra SoC
+
+maintainers:
+  - Imran Shaik <imran.shaik@oss.qualcomm.com>
+
+description: |
+  Audio Core CSR module provides the resets on Qualcomm Shikra SoC platform.
+
+  See also:
+  - include/dt-bindings/clock/qcom,shikra-audiocorecc.h
+
+properties:
+  compatible:
+    const: qcom,shikra-audiocore-csr
+
+  reg:
+    maxItems: 1
+
+  '#reset-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    reset-controller@a0b4000 {
+      compatible = "qcom,shikra-audiocore-csr";
+      reg = <0x0a0b4000 0x1000>;
+      #reset-cells = <1>;
+    };
+...
diff --git a/include/dt-bindings/clock/qcom,shikra-audiocorecc.h b/include/dt-bindings/clock/qcom,shikra-audiocorecc.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e64a42523f1ec4213ce8cbbbe6f8262d414f0eb
--- /dev/null
+++ b/include/dt-bindings/clock/qcom,shikra-audiocorecc.h
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_AUDIO_CORE_CC_SHIKRA_H
+#define _DT_BINDINGS_CLK_QCOM_AUDIO_CORE_CC_SHIKRA_H
+
+/* AUDIO_CORE_CC clocks */
+#define AUDIO_CORE_CC_DIG_PLL_OUT_AUX				0
+#define AUDIO_CORE_CC_DIG_PLL_OUT_AUX2				1
+#define AUDIO_CORE_CC_DIG_PLL					2
+#define AUDIO_CORE_CC_AIF_IF0_CLK_SRC				3
+#define AUDIO_CORE_CC_AIF_IF0_EBIT_CLK				4
+#define AUDIO_CORE_CC_AIF_IF0_IBIT_CLK				5
+#define AUDIO_CORE_CC_AIF_IF1_CLK_SRC				6
+#define AUDIO_CORE_CC_AIF_IF1_EBIT_CLK				7
+#define AUDIO_CORE_CC_AIF_IF1_IBIT_CLK				8
+#define AUDIO_CORE_CC_AIF_IF2_CLK_SRC				9
+#define AUDIO_CORE_CC_AIF_IF2_EBIT_CLK				10
+#define AUDIO_CORE_CC_AIF_IF2_IBIT_CLK				11
+#define AUDIO_CORE_CC_AIF_IF3_CLK_SRC				12
+#define AUDIO_CORE_CC_AIF_IF3_EBIT_CLK				13
+#define AUDIO_CORE_CC_AIF_IF3_IBIT_CLK				14
+#define AUDIO_CORE_CC_AUD_DMA_CLK				15
+#define AUDIO_CORE_CC_AUD_DMA_CLK_SRC				16
+#define AUDIO_CORE_CC_AUD_DMA_MEM_CLK				17
+#define AUDIO_CORE_CC_BUS_CLK					18
+#define AUDIO_CORE_CC_BUS_CLK_SRC				19
+#define AUDIO_CORE_CC_CDIV_TX_MCLK_DIV_CLK_SRC			20
+#define AUDIO_CORE_CC_EXT_MCLKA_CLK_SRC				21
+#define AUDIO_CORE_CC_EXT_MCLKA_OUT_CLK				22
+#define AUDIO_CORE_CC_EXT_MCLKB_CLK_SRC				23
+#define AUDIO_CORE_CC_EXT_MCLKB_OUT_CLK				24
+#define AUDIO_CORE_CC_IM_SLEEP_CLK				25
+#define AUDIO_CORE_CC_LPAIF_PCMOE_CLK				26
+#define AUDIO_CORE_CC_LPAIF_PCMOE_CLK_SRC			27
+#define AUDIO_CORE_CC_RX_MCLK_2X_CLK				28
+#define AUDIO_CORE_CC_RX_MCLK_CLK				29
+#define AUDIO_CORE_CC_SAMPLING_CLK				30
+#define AUDIO_CORE_CC_TX_MCLK_2X_CLK				31
+#define AUDIO_CORE_CC_TX_MCLK_CLK				32
+#define AUDIO_CORE_CC_TX_MCLK_RCG_CLK_SRC			33
+
+/* AUDIO_CORE_CSR resets */
+#define AUDIO_CORE_CSR_RX_SWR_CGCR	0
+#define AUDIO_CORE_CSR_TX_SWR_CGCR	1
+
+#endif

-- 
2.34.1


^ permalink raw reply related

* [PATCH v4 0/3] clk: qcom: Add Audio Core clock controller support on Qualcomm Shikra SoC
From: Imran Shaik @ 2026-07-24 17:15 UTC (permalink / raw)
  To: Bjorn Andersson, Michael Turquette, Stephen Boyd, Brian Masney,
	Philipp Zabel, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Konrad Dybcio
  Cc: Ajit Pandey, Taniya Das, Jagadeesh Kona, linux-arm-msm, linux-clk,
	linux-kernel, devicetree, Imran Shaik, Krzysztof Kozlowski,
	Konrad Dybcio, Dmitry Baryshkov

This series adds support for the Audio Core Clock Controller (AUDIOCORECC)
and Audio Core CSR resets on Qualcomm Shikra SoC. The Audio Core Clocks and
Resets support differs across Shikra variants based on Audio subsystem
enablement as follows:

- CQM variant: The QAIF driver runs on HLOS, hence both clocks and resets
are required to be supported on HLOS.
- CQS variant: The QAIF driver runs on the Modem, and required clocks are
handled on Modem, so from HLOS only resets are needed.
- IQS variant: no soundwire codes, hence no clocks/resets are needed.

Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
---
Changes in v4:
- Dropped "clk: qcom: common: Register reset controller only when resets are present" patch
  - Sashiko AI review pointed a valid GDSC-only corner case issue with this
    change, will address it in a separate patch.
  - This patch is not needed for this series, after splitting AudioCoreCC
    clocks and resets into different devices.
- Added NULL check for device_get_match_data() in driver [Sashiko AI review]
- Removed unnecessary <linux/mod_devicetable.h> include in driver [Uwe]
- Collected the R-By tags received on v2.
- Link to v3: https://lore.kernel.org/r/20260723-shikra-audiocorecc-v3-0-90b878ae0d4e@oss.qualcomm.com

Changes in v3:
- Rebased on next-20260722, as the dependent RPMCC/GCC and Shikra base
  DTS changes were merged. 
- Separated the audiocorecc and audiocore_csr bindings into separate schema
  docs [Rob]
- Moved the AudioCoreCSR schema to bindings/reset/, since it now only
  describes a reset controller.
- Updated audiocorecc DTS node to use status reserved [Konrad]
- Kept audiocore_csr node globally enabled by default in DTS [Konrad]
- Collected all the R-By received on v1. 
- Link to v2: https://lore.kernel.org/r/20260708-shikra-audiocorecc-v2-0-b320d822cdd0@oss.qualcomm.com

Changes in v2:
- Separated AudioCoreCC and AudioCoreCSR nodes as both resides in two
  different register spaces. [Konrad]
- Updated bindings and driver patches to handle the separate node
  compatibles.
- Updated resets in driver patch to handle HW_CTL bit.
- Link to v1: https://lore.kernel.org/r/20260605-shikra-audiocorecc-v1-0-7ee6b5f2d928@oss.qualcomm.com

---
Imran Shaik (3):
      dt-bindings: clock: qcom: Add Qualcomm Shikra AudioCoreCC and AudioCoreCSR
      clk: qcom: Add Audio Core clock controller support on Qualcomm Shikra SoC
      arm64: dts: qcom: shikra: Add support for AudioCoreCC and AudioCoreCSR nodes

 .../bindings/clock/qcom,shikra-audiocorecc.yaml    |  55 ++
 .../bindings/reset/qcom,shikra-audiocore-csr.yaml  |  42 ++
 arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts        |   4 +
 arch/arm64/boot/dts/qcom/shikra.dtsi               |  17 +
 drivers/clk/qcom/Kconfig                           |  10 +
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/audiocorecc-shikra.c              | 810 +++++++++++++++++++++
 .../dt-bindings/clock/qcom,shikra-audiocorecc.h    |  49 ++
 8 files changed, 988 insertions(+)
---
base-commit: b4515cf4156356e8f4fe6e0fdc17f59adab9772f
change-id: 20260605-shikra-audiocorecc-85efef073474

Best regards,
-- 
Imran Shaik <imran.shaik@oss.qualcomm.com>


^ permalink raw reply

* Re: [PATCH v18 1/2] dt-bindings: embedded-controller: Add synology microp devices
From: sashiko-bot @ 2026-07-24 17:15 UTC (permalink / raw)
  To: Markus Probst; +Cc: robh, lee, devicetree, conor+dt, linux-leds, ojeda
In-Reply-To: <20260724-synology_microp_initial-v18-1-fb2f49f10e77@posteo.de>

> Add the Synology Microp devicetree bindings. Those devices are
> microcontrollers found on Synology NAS devices. They are connected to a
> serial port on the host device.
> 
> Those devices are used to control certain LEDs, fan speeds, a beeper, to
> handle buttons, fan failures and to properly shutdown and reboot the
> device.
> 
> The device has a different feature set depending on the Synology NAS
> model, like having different number of fans, buttons and leds. Depending
> on the architecture of the model, they also need a different system
> shutdown behaviour.
> 
> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> Signed-off-by: Markus Probst <markus.probst@posteo.de>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724-synology_microp_initial-v18-0-fb2f49f10e77@posteo.de?part=1


^ permalink raw reply

* [PATCH v18 2/2] platform: Add initial synology microp driver
From: Markus Probst @ 2026-07-24 17:10 UTC (permalink / raw)
  To: Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
	Lee Jones, Pavel Machek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Greg Kroah-Hartman, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: platform-driver-x86, linux-leds, devicetree, linux-kernel,
	rust-for-linux, Markus Probst
In-Reply-To: <20260724-synology_microp_initial-v18-0-fb2f49f10e77@posteo.de>

Add a initial synology microp driver, written in Rust.
The driver targets a microcontroller found in Synology NAS devices. It
currently only supports controlling of the power led, status led, alert
led and usb led. Other components such as fan control or handling
on-device buttons will be added once the required rust abstractions are
there.

This driver can be used both on arm and x86, thus it goes into the root
directory of drivers/platform.

Tested successfully on a Synology DS923+.

Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
 MAINTAINERS                                        |   7 +
 drivers/platform/Kconfig                           |   2 +
 drivers/platform/Makefile                          |   1 +
 drivers/platform/synology_microp/Kconfig           |  13 +
 drivers/platform/synology_microp/Makefile          |   5 +
 drivers/platform/synology_microp/command.rs        |  54 ++++
 drivers/platform/synology_microp/led.rs            | 304 +++++++++++++++++++++
 drivers/platform/synology_microp/model.rs          |  49 ++++
 .../platform/synology_microp/synology_microp.rs    |  91 ++++++
 9 files changed, 526 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index dacc8640926a..ced5fea318f4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26145,6 +26145,13 @@ F:	drivers/dma-buf/sync_*
 F:	include/linux/sync_file.h
 F:	include/uapi/linux/sync_file.h
 
+SYNOLOGY MICROP DRIVER
+M:	Markus Probst <markus.probst@posteo.de>
+L:	platform-driver-x86@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
+F:	drivers/platform/synology_microp/
+
 SYNOPSYS ARC ARCHITECTURE
 M:	Vineet Gupta <vgupta@kernel.org>
 L:	linux-snps-arc@lists.infradead.org
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 312788f249c9..996050566a4a 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -22,3 +22,5 @@ source "drivers/platform/arm64/Kconfig"
 source "drivers/platform/raspberrypi/Kconfig"
 
 source "drivers/platform/wmi/Kconfig"
+
+source "drivers/platform/synology_microp/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index fa322e7f8716..2381872e9133 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_SURFACE_PLATFORMS)	+= surface/
 obj-$(CONFIG_ARM64_PLATFORM_DEVICES)	+= arm64/
 obj-$(CONFIG_BCM2835_VCHIQ)	+= raspberrypi/
 obj-$(CONFIG_ACPI_WMI)		+= wmi/
+obj-$(CONFIG_SYNOLOGY_MICROP)	+= synology_microp/
diff --git a/drivers/platform/synology_microp/Kconfig b/drivers/platform/synology_microp/Kconfig
new file mode 100644
index 000000000000..8878cfb7bcdd
--- /dev/null
+++ b/drivers/platform/synology_microp/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config SYNOLOGY_MICROP
+	tristate "Synology Microp driver"
+	depends on LEDS_CLASS && LEDS_CLASS_MULTICOLOR
+	depends on RUST_SERIAL_DEV_BUS_ABSTRACTIONS
+	help
+	  Enable support for the EC found in Synology NAS devices.
+
+	  This is needed to properly shutdown and reboot the device, as well as
+	  additional functionality like fan and LED control.
+
+	  This driver is work in progress and may not be fully functional.
diff --git a/drivers/platform/synology_microp/Makefile b/drivers/platform/synology_microp/Makefile
new file mode 100644
index 000000000000..2681a793d6d8
--- /dev/null
+++ b/drivers/platform/synology_microp/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_SYNOLOGY_MICROP) += synology-microp.o
+synology-microp-y += synology_microp.o
+
diff --git a/drivers/platform/synology_microp/command.rs b/drivers/platform/synology_microp/command.rs
new file mode 100644
index 000000000000..490719490391
--- /dev/null
+++ b/drivers/platform/synology_microp/command.rs
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::{
+    device::Bound,
+    error::Result,
+    serdev, //
+};
+
+use crate::led;
+
+#[expect(
+    clippy::enum_variant_names,
+    reason = "future variants will not end with Led"
+)]
+pub(crate) enum Command {
+    PowerLed(led::State),
+    StatusLed(led::StatusLedColor, led::State),
+    AlertLed(led::State),
+    UsbLed(led::State),
+    EsataLed(led::State),
+}
+
+impl Command {
+    pub(crate) fn write(self, dev: &serdev::Device<Bound>) -> Result {
+        dev.write_all(
+            match self {
+                Self::PowerLed(led::State::On) => &[0x34],
+                Self::PowerLed(led::State::Blink) => &[0x35],
+                Self::PowerLed(led::State::Off) => &[0x36],
+
+                Self::StatusLed(_, led::State::Off) => &[0x37],
+                Self::StatusLed(led::StatusLedColor::Green, led::State::On) => &[0x38],
+                Self::StatusLed(led::StatusLedColor::Green, led::State::Blink) => &[0x39],
+                Self::StatusLed(led::StatusLedColor::Amber, led::State::On) => &[0x3A],
+                Self::StatusLed(led::StatusLedColor::Amber, led::State::Blink) => &[0x3B],
+
+                Self::AlertLed(led::State::On) => &[0x4C, 0x41, 0x31],
+                Self::AlertLed(led::State::Blink) => &[0x4C, 0x41, 0x32],
+                Self::AlertLed(led::State::Off) => &[0x4C, 0x41, 0x33],
+
+                Self::UsbLed(led::State::On) => &[0x40],
+                Self::UsbLed(led::State::Blink) => &[0x41],
+                Self::UsbLed(led::State::Off) => &[0x42],
+
+                Self::EsataLed(led::State::On) => &[0x4C, 0x45, 0x31],
+                Self::EsataLed(led::State::Blink) => &[0x4C, 0x45, 0x32],
+                Self::EsataLed(led::State::Off) => &[0x4C, 0x45, 0x33],
+            },
+            0,
+        )?;
+        dev.wait_until_sent(0);
+        Ok(())
+    }
+}
diff --git a/drivers/platform/synology_microp/led.rs b/drivers/platform/synology_microp/led.rs
new file mode 100644
index 000000000000..01cad98616fd
--- /dev/null
+++ b/drivers/platform/synology_microp/led.rs
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::{
+    device::Bound,
+    led::{
+        self,
+        LedOps,
+        MultiColorSubLed, //
+    },
+    new_mutex,
+    prelude::*,
+    serdev,
+    str::CString,
+    sync::Mutex,
+    time::Delta, //
+};
+use pin_init::pin_init_scope;
+
+use crate::{
+    command::Command,
+    model::Model, //
+};
+
+#[pin_data]
+pub(crate) struct Data<'bound> {
+    #[pin]
+    status: led::MultiColorDevice<'bound, StatusLedHandler>,
+    power_name: CString,
+    #[pin]
+    power: led::Device<'bound, LedHandler>,
+    alert: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
+    usb_copy: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
+    esata: Option<Pin<KBox<led::Device<'bound, LedHandler>>>>,
+}
+
+impl<'bound> Data<'bound> {
+    pub(super) fn register<'a>(
+        dev: &'bound serdev::Device<Bound>,
+        model: &'a Model,
+    ) -> impl PinInit<Self, Error> + 'a
+    where
+        'bound: 'a,
+    {
+        pin_init_scope(move || {
+            Ok(try_pin_init!(Self {
+                status <- led::DeviceBuilder::new()
+                    .color(led::Color::Multi)
+                    .name(c"synology:multicolor:status")
+                    .build_multicolor(
+                        dev,
+                        try_pin_init!(StatusLedHandler {
+                            blink <- new_mutex!(false),
+                        }),
+                        &[
+                            MultiColorSubLed::new(led::Color::Green).initial_intensity(1),
+                            MultiColorSubLed::new(led::Color::Amber),
+                        ],
+                    ),
+                power_name: CString::try_from_fmt(fmt!(
+                    "synology:{}:power",
+                    model.led_power.as_c_str().to_str()?
+                ))?,
+                power <- led::DeviceBuilder::new()
+                    .color(model.led_power)
+                    .name(power_name)
+                    .build(
+                        dev,
+                        try_pin_init!(LedHandler {
+                            blink <- new_mutex!(false),
+                            command: Command::PowerLed,
+                        }),
+                    ),
+                alert: {
+                    if let Some(color) = model.led_alert {
+                        let name = CString::try_from_fmt(fmt!(
+                            "synology:{}:alarm",
+                            color.as_c_str().to_str()?
+                        ))?;
+                        Some(KBox::pin_init(
+                            led::DeviceBuilder::new().color(color).name(&name).build(
+                                dev,
+                                try_pin_init!(LedHandler {
+                                    blink <- new_mutex!(false),
+                                    command: Command::AlertLed,
+                                }),
+                            ),
+                            GFP_KERNEL,
+                        )?)
+                    } else {
+                        None
+                    }
+                },
+                usb_copy: {
+                    if model.led_usb_copy {
+                        Some(KBox::pin_init(
+                            led::DeviceBuilder::new()
+                                .color(led::Color::Green)
+                                .name(c"synology:green:usb")
+                                .build(
+                                    dev,
+                                    try_pin_init!(LedHandler {
+                                        blink <- new_mutex!(false),
+                                        command: Command::UsbLed,
+                                    }),
+                                ),
+                            GFP_KERNEL,
+                        )?)
+                    } else {
+                        None
+                    }
+                },
+                esata: {
+                    if model.led_esata {
+                        Some(KBox::pin_init(
+                            led::DeviceBuilder::new()
+                                .color(led::Color::Green)
+                                .name(c"synology:green:esata")
+                                .build(
+                                    dev,
+                                    try_pin_init!(LedHandler {
+                                        blink <- new_mutex!(false),
+                                        command: Command::EsataLed,
+                                    }),
+                                ),
+                            GFP_KERNEL,
+                        )?)
+                    } else {
+                        None
+                    }
+                },
+            }))
+        })
+    }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum StatusLedColor {
+    Green,
+    Amber,
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum State {
+    On,
+    Blink,
+    Off,
+}
+
+#[pin_data]
+struct LedHandler {
+    #[pin]
+    blink: Mutex<bool>,
+    command: fn(State) -> Command,
+}
+
+/// Blink delay measured using video recording on DS923+ for Power and Status Led.
+///
+/// We assume it is the same for all other leds and models.
+const BLINK_DELAY: Delta = Delta::from_millis(167);
+
+#[vtable]
+impl LedOps for LedHandler {
+    type Bus = serdev::Device<Bound>;
+    type Mode = led::Normal;
+    const BLOCKING: bool = true;
+    const MAX_BRIGHTNESS: u32 = 1;
+
+    fn brightness_set<'bound>(
+        &self,
+        dev: &'bound Self::Bus,
+        _classdev: &led::Device<'bound, Self>,
+        brightness: u32,
+    ) -> Result<()> {
+        let mut blink = self.blink.lock();
+        (self.command)(if brightness == 0 {
+            *blink = false;
+            State::Off
+        } else if *blink {
+            State::Blink
+        } else {
+            State::On
+        })
+        .write(dev)?;
+
+        Ok(())
+    }
+
+    fn blink_set<'bound>(
+        &self,
+        dev: &'bound Self::Bus,
+        _classdev: &led::Device<'bound, Self>,
+        delay_on: &mut usize,
+        delay_off: &mut usize,
+    ) -> Result<()> {
+        let mut blink = self.blink.lock();
+
+        (self.command)(if *delay_on == 0 && *delay_off != 0 {
+            *blink = false;
+
+            State::Off
+        } else if *delay_on != 0 && *delay_off == 0 {
+            *blink = false;
+
+            State::On
+        } else {
+            *blink = true;
+            *delay_on = BLINK_DELAY.as_millis() as usize;
+            *delay_off = BLINK_DELAY.as_millis() as usize;
+
+            State::Blink
+        })
+        .write(dev)
+    }
+}
+
+#[pin_data]
+struct StatusLedHandler {
+    #[pin]
+    blink: Mutex<bool>,
+}
+
+#[vtable]
+impl LedOps for StatusLedHandler {
+    type Bus = serdev::Device<Bound>;
+    type Mode = led::MultiColor;
+    const BLOCKING: bool = true;
+    const MAX_BRIGHTNESS: u32 = 1;
+
+    fn brightness_set<'bound>(
+        &self,
+        dev: &'bound Self::Bus,
+        classdev: &led::MultiColorDevice<'bound, Self>,
+        brightness: u32,
+    ) -> Result<()> {
+        let mut blink = self.blink.lock();
+        if brightness == 0 {
+            *blink = false;
+        }
+
+        let amber_brightness = classdev.subleds()[1].brightness();
+
+        let (color, subled_brightness) = if amber_brightness == 0 {
+            (StatusLedColor::Green, classdev.subleds()[0].brightness())
+        } else {
+            (StatusLedColor::Amber, amber_brightness)
+        };
+
+        Command::StatusLed(
+            color,
+            if subled_brightness == 0 {
+                State::Off
+            } else if *blink {
+                State::Blink
+            } else {
+                State::On
+            },
+        )
+        .write(dev)
+    }
+
+    fn blink_set<'bound>(
+        &self,
+        dev: &'bound Self::Bus,
+        classdev: &led::MultiColorDevice<'bound, Self>,
+        delay_on: &mut usize,
+        delay_off: &mut usize,
+    ) -> Result<()> {
+        let mut blink = self.blink.lock();
+
+        let amber_intensity = classdev.subleds()[1].intensity();
+
+        let (color, subled_intensity) = if amber_intensity == 0 {
+            (StatusLedColor::Green, classdev.subleds()[0].intensity())
+        } else {
+            (StatusLedColor::Amber, amber_intensity)
+        };
+        Command::StatusLed(
+            color,
+            if *delay_on == 0 && *delay_off != 0 {
+                *blink = false;
+                State::Off
+            } else if *delay_on != 0 && *delay_off == 0 {
+                *blink = false;
+
+                if subled_intensity == 0 {
+                    State::Off
+                } else {
+                    State::On
+                }
+            } else {
+                *blink = true;
+                *delay_on = BLINK_DELAY.as_millis() as usize;
+                *delay_off = BLINK_DELAY.as_millis() as usize;
+
+                if subled_intensity == 0 {
+                    State::Off
+                } else {
+                    State::Blink
+                }
+            },
+        )
+        .write(dev)
+    }
+}
diff --git a/drivers/platform/synology_microp/model.rs b/drivers/platform/synology_microp/model.rs
new file mode 100644
index 000000000000..715d8840f56b
--- /dev/null
+++ b/drivers/platform/synology_microp/model.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::led::Color;
+
+pub(crate) struct Model {
+    pub(crate) led_power: Color,
+    pub(crate) led_alert: Option<Color>,
+    pub(crate) led_usb_copy: bool,
+    pub(crate) led_esata: bool,
+}
+
+impl Model {
+    pub(super) const fn new() -> Self {
+        Self {
+            led_power: Color::Blue,
+            led_alert: None,
+            led_usb_copy: false,
+            led_esata: false,
+        }
+    }
+
+    pub(super) const fn led_power(self, color: Color) -> Self {
+        Self {
+            led_power: color,
+            ..self
+        }
+    }
+
+    pub(super) const fn led_alert(self, color: Color) -> Self {
+        Self {
+            led_alert: Some(color),
+            ..self
+        }
+    }
+
+    pub(super) const fn led_esata(self) -> Self {
+        Self {
+            led_esata: true,
+            ..self
+        }
+    }
+
+    pub(super) const fn led_usb_copy(self) -> Self {
+        Self {
+            led_usb_copy: true,
+            ..self
+        }
+    }
+}
diff --git a/drivers/platform/synology_microp/synology_microp.rs b/drivers/platform/synology_microp/synology_microp.rs
new file mode 100644
index 000000000000..f7168309e611
--- /dev/null
+++ b/drivers/platform/synology_microp/synology_microp.rs
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Synology Microp driver
+
+use kernel::{
+    device,
+    led::Color,
+    of::{
+        DeviceId,
+        IdTable, //
+    },
+    of_device_table,
+    prelude::*,
+    serdev, //
+};
+use pin_init::pin_init_scope;
+
+use crate::model::Model;
+
+pub(crate) mod command;
+mod led;
+mod model;
+
+kernel::module_serdev_device_driver! {
+    type: SynologyMicropDriver<'static>,
+    name: "synology_microp",
+    authors: ["Markus Probst <markus.probst@posteo.de>"],
+    description: "Synology Microp driver",
+    license: "GPL v2",
+}
+
+#[rustfmt::skip]
+of_device_table!(
+    OF_TABLE,
+    MODULE_OF_TABLE,
+    Model,
+    [
+        // apollolake
+        (DeviceId::new(c"synology,ds918p-microp"), Model::new()),
+
+        // evansport
+        (DeviceId::new(c"synology,ds214play-microp"), Model::new()),
+
+        // geminilakenk
+        (DeviceId::new(c"synology,ds225p-microp"), Model::new().led_usb_copy()),
+
+        // pineview
+        (DeviceId::new(c"synology,ds710p-microp"), Model::new().led_esata()),
+        (DeviceId::new(c"synology,ds1010p-microp"), Model::new().led_alert(Color::Amber)),
+
+        // rtd1296
+        (DeviceId::new(c"synology,ds118-microp"), Model::new()),
+
+        // rtd1619b
+        (DeviceId::new(c"synology,ds223-microp"), Model::new().led_usb_copy()),
+
+        // v1000
+        (DeviceId::new(c"synology,ds1823xsp-microp"), Model::new()),
+        (DeviceId::new(c"synology,rs1221p-microp"), Model::new().led_power(Color::Green)),
+    ]
+);
+
+#[pin_data]
+struct SynologyMicropDriver<'bound> {
+    #[pin]
+    led: led::Data<'bound>,
+}
+
+#[vtable]
+impl serdev::Driver for SynologyMicropDriver<'_> {
+    type IdInfo = Model;
+    type Data<'bound> = SynologyMicropDriver<'bound>;
+    const OF_ID_TABLE: Option<IdTable<Self::IdInfo>> = Some(&OF_TABLE);
+
+    fn probe<'bound>(
+        dev: &'bound serdev::Device<device::Core<'_>>,
+        model: Option<&'bound Model>,
+    ) -> impl PinInit<Self::Data<'bound>, kernel::error::Error> + 'bound {
+        pin_init_scope(move || {
+            let model = model.ok_or(EINVAL)?;
+
+            dev.set_baudrate(9600).map_err(|_| EINVAL)?;
+            dev.set_flow_control(false);
+            dev.set_parity(serdev::Parity::None)?;
+
+            Ok(try_pin_init!(SynologyMicropDriver {
+                led <- led::Data::register(dev, model),
+            }))
+        })
+    }
+}

-- 
2.54.0


^ permalink raw reply related

* [PATCH v18 1/2] dt-bindings: embedded-controller: Add synology microp devices
From: Markus Probst @ 2026-07-24 17:10 UTC (permalink / raw)
  To: Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
	Lee Jones, Pavel Machek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Greg Kroah-Hartman, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: platform-driver-x86, linux-leds, devicetree, linux-kernel,
	rust-for-linux, Markus Probst, Krzysztof Kozlowski
In-Reply-To: <20260724-synology_microp_initial-v18-0-fb2f49f10e77@posteo.de>

Add the Synology Microp devicetree bindings. Those devices are
microcontrollers found on Synology NAS devices. They are connected to a
serial port on the host device.

Those devices are used to control certain LEDs, fan speeds, a beeper, to
handle buttons, fan failures and to properly shutdown and reboot the
device.

The device has a different feature set depending on the Synology NAS
model, like having different number of fans, buttons and leds. Depending
on the architecture of the model, they also need a different system
shutdown behaviour.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
 .../synology,ds918p-microp.yaml                    | 100 +++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml b/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
new file mode 100644
index 000000000000..a44101884322
--- /dev/null
+++ b/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/embedded-controller/synology,ds918p-microp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synology NAS on-board Microcontroller
+
+maintainers:
+  - Markus Probst <markus.probst@posteo.de>
+
+description: |
+  Synology Microp is a microcontroller found in Synology NAS devices.
+  It is connected to a serial port on the host device.
+
+  It is necessary to properly shutdown and reboot the NAS device and
+  provides additional functionality such as led control, fan speed control,
+  a beeper and buttons on the NAS device.
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - synology,rs1221rpp-microp
+              - synology,rs822p-microp
+              - synology,rs422p-microp
+          - const: synology,rs1221p-microp
+
+      - items:
+          - const: synology,ds1825p-microp
+          - const: synology,ds1823xsp-microp
+
+      - items:
+          - enum:
+              - synology,ds725p-microp
+              - synology,ds225p-microp
+              - synology,ds723p-microp
+              - synology,ds710p-microp
+          - const: synology,ds214play-microp
+
+      - items:
+          - enum:
+              - synology,ds425p-microp
+              - synology,ds1525p-microp
+              - synology,ds925p-microp
+              - synology,ds923p-microp
+              - synology,ds1522p-microp
+              - synology,ds1010p-microp
+              - synology,ds411p-microp
+          - const: synology,ds918p-microp
+
+      - items:
+          - enum:
+              - synology,ds124-microp
+              - synology,ds223j-microp
+              - synology,ds223-microp
+          - const: synology,ds118-microp
+
+      - enum:
+          - synology,ds118-microp
+          - synology,ds1823xsp-microp
+          - synology,rs1221p-microp
+          - synology,ds918p-microp
+          - synology,ds214play-microp
+
+  fan-failure-gpios:
+    description: GPIOs needed to determine which fans stopped working on a fan failure event.
+    minItems: 2
+    maxItems: 3
+
+required:
+  - compatible
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - synology,ds918p-microp
+              - synology,rs422p-microp
+    then:
+      required:
+        - fan-failure-gpios
+    else:
+      properties:
+        fan-failure-gpios: false
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    embedded-controller {
+      compatible = "synology,ds923p-microp", "synology,ds918p-microp";
+
+      fan-failure-gpios = <&gpio 68 GPIO_ACTIVE_HIGH>, <&gpio 69 GPIO_ACTIVE_HIGH>;
+    };

-- 
2.54.0


^ permalink raw reply related

* [PATCH v18 0/2] Introduce Synology Microp driver
From: Markus Probst @ 2026-07-24 17:10 UTC (permalink / raw)
  To: Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
	Lee Jones, Pavel Machek, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Greg Kroah-Hartman, Daniel Almeida,
	Tamir Duberstein, Alexandre Courbot, Onur Özkan
  Cc: platform-driver-x86, linux-leds, devicetree, linux-kernel,
	rust-for-linux, Markus Probst, Krzysztof Kozlowski

Synology uses a microcontroller in their NAS devices connected to a
serial port to control certain LEDs, fan speeds, a beeper, to handle
proper shutdown and restart, buttons and fan failures.

This patch series depends on the rust led abstraction [1] and the rust
serdev abstraction [2]. The latter already being in driver-core.

This is only a initial version of the driver able to control LEDs.
The following rust abstractions would be required, to implement the
remaining features:
- hwmon (include/linux/hwmon.h)
- input (include/linux/input.h)
- sysoff handler (include/linux/reboot.h)

[1] https://lore.kernel.org/rust-for-linux/20260716-rust_leds-v23-0-e91f5b608b56@posteo.de/
[2] https://lore.kernel.org/rust-for-linux/20260718-rust_serdev-v16-0-5809384d2e1b@posteo.de/

Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
Changes in v18:
- fix issues reported by Sashiko:
  - fix hardware blink delays not reported if every subled has
    intensity = 0
- fix blink aborting if every subled has intensity = 0
- Link to v17: https://patch.msgid.link/20260724-synology_microp_initial-v17-0-e2f70b4dc691@posteo.de

Changes in v17:
- adapted to rust serdev abstraction v16
- Link to v16: https://patch.msgid.link/20260629-synology_microp_initial-v16-0-601e91c49e0d@posteo.de

Changes in v16:
- fix issues reported by Sashiko:
  - fix typo in dt compatible
  - fix not compilable as loadable module
- Link to v15: https://patch.msgid.link/20260629-synology_microp_initial-v15-0-4b3d7367c7cf@posteo.de

Changes in v15:
- adapted to rust led abstractiopn v21
- Link to v14: https://patch.msgid.link/20260531-synology_microp_initial-v14-0-1377d425b24b@posteo.de

Changes in v14:
- adapt to led abstraction v18 and serdev abstraction v11
- Link to v13: https://patch.msgid.link/20260530-synology_microp_initial-v13-0-aa2bb9c56efc@posteo.de

Changes in v13:
- adapted to driver-lifetime v5 patch series.
- set blink = false as initial power led state, as set_blink hasn't been
  called yet (even though the led is blinking at startup)
- Link to v12: https://patch.msgid.link/20260429-synology_microp_initial-v12-0-40a05033c620@posteo.de

Changes in v12:
- adapted to driver-lifetime patch series. The driver can't take
  advantage of it, until class devices like led also make use of it.
- Link to v11: https://patch.msgid.link/20260427-synology_microp_initial-v11-0-9c1bd5a6f3ed@posteo.de

Changes in v11:
- rebased on top of 7.1-rc1
- add "synology" as devicename to led, like it is done in existing dts
  files in the kernel
- fix color for led being orange instead of amber. I personally can't
  clearly tell them apart, but apparently its amber.
- replaced MCU with EC in Kconfig help
- Link to v10: https://patch.msgid.link/20260424-synology_microp_initial-v10-0-e852d2f3eba1@posteo.de

Changes in v10:
- resolved issues reported by Sashiko Bot:
  - removed unneeded include from device tree
  - fix typo in of device table
  - fix blink not set to false, if delay_off or delay_on is 0
- Link to v9: https://patch.msgid.link/20260423-synology_microp_initial-v9-0-4a8533f87e07@posteo.de

Changes in v9:
- separate fallback and front compatibles in dt schema
- remove front compatibles from of id table, if all functionality is
  by covered by the fallback
- remove TODO file
- add platform-driver-x86@vger.kernel.org to Maintainers file entry
- use `Delta` type in `BLINK_DELAY` const
- Link to v8: https://patch.msgid.link/20260420-synology_microp_initial-v8-0-7946a9124491@posteo.de

Changes in v8:
- removed unnecessary Copy and Clone derive
- added `BLINK_DELAY` constant
- added compatible id fallbacks
- moved dt schema patch before the driver
- added ds411p
- Link to v7: https://lore.kernel.org/r/20260411-synology_microp_initial-v7-0-9a3a094e763a@posteo.de

Changes in v7:
- remove list of compatible ids from commit msg
- explain what makes the different models not compatible in the commit msg
- remove unnecessary examples
- Link to v6: https://lore.kernel.org/r/20260405-synology_microp_initial-v6-0-08fde474b6c9@posteo.de

Changes in v6:
- moved devicetree bindings patch at the end of the set
- remove several patches
- move of id table from model.rs to synology_microp.rs
- remove the model! macro
- use if blocks in devicetree schema to narrow down the
  fan-failure-gpios property
- add multiple devicetree examples to test if blocks
- Link to v5: https://lore.kernel.org/r/20260329-synology_microp_initial-v5-0-27cb80bdf591@posteo.de

Changes in v5:
- add esata led support
- use different compatible for each model
- add visibility modifier to of_device_table macro
- fix match data missing when using PRP0001
- Link to v4: https://lore.kernel.org/r/20260320-synology_microp_initial-v4-0-0423ddb83ca4@posteo.de

Changes in v4:
- convert to monolithic driver and moved it into drivers/platform
- removed mfd rust abstraction
- moved dt-bindings to embedded-controller
- Link to v3: https://lore.kernel.org/r/20260313-synology_microp_initial-v3-0-ad6ac463a201@posteo.de

Changes in v3:
- remove `default n` from Kconfig entry, as n is the default already.
- select RUST_SERIAL_DEV_BUS_ABSTRACTIONS in Kconfig
- add mfd rust abstraction
- split core and led parts into their own driver. It should now be considered a
  MFD device.
- split led part of dt binding into its own file
- Link to v2: https://lore.kernel.org/r/20260308-synology_microp_initial-v2-0-9389963f31c5@posteo.de

Changes in v2:
- fix missing tabs in MAINTAINERS file
- remove word binding from patch subject
- add missing signed-off-by
- add missing help entry in Kconfig
- add missing spdx license headers
- remove no-check{,-cpu}-fan properties from the dt-bindings and replace
  them with the check_fan module parameter
- use patternProperties for leds in dt-bindings
- license dt-binding as GPL-2.0-only OR BSD-2-Clause
- move driver from staging tree into mfd tree and mark it as work in
  progress inside Kconfig
- only register alert and usb led if fwnode is present
- Link to v1: https://lore.kernel.org/r/20260306-synology_microp_initial-v1-0-fcffede6448c@posteo.de

---
Markus Probst (2):
      dt-bindings: embedded-controller: Add synology microp devices
      platform: Add initial synology microp driver

 .../synology,ds918p-microp.yaml                    | 100 +++++++
 MAINTAINERS                                        |   7 +
 drivers/platform/Kconfig                           |   2 +
 drivers/platform/Makefile                          |   1 +
 drivers/platform/synology_microp/Kconfig           |  13 +
 drivers/platform/synology_microp/Makefile          |   5 +
 drivers/platform/synology_microp/command.rs        |  54 ++++
 drivers/platform/synology_microp/led.rs            | 304 +++++++++++++++++++++
 drivers/platform/synology_microp/model.rs          |  49 ++++
 .../platform/synology_microp/synology_microp.rs    |  91 ++++++
 10 files changed, 626 insertions(+)
---
base-commit: 6946cd5d0aa4dd10a414ddcb7a10844fdb0ad345
change-id: 20260306-synology_microp_initial-0f7dac7b7496
prerequisite-message-id: 20260530132736.3298549-1-dakr@kernel.org
prerequisite-patch-id: 310c6bee038ca3909a8e5e58ec12b74f7189b869
prerequisite-patch-id: 92812c3d42b29504838e6dc66c307ff5c035bb5e
prerequisite-change-id: 20251217-rust_serdev-ee5481e9085c:v16
prerequisite-patch-id: 758729124be172e4a5e7d3b1f23fbfc890c53142
prerequisite-patch-id: cfe1067f048223fca63fffebdaab3e5901aefc91
prerequisite-patch-id: 5d4c4bfebce51c436fa515d27f00968ae0f63fe6
prerequisite-patch-id: e1d6843c4904b00159ba6f1631b8599bcf0de786
prerequisite-patch-id: 7f128260015f8f3cee0bd9c9a3a6d30765547efe
prerequisite-patch-id: 52e1b7796c39486e6e35d5aeb7b5b81d384e7eac
prerequisite-patch-id: 21db58f3d1dd257ca06c61c2526080ee992b5994
prerequisite-patch-id: 338647432f003c96010a0859478a69b56872b617
prerequisite-patch-id: 2eb115a27636c9b9848debab391fa2b747e70557
prerequisite-patch-id: b75caf90bd344b7bcfb189e892a89121cb2bb67c
prerequisite-patch-id: 215159125e8d5d0b582c855e41e172642968d9dc
prerequisite-patch-id: c6563c0197b0be736285f5a82c01f70142a8102d
prerequisite-patch-id: 7b7ab1bf79b7a87b7ba74a7d93fb7f18387378fe
prerequisite-patch-id: 089e0588043b7188c938b3387132155d7dd64e0e
prerequisite-patch-id: 82cc9091bb28eaaa50af8c2e2ace6c824d359790
prerequisite-patch-id: f67d7fcae29f32779aea0d784c940c049c338f69
prerequisite-patch-id: 91de523b3e1381472e18b7e4f3bb00e443ad28a1
prerequisite-patch-id: e5f4c552bc6f08ec18837fa21fd056933a4a19f1
prerequisite-patch-id: 4567b26ae481110a38c86b4c242d1d4e6cb858b7
prerequisite-patch-id: 7ec3ecb6b7862446d7c4b1f9a4c8c700a570eb82
prerequisite-patch-id: c889413f49379e31397fe327d98be4c32cdd69ba
prerequisite-patch-id: ffc95b1356c5998ce9c4fa7548a5ed89a8a8dda7
prerequisite-patch-id: 66d27c4530d26ad9f71455576794eb77903d5e37
prerequisite-patch-id: 6d643ed52e8983566dfb9c16a7a762f30cd9655e
prerequisite-patch-id: d041853e1e971b1e40d4c8d0c13343f4e6b0dc2a
prerequisite-patch-id: 23f173318807e1a3bcc5aaa574378e521e4e753e
prerequisite-patch-id: 5f9dd7df452a227b0d5a460f2b89f4b067560aa5
prerequisite-patch-id: c96de8909ee6862136dae3d32c0cb1961d9d20b7
prerequisite-patch-id: b1779f1e7c9a140d5461d69778846bb0efe39031
prerequisite-patch-id: 6c8ebb5044ef5c86b8a41ffa8546c66bea52820e
prerequisite-patch-id: a815b3b7aee03135d1da64143ef5fa1e6bb6a3fb
prerequisite-patch-id: 254596c9e807fc49710ba7f072dd83d56b28f209
prerequisite-patch-id: b4863c1d3119693be398754536588e63b172f6fd
prerequisite-patch-id: c0796012829a47bd1f3a48badff50c05e56f935b
prerequisite-patch-id: 8526e7e9478bca98a4709c45a7bbf0d6ebb49a6a
prerequisite-patch-id: 93a198e8f4a720620a715de64e5a14122f4d8353
prerequisite-patch-id: b36f12395844957f7da88dc3434ddf0bbeae5729
prerequisite-patch-id: 20fef363cb39c18e7ba2957a0650ba58243dcd29
prerequisite-patch-id: 7a01b8add1b39c359ef47873f8010bcc1c74e6b7
prerequisite-patch-id: 2683ceaed2514c42413159f153018d6a7dbad859
prerequisite-patch-id: 61cce8bd7790f25ff19d29915975597edde6ae2b
prerequisite-patch-id: 318e5492cb46b2e86057dca815e8b45fe0f7cc05
prerequisite-patch-id: 0abb8560d65ad9895dde5ac9c65026ce6126e342
prerequisite-patch-id: 47d858128e1f744414a44ebf5fc61332f422cce9
prerequisite-patch-id: 5492435bfb57f3c9941fe523131b15620a8ac476
prerequisite-patch-id: 692ae12db14fe354250dee2125f0a0bfbec5ae05
prerequisite-patch-id: 39d8a589b1f8de8a16c25159ff6bb52b26c91c81
prerequisite-patch-id: 2cc8950b275d44ae99cd049b9c01d5678590f5bb
prerequisite-patch-id: ad5df7c8d7271b17dfdc8ad0e6285257c0deb5e5
prerequisite-patch-id: 9ac2203347264d4646c840fde268eeb34dd9349c
prerequisite-patch-id: aeff8a8f8b769ecf882a61d9b30cab6b4e67da73
prerequisite-patch-id: 6dfbebc65a1e27cf6924b8fddb1b73ac66a81d5b
prerequisite-patch-id: 27f8e68418230c7c82a84a9fed8ee09314c29727
prerequisite-patch-id: baa5b3ccd75ce4840b2c376dad10e4b7a606e1b9
prerequisite-patch-id: 641503216b2494a9d8d6bf3d18b6a39f768b415e
prerequisite-patch-id: a5c52a73518e0d06fa1973be3995ab30a3b04a53
prerequisite-patch-id: 8fb7f7eaedbdb0083412320e1eee20d36b2109f6
prerequisite-patch-id: 52abc1fe99e88131b0ee846eb339c94264673ec0
prerequisite-patch-id: fa773871a4c297ef80f2aaa5ca58a73848b3f72f
prerequisite-patch-id: 1dd2b06582d04b8b9257c333e10e2386bcf1a4bb
prerequisite-patch-id: a5ecf50542ffa5d4058d022ce52c56a42f9efad9
prerequisite-patch-id: 5e9e01eea417ec8648b2aa18b848542bebbdac20
prerequisite-patch-id: af66f960772338a543274819c8a40333695daa0b
prerequisite-patch-id: f39348add798bdd906a0c03ddbd77d4c468f3e8d
prerequisite-patch-id: 2451b3b48be4761b28e9f12835de2e0097a4bbe8
prerequisite-patch-id: 513de65c4bb152fab32ef5c0dc3602f0757428c7
prerequisite-patch-id: fa42813424ad37c1de07a6139f992959344f9b2b
prerequisite-patch-id: 47f7362948ae8809699cbc2756fdade87512172d
prerequisite-patch-id: 5d90e6a6f587c942ad5c5dc12e85582cf0d9de31
prerequisite-patch-id: cb646c7e1bbe460e7dd000005185d3ab281c761b
prerequisite-patch-id: 24a7c876143fe8904ec54fa0c046ab3831b7a375
prerequisite-patch-id: 54cd5296d3e2f613c3a4d2d61a3e447451cd451b
prerequisite-patch-id: 2c5719be59c5a5d90c33d2a34ddc43ef5d2163e1
prerequisite-patch-id: 48a5fbc414a9a8f79247e903697d4a8add24c9e8
prerequisite-patch-id: 078a1f2c3a35d87464292a53bd8027548d921443
prerequisite-patch-id: 754c2cda8ceb6fcf2b6d3e72a7fdf1fb32128a58
prerequisite-patch-id: d15c036e28041811ef738e589a2dbc0d45d92d30
prerequisite-patch-id: ee3927375b18725b4917b1c921939f7f6b7dfbcc
prerequisite-patch-id: f63bc0c307a2a63fafb0678b95695122728ee570
prerequisite-patch-id: 7cb861774241e55766b64fadcb07bc6971701d52
prerequisite-patch-id: e2ae2d9b8ce738850cdc49b6111fdb4d7a190929
prerequisite-patch-id: 50599137f271529052723d1c2f57f4a42ca12473
prerequisite-patch-id: 16961bd1bd57b9b4f01f70f607ea222dd54de473
prerequisite-patch-id: 6dd8e39e122dd543d95b8abba507f22a577b4349
prerequisite-patch-id: 0408cd4f65e6f29d9aa3c1599e6f59446e66cb70
prerequisite-patch-id: 61fe44727476f72351d5e87200a6477ac8ae1be6
prerequisite-patch-id: 4f4827537e785a4a4e3fe9f4aee7df969458758d
prerequisite-patch-id: 283d2671ef0970ec1565d31f36cc6bffbca2083c
prerequisite-patch-id: f7c9255ed462c0dc85101a068c434fee3c34fb94
prerequisite-patch-id: 043ec716956c51443faca9326b04bc0e7c9b0c15
prerequisite-patch-id: 54ba67f264ef4fa96e763f8f7d7582b71a486013
prerequisite-patch-id: 486fc8bd836babc25c40219bac95a3235e1a622f
prerequisite-patch-id: 20098d0cb6f6ba202232e5d624053bba5a9a1923
prerequisite-patch-id: 0a3517e116d3cb39798e232a79ecc1d5a978e46f
prerequisite-patch-id: 91d9d69b183c7a66bdd3684d6bc667686ecf789c
prerequisite-patch-id: 28ced1349f4c5bc3488c125dd347c78ce0e8e70e
prerequisite-patch-id: bb176edf1c15a5ec3ae2295a61d26fabf5ffdcb4
prerequisite-patch-id: 64e0000514390b2aa1301c2418b9d582fed4365a
prerequisite-patch-id: 5561e9e0fff4747755d2d549e1011145b563d32b
prerequisite-patch-id: c4cdbefcd3aa5a6f21cd9cfd24baf6f1391bb1bc
prerequisite-patch-id: 3b2b8dea8f94bcc54db4d03ab6573def8753b6f5
prerequisite-patch-id: f241b1a21e47fef40f6b993793f2e8ed73ad1ffa
prerequisite-patch-id: be0c5f7a5fae0831203806d2f0167d01e541bbab
prerequisite-patch-id: 7035fa4ac5e4aabc4cedc60a93804842bf1cf0d4
prerequisite-patch-id: bf1bcbf65bf29dc4d59bfbfc4ddb2a135cf3d12c
prerequisite-patch-id: e9a6bcec44adfdd64da278618988394e1253b656
prerequisite-patch-id: 237e77437a7d395ad21eff06d563e2cd80c8f0e6
prerequisite-patch-id: 472a0c96691e2757f0a330f4a01f92fd244aa0bf
prerequisite-patch-id: 45cd246250018cc0f0d716d3a337dd005715180d
prerequisite-patch-id: fd01d57daae7adb022e8214db5f2ea14ff28b3a1
prerequisite-patch-id: c209cabc697c1e4219fc4932562c8a028cf1dc63
prerequisite-patch-id: ec72151474ec08191cb98c8cfd188511b50ce2ae
prerequisite-patch-id: b795e49fd30c1a55552cc1346ca6510f1d0a2d03
prerequisite-patch-id: d01f9aeb94786c7d8e64420d7d23b1cbf6d5987e
prerequisite-patch-id: bca446ad6423c2b9da744e8bf55d38b7c9c9acd6
prerequisite-patch-id: a1a69e97c973e5bf4e636b47521bb92d74024095
prerequisite-patch-id: 8d6039a8286a6b69d47d61b62e4856e498de8e5d
prerequisite-patch-id: a3e00608edf9f1621a916f5a2b5100cc441f00a7
prerequisite-patch-id: 64e778aa1e6c84801f44eace5950905635ee2dfb
prerequisite-patch-id: 9640d5ab5846887bdfb9951ad8ad3cd6e5e9e2cc
prerequisite-patch-id: 1cd3fa064d3748ebffcefd336673e6ba0fd89376
prerequisite-patch-id: 75a2672e5aa72be701d59cb64157df16031d17cf
prerequisite-patch-id: 1a4545cffe6ba26a91330294ad9b04b488f7c6d2
prerequisite-patch-id: 1c18c3bcfd41d5aa4b0338e68bbb577f3d0a40be
prerequisite-patch-id: c90f9cb5b70a58987e5cba5be920c4ea1dad73d9
prerequisite-patch-id: 6fcec84bb64b4dacece8fd478de1bfc29d9a9d01
prerequisite-patch-id: 157146b90ddba007f29aac3328e63dfd6c898f6c
prerequisite-patch-id: b44a1bfbad90b442c8e0cf2d8470ff20edceb299
prerequisite-patch-id: 84d73805c6b06f289883fba2b74f467e859f13fe
prerequisite-patch-id: 7fe3ebae038d7fffea9fb920e19a133efc44c871
prerequisite-patch-id: 64e5bf13fba0f93b27a59bd0dfb876b52cfa4d83
prerequisite-patch-id: 184a9a7b3bf89b5d812a040b9dd5ee6fafdc28e5
prerequisite-patch-id: 603d04768deb8c44b2f9c6e26f61403a131f7c1f
prerequisite-patch-id: 28017dfc65ecf78b80a5e99c0cf1dc3493a11024
prerequisite-patch-id: b0c0ba83cf8cae6fcf8249b5fec0bd694d299516
prerequisite-patch-id: f34d480de86fd35d46460aafcecbacdb76984796
prerequisite-patch-id: 4ab16637d4b206ce4b243e8b8f641cc768a0bc96
prerequisite-patch-id: 904c5ff8275b58a896df19b9f1046795267240a4
prerequisite-patch-id: 9b8309dfdbaac875a06e85cce52f18e44cc545b1
prerequisite-patch-id: 2f42648521002583eae78b7c9a2b72aa7f3dcbbb
prerequisite-patch-id: 0f9ed99de84199fc575fb02f9344363dacdb6516
prerequisite-patch-id: 02bda9e8a464978cea853a55643e2b0e52853b07
prerequisite-patch-id: d876986e665b0bb591a55810c4df7017fb771846
prerequisite-patch-id: 460719ab91bdac5697015a421cf69a36e29970af
prerequisite-patch-id: 653b5ed584b68dd346bc15391bb46d2622f17e6f
prerequisite-patch-id: bcc8b57f63b159c1be2eeb9385e7f8c4288d661a
prerequisite-patch-id: 0ac4a07906988f1d796e532cd3b1b3ce07ffb568
prerequisite-patch-id: 28e886d6d9c0ca337cfff92e840441e7ba00a4b6
prerequisite-patch-id: 1ae481193b53ce79524b960427c532a799b01049
prerequisite-patch-id: 9b67d597c50010e390a85c19327b8ece6cf6f4cc
prerequisite-patch-id: e4c28dba45c6dd0adc48fb6018ac73c5f0c6bfb9
prerequisite-patch-id: 76f0e451e23c826b481f2927f308b4738ba2faf4
prerequisite-patch-id: 0e03991e9e9ec288d8b5528af65ad37906fe55f3
prerequisite-patch-id: 570c817958d71807afd20a9439d565423135783b
prerequisite-patch-id: d08de79087a623a0990a289169fb0ca5a476a7fb
prerequisite-patch-id: f44cd13de2bc5ed351f233b943d9acc45c34b7a4
prerequisite-patch-id: 9efed0e99f1f6091e85fdf4bc2ea2750d25fa47c
prerequisite-patch-id: bd25759140a0142073cbafe064964af0aa75c09b
prerequisite-patch-id: 680043db35a6522d3a09beb8b7961c25252fac40
prerequisite-patch-id: 0dcfc9771dbcfd5920d24d51c434d5c740a235ab
prerequisite-patch-id: 58a43927a62b0180b9fc22910051607d3ef7eee8
prerequisite-patch-id: f49f5a2a55969c16032220ade340e0a9d930ab8c
prerequisite-patch-id: d1cfe95ff14c0048f331b581885aa870cc5279d4
prerequisite-patch-id: e3c27182060dbe3ee93f563fc650aaa771c38264
prerequisite-patch-id: 4766a72798e0751b5ca001fa0ea16decb6f7891b
prerequisite-patch-id: e9855852080df6a148ea3ac3aa8ff574e0b48af9
prerequisite-patch-id: 4160c29c86c7ac79e647a06444dad7d6cb0f7b2d
prerequisite-patch-id: 80ae3dfb7071808f24ceeea875c78c3be2dd6bd0
prerequisite-patch-id: b14942aabd092428b11dd1172e55fd715d85d5cf
prerequisite-patch-id: ef516f09c7c0b80e5d3ebf433b69f266fb8ac03e
prerequisite-patch-id: 833e577c5ce3bfc27fe8a2b8a6940bee06966da0
prerequisite-patch-id: 084454581b62788cb3d847f4bee52b0f8698ee7f
prerequisite-patch-id: cb546df51d571603da9504734ff49dd0dbc2676c
prerequisite-patch-id: 553e4c5826e0b2ff4b36aa4e29b3d397837c59cf
prerequisite-patch-id: 9739c6e0a489bce2695547db11ba7169f68d9a50
prerequisite-patch-id: 7014aa1c25f97908dd82e60119ea36d9eda78f02
prerequisite-patch-id: 3e5eeabe4f3f40d4232e1aaa26006844fc139c25
prerequisite-patch-id: 67d13fd5ee0ad16d0ce594daf1b98a917ec83374
prerequisite-patch-id: 2c68c547c522d508c90adbcf723ed547705b34dd
prerequisite-patch-id: 46d231301c479b278755d04c377b6c282687d6fd
prerequisite-patch-id: c32802d6b94dc3de459dd07d7b222b7fa9cc0e06
prerequisite-patch-id: f6e25d3281a669766bdd802317b63fd9f34ec8cb
prerequisite-patch-id: 0d51ee9e00ec67c7d2c239b1cd18e750bbd27452
prerequisite-patch-id: 61aaaaca3b8a16c223a88bc4d1bb30b8f8a4504e
prerequisite-patch-id: 1f0583b62928906079c75ea461195e1354ae092c
prerequisite-patch-id: 4c3264c36e34c62076c0a0623476fac0255d042b
prerequisite-patch-id: abf0d834cb48f061cac3aa3c37d41f626b97339b
prerequisite-patch-id: e15b537afd1b7903e715c114a83c11951f1f231e
prerequisite-patch-id: 20b6ac2032f590f07a3ab82a6c5ab9667d1e9113
prerequisite-patch-id: 67832216a84c560320fd625020d4f5fa5d6ff39c
prerequisite-patch-id: ba3a57567f0086a6bdf90e7f07b97d98067253c7
prerequisite-patch-id: fa2f4cc25b0455bb20cb9fce6ccb32c18059cebb
prerequisite-patch-id: 7688e257f73660c6872d2833f53632c79e793c03
prerequisite-patch-id: af525532f2a9d2ba8e954d49508aa14d5e646ea0
prerequisite-patch-id: 65aa30404ee04d5aff85852b3bef800ea254f59b
prerequisite-patch-id: 6296c626148dca2f60a6d42c40fcbeb86862da42
prerequisite-patch-id: 1d62afa974f37416ce0c7930890e76cc468a9e2a
prerequisite-patch-id: 122751c540f41ef0b206e92cbf13437e662eee91
prerequisite-patch-id: 78c1812d6e7d20a6686b89335931a6a0c9ce6a1c
prerequisite-patch-id: 2888056d4ec126894e90196185e0a9b38b1c42d5
prerequisite-patch-id: 6259c8ed92317a46f38b8d9a6d881d50cf150ba6
prerequisite-patch-id: df5df4bf3b9c430d4c8f13483d9ba5df4ed39ac8
prerequisite-patch-id: f2b23f1e103e0996bcf8479131ad0fe5e1636d57
prerequisite-patch-id: ac4058dac5f425419ef34e101542d881f9b6dc0e
prerequisite-patch-id: e72e20e0180741911815678973ee4894d169f2d6
prerequisite-patch-id: b4e6a1792b424ac2dedf95ee8390d3294051e601
prerequisite-patch-id: 5a398a4efdb9b25fc67421e269e528f28f203fd6
prerequisite-patch-id: e88f5d96ceb261e1375127d7a4886658ecefbb7d
prerequisite-patch-id: c2580b68df2f4d0275b2f3d41d00910984298c2d
prerequisite-patch-id: 0a61e5fd7ca917b9e13862ad9d3f322a8da38ab5
prerequisite-patch-id: cd9cffe8cdda43f3d339d921f03b38307d1c352d
prerequisite-patch-id: 70837c37eb707da564227bde786e26151e1639f2
prerequisite-patch-id: 38ac3dd884fa8ced336cb338a59c138f97e45c3a
prerequisite-patch-id: a944a771dc709ddb231f562ed0d637328d4f9361
prerequisite-patch-id: b3c48f5d22d1fb4c649cc067f9c8d3c2641fef4d
prerequisite-patch-id: 582a3d0fa51879377932dbffb49d3503b049e069
prerequisite-patch-id: f53645f17133a844d694fb7a29d40d49a3abc758
prerequisite-patch-id: 0d593512b74b52a2916719397e20dd82f1b78969
prerequisite-patch-id: d44b058e266b9ad78f3648b11770e139d410d51d
prerequisite-patch-id: 72b7b23e39fd0900ffb34096cbd1f2e931749df0
prerequisite-patch-id: baa086a8b8a533c56f1385f55ede7f8532ee959a
prerequisite-patch-id: 73e0a5807ba90d541dd288be2947761ee05a5a2d
prerequisite-patch-id: 32aec68c099e258d049d404f75be861672aa5d78
prerequisite-patch-id: 0424a264cd2a75c37efae95571ceec634df8a1d5
prerequisite-patch-id: 12a2a93a49479ea9748ab10edca77e827d4f95d4
prerequisite-patch-id: 78c84c9bf09d3eb42a680c2f3275cd64f2107301
prerequisite-patch-id: eee156bebde6c00e21a58b55aa8d0508e29a1316
prerequisite-patch-id: e42c1c0d3a14191950cb724c586d2002a7993bb0
prerequisite-patch-id: ae265bdb5fab06db37d67786e35e0f6b2687957c
prerequisite-patch-id: f51cae30f4e6532516eecc40b1c5be8ea3bb6991
prerequisite-patch-id: 7289f1c76239739c8de610ad7ef1ec39bc30b289
prerequisite-patch-id: 41f60ffdbbd28b76606698d34e431fac4b432514
prerequisite-patch-id: b1efadb5d3857299c57d2a01777716357431750b
prerequisite-patch-id: 5d1ed06283b191f9c00f3283097f00ceb773c55b
prerequisite-patch-id: 23991248caea4e63e096c93efaf7de0f87ad9dee
prerequisite-patch-id: 908dbcbc07690e87d8153da8e6e4771e14aa2d51
prerequisite-patch-id: a7b1061cb86f7545f7895044f3015c334f29495d
prerequisite-patch-id: 65e3952e01c640730926836b6f8db0445c90b880
prerequisite-patch-id: a0ddcb52732e8acd7a5d241c1a778ae2ad237cb3
prerequisite-patch-id: b5a98faa73b0c67d2d4f0a27dd69d0b762655cb9
prerequisite-patch-id: 4f4ef99972a2798c5686250fb18efb698cef92dd
prerequisite-patch-id: f1f2a3de67b7637f31d5bf3b6e922af64b746589
prerequisite-patch-id: 15e8d30efb7c54e2ce9f0604922b96d2a804fc37
prerequisite-patch-id: ff29af1c3eee2b9c738976896ae47744aac08fea
prerequisite-patch-id: 64d4473175f026a7b050fb94cdacc3e69da3745b
prerequisite-patch-id: ee98d845c879769dc3d2297c182aba569a53c7ca
prerequisite-patch-id: 65b87159b9b215914c5e75a55bd2816bd4c1955f
prerequisite-patch-id: a7e7f51f8f02dd70bebdc2836dbfead17bf530da
prerequisite-patch-id: 3fcbe80bc0efeb31e5066dc708938c23122bc289
prerequisite-patch-id: e43fab5b7a254985271fe77de6bf9fbaf4f8fd7c
prerequisite-patch-id: 82b9cd3669fb20ce154fd65acf3aec437cfdceed
prerequisite-patch-id: be960dad31fd0e238d59bbe5e94a8bbc556efdf9
prerequisite-patch-id: 5fc8fee0658ab67e837b9ce9b59a4587faef8d29
prerequisite-patch-id: 3c46714d0ad9b3f3151e51d2c4899d47d7be1c0a
prerequisite-patch-id: a6a2f587ed6a98296b52f8aeb789c25e5559cca0
prerequisite-patch-id: e6b63bc6fde6316a054f682094b80247ef10d17a
prerequisite-patch-id: 419863ba23cedc5a32f4b67393bf77ba4ef04d3d
prerequisite-patch-id: c5d34666368f45c8bb559810f29d1d8eb64d58f3
prerequisite-patch-id: 1c4bacbf2bbb88998965f7090c48f8c942be6540
prerequisite-patch-id: f6a4d4d9b273526b12f31c5125d55400d17626be
prerequisite-patch-id: 8a020ed6a430204c8a93dfe60e9ccf7830983871
prerequisite-patch-id: ab3f1c2f69624c69d25ce08de8fc58410b0ef713
prerequisite-patch-id: 13e83f3119f12c51bf62dbbad20c0756f3e31190
prerequisite-patch-id: fc4c55538ab9bddcf0170d807a5728f5b91aebf6
prerequisite-patch-id: bc09476500fdafce3fe31774848f61ef9f794b80
prerequisite-patch-id: e20fa335621314733a718572bc4bac4bed689df6
prerequisite-patch-id: f5e9cc57ef61028736876f6ebe2f84fb5929e709
prerequisite-patch-id: ac057e22c107d812008542b01a670ded6f767f98
prerequisite-patch-id: 87bc14e99de6e6e02af682f10e80e55708b378c3
prerequisite-patch-id: feee387d0b7b56ed234867016a2156f336d5cb78
prerequisite-patch-id: e82f6ad4003f47f521ded6175e8325da01285542
prerequisite-patch-id: 66fb8f6c1c4eab8af60b7d431c297971204b8928
prerequisite-patch-id: b0245728da44f153f66e412fedd3cfce3242d313
prerequisite-patch-id: d61bfcc6c92a59eba4a917a528eb759ea570ea55
prerequisite-patch-id: ae7eb920e521f6f910de1134afc394ddfd4cc469
prerequisite-patch-id: 0aeb63285072d0ec615647133145da2d45a01ce7
prerequisite-patch-id: b57c750c482afc0f1683b15c545f16510928d68e
prerequisite-patch-id: f4da09149ea49ffb6927b225633507b3518f5e82
prerequisite-patch-id: 56387f09032c3ba253117ac44d83265669a58320
prerequisite-patch-id: 0465924bbb6a6fc2093dc11f996c5c3192252b0b
prerequisite-patch-id: 117eb526127d01a799084ea2c24fc093eb3bc9e4
prerequisite-patch-id: 6bbde4c54c42752bc4bfe6f6a1b84bdf23a8a530
prerequisite-patch-id: 83e1ea8356394782b0b02082e592d2865687aeeb
prerequisite-patch-id: 39fa3fd8f04dc7b7837e592211fd0d2afbd74195
prerequisite-patch-id: aeb37fe7b961cdca885915db437e187dc9cca2f6
prerequisite-patch-id: d52de9e286bb02e79bfbf7e52a54f79ff697add8
prerequisite-patch-id: e58d45a6d4c23078109909e2d48ff31cf39960ee
prerequisite-patch-id: e86d18f05f6fd764c31cdfd7ea0d02dd69c7c85d
prerequisite-patch-id: 9914e702fb3bb76bcfb3410e283079614c72796e
prerequisite-patch-id: 163eb2b8353b871f4d21976d147c1f012431c803
prerequisite-patch-id: 272b1c218d0e564b69a1ad231a3672c05dcd1217
prerequisite-patch-id: d41b195905456d51ec65eaca9551fc79e5c93e3c
prerequisite-patch-id: 24f47b4ee4f773c3b0ed9399f23ec11760bc00b8
prerequisite-patch-id: 5f526576bdb9ccc8ebf7ba500e4bf45b814fe70d
prerequisite-patch-id: f8a0bb6a217d14bf5e482708d60551bddd87f07e
prerequisite-patch-id: 444f91751b0ae3c805191abe11a6b6741ee7dc9c
prerequisite-patch-id: d509943df5d6be1f3bfeb5e416e18e34a6d58407
prerequisite-patch-id: f2ca1061ce9fef7412e45092bb72216c57755337
prerequisite-patch-id: 3a705dcadb86e2e684116ecd75c0f2fceeade484
prerequisite-patch-id: 457fa7914fc414a58bd1e75cc2ff7f974a1b34a0
prerequisite-patch-id: c8aff0970ca3a8dafcd7f5ff019f3012bb47475a
prerequisite-patch-id: e3222f79d11bd3535b49d5db209d385da4e598d2
prerequisite-patch-id: 4d99c5e5337be456c4c7fc6e850c4cd4eb3d3adc
prerequisite-patch-id: 27a9601ef0ca72173ca67d642d2a18d26119fd7f
prerequisite-patch-id: c73163d0ae02994f368522362af56e00ce6fbb64
prerequisite-patch-id: 890aaf9a33336302acbeabed40a41144ffc7d294
prerequisite-patch-id: 9d9cec780c90d5c183b0e1da7195c0ab72eadd19
prerequisite-patch-id: 0c2a1a147fa4c1f290d91e9aa817638515c50d4f
prerequisite-patch-id: 0ab296aa25bee524a5a350dc4ec2b1e8ac4f8e5c
prerequisite-patch-id: ddc6ad0cd1069aab670c6edbfb361b066d23486e
prerequisite-patch-id: 8161883ce47494d5a10b319fdb4f545460a56247
prerequisite-patch-id: 077d3f88d8b87aa994f48c524a002b1c55e30a57
prerequisite-patch-id: 2cd223e8c24e4669522d575890a338a664915579
prerequisite-patch-id: f4bf837eb707f76b78376bb65cac258705321628
prerequisite-patch-id: ae2872c16480c6f7c01869bff2d37e2482daba71
prerequisite-patch-id: f27a10f60939cf1ea254981f06746a4bcdf6d37e
prerequisite-patch-id: 6f3c1958e2566f8d5e1e7d96e83d7eb2b0d7155e
prerequisite-patch-id: 7714aea90a2cca66f7b0073e4f5f7b10c947b228
prerequisite-patch-id: ab4e23fabda5d6f816cdb19701f6357f180789a5
prerequisite-patch-id: bf85b322b8d873d9620ff2fff9d3594f5e76760d
prerequisite-patch-id: d715bec9c13e5ed96527da78371f868ee4c68152
prerequisite-patch-id: b2e2964815ce60582f98600937a736c489cff185
prerequisite-patch-id: b456f7dac20fee194fb65401662b7b8134b1ddab
prerequisite-patch-id: 560189e4310029c777ac08f9998d3b13be97ebe1
prerequisite-patch-id: 93158ca225bb94a4dd622303c485808a9f54fe96
prerequisite-patch-id: a344bb37480f8f85a273f987d37c7425e40b0775
prerequisite-patch-id: de26772d3ffc4ecacf8637a51c55c7d0ce3efa10
prerequisite-patch-id: 9c169d6195bad4bacd6de852525ef7212534946f
prerequisite-patch-id: eca39a1fcc10338f94331ca50fac72edfafbcf7b
prerequisite-patch-id: 19a82ecc5e284588f3d3564c6dde1672a3e823cd
prerequisite-patch-id: d2d47e52a6481eebda344e25304c653146a72253
prerequisite-patch-id: 5c3c71aa9b5ebe2b3f9921da1ab6b289ce2c077c
prerequisite-patch-id: 956de3aea9e48fa66cd99f4f8d305ae2b55fe78e
prerequisite-patch-id: f66a31af859f77d575f07fa641f42b4015d21dda
prerequisite-patch-id: d9223729effc35206853ef339a776348942f980b
prerequisite-patch-id: eda421f42878fc4ea617e024d0fd711ed6f91cec
prerequisite-patch-id: 81a13e58aa38f089dc1451a75e1d53a22d3279bd
prerequisite-patch-id: 8744e733bab56deba0516da02d2387901d3d44cc
prerequisite-patch-id: b68e6c0f2d1fa91e9c440e7724cfae33200a7ee0
prerequisite-patch-id: c004e499edac0f397a20528c6ee99f597523c004
prerequisite-patch-id: ee2cdff010973a82db925edc167ea243bf30d2fa
prerequisite-patch-id: f466cbd99c8ea3a48bb625524f3de61311540b55
prerequisite-patch-id: c18ae638f10e710e2a0a6b99378c7c7dd6a02b67
prerequisite-patch-id: 05507d9fedb8616b7be8ff52798590658338421a
prerequisite-patch-id: 4047c277a29f7f257b86c1a7ab74c4a84da22ad6
prerequisite-patch-id: 2a269c06fedf1067352727a4ab8b7ff353fa0401
prerequisite-patch-id: 888380e28bd10836e7585a7123a8d429b1dbc575
prerequisite-patch-id: 0205db9174e7e1288b2112fe45718ef5898c249b
prerequisite-patch-id: 27601e161a61c2fc009d64fafeb90c26f3e87e16
prerequisite-patch-id: 2052872bb614cd6b65dca1c8402aebcaedf99d76
prerequisite-patch-id: 5c87bdcbc3074d6f830bd7a1e6cacd03ddaf348b
prerequisite-patch-id: 1db604c379428fd8c0b550f5ba7441e81b54ad3e
prerequisite-patch-id: d575a2dc519c80942e5986e31792e8a9b13d2057
prerequisite-patch-id: fa789c320a1623358794b2f847c4b2e4bd99c1c5
prerequisite-patch-id: 64c59eb86620fc7c2916193754c8451500917b52
prerequisite-patch-id: 5ecff115c0c3c190ab7baaf8bdf05a26c684be91
prerequisite-patch-id: cb32c6216bd0c0505ecb328aa93940a68edc2be1
prerequisite-patch-id: 92d11a49dddab2f190b70c819a5aea964ad2f492
prerequisite-patch-id: 923d04a4105dc262676350da8c17da530a3f5fa8
prerequisite-patch-id: dfded5bce9a5939e79297948afc9715691802b53
prerequisite-patch-id: 78ea74fd5733a6dc55d19939475012bfdaf92b49
prerequisite-patch-id: 4f07fd3c9bc43e34f2aaa0fccde89b62de08efe1
prerequisite-patch-id: 5c18d940d4628ebf938f805a8128ef7f4ca20539
prerequisite-patch-id: 94dad93545abad1496e7f2fe622bd1104102adcb
prerequisite-patch-id: 8dce13063193e0beebe540804cfec77d367fbc73
prerequisite-patch-id: c02d1637232a9806e4f4511c457af2af9151cc63
prerequisite-patch-id: d48cb7b5ad3d27c5fec502f0fee1196cd6e14941
prerequisite-patch-id: c48ceac3deb0969381b4cf925fb9a0662bda6165
prerequisite-patch-id: a1613cbfeab21273512f60c8c09aecfdab927ce3
prerequisite-patch-id: 49fdad3ff89f2a3a1cc693482d982b5556bfa789
prerequisite-patch-id: 955024218f3b50f852ed45ec8f1bc3603e28a282
prerequisite-patch-id: 2a72169b93eeaf55d608736c9ab3c97a867ec6a3
prerequisite-patch-id: 9af916e2c5a84e3f29a639d8b46d6b054ec0b0ed
prerequisite-patch-id: 852aebb867c0b5cb0c2b48f5c65329ed03d1e4e6
prerequisite-patch-id: 7aa00def5802397206875c6d13a3c1e44f3a3e66
prerequisite-patch-id: 7d5e576a8698670ee0735d3e806f1df528af6227
prerequisite-patch-id: 870b7aa9796e8468326da3a5ae145a15e8b4a935
prerequisite-patch-id: 1c47e3c3c5f497f82317fb7ce4b74224a112b281
prerequisite-patch-id: eae766b891dc5bf296cb3807fae33c9ee047ba12
prerequisite-patch-id: a0786381e9e8f4386c0819c9a6ad3403c7e600eb
prerequisite-patch-id: c26b927b208ead3f118559f95bfa24e581778164
prerequisite-patch-id: 7a07bf2b4ef567c1dd452c9469cfcc1c5ae74a01
prerequisite-patch-id: 58be146f073bd80e5b47540dbae83a3d4345c246
prerequisite-patch-id: 8ae03f8b68675dfe3ea0fdda78eace2481d13dea
prerequisite-patch-id: 95e7d5c924512db8e0439929e7dc165ac9be9018
prerequisite-patch-id: 44c52ec3ea648c4edcb9956a97c753699b3d4457
prerequisite-patch-id: cddf5aa2d54a8a60c01cc11e7521241abefa8d74
prerequisite-patch-id: 3c262cc10eb07a9dbdb88d305029b93c148e1209
prerequisite-patch-id: a65479ade63fc119d78b78772ed163bcea8d50c7
prerequisite-patch-id: 39852dc19c46d41c1afeac11133ffaa642ec9202
prerequisite-patch-id: ca3262006c3d51854f68d4b75d607e313c80c3f3
prerequisite-patch-id: bbfcf43fdd26c320a9449f3d48f45ce67dbe9aa8
prerequisite-patch-id: 94b43b6d94b1bea58f4fe6250dbff1efa2351247
prerequisite-patch-id: d3ea90d4194e70a2d3ce9c1a78a2e0b809a41dce
prerequisite-patch-id: 0f5c240401fc1231dc202e911739d649cb954c18
prerequisite-patch-id: a5c8d9ac91675b514c0b3c8b0eefd3a9237ad9e7
prerequisite-patch-id: 0d834798e64d8deeaee5727759b4b58896f3576f
prerequisite-patch-id: d5b07fa142ab699cb39706419379ca67d8aab978
prerequisite-patch-id: 9c76b468271240e7a0da257ddc9e507ceac81af7
prerequisite-patch-id: 6527f6abbcc2c9bc706eff1fabb2950a457ec239
prerequisite-patch-id: d2c73d6c694438b7511b49f0df85831d0e0d7bf7
prerequisite-patch-id: 630a08a3adfceb268c46c67f25345e0a80d90c96
prerequisite-patch-id: c51a122a158745d9c4871f814cb3937481956add
prerequisite-patch-id: 39b61d1b49e7929560dd5052101099ad1dd095d5
prerequisite-patch-id: 46f6378780d0810f8d31ee86e1bf4603dc8e1d80
prerequisite-patch-id: b4999ce5e9c7c4814289596f0b6af293b1803f98
prerequisite-patch-id: ee0be76f833ad5db9d7d1e293ff2defeffcc485c
prerequisite-patch-id: d0e60fa4d488bb464e9f8951630de45bcf87b634
prerequisite-patch-id: 55b7352f9a386a3fa5e6abf3dbee9784d3de6943
prerequisite-patch-id: c75bab6e55c771c9bef48eabe101338a19bb17e0
prerequisite-patch-id: a1483f8d0e06987819582c69b4c648e2a591b0ca
prerequisite-patch-id: 881d2c330d0158e78a6b2c50ce20291c0b5ef81f
prerequisite-patch-id: f420a46d36e2a9301875fd7a0667473ff83fe830
prerequisite-patch-id: e5bc5f0eeec0342495d740f8b0e38404f1d410ae
prerequisite-patch-id: 2681d63b824ac20906e90f1b411062617781fde2
prerequisite-patch-id: 150ad64e9e5e61bf95f49ebbf0160d6171853d05
prerequisite-patch-id: 8ba07667a735f3c0e396e8584a40e519584488ee
prerequisite-patch-id: b5578db248cacdb23013378fe19c2ebfdadbb2ac
prerequisite-patch-id: 5faaf73ab4b2f4a6f461264ecf27f61ca6d7638b
prerequisite-patch-id: a7355f7ec1f1f10aec66af03a548e2ce9eec6ba8
prerequisite-patch-id: 6e68fdb062db2d42d656d64a6475b9586e5d9a0f
prerequisite-patch-id: c0849b197998748d14fbe2f863d0d5736b0e495a
prerequisite-patch-id: 1dccb562027c53b0344549c94cfda3502a87c3f7
prerequisite-patch-id: 04572cb50567a83a11c1bfdf4c5eaf201e29f354
prerequisite-patch-id: 461a94c12400839bbf73d4191f9f5d673a3848fe
prerequisite-patch-id: 905522469817adf8060420bebf372625996b83ec
prerequisite-patch-id: 0b956eea5da344f919ec068405fd1f078b523b0b
prerequisite-patch-id: 7956de1534c40c834f0d7f7d1f5cb9aba2621722
prerequisite-patch-id: 373e3433c99d029b823d9be481ae97a7a288f436
prerequisite-patch-id: d0f385280473e77690b0bc501f82d5487d3e4c90
prerequisite-patch-id: de5d7bb60ff42a72bfd2e833333e334e81f5bb87
prerequisite-patch-id: 7dfcbbbd2daecd587b0bc01cd73d6789350d0f87
prerequisite-patch-id: c5539c82d437cd615344af7244d29eefe307cbc8
prerequisite-patch-id: 1e5c740f54d449f7f2adfeac5813f18ba55e4cb0
prerequisite-patch-id: 5e1d564216338450b9d4572f9b0250326938a320
prerequisite-patch-id: 64791ca67a235252467ed99c3f6a68509735cd86
prerequisite-patch-id: fdb71bdd3f084ccf8f2c46ab9e4f6773adf6127e
prerequisite-patch-id: f72ebf1fcb6bfd57e75078e90a91cc37e507a7b6
prerequisite-patch-id: 43ae0e4f039d88ce74370141c81e94b06a4a4fed
prerequisite-patch-id: b340844a2a0375893f4b0686f35a9a2a28943397
prerequisite-patch-id: 371653dadb3c905f3c5532adb181acdffa5c72ab
prerequisite-patch-id: 2d2f200a40e93c3c1a8b1b65b9b78cb06564db0a
prerequisite-patch-id: 4becfeff2c19c7743f89c7aa2d765bd8f02bab61
prerequisite-patch-id: 0af649ac28299575572b6630b4da9257cd6e43a9
prerequisite-patch-id: 68ad716ba16481e3a2b4bc3c1757553c27817567
prerequisite-patch-id: e1ac4433937fad8fff614d7f4e07927d0792e014
prerequisite-patch-id: ca194d083303456eaa06198e9f23ef49bfebf562
prerequisite-patch-id: 094f605db4189180099deff36e40d2e3c62b9bf6
prerequisite-patch-id: 8b2e75e46b7aea48f5ca3a35680182eef54b74f1
prerequisite-patch-id: 8f234f224e4fda0c1d0c209ab4185066cb61bf5b
prerequisite-patch-id: c56cca15d4e944da437c2ddd2c42269e0b11fdda
prerequisite-patch-id: 71aeb820a7f19fd9d8df9f480395530e6daf038b
prerequisite-patch-id: 81202c3faec42e89333bb07f20fc3a7ec878386a
prerequisite-patch-id: 54b31357059679fad326abd678b3ffbb2b595d9e
prerequisite-patch-id: d442aacd8a008eca88771818510a288aa6a85a04
prerequisite-patch-id: 96e30e6552bc38bdc174cc2e65e0f360e76c2e5f
prerequisite-patch-id: 406fbf843b77d1ecd370c3c2c63842af670ac217
prerequisite-patch-id: db2221a321839b7ab49a5adf447a5f7fffbf17af
prerequisite-patch-id: 61fe4da153f2997b0bbed5fd9023b74c1b9827db
prerequisite-patch-id: c759ee2e43b3e7a4540cce7c08c15a0d2afa8912
prerequisite-patch-id: d82e7123363da9dbab89c35a1f780135d1841c9f
prerequisite-patch-id: 6a19814ca613d4857bcfdb138fe34c088efbd98b
prerequisite-patch-id: b7b374b18674e20f07346c23ee556e89e5dd559f
prerequisite-patch-id: 2dd12b14f19d7719f57a7637824a2d962bafa77e
prerequisite-patch-id: 50b9b010c04cb3362ee8de7c7d57e6b9bd77bdc2
prerequisite-patch-id: 140f7dee354d42635dbbf3360a6eac8efccf6a9d
prerequisite-patch-id: 24eaa90f7e594ec31db122374c7c2175406276f5
prerequisite-patch-id: 16411f8e8f98b10737f41299eeef32f2620288f2
prerequisite-patch-id: 81b63bd83d5ae5bf72a7bc5cf3cc327f08878236
prerequisite-patch-id: 40f989fb547c10bb87fff91eaf85fe116cdf465f
prerequisite-patch-id: ebfa3fee6d293554cbc848571a6b44ac0f1fe913
prerequisite-patch-id: 1449c08a8d6944ed9aa4520f0be40596fc0ae68d
prerequisite-patch-id: 254cab5630a0b43aad02fc38708e6b0f1fc20602
prerequisite-patch-id: e68da810dc13fff76e7de54328f26267e5413979
prerequisite-patch-id: 5e7a713e9b1bb492ebe6a21d134b518252975889
prerequisite-patch-id: f2a5714b42ab594f8c6bf2145d951a36a3537129
prerequisite-patch-id: 0fdfc38fbdf7cbf6702337ab46879ccd8357b344
prerequisite-patch-id: e6293401b80225c3ffd007adbe11f64ccacb279e
prerequisite-patch-id: 2ff92d26b81a983c6648938485660f52d29038eb
prerequisite-patch-id: 5289e64e552f0bd30365e1808c164c0c49366b22
prerequisite-patch-id: 875e5d31ae9bb40196b39e200c0c30930a88d205
prerequisite-patch-id: 883048251cf1173cbc61766c39c2c51ae126998d
prerequisite-patch-id: 183f68113dc8b05131befe65590e3e818698e915
prerequisite-patch-id: 68c358d1016b1225edf03dcffb720f4d0e10b3b2
prerequisite-patch-id: 3233e01273270c6f8fb4142232040ffb74bf0b56
prerequisite-patch-id: 2cef89f453481c31839e5e38ac44a0f50826c456
prerequisite-patch-id: 79a84c77823c7d6a93e48bcd3ced9380a0e3e8bd
prerequisite-patch-id: ce64414ca7f3c24bc36c1d8c597704c70f286a4b
prerequisite-patch-id: 77b9ad73f64b3b04fa35f7f53eef68a9ea70cf90
prerequisite-patch-id: 491be4c55303f3780aa564963bab5d079e92b7f3
prerequisite-patch-id: 0954d6a4980eaf419db02ded8e87ff5f7fa39cdb
prerequisite-patch-id: 9d6d66c8b73cafa7ca311103c55201ffcf5a4c9b
prerequisite-patch-id: 003401ec234a6bcfcf7c119431fc0f42ad0de6e6
prerequisite-patch-id: 392b09f3615af798d689b73cb215c982f73d442b
prerequisite-patch-id: 4536a4a671bf0dc9e6387b6f1a93df6bfdd99e15
prerequisite-patch-id: 7fb6dc1709465ca3669808874919a397c967904f
prerequisite-patch-id: 31215bf334fd23187ec8d6379e12abddaeac0f1f
prerequisite-patch-id: 8da1c9c3fc318410b70cb5c7687c14a180dbf634
prerequisite-patch-id: 588decf268080140d2740556ee5feff8b14c1e87
prerequisite-patch-id: bf97fd8b894461ca62445978f4f6422c736611b3
prerequisite-patch-id: 5c23abbc83c1a297d19eb039610151fb377ea188
prerequisite-patch-id: a8da8aa7b602b3ff5083f9a785c2b1cd353010bb
prerequisite-patch-id: 1087692e25d4b8d4a7a047aa0647d82136efe190
prerequisite-patch-id: 2f5287b3a8f06de2542e0531d8330103c7a2e2c2
prerequisite-patch-id: f27af6a671e0517797dc8dae7b359c1c95a79011
prerequisite-patch-id: fe5bad7a004b214806b70962dc560dc7bbd582d9
prerequisite-patch-id: ecf494be8ea09455536ba835320c5f0f2829ba61
prerequisite-patch-id: 9b558d5db7f018d8d5db57faef392cb577395bcf
prerequisite-patch-id: 10035bca946ebf35a04e2d49197925558dac4bf7
prerequisite-patch-id: f40ab41e396ea547cc78087e21707af45b990cfa
prerequisite-patch-id: 21d2351a41fc5838fe710939f3d28403e9daa41a
prerequisite-patch-id: b8a10a893a55133434b5e8da150f9249ff403f2c
prerequisite-patch-id: b3f583a162876db2b8336e8a7a198c17416e75fa
prerequisite-patch-id: 82059d318c802436c9716012274d34d09a216156
prerequisite-patch-id: fca85f9b3e7e64fad4b7e9463974bfd359240d32
prerequisite-patch-id: eb59289b473e5379db29839cb8957968af58e695
prerequisite-patch-id: 36b38b7659211f7252496f8cd7a531c604b31de8
prerequisite-patch-id: e716dc1191fe98d88e77c37ea0b619504cd0f328
prerequisite-patch-id: 62e6b9eaacc6a1cc167341c308a2249ca19071b7
prerequisite-patch-id: aa5a7cd7c367095ce3e4947873dee55367bbbeb5
prerequisite-patch-id: 7d9157867e03828797ede09bb5e6e602e9a2d16f
prerequisite-patch-id: e92d4f539c0c329f3b5764d2059ef9f2a5335ea3
prerequisite-patch-id: 5e0df6647eb8369a1dfd3b1646739f955d3d030c
prerequisite-patch-id: 70ef7c565225dd726024efafeedf423b1fbe3981
prerequisite-patch-id: 41b99ed4ade61da9bd97dba6101e5c794b0aebec
prerequisite-patch-id: ddd3d8345850c9f94d4a162ea4bc6b121af63370
prerequisite-patch-id: 1a8b6fae36313b0709282bb310406604046686bc
prerequisite-patch-id: db7b7415f67e8b7b1e18075094695b18cd00b3f0
prerequisite-patch-id: 28ba9485a51888f2761b6f14a7b44e95f4e73c22
prerequisite-patch-id: 01ee96a9670cacd384ba5aa9c991ac319b02bb2e
prerequisite-patch-id: a5e482e8bd37dc4642aa1037545112f889ff410a
prerequisite-patch-id: 8aa5df434142ec3e84e08af26f51459bfa8a83d1
prerequisite-patch-id: 71227939da339e3c95f1cdfd7d6c5634ca01cbff
prerequisite-patch-id: 02d0521cf531cf1b4c5c6460cc30dd65002ae586
prerequisite-patch-id: dc81420be2eca8872aac4b3c09a3981c1988c72b
prerequisite-patch-id: 9dac1fc16796b9d93a4285ca765eb63a0e4cd780
prerequisite-patch-id: 364dfbb94c00b71a93f62febd769c679e60f6145
prerequisite-patch-id: 24594c924643efc149fefd95576f1e9a883bc6f4
prerequisite-patch-id: 264ef6158b57d2cba4fa4b1d058880838b356a83
prerequisite-patch-id: 0758882aa473872d997df380290000744380407d
prerequisite-patch-id: 295ffe473056eaae0663bc33d91e8dcec1f3fa74
prerequisite-patch-id: 8f3993e284e8aae3300351c728ff3fab5e01fefa
prerequisite-patch-id: 727f85b28c5b76e9f4507011733384c15e01a1cd
prerequisite-patch-id: d6be3b881d41c7205febf9d76419039de8b48da4
prerequisite-patch-id: 473cdff3ff8b222d75f02b5fb6bcafed0d1b93fe
prerequisite-patch-id: ae3dd4eac871af039013ea886c20fa7d362641c4
prerequisite-patch-id: b7aca5586c29b97b1d2492f2094c906a0d8f044c
prerequisite-patch-id: d84087fb1595020c72301c76c170674631e95994
prerequisite-patch-id: c2b6fab9cbdec499b5014d4721532de3ad7da453
prerequisite-patch-id: 407a611a69265469ee8847a9aa19c5c0779c496d
prerequisite-patch-id: 3fbb7739f8ac8c8c3997ba590ed3bb5870393be1
prerequisite-patch-id: cf03eb694b771257f3877e34f4176603efd620ca
prerequisite-patch-id: 1561fdff512222d5af8ea60a498a0a93575cf87c
prerequisite-patch-id: 53f528b918aa21055d0fcc9032a4bc677cc0d7ee
prerequisite-patch-id: ee20b4b36cfca3eacbe83cc72b5ddae6ee6865c8
prerequisite-patch-id: dfb14c6056968734ff03c9e2be7c62bc06662d79
prerequisite-patch-id: 85511a3788ee5921cc68ff6fd3dc0b17a7b3784a
prerequisite-patch-id: 6d1afcc87cc8acfa0b7366f1c793a3f71be45be0
prerequisite-patch-id: b107a8a4a1aa8af549f78a25c0d1f735bf0763b2
prerequisite-patch-id: b8578f76e4384eb66fa04447e46a54214de1b6a2
prerequisite-patch-id: 87e1e5b64d7b192acc6973837a652cdd53fd11f4
prerequisite-patch-id: a4f328ac2ee5554b76b98871840d5c2c175afe06
prerequisite-patch-id: d9c982c797e9a004ddf9a53fec14479efc558920
prerequisite-patch-id: d84f835896411ec52bf449aa20907372fb66b626
prerequisite-patch-id: 8f272c120e0f555b88555cab518c4bc99f005940
prerequisite-patch-id: b58092c8cdb23fc133b3eff4f493c5d1bd1c3aa7
prerequisite-patch-id: bf91bfa3ae54668421a6c0a1dba7e0a3304d683a
prerequisite-patch-id: 65b714d482a2e50a14b9b3c3702452d7e1438edb
prerequisite-patch-id: daf1c95929efbef225894c0a1d263d5562bdf477
prerequisite-patch-id: 05579c28af95f4b0ad8fdbf19c11cf5138e00e53
prerequisite-patch-id: ce56cbb9e1c57d35f76c7419f56987efe7e44880
prerequisite-patch-id: 0d6fb50bddddd2ad3b40c4cf046a65692f1ddcfc
prerequisite-patch-id: cb007d294507a29fdc2cc0db76a0eb44b399ec3f
prerequisite-patch-id: fc94aaabf7f1dff700ceca69006f7c6d23caef79
prerequisite-patch-id: b0bb0a16d04c03b3c2a5b1d0154f455b8feee7d0
prerequisite-patch-id: 050fa6978786f9f301adb22b46aebb978cab9412
prerequisite-patch-id: e0636ae46b0eb2df68040e461f2c4030b89462fc
prerequisite-patch-id: 19b7ff8aa6c9f515671c69ee0941aea5151e9a8a
prerequisite-patch-id: b2bff969e1074362fbcae781dc74c55c4ecd533c
prerequisite-patch-id: 200adafa573d4e549fe1f7f338715f49016d5879
prerequisite-patch-id: cae678048f19a01e53cee13b94e1b57e97ce6a80
prerequisite-patch-id: e2ec5d789101f864c0b9419dd86015fa1143a294
prerequisite-patch-id: 11756c143762f2fee89b13e68a870a0c03e57799
prerequisite-patch-id: 13cc70a292a8bfeb2c66f158645807936507d557
prerequisite-patch-id: e81893b77f4c15b6e6383a758c27c51b80f125b6
prerequisite-patch-id: a6096bba2cba65ba2f442946b2b65f0e97f15a2c
prerequisite-patch-id: 6c9f8833e198041ba127b3b272ce7cc120bcd970
prerequisite-patch-id: cd809dee9a5429c4ce9d88b63ff2be7448a60007
prerequisite-patch-id: efee4be8684e0ec566ba09c680e919403fdb6c12
prerequisite-patch-id: 4cf783d95f49a74f9fb0a1c9c4aa2f63e5547f1b
prerequisite-patch-id: 820bdc262d7583a6f63c48c7aa28ed26468cb5a5
prerequisite-patch-id: d7e8a8607d74a1797a7e566d97f956caf5a12c10
prerequisite-patch-id: e2b21360119830b689cff02f58fbd0ece96b8bb0
prerequisite-patch-id: 54fe558a8b26102db4103832c2e183694fdcd19a
prerequisite-patch-id: 63162c3f44db8692545c23d8c92d352fa0a912e7
prerequisite-patch-id: 7941436603dadb8004a2263f5c5616333307d275
prerequisite-patch-id: b012fed37c7f747e7b13f3bf62051deae5b60752
prerequisite-patch-id: 7a0b7ad1e67078007d37641e5a06ac61d076c2bf
prerequisite-patch-id: 78d799b2932e41b6a18e5b3d4309faad6c9cbd81
prerequisite-patch-id: a851eacf0509132233d88dc5ad3584adb82068e2
prerequisite-patch-id: 0df38fd6cb605c11fa2ab5aafbcc9cfe774c0c0b
prerequisite-patch-id: 048f19583aaf1d05664c79a032d6f720f00b40bd
prerequisite-patch-id: d737bf4de3d1a6c3bc326c5c714feb7fb540fd9d
prerequisite-patch-id: f43bba256cd3ec816c19f139bd65112f63b6e7cd
prerequisite-patch-id: 0064f904081430f4f0fbc51fb3cd69a5a49028a2
prerequisite-patch-id: 2ae4118af806c8f93a5440dfd86b42258131b8d4
prerequisite-patch-id: 2a7af1e10c0094332bdb1a1e96d00b3aa1e64e1c
prerequisite-patch-id: 663b32b92d6c08387a14a0c2f83be7865af22feb
prerequisite-patch-id: b84c830c63ce4bc3b18458e1134e130202911992
prerequisite-patch-id: fa21bfb5010a9da5f38db0ef4cd36b1ae4fdcf4e
prerequisite-patch-id: 4a2cf7bfaaf0f027d70445cc4f8be2331c00634e
prerequisite-patch-id: 38a82e3b49024c46f49ed071ad083ad73a1a5004
prerequisite-patch-id: e5517eaebf2a560b96a76099909665a00e38d7c5
prerequisite-patch-id: 23d03b7fd8290672d86383e481db7ff5f868d402
prerequisite-patch-id: 8e120ea84a22991545fbfb42c1abe745ba29ab72
prerequisite-patch-id: e1eaee992e15ebac86c65c00803d831718d08399
prerequisite-patch-id: fc7bd026a8b93fc866731d118df30beace9ff013
prerequisite-patch-id: 20652eeeb13e28d80f623bbf091eca10f85b52f1
prerequisite-patch-id: 5e47c483a0958e6a21f6c65e6b479ceb64692a4f
prerequisite-patch-id: a88046c0f86c3ed7712b1967c6090283640eb7fa
prerequisite-patch-id: e4a0f14d7265301f5269b0c091f2e07edf900c0c
prerequisite-patch-id: 39944cafce6f4fb7ec9504dacfd8c6b5fe926b1d
prerequisite-patch-id: 8075232793c269bd35a05fabc94d008a79a20410
prerequisite-patch-id: d058a5d1e59605c07c105ae35c43c0962b807b4f
prerequisite-patch-id: 82b4e76a17509763c38ffc671feb2e3dad9bdb9c
prerequisite-patch-id: efd43d17e0ac76be8d2b499eaccbb9f000c8beea
prerequisite-patch-id: 8a35dca3b2709ea10050751d79a2c302873cc44c
prerequisite-patch-id: 5a2b132642428d97189b744504b53910422ea4c0
prerequisite-patch-id: 19cd1ab17e31f0ab77b0121ca5bf325d4b856688
prerequisite-patch-id: 8bfd83959ef0593f1ff7f3e32785b28ef95bd735
prerequisite-patch-id: ae5625753a9dec3220140a5429b6edf26a4ed3ef
prerequisite-patch-id: 48868f67a7a79699133f293949199bb62cb4d14f
prerequisite-patch-id: caadf1abbd9a89bdf412301d3dd8385f7620a68e
prerequisite-patch-id: b16d4bf162b2bbfc6aa2375e50f8d980f2094474
prerequisite-patch-id: be4a9f45a5f8bffcb112dc3d85a26556198bdb36
prerequisite-patch-id: 922d1e659004bb73a6cf9e8be4dffb059a1f7064
prerequisite-patch-id: 179a35f019d9b4e710871b73f8dcd11e6da07751
prerequisite-patch-id: 01d75e65d388d865b98f64df4c01520dac429a20
prerequisite-patch-id: 68aa2e329ce57a7d66e1565131465e0d1ec4cd4a
prerequisite-patch-id: 8881fa175c0cf2428e6e0f799cca99fb2a25e1b3
prerequisite-patch-id: 323d3686013fc1f9d62cd5dbb70990e5c10e7ff2
prerequisite-patch-id: ba903b136884d82f37db71df80eb61b1fd22c866
prerequisite-patch-id: 3f0b8185e387ef5ade47c38b93ba710bda13887a
prerequisite-patch-id: 50033db4bc14758bdd6eccb5d7b093030414375c
prerequisite-patch-id: 4b313a5d714e0f12e09bd1aa88c54dfbb1ae4865
prerequisite-patch-id: a2a4f7e4257e94779980d775d88e434240893ec1
prerequisite-patch-id: 3388c9855ea65493e7881cbb7b0b81bbfdcbe9b2
prerequisite-patch-id: f2b0676b2ebc7e47f257fea81ada7f0a22b637c2
prerequisite-patch-id: 58824481e1afe8430d157d8082704dbc813969e8
prerequisite-patch-id: 0ccbf7fc2052ce0798299982942ed31b6c03b7f0
prerequisite-patch-id: ab46fbaba2bf0a3d7c78788e8191f05e2e63b280
prerequisite-patch-id: 7b0069306569bf2cbe452abc5794bfa733f3ce51
prerequisite-patch-id: cf5d6669f8d8a26efa402e885f394391f60d4d05
prerequisite-patch-id: 3b13a73a6c667534523d8cd633c42418918c4e6d
prerequisite-patch-id: f8b5b7803e480a5023b738db1ca7ebb3c590ea97
prerequisite-patch-id: cd45857f5ddaceb76f53585ef69178446d594a59
prerequisite-patch-id: e14b0b8e19cdf397e9e5888459a1e680be762461
prerequisite-patch-id: 0f3f0b8c24e8c202b7c55fec1a834ee7ba44c6b4
prerequisite-patch-id: 59d8e3f737b6e8b7aa63131c5f75593ff7d7403f
prerequisite-patch-id: dd0b972b8b9a69216ed2610968fe5c71c9af2396
prerequisite-patch-id: c72bf9ba1a955b64cca58cfce0ef043780d47deb
prerequisite-patch-id: f8c1636f8d785e0f6c081bf1ebfc4c2f123d04a7
prerequisite-patch-id: a198a737cf7c0c4dc41ebe2e92fe32c6ce8288b1
prerequisite-patch-id: 878433be96f3d561cd71053c841febbfe2908dd4
prerequisite-patch-id: 66b374a29bf25cb55fc6a3de02a899136ae67d03
prerequisite-patch-id: 438f8c4e8e6e96c3e5f50237fb9b7a347028d628
prerequisite-patch-id: 716400c27b4ec19270e55d1aec908ddfe71d7780
prerequisite-patch-id: 121d33c159c0e5a763e318898bca84499dfd6aab
prerequisite-patch-id: 515030174cf7280fcf6dcdfe8c02894fe0a6d3b1
prerequisite-patch-id: 027406b77f0d667bc6233d64005720733059d748
prerequisite-patch-id: d2a51cfef6d475123553789be63ba1b5d5276276
prerequisite-patch-id: 035b6bdbe83fb364237f97fc9479735a065f53c8
prerequisite-patch-id: fd1ccd0ba5fbeb2f457d71e61e36e9c7266354e1
prerequisite-patch-id: 214e50fabac06c539b8f34bc2aa33717f91ab6e5
prerequisite-patch-id: 04c1a3a94b774e86a922fedc4c1d0021b3e9c2d7
prerequisite-patch-id: 3b4cb673a0378132bfb7e40fe707d69e417535f9
prerequisite-patch-id: 0703933e63a153ef9003bbc03f40e9716bc87459
prerequisite-patch-id: ecc6be674ba266dc23196989cee57c39fcbad6a0
prerequisite-patch-id: 2f839d93d8dc96fef542d443e48c5424769babd7
prerequisite-patch-id: f774b57f9f0c8e1598d9f0ac7fd642307e68ee00
prerequisite-patch-id: d5677c04ecb9415cf2597e448754c4e7936f4b52
prerequisite-patch-id: 7919b6dc0b1fc040a814b3e75a102a00e52e9895
prerequisite-patch-id: 0f65255a57e5cc13b62f4dadd17268db45402287
prerequisite-patch-id: 3892fee51ee7f9d9a3009fe1046c188c72375c81
prerequisite-patch-id: 38536dcbe76351c37c7286ff39efd3d0065bd61a
prerequisite-patch-id: 0095e734b35fc7e7ae52c5ecbceb7ec7754c9f5c
prerequisite-patch-id: 4fcf3ce5ec83da4c8203e344d896802035700c78
prerequisite-patch-id: f686dfa676a0ff2211356f9ebdabfaa7a0f4976d
prerequisite-patch-id: dc16c5aa9fad5aed68fb3e2ee33c3fc288b88de2
prerequisite-patch-id: 3551bfbc9309b5af45f5c2145f09874da63625c4
prerequisite-patch-id: 8c98176159eb3f17175d95267321351e4a906458
prerequisite-patch-id: 65a9b5dba5d52898d833a19d2b48004e9e967ffc
prerequisite-patch-id: 773347845e735c2eb2200ac2e517e0aa35b60dce
prerequisite-patch-id: 499030d2d8ba5ad12a580633336899e7d0eee927
prerequisite-patch-id: d1ef49cc749413b0991176588947d903bc112e3a
prerequisite-patch-id: 5bcf5d3206857624e50753c91d4a661a36b97527
prerequisite-patch-id: 40950431ad08fa2fb3420bfa9fef9b2141830c29
prerequisite-patch-id: 4e5c9807558f146a9b15989a605979176aca287a
prerequisite-patch-id: a847b3ca554d1bf4c14264e3055e61602447d196
prerequisite-patch-id: c4c5f6c3102f9e3db2415ec329c0cc0b756f6db2
prerequisite-patch-id: c1fddf5901196361f2840085f602977302dbdd33
prerequisite-patch-id: cc23b6642f00109cf5bc777457e85fe16671c259
prerequisite-patch-id: 17dd2b3e560469ba0fe35bee1b8f7861690564ba
prerequisite-patch-id: a9eb46652de672d01b7ff6db3d25cfbc33caaf34
prerequisite-patch-id: aa6c9b6f428f9f6d51cbc2261da0dcfd7f6f8104
prerequisite-patch-id: 03867e027920ffb60a213b6042b39c3c0ec47202
prerequisite-patch-id: 5e8cbdc0b210187057c8916c55da14bedd5ecf3f
prerequisite-patch-id: bd8b784c2b405df5ae1897e6fa655fbef7d5bde4
prerequisite-patch-id: c39d924db7f21eaca08c8d20493d3f95af9c8a20
prerequisite-patch-id: ca5a9840c4668dbb52ff1929e3ec5734cf4a9f43
prerequisite-patch-id: e018169573401a6d0b002381ab85093df01538c0
prerequisite-patch-id: 77b31b99bc68b4691dc2f22d264c7d1195e7bf90
prerequisite-patch-id: 9de64d7fcd9392f90217276d8b5eeb6c2dac7ec5
prerequisite-patch-id: 52341ef161c614c1284b4f9c0709f8bead489612
prerequisite-patch-id: 2c0fe4dc3ce6f7bf585bae9685a8724b3b1de81d
prerequisite-patch-id: f2cb4b5891c152ca8ff98e2e901e72469d61c3c1
prerequisite-patch-id: 7e2a6c6300694229ef94f8595f3308f1476c9b3a
prerequisite-patch-id: 798566431467a5b6f03152abb270b9cae09485ea
prerequisite-patch-id: ed90bf151bb041e8e36a30c4f8aa7c565edf4cf2
prerequisite-patch-id: a2f09807bf4af35e28dcec50e41f0c52675ea3fd
prerequisite-patch-id: d3a52b1651d418d7482473a65e4cf5bd5debda76
prerequisite-patch-id: 4d5e7842916c447b57647a61c550f461d456fb58
prerequisite-patch-id: f4567d45a48054503b8cc7109b81657d7d658473
prerequisite-patch-id: 24da9f35f581ed529352ba50dd4ddcba01d7d820
prerequisite-patch-id: f90aab2cdb7a1ff163bd3883bf91e50056ed9b18
prerequisite-patch-id: a52ea7b8919b598df6e443c02621609fe08d9925
prerequisite-patch-id: 00f752c5b25bd632ced319495752389bb59f6733
prerequisite-patch-id: 8022e402b4d68acf698ddc78980db8e83f14e579
prerequisite-patch-id: 476c7ca07e1061a04208696782b0ae7a544723f7
prerequisite-patch-id: 178fa8dc86f7245f6d40e17c66f1b150005e0939
prerequisite-patch-id: 439eeb1d5864182e015b12e1ea00e92a88bab0bf
prerequisite-patch-id: 3fc4e617203cd8245dfb8fb584d61d6bec2c9d46
prerequisite-patch-id: 9dbef7566cc9999323ddb3d63a7e6ec69d705550
prerequisite-patch-id: cf0b3ed7ed0d14c5b36c4b8232d479a1a3eb8016
prerequisite-patch-id: ddcc26a7dfeef146f35338cfc4b8e395cc7d8b3d
prerequisite-patch-id: 407f85cac6b5af1b9d52a5decee1099f15a00a3b
prerequisite-patch-id: 2e923c2ce5e566434d3f9ad87ddbc43ff60e960a
prerequisite-patch-id: 4f65429d2b9411682d62a303666132056895834f
prerequisite-patch-id: 880a34e8345a3f2d3803437043350442cef9055e
prerequisite-patch-id: 1c667a8f50bc91a1e8535e65a200d32594941602
prerequisite-patch-id: c6bdcbbd2901f6d25852772e2cf1969b542a4bc3
prerequisite-patch-id: 3fc29a406bb494eb7c45ab540f3ce38a4c09435b
prerequisite-patch-id: dde56d3f9698993e597e2b578376a961607bdfae
prerequisite-patch-id: 034d59e134df7c4d1a59c0db73b5acadd43a4064
prerequisite-patch-id: c967fa085945ee8d3224067f623a44a7cfc3c680
prerequisite-patch-id: 65fdca11ea35f68d669808f3a9bd9506a9cf7b62
prerequisite-patch-id: 4ce38942c3c657efb1fa8eb406c652ee2d39e3c0
prerequisite-patch-id: 28f2799708010db4a5ae73bd967566830c3caa65
prerequisite-patch-id: 7bd4e446bd8a238cc321c7065492ad58fa12cabf
prerequisite-patch-id: 6a4ece04a7ddd01a791a6aaf04bfec508b8f9754
prerequisite-patch-id: d605dcb33c1624ddabf60cc5c08553d5e87ef4e5
prerequisite-patch-id: 73ad753f92a04ba0e3ff1b897fe8e3a094ed803f
prerequisite-patch-id: 9f6bc53c45286627ee604ae3b9e6fd66b923d631
prerequisite-patch-id: f5b6f56af03d92d5cb03156c1b5185bd3c50fc20
prerequisite-patch-id: 52ba0add2c45454ee0bb44e64d5a2428dd214f7e
prerequisite-patch-id: 06964191450812d5462e415df5cb6cf3f5df0d51
prerequisite-patch-id: 2f78520797da18b49e8b372029d4c9a322d8d6aa
prerequisite-patch-id: aa93a59553b483a902b98ddff41a610d71e8e63e
prerequisite-patch-id: 08fceb470d9d641112892a2bc0fb31a99509ae94
prerequisite-patch-id: 0c8795e057035fca86421893634fcd18b763837f
prerequisite-patch-id: 3b44ad0750fbf612fb93e9e1ef0ec7e5e67b7461
prerequisite-patch-id: 7f43182c22270d94f92a7e2b27e9644b279cc2df
prerequisite-patch-id: dc8efaf0543d0c3dffaec127592bb2e3d9caf621
prerequisite-patch-id: e538fe68374df67cd1dcab9c22cabb9af472efd6
prerequisite-patch-id: 0c06084779307707efd893ff6cec4a397272e39a
prerequisite-patch-id: 3fc7bcb4397e3280a2f3fd1a5aea5e3e99f4a6bb
prerequisite-patch-id: 74feb45b278382cd640750c0309ccc144627ebef
prerequisite-patch-id: cffec315624eee697a689737c3604607f233e3a6
prerequisite-patch-id: 1c81a51134176e3ddc24df64a2bc15e418336a98
prerequisite-patch-id: 983296028729d18301f9c0e5a751a0b1cfd2d836
prerequisite-patch-id: 051d77844b175126224a6e11c54e24ce9c0a11a6
prerequisite-patch-id: c31acaab5a72316453476754142c684645f8d411
prerequisite-patch-id: 2714666603a45ecf37d6186652c07e92dc32b016
prerequisite-patch-id: c1e1b555e8f81e705d4adb4d0e13c6808aeb6d2c
prerequisite-patch-id: a0b8cd19cde4b098a9bbcd46ab306ac74d4b11fa
prerequisite-patch-id: 2a262f5aedc481d0b7326be4257480145b514821
prerequisite-patch-id: 3a886df9c04d5b2a3f808e33b31f33e7035ef61d
prerequisite-patch-id: 3af63c36a741b386b46591a316bc0b8454151476
prerequisite-patch-id: 1bb15abb410b8e02d31d988109327b8beb66966f
prerequisite-patch-id: 42f86de585ff18f2be55593a2eb9ac0e81134cdc
prerequisite-patch-id: df2534beffb39688aa566a68530984d65c6a25ff
prerequisite-patch-id: c62f20b677f721083659b6cdc1ea98742f1fe837
prerequisite-patch-id: a90c03d30f23e9ecd406e5b437914764575a804b
prerequisite-patch-id: 193b303d6108c638788f6708fb248178d3c29920
prerequisite-patch-id: 34bb990cb6732901c9f133a23df0bcc22c60d5bb
prerequisite-patch-id: 15cec68cf90b9cff2eaed000c2e76ae67f35f7de
prerequisite-patch-id: f5356cc7a0c8cbfde0c812e3fad94372ce02a759
prerequisite-patch-id: d22991f648f980c8a9e4c23fb5ce807e3ba20443
prerequisite-patch-id: a304772d6fa7e3e68ffb6e79b58d5e032db8b10b
prerequisite-patch-id: 723753ca986edebe8defc3e0aaf2320fd575b720
prerequisite-patch-id: b6e249431a1ab4a3b48e6da77a1d6530c13d938e
prerequisite-patch-id: 132a3160f140c41dfdbba5a4e2f8f64c16b0b749
prerequisite-patch-id: dfbedf94f9a4b6d5bdcc9167c2aed8236af4fbd0
prerequisite-patch-id: 4c4d1afdedf1b5fb31c9eddff85bdaba9d233b23
prerequisite-patch-id: 006cf470361d821adead418bde37b6966a33a3ec
prerequisite-patch-id: 3dc3f4c86097fa2b08ed506d01ddfee4cc247e03
prerequisite-patch-id: 923c604a08550f07959aee68459733a5febd26db
prerequisite-patch-id: 5c234eeb7412936487ae6916e9148d9605953ef2
prerequisite-patch-id: 6f551a26214b52a5bd275eb44da7d215bb5f6ac4
prerequisite-patch-id: 3f90d97c90e509f9235b3c26a0748a43e8d43f16
prerequisite-patch-id: d71bfce8ebbcb303b8293051850f8cc8cc272691
prerequisite-patch-id: fb977252a2a911434db714f52cce311209896850
prerequisite-patch-id: 33b6eec1b330dd853579e9d3a71084cdb253960e
prerequisite-patch-id: 2d87370f0586d2f9a5b5de6acde76ab0cf31223d
prerequisite-patch-id: 8eb45251e980302f13ccc6b4b117d3ac2a573e22
prerequisite-patch-id: d2d6bc285f6b973ffedf7d03c3ae6b7d2013090c
prerequisite-patch-id: cebff9d9178ebc3222e39d116ede173669a591d1
prerequisite-patch-id: 451fc6cd72b5e1e1bb27c5a3db2b60cb389a8c35
prerequisite-patch-id: 6c2676b84b05cca5e6382beb30fad456b10fd62d
prerequisite-patch-id: 8bdd7b28f09e97cff4f5995196b83b377c961d8b
prerequisite-patch-id: 6781b7ce5156d229fd21a757ef0cd66dd76130cc
prerequisite-patch-id: 56bcbbdceddf4533770d48d1835d5b7e11f47d56
prerequisite-patch-id: 2ccd038b5bb59697c764b6243175a28707bf7021
prerequisite-patch-id: 1be8d324f6455df332009dba20333e7c810574d4
prerequisite-patch-id: 3a596ce523f9d1082546a1106b472ef1eca749e9
prerequisite-patch-id: eff54772448531c9bcfffc3ab7483b4c18e086a2
prerequisite-patch-id: 91ed327dfe93dd8c89b308491cda5306f5c9fd8c
prerequisite-patch-id: 310c6bee038ca3909a8e5e58ec12b74f7189b869
prerequisite-patch-id: 92812c3d42b29504838e6dc66c307ff5c035bb5e
prerequisite-patch-id: 05775eaad4786fec6bb8579233449a6d21649217
prerequisite-patch-id: 5f445ad483e2c81ea07daaa1e895985b77bff201
prerequisite-patch-id: 55d6a70baf3be7f4da36b82cf02a5a7d59457520
prerequisite-change-id: 20251114-rust_leds-a959f7c2f7f9:v23
prerequisite-patch-id: b1580b8001aff8803e263065aac0e99e097a5c2e
prerequisite-patch-id: ed8f59cf86d4da65410e0a02fc1f7028a4b798bb
prerequisite-patch-id: 0fb1122e3dd00c01ebd0bf5525c4a2575679ae1c


^ permalink raw reply

* Re: [PATCH v2 2/4] drm: mxsfb: Add optional DPI output bus-width configuration
From: Frank Li @ 2026-07-24 17:01 UTC (permalink / raw)
  To: Francesco Dolcini
  Cc: Marek Vasut, Stefan Agner, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, David Airlie, Simona Vetter, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
	Pengutronix Kernel Team, Fabio Estevam, Alexander Stein,
	Francesco Dolcini, dri-devel, devicetree, linux-kernel, imx,
	linux-arm-kernel
In-Reply-To: <20260723155332.GB4453@francesco-nb>

On Thu, Jul 23, 2026 at 05:53:32PM +0200, Francesco Dolcini wrote:
> On Thu, Jul 23, 2026 at 10:47:36AM -0500, Frank Li wrote:
> > On Thu, Jul 23, 2026 at 11:38:09AM +0200, Francesco Dolcini wrote:
> > > From: Francesco Dolcini <francesco.dolcini@toradex.com>
> > >
> > > LCDIF programs LCD_DATABUS_WIDTH from the selected media bus format. The
> > > format reported by the downstream panel or bridge describes the display
> > > input, but it does not describe how the LCDIF data pins are physically
> > > wired on the board.
> > >
> > > These can differ. For example, a 16-bit LCDIF bus can be connected to a
> > > 24-bit display by wiring the available color bits to the corresponding
> > > display inputs. In that case, using the display's 24-bit format to
> > > configure LCDIF selects the wrong data-bus mode and changes the assignment
> > > of color bits on the LCD_DATA pins.
> > >
> > > Read the optional bus-width endpoint property from the LCDIF output port
> > > and use it to select the media bus format used to configure LCDIF. This
> > > allows the LCDIF bus mode to describe the physical interface
> > > independently of the downstream display format.
> > >
> > > When the optional property is absent, continue using the format reported
> > > by the downstream display device, preserving the existing behavior.
> > >
> > > Signed-off-by: Francesco Dolcini <francesco.dolcini@toradex.com>
> > > ---
> > > v2: use the common bus-width property instead of the legacy interface-pix-fmt
> > > ---
> > >  drivers/gpu/drm/mxsfb/mxsfb_drv.c | 24 ++++++++++++++++++++++++
> > >  drivers/gpu/drm/mxsfb/mxsfb_drv.h |  2 ++
> > >  drivers/gpu/drm/mxsfb/mxsfb_kms.c | 12 ++++++++++++
> > >  3 files changed, 38 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > > index 9b8fbda85d28..0545718a4b65 100644
> > > --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > > +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c
> > > @@ -12,7 +12,10 @@
> > >  #include <linux/clk.h>
> > >  #include <linux/dma-mapping.h>
> > >  #include <linux/io.h>
> > > +#include <linux/media-bus-format.h>
> > >  #include <linux/module.h>
> > > +#include <linux/of.h>
> > > +#include <linux/of_graph.h>
> > >  #include <linux/platform_device.h>
> > >  #include <linux/property.h>
> > >  #include <linux/pm_runtime.h>
> > > @@ -209,7 +212,10 @@ static int mxsfb_load(struct drm_device *drm,
> > >  		      const struct mxsfb_devdata *devdata)
> > >  {
> > >  	struct platform_device *pdev = to_platform_device(drm->dev);
> > > +	struct device_node *np = pdev->dev.of_node;
> > >  	struct mxsfb_drm_private *mxsfb;
> > > +	struct device_node *ep;
> > > +	u32 bus_width = 0;
> > >  	int ret;
> > >
> > >  	mxsfb = devm_kzalloc(&pdev->dev, sizeof(*mxsfb), GFP_KERNEL);
> > > @@ -236,6 +242,24 @@ static int mxsfb_load(struct drm_device *drm,
> > >  	if (IS_ERR(mxsfb->clk_disp_axi))
> > >  		mxsfb->clk_disp_axi = NULL;
> > >
> > > +	ep = of_graph_get_next_endpoint(np, NULL);
> >
> > use auto cleanup
> >
> > 	struct device_node *ep __free(device_node) = of_graph_get_next_endpoint(np, NULL);
>
> Does it makes the code more read-able or better in this specific case? I
> would say no, to me it is more compact and clear the way it is.

Recently there are bunch of patch to fix miss of_put_node(). auto cleanup
help avoid manual to manage it and let us to force key part.

recently, perfer use fwnode_graph_get_next_endpoint() and other fwnode_xxx
node function.

it is also okay to keep use of_xxx() to align existing code.

Frank

>
>

^ permalink raw reply

* Re: [PATCH v3 2/2] hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: sashiko-bot @ 2026-07-24 16:59 UTC (permalink / raw)
  To: Pradhan, Sanman; +Cc: conor+dt, devicetree, linux-hwmon, robh
In-Reply-To: <20260724164919.247162-3-sanman.pradhan@hpe.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The arithmetic calculation in `vt7505_set_m()` can overflow when converting the 64-bit result to a signed 32-bit integer, resulting in a negative or corrupted PMBus coefficient.
--

--- Patch [2]: [PATCH v3 2/2] hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505 ---
commit 6d968d4ee814c7e869f893c1177921f54e4e55cd
Author: Georgi Vlaev <gvlaev@juniper.net>

hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505

This commit adds a PMBus driver for the MAX16545, MAX16550, and VT7505
controllers. It reports voltage, current, power, and temperature over
PMBus, calculating current and power coefficients based on the
adi,rload-ohms device tree property.

> diff --git a/drivers/hwmon/pmbus/vt7505.c b/drivers/hwmon/pmbus/vt7505.c
> new file mode 100644
> index 0000000000000..c60f849e1f9ea
> --- /dev/null
> +++ b/drivers/hwmon/pmbus/vt7505.c

[ ... ]

> +static void vt7505_set_m(int *m, u32 rload)
> +{
> +	u64 val = (u64)*m * rload;
> +
> +	/* Make sure m fits the s32 type */
> +	*m = DIV_ROUND_CLOSEST_ULL(val, 1000);

[Severity: Medium]
Does this downcast to a signed 32-bit integer safely handle large values of
rload?

If the rload value is sufficiently large, could the result of
DIV_ROUND_CLOSEST_ULL() exceed INT_MAX and silently overflow into a
negative PMBus coefficient?

> +}
> +
> +static int vt7505_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	const struct vt7505_chip_data *chip;
> +	struct pmbus_driver_info *info;
> +	u32 rload;
> +	int ret;

[ ... ]

> +	/*
> +	 * The m coefficient used in the direct-format current and power
> +	 * calculations depends on RLOAD, the external current-report resistor
> +	 * connected between the ILOAD pin and ground. Use the default value if
> +	 * none is specified.
> +	 */
> +	if (of_property_read_u32(dev->of_node, "adi,rload-ohms", &rload))
> +		rload = VT7505_RLOAD_DEFAULT;
> +
> +	if (!rload)
> +		return dev_err_probe(dev, -EINVAL,
> +				     "adi,rload-ohms must be non-zero\n");

[Severity: Medium]
Should there be an upper bound validation for rload here?

Because rload is read directly from the device tree and passed to
vt7505_set_m(), an unexpectedly large unbounded value could trigger the
arithmetic overflow mentioned above.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724164919.247162-1-sanman.pradhan@hpe.com?part=2

^ permalink raw reply

* Re: [PATCH v3 1/2] dt-bindings: hwmon: pmbus: Add Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: sashiko-bot @ 2026-07-24 16:53 UTC (permalink / raw)
  To: Pradhan, Sanman; +Cc: conor+dt, robh, linux-hwmon, devicetree
In-Reply-To: <20260724164919.247162-2-sanman.pradhan@hpe.com>

> From: Sanman Pradhan <psanman@juniper.net>
> 
> Add device tree binding documentation for the Analog Devices MAX16545 and
> MAX16550, and the Volterra VT7505 PMBus controllers.
> 
> Signed-off-by: Sanman Pradhan <psanman@juniper.net>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260724164919.247162-1-sanman.pradhan@hpe.com?part=1


^ permalink raw reply

* Re: [PATCH v2 1/6] dt-bindings: iio: dac: ad5696: add AD5673R/AD5677R support
From: Conor Dooley @ 2026-07-24 16:53 UTC (permalink / raw)
  To: rodrigo.alencar
  Cc: Michael Auchter, linux, linux-iio, devicetree, linux-kernel,
	Michael Hennerich, Jonathan Cameron, David Lechner,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <20260724-ad5686-extend-dev-support-v2-1-cfc2b30ce988@analog.com>

[-- Attachment #1: Type: text/plain, Size: 430 bytes --]

On Fri, Jul 24, 2026 at 01:03:11PM +0100, Rodrigo Alencar via B4 Relay wrote:
> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
> 
> Add compatible entries for AD5673R and AD5677R. These 16-channel devices
> have different bit resolutions so no fallback compatibles are used.
> 
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>

Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v2 4/6] dt-bindings: iio: dac: ad5696: extend device support
From: Conor Dooley @ 2026-07-24 16:53 UTC (permalink / raw)
  To: rodrigo.alencar
  Cc: Michael Auchter, linux, linux-iio, devicetree, linux-kernel,
	Michael Hennerich, Jonathan Cameron, David Lechner,
	Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley
In-Reply-To: <20260724-ad5686-extend-dev-support-v2-4-cfc2b30ce988@analog.com>

[-- Attachment #1: Type: text/plain, Size: 75 bytes --]

Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v5 3/4] hwmon: (kb9002) Add driver for Kandou KB9002 retimer
From: Guenter Roeck @ 2026-07-24 16:52 UTC (permalink / raw)
  To: Andy Chung
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet,
	Shuah Khan, devicetree, linux-kernel, linux-hwmon, linux-doc
In-Reply-To: <20260724-kb9002-upstream-v5-3-9523c3ffe83a@amd.com>

On Fri, Jul 24, 2026 at 12:47:39PM +0800, Andy Chung wrote:
> From: Andy Chung <Andy.Chung@amd.com>
> 
> The Kandou KB9002 is an 8-lane PCIe 5.0 retimer that exposes an SMBus
> target with mandatory PEC. Add a hwmon driver reporting the firmware
> aggregated maximum die temperature as temp1_input, with the firmware
> version and boot status under debugfs.
> 
> Signed-off-by: Andy Chung <Andy.Chung@amd.com>

For my reference:

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

Thanks,
Guenter

^ permalink raw reply

* Re: [PATCH v5 4/4] hwmon: (kb9002) Add documentation
From: Guenter Roeck @ 2026-07-24 16:51 UTC (permalink / raw)
  To: Andy Chung
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jonathan Corbet,
	Shuah Khan, devicetree, linux-kernel, linux-hwmon, linux-doc
In-Reply-To: <20260724-kb9002-upstream-v5-4-9523c3ffe83a@amd.com>

On Fri, Jul 24, 2026 at 12:47:40PM +0800, Andy Chung wrote:
> From: Andy Chung <Andy.Chung@amd.com>
> 
> Document the sysfs and debugfs interfaces of the Kandou KB9002 hwmon
> driver.
> 
> Signed-off-by: Andy Chung <Andy.Chung@amd.com>

For my reference:

Reviewed-by: Guenter Roeck <linux@roeck-us.net>

(waiting for DT patch review)

Thanks,
Guenter

^ permalink raw reply

* Re: [PATCH v3 3/8] dt-bindings: arm: altera: add Agilex5 SOCDK eMMC board variant
From: Conor Dooley @ 2026-07-24 16:51 UTC (permalink / raw)
  To: Tanmay Kathpalia
  Cc: linux-mmc, ulfh, adrian.hunter, krzk+dt, robh, conor+dt, dinguyen,
	p.zabel, devicetree, linux-kernel
In-Reply-To: <20260724145009.7456-3-tanmay.kathpalia@altera.com>

[-- Attachment #1: Type: text/plain, Size: 75 bytes --]

Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/2] hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: Pradhan, Sanman @ 2026-07-24 16:50 UTC (permalink / raw)
  To: linux@roeck-us.net
  Cc: krzk@kernel.org, linux-hwmon@vger.kernel.org, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, corbet@lwn.net,
	skhan@linuxfoundation.org, devicetree@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Sanman Pradhan
In-Reply-To: <668b28b1-875f-4fdd-b367-b09edef95367@roeck-us.net>

From: Sanman Pradhan <psanman@juniper.net>

On Fri, Jul 24, 2026 at 06:15:35 -0700, Guenter Roeck wrote:
> On 7/24/26 02:03, Krzysztof Kozlowski wrote:
> > On Thu, Jul 23, 2026 at 04:43:59PM +0000, Pradhan, Sanman wrote:
> > > +enum chips { max16550, vt7505 };
> >
> > You must adjust to upstream kernel style and such constants/defines are
> > UPPER CASE
>
> No, you must not. Not in the hardware monitoring subsystem, where the
> chips enumeration is and always has been traditionally lower case.

Thanks for the reviews, Krzysztof and Guenter. I've tried to address
all the comments in v3.

Regarding adi,rload-ohms: after checking the datasheet more carefully,
this does not seem to be the same as the current-path sense resistor
that shunt-resistor-micro-ohms describes. These devices use integrated
lossless current sensing the ILOAD pin sources a small reporting
current proportional to the load current (typically 5 uA/A), and RLOAD
simply converts that reporting current into a voltage for telemetry
scaling. It does not carry the load current itself. I've kept the
device-specific property and tried to clarify this distinction in the
binding description.

I've also moved additionalProperties after the allOf block and added
adi,ocp-severe-filter-us to the example. The property is still
optional, when absent, the driver leaves the existing MFR_CONFIG
setting unchanged.

In the driver, I've replaced the raw enum match values with per-device
match data for MAX16545, MAX16550, and VT7505. This avoids the
zero-valued match data concern and removes the compatible-string check
from probe. The match data now carries the temperature coefficients and
a flag indicating whether the severe OCP filter is programmable.

Thank you.

Regards,
Sanman Pradhan

^ permalink raw reply

* [PATCH v3 2/2] hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: Pradhan, Sanman @ 2026-07-24 16:50 UTC (permalink / raw)
  To: linux-hwmon@vger.kernel.org
  Cc: linux@roeck-us.net, robh@kernel.org, krzk+dt@kernel.org,
	krzk@kernel.org, conor+dt@kernel.org, corbet@lwn.net,
	skhan@linuxfoundation.org, devicetree@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Sanman Pradhan, Georgi Vlaev, Dhruva Devineni, Debjit Ghosh,
	Jawahar Balaji Thirumalaisamy, Avadhut Naik,
	Santhanakrishnan Balraj, Brian Mak
In-Reply-To: <20260724164919.247162-1-sanman.pradhan@hpe.com>

From: Georgi Vlaev <gvlaev@juniper.net>

Add a PMBus driver for the Analog Devices MAX16545 and MAX16550, and the
Volterra VT7505 controllers. The driver reports input/output voltage,
input/output current, input power and temperature over PMBus. All values
use the direct data format. Peak input voltage, output voltage, output
current, input power and temperature readings are exposed and can be
reset.

The reported current and power depend on the external current-report
resistor connected to the ILOAD pin, which can be provided through the
"adi,rload-ohms" device tree property.

On the MAX16550 and VT7505, the severe-OCP deglitch time can optionally
be configured with the "adi,ocp-severe-filter-us" device tree property.
When omitted, the existing hardware setting is left unchanged.

Signed-off-by: Georgi Vlaev <gvlaev@juniper.net>
Co-developed-by: Dhruva Devineni <ddevineni@juniper.net>
Signed-off-by: Dhruva Devineni <ddevineni@juniper.net>
Co-developed-by: Debjit Ghosh <dghosh@juniper.net>
Signed-off-by: Debjit Ghosh <dghosh@juniper.net>
Co-developed-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
Signed-off-by: JawaharBalaji Thirumalaisamy <jawaharb@juniper.net>
Co-developed-by: Avadhut Naik <avadhutn@juniper.net>
Signed-off-by: Avadhut Naik <avadhutn@juniper.net>
Co-developed-by: Santhanakrishnan Balraj <sbalraj@juniper.net>
Signed-off-by: Santhanakrishnan Balraj <sbalraj@juniper.net>
Co-developed-by: Brian Mak <makb@juniper.net>
Signed-off-by: Brian Mak <makb@juniper.net>
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
---
Changes in v3:
- Use per-device match data instead of an enum (no zero-valued match
  data); derive the temperature coefficients and severe-OCP filter
  support from it.
- Add an explicit adi,max16545 match entry and drop the compatible-string
  check in probe.
- Use designated initializers for the I2C device ID table.
- Replace the SPDX-FileCopyrightText tag with a plain copyright line.

Changes in v2:
- Map the microsecond adi,ocp-severe-filter-us value to the
  MFR_CONFIG[15:14] register field.

 Documentation/hwmon/index.rst  |   1 +
 Documentation/hwmon/vt7505.rst |  89 +++++++++++
 MAINTAINERS                    |   8 +
 drivers/hwmon/pmbus/Kconfig    |   9 ++
 drivers/hwmon/pmbus/Makefile   |   1 +
 drivers/hwmon/pmbus/vt7505.c   | 284 +++++++++++++++++++++++++++++++++
 6 files changed, 392 insertions(+)
 create mode 100644 Documentation/hwmon/vt7505.rst
 create mode 100644 drivers/hwmon/pmbus/vt7505.c

diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst
index 956f3da0b7223..62687bb994ac1 100644
--- a/Documentation/hwmon/index.rst
+++ b/Documentation/hwmon/index.rst
@@ -281,6 +281,7 @@ Hardware Monitoring Kernel Drivers
    vexpress
    via686a
    vt1211
+   vt7505
    w83627ehf
    w83627hf
    w83773g
diff --git a/Documentation/hwmon/vt7505.rst b/Documentation/hwmon/vt7505.rst
new file mode 100644
index 0000000000000..e56dc0055e89f
--- /dev/null
+++ b/Documentation/hwmon/vt7505.rst
@@ -0,0 +1,89 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Kernel driver vt7505
+====================
+
+Supported chips:
+
+  * Analog Devices MAX16545
+
+    Prefix: 'max16545'
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max16545b-max16545c.pdf
+
+  * Analog Devices MAX16550
+
+    Prefix: 'max16550'
+
+    Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max16550.pdf
+
+  * Volterra VT7505
+
+    Prefix: 'vt7505'
+
+    Datasheet: Not publicly available; register-compatible with the MAX16545.
+
+Author: Georgi Vlaev <gvlaev@juniper.net>
+
+Description
+-----------
+
+This driver supports hardware monitoring for the Analog Devices MAX16545 and
+MAX16550, and the Volterra VT7505 PMBus controllers.
+
+The devices report input and output voltage, input and output current,
+input power, and temperature. All values use the PMBus direct data format.
+Peak (maximum) values for input voltage, output voltage, output current,
+input power and temperature are exposed and can be reset. Writing to any
+``*_reset_history`` attribute clears all of the device's peak values.
+
+The reported current and power values depend on the resistance of the
+external current-report resistor connected between the ILOAD pin and
+ground. This resistance can be provided via the ``adi,rload-ohms``
+device tree property; a default of 4750 ohms is used when it is absent.
+
+Sysfs entries
+-------------
+
+The limit and alarm attributes are created by the PMBus core for the limit
+registers that the device implements. See
+Documentation/hwmon/sysfs-interface.rst for the meaning of each attribute.
+
+======================= ========================================================
+in1_label               "vin"
+in1_input               Measured input voltage.
+in1_min                 Input undervoltage warning limit.
+in1_min_alarm           Input undervoltage warning alarm.
+in1_lcrit               Input undervoltage fault limit.
+in1_lcrit_alarm         Input undervoltage fault alarm.
+in1_highest             Historical maximum input voltage.
+in1_reset_history       Write to reset all peak values.
+in2_label               "vout1"
+in2_input               Measured output voltage.
+in2_min                 Output undervoltage warning limit.
+in2_min_alarm           Output undervoltage warning alarm.
+in2_highest             Historical maximum output voltage.
+in2_reset_history       Write to reset all peak values.
+curr1_label             "iin"
+curr1_input             Measured input current.
+curr1_alarm             Input current alarm.
+curr2_label             "iout1"
+curr2_input             Measured output current.
+curr2_max               Output overcurrent warning limit.
+curr2_max_alarm         Output overcurrent warning alarm.
+curr2_highest           Historical maximum output current.
+curr2_reset_history     Write to reset all peak values.
+power1_label            "pin"
+power1_input            Measured input power.
+power1_max              Input overpower warning limit.
+power1_alarm            Input overpower warning alarm.
+power1_input_highest    Historical maximum input power.
+power1_reset_history    Write to reset all peak values.
+temp1_input             Measured temperature.
+temp1_max               Overtemperature warning limit.
+temp1_max_alarm         Overtemperature warning alarm.
+temp1_crit              Overtemperature fault limit.
+temp1_crit_alarm        Overtemperature fault alarm.
+temp1_highest           Historical maximum temperature.
+temp1_reset_history     Write to reset all peak values.
+======================= ========================================================
diff --git a/MAINTAINERS b/MAINTAINERS
index d88c0dd4c8142..b914aafb8514c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -28958,6 +28958,14 @@ S:	Maintained
 F:	Documentation/hwmon/vt1211.rst
 F:	drivers/hwmon/vt1211.c
 
+VT7505 HARDWARE MONITOR DRIVER
+M:	Sanman Pradhan <psanman@juniper.net>
+L:	linux-hwmon@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/hwmon/pmbus/adi,vt7505.yaml
+F:	Documentation/hwmon/vt7505.rst
+F:	drivers/hwmon/pmbus/vt7505.c
+
 VT8231 HARDWARE MONITOR DRIVER
 M:	Roger Lucas <vt8231@hiddenengine.co.uk>
 L:	linux-hwmon@vger.kernel.org
diff --git a/drivers/hwmon/pmbus/Kconfig b/drivers/hwmon/pmbus/Kconfig
index ca312be58ed5c..6c97a6dc88a59 100644
--- a/drivers/hwmon/pmbus/Kconfig
+++ b/drivers/hwmon/pmbus/Kconfig
@@ -795,6 +795,15 @@ config SENSORS_UCD9200
 	  This driver can also be built as a module. If so, the module will
 	  be called ucd9200.
 
+config SENSORS_VT7505
+	tristate "Analog Devices MAX16545, MAX16550 and Volterra VT7505"
+	help
+	  If you say yes here you get hardware monitoring support for Analog
+	  Devices MAX16545, MAX16550 and Volterra VT7505 PMBus controllers.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called vt7505.
+
 config SENSORS_XDP710
 	tristate "Infineon XDP710 family"
 	help
diff --git a/drivers/hwmon/pmbus/Makefile b/drivers/hwmon/pmbus/Makefile
index 080d366809f32..daa4b49bc90fd 100644
--- a/drivers/hwmon/pmbus/Makefile
+++ b/drivers/hwmon/pmbus/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_SENSORS_TPS53679)	+= tps53679.o
 obj-$(CONFIG_SENSORS_TPS546D24)	+= tps546d24.o
 obj-$(CONFIG_SENSORS_UCD9000)	+= ucd9000.o
 obj-$(CONFIG_SENSORS_UCD9200)	+= ucd9200.o
+obj-$(CONFIG_SENSORS_VT7505)	+= vt7505.o
 obj-$(CONFIG_SENSORS_XDP710)	+= xdp710.o
 obj-$(CONFIG_SENSORS_XDP720)	+= xdp720.o
 obj-$(CONFIG_SENSORS_XDPE122)	+= xdpe12284.o
diff --git a/drivers/hwmon/pmbus/vt7505.c b/drivers/hwmon/pmbus/vt7505.c
new file mode 100644
index 0000000000000..c60f849e1f9ea
--- /dev/null
+++ b/drivers/hwmon/pmbus/vt7505.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Hardware monitoring driver for Analog Devices MAX16545/MAX16550 and
+ * Volterra VT7505 PMBus controllers.
+ *
+ * Copyright 2026 Hewlett Packard Enterprise Development LP
+ */
+
+#include <linux/bitfield.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pmbus.h>
+
+#include "pmbus.h"
+
+#define VT7505_MFR_CONFIG		0xd0
+#define VT7505_CFG_OCP_S_FILT_MASK	GENMASK(15, 14)
+
+#define VT7505_MFR_PEAK_VIN		0xd1
+#define VT7505_MFR_PEAK_IOUT		0xd2
+#define VT7505_MFR_PEAK_PIN		0xd3
+#define VT7505_MFR_PEAK_TEMP		0xd4
+#define VT7505_MFR_CLEAR_PEAKS		0xd5
+#define VT7505_MFR_PEAK_VOUT		0xfd
+
+#define VT7505_RLOAD_DEFAULT		4750
+
+struct vt7505_chip_data {
+	int temp_m;
+	int temp_b;
+	bool has_ocp_filter;
+};
+
+static const struct vt7505_chip_data max16545_data = {
+	.temp_m = 205,
+	.temp_b = 6545,
+};
+
+static const struct vt7505_chip_data max16550_data = {
+	.temp_m = 199,
+	.temp_b = 7046,
+	.has_ocp_filter = true,
+};
+
+static const struct vt7505_chip_data vt7505_data = {
+	.temp_m = 205,
+	.temp_b = 6545,
+	.has_ocp_filter = true,
+};
+
+static int vt7505_read_word_data(struct i2c_client *client, int page,
+				 int phase, int reg)
+{
+	switch (reg) {
+	case PMBUS_VIRT_READ_VIN_MAX:
+		return pmbus_read_word_data(client, page, phase,
+					    VT7505_MFR_PEAK_VIN);
+	case PMBUS_VIRT_READ_IOUT_MAX:
+		return pmbus_read_word_data(client, page, phase,
+					    VT7505_MFR_PEAK_IOUT);
+	case PMBUS_VIRT_READ_PIN_MAX:
+		return pmbus_read_word_data(client, page, phase,
+					    VT7505_MFR_PEAK_PIN);
+	case PMBUS_VIRT_READ_TEMP_MAX:
+		return pmbus_read_word_data(client, page, phase,
+					    VT7505_MFR_PEAK_TEMP);
+	case PMBUS_VIRT_READ_VOUT_MAX:
+		return pmbus_read_word_data(client, page, phase,
+					    VT7505_MFR_PEAK_VOUT);
+	case PMBUS_VIRT_RESET_VIN_HISTORY:
+	case PMBUS_VIRT_RESET_IOUT_HISTORY:
+	case PMBUS_VIRT_RESET_PIN_HISTORY:
+	case PMBUS_VIRT_RESET_TEMP_HISTORY:
+	case PMBUS_VIRT_RESET_VOUT_HISTORY:
+		return 0;
+	default:
+		return -ENODATA;
+	}
+}
+
+static int vt7505_write_word_data(struct i2c_client *client, int page,
+				  int reg, u16 word)
+{
+	switch (reg) {
+	/*
+	 * A single reset command clears all peak values. CLEAR_PEAKS is a
+	 * send-byte command; the device NAKs a word or byte-data write to it.
+	 */
+	case PMBUS_VIRT_RESET_VIN_HISTORY:
+	case PMBUS_VIRT_RESET_IOUT_HISTORY:
+	case PMBUS_VIRT_RESET_PIN_HISTORY:
+	case PMBUS_VIRT_RESET_TEMP_HISTORY:
+	case PMBUS_VIRT_RESET_VOUT_HISTORY:
+		return pmbus_write_byte(client, page,
+					VT7505_MFR_CLEAR_PEAKS);
+	default:
+		return -ENODATA;
+	}
+}
+
+/*
+ * None of these controllers implement the standard PMBus WRITE_PROTECT
+ * (0x10) register, so tell the core not to access it.
+ */
+static struct pmbus_platform_data vt7505_pdata = {
+	.flags = PMBUS_NO_WRITE_PROTECT,
+};
+
+static int vt7505_set_ocp_filter(struct i2c_client *client)
+{
+	u32 ocp_us;
+	u8 field;
+	int ret;
+	u16 word;
+
+	if (of_property_read_u32(client->dev.of_node, "adi,ocp-severe-filter-us",
+				 &ocp_us))
+		return 0;
+
+	switch (ocp_us) {
+	case 0:
+		field = 0;
+		break;
+	case 1:
+		field = 1;
+		break;
+	case 2:
+		field = 2;
+		break;
+	case 10:
+		field = 3;
+		break;
+	default:
+		return dev_err_probe(&client->dev, -EINVAL,
+				     "invalid adi,ocp-severe-filter-us value %u\n",
+				     ocp_us);
+	}
+
+	ret = i2c_smbus_read_word_data(client, VT7505_MFR_CONFIG);
+	if (ret < 0)
+		return dev_err_probe(&client->dev, ret,
+				     "failed to read MFR_CONFIG\n");
+
+	word = ret & ~VT7505_CFG_OCP_S_FILT_MASK;
+	word |= FIELD_PREP(VT7505_CFG_OCP_S_FILT_MASK, field);
+
+	ret = i2c_smbus_write_word_data(client, VT7505_MFR_CONFIG, word);
+	if (ret < 0)
+		return dev_err_probe(&client->dev, ret,
+				     "failed to write MFR_CONFIG\n");
+
+	return 0;
+}
+
+static void vt7505_set_m(int *m, u32 rload)
+{
+	u64 val = (u64)*m * rload;
+
+	/* Make sure m fits the s32 type */
+	*m = DIV_ROUND_CLOSEST_ULL(val, 1000);
+}
+
+static int vt7505_probe(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	const struct vt7505_chip_data *chip;
+	struct pmbus_driver_info *info;
+	u32 rload;
+	int ret;
+
+	chip = i2c_get_match_data(client);
+	if (!chip)
+		return -ENODEV;
+
+	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	dev->platform_data = &vt7505_pdata;
+
+	/*
+	 * The m coefficient used in the direct-format current and power
+	 * calculations depends on RLOAD, the external current-report resistor
+	 * connected between the ILOAD pin and ground. Use the default value if
+	 * none is specified.
+	 */
+	if (of_property_read_u32(dev->of_node, "adi,rload-ohms", &rload))
+		rload = VT7505_RLOAD_DEFAULT;
+
+	if (!rload)
+		return dev_err_probe(dev, -EINVAL,
+				     "adi,rload-ohms must be non-zero\n");
+
+	info->pages = 1;
+	info->read_word_data = vt7505_read_word_data;
+	info->write_word_data = vt7505_write_word_data;
+
+	info->format[PSC_VOLTAGE_IN] = direct;
+	info->format[PSC_VOLTAGE_OUT] = direct;
+	info->format[PSC_CURRENT_IN] = direct;
+	info->format[PSC_CURRENT_OUT] = direct;
+	info->format[PSC_POWER] = direct;
+	info->format[PSC_TEMPERATURE] = direct;
+
+	/*
+	 * Direct data format coefficients from the device datasheet ("PMBus
+	 * Equation Parameters"). The current and power m coefficients scale
+	 * with RLOAD; vt7505_set_m() applies the 1/1000 factor below, giving
+	 * m = 3.824 * RLOAD for current and 0.895 * RLOAD for power. The
+	 * temperature coefficients are chip specific (see the chip data).
+	 */
+	info->m[PSC_VOLTAGE_IN] = 7578;
+	info->R[PSC_VOLTAGE_IN] = -2;
+	info->m[PSC_VOLTAGE_OUT] = 7578;
+	info->R[PSC_VOLTAGE_OUT] = -2;
+	info->m[PSC_CURRENT_IN] = 3824;
+	info->b[PSC_CURRENT_IN] = -4300;
+	info->R[PSC_CURRENT_IN] = -3;
+	info->m[PSC_CURRENT_OUT] = 3824;
+	info->b[PSC_CURRENT_OUT] = -4300;
+	info->R[PSC_CURRENT_OUT] = -3;
+	info->m[PSC_POWER] = 895;
+	info->b[PSC_POWER] = -9100;
+	info->R[PSC_POWER] = -2;
+
+	vt7505_set_m(&info->m[PSC_CURRENT_IN], rload);
+	vt7505_set_m(&info->m[PSC_CURRENT_OUT], rload);
+	vt7505_set_m(&info->m[PSC_POWER], rload);
+
+	info->m[PSC_TEMPERATURE] = chip->temp_m;
+	info->b[PSC_TEMPERATURE] = chip->temp_b;
+	info->R[PSC_TEMPERATURE] = -2;
+
+	info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
+			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+			PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+			PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP |
+			PMBUS_HAVE_IIN | PMBUS_HAVE_PIN;
+
+	/*
+	 * The severe OCP deglitch filter is programmable on the MAX16550 and
+	 * the VT7505, but fixed on the MAX16545.
+	 */
+	if (chip->has_ocp_filter) {
+		ret = vt7505_set_ocp_filter(client);
+		if (ret)
+			return ret;
+	}
+
+	return pmbus_do_probe(client, info);
+}
+
+static const struct i2c_device_id vt7505_id[] = {
+	{ .name = "max16545", .driver_data = (kernel_ulong_t)&max16545_data },
+	{ .name = "max16550", .driver_data = (kernel_ulong_t)&max16550_data },
+	{ .name = "vt7505", .driver_data = (kernel_ulong_t)&vt7505_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, vt7505_id);
+
+static const struct of_device_id vt7505_of_match[] = {
+	{ .compatible = "adi,max16545", .data = &max16545_data },
+	{ .compatible = "adi,max16550", .data = &max16550_data },
+	{ .compatible = "adi,vt7505", .data = &vt7505_data },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, vt7505_of_match);
+
+static struct i2c_driver vt7505_driver = {
+	.driver = {
+		.name = "vt7505",
+		.of_match_table = vt7505_of_match,
+	},
+	.probe = vt7505_probe,
+	.id_table = vt7505_id,
+};
+module_i2c_driver(vt7505_driver);
+
+MODULE_AUTHOR("Georgi Vlaev <gvlaev@juniper.net>");
+MODULE_DESCRIPTION("PMBus driver for Analog Devices MAX16545/MAX16550 and Volterra VT7505");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("PMBUS");
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 1/2] dt-bindings: hwmon: pmbus: Add Analog Devices MAX16545/MAX16550 and Volterra VT7505
From: Pradhan, Sanman @ 2026-07-24 16:49 UTC (permalink / raw)
  To: linux-hwmon@vger.kernel.org
  Cc: linux@roeck-us.net, robh@kernel.org, krzk+dt@kernel.org,
	krzk@kernel.org, conor+dt@kernel.org, corbet@lwn.net,
	skhan@linuxfoundation.org, devicetree@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Sanman Pradhan
In-Reply-To: <20260724164919.247162-1-sanman.pradhan@hpe.com>

From: Sanman Pradhan <psanman@juniper.net>

Add device tree binding documentation for the Analog Devices MAX16545 and
MAX16550, and the Volterra VT7505 PMBus controllers.

Signed-off-by: Sanman Pradhan <psanman@juniper.net>
---
Changes in v3:
- Clarify that adi,rload-ohms is the ILOAD telemetry resistor, not a
  current-path shunt.
- Note that the severe-OCP filter retains the existing hardware setting
  when omitted, and add it to the example.
- Move additionalProperties after the allOf block.

Changes in v2:
- Represent the severe-OCP deglitch filter in microseconds
  (renamed to adi,ocp-severe-filter-us, values 0/1/2/10).

 .../bindings/hwmon/pmbus/adi,vt7505.yaml      | 84 +++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/pmbus/adi,vt7505.yaml

diff --git a/Documentation/devicetree/bindings/hwmon/pmbus/adi,vt7505.yaml b/Documentation/devicetree/bindings/hwmon/pmbus/adi,vt7505.yaml
new file mode 100644
index 0000000000000..cc538de6c0675
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/pmbus/adi,vt7505.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/hwmon/pmbus/adi,vt7505.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Analog Devices MAX16545/MAX16550 and Volterra VT7505 PMBus controllers
+
+maintainers:
+  - Sanman Pradhan <psanman@juniper.net>
+
+description: |
+  The Analog Devices MAX16545 and MAX16550, and the Volterra VT7505, are PMBus
+  controllers that provide input/output voltage, input/output current,
+  input power and temperature monitoring over the PMBus interface.
+
+  The MAX16545 uses the same programming model as the VT7505.
+
+  Datasheets:
+  https://www.analog.com/media/en/technical-documentation/data-sheets/max16545b-max16545c.pdf
+  https://www.analog.com/media/en/technical-documentation/data-sheets/max16550.pdf
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - adi,max16550
+          - adi,vt7505
+      - items:
+          - const: adi,max16545
+          - const: adi,vt7505
+
+  reg:
+    maxItems: 1
+
+  adi,rload-ohms:
+    description:
+      Resistance in ohms of the external telemetry load resistor connected
+      between the ILOAD current-output pin and ground. This is not a
+      current-path shunt resistor; it sets the scaling of the reported input
+      current, output current and input power.
+    minimum: 1
+    default: 4750
+
+  adi,ocp-severe-filter-us:
+    description:
+      Deglitch time, in microseconds, applied to the severe
+      overcurrent-protection comparator, programmed into the
+      MFR_CONFIG[15:14] field. The MAX16550 and VT7505 expose this field.
+      On the MAX16545 the severe overcurrent delay is fixed and these bits
+      are reserved. If omitted, the existing hardware setting is retained.
+    enum: [0, 1, 2, 10]
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  # The severe OCP deglitch filter is fixed on the MAX16545, so the property
+  # is only valid for the MAX16550 and VT7505.
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: adi,max16545
+    then:
+      properties:
+        adi,ocp-severe-filter-us: false
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        regulator@40 {
+            compatible = "adi,vt7505";
+            reg = <0x40>;
+            adi,rload-ohms = <4750>;
+            adi,ocp-severe-filter-us = <10>;
+        };
+    };
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 0/2] hwmon: (pmbus) Add Analog Devices MAX16545/MAX16550 and Volterra VT7505 driver
From: Pradhan, Sanman @ 2026-07-24 16:49 UTC (permalink / raw)
  To: linux-hwmon@vger.kernel.org
  Cc: linux@roeck-us.net, robh@kernel.org, krzk+dt@kernel.org,
	krzk@kernel.org, conor+dt@kernel.org, corbet@lwn.net,
	skhan@linuxfoundation.org, devicetree@vger.kernel.org,
	linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
	Sanman Pradhan

From: Sanman Pradhan <psanman@juniper.net>

This series adds a PMBus driver for the Analog Devices MAX16545 and
MAX16550, and the Volterra VT7505 controllers.

The driver reports input and output voltage, input and output current,
input power, and temperature over PMBus. All sensors use the direct data
format. Peak input voltage, output voltage, output current, input power
and temperature readings are exposed and can be reset.

The MAX16545 uses the same programming model as the VT7505 and is
described with a fallback compatible.

The current and power scaling depend on the external current-report
resistor on the ILOAD pin, which can be specified with the
"adi,rload-ohms" device tree property. On the MAX16550 and VT7505, the
severe overcurrent-protection deglitch time can optionally be programmed
with the "adi,ocp-severe-filter-us" property; on the MAX16545 that delay
is fixed, so the property is rejected for that part.

The driver was tested on Juniper PTX hardware.

Changes in v3:
- dt-bindings: clarify that adi,rload-ohms is the ILOAD telemetry
  resistor, not a current-path shunt; note that the severe-OCP filter
  retains the existing hardware setting when omitted, and add it to the
  example; move additionalProperties after the allOf block.
- driver: use per-device match data instead of an enum (no zero-valued
  match data), derive the temperature coefficients and severe-OCP filter
  support from it, add an explicit adi,max16545 match entry, and replace
  the SPDX-FileCopyrightText tag with a plain copyright line.

Changes in v2:
- dt-bindings: represent the severe-OCP deglitch filter in microseconds
  (renamed to adi,ocp-severe-filter-us, values 0/1/2/10).
- driver: map the microsecond value to the MFR_CONFIG[15:14] field.



Georgi Vlaev (1):
  hwmon: (pmbus/vt7505) Add driver for Analog Devices MAX16545/MAX16550
    and Volterra VT7505

Sanman Pradhan (1):
  dt-bindings: hwmon: pmbus: Add Analog Devices MAX16545/MAX16550 and
    Volterra VT7505

 .../bindings/hwmon/pmbus/adi,vt7505.yaml      |  84 ++++++
 Documentation/hwmon/index.rst                 |   1 +
 Documentation/hwmon/vt7505.rst                |  89 ++++++
 MAINTAINERS                                   |   8 +
 drivers/hwmon/pmbus/Kconfig                   |   9 +
 drivers/hwmon/pmbus/Makefile                  |   1 +
 drivers/hwmon/pmbus/vt7505.c                  | 284 ++++++++++++++++++
 7 files changed, 476 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/hwmon/pmbus/adi,vt7505.yaml
 create mode 100644 Documentation/hwmon/vt7505.rst
 create mode 100644 drivers/hwmon/pmbus/vt7505.c


base-commit: fa8ff8bde9207509f90adacc157b208ee732adad
-- 
2.34.1


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox