[PATCH v7 6/6] ARM: S5PV210: Initial CPUFREQ Support
Kukjin Kim
kgene.kim at samsung.com
Wed Aug 18 19:30:48 EDT 2010
MyungJoo Ham wrote:
>
> S5PV210 CPUFREQ Support.
>
> This CPUFREQ may work without PMIC's DVS support. However, it is not
> as effective without DVS support as supposed. AVS is not supported in
> this version.
>
> Note that CLK_SRC of some clocks including ARMCLK, G3D, G2D, MFC,
> and ONEDRAM are modified directly without updating clksrc_src
> representations of the clocks. Because CPUFREQ reverts the CLK_SRC
> to the supposed values, this does not affect the consistency as long as
> there are no other modules that modifies clock sources of ARMCLK, G3D,
> G2D, MFC, and ONEDRAM (and only CPUFREQ should have the control). As
> soon as clock framework is settled, we may update source clocks
> (.parent field) of those clocks accordingly later.
>
> Signed-off-by: MyungJoo Ham <myungjoo.ham at samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
> --
> v2:
> - Ramp-up delay is removed. (let regulator framework do the job)
> - Provide proper max values for regulator_set_voltage
> - Removed unneccesary #ifdef's.
> - Removed unnecessary initialiser for CLK_OUT
> v3:
> - Style corrections (pr_info/pr_err, ...)
> - Revised dvs_conf struct
> v4:
> - Renamed cpufreq-s5pv210.c -> cpufreq.c
> - Style corrections (less #ifdef's, comments)
> - Removed unncessary codes
> - Remove #ifdef for WORKAROUND, use s5pv210_workaround()
> - Renamed some static variables (get rid of s5pv210 prefix)
> - Added machine dependency to Kconfig/Makefile
> - DMC0, DMC1 refresh counter is not updated by a hardcoded value,
but
> with the value given as the default and relative clock speeds.
Besides,
> the algorithm to update DMC0/1 refresh counter is reformed.
> v5:
> - Remove unnecessary USE_FREQ_TABLE
> - Renamed functions
> - s5pv210_cpufreq_target's initialization revised. (first_run)
> - "workaround" --> "revision"
> - CLK_*_STAT register entries use macros: they are used mutiple
> times.
> v6:
> - Restyled evt0-related codes.
> v7:
> - Updated evt0-check method.
> - Enable CPUFREQ Only for Aquila/Goni
> - Style patch (inline functions)
>
> ---
> arch/arm/Kconfig | 1 +
> arch/arm/mach-s5pv210/Kconfig | 6 +
> arch/arm/mach-s5pv210/Makefile | 2 +
> arch/arm/mach-s5pv210/cpufreq.c | 792
> +++++++++++++++++++++++++
> arch/arm/mach-s5pv210/include/mach/cpu-freq.h | 38 ++
> 5 files changed, 839 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-s5pv210/cpufreq.c
> create mode 100644 arch/arm/mach-s5pv210/include/mach/cpu-freq.h
>
(snip)
> +#ifdef CONFIG_PM
> +static int previous_frequency;
> +
> +static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy,
> + pm_message_t pmsg)
> +{
> + int ret = 0;
> + pr_info("cpufreq: Entering suspend.\n");
> +
> + previous_frequency = cpufreq_get(0);
> + ret = __cpufreq_driver_target(cpufreq_cpu_get(0), SLEEP_FREQ,
> + DISABLE_FURTHER_CPUFREQ);
> + return ret;
> +}
> +
> +static int s5pv210_cpufreq_resume(struct cpufreq_policy *policy)
> +{
> + int ret = 0;
> + u32 rate;
> + int level = CPUFREQ_TABLE_END;
> + int i = 0;
> +
> + pr_info("cpufreq: Waking up from a suspend.\n");
> +
> + __cpufreq_driver_target(cpufreq_cpu_get(0), previous_frequency,
> + ENABLE_FURTHER_CPUFREQ);
> +
> + /* Clock information update with wakeup value */
> + rate = clk_get_rate(mpu_clk);
> +
> + while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
> + if (freq_table[i].frequency * 1000 == rate) {
> + level = freq_table[i].index;
> + break;
> + }
> + i++;
> + }
> +
> + if (level == CPUFREQ_TABLE_END) { /* Not found */
> + pr_err("[%s:%d] clock speed does not match: "
> + "%d. Using L1 of 800MHz.\n",
> + __FILE__, __LINE__, rate);
> + level = L1;
> + }
> +
> + memcpy(&s3c_freqs.old, &clk_info[level],
> + sizeof(struct s3c_freq));
> + previous_arm_volt = dvs_conf[level].arm_volt;
> + return ret;
> +}
> +#endif
> +
(snip)
Hi,
Did you test on the board?
The following error occurs.
--
...
cpufreq: Entering suspend.
BUG: sleeping function called from invalid context at kernel/rwsem.c:21
in_atomic(): 0, irqs_disabled(): 128, pid: 13, name: suspend
[<c002c91c>] (unwind_backtrace+0x0/0xec) from [<c0295dd0>]
(down_read+0x18/0x28)
[<c0295dd0>] (down_read+0x18/0x28) from [<c01e8524>]
(lock_policy_rwsem_read+0x2c/0x50)
[<c01e8524>] (lock_policy_rwsem_read+0x2c/0x50) from [<c01e85d4>]
(cpufreq_get+0x20/0x50)
[<c01e85d4>] (cpufreq_get+0x20/0x50) from [<c0031e5c>]
(s5pv210_cpufreq_suspend+0x14/0x40)
[<c0031e5c>] (s5pv210_cpufreq_suspend+0x14/0x40) from [<c01e78c8>]
(cpufreq_suspend+0x50/0x84)
[<c01e78c8>] (cpufreq_suspend+0x50/0x84) from [<c0175464>]
(sysdev_suspend+0x84/0x28c)
[<c0175464>] (sysdev_suspend+0x84/0x28c) from [<c0071324>]
(suspend_devices_and_enter+0xe0/0x1a0)
[<c0071324>] (suspend_devices_and_enter+0xe0/0x1a0) from [<c007148c>]
(enter_state+0xa8/0xd4)
[<c007148c>] (enter_state+0xa8/0xd4) from [<c0072914>] (suspend+0x60/0x124)
[<c0072914>] (suspend+0x60/0x124) from [<c0058260>]
(worker_thread+0x15c/0x1ec)
[<c0058260>] (worker_thread+0x15c/0x1ec) from [<c005b58c>]
(kthread+0x78/0x80)
[<c005b58c>] (kthread+0x78/0x80) from [<c0027f64>]
(kernel_thread_exit+0x0/0x8)
...
--
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim at samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
More information about the linux-arm-kernel
mailing list