[PATCH] md: support stripe/offset mode in raid10
[powerpc.git] / drivers / video / au1100fb.c
index 2406899..d63c3f4 100644 (file)
@@ -7,6 +7,8 @@
  *     Karl Lessard <klessard@sunrisetelecom.com>
  *     <c.pellegrin@exadron.com>
  *
+ * PM support added by Rodolfo Giometti <giometti@linux.it>
+ *
  * Copyright 2002 MontaVista Software
  * Author: MontaVista Software, Inc.
  *             ppopov@mvista.com or source@mvista.com
@@ -49,6 +51,7 @@
 #include <linux/interrupt.h>
 #include <linux/ctype.h>
 #include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
 
 #include <asm/mach-au1x00/au1000.h>
 
@@ -213,10 +216,13 @@ int au1100fb_setmode(struct au1100fb_device *fbdev)
  */
 int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi)
 {
-       struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
-       u32 *palette = fbdev->regs->lcd_pallettebase;
+       struct au1100fb_device *fbdev;
+       u32 *palette;
        u32 value;
 
+       fbdev = to_au1100fb_device(fbi);
+       palette = fbdev->regs->lcd_pallettebase;
+
        if (regno > (AU1100_LCD_NBR_PALETTE_ENTRIES - 1))
                return -EINVAL;
 
@@ -315,9 +321,11 @@ int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi)
  */
 int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi)
 {
-       struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+       struct au1100fb_device *fbdev;
        int dy;
 
+       fbdev = to_au1100fb_device(fbi);
+
        print_dbg("fb_pan_display %p %p", var, fbi);
 
        if (!var || !fbdev) {
@@ -381,10 +389,12 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle)
  */
 int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 {
-       struct au1100fb_device *fbdev = to_au1100fb_device(fbi);
+       struct au1100fb_device *fbdev;
        unsigned int len;
        unsigned long start=0, off;
 
+       fbdev = to_au1100fb_device(fbi);
+
        if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
                return -EINVAL;
        }
@@ -406,7 +416,7 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
 
        vma->vm_flags |= VM_IO;
 
-       if (io_remap_page_range(vma, vma->vm_start, off,
+       if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
                                vma->vm_end - vma->vm_start,
                                vma->vm_page_prot)) {
                return -EAGAIN;
@@ -466,7 +476,7 @@ int au1100fb_drv_probe(struct device *dev)
 
        if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len,
                                DRIVER_NAME)) {
-               print_err("fail to lock memory region at 0x%08x",
+               print_err("fail to lock memory region at 0x%08lx",
                                au1100fb_fix.mmio_start);
                return -EBUSY;
        }
@@ -594,17 +604,52 @@ int au1100fb_drv_remove(struct device *dev)
        return 0;
 }
 
-int au1100fb_drv_suspend(struct device *dev, u32 state, u32 level)
+#ifdef CONFIG_PM
+static u32 sys_clksrc;
+static struct au1100fb_regs fbregs;
+
+int au1100fb_drv_suspend(struct device *dev, pm_message_t state)
 {
-       /* TODO */
+       struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+
+       if (!fbdev)
+               return 0;
+
+       /* Save the clock source state */
+       sys_clksrc = au_readl(SYS_CLKSRC);
+
+       /* Blank the LCD */
+       au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info);
+
+       /* Stop LCD clocking */
+       au_writel(sys_clksrc & ~SYS_CS_ML_MASK, SYS_CLKSRC);
+
+       memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs));
+
        return 0;
 }
 
-int au1100fb_drv_resume(struct device *dev, u32 level)
+int au1100fb_drv_resume(struct device *dev)
 {
-       /* TODO */
+       struct au1100fb_device *fbdev = dev_get_drvdata(dev);
+
+       if (!fbdev)
+               return 0;
+
+       memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs));
+
+       /* Restart LCD clocking */
+       au_writel(sys_clksrc, SYS_CLKSRC);
+
+       /* Unblank the LCD */
+       au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info);
+
        return 0;
 }
+#else
+#define au1100fb_drv_suspend NULL
+#define au1100fb_drv_resume NULL
+#endif
 
 static struct device_driver au1100fb_driver = {
        .name           = "au1100-lcd",