From 52c1f5704d7555a16641429b2e7af5d26d7b119a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 5 Nov 2006 22:40:03 -0500 Subject: Input: touchscreens - handle errors when registering input devices Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/corgi_ts.c | 30 ++++++++++++++++++------------ drivers/input/touchscreen/gunze.c | 14 +++++++++----- drivers/input/touchscreen/hp680_ts_input.c | 29 +++++++++++++++++++---------- drivers/input/touchscreen/mk712.c | 26 ++++++++++++++------------ drivers/input/touchscreen/mtouch.c | 13 ++++++++----- 5 files changed, 68 insertions(+), 44 deletions(-) (limited to 'drivers/input/touchscreen') diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 66121f6..e294558 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c @@ -175,17 +175,19 @@ static int read_xydata(struct corgi_ts *corgi_ts) static void new_data(struct corgi_ts *corgi_ts) { + struct input_dev *dev = corgi_ts->input; + if (corgi_ts->power_mode != PWR_MODE_ACTIVE) return; if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) return; - input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x); - input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y); - input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); - input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); - input_sync(corgi_ts->input); + input_report_abs(dev, ABS_X, corgi_ts->tc.x); + input_report_abs(dev, ABS_Y, corgi_ts->tc.y); + input_report_abs(dev, ABS_PRESSURE, corgi_ts->tc.pressure); + input_report_key(dev, BTN_TOUCH, corgi_ts->pendown); + input_sync(dev); } static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) @@ -219,12 +221,14 @@ static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer) static void corgi_ts_timer(unsigned long data) { struct corgi_ts *corgits_data = (struct corgi_ts *) data; + ts_interrupt_main(corgits_data, 1); } static irqreturn_t ts_interrupt(int irq, void *dev_id) { struct corgi_ts *corgits_data = dev_id; + ts_interrupt_main(corgits_data, 0); return IRQ_HANDLED; } @@ -272,7 +276,7 @@ static int __init corgits_probe(struct platform_device *pdev) corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); input_dev = input_allocate_device(); if (!corgi_ts || !input_dev) - goto fail; + goto fail1; platform_set_drvdata(pdev, corgi_ts); @@ -281,7 +285,7 @@ static int __init corgits_probe(struct platform_device *pdev) if (corgi_ts->irq_gpio < 0) { err = -ENODEV; - goto fail; + goto fail1; } corgi_ts->input = input_dev; @@ -319,10 +323,12 @@ static int __init corgits_probe(struct platform_device *pdev) if (request_irq(corgi_ts->irq_gpio, ts_interrupt, IRQF_DISABLED, "ts", corgi_ts)) { err = -EBUSY; - goto fail; + goto fail1; } - input_register_device(corgi_ts->input); + err = input_register_device(corgi_ts->input); + if (err) + goto fail2; corgi_ts->power_mode = PWR_MODE_ACTIVE; @@ -331,17 +337,17 @@ static int __init corgits_probe(struct platform_device *pdev) return 0; - fail: input_free_device(input_dev); + fail2: free_irq(corgi_ts->irq_gpio, corgi_ts); + fail1: input_free_device(input_dev); kfree(corgi_ts); return err; - } static int corgits_remove(struct platform_device *pdev) { struct corgi_ts *corgi_ts = platform_get_drvdata(pdev); - free_irq(corgi_ts->irq_gpio, NULL); + free_irq(corgi_ts->irq_gpio, corgi_ts); del_timer_sync(&corgi_ts->timer); corgi_ts->machinfo->put_hsync(); input_unregister_device(corgi_ts->input); diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 817c219..44f397f 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -123,7 +123,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) input_dev = input_allocate_device(); if (!gunze || !input_dev) { err = -ENOMEM; - goto fail; + goto fail1; } gunze->serio = serio; @@ -146,13 +146,17 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; + + err = input_register_device(gunze->dev); + if (err) + goto fail3; - input_register_device(gunze->dev); return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(gunze); return err; } diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 58fca31..2490874 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c @@ -76,38 +76,47 @@ static irqreturn_t hp680_ts_interrupt(int irq, void *dev) static int __init hp680_ts_init(void) { + int err; + hp680_ts_dev = input_allocate_device(); if (!hp680_ts_dev) return -ENOMEM; hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); - hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); - hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN; - hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; - hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX; - hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; + input_set_abs_params(hp680_ts_dev, ABS_X, + HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0); + input_set_abs_params(hp680_ts_dev, ABS_Y, + HP680_TS_ABS_Y_MIN, HP680_TS_ABS_Y_MAX, 0, 0); hp680_ts_dev->name = "HP Jornada touchscreen"; hp680_ts_dev->phys = "hp680_ts/input0"; - input_register_device(hp680_ts_dev); - if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, IRQF_DISABLED, MODNAME, 0) < 0) { printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", HP680_TS_IRQ); - input_unregister_device(hp680_ts_dev); - return -EBUSY; + err = -EBUSY; + goto fail1; } + err = input_register_device(hp680_ts_dev); + if (err) + goto fail2; + return 0; + + fail2: free_irq(HP680_TS_IRQ, NULL); + cancel_delayed_work(&work); + flush_scheduled_work(); + fail1: input_free_device(hp680_ts_dev); + return err; } static void __exit hp680_ts_exit(void) { - free_irq(HP680_TS_IRQ, 0); + free_irq(HP680_TS_IRQ, NULL); cancel_delayed_work(&work); flush_scheduled_work(); input_unregister_device(hp680_ts_dev); diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index 4cbcaa6..44140fe 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c @@ -96,15 +96,13 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) goto end; } - if (~status & MK712_STATUS_TOUCH) - { + if (~status & MK712_STATUS_TOUCH) { debounce = 1; input_report_key(mk712_dev, BTN_TOUCH, 0); goto end; } - if (debounce) - { + if (debounce) { debounce = 0; goto end; } @@ -113,8 +111,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id) input_report_abs(mk712_dev, ABS_X, last_x); input_report_abs(mk712_dev, ABS_Y, last_y); -end: - + end: last_x = inw(mk712_io + MK712_X) & 0x0fff; last_y = inw(mk712_io + MK712_Y) & 0x0fff; input_sync(mk712_dev); @@ -169,13 +166,14 @@ static int __init mk712_init(void) (inw(mk712_io + MK712_STATUS) & 0xf333)) { printk(KERN_WARNING "mk712: device not present\n"); err = -ENODEV; - goto fail; + goto fail1; } - if (!(mk712_dev = input_allocate_device())) { + mk712_dev = input_allocate_device(); + if (!mk712_dev) { printk(KERN_ERR "mk712: not enough memory\n"); err = -ENOMEM; - goto fail; + goto fail1; } mk712_dev->name = "ICS MicroClock MK712 TouchScreen"; @@ -196,13 +194,17 @@ static int __init mk712_init(void) if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) { printk(KERN_WARNING "mk712: unable to get IRQ\n"); err = -EBUSY; - goto fail; + goto fail1; } - input_register_device(mk712_dev); + err = input_register_device(mk712_dev); + if (err) + goto fail2; + return 0; - fail: input_free_device(mk712_dev); + fail2: free_irq(mk712_irq, mk712_dev); + fail1: input_free_device(mk712_dev); release_region(mk712_io, 8); return err; } diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index 3b4c616..c66b399 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -137,7 +137,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) input_dev = input_allocate_device(); if (!mtouch || !input_dev) { err = -ENOMEM; - goto fail; + goto fail1; } mtouch->serio = serio; @@ -160,14 +160,17 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) err = serio_open(serio, drv); if (err) - goto fail; + goto fail2; - input_register_device(mtouch->dev); + err = input_register_device(mtouch->dev); + if (err) + goto fail3; return 0; - fail: serio_set_drvdata(serio, NULL); - input_free_device(input_dev); + fail3: serio_close(serio); + fail2: serio_set_drvdata(serio, NULL); + fail1: input_free_device(input_dev); kfree(mtouch); return err; } -- cgit v1.1