diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/mips/alchemy | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'arch/mips/alchemy')
26 files changed, 957 insertions, 5751 deletions
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index c8862bdc2ff..2ccfd4a135b 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig | |||
@@ -2,10 +2,6 @@ | |||
2 | config ALCHEMY_GPIOINT_AU1000 | 2 | config ALCHEMY_GPIOINT_AU1000 |
3 | bool | 3 | bool |
4 | 4 | ||
5 | # au1300-style GPIO/INT controller | ||
6 | config ALCHEMY_GPIOINT_AU1300 | ||
7 | bool | ||
8 | |||
9 | # select this in your board config if you don't want to use the gpio | 5 | # select this in your board config if you don't want to use the gpio |
10 | # namespace as documented in the manuals. In this case however you need | 6 | # namespace as documented in the manuals. In this case however you need |
11 | # to create the necessary gpio_* functions in your board code/headers! | 7 | # to create the necessary gpio_* functions in your board code/headers! |
@@ -22,13 +18,43 @@ config MIPS_MTX1 | |||
22 | bool "4G Systems MTX-1 board" | 18 | bool "4G Systems MTX-1 board" |
23 | select DMA_NONCOHERENT | 19 | select DMA_NONCOHERENT |
24 | select HW_HAS_PCI | 20 | select HW_HAS_PCI |
25 | select ALCHEMY_GPIOINT_AU1000 | 21 | select SOC_AU1500 |
22 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
23 | select SYS_HAS_EARLY_PRINTK | ||
24 | |||
25 | config MIPS_BOSPORUS | ||
26 | bool "Alchemy Bosporus board" | ||
27 | select SOC_AU1500 | ||
28 | select DMA_NONCOHERENT | ||
26 | select SYS_SUPPORTS_LITTLE_ENDIAN | 29 | select SYS_SUPPORTS_LITTLE_ENDIAN |
27 | select SYS_HAS_EARLY_PRINTK | 30 | select SYS_HAS_EARLY_PRINTK |
28 | 31 | ||
29 | config MIPS_DB1000 | 32 | config MIPS_DB1000 |
30 | bool "Alchemy DB1000/DB1500/DB1100 PB1500/1100 boards" | 33 | bool "Alchemy DB1000 board" |
31 | select ALCHEMY_GPIOINT_AU1000 | 34 | select SOC_AU1000 |
35 | select DMA_NONCOHERENT | ||
36 | select HW_HAS_PCI | ||
37 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
38 | select SYS_HAS_EARLY_PRINTK | ||
39 | |||
40 | config MIPS_DB1100 | ||
41 | bool "Alchemy DB1100 board" | ||
42 | select SOC_AU1100 | ||
43 | select DMA_NONCOHERENT | ||
44 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
45 | select SYS_HAS_EARLY_PRINTK | ||
46 | |||
47 | config MIPS_DB1200 | ||
48 | bool "Alchemy DB1200 board" | ||
49 | select SOC_AU1200 | ||
50 | select DMA_COHERENT | ||
51 | select MIPS_DISABLE_OBSOLETE_IDE | ||
52 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
53 | select SYS_HAS_EARLY_PRINTK | ||
54 | |||
55 | config MIPS_DB1500 | ||
56 | bool "Alchemy DB1500 board" | ||
57 | select SOC_AU1500 | ||
32 | select DMA_NONCOHERENT | 58 | select DMA_NONCOHERENT |
33 | select HW_HAS_PCI | 59 | select HW_HAS_PCI |
34 | select MIPS_DISABLE_OBSOLETE_IDE | 60 | select MIPS_DISABLE_OBSOLETE_IDE |
@@ -36,11 +62,61 @@ config MIPS_DB1000 | |||
36 | select SYS_SUPPORTS_LITTLE_ENDIAN | 62 | select SYS_SUPPORTS_LITTLE_ENDIAN |
37 | select SYS_HAS_EARLY_PRINTK | 63 | select SYS_HAS_EARLY_PRINTK |
38 | 64 | ||
39 | config MIPS_DB1235 | 65 | config MIPS_DB1550 |
40 | bool "Alchemy DB1200/PB1200/DB1300/DB1550/PB1550 boards" | 66 | bool "Alchemy DB1550 board" |
41 | select ARCH_REQUIRE_GPIOLIB | 67 | select SOC_AU1550 |
68 | select HW_HAS_PCI | ||
69 | select DMA_NONCOHERENT | ||
70 | select MIPS_DISABLE_OBSOLETE_IDE | ||
71 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
72 | select SYS_HAS_EARLY_PRINTK | ||
73 | |||
74 | config MIPS_MIRAGE | ||
75 | bool "Alchemy Mirage board" | ||
76 | select DMA_NONCOHERENT | ||
77 | select SOC_AU1500 | ||
78 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
79 | select SYS_HAS_EARLY_PRINTK | ||
80 | |||
81 | config MIPS_PB1000 | ||
82 | bool "Alchemy PB1000 board" | ||
83 | select SOC_AU1000 | ||
84 | select DMA_NONCOHERENT | ||
85 | select HW_HAS_PCI | ||
86 | select SWAP_IO_SPACE | ||
87 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
88 | select SYS_HAS_EARLY_PRINTK | ||
89 | |||
90 | config MIPS_PB1100 | ||
91 | bool "Alchemy PB1100 board" | ||
92 | select SOC_AU1100 | ||
93 | select DMA_NONCOHERENT | ||
94 | select HW_HAS_PCI | ||
95 | select SWAP_IO_SPACE | ||
96 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
97 | select SYS_HAS_EARLY_PRINTK | ||
98 | |||
99 | config MIPS_PB1200 | ||
100 | bool "Alchemy PB1200 board" | ||
101 | select SOC_AU1200 | ||
102 | select DMA_NONCOHERENT | ||
103 | select MIPS_DISABLE_OBSOLETE_IDE | ||
104 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
105 | select SYS_HAS_EARLY_PRINTK | ||
106 | |||
107 | config MIPS_PB1500 | ||
108 | bool "Alchemy PB1500 board" | ||
109 | select SOC_AU1500 | ||
110 | select DMA_NONCOHERENT | ||
111 | select HW_HAS_PCI | ||
112 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
113 | select SYS_HAS_EARLY_PRINTK | ||
114 | |||
115 | config MIPS_PB1550 | ||
116 | bool "Alchemy PB1550 board" | ||
117 | select SOC_AU1550 | ||
118 | select DMA_NONCOHERENT | ||
42 | select HW_HAS_PCI | 119 | select HW_HAS_PCI |
43 | select DMA_COHERENT | ||
44 | select MIPS_DISABLE_OBSOLETE_IDE | 120 | select MIPS_DISABLE_OBSOLETE_IDE |
45 | select SYS_SUPPORTS_LITTLE_ENDIAN | 121 | select SYS_SUPPORTS_LITTLE_ENDIAN |
46 | select SYS_HAS_EARLY_PRINTK | 122 | select SYS_HAS_EARLY_PRINTK |
@@ -48,13 +124,13 @@ config MIPS_DB1235 | |||
48 | config MIPS_XXS1500 | 124 | config MIPS_XXS1500 |
49 | bool "MyCable XXS1500 board" | 125 | bool "MyCable XXS1500 board" |
50 | select DMA_NONCOHERENT | 126 | select DMA_NONCOHERENT |
51 | select ALCHEMY_GPIOINT_AU1000 | 127 | select SOC_AU1500 |
52 | select SYS_SUPPORTS_LITTLE_ENDIAN | 128 | select SYS_SUPPORTS_LITTLE_ENDIAN |
53 | select SYS_HAS_EARLY_PRINTK | 129 | select SYS_HAS_EARLY_PRINTK |
54 | 130 | ||
55 | config MIPS_GPR | 131 | config MIPS_GPR |
56 | bool "Trapeze ITS GPR board" | 132 | bool "Trapeze ITS GPR board" |
57 | select ALCHEMY_GPIOINT_AU1000 | 133 | select SOC_AU1550 |
58 | select HW_HAS_PCI | 134 | select HW_HAS_PCI |
59 | select DMA_NONCOHERENT | 135 | select DMA_NONCOHERENT |
60 | select MIPS_DISABLE_OBSOLETE_IDE | 136 | select MIPS_DISABLE_OBSOLETE_IDE |
@@ -62,3 +138,23 @@ config MIPS_GPR | |||
62 | select SYS_HAS_EARLY_PRINTK | 138 | select SYS_HAS_EARLY_PRINTK |
63 | 139 | ||
64 | endchoice | 140 | endchoice |
141 | |||
142 | config SOC_AU1000 | ||
143 | bool | ||
144 | select ALCHEMY_GPIOINT_AU1000 | ||
145 | |||
146 | config SOC_AU1100 | ||
147 | bool | ||
148 | select ALCHEMY_GPIOINT_AU1000 | ||
149 | |||
150 | config SOC_AU1500 | ||
151 | bool | ||
152 | select ALCHEMY_GPIOINT_AU1000 | ||
153 | |||
154 | config SOC_AU1550 | ||
155 | bool | ||
156 | select ALCHEMY_GPIOINT_AU1000 | ||
157 | |||
158 | config SOC_AU1200 | ||
159 | bool | ||
160 | select ALCHEMY_GPIOINT_AU1000 | ||
diff --git a/arch/mips/alchemy/Makefile b/arch/mips/alchemy/Makefile deleted file mode 100644 index aac3b179bbc..00000000000 --- a/arch/mips/alchemy/Makefile +++ /dev/null | |||
@@ -1,3 +0,0 @@ | |||
1 | obj-$(CONFIG_MIPS_GPR) += board-gpr.o | ||
2 | obj-$(CONFIG_MIPS_MTX1) += board-mtx1.o | ||
3 | obj-$(CONFIG_MIPS_XXS1500) += board-xxs1500.o | ||
diff --git a/arch/mips/alchemy/Platform b/arch/mips/alchemy/Platform index 942c5800a68..96e9e41f1b2 100644 --- a/arch/mips/alchemy/Platform +++ b/arch/mips/alchemy/Platform | |||
@@ -5,53 +5,105 @@ platform-$(CONFIG_MIPS_ALCHEMY) += alchemy/common/ | |||
5 | 5 | ||
6 | 6 | ||
7 | # | 7 | # |
8 | # AMD Alchemy Pb1000 eval board | ||
9 | # | ||
10 | platform-$(CONFIG_MIPS_PB1000) += alchemy/devboards/ | ||
11 | cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00 | ||
12 | load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000 | ||
13 | |||
14 | # | ||
8 | # AMD Alchemy Pb1100 eval board | 15 | # AMD Alchemy Pb1100 eval board |
9 | # | 16 | # |
10 | platform-$(CONFIG_MIPS_PB1100) += alchemy/devboards/ | 17 | platform-$(CONFIG_MIPS_PB1100) += alchemy/devboards/ |
18 | cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00 | ||
11 | load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000 | 19 | load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000 |
12 | 20 | ||
13 | # | 21 | # |
14 | # AMD Alchemy Pb1500 eval board | 22 | # AMD Alchemy Pb1500 eval board |
15 | # | 23 | # |
16 | platform-$(CONFIG_MIPS_PB1500) += alchemy/devboards/ | 24 | platform-$(CONFIG_MIPS_PB1500) += alchemy/devboards/ |
25 | cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00 | ||
17 | load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000 | 26 | load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000 |
18 | 27 | ||
19 | # | 28 | # |
20 | # AMD Alchemy Pb1550 eval board | 29 | # AMD Alchemy Pb1550 eval board |
21 | # | 30 | # |
22 | platform-$(CONFIG_MIPS_PB1550) += alchemy/devboards/ | 31 | platform-$(CONFIG_MIPS_PB1550) += alchemy/devboards/ |
32 | cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00 | ||
23 | load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000 | 33 | load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000 |
24 | 34 | ||
25 | # | 35 | # |
26 | # AMD Alchemy Db1000/Db1500/Db1100 eval boards | 36 | # AMD Alchemy Pb1200 eval board |
37 | # | ||
38 | platform-$(CONFIG_MIPS_PB1200) += alchemy/devboards/ | ||
39 | cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00 | ||
40 | load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000 | ||
41 | |||
42 | # | ||
43 | # AMD Alchemy Db1000 eval board | ||
27 | # | 44 | # |
28 | platform-$(CONFIG_MIPS_DB1000) += alchemy/devboards/ | 45 | platform-$(CONFIG_MIPS_DB1000) += alchemy/devboards/ |
29 | cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | 46 | cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 |
30 | load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000 | 47 | load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000 |
31 | 48 | ||
32 | # | 49 | # |
33 | # AMD Alchemy Db1200/Pb1200/Db1550/Db1300 eval boards | 50 | # AMD Alchemy Db1100 eval board |
51 | # | ||
52 | platform-$(CONFIG_MIPS_DB1100) += alchemy/devboards/ | ||
53 | cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | ||
54 | load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000 | ||
55 | |||
56 | # | ||
57 | # AMD Alchemy Db1500 eval board | ||
58 | # | ||
59 | platform-$(CONFIG_MIPS_DB1500) += alchemy/devboards/ | ||
60 | cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | ||
61 | load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000 | ||
62 | |||
63 | # | ||
64 | # AMD Alchemy Db1550 eval board | ||
65 | # | ||
66 | platform-$(CONFIG_MIPS_DB1550) += alchemy/devboards/ | ||
67 | cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | ||
68 | load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000 | ||
69 | |||
70 | # | ||
71 | # AMD Alchemy Db1200 eval board | ||
72 | # | ||
73 | platform-$(CONFIG_MIPS_DB1200) += alchemy/devboards/ | ||
74 | cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | ||
75 | load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000 | ||
76 | |||
77 | # | ||
78 | # AMD Alchemy Bosporus eval board | ||
79 | # | ||
80 | platform-$(CONFIG_MIPS_BOSPORUS) += alchemy/devboards/ | ||
81 | cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | ||
82 | load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000 | ||
83 | |||
84 | # | ||
85 | # AMD Alchemy Mirage eval board | ||
34 | # | 86 | # |
35 | platform-$(CONFIG_MIPS_DB1235) += alchemy/devboards/ | 87 | platform-$(CONFIG_MIPS_MIRAGE) += alchemy/devboards/ |
36 | cflags-$(CONFIG_MIPS_DB1235) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 | 88 | cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00 |
37 | load-$(CONFIG_MIPS_DB1235) += 0xffffffff80100000 | 89 | load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000 |
38 | 90 | ||
39 | # | 91 | # |
40 | # 4G-Systems MTX-1 "MeshCube" wireless router | 92 | # 4G-Systems eval board |
41 | # | 93 | # |
42 | platform-$(CONFIG_MIPS_MTX1) += alchemy/ | 94 | platform-$(CONFIG_MIPS_MTX1) += alchemy/mtx-1/ |
43 | load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000 | 95 | load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000 |
44 | 96 | ||
45 | # | 97 | # |
46 | # MyCable eval board | 98 | # MyCable eval board |
47 | # | 99 | # |
48 | platform-$(CONFIG_MIPS_XXS1500) += alchemy/ | 100 | platform-$(CONFIG_MIPS_XXS1500) += alchemy/xxs1500/ |
49 | load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000 | 101 | load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000 |
50 | 102 | ||
51 | # | 103 | # |
52 | # Trapeze ITS GRP board | 104 | # Trapeze ITS GRP board |
53 | # | 105 | # |
54 | platform-$(CONFIG_MIPS_GPR) += alchemy/ | 106 | platform-$(CONFIG_MIPS_GPR) += alchemy/gpr/ |
55 | load-$(CONFIG_MIPS_GPR) += 0xffffffff80100000 | 107 | load-$(CONFIG_MIPS_GPR) += 0xffffffff80100000 |
56 | 108 | ||
57 | # boards can specify their own <gpio.h> in one of their include dirs. | 109 | # boards can specify their own <gpio.h> in one of their include dirs. |
diff --git a/arch/mips/alchemy/board-gpr.c b/arch/mips/alchemy/board-gpr.c deleted file mode 100644 index ba3259086b9..00000000000 --- a/arch/mips/alchemy/board-gpr.c +++ /dev/null | |||
@@ -1,303 +0,0 @@ | |||
1 | /* | ||
2 | * GPR board platform device registration (Au1550) | ||
3 | * | ||
4 | * Copyright (C) 2010 Wolfgang Grandegger <wg@denx.de> | ||
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; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/delay.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/pm.h> | ||
27 | #include <linux/mtd/partitions.h> | ||
28 | #include <linux/mtd/physmap.h> | ||
29 | #include <linux/leds.h> | ||
30 | #include <linux/gpio.h> | ||
31 | #include <linux/i2c.h> | ||
32 | #include <linux/i2c-gpio.h> | ||
33 | #include <asm/bootinfo.h> | ||
34 | #include <asm/reboot.h> | ||
35 | #include <asm/mach-au1x00/au1000.h> | ||
36 | #include <prom.h> | ||
37 | |||
38 | const char *get_system_type(void) | ||
39 | { | ||
40 | return "GPR"; | ||
41 | } | ||
42 | |||
43 | void __init prom_init(void) | ||
44 | { | ||
45 | unsigned char *memsize_str; | ||
46 | unsigned long memsize; | ||
47 | |||
48 | prom_argc = fw_arg0; | ||
49 | prom_argv = (char **)fw_arg1; | ||
50 | prom_envp = (char **)fw_arg2; | ||
51 | |||
52 | prom_init_cmdline(); | ||
53 | |||
54 | memsize_str = prom_getenv("memsize"); | ||
55 | if (!memsize_str) | ||
56 | memsize = 0x04000000; | ||
57 | else | ||
58 | strict_strtoul(memsize_str, 0, &memsize); | ||
59 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
60 | } | ||
61 | |||
62 | void prom_putchar(unsigned char c) | ||
63 | { | ||
64 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); | ||
65 | } | ||
66 | |||
67 | static void gpr_reset(char *c) | ||
68 | { | ||
69 | /* switch System-LED to orange (red# and green# on) */ | ||
70 | alchemy_gpio_direction_output(4, 0); | ||
71 | alchemy_gpio_direction_output(5, 0); | ||
72 | |||
73 | /* trigger watchdog to reset board in 200ms */ | ||
74 | printk(KERN_EMERG "Triggering watchdog soft reset...\n"); | ||
75 | raw_local_irq_disable(); | ||
76 | alchemy_gpio_direction_output(1, 0); | ||
77 | udelay(1); | ||
78 | alchemy_gpio_set_value(1, 1); | ||
79 | while (1) | ||
80 | cpu_wait(); | ||
81 | } | ||
82 | |||
83 | static void gpr_power_off(void) | ||
84 | { | ||
85 | while (1) | ||
86 | cpu_wait(); | ||
87 | } | ||
88 | |||
89 | void __init board_setup(void) | ||
90 | { | ||
91 | printk(KERN_INFO "Trapeze ITS GPR board\n"); | ||
92 | |||
93 | pm_power_off = gpr_power_off; | ||
94 | _machine_halt = gpr_power_off; | ||
95 | _machine_restart = gpr_reset; | ||
96 | |||
97 | /* Enable UART1/3 */ | ||
98 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); | ||
99 | alchemy_uart_enable(AU1000_UART1_PHYS_ADDR); | ||
100 | |||
101 | /* Take away Reset of UMTS-card */ | ||
102 | alchemy_gpio_direction_output(215, 1); | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Watchdog | ||
107 | */ | ||
108 | static struct resource gpr_wdt_resource[] = { | ||
109 | [0] = { | ||
110 | .start = 1, | ||
111 | .end = 1, | ||
112 | .name = "gpr-adm6320-wdt", | ||
113 | .flags = IORESOURCE_IRQ, | ||
114 | } | ||
115 | }; | ||
116 | |||
117 | static struct platform_device gpr_wdt_device = { | ||
118 | .name = "adm6320-wdt", | ||
119 | .id = 0, | ||
120 | .num_resources = ARRAY_SIZE(gpr_wdt_resource), | ||
121 | .resource = gpr_wdt_resource, | ||
122 | }; | ||
123 | |||
124 | /* | ||
125 | * FLASH | ||
126 | * | ||
127 | * 0x00000000-0x00200000 : "kernel" | ||
128 | * 0x00200000-0x00a00000 : "rootfs" | ||
129 | * 0x01d00000-0x01f00000 : "config" | ||
130 | * 0x01c00000-0x01d00000 : "yamon" | ||
131 | * 0x01d00000-0x01d40000 : "yamon env vars" | ||
132 | * 0x00000000-0x00a00000 : "kernel+rootfs" | ||
133 | */ | ||
134 | static struct mtd_partition gpr_mtd_partitions[] = { | ||
135 | { | ||
136 | .name = "kernel", | ||
137 | .size = 0x00200000, | ||
138 | .offset = 0, | ||
139 | }, | ||
140 | { | ||
141 | .name = "rootfs", | ||
142 | .size = 0x00800000, | ||
143 | .offset = MTDPART_OFS_APPEND, | ||
144 | .mask_flags = MTD_WRITEABLE, | ||
145 | }, | ||
146 | { | ||
147 | .name = "config", | ||
148 | .size = 0x00200000, | ||
149 | .offset = 0x01d00000, | ||
150 | }, | ||
151 | { | ||
152 | .name = "yamon", | ||
153 | .size = 0x00100000, | ||
154 | .offset = 0x01c00000, | ||
155 | }, | ||
156 | { | ||
157 | .name = "yamon env vars", | ||
158 | .size = 0x00040000, | ||
159 | .offset = MTDPART_OFS_APPEND, | ||
160 | }, | ||
161 | { | ||
162 | .name = "kernel+rootfs", | ||
163 | .size = 0x00a00000, | ||
164 | .offset = 0, | ||
165 | }, | ||
166 | }; | ||
167 | |||
168 | static struct physmap_flash_data gpr_flash_data = { | ||
169 | .width = 4, | ||
170 | .nr_parts = ARRAY_SIZE(gpr_mtd_partitions), | ||
171 | .parts = gpr_mtd_partitions, | ||
172 | }; | ||
173 | |||
174 | static struct resource gpr_mtd_resource = { | ||
175 | .start = 0x1e000000, | ||
176 | .end = 0x1fffffff, | ||
177 | .flags = IORESOURCE_MEM, | ||
178 | }; | ||
179 | |||
180 | static struct platform_device gpr_mtd_device = { | ||
181 | .name = "physmap-flash", | ||
182 | .dev = { | ||
183 | .platform_data = &gpr_flash_data, | ||
184 | }, | ||
185 | .num_resources = 1, | ||
186 | .resource = &gpr_mtd_resource, | ||
187 | }; | ||
188 | |||
189 | /* | ||
190 | * LEDs | ||
191 | */ | ||
192 | static struct gpio_led gpr_gpio_leds[] = { | ||
193 | { /* green */ | ||
194 | .name = "gpr:green", | ||
195 | .gpio = 4, | ||
196 | .active_low = 1, | ||
197 | }, | ||
198 | { /* red */ | ||
199 | .name = "gpr:red", | ||
200 | .gpio = 5, | ||
201 | .active_low = 1, | ||
202 | } | ||
203 | }; | ||
204 | |||
205 | static struct gpio_led_platform_data gpr_led_data = { | ||
206 | .num_leds = ARRAY_SIZE(gpr_gpio_leds), | ||
207 | .leds = gpr_gpio_leds, | ||
208 | }; | ||
209 | |||
210 | static struct platform_device gpr_led_devices = { | ||
211 | .name = "leds-gpio", | ||
212 | .id = -1, | ||
213 | .dev = { | ||
214 | .platform_data = &gpr_led_data, | ||
215 | } | ||
216 | }; | ||
217 | |||
218 | /* | ||
219 | * I2C | ||
220 | */ | ||
221 | static struct i2c_gpio_platform_data gpr_i2c_data = { | ||
222 | .sda_pin = 209, | ||
223 | .sda_is_open_drain = 1, | ||
224 | .scl_pin = 210, | ||
225 | .scl_is_open_drain = 1, | ||
226 | .udelay = 2, /* ~100 kHz */ | ||
227 | .timeout = HZ, | ||
228 | }; | ||
229 | |||
230 | static struct platform_device gpr_i2c_device = { | ||
231 | .name = "i2c-gpio", | ||
232 | .id = -1, | ||
233 | .dev.platform_data = &gpr_i2c_data, | ||
234 | }; | ||
235 | |||
236 | static struct i2c_board_info gpr_i2c_info[] __initdata = { | ||
237 | { | ||
238 | I2C_BOARD_INFO("lm83", 0x18), | ||
239 | .type = "lm83" | ||
240 | } | ||
241 | }; | ||
242 | |||
243 | |||
244 | |||
245 | static struct resource alchemy_pci_host_res[] = { | ||
246 | [0] = { | ||
247 | .start = AU1500_PCI_PHYS_ADDR, | ||
248 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
249 | .flags = IORESOURCE_MEM, | ||
250 | }, | ||
251 | }; | ||
252 | |||
253 | static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
254 | { | ||
255 | if ((slot == 0) && (pin == 1)) | ||
256 | return AU1550_PCI_INTA; | ||
257 | else if ((slot == 0) && (pin == 2)) | ||
258 | return AU1550_PCI_INTB; | ||
259 | |||
260 | return 0xff; | ||
261 | } | ||
262 | |||
263 | static struct alchemy_pci_platdata gpr_pci_pd = { | ||
264 | .board_map_irq = gpr_map_pci_irq, | ||
265 | .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H | | ||
266 | PCI_CONFIG_CH | | ||
267 | #if defined(__MIPSEB__) | ||
268 | PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM, | ||
269 | #else | ||
270 | 0, | ||
271 | #endif | ||
272 | }; | ||
273 | |||
274 | static struct platform_device gpr_pci_host_dev = { | ||
275 | .dev.platform_data = &gpr_pci_pd, | ||
276 | .name = "alchemy-pci", | ||
277 | .id = 0, | ||
278 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
279 | .resource = alchemy_pci_host_res, | ||
280 | }; | ||
281 | |||
282 | static struct platform_device *gpr_devices[] __initdata = { | ||
283 | &gpr_wdt_device, | ||
284 | &gpr_mtd_device, | ||
285 | &gpr_i2c_device, | ||
286 | &gpr_led_devices, | ||
287 | }; | ||
288 | |||
289 | static int __init gpr_pci_init(void) | ||
290 | { | ||
291 | return platform_device_register(&gpr_pci_host_dev); | ||
292 | } | ||
293 | /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ | ||
294 | arch_initcall(gpr_pci_init); | ||
295 | |||
296 | |||
297 | static int __init gpr_dev_init(void) | ||
298 | { | ||
299 | i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info)); | ||
300 | |||
301 | return platform_add_devices(gpr_devices, ARRAY_SIZE(gpr_devices)); | ||
302 | } | ||
303 | device_initcall(gpr_dev_init); | ||
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c deleted file mode 100644 index a124c251c0c..00000000000 --- a/arch/mips/alchemy/board-mtx1.c +++ /dev/null | |||
@@ -1,315 +0,0 @@ | |||
1 | /* | ||
2 | * MTX-1 platform devices registration (Au1500) | ||
3 | * | ||
4 | * Copyright (C) 2007-2009, Florian Fainelli <florian@openwrt.org> | ||
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; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/init.h> | ||
22 | #include <linux/interrupt.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/leds.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/gpio_keys.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/mtd/partitions.h> | ||
30 | #include <linux/mtd/physmap.h> | ||
31 | #include <mtd/mtd-abi.h> | ||
32 | #include <asm/bootinfo.h> | ||
33 | #include <asm/reboot.h> | ||
34 | #include <asm/mach-au1x00/au1000.h> | ||
35 | #include <asm/mach-au1x00/au1xxx_eth.h> | ||
36 | #include <prom.h> | ||
37 | |||
38 | const char *get_system_type(void) | ||
39 | { | ||
40 | return "MTX-1"; | ||
41 | } | ||
42 | |||
43 | void __init prom_init(void) | ||
44 | { | ||
45 | unsigned char *memsize_str; | ||
46 | unsigned long memsize; | ||
47 | |||
48 | prom_argc = fw_arg0; | ||
49 | prom_argv = (char **)fw_arg1; | ||
50 | prom_envp = (char **)fw_arg2; | ||
51 | |||
52 | prom_init_cmdline(); | ||
53 | |||
54 | memsize_str = prom_getenv("memsize"); | ||
55 | if (!memsize_str) | ||
56 | memsize = 0x04000000; | ||
57 | else | ||
58 | strict_strtoul(memsize_str, 0, &memsize); | ||
59 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
60 | } | ||
61 | |||
62 | void prom_putchar(unsigned char c) | ||
63 | { | ||
64 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); | ||
65 | } | ||
66 | |||
67 | static void mtx1_reset(char *c) | ||
68 | { | ||
69 | /* Jump to the reset vector */ | ||
70 | __asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000)); | ||
71 | } | ||
72 | |||
73 | static void mtx1_power_off(void) | ||
74 | { | ||
75 | while (1) | ||
76 | asm volatile ( | ||
77 | " .set mips32 \n" | ||
78 | " wait \n" | ||
79 | " .set mips0 \n"); | ||
80 | } | ||
81 | |||
82 | void __init board_setup(void) | ||
83 | { | ||
84 | #if IS_ENABLED(CONFIG_USB_OHCI_HCD) | ||
85 | /* Enable USB power switch */ | ||
86 | alchemy_gpio_direction_output(204, 0); | ||
87 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ | ||
88 | |||
89 | /* Initialize sys_pinfunc */ | ||
90 | au_writel(SYS_PF_NI2, SYS_PINFUNC); | ||
91 | |||
92 | /* Initialize GPIO */ | ||
93 | au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR); | ||
94 | alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */ | ||
95 | alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */ | ||
96 | alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */ | ||
97 | alchemy_gpio_direction_output(5, 0); /* Disable eth PHY TX_ER */ | ||
98 | |||
99 | /* Enable LED and set it to green */ | ||
100 | alchemy_gpio_direction_output(211, 1); /* green on */ | ||
101 | alchemy_gpio_direction_output(212, 0); /* red off */ | ||
102 | |||
103 | pm_power_off = mtx1_power_off; | ||
104 | _machine_halt = mtx1_power_off; | ||
105 | _machine_restart = mtx1_reset; | ||
106 | |||
107 | printk(KERN_INFO "4G Systems MTX-1 Board\n"); | ||
108 | } | ||
109 | |||
110 | /******************************************************************************/ | ||
111 | |||
112 | static struct gpio_keys_button mtx1_gpio_button[] = { | ||
113 | { | ||
114 | .gpio = 207, | ||
115 | .code = BTN_0, | ||
116 | .desc = "System button", | ||
117 | } | ||
118 | }; | ||
119 | |||
120 | static struct gpio_keys_platform_data mtx1_buttons_data = { | ||
121 | .buttons = mtx1_gpio_button, | ||
122 | .nbuttons = ARRAY_SIZE(mtx1_gpio_button), | ||
123 | }; | ||
124 | |||
125 | static struct platform_device mtx1_button = { | ||
126 | .name = "gpio-keys", | ||
127 | .id = -1, | ||
128 | .dev = { | ||
129 | .platform_data = &mtx1_buttons_data, | ||
130 | } | ||
131 | }; | ||
132 | |||
133 | static struct resource mtx1_wdt_res[] = { | ||
134 | [0] = { | ||
135 | .start = 215, | ||
136 | .end = 215, | ||
137 | .name = "mtx1-wdt-gpio", | ||
138 | .flags = IORESOURCE_IRQ, | ||
139 | } | ||
140 | }; | ||
141 | |||
142 | static struct platform_device mtx1_wdt = { | ||
143 | .name = "mtx1-wdt", | ||
144 | .id = 0, | ||
145 | .num_resources = ARRAY_SIZE(mtx1_wdt_res), | ||
146 | .resource = mtx1_wdt_res, | ||
147 | }; | ||
148 | |||
149 | static struct gpio_led default_leds[] = { | ||
150 | { | ||
151 | .name = "mtx1:green", | ||
152 | .gpio = 211, | ||
153 | }, { | ||
154 | .name = "mtx1:red", | ||
155 | .gpio = 212, | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | static struct gpio_led_platform_data mtx1_led_data = { | ||
160 | .num_leds = ARRAY_SIZE(default_leds), | ||
161 | .leds = default_leds, | ||
162 | }; | ||
163 | |||
164 | static struct platform_device mtx1_gpio_leds = { | ||
165 | .name = "leds-gpio", | ||
166 | .id = -1, | ||
167 | .dev = { | ||
168 | .platform_data = &mtx1_led_data, | ||
169 | } | ||
170 | }; | ||
171 | |||
172 | static struct mtd_partition mtx1_mtd_partitions[] = { | ||
173 | { | ||
174 | .name = "filesystem", | ||
175 | .size = 0x01C00000, | ||
176 | .offset = 0, | ||
177 | }, | ||
178 | { | ||
179 | .name = "yamon", | ||
180 | .size = 0x00100000, | ||
181 | .offset = MTDPART_OFS_APPEND, | ||
182 | .mask_flags = MTD_WRITEABLE, | ||
183 | }, | ||
184 | { | ||
185 | .name = "kernel", | ||
186 | .size = 0x002c0000, | ||
187 | .offset = MTDPART_OFS_APPEND, | ||
188 | }, | ||
189 | { | ||
190 | .name = "yamon env", | ||
191 | .size = 0x00040000, | ||
192 | .offset = MTDPART_OFS_APPEND, | ||
193 | }, | ||
194 | }; | ||
195 | |||
196 | static struct physmap_flash_data mtx1_flash_data = { | ||
197 | .width = 4, | ||
198 | .nr_parts = 4, | ||
199 | .parts = mtx1_mtd_partitions, | ||
200 | }; | ||
201 | |||
202 | static struct resource mtx1_mtd_resource = { | ||
203 | .start = 0x1e000000, | ||
204 | .end = 0x1fffffff, | ||
205 | .flags = IORESOURCE_MEM, | ||
206 | }; | ||
207 | |||
208 | static struct platform_device mtx1_mtd = { | ||
209 | .name = "physmap-flash", | ||
210 | .dev = { | ||
211 | .platform_data = &mtx1_flash_data, | ||
212 | }, | ||
213 | .num_resources = 1, | ||
214 | .resource = &mtx1_mtd_resource, | ||
215 | }; | ||
216 | |||
217 | static struct resource alchemy_pci_host_res[] = { | ||
218 | [0] = { | ||
219 | .start = AU1500_PCI_PHYS_ADDR, | ||
220 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
221 | .flags = IORESOURCE_MEM, | ||
222 | }, | ||
223 | }; | ||
224 | |||
225 | static int mtx1_pci_idsel(unsigned int devsel, int assert) | ||
226 | { | ||
227 | /* This function is only necessary to support a proprietary Cardbus | ||
228 | * adapter on the mtx-1 "singleboard" variant. It triggers a custom | ||
229 | * logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals. | ||
230 | */ | ||
231 | udelay(1); | ||
232 | |||
233 | if (assert && devsel != 0) | ||
234 | /* Suppress signal to Cardbus */ | ||
235 | alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */ | ||
236 | else | ||
237 | alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */ | ||
238 | |||
239 | udelay(1); | ||
240 | return 1; | ||
241 | } | ||
242 | |||
243 | static const char mtx1_irqtab[][5] = { | ||
244 | [0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */ | ||
245 | [1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ | ||
246 | [2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */ | ||
247 | [3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ | ||
248 | [4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */ | ||
249 | [5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */ | ||
250 | [6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */ | ||
251 | [7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */ | ||
252 | }; | ||
253 | |||
254 | static int mtx1_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
255 | { | ||
256 | return mtx1_irqtab[slot][pin]; | ||
257 | } | ||
258 | |||
259 | static struct alchemy_pci_platdata mtx1_pci_pd = { | ||
260 | .board_map_irq = mtx1_map_pci_irq, | ||
261 | .board_pci_idsel = mtx1_pci_idsel, | ||
262 | .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H | | ||
263 | PCI_CONFIG_CH | | ||
264 | #if defined(__MIPSEB__) | ||
265 | PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM, | ||
266 | #else | ||
267 | 0, | ||
268 | #endif | ||
269 | }; | ||
270 | |||
271 | static struct platform_device mtx1_pci_host = { | ||
272 | .dev.platform_data = &mtx1_pci_pd, | ||
273 | .name = "alchemy-pci", | ||
274 | .id = 0, | ||
275 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
276 | .resource = alchemy_pci_host_res, | ||
277 | }; | ||
278 | |||
279 | static struct __initdata platform_device * mtx1_devs[] = { | ||
280 | &mtx1_pci_host, | ||
281 | &mtx1_gpio_leds, | ||
282 | &mtx1_wdt, | ||
283 | &mtx1_button, | ||
284 | &mtx1_mtd, | ||
285 | }; | ||
286 | |||
287 | static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = { | ||
288 | .phy_search_highest_addr = 1, | ||
289 | .phy1_search_mac0 = 1, | ||
290 | }; | ||
291 | |||
292 | static int __init mtx1_register_devices(void) | ||
293 | { | ||
294 | int rc; | ||
295 | |||
296 | irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH); | ||
297 | irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW); | ||
298 | irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW); | ||
299 | irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW); | ||
300 | irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW); | ||
301 | |||
302 | au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata); | ||
303 | |||
304 | rc = gpio_request(mtx1_gpio_button[0].gpio, | ||
305 | mtx1_gpio_button[0].desc); | ||
306 | if (rc < 0) { | ||
307 | printk(KERN_INFO "mtx1: failed to request %d\n", | ||
308 | mtx1_gpio_button[0].gpio); | ||
309 | goto out; | ||
310 | } | ||
311 | gpio_direction_input(mtx1_gpio_button[0].gpio); | ||
312 | out: | ||
313 | return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs)); | ||
314 | } | ||
315 | arch_initcall(mtx1_register_devices); | ||
diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c deleted file mode 100644 index bd551365029..00000000000 --- a/arch/mips/alchemy/board-xxs1500.c +++ /dev/null | |||
@@ -1,154 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * MyCable XXS1500 board support | ||
4 | * | ||
5 | * Copyright 2003, 2008 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/pm.h> | ||
30 | #include <asm/bootinfo.h> | ||
31 | #include <asm/reboot.h> | ||
32 | #include <asm/mach-au1x00/au1000.h> | ||
33 | #include <prom.h> | ||
34 | |||
35 | const char *get_system_type(void) | ||
36 | { | ||
37 | return "XXS1500"; | ||
38 | } | ||
39 | |||
40 | void __init prom_init(void) | ||
41 | { | ||
42 | unsigned char *memsize_str; | ||
43 | unsigned long memsize; | ||
44 | |||
45 | prom_argc = fw_arg0; | ||
46 | prom_argv = (char **)fw_arg1; | ||
47 | prom_envp = (char **)fw_arg2; | ||
48 | |||
49 | prom_init_cmdline(); | ||
50 | |||
51 | memsize_str = prom_getenv("memsize"); | ||
52 | if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize)) | ||
53 | memsize = 0x04000000; | ||
54 | |||
55 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
56 | } | ||
57 | |||
58 | void prom_putchar(unsigned char c) | ||
59 | { | ||
60 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); | ||
61 | } | ||
62 | |||
63 | static void xxs1500_reset(char *c) | ||
64 | { | ||
65 | /* Jump to the reset vector */ | ||
66 | __asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000)); | ||
67 | } | ||
68 | |||
69 | static void xxs1500_power_off(void) | ||
70 | { | ||
71 | while (1) | ||
72 | asm volatile ( | ||
73 | " .set mips32 \n" | ||
74 | " wait \n" | ||
75 | " .set mips0 \n"); | ||
76 | } | ||
77 | |||
78 | void __init board_setup(void) | ||
79 | { | ||
80 | u32 pin_func; | ||
81 | |||
82 | pm_power_off = xxs1500_power_off; | ||
83 | _machine_halt = xxs1500_power_off; | ||
84 | _machine_restart = xxs1500_reset; | ||
85 | |||
86 | alchemy_gpio1_input_enable(); | ||
87 | alchemy_gpio2_enable(); | ||
88 | |||
89 | /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ | ||
90 | pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; | ||
91 | pin_func |= SYS_PF_UR3; | ||
92 | au_writel(pin_func, SYS_PINFUNC); | ||
93 | |||
94 | /* Enable UART */ | ||
95 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); | ||
96 | /* Enable DTR (MCR bit 0) = USB power up */ | ||
97 | __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18)); | ||
98 | wmb(); | ||
99 | } | ||
100 | |||
101 | /******************************************************************************/ | ||
102 | |||
103 | static struct resource xxs1500_pcmcia_res[] = { | ||
104 | { | ||
105 | .name = "pcmcia-io", | ||
106 | .flags = IORESOURCE_MEM, | ||
107 | .start = AU1000_PCMCIA_IO_PHYS_ADDR, | ||
108 | .end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1, | ||
109 | }, | ||
110 | { | ||
111 | .name = "pcmcia-attr", | ||
112 | .flags = IORESOURCE_MEM, | ||
113 | .start = AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
114 | .end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | ||
115 | }, | ||
116 | { | ||
117 | .name = "pcmcia-mem", | ||
118 | .flags = IORESOURCE_MEM, | ||
119 | .start = AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
120 | .end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | ||
121 | }, | ||
122 | }; | ||
123 | |||
124 | static struct platform_device xxs1500_pcmcia_dev = { | ||
125 | .name = "xxs1500_pcmcia", | ||
126 | .id = -1, | ||
127 | .num_resources = ARRAY_SIZE(xxs1500_pcmcia_res), | ||
128 | .resource = xxs1500_pcmcia_res, | ||
129 | }; | ||
130 | |||
131 | static struct platform_device *xxs1500_devs[] __initdata = { | ||
132 | &xxs1500_pcmcia_dev, | ||
133 | }; | ||
134 | |||
135 | static int __init xxs1500_dev_init(void) | ||
136 | { | ||
137 | irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH); | ||
138 | irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW); | ||
139 | irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW); | ||
140 | irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW); | ||
141 | irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW); | ||
142 | irq_set_irq_type(AU1500_GPIO207_INT, IRQ_TYPE_LEVEL_LOW); | ||
143 | |||
144 | irq_set_irq_type(AU1500_GPIO0_INT, IRQ_TYPE_LEVEL_LOW); | ||
145 | irq_set_irq_type(AU1500_GPIO1_INT, IRQ_TYPE_LEVEL_LOW); | ||
146 | irq_set_irq_type(AU1500_GPIO2_INT, IRQ_TYPE_LEVEL_LOW); | ||
147 | irq_set_irq_type(AU1500_GPIO3_INT, IRQ_TYPE_LEVEL_LOW); | ||
148 | irq_set_irq_type(AU1500_GPIO4_INT, IRQ_TYPE_LEVEL_LOW); /* CF irq */ | ||
149 | irq_set_irq_type(AU1500_GPIO5_INT, IRQ_TYPE_LEVEL_LOW); | ||
150 | |||
151 | return platform_add_devices(xxs1500_devs, | ||
152 | ARRAY_SIZE(xxs1500_devs)); | ||
153 | } | ||
154 | device_initcall(xxs1500_dev_init); | ||
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index cb83d8d21ae..27811fe341d 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -6,9 +6,15 @@ | |||
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ | 8 | obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ |
9 | sleeper.o dma.o dbdma.o vss.o irq.o usb.o | 9 | sleeper.o dma.o dbdma.o |
10 | |||
11 | obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o | ||
10 | 12 | ||
11 | # optional gpiolib support | 13 | # optional gpiolib support |
12 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) | 14 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) |
13 | obj-$(CONFIG_GPIOLIB) += gpiolib.o | 15 | ifeq ($(CONFIG_GPIOLIB),y) |
16 | obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o | ||
17 | endif | ||
14 | endif | 18 | endif |
19 | |||
20 | obj-$(CONFIG_PCI) += pci.o | ||
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index cf02d7dc2df..3a5abb54d50 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
42 | 42 | ||
43 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
44 | |||
43 | /* | 45 | /* |
44 | * The Descriptor Based DMA supports up to 16 channels. | 46 | * The Descriptor Based DMA supports up to 16 channels. |
45 | * | 47 | * |
@@ -60,140 +62,120 @@ static dbdma_global_t *dbdma_gptr = | |||
60 | (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); | 62 | (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); |
61 | static int dbdma_initialized; | 63 | static int dbdma_initialized; |
62 | 64 | ||
63 | static dbdev_tab_t *dbdev_tab; | 65 | static dbdev_tab_t dbdev_tab[] = { |
64 | 66 | #ifdef CONFIG_SOC_AU1550 | |
65 | static dbdev_tab_t au1550_dbdev_tab[] __initdata = { | ||
66 | /* UARTS */ | 67 | /* UARTS */ |
67 | { AU1550_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, | 68 | { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, |
68 | { AU1550_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, | 69 | { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, |
69 | { AU1550_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 }, | 70 | { DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 }, |
70 | { AU1550_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 }, | 71 | { DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 }, |
71 | 72 | ||
72 | /* EXT DMA */ | 73 | /* EXT DMA */ |
73 | { AU1550_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, | 74 | { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, |
74 | { AU1550_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, | 75 | { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, |
75 | { AU1550_DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 }, | 76 | { DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 }, |
76 | { AU1550_DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 }, | 77 | { DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 }, |
77 | 78 | ||
78 | /* USB DEV */ | 79 | /* USB DEV */ |
79 | { AU1550_DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 }, | 80 | { DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 }, |
80 | { AU1550_DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 }, | 81 | { DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 }, |
81 | { AU1550_DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 }, | 82 | { DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 }, |
82 | { AU1550_DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 }, | 83 | { DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 }, |
83 | { AU1550_DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 }, | 84 | { DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 }, |
84 | { AU1550_DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 }, | 85 | { DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 }, |
85 | |||
86 | /* PSCs */ | ||
87 | { AU1550_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, | ||
88 | { AU1550_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, | ||
89 | { AU1550_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, | ||
90 | { AU1550_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, | ||
91 | { AU1550_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 }, | ||
92 | { AU1550_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 }, | ||
93 | { AU1550_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 }, | ||
94 | { AU1550_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 }, | ||
95 | |||
96 | { AU1550_DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */ | ||
97 | { AU1550_DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */ | ||
98 | |||
99 | /* MAC 0 */ | ||
100 | { AU1550_DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | ||
101 | { AU1550_DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | ||
102 | |||
103 | /* MAC 1 */ | ||
104 | { AU1550_DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | ||
105 | { AU1550_DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, | ||
106 | |||
107 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
108 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
109 | }; | ||
110 | 86 | ||
111 | static dbdev_tab_t au1200_dbdev_tab[] __initdata = { | 87 | /* PSC 0 */ |
112 | { AU1200_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, | 88 | { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, |
113 | { AU1200_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, | 89 | { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, |
114 | { AU1200_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 }, | ||
115 | { AU1200_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 }, | ||
116 | 90 | ||
117 | { AU1200_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, | 91 | /* PSC 1 */ |
118 | { AU1200_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, | 92 | { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, |
93 | { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 }, | ||
119 | 94 | ||
120 | { AU1200_DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 95 | /* PSC 2 */ |
121 | { AU1200_DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 96 | { DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 }, |
122 | { AU1200_DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 97 | { DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 }, |
123 | { AU1200_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
124 | 98 | ||
125 | { AU1200_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, | 99 | /* PSC 3 */ |
126 | { AU1200_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, | 100 | { DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 }, |
127 | { AU1200_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, | 101 | { DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 }, |
128 | { AU1200_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, | ||
129 | 102 | ||
130 | { AU1200_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, | 103 | { DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */ |
131 | { AU1200_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, | 104 | { DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */ |
132 | 105 | ||
133 | { AU1200_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, | 106 | /* MAC 0 */ |
134 | { AU1200_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, | 107 | { DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
135 | { AU1200_DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 108 | { DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, |
136 | { AU1200_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 }, | ||
137 | { AU1200_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 }, | ||
138 | { AU1200_DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
139 | 109 | ||
140 | { AU1200_DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, | 110 | /* MAC 1 */ |
141 | { AU1200_DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, | 111 | { DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
142 | { AU1200_DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, | 112 | { DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, |
143 | { AU1200_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
144 | 113 | ||
145 | { AU1200_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 114 | #endif /* CONFIG_SOC_AU1550 */ |
146 | 115 | ||
147 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 116 | #ifdef CONFIG_SOC_AU1200 |
148 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 117 | { DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, |
149 | }; | 118 | { DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, |
119 | { DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 }, | ||
120 | { DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 }, | ||
150 | 121 | ||
151 | static dbdev_tab_t au1300_dbdev_tab[] __initdata = { | 122 | { DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, |
152 | { AU1300_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x10100004, 0, 0 }, | 123 | { DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, |
153 | { AU1300_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x10100000, 0, 0 }, | ||
154 | { AU1300_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x10101004, 0, 0 }, | ||
155 | { AU1300_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x10101000, 0, 0 }, | ||
156 | { AU1300_DSCR_CMD0_UART2_TX, DEV_FLAGS_OUT, 0, 8, 0x10102004, 0, 0 }, | ||
157 | { AU1300_DSCR_CMD0_UART2_RX, DEV_FLAGS_IN, 0, 8, 0x10102000, 0, 0 }, | ||
158 | { AU1300_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x10103004, 0, 0 }, | ||
159 | { AU1300_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x10103000, 0, 0 }, | ||
160 | 124 | ||
161 | { AU1300_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, | 125 | { DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
162 | { AU1300_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, | 126 | { DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
163 | { AU1300_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 8, 8, 0x10601000, 0, 0 }, | 127 | { DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
164 | { AU1300_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 8, 8, 0x10601004, 0, 0 }, | 128 | { DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
165 | 129 | ||
166 | { AU1300_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, | 130 | { DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 }, |
167 | { AU1300_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, | 131 | { DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 }, |
132 | { DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 }, | ||
133 | { DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 }, | ||
168 | 134 | ||
169 | { AU1300_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0001c, 0, 0 }, | 135 | { DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 }, |
170 | { AU1300_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x10a0001c, 0, 0 }, | 136 | { DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 }, |
171 | { AU1300_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0101c, 0, 0 }, | ||
172 | { AU1300_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x10a0101c, 0, 0 }, | ||
173 | { AU1300_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0201c, 0, 0 }, | ||
174 | { AU1300_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 16, 0x10a0201c, 0, 0 }, | ||
175 | { AU1300_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0301c, 0, 0 }, | ||
176 | { AU1300_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 16, 0x10a0301c, 0, 0 }, | ||
177 | 137 | ||
178 | { AU1300_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 138 | { DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 }, |
179 | { AU1300_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, | 139 | { DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 }, |
140 | { DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
180 | 141 | ||
181 | { AU1300_DSCR_CMD0_SDMS_TX2, DEV_FLAGS_OUT, 4, 8, 0x10602000, 0, 0 }, | 142 | { DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 }, |
182 | { AU1300_DSCR_CMD0_SDMS_RX2, DEV_FLAGS_IN, 4, 8, 0x10602004, 0, 0 }, | 143 | { DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 }, |
144 | { DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
183 | 145 | ||
184 | { AU1300_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 146 | { DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 }, |
147 | { DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 }, | ||
148 | { DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 }, | ||
149 | { DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | ||
185 | 150 | ||
186 | { AU1300_DSCR_CMD0_UDMA, DEV_FLAGS_ANYUSE, 0, 32, 0x14001810, 0, 0 }, | 151 | { DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, |
187 | 152 | ||
188 | { AU1300_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, | 153 | #endif /* CONFIG_SOC_AU1200 */ |
189 | { AU1300_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, | ||
190 | 154 | ||
191 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 155 | { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
192 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, | 156 | { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, |
157 | |||
158 | /* Provide 16 user definable device types */ | ||
159 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
160 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
161 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
162 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
163 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
164 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
165 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
166 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
167 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
168 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
169 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
170 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
171 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
172 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
173 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
174 | { ~0, 0, 0, 0, 0, 0, 0 }, | ||
193 | }; | 175 | }; |
194 | 176 | ||
195 | /* 32 predefined plus 32 custom */ | 177 | #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) |
196 | #define DBDEV_TAB_SIZE 64 | 178 | |
197 | 179 | ||
198 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; | 180 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; |
199 | 181 | ||
@@ -1046,44 +1028,38 @@ static struct syscore_ops alchemy_dbdma_syscore_ops = { | |||
1046 | .resume = alchemy_dbdma_resume, | 1028 | .resume = alchemy_dbdma_resume, |
1047 | }; | 1029 | }; |
1048 | 1030 | ||
1049 | static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) | 1031 | static int __init au1xxx_dbdma_init(void) |
1050 | { | 1032 | { |
1051 | int ret; | 1033 | int irq_nr, ret; |
1052 | |||
1053 | dbdev_tab = kzalloc(sizeof(dbdev_tab_t) * DBDEV_TAB_SIZE, GFP_KERNEL); | ||
1054 | if (!dbdev_tab) | ||
1055 | return -ENOMEM; | ||
1056 | |||
1057 | memcpy(dbdev_tab, idtable, 32 * sizeof(dbdev_tab_t)); | ||
1058 | for (ret = 32; ret < DBDEV_TAB_SIZE; ret++) | ||
1059 | dbdev_tab[ret].dev_id = ~0; | ||
1060 | 1034 | ||
1061 | dbdma_gptr->ddma_config = 0; | 1035 | dbdma_gptr->ddma_config = 0; |
1062 | dbdma_gptr->ddma_throttle = 0; | 1036 | dbdma_gptr->ddma_throttle = 0; |
1063 | dbdma_gptr->ddma_inten = 0xffff; | 1037 | dbdma_gptr->ddma_inten = 0xffff; |
1064 | au_sync(); | 1038 | au_sync(); |
1065 | 1039 | ||
1066 | ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr); | 1040 | switch (alchemy_get_cputype()) { |
1041 | case ALCHEMY_CPU_AU1550: | ||
1042 | irq_nr = AU1550_DDMA_INT; | ||
1043 | break; | ||
1044 | case ALCHEMY_CPU_AU1200: | ||
1045 | irq_nr = AU1200_DDMA_INT; | ||
1046 | break; | ||
1047 | default: | ||
1048 | return -ENODEV; | ||
1049 | } | ||
1050 | |||
1051 | ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED, | ||
1052 | "Au1xxx dbdma", (void *)dbdma_gptr); | ||
1067 | if (ret) | 1053 | if (ret) |
1068 | printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); | 1054 | printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); |
1069 | else { | 1055 | else { |
1070 | dbdma_initialized = 1; | 1056 | dbdma_initialized = 1; |
1057 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); | ||
1071 | register_syscore_ops(&alchemy_dbdma_syscore_ops); | 1058 | register_syscore_ops(&alchemy_dbdma_syscore_ops); |
1072 | } | 1059 | } |
1073 | 1060 | ||
1074 | return ret; | 1061 | return ret; |
1075 | } | 1062 | } |
1063 | subsys_initcall(au1xxx_dbdma_init); | ||
1076 | 1064 | ||
1077 | static int __init alchemy_dbdma_init(void) | 1065 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ |
1078 | { | ||
1079 | switch (alchemy_get_cputype()) { | ||
1080 | case ALCHEMY_CPU_AU1550: | ||
1081 | return dbdma_setup(AU1550_DDMA_INT, au1550_dbdev_tab); | ||
1082 | case ALCHEMY_CPU_AU1200: | ||
1083 | return dbdma_setup(AU1200_DDMA_INT, au1200_dbdev_tab); | ||
1084 | case ALCHEMY_CPU_AU1300: | ||
1085 | return dbdma_setup(AU1300_DDMA_INT, au1300_dbdev_tab); | ||
1086 | } | ||
1087 | return 0; | ||
1088 | } | ||
1089 | subsys_initcall(alchemy_dbdma_init); | ||
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index 9b624e2c0fc..347980e79a8 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
41 | #include <asm/mach-au1x00/au1000_dma.h> | 41 | #include <asm/mach-au1x00/au1000_dma.h> |
42 | 42 | ||
43 | #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \ | ||
44 | defined(CONFIG_SOC_AU1100) | ||
43 | /* | 45 | /* |
44 | * A note on resource allocation: | 46 | * A note on resource allocation: |
45 | * | 47 | * |
@@ -86,12 +88,12 @@ static const struct dma_dev { | |||
86 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ | 88 | { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ |
87 | { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ | 89 | { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ |
88 | { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ | 90 | { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ |
89 | { AU1000_USB_UDC_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ | 91 | { AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ |
90 | { AU1000_USB_UDC_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ | 92 | { AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ |
91 | { AU1000_USB_UDC_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ | 93 | { AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ |
92 | { AU1000_USB_UDC_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ | 94 | { AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ |
93 | { AU1000_USB_UDC_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ | 95 | { AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ |
94 | { AU1000_USB_UDC_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ | 96 | { AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ |
95 | /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ | 97 | /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ |
96 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ | 98 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ |
97 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ | 99 | { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ |
@@ -168,13 +170,13 @@ int request_au1000_dma(int dev_id, const char *dev_str, | |||
168 | const struct dma_dev *dev; | 170 | const struct dma_dev *dev; |
169 | int i, ret; | 171 | int i, ret; |
170 | 172 | ||
171 | if (alchemy_get_cputype() == ALCHEMY_CPU_AU1100) { | 173 | #if defined(CONFIG_SOC_AU1100) |
172 | if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) | 174 | if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) |
173 | return -EINVAL; | 175 | return -EINVAL; |
174 | } else { | 176 | #else |
175 | if (dev_id < 0 || dev_id >= DMA_NUM_DEV) | 177 | if (dev_id < 0 || dev_id >= DMA_NUM_DEV) |
176 | return -EINVAL; | 178 | return -EINVAL; |
177 | } | 179 | #endif |
178 | 180 | ||
179 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) | 181 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) |
180 | if (au1000_dma_table[i].dev_id < 0) | 182 | if (au1000_dma_table[i].dev_id < 0) |
@@ -237,28 +239,30 @@ EXPORT_SYMBOL(free_au1000_dma); | |||
237 | 239 | ||
238 | static int __init au1000_dma_init(void) | 240 | static int __init au1000_dma_init(void) |
239 | { | 241 | { |
240 | int base, i; | 242 | int base, i; |
241 | 243 | ||
242 | switch (alchemy_get_cputype()) { | 244 | switch (alchemy_get_cputype()) { |
243 | case ALCHEMY_CPU_AU1000: | 245 | case ALCHEMY_CPU_AU1000: |
244 | base = AU1000_DMA_INT_BASE; | 246 | base = AU1000_DMA_INT_BASE; |
245 | break; | 247 | break; |
246 | case ALCHEMY_CPU_AU1500: | 248 | case ALCHEMY_CPU_AU1500: |
247 | base = AU1500_DMA_INT_BASE; | 249 | base = AU1500_DMA_INT_BASE; |
248 | break; | 250 | break; |
249 | case ALCHEMY_CPU_AU1100: | 251 | case ALCHEMY_CPU_AU1100: |
250 | base = AU1100_DMA_INT_BASE; | 252 | base = AU1100_DMA_INT_BASE; |
251 | break; | 253 | break; |
252 | default: | 254 | default: |
253 | goto out; | 255 | goto out; |
254 | } | 256 | } |
255 | 257 | ||
256 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) | 258 | for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) |
257 | au1000_dma_table[i].irq = base + i; | 259 | au1000_dma_table[i].irq = base + i; |
258 | 260 | ||
259 | printk(KERN_INFO "Alchemy DMA initialized\n"); | 261 | printk(KERN_INFO "Alchemy DMA initialized\n"); |
260 | 262 | ||
261 | out: | 263 | out: |
262 | return 0; | 264 | return 0; |
263 | } | 265 | } |
264 | arch_initcall(au1000_dma_init); | 266 | arch_initcall(au1000_dma_init); |
267 | |||
268 | #endif /* AU1000 AU1500 AU1100 */ | ||
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c deleted file mode 100644 index f1b50f0c01d..00000000000 --- a/arch/mips/alchemy/common/gpiolib.c +++ /dev/null | |||
@@ -1,175 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org> | ||
3 | * GPIOLIB support for Alchemy chips. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | * | ||
10 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
11 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
13 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
14 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
15 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
16 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
17 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
18 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
19 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along | ||
22 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
23 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
24 | * | ||
25 | * Notes : | ||
26 | * This file must ONLY be built when CONFIG_GPIOLIB=y and | ||
27 | * CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail! | ||
28 | * au1000 SoC have only one GPIO block : GPIO1 | ||
29 | * Au1100, Au15x0, Au12x0 have a second one : GPIO2 | ||
30 | * Au1300 is totally different: 1 block with up to 128 GPIOs | ||
31 | */ | ||
32 | |||
33 | #include <linux/init.h> | ||
34 | #include <linux/kernel.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/types.h> | ||
37 | #include <linux/gpio.h> | ||
38 | #include <asm/mach-au1x00/gpio-au1000.h> | ||
39 | #include <asm/mach-au1x00/gpio-au1300.h> | ||
40 | |||
41 | static int gpio2_get(struct gpio_chip *chip, unsigned offset) | ||
42 | { | ||
43 | return alchemy_gpio2_get_value(offset + ALCHEMY_GPIO2_BASE); | ||
44 | } | ||
45 | |||
46 | static void gpio2_set(struct gpio_chip *chip, unsigned offset, int value) | ||
47 | { | ||
48 | alchemy_gpio2_set_value(offset + ALCHEMY_GPIO2_BASE, value); | ||
49 | } | ||
50 | |||
51 | static int gpio2_direction_input(struct gpio_chip *chip, unsigned offset) | ||
52 | { | ||
53 | return alchemy_gpio2_direction_input(offset + ALCHEMY_GPIO2_BASE); | ||
54 | } | ||
55 | |||
56 | static int gpio2_direction_output(struct gpio_chip *chip, unsigned offset, | ||
57 | int value) | ||
58 | { | ||
59 | return alchemy_gpio2_direction_output(offset + ALCHEMY_GPIO2_BASE, | ||
60 | value); | ||
61 | } | ||
62 | |||
63 | static int gpio2_to_irq(struct gpio_chip *chip, unsigned offset) | ||
64 | { | ||
65 | return alchemy_gpio2_to_irq(offset + ALCHEMY_GPIO2_BASE); | ||
66 | } | ||
67 | |||
68 | |||
69 | static int gpio1_get(struct gpio_chip *chip, unsigned offset) | ||
70 | { | ||
71 | return alchemy_gpio1_get_value(offset + ALCHEMY_GPIO1_BASE); | ||
72 | } | ||
73 | |||
74 | static void gpio1_set(struct gpio_chip *chip, | ||
75 | unsigned offset, int value) | ||
76 | { | ||
77 | alchemy_gpio1_set_value(offset + ALCHEMY_GPIO1_BASE, value); | ||
78 | } | ||
79 | |||
80 | static int gpio1_direction_input(struct gpio_chip *chip, unsigned offset) | ||
81 | { | ||
82 | return alchemy_gpio1_direction_input(offset + ALCHEMY_GPIO1_BASE); | ||
83 | } | ||
84 | |||
85 | static int gpio1_direction_output(struct gpio_chip *chip, | ||
86 | unsigned offset, int value) | ||
87 | { | ||
88 | return alchemy_gpio1_direction_output(offset + ALCHEMY_GPIO1_BASE, | ||
89 | value); | ||
90 | } | ||
91 | |||
92 | static int gpio1_to_irq(struct gpio_chip *chip, unsigned offset) | ||
93 | { | ||
94 | return alchemy_gpio1_to_irq(offset + ALCHEMY_GPIO1_BASE); | ||
95 | } | ||
96 | |||
97 | struct gpio_chip alchemy_gpio_chip[] = { | ||
98 | [0] = { | ||
99 | .label = "alchemy-gpio1", | ||
100 | .direction_input = gpio1_direction_input, | ||
101 | .direction_output = gpio1_direction_output, | ||
102 | .get = gpio1_get, | ||
103 | .set = gpio1_set, | ||
104 | .to_irq = gpio1_to_irq, | ||
105 | .base = ALCHEMY_GPIO1_BASE, | ||
106 | .ngpio = ALCHEMY_GPIO1_NUM, | ||
107 | }, | ||
108 | [1] = { | ||
109 | .label = "alchemy-gpio2", | ||
110 | .direction_input = gpio2_direction_input, | ||
111 | .direction_output = gpio2_direction_output, | ||
112 | .get = gpio2_get, | ||
113 | .set = gpio2_set, | ||
114 | .to_irq = gpio2_to_irq, | ||
115 | .base = ALCHEMY_GPIO2_BASE, | ||
116 | .ngpio = ALCHEMY_GPIO2_NUM, | ||
117 | }, | ||
118 | }; | ||
119 | |||
120 | static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off) | ||
121 | { | ||
122 | return au1300_gpio_get_value(off + AU1300_GPIO_BASE); | ||
123 | } | ||
124 | |||
125 | static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v) | ||
126 | { | ||
127 | au1300_gpio_set_value(off + AU1300_GPIO_BASE, v); | ||
128 | } | ||
129 | |||
130 | static int alchemy_gpic_dir_input(struct gpio_chip *chip, unsigned int off) | ||
131 | { | ||
132 | return au1300_gpio_direction_input(off + AU1300_GPIO_BASE); | ||
133 | } | ||
134 | |||
135 | static int alchemy_gpic_dir_output(struct gpio_chip *chip, unsigned int off, | ||
136 | int v) | ||
137 | { | ||
138 | return au1300_gpio_direction_output(off + AU1300_GPIO_BASE, v); | ||
139 | } | ||
140 | |||
141 | static int alchemy_gpic_gpio_to_irq(struct gpio_chip *chip, unsigned int off) | ||
142 | { | ||
143 | return au1300_gpio_to_irq(off + AU1300_GPIO_BASE); | ||
144 | } | ||
145 | |||
146 | static struct gpio_chip au1300_gpiochip = { | ||
147 | .label = "alchemy-gpic", | ||
148 | .direction_input = alchemy_gpic_dir_input, | ||
149 | .direction_output = alchemy_gpic_dir_output, | ||
150 | .get = alchemy_gpic_get, | ||
151 | .set = alchemy_gpic_set, | ||
152 | .to_irq = alchemy_gpic_gpio_to_irq, | ||
153 | .base = AU1300_GPIO_BASE, | ||
154 | .ngpio = AU1300_GPIO_NUM, | ||
155 | }; | ||
156 | |||
157 | static int __init alchemy_gpiochip_init(void) | ||
158 | { | ||
159 | int ret = 0; | ||
160 | |||
161 | switch (alchemy_get_cputype()) { | ||
162 | case ALCHEMY_CPU_AU1000: | ||
163 | ret = gpiochip_add(&alchemy_gpio_chip[0]); | ||
164 | break; | ||
165 | case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200: | ||
166 | ret = gpiochip_add(&alchemy_gpio_chip[0]); | ||
167 | ret |= gpiochip_add(&alchemy_gpio_chip[1]); | ||
168 | break; | ||
169 | case ALCHEMY_CPU_AU1300: | ||
170 | ret = gpiochip_add(&au1300_gpiochip); | ||
171 | break; | ||
172 | } | ||
173 | return ret; | ||
174 | } | ||
175 | arch_initcall(alchemy_gpiochip_init); | ||
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 94fbcd19eb9..8b60ba0675e 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -25,15 +25,19 @@ | |||
25 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/export.h> | 28 | #include <linux/bitops.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/irq.h> | ||
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/syscore_ops.h> | 33 | #include <linux/syscore_ops.h> |
33 | 34 | ||
34 | #include <asm/irq_cpu.h> | 35 | #include <asm/irq_cpu.h> |
36 | #include <asm/mipsregs.h> | ||
35 | #include <asm/mach-au1x00/au1000.h> | 37 | #include <asm/mach-au1x00/au1000.h> |
36 | #include <asm/mach-au1x00/gpio-au1300.h> | 38 | #ifdef CONFIG_MIPS_PB1000 |
39 | #include <asm/mach-pb1x00/pb1000.h> | ||
40 | #endif | ||
37 | 41 | ||
38 | /* Interrupt Controller register offsets */ | 42 | /* Interrupt Controller register offsets */ |
39 | #define IC_CFG0RD 0x40 | 43 | #define IC_CFG0RD 0x40 |
@@ -65,17 +69,7 @@ | |||
65 | #define IC_FALLINGCLR 0x7C | 69 | #define IC_FALLINGCLR 0x7C |
66 | #define IC_TESTBIT 0x80 | 70 | #define IC_TESTBIT 0x80 |
67 | 71 | ||
68 | /* per-processor fixed function irqs */ | 72 | static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type); |
69 | struct alchemy_irqmap { | ||
70 | int irq; /* linux IRQ number */ | ||
71 | int type; /* IRQ_TYPE_ */ | ||
72 | int prio; /* irq priority, 0 highest, 3 lowest */ | ||
73 | int internal; /* GPIC: internal source (no ext. pin)? */ | ||
74 | }; | ||
75 | |||
76 | static int au1x_ic_settype(struct irq_data *d, unsigned int type); | ||
77 | static int au1300_gpic_settype(struct irq_data *d, unsigned int type); | ||
78 | |||
79 | 73 | ||
80 | /* NOTE on interrupt priorities: The original writers of this code said: | 74 | /* NOTE on interrupt priorities: The original writers of this code said: |
81 | * | 75 | * |
@@ -83,207 +77,176 @@ static int au1300_gpic_settype(struct irq_data *d, unsigned int type); | |||
83 | * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT) | 77 | * the USB devices-side packet complete interrupt (USB_DEV_REQ_INT) |
84 | * needs the highest priority. | 78 | * needs the highest priority. |
85 | */ | 79 | */ |
86 | struct alchemy_irqmap au1000_irqmap[] __initdata = { | 80 | |
87 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 81 | /* per-processor fixed function irqs */ |
88 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 82 | struct au1xxx_irqmap { |
89 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 83 | int im_irq; |
90 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 84 | int im_type; |
91 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 85 | int im_request; /* set 1 to get higher priority */ |
92 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
93 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
94 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
95 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
96 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
97 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
98 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
99 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
100 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
101 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
102 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
103 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
104 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
105 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
106 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
107 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
108 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, | ||
109 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
110 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
111 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, | ||
112 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
113 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | ||
114 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
115 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
116 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
117 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
118 | { -1, }, | ||
119 | }; | 86 | }; |
120 | 87 | ||
121 | struct alchemy_irqmap au1500_irqmap[] __initdata = { | 88 | struct au1xxx_irqmap au1000_irqmap[] __initdata = { |
122 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 89 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
123 | { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 90 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
124 | { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 91 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
125 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 92 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
126 | { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 93 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
127 | { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 94 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
128 | { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 95 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, |
129 | { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 96 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, |
130 | { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 97 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, |
131 | { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 98 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, |
132 | { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 99 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, |
133 | { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 100 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, |
134 | { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 101 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, |
135 | { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 102 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, |
136 | { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 103 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
137 | { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 104 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
138 | { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 105 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
139 | { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 106 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
140 | { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 107 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
141 | { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 108 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
142 | { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 109 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
143 | { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, | 110 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
144 | { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, | 111 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
145 | { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 112 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
146 | { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 113 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
147 | { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 114 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
148 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 115 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
149 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 116 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
150 | { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 117 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
118 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
119 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
151 | { -1, }, | 120 | { -1, }, |
152 | }; | 121 | }; |
153 | 122 | ||
154 | struct alchemy_irqmap au1100_irqmap[] __initdata = { | 123 | struct au1xxx_irqmap au1500_irqmap[] __initdata = { |
155 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 124 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
156 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 125 | { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, |
157 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 126 | { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, |
158 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 127 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
159 | { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 128 | { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, |
160 | { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 129 | { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, |
161 | { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 130 | { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, |
162 | { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 131 | { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, |
163 | { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 132 | { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, |
164 | { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 133 | { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, |
165 | { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 134 | { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, |
166 | { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 135 | { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, |
167 | { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 136 | { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, |
168 | { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 137 | { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, |
169 | { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 138 | { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
170 | { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 139 | { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
171 | { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 140 | { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
172 | { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 141 | { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
173 | { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 142 | { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
174 | { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 143 | { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
175 | { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 144 | { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
176 | { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, | 145 | { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
177 | { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 146 | { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
178 | { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 147 | { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
179 | { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, | 148 | { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
180 | { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 149 | { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
181 | { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 150 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
182 | { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 151 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
183 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 152 | { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
184 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | ||
185 | { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | ||
186 | { -1, }, | 153 | { -1, }, |
187 | }; | 154 | }; |
188 | 155 | ||
189 | struct alchemy_irqmap au1550_irqmap[] __initdata = { | 156 | struct au1xxx_irqmap au1100_irqmap[] __initdata = { |
190 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 157 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
191 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 158 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
192 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 159 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
193 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 160 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
194 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 161 | { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
195 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 162 | { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
196 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 163 | { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, |
197 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 164 | { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, |
198 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 165 | { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, |
199 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 166 | { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, |
200 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 167 | { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, |
201 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 168 | { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, |
202 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 169 | { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, |
203 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 170 | { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, |
204 | { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 171 | { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
205 | { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 172 | { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
206 | { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 173 | { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
207 | { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 174 | { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
208 | { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 175 | { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
209 | { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 176 | { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
210 | { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 177 | { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
211 | { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, | 178 | { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
212 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 179 | { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
213 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 }, | 180 | { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
214 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 181 | { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, |
215 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 }, | 182 | { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
216 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 183 | { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
217 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 184 | { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
185 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
186 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
187 | { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
218 | { -1, }, | 188 | { -1, }, |
219 | }; | 189 | }; |
220 | 190 | ||
221 | struct alchemy_irqmap au1200_irqmap[] __initdata = { | 191 | struct au1xxx_irqmap au1550_irqmap[] __initdata = { |
222 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 192 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
223 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 193 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, |
224 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 194 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, |
225 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 195 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
226 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 196 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
227 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 197 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, |
228 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 198 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, |
229 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 199 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, |
230 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 200 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
231 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 201 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
232 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 202 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
233 | { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 203 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
234 | { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 204 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
235 | { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 205 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
236 | { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 206 | { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
237 | { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 207 | { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
238 | { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 208 | { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
239 | { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 209 | { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
240 | { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 }, | 210 | { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
241 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 }, | 211 | { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
242 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 212 | { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
243 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 213 | { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
244 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 }, | 214 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
215 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 }, | ||
216 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
217 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
218 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
219 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
245 | { -1, }, | 220 | { -1, }, |
246 | }; | 221 | }; |
247 | 222 | ||
248 | static struct alchemy_irqmap au1300_irqmap[] __initdata = { | 223 | struct au1xxx_irqmap au1200_irqmap[] __initdata = { |
249 | /* multifunction: gpio pin or device */ | 224 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
250 | { AU1300_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 225 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
251 | { AU1300_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 226 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
252 | { AU1300_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 227 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
253 | { AU1300_SD1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 228 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
254 | { AU1300_SD2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 229 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
255 | { AU1300_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 230 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
256 | { AU1300_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 231 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
257 | { AU1300_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 232 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
258 | { AU1300_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 233 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
259 | { AU1300_NAND_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, }, | 234 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
260 | /* au1300 internal */ | 235 | { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
261 | { AU1300_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | 236 | { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
262 | { AU1300_MMU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | 237 | { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
263 | { AU1300_MPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | 238 | { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
264 | { AU1300_GPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | 239 | { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
265 | { AU1300_UDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | 240 | { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
266 | { AU1300_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 241 | { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
267 | { AU1300_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 242 | { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, |
268 | { AU1300_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 243 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, |
269 | { AU1300_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 244 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
270 | { AU1300_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 245 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
271 | { AU1300_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 246 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
272 | { AU1300_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | 247 | { -1, }, |
273 | { AU1300_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 1, }, | ||
274 | { AU1300_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
275 | { AU1300_SD0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
276 | { AU1300_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
277 | { AU1300_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
278 | { AU1300_BSA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
279 | { AU1300_MPE_INT, IRQ_TYPE_EDGE_RISING, 1, 1, }, | ||
280 | { AU1300_ITE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
281 | { AU1300_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
282 | { AU1300_CIM_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, }, | ||
283 | { -1, }, /* terminator */ | ||
284 | }; | 248 | }; |
285 | 249 | ||
286 | /******************************************************************************/ | ||
287 | 250 | ||
288 | static void au1x_ic0_unmask(struct irq_data *d) | 251 | static void au1x_ic0_unmask(struct irq_data *d) |
289 | { | 252 | { |
@@ -302,6 +265,14 @@ static void au1x_ic1_unmask(struct irq_data *d) | |||
302 | 265 | ||
303 | __raw_writel(1 << bit, base + IC_MASKSET); | 266 | __raw_writel(1 << bit, base + IC_MASKSET); |
304 | __raw_writel(1 << bit, base + IC_WAKESET); | 267 | __raw_writel(1 << bit, base + IC_WAKESET); |
268 | |||
269 | /* very hacky. does the pb1000 cpld auto-disable this int? | ||
270 | * nowhere in the current kernel sources is it disabled. --mlau | ||
271 | */ | ||
272 | #if defined(CONFIG_MIPS_PB1000) | ||
273 | if (d->irq == AU1000_GPIO15_INT) | ||
274 | __raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */ | ||
275 | #endif | ||
305 | wmb(); | 276 | wmb(); |
306 | } | 277 | } |
307 | 278 | ||
@@ -499,219 +470,40 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type) | |||
499 | return ret; | 470 | return ret; |
500 | } | 471 | } |
501 | 472 | ||
502 | /******************************************************************************/ | 473 | asmlinkage void plat_irq_dispatch(void) |
503 | |||
504 | /* | ||
505 | * au1300_gpic_chgcfg - change PIN configuration. | ||
506 | * @gpio: pin to change (0-based GPIO number from datasheet). | ||
507 | * @clr: clear all bits set in 'clr'. | ||
508 | * @set: set these bits. | ||
509 | * | ||
510 | * modifies a pins' configuration register, bits set in @clr will | ||
511 | * be cleared in the register, bits in @set will be set. | ||
512 | */ | ||
513 | static inline void au1300_gpic_chgcfg(unsigned int gpio, | ||
514 | unsigned long clr, | ||
515 | unsigned long set) | ||
516 | { | ||
517 | void __iomem *r = AU1300_GPIC_ADDR; | ||
518 | unsigned long l; | ||
519 | |||
520 | r += gpio * 4; /* offset into pin config array */ | ||
521 | l = __raw_readl(r + AU1300_GPIC_PINCFG); | ||
522 | l &= ~clr; | ||
523 | l |= set; | ||
524 | __raw_writel(l, r + AU1300_GPIC_PINCFG); | ||
525 | wmb(); | ||
526 | } | ||
527 | |||
528 | /* | ||
529 | * au1300_pinfunc_to_gpio - assign a pin as GPIO input (GPIO ctrl). | ||
530 | * @pin: pin (0-based GPIO number from datasheet). | ||
531 | * | ||
532 | * Assigns a GPIO pin to the GPIO controller, so its level can either | ||
533 | * be read or set through the generic GPIO functions. | ||
534 | * If you need a GPOUT, use au1300_gpio_set_value(pin, 0/1). | ||
535 | * REVISIT: is this function really necessary? | ||
536 | */ | ||
537 | void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio) | ||
538 | { | ||
539 | au1300_gpio_direction_input(gpio + AU1300_GPIO_BASE); | ||
540 | } | ||
541 | EXPORT_SYMBOL_GPL(au1300_pinfunc_to_gpio); | ||
542 | |||
543 | /* | ||
544 | * au1300_pinfunc_to_dev - assign a pin to the device function. | ||
545 | * @pin: pin (0-based GPIO number from datasheet). | ||
546 | * | ||
547 | * Assigns a GPIO pin to its associated device function; the pin will be | ||
548 | * driven by the device and not through GPIO functions. | ||
549 | */ | ||
550 | void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio) | ||
551 | { | ||
552 | void __iomem *r = AU1300_GPIC_ADDR; | ||
553 | unsigned long bit; | ||
554 | |||
555 | r += GPIC_GPIO_BANKOFF(gpio); | ||
556 | bit = GPIC_GPIO_TO_BIT(gpio); | ||
557 | __raw_writel(bit, r + AU1300_GPIC_DEVSEL); | ||
558 | wmb(); | ||
559 | } | ||
560 | EXPORT_SYMBOL_GPL(au1300_pinfunc_to_dev); | ||
561 | |||
562 | /* | ||
563 | * au1300_set_irq_priority - set internal priority of IRQ. | ||
564 | * @irq: irq to set priority (linux irq number). | ||
565 | * @p: priority (0 = highest, 3 = lowest). | ||
566 | */ | ||
567 | void au1300_set_irq_priority(unsigned int irq, int p) | ||
568 | { | ||
569 | irq -= ALCHEMY_GPIC_INT_BASE; | ||
570 | au1300_gpic_chgcfg(irq, GPIC_CFG_IL_MASK, GPIC_CFG_IL_SET(p)); | ||
571 | } | ||
572 | EXPORT_SYMBOL_GPL(au1300_set_irq_priority); | ||
573 | |||
574 | /* | ||
575 | * au1300_set_dbdma_gpio - assign a gpio to one of the DBDMA triggers. | ||
576 | * @dchan: dbdma trigger select (0, 1). | ||
577 | * @gpio: pin to assign as trigger. | ||
578 | * | ||
579 | * DBDMA controller has 2 external trigger sources; this function | ||
580 | * assigns a GPIO to the selected trigger. | ||
581 | */ | ||
582 | void au1300_set_dbdma_gpio(int dchan, unsigned int gpio) | ||
583 | { | ||
584 | unsigned long r; | ||
585 | |||
586 | if ((dchan >= 0) && (dchan <= 1)) { | ||
587 | r = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL); | ||
588 | r &= ~(0xff << (8 * dchan)); | ||
589 | r |= (gpio & 0x7f) << (8 * dchan); | ||
590 | __raw_writel(r, AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL); | ||
591 | wmb(); | ||
592 | } | ||
593 | } | ||
594 | |||
595 | static inline void gpic_pin_set_idlewake(unsigned int gpio, int allow) | ||
596 | { | ||
597 | au1300_gpic_chgcfg(gpio, GPIC_CFG_IDLEWAKE, | ||
598 | allow ? GPIC_CFG_IDLEWAKE : 0); | ||
599 | } | ||
600 | |||
601 | static void au1300_gpic_mask(struct irq_data *d) | ||
602 | { | ||
603 | void __iomem *r = AU1300_GPIC_ADDR; | ||
604 | unsigned long bit, irq = d->irq; | ||
605 | |||
606 | irq -= ALCHEMY_GPIC_INT_BASE; | ||
607 | r += GPIC_GPIO_BANKOFF(irq); | ||
608 | bit = GPIC_GPIO_TO_BIT(irq); | ||
609 | __raw_writel(bit, r + AU1300_GPIC_IDIS); | ||
610 | wmb(); | ||
611 | |||
612 | gpic_pin_set_idlewake(irq, 0); | ||
613 | } | ||
614 | |||
615 | static void au1300_gpic_unmask(struct irq_data *d) | ||
616 | { | ||
617 | void __iomem *r = AU1300_GPIC_ADDR; | ||
618 | unsigned long bit, irq = d->irq; | ||
619 | |||
620 | irq -= ALCHEMY_GPIC_INT_BASE; | ||
621 | |||
622 | gpic_pin_set_idlewake(irq, 1); | ||
623 | |||
624 | r += GPIC_GPIO_BANKOFF(irq); | ||
625 | bit = GPIC_GPIO_TO_BIT(irq); | ||
626 | __raw_writel(bit, r + AU1300_GPIC_IEN); | ||
627 | wmb(); | ||
628 | } | ||
629 | |||
630 | static void au1300_gpic_maskack(struct irq_data *d) | ||
631 | { | ||
632 | void __iomem *r = AU1300_GPIC_ADDR; | ||
633 | unsigned long bit, irq = d->irq; | ||
634 | |||
635 | irq -= ALCHEMY_GPIC_INT_BASE; | ||
636 | r += GPIC_GPIO_BANKOFF(irq); | ||
637 | bit = GPIC_GPIO_TO_BIT(irq); | ||
638 | __raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */ | ||
639 | __raw_writel(bit, r + AU1300_GPIC_IDIS); /* mask */ | ||
640 | wmb(); | ||
641 | |||
642 | gpic_pin_set_idlewake(irq, 0); | ||
643 | } | ||
644 | |||
645 | static void au1300_gpic_ack(struct irq_data *d) | ||
646 | { | ||
647 | void __iomem *r = AU1300_GPIC_ADDR; | ||
648 | unsigned long bit, irq = d->irq; | ||
649 | |||
650 | irq -= ALCHEMY_GPIC_INT_BASE; | ||
651 | r += GPIC_GPIO_BANKOFF(irq); | ||
652 | bit = GPIC_GPIO_TO_BIT(irq); | ||
653 | __raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */ | ||
654 | wmb(); | ||
655 | } | ||
656 | |||
657 | static struct irq_chip au1300_gpic = { | ||
658 | .name = "GPIOINT", | ||
659 | .irq_ack = au1300_gpic_ack, | ||
660 | .irq_mask = au1300_gpic_mask, | ||
661 | .irq_mask_ack = au1300_gpic_maskack, | ||
662 | .irq_unmask = au1300_gpic_unmask, | ||
663 | .irq_set_type = au1300_gpic_settype, | ||
664 | }; | ||
665 | |||
666 | static int au1300_gpic_settype(struct irq_data *d, unsigned int type) | ||
667 | { | 474 | { |
668 | unsigned long s; | 475 | unsigned int pending = read_c0_status() & read_c0_cause(); |
669 | unsigned char *name = NULL; | 476 | unsigned long s, off; |
670 | irq_flow_handler_t hdl = NULL; | 477 | |
671 | 478 | if (pending & CAUSEF_IP7) { | |
672 | switch (type) { | 479 | off = MIPS_CPU_IRQ_BASE + 7; |
673 | case IRQ_TYPE_LEVEL_HIGH: | 480 | goto handle; |
674 | s = GPIC_CFG_IC_LEVEL_HIGH; | 481 | } else if (pending & CAUSEF_IP2) { |
675 | name = "high"; | 482 | s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT; |
676 | hdl = handle_level_irq; | 483 | off = AU1000_INTC0_INT_BASE; |
677 | break; | 484 | } else if (pending & CAUSEF_IP3) { |
678 | case IRQ_TYPE_LEVEL_LOW: | 485 | s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT; |
679 | s = GPIC_CFG_IC_LEVEL_LOW; | 486 | off = AU1000_INTC0_INT_BASE; |
680 | name = "low"; | 487 | } else if (pending & CAUSEF_IP4) { |
681 | hdl = handle_level_irq; | 488 | s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT; |
682 | break; | 489 | off = AU1000_INTC1_INT_BASE; |
683 | case IRQ_TYPE_EDGE_RISING: | 490 | } else if (pending & CAUSEF_IP5) { |
684 | s = GPIC_CFG_IC_EDGE_RISE; | 491 | s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT; |
685 | name = "posedge"; | 492 | off = AU1000_INTC1_INT_BASE; |
686 | hdl = handle_edge_irq; | 493 | } else |
687 | break; | 494 | goto spurious; |
688 | case IRQ_TYPE_EDGE_FALLING: | 495 | |
689 | s = GPIC_CFG_IC_EDGE_FALL; | 496 | s = __raw_readl((void __iomem *)s); |
690 | name = "negedge"; | 497 | if (unlikely(!s)) { |
691 | hdl = handle_edge_irq; | 498 | spurious: |
692 | break; | 499 | spurious_interrupt(); |
693 | case IRQ_TYPE_EDGE_BOTH: | 500 | return; |
694 | s = GPIC_CFG_IC_EDGE_BOTH; | ||
695 | name = "bothedge"; | ||
696 | hdl = handle_edge_irq; | ||
697 | break; | ||
698 | case IRQ_TYPE_NONE: | ||
699 | s = GPIC_CFG_IC_OFF; | ||
700 | name = "disabled"; | ||
701 | hdl = handle_level_irq; | ||
702 | break; | ||
703 | default: | ||
704 | return -EINVAL; | ||
705 | } | 501 | } |
706 | 502 | off += __ffs(s); | |
707 | __irq_set_chip_handler_name_locked(d->irq, &au1300_gpic, hdl, name); | 503 | handle: |
708 | 504 | do_IRQ(off); | |
709 | au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s); | ||
710 | |||
711 | return 0; | ||
712 | } | 505 | } |
713 | 506 | ||
714 | /******************************************************************************/ | ||
715 | 507 | ||
716 | static inline void ic_init(void __iomem *base) | 508 | static inline void ic_init(void __iomem *base) |
717 | { | 509 | { |
@@ -729,159 +521,13 @@ static inline void ic_init(void __iomem *base) | |||
729 | wmb(); | 521 | wmb(); |
730 | } | 522 | } |
731 | 523 | ||
732 | static unsigned long alchemy_gpic_pmdata[ALCHEMY_GPIC_INT_NUM + 6]; | 524 | static void __init au1000_init_irq(struct au1xxx_irqmap *map) |
733 | |||
734 | static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d) | ||
735 | { | ||
736 | d[0] = __raw_readl(base + IC_CFG0RD); | ||
737 | d[1] = __raw_readl(base + IC_CFG1RD); | ||
738 | d[2] = __raw_readl(base + IC_CFG2RD); | ||
739 | d[3] = __raw_readl(base + IC_SRCRD); | ||
740 | d[4] = __raw_readl(base + IC_ASSIGNRD); | ||
741 | d[5] = __raw_readl(base + IC_WAKERD); | ||
742 | d[6] = __raw_readl(base + IC_MASKRD); | ||
743 | ic_init(base); /* shut it up too while at it */ | ||
744 | } | ||
745 | |||
746 | static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d) | ||
747 | { | ||
748 | ic_init(base); | ||
749 | |||
750 | __raw_writel(d[0], base + IC_CFG0SET); | ||
751 | __raw_writel(d[1], base + IC_CFG1SET); | ||
752 | __raw_writel(d[2], base + IC_CFG2SET); | ||
753 | __raw_writel(d[3], base + IC_SRCSET); | ||
754 | __raw_writel(d[4], base + IC_ASSIGNSET); | ||
755 | __raw_writel(d[5], base + IC_WAKESET); | ||
756 | wmb(); | ||
757 | |||
758 | __raw_writel(d[6], base + IC_MASKSET); | ||
759 | wmb(); | ||
760 | } | ||
761 | |||
762 | static int alchemy_ic_suspend(void) | ||
763 | { | ||
764 | alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), | ||
765 | alchemy_gpic_pmdata); | ||
766 | alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), | ||
767 | &alchemy_gpic_pmdata[7]); | ||
768 | return 0; | ||
769 | } | ||
770 | |||
771 | static void alchemy_ic_resume(void) | ||
772 | { | ||
773 | alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), | ||
774 | &alchemy_gpic_pmdata[7]); | ||
775 | alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), | ||
776 | alchemy_gpic_pmdata); | ||
777 | } | ||
778 | |||
779 | static int alchemy_gpic_suspend(void) | ||
780 | { | ||
781 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); | ||
782 | int i; | ||
783 | |||
784 | /* save 4 interrupt mask status registers */ | ||
785 | alchemy_gpic_pmdata[0] = __raw_readl(base + AU1300_GPIC_IEN + 0x0); | ||
786 | alchemy_gpic_pmdata[1] = __raw_readl(base + AU1300_GPIC_IEN + 0x4); | ||
787 | alchemy_gpic_pmdata[2] = __raw_readl(base + AU1300_GPIC_IEN + 0x8); | ||
788 | alchemy_gpic_pmdata[3] = __raw_readl(base + AU1300_GPIC_IEN + 0xc); | ||
789 | |||
790 | /* save misc register(s) */ | ||
791 | alchemy_gpic_pmdata[4] = __raw_readl(base + AU1300_GPIC_DMASEL); | ||
792 | |||
793 | /* molto silenzioso */ | ||
794 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0); | ||
795 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4); | ||
796 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8); | ||
797 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc); | ||
798 | wmb(); | ||
799 | |||
800 | /* save pin/int-type configuration */ | ||
801 | base += AU1300_GPIC_PINCFG; | ||
802 | for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++) | ||
803 | alchemy_gpic_pmdata[i + 5] = __raw_readl(base + (i << 2)); | ||
804 | |||
805 | wmb(); | ||
806 | |||
807 | return 0; | ||
808 | } | ||
809 | |||
810 | static void alchemy_gpic_resume(void) | ||
811 | { | ||
812 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); | ||
813 | int i; | ||
814 | |||
815 | /* disable all first */ | ||
816 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0); | ||
817 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4); | ||
818 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8); | ||
819 | __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc); | ||
820 | wmb(); | ||
821 | |||
822 | /* restore pin/int-type configurations */ | ||
823 | base += AU1300_GPIC_PINCFG; | ||
824 | for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++) | ||
825 | __raw_writel(alchemy_gpic_pmdata[i + 5], base + (i << 2)); | ||
826 | wmb(); | ||
827 | |||
828 | /* restore misc register(s) */ | ||
829 | base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR); | ||
830 | __raw_writel(alchemy_gpic_pmdata[4], base + AU1300_GPIC_DMASEL); | ||
831 | wmb(); | ||
832 | |||
833 | /* finally restore masks */ | ||
834 | __raw_writel(alchemy_gpic_pmdata[0], base + AU1300_GPIC_IEN + 0x0); | ||
835 | __raw_writel(alchemy_gpic_pmdata[1], base + AU1300_GPIC_IEN + 0x4); | ||
836 | __raw_writel(alchemy_gpic_pmdata[2], base + AU1300_GPIC_IEN + 0x8); | ||
837 | __raw_writel(alchemy_gpic_pmdata[3], base + AU1300_GPIC_IEN + 0xc); | ||
838 | wmb(); | ||
839 | } | ||
840 | |||
841 | static struct syscore_ops alchemy_ic_pmops = { | ||
842 | .suspend = alchemy_ic_suspend, | ||
843 | .resume = alchemy_ic_resume, | ||
844 | }; | ||
845 | |||
846 | static struct syscore_ops alchemy_gpic_pmops = { | ||
847 | .suspend = alchemy_gpic_suspend, | ||
848 | .resume = alchemy_gpic_resume, | ||
849 | }; | ||
850 | |||
851 | /******************************************************************************/ | ||
852 | |||
853 | /* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */ | ||
854 | #define DISP(name, base, addr) \ | ||
855 | static void au1000_##name##_dispatch(unsigned int irq, struct irq_desc *d) \ | ||
856 | { \ | ||
857 | unsigned long r = __raw_readl((void __iomem *)KSEG1ADDR(addr)); \ | ||
858 | if (likely(r)) \ | ||
859 | generic_handle_irq(base + __ffs(r)); \ | ||
860 | else \ | ||
861 | spurious_interrupt(); \ | ||
862 | } | ||
863 | |||
864 | DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT) | ||
865 | DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT) | ||
866 | DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT) | ||
867 | DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT) | ||
868 | |||
869 | static void alchemy_gpic_dispatch(unsigned int irq, struct irq_desc *d) | ||
870 | { | ||
871 | int i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC); | ||
872 | generic_handle_irq(ALCHEMY_GPIC_INT_BASE + i); | ||
873 | } | ||
874 | |||
875 | /******************************************************************************/ | ||
876 | |||
877 | static void __init au1000_init_irq(struct alchemy_irqmap *map) | ||
878 | { | 525 | { |
879 | unsigned int bit, irq_nr; | 526 | unsigned int bit, irq_nr; |
880 | void __iomem *base; | 527 | void __iomem *base; |
881 | 528 | ||
882 | ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR)); | 529 | ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR)); |
883 | ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR)); | 530 | ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR)); |
884 | register_syscore_ops(&alchemy_ic_pmops); | ||
885 | mips_cpu_irq_init(); | 531 | mips_cpu_irq_init(); |
886 | 532 | ||
887 | /* register all 64 possible IC0+IC1 irq sources as type "none". | 533 | /* register all 64 possible IC0+IC1 irq sources as type "none". |
@@ -898,8 +544,8 @@ static void __init au1000_init_irq(struct alchemy_irqmap *map) | |||
898 | /* | 544 | /* |
899 | * Initialize IC0, which is fixed per processor. | 545 | * Initialize IC0, which is fixed per processor. |
900 | */ | 546 | */ |
901 | while (map->irq != -1) { | 547 | while (map->im_irq != -1) { |
902 | irq_nr = map->irq; | 548 | irq_nr = map->im_irq; |
903 | 549 | ||
904 | if (irq_nr >= AU1000_INTC1_INT_BASE) { | 550 | if (irq_nr >= AU1000_INTC1_INT_BASE) { |
905 | bit = irq_nr - AU1000_INTC1_INT_BASE; | 551 | bit = irq_nr - AU1000_INTC1_INT_BASE; |
@@ -908,61 +554,16 @@ static void __init au1000_init_irq(struct alchemy_irqmap *map) | |||
908 | bit = irq_nr - AU1000_INTC0_INT_BASE; | 554 | bit = irq_nr - AU1000_INTC0_INT_BASE; |
909 | base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); | 555 | base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR); |
910 | } | 556 | } |
911 | if (map->prio == 0) | 557 | if (map->im_request) |
912 | __raw_writel(1 << bit, base + IC_ASSIGNSET); | 558 | __raw_writel(1 << bit, base + IC_ASSIGNSET); |
913 | 559 | ||
914 | au1x_ic_settype(irq_get_irq_data(irq_nr), map->type); | 560 | au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type); |
915 | ++map; | 561 | ++map; |
916 | } | 562 | } |
917 | 563 | ||
918 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, au1000_ic0r0_dispatch); | 564 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); |
919 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, au1000_ic0r1_dispatch); | ||
920 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, au1000_ic1r0_dispatch); | ||
921 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, au1000_ic1r1_dispatch); | ||
922 | } | ||
923 | |||
924 | static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints) | ||
925 | { | ||
926 | int i; | ||
927 | void __iomem *bank_base; | ||
928 | |||
929 | register_syscore_ops(&alchemy_gpic_pmops); | ||
930 | mips_cpu_irq_init(); | ||
931 | |||
932 | /* disable & ack all possible interrupt sources */ | ||
933 | for (i = 0; i < 4; i++) { | ||
934 | bank_base = AU1300_GPIC_ADDR + (i * 4); | ||
935 | __raw_writel(~0UL, bank_base + AU1300_GPIC_IDIS); | ||
936 | wmb(); | ||
937 | __raw_writel(~0UL, bank_base + AU1300_GPIC_IPEND); | ||
938 | wmb(); | ||
939 | } | ||
940 | |||
941 | /* register an irq_chip for them, with 2nd highest priority */ | ||
942 | for (i = ALCHEMY_GPIC_INT_BASE; i <= ALCHEMY_GPIC_INT_LAST; i++) { | ||
943 | au1300_set_irq_priority(i, 1); | ||
944 | au1300_gpic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE); | ||
945 | } | ||
946 | |||
947 | /* setup known on-chip sources */ | ||
948 | while ((i = dints->irq) != -1) { | ||
949 | au1300_gpic_settype(irq_get_irq_data(i), dints->type); | ||
950 | au1300_set_irq_priority(i, dints->prio); | ||
951 | |||
952 | if (dints->internal) | ||
953 | au1300_pinfunc_to_dev(i - ALCHEMY_GPIC_INT_BASE); | ||
954 | |||
955 | dints++; | ||
956 | } | ||
957 | |||
958 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, alchemy_gpic_dispatch); | ||
959 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, alchemy_gpic_dispatch); | ||
960 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, alchemy_gpic_dispatch); | ||
961 | irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, alchemy_gpic_dispatch); | ||
962 | } | 565 | } |
963 | 566 | ||
964 | /******************************************************************************/ | ||
965 | |||
966 | void __init arch_init_irq(void) | 567 | void __init arch_init_irq(void) |
967 | { | 568 | { |
968 | switch (alchemy_get_cputype()) { | 569 | switch (alchemy_get_cputype()) { |
@@ -981,17 +582,65 @@ void __init arch_init_irq(void) | |||
981 | case ALCHEMY_CPU_AU1200: | 582 | case ALCHEMY_CPU_AU1200: |
982 | au1000_init_irq(au1200_irqmap); | 583 | au1000_init_irq(au1200_irqmap); |
983 | break; | 584 | break; |
984 | case ALCHEMY_CPU_AU1300: | ||
985 | alchemy_gpic_init_irq(au1300_irqmap); | ||
986 | break; | ||
987 | default: | ||
988 | pr_err("unknown Alchemy IRQ core\n"); | ||
989 | break; | ||
990 | } | 585 | } |
991 | } | 586 | } |
992 | 587 | ||
993 | asmlinkage void plat_irq_dispatch(void) | 588 | |
589 | static unsigned long alchemy_ic_pmdata[7 * 2]; | ||
590 | |||
591 | static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d) | ||
994 | { | 592 | { |
995 | unsigned long r = (read_c0_status() & read_c0_cause()) >> 8; | 593 | d[0] = __raw_readl(base + IC_CFG0RD); |
996 | do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff)); | 594 | d[1] = __raw_readl(base + IC_CFG1RD); |
595 | d[2] = __raw_readl(base + IC_CFG2RD); | ||
596 | d[3] = __raw_readl(base + IC_SRCRD); | ||
597 | d[4] = __raw_readl(base + IC_ASSIGNRD); | ||
598 | d[5] = __raw_readl(base + IC_WAKERD); | ||
599 | d[6] = __raw_readl(base + IC_MASKRD); | ||
600 | ic_init(base); /* shut it up too while at it */ | ||
601 | } | ||
602 | |||
603 | static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d) | ||
604 | { | ||
605 | ic_init(base); | ||
606 | |||
607 | __raw_writel(d[0], base + IC_CFG0SET); | ||
608 | __raw_writel(d[1], base + IC_CFG1SET); | ||
609 | __raw_writel(d[2], base + IC_CFG2SET); | ||
610 | __raw_writel(d[3], base + IC_SRCSET); | ||
611 | __raw_writel(d[4], base + IC_ASSIGNSET); | ||
612 | __raw_writel(d[5], base + IC_WAKESET); | ||
613 | wmb(); | ||
614 | |||
615 | __raw_writel(d[6], base + IC_MASKSET); | ||
616 | wmb(); | ||
617 | } | ||
618 | |||
619 | static int alchemy_ic_suspend(void) | ||
620 | { | ||
621 | alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), | ||
622 | alchemy_ic_pmdata); | ||
623 | alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), | ||
624 | &alchemy_ic_pmdata[7]); | ||
625 | return 0; | ||
626 | } | ||
627 | |||
628 | static void alchemy_ic_resume(void) | ||
629 | { | ||
630 | alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR), | ||
631 | &alchemy_ic_pmdata[7]); | ||
632 | alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR), | ||
633 | alchemy_ic_pmdata); | ||
634 | } | ||
635 | |||
636 | static struct syscore_ops alchemy_ic_syscore_ops = { | ||
637 | .suspend = alchemy_ic_suspend, | ||
638 | .resume = alchemy_ic_resume, | ||
639 | }; | ||
640 | |||
641 | static int __init alchemy_ic_pm_init(void) | ||
642 | { | ||
643 | register_syscore_ops(&alchemy_ic_syscore_ops); | ||
644 | return 0; | ||
997 | } | 645 | } |
646 | device_initcall(alchemy_ic_pm_init); | ||
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 7af941d8e71..f72c48d4804 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -17,10 +17,8 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/serial_8250.h> | 18 | #include <linux/serial_8250.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/usb/ehci_pdriver.h> | ||
21 | #include <linux/usb/ohci_pdriver.h> | ||
22 | 20 | ||
23 | #include <asm/mach-au1x00/au1000.h> | 21 | #include <asm/mach-au1x00/au1xxx.h> |
24 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 22 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
25 | #include <asm/mach-au1x00/au1100_mmc.h> | 23 | #include <asm/mach-au1x00/au1100_mmc.h> |
26 | #include <asm/mach-au1x00/au1xxx_eth.h> | 24 | #include <asm/mach-au1x00/au1xxx_eth.h> |
@@ -84,12 +82,6 @@ static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = { | |||
84 | PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT), | 82 | PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT), |
85 | PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT), | 83 | PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT), |
86 | }, | 84 | }, |
87 | [ALCHEMY_CPU_AU1300] = { | ||
88 | PORT(AU1300_UART0_PHYS_ADDR, AU1300_UART0_INT), | ||
89 | PORT(AU1300_UART1_PHYS_ADDR, AU1300_UART1_INT), | ||
90 | PORT(AU1300_UART2_PHYS_ADDR, AU1300_UART2_INT), | ||
91 | PORT(AU1300_UART3_PHYS_ADDR, AU1300_UART3_INT), | ||
92 | }, | ||
93 | }; | 85 | }; |
94 | 86 | ||
95 | static struct platform_device au1xx0_uart_device = { | 87 | static struct platform_device au1xx0_uart_device = { |
@@ -119,158 +111,270 @@ static void __init alchemy_setup_uarts(int ctype) | |||
119 | printk(KERN_INFO "Alchemy: failed to register UARTs\n"); | 111 | printk(KERN_INFO "Alchemy: failed to register UARTs\n"); |
120 | } | 112 | } |
121 | 113 | ||
114 | /* OHCI (USB full speed host controller) */ | ||
115 | static struct resource au1xxx_usb_ohci_resources[] = { | ||
116 | [0] = { | ||
117 | .start = USB_OHCI_BASE, | ||
118 | .end = USB_OHCI_BASE + USB_OHCI_LEN - 1, | ||
119 | .flags = IORESOURCE_MEM, | ||
120 | }, | ||
121 | [1] = { | ||
122 | .start = FOR_PLATFORM_C_USB_HOST_INT, | ||
123 | .end = FOR_PLATFORM_C_USB_HOST_INT, | ||
124 | .flags = IORESOURCE_IRQ, | ||
125 | }, | ||
126 | }; | ||
122 | 127 | ||
123 | /* The dmamask must be set for OHCI/EHCI to work */ | 128 | /* The dmamask must be set for OHCI to work */ |
124 | static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32); | 129 | static u64 ohci_dmamask = DMA_BIT_MASK(32); |
125 | static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32); | ||
126 | 130 | ||
127 | /* Power on callback for the ehci platform driver */ | 131 | static struct platform_device au1xxx_usb_ohci_device = { |
128 | static int alchemy_ehci_power_on(struct platform_device *pdev) | 132 | .name = "au1xxx-ohci", |
129 | { | 133 | .id = 0, |
130 | return alchemy_usb_control(ALCHEMY_USB_EHCI0, 1); | 134 | .dev = { |
131 | } | 135 | .dma_mask = &ohci_dmamask, |
136 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
137 | }, | ||
138 | .num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources), | ||
139 | .resource = au1xxx_usb_ohci_resources, | ||
140 | }; | ||
132 | 141 | ||
133 | /* Power off/suspend callback for the ehci platform driver */ | 142 | /*** AU1100 LCD controller ***/ |
134 | static void alchemy_ehci_power_off(struct platform_device *pdev) | ||
135 | { | ||
136 | alchemy_usb_control(ALCHEMY_USB_EHCI0, 0); | ||
137 | } | ||
138 | 143 | ||
139 | static struct usb_ehci_pdata alchemy_ehci_pdata = { | 144 | #ifdef CONFIG_FB_AU1100 |
140 | .no_io_watchdog = 1, | 145 | static struct resource au1100_lcd_resources[] = { |
141 | .power_on = alchemy_ehci_power_on, | 146 | [0] = { |
142 | .power_off = alchemy_ehci_power_off, | 147 | .start = LCD_PHYS_ADDR, |
143 | .power_suspend = alchemy_ehci_power_off, | 148 | .end = LCD_PHYS_ADDR + 0x800 - 1, |
149 | .flags = IORESOURCE_MEM, | ||
150 | }, | ||
151 | [1] = { | ||
152 | .start = AU1100_LCD_INT, | ||
153 | .end = AU1100_LCD_INT, | ||
154 | .flags = IORESOURCE_IRQ, | ||
155 | } | ||
144 | }; | 156 | }; |
145 | 157 | ||
146 | /* Power on callback for the ohci platform driver */ | 158 | static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); |
147 | static int alchemy_ohci_power_on(struct platform_device *pdev) | ||
148 | { | ||
149 | int unit; | ||
150 | 159 | ||
151 | unit = (pdev->id == 1) ? | 160 | static struct platform_device au1100_lcd_device = { |
152 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | 161 | .name = "au1100-lcd", |
162 | .id = 0, | ||
163 | .dev = { | ||
164 | .dma_mask = &au1100_lcd_dmamask, | ||
165 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
166 | }, | ||
167 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
168 | .resource = au1100_lcd_resources, | ||
169 | }; | ||
170 | #endif | ||
153 | 171 | ||
154 | return alchemy_usb_control(unit, 1); | 172 | #ifdef CONFIG_SOC_AU1200 |
155 | } | 173 | /* EHCI (USB high speed host controller) */ |
174 | static struct resource au1xxx_usb_ehci_resources[] = { | ||
175 | [0] = { | ||
176 | .start = USB_EHCI_BASE, | ||
177 | .end = USB_EHCI_BASE + USB_EHCI_LEN - 1, | ||
178 | .flags = IORESOURCE_MEM, | ||
179 | }, | ||
180 | [1] = { | ||
181 | .start = AU1200_USB_INT, | ||
182 | .end = AU1200_USB_INT, | ||
183 | .flags = IORESOURCE_IRQ, | ||
184 | }, | ||
185 | }; | ||
156 | 186 | ||
157 | /* Power off/suspend callback for the ohci platform driver */ | 187 | static u64 ehci_dmamask = DMA_BIT_MASK(32); |
158 | static void alchemy_ohci_power_off(struct platform_device *pdev) | ||
159 | { | ||
160 | int unit; | ||
161 | 188 | ||
162 | unit = (pdev->id == 1) ? | 189 | static struct platform_device au1xxx_usb_ehci_device = { |
163 | ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0; | 190 | .name = "au1xxx-ehci", |
191 | .id = 0, | ||
192 | .dev = { | ||
193 | .dma_mask = &ehci_dmamask, | ||
194 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
195 | }, | ||
196 | .num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), | ||
197 | .resource = au1xxx_usb_ehci_resources, | ||
198 | }; | ||
164 | 199 | ||
165 | alchemy_usb_control(unit, 0); | 200 | /* Au1200 UDC (USB gadget controller) */ |
166 | } | 201 | static struct resource au1xxx_usb_gdt_resources[] = { |
202 | [0] = { | ||
203 | .start = USB_UDC_BASE, | ||
204 | .end = USB_UDC_BASE + USB_UDC_LEN - 1, | ||
205 | .flags = IORESOURCE_MEM, | ||
206 | }, | ||
207 | [1] = { | ||
208 | .start = AU1200_USB_INT, | ||
209 | .end = AU1200_USB_INT, | ||
210 | .flags = IORESOURCE_IRQ, | ||
211 | }, | ||
212 | }; | ||
213 | |||
214 | static u64 udc_dmamask = DMA_BIT_MASK(32); | ||
167 | 215 | ||
168 | static struct usb_ohci_pdata alchemy_ohci_pdata = { | 216 | static struct platform_device au1xxx_usb_gdt_device = { |
169 | .power_on = alchemy_ohci_power_on, | 217 | .name = "au1xxx-udc", |
170 | .power_off = alchemy_ohci_power_off, | 218 | .id = 0, |
171 | .power_suspend = alchemy_ohci_power_off, | 219 | .dev = { |
220 | .dma_mask = &udc_dmamask, | ||
221 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
222 | }, | ||
223 | .num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources), | ||
224 | .resource = au1xxx_usb_gdt_resources, | ||
172 | }; | 225 | }; |
173 | 226 | ||
174 | static unsigned long alchemy_ohci_data[][2] __initdata = { | 227 | /* Au1200 UOC (USB OTG controller) */ |
175 | [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT }, | 228 | static struct resource au1xxx_usb_otg_resources[] = { |
176 | [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT }, | 229 | [0] = { |
177 | [ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT }, | 230 | .start = USB_UOC_BASE, |
178 | [ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT }, | 231 | .end = USB_UOC_BASE + USB_UOC_LEN - 1, |
179 | [ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT }, | 232 | .flags = IORESOURCE_MEM, |
180 | [ALCHEMY_CPU_AU1300] = { AU1300_USB_OHCI0_PHYS_ADDR, AU1300_USB_INT }, | 233 | }, |
234 | [1] = { | ||
235 | .start = AU1200_USB_INT, | ||
236 | .end = AU1200_USB_INT, | ||
237 | .flags = IORESOURCE_IRQ, | ||
238 | }, | ||
181 | }; | 239 | }; |
182 | 240 | ||
183 | static unsigned long alchemy_ehci_data[][2] __initdata = { | 241 | static u64 uoc_dmamask = DMA_BIT_MASK(32); |
184 | [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT }, | 242 | |
185 | [ALCHEMY_CPU_AU1300] = { AU1300_USB_EHCI_PHYS_ADDR, AU1300_USB_INT }, | 243 | static struct platform_device au1xxx_usb_otg_device = { |
244 | .name = "au1xxx-uoc", | ||
245 | .id = 0, | ||
246 | .dev = { | ||
247 | .dma_mask = &uoc_dmamask, | ||
248 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
249 | }, | ||
250 | .num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources), | ||
251 | .resource = au1xxx_usb_otg_resources, | ||
186 | }; | 252 | }; |
187 | 253 | ||
188 | static int __init _new_usbres(struct resource **r, struct platform_device **d) | 254 | static struct resource au1200_lcd_resources[] = { |
189 | { | 255 | [0] = { |
190 | *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); | 256 | .start = LCD_PHYS_ADDR, |
191 | if (!*r) | 257 | .end = LCD_PHYS_ADDR + 0x800 - 1, |
192 | return -ENOMEM; | 258 | .flags = IORESOURCE_MEM, |
193 | *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL); | 259 | }, |
194 | if (!*d) { | 260 | [1] = { |
195 | kfree(*r); | 261 | .start = AU1200_LCD_INT, |
196 | return -ENOMEM; | 262 | .end = AU1200_LCD_INT, |
263 | .flags = IORESOURCE_IRQ, | ||
197 | } | 264 | } |
265 | }; | ||
198 | 266 | ||
199 | (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 267 | static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32); |
200 | (*d)->num_resources = 2; | ||
201 | (*d)->resource = *r; | ||
202 | 268 | ||
203 | return 0; | 269 | static struct platform_device au1200_lcd_device = { |
204 | } | 270 | .name = "au1200-lcd", |
271 | .id = 0, | ||
272 | .dev = { | ||
273 | .dma_mask = &au1200_lcd_dmamask, | ||
274 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
275 | }, | ||
276 | .num_resources = ARRAY_SIZE(au1200_lcd_resources), | ||
277 | .resource = au1200_lcd_resources, | ||
278 | }; | ||
205 | 279 | ||
206 | static void __init alchemy_setup_usb(int ctype) | 280 | static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); |
207 | { | ||
208 | struct resource *res; | ||
209 | struct platform_device *pdev; | ||
210 | 281 | ||
211 | /* setup OHCI0. Every variant has one */ | 282 | extern struct au1xmmc_platform_data au1xmmc_platdata[2]; |
212 | if (_new_usbres(&res, &pdev)) | ||
213 | return; | ||
214 | 283 | ||
215 | res[0].start = alchemy_ohci_data[ctype][0]; | 284 | static struct resource au1200_mmc0_resources[] = { |
216 | res[0].end = res[0].start + 0x100 - 1; | 285 | [0] = { |
217 | res[0].flags = IORESOURCE_MEM; | 286 | .start = AU1100_SD0_PHYS_ADDR, |
218 | res[1].start = alchemy_ohci_data[ctype][1]; | 287 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, |
219 | res[1].end = res[1].start; | 288 | .flags = IORESOURCE_MEM, |
220 | res[1].flags = IORESOURCE_IRQ; | 289 | }, |
221 | pdev->name = "ohci-platform"; | 290 | [1] = { |
222 | pdev->id = 0; | 291 | .start = AU1200_SD_INT, |
223 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; | 292 | .end = AU1200_SD_INT, |
224 | pdev->dev.platform_data = &alchemy_ohci_pdata; | 293 | .flags = IORESOURCE_IRQ, |
225 | 294 | }, | |
226 | if (platform_device_register(pdev)) | 295 | [2] = { |
227 | printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n"); | 296 | .start = DSCR_CMD0_SDMS_TX0, |
228 | 297 | .end = DSCR_CMD0_SDMS_TX0, | |
229 | 298 | .flags = IORESOURCE_DMA, | |
230 | /* setup EHCI0: Au1200/Au1300 */ | 299 | }, |
231 | if ((ctype == ALCHEMY_CPU_AU1200) || (ctype == ALCHEMY_CPU_AU1300)) { | 300 | [3] = { |
232 | if (_new_usbres(&res, &pdev)) | 301 | .start = DSCR_CMD0_SDMS_RX0, |
233 | return; | 302 | .end = DSCR_CMD0_SDMS_RX0, |
234 | 303 | .flags = IORESOURCE_DMA, | |
235 | res[0].start = alchemy_ehci_data[ctype][0]; | ||
236 | res[0].end = res[0].start + 0x100 - 1; | ||
237 | res[0].flags = IORESOURCE_MEM; | ||
238 | res[1].start = alchemy_ehci_data[ctype][1]; | ||
239 | res[1].end = res[1].start; | ||
240 | res[1].flags = IORESOURCE_IRQ; | ||
241 | pdev->name = "ehci-platform"; | ||
242 | pdev->id = 0; | ||
243 | pdev->dev.dma_mask = &alchemy_ehci_dmamask; | ||
244 | pdev->dev.platform_data = &alchemy_ehci_pdata; | ||
245 | |||
246 | if (platform_device_register(pdev)) | ||
247 | printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n"); | ||
248 | } | 304 | } |
305 | }; | ||
306 | |||
307 | static struct platform_device au1200_mmc0_device = { | ||
308 | .name = "au1xxx-mmc", | ||
309 | .id = 0, | ||
310 | .dev = { | ||
311 | .dma_mask = &au1xxx_mmc_dmamask, | ||
312 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
313 | .platform_data = &au1xmmc_platdata[0], | ||
314 | }, | ||
315 | .num_resources = ARRAY_SIZE(au1200_mmc0_resources), | ||
316 | .resource = au1200_mmc0_resources, | ||
317 | }; | ||
249 | 318 | ||
250 | /* Au1300: OHCI1 */ | 319 | #ifndef CONFIG_MIPS_DB1200 |
251 | if (ctype == ALCHEMY_CPU_AU1300) { | 320 | static struct resource au1200_mmc1_resources[] = { |
252 | if (_new_usbres(&res, &pdev)) | 321 | [0] = { |
253 | return; | 322 | .start = AU1100_SD1_PHYS_ADDR, |
254 | 323 | .end = AU1100_SD1_PHYS_ADDR + 0xfff, | |
255 | res[0].start = AU1300_USB_OHCI1_PHYS_ADDR; | 324 | .flags = IORESOURCE_MEM, |
256 | res[0].end = res[0].start + 0x100 - 1; | 325 | }, |
257 | res[0].flags = IORESOURCE_MEM; | 326 | [1] = { |
258 | res[1].start = AU1300_USB_INT; | 327 | .start = AU1200_SD_INT, |
259 | res[1].end = res[1].start; | 328 | .end = AU1200_SD_INT, |
260 | res[1].flags = IORESOURCE_IRQ; | 329 | .flags = IORESOURCE_IRQ, |
261 | pdev->name = "ohci-platform"; | 330 | }, |
262 | pdev->id = 1; | 331 | [2] = { |
263 | pdev->dev.dma_mask = &alchemy_ohci_dmamask; | 332 | .start = DSCR_CMD0_SDMS_TX1, |
264 | pdev->dev.platform_data = &alchemy_ohci_pdata; | 333 | .end = DSCR_CMD0_SDMS_TX1, |
265 | 334 | .flags = IORESOURCE_DMA, | |
266 | if (platform_device_register(pdev)) | 335 | }, |
267 | printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n"); | 336 | [3] = { |
337 | .start = DSCR_CMD0_SDMS_RX1, | ||
338 | .end = DSCR_CMD0_SDMS_RX1, | ||
339 | .flags = IORESOURCE_DMA, | ||
268 | } | 340 | } |
269 | } | 341 | }; |
342 | |||
343 | static struct platform_device au1200_mmc1_device = { | ||
344 | .name = "au1xxx-mmc", | ||
345 | .id = 1, | ||
346 | .dev = { | ||
347 | .dma_mask = &au1xxx_mmc_dmamask, | ||
348 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
349 | .platform_data = &au1xmmc_platdata[1], | ||
350 | }, | ||
351 | .num_resources = ARRAY_SIZE(au1200_mmc1_resources), | ||
352 | .resource = au1200_mmc1_resources, | ||
353 | }; | ||
354 | #endif /* #ifndef CONFIG_MIPS_DB1200 */ | ||
355 | #endif /* #ifdef CONFIG_SOC_AU1200 */ | ||
356 | |||
357 | /* All Alchemy demoboards with I2C have this #define in their headers */ | ||
358 | #ifdef SMBUS_PSC_BASE | ||
359 | static struct resource pbdb_smbus_resources[] = { | ||
360 | { | ||
361 | .start = CPHYSADDR(SMBUS_PSC_BASE), | ||
362 | .end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff), | ||
363 | .flags = IORESOURCE_MEM, | ||
364 | }, | ||
365 | }; | ||
366 | |||
367 | static struct platform_device pbdb_smbus_device = { | ||
368 | .name = "au1xpsc_smbus", | ||
369 | .id = 0, /* bus number */ | ||
370 | .num_resources = ARRAY_SIZE(pbdb_smbus_resources), | ||
371 | .resource = pbdb_smbus_resources, | ||
372 | }; | ||
373 | #endif | ||
270 | 374 | ||
271 | /* Macro to help defining the Ethernet MAC resources */ | 375 | /* Macro to help defining the Ethernet MAC resources */ |
272 | #define MAC_RES_COUNT 4 /* MAC regs, MAC en, MAC INT, MACDMA regs */ | 376 | #define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */ |
273 | #define MAC_RES(_base, _enable, _irq, _macdma) \ | 377 | #define MAC_RES(_base, _enable, _irq) \ |
274 | { \ | 378 | { \ |
275 | .start = _base, \ | 379 | .start = _base, \ |
276 | .end = _base + 0xffff, \ | 380 | .end = _base + 0xffff, \ |
@@ -285,37 +389,28 @@ static void __init alchemy_setup_usb(int ctype) | |||
285 | .start = _irq, \ | 389 | .start = _irq, \ |
286 | .end = _irq, \ | 390 | .end = _irq, \ |
287 | .flags = IORESOURCE_IRQ \ | 391 | .flags = IORESOURCE_IRQ \ |
288 | }, \ | ||
289 | { \ | ||
290 | .start = _macdma, \ | ||
291 | .end = _macdma + 0x1ff, \ | ||
292 | .flags = IORESOURCE_MEM, \ | ||
293 | } | 392 | } |
294 | 393 | ||
295 | static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { | 394 | static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { |
296 | [ALCHEMY_CPU_AU1000] = { | 395 | [ALCHEMY_CPU_AU1000] = { |
297 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | 396 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
298 | AU1000_MACEN_PHYS_ADDR, | 397 | AU1000_MACEN_PHYS_ADDR, |
299 | AU1000_MAC0_DMA_INT, | 398 | AU1000_MAC0_DMA_INT) |
300 | AU1000_MACDMA0_PHYS_ADDR) | ||
301 | }, | 399 | }, |
302 | [ALCHEMY_CPU_AU1500] = { | 400 | [ALCHEMY_CPU_AU1500] = { |
303 | MAC_RES(AU1500_MAC0_PHYS_ADDR, | 401 | MAC_RES(AU1500_MAC0_PHYS_ADDR, |
304 | AU1500_MACEN_PHYS_ADDR, | 402 | AU1500_MACEN_PHYS_ADDR, |
305 | AU1500_MAC0_DMA_INT, | 403 | AU1500_MAC0_DMA_INT) |
306 | AU1000_MACDMA0_PHYS_ADDR) | ||
307 | }, | 404 | }, |
308 | [ALCHEMY_CPU_AU1100] = { | 405 | [ALCHEMY_CPU_AU1100] = { |
309 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | 406 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
310 | AU1000_MACEN_PHYS_ADDR, | 407 | AU1000_MACEN_PHYS_ADDR, |
311 | AU1100_MAC0_DMA_INT, | 408 | AU1100_MAC0_DMA_INT) |
312 | AU1000_MACDMA0_PHYS_ADDR) | ||
313 | }, | 409 | }, |
314 | [ALCHEMY_CPU_AU1550] = { | 410 | [ALCHEMY_CPU_AU1550] = { |
315 | MAC_RES(AU1000_MAC0_PHYS_ADDR, | 411 | MAC_RES(AU1000_MAC0_PHYS_ADDR, |
316 | AU1000_MACEN_PHYS_ADDR, | 412 | AU1000_MACEN_PHYS_ADDR, |
317 | AU1550_MAC0_DMA_INT, | 413 | AU1550_MAC0_DMA_INT) |
318 | AU1000_MACDMA0_PHYS_ADDR) | ||
319 | }, | 414 | }, |
320 | }; | 415 | }; |
321 | 416 | ||
@@ -334,20 +429,17 @@ static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = { | |||
334 | [ALCHEMY_CPU_AU1000] = { | 429 | [ALCHEMY_CPU_AU1000] = { |
335 | MAC_RES(AU1000_MAC1_PHYS_ADDR, | 430 | MAC_RES(AU1000_MAC1_PHYS_ADDR, |
336 | AU1000_MACEN_PHYS_ADDR + 4, | 431 | AU1000_MACEN_PHYS_ADDR + 4, |
337 | AU1000_MAC1_DMA_INT, | 432 | AU1000_MAC1_DMA_INT) |
338 | AU1000_MACDMA1_PHYS_ADDR) | ||
339 | }, | 433 | }, |
340 | [ALCHEMY_CPU_AU1500] = { | 434 | [ALCHEMY_CPU_AU1500] = { |
341 | MAC_RES(AU1500_MAC1_PHYS_ADDR, | 435 | MAC_RES(AU1500_MAC1_PHYS_ADDR, |
342 | AU1500_MACEN_PHYS_ADDR + 4, | 436 | AU1500_MACEN_PHYS_ADDR + 4, |
343 | AU1500_MAC1_DMA_INT, | 437 | AU1500_MAC1_DMA_INT) |
344 | AU1000_MACDMA1_PHYS_ADDR) | ||
345 | }, | 438 | }, |
346 | [ALCHEMY_CPU_AU1550] = { | 439 | [ALCHEMY_CPU_AU1550] = { |
347 | MAC_RES(AU1000_MAC1_PHYS_ADDR, | 440 | MAC_RES(AU1000_MAC1_PHYS_ADDR, |
348 | AU1000_MACEN_PHYS_ADDR + 4, | 441 | AU1000_MACEN_PHYS_ADDR + 4, |
349 | AU1550_MAC1_DMA_INT, | 442 | AU1550_MAC1_DMA_INT) |
350 | AU1000_MACDMA1_PHYS_ADDR) | ||
351 | }, | 443 | }, |
352 | }; | 444 | }; |
353 | 445 | ||
@@ -386,12 +478,13 @@ static void __init alchemy_setup_macs(int ctype) | |||
386 | if (alchemy_get_macs(ctype) < 1) | 478 | if (alchemy_get_macs(ctype) < 1) |
387 | return; | 479 | return; |
388 | 480 | ||
389 | macres = kmemdup(au1xxx_eth0_resources[ctype], | 481 | macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); |
390 | sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | ||
391 | if (!macres) { | 482 | if (!macres) { |
392 | printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n"); | 483 | printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n"); |
393 | return; | 484 | return; |
394 | } | 485 | } |
486 | memcpy(macres, au1xxx_eth0_resources[ctype], | ||
487 | sizeof(struct resource) * MAC_RES_COUNT); | ||
395 | au1xxx_eth0_device.resource = macres; | 488 | au1xxx_eth0_device.resource = macres; |
396 | 489 | ||
397 | i = prom_get_ethernet_addr(ethaddr); | 490 | i = prom_get_ethernet_addr(ethaddr); |
@@ -407,12 +500,13 @@ static void __init alchemy_setup_macs(int ctype) | |||
407 | if (alchemy_get_macs(ctype) < 2) | 500 | if (alchemy_get_macs(ctype) < 2) |
408 | return; | 501 | return; |
409 | 502 | ||
410 | macres = kmemdup(au1xxx_eth1_resources[ctype], | 503 | macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); |
411 | sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL); | ||
412 | if (!macres) { | 504 | if (!macres) { |
413 | printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n"); | 505 | printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n"); |
414 | return; | 506 | return; |
415 | } | 507 | } |
508 | memcpy(macres, au1xxx_eth1_resources[ctype], | ||
509 | sizeof(struct resource) * MAC_RES_COUNT); | ||
416 | au1xxx_eth1_device.resource = macres; | 510 | au1xxx_eth1_device.resource = macres; |
417 | 511 | ||
418 | ethaddr[5] += 1; /* next addr for 2nd MAC */ | 512 | ethaddr[5] += 1; /* next addr for 2nd MAC */ |
@@ -427,15 +521,36 @@ static void __init alchemy_setup_macs(int ctype) | |||
427 | } | 521 | } |
428 | } | 522 | } |
429 | 523 | ||
524 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | ||
525 | &au1xxx_usb_ohci_device, | ||
526 | #ifdef CONFIG_FB_AU1100 | ||
527 | &au1100_lcd_device, | ||
528 | #endif | ||
529 | #ifdef CONFIG_SOC_AU1200 | ||
530 | &au1xxx_usb_ehci_device, | ||
531 | &au1xxx_usb_gdt_device, | ||
532 | &au1xxx_usb_otg_device, | ||
533 | &au1200_lcd_device, | ||
534 | &au1200_mmc0_device, | ||
535 | #ifndef CONFIG_MIPS_DB1200 | ||
536 | &au1200_mmc1_device, | ||
537 | #endif | ||
538 | #endif | ||
539 | #ifdef SMBUS_PSC_BASE | ||
540 | &pbdb_smbus_device, | ||
541 | #endif | ||
542 | }; | ||
543 | |||
430 | static int __init au1xxx_platform_init(void) | 544 | static int __init au1xxx_platform_init(void) |
431 | { | 545 | { |
432 | int ctype = alchemy_get_cputype(); | 546 | int err, ctype = alchemy_get_cputype(); |
433 | 547 | ||
434 | alchemy_setup_uarts(ctype); | 548 | alchemy_setup_uarts(ctype); |
435 | alchemy_setup_macs(ctype); | 549 | alchemy_setup_macs(ctype); |
436 | alchemy_setup_usb(ctype); | ||
437 | 550 | ||
438 | return 0; | 551 | err = platform_add_devices(au1xxx_platform_devices, |
552 | ARRAY_SIZE(au1xxx_platform_devices)); | ||
553 | return err; | ||
439 | } | 554 | } |
440 | 555 | ||
441 | arch_initcall(au1xxx_platform_init); | 556 | arch_initcall(au1xxx_platform_init); |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 0c7fce2a3c1..b86324a4260 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -37,6 +37,8 @@ | |||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/mach-au1x00/au1000.h> | 38 | #include <asm/mach-au1x00/au1000.h> |
39 | 39 | ||
40 | #ifdef CONFIG_PM | ||
41 | |||
40 | /* | 42 | /* |
41 | * We need to save/restore a bunch of core registers that are | 43 | * We need to save/restore a bunch of core registers that are |
42 | * either volatile or reset to some state across a processor sleep. | 44 | * either volatile or reset to some state across a processor sleep. |
@@ -47,6 +49,7 @@ | |||
47 | * We only have to save/restore registers that aren't otherwise | 49 | * We only have to save/restore registers that aren't otherwise |
48 | * done as part of a driver pm_* function. | 50 | * done as part of a driver pm_* function. |
49 | */ | 51 | */ |
52 | static unsigned int sleep_usb[2]; | ||
50 | static unsigned int sleep_sys_clocks[5]; | 53 | static unsigned int sleep_sys_clocks[5]; |
51 | static unsigned int sleep_sys_pinfunc; | 54 | static unsigned int sleep_sys_pinfunc; |
52 | static unsigned int sleep_static_memctlr[4][3]; | 55 | static unsigned int sleep_static_memctlr[4][3]; |
@@ -54,6 +57,31 @@ static unsigned int sleep_static_memctlr[4][3]; | |||
54 | 57 | ||
55 | static void save_core_regs(void) | 58 | static void save_core_regs(void) |
56 | { | 59 | { |
60 | #ifndef CONFIG_SOC_AU1200 | ||
61 | /* Shutdown USB host/device. */ | ||
62 | sleep_usb[0] = au_readl(USB_HOST_CONFIG); | ||
63 | |||
64 | /* There appears to be some undocumented reset register.... */ | ||
65 | au_writel(0, 0xb0100004); | ||
66 | au_sync(); | ||
67 | au_writel(0, USB_HOST_CONFIG); | ||
68 | au_sync(); | ||
69 | |||
70 | sleep_usb[1] = au_readl(USBD_ENABLE); | ||
71 | au_writel(0, USBD_ENABLE); | ||
72 | au_sync(); | ||
73 | |||
74 | #else /* AU1200 */ | ||
75 | |||
76 | /* enable access to OTG mmio so we can save OTG CAP/MUX. | ||
77 | * FIXME: write an OTG driver and move this stuff there! | ||
78 | */ | ||
79 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
80 | au_sync(); | ||
81 | sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */ | ||
82 | sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */ | ||
83 | #endif | ||
84 | |||
57 | /* Clocks and PLLs. */ | 85 | /* Clocks and PLLs. */ |
58 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); | 86 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); |
59 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); | 87 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); |
@@ -97,6 +125,22 @@ static void restore_core_regs(void) | |||
97 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); | 125 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); |
98 | au_sync(); | 126 | au_sync(); |
99 | 127 | ||
128 | #ifndef CONFIG_SOC_AU1200 | ||
129 | au_writel(sleep_usb[0], USB_HOST_CONFIG); | ||
130 | au_writel(sleep_usb[1], USBD_ENABLE); | ||
131 | au_sync(); | ||
132 | #else | ||
133 | /* enable access to OTG memory */ | ||
134 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
135 | au_sync(); | ||
136 | |||
137 | /* restore OTG caps and port mux. */ | ||
138 | au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */ | ||
139 | au_sync(); | ||
140 | au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */ | ||
141 | au_sync(); | ||
142 | #endif | ||
143 | |||
100 | /* Restore the static memory controller configuration. */ | 144 | /* Restore the static memory controller configuration. */ |
101 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); | 145 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); |
102 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); | 146 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); |
@@ -126,10 +170,9 @@ void au_sleep(void) | |||
126 | case ALCHEMY_CPU_AU1200: | 170 | case ALCHEMY_CPU_AU1200: |
127 | alchemy_sleep_au1550(); | 171 | alchemy_sleep_au1550(); |
128 | break; | 172 | break; |
129 | case ALCHEMY_CPU_AU1300: | ||
130 | alchemy_sleep_au1300(); | ||
131 | break; | ||
132 | } | 173 | } |
133 | 174 | ||
134 | restore_core_regs(); | 175 | restore_core_regs(); |
135 | } | 176 | } |
177 | |||
178 | #endif /* CONFIG_PM */ | ||
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 37ffd997c61..1b887c86841 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -73,8 +73,8 @@ void __init plat_mem_setup(void) | |||
73 | /* This routine should be valid for all Au1x based boards */ | 73 | /* This routine should be valid for all Au1x based boards */ |
74 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | 74 | phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) |
75 | { | 75 | { |
76 | unsigned long start = ALCHEMY_PCI_MEMWIN_START; | 76 | u32 start = (u32)Au1500_PCI_MEM_START; |
77 | unsigned long end = ALCHEMY_PCI_MEMWIN_END; | 77 | u32 end = (u32)Au1500_PCI_MEM_END; |
78 | 78 | ||
79 | /* Don't fixup 36-bit addresses */ | 79 | /* Don't fixup 36-bit addresses */ |
80 | if ((phys_addr >> 32) != 0) | 80 | if ((phys_addr >> 32) != 0) |
@@ -82,7 +82,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) | |||
82 | 82 | ||
83 | /* Check for PCI memory window */ | 83 | /* Check for PCI memory window */ |
84 | if (phys_addr >= start && (phys_addr + size - 1) <= end) | 84 | if (phys_addr >= start && (phys_addr + size - 1) <= end) |
85 | return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr); | 85 | return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START); |
86 | 86 | ||
87 | /* default nop */ | 87 | /* default nop */ |
88 | return phys_addr; | 88 | return phys_addr; |
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S index c7bcc7e5c82..77f3c743b71 100644 --- a/arch/mips/alchemy/common/sleeper.S +++ b/arch/mips/alchemy/common/sleeper.S | |||
@@ -153,79 +153,6 @@ LEAF(alchemy_sleep_au1550) | |||
153 | 153 | ||
154 | END(alchemy_sleep_au1550) | 154 | END(alchemy_sleep_au1550) |
155 | 155 | ||
156 | /* sleepcode for Au1300 memory controller type */ | ||
157 | LEAF(alchemy_sleep_au1300) | ||
158 | |||
159 | SETUP_SLEEP | ||
160 | |||
161 | /* cache following instructions, as memory gets put to sleep */ | ||
162 | la t0, 2f | ||
163 | la t1, 4f | ||
164 | subu t2, t1, t0 | ||
165 | |||
166 | .set mips3 | ||
167 | |||
168 | 1: cache 0x14, 0(t0) | ||
169 | subu t2, t2, 32 | ||
170 | bgez t2, 1b | ||
171 | addu t0, t0, 32 | ||
172 | |||
173 | .set mips0 | ||
174 | |||
175 | 2: lui a0, 0xb400 /* mem_xxx */ | ||
176 | |||
177 | /* disable all ports in mem_sdportcfga */ | ||
178 | sw zero, 0x868(a0) /* mem_sdportcfga */ | ||
179 | sync | ||
180 | |||
181 | /* disable ODT */ | ||
182 | li t0, 0x03010000 | ||
183 | sw t0, 0x08d8(a0) /* mem_sdcmd0 */ | ||
184 | sw t0, 0x08dc(a0) /* mem_sdcmd1 */ | ||
185 | sync | ||
186 | |||
187 | /* precharge */ | ||
188 | li t0, 0x23000400 | ||
189 | sw t0, 0x08dc(a0) /* mem_sdcmd1 */ | ||
190 | sw t0, 0x08d8(a0) /* mem_sdcmd0 */ | ||
191 | sync | ||
192 | |||
193 | /* auto refresh */ | ||
194 | sw zero, 0x08c8(a0) /* mem_sdautoref */ | ||
195 | sync | ||
196 | |||
197 | /* block access to the DDR */ | ||
198 | lw t0, 0x0848(a0) /* mem_sdconfigb */ | ||
199 | li t1, (1 << 7 | 0x3F) | ||
200 | or t0, t0, t1 | ||
201 | sw t0, 0x0848(a0) /* mem_sdconfigb */ | ||
202 | sync | ||
203 | |||
204 | /* issue the Self Refresh command */ | ||
205 | li t0, 0x10000000 | ||
206 | sw t0, 0x08dc(a0) /* mem_sdcmd1 */ | ||
207 | sw t0, 0x08d8(a0) /* mem_sdcmd0 */ | ||
208 | sync | ||
209 | |||
210 | /* wait for sdram to enter self-refresh mode */ | ||
211 | lui t0, 0x0300 | ||
212 | 3: lw t1, 0x0850(a0) /* mem_sdstat */ | ||
213 | and t2, t1, t0 | ||
214 | bne t2, t0, 3b | ||
215 | nop | ||
216 | |||
217 | /* disable SDRAM clocks */ | ||
218 | li t0, ~(3<<28) | ||
219 | lw t1, 0x0840(a0) /* mem_sdconfiga */ | ||
220 | and t1, t1, t0 /* clear CE[1:0] */ | ||
221 | sw t1, 0x0840(a0) /* mem_sdconfiga */ | ||
222 | sync | ||
223 | |||
224 | DO_SLEEP | ||
225 | 4: | ||
226 | |||
227 | END(alchemy_sleep_au1300) | ||
228 | |||
229 | 156 | ||
230 | /* This is where we return upon wakeup. | 157 | /* This is where we return upon wakeup. |
231 | * Reload all of the registers and return. | 158 | * Reload all of the registers and return. |
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index b67930d1932..d5da6adbf63 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c | |||
@@ -53,7 +53,7 @@ static struct clocksource au1x_counter1_clocksource = { | |||
53 | .read = au1x_counter1_read, | 53 | .read = au1x_counter1_read, |
54 | .mask = CLOCKSOURCE_MASK(32), | 54 | .mask = CLOCKSOURCE_MASK(32), |
55 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 55 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
56 | .rating = 1500, | 56 | .rating = 100, |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static int au1x_rtcmatch2_set_next_event(unsigned long delta, | 59 | static int au1x_rtcmatch2_set_next_event(unsigned long delta, |
@@ -84,7 +84,7 @@ static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id) | |||
84 | static struct clock_event_device au1x_rtcmatch2_clockdev = { | 84 | static struct clock_event_device au1x_rtcmatch2_clockdev = { |
85 | .name = "rtcmatch2", | 85 | .name = "rtcmatch2", |
86 | .features = CLOCK_EVT_FEAT_ONESHOT, | 86 | .features = CLOCK_EVT_FEAT_ONESHOT, |
87 | .rating = 1500, | 87 | .rating = 100, |
88 | .set_next_event = au1x_rtcmatch2_set_next_event, | 88 | .set_next_event = au1x_rtcmatch2_set_next_event, |
89 | .set_mode = au1x_rtcmatch2_set_mode, | 89 | .set_mode = au1x_rtcmatch2_set_mode, |
90 | .cpumask = cpu_all_mask, | 90 | .cpumask = cpu_all_mask, |
@@ -92,7 +92,7 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = { | |||
92 | 92 | ||
93 | static struct irqaction au1x_rtcmatch2_irqaction = { | 93 | static struct irqaction au1x_rtcmatch2_irqaction = { |
94 | .handler = au1x_rtcmatch2_irq, | 94 | .handler = au1x_rtcmatch2_irq, |
95 | .flags = IRQF_TIMER, | 95 | .flags = IRQF_DISABLED | IRQF_TIMER, |
96 | .name = "timer", | 96 | .name = "timer", |
97 | .dev_id = &au1x_rtcmatch2_clockdev, | 97 | .dev_id = &au1x_rtcmatch2_clockdev, |
98 | }; | 98 | }; |
@@ -146,7 +146,7 @@ static int __init alchemy_time_init(unsigned int m2int) | |||
146 | cd->shift = 32; | 146 | cd->shift = 32; |
147 | cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift); | 147 | cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift); |
148 | cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); | 148 | cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); |
149 | cd->min_delta_ns = clockevent_delta2ns(9, cd); /* ~0.28ms */ | 149 | cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */ |
150 | clockevents_register_device(cd); | 150 | clockevents_register_device(cd); |
151 | setup_irq(m2int, &au1x_rtcmatch2_irqaction); | 151 | setup_irq(m2int, &au1x_rtcmatch2_irqaction); |
152 | 152 | ||
@@ -158,13 +158,26 @@ cntr_err: | |||
158 | return -1; | 158 | return -1; |
159 | } | 159 | } |
160 | 160 | ||
161 | static void __init alchemy_setup_c0timer(void) | ||
162 | { | ||
163 | /* | ||
164 | * MIPS kernel assigns 'au1k_wait' to 'cpu_wait' before this | ||
165 | * function is called. Because the Alchemy counters are unusable | ||
166 | * the C0 timekeeping code is installed and use of the 'wait' | ||
167 | * instruction must be prohibited, which is done most easily by | ||
168 | * assigning NULL to cpu_wait. | ||
169 | */ | ||
170 | cpu_wait = NULL; | ||
171 | r4k_clockevent_init(); | ||
172 | init_r4k_clocksource(); | ||
173 | } | ||
174 | |||
161 | static int alchemy_m2inttab[] __initdata = { | 175 | static int alchemy_m2inttab[] __initdata = { |
162 | AU1000_RTC_MATCH2_INT, | 176 | AU1000_RTC_MATCH2_INT, |
163 | AU1500_RTC_MATCH2_INT, | 177 | AU1500_RTC_MATCH2_INT, |
164 | AU1100_RTC_MATCH2_INT, | 178 | AU1100_RTC_MATCH2_INT, |
165 | AU1550_RTC_MATCH2_INT, | 179 | AU1550_RTC_MATCH2_INT, |
166 | AU1200_RTC_MATCH2_INT, | 180 | AU1200_RTC_MATCH2_INT, |
167 | AU1300_RTC_MATCH2_INT, | ||
168 | }; | 181 | }; |
169 | 182 | ||
170 | void __init plat_time_init(void) | 183 | void __init plat_time_init(void) |
@@ -172,7 +185,8 @@ void __init plat_time_init(void) | |||
172 | int t; | 185 | int t; |
173 | 186 | ||
174 | t = alchemy_get_cputype(); | 187 | t = alchemy_get_cputype(); |
175 | if (t == ALCHEMY_CPU_UNKNOWN || | 188 | if (t == ALCHEMY_CPU_UNKNOWN) |
176 | alchemy_time_init(alchemy_m2inttab[t])) | 189 | alchemy_setup_c0timer(); |
177 | cpu_wait = NULL; /* wait doesn't work with r4k timer */ | 190 | else if (alchemy_time_init(alchemy_m2inttab[t])) |
191 | alchemy_setup_c0timer(); | ||
178 | } | 192 | } |
diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c deleted file mode 100644 index 936af8359fb..00000000000 --- a/arch/mips/alchemy/common/usb.c +++ /dev/null | |||
@@ -1,614 +0,0 @@ | |||
1 | /* | ||
2 | * USB block power/access management abstraction. | ||
3 | * | ||
4 | * Au1000+: The OHCI block control register is at the far end of the OHCI memory | ||
5 | * area. Au1550 has OHCI on different base address. No need to handle | ||
6 | * UDC here. | ||
7 | * Au1200: one register to control access and clocks to O/EHCI, UDC and OTG | ||
8 | * as well as the PHY for EHCI and UDC. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/syscore_ops.h> | ||
17 | #include <asm/mach-au1x00/au1000.h> | ||
18 | |||
19 | /* control register offsets */ | ||
20 | #define AU1000_OHCICFG 0x7fffc | ||
21 | #define AU1550_OHCICFG 0x07ffc | ||
22 | #define AU1200_USBCFG 0x04 | ||
23 | |||
24 | /* Au1000 USB block config bits */ | ||
25 | #define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */ | ||
26 | #define USBHEN_CE (1 << 3) /* OHCI block clock enable */ | ||
27 | #define USBHEN_E (1 << 2) /* OHCI block enable */ | ||
28 | #define USBHEN_C (1 << 1) /* OHCI block coherency bit */ | ||
29 | #define USBHEN_BE (1 << 0) /* OHCI Big-Endian */ | ||
30 | |||
31 | /* Au1200 USB config bits */ | ||
32 | #define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */ | ||
33 | #define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */ | ||
34 | #define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */ | ||
35 | #define USBCFG_SSD (1 << 23) /* serial short detect en */ | ||
36 | #define USBCFG_PPE (1 << 19) /* HS PHY PLL */ | ||
37 | #define USBCFG_UCE (1 << 18) /* UDC clock enable */ | ||
38 | #define USBCFG_ECE (1 << 17) /* EHCI clock enable */ | ||
39 | #define USBCFG_OCE (1 << 16) /* OHCI clock enable */ | ||
40 | #define USBCFG_FLA(x) (((x) & 0x3f) << 8) | ||
41 | #define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */ | ||
42 | #define USBCFG_GME (1 << 6) /* OTG mem access */ | ||
43 | #define USBCFG_DBE (1 << 5) /* UDC busmaster enable */ | ||
44 | #define USBCFG_DME (1 << 4) /* UDC mem enable */ | ||
45 | #define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */ | ||
46 | #define USBCFG_EME (1 << 2) /* EHCI mem enable */ | ||
47 | #define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */ | ||
48 | #define USBCFG_OME (1 << 0) /* OHCI mem enable */ | ||
49 | #define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\ | ||
50 | USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \ | ||
51 | USBCFG_GME | USBCFG_DBE | USBCFG_DME | \ | ||
52 | USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \ | ||
53 | USBCFG_OME) | ||
54 | |||
55 | /* Au1300 USB config registers */ | ||
56 | #define USB_DWC_CTRL1 0x00 | ||
57 | #define USB_DWC_CTRL2 0x04 | ||
58 | #define USB_VBUS_TIMER 0x10 | ||
59 | #define USB_SBUS_CTRL 0x14 | ||
60 | #define USB_MSR_ERR 0x18 | ||
61 | #define USB_DWC_CTRL3 0x1C | ||
62 | #define USB_DWC_CTRL4 0x20 | ||
63 | #define USB_OTG_STATUS 0x28 | ||
64 | #define USB_DWC_CTRL5 0x2C | ||
65 | #define USB_DWC_CTRL6 0x30 | ||
66 | #define USB_DWC_CTRL7 0x34 | ||
67 | #define USB_PHY_STATUS 0xC0 | ||
68 | #define USB_INT_STATUS 0xC4 | ||
69 | #define USB_INT_ENABLE 0xC8 | ||
70 | |||
71 | #define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */ | ||
72 | #define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */ | ||
73 | #define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */ | ||
74 | |||
75 | #define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */ | ||
76 | #define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */ | ||
77 | #define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */ | ||
78 | |||
79 | #define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19) | ||
80 | #define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18) | ||
81 | #define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17) | ||
82 | #define USB_DWC_CTRL3_OTG0_CKEN (1 << 16) | ||
83 | |||
84 | #define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */ | ||
85 | |||
86 | #define USB_INTEN_FORCE 0x20 | ||
87 | #define USB_INTEN_PHY 0x10 | ||
88 | #define USB_INTEN_UDC 0x08 | ||
89 | #define USB_INTEN_EHCI 0x04 | ||
90 | #define USB_INTEN_OHCI1 0x02 | ||
91 | #define USB_INTEN_OHCI0 0x01 | ||
92 | |||
93 | static DEFINE_SPINLOCK(alchemy_usb_lock); | ||
94 | |||
95 | static inline void __au1300_usb_phyctl(void __iomem *base, int enable) | ||
96 | { | ||
97 | unsigned long r, s; | ||
98 | |||
99 | r = __raw_readl(base + USB_DWC_CTRL2); | ||
100 | s = __raw_readl(base + USB_DWC_CTRL3); | ||
101 | |||
102 | s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN | | ||
103 | USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN; | ||
104 | |||
105 | if (enable) { | ||
106 | /* simply enable all PHYs */ | ||
107 | r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
108 | USB_DWC_CTRL2_PHYRS; | ||
109 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
110 | wmb(); | ||
111 | } else if (!s) { | ||
112 | /* no USB block active, do disable all PHYs */ | ||
113 | r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS | | ||
114 | USB_DWC_CTRL2_PHYRS); | ||
115 | __raw_writel(r, base + USB_DWC_CTRL2); | ||
116 | wmb(); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static inline void __au1300_ohci_control(void __iomem *base, int enable, int id) | ||
121 | { | ||
122 | unsigned long r; | ||
123 | |||
124 | if (enable) { | ||
125 | __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */ | ||
126 | wmb(); | ||
127 | |||
128 | r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */ | ||
129 | r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
130 | : USB_DWC_CTRL3_OHCI1_CKEN; | ||
131 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
132 | wmb(); | ||
133 | |||
134 | __au1300_usb_phyctl(base, enable); /* power up the PHYs */ | ||
135 | |||
136 | r = __raw_readl(base + USB_INT_ENABLE); | ||
137 | r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1; | ||
138 | __raw_writel(r, base + USB_INT_ENABLE); | ||
139 | wmb(); | ||
140 | |||
141 | /* reset the OHCI start clock bit */ | ||
142 | __raw_writel(0, base + USB_DWC_CTRL7); | ||
143 | wmb(); | ||
144 | } else { | ||
145 | r = __raw_readl(base + USB_INT_ENABLE); | ||
146 | r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1); | ||
147 | __raw_writel(r, base + USB_INT_ENABLE); | ||
148 | wmb(); | ||
149 | |||
150 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
151 | r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN | ||
152 | : USB_DWC_CTRL3_OHCI1_CKEN); | ||
153 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
154 | wmb(); | ||
155 | |||
156 | __au1300_usb_phyctl(base, enable); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static inline void __au1300_ehci_control(void __iomem *base, int enable) | ||
161 | { | ||
162 | unsigned long r; | ||
163 | |||
164 | if (enable) { | ||
165 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
166 | r |= USB_DWC_CTRL3_EHCI0_CKEN; | ||
167 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
168 | wmb(); | ||
169 | |||
170 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
171 | r |= USB_DWC_CTRL1_HSTRS; | ||
172 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
173 | wmb(); | ||
174 | |||
175 | __au1300_usb_phyctl(base, enable); | ||
176 | |||
177 | r = __raw_readl(base + USB_INT_ENABLE); | ||
178 | r |= USB_INTEN_EHCI; | ||
179 | __raw_writel(r, base + USB_INT_ENABLE); | ||
180 | wmb(); | ||
181 | } else { | ||
182 | r = __raw_readl(base + USB_INT_ENABLE); | ||
183 | r &= ~USB_INTEN_EHCI; | ||
184 | __raw_writel(r, base + USB_INT_ENABLE); | ||
185 | wmb(); | ||
186 | |||
187 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
188 | r &= ~USB_DWC_CTRL1_HSTRS; | ||
189 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
190 | wmb(); | ||
191 | |||
192 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
193 | r &= ~USB_DWC_CTRL3_EHCI0_CKEN; | ||
194 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
195 | wmb(); | ||
196 | |||
197 | __au1300_usb_phyctl(base, enable); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | static inline void __au1300_udc_control(void __iomem *base, int enable) | ||
202 | { | ||
203 | unsigned long r; | ||
204 | |||
205 | if (enable) { | ||
206 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
207 | r |= USB_DWC_CTRL1_DCRS; | ||
208 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
209 | wmb(); | ||
210 | |||
211 | __au1300_usb_phyctl(base, enable); | ||
212 | |||
213 | r = __raw_readl(base + USB_INT_ENABLE); | ||
214 | r |= USB_INTEN_UDC; | ||
215 | __raw_writel(r, base + USB_INT_ENABLE); | ||
216 | wmb(); | ||
217 | } else { | ||
218 | r = __raw_readl(base + USB_INT_ENABLE); | ||
219 | r &= ~USB_INTEN_UDC; | ||
220 | __raw_writel(r, base + USB_INT_ENABLE); | ||
221 | wmb(); | ||
222 | |||
223 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
224 | r &= ~USB_DWC_CTRL1_DCRS; | ||
225 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
226 | wmb(); | ||
227 | |||
228 | __au1300_usb_phyctl(base, enable); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | static inline void __au1300_otg_control(void __iomem *base, int enable) | ||
233 | { | ||
234 | unsigned long r; | ||
235 | if (enable) { | ||
236 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
237 | r |= USB_DWC_CTRL3_OTG0_CKEN; | ||
238 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
239 | wmb(); | ||
240 | |||
241 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
242 | r &= ~USB_DWC_CTRL1_OTGD; | ||
243 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
244 | wmb(); | ||
245 | |||
246 | __au1300_usb_phyctl(base, enable); | ||
247 | } else { | ||
248 | r = __raw_readl(base + USB_DWC_CTRL1); | ||
249 | r |= USB_DWC_CTRL1_OTGD; | ||
250 | __raw_writel(r, base + USB_DWC_CTRL1); | ||
251 | wmb(); | ||
252 | |||
253 | r = __raw_readl(base + USB_DWC_CTRL3); | ||
254 | r &= ~USB_DWC_CTRL3_OTG0_CKEN; | ||
255 | __raw_writel(r, base + USB_DWC_CTRL3); | ||
256 | wmb(); | ||
257 | |||
258 | __au1300_usb_phyctl(base, enable); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static inline int au1300_usb_control(int block, int enable) | ||
263 | { | ||
264 | void __iomem *base = | ||
265 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
266 | int ret = 0; | ||
267 | |||
268 | switch (block) { | ||
269 | case ALCHEMY_USB_OHCI0: | ||
270 | __au1300_ohci_control(base, enable, 0); | ||
271 | break; | ||
272 | case ALCHEMY_USB_OHCI1: | ||
273 | __au1300_ohci_control(base, enable, 1); | ||
274 | break; | ||
275 | case ALCHEMY_USB_EHCI0: | ||
276 | __au1300_ehci_control(base, enable); | ||
277 | break; | ||
278 | case ALCHEMY_USB_UDC0: | ||
279 | __au1300_udc_control(base, enable); | ||
280 | break; | ||
281 | case ALCHEMY_USB_OTG0: | ||
282 | __au1300_otg_control(base, enable); | ||
283 | break; | ||
284 | default: | ||
285 | ret = -ENODEV; | ||
286 | } | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | static inline void au1300_usb_init(void) | ||
291 | { | ||
292 | void __iomem *base = | ||
293 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
294 | |||
295 | /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4 | ||
296 | * here at all: Port 2 routing (EHCI or UDC) must be set either | ||
297 | * by boot firmware or platform init code; I can't autodetect | ||
298 | * a sane setting. | ||
299 | */ | ||
300 | __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */ | ||
301 | wmb(); | ||
302 | __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */ | ||
303 | wmb(); | ||
304 | __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */ | ||
305 | wmb(); | ||
306 | __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */ | ||
307 | wmb(); | ||
308 | /* set coherent access bit */ | ||
309 | __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL); | ||
310 | wmb(); | ||
311 | } | ||
312 | |||
313 | static inline void __au1200_ohci_control(void __iomem *base, int enable) | ||
314 | { | ||
315 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
316 | if (enable) { | ||
317 | __raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG); | ||
318 | wmb(); | ||
319 | udelay(2000); | ||
320 | } else { | ||
321 | __raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG); | ||
322 | wmb(); | ||
323 | udelay(1000); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | static inline void __au1200_ehci_control(void __iomem *base, int enable) | ||
328 | { | ||
329 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
330 | if (enable) { | ||
331 | __raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG); | ||
332 | wmb(); | ||
333 | udelay(1000); | ||
334 | } else { | ||
335 | if (!(r & USBCFG_UCE)) /* UDC also off? */ | ||
336 | r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ | ||
337 | __raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG); | ||
338 | wmb(); | ||
339 | udelay(1000); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | static inline void __au1200_udc_control(void __iomem *base, int enable) | ||
344 | { | ||
345 | unsigned long r = __raw_readl(base + AU1200_USBCFG); | ||
346 | if (enable) { | ||
347 | __raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG); | ||
348 | wmb(); | ||
349 | } else { | ||
350 | if (!(r & USBCFG_ECE)) /* EHCI also off? */ | ||
351 | r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */ | ||
352 | __raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG); | ||
353 | wmb(); | ||
354 | } | ||
355 | } | ||
356 | |||
357 | static inline int au1200_coherency_bug(void) | ||
358 | { | ||
359 | #if defined(CONFIG_DMA_COHERENT) | ||
360 | /* Au1200 AB USB does not support coherent memory */ | ||
361 | if (!(read_c0_prid() & 0xff)) { | ||
362 | printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n"); | ||
363 | printk(KERN_INFO "Au1200 USB: update your board or re-configure" | ||
364 | " the kernel\n"); | ||
365 | return -ENODEV; | ||
366 | } | ||
367 | #endif | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static inline int au1200_usb_control(int block, int enable) | ||
372 | { | ||
373 | void __iomem *base = | ||
374 | (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); | ||
375 | int ret = 0; | ||
376 | |||
377 | switch (block) { | ||
378 | case ALCHEMY_USB_OHCI0: | ||
379 | ret = au1200_coherency_bug(); | ||
380 | if (ret && enable) | ||
381 | goto out; | ||
382 | __au1200_ohci_control(base, enable); | ||
383 | break; | ||
384 | case ALCHEMY_USB_UDC0: | ||
385 | __au1200_udc_control(base, enable); | ||
386 | break; | ||
387 | case ALCHEMY_USB_EHCI0: | ||
388 | ret = au1200_coherency_bug(); | ||
389 | if (ret && enable) | ||
390 | goto out; | ||
391 | __au1200_ehci_control(base, enable); | ||
392 | break; | ||
393 | default: | ||
394 | ret = -ENODEV; | ||
395 | } | ||
396 | out: | ||
397 | return ret; | ||
398 | } | ||
399 | |||
400 | |||
401 | /* initialize USB block(s) to a known working state */ | ||
402 | static inline void au1200_usb_init(void) | ||
403 | { | ||
404 | void __iomem *base = | ||
405 | (void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR); | ||
406 | __raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG); | ||
407 | wmb(); | ||
408 | udelay(1000); | ||
409 | } | ||
410 | |||
411 | static inline void au1000_usb_init(unsigned long rb, int reg) | ||
412 | { | ||
413 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); | ||
414 | unsigned long r = __raw_readl(base); | ||
415 | |||
416 | #if defined(__BIG_ENDIAN) | ||
417 | r |= USBHEN_BE; | ||
418 | #endif | ||
419 | r |= USBHEN_C; | ||
420 | |||
421 | __raw_writel(r, base); | ||
422 | wmb(); | ||
423 | udelay(1000); | ||
424 | } | ||
425 | |||
426 | |||
427 | static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) | ||
428 | { | ||
429 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb); | ||
430 | unsigned long r = __raw_readl(base + creg); | ||
431 | |||
432 | if (enable) { | ||
433 | __raw_writel(r | USBHEN_CE, base + creg); | ||
434 | wmb(); | ||
435 | udelay(1000); | ||
436 | __raw_writel(r | USBHEN_CE | USBHEN_E, base + creg); | ||
437 | wmb(); | ||
438 | udelay(1000); | ||
439 | |||
440 | /* wait for reset complete (read reg twice: au1500 erratum) */ | ||
441 | while (__raw_readl(base + creg), | ||
442 | !(__raw_readl(base + creg) & USBHEN_RD)) | ||
443 | udelay(1000); | ||
444 | } else { | ||
445 | __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); | ||
446 | wmb(); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | static inline int au1000_usb_control(int block, int enable, unsigned long rb, | ||
451 | int creg) | ||
452 | { | ||
453 | int ret = 0; | ||
454 | |||
455 | switch (block) { | ||
456 | case ALCHEMY_USB_OHCI0: | ||
457 | __au1xx0_ohci_control(enable, rb, creg); | ||
458 | break; | ||
459 | default: | ||
460 | ret = -ENODEV; | ||
461 | } | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * alchemy_usb_control - control Alchemy on-chip USB blocks | ||
467 | * @block: USB block to target | ||
468 | * @enable: set 1 to enable a block, 0 to disable | ||
469 | */ | ||
470 | int alchemy_usb_control(int block, int enable) | ||
471 | { | ||
472 | unsigned long flags; | ||
473 | int ret; | ||
474 | |||
475 | spin_lock_irqsave(&alchemy_usb_lock, flags); | ||
476 | switch (alchemy_get_cputype()) { | ||
477 | case ALCHEMY_CPU_AU1000: | ||
478 | case ALCHEMY_CPU_AU1500: | ||
479 | case ALCHEMY_CPU_AU1100: | ||
480 | ret = au1000_usb_control(block, enable, | ||
481 | AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | ||
482 | break; | ||
483 | case ALCHEMY_CPU_AU1550: | ||
484 | ret = au1000_usb_control(block, enable, | ||
485 | AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | ||
486 | break; | ||
487 | case ALCHEMY_CPU_AU1200: | ||
488 | ret = au1200_usb_control(block, enable); | ||
489 | break; | ||
490 | case ALCHEMY_CPU_AU1300: | ||
491 | ret = au1300_usb_control(block, enable); | ||
492 | break; | ||
493 | default: | ||
494 | ret = -ENODEV; | ||
495 | } | ||
496 | spin_unlock_irqrestore(&alchemy_usb_lock, flags); | ||
497 | return ret; | ||
498 | } | ||
499 | EXPORT_SYMBOL_GPL(alchemy_usb_control); | ||
500 | |||
501 | |||
502 | static unsigned long alchemy_usb_pmdata[2]; | ||
503 | |||
504 | static void au1000_usb_pm(unsigned long br, int creg, int susp) | ||
505 | { | ||
506 | void __iomem *base = (void __iomem *)KSEG1ADDR(br); | ||
507 | |||
508 | if (susp) { | ||
509 | alchemy_usb_pmdata[0] = __raw_readl(base + creg); | ||
510 | /* There appears to be some undocumented reset register.... */ | ||
511 | __raw_writel(0, base + 0x04); | ||
512 | wmb(); | ||
513 | __raw_writel(0, base + creg); | ||
514 | wmb(); | ||
515 | } else { | ||
516 | __raw_writel(alchemy_usb_pmdata[0], base + creg); | ||
517 | wmb(); | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void au1200_usb_pm(int susp) | ||
522 | { | ||
523 | void __iomem *base = | ||
524 | (void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR); | ||
525 | if (susp) { | ||
526 | /* save OTG_CAP/MUX registers which indicate port routing */ | ||
527 | /* FIXME: write an OTG driver to do that */ | ||
528 | alchemy_usb_pmdata[0] = __raw_readl(base + 0x00); | ||
529 | alchemy_usb_pmdata[1] = __raw_readl(base + 0x04); | ||
530 | } else { | ||
531 | /* restore access to all MMIO areas */ | ||
532 | au1200_usb_init(); | ||
533 | |||
534 | /* restore OTG_CAP/MUX registers */ | ||
535 | __raw_writel(alchemy_usb_pmdata[0], base + 0x00); | ||
536 | __raw_writel(alchemy_usb_pmdata[1], base + 0x04); | ||
537 | wmb(); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | static void au1300_usb_pm(int susp) | ||
542 | { | ||
543 | void __iomem *base = | ||
544 | (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR); | ||
545 | /* remember Port2 routing */ | ||
546 | if (susp) { | ||
547 | alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4); | ||
548 | } else { | ||
549 | au1300_usb_init(); | ||
550 | __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4); | ||
551 | wmb(); | ||
552 | } | ||
553 | } | ||
554 | |||
555 | static void alchemy_usb_pm(int susp) | ||
556 | { | ||
557 | switch (alchemy_get_cputype()) { | ||
558 | case ALCHEMY_CPU_AU1000: | ||
559 | case ALCHEMY_CPU_AU1500: | ||
560 | case ALCHEMY_CPU_AU1100: | ||
561 | au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp); | ||
562 | break; | ||
563 | case ALCHEMY_CPU_AU1550: | ||
564 | au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp); | ||
565 | break; | ||
566 | case ALCHEMY_CPU_AU1200: | ||
567 | au1200_usb_pm(susp); | ||
568 | break; | ||
569 | case ALCHEMY_CPU_AU1300: | ||
570 | au1300_usb_pm(susp); | ||
571 | break; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | static int alchemy_usb_suspend(void) | ||
576 | { | ||
577 | alchemy_usb_pm(1); | ||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | static void alchemy_usb_resume(void) | ||
582 | { | ||
583 | alchemy_usb_pm(0); | ||
584 | } | ||
585 | |||
586 | static struct syscore_ops alchemy_usb_pm_ops = { | ||
587 | .suspend = alchemy_usb_suspend, | ||
588 | .resume = alchemy_usb_resume, | ||
589 | }; | ||
590 | |||
591 | static int __init alchemy_usb_init(void) | ||
592 | { | ||
593 | switch (alchemy_get_cputype()) { | ||
594 | case ALCHEMY_CPU_AU1000: | ||
595 | case ALCHEMY_CPU_AU1500: | ||
596 | case ALCHEMY_CPU_AU1100: | ||
597 | au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | ||
598 | break; | ||
599 | case ALCHEMY_CPU_AU1550: | ||
600 | au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | ||
601 | break; | ||
602 | case ALCHEMY_CPU_AU1200: | ||
603 | au1200_usb_init(); | ||
604 | break; | ||
605 | case ALCHEMY_CPU_AU1300: | ||
606 | au1300_usb_init(); | ||
607 | break; | ||
608 | } | ||
609 | |||
610 | register_syscore_ops(&alchemy_usb_pm_ops); | ||
611 | |||
612 | return 0; | ||
613 | } | ||
614 | arch_initcall(alchemy_usb_init); | ||
diff --git a/arch/mips/alchemy/common/vss.c b/arch/mips/alchemy/common/vss.c deleted file mode 100644 index d23b1444d36..00000000000 --- a/arch/mips/alchemy/common/vss.c +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * Au1300 media block power gating (VSS) | ||
3 | * | ||
4 | * This is a stop-gap solution until I have the clock framework integration | ||
5 | * ready. This stuff here really must be handled transparently when clocks | ||
6 | * for various media blocks are enabled/disabled. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <asm/mach-au1x00/au1000.h> | ||
12 | |||
13 | #define VSS_GATE 0x00 /* gate wait timers */ | ||
14 | #define VSS_CLKRST 0x04 /* clock/block control */ | ||
15 | #define VSS_FTR 0x08 /* footers */ | ||
16 | |||
17 | #define VSS_ADDR(blk) (KSEG1ADDR(AU1300_VSS_PHYS_ADDR) + (blk * 0x0c)) | ||
18 | |||
19 | static DEFINE_SPINLOCK(au1300_vss_lock); | ||
20 | |||
21 | /* enable a block as outlined in the databook */ | ||
22 | static inline void __enable_block(int block) | ||
23 | { | ||
24 | void __iomem *base = (void __iomem *)VSS_ADDR(block); | ||
25 | |||
26 | __raw_writel(3, base + VSS_CLKRST); /* enable clock, assert reset */ | ||
27 | wmb(); | ||
28 | |||
29 | __raw_writel(0x01fffffe, base + VSS_GATE); /* maximum setup time */ | ||
30 | wmb(); | ||
31 | |||
32 | /* enable footers in sequence */ | ||
33 | __raw_writel(0x01, base + VSS_FTR); | ||
34 | wmb(); | ||
35 | __raw_writel(0x03, base + VSS_FTR); | ||
36 | wmb(); | ||
37 | __raw_writel(0x07, base + VSS_FTR); | ||
38 | wmb(); | ||
39 | __raw_writel(0x0f, base + VSS_FTR); | ||
40 | wmb(); | ||
41 | |||
42 | __raw_writel(0x01ffffff, base + VSS_GATE); /* start FSM too */ | ||
43 | wmb(); | ||
44 | |||
45 | __raw_writel(2, base + VSS_CLKRST); /* deassert reset */ | ||
46 | wmb(); | ||
47 | |||
48 | __raw_writel(0x1f, base + VSS_FTR); /* enable isolation cells */ | ||
49 | wmb(); | ||
50 | } | ||
51 | |||
52 | /* disable a block as outlined in the databook */ | ||
53 | static inline void __disable_block(int block) | ||
54 | { | ||
55 | void __iomem *base = (void __iomem *)VSS_ADDR(block); | ||
56 | |||
57 | __raw_writel(0x0f, base + VSS_FTR); /* disable isolation cells */ | ||
58 | wmb(); | ||
59 | __raw_writel(0, base + VSS_GATE); /* disable FSM */ | ||
60 | wmb(); | ||
61 | __raw_writel(3, base + VSS_CLKRST); /* assert reset */ | ||
62 | wmb(); | ||
63 | __raw_writel(1, base + VSS_CLKRST); /* disable clock */ | ||
64 | wmb(); | ||
65 | __raw_writel(0, base + VSS_FTR); /* disable all footers */ | ||
66 | wmb(); | ||
67 | } | ||
68 | |||
69 | void au1300_vss_block_control(int block, int enable) | ||
70 | { | ||
71 | unsigned long flags; | ||
72 | |||
73 | if (alchemy_get_cputype() != ALCHEMY_CPU_AU1300) | ||
74 | return; | ||
75 | |||
76 | /* only one block at a time */ | ||
77 | spin_lock_irqsave(&au1300_vss_lock, flags); | ||
78 | if (enable) | ||
79 | __enable_block(block); | ||
80 | else | ||
81 | __disable_block(block); | ||
82 | spin_unlock_irqrestore(&au1300_vss_lock, flags); | ||
83 | } | ||
84 | EXPORT_SYMBOL_GPL(au1300_vss_block_control); | ||
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile index 15bf7306648..826449c817c 100644 --- a/arch/mips/alchemy/devboards/Makefile +++ b/arch/mips/alchemy/devboards/Makefile | |||
@@ -2,7 +2,17 @@ | |||
2 | # Alchemy Develboards | 2 | # Alchemy Develboards |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += bcsr.o platform.o | 5 | obj-y += prom.o bcsr.o platform.o |
6 | obj-$(CONFIG_PM) += pm.o | 6 | obj-$(CONFIG_PM) += pm.o |
7 | obj-$(CONFIG_MIPS_DB1000) += db1000.o | 7 | obj-$(CONFIG_MIPS_PB1000) += pb1000/ |
8 | obj-$(CONFIG_MIPS_DB1235) += db1235.o db1200.o db1300.o db1550.o | 8 | obj-$(CONFIG_MIPS_PB1100) += pb1100/ |
9 | obj-$(CONFIG_MIPS_PB1200) += pb1200/ | ||
10 | obj-$(CONFIG_MIPS_PB1500) += pb1500/ | ||
11 | obj-$(CONFIG_MIPS_PB1550) += pb1550/ | ||
12 | obj-$(CONFIG_MIPS_DB1000) += db1x00/ | ||
13 | obj-$(CONFIG_MIPS_DB1100) += db1x00/ | ||
14 | obj-$(CONFIG_MIPS_DB1200) += db1200/ | ||
15 | obj-$(CONFIG_MIPS_DB1500) += db1x00/ | ||
16 | obj-$(CONFIG_MIPS_DB1550) += db1x00/ | ||
17 | obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/ | ||
18 | obj-$(CONFIG_MIPS_MIRAGE) += db1x00/ | ||
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c index f2039ef2c29..463d2c4d944 100644 --- a/arch/mips/alchemy/devboards/bcsr.c +++ b/arch/mips/alchemy/devboards/bcsr.c | |||
@@ -90,13 +90,21 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d) | |||
90 | unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT); | 90 | unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT); |
91 | 91 | ||
92 | disable_irq_nosync(irq); | 92 | disable_irq_nosync(irq); |
93 | generic_handle_irq(bcsr_csc_base + __ffs(bisr)); | 93 | |
94 | for ( ; bisr; bisr &= bisr - 1) | ||
95 | generic_handle_irq(bcsr_csc_base + __ffs(bisr)); | ||
96 | |||
94 | enable_irq(irq); | 97 | enable_irq(irq); |
95 | } | 98 | } |
96 | 99 | ||
100 | /* NOTE: both the enable and mask bits must be cleared, otherwise the | ||
101 | * CPLD generates tons of spurious interrupts (at least on my DB1200). | ||
102 | * -- mlau | ||
103 | */ | ||
97 | static void bcsr_irq_mask(struct irq_data *d) | 104 | static void bcsr_irq_mask(struct irq_data *d) |
98 | { | 105 | { |
99 | unsigned short v = 1 << (d->irq - bcsr_csc_base); | 106 | unsigned short v = 1 << (d->irq - bcsr_csc_base); |
107 | __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); | ||
100 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); | 108 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); |
101 | wmb(); | 109 | wmb(); |
102 | } | 110 | } |
@@ -104,6 +112,7 @@ static void bcsr_irq_mask(struct irq_data *d) | |||
104 | static void bcsr_irq_maskack(struct irq_data *d) | 112 | static void bcsr_irq_maskack(struct irq_data *d) |
105 | { | 113 | { |
106 | unsigned short v = 1 << (d->irq - bcsr_csc_base); | 114 | unsigned short v = 1 << (d->irq - bcsr_csc_base); |
115 | __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR); | ||
107 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); | 116 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR); |
108 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */ | 117 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */ |
109 | wmb(); | 118 | wmb(); |
@@ -112,6 +121,7 @@ static void bcsr_irq_maskack(struct irq_data *d) | |||
112 | static void bcsr_irq_unmask(struct irq_data *d) | 121 | static void bcsr_irq_unmask(struct irq_data *d) |
113 | { | 122 | { |
114 | unsigned short v = 1 << (d->irq - bcsr_csc_base); | 123 | unsigned short v = 1 << (d->irq - bcsr_csc_base); |
124 | __raw_writew(v, bcsr_virt + BCSR_REG_INTSET); | ||
115 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET); | 125 | __raw_writew(v, bcsr_virt + BCSR_REG_MASKSET); |
116 | wmb(); | 126 | wmb(); |
117 | } | 127 | } |
@@ -127,9 +137,9 @@ void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq) | |||
127 | { | 137 | { |
128 | unsigned int irq; | 138 | unsigned int irq; |
129 | 139 | ||
130 | /* mask & enable & ack all */ | 140 | /* mask & disable & ack all */ |
141 | __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTCLR); | ||
131 | __raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR); | 142 | __raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR); |
132 | __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSET); | ||
133 | __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT); | 143 | __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT); |
134 | wmb(); | 144 | wmb(); |
135 | 145 | ||
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c deleted file mode 100644 index 8187845650f..00000000000 --- a/arch/mips/alchemy/devboards/db1000.c +++ /dev/null | |||
@@ -1,629 +0,0 @@ | |||
1 | /* | ||
2 | * DBAu1000/1500/1100 PBAu1100/1500 board support | ||
3 | * | ||
4 | * Copyright 2000, 2008 MontaVista Software Inc. | ||
5 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/gpio.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/leds.h> | ||
27 | #include <linux/mmc/host.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/pm.h> | ||
31 | #include <linux/spi/spi.h> | ||
32 | #include <linux/spi/spi_gpio.h> | ||
33 | #include <linux/spi/ads7846.h> | ||
34 | #include <asm/mach-au1x00/au1000.h> | ||
35 | #include <asm/mach-au1x00/au1000_dma.h> | ||
36 | #include <asm/mach-au1x00/au1100_mmc.h> | ||
37 | #include <asm/mach-db1x00/bcsr.h> | ||
38 | #include <asm/reboot.h> | ||
39 | #include <prom.h> | ||
40 | #include "platform.h" | ||
41 | |||
42 | #define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT) | ||
43 | |||
44 | struct pci_dev; | ||
45 | |||
46 | static const char *board_type_str(void) | ||
47 | { | ||
48 | switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { | ||
49 | case BCSR_WHOAMI_DB1000: | ||
50 | return "DB1000"; | ||
51 | case BCSR_WHOAMI_DB1500: | ||
52 | return "DB1500"; | ||
53 | case BCSR_WHOAMI_DB1100: | ||
54 | return "DB1100"; | ||
55 | case BCSR_WHOAMI_PB1500: | ||
56 | case BCSR_WHOAMI_PB1500R2: | ||
57 | return "PB1500"; | ||
58 | case BCSR_WHOAMI_PB1100: | ||
59 | return "PB1100"; | ||
60 | default: | ||
61 | return "(unknown)"; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | const char *get_system_type(void) | ||
66 | { | ||
67 | return board_type_str(); | ||
68 | } | ||
69 | |||
70 | void __init board_setup(void) | ||
71 | { | ||
72 | /* initialize board register space */ | ||
73 | bcsr_init(DB1000_BCSR_PHYS_ADDR, | ||
74 | DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS); | ||
75 | |||
76 | printk(KERN_INFO "AMD Alchemy %s Board\n", board_type_str()); | ||
77 | } | ||
78 | |||
79 | |||
80 | static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
81 | { | ||
82 | if ((slot < 12) || (slot > 13) || pin == 0) | ||
83 | return -1; | ||
84 | if (slot == 12) | ||
85 | return (pin == 1) ? AU1500_PCI_INTA : 0xff; | ||
86 | if (slot == 13) { | ||
87 | switch (pin) { | ||
88 | case 1: return AU1500_PCI_INTA; | ||
89 | case 2: return AU1500_PCI_INTB; | ||
90 | case 3: return AU1500_PCI_INTC; | ||
91 | case 4: return AU1500_PCI_INTD; | ||
92 | } | ||
93 | } | ||
94 | return -1; | ||
95 | } | ||
96 | |||
97 | static struct resource alchemy_pci_host_res[] = { | ||
98 | [0] = { | ||
99 | .start = AU1500_PCI_PHYS_ADDR, | ||
100 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
101 | .flags = IORESOURCE_MEM, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | static struct alchemy_pci_platdata db1500_pci_pd = { | ||
106 | .board_map_irq = db1500_map_pci_irq, | ||
107 | }; | ||
108 | |||
109 | static struct platform_device db1500_pci_host_dev = { | ||
110 | .dev.platform_data = &db1500_pci_pd, | ||
111 | .name = "alchemy-pci", | ||
112 | .id = 0, | ||
113 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
114 | .resource = alchemy_pci_host_res, | ||
115 | }; | ||
116 | |||
117 | static int __init db1500_pci_init(void) | ||
118 | { | ||
119 | int id = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | ||
120 | if ((id == BCSR_WHOAMI_DB1500) || (id == BCSR_WHOAMI_PB1500) || | ||
121 | (id == BCSR_WHOAMI_PB1500R2)) | ||
122 | return platform_device_register(&db1500_pci_host_dev); | ||
123 | return 0; | ||
124 | } | ||
125 | /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ | ||
126 | arch_initcall(db1500_pci_init); | ||
127 | |||
128 | |||
129 | static struct resource au1100_lcd_resources[] = { | ||
130 | [0] = { | ||
131 | .start = AU1100_LCD_PHYS_ADDR, | ||
132 | .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1, | ||
133 | .flags = IORESOURCE_MEM, | ||
134 | }, | ||
135 | [1] = { | ||
136 | .start = AU1100_LCD_INT, | ||
137 | .end = AU1100_LCD_INT, | ||
138 | .flags = IORESOURCE_IRQ, | ||
139 | } | ||
140 | }; | ||
141 | |||
142 | static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); | ||
143 | |||
144 | static struct platform_device au1100_lcd_device = { | ||
145 | .name = "au1100-lcd", | ||
146 | .id = 0, | ||
147 | .dev = { | ||
148 | .dma_mask = &au1100_lcd_dmamask, | ||
149 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
150 | }, | ||
151 | .num_resources = ARRAY_SIZE(au1100_lcd_resources), | ||
152 | .resource = au1100_lcd_resources, | ||
153 | }; | ||
154 | |||
155 | static struct resource alchemy_ac97c_res[] = { | ||
156 | [0] = { | ||
157 | .start = AU1000_AC97_PHYS_ADDR, | ||
158 | .end = AU1000_AC97_PHYS_ADDR + 0xfff, | ||
159 | .flags = IORESOURCE_MEM, | ||
160 | }, | ||
161 | [1] = { | ||
162 | .start = DMA_ID_AC97C_TX, | ||
163 | .end = DMA_ID_AC97C_TX, | ||
164 | .flags = IORESOURCE_DMA, | ||
165 | }, | ||
166 | [2] = { | ||
167 | .start = DMA_ID_AC97C_RX, | ||
168 | .end = DMA_ID_AC97C_RX, | ||
169 | .flags = IORESOURCE_DMA, | ||
170 | }, | ||
171 | }; | ||
172 | |||
173 | static struct platform_device alchemy_ac97c_dev = { | ||
174 | .name = "alchemy-ac97c", | ||
175 | .id = -1, | ||
176 | .resource = alchemy_ac97c_res, | ||
177 | .num_resources = ARRAY_SIZE(alchemy_ac97c_res), | ||
178 | }; | ||
179 | |||
180 | static struct platform_device alchemy_ac97c_dma_dev = { | ||
181 | .name = "alchemy-pcm-dma", | ||
182 | .id = 0, | ||
183 | }; | ||
184 | |||
185 | static struct platform_device db1x00_codec_dev = { | ||
186 | .name = "ac97-codec", | ||
187 | .id = -1, | ||
188 | }; | ||
189 | |||
190 | static struct platform_device db1x00_audio_dev = { | ||
191 | .name = "db1000-audio", | ||
192 | }; | ||
193 | |||
194 | /******************************************************************************/ | ||
195 | |||
196 | static irqreturn_t db1100_mmc_cd(int irq, void *ptr) | ||
197 | { | ||
198 | void (*mmc_cd)(struct mmc_host *, unsigned long); | ||
199 | /* link against CONFIG_MMC=m */ | ||
200 | mmc_cd = symbol_get(mmc_detect_change); | ||
201 | mmc_cd(ptr, msecs_to_jiffies(500)); | ||
202 | symbol_put(mmc_detect_change); | ||
203 | |||
204 | return IRQ_HANDLED; | ||
205 | } | ||
206 | |||
207 | static int db1100_mmc_cd_setup(void *mmc_host, int en) | ||
208 | { | ||
209 | int ret = 0, irq; | ||
210 | |||
211 | if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) | ||
212 | irq = AU1100_GPIO19_INT; | ||
213 | else | ||
214 | irq = AU1100_GPIO14_INT; /* PB1100 SD0 CD# */ | ||
215 | |||
216 | if (en) { | ||
217 | irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); | ||
218 | ret = request_irq(irq, db1100_mmc_cd, 0, | ||
219 | "sd0_cd", mmc_host); | ||
220 | } else | ||
221 | free_irq(irq, mmc_host); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static int db1100_mmc1_cd_setup(void *mmc_host, int en) | ||
226 | { | ||
227 | int ret = 0, irq; | ||
228 | |||
229 | if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) | ||
230 | irq = AU1100_GPIO20_INT; | ||
231 | else | ||
232 | irq = AU1100_GPIO15_INT; /* PB1100 SD1 CD# */ | ||
233 | |||
234 | if (en) { | ||
235 | irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH); | ||
236 | ret = request_irq(irq, db1100_mmc_cd, 0, | ||
237 | "sd1_cd", mmc_host); | ||
238 | } else | ||
239 | free_irq(irq, mmc_host); | ||
240 | return ret; | ||
241 | } | ||
242 | |||
243 | static int db1100_mmc_card_readonly(void *mmc_host) | ||
244 | { | ||
245 | /* testing suggests that this bit is inverted */ | ||
246 | return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1; | ||
247 | } | ||
248 | |||
249 | static int db1100_mmc_card_inserted(void *mmc_host) | ||
250 | { | ||
251 | return !alchemy_gpio_get_value(19); | ||
252 | } | ||
253 | |||
254 | static void db1100_mmc_set_power(void *mmc_host, int state) | ||
255 | { | ||
256 | int bit; | ||
257 | |||
258 | if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) | ||
259 | bit = BCSR_BOARD_SD0PWR; | ||
260 | else | ||
261 | bit = BCSR_BOARD_PB1100_SD0PWR; | ||
262 | |||
263 | if (state) { | ||
264 | bcsr_mod(BCSR_BOARD, 0, bit); | ||
265 | msleep(400); /* stabilization time */ | ||
266 | } else | ||
267 | bcsr_mod(BCSR_BOARD, bit, 0); | ||
268 | } | ||
269 | |||
270 | static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b) | ||
271 | { | ||
272 | if (b != LED_OFF) | ||
273 | bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0); | ||
274 | else | ||
275 | bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0); | ||
276 | } | ||
277 | |||
278 | static struct led_classdev db1100_mmc_led = { | ||
279 | .brightness_set = db1100_mmcled_set, | ||
280 | }; | ||
281 | |||
282 | static int db1100_mmc1_card_readonly(void *mmc_host) | ||
283 | { | ||
284 | return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0; | ||
285 | } | ||
286 | |||
287 | static int db1100_mmc1_card_inserted(void *mmc_host) | ||
288 | { | ||
289 | return !alchemy_gpio_get_value(20); | ||
290 | } | ||
291 | |||
292 | static void db1100_mmc1_set_power(void *mmc_host, int state) | ||
293 | { | ||
294 | int bit; | ||
295 | |||
296 | if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1100) | ||
297 | bit = BCSR_BOARD_SD1PWR; | ||
298 | else | ||
299 | bit = BCSR_BOARD_PB1100_SD1PWR; | ||
300 | |||
301 | if (state) { | ||
302 | bcsr_mod(BCSR_BOARD, 0, bit); | ||
303 | msleep(400); /* stabilization time */ | ||
304 | } else | ||
305 | bcsr_mod(BCSR_BOARD, bit, 0); | ||
306 | } | ||
307 | |||
308 | static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b) | ||
309 | { | ||
310 | if (b != LED_OFF) | ||
311 | bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0); | ||
312 | else | ||
313 | bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1); | ||
314 | } | ||
315 | |||
316 | static struct led_classdev db1100_mmc1_led = { | ||
317 | .brightness_set = db1100_mmc1led_set, | ||
318 | }; | ||
319 | |||
320 | static struct au1xmmc_platform_data db1100_mmc_platdata[2] = { | ||
321 | [0] = { | ||
322 | .cd_setup = db1100_mmc_cd_setup, | ||
323 | .set_power = db1100_mmc_set_power, | ||
324 | .card_inserted = db1100_mmc_card_inserted, | ||
325 | .card_readonly = db1100_mmc_card_readonly, | ||
326 | .led = &db1100_mmc_led, | ||
327 | }, | ||
328 | [1] = { | ||
329 | .cd_setup = db1100_mmc1_cd_setup, | ||
330 | .set_power = db1100_mmc1_set_power, | ||
331 | .card_inserted = db1100_mmc1_card_inserted, | ||
332 | .card_readonly = db1100_mmc1_card_readonly, | ||
333 | .led = &db1100_mmc1_led, | ||
334 | }, | ||
335 | }; | ||
336 | |||
337 | static struct resource au1100_mmc0_resources[] = { | ||
338 | [0] = { | ||
339 | .start = AU1100_SD0_PHYS_ADDR, | ||
340 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, | ||
341 | .flags = IORESOURCE_MEM, | ||
342 | }, | ||
343 | [1] = { | ||
344 | .start = AU1100_SD_INT, | ||
345 | .end = AU1100_SD_INT, | ||
346 | .flags = IORESOURCE_IRQ, | ||
347 | }, | ||
348 | [2] = { | ||
349 | .start = DMA_ID_SD0_TX, | ||
350 | .end = DMA_ID_SD0_TX, | ||
351 | .flags = IORESOURCE_DMA, | ||
352 | }, | ||
353 | [3] = { | ||
354 | .start = DMA_ID_SD0_RX, | ||
355 | .end = DMA_ID_SD0_RX, | ||
356 | .flags = IORESOURCE_DMA, | ||
357 | } | ||
358 | }; | ||
359 | |||
360 | static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); | ||
361 | |||
362 | static struct platform_device db1100_mmc0_dev = { | ||
363 | .name = "au1xxx-mmc", | ||
364 | .id = 0, | ||
365 | .dev = { | ||
366 | .dma_mask = &au1xxx_mmc_dmamask, | ||
367 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
368 | .platform_data = &db1100_mmc_platdata[0], | ||
369 | }, | ||
370 | .num_resources = ARRAY_SIZE(au1100_mmc0_resources), | ||
371 | .resource = au1100_mmc0_resources, | ||
372 | }; | ||
373 | |||
374 | static struct resource au1100_mmc1_res[] = { | ||
375 | [0] = { | ||
376 | .start = AU1100_SD1_PHYS_ADDR, | ||
377 | .end = AU1100_SD1_PHYS_ADDR + 0xfff, | ||
378 | .flags = IORESOURCE_MEM, | ||
379 | }, | ||
380 | [1] = { | ||
381 | .start = AU1100_SD_INT, | ||
382 | .end = AU1100_SD_INT, | ||
383 | .flags = IORESOURCE_IRQ, | ||
384 | }, | ||
385 | [2] = { | ||
386 | .start = DMA_ID_SD1_TX, | ||
387 | .end = DMA_ID_SD1_TX, | ||
388 | .flags = IORESOURCE_DMA, | ||
389 | }, | ||
390 | [3] = { | ||
391 | .start = DMA_ID_SD1_RX, | ||
392 | .end = DMA_ID_SD1_RX, | ||
393 | .flags = IORESOURCE_DMA, | ||
394 | } | ||
395 | }; | ||
396 | |||
397 | static struct platform_device db1100_mmc1_dev = { | ||
398 | .name = "au1xxx-mmc", | ||
399 | .id = 1, | ||
400 | .dev = { | ||
401 | .dma_mask = &au1xxx_mmc_dmamask, | ||
402 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
403 | .platform_data = &db1100_mmc_platdata[1], | ||
404 | }, | ||
405 | .num_resources = ARRAY_SIZE(au1100_mmc1_res), | ||
406 | .resource = au1100_mmc1_res, | ||
407 | }; | ||
408 | |||
409 | /******************************************************************************/ | ||
410 | |||
411 | static void db1000_irda_set_phy_mode(int mode) | ||
412 | { | ||
413 | unsigned short mask = BCSR_RESETS_IRDA_MODE_MASK | BCSR_RESETS_FIR_SEL; | ||
414 | |||
415 | switch (mode) { | ||
416 | case AU1000_IRDA_PHY_MODE_OFF: | ||
417 | bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_OFF); | ||
418 | break; | ||
419 | case AU1000_IRDA_PHY_MODE_SIR: | ||
420 | bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL); | ||
421 | break; | ||
422 | case AU1000_IRDA_PHY_MODE_FIR: | ||
423 | bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL | | ||
424 | BCSR_RESETS_FIR_SEL); | ||
425 | break; | ||
426 | } | ||
427 | } | ||
428 | |||
429 | static struct au1k_irda_platform_data db1000_irda_platdata = { | ||
430 | .set_phy_mode = db1000_irda_set_phy_mode, | ||
431 | }; | ||
432 | |||
433 | static struct resource au1000_irda_res[] = { | ||
434 | [0] = { | ||
435 | .start = AU1000_IRDA_PHYS_ADDR, | ||
436 | .end = AU1000_IRDA_PHYS_ADDR + 0x0fff, | ||
437 | .flags = IORESOURCE_MEM, | ||
438 | }, | ||
439 | [1] = { | ||
440 | .start = AU1000_IRDA_TX_INT, | ||
441 | .end = AU1000_IRDA_TX_INT, | ||
442 | .flags = IORESOURCE_IRQ, | ||
443 | }, | ||
444 | [2] = { | ||
445 | .start = AU1000_IRDA_RX_INT, | ||
446 | .end = AU1000_IRDA_RX_INT, | ||
447 | .flags = IORESOURCE_IRQ, | ||
448 | }, | ||
449 | }; | ||
450 | |||
451 | static struct platform_device db1000_irda_dev = { | ||
452 | .name = "au1000-irda", | ||
453 | .id = -1, | ||
454 | .dev = { | ||
455 | .platform_data = &db1000_irda_platdata, | ||
456 | }, | ||
457 | .resource = au1000_irda_res, | ||
458 | .num_resources = ARRAY_SIZE(au1000_irda_res), | ||
459 | }; | ||
460 | |||
461 | /******************************************************************************/ | ||
462 | |||
463 | static struct ads7846_platform_data db1100_touch_pd = { | ||
464 | .model = 7846, | ||
465 | .vref_mv = 3300, | ||
466 | .gpio_pendown = 21, | ||
467 | }; | ||
468 | |||
469 | static struct spi_gpio_platform_data db1100_spictl_pd = { | ||
470 | .sck = 209, | ||
471 | .mosi = 208, | ||
472 | .miso = 207, | ||
473 | .num_chipselect = 1, | ||
474 | }; | ||
475 | |||
476 | static struct spi_board_info db1100_spi_info[] __initdata = { | ||
477 | [0] = { | ||
478 | .modalias = "ads7846", | ||
479 | .max_speed_hz = 3250000, | ||
480 | .bus_num = 0, | ||
481 | .chip_select = 0, | ||
482 | .mode = 0, | ||
483 | .irq = AU1100_GPIO21_INT, | ||
484 | .platform_data = &db1100_touch_pd, | ||
485 | .controller_data = (void *)210, /* for spi_gpio: CS# GPIO210 */ | ||
486 | }, | ||
487 | }; | ||
488 | |||
489 | static struct platform_device db1100_spi_dev = { | ||
490 | .name = "spi_gpio", | ||
491 | .id = 0, | ||
492 | .dev = { | ||
493 | .platform_data = &db1100_spictl_pd, | ||
494 | }, | ||
495 | }; | ||
496 | |||
497 | |||
498 | static struct platform_device *db1x00_devs[] = { | ||
499 | &db1x00_codec_dev, | ||
500 | &alchemy_ac97c_dma_dev, | ||
501 | &alchemy_ac97c_dev, | ||
502 | &db1x00_audio_dev, | ||
503 | }; | ||
504 | |||
505 | static struct platform_device *db1000_devs[] = { | ||
506 | &db1000_irda_dev, | ||
507 | }; | ||
508 | |||
509 | static struct platform_device *db1100_devs[] = { | ||
510 | &au1100_lcd_device, | ||
511 | &db1100_mmc0_dev, | ||
512 | &db1100_mmc1_dev, | ||
513 | &db1000_irda_dev, | ||
514 | }; | ||
515 | |||
516 | static int __init db1000_dev_init(void) | ||
517 | { | ||
518 | int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | ||
519 | int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1; | ||
520 | unsigned long pfc; | ||
521 | |||
522 | if (board == BCSR_WHOAMI_DB1500) { | ||
523 | c0 = AU1500_GPIO2_INT; | ||
524 | c1 = AU1500_GPIO5_INT; | ||
525 | d0 = AU1500_GPIO0_INT; | ||
526 | d1 = AU1500_GPIO3_INT; | ||
527 | s0 = AU1500_GPIO1_INT; | ||
528 | s1 = AU1500_GPIO4_INT; | ||
529 | } else if (board == BCSR_WHOAMI_DB1100) { | ||
530 | c0 = AU1100_GPIO2_INT; | ||
531 | c1 = AU1100_GPIO5_INT; | ||
532 | d0 = AU1100_GPIO0_INT; | ||
533 | d1 = AU1100_GPIO3_INT; | ||
534 | s0 = AU1100_GPIO1_INT; | ||
535 | s1 = AU1100_GPIO4_INT; | ||
536 | |||
537 | gpio_direction_input(19); /* sd0 cd# */ | ||
538 | gpio_direction_input(20); /* sd1 cd# */ | ||
539 | gpio_direction_input(21); /* touch pendown# */ | ||
540 | gpio_direction_input(207); /* SPI MISO */ | ||
541 | gpio_direction_output(208, 0); /* SPI MOSI */ | ||
542 | gpio_direction_output(209, 1); /* SPI SCK */ | ||
543 | gpio_direction_output(210, 1); /* SPI CS# */ | ||
544 | |||
545 | /* spi_gpio on SSI0 pins */ | ||
546 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | ||
547 | pfc |= (1 << 0); /* SSI0 pins as GPIOs */ | ||
548 | __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | ||
549 | wmb(); | ||
550 | |||
551 | spi_register_board_info(db1100_spi_info, | ||
552 | ARRAY_SIZE(db1100_spi_info)); | ||
553 | |||
554 | platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); | ||
555 | platform_device_register(&db1100_spi_dev); | ||
556 | } else if (board == BCSR_WHOAMI_DB1000) { | ||
557 | c0 = AU1000_GPIO2_INT; | ||
558 | c1 = AU1000_GPIO5_INT; | ||
559 | d0 = AU1000_GPIO0_INT; | ||
560 | d1 = AU1000_GPIO3_INT; | ||
561 | s0 = AU1000_GPIO1_INT; | ||
562 | s1 = AU1000_GPIO4_INT; | ||
563 | platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs)); | ||
564 | } else if ((board == BCSR_WHOAMI_PB1500) || | ||
565 | (board == BCSR_WHOAMI_PB1500R2)) { | ||
566 | c0 = AU1500_GPIO203_INT; | ||
567 | d0 = AU1500_GPIO201_INT; | ||
568 | s0 = AU1500_GPIO202_INT; | ||
569 | twosocks = 0; | ||
570 | flashsize = 64; | ||
571 | /* RTC and daughtercard irqs */ | ||
572 | irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_LOW); | ||
573 | irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW); | ||
574 | /* EPSON S1D13806 0x1b000000 | ||
575 | * SRAM 1MB/2MB 0x1a000000 | ||
576 | * DS1693 RTC 0x0c000000 | ||
577 | */ | ||
578 | } else if (board == BCSR_WHOAMI_PB1100) { | ||
579 | c0 = AU1100_GPIO11_INT; | ||
580 | d0 = AU1100_GPIO9_INT; | ||
581 | s0 = AU1100_GPIO10_INT; | ||
582 | twosocks = 0; | ||
583 | flashsize = 64; | ||
584 | /* pendown, rtc, daughtercard irqs */ | ||
585 | irq_set_irq_type(AU1100_GPIO8_INT, IRQ_TYPE_LEVEL_LOW); | ||
586 | irq_set_irq_type(AU1100_GPIO12_INT, IRQ_TYPE_LEVEL_LOW); | ||
587 | irq_set_irq_type(AU1100_GPIO13_INT, IRQ_TYPE_LEVEL_LOW); | ||
588 | /* EPSON S1D13806 0x1b000000 | ||
589 | * SRAM 1MB/2MB 0x1a000000 | ||
590 | * DiskOnChip 0x0d000000 | ||
591 | * DS1693 RTC 0x0c000000 | ||
592 | */ | ||
593 | platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); | ||
594 | } else | ||
595 | return 0; /* unknown board, no further dev setup to do */ | ||
596 | |||
597 | irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH); | ||
598 | irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW); | ||
599 | irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW); | ||
600 | |||
601 | db1x_register_pcmcia_socket( | ||
602 | AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
603 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | ||
604 | AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
605 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | ||
606 | AU1000_PCMCIA_IO_PHYS_ADDR, | ||
607 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | ||
608 | c0, d0, /*s0*/0, 0, 0); | ||
609 | |||
610 | if (twosocks) { | ||
611 | irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH); | ||
612 | irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW); | ||
613 | irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW); | ||
614 | |||
615 | db1x_register_pcmcia_socket( | ||
616 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | ||
617 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, | ||
618 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, | ||
619 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, | ||
620 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, | ||
621 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, | ||
622 | c1, d1, /*s1*/0, 0, 1); | ||
623 | } | ||
624 | |||
625 | platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs)); | ||
626 | db1x_register_norflash(flashsize << 20, 4 /* 32bit */, F_SWAPPED); | ||
627 | return 0; | ||
628 | } | ||
629 | device_initcall(db1000_dev_init); | ||
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c deleted file mode 100644 index 299b7d202be..00000000000 --- a/arch/mips/alchemy/devboards/db1200.c +++ /dev/null | |||
@@ -1,908 +0,0 @@ | |||
1 | /* | ||
2 | * DBAu1200/PBAu1200 board platform device registration | ||
3 | * | ||
4 | * Copyright (C) 2008-2011 Manuel Lauss | ||
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; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/io.h> | ||
28 | #include <linux/leds.h> | ||
29 | #include <linux/mmc/host.h> | ||
30 | #include <linux/mtd/mtd.h> | ||
31 | #include <linux/mtd/nand.h> | ||
32 | #include <linux/mtd/partitions.h> | ||
33 | #include <linux/platform_device.h> | ||
34 | #include <linux/serial_8250.h> | ||
35 | #include <linux/spi/spi.h> | ||
36 | #include <linux/spi/flash.h> | ||
37 | #include <linux/smc91x.h> | ||
38 | #include <asm/mach-au1x00/au1000.h> | ||
39 | #include <asm/mach-au1x00/au1100_mmc.h> | ||
40 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
41 | #include <asm/mach-au1x00/au1200fb.h> | ||
42 | #include <asm/mach-au1x00/au1550_spi.h> | ||
43 | #include <asm/mach-db1x00/bcsr.h> | ||
44 | #include <asm/mach-db1x00/db1200.h> | ||
45 | |||
46 | #include "platform.h" | ||
47 | |||
48 | const char *get_system_type(void); | ||
49 | |||
50 | static int __init db1200_detect_board(void) | ||
51 | { | ||
52 | int bid; | ||
53 | |||
54 | /* try the DB1200 first */ | ||
55 | bcsr_init(DB1200_BCSR_PHYS_ADDR, | ||
56 | DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS); | ||
57 | if (BCSR_WHOAMI_DB1200 == BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { | ||
58 | unsigned short t = bcsr_read(BCSR_HEXLEDS); | ||
59 | bcsr_write(BCSR_HEXLEDS, ~t); | ||
60 | if (bcsr_read(BCSR_HEXLEDS) != t) { | ||
61 | bcsr_write(BCSR_HEXLEDS, t); | ||
62 | return 0; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | /* okay, try the PB1200 then */ | ||
67 | bcsr_init(PB1200_BCSR_PHYS_ADDR, | ||
68 | PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS); | ||
69 | bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | ||
70 | if ((bid == BCSR_WHOAMI_PB1200_DDR1) || | ||
71 | (bid == BCSR_WHOAMI_PB1200_DDR2)) { | ||
72 | unsigned short t = bcsr_read(BCSR_HEXLEDS); | ||
73 | bcsr_write(BCSR_HEXLEDS, ~t); | ||
74 | if (bcsr_read(BCSR_HEXLEDS) != t) { | ||
75 | bcsr_write(BCSR_HEXLEDS, t); | ||
76 | return 0; | ||
77 | } | ||
78 | } | ||
79 | |||
80 | return 1; /* it's neither */ | ||
81 | } | ||
82 | |||
83 | int __init db1200_board_setup(void) | ||
84 | { | ||
85 | unsigned long freq0, clksrc, div, pfc; | ||
86 | unsigned short whoami; | ||
87 | |||
88 | if (db1200_detect_board()) | ||
89 | return -ENODEV; | ||
90 | |||
91 | whoami = bcsr_read(BCSR_WHOAMI); | ||
92 | printk(KERN_INFO "Alchemy/AMD/RMI %s Board, CPLD Rev %d" | ||
93 | " Board-ID %d Daughtercard ID %d\n", get_system_type(), | ||
94 | (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); | ||
95 | |||
96 | /* SMBus/SPI on PSC0, Audio on PSC1 */ | ||
97 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | ||
98 | pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B); | ||
99 | pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3); | ||
100 | pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */ | ||
101 | __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | ||
102 | wmb(); | ||
103 | |||
104 | /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from | ||
105 | * CPU clock; all other clock generators off/unused. | ||
106 | */ | ||
107 | div = (get_au1x00_speed() + 25000000) / 50000000; | ||
108 | if (div & 1) | ||
109 | div++; | ||
110 | div = ((div >> 1) - 1) & 0xff; | ||
111 | |||
112 | freq0 = div << SYS_FC_FRDIV0_BIT; | ||
113 | __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0); | ||
114 | wmb(); | ||
115 | freq0 |= SYS_FC_FE0; /* enable F0 */ | ||
116 | __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0); | ||
117 | wmb(); | ||
118 | |||
119 | /* psc0_intclk comes 1:1 from F0 */ | ||
120 | clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT; | ||
121 | __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC); | ||
122 | wmb(); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | /******************************************************************************/ | ||
128 | |||
129 | static struct mtd_partition db1200_spiflash_parts[] = { | ||
130 | { | ||
131 | .name = "spi_flash", | ||
132 | .offset = 0, | ||
133 | .size = MTDPART_SIZ_FULL, | ||
134 | }, | ||
135 | }; | ||
136 | |||
137 | static struct flash_platform_data db1200_spiflash_data = { | ||
138 | .name = "s25fl001", | ||
139 | .parts = db1200_spiflash_parts, | ||
140 | .nr_parts = ARRAY_SIZE(db1200_spiflash_parts), | ||
141 | .type = "m25p10", | ||
142 | }; | ||
143 | |||
144 | static struct spi_board_info db1200_spi_devs[] __initdata = { | ||
145 | { | ||
146 | /* TI TMP121AIDBVR temp sensor */ | ||
147 | .modalias = "tmp121", | ||
148 | .max_speed_hz = 2000000, | ||
149 | .bus_num = 0, | ||
150 | .chip_select = 0, | ||
151 | .mode = 0, | ||
152 | }, | ||
153 | { | ||
154 | /* Spansion S25FL001D0FMA SPI flash */ | ||
155 | .modalias = "m25p80", | ||
156 | .max_speed_hz = 50000000, | ||
157 | .bus_num = 0, | ||
158 | .chip_select = 1, | ||
159 | .mode = 0, | ||
160 | .platform_data = &db1200_spiflash_data, | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | static struct i2c_board_info db1200_i2c_devs[] __initdata = { | ||
165 | { I2C_BOARD_INFO("24c04", 0x52), }, /* AT24C04-10 I2C eeprom */ | ||
166 | { I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */ | ||
167 | { I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec WM8731 */ | ||
168 | }; | ||
169 | |||
170 | /**********************************************************************/ | ||
171 | |||
172 | static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
173 | unsigned int ctrl) | ||
174 | { | ||
175 | struct nand_chip *this = mtd->priv; | ||
176 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; | ||
177 | |||
178 | ioaddr &= 0xffffff00; | ||
179 | |||
180 | if (ctrl & NAND_CLE) { | ||
181 | ioaddr += MEM_STNAND_CMD; | ||
182 | } else if (ctrl & NAND_ALE) { | ||
183 | ioaddr += MEM_STNAND_ADDR; | ||
184 | } else { | ||
185 | /* assume we want to r/w real data by default */ | ||
186 | ioaddr += MEM_STNAND_DATA; | ||
187 | } | ||
188 | this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr; | ||
189 | if (cmd != NAND_CMD_NONE) { | ||
190 | __raw_writeb(cmd, this->IO_ADDR_W); | ||
191 | wmb(); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static int au1200_nand_device_ready(struct mtd_info *mtd) | ||
196 | { | ||
197 | return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | ||
198 | } | ||
199 | |||
200 | static struct mtd_partition db1200_nand_parts[] = { | ||
201 | { | ||
202 | .name = "NAND FS 0", | ||
203 | .offset = 0, | ||
204 | .size = 8 * 1024 * 1024, | ||
205 | }, | ||
206 | { | ||
207 | .name = "NAND FS 1", | ||
208 | .offset = MTDPART_OFS_APPEND, | ||
209 | .size = MTDPART_SIZ_FULL | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | struct platform_nand_data db1200_nand_platdata = { | ||
214 | .chip = { | ||
215 | .nr_chips = 1, | ||
216 | .chip_offset = 0, | ||
217 | .nr_partitions = ARRAY_SIZE(db1200_nand_parts), | ||
218 | .partitions = db1200_nand_parts, | ||
219 | .chip_delay = 20, | ||
220 | }, | ||
221 | .ctrl = { | ||
222 | .dev_ready = au1200_nand_device_ready, | ||
223 | .cmd_ctrl = au1200_nand_cmd_ctrl, | ||
224 | }, | ||
225 | }; | ||
226 | |||
227 | static struct resource db1200_nand_res[] = { | ||
228 | [0] = { | ||
229 | .start = DB1200_NAND_PHYS_ADDR, | ||
230 | .end = DB1200_NAND_PHYS_ADDR + 0xff, | ||
231 | .flags = IORESOURCE_MEM, | ||
232 | }, | ||
233 | }; | ||
234 | |||
235 | static struct platform_device db1200_nand_dev = { | ||
236 | .name = "gen_nand", | ||
237 | .num_resources = ARRAY_SIZE(db1200_nand_res), | ||
238 | .resource = db1200_nand_res, | ||
239 | .id = -1, | ||
240 | .dev = { | ||
241 | .platform_data = &db1200_nand_platdata, | ||
242 | } | ||
243 | }; | ||
244 | |||
245 | /**********************************************************************/ | ||
246 | |||
247 | static struct smc91x_platdata db1200_eth_data = { | ||
248 | .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT, | ||
249 | .leda = RPC_LED_100_10, | ||
250 | .ledb = RPC_LED_TX_RX, | ||
251 | }; | ||
252 | |||
253 | static struct resource db1200_eth_res[] = { | ||
254 | [0] = { | ||
255 | .start = DB1200_ETH_PHYS_ADDR, | ||
256 | .end = DB1200_ETH_PHYS_ADDR + 0xf, | ||
257 | .flags = IORESOURCE_MEM, | ||
258 | }, | ||
259 | [1] = { | ||
260 | .start = DB1200_ETH_INT, | ||
261 | .end = DB1200_ETH_INT, | ||
262 | .flags = IORESOURCE_IRQ, | ||
263 | }, | ||
264 | }; | ||
265 | |||
266 | static struct platform_device db1200_eth_dev = { | ||
267 | .dev = { | ||
268 | .platform_data = &db1200_eth_data, | ||
269 | }, | ||
270 | .name = "smc91x", | ||
271 | .id = -1, | ||
272 | .num_resources = ARRAY_SIZE(db1200_eth_res), | ||
273 | .resource = db1200_eth_res, | ||
274 | }; | ||
275 | |||
276 | /**********************************************************************/ | ||
277 | |||
278 | static struct resource db1200_ide_res[] = { | ||
279 | [0] = { | ||
280 | .start = DB1200_IDE_PHYS_ADDR, | ||
281 | .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1, | ||
282 | .flags = IORESOURCE_MEM, | ||
283 | }, | ||
284 | [1] = { | ||
285 | .start = DB1200_IDE_INT, | ||
286 | .end = DB1200_IDE_INT, | ||
287 | .flags = IORESOURCE_IRQ, | ||
288 | }, | ||
289 | [2] = { | ||
290 | .start = AU1200_DSCR_CMD0_DMA_REQ1, | ||
291 | .end = AU1200_DSCR_CMD0_DMA_REQ1, | ||
292 | .flags = IORESOURCE_DMA, | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | static u64 au1200_ide_dmamask = DMA_BIT_MASK(32); | ||
297 | |||
298 | static struct platform_device db1200_ide_dev = { | ||
299 | .name = "au1200-ide", | ||
300 | .id = 0, | ||
301 | .dev = { | ||
302 | .dma_mask = &au1200_ide_dmamask, | ||
303 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
304 | }, | ||
305 | .num_resources = ARRAY_SIZE(db1200_ide_res), | ||
306 | .resource = db1200_ide_res, | ||
307 | }; | ||
308 | |||
309 | /**********************************************************************/ | ||
310 | |||
311 | /* SD carddetects: they're supposed to be edge-triggered, but ack | ||
312 | * doesn't seem to work (CPLD Rev 2). Instead, the screaming one | ||
313 | * is disabled and its counterpart enabled. The 500ms timeout is | ||
314 | * because the carddetect isn't debounced in hardware. | ||
315 | */ | ||
316 | static irqreturn_t db1200_mmc_cd(int irq, void *ptr) | ||
317 | { | ||
318 | void(*mmc_cd)(struct mmc_host *, unsigned long); | ||
319 | |||
320 | if (irq == DB1200_SD0_INSERT_INT) { | ||
321 | disable_irq_nosync(DB1200_SD0_INSERT_INT); | ||
322 | enable_irq(DB1200_SD0_EJECT_INT); | ||
323 | } else { | ||
324 | disable_irq_nosync(DB1200_SD0_EJECT_INT); | ||
325 | enable_irq(DB1200_SD0_INSERT_INT); | ||
326 | } | ||
327 | |||
328 | /* link against CONFIG_MMC=m */ | ||
329 | mmc_cd = symbol_get(mmc_detect_change); | ||
330 | if (mmc_cd) { | ||
331 | mmc_cd(ptr, msecs_to_jiffies(500)); | ||
332 | symbol_put(mmc_detect_change); | ||
333 | } | ||
334 | |||
335 | return IRQ_HANDLED; | ||
336 | } | ||
337 | |||
338 | static int db1200_mmc_cd_setup(void *mmc_host, int en) | ||
339 | { | ||
340 | int ret; | ||
341 | |||
342 | if (en) { | ||
343 | ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd, | ||
344 | 0, "sd_insert", mmc_host); | ||
345 | if (ret) | ||
346 | goto out; | ||
347 | |||
348 | ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd, | ||
349 | 0, "sd_eject", mmc_host); | ||
350 | if (ret) { | ||
351 | free_irq(DB1200_SD0_INSERT_INT, mmc_host); | ||
352 | goto out; | ||
353 | } | ||
354 | |||
355 | if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) | ||
356 | enable_irq(DB1200_SD0_EJECT_INT); | ||
357 | else | ||
358 | enable_irq(DB1200_SD0_INSERT_INT); | ||
359 | |||
360 | } else { | ||
361 | free_irq(DB1200_SD0_INSERT_INT, mmc_host); | ||
362 | free_irq(DB1200_SD0_EJECT_INT, mmc_host); | ||
363 | } | ||
364 | ret = 0; | ||
365 | out: | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | static void db1200_mmc_set_power(void *mmc_host, int state) | ||
370 | { | ||
371 | if (state) { | ||
372 | bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR); | ||
373 | msleep(400); /* stabilization time */ | ||
374 | } else | ||
375 | bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0); | ||
376 | } | ||
377 | |||
378 | static int db1200_mmc_card_readonly(void *mmc_host) | ||
379 | { | ||
380 | return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0; | ||
381 | } | ||
382 | |||
383 | static int db1200_mmc_card_inserted(void *mmc_host) | ||
384 | { | ||
385 | return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0; | ||
386 | } | ||
387 | |||
388 | static void db1200_mmcled_set(struct led_classdev *led, | ||
389 | enum led_brightness brightness) | ||
390 | { | ||
391 | if (brightness != LED_OFF) | ||
392 | bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0); | ||
393 | else | ||
394 | bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0); | ||
395 | } | ||
396 | |||
397 | static struct led_classdev db1200_mmc_led = { | ||
398 | .brightness_set = db1200_mmcled_set, | ||
399 | }; | ||
400 | |||
401 | /* -- */ | ||
402 | |||
403 | static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr) | ||
404 | { | ||
405 | void(*mmc_cd)(struct mmc_host *, unsigned long); | ||
406 | |||
407 | if (irq == PB1200_SD1_INSERT_INT) { | ||
408 | disable_irq_nosync(PB1200_SD1_INSERT_INT); | ||
409 | enable_irq(PB1200_SD1_EJECT_INT); | ||
410 | } else { | ||
411 | disable_irq_nosync(PB1200_SD1_EJECT_INT); | ||
412 | enable_irq(PB1200_SD1_INSERT_INT); | ||
413 | } | ||
414 | |||
415 | /* link against CONFIG_MMC=m */ | ||
416 | mmc_cd = symbol_get(mmc_detect_change); | ||
417 | if (mmc_cd) { | ||
418 | mmc_cd(ptr, msecs_to_jiffies(500)); | ||
419 | symbol_put(mmc_detect_change); | ||
420 | } | ||
421 | |||
422 | return IRQ_HANDLED; | ||
423 | } | ||
424 | |||
425 | static int pb1200_mmc1_cd_setup(void *mmc_host, int en) | ||
426 | { | ||
427 | int ret; | ||
428 | |||
429 | if (en) { | ||
430 | ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0, | ||
431 | "sd1_insert", mmc_host); | ||
432 | if (ret) | ||
433 | goto out; | ||
434 | |||
435 | ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0, | ||
436 | "sd1_eject", mmc_host); | ||
437 | if (ret) { | ||
438 | free_irq(PB1200_SD1_INSERT_INT, mmc_host); | ||
439 | goto out; | ||
440 | } | ||
441 | |||
442 | if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) | ||
443 | enable_irq(PB1200_SD1_EJECT_INT); | ||
444 | else | ||
445 | enable_irq(PB1200_SD1_INSERT_INT); | ||
446 | |||
447 | } else { | ||
448 | free_irq(PB1200_SD1_INSERT_INT, mmc_host); | ||
449 | free_irq(PB1200_SD1_EJECT_INT, mmc_host); | ||
450 | } | ||
451 | ret = 0; | ||
452 | out: | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | static void pb1200_mmc1led_set(struct led_classdev *led, | ||
457 | enum led_brightness brightness) | ||
458 | { | ||
459 | if (brightness != LED_OFF) | ||
460 | bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0); | ||
461 | else | ||
462 | bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1); | ||
463 | } | ||
464 | |||
465 | static struct led_classdev pb1200_mmc1_led = { | ||
466 | .brightness_set = pb1200_mmc1led_set, | ||
467 | }; | ||
468 | |||
469 | static void pb1200_mmc1_set_power(void *mmc_host, int state) | ||
470 | { | ||
471 | if (state) { | ||
472 | bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR); | ||
473 | msleep(400); /* stabilization time */ | ||
474 | } else | ||
475 | bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0); | ||
476 | } | ||
477 | |||
478 | static int pb1200_mmc1_card_readonly(void *mmc_host) | ||
479 | { | ||
480 | return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0; | ||
481 | } | ||
482 | |||
483 | static int pb1200_mmc1_card_inserted(void *mmc_host) | ||
484 | { | ||
485 | return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0; | ||
486 | } | ||
487 | |||
488 | |||
489 | static struct au1xmmc_platform_data db1200_mmc_platdata[2] = { | ||
490 | [0] = { | ||
491 | .cd_setup = db1200_mmc_cd_setup, | ||
492 | .set_power = db1200_mmc_set_power, | ||
493 | .card_inserted = db1200_mmc_card_inserted, | ||
494 | .card_readonly = db1200_mmc_card_readonly, | ||
495 | .led = &db1200_mmc_led, | ||
496 | }, | ||
497 | [1] = { | ||
498 | .cd_setup = pb1200_mmc1_cd_setup, | ||
499 | .set_power = pb1200_mmc1_set_power, | ||
500 | .card_inserted = pb1200_mmc1_card_inserted, | ||
501 | .card_readonly = pb1200_mmc1_card_readonly, | ||
502 | .led = &pb1200_mmc1_led, | ||
503 | }, | ||
504 | }; | ||
505 | |||
506 | static struct resource au1200_mmc0_resources[] = { | ||
507 | [0] = { | ||
508 | .start = AU1100_SD0_PHYS_ADDR, | ||
509 | .end = AU1100_SD0_PHYS_ADDR + 0xfff, | ||
510 | .flags = IORESOURCE_MEM, | ||
511 | }, | ||
512 | [1] = { | ||
513 | .start = AU1200_SD_INT, | ||
514 | .end = AU1200_SD_INT, | ||
515 | .flags = IORESOURCE_IRQ, | ||
516 | }, | ||
517 | [2] = { | ||
518 | .start = AU1200_DSCR_CMD0_SDMS_TX0, | ||
519 | .end = AU1200_DSCR_CMD0_SDMS_TX0, | ||
520 | .flags = IORESOURCE_DMA, | ||
521 | }, | ||
522 | [3] = { | ||
523 | .start = AU1200_DSCR_CMD0_SDMS_RX0, | ||
524 | .end = AU1200_DSCR_CMD0_SDMS_RX0, | ||
525 | .flags = IORESOURCE_DMA, | ||
526 | } | ||
527 | }; | ||
528 | |||
529 | static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32); | ||
530 | |||
531 | static struct platform_device db1200_mmc0_dev = { | ||
532 | .name = "au1xxx-mmc", | ||
533 | .id = 0, | ||
534 | .dev = { | ||
535 | .dma_mask = &au1xxx_mmc_dmamask, | ||
536 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
537 | .platform_data = &db1200_mmc_platdata[0], | ||
538 | }, | ||
539 | .num_resources = ARRAY_SIZE(au1200_mmc0_resources), | ||
540 | .resource = au1200_mmc0_resources, | ||
541 | }; | ||
542 | |||
543 | static struct resource au1200_mmc1_res[] = { | ||
544 | [0] = { | ||
545 | .start = AU1100_SD1_PHYS_ADDR, | ||
546 | .end = AU1100_SD1_PHYS_ADDR + 0xfff, | ||
547 | .flags = IORESOURCE_MEM, | ||
548 | }, | ||
549 | [1] = { | ||
550 | .start = AU1200_SD_INT, | ||
551 | .end = AU1200_SD_INT, | ||
552 | .flags = IORESOURCE_IRQ, | ||
553 | }, | ||
554 | [2] = { | ||
555 | .start = AU1200_DSCR_CMD0_SDMS_TX1, | ||
556 | .end = AU1200_DSCR_CMD0_SDMS_TX1, | ||
557 | .flags = IORESOURCE_DMA, | ||
558 | }, | ||
559 | [3] = { | ||
560 | .start = AU1200_DSCR_CMD0_SDMS_RX1, | ||
561 | .end = AU1200_DSCR_CMD0_SDMS_RX1, | ||
562 | .flags = IORESOURCE_DMA, | ||
563 | } | ||
564 | }; | ||
565 | |||
566 | static struct platform_device pb1200_mmc1_dev = { | ||
567 | .name = "au1xxx-mmc", | ||
568 | .id = 1, | ||
569 | .dev = { | ||
570 | .dma_mask = &au1xxx_mmc_dmamask, | ||
571 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
572 | .platform_data = &db1200_mmc_platdata[1], | ||
573 | }, | ||
574 | .num_resources = ARRAY_SIZE(au1200_mmc1_res), | ||
575 | .resource = au1200_mmc1_res, | ||
576 | }; | ||
577 | |||
578 | /**********************************************************************/ | ||
579 | |||
580 | static int db1200fb_panel_index(void) | ||
581 | { | ||
582 | return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f; | ||
583 | } | ||
584 | |||
585 | static int db1200fb_panel_init(void) | ||
586 | { | ||
587 | /* Apply power */ | ||
588 | bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | | ||
589 | BCSR_BOARD_LCDBL); | ||
590 | return 0; | ||
591 | } | ||
592 | |||
593 | static int db1200fb_panel_shutdown(void) | ||
594 | { | ||
595 | /* Remove power */ | ||
596 | bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD | | ||
597 | BCSR_BOARD_LCDBL, 0); | ||
598 | return 0; | ||
599 | } | ||
600 | |||
601 | static struct au1200fb_platdata db1200fb_pd = { | ||
602 | .panel_index = db1200fb_panel_index, | ||
603 | .panel_init = db1200fb_panel_init, | ||
604 | .panel_shutdown = db1200fb_panel_shutdown, | ||
605 | }; | ||
606 | |||
607 | static struct resource au1200_lcd_res[] = { | ||
608 | [0] = { | ||
609 | .start = AU1200_LCD_PHYS_ADDR, | ||
610 | .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1, | ||
611 | .flags = IORESOURCE_MEM, | ||
612 | }, | ||
613 | [1] = { | ||
614 | .start = AU1200_LCD_INT, | ||
615 | .end = AU1200_LCD_INT, | ||
616 | .flags = IORESOURCE_IRQ, | ||
617 | } | ||
618 | }; | ||
619 | |||
620 | static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32); | ||
621 | |||
622 | static struct platform_device au1200_lcd_dev = { | ||
623 | .name = "au1200-lcd", | ||
624 | .id = 0, | ||
625 | .dev = { | ||
626 | .dma_mask = &au1200_lcd_dmamask, | ||
627 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
628 | .platform_data = &db1200fb_pd, | ||
629 | }, | ||
630 | .num_resources = ARRAY_SIZE(au1200_lcd_res), | ||
631 | .resource = au1200_lcd_res, | ||
632 | }; | ||
633 | |||
634 | /**********************************************************************/ | ||
635 | |||
636 | static struct resource au1200_psc0_res[] = { | ||
637 | [0] = { | ||
638 | .start = AU1550_PSC0_PHYS_ADDR, | ||
639 | .end = AU1550_PSC0_PHYS_ADDR + 0xfff, | ||
640 | .flags = IORESOURCE_MEM, | ||
641 | }, | ||
642 | [1] = { | ||
643 | .start = AU1200_PSC0_INT, | ||
644 | .end = AU1200_PSC0_INT, | ||
645 | .flags = IORESOURCE_IRQ, | ||
646 | }, | ||
647 | [2] = { | ||
648 | .start = AU1200_DSCR_CMD0_PSC0_TX, | ||
649 | .end = AU1200_DSCR_CMD0_PSC0_TX, | ||
650 | .flags = IORESOURCE_DMA, | ||
651 | }, | ||
652 | [3] = { | ||
653 | .start = AU1200_DSCR_CMD0_PSC0_RX, | ||
654 | .end = AU1200_DSCR_CMD0_PSC0_RX, | ||
655 | .flags = IORESOURCE_DMA, | ||
656 | }, | ||
657 | }; | ||
658 | |||
659 | static struct platform_device db1200_i2c_dev = { | ||
660 | .name = "au1xpsc_smbus", | ||
661 | .id = 0, /* bus number */ | ||
662 | .num_resources = ARRAY_SIZE(au1200_psc0_res), | ||
663 | .resource = au1200_psc0_res, | ||
664 | }; | ||
665 | |||
666 | static void db1200_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol) | ||
667 | { | ||
668 | if (cs) | ||
669 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_SPISEL); | ||
670 | else | ||
671 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_SPISEL, 0); | ||
672 | } | ||
673 | |||
674 | static struct au1550_spi_info db1200_spi_platdata = { | ||
675 | .mainclk_hz = 50000000, /* PSC0 clock */ | ||
676 | .num_chipselect = 2, | ||
677 | .activate_cs = db1200_spi_cs_en, | ||
678 | }; | ||
679 | |||
680 | static u64 spi_dmamask = DMA_BIT_MASK(32); | ||
681 | |||
682 | static struct platform_device db1200_spi_dev = { | ||
683 | .dev = { | ||
684 | .dma_mask = &spi_dmamask, | ||
685 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
686 | .platform_data = &db1200_spi_platdata, | ||
687 | }, | ||
688 | .name = "au1550-spi", | ||
689 | .id = 0, /* bus number */ | ||
690 | .num_resources = ARRAY_SIZE(au1200_psc0_res), | ||
691 | .resource = au1200_psc0_res, | ||
692 | }; | ||
693 | |||
694 | static struct resource au1200_psc1_res[] = { | ||
695 | [0] = { | ||
696 | .start = AU1550_PSC1_PHYS_ADDR, | ||
697 | .end = AU1550_PSC1_PHYS_ADDR + 0xfff, | ||
698 | .flags = IORESOURCE_MEM, | ||
699 | }, | ||
700 | [1] = { | ||
701 | .start = AU1200_PSC1_INT, | ||
702 | .end = AU1200_PSC1_INT, | ||
703 | .flags = IORESOURCE_IRQ, | ||
704 | }, | ||
705 | [2] = { | ||
706 | .start = AU1200_DSCR_CMD0_PSC1_TX, | ||
707 | .end = AU1200_DSCR_CMD0_PSC1_TX, | ||
708 | .flags = IORESOURCE_DMA, | ||
709 | }, | ||
710 | [3] = { | ||
711 | .start = AU1200_DSCR_CMD0_PSC1_RX, | ||
712 | .end = AU1200_DSCR_CMD0_PSC1_RX, | ||
713 | .flags = IORESOURCE_DMA, | ||
714 | }, | ||
715 | }; | ||
716 | |||
717 | /* AC97 or I2S device */ | ||
718 | static struct platform_device db1200_audio_dev = { | ||
719 | /* name assigned later based on switch setting */ | ||
720 | .id = 1, /* PSC ID */ | ||
721 | .num_resources = ARRAY_SIZE(au1200_psc1_res), | ||
722 | .resource = au1200_psc1_res, | ||
723 | }; | ||
724 | |||
725 | /* DB1200 ASoC card device */ | ||
726 | static struct platform_device db1200_sound_dev = { | ||
727 | /* name assigned later based on switch setting */ | ||
728 | .id = 1, /* PSC ID */ | ||
729 | }; | ||
730 | |||
731 | static struct platform_device db1200_stac_dev = { | ||
732 | .name = "ac97-codec", | ||
733 | .id = 1, /* on PSC1 */ | ||
734 | }; | ||
735 | |||
736 | static struct platform_device db1200_audiodma_dev = { | ||
737 | .name = "au1xpsc-pcm", | ||
738 | .id = 1, /* PSC ID */ | ||
739 | }; | ||
740 | |||
741 | static struct platform_device *db1200_devs[] __initdata = { | ||
742 | NULL, /* PSC0, selected by S6.8 */ | ||
743 | &db1200_ide_dev, | ||
744 | &db1200_mmc0_dev, | ||
745 | &au1200_lcd_dev, | ||
746 | &db1200_eth_dev, | ||
747 | &db1200_nand_dev, | ||
748 | &db1200_audiodma_dev, | ||
749 | &db1200_audio_dev, | ||
750 | &db1200_stac_dev, | ||
751 | &db1200_sound_dev, | ||
752 | }; | ||
753 | |||
754 | static struct platform_device *pb1200_devs[] __initdata = { | ||
755 | &pb1200_mmc1_dev, | ||
756 | }; | ||
757 | |||
758 | /* Some peripheral base addresses differ on the PB1200 */ | ||
759 | static int __init pb1200_res_fixup(void) | ||
760 | { | ||
761 | /* CPLD Revs earlier than 4 cause problems */ | ||
762 | if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) { | ||
763 | printk(KERN_ERR "WARNING!!!\n"); | ||
764 | printk(KERN_ERR "WARNING!!!\n"); | ||
765 | printk(KERN_ERR "PB1200 must be at CPLD rev 4. Please have\n"); | ||
766 | printk(KERN_ERR "the board updated to latest revisions.\n"); | ||
767 | printk(KERN_ERR "This software will not work reliably\n"); | ||
768 | printk(KERN_ERR "on anything older than CPLD rev 4.!\n"); | ||
769 | printk(KERN_ERR "WARNING!!!\n"); | ||
770 | printk(KERN_ERR "WARNING!!!\n"); | ||
771 | return 1; | ||
772 | } | ||
773 | |||
774 | db1200_nand_res[0].start = PB1200_NAND_PHYS_ADDR; | ||
775 | db1200_nand_res[0].end = PB1200_NAND_PHYS_ADDR + 0xff; | ||
776 | db1200_ide_res[0].start = PB1200_IDE_PHYS_ADDR; | ||
777 | db1200_ide_res[0].end = PB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1; | ||
778 | db1200_eth_res[0].start = PB1200_ETH_PHYS_ADDR; | ||
779 | db1200_eth_res[0].end = PB1200_ETH_PHYS_ADDR + 0xff; | ||
780 | return 0; | ||
781 | } | ||
782 | |||
783 | int __init db1200_dev_setup(void) | ||
784 | { | ||
785 | unsigned long pfc; | ||
786 | unsigned short sw; | ||
787 | int swapped, bid; | ||
788 | |||
789 | bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | ||
790 | if ((bid == BCSR_WHOAMI_PB1200_DDR1) || | ||
791 | (bid == BCSR_WHOAMI_PB1200_DDR2)) { | ||
792 | if (pb1200_res_fixup()) | ||
793 | return -ENODEV; | ||
794 | } | ||
795 | |||
796 | /* GPIO7 is low-level triggered CPLD cascade */ | ||
797 | irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW); | ||
798 | bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); | ||
799 | |||
800 | /* insert/eject pairs: one of both is always screaming. To avoid | ||
801 | * issues they must not be automatically enabled when initially | ||
802 | * requested. | ||
803 | */ | ||
804 | irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN); | ||
805 | irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN); | ||
806 | irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN); | ||
807 | irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN); | ||
808 | irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN); | ||
809 | irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN); | ||
810 | |||
811 | i2c_register_board_info(0, db1200_i2c_devs, | ||
812 | ARRAY_SIZE(db1200_i2c_devs)); | ||
813 | spi_register_board_info(db1200_spi_devs, | ||
814 | ARRAY_SIZE(db1200_i2c_devs)); | ||
815 | |||
816 | /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) | ||
817 | * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) | ||
818 | * or S12 on the PB1200. | ||
819 | */ | ||
820 | |||
821 | /* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however | ||
822 | * this pin is claimed by PSC0 (unused though, but pinmux doesn't | ||
823 | * allow to free it without crippling the SPI interface). | ||
824 | * As a result, in SPI mode, OTG simply won't work (PSC0 uses | ||
825 | * it as an input pin which is pulled high on the boards). | ||
826 | */ | ||
827 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A; | ||
828 | |||
829 | /* switch off OTG VBUS supply */ | ||
830 | gpio_request(215, "otg-vbus"); | ||
831 | gpio_direction_output(215, 1); | ||
832 | |||
833 | printk(KERN_INFO "%s device configuration:\n", get_system_type()); | ||
834 | |||
835 | sw = bcsr_read(BCSR_SWITCHES); | ||
836 | if (sw & BCSR_SWITCHES_DIP_8) { | ||
837 | db1200_devs[0] = &db1200_i2c_dev; | ||
838 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0); | ||
839 | |||
840 | pfc |= (2 << 17); /* GPIO2 block owns GPIO215 */ | ||
841 | |||
842 | printk(KERN_INFO " S6.8 OFF: PSC0 mode I2C\n"); | ||
843 | printk(KERN_INFO " OTG port VBUS supply available!\n"); | ||
844 | } else { | ||
845 | db1200_devs[0] = &db1200_spi_dev; | ||
846 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC0MUX); | ||
847 | |||
848 | pfc |= (1 << 17); /* PSC0 owns GPIO215 */ | ||
849 | |||
850 | printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n"); | ||
851 | printk(KERN_INFO " OTG port VBUS supply disabled\n"); | ||
852 | } | ||
853 | __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | ||
854 | wmb(); | ||
855 | |||
856 | /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S! | ||
857 | * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S | ||
858 | */ | ||
859 | sw &= BCSR_SWITCHES_DIP_8 | BCSR_SWITCHES_DIP_7; | ||
860 | if (sw == BCSR_SWITCHES_DIP_8) { | ||
861 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX); | ||
862 | db1200_audio_dev.name = "au1xpsc_i2s"; | ||
863 | db1200_sound_dev.name = "db1200-i2s"; | ||
864 | printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n"); | ||
865 | } else { | ||
866 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0); | ||
867 | db1200_audio_dev.name = "au1xpsc_ac97"; | ||
868 | db1200_sound_dev.name = "db1200-ac97"; | ||
869 | printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n"); | ||
870 | } | ||
871 | |||
872 | /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ | ||
873 | __raw_writel(PSC_SEL_CLK_SERCLK, | ||
874 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
875 | wmb(); | ||
876 | |||
877 | db1x_register_pcmcia_socket( | ||
878 | AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
879 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | ||
880 | AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
881 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | ||
882 | AU1000_PCMCIA_IO_PHYS_ADDR, | ||
883 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | ||
884 | DB1200_PC0_INT, DB1200_PC0_INSERT_INT, | ||
885 | /*DB1200_PC0_STSCHG_INT*/0, DB1200_PC0_EJECT_INT, 0); | ||
886 | |||
887 | db1x_register_pcmcia_socket( | ||
888 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | ||
889 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, | ||
890 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, | ||
891 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, | ||
892 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, | ||
893 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, | ||
894 | DB1200_PC1_INT, DB1200_PC1_INSERT_INT, | ||
895 | /*DB1200_PC1_STSCHG_INT*/0, DB1200_PC1_EJECT_INT, 1); | ||
896 | |||
897 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; | ||
898 | db1x_register_norflash(64 << 20, 2, swapped); | ||
899 | |||
900 | platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs)); | ||
901 | |||
902 | /* PB1200 is a DB1200 with a 2nd MMC and Camera connector */ | ||
903 | if ((bid == BCSR_WHOAMI_PB1200_DDR1) || | ||
904 | (bid == BCSR_WHOAMI_PB1200_DDR2)) | ||
905 | platform_add_devices(pb1200_devs, ARRAY_SIZE(pb1200_devs)); | ||
906 | |||
907 | return 0; | ||
908 | } | ||
diff --git a/arch/mips/alchemy/devboards/db1235.c b/arch/mips/alchemy/devboards/db1235.c deleted file mode 100644 index c76a90f7866..00000000000 --- a/arch/mips/alchemy/devboards/db1235.c +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * DB1200/PB1200 / DB1550 / DB1300 board support. | ||
3 | * | ||
4 | * These 4 boards can reliably be supported in a single kernel image. | ||
5 | */ | ||
6 | |||
7 | #include <asm/mach-au1x00/au1000.h> | ||
8 | #include <asm/mach-db1x00/bcsr.h> | ||
9 | |||
10 | int __init db1200_board_setup(void); | ||
11 | int __init db1200_dev_setup(void); | ||
12 | int __init db1300_board_setup(void); | ||
13 | int __init db1300_dev_setup(void); | ||
14 | int __init db1550_board_setup(void); | ||
15 | int __init db1550_dev_setup(void); | ||
16 | int __init db1550_pci_setup(int); | ||
17 | |||
18 | static const char *board_type_str(void) | ||
19 | { | ||
20 | switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { | ||
21 | case BCSR_WHOAMI_PB1200_DDR1: | ||
22 | case BCSR_WHOAMI_PB1200_DDR2: | ||
23 | return "PB1200"; | ||
24 | case BCSR_WHOAMI_DB1200: | ||
25 | return "DB1200"; | ||
26 | case BCSR_WHOAMI_DB1300: | ||
27 | return "DB1300"; | ||
28 | case BCSR_WHOAMI_DB1550: | ||
29 | return "DB1550"; | ||
30 | case BCSR_WHOAMI_PB1550_SDR: | ||
31 | case BCSR_WHOAMI_PB1550_DDR: | ||
32 | return "PB1550"; | ||
33 | default: | ||
34 | return "(unknown)"; | ||
35 | } | ||
36 | } | ||
37 | |||
38 | const char *get_system_type(void) | ||
39 | { | ||
40 | return board_type_str(); | ||
41 | } | ||
42 | |||
43 | void __init board_setup(void) | ||
44 | { | ||
45 | int ret; | ||
46 | |||
47 | switch (alchemy_get_cputype()) { | ||
48 | case ALCHEMY_CPU_AU1550: | ||
49 | ret = db1550_board_setup(); | ||
50 | break; | ||
51 | case ALCHEMY_CPU_AU1200: | ||
52 | ret = db1200_board_setup(); | ||
53 | break; | ||
54 | case ALCHEMY_CPU_AU1300: | ||
55 | ret = db1300_board_setup(); | ||
56 | break; | ||
57 | default: | ||
58 | pr_err("unsupported CPU on board\n"); | ||
59 | ret = -ENODEV; | ||
60 | } | ||
61 | if (ret) | ||
62 | panic("cannot initialize board support\n"); | ||
63 | } | ||
64 | |||
65 | int __init db1235_arch_init(void) | ||
66 | { | ||
67 | int id = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | ||
68 | if (id == BCSR_WHOAMI_DB1550) | ||
69 | return db1550_pci_setup(0); | ||
70 | else if ((id == BCSR_WHOAMI_PB1550_SDR) || | ||
71 | (id == BCSR_WHOAMI_PB1550_DDR)) | ||
72 | return db1550_pci_setup(1); | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | arch_initcall(db1235_arch_init); | ||
77 | |||
78 | int __init db1235_dev_init(void) | ||
79 | { | ||
80 | switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) { | ||
81 | case BCSR_WHOAMI_PB1200_DDR1: | ||
82 | case BCSR_WHOAMI_PB1200_DDR2: | ||
83 | case BCSR_WHOAMI_DB1200: | ||
84 | return db1200_dev_setup(); | ||
85 | case BCSR_WHOAMI_DB1300: | ||
86 | return db1300_dev_setup(); | ||
87 | case BCSR_WHOAMI_DB1550: | ||
88 | case BCSR_WHOAMI_PB1550_SDR: | ||
89 | case BCSR_WHOAMI_PB1550_DDR: | ||
90 | return db1550_dev_setup(); | ||
91 | } | ||
92 | return 0; | ||
93 | } | ||
94 | device_initcall(db1235_dev_init); | ||
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c deleted file mode 100644 index cdf37cbd3d1..00000000000 --- a/arch/mips/alchemy/devboards/db1300.c +++ /dev/null | |||
@@ -1,778 +0,0 @@ | |||
1 | /* | ||
2 | * DBAu1300 init and platform device setup. | ||
3 | * | ||
4 | * (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/dma-mapping.h> | ||
8 | #include <linux/gpio.h> | ||
9 | #include <linux/gpio_keys.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/input.h> /* KEY_* codes */ | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/leds.h> | ||
15 | #include <linux/ata_platform.h> | ||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mtd/mtd.h> | ||
19 | #include <linux/mtd/nand.h> | ||
20 | #include <linux/mtd/partitions.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/smsc911x.h> | ||
23 | |||
24 | #include <asm/mach-au1x00/au1000.h> | ||
25 | #include <asm/mach-au1x00/au1100_mmc.h> | ||
26 | #include <asm/mach-au1x00/au1200fb.h> | ||
27 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
28 | #include <asm/mach-au1x00/au1xxx_psc.h> | ||
29 | #include <asm/mach-db1x00/db1300.h> | ||
30 | #include <asm/mach-db1x00/bcsr.h> | ||
31 | #include <asm/mach-au1x00/prom.h> | ||
32 | |||
33 | #include "platform.h" | ||
34 | |||
35 | static struct i2c_board_info db1300_i2c_devs[] __initdata = { | ||
36 | { I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec */ | ||
37 | { I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */ | ||
38 | }; | ||
39 | |||
40 | /* multifunction pins to assign to GPIO controller */ | ||
41 | static int db1300_gpio_pins[] __initdata = { | ||
42 | AU1300_PIN_LCDPWM0, AU1300_PIN_PSC2SYNC1, AU1300_PIN_WAKE1, | ||
43 | AU1300_PIN_WAKE2, AU1300_PIN_WAKE3, AU1300_PIN_FG3AUX, | ||
44 | AU1300_PIN_EXTCLK1, | ||
45 | -1, /* terminator */ | ||
46 | }; | ||
47 | |||
48 | /* multifunction pins to assign to device functions */ | ||
49 | static int db1300_dev_pins[] __initdata = { | ||
50 | /* wake-from-str pins 0-3 */ | ||
51 | AU1300_PIN_WAKE0, | ||
52 | /* external clock sources for PSC0 */ | ||
53 | AU1300_PIN_EXTCLK0, | ||
54 | /* 8bit MMC interface on SD0: 6-9 */ | ||
55 | AU1300_PIN_SD0DAT4, AU1300_PIN_SD0DAT5, AU1300_PIN_SD0DAT6, | ||
56 | AU1300_PIN_SD0DAT7, | ||
57 | /* UART1 pins: 11-18 */ | ||
58 | AU1300_PIN_U1RI, AU1300_PIN_U1DCD, AU1300_PIN_U1DSR, | ||
59 | AU1300_PIN_U1CTS, AU1300_PIN_U1RTS, AU1300_PIN_U1DTR, | ||
60 | AU1300_PIN_U1RX, AU1300_PIN_U1TX, | ||
61 | /* UART0 pins: 19-24 */ | ||
62 | AU1300_PIN_U0RI, AU1300_PIN_U0DCD, AU1300_PIN_U0DSR, | ||
63 | AU1300_PIN_U0CTS, AU1300_PIN_U0RTS, AU1300_PIN_U0DTR, | ||
64 | /* UART2: 25-26 */ | ||
65 | AU1300_PIN_U2RX, AU1300_PIN_U2TX, | ||
66 | /* UART3: 27-28 */ | ||
67 | AU1300_PIN_U3RX, AU1300_PIN_U3TX, | ||
68 | /* LCD controller PWMs, ext pixclock: 30-31 */ | ||
69 | AU1300_PIN_LCDPWM1, AU1300_PIN_LCDCLKIN, | ||
70 | /* SD1 interface: 32-37 */ | ||
71 | AU1300_PIN_SD1DAT0, AU1300_PIN_SD1DAT1, AU1300_PIN_SD1DAT2, | ||
72 | AU1300_PIN_SD1DAT3, AU1300_PIN_SD1CMD, AU1300_PIN_SD1CLK, | ||
73 | /* SD2 interface: 38-43 */ | ||
74 | AU1300_PIN_SD2DAT0, AU1300_PIN_SD2DAT1, AU1300_PIN_SD2DAT2, | ||
75 | AU1300_PIN_SD2DAT3, AU1300_PIN_SD2CMD, AU1300_PIN_SD2CLK, | ||
76 | /* PSC0/1 clocks: 44-45 */ | ||
77 | AU1300_PIN_PSC0CLK, AU1300_PIN_PSC1CLK, | ||
78 | /* PSCs: 46-49/50-53/54-57/58-61 */ | ||
79 | AU1300_PIN_PSC0SYNC0, AU1300_PIN_PSC0SYNC1, AU1300_PIN_PSC0D0, | ||
80 | AU1300_PIN_PSC0D1, | ||
81 | AU1300_PIN_PSC1SYNC0, AU1300_PIN_PSC1SYNC1, AU1300_PIN_PSC1D0, | ||
82 | AU1300_PIN_PSC1D1, | ||
83 | AU1300_PIN_PSC2SYNC0, AU1300_PIN_PSC2D0, | ||
84 | AU1300_PIN_PSC2D1, | ||
85 | AU1300_PIN_PSC3SYNC0, AU1300_PIN_PSC3SYNC1, AU1300_PIN_PSC3D0, | ||
86 | AU1300_PIN_PSC3D1, | ||
87 | /* PCMCIA interface: 62-70 */ | ||
88 | AU1300_PIN_PCE2, AU1300_PIN_PCE1, AU1300_PIN_PIOS16, | ||
89 | AU1300_PIN_PIOR, AU1300_PIN_PWE, AU1300_PIN_PWAIT, | ||
90 | AU1300_PIN_PREG, AU1300_PIN_POE, AU1300_PIN_PIOW, | ||
91 | /* camera interface H/V sync inputs: 71-72 */ | ||
92 | AU1300_PIN_CIMLS, AU1300_PIN_CIMFS, | ||
93 | /* PSC2/3 clocks: 73-74 */ | ||
94 | AU1300_PIN_PSC2CLK, AU1300_PIN_PSC3CLK, | ||
95 | -1, /* terminator */ | ||
96 | }; | ||
97 | |||
98 | static void __init db1300_gpio_config(void) | ||
99 | { | ||
100 | int *i; | ||
101 | |||
102 | i = &db1300_dev_pins[0]; | ||
103 | while (*i != -1) | ||
104 | au1300_pinfunc_to_dev(*i++); | ||
105 | |||
106 | i = &db1300_gpio_pins[0]; | ||
107 | while (*i != -1) | ||
108 | au1300_gpio_direction_input(*i++);/* implies pin_to_gpio */ | ||
109 | |||
110 | au1300_set_dbdma_gpio(1, AU1300_PIN_FG3AUX); | ||
111 | } | ||
112 | |||
113 | /**********************************************************************/ | ||
114 | |||
115 | static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
116 | unsigned int ctrl) | ||
117 | { | ||
118 | struct nand_chip *this = mtd->priv; | ||
119 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; | ||
120 | |||
121 | ioaddr &= 0xffffff00; | ||
122 | |||
123 | if (ctrl & NAND_CLE) { | ||
124 | ioaddr += MEM_STNAND_CMD; | ||
125 | } else if (ctrl & NAND_ALE) { | ||
126 | ioaddr += MEM_STNAND_ADDR; | ||
127 | } else { | ||
128 | /* assume we want to r/w real data by default */ | ||
129 | ioaddr += MEM_STNAND_DATA; | ||
130 | } | ||
131 | this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr; | ||
132 | if (cmd != NAND_CMD_NONE) { | ||
133 | __raw_writeb(cmd, this->IO_ADDR_W); | ||
134 | wmb(); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | static int au1300_nand_device_ready(struct mtd_info *mtd) | ||
139 | { | ||
140 | return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | ||
141 | } | ||
142 | |||
143 | static struct mtd_partition db1300_nand_parts[] = { | ||
144 | { | ||
145 | .name = "NAND FS 0", | ||
146 | .offset = 0, | ||
147 | .size = 8 * 1024 * 1024, | ||
148 | }, | ||
149 | { | ||
150 | .name = "NAND FS 1", | ||
151 | .offset = MTDPART_OFS_APPEND, | ||
152 | .size = MTDPART_SIZ_FULL | ||
153 | }, | ||
154 | }; | ||
155 | |||
156 | struct platform_nand_data db1300_nand_platdata = { | ||
157 | .chip = { | ||
158 | .nr_chips = 1, | ||
159 | .chip_offset = 0, | ||
160 | .nr_partitions = ARRAY_SIZE(db1300_nand_parts), | ||
161 | .partitions = db1300_nand_parts, | ||
162 | .chip_delay = 20, | ||
163 | }, | ||
164 | .ctrl = { | ||
165 | .dev_ready = au1300_nand_device_ready, | ||
166 | .cmd_ctrl = au1300_nand_cmd_ctrl, | ||
167 | }, | ||
168 | }; | ||
169 | |||
170 | static struct resource db1300_nand_res[] = { | ||
171 | [0] = { | ||
172 | .start = DB1300_NAND_PHYS_ADDR, | ||
173 | .end = DB1300_NAND_PHYS_ADDR + 0xff, | ||
174 | .flags = IORESOURCE_MEM, | ||
175 | }, | ||
176 | }; | ||
177 | |||
178 | static struct platform_device db1300_nand_dev = { | ||
179 | .name = "gen_nand", | ||
180 | .num_resources = ARRAY_SIZE(db1300_nand_res), | ||
181 | .resource = db1300_nand_res, | ||
182 | .id = -1, | ||
183 | .dev = { | ||
184 | .platform_data = &db1300_nand_platdata, | ||
185 | } | ||
186 | }; | ||
187 | |||
188 | /**********************************************************************/ | ||
189 | |||
190 | static struct resource db1300_eth_res[] = { | ||
191 | [0] = { | ||
192 | .start = DB1300_ETH_PHYS_ADDR, | ||
193 | .end = DB1300_ETH_PHYS_END, | ||
194 | .flags = IORESOURCE_MEM, | ||
195 | }, | ||
196 | [1] = { | ||
197 | .start = DB1300_ETH_INT, | ||
198 | .end = DB1300_ETH_INT, | ||
199 | .flags = IORESOURCE_IRQ, | ||
200 | }, | ||
201 | }; | ||
202 | |||
203 | static struct smsc911x_platform_config db1300_eth_config = { | ||
204 | .phy_interface = PHY_INTERFACE_MODE_MII, | ||
205 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | ||
206 | .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL, | ||
207 | .flags = SMSC911X_USE_32BIT, | ||
208 | }; | ||
209 | |||
210 | static struct platform_device db1300_eth_dev = { | ||
211 | .name = "smsc911x", | ||
212 | .id = -1, | ||
213 | .num_resources = ARRAY_SIZE(db1300_eth_res), | ||
214 | .resource = db1300_eth_res, | ||
215 | .dev = { | ||
216 | .platform_data = &db1300_eth_config, | ||
217 | }, | ||
218 | }; | ||
219 | |||
220 | /**********************************************************************/ | ||
221 | |||
222 | static struct resource au1300_psc1_res[] = { | ||
223 | [0] = { | ||
224 | .start = AU1300_PSC1_PHYS_ADDR, | ||
225 | .end = AU1300_PSC1_PHYS_ADDR + 0x0fff, | ||
226 | .flags = IORESOURCE_MEM, | ||
227 | }, | ||
228 | [1] = { | ||
229 | .start = AU1300_PSC1_INT, | ||
230 | .end = AU1300_PSC1_INT, | ||
231 | .flags = IORESOURCE_IRQ, | ||
232 | }, | ||
233 | [2] = { | ||
234 | .start = AU1300_DSCR_CMD0_PSC1_TX, | ||
235 | .end = AU1300_DSCR_CMD0_PSC1_TX, | ||
236 | .flags = IORESOURCE_DMA, | ||
237 | }, | ||
238 | [3] = { | ||
239 | .start = AU1300_DSCR_CMD0_PSC1_RX, | ||
240 | .end = AU1300_DSCR_CMD0_PSC1_RX, | ||
241 | .flags = IORESOURCE_DMA, | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | static struct platform_device db1300_ac97_dev = { | ||
246 | .name = "au1xpsc_ac97", | ||
247 | .id = 1, /* PSC ID. match with AC97 codec ID! */ | ||
248 | .num_resources = ARRAY_SIZE(au1300_psc1_res), | ||
249 | .resource = au1300_psc1_res, | ||
250 | }; | ||
251 | |||
252 | /**********************************************************************/ | ||
253 | |||
254 | static struct resource au1300_psc2_res[] = { | ||
255 | [0] = { | ||
256 | .start = AU1300_PSC2_PHYS_ADDR, | ||
257 | .end = AU1300_PSC2_PHYS_ADDR + 0x0fff, | ||
258 | .flags = IORESOURCE_MEM, | ||
259 | }, | ||
260 | [1] = { | ||
261 | .start = AU1300_PSC2_INT, | ||
262 | .end = AU1300_PSC2_INT, | ||
263 | .flags = IORESOURCE_IRQ, | ||
264 | }, | ||
265 | [2] = { | ||
266 | .start = AU1300_DSCR_CMD0_PSC2_TX, | ||
267 | .end = AU1300_DSCR_CMD0_PSC2_TX, | ||
268 | .flags = IORESOURCE_DMA, | ||
269 | }, | ||
270 | [3] = { | ||
271 | .start = AU1300_DSCR_CMD0_PSC2_RX, | ||
272 | .end = AU1300_DSCR_CMD0_PSC2_RX, | ||
273 | .flags = IORESOURCE_DMA, | ||
274 | }, | ||
275 | }; | ||
276 | |||
277 | static struct platform_device db1300_i2s_dev = { | ||
278 | .name = "au1xpsc_i2s", | ||
279 | .id = 2, /* PSC ID */ | ||
280 | .num_resources = ARRAY_SIZE(au1300_psc2_res), | ||
281 | .resource = au1300_psc2_res, | ||
282 | }; | ||
283 | |||
284 | /**********************************************************************/ | ||
285 | |||
286 | static struct resource au1300_psc3_res[] = { | ||
287 | [0] = { | ||
288 | .start = AU1300_PSC3_PHYS_ADDR, | ||
289 | .end = AU1300_PSC3_PHYS_ADDR + 0x0fff, | ||
290 | .flags = IORESOURCE_MEM, | ||
291 | }, | ||
292 | [1] = { | ||
293 | .start = AU1300_PSC3_INT, | ||
294 | .end = AU1300_PSC3_INT, | ||
295 | .flags = IORESOURCE_IRQ, | ||
296 | }, | ||
297 | [2] = { | ||
298 | .start = AU1300_DSCR_CMD0_PSC3_TX, | ||
299 | .end = AU1300_DSCR_CMD0_PSC3_TX, | ||
300 | .flags = IORESOURCE_DMA, | ||
301 | }, | ||
302 | [3] = { | ||
303 | .start = AU1300_DSCR_CMD0_PSC3_RX, | ||
304 | .end = AU1300_DSCR_CMD0_PSC3_RX, | ||
305 | .flags = IORESOURCE_DMA, | ||
306 | }, | ||
307 | }; | ||
308 | |||
309 | static struct platform_device db1300_i2c_dev = { | ||
310 | .name = "au1xpsc_smbus", | ||
311 | .id = 0, /* bus number */ | ||
312 | .num_resources = ARRAY_SIZE(au1300_psc3_res), | ||
313 | .resource = au1300_psc3_res, | ||
314 | }; | ||
315 | |||
316 | /**********************************************************************/ | ||
317 | |||
318 | /* proper key assignments when facing the LCD panel. For key assignments | ||
319 | * according to the schematics swap up with down and left with right. | ||
320 | * I chose to use it to emulate the arrow keys of a keyboard. | ||
321 | */ | ||
322 | static struct gpio_keys_button db1300_5waysw_arrowkeys[] = { | ||
323 | { | ||
324 | .code = KEY_DOWN, | ||
325 | .gpio = AU1300_PIN_LCDPWM0, | ||
326 | .type = EV_KEY, | ||
327 | .debounce_interval = 1, | ||
328 | .active_low = 1, | ||
329 | .desc = "5waysw-down", | ||
330 | }, | ||
331 | { | ||
332 | .code = KEY_UP, | ||
333 | .gpio = AU1300_PIN_PSC2SYNC1, | ||
334 | .type = EV_KEY, | ||
335 | .debounce_interval = 1, | ||
336 | .active_low = 1, | ||
337 | .desc = "5waysw-up", | ||
338 | }, | ||
339 | { | ||
340 | .code = KEY_RIGHT, | ||
341 | .gpio = AU1300_PIN_WAKE3, | ||
342 | .type = EV_KEY, | ||
343 | .debounce_interval = 1, | ||
344 | .active_low = 1, | ||
345 | .desc = "5waysw-right", | ||
346 | }, | ||
347 | { | ||
348 | .code = KEY_LEFT, | ||
349 | .gpio = AU1300_PIN_WAKE2, | ||
350 | .type = EV_KEY, | ||
351 | .debounce_interval = 1, | ||
352 | .active_low = 1, | ||
353 | .desc = "5waysw-left", | ||
354 | }, | ||
355 | { | ||
356 | .code = KEY_ENTER, | ||
357 | .gpio = AU1300_PIN_WAKE1, | ||
358 | .type = EV_KEY, | ||
359 | .debounce_interval = 1, | ||
360 | .active_low = 1, | ||
361 | .desc = "5waysw-push", | ||
362 | }, | ||
363 | }; | ||
364 | |||
365 | static struct gpio_keys_platform_data db1300_5waysw_data = { | ||
366 | .buttons = db1300_5waysw_arrowkeys, | ||
367 | .nbuttons = ARRAY_SIZE(db1300_5waysw_arrowkeys), | ||
368 | .rep = 1, | ||
369 | .name = "db1300-5wayswitch", | ||
370 | }; | ||
371 | |||
372 | static struct platform_device db1300_5waysw_dev = { | ||
373 | .name = "gpio-keys", | ||
374 | .dev = { | ||
375 | .platform_data = &db1300_5waysw_data, | ||
376 | }, | ||
377 | }; | ||
378 | |||
379 | /**********************************************************************/ | ||
380 | |||
381 | static struct pata_platform_info db1300_ide_info = { | ||
382 | .ioport_shift = DB1300_IDE_REG_SHIFT, | ||
383 | }; | ||
384 | |||
385 | #define IDE_ALT_START (14 << DB1300_IDE_REG_SHIFT) | ||
386 | static struct resource db1300_ide_res[] = { | ||
387 | [0] = { | ||
388 | .start = DB1300_IDE_PHYS_ADDR, | ||
389 | .end = DB1300_IDE_PHYS_ADDR + IDE_ALT_START - 1, | ||
390 | .flags = IORESOURCE_MEM, | ||
391 | }, | ||
392 | [1] = { | ||
393 | .start = DB1300_IDE_PHYS_ADDR + IDE_ALT_START, | ||
394 | .end = DB1300_IDE_PHYS_ADDR + DB1300_IDE_PHYS_LEN - 1, | ||
395 | .flags = IORESOURCE_MEM, | ||
396 | }, | ||
397 | [2] = { | ||
398 | .start = DB1300_IDE_INT, | ||
399 | .end = DB1300_IDE_INT, | ||
400 | .flags = IORESOURCE_IRQ, | ||
401 | }, | ||
402 | }; | ||
403 | |||
404 | static struct platform_device db1300_ide_dev = { | ||
405 | .dev = { | ||
406 | .platform_data = &db1300_ide_info, | ||
407 | }, | ||
408 | .name = "pata_platform", | ||
409 | .resource = db1300_ide_res, | ||
410 | .num_resources = ARRAY_SIZE(db1300_ide_res), | ||
411 | }; | ||
412 | |||
413 | /**********************************************************************/ | ||
414 | |||
415 | static irqreturn_t db1300_mmc_cd(int irq, void *ptr) | ||
416 | { | ||
417 | void(*mmc_cd)(struct mmc_host *, unsigned long); | ||
418 | |||
419 | /* disable the one currently screaming. No other way to shut it up */ | ||
420 | if (irq == DB1300_SD1_INSERT_INT) { | ||
421 | disable_irq_nosync(DB1300_SD1_INSERT_INT); | ||
422 | enable_irq(DB1300_SD1_EJECT_INT); | ||
423 | } else { | ||
424 | disable_irq_nosync(DB1300_SD1_EJECT_INT); | ||
425 | enable_irq(DB1300_SD1_INSERT_INT); | ||
426 | } | ||
427 | |||
428 | /* link against CONFIG_MMC=m. We can only be called once MMC core has | ||
429 | * initialized the controller, so symbol_get() should always succeed. | ||
430 | */ | ||
431 | mmc_cd = symbol_get(mmc_detect_change); | ||
432 | mmc_cd(ptr, msecs_to_jiffies(500)); | ||
433 | symbol_put(mmc_detect_change); | ||
434 | |||
435 | return IRQ_HANDLED; | ||
436 | } | ||
437 | |||
438 | static int db1300_mmc_card_readonly(void *mmc_host) | ||
439 | { | ||
440 | /* it uses SD1 interface, but the DB1200's SD0 bit in the CPLD */ | ||
441 | return bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP; | ||
442 | } | ||
443 | |||
444 | static int db1300_mmc_card_inserted(void *mmc_host) | ||
445 | { | ||
446 | return bcsr_read(BCSR_SIGSTAT) & (1 << 12); /* insertion irq signal */ | ||
447 | } | ||
448 | |||
449 | static int db1300_mmc_cd_setup(void *mmc_host, int en) | ||
450 | { | ||
451 | int ret; | ||
452 | |||
453 | if (en) { | ||
454 | ret = request_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, 0, | ||
455 | "sd_insert", mmc_host); | ||
456 | if (ret) | ||
457 | goto out; | ||
458 | |||
459 | ret = request_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, 0, | ||
460 | "sd_eject", mmc_host); | ||
461 | if (ret) { | ||
462 | free_irq(DB1300_SD1_INSERT_INT, mmc_host); | ||
463 | goto out; | ||
464 | } | ||
465 | |||
466 | if (db1300_mmc_card_inserted(mmc_host)) | ||
467 | enable_irq(DB1300_SD1_EJECT_INT); | ||
468 | else | ||
469 | enable_irq(DB1300_SD1_INSERT_INT); | ||
470 | |||
471 | } else { | ||
472 | free_irq(DB1300_SD1_INSERT_INT, mmc_host); | ||
473 | free_irq(DB1300_SD1_EJECT_INT, mmc_host); | ||
474 | } | ||
475 | ret = 0; | ||
476 | out: | ||
477 | return ret; | ||
478 | } | ||
479 | |||
480 | static void db1300_mmcled_set(struct led_classdev *led, | ||
481 | enum led_brightness brightness) | ||
482 | { | ||
483 | if (brightness != LED_OFF) | ||
484 | bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0); | ||
485 | else | ||
486 | bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0); | ||
487 | } | ||
488 | |||
489 | static struct led_classdev db1300_mmc_led = { | ||
490 | .brightness_set = db1300_mmcled_set, | ||
491 | }; | ||
492 | |||
493 | struct au1xmmc_platform_data db1300_sd1_platdata = { | ||
494 | .cd_setup = db1300_mmc_cd_setup, | ||
495 | .card_inserted = db1300_mmc_card_inserted, | ||
496 | .card_readonly = db1300_mmc_card_readonly, | ||
497 | .led = &db1300_mmc_led, | ||
498 | }; | ||
499 | |||
500 | static struct resource au1300_sd1_res[] = { | ||
501 | [0] = { | ||
502 | .start = AU1300_SD1_PHYS_ADDR, | ||
503 | .end = AU1300_SD1_PHYS_ADDR, | ||
504 | .flags = IORESOURCE_MEM, | ||
505 | }, | ||
506 | [1] = { | ||
507 | .start = AU1300_SD1_INT, | ||
508 | .end = AU1300_SD1_INT, | ||
509 | .flags = IORESOURCE_IRQ, | ||
510 | }, | ||
511 | [2] = { | ||
512 | .start = AU1300_DSCR_CMD0_SDMS_TX1, | ||
513 | .end = AU1300_DSCR_CMD0_SDMS_TX1, | ||
514 | .flags = IORESOURCE_DMA, | ||
515 | }, | ||
516 | [3] = { | ||
517 | .start = AU1300_DSCR_CMD0_SDMS_RX1, | ||
518 | .end = AU1300_DSCR_CMD0_SDMS_RX1, | ||
519 | .flags = IORESOURCE_DMA, | ||
520 | }, | ||
521 | }; | ||
522 | |||
523 | static struct platform_device db1300_sd1_dev = { | ||
524 | .dev = { | ||
525 | .platform_data = &db1300_sd1_platdata, | ||
526 | }, | ||
527 | .name = "au1xxx-mmc", | ||
528 | .id = 1, | ||
529 | .resource = au1300_sd1_res, | ||
530 | .num_resources = ARRAY_SIZE(au1300_sd1_res), | ||
531 | }; | ||
532 | |||
533 | /**********************************************************************/ | ||
534 | |||
535 | static int db1300_movinand_inserted(void *mmc_host) | ||
536 | { | ||
537 | return 0; /* disable for now, it doesn't work yet */ | ||
538 | } | ||
539 | |||
540 | static int db1300_movinand_readonly(void *mmc_host) | ||
541 | { | ||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static void db1300_movinand_led_set(struct led_classdev *led, | ||
546 | enum led_brightness brightness) | ||
547 | { | ||
548 | if (brightness != LED_OFF) | ||
549 | bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0); | ||
550 | else | ||
551 | bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1); | ||
552 | } | ||
553 | |||
554 | static struct led_classdev db1300_movinand_led = { | ||
555 | .brightness_set = db1300_movinand_led_set, | ||
556 | }; | ||
557 | |||
558 | struct au1xmmc_platform_data db1300_sd0_platdata = { | ||
559 | .card_inserted = db1300_movinand_inserted, | ||
560 | .card_readonly = db1300_movinand_readonly, | ||
561 | .led = &db1300_movinand_led, | ||
562 | .mask_host_caps = MMC_CAP_NEEDS_POLL, | ||
563 | }; | ||
564 | |||
565 | static struct resource au1300_sd0_res[] = { | ||
566 | [0] = { | ||
567 | .start = AU1100_SD0_PHYS_ADDR, | ||
568 | .end = AU1100_SD0_PHYS_ADDR, | ||
569 | .flags = IORESOURCE_MEM, | ||
570 | }, | ||
571 | [1] = { | ||
572 | .start = AU1300_SD0_INT, | ||
573 | .end = AU1300_SD0_INT, | ||
574 | .flags = IORESOURCE_IRQ, | ||
575 | }, | ||
576 | [2] = { | ||
577 | .start = AU1300_DSCR_CMD0_SDMS_TX0, | ||
578 | .end = AU1300_DSCR_CMD0_SDMS_TX0, | ||
579 | .flags = IORESOURCE_DMA, | ||
580 | }, | ||
581 | [3] = { | ||
582 | .start = AU1300_DSCR_CMD0_SDMS_RX0, | ||
583 | .end = AU1300_DSCR_CMD0_SDMS_RX0, | ||
584 | .flags = IORESOURCE_DMA, | ||
585 | }, | ||
586 | }; | ||
587 | |||
588 | static struct platform_device db1300_sd0_dev = { | ||
589 | .dev = { | ||
590 | .platform_data = &db1300_sd0_platdata, | ||
591 | }, | ||
592 | .name = "au1xxx-mmc", | ||
593 | .id = 0, | ||
594 | .resource = au1300_sd0_res, | ||
595 | .num_resources = ARRAY_SIZE(au1300_sd0_res), | ||
596 | }; | ||
597 | |||
598 | /**********************************************************************/ | ||
599 | |||
600 | static struct platform_device db1300_wm9715_dev = { | ||
601 | .name = "wm9712-codec", | ||
602 | .id = 1, /* ID of PSC for AC97 audio, see asoc glue! */ | ||
603 | }; | ||
604 | |||
605 | static struct platform_device db1300_ac97dma_dev = { | ||
606 | .name = "au1xpsc-pcm", | ||
607 | .id = 1, /* PSC ID */ | ||
608 | }; | ||
609 | |||
610 | static struct platform_device db1300_i2sdma_dev = { | ||
611 | .name = "au1xpsc-pcm", | ||
612 | .id = 2, /* PSC ID */ | ||
613 | }; | ||
614 | |||
615 | static struct platform_device db1300_sndac97_dev = { | ||
616 | .name = "db1300-ac97", | ||
617 | }; | ||
618 | |||
619 | static struct platform_device db1300_sndi2s_dev = { | ||
620 | .name = "db1300-i2s", | ||
621 | }; | ||
622 | |||
623 | /**********************************************************************/ | ||
624 | |||
625 | static int db1300fb_panel_index(void) | ||
626 | { | ||
627 | return 9; /* DB1300_800x480 */ | ||
628 | } | ||
629 | |||
630 | static int db1300fb_panel_init(void) | ||
631 | { | ||
632 | /* Apply power (Vee/Vdd logic is inverted on Panel DB1300_800x480) */ | ||
633 | bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD, | ||
634 | BCSR_BOARD_LCDBL); | ||
635 | return 0; | ||
636 | } | ||
637 | |||
638 | static int db1300fb_panel_shutdown(void) | ||
639 | { | ||
640 | /* Remove power (Vee/Vdd logic is inverted on Panel DB1300_800x480) */ | ||
641 | bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDBL, | ||
642 | BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD); | ||
643 | return 0; | ||
644 | } | ||
645 | |||
646 | static struct au1200fb_platdata db1300fb_pd = { | ||
647 | .panel_index = db1300fb_panel_index, | ||
648 | .panel_init = db1300fb_panel_init, | ||
649 | .panel_shutdown = db1300fb_panel_shutdown, | ||
650 | }; | ||
651 | |||
652 | static struct resource au1300_lcd_res[] = { | ||
653 | [0] = { | ||
654 | .start = AU1200_LCD_PHYS_ADDR, | ||
655 | .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1, | ||
656 | .flags = IORESOURCE_MEM, | ||
657 | }, | ||
658 | [1] = { | ||
659 | .start = AU1300_LCD_INT, | ||
660 | .end = AU1300_LCD_INT, | ||
661 | .flags = IORESOURCE_IRQ, | ||
662 | } | ||
663 | }; | ||
664 | |||
665 | static u64 au1300_lcd_dmamask = DMA_BIT_MASK(32); | ||
666 | |||
667 | static struct platform_device db1300_lcd_dev = { | ||
668 | .name = "au1200-lcd", | ||
669 | .id = 0, | ||
670 | .dev = { | ||
671 | .dma_mask = &au1300_lcd_dmamask, | ||
672 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
673 | .platform_data = &db1300fb_pd, | ||
674 | }, | ||
675 | .num_resources = ARRAY_SIZE(au1300_lcd_res), | ||
676 | .resource = au1300_lcd_res, | ||
677 | }; | ||
678 | |||
679 | /**********************************************************************/ | ||
680 | |||
681 | static struct platform_device *db1300_dev[] __initdata = { | ||
682 | &db1300_eth_dev, | ||
683 | &db1300_i2c_dev, | ||
684 | &db1300_5waysw_dev, | ||
685 | &db1300_nand_dev, | ||
686 | &db1300_ide_dev, | ||
687 | &db1300_sd0_dev, | ||
688 | &db1300_sd1_dev, | ||
689 | &db1300_lcd_dev, | ||
690 | &db1300_ac97_dev, | ||
691 | &db1300_i2s_dev, | ||
692 | &db1300_wm9715_dev, | ||
693 | &db1300_ac97dma_dev, | ||
694 | &db1300_i2sdma_dev, | ||
695 | &db1300_sndac97_dev, | ||
696 | &db1300_sndi2s_dev, | ||
697 | }; | ||
698 | |||
699 | int __init db1300_dev_setup(void) | ||
700 | { | ||
701 | int swapped, cpldirq; | ||
702 | |||
703 | /* setup CPLD IRQ muxer */ | ||
704 | cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1); | ||
705 | irq_set_irq_type(cpldirq, IRQ_TYPE_LEVEL_HIGH); | ||
706 | bcsr_init_irq(DB1300_FIRST_INT, DB1300_LAST_INT, cpldirq); | ||
707 | |||
708 | /* insert/eject IRQs: one always triggers so don't enable them | ||
709 | * when doing request_irq() on them. DB1200 has this bug too. | ||
710 | */ | ||
711 | irq_set_status_flags(DB1300_SD1_INSERT_INT, IRQ_NOAUTOEN); | ||
712 | irq_set_status_flags(DB1300_SD1_EJECT_INT, IRQ_NOAUTOEN); | ||
713 | irq_set_status_flags(DB1300_CF_INSERT_INT, IRQ_NOAUTOEN); | ||
714 | irq_set_status_flags(DB1300_CF_EJECT_INT, IRQ_NOAUTOEN); | ||
715 | |||
716 | /* | ||
717 | * setup board | ||
718 | */ | ||
719 | prom_get_ethernet_addr(&db1300_eth_config.mac[0]); | ||
720 | |||
721 | i2c_register_board_info(0, db1300_i2c_devs, | ||
722 | ARRAY_SIZE(db1300_i2c_devs)); | ||
723 | |||
724 | /* Audio PSC clock is supplied by codecs (PSC1, 2) */ | ||
725 | __raw_writel(PSC_SEL_CLK_SERCLK, | ||
726 | (void __iomem *)KSEG1ADDR(AU1300_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
727 | wmb(); | ||
728 | __raw_writel(PSC_SEL_CLK_SERCLK, | ||
729 | (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
730 | wmb(); | ||
731 | /* I2C uses internal 48MHz EXTCLK1 */ | ||
732 | __raw_writel(PSC_SEL_CLK_INTCLK, | ||
733 | (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
734 | wmb(); | ||
735 | |||
736 | /* enable power to USB ports */ | ||
737 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_USBHPWR | BCSR_RESETS_OTGPWR); | ||
738 | |||
739 | /* although it is socket #0, it uses the CPLD bits which previous boards | ||
740 | * have used for socket #1. | ||
741 | */ | ||
742 | db1x_register_pcmcia_socket( | ||
743 | AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
744 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x00400000 - 1, | ||
745 | AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
746 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x00400000 - 1, | ||
747 | AU1000_PCMCIA_IO_PHYS_ADDR, | ||
748 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x00010000 - 1, | ||
749 | DB1300_CF_INT, DB1300_CF_INSERT_INT, 0, DB1300_CF_EJECT_INT, 1); | ||
750 | |||
751 | swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; | ||
752 | db1x_register_norflash(64 << 20, 2, swapped); | ||
753 | |||
754 | return platform_add_devices(db1300_dev, ARRAY_SIZE(db1300_dev)); | ||
755 | } | ||
756 | |||
757 | |||
758 | int __init db1300_board_setup(void) | ||
759 | { | ||
760 | unsigned short whoami; | ||
761 | |||
762 | db1300_gpio_config(); | ||
763 | bcsr_init(DB1300_BCSR_PHYS_ADDR, | ||
764 | DB1300_BCSR_PHYS_ADDR + DB1300_BCSR_HEXLED_OFS); | ||
765 | |||
766 | whoami = bcsr_read(BCSR_WHOAMI); | ||
767 | printk(KERN_INFO "NetLogic DBAu1300 Development Platform.\n\t" | ||
768 | "BoardID %d CPLD Rev %d DaughtercardID %d\n", | ||
769 | BCSR_WHOAMI_BOARD(whoami), BCSR_WHOAMI_CPLD(whoami), | ||
770 | BCSR_WHOAMI_DCID(whoami)); | ||
771 | |||
772 | /* enable UARTs, YAMON only enables #2 */ | ||
773 | alchemy_uart_enable(AU1300_UART0_PHYS_ADDR); | ||
774 | alchemy_uart_enable(AU1300_UART1_PHYS_ADDR); | ||
775 | alchemy_uart_enable(AU1300_UART3_PHYS_ADDR); | ||
776 | |||
777 | return 0; | ||
778 | } | ||
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c deleted file mode 100644 index 5a9ae609542..00000000000 --- a/arch/mips/alchemy/devboards/db1550.c +++ /dev/null | |||
@@ -1,601 +0,0 @@ | |||
1 | /* | ||
2 | * Alchemy Db1550/Pb1550 board support | ||
3 | * | ||
4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> | ||
5 | */ | ||
6 | |||
7 | #include <linux/dma-mapping.h> | ||
8 | #include <linux/gpio.h> | ||
9 | #include <linux/i2c.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/mtd/mtd.h> | ||
14 | #include <linux/mtd/nand.h> | ||
15 | #include <linux/mtd/partitions.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/pm.h> | ||
18 | #include <linux/spi/spi.h> | ||
19 | #include <linux/spi/flash.h> | ||
20 | #include <asm/bootinfo.h> | ||
21 | #include <asm/mach-au1x00/au1000.h> | ||
22 | #include <asm/mach-au1x00/au1xxx_eth.h> | ||
23 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
24 | #include <asm/mach-au1x00/au1xxx_psc.h> | ||
25 | #include <asm/mach-au1x00/au1550_spi.h> | ||
26 | #include <asm/mach-au1x00/au1550nd.h> | ||
27 | #include <asm/mach-db1x00/bcsr.h> | ||
28 | #include <prom.h> | ||
29 | #include "platform.h" | ||
30 | |||
31 | static void __init db1550_hw_setup(void) | ||
32 | { | ||
33 | void __iomem *base; | ||
34 | |||
35 | /* complete SPI setup: link psc0_intclk to a 48MHz source, | ||
36 | * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC | ||
37 | * for AC97 on PB1550. | ||
38 | */ | ||
39 | base = (void __iomem *)SYS_CLKSRC; | ||
40 | __raw_writel(__raw_readl(base) | 0x000001e0, base); | ||
41 | base = (void __iomem *)SYS_PINFUNC; | ||
42 | __raw_writel(__raw_readl(base) | 1 | SYS_PF_PSC1_S1, base); | ||
43 | wmb(); | ||
44 | |||
45 | /* reset the AC97 codec now, the reset time in the psc-ac97 driver | ||
46 | * is apparently too short although it's ridiculous as it is. | ||
47 | */ | ||
48 | base = (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR); | ||
49 | __raw_writel(PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE, | ||
50 | base + PSC_SEL_OFFSET); | ||
51 | __raw_writel(PSC_CTRL_DISABLE, base + PSC_CTRL_OFFSET); | ||
52 | wmb(); | ||
53 | __raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET); | ||
54 | wmb(); | ||
55 | } | ||
56 | |||
57 | int __init db1550_board_setup(void) | ||
58 | { | ||
59 | unsigned short whoami; | ||
60 | |||
61 | bcsr_init(DB1550_BCSR_PHYS_ADDR, | ||
62 | DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS); | ||
63 | |||
64 | whoami = bcsr_read(BCSR_WHOAMI); /* PB1550 hexled offset differs */ | ||
65 | if ((BCSR_WHOAMI_BOARD(whoami) == BCSR_WHOAMI_PB1550_SDR) || | ||
66 | (BCSR_WHOAMI_BOARD(whoami) == BCSR_WHOAMI_PB1550_DDR)) | ||
67 | bcsr_init(PB1550_BCSR_PHYS_ADDR, | ||
68 | PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS); | ||
69 | |||
70 | pr_info("Alchemy/AMD %s Board, CPLD Rev %d Board-ID %d " \ | ||
71 | "Daughtercard ID %d\n", get_system_type(), | ||
72 | (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); | ||
73 | |||
74 | db1550_hw_setup(); | ||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | /*****************************************************************************/ | ||
79 | |||
80 | static struct mtd_partition db1550_spiflash_parts[] = { | ||
81 | { | ||
82 | .name = "spi_flash", | ||
83 | .offset = 0, | ||
84 | .size = MTDPART_SIZ_FULL, | ||
85 | }, | ||
86 | }; | ||
87 | |||
88 | static struct flash_platform_data db1550_spiflash_data = { | ||
89 | .name = "s25fl010", | ||
90 | .parts = db1550_spiflash_parts, | ||
91 | .nr_parts = ARRAY_SIZE(db1550_spiflash_parts), | ||
92 | .type = "m25p10", | ||
93 | }; | ||
94 | |||
95 | static struct spi_board_info db1550_spi_devs[] __initdata = { | ||
96 | { | ||
97 | /* TI TMP121AIDBVR temp sensor */ | ||
98 | .modalias = "tmp121", | ||
99 | .max_speed_hz = 2400000, | ||
100 | .bus_num = 0, | ||
101 | .chip_select = 0, | ||
102 | .mode = SPI_MODE_0, | ||
103 | }, | ||
104 | { | ||
105 | /* Spansion S25FL001D0FMA SPI flash */ | ||
106 | .modalias = "m25p80", | ||
107 | .max_speed_hz = 2400000, | ||
108 | .bus_num = 0, | ||
109 | .chip_select = 1, | ||
110 | .mode = SPI_MODE_0, | ||
111 | .platform_data = &db1550_spiflash_data, | ||
112 | }, | ||
113 | }; | ||
114 | |||
115 | static struct i2c_board_info db1550_i2c_devs[] __initdata = { | ||
116 | { I2C_BOARD_INFO("24c04", 0x52),}, /* AT24C04-10 I2C eeprom */ | ||
117 | { I2C_BOARD_INFO("ne1619", 0x2d),}, /* adm1025-compat hwmon */ | ||
118 | { I2C_BOARD_INFO("wm8731", 0x1b),}, /* I2S audio codec WM8731 */ | ||
119 | }; | ||
120 | |||
121 | /**********************************************************************/ | ||
122 | |||
123 | static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
124 | unsigned int ctrl) | ||
125 | { | ||
126 | struct nand_chip *this = mtd->priv; | ||
127 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; | ||
128 | |||
129 | ioaddr &= 0xffffff00; | ||
130 | |||
131 | if (ctrl & NAND_CLE) { | ||
132 | ioaddr += MEM_STNAND_CMD; | ||
133 | } else if (ctrl & NAND_ALE) { | ||
134 | ioaddr += MEM_STNAND_ADDR; | ||
135 | } else { | ||
136 | /* assume we want to r/w real data by default */ | ||
137 | ioaddr += MEM_STNAND_DATA; | ||
138 | } | ||
139 | this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr; | ||
140 | if (cmd != NAND_CMD_NONE) { | ||
141 | __raw_writeb(cmd, this->IO_ADDR_W); | ||
142 | wmb(); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | static int au1550_nand_device_ready(struct mtd_info *mtd) | ||
147 | { | ||
148 | return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | ||
149 | } | ||
150 | |||
151 | static struct mtd_partition db1550_nand_parts[] = { | ||
152 | { | ||
153 | .name = "NAND FS 0", | ||
154 | .offset = 0, | ||
155 | .size = 8 * 1024 * 1024, | ||
156 | }, | ||
157 | { | ||
158 | .name = "NAND FS 1", | ||
159 | .offset = MTDPART_OFS_APPEND, | ||
160 | .size = MTDPART_SIZ_FULL | ||
161 | }, | ||
162 | }; | ||
163 | |||
164 | struct platform_nand_data db1550_nand_platdata = { | ||
165 | .chip = { | ||
166 | .nr_chips = 1, | ||
167 | .chip_offset = 0, | ||
168 | .nr_partitions = ARRAY_SIZE(db1550_nand_parts), | ||
169 | .partitions = db1550_nand_parts, | ||
170 | .chip_delay = 20, | ||
171 | }, | ||
172 | .ctrl = { | ||
173 | .dev_ready = au1550_nand_device_ready, | ||
174 | .cmd_ctrl = au1550_nand_cmd_ctrl, | ||
175 | }, | ||
176 | }; | ||
177 | |||
178 | static struct resource db1550_nand_res[] = { | ||
179 | [0] = { | ||
180 | .start = 0x20000000, | ||
181 | .end = 0x200000ff, | ||
182 | .flags = IORESOURCE_MEM, | ||
183 | }, | ||
184 | }; | ||
185 | |||
186 | static struct platform_device db1550_nand_dev = { | ||
187 | .name = "gen_nand", | ||
188 | .num_resources = ARRAY_SIZE(db1550_nand_res), | ||
189 | .resource = db1550_nand_res, | ||
190 | .id = -1, | ||
191 | .dev = { | ||
192 | .platform_data = &db1550_nand_platdata, | ||
193 | } | ||
194 | }; | ||
195 | |||
196 | static struct au1550nd_platdata pb1550_nand_pd = { | ||
197 | .parts = db1550_nand_parts, | ||
198 | .num_parts = ARRAY_SIZE(db1550_nand_parts), | ||
199 | .devwidth = 0, /* x8 NAND default, needs fixing up */ | ||
200 | }; | ||
201 | |||
202 | static struct platform_device pb1550_nand_dev = { | ||
203 | .name = "au1550-nand", | ||
204 | .id = -1, | ||
205 | .resource = db1550_nand_res, | ||
206 | .num_resources = ARRAY_SIZE(db1550_nand_res), | ||
207 | .dev = { | ||
208 | .platform_data = &pb1550_nand_pd, | ||
209 | }, | ||
210 | }; | ||
211 | |||
212 | static void __init pb1550_nand_setup(void) | ||
213 | { | ||
214 | int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | | ||
215 | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); | ||
216 | |||
217 | gpio_direction_input(206); /* de-assert NAND CS# */ | ||
218 | switch (boot_swapboot) { | ||
219 | case 0: case 2: case 8: case 0xC: case 0xD: | ||
220 | /* x16 NAND Flash */ | ||
221 | pb1550_nand_pd.devwidth = 1; | ||
222 | /* fallthrough */ | ||
223 | case 1: case 3: case 9: case 0xE: case 0xF: | ||
224 | /* x8 NAND, already set up */ | ||
225 | platform_device_register(&pb1550_nand_dev); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | /**********************************************************************/ | ||
230 | |||
231 | static struct resource au1550_psc0_res[] = { | ||
232 | [0] = { | ||
233 | .start = AU1550_PSC0_PHYS_ADDR, | ||
234 | .end = AU1550_PSC0_PHYS_ADDR + 0xfff, | ||
235 | .flags = IORESOURCE_MEM, | ||
236 | }, | ||
237 | [1] = { | ||
238 | .start = AU1550_PSC0_INT, | ||
239 | .end = AU1550_PSC0_INT, | ||
240 | .flags = IORESOURCE_IRQ, | ||
241 | }, | ||
242 | [2] = { | ||
243 | .start = AU1550_DSCR_CMD0_PSC0_TX, | ||
244 | .end = AU1550_DSCR_CMD0_PSC0_TX, | ||
245 | .flags = IORESOURCE_DMA, | ||
246 | }, | ||
247 | [3] = { | ||
248 | .start = AU1550_DSCR_CMD0_PSC0_RX, | ||
249 | .end = AU1550_DSCR_CMD0_PSC0_RX, | ||
250 | .flags = IORESOURCE_DMA, | ||
251 | }, | ||
252 | }; | ||
253 | |||
254 | static void db1550_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol) | ||
255 | { | ||
256 | if (cs) | ||
257 | bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SPISEL); | ||
258 | else | ||
259 | bcsr_mod(BCSR_BOARD, BCSR_BOARD_SPISEL, 0); | ||
260 | } | ||
261 | |||
262 | static struct au1550_spi_info db1550_spi_platdata = { | ||
263 | .mainclk_hz = 48000000, /* PSC0 clock: max. 2.4MHz SPI clk */ | ||
264 | .num_chipselect = 2, | ||
265 | .activate_cs = db1550_spi_cs_en, | ||
266 | }; | ||
267 | |||
268 | static u64 spi_dmamask = DMA_BIT_MASK(32); | ||
269 | |||
270 | static struct platform_device db1550_spi_dev = { | ||
271 | .dev = { | ||
272 | .dma_mask = &spi_dmamask, | ||
273 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
274 | .platform_data = &db1550_spi_platdata, | ||
275 | }, | ||
276 | .name = "au1550-spi", | ||
277 | .id = 0, /* bus number */ | ||
278 | .num_resources = ARRAY_SIZE(au1550_psc0_res), | ||
279 | .resource = au1550_psc0_res, | ||
280 | }; | ||
281 | |||
282 | /**********************************************************************/ | ||
283 | |||
284 | static struct resource au1550_psc1_res[] = { | ||
285 | [0] = { | ||
286 | .start = AU1550_PSC1_PHYS_ADDR, | ||
287 | .end = AU1550_PSC1_PHYS_ADDR + 0xfff, | ||
288 | .flags = IORESOURCE_MEM, | ||
289 | }, | ||
290 | [1] = { | ||
291 | .start = AU1550_PSC1_INT, | ||
292 | .end = AU1550_PSC1_INT, | ||
293 | .flags = IORESOURCE_IRQ, | ||
294 | }, | ||
295 | [2] = { | ||
296 | .start = AU1550_DSCR_CMD0_PSC1_TX, | ||
297 | .end = AU1550_DSCR_CMD0_PSC1_TX, | ||
298 | .flags = IORESOURCE_DMA, | ||
299 | }, | ||
300 | [3] = { | ||
301 | .start = AU1550_DSCR_CMD0_PSC1_RX, | ||
302 | .end = AU1550_DSCR_CMD0_PSC1_RX, | ||
303 | .flags = IORESOURCE_DMA, | ||
304 | }, | ||
305 | }; | ||
306 | |||
307 | static struct platform_device db1550_ac97_dev = { | ||
308 | .name = "au1xpsc_ac97", | ||
309 | .id = 1, /* PSC ID */ | ||
310 | .num_resources = ARRAY_SIZE(au1550_psc1_res), | ||
311 | .resource = au1550_psc1_res, | ||
312 | }; | ||
313 | |||
314 | |||
315 | static struct resource au1550_psc2_res[] = { | ||
316 | [0] = { | ||
317 | .start = AU1550_PSC2_PHYS_ADDR, | ||
318 | .end = AU1550_PSC2_PHYS_ADDR + 0xfff, | ||
319 | .flags = IORESOURCE_MEM, | ||
320 | }, | ||
321 | [1] = { | ||
322 | .start = AU1550_PSC2_INT, | ||
323 | .end = AU1550_PSC2_INT, | ||
324 | .flags = IORESOURCE_IRQ, | ||
325 | }, | ||
326 | [2] = { | ||
327 | .start = AU1550_DSCR_CMD0_PSC2_TX, | ||
328 | .end = AU1550_DSCR_CMD0_PSC2_TX, | ||
329 | .flags = IORESOURCE_DMA, | ||
330 | }, | ||
331 | [3] = { | ||
332 | .start = AU1550_DSCR_CMD0_PSC2_RX, | ||
333 | .end = AU1550_DSCR_CMD0_PSC2_RX, | ||
334 | .flags = IORESOURCE_DMA, | ||
335 | }, | ||
336 | }; | ||
337 | |||
338 | static struct platform_device db1550_i2c_dev = { | ||
339 | .name = "au1xpsc_smbus", | ||
340 | .id = 0, /* bus number */ | ||
341 | .num_resources = ARRAY_SIZE(au1550_psc2_res), | ||
342 | .resource = au1550_psc2_res, | ||
343 | }; | ||
344 | |||
345 | /**********************************************************************/ | ||
346 | |||
347 | static struct resource au1550_psc3_res[] = { | ||
348 | [0] = { | ||
349 | .start = AU1550_PSC3_PHYS_ADDR, | ||
350 | .end = AU1550_PSC3_PHYS_ADDR + 0xfff, | ||
351 | .flags = IORESOURCE_MEM, | ||
352 | }, | ||
353 | [1] = { | ||
354 | .start = AU1550_PSC3_INT, | ||
355 | .end = AU1550_PSC3_INT, | ||
356 | .flags = IORESOURCE_IRQ, | ||
357 | }, | ||
358 | [2] = { | ||
359 | .start = AU1550_DSCR_CMD0_PSC3_TX, | ||
360 | .end = AU1550_DSCR_CMD0_PSC3_TX, | ||
361 | .flags = IORESOURCE_DMA, | ||
362 | }, | ||
363 | [3] = { | ||
364 | .start = AU1550_DSCR_CMD0_PSC3_RX, | ||
365 | .end = AU1550_DSCR_CMD0_PSC3_RX, | ||
366 | .flags = IORESOURCE_DMA, | ||
367 | }, | ||
368 | }; | ||
369 | |||
370 | static struct platform_device db1550_i2s_dev = { | ||
371 | .name = "au1xpsc_i2s", | ||
372 | .id = 3, /* PSC ID */ | ||
373 | .num_resources = ARRAY_SIZE(au1550_psc3_res), | ||
374 | .resource = au1550_psc3_res, | ||
375 | }; | ||
376 | |||
377 | /**********************************************************************/ | ||
378 | |||
379 | static struct platform_device db1550_stac_dev = { | ||
380 | .name = "ac97-codec", | ||
381 | .id = 1, /* on PSC1 */ | ||
382 | }; | ||
383 | |||
384 | static struct platform_device db1550_ac97dma_dev = { | ||
385 | .name = "au1xpsc-pcm", | ||
386 | .id = 1, /* on PSC3 */ | ||
387 | }; | ||
388 | |||
389 | static struct platform_device db1550_i2sdma_dev = { | ||
390 | .name = "au1xpsc-pcm", | ||
391 | .id = 3, /* on PSC3 */ | ||
392 | }; | ||
393 | |||
394 | static struct platform_device db1550_sndac97_dev = { | ||
395 | .name = "db1550-ac97", | ||
396 | }; | ||
397 | |||
398 | static struct platform_device db1550_sndi2s_dev = { | ||
399 | .name = "db1550-i2s", | ||
400 | }; | ||
401 | |||
402 | /**********************************************************************/ | ||
403 | |||
404 | static int db1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
405 | { | ||
406 | if ((slot < 11) || (slot > 13) || pin == 0) | ||
407 | return -1; | ||
408 | if (slot == 11) | ||
409 | return (pin == 1) ? AU1550_PCI_INTC : 0xff; | ||
410 | if (slot == 12) { | ||
411 | switch (pin) { | ||
412 | case 1: return AU1550_PCI_INTB; | ||
413 | case 2: return AU1550_PCI_INTC; | ||
414 | case 3: return AU1550_PCI_INTD; | ||
415 | case 4: return AU1550_PCI_INTA; | ||
416 | } | ||
417 | } | ||
418 | if (slot == 13) { | ||
419 | switch (pin) { | ||
420 | case 1: return AU1550_PCI_INTA; | ||
421 | case 2: return AU1550_PCI_INTB; | ||
422 | case 3: return AU1550_PCI_INTC; | ||
423 | case 4: return AU1550_PCI_INTD; | ||
424 | } | ||
425 | } | ||
426 | return -1; | ||
427 | } | ||
428 | |||
429 | static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin) | ||
430 | { | ||
431 | if ((slot < 12) || (slot > 13) || pin == 0) | ||
432 | return -1; | ||
433 | if (slot == 12) { | ||
434 | switch (pin) { | ||
435 | case 1: return AU1500_PCI_INTB; | ||
436 | case 2: return AU1500_PCI_INTC; | ||
437 | case 3: return AU1500_PCI_INTD; | ||
438 | case 4: return AU1500_PCI_INTA; | ||
439 | } | ||
440 | } | ||
441 | if (slot == 13) { | ||
442 | switch (pin) { | ||
443 | case 1: return AU1500_PCI_INTA; | ||
444 | case 2: return AU1500_PCI_INTB; | ||
445 | case 3: return AU1500_PCI_INTC; | ||
446 | case 4: return AU1500_PCI_INTD; | ||
447 | } | ||
448 | } | ||
449 | return -1; | ||
450 | } | ||
451 | |||
452 | static struct resource alchemy_pci_host_res[] = { | ||
453 | [0] = { | ||
454 | .start = AU1500_PCI_PHYS_ADDR, | ||
455 | .end = AU1500_PCI_PHYS_ADDR + 0xfff, | ||
456 | .flags = IORESOURCE_MEM, | ||
457 | }, | ||
458 | }; | ||
459 | |||
460 | static struct alchemy_pci_platdata db1550_pci_pd = { | ||
461 | .board_map_irq = db1550_map_pci_irq, | ||
462 | }; | ||
463 | |||
464 | static struct platform_device db1550_pci_host_dev = { | ||
465 | .dev.platform_data = &db1550_pci_pd, | ||
466 | .name = "alchemy-pci", | ||
467 | .id = 0, | ||
468 | .num_resources = ARRAY_SIZE(alchemy_pci_host_res), | ||
469 | .resource = alchemy_pci_host_res, | ||
470 | }; | ||
471 | |||
472 | /**********************************************************************/ | ||
473 | |||
474 | static struct platform_device *db1550_devs[] __initdata = { | ||
475 | &db1550_i2c_dev, | ||
476 | &db1550_ac97_dev, | ||
477 | &db1550_spi_dev, | ||
478 | &db1550_i2s_dev, | ||
479 | &db1550_stac_dev, | ||
480 | &db1550_ac97dma_dev, | ||
481 | &db1550_i2sdma_dev, | ||
482 | &db1550_sndac97_dev, | ||
483 | &db1550_sndi2s_dev, | ||
484 | }; | ||
485 | |||
486 | /* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */ | ||
487 | int __init db1550_pci_setup(int id) | ||
488 | { | ||
489 | if (id) | ||
490 | db1550_pci_pd.board_map_irq = pb1550_map_pci_irq; | ||
491 | return platform_device_register(&db1550_pci_host_dev); | ||
492 | } | ||
493 | |||
494 | static void __init db1550_devices(void) | ||
495 | { | ||
496 | alchemy_gpio_direction_output(203, 0); /* red led on */ | ||
497 | |||
498 | irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */ | ||
499 | irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */ | ||
500 | irq_set_irq_type(AU1550_GPIO3_INT, IRQ_TYPE_LEVEL_LOW); /* CARD0# */ | ||
501 | irq_set_irq_type(AU1550_GPIO5_INT, IRQ_TYPE_LEVEL_LOW); /* CARD1# */ | ||
502 | irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */ | ||
503 | irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */ | ||
504 | |||
505 | db1x_register_pcmcia_socket( | ||
506 | AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
507 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | ||
508 | AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
509 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | ||
510 | AU1000_PCMCIA_IO_PHYS_ADDR, | ||
511 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | ||
512 | AU1550_GPIO3_INT, AU1550_GPIO0_INT, | ||
513 | /*AU1550_GPIO21_INT*/0, 0, 0); | ||
514 | |||
515 | db1x_register_pcmcia_socket( | ||
516 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000, | ||
517 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, | ||
518 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000, | ||
519 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, | ||
520 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000, | ||
521 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, | ||
522 | AU1550_GPIO5_INT, AU1550_GPIO1_INT, | ||
523 | /*AU1550_GPIO22_INT*/0, 0, 1); | ||
524 | |||
525 | platform_device_register(&db1550_nand_dev); | ||
526 | |||
527 | alchemy_gpio_direction_output(202, 0); /* green led on */ | ||
528 | } | ||
529 | |||
530 | static void __init pb1550_devices(void) | ||
531 | { | ||
532 | irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_LEVEL_LOW); | ||
533 | irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_LEVEL_LOW); | ||
534 | irq_set_irq_type(AU1550_GPIO201_205_INT, IRQ_TYPE_LEVEL_HIGH); | ||
535 | |||
536 | /* enable both PCMCIA card irqs in the shared line */ | ||
537 | alchemy_gpio2_enable_int(201); /* socket 0 card irq */ | ||
538 | alchemy_gpio2_enable_int(202); /* socket 1 card irq */ | ||
539 | |||
540 | /* Pb1550, like all others, also has statuschange irqs; however they're | ||
541 | * wired up on one of the Au1550's shared GPIO201_205 line, which also | ||
542 | * services the PCMCIA card interrupts. So we ignore statuschange and | ||
543 | * use the GPIO201_205 exclusively for card interrupts, since a) pcmcia | ||
544 | * drivers are used to shared irqs and b) statuschange isn't really use- | ||
545 | * ful anyway. | ||
546 | */ | ||
547 | db1x_register_pcmcia_socket( | ||
548 | AU1000_PCMCIA_ATTR_PHYS_ADDR, | ||
549 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, | ||
550 | AU1000_PCMCIA_MEM_PHYS_ADDR, | ||
551 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, | ||
552 | AU1000_PCMCIA_IO_PHYS_ADDR, | ||
553 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, | ||
554 | AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0); | ||
555 | |||
556 | db1x_register_pcmcia_socket( | ||
557 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000, | ||
558 | AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, | ||
559 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000, | ||
560 | AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, | ||
561 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000, | ||
562 | AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, | ||
563 | AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1); | ||
564 | |||
565 | pb1550_nand_setup(); | ||
566 | } | ||
567 | |||
568 | int __init db1550_dev_setup(void) | ||
569 | { | ||
570 | int swapped, id; | ||
571 | |||
572 | id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550); | ||
573 | |||
574 | i2c_register_board_info(0, db1550_i2c_devs, | ||
575 | ARRAY_SIZE(db1550_i2c_devs)); | ||
576 | spi_register_board_info(db1550_spi_devs, | ||
577 | ARRAY_SIZE(db1550_i2c_devs)); | ||
578 | |||
579 | /* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */ | ||
580 | __raw_writel(PSC_SEL_CLK_SERCLK, | ||
581 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
582 | wmb(); | ||
583 | __raw_writel(PSC_SEL_CLK_SERCLK, | ||
584 | (void __iomem *)KSEG1ADDR(AU1550_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
585 | wmb(); | ||
586 | /* SPI/I2C use internally supplied 50MHz source */ | ||
587 | __raw_writel(PSC_SEL_CLK_INTCLK, | ||
588 | (void __iomem *)KSEG1ADDR(AU1550_PSC0_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
589 | wmb(); | ||
590 | __raw_writel(PSC_SEL_CLK_INTCLK, | ||
591 | (void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); | ||
592 | wmb(); | ||
593 | |||
594 | id ? pb1550_devices() : db1550_devices(); | ||
595 | |||
596 | swapped = bcsr_read(BCSR_STATUS) & | ||
597 | (id ? BCSR_STATUS_PB1550_SWAPBOOT : BCSR_STATUS_DB1000_SWAPBOOT); | ||
598 | db1x_register_norflash(128 << 20, 4, swapped); | ||
599 | |||
600 | return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs)); | ||
601 | } | ||
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 8df86eb9497..49a4b3244d8 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c | |||
@@ -10,45 +10,9 @@ | |||
10 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
11 | #include <linux/pm.h> | 11 | #include <linux/pm.h> |
12 | 12 | ||
13 | #include <asm/bootinfo.h> | ||
14 | #include <asm/reboot.h> | 13 | #include <asm/reboot.h> |
15 | #include <asm/mach-au1x00/au1000.h> | ||
16 | #include <asm/mach-db1x00/bcsr.h> | 14 | #include <asm/mach-db1x00/bcsr.h> |
17 | 15 | ||
18 | #include <prom.h> | ||
19 | |||
20 | void __init prom_init(void) | ||
21 | { | ||
22 | unsigned char *memsize_str; | ||
23 | unsigned long memsize; | ||
24 | |||
25 | prom_argc = (int)fw_arg0; | ||
26 | prom_argv = (char **)fw_arg1; | ||
27 | prom_envp = (char **)fw_arg2; | ||
28 | |||
29 | prom_init_cmdline(); | ||
30 | memsize_str = prom_getenv("memsize"); | ||
31 | if (!memsize_str || kstrtoul(memsize_str, 0, &memsize)) | ||
32 | memsize = 64 << 20; /* all devboards have at least 64MB RAM */ | ||
33 | |||
34 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
35 | } | ||
36 | |||
37 | void prom_putchar(unsigned char c) | ||
38 | { | ||
39 | if (alchemy_get_cputype() == ALCHEMY_CPU_AU1300) | ||
40 | alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c); | ||
41 | else | ||
42 | alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c); | ||
43 | } | ||
44 | |||
45 | |||
46 | static struct platform_device db1x00_rtc_dev = { | ||
47 | .name = "rtc-au1xxx", | ||
48 | .id = -1, | ||
49 | }; | ||
50 | |||
51 | |||
52 | static void db1x_power_off(void) | 16 | static void db1x_power_off(void) |
53 | { | 17 | { |
54 | bcsr_write(BCSR_RESETS, 0); | 18 | bcsr_write(BCSR_RESETS, 0); |
@@ -61,7 +25,7 @@ static void db1x_reset(char *c) | |||
61 | bcsr_write(BCSR_SYSTEM, 0); | 25 | bcsr_write(BCSR_SYSTEM, 0); |
62 | } | 26 | } |
63 | 27 | ||
64 | static int __init db1x_late_setup(void) | 28 | static int __init db1x_poweroff_setup(void) |
65 | { | 29 | { |
66 | if (!pm_power_off) | 30 | if (!pm_power_off) |
67 | pm_power_off = db1x_power_off; | 31 | pm_power_off = db1x_power_off; |
@@ -70,11 +34,9 @@ static int __init db1x_late_setup(void) | |||
70 | if (!_machine_restart) | 34 | if (!_machine_restart) |
71 | _machine_restart = db1x_reset; | 35 | _machine_restart = db1x_reset; |
72 | 36 | ||
73 | platform_device_register(&db1x00_rtc_dev); | ||
74 | |||
75 | return 0; | 37 | return 0; |
76 | } | 38 | } |
77 | device_initcall(db1x_late_setup); | 39 | late_initcall(db1x_poweroff_setup); |
78 | 40 | ||
79 | /* register a pcmcia socket */ | 41 | /* register a pcmcia socket */ |
80 | int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start, | 42 | int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start, |