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>
This commit is contained in:
Philipp Zabel 2017-05-08 12:45:52 +02:00
parent e1e9733cd3
commit 93adc8b570
2 changed files with 17 additions and 14 deletions

View File

@ -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];
if (channel->busy) {
list_for_each_entry(channel, &ipu->channels, list) {
if (channel->num == num) {
channel = ERR_PTR(-EBUSY);
goto out;
}
}
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);

View File

@ -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;