From: Jim Cromie Date: Tue, 27 Jun 2006 09:54:14 +0000 (-0700) Subject: [PATCH] chardev: GPIO for SCx200 & PC-8736x: modernize driver init to 2.6 api X-Git-Tag: v2.6.18-rc1~535 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d7f212661d68d231fdfaead03dda0dd44d5bbbb;p=linux-2.6 [PATCH] chardev: GPIO for SCx200 & PC-8736x: modernize driver init to 2.6 api Adopt many modern 2.6 coding practices, ala LDD3, chapter 3. Changes are limited to initialization calls from module init, ie: cdev_init, cdev_add, *_chrdev_region, mkdev. Signed-off-by: Jim Cromie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index dd051ea675..507a5bf567 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -14,6 +14,9 @@ #include #include +#include +#include + #include #define NAME "scx200_gpio" @@ -26,6 +29,8 @@ static int major = 0; /* default to dynamic major */ module_param(major, int, 0); MODULE_PARM_DESC(major, "Major device number"); +extern void scx200_gpio_dump(unsigned index); + static ssize_t scx200_gpio_write(struct file *file, const char __user *data, size_t len, loff_t *ppos) { @@ -108,33 +113,57 @@ static struct file_operations scx200_gpio_fops = { .release = scx200_gpio_release, }; +struct cdev *scx200_devices; +int num_devs = 32; + static int __init scx200_gpio_init(void) { - int r; + int rc, i; + dev_t dev = MKDEV(major, 0); printk(KERN_DEBUG NAME ": NatSemi SCx200 GPIO Driver\n"); if (!scx200_gpio_present()) { - printk(KERN_ERR NAME ": no SCx200 gpio pins available\n"); + printk(KERN_ERR NAME ": no SCx200 gpio present\n"); return -ENODEV; } - - r = register_chrdev(major, NAME, &scx200_gpio_fops); - if (r < 0) { - printk(KERN_ERR NAME ": unable to register character device\n"); - return r; + if (major) + rc = register_chrdev_region(dev, num_devs, "scx200_gpio"); + else { + rc = alloc_chrdev_region(&dev, 0, num_devs, "scx200_gpio"); + major = MAJOR(dev); } - if (!major) { - major = r; - printk(KERN_DEBUG NAME ": got dynamic major %d\n", major); + if (rc < 0) { + printk(KERN_ERR NAME ": SCx200 chrdev_region: %d\n", rc); + return rc; + } + scx200_devices = kzalloc(num_devs * sizeof(struct cdev), GFP_KERNEL); + if (!scx200_devices) { + rc = -ENOMEM; + goto fail_malloc; + } + for (i = 0; i < num_devs; i++) { + struct cdev *cdev = &scx200_devices[i]; + cdev_init(cdev, &scx200_gpio_fops); + cdev->owner = THIS_MODULE; + cdev->ops = &scx200_gpio_fops; + rc = cdev_add(cdev, MKDEV(major, i), 1); + /* Fail gracefully if need be */ + if (rc) + printk(KERN_ERR NAME "Error %d on minor %d", rc, i); } - return 0; + return 0; /* succeed */ + +fail_malloc: + unregister_chrdev_region(dev, num_devs); + return rc; } static void __exit scx200_gpio_cleanup(void) { - unregister_chrdev(major, NAME); + kfree(scx200_devices); + unregister_chrdev_region(MKDEV(major, 0), num_devs); } module_init(scx200_gpio_init);