media: ddbridge: add helper for IRQ handler setup
authorDaniel Scheller <d.scheller@gmx.net>
Mon, 9 Apr 2018 16:47:40 +0000 (12:47 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Fri, 4 May 2018 14:34:04 +0000 (10:34 -0400)
Introduce the ddb_irq_set() helper function (along with a matching
prototype in ddbridge.h) to improve the set up of the IRQ handlers
and handler_data, and rework storing this data into the ddb_link
using a new ddb_irq struct. This also does the necessary rework
of affected variables. And while at it, always do queue_work in
input_handler() as there's not much of a difference to directly
calling input_work if there's no ptr at input->redi, or queueing
this call.

Picked up from the upstream dddvb-0.9.33 release.

Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/pci/ddbridge/ddbridge-core.c
drivers/media/pci/ddbridge/ddbridge-i2c.c
drivers/media/pci/ddbridge/ddbridge.h

index ea34f1495599fc69d69a8bd1cf642f9556b7fb05..707a479e7b18143736b68bcced2e8f36be1f969e 100644 (file)
@@ -108,6 +108,16 @@ static struct ddb *ddbs[DDB_MAX_ADAPTER];
 /****************************************************************************/
 /****************************************************************************/
 
+struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr,
+                           void (*handler)(void *), void *data)
+{
+       struct ddb_irq *irq = &dev->link[link].irq[nr];
+
+       irq->handler = handler;
+       irq->data = data;
+       return irq;
+}
+
 static void ddb_set_dma_table(struct ddb_io *io)
 {
        struct ddb *dev = io->port->dev;
@@ -2094,26 +2104,18 @@ static void input_work(struct work_struct *work)
        spin_unlock_irqrestore(&dma->lock, flags);
 }
 
-static void input_handler(unsigned long data)
+static void input_handler(void *data)
 {
        struct ddb_input *input = (struct ddb_input *)data;
        struct ddb_dma *dma = input->dma;
 
-       /*
-        * If there is no input connected, input_tasklet() will
-        * just copy pointers and ACK. So, there is no need to go
-        * through the tasklet scheduler.
-        */
-       if (input->redi)
-               queue_work(ddb_wq, &dma->work);
-       else
-               input_work(&dma->work);
+       queue_work(ddb_wq, &dma->work);
 }
 
-static void output_handler(unsigned long data)
+static void output_work(struct work_struct *work)
 {
-       struct ddb_output *output = (struct ddb_output *)data;
-       struct ddb_dma *dma = output->dma;
+       struct ddb_dma *dma = container_of(work, struct ddb_dma, work);
+       struct ddb_output *output = (struct ddb_output *)dma->io;
        struct ddb *dev = output->port->dev;
 
        spin_lock(&dma->lock);
@@ -2129,6 +2131,14 @@ static void output_handler(unsigned long data)
        spin_unlock(&dma->lock);
 }
 
+static void output_handler(void *data)
+{
+       struct ddb_output *output = (struct ddb_output *)data;
+       struct ddb_dma *dma = output->dma;
+
+       queue_work(ddb_wq, &dma->work);
+}
+
 /****************************************************************************/
 /****************************************************************************/
 
@@ -2159,6 +2169,7 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out)
        spin_lock_init(&dma->lock);
        init_waitqueue_head(&dma->wq);
        if (out) {
+               INIT_WORK(&dma->work, output_work);
                dma->regs = rm->odma->base + rm->odma->size * nr;
                dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr;
                dma->num = OUTPUT_DMA_BUFS;
@@ -2203,8 +2214,7 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
                dev_dbg(dev->dev, "init link %u, input %u, handler %u\n",
                        port->lnr, nr, dma_nr + base);
 
-               dev->handler[0][dma_nr + base] = input_handler;
-               dev->handler_data[0][dma_nr + base] = (unsigned long)input;
+               ddb_irq_set(dev, 0, dma_nr + base, &input_handler, input);
                ddb_dma_init(input, dma_nr, 0);
        }
 }
@@ -2229,8 +2239,7 @@ static void ddb_output_init(struct ddb_port *port, int nr)
                const struct ddb_regmap *rm0 = io_regmap(output, 0);
                u32 base = rm0->irq_base_odma;
 
-               dev->handler[0][nr + base] = output_handler;
-               dev->handler_data[0][nr + base] = (unsigned long)output;
+               ddb_irq_set(dev, 0, nr + base, &output_handler, output);
                ddb_dma_init(output, nr, 1);
        }
 }
@@ -2374,8 +2383,9 @@ void ddb_ports_release(struct ddb *dev)
 /****************************************************************************/
 
 #define IRQ_HANDLE(_nr) \
-       do { if ((s & (1UL << ((_nr) & 0x1f))) && dev->handler[0][_nr]) \
-               dev->handler[0][_nr](dev->handler_data[0][_nr]); } \
+       do { if ((s & (1UL << ((_nr) & 0x1f))) && \
+                dev->link[0].irq[_nr].handler) \
+               dev->link[0].irq[_nr].handler(dev->link[0].irq[_nr].data); } \
        while (0)
 
 static void irq_handle_msg(struct ddb *dev, u32 s)
@@ -3186,7 +3196,7 @@ static void tempmon_setfan(struct ddb_link *link)
        ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL);
 }
 
-static void temp_handler(unsigned long data)
+static void temp_handler(void *data)
 {
        struct ddb_link *link = (struct ddb_link *)data;
 
@@ -3209,8 +3219,7 @@ static int tempmon_init(struct ddb_link *link, int first_time)
                memcpy(link->temp_tab, temperature_table,
                       sizeof(temperature_table));
        }
-       dev->handler[l][link->info->tempmon_irq] = temp_handler;
-       dev->handler_data[l][link->info->tempmon_irq] = (unsigned long)link;
+       ddb_irq_set(dev, l, link->info->tempmon_irq, temp_handler, link);
        ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
                          TEMPMON_CONTROL_INTENABLE),
                   TEMPMON_CONTROL);
index 82a9a0e806fc2664aab2cb67699d7642853589b8..667340c86ea7140a41072b99c9c394733a31013c 100644 (file)
@@ -147,7 +147,7 @@ void ddb_i2c_release(struct ddb *dev)
        }
 }
 
-static void i2c_handler(unsigned long priv)
+static void i2c_handler(void *priv)
 {
        struct ddb_i2c *i2c = (struct ddb_i2c *)priv;
 
@@ -210,8 +210,7 @@ int ddb_i2c_init(struct ddb *dev)
                        if (!(dev->link[l].info->i2c_mask & (1 << i)))
                                continue;
                        i2c = &dev->i2c[num];
-                       dev->handler_data[l][i + base] = (unsigned long)i2c;
-                       dev->handler[l][i + base] = i2c_handler;
+                       ddb_irq_set(dev, l, i + base, i2c_handler, i2c);
                        stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
                        if (stat)
                                break;
index dbd5f551ce769d96a8fa37cc8eba4cbb4c220ec6..de9ddf1068bf9245bc6c132db59f1e3e5ab2a32a 100644 (file)
@@ -305,6 +305,11 @@ struct ddb_lnb {
        u32                    fmode;
 };
 
+struct ddb_irq {
+       void                   (*handler)(void *);
+       void                  *data;
+};
+
 struct ddb_link {
        struct ddb            *dev;
        const struct ddb_info *info;
@@ -319,6 +324,7 @@ struct ddb_link {
        spinlock_t             temp_lock; /* lock temp chip access */
        int                    overtemperature_error;
        u8                     temp_tab[11];
+       struct ddb_irq         irq[256];
 };
 
 struct ddb {
@@ -343,9 +349,6 @@ struct ddb {
        struct ddb_dma           idma[DDB_MAX_INPUT];
        struct ddb_dma           odma[DDB_MAX_OUTPUT];
 
-       void                     (*handler[4][256])(unsigned long);
-       unsigned long            handler_data[4][256];
-
        struct device           *ddb_dev;
        u32                      ddb_dev_users;
        u32                      nr;
@@ -369,6 +372,8 @@ int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
 /****************************************************************************/
 
 /* ddbridge-core.c */
+struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr,
+                           void (*handler)(void *), void *data);
 void ddb_ports_detach(struct ddb *dev);
 void ddb_ports_release(struct ddb *dev);
 void ddb_buffers_free(struct ddb *dev);