diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2006-09-29 04:59:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-29 12:18:10 -0400 |
commit | 08c67d2a5d1c97b7997dc9589f702d875c63de07 (patch) | |
tree | b0b8f98c0d689dded45514ce801429e7264ad542 | |
parent | aa83aa40ed2ae113d9ee5529cdd9e8c0e5fabe61 (diff) |
[PATCH] ucb1x00-ts: handle errors from input_register_device()
ucb1x00-ts: handle errors from input_register_device()
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/mfd/ucb1x00-ts.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 02776814443e..82938ad6ddbd 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c | |||
@@ -58,6 +58,7 @@ static int adcsync; | |||
58 | static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y) | 58 | static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y) |
59 | { | 59 | { |
60 | struct input_dev *idev = ts->idev; | 60 | struct input_dev *idev = ts->idev; |
61 | |||
61 | input_report_abs(idev, ABS_X, x); | 62 | input_report_abs(idev, ABS_X, x); |
62 | input_report_abs(idev, ABS_Y, y); | 63 | input_report_abs(idev, ABS_Y, y); |
63 | input_report_abs(idev, ABS_PRESSURE, pressure); | 64 | input_report_abs(idev, ABS_PRESSURE, pressure); |
@@ -67,6 +68,7 @@ static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x | |||
67 | static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) | 68 | static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts) |
68 | { | 69 | { |
69 | struct input_dev *idev = ts->idev; | 70 | struct input_dev *idev = ts->idev; |
71 | |||
70 | input_report_abs(idev, ABS_PRESSURE, 0); | 72 | input_report_abs(idev, ABS_PRESSURE, 0); |
71 | input_sync(idev); | 73 | input_sync(idev); |
72 | } | 74 | } |
@@ -189,6 +191,7 @@ static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts) | |||
189 | static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts) | 191 | static inline int ucb1x00_ts_pen_down(struct ucb1x00_ts *ts) |
190 | { | 192 | { |
191 | unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR); | 193 | unsigned int val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR); |
194 | |||
192 | if (machine_is_collie()) | 195 | if (machine_is_collie()) |
193 | return (!(val & (UCB_TS_CR_TSPX_LOW))); | 196 | return (!(val & (UCB_TS_CR_TSPX_LOW))); |
194 | else | 197 | else |
@@ -291,6 +294,7 @@ static int ucb1x00_thread(void *_ts) | |||
291 | static void ucb1x00_ts_irq(int idx, void *id) | 294 | static void ucb1x00_ts_irq(int idx, void *id) |
292 | { | 295 | { |
293 | struct ucb1x00_ts *ts = id; | 296 | struct ucb1x00_ts *ts = id; |
297 | |||
294 | ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); | 298 | ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING); |
295 | wake_up(&ts->irq_wait); | 299 | wake_up(&ts->irq_wait); |
296 | } | 300 | } |
@@ -372,36 +376,43 @@ static int ucb1x00_ts_resume(struct ucb1x00_dev *dev) | |||
372 | static int ucb1x00_ts_add(struct ucb1x00_dev *dev) | 376 | static int ucb1x00_ts_add(struct ucb1x00_dev *dev) |
373 | { | 377 | { |
374 | struct ucb1x00_ts *ts; | 378 | struct ucb1x00_ts *ts; |
379 | struct input_dev *idev; | ||
380 | int err; | ||
375 | 381 | ||
376 | ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); | 382 | ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); |
377 | if (!ts) | 383 | idev = input_allocate_device(); |
378 | return -ENOMEM; | 384 | if (!ts || !idev) { |
379 | 385 | err = -ENOMEM; | |
380 | ts->idev = input_allocate_device(); | 386 | goto fail; |
381 | if (!ts->idev) { | ||
382 | kfree(ts); | ||
383 | return -ENOMEM; | ||
384 | } | 387 | } |
385 | 388 | ||
386 | ts->ucb = dev->ucb; | 389 | ts->ucb = dev->ucb; |
390 | ts->idev = idev; | ||
387 | ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; | 391 | ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; |
388 | 392 | ||
389 | ts->idev->private = ts; | 393 | idev->private = ts; |
390 | ts->idev->name = "Touchscreen panel"; | 394 | idev->name = "Touchscreen panel"; |
391 | ts->idev->id.product = ts->ucb->id; | 395 | idev->id.product = ts->ucb->id; |
392 | ts->idev->open = ucb1x00_ts_open; | 396 | idev->open = ucb1x00_ts_open; |
393 | ts->idev->close = ucb1x00_ts_close; | 397 | idev->close = ucb1x00_ts_close; |
394 | 398 | ||
395 | __set_bit(EV_ABS, ts->idev->evbit); | 399 | __set_bit(EV_ABS, idev->evbit); |
396 | __set_bit(ABS_X, ts->idev->absbit); | 400 | __set_bit(ABS_X, idev->absbit); |
397 | __set_bit(ABS_Y, ts->idev->absbit); | 401 | __set_bit(ABS_Y, idev->absbit); |
398 | __set_bit(ABS_PRESSURE, ts->idev->absbit); | 402 | __set_bit(ABS_PRESSURE, idev->absbit); |
399 | 403 | ||
400 | input_register_device(ts->idev); | 404 | err = input_register_device(idev); |
405 | if (err) | ||
406 | goto fail; | ||
401 | 407 | ||
402 | dev->priv = ts; | 408 | dev->priv = ts; |
403 | 409 | ||
404 | return 0; | 410 | return 0; |
411 | |||
412 | fail: | ||
413 | input_free_device(idev); | ||
414 | kfree(ts); | ||
415 | return err; | ||
405 | } | 416 | } |
406 | 417 | ||
407 | static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) | 418 | static void ucb1x00_ts_remove(struct ucb1x00_dev *dev) |