Commit 6e3b473e authored by Marc Zyngier's avatar Marc Zyngier

Merge branch irq/qcom-pdc-nowake-cleanup into irq/irqchip-next

* irq/qcom-pdc-nowake-cleanup:
  : Fix the QCOM PDC mishandling of the interrupt hierarchy by trimming
  : it when necessary.
  : Export irq_domain_disconnect_hierarchy as a consequence of it.
  irqchip/qcom-pdc: Trim unused levels of the interrupt hierarchy
  irqdomain: Export irq_domain_disconnect_hierarchy()
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
parents acdcfd94 9d4f24bf
...@@ -53,26 +53,6 @@ static u32 pdc_reg_read(int reg, u32 i) ...@@ -53,26 +53,6 @@ static u32 pdc_reg_read(int reg, u32 i)
return readl_relaxed(pdc_base + reg + i * sizeof(u32)); return readl_relaxed(pdc_base + reg + i * sizeof(u32));
} }
static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d,
enum irqchip_irq_state which,
bool *state)
{
if (d->hwirq == GPIO_NO_WAKE_IRQ)
return 0;
return irq_chip_get_parent_state(d, which, state);
}
static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d,
enum irqchip_irq_state which,
bool value)
{
if (d->hwirq == GPIO_NO_WAKE_IRQ)
return 0;
return irq_chip_set_parent_state(d, which, value);
}
static void pdc_enable_intr(struct irq_data *d, bool on) static void pdc_enable_intr(struct irq_data *d, bool on)
{ {
int pin_out = d->hwirq; int pin_out = d->hwirq;
...@@ -91,38 +71,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on) ...@@ -91,38 +71,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on)
static void qcom_pdc_gic_disable(struct irq_data *d) static void qcom_pdc_gic_disable(struct irq_data *d)
{ {
if (d->hwirq == GPIO_NO_WAKE_IRQ)
return;
pdc_enable_intr(d, false); pdc_enable_intr(d, false);
irq_chip_disable_parent(d); irq_chip_disable_parent(d);
} }
static void qcom_pdc_gic_enable(struct irq_data *d) static void qcom_pdc_gic_enable(struct irq_data *d)
{ {
if (d->hwirq == GPIO_NO_WAKE_IRQ)
return;
pdc_enable_intr(d, true); pdc_enable_intr(d, true);
irq_chip_enable_parent(d); irq_chip_enable_parent(d);
} }
static void qcom_pdc_gic_mask(struct irq_data *d)
{
if (d->hwirq == GPIO_NO_WAKE_IRQ)
return;
irq_chip_mask_parent(d);
}
static void qcom_pdc_gic_unmask(struct irq_data *d)
{
if (d->hwirq == GPIO_NO_WAKE_IRQ)
return;
irq_chip_unmask_parent(d);
}
/* /*
* GIC does not handle falling edge or active low. To allow falling edge and * GIC does not handle falling edge or active low. To allow falling edge and
* active low interrupts to be handled at GIC, PDC has an inverter that inverts * active low interrupts to be handled at GIC, PDC has an inverter that inverts
...@@ -159,14 +117,10 @@ enum pdc_irq_config_bits { ...@@ -159,14 +117,10 @@ enum pdc_irq_config_bits {
*/ */
static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
{ {
int pin_out = d->hwirq;
enum pdc_irq_config_bits pdc_type; enum pdc_irq_config_bits pdc_type;
enum pdc_irq_config_bits old_pdc_type; enum pdc_irq_config_bits old_pdc_type;
int ret; int ret;
if (pin_out == GPIO_NO_WAKE_IRQ)
return 0;
switch (type) { switch (type) {
case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_RISING:
pdc_type = PDC_EDGE_RISING; pdc_type = PDC_EDGE_RISING;
...@@ -191,8 +145,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) ...@@ -191,8 +145,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
return -EINVAL; return -EINVAL;
} }
old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out); old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq);
pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type); pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type);
ret = irq_chip_set_type_parent(d, type); ret = irq_chip_set_type_parent(d, type);
if (ret) if (ret)
...@@ -216,12 +170,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) ...@@ -216,12 +170,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type)
static struct irq_chip qcom_pdc_gic_chip = { static struct irq_chip qcom_pdc_gic_chip = {
.name = "PDC", .name = "PDC",
.irq_eoi = irq_chip_eoi_parent, .irq_eoi = irq_chip_eoi_parent,
.irq_mask = qcom_pdc_gic_mask, .irq_mask = irq_chip_mask_parent,
.irq_unmask = qcom_pdc_gic_unmask, .irq_unmask = irq_chip_unmask_parent,
.irq_disable = qcom_pdc_gic_disable, .irq_disable = qcom_pdc_gic_disable,
.irq_enable = qcom_pdc_gic_enable, .irq_enable = qcom_pdc_gic_enable,
.irq_get_irqchip_state = qcom_pdc_gic_get_irqchip_state, .irq_get_irqchip_state = irq_chip_get_parent_state,
.irq_set_irqchip_state = qcom_pdc_gic_set_irqchip_state, .irq_set_irqchip_state = irq_chip_set_parent_state,
.irq_retrigger = irq_chip_retrigger_hierarchy, .irq_retrigger = irq_chip_retrigger_hierarchy,
.irq_set_type = qcom_pdc_gic_set_type, .irq_set_type = qcom_pdc_gic_set_type,
.flags = IRQCHIP_MASK_ON_SUSPEND | .flags = IRQCHIP_MASK_ON_SUSPEND |
...@@ -282,7 +236,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -282,7 +236,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq,
parent_hwirq = get_parent_hwirq(hwirq); parent_hwirq = get_parent_hwirq(hwirq);
if (parent_hwirq == PDC_NO_PARENT_IRQ) if (parent_hwirq == PDC_NO_PARENT_IRQ)
return 0; return irq_domain_disconnect_hierarchy(domain->parent, virq);
if (type & IRQ_TYPE_EDGE_BOTH) if (type & IRQ_TYPE_EDGE_BOTH)
type = IRQ_TYPE_EDGE_RISING; type = IRQ_TYPE_EDGE_RISING;
...@@ -319,17 +273,17 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq, ...@@ -319,17 +273,17 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq,
if (ret) if (ret)
return ret; return ret;
if (hwirq == GPIO_NO_WAKE_IRQ)
return irq_domain_disconnect_hierarchy(domain, virq);
ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq,
&qcom_pdc_gic_chip, NULL); &qcom_pdc_gic_chip, NULL);
if (ret) if (ret)
return ret; return ret;
if (hwirq == GPIO_NO_WAKE_IRQ)
return 0;
parent_hwirq = get_parent_hwirq(hwirq); parent_hwirq = get_parent_hwirq(hwirq);
if (parent_hwirq == PDC_NO_PARENT_IRQ) if (parent_hwirq == PDC_NO_PARENT_IRQ)
return 0; return irq_domain_disconnect_hierarchy(domain->parent, virq);
if (type & IRQ_TYPE_EDGE_BOTH) if (type & IRQ_TYPE_EDGE_BOTH)
type = IRQ_TYPE_EDGE_RISING; type = IRQ_TYPE_EDGE_RISING;
......
...@@ -1215,6 +1215,7 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain, ...@@ -1215,6 +1215,7 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain,
irqd->chip = ERR_PTR(-ENOTCONN); irqd->chip = ERR_PTR(-ENOTCONN);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(irq_domain_disconnect_hierarchy);
static int irq_domain_trim_hierarchy(unsigned int virq) static int irq_domain_trim_hierarchy(unsigned int virq)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment