diff options
author | Benjamin Tissoires <benjamin.tissoires@redhat.com> | 2016-11-29 20:42:13 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2016-11-30 12:03:13 -0500 |
commit | a64ea311f1e4bc090c89960650637423e86c35c0 (patch) | |
tree | a273f1a5be6b21b2326de22ceb58e6c07a65fb93 | |
parent | 0d37d63a001202b4932f6b14b05d8d055a0a45b6 (diff) |
Input: synaptics-rmi4 - add rmi_enable/disable_irq
Set the .enabled boolean and trigger an event processing when enabling
for edge-triggered systems.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/rmi4/rmi_driver.c | 83 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_driver.h | 2 | ||||
-rw-r--r-- | include/linux/rmi.h | 1 |
3 files changed, 67 insertions, 19 deletions
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c index 2b17d8cb3d10..f04fc4152c1f 100644 --- a/drivers/input/rmi4/rmi_driver.c +++ b/drivers/input/rmi4/rmi_driver.c | |||
@@ -215,6 +215,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) | |||
215 | static int rmi_irq_init(struct rmi_device *rmi_dev) | 215 | static int rmi_irq_init(struct rmi_device *rmi_dev) |
216 | { | 216 | { |
217 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | 217 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); |
218 | struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); | ||
218 | int irq_flags = irq_get_trigger_type(pdata->irq); | 219 | int irq_flags = irq_get_trigger_type(pdata->irq); |
219 | int ret; | 220 | int ret; |
220 | 221 | ||
@@ -232,6 +233,8 @@ static int rmi_irq_init(struct rmi_device *rmi_dev) | |||
232 | return ret; | 233 | return ret; |
233 | } | 234 | } |
234 | 235 | ||
236 | data->enabled = true; | ||
237 | |||
235 | return 0; | 238 | return 0; |
236 | } | 239 | } |
237 | 240 | ||
@@ -866,17 +869,54 @@ err_put_fn: | |||
866 | return error; | 869 | return error; |
867 | } | 870 | } |
868 | 871 | ||
869 | int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake) | 872 | void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake) |
870 | { | 873 | { |
871 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | 874 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); |
875 | struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); | ||
872 | int irq = pdata->irq; | 876 | int irq = pdata->irq; |
873 | int retval = 0; | 877 | int irq_flags; |
878 | int retval; | ||
874 | 879 | ||
875 | retval = rmi_suspend_functions(rmi_dev); | 880 | mutex_lock(&data->enabled_mutex); |
876 | if (retval) | 881 | |
877 | dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n", | 882 | if (data->enabled) |
878 | retval); | 883 | goto out; |
884 | |||
885 | enable_irq(irq); | ||
886 | data->enabled = true; | ||
887 | if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) { | ||
888 | retval = disable_irq_wake(irq); | ||
889 | if (!retval) | ||
890 | dev_warn(&rmi_dev->dev, | ||
891 | "Failed to disable irq for wake: %d\n", | ||
892 | retval); | ||
893 | } | ||
894 | |||
895 | /* | ||
896 | * Call rmi_process_interrupt_requests() after enabling irq, | ||
897 | * otherwise we may lose interrupt on edge-triggered systems. | ||
898 | */ | ||
899 | irq_flags = irq_get_trigger_type(pdata->irq); | ||
900 | if (irq_flags & IRQ_TYPE_EDGE_BOTH) | ||
901 | rmi_process_interrupt_requests(rmi_dev); | ||
902 | |||
903 | out: | ||
904 | mutex_unlock(&data->enabled_mutex); | ||
905 | } | ||
906 | |||
907 | void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake) | ||
908 | { | ||
909 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | ||
910 | struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); | ||
911 | int irq = pdata->irq; | ||
912 | int retval; | ||
913 | |||
914 | mutex_lock(&data->enabled_mutex); | ||
915 | |||
916 | if (!data->enabled) | ||
917 | goto out; | ||
879 | 918 | ||
919 | data->enabled = false; | ||
880 | disable_irq(irq); | 920 | disable_irq(irq); |
881 | if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) { | 921 | if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) { |
882 | retval = enable_irq_wake(irq); | 922 | retval = enable_irq_wake(irq); |
@@ -885,24 +925,30 @@ int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake) | |||
885 | "Failed to enable irq for wake: %d\n", | 925 | "Failed to enable irq for wake: %d\n", |
886 | retval); | 926 | retval); |
887 | } | 927 | } |
928 | |||
929 | out: | ||
930 | mutex_unlock(&data->enabled_mutex); | ||
931 | } | ||
932 | |||
933 | int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake) | ||
934 | { | ||
935 | int retval; | ||
936 | |||
937 | retval = rmi_suspend_functions(rmi_dev); | ||
938 | if (retval) | ||
939 | dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n", | ||
940 | retval); | ||
941 | |||
942 | rmi_disable_irq(rmi_dev, enable_wake); | ||
888 | return retval; | 943 | return retval; |
889 | } | 944 | } |
890 | EXPORT_SYMBOL_GPL(rmi_driver_suspend); | 945 | EXPORT_SYMBOL_GPL(rmi_driver_suspend); |
891 | 946 | ||
892 | int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake) | 947 | int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake) |
893 | { | 948 | { |
894 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | ||
895 | int irq = pdata->irq; | ||
896 | int retval; | 949 | int retval; |
897 | 950 | ||
898 | enable_irq(irq); | 951 | rmi_enable_irq(rmi_dev, clear_wake); |
899 | if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) { | ||
900 | retval = disable_irq_wake(irq); | ||
901 | if (!retval) | ||
902 | dev_warn(&rmi_dev->dev, | ||
903 | "Failed to disable irq for wake: %d\n", | ||
904 | retval); | ||
905 | } | ||
906 | 952 | ||
907 | retval = rmi_resume_functions(rmi_dev); | 953 | retval = rmi_resume_functions(rmi_dev); |
908 | if (retval) | 954 | if (retval) |
@@ -916,10 +962,8 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume); | |||
916 | static int rmi_driver_remove(struct device *dev) | 962 | static int rmi_driver_remove(struct device *dev) |
917 | { | 963 | { |
918 | struct rmi_device *rmi_dev = to_rmi_device(dev); | 964 | struct rmi_device *rmi_dev = to_rmi_device(dev); |
919 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | ||
920 | int irq = pdata->irq; | ||
921 | 965 | ||
922 | disable_irq(irq); | 966 | rmi_disable_irq(rmi_dev, false); |
923 | 967 | ||
924 | rmi_f34_remove_sysfs(rmi_dev); | 968 | rmi_f34_remove_sysfs(rmi_dev); |
925 | rmi_free_function_list(rmi_dev); | 969 | rmi_free_function_list(rmi_dev); |
@@ -1108,6 +1152,7 @@ static int rmi_driver_probe(struct device *dev) | |||
1108 | } | 1152 | } |
1109 | 1153 | ||
1110 | mutex_init(&data->irq_mutex); | 1154 | mutex_init(&data->irq_mutex); |
1155 | mutex_init(&data->enabled_mutex); | ||
1111 | 1156 | ||
1112 | retval = rmi_probe_interrupts(data); | 1157 | retval = rmi_probe_interrupts(data); |
1113 | if (retval) | 1158 | if (retval) |
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h index 5b201f369505..c9fe3d3deef3 100644 --- a/drivers/input/rmi4/rmi_driver.h +++ b/drivers/input/rmi4/rmi_driver.h | |||
@@ -101,6 +101,8 @@ int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, | |||
101 | int (*callback)(struct rmi_device *rmi_dev, void *ctx, | 101 | int (*callback)(struct rmi_device *rmi_dev, void *ctx, |
102 | const struct pdt_entry *entry)); | 102 | const struct pdt_entry *entry)); |
103 | int rmi_probe_interrupts(struct rmi_driver_data *data); | 103 | int rmi_probe_interrupts(struct rmi_driver_data *data); |
104 | void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake); | ||
105 | void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake); | ||
104 | int rmi_init_functions(struct rmi_driver_data *data); | 106 | int rmi_init_functions(struct rmi_driver_data *data); |
105 | int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx, | 107 | int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx, |
106 | const struct pdt_entry *pdt); | 108 | const struct pdt_entry *pdt); |
diff --git a/include/linux/rmi.h b/include/linux/rmi.h index 0b118ab47b8d..621f098f1243 100644 --- a/include/linux/rmi.h +++ b/include/linux/rmi.h | |||
@@ -356,6 +356,7 @@ struct rmi_driver_data { | |||
356 | u8 num_tx_electrodes; | 356 | u8 num_tx_electrodes; |
357 | 357 | ||
358 | bool enabled; | 358 | bool enabled; |
359 | struct mutex enabled_mutex; | ||
359 | }; | 360 | }; |
360 | 361 | ||
361 | int rmi_register_transport_device(struct rmi_transport_dev *xport); | 362 | int rmi_register_transport_device(struct rmi_transport_dev *xport); |