drivers/video/msm: update to new kernel
[safe/jmp/linux-2.6] / drivers / video / sa1100fb.c
index 2d29db7..cdaa873 100644 (file)
@@ -66,7 +66,7 @@
  *     - FrameBuffer memory is now allocated at run-time when the
  *       driver is initialized.    
  *
- * 2000/04/10: Nicolas Pitre <nico@cam.org>
+ * 2000/04/10: Nicolas Pitre <nico@fluxnic.net>
  *     - Big cleanup for dynamic selection of machine type at run time.
  *
  * 2000/07/19: Jamey Hicks <jamey@crl.dec.com>
  *     - convert dma address types to dma_addr_t
  *     - remove unused 'montype' stuff
  *     - remove redundant zero inits of init_var after the initial
- *       memzero.
+ *       memset.
  *     - remove allow_modeset (acornfb idea does not belong here)
  *
  * 2001/05/28: <rmk@arm.linux.org.uk>
  *     - Add patch 681/1 and clean up stork definitions.
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/cpufreq.h>
-#include <linux/device.h>
+#include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
 
-#include <asm/hardware.h>
-#include <asm/io.h>
-#include <asm/irq.h>
+#include <mach/hardware.h>
 #include <asm/mach-types.h>
-#include <asm/uaccess.h>
-#include <asm/arch/assabet.h>
-#include <asm/arch/shannon.h>
+#include <mach/assabet.h>
+#include <mach/shannon.h>
 
 /*
  * debugging?
 extern void (*sa1100fb_backlight_power)(int on);
 extern void (*sa1100fb_lcd_power)(int on);
 
-/*
- * IMHO this looks wrong.  In 8BPP, length should be 8.
- */
-static struct sa1100fb_rgb rgb_8 = {
+static struct sa1100fb_rgb rgb_4 = {
        .red    = { .offset = 0,  .length = 4, },
        .green  = { .offset = 0,  .length = 4, },
        .blue   = { .offset = 0,  .length = 4, },
        .transp = { .offset = 0,  .length = 0, },
 };
 
+static struct sa1100fb_rgb rgb_8 = {
+       .red    = { .offset = 0,  .length = 8, },
+       .green  = { .offset = 0,  .length = 8, },
+       .blue   = { .offset = 0,  .length = 8, },
+       .transp = { .offset = 0,  .length = 0, },
+};
+
 static struct sa1100fb_rgb def_rgb_16 = {
        .red    = { .offset = 11, .length = 5, },
        .green  = { .offset = 5,  .length = 6, },
@@ -252,22 +255,6 @@ static struct sa1100fb_mach_info pal_info __initdata = {
 #endif
 #endif
 
-#ifdef CONFIG_SA1100_H3800
-static struct sa1100fb_mach_info h3800_info __initdata = {
-       .pixclock       = 174757,       .bpp            = 16,
-       .xres           = 320,          .yres           = 240,
-
-       .hsync_len      = 3,            .vsync_len      = 3,
-       .left_margin    = 12,           .upper_margin   = 10,
-       .right_margin   = 17,           .lower_margin   = 1,
-
-       .cmap_static    = 1,
-
-       .lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-       .lccr3          = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-};
-#endif
-
 #ifdef CONFIG_SA1100_H3600
 static struct sa1100fb_mach_info h3600_info __initdata = {
        .pixclock       = 174757,       .bpp            = 16,
@@ -433,11 +420,6 @@ sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
                fbi->rgb[RGB_16] = &h3600_rgb_16;
        }
 #endif
-#ifdef CONFIG_SA1100_H3800
-       if (machine_is_h3800()) {
-               inf = &h3800_info;
-       }
-#endif
 #ifdef CONFIG_SA1100_COLLIE
        if (machine_is_collie()) {
                inf = &collie_info;
@@ -592,13 +574,14 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
        return ret;
 }
 
+#ifdef CONFIG_CPU_FREQ
 /*
  *  sa1100fb_display_dma_period()
  *    Calculate the minimum period (in picoseconds) between two DMA
  *    requests for the LCD controller.  If we hit this, it means we're
  *    doing nothing but LCD DMA.
  */
-static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
+static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
 {
        /*
         * Period = pixclock * bits_per_byte * bytes_per_transfer
@@ -606,6 +589,7 @@ static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var)
         */
        return var->pixclock * 8 * 16 / var->bits_per_pixel;
 }
+#endif
 
 /*
  *  sa1100fb_check_var():
@@ -633,7 +617,7 @@ sa1100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
        DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
        switch (var->bits_per_pixel) {
        case 4:
-               rgbidx = RGB_8;
+               rgbidx = RGB_4;
                break;
        case 8:
                rgbidx = RGB_8;
@@ -814,7 +798,7 @@ static int sa1100fb_blank(int blank, struct fb_info *info)
        return 0;
 }
 
-static int sa1100fb_mmap(struct fb_info *info, struct file *file,
+static int sa1100fb_mmap(struct fb_info *info,
                         struct vm_area_struct *vma)
 {
        struct sa1100fb_info *fbi = (struct sa1100fb_info *)info;
@@ -851,7 +835,6 @@ static struct fb_ops sa1100fb_ops = {
        .fb_copyarea    = cfb_copyarea,
        .fb_imageblit   = cfb_imageblit,
        .fb_blank       = sa1100fb_blank,
-       .fb_cursor      = soft_cursor,
        .fb_mmap        = sa1100fb_mmap,
 };
 
@@ -1086,7 +1069,7 @@ static void sa1100fb_disable_controller(struct sa1100fb_info *fbi)
 /*
  *  sa1100fb_handle_irq: Handle 'LCD DONE' interrupts.
  */
-static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t sa1100fb_handle_irq(int irq, void *dev_id)
 {
        struct sa1100fb_info *fbi = dev_id;
        unsigned int lcsr = LCSR;
@@ -1109,7 +1092,7 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
 {
        u_int old_state;
 
-       down(&fbi->ctrlr_sem);
+       mutex_lock(&fbi->ctrlr_lock);
 
        old_state = fbi->state;
 
@@ -1194,16 +1177,16 @@ static void set_ctrlr_state(struct sa1100fb_info *fbi, u_int state)
                }
                break;
        }
-       up(&fbi->ctrlr_sem);
+       mutex_unlock(&fbi->ctrlr_lock);
 }
 
 /*
  * Our LCD controller task (which is called when we blank or unblank)
  * via keventd.
  */
-static void sa1100fb_task(void *dummy)
+static void sa1100fb_task(struct work_struct *w)
 {
-       struct sa1100fb_info *fbi = dummy;
+       struct sa1100fb_info *fbi = container_of(w, struct sa1100fb_info, task);
        u_int state = xchg(&fbi->task_state, -1);
 
        set_ctrlr_state(fbi, state);
@@ -1307,21 +1290,19 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
  * Power management hooks.  Note that we won't be called from IRQ context,
  * unlike the blank functions above, so we may sleep.
  */
-static int sa1100fb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1100fb_suspend(struct platform_device *dev, pm_message_t state)
 {
-       struct sa1100fb_info *fbi = dev_get_drvdata(dev);
+       struct sa1100fb_info *fbi = platform_get_drvdata(dev);
 
-       if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
-               set_ctrlr_state(fbi, C_DISABLE_PM);
+       set_ctrlr_state(fbi, C_DISABLE_PM);
        return 0;
 }
 
-static int sa1100fb_resume(struct device *dev, u32 level)
+static int sa1100fb_resume(struct platform_device *dev)
 {
-       struct sa1100fb_info *fbi = dev_get_drvdata(dev);
+       struct sa1100fb_info *fbi = platform_get_drvdata(dev);
 
-       if (level == RESUME_ENABLE)
-               set_ctrlr_state(fbi, C_ENABLE_PM);
+       set_ctrlr_state(fbi, C_ENABLE_PM);
        return 0;
 }
 #else
@@ -1405,6 +1386,7 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
        fbi->fb.monspecs        = monspecs;
        fbi->fb.pseudo_palette  = (fbi + 1);
 
+       fbi->rgb[RGB_4]         = &rgb_4;
        fbi->rgb[RGB_8]         = &rgb_8;
        fbi->rgb[RGB_16]        = &def_rgb_16;
 
@@ -1447,21 +1429,25 @@ static struct sa1100fb_info * __init sa1100fb_init_fbinfo(struct device *dev)
                                          fbi->max_bpp / 8;
 
        init_waitqueue_head(&fbi->ctrlr_wait);
-       INIT_WORK(&fbi->task, sa1100fb_task, fbi);
-       init_MUTEX(&fbi->ctrlr_sem);
+       INIT_WORK(&fbi->task, sa1100fb_task);
+       mutex_init(&fbi->ctrlr_lock);
 
        return fbi;
 }
 
-static int __init sa1100fb_probe(struct device *dev)
+static int __init sa1100fb_probe(struct platform_device *pdev)
 {
        struct sa1100fb_info *fbi;
-       int ret;
+       int ret, irq;
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return -EINVAL;
 
        if (!request_mem_region(0xb0100000, 0x10000, "LCD"))
                return -EBUSY;
 
-       fbi = sa1100fb_init_fbinfo(dev);
+       fbi = sa1100fb_init_fbinfo(&pdev->dev);
        ret = -ENOMEM;
        if (!fbi)
                goto failed;
@@ -1471,7 +1457,7 @@ static int __init sa1100fb_probe(struct device *dev)
        if (ret)
                goto failed;
 
-       ret = request_irq(IRQ_LCD, sa1100fb_handle_irq, SA_INTERRUPT,
+       ret = request_irq(irq, sa1100fb_handle_irq, IRQF_DISABLED,
                          "LCD", fbi);
        if (ret) {
                printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
@@ -1489,11 +1475,11 @@ static int __init sa1100fb_probe(struct device *dev)
         */
        sa1100fb_check_var(&fbi->fb.var, &fbi->fb);
 
-       dev_set_drvdata(dev, fbi);
+       platform_set_drvdata(pdev, fbi);
 
        ret = register_framebuffer(&fbi->fb);
        if (ret < 0)
-               goto failed;
+               goto err_free_irq;
 
 #ifdef CONFIG_CPU_FREQ
        fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
@@ -1505,19 +1491,22 @@ static int __init sa1100fb_probe(struct device *dev)
        /* This driver cannot be unloaded at the moment */
        return 0;
 
-failed:
-       dev_set_drvdata(dev, NULL);
+ err_free_irq:
+       free_irq(irq, fbi);
+ failed:
+       platform_set_drvdata(pdev, NULL);
        kfree(fbi);
        release_mem_region(0xb0100000, 0x10000);
        return ret;
 }
 
-static struct device_driver sa1100fb_driver = {
-       .name           = "sa11x0-fb",
-       .bus            = &platform_bus_type,
+static struct platform_driver sa1100fb_driver = {
        .probe          = sa1100fb_probe,
        .suspend        = sa1100fb_suspend,
        .resume         = sa1100fb_resume,
+       .driver         = {
+               .name   = "sa11x0-fb",
+       },
 };
 
 int __init sa1100fb_init(void)
@@ -1525,7 +1514,7 @@ int __init sa1100fb_init(void)
        if (fb_get_options("sa1100fb", NULL))
                return -ENODEV;
 
-       return driver_register(&sa1100fb_driver);
+       return platform_driver_register(&sa1100fb_driver);
 }
 
 int __init sa1100fb_setup(char *options)