diff options
| -rw-r--r-- | drivers/hid/hid-core.c | 89 | ||||
| -rw-r--r-- | include/linux/hid.h | 72 |
2 files changed, 98 insertions, 63 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 04cee65531d7..f93dd6f48a79 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
| @@ -1750,6 +1750,94 @@ void hid_disconnect(struct hid_device *hdev) | |||
| 1750 | } | 1750 | } |
| 1751 | EXPORT_SYMBOL_GPL(hid_disconnect); | 1751 | EXPORT_SYMBOL_GPL(hid_disconnect); |
| 1752 | 1752 | ||
| 1753 | /** | ||
| 1754 | * hid_hw_start - start underlying HW | ||
| 1755 | * @hdev: hid device | ||
| 1756 | * @connect_mask: which outputs to connect, see HID_CONNECT_* | ||
| 1757 | * | ||
| 1758 | * Call this in probe function *after* hid_parse. This will setup HW | ||
| 1759 | * buffers and start the device (if not defeirred to device open). | ||
| 1760 | * hid_hw_stop must be called if this was successful. | ||
| 1761 | */ | ||
| 1762 | int hid_hw_start(struct hid_device *hdev, unsigned int connect_mask) | ||
| 1763 | { | ||
| 1764 | int error; | ||
| 1765 | |||
| 1766 | error = hdev->ll_driver->start(hdev); | ||
| 1767 | if (error) | ||
| 1768 | return error; | ||
| 1769 | |||
| 1770 | if (connect_mask) { | ||
| 1771 | error = hid_connect(hdev, connect_mask); | ||
| 1772 | if (error) { | ||
| 1773 | hdev->ll_driver->stop(hdev); | ||
| 1774 | return error; | ||
| 1775 | } | ||
| 1776 | } | ||
| 1777 | |||
| 1778 | return 0; | ||
| 1779 | } | ||
| 1780 | EXPORT_SYMBOL_GPL(hid_hw_start); | ||
| 1781 | |||
| 1782 | /** | ||
| 1783 | * hid_hw_stop - stop underlying HW | ||
| 1784 | * @hdev: hid device | ||
| 1785 | * | ||
| 1786 | * This is usually called from remove function or from probe when something | ||
| 1787 | * failed and hid_hw_start was called already. | ||
| 1788 | */ | ||
| 1789 | void hid_hw_stop(struct hid_device *hdev) | ||
| 1790 | { | ||
| 1791 | hid_disconnect(hdev); | ||
| 1792 | hdev->ll_driver->stop(hdev); | ||
| 1793 | } | ||
| 1794 | EXPORT_SYMBOL_GPL(hid_hw_stop); | ||
| 1795 | |||
| 1796 | /** | ||
| 1797 | * hid_hw_open - signal underlying HW to start delivering events | ||
| 1798 | * @hdev: hid device | ||
| 1799 | * | ||
| 1800 | * Tell underlying HW to start delivering events from the device. | ||
| 1801 | * This function should be called sometime after successful call | ||
| 1802 | * to hid_hiw_start(). | ||
| 1803 | */ | ||
| 1804 | int hid_hw_open(struct hid_device *hdev) | ||
| 1805 | { | ||
| 1806 | int ret; | ||
| 1807 | |||
| 1808 | ret = mutex_lock_killable(&hdev->ll_open_lock); | ||
| 1809 | if (ret) | ||
| 1810 | return ret; | ||
| 1811 | |||
| 1812 | if (!hdev->ll_open_count++) { | ||
| 1813 | ret = hdev->ll_driver->open(hdev); | ||
| 1814 | if (ret) | ||
| 1815 | hdev->ll_open_count--; | ||
| 1816 | } | ||
| 1817 | |||
| 1818 | mutex_unlock(&hdev->ll_open_lock); | ||
| 1819 | return ret; | ||
| 1820 | } | ||
| 1821 | EXPORT_SYMBOL_GPL(hid_hw_open); | ||
| 1822 | |||
| 1823 | /** | ||
| 1824 | * hid_hw_close - signal underlaying HW to stop delivering events | ||
| 1825 | * | ||
| 1826 | * @hdev: hid device | ||
| 1827 | * | ||
| 1828 | * This function indicates that we are not interested in the events | ||
| 1829 | * from this device anymore. Delivery of events may or may not stop, | ||
| 1830 | * depending on the number of users still outstanding. | ||
| 1831 | */ | ||
| 1832 | void hid_hw_close(struct hid_device *hdev) | ||
| 1833 | { | ||
| 1834 | mutex_lock(&hdev->ll_open_lock); | ||
| 1835 | if (!--hdev->ll_open_count) | ||
| 1836 | hdev->ll_driver->close(hdev); | ||
| 1837 | mutex_unlock(&hdev->ll_open_lock); | ||
| 1838 | } | ||
| 1839 | EXPORT_SYMBOL_GPL(hid_hw_close); | ||
| 1840 | |||
| 1753 | /* | 1841 | /* |
| 1754 | * A list of devices for which there is a specialized driver on HID bus. | 1842 | * A list of devices for which there is a specialized driver on HID bus. |
| 1755 | * | 1843 | * |
| @@ -2747,6 +2835,7 @@ struct hid_device *hid_allocate_device(void) | |||
| 2747 | spin_lock_init(&hdev->debug_list_lock); | 2835 | spin_lock_init(&hdev->debug_list_lock); |
| 2748 | sema_init(&hdev->driver_lock, 1); | 2836 | sema_init(&hdev->driver_lock, 1); |
| 2749 | sema_init(&hdev->driver_input_lock, 1); | 2837 | sema_init(&hdev->driver_input_lock, 1); |
| 2838 | mutex_init(&hdev->ll_open_lock); | ||
| 2750 | 2839 | ||
| 2751 | return hdev; | 2840 | return hdev; |
| 2752 | } | 2841 | } |
diff --git a/include/linux/hid.h b/include/linux/hid.h index 5be325d890d9..5501eb64dbc4 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| 35 | #include <linux/input.h> | 35 | #include <linux/input.h> |
| 36 | #include <linux/semaphore.h> | 36 | #include <linux/semaphore.h> |
| 37 | #include <linux/mutex.h> | ||
| 37 | #include <linux/power_supply.h> | 38 | #include <linux/power_supply.h> |
| 38 | #include <uapi/linux/hid.h> | 39 | #include <uapi/linux/hid.h> |
| 39 | 40 | ||
| @@ -520,7 +521,10 @@ struct hid_device { /* device report descriptor */ | |||
| 520 | struct semaphore driver_input_lock; /* protects the current driver */ | 521 | struct semaphore driver_input_lock; /* protects the current driver */ |
| 521 | struct device dev; /* device */ | 522 | struct device dev; /* device */ |
| 522 | struct hid_driver *driver; | 523 | struct hid_driver *driver; |
| 524 | |||
| 523 | struct hid_ll_driver *ll_driver; | 525 | struct hid_ll_driver *ll_driver; |
| 526 | struct mutex ll_open_lock; | ||
| 527 | unsigned int ll_open_count; | ||
| 524 | 528 | ||
| 525 | #ifdef CONFIG_HID_BATTERY_STRENGTH | 529 | #ifdef CONFIG_HID_BATTERY_STRENGTH |
| 526 | /* | 530 | /* |
| @@ -937,69 +941,11 @@ static inline int __must_check hid_parse(struct hid_device *hdev) | |||
| 937 | return hid_open_report(hdev); | 941 | return hid_open_report(hdev); |
| 938 | } | 942 | } |
| 939 | 943 | ||
| 940 | /** | 944 | int __must_check hid_hw_start(struct hid_device *hdev, |
| 941 | * hid_hw_start - start underlaying HW | 945 | unsigned int connect_mask); |
| 942 | * | 946 | void hid_hw_stop(struct hid_device *hdev); |
| 943 | * @hdev: hid device | 947 | int __must_check hid_hw_open(struct hid_device *hdev); |
| 944 | * @connect_mask: which outputs to connect, see HID_CONNECT_* | 948 | void hid_hw_close(struct hid_device *hdev); |
| 945 | * | ||
| 946 | * Call this in probe function *after* hid_parse. This will setup HW buffers | ||
| 947 | * and start the device (if not deffered to device open). hid_hw_stop must be | ||
| 948 | * called if this was successful. | ||
| 949 | */ | ||
| 950 | static inline int __must_check hid_hw_start(struct hid_device *hdev, | ||
| 951 | unsigned int connect_mask) | ||
| 952 | { | ||
| 953 | int ret = hdev->ll_driver->start(hdev); | ||
| 954 | if (ret || !connect_mask) | ||
| 955 | return ret; | ||
| 956 | ret = hid_connect(hdev, connect_mask); | ||
| 957 | if (ret) | ||
| 958 | hdev->ll_driver->stop(hdev); | ||
| 959 | return ret; | ||
| 960 | } | ||
| 961 | |||
| 962 | /** | ||
| 963 | * hid_hw_stop - stop underlaying HW | ||
| 964 | * | ||
| 965 | * @hdev: hid device | ||
| 966 | * | ||
| 967 | * This is usually called from remove function or from probe when something | ||
| 968 | * failed and hid_hw_start was called already. | ||
| 969 | */ | ||
| 970 | static inline void hid_hw_stop(struct hid_device *hdev) | ||
| 971 | { | ||
| 972 | hid_disconnect(hdev); | ||
| 973 | hdev->ll_driver->stop(hdev); | ||
| 974 | } | ||
| 975 | |||
| 976 | /** | ||
| 977 | * hid_hw_open - signal underlaying HW to start delivering events | ||
| 978 | * | ||
| 979 | * @hdev: hid device | ||
| 980 | * | ||
| 981 | * Tell underlying HW to start delivering events from the device. | ||
| 982 | * This function should be called sometime after successful call | ||
| 983 | * to hid_hiw_start(). | ||
| 984 | */ | ||
| 985 | static inline int __must_check hid_hw_open(struct hid_device *hdev) | ||
| 986 | { | ||
| 987 | return hdev->ll_driver->open(hdev); | ||
| 988 | } | ||
| 989 | |||
| 990 | /** | ||
| 991 | * hid_hw_close - signal underlaying HW to stop delivering events | ||
| 992 | * | ||
| 993 | * @hdev: hid device | ||
| 994 | * | ||
| 995 | * This function indicates that we are not interested in the events | ||
| 996 | * from this device anymore. Delivery of events may or may not stop, | ||
| 997 | * depending on the number of users still outstanding. | ||
| 998 | */ | ||
| 999 | static inline void hid_hw_close(struct hid_device *hdev) | ||
| 1000 | { | ||
| 1001 | hdev->ll_driver->close(hdev); | ||
| 1002 | } | ||
| 1003 | 949 | ||
| 1004 | /** | 950 | /** |
| 1005 | * hid_hw_power - requests underlying HW to go into given power mode | 951 | * hid_hw_power - requests underlying HW to go into given power mode |
