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 |