Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68229689 authored by Oliver Neukum's avatar Oliver Neukum Committed by Jiri Kosina
Browse files

HID: usbhid: base runtime PM on modern API



This patch doesn't alter functionality, but removes a dedicated kernel
thread.

Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Tested-by: default avatarMaulik Mankad <x0082077@ti.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 1874542d
Loading
Loading
Loading
Loading
+19 −38
Original line number Diff line number Diff line
@@ -67,7 +67,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
 * Input submission and I/O error handler.
 */
static DEFINE_MUTEX(hid_open_mut);
static struct workqueue_struct *resumption_waker;

static void hid_io_error(struct hid_device *hid);
static int hid_submit_out(struct hid_device *hid);
@@ -300,10 +299,19 @@ static int hid_submit_out(struct hid_device *hid)
	struct hid_report *report;
	char *raw_report;
	struct usbhid_device *usbhid = hid->driver_data;
	int r;

	report = usbhid->out[usbhid->outtail].report;
	raw_report = usbhid->out[usbhid->outtail].raw_report;

	r = usb_autopm_get_interface_async(usbhid->intf);
	if (r < 0)
		return -1;

	/*
	 * if the device hasn't been woken, we leave the output
	 * to resume()
	 */
	if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
		usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
		usbhid->urbout->dev = hid_to_usb_dev(hid);
@@ -314,16 +322,10 @@ static int hid_submit_out(struct hid_device *hid)

		if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
			hid_err(hid, "usb_submit_urb(out) failed\n");
			usb_autopm_put_interface_async(usbhid->intf);
			return -1;
		}
		usbhid->last_out = jiffies;
	} else {
		/*
		 * queue work to wake up the device.
		 * as the work queue is freezeable, this is safe
		 * with respect to STD and STR
		 */
		queue_work(resumption_waker, &usbhid->restart_work);
	}

	return 0;
@@ -334,13 +336,16 @@ static int hid_submit_ctrl(struct hid_device *hid)
	struct hid_report *report;
	unsigned char dir;
	char *raw_report;
	int len;
	int len, r;
	struct usbhid_device *usbhid = hid->driver_data;

	report = usbhid->ctrl[usbhid->ctrltail].report;
	raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
	dir = usbhid->ctrl[usbhid->ctrltail].dir;

	r = usb_autopm_get_interface_async(usbhid->intf);
	if (r < 0)
		return -1;
	if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
		len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
		if (dir == USB_DIR_OUT) {
@@ -375,17 +380,11 @@ static int hid_submit_ctrl(struct hid_device *hid)
			usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);

		if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
			usb_autopm_put_interface_async(usbhid->intf);
			hid_err(hid, "usb_submit_urb(ctrl) failed\n");
			return -1;
		}
		usbhid->last_ctrl = jiffies;
	} else {
		/*
		 * queue work to wake up the device.
		 * as the work queue is freezeable, this is safe
		 * with respect to STD and STR
		 */
		queue_work(resumption_waker, &usbhid->restart_work);
	}

	return 0;
@@ -435,6 +434,7 @@ static void hid_irq_out(struct urb *urb)

	clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
	spin_unlock_irqrestore(&usbhid->lock, flags);
	usb_autopm_put_interface_async(usbhid->intf);
	wake_up(&usbhid->wait);
}

@@ -480,11 +480,13 @@ static void hid_ctrl(struct urb *urb)
			wake_up(&usbhid->wait);
		}
		spin_unlock(&usbhid->lock);
		usb_autopm_put_interface_async(usbhid->intf);
		return;
	}

	clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
	spin_unlock(&usbhid->lock);
	usb_autopm_put_interface_async(usbhid->intf);
	wake_up(&usbhid->wait);
}

@@ -655,7 +657,7 @@ int usbhid_open(struct hid_device *hid)
	mutex_lock(&hid_open_mut);
	if (!hid->open++) {
		res = usb_autopm_get_interface(usbhid->intf);
		/* the device must be awake to reliable request remote wakeup */
		/* the device must be awake to reliably request remote wakeup */
		if (res < 0) {
			hid->open--;
			mutex_unlock(&hid_open_mut);
@@ -856,18 +858,6 @@ static void usbhid_restart_queues(struct usbhid_device *usbhid)
	usbhid_restart_ctrl_queue(usbhid);
}

static void __usbhid_restart_queues(struct work_struct *work)
{
	struct usbhid_device *usbhid =
		container_of(work, struct usbhid_device, restart_work);
	int r;

	r = usb_autopm_get_interface(usbhid->intf);
	if (r < 0)
		return;
	usb_autopm_put_interface(usbhid->intf);
}

static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
	struct usbhid_device *usbhid = hid->driver_data;
@@ -1204,7 +1194,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *

	init_waitqueue_head(&usbhid->wait);
	INIT_WORK(&usbhid->reset_work, hid_reset);
	INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
	setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
	spin_lock_init(&usbhid->lock);

@@ -1239,7 +1228,6 @@ static void usbhid_disconnect(struct usb_interface *intf)
static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
{
	del_timer_sync(&usbhid->io_retry);
	cancel_work_sync(&usbhid->restart_work);
	cancel_work_sync(&usbhid->reset_work);
}

@@ -1260,7 +1248,6 @@ static int hid_pre_reset(struct usb_interface *intf)
	spin_lock_irq(&usbhid->lock);
	set_bit(HID_RESET_PENDING, &usbhid->iofl);
	spin_unlock_irq(&usbhid->lock);
	cancel_work_sync(&usbhid->restart_work);
	hid_cease_io(usbhid);

	return 0;
@@ -1459,9 +1446,6 @@ static int __init hid_init(void)
{
	int retval = -ENOMEM;

	resumption_waker = create_freezeable_workqueue("usbhid_resumer");
	if (!resumption_waker)
		goto no_queue;
	retval = hid_register_driver(&hid_usb_driver);
	if (retval)
		goto hid_register_fail;
@@ -1479,8 +1463,6 @@ static int __init hid_init(void)
usbhid_quirks_init_fail:
	hid_unregister_driver(&hid_usb_driver);
hid_register_fail:
	destroy_workqueue(resumption_waker);
no_queue:
	return retval;
}

@@ -1489,7 +1471,6 @@ static void __exit hid_exit(void)
	usb_deregister(&hid_driver);
	usbhid_quirks_exit();
	hid_unregister_driver(&hid_usb_driver);
	destroy_workqueue(resumption_waker);
}

module_init(hid_init);
+0 −1
Original line number Diff line number Diff line
@@ -95,7 +95,6 @@ struct usbhid_device {
	unsigned long stop_retry;                                       /* Time to give up, in jiffies */
	unsigned int retry_delay;                                       /* Delay length in ms */
	struct work_struct reset_work;                                  /* Task context for resets */
	struct work_struct restart_work;				/* waking up for output to be done in a task */
	wait_queue_head_t wait;						/* For sleeping */
	int ledcount;							/* counting the number of active leds */
};