* [PATCH v5 1/4] soc/tegra: cbb: Move driver registration from pure_initcall to core_initcall
From: Shashank Balaji @ 2026-05-18 10:19 UTC (permalink / raw)
To: Suzuki K Poulose, James Clark, Alexander Shishkin,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Mike Leach, Leo Yan,
Thierry Reding, Jonathan Hunter, Mike Leach
Cc: Rahul Bukte, Shashank Balaji, linux-kernel, coresight,
linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <20260518-acpi_mod_name-v5-0-705ccc430885@sony.com>
Commit "driver core: platform: set mod_name in driver registration" will set
struct device_driver's mod_name member for platform driver registration. For a
driver to be registered with its mod_name set, module_kset needs to be
initialized, which currently happens in a subsys_initcall in param_sysfs_init().
The tegra cbb drivers register themselves before module_kset init, in a
pure_initcall. This works currently because lookup_or_create_module_kobject(),
which dereferences module_kset via kset_find_obj(), is not called if mod_name
is not set, which is the case now.
So in preparation for the commit "driver core: platform: set mod_name in driver registration",
move tegra cbb driver registration to core_initcall level, and commit
"kernel: param: initialize module_kset in a pure_initcall" will move module_kset
init to pure_initcall level, ensuring module_kset init happens before tegra cbb
driver registration.
Suggested-by: Gary Guo <gary@garyguo.net>
Acked-by: Sumit Gupta <sumitg@nvidia.com>
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
Patch 4 depends on this patch
---
drivers/soc/tegra/cbb/tegra194-cbb.c | 2 +-
drivers/soc/tegra/cbb/tegra234-cbb.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c
index ab75d50cc85c..2f69e104c838 100644
--- a/drivers/soc/tegra/cbb/tegra194-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
@@ -2342,7 +2342,7 @@ static int __init tegra194_cbb_init(void)
{
return platform_driver_register(&tegra194_cbb_driver);
}
-pure_initcall(tegra194_cbb_init);
+core_initcall(tegra194_cbb_init);
static void __exit tegra194_cbb_exit(void)
{
diff --git a/drivers/soc/tegra/cbb/tegra234-cbb.c b/drivers/soc/tegra/cbb/tegra234-cbb.c
index fb26f085f691..785072fa4e85 100644
--- a/drivers/soc/tegra/cbb/tegra234-cbb.c
+++ b/drivers/soc/tegra/cbb/tegra234-cbb.c
@@ -1774,7 +1774,7 @@ static int __init tegra234_cbb_init(void)
{
return platform_driver_register(&tegra234_cbb_driver);
}
-pure_initcall(tegra234_cbb_init);
+core_initcall(tegra234_cbb_init);
static void __exit tegra234_cbb_exit(void)
{
--
2.43.0
^ permalink raw reply related
* [PATCH v5 3/4] coresight: pass THIS_MODULE implicitly through a macro
From: Shashank Balaji @ 2026-05-18 10:19 UTC (permalink / raw)
To: Suzuki K Poulose, James Clark, Alexander Shishkin,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Mike Leach, Leo Yan,
Thierry Reding, Jonathan Hunter, Mike Leach
Cc: Rahul Bukte, Shashank Balaji, linux-kernel, coresight,
linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <20260518-acpi_mod_name-v5-0-705ccc430885@sony.com>
Rename coresight_init_driver() to coresight_init_driver_with_owner() and replace
it with a macro wrapper that passes THIS_MODULE implicitly. This is in line with
what other buses do.
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Leo Yan <leo.yan@arm.com>
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
Patch 4 depends on this patch
---
drivers/hwtracing/coresight/coresight-catu.c | 2 +-
drivers/hwtracing/coresight/coresight-core.c | 6 +++---
drivers/hwtracing/coresight/coresight-cpu-debug.c | 3 +--
drivers/hwtracing/coresight/coresight-funnel.c | 3 +--
drivers/hwtracing/coresight/coresight-replicator.c | 3 +--
drivers/hwtracing/coresight/coresight-stm.c | 2 +-
drivers/hwtracing/coresight/coresight-tmc-core.c | 2 +-
drivers/hwtracing/coresight/coresight-tnoc.c | 2 +-
drivers/hwtracing/coresight/coresight-tpdm.c | 3 +--
drivers/hwtracing/coresight/coresight-tpiu.c | 2 +-
include/linux/coresight.h | 6 ++++--
11 files changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index ce71dcddfca2..0c8698c8fc5e 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -706,7 +706,7 @@ static int __init catu_init(void)
{
int ret;
- ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE);
+ ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver);
tmc_etr_set_catu_ops(&etr_catu_buf_ops);
return ret;
}
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 46f247f73cf6..54ad5193b850 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1694,8 +1694,8 @@ static void __exit coresight_exit(void)
module_init(coresight_init);
module_exit(coresight_exit);
-int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner)
+int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_drv,
+ struct platform_driver *pdev_drv, struct module *owner)
{
int ret;
@@ -1713,7 +1713,7 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
amba_driver_unregister(amba_drv);
return ret;
}
-EXPORT_SYMBOL_GPL(coresight_init_driver);
+EXPORT_SYMBOL_GPL(coresight_init_driver_with_owner);
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv)
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 629614278e46..3a806c1d50ea 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -757,8 +757,7 @@ static struct platform_driver debug_platform_driver = {
static int __init debug_init(void)
{
- return coresight_init_driver("debug", &debug_driver, &debug_platform_driver,
- THIS_MODULE);
+ return coresight_init_driver("debug", &debug_driver, &debug_platform_driver);
}
static void __exit debug_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 3f56ceccd8c9..0abc11f0690c 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -412,8 +412,7 @@ static struct amba_driver dynamic_funnel_driver = {
static int __init funnel_init(void)
{
- return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver,
- THIS_MODULE);
+ return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver);
}
static void __exit funnel_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 07fc04f53b88..2f382de357ee 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -418,8 +418,7 @@ static struct amba_driver dynamic_replicator_driver = {
static int __init replicator_init(void)
{
- return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver,
- THIS_MODULE);
+ return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver);
}
static void __exit replicator_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index aca6cec7885a..4e860519a73f 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -1050,7 +1050,7 @@ static struct platform_driver stm_platform_driver = {
static int __init stm_init(void)
{
- return coresight_init_driver("stm", &stm_driver, &stm_platform_driver, THIS_MODULE);
+ return coresight_init_driver("stm", &stm_driver, &stm_platform_driver);
}
static void __exit stm_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index c89fe996af23..bc5a133ada3e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -1046,7 +1046,7 @@ static struct platform_driver tmc_platform_driver = {
static int __init tmc_init(void)
{
- return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver, THIS_MODULE);
+ return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver);
}
static void __exit tmc_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c
index 96a25877b824..9e8de4323d28 100644
--- a/drivers/hwtracing/coresight/coresight-tnoc.c
+++ b/drivers/hwtracing/coresight/coresight-tnoc.c
@@ -344,7 +344,7 @@ static struct platform_driver itnoc_driver = {
static int __init tnoc_init(void)
{
- return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver, THIS_MODULE);
+ return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver);
}
static void __exit tnoc_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index eaf7210af648..8464edbba2d4 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -1563,8 +1563,7 @@ static struct platform_driver static_tpdm_driver = {
static int __init tpdm_init(void)
{
- return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver,
- THIS_MODULE);
+ return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver);
}
static void __exit tpdm_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index b8560b140e0f..7b029d2eb389 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -310,7 +310,7 @@ static struct platform_driver tpiu_platform_driver = {
static int __init tpiu_init(void)
{
- return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver, THIS_MODULE);
+ return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver);
}
static void __exit tpiu_exit(void)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 2131febebee9..cd8fb47a1192 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -691,8 +691,10 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
enum coresight_dev_type type,
union coresight_dev_subtype subtype);
-int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner);
+int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_drv,
+ struct platform_driver *pdev_drv, struct module *owner);
+#define coresight_init_driver(drv, amba_drv, pdev_drv) \
+ coresight_init_driver_with_owner(drv, amba_drv, pdev_drv, THIS_MODULE)
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
--
2.43.0
^ permalink raw reply related
* [PATCH v5 4/4] driver core: platform: set mod_name in driver registration
From: Shashank Balaji @ 2026-05-18 10:20 UTC (permalink / raw)
To: Suzuki K Poulose, James Clark, Alexander Shishkin,
Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Mike Leach, Leo Yan,
Thierry Reding, Jonathan Hunter, Mike Leach
Cc: Rahul Bukte, Shashank Balaji, linux-kernel, coresight,
linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <20260518-acpi_mod_name-v5-0-705ccc430885@sony.com>
Pass KBUILD_MODNAME through the driver registration macro so that
the driver core can create the module symlink in sysfs for built-in
drivers, and fixup all callers.
The Rust platform adapter is updated to pass the module name through to the new
parameter.
Tested on qemu with:
- x86 defconfig + CONFIG_RUST
- arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT stuff
Examples after this patch:
/sys/bus/platform/drivers/...
coresight-itnoc/module -> coresight_tnoc
coresight-static-tpdm/module -> coresight_tpdm
coresight-catu-platform/module -> coresight_catu
serial8250/module -> 8250
acpi-ged/module -> acpi
vmclock/module -> ptp_vmclock
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
This patch depends on patches 1, 2, 3
---
Documentation/driver-api/driver-model/platform.rst | 3 ++-
drivers/base/platform.c | 21 ++++++++++++++-------
drivers/hwtracing/coresight/coresight-core.c | 5 +++--
include/linux/coresight.h | 5 +++--
include/linux/platform_device.h | 17 +++++++++--------
rust/kernel/platform.rs | 4 +++-
6 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
index cf5ff48d3115..9673470bded2 100644
--- a/Documentation/driver-api/driver-model/platform.rst
+++ b/Documentation/driver-api/driver-model/platform.rst
@@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
provides helpers to register and unregister an array of drivers::
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner);
+ unsigned int count, struct module *owner,
+ const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 75b4698d0e58..2b0cc0889386 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -901,11 +901,14 @@ EXPORT_SYMBOL_GPL(platform_device_register_full);
* __platform_driver_register - register a driver for platform-level devices
* @drv: platform driver structure
* @owner: owning module/driver
+ * @mod_name: module name string
*/
-int __platform_driver_register(struct platform_driver *drv, struct module *owner)
+int __platform_driver_register(struct platform_driver *drv, struct module *owner,
+ const char *mod_name)
{
drv->driver.owner = owner;
drv->driver.bus = &platform_bus_type;
+ drv->driver.mod_name = mod_name;
return driver_register(&drv->driver);
}
@@ -938,6 +941,7 @@ static int is_bound_to_driver(struct device *dev, void *driver)
* @drv: platform driver structure
* @probe: the driver probe routine, probably from an __init section
* @module: module which will be the owner of the driver
+ * @mod_name: module name string
*
* Use this instead of platform_driver_register() when you know the device
* is not hotpluggable and has already been registered, and you want to
@@ -955,7 +959,8 @@ static int is_bound_to_driver(struct device *dev, void *driver)
*/
int __init_or_module __platform_driver_probe(struct platform_driver *drv,
int (*probe)(struct platform_device *),
- struct module *module)
+ struct module *module,
+ const char *mod_name)
{
int retval;
@@ -983,7 +988,7 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv,
/* temporary section violation during probe() */
drv->probe = probe;
- retval = __platform_driver_register(drv, module);
+ retval = __platform_driver_register(drv, module, mod_name);
if (retval)
return retval;
@@ -1011,6 +1016,7 @@ EXPORT_SYMBOL_GPL(__platform_driver_probe);
* @data: platform specific data for this platform device
* @size: size of platform specific data
* @module: module which will be the owner of the driver
+ * @mod_name: module name string
*
* Use this in legacy-style modules that probe hardware directly and
* register a single platform device and corresponding platform driver.
@@ -1021,7 +1027,7 @@ struct platform_device * __init_or_module
__platform_create_bundle(struct platform_driver *driver,
int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
- const void *data, size_t size, struct module *module)
+ const void *data, size_t size, struct module *module, const char *mod_name)
{
struct platform_device *pdev;
int error;
@@ -1044,7 +1050,7 @@ __platform_create_bundle(struct platform_driver *driver,
if (error)
goto err_pdev_put;
- error = __platform_driver_probe(driver, probe, module);
+ error = __platform_driver_probe(driver, probe, module, mod_name);
if (error)
goto err_pdev_del;
@@ -1064,6 +1070,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* @drivers: an array of drivers to register
* @count: the number of drivers to register
* @owner: module owning the drivers
+ * @mod_name: module name string
*
* Registers platform drivers specified by an array. On failure to register a
* driver, all previously registered drivers will be unregistered. Callers of
@@ -1073,7 +1080,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* Returns: 0 on success or a negative error code on failure.
*/
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner)
+ unsigned int count, struct module *owner, const char *mod_name)
{
unsigned int i;
int err;
@@ -1081,7 +1088,7 @@ int __platform_register_drivers(struct platform_driver * const *drivers,
for (i = 0; i < count; i++) {
pr_debug("registering platform driver %ps\n", drivers[i]);
- err = __platform_driver_register(drivers[i], owner);
+ err = __platform_driver_register(drivers[i], owner, mod_name);
if (err < 0) {
pr_err("failed to register platform driver %ps: %d\n",
drivers[i], err);
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 54ad5193b850..94ee24afdc6d 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1695,7 +1695,8 @@ module_init(coresight_init);
module_exit(coresight_exit);
int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner)
+ struct platform_driver *pdev_drv, struct module *owner,
+ const char *mod_name)
{
int ret;
@@ -1705,7 +1706,7 @@ int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_d
return ret;
}
- ret = __platform_driver_register(pdev_drv, owner);
+ ret = __platform_driver_register(pdev_drv, owner, mod_name);
if (!ret)
return 0;
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index cd8fb47a1192..1cf85d772bea 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -692,9 +692,10 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
union coresight_dev_subtype subtype);
int coresight_init_driver_with_owner(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner);
+ struct platform_driver *pdev_drv, struct module *owner,
+ const char *mod_name);
#define coresight_init_driver(drv, amba_drv, pdev_drv) \
- coresight_init_driver_with_owner(drv, amba_drv, pdev_drv, THIS_MODULE)
+ coresight_init_driver_with_owner(drv, amba_drv, pdev_drv, THIS_MODULE, KBUILD_MODNAME)
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 975400a472e3..26e6a43358e2 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -293,18 +293,19 @@ struct platform_driver {
* use a macro to avoid include chaining to get THIS_MODULE
*/
#define platform_driver_register(drv) \
- __platform_driver_register(drv, THIS_MODULE)
+ __platform_driver_register(drv, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_register(struct platform_driver *,
- struct module *);
+ struct module *, const char *mod_name);
extern void platform_driver_unregister(struct platform_driver *);
/* non-hotpluggable platform devices may use this so that probe() and
* its support may live in __init sections, conserving runtime memory.
*/
#define platform_driver_probe(drv, probe) \
- __platform_driver_probe(drv, probe, THIS_MODULE)
+ __platform_driver_probe(drv, probe, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_probe(struct platform_driver *driver,
- int (*probe)(struct platform_device *), struct module *module);
+ int (*probe)(struct platform_device *), struct module *module,
+ const char *mod_name);
static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
@@ -368,19 +369,19 @@ static int __init __platform_driver##_init(void) \
device_initcall(__platform_driver##_init); \
#define platform_create_bundle(driver, probe, res, n_res, data, size) \
- __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE)
+ __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE, KBUILD_MODNAME)
extern struct platform_device *__platform_create_bundle(
struct platform_driver *driver, int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
- const void *data, size_t size, struct module *module);
+ const void *data, size_t size, struct module *module, const char *mod_name);
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner);
+ unsigned int count, struct module *owner, const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
#define platform_register_drivers(drivers, count) \
- __platform_register_drivers(drivers, count, THIS_MODULE)
+ __platform_register_drivers(drivers, count, THIS_MODULE, KBUILD_MODNAME)
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 8917d4ee499f..2d626eecc450 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -82,7 +82,9 @@ unsafe fn register(
}
// SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
- to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) })
+ to_result(unsafe {
+ bindings::__platform_driver_register(pdrv.get(), module.0, name.as_char_ptr())
+ })
}
unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) {
--
2.43.0
^ permalink raw reply related
* [PATCH 00/16] media: sun6i-csi/isp MC-centric support and cleanups
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
This series first introduces some fixes and new formats to v4l2 format
info, one of which we need for the sun6i-csi driver. Support for
MC-centric format enumeration is then added, along with cleanups and
improvements for both the sun6i-csi and sun6i-isp drivers.
The first 4 patches are already reviewed and ready to go and are
included here as a reminder that this series depends on them.
Arash Golgol (4):
media: sun6i-csi: bridge: Use V4L2 subdev active state
media: sun6i-csi: capture: Implement vidioc_enum_framesizes
media: sun6i-mipi-csi2: Use V4L2 subdev active state
media: sun8i-a83t-mipi-csi2: Use V4L2 subdev active state
Paul Kocialkowski (12):
media: v4l2-common: Fix NV15_4L4 format info block height
media: v4l2-common: Add missing tiled format info block sizes
media: v4l2-common: Add NV12_16L16 pixel format to v4l2 format info
media: v4l2-common: Add NV12_32L32 pixel format to v4l2 format info
media: sun6i-csi: Split format validation to a dedicated helper
media: sun6i-csi: Add support for MC-centric format enumeration
media: sun6i-csi: Tidy up and unify coding style
media: sun6i-mipi-csi2: Fix parenthesis alignment
media: sun6i-isp: Add dummy params link_validate implementation
media: sun6i-isp: Use V4L2 subdev active state
media: sun6i-isp: Add support for MC-centric format enumeration
media: sun6i-isp: Add support for frame size enumeration
.../sunxi/sun6i-csi/sun6i_csi_bridge.c | 153 +++++++---------
.../sunxi/sun6i-csi/sun6i_csi_bridge.h | 9 -
.../sunxi/sun6i-csi/sun6i_csi_capture.c | 168 +++++++++++++-----
.../sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c | 107 ++++++-----
.../sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h | 2 -
.../sun8i_a83t_mipi_csi2.c | 113 ++++++------
.../sun8i_a83t_mipi_csi2.h | 2 -
drivers/media/v4l2-core/v4l2-common.c | 12 +-
.../media/sunxi/sun6i-isp/sun6i_isp_capture.c | 47 ++++-
.../media/sunxi/sun6i-isp/sun6i_isp_params.c | 37 +++-
.../media/sunxi/sun6i-isp/sun6i_isp_params.h | 4 +-
.../media/sunxi/sun6i-isp/sun6i_isp_proc.c | 117 ++++++------
.../media/sunxi/sun6i-isp/sun6i_isp_proc.h | 7 -
13 files changed, 437 insertions(+), 341 deletions(-)
--
2.54.0
^ permalink raw reply
* [PATCH 01/16] media: sun6i-csi: bridge: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
From: Arash Golgol <arash.golgol@gmail.com>
Use the V4L2 subdev active state API to store the active format.
This simplifies the driver not only by dropping the bridge mbus_format
field, but it also allows dropping the bridge lock, replaced with
the state lock.
Previously, capture accessed bridge private state directly. After
moving to framework-managed state, resolve the format through the
subdev pad API.
The sun6i-csi-bridge hardware does not perform any format conversion.
Enforce identical formats on the sink and source pads in the set_fmt()
and init_state() callbacks.
Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Reviewed-by: Paul Kocialkowski <paulk@sys-base.io>
Tested-by: Paul Kocialkowski <paulk@sys-base.io>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
.../sunxi/sun6i-csi/sun6i_csi_bridge.c | 155 ++++++++----------
.../sunxi/sun6i-csi/sun6i_csi_bridge.h | 9 -
.../sunxi/sun6i-csi/sun6i_csi_capture.c | 27 ++-
3 files changed, 86 insertions(+), 105 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
index d006d9dd0170..43a85bcc2ba2 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
@@ -13,26 +13,6 @@
#include "sun6i_csi_bridge.h"
#include "sun6i_csi_reg.h"
-/* Helpers */
-
-void sun6i_csi_bridge_dimensions(struct sun6i_csi_device *csi_dev,
- unsigned int *width, unsigned int *height)
-{
- if (width)
- *width = csi_dev->bridge.mbus_format.width;
- if (height)
- *height = csi_dev->bridge.mbus_format.height;
-}
-
-void sun6i_csi_bridge_format(struct sun6i_csi_device *csi_dev,
- u32 *mbus_code, u32 *field)
-{
- if (mbus_code)
- *mbus_code = csi_dev->bridge.mbus_format.code;
- if (field)
- *field = csi_dev->bridge.mbus_format.field;
-}
-
/* Format */
static const struct sun6i_csi_bridge_format sun6i_csi_bridge_formats[] = {
@@ -226,7 +206,8 @@ static void sun6i_csi_bridge_disable(struct sun6i_csi_device *csi_dev)
}
static void
-sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev)
+sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct device *dev = csi_dev->dev;
struct regmap *regmap = csi_dev->regmap;
@@ -234,11 +215,9 @@ sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev)
&csi_dev->bridge.source_parallel.endpoint;
unsigned char bus_width = endpoint->bus.parallel.bus_width;
unsigned int flags = endpoint->bus.parallel.flags;
- u32 field;
+ u32 field = mbus_format->field;
u32 value = SUN6I_CSI_IF_CFG_IF_CSI;
- sun6i_csi_bridge_format(csi_dev, NULL, &field);
-
if (field == V4L2_FIELD_INTERLACED ||
field == V4L2_FIELD_INTERLACED_TB ||
field == V4L2_FIELD_INTERLACED_BT)
@@ -317,13 +296,12 @@ sun6i_csi_bridge_configure_parallel(struct sun6i_csi_device *csi_dev)
}
static void
-sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev)
+sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct regmap *regmap = csi_dev->regmap;
u32 value = SUN6I_CSI_IF_CFG_IF_MIPI;
- u32 field;
-
- sun6i_csi_bridge_format(csi_dev, NULL, &field);
+ u32 field = mbus_format->field;
if (field == V4L2_FIELD_INTERLACED ||
field == V4L2_FIELD_INTERLACED_TB ||
@@ -335,19 +313,20 @@ sun6i_csi_bridge_configure_mipi_csi2(struct sun6i_csi_device *csi_dev)
regmap_write(regmap, SUN6I_CSI_IF_CFG_REG, value);
}
-static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev)
+static void
+sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct regmap *regmap = csi_dev->regmap;
bool capture_streaming = csi_dev->capture.state.streaming;
const struct sun6i_csi_bridge_format *bridge_format;
const struct sun6i_csi_capture_format *capture_format;
- u32 mbus_code, field, pixelformat;
+ u32 pixelformat;
+ u32 field = mbus_format->field;
u8 input_format, input_yuv_seq, output_format;
u32 value = 0;
- sun6i_csi_bridge_format(csi_dev, &mbus_code, &field);
-
- bridge_format = sun6i_csi_bridge_format_find(mbus_code);
+ bridge_format = sun6i_csi_bridge_format_find(mbus_format->code);
if (WARN_ON(!bridge_format))
return;
@@ -391,16 +370,17 @@ static void sun6i_csi_bridge_configure_format(struct sun6i_csi_device *csi_dev)
}
static void sun6i_csi_bridge_configure(struct sun6i_csi_device *csi_dev,
- struct sun6i_csi_bridge_source *source)
+ struct sun6i_csi_bridge_source *source,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct sun6i_csi_bridge *bridge = &csi_dev->bridge;
if (source == &bridge->source_parallel)
- sun6i_csi_bridge_configure_parallel(csi_dev);
+ sun6i_csi_bridge_configure_parallel(csi_dev, mbus_format);
else
- sun6i_csi_bridge_configure_mipi_csi2(csi_dev);
+ sun6i_csi_bridge_configure_mipi_csi2(csi_dev, mbus_format);
- sun6i_csi_bridge_configure_format(csi_dev);
+ sun6i_csi_bridge_configure_format(csi_dev, mbus_format);
}
/* V4L2 Subdev */
@@ -415,6 +395,8 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
struct sun6i_csi_bridge_source *source;
struct v4l2_subdev *source_subdev;
struct media_pad *remote_pad;
+ struct v4l2_subdev_state *state;
+ const struct v4l2_mbus_framefmt *mbus_format;
int ret;
/* Source */
@@ -433,6 +415,10 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
else
source = &bridge->source_mipi_csi2;
+ /* Active State */
+
+ state = v4l2_subdev_lock_and_get_active_state(subdev);
+
if (!on) {
v4l2_subdev_call(source_subdev, video, s_stream, 0);
ret = 0;
@@ -443,7 +429,7 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
- return ret;
+ goto unlock;
/* Clear */
@@ -451,7 +437,9 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
/* Configure */
- sun6i_csi_bridge_configure(csi_dev, source);
+ mbus_format = v4l2_subdev_state_get_format(state,
+ SUN6I_CSI_BRIDGE_PAD_SINK);
+ sun6i_csi_bridge_configure(csi_dev, source, mbus_format);
if (capture_streaming)
sun6i_csi_capture_configure(csi_dev);
@@ -472,7 +460,8 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
if (ret && ret != -ENOIOCTLCMD)
goto disable;
- return 0;
+ ret = 0;
+ goto unlock;
disable:
if (capture_streaming)
@@ -482,6 +471,8 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
pm_runtime_put(dev);
+unlock:
+ v4l2_subdev_unlock_state(state);
return ret;
}
@@ -504,21 +495,23 @@ sun6i_csi_bridge_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
static int sun6i_csi_bridge_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state)
{
- struct sun6i_csi_device *csi_dev = v4l2_get_subdevdata(subdev);
- unsigned int pad = SUN6I_CSI_BRIDGE_PAD_SINK;
- struct v4l2_mbus_framefmt *mbus_format =
- v4l2_subdev_state_get_format(state, pad);
- struct mutex *lock = &csi_dev->bridge.lock;
+ unsigned int pad;
- mutex_lock(lock);
+ /*
+ * This subdev does not perform format conversion,
+ * initialize both pads identically.
+ */
+ for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+ struct v4l2_mbus_framefmt *mbus_format;
- mbus_format->code = sun6i_csi_bridge_formats[0].mbus_code;
- mbus_format->width = 1280;
- mbus_format->height = 720;
+ mbus_format = v4l2_subdev_state_get_format(state, pad);
- sun6i_csi_bridge_mbus_format_prepare(mbus_format);
+ mbus_format->code = sun6i_csi_bridge_formats[0].mbus_code;
+ mbus_format->width = 1280;
+ mbus_format->height = 720;
- mutex_unlock(lock);
+ sun6i_csi_bridge_mbus_format_prepare(mbus_format);
+ }
return 0;
}
@@ -536,53 +529,32 @@ sun6i_csi_bridge_enum_mbus_code(struct v4l2_subdev *subdev,
return 0;
}
-static int sun6i_csi_bridge_get_fmt(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *format)
-{
- struct sun6i_csi_device *csi_dev = v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &csi_dev->bridge.lock;
-
- mutex_lock(lock);
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *mbus_format = *v4l2_subdev_state_get_format(state,
- format->pad);
- else
- *mbus_format = csi_dev->bridge.mbus_format;
-
- mutex_unlock(lock);
-
- return 0;
-}
-
static int sun6i_csi_bridge_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
- struct sun6i_csi_device *csi_dev = v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &csi_dev->bridge.lock;
+ struct v4l2_mbus_framefmt *fmt;
- mutex_lock(lock);
+ /* The format on the source pad always matches the sink pad. */
+ if (format->pad != SUN6I_CSI_BRIDGE_PAD_SINK)
+ return v4l2_subdev_get_fmt(subdev, state, format);
- sun6i_csi_bridge_mbus_format_prepare(mbus_format);
+ sun6i_csi_bridge_mbus_format_prepare(&format->format);
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *v4l2_subdev_state_get_format(state, format->pad) =
- *mbus_format;
- else
- csi_dev->bridge.mbus_format = *mbus_format;
+ /* Set the format on the sink pad. */
+ fmt = v4l2_subdev_state_get_format(state, format->pad);
+ *fmt = format->format;
- mutex_unlock(lock);
+ /* Propagate the format to the source pad. */
+ fmt = v4l2_subdev_state_get_format(state, SUN6I_CSI_BRIDGE_PAD_SOURCE);
+ *fmt = format->format;
return 0;
}
static const struct v4l2_subdev_pad_ops sun6i_csi_bridge_pad_ops = {
.enum_mbus_code = sun6i_csi_bridge_enum_mbus_code,
- .get_fmt = sun6i_csi_bridge_get_fmt,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = sun6i_csi_bridge_set_fmt,
};
@@ -780,8 +752,6 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
};
int ret;
- mutex_init(&bridge->lock);
-
/* V4L2 Subdev */
v4l2_subdev_init(subdev, &sun6i_csi_bridge_subdev_ops);
@@ -809,6 +779,12 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
if (ret < 0)
return ret;
+ /* V4L2 Subdev finalize */
+
+ ret = v4l2_subdev_init_finalize(subdev);
+ if (ret < 0)
+ goto error_media_entity;
+
/* V4L2 Subdev */
if (csi_dev->isp_available)
@@ -818,7 +794,7 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
if (ret) {
dev_err(dev, "failed to register v4l2 subdev: %d\n", ret);
- goto error_media_entity;
+ goto error_subdev_finalize;
}
/* V4L2 Async */
@@ -852,6 +828,9 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
else
v4l2_device_unregister_subdev(subdev);
+error_subdev_finalize:
+ v4l2_subdev_cleanup(subdev);
+
error_media_entity:
media_entity_cleanup(&subdev->entity);
@@ -868,5 +847,7 @@ void sun6i_csi_bridge_cleanup(struct sun6i_csi_device *csi_dev)
v4l2_device_unregister_subdev(subdev);
+ v4l2_subdev_cleanup(subdev);
+
media_entity_cleanup(&subdev->entity);
}
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h
index 44653b38f722..a5b0a6f064dd 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.h
@@ -42,20 +42,11 @@ struct sun6i_csi_bridge {
struct v4l2_subdev subdev;
struct v4l2_async_notifier notifier;
struct media_pad pads[2];
- struct v4l2_mbus_framefmt mbus_format;
- struct mutex lock; /* Mbus format lock. */
struct sun6i_csi_bridge_source source_parallel;
struct sun6i_csi_bridge_source source_mipi_csi2;
};
-/* Helpers */
-
-void sun6i_csi_bridge_dimensions(struct sun6i_csi_device *csi_dev,
- unsigned int *width, unsigned int *height);
-void sun6i_csi_bridge_format(struct sun6i_csi_device *csi_dev,
- u32 *mbus_code, u32 *field);
-
/* Format */
const struct sun6i_csi_bridge_format *
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index 65879f4802c0..d90abba21309 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -888,14 +888,19 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
media_entity_to_video_device(link->sink->entity);
struct sun6i_csi_device *csi_dev = video_get_drvdata(video_dev);
struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev;
+ struct v4l2_subdev *src_subdev =
+ media_entity_to_v4l2_subdev(link->source->entity);
const struct sun6i_csi_capture_format *capture_format;
const struct sun6i_csi_bridge_format *bridge_format;
unsigned int capture_width, capture_height;
- unsigned int bridge_width, bridge_height;
const struct v4l2_format_info *format_info;
+ struct v4l2_subdev_format src_fmt = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .pad = link->source->index
+ };
u32 pixelformat, capture_field;
- u32 mbus_code, bridge_field;
bool match;
+ int ret;
sun6i_csi_capture_dimensions(csi_dev, &capture_width, &capture_height);
@@ -904,19 +909,22 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
if (WARN_ON(!capture_format))
return -EINVAL;
- sun6i_csi_bridge_dimensions(csi_dev, &bridge_width, &bridge_height);
+ /* Resolve csi bridge format. */
+ ret = v4l2_subdev_call(src_subdev, pad, get_fmt, NULL, &src_fmt);
+ if (ret)
+ return ret;
- sun6i_csi_bridge_format(csi_dev, &mbus_code, &bridge_field);
- bridge_format = sun6i_csi_bridge_format_find(mbus_code);
+ bridge_format = sun6i_csi_bridge_format_find(src_fmt.format.code);
if (WARN_ON(!bridge_format))
return -EINVAL;
/* No cropping/scaling is supported. */
- if (capture_width != bridge_width || capture_height != bridge_height) {
+ if (capture_width != src_fmt.format.width ||
+ capture_height != src_fmt.format.height) {
v4l2_err(v4l2_dev,
"invalid input/output dimensions: %ux%u/%ux%u\n",
- bridge_width, bridge_height, capture_width,
- capture_height);
+ src_fmt.format.width, src_fmt.format.height,
+ capture_width, capture_height);
return -EINVAL;
}
@@ -947,7 +955,8 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
/* With raw input mode, we need a 1:1 match between input and output. */
if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_RAW ||
capture_format->input_format_raw) {
- match = sun6i_csi_capture_format_match(pixelformat, mbus_code);
+ match = sun6i_csi_capture_format_match(pixelformat,
+ src_fmt.format.code);
if (!match)
goto invalid;
}
--
2.54.0
^ permalink raw reply related
* [PATCH 02/16] media: sun6i-csi: capture: Implement vidioc_enum_framesizes
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
From: Arash Golgol <arash.golgol@gmail.com>
Report the stepwise frame size range supported by the CSI capture
hardware for the pixel formats exposed by the driver.
The hardware does not perform scaling and accepts any even width and
height within the reported limits.
Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Reviewed-by: Paul Kocialkowski <paulk@sys-base.io>
Tested-by: Paul Kocialkowski <paulk@sys-base.io>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
.../sunxi/sun6i-csi/sun6i_csi_capture.c | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index d90abba21309..f788b4234673 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -738,6 +738,27 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
return 0;
}
+static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index)
+ return -EINVAL;
+
+ /* Only accept format in map table. */
+ if (!sun6i_csi_capture_format_find(fsize->pixel_format))
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ fsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN;
+ fsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX;
+ fsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN;
+ fsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX;
+ fsize->stepwise.step_width = 2;
+ fsize->stepwise.step_height = 2;
+
+ return 0;
+}
+
static int sun6i_csi_capture_g_fmt(struct file *file, void *priv,
struct v4l2_format *format)
{
@@ -805,6 +826,7 @@ static const struct v4l2_ioctl_ops sun6i_csi_capture_ioctl_ops = {
.vidioc_querycap = sun6i_csi_capture_querycap,
.vidioc_enum_fmt_vid_cap = sun6i_csi_capture_enum_fmt,
+ .vidioc_enum_framesizes = sun6i_csi_capture_enum_framesize,
.vidioc_g_fmt_vid_cap = sun6i_csi_capture_g_fmt,
.vidioc_s_fmt_vid_cap = sun6i_csi_capture_s_fmt,
.vidioc_try_fmt_vid_cap = sun6i_csi_capture_try_fmt,
--
2.54.0
^ permalink raw reply related
* [PATCH 03/16] media: sun6i-mipi-csi2: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
From: Arash Golgol <arash.golgol@gmail.com>
Use the V4L2 subdev active state API to store the active format.
This simplifies the driver not only by dropping the bridge mbus_format
field, but it also allows dropping the bridge lock, replaced with
the state lock.
The sun6i-mipi-csi2 hardware does not perform any format conversion.
Enforce identical formats on the sink and source pads in the set_fmt()
and init_state() callbacks.
Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
.../sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c | 107 +++++++++---------
.../sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h | 2 -
2 files changed, 53 insertions(+), 56 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
index b06cb73015cd..682bdd82098c 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
@@ -95,12 +95,12 @@ static void sun6i_mipi_csi2_disable(struct sun6i_mipi_csi2_device *csi2_dev)
SUN6I_MIPI_CSI2_CTL_EN, 0);
}
-static void sun6i_mipi_csi2_configure(struct sun6i_mipi_csi2_device *csi2_dev)
+static void sun6i_mipi_csi2_configure(struct sun6i_mipi_csi2_device *csi2_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct regmap *regmap = csi2_dev->regmap;
unsigned int lanes_count =
csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes;
- struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
const struct sun6i_mipi_csi2_format *format;
struct device *dev = csi2_dev->dev;
u32 version = 0;
@@ -173,7 +173,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
struct v4l2_subdev *source_subdev = csi2_dev->bridge.source_subdev;
union phy_configure_opts dphy_opts = { 0 };
struct phy_configure_opts_mipi_dphy *dphy_cfg = &dphy_opts.mipi_dphy;
- struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
+ struct v4l2_subdev_state *state;
+ const struct v4l2_mbus_framefmt *mbus_format;
const struct sun6i_mipi_csi2_format *format;
struct phy *dphy = csi2_dev->dphy;
struct device *dev = csi2_dev->dev;
@@ -183,8 +184,12 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
unsigned long pixel_rate;
int ret;
- if (!source_subdev)
- return -ENODEV;
+ state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+ if (!source_subdev) {
+ ret = -ENODEV;
+ goto unlock;
+ }
if (!on) {
v4l2_subdev_call(source_subdev, video, s_stream, 0);
@@ -196,7 +201,7 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
- return ret;
+ goto unlock;
/* Sensor Pixel Rate */
@@ -222,6 +227,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
goto error_pm;
}
+ mbus_format = v4l2_subdev_state_get_format(state,
+ SUN6I_MIPI_CSI2_PAD_SINK);
format = sun6i_mipi_csi2_format_find(mbus_format->code);
if (WARN_ON(!format)) {
ret = -ENODEV;
@@ -260,7 +267,7 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
/* Controller */
- sun6i_mipi_csi2_configure(csi2_dev);
+ sun6i_mipi_csi2_configure(csi2_dev, mbus_format);
sun6i_mipi_csi2_enable(csi2_dev);
/* D-PHY */
@@ -277,7 +284,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
if (ret && ret != -ENOIOCTLCMD)
goto disable;
- return 0;
+ ret = 0;
+ goto unlock;
disable:
phy_power_off(dphy);
@@ -286,6 +294,8 @@ static int sun6i_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
error_pm:
pm_runtime_put(dev);
+unlock:
+ v4l2_subdev_unlock_state(state);
return ret;
}
@@ -308,21 +318,23 @@ sun6i_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
static int sun6i_mipi_csi2_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state)
{
- struct sun6i_mipi_csi2_device *csi2_dev = v4l2_get_subdevdata(subdev);
- unsigned int pad = SUN6I_MIPI_CSI2_PAD_SINK;
- struct v4l2_mbus_framefmt *mbus_format =
- v4l2_subdev_state_get_format(state, pad);
- struct mutex *lock = &csi2_dev->bridge.lock;
+ unsigned int pad;
- mutex_lock(lock);
+ /*
+ * This subdev does not perform format conversion,
+ * initialize both pads identically.
+ */
+ for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+ struct v4l2_mbus_framefmt *mbus_format;
- mbus_format->code = sun6i_mipi_csi2_formats[0].mbus_code;
- mbus_format->width = 640;
- mbus_format->height = 480;
+ mbus_format = v4l2_subdev_state_get_format(state, pad);
- sun6i_mipi_csi2_mbus_format_prepare(mbus_format);
+ mbus_format->code = sun6i_mipi_csi2_formats[0].mbus_code;
+ mbus_format->width = 640;
+ mbus_format->height = 480;
- mutex_unlock(lock);
+ sun6i_mipi_csi2_mbus_format_prepare(mbus_format);
+ }
return 0;
}
@@ -340,53 +352,32 @@ sun6i_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev,
return 0;
}
-static int sun6i_mipi_csi2_get_fmt(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *format)
-{
- struct sun6i_mipi_csi2_device *csi2_dev = v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &csi2_dev->bridge.lock;
-
- mutex_lock(lock);
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *mbus_format = *v4l2_subdev_state_get_format(state,
- format->pad);
- else
- *mbus_format = csi2_dev->bridge.mbus_format;
-
- mutex_unlock(lock);
-
- return 0;
-}
-
static int sun6i_mipi_csi2_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
- struct sun6i_mipi_csi2_device *csi2_dev = v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &csi2_dev->bridge.lock;
+ struct v4l2_mbus_framefmt *fmt;
- mutex_lock(lock);
+ /* The format on the source pad always matches the sink pad. */
+ if (format->pad != SUN6I_MIPI_CSI2_PAD_SINK)
+ return v4l2_subdev_get_fmt(subdev, state, format);
- sun6i_mipi_csi2_mbus_format_prepare(mbus_format);
+ sun6i_mipi_csi2_mbus_format_prepare(&format->format);
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *v4l2_subdev_state_get_format(state, format->pad) =
- *mbus_format;
- else
- csi2_dev->bridge.mbus_format = *mbus_format;
+ /* Set the format on the sink pad. */
+ fmt = v4l2_subdev_state_get_format(state, format->pad);
+ *fmt = format->format;
- mutex_unlock(lock);
+ /* Propagate the format to the source pad. */
+ fmt = v4l2_subdev_state_get_format(state, SUN6I_MIPI_CSI2_PAD_SOURCE);
+ *fmt = format->format;
return 0;
}
static const struct v4l2_subdev_pad_ops sun6i_mipi_csi2_pad_ops = {
.enum_mbus_code = sun6i_mipi_csi2_enum_mbus_code,
- .get_fmt = sun6i_mipi_csi2_get_fmt,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = sun6i_mipi_csi2_set_fmt,
};
@@ -502,8 +493,6 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
bool notifier_registered = false;
int ret;
- mutex_init(&bridge->lock);
-
/* V4L2 Subdev */
v4l2_subdev_init(subdev, &sun6i_mipi_csi2_subdev_ops);
@@ -532,6 +521,12 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
if (ret)
return ret;
+ /* V4L2 Subdev finalize */
+
+ ret = v4l2_subdev_init_finalize(subdev);
+ if (ret < 0)
+ goto error_media_entity_cleanup;
+
/* V4L2 Async */
v4l2_async_subdev_nf_init(notifier, subdev);
@@ -565,6 +560,9 @@ static int sun6i_mipi_csi2_bridge_setup(struct sun6i_mipi_csi2_device *csi2_dev)
error_v4l2_notifier_cleanup:
v4l2_async_nf_cleanup(notifier);
+ v4l2_subdev_cleanup(subdev);
+
+error_media_entity_cleanup:
media_entity_cleanup(&subdev->entity);
return ret;
@@ -579,6 +577,7 @@ sun6i_mipi_csi2_bridge_cleanup(struct sun6i_mipi_csi2_device *csi2_dev)
v4l2_async_unregister_subdev(subdev);
v4l2_async_nf_unregister(notifier);
v4l2_async_nf_cleanup(notifier);
+ v4l2_subdev_cleanup(subdev);
media_entity_cleanup(&subdev->entity);
}
diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h
index 24b15e34b5e8..d72dfbd6a993 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.h
@@ -32,8 +32,6 @@ struct sun6i_mipi_csi2_bridge {
struct media_pad pads[SUN6I_MIPI_CSI2_PAD_COUNT];
struct v4l2_fwnode_endpoint endpoint;
struct v4l2_async_notifier notifier;
- struct v4l2_mbus_framefmt mbus_format;
- struct mutex lock; /* Mbus format lock. */
struct v4l2_subdev *source_subdev;
};
--
2.54.0
^ permalink raw reply related
* [PATCH 04/16] media: sun8i-a83t-mipi-csi2: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
From: Arash Golgol <arash.golgol@gmail.com>
Use the V4L2 subdev active state API to store the active format.
This simplifies the driver not only by dropping the bridge mbus_format
field, but it also allows dropping the bridge lock, replaced with
the state lock.
The sun8i-a83t-mipi-csi2 hardware does not perform any format
conversion. Enforce identical formats on the sink and source pads in
the set_fmt() and init_state() callbacks.
Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
---
.../sun8i_a83t_mipi_csi2.c | 113 +++++++++---------
.../sun8i_a83t_mipi_csi2.h | 2 -
2 files changed, 56 insertions(+), 59 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
index dbc51daa4fe3..2b7635f3952d 100644
--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.c
@@ -144,12 +144,12 @@ sun8i_a83t_mipi_csi2_disable(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
}
static void
-sun8i_a83t_mipi_csi2_configure(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
+sun8i_a83t_mipi_csi2_configure(struct sun8i_a83t_mipi_csi2_device *csi2_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct regmap *regmap = csi2_dev->regmap;
unsigned int lanes_count =
csi2_dev->bridge.endpoint.bus.mipi_csi2.num_data_lanes;
- struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
const struct sun8i_a83t_mipi_csi2_format *format;
struct device *dev = csi2_dev->dev;
u32 version = 0;
@@ -205,7 +205,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
struct v4l2_subdev *source_subdev = csi2_dev->bridge.source_subdev;
union phy_configure_opts dphy_opts = { 0 };
struct phy_configure_opts_mipi_dphy *dphy_cfg = &dphy_opts.mipi_dphy;
- struct v4l2_mbus_framefmt *mbus_format = &csi2_dev->bridge.mbus_format;
+ struct v4l2_subdev_state *state;
+ const struct v4l2_mbus_framefmt *mbus_format;
const struct sun8i_a83t_mipi_csi2_format *format;
struct phy *dphy = csi2_dev->dphy;
struct device *dev = csi2_dev->dev;
@@ -215,8 +216,12 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
unsigned long pixel_rate;
int ret;
- if (!source_subdev)
- return -ENODEV;
+ state = v4l2_subdev_lock_and_get_active_state(subdev);
+
+ if (!source_subdev) {
+ ret = -ENODEV;
+ goto unlock;
+ }
if (!on) {
v4l2_subdev_call(source_subdev, video, s_stream, 0);
@@ -228,7 +233,7 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
- return ret;
+ goto unlock;
/* Sensor pixel rate */
@@ -254,6 +259,9 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
goto error_pm;
}
+ mbus_format =
+ v4l2_subdev_state_get_format(state,
+ SUN8I_A83T_MIPI_CSI2_PAD_SINK);
format = sun8i_a83t_mipi_csi2_format_find(mbus_format->code);
if (WARN_ON(!format)) {
ret = -ENODEV;
@@ -292,7 +300,7 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
/* Controller */
- sun8i_a83t_mipi_csi2_configure(csi2_dev);
+ sun8i_a83t_mipi_csi2_configure(csi2_dev, mbus_format);
sun8i_a83t_mipi_csi2_enable(csi2_dev);
/* D-PHY */
@@ -309,7 +317,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
if (ret && ret != -ENOIOCTLCMD)
goto disable;
- return 0;
+ ret = 0;
+ goto unlock;
disable:
phy_power_off(dphy);
@@ -318,6 +327,8 @@ static int sun8i_a83t_mipi_csi2_s_stream(struct v4l2_subdev *subdev, int on)
error_pm:
pm_runtime_put(dev);
+unlock:
+ v4l2_subdev_unlock_state(state);
return ret;
}
@@ -341,22 +352,24 @@ sun8i_a83t_mipi_csi2_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
static int sun8i_a83t_mipi_csi2_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state)
{
- struct sun8i_a83t_mipi_csi2_device *csi2_dev =
- v4l2_get_subdevdata(subdev);
- unsigned int pad = SUN8I_A83T_MIPI_CSI2_PAD_SINK;
- struct v4l2_mbus_framefmt *mbus_format =
- v4l2_subdev_state_get_format(state, pad);
- struct mutex *lock = &csi2_dev->bridge.lock;
+ unsigned int pad;
- mutex_lock(lock);
+ /*
+ * This subdev does not perform format conversion,
+ * initialize both pads identically.
+ */
+ for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+ struct v4l2_mbus_framefmt *mbus_format;
- mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code;
- mbus_format->width = 640;
- mbus_format->height = 480;
+ mbus_format = v4l2_subdev_state_get_format(state, pad);
+
+ mbus_format->code = sun8i_a83t_mipi_csi2_formats[0].mbus_code;
+ mbus_format->width = 640;
+ mbus_format->height = 480;
- sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
+ sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
+ }
- mutex_unlock(lock);
return 0;
}
@@ -375,55 +388,33 @@ sun8i_a83t_mipi_csi2_enum_mbus_code(struct v4l2_subdev *subdev,
return 0;
}
-static int sun8i_a83t_mipi_csi2_get_fmt(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *format)
-{
- struct sun8i_a83t_mipi_csi2_device *csi2_dev =
- v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &csi2_dev->bridge.lock;
-
- mutex_lock(lock);
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *mbus_format = *v4l2_subdev_state_get_format(state,
- format->pad);
- else
- *mbus_format = csi2_dev->bridge.mbus_format;
-
- mutex_unlock(lock);
-
- return 0;
-}
-
static int sun8i_a83t_mipi_csi2_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
- struct sun8i_a83t_mipi_csi2_device *csi2_dev =
- v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &csi2_dev->bridge.lock;
+ struct v4l2_mbus_framefmt *fmt;
- mutex_lock(lock);
+ /* The format on the source pad always matches the sink pad. */
+ if (format->pad != SUN8I_A83T_MIPI_CSI2_PAD_SINK)
+ return v4l2_subdev_get_fmt(subdev, state, format);
- sun8i_a83t_mipi_csi2_mbus_format_prepare(mbus_format);
+ sun8i_a83t_mipi_csi2_mbus_format_prepare(&format->format);
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *v4l2_subdev_state_get_format(state, format->pad) =
- *mbus_format;
- else
- csi2_dev->bridge.mbus_format = *mbus_format;
+ /* Set the format on the sink pad. */
+ fmt = v4l2_subdev_state_get_format(state, format->pad);
+ *fmt = format->format;
- mutex_unlock(lock);
+ /* Propagate the format to the source pad. */
+ fmt = v4l2_subdev_state_get_format(state,
+ SUN8I_A83T_MIPI_CSI2_PAD_SOURCE);
+ *fmt = format->format;
return 0;
}
static const struct v4l2_subdev_pad_ops sun8i_a83t_mipi_csi2_pad_ops = {
.enum_mbus_code = sun8i_a83t_mipi_csi2_enum_mbus_code,
- .get_fmt = sun8i_a83t_mipi_csi2_get_fmt,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = sun8i_a83t_mipi_csi2_set_fmt,
};
@@ -540,8 +531,6 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
bool notifier_registered = false;
int ret;
- mutex_init(&bridge->lock);
-
/* V4L2 Subdev */
v4l2_subdev_init(subdev, &sun8i_a83t_mipi_csi2_subdev_ops);
@@ -570,6 +559,12 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
if (ret)
return ret;
+ /* V4L2 Subdev finalize */
+
+ ret = v4l2_subdev_init_finalize(subdev);
+ if (ret < 0)
+ goto error_media_entity_cleanup;
+
/* V4L2 Async */
v4l2_async_subdev_nf_init(notifier, subdev);
@@ -603,6 +598,9 @@ sun8i_a83t_mipi_csi2_bridge_setup(struct sun8i_a83t_mipi_csi2_device *csi2_dev)
error_v4l2_notifier_cleanup:
v4l2_async_nf_cleanup(notifier);
+ v4l2_subdev_cleanup(subdev);
+
+error_media_entity_cleanup:
media_entity_cleanup(&subdev->entity);
return ret;
@@ -617,6 +615,7 @@ sun8i_a83t_mipi_csi2_bridge_cleanup(struct sun8i_a83t_mipi_csi2_device *csi2_dev
v4l2_async_unregister_subdev(subdev);
v4l2_async_nf_unregister(notifier);
v4l2_async_nf_cleanup(notifier);
+ v4l2_subdev_cleanup(subdev);
media_entity_cleanup(&subdev->entity);
}
diff --git a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h
index f1e64c53434c..819527bcd64d 100644
--- a/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h
+++ b/drivers/media/platform/sunxi/sun8i-a83t-mipi-csi2/sun8i_a83t_mipi_csi2.h
@@ -33,8 +33,6 @@ struct sun8i_a83t_mipi_csi2_bridge {
struct media_pad pads[SUN8I_A83T_MIPI_CSI2_PAD_COUNT];
struct v4l2_fwnode_endpoint endpoint;
struct v4l2_async_notifier notifier;
- struct v4l2_mbus_framefmt mbus_format;
- struct mutex lock; /* Mbus format lock. */
struct v4l2_subdev *source_subdev;
};
--
2.54.0
^ permalink raw reply related
* Re: [PATCH 2/2] firmware: samsung: acpm: add Exynos850 support
From: Tudor Ambarus @ 2026-05-18 10:27 UTC (permalink / raw)
To: Alexey Klimov, Sam Protsenko, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Krzysztof Kozlowski, Alim Akhtar
Cc: Peter Griffin, linux-samsung-soc, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260513-exynos850-acpm-firmware-support-v1-2-3858d097e433@linaro.org>
On 5/13/26 2:12 AM, Alexey Klimov wrote:
> The Exynos850 SoC contains an APM co-processor. Communication
> with this hardware block is established using the ACPM protocol,
> which handles IPC messages for clocks, power, thermal management,
> and PMIC control.
>
> Add the "samsung,exynos850-acpm-ipc" compatible string along with
> its associated match data. This includes the specific initialisation
s/initialisation/initialization
> data base offset (which differs from the GS101 offset) and the
> "exynos850-acpm-clk" device name required to properly instantiate
> the clock provider.
The patch looks alright. With what client did you test it, cpufreq?
Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
^ permalink raw reply
* [PATCH 05/16] media: v4l2-common: Fix NV15_4L4 format info block height
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
The NV15_4L4 format is specified as a 4x4 format, not 4x1.
In addition the block size should not take subsampling in account,
so specify it as 4x4 for both luma and chroma.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
drivers/media/v4l2-core/v4l2-common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 554c591e1113..77a0daa92c2b 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -309,7 +309,7 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
/* Tiled YUV formats */
{ .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
{ .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
- .block_w = { 4, 2, 0, 0 }, .block_h = { 1, 1, 0, 0 }},
+ .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
/* YUV planar formats, non contiguous variant */
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v5 4/4] driver core: platform: set mod_name in driver registration
From: Greg Kroah-Hartman @ 2026-05-18 10:27 UTC (permalink / raw)
To: Shashank Balaji
Cc: Suzuki K Poulose, James Clark, Alexander Shishkin,
Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Jonathan Corbet, Shuah Khan,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Mike Leach, Leo Yan, Thierry Reding,
Jonathan Hunter, Rahul Bukte, linux-kernel, coresight,
linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <20260518-acpi_mod_name-v5-4-705ccc430885@sony.com>
On Mon, May 18, 2026 at 07:20:00PM +0900, Shashank Balaji wrote:
> Pass KBUILD_MODNAME through the driver registration macro so that
> the driver core can create the module symlink in sysfs for built-in
> drivers, and fixup all callers.
>
> The Rust platform adapter is updated to pass the module name through to the new
> parameter.
>
> Tested on qemu with:
> - x86 defconfig + CONFIG_RUST
> - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT stuff
>
> Examples after this patch:
>
> /sys/bus/platform/drivers/...
> coresight-itnoc/module -> coresight_tnoc
> coresight-static-tpdm/module -> coresight_tpdm
> coresight-catu-platform/module -> coresight_catu
> serial8250/module -> 8250
> acpi-ged/module -> acpi
> vmclock/module -> ptp_vmclock
>
> Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> ---
> This patch depends on patches 1, 2, 3
> ---
> Documentation/driver-api/driver-model/platform.rst | 3 ++-
> drivers/base/platform.c | 21 ++++++++++++++-------
> drivers/hwtracing/coresight/coresight-core.c | 5 +++--
> include/linux/coresight.h | 5 +++--
> include/linux/platform_device.h | 17 +++++++++--------
> rust/kernel/platform.rs | 4 +++-
> 6 files changed, 34 insertions(+), 21 deletions(-)
>
> diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
> index cf5ff48d3115..9673470bded2 100644
> --- a/Documentation/driver-api/driver-model/platform.rst
> +++ b/Documentation/driver-api/driver-model/platform.rst
> @@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
> provides helpers to register and unregister an array of drivers::
>
> int __platform_register_drivers(struct platform_driver * const *drivers,
> - unsigned int count, struct module *owner);
> + unsigned int count, struct module *owner,
> + const char *mod_name);
Why can't you just use the owner->name value instead? They are always
the same here, right?
thanks,
greg k-h
^ permalink raw reply
* [PATCH 06/16] media: v4l2-common: Add missing tiled format info block sizes
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Some YUV420 tiled format info definitions are missing block sizes.
Add the missing block sizes (they are all 4x4).
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
drivers/media/v4l2-core/v4l2-common.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 77a0daa92c2b..e142d40c71b9 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -307,10 +307,12 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
{ .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
/* Tiled YUV formats */
- { .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_NV12_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+ .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
{ .format = V4L2_PIX_FMT_NV15_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 5, 10, 0, 0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
.block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
- { .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
+ { .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+ .block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
/* YUV planar formats, non contiguous variant */
{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
--
2.54.0
^ permalink raw reply related
* [PATCH 07/16] media: v4l2-common: Add NV12_16L16 pixel format to v4l2 format info
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Represent the NV12_16L16 pixel format in the v4l2 format info table.
This is a 16x16 tiled version of NV12.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
drivers/media/v4l2-core/v4l2-common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index e142d40c71b9..6194d6eb9c56 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -313,6 +313,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
.block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
{ .format = V4L2_PIX_FMT_P010_4L4, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 2, 4, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
.block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
+ { .format = V4L2_PIX_FMT_NV12_16L16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+ .block_w = { 16, 16, 0, 0 }, .block_h = { 16, 16, 0, 0 }},
/* YUV planar formats, non contiguous variant */
{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
--
2.54.0
^ permalink raw reply related
* [PATCH 08/16] media: v4l2-common: Add NV12_32L32 pixel format to v4l2 format info
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Represent the NV12_32L32 pixel format in the v4l2 format info table.
This is a 32x32 tiled version of NV12.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
drivers/media/v4l2-core/v4l2-common.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-core/v4l2-common.c
index 6194d6eb9c56..fe7141883ec5 100644
--- a/drivers/media/v4l2-core/v4l2-common.c
+++ b/drivers/media/v4l2-core/v4l2-common.c
@@ -315,6 +315,8 @@ const struct v4l2_format_info *v4l2_format_info(u32 format)
.block_w = { 4, 4, 0, 0 }, .block_h = { 4, 4, 0, 0 }},
{ .format = V4L2_PIX_FMT_NV12_16L16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
.block_w = { 16, 16, 0, 0 }, .block_h = { 16, 16, 0, 0 }},
+ { .format = V4L2_PIX_FMT_NV12_32L32, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2,
+ .block_w = { 32, 32, 0, 0 }, .block_h = { 32, 32, 0, 0 }},
/* YUV planar formats, non contiguous variant */
{ .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 2 },
--
2.54.0
^ permalink raw reply related
* [PATCH 09/16] media: sun6i-csi: Split format validation to a dedicated helper
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Introduce a new sun6i_csi_capture_format_check helper based on the
link_validate code, which will be reused to implement MC-style
pixelformat enumeration.
Formats not listed in v4l2_format_info are now checked via
sun6i_csi_capture_format_check (which only concerns raw formats)
instead of blindly allowing them.
Also fix a comment in the raw format table.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../sunxi/sun6i-csi/sun6i_csi_capture.c | 87 +++++++++++--------
1 file changed, 49 insertions(+), 38 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index f788b4234673..a836fa7f081a 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -213,7 +213,7 @@ struct sun6i_csi_capture_format *sun6i_csi_capture_format_find(u32 pixelformat)
/* RAW formats need an exact match between pixel and mbus formats. */
static const
struct sun6i_csi_capture_format_match sun6i_csi_capture_format_matches[] = {
- /* YUV420 */
+ /* YUV422 */
{
.pixelformat = V4L2_PIX_FMT_YUYV,
.mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
@@ -327,6 +327,51 @@ static bool sun6i_csi_capture_format_match(u32 pixelformat, u32 mbus_code)
return false;
}
+static bool
+sun6i_csi_capture_format_check(const struct sun6i_csi_capture_format *capture_format,
+ const struct sun6i_csi_bridge_format *bridge_format)
+{
+ const struct v4l2_format_info *format_info;
+ u32 pixelformat = capture_format->pixelformat;
+ u32 mbus_code = bridge_format->mbus_code;
+ bool match;
+
+ format_info = v4l2_format_info(pixelformat);
+
+ /* Some raw formats like JPEG are not listed: try a direct match. */
+ if (!format_info)
+ return sun6i_csi_capture_format_match(pixelformat, mbus_code);
+
+ if (format_info->pixel_enc == V4L2_PIXEL_ENC_BAYER &&
+ bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
+ return false;
+
+ if (format_info->pixel_enc == V4L2_PIXEL_ENC_RGB &&
+ bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
+ return false;
+
+ if (format_info->pixel_enc == V4L2_PIXEL_ENC_YUV) {
+ if (bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV420 &&
+ bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV422)
+ return false;
+
+ /* YUV420 input can't produce YUV422 output. */
+ if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_YUV420 &&
+ format_info->vdiv == 1)
+ return false;
+ }
+
+ /* With raw input mode, we need a 1:1 match between input and output. */
+ if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_RAW ||
+ capture_format->input_format_raw) {
+ match = sun6i_csi_capture_format_match(pixelformat, mbus_code);
+ if (!match)
+ return false;
+ }
+
+ return true;
+}
+
/* Capture */
static void
@@ -915,13 +960,11 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
const struct sun6i_csi_capture_format *capture_format;
const struct sun6i_csi_bridge_format *bridge_format;
unsigned int capture_width, capture_height;
- const struct v4l2_format_info *format_info;
struct v4l2_subdev_format src_fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
.pad = link->source->index
};
u32 pixelformat, capture_field;
- bool match;
int ret;
sun6i_csi_capture_dimensions(csi_dev, &capture_width, &capture_height);
@@ -950,44 +993,12 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
return -EINVAL;
}
- format_info = v4l2_format_info(pixelformat);
- /* Some formats are not listed. */
- if (!format_info)
- return 0;
-
- if (format_info->pixel_enc == V4L2_PIXEL_ENC_BAYER &&
- bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
- goto invalid;
-
- if (format_info->pixel_enc == V4L2_PIXEL_ENC_RGB &&
- bridge_format->input_format != SUN6I_CSI_INPUT_FMT_RAW)
- goto invalid;
-
- if (format_info->pixel_enc == V4L2_PIXEL_ENC_YUV) {
- if (bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV420 &&
- bridge_format->input_format != SUN6I_CSI_INPUT_FMT_YUV422)
- goto invalid;
-
- /* YUV420 input can't produce YUV422 output. */
- if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_YUV420 &&
- format_info->vdiv == 1)
- goto invalid;
- }
-
- /* With raw input mode, we need a 1:1 match between input and output. */
- if (bridge_format->input_format == SUN6I_CSI_INPUT_FMT_RAW ||
- capture_format->input_format_raw) {
- match = sun6i_csi_capture_format_match(pixelformat,
- src_fmt.format.code);
- if (!match)
- goto invalid;
+ if (!sun6i_csi_capture_format_check(capture_format, bridge_format)) {
+ v4l2_err(v4l2_dev, "invalid input/output format combination\n");
+ return -EINVAL;
}
return 0;
-
-invalid:
- v4l2_err(v4l2_dev, "invalid input/output format combination\n");
- return -EINVAL;
}
static const struct media_entity_operations sun6i_csi_capture_media_ops = {
--
2.54.0
^ permalink raw reply related
* [PATCH 10/16] media: sun6i-csi: Add support for MC-centric format enumeration
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Use the dedicated helper to check possible pixelformats against the
provided mbus code in order to support MC-centric format enumeration.
Note that multiple pixelformats may be returned for a given mbus code.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../sunxi/sun6i-csi/sun6i_csi_capture.c | 38 +++++++++++++++++--
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index a836fa7f081a..409c28621093 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -773,14 +773,43 @@ static int sun6i_csi_capture_querycap(struct file *file, void *priv,
static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtdesc)
{
+ const struct sun6i_csi_capture_format *capture_format;
+ const struct sun6i_csi_bridge_format *bridge_format;
+ u32 mbus_code = fmtdesc->mbus_code;
u32 index = fmtdesc->index;
+ unsigned int index_valid = 0;
+ unsigned int i;
+
+ /* Video-node-centric enumeration. */
+ if (!mbus_code) {
+ if (index >= ARRAY_SIZE(sun6i_csi_capture_formats))
+ return -EINVAL;
+
+ fmtdesc->pixelformat =
+ sun6i_csi_capture_formats[index].pixelformat;
+ return 0;
+ }
- if (index >= ARRAY_SIZE(sun6i_csi_capture_formats))
+ bridge_format = sun6i_csi_bridge_format_find(mbus_code);
+ if (!bridge_format)
return -EINVAL;
- fmtdesc->pixelformat = sun6i_csi_capture_formats[index].pixelformat;
+ for (i = 0; i < ARRAY_SIZE(sun6i_csi_capture_formats); i++) {
+ capture_format = &sun6i_csi_capture_formats[i];
- return 0;
+ if (!sun6i_csi_capture_format_check(capture_format,
+ bridge_format))
+ continue;
+
+ if (index_valid == index) {
+ fmtdesc->pixelformat = capture_format->pixelformat;
+ return 0;
+ }
+
+ index_valid++;
+ }
+
+ return -EINVAL;
}
static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh,
@@ -1076,7 +1105,8 @@ int sun6i_csi_capture_setup(struct sun6i_csi_device *csi_dev)
strscpy(video_dev->name, SUN6I_CSI_CAPTURE_NAME,
sizeof(video_dev->name));
- video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+ V4L2_CAP_IO_MC;
video_dev->vfl_dir = VFL_DIR_RX;
video_dev->release = video_device_release_empty;
video_dev->fops = &sun6i_csi_capture_fops;
--
2.54.0
^ permalink raw reply related
* [PATCH 11/16] media: sun6i-csi: Tidy up and unify coding style
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Bring recent changes to the same coding style as the rest of the driver.
This is purely cosmetic and no functional change is intended.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../sunxi/sun6i-csi/sun6i_csi_bridge.c | 16 ++---
.../sunxi/sun6i-csi/sun6i_csi_capture.c | 72 ++++++++++---------
2 files changed, 46 insertions(+), 42 deletions(-)
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
index 43a85bcc2ba2..18f79075d3ad 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_bridge.c
@@ -473,6 +473,7 @@ static int sun6i_csi_bridge_s_stream(struct v4l2_subdev *subdev, int on)
unlock:
v4l2_subdev_unlock_state(state);
+
return ret;
}
@@ -533,7 +534,7 @@ static int sun6i_csi_bridge_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
- struct v4l2_mbus_framefmt *fmt;
+ struct v4l2_mbus_framefmt *mbus_format;
/* The format on the source pad always matches the sink pad. */
if (format->pad != SUN6I_CSI_BRIDGE_PAD_SINK)
@@ -542,12 +543,12 @@ static int sun6i_csi_bridge_set_fmt(struct v4l2_subdev *subdev,
sun6i_csi_bridge_mbus_format_prepare(&format->format);
/* Set the format on the sink pad. */
- fmt = v4l2_subdev_state_get_format(state, format->pad);
- *fmt = format->format;
+ mbus_format = v4l2_subdev_state_get_format(state, format->pad);
+ *mbus_format = format->format;
/* Propagate the format to the source pad. */
- fmt = v4l2_subdev_state_get_format(state, SUN6I_CSI_BRIDGE_PAD_SOURCE);
- *fmt = format->format;
+ mbus_format = v4l2_subdev_state_get_format(state, SUN6I_CSI_BRIDGE_PAD_SOURCE);
+ *mbus_format = format->format;
return 0;
}
@@ -779,14 +780,12 @@ int sun6i_csi_bridge_setup(struct sun6i_csi_device *csi_dev)
if (ret < 0)
return ret;
- /* V4L2 Subdev finalize */
+ /* V4L2 Subdev */
ret = v4l2_subdev_init_finalize(subdev);
if (ret < 0)
goto error_media_entity;
- /* V4L2 Subdev */
-
if (csi_dev->isp_available)
ret = v4l2_async_register_subdev(subdev);
else
@@ -846,7 +845,6 @@ void sun6i_csi_bridge_cleanup(struct sun6i_csi_device *csi_dev)
v4l2_async_nf_cleanup(notifier);
v4l2_device_unregister_subdev(subdev);
-
v4l2_subdev_cleanup(subdev);
media_entity_cleanup(&subdev->entity);
diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
index 409c28621093..eea682f47eea 100644
--- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
+++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi_capture.c
@@ -812,27 +812,6 @@ static int sun6i_csi_capture_enum_fmt(struct file *file, void *priv,
return -EINVAL;
}
-static int sun6i_csi_capture_enum_framesize(struct file *file, void *fh,
- struct v4l2_frmsizeenum *fsize)
-{
- if (fsize->index)
- return -EINVAL;
-
- /* Only accept format in map table. */
- if (!sun6i_csi_capture_format_find(fsize->pixel_format))
- return -EINVAL;
-
- fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
- fsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN;
- fsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX;
- fsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN;
- fsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX;
- fsize->stepwise.step_width = 2;
- fsize->stepwise.step_height = 2;
-
- return 0;
-}
-
static int sun6i_csi_capture_g_fmt(struct file *file, void *priv,
struct v4l2_format *format)
{
@@ -867,6 +846,27 @@ static int sun6i_csi_capture_try_fmt(struct file *file, void *priv,
return 0;
}
+static int sun6i_csi_capture_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *frmsize)
+{
+ if (frmsize->index)
+ return -EINVAL;
+
+ /* Only accept format in map table. */
+ if (!sun6i_csi_capture_format_find(frmsize->pixel_format))
+ return -EINVAL;
+
+ frmsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ frmsize->stepwise.min_width = SUN6I_CSI_CAPTURE_WIDTH_MIN;
+ frmsize->stepwise.max_width = SUN6I_CSI_CAPTURE_WIDTH_MAX;
+ frmsize->stepwise.min_height = SUN6I_CSI_CAPTURE_HEIGHT_MIN;
+ frmsize->stepwise.max_height = SUN6I_CSI_CAPTURE_HEIGHT_MAX;
+ frmsize->stepwise.step_width = 2;
+ frmsize->stepwise.step_height = 2;
+
+ return 0;
+}
+
static int sun6i_csi_capture_enum_input(struct file *file, void *priv,
struct v4l2_input *input)
{
@@ -900,11 +900,12 @@ static const struct v4l2_ioctl_ops sun6i_csi_capture_ioctl_ops = {
.vidioc_querycap = sun6i_csi_capture_querycap,
.vidioc_enum_fmt_vid_cap = sun6i_csi_capture_enum_fmt,
- .vidioc_enum_framesizes = sun6i_csi_capture_enum_framesize,
.vidioc_g_fmt_vid_cap = sun6i_csi_capture_g_fmt,
.vidioc_s_fmt_vid_cap = sun6i_csi_capture_s_fmt,
.vidioc_try_fmt_vid_cap = sun6i_csi_capture_try_fmt,
+ .vidioc_enum_framesizes = sun6i_csi_capture_enum_framesizes,
+
.vidioc_enum_input = sun6i_csi_capture_enum_input,
.vidioc_g_input = sun6i_csi_capture_g_input,
.vidioc_s_input = sun6i_csi_capture_s_input,
@@ -984,16 +985,17 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
media_entity_to_video_device(link->sink->entity);
struct sun6i_csi_device *csi_dev = video_get_drvdata(video_dev);
struct v4l2_device *v4l2_dev = csi_dev->v4l2_dev;
- struct v4l2_subdev *src_subdev =
+ struct v4l2_subdev *bridge_subdev =
media_entity_to_v4l2_subdev(link->source->entity);
const struct sun6i_csi_capture_format *capture_format;
const struct sun6i_csi_bridge_format *bridge_format;
unsigned int capture_width, capture_height;
- struct v4l2_subdev_format src_fmt = {
- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
- .pad = link->source->index
+ unsigned int bridge_width, bridge_height;
+ struct v4l2_subdev_format bridge_subdev_format = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .pad = link->source->index,
};
- u32 pixelformat, capture_field;
+ u32 pixelformat, capture_field, mbus_code;
int ret;
sun6i_csi_capture_dimensions(csi_dev, &capture_width, &capture_height);
@@ -1004,21 +1006,25 @@ static int sun6i_csi_capture_link_validate(struct media_link *link)
return -EINVAL;
/* Resolve csi bridge format. */
- ret = v4l2_subdev_call(src_subdev, pad, get_fmt, NULL, &src_fmt);
+ ret = v4l2_subdev_call(bridge_subdev, pad, get_fmt, NULL,
+ &bridge_subdev_format);
if (ret)
return ret;
- bridge_format = sun6i_csi_bridge_format_find(src_fmt.format.code);
+ bridge_width = bridge_subdev_format.format.width;
+ bridge_height = bridge_subdev_format.format.height;
+ mbus_code = bridge_subdev_format.format.code;
+
+ bridge_format = sun6i_csi_bridge_format_find(mbus_code);
if (WARN_ON(!bridge_format))
return -EINVAL;
/* No cropping/scaling is supported. */
- if (capture_width != src_fmt.format.width ||
- capture_height != src_fmt.format.height) {
+ if (capture_width != bridge_width || capture_height != bridge_height) {
v4l2_err(v4l2_dev,
"invalid input/output dimensions: %ux%u/%ux%u\n",
- src_fmt.format.width, src_fmt.format.height,
- capture_width, capture_height);
+ bridge_width, bridge_height, capture_width,
+ capture_height);
return -EINVAL;
}
--
2.54.0
^ permalink raw reply related
* [PATCH 12/16] media: sun6i-mipi-csi2: Fix parenthesis alignment
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
This is purely cosmetic, no functional change intended.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
index 682bdd82098c..17a9a215a98a 100644
--- a/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
+++ b/drivers/media/platform/sunxi/sun6i-mipi-csi2/sun6i_mipi_csi2.c
@@ -96,7 +96,7 @@ static void sun6i_mipi_csi2_disable(struct sun6i_mipi_csi2_device *csi2_dev)
}
static void sun6i_mipi_csi2_configure(struct sun6i_mipi_csi2_device *csi2_dev,
- const struct v4l2_mbus_framefmt *mbus_format)
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct regmap *regmap = csi2_dev->regmap;
unsigned int lanes_count =
--
2.54.0
^ permalink raw reply related
* [PATCH 13/16] media: sun6i-isp: Add dummy params link_validate implementation
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
There isn't anything configurable about the params video device link,
but the v4l2 core complains that no op is provided so implement a dummy
one to make it happy.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../media/sunxi/sun6i-isp/sun6i_isp_params.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index 77c2d06c0436..b7ef33fa2b13 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -450,6 +450,18 @@ static const struct v4l2_file_operations sun6i_isp_params_fops = {
.poll = vb2_fop_poll,
};
+/* Media Entity */
+
+static int sun6i_isp_params_link_validate(struct media_link *link)
+{
+ /* Nothing to validate here. */
+ return 0;
+}
+
+static const struct media_entity_operations sun6i_isp_params_entity_ops = {
+ .link_validate = sun6i_isp_params_link_validate,
+};
+
/* Params */
int sun6i_isp_params_setup(struct sun6i_isp_device *isp_dev)
@@ -470,6 +482,10 @@ int sun6i_isp_params_setup(struct sun6i_isp_device *isp_dev)
INIT_LIST_HEAD(&state->queue);
spin_lock_init(&state->lock);
+ /* Media Entity */
+
+ video_dev->entity.ops = &sun6i_isp_params_entity_ops;
+
/* Media Pads */
pad->flags = MEDIA_PAD_FL_SOURCE | MEDIA_PAD_FL_MUST_CONNECT;
--
2.54.0
^ permalink raw reply related
* [PATCH 14/16] media: sun6i-isp: Use V4L2 subdev active state
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Store the active format using the common V4L2 subdev active state
instead of our local copy of it.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../media/sunxi/sun6i-isp/sun6i_isp_capture.c | 16 ++-
.../media/sunxi/sun6i-isp/sun6i_isp_params.c | 18 ++-
.../media/sunxi/sun6i-isp/sun6i_isp_params.h | 4 +-
.../media/sunxi/sun6i-isp/sun6i_isp_proc.c | 117 ++++++++----------
.../media/sunxi/sun6i-isp/sun6i_isp_proc.h | 7 --
5 files changed, 82 insertions(+), 80 deletions(-)
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index e7b99cee63d6..24e731bcabe9 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -595,11 +595,25 @@ static int sun6i_isp_capture_link_validate(struct media_link *link)
media_entity_to_video_device(link->sink->entity);
struct sun6i_isp_device *isp_dev = video_get_drvdata(video_dev);
struct v4l2_device *v4l2_dev = &isp_dev->v4l2.v4l2_dev;
+ struct v4l2_subdev *proc_subdev =
+ media_entity_to_v4l2_subdev(link->source->entity);
unsigned int capture_width, capture_height;
unsigned int proc_width, proc_height;
+ struct v4l2_subdev_format proc_subdev_format = {
+ .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+ .pad = link->source->index,
+ };
+ int ret;
sun6i_isp_capture_dimensions(isp_dev, &capture_width, &capture_height);
- sun6i_isp_proc_dimensions(isp_dev, &proc_width, &proc_height);
+
+ ret = v4l2_subdev_call(proc_subdev, pad, get_fmt, NULL,
+ &proc_subdev_format);
+ if (ret)
+ return ret;
+
+ proc_width = proc_subdev_format.format.width;
+ proc_height = proc_subdev_format.format.height;
/* No cropping/scaling is supported (yet). */
if (capture_width != proc_width || capture_height != proc_height) {
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index b7ef33fa2b13..0cc48e2bc8c6 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -43,11 +43,14 @@ static const struct sun6i_isp_params_config sun6i_isp_params_config_default = {
},
};
-static void sun6i_isp_params_configure_ob(struct sun6i_isp_device *isp_dev)
+static void
+sun6i_isp_params_configure_ob(struct sun6i_isp_device *isp_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
unsigned int width, height;
- sun6i_isp_proc_dimensions(isp_dev, &width, &height);
+ width = mbus_format->width;
+ height = mbus_format->height;
sun6i_isp_load_write(isp_dev, SUN6I_ISP_OB_SIZE_REG,
SUN6I_ISP_OB_SIZE_WIDTH(width) |
@@ -112,10 +115,12 @@ static void sun6i_isp_params_configure_wb(struct sun6i_isp_device *isp_dev)
SUN6I_ISP_WB_CFG_CLIP(0xfff));
}
-static void sun6i_isp_params_configure_base(struct sun6i_isp_device *isp_dev)
+static void
+sun6i_isp_params_configure_base(struct sun6i_isp_device *isp_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
sun6i_isp_params_configure_ae(isp_dev);
- sun6i_isp_params_configure_ob(isp_dev);
+ sun6i_isp_params_configure_ob(isp_dev, mbus_format);
sun6i_isp_params_configure_wb(isp_dev);
}
@@ -170,14 +175,15 @@ sun6i_isp_params_configure_modules(struct sun6i_isp_device *isp_dev,
sun6i_isp_load_write(isp_dev, SUN6I_ISP_MODULE_EN_REG, value);
}
-void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev)
+void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
struct sun6i_isp_params_state *state = &isp_dev->params.state;
unsigned long flags;
spin_lock_irqsave(&state->lock, flags);
- sun6i_isp_params_configure_base(isp_dev);
+ sun6i_isp_params_configure_base(isp_dev, mbus_format);
/* Default config is only applied at the very first stream start. */
if (state->configured)
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h
index 50f10f879c42..c0d6cff95d54 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.h
@@ -36,8 +36,8 @@ struct sun6i_isp_params {
/* Params */
-void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev);
-
+void sun6i_isp_params_configure(struct sun6i_isp_device *isp_dev,
+ const struct v4l2_mbus_framefmt *mbus_format);
/* State */
void sun6i_isp_params_state_update(struct sun6i_isp_device *isp_dev,
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
index 46a334b602f1..9073a7f3f8c8 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.c
@@ -15,17 +15,6 @@
#include "sun6i_isp_proc.h"
#include "sun6i_isp_reg.h"
-/* Helpers */
-
-void sun6i_isp_proc_dimensions(struct sun6i_isp_device *isp_dev,
- unsigned int *width, unsigned int *height)
-{
- if (width)
- *width = isp_dev->proc.mbus_format.width;
- if (height)
- *height = isp_dev->proc.mbus_format.height;
-}
-
/* Format */
static const struct sun6i_isp_proc_format sun6i_isp_proc_formats[] = {
@@ -137,9 +126,10 @@ static void sun6i_isp_proc_disable(struct sun6i_isp_device *isp_dev)
regmap_write(regmap, SUN6I_ISP_FE_CFG_REG, 0);
}
-static void sun6i_isp_proc_configure(struct sun6i_isp_device *isp_dev)
+static void
+sun6i_isp_proc_configure(struct sun6i_isp_device *isp_dev,
+ const struct v4l2_mbus_framefmt *mbus_format)
{
- struct v4l2_mbus_framefmt *mbus_format = &isp_dev->proc.mbus_format;
const struct sun6i_isp_proc_format *format;
u32 value;
@@ -173,6 +163,8 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
struct sun6i_isp_proc_source *source;
struct v4l2_subdev *source_subdev;
struct media_pad *remote_pad;
+ struct v4l2_subdev_state *state;
+ const struct v4l2_mbus_framefmt *mbus_format;
int ret;
/* Source */
@@ -191,6 +183,10 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
else
source = &proc->source_csi1;
+ /* Active State */
+
+ state = v4l2_subdev_lock_and_get_active_state(subdev);
+
if (!on) {
sun6i_isp_proc_irq_disable(isp_dev);
v4l2_subdev_call(source_subdev, video, s_stream, 0);
@@ -202,7 +198,7 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
- return ret;
+ goto unlock;
/* Clear */
@@ -210,9 +206,12 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
/* Configure */
+ mbus_format = v4l2_subdev_state_get_format(state,
+ SUN6I_ISP_PROC_PAD_SINK_CSI);
+
sun6i_isp_tables_configure(isp_dev);
- sun6i_isp_params_configure(isp_dev);
- sun6i_isp_proc_configure(isp_dev);
+ sun6i_isp_params_configure(isp_dev, mbus_format);
+ sun6i_isp_proc_configure(isp_dev, mbus_format);
sun6i_isp_capture_configure(isp_dev);
/* State Update */
@@ -230,13 +229,17 @@ static int sun6i_isp_proc_s_stream(struct v4l2_subdev *subdev, int on)
goto disable;
}
- return 0;
+ ret = 0;
+ goto unlock;
disable:
sun6i_isp_proc_disable(isp_dev);
pm_runtime_put(dev);
+unlock:
+ v4l2_subdev_unlock_state(state);
+
return ret;
}
@@ -259,21 +262,22 @@ sun6i_isp_proc_mbus_format_prepare(struct v4l2_mbus_framefmt *mbus_format)
static int sun6i_isp_proc_init_state(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state)
{
- struct sun6i_isp_device *isp_dev = v4l2_get_subdevdata(subdev);
- unsigned int pad = SUN6I_ISP_PROC_PAD_SINK_CSI;
- struct v4l2_mbus_framefmt *mbus_format =
- v4l2_subdev_state_get_format(state, pad);
- struct mutex *lock = &isp_dev->proc.lock;
+ unsigned int pad;
- mutex_lock(lock);
+ for (pad = 0; pad < subdev->entity.num_pads; pad++) {
+ struct v4l2_mbus_framefmt *mbus_format;
- mbus_format->code = sun6i_isp_proc_formats[0].mbus_code;
- mbus_format->width = 1280;
- mbus_format->height = 720;
+ if (pad == SUN6I_ISP_PROC_PAD_SINK_PARAMS)
+ continue;
- sun6i_isp_proc_mbus_format_prepare(mbus_format);
+ mbus_format = v4l2_subdev_state_get_format(state, pad);
- mutex_unlock(lock);
+ mbus_format->code = sun6i_isp_proc_formats[0].mbus_code;
+ mbus_format->width = 1280;
+ mbus_format->height = 720;
+
+ sun6i_isp_proc_mbus_format_prepare(mbus_format);
+ }
return 0;
}
@@ -291,53 +295,31 @@ sun6i_isp_proc_enum_mbus_code(struct v4l2_subdev *subdev,
return 0;
}
-static int sun6i_isp_proc_get_fmt(struct v4l2_subdev *subdev,
- struct v4l2_subdev_state *state,
- struct v4l2_subdev_format *format)
-{
- struct sun6i_isp_device *isp_dev = v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &isp_dev->proc.lock;
-
- mutex_lock(lock);
-
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *mbus_format = *v4l2_subdev_state_get_format(state,
- format->pad);
- else
- *mbus_format = isp_dev->proc.mbus_format;
-
- mutex_unlock(lock);
-
- return 0;
-}
-
static int sun6i_isp_proc_set_fmt(struct v4l2_subdev *subdev,
struct v4l2_subdev_state *state,
struct v4l2_subdev_format *format)
{
- struct sun6i_isp_device *isp_dev = v4l2_get_subdevdata(subdev);
- struct v4l2_mbus_framefmt *mbus_format = &format->format;
- struct mutex *lock = &isp_dev->proc.lock;
+ struct v4l2_mbus_framefmt *mbus_format;
- mutex_lock(lock);
+ if (format->pad != SUN6I_ISP_PROC_PAD_SINK_CSI)
+ return v4l2_subdev_get_fmt(subdev, state, format);
- sun6i_isp_proc_mbus_format_prepare(mbus_format);
+ sun6i_isp_proc_mbus_format_prepare(&format->format);
- if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *v4l2_subdev_state_get_format(state, format->pad) =
- *mbus_format;
- else
- isp_dev->proc.mbus_format = *mbus_format;
+ mbus_format = v4l2_subdev_state_get_format(state, format->pad);
+ *mbus_format = format->format;
- mutex_unlock(lock);
+ /* Propagate the format to the source pad. */
+ mbus_format = v4l2_subdev_state_get_format(state,
+ SUN6I_ISP_PROC_PAD_SOURCE);
+ *mbus_format = format->format;
return 0;
}
static const struct v4l2_subdev_pad_ops sun6i_isp_proc_pad_ops = {
.enum_mbus_code = sun6i_isp_proc_enum_mbus_code,
- .get_fmt = sun6i_isp_proc_get_fmt,
+ .get_fmt = v4l2_subdev_get_fmt,
.set_fmt = sun6i_isp_proc_set_fmt,
};
@@ -499,8 +481,6 @@ int sun6i_isp_proc_setup(struct sun6i_isp_device *isp_dev)
struct media_pad *pads = proc->pads;
int ret;
- mutex_init(&proc->lock);
-
/* V4L2 Subdev */
v4l2_subdev_init(subdev, &sun6i_isp_proc_subdev_ops);
@@ -532,10 +512,14 @@ int sun6i_isp_proc_setup(struct sun6i_isp_device *isp_dev)
/* V4L2 Subdev */
+ ret = v4l2_subdev_init_finalize(subdev);
+ if (ret < 0)
+ goto error_media_entity;
+
ret = v4l2_device_register_subdev(v4l2_dev, subdev);
if (ret < 0) {
v4l2_err(v4l2_dev, "failed to register v4l2 subdev: %d\n", ret);
- goto error_media_entity;
+ goto error_subdev_finalize;
}
/* V4L2 Async */
@@ -562,6 +546,9 @@ int sun6i_isp_proc_setup(struct sun6i_isp_device *isp_dev)
v4l2_device_unregister_subdev(subdev);
+error_subdev_finalize:
+ v4l2_subdev_cleanup(subdev);
+
error_media_entity:
media_entity_cleanup(&subdev->entity);
@@ -577,5 +564,7 @@ void sun6i_isp_proc_cleanup(struct sun6i_isp_device *isp_dev)
v4l2_async_nf_cleanup(notifier);
v4l2_device_unregister_subdev(subdev);
+ v4l2_subdev_cleanup(subdev);
+
media_entity_cleanup(&subdev->entity);
}
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h
index db6738a39147..26c4327c5ed7 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_proc.h
@@ -42,18 +42,11 @@ struct sun6i_isp_proc {
struct v4l2_subdev subdev;
struct media_pad pads[3];
struct v4l2_async_notifier notifier;
- struct v4l2_mbus_framefmt mbus_format;
- struct mutex lock; /* Mbus format lock. */
struct sun6i_isp_proc_source source_csi0;
struct sun6i_isp_proc_source source_csi1;
};
-/* Helpers */
-
-void sun6i_isp_proc_dimensions(struct sun6i_isp_device *isp_dev,
- unsigned int *width, unsigned int *height);
-
/* Format */
const struct sun6i_isp_proc_format *sun6i_isp_proc_format_find(u32 mbus_code);
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v5 4/4] driver core: platform: set mod_name in driver registration
From: Shashank Balaji @ 2026-05-18 10:32 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: Suzuki K Poulose, James Clark, Alexander Shishkin,
Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Jonathan Corbet, Shuah Khan,
Luis Chamberlain, Petr Pavlu, Daniel Gomez, Sami Tolvanen,
Aaron Tomlin, Mike Leach, Leo Yan, Thierry Reding,
Jonathan Hunter, Rahul Bukte, linux-kernel, coresight,
linux-arm-kernel, driver-core, rust-for-linux, linux-doc,
Daniel Palmer, Tim Bird, linux-modules, linux-tegra, Sumit Gupta
In-Reply-To: <2026051827-curler-disjoin-c83f@gregkh>
On Mon, May 18, 2026 at 12:27:13PM +0200, Greg Kroah-Hartman wrote:
> On Mon, May 18, 2026 at 07:20:00PM +0900, Shashank Balaji wrote:
> > Pass KBUILD_MODNAME through the driver registration macro so that
> > the driver core can create the module symlink in sysfs for built-in
> > drivers, and fixup all callers.
> >
> > The Rust platform adapter is updated to pass the module name through to the new
> > parameter.
> >
> > Tested on qemu with:
> > - x86 defconfig + CONFIG_RUST
> > - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT stuff
> >
> > Examples after this patch:
> >
> > /sys/bus/platform/drivers/...
> > coresight-itnoc/module -> coresight_tnoc
> > coresight-static-tpdm/module -> coresight_tpdm
> > coresight-catu-platform/module -> coresight_catu
> > serial8250/module -> 8250
> > acpi-ged/module -> acpi
> > vmclock/module -> ptp_vmclock
> >
> > Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> > Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> > Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> > ---
> > This patch depends on patches 1, 2, 3
> > ---
> > Documentation/driver-api/driver-model/platform.rst | 3 ++-
> > drivers/base/platform.c | 21 ++++++++++++++-------
> > drivers/hwtracing/coresight/coresight-core.c | 5 +++--
> > include/linux/coresight.h | 5 +++--
> > include/linux/platform_device.h | 17 +++++++++--------
> > rust/kernel/platform.rs | 4 +++-
> > 6 files changed, 34 insertions(+), 21 deletions(-)
> >
> > diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
> > index cf5ff48d3115..9673470bded2 100644
> > --- a/Documentation/driver-api/driver-model/platform.rst
> > +++ b/Documentation/driver-api/driver-model/platform.rst
> > @@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
> > provides helpers to register and unregister an array of drivers::
> >
> > int __platform_register_drivers(struct platform_driver * const *drivers,
> > - unsigned int count, struct module *owner);
> > + unsigned int count, struct module *owner,
> > + const char *mod_name);
>
> Why can't you just use the owner->name value instead? They are always
> the same here, right?
owner is NULL for built-in modules.
^ permalink raw reply
* [PATCH 15/16] media: sun6i-isp: Add support for MC-centric format enumeration
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
Just make sure the provided mbus code is supported and carry on with the
existing implementation since the pixelformat is independent from the
mbus code.
The params video node only supports a single format and does not care
about the mbus format, but we can still report MC-centric support.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c | 9 ++++++++-
drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c | 3 ++-
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index 24e731bcabe9..372b9331bd6d 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -436,8 +436,14 @@ static int sun6i_isp_capture_querycap(struct file *file, void *priv,
static int sun6i_isp_capture_enum_fmt(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtdesc)
{
+ u32 mbus_code = fmtdesc->mbus_code;
u32 index = fmtdesc->index;
+ if (mbus_code && !sun6i_isp_proc_format_find(mbus_code))
+ return -EINVAL;
+
+ /* Capture format is independent from proc format. */
+
if (index >= ARRAY_SIZE(sun6i_isp_capture_formats))
return -EINVAL;
@@ -697,7 +703,8 @@ int sun6i_isp_capture_setup(struct sun6i_isp_device *isp_dev)
strscpy(video_dev->name, SUN6I_ISP_CAPTURE_NAME,
sizeof(video_dev->name));
- video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+ video_dev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
+ V4L2_CAP_IO_MC;
video_dev->vfl_dir = VFL_DIR_RX;
video_dev->release = video_device_release_empty;
video_dev->fops = &sun6i_isp_capture_fops;
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
index 0cc48e2bc8c6..2622e5a07817 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_params.c
@@ -531,7 +531,8 @@ int sun6i_isp_params_setup(struct sun6i_isp_device *isp_dev)
strscpy(video_dev->name, SUN6I_ISP_PARAMS_NAME,
sizeof(video_dev->name));
- video_dev->device_caps = V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING;
+ video_dev->device_caps = V4L2_CAP_META_OUTPUT | V4L2_CAP_STREAMING |
+ V4L2_CAP_IO_MC;
video_dev->vfl_dir = VFL_DIR_TX;
video_dev->release = video_device_release_empty;
video_dev->fops = &sun6i_isp_params_fops;
--
2.54.0
^ permalink raw reply related
* Re: [PATCH 2/5] arm_mpam: Split the locking around the mon_sel registers
From: Niyas Sait @ 2026-05-18 10:31 UTC (permalink / raw)
To: andre.przywara
Cc: ben.horgan, catalin.marinas, fenghuay, guohanjun, james.morse,
jic23, lenb, linux-acpi, linux-arm-kernel, linux-kernel,
lpieralisi, rafael, reinette.chatre, sudeep.holla, will
In-Reply-To: <20260429141339.3171205-3-andre.przywara@arm.com>
Hi Andre,
On Wed, Apr 29, 2026 at 04:13:36PM +0200, Andre Przywara wrote:
> @@ -1635,8 +1643,11 @@ static int mpam_restore_mbwu_state(void *_ris)
> u64 val;
> struct mon_read mwbu_arg;
> struct mpam_msc_ris *ris = _ris;
> + struct mpam_msc *msc = ris->vmsc->msc;
> struct mpam_class *class = ris->vmsc->comp->class;
>
> + mpam_mon_sel_outer_lock(msc);
> +
> for (i = 0; i < ris->props.num_mbwu_mon; i++) {
> if (ris->mbwu_state[i].enabled) {
> mwbu_arg.ris = ris;
> @@ -1648,10 +1659,12 @@ static int mpam_restore_mbwu_state(void *_ris)
> }
> }
>
> + mpam_mon_sel_outer_unlock(msc);
> +
> return 0;
> }
There looks to be a lock nesting issue here. mpam_reprogram_msc() already
holds outer_mon_sel_lock when it calls mpam_restore_mbwu_state(), and
mpam_restore_mbwu_state() then takes the same outer lock again.
Thanks,
Niyas
^ permalink raw reply
* [PATCH 16/16] media: sun6i-isp: Add support for frame size enumeration
From: Paul Kocialkowski @ 2026-05-18 10:24 UTC (permalink / raw)
To: linux-media, linux-arm-kernel, linux-sunxi, linux-kernel,
linux-staging
Cc: Paul Kocialkowski, Mauro Carvalho Chehab, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, Greg Kroah-Hartman, Arash Golgol,
Laurent Pinchart, Nicolas Dufresne
In-Reply-To: <20260518102451.417971-1-paulk@sys-base.io>
This implements the enum_framesizes operation, which reports support for
even sizes.
Signed-off-by: Paul Kocialkowski <paulk@sys-base.io>
---
.../media/sunxi/sun6i-isp/sun6i_isp_capture.c | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
index 372b9331bd6d..e638ec32c7cd 100644
--- a/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
+++ b/drivers/staging/media/sunxi/sun6i-isp/sun6i_isp_capture.c
@@ -452,6 +452,26 @@ static int sun6i_isp_capture_enum_fmt(struct file *file, void *priv,
return 0;
}
+static int sun6i_isp_capture_enum_framesizes(struct file *file, void *fh,
+ struct v4l2_frmsizeenum *frmsize)
+{
+ if (frmsize->index)
+ return -EINVAL;
+
+ if (!sun6i_isp_capture_format_find(frmsize->pixel_format))
+ return -EINVAL;
+
+ frmsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
+ frmsize->stepwise.min_width = SUN6I_ISP_CAPTURE_WIDTH_MIN;
+ frmsize->stepwise.max_width = SUN6I_ISP_CAPTURE_WIDTH_MAX;
+ frmsize->stepwise.min_height = SUN6I_ISP_CAPTURE_HEIGHT_MIN;
+ frmsize->stepwise.max_height = SUN6I_ISP_CAPTURE_HEIGHT_MAX;
+ frmsize->stepwise.step_width = 2;
+ frmsize->stepwise.step_height = 2;
+
+ return 0;
+}
+
static int sun6i_isp_capture_g_fmt(struct file *file, void *priv,
struct v4l2_format *format)
{
@@ -522,6 +542,8 @@ static const struct v4l2_ioctl_ops sun6i_isp_capture_ioctl_ops = {
.vidioc_s_fmt_vid_cap = sun6i_isp_capture_s_fmt,
.vidioc_try_fmt_vid_cap = sun6i_isp_capture_try_fmt,
+ .vidioc_enum_framesizes = sun6i_isp_capture_enum_framesizes,
+
.vidioc_enum_input = sun6i_isp_capture_enum_input,
.vidioc_g_input = sun6i_isp_capture_g_input,
.vidioc_s_input = sun6i_isp_capture_s_input,
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v2 1/3] dt-bindings: arm: aspeed: add Anacapa EVT1 EVT2 board
From: Colin Huang @ 2026-05-18 10:43 UTC (permalink / raw)
To: Conor Dooley
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Joel Stanley,
Andrew Jeffery, devicetree, linux-arm-kernel, linux-aspeed,
linux-kernel, colin.huang2
In-Reply-To: <20260420-garnet-goal-4a284a8818fc@spud>
Conor Dooley <conor@kernel.org> 於 2026年4月20日週一 下午11:36寫道:
>
> On Mon, Apr 20, 2026 at 01:41:30PM +0800, Colin Huang wrote:
> > Conor Dooley <conor@kernel.org> 於 2026年4月9日週四 下午11:36寫道:
> > >
> > > On Thu, Apr 09, 2026 at 07:40:26PM +0800, Colin Huang wrote:
> > > > Document Anacapa BMC EVT1 and EVT2 compatibles.
> > > >
> > > > Signed-off-by: Colin Huang <u8813345@gmail.com>
> > >
> > > Acked-by: Conor Dooley <conor.dooley@microchip.com>
> > > pw-bot: not-applicable
> >
> > Hi
> > Could anyone let me know, what is my next step which I need to do?
> > I can't find the changed in for-next branch of
> > https://git.kernel.org/pub/scm/linux/kernel/git/bmc/linux.git .
> > Thanks.
>
> You wait for the merge window to end and the maintainer to apply your
> patches.
Hi
soft-remind for these patches merge.
^ 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