add temporary toggleable version of i2c-battery.diff (disabled by default)
[kernel-bfs] / kernel-bfs-2.6.28 / debian / patches / extra / i2c-battery-sysfs.diff
1 diff -urpN linux-2.6.28.orig/drivers/i2c/i2c-dev.c linux-2.6.28/drivers/i2c/i2c-dev.c
2 --- linux-2.6.28.orig/drivers/i2c/i2c-dev.c     2008-12-25 00:26:37.000000000 +0100
3 +++ linux-2.6.28/drivers/i2c/i2c-dev.c  2011-09-27 19:55:45.752843074 +0200
4 @@ -37,6 +37,31 @@
5  #include <linux/smp_lock.h>
6  #include <asm/uaccess.h>
7  
8 +/* Sysfs knob for the N900 */
9 +#include <linux/kobject.h>
10 +#include <linux/sysfs.h>
11 +
12 +static int break_ioctl;
13 +static int sysfs_succes;
14 +
15 +static ssize_t break_ioctl_show(struct kobject *kobj, struct kobj_attribute *attr,
16 +                       char *buf)
17 +{
18 +       return sprintf(buf, "%d\n", break_ioctl);
19 +}
20 +
21 +static ssize_t break_ioctl_store(struct kobject *kobj, struct kobj_attribute *attr,
22 +                       const char *buf, size_t count)
23 +{
24 +       sscanf(buf, "%du", &break_ioctl);
25 +       return count;
26 +}
27 +
28 +static struct kobj_attribute break_ioctl_attribute =
29 +       __ATTR(i2c-dev_break_ioctl, 0644, break_ioctl_show, break_ioctl_store);
30 +
31 +
32 +static struct kobject *n900_kobj;
33  static struct i2c_driver i2cdev_driver;
34  
35  /*
36 @@ -391,9 +416,14 @@ static long i2cdev_ioctl(struct file *fi
37                 if ((arg > 0x3ff) ||
38                     (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
39                         return -EINVAL;
40 -               if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg))
41 -                       return -EBUSY;
42 -               /* REVISIT: address could become busy later */
43 +               if (!break_ioctl) {
44 +                       if (cmd == I2C_SLAVE && i2cdev_check_addr(client->adapter, arg)) {
45 +                               return -EBUSY;
46 +                       }
47 +                       /* REVISIT: address could become busy later */
48 +               } else {
49 +                       printk(KERN_INFO "i2c-dev: HACK: omitting lock (EBUSY)\n");
50 +               }
51                 client->addr = arg;
52                 return 0;
53         case I2C_TENBIT:
54 @@ -592,8 +622,23 @@ static int __init i2c_dev_init(void)
55         if (res)
56                 goto out_unreg_class;
57  
58 +       break_ioctl = 0; /* do not break by default */
59 +
60 +       n900_kobj = kobject_create_and_add("n900", kernel_kobj);
61 +       if (!n900_kobj)
62 +               goto skip_sysfs;
63 +
64 +       res = sysfs_create_file(n900_kobj, &break_ioctl_attribute.attr);
65 +       if (res)
66 +               kobject_put(n900_kobj);
67 +
68 +       sysfs_succes = 1;
69         return 0;
70  
71 +skip_sysfs:
72 +       sysfs_succes = 0;
73 +       printk(KERN_INFO "Failed to create i2c-dev_break_ioctl sysfs knob\n");
74 +       return 0;
75  out_unreg_class:
76         class_destroy(i2c_dev_class);
77  out_unreg_chrdev:
78 @@ -605,6 +650,8 @@ out:
79  
80  static void __exit i2c_dev_exit(void)
81  {
82 +       if (sysfs_succes)
83 +               kobject_put(n900_kobj);
84         i2c_del_driver(&i2cdev_driver);
85         class_destroy(i2c_dev_class);
86         unregister_chrdev(I2C_MAJOR,"i2c");