- drivers-media-handle-errors-from-input_register_device.patch removed from -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     drivers/media: handle errors from input_register_device()
has been removed from the -mm tree.  Its filename was
     drivers-media-handle-errors-from-input_register_device.patch

This patch was dropped because it was merged into mainline or a subsystem tree

------------------------------------------------------
Subject: drivers/media: handle errors from input_register_device()
From: Dmitry Torokhov <dtor@xxxxxxxxxxxxx>

drivers/media: handle errors from input_register_device()

Also sprinkled some input_sync() throughout the code.

Signed-off-by: Dmitry Torokhov <dtor@xxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 drivers/media/dvb/cinergyT2/cinergyT2.c           |   13 +
 drivers/media/dvb/dvb-usb/dvb-usb-remote.c        |   37 ++--
 drivers/media/dvb/ttpci/av7110_ir.c               |   25 ++
 drivers/media/dvb/ttpci/budget-ci.c               |   42 ++--
 drivers/media/dvb/ttusb-dec/ttusb_dec.c           |   11 +
 drivers/media/video/bt8xx/bttv-input.c            |  101 ++++++------
 drivers/media/video/cx88/cx88-input.c             |   77 +++++----
 drivers/media/video/ir-kbd-i2c.c                  |   43 +++--
 drivers/media/video/saa7134/saa7134-input.c       |   48 ++++-
 drivers/media/video/usbvideo/quickcam_messenger.c |    9 -
 10 files changed, 257 insertions(+), 149 deletions(-)

diff -puN drivers/media/dvb/cinergyT2/cinergyT2.c~drivers-media-handle-errors-from-input_register_device drivers/media/dvb/cinergyT2/cinergyT2.c
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -746,6 +746,7 @@ static void cinergyt2_query_rc (void *da
 				dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
 				input_report_key(cinergyt2->rc_input_dev,
 						 cinergyt2->rc_input_event, 0);
+				input_sync(cinergyt2->rc_input_dev);
 				cinergyt2->rc_input_event = KEY_MAX;
 			}
 			cinergyt2->rc_last_code = ~0;
@@ -783,6 +784,7 @@ static void cinergyt2_query_rc (void *da
 			dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
 			input_report_key(cinergyt2->rc_input_dev,
 					 cinergyt2->rc_input_event, 1);
+			input_sync(cinergyt2->rc_input_dev);
 			cinergyt2->rc_last_code = rc_events[n].value;
 		}
 	}
@@ -798,8 +800,9 @@ static int cinergyt2_register_rc(struct 
 {
 	struct input_dev *input_dev;
 	int i;
+	int err;
 
-	cinergyt2->rc_input_dev = input_dev = input_allocate_device();
+	input_dev = input_allocate_device();
 	if (!input_dev)
 		return -ENOMEM;
 
@@ -817,7 +820,13 @@ static int cinergyt2_register_rc(struct 
 	input_dev->keycodesize = 0;
 	input_dev->keycodemax = 0;
 
-	input_register_device(cinergyt2->rc_input_dev);
+	err = input_register_device(input_dev);
+	if (err) {
+		input_free_device(input_dev);
+		return err;
+	}
+
+	cinergyt2->rc_input_dev = input_dev;
 	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
 
 	return 0;
diff -puN drivers/media/dvb/dvb-usb/dvb-usb-remote.c~drivers-media-handle-errors-from-input_register_device drivers/media/dvb/dvb-usb/dvb-usb-remote.c
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -89,7 +89,9 @@ schedule:
 
 int dvb_usb_remote_init(struct dvb_usb_device *d)
 {
+	struct input_dev *input_dev;
 	int i;
+	int err;
 
 	if (d->props.rc_key_map == NULL ||
 		d->props.rc_query == NULL ||
@@ -99,23 +101,24 @@ int dvb_usb_remote_init(struct dvb_usb_d
 	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
 	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
 
-	d->rc_input_dev = input_allocate_device();
-	if (!d->rc_input_dev)
+	input_dev = input_allocate_device();
+	if (!input_dev)
 		return -ENOMEM;
 
-	d->rc_input_dev->evbit[0] = BIT(EV_KEY);
-	d->rc_input_dev->keycodesize = sizeof(unsigned char);
-	d->rc_input_dev->keycodemax = KEY_MAX;
-	d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
-	d->rc_input_dev->phys = d->rc_phys;
-	usb_to_input_id(d->udev, &d->rc_input_dev->id);
-	d->rc_input_dev->cdev.dev = &d->udev->dev;
+	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = KEY_MAX;
+	input_dev->name = "IR-receiver inside an USB DVB receiver";
+	input_dev->phys = d->rc_phys;
+	usb_to_input_id(d->udev, &input_dev->id);
+	input_dev->cdev.dev = &d->udev->dev;
 
 	/* set the bits for the keys */
 	deb_rc("key map size: %d\n", d->props.rc_key_map_size);
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
-		deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
-		set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
+		deb_rc("setting bit for event %d item %d\n",
+			d->props.rc_key_map[i].event, i);
+		set_bit(d->props.rc_key_map[i].event, input_dev->keybit);
 	}
 
 	/* Start the remote-control polling. */
@@ -123,10 +126,16 @@ int dvb_usb_remote_init(struct dvb_usb_d
 		d->props.rc_interval = 100; /* default */
 
 	/* setting these two values to non-zero, we have to manage key repeats */
-	d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval;
-	d->rc_input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
+	input_dev->rep[REP_PERIOD] = d->props.rc_interval;
+	input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
 
-	input_register_device(d->rc_input_dev);
+	err = input_register_device(input_dev);
+	if (err) {
+		input_free_device(input_dev);
+		return err;
+	}
+
+	d->rc_input_dev = input_dev;
 
 	INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
 
diff -puN drivers/media/dvb/ttpci/av7110_ir.c~drivers-media-handle-errors-from-input_register_device drivers/media/dvb/ttpci/av7110_ir.c
--- a/drivers/media/dvb/ttpci/av7110_ir.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/dvb/ttpci/av7110_ir.c
@@ -48,7 +48,8 @@ static void av7110_emit_keyup(unsigned l
 	if (!data || !test_bit(data, input_dev->key))
 		return;
 
-	input_event(input_dev, EV_KEY, data, !!0);
+	input_report_key(input_dev, data, 0);
+	input_sync(input_dev);
 }
 
 
@@ -115,14 +116,17 @@ static void av7110_emit_key(unsigned lon
 		del_timer(&keyup_timer);
 		if (keyup_timer.data != keycode || new_toggle != old_toggle) {
 			delay_timer_finished = 0;
-			input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
-			input_event(input_dev, EV_KEY, keycode, !0);
-		} else
-			if (delay_timer_finished)
-				input_event(input_dev, EV_KEY, keycode, 2);
+			input_event(input_dev, EV_KEY, keyup_timer.data, 0);
+			input_event(input_dev, EV_KEY, keycode, 1);
+			input_sync(input_dev);
+		} else if (delay_timer_finished) {
+			input_event(input_dev, EV_KEY, keycode, 2);
+			input_sync(input_dev);
+		}
 	} else {
 		delay_timer_finished = 0;
-		input_event(input_dev, EV_KEY, keycode, !0);
+		input_event(input_dev, EV_KEY, keycode, 1);
+		input_sync(input_dev);
 	}
 
 	keyup_timer.expires = jiffies + UP_TIMEOUT;
@@ -211,6 +215,7 @@ static void ir_handler(struct av7110 *av
 int __devinit av7110_ir_init(struct av7110 *av7110)
 {
 	static struct proc_dir_entry *e;
+	int err;
 
 	if (av_cnt >= sizeof av_list/sizeof av_list[0])
 		return -ENOSPC;
@@ -231,7 +236,11 @@ int __devinit av7110_ir_init(struct av71
 		set_bit(EV_KEY, input_dev->evbit);
 		set_bit(EV_REP, input_dev->evbit);
 		input_register_keys();
-		input_register_device(input_dev);
+		err = input_register_device(input_dev);
+		if (err) {
+			input_free_device(input_dev);
+			return err;
+		}
 		input_dev->timer.function = input_repeat_key;
 
 		e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
diff -puN drivers/media/dvb/ttpci/budget-ci.c~drivers-media-handle-errors-from-input_register_device drivers/media/dvb/ttpci/budget-ci.c
--- a/drivers/media/dvb/ttpci/budget-ci.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/dvb/ttpci/budget-ci.c
@@ -143,14 +143,14 @@ static void msp430_ir_debounce(unsigned 
 	struct input_dev *dev = (struct input_dev *) data;
 
 	if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
-		input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
-		return;
+		input_event(dev, EV_KEY, key_map[dev->repeat_key], 0);
+	} else {
+		dev->rep[0] = 0;
+		dev->timer.expires = jiffies + HZ * 350 / 1000;
+		add_timer(&dev->timer);
+		input_event(dev, EV_KEY, key_map[dev->repeat_key], 2);	/* REPEAT */
 	}
-
-	dev->rep[0] = 0;
-	dev->timer.expires = jiffies + HZ * 350 / 1000;
-	add_timer(&dev->timer);
-	input_event(dev, EV_KEY, key_map[dev->repeat_key], 2);	/* REPEAT */
+	input_sync(dev);
 }
 
 static void msp430_ir_interrupt(unsigned long data)
@@ -169,7 +169,7 @@ static void msp430_ir_interrupt(unsigned
 				return;
 			}
 			del_timer(&dev->timer);
-			input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
+			input_event(dev, EV_KEY, key_map[dev->repeat_key], 0);
 		}
 
 		if (!key_map[code]) {
@@ -177,15 +177,14 @@ static void msp430_ir_interrupt(unsigned
 			return;
 		}
 
+		input_event(dev, EV_KEY, key_map[code], 1);
+		input_sync(dev);
+
 		/* initialize debounce and repeat */
 		dev->repeat_key = code;
 		/* Zenith remote _always_ sends 2 sequences */
 		dev->rep[0] = ~0;
-		/* 350 milliseconds */
-		dev->timer.expires = jiffies + HZ * 350 / 1000;
-		/* MAKE */
-		input_event(dev, EV_KEY, key_map[code], !0);
-		add_timer(&dev->timer);
+		mod_timer(&dev->timer, jiffies + msecs_to_jiffies(350));
 	}
 }
 
@@ -194,8 +193,9 @@ static int msp430_ir_init(struct budget_
 	struct saa7146_dev *saa = budget_ci->budget.dev;
 	struct input_dev *input_dev;
 	int i;
+	int err;
 
-	budget_ci->input_dev = input_dev = input_allocate_device();
+	input_dev = input_allocate_device();
 	if (!input_dev)
 		return -ENOMEM;
 
@@ -208,10 +208,16 @@ static int msp430_ir_init(struct budget_
 		if (key_map[i])
 			set_bit(key_map[i], input_dev->keybit);
 
-	input_register_device(budget_ci->input_dev);
+	err = input_register_device(input_dev);
+	if (err) {
+		input_free_device(input_dev);
+		return err;
+	}
 
 	input_dev->timer.function = msp430_ir_debounce;
 
+	budget_ci->input_dev = input_dev;
+
 	saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
 	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
 
@@ -226,8 +232,10 @@ static void msp430_ir_deinit(struct budg
 	saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
 	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
 
-	if (del_timer(&dev->timer))
-		input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
+	if (del_timer(&dev->timer)) {
+		input_event(dev, EV_KEY, key_map[dev->repeat_key], 0);
+		input_sync(dev);
+	}
 
 	input_unregister_device(dev);
 }
diff -puN drivers/media/dvb/ttusb-dec/ttusb_dec.c~drivers-media-handle-errors-from-input_register_device drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -238,6 +238,7 @@ static void ttusb_dec_handle_irq( struct
 		 * for now lets report each signal as a key down and up*/
 		dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
 		input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+		input_sync(dec->rc_input_dev);
 		input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
 		input_sync(dec->rc_input_dev);
 	}
@@ -1188,11 +1189,12 @@ static int ttusb_init_rc( struct ttusb_d
 	struct input_dev *input_dev;
 	u8 b[] = { 0x00, 0x01 };
 	int i;
+	int err;
 
 	usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
 	strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
 
-	dec->rc_input_dev = input_dev = input_allocate_device();
+	input_dev = input_allocate_device();
 	if (!input_dev)
 		return -ENOMEM;
 
@@ -1206,8 +1208,13 @@ static int ttusb_init_rc( struct ttusb_d
 	for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
 		  set_bit(rc_keys[i], input_dev->keybit);
 
-	input_register_device(input_dev);
+	err = input_register_device(input_dev);
+	if (err) {
+		input_free_device(input_dev);
+		return err;
+	}
 
+	dec->rc_input_dev = input_dev;
 	if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
 		printk("%s: usb_submit_urb failed\n",__FUNCTION__);
 	/* enable irq pipe */
diff -puN drivers/media/video/bt8xx/bttv-input.c~drivers-media-handle-errors-from-input_register_device drivers/media/video/bt8xx/bttv-input.c
--- a/drivers/media/video/bt8xx/bttv-input.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/video/bt8xx/bttv-input.c
@@ -259,24 +259,59 @@ static void bttv_rc5_timer_keyup(unsigne
 
 /* ---------------------------------------------------------------------- */
 
+static void bttv_ir_start(struct bttv *btv, struct bttv_ir *ir)
+{
+	if (ir->polling) {
+		init_timer(&ir->timer);
+		ir->timer.function = bttv_input_timer;
+		ir->timer.data     = (unsigned long)btv;
+		ir->timer.expires  = jiffies + HZ;
+		add_timer(&ir->timer);
+	} else if (ir->rc5_gpio) {
+		/* set timer_end for code completion */
+		init_timer(&ir->timer_end);
+		ir->timer_end.function = bttv_rc5_timer_end;
+		ir->timer_end.data = (unsigned long)ir;
+
+		init_timer(&ir->timer_keyup);
+		ir->timer_keyup.function = bttv_rc5_timer_keyup;
+		ir->timer_keyup.data = (unsigned long)ir;
+	}
+}
+
+static void bttv_ir_stop(struct bttv *btv)
+{
+	if (btv->remote->polling) {
+		del_timer_sync(&btv->remote->timer);
+		flush_scheduled_work();
+	}
+
+	if (btv->remote->rc5_gpio) {
+		u32 gpio;
+
+		del_timer_sync(&btv->remote->timer_end);
+		flush_scheduled_work();
+
+		gpio = bttv_gpio_read(&btv->c);
+		bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
+	}
+}
+
 int bttv_input_init(struct bttv *btv)
 {
 	struct bttv_ir *ir;
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	struct input_dev *input_dev;
 	int ir_type = IR_TYPE_OTHER;
+	int err = -ENOMEM;
 
 	if (!btv->has_remote)
 		return -ENODEV;
 
 	ir = kzalloc(sizeof(*ir),GFP_KERNEL);
 	input_dev = input_allocate_device();
-	if (!ir || !input_dev) {
-		kfree(ir);
-		input_free_device(input_dev);
-		return -ENOMEM;
-	}
-	memset(ir,0,sizeof(*ir));
+	if (!ir || !input_dev)
+		goto err_out_free;
 
 	/* detect & configure */
 	switch (btv->c.type) {
@@ -348,10 +383,9 @@ int bttv_input_init(struct bttv *btv)
 		break;
 	}
 	if (NULL == ir_codes) {
-		dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type);
-		kfree(ir);
-		input_free_device(input_dev);
-		return -ENODEV;
+		dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type);
+		err = -ENODEV;
+		goto err_out_free;
 	}
 
 	if (ir->rc5_gpio) {
@@ -389,32 +423,26 @@ int bttv_input_init(struct bttv *btv)
 	input_dev->cdev.dev = &btv->c.pci->dev;
 
 	btv->remote = ir;
-	if (ir->polling) {
-		init_timer(&ir->timer);
-		ir->timer.function = bttv_input_timer;
-		ir->timer.data     = (unsigned long)btv;
-		ir->timer.expires  = jiffies + HZ;
-		add_timer(&ir->timer);
-	} else if (ir->rc5_gpio) {
-		/* set timer_end for code completion */
-		init_timer(&ir->timer_end);
-		ir->timer_end.function = bttv_rc5_timer_end;
-		ir->timer_end.data = (unsigned long)ir;
-
-		init_timer(&ir->timer_keyup);
-		ir->timer_keyup.function = bttv_rc5_timer_keyup;
-		ir->timer_keyup.data = (unsigned long)ir;
-	}
+	bttv_ir_start(btv, ir);
 
 	/* all done */
-	input_register_device(btv->remote->dev);
-	printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
+	err = input_register_device(btv->remote->dev);
+	if (err)
+		goto err_out_stop;
 
 	/* the remote isn't as bouncy as a keyboard */
 	ir->dev->rep[REP_DELAY] = repeat_delay;
 	ir->dev->rep[REP_PERIOD] = repeat_period;
 
 	return 0;
+
+ err_out_stop:
+	bttv_ir_stop(btv);
+	btv->remote = NULL;
+ err_out_free:
+	input_free_device(input_dev);
+	kfree(ir);
+	return err;
 }
 
 void bttv_input_fini(struct bttv *btv)
@@ -422,22 +450,7 @@ void bttv_input_fini(struct bttv *btv)
 	if (btv->remote == NULL)
 		return;
 
-	if (btv->remote->polling) {
-		del_timer_sync(&btv->remote->timer);
-		flush_scheduled_work();
-	}
-
-
-	if (btv->remote->rc5_gpio) {
-		u32 gpio;
-
-		del_timer_sync(&btv->remote->timer_end);
-		flush_scheduled_work();
-
-		gpio = bttv_gpio_read(&btv->c);
-		bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
-	}
-
+	bttv_ir_stop(btv);
 	input_unregister_device(btv->remote->dev);
 	kfree(btv->remote);
 	btv->remote = NULL;
diff -puN drivers/media/video/cx88/cx88-input.c~drivers-media-handle-errors-from-input_register_device drivers/media/video/cx88/cx88-input.c
--- a/drivers/media/video/cx88/cx88-input.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/video/cx88/cx88-input.c
@@ -155,6 +155,35 @@ static void cx88_ir_work(void *data)
 	mod_timer(&ir->timer, timeout);
 }
 
+static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
+{
+	if (ir->polling) {
+		INIT_WORK(&ir->work, cx88_ir_work, ir);
+		init_timer(&ir->timer);
+		ir->timer.function = ir_timer;
+		ir->timer.data = (unsigned long)ir;
+		schedule_work(&ir->work);
+	}
+	if (ir->sampling) {
+		core->pci_irqmask |= (1 << 18);	/* IR_SMP_INT */
+		cx_write(MO_DDS_IO, 0xa80a80);	/* 4 kHz sample rate */
+		cx_write(MO_DDSCFG_IO, 0x5);	/* enable */
+	}
+}
+
+static void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
+{
+	if (ir->sampling) {
+		cx_write(MO_DDSCFG_IO, 0x0);
+		core->pci_irqmask &= ~(1 << 18);
+	}
+
+	if (ir->polling) {
+		del_timer_sync(&ir->timer);
+		flush_scheduled_work();
+	}
+}
+
 /* ---------------------------------------------------------------------- */
 
 int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
@@ -163,14 +192,12 @@ int cx88_ir_init(struct cx88_core *core,
 	struct input_dev *input_dev;
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	int ir_type = IR_TYPE_OTHER;
+	int err = -ENOMEM;
 
 	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
 	input_dev = input_allocate_device();
-	if (!ir || !input_dev) {
-		kfree(ir);
-		input_free_device(input_dev);
-		return -ENOMEM;
-	}
+	if (!ir || !input_dev)
+		goto err_out_free;
 
 	ir->input = input_dev;
 
@@ -280,9 +307,8 @@ int cx88_ir_init(struct cx88_core *core,
 	}
 
 	if (NULL == ir_codes) {
-		kfree(ir);
-		input_free_device(input_dev);
-		return -ENODEV;
+		err = -ENODEV;
+		goto err_out_free;
 	}
 
 	/* init input device */
@@ -307,23 +333,22 @@ int cx88_ir_init(struct cx88_core *core,
 	ir->core = core;
 	core->ir = ir;
 
-	if (ir->polling) {
-		INIT_WORK(&ir->work, cx88_ir_work, ir);
-		init_timer(&ir->timer);
-		ir->timer.function = ir_timer;
-		ir->timer.data = (unsigned long)ir;
-		schedule_work(&ir->work);
-	}
-	if (ir->sampling) {
-		core->pci_irqmask |= (1 << 18);	/* IR_SMP_INT */
-		cx_write(MO_DDS_IO, 0xa80a80);	/* 4 kHz sample rate */
-		cx_write(MO_DDSCFG_IO, 0x5);	/* enable */
-	}
+	cx88_ir_start(core, ir);
 
 	/* all done */
-	input_register_device(ir->input);
+	err = input_register_device(ir->input);
+	if (err)
+		goto err_out_stop;
 
 	return 0;
+
+ err_out_stop:
+	cx88_ir_stop(core, ir);
+	core->ir = NULL;
+ err_out_free:
+	input_free_device(input_dev);
+	kfree(ir);
+	return err;
 }
 
 int cx88_ir_fini(struct cx88_core *core)
@@ -334,15 +359,7 @@ int cx88_ir_fini(struct cx88_core *core)
 	if (NULL == ir)
 		return 0;
 
-	if (ir->sampling) {
-		cx_write(MO_DDSCFG_IO, 0x0);
-		core->pci_irqmask &= ~(1 << 18);
-	}
-	if (ir->polling) {
-		del_timer(&ir->timer);
-		flush_scheduled_work();
-	}
-
+	cx88_ir_stop(core, ir);
 	input_unregister_device(ir->input);
 	kfree(ir);
 
diff -puN drivers/media/video/ir-kbd-i2c.c~drivers-media-handle-errors-from-input_register_device drivers/media/video/ir-kbd-i2c.c
--- a/drivers/media/video/ir-kbd-i2c.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/video/ir-kbd-i2c.c
@@ -305,15 +305,14 @@ static int ir_attach(struct i2c_adapter 
 	int ir_type;
 	struct IR_i2c *ir;
 	struct input_dev *input_dev;
+	int err;
 
 	ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!ir || !input_dev) {
-		input_free_device(input_dev);
-		kfree(ir);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out_free;
 	}
-	memset(ir,0,sizeof(*ir));
 
 	ir->c = client_template;
 	ir->input = input_dev;
@@ -361,26 +360,27 @@ static int ir_attach(struct i2c_adapter 
 		break;
 	default:
 		/* shouldn't happen */
-		printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n",addr);
-		kfree(ir);
-		return -1;
+		printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
+		err = -ENODEV;
+		goto err_out_free;
 	}
 
 	/* Sets name */
 	snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
-	ir->ir_codes=ir_codes;
+	ir->ir_codes = ir_codes;
 
 	/* register i2c device
 	 * At device register, IR codes may be changed to be
 	 * board dependent.
 	 */
-	i2c_attach_client(&ir->c);
+	err = i2c_attach_client(&ir->c);
+	if (err)
+		goto err_out_free;
 
 	/* If IR not supported or disabled, unregisters driver */
 	if (ir->get_key == NULL) {
-		i2c_detach_client(&ir->c);
-		kfree(ir);
-		return -1;
+		err = -ENODEV;
+		goto err_out_detach;
 	}
 
 	/* Phys addr can only be set after attaching (for ir->c.dev.bus_id) */
@@ -389,15 +389,17 @@ static int ir_attach(struct i2c_adapter 
 		 ir->c.dev.bus_id);
 
 	/* init + register input device */
-	ir_input_init(input_dev,&ir->ir,ir_type,ir->ir_codes);
+	ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
 	input_dev->id.bustype = BUS_I2C;
 	input_dev->name       = ir->c.name;
 	input_dev->phys       = ir->phys;
 
-	/* register event device */
-	input_register_device(ir->input);
+	err = input_register_device(ir->input);
+	if (err)
+		goto err_out_detach;
+
 	printk(DEVNAME ": %s detected at %s [%s]\n",
-	       ir->input->name,ir->input->phys,adap->name);
+	       ir->input->name, ir->input->phys, adap->name);
 
 	/* start polling via eventd */
 	INIT_WORK(&ir->work, ir_work, ir);
@@ -407,6 +409,13 @@ static int ir_attach(struct i2c_adapter 
 	schedule_work(&ir->work);
 
 	return 0;
+
+ err_out_detach:
+	i2c_detach_client(&ir->c);
+ err_out_free:
+	input_free_device(input_dev);
+	kfree(ir);
+	return err;
 }
 
 static int ir_detach(struct i2c_client *client)
@@ -414,7 +423,7 @@ static int ir_detach(struct i2c_client *
 	struct IR_i2c *ir = i2c_get_clientdata(client);
 
 	/* kill outstanding polls */
-	del_timer(&ir->timer);
+	del_timer_sync(&ir->timer);
 	flush_scheduled_work();
 
 	/* unregister devices */
diff -puN drivers/media/video/saa7134/saa7134-input.c~drivers-media-handle-errors-from-input_register_device drivers/media/video/saa7134/saa7134-input.c
--- a/drivers/media/video/saa7134/saa7134-input.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/video/saa7134/saa7134-input.c
@@ -131,6 +131,23 @@ static void saa7134_input_timer(unsigned
 	mod_timer(&ir->timer, timeout);
 }
 
+static void saa7134_ir_start(struct saa7134_dev *dev, struct saa7134_ir *ir)
+{
+	if (ir->polling) {
+		init_timer(&ir->timer);
+		ir->timer.function = saa7134_input_timer;
+		ir->timer.data     = (unsigned long)dev;
+		ir->timer.expires  = jiffies + HZ;
+		add_timer(&ir->timer);
+	}
+}
+
+static void saa7134_ir_stop(struct saa7134_dev *dev)
+{
+	if (dev->remote->polling)
+		del_timer_sync(&dev->remote->timer);
+}
+
 int saa7134_input_init1(struct saa7134_dev *dev)
 {
 	struct saa7134_ir *ir;
@@ -141,6 +158,7 @@ int saa7134_input_init1(struct saa7134_d
 	u32 mask_keyup   = 0;
 	int polling      = 0;
 	int ir_type      = IR_TYPE_OTHER;
+	int err;
 
 	if (dev->has_remote != SAA7134_REMOTE_GPIO)
 		return -ENODEV;
@@ -279,9 +297,8 @@ int saa7134_input_init1(struct saa7134_d
 	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
 	input_dev = input_allocate_device();
 	if (!ir || !input_dev) {
-		kfree(ir);
-		input_free_device(input_dev);
-		return -ENOMEM;
+		err = -ENOMEM;
+		goto err_out_free;
 	}
 
 	ir->dev = input_dev;
@@ -312,18 +329,22 @@ int saa7134_input_init1(struct saa7134_d
 	}
 	input_dev->cdev.dev = &dev->pci->dev;
 
-	/* all done */
 	dev->remote = ir;
-	if (ir->polling) {
-		init_timer(&ir->timer);
-		ir->timer.function = saa7134_input_timer;
-		ir->timer.data     = (unsigned long)dev;
-		ir->timer.expires  = jiffies + HZ;
-		add_timer(&ir->timer);
-	}
+	saa7134_ir_start(dev, ir);
+
+	err = input_register_device(ir->dev);
+	if (err)
+		goto err_out_stop;
 
-	input_register_device(ir->dev);
 	return 0;
+
+ err_out_stop:
+	saa7134_ir_stop(dev);
+	dev->remote = NULL;
+ err_out_free:
+	input_free_device(input_dev);
+	kfree(ir);
+	return err;
 }
 
 void saa7134_input_fini(struct saa7134_dev *dev)
@@ -331,8 +352,7 @@ void saa7134_input_fini(struct saa7134_d
 	if (NULL == dev->remote)
 		return;
 
-	if (dev->remote->polling)
-		del_timer_sync(&dev->remote->timer);
+	saa7134_ir_stop(dev);
 	input_unregister_device(dev->remote->dev);
 	kfree(dev->remote);
 	dev->remote = NULL;
diff -puN drivers/media/video/usbvideo/quickcam_messenger.c~drivers-media-handle-errors-from-input_register_device drivers/media/video/usbvideo/quickcam_messenger.c
--- a/drivers/media/video/usbvideo/quickcam_messenger.c~drivers-media-handle-errors-from-input_register_device
+++ a/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -86,6 +86,7 @@ MODULE_DEVICE_TABLE(usb, qcm_table);
 static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
 {
 	struct input_dev *input_dev;
+	int error;
 
 	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
 	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
@@ -106,7 +107,13 @@ static void qcm_register_input(struct qc
 
 	input_dev->private = cam;
 
-	input_register_device(cam->input);
+	error = input_register_device(cam->input);
+	if (error) {
+		warn("Failed to register camera's input device, err: %d\n",
+		     error);
+		input_free_device(cam->input);
+		cam->input = NULL;
+	}
 }
 
 static void qcm_unregister_input(struct qcm *cam)
_

Patches currently in -mm which might be from dtor@xxxxxxxxxxxxx are

git-acpi.patch
git-dvb.patch
git-input.patch
git-netdev-all.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux