Commit 5bea7660 authored by Dmitry Torokhov's avatar Dmitry Torokhov Committed by Jiri Kosina

HID: add hid_hw_open/close/power() handlers

Instead of exposing the guts of hid->ll_driver relationship to HID
sub-drivers provide these helpers to encapsulate the details.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 33d6eb57
...@@ -772,14 +772,14 @@ static int hidinput_open(struct input_dev *dev) ...@@ -772,14 +772,14 @@ static int hidinput_open(struct input_dev *dev)
{ {
struct hid_device *hid = input_get_drvdata(dev); struct hid_device *hid = input_get_drvdata(dev);
return hid->ll_driver->open(hid); return hid_hw_open(hid);
} }
static void hidinput_close(struct input_dev *dev) static void hidinput_close(struct input_dev *dev)
{ {
struct hid_device *hid = input_get_drvdata(dev); struct hid_device *hid = input_get_drvdata(dev);
hid->ll_driver->close(hid); hid_hw_close(hid);
} }
/* /*
......
...@@ -2635,7 +2635,7 @@ static int picolcd_probe(struct hid_device *hdev, ...@@ -2635,7 +2635,7 @@ static int picolcd_probe(struct hid_device *hdev,
goto err_cleanup_data; goto err_cleanup_data;
} }
error = hdev->ll_driver->open(hdev); error = hid_hw_open(hdev);
if (error) { if (error) {
dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n"); dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n");
goto err_cleanup_hid_hw; goto err_cleanup_hid_hw;
...@@ -2668,7 +2668,7 @@ static int picolcd_probe(struct hid_device *hdev, ...@@ -2668,7 +2668,7 @@ static int picolcd_probe(struct hid_device *hdev,
err_cleanup_sysfs1: err_cleanup_sysfs1:
device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
err_cleanup_hid_ll: err_cleanup_hid_ll:
hdev->ll_driver->close(hdev); hid_hw_close(hdev);
err_cleanup_hid_hw: err_cleanup_hid_hw:
hid_hw_stop(hdev); hid_hw_stop(hdev);
err_cleanup_data: err_cleanup_data:
...@@ -2699,7 +2699,7 @@ static void picolcd_remove(struct hid_device *hdev) ...@@ -2699,7 +2699,7 @@ static void picolcd_remove(struct hid_device *hdev)
picolcd_exit_devfs(data); picolcd_exit_devfs(data);
device_remove_file(&hdev->dev, &dev_attr_operation_mode); device_remove_file(&hdev->dev, &dev_attr_operation_mode);
device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay);
hdev->ll_driver->close(hdev); hid_hw_close(hdev);
hid_hw_stop(hdev); hid_hw_stop(hdev);
hid_set_drvdata(hdev, NULL); hid_set_drvdata(hdev, NULL);
......
...@@ -173,19 +173,15 @@ static int roccat_open(struct inode *inode, struct file *file) ...@@ -173,19 +173,15 @@ static int roccat_open(struct inode *inode, struct file *file)
if (!device->open++) { if (!device->open++) {
/* power on device on adding first reader */ /* power on device on adding first reader */
if (device->hid->ll_driver->power) { error = hid_hw_power(device->hid, PM_HINT_FULLON);
error = device->hid->ll_driver->power(device->hid, if (error < 0) {
PM_HINT_FULLON); --device->open;
if (error < 0) { goto exit_err;
--device->open;
goto exit_err;
}
} }
error = device->hid->ll_driver->open(device->hid);
error = hid_hw_open(device->hid);
if (error < 0) { if (error < 0) {
if (device->hid->ll_driver->power) hid_hw_power(device->hid, PM_HINT_NORMAL);
device->hid->ll_driver->power(device->hid,
PM_HINT_NORMAL);
--device->open; --device->open;
goto exit_err; goto exit_err;
} }
...@@ -231,10 +227,8 @@ static int roccat_release(struct inode *inode, struct file *file) ...@@ -231,10 +227,8 @@ static int roccat_release(struct inode *inode, struct file *file)
if (!--device->open) { if (!--device->open) {
/* removing last reader */ /* removing last reader */
if (device->exist) { if (device->exist) {
if (device->hid->ll_driver->power) hid_hw_power(device->hid, PM_HINT_NORMAL);
device->hid->ll_driver->power(device->hid, hid_hw_close(device->hid);
PM_HINT_NORMAL);
device->hid->ll_driver->close(device->hid);
} else { } else {
kfree(device); kfree(device);
} }
...@@ -370,7 +364,7 @@ void roccat_disconnect(int minor) ...@@ -370,7 +364,7 @@ void roccat_disconnect(int minor)
device_destroy(roccat_class, MKDEV(roccat_major, minor)); device_destroy(roccat_class, MKDEV(roccat_major, minor));
if (device->open) { if (device->open) {
device->hid->ll_driver->close(device->hid); hid_hw_close(device->hid);
wake_up_interruptible(&device->wait); wake_up_interruptible(&device->wait);
} else { } else {
kfree(device); kfree(device);
......
...@@ -193,15 +193,13 @@ static int hidraw_open(struct inode *inode, struct file *file) ...@@ -193,15 +193,13 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor]; dev = hidraw_table[minor];
if (!dev->open++) { if (!dev->open++) {
if (dev->hid->ll_driver->power) { err = hid_hw_power(dev->hid, PM_HINT_FULLON);
err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON); if (err < 0)
if (err < 0) goto out_unlock;
goto out_unlock;
} err = hid_hw_open(dev->hid);
err = dev->hid->ll_driver->open(dev->hid);
if (err < 0) { if (err < 0) {
if (dev->hid->ll_driver->power) hid_hw_power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->open--; dev->open--;
} }
} }
...@@ -230,9 +228,8 @@ static int hidraw_release(struct inode * inode, struct file * file) ...@@ -230,9 +228,8 @@ static int hidraw_release(struct inode * inode, struct file * file)
dev = hidraw_table[minor]; dev = hidraw_table[minor];
if (!--dev->open) { if (!--dev->open) {
if (list->hidraw->exist) { if (list->hidraw->exist) {
if (dev->hid->ll_driver->power) hid_hw_power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); hid_hw_close(dev->hid);
dev->hid->ll_driver->close(dev->hid);
} else { } else {
kfree(list->hidraw); kfree(list->hidraw);
} }
...@@ -434,7 +431,7 @@ void hidraw_disconnect(struct hid_device *hid) ...@@ -434,7 +431,7 @@ void hidraw_disconnect(struct hid_device *hid)
device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor));
if (hidraw->open) { if (hidraw->open) {
hid->ll_driver->close(hid); hid_hw_close(hid);
wake_up_interruptible(&hidraw->wait); wake_up_interruptible(&hidraw->wait);
} else { } else {
kfree(hidraw); kfree(hidraw);
......
...@@ -820,6 +820,49 @@ static inline void hid_hw_stop(struct hid_device *hdev) ...@@ -820,6 +820,49 @@ static inline void hid_hw_stop(struct hid_device *hdev)
hdev->ll_driver->stop(hdev); hdev->ll_driver->stop(hdev);
} }
/**
* hid_hw_open - signal underlaying HW to start delivering events
*
* @hdev: hid device
*
* Tell underlying HW to start delivering events from the device.
* This function should be called sometime after successful call
* to hid_hiw_start().
*/
static inline int __must_check hid_hw_open(struct hid_device *hdev)
{
return hdev->ll_driver->open(hdev);
}
/**
* hid_hw_close - signal underlaying HW to stop delivering events
*
* @hdev: hid device
*
* This function indicates that we are not interested in the events
* from this device anymore. Delivery of events may or may not stop,
* depending on the number of users still outstanding.
*/
static inline void hid_hw_close(struct hid_device *hdev)
{
hdev->ll_driver->close(hdev);
}
/**
* hid_hw_power - requests underlying HW to go into given power mode
*
* @hdev: hid device
* @level: requested power level (one of %PM_HINT_* defines)
*
* This function requests underlying hardware to enter requested power
* mode.
*/
static inline int hid_hw_power(struct hid_device *hdev, int level)
{
return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0;
}
void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
int interrupt); int interrupt);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment