From patchwork Sun Dec 13 12:14:50 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauro Carvalho Chehab X-Patchwork-Id: 67000 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nBDCG8Ct030890 for ; Sun, 13 Dec 2009 12:16:08 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752920AbZLMMPj (ORCPT ); Sun, 13 Dec 2009 07:15:39 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752939AbZLMMPi (ORCPT ); Sun, 13 Dec 2009 07:15:38 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45514 "HELO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1752911AbZLMMPh (ORCPT ); Sun, 13 Dec 2009 07:15:37 -0500 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nBDCFBM7018602 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 13 Dec 2009 07:15:11 -0500 Received: from [172.17.92.2] (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nBDCEwYO015338 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 13 Dec 2009 07:15:02 -0500 Message-ID: <4B24DABA.9040007@redhat.com> Date: Sun, 13 Dec 2009 10:14:50 -0200 From: Mauro Carvalho Chehab User-Agent: Thunderbird 2.0.0.22 (X11/20090609) MIME-Version: 1.0 To: Dmitry Torokhov CC: Krzysztof Halasa , Jon Smirl , hermann pitton , Christoph Bartelmus , awalls@radix.net, j@jannau.net, jarod@redhat.com, jarod@wilsonet.com, kraxel@redhat.com, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, linux-media@vger.kernel.org, superm1@ubuntu.com Subject: Re: [RFC] What are the goals for the architecture of an in-kernel IR system? References: <20091204220708.GD25669@core.coreip.homeip.net> <9e4733910912041628g5bedc9d2jbee3b0861aeb5511@mail.gmail.com> <1260070593.3236.6.camel@pc07.localdom.local> <20091206065512.GA14651@core.coreip.homeip.net> <4B1B99A5.2080903@redhat.com> <9e4733910912060952h4aad49dake8e8486acb6566bc@mail.gmail.com> <20091207184153.GD998@core.coreip.homeip.net> In-Reply-To: <20091207184153.GD998@core.coreip.homeip.net> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org --- master.orig/linux/drivers/media/IR/Makefile +++ master/linux/drivers/media/IR/Makefile @@ -1,5 +1,5 @@ ir-common-objs := ir-functions.o ir-keymaps.o -ir-core-objs := ir-keytable.o +ir-core-objs := ir-keytable.o ir-sysfs.o obj-$(CONFIG_IR_CORE) += ir-core.o obj-$(CONFIG_VIDEO_IR) += ir-common.o --- master.orig/linux/drivers/media/IR/ir-keytable.c +++ master/linux/drivers/media/IR/ir-keytable.c @@ -448,12 +448,21 @@ int ir_input_register(struct input_dev * input_set_drvdata(input_dev, ir_dev); rc = input_register_device(input_dev); + if (rc < 0) + goto err; + + rc = ir_register_class(input_dev); if (rc < 0) { - kfree(rc_tab->scan); - kfree(ir_dev); - input_set_drvdata(input_dev, NULL); + input_unregister_device(input_dev); + goto err; } + return 0; + +err: + kfree(rc_tab->scan); + kfree(ir_dev); + input_set_drvdata(input_dev, NULL); return rc; } EXPORT_SYMBOL_GPL(ir_input_register); @@ -473,6 +482,8 @@ void ir_input_unregister(struct input_de kfree(rc_tab->scan); rc_tab->scan = NULL; + ir_unregister_class(dev); + kfree(ir_dev); input_unregister_device(dev); } --- /dev/null +++ master/linux/drivers/media/IR/ir-sysfs.c @@ -0,0 +1,94 @@ +/* ir-register.c - handle IR scancode->keycode tables + * + * Copyright (C) 2009 by Mauro Carvalho Chehab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#define IRRCV_NUM_DEVICES 256 + +unsigned long ir_core_dev_number; + +static struct class *ir_input_class; + +static DEVICE_ATTR(ir_protocol, S_IRUGO | S_IWUSR, NULL, NULL); + +static struct attribute *ir_dev_attrs[] = { + &dev_attr_ir_protocol.attr, +}; + +int ir_register_class(struct input_dev *input_dev) +{ + int rc; + struct kobject *kobj; + + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + int devno = find_first_zero_bit(&ir_core_dev_number, + IRRCV_NUM_DEVICES); + + if (unlikely(devno < 0)) + return devno; + + ir_dev->attr.attrs = ir_dev_attrs; + ir_dev->class_dev = device_create(ir_input_class, NULL, + input_dev->dev.devt, ir_dev, + "irrcv%d", devno); + kobj= &ir_dev->class_dev->kobj; + + printk(KERN_WARNING "Creating IR device %s\n", kobject_name(kobj)); + rc = sysfs_create_group(kobj, &ir_dev->attr); + if (unlikely (rc < 0)) { + device_destroy(ir_input_class, input_dev->dev.devt); + return -ENOMEM; + } + + ir_dev->devno = devno; + set_bit(devno, &ir_core_dev_number); + + return 0; +}; + +void ir_unregister_class(struct input_dev *input_dev) +{ + struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); + struct kobject *kobj; + + clear_bit(ir_dev->devno, &ir_core_dev_number); + + kobj= &ir_dev->class_dev->kobj; + + sysfs_remove_group(kobj, &ir_dev->attr); + device_destroy(ir_input_class, input_dev->dev.devt); + + kfree(ir_dev->attr.name); +} + +static int __init ir_core_init(void) +{ + ir_input_class = class_create(THIS_MODULE, "irrcv"); + if (IS_ERR(ir_input_class)) { + printk(KERN_ERR "ir_core: unable to register irrcv class\n"); + return PTR_ERR(ir_input_class); + } + + return 0; +} + +static void __exit ir_core_exit(void) +{ + class_destroy(ir_input_class); +} + +module_init(ir_core_init); +module_exit(ir_core_exit); --- master.orig/linux/include/media/ir-core.h +++ master/linux/include/media/ir-core.h @@ -42,8 +42,11 @@ struct ir_scancode_table { }; struct ir_input_dev { - struct input_dev *dev; - struct ir_scancode_table rc_tab; + struct input_dev *dev; /* Input device*/ + struct ir_scancode_table rc_tab; /* scan/key table */ + unsigned long devno; /* device number */ + struct attribute_group attr; /* IR attributes */ + struct device *class_dev; /* virtual class dev */ }; /* Routines from ir-keytable.c */ @@ -59,4 +62,9 @@ int ir_input_register(struct input_dev * struct ir_scancode_table *ir_codes); void ir_input_unregister(struct input_dev *input_dev); +/* Routines from ir-sysfs.c */ + +int ir_register_class(struct input_dev *input_dev); +void ir_unregister_class(struct input_dev *input_dev); + #endif