diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2017-05-08 12:45:52 +0200 |
---|---|---|
committer | Philipp Zabel <p.zabel@pengutronix.de> | 2017-06-08 08:57:19 +0200 |
commit | 93adc8b5705c14d16be382d43699d2ba71248a4b (patch) | |
tree | 22324a2cf6b2948a903e609b80d7741aa88b3ae6 /drivers/gpu/ipu-v3 | |
parent | e1e9733cd37908a9ba61e29154561f0c81420e06 (diff) |
gpu: ipu-v3: allocate ipuv3_channels as needed
Most of the 64 IPUv3 DMA channels are never used, some of them (channels
16, 30, 32, 34-39, and 53-63) are even marked as reserved.
Allocate the channel control structure only when a channel is actually
requested, replace the fixed size array with a list, and remove the
unused enabled and busy fields from the ipuv3_channel structure.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers/gpu/ipu-v3')
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-common.c | 23 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-prv.h | 8 |
2 files changed, 17 insertions, 14 deletions
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 16d556816b5f..61310f8be309 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -274,15 +274,22 @@ struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num) mutex_lock(&ipu->channel_lock); - channel = &ipu->channel[num]; + list_for_each_entry(channel, &ipu->channels, list) { + if (channel->num == num) { + channel = ERR_PTR(-EBUSY); + goto out; + } + } - if (channel->busy) { - channel = ERR_PTR(-EBUSY); + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) { + channel = ERR_PTR(-ENOMEM); goto out; } - channel->busy = true; channel->num = num; + channel->ipu = ipu; + list_add(&channel->list, &ipu->channels); out: mutex_unlock(&ipu->channel_lock); @@ -299,7 +306,8 @@ void ipu_idmac_put(struct ipuv3_channel *channel) mutex_lock(&ipu->channel_lock); - channel->busy = false; + list_del(&channel->list); + kfree(channel); mutex_unlock(&ipu->channel_lock); } @@ -1376,7 +1384,7 @@ static int ipu_probe(struct platform_device *pdev) struct ipu_soc *ipu; struct resource *res; unsigned long ipu_base; - int i, ret, irq_sync, irq_err; + int ret, irq_sync, irq_err; const struct ipu_devtype *devtype; devtype = of_device_get_match_data(&pdev->dev); @@ -1409,13 +1417,12 @@ static int ipu_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - for (i = 0; i < 64; i++) - ipu->channel[i].ipu = ipu; ipu->devtype = devtype; ipu->ipu_type = devtype->type; spin_lock_init(&ipu->lock); mutex_init(&ipu->channel_lock); + INIT_LIST_HEAD(&ipu->channels); dev_dbg(&pdev->dev, "cm_reg: 0x%08lx\n", ipu_base + devtype->cm_ofs); diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index ca2a223a0d1e..b6e22d64159f 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -157,11 +157,8 @@ enum ipu_modules { struct ipuv3_channel { unsigned int num; - - bool enabled; - bool busy; - struct ipu_soc *ipu; + struct list_head list; }; struct ipu_cpmem; @@ -184,6 +181,7 @@ struct ipu_soc { enum ipuv3_type ipu_type; spinlock_t lock; struct mutex channel_lock; + struct list_head channels; void __iomem *cm_reg; void __iomem *idmac_reg; @@ -193,8 +191,6 @@ struct ipu_soc { struct clk *clk; - struct ipuv3_channel channel[64]; - int irq_sync; int irq_err; struct irq_domain *domain; |