diff options
-rw-r--r-- | drivers/video/da8xx-fb.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index fe0025213a8..8966274bbbb 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -28,6 +28,7 @@ #include <linux/uaccess.h> #include <linux/interrupt.h> #include <linux/clk.h> +#include <linux/cpufreq.h> #include <video/da8xx-fb.h> #define DRIVER_NAME "da8xx_lcdc" @@ -114,6 +115,9 @@ struct da8xx_fb_par { unsigned int databuf_sz; unsigned int palette_sz; unsigned int pxl_clk; +#ifdef CONFIG_CPU_FREQ + struct notifier_block freq_transition; +#endif }; /* Variable Screen Information */ @@ -586,6 +590,41 @@ static int fb_check_var(struct fb_var_screeninfo *var, return err; } +#ifdef CONFIG_CPU_FREQ +static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, + unsigned long val, void *data) +{ + struct da8xx_fb_par *par; + unsigned int reg; + + par = container_of(nb, struct da8xx_fb_par, freq_transition); + if (val == CPUFREQ_PRECHANGE) { + reg = lcdc_read(LCD_RASTER_CTRL_REG); + lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); + } else if (val == CPUFREQ_POSTCHANGE) { + lcd_calc_clk_divider(par); + reg = lcdc_read(LCD_RASTER_CTRL_REG); + lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); + } + + return 0; +} + +static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) +{ + par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition; + + return cpufreq_register_notifier(&par->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +} + +static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par) +{ + cpufreq_unregister_notifier(&par->freq_transition, + CPUFREQ_TRANSITION_NOTIFIER); +} +#endif + static int __devexit fb_remove(struct platform_device *dev) { struct fb_info *info = dev_get_drvdata(&dev->dev); @@ -593,6 +632,9 @@ static int __devexit fb_remove(struct platform_device *dev) if (info) { struct da8xx_fb_par *par = info->par; +#ifdef CONFIG_CPU_FREQ + lcd_da8xx_cpufreq_deregister(par); +#endif if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE) lcd_disable_raster(par); lcdc_write(0, LCD_RASTER_CTRL_REG); @@ -826,12 +868,25 @@ static int __init fb_probe(struct platform_device *device) goto err_dealloc_cmap; } +#ifdef CONFIG_CPU_FREQ + ret = lcd_da8xx_cpufreq_register(par); + if (ret) { + dev_err(&device->dev, "failed to register cpufreq\n"); + goto err_cpu_freq; + } +#endif + /* enable raster engine */ lcdc_write(lcdc_read(LCD_RASTER_CTRL_REG) | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); return 0; +#ifdef CONFIG_CPU_FREQ +err_cpu_freq: + unregister_framebuffer(da8xx_fb_info); +#endif + err_dealloc_cmap: fb_dealloc_cmap(&da8xx_fb_info->cmap); |