Commit 2ee6181f authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

Merge branch 'pci/controller/rcar-host'

- Pass the correct IRQ domain to generic_handle_domain_irq() to fix a
  regression when converting to msi_create_parent_irq_domain() (Claudiu
  Beznea)

- Drop the spinlock protecting the PMSR register; it's no longer required
  since pci_lock already serializes accesses (Marek Vasut)

- Convert struct rcar_msi mask_lock to raw spinlock to avoid a lock nesting
  error (Marek Vasut)

* pci/controller/rcar-host:
  PCI: rcar-host: Convert struct rcar_msi mask_lock into raw spinlock
  PCI: rcar-host: Drop PMSR spinlock
  PCI: rcar-host: Pass proper IRQ domain to generic_handle_domain_irq()
parents 86a3f3db 5ed35b4d
Loading
Loading
Loading
Loading
+16 −26
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
 */

#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
@@ -38,7 +39,7 @@ struct rcar_msi {
	DECLARE_BITMAP(used, INT_PCI_MSI_NR);
	struct irq_domain *domain;
	struct mutex map_lock;
	spinlock_t mask_lock;
	raw_spinlock_t mask_lock;
	int irq1;
	int irq2;
};
@@ -52,20 +53,13 @@ struct rcar_pcie_host {
	int			(*phy_init_fn)(struct rcar_pcie_host *host);
};

static DEFINE_SPINLOCK(pmsr_lock);

static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base)
{
	unsigned long flags;
	u32 pmsr, val;
	int ret = 0;

	spin_lock_irqsave(&pmsr_lock, flags);

	if (!pcie_base || pm_runtime_suspended(pcie_dev)) {
		ret = -EINVAL;
		goto unlock_exit;
	}
	if (!pcie_base || pm_runtime_suspended(pcie_dev))
		return -EINVAL;

	pmsr = readl(pcie_base + PMSR);

@@ -87,8 +81,6 @@ static int rcar_pcie_wakeup(struct device *pcie_dev, void __iomem *pcie_base)
		writel(L1FAEG | PMEL1RX, pcie_base + PMSR);
	}

unlock_exit:
	spin_unlock_irqrestore(&pmsr_lock, flags);
	return ret;
}

@@ -584,7 +576,7 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
		unsigned int index = find_first_bit(&reg, 32);
		int ret;

		ret = generic_handle_domain_irq(msi->domain->parent, index);
		ret = generic_handle_domain_irq(msi->domain, index);
		if (ret) {
			/* Unknown MSI, just clear it */
			dev_dbg(dev, "unexpected MSI\n");
@@ -611,28 +603,26 @@ static void rcar_msi_irq_mask(struct irq_data *d)
{
	struct rcar_msi *msi = irq_data_get_irq_chip_data(d);
	struct rcar_pcie *pcie = &msi_to_host(msi)->pcie;
	unsigned long flags;
	u32 value;

	spin_lock_irqsave(&msi->mask_lock, flags);
	scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) {
		value = rcar_pci_read_reg(pcie, PCIEMSIIER);
		value &= ~BIT(d->hwirq);
		rcar_pci_write_reg(pcie, value, PCIEMSIIER);
	spin_unlock_irqrestore(&msi->mask_lock, flags);
	}
}

static void rcar_msi_irq_unmask(struct irq_data *d)
{
	struct rcar_msi *msi = irq_data_get_irq_chip_data(d);
	struct rcar_pcie *pcie = &msi_to_host(msi)->pcie;
	unsigned long flags;
	u32 value;

	spin_lock_irqsave(&msi->mask_lock, flags);
	scoped_guard(raw_spinlock_irqsave, &msi->mask_lock) {
		value = rcar_pci_read_reg(pcie, PCIEMSIIER);
		value |= BIT(d->hwirq);
		rcar_pci_write_reg(pcie, value, PCIEMSIIER);
	spin_unlock_irqrestore(&msi->mask_lock, flags);
	}
}

static void rcar_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
@@ -745,7 +735,7 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host)
	int err;

	mutex_init(&msi->map_lock);
	spin_lock_init(&msi->mask_lock);
	raw_spin_lock_init(&msi->mask_lock);

	err = of_address_to_resource(dev->of_node, 0, &res);
	if (err)