mutex_lock(&wacom->lock);
 
+       if (wacom->open)
+               goto out;
+
        if (usb_submit_urb(wacom->irq, GFP_KERNEL)) {
                retval = -EIO;
                goto out;
        autopm_error = usb_autopm_get_interface(wacom->intf);
 
        mutex_lock(&wacom->lock);
+       if (!wacom->open)
+               goto out;
+
        usb_kill_urb(wacom->irq);
        wacom->open = false;
        wacom->intf->needs_remote_wakeup = 0;
+
+out:
        mutex_unlock(&wacom->lock);
 
        if (!autopm_error)
        }
 }
 
-static int wacom_register_input(struct wacom *wacom)
+static struct input_dev *wacom_allocate_input(struct wacom *wacom)
 {
        struct input_dev *input_dev;
        struct usb_interface *intf = wacom->intf;
        struct usb_device *dev = interface_to_usbdev(intf);
        struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
-       int error;
 
        input_dev = input_allocate_device();
-       if (!input_dev) {
-               error = -ENOMEM;
-               goto fail1;
-       }
+       if (!input_dev)
+               return NULL;
 
        input_dev->name = wacom_wac->name;
        input_dev->phys = wacom->phys;
        usb_to_input_id(dev, &input_dev->id);
        input_set_drvdata(input_dev, wacom);
 
+       return input_dev;
+}
+
+static int wacom_register_input(struct wacom *wacom)
+{
+       struct input_dev *input_dev, *pad_input_dev;
+       struct wacom_wac *wacom_wac = &(wacom->wacom_wac);
+       int error;
+
+       input_dev = wacom_allocate_input(wacom);
+       pad_input_dev = wacom_allocate_input(wacom);
+       if (!input_dev || !pad_input_dev) {
+               error = -ENOMEM;
+               goto fail1;
+       }
+
        wacom_wac->input = input_dev;
+       wacom_wac->pad_input = pad_input_dev;
+       wacom_wac->pad_input->name = wacom_wac->pad_name;
+
        error = wacom_setup_input_capabilities(input_dev, wacom_wac);
        if (error)
-               goto fail1;
+               goto fail2;
 
        error = input_register_device(input_dev);
        if (error)
                goto fail2;
 
+       error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
+       if (error) {
+               /* no pad in use on this interface */
+               input_free_device(pad_input_dev);
+               wacom_wac->pad_input = NULL;
+               pad_input_dev = NULL;
+       } else {
+               error = input_register_device(pad_input_dev);
+               if (error)
+                       goto fail3;
+       }
+
        return 0;
 
+fail3:
+       input_unregister_device(input_dev);
+       input_dev = NULL;
 fail2:
-       input_free_device(input_dev);
        wacom_wac->input = NULL;
+       wacom_wac->pad_input = NULL;
 fail1:
+       if (input_dev)
+               input_free_device(input_dev);
+       if (pad_input_dev)
+               input_free_device(pad_input_dev);
        return error;
 }
 
        wacom_calculate_res(features);
 
        strlcpy(wacom_wac->name, features->name, sizeof(wacom_wac->name));
+       snprintf(wacom_wac->pad_name, sizeof(wacom_wac->pad_name),
+               "%s Pad", features->name);
 
        if (features->quirks & WACOM_QUIRK_MULTI_INPUT) {
                struct usb_device *other_dev;
        cancel_work_sync(&wacom->work);
        if (wacom->wacom_wac.input)
                input_unregister_device(wacom->wacom_wac.input);
+       if (wacom->wacom_wac.pad_input)
+               input_unregister_device(wacom->wacom_wac.pad_input);
        wacom_destroy_battery(wacom);
        wacom_destroy_leds(wacom);
        usb_free_urb(wacom->irq);
 
                break;
        }
 
-       if (sync)
+       if (sync) {
                input_sync(wacom_wac->input);
+               if (wacom_wac->pad_input)
+                       input_sync(wacom_wac->pad_input);
+       }
 }
 
 static void wacom_setup_cintiq(struct wacom_wac *wacom_wac)
        return 0;
 }
 
+int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
+                                  struct wacom_wac *wacom_wac)
+{
+       struct wacom_features *features = &wacom_wac->features;
+
+       input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+
+       /* kept for making legacy xf86-input-wacom working with the wheels */
+       __set_bit(ABS_MISC, input_dev->absbit);
+
+       /* kept for making legacy xf86-input-wacom accepting the pad */
+       input_set_abs_params(input_dev, ABS_X, 0, 1, 0, 0);
+       input_set_abs_params(input_dev, ABS_Y, 0, 1, 0, 0);
+
+       switch (features->type) {
+       default:
+               /* no pad supported */
+               return 1;
+       }
+       return 0;
+}
+
 static const struct wacom_features wacom_features_0x00 =
        { "Wacom Penpartner",     WACOM_PKGLEN_PENPRTN,    5040,  3780,  255,
          0, PENPARTNER, WACOM_PENPRTN_RES, WACOM_PENPRTN_RES };