Commit 1dda87ac authored by Daniel Scheller's avatar Daniel Scheller Committed by Mauro Carvalho Chehab

media: ddbridge: add helper for IRQ handler setup

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: default avatarDaniel Scheller <d.scheller@gmx.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 6bf0f051
...@@ -108,6 +108,16 @@ static struct ddb *ddbs[DDB_MAX_ADAPTER]; ...@@ -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) static void ddb_set_dma_table(struct ddb_io *io)
{ {
struct ddb *dev = io->port->dev; struct ddb *dev = io->port->dev;
...@@ -2094,26 +2104,18 @@ static void input_work(struct work_struct *work) ...@@ -2094,26 +2104,18 @@ static void input_work(struct work_struct *work)
spin_unlock_irqrestore(&dma->lock, flags); 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_input *input = (struct ddb_input *)data;
struct ddb_dma *dma = input->dma; 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); queue_work(ddb_wq, &dma->work);
else
input_work(&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 = container_of(work, struct ddb_dma, work);
struct ddb_dma *dma = output->dma; struct ddb_output *output = (struct ddb_output *)dma->io;
struct ddb *dev = output->port->dev; struct ddb *dev = output->port->dev;
spin_lock(&dma->lock); spin_lock(&dma->lock);
...@@ -2129,6 +2131,14 @@ static void output_handler(unsigned long data) ...@@ -2129,6 +2131,14 @@ static void output_handler(unsigned long data)
spin_unlock(&dma->lock); 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) ...@@ -2159,6 +2169,7 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out)
spin_lock_init(&dma->lock); spin_lock_init(&dma->lock);
init_waitqueue_head(&dma->wq); init_waitqueue_head(&dma->wq);
if (out) { if (out) {
INIT_WORK(&dma->work, output_work);
dma->regs = rm->odma->base + rm->odma->size * nr; dma->regs = rm->odma->base + rm->odma->size * nr;
dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr; dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr;
dma->num = OUTPUT_DMA_BUFS; dma->num = OUTPUT_DMA_BUFS;
...@@ -2203,8 +2214,7 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) ...@@ -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", dev_dbg(dev->dev, "init link %u, input %u, handler %u\n",
port->lnr, nr, dma_nr + base); port->lnr, nr, dma_nr + base);
dev->handler[0][dma_nr + base] = input_handler; ddb_irq_set(dev, 0, dma_nr + base, &input_handler, input);
dev->handler_data[0][dma_nr + base] = (unsigned long)input;
ddb_dma_init(input, dma_nr, 0); ddb_dma_init(input, dma_nr, 0);
} }
} }
...@@ -2229,8 +2239,7 @@ static void ddb_output_init(struct ddb_port *port, int nr) ...@@ -2229,8 +2239,7 @@ static void ddb_output_init(struct ddb_port *port, int nr)
const struct ddb_regmap *rm0 = io_regmap(output, 0); const struct ddb_regmap *rm0 = io_regmap(output, 0);
u32 base = rm0->irq_base_odma; u32 base = rm0->irq_base_odma;
dev->handler[0][nr + base] = output_handler; ddb_irq_set(dev, 0, nr + base, &output_handler, output);
dev->handler_data[0][nr + base] = (unsigned long)output;
ddb_dma_init(output, nr, 1); ddb_dma_init(output, nr, 1);
} }
} }
...@@ -2374,8 +2383,9 @@ void ddb_ports_release(struct ddb *dev) ...@@ -2374,8 +2383,9 @@ void ddb_ports_release(struct ddb *dev)
/****************************************************************************/ /****************************************************************************/
#define IRQ_HANDLE(_nr) \ #define IRQ_HANDLE(_nr) \
do { if ((s & (1UL << ((_nr) & 0x1f))) && dev->handler[0][_nr]) \ do { if ((s & (1UL << ((_nr) & 0x1f))) && \
dev->handler[0][_nr](dev->handler_data[0][_nr]); } \ dev->link[0].irq[_nr].handler) \
dev->link[0].irq[_nr].handler(dev->link[0].irq[_nr].data); } \
while (0) while (0)
static void irq_handle_msg(struct ddb *dev, u32 s) static void irq_handle_msg(struct ddb *dev, u32 s)
...@@ -3186,7 +3196,7 @@ static void tempmon_setfan(struct ddb_link *link) ...@@ -3186,7 +3196,7 @@ static void tempmon_setfan(struct ddb_link *link)
ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL); 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; struct ddb_link *link = (struct ddb_link *)data;
...@@ -3209,8 +3219,7 @@ static int tempmon_init(struct ddb_link *link, int first_time) ...@@ -3209,8 +3219,7 @@ static int tempmon_init(struct ddb_link *link, int first_time)
memcpy(link->temp_tab, temperature_table, memcpy(link->temp_tab, temperature_table,
sizeof(temperature_table)); sizeof(temperature_table));
} }
dev->handler[l][link->info->tempmon_irq] = temp_handler; ddb_irq_set(dev, l, link->info->tempmon_irq, temp_handler, link);
dev->handler_data[l][link->info->tempmon_irq] = (unsigned long)link;
ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN | ddblwritel(link, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
TEMPMON_CONTROL_INTENABLE), TEMPMON_CONTROL_INTENABLE),
TEMPMON_CONTROL); TEMPMON_CONTROL);
......
...@@ -147,7 +147,7 @@ void ddb_i2c_release(struct ddb *dev) ...@@ -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; struct ddb_i2c *i2c = (struct ddb_i2c *)priv;
...@@ -210,8 +210,7 @@ int ddb_i2c_init(struct ddb *dev) ...@@ -210,8 +210,7 @@ int ddb_i2c_init(struct ddb *dev)
if (!(dev->link[l].info->i2c_mask & (1 << i))) if (!(dev->link[l].info->i2c_mask & (1 << i)))
continue; continue;
i2c = &dev->i2c[num]; i2c = &dev->i2c[num];
dev->handler_data[l][i + base] = (unsigned long)i2c; ddb_irq_set(dev, l, i + base, i2c_handler, i2c);
dev->handler[l][i + base] = i2c_handler;
stat = ddb_i2c_add(dev, i2c, regmap, l, i, num); stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
if (stat) if (stat)
break; break;
......
...@@ -305,6 +305,11 @@ struct ddb_lnb { ...@@ -305,6 +305,11 @@ struct ddb_lnb {
u32 fmode; u32 fmode;
}; };
struct ddb_irq {
void (*handler)(void *);
void *data;
};
struct ddb_link { struct ddb_link {
struct ddb *dev; struct ddb *dev;
const struct ddb_info *info; const struct ddb_info *info;
...@@ -319,6 +324,7 @@ struct ddb_link { ...@@ -319,6 +324,7 @@ struct ddb_link {
spinlock_t temp_lock; /* lock temp chip access */ spinlock_t temp_lock; /* lock temp chip access */
int overtemperature_error; int overtemperature_error;
u8 temp_tab[11]; u8 temp_tab[11];
struct ddb_irq irq[256];
}; };
struct ddb { struct ddb {
...@@ -343,9 +349,6 @@ struct ddb { ...@@ -343,9 +349,6 @@ struct ddb {
struct ddb_dma idma[DDB_MAX_INPUT]; struct ddb_dma idma[DDB_MAX_INPUT];
struct ddb_dma odma[DDB_MAX_OUTPUT]; struct ddb_dma odma[DDB_MAX_OUTPUT];
void (*handler[4][256])(unsigned long);
unsigned long handler_data[4][256];
struct device *ddb_dev; struct device *ddb_dev;
u32 ddb_dev_users; u32 ddb_dev_users;
u32 nr; u32 nr;
...@@ -369,6 +372,8 @@ int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len); ...@@ -369,6 +372,8 @@ int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
/****************************************************************************/ /****************************************************************************/
/* ddbridge-core.c */ /* 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_detach(struct ddb *dev);
void ddb_ports_release(struct ddb *dev); void ddb_ports_release(struct ddb *dev);
void ddb_buffers_free(struct ddb *dev); void ddb_buffers_free(struct ddb *dev);
......
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