1 /* arch/arm/plat-samsung/irq-uart.c
2 * originally part of arch/arm/plat-s3c64xx/irq.c
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
9 * Samsung- UART Interrupt handling
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
16 #include <linux/kernel.h>
17 #include <linux/interrupt.h>
18 #include <linux/serial_core.h>
19 #include <linux/irq.h>
23 #include <plat/irq-uart.h>
24 #include <plat/regs-serial.h>
27 /* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
28 * are consecutive when looking up the interrupt in the demux routines.
30 static void s3c_irq_demux_uart(unsigned int irq
, struct irq_desc
*desc
)
32 struct s3c_uart_irq
*uirq
= desc
->irq_data
.handler_data
;
33 u32 pend
= __raw_readl(uirq
->regs
+ S3C64XX_UINTP
);
34 int base
= uirq
->base_irq
;
37 generic_handle_irq(base
);
39 generic_handle_irq(base
+ 1);
41 generic_handle_irq(base
+ 2);
43 generic_handle_irq(base
+ 3);
46 static void __init
s3c_init_uart_irq(struct s3c_uart_irq
*uirq
)
48 void __iomem
*reg_base
= uirq
->regs
;
49 struct irq_chip_generic
*gc
;
50 struct irq_chip_type
*ct
;
52 /* mask all interrupts at the start. */
53 __raw_writel(0xf, reg_base
+ S3C64XX_UINTM
);
55 gc
= irq_alloc_generic_chip("s3c-uart", 1, uirq
->base_irq
, reg_base
,
58 ct
->chip
.irq_ack
= irq_gc_ack
;
59 ct
->chip
.irq_mask
= irq_gc_mask_set_bit
;
60 ct
->chip
.irq_unmask
= irq_gc_mask_clr_bit
;
61 ct
->regs
.ack
= S3C64XX_UINTP
;
62 ct
->regs
.mask
= S3C64XX_UINTM
;
63 irq_setup_generic_chip(gc
, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE
,
64 IRQ_NOREQUEST
| IRQ_NOPROBE
, 0);
66 irq_set_handler_data(uirq
->parent_irq
, uirq
);
67 irq_set_chained_handler(uirq
->parent_irq
, s3c_irq_demux_uart
);
71 * s3c_init_uart_irqs() - initialise UART IRQs and the necessary demuxing
72 * @irq: The interrupt data for registering
73 * @nr_irqs: The number of interrupt descriptions in @irq.
75 * Register the UART interrupts specified by @irq including the demuxing
76 * routines. This supports the S3C6400 and newer style of devices.
78 void __init
s3c_init_uart_irqs(struct s3c_uart_irq
*irq
, unsigned int nr_irqs
)
80 for (; nr_irqs
> 0; nr_irqs
--, irq
++)
81 s3c_init_uart_irq(irq
);