[media] lirc_sir: make device registration work

Message ID 1338829524-29623-1-git-send-email-jarod@redhat.com (mailing list archive)
State Accepted, archived
Headers

Commit Message

Jarod Wilson June 4, 2012, 5:05 p.m. UTC
  For one, the driver device pointer needs to be filled in, or the lirc core
will refuse to load the driver. And we really need to wire up all the
platform_device bits. This has been tested via the lirc sourceforge tree
and verified to work, been sitting there for months, finally getting
around to sending it. :\

CC: Josh Boyer <jwboyer@redhat.com>
CC: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
 drivers/staging/media/lirc/lirc_sir.c |   60 +++++++++++++++++++++++++++++++-
 1 files changed, 58 insertions(+), 2 deletions(-)
  

Comments

Stefan Lippers-Hollmann July 8, 2012, 8:46 p.m. UTC | #1
Hi

On Monday 04 June 2012, Jarod Wilson wrote:
> For one, the driver device pointer needs to be filled in, or the lirc core
> will refuse to load the driver. And we really need to wire up all the
> platform_device bits. This has been tested via the lirc sourceforge tree
> and verified to work, been sitting there for months, finally getting
> around to sending it. :\

Please consider pushing this[1] patch to 3.5 and -stable (at least 3.0+
is affected, most likely everything >= 2.6.37[2]). I can confirm 
bug - and this patch fixing it on 3.4.4:

serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
smsc_superio_flat(): fir: 0x230, sir: 0x2f8, dma: 03, irq: 3, mode: 0x0e
smsc_ircc_present: can't get sir_base of 0x2f8
[…]
lirc_dev: IR Remote Control driver registered, major 251
lirc_sir: module is from the staging directory, the quality is unknown, you have been warned.
lirc_register_driver: dev pointer not filled in!
lirc_sir: init_chrdev() failed.

After applying this patch lirc_sir loads find and is usable with 
irrecord and lirc.

serial8250: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A
smsc_superio_flat(): fir: 0x230, sir: 0x2f8, dma: 03, irq: 3, mode: 0x0e
smsc_ircc_present: can't get sir_base of 0x2f8
[…]
lirc_dev: IR Remote Control driver registered, major 251 
lirc_sir: module is from the staging directory, the quality is unknown, you have been warned.
platform lirc_dev.0: lirc_dev: driver lirc_sir registered at minor = 0
lirc_sir: I/O port 0x02f8, IRQ 3.
lirc_sir: Installed

Without this patch lirc_sir can't even get loaded, the alternative 
would be to mark it as BROKEN for <<3.6.

Regards
	Stefan Lippers-Hollmann

[1]	http://git.kernel.org/?p=linux/kernel/git/next/linux-next.git;a=commitdiff;h=4b71ca6bce8fab3d08c61bf330e781f957934ae1
	http://patchwork.linuxtv.org/patch/11579/
[2]	RedHat bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=557210 [2.6.31.9-174.fc12.i686.PAE]
	Ubuntu launchpad: https://bugs.launchpad.net/ubuntu/+source/lirc/+bug/912251 [3.0.0-12-generic]
	Debian BTS: http://bugs.debian.org/680762 [3.2+]
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  

Patch

diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index 945d962..4afc3b4 100644
--- a/drivers/staging/media/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
@@ -52,6 +52,7 @@ 
 #include <linux/io.h>
 #include <asm/irq.h>
 #include <linux/fcntl.h>
+#include <linux/platform_device.h>
 #ifdef LIRC_ON_SA1100
 #include <asm/hardware.h>
 #ifdef CONFIG_SA1100_COLLIE
@@ -487,9 +488,11 @@  static struct lirc_driver driver = {
 	.owner		= THIS_MODULE,
 };
 
+static struct platform_device *lirc_sir_dev;
 
 static int init_chrdev(void)
 {
+	driver.dev = &lirc_sir_dev->dev;
 	driver.minor = lirc_register_driver(&driver);
 	if (driver.minor < 0) {
 		printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
@@ -1215,20 +1218,71 @@  static int init_lirc_sir(void)
 	return 0;
 }
 
+static int __devinit lirc_sir_probe(struct platform_device *dev)
+{
+	return 0;
+}
+
+static int __devexit lirc_sir_remove(struct platform_device *dev)
+{
+	return 0;
+}
+
+static struct platform_driver lirc_sir_driver = {
+	.probe		= lirc_sir_probe,
+	.remove		= __devexit_p(lirc_sir_remove),
+	.driver		= {
+		.name	= "lirc_sir",
+		.owner	= THIS_MODULE,
+	},
+};
 
 static int __init lirc_sir_init(void)
 {
 	int retval;
 
+	retval = platform_driver_register(&lirc_sir_driver);
+	if (retval) {
+		printk(KERN_ERR LIRC_DRIVER_NAME ": Platform driver register "
+		       "failed!\n");
+		return -ENODEV;
+	}
+
+	lirc_sir_dev = platform_device_alloc("lirc_dev", 0);
+	if (!lirc_sir_dev) {
+		printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device alloc "
+		       "failed!\n");
+		retval = -ENOMEM;
+		goto pdev_alloc_fail;
+	}
+
+	retval = platform_device_add(lirc_sir_dev);
+	if (retval) {
+		printk(KERN_ERR LIRC_DRIVER_NAME ": Platform device add "
+		       "failed!\n");
+		retval = -ENODEV;
+		goto pdev_add_fail;
+	}
+
 	retval = init_chrdev();
 	if (retval < 0)
-		return retval;
+		goto fail;
+
 	retval = init_lirc_sir();
 	if (retval) {
 		drop_chrdev();
-		return retval;
+		goto fail;
 	}
+
 	return 0;
+
+fail:
+	platform_device_del(lirc_sir_dev);
+pdev_add_fail:
+	platform_device_put(lirc_sir_dev);
+pdev_alloc_fail:
+	platform_driver_unregister(&lirc_sir_driver);
+	return retval;
 }
 
 static void __exit lirc_sir_exit(void)
@@ -1236,6 +1290,8 @@  static void __exit lirc_sir_exit(void)
 	drop_hardware();
 	drop_chrdev();
 	drop_port();
+	platform_device_unregister(lirc_sir_dev);
+	platform_driver_unregister(&lirc_sir_driver);
 	printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
 }