diff options
Diffstat (limited to 'drivers/char/scx200_gpio.c')
-rw-r--r-- | drivers/char/scx200_gpio.c | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c index 425c58719db6..e7665c1ad134 100644 --- a/drivers/char/scx200_gpio.c +++ b/drivers/char/scx200_gpio.c | |||
@@ -5,7 +5,6 @@ | |||
5 | 5 | ||
6 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */ | 6 | Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com> */ |
7 | 7 | ||
8 | #include <linux/config.h> | ||
9 | #include <linux/device.h> | 8 | #include <linux/device.h> |
10 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
11 | #include <linux/module.h> | 10 | #include <linux/module.h> |
@@ -22,19 +21,20 @@ | |||
22 | #include <linux/scx200_gpio.h> | 21 | #include <linux/scx200_gpio.h> |
23 | #include <linux/nsc_gpio.h> | 22 | #include <linux/nsc_gpio.h> |
24 | 23 | ||
25 | #define NAME "scx200_gpio" | 24 | #define DRVNAME "scx200_gpio" |
26 | #define DEVNAME NAME | ||
27 | 25 | ||
28 | static struct platform_device *pdev; | 26 | static struct platform_device *pdev; |
29 | 27 | ||
30 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); | 28 | MODULE_AUTHOR("Christer Weinigel <wingel@nano-system.com>"); |
31 | MODULE_DESCRIPTION("NatSemi SCx200 GPIO Pin Driver"); | 29 | MODULE_DESCRIPTION("NatSemi/AMD SCx200 GPIO Pin Driver"); |
32 | MODULE_LICENSE("GPL"); | 30 | MODULE_LICENSE("GPL"); |
33 | 31 | ||
34 | static int major = 0; /* default to dynamic major */ | 32 | static int major = 0; /* default to dynamic major */ |
35 | module_param(major, int, 0); | 33 | module_param(major, int, 0); |
36 | MODULE_PARM_DESC(major, "Major device number"); | 34 | MODULE_PARM_DESC(major, "Major device number"); |
37 | 35 | ||
36 | #define MAX_PINS 32 /* 64 later, when known ok */ | ||
37 | |||
38 | struct nsc_gpio_ops scx200_access = { | 38 | struct nsc_gpio_ops scx200_access = { |
39 | .owner = THIS_MODULE, | 39 | .owner = THIS_MODULE, |
40 | .gpio_config = scx200_gpio_configure, | 40 | .gpio_config = scx200_gpio_configure, |
@@ -46,13 +46,14 @@ struct nsc_gpio_ops scx200_access = { | |||
46 | .gpio_change = scx200_gpio_change, | 46 | .gpio_change = scx200_gpio_change, |
47 | .gpio_current = scx200_gpio_current | 47 | .gpio_current = scx200_gpio_current |
48 | }; | 48 | }; |
49 | EXPORT_SYMBOL(scx200_access); | ||
49 | 50 | ||
50 | static int scx200_gpio_open(struct inode *inode, struct file *file) | 51 | static int scx200_gpio_open(struct inode *inode, struct file *file) |
51 | { | 52 | { |
52 | unsigned m = iminor(inode); | 53 | unsigned m = iminor(inode); |
53 | file->private_data = &scx200_access; | 54 | file->private_data = &scx200_access; |
54 | 55 | ||
55 | if (m > 63) | 56 | if (m >= MAX_PINS) |
56 | return -EINVAL; | 57 | return -EINVAL; |
57 | return nonseekable_open(inode, file); | 58 | return nonseekable_open(inode, file); |
58 | } | 59 | } |
@@ -72,20 +73,19 @@ static const struct file_operations scx200_gpio_fops = { | |||
72 | }; | 73 | }; |
73 | 74 | ||
74 | struct cdev *scx200_devices; | 75 | struct cdev *scx200_devices; |
75 | static int num_pins = 32; | ||
76 | 76 | ||
77 | static int __init scx200_gpio_init(void) | 77 | static int __init scx200_gpio_init(void) |
78 | { | 78 | { |
79 | int rc, i; | 79 | int rc, i; |
80 | dev_t dev = MKDEV(major, 0); | 80 | dev_t devid; |
81 | 81 | ||
82 | if (!scx200_gpio_present()) { | 82 | if (!scx200_gpio_present()) { |
83 | printk(KERN_ERR NAME ": no SCx200 gpio present\n"); | 83 | printk(KERN_ERR DRVNAME ": no SCx200 gpio present\n"); |
84 | return -ENODEV; | 84 | return -ENODEV; |
85 | } | 85 | } |
86 | 86 | ||
87 | /* support dev_dbg() with pdev->dev */ | 87 | /* support dev_dbg() with pdev->dev */ |
88 | pdev = platform_device_alloc(DEVNAME, 0); | 88 | pdev = platform_device_alloc(DRVNAME, 0); |
89 | if (!pdev) | 89 | if (!pdev) |
90 | return -ENOMEM; | 90 | return -ENOMEM; |
91 | 91 | ||
@@ -96,22 +96,23 @@ static int __init scx200_gpio_init(void) | |||
96 | /* nsc_gpio uses dev_dbg(), so needs this */ | 96 | /* nsc_gpio uses dev_dbg(), so needs this */ |
97 | scx200_access.dev = &pdev->dev; | 97 | scx200_access.dev = &pdev->dev; |
98 | 98 | ||
99 | if (major) | 99 | if (major) { |
100 | rc = register_chrdev_region(dev, num_pins, "scx200_gpio"); | 100 | devid = MKDEV(major, 0); |
101 | else { | 101 | rc = register_chrdev_region(devid, MAX_PINS, "scx200_gpio"); |
102 | rc = alloc_chrdev_region(&dev, 0, num_pins, "scx200_gpio"); | 102 | } else { |
103 | major = MAJOR(dev); | 103 | rc = alloc_chrdev_region(&devid, 0, MAX_PINS, "scx200_gpio"); |
104 | major = MAJOR(devid); | ||
104 | } | 105 | } |
105 | if (rc < 0) { | 106 | if (rc < 0) { |
106 | dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); | 107 | dev_err(&pdev->dev, "SCx200 chrdev_region err: %d\n", rc); |
107 | goto undo_platform_device_add; | 108 | goto undo_platform_device_add; |
108 | } | 109 | } |
109 | scx200_devices = kzalloc(num_pins * sizeof(struct cdev), GFP_KERNEL); | 110 | scx200_devices = kzalloc(MAX_PINS * sizeof(struct cdev), GFP_KERNEL); |
110 | if (!scx200_devices) { | 111 | if (!scx200_devices) { |
111 | rc = -ENOMEM; | 112 | rc = -ENOMEM; |
112 | goto undo_chrdev_region; | 113 | goto undo_chrdev_region; |
113 | } | 114 | } |
114 | for (i = 0; i < num_pins; i++) { | 115 | for (i = 0; i < MAX_PINS; i++) { |
115 | struct cdev *cdev = &scx200_devices[i]; | 116 | struct cdev *cdev = &scx200_devices[i]; |
116 | cdev_init(cdev, &scx200_gpio_fops); | 117 | cdev_init(cdev, &scx200_gpio_fops); |
117 | cdev->owner = THIS_MODULE; | 118 | cdev->owner = THIS_MODULE; |
@@ -124,7 +125,7 @@ static int __init scx200_gpio_init(void) | |||
124 | return 0; /* succeed */ | 125 | return 0; /* succeed */ |
125 | 126 | ||
126 | undo_chrdev_region: | 127 | undo_chrdev_region: |
127 | unregister_chrdev_region(dev, num_pins); | 128 | unregister_chrdev_region(devid, MAX_PINS); |
128 | undo_platform_device_add: | 129 | undo_platform_device_add: |
129 | platform_device_del(pdev); | 130 | platform_device_del(pdev); |
130 | undo_malloc: | 131 | undo_malloc: |
@@ -136,9 +137,8 @@ undo_malloc: | |||
136 | static void __exit scx200_gpio_cleanup(void) | 137 | static void __exit scx200_gpio_cleanup(void) |
137 | { | 138 | { |
138 | kfree(scx200_devices); | 139 | kfree(scx200_devices); |
139 | unregister_chrdev_region(MKDEV(major, 0), num_pins); | 140 | unregister_chrdev_region(MKDEV(major, 0), MAX_PINS); |
140 | platform_device_unregister(pdev); | 141 | platform_device_unregister(pdev); |
141 | /* kfree(pdev); */ | ||
142 | } | 142 | } |
143 | 143 | ||
144 | module_init(scx200_gpio_init); | 144 | module_init(scx200_gpio_init); |