Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93adc8b5 authored by Philipp Zabel's avatar Philipp Zabel
Browse files

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: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent e1e9733c
Loading
Loading
Loading
Loading
+15 −8
Original line number Diff line number Diff line
@@ -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);
+2 −6
Original line number Diff line number Diff line
@@ -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;