* [PATCH v1 03/10] devfreq: Add a dedicated mutex for the governor list
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
Accessing the list of available governors ('devfreq_governor_list') is
currently guarded by 'devfreq_list_lock', but 'devfreq_list_lock' is
supposed to protect the list of devfreq devices ('devfreq_list').
The scope of 'devfreq_list_lock' is too broad to maintain.
'devfreq_governor_list' should have its own mutex lock rather than share
with 'devfreq_list'.
Add a governor mutex lock and lock it when accessing the governor list.
Remove locking of 'devfreq_list_lock' around 'devfreq_governor_list'.
This is also a preparation for further refactoring around
try_then_request_governor().
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 31 +++++++++++++------------------
1 file changed, 13 insertions(+), 18 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 83f75dc21c99..e54e3092e0e0 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -49,6 +49,7 @@ static struct workqueue_struct *devfreq_wq;
/* The list of all device-devfreq governors */
static LIST_HEAD(devfreq_governor_list);
+static DEFINE_MUTEX(devfreq_gov_lock);
/* The list of all device-devfreq */
static LIST_HEAD(devfreq_list);
static DEFINE_MUTEX(devfreq_list_lock);
@@ -255,19 +256,18 @@ EXPORT_SYMBOL(devfreq_update_status);
* @name: name of the governor
*
* Search the list of devfreq governors and return the matched
- * governor's pointer. devfreq_list_lock should be held by the caller.
+ * governor's pointer.
*/
static struct devfreq_governor *find_devfreq_governor(const char *name)
{
struct devfreq_governor *tmp_governor;
- lockdep_assert_held(&devfreq_list_lock);
-
if (IS_ERR_OR_NULL(name)) {
pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
return ERR_PTR(-EINVAL);
}
+ guard(mutex)(&devfreq_gov_lock);
list_for_each_entry(tmp_governor, &devfreq_governor_list, node) {
if (!strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
return tmp_governor;
@@ -284,16 +284,13 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
* Search the list of devfreq governors and request the module and try again
* if is not found. This can happen when both drivers (the governor driver
* and the driver that call devfreq_add_device) are built as modules.
- * devfreq_list_lock should be held by the caller. Returns the matched
- * governor's pointer or an error pointer.
+ * Returns the matched governor's pointer or an error pointer.
*/
static struct devfreq_governor *try_then_request_governor(const char *name)
{
struct devfreq_governor *governor;
int err = 0;
- lockdep_assert_held(&devfreq_list_lock);
-
if (IS_ERR_OR_NULL(name)) {
pr_err("DEVFREQ: %s: Invalid parameters\n", __func__);
return ERR_PTR(-EINVAL);
@@ -301,15 +298,12 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
governor = find_devfreq_governor(name);
if (IS_ERR(governor)) {
- mutex_unlock(&devfreq_list_lock);
-
if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND,
DEVFREQ_NAME_LEN))
err = request_module("governor_%s", "simpleondemand");
else
err = request_module("governor_%s", name);
/* Restore previous state before return */
- mutex_lock(&devfreq_list_lock);
if (err)
return (err < 0) ? ERR_PTR(err) : ERR_PTR(-EINVAL);
@@ -933,16 +927,15 @@ struct devfreq *devfreq_add_device(struct device *dev,
if (err)
goto err_devfreq;
- mutex_lock(&devfreq_list_lock);
-
governor = try_then_request_governor(governor_name);
if (IS_ERR(governor)) {
dev_err(dev, "%s: Unable to find governor for the device\n",
__func__);
err = PTR_ERR(governor);
- goto err_init;
+ goto err_devfreq;
}
+ mutex_lock(&devfreq_list_lock);
devfreq->governor = governor;
err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START,
NULL);
@@ -1269,7 +1262,6 @@ int devfreq_add_governor(struct devfreq_governor *governor)
return -EINVAL;
}
- guard(mutex)(&devfreq_list_lock);
g = find_devfreq_governor(governor->name);
if (!IS_ERR(g)) {
pr_err("%s: governor %s already registered\n", __func__,
@@ -1277,8 +1269,10 @@ int devfreq_add_governor(struct devfreq_governor *governor)
return -EINVAL;
}
- list_add(&governor->node, &devfreq_governor_list);
+ scoped_guard(mutex, &devfreq_gov_lock)
+ list_add(&governor->node, &devfreq_governor_list);
+ guard(mutex)(&devfreq_list_lock);
list_for_each_entry(devfreq, &devfreq_list, node) {
int ret = 0;
struct device *dev = devfreq->dev.parent;
@@ -1355,7 +1349,6 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
return -EINVAL;
}
- guard(mutex)(&devfreq_list_lock);
g = find_devfreq_governor(governor->name);
if (IS_ERR(g)) {
pr_err("%s: governor %s not registered\n", __func__,
@@ -1363,6 +1356,7 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
return PTR_ERR(g);
}
+ guard(mutex)(&devfreq_list_lock);
list_for_each_entry(devfreq, &devfreq_list, node) {
int ret;
struct device *dev = devfreq->dev.parent;
@@ -1383,7 +1377,8 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
}
}
- list_del(&governor->node);
+ scoped_guard(mutex, &devfreq_gov_lock)
+ list_del(&governor->node);
return 0;
}
@@ -1423,11 +1418,11 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
if (ret != 1)
return -EINVAL;
- guard(mutex)(&devfreq_list_lock);
governor = try_then_request_governor(str_governor);
if (IS_ERR(governor))
return PTR_ERR(governor);
+ guard(mutex)(&devfreq_list_lock);
if (df->governor == governor)
return count;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 09/10] devfreq: Allow showing available_governors when device governor is NULL
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
From: Zhi Wang <wangzhi12@huawei.com>
Allow showing available_governors via sysfs when a device's governor is
NULL, enabling reconfiguration of the device's governor.
Before:
$: echo simple_ondemand > governor
$: rmmod -f governor_simpleondemand
$: cat available_governors
cat: available_governors: Invalid argument
After:
$: echo simple_ondemand > governor
$: rmmod -f governor_simpleondemand
$: cat available_governors
hisi_platform userspace powersave performance
Signed-off-by: Zhi Wang <wangzhi12@huawei.com>
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index c6b670b8fd22..5aebb32e89b0 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1461,16 +1461,13 @@ static ssize_t available_governors_show(struct device *d,
struct devfreq *df = to_devfreq(d);
ssize_t count = 0;
- if (!df->governor)
- return -EINVAL;
-
mutex_lock(&devfreq_list_lock);
/*
* The devfreq with immutable governor (e.g., passive) shows
* only own governor.
*/
- if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)) {
+ if (df->governor && IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)) {
count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
"%s ", df->governor->name);
/*
--
2.43.0
^ permalink raw reply related
* [PATCH v1 05/10] devfreq: Remove dead code in devfreq_add_governor()
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
In devfreq_add_governor(), we've already checked the governor list to
see if there's a governor already registered with the same name.
It's impossible that a devfreq device is using such a governor, so the
check can never be true and the error handling is unreachable.
Remove the redundant error handling to simplify the logic.
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 34 ----------------------------------
1 file changed, 34 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 378a01f71165..7e71e8c76303 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1300,7 +1300,6 @@ void devfreq_resume(void)
int devfreq_add_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
- struct devfreq *devfreq;
if (!governor) {
pr_err("%s: Invalid parameters.\n", __func__);
@@ -1317,39 +1316,6 @@ int devfreq_add_governor(struct devfreq_governor *governor)
scoped_guard(mutex, &devfreq_gov_lock)
list_add(&governor->node, &devfreq_governor_list);
- guard(mutex)(&devfreq_list_lock);
- list_for_each_entry(devfreq, &devfreq_list, node) {
- int ret = 0;
- struct device *dev = devfreq->dev.parent;
-
- if (!strncmp(devfreq->governor->name, governor->name,
- DEVFREQ_NAME_LEN)) {
- /* The following should never occur */
- if (devfreq->governor) {
- dev_warn(dev,
- "%s: Governor %s already present\n",
- __func__, devfreq->governor->name);
- ret = devfreq->governor->event_handler(devfreq,
- DEVFREQ_GOV_STOP, NULL);
- if (ret) {
- dev_warn(dev,
- "%s: Governor %s stop = %d\n",
- __func__,
- devfreq->governor->name, ret);
- }
- /* Fall through */
- }
- devfreq->governor = governor;
- ret = devfreq->governor->event_handler(devfreq,
- DEVFREQ_GOV_START, NULL);
- if (ret) {
- dev_warn(dev, "%s: Governor %s start=%d\n",
- __func__, devfreq->governor->name,
- ret);
- }
- }
- }
-
return 0;
}
EXPORT_SYMBOL(devfreq_add_governor);
--
2.43.0
^ permalink raw reply related
* [PATCH v1 00/10] devfreq: Fix NULL pointer dereference when a governor module is unloaded
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
When compiled as a kernel module, the governor module can be dynamically
inserted or removed. 'devfreq->governor' would become NULL if the governor
module is removed when it's in use, and NULL pointer dereference would be
triggered. A similar issue was also reported in [1].
To address this issue:
Patch 1-5 rework mutex, factor out a common governor setting function, and
clean up some unreachable code.
Patch 6-8 prevent a governor module in use from being removed (except for
force unload) by getting/putting a refcount of the governor's module when
switching governors.
Patch 9-10 allow 'governor' and 'available_governors' to work normally even
when a governor module in use is force unloaded.
Note that this series is based on [1] or devfreq-next, otherwise code
would conflict.
[1] https://lore.kernel.org/all/20260319091409.998397-1-tianyaxiong@kylinos.cn/
[2] https://lore.kernel.org/all/20251216031153.2242306-1-zhangpengjie2@huawei.com/
Jie Zhan (8):
devfreq: Use mutex guard in governor_store()
devfreq: Use mutex guard in devfreq_add/remove_governor()
devfreq: Add a dedicated mutex for the governor list
devfreq: Factor out devfreq_set_governor[_locked]()
devfreq: Remove dead code in devfreq_add_governor()
devfreq: Add module owner to devfreq governor
devfreq: Get and put module refcount when switching governor
devfreq: Allow find_devfreq_governor() to get module refcount
Zhi Wang (2):
devfreq: Allow showing available_governors when device governor is
NULL
devfreq: Allow setting governor when device governor is NULL
drivers/devfreq/devfreq.c | 287 +++++++++++++------------------
include/linux/devfreq-governor.h | 26 ++-
2 files changed, 143 insertions(+), 170 deletions(-)
--
2.43.0
^ permalink raw reply
* [PATCH v1 04/10] devfreq: Factor out devfreq_set_governor[_locked]()
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
Factor out common governor setting logic into devfreq_set_governor() to
reduce code duplication in governor_store() and devfreq_add_device().
Additionally, devfreq_set_governor_locked() is used when
'devfreq_list_lock' is already held by the caller, e.g. in
devfreq_set_governor(), to avoid an immediate relock after unlock.
Note that the new functions support setting a governor even if
devfreq->governor is NULL.
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 129 +++++++++++++++++++-------------------
1 file changed, 63 insertions(+), 66 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index e54e3092e0e0..378a01f71165 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -313,6 +313,64 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
return governor;
}
+static int devfreq_set_governor_locked(struct devfreq *df,
+ const struct devfreq_governor *new_gov)
+{
+ const struct devfreq_governor *old_gov;
+ struct device *dev;
+ int ret;
+
+ old_gov = df->governor;
+ dev = &df->dev;
+
+ if (old_gov) {
+ if (old_gov == new_gov)
+ return 0;
+
+ if (IS_SUPPORTED_FLAG(old_gov->flags, IMMUTABLE) ||
+ IS_SUPPORTED_FLAG(new_gov->flags, IMMUTABLE))
+ return -EINVAL;
+
+ /* Stop the current governor */
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
+ __func__, df->governor->name, ret);
+ return ret;
+ }
+ }
+
+ /* Start the new governor */
+ df->governor = new_gov;
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
+ if (ret) {
+ dev_warn(dev, "%s: Governor %s not started(%d)\n",
+ __func__, df->governor->name, ret);
+
+ if (!old_gov)
+ return ret;
+
+ /* Restore previous governor */
+ df->governor = old_gov;
+ ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
+ if (ret) {
+ dev_err(dev, "%s: restore Governor %s failed (%d)\n",
+ __func__, old_gov->name, ret);
+ df->governor = NULL;
+ return ret;
+ }
+ }
+
+ return sysfs_update_group(&df->dev.kobj, &gov_attr_group);
+}
+
+static int devfreq_set_governor(struct devfreq *df,
+ const struct devfreq_governor *new_gov)
+{
+ guard(mutex)(&devfreq_list_lock);
+ return devfreq_set_governor_locked(df, new_gov);
+}
+
static int devfreq_notify_transition(struct devfreq *devfreq,
struct devfreq_freqs *freqs, unsigned int state)
{
@@ -936,22 +994,11 @@ struct devfreq *devfreq_add_device(struct device *dev,
}
mutex_lock(&devfreq_list_lock);
- devfreq->governor = governor;
- err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START,
- NULL);
- if (err) {
- dev_err_probe(dev, err,
- "%s: Unable to start governor for the device\n",
- __func__);
- goto err_init;
- }
-
- err = sysfs_update_group(&devfreq->dev.kobj, &gov_attr_group);
+ err = devfreq_set_governor_locked(devfreq, governor);
if (err)
- goto err_init;
+ goto err_devfreq;
list_add(&devfreq->node, &devfreq_list);
-
mutex_unlock(&devfreq_list_lock);
if (devfreq->profile->is_cooling_device) {
@@ -962,8 +1009,6 @@ struct devfreq *devfreq_add_device(struct device *dev,
return devfreq;
-err_init:
- mutex_unlock(&devfreq_list_lock);
err_devfreq:
devfreq_remove_device(devfreq);
devfreq = NULL;
@@ -1409,7 +1454,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
struct devfreq *df = to_devfreq(dev);
int ret;
char str_governor[DEVFREQ_NAME_LEN + 1];
- const struct devfreq_governor *governor, *prev_governor;
+ const struct devfreq_governor *governor;
if (!df->governor)
return -EINVAL;
@@ -1422,57 +1467,9 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
if (IS_ERR(governor))
return PTR_ERR(governor);
- guard(mutex)(&devfreq_list_lock);
- if (df->governor == governor)
- return count;
-
- if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE) ||
- IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE))
- return -EINVAL;
-
- /*
- * Stop the current governor and remove the specific sysfs files
- * which depend on current governor.
- */
- ret = df->governor->event_handler(df, DEVFREQ_GOV_STOP, NULL);
- if (ret) {
- dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
- __func__, df->governor->name, ret);
- return ret;
- }
-
- /*
- * Start the new governor and create the specific sysfs files
- * which depend on the new governor.
- */
- prev_governor = df->governor;
- df->governor = governor;
- ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
- if (ret) {
- dev_warn(dev, "%s: Governor %s not started(%d)\n",
- __func__, df->governor->name, ret);
-
- /* Restore previous governor */
- df->governor = prev_governor;
- ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
- if (ret) {
- dev_err(dev,
- "%s: reverting to Governor %s failed (%d)\n",
- __func__, prev_governor->name, ret);
- df->governor = NULL;
- return ret;
- }
- }
-
- /*
- * Create the sysfs files for the new governor. But if failed to start
- * the new governor, restore the sysfs files of previous governor.
- */
- ret = sysfs_update_group(&df->dev.kobj, &gov_attr_group);
- if (ret)
- return ret;
+ ret = devfreq_set_governor(df, governor);
- return count;
+ return ret ? ret : count;
}
static DEVICE_ATTR_RW(governor);
--
2.43.0
^ permalink raw reply related
* [PATCH v1 01/10] devfreq: Use mutex guard in governor_store()
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
Use mutex guard in governor_store() so as to simplify the locking logic.
No functional impact intended.
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index fcad3edceeea..21aa9661de0b 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1431,20 +1431,17 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
if (ret != 1)
return -EINVAL;
- mutex_lock(&devfreq_list_lock);
+ guard(mutex)(&devfreq_list_lock);
governor = try_then_request_governor(str_governor);
- if (IS_ERR(governor)) {
- ret = PTR_ERR(governor);
- goto out;
- }
- if (df->governor == governor) {
- ret = 0;
- goto out;
- } else if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE)
- || IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE)) {
- ret = -EINVAL;
- goto out;
- }
+ if (IS_ERR(governor))
+ return PTR_ERR(governor);
+
+ if (df->governor == governor)
+ return count;
+
+ if (IS_SUPPORTED_FLAG(df->governor->flags, IMMUTABLE) ||
+ IS_SUPPORTED_FLAG(governor->flags, IMMUTABLE))
+ return -EINVAL;
/*
* Stop the current governor and remove the specific sysfs files
@@ -1454,7 +1451,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
if (ret) {
dev_warn(dev, "%s: Governor %s not stopped(%d)\n",
__func__, df->governor->name, ret);
- goto out;
+ return ret;
}
/*
@@ -1476,7 +1473,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
"%s: reverting to Governor %s failed (%d)\n",
__func__, prev_governor->name, ret);
df->governor = NULL;
- goto out;
+ return ret;
}
}
@@ -1485,13 +1482,10 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
* the new governor, restore the sysfs files of previous governor.
*/
ret = sysfs_update_group(&df->dev.kobj, &gov_attr_group);
+ if (ret)
+ return ret;
-out:
- mutex_unlock(&devfreq_list_lock);
-
- if (!ret)
- ret = count;
- return ret;
+ return count;
}
static DEVICE_ATTR_RW(governor);
--
2.43.0
^ permalink raw reply related
* [PATCH v1 02/10] devfreq: Use mutex guard in devfreq_add/remove_governor()
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
Use mutex guard in devfreq_add/remove_governor() so as to simplify the
locking logic.
No functional impact intended.
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 22 +++++++---------------
1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 21aa9661de0b..83f75dc21c99 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1263,20 +1263,18 @@ int devfreq_add_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
struct devfreq *devfreq;
- int err = 0;
if (!governor) {
pr_err("%s: Invalid parameters.\n", __func__);
return -EINVAL;
}
- mutex_lock(&devfreq_list_lock);
+ guard(mutex)(&devfreq_list_lock);
g = find_devfreq_governor(governor->name);
if (!IS_ERR(g)) {
pr_err("%s: governor %s already registered\n", __func__,
g->name);
- err = -EINVAL;
- goto err_out;
+ return -EINVAL;
}
list_add(&governor->node, &devfreq_governor_list);
@@ -1313,10 +1311,7 @@ int devfreq_add_governor(struct devfreq_governor *governor)
}
}
-err_out:
- mutex_unlock(&devfreq_list_lock);
-
- return err;
+ return 0;
}
EXPORT_SYMBOL(devfreq_add_governor);
@@ -1354,21 +1349,20 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
{
struct devfreq_governor *g;
struct devfreq *devfreq;
- int err = 0;
if (!governor) {
pr_err("%s: Invalid parameters.\n", __func__);
return -EINVAL;
}
- mutex_lock(&devfreq_list_lock);
+ guard(mutex)(&devfreq_list_lock);
g = find_devfreq_governor(governor->name);
if (IS_ERR(g)) {
pr_err("%s: governor %s not registered\n", __func__,
governor->name);
- err = PTR_ERR(g);
- goto err_out;
+ return PTR_ERR(g);
}
+
list_for_each_entry(devfreq, &devfreq_list, node) {
int ret;
struct device *dev = devfreq->dev.parent;
@@ -1390,10 +1384,8 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
}
list_del(&governor->node);
-err_out:
- mutex_unlock(&devfreq_list_lock);
- return err;
+ return 0;
}
EXPORT_SYMBOL(devfreq_remove_governor);
--
2.43.0
^ permalink raw reply related
* [PATCH v1 08/10] devfreq: Allow find_devfreq_governor() to get module refcount
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
Add a 'get' parameter for find_devfreq_governor() to optionally get a
refcount of the governor module.
Getting refcount in try_then_request_governor() prevents the governor
module from being removed during the governor setting phase.
However, in devfreq_add/remove_governor(), it doesn't need to get a
refcount of the governor module because it just checks whether a
governor registered with the same name exists or not.
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index ba09948915ba..c6b670b8fd22 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -254,11 +254,13 @@ EXPORT_SYMBOL(devfreq_update_status);
/**
* find_devfreq_governor() - find devfreq governor from name
* @name: name of the governor
+ * @get: whether to get a refcount of the governor module
*
* Search the list of devfreq governors and return the matched
* governor's pointer.
*/
-static struct devfreq_governor *find_devfreq_governor(const char *name)
+static struct devfreq_governor *find_devfreq_governor(const char *name,
+ bool get)
{
struct devfreq_governor *tmp_governor;
@@ -269,8 +271,13 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
guard(mutex)(&devfreq_gov_lock);
list_for_each_entry(tmp_governor, &devfreq_governor_list, node) {
- if (!strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
- return tmp_governor;
+ if (strncmp(tmp_governor->name, name, DEVFREQ_NAME_LEN))
+ continue;
+
+ if (get && !try_module_get(tmp_governor->owner))
+ return ERR_PTR(-EBUSY);
+
+ return tmp_governor;
}
return ERR_PTR(-ENODEV);
@@ -285,6 +292,9 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
* if is not found. This can happen when both drivers (the governor driver
* and the driver that call devfreq_add_device) are built as modules.
* Returns the matched governor's pointer or an error pointer.
+ * On success, this holds a refcount of the governor module to prevent the
+ * module from being unloaded during usage, so the caller should put a module
+ * refcount after using it.
*/
static struct devfreq_governor *try_then_request_governor(const char *name)
{
@@ -296,7 +306,7 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
return ERR_PTR(-EINVAL);
}
- governor = find_devfreq_governor(name);
+ governor = find_devfreq_governor(name, true);
if (IS_ERR(governor)) {
if (!strncmp(name, DEVFREQ_GOV_SIMPLE_ONDEMAND,
DEVFREQ_NAME_LEN))
@@ -307,7 +317,7 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
if (err)
return (err < 0) ? ERR_PTR(err) : ERR_PTR(-EINVAL);
- governor = find_devfreq_governor(name);
+ governor = find_devfreq_governor(name, true);
}
return governor;
@@ -1007,6 +1017,8 @@ struct devfreq *devfreq_add_device(struct device *dev,
if (err)
goto err_devfreq;
+ module_put(governor->owner);
+
list_add(&devfreq->node, &devfreq_list);
mutex_unlock(&devfreq_list_lock);
@@ -1312,7 +1324,7 @@ int __devfreq_add_governor(struct devfreq_governor *governor,
return -EINVAL;
}
- g = find_devfreq_governor(governor->name);
+ g = find_devfreq_governor(governor->name, false);
if (!IS_ERR(g)) {
pr_err("%s: governor %s already registered\n", __func__,
g->name);
@@ -1361,7 +1373,7 @@ int devfreq_remove_governor(struct devfreq_governor *governor)
return -EINVAL;
}
- g = find_devfreq_governor(governor->name);
+ g = find_devfreq_governor(governor->name, false);
if (IS_ERR(g)) {
pr_err("%s: governor %s not registered\n", __func__,
governor->name);
@@ -1436,6 +1448,8 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
ret = devfreq_set_governor(df, governor);
+ module_put(governor->owner);
+
return ret ? ret : count;
}
static DEVICE_ATTR_RW(governor);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 0/2] mmc: hisilicon: Convert dw-mshc bindings and fix dtbs
From: Ulf Hansson @ 2026-03-26 12:39 UTC (permalink / raw)
To: Wei Xu
Cc: Bhargav Joshi, devicetree, linux-arm-kernel, robh, krzk+dt,
conor+dt, zhangfei.gao, linux-mmc, daniel.baluta, simona.toaca,
d-gole, m-chawdhry, linux-kernel
In-Reply-To: <69C51640.8070408@hisilicon.com>
On Thu, 26 Mar 2026 at 12:19, Wei Xu <xuwei5@hisilicon.com> wrote:
>
> Hi Bhargav,
>
> On 2026/3/26 6:54, Bhargav Joshi wrote:
> > This series converts the Hisilicon dw-mshc text bindings to DT schema
> > format and cleans up legacy node names in Hisilicon board files.
> >
> > While testing the new YAML schema, dtbs_check flagged the hi3660,
> > hi3670, and hi6220 SoC files for using the non-standard 'dwmmc' node
> > name prefix. resulting in warnings.
> >
> > Patch 1 Convert to DT schema
> > Patch 2 updates the Hisilicon dtsi files to use standard 'mmc'
> > node name.
> >
> > Changes in v2:
> > - Patch 1:
> > - Grouped compatible strings into an enum.
> > - Replaced raw numbers with proper flags.
> > - Fixed property order and removed invalid hex values.
> > - Added explanation for clock order change in commit message.
> > - Collected Acked-by tag.
> > - Patch 2:
> > - No code changes.
> > - Collected Acked-by and Reviewed-by tags.
> >
> > Signed-off-by: Bhargav Joshi <rougueprince47@gmail.com>
> > ---
> > Note: this patch is part of the process for applying to GSoC device
> > tree bindings conversion project #
> > https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings
> >
> > - The file is enabled by arm64 defconfig (CONFIG_MMC_DW_K3=y)
> > - It is used in following
> > /arch/arm64/boot/dts/hisilicon/hi3660.dtsi
> > -included by /arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
> > /arch/arm64/boot/dts/hisilicon/hi3670.dtsi
> > -included by /arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts
> >
> > Bhargav Joshi (2):
> > dt-bindings: mmc: hisilicon,hi3660-dw-mshc: Convert to DT schema
> > arm64: dts: hisilicon: Rename dwmmc nodes to mmc
> >
> > .../mmc/hisilicon,hi3660-dw-mshc.yaml | 117 ++++++++++++++++++
> > .../devicetree/bindings/mmc/k3-dw-mshc.txt | 73 -----------
> > arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 +-
> > arch/arm64/boot/dts/hisilicon/hi3670.dtsi | 4 +-
> > arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 6 +-
> > 5 files changed, 124 insertions(+), 80 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/mmc/hisilicon,hi3660-dw-mshc.yaml
> > delete mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
> >
>
> Series applied to the HiSilicon arm64 dt tree.
> Thanks!
>
> Best Regards,
> Wei
Usually I pick DT bindings (patch1/2) for mmc via my mmc tree and I
also just did. Would it be possible for you to drop patch1/2 from your
tree?
Kind regards
Uffe
^ permalink raw reply
* [PATCH v1 07/10] devfreq: Get and put module refcount when switching governor
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
When compiled as a kernel module, the governor module can be dynamically
inserted or removed. 'devfreq->governor' would become NULL if the
governor module is removed when it's in use.
To prevent the governor module from being removed (except for force
unload) when it's in use, get and put a refcount of the governor module
when starting and stopping the governor.
Now, unloading a governor module that is set for a devfreq device
returns an error, for example:
# cat governor
performance
# rmmod governor_performance
rmmod: ERROR: Module governor_performance is in use
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 9b078458d129..ba09948915ba 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -338,22 +338,31 @@ static int devfreq_set_governor_locked(struct devfreq *df,
__func__, df->governor->name, ret);
return ret;
}
+ module_put(old_gov->owner);
}
/* Start the new governor */
+ if (!try_module_get(new_gov->owner))
+ return -EINVAL;
+
df->governor = new_gov;
ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
if (ret) {
dev_warn(dev, "%s: Governor %s not started(%d)\n",
__func__, df->governor->name, ret);
+ module_put(new_gov->owner);
if (!old_gov)
return ret;
/* Restore previous governor */
+ if (!try_module_get(old_gov->owner))
+ return -EINVAL;
+
df->governor = old_gov;
ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
if (ret) {
+ module_put(old_gov->owner);
dev_err(dev, "%s: restore Governor %s failed (%d)\n",
__func__, old_gov->name, ret);
df->governor = NULL;
--
2.43.0
^ permalink raw reply related
* [PATCH v1 06/10] devfreq: Add module owner to devfreq governor
From: Jie Zhan @ 2026-03-26 12:34 UTC (permalink / raw)
To: cw00.choi, myungjoo.ham, kyungmin.park, tianyaxiong
Cc: linux-pm, linux-arm-kernel, linuxarm, zhanjie9, jonathan.cameron,
zhenglifeng1, zhangpengjie2, lihuisong, prime.zeng
In-Reply-To: <20260326123428.800407-1-zhanjie9@hisilicon.com>
Add an 'owner' member to struct devfreq_governor, such that we can find
the module that holds the governor code when it's compiled as a kernel
module. This allows the devfreq core to properly manage the lifecycle
of governors.
Update devfreq_add_governor() and devm_devfreq_add_governor() to
automatically set 'owner' to THIS_MODULE via helper macros.
This is a prerequisite for implementing governor reference counting
to prevent module unloading while a governor is in use.
Signed-off-by: Jie Zhan <zhanjie9@hisilicon.com>
---
drivers/devfreq/devfreq.c | 26 +++++++++-----------------
include/linux/devfreq-governor.h | 26 +++++++++++++++++++++++---
2 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 7e71e8c76303..9b078458d129 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -1293,11 +1293,8 @@ void devfreq_resume(void)
mutex_unlock(&devfreq_list_lock);
}
-/**
- * devfreq_add_governor() - Add devfreq governor
- * @governor: the devfreq governor to be added
- */
-int devfreq_add_governor(struct devfreq_governor *governor)
+int __devfreq_add_governor(struct devfreq_governor *governor,
+ struct module *mod)
{
struct devfreq_governor *g;
@@ -1313,38 +1310,33 @@ int devfreq_add_governor(struct devfreq_governor *governor)
return -EINVAL;
}
+ governor->owner = mod;
scoped_guard(mutex, &devfreq_gov_lock)
list_add(&governor->node, &devfreq_governor_list);
return 0;
}
-EXPORT_SYMBOL(devfreq_add_governor);
+EXPORT_SYMBOL(__devfreq_add_governor);
static void devm_devfreq_remove_governor(void *governor)
{
WARN_ON(devfreq_remove_governor(governor));
}
-/**
- * devm_devfreq_add_governor() - Add devfreq governor
- * @dev: device which adds devfreq governor
- * @governor: the devfreq governor to be added
- *
- * This is a resource-managed variant of devfreq_add_governor().
- */
-int devm_devfreq_add_governor(struct device *dev,
- struct devfreq_governor *governor)
+int __devm_devfreq_add_governor(struct device *dev,
+ struct devfreq_governor *governor,
+ struct module *mod)
{
int err;
- err = devfreq_add_governor(governor);
+ err = __devfreq_add_governor(governor, mod);
if (err)
return err;
return devm_add_action_or_reset(dev, devm_devfreq_remove_governor,
governor);
}
-EXPORT_SYMBOL(devm_devfreq_add_governor);
+EXPORT_SYMBOL(__devm_devfreq_add_governor);
/**
* devfreq_remove_governor() - Remove devfreq feature from a device.
diff --git a/include/linux/devfreq-governor.h b/include/linux/devfreq-governor.h
index dfdd0160a29f..1c4ff57e24de 100644
--- a/include/linux/devfreq-governor.h
+++ b/include/linux/devfreq-governor.h
@@ -12,6 +12,7 @@
#define __LINUX_DEVFREQ_DEVFREQ_H__
#include <linux/devfreq.h>
+struct module;
#define DEVFREQ_NAME_LEN 16
@@ -50,6 +51,7 @@
/**
* struct devfreq_governor - Devfreq policy governor
* @node: list node - contains registered devfreq governors
+ * @owner: Module that this governor belongs to
* @name: Governor's name
* @attrs: Governor's sysfs attribute flags
* @flags: Governor's feature flags
@@ -67,6 +69,7 @@
struct devfreq_governor {
struct list_head node;
+ struct module *owner;
const char name[DEVFREQ_NAME_LEN];
const u64 attrs;
const u64 flags;
@@ -81,11 +84,28 @@ void devfreq_monitor_suspend(struct devfreq *devfreq);
void devfreq_monitor_resume(struct devfreq *devfreq);
void devfreq_update_interval(struct devfreq *devfreq, unsigned int *delay);
-int devfreq_add_governor(struct devfreq_governor *governor);
+/**
+ * devfreq_add_governor() - Add devfreq governor
+ * @governor: The devfreq governor to be added
+ */
+#define devfreq_add_governor(governor) \
+ __devfreq_add_governor((governor), THIS_MODULE)
+int __devfreq_add_governor(struct devfreq_governor *governor,
+ struct module *mod);
int devfreq_remove_governor(struct devfreq_governor *governor);
-int devm_devfreq_add_governor(struct device *dev,
- struct devfreq_governor *governor);
+/**
+ * devm_devfreq_add_governor() - Add devfreq governor
+ * @dev: device which adds devfreq governor
+ * @governor: the devfreq governor to be added
+ *
+ * This is a resource-managed variant of devfreq_add_governor().
+ */
+#define devm_devfreq_add_governor(dev, governor) \
+ __devm_devfreq_add_governor((dev), (governor), THIS_MODULE)
+int __devm_devfreq_add_governor(struct device *dev,
+ struct devfreq_governor *governor,
+ struct module *mod);
int devfreq_update_status(struct devfreq *devfreq, unsigned long freq);
int devfreq_update_target(struct devfreq *devfreq, unsigned long freq);
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 2/4] mm: replace exec_folio_order() with generic preferred_exec_order()
From: Usama Arif @ 2026-03-26 12:40 UTC (permalink / raw)
To: Jan Kara, david, ryan.roberts
Cc: Andrew Morton, willy, linux-mm, r, ajd, apopple, baohua,
baolin.wang, brauner, catalin.marinas, dev.jain, kees,
kevin.brodsky, lance.yang, Liam.Howlett, linux-arm-kernel,
linux-fsdevel, linux-kernel, lorenzo.stoakes, mhocko, npache,
pasha.tatashin, rmclure, rppt, surenb, vbabka, Al Viro,
wilts.infradead.org, ziy, hannes, kas, shakeel.butt, kernel-team
In-Reply-To: <k45xs6btmt62uerbglqe665jozrtkeoklu4rek6odgxjdj63ni@ftw6ef3ug33x>
On 20/03/2026 17:42, Jan Kara wrote:
> On Fri 20-03-26 06:58:52, Usama Arif wrote:
>> Replace the arch-specific exec_folio_order() hook with a generic
>> preferred_exec_order() that dynamically computes the readahead folio
>> order for executable memory. It targets min(PMD_ORDER, 2M) as the
>> maximum, which optimally gives the right answer for contpte (arm64),
>> PMD mapping (x86, arm64 4K), and architectures with smaller PMDs
>> (s390 1M). It adapts at runtime based on:
>>
>> - VMA size: caps the order so folios fit within the mapping
>> - Memory pressure: steps down the order when the local node's free
>> memory is below the high watermark for the requested order
>>
>> This avoids over-allocating on memory-constrained systems while still
>> requesting the optimal order when memory is plentiful.
>>
>> Since exec_folio_order() is no longer needed, remove the arm64
>> definition and the generic default from pgtable.h.
>>
>> Signed-off-by: Usama Arif <usama.arif@linux.dev>
> ...
>> +static unsigned int preferred_exec_order(struct vm_area_struct *vma)
>> +{
>> + int order;
>> + unsigned long vma_len = vma_pages(vma);
>> + struct zone *zone;
>> + gfp_t gfp;
>> +
>> + if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
>> + return 0;
>> +
>> + /* Cap at min(PMD_ORDER, 2M) */
>> + order = min(HPAGE_PMD_ORDER, ilog2(SZ_2M >> PAGE_SHIFT));
>> +
>> + /* Don't request folios larger than the VMA */
>> + order = min(order, ilog2(vma_len));
>
Hi Jan,
Thanks for the feedback and sorry for the late reply! I was travelling
during the week.
> Hum, as far as I'm checking page_cache_ra_order() used in
> do_sync_mmap_readahead(), ra->order is the preferred order but it will be
> trimmed down to fit both within the file and within ra->size. And ra->size
> is set for the readahead to fit within the vma so I don't think any order
> trimming based on vma length is needed in this place?
Ack, yes makes sense.
>
>> + /* Step down under memory pressure */
>> + gfp = mapping_gfp_mask(vma->vm_file->f_mapping);
>> + zone = first_zones_zonelist(node_zonelist(numa_node_id(), gfp),
>> + gfp_zone(gfp), NULL)->zone;
>> + if (zone) {
>> + while (order > 0 &&
>> + !zone_watermark_ok(zone, order,
>> + high_wmark_pages(zone), 0, 0))
>> + order--;
>> + }
>
> It looks wrong for this logic to be here. Trimming order based on memory
> pressure makes sense (and we've already got reports that on memory limited
> devices large order folios in the page cache have too big memory overhead
> so we'll likely need to handle that for page cache allocations in general)
> but IMHO it belongs to page_cache_ra_order() or some other common place
> like that.
>
> Honza
So I have been thinking about this. readahead_gfp_mask() already sets
__GFP_NORETRY, so we wont try aggressive reclaim/compaction to satisfy
the allocation. page_cache_ra_order() falls through to the fallback path
faulting in order 0 page when allocation is not satsified.
So the allocator already naturally steps down under memory pressure,
the explicit zone_watermark_ok() loop might be redundant?
What are your thoughts on just setting
ra->order = min(HPAGE_PMD_ORDER, ilog2(SZ_2M >> PAGE_SHIFT))?
We can do the higher orlder allocation with gfp &= ~__GFP_RECLAIM
for the VM_EXEC case.
^ permalink raw reply
* Re: [PATCH v11 03/22] drm: Add new general DRM property "color format"
From: Nicolas Frattaroli @ 2026-03-26 12:44 UTC (permalink / raw)
To: Maxime Ripard, Ville Syrjälä
Cc: Harry Wentland, Leo Li, Rodrigo Siqueira, Alex Deucher,
Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, Jonathan Corbet,
Shuah Khan, kernel, amd-gfx, dri-devel, linux-kernel,
linux-arm-kernel, linux-rockchip, intel-gfx, intel-xe, linux-doc,
Werner Sembach, Andri Yngvason, Marius Vlad
In-Reply-To: <acPA60Ci3n_t__xF@intel.com>
On Wednesday, 25 March 2026 12:03:07 Central European Standard Time Ville Syrjälä wrote:
> On Wed, Mar 25, 2026 at 09:24:27AM +0100, Maxime Ripard wrote:
> > On Tue, Mar 24, 2026 at 09:53:35PM +0200, Ville Syrjälä wrote:
> > > On Tue, Mar 24, 2026 at 08:10:11PM +0100, Nicolas Frattaroli wrote:
> > > > On Tuesday, 24 March 2026 18:00:45 Central European Standard Time Ville Syrjälä wrote:
> > > > > On Tue, Mar 24, 2026 at 05:01:07PM +0100, Nicolas Frattaroli wrote:
> > > > > > +enum drm_connector_color_format {
> > > > > > + /**
> > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_AUTO: The driver or display protocol
> > > > > > + * helpers should pick a suitable color format. All implementations of a
> > > > > > + * specific display protocol must behave the same way with "AUTO", but
> > > > > > + * different display protocols do not necessarily have the same "AUTO"
> > > > > > + * semantics.
> > > > > > + *
> > > > > > + * For HDMI, "AUTO" picks RGB, but falls back to YCbCr 4:2:0 if the
> > > > > > + * bandwidth required for full-scale RGB is not available, or the mode
> > > > > > + * is YCbCr 4:2:0-only, as long as the mode and output both support
> > > > > > + * YCbCr 4:2:0.
> > > > > > + *
> > > > > > + * For display protocols other than HDMI, the recursive bridge chain
> > > > > > + * format selection picks the first chain of bridge formats that works,
> > > > > > + * as has already been the case before the introduction of the "color
> > > > > > + * format" property. Non-HDMI bridges should therefore either sort their
> > > > > > + * bus output formats by preference, or agree on a unified auto format
> > > > > > + * selection logic that's implemented in a common state helper (like
> > > > > > + * how HDMI does it).
> > > > > > + */
> > > > > > + DRM_CONNECTOR_COLOR_FORMAT_AUTO = 0,
> > > > > > +
> > > > > > + /**
> > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_RGB444: RGB output format
> > > > > > + */
> > > > > > + DRM_CONNECTOR_COLOR_FORMAT_RGB444,
> > > > > > +
> > > > > > + /**
> > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR444: YCbCr 4:4:4 output format (ie.
> > > > > > + * not subsampled)
> > > > > > + */
> > > > > > + DRM_CONNECTOR_COLOR_FORMAT_YCBCR444,
> > > > > > +
> > > > > > + /**
> > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR422: YCbCr 4:2:2 output format (ie.
> > > > > > + * with horizontal subsampling)
> > > > > > + */
> > > > > > + DRM_CONNECTOR_COLOR_FORMAT_YCBCR422,
> > > > > > +
> > > > > > + /**
> > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR420: YCbCr 4:2:0 output format (ie.
> > > > > > + * with horizontal and vertical subsampling)
> > > > > > + */
> > > > > > + DRM_CONNECTOR_COLOR_FORMAT_YCBCR420,
> > > > >
> > > > > Seems like this should document what the quantization range
> > > > > should be for each format.
> > > > >
> > > >
> > > > I don't think so? If you want per-component bit depth values,
> > > > DRM_FORMAT_* defines would be the appropriate values to use. This
> > > > enum is more abstract than that, and is there to communicate
> > > > YUV vs. RGB and chroma subsampling, with bit depth being handled
> > > > by other properties.
> > > >
> > > > If you mean the factor used for subsampling, then that'd only be
> > > > relevant if YCBCR410 was supported where one chroma plane isn't
> > > > halved but quartered in resolution. I suspect 4:1:0 will never
> > > > be added; no digital display protocol standard supports it to my
> > > > knowledge, and hopefully none ever will.
> > >
> > > No, I mean the quantization range (16-235 vs. 0-255 etc).
> > >
> > > The i915 behaviour is that YCbCr is always limited range,
> > > RGB can either be full or limited range depending on the
> > > "Broadcast RGB" property and other related factors.
> >
> > So far the HDMI state has both the format and quantization range as
> > different fields. I'm not sure we need to document the range in the
> > format field, maybe only mention it's not part of the format but has a
> > field of its own?
>
> I think we only have it for RGB (on some drivers only?). For YCbCr
> I think the assumption is limited range everywhere.
>
> But I'm not really concerned about documenting struct members.
> What I'm talking about is the *uapi* docs. Surely userspace
> will want to know what the new property actually does so the
> uapi needs to be documented properly. And down the line some
> new driver might also implement the wrong behaviour if there
> is no clear specification.
>
> So I'm thinking (or perhaps hoping) the rule might be something like:
> - YCbCr limited range
> - RGB full range if "Broadcast RGB" property is not present
> - RGB full or limited range based on the "Broadcast RGB" property
> if it's present
>
> I think the "Broadcast RGB" property itself might also be lacking
> proper uapi docs, so that may need to be remedied as well.
>
>
Alright, so in v12 I'll do the following:
- Add a line to all YCBCR connector formats that specifies they're
limited range as long as Broadcast RGB is limited. Whether it's limited
range when Broadcast RGB is full is purposefully left undefined.
In the future, we can expand this to state they're limited range by
default unless some other property is set. If we're not re-using
Broadcast RGB for that, this will work out fine, because users who
don't know about the eventual new property won't have this behaviour
changed. If we do re-use "Broadcast RGB" for that, then only users
relying on things we explicitly left undefined will get surprise
full range YCBCR.
- Add a line to the RGB connector format that specifies its range
depends on the "Broadcast RGB" property
This is a bit of a mess, because it's entirely reasonable that a
future YCBCR range property would want to default to full range
so that users get the most color out of their monitors. But with
this description of the connector color formats, we can't do that.
If there are alternate suggestions, I'm open for them. We can't
really rename "Broadcast RGB" but if I had a time machine, that'd
be my first choice.
Kind regards,
Nicolas Frattaroli
^ permalink raw reply
* Re: [PATCH net-next v2 4/4] net: phy: Introduce Airoha AN8801/R Gigabit Ethernet PHY driver
From: Andrew Lunn @ 2026-03-26 12:47 UTC (permalink / raw)
To: Louis-Alexis Eyraud
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
kevin-kw.huang, macpaul.lin, matthias.bgg, kernel, netdev,
devicetree, linux-arm-kernel, linux-mediatek, linux-kernel
In-Reply-To: <20260326-add-airoha-an8801-support-v2-4-1a42d6b6050f@collabora.com>
> +static int an8801r_led_blink_set(struct phy_device *phydev, u8 index,
> + unsigned long *delay_on,
> + unsigned long *delay_off)
> +{
...
> + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, LED_ON_CTRL(index),
> + LED_ON_EN, blink ? LED_ON_EN : 0);
> + if (ret)
> + return ret;
> +
> + return 0;
Just
return phy_modify_mmd(phydev, MDIO_MMD_VEND2, LED_ON_CTRL(index),
LED_ON_EN, blink ? LED_ON_EN : 0);
> + if (!led_trigger)
> + continue;
> +
> + ret = an8801r_led_hw_control_set(phydev, led_id, led_trigger);
> + if (ret)
> + return ret;
> + }
> + return 0;
> +}
Please take a look at all your functions. Can the last error check be
removed and just use return ret, etc.
> +static int an8801r_of_init_leds(struct phy_device *phydev, u8 *led_cfg)
> +{
> + struct device *dev = &phydev->mdio.dev;
> + struct device_node *np = dev->of_node;
> + struct device_node *leds;
> + u32 function_enum_idx;
> + int ret;
> +
> + if (!np)
> + return 0;
> +
> + /* If devicetree is present, leds configuration is required */
> + leds = of_get_child_by_name(np, "leds");
> + if (!leds)
> + return 0;
> +
> + for_each_available_child_of_node_scoped(leds, led) {
> + u32 led_idx;
> +
> + ret = of_property_read_u32(led, "reg", &led_idx);
> + if (ret)
> + goto out;
> +
> + if (led_idx >= AN8801R_NUM_LEDS) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + ret = of_property_read_u32(led, "function-enumerator",
> + &function_enum_idx);
> + if (ret)
> + function_enum_idx = AN8801R_LED_FN_NONE;
> +
What is this doing? Is this documented in the binding?
> + if (function_enum_idx >= AN8801R_LED_FN_MAX) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + led_cfg[led_idx] = function_enum_idx;
> + }
> +out:
> + of_node_put(leds);
> + return ret;
> +}
> +static int an8801r_read_status(struct phy_device *phydev)
> +{
> + int prev_speed, ret;
> + u32 val;
> +
> + prev_speed = phydev->speed;
> +
> + ret = genphy_read_status(phydev);
> + if (ret)
> + return ret;
> +
> + if (phydev->link && prev_speed != phydev->speed) {
> + val = phydev->speed == SPEED_1000 ?
> + AN8801_BPBUS_LINK_MODE_1000 : 0;
> +
> + return an8801_buckpbus_reg_rmw(phydev,
> + AN8801_BPBUS_REG_LINK_MODE,
> + AN8801_BPBUS_LINK_MODE_1000,
> + val);
> + };
This is unusual. What is it doing? Please add a comment.
Andrew
^ permalink raw reply
* Re: [PATCH v2 1/3] KVM: arm64: Disable TRBE Trace Buffer Unit when running in guest context
From: Will Deacon @ 2026-03-26 12:49 UTC (permalink / raw)
To: Fuad Tabba
Cc: kvmarm, mark.rutland, linux-arm-kernel, Marc Zyngier,
Oliver Upton, James Clark, Leo Yan, Suzuki K Poulose,
Alexandru Elisei, Yabin Cui
In-Reply-To: <CA+EHjTxcc2FArmi1hu17LW3BHUZ5zTnqbaQP0kbV39HXZfp9+Q@mail.gmail.com>
On Wed, Mar 25, 2026 at 07:27:32PM +0000, Fuad Tabba wrote:
> On Fri, 27 Feb 2026 at 21:22, Will Deacon <will@kernel.org> wrote:
> >
> > The nVHE world-switch code relies on zeroing TRFCR_EL1 to disable trace
> > generation in guest context when self-hosted TRBE is in use by the host.
> >
> > Per D3.2.1 ("Controls to prohibit trace at Exception levels"), clearing
> > TRFCR_EL1 means that trace generation is prohibited at EL1 and EL0 but
> > per R_YCHKJ the Trace Buffer Unit will still be enabled if
> > TRBLIMITR_EL1.E is set. R_SJFRQ goes on to state that, when enabled, the
> > Trace Buffer Unit can perform address translation for the "owning
> > exception level" even when it is out of context.
> >
> > Consequently, we can end up in a state where TRBE performs speculative
> > page-table walks for a host VA/IPA in guest/hypervisor context depending
> > on the value of MDCR_EL2.E2TB, which changes over world-switch. The
> > potential result appears to be a heady mixture of SErrors, data
> > corruption and hardware lockups.
> >
> > Extend the TRBE world-switch code to clear TRBLIMITR_EL1.E after
> > draining the buffer, restoring the register on return to the host. This
> > unfortunately means we need to tackle CPU errata #2064142 and #2038923
> > which add additional synchronisation requirements around manipulations
> > of the limit register. Hopefully this doesn't need to be fast.
> >
> > Cc: Marc Zyngier <maz@kernel.org>
> > Cc: Oliver Upton <oupton@kernel.org>
> > Cc: James Clark <james.clark@linaro.org>
> > Cc: Leo Yan <leo.yan@arm.com>
> > Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
> > Cc: Fuad Tabba <tabba@google.com>
> > Cc: Alexandru Elisei <alexandru.elisei@arm.com>
> > Fixes: a1319260bf62 ("arm64: KVM: Enable access to TRBE support for host")
> > Signed-off-by: Will Deacon <will@kernel.org>
> > ---
> > arch/arm64/include/asm/kvm_host.h | 1 +
> > arch/arm64/kvm/hyp/nvhe/debug-sr.c | 73 ++++++++++++++++++++++++++----
> > arch/arm64/kvm/hyp/nvhe/switch.c | 2 +-
> > 3 files changed, 66 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> > index 5d5a3bbdb95e..1532ad2b2ec2 100644
> > --- a/arch/arm64/include/asm/kvm_host.h
> > +++ b/arch/arm64/include/asm/kvm_host.h
> > @@ -770,6 +770,7 @@ struct kvm_host_data {
> > u64 pmscr_el1;
> > /* Self-hosted trace */
> > u64 trfcr_el1;
> > + u64 trblimitr_el1;
> > /* Values of trap registers for the host before guest entry. */
> > u64 mdcr_el2;
> > u64 brbcr_el1;
> > diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> > index 2a1c0f49792b..3dbdee1148d3 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c
> > @@ -57,12 +57,56 @@ static void __trace_do_switch(u64 *saved_trfcr, u64 new_trfcr)
> > write_sysreg_el1(new_trfcr, SYS_TRFCR);
> > }
> >
> > -static bool __trace_needs_drain(void)
> > +static void __trace_drain_and_disable(void)
> > {
> > - if (is_protected_kvm_enabled() && host_data_test_flag(HAS_TRBE))
> > - return read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_EL1_E;
> > + u64 *trblimitr_el1 = host_data_ptr(host_debug_state.trblimitr_el1);
> >
> > - return host_data_test_flag(TRBE_ENABLED);
> > + *trblimitr_el1 = 0;
> > +
> > + if (is_protected_kvm_enabled()) {
> > + if (!host_data_test_flag(HAS_TRBE))
> > + return;
> > + } else {
> > + if (!host_data_test_flag(TRBE_ENABLED))
> > + return;
> > + }
>
> Can we simplify this? e.g.,
>
> + bool needs_drain = is_protected_kvm_enabled() ?
> host_data_test_flag(HAS_TRBE) : host_data_test_flag(TRBE_ENABLED);
> ....
Good idea. I tend to avoid 'bool's as they often make the code less
readable in my experience, but in this case it would be a lot better
than the nested conditionals I have. I'll spin a v3!
> That said:
>
> Tested-by: Fuad Tabba <tabba@google.com>
> Reviewed-by: Fuad Tabba <tabba@google.com>
Cheers,
Will
^ permalink raw reply
* Re: [PATCH] ARM: dts: renesas: rza2mevb: Drop RTL8211F PHY C22 compatible string
From: Marek Vasut @ 2026-03-26 12:52 UTC (permalink / raw)
To: Geert Uytterhoeven, Marek Vasut
Cc: linux-arm-kernel, Conor Dooley, Krzysztof Kozlowski, Magnus Damm,
Rob Herring, devicetree, linux-kernel, linux-renesas-soc
In-Reply-To: <CAMuHMdVwa47N2VsvH8pBkAD215dr3M-qkA0SXed0vhLS2-aoKA@mail.gmail.com>
On 3/26/26 10:45 AM, Geert Uytterhoeven wrote:
Hello Geert,
> On Thu, 26 Mar 2026 at 05:54, Marek Vasut
> <marek.vasut+renesas@mailbox.org> wrote:
>> Realtek RTL8211F PHY schema indicates that compatible string
>> "ethernet-phy-id001c.c916" must not be followed by any other
>
> This is actually RTL8201F / c816; I will fix this while applying.
Ouf ... thank you.
^ permalink raw reply
* Re: [PATCH v5 1/9] arm64: dts: amlogic: t7: Add eMMC, SD card and SDIO pinctrl nodes
From: Neil Armstrong @ 2026-03-26 12:53 UTC (permalink / raw)
To: Ronald Claveau, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ulf Hansson,
Johannes Berg, van Spriel
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless
In-Reply-To: <20260326-add-emmc-t7-vim4-v5-1-d3f182b48e9d@aliel.fr>
On 3/26/26 10:59, Ronald Claveau wrote:
> These pinctrl nodes are required by the eMMC, SD card and SDIO drivers
> to configure pin muxing at runtime.
>
> - eMMC: control, 4-bit/8-bit data, data strobe and clock gate pins
> - SD card: data, clock, command and clock gate pins
> - SDIO: data, clock, command and clock gate pins
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 98 +++++++++++++++++++++++++++++
> 1 file changed, 98 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 6510068bcff92..36d13371f56ba 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -250,6 +250,104 @@ gpio: bank@4000 {
> #gpio-cells = <2>;
> gpio-ranges = <&periphs_pinctrl 0 0 157>;
> };
> +
> + emmc_ctrl_pins: emmc-ctrl {
> + mux-0 {
> + groups = "emmc_cmd";
> + function = "emmc";
> + bias-pull-up;
> + };
> +
> + mux-1 {
> + groups = "emmc_clk";
> + function = "emmc";
> + bias-disable;
> + };
> + };
> +
> + emmc_data_4b_pins: emmc-data-4b {
> + mux {
> + groups = "emmc_nand_d0",
> + "emmc_nand_d1",
> + "emmc_nand_d2",
> + "emmc_nand_d3";
> + function = "emmc";
> + bias-pull-up;
> + };
> + };
> +
> + emmc_data_8b_pins: emmc-data-8b {
> + mux {
> + groups = "emmc_nand_d0",
> + "emmc_nand_d1",
> + "emmc_nand_d2",
> + "emmc_nand_d3",
> + "emmc_nand_d4",
> + "emmc_nand_d5",
> + "emmc_nand_d6",
> + "emmc_nand_d7";
> + function = "emmc";
> + bias-pull-up;
> + };
> + };
> +
> + emmc_ds_pins: emmc-ds {
> + mux {
> + groups = "emmc_nand_ds";
> + function = "emmc";
> + bias-pull-down;
> + };
> + };
> +
> + emmc_clk_gate_pins: emmc-clk-gate {
> + mux {
> + groups = "GPIOB_8";
> + function = "gpio_periphs";
> + bias-pull-down;
> + };
> + };
> +
> + sdcard_pins: sdcard {
> + mux {
> + groups = "sdcard_d0",
> + "sdcard_d1",
> + "sdcard_d2",
> + "sdcard_d3",
> + "sdcard_clk",
> + "sdcard_cmd";
> + function = "sdcard";
> + bias-pull-up;
> + };
> + };
> +
> + sdcard_clk_gate_pins: sdcard-clk-gate {
> + mux {
> + groups = "GPIOC_4";
> + function = "gpio_periphs";
> + bias-pull-down;
> + };
> + };
> +
> + sdio_pins: sdio {
> + mux {
> + groups = "sdio_d0",
> + "sdio_d1",
> + "sdio_d2",
> + "sdio_d3",
> + "sdio_clk",
> + "sdio_cmd";
> + function = "sdio";
> + bias-pull-up;
> + };
> + };
> +
> + sdio_clk_gate_pins: sdio-clk-gate {
> + mux {
> + groups = "GPIOX_4";
> + function = "gpio_periphs";
> + bias-pull-up;
> + };
> + };
> };
>
> gpio_intc: interrupt-controller@4080 {
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v2 0/2] mmc: hisilicon: Convert dw-mshc bindings and fix dtbs
From: Wei Xu @ 2026-03-26 12:53 UTC (permalink / raw)
To: Ulf Hansson
Cc: Bhargav Joshi, devicetree, linux-arm-kernel, robh, krzk+dt,
conor+dt, zhangfei.gao, linux-mmc, daniel.baluta, simona.toaca,
d-gole, m-chawdhry, linux-kernel
In-Reply-To: <CAPDyKFq6F3PZgqTtHXZPQPPBvdPhsQPtUVHiZV6X-QXvS42+CA@mail.gmail.com>
Hi Uffe,
On 2026/3/26 20:39, Ulf Hansson wrote:
> On Thu, 26 Mar 2026 at 12:19, Wei Xu <xuwei5@hisilicon.com> wrote:
>>
>> Hi Bhargav,
>>
>> On 2026/3/26 6:54, Bhargav Joshi wrote:
>>> This series converts the Hisilicon dw-mshc text bindings to DT schema
>>> format and cleans up legacy node names in Hisilicon board files.
>>>
>>> While testing the new YAML schema, dtbs_check flagged the hi3660,
>>> hi3670, and hi6220 SoC files for using the non-standard 'dwmmc' node
>>> name prefix. resulting in warnings.
>>>
>>> Patch 1 Convert to DT schema
>>> Patch 2 updates the Hisilicon dtsi files to use standard 'mmc'
>>> node name.
>>>
>>> Changes in v2:
>>> - Patch 1:
>>> - Grouped compatible strings into an enum.
>>> - Replaced raw numbers with proper flags.
>>> - Fixed property order and removed invalid hex values.
>>> - Added explanation for clock order change in commit message.
>>> - Collected Acked-by tag.
>>> - Patch 2:
>>> - No code changes.
>>> - Collected Acked-by and Reviewed-by tags.
>>>
>>> Signed-off-by: Bhargav Joshi <rougueprince47@gmail.com>
>>> ---
>>> Note: this patch is part of the process for applying to GSoC device
>>> tree bindings conversion project #
>>> https://github.com/LinuxFoundationGSoC/ProjectIdeas/wiki/GSoC-2026-Device-Tree-Bindings
>>>
>>> - The file is enabled by arm64 defconfig (CONFIG_MMC_DW_K3=y)
>>> - It is used in following
>>> /arch/arm64/boot/dts/hisilicon/hi3660.dtsi
>>> -included by /arch/arm64/boot/dts/hisilicon/hi3660-hikey960.dts
>>> /arch/arm64/boot/dts/hisilicon/hi3670.dtsi
>>> -included by /arch/arm64/boot/dts/hisilicon/hi3670-hikey970.dts
>>>
>>> Bhargav Joshi (2):
>>> dt-bindings: mmc: hisilicon,hi3660-dw-mshc: Convert to DT schema
>>> arm64: dts: hisilicon: Rename dwmmc nodes to mmc
>>>
>>> .../mmc/hisilicon,hi3660-dw-mshc.yaml | 117 ++++++++++++++++++
>>> .../devicetree/bindings/mmc/k3-dw-mshc.txt | 73 -----------
>>> arch/arm64/boot/dts/hisilicon/hi3660.dtsi | 4 +-
>>> arch/arm64/boot/dts/hisilicon/hi3670.dtsi | 4 +-
>>> arch/arm64/boot/dts/hisilicon/hi6220.dtsi | 6 +-
>>> 5 files changed, 124 insertions(+), 80 deletions(-)
>>> create mode 100644 Documentation/devicetree/bindings/mmc/hisilicon,hi3660-dw-mshc.yaml
>>> delete mode 100644 Documentation/devicetree/bindings/mmc/k3-dw-mshc.txt
>>>
>>
>> Series applied to the HiSilicon arm64 dt tree.
>> Thanks!
>>
>> Best Regards,
>> Wei
>
> Usually I pick DT bindings (patch1/2) for mmc via my mmc tree and I
> also just did. Would it be possible for you to drop patch1/2 from your
> tree?
So I will drop them.
Thanks!
Best Regards,
Wei
>
> Kind regards
> Uffe
>
> .
>
^ permalink raw reply
* Re: [PATCH v5 8/9] dt-bindings: net: wireless: brcm: Add compatible for bcm43752
From: Neil Armstrong @ 2026-03-26 12:55 UTC (permalink / raw)
To: Ronald Claveau, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ulf Hansson,
Johannes Berg, van Spriel
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless, Conor Dooley
In-Reply-To: <20260326-add-emmc-t7-vim4-v5-8-d3f182b48e9d@aliel.fr>
On 3/26/26 10:59, Ronald Claveau wrote:
> Add bcm43752 compatible with its bcm4329 compatible fallback.
>
> Acked-by: Conor Dooley <conor.dooley@microchip.com>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
> index 3be7576787644..81fd3e37452a6 100644
> --- a/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
> +++ b/Documentation/devicetree/bindings/net/wireless/brcm,bcm4329-fmac.yaml
> @@ -42,6 +42,7 @@ properties:
> - brcm,bcm4356-fmac
> - brcm,bcm4359-fmac
> - brcm,bcm4366-fmac
> + - brcm,bcm43752-fmac
> - cypress,cyw4373-fmac
> - cypress,cyw43012-fmac
> - infineon,cyw43439-fmac
>
I'll apply all the other DT patches, please send this one alone with the [PATCH net-next] prefix so it gets picked by the wireless/net people.
Thanks,
Neil
^ permalink raw reply
* Re: [PATCH v5 3/9] arm64: dts: amlogic: t7: Add MMC controller nodes
From: Neil Armstrong @ 2026-03-26 12:56 UTC (permalink / raw)
To: Ronald Claveau, Kevin Hilman, Jerome Brunet, Martin Blumenstingl,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ulf Hansson,
Johannes Berg, van Spriel
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless
In-Reply-To: <20260326-add-emmc-t7-vim4-v5-3-d3f182b48e9d@aliel.fr>
On 3/26/26 10:59, Ronald Claveau wrote:
> Add device tree nodes for the three MMC controllers available
> on the Amlogic T7 SoC, using amlogic,meson-axg-mmc as fallback compatible.
> All nodes are disabled by default and should be
> enabled in the board-specific DTS file.
>
> Signed-off-by: Ronald Claveau <linux-kernel-dev@aliel.fr>
> ---
> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 39 +++++++++++++++++++++++++++++
> 1 file changed, 39 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> index 36d13371f56ba..fe1ced0a58967 100644
> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
> @@ -374,6 +374,45 @@ sec_ao: ao-secure@10220 {
> reg = <0x0 0x10220 0x0 0x140>;
> amlogic,has-chip-id;
> };
> +
> + sd_emmc_a: mmc@88000 {
> + compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc";
> + reg = <0x0 0x88000 0x0 0x800>;
> + interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_A>,
> + <&clkc_periphs CLKID_SD_EMMC_A>,
> + <&scmi_clk CLKID_FCLK_DIV2>;
> + clock-names = "core", "clkin0", "clkin1";
> + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_A_SEL>;
> + assigned-clock-parents = <&xtal>;
> + status = "disabled";
> + };
> +
> + sd_emmc_b: mmc@8a000 {
> + compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc";
> + reg = <0x0 0x8a000 0x0 0x800>;
> + interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_B>,
> + <&clkc_periphs CLKID_SD_EMMC_B>,
> + <&scmi_clk CLKID_FCLK_DIV2>;
> + clock-names = "core", "clkin0", "clkin1";
> + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_B_SEL>;
> + assigned-clock-parents = <&xtal>;
> + status = "disabled";
> + };
> +
> + sd_emmc_c: mmc@8c000 {
> + compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc";
> + reg = <0x0 0x8c000 0x0 0x800>;
> + interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
> + clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_C>,
> + <&clkc_periphs CLKID_SD_EMMC_C>,
> + <&scmi_clk CLKID_FCLK_DIV2>;
> + clock-names = "core", "clkin0", "clkin1";
> + assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_C_SEL>;
> + assigned-clock-parents = <&xtal>;
> + status = "disabled";
> + };
> };
>
> };
>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Thanks,
Neil
^ permalink raw reply
* [PATCH v4 0/2] Support TQMa8QM
From: Alexander Stein @ 2026-03-26 13:02 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Alexander Stein, imx, linux-arm-kernel, devicetree, linux-kernel,
linux, linux-renesas-soc
Hi,
this series adds support for TQ's TQMa8QM. In v4 several prepatory have been
merged already. So this series include only the two missing patches:
1. platform DT
2. Workaround for missing "ERR050104: Arm/A53: Cache coherency issue"
workaround. See [1] for details. Split into separate commit for easy revert
once an errata workaround has been integrated.
Changes in v4:
* Reduced recipient audience due to reduced patches
* Sorted nodes by name (not by phandle)
Changes in v3:
* Small cleanups in patch 1 & 4
Changes in v2:
The need for clock-output-names properties for renesas,9fgv0441 has
been removed by reworkging the PCIe clocking
Best regards,
Alexander
[1] https://lore.kernel.org/all/20230420112952.28340-1-iivanov@suse.de/
Alexander Stein (2):
arm64: dts: freescale: add initial device tree for TQMa8x
arm64: dts: imx8qm-tqma8qm-mba8x: Disable Cortex-A72 cluster
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../dts/freescale/imx8qm-tqma8qm-mba8x.dts | 871 ++++++++++++++++++
.../boot/dts/freescale/imx8qm-tqma8qm.dtsi | 325 +++++++
3 files changed, 1197 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
--
2.43.0
^ permalink raw reply
* [PATCH v4 2/2] arm64: dts: imx8qm-tqma8qm-mba8x: Disable Cortex-A72 cluster
From: Alexander Stein @ 2026-03-26 13:02 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Alexander Stein, imx, linux-arm-kernel, devicetree, linux-kernel,
linux, linux-renesas-soc
In-Reply-To: <20260326130225.1406806-1-alexander.stein@ew.tq-group.com>
Due to missing workaround for "ERR050104: Arm/A53: Cache coherency issue"
disable the whole Cortex-A72 cluster.
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
Changes in v4:
* None
.../dts/freescale/imx8qm-tqma8qm-mba8x.dts | 39 -------------------
.../boot/dts/freescale/imx8qm-tqma8qm.dtsi | 13 +++++--
2 files changed, 10 insertions(+), 42 deletions(-)
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
index bf972010a88e7..ab3b244b684fd 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
+++ b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
@@ -298,45 +298,6 @@ map3 {
};
};
};
-
- cpu1-thermal {
- trips {
- soc_active1_0: trip-active0 {
- temperature = <40000>;
- hysteresis = <5000>;
- type = "active";
- };
-
- soc_active1_1: trip-active1 {
- temperature = <48000>;
- hysteresis = <3000>;
- type = "active";
- };
-
- soc_active1_2: trip-active2 {
- temperature = <60000>;
- hysteresis = <10000>;
- type = "active";
- };
- };
-
- cooling-maps {
- map1 {
- trip = <&soc_active1_0>;
- cooling-device = <&fan0 1 1>;
- };
-
- map2 {
- trip = <&soc_active1_1>;
- cooling-device = <&fan0 2 2>;
- };
-
- map3 {
- trip = <&soc_active1_2>;
- cooling-device = <&fan0 3 3>;
- };
- };
- };
};
};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
index d94605c999915..f0e398eb2aad7 100644
--- a/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
@@ -15,6 +15,13 @@ / {
model = "TQ-Systems i.MX8QM TQMa8QM";
compatible = "tq,imx8qm-tqma8qm", "fsl,imx8qm";
+ /* Due to missing workaround for ERR050104 */
+ cpus {
+ /delete-node/ cpu-map;
+ /delete-node/ cpu@100;
+ /delete-node/ cpu@101;
+ };
+
memory@80000000 {
device_type = "memory";
/*
@@ -174,6 +181,8 @@ &mu2_m0 {
};
&thermal_zones {
+ /delete-node/ cpu1-thermal;
+
pmic0-thermal {
polling-delay-passive = <250>;
polling-delay = <2000>;
@@ -199,9 +208,7 @@ map0 {
<&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
<&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
- <&A72_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
--
2.43.0
^ permalink raw reply related
* [PATCH v4 1/2] arm64: dts: freescale: add initial device tree for TQMa8x
From: Alexander Stein @ 2026-03-26 13:02 UTC (permalink / raw)
To: Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm
Cc: Alexander Stein, imx, linux-arm-kernel, devicetree, linux-kernel,
linux, linux-renesas-soc
In-Reply-To: <20260326130225.1406806-1-alexander.stein@ew.tq-group.com>
This adds support for TQMa8QM module on MBa8x board, based on i.MX8 SoC.
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
Changes in v4:
* Sorted nodes by node name, not by phandle
arch/arm64/boot/dts/freescale/Makefile | 1 +
.../dts/freescale/imx8qm-tqma8qm-mba8x.dts | 910 ++++++++++++++++++
.../boot/dts/freescale/imx8qm-tqma8qm.dtsi | 318 ++++++
3 files changed, 1229 insertions(+)
create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
create mode 100644 arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 04cf176fc1d81..c58b97522e7f0 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -404,6 +404,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-eval-v1.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-ixora-v1.1.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-apalis-v1.1-ixora-v1.2.dtb
dtb-$(CONFIG_ARCH_MXC) += imx8qm-mek.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8qm-tqma8qm-mba8x.dtb
imx8qm-mek-ov5640-csi0-dtbs := imx8qm-mek.dtb imx8qm-mek-ov5640-csi0.dtbo
dtb-${CONFIG_ARCH_MXC} += imx8qm-mek-ov5640-csi0.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
new file mode 100644
index 0000000000000..bf972010a88e7
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm-mba8x.dts
@@ -0,0 +1,910 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2019-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/leds/common.h>
+#include <dt-bindings/net/ti-dp83867.h>
+#include <dt-bindings/pwm/pwm.h>
+
+#include "imx8qm-tqma8qm.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8QM TQMa8QM on MBa8x";
+ compatible = "tq,imx8qm-tqma8qm-mba8x", "tq,imx8qm-tqma8qm", "fsl,imx8qm";
+
+ adc {
+ compatible = "iio-hwmon";
+ io-channels = <&adc0 0>, <&adc0 1>, <&adc0 2>;
+ };
+
+ aliases {
+ rtc0 = &pcf85063;
+ rtc1 = &rtc;
+ };
+
+ chosen {
+ stdout-path = &lpuart0;
+ };
+
+
+ clk_xtal25: clk-xtal25 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <25000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpiokeys>;
+ autorepeat;
+
+ switch-1 {
+ label = "SWITCH_A";
+ linux,code = <BTN_0>;
+ gpios = <&lsio_gpio2 11 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+
+ switch-2 {
+ label = "SWITCH_B";
+ linux,code = <BTN_1>;
+ gpios = <&lsio_gpio1 0 GPIO_ACTIVE_LOW>;
+ wakeup-source;
+ };
+ };
+
+ gpio-leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpioled>;
+
+ user-led0 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_HEARTBEAT;
+ gpios = <&lsio_gpio5 20 GPIO_ACTIVE_HIGH>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ user-led1 {
+ color = <LED_COLOR_ID_GREEN>;
+ function = LED_FUNCTION_STATUS;
+ gpios = <&lsio_gpio5 19 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ fan0: pwm-fan {
+ compatible = "pwm-fan";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwmfan>;
+ fan-supply = <®_pwm_fan>;
+ #cooling-cells = <2>;
+ /* typical 25 kHz -> 40.000 nsec */
+ pwms = <&lsio_pwm3 0 40000 PWM_POLARITY_INVERTED>;
+ cooling-levels = <0 32 64 128 196 240>;
+ pulses-per-revolution = <2>;
+ interrupt-parent = <&lsio_gpio2>;
+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
+ status = "disabled";
+ };
+
+ reg_mba8x_12v: regulator-mba8x-12v {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_mba8x_12v>;
+ regulator-name = "MBa8x-V12";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ enable-active-high;
+ gpio = <&lsio_gpio1 2 GPIO_ACTIVE_HIGH>;
+ };
+
+ reg_mba8x_v3v3: regulator-mba8x-v3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_MB";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ reg_pwm_fan: regulator-pwm-fan {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_regpwmfan>;
+ regulator-name = "FAN_PWR";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&lsio_gpio2 12 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <®_mba8x_12v>;
+ };
+
+ reg_usb_phy: regulator-usb-phy {
+ compatible = "regulator-fixed";
+ regulator-max-microvolt = <3000000>;
+ regulator-min-microvolt = <3000000>;
+ regulator-name = "usb-phy-dummy";
+ };
+
+ reg_v1v5_pcie: regulator-v1v5-pcie {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_pcie_v1v5>;
+ regulator-name = "V_1V5_MPCIE";
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ vin-supply = <®_mba8x_v3v3>;
+ enable-active-high;
+ gpio = <&lsio_gpio0 31 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ };
+
+ reg_v1v8: regulator-v1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "MBa8x-V1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reg_v3v3_pcie: regulator-v3v3-pcie {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_pcie_v3v3>;
+ regulator-name = "V_3V3_MPCIE";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <®_mba8x_v3v3>;
+ enable-active-high;
+ gpio = <&lsio_gpio1 1 GPIO_ACTIVE_HIGH>;
+ regulator-always-on;
+ };
+
+ reg_v3v3_sd: regulator-v3v3-sd {
+ compatible = "regulator-fixed";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_reg_v3v3_sd>;
+ regulator-name = "V3V3_SD";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <®_mba8x_v3v3>;
+ gpio = <&lsio_gpio4 7 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ regulator-boot-on;
+ off-on-delay-us = <200000>;
+ };
+
+ reg_vref_v1v8: regulator-vref-v1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VREF_V1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ /*
+ * global autoconfigured region for contiguous allocations
+ * must not exceed memory size and region
+ */
+ linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0 0x3c000000>;
+ alloc-ranges = <0 0x96000000 0 0x3c000000>;
+ linux,cma-default;
+ };
+
+ decoder_boot: decoder-boot@84000000 {
+ reg = <0 0x84000000 0 0x2000000>;
+ no-map;
+ };
+
+ encoder1_boot: encoder1-boot@86000000 {
+ reg = <0 0x86000000 0 0x200000>;
+ no-map;
+ };
+
+ encoder2_boot: encoder2-boot@86200000 {
+ reg = <0 0x86200000 0 0x200000>;
+ no-map;
+ };
+
+ decoder_rpc: decoder-rpc@92000000 {
+ reg = <0 0x92000000 0 0x100000>;
+ no-map;
+ };
+
+ encoder1_rpc: encoder1-rpc@92100000 {
+ reg = <0 0x92100000 0 0x700000>;
+ no-map;
+ };
+
+ encoder2_rpc: encoder1-rpc@92800000 {
+ reg = <0 0x92800000 0 0x700000>;
+ no-map;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx-audio-tlv320aic32x4";
+ model = "tqm-tlv320aic32";
+ ssi-controller = <&sai1>;
+ audio-codec = <&tlv320aic3x04>;
+ audio-routing =
+ "IN3_L", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "IN1_L", "Line In Jack",
+ "IN1_R", "Line In Jack",
+ "Line Out Jack", "LOL",
+ "Line Out Jack", "LOR";
+ };
+
+ sound-hdmi {
+ compatible = "fsl,imx-audio-hdmi";
+ model = "imx-audio-dp";
+ audio-cpu = <&sai5>;
+ hdmi-out;
+ };
+
+ thermal-zones {
+ cpu0-thermal {
+ trips {
+ soc_active0_0: trip-active0 {
+ temperature = <40000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ soc_active0_1: trip-active1 {
+ temperature = <48000>;
+ hysteresis = <3000>;
+ type = "active";
+ };
+
+ soc_active0_2: trip-active2 {
+ temperature = <60000>;
+ hysteresis = <10000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map1 {
+ trip = <&soc_active0_0>;
+ cooling-device = <&fan0 1 1>;
+ };
+
+ map2 {
+ trip = <&soc_active0_1>;
+ cooling-device = <&fan0 2 2>;
+ };
+
+ map3 {
+ trip = <&soc_active0_2>;
+ cooling-device = <&fan0 3 3>;
+ };
+ };
+ };
+
+ cpu1-thermal {
+ trips {
+ soc_active1_0: trip-active0 {
+ temperature = <40000>;
+ hysteresis = <5000>;
+ type = "active";
+ };
+
+ soc_active1_1: trip-active1 {
+ temperature = <48000>;
+ hysteresis = <3000>;
+ type = "active";
+ };
+
+ soc_active1_2: trip-active2 {
+ temperature = <60000>;
+ hysteresis = <10000>;
+ type = "active";
+ };
+ };
+
+ cooling-maps {
+ map1 {
+ trip = <&soc_active1_0>;
+ cooling-device = <&fan0 1 1>;
+ };
+
+ map2 {
+ trip = <&soc_active1_1>;
+ cooling-device = <&fan0 2 2>;
+ };
+
+ map3 {
+ trip = <&soc_active1_2>;
+ cooling-device = <&fan0 3 3>;
+ };
+ };
+ };
+ };
+};
+
+&fec1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec1>;
+ phy-mode = "rgmii-id";
+ phy-handle = <ðphy0>;
+ nvmem-cells = <&fec_mac0>;
+ nvmem-cell-names = "mac-address";
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ethphy0>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ reset-gpios = <&lsio_gpio2 6 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ enet-phy-lane-no-swap;
+ interrupt-parent = <&lsio_gpio2>;
+ interrupts = <8 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
+};
+
+&fec2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec2>;
+ phy-mode = "rgmii-id";
+ phy-handle = <ðphy3>;
+ nvmem-cells = <&fec_mac1>;
+ nvmem-cell-names = "mac-address";
+ status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy3: ethernet-phy@3 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <3>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ethphy3>;
+ ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
+ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
+ ti,dp83867-rxctrl-strap-quirk;
+ ti,clk-output-sel = <DP83867_CLK_O_SEL_OFF>;
+ reset-gpios = <&lsio_gpio2 4 GPIO_ACTIVE_LOW>;
+ reset-assert-us = <500000>;
+ reset-deassert-us = <50000>;
+ enet-phy-lane-no-swap;
+ };
+ };
+};
+
+&flexcan1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan1>;
+ status = "okay";
+};
+
+&flexcan2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexcan2>;
+ status = "okay";
+};
+
+&hsio_phy {
+ fsl,hsio-cfg = "pciea-pcieb-sata";
+ fsl,refclk-pad-mode = "input";
+ status = "okay";
+};
+
+/* no refclock gating */
+&hsio_refa_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pcieclk 0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ /delete-property/ enable-gpios;
+};
+
+&hsio_refb_clk {
+ compatible = "fixed-factor-clock";
+ clocks = <&pcieclk 0>;
+ clock-div = <1>;
+ clock-mult = <1>;
+ /delete-property/ enable-gpios;
+};
+
+&i2c1 {
+ tlv320aic3x04: audio-codec@18 {
+ compatible = "ti,tlv320aic32x4";
+ reg = <0x18>;
+ clocks = <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+ clock-names = "mclk";
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&mclkout0_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <12288000>;
+ ldoin-supply = <®_mba8x_v3v3>;
+ iov-supply = <®_v1v8>;
+ };
+
+ sensor1: temperature-sensor@1c {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x1c>;
+ };
+
+ eeprom2: eeprom@54 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x54>;
+ pagesize = <16>;
+ vcc-supply = <®_mba8x_v3v3>;
+ };
+
+ pcieclk: clock-generator@68 {
+ compatible = "renesas,9fgv0441";
+ reg = <0x68>;
+ clocks = <&clk_xtal25>;
+ #clock-cells = <1>;
+ };
+};
+
+&lpspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi0 &pinctrl_lpspi0_cs>;
+ cs-gpios = <&lsio_gpio3 5 GPIO_ACTIVE_LOW>, <&lsio_gpio3 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&lpspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi1 &pinctrl_lpspi1_cs>;
+ cs-gpios = <&lsio_gpio3 24 GPIO_ACTIVE_LOW>, <&lsio_gpio3 25 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&lpspi2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpspi2 &pinctrl_lpspi2_cs>;
+ cs-gpios = <&lsio_gpio3 10 GPIO_ACTIVE_LOW>, <&lsio_gpio3 11 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&lpuart0 {
+ /* console */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart0>;
+ status = "okay";
+};
+
+&lpuart1 {
+ /* X62 pin header */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart1>;
+ status = "okay";
+};
+
+&lpuart2 {
+ /* mikroBUS */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lpuart2>;
+ status = "okay";
+};
+
+&lsio_gpio2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio2>;
+ gpio-line-names = "", "", "", "",
+ "", "PCIE0_DISABLE#", "", "";
+
+ pcie0-wdisable1-hog {
+ gpio-hog;
+ gpios = <5 0>;
+ output-high;
+ line-name = "PCIE0_DISABLE#";
+ };
+
+ pcie-clk-pd-hog {
+ gpio-hog;
+ gpios = <10 0>;
+ output-high;
+ line-name = "PCIE_CLK_PD#";
+ };
+};
+
+&lsio_pwm3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_lsio_pwm3>;
+ status = "okay";
+};
+
+&pciea {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pciea>;
+ phys = <&hsio_phy 0 PHY_TYPE_PCIE 0>;
+ phy-names = "pcie-phy";
+ reset-gpio = <&lsio_gpio4 29 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&pcieb {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pcieb>;
+ phys = <&hsio_phy 1 PHY_TYPE_PCIE 1>;
+ phy-names = "pcie-phy";
+ reset-gpio = <&lsio_gpio5 0 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&sai1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sai1>;
+ assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
+ <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
+ <&sai1_lpcg IMX_LPCG_CLK_0>;
+ assigned-clock-rates = <786432000>, <49152000>, <12288000>, <49152000>;
+ status = "okay";
+};
+
+&sai5 {
+ status = "okay";
+};
+
+&sai5_lpcg {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&usbphy1 {
+ phy-3p0-supply = <®_usb_phy>;
+ status = "okay";
+};
+
+&usbotg1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg1>;
+ srp-disable;
+ hnp-disable;
+ adp-disable;
+ power-active-high;
+ over-current-active-low;
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usb3_phy {
+ status = "okay";
+};
+
+&usbotg3 {
+ /* over-current disabled by default */
+ status = "okay";
+};
+
+&usbotg3_cdns3 {
+ dr_mode = "host";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbhub>;
+ status = "okay";
+
+ hub_2_0: hub@1 {
+ compatible = "usb451,8142";
+ reg = <1>;
+ peer-hub = <&hub_3_0>;
+ reset-gpios = <&lsio_gpio2 7 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_mba8x_v3v3>;
+ };
+
+ hub_3_0: hub@2 {
+ compatible = "usb451,8140";
+ reg = <2>;
+ peer-hub = <&hub_2_0>;
+ reset-gpios = <&lsio_gpio2 7 GPIO_ACTIVE_LOW>;
+ vdd-supply = <®_mba8x_v3v3>;
+ };
+};
+
+&usdhc2 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+ pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+ bus-width = <4>;
+ cd-gpios = <&lsio_gpio5 22 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&lsio_gpio5 21 GPIO_ACTIVE_HIGH>;
+ vmmc-supply = <®_v3v3_sd>;
+ no-mmc;
+ no-sdio;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio>;
+
+ pinctrl_adc0: adc0grp {
+ fsl,pins = <IMX8QM_ADC_IN1_DMA_ADC0_IN1 0x02000060>,
+ <IMX8QM_ADC_IN2_DMA_ADC0_IN2 0x02000060>;
+ };
+
+ pinctrl_ethphy0: ethphy0grp {
+ fsl,pins = <IMX8QM_ESAI1_SCKR_LSIO_GPIO2_IO06 0x00000041>,
+ <IMX8QM_ESAI1_TX0_LSIO_GPIO2_IO08 0x00000021>;
+ };
+
+ pinctrl_ethphy3: ethphy3grp {
+ fsl,pins = <IMX8QM_ESAI1_FSR_LSIO_GPIO2_IO04 0x00000041>;
+ };
+
+ pinctrl_fec1: fec1grp {
+ fsl,pins = <IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0>,
+ <IMX8QM_ENET0_MDC_CONN_ENET0_MDC 0x06000041>,
+ <IMX8QM_ENET0_MDIO_CONN_ENET0_MDIO 0x06000041>,
+ <IMX8QM_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000041>,
+ <IMX8QM_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000041>,
+ <IMX8QM_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000041>,
+ <IMX8QM_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000041>,
+ <IMX8QM_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000041>,
+ <IMX8QM_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000041>,
+ <IMX8QM_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000040>,
+ <IMX8QM_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000040>,
+ <IMX8QM_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000040>,
+ <IMX8QM_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000040>,
+ <IMX8QM_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000040>,
+ <IMX8QM_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000040>;
+ };
+
+ pinctrl_fec2: fec2grp {
+ fsl,pins = <IMX8QM_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0>,
+ <IMX8QM_ENET1_MDC_CONN_ENET1_MDC 0x06000041>,
+ <IMX8QM_ENET1_MDIO_CONN_ENET1_MDIO 0x06000041>,
+ <IMX8QM_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x00000041>,
+ <IMX8QM_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC 0x00000041>,
+ <IMX8QM_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x00000041>,
+ <IMX8QM_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x00000041>,
+ <IMX8QM_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 0x00000041>,
+ <IMX8QM_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 0x00000041>,
+ <IMX8QM_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC 0x00000040>,
+ <IMX8QM_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x00000040>,
+ <IMX8QM_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x00000040>,
+ <IMX8QM_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x00000040>,
+ <IMX8QM_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 0x00000040>,
+ <IMX8QM_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 0x00000040>;
+ };
+
+ pinctrl_flexcan1: flexcan0grp {
+ fsl,pins = <IMX8QM_FLEXCAN0_TX_DMA_FLEXCAN0_TX 0x00000021>,
+ <IMX8QM_FLEXCAN0_RX_DMA_FLEXCAN0_RX 0x00000021>;
+ };
+
+ pinctrl_flexcan2: flexcan1grp {
+ fsl,pins = <IMX8QM_FLEXCAN1_TX_DMA_FLEXCAN1_TX 0x00000021>,
+ <IMX8QM_FLEXCAN1_RX_DMA_FLEXCAN1_RX 0x00000021>;
+ };
+
+ pinctrl_gpio2: gpio2grp {
+ fsl,pins = <IMX8QM_ESAI1_FST_LSIO_GPIO2_IO05 0x00000021>,
+ <IMX8QM_ESAI1_TX2_RX3_LSIO_GPIO2_IO10 0x00000021>;
+ };
+
+ pinctrl_gpio: gpiogrp {
+ fsl,pins = /* GPIO0_05 on X62:26 */
+ <IMX8QM_SIM0_GPIO0_00_LSIO_GPIO0_IO05 0x00000021>,
+ /* GPIO1_14 on X64:21 */
+ <IMX8QM_LVDS1_I2C1_SCL_LSIO_GPIO1_IO14 0x00000021>,
+ /* GPIO1_15 on X64:23 */
+ <IMX8QM_LVDS1_I2C1_SDA_LSIO_GPIO1_IO15 0x00000021>,
+ /* GPIO2_17 on X63:37 */
+ <IMX8QM_SPI3_SCK_LSIO_GPIO2_IO17 0x00000021>,
+ /* GPIO2_21 on X63:39 */
+ <IMX8QM_SPI3_CS1_LSIO_GPIO2_IO21 0x00000021>,
+ /* GPIO4_12 on X61:24 */
+ <IMX8QM_USDHC2_CD_B_LSIO_GPIO4_IO12 0x00000021>,
+ /* GPIO4_11 on X61:26 */
+ <IMX8QM_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021>,
+ /* GPIO4_10 on X61:28 */
+ <IMX8QM_USDHC2_VSELECT_LSIO_GPIO4_IO10 0x00000021>,
+ /* GPIO4_09 on X61:30 */
+ <IMX8QM_USDHC2_RESET_B_LSIO_GPIO4_IO09 0x00000021>,
+ /* GPIO5_23 on X62:24 */
+ <IMX8QM_USDHC1_STROBE_LSIO_GPIO5_IO23 0x00000021>,
+ /* GPIO5_24 on X61:15 */
+ <IMX8QM_USDHC2_CLK_LSIO_GPIO5_IO24 0x00000021>,
+ /* GPIO5_25 on X61:17 */
+ <IMX8QM_USDHC2_CMD_LSIO_GPIO5_IO25 0x00000021>,
+ /* GPIO5_26 on X61:19 */
+ <IMX8QM_USDHC2_DATA0_LSIO_GPIO5_IO26 0x00000021>,
+ /* GPIO5_27 on X61:21 */
+ <IMX8QM_USDHC2_DATA1_LSIO_GPIO5_IO27 0x00000021>,
+ /* GPIO5_28 on X61:23 */
+ <IMX8QM_USDHC2_DATA2_LSIO_GPIO5_IO28 0x00000021>,
+ /* GPIO5_29 on X61:25 */
+ <IMX8QM_USDHC2_DATA3_LSIO_GPIO5_IO29 0x00000021>;
+ };
+
+ pinctrl_gpiokeys: gpiokeysgrp {
+ fsl,pins = <IMX8QM_ESAI1_TX3_RX2_LSIO_GPIO2_IO11 0x00000021>,
+ <IMX8QM_SCU_GPIO0_04_LSIO_GPIO1_IO00 0x00000021>;
+ };
+
+ pinctrl_gpioled: gpioledgrp {
+ fsl,pins = <IMX8QM_USDHC1_DATA4_LSIO_GPIO5_IO19 0x00000021>,
+ <IMX8QM_USDHC1_DATA5_LSIO_GPIO5_IO20 0x00000021>;
+ };
+
+ pinctrl_lpspi0_cs: lpspi0csgrp {
+ fsl,pins = <IMX8QM_SPI0_CS0_LSIO_GPIO3_IO05 0x00000021>,
+ <IMX8QM_SPI0_CS1_LSIO_GPIO3_IO06 0x00000021>;
+ };
+
+ pinctrl_lpspi0: lpspi0grp {
+ fsl,pins = <IMX8QM_SPI0_SCK_DMA_SPI0_SCK 0x0600004d>,
+ <IMX8QM_SPI0_SDO_DMA_SPI0_SDO 0x0600004d>,
+ <IMX8QM_SPI0_SDI_DMA_SPI0_SDI 0x0600004d>;
+ };
+
+ pinctrl_lpspi1_cs: lpspi1csgrp {
+ fsl,pins = <IMX8QM_ADC_IN6_LSIO_GPIO3_IO24 0x00000021>,
+ <IMX8QM_ADC_IN7_LSIO_GPIO3_IO25 0x00000021>;
+ };
+
+ pinctrl_lpspi1: lpspi1grp {
+ fsl,pins = <IMX8QM_ADC_IN3_DMA_SPI1_SCK 0x0600004d>,
+ <IMX8QM_ADC_IN4_DMA_SPI1_SDO 0x0600004d>,
+ <IMX8QM_ADC_IN5_DMA_SPI1_SDI 0x0600004d>;
+ };
+
+ pinctrl_lpspi2: lpspi2grp {
+ fsl,pins = <IMX8QM_SPI2_SCK_DMA_SPI2_SCK 0x0600004d>,
+ <IMX8QM_SPI2_SDO_DMA_SPI2_SDO 0x0600004d>,
+ <IMX8QM_SPI2_SDI_DMA_SPI2_SDI 0x0600004d>;
+ };
+
+ pinctrl_lpspi2_cs: lpspi2sgrp {
+ fsl,pins = <IMX8QM_SPI2_CS0_LSIO_GPIO3_IO10 0x00000021>,
+ <IMX8QM_SPI2_CS1_LSIO_GPIO3_IO11 0x00000021>;
+ };
+
+ pinctrl_lpuart0: lpuart0grp {
+ fsl,pins = <IMX8QM_UART0_RX_DMA_UART0_RX 0x06000021>,
+ <IMX8QM_UART0_TX_DMA_UART0_TX 0x06000021>,
+ <IMX8QM_UART0_CTS_B_DMA_UART0_CTS_B 0x00000021>,
+ <IMX8QM_UART0_RTS_B_DMA_UART0_RTS_B 0x00000021>;
+ };
+
+ pinctrl_lpuart1: lpuart1grp {
+ fsl,pins = <IMX8QM_UART1_RX_DMA_UART1_RX 0x06000021>,
+ <IMX8QM_UART1_TX_DMA_UART1_TX 0x06000021>,
+ <IMX8QM_UART1_CTS_B_DMA_UART1_CTS_B 0x00000021>,
+ <IMX8QM_UART1_RTS_B_DMA_UART1_RTS_B 0x00000021>;
+ };
+
+ pinctrl_lpuart2: lpuart2grp {
+ fsl,pins = <IMX8QM_LVDS0_I2C1_SDA_DMA_UART2_RX 0x06000021>,
+ <IMX8QM_LVDS0_I2C1_SCL_DMA_UART2_TX 0x06000021>;
+ };
+
+ pinctrl_lsio_pwm3: lsiopwm3grp {
+ fsl,pins = <IMX8QM_GPT0_COMPARE_LSIO_PWM3_OUT 0x00000021>;
+ };
+
+ pinctrl_pciea: pcieagrp {
+ fsl,pins = <IMX8QM_PCIE_CTRL0_PERST_B_LSIO_GPIO4_IO29 0x06000021>,
+ <IMX8QM_PCIE_CTRL0_CLKREQ_B_HSIO_PCIE0_CLKREQ_B 0x06000021>,
+ <IMX8QM_PCIE_CTRL0_WAKE_B_LSIO_GPIO4_IO28 0x04000021>;
+ };
+
+ pinctrl_pcieb: pciebgrp {
+ fsl,pins = <IMX8QM_PCIE_CTRL1_PERST_B_LSIO_GPIO5_IO00 0x06000021>,
+ <IMX8QM_PCIE_CTRL1_CLKREQ_B_HSIO_PCIE1_CLKREQ_B 0x06000021>,
+ <IMX8QM_PCIE_CTRL1_WAKE_B_LSIO_GPIO4_IO31 0x04000021>;
+ };
+
+ pinctrl_pwmfan: pwmfangrp {
+ fsl,pins = <IMX8QM_SPI3_CS0_LSIO_GPIO2_IO20 0x30>;
+ };
+
+ pinctrl_reg_mba8x_12v: regmba12vgrp {
+ fsl,pins = <IMX8QM_SCU_GPIO0_06_LSIO_GPIO1_IO02 0x00000021>;
+ };
+
+ pinctrl_reg_pcie_v1v5: regpcie1v5grp {
+ fsl,pins = <IMX8QM_SCU_GPIO0_03_LSIO_GPIO0_IO31 0x00000021>;
+ };
+
+ pinctrl_reg_pcie_v3v3: regpcie3v3grp {
+ fsl,pins = <IMX8QM_SCU_GPIO0_05_LSIO_GPIO1_IO01 0x00000021>;
+ };
+
+ pinctrl_regpwmfan: regpwmfangrp {
+ fsl,pins = <IMX8QM_ESAI1_TX4_RX1_LSIO_GPIO2_IO12 0x00000021>;
+ };
+
+ pinctrl_reg_v3v3_sd: regv3v3sdgrp {
+ fsl,pins = <IMX8QM_USDHC1_RESET_B_LSIO_GPIO4_IO07 0x00000021>;
+ };
+
+ pinctrl_sai1: sai1grp {
+ fsl,pins = <IMX8QM_SAI1_RXD_AUD_SAI1_RXD 0x06000041>,
+ <IMX8QM_SAI1_RXC_AUD_SAI1_RXC 0x06000041>,
+ <IMX8QM_SAI1_RXFS_AUD_SAI1_RXFS 0x06000041>,
+ <IMX8QM_SAI1_TXD_AUD_SAI1_TXD 0x06000061>,
+ <IMX8QM_SAI1_TXC_AUD_SAI1_TXC 0x06000041>,
+ <IMX8QM_MCLK_OUT0_AUD_ACM_MCLK_OUT0 0x0600004d>;
+ };
+
+ pinctrl_usbhub: usbhubgrp {
+ fsl,pins = <IMX8QM_ESAI1_SCKT_LSIO_GPIO2_IO07 0x00000021>;
+ };
+
+ pinctrl_usbotg1: usbotg1grp {
+ fsl,pins = <IMX8QM_USB_SS3_TC2_CONN_USB_OTG1_OC 0x00000021>,
+ <IMX8QM_USB_SS3_TC0_CONN_USB_OTG1_PWR 0x00000021>;
+ };
+
+ pinctrl_usdhc2: usdhc2grp {
+ fsl,pins = <IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041>,
+ <IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021>,
+ <IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021>,
+ <IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021>,
+ <IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021>,
+ <IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021>,
+ <IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021>;
+ };
+
+ pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+ fsl,pins = <IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041>,
+ <IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021>,
+ <IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021>,
+ <IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021>,
+ <IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021>,
+ <IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021>,
+ <IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021>;
+ };
+
+ pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+ fsl,pins = <IMX8QM_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041>,
+ <IMX8QM_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021>,
+ <IMX8QM_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021>,
+ <IMX8QM_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021>,
+ <IMX8QM_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021>,
+ <IMX8QM_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021>,
+ <IMX8QM_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021>;
+ };
+
+ pinctrl_usdhc2_gpio: usdhc2-gpiogrp {
+ fsl,pins = <IMX8QM_USDHC1_DATA6_LSIO_GPIO5_IO21 0x00000021>,
+ <IMX8QM_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021>;
+ };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
new file mode 100644
index 0000000000000..d94605c999915
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8qm-tqma8qm.dtsi
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: (GPL-2.0-or-later OR MIT)
+/*
+ * Copyright (c) 2019-2026 TQ-Systems GmbH <linux@ew.tq-group.com>,
+ * D-82229 Seefeld, Germany.
+ * Author: Alexander Stein
+ */
+
+#include <dt-bindings/firmware/imx/rsrc.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/thermal/thermal.h>
+
+#include "imx8qm.dtsi"
+
+/ {
+ model = "TQ-Systems i.MX8QM TQMa8QM";
+ compatible = "tq,imx8qm-tqma8qm", "fsl,imx8qm";
+
+ memory@80000000 {
+ device_type = "memory";
+ /*
+ * DRAM base addr, size : 1024 MiB DRAM
+ * should be corrected by bootloader
+ */
+ reg = <0x00000000 0x80000000 0 0x40000000>;
+ };
+
+ reg_tqma8x_v3v3: regulator-tqma8x-v3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ /* SW7 controlled by SCU */
+ reg_1v8_io1: regulator-v1v8-io1 {
+ compatible = "regulator-fixed";
+ regulator-name = "V_1V8_IO1";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ /* LDO4 controlled by SCU */
+ reg_3v3_emmc: regulator-v3v3-emmc {
+ compatible = "regulator-fixed";
+ regulator-name = "V_3V3_EMMC";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
+
+&acm {
+ status = "okay";
+};
+
+&adc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_adc0>;
+ vref-supply = <®_vref_v1v8>;
+ status = "okay";
+};
+
+/* TQMa8QM only uses industrial grade, reduce trip points accordingly */
+&cpu_alert0 {
+ temperature = <95000>;
+};
+
+&cpu_crit0 {
+ temperature = <100000>;
+};
+
+&cpu_alert1 {
+ temperature = <95000>;
+};
+
+&cpu_crit1 {
+ temperature = <100000>;
+};
+
+&gpu_alert0 {
+ temperature = <95000>;
+};
+
+&gpu_crit0 {
+ temperature = <100000>;
+};
+
+&gpu_alert1 {
+ temperature = <95000>;
+};
+
+&gpu_crit1 {
+ temperature = <100000>;
+};
+
+&drc_alert0 {
+ temperature = <95000>;
+};
+
+&drc_crit0 {
+ temperature = <100000>;
+};
+/* end of temperature grade adjustments */
+
+&flexspi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_flexspi0>;
+ status = "okay";
+
+ flash0: flash@0 {
+ compatible = "jedec,spi-nor";
+ reg = <0>;
+ spi-max-frequency = <66000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ vcc-supply = <®_1v8_io1>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+ };
+};
+
+&i2c1 {
+ clock-frequency = <400000>;
+ pinctrl-names = "default", "gpio";
+ pinctrl-0 = <&pinctrl_lpi2c1>;
+ pinctrl-1 = <&pinctrl_lpi2c1gpio>;
+ scl-gpios = <&lsio_gpio0 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ sda-gpios = <&lsio_gpio0 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+ status = "okay";
+
+ se97: temperature-sensor@1b {
+ compatible = "nxp,se97b", "jedec,jc-42.4-temp";
+ reg = <0x1b>;
+ };
+
+ pcf85063: rtc@51 {
+ compatible = "nxp,pcf85063a";
+ reg = <0x51>;
+ quartz-load-femtofarads = <7000>;
+ };
+
+ at24c02: eeprom@53 {
+ compatible = "nxp,se97b", "atmel,24c02";
+ reg = <0x53>;
+ pagesize = <16>;
+ read-only;
+ vcc-supply = <®_tqma8x_v3v3>;
+ };
+
+ m24c64: eeprom@57 {
+ compatible = "atmel,24c64";
+ reg = <0x57>;
+ pagesize = <32>;
+ vcc-supply = <®_tqma8x_v3v3>;
+ };
+};
+
+&mu_m0 {
+ status = "okay";
+};
+
+&mu1_m0 {
+ status = "okay";
+};
+
+&mu2_m0 {
+ status = "okay";
+};
+
+&thermal_zones {
+ pmic0-thermal {
+ polling-delay-passive = <250>;
+ polling-delay = <2000>;
+ thermal-sensors = <&tsens IMX_SC_R_PMIC_0>;
+
+ trips {
+ pmic_alert0: trip0 {
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+ pmic_crit0: trip1 {
+ temperature = <125000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map0 {
+ trip = <&pmic_alert0>;
+ cooling-device =
+ <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A72_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&A72_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+};
+
+&usdhc1 {
+ pinctrl-names = "default", "state_100mhz", "state_200mhz";
+ pinctrl-0 = <&pinctrl_usdhc1>;
+ pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+ pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+ bus-width = <8>;
+ vmmc-supply = <®_3v3_emmc>;
+ vqmmc-supply = <®_1v8_io1>;
+ no-sd;
+ no-sdio;
+ non-removable;
+ status = "okay";
+};
+
+&vpu {
+ compatible = "nxp,imx8qm-vpu";
+ status = "okay";
+};
+
+&vpu_core0 {
+ memory-region = <&decoder_boot>, <&decoder_rpc>;
+ status = "okay";
+};
+
+&vpu_core1 {
+ memory-region = <&encoder1_boot>, <&encoder1_rpc>;
+ status = "okay";
+};
+
+&vpu_core2 {
+ memory-region = <&encoder2_boot>, <&encoder2_rpc>;
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl_lpi2c1: lpi2c1grp {
+ fsl,pins = <IMX8QM_GPT0_CAPTURE_DMA_I2C1_SDA 0x0600004d>,
+ <IMX8QM_GPT0_CLK_DMA_I2C1_SCL 0x0600004d>;
+ };
+
+ pinctrl_lpi2c1gpio: lpi2c1gpiogrp {
+ fsl,pins = <IMX8QM_GPT0_CAPTURE_LSIO_GPIO0_IO15 0x0600004d>,
+ <IMX8QM_GPT0_CLK_LSIO_GPIO0_IO14 0x0600004d>;
+ };
+
+ pinctrl_usdhc1: usdhc1grp {
+ fsl,pins = <IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041>,
+ <IMX8QM_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021>,
+ <IMX8QM_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021>,
+ <IMX8QM_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021>,
+ <IMX8QM_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021>,
+ <IMX8QM_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021>,
+ <IMX8QM_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021>,
+ <IMX8QM_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021>,
+ <IMX8QM_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021>,
+ <IMX8QM_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021>,
+ <IMX8QM_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041>,
+ <IMX8QM_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021>;
+ };
+
+ pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+ fsl,pins = <IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040>,
+ <IMX8QM_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021>,
+ <IMX8QM_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021>,
+ <IMX8QM_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021>,
+ <IMX8QM_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021>,
+ <IMX8QM_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021>,
+ <IMX8QM_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021>,
+ <IMX8QM_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021>,
+ <IMX8QM_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021>,
+ <IMX8QM_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021>,
+ <IMX8QM_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041>,
+ <IMX8QM_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021>;
+ };
+
+ pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+ fsl,pins = <IMX8QM_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040>,
+ <IMX8QM_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021>,
+ <IMX8QM_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021>,
+ <IMX8QM_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021>,
+ <IMX8QM_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021>,
+ <IMX8QM_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021>,
+ <IMX8QM_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021>,
+ <IMX8QM_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021>,
+ <IMX8QM_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021>,
+ <IMX8QM_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021>,
+ <IMX8QM_EMMC0_STROBE_CONN_EMMC0_STROBE 0x00000041>,
+ <IMX8QM_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021>;
+ };
+
+ pinctrl_flexspi0: flexspi0grp {
+ fsl,pins = <IMX8QM_QSPI0A_DATA0_LSIO_QSPI0A_DATA0 0x0000004d>,
+ <IMX8QM_QSPI0A_DATA1_LSIO_QSPI0A_DATA1 0x0000004d>,
+ <IMX8QM_QSPI0A_DATA2_LSIO_QSPI0A_DATA2 0x0000004d>,
+ <IMX8QM_QSPI0A_DATA3_LSIO_QSPI0A_DATA3 0x0000004d>,
+ <IMX8QM_QSPI0A_DQS_LSIO_QSPI0A_DQS 0x0000004d>,
+ <IMX8QM_QSPI0A_SS0_B_LSIO_QSPI0A_SS0_B 0x0000004d>,
+ <IMX8QM_QSPI0A_SS1_B_LSIO_QSPI0A_SS1_B 0x0000004d>,
+ <IMX8QM_QSPI0A_SCLK_LSIO_QSPI0A_SCLK 0x0000004d>,
+ <IMX8QM_QSPI0B_SCLK_LSIO_QSPI0B_SCLK 0x0000004d>,
+ <IMX8QM_QSPI0B_DATA0_LSIO_QSPI0B_DATA0 0x0000004d>,
+ <IMX8QM_QSPI0B_DATA1_LSIO_QSPI0B_DATA1 0x0000004d>,
+ <IMX8QM_QSPI0B_DATA2_LSIO_QSPI0B_DATA2 0x0000004d>,
+ <IMX8QM_QSPI0B_DATA3_LSIO_QSPI0B_DATA3 0x0000004d>,
+ <IMX8QM_QSPI0B_DQS_LSIO_QSPI0B_DQS 0x0000004d>,
+ <IMX8QM_QSPI0B_SS0_B_LSIO_QSPI0B_SS0_B 0x0000004d>,
+ <IMX8QM_QSPI0B_SS1_B_LSIO_QSPI0B_SS1_B 0x0000004d>;
+ };
+};
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v11 03/22] drm: Add new general DRM property "color format"
From: Ville Syrjälä @ 2026-03-26 13:07 UTC (permalink / raw)
To: Nicolas Frattaroli
Cc: Maxime Ripard, Harry Wentland, Leo Li, Rodrigo Siqueira,
Alex Deucher, Christian König, David Airlie, Simona Vetter,
Maarten Lankhorst, Thomas Zimmermann, Andrzej Hajda,
Neil Armstrong, Robert Foss, Laurent Pinchart, Jonas Karlman,
Jernej Skrabec, Sandy Huang, Heiko Stübner, Andy Yan,
Jani Nikula, Rodrigo Vivi, Joonas Lahtinen, Tvrtko Ursulin,
Dmitry Baryshkov, Sascha Hauer, Rob Herring, Jonathan Corbet,
Shuah Khan, kernel, amd-gfx, dri-devel, linux-kernel,
linux-arm-kernel, linux-rockchip, intel-gfx, intel-xe, linux-doc,
Werner Sembach, Andri Yngvason, Marius Vlad
In-Reply-To: <3979783.tdWV9SEqCh@workhorse>
On Thu, Mar 26, 2026 at 01:44:03PM +0100, Nicolas Frattaroli wrote:
> On Wednesday, 25 March 2026 12:03:07 Central European Standard Time Ville Syrjälä wrote:
> > On Wed, Mar 25, 2026 at 09:24:27AM +0100, Maxime Ripard wrote:
> > > On Tue, Mar 24, 2026 at 09:53:35PM +0200, Ville Syrjälä wrote:
> > > > On Tue, Mar 24, 2026 at 08:10:11PM +0100, Nicolas Frattaroli wrote:
> > > > > On Tuesday, 24 March 2026 18:00:45 Central European Standard Time Ville Syrjälä wrote:
> > > > > > On Tue, Mar 24, 2026 at 05:01:07PM +0100, Nicolas Frattaroli wrote:
> > > > > > > +enum drm_connector_color_format {
> > > > > > > + /**
> > > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_AUTO: The driver or display protocol
> > > > > > > + * helpers should pick a suitable color format. All implementations of a
> > > > > > > + * specific display protocol must behave the same way with "AUTO", but
> > > > > > > + * different display protocols do not necessarily have the same "AUTO"
> > > > > > > + * semantics.
> > > > > > > + *
> > > > > > > + * For HDMI, "AUTO" picks RGB, but falls back to YCbCr 4:2:0 if the
> > > > > > > + * bandwidth required for full-scale RGB is not available, or the mode
> > > > > > > + * is YCbCr 4:2:0-only, as long as the mode and output both support
> > > > > > > + * YCbCr 4:2:0.
> > > > > > > + *
> > > > > > > + * For display protocols other than HDMI, the recursive bridge chain
> > > > > > > + * format selection picks the first chain of bridge formats that works,
> > > > > > > + * as has already been the case before the introduction of the "color
> > > > > > > + * format" property. Non-HDMI bridges should therefore either sort their
> > > > > > > + * bus output formats by preference, or agree on a unified auto format
> > > > > > > + * selection logic that's implemented in a common state helper (like
> > > > > > > + * how HDMI does it).
> > > > > > > + */
> > > > > > > + DRM_CONNECTOR_COLOR_FORMAT_AUTO = 0,
> > > > > > > +
> > > > > > > + /**
> > > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_RGB444: RGB output format
> > > > > > > + */
> > > > > > > + DRM_CONNECTOR_COLOR_FORMAT_RGB444,
> > > > > > > +
> > > > > > > + /**
> > > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR444: YCbCr 4:4:4 output format (ie.
> > > > > > > + * not subsampled)
> > > > > > > + */
> > > > > > > + DRM_CONNECTOR_COLOR_FORMAT_YCBCR444,
> > > > > > > +
> > > > > > > + /**
> > > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR422: YCbCr 4:2:2 output format (ie.
> > > > > > > + * with horizontal subsampling)
> > > > > > > + */
> > > > > > > + DRM_CONNECTOR_COLOR_FORMAT_YCBCR422,
> > > > > > > +
> > > > > > > + /**
> > > > > > > + * @DRM_CONNECTOR_COLOR_FORMAT_YCBCR420: YCbCr 4:2:0 output format (ie.
> > > > > > > + * with horizontal and vertical subsampling)
> > > > > > > + */
> > > > > > > + DRM_CONNECTOR_COLOR_FORMAT_YCBCR420,
> > > > > >
> > > > > > Seems like this should document what the quantization range
> > > > > > should be for each format.
> > > > > >
> > > > >
> > > > > I don't think so? If you want per-component bit depth values,
> > > > > DRM_FORMAT_* defines would be the appropriate values to use. This
> > > > > enum is more abstract than that, and is there to communicate
> > > > > YUV vs. RGB and chroma subsampling, with bit depth being handled
> > > > > by other properties.
> > > > >
> > > > > If you mean the factor used for subsampling, then that'd only be
> > > > > relevant if YCBCR410 was supported where one chroma plane isn't
> > > > > halved but quartered in resolution. I suspect 4:1:0 will never
> > > > > be added; no digital display protocol standard supports it to my
> > > > > knowledge, and hopefully none ever will.
> > > >
> > > > No, I mean the quantization range (16-235 vs. 0-255 etc).
> > > >
> > > > The i915 behaviour is that YCbCr is always limited range,
> > > > RGB can either be full or limited range depending on the
> > > > "Broadcast RGB" property and other related factors.
> > >
> > > So far the HDMI state has both the format and quantization range as
> > > different fields. I'm not sure we need to document the range in the
> > > format field, maybe only mention it's not part of the format but has a
> > > field of its own?
> >
> > I think we only have it for RGB (on some drivers only?). For YCbCr
> > I think the assumption is limited range everywhere.
> >
> > But I'm not really concerned about documenting struct members.
> > What I'm talking about is the *uapi* docs. Surely userspace
> > will want to know what the new property actually does so the
> > uapi needs to be documented properly. And down the line some
> > new driver might also implement the wrong behaviour if there
> > is no clear specification.
> >
> > So I'm thinking (or perhaps hoping) the rule might be something like:
> > - YCbCr limited range
> > - RGB full range if "Broadcast RGB" property is not present
> > - RGB full or limited range based on the "Broadcast RGB" property
> > if it's present
> >
> > I think the "Broadcast RGB" property itself might also be lacking
> > proper uapi docs, so that may need to be remedied as well.
> >
> >
>
> Alright, so in v12 I'll do the following:
>
> - Add a line to all YCBCR connector formats that specifies they're
> limited range as long as Broadcast RGB is limited. Whether it's limited
> range when Broadcast RGB is full is purposefully left undefined.
"Broadcast RGB", as the name implies, only affects RGB output.
> In the future, we can expand this to state they're limited range by
> default unless some other property is set. If we're not re-using
> Broadcast RGB for that, this will work out fine, because users who
> don't know about the eventual new property won't have this behaviour
> changed. If we do re-use "Broadcast RGB" for that, then only users
> relying on things we explicitly left undefined will get surprise
> full range YCBCR.
> - Add a line to the RGB connector format that specifies its range
> depends on the "Broadcast RGB" property
>
> This is a bit of a mess, because it's entirely reasonable that a
> future YCBCR range property would want to default to full range
> so that users get the most color out of their monitors. But with
> this description of the connector color formats, we can't do that.
>
> If there are alternate suggestions, I'm open for them. We can't
> really rename "Broadcast RGB" but if I had a time machine, that'd
> be my first choice.
>
> Kind regards,
> Nicolas Frattaroli
>
--
Ville Syrjälä
Intel
^ permalink raw reply
* Re: (subset) [PATCH v5 0/9] arm64: dts: amlogic: Add MMC/SD/SDIO support for Khadas VIM4 (Amlogic T7)
From: Neil Armstrong @ 2026-03-26 13:08 UTC (permalink / raw)
To: Kevin Hilman, Jerome Brunet, Martin Blumenstingl, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Ulf Hansson, Johannes Berg,
van Spriel, Ronald Claveau
Cc: linux-arm-kernel, linux-amlogic, devicetree, linux-kernel,
linux-mmc, linux-wireless, Conor Dooley, Xianwei Zhao, Nick Xie
In-Reply-To: <20260326-add-emmc-t7-vim4-v5-0-d3f182b48e9d@aliel.fr>
Hi,
On Thu, 26 Mar 2026 10:59:11 +0100, Ronald Claveau wrote:
> This patch series depends on Jian's SCMI clock patches yet to merge
> https://lore.kernel.org/all/20260313070022.700437-1-jian.hu@amlogic.com/
>
> This series adds device tree support for the MMC, SD card and SDIO
> interfaces on the Amlogic T7 SoC and the Khadas VIM4 board.
>
> The first patches add the necessary building blocks in the T7 SoC
> DTSI: pinctrl nodes for pin muxing, PWM controller nodes, and MMC
> controller nodes. The amlogic,t7-mmc and amlogic,t7-pwm compatible
> strings are introduced with fallbacks to existing drivers, avoiding
> the need for new driver code.
>
> [...]
Thanks, Applied to https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git (v7.1/arm64-dt)
[1/9] arm64: dts: amlogic: t7: Add eMMC, SD card and SDIO pinctrl nodes
https://git.kernel.org/amlogic/c/fb69fa2cabc68da247bcc0bc99a14dc857b16842
[4/9] arm64: dts: amlogic: t7: Add PWM pinctrl nodes
https://git.kernel.org/amlogic/c/b1e49f6c1ac15b2c947bdb1d22a82b823de22d27
[6/9] arm64: dts: amlogic: t7: khadas-vim4: Add power regulators
https://git.kernel.org/amlogic/c/60eff75ac67bbf5445bdbd2842b0109ac591441c
These changes has been applied on the intermediate git tree [1].
The v7.1/arm64-dt branch will then be sent via a formal Pull Request to the Linux SoC maintainers
for inclusion in their intermediate git branches in order to be sent to Linus during
the next merge window, or sooner if it's a set of fixes.
In the cases of fixes, those will be merged in the current release candidate
kernel and as soon they appear on the Linux master branch they will be
backported to the previous Stable and Long-Stable kernels [2].
The intermediate git branches are merged daily in the linux-next tree [3],
people are encouraged testing these pre-release kernels and report issues on the
relevant mailing-lists.
If problems are discovered on those changes, please submit a signed-off-by revert
patch followed by a corrective changeset.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/amlogic/linux.git
[2] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
[3] https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
--
Neil
^ 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