diff options
author | Tejun Heo <tj@kernel.org> | 2009-07-03 18:13:18 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-07-03 18:13:18 -0400 |
commit | c43768cbb7655ea5ff782ae250f6e2ef4297cf98 (patch) | |
tree | 3982e41dde3eecaa3739a5d1a8ed18d04bd74f01 /arch/xtensa | |
parent | 1a8dd307cc0a2119be4e578c517795464e6dabba (diff) | |
parent | 746a99a5af60ee676afa2ba469ccd1373493c7e7 (diff) |
Merge branch 'master' into for-next
Pull linus#master to merge PER_CPU_DEF_ATTRIBUTES and alpha build fix
changes. As alpha in percpu tree uses 'weak' attribute instead of
inline assembly, there's no need for __used attribute.
Conflicts:
arch/alpha/include/asm/percpu.h
arch/mn10300/kernel/vmlinux.lds.S
include/linux/percpu-defs.h
Diffstat (limited to 'arch/xtensa')
-rw-r--r-- | arch/xtensa/configs/s6105_defconfig | 105 | ||||
-rw-r--r-- | arch/xtensa/include/asm/cacheflush.h | 95 | ||||
-rw-r--r-- | arch/xtensa/include/asm/gpio.h | 8 | ||||
-rw-r--r-- | arch/xtensa/include/asm/irq.h | 12 | ||||
-rw-r--r-- | arch/xtensa/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/xtensa/platforms/s6105/device.c | 94 | ||||
-rw-r--r-- | arch/xtensa/platforms/s6105/setup.c | 11 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/Makefile | 2 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/dmac.c | 173 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/gpio.c | 163 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/include/variant/dmac.h | 387 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/include/variant/gpio.h | 2 | ||||
-rw-r--r-- | arch/xtensa/variants/s6000/include/variant/irq.h | 6 |
13 files changed, 1044 insertions, 16 deletions
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig index 768bee006037..bb84fbc9921f 100644 --- a/arch/xtensa/configs/s6105_defconfig +++ b/arch/xtensa/configs/s6105_defconfig | |||
@@ -263,7 +263,54 @@ CONFIG_HAVE_IDE=y | |||
263 | # CONFIG_SCSI_NETLINK is not set | 263 | # CONFIG_SCSI_NETLINK is not set |
264 | # CONFIG_ATA is not set | 264 | # CONFIG_ATA is not set |
265 | # CONFIG_MD is not set | 265 | # CONFIG_MD is not set |
266 | # CONFIG_NETDEVICES is not set | 266 | CONFIG_NETDEVICES=y |
267 | # CONFIG_DUMMY is not set | ||
268 | # CONFIG_BONDING is not set | ||
269 | # CONFIG_MACVLAN is not set | ||
270 | # CONFIG_EQUALIZER is not set | ||
271 | # CONFIG_TUN is not set | ||
272 | # CONFIG_VETH is not set | ||
273 | CONFIG_PHYLIB=y | ||
274 | |||
275 | # | ||
276 | # MII PHY device drivers | ||
277 | # | ||
278 | # CONFIG_MARVELL_PHY is not set | ||
279 | # CONFIG_DAVICOM_PHY is not set | ||
280 | # CONFIG_QSEMI_PHY is not set | ||
281 | # CONFIG_LXT_PHY is not set | ||
282 | # CONFIG_CICADA_PHY is not set | ||
283 | # CONFIG_VITESSE_PHY is not set | ||
284 | CONFIG_SMSC_PHY=y | ||
285 | # CONFIG_BROADCOM_PHY is not set | ||
286 | # CONFIG_ICPLUS_PHY is not set | ||
287 | # CONFIG_REALTEK_PHY is not set | ||
288 | # CONFIG_NATIONAL_PHY is not set | ||
289 | # CONFIG_STE10XP is not set | ||
290 | # CONFIG_LSI_ET1011C_PHY is not set | ||
291 | # CONFIG_FIXED_PHY is not set | ||
292 | # CONFIG_MDIO_BITBANG is not set | ||
293 | # CONFIG_NET_ETHERNET is not set | ||
294 | CONFIG_NETDEV_1000=y | ||
295 | CONFIG_S6GMAC=y | ||
296 | # CONFIG_NETDEV_10000 is not set | ||
297 | |||
298 | # | ||
299 | # Wireless LAN | ||
300 | # | ||
301 | # CONFIG_WLAN_PRE80211 is not set | ||
302 | # CONFIG_WLAN_80211 is not set | ||
303 | # CONFIG_IWLWIFI_LEDS is not set | ||
304 | |||
305 | # | ||
306 | # Enable WiMAX (Networking options) to see the WiMAX drivers | ||
307 | # | ||
308 | # CONFIG_WAN is not set | ||
309 | # CONFIG_PPP is not set | ||
310 | # CONFIG_SLIP is not set | ||
311 | # CONFIG_NETCONSOLE is not set | ||
312 | # CONFIG_NETPOLL is not set | ||
313 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
267 | # CONFIG_ISDN is not set | 314 | # CONFIG_ISDN is not set |
268 | # CONFIG_PHONE is not set | 315 | # CONFIG_PHONE is not set |
269 | 316 | ||
@@ -304,8 +351,6 @@ CONFIG_UNIX98_PTYS=y | |||
304 | # CONFIG_LEGACY_PTYS is not set | 351 | # CONFIG_LEGACY_PTYS is not set |
305 | # CONFIG_IPMI_HANDLER is not set | 352 | # CONFIG_IPMI_HANDLER is not set |
306 | # CONFIG_HW_RANDOM is not set | 353 | # CONFIG_HW_RANDOM is not set |
307 | # CONFIG_RTC is not set | ||
308 | # CONFIG_GEN_RTC is not set | ||
309 | # CONFIG_R3964 is not set | 354 | # CONFIG_R3964 is not set |
310 | # CONFIG_RAW_DRIVER is not set | 355 | # CONFIG_RAW_DRIVER is not set |
311 | # CONFIG_TCG_TPM is not set | 356 | # CONFIG_TCG_TPM is not set |
@@ -387,7 +432,59 @@ CONFIG_SSB_POSSIBLE=y | |||
387 | # CONFIG_MEMSTICK is not set | 432 | # CONFIG_MEMSTICK is not set |
388 | # CONFIG_NEW_LEDS is not set | 433 | # CONFIG_NEW_LEDS is not set |
389 | # CONFIG_ACCESSIBILITY is not set | 434 | # CONFIG_ACCESSIBILITY is not set |
390 | # CONFIG_RTC_CLASS is not set | 435 | CONFIG_RTC_LIB=y |
436 | CONFIG_RTC_CLASS=y | ||
437 | CONFIG_RTC_HCTOSYS=y | ||
438 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
439 | # CONFIG_RTC_DEBUG is not set | ||
440 | |||
441 | # | ||
442 | # RTC interfaces | ||
443 | # | ||
444 | # CONFIG_RTC_INTF_SYSFS is not set | ||
445 | # CONFIG_RTC_INTF_PROC is not set | ||
446 | # CONFIG_RTC_INTF_DEV is not set | ||
447 | # CONFIG_RTC_DRV_TEST is not set | ||
448 | |||
449 | # | ||
450 | # I2C RTC drivers | ||
451 | # | ||
452 | # CONFIG_RTC_DRV_DS1307 is not set | ||
453 | # CONFIG_RTC_DRV_DS1374 is not set | ||
454 | # CONFIG_RTC_DRV_DS1672 is not set | ||
455 | # CONFIG_RTC_DRV_MAX6900 is not set | ||
456 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
457 | # CONFIG_RTC_DRV_ISL1208 is not set | ||
458 | # CONFIG_RTC_DRV_X1205 is not set | ||
459 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
460 | # CONFIG_RTC_DRV_PCF8583 is not set | ||
461 | CONFIG_RTC_DRV_M41T80=y | ||
462 | # CONFIG_RTC_DRV_M41T80_WDT is not set | ||
463 | # CONFIG_RTC_DRV_S35390A is not set | ||
464 | # CONFIG_RTC_DRV_FM3130 is not set | ||
465 | # CONFIG_RTC_DRV_RX8581 is not set | ||
466 | |||
467 | # | ||
468 | # SPI RTC drivers | ||
469 | # | ||
470 | |||
471 | # | ||
472 | # Platform RTC drivers | ||
473 | # | ||
474 | # CONFIG_RTC_DRV_DS1286 is not set | ||
475 | # CONFIG_RTC_DRV_DS1511 is not set | ||
476 | # CONFIG_RTC_DRV_DS1553 is not set | ||
477 | # CONFIG_RTC_DRV_DS1742 is not set | ||
478 | # CONFIG_RTC_DRV_STK17TA8 is not set | ||
479 | # CONFIG_RTC_DRV_M48T86 is not set | ||
480 | # CONFIG_RTC_DRV_M48T35 is not set | ||
481 | # CONFIG_RTC_DRV_M48T59 is not set | ||
482 | # CONFIG_RTC_DRV_BQ4802 is not set | ||
483 | # CONFIG_RTC_DRV_V3020 is not set | ||
484 | |||
485 | # | ||
486 | # on-CPU RTC drivers | ||
487 | # | ||
391 | # CONFIG_DMADEVICES is not set | 488 | # CONFIG_DMADEVICES is not set |
392 | # CONFIG_UIO is not set | 489 | # CONFIG_UIO is not set |
393 | # CONFIG_STAGING is not set | 490 | # CONFIG_STAGING is not set |
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 8fc1c0c8de07..b7b8fbe47c77 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h | |||
@@ -155,5 +155,100 @@ extern void copy_from_user_page(struct vm_area_struct*, struct page*, | |||
155 | 155 | ||
156 | #endif | 156 | #endif |
157 | 157 | ||
158 | #define XTENSA_CACHEBLK_LOG2 29 | ||
159 | #define XTENSA_CACHEBLK_SIZE (1 << XTENSA_CACHEBLK_LOG2) | ||
160 | #define XTENSA_CACHEBLK_MASK (7 << XTENSA_CACHEBLK_LOG2) | ||
161 | |||
162 | #if XCHAL_HAVE_CACHEATTR | ||
163 | static inline u32 xtensa_get_cacheattr(void) | ||
164 | { | ||
165 | u32 r; | ||
166 | asm volatile(" rsr %0, CACHEATTR" : "=a"(r)); | ||
167 | return r; | ||
168 | } | ||
169 | |||
170 | static inline u32 xtensa_get_dtlb1(u32 addr) | ||
171 | { | ||
172 | u32 r = addr & XTENSA_CACHEBLK_MASK; | ||
173 | return r | ((xtensa_get_cacheattr() >> (r >> (XTENSA_CACHEBLK_LOG2-2))) | ||
174 | & 0xF); | ||
175 | } | ||
176 | #else | ||
177 | static inline u32 xtensa_get_dtlb1(u32 addr) | ||
178 | { | ||
179 | u32 r; | ||
180 | asm volatile(" rdtlb1 %0, %1" : "=a"(r) : "a"(addr)); | ||
181 | asm volatile(" dsync"); | ||
182 | return r; | ||
183 | } | ||
184 | |||
185 | static inline u32 xtensa_get_cacheattr(void) | ||
186 | { | ||
187 | u32 r = 0; | ||
188 | u32 a = 0; | ||
189 | do { | ||
190 | a -= XTENSA_CACHEBLK_SIZE; | ||
191 | r = (r << 4) | (xtensa_get_dtlb1(a) & 0xF); | ||
192 | } while (a); | ||
193 | return r; | ||
194 | } | ||
195 | #endif | ||
196 | |||
197 | static inline int xtensa_need_flush_dma_source(u32 addr) | ||
198 | { | ||
199 | return (xtensa_get_dtlb1(addr) & ((1 << XCHAL_CA_BITS) - 1)) >= 4; | ||
200 | } | ||
201 | |||
202 | static inline int xtensa_need_invalidate_dma_destination(u32 addr) | ||
203 | { | ||
204 | return (xtensa_get_dtlb1(addr) & ((1 << XCHAL_CA_BITS) - 1)) != 2; | ||
205 | } | ||
206 | |||
207 | static inline void flush_dcache_unaligned(u32 addr, u32 size) | ||
208 | { | ||
209 | u32 cnt; | ||
210 | if (size) { | ||
211 | cnt = (size + ((XCHAL_DCACHE_LINESIZE - 1) & addr) | ||
212 | + XCHAL_DCACHE_LINESIZE - 1) / XCHAL_DCACHE_LINESIZE; | ||
213 | while (cnt--) { | ||
214 | asm volatile(" dhwb %0, 0" : : "a"(addr)); | ||
215 | addr += XCHAL_DCACHE_LINESIZE; | ||
216 | } | ||
217 | asm volatile(" dsync"); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | static inline void invalidate_dcache_unaligned(u32 addr, u32 size) | ||
222 | { | ||
223 | int cnt; | ||
224 | if (size) { | ||
225 | asm volatile(" dhwbi %0, 0 ;" : : "a"(addr)); | ||
226 | cnt = (size + ((XCHAL_DCACHE_LINESIZE - 1) & addr) | ||
227 | - XCHAL_DCACHE_LINESIZE - 1) / XCHAL_DCACHE_LINESIZE; | ||
228 | while (cnt-- > 0) { | ||
229 | asm volatile(" dhi %0, %1" : : "a"(addr), | ||
230 | "n"(XCHAL_DCACHE_LINESIZE)); | ||
231 | addr += XCHAL_DCACHE_LINESIZE; | ||
232 | } | ||
233 | asm volatile(" dhwbi %0, %1" : : "a"(addr), | ||
234 | "n"(XCHAL_DCACHE_LINESIZE)); | ||
235 | asm volatile(" dsync"); | ||
236 | } | ||
237 | } | ||
238 | |||
239 | static inline void flush_invalidate_dcache_unaligned(u32 addr, u32 size) | ||
240 | { | ||
241 | u32 cnt; | ||
242 | if (size) { | ||
243 | cnt = (size + ((XCHAL_DCACHE_LINESIZE - 1) & addr) | ||
244 | + XCHAL_DCACHE_LINESIZE - 1) / XCHAL_DCACHE_LINESIZE; | ||
245 | while (cnt--) { | ||
246 | asm volatile(" dhwbi %0, 0" : : "a"(addr)); | ||
247 | addr += XCHAL_DCACHE_LINESIZE; | ||
248 | } | ||
249 | asm volatile(" dsync"); | ||
250 | } | ||
251 | } | ||
252 | |||
158 | #endif /* __KERNEL__ */ | 253 | #endif /* __KERNEL__ */ |
159 | #endif /* _XTENSA_CACHEFLUSH_H */ | 254 | #endif /* _XTENSA_CACHEFLUSH_H */ |
diff --git a/arch/xtensa/include/asm/gpio.h b/arch/xtensa/include/asm/gpio.h index 0763b0763960..a8c9fc46c790 100644 --- a/arch/xtensa/include/asm/gpio.h +++ b/arch/xtensa/include/asm/gpio.h | |||
@@ -38,14 +38,14 @@ static inline int gpio_cansleep(unsigned int gpio) | |||
38 | return __gpio_cansleep(gpio); | 38 | return __gpio_cansleep(gpio); |
39 | } | 39 | } |
40 | 40 | ||
41 | /* | ||
42 | * Not implemented, yet. | ||
43 | */ | ||
44 | static inline int gpio_to_irq(unsigned int gpio) | 41 | static inline int gpio_to_irq(unsigned int gpio) |
45 | { | 42 | { |
46 | return -ENOSYS; | 43 | return __gpio_to_irq(gpio); |
47 | } | 44 | } |
48 | 45 | ||
46 | /* | ||
47 | * Not implemented, yet. | ||
48 | */ | ||
49 | static inline int irq_to_gpio(unsigned int irq) | 49 | static inline int irq_to_gpio(unsigned int irq) |
50 | { | 50 | { |
51 | return -EINVAL; | 51 | return -EINVAL; |
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h index dfac82dc52ad..4c0ccc9c4f4c 100644 --- a/arch/xtensa/include/asm/irq.h +++ b/arch/xtensa/include/asm/irq.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #ifndef _XTENSA_IRQ_H | 11 | #ifndef _XTENSA_IRQ_H |
12 | #define _XTENSA_IRQ_H | 12 | #define _XTENSA_IRQ_H |
13 | 13 | ||
14 | #include <linux/init.h> | ||
14 | #include <platform/hardware.h> | 15 | #include <platform/hardware.h> |
15 | #include <variant/core.h> | 16 | #include <variant/core.h> |
16 | 17 | ||
@@ -21,11 +22,20 @@ static inline void variant_irq_enable(unsigned int irq) { } | |||
21 | static inline void variant_irq_disable(unsigned int irq) { } | 22 | static inline void variant_irq_disable(unsigned int irq) { } |
22 | #endif | 23 | #endif |
23 | 24 | ||
25 | #ifndef VARIANT_NR_IRQS | ||
26 | # define VARIANT_NR_IRQS 0 | ||
27 | #endif | ||
24 | #ifndef PLATFORM_NR_IRQS | 28 | #ifndef PLATFORM_NR_IRQS |
25 | # define PLATFORM_NR_IRQS 0 | 29 | # define PLATFORM_NR_IRQS 0 |
26 | #endif | 30 | #endif |
27 | #define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS | 31 | #define XTENSA_NR_IRQS XCHAL_NUM_INTERRUPTS |
28 | #define NR_IRQS (XTENSA_NR_IRQS + PLATFORM_NR_IRQS) | 32 | #define NR_IRQS (XTENSA_NR_IRQS + VARIANT_NR_IRQS + PLATFORM_NR_IRQS) |
33 | |||
34 | #if VARIANT_NR_IRQS == 0 | ||
35 | static inline void variant_init_irq(void) { } | ||
36 | #else | ||
37 | void variant_init_irq(void) __init; | ||
38 | #endif | ||
29 | 39 | ||
30 | static __inline__ int irq_canonicalize(int irq) | 40 | static __inline__ int irq_canonicalize(int irq) |
31 | { | 41 | { |
diff --git a/arch/xtensa/kernel/irq.c b/arch/xtensa/kernel/irq.c index a36c85edd045..a1badb32fcda 100644 --- a/arch/xtensa/kernel/irq.c +++ b/arch/xtensa/kernel/irq.c | |||
@@ -197,4 +197,6 @@ void __init init_IRQ(void) | |||
197 | } | 197 | } |
198 | 198 | ||
199 | cached_irq_mask = 0; | 199 | cached_irq_mask = 0; |
200 | |||
201 | variant_init_irq(); | ||
200 | } | 202 | } |
diff --git a/arch/xtensa/platforms/s6105/device.c b/arch/xtensa/platforms/s6105/device.c index 78b08be5a92d..65333ffefb07 100644 --- a/arch/xtensa/platforms/s6105/device.c +++ b/arch/xtensa/platforms/s6105/device.c | |||
@@ -5,14 +5,27 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/gpio.h> | ||
8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/irq.h> | ||
11 | #include <linux/phy.h> | ||
9 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
10 | #include <linux/serial.h> | 13 | #include <linux/serial.h> |
11 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
12 | 15 | ||
13 | #include <variant/hardware.h> | 16 | #include <variant/hardware.h> |
17 | #include <variant/dmac.h> | ||
14 | 18 | ||
19 | #include <platform/gpio.h> | ||
20 | |||
21 | #define GPIO3_INTNUM 3 | ||
15 | #define UART_INTNUM 4 | 22 | #define UART_INTNUM 4 |
23 | #define GMAC_INTNUM 5 | ||
24 | |||
25 | static const signed char gpio3_irq_mappings[] = { | ||
26 | S6_INTC_GPIO(3), | ||
27 | -1 | ||
28 | }; | ||
16 | 29 | ||
17 | static const signed char uart_irq_mappings[] = { | 30 | static const signed char uart_irq_mappings[] = { |
18 | S6_INTC_UART(0), | 31 | S6_INTC_UART(0), |
@@ -20,8 +33,18 @@ static const signed char uart_irq_mappings[] = { | |||
20 | -1, | 33 | -1, |
21 | }; | 34 | }; |
22 | 35 | ||
36 | static const signed char gmac_irq_mappings[] = { | ||
37 | S6_INTC_GMAC_STAT, | ||
38 | S6_INTC_GMAC_ERR, | ||
39 | S6_INTC_DMA_HOSTTERMCNT(0), | ||
40 | S6_INTC_DMA_HOSTTERMCNT(1), | ||
41 | -1 | ||
42 | }; | ||
43 | |||
23 | const signed char *platform_irq_mappings[NR_IRQS] = { | 44 | const signed char *platform_irq_mappings[NR_IRQS] = { |
45 | [GPIO3_INTNUM] = gpio3_irq_mappings, | ||
24 | [UART_INTNUM] = uart_irq_mappings, | 46 | [UART_INTNUM] = uart_irq_mappings, |
47 | [GMAC_INTNUM] = gmac_irq_mappings, | ||
25 | }; | 48 | }; |
26 | 49 | ||
27 | static struct plat_serial8250_port serial_platform_data[] = { | 50 | static struct plat_serial8250_port serial_platform_data[] = { |
@@ -46,6 +69,66 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
46 | { }, | 69 | { }, |
47 | }; | 70 | }; |
48 | 71 | ||
72 | static struct resource s6_gmac_resource[] = { | ||
73 | { | ||
74 | .name = "mem", | ||
75 | .start = (resource_size_t)S6_REG_GMAC, | ||
76 | .end = (resource_size_t)S6_REG_GMAC + 0x10000 - 1, | ||
77 | .flags = IORESOURCE_MEM, | ||
78 | }, | ||
79 | { | ||
80 | .name = "dma", | ||
81 | .start = (resource_size_t) | ||
82 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX), | ||
83 | .end = (resource_size_t) | ||
84 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACTX) + 0x100 - 1, | ||
85 | .flags = IORESOURCE_DMA, | ||
86 | }, | ||
87 | { | ||
88 | .name = "dma", | ||
89 | .start = (resource_size_t) | ||
90 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX), | ||
91 | .end = (resource_size_t) | ||
92 | DMA_CHNL(S6_REG_HIFDMA, S6_HIFDMA_GMACRX) + 0x100 - 1, | ||
93 | .flags = IORESOURCE_DMA, | ||
94 | }, | ||
95 | { | ||
96 | .name = "io", | ||
97 | .start = (resource_size_t)S6_MEM_GMAC, | ||
98 | .end = (resource_size_t)S6_MEM_GMAC + 0x2000000 - 1, | ||
99 | .flags = IORESOURCE_IO, | ||
100 | }, | ||
101 | { | ||
102 | .name = "irq", | ||
103 | .start = (resource_size_t)GMAC_INTNUM, | ||
104 | .flags = IORESOURCE_IRQ, | ||
105 | }, | ||
106 | { | ||
107 | .name = "irq", | ||
108 | .start = (resource_size_t)PHY_POLL, | ||
109 | .flags = IORESOURCE_IRQ, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | static int __init prepare_phy_irq(int pin) | ||
114 | { | ||
115 | int irq; | ||
116 | if (gpio_request(pin, "s6gmac_phy") < 0) | ||
117 | goto fail; | ||
118 | if (gpio_direction_input(pin) < 0) | ||
119 | goto free; | ||
120 | irq = gpio_to_irq(pin); | ||
121 | if (irq < 0) | ||
122 | goto free; | ||
123 | if (set_irq_type(irq, IRQ_TYPE_LEVEL_LOW) < 0) | ||
124 | goto free; | ||
125 | return irq; | ||
126 | free: | ||
127 | gpio_free(pin); | ||
128 | fail: | ||
129 | return PHY_POLL; | ||
130 | } | ||
131 | |||
49 | static struct platform_device platform_devices[] = { | 132 | static struct platform_device platform_devices[] = { |
50 | { | 133 | { |
51 | .name = "serial8250", | 134 | .name = "serial8250", |
@@ -54,12 +137,23 @@ static struct platform_device platform_devices[] = { | |||
54 | .platform_data = serial_platform_data, | 137 | .platform_data = serial_platform_data, |
55 | }, | 138 | }, |
56 | }, | 139 | }, |
140 | { | ||
141 | .name = "s6gmac", | ||
142 | .id = 0, | ||
143 | .resource = s6_gmac_resource, | ||
144 | .num_resources = ARRAY_SIZE(s6_gmac_resource), | ||
145 | }, | ||
146 | { | ||
147 | I2C_BOARD_INFO("m41t62", S6I2C_ADDR_M41T62), | ||
148 | }, | ||
57 | }; | 149 | }; |
58 | 150 | ||
59 | static int __init device_init(void) | 151 | static int __init device_init(void) |
60 | { | 152 | { |
61 | int i; | 153 | int i; |
62 | 154 | ||
155 | s6_gmac_resource[5].start = prepare_phy_irq(GPIO_PHY_IRQ); | ||
156 | |||
63 | for (i = 0; i < ARRAY_SIZE(platform_devices); i++) | 157 | for (i = 0; i < ARRAY_SIZE(platform_devices); i++) |
64 | platform_device_register(&platform_devices[i]); | 158 | platform_device_register(&platform_devices[i]); |
65 | return 0; | 159 | return 0; |
diff --git a/arch/xtensa/platforms/s6105/setup.c b/arch/xtensa/platforms/s6105/setup.c index 855ddeadc43d..86ce730f7913 100644 --- a/arch/xtensa/platforms/s6105/setup.c +++ b/arch/xtensa/platforms/s6105/setup.c | |||
@@ -35,12 +35,21 @@ void __init platform_setup(char **cmdline) | |||
35 | { | 35 | { |
36 | unsigned long reg; | 36 | unsigned long reg; |
37 | 37 | ||
38 | reg = readl(S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
39 | reg &= ~(S6_GREG1_PLLSEL_GMAC_MASK << S6_GREG1_PLLSEL_GMAC | | ||
40 | S6_GREG1_PLLSEL_GMII_MASK << S6_GREG1_PLLSEL_GMII); | ||
41 | reg |= S6_GREG1_PLLSEL_GMAC_125MHZ << S6_GREG1_PLLSEL_GMAC | | ||
42 | S6_GREG1_PLLSEL_GMII_125MHZ << S6_GREG1_PLLSEL_GMII; | ||
43 | writel(reg, S6_REG_GREG1 + S6_GREG1_PLLSEL); | ||
44 | |||
38 | reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE); | 45 | reg = readl(S6_REG_GREG1 + S6_GREG1_CLKGATE); |
39 | reg &= ~(1 << S6_GREG1_BLOCK_SB); | 46 | reg &= ~(1 << S6_GREG1_BLOCK_SB); |
47 | reg &= ~(1 << S6_GREG1_BLOCK_GMAC); | ||
40 | writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE); | 48 | writel(reg, S6_REG_GREG1 + S6_GREG1_CLKGATE); |
41 | 49 | ||
42 | reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA); | 50 | reg = readl(S6_REG_GREG1 + S6_GREG1_BLOCKENA); |
43 | reg |= 1 << S6_GREG1_BLOCK_SB; | 51 | reg |= 1 << S6_GREG1_BLOCK_SB; |
52 | reg |= 1 << S6_GREG1_BLOCK_GMAC; | ||
44 | writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA); | 53 | writel(reg, S6_REG_GREG1 + S6_GREG1_BLOCKENA); |
45 | 54 | ||
46 | printk(KERN_NOTICE "S6105 on Stretch S6000 - " | 55 | printk(KERN_NOTICE "S6105 on Stretch S6000 - " |
@@ -49,7 +58,7 @@ void __init platform_setup(char **cmdline) | |||
49 | 58 | ||
50 | void __init platform_init(bp_tag_t *first) | 59 | void __init platform_init(bp_tag_t *first) |
51 | { | 60 | { |
52 | s6_gpio_init(); | 61 | s6_gpio_init(0); |
53 | gpio_request(GPIO_LED1_NGREEN, "led1_green"); | 62 | gpio_request(GPIO_LED1_NGREEN, "led1_green"); |
54 | gpio_request(GPIO_LED1_RED, "led1_red"); | 63 | gpio_request(GPIO_LED1_RED, "led1_red"); |
55 | gpio_direction_output(GPIO_LED1_NGREEN, 1); | 64 | gpio_direction_output(GPIO_LED1_NGREEN, 1); |
diff --git a/arch/xtensa/variants/s6000/Makefile b/arch/xtensa/variants/s6000/Makefile index d83f3805130c..3e7ef0a0c498 100644 --- a/arch/xtensa/variants/s6000/Makefile +++ b/arch/xtensa/variants/s6000/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # s6000 Makefile | 1 | # s6000 Makefile |
2 | 2 | ||
3 | obj-y += irq.o gpio.o | 3 | obj-y += irq.o gpio.o dmac.o |
4 | obj-$(CONFIG_XTENSA_CALIBRATE_CCOUNT) += delay.o | 4 | obj-$(CONFIG_XTENSA_CALIBRATE_CCOUNT) += delay.o |
diff --git a/arch/xtensa/variants/s6000/dmac.c b/arch/xtensa/variants/s6000/dmac.c new file mode 100644 index 000000000000..dc7f7c573518 --- /dev/null +++ b/arch/xtensa/variants/s6000/dmac.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Authors: Oskar Schirmer <os@emlix.com> | ||
3 | * Daniel Gloeckner <dg@emlix.com> | ||
4 | * (c) 2008 emlix GmbH http://www.emlix.com | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/errno.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include <variant/dmac.h> | ||
19 | |||
20 | /* DMA engine lookup */ | ||
21 | |||
22 | struct s6dmac_ctrl s6dmac_ctrl[S6_DMAC_NB]; | ||
23 | |||
24 | |||
25 | /* DMA control, per engine */ | ||
26 | |||
27 | void s6dmac_put_fifo_cache(u32 dmac, int chan, u32 src, u32 dst, u32 size) | ||
28 | { | ||
29 | if (xtensa_need_flush_dma_source(src)) { | ||
30 | u32 base = src; | ||
31 | u32 span = size; | ||
32 | u32 chunk = readl(DMA_CHNL(dmac, chan) + S6_DMA_CMONCHUNK); | ||
33 | if (chunk && (size > chunk)) { | ||
34 | s32 skip = | ||
35 | readl(DMA_CHNL(dmac, chan) + S6_DMA_SRCSKIP); | ||
36 | u32 gaps = (size+chunk-1)/chunk - 1; | ||
37 | if (skip >= 0) { | ||
38 | span += gaps * skip; | ||
39 | } else if (-skip > chunk) { | ||
40 | s32 decr = gaps * (chunk + skip); | ||
41 | base += decr; | ||
42 | span = chunk - decr; | ||
43 | } else { | ||
44 | span = max(span + gaps * skip, | ||
45 | (chunk + skip) * gaps - skip); | ||
46 | } | ||
47 | } | ||
48 | flush_dcache_unaligned(base, span); | ||
49 | } | ||
50 | if (xtensa_need_invalidate_dma_destination(dst)) { | ||
51 | u32 base = dst; | ||
52 | u32 span = size; | ||
53 | u32 chunk = readl(DMA_CHNL(dmac, chan) + S6_DMA_CMONCHUNK); | ||
54 | if (chunk && (size > chunk)) { | ||
55 | s32 skip = | ||
56 | readl(DMA_CHNL(dmac, chan) + S6_DMA_DSTSKIP); | ||
57 | u32 gaps = (size+chunk-1)/chunk - 1; | ||
58 | if (skip >= 0) { | ||
59 | span += gaps * skip; | ||
60 | } else if (-skip > chunk) { | ||
61 | s32 decr = gaps * (chunk + skip); | ||
62 | base += decr; | ||
63 | span = chunk - decr; | ||
64 | } else { | ||
65 | span = max(span + gaps * skip, | ||
66 | (chunk + skip) * gaps - skip); | ||
67 | } | ||
68 | } | ||
69 | invalidate_dcache_unaligned(base, span); | ||
70 | } | ||
71 | s6dmac_put_fifo(dmac, chan, src, dst, size); | ||
72 | } | ||
73 | |||
74 | void s6dmac_disable_error_irqs(u32 dmac, u32 mask) | ||
75 | { | ||
76 | unsigned long flags; | ||
77 | spinlock_t *spinl = &s6dmac_ctrl[_dmac_addr_index(dmac)].lock; | ||
78 | spin_lock_irqsave(spinl, flags); | ||
79 | _s6dmac_disable_error_irqs(dmac, mask); | ||
80 | spin_unlock_irqrestore(spinl, flags); | ||
81 | } | ||
82 | |||
83 | u32 s6dmac_int_sources(u32 dmac, u32 channel) | ||
84 | { | ||
85 | u32 mask, ret, tmp; | ||
86 | mask = 1 << channel; | ||
87 | |||
88 | tmp = readl(dmac + S6_DMA_TERMCNTIRQSTAT); | ||
89 | tmp &= mask; | ||
90 | writel(tmp, dmac + S6_DMA_TERMCNTIRQCLR); | ||
91 | ret = tmp >> channel; | ||
92 | |||
93 | tmp = readl(dmac + S6_DMA_PENDCNTIRQSTAT); | ||
94 | tmp &= mask; | ||
95 | writel(tmp, dmac + S6_DMA_PENDCNTIRQCLR); | ||
96 | ret |= (tmp >> channel) << 1; | ||
97 | |||
98 | tmp = readl(dmac + S6_DMA_LOWWMRKIRQSTAT); | ||
99 | tmp &= mask; | ||
100 | writel(tmp, dmac + S6_DMA_LOWWMRKIRQCLR); | ||
101 | ret |= (tmp >> channel) << 2; | ||
102 | |||
103 | tmp = readl(dmac + S6_DMA_INTRAW0); | ||
104 | tmp &= (mask << S6_DMA_INT0_OVER) | (mask << S6_DMA_INT0_UNDER); | ||
105 | writel(tmp, dmac + S6_DMA_INTCLEAR0); | ||
106 | |||
107 | if (tmp & (mask << S6_DMA_INT0_UNDER)) | ||
108 | ret |= 1 << 3; | ||
109 | if (tmp & (mask << S6_DMA_INT0_OVER)) | ||
110 | ret |= 1 << 4; | ||
111 | |||
112 | tmp = readl(dmac + S6_DMA_MASTERERRINFO); | ||
113 | mask <<= S6_DMA_INT1_CHANNEL; | ||
114 | if (((tmp >> S6_DMA_MASTERERR_CHAN(0)) & S6_DMA_MASTERERR_CHAN_MASK) | ||
115 | == channel) | ||
116 | mask |= 1 << S6_DMA_INT1_MASTER; | ||
117 | if (((tmp >> S6_DMA_MASTERERR_CHAN(1)) & S6_DMA_MASTERERR_CHAN_MASK) | ||
118 | == channel) | ||
119 | mask |= 1 << (S6_DMA_INT1_MASTER + 1); | ||
120 | if (((tmp >> S6_DMA_MASTERERR_CHAN(2)) & S6_DMA_MASTERERR_CHAN_MASK) | ||
121 | == channel) | ||
122 | mask |= 1 << (S6_DMA_INT1_MASTER + 2); | ||
123 | |||
124 | tmp = readl(dmac + S6_DMA_INTRAW1) & mask; | ||
125 | writel(tmp, dmac + S6_DMA_INTCLEAR1); | ||
126 | ret |= ((tmp >> channel) & 1) << 5; | ||
127 | ret |= ((tmp >> S6_DMA_INT1_MASTER) & S6_DMA_INT1_MASTER_MASK) << 6; | ||
128 | |||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | void s6dmac_release_chan(u32 dmac, int chan) | ||
133 | { | ||
134 | if (chan >= 0) | ||
135 | s6dmac_disable_chan(dmac, chan); | ||
136 | } | ||
137 | |||
138 | |||
139 | /* global init */ | ||
140 | |||
141 | static inline void __init dmac_init(u32 dmac, u8 chan_nb) | ||
142 | { | ||
143 | s6dmac_ctrl[S6_DMAC_INDEX(dmac)].dmac = dmac; | ||
144 | spin_lock_init(&s6dmac_ctrl[S6_DMAC_INDEX(dmac)].lock); | ||
145 | s6dmac_ctrl[S6_DMAC_INDEX(dmac)].chan_nb = chan_nb; | ||
146 | writel(S6_DMA_INT1_MASTER_MASK << S6_DMA_INT1_MASTER, | ||
147 | dmac + S6_DMA_INTCLEAR1); | ||
148 | } | ||
149 | |||
150 | static inline void __init dmac_master(u32 dmac, | ||
151 | u32 m0start, u32 m0end, u32 m1start, u32 m1end) | ||
152 | { | ||
153 | writel(m0start, dmac + S6_DMA_MASTER0START); | ||
154 | writel(m0end - 1, dmac + S6_DMA_MASTER0END); | ||
155 | writel(m1start, dmac + S6_DMA_MASTER1START); | ||
156 | writel(m1end - 1, dmac + S6_DMA_MASTER1END); | ||
157 | } | ||
158 | |||
159 | static void __init s6_dmac_init(void) | ||
160 | { | ||
161 | dmac_init(S6_REG_LMSDMA, S6_LMSDMA_NB); | ||
162 | dmac_master(S6_REG_LMSDMA, | ||
163 | S6_MEM_DDR, S6_MEM_PCIE_APER, S6_MEM_EFI, S6_MEM_GMAC); | ||
164 | dmac_init(S6_REG_NIDMA, S6_NIDMA_NB); | ||
165 | dmac_init(S6_REG_DPDMA, S6_DPDMA_NB); | ||
166 | dmac_master(S6_REG_DPDMA, | ||
167 | S6_MEM_DDR, S6_MEM_PCIE_APER, S6_REG_DP, S6_REG_DPDMA); | ||
168 | dmac_init(S6_REG_HIFDMA, S6_HIFDMA_NB); | ||
169 | dmac_master(S6_REG_HIFDMA, | ||
170 | S6_MEM_GMAC, S6_MEM_PCIE_CFG, S6_MEM_PCIE_APER, S6_MEM_AUX); | ||
171 | } | ||
172 | |||
173 | arch_initcall(s6_dmac_init); | ||
diff --git a/arch/xtensa/variants/s6000/gpio.c b/arch/xtensa/variants/s6000/gpio.c index 79317fdcf14c..380a70fff756 100644 --- a/arch/xtensa/variants/s6000/gpio.c +++ b/arch/xtensa/variants/s6000/gpio.c | |||
@@ -4,15 +4,20 @@ | |||
4 | * Copyright (c) 2009 emlix GmbH | 4 | * Copyright (c) 2009 emlix GmbH |
5 | * Authors: Oskar Schirmer <os@emlix.com> | 5 | * Authors: Oskar Schirmer <os@emlix.com> |
6 | * Johannes Weiner <jw@emlix.com> | 6 | * Johannes Weiner <jw@emlix.com> |
7 | * Daniel Gloeckner <dg@emlix.com> | ||
7 | */ | 8 | */ |
9 | #include <linux/bitops.h> | ||
8 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
9 | #include <linux/module.h> | 11 | #include <linux/module.h> |
10 | #include <linux/init.h> | 12 | #include <linux/init.h> |
11 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/irq.h> | ||
12 | #include <linux/gpio.h> | 15 | #include <linux/gpio.h> |
13 | 16 | ||
14 | #include <variant/hardware.h> | 17 | #include <variant/hardware.h> |
15 | 18 | ||
19 | #define IRQ_BASE XTENSA_NR_IRQS | ||
20 | |||
16 | #define S6_GPIO_DATA 0x000 | 21 | #define S6_GPIO_DATA 0x000 |
17 | #define S6_GPIO_IS 0x404 | 22 | #define S6_GPIO_IS 0x404 |
18 | #define S6_GPIO_IBE 0x408 | 23 | #define S6_GPIO_IBE 0x408 |
@@ -52,19 +57,175 @@ static void set(struct gpio_chip *chip, unsigned int off, int val) | |||
52 | writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off)); | 57 | writeb(val ? ~0 : 0, S6_REG_GPIO + S6_GPIO_DATA + S6_GPIO_OFFSET(off)); |
53 | } | 58 | } |
54 | 59 | ||
60 | static int to_irq(struct gpio_chip *chip, unsigned offset) | ||
61 | { | ||
62 | if (offset < 8) | ||
63 | return offset + IRQ_BASE; | ||
64 | return -EINVAL; | ||
65 | } | ||
66 | |||
55 | static struct gpio_chip gpiochip = { | 67 | static struct gpio_chip gpiochip = { |
56 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
57 | .direction_input = direction_input, | 69 | .direction_input = direction_input, |
58 | .get = get, | 70 | .get = get, |
59 | .direction_output = direction_output, | 71 | .direction_output = direction_output, |
60 | .set = set, | 72 | .set = set, |
73 | .to_irq = to_irq, | ||
61 | .base = 0, | 74 | .base = 0, |
62 | .ngpio = 24, | 75 | .ngpio = 24, |
63 | .can_sleep = 0, /* no blocking io needed */ | 76 | .can_sleep = 0, /* no blocking io needed */ |
64 | .exported = 0, /* no exporting to userspace */ | 77 | .exported = 0, /* no exporting to userspace */ |
65 | }; | 78 | }; |
66 | 79 | ||
67 | int s6_gpio_init(void) | 80 | int s6_gpio_init(u32 afsel) |
68 | { | 81 | { |
82 | writeb(afsel, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_AFSEL); | ||
83 | writeb(afsel >> 8, S6_REG_GPIO + S6_GPIO_BANK(1) + S6_GPIO_AFSEL); | ||
84 | writeb(afsel >> 16, S6_REG_GPIO + S6_GPIO_BANK(2) + S6_GPIO_AFSEL); | ||
69 | return gpiochip_add(&gpiochip); | 85 | return gpiochip_add(&gpiochip); |
70 | } | 86 | } |
87 | |||
88 | static void ack(unsigned int irq) | ||
89 | { | ||
90 | writeb(1 << (irq - IRQ_BASE), S6_REG_GPIO + S6_GPIO_IC); | ||
91 | } | ||
92 | |||
93 | static void mask(unsigned int irq) | ||
94 | { | ||
95 | u8 r = readb(S6_REG_GPIO + S6_GPIO_IE); | ||
96 | r &= ~(1 << (irq - IRQ_BASE)); | ||
97 | writeb(r, S6_REG_GPIO + S6_GPIO_IE); | ||
98 | } | ||
99 | |||
100 | static void unmask(unsigned int irq) | ||
101 | { | ||
102 | u8 m = readb(S6_REG_GPIO + S6_GPIO_IE); | ||
103 | m |= 1 << (irq - IRQ_BASE); | ||
104 | writeb(m, S6_REG_GPIO + S6_GPIO_IE); | ||
105 | } | ||
106 | |||
107 | static int set_type(unsigned int irq, unsigned int type) | ||
108 | { | ||
109 | const u8 m = 1 << (irq - IRQ_BASE); | ||
110 | irq_flow_handler_t handler; | ||
111 | struct irq_desc *desc; | ||
112 | u8 reg; | ||
113 | |||
114 | if (type == IRQ_TYPE_PROBE) { | ||
115 | if ((readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_AFSEL) & m) | ||
116 | || (readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IE) & m) | ||
117 | || readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_DIR | ||
118 | + S6_GPIO_MASK(irq - IRQ_BASE))) | ||
119 | return 0; | ||
120 | type = IRQ_TYPE_EDGE_BOTH; | ||
121 | } | ||
122 | |||
123 | reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS); | ||
124 | if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) { | ||
125 | reg |= m; | ||
126 | handler = handle_level_irq; | ||
127 | } else { | ||
128 | reg &= ~m; | ||
129 | handler = handle_edge_irq; | ||
130 | } | ||
131 | writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IS); | ||
132 | desc = irq_to_desc(irq); | ||
133 | desc->handle_irq = handler; | ||
134 | |||
135 | reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV); | ||
136 | if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) | ||
137 | reg |= m; | ||
138 | else | ||
139 | reg &= ~m; | ||
140 | writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IEV); | ||
141 | |||
142 | reg = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IBE); | ||
143 | if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) | ||
144 | reg |= m; | ||
145 | else | ||
146 | reg &= ~m; | ||
147 | writeb(reg, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IBE); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static struct irq_chip gpioirqs = { | ||
152 | .name = "GPIO", | ||
153 | .ack = ack, | ||
154 | .mask = mask, | ||
155 | .unmask = unmask, | ||
156 | .set_type = set_type, | ||
157 | }; | ||
158 | |||
159 | static u8 demux_masks[4]; | ||
160 | |||
161 | static void demux_irqs(unsigned int irq, struct irq_desc *desc) | ||
162 | { | ||
163 | u8 *mask = get_irq_desc_data(desc); | ||
164 | u8 pending; | ||
165 | int cirq; | ||
166 | |||
167 | desc->chip->mask(irq); | ||
168 | desc->chip->ack(irq); | ||
169 | pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; | ||
170 | cirq = IRQ_BASE - 1; | ||
171 | while (pending) { | ||
172 | int n = ffs(pending); | ||
173 | cirq += n; | ||
174 | pending >>= n; | ||
175 | generic_handle_irq(cirq); | ||
176 | } | ||
177 | desc->chip->unmask(irq); | ||
178 | } | ||
179 | |||
180 | extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; | ||
181 | |||
182 | void __init variant_init_irq(void) | ||
183 | { | ||
184 | int irq, n; | ||
185 | writeb(0, S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_IE); | ||
186 | for (irq = n = 0; irq < XTENSA_NR_IRQS; irq++) { | ||
187 | const signed char *mapping = platform_irq_mappings[irq]; | ||
188 | int alone = 1; | ||
189 | u8 mask; | ||
190 | if (!mapping) | ||
191 | continue; | ||
192 | for(mask = 0; *mapping != -1; mapping++) | ||
193 | switch (*mapping) { | ||
194 | case S6_INTC_GPIO(0): | ||
195 | mask |= 1 << 0; | ||
196 | break; | ||
197 | case S6_INTC_GPIO(1): | ||
198 | mask |= 1 << 1; | ||
199 | break; | ||
200 | case S6_INTC_GPIO(2): | ||
201 | mask |= 1 << 2; | ||
202 | break; | ||
203 | case S6_INTC_GPIO(3): | ||
204 | mask |= 0x1f << 3; | ||
205 | break; | ||
206 | default: | ||
207 | alone = 0; | ||
208 | } | ||
209 | if (mask) { | ||
210 | int cirq, i; | ||
211 | if (!alone) { | ||
212 | printk(KERN_ERR "chained irq chips can't share" | ||
213 | " parent irq %i\n", irq); | ||
214 | continue; | ||
215 | } | ||
216 | demux_masks[n] = mask; | ||
217 | cirq = IRQ_BASE - 1; | ||
218 | do { | ||
219 | i = ffs(mask); | ||
220 | cirq += i; | ||
221 | mask >>= i; | ||
222 | set_irq_chip(cirq, &gpioirqs); | ||
223 | set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); | ||
224 | } while (mask); | ||
225 | set_irq_data(irq, demux_masks + n); | ||
226 | set_irq_chained_handler(irq, demux_irqs); | ||
227 | if (++n == ARRAY_SIZE(demux_masks)) | ||
228 | break; | ||
229 | } | ||
230 | } | ||
231 | } | ||
diff --git a/arch/xtensa/variants/s6000/include/variant/dmac.h b/arch/xtensa/variants/s6000/include/variant/dmac.h new file mode 100644 index 000000000000..89ab9484fb71 --- /dev/null +++ b/arch/xtensa/variants/s6000/include/variant/dmac.h | |||
@@ -0,0 +1,387 @@ | |||
1 | /* | ||
2 | * include/asm-xtensa/variant-s6000/dmac.h | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2006 Tensilica Inc. | ||
9 | * Copyright (C) 2008 Emlix GmbH <info@emlix.com> | ||
10 | * Authors: Fabian Godehardt <fg@emlix.com> | ||
11 | * Oskar Schirmer <os@emlix.com> | ||
12 | * Daniel Gloeckner <dg@emlix.com> | ||
13 | */ | ||
14 | |||
15 | #ifndef __ASM_XTENSA_S6000_DMAC_H | ||
16 | #define __ASM_XTENSA_S6000_DMAC_H | ||
17 | #include <linux/io.h> | ||
18 | #include <variant/hardware.h> | ||
19 | |||
20 | /* DMA global */ | ||
21 | |||
22 | #define S6_DMA_INTSTAT0 0x000 | ||
23 | #define S6_DMA_INTSTAT1 0x004 | ||
24 | #define S6_DMA_INTENABLE0 0x008 | ||
25 | #define S6_DMA_INTENABLE1 0x00C | ||
26 | #define S6_DMA_INTRAW0 0x010 | ||
27 | #define S6_DMA_INTRAW1 0x014 | ||
28 | #define S6_DMA_INTCLEAR0 0x018 | ||
29 | #define S6_DMA_INTCLEAR1 0x01C | ||
30 | #define S6_DMA_INTSET0 0x020 | ||
31 | #define S6_DMA_INTSET1 0x024 | ||
32 | #define S6_DMA_INT0_UNDER 0 | ||
33 | #define S6_DMA_INT0_OVER 16 | ||
34 | #define S6_DMA_INT1_CHANNEL 0 | ||
35 | #define S6_DMA_INT1_MASTER 16 | ||
36 | #define S6_DMA_INT1_MASTER_MASK 7 | ||
37 | #define S6_DMA_TERMCNTIRQSTAT 0x028 | ||
38 | #define S6_DMA_TERMCNTIRQCLR 0x02C | ||
39 | #define S6_DMA_TERMCNTIRQSET 0x030 | ||
40 | #define S6_DMA_PENDCNTIRQSTAT 0x034 | ||
41 | #define S6_DMA_PENDCNTIRQCLR 0x038 | ||
42 | #define S6_DMA_PENDCNTIRQSET 0x03C | ||
43 | #define S6_DMA_LOWWMRKIRQSTAT 0x040 | ||
44 | #define S6_DMA_LOWWMRKIRQCLR 0x044 | ||
45 | #define S6_DMA_LOWWMRKIRQSET 0x048 | ||
46 | #define S6_DMA_MASTERERRINFO 0x04C | ||
47 | #define S6_DMA_MASTERERR_CHAN(n) (4*(n)) | ||
48 | #define S6_DMA_MASTERERR_CHAN_MASK 0xF | ||
49 | #define S6_DMA_DESCRFIFO0 0x050 | ||
50 | #define S6_DMA_DESCRFIFO1 0x054 | ||
51 | #define S6_DMA_DESCRFIFO2 0x058 | ||
52 | #define S6_DMA_DESCRFIFO2_AUTODISABLE 24 | ||
53 | #define S6_DMA_DESCRFIFO3 0x05C | ||
54 | #define S6_DMA_MASTER0START 0x060 | ||
55 | #define S6_DMA_MASTER0END 0x064 | ||
56 | #define S6_DMA_MASTER1START 0x068 | ||
57 | #define S6_DMA_MASTER1END 0x06C | ||
58 | #define S6_DMA_NEXTFREE 0x070 | ||
59 | #define S6_DMA_NEXTFREE_CHAN 0 | ||
60 | #define S6_DMA_NEXTFREE_CHAN_MASK 0x1F | ||
61 | #define S6_DMA_NEXTFREE_ENA 16 | ||
62 | #define S6_DMA_NEXTFREE_ENA_MASK ((1 << 16) - 1) | ||
63 | #define S6_DMA_DPORTCTRLGRP(p) ((p) * 4 + 0x074) | ||
64 | #define S6_DMA_DPORTCTRLGRP_FRAMEREP 0 | ||
65 | #define S6_DMA_DPORTCTRLGRP_NRCHANS 1 | ||
66 | #define S6_DMA_DPORTCTRLGRP_NRCHANS_1 0 | ||
67 | #define S6_DMA_DPORTCTRLGRP_NRCHANS_3 1 | ||
68 | #define S6_DMA_DPORTCTRLGRP_NRCHANS_4 2 | ||
69 | #define S6_DMA_DPORTCTRLGRP_NRCHANS_2 3 | ||
70 | #define S6_DMA_DPORTCTRLGRP_ENA 31 | ||
71 | |||
72 | |||
73 | /* DMA per channel */ | ||
74 | |||
75 | #define DMA_CHNL(dmac, n) ((dmac) + 0x1000 + (n) * 0x100) | ||
76 | #define DMA_INDEX_CHNL(addr) (((addr) >> 8) & 0xF) | ||
77 | #define DMA_MASK_DMAC(addr) ((addr) & 0xFFFF0000) | ||
78 | #define S6_DMA_CHNCTRL 0x000 | ||
79 | #define S6_DMA_CHNCTRL_ENABLE 0 | ||
80 | #define S6_DMA_CHNCTRL_PAUSE 1 | ||
81 | #define S6_DMA_CHNCTRL_PRIO 2 | ||
82 | #define S6_DMA_CHNCTRL_PRIO_MASK 3 | ||
83 | #define S6_DMA_CHNCTRL_PERIPHXFER 4 | ||
84 | #define S6_DMA_CHNCTRL_PERIPHENA 5 | ||
85 | #define S6_DMA_CHNCTRL_SRCINC 6 | ||
86 | #define S6_DMA_CHNCTRL_DSTINC 7 | ||
87 | #define S6_DMA_CHNCTRL_BURSTLOG 8 | ||
88 | #define S6_DMA_CHNCTRL_BURSTLOG_MASK 7 | ||
89 | #define S6_DMA_CHNCTRL_DESCFIFODEPTH 12 | ||
90 | #define S6_DMA_CHNCTRL_DESCFIFODEPTH_MASK 0x1F | ||
91 | #define S6_DMA_CHNCTRL_DESCFIFOFULL 17 | ||
92 | #define S6_DMA_CHNCTRL_BWCONSEL 18 | ||
93 | #define S6_DMA_CHNCTRL_BWCONENA 19 | ||
94 | #define S6_DMA_CHNCTRL_PENDGCNTSTAT 20 | ||
95 | #define S6_DMA_CHNCTRL_PENDGCNTSTAT_MASK 0x3F | ||
96 | #define S6_DMA_CHNCTRL_LOWWMARK 26 | ||
97 | #define S6_DMA_CHNCTRL_LOWWMARK_MASK 0xF | ||
98 | #define S6_DMA_CHNCTRL_TSTAMP 30 | ||
99 | #define S6_DMA_TERMCNTNB 0x004 | ||
100 | #define S6_DMA_TERMCNTNB_MASK 0xFFFF | ||
101 | #define S6_DMA_TERMCNTTMO 0x008 | ||
102 | #define S6_DMA_TERMCNTSTAT 0x00C | ||
103 | #define S6_DMA_TERMCNTSTAT_MASK 0xFF | ||
104 | #define S6_DMA_CMONCHUNK 0x010 | ||
105 | #define S6_DMA_SRCSKIP 0x014 | ||
106 | #define S6_DMA_DSTSKIP 0x018 | ||
107 | #define S6_DMA_CUR_SRC 0x024 | ||
108 | #define S6_DMA_CUR_DST 0x028 | ||
109 | #define S6_DMA_TIMESTAMP 0x030 | ||
110 | |||
111 | /* DMA channel lists */ | ||
112 | |||
113 | #define S6_DPDMA_CHAN(stream, channel) (4 * (stream) + (channel)) | ||
114 | #define S6_DPDMA_NB 16 | ||
115 | |||
116 | #define S6_HIFDMA_GMACTX 0 | ||
117 | #define S6_HIFDMA_GMACRX 1 | ||
118 | #define S6_HIFDMA_I2S0 2 | ||
119 | #define S6_HIFDMA_I2S1 3 | ||
120 | #define S6_HIFDMA_EGIB 4 | ||
121 | #define S6_HIFDMA_PCITX 5 | ||
122 | #define S6_HIFDMA_PCIRX 6 | ||
123 | #define S6_HIFDMA_NB 7 | ||
124 | |||
125 | #define S6_NIDMA_NB 4 | ||
126 | |||
127 | #define S6_LMSDMA_NB 12 | ||
128 | |||
129 | /* controller access */ | ||
130 | |||
131 | #define S6_DMAC_NB 4 | ||
132 | #define S6_DMAC_INDEX(dmac) (((unsigned)(dmac) >> 18) % S6_DMAC_NB) | ||
133 | |||
134 | struct s6dmac_ctrl { | ||
135 | u32 dmac; | ||
136 | spinlock_t lock; | ||
137 | u8 chan_nb; | ||
138 | }; | ||
139 | |||
140 | extern struct s6dmac_ctrl s6dmac_ctrl[S6_DMAC_NB]; | ||
141 | |||
142 | |||
143 | /* DMA control, per channel */ | ||
144 | |||
145 | static inline int s6dmac_fifo_full(u32 dmac, int chan) | ||
146 | { | ||
147 | return (readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) | ||
148 | & (1 << S6_DMA_CHNCTRL_DESCFIFOFULL)) && 1; | ||
149 | } | ||
150 | |||
151 | static inline int s6dmac_termcnt_irq(u32 dmac, int chan) | ||
152 | { | ||
153 | u32 m = 1 << chan; | ||
154 | int r = (readl(dmac + S6_DMA_TERMCNTIRQSTAT) & m) && 1; | ||
155 | if (r) | ||
156 | writel(m, dmac + S6_DMA_TERMCNTIRQCLR); | ||
157 | return r; | ||
158 | } | ||
159 | |||
160 | static inline int s6dmac_pendcnt_irq(u32 dmac, int chan) | ||
161 | { | ||
162 | u32 m = 1 << chan; | ||
163 | int r = (readl(dmac + S6_DMA_PENDCNTIRQSTAT) & m) && 1; | ||
164 | if (r) | ||
165 | writel(m, dmac + S6_DMA_PENDCNTIRQCLR); | ||
166 | return r; | ||
167 | } | ||
168 | |||
169 | static inline int s6dmac_lowwmark_irq(u32 dmac, int chan) | ||
170 | { | ||
171 | int r = (readl(dmac + S6_DMA_LOWWMRKIRQSTAT) & (1 << chan)) ? 1 : 0; | ||
172 | if (r) | ||
173 | writel(1 << chan, dmac + S6_DMA_LOWWMRKIRQCLR); | ||
174 | return r; | ||
175 | } | ||
176 | |||
177 | static inline u32 s6dmac_pending_count(u32 dmac, int chan) | ||
178 | { | ||
179 | return (readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) | ||
180 | >> S6_DMA_CHNCTRL_PENDGCNTSTAT) | ||
181 | & S6_DMA_CHNCTRL_PENDGCNTSTAT_MASK; | ||
182 | } | ||
183 | |||
184 | static inline void s6dmac_set_terminal_count(u32 dmac, int chan, u32 n) | ||
185 | { | ||
186 | n &= S6_DMA_TERMCNTNB_MASK; | ||
187 | n |= readl(DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB) | ||
188 | & ~S6_DMA_TERMCNTNB_MASK; | ||
189 | writel(n, DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB); | ||
190 | } | ||
191 | |||
192 | static inline u32 s6dmac_get_terminal_count(u32 dmac, int chan) | ||
193 | { | ||
194 | return (readl(DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB)) | ||
195 | & S6_DMA_TERMCNTNB_MASK; | ||
196 | } | ||
197 | |||
198 | static inline u32 s6dmac_timestamp(u32 dmac, int chan) | ||
199 | { | ||
200 | return readl(DMA_CHNL(dmac, chan) + S6_DMA_TIMESTAMP); | ||
201 | } | ||
202 | |||
203 | static inline u32 s6dmac_cur_src(u32 dmac, int chan) | ||
204 | { | ||
205 | return readl(DMA_CHNL(dmac, chan) + S6_DMA_CUR_SRC); | ||
206 | } | ||
207 | |||
208 | static inline u32 s6dmac_cur_dst(u32 dmac, int chan) | ||
209 | { | ||
210 | return readl(DMA_CHNL(dmac, chan) + S6_DMA_CUR_DST); | ||
211 | } | ||
212 | |||
213 | static inline void s6dmac_disable_chan(u32 dmac, int chan) | ||
214 | { | ||
215 | u32 ctrl; | ||
216 | writel(readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) | ||
217 | & ~(1 << S6_DMA_CHNCTRL_ENABLE), | ||
218 | DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); | ||
219 | do | ||
220 | ctrl = readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); | ||
221 | while (ctrl & (1 << S6_DMA_CHNCTRL_ENABLE)); | ||
222 | } | ||
223 | |||
224 | static inline void s6dmac_set_stride_skip(u32 dmac, int chan, | ||
225 | int comchunk, /* 0: disable scatter/gather */ | ||
226 | int srcskip, int dstskip) | ||
227 | { | ||
228 | writel(comchunk, DMA_CHNL(dmac, chan) + S6_DMA_CMONCHUNK); | ||
229 | writel(srcskip, DMA_CHNL(dmac, chan) + S6_DMA_SRCSKIP); | ||
230 | writel(dstskip, DMA_CHNL(dmac, chan) + S6_DMA_DSTSKIP); | ||
231 | } | ||
232 | |||
233 | static inline void s6dmac_enable_chan(u32 dmac, int chan, | ||
234 | int prio, /* 0 (highest) .. 3 (lowest) */ | ||
235 | int periphxfer, /* <0: disable p.req.line, 0..1: mode */ | ||
236 | int srcinc, int dstinc, /* 0: dont increment src/dst address */ | ||
237 | int comchunk, /* 0: disable scatter/gather */ | ||
238 | int srcskip, int dstskip, | ||
239 | int burstsize, /* 4 for I2S, 7 for everything else */ | ||
240 | int bandwidthconserve, /* <0: disable, 0..1: select */ | ||
241 | int lowwmark, /* 0..15 */ | ||
242 | int timestamp, /* 0: disable timestamp */ | ||
243 | int enable) /* 0: disable for now */ | ||
244 | { | ||
245 | writel(1, DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTNB); | ||
246 | writel(0, DMA_CHNL(dmac, chan) + S6_DMA_TERMCNTTMO); | ||
247 | writel(lowwmark << S6_DMA_CHNCTRL_LOWWMARK, | ||
248 | DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); | ||
249 | s6dmac_set_stride_skip(dmac, chan, comchunk, srcskip, dstskip); | ||
250 | writel(((enable ? 1 : 0) << S6_DMA_CHNCTRL_ENABLE) | | ||
251 | (prio << S6_DMA_CHNCTRL_PRIO) | | ||
252 | (((periphxfer > 0) ? 1 : 0) << S6_DMA_CHNCTRL_PERIPHXFER) | | ||
253 | (((periphxfer < 0) ? 0 : 1) << S6_DMA_CHNCTRL_PERIPHENA) | | ||
254 | ((srcinc ? 1 : 0) << S6_DMA_CHNCTRL_SRCINC) | | ||
255 | ((dstinc ? 1 : 0) << S6_DMA_CHNCTRL_DSTINC) | | ||
256 | (burstsize << S6_DMA_CHNCTRL_BURSTLOG) | | ||
257 | (((bandwidthconserve > 0) ? 1 : 0) << S6_DMA_CHNCTRL_BWCONSEL) | | ||
258 | (((bandwidthconserve < 0) ? 0 : 1) << S6_DMA_CHNCTRL_BWCONENA) | | ||
259 | (lowwmark << S6_DMA_CHNCTRL_LOWWMARK) | | ||
260 | ((timestamp ? 1 : 0) << S6_DMA_CHNCTRL_TSTAMP), | ||
261 | DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL); | ||
262 | } | ||
263 | |||
264 | |||
265 | /* DMA control, per engine */ | ||
266 | |||
267 | static inline unsigned _dmac_addr_index(u32 dmac) | ||
268 | { | ||
269 | unsigned i = S6_DMAC_INDEX(dmac); | ||
270 | if (s6dmac_ctrl[i].dmac != dmac) | ||
271 | BUG(); | ||
272 | return i; | ||
273 | } | ||
274 | |||
275 | static inline void _s6dmac_disable_error_irqs(u32 dmac, u32 mask) | ||
276 | { | ||
277 | writel(mask, dmac + S6_DMA_TERMCNTIRQCLR); | ||
278 | writel(mask, dmac + S6_DMA_PENDCNTIRQCLR); | ||
279 | writel(mask, dmac + S6_DMA_LOWWMRKIRQCLR); | ||
280 | writel(readl(dmac + S6_DMA_INTENABLE0) | ||
281 | & ~((mask << S6_DMA_INT0_UNDER) | (mask << S6_DMA_INT0_OVER)), | ||
282 | dmac + S6_DMA_INTENABLE0); | ||
283 | writel(readl(dmac + S6_DMA_INTENABLE1) & ~(mask << S6_DMA_INT1_CHANNEL), | ||
284 | dmac + S6_DMA_INTENABLE1); | ||
285 | writel((mask << S6_DMA_INT0_UNDER) | (mask << S6_DMA_INT0_OVER), | ||
286 | dmac + S6_DMA_INTCLEAR0); | ||
287 | writel(mask << S6_DMA_INT1_CHANNEL, dmac + S6_DMA_INTCLEAR1); | ||
288 | } | ||
289 | |||
290 | /* | ||
291 | * request channel from specified engine | ||
292 | * with chan<0, accept any channel | ||
293 | * further parameters see s6dmac_enable_chan | ||
294 | * returns < 0 upon error, channel nb otherwise | ||
295 | */ | ||
296 | static inline int s6dmac_request_chan(u32 dmac, int chan, | ||
297 | int prio, | ||
298 | int periphxfer, | ||
299 | int srcinc, int dstinc, | ||
300 | int comchunk, | ||
301 | int srcskip, int dstskip, | ||
302 | int burstsize, | ||
303 | int bandwidthconserve, | ||
304 | int lowwmark, | ||
305 | int timestamp, | ||
306 | int enable) | ||
307 | { | ||
308 | int r = chan; | ||
309 | unsigned long flags; | ||
310 | spinlock_t *spinl = &s6dmac_ctrl[_dmac_addr_index(dmac)].lock; | ||
311 | spin_lock_irqsave(spinl, flags); | ||
312 | if (r < 0) { | ||
313 | r = (readl(dmac + S6_DMA_NEXTFREE) >> S6_DMA_NEXTFREE_CHAN) | ||
314 | & S6_DMA_NEXTFREE_CHAN_MASK; | ||
315 | } | ||
316 | if (r >= s6dmac_ctrl[_dmac_addr_index(dmac)].chan_nb) { | ||
317 | if (chan < 0) | ||
318 | r = -EBUSY; | ||
319 | else | ||
320 | r = -ENXIO; | ||
321 | } else if (((readl(dmac + S6_DMA_NEXTFREE) >> S6_DMA_NEXTFREE_ENA) | ||
322 | >> r) & 1) { | ||
323 | r = -EBUSY; | ||
324 | } else { | ||
325 | s6dmac_enable_chan(dmac, r, prio, periphxfer, | ||
326 | srcinc, dstinc, comchunk, srcskip, dstskip, burstsize, | ||
327 | bandwidthconserve, lowwmark, timestamp, enable); | ||
328 | } | ||
329 | spin_unlock_irqrestore(spinl, flags); | ||
330 | return r; | ||
331 | } | ||
332 | |||
333 | static inline void s6dmac_put_fifo(u32 dmac, int chan, | ||
334 | u32 src, u32 dst, u32 size) | ||
335 | { | ||
336 | unsigned long flags; | ||
337 | spinlock_t *spinl = &s6dmac_ctrl[_dmac_addr_index(dmac)].lock; | ||
338 | spin_lock_irqsave(spinl, flags); | ||
339 | writel(src, dmac + S6_DMA_DESCRFIFO0); | ||
340 | writel(dst, dmac + S6_DMA_DESCRFIFO1); | ||
341 | writel(size, dmac + S6_DMA_DESCRFIFO2); | ||
342 | writel(chan, dmac + S6_DMA_DESCRFIFO3); | ||
343 | spin_unlock_irqrestore(spinl, flags); | ||
344 | } | ||
345 | |||
346 | static inline u32 s6dmac_channel_enabled(u32 dmac, int chan) | ||
347 | { | ||
348 | return readl(DMA_CHNL(dmac, chan) + S6_DMA_CHNCTRL) & | ||
349 | (1 << S6_DMA_CHNCTRL_ENABLE); | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * group 1-4 data port channels | ||
354 | * with port=0..3, nrch=1-4 channels, | ||
355 | * frrep=0/1 (dis- or enable frame repeat) | ||
356 | */ | ||
357 | static inline void s6dmac_dp_setup_group(u32 dmac, int port, | ||
358 | int nrch, int frrep) | ||
359 | { | ||
360 | const static u8 mask[4] = {0, 3, 1, 2}; | ||
361 | BUG_ON(dmac != S6_REG_DPDMA); | ||
362 | if ((port < 0) || (port > 3) || (nrch < 1) || (nrch > 4)) | ||
363 | return; | ||
364 | writel((mask[nrch - 1] << S6_DMA_DPORTCTRLGRP_NRCHANS) | ||
365 | | ((frrep ? 1 : 0) << S6_DMA_DPORTCTRLGRP_FRAMEREP), | ||
366 | dmac + S6_DMA_DPORTCTRLGRP(port)); | ||
367 | } | ||
368 | |||
369 | static inline void s6dmac_dp_switch_group(u32 dmac, int port, int enable) | ||
370 | { | ||
371 | u32 tmp; | ||
372 | BUG_ON(dmac != S6_REG_DPDMA); | ||
373 | tmp = readl(dmac + S6_DMA_DPORTCTRLGRP(port)); | ||
374 | if (enable) | ||
375 | tmp |= (1 << S6_DMA_DPORTCTRLGRP_ENA); | ||
376 | else | ||
377 | tmp &= ~(1 << S6_DMA_DPORTCTRLGRP_ENA); | ||
378 | writel(tmp, dmac + S6_DMA_DPORTCTRLGRP(port)); | ||
379 | } | ||
380 | |||
381 | extern void s6dmac_put_fifo_cache(u32 dmac, int chan, | ||
382 | u32 src, u32 dst, u32 size); | ||
383 | extern void s6dmac_disable_error_irqs(u32 dmac, u32 mask); | ||
384 | extern u32 s6dmac_int_sources(u32 dmac, u32 channel); | ||
385 | extern void s6dmac_release_chan(u32 dmac, int chan); | ||
386 | |||
387 | #endif /* __ASM_XTENSA_S6000_DMAC_H */ | ||
diff --git a/arch/xtensa/variants/s6000/include/variant/gpio.h b/arch/xtensa/variants/s6000/include/variant/gpio.h index 8327f62167eb..8484ab0df461 100644 --- a/arch/xtensa/variants/s6000/include/variant/gpio.h +++ b/arch/xtensa/variants/s6000/include/variant/gpio.h | |||
@@ -1,6 +1,6 @@ | |||
1 | #ifndef _XTENSA_VARIANT_S6000_GPIO_H | 1 | #ifndef _XTENSA_VARIANT_S6000_GPIO_H |
2 | #define _XTENSA_VARIANT_S6000_GPIO_H | 2 | #define _XTENSA_VARIANT_S6000_GPIO_H |
3 | 3 | ||
4 | extern int s6_gpio_init(void); | 4 | extern int s6_gpio_init(u32 afsel); |
5 | 5 | ||
6 | #endif /* _XTENSA_VARIANT_S6000_GPIO_H */ | 6 | #endif /* _XTENSA_VARIANT_S6000_GPIO_H */ |
diff --git a/arch/xtensa/variants/s6000/include/variant/irq.h b/arch/xtensa/variants/s6000/include/variant/irq.h index fa031cb0acc4..97d6fc48deff 100644 --- a/arch/xtensa/variants/s6000/include/variant/irq.h +++ b/arch/xtensa/variants/s6000/include/variant/irq.h | |||
@@ -1,9 +1,9 @@ | |||
1 | #ifndef __XTENSA_S6000_IRQ_H | 1 | #ifndef _XTENSA_S6000_IRQ_H |
2 | #define __XTENSA_S6000_IRQ_H | 2 | #define _XTENSA_S6000_IRQ_H |
3 | 3 | ||
4 | #define NO_IRQ (-1) | 4 | #define NO_IRQ (-1) |
5 | #define VARIANT_NR_IRQS 8 /* GPIO interrupts */ | ||
5 | 6 | ||
6 | extern void variant_irq_enable(unsigned int irq); | 7 | extern void variant_irq_enable(unsigned int irq); |
7 | extern void variant_irq_disable(unsigned int irq); | ||
8 | 8 | ||
9 | #endif /* __XTENSA_S6000_IRQ_H */ | 9 | #endif /* __XTENSA_S6000_IRQ_H */ |