diff options
author | Cyrill V. Gorcunov <gorcunov@gmail.com> | 2007-02-10 01:29:19 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-02-10 01:29:19 -0500 |
commit | b350620cc5e8e62782a4d47bf45952442a18a0b0 (patch) | |
tree | 03850d27686950a0aba6cbd702e70334dc39c24c /drivers/input | |
parent | ff141a03e1909db719c6afd3230c2f16a4141860 (diff) |
Input: HIL - handle erros from input_register_device()
Also some whitespace cleanup.
Signed-off-by: Cyrill V. Gorcunov <gorcunov@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/hilkbd.c | 114 |
1 files changed, 66 insertions, 48 deletions
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c index 35461eab2faf..255a6ec75a48 100644 --- a/drivers/input/keyboard/hilkbd.c +++ b/drivers/input/keyboard/hilkbd.c | |||
@@ -6,10 +6,10 @@ | |||
6 | * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> | 6 | * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> |
7 | * | 7 | * |
8 | * Very basic HP Human Interface Loop (HIL) driver. | 8 | * Very basic HP Human Interface Loop (HIL) driver. |
9 | * This driver handles the keyboard on HP300 (m68k) and on some | 9 | * This driver handles the keyboard on HP300 (m68k) and on some |
10 | * HP700 (parisc) series machines. | 10 | * HP700 (parisc) series machines. |
11 | * | 11 | * |
12 | * | 12 | * |
13 | * This file is subject to the terms and conditions of the GNU General Public | 13 | * This file is subject to the terms and conditions of the GNU General Public |
14 | * License version 2. See the file COPYING in the main directory of this | 14 | * License version 2. See the file COPYING in the main directory of this |
15 | * archive for more details. | 15 | * archive for more details. |
@@ -64,9 +64,9 @@ MODULE_LICENSE("GPL v2"); | |||
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | 66 | ||
67 | 67 | ||
68 | /* HIL helper functions */ | 68 | /* HIL helper functions */ |
69 | 69 | ||
70 | #define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY) | 70 | #define hil_busy() (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY) |
71 | #define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY) | 71 | #define hil_data_available() (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY) |
72 | #define hil_status() (hil_readb(HILBASE + HIL_CMD)) | 72 | #define hil_status() (hil_readb(HILBASE + HIL_CMD)) |
@@ -75,7 +75,7 @@ MODULE_LICENSE("GPL v2"); | |||
75 | #define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0) | 75 | #define hil_write_data(x) do { hil_writeb((x), HILBASE + HIL_DATA); } while (0) |
76 | 76 | ||
77 | /* HIL constants */ | 77 | /* HIL constants */ |
78 | 78 | ||
79 | #define HIL_BUSY 0x02 | 79 | #define HIL_BUSY 0x02 |
80 | #define HIL_DATA_RDY 0x01 | 80 | #define HIL_DATA_RDY 0x01 |
81 | 81 | ||
@@ -86,10 +86,10 @@ MODULE_LICENSE("GPL v2"); | |||
86 | #define HIL_INTON 0x5C /* Turn on interrupts. */ | 86 | #define HIL_INTON 0x5C /* Turn on interrupts. */ |
87 | #define HIL_INTOFF 0x5D /* Turn off interrupts. */ | 87 | #define HIL_INTOFF 0x5D /* Turn off interrupts. */ |
88 | 88 | ||
89 | #define HIL_READKBDSADR 0xF9 | 89 | #define HIL_READKBDSADR 0xF9 |
90 | #define HIL_WRITEKBDSADR 0xE9 | 90 | #define HIL_WRITEKBDSADR 0xE9 |
91 | 91 | ||
92 | static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = | 92 | static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] = |
93 | { HIL_KEYCODES_SET1 }; | 93 | { HIL_KEYCODES_SET1 }; |
94 | 94 | ||
95 | /* HIL structure */ | 95 | /* HIL structure */ |
@@ -97,11 +97,11 @@ static struct { | |||
97 | struct input_dev *dev; | 97 | struct input_dev *dev; |
98 | 98 | ||
99 | unsigned int curdev; | 99 | unsigned int curdev; |
100 | 100 | ||
101 | unsigned char s; | 101 | unsigned char s; |
102 | unsigned char c; | 102 | unsigned char c; |
103 | int valid; | 103 | int valid; |
104 | 104 | ||
105 | unsigned char data[16]; | 105 | unsigned char data[16]; |
106 | unsigned int ptr; | 106 | unsigned int ptr; |
107 | spinlock_t lock; | 107 | spinlock_t lock; |
@@ -115,7 +115,7 @@ static void poll_finished(void) | |||
115 | int down; | 115 | int down; |
116 | int key; | 116 | int key; |
117 | unsigned char scode; | 117 | unsigned char scode; |
118 | 118 | ||
119 | switch (hil_dev.data[0]) { | 119 | switch (hil_dev.data[0]) { |
120 | case 0x40: | 120 | case 0x40: |
121 | down = (hil_dev.data[1] & 1) == 0; | 121 | down = (hil_dev.data[1] & 1) == 0; |
@@ -127,6 +127,7 @@ static void poll_finished(void) | |||
127 | hil_dev.curdev = 0; | 127 | hil_dev.curdev = 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | |||
130 | static inline void handle_status(unsigned char s, unsigned char c) | 131 | static inline void handle_status(unsigned char s, unsigned char c) |
131 | { | 132 | { |
132 | if (c & 0x8) { | 133 | if (c & 0x8) { |
@@ -143,6 +144,7 @@ static inline void handle_status(unsigned char s, unsigned char c) | |||
143 | } | 144 | } |
144 | } | 145 | } |
145 | 146 | ||
147 | |||
146 | static inline void handle_data(unsigned char s, unsigned char c) | 148 | static inline void handle_data(unsigned char s, unsigned char c) |
147 | { | 149 | { |
148 | if (hil_dev.curdev) { | 150 | if (hil_dev.curdev) { |
@@ -152,13 +154,11 @@ static inline void handle_data(unsigned char s, unsigned char c) | |||
152 | } | 154 | } |
153 | 155 | ||
154 | 156 | ||
155 | /* | 157 | /* handle HIL interrupts */ |
156 | * Handle HIL interrupts. | ||
157 | */ | ||
158 | static irqreturn_t hil_interrupt(int irq, void *handle) | 158 | static irqreturn_t hil_interrupt(int irq, void *handle) |
159 | { | 159 | { |
160 | unsigned char s, c; | 160 | unsigned char s, c; |
161 | 161 | ||
162 | s = hil_status(); | 162 | s = hil_status(); |
163 | c = hil_read_data(); | 163 | c = hil_read_data(); |
164 | 164 | ||
@@ -179,10 +179,8 @@ static irqreturn_t hil_interrupt(int irq, void *handle) | |||
179 | return IRQ_HANDLED; | 179 | return IRQ_HANDLED; |
180 | } | 180 | } |
181 | 181 | ||
182 | /* | ||
183 | * Send a command to the HIL | ||
184 | */ | ||
185 | 182 | ||
183 | /* send a command to the HIL */ | ||
186 | static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | 184 | static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) |
187 | { | 185 | { |
188 | unsigned long flags; | 186 | unsigned long flags; |
@@ -200,16 +198,14 @@ static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len) | |||
200 | } | 198 | } |
201 | 199 | ||
202 | 200 | ||
203 | /* | 201 | /* initialise HIL */ |
204 | * Initialise HIL. | ||
205 | */ | ||
206 | |||
207 | static int __init | 202 | static int __init |
208 | hil_keyb_init(void) | 203 | hil_keyb_init(void) |
209 | { | 204 | { |
210 | unsigned char c; | 205 | unsigned char c; |
211 | unsigned int i, kbid; | 206 | unsigned int i, kbid; |
212 | wait_queue_head_t hil_wait; | 207 | wait_queue_head_t hil_wait; |
208 | int err; | ||
213 | 209 | ||
214 | if (hil_dev.dev) { | 210 | if (hil_dev.dev) { |
215 | return -ENODEV; /* already initialized */ | 211 | return -ENODEV; /* already initialized */ |
@@ -219,15 +215,25 @@ hil_keyb_init(void) | |||
219 | if (!hil_dev.dev) | 215 | if (!hil_dev.dev) |
220 | return -ENOMEM; | 216 | return -ENOMEM; |
221 | hil_dev.dev->private = &hil_dev; | 217 | hil_dev.dev->private = &hil_dev; |
222 | 218 | ||
223 | #if defined(CONFIG_HP300) | 219 | #if defined(CONFIG_HP300) |
224 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) | 220 | if (!hwreg_present((void *)(HILBASE + HIL_DATA))) { |
225 | return -ENODEV; | 221 | printk(KERN_ERR "HIL: hardware register was not found\n"); |
226 | 222 | err = -ENODEV; | |
227 | request_region(HILBASE+HIL_DATA, 2, "hil"); | 223 | goto err1; |
224 | } | ||
225 | if (!request_region(HILBASE + HIL_DATA, 2, "hil")) { | ||
226 | printk(KERN_ERR "HIL: IOPORT region already used\n"); | ||
227 | err = -EIO; | ||
228 | goto err1; | ||
229 | } | ||
228 | #endif | 230 | #endif |
229 | 231 | ||
230 | request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); | 232 | err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id); |
233 | if (err) { | ||
234 | printk(KERN_ERR "HIL: Can't get IRQ\n"); | ||
235 | goto err2; | ||
236 | } | ||
231 | 237 | ||
232 | /* Turn on interrupts */ | 238 | /* Turn on interrupts */ |
233 | hil_do(HIL_INTON, NULL, 0); | 239 | hil_do(HIL_INTON, NULL, 0); |
@@ -239,47 +245,63 @@ hil_keyb_init(void) | |||
239 | init_waitqueue_head(&hil_wait); | 245 | init_waitqueue_head(&hil_wait); |
240 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); | 246 | wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ); |
241 | if (!hil_dev.valid) { | 247 | if (!hil_dev.valid) { |
242 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present.\n"); | 248 | printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n"); |
243 | } | 249 | } |
244 | 250 | ||
245 | c = hil_dev.c; | 251 | c = hil_dev.c; |
246 | hil_dev.valid = 0; | 252 | hil_dev.valid = 0; |
247 | if (c == 0) { | 253 | if (c == 0) { |
248 | kbid = -1; | 254 | kbid = -1; |
249 | printk(KERN_WARNING "HIL: no keyboard present.\n"); | 255 | printk(KERN_WARNING "HIL: no keyboard present\n"); |
250 | } else { | 256 | } else { |
251 | kbid = ffz(~c); | 257 | kbid = ffz(~c); |
252 | /* printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); */ | 258 | printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid); |
253 | } | 259 | } |
254 | 260 | ||
255 | /* set it to raw mode */ | 261 | /* set it to raw mode */ |
256 | c = 0; | 262 | c = 0; |
257 | hil_do(HIL_WRITEKBDSADR, &c, 1); | 263 | hil_do(HIL_WRITEKBDSADR, &c, 1); |
258 | 264 | ||
259 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) | 265 | for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++) |
260 | if (hphilkeyb_keycode[i] != KEY_RESERVED) | 266 | if (hphilkeyb_keycode[i] != KEY_RESERVED) |
261 | set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); | 267 | set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); |
262 | 268 | ||
263 | hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 269 | hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
264 | hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); | 270 | hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); |
265 | hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; | 271 | hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; |
266 | hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]); | 272 | hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]); |
267 | hil_dev.dev->keycode = hphilkeyb_keycode; | 273 | hil_dev.dev->keycode = hphilkeyb_keycode; |
268 | hil_dev.dev->name = "HIL keyboard"; | 274 | hil_dev.dev->name = "HIL keyboard"; |
269 | hil_dev.dev->phys = "hpkbd/input0"; | 275 | hil_dev.dev->phys = "hpkbd/input0"; |
270 | 276 | ||
271 | hil_dev.dev->id.bustype = BUS_HIL; | 277 | hil_dev.dev->id.bustype = BUS_HIL; |
272 | hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; | 278 | hil_dev.dev->id.vendor = PCI_VENDOR_ID_HP; |
273 | hil_dev.dev->id.product = 0x0001; | 279 | hil_dev.dev->id.product = 0x0001; |
274 | hil_dev.dev->id.version = 0x0010; | 280 | hil_dev.dev->id.version = 0x0010; |
275 | 281 | ||
276 | input_register_device(hil_dev.dev); | 282 | err = input_register_device(hil_dev.dev); |
283 | if (err) { | ||
284 | printk(KERN_ERR "HIL: Can't register device\n"); | ||
285 | goto err3; | ||
286 | } | ||
277 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", | 287 | printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n", |
278 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); | 288 | hil_dev.dev->name, kbid, HILBASE, HIL_IRQ); |
279 | 289 | ||
280 | return 0; | 290 | return 0; |
291 | |||
292 | err3: | ||
293 | hil_do(HIL_INTOFF, NULL, 0); | ||
294 | disable_irq(HIL_IRQ); | ||
295 | free_irq(HIL_IRQ, hil_dev.dev_id); | ||
296 | err2: | ||
297 | release_region(HILBASE + HIL_DATA, 2); | ||
298 | err1: | ||
299 | input_free_device(hil_dev.dev); | ||
300 | hil_dev.dev = NULL; | ||
301 | return err; | ||
281 | } | 302 | } |
282 | 303 | ||
304 | |||
283 | #if defined(CONFIG_PARISC) | 305 | #if defined(CONFIG_PARISC) |
284 | static int __init | 306 | static int __init |
285 | hil_init_chip(struct parisc_device *dev) | 307 | hil_init_chip(struct parisc_device *dev) |
@@ -292,7 +314,7 @@ hil_init_chip(struct parisc_device *dev) | |||
292 | hil_base = dev->hpa.start; | 314 | hil_base = dev->hpa.start; |
293 | hil_irq = dev->irq; | 315 | hil_irq = dev->irq; |
294 | hil_dev.dev_id = dev; | 316 | hil_dev.dev_id = dev; |
295 | 317 | ||
296 | printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq); | 318 | printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq); |
297 | 319 | ||
298 | return hil_keyb_init(); | 320 | return hil_keyb_init(); |
@@ -313,9 +335,6 @@ static struct parisc_driver hil_driver = { | |||
313 | #endif /* CONFIG_PARISC */ | 335 | #endif /* CONFIG_PARISC */ |
314 | 336 | ||
315 | 337 | ||
316 | |||
317 | |||
318 | |||
319 | static int __init hil_init(void) | 338 | static int __init hil_init(void) |
320 | { | 339 | { |
321 | #if defined(CONFIG_PARISC) | 340 | #if defined(CONFIG_PARISC) |
@@ -349,4 +368,3 @@ static void __exit hil_exit(void) | |||
349 | 368 | ||
350 | module_init(hil_init); | 369 | module_init(hil_init); |
351 | module_exit(hil_exit); | 370 | module_exit(hil_exit); |
352 | |||