fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / arm / mach-integrator / impd1.c
index 0859557..92d79fb 100644 (file)
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/clcd.h>
 
 #include <asm/io.h>
 #include <asm/hardware/icst525.h>
-#include <asm/hardware/amba.h>
-#include <asm/hardware/amba_clcd.h>
 #include <asm/arch/lm.h>
 #include <asm/arch/impd1.h>
 #include <asm/sizes.h>
@@ -34,7 +35,7 @@ module_param_named(lmid, module_id, int, 0444);
 MODULE_PARM_DESC(lmid, "logic module stack position");
 
 struct impd1_module {
-       void            *base;
+       void __iomem    *base;
        struct clk      vcos[2];
 };
 
@@ -66,7 +67,7 @@ static void impd1_setvco(struct clk *clk, struct icst525_vco vco)
        }
        writel(0, impd1->base + IMPD1_LOCK);
 
-#if DEBUG
+#ifdef DEBUG
        vco.v = val & 0x1ff;
        vco.r = (val >> 9) & 0x7f;
        vco.s = (val >> 16) & 7;
@@ -259,6 +260,17 @@ static int impd1fb_clcd_setup(struct clcd_fb *fb)
        return ret;
 }
 
+static int impd1fb_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
+{
+       unsigned long start, size;
+
+       start = vma->vm_pgoff + (fb->fb.fix.smem_start >> PAGE_SHIFT);
+       size = vma->vm_end - vma->vm_start;
+
+       return remap_pfn_range(vma, vma->vm_start, start, size,
+                              vma->vm_page_prot);
+}
+
 static void impd1fb_clcd_remove(struct clcd_fb *fb)
 {
        iounmap(fb->fb.screen_base);
@@ -272,6 +284,7 @@ static struct clcd_board impd1_clcd_data = {
        .disable        = impd1fb_clcd_disable,
        .enable         = impd1fb_clcd_enable,
        .setup          = impd1fb_clcd_setup,
+       .mmap           = impd1fb_clcd_mmap,
        .remove         = impd1fb_clcd_remove,
 };
 
@@ -342,12 +355,11 @@ static int impd1_probe(struct lm_device *dev)
        if (!request_mem_region(dev->resource.start, SZ_4K, "LM registers"))
                return -EBUSY;
 
-       impd1 = kmalloc(sizeof(struct impd1_module), GFP_KERNEL);
+       impd1 = kzalloc(sizeof(struct impd1_module), GFP_KERNEL);
        if (!impd1) {
                ret = -ENOMEM;
                goto release_lm;
        }
-       memset(impd1, 0, sizeof(struct impd1_module));
 
        impd1->base = ioremap(dev->resource.start, SZ_4K);
        if (!impd1->base) {
@@ -376,12 +388,10 @@ static int impd1_probe(struct lm_device *dev)
 
                pc_base = dev->resource.start + idev->offset;
 
-               d = kmalloc(sizeof(struct amba_device), GFP_KERNEL);
+               d = kzalloc(sizeof(struct amba_device), GFP_KERNEL);
                if (!d)
                        continue;
 
-               memset(d, 0, sizeof(struct amba_device));
-
                snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
                         "lm%x:%5.5lx", dev->id, idev->offset >> 12);
 
@@ -407,24 +417,24 @@ static int impd1_probe(struct lm_device *dev)
  free_impd1:
        if (impd1 && impd1->base)
                iounmap(impd1->base);
-       if (impd1)
-               kfree(impd1);
+       kfree(impd1);
  release_lm:
        release_mem_region(dev->resource.start, SZ_4K);
        return ret;
 }
 
+static int impd1_remove_one(struct device *dev, void *data)
+{
+       device_unregister(dev);
+       return 0;
+}
+
 static void impd1_remove(struct lm_device *dev)
 {
        struct impd1_module *impd1 = lm_get_drvdata(dev);
-       struct list_head *l, *n;
        int i;
 
-       list_for_each_safe(l, n, &dev->dev.children) {
-               struct device *d = list_to_dev(l);
-
-               device_unregister(d);
-       }
+       device_for_each_child(&dev->dev, NULL, impd1_remove_one);
 
        for (i = 0; i < ARRAY_SIZE(impd1->vcos); i++)
                clk_unregister(&impd1->vcos[i]);