Commit graph

14 commits

Author SHA1 Message Date
guanyi3
3839a11f2b drivers/devfreq: add ondemand governor build support
Add Kconfig, Make.defs, and CMakeLists.txt entries for the ondemand governor so it can be enabled via CONFIG_DEVFREQ_GOV_ONDEMAND.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
2d66436185 drivers/devfreq: guard backtrace code with CONFIG_LIBC_BACKTRACE_DEPTH
When CONFIG_LIBC_BACKTRACE_DEPTH is not set or <= 0, backtrace_get()
is a macro that always sets depth to 0, making the for-loop body
unreachable (Coverity CID 8405332 DEADCODE).

Wrap backtrace_get() call, the loop, and related variable declarations
with #if CONFIG_LIBC_BACKTRACE_DEPTH > 0 to eliminate the dead code
and avoid unused variable warnings.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
31041f84ea drivers/devfreq: fix qos_get_value returning wrong min/max aggregation
QOS_REQ_MIN should return the highest value among all min requests
(most restrictive lower bound), but plist_first returns the lowest.
QOS_REQ_MAX should return the lowest value among all max requests
(most restrictive upper bound), but plist_last returns the highest.

This caused qos constraints to be ineffective. For example, two
requests (32, 208000) and (104000, 104000) would merge to (32, 208000)
instead of the correct (104000, 104000).

Fix by using plist_last for QOS_REQ_MIN and plist_first for QOS_REQ_MAX.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
674e5ef4d8 drivers/devfreq: use hardware frequency instead of cached value in driver_target
The cached devfreq->cur may become stale when the hardware frequency is
changed externally (e.g. by another core or governor). This causes
driver_target to incorrectly skip frequency transitions when the target
matches the cached value but differs from the actual hardware frequency.

Use driver->get_frequency() to read the real hardware frequency for the
unchanged check, and sync devfreq->cur on match to keep the cache correct.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
414694b780 devfreq/ondemand: fix use-after-free in ondemand worker
When devfreq_gov_ondemand_stop() is called from idle task context,
work_cancel() is used instead of work_cancel_sync(), which does not
wait for the currently running worker to complete. If
devfreq_gov_ondemand_exit() then frees governor_data, the worker
may still be accessing it, causing a use-after-free crash.

Fix this by:
- Nullifying dev->governor_data under dev->lock in exit before freeing.
- Moving the governor_data read inside dev->lock in the worker and
  adding a NULL check to bail out early if data has been freed.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
77cb20f041 drivers/devfreq: add conflict_policy to devfreq_driver_s
When multiple QoS requests have no overlapping frequency range (min > max), the previous behavior always clamped to the lower frequency. Add a conflict_policy field to devfreq_driver_s so callers can choose between DEVFREQ_CONFLICT_PREFER_HIGH (default, choose higher freq) and DEVFREQ_CONFLICT_PREFER_LOW (choose lower freq) at registration.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
7a1c62911d devfreq/procfs: add write support for frequency QoS constraints
Add the ability to set frequency constraints via procfs write.
Supported formats:
  echo <min>,<max> > /proc/devfreq/<name>  - set frequency range
  echo 0,0 > /proc/devfreq/<name>          - remove constraint

The QoS request is bound to the devfreq device lifetime so that
shell commands like echo (which open, write, close immediately)
work correctly. Leading whitespace in the write buffer is skipped
to handle extra writes from nsh echo (e.g. trailing newline).

Also add write permissions in devfreq_stat() and a procfs_qos
field in devfreq_s guarded by CONFIG_DEVFREQ_PROCFS.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
(cherry picked from commit 70ae195c84f35a4d0b85fcc14187989b60fc0280)
2026-08-08 15:23:54 -03:00
guanyi3
ecd64e04c0 drivers/devfreq: replace mutex to spinlock
we may call devfreq_find_by_name() in pm_callback, and shouldn't call nxmutex_lock() in idle_loop, so replace mutex to spinlock.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
072cae5193 drivers/devfreq: ondemand should init governor_data before use it
devfreq_qos_add_request -> devfreq_refresh_limit -> devfreq_limit_governor -> devfreq_gov_ondemand_limit, here use governor_data but it's 0x0

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
4f6a0bd36c drivers/devfreq: add ondemand governor
Add devfreq ondemand governor that scales device frequency based on CPU load. When CPU load exceeds the configured threshold, frequency is set to maximum; otherwise it is scaled proportionally.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
20cb512617 drivers/devfreq: add const to devfreq_governor_s and devfreq_driver_s
we do not hope the governor and driver in devfreq to be modified.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi3
1e2f9745cb drivers/devfreq: remove default governor
It's better not to use global governor, as modifying one device will cause all devices' governor to be modified.

Signed-off-by: guanyi3 <guanyi3@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi
827b455f68 driver/devfreq: add procfs for devfreq
> ls /proc/devfreq
 /proc/devfreq:
 test_devfreq
> cat /proc/devfreq/test_devfreq
 devfreq:     test_devfreq
 governor:    test_devfreq_governor
 cur_freq:    500
 suspended:   False
 freq_table:  100 300 500 700 900
 qos_list(min, max, backtrace):
 195, 829, 0x4007c26 0x40a0e0e 0x405c706 0x4011186 0x4010dca 0x42777cc 0x4062f7e 0x409da6a

Signed-off-by: guanyi <guanyi@xiaomi.com>
2026-08-08 15:23:54 -03:00
guanyi
e29a7bcb07 driver/devfreq: DVFS framework for devices
This commit introduces a devfreq framework to manage device frequency
scaling. The framework includes the following features:
1.devfreq governor
  - provide governor ops, including init, start, stop, exit
  - default governor, performance & powersave
  - customized governor, device can provide governor when register
2.runtime register and unregister
  - device can runtime register & unregister, search by name
3.suspend and resume
  - suspend and resume frequency scaling
4.notify
  - register & unregister notifier callback, notify frequency changes
5.qos support
  - simplified QoS, manage multiple freq range request
  - including init, add/remove/update request, get value

Signed-off-by: guanyi <guanyi@xiaomi.com>
2026-08-08 15:23:54 -03:00