Commit a64ea311 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Dmitry Torokhov

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: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 0d37d63a
...@@ -215,6 +215,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id) ...@@ -215,6 +215,7 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
static int rmi_irq_init(struct rmi_device *rmi_dev) static int rmi_irq_init(struct rmi_device *rmi_dev)
{ {
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
int irq_flags = irq_get_trigger_type(pdata->irq); int irq_flags = irq_get_trigger_type(pdata->irq);
int ret; int ret;
...@@ -232,6 +233,8 @@ static int rmi_irq_init(struct rmi_device *rmi_dev) ...@@ -232,6 +233,8 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
return ret; return ret;
} }
data->enabled = true;
return 0; return 0;
} }
...@@ -866,17 +869,54 @@ static int rmi_create_function(struct rmi_device *rmi_dev, ...@@ -866,17 +869,54 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
return error; return error;
} }
int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake) void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake)
{ {
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
int irq = pdata->irq; int irq = pdata->irq;
int retval = 0; int irq_flags;
int retval;
retval = rmi_suspend_functions(rmi_dev); mutex_lock(&data->enabled_mutex);
if (retval)
dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n", if (data->enabled)
retval); goto out;
enable_irq(irq);
data->enabled = true;
if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) {
retval = disable_irq_wake(irq);
if (!retval)
dev_warn(&rmi_dev->dev,
"Failed to disable irq for wake: %d\n",
retval);
}
/*
* Call rmi_process_interrupt_requests() after enabling irq,
* otherwise we may lose interrupt on edge-triggered systems.
*/
irq_flags = irq_get_trigger_type(pdata->irq);
if (irq_flags & IRQ_TYPE_EDGE_BOTH)
rmi_process_interrupt_requests(rmi_dev);
out:
mutex_unlock(&data->enabled_mutex);
}
void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake)
{
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
int irq = pdata->irq;
int retval;
mutex_lock(&data->enabled_mutex);
if (!data->enabled)
goto out;
data->enabled = false;
disable_irq(irq); disable_irq(irq);
if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) { if (enable_wake && device_may_wakeup(rmi_dev->xport->dev)) {
retval = enable_irq_wake(irq); retval = enable_irq_wake(irq);
...@@ -885,24 +925,30 @@ int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake) ...@@ -885,24 +925,30 @@ int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake)
"Failed to enable irq for wake: %d\n", "Failed to enable irq for wake: %d\n",
retval); retval);
} }
out:
mutex_unlock(&data->enabled_mutex);
}
int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake)
{
int retval;
retval = rmi_suspend_functions(rmi_dev);
if (retval)
dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n",
retval);
rmi_disable_irq(rmi_dev, enable_wake);
return retval; return retval;
} }
EXPORT_SYMBOL_GPL(rmi_driver_suspend); EXPORT_SYMBOL_GPL(rmi_driver_suspend);
int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake) int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake)
{ {
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
int irq = pdata->irq;
int retval; int retval;
enable_irq(irq); rmi_enable_irq(rmi_dev, clear_wake);
if (clear_wake && device_may_wakeup(rmi_dev->xport->dev)) {
retval = disable_irq_wake(irq);
if (!retval)
dev_warn(&rmi_dev->dev,
"Failed to disable irq for wake: %d\n",
retval);
}
retval = rmi_resume_functions(rmi_dev); retval = rmi_resume_functions(rmi_dev);
if (retval) if (retval)
...@@ -916,10 +962,8 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume); ...@@ -916,10 +962,8 @@ EXPORT_SYMBOL_GPL(rmi_driver_resume);
static int rmi_driver_remove(struct device *dev) static int rmi_driver_remove(struct device *dev)
{ {
struct rmi_device *rmi_dev = to_rmi_device(dev); struct rmi_device *rmi_dev = to_rmi_device(dev);
struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev);
int irq = pdata->irq;
disable_irq(irq); rmi_disable_irq(rmi_dev, false);
rmi_f34_remove_sysfs(rmi_dev); rmi_f34_remove_sysfs(rmi_dev);
rmi_free_function_list(rmi_dev); rmi_free_function_list(rmi_dev);
...@@ -1108,6 +1152,7 @@ static int rmi_driver_probe(struct device *dev) ...@@ -1108,6 +1152,7 @@ static int rmi_driver_probe(struct device *dev)
} }
mutex_init(&data->irq_mutex); mutex_init(&data->irq_mutex);
mutex_init(&data->enabled_mutex);
retval = rmi_probe_interrupts(data); retval = rmi_probe_interrupts(data);
if (retval) if (retval)
......
...@@ -101,6 +101,8 @@ int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx, ...@@ -101,6 +101,8 @@ int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx,
int (*callback)(struct rmi_device *rmi_dev, void *ctx, int (*callback)(struct rmi_device *rmi_dev, void *ctx,
const struct pdt_entry *entry)); const struct pdt_entry *entry));
int rmi_probe_interrupts(struct rmi_driver_data *data); int rmi_probe_interrupts(struct rmi_driver_data *data);
void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake);
void rmi_disable_irq(struct rmi_device *rmi_dev, bool enable_wake);
int rmi_init_functions(struct rmi_driver_data *data); int rmi_init_functions(struct rmi_driver_data *data);
int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx, int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx,
const struct pdt_entry *pdt); const struct pdt_entry *pdt);
......
...@@ -356,6 +356,7 @@ struct rmi_driver_data { ...@@ -356,6 +356,7 @@ struct rmi_driver_data {
u8 num_tx_electrodes; u8 num_tx_electrodes;
bool enabled; bool enabled;
struct mutex enabled_mutex;
}; };
int rmi_register_transport_device(struct rmi_transport_dev *xport); int rmi_register_transport_device(struct rmi_transport_dev *xport);
......
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