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

Commit dd74929d authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: tspp: Request IRQs on first use"

parents c40c6372 83585886
Loading
Loading
Loading
Loading
+88 −36
Original line number Diff line number Diff line
@@ -464,7 +464,6 @@ struct tspp_device {
	struct dentry *debugfs_regs[ARRAY_SIZE(debugfs_tspp_regs)];
};


static int tspp_key_entry;
static u32 channel_id;  /* next channel id number to assign */

@@ -909,9 +908,11 @@ static int tspp_start_tsif(struct tspp_tsif_device *tsif_device)
	}

	ctl = readl_relaxed(tsif_device->base + TSIF_STS_CTL_OFF);
	tsif_device->ref_count++;
	if (!(ctl & TSIF_STS_CTL_START))
		return -EBUSY;

	return (ctl & TSIF_STS_CTL_START) ? 0 : -EBUSY;
	tsif_device->ref_count++;
	return 0;
}

static void tspp_stop_tsif(struct tspp_tsif_device *tsif_device)
@@ -1252,6 +1253,56 @@ static void tspp_destroy_buffers(u32 channel_id, struct tspp_channel *channel)
	}
}

static int msm_tspp_req_irqs(struct tspp_device *device)
{
	int rc;
	int i;
	int j;

	rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
		dev_name(&device->pdev->dev), device);
	if (rc) {
		dev_err(&device->pdev->dev,
			"failed to request TSPP IRQ %d : %d",
			device->tspp_irq, rc);
		return rc;
	}

	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
		rc = request_irq(device->tsif[i].tsif_irq,
			tsif_isr, IRQF_SHARED, dev_name(&device->pdev->dev),
			&device->tsif[i]);
		if (rc) {
			dev_err(&device->pdev->dev,
				"failed to request TSIF%d IRQ: %d",
				i, rc);
			goto failed;
		}
	}

	return 0;

failed:
	free_irq(device->tspp_irq, device);
	for (j = 0; j < i; j++)
		free_irq(device->tsif[j].tsif_irq, device);

	return rc;
}

static inline void msm_tspp_free_irqs(struct tspp_device *device)
{
	int i;

	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
		if (device->tsif[i].tsif_irq)
			free_irq(device->tsif[i].tsif_irq,  &device->tsif[i]);
	}

	if (device->tspp_irq)
		free_irq(device->tspp_irq, device);
}

/*** TSPP API functions ***/

/**
@@ -1268,6 +1319,8 @@ int tspp_open_stream(u32 dev, u32 channel_id,
			struct tspp_select_source *source)
{
	u32 val;
	int rc;
	bool req_irq = false;
	struct tspp_device *pdev;
	struct tspp_channel *channel;

@@ -1296,16 +1349,30 @@ int tspp_open_stream(u32 dev, u32 channel_id,
			source->data_inverse, source->sync_inverse,
			source->enable_inverse);

	/* Request IRQ resources on first open */
	if ((source->source == TSPP_SOURCE_TSIF0 ||
		source->source == TSPP_SOURCE_TSIF1) &&
		(pdev->tsif[0].ref_count + pdev->tsif[1].ref_count) == 0) {
		rc = msm_tspp_req_irqs(pdev);
		if (rc) {
			pr_err("tspp: error requesting irqs\n");
			return rc;
		}
		req_irq = true;
	}

	switch (source->source) {
	case TSPP_SOURCE_TSIF0:
		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
			rc = -EBUSY;
			pr_err("tspp: error enabling tsif0 GPIOs\n");
			return -EBUSY;
			goto free_irq;
		}
		/* make sure TSIF0 is running & enabled */
		if (tspp_start_tsif(&pdev->tsif[0]) != 0) {
			rc = -EBUSY;
			pr_err("tspp: error starting tsif0");
			return -EBUSY;
			goto free_irq;
		}
		if (pdev->tsif[0].ref_count == 1) {
			val = readl_relaxed(pdev->base + TSPP_CONTROL);
@@ -1316,13 +1383,15 @@ int tspp_open_stream(u32 dev, u32 channel_id,
		break;
	case TSPP_SOURCE_TSIF1:
		if (tspp_config_gpios(pdev, channel->src, 1) != 0) {
			rc = -EBUSY;
			pr_err("tspp: error enabling tsif1 GPIOs\n");
			return -EBUSY;
			goto free_irq;
		}
		/* make sure TSIF1 is running & enabled */
		if (tspp_start_tsif(&pdev->tsif[1]) != 0) {
			rc = -EBUSY;
			pr_err("tspp: error starting tsif1");
			return -EBUSY;
			goto free_irq;
		}
		if (pdev->tsif[1].ref_count == 1) {
			val = readl_relaxed(pdev->base + TSPP_CONTROL);
@@ -1340,6 +1409,11 @@ int tspp_open_stream(u32 dev, u32 channel_id,
	}

	return 0;

free_irq:
	if (req_irq)
		msm_tspp_free_irqs(pdev);
	return rc;
}
EXPORT_SYMBOL(tspp_open_stream);

@@ -1355,7 +1429,7 @@ EXPORT_SYMBOL(tspp_open_stream);
int tspp_close_stream(u32 dev, u32 channel_id)
{
	u32 val;
	u32 prev_ref_count;
	u32 prev_ref_count = 0;
	struct tspp_device *pdev;
	struct tspp_channel *channel;

@@ -1404,6 +1478,12 @@ int tspp_close_stream(u32 dev, u32 channel_id)
	}

	channel->src = TSPP_SOURCE_NONE;

	/* Free requested interrupts to save power */
	if ((pdev->tsif[0].ref_count + pdev->tsif[1].ref_count) == 0 &&
		prev_ref_count)
		msm_tspp_free_irqs(pdev);

	return 0;
}
EXPORT_SYMBOL(tspp_close_stream);
@@ -2542,7 +2622,6 @@ static int msm_tspp_map_irqs(struct platform_device *pdev,
				struct tspp_device *device)
{
	int rc;
	int i;

	/* get IRQ numbers from platform information */

@@ -2550,15 +2629,6 @@ static int msm_tspp_map_irqs(struct platform_device *pdev,
	rc = platform_get_irq_byname(pdev, "TSIF_TSPP_IRQ");
	if (rc > 0) {
		device->tspp_irq = rc;
		rc = request_irq(device->tspp_irq, tspp_isr, IRQF_SHARED,
				 dev_name(&pdev->dev), device);
		if (rc) {
			dev_err(&pdev->dev,
				"failed to request TSPP IRQ %d : %d",
				device->tspp_irq, rc);
			device->tspp_irq = 0;
			return -EINVAL;
		}
	} else {
		dev_err(&pdev->dev, "failed to get TSPP IRQ");
		return -EINVAL;
@@ -2581,17 +2651,6 @@ static int msm_tspp_map_irqs(struct platform_device *pdev,
		return -EINVAL;
	}

	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
		rc = request_irq(device->tsif[i].tsif_irq,
				tsif_isr, IRQF_SHARED,
				dev_name(&pdev->dev), &device->tsif[i]);
		if (rc) {
			dev_warn(&pdev->dev, "failed to request TSIF%d IRQ: %d",
				i, rc);
			device->tsif[i].tsif_irq = 0;
		}
	}

	/* map BAM IRQ */
	rc = platform_get_irq_byname(pdev, "TSIF_BAM_IRQ");
	if (rc > 0) {
@@ -2850,13 +2909,6 @@ err_bam:
	for (i = 0; i < TSPP_TSIF_INSTANCES; i++)
		tsif_debugfs_exit(&device->tsif[i]);
err_irq:
	for (i = 0; i < TSPP_TSIF_INSTANCES; i++) {
		if (device->tsif[i].tsif_irq)
			free_irq(device->tsif[i].tsif_irq,  &device->tsif[i]);
	}
	if (device->tspp_irq)
		free_irq(device->tspp_irq, device);

	iounmap(device->bam_props.virt_addr);
err_map_bam:
err_res_bam: