diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-01-20 03:23:28 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-20 03:23:28 -0500 |
commit | 0ce1c383681370964e7f77dd44506aeb3a6ba657 (patch) | |
tree | 75aa590c636feed7d110c03eddb56cc518fc034c /arch/mips/alchemy | |
parent | 0a2a18b721abc960fbcada406746877d22340a60 (diff) | |
parent | 1de9e8e70f5acc441550ca75433563d91b269bbe (diff) |
Merge commit 'v2.6.29-rc2' into x86/mm
Diffstat (limited to 'arch/mips/alchemy')
45 files changed, 1336 insertions, 1882 deletions
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig index e4a057d80ab6..7f8ef13d0014 100644 --- a/arch/mips/alchemy/Kconfig +++ b/arch/mips/alchemy/Kconfig | |||
@@ -128,9 +128,10 @@ config SOC_AU1200 | |||
128 | config SOC_AU1X00 | 128 | config SOC_AU1X00 |
129 | bool | 129 | bool |
130 | select 64BIT_PHYS_ADDR | 130 | select 64BIT_PHYS_ADDR |
131 | select CEVT_R4K | 131 | select CEVT_R4K_LIB |
132 | select CSRC_R4K | 132 | select CSRC_R4K_LIB |
133 | select IRQ_CPU | 133 | select IRQ_CPU |
134 | select SYS_HAS_CPU_MIPS32_R1 | 134 | select SYS_HAS_CPU_MIPS32_R1 |
135 | select SYS_SUPPORTS_32BIT_KERNEL | 135 | select SYS_SUPPORTS_32BIT_KERNEL |
136 | select SYS_SUPPORTS_APM_EMULATION | 136 | select SYS_SUPPORTS_APM_EMULATION |
137 | select GENERIC_HARDIRQS_NO__DO_IRQ | ||
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index df48fd65bbf3..d50d4764eafe 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -6,8 +6,8 @@ | |||
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y += prom.o irq.o puts.o time.o reset.o \ | 8 | obj-y += prom.o irq.o puts.o time.o reset.o \ |
9 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ | 9 | clocks.o platform.o power.o setup.o \ |
10 | sleeper.o cputable.o dma.o dbdma.o gpio.o | 10 | sleeper.o dma.o dbdma.o gpio.o |
11 | 11 | ||
12 | obj-$(CONFIG_PCI) += pci.o | 12 | obj-$(CONFIG_PCI) += pci.o |
13 | 13 | ||
diff --git a/arch/mips/alchemy/common/au1xxx_irqmap.c b/arch/mips/alchemy/common/au1xxx_irqmap.c deleted file mode 100644 index c7ca1596394c..000000000000 --- a/arch/mips/alchemy/common/au1xxx_irqmap.c +++ /dev/null | |||
@@ -1,205 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Au1xxx processor specific IRQ tables | ||
4 | * | ||
5 | * Copyright 2004 Embedded Edge, LLC | ||
6 | * dan@embeddededge.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/kernel.h> | ||
30 | |||
31 | #include <au1000.h> | ||
32 | |||
33 | /* The IC0 interrupt table. This is processor, rather than | ||
34 | * board dependent, so no reason to keep this info in the board | ||
35 | * dependent files. | ||
36 | * | ||
37 | * Careful if you change match 2 request! | ||
38 | * The interrupt handler is called directly from the low level dispatch code. | ||
39 | */ | ||
40 | struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = { | ||
41 | |||
42 | #if defined(CONFIG_SOC_AU1000) | ||
43 | { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
44 | { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
45 | { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
46 | { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
47 | { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
48 | { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
49 | { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 }, | ||
50 | { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 }, | ||
51 | { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 }, | ||
52 | { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 }, | ||
53 | { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 }, | ||
54 | { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 }, | ||
55 | { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 }, | ||
56 | { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 }, | ||
57 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | ||
58 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
59 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
60 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | ||
61 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
62 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
63 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
64 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | ||
65 | { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
66 | { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
67 | { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
68 | { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, | ||
69 | { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, | ||
70 | { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
71 | { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
72 | { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
73 | { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, | ||
74 | |||
75 | #elif defined(CONFIG_SOC_AU1500) | ||
76 | |||
77 | { AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
78 | { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, | ||
79 | { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, | ||
80 | { AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
81 | { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, | ||
82 | { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, | ||
83 | { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 }, | ||
84 | { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 }, | ||
85 | { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 }, | ||
86 | { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 }, | ||
87 | { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 }, | ||
88 | { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 }, | ||
89 | { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 }, | ||
90 | { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 }, | ||
91 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | ||
92 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
93 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
94 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | ||
95 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
96 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
97 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
98 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | ||
99 | { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
100 | { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, | ||
101 | { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, | ||
102 | { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
103 | { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
104 | { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
105 | { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, | ||
106 | |||
107 | #elif defined(CONFIG_SOC_AU1100) | ||
108 | |||
109 | { AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
110 | { AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
111 | { AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
112 | { AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
113 | { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
114 | { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
115 | { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 }, | ||
116 | { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 }, | ||
117 | { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 }, | ||
118 | { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 }, | ||
119 | { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 }, | ||
120 | { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 }, | ||
121 | { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 }, | ||
122 | { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 }, | ||
123 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | ||
124 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
125 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
126 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | ||
127 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
128 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
129 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
130 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | ||
131 | { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
132 | { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
133 | { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
134 | { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, | ||
135 | { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, | ||
136 | { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
137 | { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
138 | /* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */ | ||
139 | { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
140 | { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 }, | ||
141 | |||
142 | #elif defined(CONFIG_SOC_AU1550) | ||
143 | |||
144 | { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
145 | { AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 }, | ||
146 | { AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 }, | ||
147 | { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
148 | { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
149 | { AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 }, | ||
150 | { AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 }, | ||
151 | { AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 }, | ||
152 | { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
153 | { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
154 | { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
155 | { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
156 | { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
157 | { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
158 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | ||
159 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
160 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
161 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | ||
162 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
163 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
164 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
165 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | ||
166 | { AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 }, | ||
167 | { AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
168 | { AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 }, | ||
169 | { AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 }, | ||
170 | { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
171 | { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
172 | |||
173 | #elif defined(CONFIG_SOC_AU1200) | ||
174 | |||
175 | { AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
176 | { AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 }, | ||
177 | { AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
178 | { AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
179 | { AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
180 | { AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
181 | { AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
182 | { AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
183 | { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
184 | { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
185 | { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
186 | { AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 }, | ||
187 | { AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
188 | { AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
189 | { AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 }, | ||
190 | { AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 }, | ||
191 | { AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 }, | ||
192 | { AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 }, | ||
193 | { AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 }, | ||
194 | { AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 }, | ||
195 | { AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
196 | { AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
197 | { AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 }, | ||
198 | |||
199 | #else | ||
200 | #error "Error: Unknown Alchemy SOC" | ||
201 | #endif | ||
202 | |||
203 | }; | ||
204 | |||
205 | int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map); | ||
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c index 043429d17c5f..d8991854530e 100644 --- a/arch/mips/alchemy/common/clocks.c +++ b/arch/mips/alchemy/common/clocks.c | |||
@@ -27,12 +27,21 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/spinlock.h> | ||
31 | #include <asm/time.h> | ||
30 | #include <asm/mach-au1x00/au1000.h> | 32 | #include <asm/mach-au1x00/au1000.h> |
31 | 33 | ||
34 | /* | ||
35 | * I haven't found anyone that doesn't use a 12 MHz source clock, | ||
36 | * but just in case..... | ||
37 | */ | ||
38 | #define AU1000_SRC_CLK 12000000 | ||
39 | |||
32 | static unsigned int au1x00_clock; /* Hz */ | 40 | static unsigned int au1x00_clock; /* Hz */ |
33 | static unsigned int lcd_clock; /* KHz */ | ||
34 | static unsigned long uart_baud_base; | 41 | static unsigned long uart_baud_base; |
35 | 42 | ||
43 | static DEFINE_SPINLOCK(time_lock); | ||
44 | |||
36 | /* | 45 | /* |
37 | * Set the au1000_clock | 46 | * Set the au1000_clock |
38 | */ | 47 | */ |
@@ -63,31 +72,45 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base) | |||
63 | } | 72 | } |
64 | 73 | ||
65 | /* | 74 | /* |
66 | * Calculate the Au1x00's LCD clock based on the current | 75 | * We read the real processor speed from the PLL. This is important |
67 | * cpu clock and the system bus clock, and try to keep it | 76 | * because it is more accurate than computing it from the 32 KHz |
68 | * below 40 MHz (the Pb1000 board can lock-up if the LCD | 77 | * counter, if it exists. If we don't have an accurate processor |
69 | * clock is over 40 MHz). | 78 | * speed, all of the peripherals that derive their clocks based on |
79 | * this advertised speed will introduce error and sometimes not work | ||
80 | * properly. This function is futher convoluted to still allow configurations | ||
81 | * to do that in case they have really, really old silicon with a | ||
82 | * write-only PLL register. -- Dan | ||
70 | */ | 83 | */ |
71 | void set_au1x00_lcd_clock(void) | 84 | unsigned long au1xxx_calc_clock(void) |
72 | { | 85 | { |
73 | unsigned int static_cfg0; | 86 | unsigned long cpu_speed; |
74 | unsigned int sys_busclk = (get_au1x00_speed() / 1000) / | 87 | unsigned long flags; |
75 | ((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2); | ||
76 | 88 | ||
77 | static_cfg0 = au_readl(MEM_STCFG0); | 89 | spin_lock_irqsave(&time_lock, flags); |
78 | 90 | ||
79 | if (static_cfg0 & (1 << 11)) | 91 | /* |
80 | lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */ | 92 | * On early Au1000, sys_cpupll was write-only. Since these |
93 | * silicon versions of Au1000 are not sold by AMD, we don't bend | ||
94 | * over backwards trying to determine the frequency. | ||
95 | */ | ||
96 | if (au1xxx_cpu_has_pll_wo()) | ||
97 | #ifdef CONFIG_SOC_AU1000_FREQUENCY | ||
98 | cpu_speed = CONFIG_SOC_AU1000_FREQUENCY; | ||
99 | #else | ||
100 | cpu_speed = 396000000; | ||
101 | #endif | ||
81 | else | 102 | else |
82 | lcd_clock = sys_busclk / 4; | 103 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; |
83 | 104 | ||
84 | if (lcd_clock > 50000) /* Epson MAX */ | 105 | /* On Alchemy CPU:counter ratio is 1:1 */ |
85 | printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n", | 106 | mips_hpt_frequency = cpu_speed; |
86 | lcd_clock); | 107 | /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */ |
87 | } | 108 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) |
109 | & 0x03) + 2) * 16)); | ||
88 | 110 | ||
89 | unsigned int get_au1x00_lcd_clock(void) | 111 | spin_unlock_irqrestore(&time_lock, flags); |
90 | { | 112 | |
91 | return lcd_clock; | 113 | set_au1x00_speed(cpu_speed); |
114 | |||
115 | return cpu_speed; | ||
92 | } | 116 | } |
93 | EXPORT_SYMBOL(get_au1x00_lcd_clock); | ||
diff --git a/arch/mips/alchemy/common/cputable.c b/arch/mips/alchemy/common/cputable.c deleted file mode 100644 index ba6430bc2d03..000000000000 --- a/arch/mips/alchemy/common/cputable.c +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * arch/mips/au1000/common/cputable.c | ||
3 | * | ||
4 | * Copyright (C) 2004 Dan Malek (dan@embeddededge.com) | ||
5 | * Copied from PowerPC and updated for Alchemy Au1xxx processors. | ||
6 | * | ||
7 | * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or | ||
10 | * modify it under the terms of the GNU General Public License | ||
11 | * as published by the Free Software Foundation; either version | ||
12 | * 2 of the License, or (at your option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <asm/mach-au1x00/au1000.h> | ||
16 | |||
17 | struct cpu_spec *cur_cpu_spec[NR_CPUS]; | ||
18 | |||
19 | /* With some thought, we can probably use the mask to reduce the | ||
20 | * size of the table. | ||
21 | */ | ||
22 | struct cpu_spec cpu_specs[] = { | ||
23 | { 0xffffffff, 0x00030100, "Au1000 DA", 1, 0, 1 }, | ||
24 | { 0xffffffff, 0x00030201, "Au1000 HA", 1, 0, 1 }, | ||
25 | { 0xffffffff, 0x00030202, "Au1000 HB", 1, 0, 1 }, | ||
26 | { 0xffffffff, 0x00030203, "Au1000 HC", 1, 1, 0 }, | ||
27 | { 0xffffffff, 0x00030204, "Au1000 HD", 1, 1, 0 }, | ||
28 | { 0xffffffff, 0x01030200, "Au1500 AB", 1, 1, 0 }, | ||
29 | { 0xffffffff, 0x01030201, "Au1500 AC", 0, 1, 0 }, | ||
30 | { 0xffffffff, 0x01030202, "Au1500 AD", 0, 1, 0 }, | ||
31 | { 0xffffffff, 0x02030200, "Au1100 AB", 1, 1, 0 }, | ||
32 | { 0xffffffff, 0x02030201, "Au1100 BA", 1, 1, 0 }, | ||
33 | { 0xffffffff, 0x02030202, "Au1100 BC", 1, 1, 0 }, | ||
34 | { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1, 0 }, | ||
35 | { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1, 0 }, | ||
36 | { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1, 0 }, | ||
37 | { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0, 0 }, | ||
38 | { 0xffffffff, 0x04030201, "Au1200 AC", 1, 0, 0 }, | ||
39 | { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 } | ||
40 | }; | ||
41 | |||
42 | void set_cpuspec(void) | ||
43 | { | ||
44 | struct cpu_spec *sp; | ||
45 | u32 prid; | ||
46 | |||
47 | prid = read_c0_prid(); | ||
48 | sp = cpu_specs; | ||
49 | while ((prid & sp->prid_mask) != sp->prid_value) | ||
50 | sp++; | ||
51 | cur_cpu_spec[0] = sp; | ||
52 | } | ||
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 601ee9180ee4..3ab6d80d150d 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -174,6 +174,11 @@ static dbdev_tab_t dbdev_tab[] = { | |||
174 | 174 | ||
175 | #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) | 175 | #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) |
176 | 176 | ||
177 | #ifdef CONFIG_PM | ||
178 | static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][8]; | ||
179 | #endif | ||
180 | |||
181 | |||
177 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; | 182 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; |
178 | 183 | ||
179 | static dbdev_tab_t *find_dbdev_id(u32 id) | 184 | static dbdev_tab_t *find_dbdev_id(u32 id) |
@@ -975,4 +980,64 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) | |||
975 | return nbytes; | 980 | return nbytes; |
976 | } | 981 | } |
977 | 982 | ||
983 | #ifdef CONFIG_PM | ||
984 | void au1xxx_dbdma_suspend(void) | ||
985 | { | ||
986 | int i; | ||
987 | u32 addr; | ||
988 | |||
989 | addr = DDMA_GLOBAL_BASE; | ||
990 | au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00); | ||
991 | au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04); | ||
992 | au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08); | ||
993 | au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c); | ||
994 | |||
995 | /* save channel configurations */ | ||
996 | for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) { | ||
997 | au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00); | ||
998 | au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04); | ||
999 | au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08); | ||
1000 | au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c); | ||
1001 | au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10); | ||
1002 | au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14); | ||
1003 | au1xxx_dbdma_pm_regs[i][6] = au_readl(addr + 0x18); | ||
1004 | |||
1005 | /* halt channel */ | ||
1006 | au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00); | ||
1007 | au_sync(); | ||
1008 | while (!(au_readl(addr + 0x14) & 1)) | ||
1009 | au_sync(); | ||
1010 | |||
1011 | addr += 0x100; /* next channel base */ | ||
1012 | } | ||
1013 | /* disable channel interrupts */ | ||
1014 | au_writel(0, DDMA_GLOBAL_BASE + 0x0c); | ||
1015 | au_sync(); | ||
1016 | } | ||
1017 | |||
1018 | void au1xxx_dbdma_resume(void) | ||
1019 | { | ||
1020 | int i; | ||
1021 | u32 addr; | ||
1022 | |||
1023 | addr = DDMA_GLOBAL_BASE; | ||
1024 | au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00); | ||
1025 | au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04); | ||
1026 | au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08); | ||
1027 | au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c); | ||
1028 | |||
1029 | /* restore channel configurations */ | ||
1030 | for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) { | ||
1031 | au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00); | ||
1032 | au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04); | ||
1033 | au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08); | ||
1034 | au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c); | ||
1035 | au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10); | ||
1036 | au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14); | ||
1037 | au_writel(au1xxx_dbdma_pm_regs[i][6], addr + 0x18); | ||
1038 | au_sync(); | ||
1039 | addr += 0x100; /* next channel base */ | ||
1040 | } | ||
1041 | } | ||
1042 | #endif /* CONFIG_PM */ | ||
978 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ | 1043 | #endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ |
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 40c6ceceb5f9..c88c821b4c36 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -24,6 +24,7 @@ | |||
24 | * with this program; if not, write to the Free Software Foundation, Inc., | 24 | * with this program; if not, write to the Free Software Foundation, Inc., |
25 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 25 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
26 | */ | 26 | */ |
27 | |||
27 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
28 | #include <linux/init.h> | 29 | #include <linux/init.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
@@ -36,15 +37,172 @@ | |||
36 | #include <asm/mach-pb1x00/pb1000.h> | 37 | #include <asm/mach-pb1x00/pb1000.h> |
37 | #endif | 38 | #endif |
38 | 39 | ||
39 | #define EXT_INTC0_REQ0 2 /* IP 2 */ | 40 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type); |
40 | #define EXT_INTC0_REQ1 3 /* IP 3 */ | 41 | |
41 | #define EXT_INTC1_REQ0 4 /* IP 4 */ | 42 | /* per-processor fixed function irqs */ |
42 | #define EXT_INTC1_REQ1 5 /* IP 5 */ | 43 | struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = { |
43 | #define MIPS_TIMER_IP 7 /* IP 7 */ | 44 | |
44 | 45 | #if defined(CONFIG_SOC_AU1000) | |
45 | void (*board_init_irq)(void) __initdata = NULL; | 46 | { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, |
47 | { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
48 | { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
49 | { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
50 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
51 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
52 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
53 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
54 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
55 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
56 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
57 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
58 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
59 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
60 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
61 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
62 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
63 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
64 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
65 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
66 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
67 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
68 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
69 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
70 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
71 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
72 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
73 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
74 | { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
75 | { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
76 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
77 | |||
78 | #elif defined(CONFIG_SOC_AU1500) | ||
79 | |||
80 | { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
81 | { AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
82 | { AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
83 | { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
84 | { AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
85 | { AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
86 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
87 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
88 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
89 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
90 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
91 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
92 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
93 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
94 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
95 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
96 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
97 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
98 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
99 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
100 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
101 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
102 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
103 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
104 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
105 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
106 | { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
107 | { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
108 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
109 | |||
110 | #elif defined(CONFIG_SOC_AU1100) | ||
111 | |||
112 | { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
113 | { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
114 | { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
115 | { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
116 | { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
117 | { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
118 | { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
119 | { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
120 | { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
121 | { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
122 | { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
123 | { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
124 | { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
125 | { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
126 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
127 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
128 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
129 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
130 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
131 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
132 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
133 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
134 | { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
135 | { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
136 | { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
137 | { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
138 | { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
139 | { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
140 | { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
141 | { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
142 | { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
143 | |||
144 | #elif defined(CONFIG_SOC_AU1550) | ||
145 | |||
146 | { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
147 | { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
148 | { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
149 | { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
150 | { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
151 | { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
152 | { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
153 | { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
154 | { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
155 | { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
156 | { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
157 | { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
158 | { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
159 | { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
160 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
161 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
162 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
163 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
164 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
165 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
166 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
167 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
168 | { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
169 | { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
170 | { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
171 | { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 }, | ||
172 | { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
173 | { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
174 | |||
175 | #elif defined(CONFIG_SOC_AU1200) | ||
176 | |||
177 | { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
178 | { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
179 | { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
180 | { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
181 | { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
182 | { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
183 | { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
184 | { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
185 | { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
186 | { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
187 | { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
188 | { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
189 | { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
190 | { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
191 | { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 }, | ||
192 | { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
193 | { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
194 | { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
195 | { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
196 | { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 }, | ||
197 | { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
198 | { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
199 | { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 }, | ||
200 | |||
201 | #else | ||
202 | #error "Error: Unknown Alchemy SOC" | ||
203 | #endif | ||
204 | }; | ||
46 | 205 | ||
47 | static DEFINE_SPINLOCK(irq_lock); | ||
48 | 206 | ||
49 | #ifdef CONFIG_PM | 207 | #ifdef CONFIG_PM |
50 | 208 | ||
@@ -130,67 +288,47 @@ void restore_au1xxx_intctl(void) | |||
130 | #endif /* CONFIG_PM */ | 288 | #endif /* CONFIG_PM */ |
131 | 289 | ||
132 | 290 | ||
133 | inline void local_enable_irq(unsigned int irq_nr) | 291 | static void au1x_ic0_unmask(unsigned int irq_nr) |
134 | { | 292 | { |
135 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 293 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; |
136 | 294 | au_writel(1 << bit, IC0_MASKSET); | |
137 | if (bit >= 32) { | 295 | au_writel(1 << bit, IC0_WAKESET); |
138 | au_writel(1 << (bit - 32), IC1_MASKSET); | ||
139 | au_writel(1 << (bit - 32), IC1_WAKESET); | ||
140 | } else { | ||
141 | au_writel(1 << bit, IC0_MASKSET); | ||
142 | au_writel(1 << bit, IC0_WAKESET); | ||
143 | } | ||
144 | au_sync(); | 296 | au_sync(); |
145 | } | 297 | } |
146 | 298 | ||
147 | 299 | static void au1x_ic1_unmask(unsigned int irq_nr) | |
148 | inline void local_disable_irq(unsigned int irq_nr) | ||
149 | { | 300 | { |
150 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 301 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; |
302 | au_writel(1 << bit, IC1_MASKSET); | ||
303 | au_writel(1 << bit, IC1_WAKESET); | ||
151 | 304 | ||
152 | if (bit >= 32) { | 305 | /* very hacky. does the pb1000 cpld auto-disable this int? |
153 | au_writel(1 << (bit - 32), IC1_MASKCLR); | 306 | * nowhere in the current kernel sources is it disabled. --mlau |
154 | au_writel(1 << (bit - 32), IC1_WAKECLR); | 307 | */ |
155 | } else { | 308 | #if defined(CONFIG_MIPS_PB1000) |
156 | au_writel(1 << bit, IC0_MASKCLR); | 309 | if (irq_nr == AU1000_GPIO_15) |
157 | au_writel(1 << bit, IC0_WAKECLR); | 310 | au_writel(0x4000, PB1000_MDR); /* enable int */ |
158 | } | 311 | #endif |
159 | au_sync(); | 312 | au_sync(); |
160 | } | 313 | } |
161 | 314 | ||
162 | 315 | static void au1x_ic0_mask(unsigned int irq_nr) | |
163 | static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr) | ||
164 | { | 316 | { |
165 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 317 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; |
166 | 318 | au_writel(1 << bit, IC0_MASKCLR); | |
167 | if (bit >= 32) { | 319 | au_writel(1 << bit, IC0_WAKECLR); |
168 | au_writel(1 << (bit - 32), IC1_RISINGCLR); | ||
169 | au_writel(1 << (bit - 32), IC1_MASKCLR); | ||
170 | } else { | ||
171 | au_writel(1 << bit, IC0_RISINGCLR); | ||
172 | au_writel(1 << bit, IC0_MASKCLR); | ||
173 | } | ||
174 | au_sync(); | 320 | au_sync(); |
175 | } | 321 | } |
176 | 322 | ||
177 | 323 | static void au1x_ic1_mask(unsigned int irq_nr) | |
178 | static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr) | ||
179 | { | 324 | { |
180 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 325 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; |
181 | 326 | au_writel(1 << bit, IC1_MASKCLR); | |
182 | if (bit >= 32) { | 327 | au_writel(1 << bit, IC1_WAKECLR); |
183 | au_writel(1 << (bit - 32), IC1_FALLINGCLR); | ||
184 | au_writel(1 << (bit - 32), IC1_MASKCLR); | ||
185 | } else { | ||
186 | au_writel(1 << bit, IC0_FALLINGCLR); | ||
187 | au_writel(1 << bit, IC0_MASKCLR); | ||
188 | } | ||
189 | au_sync(); | 328 | au_sync(); |
190 | } | 329 | } |
191 | 330 | ||
192 | 331 | static void au1x_ic0_ack(unsigned int irq_nr) | |
193 | static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr) | ||
194 | { | 332 | { |
195 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 333 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; |
196 | 334 | ||
@@ -198,349 +336,229 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr) | |||
198 | * This may assume that we don't get interrupts from | 336 | * This may assume that we don't get interrupts from |
199 | * both edges at once, or if we do, that we don't care. | 337 | * both edges at once, or if we do, that we don't care. |
200 | */ | 338 | */ |
201 | if (bit >= 32) { | 339 | au_writel(1 << bit, IC0_FALLINGCLR); |
202 | au_writel(1 << (bit - 32), IC1_FALLINGCLR); | 340 | au_writel(1 << bit, IC0_RISINGCLR); |
203 | au_writel(1 << (bit - 32), IC1_RISINGCLR); | ||
204 | au_writel(1 << (bit - 32), IC1_MASKCLR); | ||
205 | } else { | ||
206 | au_writel(1 << bit, IC0_FALLINGCLR); | ||
207 | au_writel(1 << bit, IC0_RISINGCLR); | ||
208 | au_writel(1 << bit, IC0_MASKCLR); | ||
209 | } | ||
210 | au_sync(); | 341 | au_sync(); |
211 | } | 342 | } |
212 | 343 | ||
213 | static inline void mask_and_ack_level_irq(unsigned int irq_nr) | 344 | static void au1x_ic1_ack(unsigned int irq_nr) |
214 | { | 345 | { |
215 | local_disable_irq(irq_nr); | 346 | unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE; |
216 | au_sync(); | ||
217 | #if defined(CONFIG_MIPS_PB1000) | ||
218 | if (irq_nr == AU1000_GPIO_15) { | ||
219 | au_writel(0x8000, PB1000_MDR); /* ack int */ | ||
220 | au_sync(); | ||
221 | } | ||
222 | #endif | ||
223 | } | ||
224 | |||
225 | static void end_irq(unsigned int irq_nr) | ||
226 | { | ||
227 | if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS))) | ||
228 | local_enable_irq(irq_nr); | ||
229 | 347 | ||
230 | #if defined(CONFIG_MIPS_PB1000) | 348 | /* |
231 | if (irq_nr == AU1000_GPIO_15) { | 349 | * This may assume that we don't get interrupts from |
232 | au_writel(0x4000, PB1000_MDR); /* enable int */ | 350 | * both edges at once, or if we do, that we don't care. |
233 | au_sync(); | 351 | */ |
234 | } | 352 | au_writel(1 << bit, IC1_FALLINGCLR); |
235 | #endif | 353 | au_writel(1 << bit, IC1_RISINGCLR); |
354 | au_sync(); | ||
236 | } | 355 | } |
237 | 356 | ||
238 | unsigned long save_local_and_disable(int controller) | 357 | static int au1x_ic1_setwake(unsigned int irq, unsigned int on) |
239 | { | 358 | { |
240 | int i; | 359 | unsigned int bit = irq - AU1000_INTC1_INT_BASE; |
241 | unsigned long flags, mask; | 360 | unsigned long wakemsk, flags; |
242 | |||
243 | spin_lock_irqsave(&irq_lock, flags); | ||
244 | if (controller) { | ||
245 | mask = au_readl(IC1_MASKSET); | ||
246 | for (i = 32; i < 64; i++) | ||
247 | local_disable_irq(i); | ||
248 | } else { | ||
249 | mask = au_readl(IC0_MASKSET); | ||
250 | for (i = 0; i < 32; i++) | ||
251 | local_disable_irq(i); | ||
252 | } | ||
253 | spin_unlock_irqrestore(&irq_lock, flags); | ||
254 | |||
255 | return mask; | ||
256 | } | ||
257 | 361 | ||
258 | void restore_local_and_enable(int controller, unsigned long mask) | 362 | /* only GPIO 0-7 can act as wakeup source: */ |
259 | { | 363 | if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7)) |
260 | int i; | 364 | return -EINVAL; |
261 | unsigned long flags, new_mask; | ||
262 | |||
263 | spin_lock_irqsave(&irq_lock, flags); | ||
264 | for (i = 0; i < 32; i++) | ||
265 | if (mask & (1 << i)) { | ||
266 | if (controller) | ||
267 | local_enable_irq(i + 32); | ||
268 | else | ||
269 | local_enable_irq(i); | ||
270 | } | ||
271 | 365 | ||
272 | if (controller) | 366 | local_irq_save(flags); |
273 | new_mask = au_readl(IC1_MASKSET); | 367 | wakemsk = au_readl(SYS_WAKEMSK); |
368 | if (on) | ||
369 | wakemsk |= 1 << bit; | ||
274 | else | 370 | else |
275 | new_mask = au_readl(IC0_MASKSET); | 371 | wakemsk &= ~(1 << bit); |
372 | au_writel(wakemsk, SYS_WAKEMSK); | ||
373 | au_sync(); | ||
374 | local_irq_restore(flags); | ||
276 | 375 | ||
277 | spin_unlock_irqrestore(&irq_lock, flags); | 376 | return 0; |
278 | } | 377 | } |
279 | 378 | ||
280 | 379 | /* | |
281 | static struct irq_chip rise_edge_irq_type = { | 380 | * irq_chips for both ICs; this way the mask handlers can be |
282 | .name = "Au1000 Rise Edge", | 381 | * as short as possible. |
283 | .ack = mask_and_ack_rise_edge_irq, | 382 | * |
284 | .mask = local_disable_irq, | 383 | * NOTE: the ->ack() callback is used by the handle_edge_irq |
285 | .mask_ack = mask_and_ack_rise_edge_irq, | 384 | * flowhandler only, the ->mask_ack() one by handle_level_irq, |
286 | .unmask = local_enable_irq, | 385 | * so no need for an irq_chip for each type of irq (level/edge). |
287 | .end = end_irq, | 386 | */ |
288 | }; | 387 | static struct irq_chip au1x_ic0_chip = { |
289 | 388 | .name = "Alchemy-IC0", | |
290 | static struct irq_chip fall_edge_irq_type = { | 389 | .ack = au1x_ic0_ack, /* edge */ |
291 | .name = "Au1000 Fall Edge", | 390 | .mask = au1x_ic0_mask, |
292 | .ack = mask_and_ack_fall_edge_irq, | 391 | .mask_ack = au1x_ic0_mask, /* level */ |
293 | .mask = local_disable_irq, | 392 | .unmask = au1x_ic0_unmask, |
294 | .mask_ack = mask_and_ack_fall_edge_irq, | 393 | .set_type = au1x_ic_settype, |
295 | .unmask = local_enable_irq, | ||
296 | .end = end_irq, | ||
297 | }; | ||
298 | |||
299 | static struct irq_chip either_edge_irq_type = { | ||
300 | .name = "Au1000 Rise or Fall Edge", | ||
301 | .ack = mask_and_ack_either_edge_irq, | ||
302 | .mask = local_disable_irq, | ||
303 | .mask_ack = mask_and_ack_either_edge_irq, | ||
304 | .unmask = local_enable_irq, | ||
305 | .end = end_irq, | ||
306 | }; | 394 | }; |
307 | 395 | ||
308 | static struct irq_chip level_irq_type = { | 396 | static struct irq_chip au1x_ic1_chip = { |
309 | .name = "Au1000 Level", | 397 | .name = "Alchemy-IC1", |
310 | .ack = mask_and_ack_level_irq, | 398 | .ack = au1x_ic1_ack, /* edge */ |
311 | .mask = local_disable_irq, | 399 | .mask = au1x_ic1_mask, |
312 | .mask_ack = mask_and_ack_level_irq, | 400 | .mask_ack = au1x_ic1_mask, /* level */ |
313 | .unmask = local_enable_irq, | 401 | .unmask = au1x_ic1_unmask, |
314 | .end = end_irq, | 402 | .set_type = au1x_ic_settype, |
403 | .set_wake = au1x_ic1_setwake, | ||
315 | }; | 404 | }; |
316 | 405 | ||
317 | static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req) | 406 | static int au1x_ic_settype(unsigned int irq, unsigned int flow_type) |
318 | { | 407 | { |
319 | unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE; | 408 | struct irq_chip *chip; |
320 | 409 | unsigned long icr[6]; | |
321 | if (irq_nr > AU1000_MAX_INTR) | 410 | unsigned int bit, ic; |
322 | return; | 411 | int ret; |
323 | 412 | ||
324 | /* Config2[n], Config1[n], Config0[n] */ | 413 | if (irq >= AU1000_INTC1_INT_BASE) { |
325 | if (bit >= 32) { | 414 | bit = irq - AU1000_INTC1_INT_BASE; |
326 | switch (type) { | 415 | chip = &au1x_ic1_chip; |
327 | case INTC_INT_RISE_EDGE: /* 0:0:1 */ | 416 | ic = 1; |
328 | au_writel(1 << (bit - 32), IC1_CFG2CLR); | ||
329 | au_writel(1 << (bit - 32), IC1_CFG1CLR); | ||
330 | au_writel(1 << (bit - 32), IC1_CFG0SET); | ||
331 | set_irq_chip(irq_nr, &rise_edge_irq_type); | ||
332 | break; | ||
333 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | ||
334 | au_writel(1 << (bit - 32), IC1_CFG2CLR); | ||
335 | au_writel(1 << (bit - 32), IC1_CFG1SET); | ||
336 | au_writel(1 << (bit - 32), IC1_CFG0CLR); | ||
337 | set_irq_chip(irq_nr, &fall_edge_irq_type); | ||
338 | break; | ||
339 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | ||
340 | au_writel(1 << (bit - 32), IC1_CFG2CLR); | ||
341 | au_writel(1 << (bit - 32), IC1_CFG1SET); | ||
342 | au_writel(1 << (bit - 32), IC1_CFG0SET); | ||
343 | set_irq_chip(irq_nr, &either_edge_irq_type); | ||
344 | break; | ||
345 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | ||
346 | au_writel(1 << (bit - 32), IC1_CFG2SET); | ||
347 | au_writel(1 << (bit - 32), IC1_CFG1CLR); | ||
348 | au_writel(1 << (bit - 32), IC1_CFG0SET); | ||
349 | set_irq_chip(irq_nr, &level_irq_type); | ||
350 | break; | ||
351 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | ||
352 | au_writel(1 << (bit - 32), IC1_CFG2SET); | ||
353 | au_writel(1 << (bit - 32), IC1_CFG1SET); | ||
354 | au_writel(1 << (bit - 32), IC1_CFG0CLR); | ||
355 | set_irq_chip(irq_nr, &level_irq_type); | ||
356 | break; | ||
357 | case INTC_INT_DISABLED: /* 0:0:0 */ | ||
358 | au_writel(1 << (bit - 32), IC1_CFG0CLR); | ||
359 | au_writel(1 << (bit - 32), IC1_CFG1CLR); | ||
360 | au_writel(1 << (bit - 32), IC1_CFG2CLR); | ||
361 | break; | ||
362 | default: /* disable the interrupt */ | ||
363 | printk(KERN_WARNING "unexpected int type %d (irq %d)\n", | ||
364 | type, irq_nr); | ||
365 | au_writel(1 << (bit - 32), IC1_CFG0CLR); | ||
366 | au_writel(1 << (bit - 32), IC1_CFG1CLR); | ||
367 | au_writel(1 << (bit - 32), IC1_CFG2CLR); | ||
368 | return; | ||
369 | } | ||
370 | if (int_req) /* assign to interrupt request 1 */ | ||
371 | au_writel(1 << (bit - 32), IC1_ASSIGNCLR); | ||
372 | else /* assign to interrupt request 0 */ | ||
373 | au_writel(1 << (bit - 32), IC1_ASSIGNSET); | ||
374 | au_writel(1 << (bit - 32), IC1_SRCSET); | ||
375 | au_writel(1 << (bit - 32), IC1_MASKCLR); | ||
376 | au_writel(1 << (bit - 32), IC1_WAKECLR); | ||
377 | } else { | 417 | } else { |
378 | switch (type) { | 418 | bit = irq - AU1000_INTC0_INT_BASE; |
379 | case INTC_INT_RISE_EDGE: /* 0:0:1 */ | 419 | chip = &au1x_ic0_chip; |
380 | au_writel(1 << bit, IC0_CFG2CLR); | 420 | ic = 0; |
381 | au_writel(1 << bit, IC0_CFG1CLR); | 421 | } |
382 | au_writel(1 << bit, IC0_CFG0SET); | 422 | |
383 | set_irq_chip(irq_nr, &rise_edge_irq_type); | 423 | if (bit > 31) |
384 | break; | 424 | return -EINVAL; |
385 | case INTC_INT_FALL_EDGE: /* 0:1:0 */ | 425 | |
386 | au_writel(1 << bit, IC0_CFG2CLR); | 426 | icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET; |
387 | au_writel(1 << bit, IC0_CFG1SET); | 427 | icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET; |
388 | au_writel(1 << bit, IC0_CFG0CLR); | 428 | icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET; |
389 | set_irq_chip(irq_nr, &fall_edge_irq_type); | 429 | icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR; |
390 | break; | 430 | icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR; |
391 | case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ | 431 | icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR; |
392 | au_writel(1 << bit, IC0_CFG2CLR); | 432 | |
393 | au_writel(1 << bit, IC0_CFG1SET); | 433 | ret = 0; |
394 | au_writel(1 << bit, IC0_CFG0SET); | 434 | |
395 | set_irq_chip(irq_nr, &either_edge_irq_type); | 435 | switch (flow_type) { /* cfgregs 2:1:0 */ |
396 | break; | 436 | case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */ |
397 | case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ | 437 | au_writel(1 << bit, icr[5]); |
398 | au_writel(1 << bit, IC0_CFG2SET); | 438 | au_writel(1 << bit, icr[4]); |
399 | au_writel(1 << bit, IC0_CFG1CLR); | 439 | au_writel(1 << bit, icr[0]); |
400 | au_writel(1 << bit, IC0_CFG0SET); | 440 | set_irq_chip_and_handler_name(irq, chip, |
401 | set_irq_chip(irq_nr, &level_irq_type); | 441 | handle_edge_irq, "riseedge"); |
402 | break; | 442 | break; |
403 | case INTC_INT_LOW_LEVEL: /* 1:1:0 */ | 443 | case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */ |
404 | au_writel(1 << bit, IC0_CFG2SET); | 444 | au_writel(1 << bit, icr[5]); |
405 | au_writel(1 << bit, IC0_CFG1SET); | 445 | au_writel(1 << bit, icr[1]); |
406 | au_writel(1 << bit, IC0_CFG0CLR); | 446 | au_writel(1 << bit, icr[3]); |
407 | set_irq_chip(irq_nr, &level_irq_type); | 447 | set_irq_chip_and_handler_name(irq, chip, |
408 | break; | 448 | handle_edge_irq, "falledge"); |
409 | case INTC_INT_DISABLED: /* 0:0:0 */ | 449 | break; |
410 | au_writel(1 << bit, IC0_CFG0CLR); | 450 | case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */ |
411 | au_writel(1 << bit, IC0_CFG1CLR); | 451 | au_writel(1 << bit, icr[5]); |
412 | au_writel(1 << bit, IC0_CFG2CLR); | 452 | au_writel(1 << bit, icr[1]); |
413 | break; | 453 | au_writel(1 << bit, icr[0]); |
414 | default: /* disable the interrupt */ | 454 | set_irq_chip_and_handler_name(irq, chip, |
415 | printk(KERN_WARNING "unexpected int type %d (irq %d)\n", | 455 | handle_edge_irq, "bothedge"); |
416 | type, irq_nr); | 456 | break; |
417 | au_writel(1 << bit, IC0_CFG0CLR); | 457 | case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */ |
418 | au_writel(1 << bit, IC0_CFG1CLR); | 458 | au_writel(1 << bit, icr[2]); |
419 | au_writel(1 << bit, IC0_CFG2CLR); | 459 | au_writel(1 << bit, icr[4]); |
420 | return; | 460 | au_writel(1 << bit, icr[0]); |
421 | } | 461 | set_irq_chip_and_handler_name(irq, chip, |
422 | if (int_req) /* assign to interrupt request 1 */ | 462 | handle_level_irq, "hilevel"); |
423 | au_writel(1 << bit, IC0_ASSIGNCLR); | 463 | break; |
424 | else /* assign to interrupt request 0 */ | 464 | case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */ |
425 | au_writel(1 << bit, IC0_ASSIGNSET); | 465 | au_writel(1 << bit, icr[2]); |
426 | au_writel(1 << bit, IC0_SRCSET); | 466 | au_writel(1 << bit, icr[1]); |
427 | au_writel(1 << bit, IC0_MASKCLR); | 467 | au_writel(1 << bit, icr[3]); |
428 | au_writel(1 << bit, IC0_WAKECLR); | 468 | set_irq_chip_and_handler_name(irq, chip, |
469 | handle_level_irq, "lowlevel"); | ||
470 | break; | ||
471 | case IRQ_TYPE_NONE: /* 0:0:0 */ | ||
472 | au_writel(1 << bit, icr[5]); | ||
473 | au_writel(1 << bit, icr[4]); | ||
474 | au_writel(1 << bit, icr[3]); | ||
475 | /* set at least chip so we can call set_irq_type() on it */ | ||
476 | set_irq_chip(irq, chip); | ||
477 | break; | ||
478 | default: | ||
479 | ret = -EINVAL; | ||
429 | } | 480 | } |
430 | au_sync(); | 481 | au_sync(); |
431 | } | ||
432 | 482 | ||
433 | /* | 483 | return ret; |
434 | * Interrupts are nested. Even if an interrupt handler is registered | 484 | } |
435 | * as "fast", we might get another interrupt before we return from | ||
436 | * intcX_reqX_irqdispatch(). | ||
437 | */ | ||
438 | 485 | ||
439 | static void intc0_req0_irqdispatch(void) | 486 | asmlinkage void plat_irq_dispatch(void) |
440 | { | 487 | { |
441 | static unsigned long intc0_req0; | 488 | unsigned int pending = read_c0_status() & read_c0_cause(); |
442 | unsigned int bit; | 489 | unsigned long s, off, bit; |
443 | |||
444 | intc0_req0 |= au_readl(IC0_REQ0INT); | ||
445 | 490 | ||
446 | if (!intc0_req0) | 491 | if (pending & CAUSEF_IP7) { |
492 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); | ||
447 | return; | 493 | return; |
448 | 494 | } else if (pending & CAUSEF_IP2) { | |
495 | s = IC0_REQ0INT; | ||
496 | off = AU1000_INTC0_INT_BASE; | ||
497 | } else if (pending & CAUSEF_IP3) { | ||
498 | s = IC0_REQ1INT; | ||
499 | off = AU1000_INTC0_INT_BASE; | ||
500 | } else if (pending & CAUSEF_IP4) { | ||
501 | s = IC1_REQ0INT; | ||
502 | off = AU1000_INTC1_INT_BASE; | ||
503 | } else if (pending & CAUSEF_IP5) { | ||
504 | s = IC1_REQ1INT; | ||
505 | off = AU1000_INTC1_INT_BASE; | ||
506 | } else | ||
507 | goto spurious; | ||
508 | |||
509 | bit = 0; | ||
510 | s = au_readl(s); | ||
511 | if (unlikely(!s)) { | ||
512 | spurious: | ||
513 | spurious_interrupt(); | ||
514 | return; | ||
515 | } | ||
449 | #ifdef AU1000_USB_DEV_REQ_INT | 516 | #ifdef AU1000_USB_DEV_REQ_INT |
450 | /* | 517 | /* |
451 | * Because of the tight timing of SETUP token to reply | 518 | * Because of the tight timing of SETUP token to reply |
452 | * transactions, the USB devices-side packet complete | 519 | * transactions, the USB devices-side packet complete |
453 | * interrupt needs the highest priority. | 520 | * interrupt needs the highest priority. |
454 | */ | 521 | */ |
455 | if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) { | 522 | bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE); |
456 | intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT); | 523 | if ((pending & CAUSEF_IP2) && (s & bit)) { |
457 | do_IRQ(AU1000_USB_DEV_REQ_INT); | 524 | do_IRQ(AU1000_USB_DEV_REQ_INT); |
458 | return; | 525 | return; |
459 | } | 526 | } |
460 | #endif | 527 | #endif |
461 | bit = __ffs(intc0_req0); | 528 | do_IRQ(__ffs(s) + off); |
462 | intc0_req0 &= ~(1 << bit); | ||
463 | do_IRQ(AU1000_INTC0_INT_BASE + bit); | ||
464 | } | 529 | } |
465 | 530 | ||
466 | 531 | /* setup edge/level and assign request 0/1 */ | |
467 | static void intc0_req1_irqdispatch(void) | 532 | void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count) |
468 | { | ||
469 | static unsigned long intc0_req1; | ||
470 | unsigned int bit; | ||
471 | |||
472 | intc0_req1 |= au_readl(IC0_REQ1INT); | ||
473 | |||
474 | if (!intc0_req1) | ||
475 | return; | ||
476 | |||
477 | bit = __ffs(intc0_req1); | ||
478 | intc0_req1 &= ~(1 << bit); | ||
479 | do_IRQ(AU1000_INTC0_INT_BASE + bit); | ||
480 | } | ||
481 | |||
482 | |||
483 | /* | ||
484 | * Interrupt Controller 1: | ||
485 | * interrupts 32 - 63 | ||
486 | */ | ||
487 | static void intc1_req0_irqdispatch(void) | ||
488 | { | 533 | { |
489 | static unsigned long intc1_req0; | 534 | unsigned int bit, irq_nr; |
490 | unsigned int bit; | 535 | |
491 | 536 | while (count--) { | |
492 | intc1_req0 |= au_readl(IC1_REQ0INT); | 537 | irq_nr = map[count].im_irq; |
493 | 538 | ||
494 | if (!intc1_req0) | 539 | if (((irq_nr < AU1000_INTC0_INT_BASE) || |
495 | return; | 540 | (irq_nr >= AU1000_INTC0_INT_BASE + 32)) && |
496 | 541 | ((irq_nr < AU1000_INTC1_INT_BASE) || | |
497 | bit = __ffs(intc1_req0); | 542 | (irq_nr >= AU1000_INTC1_INT_BASE + 32))) |
498 | intc1_req0 &= ~(1 << bit); | 543 | continue; |
499 | do_IRQ(AU1000_INTC1_INT_BASE + bit); | 544 | |
500 | } | 545 | if (irq_nr >= AU1000_INTC1_INT_BASE) { |
501 | 546 | bit = irq_nr - AU1000_INTC1_INT_BASE; | |
502 | 547 | if (map[count].im_request) | |
503 | static void intc1_req1_irqdispatch(void) | 548 | au_writel(1 << bit, IC1_ASSIGNCLR); |
504 | { | 549 | } else { |
505 | static unsigned long intc1_req1; | 550 | bit = irq_nr - AU1000_INTC0_INT_BASE; |
506 | unsigned int bit; | 551 | if (map[count].im_request) |
507 | 552 | au_writel(1 << bit, IC0_ASSIGNCLR); | |
508 | intc1_req1 |= au_readl(IC1_REQ1INT); | 553 | } |
509 | |||
510 | if (!intc1_req1) | ||
511 | return; | ||
512 | |||
513 | bit = __ffs(intc1_req1); | ||
514 | intc1_req1 &= ~(1 << bit); | ||
515 | do_IRQ(AU1000_INTC1_INT_BASE + bit); | ||
516 | } | ||
517 | |||
518 | asmlinkage void plat_irq_dispatch(void) | ||
519 | { | ||
520 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
521 | 554 | ||
522 | if (pending & CAUSEF_IP7) | 555 | au1x_ic_settype(irq_nr, map[count].im_type); |
523 | do_IRQ(MIPS_CPU_IRQ_BASE + 7); | 556 | } |
524 | else if (pending & CAUSEF_IP2) | ||
525 | intc0_req0_irqdispatch(); | ||
526 | else if (pending & CAUSEF_IP3) | ||
527 | intc0_req1_irqdispatch(); | ||
528 | else if (pending & CAUSEF_IP4) | ||
529 | intc1_req0_irqdispatch(); | ||
530 | else if (pending & CAUSEF_IP5) | ||
531 | intc1_req1_irqdispatch(); | ||
532 | else | ||
533 | spurious_interrupt(); | ||
534 | } | 557 | } |
535 | 558 | ||
536 | void __init arch_init_irq(void) | 559 | void __init arch_init_irq(void) |
537 | { | 560 | { |
538 | int i; | 561 | int i; |
539 | struct au1xxx_irqmap *imp; | ||
540 | extern struct au1xxx_irqmap au1xxx_irq_map[]; | ||
541 | extern struct au1xxx_irqmap au1xxx_ic0_map[]; | ||
542 | extern int au1xxx_nr_irqs; | ||
543 | extern int au1xxx_ic0_nr_irqs; | ||
544 | 562 | ||
545 | /* | 563 | /* |
546 | * Initialize interrupt controllers to a safe state. | 564 | * Initialize interrupt controllers to a safe state. |
@@ -569,28 +587,25 @@ void __init arch_init_irq(void) | |||
569 | 587 | ||
570 | mips_cpu_irq_init(); | 588 | mips_cpu_irq_init(); |
571 | 589 | ||
572 | /* | 590 | /* register all 64 possible IC0+IC1 irq sources as type "none". |
573 | * Initialize IC0, which is fixed per processor. | 591 | * Use set_irq_type() to set edge/level behaviour at runtime. |
574 | */ | 592 | */ |
575 | imp = au1xxx_ic0_map; | 593 | for (i = AU1000_INTC0_INT_BASE; |
576 | for (i = 0; i < au1xxx_ic0_nr_irqs; i++) { | 594 | (i < AU1000_INTC0_INT_BASE + 32); i++) |
577 | setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); | 595 | au1x_ic_settype(i, IRQ_TYPE_NONE); |
578 | imp++; | 596 | |
579 | } | 597 | for (i = AU1000_INTC1_INT_BASE; |
598 | (i < AU1000_INTC1_INT_BASE + 32); i++) | ||
599 | au1x_ic_settype(i, IRQ_TYPE_NONE); | ||
580 | 600 | ||
581 | /* | 601 | /* |
582 | * Now set up the irq mapping for the board. | 602 | * Initialize IC0, which is fixed per processor. |
583 | */ | 603 | */ |
584 | imp = au1xxx_irq_map; | 604 | au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map)); |
585 | for (i = 0; i < au1xxx_nr_irqs; i++) { | ||
586 | setup_local_irq(imp->im_irq, imp->im_type, imp->im_request); | ||
587 | imp++; | ||
588 | } | ||
589 | |||
590 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4); | ||
591 | 605 | ||
592 | /* Board specific IRQ initialization. | 606 | /* Boards can register additional (GPIO-based) IRQs. |
593 | */ | 607 | */ |
594 | if (board_init_irq) | 608 | board_init_irq(); |
595 | board_init_irq(); | 609 | |
610 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3); | ||
596 | } | 611 | } |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index bd854a6d1d89..6ab7b42aa1be 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -35,25 +35,12 @@ | |||
35 | #include <linux/jiffies.h> | 35 | #include <linux/jiffies.h> |
36 | 36 | ||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/cacheflush.h> | ||
39 | #include <asm/mach-au1x00/au1000.h> | 38 | #include <asm/mach-au1x00/au1000.h> |
40 | 39 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | |
41 | #ifdef CONFIG_PM | 40 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
42 | |||
43 | #define DEBUG 1 | ||
44 | #ifdef DEBUG | ||
45 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args) | ||
46 | #else | ||
47 | #define DPRINTK(fmt, args...) | ||
48 | #endif | 41 | #endif |
49 | 42 | ||
50 | static void au1000_calibrate_delay(void); | 43 | #ifdef CONFIG_PM |
51 | |||
52 | extern unsigned long save_local_and_disable(int controller); | ||
53 | extern void restore_local_and_enable(int controller, unsigned long mask); | ||
54 | extern void local_enable_irq(unsigned int irq_nr); | ||
55 | |||
56 | static DEFINE_SPINLOCK(pm_lock); | ||
57 | 44 | ||
58 | /* | 45 | /* |
59 | * We need to save/restore a bunch of core registers that are | 46 | * We need to save/restore a bunch of core registers that are |
@@ -65,29 +52,16 @@ static DEFINE_SPINLOCK(pm_lock); | |||
65 | * We only have to save/restore registers that aren't otherwise | 52 | * We only have to save/restore registers that aren't otherwise |
66 | * done as part of a driver pm_* function. | 53 | * done as part of a driver pm_* function. |
67 | */ | 54 | */ |
68 | static unsigned int sleep_aux_pll_cntrl; | 55 | static unsigned int sleep_uart0_inten; |
69 | static unsigned int sleep_cpu_pll_cntrl; | 56 | static unsigned int sleep_uart0_fifoctl; |
70 | static unsigned int sleep_pin_function; | 57 | static unsigned int sleep_uart0_linectl; |
71 | static unsigned int sleep_uart0_inten; | 58 | static unsigned int sleep_uart0_clkdiv; |
72 | static unsigned int sleep_uart0_fifoctl; | 59 | static unsigned int sleep_uart0_enable; |
73 | static unsigned int sleep_uart0_linectl; | 60 | static unsigned int sleep_usb[2]; |
74 | static unsigned int sleep_uart0_clkdiv; | 61 | static unsigned int sleep_sys_clocks[5]; |
75 | static unsigned int sleep_uart0_enable; | 62 | static unsigned int sleep_sys_pinfunc; |
76 | static unsigned int sleep_usbhost_enable; | 63 | static unsigned int sleep_static_memctlr[4][3]; |
77 | static unsigned int sleep_usbdev_enable; | ||
78 | static unsigned int sleep_static_memctlr[4][3]; | ||
79 | 64 | ||
80 | /* | ||
81 | * Define this to cause the value you write to /proc/sys/pm/sleep to | ||
82 | * set the TOY timer for the amount of time you want to sleep. | ||
83 | * This is done mainly for testing, but may be useful in other cases. | ||
84 | * The value is number of 32KHz ticks to sleep. | ||
85 | */ | ||
86 | #define SLEEP_TEST_TIMEOUT 1 | ||
87 | #ifdef SLEEP_TEST_TIMEOUT | ||
88 | static int sleep_ticks; | ||
89 | void wakeup_counter0_set(int ticks); | ||
90 | #endif | ||
91 | 65 | ||
92 | static void save_core_regs(void) | 66 | static void save_core_regs(void) |
93 | { | 67 | { |
@@ -105,31 +79,45 @@ static void save_core_regs(void) | |||
105 | sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); | 79 | sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR); |
106 | sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); | 80 | sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK); |
107 | sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); | 81 | sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL); |
82 | au_sync(); | ||
108 | 83 | ||
84 | #ifndef CONFIG_SOC_AU1200 | ||
109 | /* Shutdown USB host/device. */ | 85 | /* Shutdown USB host/device. */ |
110 | sleep_usbhost_enable = au_readl(USB_HOST_CONFIG); | 86 | sleep_usb[0] = au_readl(USB_HOST_CONFIG); |
111 | 87 | ||
112 | /* There appears to be some undocumented reset register.... */ | 88 | /* There appears to be some undocumented reset register.... */ |
113 | au_writel(0, 0xb0100004); au_sync(); | 89 | au_writel(0, 0xb0100004); |
114 | au_writel(0, USB_HOST_CONFIG); au_sync(); | 90 | au_sync(); |
91 | au_writel(0, USB_HOST_CONFIG); | ||
92 | au_sync(); | ||
115 | 93 | ||
116 | sleep_usbdev_enable = au_readl(USBD_ENABLE); | 94 | sleep_usb[1] = au_readl(USBD_ENABLE); |
117 | au_writel(0, USBD_ENABLE); au_sync(); | 95 | au_writel(0, USBD_ENABLE); |
96 | au_sync(); | ||
97 | |||
98 | #else /* AU1200 */ | ||
99 | |||
100 | /* enable access to OTG mmio so we can save OTG CAP/MUX. | ||
101 | * FIXME: write an OTG driver and move this stuff there! | ||
102 | */ | ||
103 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
104 | au_sync(); | ||
105 | sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */ | ||
106 | sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */ | ||
107 | #endif | ||
118 | 108 | ||
119 | /* Save interrupt controller state. */ | 109 | /* Save interrupt controller state. */ |
120 | save_au1xxx_intctl(); | 110 | save_au1xxx_intctl(); |
121 | 111 | ||
122 | /* Clocks and PLLs. */ | 112 | /* Clocks and PLLs. */ |
123 | sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL); | 113 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); |
114 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); | ||
115 | sleep_sys_clocks[2] = au_readl(SYS_CLKSRC); | ||
116 | sleep_sys_clocks[3] = au_readl(SYS_CPUPLL); | ||
117 | sleep_sys_clocks[4] = au_readl(SYS_AUXPLL); | ||
124 | 118 | ||
125 | /* | 119 | /* pin mux config */ |
126 | * We don't really need to do this one, but unless we | 120 | sleep_sys_pinfunc = au_readl(SYS_PINFUNC); |
127 | * write it again it won't have a valid value if we | ||
128 | * happen to read it. | ||
129 | */ | ||
130 | sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL); | ||
131 | |||
132 | sleep_pin_function = au_readl(SYS_PINFUNC); | ||
133 | 121 | ||
134 | /* Save the static memory controller configuration. */ | 122 | /* Save the static memory controller configuration. */ |
135 | sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); | 123 | sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); |
@@ -144,16 +132,45 @@ static void save_core_regs(void) | |||
144 | sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); | 132 | sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); |
145 | sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); | 133 | sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); |
146 | sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); | 134 | sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); |
135 | |||
136 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
137 | au1xxx_dbdma_suspend(); | ||
138 | #endif | ||
147 | } | 139 | } |
148 | 140 | ||
149 | static void restore_core_regs(void) | 141 | static void restore_core_regs(void) |
150 | { | 142 | { |
151 | extern void restore_au1xxx_intctl(void); | 143 | /* restore clock configuration. Writing CPUPLL last will |
152 | extern void wakeup_counter0_adjust(void); | 144 | * stall a bit and stabilize other clocks (unless this is |
145 | * one of those Au1000 with a write-only PLL, where we dont | ||
146 | * have a valid value) | ||
147 | */ | ||
148 | au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0); | ||
149 | au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1); | ||
150 | au_writel(sleep_sys_clocks[2], SYS_CLKSRC); | ||
151 | au_writel(sleep_sys_clocks[4], SYS_AUXPLL); | ||
152 | if (!au1xxx_cpu_has_pll_wo()) | ||
153 | au_writel(sleep_sys_clocks[3], SYS_CPUPLL); | ||
154 | au_sync(); | ||
153 | 155 | ||
154 | au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync(); | 156 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); |
155 | au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync(); | 157 | au_sync(); |
156 | au_writel(sleep_pin_function, SYS_PINFUNC); au_sync(); | 158 | |
159 | #ifndef CONFIG_SOC_AU1200 | ||
160 | au_writel(sleep_usb[0], USB_HOST_CONFIG); | ||
161 | au_writel(sleep_usb[1], USBD_ENABLE); | ||
162 | au_sync(); | ||
163 | #else | ||
164 | /* enable accces to OTG memory */ | ||
165 | au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); | ||
166 | au_sync(); | ||
167 | |||
168 | /* restore OTG caps and port mux. */ | ||
169 | au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */ | ||
170 | au_sync(); | ||
171 | au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */ | ||
172 | au_sync(); | ||
173 | #endif | ||
157 | 174 | ||
158 | /* Restore the static memory controller configuration. */ | 175 | /* Restore the static memory controller configuration. */ |
159 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); | 176 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); |
@@ -184,282 +201,17 @@ static void restore_core_regs(void) | |||
184 | } | 201 | } |
185 | 202 | ||
186 | restore_au1xxx_intctl(); | 203 | restore_au1xxx_intctl(); |
187 | wakeup_counter0_adjust(); | ||
188 | } | ||
189 | |||
190 | unsigned long suspend_mode; | ||
191 | 204 | ||
192 | void wakeup_from_suspend(void) | 205 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) |
193 | { | 206 | au1xxx_dbdma_resume(); |
194 | suspend_mode = 0; | 207 | #endif |
195 | } | 208 | } |
196 | 209 | ||
197 | int au_sleep(void) | 210 | void au_sleep(void) |
198 | { | 211 | { |
199 | unsigned long wakeup, flags; | ||
200 | extern void save_and_sleep(void); | ||
201 | |||
202 | spin_lock_irqsave(&pm_lock, flags); | ||
203 | |||
204 | save_core_regs(); | 212 | save_core_regs(); |
205 | 213 | au1xxx_save_and_sleep(); | |
206 | flush_cache_all(); | ||
207 | |||
208 | /** | ||
209 | ** The code below is all system dependent and we should probably | ||
210 | ** have a function call out of here to set this up. You need | ||
211 | ** to configure the GPIO or timer interrupts that will bring | ||
212 | ** you out of sleep. | ||
213 | ** For testing, the TOY counter wakeup is useful. | ||
214 | **/ | ||
215 | #if 0 | ||
216 | au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD); | ||
217 | |||
218 | /* GPIO 6 can cause a wake up event */ | ||
219 | wakeup = au_readl(SYS_WAKEMSK); | ||
220 | wakeup &= ~(1 << 8); /* turn off match20 wakeup */ | ||
221 | wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */ | ||
222 | #else | ||
223 | /* For testing, allow match20 to wake us up. */ | ||
224 | #ifdef SLEEP_TEST_TIMEOUT | ||
225 | wakeup_counter0_set(sleep_ticks); | ||
226 | #endif | ||
227 | wakeup = 1 << 8; /* turn on match20 wakeup */ | ||
228 | wakeup = 0; | ||
229 | #endif | ||
230 | au_writel(1, SYS_WAKESRC); /* clear cause */ | ||
231 | au_sync(); | ||
232 | au_writel(wakeup, SYS_WAKEMSK); | ||
233 | au_sync(); | ||
234 | |||
235 | save_and_sleep(); | ||
236 | |||
237 | /* | ||
238 | * After a wakeup, the cpu vectors back to 0x1fc00000, so | ||
239 | * it's up to the boot code to get us back here. | ||
240 | */ | ||
241 | restore_core_regs(); | 214 | restore_core_regs(); |
242 | spin_unlock_irqrestore(&pm_lock, flags); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int pm_do_sleep(ctl_table *ctl, int write, struct file *file, | ||
247 | void __user *buffer, size_t *len, loff_t *ppos) | ||
248 | { | ||
249 | #ifdef SLEEP_TEST_TIMEOUT | ||
250 | #define TMPBUFLEN2 16 | ||
251 | char buf[TMPBUFLEN2], *p; | ||
252 | #endif | ||
253 | |||
254 | if (!write) | ||
255 | *len = 0; | ||
256 | else { | ||
257 | #ifdef SLEEP_TEST_TIMEOUT | ||
258 | if (*len > TMPBUFLEN2 - 1) | ||
259 | return -EFAULT; | ||
260 | if (copy_from_user(buf, buffer, *len)) | ||
261 | return -EFAULT; | ||
262 | buf[*len] = 0; | ||
263 | p = buf; | ||
264 | sleep_ticks = simple_strtoul(p, &p, 0); | ||
265 | #endif | ||
266 | |||
267 | au_sleep(); | ||
268 | } | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | static int pm_do_freq(ctl_table *ctl, int write, struct file *file, | ||
273 | void __user *buffer, size_t *len, loff_t *ppos) | ||
274 | { | ||
275 | int retval = 0, i; | ||
276 | unsigned long val, pll; | ||
277 | #define TMPBUFLEN 64 | ||
278 | #define MAX_CPU_FREQ 396 | ||
279 | char buf[TMPBUFLEN], *p; | ||
280 | unsigned long flags, intc0_mask, intc1_mask; | ||
281 | unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh; | ||
282 | unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh; | ||
283 | unsigned long baud_rate; | ||
284 | |||
285 | spin_lock_irqsave(&pm_lock, flags); | ||
286 | if (!write) | ||
287 | *len = 0; | ||
288 | else { | ||
289 | /* Parse the new frequency */ | ||
290 | if (*len > TMPBUFLEN - 1) { | ||
291 | spin_unlock_irqrestore(&pm_lock, flags); | ||
292 | return -EFAULT; | ||
293 | } | ||
294 | if (copy_from_user(buf, buffer, *len)) { | ||
295 | spin_unlock_irqrestore(&pm_lock, flags); | ||
296 | return -EFAULT; | ||
297 | } | ||
298 | buf[*len] = 0; | ||
299 | p = buf; | ||
300 | val = simple_strtoul(p, &p, 0); | ||
301 | if (val > MAX_CPU_FREQ) { | ||
302 | spin_unlock_irqrestore(&pm_lock, flags); | ||
303 | return -EFAULT; | ||
304 | } | ||
305 | |||
306 | pll = val / 12; | ||
307 | if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */ | ||
308 | /* Revisit this for higher speed CPUs */ | ||
309 | spin_unlock_irqrestore(&pm_lock, flags); | ||
310 | return -EFAULT; | ||
311 | } | ||
312 | |||
313 | old_baud_base = get_au1x00_uart_baud_base(); | ||
314 | old_cpu_freq = get_au1x00_speed(); | ||
315 | |||
316 | new_cpu_freq = pll * 12 * 1000000; | ||
317 | new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL) | ||
318 | & 0x03) + 2) * 16)); | ||
319 | set_au1x00_speed(new_cpu_freq); | ||
320 | set_au1x00_uart_baud_base(new_baud_base); | ||
321 | |||
322 | old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff; | ||
323 | new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) | | ||
324 | (au_readl(MEM_SDREFCFG) & ~0x1ffffff); | ||
325 | |||
326 | au_writel(pll, SYS_CPUPLL); | ||
327 | au_sync_delay(1); | ||
328 | au_writel(new_refresh, MEM_SDREFCFG); | ||
329 | au_sync_delay(1); | ||
330 | |||
331 | for (i = 0; i < 4; i++) | ||
332 | if (au_readl(UART_BASE + UART_MOD_CNTRL + | ||
333 | i * 0x00100000) == 3) { | ||
334 | old_clk = au_readl(UART_BASE + UART_CLK + | ||
335 | i * 0x00100000); | ||
336 | baud_rate = old_baud_base / old_clk; | ||
337 | /* | ||
338 | * We won't get an exact baud rate and the error | ||
339 | * could be significant enough that our new | ||
340 | * calculation will result in a clock that will | ||
341 | * give us a baud rate that's too far off from | ||
342 | * what we really want. | ||
343 | */ | ||
344 | if (baud_rate > 100000) | ||
345 | baud_rate = 115200; | ||
346 | else if (baud_rate > 50000) | ||
347 | baud_rate = 57600; | ||
348 | else if (baud_rate > 30000) | ||
349 | baud_rate = 38400; | ||
350 | else if (baud_rate > 17000) | ||
351 | baud_rate = 19200; | ||
352 | else | ||
353 | baud_rate = 9600; | ||
354 | new_clk = new_baud_base / baud_rate; | ||
355 | au_writel(new_clk, UART_BASE + UART_CLK + | ||
356 | i * 0x00100000); | ||
357 | au_sync_delay(10); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * We don't want _any_ interrupts other than match20. Otherwise our | ||
363 | * au1000_calibrate_delay() calculation will be off, potentially a lot. | ||
364 | */ | ||
365 | intc0_mask = save_local_and_disable(0); | ||
366 | intc1_mask = save_local_and_disable(1); | ||
367 | local_enable_irq(AU1000_TOY_MATCH2_INT); | ||
368 | spin_unlock_irqrestore(&pm_lock, flags); | ||
369 | au1000_calibrate_delay(); | ||
370 | restore_local_and_enable(0, intc0_mask); | ||
371 | restore_local_and_enable(1, intc1_mask); | ||
372 | |||
373 | return retval; | ||
374 | } | 215 | } |
375 | 216 | ||
376 | |||
377 | static struct ctl_table pm_table[] = { | ||
378 | { | ||
379 | .ctl_name = CTL_UNNUMBERED, | ||
380 | .procname = "sleep", | ||
381 | .data = NULL, | ||
382 | .maxlen = 0, | ||
383 | .mode = 0600, | ||
384 | .proc_handler = &pm_do_sleep | ||
385 | }, | ||
386 | { | ||
387 | .ctl_name = CTL_UNNUMBERED, | ||
388 | .procname = "freq", | ||
389 | .data = NULL, | ||
390 | .maxlen = 0, | ||
391 | .mode = 0600, | ||
392 | .proc_handler = &pm_do_freq | ||
393 | }, | ||
394 | {} | ||
395 | }; | ||
396 | |||
397 | static struct ctl_table pm_dir_table[] = { | ||
398 | { | ||
399 | .ctl_name = CTL_UNNUMBERED, | ||
400 | .procname = "pm", | ||
401 | .mode = 0555, | ||
402 | .child = pm_table | ||
403 | }, | ||
404 | {} | ||
405 | }; | ||
406 | |||
407 | /* | ||
408 | * Initialize power interface | ||
409 | */ | ||
410 | static int __init pm_init(void) | ||
411 | { | ||
412 | register_sysctl_table(pm_dir_table); | ||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | __initcall(pm_init); | ||
417 | |||
418 | /* | ||
419 | * This is right out of init/main.c | ||
420 | */ | ||
421 | |||
422 | /* | ||
423 | * This is the number of bits of precision for the loops_per_jiffy. | ||
424 | * Each bit takes on average 1.5/HZ seconds. This (like the original) | ||
425 | * is a little better than 1%. | ||
426 | */ | ||
427 | #define LPS_PREC 8 | ||
428 | |||
429 | static void au1000_calibrate_delay(void) | ||
430 | { | ||
431 | unsigned long ticks, loopbit; | ||
432 | int lps_precision = LPS_PREC; | ||
433 | |||
434 | loops_per_jiffy = 1 << 12; | ||
435 | |||
436 | while (loops_per_jiffy <<= 1) { | ||
437 | /* Wait for "start of" clock tick */ | ||
438 | ticks = jiffies; | ||
439 | while (ticks == jiffies) | ||
440 | /* nothing */ ; | ||
441 | /* Go ... */ | ||
442 | ticks = jiffies; | ||
443 | __delay(loops_per_jiffy); | ||
444 | ticks = jiffies - ticks; | ||
445 | if (ticks) | ||
446 | break; | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * Do a binary approximation to get loops_per_jiffy set to be equal | ||
451 | * one clock (up to lps_precision bits) | ||
452 | */ | ||
453 | loops_per_jiffy >>= 1; | ||
454 | loopbit = loops_per_jiffy; | ||
455 | while (lps_precision-- && (loopbit >>= 1)) { | ||
456 | loops_per_jiffy |= loopbit; | ||
457 | ticks = jiffies; | ||
458 | while (ticks == jiffies); | ||
459 | ticks = jiffies; | ||
460 | __delay(loops_per_jiffy); | ||
461 | if (jiffies != ticks) /* longer than 1 tick */ | ||
462 | loops_per_jiffy &= ~loopbit; | ||
463 | } | ||
464 | } | ||
465 | #endif /* CONFIG_PM */ | 217 | #endif /* CONFIG_PM */ |
diff --git a/arch/mips/alchemy/common/reset.c b/arch/mips/alchemy/common/reset.c index d555429c8d6f..0191c936cb5e 100644 --- a/arch/mips/alchemy/common/reset.c +++ b/arch/mips/alchemy/common/reset.c | |||
@@ -31,8 +31,6 @@ | |||
31 | 31 | ||
32 | #include <asm/mach-au1x00/au1000.h> | 32 | #include <asm/mach-au1x00/au1000.h> |
33 | 33 | ||
34 | extern int au_sleep(void); | ||
35 | |||
36 | void au1000_restart(char *command) | 34 | void au1000_restart(char *command) |
37 | { | 35 | { |
38 | /* Set all integrated peripherals to disabled states */ | 36 | /* Set all integrated peripherals to disabled states */ |
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 1ac6b06f42a3..3f036b3d400e 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/time.h> | 35 | #include <asm/time.h> |
36 | 36 | ||
37 | #include <au1000.h> | 37 | #include <au1000.h> |
38 | #include <prom.h> | ||
39 | 38 | ||
40 | extern void __init board_setup(void); | 39 | extern void __init board_setup(void); |
41 | extern void au1000_restart(char *); | 40 | extern void au1000_restart(char *); |
@@ -45,80 +44,34 @@ extern void set_cpuspec(void); | |||
45 | 44 | ||
46 | void __init plat_mem_setup(void) | 45 | void __init plat_mem_setup(void) |
47 | { | 46 | { |
48 | struct cpu_spec *sp; | 47 | unsigned long est_freq; |
49 | char *argptr; | ||
50 | unsigned long prid, cpufreq, bclk; | ||
51 | 48 | ||
52 | set_cpuspec(); | 49 | /* determine core clock */ |
53 | sp = cur_cpu_spec[0]; | 50 | est_freq = au1xxx_calc_clock(); |
51 | est_freq += 5000; /* round */ | ||
52 | est_freq -= est_freq % 10000; | ||
53 | printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(), | ||
54 | est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); | ||
54 | 55 | ||
55 | board_setup(); /* board specific setup */ | 56 | _machine_restart = au1000_restart; |
56 | 57 | _machine_halt = au1000_halt; | |
57 | prid = read_c0_prid(); | 58 | pm_power_off = au1000_power_off; |
58 | if (sp->cpu_pll_wo) | ||
59 | #ifdef CONFIG_SOC_AU1000_FREQUENCY | ||
60 | cpufreq = CONFIG_SOC_AU1000_FREQUENCY / 1000000; | ||
61 | #else | ||
62 | cpufreq = 396; | ||
63 | #endif | ||
64 | else | ||
65 | cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12; | ||
66 | printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq); | ||
67 | 59 | ||
68 | if (sp->cpu_bclk) { | 60 | board_setup(); /* board specific setup */ |
69 | /* Enable BCLK switching */ | ||
70 | bclk = au_readl(SYS_POWERCTRL); | ||
71 | au_writel(bclk | 0x60, SYS_POWERCTRL); | ||
72 | printk(KERN_INFO "BCLK switching enabled!\n"); | ||
73 | } | ||
74 | 61 | ||
75 | if (sp->cpu_od) | 62 | if (au1xxx_cpu_needs_config_od()) |
76 | /* Various early Au1xx0 errata corrected by this */ | 63 | /* Various early Au1xx0 errata corrected by this */ |
77 | set_c0_config(1 << 19); /* Set Config[OD] */ | 64 | set_c0_config(1 << 19); /* Set Config[OD] */ |
78 | else | 65 | else |
79 | /* Clear to obtain best system bus performance */ | 66 | /* Clear to obtain best system bus performance */ |
80 | clear_c0_config(1 << 19); /* Clear Config[OD] */ | 67 | clear_c0_config(1 << 19); /* Clear Config[OD] */ |
81 | 68 | ||
82 | argptr = prom_getcmdline(); | ||
83 | |||
84 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
85 | argptr = strstr(argptr, "console="); | ||
86 | if (argptr == NULL) { | ||
87 | argptr = prom_getcmdline(); | ||
88 | strcat(argptr, " console=ttyS0,115200"); | ||
89 | } | ||
90 | #endif | ||
91 | |||
92 | #ifdef CONFIG_FB_AU1100 | ||
93 | argptr = strstr(argptr, "video="); | ||
94 | if (argptr == NULL) { | ||
95 | argptr = prom_getcmdline(); | ||
96 | /* default panel */ | ||
97 | /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ | ||
98 | } | ||
99 | #endif | ||
100 | |||
101 | #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) | ||
102 | /* au1000 does not support vra, au1500 and au1100 do */ | ||
103 | strcat(argptr, " au1000_audio=vra"); | ||
104 | argptr = prom_getcmdline(); | ||
105 | #endif | ||
106 | _machine_restart = au1000_restart; | ||
107 | _machine_halt = au1000_halt; | ||
108 | pm_power_off = au1000_power_off; | ||
109 | |||
110 | /* IO/MEM resources. */ | 69 | /* IO/MEM resources. */ |
111 | set_io_port_base(0); | 70 | set_io_port_base(0); |
112 | ioport_resource.start = IOPORT_RESOURCE_START; | 71 | ioport_resource.start = IOPORT_RESOURCE_START; |
113 | ioport_resource.end = IOPORT_RESOURCE_END; | 72 | ioport_resource.end = IOPORT_RESOURCE_END; |
114 | iomem_resource.start = IOMEM_RESOURCE_START; | 73 | iomem_resource.start = IOMEM_RESOURCE_START; |
115 | iomem_resource.end = IOMEM_RESOURCE_END; | 74 | iomem_resource.end = IOMEM_RESOURCE_END; |
116 | |||
117 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S); | ||
118 | au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL); | ||
119 | au_sync(); | ||
120 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S); | ||
121 | au_writel(0, SYS_TOYTRIM); | ||
122 | } | 75 | } |
123 | 76 | ||
124 | #if defined(CONFIG_64BIT_PHYS_ADDR) | 77 | #if defined(CONFIG_64BIT_PHYS_ADDR) |
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S index 3006e270c8bc..4f4b16741d12 100644 --- a/arch/mips/alchemy/common/sleeper.S +++ b/arch/mips/alchemy/common/sleeper.S | |||
@@ -15,16 +15,17 @@ | |||
15 | #include <asm/regdef.h> | 15 | #include <asm/regdef.h> |
16 | #include <asm/stackframe.h> | 16 | #include <asm/stackframe.h> |
17 | 17 | ||
18 | .extern __flush_cache_all | ||
19 | |||
18 | .text | 20 | .text |
19 | .set macro | 21 | .set noreorder |
20 | .set noat | 22 | .set noat |
21 | .align 5 | 23 | .align 5 |
22 | 24 | ||
23 | /* Save all of the processor general registers and go to sleep. | 25 | /* Save all of the processor general registers and go to sleep. |
24 | * A wakeup condition will get us back here to restore the registers. | 26 | * A wakeup condition will get us back here to restore the registers. |
25 | */ | 27 | */ |
26 | LEAF(save_and_sleep) | 28 | LEAF(au1xxx_save_and_sleep) |
27 | |||
28 | subu sp, PT_SIZE | 29 | subu sp, PT_SIZE |
29 | sw $1, PT_R1(sp) | 30 | sw $1, PT_R1(sp) |
30 | sw $2, PT_R2(sp) | 31 | sw $2, PT_R2(sp) |
@@ -33,14 +34,6 @@ LEAF(save_and_sleep) | |||
33 | sw $5, PT_R5(sp) | 34 | sw $5, PT_R5(sp) |
34 | sw $6, PT_R6(sp) | 35 | sw $6, PT_R6(sp) |
35 | sw $7, PT_R7(sp) | 36 | sw $7, PT_R7(sp) |
36 | sw $8, PT_R8(sp) | ||
37 | sw $9, PT_R9(sp) | ||
38 | sw $10, PT_R10(sp) | ||
39 | sw $11, PT_R11(sp) | ||
40 | sw $12, PT_R12(sp) | ||
41 | sw $13, PT_R13(sp) | ||
42 | sw $14, PT_R14(sp) | ||
43 | sw $15, PT_R15(sp) | ||
44 | sw $16, PT_R16(sp) | 37 | sw $16, PT_R16(sp) |
45 | sw $17, PT_R17(sp) | 38 | sw $17, PT_R17(sp) |
46 | sw $18, PT_R18(sp) | 39 | sw $18, PT_R18(sp) |
@@ -49,12 +42,9 @@ LEAF(save_and_sleep) | |||
49 | sw $21, PT_R21(sp) | 42 | sw $21, PT_R21(sp) |
50 | sw $22, PT_R22(sp) | 43 | sw $22, PT_R22(sp) |
51 | sw $23, PT_R23(sp) | 44 | sw $23, PT_R23(sp) |
52 | sw $24, PT_R24(sp) | ||
53 | sw $25, PT_R25(sp) | ||
54 | sw $26, PT_R26(sp) | 45 | sw $26, PT_R26(sp) |
55 | sw $27, PT_R27(sp) | 46 | sw $27, PT_R27(sp) |
56 | sw $28, PT_R28(sp) | 47 | sw $28, PT_R28(sp) |
57 | sw $29, PT_R29(sp) | ||
58 | sw $30, PT_R30(sp) | 48 | sw $30, PT_R30(sp) |
59 | sw $31, PT_R31(sp) | 49 | sw $31, PT_R31(sp) |
60 | mfc0 k0, CP0_STATUS | 50 | mfc0 k0, CP0_STATUS |
@@ -66,20 +56,26 @@ LEAF(save_and_sleep) | |||
66 | mfc0 k0, CP0_CONFIG | 56 | mfc0 k0, CP0_CONFIG |
67 | sw k0, 0x14(sp) | 57 | sw k0, 0x14(sp) |
68 | 58 | ||
59 | /* flush caches to make sure context is in memory */ | ||
60 | la t1, __flush_cache_all | ||
61 | lw t0, 0(t1) | ||
62 | jalr t0 | ||
63 | nop | ||
64 | |||
69 | /* Now set up the scratch registers so the boot rom will | 65 | /* Now set up the scratch registers so the boot rom will |
70 | * return to this point upon wakeup. | 66 | * return to this point upon wakeup. |
67 | * sys_scratch0 : SP | ||
68 | * sys_scratch1 : RA | ||
71 | */ | 69 | */ |
72 | la k0, 1f | 70 | lui t3, 0xb190 /* sys_xxx */ |
73 | lui k1, 0xb190 | 71 | sw sp, 0x0018(t3) |
74 | ori k1, 0x18 | 72 | la k0, 3f /* resume path */ |
75 | sw sp, 0(k1) | 73 | sw k0, 0x001c(t3) |
76 | ori k1, 0x1c | ||
77 | sw k0, 0(k1) | ||
78 | 74 | ||
79 | /* Put SDRAM into self refresh. Preload instructions into cache, | 75 | /* Put SDRAM into self refresh: Preload instructions into cache, |
80 | * issue a precharge, then auto refresh, then sleep commands to it. | 76 | * issue a precharge, auto/self refresh, then sleep commands to it. |
81 | */ | 77 | */ |
82 | la t0, sdsleep | 78 | la t0, 1f |
83 | .set mips3 | 79 | .set mips3 |
84 | cache 0x14, 0(t0) | 80 | cache 0x14, 0(t0) |
85 | cache 0x14, 32(t0) | 81 | cache 0x14, 32(t0) |
@@ -87,24 +83,57 @@ LEAF(save_and_sleep) | |||
87 | cache 0x14, 96(t0) | 83 | cache 0x14, 96(t0) |
88 | .set mips0 | 84 | .set mips0 |
89 | 85 | ||
90 | sdsleep: | 86 | 1: lui a0, 0xb400 /* mem_xxx */ |
91 | lui k0, 0xb400 | 87 | #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || \ |
92 | sw zero, 0x001c(k0) /* Precharge */ | 88 | defined(CONFIG_SOC_AU1500) |
93 | sw zero, 0x0020(k0) /* Auto refresh */ | 89 | sw zero, 0x001c(a0) /* Precharge */ |
94 | sw zero, 0x0030(k0) /* SDRAM sleep */ | 90 | sync |
91 | sw zero, 0x0020(a0) /* Auto Refresh */ | ||
92 | sync | ||
93 | sw zero, 0x0030(a0) /* Sleep */ | ||
94 | sync | ||
95 | #endif | ||
96 | |||
97 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
98 | sw zero, 0x08c0(a0) /* Precharge */ | ||
95 | sync | 99 | sync |
100 | sw zero, 0x08d0(a0) /* Self Refresh */ | ||
101 | sync | ||
102 | |||
103 | /* wait for sdram to enter self-refresh mode */ | ||
104 | lui t0, 0x0100 | ||
105 | 2: lw t1, 0x0850(a0) /* mem_sdstat */ | ||
106 | and t2, t1, t0 | ||
107 | beq t2, zero, 2b | ||
108 | nop | ||
96 | 109 | ||
97 | lui k1, 0xb190 | 110 | /* disable SDRAM clocks */ |
98 | sw zero, 0x0078(k1) /* get ready to sleep */ | 111 | lui t0, 0xcfff |
112 | ori t0, t0, 0xffff | ||
113 | lw t1, 0x0840(a0) /* mem_sdconfiga */ | ||
114 | and t1, t0, t1 /* clear CE[1:0] */ | ||
115 | sw t1, 0x0840(a0) /* mem_sdconfiga */ | ||
99 | sync | 116 | sync |
100 | sw zero, 0x007c(k1) /* Put processor to sleep */ | 117 | #endif |
118 | |||
119 | /* put power supply and processor to sleep */ | ||
120 | sw zero, 0x0078(t3) /* sys_slppwr */ | ||
121 | sync | ||
122 | sw zero, 0x007c(t3) /* sys_sleep */ | ||
101 | sync | 123 | sync |
124 | nop | ||
125 | nop | ||
126 | nop | ||
127 | nop | ||
128 | nop | ||
129 | nop | ||
130 | nop | ||
131 | nop | ||
102 | 132 | ||
103 | /* This is where we return upon wakeup. | 133 | /* This is where we return upon wakeup. |
104 | * Reload all of the registers and return. | 134 | * Reload all of the registers and return. |
105 | */ | 135 | */ |
106 | 1: nop | 136 | 3: lw k0, 0x20(sp) |
107 | lw k0, 0x20(sp) | ||
108 | mtc0 k0, CP0_STATUS | 137 | mtc0 k0, CP0_STATUS |
109 | lw k0, 0x1c(sp) | 138 | lw k0, 0x1c(sp) |
110 | mtc0 k0, CP0_CONTEXT | 139 | mtc0 k0, CP0_CONTEXT |
@@ -113,10 +142,11 @@ sdsleep: | |||
113 | lw k0, 0x14(sp) | 142 | lw k0, 0x14(sp) |
114 | mtc0 k0, CP0_CONFIG | 143 | mtc0 k0, CP0_CONFIG |
115 | 144 | ||
116 | /* We need to catch the ealry Alchemy SOCs with | 145 | /* We need to catch the early Alchemy SOCs with |
117 | * the write-only Config[OD] bit and set it back to one... | 146 | * the write-only Config[OD] bit and set it back to one... |
118 | */ | 147 | */ |
119 | jal au1x00_fixup_config_od | 148 | jal au1x00_fixup_config_od |
149 | nop | ||
120 | lw $1, PT_R1(sp) | 150 | lw $1, PT_R1(sp) |
121 | lw $2, PT_R2(sp) | 151 | lw $2, PT_R2(sp) |
122 | lw $3, PT_R3(sp) | 152 | lw $3, PT_R3(sp) |
@@ -124,14 +154,6 @@ sdsleep: | |||
124 | lw $5, PT_R5(sp) | 154 | lw $5, PT_R5(sp) |
125 | lw $6, PT_R6(sp) | 155 | lw $6, PT_R6(sp) |
126 | lw $7, PT_R7(sp) | 156 | lw $7, PT_R7(sp) |
127 | lw $8, PT_R8(sp) | ||
128 | lw $9, PT_R9(sp) | ||
129 | lw $10, PT_R10(sp) | ||
130 | lw $11, PT_R11(sp) | ||
131 | lw $12, PT_R12(sp) | ||
132 | lw $13, PT_R13(sp) | ||
133 | lw $14, PT_R14(sp) | ||
134 | lw $15, PT_R15(sp) | ||
135 | lw $16, PT_R16(sp) | 157 | lw $16, PT_R16(sp) |
136 | lw $17, PT_R17(sp) | 158 | lw $17, PT_R17(sp) |
137 | lw $18, PT_R18(sp) | 159 | lw $18, PT_R18(sp) |
@@ -140,15 +162,11 @@ sdsleep: | |||
140 | lw $21, PT_R21(sp) | 162 | lw $21, PT_R21(sp) |
141 | lw $22, PT_R22(sp) | 163 | lw $22, PT_R22(sp) |
142 | lw $23, PT_R23(sp) | 164 | lw $23, PT_R23(sp) |
143 | lw $24, PT_R24(sp) | ||
144 | lw $25, PT_R25(sp) | ||
145 | lw $26, PT_R26(sp) | 165 | lw $26, PT_R26(sp) |
146 | lw $27, PT_R27(sp) | 166 | lw $27, PT_R27(sp) |
147 | lw $28, PT_R28(sp) | 167 | lw $28, PT_R28(sp) |
148 | lw $29, PT_R29(sp) | ||
149 | lw $30, PT_R30(sp) | 168 | lw $30, PT_R30(sp) |
150 | lw $31, PT_R31(sp) | 169 | lw $31, PT_R31(sp) |
151 | addiu sp, PT_SIZE | ||
152 | |||
153 | jr ra | 170 | jr ra |
154 | END(save_and_sleep) | 171 | addiu sp, PT_SIZE |
172 | END(au1xxx_save_and_sleep) | ||
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index 563d9390a872..32880146cbc1 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
2 | * | 3 | * |
4 | * Previous incarnations were: | ||
3 | * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com> | 5 | * Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com> |
4 | * Copied and modified Carsten Langgaard's time.c | 6 | * Copied and modified Carsten Langgaard's time.c |
5 | * | 7 | * |
@@ -23,244 +25,141 @@ | |||
23 | * | 25 | * |
24 | * ######################################################################## | 26 | * ######################################################################## |
25 | * | 27 | * |
26 | * Setting up the clock on the MIPS boards. | 28 | * Clocksource/event using the 32.768kHz-clocked Counter1 ('RTC' in the |
27 | * | 29 | * databooks). Firmware/Board init code must enable the counters in the |
28 | * We provide the clock interrupt processing and the timer offset compute | 30 | * counter control register, otherwise the CP0 counter clocksource/event |
29 | * functions. If CONFIG_PM is selected, we also ensure the 32KHz timer is | 31 | * will be installed instead (and use of 'wait' instruction is prohibited). |
30 | * available. -- Dan | ||
31 | */ | 32 | */ |
32 | 33 | ||
33 | #include <linux/types.h> | 34 | #include <linux/clockchips.h> |
34 | #include <linux/init.h> | 35 | #include <linux/clocksource.h> |
36 | #include <linux/interrupt.h> | ||
35 | #include <linux/spinlock.h> | 37 | #include <linux/spinlock.h> |
36 | 38 | ||
37 | #include <asm/mipsregs.h> | ||
38 | #include <asm/time.h> | 39 | #include <asm/time.h> |
39 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
40 | 41 | ||
41 | static int no_au1xxx_32khz; | 42 | /* 32kHz clock enabled and detected */ |
42 | extern int allow_au1k_wait; /* default off for CP0 Counter */ | 43 | #define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S) |
43 | |||
44 | #ifdef CONFIG_PM | ||
45 | #if HZ < 100 || HZ > 1000 | ||
46 | #error "unsupported HZ value! Must be in [100,1000]" | ||
47 | #endif | ||
48 | #define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */ | ||
49 | static unsigned long last_pc0, last_match20; | ||
50 | #endif | ||
51 | 44 | ||
52 | static DEFINE_SPINLOCK(time_lock); | 45 | extern int allow_au1k_wait; /* default off for CP0 Counter */ |
53 | |||
54 | unsigned long wtimer; | ||
55 | 46 | ||
56 | #ifdef CONFIG_PM | 47 | static cycle_t au1x_counter1_read(void) |
57 | static irqreturn_t counter0_irq(int irq, void *dev_id) | ||
58 | { | 48 | { |
59 | unsigned long pc0; | 49 | return au_readl(SYS_RTCREAD); |
60 | int time_elapsed; | ||
61 | static int jiffie_drift; | ||
62 | |||
63 | if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) { | ||
64 | /* should never happen! */ | ||
65 | printk(KERN_WARNING "counter 0 w status error\n"); | ||
66 | return IRQ_NONE; | ||
67 | } | ||
68 | |||
69 | pc0 = au_readl(SYS_TOYREAD); | ||
70 | if (pc0 < last_match20) | ||
71 | /* counter overflowed */ | ||
72 | time_elapsed = (0xffffffff - last_match20) + pc0; | ||
73 | else | ||
74 | time_elapsed = pc0 - last_match20; | ||
75 | |||
76 | while (time_elapsed > 0) { | ||
77 | do_timer(1); | ||
78 | #ifndef CONFIG_SMP | ||
79 | update_process_times(user_mode(get_irq_regs())); | ||
80 | #endif | ||
81 | time_elapsed -= MATCH20_INC; | ||
82 | last_match20 += MATCH20_INC; | ||
83 | jiffie_drift++; | ||
84 | } | ||
85 | |||
86 | last_pc0 = pc0; | ||
87 | au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); | ||
88 | au_sync(); | ||
89 | |||
90 | /* | ||
91 | * Our counter ticks at 10.009765625 ms/tick, we we're running | ||
92 | * almost 10 uS too slow per tick. | ||
93 | */ | ||
94 | |||
95 | if (jiffie_drift >= 999) { | ||
96 | jiffie_drift -= 999; | ||
97 | do_timer(1); /* increment jiffies by one */ | ||
98 | #ifndef CONFIG_SMP | ||
99 | update_process_times(user_mode(get_irq_regs())); | ||
100 | #endif | ||
101 | } | ||
102 | |||
103 | return IRQ_HANDLED; | ||
104 | } | 50 | } |
105 | 51 | ||
106 | struct irqaction counter0_action = { | 52 | static struct clocksource au1x_counter1_clocksource = { |
107 | .handler = counter0_irq, | 53 | .name = "alchemy-counter1", |
108 | .flags = IRQF_DISABLED, | 54 | .read = au1x_counter1_read, |
109 | .name = "alchemy-toy", | 55 | .mask = CLOCKSOURCE_MASK(32), |
110 | .dev_id = NULL, | 56 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
57 | .rating = 100, | ||
111 | }; | 58 | }; |
112 | 59 | ||
113 | /* When we wakeup from sleep, we have to "catch up" on all of the | 60 | static int au1x_rtcmatch2_set_next_event(unsigned long delta, |
114 | * timer ticks we have missed. | 61 | struct clock_event_device *cd) |
115 | */ | ||
116 | void wakeup_counter0_adjust(void) | ||
117 | { | 62 | { |
118 | unsigned long pc0; | 63 | delta += au_readl(SYS_RTCREAD); |
119 | int time_elapsed; | 64 | /* wait for register access */ |
120 | 65 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21) | |
121 | pc0 = au_readl(SYS_TOYREAD); | 66 | ; |
122 | if (pc0 < last_match20) | 67 | au_writel(delta, SYS_RTCMATCH2); |
123 | /* counter overflowed */ | ||
124 | time_elapsed = (0xffffffff - last_match20) + pc0; | ||
125 | else | ||
126 | time_elapsed = pc0 - last_match20; | ||
127 | |||
128 | while (time_elapsed > 0) { | ||
129 | time_elapsed -= MATCH20_INC; | ||
130 | last_match20 += MATCH20_INC; | ||
131 | } | ||
132 | |||
133 | last_pc0 = pc0; | ||
134 | au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); | ||
135 | au_sync(); | 68 | au_sync(); |
136 | 69 | ||
70 | return 0; | ||
137 | } | 71 | } |
138 | 72 | ||
139 | /* This is just for debugging to set the timer for a sleep delay. */ | 73 | static void au1x_rtcmatch2_set_mode(enum clock_event_mode mode, |
140 | void wakeup_counter0_set(int ticks) | 74 | struct clock_event_device *cd) |
141 | { | 75 | { |
142 | unsigned long pc0; | ||
143 | |||
144 | pc0 = au_readl(SYS_TOYREAD); | ||
145 | last_pc0 = pc0; | ||
146 | au_writel(last_match20 + (MATCH20_INC * ticks), SYS_TOYMATCH2); | ||
147 | au_sync(); | ||
148 | } | 76 | } |
149 | #endif | ||
150 | 77 | ||
151 | /* | 78 | static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id) |
152 | * I haven't found anyone that doesn't use a 12 MHz source clock, | ||
153 | * but just in case..... | ||
154 | */ | ||
155 | #define AU1000_SRC_CLK 12000000 | ||
156 | |||
157 | /* | ||
158 | * We read the real processor speed from the PLL. This is important | ||
159 | * because it is more accurate than computing it from the 32 KHz | ||
160 | * counter, if it exists. If we don't have an accurate processor | ||
161 | * speed, all of the peripherals that derive their clocks based on | ||
162 | * this advertised speed will introduce error and sometimes not work | ||
163 | * properly. This function is futher convoluted to still allow configurations | ||
164 | * to do that in case they have really, really old silicon with a | ||
165 | * write-only PLL register, that we need the 32 KHz when power management | ||
166 | * "wait" is enabled, and we need to detect if the 32 KHz isn't present | ||
167 | * but requested......got it? :-) -- Dan | ||
168 | */ | ||
169 | unsigned long calc_clock(void) | ||
170 | { | 79 | { |
171 | unsigned long cpu_speed; | 80 | struct clock_event_device *cd = dev_id; |
172 | unsigned long flags; | 81 | cd->event_handler(cd); |
173 | unsigned long counter; | 82 | return IRQ_HANDLED; |
174 | 83 | } | |
175 | spin_lock_irqsave(&time_lock, flags); | ||
176 | |||
177 | /* Power management cares if we don't have a 32 KHz counter. */ | ||
178 | no_au1xxx_32khz = 0; | ||
179 | counter = au_readl(SYS_COUNTER_CNTRL); | ||
180 | if (counter & SYS_CNTRL_E0) { | ||
181 | int trim_divide = 16; | ||
182 | |||
183 | au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL); | ||
184 | |||
185 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); | ||
186 | /* RTC now ticks at 32.768/16 kHz */ | ||
187 | au_writel(trim_divide - 1, SYS_RTCTRIM); | ||
188 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S); | ||
189 | 84 | ||
190 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); | 85 | static struct clock_event_device au1x_rtcmatch2_clockdev = { |
191 | au_writel(0, SYS_TOYWRITE); | 86 | .name = "rtcmatch2", |
192 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S); | 87 | .features = CLOCK_EVT_FEAT_ONESHOT, |
193 | } else | 88 | .rating = 100, |
194 | no_au1xxx_32khz = 1; | 89 | .irq = AU1000_RTC_MATCH2_INT, |
90 | .set_next_event = au1x_rtcmatch2_set_next_event, | ||
91 | .set_mode = au1x_rtcmatch2_set_mode, | ||
92 | .cpumask = CPU_MASK_ALL, | ||
93 | }; | ||
195 | 94 | ||
196 | /* | 95 | static struct irqaction au1x_rtcmatch2_irqaction = { |
197 | * On early Au1000, sys_cpupll was write-only. Since these | 96 | .handler = au1x_rtcmatch2_irq, |
198 | * silicon versions of Au1000 are not sold by AMD, we don't bend | 97 | .flags = IRQF_DISABLED | IRQF_TIMER, |
199 | * over backwards trying to determine the frequency. | 98 | .name = "timer", |
200 | */ | 99 | .dev_id = &au1x_rtcmatch2_clockdev, |
201 | if (cur_cpu_spec[0]->cpu_pll_wo) | 100 | }; |
202 | #ifdef CONFIG_SOC_AU1000_FREQUENCY | ||
203 | cpu_speed = CONFIG_SOC_AU1000_FREQUENCY; | ||
204 | #else | ||
205 | cpu_speed = 396000000; | ||
206 | #endif | ||
207 | else | ||
208 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; | ||
209 | /* On Alchemy CPU:counter ratio is 1:1 */ | ||
210 | mips_hpt_frequency = cpu_speed; | ||
211 | /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */ | ||
212 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) | ||
213 | & 0x03) + 2) * 16)); | ||
214 | spin_unlock_irqrestore(&time_lock, flags); | ||
215 | return cpu_speed; | ||
216 | } | ||
217 | 101 | ||
218 | void __init plat_time_init(void) | 102 | void __init plat_time_init(void) |
219 | { | 103 | { |
220 | unsigned int est_freq = calc_clock(); | 104 | struct clock_event_device *cd = &au1x_rtcmatch2_clockdev; |
221 | 105 | unsigned long t; | |
222 | est_freq += 5000; /* round */ | 106 | |
223 | est_freq -= est_freq%10000; | 107 | /* Check if firmware (YAMON, ...) has enabled 32kHz and clock |
224 | printk(KERN_INFO "CPU frequency %u.%02u MHz\n", | 108 | * has been detected. If so install the rtcmatch2 clocksource, |
225 | est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); | 109 | * otherwise don't bother. Note that both bits being set is by |
226 | set_au1x00_speed(est_freq); | 110 | * no means a definite guarantee that the counters actually work |
227 | set_au1x00_lcd_clock(); /* program the LCD clock */ | 111 | * (the 32S bit seems to be stuck set to 1 once a single clock- |
112 | * edge is detected, hence the timeouts). | ||
113 | */ | ||
114 | if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK)) | ||
115 | goto cntr_err; | ||
228 | 116 | ||
229 | #ifdef CONFIG_PM | ||
230 | /* | 117 | /* |
231 | * setup counter 0, since it keeps ticking after a | 118 | * setup counter 1 (RTC) to tick at full speed |
232 | * 'wait' instruction has been executed. The CP0 timer and | ||
233 | * counter 1 do NOT continue running after 'wait' | ||
234 | * | ||
235 | * It's too early to call request_irq() here, so we handle | ||
236 | * counter 0 interrupt as a special irq and it doesn't show | ||
237 | * up under /proc/interrupts. | ||
238 | * | ||
239 | * Check to ensure we really have a 32 KHz oscillator before | ||
240 | * we do this. | ||
241 | */ | 119 | */ |
242 | if (no_au1xxx_32khz) | 120 | t = 0xffffff; |
243 | printk(KERN_WARNING "WARNING: no 32KHz clock found.\n"); | 121 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && t--) |
244 | else { | 122 | asm volatile ("nop"); |
245 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); | 123 | if (!t) |
246 | au_writel(0, SYS_TOYWRITE); | 124 | goto cntr_err; |
247 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S); | ||
248 | |||
249 | au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK); | ||
250 | au_writel(~0, SYS_WAKESRC); | ||
251 | au_sync(); | ||
252 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | ||
253 | 125 | ||
254 | /* Setup match20 to interrupt once every HZ */ | 126 | au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */ |
255 | last_pc0 = last_match20 = au_readl(SYS_TOYREAD); | 127 | au_sync(); |
256 | au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2); | ||
257 | au_sync(); | ||
258 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20); | ||
259 | setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action); | ||
260 | 128 | ||
261 | /* We can use the real 'wait' instruction. */ | 129 | t = 0xffffff; |
262 | allow_au1k_wait = 1; | 130 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--) |
263 | } | 131 | asm volatile ("nop"); |
132 | if (!t) | ||
133 | goto cntr_err; | ||
134 | au_writel(0, SYS_RTCWRITE); | ||
135 | au_sync(); | ||
264 | 136 | ||
265 | #endif | 137 | t = 0xffffff; |
138 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--) | ||
139 | asm volatile ("nop"); | ||
140 | if (!t) | ||
141 | goto cntr_err; | ||
142 | |||
143 | /* register counter1 clocksource and event device */ | ||
144 | clocksource_set_clock(&au1x_counter1_clocksource, 32768); | ||
145 | clocksource_register(&au1x_counter1_clocksource); | ||
146 | |||
147 | cd->shift = 32; | ||
148 | cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift); | ||
149 | cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); | ||
150 | cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */ | ||
151 | clockevents_register_device(cd); | ||
152 | setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction); | ||
153 | |||
154 | printk(KERN_INFO "Alchemy clocksource installed\n"); | ||
155 | |||
156 | /* can now use 'wait' */ | ||
157 | allow_au1k_wait = 1; | ||
158 | return; | ||
159 | |||
160 | cntr_err: | ||
161 | /* counters unusable, use C0 counter */ | ||
162 | r4k_clockevent_init(); | ||
163 | init_r4k_clocksource(); | ||
164 | allow_au1k_wait = 0; | ||
266 | } | 165 | } |
diff --git a/arch/mips/alchemy/db1x00/init.c b/arch/mips/alchemy/db1x00/init.c deleted file mode 100644 index 847413514964..000000000000 --- a/arch/mips/alchemy/db1x00/init.c +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * PB1000 board setup | ||
4 | * | ||
5 | * Copyright 2001, 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 it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/kernel.h> | ||
31 | |||
32 | #include <asm/bootinfo.h> | ||
33 | |||
34 | #include <prom.h> | ||
35 | |||
36 | const char *get_system_type(void) | ||
37 | { | ||
38 | #ifdef CONFIG_MIPS_BOSPORUS | ||
39 | return "Alchemy Bosporus Gateway Reference"; | ||
40 | #else | ||
41 | return "Alchemy Db1x00"; | ||
42 | #endif | ||
43 | } | ||
44 | |||
45 | void __init prom_init(void) | ||
46 | { | ||
47 | unsigned char *memsize_str; | ||
48 | unsigned long memsize; | ||
49 | |||
50 | prom_argc = fw_arg0; | ||
51 | prom_argv = (char **)fw_arg1; | ||
52 | prom_envp = (char **)fw_arg2; | ||
53 | |||
54 | prom_init_cmdline(); | ||
55 | |||
56 | memsize_str = prom_getenv("memsize"); | ||
57 | if (!memsize_str) | ||
58 | memsize = 0x04000000; | ||
59 | else | ||
60 | strict_strtol(memsize_str, 0, &memsize); | ||
61 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
62 | } | ||
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile new file mode 100644 index 000000000000..730f9f2b30e8 --- /dev/null +++ b/arch/mips/alchemy/devboards/Makefile | |||
@@ -0,0 +1,18 @@ | |||
1 | # | ||
2 | # Alchemy Develboards | ||
3 | # | ||
4 | |||
5 | obj-y += prom.o | ||
6 | obj-$(CONFIG_PM) += pm.o | ||
7 | obj-$(CONFIG_MIPS_PB1000) += pb1000/ | ||
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) += pb1200/ | ||
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/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile index 274db3b55d82..432241ab8677 100644 --- a/arch/mips/alchemy/db1x00/Makefile +++ b/arch/mips/alchemy/devboards/db1x00/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # Makefile for the Alchemy Semiconductor DBAu1xx0 boards. | 5 | # Makefile for the Alchemy Semiconductor DBAu1xx0 boards. |
6 | # | 6 | # |
7 | 7 | ||
8 | lib-y := init.o board_setup.o irqmap.o | 8 | obj-y := board_setup.o irqmap.o |
diff --git a/arch/mips/alchemy/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c index 9e5ccbbfcedd..a75ffbf99f25 100644 --- a/arch/mips/alchemy/db1x00/board_setup.c +++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c | |||
@@ -32,8 +32,20 @@ | |||
32 | #include <asm/mach-au1x00/au1000.h> | 32 | #include <asm/mach-au1x00/au1000.h> |
33 | #include <asm/mach-db1x00/db1x00.h> | 33 | #include <asm/mach-db1x00/db1x00.h> |
34 | 34 | ||
35 | #include <prom.h> | ||
36 | |||
37 | |||
35 | static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; | 38 | static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR; |
36 | 39 | ||
40 | const char *get_system_type(void) | ||
41 | { | ||
42 | #ifdef CONFIG_MIPS_BOSPORUS | ||
43 | return "Alchemy Bosporus Gateway Reference"; | ||
44 | #else | ||
45 | return "Alchemy Db1x00"; | ||
46 | #endif | ||
47 | } | ||
48 | |||
37 | void board_reset(void) | 49 | void board_reset(void) |
38 | { | 50 | { |
39 | /* Hit BCSR.SW_RESET[RESET] */ | 51 | /* Hit BCSR.SW_RESET[RESET] */ |
@@ -43,6 +55,31 @@ void board_reset(void) | |||
43 | void __init board_setup(void) | 55 | void __init board_setup(void) |
44 | { | 56 | { |
45 | u32 pin_func = 0; | 57 | u32 pin_func = 0; |
58 | char *argptr; | ||
59 | |||
60 | argptr = prom_getcmdline(); | ||
61 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
62 | argptr = strstr(argptr, "console="); | ||
63 | if (argptr == NULL) { | ||
64 | argptr = prom_getcmdline(); | ||
65 | strcat(argptr, " console=ttyS0,115200"); | ||
66 | } | ||
67 | #endif | ||
68 | |||
69 | #ifdef CONFIG_FB_AU1100 | ||
70 | argptr = strstr(argptr, "video="); | ||
71 | if (argptr == NULL) { | ||
72 | argptr = prom_getcmdline(); | ||
73 | /* default panel */ | ||
74 | /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) | ||
79 | /* au1000 does not support vra, au1500 and au1100 do */ | ||
80 | strcat(argptr, " au1000_audio=vra"); | ||
81 | argptr = prom_getcmdline(); | ||
82 | #endif | ||
46 | 83 | ||
47 | /* Not valid for Au1550 */ | 84 | /* Not valid for Au1550 */ |
48 | #if defined(CONFIG_IRDA) && \ | 85 | #if defined(CONFIG_IRDA) && \ |
diff --git a/arch/mips/alchemy/db1x00/irqmap.c b/arch/mips/alchemy/devboards/db1x00/irqmap.c index 94c090e8bf7a..0b09025087c6 100644 --- a/arch/mips/alchemy/db1x00/irqmap.c +++ b/arch/mips/alchemy/devboards/db1x00/irqmap.c | |||
@@ -27,6 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/interrupt.h> | ||
30 | 31 | ||
31 | #include <asm/mach-au1x00/au1000.h> | 32 | #include <asm/mach-au1x00/au1000.h> |
32 | 33 | ||
@@ -66,21 +67,24 @@ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | |||
66 | 67 | ||
67 | #ifndef CONFIG_MIPS_MIRAGE | 68 | #ifndef CONFIG_MIPS_MIRAGE |
68 | #ifdef CONFIG_MIPS_DB1550 | 69 | #ifdef CONFIG_MIPS_DB1550 |
69 | { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */ | 70 | { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */ |
70 | { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */ | 71 | { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */ |
71 | #else | 72 | #else |
72 | { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 Fully_Interted# */ | 73 | { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 Fully_Interted# */ |
73 | { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 STSCHG# */ | 74 | { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 STSCHG# */ |
74 | { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */ | 75 | { AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */ |
75 | 76 | ||
76 | { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 Fully_Interted# */ | 77 | { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 Fully_Interted# */ |
77 | { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 STSCHG# */ | 78 | { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */ |
78 | { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */ | 79 | { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */ |
79 | #endif | 80 | #endif |
80 | #else | 81 | #else |
81 | { AU1000_GPIO_7, INTC_INT_RISE_EDGE, 0 }, /* touchscreen pen down */ | 82 | { AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */ |
82 | #endif | 83 | #endif |
83 | 84 | ||
84 | }; | 85 | }; |
85 | 86 | ||
86 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | 87 | void __init board_init_irq(void) |
88 | { | ||
89 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
90 | } | ||
diff --git a/arch/mips/alchemy/pb1000/Makefile b/arch/mips/alchemy/devboards/pb1000/Makefile index 99bbec0ca41b..97c6615ba2bb 100644 --- a/arch/mips/alchemy/pb1000/Makefile +++ b/arch/mips/alchemy/devboards/pb1000/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # Makefile for the Alchemy Semiconductor Pb1000 board. | 5 | # Makefile for the Alchemy Semiconductor Pb1000 board. |
6 | # | 6 | # |
7 | 7 | ||
8 | lib-y := init.o board_setup.o irqmap.o | 8 | obj-y := board_setup.o |
diff --git a/arch/mips/alchemy/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c index 25df167a95b3..aed2fdecc709 100644 --- a/arch/mips/alchemy/pb1000/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c | |||
@@ -23,22 +23,48 @@ | |||
23 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
28 | 27 | #include <linux/init.h> | |
28 | #include <linux/interrupt.h> | ||
29 | #include <asm/mach-au1x00/au1000.h> | 29 | #include <asm/mach-au1x00/au1000.h> |
30 | #include <asm/mach-pb1x00/pb1000.h> | 30 | #include <asm/mach-pb1x00/pb1000.h> |
31 | #include <prom.h> | ||
32 | |||
33 | |||
34 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
35 | { AU1000_GPIO_15, IRQF_TRIGGER_LOW, 0 }, | ||
36 | }; | ||
37 | |||
38 | |||
39 | const char *get_system_type(void) | ||
40 | { | ||
41 | return "Alchemy Pb1000"; | ||
42 | } | ||
31 | 43 | ||
32 | void board_reset(void) | 44 | void board_reset(void) |
33 | { | 45 | { |
34 | } | 46 | } |
35 | 47 | ||
48 | void __init board_init_irq(void) | ||
49 | { | ||
50 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
51 | } | ||
52 | |||
36 | void __init board_setup(void) | 53 | void __init board_setup(void) |
37 | { | 54 | { |
38 | u32 pin_func, static_cfg0; | 55 | u32 pin_func, static_cfg0; |
39 | u32 sys_freqctrl, sys_clksrc; | 56 | u32 sys_freqctrl, sys_clksrc; |
40 | u32 prid = read_c0_prid(); | 57 | u32 prid = read_c0_prid(); |
41 | 58 | ||
59 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
60 | char *argptr = prom_getcmdline(); | ||
61 | argptr = strstr(argptr, "console="); | ||
62 | if (argptr == NULL) { | ||
63 | argptr = prom_getcmdline(); | ||
64 | strcat(argptr, " console=ttyS0,115200"); | ||
65 | } | ||
66 | #endif | ||
67 | |||
42 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ | 68 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ |
43 | au_writel(8, SYS_AUXPLL); | 69 | au_writel(8, SYS_AUXPLL); |
44 | au_writel(0, SYS_PINSTATERD); | 70 | au_writel(0, SYS_PINSTATERD); |
diff --git a/arch/mips/alchemy/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile index 793e97c49e46..c586dd7e91dc 100644 --- a/arch/mips/alchemy/pb1100/Makefile +++ b/arch/mips/alchemy/devboards/pb1100/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # Makefile for the Alchemy Semiconductor Pb1100 board. | 5 | # Makefile for the Alchemy Semiconductor Pb1100 board. |
6 | # | 6 | # |
7 | 7 | ||
8 | lib-y := init.o board_setup.o irqmap.o | 8 | obj-y := board_setup.o |
diff --git a/arch/mips/alchemy/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c index c0bfd59a7a36..4df57fae15d4 100644 --- a/arch/mips/alchemy/pb1100/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c | |||
@@ -25,19 +25,66 @@ | |||
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/interrupt.h> | ||
28 | 29 | ||
29 | #include <asm/mach-au1x00/au1000.h> | 30 | #include <asm/mach-au1x00/au1000.h> |
30 | #include <asm/mach-pb1x00/pb1100.h> | 31 | #include <asm/mach-pb1x00/pb1100.h> |
31 | 32 | ||
33 | #include <prom.h> | ||
34 | |||
35 | |||
36 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
37 | { AU1000_GPIO_9, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card Fully_Inserted# */ | ||
38 | { AU1000_GPIO_10, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card STSCHG# */ | ||
39 | { AU1000_GPIO_11, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card IRQ# */ | ||
40 | { AU1000_GPIO_13, IRQF_TRIGGER_LOW, 0 }, /* DC_IRQ# */ | ||
41 | }; | ||
42 | |||
43 | |||
44 | const char *get_system_type(void) | ||
45 | { | ||
46 | return "Alchemy Pb1100"; | ||
47 | } | ||
48 | |||
32 | void board_reset(void) | 49 | void board_reset(void) |
33 | { | 50 | { |
34 | /* Hit BCSR.RST_VDDI[SOFT_RESET] */ | 51 | /* Hit BCSR.RST_VDDI[SOFT_RESET] */ |
35 | au_writel(0x00000000, PB1100_RST_VDDI); | 52 | au_writel(0x00000000, PB1100_RST_VDDI); |
36 | } | 53 | } |
37 | 54 | ||
55 | void __init board_init_irq(void) | ||
56 | { | ||
57 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
58 | } | ||
59 | |||
38 | void __init board_setup(void) | 60 | void __init board_setup(void) |
39 | { | 61 | { |
40 | volatile void __iomem *base = (volatile void __iomem *)0xac000000UL; | 62 | volatile void __iomem *base = (volatile void __iomem *)0xac000000UL; |
63 | char *argptr; | ||
64 | |||
65 | argptr = prom_getcmdline(); | ||
66 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
67 | argptr = strstr(argptr, "console="); | ||
68 | if (argptr == NULL) { | ||
69 | argptr = prom_getcmdline(); | ||
70 | strcat(argptr, " console=ttyS0,115200"); | ||
71 | } | ||
72 | #endif | ||
73 | |||
74 | #ifdef CONFIG_FB_AU1100 | ||
75 | argptr = strstr(argptr, "video="); | ||
76 | if (argptr == NULL) { | ||
77 | argptr = prom_getcmdline(); | ||
78 | /* default panel */ | ||
79 | /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/ | ||
80 | } | ||
81 | #endif | ||
82 | |||
83 | #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) | ||
84 | /* au1000 does not support vra, au1500 and au1100 do */ | ||
85 | strcat(argptr, " au1000_audio=vra"); | ||
86 | argptr = prom_getcmdline(); | ||
87 | #endif | ||
41 | 88 | ||
42 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ | 89 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ |
43 | au_writel(8, SYS_AUXPLL); | 90 | au_writel(8, SYS_AUXPLL); |
diff --git a/arch/mips/alchemy/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile index d678adf7ce85..c8c3a99fb68a 100644 --- a/arch/mips/alchemy/pb1200/Makefile +++ b/arch/mips/alchemy/devboards/pb1200/Makefile | |||
@@ -2,7 +2,6 @@ | |||
2 | # Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards. | 2 | # Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards. |
3 | # | 3 | # |
4 | 4 | ||
5 | lib-y := init.o board_setup.o irqmap.o | 5 | obj-y := board_setup.o irqmap.o platform.o |
6 | obj-y += platform.o | ||
7 | 6 | ||
8 | EXTRA_CFLAGS += -Werror | 7 | EXTRA_CFLAGS += -Werror |
diff --git a/arch/mips/alchemy/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c index 6cb2115059ad..94e6b7e7753d 100644 --- a/arch/mips/alchemy/pb1200/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c | |||
@@ -30,8 +30,11 @@ | |||
30 | #include <prom.h> | 30 | #include <prom.h> |
31 | #include <au1xxx.h> | 31 | #include <au1xxx.h> |
32 | 32 | ||
33 | extern void _board_init_irq(void); | 33 | |
34 | extern void (*board_init_irq)(void); | 34 | const char *get_system_type(void) |
35 | { | ||
36 | return "Alchemy Pb1200"; | ||
37 | } | ||
35 | 38 | ||
36 | void board_reset(void) | 39 | void board_reset(void) |
37 | { | 40 | { |
@@ -41,7 +44,19 @@ void board_reset(void) | |||
41 | 44 | ||
42 | void __init board_setup(void) | 45 | void __init board_setup(void) |
43 | { | 46 | { |
44 | char *argptr = NULL; | 47 | char *argptr; |
48 | |||
49 | argptr = prom_getcmdline(); | ||
50 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
51 | argptr = strstr(argptr, "console="); | ||
52 | if (argptr == NULL) { | ||
53 | argptr = prom_getcmdline(); | ||
54 | strcat(argptr, " console=ttyS0,115200"); | ||
55 | } | ||
56 | #endif | ||
57 | #ifdef CONFIG_FB_AU1200 | ||
58 | strcat(argptr, " video=au1200fb:panel:bs"); | ||
59 | #endif | ||
45 | 60 | ||
46 | #if 0 | 61 | #if 0 |
47 | { | 62 | { |
@@ -99,16 +114,6 @@ void __init board_setup(void) | |||
99 | } | 114 | } |
100 | #endif | 115 | #endif |
101 | 116 | ||
102 | #ifdef CONFIG_FB_AU1200 | ||
103 | argptr = prom_getcmdline(); | ||
104 | #ifdef CONFIG_MIPS_PB1200 | ||
105 | strcat(argptr, " video=au1200fb:panel:bs"); | ||
106 | #endif | ||
107 | #ifdef CONFIG_MIPS_DB1200 | ||
108 | strcat(argptr, " video=au1200fb:panel:bs"); | ||
109 | #endif | ||
110 | #endif | ||
111 | |||
112 | /* | 117 | /* |
113 | * The Pb1200 development board uses external MUX for PSC0 to | 118 | * The Pb1200 development board uses external MUX for PSC0 to |
114 | * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI | 119 | * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI |
@@ -124,9 +129,6 @@ void __init board_setup(void) | |||
124 | #ifdef CONFIG_MIPS_DB1200 | 129 | #ifdef CONFIG_MIPS_DB1200 |
125 | printk(KERN_INFO "AMD Alchemy Db1200 Board\n"); | 130 | printk(KERN_INFO "AMD Alchemy Db1200 Board\n"); |
126 | #endif | 131 | #endif |
127 | |||
128 | /* Setup Pb1200 External Interrupt Controller */ | ||
129 | board_init_irq = _board_init_irq; | ||
130 | } | 132 | } |
131 | 133 | ||
132 | int board_au1200fb_panel(void) | 134 | int board_au1200fb_panel(void) |
diff --git a/arch/mips/alchemy/pb1200/irqmap.c b/arch/mips/alchemy/devboards/pb1200/irqmap.c index 2a505ad8715b..fe47498da280 100644 --- a/arch/mips/alchemy/pb1200/irqmap.c +++ b/arch/mips/alchemy/devboards/pb1200/irqmap.c | |||
@@ -40,91 +40,65 @@ | |||
40 | 40 | ||
41 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | 41 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
42 | /* This is external interrupt cascade */ | 42 | /* This is external interrupt cascade */ |
43 | { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 }, | 43 | { AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 }, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | ||
47 | 46 | ||
48 | /* | 47 | /* |
49 | * Support for External interrupts on the Pb1200 Development platform. | 48 | * Support for External interrupts on the Pb1200 Development platform. |
50 | */ | 49 | */ |
51 | static volatile int pb1200_cascade_en; | ||
52 | 50 | ||
53 | irqreturn_t pb1200_cascade_handler(int irq, void *dev_id) | 51 | static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d) |
54 | { | 52 | { |
55 | unsigned short bisr = bcsr->int_status; | 53 | unsigned short bisr = bcsr->int_status; |
56 | int extirq_nr = 0; | ||
57 | |||
58 | /* Clear all the edge interrupts. This has no effect on level. */ | ||
59 | bcsr->int_status = bisr; | ||
60 | for ( ; bisr; bisr &= bisr - 1) { | ||
61 | extirq_nr = PB1200_INT_BEGIN + __ffs(bisr); | ||
62 | /* Ack and dispatch IRQ */ | ||
63 | do_IRQ(extirq_nr); | ||
64 | } | ||
65 | |||
66 | return IRQ_RETVAL(1); | ||
67 | } | ||
68 | 54 | ||
69 | inline void pb1200_enable_irq(unsigned int irq_nr) | 55 | for ( ; bisr; bisr &= bisr - 1) |
70 | { | 56 | generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr)); |
71 | bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN); | ||
72 | bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN); | ||
73 | } | 57 | } |
74 | 58 | ||
75 | inline void pb1200_disable_irq(unsigned int irq_nr) | 59 | /* NOTE: both the enable and mask bits must be cleared, otherwise the |
60 | * CPLD generates tons of spurious interrupts (at least on the DB1200). | ||
61 | */ | ||
62 | static void pb1200_mask_irq(unsigned int irq_nr) | ||
76 | { | 63 | { |
77 | bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN); | 64 | bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN); |
78 | bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN); | 65 | bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN); |
66 | au_sync(); | ||
79 | } | 67 | } |
80 | 68 | ||
81 | static unsigned int pb1200_setup_cascade(void) | 69 | static void pb1200_maskack_irq(unsigned int irq_nr) |
82 | { | ||
83 | return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler, | ||
84 | 0, "Pb1200 Cascade", &pb1200_cascade_handler); | ||
85 | } | ||
86 | |||
87 | static unsigned int pb1200_startup_irq(unsigned int irq) | ||
88 | { | 70 | { |
89 | if (++pb1200_cascade_en == 1) { | 71 | bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN); |
90 | int res; | 72 | bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN); |
91 | 73 | bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN); /* ack */ | |
92 | res = pb1200_setup_cascade(); | 74 | au_sync(); |
93 | if (res) | ||
94 | return res; | ||
95 | } | ||
96 | |||
97 | pb1200_enable_irq(irq); | ||
98 | |||
99 | return 0; | ||
100 | } | 75 | } |
101 | 76 | ||
102 | static void pb1200_shutdown_irq(unsigned int irq) | 77 | static void pb1200_unmask_irq(unsigned int irq_nr) |
103 | { | 78 | { |
104 | pb1200_disable_irq(irq); | 79 | bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN); |
105 | if (--pb1200_cascade_en == 0) | 80 | bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN); |
106 | free_irq(AU1000_GPIO_7, &pb1200_cascade_handler); | 81 | au_sync(); |
107 | } | 82 | } |
108 | 83 | ||
109 | static struct irq_chip external_irq_type = { | 84 | static struct irq_chip pb1200_cpld_irq_type = { |
110 | #ifdef CONFIG_MIPS_PB1200 | 85 | #ifdef CONFIG_MIPS_PB1200 |
111 | .name = "Pb1200 Ext", | 86 | .name = "Pb1200 Ext", |
112 | #endif | 87 | #endif |
113 | #ifdef CONFIG_MIPS_DB1200 | 88 | #ifdef CONFIG_MIPS_DB1200 |
114 | .name = "Db1200 Ext", | 89 | .name = "Db1200 Ext", |
115 | #endif | 90 | #endif |
116 | .startup = pb1200_startup_irq, | 91 | .mask = pb1200_mask_irq, |
117 | .shutdown = pb1200_shutdown_irq, | 92 | .mask_ack = pb1200_maskack_irq, |
118 | .ack = pb1200_disable_irq, | 93 | .unmask = pb1200_unmask_irq, |
119 | .mask = pb1200_disable_irq, | ||
120 | .mask_ack = pb1200_disable_irq, | ||
121 | .unmask = pb1200_enable_irq, | ||
122 | }; | 94 | }; |
123 | 95 | ||
124 | void _board_init_irq(void) | 96 | void __init board_init_irq(void) |
125 | { | 97 | { |
126 | unsigned int irq; | 98 | unsigned int irq; |
127 | 99 | ||
100 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
101 | |||
128 | #ifdef CONFIG_MIPS_PB1200 | 102 | #ifdef CONFIG_MIPS_PB1200 |
129 | /* We have a problem with CPLD rev 3. */ | 103 | /* We have a problem with CPLD rev 3. */ |
130 | if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) { | 104 | if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) { |
@@ -146,15 +120,15 @@ void _board_init_irq(void) | |||
146 | panic("Game over. Your score is 0."); | 120 | panic("Game over. Your score is 0."); |
147 | } | 121 | } |
148 | #endif | 122 | #endif |
123 | /* mask & disable & ack all */ | ||
124 | bcsr->intclr_mask = 0xffff; | ||
125 | bcsr->intclr = 0xffff; | ||
126 | bcsr->int_status = 0xffff; | ||
127 | au_sync(); | ||
149 | 128 | ||
150 | for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++) { | 129 | for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++) |
151 | set_irq_chip_and_handler(irq, &external_irq_type, | 130 | set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type, |
152 | handle_level_irq); | 131 | handle_level_irq, "level"); |
153 | pb1200_disable_irq(irq); | ||
154 | } | ||
155 | 132 | ||
156 | /* | 133 | set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler); |
157 | * GPIO_7 can not be hooked here, so it is hooked upon first | ||
158 | * request of any source attached to the cascade. | ||
159 | */ | ||
160 | } | 134 | } |
diff --git a/arch/mips/alchemy/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c index 95303297c534..95303297c534 100644 --- a/arch/mips/alchemy/pb1200/platform.c +++ b/arch/mips/alchemy/devboards/pb1200/platform.c | |||
diff --git a/arch/mips/alchemy/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile index 602f38df20bb..173b419a7479 100644 --- a/arch/mips/alchemy/pb1500/Makefile +++ b/arch/mips/alchemy/devboards/pb1500/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # Makefile for the Alchemy Semiconductor Pb1500 board. | 5 | # Makefile for the Alchemy Semiconductor Pb1500 board. |
6 | # | 6 | # |
7 | 7 | ||
8 | lib-y := init.o board_setup.o irqmap.o | 8 | obj-y := board_setup.o |
diff --git a/arch/mips/alchemy/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c index 035771c6e5b8..fed3b093156a 100644 --- a/arch/mips/alchemy/pb1500/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c | |||
@@ -25,20 +25,64 @@ | |||
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/interrupt.h> | ||
28 | 29 | ||
29 | #include <asm/mach-au1x00/au1000.h> | 30 | #include <asm/mach-au1x00/au1000.h> |
30 | #include <asm/mach-pb1x00/pb1500.h> | 31 | #include <asm/mach-pb1x00/pb1500.h> |
31 | 32 | ||
33 | #include <prom.h> | ||
34 | |||
35 | |||
36 | char irq_tab_alchemy[][5] __initdata = { | ||
37 | [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */ | ||
38 | [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */ | ||
39 | }; | ||
40 | |||
41 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
42 | { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 }, | ||
43 | { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 }, | ||
44 | { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 }, | ||
45 | { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 }, | ||
46 | { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 }, | ||
47 | }; | ||
48 | |||
49 | |||
50 | const char *get_system_type(void) | ||
51 | { | ||
52 | return "Alchemy Pb1500"; | ||
53 | } | ||
54 | |||
32 | void board_reset(void) | 55 | void board_reset(void) |
33 | { | 56 | { |
34 | /* Hit BCSR.RST_VDDI[SOFT_RESET] */ | 57 | /* Hit BCSR.RST_VDDI[SOFT_RESET] */ |
35 | au_writel(0x00000000, PB1500_RST_VDDI); | 58 | au_writel(0x00000000, PB1500_RST_VDDI); |
36 | } | 59 | } |
37 | 60 | ||
61 | void __init board_init_irq(void) | ||
62 | { | ||
63 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
64 | } | ||
65 | |||
38 | void __init board_setup(void) | 66 | void __init board_setup(void) |
39 | { | 67 | { |
40 | u32 pin_func; | 68 | u32 pin_func; |
41 | u32 sys_freqctrl, sys_clksrc; | 69 | u32 sys_freqctrl, sys_clksrc; |
70 | char *argptr; | ||
71 | |||
72 | argptr = prom_getcmdline(); | ||
73 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
74 | argptr = strstr(argptr, "console="); | ||
75 | if (argptr == NULL) { | ||
76 | argptr = prom_getcmdline(); | ||
77 | strcat(argptr, " console=ttyS0,115200"); | ||
78 | } | ||
79 | #endif | ||
80 | |||
81 | #if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000) | ||
82 | /* au1000 does not support vra, au1500 and au1100 do */ | ||
83 | strcat(argptr, " au1000_audio=vra"); | ||
84 | argptr = prom_getcmdline(); | ||
85 | #endif | ||
42 | 86 | ||
43 | sys_clksrc = sys_freqctrl = pin_func = 0; | 87 | sys_clksrc = sys_freqctrl = pin_func = 0; |
44 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ | 88 | /* Set AUX clock to 12 MHz * 8 = 96 MHz */ |
diff --git a/arch/mips/alchemy/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile index 7d8beca87fa5..cff95bcdb2ca 100644 --- a/arch/mips/alchemy/pb1550/Makefile +++ b/arch/mips/alchemy/devboards/pb1550/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # Makefile for the Alchemy Semiconductor Pb1550 board. | 5 | # Makefile for the Alchemy Semiconductor Pb1550 board. |
6 | # | 6 | # |
7 | 7 | ||
8 | lib-y := init.o board_setup.o irqmap.o | 8 | obj-y := board_setup.o |
diff --git a/arch/mips/alchemy/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c index 0ed76b64b6ab..b6e9e7d247a3 100644 --- a/arch/mips/alchemy/pb1550/board_setup.c +++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c | |||
@@ -28,20 +28,54 @@ | |||
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/interrupt.h> | ||
31 | 32 | ||
32 | #include <asm/mach-au1x00/au1000.h> | 33 | #include <asm/mach-au1x00/au1000.h> |
33 | #include <asm/mach-pb1x00/pb1550.h> | 34 | #include <asm/mach-pb1x00/pb1550.h> |
34 | 35 | ||
36 | #include <prom.h> | ||
37 | |||
38 | |||
39 | char irq_tab_alchemy[][5] __initdata = { | ||
40 | [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */ | ||
41 | [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */ | ||
42 | }; | ||
43 | |||
44 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
45 | { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, | ||
46 | { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, | ||
47 | }; | ||
48 | |||
49 | const char *get_system_type(void) | ||
50 | { | ||
51 | return "Alchemy Pb1550"; | ||
52 | } | ||
53 | |||
35 | void board_reset(void) | 54 | void board_reset(void) |
36 | { | 55 | { |
37 | /* Hit BCSR.SYSTEM[RESET] */ | 56 | /* Hit BCSR.SYSTEM[RESET] */ |
38 | au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C); | 57 | au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C); |
39 | } | 58 | } |
40 | 59 | ||
60 | void __init board_init_irq(void) | ||
61 | { | ||
62 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
63 | } | ||
64 | |||
41 | void __init board_setup(void) | 65 | void __init board_setup(void) |
42 | { | 66 | { |
43 | u32 pin_func; | 67 | u32 pin_func; |
44 | 68 | ||
69 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
70 | char *argptr; | ||
71 | argptr = prom_getcmdline(); | ||
72 | argptr = strstr(argptr, "console="); | ||
73 | if (argptr == NULL) { | ||
74 | argptr = prom_getcmdline(); | ||
75 | strcat(argptr, " console=ttyS0,115200"); | ||
76 | } | ||
77 | #endif | ||
78 | |||
45 | /* | 79 | /* |
46 | * Enable PSC1 SYNC for AC'97. Normaly done in audio driver, | 80 | * Enable PSC1 SYNC for AC'97. Normaly done in audio driver, |
47 | * but it is board specific code, so put it here. | 81 | * but it is board specific code, so put it here. |
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c new file mode 100644 index 000000000000..d5eb9c325ed0 --- /dev/null +++ b/arch/mips/alchemy/devboards/pm.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * Alchemy Development Board example suspend userspace interface. | ||
3 | * | ||
4 | * (c) 2008 Manuel Lauss <mano@roarinelk.homelinux.net> | ||
5 | */ | ||
6 | |||
7 | #include <linux/init.h> | ||
8 | #include <linux/kobject.h> | ||
9 | #include <linux/suspend.h> | ||
10 | #include <linux/sysfs.h> | ||
11 | #include <asm/mach-au1x00/au1000.h> | ||
12 | |||
13 | /* | ||
14 | * Generic suspend userspace interface for Alchemy development boards. | ||
15 | * This code exports a few sysfs nodes under /sys/power/db1x/ which | ||
16 | * can be used by userspace to en/disable all au1x-provided wakeup | ||
17 | * sources and configure the timeout after which the the TOYMATCH2 irq | ||
18 | * is to trigger a wakeup. | ||
19 | */ | ||
20 | |||
21 | |||
22 | static unsigned long db1x_pm_sleep_secs; | ||
23 | static unsigned long db1x_pm_wakemsk; | ||
24 | static unsigned long db1x_pm_last_wakesrc; | ||
25 | |||
26 | static int db1x_pm_enter(suspend_state_t state) | ||
27 | { | ||
28 | /* enable GPIO based wakeup */ | ||
29 | au_writel(1, SYS_PININPUTEN); | ||
30 | |||
31 | /* clear and setup wake cause and source */ | ||
32 | au_writel(0, SYS_WAKEMSK); | ||
33 | au_sync(); | ||
34 | au_writel(0, SYS_WAKESRC); | ||
35 | au_sync(); | ||
36 | |||
37 | au_writel(db1x_pm_wakemsk, SYS_WAKEMSK); | ||
38 | au_sync(); | ||
39 | |||
40 | /* setup 1Hz-timer-based wakeup: wait for reg access */ | ||
41 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) | ||
42 | asm volatile ("nop"); | ||
43 | |||
44 | au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2); | ||
45 | au_sync(); | ||
46 | |||
47 | /* wait for value to really hit the register */ | ||
48 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) | ||
49 | asm volatile ("nop"); | ||
50 | |||
51 | /* ...and now the sandman can come! */ | ||
52 | au_sleep(); | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static int db1x_pm_begin(suspend_state_t state) | ||
58 | { | ||
59 | if (!db1x_pm_wakemsk) { | ||
60 | printk(KERN_ERR "db1x: no wakeup source activated!\n"); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static void db1x_pm_end(void) | ||
68 | { | ||
69 | /* read and store wakeup source, the clear the register. To | ||
70 | * be able to clear it, WAKEMSK must be cleared first. | ||
71 | */ | ||
72 | db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC); | ||
73 | |||
74 | au_writel(0, SYS_WAKEMSK); | ||
75 | au_writel(0, SYS_WAKESRC); | ||
76 | au_sync(); | ||
77 | |||
78 | } | ||
79 | |||
80 | static struct platform_suspend_ops db1x_pm_ops = { | ||
81 | .valid = suspend_valid_only_mem, | ||
82 | .begin = db1x_pm_begin, | ||
83 | .enter = db1x_pm_enter, | ||
84 | .end = db1x_pm_end, | ||
85 | }; | ||
86 | |||
87 | #define ATTRCMP(x) (0 == strcmp(attr->attr.name, #x)) | ||
88 | |||
89 | static ssize_t db1x_pmattr_show(struct kobject *kobj, | ||
90 | struct kobj_attribute *attr, | ||
91 | char *buf) | ||
92 | { | ||
93 | int idx; | ||
94 | |||
95 | if (ATTRCMP(timer_timeout)) | ||
96 | return sprintf(buf, "%lu\n", db1x_pm_sleep_secs); | ||
97 | |||
98 | else if (ATTRCMP(timer)) | ||
99 | return sprintf(buf, "%u\n", | ||
100 | !!(db1x_pm_wakemsk & SYS_WAKEMSK_M2)); | ||
101 | |||
102 | else if (ATTRCMP(wakesrc)) | ||
103 | return sprintf(buf, "%lu\n", db1x_pm_last_wakesrc); | ||
104 | |||
105 | else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) || | ||
106 | ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) || | ||
107 | ATTRCMP(gpio6) || ATTRCMP(gpio7)) { | ||
108 | idx = (attr->attr.name)[4] - '0'; | ||
109 | return sprintf(buf, "%d\n", | ||
110 | !!(db1x_pm_wakemsk & SYS_WAKEMSK_GPIO(idx))); | ||
111 | |||
112 | } else if (ATTRCMP(wakemsk)) { | ||
113 | return sprintf(buf, "%08lx\n", db1x_pm_wakemsk); | ||
114 | } | ||
115 | |||
116 | return -ENOENT; | ||
117 | } | ||
118 | |||
119 | static ssize_t db1x_pmattr_store(struct kobject *kobj, | ||
120 | struct kobj_attribute *attr, | ||
121 | const char *instr, | ||
122 | size_t bytes) | ||
123 | { | ||
124 | unsigned long l; | ||
125 | int tmp; | ||
126 | |||
127 | if (ATTRCMP(timer_timeout)) { | ||
128 | tmp = strict_strtoul(instr, 0, &l); | ||
129 | if (tmp) | ||
130 | return tmp; | ||
131 | |||
132 | db1x_pm_sleep_secs = l; | ||
133 | |||
134 | } else if (ATTRCMP(timer)) { | ||
135 | if (instr[0] != '0') | ||
136 | db1x_pm_wakemsk |= SYS_WAKEMSK_M2; | ||
137 | else | ||
138 | db1x_pm_wakemsk &= ~SYS_WAKEMSK_M2; | ||
139 | |||
140 | } else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) || | ||
141 | ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) || | ||
142 | ATTRCMP(gpio6) || ATTRCMP(gpio7)) { | ||
143 | tmp = (attr->attr.name)[4] - '0'; | ||
144 | if (instr[0] != '0') { | ||
145 | db1x_pm_wakemsk |= SYS_WAKEMSK_GPIO(tmp); | ||
146 | } else { | ||
147 | db1x_pm_wakemsk &= ~SYS_WAKEMSK_GPIO(tmp); | ||
148 | } | ||
149 | |||
150 | } else if (ATTRCMP(wakemsk)) { | ||
151 | tmp = strict_strtoul(instr, 0, &l); | ||
152 | if (tmp) | ||
153 | return tmp; | ||
154 | |||
155 | db1x_pm_wakemsk = l & 0x0000003f; | ||
156 | |||
157 | } else | ||
158 | bytes = -ENOENT; | ||
159 | |||
160 | return bytes; | ||
161 | } | ||
162 | |||
163 | #define ATTR(x) \ | ||
164 | static struct kobj_attribute x##_attribute = \ | ||
165 | __ATTR(x, 0664, db1x_pmattr_show, \ | ||
166 | db1x_pmattr_store); | ||
167 | |||
168 | ATTR(gpio0) /* GPIO-based wakeup enable */ | ||
169 | ATTR(gpio1) | ||
170 | ATTR(gpio2) | ||
171 | ATTR(gpio3) | ||
172 | ATTR(gpio4) | ||
173 | ATTR(gpio5) | ||
174 | ATTR(gpio6) | ||
175 | ATTR(gpio7) | ||
176 | ATTR(timer) /* TOYMATCH2-based wakeup enable */ | ||
177 | ATTR(timer_timeout) /* timer-based wakeup timeout value, in seconds */ | ||
178 | ATTR(wakesrc) /* contents of SYS_WAKESRC after last wakeup */ | ||
179 | ATTR(wakemsk) /* direct access to SYS_WAKEMSK */ | ||
180 | |||
181 | #define ATTR_LIST(x) & x ## _attribute.attr | ||
182 | static struct attribute *db1x_pmattrs[] = { | ||
183 | ATTR_LIST(gpio0), | ||
184 | ATTR_LIST(gpio1), | ||
185 | ATTR_LIST(gpio2), | ||
186 | ATTR_LIST(gpio3), | ||
187 | ATTR_LIST(gpio4), | ||
188 | ATTR_LIST(gpio5), | ||
189 | ATTR_LIST(gpio6), | ||
190 | ATTR_LIST(gpio7), | ||
191 | ATTR_LIST(timer), | ||
192 | ATTR_LIST(timer_timeout), | ||
193 | ATTR_LIST(wakesrc), | ||
194 | ATTR_LIST(wakemsk), | ||
195 | NULL, /* terminator */ | ||
196 | }; | ||
197 | |||
198 | static struct attribute_group db1x_pmattr_group = { | ||
199 | .name = "db1x", | ||
200 | .attrs = db1x_pmattrs, | ||
201 | }; | ||
202 | |||
203 | /* | ||
204 | * Initialize suspend interface | ||
205 | */ | ||
206 | static int __init pm_init(void) | ||
207 | { | ||
208 | /* init TOY to tick at 1Hz if not already done. No need to wait | ||
209 | * for confirmation since there's plenty of time from here to | ||
210 | * the next suspend cycle. | ||
211 | */ | ||
212 | if (au_readl(SYS_TOYTRIM) != 32767) { | ||
213 | au_writel(32767, SYS_TOYTRIM); | ||
214 | au_sync(); | ||
215 | } | ||
216 | |||
217 | db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC); | ||
218 | |||
219 | au_writel(0, SYS_WAKESRC); | ||
220 | au_sync(); | ||
221 | au_writel(0, SYS_WAKEMSK); | ||
222 | au_sync(); | ||
223 | |||
224 | suspend_set_ops(&db1x_pm_ops); | ||
225 | |||
226 | return sysfs_create_group(power_kobj, &db1x_pmattr_group); | ||
227 | } | ||
228 | |||
229 | late_initcall(pm_init); | ||
diff --git a/arch/mips/alchemy/pb1550/init.c b/arch/mips/alchemy/devboards/prom.c index e1055a13a1a0..0042bd6b1d7d 100644 --- a/arch/mips/alchemy/pb1550/init.c +++ b/arch/mips/alchemy/devboards/prom.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Common code used by all Alchemy develboards. | ||
2 | * | 3 | * |
3 | * BRIEF MODULE DESCRIPTION | 4 | * Extracted from files which had this to say: |
4 | * Pb1550 board setup | ||
5 | * | 5 | * |
6 | * Copyright 2001, 2008 MontaVista Software Inc. | 6 | * Copyright 2000, 2008 MontaVista Software Inc. |
7 | * Author: MontaVista Software, Inc. <source@mvista.com> | 7 | * Author: MontaVista Software, Inc. <source@mvista.com> |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
@@ -29,15 +29,19 @@ | |||
29 | 29 | ||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | |||
33 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
34 | 33 | #include <asm/mach-au1x00/au1000.h> | |
35 | #include <prom.h> | 34 | #include <prom.h> |
36 | 35 | ||
37 | const char *get_system_type(void) | 36 | #if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || \ |
38 | { | 37 | defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || \ |
39 | return "Alchemy Pb1550"; | 38 | defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) || \ |
40 | } | 39 | defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE) |
40 | #define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000 | ||
41 | |||
42 | #else /* Au1550/Au1200-based develboards */ | ||
43 | #define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000 | ||
44 | #endif | ||
41 | 45 | ||
42 | void __init prom_init(void) | 46 | void __init prom_init(void) |
43 | { | 47 | { |
@@ -51,8 +55,8 @@ void __init prom_init(void) | |||
51 | prom_init_cmdline(); | 55 | prom_init_cmdline(); |
52 | memsize_str = prom_getenv("memsize"); | 56 | memsize_str = prom_getenv("memsize"); |
53 | if (!memsize_str) | 57 | if (!memsize_str) |
54 | memsize = 0x08000000; | 58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; |
55 | else | 59 | else |
56 | strict_strtol(memsize_str, 0, &memsize); | 60 | strict_strtoul(memsize_str, 0, &memsize); |
57 | add_memory_region(0, memsize, BOOT_MEM_RAM); | 61 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
58 | } | 62 | } |
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c index 3f8079186cf2..8ed1ae12bc55 100644 --- a/arch/mips/alchemy/mtx-1/board_setup.c +++ b/arch/mips/alchemy/mtx-1/board_setup.c | |||
@@ -32,6 +32,8 @@ | |||
32 | 32 | ||
33 | #include <asm/mach-au1x00/au1000.h> | 33 | #include <asm/mach-au1x00/au1000.h> |
34 | 34 | ||
35 | #include <prom.h> | ||
36 | |||
35 | extern int (*board_pci_idsel)(unsigned int devsel, int assert); | 37 | extern int (*board_pci_idsel)(unsigned int devsel, int assert); |
36 | int mtx1_pci_idsel(unsigned int devsel, int assert); | 38 | int mtx1_pci_idsel(unsigned int devsel, int assert); |
37 | 39 | ||
@@ -43,6 +45,16 @@ void board_reset(void) | |||
43 | 45 | ||
44 | void __init board_setup(void) | 46 | void __init board_setup(void) |
45 | { | 47 | { |
48 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
49 | char *argptr; | ||
50 | argptr = prom_getcmdline(); | ||
51 | argptr = strstr(argptr, "console="); | ||
52 | if (argptr == NULL) { | ||
53 | argptr = prom_getcmdline(); | ||
54 | strcat(argptr, " console=ttyS0,115200"); | ||
55 | } | ||
56 | #endif | ||
57 | |||
46 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) | 58 | #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) |
47 | /* Enable USB power switch */ | 59 | /* Enable USB power switch */ |
48 | au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR); | 60 | au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR); |
diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c index 3bae13c28954..5e871c8d9e96 100644 --- a/arch/mips/alchemy/mtx-1/init.c +++ b/arch/mips/alchemy/mtx-1/init.c | |||
@@ -55,6 +55,6 @@ void __init prom_init(void) | |||
55 | if (!memsize_str) | 55 | if (!memsize_str) |
56 | memsize = 0x04000000; | 56 | memsize = 0x04000000; |
57 | else | 57 | else |
58 | strict_strtol(memsize_str, 0, &memsize); | 58 | strict_strtoul(memsize_str, 0, &memsize); |
59 | add_memory_region(0, memsize, BOOT_MEM_RAM); | 59 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
60 | } | 60 | } |
diff --git a/arch/mips/alchemy/mtx-1/irqmap.c b/arch/mips/alchemy/mtx-1/irqmap.c index f2bf02951e9c..f1ab12ab3433 100644 --- a/arch/mips/alchemy/mtx-1/irqmap.c +++ b/arch/mips/alchemy/mtx-1/irqmap.c | |||
@@ -27,7 +27,7 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | 30 | #include <linux/interrupt.h> | |
31 | #include <asm/mach-au1x00/au1000.h> | 31 | #include <asm/mach-au1x00/au1000.h> |
32 | 32 | ||
33 | char irq_tab_alchemy[][5] __initdata = { | 33 | char irq_tab_alchemy[][5] __initdata = { |
@@ -42,11 +42,15 @@ char irq_tab_alchemy[][5] __initdata = { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | 44 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
45 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 }, | 45 | { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 }, |
46 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, | 46 | { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 }, |
47 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, | 47 | { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 }, |
48 | { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, | 48 | { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 }, |
49 | { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, | 49 | { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 }, |
50 | }; | 50 | }; |
51 | 51 | ||
52 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | 52 | |
53 | void __init board_init_irq(void) | ||
54 | { | ||
55 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
56 | } | ||
diff --git a/arch/mips/alchemy/pb1000/init.c b/arch/mips/alchemy/pb1000/init.c deleted file mode 100644 index 8a9c7d57208d..000000000000 --- a/arch/mips/alchemy/pb1000/init.c +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Pb1000 board setup | ||
4 | * | ||
5 | * Copyright 2001, 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 it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/kernel.h> | ||
31 | |||
32 | #include <asm/bootinfo.h> | ||
33 | |||
34 | #include <prom.h> | ||
35 | |||
36 | const char *get_system_type(void) | ||
37 | { | ||
38 | return "Alchemy Pb1000"; | ||
39 | } | ||
40 | |||
41 | void __init prom_init(void) | ||
42 | { | ||
43 | unsigned char *memsize_str; | ||
44 | unsigned long memsize; | ||
45 | |||
46 | prom_argc = (int)fw_arg0; | ||
47 | prom_argv = (char **)fw_arg1; | ||
48 | prom_envp = (char **)fw_arg2; | ||
49 | |||
50 | prom_init_cmdline(); | ||
51 | memsize_str = prom_getenv("memsize"); | ||
52 | if (!memsize_str) | ||
53 | memsize = 0x04000000; | ||
54 | else | ||
55 | strict_strtol(memsize_str, 0, &memsize); | ||
56 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
57 | } | ||
diff --git a/arch/mips/alchemy/pb1000/irqmap.c b/arch/mips/alchemy/pb1000/irqmap.c deleted file mode 100644 index b3d56b0af321..000000000000 --- a/arch/mips/alchemy/pb1000/irqmap.c +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Au1xxx irq map table | ||
4 | * | ||
5 | * Copyright 2003 Embedded Edge, LLC | ||
6 | * dan@embeddededge.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | #include <linux/interrupt.h> | ||
31 | |||
32 | #include <asm/mach-au1x00/au1000.h> | ||
33 | |||
34 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
35 | { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 }, | ||
36 | }; | ||
37 | |||
38 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | ||
diff --git a/arch/mips/alchemy/pb1100/init.c b/arch/mips/alchemy/pb1100/init.c deleted file mode 100644 index 7c6792308bc5..000000000000 --- a/arch/mips/alchemy/pb1100/init.c +++ /dev/null | |||
@@ -1,60 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * Pb1100 board setup | ||
5 | * | ||
6 | * Copyright 2002, 2008 MontaVista Software Inc. | ||
7 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <linux/init.h> | ||
31 | #include <linux/kernel.h> | ||
32 | |||
33 | #include <asm/bootinfo.h> | ||
34 | |||
35 | #include <prom.h> | ||
36 | |||
37 | const char *get_system_type(void) | ||
38 | { | ||
39 | return "Alchemy Pb1100"; | ||
40 | } | ||
41 | |||
42 | void __init prom_init(void) | ||
43 | { | ||
44 | unsigned char *memsize_str; | ||
45 | unsigned long memsize; | ||
46 | |||
47 | prom_argc = fw_arg0; | ||
48 | prom_argv = (char **)fw_arg1; | ||
49 | prom_envp = (char **)fw_arg3; | ||
50 | |||
51 | prom_init_cmdline(); | ||
52 | |||
53 | memsize_str = prom_getenv("memsize"); | ||
54 | if (!memsize_str) | ||
55 | memsize = 0x04000000; | ||
56 | else | ||
57 | strict_strtol(memsize_str, 0, &memsize); | ||
58 | |||
59 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
60 | } | ||
diff --git a/arch/mips/alchemy/pb1100/irqmap.c b/arch/mips/alchemy/pb1100/irqmap.c deleted file mode 100644 index 9b7dd8b41283..000000000000 --- a/arch/mips/alchemy/pb1100/irqmap.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Au1xx0 IRQ map table | ||
4 | * | ||
5 | * Copyright 2003 Embedded Edge, LLC | ||
6 | * dan@embeddededge.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | |||
31 | #include <asm/mach-au1x00/au1000.h> | ||
32 | |||
33 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
34 | { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */ | ||
35 | { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */ | ||
36 | { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */ | ||
37 | { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */ | ||
38 | }; | ||
39 | |||
40 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | ||
diff --git a/arch/mips/alchemy/pb1200/init.c b/arch/mips/alchemy/pb1200/init.c deleted file mode 100644 index e9b2a0fd48ae..000000000000 --- a/arch/mips/alchemy/pb1200/init.c +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * PB1200 board setup | ||
5 | * | ||
6 | * Copyright 2001, 2008 MontaVista Software Inc. | ||
7 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <linux/init.h> | ||
31 | #include <linux/kernel.h> | ||
32 | |||
33 | #include <asm/bootinfo.h> | ||
34 | |||
35 | #include <prom.h> | ||
36 | |||
37 | const char *get_system_type(void) | ||
38 | { | ||
39 | return "Alchemy Pb1200"; | ||
40 | } | ||
41 | |||
42 | void __init prom_init(void) | ||
43 | { | ||
44 | unsigned char *memsize_str; | ||
45 | unsigned long memsize; | ||
46 | |||
47 | prom_argc = (int)fw_arg0; | ||
48 | prom_argv = (char **)fw_arg1; | ||
49 | prom_envp = (char **)fw_arg2; | ||
50 | |||
51 | prom_init_cmdline(); | ||
52 | memsize_str = prom_getenv("memsize"); | ||
53 | if (!memsize_str) | ||
54 | memsize = 0x08000000; | ||
55 | else | ||
56 | strict_strtol(memsize_str, 0, &memsize); | ||
57 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
58 | } | ||
diff --git a/arch/mips/alchemy/pb1500/init.c b/arch/mips/alchemy/pb1500/init.c deleted file mode 100644 index 3b6e395cf952..000000000000 --- a/arch/mips/alchemy/pb1500/init.c +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * BRIEF MODULE DESCRIPTION | ||
4 | * Pb1500 board setup | ||
5 | * | ||
6 | * Copyright 2001, 2008 MontaVista Software Inc. | ||
7 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | * | ||
14 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
16 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
17 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
20 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
21 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
24 | * | ||
25 | * You should have received a copy of the GNU General Public License along | ||
26 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
27 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
28 | */ | ||
29 | |||
30 | #include <linux/init.h> | ||
31 | #include <linux/kernel.h> | ||
32 | |||
33 | #include <asm/bootinfo.h> | ||
34 | |||
35 | #include <prom.h> | ||
36 | |||
37 | const char *get_system_type(void) | ||
38 | { | ||
39 | return "Alchemy Pb1500"; | ||
40 | } | ||
41 | |||
42 | void __init prom_init(void) | ||
43 | { | ||
44 | unsigned char *memsize_str; | ||
45 | unsigned long memsize; | ||
46 | |||
47 | prom_argc = (int)fw_arg0; | ||
48 | prom_argv = (char **)fw_arg1; | ||
49 | prom_envp = (char **)fw_arg2; | ||
50 | |||
51 | prom_init_cmdline(); | ||
52 | memsize_str = prom_getenv("memsize"); | ||
53 | if (!memsize_str) | ||
54 | memsize = 0x04000000; | ||
55 | else | ||
56 | strict_strtol(memsize_str, 0, &memsize); | ||
57 | add_memory_region(0, memsize, BOOT_MEM_RAM); | ||
58 | } | ||
diff --git a/arch/mips/alchemy/pb1500/irqmap.c b/arch/mips/alchemy/pb1500/irqmap.c deleted file mode 100644 index 39c4682766a8..000000000000 --- a/arch/mips/alchemy/pb1500/irqmap.c +++ /dev/null | |||
@@ -1,46 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Au1xxx irq map table | ||
4 | * | ||
5 | * Copyright 2003 Embedded Edge, LLC | ||
6 | * dan@embeddededge.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | |||
31 | #include <asm/mach-au1x00/au1000.h> | ||
32 | |||
33 | char irq_tab_alchemy[][5] __initdata = { | ||
34 | [12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */ | ||
35 | [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */ | ||
36 | }; | ||
37 | |||
38 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
39 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 }, | ||
40 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, | ||
41 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, | ||
42 | { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, | ||
43 | { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, | ||
44 | }; | ||
45 | |||
46 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | ||
diff --git a/arch/mips/alchemy/pb1550/irqmap.c b/arch/mips/alchemy/pb1550/irqmap.c deleted file mode 100644 index a02a4d1fa899..000000000000 --- a/arch/mips/alchemy/pb1550/irqmap.c +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Au1xx0 IRQ map table | ||
4 | * | ||
5 | * Copyright 2003 Embedded Edge, LLC | ||
6 | * dan@embeddededge.com | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/init.h> | ||
30 | |||
31 | #include <asm/mach-au1x00/au1000.h> | ||
32 | |||
33 | char irq_tab_alchemy[][5] __initdata = { | ||
34 | [12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */ | ||
35 | [13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */ | ||
36 | }; | ||
37 | |||
38 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | ||
39 | { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, | ||
40 | { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, | ||
41 | }; | ||
42 | |||
43 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | ||
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c index 4c587acac5c3..a2634fabc50d 100644 --- a/arch/mips/alchemy/xxs1500/board_setup.c +++ b/arch/mips/alchemy/xxs1500/board_setup.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #include <asm/mach-au1x00/au1000.h> | 29 | #include <asm/mach-au1x00/au1000.h> |
30 | 30 | ||
31 | #include <prom.h> | ||
32 | |||
31 | void board_reset(void) | 33 | void board_reset(void) |
32 | { | 34 | { |
33 | /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ | 35 | /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ |
@@ -38,6 +40,16 @@ void __init board_setup(void) | |||
38 | { | 40 | { |
39 | u32 pin_func; | 41 | u32 pin_func; |
40 | 42 | ||
43 | #ifdef CONFIG_SERIAL_8250_CONSOLE | ||
44 | char *argptr; | ||
45 | argptr = prom_getcmdline(); | ||
46 | argptr = strstr(argptr, "console="); | ||
47 | if (argptr == NULL) { | ||
48 | argptr = prom_getcmdline(); | ||
49 | strcat(argptr, " console=ttyS0,115200"); | ||
50 | } | ||
51 | #endif | ||
52 | |||
41 | /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ | 53 | /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ |
42 | pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; | 54 | pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; |
43 | pin_func |= SYS_PF_UR3; | 55 | pin_func |= SYS_PF_UR3; |
diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c index 7516434760a1..456fa142c093 100644 --- a/arch/mips/alchemy/xxs1500/init.c +++ b/arch/mips/alchemy/xxs1500/init.c | |||
@@ -53,6 +53,6 @@ void __init prom_init(void) | |||
53 | if (!memsize_str) | 53 | if (!memsize_str) |
54 | memsize = 0x04000000; | 54 | memsize = 0x04000000; |
55 | else | 55 | else |
56 | strict_strtol(memsize_str, 0, &memsize); | 56 | strict_strtoul(memsize_str, 0, &memsize); |
57 | add_memory_region(0, memsize, BOOT_MEM_RAM); | 57 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
58 | } | 58 | } |
diff --git a/arch/mips/alchemy/xxs1500/irqmap.c b/arch/mips/alchemy/xxs1500/irqmap.c index edf06ed11870..0f0f3012e5fd 100644 --- a/arch/mips/alchemy/xxs1500/irqmap.c +++ b/arch/mips/alchemy/xxs1500/irqmap.c | |||
@@ -27,23 +27,26 @@ | |||
27 | */ | 27 | */ |
28 | 28 | ||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | 30 | #include <linux/interrupt.h> | |
31 | #include <asm/mach-au1x00/au1000.h> | 31 | #include <asm/mach-au1x00/au1000.h> |
32 | 32 | ||
33 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { | 33 | struct au1xxx_irqmap __initdata au1xxx_irq_map[] = { |
34 | { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 }, | 34 | { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 }, |
35 | { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 }, | 35 | { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 }, |
36 | { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, | 36 | { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 }, |
37 | { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, | 37 | { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 }, |
38 | { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, | 38 | { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 }, |
39 | { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 }, | 39 | { AU1500_GPIO_207, IRQF_TRIGGER_LOW, 0 }, |
40 | 40 | ||
41 | { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, | 41 | { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, |
42 | { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, | 42 | { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, |
43 | { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, | 43 | { AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, |
44 | { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, | 44 | { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, |
45 | { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */ | 45 | { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* CF interrupt */ |
46 | { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, | 46 | { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map); | 49 | void __init board_init_irq(void) |
50 | { | ||
51 | au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map)); | ||
52 | } | ||