From e592356dbbf6b403b4389d0ec2e1c4d4048b5fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=99=B4?= Date: Wed, 15 Aug 2012 17:20:59 +0800 Subject: [PATCH 1/7] rk2928:sdk:support pwm set voltage --- .../mach-rk2928/board-rk2928-sdk-tps65910.c | 13 +- arch/arm/mach-rk2928/board-rk2928-sdk.c | 64 ++++++- drivers/regulator/rk30-pwm-regulator.c | 161 ++++++++++++++---- include/linux/regulator/rk29-pwm-regulator.h | 5 + 4 files changed, 200 insertions(+), 43 deletions(-) mode change 100644 => 100755 include/linux/regulator/rk29-pwm-regulator.h diff --git a/arch/arm/mach-rk2928/board-rk2928-sdk-tps65910.c b/arch/arm/mach-rk2928/board-rk2928-sdk-tps65910.c index 51cf60dc2029..4b8d6058d3ee 100755 --- a/arch/arm/mach-rk2928/board-rk2928-sdk-tps65910.c +++ b/arch/arm/mach-rk2928/board-rk2928-sdk-tps65910.c @@ -237,6 +237,10 @@ int tps65910_post_init(struct tps65910 *tps65910) struct regulator *dcdc; struct regulator *ldo; printk("%s,line=%d\n", __func__,__LINE__); + + #ifdef CONFIG_RK30_PWM_REGULATOR + platform_device_register(&pwm_regulator_device[0]); + #endif dcdc = regulator_get(NULL, "vio"); //vcc_io regulator_set_voltage(dcdc, 3300000, 3300000); @@ -315,15 +319,6 @@ int tps65910_post_init(struct tps65910 *tps65910) regulator_put(ldo); udelay(100); - #ifdef CONFIG_RK30_PWM_REGULATOR - dcdc = regulator_get(NULL, "vdd_core"); // vdd_log - regulator_set_voltage(dcdc, 1100000, 1100000); - regulator_enable(dcdc); - printk("%s set vdd_core=%dmV end\n", __func__, regulator_get_voltage(dcdc)); - regulator_put(dcdc); - udelay(100); - #endif - printk("%s,line=%d END\n", __func__,__LINE__); return 0; diff --git a/arch/arm/mach-rk2928/board-rk2928-sdk.c b/arch/arm/mach-rk2928/board-rk2928-sdk.c index fb48103c0245..57eef7b606de 100755 --- a/arch/arm/mach-rk2928/board-rk2928-sdk.c +++ b/arch/arm/mach-rk2928/board-rk2928-sdk.c @@ -379,6 +379,59 @@ static struct platform_device device_ion = { }; #endif +#if CONFIG_RK30_PWM_REGULATOR +const static int pwm_voltage_map[] = { + 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000 +}; + +static struct regulator_consumer_supply pwm_dcdc1_consumers[] = { + { + .supply = "vdd_core", + } +}; + +struct regulator_init_data pwm_regulator_init_dcdc[1] = +{ + { + .constraints = { + .name = "PWM_DCDC1", + .min_uV = 600000, + .max_uV = 1800000, //0.6-1.8V + .apply_uV = true, + .valid_ops_mask = REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(pwm_dcdc1_consumers), + .consumer_supplies = pwm_dcdc1_consumers, + }, +}; + +static struct pwm_platform_data pwm_regulator_info[1] = { + { + .pwm_id = 2, + .pwm_gpio = RK2928_PIN0_PD4, + .pwm_iomux_name = GPIO0D4_PWM_2_NAME, + .pwm_iomux_pwm = GPIO0D_PWM_2, + .pwm_iomux_gpio = GPIO0D_GPIO0D4, + .pwm_voltage = 1200000, + .suspend_voltage = 1050000, + .min_uV = 1000000, + .max_uV = 1400000, + .coefficient = 455, //45.5% + .pwm_voltage_map = pwm_voltage_map, + .init_data = &pwm_regulator_init_dcdc[0], + }, +}; + +struct platform_device pwm_regulator_device[1] = { + { + .name = "pwm-voltage-regulator", + .id = 0, + .dev = { + .platform_data = &pwm_regulator_info[0], + } + }, +}; +#endif /************************************************************************************************** * SDMMC devices, include the module of SD,MMC,and sdio.noted by xbw at 2012-03-05 **************************************************************************************************/ @@ -717,10 +770,15 @@ static void __init rk30_i2c_register_board_info(void) //end of i2c #define POWER_ON_PIN RK2928_PIN3_PC5 //power_hold -static void rk30_pm_power_off(void) +static void rk2928_pm_power_off(void) { - printk(KERN_ERR "rk30_pm_power_off start...\n"); + printk(KERN_ERR "rk2928_pm_power_off start...\n"); + + #if defined(CONFIG_MFD_TPS65910) + tps65910_device_shutdown();//tps65910 shutdown + #endif gpio_direction_output(POWER_ON_PIN, GPIO_LOW); + }; static void __init rk2928_board_init(void) @@ -729,7 +787,7 @@ static void __init rk2928_board_init(void) gpio_direction_output(POWER_ON_PIN, GPIO_HIGH); gpio_free(POWER_ON_PIN); - pm_power_off = rk30_pm_power_off; + pm_power_off = rk2928_pm_power_off; rk30_i2c_register_board_info(); spi_register_board_info(board_spi_devices, ARRAY_SIZE(board_spi_devices)); diff --git a/drivers/regulator/rk30-pwm-regulator.c b/drivers/regulator/rk30-pwm-regulator.c index 7a89527b0b06..ce7aee35eee5 100755 --- a/drivers/regulator/rk30-pwm-regulator.c +++ b/drivers/regulator/rk30-pwm-regulator.c @@ -66,34 +66,37 @@ struct rk_pwm_dcdc { #define pwm_read_reg(id, addr) __raw_readl(addr+(RK30_PWM01_BASE+(id>>1)*0x20000+id*0x10)) #elif defined(CONFIG_ARCH_RK29) #define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK29_PWM_BASE+id*0x10)) -#define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10)) +#define pwm_read_reg(id, addr) __raw_readl(addr+(RK29_PWM_BASE+id*0x10)) +#elif defined(CONFIG_ARCH_RK2928) +#define pwm_write_reg(id, addr, val) __raw_writel(val, addr+(RK2928_PWM_BASE+id*0x10)) +#define pwm_read_reg(id, addr) __raw_readl(addr+(RK2928_PWM_BASE+id*0x10)) #endif const static int pwm_voltage_map[] = { - 850000,875000,900000,925000,950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000 + 1000000, 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000 }; static struct clk *pwm_clk[2]; +static struct rk_pwm_dcdc *g_dcdc; static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate) { u32 divh,divTotal; int id = pdata->pwm_id; unsigned long clkrate; - - if ( id >3 || id <0 ) + /* + if ( id >2 || id <0 ) { printk("%s:pwm id error,id=%d\n",__func__,id); return -1; } if((id==0) || (id == 1)) + */ clkrate = clk_get_rate(pwm_clk[0]); - else - clkrate = clk_get_rate(pwm_clk[1]); - DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate); - + DBG("%s:id=%d,rate=%d,clkrate=%d\n",__func__,id,rate,clkrate); + if(rate == 0) { // iomux pwm to gpio @@ -101,9 +104,9 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate) //disable pull up or down gpio_pull_updown(pdata->pwm_gpio,PullDisable); // set gpio to low level - gpio_set_value(pdata->pwm_gpio,GPIO_LOW); + gpio_direction_output(pdata->pwm_gpio,GPIO_LOW); } - else if (rate <= 100) + else if (rate < 100) { // iomux pwm rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_pwm); @@ -119,6 +122,16 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate) pwm_write_reg(id,PWM_REG_CNTR,0); pwm_write_reg(id, PWM_REG_CTRL,pwm_read_reg(id,PWM_REG_CTRL)|PWM_DIV|PWM_ENABLE|PWM_TimeEN); } + else if (rate == 100) + { + // iomux pwm to gpio + rk29_mux_api_set(pdata->pwm_iomux_name, pdata->pwm_iomux_gpio); + //disable pull up or down + gpio_pull_updown(pdata->pwm_gpio,PullDisable); + // set gpio to low level + gpio_direction_output(pdata->pwm_gpio,GPIO_HIGH); + + } else { printk("%s:rate error\n",__func__); @@ -132,8 +145,9 @@ static int pwm_set_rate(struct pwm_platform_data *pdata,int nHz,u32 rate) static int pwm_regulator_list_voltage(struct regulator_dev *dev,unsigned int index) { - if (index < sizeof(pwm_voltage_map)/sizeof(int)) - return pwm_voltage_map[index]; + struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev); + if (index < dcdc->desc.n_voltages) + return dcdc->pdata->pwm_voltage_map[index]; else return -1; } @@ -176,15 +190,14 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev, #endif { struct rk_pwm_dcdc *dcdc = rdev_get_drvdata(dev); - const int *voltage_map = pwm_voltage_map; - - int min_mV = min_uV, max_mA = max_uV; - - u32 size = sizeof(pwm_voltage_map)/sizeof(int), i, vol,pwm_value; + const int *voltage_map = dcdc->pdata->pwm_voltage_map; + int max = dcdc->pdata->max_uV; + int coefficient = dcdc->pdata->coefficient; + u32 size = dcdc->desc.n_voltages, i, vol,pwm_value; 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]) + if (min_uV < voltage_map[0] ||max_uV > voltage_map[size-1]) { printk("%s:voltage is out of table\n",__func__); return -EINVAL; @@ -192,7 +205,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev, for (i = 0; i < size; i++) { - if (voltage_map[i] >= min_mV) + if (voltage_map[i] >= min_uV) break; } @@ -201,9 +214,8 @@ static int pwm_regulator_set_voltage(struct regulator_dev *dev, dcdc->pdata->pwm_voltage = vol; - // VDD12 = 1.42 - 0.56*D , 其中D为PWM占空比, - pwm_value = (1325000-vol)/5800; // pwm_value % - + // VDD12 = 1.40 - 0.455*D , 其中D为PWM占空比, + pwm_value = (max-vol)/coefficient/10; // pwm_value %, coefficient *1000 if (pwm_set_rate(dcdc->pdata,1000*1000,pwm_value)!=0) { @@ -242,7 +254,6 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev) struct pwm_platform_data *pdata = pdev->dev.platform_data; struct rk_pwm_dcdc *dcdc; int pwm_id = pdata->pwm_id; - struct regulator_dev *rdev; int id = pdev->id; int ret ; char gpio_name[20]; @@ -251,8 +262,23 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev) return -ENODEV; if (!pdata->pwm_voltage) - pdata->pwm_voltage = 1200000; // default 1.2v + pdata->pwm_voltage = 1100000; // default 1.1v + if(!pdata->pwm_voltage_map) + pdata->pwm_voltage_map = pwm_voltage_map; + + if(!pdata->max_uV) + pdata->max_uV = 1400000; + + if(!pdata->min_uV) + pdata->min_uV = 1000000; + + if(pdata->suspend_voltage < pdata->min_uV) + pdata->suspend_voltage = pdata->min_uV; + + if(pdata->suspend_voltage > pdata->max_uV) + pdata->suspend_voltage = pdata->max_uV; + dcdc = kzalloc(sizeof(struct rk_pwm_dcdc), GFP_KERNEL); if (dcdc == NULL) { dev_err(&pdev->dev, "Unable to allocate private data\n"); @@ -263,11 +289,11 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev) dcdc->desc.name = dcdc->name; dcdc->desc.id = id; dcdc->desc.type = REGULATOR_VOLTAGE; - dcdc->desc.n_voltages = 50; + dcdc->desc.n_voltages = ARRAY_SIZE(pwm_voltage_map); dcdc->desc.ops = &pwm_voltage_ops; dcdc->desc.owner = THIS_MODULE; dcdc->pdata = pdata; - + printk("%s:n_voltages=%d\n",__func__,dcdc->desc.n_voltages); dcdc->regulator = regulator_register(&dcdc->desc, &pdev->dev, pdata->init_data, dcdc); if (IS_ERR(dcdc->regulator)) { @@ -297,10 +323,17 @@ static int __devinit pwm_regulator_probe(struct platform_device *pdev) pwm_clk[1] = clk_get(NULL, "pwm23"); clk_enable(pwm_clk[1]); } +#elif defined(CONFIG_ARCH_RK2928) + pwm_clk[0] = clk_get(NULL, "pwm01"); + if (IS_ERR(pwm_clk[0])) { + printk("pwm_clk get error %p\n", pwm_clk[0]); + return -EINVAL; + } + clk_enable(pwm_clk[0]); #endif - - - platform_set_drvdata(pdev, dcdc); + + g_dcdc = dcdc; + platform_set_drvdata(pdev, dcdc); printk(KERN_INFO "pwm_regulator.%d: driver initialized\n",id); return 0; @@ -314,10 +347,73 @@ err: } +static int __sramdata g_PWM_REG_LRC = 0; +static int __sramdata g_PWM_REG_HRC = 0; +void pwm_suspend_voltage(void) +{ + struct rk_pwm_dcdc *dcdc = g_dcdc; + int suspend_voltage = 0; + int pwm_id = 0; + + if(!dcdc) + return; + pwm_id = dcdc->pdata->pwm_id; + suspend_voltage = dcdc->pdata->suspend_voltage; + + g_PWM_REG_LRC = pwm_read_reg(pwm_id, PWM_REG_LRC); + g_PWM_REG_HRC = pwm_read_reg(pwm_id,PWM_REG_HRC); + + switch(suspend_voltage) + { + case 1000000: + pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25); + pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00 + break; + + case 1050000: + pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25); + pwm_write_reg(pwm_id,PWM_REG_HRC,0x1c); // 1 .05 + break; + + case 1100000: + pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25); + pwm_write_reg(pwm_id,PWM_REG_HRC,0x18); // 1 .1 + break; + + case 1150000: + pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25); + pwm_write_reg(pwm_id,PWM_REG_HRC,0x13); // 1 .15 + break; + + default: + pwm_write_reg(pwm_id, PWM_REG_LRC, 0x25); + pwm_write_reg(pwm_id,PWM_REG_HRC,0x20); // 1 .00 + break; + + } + +} + +void pwm_resume_voltage(void) + { + struct rk_pwm_dcdc *dcdc = g_dcdc; + int pwm_id = 0; + + if(!dcdc) + return; + pwm_id = dcdc->pdata->pwm_id; + pwm_write_reg(pwm_id, PWM_REG_LRC, g_PWM_REG_LRC); + pwm_write_reg(pwm_id,PWM_REG_HRC, g_PWM_REG_HRC); + +} + + static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t state) { struct pwm_platform_data *pdata = pdev->dev.platform_data; - pwm_set_rate(pdata,1000*1000,0);//pwm clk will change to 24M after suspend + //struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev); + //unsigned selector = 0; + //pwm_regulator_set_voltage(dcdc->regulator, 1100000, 1100000, &selector); DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id); return 0; } @@ -325,6 +421,9 @@ static int pwm_regulator_suspend(struct platform_device *pdev, pm_message_t stat static int pwm_regulator_resume(struct platform_device *pdev) { struct pwm_platform_data *pdata = pdev->dev.platform_data; + //struct rk_pwm_dcdc *dcdc = platform_get_drvdata(pdev); + //unsigned selector = 0; + //pwm_regulator_set_voltage(dcdc->regulator, 1150000, 1150000, &selector); DBG("%s,pwm_id=%d\n",__func__,pdata->pwm_id); return 0; } @@ -361,7 +460,7 @@ static void __exit pwm_regulator_module_exit(void) } -subsys_initcall(pwm_regulator_module_init); +fs_initcall(pwm_regulator_module_init); module_exit(pwm_regulator_module_exit); diff --git a/include/linux/regulator/rk29-pwm-regulator.h b/include/linux/regulator/rk29-pwm-regulator.h old mode 100644 new mode 100755 index e0a0487d2a85..e74b812f73d3 --- a/include/linux/regulator/rk29-pwm-regulator.h +++ b/include/linux/regulator/rk29-pwm-regulator.h @@ -57,6 +57,11 @@ struct pwm_platform_data { unsigned int pwm_iomux_pwm; int pwm_iomux_gpio; int pwm_voltage; + int suspend_voltage; + int coefficient; + int min_uV; + int max_uV; + int *pwm_voltage_map; struct regulator_init_data *init_data; }; From 43e39f9617ad5a24b8b38ebfe625f8ebbe2ccd1e Mon Sep 17 00:00:00 2001 From: chenxing Date: Wed, 15 Aug 2012 20:05:59 +0800 Subject: [PATCH 2/7] rk2928:sdk: use lowest rate when all div rates are higher then request --- arch/arm/mach-rk2928/clock_data.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/mach-rk2928/clock_data.c b/arch/arm/mach-rk2928/clock_data.c index 8b311cc95776..50eb07b4e6f4 100644 --- a/arch/arm/mach-rk2928/clock_data.c +++ b/arch/arm/mach-rk2928/clock_data.c @@ -62,6 +62,7 @@ struct pll_clk_set { #define CLKDATA_LOG(fmt, args...) do {} while(0) #endif #define CLKDATA_ERR(fmt, args...) printk(KERN_ERR "CLKDATA_ERR:\t"fmt, ##args) +#define CLKDATA_WARNNING(fmt, args...) printk("CLKDATA_WANNING:\t"fmt, ##args) #define cru_readl(offset) readl_relaxed(RK2928_CRU_BASE + offset) #define cru_writel(v, offset) do { writel_relaxed(v, RK2928_CRU_BASE + offset); dsb(); } while (0) @@ -330,6 +331,12 @@ static int clksel_set_rate_freediv(struct clk *clk, unsigned long rate) CLKDATA_DBG("clksel_set_rate_freediv for clock %s to rate %ld (div %d)\n", clk->name, rate, div + 1); return 0; } + if (div == clk->div_max - 1) { + CLKDATA_WARNNING("%s clk=%s, div=%u, rate=%lu, new_rate=%u\n", + __func__, clk->name, div, rate, new_rate); + set_cru_bits_w_msk(div,clk->div_mask,clk->div_shift,clk->clksel_con); + return 0; + } } return -ENOENT; } From 24424b7461bf0713d612fed1bfa8de9dea1be006 Mon Sep 17 00:00:00 2001 From: gwl Date: Wed, 15 Aug 2012 21:08:54 +0800 Subject: [PATCH 3/7] Add wifi reset control (for RK2928) --- arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c b/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c index e74fb1ab7ab0..69be61c317f1 100644 --- a/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c +++ b/arch/arm/mach-rk2928/board-rk2928-sdk-sdmmc.c @@ -203,6 +203,7 @@ static void rk29_sdmmc_set_iomux(int device_id, unsigned int bus_width) #ifdef CONFIG_WIFI_CONTROL_FUNC #define RK30SDK_WIFI_GPIO_POWER_N RK2928_PIN0_PD6 +#define RK29SDK_WIFI_GPIO_RESET_N RK2928_PIN3_PC2 #define PREALLOC_WLAN_SEC_NUM 4 #define PREALLOC_WLAN_BUF_NUM 160 @@ -309,12 +310,12 @@ static int __init rk29sdk_wifi_bt_gpio_control_init(void) return -1; } - /*if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) { + if (gpio_request(RK29SDK_WIFI_GPIO_RESET_N, "wifi reset")) { pr_info("%s: request wifi reset gpio failed\n", __func__); gpio_free(RK30SDK_WIFI_GPIO_POWER_N); return -1; } - + /* if (gpio_request(RK29SDK_BT_GPIO_RESET_N, "bt reset")) { pr_info("%s: request bt reset gpio failed\n", __func__); gpio_free(RK29SDK_WIFI_GPIO_RESET_N); @@ -322,7 +323,7 @@ static int __init rk29sdk_wifi_bt_gpio_control_init(void) }*/ gpio_direction_output(RK30SDK_WIFI_GPIO_POWER_N, GPIO_LOW); - //gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); + gpio_direction_output(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); //gpio_direction_output(RK29SDK_BT_GPIO_RESET_N, GPIO_LOW); #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) @@ -351,12 +352,12 @@ static int rk29sdk_wifi_power(int on) pr_info("%s: %d\n", __func__, on); if (on){ gpio_set_value(RK30SDK_WIFI_GPIO_POWER_N, GPIO_HIGH); - + mdelay(50); #if defined(CONFIG_SDMMC1_RK29) && !defined(CONFIG_SDMMC_RK29_OLD) rk29_sdmmc_gpio_open(1, 1); //added by xbw at 2011-10-13 #endif - //gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH); + gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_HIGH); mdelay(100); pr_info("wifi turn on power\n"); }else{ @@ -373,7 +374,7 @@ static int rk29sdk_wifi_power(int on) // { // pr_info("wifi shouldn't shut off power, bt is using it!\n"); // } - //gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); + gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, GPIO_LOW); } @@ -385,8 +386,8 @@ static int rk29sdk_wifi_reset_state; static int rk29sdk_wifi_reset(int on) { pr_info("%s: %d\n", __func__, on); - //gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, on); - //mdelay(100); + gpio_set_value(RK29SDK_WIFI_GPIO_RESET_N, on); + mdelay(100); rk29sdk_wifi_reset_state = on; return 0; } From bbc68b65d9fbba7bb10cf89644e4d984f536c059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Wed, 15 Aug 2012 10:41:41 +0800 Subject: [PATCH 4/7] i2c: rk: only rk29/rk30 need idle lock --- drivers/i2c/busses/i2c-rk29.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/i2c/busses/i2c-rk29.c b/drivers/i2c/busses/i2c-rk29.c index 69af912074c8..4e5f1e136751 100755 --- a/drivers/i2c/busses/i2c-rk29.c +++ b/drivers/i2c/busses/i2c-rk29.c @@ -111,7 +111,9 @@ struct rk29_i2c_data { #endif }; +#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30) static struct wake_lock idlelock; /* only for i2c0 */ +#endif static void rk29_set_ack(struct rk29_i2c_data *i2c) { @@ -558,8 +560,10 @@ static int rk29_i2c_xfer(struct i2c_adapter *adap, i2c->udelay_time = RK29_UDELAY_TIME(i2c->scl_rate); i2c->ack_timeout = RK29_I2C_ACK_TIMEOUT_COUNT * i2c->udelay_time; +#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30) if (adap->nr == 0) wake_lock(&idlelock); +#endif for (i = 0; i < num; i++) { @@ -572,8 +576,10 @@ static int rk29_i2c_xfer(struct i2c_adapter *adap, } } +#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30) if (adap->nr == 0) wake_unlock(&idlelock); +#endif /* if( --retry && num < 0) @@ -887,7 +893,9 @@ static struct platform_driver rk29_i2c_driver = { static int __init rk29_i2c_adap_init(void) { +#if defined(CONFIG_ARCH_RK29) || defined(CONFIG_ARCH_RK30) wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "i2c0"); +#endif return platform_driver_register(&rk29_i2c_driver); } From 7db28b5ce2007ca5440b4c03561f4493352671b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 09:18:32 +0800 Subject: [PATCH 5/7] rk2928: sram: fix loop use Thumb instruction set --- arch/arm/mach-rk2928/include/mach/sram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-rk2928/include/mach/sram.h b/arch/arm/mach-rk2928/include/mach/sram.h index eba76bccf64d..4dec061dfeca 100644 --- a/arch/arm/mach-rk2928/include/mach/sram.h +++ b/arch/arm/mach-rk2928/include/mach/sram.h @@ -4,7 +4,7 @@ #include #define SRAM_LOOPS_PER_USEC 24 -#define SRAM_LOOP(loops) do { unsigned int i = (loops); if (i < 7) i = 7; barrier(); while (--i) barrier(); } while (0) +#define SRAM_LOOP(loops) do { unsigned int i = (loops); if (i < 7) i = 7; barrier(); asm volatile(".align 4; 1: subs %0, %0, #1; bne 1b;" : "+r" (i)); } while (0) /* delay on slow mode */ #define sram_udelay(usecs) SRAM_LOOP((usecs)*SRAM_LOOPS_PER_USEC) /* delay on deep slow mode */ From c5066ca24849fdb2e6ea4095b276c7567c7291b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 09:43:53 +0800 Subject: [PATCH 6/7] rk2928: add initial pm support --- arch/arm/mach-rk2928/pm.c | 453 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 453 insertions(+) diff --git a/arch/arm/mach-rk2928/pm.c b/arch/arm/mach-rk2928/pm.c index b8bcc0292339..0591da0f482f 100755 --- a/arch/arm/mach-rk2928/pm.c +++ b/arch/arm/mach-rk2928/pm.c @@ -14,13 +14,47 @@ #include #include +#include +#include #include #include #include +#include +#include + +#define cru_readl(offset) readl_relaxed(RK2928_CRU_BASE + offset) +#define cru_writel(v, offset) do { writel_relaxed(v, RK2928_CRU_BASE + offset); dsb(); } while (0) + +#define grf_readl(offset) readl_relaxed(RK2928_GRF_BASE + offset) +#define grf_writel(v, offset) do { writel_relaxed(v, RK2928_GRF_BASE + offset); dsb(); } while (0) + +#define gate_save_soc_clk(val, _save, cons, w_msk) \ + do { \ + (_save) = cru_readl(cons); \ + cru_writel(((~(val) | (_save)) & (w_msk)) | ((w_msk) << 16), cons); \ + } while (0) void __sramfunc sram_printch(char byte) { #ifdef DEBUG_UART_BASE + u32 clk_gate2, clk_gate4, clk_gate8; + + gate_save_soc_clk(0 + | (1 << CLK_GATE_ACLK_PERIPH % 16) + | (1 << CLK_GATE_HCLK_PERIPH % 16) + | (1 << CLK_GATE_PCLK_PERIPH % 16) + , clk_gate2, CRU_CLKGATES_CON(2), 0 + | (1 << ((CLK_GATE_ACLK_PERIPH % 16) + 16)) + | (1 << ((CLK_GATE_HCLK_PERIPH % 16) + 16)) + | (1 << ((CLK_GATE_PCLK_PERIPH % 16) + 16))); + gate_save_soc_clk((1 << CLK_GATE_ACLK_CPU_PERI % 16) + , clk_gate4, CRU_CLKGATES_CON(4), + (1 << ((CLK_GATE_ACLK_CPU_PERI % 16) + 16))); + gate_save_soc_clk((1 << ((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16)), + clk_gate8, CRU_CLKGATES_CON(8), + (1 << (((CLK_GATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART) % 16) + 16))); + sram_udelay(1); + writel_relaxed(byte, DEBUG_UART_BASE); dsb(); @@ -28,8 +62,427 @@ void __sramfunc sram_printch(char byte) while (!(readl_relaxed(DEBUG_UART_BASE + 0x14) & 0x40)) barrier(); + cru_writel(0xffff0000 | clk_gate2, CRU_CLKGATES_CON(2)); + cru_writel(0xffff0000 | clk_gate4, CRU_CLKGATES_CON(4)); + cru_writel(0xffff0000 | clk_gate8, CRU_CLKGATES_CON(8)); + if (byte == '\n') sram_printch('\r'); #endif } +__weak void __sramfunc ddr_suspend(void) {} +__weak void __sramfunc ddr_resume(void) {} +__weak uint32_t __sramfunc ddr_change_freq(uint32_t nMHz) { return nMHz; } + +#ifdef CONFIG_DDR_TEST +static int ddr_debug=0; +module_param(ddr_debug, int, 0644); + +static int inline calc_crc32(u32 addr, size_t len) +{ + return crc32_le(~0, (const unsigned char *)addr, len); +} + +static void ddr_testmode(void) +{ + int32_t g_crc1, g_crc2; + uint32_t nMHz; + uint32_t n = 0; + uint32_t min,max; + extern char _stext[], _etext[]; + + + if (ddr_debug == 1) { + max=500; + min=100; + for (;;) { + sram_printascii("\n change freq:"); + g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext)); + do + { + nMHz = min + random32(); + nMHz %= max; + }while(nMHz < min); + sram_printhex(nMHz); + sram_printch(' '); + nMHz = ddr_change_freq(nMHz); + sram_printhex(n++); + sram_printch(' '); + g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext)); + if (g_crc1!=g_crc2) { + sram_printascii("fail\n"); + } + //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++); + // sram_printascii("change freq success\n"); + } + } else if(ddr_debug == 2) { + for (;;) { + sram_printch(' '); + sram_printch('9'); + sram_printch('9'); + sram_printch('9'); + sram_printch(' '); + g_crc1 = calc_crc32((u32)_stext, (size_t)(_etext-_stext)); + nMHz = (random32()>>13);// 16.7s max + ddr_suspend(); + sram_udelay(nMHz); + ddr_resume(); + sram_printhex(nMHz); + sram_printch(' '); + sram_printhex(n++); + g_crc2 = calc_crc32((u32)_stext, (size_t)(_etext-_stext)); + if (g_crc1 != g_crc2) { + sram_printch(' '); + sram_printch('f'); + sram_printch('a'); + sram_printch('i'); + sram_printch('l'); + } + // ddr_print("check image crc32 fail!, count:%d\n", n++); + // sram_printascii("self refresh fail\n"); + //else + //ddr_print("check image crc32 success--crc value = 0x%x!, count:%d\n",g_crc1, n++); + // sram_printascii("self refresh success\n"); + } + } else if (ddr_debug == 3) { + extern int memtester(void); + memtester(); + } + else + { + ddr_change_freq(ddr_debug); + ddr_debug=0; + } +} +#else +static void ddr_testmode(void) {} +#endif + +static noinline void rk2928_pm_dump_irq(void) +{ + u32 irq_gpio = (readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + (IRQ_GPIO0 / 32) * 4) >> (IRQ_GPIO0 % 32)) & 0xF; + printk("wakeup irq: %08x %08x %08x\n", + readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 4), + readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 8), + readl_relaxed(RK2928_GICD_BASE + GIC_DIST_PENDING_SET + 12)); + if (irq_gpio & 1) + printk("wakeup gpio0: %08x\n", readl_relaxed(RK2928_GPIO0_BASE + GPIO_INT_STATUS)); + if (irq_gpio & 2) + printk("wakeup gpio1: %08x\n", readl_relaxed(RK2928_GPIO1_BASE + GPIO_INT_STATUS)); + if (irq_gpio & 4) + printk("wakeup gpio2: %08x\n", readl_relaxed(RK2928_GPIO2_BASE + GPIO_INT_STATUS)); + if (irq_gpio & 8) + printk("wakeup gpio3: %08x\n", readl_relaxed(RK2928_GPIO3_BASE + GPIO_INT_STATUS)); +} + +#define DUMP_GPIO_INTEN(ID) \ +do { \ + u32 en = readl_relaxed(RK2928_GPIO##ID##_BASE + GPIO_INTEN); \ + if (en) { \ + sram_printascii("GPIO" #ID "_INTEN: "); \ + sram_printhex(en); \ + sram_printch('\n'); \ + } \ +} while (0) + +static noinline void rk2928_pm_dump_inten(void) +{ + DUMP_GPIO_INTEN(0); + DUMP_GPIO_INTEN(1); + DUMP_GPIO_INTEN(2); + DUMP_GPIO_INTEN(3); +} + +static void pm_pll_wait_lock(int pll_idx) +{ + u32 pll_state[4] = { 1, 0, 2, 3 }; + u32 bit = 0x10u << pll_state[pll_idx]; + u32 delay = pll_idx == APLL_ID ? 24000000U : 2400000000U; + while (delay > 0) { + if (grf_readl(GRF_SOC_STATUS0) & bit) + break; + delay--; + } + if (delay == 0) { + //CRU_PRINTK_ERR("wait pll bit 0x%x time out!\n", bit); + sram_printch('p'); + sram_printch('l'); + sram_printch('l'); + sram_printhex(pll_idx); + sram_printch('\n'); + } +} + +#define power_on_pll(id) \ + cru_writel(PLL_PWR_DN_W_MSK|PLL_PWR_ON,PLL_CONS((id),3));\ + pm_pll_wait_lock((id)) + +#define DDR_SAVE_SP(save_sp) do { save_sp = ddr_save_sp(((unsigned long)SRAM_DATA_END & (~7))); } while (0) +#define DDR_RESTORE_SP(save_sp) do { ddr_save_sp(save_sp); } while (0) + +static unsigned long save_sp; + +static noinline void interface_ctr_reg_pread(void) +{ + u32 addr; + + flush_cache_all(); + outer_flush_all(); + local_flush_tlb_all(); + + for (addr = (u32)SRAM_CODE_OFFSET; addr < (u32)SRAM_DATA_END; addr += PAGE_SIZE) + readl_relaxed(addr); + readl_relaxed(RK2928_GRF_BASE); + readl_relaxed(RK2928_DDR_PCTL_BASE); + readl_relaxed(RK2928_DDR_PHY_BASE); +// readl_relaxed(RK2928_I2C1_BASE); +} + +__weak void board_gpio_suspend(void) {} +__weak void board_gpio_resume(void) {} +__weak void __sramfunc board_pmu_suspend(void) {} +__weak void __sramfunc board_pmu_resume(void) {} +__weak void __sramfunc rk30_suspend_voltage_set(unsigned int vol) {} +__weak void __sramfunc rk30_suspend_voltage_resume(unsigned int vol) {} + +__weak void rk30_pwm_suspend_voltage_set(void) {} +__weak void rk30_pwm_resume_voltage_set(void) {} + +__weak void __sramfunc rk30_pwm_logic_suspend_voltage(void) {} +__weak void __sramfunc rk30_pwm_logic_resume_voltage(void) {} + +static void __sramfunc rk2928_sram_suspend(void) +{ + u32 cru_clksel0_con; + u32 clkgt_regs[CRU_CLKGATES_CON_CNT]; + int i; + + sram_printch('5'); + ddr_suspend(); + sram_printch('6'); + rk30_suspend_voltage_set(1000000); + rk30_pwm_logic_suspend_voltage(); + sram_printch('7'); + + for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) { + clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i)); + } + gate_save_soc_clk(0 + | (1 << CLK_GATE_CORE_PERIPH) + | (1 << CLK_GATE_DDRPHY_SRC) + | (1 << CLK_GATE_ACLK_CPU) + | (1 << CLK_GATE_HCLK_CPU) + | (1 << CLK_GATE_PCLK_CPU) + | (1 << CLK_GATE_ACLK_CORE) + , clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff); + if (!(clkgt_regs[8] & (0xf << (CLK_GATE_PCLK_GPIO0 % 16)))) { + gate_save_soc_clk(0 + | (1 << CLK_GATE_PERIPH_SRC % 16) + | (1 << CLK_GATE_PCLK_PERIPH % 16) + , clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff); + } else { + gate_save_soc_clk(0, clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff); + } + gate_save_soc_clk(0 + | (1 << CLK_GATE_ACLK_STRC_SYS % 16) + | (1 << CLK_GATE_ACLK_INTMEM % 16) + , clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff); + gate_save_soc_clk(0 + | (1 << CLK_GATE_PCLK_GRF % 16) + | (1 << CLK_GATE_PCLK_DDRUPCTL % 16) + , clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff); + gate_save_soc_clk(0, clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff); + gate_save_soc_clk(0 + | (1 << CLK_GATE_CLK_L2C % 16) + , clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff); + + board_pmu_suspend(); + cru_clksel0_con = cru_readl(CRU_CLKSELS_CON(0)); + cru_writel((0x1f << 16) | 0x1f, CRU_CLKSELS_CON(0)); + + dsb(); + wfi(); + + cru_writel((0x1f << 16) | cru_clksel0_con, CRU_CLKSELS_CON(0)); + board_pmu_resume(); + + for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) { + cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i)); + } + + sram_printch('7'); + rk30_pwm_logic_resume_voltage(); + rk30_suspend_voltage_resume(1100000); + + sram_printch('6'); + ddr_resume(); + sram_printch('5'); +} + +static void noinline rk2928_suspend(void) +{ + DDR_SAVE_SP(save_sp); + rk2928_sram_suspend(); + DDR_RESTORE_SP(save_sp); +} + +static int rk2928_pm_enter(suspend_state_t state) +{ + u32 i; + u32 clkgt_regs[CRU_CLKGATES_CON_CNT]; + u32 clk_sel0, clk_sel1, clk_sel10; + u32 cru_mode_con; + + // dump GPIO INTEN for debug + rk2928_pm_dump_inten(); + + sram_printch('0'); + +#ifdef CONFIG_DDR_TEST + // memory tester + if (ddr_debug != 0) + ddr_testmode(); +#endif + + sram_printch('1'); + local_fiq_disable(); + + for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) { + clkgt_regs[i] = cru_readl(CRU_CLKGATES_CON(i)); + } + + gate_save_soc_clk(0 + | (1 << CLK_GATE_CORE_PERIPH) + | (1 << CLK_GATE_DDRPHY_SRC) + | (1 << CLK_GATE_ACLK_CPU) + | (1 << CLK_GATE_HCLK_CPU) + | (1 << CLK_GATE_PCLK_CPU) + | (1 << CLK_GATE_ACLK_CORE) + , clkgt_regs[0], CRU_CLKGATES_CON(0), 0xffff); + gate_save_soc_clk(0, clkgt_regs[1], CRU_CLKGATES_CON(1), 0xffff); + gate_save_soc_clk(0 + | (1 << CLK_GATE_PERIPH_SRC % 16) + | (1 << CLK_GATE_PCLK_PERIPH % 16) + | (1 << CLK_GATE_ACLK_PERIPH % 16) + , clkgt_regs[2], CRU_CLKGATES_CON(2), 0xffff); + gate_save_soc_clk(0, clkgt_regs[3], CRU_CLKGATES_CON(3), 0xff9f); + gate_save_soc_clk(0 + | (1 << CLK_GATE_HCLK_PERI_AXI_MATRIX % 16) + | (1 << CLK_GATE_PCLK_PERI_AXI_MATRIX % 16) + | (1 << CLK_GATE_ACLK_CPU_PERI % 16) + | (1 << CLK_GATE_ACLK_PERI_AXI_MATRIX % 16) + | (1 << CLK_GATE_ACLK_STRC_SYS % 16) + | (1 << CLK_GATE_ACLK_INTMEM % 16) + , clkgt_regs[4], CRU_CLKGATES_CON(4), 0xffff); + gate_save_soc_clk(0 + | (1 << CLK_GATE_PCLK_GRF % 16) + | (1 << CLK_GATE_PCLK_DDRUPCTL % 16) + , clkgt_regs[5], CRU_CLKGATES_CON(5), 0xffff); + gate_save_soc_clk(0, clkgt_regs[6], CRU_CLKGATES_CON(6), 0xffff); + gate_save_soc_clk(0 + |(1 << CLK_GATE_PCLK_PWM01%16) + , clkgt_regs[7], CRU_CLKGATES_CON(7), 0xffff); + gate_save_soc_clk(0, clkgt_regs[8], CRU_CLKGATES_CON(8), 0x01ff); + gate_save_soc_clk(0 + | (1 << CLK_GATE_CLK_L2C % 16) + | (1 << CLK_GATE_HCLK_PERI_ARBI % 16) + | (1 << CLK_GATE_ACLK_PERI_NIU % 16) + , clkgt_regs[9], CRU_CLKGATES_CON(9), 0x07ff); + + sram_printch('2'); + + cru_mode_con = cru_readl(CRU_MODE_CON); + + //cpll + cru_writel(PLL_MODE_SLOW(CPLL_ID), CRU_MODE_CON); + + //gpll + clk_sel10 = cru_readl(CRU_CLKSELS_CON(10)); + cru_writel(PLL_MODE_SLOW(GPLL_ID), CRU_MODE_CON); + cru_writel(PERI_SET_ACLK_DIV(1) + | PERI_SET_A2H_RATIO(RATIO_11) + | PERI_SET_A2P_RATIO(RATIO_11) + , CRU_CLKSELS_CON(10)); + + //apll + clk_sel0 = cru_readl(CRU_CLKSELS_CON(0)); + clk_sel1 = cru_readl(CRU_CLKSELS_CON(1)); + cru_writel(PLL_MODE_SLOW(APLL_ID), CRU_MODE_CON); + cru_writel(CLK_CORE_DIV(1) | ACLK_CPU_DIV(1), CRU_CLKSELS_CON(0)); + cru_writel(CLK_CORE_PERI_DIV(1) | ACLK_CORE_DIV(1) | HCLK_CPU_DIV(1) | PCLK_CPU_DIV(1), CRU_CLKSELS_CON(1)); + + sram_printch('3'); + rk30_pwm_suspend_voltage_set(); + + board_gpio_suspend(); + + interface_ctr_reg_pread(); + + sram_printch('4'); + rk2928_suspend(); + sram_printch('4'); + + board_gpio_resume(); + rk30_pwm_resume_voltage_set(); + sram_printch('3'); + + //apll + cru_writel(0xffff0000 | clk_sel1, CRU_CLKSELS_CON(1)); + cru_writel(0xffff0000 | clk_sel0, CRU_CLKSELS_CON(0)); + cru_writel((PLL_MODE_MSK(APLL_ID) << 16) | (PLL_MODE_MSK(APLL_ID) & cru_mode_con), CRU_MODE_CON); + + //gpll + cru_writel(0xffff0000 | clk_sel10, CRU_CLKSELS_CON(10)); + cru_writel(clk_sel10, CRU_CLKSELS_CON(10)); + cru_writel((PLL_MODE_MSK(GPLL_ID) << 16) | (PLL_MODE_MSK(GPLL_ID) & cru_mode_con), CRU_MODE_CON); + + //cpll + cru_writel((PLL_MODE_MSK(CPLL_ID) << 16) | (PLL_MODE_MSK(CPLL_ID) & cru_mode_con), CRU_MODE_CON); + + sram_printch('2'); + + for (i = 0; i < CRU_CLKGATES_CON_CNT; i++) { + cru_writel(clkgt_regs[i] | 0xffff0000, CRU_CLKGATES_CON(i)); + } + + local_fiq_enable(); + sram_printch('1'); + + sram_printascii("0\n"); + + rk2928_pm_dump_irq(); + + return 0; +} + +static int rk2928_pm_prepare(void) +{ + /* disable entering idle by disable_hlt() */ + disable_hlt(); + return 0; +} + +static void rk2928_pm_finish(void) +{ + enable_hlt(); +} + +static struct platform_suspend_ops rk2928_pm_ops = { + .enter = rk2928_pm_enter, + .valid = suspend_valid_only_mem, + .prepare = rk2928_pm_prepare, + .finish = rk2928_pm_finish, +}; + +static int __init rk2928_pm_init(void) +{ + suspend_set_ops(&rk2928_pm_ops); + +#ifdef CONFIG_EARLYSUSPEND + pm_set_vt_switch(0); /* disable vt switch while suspend */ +#endif + + return 0; +} +__initcall(rk2928_pm_init); From 278d2a1ab231c04241452583bf3f55bc45202aac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=B6=9B?= Date: Thu, 16 Aug 2012 11:51:17 +0800 Subject: [PATCH 7/7] gpio: rk2928: enable support rk30_gpiolib_pull_updown --- drivers/gpio/gpio-rk30.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-rk30.c b/drivers/gpio/gpio-rk30.c index 14417a33a4a9..911636cf49c1 100755 --- a/drivers/gpio/gpio-rk30.c +++ b/drivers/gpio/gpio-rk30.c @@ -318,10 +318,9 @@ static void rk30_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val) spin_unlock_irqrestore(&bank->lock, flags); } - static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, unsigned enable) { -#if defined(CONFIG_ARCH_RK30) +#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928) struct rk30_gpio_bank *bank = to_rk30_gpio_bank(chip); unsigned long flags; @@ -335,7 +334,6 @@ static int rk30_gpiolib_pull_updown(struct gpio_chip *chip, unsigned offset, uns return 0; } - static int rk30_gpiolib_to_irq(struct gpio_chip *chip, unsigned offset) { return chip->base + offset;