Merge branch irq/parent_device into irq/irqchip-next
* irq/parent_device: : . : Move irq_chip::parent_device to irq_domain::dev to track the : PM state of the device implementing the irqchip. : . genirq: Kill irq_chip::parent_device pinctrl: starfive: Move PM device over to irq domain pinctrl: npcm: Fix broken references to chip->parent_device gpio: tpmx86: Move PM device over to irq domain gpio: rcar: Move PM device over to irq domain gpio: omap: Move PM device over to irq domain gpio: mt7621: Kill parent_device usage irqchip/imx-intmux: Move PM device over to irq domain irqchip/renesas-irqc: Move PM device over to irq domain irqchip/renesas-intc-irqpin: Move PM device over to irq domain irqchip/gic: Move PM device over to irq domain genirq: Allow the PM device to originate from irq domain Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
commit
add679d2cb
|
|
@ -239,7 +239,6 @@ mediatek_gpio_bank_probe(struct device *dev, int bank)
|
|||
|
||||
rg->chip.offset = bank * MTK_BANK_WIDTH;
|
||||
rg->irq_chip.name = dev_name(dev);
|
||||
rg->irq_chip.parent_device = dev;
|
||||
rg->irq_chip.irq_unmask = mediatek_gpio_irq_unmask;
|
||||
rg->irq_chip.irq_mask = mediatek_gpio_irq_mask;
|
||||
rg->irq_chip.irq_mask_ack = mediatek_gpio_irq_mask;
|
||||
|
|
|
|||
|
|
@ -986,7 +986,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
|
|||
writel_relaxed(0, base + bank->regs->ctrl);
|
||||
}
|
||||
|
||||
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc,
|
||||
struct device *pm_dev)
|
||||
{
|
||||
struct gpio_irq_chip *irq;
|
||||
static int gpio;
|
||||
|
|
@ -1052,6 +1053,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
|||
if (ret)
|
||||
return dev_err_probe(bank->chip.parent, ret, "Could not register gpio chip\n");
|
||||
|
||||
irq_domain_set_pm_device(bank->chip.irq.domain, pm_dev);
|
||||
ret = devm_request_irq(bank->chip.parent, bank->irq,
|
||||
omap_gpio_irq_handler,
|
||||
0, dev_name(bank->chip.parent), bank);
|
||||
|
|
@ -1402,7 +1404,6 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|||
irqc->irq_bus_sync_unlock = gpio_irq_bus_sync_unlock,
|
||||
irqc->name = dev_name(&pdev->dev);
|
||||
irqc->flags = IRQCHIP_MASK_ON_SUSPEND;
|
||||
irqc->parent_device = dev;
|
||||
|
||||
bank->irq = platform_get_irq(pdev, 0);
|
||||
if (bank->irq <= 0) {
|
||||
|
|
@ -1466,7 +1467,7 @@ static int omap_gpio_probe(struct platform_device *pdev)
|
|||
|
||||
omap_gpio_mod_init(bank);
|
||||
|
||||
ret = omap_gpio_chip_init(bank, irqc);
|
||||
ret = omap_gpio_chip_init(bank, irqc, dev);
|
||||
if (ret) {
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
|
|
|
|||
|
|
@ -530,7 +530,6 @@ static int gpio_rcar_probe(struct platform_device *pdev)
|
|||
|
||||
irq_chip = &p->irq_chip;
|
||||
irq_chip->name = "gpio-rcar";
|
||||
irq_chip->parent_device = dev;
|
||||
irq_chip->irq_mask = gpio_rcar_irq_disable;
|
||||
irq_chip->irq_unmask = gpio_rcar_irq_enable;
|
||||
irq_chip->irq_set_type = gpio_rcar_irq_set_type;
|
||||
|
|
@ -552,6 +551,7 @@ static int gpio_rcar_probe(struct platform_device *pdev)
|
|||
goto err0;
|
||||
}
|
||||
|
||||
irq_domain_set_pm_device(gpio_chip->irq.domain, dev);
|
||||
ret = devm_request_irq(dev, p->irq_parent, gpio_rcar_irq_handler,
|
||||
IRQF_SHARED, name, p);
|
||||
if (ret) {
|
||||
|
|
|
|||
|
|
@ -281,7 +281,6 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
|
|||
u8 irq_status;
|
||||
|
||||
irq_chip->name = chip->label;
|
||||
irq_chip->parent_device = &pdev->dev;
|
||||
irq_chip->irq_mask = tqmx86_gpio_irq_mask;
|
||||
irq_chip->irq_unmask = tqmx86_gpio_irq_unmask;
|
||||
irq_chip->irq_set_type = tqmx86_gpio_irq_set_type;
|
||||
|
|
@ -316,6 +315,8 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
|
|||
goto out_pm_dis;
|
||||
}
|
||||
|
||||
irq_domain_set_pm_device(girq->domain, dev);
|
||||
|
||||
dev_info(dev, "GPIO functionality initialized with %d pins\n",
|
||||
chip->ngpio);
|
||||
|
||||
|
|
|
|||
|
|
@ -1127,13 +1127,12 @@ static const struct irq_domain_ops gic_irq_domain_ops = {
|
|||
.unmap = gic_irq_domain_unmap,
|
||||
};
|
||||
|
||||
static void gic_init_chip(struct gic_chip_data *gic, struct device *dev,
|
||||
const char *name, bool use_eoimode1)
|
||||
static void gic_init_chip(struct gic_chip_data *gic, const char *name,
|
||||
bool use_eoimode1)
|
||||
{
|
||||
/* Initialize irq_chip */
|
||||
gic->chip = gic_chip;
|
||||
gic->chip.name = name;
|
||||
gic->chip.parent_device = dev;
|
||||
|
||||
if (use_eoimode1) {
|
||||
gic->chip.irq_mask = gic_eoimode1_mask_irq;
|
||||
|
|
@ -1268,10 +1267,10 @@ static int __init __gic_init_bases(struct gic_chip_data *gic,
|
|||
|
||||
if (static_branch_likely(&supports_deactivate_key) && gic == &gic_data[0]) {
|
||||
name = kasprintf(GFP_KERNEL, "GICv2");
|
||||
gic_init_chip(gic, NULL, name, true);
|
||||
gic_init_chip(gic, name, true);
|
||||
} else {
|
||||
name = kasprintf(GFP_KERNEL, "GIC-%d", (int)(gic-&gic_data[0]));
|
||||
gic_init_chip(gic, NULL, name, false);
|
||||
gic_init_chip(gic, name, false);
|
||||
}
|
||||
|
||||
ret = gic_init_bases(gic, handle);
|
||||
|
|
@ -1460,7 +1459,7 @@ int gic_of_init_child(struct device *dev, struct gic_chip_data **gic, int irq)
|
|||
if (!*gic)
|
||||
return -ENOMEM;
|
||||
|
||||
gic_init_chip(*gic, dev, dev->of_node->name, false);
|
||||
gic_init_chip(*gic, dev->of_node->name, false);
|
||||
|
||||
ret = gic_of_setup(*gic, dev->of_node);
|
||||
if (ret)
|
||||
|
|
@ -1472,6 +1471,7 @@ int gic_of_init_child(struct device *dev, struct gic_chip_data **gic, int irq)
|
|||
return ret;
|
||||
}
|
||||
|
||||
irq_domain_set_pm_device((*gic)->domain, dev);
|
||||
irq_set_chained_handler_and_data(irq, gic_handle_cascade_irq, *gic);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@
|
|||
#define CHAN_MAX_NUM 0x8
|
||||
|
||||
struct intmux_irqchip_data {
|
||||
struct irq_chip chip;
|
||||
u32 saved_reg;
|
||||
int chanidx;
|
||||
int irq;
|
||||
|
|
@ -114,7 +113,7 @@ static void imx_intmux_irq_unmask(struct irq_data *d)
|
|||
raw_spin_unlock_irqrestore(&data->lock, flags);
|
||||
}
|
||||
|
||||
static struct irq_chip imx_intmux_irq_chip = {
|
||||
static struct irq_chip imx_intmux_irq_chip __ro_after_init = {
|
||||
.name = "intmux",
|
||||
.irq_mask = imx_intmux_irq_mask,
|
||||
.irq_unmask = imx_intmux_irq_unmask,
|
||||
|
|
@ -126,7 +125,7 @@ static int imx_intmux_irq_map(struct irq_domain *h, unsigned int irq,
|
|||
struct intmux_irqchip_data *data = h->host_data;
|
||||
|
||||
irq_set_chip_data(irq, data);
|
||||
irq_set_chip_and_handler(irq, &data->chip, handle_level_irq);
|
||||
irq_set_chip_and_handler(irq, &imx_intmux_irq_chip, handle_level_irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -241,8 +240,6 @@ static int imx_intmux_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
for (i = 0; i < channum; i++) {
|
||||
data->irqchip_data[i].chip = imx_intmux_irq_chip;
|
||||
data->irqchip_data[i].chip.parent_device = &pdev->dev;
|
||||
data->irqchip_data[i].chanidx = i;
|
||||
|
||||
data->irqchip_data[i].irq = irq_of_parse_and_map(np, i);
|
||||
|
|
@ -260,6 +257,7 @@ static int imx_intmux_probe(struct platform_device *pdev)
|
|||
goto out;
|
||||
}
|
||||
data->irqchip_data[i].domain = domain;
|
||||
irq_domain_set_pm_device(domain, &pdev->dev);
|
||||
|
||||
/* disable all interrupt sources of this channel firstly */
|
||||
writel_relaxed(0, data->regs + CHANIER(i));
|
||||
|
|
|
|||
|
|
@ -508,7 +508,6 @@ static int intc_irqpin_probe(struct platform_device *pdev)
|
|||
|
||||
irq_chip = &p->irq_chip;
|
||||
irq_chip->name = "intc-irqpin";
|
||||
irq_chip->parent_device = dev;
|
||||
irq_chip->irq_mask = disable_fn;
|
||||
irq_chip->irq_unmask = enable_fn;
|
||||
irq_chip->irq_set_type = intc_irqpin_irq_set_type;
|
||||
|
|
@ -523,6 +522,8 @@ static int intc_irqpin_probe(struct platform_device *pdev)
|
|||
goto err0;
|
||||
}
|
||||
|
||||
irq_domain_set_pm_device(p->irq_domain, dev);
|
||||
|
||||
if (p->shared_irqs) {
|
||||
/* request one shared interrupt */
|
||||
if (devm_request_irq(dev, p->irq[0].requested_irq,
|
||||
|
|
|
|||
|
|
@ -188,13 +188,14 @@ static int irqc_probe(struct platform_device *pdev)
|
|||
p->gc->reg_base = p->cpu_int_base;
|
||||
p->gc->chip_types[0].regs.enable = IRQC_EN_SET;
|
||||
p->gc->chip_types[0].regs.disable = IRQC_EN_STS;
|
||||
p->gc->chip_types[0].chip.parent_device = dev;
|
||||
p->gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg;
|
||||
p->gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg;
|
||||
p->gc->chip_types[0].chip.irq_set_type = irqc_irq_set_type;
|
||||
p->gc->chip_types[0].chip.irq_set_wake = irqc_irq_set_wake;
|
||||
p->gc->chip_types[0].chip.flags = IRQCHIP_MASK_ON_SUSPEND;
|
||||
|
||||
irq_domain_set_pm_device(p->irq_domain, dev);
|
||||
|
||||
/* request interrupts one by one */
|
||||
for (k = 0; k < p->number_of_irqs; k++) {
|
||||
if (devm_request_irq(dev, p->irq[k].requested_irq,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ struct npcm7xx_gpio {
|
|||
struct gpio_chip gc;
|
||||
int irqbase;
|
||||
int irq;
|
||||
void *priv;
|
||||
struct irq_chip irq_chip;
|
||||
u32 pinctrl_id;
|
||||
int (*direction_input)(struct gpio_chip *chip, unsigned offset);
|
||||
|
|
@ -226,7 +225,7 @@ static void npcmgpio_irq_handler(struct irq_desc *desc)
|
|||
chained_irq_enter(chip, desc);
|
||||
sts = ioread32(bank->base + NPCM7XX_GP_N_EVST);
|
||||
en = ioread32(bank->base + NPCM7XX_GP_N_EVEN);
|
||||
dev_dbg(chip->parent_device, "==> got irq sts %.8x %.8x\n", sts,
|
||||
dev_dbg(bank->gc.parent, "==> got irq sts %.8x %.8x\n", sts,
|
||||
en);
|
||||
|
||||
sts &= en;
|
||||
|
|
@ -241,33 +240,33 @@ static int npcmgpio_set_irq_type(struct irq_data *d, unsigned int type)
|
|||
gpiochip_get_data(irq_data_get_irq_chip_data(d));
|
||||
unsigned int gpio = BIT(d->hwirq);
|
||||
|
||||
dev_dbg(d->chip->parent_device, "setirqtype: %u.%u = %u\n", gpio,
|
||||
dev_dbg(bank->gc.parent, "setirqtype: %u.%u = %u\n", gpio,
|
||||
d->irq, type);
|
||||
switch (type) {
|
||||
case IRQ_TYPE_EDGE_RISING:
|
||||
dev_dbg(d->chip->parent_device, "edge.rising\n");
|
||||
dev_dbg(bank->gc.parent, "edge.rising\n");
|
||||
npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio);
|
||||
npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_FALLING:
|
||||
dev_dbg(d->chip->parent_device, "edge.falling\n");
|
||||
dev_dbg(bank->gc.parent, "edge.falling\n");
|
||||
npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio);
|
||||
npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
|
||||
break;
|
||||
case IRQ_TYPE_EDGE_BOTH:
|
||||
dev_dbg(d->chip->parent_device, "edge.both\n");
|
||||
dev_dbg(bank->gc.parent, "edge.both\n");
|
||||
npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_EVBE, gpio);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_LOW:
|
||||
dev_dbg(d->chip->parent_device, "level.low\n");
|
||||
dev_dbg(bank->gc.parent, "level.low\n");
|
||||
npcm_gpio_set(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
|
||||
break;
|
||||
case IRQ_TYPE_LEVEL_HIGH:
|
||||
dev_dbg(d->chip->parent_device, "level.high\n");
|
||||
dev_dbg(bank->gc.parent, "level.high\n");
|
||||
npcm_gpio_clr(&bank->gc, bank->base + NPCM7XX_GP_N_POL, gpio);
|
||||
break;
|
||||
default:
|
||||
dev_dbg(d->chip->parent_device, "invalid irq type\n");
|
||||
dev_dbg(bank->gc.parent, "invalid irq type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +288,7 @@ static void npcmgpio_irq_ack(struct irq_data *d)
|
|||
gpiochip_get_data(irq_data_get_irq_chip_data(d));
|
||||
unsigned int gpio = d->hwirq;
|
||||
|
||||
dev_dbg(d->chip->parent_device, "irq_ack: %u.%u\n", gpio, d->irq);
|
||||
dev_dbg(bank->gc.parent, "irq_ack: %u.%u\n", gpio, d->irq);
|
||||
iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVST);
|
||||
}
|
||||
|
||||
|
|
@ -301,7 +300,7 @@ static void npcmgpio_irq_mask(struct irq_data *d)
|
|||
unsigned int gpio = d->hwirq;
|
||||
|
||||
/* Clear events */
|
||||
dev_dbg(d->chip->parent_device, "irq_mask: %u.%u\n", gpio, d->irq);
|
||||
dev_dbg(bank->gc.parent, "irq_mask: %u.%u\n", gpio, d->irq);
|
||||
iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVENC);
|
||||
}
|
||||
|
||||
|
|
@ -313,7 +312,7 @@ static void npcmgpio_irq_unmask(struct irq_data *d)
|
|||
unsigned int gpio = d->hwirq;
|
||||
|
||||
/* Enable events */
|
||||
dev_dbg(d->chip->parent_device, "irq_unmask: %u.%u\n", gpio, d->irq);
|
||||
dev_dbg(bank->gc.parent, "irq_unmask: %u.%u\n", gpio, d->irq);
|
||||
iowrite32(BIT(gpio), bank->base + NPCM7XX_GP_N_EVENS);
|
||||
}
|
||||
|
||||
|
|
@ -323,7 +322,7 @@ static unsigned int npcmgpio_irq_startup(struct irq_data *d)
|
|||
unsigned int gpio = d->hwirq;
|
||||
|
||||
/* active-high, input, clear interrupt, enable interrupt */
|
||||
dev_dbg(d->chip->parent_device, "startup: %u.%u\n", gpio, d->irq);
|
||||
dev_dbg(gc->parent, "startup: %u.%u\n", gpio, d->irq);
|
||||
npcmgpio_direction_input(gc, gpio);
|
||||
npcmgpio_irq_ack(d);
|
||||
npcmgpio_irq_unmask(d);
|
||||
|
|
|
|||
|
|
@ -1307,7 +1307,6 @@ static int starfive_probe(struct platform_device *pdev)
|
|||
sfp->gc.base = -1;
|
||||
sfp->gc.ngpio = NR_GPIOS;
|
||||
|
||||
starfive_irq_chip.parent_device = dev;
|
||||
starfive_irq_chip.name = sfp->gc.label;
|
||||
|
||||
sfp->gc.irq.chip = &starfive_irq_chip;
|
||||
|
|
@ -1330,6 +1329,8 @@ static int starfive_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return dev_err_probe(dev, ret, "could not register gpiochip\n");
|
||||
|
||||
irq_domain_set_pm_device(sfp->gc.irq.domain, dev);
|
||||
|
||||
out_pinctrl_enable:
|
||||
return pinctrl_enable(sfp->pctl);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -456,7 +456,6 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
|
|||
/**
|
||||
* struct irq_chip - hardware interrupt chip descriptor
|
||||
*
|
||||
* @parent_device: pointer to parent device for irqchip
|
||||
* @name: name for /proc/interrupts
|
||||
* @irq_startup: start up the interrupt (defaults to ->enable if NULL)
|
||||
* @irq_shutdown: shut down the interrupt (defaults to ->disable if NULL)
|
||||
|
|
@ -503,7 +502,6 @@ static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
|
|||
* @flags: chip specific flags
|
||||
*/
|
||||
struct irq_chip {
|
||||
struct device *parent_device;
|
||||
const char *name;
|
||||
unsigned int (*irq_startup)(struct irq_data *data);
|
||||
void (*irq_shutdown)(struct irq_data *data);
|
||||
|
|
|
|||
|
|
@ -151,6 +151,8 @@ struct irq_domain_chip_generic;
|
|||
* @gc: Pointer to a list of generic chips. There is a helper function for
|
||||
* setting up one or more generic chips for interrupt controllers
|
||||
* drivers using the generic chip library which uses this pointer.
|
||||
* @dev: Pointer to a device that the domain represent, and that will be
|
||||
* used for power management purposes.
|
||||
* @parent: Pointer to parent irq_domain to support hierarchy irq_domains
|
||||
*
|
||||
* Revmap data, used internally by irq_domain
|
||||
|
|
@ -171,6 +173,7 @@ struct irq_domain {
|
|||
struct fwnode_handle *fwnode;
|
||||
enum irq_domain_bus_token bus_token;
|
||||
struct irq_domain_chip_generic *gc;
|
||||
struct device *dev;
|
||||
#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
|
||||
struct irq_domain *parent;
|
||||
#endif
|
||||
|
|
@ -226,6 +229,13 @@ static inline struct device_node *irq_domain_get_of_node(struct irq_domain *d)
|
|||
return to_of_node(d->fwnode);
|
||||
}
|
||||
|
||||
static inline void irq_domain_set_pm_device(struct irq_domain *d,
|
||||
struct device *dev)
|
||||
{
|
||||
if (d)
|
||||
d->dev = dev;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IRQ_DOMAIN
|
||||
struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id,
|
||||
const char *name, phys_addr_t *pa);
|
||||
|
|
|
|||
|
|
@ -1558,6 +1558,14 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct device *irq_get_parent_device(struct irq_data *data)
|
||||
{
|
||||
if (data->domain)
|
||||
return data->domain->dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* irq_chip_pm_get - Enable power for an IRQ chip
|
||||
* @data: Pointer to interrupt specific data
|
||||
|
|
@ -1567,12 +1575,13 @@ int irq_chip_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
|
|||
*/
|
||||
int irq_chip_pm_get(struct irq_data *data)
|
||||
{
|
||||
struct device *dev = irq_get_parent_device(data);
|
||||
int retval;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device) {
|
||||
retval = pm_runtime_get_sync(data->chip->parent_device);
|
||||
if (IS_ENABLED(CONFIG_PM) && dev) {
|
||||
retval = pm_runtime_get_sync(dev);
|
||||
if (retval < 0) {
|
||||
pm_runtime_put_noidle(data->chip->parent_device);
|
||||
pm_runtime_put_noidle(dev);
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
|
@ -1590,10 +1599,11 @@ int irq_chip_pm_get(struct irq_data *data)
|
|||
*/
|
||||
int irq_chip_pm_put(struct irq_data *data)
|
||||
{
|
||||
struct device *dev = irq_get_parent_device(data);
|
||||
int retval = 0;
|
||||
|
||||
if (IS_ENABLED(CONFIG_PM) && data->chip->parent_device)
|
||||
retval = pm_runtime_put(data->chip->parent_device);
|
||||
if (IS_ENABLED(CONFIG_PM) && dev)
|
||||
retval = pm_runtime_put(dev);
|
||||
|
||||
return (retval < 0) ? retval : 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue