aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/input/rmi4/rmi_driver.c49
-rw-r--r--include/linux/rmi.h11
2 files changed, 58 insertions, 2 deletions
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index a718e51afb0b..85062e414e73 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -191,16 +191,53 @@ static int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
191 return 0; 191 return 0;
192} 192}
193 193
194void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
195 void *data, size_t size)
196{
197 struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
198 struct rmi4_attn_data attn_data;
199 void *fifo_data;
200
201 if (!drvdata->enabled)
202 return;
203
204 fifo_data = kmemdup(data, size, GFP_ATOMIC);
205 if (!fifo_data)
206 return;
207
208 attn_data.irq_status = irq_status;
209 attn_data.size = size;
210 attn_data.data = fifo_data;
211
212 kfifo_put(&drvdata->attn_fifo, attn_data);
213}
214EXPORT_SYMBOL_GPL(rmi_set_attn_data);
215
194static irqreturn_t rmi_irq_fn(int irq, void *dev_id) 216static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
195{ 217{
196 struct rmi_device *rmi_dev = dev_id; 218 struct rmi_device *rmi_dev = dev_id;
197 int ret; 219 struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
220 struct rmi4_attn_data attn_data = {0};
221 int ret, count;
222
223 count = kfifo_get(&drvdata->attn_fifo, &attn_data);
224 if (count) {
225 *(drvdata->irq_status) = attn_data.irq_status;
226 rmi_dev->xport->attn_data = attn_data.data;
227 rmi_dev->xport->attn_size = attn_data.size;
228 }
198 229
199 ret = rmi_process_interrupt_requests(rmi_dev); 230 ret = rmi_process_interrupt_requests(rmi_dev);
200 if (ret) 231 if (ret)
201 rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, 232 rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
202 "Failed to process interrupt request: %d\n", ret); 233 "Failed to process interrupt request: %d\n", ret);
203 234
235 if (count)
236 kfree(attn_data.data);
237
238 if (!kfifo_is_empty(&drvdata->attn_fifo))
239 return rmi_irq_fn(irq, dev_id);
240
204 return IRQ_HANDLED; 241 return IRQ_HANDLED;
205} 242}
206 243
@@ -880,8 +917,9 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
880{ 917{
881 struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); 918 struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
882 struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev); 919 struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
920 struct rmi4_attn_data attn_data = {0};
883 int irq = pdata->irq; 921 int irq = pdata->irq;
884 int retval; 922 int retval, count;
885 923
886 mutex_lock(&data->enabled_mutex); 924 mutex_lock(&data->enabled_mutex);
887 925
@@ -898,6 +936,13 @@ void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
898 retval); 936 retval);
899 } 937 }
900 938
939 /* make sure the fifo is clean */
940 while (!kfifo_is_empty(&data->attn_fifo)) {
941 count = kfifo_get(&data->attn_fifo, &attn_data);
942 if (count)
943 kfree(attn_data.data);
944 }
945
901out: 946out:
902 mutex_unlock(&data->enabled_mutex); 947 mutex_unlock(&data->enabled_mutex);
903} 948}
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 7780e40a2573..1d4865621493 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/input.h> 15#include <linux/input.h>
16#include <linux/kfifo.h>
16#include <linux/list.h> 17#include <linux/list.h>
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/types.h> 19#include <linux/types.h>
@@ -331,6 +332,12 @@ struct rmi_device {
331 332
332}; 333};
333 334
335struct rmi4_attn_data {
336 unsigned long irq_status;
337 size_t size;
338 void *data;
339};
340
334struct rmi_driver_data { 341struct rmi_driver_data {
335 struct list_head function_list; 342 struct list_head function_list;
336 343
@@ -357,11 +364,15 @@ struct rmi_driver_data {
357 364
358 bool enabled; 365 bool enabled;
359 struct mutex enabled_mutex; 366 struct mutex enabled_mutex;
367 DECLARE_KFIFO(attn_fifo, struct rmi4_attn_data, 16);
360}; 368};
361 369
362int rmi_register_transport_device(struct rmi_transport_dev *xport); 370int rmi_register_transport_device(struct rmi_transport_dev *xport);
363void rmi_unregister_transport_device(struct rmi_transport_dev *xport); 371void rmi_unregister_transport_device(struct rmi_transport_dev *xport);
364 372
373void rmi_set_attn_data(struct rmi_device *rmi_dev, unsigned long irq_status,
374 void *data, size_t size);
375
365int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake); 376int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake);
366int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake); 377int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake);
367#endif 378#endif