diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /arch/arm/plat-s5p/irq-eint.c | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2 |
samsung update 1
Diffstat (limited to 'arch/arm/plat-s5p/irq-eint.c')
-rw-r--r-- | arch/arm/plat-s5p/irq-eint.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index b5bb774..2f08070 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -65,6 +65,7 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) int shift; u32 ctrl, mask; u32 newvalue = 0; + struct irq_desc *desc = irq_to_desc(data->irq); switch (type) { case IRQ_TYPE_EDGE_RISING: @@ -115,6 +116,11 @@ static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type) else printk(KERN_ERR "No such irq number %d", offs); + if (type & IRQ_TYPE_EDGE_BOTH) + desc->handle_irq = handle_edge_irq; + else + desc->handle_irq = handle_level_irq; + return 0; } @@ -123,6 +129,7 @@ static struct irq_chip s5p_irq_eint = { .irq_mask = s5p_irq_eint_mask, .irq_unmask = s5p_irq_eint_unmask, .irq_mask_ack = s5p_irq_eint_maskack, + .irq_disable = s5p_irq_eint_maskack, .irq_ack = s5p_irq_eint_ack, .irq_set_type = s5p_irq_eint_set_type, #ifdef CONFIG_PM @@ -138,11 +145,12 @@ static struct irq_chip s5p_irq_eint = { * * Each EINT pend/mask registers handle eight of them. */ -static inline void s5p_irq_demux_eint(unsigned int start) +static inline u32 s5p_irq_demux_eint(unsigned int start) { u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); unsigned int irq; + u32 action = 0; status &= ~mask; status &= 0xff; @@ -151,13 +159,21 @@ static inline void s5p_irq_demux_eint(unsigned int start) irq = fls(status) - 1; generic_handle_irq(irq + start); status &= ~(1 << irq); + ++action; } + + return action; } static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) { - s5p_irq_demux_eint(IRQ_EINT(16)); - s5p_irq_demux_eint(IRQ_EINT(24)); + u32 a16_23, a24_31; + + a16_23 = s5p_irq_demux_eint(IRQ_EINT(16)); + a24_31 = s5p_irq_demux_eint(IRQ_EINT(24)); + + if (!a16_23 && !a24_31) + do_bad_IRQ(irq, desc); } static inline void s5p_irq_vic_eint_mask(struct irq_data *data) |