* Re: [PATCH v2 2/5] arm64: dts: rockchip: Enable USB 2.0 ports on Radxa E20C
From: Chukun Pan @ 2026-05-25 6:50 UTC (permalink / raw)
To: heiko; +Cc: jonas, linux-arm-kernel, linux-kernel, linux-rockchip, Chukun Pan
In-Reply-To: <20260505171208.3267387-3-heiko@sntech.de>
Hi,
> +&usb_host0_xhci {
> + extcon = <&usb2phy>;
> + maximum-speed = "high-speed";
> + phys = <&usb2phy_otg>;
> + phy-names = "usb2-phy";
I received this warning for this otg port:
[ 0.163307] dwc3 fe500000.usb: Configuration mismatch. dr_mode forced to host
> + snps,dis_u2_susphy_quirk;
This property is missing in the sige1 patch. Since this property
is related to phy vbus detection, can we move it to rk3528.dtsi?
Thanks,
Chukun
^ permalink raw reply
* Re: [PATCH 1/2] crypto: Delete Qualcomm crypto engine driver
From: Demi Marie Obenour @ 2026-05-25 7:49 UTC (permalink / raw)
To: Kuldeep Singh, Eric Biggers, Krzysztof Kozlowski
Cc: Dmitry Baryshkov, Herbert Xu, David S. Miller, Thara Gopinath,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson,
Konrad Dybcio, Russell King, linux-kernel, linux-crypto,
linux-arm-msm, Ard Biesheuvel, devicetree, linux-arm-kernel
In-Reply-To: <e36172c6-4424-4b77-9b3c-47dcdbdff05b@oss.qualcomm.com>
[-- Attachment #1.1.1: Type: text/plain, Size: 1441 bytes --]
On 5/25/26 02:29, Kuldeep Singh wrote:
>> This driver is more than an order of magnitude slower than the CPU for
>> both encryption and hashing. See:
>>
>> https://lore.kernel.org/r/20250704070322.20692-1-ebiggers@kernel.org/
>> https://lore.kernel.org/r/20250615031807.GA81869@sol/
>>
>> There are many examples of it having bugs as well, for example see the
>> second link above.
>>
>> That's why it had to be disabled via the cra_priority system. This
>> driver was actively making Linux worse.
>>
>> This isn't particularly unique to drivers/crypto/, of course. This one
>> we just have data on, so it's a bit clearer.
>>
>> I've yet to see any real reason to keep this driver.
>
> https://lore.kernel.org/all/c1697372-54ec-4f57-85d9-ad375ff1a44d@oss.qualcomm.com/
> Kindly check my latest reply to the thread. There are numerous usecases
> like DRM(Digital rights management) coming up and qce driver is required
> for secure content.
1. This content is restricted. It's no more secure.
2. General purpose (desktop, laptop) systems won't be able to display
restricted content. To the best of my knowledge, the only Wayland
compositors that support restricted content are Weston and Chromium
OS's compositor.
3. Will this code be useful without out of tree drivers?
4. Does this use the existing crypto APIs or a separate API?
--
Sincerely,
Demi Marie Obenour (she/her/hers)
[-- Attachment #1.1.2: OpenPGP public key --]
[-- Type: application/pgp-keys, Size: 7253 bytes --]
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] drivers/acpi: Move RISC-V interrupt controllers autodep to ACPI IRQ code
From: Lorenzo Pieralisi @ 2026-05-25 8:03 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Len Brown, Sunil V L, Marc Zyngier, Thomas Gleixner, Huacai Chen,
Anup Patel, Hanjun Guo, Sudeep Holla, Catalin Marinas,
Will Deacon, linux-riscv, linux-kernel, linux-acpi,
linux-arm-kernel, loongarch
In-Reply-To: <CAJZ5v0g+bjXdghhb-+iRpFif7TURAmyjotY_4wQ5GHu7V2FaTQ@mail.gmail.com>
On Fri, May 22, 2026 at 07:45:27PM +0200, Rafael J. Wysocki wrote:
> On Tue, May 5, 2026 at 10:48 AM Lorenzo Pieralisi <lpieralisi@kernel.org> wrote:
> >
> > RISC-V implements arch code to detect probe dependencies for devices and
> > the interrupt controller the devices GSIs are routed to.
> >
> > The code itself is arch agnostic apart from an arch specific helper
> > function required to retrieve the acpi_handle of the interrupt controller
> > that manages the device GSI interrupt.
> >
> > In order to enable IRQ probe dependencies detection on other
> > architectures, move RISC-V IRQ probe dependency detection code to
> > generic ACPI IRQ code.
> >
> > RISC-V IRQ code detecting IRQ probe dependency has some limitations/latent
> > bugs:
> >
> > - riscv_acpi_irq_get_dep() would force the loop in
> > riscv_acpi_add_irq_dep() to stop at the first IRQ index that does not
> > map to an interrupt controller handle (missing some possible
> > dependencies)
> > - riscv_acpi_add_prt_dep() does not validate acpi_get_handle() output
> > - riscv_acpi_add_prt_dep() logic to handle memory allocation failure is
> > forcing the loop to continue on the same PRT entry
> >
> > Fix the above limitations along with the code move.
>
> I'd rather do the cleanup first, possibly in multiple steps, and then
> move the code separately.
>
> As it stands, it's quite hard to figure out what's going on and why.
Yes, shortcuts are never a good idea. I will do.
Thanks,
Lorenzo
> > Allow interrupt controller drivers to register an arch specific
> > function to determine the acpi_handle for a specific GSI number to use
> > the mechanism if needed by the respective interrupt controller drivers.
> >
> > Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
> > Cc: Huacai Chen <chenhuacai@kernel.org>
> > Cc: Thomas Gleixner <tglx@kernel.org>
> > Cc: Anup Patel <anup@brainfault.org>
> > Cc: "Rafael J. Wysocki" <rafael@kernel.org>
> > Cc: Sunil V L <sunilvl@ventanamicro.com>
> > Cc: Marc Zyngier <maz@kernel.org>
> > ---
> > arch/riscv/include/asm/acpi.h | 1 +
> > drivers/acpi/irq.c | 172 +++++++++++++++++++++++++++++++++++-
> > drivers/acpi/riscv/irq.c | 141 +----------------------------
> > drivers/irqchip/irq-gic-v3.c | 2 +-
> > drivers/irqchip/irq-gic-v5.c | 2 +-
> > drivers/irqchip/irq-gic.c | 2 +-
> > drivers/irqchip/irq-loongarch-cpu.c | 2 +-
> > drivers/irqchip/irq-riscv-intc.c | 3 +-
> > include/linux/acpi.h | 5 +-
> > 9 files changed, 181 insertions(+), 149 deletions(-)
> >
> > diff --git a/arch/riscv/include/asm/acpi.h b/arch/riscv/include/asm/acpi.h
> > index 26ab37c171bc..f598520ac903 100644
> > --- a/arch/riscv/include/asm/acpi.h
> > +++ b/arch/riscv/include/asm/acpi.h
> > @@ -67,6 +67,7 @@ int acpi_get_riscv_isa(struct acpi_table_header *table,
> >
> > void acpi_get_cbo_block_size(struct acpi_table_header *table, u32 *cbom_size,
> > u32 *cboz_size, u32 *cbop_size);
> > +acpi_handle acpi_get_riscv_gsi_handle(u32 gsi);
> > #else
> > static inline void acpi_init_rintc_map(void) { }
> > static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
> > diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c
> > index d1595156c86a..e4293458bf61 100644
> > --- a/drivers/acpi/irq.c
> > +++ b/drivers/acpi/irq.c
> > @@ -13,6 +13,7 @@
> > enum acpi_irq_model_id acpi_irq_model;
> >
> > static acpi_gsi_domain_disp_fn acpi_get_gsi_domain_id;
> > +static acpi_gsi_handle_disp_fn acpi_get_gsi_handle;
> > static u32 (*acpi_gsi_to_irq_fallback)(u32 gsi);
> >
> > /**
> > @@ -321,15 +322,19 @@ const struct cpumask *acpi_irq_get_affinity(acpi_handle handle,
> >
> > /**
> > * acpi_set_irq_model - Setup the GSI irqdomain information
> > - * @model: the value assigned to acpi_irq_model
> > - * @fn: a dispatcher function that will return the domain fwnode
> > - * for a given GSI
> > + * @model: the value assigned to acpi_irq_model
> > + * @fn: a dispatcher function that will return the domain fwnode
> > + * for a given GSI
> > + * @gsi_dep_fn: a function to retrieve the acpi_handle a GSI interrupt is
> > + * dependent on
> > + *
> > */
> > void __init acpi_set_irq_model(enum acpi_irq_model_id model,
> > - acpi_gsi_domain_disp_fn fn)
> > + acpi_gsi_domain_disp_fn fn, acpi_gsi_handle_disp_fn gsi_dep_fn)
> > {
> > acpi_irq_model = model;
> > acpi_get_gsi_domain_id = fn;
> > + acpi_get_gsi_handle = gsi_dep_fn;
> > }
> >
> > /*
> > @@ -385,3 +390,162 @@ struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags,
> > host_data);
> > }
> > EXPORT_SYMBOL_GPL(acpi_irq_create_hierarchy);
> > +
> > +struct acpi_irq_dep_ctx {
> > + int rc;
> > + unsigned int index;
> > + acpi_handle handle;
> > +};
> > +
> > +static acpi_status acpi_irq_get_parent(struct acpi_resource *ares, void *context)
> > +{
> > + struct acpi_irq_dep_ctx *ctx = context;
> > + struct acpi_resource_irq *irq;
> > + struct acpi_resource_extended_irq *eirq;
> > +
> > + switch (ares->type) {
> > + case ACPI_RESOURCE_TYPE_IRQ:
> > + irq = &ares->data.irq;
> > + if (ctx->index >= irq->interrupt_count) {
> > + ctx->index -= irq->interrupt_count;
> > + return AE_OK;
> > + }
> > + ctx->handle = acpi_get_gsi_handle(irq->interrupts[ctx->index]);
> > + ctx->rc = 0;
> > + return AE_CTRL_TERMINATE;
> > + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > + eirq = &ares->data.extended_irq;
> > + if (eirq->producer_consumer == ACPI_PRODUCER)
> > + return AE_OK;
> > +
> > + if (ctx->index >= eirq->interrupt_count) {
> > + ctx->index -= eirq->interrupt_count;
> > + return AE_OK;
> > + }
> > +
> > + /* Support GSIs only */
> > + if (eirq->resource_source.string_length)
> > + return AE_OK;
> > +
> > + ctx->handle = acpi_get_gsi_handle(eirq->interrupts[ctx->index]);
> > + ctx->rc = 0;
> > + return AE_CTRL_TERMINATE;
> > + }
> > +
> > + return AE_OK;
> > +}
> > +
> > +static int acpi_irq_get_dep(acpi_handle handle, unsigned int index, acpi_handle *gsi_handle)
> > +{
> > + struct acpi_irq_dep_ctx ctx = {-EINVAL, index, NULL};
> > +
> > + if (!gsi_handle)
> > + return -EINVAL;
> > +
> > + acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_get_parent, &ctx);
> > + *gsi_handle = ctx.handle;
> > +
> > + return ctx.rc;
> > +}
> > +
> > +static bool acpi_prt_entry_valid(void *prt_entry)
> > +{
> > + struct acpi_pci_routing_table *entry = prt_entry;
> > +
> > + return entry && entry->length > 0;
> > +}
> > +
> > +static void *acpi_prt_next_entry(void *prt_entry)
> > +{
> > + struct acpi_pci_routing_table *entry = prt_entry;
> > +
> > + return prt_entry + entry->length;
> > +}
> > +
> > +static u32 acpi_add_prt_dep(acpi_handle handle)
> > +{
> > + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> > + struct acpi_pci_routing_table *entry;
> > + struct acpi_handle_list dep_devices;
> > + acpi_handle gsi_handle;
> > + acpi_handle link_handle;
> > + acpi_status status;
> > + u32 count = 0;
> > +
> > + status = acpi_get_irq_routing_table(handle, &buffer);
> > + if (ACPI_FAILURE(status)) {
> > + acpi_handle_err(handle, "failed to get IRQ routing table\n");
> > + kfree(buffer.pointer);
> > + return 0;
> > + }
> > +
> > + entry = buffer.pointer;
> > + for (; acpi_prt_entry_valid(entry); entry = acpi_prt_next_entry(entry)) {
> > + if (entry->source[0]) {
> > + status = acpi_get_handle(handle, entry->source, &link_handle);
> > + if (ACPI_FAILURE(status))
> > + continue;
> > + dep_devices.count = 1;
> > + dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL);
> > + if (!dep_devices.handles) {
> > + acpi_handle_err(handle, "failed to allocate memory\n");
> > + continue;
> > + }
> > +
> > + dep_devices.handles[0] = link_handle;
> > + count += acpi_scan_add_dep(handle, &dep_devices);
> > + } else {
> > + gsi_handle = acpi_get_gsi_handle(entry->source_index);
> > + if (!gsi_handle)
> > + continue;
> > + dep_devices.count = 1;
> > + dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL);
> > + if (!dep_devices.handles) {
> > + acpi_handle_err(handle, "failed to allocate memory\n");
> > + continue;
> > + }
> > +
> > + dep_devices.handles[0] = gsi_handle;
> > + count += acpi_scan_add_dep(handle, &dep_devices);
> > + }
> > + }
> > +
> > + kfree(buffer.pointer);
> > + return count;
> > +}
> > +
> > +static u32 acpi_add_irq_dep(acpi_handle handle)
> > +{
> > + struct acpi_handle_list dep_devices;
> > + acpi_handle gsi_handle;
> > + u32 count = 0;
> > + int i;
> > +
> > + for (i = 0; !acpi_irq_get_dep(handle, i, &gsi_handle); i++) {
> > + if (!gsi_handle)
> > + continue;
> > +
> > + dep_devices.count = 1;
> > + dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL);
> > + if (!dep_devices.handles) {
> > + acpi_handle_err(handle, "failed to allocate memory\n");
> > + continue;
> > + }
> > +
> > + dep_devices.handles[0] = gsi_handle;
> > + count += acpi_scan_add_dep(handle, &dep_devices);
> > + }
> > +
> > + return count;
> > +}
> > +
> > +u32 acpi_irq_add_auto_dep(acpi_handle handle)
> > +{
> > + if (!acpi_get_gsi_handle)
> > + return 0;
> > +
> > + if (acpi_has_method(handle, "_PRT"))
> > + return acpi_add_prt_dep(handle);
> > +
> > + return acpi_add_irq_dep(handle);
> > +}
> > diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c
> > index 9b88d0993e88..da2c42e0ebfd 100644
> > --- a/drivers/acpi/riscv/irq.c
> > +++ b/drivers/acpi/riscv/irq.c
> > @@ -23,12 +23,6 @@ struct riscv_ext_intc_list {
> > struct list_head list;
> > };
> >
> > -struct acpi_irq_dep_ctx {
> > - int rc;
> > - unsigned int index;
> > - acpi_handle handle;
> > -};
> > -
> > LIST_HEAD(ext_intc_list);
> >
> > static int irqchip_cmp_func(const void *in0, const void *in1)
> > @@ -254,7 +248,7 @@ void __init riscv_acpi_init_gsi_mapping(void)
> > acpi_get_devices("RSCV0006", riscv_acpi_create_gsi_map_smsi, NULL, NULL);
> > }
> >
> > -static acpi_handle riscv_acpi_get_gsi_handle(u32 gsi)
> > +acpi_handle acpi_get_riscv_gsi_handle(u32 gsi)
> > {
> > struct riscv_ext_intc_list *ext_intc_element;
> > struct list_head *i;
> > @@ -269,138 +263,7 @@ static acpi_handle riscv_acpi_get_gsi_handle(u32 gsi)
> > return NULL;
> > }
> >
> > -static acpi_status riscv_acpi_irq_get_parent(struct acpi_resource *ares, void *context)
> > -{
> > - struct acpi_irq_dep_ctx *ctx = context;
> > - struct acpi_resource_irq *irq;
> > - struct acpi_resource_extended_irq *eirq;
> > -
> > - switch (ares->type) {
> > - case ACPI_RESOURCE_TYPE_IRQ:
> > - irq = &ares->data.irq;
> > - if (ctx->index >= irq->interrupt_count) {
> > - ctx->index -= irq->interrupt_count;
> > - return AE_OK;
> > - }
> > - ctx->handle = riscv_acpi_get_gsi_handle(irq->interrupts[ctx->index]);
> > - return AE_CTRL_TERMINATE;
> > - case ACPI_RESOURCE_TYPE_EXTENDED_IRQ:
> > - eirq = &ares->data.extended_irq;
> > - if (eirq->producer_consumer == ACPI_PRODUCER)
> > - return AE_OK;
> > -
> > - if (ctx->index >= eirq->interrupt_count) {
> > - ctx->index -= eirq->interrupt_count;
> > - return AE_OK;
> > - }
> > -
> > - /* Support GSIs only */
> > - if (eirq->resource_source.string_length)
> > - return AE_OK;
> > -
> > - ctx->handle = riscv_acpi_get_gsi_handle(eirq->interrupts[ctx->index]);
> > - return AE_CTRL_TERMINATE;
> > - }
> > -
> > - return AE_OK;
> > -}
> > -
> > -static int riscv_acpi_irq_get_dep(acpi_handle handle, unsigned int index, acpi_handle *gsi_handle)
> > -{
> > - struct acpi_irq_dep_ctx ctx = {-EINVAL, index, NULL};
> > -
> > - if (!gsi_handle)
> > - return 0;
> > -
> > - acpi_walk_resources(handle, METHOD_NAME__CRS, riscv_acpi_irq_get_parent, &ctx);
> > - *gsi_handle = ctx.handle;
> > - if (*gsi_handle)
> > - return 1;
> > -
> > - return 0;
> > -}
> > -
> > -static u32 riscv_acpi_add_prt_dep(acpi_handle handle)
> > -{
> > - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
> > - struct acpi_pci_routing_table *entry;
> > - struct acpi_handle_list dep_devices;
> > - acpi_handle gsi_handle;
> > - acpi_handle link_handle;
> > - acpi_status status;
> > - u32 count = 0;
> > -
> > - status = acpi_get_irq_routing_table(handle, &buffer);
> > - if (ACPI_FAILURE(status)) {
> > - acpi_handle_err(handle, "failed to get IRQ routing table\n");
> > - kfree(buffer.pointer);
> > - return 0;
> > - }
> > -
> > - entry = buffer.pointer;
> > - while (entry && (entry->length > 0)) {
> > - if (entry->source[0]) {
> > - acpi_get_handle(handle, entry->source, &link_handle);
> > - dep_devices.count = 1;
> > - dep_devices.handles = kzalloc_objs(*dep_devices.handles,
> > - 1);
> > - if (!dep_devices.handles) {
> > - acpi_handle_err(handle, "failed to allocate memory\n");
> > - continue;
> > - }
> > -
> > - dep_devices.handles[0] = link_handle;
> > - count += acpi_scan_add_dep(handle, &dep_devices);
> > - } else {
> > - gsi_handle = riscv_acpi_get_gsi_handle(entry->source_index);
> > - dep_devices.count = 1;
> > - dep_devices.handles = kzalloc_objs(*dep_devices.handles,
> > - 1);
> > - if (!dep_devices.handles) {
> > - acpi_handle_err(handle, "failed to allocate memory\n");
> > - continue;
> > - }
> > -
> > - dep_devices.handles[0] = gsi_handle;
> > - count += acpi_scan_add_dep(handle, &dep_devices);
> > - }
> > -
> > - entry = (struct acpi_pci_routing_table *)
> > - ((unsigned long)entry + entry->length);
> > - }
> > -
> > - kfree(buffer.pointer);
> > - return count;
> > -}
> > -
> > -static u32 riscv_acpi_add_irq_dep(acpi_handle handle)
> > -{
> > - struct acpi_handle_list dep_devices;
> > - acpi_handle gsi_handle;
> > - u32 count = 0;
> > - int i;
> > -
> > - for (i = 0;
> > - riscv_acpi_irq_get_dep(handle, i, &gsi_handle);
> > - i++) {
> > - dep_devices.count = 1;
> > - dep_devices.handles = kzalloc_objs(*dep_devices.handles, 1);
> > - if (!dep_devices.handles) {
> > - acpi_handle_err(handle, "failed to allocate memory\n");
> > - continue;
> > - }
> > -
> > - dep_devices.handles[0] = gsi_handle;
> > - count += acpi_scan_add_dep(handle, &dep_devices);
> > - }
> > -
> > - return count;
> > -}
> > -
> > u32 arch_acpi_add_auto_dep(acpi_handle handle)
> > {
> > - if (acpi_has_method(handle, "_PRT"))
> > - return riscv_acpi_add_prt_dep(handle);
> > -
> > - return riscv_acpi_add_irq_dep(handle);
> > + return acpi_irq_add_auto_dep(handle);
> > }
> > diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> > index 99444a1b2ffa..2673954d4577 100644
> > --- a/drivers/irqchip/irq-gic-v3.c
> > +++ b/drivers/irqchip/irq-gic-v3.c
> > @@ -2588,7 +2588,7 @@ gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end)
> > if (err)
> > goto out_fwhandle_free;
> >
> > - acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v3_get_gsi_domain_id);
> > + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v3_get_gsi_domain_id, NULL);
> >
> > if (static_branch_likely(&supports_deactivate_key))
> > gic_acpi_setup_kvm_info();
> > diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c
> > index 6b0903be8ebf..03cc2830b260 100644
> > --- a/drivers/irqchip/irq-gic-v5.c
> > +++ b/drivers/irqchip/irq-gic-v5.c
> > @@ -1242,7 +1242,7 @@ static int __init gic_acpi_init(union acpi_subtable_headers *header, const unsig
> > if (ret)
> > goto out_irs;
> >
> > - acpi_set_irq_model(ACPI_IRQ_MODEL_GIC_V5, gic_v5_get_gsi_domain_id);
> > + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC_V5, gic_v5_get_gsi_domain_id, NULL);
> >
> > return 0;
> >
> > diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
> > index ec70c84e9f91..f6bc29f515fb 100644
> > --- a/drivers/irqchip/irq-gic.c
> > +++ b/drivers/irqchip/irq-gic.c
> > @@ -1690,7 +1690,7 @@ static int __init gic_v2_acpi_init(union acpi_subtable_headers *header,
> > return ret;
> > }
> >
> > - acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v2_get_gsi_domain_id);
> > + acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, gic_v2_get_gsi_domain_id, NULL);
> >
> > if (IS_ENABLED(CONFIG_ARM_GIC_V2M))
> > gicv2m_init(NULL, gic_data[0].domain);
> > diff --git a/drivers/irqchip/irq-loongarch-cpu.c b/drivers/irqchip/irq-loongarch-cpu.c
> > index 950bc087e388..84ce24889488 100644
> > --- a/drivers/irqchip/irq-loongarch-cpu.c
> > +++ b/drivers/irqchip/irq-loongarch-cpu.c
> > @@ -168,7 +168,7 @@ static int __init cpuintc_acpi_init(union acpi_subtable_headers *header,
> > panic("Failed to add irqdomain for LoongArch CPU");
> >
> > set_handle_irq(&handle_cpu_irq);
> > - acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id);
> > + acpi_set_irq_model(ACPI_IRQ_MODEL_LPIC, lpic_get_gsi_domain_id, NULL);
> > acpi_set_gsi_to_irq_fallback(lpic_gsi_to_irq);
> > ret = acpi_cascade_irqdomain_init();
> >
> > diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
> > index 84418dbd5a27..0595144116e2 100644
> > --- a/drivers/irqchip/irq-riscv-intc.c
> > +++ b/drivers/irqchip/irq-riscv-intc.c
> > @@ -384,7 +384,8 @@ static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header,
> > if (rc)
> > irq_domain_free_fwnode(fn);
> > else
> > - acpi_set_irq_model(ACPI_IRQ_MODEL_RINTC, riscv_acpi_get_gsi_domain_id);
> > + acpi_set_irq_model(ACPI_IRQ_MODEL_RINTC, riscv_acpi_get_gsi_domain_id,
> > + acpi_get_riscv_gsi_handle);
> >
> > return rc;
> > }
> > diff --git a/include/linux/acpi.h b/include/linux/acpi.h
> > index 67effb91fa98..468fc6a54651 100644
> > --- a/include/linux/acpi.h
> > +++ b/include/linux/acpi.h
> > @@ -360,9 +360,10 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
> > int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
> >
> > typedef struct fwnode_handle *(*acpi_gsi_domain_disp_fn)(u32);
> > +typedef acpi_handle (*acpi_gsi_handle_disp_fn)(u32);
> >
> > void acpi_set_irq_model(enum acpi_irq_model_id model,
> > - acpi_gsi_domain_disp_fn fn);
> > + acpi_gsi_domain_disp_fn fn, acpi_gsi_handle_disp_fn gsi_dep_fn);
> > acpi_gsi_domain_disp_fn acpi_get_gsi_dispatcher(void);
> > void acpi_set_gsi_to_irq_fallback(u32 (*)(u32));
> >
> > @@ -372,6 +373,8 @@ struct irq_domain *acpi_irq_create_hierarchy(unsigned int flags,
> > const struct irq_domain_ops *ops,
> > void *host_data);
> >
> > +u32 acpi_irq_add_auto_dep(acpi_handle handle);
> > +
> > #ifdef CONFIG_X86_IO_APIC
> > extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
> > #else
> >
> > --
> > 2.54.0
> >
^ permalink raw reply
* Re: [PATCH v5 1/3] dt-bindings: mfd: aspeed,ast2x00-scu: Support AST2700 SoC1 pinctrl
From: Linus Walleij @ 2026-05-25 8:03 UTC (permalink / raw)
To: Billy Tsai
Cc: Tony Lindgren, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Bartosz Golaszewski, Lee Jones,
Ryan Chen, patrickw3, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, linux-aspeed, BMC-SW, openbmc, Andrew Jeffery,
linux-clk, Conor Dooley
In-Reply-To: <20260521-pinctrl-single-bit-v5-1-308be2c160fc@aspeedtech.com>
On Thu, May 21, 2026 at 11:17 AM Billy Tsai <billy_tsai@aspeedtech.com> wrote:
> The AST2700 SoC integrates two interconnected SoC instances, each
> managed by its own System Control Unit (SCU).
>
> Allow the AST2700 SoC1 pin controller to be described as a child
> node of the SCU by extending the compatible strings accepted by
> the SCU binding.
>
> There is no functional change to the SCU binding beyond permitting
> the aspeed,ast2700-soc1-pinctrl compatible string.
>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Lee can you pick this up at your convenience?
I'll apply patches 2 & 3.
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH v5 0/3] pinctrl: aspeed: Add AST2700 SoC1 support
From: Linus Walleij @ 2026-05-25 8:06 UTC (permalink / raw)
To: Billy Tsai
Cc: Tony Lindgren, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Bartosz Golaszewski, Lee Jones,
Ryan Chen, patrickw3, linux-gpio, devicetree, linux-kernel,
linux-arm-kernel, linux-aspeed, BMC-SW, openbmc, Andrew Jeffery,
linux-clk, Conor Dooley
In-Reply-To: <20260521-pinctrl-single-bit-v5-0-308be2c160fc@aspeedtech.com>
On Thu, May 21, 2026 at 11:17 AM Billy Tsai <billy_tsai@aspeedtech.com> wrote:
> Legacy ASPEED pin controllers have historically not had a coherent
> register interface. Control fields often had no consistent mapping to
> individual pins, and configuring a function frequently required
> coordinating multiple control bits across several registers. As a
> result, the existing ASPEED pinctrl drivers rely on complex macro
> infrastructure to describe the dependencies between pins, functions,
> and register fields.
>
> The pin controller for SoC1 in the AST2700 breaks from this legacy
> design.
>
> For SoC1, each pin maps directly to a dedicated function field in the
> SCU register space that determines the active mux function for that
> pin. This results in a much more regular register layout compared to
> previous generations.
>
> While the behaviour is conceptually similar to pinctrl-single, the
> register layout and configuration model differ enough that reusing
> pinctrl-single directly is not practical. Therefore this driver is
> implemented as a SoC-specific pinctrl driver using static data tables
> to describe the register layout.
>
> The binding reuses the standard pinmux and generic pin configuration
> schemas and does not introduce any custom Devicetree properties.
>
> Signed-off-by: Billy Tsai <billy_tsai@aspeedtech.com>
Patches 2 & 3 applied to the pinctrl tree, thanks Billy!
Sashiko is moaning about something, look into it but my confidence
is low since it is using weasel words like "critical" for things that are
certainly not critical, if there is some validty to these comments it
can certainly be fixed up in-tree.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v8 0/2] media: nxp: Add CSI Pixel Formatter support
From: Guoniu Zhou @ 2026-05-25 8:12 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
Guoniu Zhou, Frank Li, Krzysztof Kozlowski
CSI Pixel Formatter is a module found on i.MX95. It could unpack the
pixels received by the formatter and reformat them to meet the pixel
link format requirement.
This patch series adds a new V4L2 driver for CSI Pixel Formatter.
v4l2-compliance 1.28.1-5233, 64 bits, 64-bit time_t
v4l2-compliance SHA: fc15e229d9d3 2024-07-23 19:22:15
Compliance test for device /dev/v4l-subdev9:
Driver Info:
Driver version : 7.1.0
Capabilities : 0x00000002
Streams Support
Client Capabilities: 0x0000000000000003
streams interval-uses-which
Required ioctls:
test VIDIOC_SUDBEV_QUERYCAP: OK
test invalid ioctls: OK
Allow for multiple opens:
test second /dev/v4l-subdev9 open: OK
test VIDIOC_SUBDEV_QUERYCAP: OK
test for unlimited opens: OK
Debug ioctls:
test VIDIOC_LOG_STATUS: OK (Not Supported)
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 0
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK (Not Supported)
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Sub-Device routing ioctls:
test Try VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: OK
test Active VIDIOC_SUBDEV_G_ROUTING/VIDIOC_SUBDEV_S_ROUTING: OK
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK (Not Supported)
test VIDIOC_QUERYCTRL: OK (Not Supported)
test VIDIOC_G/S_CTRL: OK (Not Supported)
test VIDIOC_G/S/TRY_EXT_CTRLS: OK (Not Supported)
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK (Not Supported)
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 0 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK (Not Supported)
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
test CREATE_BUFS maximum buffers: OK
test VIDIOC_REMOVE_BUFS: OK
test VIDIOC_EXPBUF: OK (Not Supported)
test Requests: OK (Not Supported)
Total for device /dev/v4l-subdev9: 47, Succeeded: 47, Failed: 0, Warnings: 0
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
Changes in v8:
- Rebase to latest media/next
- Use standard port reference instead of video-interfaces.yaml
- Add parent syscon node in example to show device integration
- Remove fmt field and look up format from subdev state instead
- Unify function and structure naming to use csi_formatter_ prefix
- Remove misleading alignment comment from set_fmt function
- Optimize get_frame_desc to call once per start_stream
- Replace V4L2_FRAME_DESC_ENTRY_MAX with CSI_FORMATTER_VC_NUM in loops
- Remove redundant debug message in enable_streams
- Use MEDIA_PAD_FL_MUST_CONNECT flag instead of manual link check
- Link to v7: https://lore.kernel.org/r/20260518-csi_formatter-v7-0-562b750557e3@oss.nxp.com
Changes in v7:
- Change compatible to imx95-csi-formatter as IP is i.MX95 specific per Marco's suggestion
Link: https://lore.kernel.org/linux-media/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com/T/#mcd135b3de179b3cb69daa1fd6e0e8e27c85b3332
- Update references from imx9 to imx95 for consistency with dt-bindings
- Enable PM runtime before async registration
- Link to v6: https://lore.kernel.org/r/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com
Changes in v6:
- Rebase to latest media/next
- Update v4l2-compliace test
- Remove unused header includes
- Unify macro naming: VCx/VCX -> VC and parameter x -> vc
- Remove unused format field from csi_formatter struct
- Use compact initialization for formats array
- Make find_csi_format() return NULL instead of default format
- Use unsigned int for array index in find_csi_format()
- Add err_ prefix to error handling labels
- Add v4l2_subdev_cleanup() and reorder cleanup sequence
- Update enable_streams debug output format
- Rename VC_MAX to VC_NUM and fix boundary check
- Update CSI formatter Kconfig description
- Use v4l2_subdev_get_frame_desc_passthrough() helper
- Fix error paths in async registration and probe
- Add mutex to protect enabled_streams
- Switch to devm_pm_runtime_enable()
- Remove redundant num_routes check in set_routing
- Optimize get_index_by_dt() and add warning for unsupported type
- csi_formatter_start/stop_stream: Process all streams in mask
- Link to v5: https://lore.kernel.org/r/20260123-csi_formatter-v5-0-d5b803f867bf@nxp.com
Changes in v5:
- Remove CSI_FORMATTER_DRV_NAME macro since only use once.
- Remove sd->owner = THIS_MODULE;
- Simplify code by using DEFINE_RUNTIME_DEV_PM_OPS macro.
- Link to v4: https://lore.kernel.org/r/20260122-csi_formatter-v4-0-6f6fcad1c33a@nxp.com
Changes in v4:
- Rebase to latest media/next.
- Add comments to describe the index field in formatter_dt_to_index_map array.
- Link to v3: https://lore.kernel.org/r/20251219-csi_formatter-v3-0-8680d6d87091@nxp.com
Changes in v3:
- Rename nxp,imx9-csi-formatter.yaml to fsl,imx9-csi-formatter.yaml.
- Drop clock-names property.
- Drop macro IMX95_PD_CAMERA definition and use a constant directly.
[PATCH 1/2] media: dt-bindings: Add CSI Pixel Formatter DT bindings
- Remove the assignment driver.owner = THIS_MODULE.
- Assign struct fwnode_handle *ep __free(fwnode_handle) when definition.
- Update yaml file name for csi formatter in MAINTAINERS.
[PATCH 2/2] media: nxp: Add i.MX9 CSI pixel formatter v4l2 driver
- Link to v2: https://lore.kernel.org/r/20251217-csi_formatter-v2-0-62168af80210@nxp.com
Changes in v2:
- Delete "|" for description key.
- Add empty line between child node and property.
- Delete labels for endpoint of child nodes.
[PATCH 1/2] media: dt-bindings: Add CSI Pixel Formatter DT bindings
- Update commit message.
- Use the value defined by bellow macros directly since they are used only once.
#define CSI_FORMATTER_DEF_MBUS_CODE MEDIA_BUS_FMT_UYVY8_1X16
#define CSI_FORMATTER_DEF_PIX_WIDTH 1920U
#define CSI_FORMATTER_DEF_PIX_HEIGHT 1080U
#define CSI_FORMATTER_MAX_PIX_WIDTH 0xffff
#define CSI_FORMATTER_MAX_PIX_HEIGHT 0xffff
- Use macro pm_ptr() to fix build warning when CONFIG_PM is disabled.
- Finish route loop by break statement, instead of goto.
- Return dev_err_probe() when meet errors in probe() function instead of dev_err().
- Remove MODULE_ALIAS().
- Refine .enable(.dsable)_stream callback implementation, include bellow changes:
Add stream checking.
Fix potential pm runtime count unbalance issue.
Add stop stream error handling when enabling remote subdev stream.
- Use __free(fwnode_handle) to drop reference to a device node automatically.
[PATCH 2/2] media: nxp: Add i.MX9 CSI pixel formatter v4l2 driver
- Link to v1: https://lore.kernel.org/r/20251203-csi_formatter-v1-0-eb9e1147b49e@nxp.com
---
Guoniu Zhou (2):
media: dt-bindings: Add CSI Pixel Formatter DT bindings
media: nxp: Add i.MX95 CSI pixel formatter v4l2 driver
.../bindings/media/fsl,imx95-csi-formatter.yaml | 92 +++
MAINTAINERS | 8 +
drivers/media/platform/nxp/Kconfig | 14 +
drivers/media/platform/nxp/Makefile | 1 +
drivers/media/platform/nxp/imx95-csi-formatter.c | 757 +++++++++++++++++++++
5 files changed, 872 insertions(+)
---
base-commit: a3d78e74dd3ed04797ea351edb7f0a19b961c063
change-id: 20251125-csi_formatter-e6d29316dce6
Best regards,
--
Guoniu Zhou <guoniu.zhou@oss.nxp.com>
^ permalink raw reply
* [PATCH v8 1/2] media: dt-bindings: Add CSI Pixel Formatter DT bindings
From: Guoniu Zhou @ 2026-05-25 8:12 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
Guoniu Zhou, Frank Li, Krzysztof Kozlowski
In-Reply-To: <20260525-csi_formatter-v8-0-6b646231224b@oss.nxp.com>
From: Guoniu Zhou <guoniu.zhou@nxp.com>
The i.MX95 CSI pixel formatting module uses packet info, pixel and
non-pixel data from the CSI-2 host controller and reformat them to
match Pixel Link(PL) definition.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
Changes in v8:
- Use standard port reference instead of video-interfaces.yaml
- Add parent syscon node in example to show device integration
- Add required constraints for port@0 and port@1 in ports node
Changes in v7:
- Change compatible to imx95-csi-formatter as IP is i.MX95 specific per Marco's suggestion
Link: https://lore.kernel.org/linux-media/20260511-csi_formatter-v6-0-01028e312e2b@oss.nxp.com/T/#mcd135b3de179b3cb69daa1fd6e0e8e27c85b3332
---
.../bindings/media/fsl,imx95-csi-formatter.yaml | 92 ++++++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml b/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
new file mode 100644
index 000000000000..bc2f5d448fe5
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
@@ -0,0 +1,92 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/fsl,imx95-csi-formatter.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: i.MX95 CSI Pixel Formatter
+
+maintainers:
+ - Guoniu Zhou <guoniu.zhou@nxp.com>
+
+description:
+ The CSI pixel formatting module found on i.MX95 uses packet info, pixel
+ and non-pixel data from the CSI-2 host controller and reformat them to
+ match Pixel Link(PL) definition.
+
+properties:
+ compatible:
+ const: fsl,imx95-csi-formatter
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ power-domains:
+ maxItems: 1
+
+ ports:
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port@0:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: MIPI CSI-2 RX IDI interface
+
+ port@1:
+ $ref: /schemas/graph.yaml#/properties/port
+ description: Pixel Link Interface
+
+ required:
+ - port@0
+ - port@1
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - power-domains
+ - ports
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/clock/nxp,imx95-clock.h>
+
+ syscon@4ac10000 {
+ compatible = "nxp,imx95-camera-csr", "syscon";
+ reg = <0x0 0x4ac10000 0x0 0x10000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ formatter@20 {
+ compatible = "fsl,imx95-csi-formatter";
+ reg = <0x20 0x100>;
+ clocks = <&cameramix_csr IMX95_CLK_CAMBLK_CSI2_FOR0>;
+ power-domains = <&scmi_devpd 3>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ endpoint {
+ remote-endpoint = <&mipi_csi_0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ endpoint {
+ remote-endpoint = <&isi_in_2>;
+ };
+ };
+ };
+ };
+ };
--
2.34.1
^ permalink raw reply related
* [PATCH v8 2/2] media: nxp: Add i.MX95 CSI pixel formatter v4l2 driver
From: Guoniu Zhou @ 2026-05-25 8:12 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Shawn Guo, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Laurent Pinchart, Frank Li
Cc: imx, linux-media, devicetree, linux-arm-kernel, linux-kernel,
Guoniu Zhou, Frank Li
In-Reply-To: <20260525-csi_formatter-v8-0-6b646231224b@oss.nxp.com>
From: Guoniu Zhou <guoniu.zhou@nxp.com>
The CSI pixel formatter is a module found on i.MX95 used to reformat
packet info, pixel and non-pixel data from CSI-2 host controller to
match Pixel Link(PL) definition.
Add data formatting support.
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Guoniu Zhou <guoniu.zhou@nxp.com>
---
Changes in v8:
- Remove fmt field and look up format from subdev state instead
- Unify function and structure naming to use csi_formatter_ prefix
- Remove misleading alignment comment from set_fmt function
- Optimize get_frame_desc to call once per start_stream
- Replace V4L2_FRAME_DESC_ENTRY_MAX with CSI_FORMATTER_VC_NUM in loops
- Remove redundant debug message in enable_streams
- Use MEDIA_PAD_FL_MUST_CONNECT flag instead of manual link check
- Fix typo: Formater -> Formatter in Kconfig help text
- Improve grammar in data type index mapping comment
Changes in v7:
- Update references from imx9 to imx95 for consistency with dt-bindings
- Enable PM runtime before async registration
Changes in v6:
- Remove unused header includes
- Unify macro naming: VCx/VCX -> VC and parameter x -> vc
- Remove unused format field from csi_formatter struct
- Use compact initialization for formats array
- Make find_csi_format() return NULL instead of default format
- Use unsigned int for array index in find_csi_format()
- Add err_ prefix to error handling labels
- Add v4l2_subdev_cleanup() and reorder cleanup sequence
- Update enable_streams debug output format
- Rename VC_MAX to VC_NUM and fix boundary check
- Update CSI formatter Kconfig description
- Use v4l2_subdev_get_frame_desc_passthrough() helper
- Fix error paths in async registration and probe
- Add mutex to protect enabled_streams
- Switch to devm_pm_runtime_enable()
- Remove redundant num_routes check in set_routing
- Optimize get_index_by_dt() and add warning for unsupported type
- csi_formatter_start/stop_stream: Process all streams in mask
---
MAINTAINERS | 8 +
drivers/media/platform/nxp/Kconfig | 14 +
drivers/media/platform/nxp/Makefile | 1 +
drivers/media/platform/nxp/imx95-csi-formatter.c | 757 +++++++++++++++++++++++
4 files changed, 780 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 3124500ff432..5229b75d930a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19269,6 +19269,14 @@ S: Maintained
F: Documentation/devicetree/bindings/media/nxp,imx8-jpeg.yaml
F: drivers/media/platform/nxp/imx-jpeg
+NXP i.MX 95 CSI PIXEL FORMATTER V4L2 DRIVER
+M: Guoniu Zhou <guoniu.zhou@nxp.com>
+L: imx@lists.linux.dev
+L: linux-media@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/media/fsl,imx95-csi-formatter.yaml
+F: drivers/media/platform/nxp/imx95-csi-formatter.c
+
NXP i.MX CLOCK DRIVERS
M: Abel Vesa <abelvesa@kernel.org>
R: Peng Fan <peng.fan@nxp.com>
diff --git a/drivers/media/platform/nxp/Kconfig b/drivers/media/platform/nxp/Kconfig
index 40e3436669e2..1eccf128d149 100644
--- a/drivers/media/platform/nxp/Kconfig
+++ b/drivers/media/platform/nxp/Kconfig
@@ -28,6 +28,20 @@ config VIDEO_IMX8MQ_MIPI_CSI2
Video4Linux2 driver for the MIPI CSI-2 receiver found on the i.MX8MQ
SoC.
+config VIDEO_IMX95_CSI_FORMATTER
+ tristate "NXP i.MX95 CSI Pixel Formatter driver"
+ depends on ARCH_MXC || COMPILE_TEST
+ depends on VIDEO_DEV
+ select MEDIA_CONTROLLER
+ select V4L2_FWNODE
+ select VIDEO_V4L2_SUBDEV_API
+ help
+ This driver provides support for the CSI Pixel Formatter found on
+ i.MX95 series SoCs. This module unpacks the pixels received from the
+ CSI-2 interface and reformats them to meet pixel link requirements.
+
+ Say Y here to enable CSI Pixel Formatter module for i.MX95 SoC.
+
config VIDEO_IMX_MIPI_CSIS
tristate "NXP MIPI CSI-2 CSIS receiver found on i.MX7 and i.MX8 models"
depends on ARCH_MXC || COMPILE_TEST
diff --git a/drivers/media/platform/nxp/Makefile b/drivers/media/platform/nxp/Makefile
index 4d90eb713652..6410115d870e 100644
--- a/drivers/media/platform/nxp/Makefile
+++ b/drivers/media/platform/nxp/Makefile
@@ -6,6 +6,7 @@ obj-y += imx8-isi/
obj-$(CONFIG_VIDEO_IMX7_CSI) += imx7-media-csi.o
obj-$(CONFIG_VIDEO_IMX8MQ_MIPI_CSI2) += imx8mq-mipi-csi2.o
+obj-$(CONFIG_VIDEO_IMX95_CSI_FORMATTER) += imx95-csi-formatter.o
obj-$(CONFIG_VIDEO_IMX_MIPI_CSIS) += imx-mipi-csis.o
obj-$(CONFIG_VIDEO_IMX_PXP) += imx-pxp.o
obj-$(CONFIG_VIDEO_MX2_EMMAPRP) += mx2_emmaprp.o
diff --git a/drivers/media/platform/nxp/imx95-csi-formatter.c b/drivers/media/platform/nxp/imx95-csi-formatter.c
new file mode 100644
index 000000000000..671979444d48
--- /dev/null
+++ b/drivers/media/platform/nxp/imx95-csi-formatter.c
@@ -0,0 +1,757 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2025 NXP
+ */
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+
+#include <media/mipi-csi2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
+#include <media/v4l2-fwnode.h>
+#include <media/v4l2-mc.h>
+#include <media/v4l2-subdev.h>
+
+/* CSI Pixel Formatter registers map */
+
+#define CSI_VC_INTERLACED_LINE_CNT(vc) (0x00 + (vc) * 0x04)
+#define INTERLACED_ODD_LINE_CNT_SET(x) FIELD_PREP(GENMASK(13, 0), (x))
+#define INTERLACED_EVEN_LINE_CNT_SET(x) FIELD_PREP(GENMASK(29, 16), (x))
+
+#define CSI_VC_INTERLACED_CTRL 0x20
+
+#define CSI_VC_INTERLACED_ERR 0x24
+#define CSI_VC_ERR_MASK GENMASK(7, 0)
+#define CSI_VC_ERR(vc) BIT((vc))
+
+#define CSI_VC_YUV420_FIRST_LINE_EVEN 0x28
+#define YUV420_FIRST_LINE_EVEN(vc) BIT((vc))
+
+#define CSI_RAW32_CTRL 0x30
+#define CSI_VC_RAW32_MODE(vc) BIT((vc))
+#define CSI_VC_RAW32_SWAP_MODE(vc) BIT((vc) + 8)
+
+#define CSI_STREAM_FENCING_CTRL 0x34
+#define CSI_VC_STREAM_FENCING(vc) BIT((vc))
+#define CSI_VC_STREAM_FENCING_RST(vc) BIT((vc) + 8)
+
+#define CSI_STREAM_FENCING_STS 0x38
+#define CSI_STREAM_FENCING_STS_MASK GENMASK(7, 0)
+
+#define CSI_VC_NON_PIXEL_DATA_TYPE(vc) (0x40 + (vc) * 0x04)
+
+#define CSI_VC_PIXEL_DATA_CTRL(vc) (0x60 + (vc) * 0x04)
+#define NEW_VC(vc) FIELD_PREP(GENMASK(3, 1), vc)
+#define REROUTE_VC_ENABLE BIT(0)
+
+#define CSI_VC_ROUTE_PIXEL_DATA_TYPE(vc) (0x80 + (vc) * 0x04)
+
+#define CSI_VC_NON_PIXEL_DATA_CTRL(vc) (0xa0 + (vc) * 0x04)
+
+#define CSI_VC_PIXEL_DATA_TYPE(vc) (0xc0 + (vc) * 0x04)
+
+#define CSI_VC_PIXEL_DATA_TYPE_ERR(vc) (0xe0 + (vc) * 0x04)
+
+#define CSI_FORMATTER_PAD_SINK 0
+#define CSI_FORMATTER_PAD_SOURCE 1
+#define CSI_FORMATTER_PAD_NUM 2
+
+#define CSI_FORMATTER_VC_NUM 8 /* Number of virtual channels */
+
+struct csi_formatter_pix_format {
+ u32 code;
+ u32 data_type;
+};
+
+struct csi_formatter {
+ struct device *dev;
+ struct regmap *regs;
+ struct clk *clk;
+
+ struct v4l2_subdev sd;
+ struct v4l2_subdev *csi_sd;
+ struct v4l2_async_notifier notifier;
+ struct media_pad pads[CSI_FORMATTER_PAD_NUM];
+
+ u32 remote_pad;
+ u32 reg_offset;
+
+ /* Protects enabled_streams */
+ struct mutex lock;
+ u64 enabled_streams;
+};
+
+struct csi_formatter_dt_index {
+ u8 dtype;
+ u8 index;
+};
+
+/*
+ * The index corresponds to the bit index in the register that enables
+ * the data type of pixel data transported by the Formatter.
+ */
+static const struct csi_formatter_dt_index formatter_dt_to_index_map[] = {
+ { .dtype = MIPI_CSI2_DT_YUV420_8B, .index = 0 },
+ { .dtype = MIPI_CSI2_DT_YUV420_8B_LEGACY, .index = 2 },
+ { .dtype = MIPI_CSI2_DT_YUV422_8B, .index = 6 },
+ { .dtype = MIPI_CSI2_DT_RGB444, .index = 8 },
+ { .dtype = MIPI_CSI2_DT_RGB555, .index = 9 },
+ { .dtype = MIPI_CSI2_DT_RGB565, .index = 10 },
+ { .dtype = MIPI_CSI2_DT_RGB666, .index = 11 },
+ { .dtype = MIPI_CSI2_DT_RGB888, .index = 12 },
+ { .dtype = MIPI_CSI2_DT_RAW6, .index = 16 },
+ { .dtype = MIPI_CSI2_DT_RAW7, .index = 17 },
+ { .dtype = MIPI_CSI2_DT_RAW8, .index = 18 },
+ { .dtype = MIPI_CSI2_DT_RAW10, .index = 19 },
+ { .dtype = MIPI_CSI2_DT_RAW12, .index = 20 },
+ { .dtype = MIPI_CSI2_DT_RAW14, .index = 21 },
+ { .dtype = MIPI_CSI2_DT_RAW16, .index = 22 },
+};
+
+static const struct csi_formatter_pix_format formats[] = {
+ /* YUV formats */
+ { MEDIA_BUS_FMT_UYVY8_1X16, MIPI_CSI2_DT_YUV422_8B },
+ /* RGB formats */
+ { MEDIA_BUS_FMT_RGB565_1X16, MIPI_CSI2_DT_RGB565 },
+ { MEDIA_BUS_FMT_RGB888_1X24, MIPI_CSI2_DT_RGB888 },
+ /* RAW (Bayer and greyscale) formats */
+ { MEDIA_BUS_FMT_SBGGR8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SGBRG8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SGRBG8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SRGGB8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_Y8_1X8, MIPI_CSI2_DT_RAW8 },
+ { MEDIA_BUS_FMT_SBGGR10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SGBRG10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SGRBG10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SRGGB10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_Y10_1X10, MIPI_CSI2_DT_RAW10 },
+ { MEDIA_BUS_FMT_SBGGR12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SGBRG12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SGRBG12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SRGGB12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_Y12_1X12, MIPI_CSI2_DT_RAW12 },
+ { MEDIA_BUS_FMT_SBGGR14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SGBRG14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SGRBG14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SRGGB14_1X14, MIPI_CSI2_DT_RAW14 },
+ { MEDIA_BUS_FMT_SBGGR16_1X16, MIPI_CSI2_DT_RAW16 },
+ { MEDIA_BUS_FMT_SGBRG16_1X16, MIPI_CSI2_DT_RAW16 },
+ { MEDIA_BUS_FMT_SGRBG16_1X16, MIPI_CSI2_DT_RAW16 },
+ { MEDIA_BUS_FMT_SRGGB16_1X16, MIPI_CSI2_DT_RAW16 },
+};
+
+static const struct v4l2_mbus_framefmt formatter_default_fmt = {
+ .code = MEDIA_BUS_FMT_UYVY8_1X16,
+ .width = 1920U,
+ .height = 1080U,
+ .field = V4L2_FIELD_NONE,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
+ .xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+ .ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(V4L2_COLORSPACE_SMPTE170M),
+ .quantization = V4L2_QUANTIZATION_LIM_RANGE,
+};
+
+static const struct csi_formatter_pix_format *csi_formatter_find_format(u32 code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formats); i++)
+ if (code == formats[i].code)
+ return &formats[i];
+
+ return NULL;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev operations
+ */
+
+static inline struct csi_formatter *sd_to_formatter(struct v4l2_subdev *sdev)
+{
+ return container_of(sdev, struct csi_formatter, sd);
+}
+
+static int __csi_formatter_subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ struct v4l2_subdev_krouting *routing)
+{
+ int ret;
+
+ ret = v4l2_subdev_routing_validate(sd, routing,
+ V4L2_SUBDEV_ROUTING_ONLY_1_TO_1);
+ if (ret)
+ return ret;
+
+ return v4l2_subdev_set_routing_with_fmt(sd, state, routing,
+ &formatter_default_fmt);
+}
+
+static int csi_formatter_subdev_init_state(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state)
+{
+ struct v4l2_subdev_route routes[] = {
+ {
+ .sink_pad = CSI_FORMATTER_PAD_SINK,
+ .sink_stream = 0,
+ .source_pad = CSI_FORMATTER_PAD_SOURCE,
+ .source_stream = 0,
+ .flags = V4L2_SUBDEV_ROUTE_FL_ACTIVE,
+ },
+ };
+
+ struct v4l2_subdev_krouting routing = {
+ .num_routes = ARRAY_SIZE(routes),
+ .routes = routes,
+ };
+
+ return __csi_formatter_subdev_set_routing(sd, sd_state, &routing);
+}
+
+static int csi_formatter_subdev_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ if (code->pad == CSI_FORMATTER_PAD_SOURCE) {
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (code->index > 0)
+ return -EINVAL;
+
+ fmt = v4l2_subdev_state_get_format(sd_state, code->pad,
+ code->stream);
+ code->code = fmt->code;
+ return 0;
+ }
+
+ if (code->index >= ARRAY_SIZE(formats))
+ return -EINVAL;
+
+ code->code = formats[code->index].code;
+
+ return 0;
+}
+
+static int csi_formatter_subdev_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_format *sdformat)
+{
+ struct csi_formatter_pix_format const *format;
+ struct v4l2_mbus_framefmt *fmt;
+
+ if (sdformat->pad == CSI_FORMATTER_PAD_SOURCE)
+ return v4l2_subdev_get_fmt(sd, sd_state, sdformat);
+
+ format = csi_formatter_find_format(sdformat->format.code);
+ if (!format)
+ format = &formats[0];
+
+ v4l_bound_align_image(&sdformat->format.width, 1, 0xffff, 2,
+ &sdformat->format.height, 1, 0xffff, 0, 0);
+
+ fmt = v4l2_subdev_state_get_format(sd_state, sdformat->pad,
+ sdformat->stream);
+ *fmt = sdformat->format;
+
+ /* Set default code if user set an invalid value */
+ fmt->code = format->code;
+
+ /* Propagate the format from sink stream to source stream */
+ fmt = v4l2_subdev_state_get_opposite_stream_format(sd_state, sdformat->pad,
+ sdformat->stream);
+ if (!fmt)
+ return -EINVAL;
+
+ *fmt = sdformat->format;
+
+ return 0;
+}
+
+static int csi_formatter_subdev_set_routing(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ enum v4l2_subdev_format_whence which,
+ struct v4l2_subdev_krouting *routing)
+{
+ if (which == V4L2_SUBDEV_FORMAT_ACTIVE &&
+ media_entity_is_streaming(&sd->entity))
+ return -EBUSY;
+
+ return __csi_formatter_subdev_set_routing(sd, state, routing);
+}
+
+static inline void csi_formatter_write(struct csi_formatter *formatter,
+ unsigned int reg, unsigned int value)
+{
+ u32 offset = formatter->reg_offset;
+
+ regmap_write(formatter->regs, reg + offset, value);
+}
+
+static u8 csi_formatter_get_index_by_dt(u8 data_type)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(formatter_dt_to_index_map); ++i) {
+ const struct csi_formatter_dt_index *entry =
+ &formatter_dt_to_index_map[i];
+
+ if (data_type == entry->dtype)
+ return entry->index;
+ }
+
+ pr_warn_once("Unsupported data type 0x%x, using default\n", data_type);
+
+ return formatter_dt_to_index_map[0].index;
+}
+
+static int csi_formatter_get_vc(struct csi_formatter *formatter,
+ struct v4l2_mbus_frame_desc *fd,
+ unsigned int stream)
+{
+ struct v4l2_mbus_frame_desc_entry *entry = NULL;
+ unsigned int i;
+ int vc;
+
+ for (i = 0; i < fd->num_entries; ++i) {
+ if (fd->entry[i].stream == stream) {
+ entry = &fd->entry[i];
+ break;
+ }
+ }
+
+ if (!entry) {
+ dev_err(formatter->dev,
+ "No frame desc entry for stream %u\n", stream);
+ return -EPIPE;
+ }
+
+ vc = entry->bus.csi2.vc;
+
+ if (vc < 0 || vc >= CSI_FORMATTER_VC_NUM) {
+ dev_err(formatter->dev, "Invalid virtual channel %d\n", vc);
+ return -EINVAL;
+ }
+
+ return vc;
+}
+
+static void csi_formatter_stop_stream(struct csi_formatter *formatter,
+ u64 stream_mask)
+{
+ unsigned int i;
+
+ for (i = 0; i < CSI_FORMATTER_VC_NUM; ++i) {
+ if (!(stream_mask & BIT(i)))
+ continue;
+
+ csi_formatter_write(formatter, CSI_VC_PIXEL_DATA_TYPE(i), 0);
+ }
+}
+
+static int csi_formatter_start_stream(struct csi_formatter *formatter,
+ struct v4l2_subdev_state *state,
+ u64 stream_mask)
+{
+ const struct csi_formatter_pix_format *pix_fmt;
+ struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_mbus_frame_desc fd = {};
+ u64 configured_streams = 0;
+ unsigned int i;
+ u32 val;
+ int vc;
+ int ret;
+
+ ret = v4l2_subdev_call(formatter->csi_sd, pad, get_frame_desc,
+ formatter->remote_pad, &fd);
+ if (ret < 0 && ret != -ENOIOCTLCMD) {
+ dev_err(formatter->dev, "Failed to get frame desc: %d\n", ret);
+ return ret;
+ }
+
+ for (i = 0; i < CSI_FORMATTER_VC_NUM; ++i) {
+ if (!(stream_mask & BIT(i)))
+ continue;
+
+ fmt = v4l2_subdev_state_get_format(state,
+ CSI_FORMATTER_PAD_SINK, i);
+
+ pix_fmt = csi_formatter_find_format(fmt->code);
+
+ val = BIT(csi_formatter_get_index_by_dt(pix_fmt->data_type));
+
+ if (ret == -ENOIOCTLCMD) {
+ /*
+ * Source doesn't implement get_frame_desc, use
+ * default VC 0
+ */
+ vc = 0;
+ } else {
+ vc = csi_formatter_get_vc(formatter, &fd, i);
+ if (vc < 0) {
+ ret = vc;
+ goto err_cleanup;
+ }
+ }
+
+ csi_formatter_write(formatter, CSI_VC_PIXEL_DATA_TYPE(vc), val);
+ configured_streams |= BIT(i);
+ }
+
+ return 0;
+
+err_cleanup:
+ csi_formatter_stop_stream(formatter, configured_streams);
+ return ret;
+}
+
+static int csi_formatter_subdev_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+ struct device *dev = formatter->dev;
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ CSI_FORMATTER_PAD_SOURCE,
+ CSI_FORMATTER_PAD_SINK,
+ &streams_mask);
+ if (!sink_streams || !streams_mask)
+ return -EINVAL;
+
+ guard(mutex)(&formatter->lock);
+
+ if (!formatter->enabled_streams) {
+ ret = pm_runtime_resume_and_get(formatter->dev);
+ if (ret < 0) {
+ dev_err(dev, "Failed to resume runtime PM: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = csi_formatter_start_stream(formatter, state, streams_mask);
+ if (ret)
+ goto err_runtime_put;
+
+ ret = v4l2_subdev_enable_streams(formatter->csi_sd,
+ formatter->remote_pad,
+ sink_streams);
+ if (ret)
+ goto err_stop_stream;
+
+ formatter->enabled_streams |= streams_mask;
+
+ return 0;
+
+err_stop_stream:
+ csi_formatter_stop_stream(formatter, streams_mask);
+err_runtime_put:
+ if (!formatter->enabled_streams)
+ pm_runtime_put(formatter->dev);
+ return ret;
+}
+
+static int csi_formatter_subdev_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state,
+ u32 pad, u64 streams_mask)
+{
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+ u64 sink_streams;
+ int ret;
+
+ sink_streams = v4l2_subdev_state_xlate_streams(state,
+ CSI_FORMATTER_PAD_SOURCE,
+ CSI_FORMATTER_PAD_SINK,
+ &streams_mask);
+ if (!sink_streams || !streams_mask)
+ return -EINVAL;
+
+ guard(mutex)(&formatter->lock);
+
+ ret = v4l2_subdev_disable_streams(formatter->csi_sd, formatter->remote_pad,
+ sink_streams);
+ if (ret)
+ dev_err(formatter->dev, "Failed to disable streams: %d\n", ret);
+
+ csi_formatter_stop_stream(formatter, streams_mask);
+
+ formatter->enabled_streams &= ~streams_mask;
+
+ if (!formatter->enabled_streams)
+ pm_runtime_put(formatter->dev);
+
+ return ret;
+}
+
+static const struct v4l2_subdev_pad_ops formatter_subdev_pad_ops = {
+ .enum_mbus_code = csi_formatter_subdev_enum_mbus_code,
+ .get_fmt = v4l2_subdev_get_fmt,
+ .set_fmt = csi_formatter_subdev_set_fmt,
+ .get_frame_desc = v4l2_subdev_get_frame_desc_passthrough,
+ .set_routing = csi_formatter_subdev_set_routing,
+ .enable_streams = csi_formatter_subdev_enable_streams,
+ .disable_streams = csi_formatter_subdev_disable_streams,
+};
+
+static const struct v4l2_subdev_ops formatter_subdev_ops = {
+ .pad = &formatter_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops formatter_internal_ops = {
+ .init_state = csi_formatter_subdev_init_state,
+};
+
+/* -----------------------------------------------------------------------------
+ * Media entity operations
+ */
+
+static const struct media_entity_operations formatter_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+ .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
+};
+
+static int csi_formatter_subdev_init(struct csi_formatter *formatter)
+{
+ struct v4l2_subdev *sd = &formatter->sd;
+ int ret;
+
+ v4l2_subdev_init(sd, &formatter_subdev_ops);
+
+ snprintf(sd->name, sizeof(sd->name), "%s", dev_name(formatter->dev));
+ sd->internal_ops = &formatter_internal_ops;
+
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
+ V4L2_SUBDEV_FL_HAS_EVENTS |
+ V4L2_SUBDEV_FL_STREAMS;
+ sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
+ sd->entity.ops = &formatter_entity_ops;
+ sd->dev = formatter->dev;
+
+ formatter->pads[CSI_FORMATTER_PAD_SINK].flags = MEDIA_PAD_FL_SINK
+ | MEDIA_PAD_FL_MUST_CONNECT;
+ formatter->pads[CSI_FORMATTER_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+
+ ret = media_entity_pads_init(&sd->entity, CSI_FORMATTER_PAD_NUM,
+ formatter->pads);
+ if (ret) {
+ dev_err(formatter->dev, "Failed to init pads\n");
+ return ret;
+ }
+
+ ret = v4l2_subdev_init_finalize(sd);
+ if (ret)
+ media_entity_cleanup(&sd->entity);
+
+ return ret;
+}
+
+static inline struct csi_formatter *
+notifier_to_csi_formatter(struct v4l2_async_notifier *n)
+{
+ return container_of(n, struct csi_formatter, notifier);
+}
+
+static int csi_formatter_notify_bound(struct v4l2_async_notifier *notifier,
+ struct v4l2_subdev *sd,
+ struct v4l2_async_connection *asc)
+{
+ const unsigned int link_flags = MEDIA_LNK_FL_IMMUTABLE
+ | MEDIA_LNK_FL_ENABLED;
+ struct csi_formatter *formatter = notifier_to_csi_formatter(notifier);
+ struct v4l2_subdev *sdev = &formatter->sd;
+ struct media_pad *sink = &sdev->entity.pads[CSI_FORMATTER_PAD_SINK];
+ struct media_pad *remote_pad;
+ int ret;
+
+ formatter->csi_sd = sd;
+
+ dev_dbg(formatter->dev, "Bound subdev: %s pad\n", sd->name);
+
+ ret = v4l2_create_fwnode_links_to_pad(sd, sink, link_flags);
+ if (ret < 0)
+ return ret;
+
+ remote_pad = media_pad_remote_pad_first(sink);
+ if (!remote_pad) {
+ dev_err(formatter->dev, "Pipe not setup correctly\n");
+ return -EPIPE;
+ }
+ formatter->remote_pad = remote_pad->index;
+
+ return 0;
+}
+
+static const struct v4l2_async_notifier_operations formatter_notify_ops = {
+ .bound = csi_formatter_notify_bound,
+};
+
+static int csi_formatter_async_register(struct csi_formatter *formatter)
+{
+ struct device *dev = formatter->dev;
+ struct v4l2_async_connection *asc;
+ int ret;
+
+ struct fwnode_handle *ep __free(fwnode_handle) =
+ fwnode_graph_get_endpoint_by_id(dev_fwnode(dev), 0, 0,
+ FWNODE_GRAPH_ENDPOINT_NEXT);
+ if (!ep)
+ return -ENOTCONN;
+
+ v4l2_async_subdev_nf_init(&formatter->notifier, &formatter->sd);
+
+ asc = v4l2_async_nf_add_fwnode_remote(&formatter->notifier, ep,
+ struct v4l2_async_connection);
+ if (IS_ERR(asc)) {
+ ret = PTR_ERR(asc);
+ goto err_cleanup_notifier;
+ }
+
+ formatter->notifier.ops = &formatter_notify_ops;
+
+ ret = v4l2_async_nf_register(&formatter->notifier);
+ if (ret)
+ goto err_cleanup_notifier;
+
+ ret = v4l2_async_register_subdev(&formatter->sd);
+ if (ret)
+ goto err_unregister_notifier;
+
+ return 0;
+
+err_unregister_notifier:
+ v4l2_async_nf_unregister(&formatter->notifier);
+err_cleanup_notifier:
+ v4l2_async_nf_cleanup(&formatter->notifier);
+ return ret;
+}
+
+static void csi_formatter_async_unregister(struct csi_formatter *formatter)
+{
+ v4l2_async_unregister_subdev(&formatter->sd);
+ v4l2_async_nf_unregister(&formatter->notifier);
+ v4l2_async_nf_cleanup(&formatter->notifier);
+}
+
+/* -----------------------------------------------------------------------------
+ * Suspend/resume
+ */
+
+static int csi_formatter_runtime_suspend(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+
+ clk_disable_unprepare(formatter->clk);
+
+ return 0;
+}
+
+static int csi_formatter_runtime_resume(struct device *dev)
+{
+ struct v4l2_subdev *sd = dev_get_drvdata(dev);
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+
+ return clk_prepare_enable(formatter->clk);
+}
+
+static DEFINE_RUNTIME_DEV_PM_OPS(csi_formatter_pm_ops,
+ csi_formatter_runtime_suspend,
+ csi_formatter_runtime_resume, NULL);
+
+static int csi_formatter_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct csi_formatter *formatter;
+ u32 val;
+ int ret;
+
+ formatter = devm_kzalloc(dev, sizeof(*formatter), GFP_KERNEL);
+ if (!formatter)
+ return -ENOMEM;
+
+ formatter->dev = dev;
+
+ ret = devm_mutex_init(dev, &formatter->lock);
+ if (ret)
+ return ret;
+
+ formatter->regs = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(formatter->regs))
+ return dev_err_probe(dev, PTR_ERR(formatter->regs),
+ "Failed to get csi formatter regmap\n");
+
+ ret = of_property_read_u32(dev->of_node, "reg", &val);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to get csi formatter reg property\n");
+
+ formatter->reg_offset = val;
+
+ formatter->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(formatter->clk))
+ return dev_err_probe(dev, PTR_ERR(formatter->clk),
+ "Failed to get pixel clock\n");
+
+ ret = csi_formatter_subdev_init(formatter);
+ if (ret < 0)
+ return dev_err_probe(dev, ret, "Failed to initialize formatter subdev\n");
+
+ platform_set_drvdata(pdev, &formatter->sd);
+
+ /* Enable runtime PM. */
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ goto err_cleanup_subdev;
+
+ ret = csi_formatter_async_register(formatter);
+ if (ret < 0) {
+ dev_err_probe(dev, ret, "Failed to register async subdevice\n");
+ goto err_cleanup_subdev;
+ }
+
+ return 0;
+
+err_cleanup_subdev:
+ v4l2_subdev_cleanup(&formatter->sd);
+ media_entity_cleanup(&formatter->sd.entity);
+ return ret;
+}
+
+static void csi_formatter_remove(struct platform_device *pdev)
+{
+ struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+ struct csi_formatter *formatter = sd_to_formatter(sd);
+
+ csi_formatter_async_unregister(formatter);
+
+ v4l2_subdev_cleanup(&formatter->sd);
+ media_entity_cleanup(&formatter->sd.entity);
+}
+
+static const struct of_device_id csi_formatter_of_match[] = {
+ { .compatible = "fsl,imx95-csi-formatter" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, csi_formatter_of_match);
+
+static struct platform_driver csi_formatter_device_driver = {
+ .driver = {
+ .name = "csi-pixel-formatter",
+ .of_match_table = csi_formatter_of_match,
+ .pm = pm_ptr(&csi_formatter_pm_ops),
+ },
+ .probe = csi_formatter_probe,
+ .remove = csi_formatter_remove,
+};
+
+module_platform_driver(csi_formatter_device_driver);
+
+MODULE_AUTHOR("NXP Semiconductor, Inc.");
+MODULE_DESCRIPTION("NXP i.MX95 CSI Pixel Formatter driver");
+MODULE_LICENSE("GPL");
--
2.34.1
^ permalink raw reply related
* RE: [PATCH v2] iommu: Allow device driver to use its own PASID space for SVA
From: Tian, Kevin @ 2026-05-25 8:10 UTC (permalink / raw)
To: Joonwon Kang, jgg@ziepe.ca, will@kernel.org, robin.murphy@arm.com,
joro@8bytes.org, jpb@kernel.org
Cc: Alexander.Grest@microsoft.com, amhetre@nvidia.com,
baolu.lu@linux.intel.com, easwar.hariharan@linux.microsoft.com,
jacob.jun.pan@linux.intel.com, kees@kernel.org,
nicolinc@nvidia.com, praan@google.com, smostafa@google.com,
tglx@kernel.org, mingo@redhat.com, bp@alien8.de,
dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com,
peterz@infradead.org, Mehta, Sohil, kas@kernel.org,
alexander.shishkin@linux.intel.com, ryasuoka@redhat.com,
xin@zytor.com, linux-kernel@vger.kernel.org,
iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20260520150743.727106-1-joonwonkang@google.com>
> From: Joonwon Kang <joonwonkang@google.com>
> Sent: Wednesday, May 20, 2026 11:08 PM
>
[...]
>
> This commit resolves the issue by allowing device driver to maintain its
> own PASID space and assign a PASID from that for the process-device bond
> via a new API called `iommu_sva_bind_device_pasid(dev, mm, pasid)`. Doing
> that, however, will disallow the process to execute the ENQCMD-like
> instructions at EL0. It is because the process cannot change its PASID in
> IA32_PASID(or ACCDATA_EL1 on ARM) for each device without the kernel's
> intervention. For this reason, calling `iommu_sva_bind_device()` and then
> `iommu_sva_bind_device_pasid()` for the same process will not be allowed
> and vice versa.
>
> Currently, there is a limitation that a process simultaneously doing SVA
> with multiple devices with different PASIDs is not supported. So, calling
> `iommu_sva_bind_device_pasid()` multiple times for the same process with
> different devices will not be allowed for now while that for
> `iommu_sva_bind_device()` will be.
>
> Another limitation is that a process cannot do `iommu_sva_bind_device()`
> if it has ever done `iommu_sva_bind_device_pasid()` even though it has
> been unbound after use.
Why not making it clean in one step instead of leaving many unsupported
cases which are likely required soon in this "1" to "many" transition?
for each mm:
- one global pasid for ENQCMD or ST64BV0
- an array of device local pasids tracked in [struct device *, pasid] tuple.
upon gp fault or equivalent, fetch the global pasid.
upon device-specific bind, match [dev, pasid].
>
> Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
> Suggested-by: Kevin Tian <kevin.tian@intel.com>
> Signed-off-by: Joonwon Kang <joonwonkang@google.com>
> ---
> v2: Reuse iommu_mm->pasid after SVA bound by
> iommu_sva_bind_device_pasid()
> is unbound.
No idea what it talks about.
btw a new kAPI always needs accompanied users to review together.
^ permalink raw reply
* Re: [PATCH 1/2] crypto: Delete Qualcomm crypto engine driver
From: Dmitry Baryshkov @ 2026-05-25 8:11 UTC (permalink / raw)
To: Kuldeep Singh
Cc: Eric Biggers, Krzysztof Kozlowski, Demi Marie Obenour, Herbert Xu,
David S. Miller, Thara Gopinath, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio, Russell King,
linux-kernel, linux-crypto, linux-arm-msm, Ard Biesheuvel,
devicetree, linux-arm-kernel
In-Reply-To: <e36172c6-4424-4b77-9b3c-47dcdbdff05b@oss.qualcomm.com>
On Mon, May 25, 2026 at 11:59:33AM +0530, Kuldeep Singh wrote:
> > This driver is more than an order of magnitude slower than the CPU for
> > both encryption and hashing. See:
> >
> > https://lore.kernel.org/r/20250704070322.20692-1-ebiggers@kernel.org/
> > https://lore.kernel.org/r/20250615031807.GA81869@sol/
> >
> > There are many examples of it having bugs as well, for example see the
> > second link above.
> >
> > That's why it had to be disabled via the cra_priority system. This
> > driver was actively making Linux worse.
> >
> > This isn't particularly unique to drivers/crypto/, of course. This one
> > we just have data on, so it's a bit clearer.
> >
> > I've yet to see any real reason to keep this driver.
>
> https://lore.kernel.org/all/c1697372-54ec-4f57-85d9-ad375ff1a44d@oss.qualcomm.com/
> Kindly check my latest reply to the thread. There are numerous usecases
> like DRM(Digital rights management) coming up and qce driver is required
> for secure content.
>
> > Crypto drivers need to be held to a higher standard than other device
> > drivers, as well. The onus is on those who want to keep a particular
> > crypto driver to prove that it's worth keeping.
> Sure, I'll be working on stabilizing self_tests infra for qce.
> Kindly allow sometime to go over failures in crypto selftest and will
> submit fix if applicable.
Why are not selftests a part of your default config? How are you testing
the driver?
> So far, i am observing 2 ciphers failing(xts-aes-qce and ctr-aes-qce )
> with CONFIG_CRYPTO_SELFTESTS enabled.
Please make sure to run the tests on older platforms too, not just the
latest & greatest.
>
> https://lore.kernel.org/r/20250615031807.GA81869@sol/
> May I know how to issue reproduce steps because I didn't observe
> crypto/ahash.c failure with CONFIG_CRYPTO_SELFTESTS?
--
With best wishes
Dmitry
^ permalink raw reply
* [PATCH v7 01/10] dt-bindings: display: rockchip: analogix-dp: Fix hclk as third clock for RK3588
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
RK3588 eDP controller requires HCLK_VO1 to access the VO1 GRF
registers and enable the video datapath.
Previously, the clock was enabled implicitly via the 'rockchip,vo-grf'
phandle reference, which allowed the eDP to work without explicitly
managing the hclk_vo1 clock. However, this is not safe or explicit.
To make the clock dependency explicit, enforce per-SoC clock-names
requirements:
- RK3288: 2 clocks (dp, pclk)
- RK3399: 3 clocks (dp, pclk, grf)
- RK3588: 3 clocks (dp, pclk, hclk)
Do not reuse the 'grf' clock name for RK3588 because it represents
a different clock with distinct control logic:
- The 'grf' clock is only for GRF register access and is toggled
dynamically during register access.
- The 'hclk' clock controls both GRF access and video datapath
gating, and must remain enabled during probe.
Fixes: f855146263b1 ("dt-bindings: display: rockchip: analogix-dp: Add support for RK3588")
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v4:
- Modify the commit msg.
Changes in v5:
- Enforce the correct third clock name on a per-compatible basis.
- Modify the commit msg simultaneously.
Changes in v6:
- Expand more detail commit msg about using hclk instead of grf clock.
Changes in v7:
- List all valid clock names at the top level, and constrain the clock
count for each platform with minItems/maxItems in allOf.
---
.../rockchip/rockchip,analogix-dp.yaml | 34 ++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index d99b23b88cc5..7fe7655c1f37 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -26,7 +26,9 @@ properties:
items:
- const: dp
- const: pclk
- - const: grf
+ - enum:
+ - grf
+ - hclk
power-domains:
maxItems: 1
@@ -60,6 +62,32 @@ required:
allOf:
- $ref: /schemas/display/bridge/analogix,dp.yaml#
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - rockchip,rk3288-dp
+ then:
+ properties:
+ clocks:
+ maxItems: 2
+ clock-names:
+ maxItems: 2
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - rockchip,rk3399-edp
+ then:
+ properties:
+ clocks:
+ minItems: 3
+ clock-names:
+ minItems: 3
+
- if:
properties:
compatible:
@@ -68,6 +96,10 @@ allOf:
- rockchip,rk3588-edp
then:
properties:
+ clocks:
+ minItems: 3
+ clock-names:
+ minItems: 3
resets:
minItems: 2
reset-names:
--
2.34.1
^ permalink raw reply related
* [PATCH v7 04/10] arm64: dts: rockchip: Add missing hclk for RK3588 eDP1
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Add the required HCLK_VO1 bus clock to RK3588 eDP1 node with
corresponding clock-name "hclk". This clock is necessary for
the eDP controller to access video output GRF and work properly.
Previously the clock was enabled implicitly via GRF phandle
reference. Add it explicitly now to align with updated binding.
Fixes: a481bb0b1ad9 ("arm64: dts: rockchip: Add eDP1 dt node for rk3588")
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v4:
- Modify the commit msg.
---
| 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
index a2640014ee04..b251bb129cdb 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -285,8 +285,8 @@ hdmi1_out: port@1 {
edp1: edp@fded0000 {
compatible = "rockchip,rk3588-edp";
reg = <0x0 0xfded0000 0x0 0x1000>;
- clocks = <&cru CLK_EDP1_24M>, <&cru PCLK_EDP1>;
- clock-names = "dp", "pclk";
+ clocks = <&cru CLK_EDP1_24M>, <&cru PCLK_EDP1>, <&cru HCLK_VO1>;
+ clock-names = "dp", "pclk", "hclk";
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH 0>;
phys = <&hdptxphy1>;
phy-names = "dp";
--
2.34.1
^ permalink raw reply related
* [PATCH v7 03/10] arm64: dts: rockchip: Add missing hclk for RK3588 eDP0
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Add the required HCLK_VO1 bus clock to RK3588 eDP0 node with
corresponding clock-name "hclk". This clock is necessary for the
eDP controller to access video output GRF and work properly.
Previously the clock was enabled implicitly via GRF phandle
reference. Add it explicitly now to align with updated binding.
Fixes: dc79d3d5e7c7 ("arm64: dts: rockchip: Add eDP0 node for RK3588")
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v4:
- Modify the commit msg.
---
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 4fb8888c281c..24a5ccbac08c 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1712,8 +1712,8 @@ hdmi0_out: port@1 {
edp0: edp@fdec0000 {
compatible = "rockchip,rk3588-edp";
reg = <0x0 0xfdec0000 0x0 0x1000>;
- clocks = <&cru CLK_EDP0_24M>, <&cru PCLK_EDP0>;
- clock-names = "dp", "pclk";
+ clocks = <&cru CLK_EDP0_24M>, <&cru PCLK_EDP0>, <&cru HCLK_VO1>;
+ clock-names = "dp", "pclk", "hclk";
interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>;
phys = <&hdptxphy0>;
phy-names = "dp";
--
2.34.1
^ permalink raw reply related
* [PATCH v7 05/10] drm/rockchip: analogix_dp: Enable hclk for RK3588
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Acquire and enable the HCLK_VO1 bus clock explicitly for RK3588
eDP controller to guarantee register and datapath access.
The clock was previously enabled implicitly via rockchip,vo-grf
phandle reference, which relies on side effect and is fragile.
Fetch optional "hclk" clock in driver to align with updated device
tree binding and keep consistent with hardware clock dependency.
Fixes: 729f8eefdcad ("drm/rockchip: analogix_dp: Add support for RK3588")
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v4:
- Modify the commit msg.
---
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 06072efd7fca..d2af5eb29dbb 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -311,6 +311,7 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
{
struct device *dev = dp->dev;
struct device_node *np = dev->of_node;
+ struct clk *clk;
dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(dp->grf))
@@ -327,6 +328,11 @@ static int rockchip_dp_of_probe(struct rockchip_dp_device *dp)
return dev_err_probe(dev, PTR_ERR(dp->pclk),
"failed to get pclk property\n");
+ clk = devm_clk_get_optional_enabled(dev, "hclk");
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk),
+ "failed to get hclk property\n");
+
dp->rst = devm_reset_control_get(dev, "dp");
if (IS_ERR(dp->rst))
return dev_err_probe(dev, PTR_ERR(dp->rst),
--
2.34.1
^ permalink raw reply related
* [PATCH v7 06/10] dt-bindings: display: rockchip: analogix-dp: Add support for RK3576
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding,
Conor Dooley
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
RK3576 integrates an eDP TX controller compatible with the existing
RK3588 hardware design, reuse the same binding configuration directly.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v2:
- Split out a separate patch to add the "hclk" clock reference.
Chanegs in v4:
- Modify the commit msg.
Changes in v5:
- Add Acked-by tag.
---
.../bindings/display/rockchip/rockchip,analogix-dp.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index 6112caff3895..b4ec101b77a3 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -15,6 +15,7 @@ properties:
enum:
- rockchip,rk3288-dp
- rockchip,rk3399-edp
+ - rockchip,rk3576-edp
- rockchip,rk3588-edp
clocks:
@@ -96,6 +97,7 @@ allOf:
compatible:
contains:
enum:
+ - rockchip,rk3576-edp
- rockchip,rk3588-edp
then:
properties:
--
2.34.1
^ permalink raw reply related
* [PATCH v7 00/10] Add eDP support for RK3576
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
Patch 1-5 are to add missing clock "hclk" for RK3588 eDP nodes.
Patch 6-7 are to add the RK3576 eDP node.
Patch 8-10 are to support the RK3576 Analogix DP controller.
Damon Ding (10):
dt-bindings: display: rockchip: analogix-dp: Fix hclk as third clock
for RK3588
dt-bindings: display: rockchip: analogix-dp: Add per-clock
descriptions
arm64: dts: rockchip: Add missing hclk for RK3588 eDP0
arm64: dts: rockchip: Add missing hclk for RK3588 eDP1
drm/rockchip: analogix_dp: Enable hclk for RK3588
dt-bindings: display: rockchip: analogix-dp: Add support for RK3576
arm64: dts: rockchip: Add eDP node for RK3576
drm/bridge: analogix_dp: Rename and simplify is_rockchip()
drm/bridge: analogix_dp: Add support for RK3576
drm/rockchip: analogix_dp: Add support for RK3576
.../rockchip/rockchip,analogix-dp.yaml | 41 ++++++++++++++++++-
arch/arm64/boot/dts/rockchip/rk3576.dtsi | 28 +++++++++++++
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 4 +-
.../arm64/boot/dts/rockchip/rk3588-extra.dtsi | 4 +-
.../drm/bridge/analogix/analogix_dp_core.c | 3 +-
.../gpu/drm/bridge/analogix/analogix_dp_reg.c | 18 ++++----
.../gpu/drm/rockchip/analogix_dp-rockchip.c | 15 +++++++
include/drm/bridge/analogix_dp.h | 13 +++++-
8 files changed, 108 insertions(+), 18 deletions(-)
---
Changes in v2:
- Split out separate patches to add the "hclk" clock reference.
- Split out separate patches to enable the "hclk" clock.
- Add Reviewed-by tag.
Changes in v3:
- Add a patch to expand descriptions for clocks of the eDP node.
- Add Reviewed-by tag.
Changes in v4:
- Modify commit msg.
Changes in v5:
- Enforce the correct third clock name on a per-compatible basis.
- Modify the commit msg simultaneously.
- Add Acked-by tag.
Changes in v6:
- Expand more detail commit msg about using hclk instead of grf clock.
Changes in v7:
- List all valid clock names at the top level, and constrain the clock
count for each platform with minItems/maxItems in allOf.
--
2.34.1
^ permalink raw reply
* [PATCH v7 02/10] dt-bindings: display: rockchip: analogix-dp: Add per-clock descriptions
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding,
Conor Dooley
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Supplement dedicated description for each clock in the clocks
property, clarifying the function of each clock input for the
Analogix DP controller binding.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v4:
- Modify the commit msg.
Changes in v5:
- Add Acked-by tag.
---
.../bindings/display/rockchip/rockchip,analogix-dp.yaml | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
index 7fe7655c1f37..6112caff3895 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip,analogix-dp.yaml
@@ -19,7 +19,10 @@ properties:
clocks:
minItems: 2
- maxItems: 3
+ items:
+ - description: Reference clock
+ - description: APB bus clock
+ - description: GRF or AHB bus clock
clock-names:
minItems: 2
--
2.34.1
^ permalink raw reply related
* [PATCH v7 07/10] arm64: dts: rockchip: Add eDP node for RK3576
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Add full device tree definition for the integrated eDP controller
on RK3576, following the existing RK3588 hardware layout.
Configure required register range, clocks, interrupt, phy, power
domain, reset and grf properties to fully describe the controller.
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
Changes in v2:
- Add Reviewed-by tag.
Changes in v4:
- Modify the commit msg.
---
arch/arm64/boot/dts/rockchip/rk3576.dtsi | 28 ++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
index 28175d8200d5..733449cb88b1 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -1496,6 +1496,34 @@ hdmi_out: port@1 {
};
};
+ edp: edp@27dc0000 {
+ compatible = "rockchip,rk3576-edp";
+ reg = <0x0 0x27dc0000 0x0 0x1000>;
+ clocks = <&cru CLK_EDP0_24M>, <&cru PCLK_EDP0>, <&cru HCLK_VO0_ROOT>;
+ clock-names = "dp", "pclk", "hclk";
+ interrupts = <GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH>;
+ phys = <&hdptxphy>;
+ phy-names = "dp";
+ power-domains = <&power RK3576_PD_VO0>;
+ resets = <&cru SRST_EDP0_24M>, <&cru SRST_P_EDP0>;
+ reset-names = "dp", "apb";
+ rockchip,grf = <&vo0_grf>;
+ status = "disabled";
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ edp_in: port@0 {
+ reg = <0>;
+ };
+
+ edp_out: port@1 {
+ reg = <1>;
+ };
+ };
+ };
+
dp: dp@27e40000 {
compatible = "rockchip,rk3576-dp";
reg = <0x0 0x27e40000 0x0 0x30000>;
--
2.34.1
^ permalink raw reply related
* [PATCH v7 09/10] drm/bridge: analogix_dp: Add support for RK3576
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Add RK3576_EDP device type entry and extend Rockchip check
to match existing hardware capabilities shared with RK3588.
Set identical maximum link rate and lane count parameters
for RK3576 eDP controller to reuse existing RK3588 config.
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
---
Changes in v3:
- Add Reviewed-by tag.
Changes in v4:
- Modify the commit msg.
---
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 1 +
include/drm/bridge/analogix_dp.h | 2 ++
2 files changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index c2fd5b978fc0..5dc07ff84cd3 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -1249,6 +1249,7 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
video_info->max_link_rate = 0x0A;
video_info->max_lane_count = 0x04;
break;
+ case RK3576_EDP:
case RK3588_EDP:
video_info->max_link_rate = 0x14;
video_info->max_lane_count = 0x04;
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 7b670dd769e9..0e0b87abee59 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -16,6 +16,7 @@ enum analogix_dp_devtype {
EXYNOS_DP,
RK3288_DP,
RK3399_EDP,
+ RK3576_EDP,
RK3588_EDP,
};
@@ -24,6 +25,7 @@ static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type)
switch (type) {
case RK3288_DP:
case RK3399_EDP:
+ case RK3576_EDP:
case RK3588_EDP:
return true;
default:
--
2.34.1
^ permalink raw reply related
* [PATCH v7 10/10] drm/rockchip: analogix_dp: Add support for RK3576
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
RK3576 integrates Analogix eDP 1.3 TX and Samsung combo PHY
hardware blocks that fully match the proven RK3588 design.
Add dedicated chip data table and device tree matching entry
to bring up basic eDP functionality for the RK3576 platform.
Support is limited to RGB output up to 4K@60Hz for now; audio,
PSR and other advanced eDP 1.3 features remain unvalidated.
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Changes in v2:
- Split out a separate patch to enable the "hclk" clock.
- Add Reviewed-by tag.
Changes in v3:
- Add Reviewed-by tag.
Changes in v4:
- Modify the commit msg.
---
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index d2af5eb29dbb..d4c5dd61e95b 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -522,6 +522,14 @@ static const struct rockchip_dp_chip_data rk3288_dp[] = {
{ /* sentinel */ }
};
+static const struct rockchip_dp_chip_data rk3576_edp[] = {
+ {
+ .chip_type = RK3576_EDP,
+ .reg = 0x27dc0000,
+ },
+ { /* sentinel */ }
+};
+
static const struct rockchip_dp_chip_data rk3588_edp[] = {
{
.edp_mode = GRF_REG_FIELD(0x0000, 0, 0),
@@ -539,6 +547,7 @@ static const struct rockchip_dp_chip_data rk3588_edp[] = {
static const struct of_device_id rockchip_dp_dt_ids[] = {
{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
+ {.compatible = "rockchip,rk3576-edp", .data = &rk3576_edp },
{.compatible = "rockchip,rk3588-edp", .data = &rk3588_edp },
{}
};
--
2.34.1
^ permalink raw reply related
* [PATCH v7 08/10] drm/bridge: analogix_dp: Rename and simplify is_rockchip()
From: Damon Ding @ 2026-05-25 8:20 UTC (permalink / raw)
To: hjc, heiko, andy.yan, maarten.lankhorst, mripard, tzimmermann,
airlied, simona, robh, krzk+dt, conor+dt, andrzej.hajda,
neil.armstrong, rfoss
Cc: Laurent.pinchart, jonas, jernej.skrabec, nicolas.frattaroli,
cristian.ciocaltea, sebastian.reichel, dmitry.baryshkov,
luca.ceresoli, dianders, m.szyprowski, dri-devel, devicetree,
linux-arm-kernel, linux-rockchip, linux-kernel, Damon Ding
In-Reply-To: <20260525082033.117569-1-damon.ding@rock-chips.com>
Rename inline helper is_rockchip() to analogix_dp_is_rockchip()
to follow driver namespace convention consistently across code.
Replace chained equality comparisons with switch-case layout
to improve readability and simplify adding new SoC entries later.
Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
Suggested-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
---
Changes in v3:
- Add Reviewed-by tag.
Changes in v4:
- Modify the commit msg.
---
.../gpu/drm/bridge/analogix/analogix_dp_core.c | 2 +-
.../gpu/drm/bridge/analogix/analogix_dp_reg.c | 18 +++++++++---------
include/drm/bridge/analogix_dp.h | 11 +++++++++--
3 files changed, 19 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
index 573900c2cefc..c2fd5b978fc0 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
@@ -870,7 +870,7 @@ static int analogix_dp_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_display_info *di = &conn_state->connector->display_info;
u32 mask = BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) | BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
- if (is_rockchip(dp->plat_data->dev_type)) {
+ if (analogix_dp_is_rockchip(dp->plat_data->dev_type)) {
if ((di->color_formats & mask)) {
DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
di->color_formats &= ~mask;
diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
index f84c1d48d671..ea8401293a23 100644
--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
+++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
@@ -72,7 +72,7 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
reg = SEL_24M | TX_DVDD_BIT_1_0625V;
writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type)) {
reg = REF_CLK_24M;
if (dp->plat_data->dev_type == RK3288_DP)
reg ^= REF_CLK_MASK;
@@ -123,7 +123,7 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
analogix_dp_stop_video(dp);
analogix_dp_enable_video_mute(dp, 0);
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type))
reg = RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N |
SW_FUNC_EN_N;
else
@@ -233,7 +233,7 @@ void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
u32 mask = DP_PLL_PD;
u32 pd_addr = ANALOGIX_DP_PLL_CTL;
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type)) {
pd_addr = ANALOGIX_DP_PD;
mask = RK_PLL_PD;
}
@@ -254,12 +254,12 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
u32 mask;
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type))
phy_pd_addr = ANALOGIX_DP_PD;
switch (block) {
case AUX_BLOCK:
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type))
mask = RK_AUX_PD;
else
mask = AUX_PD;
@@ -317,7 +317,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
* to power off everything instead of DP_PHY_PD in
* Rockchip
*/
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type))
mask = DP_INC_BG;
else
mask = DP_PHY_PD;
@@ -329,7 +329,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
reg &= ~mask;
writel(reg, dp->reg_base + phy_pd_addr);
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type))
usleep_range(10, 15);
break;
case POWER_ALL:
@@ -465,7 +465,7 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
analogix_dp_reset_aux(dp);
/* AUX_BIT_PERIOD_EXPECTED_DELAY doesn't apply to Rockchip IP */
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type))
reg = 0;
else
reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3);
@@ -837,7 +837,7 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
u32 reg;
reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
- if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
+ if (dp->plat_data && analogix_dp_is_rockchip(dp->plat_data->dev_type)) {
reg &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N);
} else {
reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
diff --git a/include/drm/bridge/analogix_dp.h b/include/drm/bridge/analogix_dp.h
index 854af692229b..7b670dd769e9 100644
--- a/include/drm/bridge/analogix_dp.h
+++ b/include/drm/bridge/analogix_dp.h
@@ -19,9 +19,16 @@ enum analogix_dp_devtype {
RK3588_EDP,
};
-static inline bool is_rockchip(enum analogix_dp_devtype type)
+static inline bool analogix_dp_is_rockchip(enum analogix_dp_devtype type)
{
- return type == RK3288_DP || type == RK3399_EDP || type == RK3588_EDP;
+ switch (type) {
+ case RK3288_DP:
+ case RK3399_EDP:
+ case RK3588_EDP:
+ return true;
+ default:
+ return false;
+ }
}
struct analogix_dp_plat_data {
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] ARM: disable broken eBPF JIT on the Risc PC
From: Linus Walleij @ 2026-05-25 8:18 UTC (permalink / raw)
To: Ethan Nelson-Moore
Cc: linux-arm-kernel, linux-kernel, stable, Russell King,
Russell King (Oracle), Arnd Bergmann, Kees Cook,
Nathan Chancellor, Thomas Weissschuh, Peter Zijlstra,
Shubham Bansal, David S. Miller
In-Reply-To: <20260518014920.135011-1-enelsonmoore@gmail.com>
On Mon, May 18, 2026 at 3:49 AM Ethan Nelson-Moore
<enelsonmoore@gmail.com> wrote:
> The eBPF JIT unconditionally generates ldrh/strh instructions, which do
> not function correctly on the Risc PC because its bus is unable to
> signal half-word accesses. Work around this issue by disabling the eBPF
> JIT when building for ARMv3 (the Risc PC is the only currently
> supported ARMv3 machine).
>
> Fixes: 39c13c204bb1 ("arm: eBPF JIT compiler")
> Cc: stable@vger.kernel.org
> Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Looks correct to me.
Reviewed-by: Linus Walleij <linusw@kernel.org>
Please put this into Russell's patch tracker!
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH] ARM: remove the last few uses of do_bad_IRQ()
From: Linus Walleij @ 2026-05-25 8:20 UTC (permalink / raw)
To: Ethan Nelson-Moore
Cc: linux-arm-kernel, linux-kernel, Russell King, Thomas Gleixner,
Bartosz Golaszewski, Greg Kroah-Hartman, Kees Cook, Arnd Bergmann,
Adrian Barnaś
In-Reply-To: <20260518024051.189979-1-enelsonmoore@gmail.com>
On Mon, May 18, 2026 at 4:41 AM Ethan Nelson-Moore
<enelsonmoore@gmail.com> wrote:
> The do_bad_IRQ() macro simply calls handle_bad_irq() with a lock around
> it. It also carries a comment stating that uses of it should be
> replaced. According to commit aec0095653cd ("irqchip: gic: Call
> handle_bad_irq() directly"), which replaced another use of
> do_bad_IRQ(), locking the IRQ descriptor is not necessary for error
> reporting. Therefore, replace all uses of do_bad_IRQ() with calls to
> handle_bad_irq() and remove do_bad_IRQ().
>
> Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Please send this patch to the SoC tree (soc@kernel.org) after review
so the SoC maintainers can apply it.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] net: thunderx: fix PTP device ref leak in nicvf_probe()
From: Haoxiang Li @ 2026-05-25 8:26 UTC (permalink / raw)
To: sgoutham, andrew+netdev, davem, edumazet, kuba, pabeni,
richardcochran, pombredanne, aleksey.makarov
Cc: linux-arm-kernel, linux-kernel, netdev, Haoxiang Li, stable
cavium_ptp_get() acquires a reference to the PTP PCI device
through pci_get_device(). If any initialization step fails
after cavium_ptp_get(), the PTP PCI device reference is leaked.
Add a common error path to release the PTP reference before
returning from probe failures.
Fixes: 4a8755096466 ("net: thunderx: add timestamping support")
Cc: stable@vger.kernel.org
Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
---
drivers/net/ethernet/cavium/thunder/nicvf_main.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index 0b6e30a8feb0..d794aec80821 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -2109,8 +2109,10 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
err = pci_enable_device(pdev);
- if (err)
- return dev_err_probe(dev, err, "Failed to enable PCI device\n");
+ if (err) {
+ err = dev_err_probe(dev, err, "Failed to enable PCI device\n");
+ goto err_put_ptp;
+ }
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
@@ -2264,6 +2266,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_release_regions(pdev);
err_disable_device:
pci_disable_device(pdev);
+err_put_ptp:
+ cavium_ptp_put(ptp_clock);
return err;
}
--
2.25.1
^ permalink raw reply related
* RE: [PATCH V2 1/2] PCI: host-generic: Simplify return value handling in pci_host_common_parse_port(s)
From: Hongxing Zhu @ 2026-05-25 8:26 UTC (permalink / raw)
To: Sherry Sun (OSS), l.stach@pengutronix.de, Frank Li,
bhelgaas@google.com, lpieralisi@kernel.org,
kwilczynski@kernel.org, mani@kernel.org, robh@kernel.org,
s.hauer@pengutronix.de, kernel@pengutronix.de, festevam@gmail.com,
will@kernel.org
Cc: imx@lists.linux.dev, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Sherry Sun
In-Reply-To: <20260525065443.2338629-2-sherry.sun@oss.nxp.com>
> -----Original Message-----
> From: Sherry Sun (OSS) <sherry.sun@oss.nxp.com>
> Sent: Monday, May 25, 2026 2:55 PM
> To: Hongxing Zhu <hongxing.zhu@nxp.com>; l.stach@pengutronix.de; Frank Li
> <frank.li@nxp.com>; bhelgaas@google.com; lpieralisi@kernel.org;
> kwilczynski@kernel.org; mani@kernel.org; robh@kernel.org;
> s.hauer@pengutronix.de; kernel@pengutronix.de; festevam@gmail.com;
> will@kernel.org
> Cc: imx@lists.linux.dev; linux-pci@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; linux-kernel@vger.kernel.org; Sherry Sun
> <sherry.sun@nxp.com>
> Subject: [PATCH V2 1/2] PCI: host-generic: Simplify return value handling in
> pci_host_common_parse_port(s)
>
> From: Sherry Sun <sherry.sun@nxp.com>
>
> The pci_host_common_parse_port() shouldn't check the RC-level binding.
> That's a policy decision that belongs to the caller, not this common helper.
>
> Simplify pci_host_common_parse_port() to only parse properties from the Root
> Port (and its children) without checking the RC node. Also change
> pci_host_common_parse_ports() to return 0 when no ports are found, since it is
> not an error.
>
> So now both functions won't return failure for "property not found" or "port not
> found", they purely return 0 on success and a negative error code on real failures.
>
> Signed-off-by: Sherry Sun <sherry.sun@nxp.com>
Reviewed-by: Richard Zhu <hongxing.zhu@nxp.com>
Best Regards
Richard Zhu
> ---
> drivers/pci/controller/pci-host-common.c | 29 ++++--------------------
> 1 file changed, 5 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/pci/controller/pci-host-common.c b/drivers/pci/controller/pci-
> host-common.c
> index 2ce6f4b66133..c93de5a10758 100644
> --- a/drivers/pci/controller/pci-host-common.c
> +++ b/drivers/pci/controller/pci-host-common.c
> @@ -108,8 +108,7 @@ static int pci_host_common_parse_perst(struct device
> *dev,
> * dependencies and the driver may fail to operate if required resources
> * are missing.
> *
> - * Return: 0 on success, -ENODEV if PERST# found in RC node (legacy binding
> - * should be used), Other negative error codes on failure.
> + * Return: 0 on success, negative error codes on failure.
> */
> static int pci_host_common_parse_port(struct device *dev,
> struct pci_host_bridge *bridge, @@ -128,22
> +127,6 @@ static int pci_host_common_parse_port(struct device *dev,
> if (ret)
> return ret;
>
> - /*
> - * 1. PERST# found in RP or its child nodes - list is not empty,
> - * continue
> - *
> - * 2. PERST# not found in RP/children, but found in RC node -
> - * return -ENODEV to fallback legacy binding
> - *
> - * 3. PERST# not found anywhere - list is empty, continue (optional
> - * PERST#)
> - */
> - if (list_empty(&port->perst)) {
> - if (of_property_present(dev->of_node, "reset-gpios") ||
> - of_property_present(dev->of_node, "reset-gpio"))
> - return -ENODEV;
> - }
> -
> INIT_LIST_HEAD(&port->list);
> list_add_tail(&port->list, &bridge->ports);
>
> @@ -158,13 +141,11 @@ static int pci_host_common_parse_port(struct device
> *dev,
> * Iterate through child nodes of the host bridge and parse Root Port
> * properties (currently only reset GPIOs).
> *
> - * Return: 0 on success, -ENODEV if no ports found or PERST# found in RC
> - * node (legacy binding should be used), Other negative error codes on
> - * failure.
> + * Return: 0 on success, negative error codes on failure.
> */
> int pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge
> *bridge) {
> - int ret = -ENODEV;
> + int ret = 0;
>
> for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> if (!of_node_is_type(of_port, "pci")) @@ -174,8 +155,8 @@ int
> pci_host_common_parse_ports(struct device *dev, struct pci_host_bridge *brid
> goto err_cleanup;
> }
>
> - if (ret)
> - return ret;
> + if (list_empty(&bridge->ports))
> + return 0;
>
> return devm_add_action_or_reset(dev, pci_host_common_delete_ports,
> &bridge->ports);
> --
> 2.37.1
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox