mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
PCI: rockchip: dw: Add affinity for legacy INTX
We try to avoid to create and look up parent domain hierarchy, which is a normal way we need because it's indeed is a hierarchy. Instead we set affinity via parent irq by using irq_set_affinity API. Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com> Change-Id: I04252b956b7c29fb5c156f1c8ff59adf82d5c638
This commit is contained in:
@@ -173,6 +173,7 @@ struct rk_pcie {
|
|||||||
bool bifurcation;
|
bool bifurcation;
|
||||||
struct regulator *vpcie3v3;
|
struct regulator *vpcie3v3;
|
||||||
struct irq_domain *irq_domain;
|
struct irq_domain *irq_domain;
|
||||||
|
int legacy_parent_irq;
|
||||||
raw_spinlock_t intx_lock;
|
raw_spinlock_t intx_lock;
|
||||||
u16 aspm;
|
u16 aspm;
|
||||||
};
|
};
|
||||||
@@ -1565,12 +1566,38 @@ static void rk_pcie_legacy_irq_unmask(struct irq_data *d)
|
|||||||
raw_spin_unlock_irqrestore(&rk_pcie->intx_lock, flags);
|
raw_spin_unlock_irqrestore(&rk_pcie->intx_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
static int rk_pcie_irq_set_affinity(struct irq_data *d,
|
||||||
|
const struct cpumask *mask_val,
|
||||||
|
bool force)
|
||||||
|
{
|
||||||
|
unsigned int cpu;
|
||||||
|
struct rk_pcie *priv = irq_data_get_irq_chip_data(d);
|
||||||
|
|
||||||
|
if (!force)
|
||||||
|
cpu = cpumask_any_and(mask_val, cpu_online_mask);
|
||||||
|
else
|
||||||
|
cpu = cpumask_first(mask_val);
|
||||||
|
|
||||||
|
if (cpu >= nr_cpu_ids)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
irq_set_affinity(priv->legacy_parent_irq, cpumask_of(cpu));
|
||||||
|
irq_data_update_effective_affinity(d, cpumask_of(cpu));
|
||||||
|
|
||||||
|
return IRQ_SET_MASK_OK_DONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct irq_chip rk_pcie_legacy_irq_chip = {
|
static struct irq_chip rk_pcie_legacy_irq_chip = {
|
||||||
.name = "rk-pcie-legacy-int",
|
.name = "rk-pcie-legacy-int",
|
||||||
.irq_enable = rk_pcie_legacy_irq_unmask,
|
.irq_enable = rk_pcie_legacy_irq_unmask,
|
||||||
.irq_disable = rk_pcie_legacy_irq_mask,
|
.irq_disable = rk_pcie_legacy_irq_mask,
|
||||||
.irq_mask = rk_pcie_legacy_irq_mask,
|
.irq_mask = rk_pcie_legacy_irq_mask,
|
||||||
.irq_unmask = rk_pcie_legacy_irq_unmask,
|
.irq_unmask = rk_pcie_legacy_irq_unmask,
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
.irq_set_affinity = rk_pcie_irq_set_affinity,
|
||||||
|
#endif
|
||||||
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
|
.flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1796,6 +1823,7 @@ retry_regulator:
|
|||||||
if (!ret) {
|
if (!ret) {
|
||||||
irq = platform_get_irq_byname(pdev, "legacy");
|
irq = platform_get_irq_byname(pdev, "legacy");
|
||||||
if (irq >= 0) {
|
if (irq >= 0) {
|
||||||
|
rk_pcie->legacy_parent_irq = irq;
|
||||||
irq_set_chained_handler_and_data(irq, rk_pcie_legacy_int_handler,
|
irq_set_chained_handler_and_data(irq, rk_pcie_legacy_int_handler,
|
||||||
rk_pcie);
|
rk_pcie);
|
||||||
/* Unmask all legacy interrupt from INTA~INTD */
|
/* Unmask all legacy interrupt from INTA~INTD */
|
||||||
|
|||||||
Reference in New Issue
Block a user