aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/staging/wfx/bus_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/wfx/bus_spi.c')
-rw-r--r--drivers/staging/wfx/bus_spi.c44
1 files changed, 20 insertions, 24 deletions
diff --git a/drivers/staging/wfx/bus_spi.c b/drivers/staging/wfx/bus_spi.c
index 61e99b09decb..e8da61fb096b 100644
--- a/drivers/staging/wfx/bus_spi.c
+++ b/drivers/staging/wfx/bus_spi.c
@@ -12,6 +12,7 @@
#include <linux/gpio/consumer.h>
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/of.h>
#include "bus.h"
@@ -39,7 +40,6 @@ struct wfx_spi_priv {
struct spi_device *func;
struct wfx_dev *core;
struct gpio_desc *gpio_reset;
- struct work_struct request_rx;
bool need_swab;
};
@@ -140,25 +140,30 @@ static irqreturn_t wfx_spi_irq_handler(int irq, void *priv)
{
struct wfx_spi_priv *bus = priv;
- if (!bus->core) {
- WARN(!bus->core, "race condition in driver init/deinit");
- return IRQ_NONE;
- }
- queue_work(system_highpri_wq, &bus->request_rx);
+ wfx_bh_request_rx(bus->core);
return IRQ_HANDLED;
}
-static void wfx_spi_request_rx(struct work_struct *work)
+static int wfx_spi_irq_subscribe(void *priv)
{
- struct wfx_spi_priv *bus =
- container_of(work, struct wfx_spi_priv, request_rx);
-
- wfx_bh_request_rx(bus->core);
+ struct wfx_spi_priv *bus = priv;
+ u32 flags;
+
+ flags = irq_get_trigger_type(bus->func->irq);
+ if (!flags)
+ flags = IRQF_TRIGGER_HIGH;
+ flags |= IRQF_ONESHOT;
+ return devm_request_threaded_irq(&bus->func->dev, bus->func->irq, NULL,
+ wfx_spi_irq_handler, IRQF_ONESHOT,
+ "wfx", bus);
}
-static void wfx_flush_irq_work(void *w)
+static int wfx_spi_irq_unsubscribe(void *priv)
{
- flush_work(w);
+ struct wfx_spi_priv *bus = priv;
+
+ devm_free_irq(&bus->func->dev, bus->func->irq, bus);
+ return 0;
}
static size_t wfx_spi_align_size(void *priv, size_t size)
@@ -170,6 +175,8 @@ static size_t wfx_spi_align_size(void *priv, size_t size)
static const struct hwbus_ops wfx_spi_hwbus_ops = {
.copy_from_io = wfx_spi_copy_from_io,
.copy_to_io = wfx_spi_copy_to_io,
+ .irq_subscribe = wfx_spi_irq_subscribe,
+ .irq_unsubscribe = wfx_spi_irq_unsubscribe,
.lock = wfx_spi_lock,
.unlock = wfx_spi_unlock,
.align_size = wfx_spi_align_size,
@@ -216,22 +223,11 @@ static int wfx_spi_probe(struct spi_device *func)
usleep_range(2000, 2500);
}
- INIT_WORK(&bus->request_rx, wfx_spi_request_rx);
bus->core = wfx_init_common(&func->dev, &wfx_spi_pdata,
&wfx_spi_hwbus_ops, bus);
if (!bus->core)
return -EIO;
- ret = devm_add_action_or_reset(&func->dev, wfx_flush_irq_work,
- &bus->request_rx);
- if (ret)
- return ret;
-
- ret = devm_request_irq(&func->dev, func->irq, wfx_spi_irq_handler,
- IRQF_TRIGGER_RISING, "wfx", bus);
- if (ret)
- return ret;
-
return wfx_probe(bus->core);
}