kernel-power v49 -> kernel-bfs
[kernel-bfs] / kernel-bfs-2.6.28 / debian / patches / radio-si4713.diff
diff --git a/kernel-bfs-2.6.28/debian/patches/radio-si4713.diff b/kernel-bfs-2.6.28/debian/patches/radio-si4713.diff
new file mode 100644 (file)
index 0000000..e100338
--- /dev/null
@@ -0,0 +1,195 @@
+--- kernel-power-2.6.28/drivers/media/radio/radio-si4713.c     2011-09-14 23:56:12.320096297 +0200
++++ kernel-power-2.6.28/drivers/media/radio/radio-si4713.c     2011-09-15 00:19:37.030080507 +0200
+@@ -55,23 +55,10 @@
+ static int radio_nr = -1;     /* radio device minor (-1 ==> auto assign) */
+ /* properties lock for write operations */
+-static int config_locked;
++static int config_locked = 1;
+-/* saved power levels */
+-static unsigned int max_pl;
+-static unsigned int min_pl;
+-
+-/* structure for pid registration */
+-struct pid_list {
+-      pid_t pid;
+-      struct list_head plist;
+-};
+-
+-#define APP_MAX_NUM   2
+-
+-static int pid_count;
+-static LIST_HEAD(pid_list_head);
+-static struct si4713_device *si4713_dev;
++/* module param for initial power level */
++static int init_power_level = 120;
+ /*
+  * Sysfs properties
+@@ -193,16 +180,7 @@ static ssize_t si4713_lock_write(struct
+                               const char *buf,
+                               size_t count)
+ {
+-      int l;
+-
+-      if (config_locked)
+-              return -EPERM;
+-
+-      sscanf(buf, "%d", &l);
+-
+-      if (l != 0)
+-              config_locked = 1;
+-
++      sscanf(buf, "%d", &config_locked);
+       return count;
+ }
+@@ -219,7 +197,7 @@ static DEVICE_ATTR(lock, S_IRUGO | S_IWU
+ /*
+  * Power level property
+  */
+-/* power_level (rw) 88 - 115 or 0 */
++/* power_level (rw) 88 - 120 or 0 */
+ static ssize_t si4713_power_level_write(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf,
+@@ -420,109 +398,13 @@ static irqreturn_t si4713_handler(int ir
+       return IRQ_HANDLED;
+ }
+-static int register_pid(pid_t pid)
+-{
+-      struct pid_list *pitem;
+-
+-      list_for_each_entry(pitem, &pid_list_head, plist) {
+-              if (pitem->pid == pid)
+-                      return -EINVAL;
+-      }
+-
+-      pitem = kmalloc(sizeof(struct pid_list), GFP_KERNEL);
+-
+-      if (!pitem)
+-              return -ENOMEM;
+-
+-      pitem->pid = pid;
+-
+-      list_add(&(pitem->plist), &pid_list_head);
+-      pid_count++;
+-
+-      return 0;
+-}
+-
+-static int unregister_pid(pid_t pid)
+-{
+-      struct pid_list *pitem, *n;
+-
+-      list_for_each_entry_safe(pitem, n, &pid_list_head, plist) {
+-              if (pitem->pid == pid) {
+-                      list_del(&(pitem->plist));
+-                      pid_count--;
+-
+-                      kfree(pitem);
+-
+-                      return 0;
+-              }
+-      }
+-      return -EINVAL;
+-}
+-
+ static int si4713_priv_ioctl(struct inode *inode, struct file *file,
+               unsigned int cmd, unsigned long arg)
+ {
+-      unsigned int pow;
+-      int pl, rval;
+-
+       if (cmd != LOCK_LOW_POWER && cmd != RELEASE_LOW_POWER)
+               return video_ioctl2(inode, file, cmd, arg);
+-
+-      pl = si4713_get_power_level(si4713_dev);
+-
+-      if (pl < 0) {
+-              rval = pl;
+-              goto exit;
+-      }
+-
+-      if (copy_from_user(&pow, (void __user *)arg, sizeof(pow))) {
+-              rval = -EFAULT;
+-              goto exit;
+-      }
+-
+-      if (cmd == LOCK_LOW_POWER) {
+-
+-              if (pid_count == APP_MAX_NUM) {
+-                      rval = -EPERM;
+-                      goto exit;
+-              }
+-
+-              if (pid_count == 0) {
+-                      if (pow > pl) {
+-                              rval = -EINVAL;
+-                              goto exit;
+-                      } else {
+-                              /* Set max possible power level */
+-                              max_pl = pl;
+-                              min_pl = pow;
+-                      }
+-              }
+-
+-              rval = register_pid(current->pid);
+-
+-              if (rval)
+-                      goto exit;
+-
+-              /* Lower min power level if asked */
+-              if (pow < min_pl)
+-                      min_pl = pow;
+-              else
+-                      pow = min_pl;
+-
+-      } else { /* RELEASE_LOW_POWER */
+-              rval = unregister_pid(current->pid);
+-
+-              if (rval)
+-                      goto exit;
+-
+-              if (pid_count == 0) {
+-                      if (pow > max_pl)
+-                              pow = max_pl;
+-              }
+-      }
+-      rval = si4713_set_power_level(si4713_dev, pow);
+-exit:
+-      return rval;
++      else
++              return 0;
+ }
+ /*
+@@ -906,8 +788,11 @@ static int si4713_i2c_driver_probe(struc
+               goto free_sysfs;
+       }
+-      /* save to global pointer for it to be accesible from ioctl() call */
+-      si4713_dev = sdev;
++      rval = si4713_set_power_level(sdev, init_power_level);
++      if (rval < 0) {
++              dev_dbg(&client->dev, "Failed to set initial power level.\n");
++              goto free_sysfs;
++      }
+       return 0;
+@@ -1013,6 +898,12 @@ module_param(radio_nr, int, 0);
+ MODULE_PARM_DESC(radio_nr,
+                "Minor number for radio device (-1 ==> auto assign)");
++module_param(init_power_level, int, 120);
++MODULE_PARM_DESC(init_power_level, "Initial value of power level (default 120)");
++
++module_param(config_locked, int, 1);
++MODULE_PARM_DESC(config_locked, "Lock power level configuration on init (default 1 - locked)");
++
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR(DRIVER_AUTHOR);
+ MODULE_DESCRIPTION(DRIVER_DESC);