]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 02:14:35 +0000 (19:14 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 28 May 2016 02:14:35 +0000 (19:14 -0700)
Pull more input subsystem updates from Dmitry Torokhov:
 "Just a few more driver fixes; new drivers will be coming in the next
  merge window"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
  Input: pwm-beeper - fix - scheduling while atomic
  Input: xpad - xbox one elite controller support
  Input: xpad - add more third-party controllers
  Input: xpad - prevent spurious input from wired Xbox 360 controllers
  Input: xpad - move pending clear to the correct location
  Input: uinput - handle compat ioctl for UI_SET_PHYS

1  2 
drivers/input/misc/pwm-beeper.c
drivers/input/misc/uinput.c

index 8d71332687455d51d0391d2f5425d3cbf48edd8f,18663d4edae5be089b112f5a0c3f830ae3ca432c..5f9655d49a65475f4e64a6ac85de5b34f33ee321
  #include <linux/platform_device.h>
  #include <linux/pwm.h>
  #include <linux/slab.h>
+ #include <linux/workqueue.h>
  
  struct pwm_beeper {
        struct input_dev *input;
        struct pwm_device *pwm;
+       struct work_struct work;
        unsigned long period;
  };
  
  #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
  
+ static void __pwm_beeper_set(struct pwm_beeper *beeper)
+ {
+       unsigned long period = beeper->period;
+       if (period) {
+               pwm_config(beeper->pwm, period / 2, period);
+               pwm_enable(beeper->pwm);
+       } else
+               pwm_disable(beeper->pwm);
+ }
+ static void pwm_beeper_work(struct work_struct *work)
+ {
+       struct pwm_beeper *beeper =
+               container_of(work, struct pwm_beeper, work);
+       __pwm_beeper_set(beeper);
+ }
  static int pwm_beeper_event(struct input_dev *input,
                            unsigned int type, unsigned int code, int value)
  {
-       int ret = 0;
        struct pwm_beeper *beeper = input_get_drvdata(input);
-       unsigned long period;
  
        if (type != EV_SND || value < 0)
                return -EINVAL;
                return -EINVAL;
        }
  
-       if (value == 0) {
-               pwm_disable(beeper->pwm);
-       } else {
-               period = HZ_TO_NANOSECONDS(value);
-               ret = pwm_config(beeper->pwm, period / 2, period);
-               if (ret)
-                       return ret;
-               ret = pwm_enable(beeper->pwm);
-               if (ret)
-                       return ret;
-               beeper->period = period;
-       }
+       if (value == 0)
+               beeper->period = 0;
+       else
+               beeper->period = HZ_TO_NANOSECONDS(value);
+       schedule_work(&beeper->work);
  
        return 0;
  }
  
+ static void pwm_beeper_stop(struct pwm_beeper *beeper)
+ {
+       cancel_work_sync(&beeper->work);
+       if (beeper->period)
+               pwm_disable(beeper->pwm);
+ }
+ static void pwm_beeper_close(struct input_dev *input)
+ {
+       struct pwm_beeper *beeper = input_get_drvdata(input);
+       pwm_beeper_stop(beeper);
+ }
  static int pwm_beeper_probe(struct platform_device *pdev)
  {
        unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev);
                goto err_free;
        }
  
 +      /*
 +       * FIXME: pwm_apply_args() should be removed when switching to
 +       * the atomic PWM API.
 +       */
 +      pwm_apply_args(beeper->pwm);
 +
+       INIT_WORK(&beeper->work, pwm_beeper_work);
        beeper->input = input_allocate_device();
        if (!beeper->input) {
                dev_err(&pdev->dev, "Failed to allocate input device\n");
        beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
  
        beeper->input->event = pwm_beeper_event;
+       beeper->input->close = pwm_beeper_close;
  
        input_set_drvdata(beeper->input, beeper);
  
@@@ -141,7 -166,6 +172,6 @@@ static int pwm_beeper_remove(struct pla
  
        input_unregister_device(beeper->input);
  
-       pwm_disable(beeper->pwm);
        pwm_free(beeper->pwm);
  
        kfree(beeper);
@@@ -153,8 -177,7 +183,7 @@@ static int __maybe_unused pwm_beeper_su
  {
        struct pwm_beeper *beeper = dev_get_drvdata(dev);
  
-       if (beeper->period)
-               pwm_disable(beeper->pwm);
+       pwm_beeper_stop(beeper);
  
        return 0;
  }
@@@ -163,10 -186,8 +192,8 @@@ static int __maybe_unused pwm_beeper_re
  {
        struct pwm_beeper *beeper = dev_get_drvdata(dev);
  
-       if (beeper->period) {
-               pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
-               pwm_enable(beeper->pwm);
-       }
+       if (beeper->period)
+               __pwm_beeper_set(beeper);
  
        return 0;
  }
index abe1a927b3328d22af925832f7b8c7c0bc76f2bb,79338f4bdecb68ec52b690ad7bc9db668e3f1868..65ebbd11170221c8d0180958040c1d1c2f939dda
@@@ -664,7 -664,7 +664,7 @@@ struct uinput_ff_upload_compat 
  static int uinput_ff_upload_to_user(char __user *buffer,
                                    const struct uinput_ff_upload *ff_up)
  {
 -      if (INPUT_COMPAT_TEST) {
 +      if (in_compat_syscall()) {
                struct uinput_ff_upload_compat ff_up_compat;
  
                ff_up_compat.request_id = ff_up->request_id;
  static int uinput_ff_upload_from_user(const char __user *buffer,
                                      struct uinput_ff_upload *ff_up)
  {
 -      if (INPUT_COMPAT_TEST) {
 +      if (in_compat_syscall()) {
                struct uinput_ff_upload_compat ff_up_compat;
  
                if (copy_from_user(&ff_up_compat, buffer,
@@@ -981,9 -981,15 +981,15 @@@ static long uinput_ioctl(struct file *f
  }
  
  #ifdef CONFIG_COMPAT
+ #define UI_SET_PHYS_COMPAT    _IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
  static long uinput_compat_ioctl(struct file *file,
                                unsigned int cmd, unsigned long arg)
  {
+       if (cmd == UI_SET_PHYS_COMPAT)
+               cmd = UI_SET_PHYS;
        return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
  }
  #endif