diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/jazz | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/jazz')
-rw-r--r-- | arch/mips/jazz/Kconfig | 34 | ||||
-rw-r--r-- | arch/mips/jazz/Makefile | 6 | ||||
-rw-r--r-- | arch/mips/jazz/Platform | 5 | ||||
-rw-r--r-- | arch/mips/jazz/irq.c | 149 | ||||
-rw-r--r-- | arch/mips/jazz/jazzdma.c | 623 | ||||
-rw-r--r-- | arch/mips/jazz/reset.c | 57 | ||||
-rw-r--r-- | arch/mips/jazz/setup.c | 212 |
7 files changed, 1086 insertions, 0 deletions
diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig new file mode 100644 index 000000000..06838f80a --- /dev/null +++ b/arch/mips/jazz/Kconfig | |||
@@ -0,0 +1,34 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | config ACER_PICA_61 | ||
3 | bool "Support for Acer PICA 1 chipset" | ||
4 | depends on MACH_JAZZ | ||
5 | select DMA_NONCOHERENT | ||
6 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
7 | help | ||
8 | This is a machine with a R4400 133/150 MHz CPU. To compile a Linux | ||
9 | kernel that runs on these, say Y here. For details about Linux on | ||
10 | the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at | ||
11 | <http://www.linux-mips.org/>. | ||
12 | |||
13 | config MIPS_MAGNUM_4000 | ||
14 | bool "Support for MIPS Magnum 4000" | ||
15 | depends on MACH_JAZZ | ||
16 | select DMA_NONCOHERENT | ||
17 | select SYS_SUPPORTS_BIG_ENDIAN | ||
18 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
19 | help | ||
20 | This is a machine with a R4000 100 MHz CPU. To compile a Linux | ||
21 | kernel that runs on these, say Y here. For details about Linux on | ||
22 | the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at | ||
23 | <http://www.linux-mips.org/>. | ||
24 | |||
25 | config OLIVETTI_M700 | ||
26 | bool "Support for Olivetti M700-10" | ||
27 | depends on MACH_JAZZ | ||
28 | select DMA_NONCOHERENT | ||
29 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
30 | help | ||
31 | This is a machine with a R4000 100 MHz CPU. To compile a Linux | ||
32 | kernel that runs on these, say Y here. For details about Linux on | ||
33 | the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at | ||
34 | <http://www.linux-mips.org/>. | ||
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile new file mode 100644 index 000000000..5815e1cb3 --- /dev/null +++ b/arch/mips/jazz/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | ||
2 | # | ||
3 | # Makefile for the Jazz family specific parts of the kernel | ||
4 | # | ||
5 | |||
6 | obj-y := irq.o jazzdma.o reset.o setup.o | ||
diff --git a/arch/mips/jazz/Platform b/arch/mips/jazz/Platform new file mode 100644 index 000000000..eb0490ae8 --- /dev/null +++ b/arch/mips/jazz/Platform | |||
@@ -0,0 +1,5 @@ | |||
1 | # | ||
2 | # Acer PICA 61, Mips Magnum 4000 and Olivetti M700. | ||
3 | # | ||
4 | cflags-$(CONFIG_MACH_JAZZ) += -I$(srctree)/arch/mips/include/asm/mach-jazz | ||
5 | load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000 | ||
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c new file mode 100644 index 000000000..495ba7cc5 --- /dev/null +++ b/arch/mips/jazz/irq.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1992 Linus Torvalds | ||
7 | * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle | ||
8 | */ | ||
9 | #include <linux/clockchips.h> | ||
10 | #include <linux/i8253.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/smp.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/pgtable.h> | ||
18 | |||
19 | #include <asm/irq_cpu.h> | ||
20 | #include <asm/i8259.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/jazz.h> | ||
23 | #include <asm/tlbmisc.h> | ||
24 | |||
25 | static DEFINE_RAW_SPINLOCK(r4030_lock); | ||
26 | |||
27 | static void enable_r4030_irq(struct irq_data *d) | ||
28 | { | ||
29 | unsigned int mask = 1 << (d->irq - JAZZ_IRQ_START); | ||
30 | unsigned long flags; | ||
31 | |||
32 | raw_spin_lock_irqsave(&r4030_lock, flags); | ||
33 | mask |= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE); | ||
34 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask); | ||
35 | raw_spin_unlock_irqrestore(&r4030_lock, flags); | ||
36 | } | ||
37 | |||
38 | void disable_r4030_irq(struct irq_data *d) | ||
39 | { | ||
40 | unsigned int mask = ~(1 << (d->irq - JAZZ_IRQ_START)); | ||
41 | unsigned long flags; | ||
42 | |||
43 | raw_spin_lock_irqsave(&r4030_lock, flags); | ||
44 | mask &= r4030_read_reg16(JAZZ_IO_IRQ_ENABLE); | ||
45 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, mask); | ||
46 | raw_spin_unlock_irqrestore(&r4030_lock, flags); | ||
47 | } | ||
48 | |||
49 | static struct irq_chip r4030_irq_type = { | ||
50 | .name = "R4030", | ||
51 | .irq_mask = disable_r4030_irq, | ||
52 | .irq_unmask = enable_r4030_irq, | ||
53 | }; | ||
54 | |||
55 | void __init init_r4030_ints(void) | ||
56 | { | ||
57 | int i; | ||
58 | |||
59 | for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++) | ||
60 | irq_set_chip_and_handler(i, &r4030_irq_type, handle_level_irq); | ||
61 | |||
62 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0); | ||
63 | r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */ | ||
64 | r4030_read_reg32(JAZZ_R4030_INVAL_ADDR); /* clear error bits */ | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * On systems with i8259-style interrupt controllers we assume for | ||
69 | * driver compatibility reasons interrupts 0 - 15 to be the i8259 | ||
70 | * interrupts even if the hardware uses a different interrupt numbering. | ||
71 | */ | ||
72 | void __init arch_init_irq(void) | ||
73 | { | ||
74 | /* | ||
75 | * this is a hack to get back the still needed wired mapping | ||
76 | * killed by init_mm() | ||
77 | */ | ||
78 | |||
79 | /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */ | ||
80 | add_wired_entry(0x02000017, 0x03c00017, 0xe0000000, PM_64K); | ||
81 | /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */ | ||
82 | add_wired_entry(0x02400017, 0x02440017, 0xe2000000, PM_16M); | ||
83 | /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */ | ||
84 | add_wired_entry(0x01800017, 0x01000017, 0xe4000000, PM_4M); | ||
85 | |||
86 | init_i8259_irqs(); /* Integrated i8259 */ | ||
87 | mips_cpu_irq_init(); | ||
88 | init_r4030_ints(); | ||
89 | |||
90 | change_c0_status(ST0_IM, IE_IRQ2 | IE_IRQ1); | ||
91 | } | ||
92 | |||
93 | asmlinkage void plat_irq_dispatch(void) | ||
94 | { | ||
95 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
96 | unsigned int irq; | ||
97 | |||
98 | if (pending & IE_IRQ4) { | ||
99 | r4030_read_reg32(JAZZ_TIMER_REGISTER); | ||
100 | do_IRQ(JAZZ_TIMER_IRQ); | ||
101 | } else if (pending & IE_IRQ2) { | ||
102 | irq = *(volatile u8 *)JAZZ_EISA_IRQ_ACK; | ||
103 | do_IRQ(irq); | ||
104 | } else if (pending & IE_IRQ1) { | ||
105 | irq = *(volatile u8 *)JAZZ_IO_IRQ_SOURCE >> 2; | ||
106 | if (likely(irq > 0)) | ||
107 | do_IRQ(irq + JAZZ_IRQ_START - 1); | ||
108 | else | ||
109 | panic("Unimplemented loc_no_irq handler"); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | struct clock_event_device r4030_clockevent = { | ||
114 | .name = "r4030", | ||
115 | .features = CLOCK_EVT_FEAT_PERIODIC, | ||
116 | .rating = 300, | ||
117 | .irq = JAZZ_TIMER_IRQ, | ||
118 | }; | ||
119 | |||
120 | static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id) | ||
121 | { | ||
122 | struct clock_event_device *cd = dev_id; | ||
123 | |||
124 | cd->event_handler(cd); | ||
125 | return IRQ_HANDLED; | ||
126 | } | ||
127 | |||
128 | void __init plat_time_init(void) | ||
129 | { | ||
130 | struct clock_event_device *cd = &r4030_clockevent; | ||
131 | unsigned int cpu = smp_processor_id(); | ||
132 | |||
133 | BUG_ON(HZ != 100); | ||
134 | |||
135 | cd->cpumask = cpumask_of(cpu); | ||
136 | clockevents_register_device(cd); | ||
137 | if (request_irq(JAZZ_TIMER_IRQ, r4030_timer_interrupt, IRQF_TIMER, | ||
138 | "R4030 timer", cd)) | ||
139 | pr_err("Failed to register R4030 timer interrupt\n"); | ||
140 | |||
141 | /* | ||
142 | * Set clock to 100Hz. | ||
143 | * | ||
144 | * The R4030 timer receives an input clock of 1kHz which is divieded by | ||
145 | * a programmable 4-bit divider. This makes it fairly inflexible. | ||
146 | */ | ||
147 | r4030_write_reg32(JAZZ_TIMER_INTERVAL, 9); | ||
148 | setup_pit_timer(); | ||
149 | } | ||
diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c new file mode 100644 index 000000000..461457b28 --- /dev/null +++ b/arch/mips/jazz/jazzdma.c | |||
@@ -0,0 +1,623 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Mips Jazz DMA controller support | ||
4 | * Copyright (C) 1995, 1996 by Andreas Busse | ||
5 | * | ||
6 | * NOTE: Some of the argument checking could be removed when | ||
7 | * things have settled down. Also, instead of returning 0xffffffff | ||
8 | * on failure of vdma_alloc() one could leave page #0 unused | ||
9 | * and return the more usual NULL pointer as logical address. | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/export.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/memblock.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/gfp.h> | ||
19 | #include <linux/dma-map-ops.h> | ||
20 | #include <asm/mipsregs.h> | ||
21 | #include <asm/jazz.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <asm/dma.h> | ||
25 | #include <asm/jazzdma.h> | ||
26 | |||
27 | /* | ||
28 | * Set this to one to enable additional vdma debug code. | ||
29 | */ | ||
30 | #define CONF_DEBUG_VDMA 0 | ||
31 | |||
32 | static VDMA_PGTBL_ENTRY *pgtbl; | ||
33 | |||
34 | static DEFINE_SPINLOCK(vdma_lock); | ||
35 | |||
36 | /* | ||
37 | * Debug stuff | ||
38 | */ | ||
39 | #define vdma_debug ((CONF_DEBUG_VDMA) ? debuglvl : 0) | ||
40 | |||
41 | static int debuglvl = 3; | ||
42 | |||
43 | /* | ||
44 | * Initialize the pagetable with a one-to-one mapping of | ||
45 | * the first 16 Mbytes of main memory and declare all | ||
46 | * entries to be unused. Using this method will at least | ||
47 | * allow some early device driver operations to work. | ||
48 | */ | ||
49 | static inline void vdma_pgtbl_init(void) | ||
50 | { | ||
51 | unsigned long paddr = 0; | ||
52 | int i; | ||
53 | |||
54 | for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) { | ||
55 | pgtbl[i].frame = paddr; | ||
56 | pgtbl[i].owner = VDMA_PAGE_EMPTY; | ||
57 | paddr += VDMA_PAGESIZE; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Initialize the Jazz R4030 dma controller | ||
63 | */ | ||
64 | static int __init vdma_init(void) | ||
65 | { | ||
66 | /* | ||
67 | * Allocate 32k of memory for DMA page tables. This needs to be page | ||
68 | * aligned and should be uncached to avoid cache flushing after every | ||
69 | * update. | ||
70 | */ | ||
71 | pgtbl = (VDMA_PGTBL_ENTRY *)__get_free_pages(GFP_KERNEL | GFP_DMA, | ||
72 | get_order(VDMA_PGTBL_SIZE)); | ||
73 | BUG_ON(!pgtbl); | ||
74 | dma_cache_wback_inv((unsigned long)pgtbl, VDMA_PGTBL_SIZE); | ||
75 | pgtbl = (VDMA_PGTBL_ENTRY *)CKSEG1ADDR((unsigned long)pgtbl); | ||
76 | |||
77 | /* | ||
78 | * Clear the R4030 translation table | ||
79 | */ | ||
80 | vdma_pgtbl_init(); | ||
81 | |||
82 | r4030_write_reg32(JAZZ_R4030_TRSTBL_BASE, | ||
83 | CPHYSADDR((unsigned long)pgtbl)); | ||
84 | r4030_write_reg32(JAZZ_R4030_TRSTBL_LIM, VDMA_PGTBL_SIZE); | ||
85 | r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); | ||
86 | |||
87 | printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n"); | ||
88 | return 0; | ||
89 | } | ||
90 | arch_initcall(vdma_init); | ||
91 | |||
92 | /* | ||
93 | * Allocate DMA pagetables using a simple first-fit algorithm | ||
94 | */ | ||
95 | unsigned long vdma_alloc(unsigned long paddr, unsigned long size) | ||
96 | { | ||
97 | int first, last, pages, frame, i; | ||
98 | unsigned long laddr, flags; | ||
99 | |||
100 | /* check arguments */ | ||
101 | |||
102 | if (paddr > 0x1fffffff) { | ||
103 | if (vdma_debug) | ||
104 | printk("vdma_alloc: Invalid physical address: %08lx\n", | ||
105 | paddr); | ||
106 | return DMA_MAPPING_ERROR; /* invalid physical address */ | ||
107 | } | ||
108 | if (size > 0x400000 || size == 0) { | ||
109 | if (vdma_debug) | ||
110 | printk("vdma_alloc: Invalid size: %08lx\n", size); | ||
111 | return DMA_MAPPING_ERROR; /* invalid physical address */ | ||
112 | } | ||
113 | |||
114 | spin_lock_irqsave(&vdma_lock, flags); | ||
115 | /* | ||
116 | * Find free chunk | ||
117 | */ | ||
118 | pages = VDMA_PAGE(paddr + size) - VDMA_PAGE(paddr) + 1; | ||
119 | first = 0; | ||
120 | while (1) { | ||
121 | while (pgtbl[first].owner != VDMA_PAGE_EMPTY && | ||
122 | first < VDMA_PGTBL_ENTRIES) first++; | ||
123 | if (first + pages > VDMA_PGTBL_ENTRIES) { /* nothing free */ | ||
124 | spin_unlock_irqrestore(&vdma_lock, flags); | ||
125 | return DMA_MAPPING_ERROR; | ||
126 | } | ||
127 | |||
128 | last = first + 1; | ||
129 | while (pgtbl[last].owner == VDMA_PAGE_EMPTY | ||
130 | && last - first < pages) | ||
131 | last++; | ||
132 | |||
133 | if (last - first == pages) | ||
134 | break; /* found */ | ||
135 | first = last + 1; | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * Mark pages as allocated | ||
140 | */ | ||
141 | laddr = (first << 12) + (paddr & (VDMA_PAGESIZE - 1)); | ||
142 | frame = paddr & ~(VDMA_PAGESIZE - 1); | ||
143 | |||
144 | for (i = first; i < last; i++) { | ||
145 | pgtbl[i].frame = frame; | ||
146 | pgtbl[i].owner = laddr; | ||
147 | frame += VDMA_PAGESIZE; | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | * Update translation table and return logical start address | ||
152 | */ | ||
153 | r4030_write_reg32(JAZZ_R4030_TRSTBL_INV, 0); | ||
154 | |||
155 | if (vdma_debug > 1) | ||
156 | printk("vdma_alloc: Allocated %d pages starting from %08lx\n", | ||
157 | pages, laddr); | ||
158 | |||
159 | if (vdma_debug > 2) { | ||
160 | printk("LADDR: "); | ||
161 | for (i = first; i < last; i++) | ||
162 | printk("%08x ", i << 12); | ||
163 | printk("\nPADDR: "); | ||
164 | for (i = first; i < last; i++) | ||
165 | printk("%08x ", pgtbl[i].frame); | ||
166 | printk("\nOWNER: "); | ||
167 | for (i = first; i < last; i++) | ||
168 | printk("%08x ", pgtbl[i].owner); | ||
169 | printk("\n"); | ||
170 | } | ||
171 | |||
172 | spin_unlock_irqrestore(&vdma_lock, flags); | ||
173 | |||
174 | return laddr; | ||
175 | } | ||
176 | |||
177 | EXPORT_SYMBOL(vdma_alloc); | ||
178 | |||
179 | /* | ||
180 | * Free previously allocated dma translation pages | ||
181 | * Note that this does NOT change the translation table, | ||
182 | * it just marks the free'd pages as unused! | ||
183 | */ | ||
184 | int vdma_free(unsigned long laddr) | ||
185 | { | ||
186 | int i; | ||
187 | |||
188 | i = laddr >> 12; | ||
189 | |||
190 | if (pgtbl[i].owner != laddr) { | ||
191 | printk | ||
192 | ("vdma_free: trying to free other's dma pages, laddr=%8lx\n", | ||
193 | laddr); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | while (i < VDMA_PGTBL_ENTRIES && pgtbl[i].owner == laddr) { | ||
198 | pgtbl[i].owner = VDMA_PAGE_EMPTY; | ||
199 | i++; | ||
200 | } | ||
201 | |||
202 | if (vdma_debug > 1) | ||
203 | printk("vdma_free: freed %ld pages starting from %08lx\n", | ||
204 | i - (laddr >> 12), laddr); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | EXPORT_SYMBOL(vdma_free); | ||
210 | |||
211 | /* | ||
212 | * Translate a physical address to a logical address. | ||
213 | * This will return the logical address of the first | ||
214 | * match. | ||
215 | */ | ||
216 | unsigned long vdma_phys2log(unsigned long paddr) | ||
217 | { | ||
218 | int i; | ||
219 | int frame; | ||
220 | |||
221 | frame = paddr & ~(VDMA_PAGESIZE - 1); | ||
222 | |||
223 | for (i = 0; i < VDMA_PGTBL_ENTRIES; i++) { | ||
224 | if (pgtbl[i].frame == frame) | ||
225 | break; | ||
226 | } | ||
227 | |||
228 | if (i == VDMA_PGTBL_ENTRIES) | ||
229 | return ~0UL; | ||
230 | |||
231 | return (i << 12) + (paddr & (VDMA_PAGESIZE - 1)); | ||
232 | } | ||
233 | |||
234 | EXPORT_SYMBOL(vdma_phys2log); | ||
235 | |||
236 | /* | ||
237 | * Translate a logical DMA address to a physical address | ||
238 | */ | ||
239 | unsigned long vdma_log2phys(unsigned long laddr) | ||
240 | { | ||
241 | return pgtbl[laddr >> 12].frame + (laddr & (VDMA_PAGESIZE - 1)); | ||
242 | } | ||
243 | |||
244 | EXPORT_SYMBOL(vdma_log2phys); | ||
245 | |||
246 | /* | ||
247 | * Print DMA statistics | ||
248 | */ | ||
249 | void vdma_stats(void) | ||
250 | { | ||
251 | int i; | ||
252 | |||
253 | printk("vdma_stats: CONFIG: %08x\n", | ||
254 | r4030_read_reg32(JAZZ_R4030_CONFIG)); | ||
255 | printk("R4030 translation table base: %08x\n", | ||
256 | r4030_read_reg32(JAZZ_R4030_TRSTBL_BASE)); | ||
257 | printk("R4030 translation table limit: %08x\n", | ||
258 | r4030_read_reg32(JAZZ_R4030_TRSTBL_LIM)); | ||
259 | printk("vdma_stats: INV_ADDR: %08x\n", | ||
260 | r4030_read_reg32(JAZZ_R4030_INV_ADDR)); | ||
261 | printk("vdma_stats: R_FAIL_ADDR: %08x\n", | ||
262 | r4030_read_reg32(JAZZ_R4030_R_FAIL_ADDR)); | ||
263 | printk("vdma_stats: M_FAIL_ADDR: %08x\n", | ||
264 | r4030_read_reg32(JAZZ_R4030_M_FAIL_ADDR)); | ||
265 | printk("vdma_stats: IRQ_SOURCE: %08x\n", | ||
266 | r4030_read_reg32(JAZZ_R4030_IRQ_SOURCE)); | ||
267 | printk("vdma_stats: I386_ERROR: %08x\n", | ||
268 | r4030_read_reg32(JAZZ_R4030_I386_ERROR)); | ||
269 | printk("vdma_chnl_modes: "); | ||
270 | for (i = 0; i < 8; i++) | ||
271 | printk("%04x ", | ||
272 | (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE + | ||
273 | (i << 5))); | ||
274 | printk("\n"); | ||
275 | printk("vdma_chnl_enables: "); | ||
276 | for (i = 0; i < 8; i++) | ||
277 | printk("%04x ", | ||
278 | (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
279 | (i << 5))); | ||
280 | printk("\n"); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * DMA transfer functions | ||
285 | */ | ||
286 | |||
287 | /* | ||
288 | * Enable a DMA channel. Also clear any error conditions. | ||
289 | */ | ||
290 | void vdma_enable(int channel) | ||
291 | { | ||
292 | int status; | ||
293 | |||
294 | if (vdma_debug) | ||
295 | printk("vdma_enable: channel %d\n", channel); | ||
296 | |||
297 | /* | ||
298 | * Check error conditions first | ||
299 | */ | ||
300 | status = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5)); | ||
301 | if (status & 0x400) | ||
302 | printk("VDMA: Channel %d: Address error!\n", channel); | ||
303 | if (status & 0x200) | ||
304 | printk("VDMA: Channel %d: Memory error!\n", channel); | ||
305 | |||
306 | /* | ||
307 | * Clear all interrupt flags | ||
308 | */ | ||
309 | r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5), | ||
310 | r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
311 | (channel << 5)) | R4030_TC_INTR | ||
312 | | R4030_MEM_INTR | R4030_ADDR_INTR); | ||
313 | |||
314 | /* | ||
315 | * Enable the desired channel | ||
316 | */ | ||
317 | r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5), | ||
318 | r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
319 | (channel << 5)) | | ||
320 | R4030_CHNL_ENABLE); | ||
321 | } | ||
322 | |||
323 | EXPORT_SYMBOL(vdma_enable); | ||
324 | |||
325 | /* | ||
326 | * Disable a DMA channel | ||
327 | */ | ||
328 | void vdma_disable(int channel) | ||
329 | { | ||
330 | if (vdma_debug) { | ||
331 | int status = | ||
332 | r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
333 | (channel << 5)); | ||
334 | |||
335 | printk("vdma_disable: channel %d\n", channel); | ||
336 | printk("VDMA: channel %d status: %04x (%s) mode: " | ||
337 | "%02x addr: %06x count: %06x\n", | ||
338 | channel, status, | ||
339 | ((status & 0x600) ? "ERROR" : "OK"), | ||
340 | (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_MODE + | ||
341 | (channel << 5)), | ||
342 | (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_ADDR + | ||
343 | (channel << 5)), | ||
344 | (unsigned) r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + | ||
345 | (channel << 5))); | ||
346 | } | ||
347 | |||
348 | r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5), | ||
349 | r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
350 | (channel << 5)) & | ||
351 | ~R4030_CHNL_ENABLE); | ||
352 | |||
353 | /* | ||
354 | * After disabling a DMA channel a remote bus register should be | ||
355 | * read to ensure that the current DMA acknowledge cycle is completed. | ||
356 | */ | ||
357 | *((volatile unsigned int *) JAZZ_DUMMY_DEVICE); | ||
358 | } | ||
359 | |||
360 | EXPORT_SYMBOL(vdma_disable); | ||
361 | |||
362 | /* | ||
363 | * Set DMA mode. This function accepts the mode values used | ||
364 | * to set a PC-style DMA controller. For the SCSI and FDC | ||
365 | * channels, we also set the default modes each time we're | ||
366 | * called. | ||
367 | * NOTE: The FAST and BURST dma modes are supported by the | ||
368 | * R4030 Rev. 2 and PICA chipsets only. I leave them disabled | ||
369 | * for now. | ||
370 | */ | ||
371 | void vdma_set_mode(int channel, int mode) | ||
372 | { | ||
373 | if (vdma_debug) | ||
374 | printk("vdma_set_mode: channel %d, mode 0x%x\n", channel, | ||
375 | mode); | ||
376 | |||
377 | switch (channel) { | ||
378 | case JAZZ_SCSI_DMA: /* scsi */ | ||
379 | r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5), | ||
380 | /* R4030_MODE_FAST | */ | ||
381 | /* R4030_MODE_BURST | */ | ||
382 | R4030_MODE_INTR_EN | | ||
383 | R4030_MODE_WIDTH_16 | | ||
384 | R4030_MODE_ATIME_80); | ||
385 | break; | ||
386 | |||
387 | case JAZZ_FLOPPY_DMA: /* floppy */ | ||
388 | r4030_write_reg32(JAZZ_R4030_CHNL_MODE + (channel << 5), | ||
389 | /* R4030_MODE_FAST | */ | ||
390 | /* R4030_MODE_BURST | */ | ||
391 | R4030_MODE_INTR_EN | | ||
392 | R4030_MODE_WIDTH_8 | | ||
393 | R4030_MODE_ATIME_120); | ||
394 | break; | ||
395 | |||
396 | case JAZZ_AUDIOL_DMA: | ||
397 | case JAZZ_AUDIOR_DMA: | ||
398 | printk("VDMA: Audio DMA not supported yet.\n"); | ||
399 | break; | ||
400 | |||
401 | default: | ||
402 | printk | ||
403 | ("VDMA: vdma_set_mode() called with unsupported channel %d!\n", | ||
404 | channel); | ||
405 | } | ||
406 | |||
407 | switch (mode) { | ||
408 | case DMA_MODE_READ: | ||
409 | r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5), | ||
410 | r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
411 | (channel << 5)) & | ||
412 | ~R4030_CHNL_WRITE); | ||
413 | break; | ||
414 | |||
415 | case DMA_MODE_WRITE: | ||
416 | r4030_write_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5), | ||
417 | r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + | ||
418 | (channel << 5)) | | ||
419 | R4030_CHNL_WRITE); | ||
420 | break; | ||
421 | |||
422 | default: | ||
423 | printk | ||
424 | ("VDMA: vdma_set_mode() called with unknown dma mode 0x%x\n", | ||
425 | mode); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | EXPORT_SYMBOL(vdma_set_mode); | ||
430 | |||
431 | /* | ||
432 | * Set Transfer Address | ||
433 | */ | ||
434 | void vdma_set_addr(int channel, long addr) | ||
435 | { | ||
436 | if (vdma_debug) | ||
437 | printk("vdma_set_addr: channel %d, addr %lx\n", channel, | ||
438 | addr); | ||
439 | |||
440 | r4030_write_reg32(JAZZ_R4030_CHNL_ADDR + (channel << 5), addr); | ||
441 | } | ||
442 | |||
443 | EXPORT_SYMBOL(vdma_set_addr); | ||
444 | |||
445 | /* | ||
446 | * Set Transfer Count | ||
447 | */ | ||
448 | void vdma_set_count(int channel, int count) | ||
449 | { | ||
450 | if (vdma_debug) | ||
451 | printk("vdma_set_count: channel %d, count %08x\n", channel, | ||
452 | (unsigned) count); | ||
453 | |||
454 | r4030_write_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5), count); | ||
455 | } | ||
456 | |||
457 | EXPORT_SYMBOL(vdma_set_count); | ||
458 | |||
459 | /* | ||
460 | * Get Residual | ||
461 | */ | ||
462 | int vdma_get_residue(int channel) | ||
463 | { | ||
464 | int residual; | ||
465 | |||
466 | residual = r4030_read_reg32(JAZZ_R4030_CHNL_COUNT + (channel << 5)); | ||
467 | |||
468 | if (vdma_debug) | ||
469 | printk("vdma_get_residual: channel %d: residual=%d\n", | ||
470 | channel, residual); | ||
471 | |||
472 | return residual; | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * Get DMA channel enable register | ||
477 | */ | ||
478 | int vdma_get_enable(int channel) | ||
479 | { | ||
480 | int enable; | ||
481 | |||
482 | enable = r4030_read_reg32(JAZZ_R4030_CHNL_ENABLE + (channel << 5)); | ||
483 | |||
484 | if (vdma_debug) | ||
485 | printk("vdma_get_enable: channel %d: enable=%d\n", channel, | ||
486 | enable); | ||
487 | |||
488 | return enable; | ||
489 | } | ||
490 | |||
491 | static void *jazz_dma_alloc(struct device *dev, size_t size, | ||
492 | dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) | ||
493 | { | ||
494 | struct page *page; | ||
495 | void *ret; | ||
496 | |||
497 | if (attrs & DMA_ATTR_NO_WARN) | ||
498 | gfp |= __GFP_NOWARN; | ||
499 | |||
500 | size = PAGE_ALIGN(size); | ||
501 | page = alloc_pages(gfp, get_order(size)); | ||
502 | if (!page) | ||
503 | return NULL; | ||
504 | ret = page_address(page); | ||
505 | memset(ret, 0, size); | ||
506 | *dma_handle = vdma_alloc(virt_to_phys(ret), size); | ||
507 | if (*dma_handle == DMA_MAPPING_ERROR) | ||
508 | goto out_free_pages; | ||
509 | arch_dma_prep_coherent(page, size); | ||
510 | return (void *)(UNCAC_BASE + __pa(ret)); | ||
511 | |||
512 | out_free_pages: | ||
513 | __free_pages(page, get_order(size)); | ||
514 | return NULL; | ||
515 | } | ||
516 | |||
517 | static void jazz_dma_free(struct device *dev, size_t size, void *vaddr, | ||
518 | dma_addr_t dma_handle, unsigned long attrs) | ||
519 | { | ||
520 | vdma_free(dma_handle); | ||
521 | __free_pages(virt_to_page(vaddr), get_order(size)); | ||
522 | } | ||
523 | |||
524 | static dma_addr_t jazz_dma_map_page(struct device *dev, struct page *page, | ||
525 | unsigned long offset, size_t size, enum dma_data_direction dir, | ||
526 | unsigned long attrs) | ||
527 | { | ||
528 | phys_addr_t phys = page_to_phys(page) + offset; | ||
529 | |||
530 | if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) | ||
531 | arch_sync_dma_for_device(phys, size, dir); | ||
532 | return vdma_alloc(phys, size); | ||
533 | } | ||
534 | |||
535 | static void jazz_dma_unmap_page(struct device *dev, dma_addr_t dma_addr, | ||
536 | size_t size, enum dma_data_direction dir, unsigned long attrs) | ||
537 | { | ||
538 | if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) | ||
539 | arch_sync_dma_for_cpu(vdma_log2phys(dma_addr), size, dir); | ||
540 | vdma_free(dma_addr); | ||
541 | } | ||
542 | |||
543 | static int jazz_dma_map_sg(struct device *dev, struct scatterlist *sglist, | ||
544 | int nents, enum dma_data_direction dir, unsigned long attrs) | ||
545 | { | ||
546 | int i; | ||
547 | struct scatterlist *sg; | ||
548 | |||
549 | for_each_sg(sglist, sg, nents, i) { | ||
550 | if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) | ||
551 | arch_sync_dma_for_device(sg_phys(sg), sg->length, | ||
552 | dir); | ||
553 | sg->dma_address = vdma_alloc(sg_phys(sg), sg->length); | ||
554 | if (sg->dma_address == DMA_MAPPING_ERROR) | ||
555 | return 0; | ||
556 | sg_dma_len(sg) = sg->length; | ||
557 | } | ||
558 | |||
559 | return nents; | ||
560 | } | ||
561 | |||
562 | static void jazz_dma_unmap_sg(struct device *dev, struct scatterlist *sglist, | ||
563 | int nents, enum dma_data_direction dir, unsigned long attrs) | ||
564 | { | ||
565 | int i; | ||
566 | struct scatterlist *sg; | ||
567 | |||
568 | for_each_sg(sglist, sg, nents, i) { | ||
569 | if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC)) | ||
570 | arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); | ||
571 | vdma_free(sg->dma_address); | ||
572 | } | ||
573 | } | ||
574 | |||
575 | static void jazz_dma_sync_single_for_device(struct device *dev, | ||
576 | dma_addr_t addr, size_t size, enum dma_data_direction dir) | ||
577 | { | ||
578 | arch_sync_dma_for_device(vdma_log2phys(addr), size, dir); | ||
579 | } | ||
580 | |||
581 | static void jazz_dma_sync_single_for_cpu(struct device *dev, | ||
582 | dma_addr_t addr, size_t size, enum dma_data_direction dir) | ||
583 | { | ||
584 | arch_sync_dma_for_cpu(vdma_log2phys(addr), size, dir); | ||
585 | } | ||
586 | |||
587 | static void jazz_dma_sync_sg_for_device(struct device *dev, | ||
588 | struct scatterlist *sgl, int nents, enum dma_data_direction dir) | ||
589 | { | ||
590 | struct scatterlist *sg; | ||
591 | int i; | ||
592 | |||
593 | for_each_sg(sgl, sg, nents, i) | ||
594 | arch_sync_dma_for_device(sg_phys(sg), sg->length, dir); | ||
595 | } | ||
596 | |||
597 | static void jazz_dma_sync_sg_for_cpu(struct device *dev, | ||
598 | struct scatterlist *sgl, int nents, enum dma_data_direction dir) | ||
599 | { | ||
600 | struct scatterlist *sg; | ||
601 | int i; | ||
602 | |||
603 | for_each_sg(sgl, sg, nents, i) | ||
604 | arch_sync_dma_for_cpu(sg_phys(sg), sg->length, dir); | ||
605 | } | ||
606 | |||
607 | const struct dma_map_ops jazz_dma_ops = { | ||
608 | .alloc = jazz_dma_alloc, | ||
609 | .free = jazz_dma_free, | ||
610 | .map_page = jazz_dma_map_page, | ||
611 | .unmap_page = jazz_dma_unmap_page, | ||
612 | .map_sg = jazz_dma_map_sg, | ||
613 | .unmap_sg = jazz_dma_unmap_sg, | ||
614 | .sync_single_for_cpu = jazz_dma_sync_single_for_cpu, | ||
615 | .sync_single_for_device = jazz_dma_sync_single_for_device, | ||
616 | .sync_sg_for_cpu = jazz_dma_sync_sg_for_cpu, | ||
617 | .sync_sg_for_device = jazz_dma_sync_sg_for_device, | ||
618 | .mmap = dma_common_mmap, | ||
619 | .get_sgtable = dma_common_get_sgtable, | ||
620 | .alloc_pages = dma_common_alloc_pages, | ||
621 | .free_pages = dma_common_free_pages, | ||
622 | }; | ||
623 | EXPORT_SYMBOL(jazz_dma_ops); | ||
diff --git a/arch/mips/jazz/reset.c b/arch/mips/jazz/reset.c new file mode 100644 index 000000000..052b01f5d --- /dev/null +++ b/arch/mips/jazz/reset.c | |||
@@ -0,0 +1,57 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Reset a Jazz machine. | ||
4 | * | ||
5 | * We don't trust the firmware so we do it the classic way by poking and | ||
6 | * stabbing at the keyboard controller ... | ||
7 | */ | ||
8 | #include <linux/jiffies.h> | ||
9 | #include <asm/jazz.h> | ||
10 | |||
11 | #define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */ | ||
12 | |||
13 | static void jazz_write_output(unsigned char val) | ||
14 | { | ||
15 | int status; | ||
16 | |||
17 | do { | ||
18 | status = jazz_kh->command; | ||
19 | } while (status & KBD_STAT_IBF); | ||
20 | jazz_kh->data = val; | ||
21 | } | ||
22 | |||
23 | static void jazz_write_command(unsigned char val) | ||
24 | { | ||
25 | int status; | ||
26 | |||
27 | do { | ||
28 | status = jazz_kh->command; | ||
29 | } while (status & KBD_STAT_IBF); | ||
30 | jazz_kh->command = val; | ||
31 | } | ||
32 | |||
33 | static unsigned char jazz_read_status(void) | ||
34 | { | ||
35 | return jazz_kh->command; | ||
36 | } | ||
37 | |||
38 | static inline void kb_wait(void) | ||
39 | { | ||
40 | unsigned long start = jiffies; | ||
41 | unsigned long timeout = start + HZ/2; | ||
42 | |||
43 | do { | ||
44 | if (! (jazz_read_status() & 0x02)) | ||
45 | return; | ||
46 | } while (time_before_eq(jiffies, timeout)); | ||
47 | } | ||
48 | |||
49 | void jazz_machine_restart(char *command) | ||
50 | { | ||
51 | while(1) { | ||
52 | kb_wait(); | ||
53 | jazz_write_command(0xd1); | ||
54 | kb_wait(); | ||
55 | jazz_write_output(0x00); | ||
56 | } | ||
57 | } | ||
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c new file mode 100644 index 000000000..04aab419a --- /dev/null +++ b/arch/mips/jazz/setup.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * Setup pointers to hardware-dependent routines. | ||
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) 1996, 1997, 1998, 2001, 07, 08 by Ralf Baechle | ||
9 | * Copyright (C) 2001 MIPS Technologies, Inc. | ||
10 | * Copyright (C) 2007 by Thomas Bogendoerfer | ||
11 | */ | ||
12 | #include <linux/eisa.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/console.h> | ||
16 | #include <linux/screen_info.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/serial_8250.h> | ||
19 | #include <linux/dma-mapping.h> | ||
20 | #include <linux/pgtable.h> | ||
21 | |||
22 | #include <asm/jazz.h> | ||
23 | #include <asm/jazzdma.h> | ||
24 | #include <asm/reboot.h> | ||
25 | #include <asm/tlbmisc.h> | ||
26 | |||
27 | extern asmlinkage void jazz_handle_int(void); | ||
28 | |||
29 | extern void jazz_machine_restart(char *command); | ||
30 | |||
31 | static struct resource jazz_io_resources[] = { | ||
32 | { | ||
33 | .start = 0x00, | ||
34 | .end = 0x1f, | ||
35 | .name = "dma1", | ||
36 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
37 | }, { | ||
38 | .start = 0x40, | ||
39 | .end = 0x5f, | ||
40 | .name = "timer", | ||
41 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
42 | }, { | ||
43 | .start = 0x80, | ||
44 | .end = 0x8f, | ||
45 | .name = "dma page reg", | ||
46 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
47 | }, { | ||
48 | .start = 0xc0, | ||
49 | .end = 0xdf, | ||
50 | .name = "dma2", | ||
51 | .flags = IORESOURCE_IO | IORESOURCE_BUSY | ||
52 | } | ||
53 | }; | ||
54 | |||
55 | void __init plat_mem_setup(void) | ||
56 | { | ||
57 | int i; | ||
58 | |||
59 | /* Map 0xe0000000 -> 0x0:800005C0, 0xe0010000 -> 0x1:30000580 */ | ||
60 | add_wired_entry(0x02000017, 0x03c00017, 0xe0000000, PM_64K); | ||
61 | /* Map 0xe2000000 -> 0x0:900005C0, 0xe3010000 -> 0x0:910005C0 */ | ||
62 | add_wired_entry(0x02400017, 0x02440017, 0xe2000000, PM_16M); | ||
63 | /* Map 0xe4000000 -> 0x0:600005C0, 0xe4100000 -> 400005C0 */ | ||
64 | add_wired_entry(0x01800017, 0x01000017, 0xe4000000, PM_4M); | ||
65 | |||
66 | set_io_port_base(JAZZ_PORT_BASE); | ||
67 | #ifdef CONFIG_EISA | ||
68 | EISA_bus = 1; | ||
69 | #endif | ||
70 | |||
71 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
72 | for (i = 0; i < ARRAY_SIZE(jazz_io_resources); i++) | ||
73 | request_resource(&ioport_resource, jazz_io_resources + i); | ||
74 | |||
75 | /* The RTC is outside the port address space */ | ||
76 | |||
77 | _machine_restart = jazz_machine_restart; | ||
78 | |||
79 | #ifdef CONFIG_VT | ||
80 | screen_info = (struct screen_info) { | ||
81 | .orig_video_cols = 160, | ||
82 | .orig_video_lines = 64, | ||
83 | .orig_video_points = 16, | ||
84 | }; | ||
85 | #endif | ||
86 | |||
87 | add_preferred_console("ttyS", 0, "9600"); | ||
88 | } | ||
89 | |||
90 | #ifdef CONFIG_OLIVETTI_M700 | ||
91 | #define UART_CLK 1843200 | ||
92 | #else | ||
93 | /* Some Jazz machines seem to have an 8MHz crystal clock but I don't know | ||
94 | exactly which ones ... XXX */ | ||
95 | #define UART_CLK (8000000 / 16) /* ( 3072000 / 16) */ | ||
96 | #endif | ||
97 | |||
98 | #define MEMPORT(_base, _irq) \ | ||
99 | { \ | ||
100 | .mapbase = (_base), \ | ||
101 | .membase = (void *)(_base), \ | ||
102 | .irq = (_irq), \ | ||
103 | .uartclk = UART_CLK, \ | ||
104 | .iotype = UPIO_MEM, \ | ||
105 | .flags = UPF_BOOT_AUTOCONF, \ | ||
106 | } | ||
107 | |||
108 | static struct plat_serial8250_port jazz_serial_data[] = { | ||
109 | MEMPORT(JAZZ_SERIAL1_BASE, JAZZ_SERIAL1_IRQ), | ||
110 | MEMPORT(JAZZ_SERIAL2_BASE, JAZZ_SERIAL2_IRQ), | ||
111 | { }, | ||
112 | }; | ||
113 | |||
114 | static struct platform_device jazz_serial8250_device = { | ||
115 | .name = "serial8250", | ||
116 | .id = PLAT8250_DEV_PLATFORM, | ||
117 | .dev = { | ||
118 | .platform_data = jazz_serial_data, | ||
119 | }, | ||
120 | }; | ||
121 | |||
122 | static struct resource jazz_esp_rsrc[] = { | ||
123 | { | ||
124 | .start = JAZZ_SCSI_BASE, | ||
125 | .end = JAZZ_SCSI_BASE + 31, | ||
126 | .flags = IORESOURCE_MEM | ||
127 | }, | ||
128 | { | ||
129 | .start = JAZZ_SCSI_DMA, | ||
130 | .end = JAZZ_SCSI_DMA, | ||
131 | .flags = IORESOURCE_MEM | ||
132 | }, | ||
133 | { | ||
134 | .start = JAZZ_SCSI_IRQ, | ||
135 | .end = JAZZ_SCSI_IRQ, | ||
136 | .flags = IORESOURCE_IRQ | ||
137 | } | ||
138 | }; | ||
139 | |||
140 | static u64 jazz_esp_dma_mask = DMA_BIT_MASK(32); | ||
141 | |||
142 | static struct platform_device jazz_esp_pdev = { | ||
143 | .name = "jazz_esp", | ||
144 | .num_resources = ARRAY_SIZE(jazz_esp_rsrc), | ||
145 | .resource = jazz_esp_rsrc, | ||
146 | .dev = { | ||
147 | .dma_mask = &jazz_esp_dma_mask, | ||
148 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
149 | } | ||
150 | }; | ||
151 | |||
152 | static struct resource jazz_sonic_rsrc[] = { | ||
153 | { | ||
154 | .start = JAZZ_ETHERNET_BASE, | ||
155 | .end = JAZZ_ETHERNET_BASE + 0xff, | ||
156 | .flags = IORESOURCE_MEM | ||
157 | }, | ||
158 | { | ||
159 | .start = JAZZ_ETHERNET_IRQ, | ||
160 | .end = JAZZ_ETHERNET_IRQ, | ||
161 | .flags = IORESOURCE_IRQ | ||
162 | } | ||
163 | }; | ||
164 | |||
165 | static u64 jazz_sonic_dma_mask = DMA_BIT_MASK(32); | ||
166 | |||
167 | static struct platform_device jazz_sonic_pdev = { | ||
168 | .name = "jazzsonic", | ||
169 | .num_resources = ARRAY_SIZE(jazz_sonic_rsrc), | ||
170 | .resource = jazz_sonic_rsrc, | ||
171 | .dev = { | ||
172 | .dma_mask = &jazz_sonic_dma_mask, | ||
173 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
174 | } | ||
175 | }; | ||
176 | |||
177 | static struct resource jazz_cmos_rsrc[] = { | ||
178 | { | ||
179 | .start = 0x70, | ||
180 | .end = 0x71, | ||
181 | .flags = IORESOURCE_IO | ||
182 | }, | ||
183 | { | ||
184 | .start = 8, | ||
185 | .end = 8, | ||
186 | .flags = IORESOURCE_IRQ | ||
187 | } | ||
188 | }; | ||
189 | |||
190 | static struct platform_device jazz_cmos_pdev = { | ||
191 | .name = "rtc_cmos", | ||
192 | .num_resources = ARRAY_SIZE(jazz_cmos_rsrc), | ||
193 | .resource = jazz_cmos_rsrc | ||
194 | }; | ||
195 | |||
196 | static struct platform_device pcspeaker_pdev = { | ||
197 | .name = "pcspkr", | ||
198 | .id = -1, | ||
199 | }; | ||
200 | |||
201 | static int __init jazz_setup_devinit(void) | ||
202 | { | ||
203 | platform_device_register(&jazz_serial8250_device); | ||
204 | platform_device_register(&jazz_esp_pdev); | ||
205 | platform_device_register(&jazz_sonic_pdev); | ||
206 | platform_device_register(&jazz_cmos_pdev); | ||
207 | platform_device_register(&pcspeaker_pdev); | ||
208 | |||
209 | return 0; | ||
210 | } | ||
211 | |||
212 | device_initcall(jazz_setup_devinit); | ||