summaryrefslogtreecommitdiff
path: root/arch/m68knommu
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68knommu')
-rw-r--r--arch/m68knommu/Kconfig4
-rw-r--r--arch/m68knommu/kernel/process.c4
-rw-r--r--arch/m68knommu/kernel/ptrace.c5
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c36
-rw-r--r--arch/m68knommu/kernel/syscalltable.S4
-rw-r--r--arch/m68knommu/platform/5206/config.c41
-rw-r--r--arch/m68knommu/platform/5206e/config.c41
-rw-r--r--arch/m68knommu/platform/520x/config.c45
-rw-r--r--arch/m68knommu/platform/523x/config.c46
-rw-r--r--arch/m68knommu/platform/5249/config.c77
-rw-r--r--arch/m68knommu/platform/5272/intc.c39
-rw-r--r--arch/m68knommu/platform/527x/config.c60
-rw-r--r--arch/m68knommu/platform/528x/config.c51
-rw-r--r--arch/m68knommu/platform/5307/config.c42
-rw-r--r--arch/m68knommu/platform/532x/config.c45
-rw-r--r--arch/m68knommu/platform/5407/config.c41
-rw-r--r--arch/m68knommu/platform/68328/ints.c8
-rw-r--r--arch/m68knommu/platform/68360/ints.c8
-rw-r--r--arch/m68knommu/platform/coldfire/intc-2.c76
-rw-r--r--arch/m68knommu/platform/coldfire/intc-simr.c68
-rw-r--r--arch/m68knommu/platform/coldfire/intc.c59
21 files changed, 765 insertions, 35 deletions
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 064f5913db1a..63be09e58d4a 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -59,6 +59,10 @@ config GENERIC_HARDIRQS
bool
default y
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ bool
+ default y
+
config GENERIC_CALIBRATE_DELAY
bool
default y
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index 5c9ecd427090..959cb249c759 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -221,6 +221,10 @@ int copy_thread(unsigned long clone_flags,
p->thread.usp = usp;
p->thread.ksp = (unsigned long)childstack;
+
+ if (clone_flags & CLONE_SETTLS)
+ task_thread_info(p)->tp_value = regs->d5;
+
/*
* Must save the current SFC/DFC value, NOT the value when
* the parent was last descheduled - RGH 10-08-96
diff --git a/arch/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
index 4d3828959fb0..85ed2f988f98 100644
--- a/arch/m68knommu/kernel/ptrace.c
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -319,6 +319,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
#endif
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(task_thread_info(child)->tp_value,
+ (unsigned long __user *)data);
+ break;
+
default:
ret = -EIO;
break;
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index b67cbc735a9b..923dd4aab875 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -190,3 +190,39 @@ int kernel_execve(const char *filename, char *const argv[], char *const envp[])
: "d" (__a), "d" (__b), "d" (__c));
return __res;
}
+
+asmlinkage unsigned long sys_get_thread_area(void)
+{
+ return current_thread_info()->tp_value;
+}
+
+asmlinkage int sys_set_thread_area(unsigned long tp)
+{
+ current_thread_info()->tp_value = tp;
+ return 0;
+}
+
+/* This syscall gets its arguments in A0 (mem), D2 (oldval) and
+ D1 (newval). */
+asmlinkage int
+sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
+ unsigned long __user * mem)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long mem_value;
+
+ down_read(&mm->mmap_sem);
+
+ mem_value = *mem;
+ if (mem_value == oldval)
+ *mem = newval;
+
+ up_read(&mm->mmap_sem);
+ return mem_value;
+}
+
+asmlinkage int sys_atomic_barrier(void)
+{
+ /* no code needed for uniprocs */
+ return 0;
+}
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
index 486837efa3d7..56dd01ded148 100644
--- a/arch/m68knommu/kernel/syscalltable.S
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -351,6 +351,10 @@ ENTRY(sys_call_table)
.long sys_pwritev /* 330 */
.long sys_rt_tgsigqueueinfo
.long sys_perf_event_open
+ .long sys_get_thread_area
+ .long sys_set_thread_area
+ .long sys_atomic_cmpxchg_32 /* 335 */
+ .long sys_atomic_barrier
.rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
diff --git a/arch/m68knommu/platform/5206/config.c b/arch/m68knommu/platform/5206/config.c
index 9c335465e66d..bb31b3448c3d 100644
--- a/arch/m68knommu/platform/5206/config.c
+++ b/arch/m68knommu/platform/5206/config.c
@@ -17,6 +17,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -38,8 +39,45 @@ static struct platform_device m5206_uart = {
.dev.platform_data = m5206_uart_platform,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m5206_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCF_IRQ_I2C,
+ .end = MCF_IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m5206_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m5206_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m5206_i2c_resources),
+ .resource = m5206_i2c_resources,
+ .dev.platform_data = &m5206_i2c_platform_data,
+};
+
+static void __init m5206_i2c_init(void)
+{
+ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
+ MCF_MBAR + MCFSIM_I2CICR);
+ mcf_mapirq2imr(MCF_IRQ_I2C, MCFINTC_I2C);
+}
+#endif
+
static struct platform_device *m5206_devices[] __initdata = {
&m5206_uart,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m5206_i2c,
+#endif
};
/***************************************************************************/
@@ -101,6 +139,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m5206_cpu_reset;
m5206_timers_init();
m5206_uarts_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m5206_i2c_init();
+#endif
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
diff --git a/arch/m68knommu/platform/5206e/config.c b/arch/m68knommu/platform/5206e/config.c
index 942397984c66..a10d9d130387 100644
--- a/arch/m68knommu/platform/5206e/config.c
+++ b/arch/m68knommu/platform/5206e/config.c
@@ -17,6 +17,7 @@
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
#include <asm/mcfdma.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -38,8 +39,45 @@ static struct platform_device m5206e_uart = {
.dev.platform_data = m5206e_uart_platform,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m5206e_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCF_IRQ_I2C,
+ .end = MCF_IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m5206e_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m5206e_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m5206e_i2c_resources),
+ .resource = m5206e_i2c_resources,
+ .dev.platform_data = &m5206e_i2c_platform_data,
+};
+
+static void __init m5206e_i2c_init(void)
+{
+ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
+ MCF_MBAR + MCFSIM_I2CICR);
+ mcf_mapirq2imr(MCF_IRQ_I2C, MCFINTC_I2C);
+}
+#endif
+
static struct platform_device *m5206e_devices[] __initdata = {
&m5206e_uart,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m5206e_i2c,
+#endif
};
/***************************************************************************/
@@ -107,6 +145,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m5206e_cpu_reset;
m5206e_timers_init();
m5206e_uarts_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m5206e_i2c_init();
+#endif
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
diff --git a/arch/m68knommu/platform/520x/config.c b/arch/m68knommu/platform/520x/config.c
index 92614de42cd3..3206f7ecf27e 100644
--- a/arch/m68knommu/platform/520x/config.c
+++ b/arch/m68knommu/platform/520x/config.c
@@ -19,6 +19,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -74,9 +75,50 @@ static struct platform_device m520x_fec = {
.resource = m520x_fec_resources,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m520x_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINT_VECBASE + MCFINT_I2C,
+ .end = MCFINT_VECBASE + MCFINT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m520x_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m520x_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m520x_i2c_resources),
+ .resource = m520x_i2c_resources,
+ .dev.platform_data = &m520x_i2c_platform_data,
+};
+
+static void __init m520x_i2c_init(void)
+{
+ u8 par;
+
+ /* setup Port FECI2C Pin Assignment Register for I2C */
+ /* set PAR_SCL to SCL and PAR_SDA to SDA */
+ par = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+ par |= 0x0f;
+ writeb(par, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+}
+#endif
+
static struct platform_device *m520x_devices[] __initdata = {
&m520x_uart,
&m520x_fec,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m520x_i2c,
+#endif
};
/***************************************************************************/
@@ -147,6 +189,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m520x_cpu_reset;
m520x_uarts_init();
m520x_fec_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m520x_i2c_init();
+#endif
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/523x/config.c b/arch/m68knommu/platform/523x/config.c
index 6ba84f2aa397..05b4ab9996d7 100644
--- a/arch/m68knommu/platform/523x/config.c
+++ b/arch/m68knommu/platform/523x/config.c
@@ -20,6 +20,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -75,9 +76,51 @@ static struct platform_device m523x_fec = {
.resource = m523x_fec_resources,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m523x_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINT_VECBASE + MCFINT_I2C,
+ .end = MCFINT_VECBASE + MCFINT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m523x_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m523x_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m523x_i2c_resources),
+ .resource = m523x_i2c_resources,
+ .dev.platform_data = &m523x_i2c_platform_data,
+};
+
+static void __init m523x_i2c_init(void)
+{
+ u8 par;
+
+ /* setup Port AS Pin Assignment Register for I2C */
+ /* set PASPA0 to SCL and PASPA1 to SDA */
+ par = readb(MCF_IPSBAR + MCFGPIO_PAR_FECI2C);
+ par |= 0x0f;
+ writeb(par, MCF_IPSBAR + MCFGPIO_PAR_FECI2C);
+}
+
+#endif
+
static struct platform_device *m523x_devices[] __initdata = {
&m523x_uart,
&m523x_fec,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m523x_i2c,
+#endif
};
/***************************************************************************/
@@ -114,6 +157,9 @@ void __init config_BSP(char *commandp, int size)
static int __init init_BSP(void)
{
m523x_fec_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m523x_i2c_init();
+#endif
platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/5249/config.c b/arch/m68knommu/platform/5249/config.c
index 646f5ba462fc..bd085427c43a 100644
--- a/arch/m68knommu/platform/5249/config.c
+++ b/arch/m68knommu/platform/5249/config.c
@@ -16,6 +16,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -37,8 +38,81 @@ static struct platform_device m5249_uart = {
.dev.platform_data = m5249_uart_platform,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m5249_i2c0_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCF_IRQ_I2C,
+ .end = MCF_IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource m5249_i2c1_resources[] = {
+ {
+ .start = MCFI2C_IOBASE2,
+ .end = MCFI2C_IOBASE2 + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINTC2_I2C,
+ .end = MCFINTC2_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m5249_i2c0_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct mcfi2c_platform_data m5249_i2c1_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m5249_i2c[] = {
+ {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m5249_i2c0_resources),
+ .resource = m5249_i2c0_resources,
+ .dev.platform_data = &m5249_i2c0_platform_data,
+ },
+ {
+ .name = "i2c-mcf",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(m5249_i2c1_resources),
+ .resource = m5249_i2c1_resources,
+ .dev.platform_data = &m5249_i2c1_platform_data,
+ },
+};
+
+static void __init m5249_i2c_init(void)
+{
+ u32 pri;
+
+ /* first I2C controller uses regular irq setup */
+ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
+ MCF_MBAR + MCFSIM_I2CICR);
+ mcf_mapirq2imr(MCF_IRQ_I2C, MCFINTC_I2C);
+
+ /* second I2C controller is completely different */
+ pri = readl(MCF_MBAR2 + MCFSIM2_INTLEVEL8);
+ pri &= ~MCFSIM2_INTPRI_62;
+ pri |= MCFSIM2_INTPRI_I2C;
+ writel(pri, MCF_MBAR2 + MCFSIM2_INTLEVEL8);
+}
+#endif
+
static struct platform_device *m5249_devices[] __initdata = {
&m5249_uart,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m5249_i2c[0],
+ &m5249_i2c[1],
+#endif
};
/***************************************************************************/
@@ -100,6 +174,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m5249_cpu_reset;
m5249_timers_init();
m5249_uarts_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m5249_i2c_init();
+#endif
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/5272/intc.c b/arch/m68knommu/platform/5272/intc.c
index 7081e0a9720e..2889f7d7cf70 100644
--- a/arch/m68knommu/platform/5272/intc.c
+++ b/arch/m68knommu/platform/5272/intc.c
@@ -103,8 +103,26 @@ static void intc_irq_ack(unsigned int irq)
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
- /* We can set the edge type here for external interrupts */
- return 0;
+ /* set the edge type for external interrupts */
+ u32 pitr;
+
+ if ((type != IRQF_TRIGGER_RISING) || (type != IRQF_TRIGGER_FALLING))
+ return -EINVAL;
+
+ switch (irq) {
+ case MCF_IRQ_EINT1 ... MCF_IRQ_EINT4:
+ case MCF_IRQ_EINT5 ... MCF_IRQ_EINT6:
+ pitr = __raw_readl(MCFSIM_PITR);
+ if (type & IRQF_TRIGGER_RISING)
+ pitr |= 1 << (96 - irq);
+ else
+ pitr &= ~(1 << (96 - irq));
+ __raw_writel(pitr, MCFSIM_PITR);
+
+ return 0;
+ default:
+ return -EINVAL;
+ }
}
static struct irq_chip intc_irq_chip = {
@@ -128,11 +146,16 @@ void __init init_IRQ(void)
writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
- intc_irq_set_type(irq, 0);
+ switch (irq) {
+ case MCF_IRQ_EINT1 ... MCF_IRQ_EINT4:
+ case MCF_IRQ_EINT5 ... MCF_IRQ_EINT6:
+ set_irq_chip_and_handler(irq, &intc_irq_chip,
+ handle_edge_irq);
+ break;
+ default:
+ set_irq_chip_and_handler(irq, &intc_irq_chip,
+ handle_level_irq);
+ break;
+ }
}
}
-
diff --git a/arch/m68knommu/platform/527x/config.c b/arch/m68knommu/platform/527x/config.c
index fa51be172830..001fa362021c 100644
--- a/arch/m68knommu/platform/527x/config.c
+++ b/arch/m68knommu/platform/527x/config.c
@@ -20,6 +20,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -106,12 +107,67 @@ static struct platform_device m527x_fec[] = {
},
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m527x_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINT_VECBASE + MCFINT_I2C,
+ .end = MCFINT_VECBASE + MCFINT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m527x_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m527x_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m527x_i2c_resources),
+ .resource = m527x_i2c_resources,
+ .dev.platform_data = &m527x_i2c_platform_data,
+};
+
+#if defined(CONFIG_M5271)
+static void __init m527x_i2c_init(void)
+{
+ u8 par;
+
+ /* setup Port FECI2C Pin Assignment Register for I2C */
+ /* set PAR_SCL to SCL and PAR_SDA to SDA */
+ par = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+ par |= 0x0f;
+ writeb(par, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+}
+#endif
+#if defined(CONFIG_M5275)
+static void __init m527x_i2c_init(void)
+{
+ u16 par;
+
+ /* setup Port FECI2C Pin Assignment Register for I2C */
+ /* set PAR_SCL to SCL and PAR_SDA to SDA */
+ par = readw(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+ par |= 0x0f;
+ writew(par, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
+}
+#endif
+#endif
+
static struct platform_device *m527x_devices[] __initdata = {
&m527x_uart,
&m527x_fec[0],
#ifdef CONFIG_FEC2
&m527x_fec[1],
#endif
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m527x_i2c,
+#endif
};
/***************************************************************************/
@@ -187,6 +243,10 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m527x_cpu_reset;
m527x_uarts_init();
m527x_fec_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m527x_i2c_init();
+#endif
+
}
/***************************************************************************/
diff --git a/arch/m68knommu/platform/528x/config.c b/arch/m68knommu/platform/528x/config.c
index 6e608d1836f1..f7516d8ea08d 100644
--- a/arch/m68knommu/platform/528x/config.c
+++ b/arch/m68knommu/platform/528x/config.c
@@ -21,6 +21,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -76,10 +77,57 @@ static struct platform_device m528x_fec = {
.resource = m528x_fec_resources,
};
+#if defined(CONFIG_GPIO_PCF857X) || defined(CONFIG_GPIO_PCF857X_MODULE)
+static struct pcf857x_platform_data pcf857x_data[] = {
+ {
+ .gpio_base = MCFGPIO_PIN_MAX,
+ },
+};
+#endif
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m528x_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINT_VECBASE + MCFINT_I2C,
+ .end = MCFINT_VECBASE + MCFINT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m528x_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m528x_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m528x_i2c_resources),
+ .resource = m528x_i2c_resources,
+ .dev.platform_data = &m528x_i2c_platform_data,
+};
+
+static void __init m528x_i2c_init(void)
+{
+ u16 paspar;
+
+ /* setup Port AS Pin Assignment Register for I2C */
+ /* set PASPA0 to SCL and PASPA1 to SDA */
+ paspar = __raw_readw(MCF_IPSBAR + MCF5282_GPIO_PASPAR);
+ paspar |= 0xF;
+ __raw_writew(paspar, MCF_IPSBAR + MCF5282_GPIO_PASPAR);
+}
+#endif
static struct platform_device *m528x_devices[] __initdata = {
&m528x_uart,
&m528x_fec,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m528x_i2c,
+#endif
};
/***************************************************************************/
@@ -174,6 +222,9 @@ static int __init init_BSP(void)
mach_reset = m528x_cpu_reset;
m528x_uarts_init();
m528x_fec_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m528x_i2c_init();
+#endif
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/5307/config.c b/arch/m68knommu/platform/5307/config.c
index 00900ac06a9c..57f51ab3ae29 100644
--- a/arch/m68knommu/platform/5307/config.c
+++ b/arch/m68knommu/platform/5307/config.c
@@ -18,6 +18,7 @@
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
#include <asm/mcfwdebug.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -47,8 +48,45 @@ static struct platform_device m5307_uart = {
.dev.platform_data = m5307_uart_platform,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m5307_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCF_IRQ_I2C,
+ .end = MCF_IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m5307_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m5307_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m5307_i2c_resources),
+ .resource = m5307_i2c_resources,
+ .dev.platform_data = &m5307_i2c_platform_data,
+};
+
+static void __init m5307_i2c_init(void)
+{
+ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
+ MCF_MBAR + MCFSIM_I2CICR);
+ mcf_mapirq2imr(MCF_IRQ_I2C, MCFINTC_I2C);
+}
+#endif
+
static struct platform_device *m5307_devices[] __initdata = {
&m5307_uart,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m5307_i2c,
+#endif
};
/***************************************************************************/
@@ -117,7 +155,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m5307_cpu_reset;
m5307_timers_init();
m5307_uarts_init();
-
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m5307_i2c_init();
+#endif
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
mcf_mapirq2imr(27, MCFINTC_EINT3);
diff --git a/arch/m68knommu/platform/532x/config.c b/arch/m68knommu/platform/532x/config.c
index d632948e64e5..7a0f14ec3460 100644
--- a/arch/m68knommu/platform/532x/config.c
+++ b/arch/m68knommu/platform/532x/config.c
@@ -27,6 +27,7 @@
#include <asm/mcfuart.h>
#include <asm/mcfdma.h>
#include <asm/mcfwdebug.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -82,9 +83,50 @@ static struct platform_device m532x_fec = {
.resource = m532x_fec_resources,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m532x_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCFINT_VECBASE + MCFINT_I2C,
+ .end = MCFINT_VECBASE + MCFINT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m532x_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m532x_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m532x_i2c_resources),
+ .resource = m532x_i2c_resources,
+ .dev.platform_data = &m532x_i2c_platform_data,
+};
+
+static void __init m532x_i2c_init(void)
+{
+ u8 par;
+
+ /* setup Port AS Pin Assignment Register for I2C */
+ /* set PASPA0 to SCL and PASPA1 to SDA */
+ par = __raw_readb(MCF_GPIO_PAR_FECI2C);
+ par |= 0x0f;
+ __raw_writeb(par, MCF_GPIO_PAR_FECI2C);
+}
+#endif
+
static struct platform_device *m532x_devices[] __initdata = {
&m532x_uart,
&m532x_fec,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m532x_i2c,
+#endif
};
/***************************************************************************/
@@ -158,6 +200,9 @@ static int __init init_BSP(void)
{
m532x_uarts_init();
m532x_fec_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m532x_i2c_init();
+#endif
platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
return 0;
}
diff --git a/arch/m68knommu/platform/5407/config.c b/arch/m68knommu/platform/5407/config.c
index 70ea789a400c..b8ceb3762c3f 100644
--- a/arch/m68knommu/platform/5407/config.c
+++ b/arch/m68knommu/platform/5407/config.c
@@ -17,6 +17,7 @@
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfuart.h>
+#include <asm/mcfi2c.h>
/***************************************************************************/
@@ -38,8 +39,45 @@ static struct platform_device m5407_uart = {
.dev.platform_data = m5407_uart_platform,
};
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+static struct resource m5407_i2c_resources[] = {
+ {
+ .start = MCFI2C_IOBASE,
+ .end = MCFI2C_IOBASE + MCFI2C_IOSIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MCF_IRQ_I2C,
+ .end = MCF_IRQ_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mcfi2c_platform_data m5407_i2c_platform_data = {
+ .bitrate = 100000,
+};
+
+static struct platform_device m5407_i2c = {
+ .name = "i2c-mcf",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(m5407_i2c_resources),
+ .resource = m5407_i2c_resources,
+ .dev.platform_data = &m5407_i2c_platform_data,
+};
+
+static void __init m5407_i2c_init(void)
+{
+ writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL5 | MCFSIM_ICR_PRI0,
+ MCF_MBAR + MCFSIM_I2CICR);
+ mcf_mapirq2imr(MCF_IRQ_I2C, MCFINTC_I2C);
+}
+#endif
+
static struct platform_device *m5407_devices[] __initdata = {
&m5407_uart,
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ &m5407_i2c,
+#endif
};
/***************************************************************************/
@@ -101,6 +139,9 @@ void __init config_BSP(char *commandp, int size)
mach_reset = m5407_cpu_reset;
m5407_timers_init();
m5407_uarts_init();
+#if defined(CONFIG_I2C_MCF) || defined(CONFIG_I2C_MCF_MODULE)
+ m5407_i2c_init();
+#endif
/* Only support the external interrupts on their primary level */
mcf_mapirq2imr(25, MCFINTC_EINT1);
diff --git a/arch/m68knommu/platform/68328/ints.c b/arch/m68knommu/platform/68328/ints.c
index b91ee85d4b5d..8a6a10212fb5 100644
--- a/arch/m68knommu/platform/68328/ints.c
+++ b/arch/m68knommu/platform/68328/ints.c
@@ -178,11 +178,7 @@ void __init init_IRQ(void)
/* turn off all interrupts */
IMR = ~0;
- for (i = 0; (i < NR_IRQS); i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
- irq_desc[i].chip = &intc_irq_chip;
- }
+ for (i = 0; (i < NR_IRQS); i++)
+ set_irq_chip_and_handler(i, &intc_irq_chip, handle_level_irq);
}
diff --git a/arch/m68knommu/platform/68360/ints.c b/arch/m68knommu/platform/68360/ints.c
index 1143f77caca4..9b94c52daa55 100644
--- a/arch/m68knommu/platform/68360/ints.c
+++ b/arch/m68knommu/platform/68360/ints.c
@@ -132,11 +132,7 @@ void init_IRQ(void)
/* turn off all CPM interrupts */
pquicc->intr_cimr = 0x00000000;
- for (i = 0; (i < NR_IRQS); i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
- irq_desc[i].chip = &intc_irq_chip;
- }
+ for (i = 0; (i < NR_IRQS); i++)
+ set_irq_chip_and_handler(i, &intc_irq_chip, handle_level_irq);
}
diff --git a/arch/m68knommu/platform/coldfire/intc-2.c b/arch/m68knommu/platform/coldfire/intc-2.c
index 5598c8b8661f..2863285927de 100644
--- a/arch/m68knommu/platform/coldfire/intc-2.c
+++ b/arch/m68knommu/platform/coldfire/intc-2.c
@@ -39,6 +39,15 @@ static void intc_irq_mask(unsigned int irq)
val = __raw_readl(imraddr);
__raw_writel(val | imrbit, imraddr);
+
+ /* only on eport */
+ if (irq >= MCFGPIO_IRQ_VECBASE ||
+ irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) {
+
+ u8 epier = __raw_readb(MCFEPORT_EPIER);
+ epier &= ~(1 << (irq - MCFGPIO_IRQ_VECBASE));
+ __raw_writeb(epier, MCFEPORT_EPIER);
+ }
}
}
@@ -64,13 +73,72 @@ static void intc_irq_unmask(unsigned int irq)
val = __raw_readl(imraddr);
__raw_writel(val & ~imrbit, imraddr);
+
+ /* only on eport */
+ if (irq >= MCFGPIO_IRQ_VECBASE ||
+ irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) {
+
+ u8 epier = __raw_readb(MCFEPORT_EPIER);
+ epier |= 1 << (irq - MCFGPIO_IRQ_VECBASE);
+ __raw_writeb(epier, MCFEPORT_EPIER);
+ }
+ }
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+ /* only on eport */
+ if (irq >= MCFGPIO_IRQ_VECBASE ||
+ irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) {
+ u8 epfr = __raw_readb(MCFEPORT_EPFR);
+ epfr |= 1 << (irq - MCFGPIO_IRQ_VECBASE);
+ __raw_writeb(epfr, MCFEPORT_EPFR);
}
}
+static int intc_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+ unsigned shift;
+ u16 eppar;
+
+ /* only on eport */
+ if (irq < MCFGPIO_IRQ_VECBASE ||
+ irq >= (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX))
+ return -EINVAL;
+
+ /* we only support TRIGGER_LOW or either (or both) RISING and FALLING */
+ if ((flow_type & IRQF_TRIGGER_HIGH) ||
+ ((flow_type & IRQF_TRIGGER_LOW) &&
+ (flow_type & (IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING))))
+ return -EINVAL;
+
+ shift = (irq - MCFGPIO_IRQ_VECBASE) * 2;
+
+ /* default to TRIGGER_LOW */
+ eppar = 0;
+ if (flow_type & IRQF_TRIGGER_RISING)
+ eppar |= (0x01 << shift);
+ if (flow_type & IRQF_TRIGGER_FALLING)
+ eppar |= (0x02 << shift);
+
+ if (eppar)
+ set_irq_handler(irq, handle_edge_irq);
+ else
+ set_irq_handler(irq, handle_level_irq);
+
+ eppar |= (__raw_readw(MCFEPORT_EPPAR) & ~(0x3 << shift));
+ __raw_writew(eppar, MCFEPORT_EPPAR);
+
+ return 0;
+}
+
static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
+ .ack = intc_irq_ack,
+ .set_type = intc_irq_set_type,
};
void __init init_IRQ(void)
@@ -83,11 +151,7 @@ void __init init_IRQ(void)
__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC0 + MCFINTC_IMRL);
__raw_writel(0x1, MCF_IPSBAR + MCFICM_INTC1 + MCFINTC_IMRL);
- for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
- }
+ for (irq = 0; (irq < NR_IRQS); irq++)
+ set_irq_chip_and_handler(irq, &intc_irq_chip, handle_level_irq);
}
diff --git a/arch/m68knommu/platform/coldfire/intc-simr.c b/arch/m68knommu/platform/coldfire/intc-simr.c
index 1b01e79c2f63..cc5473f6c2c7 100644
--- a/arch/m68knommu/platform/coldfire/intc-simr.c
+++ b/arch/m68knommu/platform/coldfire/intc-simr.c
@@ -26,6 +26,15 @@ static void intc_irq_mask(unsigned int irq)
else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_SIMR)
__raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_SIMR);
}
+
+ /* only on eport */
+ if (irq >= MCFGPIO_IRQ_VECBASE ||
+ irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) {
+
+ u8 epier = __raw_readb(MCFEPORT_EPIER);
+ epier &= ~(1 << (irq - MCFGPIO_IRQ_VECBASE));
+ __raw_writeb(epier, MCFEPORT_EPIER);
+ }
}
static void intc_irq_unmask(unsigned int irq)
@@ -36,10 +45,63 @@ static void intc_irq_unmask(unsigned int irq)
else if ((irq < MCFINT_VECBASE + 128) && MCFINTC1_CIMR)
__raw_writeb(irq - MCFINT_VECBASE - 64, MCFINTC1_CIMR);
}
+
+ /* only on eport */
+ if (irq >= MCFGPIO_IRQ_VECBASE ||
+ irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) {
+
+ u8 epier = __raw_readb(MCFEPORT_EPIER);
+ epier |= 1 << (irq - MCFGPIO_IRQ_VECBASE);
+ __raw_writeb(epier, MCFEPORT_EPIER);
+ }
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+ /* only on eport */
+ if (irq >= MCFGPIO_IRQ_VECBASE ||
+ irq < (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX)) {
+ u8 epfr = __raw_readb(MCFEPORT_EPFR);
+ epfr |= 1 << (irq - MCFGPIO_IRQ_VECBASE);
+ __raw_writeb(epfr, MCFEPORT_EPFR);
+ }
}
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
+ unsigned shift;
+ u16 eppar;
+
+ /* only on eport */
+ if (irq < MCFGPIO_IRQ_VECBASE ||
+ irq >= (MCFGPIO_IRQ_VECBASE + MCFGPIO_IRQ_MAX))
+ return -EINVAL;
+
+ /* we only support TRIGGER_LOW or either (or both) RISING and FALLING */
+ if ((type & IRQF_TRIGGER_HIGH) ||
+ ((type & IRQF_TRIGGER_LOW) &&
+ (type & (IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING))))
+ return -EINVAL;
+
+ shift = (irq - MCFGPIO_IRQ_VECBASE) * 2;
+
+ /* default to TRIGGER_LOW */
+ eppar = 0;
+ if (type & IRQF_TRIGGER_RISING)
+ eppar |= (0x01 << shift);
+ if (type & IRQF_TRIGGER_FALLING)
+ eppar |= (0x02 << shift);
+
+ if (eppar)
+ set_irq_handler(irq, handle_edge_irq);
+ else
+ set_irq_handler(irq, handle_level_irq);
+
+ eppar |= (__raw_readw(MCFEPORT_EPPAR) & ~(0x3 << shift));
+ __raw_writew(eppar, MCFEPORT_EPPAR);
+
+
if (irq >= MCFINT_VECBASE) {
if (irq < MCFINT_VECBASE + 64)
__raw_writeb(5, MCFINTC0_ICR0 + irq - MCFINT_VECBASE);
@@ -53,6 +115,7 @@ static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
+ .ack = intc_irq_ack,
.set_type = intc_irq_set_type,
};
@@ -68,10 +131,7 @@ void __init init_IRQ(void)
__raw_writeb(0xff, MCFINTC1_SIMR);
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
+ set_irq_chip_and_handler(irq, &intc_irq_chip, handle_level_irq);
intc_irq_set_type(irq, 0);
}
}
diff --git a/arch/m68knommu/platform/coldfire/intc.c b/arch/m68knommu/platform/coldfire/intc.c
index a4560c86db71..ad392a515cd2 100644
--- a/arch/m68knommu/platform/coldfire/intc.c
+++ b/arch/m68knommu/platform/coldfire/intc.c
@@ -115,16 +115,69 @@ static void intc_irq_mask(unsigned int irq)
{
if (mcf_irq2imr[irq])
mcf_setimr(mcf_irq2imr[irq]);
+
+#if defined MCFINTC2_GPIOIRQ0
+ if (irq >= MCFINTC2_GPIOIRQ0 && irq <= MCFINTC2_GPIOIRQ7) {
+ u32 gpiointenable = __raw_readl(MCFSIM2_GPIOINTENABLE);
+
+ gpiointenable &= ~(0x101 << (irq - MCFINTC2_GPIOIRQ0));
+ __raw_writel(gpiointenable, MCFSIM2_GPIOINTENABLE);
+ }
+#endif
}
static void intc_irq_unmask(unsigned int irq)
{
if (mcf_irq2imr[irq])
mcf_clrimr(mcf_irq2imr[irq]);
+
+#if defined MCFINTC2_GPIOIRQ0
+ if (irq >= MCFINTC2_GPIOIRQ0 && irq <= MCFINTC2_GPIOIRQ7) {
+ struct irq_desc *desc = irq_to_desc(irq);
+ u32 gpiointenable = __raw_readl(MCFSIM2_GPIOINTENABLE);
+
+ if (desc->status & IRQF_TRIGGER_RISING)
+ gpiointenable |= 0x0001 << (irq - MCFINTC2_GPIOIRQ0);
+ if (desc->status & IRQF_TRIGGER_FALLING)
+ gpiointenable |= 0x0100 << (irq - MCFINTC2_GPIOIRQ0);
+ __raw_writel(gpiointenable, MCFSIM2_GPIOINTENABLE);
+ }
+#endif
+}
+
+static void intc_irq_ack(unsigned int irq)
+{
+#if defined MCFINTC2_GPIOIRQ0
+ if (irq >= MCFINTC2_GPIOIRQ0 && irq <= MCFINTC2_GPIOIRQ7) {
+ u32 gpiointclear = __raw_readl(MCFSIM2_GPIOINTCLEAR);
+
+ gpiointclear |= 0x0101 << (irq - MCFINTC2_GPIOIRQ0);
+ __raw_writel(gpiointclear, MCFSIM2_GPIOINTCLEAR);
+ }
+#endif
}
static int intc_irq_set_type(unsigned int irq, unsigned int type)
{
+#if defined MCFINTC2_GPIOIRQ0
+ u32 gpiointenable;
+
+ if (type & ~(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
+ return -EINVAL;
+
+ if ((irq < MCFINTC2_GPIOIRQ0) || (irq > MCFINTC2_GPIOIRQ7))
+ return -EINVAL;
+
+ /* enable rising or falling or both */
+ gpiointenable = __raw_readl(MCFSIM2_GPIOINTENABLE);
+ gpiointenable &= ~(0x101 << (irq - MCFINTC2_GPIOIRQ0));
+ if (type & IRQF_TRIGGER_RISING)
+ gpiointenable |= 0x0001 << (irq - MCFINTC2_GPIOIRQ0);
+ if (type & IRQF_TRIGGER_FALLING)
+ gpiointenable |= 0x0100 << (irq - MCFINTC2_GPIOIRQ0);
+ __raw_writel(gpiointenable, MCFSIM2_GPIOINTENABLE);
+#endif
+
return 0;
}
@@ -132,6 +185,7 @@ static struct irq_chip intc_irq_chip = {
.name = "CF-INTC",
.mask = intc_irq_mask,
.unmask = intc_irq_unmask,
+ .ack = intc_irq_ack,
.set_type = intc_irq_set_type,
};
@@ -143,10 +197,7 @@ void __init init_IRQ(void)
mcf_maskimr(0xffffffff);
for (irq = 0; (irq < NR_IRQS); irq++) {
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = NULL;
- irq_desc[irq].depth = 1;
- irq_desc[irq].chip = &intc_irq_chip;
+ set_irq_chip_and_handler(irq, &intc_irq_chip, handle_level_irq);
intc_irq_set_type(irq, 0);
}
}