aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAndrew Victor <andrew@sanpeople.com>2007-05-11 16:01:28 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-05-11 17:02:48 -0400
commitc53c9cf60e49119e97d38390849cac5b2f0a0981 (patch)
tree37615dedbbd8980b8357df47d90843eb86d017ff /arch
parentc42dcb3dcfd3a473ab7c79c2ae91fc1c2e4dc5db (diff)
[ARM] 4331/3: Support for Micrel/Kendin KS8695 processor
Add core support for the Kendin/Micrel KS8695 processor family. It is an ARM922-T based SoC with integrated USART, 4-port Ethernet Switch, WAN Ethernet port, and optional PCI Host bridge, etc. http://www.micrel.com/page.do?page=product-info/sys_on_chip.jsp This patch is based on earlier patches from Lennert Buytenhek, Ben Dooks and Greg Ungerer posted to the arm-linux-kernel mailing list in March 2006; and Micrel's 2.6.9 port. Signed-off-by: Andrew Victor <andrew@sanpeople.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig13
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/mach-ks8695/Kconfig8
-rw-r--r--arch/arm/mach-ks8695/Makefile14
-rw-r--r--arch/arm/mach-ks8695/Makefile.boot8
-rw-r--r--arch/arm/mach-ks8695/cpu.c73
-rw-r--r--arch/arm/mach-ks8695/devices.c191
-rw-r--r--arch/arm/mach-ks8695/generic.h15
-rw-r--r--arch/arm/mach-ks8695/irq.c175
-rw-r--r--arch/arm/mach-ks8695/time.c114
-rw-r--r--arch/arm/mm/Kconfig6
11 files changed, 613 insertions, 5 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 52c209ef58b8..638f1d8080a9 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -305,6 +305,12 @@ config ARCH_L7200
305 If you have any questions or comments about the Linux kernel port 305 If you have any questions or comments about the Linux kernel port
306 to this board, send e-mail to <sjhill@cotw.com>. 306 to this board, send e-mail to <sjhill@cotw.com>.
307 307
308config ARCH_KS8695
309 bool "Micrel/Kendin KS8695"
310 help
311 Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
312 System-on-Chip devices.
313
308config ARCH_NS9XXX 314config ARCH_NS9XXX
309 bool "NetSilicon NS9xxx" 315 bool "NetSilicon NS9xxx"
310 help 316 help
@@ -451,6 +457,8 @@ source "arch/arm/mach-ns9xxx/Kconfig"
451 457
452source "arch/arm/mach-davinci/Kconfig" 458source "arch/arm/mach-davinci/Kconfig"
453 459
460source "arch/arm/mach-ks8695/Kconfig"
461
454# Definitions to make life easier 462# Definitions to make life easier
455config ARCH_ACORN 463config ARCH_ACORN
456 bool 464 bool
@@ -511,7 +519,7 @@ config ISA_DMA_API
511 bool 519 bool
512 520
513config PCI 521config PCI
514 bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX 522 bool "PCI support" if ARCH_INTEGRATOR_AP || ARCH_VERSATILE_PB || ARCH_IXP4XX || ARCH_KS8695
515 help 523 help
516 Find out whether you have a PCI motherboard. PCI is the name of a 524 Find out whether you have a PCI motherboard. PCI is the name of a
517 bus system, i.e. the way the CPU talks to the other stuff inside 525 bus system, i.e. the way the CPU talks to the other stuff inside
@@ -680,7 +688,8 @@ config LEDS
680 ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \ 688 ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
681 ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \ 689 ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
682 ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \ 690 ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
683 ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI 691 ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
692 ARCH_KS8695
684 help 693 help
685 If you say Y here, the LEDs on your machine will be used 694 If you say Y here, the LEDs on your machine will be used
686 to provide useful information about your current system status. 695 to provide useful information about your current system status.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index d568d86b0729..cbd5010d3bc3 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -136,6 +136,7 @@ endif
136 machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx 136 machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
137 textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000 137 textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000
138 machine-$(CONFIG_ARCH_DAVINCI) := davinci 138 machine-$(CONFIG_ARCH_DAVINCI) := davinci
139 machine-$(CONFIG_ARCH_KS8695) := ks8695
139 140
140ifeq ($(CONFIG_ARCH_EBSA110),y) 141ifeq ($(CONFIG_ARCH_EBSA110),y)
141# This is what happens if you forget the IOCS16 line. 142# This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
new file mode 100644
index 000000000000..44d14aa0baa7
--- /dev/null
+++ b/arch/arm/mach-ks8695/Kconfig
@@ -0,0 +1,8 @@
1if ARCH_KS8695
2
3menu "Kendin/Micrel KS8695 Implementations"
4
5
6endmenu
7
8endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
new file mode 100644
index 000000000000..0a0f496e8ccf
--- /dev/null
+++ b/arch/arm/mach-ks8695/Makefile
@@ -0,0 +1,14 @@
1# arch/arm/mach-ks8695/Makefile
2#
3# Makefile for KS8695 architecture support
4#
5
6obj-y := cpu.o irq.o time.o devices.o
7obj-m :=
8obj-n :=
9obj- :=
10
11# PCI support is optional
12#obj-$(CONFIG_PCI) += pci.o
13
14# Board-specific support
diff --git a/arch/arm/mach-ks8695/Makefile.boot b/arch/arm/mach-ks8695/Makefile.boot
new file mode 100644
index 000000000000..48eb2cb3ac77
--- /dev/null
+++ b/arch/arm/mach-ks8695/Makefile.boot
@@ -0,0 +1,8 @@
1# Note: the following conditions must always be true:
2# ZRELADDR == virt_to_phys(TEXTADDR)
3# PARAMS_PHYS must be within 4MB of ZRELADDR
4# INITRD_PHYS must be in RAM
5
6 zreladdr-y := 0x00008000
7params_phys-y := 0x00000100
8initrd_phys-y := 0x00800000
diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c
new file mode 100644
index 000000000000..407d255e42bf
--- /dev/null
+++ b/arch/arm/mach-ks8695/cpu.c
@@ -0,0 +1,73 @@
1/*
2 * arch/arm/mach-ks8695/cpu.c
3 *
4 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
5 * Copyright (C) 2006 Simtec Electronics
6 *
7 * KS8695 CPU support
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27
28#include <asm/hardware.h>
29#include <asm/io.h>
30#include <asm/mach/arch.h>
31#include <asm/mach/map.h>
32
33#include <asm/arch/regs-sys.h>
34#include <asm/arch/regs-misc.h>
35
36
37static struct __initdata map_desc ks8695_io_desc[] = {
38 {
39 .virtual = KS8695_IO_VA,
40 .pfn = __phys_to_pfn(KS8695_IO_PA),
41 .length = KS8695_IO_SIZE,
42 .type = MT_DEVICE,
43 }
44};
45
46static void __init ks8695_processor_info(void)
47{
48 unsigned long id, rev;
49
50 id = __raw_readl(KS8695_MISC_VA + KS8695_DID);
51 rev = __raw_readl(KS8695_MISC_VA + KS8695_RID);
52
53 printk("KS8695 ID=%04lx SubID=%02lx Revision=%02lx\n", (id & DID_ID), (rev & RID_SUBID), (rev & RID_REVISION));
54}
55
56static unsigned int sysclk[8] = { 125000000, 100000000, 62500000, 50000000, 41700000, 33300000, 31300000, 25000000 };
57static unsigned int cpuclk[8] = { 166000000, 166000000, 83000000, 83000000, 55300000, 55300000, 41500000, 41500000 };
58
59static void __init ks8695_clock_info(void)
60{
61 unsigned int scdc = __raw_readl(KS8695_SYS_VA + KS8695_CLKCON) & CLKCON_SCDC;
62
63 printk("Clocks: System %u MHz, CPU %u MHz\n",
64 sysclk[scdc] / 1000000, cpuclk[scdc] / 1000000);
65}
66
67void __init ks8695_map_io(void)
68{
69 iotable_init(ks8695_io_desc, ARRAY_SIZE(ks8695_io_desc));
70
71 ks8695_processor_info();
72 ks8695_clock_info();
73}
diff --git a/arch/arm/mach-ks8695/devices.c b/arch/arm/mach-ks8695/devices.c
new file mode 100644
index 000000000000..386593f8ac65
--- /dev/null
+++ b/arch/arm/mach-ks8695/devices.c
@@ -0,0 +1,191 @@
1/*
2 * arch/arm/mach-ks8695/devices.c
3 *
4 * Copyright (C) 2006 Andrew Victor
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <asm/mach/arch.h>
21#include <asm/mach/map.h>
22
23#include <linux/platform_device.h>
24
25#include <asm/arch/regs-wan.h>
26#include <asm/arch/regs-lan.h>
27#include <asm/arch/regs-hpna.h>
28
29
30/* --------------------------------------------------------------------
31 * Ethernet
32 * -------------------------------------------------------------------- */
33
34#if defined(CONFIG_ARM_KS8695_ETHER) || defined(CONFIG_ARM_KS8695_ETHER_MODULE)
35static u64 eth_dmamask = 0xffffffffUL;
36
37static struct resource ks8695_wan_resources[] = {
38 [0] = {
39 .start = KS8695_WAN_VA,
40 .end = KS8695_WAN_VA + 0x00ff,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .name = "WAN RX",
45 .start = KS8695_IRQ_WAN_RX_STATUS,
46 .end = KS8695_IRQ_WAN_RX_STATUS,
47 .flags = IORESOURCE_IRQ,
48 },
49 [2] = {
50 .name = "WAN TX",
51 .start = KS8695_IRQ_WAN_TX_STATUS,
52 .end = KS8695_IRQ_WAN_TX_STATUS,
53 .flags = IORESOURCE_IRQ,
54 },
55 [3] = {
56 .name = "WAN Link",
57 .start = KS8695_IRQ_WAN_LINK,
58 .end = KS8695_IRQ_WAN_LINK,
59 .flags = IORESOURCE_IRQ,
60 },
61};
62
63static struct platform_device ks8695_wan_device = {
64 .name = "ks8695_ether",
65 .id = 0,
66 .dev = {
67 .dma_mask = &eth_dmamask,
68 .coherent_dma_mask = 0xffffffff,
69 },
70 .resource = ks8695_wan_resources,
71 .num_resources = ARRAY_SIZE(ks8695_wan_resources),
72};
73
74
75static struct resource ks8695_lan_resources[] = {
76 [0] = {
77 .start = KS8695_LAN_VA,
78 .end = KS8695_LAN_VA + 0x00ff,
79 .flags = IORESOURCE_MEM,
80 },
81 [1] = {
82 .name = "LAN RX",
83 .start = KS8695_IRQ_LAN_RX_STATUS,
84 .end = KS8695_IRQ_LAN_RX_STATUS,
85 .flags = IORESOURCE_IRQ,
86 },
87 [2] = {
88 .name = "LAN TX",
89 .start = KS8695_IRQ_LAN_TX_STATUS,
90 .end = KS8695_IRQ_LAN_TX_STATUS,
91 .flags = IORESOURCE_IRQ,
92 },
93};
94
95static struct platform_device ks8695_lan_device = {
96 .name = "ks8695_ether",
97 .id = 1,
98 .dev = {
99 .dma_mask = &eth_dmamask,
100 .coherent_dma_mask = 0xffffffff,
101 },
102 .resource = ks8695_lan_resources,
103 .num_resources = ARRAY_SIZE(ks8695_lan_resources),
104};
105
106
107static struct resource ks8695_hpna_resources[] = {
108 [0] = {
109 .start = KS8695_HPNA_VA,
110 .end = KS8695_HPNA_VA + 0x00ff,
111 .flags = IORESOURCE_MEM,
112 },
113 [1] = {
114 .name = "HPNA RX",
115 .start = KS8695_IRQ_HPNA_RX_STATUS,
116 .end = KS8695_IRQ_HPNA_RX_STATUS,
117 .flags = IORESOURCE_IRQ,
118 },
119 [2] = {
120 .name = "HPNA TX",
121 .start = KS8695_IRQ_HPNA_TX_STATUS,
122 .end = KS8695_IRQ_HPNA_TX_STATUS,
123 .flags = IORESOURCE_IRQ,
124 },
125};
126
127static struct platform_device ks8695_hpna_device = {
128 .name = "ks8695_ether",
129 .id = 2,
130 .dev = {
131 .dma_mask = &eth_dmamask,
132 .coherent_dma_mask = 0xffffffff,
133 },
134 .resource = ks8695_hpna_resources,
135 .num_resources = ARRAY_SIZE(ks8695_hpna_resources),
136};
137
138void __init ks8695_add_device_wan(void)
139{
140 platform_device_register(&ks8695_wan_device);
141}
142
143void __init ks8695_add_device_lan(void)
144{
145 platform_device_register(&ks8695_lan_device);
146}
147
148void __init ks8696_add_device_hpna(void)
149{
150 platform_device_register(&ks8695_hpna_device);
151}
152#else
153void __init ks8695_add_device_wan(void) {}
154void __init ks8695_add_device_lan(void) {}
155void __init ks8696_add_device_hpna(void) {}
156#endif
157
158
159/* --------------------------------------------------------------------
160 * Watchdog
161 * -------------------------------------------------------------------- */
162
163#if defined(CONFIG_KS8695_WATCHDOG) || defined(CONFIG_KS8695_WATCHDOG_MODULE)
164static struct platform_device ks8695_wdt_device = {
165 .name = "ks8695_wdt",
166 .id = -1,
167 .num_resources = 0,
168};
169
170static void __init ks8695_add_device_watchdog(void)
171{
172 platform_device_register(&ks8695_wdt_device);
173}
174#else
175static void __init ks8695_add_device_watchdog(void) {}
176#endif
177
178
179/* -------------------------------------------------------------------- */
180
181/*
182 * These devices are always present and don't need any board-specific
183 * setup.
184 */
185static int __init ks8695_add_standard_devices(void)
186{
187 ks8695_add_device_watchdog();
188 return 0;
189}
190
191arch_initcall(ks8695_add_standard_devices);
diff --git a/arch/arm/mach-ks8695/generic.h b/arch/arm/mach-ks8695/generic.h
new file mode 100644
index 000000000000..2fbfab8d5fae
--- /dev/null
+++ b/arch/arm/mach-ks8695/generic.h
@@ -0,0 +1,15 @@
1/*
2 * arch/arm/mach-ks8695/generic.h
3 *
4 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
5 * Copyright (C) 2006 Simtec Electronics
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11*/
12
13extern __init void ks8695_map_io(void);
14extern __init void ks8695_init_irq(void);
15extern struct sys_timer ks8695_timer;
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
new file mode 100644
index 000000000000..2407bba00547
--- /dev/null
+++ b/arch/arm/mach-ks8695/irq.c
@@ -0,0 +1,175 @@
1/*
2 * arch/arm/mach-ks8695/irq.c
3 *
4 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
5 * Copyright (C) 2006 Simtec Electronics
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
25#include <linux/ioport.h>
26#include <linux/ptrace.h>
27#include <linux/sysdev.h>
28
29#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/io.h>
32
33#include <asm/mach/irq.h>
34
35#include <asm/arch/regs-irq.h>
36#include <asm/arch/regs-gpio.h>
37
38static void ks8695_irq_mask(unsigned int irqno)
39{
40 unsigned long inten;
41
42 inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
43 inten &= ~(1 << irqno);
44
45 __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
46}
47
48static void ks8695_irq_unmask(unsigned int irqno)
49{
50 unsigned long inten;
51
52 inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
53 inten |= (1 << irqno);
54
55 __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
56}
57
58static void ks8695_irq_ack(unsigned int irqno)
59{
60 __raw_writel((1 << irqno), KS8695_IRQ_VA + KS8695_INTST);
61}
62
63
64static struct irq_chip ks8695_irq_level_chip;
65static struct irq_chip ks8695_irq_edge_chip;
66
67
68static int ks8695_irq_set_type(unsigned int irqno, unsigned int type)
69{
70 unsigned long ctrl, mode;
71 unsigned short level_triggered = 0;
72
73 ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
74
75 switch (type) {
76 case IRQT_HIGH:
77 mode = IOPC_TM_HIGH;
78 level_triggered = 1;
79 break;
80 case IRQT_LOW:
81 mode = IOPC_TM_LOW;
82 level_triggered = 1;
83 break;
84 case IRQT_RISING:
85 mode = IOPC_TM_RISING;
86 break;
87 case IRQT_FALLING:
88 mode = IOPC_TM_FALLING;
89 break;
90 case IRQT_BOTHEDGE:
91 mode = IOPC_TM_EDGE;
92 break;
93 default:
94 return -EINVAL;
95 }
96
97 switch (irqno) {
98 case KS8695_IRQ_EXTERN0:
99 ctrl &= ~IOPC_IOEINT0TM;
100 ctrl |= IOPC_IOEINT0_MODE(mode);
101 break;
102 case KS8695_IRQ_EXTERN1:
103 ctrl &= ~IOPC_IOEINT1TM;
104 ctrl |= IOPC_IOEINT1_MODE(mode);
105 break;
106 case KS8695_IRQ_EXTERN2:
107 ctrl &= ~IOPC_IOEINT2TM;
108 ctrl |= IOPC_IOEINT2_MODE(mode);
109 break;
110 case KS8695_IRQ_EXTERN3:
111 ctrl &= ~IOPC_IOEINT3TM;
112 ctrl |= IOPC_IOEINT3_MODE(mode);
113 break;
114 default:
115 return -EINVAL;
116 }
117
118 if (level_triggered) {
119 set_irq_chip(irqno, &ks8695_irq_level_chip);
120 set_irq_handler(irqno, handle_level_irq);
121 }
122 else {
123 set_irq_chip(irqno, &ks8695_irq_edge_chip);
124 set_irq_handler(irqno, handle_edge_irq);
125 }
126
127 __raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
128 return 0;
129}
130
131static struct irq_chip ks8695_irq_level_chip = {
132 .ack = ks8695_irq_mask,
133 .mask = ks8695_irq_mask,
134 .unmask = ks8695_irq_unmask,
135 .set_type = ks8695_irq_set_type,
136};
137
138static struct irq_chip ks8695_irq_edge_chip = {
139 .ack = ks8695_irq_ack,
140 .mask = ks8695_irq_mask,
141 .unmask = ks8695_irq_unmask,
142 .set_type = ks8695_irq_set_type,
143};
144
145void __init ks8695_init_irq(void)
146{
147 unsigned int irq;
148
149 /* Disable all interrupts initially */
150 __raw_writel(0, KS8695_IRQ_VA + KS8695_INTMC);
151 __raw_writel(0, KS8695_IRQ_VA + KS8695_INTEN);
152
153 for (irq = 0; irq < NR_IRQS; irq++) {
154 switch (irq) {
155 /* Level-triggered interrupts */
156 case KS8695_IRQ_BUS_ERROR:
157 case KS8695_IRQ_UART_MODEM_STATUS:
158 case KS8695_IRQ_UART_LINE_STATUS:
159 case KS8695_IRQ_UART_RX:
160 case KS8695_IRQ_COMM_TX:
161 case KS8695_IRQ_COMM_RX:
162 set_irq_chip(irq, &ks8695_irq_level_chip);
163 set_irq_handler(irq, handle_level_irq);
164 break;
165
166 /* Edge-triggered interrupts */
167 default:
168 ks8695_irq_ack(irq); /* clear pending bit */
169 set_irq_chip(irq, &ks8695_irq_edge_chip);
170 set_irq_handler(irq, handle_edge_irq);
171 }
172
173 set_irq_flags(irq, IRQF_VALID);
174 }
175}
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
new file mode 100644
index 000000000000..d2c86e4a72eb
--- /dev/null
+++ b/arch/arm/mach-ks8695/time.c
@@ -0,0 +1,114 @@
1/*
2 * arch/arm/mach-ks8695/time.c
3 *
4 * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
5 * Copyright (C) 2006 Simtec Electronics
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/init.h>
23#include <linux/interrupt.h>
24#include <linux/irq.h>
25#include <linux/kernel.h>
26#include <linux/sched.h>
27
28#include <asm/io.h>
29#include <asm/mach/time.h>
30
31#include <asm/arch/regs-timer.h>
32#include <asm/arch/regs-irq.h>
33
34#include "generic.h"
35
36/*
37 * Returns number of ms since last clock interrupt. Note that interrupts
38 * will have been disabled by do_gettimeoffset()
39 */
40static unsigned long ks8695_gettimeoffset (void)
41{
42 unsigned long elapsed, tick2, intpending;
43
44 /*
45 * Get the current number of ticks. Note that there is a race
46 * condition between us reading the timer and checking for an
47 * interrupt. We solve this by ensuring that the counter has not
48 * reloaded between our two reads.
49 */
50 elapsed = __raw_readl(KS8695_TMR_VA + KS8695_T1TC) + __raw_readl(KS8695_TMR_VA + KS8695_T1PD);
51 do {
52 tick2 = elapsed;
53 intpending = __raw_readl(KS8695_IRQ_VA + KS8695_INTST) & (1 << KS8695_IRQ_TIMER1);
54 elapsed = __raw_readl(KS8695_TMR_VA + KS8695_T1TC) + __raw_readl(KS8695_TMR_VA + KS8695_T1PD);
55 } while (elapsed > tick2);
56
57 /* Convert to number of ticks expired (not remaining) */
58 elapsed = (CLOCK_TICK_RATE / HZ) - elapsed;
59
60 /* Is interrupt pending? If so, then timer has been reloaded already. */
61 if (intpending)
62 elapsed += (CLOCK_TICK_RATE / HZ);
63
64 /* Convert ticks to usecs */
65 return (unsigned long)(elapsed * (tick_nsec / 1000)) / LATCH;
66}
67
68/*
69 * IRQ handler for the timer.
70 */
71static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
72{
73 write_seqlock(&xtime_lock);
74 timer_tick();
75 write_sequnlock(&xtime_lock);
76
77 return IRQ_HANDLED;
78}
79
80static struct irqaction ks8695_timer_irq = {
81 .name = "ks8695_tick",
82 .flags = IRQF_DISABLED | IRQF_TIMER,
83 .handler = ks8695_timer_interrupt,
84};
85
86static void ks8695_timer_setup(void)
87{
88 unsigned long tmout = CLOCK_TICK_RATE / HZ;
89 unsigned long tmcon;
90
91 /* disable timer1 */
92 tmcon = __raw_readl(KS8695_TMR_VA + KS8695_TMCON);
93 __raw_writel(tmcon & ~TMCON_T1EN, KS8695_TMR_VA + KS8695_TMCON);
94
95 __raw_writel(tmout / 2, KS8695_TMR_VA + KS8695_T1TC);
96 __raw_writel(tmout / 2, KS8695_TMR_VA + KS8695_T1PD);
97
98 /* re-enable timer1 */
99 __raw_writel(tmcon | TMCON_T1EN, KS8695_TMR_VA + KS8695_TMCON);
100}
101
102static void __init ks8695_timer_init (void)
103{
104 ks8695_timer_setup();
105
106 /* Enable timer interrupts */
107 setup_irq(KS8695_IRQ_TIMER1, &ks8695_timer_irq);
108}
109
110struct sys_timer ks8695_timer = {
111 .init = ks8695_timer_init,
112 .offset = ks8695_gettimeoffset,
113 .resume = ks8695_timer_setup,
114};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index b8320a12e6b7..15f0284010ca 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -131,8 +131,8 @@ config CPU_ARM920T
131# ARM922T 131# ARM922T
132config CPU_ARM922T 132config CPU_ARM922T
133 bool "Support ARM922T processor" if ARCH_INTEGRATOR 133 bool "Support ARM922T processor" if ARCH_INTEGRATOR
134 depends on ARCH_LH7A40X || ARCH_INTEGRATOR 134 depends on ARCH_LH7A40X || ARCH_INTEGRATOR || ARCH_KS8695
135 default y if ARCH_LH7A40X 135 default y if ARCH_LH7A40X || ARCH_KS8695
136 select CPU_32v4T 136 select CPU_32v4T
137 select CPU_ABRT_EV4T 137 select CPU_ABRT_EV4T
138 select CPU_CACHE_V4WT 138 select CPU_CACHE_V4WT
@@ -143,7 +143,7 @@ config CPU_ARM922T
143 help 143 help
144 The ARM922T is a version of the ARM920T, but with smaller 144 The ARM922T is a version of the ARM920T, but with smaller
145 instruction and data caches. It is used in Altera's 145 instruction and data caches. It is used in Altera's
146 Excalibur XA device family. 146 Excalibur XA device family and Micrel's KS8695 Centaur.
147 147
148 Say Y if you want support for the ARM922T processor. 148 Say Y if you want support for the ARM922T processor.
149 Otherwise, say N. 149 Otherwise, say N.