浏览代码

irqchip: dw-apb-ictl: Add PM support

This patch adds in support for S2R for dw-apb-ictl irqchip driver.

We can used relaxed variants in the resume hook because there's no DMA
at all here, the device type memory attribute can ensure the operations
order and relaxed version imply compiler barrier.

Signed-off-by: Jisheng Zhang <jszhang@marvell.com>
Link: https://lkml.kernel.org/r/1415773374-4629-4-git-send-email-jszhang@marvell.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Jisheng Zhang 11 年之前
父节点
当前提交
1655b0530d
共有 1 个文件被更改,包括 19 次插入0 次删除
  1. 19 0
      drivers/irqchip/irq-dw-apb-ictl.c

+ 19 - 0
drivers/irqchip/irq-dw-apb-ictl.c

@@ -50,6 +50,21 @@ static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 	chained_irq_exit(chip, desc);
 }
 }
 
 
+#ifdef CONFIG_PM
+static void dw_apb_ictl_resume(struct irq_data *d)
+{
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct irq_chip_type *ct = irq_data_get_chip_type(d);
+
+	irq_gc_lock(gc);
+	writel_relaxed(~0, gc->reg_base + ct->regs.enable);
+	writel_relaxed(*ct->mask_cache, gc->reg_base + ct->regs.mask);
+	irq_gc_unlock(gc);
+}
+#else
+#define dw_apb_ictl_resume	NULL
+#endif /* CONFIG_PM */
+
 static int __init dw_apb_ictl_init(struct device_node *np,
 static int __init dw_apb_ictl_init(struct device_node *np,
 				   struct device_node *parent)
 				   struct device_node *parent)
 {
 {
@@ -127,13 +142,17 @@ static int __init dw_apb_ictl_init(struct device_node *np,
 	gc->reg_base = iobase;
 	gc->reg_base = iobase;
 
 
 	gc->chip_types[0].regs.mask = APB_INT_MASK_L;
 	gc->chip_types[0].regs.mask = APB_INT_MASK_L;
+	gc->chip_types[0].regs.enable = APB_INT_ENABLE_L;
 	gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
 	gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
 	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
 	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_resume = dw_apb_ictl_resume;
 
 
 	if (nrirqs > 32) {
 	if (nrirqs > 32) {
 		gc->chip_types[1].regs.mask = APB_INT_MASK_H;
 		gc->chip_types[1].regs.mask = APB_INT_MASK_H;
+		gc->chip_types[1].regs.enable = APB_INT_ENABLE_H;
 		gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit;
 		gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit;
 		gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit;
 		gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit;
+		gc->chip_types[1].chip.irq_resume = dw_apb_ictl_resume;
 	}
 	}
 
 
 	irq_set_handler_data(irq, gc);
 	irq_set_handler_data(irq, gc);