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

Commit 9f49fb6f authored by Yan He's avatar Yan He
Browse files

msm: pcie: add the checking for MSI type



Add the additional checkings for the case where QGIC based MSI
is not used.

Change-Id: I8b1a704eb9fd94a39a507b8a683755ff32c49d20
Signed-off-by: default avatarYan He <yanhe@codeaurora.org>
parent c6a146c2
Loading
Loading
Loading
Loading
+34 −15
Original line number Diff line number Diff line
@@ -125,10 +125,15 @@ void msm_pcie_config_msi_controller(struct msm_pcie_dev_t *dev)
	wmb();
}

void msm_pcie_destroy_irq(unsigned int irq)
void msm_pcie_destroy_irq(unsigned int irq, struct msm_pcie_dev_t *pcie_dev)
{
	int pos;
	struct msm_pcie_dev_t *dev = irq_get_chip_data(irq);
	struct msm_pcie_dev_t *dev;

	if (pcie_dev)
		dev = pcie_dev;
	else
		dev = irq_get_chip_data(irq);

	if (dev->msi_gicm_addr) {
		PCIE_DBG("destroy QGIC based irq\n");
@@ -140,15 +145,21 @@ void msm_pcie_destroy_irq(unsigned int irq)

	PCIE_DBG("\n");

	if (!dev->msi_gicm_addr)
		dynamic_irq_cleanup(irq);

	PCIE_DBG("Before clear_bit pos:%d msi_irq_in_use:%ld\n",
		pos, *dev->msi_irq_in_use);
	clear_bit(pos, dev->msi_irq_in_use);
	PCIE_DBG("After clear_bit pos:%d msi_irq_in_use:%ld\n",
		pos, *dev->msi_irq_in_use);
}

/* hookup to linux pci msi framework */
void arch_teardown_msi_irq(unsigned int irq)
{
	PCIE_DBG("irq %d deallocated\n", irq);
	msm_pcie_destroy_irq(irq);
	msm_pcie_destroy_irq(irq, NULL);
}

static void msm_pcie_msi_nop(struct irq_data *d)
@@ -178,14 +189,17 @@ again:
	if (pos >= PCIE_MSI_NR_IRQS)
		return -ENOSPC;

	PCIE_DBG("pos:%d msi_irq_in_use:%ld\n", pos, *dev->msi_irq_in_use);

	if (test_and_set_bit(pos, dev->msi_irq_in_use))
		goto again;
	else
		PCIE_DBG("test_and_set_bit is successful\n");

	irq = irq_create_mapping(dev->irq_domain, pos);
	if (!irq)
		return -EINVAL;


	return irq;
}

@@ -230,8 +244,12 @@ again:
	if (pos >= PCIE_MSI_NR_IRQS)
		return -ENOSPC;

	PCIE_DBG("pos:%d msi_irq_in_use:%ld\n", pos, *dev->msi_irq_in_use);

	if (test_and_set_bit(pos, dev->msi_irq_in_use))
		goto again;
	else
		PCIE_DBG("test_and_set_bit is successful\n");

	irq = dev->msi_gicm_base + pos;
	if (!irq) {
@@ -385,10 +403,10 @@ int32_t msm_pcie_irq_init(struct msm_pcie_dev_t *dev)
	}

	/* Create a virtual domain of interrupts */
	if (!dev->msi_gicm_addr) {
		dev->irq_domain = irq_domain_add_linear(dev->pdev->dev.of_node,
			PCIE_MSI_NR_IRQS,
			&msm_pcie_msi_ops,
			dev);
			PCIE_MSI_NR_IRQS, &msm_pcie_msi_ops, dev);

		if (!dev->irq_domain) {
			pr_err("PCIe: Unable to initialize irq domain\n");
			disable_irq(dev->wake_n);
@@ -396,6 +414,7 @@ int32_t msm_pcie_irq_init(struct msm_pcie_dev_t *dev)
		}

		msi_start = irq_create_mapping(dev->irq_domain, 0);
	}

	return 0;
}