From ae2d1f2f5b59d00b39283c52dc4ee675397bbacd Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 14 Jul 2006 00:24:16 -0700 Subject: [PATCH] scx200_gpio: 1 cdev for N minors: cleanup, prep this patch is mostly cleanup of scx200_gpio : - drop #include - s/DEVNAME/DRVNAME/ apparently a convention - replace variable num_pins with #define MAX_PINS - s/dev/devid/ to clarify that its a dev_t, not a struct device dev. - move devid = MKDEV(major,0) into branch where its needed. 2 minor 'changes' : - reduced MAX_PINS from 64 to 32. Ive never tested other pins, and theyre all multiplexed with other functions, some of which may be in use on my soekris 4801, so I dont know what testing should yield. - +EXPORT_SYMBOL(scx200_access); This exposes the driver's vtable, which another driver can use along with #include , to manipulate a gpio-pin. Signed-off-by Jim Cromie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/scx200_gpio.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'drivers/char/scx200_gpio.c') diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 425c58719db..e7665c1ad13 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -5,7 +5,6 @@ Copyright (c) 2001,2002 Christer Weinigel */ -#include #include #include #include @@ -22,19 +21,20 @@ #include #include -#define NAME "scx200_gpio" -#define DEVNAME NAME +#define DRVNAME "scx200_gpio" static struct platform_device *pdev; MODULE_AUTHOR("Christer Weinigel "); -MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); +MODULE_DESCRIPTION("NatSemi/AMD SCx200 GPIO Pin Driver"); MODULE_LICENSE("GPL"); static int major = 0; /* default to dynamic major */ module_param(major, int, 0); MODULE_PARM_DESC(major, "Major device number"); +#define MAX_PINS 32 /* 64 later, when known ok */ + struct nsc_gpio_ops scx200_access = { .owner = THIS_MODULE, .gpio_config = scx200_gpio_configure, @@ -46,13 +46,14 @@ struct nsc_gpio_ops scx200_access = { .gpio_change = scx200_gpio_change, .gpio_current = scx200_gpio_current }; +EXPORT_SYMBOL(scx200_access); static int scx200_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); file->private_data = &scx200_access; - if (m > 63) + if (m >= MAX_PINS) return -EINVAL; return nonseekable_open(inode, file); } @@ -72,20 +73,19 @@ static const struct file_operations scx200_gpio_fops = { }; struct cdev *scx200_devices; -static int num_pins = 32; static int __init scx200_gpio_init(void) { int rc, i; - dev_t dev = MKDEV(major, 0); + dev_t devid; if (!scx200_gpio_present()) { - printk(KERN_ERR NAME ": no SCx200 gpio present\n"); + printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n"); return -ENODEV; } /* support dev_dbg() with pdev->dev */ - pdev = platform_device_alloc(DEVNAME, 0); + pdev = platform_device_alloc(DRVNAME, 0); if (!pdev) return -ENOMEM; @@ -96,22 +96,23 @@ static int __init scx200_gpio_init(void) /* nsc_gpio uses dev_dbg(), so needs this */ scx200_access.dev = &pdev->dev; - if (major) - rc = register_chrdev_region(dev, num_pins, "scx200_gpio"); - else { - rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio"); - major = MAJOR(dev); + if (major) { + devid = MKDEV(major, 0); + rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio"); + } else { + rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio"); + major = MAJOR(devid); } if (rc < 0) { dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); goto undo_platform_device_add; } - scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL); + scx200_devices = kzalloc(MAX_PINS * sizeof(struct cdev), GFP_KERNEL); if (!scx200_devices) { rc = -ENOMEM; goto undo_chrdev_region; } - for (i = 0; i < num_pins; i++) { + for (i = 0; i < MAX_PINS; i++) { struct cdev *cdev = &scx200_devices[i]; cdev_init(cdev, &scx200_gpio_fops); cdev->owner = THIS_MODULE; @@ -124,7 +125,7 @@ static int __init scx200_gpio_init(void) return 0; /* succeed */ undo_chrdev_region: - unregister_chrdev_region(dev, num_pins); + unregister_chrdev_region(devid, MAX_PINS); undo_platform_device_add: platform_device_del(pdev); undo_malloc: @@ -136,9 +137,8 @@ undo_malloc: static void __exit scx200_gpio_cleanup(void) { kfree(scx200_devices); - unregister_chrdev_region(MKDEV(major, 0), num_pins); + unregister_chrdev_region(MKDEV(major, 0), MAX_PINS); platform_device_unregister(pdev); - /* kfree(pdev); */ } module_init(scx200_gpio_init); -- cgit v1.2.3 From 635adb6cd25c8f816c9017a0a0349cd389eafcd3 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 14 Jul 2006 00:24:16 -0700 Subject: [PATCH] scx200_gpio: use 1 cdev for N minors, not N for N Remove the scx200_gpio's cdev-array & ksalloc, replacing it with a single static struct cdev, which is sufficient for all the pins. cdev_put is commented out since kernel wont link properly with it, and its apparently not needed. With these patches, this driver continues to work with Chris Boot's leds_48xx driver. Signed-off-by Jim Cromie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/scx200_gpio.c | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'drivers/char/scx200_gpio.c') diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index e7665c1ad13..dd1f997944e 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -63,7 +63,6 @@ static int scx200_gpio_release(struct inode *inode, struct file *file) return 0; } - static const struct file_operations scx200_gpio_fops = { .owner = THIS_MODULE, .write = nsc_gpio_write, @@ -72,11 +71,11 @@ static const struct file_operations scx200_gpio_fops = { .release = scx200_gpio_release, }; -struct cdev *scx200_devices; +struct cdev scx200_gpio_cdev; /* use 1 cdev for all pins */ static int __init scx200_gpio_init(void) { - int rc, i; + int rc; dev_t devid; if (!scx200_gpio_present()) { @@ -107,25 +106,12 @@ static int __init scx200_gpio_init(void) dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); goto undo_platform_device_add; } - scx200_devices = kzalloc(MAX_PINS * sizeof(struct cdev), GFP_KERNEL); - if (!scx200_devices) { - rc = -ENOMEM; - goto undo_chrdev_region; - } - for (i = 0; i < MAX_PINS; i++) { - struct cdev *cdev = &scx200_devices[i]; - cdev_init(cdev, &scx200_gpio_fops); - cdev->owner = THIS_MODULE; - rc = cdev_add(cdev, MKDEV(major, i), 1); - /* tolerate 'minor' errors */ - if (rc) - dev_err(&pdev->dev, "Error %d on minor %d", rc, i); - } + + cdev_init(&scx200_gpio_cdev, &scx200_gpio_fops); + cdev_add(&scx200_gpio_cdev, devid, MAX_PINS); return 0; /* succeed */ -undo_chrdev_region: - unregister_chrdev_region(devid, MAX_PINS); undo_platform_device_add: platform_device_del(pdev); undo_malloc: @@ -136,7 +122,9 @@ undo_malloc: static void __exit scx200_gpio_cleanup(void) { - kfree(scx200_devices); + cdev_del(&scx200_gpio_cdev); + /* cdev_put(&scx200_gpio_cdev); */ + unregister_chrdev_region(MKDEV(major, 0), MAX_PINS); platform_device_unregister(pdev); } -- cgit v1.2.3 From 91e260b80d2fec559877f399dfc36b554f207874 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 14 Jul 2006 00:24:25 -0700 Subject: [PATCH] gpio: drop vtable members .gpio_set_high .gpio_set_low gpio_set is enough drops gpio_set_high, gpio_set_low from the nsc_gpio_ops vtable. While we can't drop them from scx200_gpio (or can we?), we dont need them for new users of the exported vtable; gpio_set(1), gpio_set(0) work fine. Signed-off-by: Jim Cromie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/pc8736x_gpio.c | 2 -- drivers/char/scx200_gpio.c | 2 -- include/linux/nsc_gpio.h | 2 -- 3 files changed, 6 deletions(-) (limited to 'drivers/char/scx200_gpio.c') diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 11bd78c8062..0b235a90bee 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -218,8 +218,6 @@ static struct nsc_gpio_ops pc8736x_access = { .gpio_dump = nsc_gpio_dump, .gpio_get = pc8736x_gpio_get, .gpio_set = pc8736x_gpio_set, - .gpio_set_high = pc8736x_gpio_set_high, - .gpio_set_low = pc8736x_gpio_set_low, .gpio_change = pc8736x_gpio_change, .gpio_current = pc8736x_gpio_current }; diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index dd1f997944e..f65372b5a65 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -41,8 +41,6 @@ struct nsc_gpio_ops scx200_access = { .gpio_dump = nsc_gpio_dump, .gpio_get = scx200_gpio_get, .gpio_set = scx200_gpio_set, - .gpio_set_high = scx200_gpio_set_high, - .gpio_set_low = scx200_gpio_set_low, .gpio_change = scx200_gpio_change, .gpio_current = scx200_gpio_current }; diff --git a/include/linux/nsc_gpio.h b/include/linux/nsc_gpio.h index 135742cfada..7da0cf3702e 100644 --- a/include/linux/nsc_gpio.h +++ b/include/linux/nsc_gpio.h @@ -25,8 +25,6 @@ struct nsc_gpio_ops { void (*gpio_dump) (struct nsc_gpio_ops *amp, unsigned iminor); int (*gpio_get) (unsigned iminor); void (*gpio_set) (unsigned iminor, int state); - void (*gpio_set_high)(unsigned iminor); - void (*gpio_set_low) (unsigned iminor); void (*gpio_change) (unsigned iminor); int (*gpio_current) (unsigned iminor); struct device* dev; /* for dev_dbg() support, set in init */ -- cgit v1.2.3 From 2e8f7a3128bb8fac8351a994f1fc325717899308 Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 14 Jul 2006 00:24:26 -0700 Subject: [PATCH] gpio: rename exported vtables to better match purpose - rename EXPORTed gpio vtables from {scx200,pc8736x}_access to _gpio_ops new name is much closer to the vtable-name struct nsc_gpio_ops, should be clearer. Also rename the _fops vtable var to _fileops to better disambiguate it from the gpio vtable. Signed-off-by: Jim Cromie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/pc8736x_gpio.c | 13 ++++++------- drivers/char/scx200_gpio.c | 12 ++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) (limited to 'drivers/char/scx200_gpio.c') diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 0b235a90bee..645eb81cb5a 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -212,7 +212,7 @@ static void pc8736x_gpio_change(unsigned index) pc8736x_gpio_set(index, !pc8736x_gpio_current(index)); } -static struct nsc_gpio_ops pc8736x_access = { +static struct nsc_gpio_ops pc8736x_gpio_ops = { .owner = THIS_MODULE, .gpio_config = pc8736x_gpio_configure, .gpio_dump = nsc_gpio_dump, @@ -221,11 +221,12 @@ static struct nsc_gpio_ops pc8736x_access = { .gpio_change = pc8736x_gpio_change, .gpio_current = pc8736x_gpio_current }; +EXPORT_SYMBOL(pc8736x_gpio_ops); static int pc8736x_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); - file->private_data = &pc8736x_access; + file->private_data = &pc8736x_gpio_ops; dev_dbg(&pdev->dev, "open %d\n", m); @@ -234,7 +235,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file) return nonseekable_open(inode, file); } -static const struct file_operations pc8736x_gpio_fops = { +static const struct file_operations pc8736x_gpio_fileops = { .owner = THIS_MODULE, .open = pc8736x_gpio_open, .write = nsc_gpio_write, @@ -276,7 +277,7 @@ static int __init pc8736x_gpio_init(void) dev_err(&pdev->dev, "no device found\n"); goto undo_platform_dev_add; } - pc8736x_access.dev = &pdev->dev; + pc8736x_gpio_ops.dev = &pdev->dev; /* Verify that chip and it's GPIO unit are both enabled. My BIOS does this, so I take minimum action here @@ -326,7 +327,7 @@ static int __init pc8736x_gpio_init(void) pc8736x_init_shadow(); /* ignore minor errs, and succeed */ - cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fops); + cdev_init(&pc8736x_gpio_cdev, &pc8736x_gpio_fileops); cdev_add(&pc8736x_gpio_cdev, devid, PC8736X_GPIO_CT); return 0; @@ -353,7 +354,5 @@ static void __exit pc8736x_gpio_cleanup(void) platform_device_put(pdev); } -EXPORT_SYMBOL(pc8736x_access); - module_init(pc8736x_gpio_init); module_exit(pc8736x_gpio_cleanup); diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index f65372b5a65..b956c7babd1 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c @@ -35,7 +35,7 @@ MODULE_PARM_DESC(major, "Major device number"); #define MAX_PINS 32 /* 64 later, when known ok */ -struct nsc_gpio_ops scx200_access = { +struct nsc_gpio_ops scx200_gpio_ops = { .owner = THIS_MODULE, .gpio_config = scx200_gpio_configure, .gpio_dump = nsc_gpio_dump, @@ -44,12 +44,12 @@ struct nsc_gpio_ops scx200_access = { .gpio_change = scx200_gpio_change, .gpio_current = scx200_gpio_current }; -EXPORT_SYMBOL(scx200_access); +EXPORT_SYMBOL(scx200_gpio_ops); static int scx200_gpio_open(struct inode *inode, struct file *file) { unsigned m = iminor(inode); - file->private_data = &scx200_access; + file->private_data = &scx200_gpio_ops; if (m >= MAX_PINS) return -EINVAL; @@ -61,7 +61,7 @@ static int scx200_gpio_release(struct inode *inode, struct file *file) return 0; } -static const struct file_operations scx200_gpio_fops = { +static const struct file_operations scx200_gpio_fileops = { .owner = THIS_MODULE, .write = nsc_gpio_write, .read = nsc_gpio_read, @@ -91,7 +91,7 @@ static int __init scx200_gpio_init(void) goto undo_malloc; /* nsc_gpio uses dev_dbg(), so needs this */ - scx200_access.dev = &pdev->dev; + scx200_gpio_ops.dev = &pdev->dev; if (major) { devid = MKDEV(major, 0); @@ -105,7 +105,7 @@ static int __init scx200_gpio_init(void) goto undo_platform_device_add; } - cdev_init(&scx200_gpio_cdev, &scx200_gpio_fops); + cdev_init(&scx200_gpio_cdev, &scx200_gpio_fileops); cdev_add(&scx200_gpio_cdev, devid, MAX_PINS); return 0; /* succeed */ -- cgit v1.2.3