From 045e8a7d9e66e7390e8a4be143f3f447cbf5cb7b Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Tue, 18 Oct 2011 11:29:36 +0800 Subject: [PATCH] regulator: rk29-pwm: fix sleep in atomic fix this bug, only happens when cpu run in 1.2G. BUG: scheduling while atomic: VideoTrackEncod/414/0x00000202 [] (unwind_backtrace+0x0/0xd8) from [] (schedule+0x74/0x540) [] (schedule+0x74/0x540) from [] (schedule_hrtimeout_range+0x138/0x178) [] (schedule_hrtimeout_range+0x138/0x178) from [] (usleep_range+0x44/0x48) [] (usleep_range+0x44/0x48) from [] (pwm_regulator_set_voltage+0x140/0x168) [] (pwm_regulator_set_voltage+0x140/0x168) from [] (regulator_set_voltage+0xe8/0x100) [] (regulator_set_voltage+0xe8/0x100) from [] (rk29_cpufreq_target+0x5f4/0x6cc) [] (rk29_cpufreq_target+0x5f4/0x6cc) from [] (__cpufreq_driver_target+0x28/0x38) [] (__cpufreq_driver_target+0x28/0x38) from [] (cpufreq_driver_target+0x44/0x60) [] (cpufreq_driver_target+0x44/0x60) from [] (rk29_cpufreq_aclk_vepu_notifier_event+0x78/0x94) [] (rk29_cpufreq_aclk_vepu_notifier_event+0x78/0x94) from [] (notifier_call_chain+0x2c/0x70) [] (notifier_call_chain+0x2c/0x70) from [] (raw_notifier_call_chain+0x14/0x18) [] (raw_notifier_call_chain+0x14/0x18) from [] (clk_notify+0x68/0xec) [] (clk_notify+0x68/0xec) from [] (clk_enable_nolock+0x4c/0xc4) [] (clk_enable_nolock+0x4c/0xc4) from [] (clk_enable+0x70/0xb4) [] (clk_enable+0x70/0xb4) from [] (vpu_service_power_on+0x48/0xec) [] (vpu_service_power_on+0x48/0xec) from [] (vpu_service_ioctl+0x688/0x6e4) [] (vpu_service_ioctl+0x688/0x6e4) from [] (vfs_ioctl+0x2c/0x8c) [] (vfs_ioctl+0x2c/0x8c) from [] (do_vfs_ioctl+0x558/0x5c4) [] (do_vfs_ioctl+0x558/0x5c4) from [] (sys_ioctl+0x34/0x54) [] (sys_ioctl+0x34/0x54) from [] (ret_fast_syscall+0x0/0x2c) --- drivers/regulator/rk29-pwm-regulator.c | 134 +++++++++++++------------ 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/drivers/regulator/rk29-pwm-regulator.c b/drivers/regulator/rk29-pwm-regulator.c index aa49b3f799cc..ddc983a467f7 100644 --- a/drivers/regulator/rk29-pwm-regulator.c +++ b/drivers/regulator/rk29-pwm-regulator.c @@ -1,48 +1,49 @@ /* drivers/regulator/rk29-pwm-regulator.c - * - * Copyright (C) 2010 ROCKCHIP, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -/*******************************************************************/ -/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */ -/******************************************************************* + * + * Copyright (C) 2010 ROCKCHIP, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +/*******************************************************************/ +/* COPYRIGHT (C) ROCK-CHIPS FUZHOU . ALL RIGHTS RESERVED. */ +/******************************************************************* FILE : rk29-pwm-regulator.c DESC : rk29 pwm regulator driver AUTHOR : hxy DATE : 2010-12-20 -NOTES : -$LOG: GPIO.C,V $ -REVISION 0.01 -********************************************************************/ - - -#include +NOTES : +$LOG: GPIO.C,V $ +REVISION 0.01 +********************************************************************/ + + +#include #include +#include #include #include #include #include #include -#include +#include #include #include #include - - -#if 0 -#define DBG(x...) printk(KERN_INFO x) -#else -#define DBG(x...) -#endif + + +#if 0 +#define DBG(x...) printk(KERN_INFO x) +#else +#define DBG(x...) +#endif #define PWM_VCORE_120 40 @@ -101,7 +102,10 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate) return -1; } - usleep_range(10*1000, 10*1000); + if (in_atomic() || irqs_disabled()) + mdelay(10); + else + usleep_range(10*1000, 10*1000); return (0); @@ -120,20 +124,20 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev) { DBG("Enter %s\n",__FUNCTION__); return 0; -} - +} + static int pwm_regulator_enable(struct regulator_dev *dev) { DBG("Enter %s\n",__FUNCTION__); return 0; -} - +} + static int pwm_regulator_disable(struct regulator_dev *dev) { DBG("Enter %s\n",__FUNCTION__); return 0; -} - +} + static int pwm_regulator_get_voltage(struct regulator_dev *dev) { struct pwm_platform_data *pdata = rdev_get_drvdata(dev); @@ -141,8 +145,8 @@ static int pwm_regulator_get_voltage(struct regulator_dev *dev) DBG("Enter %s\n",__FUNCTION__); return (pdata->pwm_voltage*1000); -} - +} + static int pwm_regulator_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { @@ -157,14 +161,14 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev, DBG("%s: min_uV = %d, max_uV = %d\n",__FUNCTION__, min_uV,max_uV); if (min_mV < voltage_map[0] ||max_mA > voltage_map[size-1]) - return -EINVAL; - + return -EINVAL; + for (i = 0; i < size; i++) { if (voltage_map[i] >= min_mV) - break; + break; } - + vol = voltage_map[i]; @@ -179,8 +183,8 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev, return 0; -} - +} + static struct regulator_ops pwm_voltage_ops = { .list_voltage = pwm_regulator_list_voltage, .set_voltage =pwm_regulator_set_voltage, @@ -189,30 +193,30 @@ static struct regulator_ops pwm_voltage_ops = { .disable = pwm_regulator_disable, .is_enabled = pwm_regulator_is_enabled, }; - + static struct regulator_desc pwm_regulator= { .name = "pwm-regulator", .ops = &pwm_voltage_ops, .type = REGULATOR_VOLTAGE, }; - + static int __devinit pwm_regulator_probe(struct platform_device *pdev) { struct pwm_platform_data *pdata = pdev->dev.platform_data; struct regulator_dev *rdev; int ret ; - - if (!pdata) - return -ENODEV; - - if (!pdata->pwm_voltage) - pdata->pwm_voltage = 1200; // default 1.2v - + + if (!pdata) + return -ENODEV; + + if (!pdata->pwm_voltage) + pdata->pwm_voltage = 1200; // default 1.2v + rdev = regulator_register(&pwm_regulator, &pdev->dev, pdata->init_data, pdata); if (IS_ERR(rdev)) { - dev_dbg(&pdev->dev, "couldn't register regulator\n"); + dev_dbg(&pdev->dev, "couldn't register regulator\n"); return PTR_ERR(rdev); } @@ -239,7 +243,7 @@ err_gpio: return ret; -} +} static int __devexit pwm_regulator_remove(struct platform_device *pdev) { struct pwm_platform_data *pdata = pdev->dev.platform_data; @@ -257,23 +261,23 @@ static struct platform_driver pwm_regulator_driver = { }, .remove = __devexit_p(pwm_regulator_remove), }; - + static int __init pwm_regulator_module_init(void) -{ +{ return platform_driver_probe(&pwm_regulator_driver, pwm_regulator_probe); -} - +} + static void __exit pwm_regulator_module_exit(void) -{ +{ platform_driver_unregister(&pwm_regulator_driver); -} +} subsys_initcall(pwm_regulator_module_init); module_exit(pwm_regulator_module_exit); - -MODULE_LICENSE("GPL"); + +MODULE_LICENSE("GPL"); MODULE_AUTHOR("hxy "); MODULE_DESCRIPTION("k29 pwm change driver"); -- 2.34.1