mfd: Drop twl4030-irq's edge_work
authorFelipe Balbi <balbi@ti.com>
Thu, 30 Jun 2011 09:51:08 +0000 (12:51 +0300)
committerSamuel Ortiz <sameo@linux.intel.com>
Mon, 24 Oct 2011 12:09:11 +0000 (14:09 +0200)
... and do all the synchronization with the
hardware during bus_sync_unlock. We can now
remove all the workqueues.

Signed-off-by: Felipe Balbi <balbi@ti.com>
Reviewed-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
drivers/mfd/twl4030-irq.c

index bf62389fc7e54a4e1c50e20bd5870d5353ee86d9..1b9ab2f40d5bba99734c9b01b8a95ef62f48f195 100644 (file)
@@ -422,8 +422,6 @@ static inline void activate_irq(int irq)
 
 /*----------------------------------------------------------------------*/
 
-static struct workqueue_struct *wq;
-
 struct sih_agent {
        int                     irq_base;
        const struct sih        *sih;
@@ -432,68 +430,10 @@ struct sih_agent {
        bool                    imr_change_pending;
 
        u32                     edge_change;
-       struct work_struct      edge_work;
 
        struct mutex            irq_lock;
 };
 
-static void twl4030_sih_do_edge(struct work_struct *work)
-{
-       struct sih_agent        *agent;
-       const struct sih        *sih;
-       u8                      bytes[6];
-       u32                     edge_change;
-       int                     status;
-
-       agent = container_of(work, struct sih_agent, edge_work);
-
-       /* see what work we have */
-       edge_change = agent->edge_change;
-       agent->edge_change = 0;
-       sih = edge_change ? agent->sih : NULL;
-       if (!sih)
-               return;
-
-       /* Read, reserving first byte for write scratch.  Yes, this
-        * could be cached for some speedup ... but be careful about
-        * any processor on the other IRQ line, EDR registers are
-        * shared.
-        */
-       status = twl_i2c_read(sih->module, bytes + 1,
-                       sih->edr_offset, sih->bytes_edr);
-       if (status) {
-               pr_err("twl4030: %s, %s --> %d\n", __func__,
-                               "read", status);
-               return;
-       }
-
-       /* Modify only the bits we know must change */
-       while (edge_change) {
-               int             i = fls(edge_change) - 1;
-               struct irq_data *idata = irq_get_irq_data(i + agent->irq_base);
-               int             byte = 1 + (i >> 2);
-               int             off = (i & 0x3) * 2;
-               unsigned int    type;
-
-               bytes[byte] &= ~(0x03 << off);
-
-               type = irqd_get_trigger_type(idata);
-               if (type & IRQ_TYPE_EDGE_RISING)
-                       bytes[byte] |= BIT(off + 1);
-               if (type & IRQ_TYPE_EDGE_FALLING)
-                       bytes[byte] |= BIT(off + 0);
-
-               edge_change &= ~BIT(i);
-       }
-
-       /* Write */
-       status = twl_i2c_write(sih->module, bytes,
-                       sih->edr_offset, sih->bytes_edr);
-       if (status)
-               pr_err("twl4030: %s, %s --> %d\n", __func__,
-                               "write", status);
-}
-
 /*----------------------------------------------------------------------*/
 
 /*
@@ -526,10 +466,8 @@ static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
        if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
                return -EINVAL;
 
-       if (irqd_get_trigger_type(data) != trigger) {
+       if (irqd_get_trigger_type(data) != trigger)
                agent->edge_change |= BIT(data->irq - agent->irq_base);
-               queue_work(wq, &agent->edge_work);
-       }
 
        return 0;
 }
@@ -566,6 +504,56 @@ static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
                                        "write", status);
        }
 
+       if (agent->edge_change) {
+               u32             edge_change;
+               u8              bytes[6];
+
+               edge_change = agent->edge_change;
+               agent->edge_change = 0;
+
+               /*
+                * Read, reserving first byte for write scratch.  Yes, this
+                * could be cached for some speedup ... but be careful about
+                * any processor on the other IRQ line, EDR registers are
+                * shared.
+                */
+               status = twl_i2c_read(sih->module, bytes + 1,
+                               sih->edr_offset, sih->bytes_edr);
+               if (status) {
+                       pr_err("twl4030: %s, %s --> %d\n", __func__,
+                                       "read", status);
+                       return;
+               }
+
+               /* Modify only the bits we know must change */
+               while (edge_change) {
+                       int             i = fls(edge_change) - 1;
+                       struct irq_data *idata;
+                       int             byte = 1 + (i >> 2);
+                       int             off = (i & 0x3) * 2;
+                       unsigned int    type;
+
+                       idata = irq_get_irq_data(i + agent->irq_base);
+
+                       bytes[byte] &= ~(0x03 << off);
+
+                       type = irqd_get_trigger_type(idata);
+                       if (type & IRQ_TYPE_EDGE_RISING)
+                               bytes[byte] |= BIT(off + 1);
+                       if (type & IRQ_TYPE_EDGE_FALLING)
+                               bytes[byte] |= BIT(off + 0);
+
+                       edge_change &= ~BIT(i);
+               }
+
+               /* Write */
+               status = twl_i2c_write(sih->module, bytes,
+                               sih->edr_offset, sih->bytes_edr);
+               if (status)
+                       pr_err("twl4030: %s, %s --> %d\n", __func__,
+                                       "write", status);
+       }
+
        mutex_unlock(&agent->irq_lock);
 }
 
@@ -672,7 +660,6 @@ int twl4030_sih_setup(int module)
        agent->sih = sih;
        agent->imr = ~0;
        mutex_init(&agent->irq_lock);
-       INIT_WORK(&agent->edge_work, twl4030_sih_do_edge);
 
        for (i = 0; i < sih->bits; i++) {
                irq = irq_base + i;
@@ -720,12 +707,6 @@ int twl4030_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
        if (status < 0)
                return status;
 
-       wq = create_singlethread_workqueue("twl4030-irqchip");
-       if (!wq) {
-               pr_err("twl4030: workqueue FAIL\n");
-               return -ESRCH;
-       }
-
        twl4030_irq_base = irq_base;
 
        /* install an irq handler for each of the SIH modules;
@@ -766,8 +747,7 @@ fail_rqirq:
 fail:
        for (i = irq_base; i < irq_end; i++)
                irq_set_chip_and_handler(i, NULL, NULL);
-       destroy_workqueue(wq);
-       wq = NULL;
+
        return status;
 }