[Balloon-svn] r474 - balloon/trunk/kernel/2.6.22.2

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: subversion@balloonboard.org
Date:  
To: balloon-svn
Subject: [Balloon-svn] r474 - balloon/trunk/kernel/2.6.22.2
Author: wookey
Date: 2008-04-29 16:51:01 +0100 (Tue, 29 Apr 2008)
New Revision: 474

Modified:
balloon/trunk/kernel/2.6.22.2/balloon3-minipug.patch
Log:
Updated minipug driver that works with udev (using classes rather than
platform driver as that didn't work - further investigation required
sometime)


Modified: balloon/trunk/kernel/2.6.22.2/balloon3-minipug.patch
===================================================================
--- balloon/trunk/kernel/2.6.22.2/balloon3-minipug.patch    2008-04-29 15:24:57 UTC (rev 473)
+++ balloon/trunk/kernel/2.6.22.2/balloon3-minipug.patch    2008-04-29 15:51:01 UTC (rev 474)
@@ -1,7 +1,7 @@
Index: linux-2.6.22.2/drivers/char/Kconfig
===================================================================
---- linux-2.6.22.2.orig/drivers/char/Kconfig    2008-03-27 15:17:27.000000000 +0000
-+++ linux-2.6.22.2/drivers/char/Kconfig    2008-03-27 15:17:27.000000000 +0000
+--- linux-2.6.22.2.orig/drivers/char/Kconfig    2008-04-29 09:52:26.000000000 +0100
++++ linux-2.6.22.2/drivers/char/Kconfig    2008-04-29 09:52:26.000000000 +0100
@@ -1092,6 +1092,12 @@
Balloon2, 8 or 16 bit on Balloon3. You normally want this
unless you are using the bus lines for something else.
@@ -17,8 +17,8 @@

Index: linux-2.6.22.2/drivers/char/Makefile
===================================================================
---- linux-2.6.22.2.orig/drivers/char/Makefile    2008-03-27 15:17:27.000000000 +0000
-+++ linux-2.6.22.2/drivers/char/Makefile    2008-03-27 15:17:27.000000000 +0000
+--- linux-2.6.22.2.orig/drivers/char/Makefile    2008-04-29 09:52:26.000000000 +0100
++++ linux-2.6.22.2/drivers/char/Makefile    2008-04-29 09:52:26.000000000 +0100
@@ -105,6 +105,7 @@
obj-$(CONFIG_TCG_TPM)        += tpm/

@@ -30,8 +30,8 @@
Index: linux-2.6.22.2/drivers/char/minipug.c
===================================================================
--- /dev/null    1970-01-01 00:00:00.000000000 +0000
-+++ linux-2.6.22.2/drivers/char/minipug.c    2008-03-27 15:23:34.000000000 +0000
-@@ -0,0 +1,640 @@
++++ linux-2.6.22.2/drivers/char/minipug.c    2008-04-29 13:42:15.000000000 +0100
+@@ -0,0 +1,729 @@
+/*
+ * linux/drivers/char/minipug.c
+ *
@@ -59,8 +59,26 @@
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
++#include "linux/cdev.h"
+#include "samosa.h"
+
++// uncomment to use a minipug class model.
++// This is needed at the moment for udev as
++// the add uevent seems to be missing the MAJOR
++// and MINOR fields if done via platform devices.
++#define MINIPUG_CLASS
++
++// uncomment for fixed node major numbering
++// #define MINIPUG_MAJOR 200
++
++#ifdef MINIPUG_MAJOR
++static int major = MINIPUG_MAJOR;
++#else
++static int major = 0;
++module_param(major, int, 0);
++MODULE_PARM_DESC(major, "Major device number");
++#endif
++
+static spinlock_t minipug_lock;
+
+#define dprintk(x...)
@@ -363,7 +381,6 @@
+    mmap:        minipug_mmap,
+};
+
-+#define MINIPUG_MAJOR 200
+
+struct minipug_info minipug[2]={
+ {display: 0},
@@ -538,76 +555,39 @@
+}
+
+/* driver initialisation */
++static int __init minipug_probe ( struct platform_device *pdev) {
+
-+static int __init minipug_probe ( struct platform_device *pdev) {
++#ifndef CONFIG_BALLOON2_BUILD_TCL_PIKEY2
+    // if smart media present - cpld cannot be so declare invalid
-+#ifndef CONFIG_BALLOON2_BUILD_TCL_PIKEY2
+    if (balloon_samosa_sm_present()) {
+        printk("%s: samosa bus not present\n",__FUNCTION__);
+     return -ENODEV;
+    }
+#endif
+
-+    // check that the displays are ready
-+    if (!minipug_ready(0)) {
-+        printk("%s: minipug0 not ready\n",__FUNCTION__);
++    if (!minipug_ready(pdev->id)) {
++        printk("%s: minipug %d not ready\n",__FUNCTION__,pdev->id);
+     return -ENODEV;
+    }
+
-+    if (!minipug_ready(1)) {
-+        printk("%s: minipug1 not ready\n",__FUNCTION__);
-+     return -ENODEV;
-+    }
-+
-+    minipug[0].buffer=(unsigned char *)vmalloc_user(BUFFER_SIZE);
-+    if (!minipug[0].buffer) {
-+        printk("%s: minipug0 not enough memory\n",__FUNCTION__);
++    minipug[pdev->id].buffer=(unsigned char *)vmalloc_user(BUFFER_SIZE);
++    if (!minipug[pdev->id].buffer) {
++        printk("%s: minipug %d not enough memory\n",__FUNCTION__,pdev->id);
+     return -ENOMEM;
+    }
+
-+    minipug[1].buffer=(unsigned char *)vmalloc_user(BUFFER_SIZE);
-+    if (!minipug[1].buffer) {
-+     kfree(minipug[0].buffer);
-+        printk("%s: minipug1 not enough memory\n",__FUNCTION__);
-+     return -ENOMEM;
-+    }
-+
-+    spin_lock_init(&minipug_lock);
-+
-+    register_chrdev(MINIPUG_MAJOR,"minipug",&minipug_fops);
-+//    register_chrdev_region(mp_dev,2,"minipug");
-+
-+    active_display=0;
-+    minipug[0].bpp=DISPLAY_BPP0;
++    active_display=pdev->id;
++    minipug[active_display].bpp=DISPLAY_BPP0;
+    minipug_setup();
+
-+    active_display=1;
-+    minipug[1].bpp=DISPLAY_BPP1;
-+    minipug_setup();
++    printk("Minipug %d display support installed\n",pdev->id);
+
-+    // create proc access to displays
-+    proc_minipug = create_proc_entry(PROC_MINIPUG,S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, &proc_root);
-+    if (proc_minipug)
-+     proc_minipug->proc_fops = &proc_minipug_operations;
-+
-+    printk("Minipug display support installed\n");
-+
+    return 0;
+}
+
+static int __exit minipug_remove (struct platform_device *_dev)
+{
-+    // remove proc entry
-+    remove_proc_entry(PROC_MINIPUG,&proc_root);
-+
-+    // remove dev entries
-+//    unregister_chrdev_region(mp_dev,2);
-+    unregister_chrdev(MINIPUG_MAJOR,"minipug");
-+
-+    // free memory
-+    vfree(minipug[0].buffer);
-+    vfree(minipug[1].buffer);
-+
++    vfree(minipug[_dev->id].buffer);
+    platform_set_drvdata(_dev,NULL);
+    return 0;
+}
@@ -636,6 +616,7 @@
+{
+}
+
++// driver definition
+static struct platform_driver minipug_driver = {
+    .probe        = minipug_probe,
+    .shutdown    = minipug_shutdown,
@@ -648,21 +629,130 @@
+    },
+};
+
-+static struct platform_device minipug_device = {
-+    .name    = "minipug",
-+    .id    = 0,
++// character device
++static struct cdev minipug_cdev = {
++    .kobj    =    {.name = "minipug", },
++    .owner    =    THIS_MODULE,
+};
+
++static dev_t dev;
++#ifdef MINIPUG_CLASS
++static struct class *minipug_class;
++#else
++static struct platform_device *minipug_device[2];
++#endif
++
+static int __init minipug_init(void)
+{
-+    platform_device_register(&minipug_device);
++    int ret;
++
++    // general initialisation
++    spin_lock_init(&minipug_lock);
++
++    // register a range of device nodes
++    if (major) {
++        dev = MKDEV(major,0);
++        ret = register_chrdev_region(dev, 2, "minipug");
++    }
++    else {
++        ret = alloc_chrdev_region(&dev, 0, 2, "minipug");
++        major = MAJOR(dev);
++    }
++
++    if (ret)
++        goto error;
++
++    // create a character device handler
++    cdev_init(&minipug_cdev,&minipug_fops);
++    // add character device with 2 entries
++    ret = cdev_add(&minipug_cdev, dev, 2);
++    if (ret) {
++        kobject_put(&minipug_cdev.kobj);
++        goto error_region;
++    }
++
++#ifdef MINIPUG_CLASS
++    // explicitly create 2 devices via a minipug class
++    // this seems necessary to avoid the problem of platform devices
++    // not sending MAJOR and MINOR fields so udev is unable to
++    // create the device nodes.
++    minipug_class = class_create(THIS_MODULE, "minipug");
++    if (IS_ERR(minipug_class)) {
++        printk(KERN_ERR "Error creating minipug class.\n");
++        cdev_del(&minipug_cdev);
++        ret = PTR_ERR(minipug_class);
++        goto error_region;
++    }
++    // create the actual devices
++    device_create(minipug_class, NULL, MKDEV(major, 0), "minipug0");
++    device_create(minipug_class, NULL, MKDEV(major, 1), "minipug1");
++#else
++#if 1
++    minipug_device[0] = platform_device_alloc("minipug", 0);
++    // this is a hack to permit uevents
++    minipug_device[0]->dev.uevent_suppress = 0;
++    minipug_device[1] = platform_device_alloc("minipug", 1);
++    // this is a hack to permit uevents
++    minipug_device[1]->dev.uevent_suppress = 0;
++#else
++    // this seems a way not to have to hack platform_device_alloc
++    // it needs a release function and also doesnt pass MAJOR or MINOR
++    minipug_device[0] = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
++    minipug_device[0]->name = "minipug";
++    minipug_device[0]->id = 0;
++//    minipug_device[0].release = minipug_release;
++
++    minipug_device[1] = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
++    minipug_device[1]->name = "minipug";
++    minipug_device[1]->id = 1;
++//    minipug_device[1].release = minipug_release;
++#endif
++
++// both the versions below work fine
++#if 1
++    platform_device_register(minipug_device[0]);
++    platform_device_register(minipug_device[1]);
++#else
++    platform_add_devices(minipug_device, ARRAY_SIZE(minipug_device));
++#endif
++#endif
++
++    // create proc access to displays
++    proc_minipug = create_proc_entry(PROC_MINIPUG,S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, &proc_root);
++    if (proc_minipug)
++     proc_minipug->proc_fops = &proc_minipug_operations;
++
++    // register the driver
+    return platform_driver_register(&minipug_driver);
++
++error_region:
++    unregister_chrdev_region(dev, 2);
++error:
++    return ret;
+}
+
+static void __exit minipug_exit(void)
+{
++    // remove proc entry
++    remove_proc_entry(PROC_MINIPUG,&proc_root);
++#ifdef MINIPUG_CLASS
++    // remove devices
++    device_destroy(minipug_class, MKDEV(major, 0));
++    device_destroy(minipug_class, MKDEV(major, 1));
++    // remove class
++    class_destroy(minipug_class);
++#else
++    platform_device_unregister(minipug_device[0]);
++    kfree(minipug_device[0]);
++    platform_device_unregister(minipug_device[1]);
++    kfree(minipug_device[1]);
++#endif
++    // remove driver
+    platform_driver_unregister(&minipug_driver);
-+    platform_device_unregister(&minipug_device);
++    // remove character device
++    cdev_del(&minipug_cdev);
++    // unregister region
++    unregister_chrdev_region(dev, 2);
+}
+
+module_init(minipug_init);
@@ -671,4 +761,3 @@
+MODULE_AUTHOR("Nick Bane <>");
+MODULE_DESCRIPTION("Minipug display interface via samosa bus on Balloon");
+MODULE_LICENSE("GPL");
-+