ARM: S3C24XX: assimilate second s3c2416 interrupt into new structure
From: Heiko Stuebner <heiko@...> Date: Sat, 17 Nov 2012 22:18:28 +0100
Commit-Message
The interrupt ack,mask and unmask functions for the main interrupt register are also able to handle the second one of the s3c2416. Signed-off-by: Heiko Stuebner <heiko@...>
Patch-Comment
arch/arm/plat-s3c24xx/irq.c | 118 ++++++++++++++++--------------------------- 1 files changed, 43 insertions(+), 75 deletions(-)
Statistics
- 43 lines added
- 75 lines removed
Changes
------------------------- arch/arm/plat-s3c24xx/irq.c --------------------------
index ace7e34..675a5f9 100644
@@ -22,6 +22,7 @@
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/syscore_ops.h>
+#include <linux/slab.h>
#include <linux/irqdomain.h>
@@ -54,6 +55,9 @@
/* s3c_irqext_chip + edge handler */
#define S3C_IRQTYPE_SUBEINT 6
+/* s3c2416_irq2_chip + edge handler */
+#define S3C_IRQTYPE_S3C2416 7
+
struct s3c_irq_data {
unsigned int type;
unsigned long parent_irq;
@@ -164,6 +168,13 @@ struct irq_chip s3c_irq_chip = {
.irq_set_wake = s3c_irq_wake
};
+struct irq_chip s3c2416_irq_second = {
+ .name = "s3c2416",
+ .irq_ack = s3c_irq_ack,
+ .irq_mask = s3c_irq_mask,
+ .irq_unmask = s3c_irq_unmask,
+};
+
static void s3c_irqext_ack(struct irq_data *data)
{
struct s3c_irq_intc *intc = data->domain->host_data;
@@ -516,6 +527,11 @@ static int s3c24xx_irq_map(struct irq_domain *h, unsigned int virq,
set_irq_flags(virq, IRQF_VALID);
attach_to_parent = true;
break;
+ case S3C_IRQTYPE_S3C2416:
+ irq_set_chip_and_handler(virq, &s3c2416_irq_second,
+ handle_edge_irq);
+ set_irq_flags(virq, IRQF_VALID);
+ break;
default:
pr_err("irq-s3c24xx: unsupported irqtype %d\n", irq_data->type);
return -EINVAL;
@@ -800,80 +816,6 @@ struct s3c_irq_data init_s3c2443base[32] = {
#endif
#ifdef CONFIG_CPU_S3C2416
struct s3c_irq_data init_s3c2416subint[32] = {
{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-RX */
{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 28 }, /* UART0-TX */
@@ -906,8 +848,21 @@ struct s3c_irq_data init_s3c2416subint[32] = {
{ .type = S3C_IRQTYPE_SUBLEVEL, .parent_irq = 9 }, /* AC97 */
};
+struct s3c_irq_data init_s3c2416_second[32] = {
+ { .type = S3C_IRQTYPE_S3C2416 }, /* 2D */
+ { .type = S3C_IRQTYPE_S3C2416 }, /* IIC1 */
+ { .type = S3C_IRQTYPE_NONE }, /* reserved */
+ { .type = S3C_IRQTYPE_NONE }, /* reserved */
+ { .type = S3C_IRQTYPE_S3C2416 }, /* PCM0 */
+ { .type = S3C_IRQTYPE_S3C2416 }, /* PCM1 */
+ { .type = S3C_IRQTYPE_S3C2416 }, /* I2S0 */
+ { .type = S3C_IRQTYPE_S3C2416 }, /* I2S1 */
+};
+
void __init s3c2416_init_irq(void)
{
+ struct s3c_irq_intc *s3c_intc2;
+
/* override irq data */
s3c_intc[0].irqs = &init_s3c2443base[0];
s3c_intc[2].irqs = &init_s3c2416subint[0];
@@ -916,7 +871,20 @@ void __init s3c2416_init_irq(void)
s3c24xx_init_irq();
+ s3c_intc2 = kzalloc(sizeof(struct s3c_irq_intc), GFP_KERNEL);
+ if (!s3c_intc2) {
+ pr_err("irq: failed to allocate memory for second controller\n");
+ return;
+ }
+
+ s3c_intc2->reg_pending = S3C2416_SRCPND2,
+ s3c_intc2->reg_intpnd = S3C2416_INTPND2,
+ s3c_intc2->reg_mask = S3C2416_INTMSK2,
+ s3c_intc2->irqs = &init_s3c2416_second[0],
+
+ s3c24xx_clear_intc(s3c_intc2);
+ s3c_intc2->domain = irq_domain_add_legacy(NULL, 8, IRQ_S3C2416_2D, 0,
+ &s3c24xx_irq_ops, s3c_intc2);
}
#ifdef CONFIG_PM