aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-13 04:52:30 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-13 04:52:30 -0400
commitc493756e2a8a78bcaae30668317890dcfe86e7c3 (patch)
tree8fb40782e79472ed882ff2098d4dd295557278ee /arch/sparc
parent0d15504f16f68725e4635aa85411015d1c573b0a (diff)
parent4480f15b3306f43bbb0310d461142b4e897ca45b (diff)
Merge branch 'linus' into oprofile
Conflicts: arch/x86/kernel/apic_32.c include/linux/pci_ids.h
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/Kconfig26
-rw-r--r--arch/sparc/include/asm/Kbuild2
-rw-r--r--arch/sparc/include/asm/asmmacro.h5
-rw-r--r--arch/sparc/include/asm/bpp.h73
-rw-r--r--arch/sparc/include/asm/bugs.h7
-rw-r--r--arch/sparc/include/asm/cpudata_64.h1
-rw-r--r--arch/sparc/include/asm/dma-mapping_32.h59
-rw-r--r--arch/sparc/include/asm/dma.h141
-rw-r--r--arch/sparc/include/asm/dma_32.h288
-rw-r--r--arch/sparc/include/asm/dma_64.h205
-rw-r--r--arch/sparc/include/asm/ebus.h8
-rw-r--r--arch/sparc/include/asm/ebus_32.h99
-rw-r--r--arch/sparc/include/asm/ebus_64.h95
-rw-r--r--arch/sparc/include/asm/ebus_dma.h35
-rw-r--r--arch/sparc/include/asm/elf_32.h7
-rw-r--r--arch/sparc/include/asm/fhc.h43
-rw-r--r--arch/sparc/include/asm/floppy_32.h16
-rw-r--r--arch/sparc/include/asm/floppy_64.h130
-rw-r--r--arch/sparc/include/asm/gpio.h36
-rw-r--r--arch/sparc/include/asm/io-unit.h4
-rw-r--r--arch/sparc/include/asm/io_32.h19
-rw-r--r--arch/sparc/include/asm/io_64.h22
-rw-r--r--arch/sparc/include/asm/iommu_64.h3
-rw-r--r--arch/sparc/include/asm/irq_64.h1
-rw-r--r--arch/sparc/include/asm/mc146818rtc_64.h10
-rw-r--r--arch/sparc/include/asm/memctrl.h9
-rw-r--r--arch/sparc/include/asm/mostek.h8
-rw-r--r--arch/sparc/include/asm/mostek_32.h171
-rw-r--r--arch/sparc/include/asm/mostek_64.h143
-rw-r--r--arch/sparc/include/asm/obio.h11
-rw-r--r--arch/sparc/include/asm/of_device.h2
-rw-r--r--arch/sparc/include/asm/of_platform.h3
-rw-r--r--arch/sparc/include/asm/oplib_32.h1
-rw-r--r--arch/sparc/include/asm/page_32.h5
-rw-r--r--arch/sparc/include/asm/page_64.h2
-rw-r--r--arch/sparc/include/asm/parport.h4
-rw-r--r--arch/sparc/include/asm/pci_32.h2
-rw-r--r--arch/sparc/include/asm/pgtable_32.h4
-rw-r--r--arch/sparc/include/asm/pgtable_64.h2
-rw-r--r--arch/sparc/include/asm/prom.h12
-rw-r--r--arch/sparc/include/asm/ptrace_64.h3
-rw-r--r--arch/sparc/include/asm/reboot.h6
-rw-r--r--arch/sparc/include/asm/rtc.h26
-rw-r--r--arch/sparc/include/asm/sbus.h8
-rw-r--r--arch/sparc/include/asm/sbus_32.h153
-rw-r--r--arch/sparc/include/asm/sbus_64.h190
-rw-r--r--arch/sparc/include/asm/spinlock_32.h2
-rw-r--r--arch/sparc/include/asm/spinlock_64.h2
-rw-r--r--arch/sparc/include/asm/sstate.h13
-rw-r--r--arch/sparc/include/asm/starfire.h1
-rw-r--r--arch/sparc/include/asm/sun4paddr.h56
-rw-r--r--arch/sparc/include/asm/sun4prom.h83
-rw-r--r--arch/sparc/include/asm/system_32.h9
-rw-r--r--arch/sparc/include/asm/system_64.h6
-rw-r--r--arch/sparc/include/asm/thread_info_32.h4
-rw-r--r--arch/sparc/include/asm/timer_32.h87
-rw-r--r--arch/sparc/include/asm/vac-ops.h7
-rw-r--r--arch/sparc/include/asm/vfc_ioctls.h58
-rw-r--r--arch/sparc/include/asm/visasm.h1
-rw-r--r--arch/sparc/kernel/Makefile4
-rw-r--r--arch/sparc/kernel/apc.c72
-rw-r--r--arch/sparc/kernel/auxio.c6
-rw-r--r--arch/sparc/kernel/devices.c2
-rw-r--r--arch/sparc/kernel/dma.c227
-rw-r--r--arch/sparc/kernel/dma.h14
-rw-r--r--arch/sparc/kernel/ebus.c393
-rw-r--r--arch/sparc/kernel/entry.S94
-rw-r--r--arch/sparc/kernel/head.S28
-rw-r--r--arch/sparc/kernel/idprom.c7
-rw-r--r--arch/sparc/kernel/ioport.c227
-rw-r--r--arch/sparc/kernel/irq.h6
-rw-r--r--arch/sparc/kernel/of_device.c74
-rw-r--r--arch/sparc/kernel/pcic.c15
-rw-r--r--arch/sparc/kernel/pmc.c59
-rw-r--r--arch/sparc/kernel/process.c2
-rw-r--r--arch/sparc/kernel/prom.c7
-rw-r--r--arch/sparc/kernel/setup.c32
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c25
-rw-r--r--arch/sparc/kernel/sun4c_irq.c156
-rw-r--r--arch/sparc/kernel/sun4d_irq.c286
-rw-r--r--arch/sparc/kernel/sun4d_smp.c13
-rw-r--r--arch/sparc/kernel/sun4m_irq.c495
-rw-r--r--arch/sparc/kernel/sun4m_smp.c6
-rw-r--r--arch/sparc/kernel/sun4setup.c75
-rw-r--r--arch/sparc/kernel/sys_sparc.c8
-rw-r--r--arch/sparc/kernel/tick14.c47
-rw-r--r--arch/sparc/kernel/time.c382
-rw-r--r--arch/sparc/kernel/traps.c17
-rw-r--r--arch/sparc/mm/Makefile9
-rw-r--r--arch/sparc/mm/btfixup.c6
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc/mm/init.c14
-rw-r--r--arch/sparc/mm/io-unit.c136
-rw-r--r--arch/sparc/mm/iommu.c113
-rw-r--r--arch/sparc/mm/nosrmmu.c59
-rw-r--r--arch/sparc/mm/srmmu.c1
-rw-r--r--arch/sparc/mm/sun4c.c204
-rw-r--r--arch/sparc/prom/Makefile2
-rw-r--r--arch/sparc/prom/bootstr.c4
-rw-r--r--arch/sparc/prom/console.c3
-rw-r--r--arch/sparc/prom/init.c12
-rw-r--r--arch/sparc/prom/memory.c14
-rw-r--r--arch/sparc/prom/ranges.c1
-rw-r--r--arch/sparc/prom/sun4prom.c161
104 files changed, 1557 insertions, 4392 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index a214002114ed..97671dac12a6 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -20,6 +20,11 @@ config GENERIC_ISA_DMA
20 bool 20 bool
21 default y 21 default y
22 22
23config GENERIC_GPIO
24 bool
25 help
26 Generic GPIO API support
27
23config ARCH_NO_VIRT_TO_BUS 28config ARCH_NO_VIRT_TO_BUS
24 def_bool y 29 def_bool y
25 30
@@ -69,6 +74,9 @@ config SPARC
69 select HAVE_OPROFILE 74 select HAVE_OPROFILE
70 select HAVE_ARCH_KGDB if !SMP 75 select HAVE_ARCH_KGDB if !SMP
71 select HAVE_ARCH_TRACEHOOK 76 select HAVE_ARCH_TRACEHOOK
77 select ARCH_WANT_OPTIONAL_GPIOLIB
78 select RTC_CLASS
79 select RTC_DRV_M48T59
72 80
73# Identify this as a Sparc32 build 81# Identify this as a Sparc32 build
74config SPARC32 82config SPARC32
@@ -204,17 +212,6 @@ config SUN_PM
204 Enable power management and CPU standby features on supported 212 Enable power management and CPU standby features on supported
205 SPARC platforms. 213 SPARC platforms.
206 214
207config SUN4
208 bool "Support for SUN4 machines (disables SUN4[CDM] support)"
209 depends on !SMP
210 default n
211 help
212 Say Y here if, and only if, your machine is a sun4. Note that
213 a kernel compiled with this option will run only on sun4.
214 (And the current version will probably work only on sun4/330.)
215
216if !SUN4
217
218config PCI 215config PCI
219 bool "Support for PCI and PS/2 keyboard/mouse" 216 bool "Support for PCI and PS/2 keyboard/mouse"
220 help 217 help
@@ -227,11 +224,6 @@ config PCI_SYSCALL
227 224
228source "drivers/pci/Kconfig" 225source "drivers/pci/Kconfig"
229 226
230endif
231
232config NO_DMA
233 def_bool !PCI
234
235config SUN_OPENPROMFS 227config SUN_OPENPROMFS
236 tristate "Openprom tree appears in /proc/openprom" 228 tristate "Openprom tree appears in /proc/openprom"
237 help 229 help
@@ -263,9 +255,7 @@ source "net/Kconfig"
263 255
264source "drivers/Kconfig" 256source "drivers/Kconfig"
265 257
266if !SUN4
267source "drivers/sbus/char/Kconfig" 258source "drivers/sbus/char/Kconfig"
268endif
269 259
270# This one must be before the filesystem configs. -DaveM 260# This one must be before the filesystem configs. -DaveM
271 261
diff --git a/arch/sparc/include/asm/Kbuild b/arch/sparc/include/asm/Kbuild
index a5f0ce734ff7..2ba7183bc1f0 100644
--- a/arch/sparc/include/asm/Kbuild
+++ b/arch/sparc/include/asm/Kbuild
@@ -22,7 +22,6 @@ header-y += unistd_64.h
22 22
23header-y += apc.h 23header-y += apc.h
24header-y += asi.h 24header-y += asi.h
25header-y += bpp.h
26header-y += display7seg.h 25header-y += display7seg.h
27header-y += envctrl.h 26header-y += envctrl.h
28header-y += fbio.h 27header-y += fbio.h
@@ -41,5 +40,4 @@ header-y += reg_64.h
41header-y += traps.h 40header-y += traps.h
42header-y += uctx.h 41header-y += uctx.h
43header-y += utrap.h 42header-y += utrap.h
44header-y += vfc_ioctls.h
45header-y += watchdog.h 43header-y += watchdog.h
diff --git a/arch/sparc/include/asm/asmmacro.h b/arch/sparc/include/asm/asmmacro.h
index a619a4d97aae..a995bf8aba3f 100644
--- a/arch/sparc/include/asm/asmmacro.h
+++ b/arch/sparc/include/asm/asmmacro.h
@@ -34,12 +34,7 @@
34/* sun4 probably wants half word accesses to ASI_SEGMAP, while sun4c+ 34/* sun4 probably wants half word accesses to ASI_SEGMAP, while sun4c+
35 likes byte accesses. These are to avoid ifdef mania. */ 35 likes byte accesses. These are to avoid ifdef mania. */
36 36
37#ifdef CONFIG_SUN4
38#define lduXa lduha
39#define stXa stha
40#else
41#define lduXa lduba 37#define lduXa lduba
42#define stXa stba 38#define stXa stba
43#endif
44 39
45#endif /* !(_SPARC_ASMMACRO_H) */ 40#endif /* !(_SPARC_ASMMACRO_H) */
diff --git a/arch/sparc/include/asm/bpp.h b/arch/sparc/include/asm/bpp.h
deleted file mode 100644
index 31f515e499a7..000000000000
--- a/arch/sparc/include/asm/bpp.h
+++ /dev/null
@@ -1,73 +0,0 @@
1#ifndef _SPARC_BPP_H
2#define _SPARC_BPP_H
3
4/*
5 * Copyright (c) 1995 Picture Elements
6 * Stephen Williams
7 * Gus Baldauf
8 *
9 * Linux/SPARC port by Peter Zaitcev.
10 * Integration into SPARC tree by Tom Dyas.
11 */
12
13#include <linux/ioctl.h>
14
15/*
16 * This is a driver that supports IEEE Std 1284-1994 communications
17 * with compliant or compatible devices. It will use whatever features
18 * the device supports, prefering those that are typically faster.
19 *
20 * When the device is opened, it is left in COMPATIBILITY mode, and
21 * writes work like any printer device. The driver only attempt to
22 * negotiate 1284 modes when needed so that plugs can be pulled,
23 * switch boxes switched, etc., without disrupting things. It will
24 * also leave the device in compatibility mode when closed.
25 */
26
27
28
29/*
30 * This driver also supplies ioctls to manually manipulate the
31 * pins. This is great for testing devices, or writing code to deal
32 * with bizzarro-mode of the ACME Special TurboThingy Plus.
33 *
34 * NOTE: These ioctl currently do not interact well with
35 * read/write. Caveat emptor.
36 *
37 * PUT_PINS allows us to assign the sense of all the pins, including
38 * the data pins if being driven by the host. The GET_PINS returns the
39 * pins that the peripheral drives, including data if appropriate.
40 */
41
42# define BPP_PUT_PINS _IOW('B', 1, int)
43# define BPP_GET_PINS _IOR('B', 2, char) /* that's bogus - should've been _IO */
44# define BPP_PUT_DATA _IOW('B', 3, int)
45# define BPP_GET_DATA _IOR('B', 4, char) /* ditto */
46
47/*
48 * Set the data bus to input mode. Disengage the data bin driver and
49 * be prepared to read values from the peripheral. If the arg is 0,
50 * then revert the bus to output mode.
51 */
52# define BPP_SET_INPUT _IOW('B', 5, int)
53
54/*
55 * These bits apply to the PUT operation...
56 */
57# define BPP_PP_nStrobe 0x0001
58# define BPP_PP_nAutoFd 0x0002
59# define BPP_PP_nInit 0x0004
60# define BPP_PP_nSelectIn 0x0008
61
62/*
63 * These apply to the GET operation, which also reads the current value
64 * of the previously put values. A bit mask of these will be returned
65 * as a bit mask in the return code of the ioctl().
66 */
67# define BPP_GP_nAck 0x0100
68# define BPP_GP_Busy 0x0200
69# define BPP_GP_PError 0x0400
70# define BPP_GP_Select 0x0800
71# define BPP_GP_nFault 0x1000
72
73#endif
diff --git a/arch/sparc/include/asm/bugs.h b/arch/sparc/include/asm/bugs.h
index e179bc12f64a..61d86bbbe2b2 100644
--- a/arch/sparc/include/asm/bugs.h
+++ b/arch/sparc/include/asm/bugs.h
@@ -7,10 +7,6 @@
7#include <asm/cpudata.h> 7#include <asm/cpudata.h>
8#endif 8#endif
9 9
10#ifdef CONFIG_SPARC64
11#include <asm/sstate.h>
12#endif
13
14extern unsigned long loops_per_jiffy; 10extern unsigned long loops_per_jiffy;
15 11
16static void __init check_bugs(void) 12static void __init check_bugs(void)
@@ -18,7 +14,4 @@ static void __init check_bugs(void)
18#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP) 14#if defined(CONFIG_SPARC32) && !defined(CONFIG_SMP)
19 cpu_data(0).udelay_val = loops_per_jiffy; 15 cpu_data(0).udelay_val = loops_per_jiffy;
20#endif 16#endif
21#ifdef CONFIG_SPARC64
22 sstate_running();
23#endif
24} 17}
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h
index 532975ecfe10..7da7c13d23c4 100644
--- a/arch/sparc/include/asm/cpudata_64.h
+++ b/arch/sparc/include/asm/cpudata_64.h
@@ -86,7 +86,6 @@ extern struct trap_per_cpu trap_block[NR_CPUS];
86extern void init_cur_cpu_trap(struct thread_info *); 86extern void init_cur_cpu_trap(struct thread_info *);
87extern void setup_tba(void); 87extern void setup_tba(void);
88extern int ncpus_probed; 88extern int ncpus_probed;
89extern void __init cpu_probe(void);
90extern const struct seq_operations cpuinfo_op; 89extern const struct seq_operations cpuinfo_op;
91 90
92extern unsigned long real_hard_smp_processor_id(void); 91extern unsigned long real_hard_smp_processor_id(void);
diff --git a/arch/sparc/include/asm/dma-mapping_32.h b/arch/sparc/include/asm/dma-mapping_32.h
index f3a641e6b2c8..8a57ea0573e6 100644
--- a/arch/sparc/include/asm/dma-mapping_32.h
+++ b/arch/sparc/include/asm/dma-mapping_32.h
@@ -1,11 +1,60 @@
1#ifndef _ASM_SPARC_DMA_MAPPING_H 1#ifndef _ASM_SPARC_DMA_MAPPING_H
2#define _ASM_SPARC_DMA_MAPPING_H 2#define _ASM_SPARC_DMA_MAPPING_H
3 3
4#include <linux/types.h>
4 5
5#ifdef CONFIG_PCI 6struct device;
6#include <asm-generic/dma-mapping.h> 7struct scatterlist;
7#else 8struct page;
8#include <asm-generic/dma-mapping-broken.h> 9
9#endif /* PCI */ 10#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
11
12extern int dma_supported(struct device *dev, u64 mask);
13extern int dma_set_mask(struct device *dev, u64 dma_mask);
14extern void *dma_alloc_coherent(struct device *dev, size_t size,
15 dma_addr_t *dma_handle, gfp_t flag);
16extern void dma_free_coherent(struct device *dev, size_t size,
17 void *cpu_addr, dma_addr_t dma_handle);
18extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
19 size_t size,
20 enum dma_data_direction direction);
21extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
22 size_t size,
23 enum dma_data_direction direction);
24extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
25 unsigned long offset, size_t size,
26 enum dma_data_direction direction);
27extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
28 size_t size, enum dma_data_direction direction);
29extern int dma_map_sg(struct device *dev, struct scatterlist *sg,
30 int nents, enum dma_data_direction direction);
31extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
32 int nents, enum dma_data_direction direction);
33extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
34 size_t size,
35 enum dma_data_direction direction);
36extern void dma_sync_single_for_device(struct device *dev,
37 dma_addr_t dma_handle,
38 size_t size,
39 enum dma_data_direction direction);
40extern void dma_sync_single_range_for_cpu(struct device *dev,
41 dma_addr_t dma_handle,
42 unsigned long offset,
43 size_t size,
44 enum dma_data_direction direction);
45extern void dma_sync_single_range_for_device(struct device *dev,
46 dma_addr_t dma_handle,
47 unsigned long offset, size_t size,
48 enum dma_data_direction direction);
49extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
50 int nelems, enum dma_data_direction direction);
51extern void dma_sync_sg_for_device(struct device *dev,
52 struct scatterlist *sg, int nelems,
53 enum dma_data_direction direction);
54extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
55extern int dma_get_cache_alignment(void);
56
57#define dma_alloc_noncoherent dma_alloc_coherent
58#define dma_free_noncoherent dma_free_coherent
10 59
11#endif /* _ASM_SPARC_DMA_MAPPING_H */ 60#endif /* _ASM_SPARC_DMA_MAPPING_H */
diff --git a/arch/sparc/include/asm/dma.h b/arch/sparc/include/asm/dma.h
index aa1d90ac04c5..b554927bbaf6 100644
--- a/arch/sparc/include/asm/dma.h
+++ b/arch/sparc/include/asm/dma.h
@@ -1,8 +1,139 @@
1#ifndef ___ASM_SPARC_DMA_H 1#ifndef _ASM_SPARC_DMA_H
2#define ___ASM_SPARC_DMA_H 2#define _ASM_SPARC_DMA_H
3#if defined(__sparc__) && defined(__arch64__) 3
4#include <asm/dma_64.h> 4/* These are irrelevant for Sparc DMA, but we leave it in so that
5 * things can compile.
6 */
7#define MAX_DMA_CHANNELS 8
8#define DMA_MODE_READ 1
9#define DMA_MODE_WRITE 2
10#define MAX_DMA_ADDRESS (~0UL)
11
12/* Useful constants */
13#define SIZE_16MB (16*1024*1024)
14#define SIZE_64K (64*1024)
15
16/* SBUS DMA controller reg offsets */
17#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
18#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
19#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
20#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
21
22/* Fields in the cond_reg register */
23/* First, the version identification bits */
24#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
25#define DMA_VERS0 0x00000000 /* Sunray DMA version */
26#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
27#define DMA_VERS1 0x80000000 /* DMA rev 1 */
28#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
29#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
30#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
31
32#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
33#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
34#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
35#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
36#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
37#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
38#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
39#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
40#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
41#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
42#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
43#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
44#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
45#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
46#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
47#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
48#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
49#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
50#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
51#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
52#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
53#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
54#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
55#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
56#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
57#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
58#define DMA_BRST64 0x000c0000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
59#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */
60#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */
61#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
62#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
63#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
64#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
65#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
66#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
67#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
68#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
69#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
70#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
71#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
72#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
73
74/* Values describing the burst-size property from the PROM */
75#define DMA_BURST1 0x01
76#define DMA_BURST2 0x02
77#define DMA_BURST4 0x04
78#define DMA_BURST8 0x08
79#define DMA_BURST16 0x10
80#define DMA_BURST32 0x20
81#define DMA_BURST64 0x40
82#define DMA_BURSTBITS 0x7f
83
84/* From PCI */
85
86#ifdef CONFIG_PCI
87extern int isa_dma_bridge_buggy;
5#else 88#else
6#include <asm/dma_32.h> 89#define isa_dma_bridge_buggy (0)
7#endif 90#endif
91
92#ifdef CONFIG_SPARC32
93
94/* Routines for data transfer buffers. */
95BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
96BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long)
97
98#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
99#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
100
101struct page;
102struct device;
103struct scatterlist;
104
105/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
106BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long)
107BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct device *, struct scatterlist *, int)
108BTFIXUPDEF_CALL(void, mmu_release_scsi_one, struct device *, __u32, unsigned long)
109BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct device *, struct scatterlist *, int)
110
111#define mmu_get_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_get_scsi_one)(dev,vaddr,len)
112#define mmu_get_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_get_scsi_sgl)(dev,sg,sz)
113#define mmu_release_scsi_one(dev,vaddr,len) BTFIXUP_CALL(mmu_release_scsi_one)(dev,vaddr,len)
114#define mmu_release_scsi_sgl(dev,sg,sz) BTFIXUP_CALL(mmu_release_scsi_sgl)(dev,sg,sz)
115
116/*
117 * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
118 *
119 * The mmu_map_dma_area establishes two mappings in one go.
120 * These mappings point to pages normally mapped at 'va' (linear address).
121 * First mapping is for CPU visible address at 'a', uncached.
122 * This is an alias, but it works because it is an uncached mapping.
123 * Second mapping is for device visible address, or "bus" address.
124 * The bus address is returned at '*pba'.
125 *
126 * These functions seem distinct, but are hard to split. On sun4c,
127 * at least for now, 'a' is equal to bus address, and retured in *pba.
128 * On sun4m, page attributes depend on the CPU type, so we have to
129 * know if we are mapping RAM or I/O, so it has to be an additional argument
130 * to a separate mapping function for CPU visible mappings.
131 */
132BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len)
133BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, struct device *, unsigned long busa, int len)
134
135#define mmu_map_dma_area(dev,pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(dev,pba,va,a,len)
136#define mmu_unmap_dma_area(dev,ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(dev,ba,len)
8#endif 137#endif
138
139#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/arch/sparc/include/asm/dma_32.h b/arch/sparc/include/asm/dma_32.h
deleted file mode 100644
index cf7189c0079b..000000000000
--- a/arch/sparc/include/asm/dma_32.h
+++ /dev/null
@@ -1,288 +0,0 @@
1/* include/asm/dma.h
2 *
3 * Copyright 1995 (C) David S. Miller (davem@davemloft.net)
4 */
5
6#ifndef _ASM_SPARC_DMA_H
7#define _ASM_SPARC_DMA_H
8
9#include <linux/kernel.h>
10#include <linux/types.h>
11
12#include <asm/vac-ops.h> /* for invalidate's, etc. */
13#include <asm/sbus.h>
14#include <asm/delay.h>
15#include <asm/oplib.h>
16#include <asm/system.h>
17#include <asm/io.h>
18#include <linux/spinlock.h>
19
20struct page;
21extern spinlock_t dma_spin_lock;
22
23static inline unsigned long claim_dma_lock(void)
24{
25 unsigned long flags;
26 spin_lock_irqsave(&dma_spin_lock, flags);
27 return flags;
28}
29
30static inline void release_dma_lock(unsigned long flags)
31{
32 spin_unlock_irqrestore(&dma_spin_lock, flags);
33}
34
35/* These are irrelevant for Sparc DMA, but we leave it in so that
36 * things can compile.
37 */
38#define MAX_DMA_CHANNELS 8
39#define MAX_DMA_ADDRESS (~0UL)
40#define DMA_MODE_READ 1
41#define DMA_MODE_WRITE 2
42
43/* Useful constants */
44#define SIZE_16MB (16*1024*1024)
45#define SIZE_64K (64*1024)
46
47/* SBUS DMA controller reg offsets */
48#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
49#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
50#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
51#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
52
53/* DVMA chip revisions */
54enum dvma_rev {
55 dvmarev0,
56 dvmaesc1,
57 dvmarev1,
58 dvmarev2,
59 dvmarev3,
60 dvmarevplus,
61 dvmahme
62};
63
64#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
65
66/* Linux DMA information structure, filled during probe. */
67struct sbus_dma {
68 struct sbus_dma *next;
69 struct sbus_dev *sdev;
70 void __iomem *regs;
71
72 /* Status, misc info */
73 int node; /* Prom node for this DMA device */
74 int running; /* Are we doing DMA now? */
75 int allocated; /* Are we "owned" by anyone yet? */
76
77 /* Transfer information. */
78 unsigned long addr; /* Start address of current transfer */
79 int nbytes; /* Size of current transfer */
80 int realbytes; /* For splitting up large transfers, etc. */
81
82 /* DMA revision */
83 enum dvma_rev revision;
84};
85
86extern struct sbus_dma *dma_chain;
87
88/* Broken hardware... */
89#ifdef CONFIG_SUN4
90/* Have to sort this out. Does rev0 work fine on sun4[cmd] without isbroken?
91 * Or is rev0 present only on sun4 boxes? -jj */
92#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev0 || (dma)->revision == dvmarev1)
93#else
94#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1)
95#endif
96#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
97
98/* Main routines in dma.c */
99extern void dvma_init(struct sbus_bus *);
100
101/* Fields in the cond_reg register */
102/* First, the version identification bits */
103#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
104#define DMA_VERS0 0x00000000 /* Sunray DMA version */
105#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
106#define DMA_VERS1 0x80000000 /* DMA rev 1 */
107#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
108#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
109#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
110
111#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
112#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
113#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
114#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
115#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
116#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
117#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
118#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
119#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
120#define DMA_RST_BPP DMA_RST_SCSI /* Reset the BPP controller */
121#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
122#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
123#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
124#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
125#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
126#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
127#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
128#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
129#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
130#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
131#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
132#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
133#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
134#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
135#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
136#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
137#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
138#define DMA_BRST64 0x00080000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
139#define DMA_BRST32 0x00040000 /* SCSI/BPP: 32byte bursts */
140#define DMA_BRST16 0x00000000 /* SCSI/BPP: 16byte bursts */
141#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
142#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
143#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
144#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
145#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
146#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
147#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
148#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
149#define DMA_BPP_ON DMA_SCSI_ON /* Enable BPP dma */
150#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
151#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
152#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
153#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
154
155/* Values describing the burst-size property from the PROM */
156#define DMA_BURST1 0x01
157#define DMA_BURST2 0x02
158#define DMA_BURST4 0x04
159#define DMA_BURST8 0x08
160#define DMA_BURST16 0x10
161#define DMA_BURST32 0x20
162#define DMA_BURST64 0x40
163#define DMA_BURSTBITS 0x7f
164
165/* Determine highest possible final transfer address given a base */
166#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
167
168/* Yes, I hack a lot of elisp in my spare time... */
169#define DMA_ERROR_P(regs) ((((regs)->cond_reg) & DMA_HNDL_ERROR))
170#define DMA_IRQ_P(regs) ((((regs)->cond_reg) & (DMA_HNDL_INTR | DMA_HNDL_ERROR)))
171#define DMA_WRITE_P(regs) ((((regs)->cond_reg) & DMA_ST_WRITE))
172#define DMA_OFF(regs) ((((regs)->cond_reg) &= (~DMA_ENABLE)))
173#define DMA_INTSOFF(regs) ((((regs)->cond_reg) &= (~DMA_INT_ENAB)))
174#define DMA_INTSON(regs) ((((regs)->cond_reg) |= (DMA_INT_ENAB)))
175#define DMA_PUNTFIFO(regs) ((((regs)->cond_reg) |= DMA_FIFO_INV))
176#define DMA_SETSTART(regs, addr) ((((regs)->st_addr) = (char *) addr))
177#define DMA_BEGINDMA_W(regs) \
178 ((((regs)->cond_reg |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB))))
179#define DMA_BEGINDMA_R(regs) \
180 ((((regs)->cond_reg |= ((DMA_ENABLE|DMA_INT_ENAB)&(~DMA_ST_WRITE)))))
181
182/* For certain DMA chips, we need to disable ints upon irq entry
183 * and turn them back on when we are done. So in any ESP interrupt
184 * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
185 * when leaving the handler. You have been warned...
186 */
187#define DMA_IRQ_ENTRY(dma, dregs) do { \
188 if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
189 } while (0)
190
191#define DMA_IRQ_EXIT(dma, dregs) do { \
192 if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
193 } while(0)
194
195#if 0 /* P3 this stuff is inline in ledma.c:init_restart_ledma() */
196/* Pause until counter runs out or BIT isn't set in the DMA condition
197 * register.
198 */
199static inline void sparc_dma_pause(struct sparc_dma_registers *regs,
200 unsigned long bit)
201{
202 int ctr = 50000; /* Let's find some bugs ;) */
203
204 /* Busy wait until the bit is not set any more */
205 while((regs->cond_reg&bit) && (ctr>0)) {
206 ctr--;
207 __delay(5);
208 }
209
210 /* Check for bogus outcome. */
211 if(!ctr)
212 panic("DMA timeout");
213}
214
215/* Reset the friggin' thing... */
216#define DMA_RESET(dma) do { \
217 struct sparc_dma_registers *regs = dma->regs; \
218 /* Let the current FIFO drain itself */ \
219 sparc_dma_pause(regs, (DMA_FIFO_ISDRAIN)); \
220 /* Reset the logic */ \
221 regs->cond_reg |= (DMA_RST_SCSI); /* assert */ \
222 __delay(400); /* let the bits set ;) */ \
223 regs->cond_reg &= ~(DMA_RST_SCSI); /* de-assert */ \
224 sparc_dma_enable_interrupts(regs); /* Re-enable interrupts */ \
225 /* Enable FAST transfers if available */ \
226 if(dma->revision>dvmarev1) regs->cond_reg |= DMA_3CLKS; \
227 dma->running = 0; \
228} while(0)
229#endif
230
231#define for_each_dvma(dma) \
232 for((dma) = dma_chain; (dma); (dma) = (dma)->next)
233
234extern int get_dma_list(char *);
235extern int request_dma(unsigned int, __const__ char *);
236extern void free_dma(unsigned int);
237
238/* From PCI */
239
240#ifdef CONFIG_PCI
241extern int isa_dma_bridge_buggy;
242#else
243#define isa_dma_bridge_buggy (0)
244#endif
245
246/* Routines for data transfer buffers. */
247BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long)
248BTFIXUPDEF_CALL(void, mmu_unlockarea, char *, unsigned long)
249
250#define mmu_lockarea(vaddr,len) BTFIXUP_CALL(mmu_lockarea)(vaddr,len)
251#define mmu_unlockarea(vaddr,len) BTFIXUP_CALL(mmu_unlockarea)(vaddr,len)
252
253/* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */
254BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus)
255BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
256BTFIXUPDEF_CALL(void, mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus)
257BTFIXUPDEF_CALL(void, mmu_release_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus)
258
259#define mmu_get_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_get_scsi_one)(vaddr,len,sbus)
260#define mmu_get_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_get_scsi_sgl)(sg,sz,sbus)
261#define mmu_release_scsi_one(vaddr,len,sbus) BTFIXUP_CALL(mmu_release_scsi_one)(vaddr,len,sbus)
262#define mmu_release_scsi_sgl(sg,sz,sbus) BTFIXUP_CALL(mmu_release_scsi_sgl)(sg,sz,sbus)
263
264/*
265 * mmu_map/unmap are provided by iommu/iounit; Invalid to call on IIep.
266 *
267 * The mmu_map_dma_area establishes two mappings in one go.
268 * These mappings point to pages normally mapped at 'va' (linear address).
269 * First mapping is for CPU visible address at 'a', uncached.
270 * This is an alias, but it works because it is an uncached mapping.
271 * Second mapping is for device visible address, or "bus" address.
272 * The bus address is returned at '*pba'.
273 *
274 * These functions seem distinct, but are hard to split. On sun4c,
275 * at least for now, 'a' is equal to bus address, and retured in *pba.
276 * On sun4m, page attributes depend on the CPU type, so we have to
277 * know if we are mapping RAM or I/O, so it has to be an additional argument
278 * to a separate mapping function for CPU visible mappings.
279 */
280BTFIXUPDEF_CALL(int, mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len)
281BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa)
282BTFIXUPDEF_CALL(void, mmu_unmap_dma_area, unsigned long busa, int len)
283
284#define mmu_map_dma_area(pba,va,a,len) BTFIXUP_CALL(mmu_map_dma_area)(pba,va,a,len)
285#define mmu_unmap_dma_area(ba,len) BTFIXUP_CALL(mmu_unmap_dma_area)(ba,len)
286#define mmu_translate_dvma(ba) BTFIXUP_CALL(mmu_translate_dvma)(ba)
287
288#endif /* !(_ASM_SPARC_DMA_H) */
diff --git a/arch/sparc/include/asm/dma_64.h b/arch/sparc/include/asm/dma_64.h
deleted file mode 100644
index 46a8aecffc02..000000000000
--- a/arch/sparc/include/asm/dma_64.h
+++ /dev/null
@@ -1,205 +0,0 @@
1/*
2 * include/asm/dma.h
3 *
4 * Copyright 1996 (C) David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#ifndef _ASM_SPARC64_DMA_H
8#define _ASM_SPARC64_DMA_H
9
10#include <linux/kernel.h>
11#include <linux/types.h>
12#include <linux/spinlock.h>
13
14#include <asm/sbus.h>
15#include <asm/delay.h>
16#include <asm/oplib.h>
17
18/* These are irrelevant for Sparc DMA, but we leave it in so that
19 * things can compile.
20 */
21#define MAX_DMA_CHANNELS 8
22#define DMA_MODE_READ 1
23#define DMA_MODE_WRITE 2
24#define MAX_DMA_ADDRESS (~0UL)
25
26/* Useful constants */
27#define SIZE_16MB (16*1024*1024)
28#define SIZE_64K (64*1024)
29
30/* SBUS DMA controller reg offsets */
31#define DMA_CSR 0x00UL /* rw DMA control/status register 0x00 */
32#define DMA_ADDR 0x04UL /* rw DMA transfer address register 0x04 */
33#define DMA_COUNT 0x08UL /* rw DMA transfer count register 0x08 */
34#define DMA_TEST 0x0cUL /* rw DMA test/debug register 0x0c */
35
36/* DVMA chip revisions */
37enum dvma_rev {
38 dvmarev0,
39 dvmaesc1,
40 dvmarev1,
41 dvmarev2,
42 dvmarev3,
43 dvmarevplus,
44 dvmahme
45};
46
47#define DMA_HASCOUNT(rev) ((rev)==dvmaesc1)
48
49/* Linux DMA information structure, filled during probe. */
50struct sbus_dma {
51 struct sbus_dma *next;
52 struct sbus_dev *sdev;
53 void __iomem *regs;
54
55 /* Status, misc info */
56 int node; /* Prom node for this DMA device */
57 int running; /* Are we doing DMA now? */
58 int allocated; /* Are we "owned" by anyone yet? */
59
60 /* Transfer information. */
61 u32 addr; /* Start address of current transfer */
62 int nbytes; /* Size of current transfer */
63 int realbytes; /* For splitting up large transfers, etc. */
64
65 /* DMA revision */
66 enum dvma_rev revision;
67};
68
69extern struct sbus_dma *dma_chain;
70
71/* Broken hardware... */
72#define DMA_ISBROKEN(dma) ((dma)->revision == dvmarev1)
73#define DMA_ISESC1(dma) ((dma)->revision == dvmaesc1)
74
75/* Main routines in dma.c */
76extern void dvma_init(struct sbus_bus *);
77
78/* Fields in the cond_reg register */
79/* First, the version identification bits */
80#define DMA_DEVICE_ID 0xf0000000 /* Device identification bits */
81#define DMA_VERS0 0x00000000 /* Sunray DMA version */
82#define DMA_ESCV1 0x40000000 /* DMA ESC Version 1 */
83#define DMA_VERS1 0x80000000 /* DMA rev 1 */
84#define DMA_VERS2 0xa0000000 /* DMA rev 2 */
85#define DMA_VERHME 0xb0000000 /* DMA hme gate array */
86#define DMA_VERSPLUS 0x90000000 /* DMA rev 1 PLUS */
87
88#define DMA_HNDL_INTR 0x00000001 /* An IRQ needs to be handled */
89#define DMA_HNDL_ERROR 0x00000002 /* We need to take an error */
90#define DMA_FIFO_ISDRAIN 0x0000000c /* The DMA FIFO is draining */
91#define DMA_INT_ENAB 0x00000010 /* Turn on interrupts */
92#define DMA_FIFO_INV 0x00000020 /* Invalidate the FIFO */
93#define DMA_ACC_SZ_ERR 0x00000040 /* The access size was bad */
94#define DMA_FIFO_STDRAIN 0x00000040 /* DMA_VERS1 Drain the FIFO */
95#define DMA_RST_SCSI 0x00000080 /* Reset the SCSI controller */
96#define DMA_RST_ENET DMA_RST_SCSI /* Reset the ENET controller */
97#define DMA_ST_WRITE 0x00000100 /* write from device to memory */
98#define DMA_ENABLE 0x00000200 /* Fire up DMA, handle requests */
99#define DMA_PEND_READ 0x00000400 /* DMA_VERS1/0/PLUS Pending Read */
100#define DMA_ESC_BURST 0x00000800 /* 1=16byte 0=32byte */
101#define DMA_READ_AHEAD 0x00001800 /* DMA read ahead partial longword */
102#define DMA_DSBL_RD_DRN 0x00001000 /* No EC drain on slave reads */
103#define DMA_BCNT_ENAB 0x00002000 /* If on, use the byte counter */
104#define DMA_TERM_CNTR 0x00004000 /* Terminal counter */
105#define DMA_SCSI_SBUS64 0x00008000 /* HME: Enable 64-bit SBUS mode. */
106#define DMA_CSR_DISAB 0x00010000 /* No FIFO drains during csr */
107#define DMA_SCSI_DISAB 0x00020000 /* No FIFO drains during reg */
108#define DMA_DSBL_WR_INV 0x00020000 /* No EC inval. on slave writes */
109#define DMA_ADD_ENABLE 0x00040000 /* Special ESC DVMA optimization */
110#define DMA_E_BURSTS 0x000c0000 /* ENET: SBUS r/w burst mask */
111#define DMA_E_BURST32 0x00040000 /* ENET: SBUS 32 byte r/w burst */
112#define DMA_E_BURST16 0x00000000 /* ENET: SBUS 16 byte r/w burst */
113#define DMA_BRST_SZ 0x000c0000 /* SCSI: SBUS r/w burst size */
114#define DMA_BRST64 0x000c0000 /* SCSI: 64byte bursts (HME on UltraSparc only) */
115#define DMA_BRST32 0x00040000 /* SCSI: 32byte bursts */
116#define DMA_BRST16 0x00000000 /* SCSI: 16byte bursts */
117#define DMA_BRST0 0x00080000 /* SCSI: no bursts (non-HME gate arrays) */
118#define DMA_ADDR_DISAB 0x00100000 /* No FIFO drains during addr */
119#define DMA_2CLKS 0x00200000 /* Each transfer = 2 clock ticks */
120#define DMA_3CLKS 0x00400000 /* Each transfer = 3 clock ticks */
121#define DMA_EN_ENETAUI DMA_3CLKS /* Put lance into AUI-cable mode */
122#define DMA_CNTR_DISAB 0x00800000 /* No IRQ when DMA_TERM_CNTR set */
123#define DMA_AUTO_NADDR 0x01000000 /* Use "auto nxt addr" feature */
124#define DMA_SCSI_ON 0x02000000 /* Enable SCSI dma */
125#define DMA_PARITY_OFF 0x02000000 /* HME: disable parity checking */
126#define DMA_LOADED_ADDR 0x04000000 /* Address has been loaded */
127#define DMA_LOADED_NADDR 0x08000000 /* Next address has been loaded */
128#define DMA_RESET_FAS366 0x08000000 /* HME: Assert RESET to FAS366 */
129
130/* Values describing the burst-size property from the PROM */
131#define DMA_BURST1 0x01
132#define DMA_BURST2 0x02
133#define DMA_BURST4 0x04
134#define DMA_BURST8 0x08
135#define DMA_BURST16 0x10
136#define DMA_BURST32 0x20
137#define DMA_BURST64 0x40
138#define DMA_BURSTBITS 0x7f
139
140/* Determine highest possible final transfer address given a base */
141#define DMA_MAXEND(addr) (0x01000000UL-(((unsigned long)(addr))&0x00ffffffUL))
142
143/* Yes, I hack a lot of elisp in my spare time... */
144#define DMA_ERROR_P(regs) ((sbus_readl((regs) + DMA_CSR) & DMA_HNDL_ERROR))
145#define DMA_IRQ_P(regs) ((sbus_readl((regs) + DMA_CSR)) & (DMA_HNDL_INTR | DMA_HNDL_ERROR))
146#define DMA_WRITE_P(regs) ((sbus_readl((regs) + DMA_CSR) & DMA_ST_WRITE))
147#define DMA_OFF(__regs) \
148do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
149 tmp &= ~DMA_ENABLE; \
150 sbus_writel(tmp, (__regs) + DMA_CSR); \
151} while(0)
152#define DMA_INTSOFF(__regs) \
153do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
154 tmp &= ~DMA_INT_ENAB; \
155 sbus_writel(tmp, (__regs) + DMA_CSR); \
156} while(0)
157#define DMA_INTSON(__regs) \
158do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
159 tmp |= DMA_INT_ENAB; \
160 sbus_writel(tmp, (__regs) + DMA_CSR); \
161} while(0)
162#define DMA_PUNTFIFO(__regs) \
163do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
164 tmp |= DMA_FIFO_INV; \
165 sbus_writel(tmp, (__regs) + DMA_CSR); \
166} while(0)
167#define DMA_SETSTART(__regs, __addr) \
168 sbus_writel((u32)(__addr), (__regs) + DMA_ADDR);
169#define DMA_BEGINDMA_W(__regs) \
170do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
171 tmp |= (DMA_ST_WRITE|DMA_ENABLE|DMA_INT_ENAB); \
172 sbus_writel(tmp, (__regs) + DMA_CSR); \
173} while(0)
174#define DMA_BEGINDMA_R(__regs) \
175do { u32 tmp = sbus_readl((__regs) + DMA_CSR); \
176 tmp |= (DMA_ENABLE|DMA_INT_ENAB); \
177 tmp &= ~DMA_ST_WRITE; \
178 sbus_writel(tmp, (__regs) + DMA_CSR); \
179} while(0)
180
181/* For certain DMA chips, we need to disable ints upon irq entry
182 * and turn them back on when we are done. So in any ESP interrupt
183 * handler you *must* call DMA_IRQ_ENTRY upon entry and DMA_IRQ_EXIT
184 * when leaving the handler. You have been warned...
185 */
186#define DMA_IRQ_ENTRY(dma, dregs) do { \
187 if(DMA_ISBROKEN(dma)) DMA_INTSOFF(dregs); \
188 } while (0)
189
190#define DMA_IRQ_EXIT(dma, dregs) do { \
191 if(DMA_ISBROKEN(dma)) DMA_INTSON(dregs); \
192 } while(0)
193
194#define for_each_dvma(dma) \
195 for((dma) = dma_chain; (dma); (dma) = (dma)->next)
196
197/* From PCI */
198
199#ifdef CONFIG_PCI
200extern int isa_dma_bridge_buggy;
201#else
202#define isa_dma_bridge_buggy (0)
203#endif
204
205#endif /* !(_ASM_SPARC64_DMA_H) */
diff --git a/arch/sparc/include/asm/ebus.h b/arch/sparc/include/asm/ebus.h
deleted file mode 100644
index 83a6d16c22e6..000000000000
--- a/arch/sparc/include/asm/ebus.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef ___ASM_SPARC_EBUS_H
2#define ___ASM_SPARC_EBUS_H
3#if defined(__sparc__) && defined(__arch64__)
4#include <asm/ebus_64.h>
5#else
6#include <asm/ebus_32.h>
7#endif
8#endif
diff --git a/arch/sparc/include/asm/ebus_32.h b/arch/sparc/include/asm/ebus_32.h
deleted file mode 100644
index f91f0b267ce1..000000000000
--- a/arch/sparc/include/asm/ebus_32.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 * ebus.h: PCI to Ebus pseudo driver software state.
3 *
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 *
6 * Adopted for sparc by V. Roganov and G. Raiko.
7 */
8
9#ifndef __SPARC_EBUS_H
10#define __SPARC_EBUS_H
11
12#ifndef _LINUX_IOPORT_H
13#include <linux/ioport.h>
14#endif
15#include <linux/of_device.h>
16#include <asm/oplib.h>
17#include <asm/prom.h>
18
19struct linux_ebus_child {
20 struct linux_ebus_child *next;
21 struct linux_ebus_device *parent;
22 struct linux_ebus *bus;
23 struct device_node *prom_node;
24 struct resource resource[PROMREG_MAX];
25 int num_addrs;
26 unsigned int irqs[PROMINTR_MAX];
27 int num_irqs;
28};
29
30struct linux_ebus_device {
31 struct of_device ofdev;
32 struct linux_ebus_device *next;
33 struct linux_ebus_child *children;
34 struct linux_ebus *bus;
35 struct device_node *prom_node;
36 struct resource resource[PROMREG_MAX];
37 int num_addrs;
38 unsigned int irqs[PROMINTR_MAX];
39 int num_irqs;
40};
41#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
42
43struct linux_ebus {
44 struct of_device ofdev;
45 struct linux_ebus *next;
46 struct linux_ebus_device *devices;
47 struct linux_pbm_info *parent;
48 struct pci_dev *self;
49 struct device_node *prom_node;
50};
51#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
52
53struct linux_ebus_dma {
54 unsigned int dcsr;
55 unsigned int dacr;
56 unsigned int dbcr;
57};
58
59#define EBUS_DCSR_INT_PEND 0x00000001
60#define EBUS_DCSR_ERR_PEND 0x00000002
61#define EBUS_DCSR_DRAIN 0x00000004
62#define EBUS_DCSR_INT_EN 0x00000010
63#define EBUS_DCSR_RESET 0x00000080
64#define EBUS_DCSR_WRITE 0x00000100
65#define EBUS_DCSR_EN_DMA 0x00000200
66#define EBUS_DCSR_CYC_PEND 0x00000400
67#define EBUS_DCSR_DIAG_RD_DONE 0x00000800
68#define EBUS_DCSR_DIAG_WR_DONE 0x00001000
69#define EBUS_DCSR_EN_CNT 0x00002000
70#define EBUS_DCSR_TC 0x00004000
71#define EBUS_DCSR_DIS_CSR_DRN 0x00010000
72#define EBUS_DCSR_BURST_SZ_MASK 0x000c0000
73#define EBUS_DCSR_BURST_SZ_1 0x00080000
74#define EBUS_DCSR_BURST_SZ_4 0x00000000
75#define EBUS_DCSR_BURST_SZ_8 0x00040000
76#define EBUS_DCSR_BURST_SZ_16 0x000c0000
77#define EBUS_DCSR_DIAG_EN 0x00100000
78#define EBUS_DCSR_DIS_ERR_PEND 0x00400000
79#define EBUS_DCSR_TCI_DIS 0x00800000
80#define EBUS_DCSR_EN_NEXT 0x01000000
81#define EBUS_DCSR_DMA_ON 0x02000000
82#define EBUS_DCSR_A_LOADED 0x04000000
83#define EBUS_DCSR_NA_LOADED 0x08000000
84#define EBUS_DCSR_DEV_ID_MASK 0xf0000000
85
86extern struct linux_ebus *ebus_chain;
87
88extern void ebus_init(void);
89
90#define for_each_ebus(bus) \
91 for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
92
93#define for_each_ebusdev(dev, bus) \
94 for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
95
96#define for_each_edevchild(dev, child) \
97 for((child) = (dev)->children; (child); (child) = (child)->next)
98
99#endif /* !(__SPARC_EBUS_H) */
diff --git a/arch/sparc/include/asm/ebus_64.h b/arch/sparc/include/asm/ebus_64.h
deleted file mode 100644
index 14c6a111f60c..000000000000
--- a/arch/sparc/include/asm/ebus_64.h
+++ /dev/null
@@ -1,95 +0,0 @@
1/*
2 * ebus.h: PCI to Ebus pseudo driver software state.
3 *
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
6 */
7
8#ifndef __SPARC64_EBUS_H
9#define __SPARC64_EBUS_H
10
11#include <linux/of_device.h>
12
13#include <asm/oplib.h>
14#include <asm/prom.h>
15
16struct linux_ebus_child {
17 struct linux_ebus_child *next;
18 struct linux_ebus_device *parent;
19 struct linux_ebus *bus;
20 struct device_node *prom_node;
21 struct resource resource[PROMREG_MAX];
22 int num_addrs;
23 unsigned int irqs[PROMINTR_MAX];
24 int num_irqs;
25};
26
27struct linux_ebus_device {
28 struct of_device ofdev;
29 struct linux_ebus_device *next;
30 struct linux_ebus_child *children;
31 struct linux_ebus *bus;
32 struct device_node *prom_node;
33 struct resource resource[PROMREG_MAX];
34 int num_addrs;
35 unsigned int irqs[PROMINTR_MAX];
36 int num_irqs;
37};
38#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
39
40struct linux_ebus {
41 struct of_device ofdev;
42 struct linux_ebus *next;
43 struct linux_ebus_device *devices;
44 struct pci_dev *self;
45 int index;
46 int is_rio;
47 struct device_node *prom_node;
48};
49#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
50
51struct ebus_dma_info {
52 spinlock_t lock;
53 void __iomem *regs;
54
55 unsigned int flags;
56#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER 0x00000001
57#define EBUS_DMA_FLAG_TCI_DISABLE 0x00000002
58
59 /* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is
60 * set.
61 */
62 void (*callback)(struct ebus_dma_info *p, int event, void *cookie);
63 void *client_cookie;
64 unsigned int irq;
65#define EBUS_DMA_EVENT_ERROR 1
66#define EBUS_DMA_EVENT_DMA 2
67#define EBUS_DMA_EVENT_DEVICE 4
68
69 unsigned char name[64];
70};
71
72extern int ebus_dma_register(struct ebus_dma_info *p);
73extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
74extern void ebus_dma_unregister(struct ebus_dma_info *p);
75extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
76 size_t len);
77extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
78extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
79extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
80extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
81
82extern struct linux_ebus *ebus_chain;
83
84extern void ebus_init(void);
85
86#define for_each_ebus(bus) \
87 for((bus) = ebus_chain; (bus); (bus) = (bus)->next)
88
89#define for_each_ebusdev(dev, bus) \
90 for((dev) = (bus)->devices; (dev); (dev) = (dev)->next)
91
92#define for_each_edevchild(dev, child) \
93 for((child) = (dev)->children; (child); (child) = (child)->next)
94
95#endif /* !(__SPARC64_EBUS_H) */
diff --git a/arch/sparc/include/asm/ebus_dma.h b/arch/sparc/include/asm/ebus_dma.h
new file mode 100644
index 000000000000..f07a5b541c98
--- /dev/null
+++ b/arch/sparc/include/asm/ebus_dma.h
@@ -0,0 +1,35 @@
1#ifndef __ASM_SPARC_EBUS_DMA_H
2#define __ASM_SPARC_EBUS_DMA_H
3
4struct ebus_dma_info {
5 spinlock_t lock;
6 void __iomem *regs;
7
8 unsigned int flags;
9#define EBUS_DMA_FLAG_USE_EBDMA_HANDLER 0x00000001
10#define EBUS_DMA_FLAG_TCI_DISABLE 0x00000002
11
12 /* These are only valid is EBUS_DMA_FLAG_USE_EBDMA_HANDLER is
13 * set.
14 */
15 void (*callback)(struct ebus_dma_info *p, int event, void *cookie);
16 void *client_cookie;
17 unsigned int irq;
18#define EBUS_DMA_EVENT_ERROR 1
19#define EBUS_DMA_EVENT_DMA 2
20#define EBUS_DMA_EVENT_DEVICE 4
21
22 unsigned char name[64];
23};
24
25extern int ebus_dma_register(struct ebus_dma_info *p);
26extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on);
27extern void ebus_dma_unregister(struct ebus_dma_info *p);
28extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr,
29 size_t len);
30extern void ebus_dma_prepare(struct ebus_dma_info *p, int write);
31extern unsigned int ebus_dma_residue(struct ebus_dma_info *p);
32extern unsigned int ebus_dma_addr(struct ebus_dma_info *p);
33extern void ebus_dma_enable(struct ebus_dma_info *p, int on);
34
35#endif /* __ASM_SPARC_EBUS_DMA_H */
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index d043f80bc2fd..b7ab60547827 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -105,11 +105,8 @@ typedef struct {
105#define ELF_DATA ELFDATA2MSB 105#define ELF_DATA ELFDATA2MSB
106 106
107#define USE_ELF_CORE_DUMP 107#define USE_ELF_CORE_DUMP
108#ifndef CONFIG_SUN4 108
109#define ELF_EXEC_PAGESIZE 4096 109#define ELF_EXEC_PAGESIZE 4096
110#else
111#define ELF_EXEC_PAGESIZE 8192
112#endif
113 110
114 111
115/* This is the location that an ET_DYN program is loaded if exec'ed. Typical 112/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
@@ -126,7 +123,7 @@ typedef struct {
126/* Sun4c has none of the capabilities, most sun4m's have them all. 123/* Sun4c has none of the capabilities, most sun4m's have them all.
127 * XXX This is gross, set some global variable at boot time. -DaveM 124 * XXX This is gross, set some global variable at boot time. -DaveM
128 */ 125 */
129#define ELF_HWCAP ((ARCH_SUN4C_SUN4) ? 0 : \ 126#define ELF_HWCAP ((ARCH_SUN4C) ? 0 : \
130 (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \ 127 (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | \
131 HWCAP_SPARC_SWAP | \ 128 HWCAP_SPARC_SWAP | \
132 ((srmmu_modtype != Cypress && \ 129 ((srmmu_modtype != Cypress && \
diff --git a/arch/sparc/include/asm/fhc.h b/arch/sparc/include/asm/fhc.h
index 788cbc46a116..57f1b303ad54 100644
--- a/arch/sparc/include/asm/fhc.h
+++ b/arch/sparc/include/asm/fhc.h
@@ -1,5 +1,4 @@
1/* 1/* fhc.h: FHC and Clock board register definitions.
2 * fhc.h: Structures for central/fhc pseudo driver on Sunfire/Starfire/Wildfire.
3 * 2 *
4 * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com) 3 * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
5 */ 4 */
@@ -7,14 +6,6 @@
7#ifndef _SPARC64_FHC_H 6#ifndef _SPARC64_FHC_H
8#define _SPARC64_FHC_H 7#define _SPARC64_FHC_H
9 8
10#include <linux/timer.h>
11
12#include <asm/oplib.h>
13#include <asm/prom.h>
14#include <asm/upa.h>
15
16struct linux_fhc;
17
18/* Clock board register offsets. */ 9/* Clock board register offsets. */
19#define CLOCK_CTRL 0x00UL /* Main control */ 10#define CLOCK_CTRL 0x00UL /* Main control */
20#define CLOCK_STAT1 0x10UL /* Status one */ 11#define CLOCK_STAT1 0x10UL /* Status one */
@@ -29,21 +20,7 @@ struct linux_fhc;
29#define CLOCK_CTRL_MLED 0x02 /* Mid LED, 1 == on */ 20#define CLOCK_CTRL_MLED 0x02 /* Mid LED, 1 == on */
30#define CLOCK_CTRL_RLED 0x01 /* RIght LED, 1 == on */ 21#define CLOCK_CTRL_RLED 0x01 /* RIght LED, 1 == on */
31 22
32struct linux_central {
33 struct linux_fhc *child;
34 unsigned long cfreg;
35 unsigned long clkregs;
36 unsigned long clkver;
37 int slots;
38 struct device_node *prom_node;
39
40 struct linux_prom_ranges central_ranges[PROMREG_MAX];
41 int num_central_ranges;
42};
43
44/* Firehose controller register offsets */ 23/* Firehose controller register offsets */
45struct fhc_regs {
46 unsigned long pregs; /* FHC internal regs */
47#define FHC_PREGS_ID 0x00UL /* FHC ID */ 24#define FHC_PREGS_ID 0x00UL /* FHC ID */
48#define FHC_ID_VERS 0xf0000000 /* Version of this FHC */ 25#define FHC_ID_VERS 0xf0000000 /* Version of this FHC */
49#define FHC_ID_PARTID 0x0ffff000 /* Part ID code (0x0f9f == FHC) */ 26#define FHC_ID_PARTID 0x0ffff000 /* Part ID code (0x0f9f == FHC) */
@@ -90,32 +67,14 @@ struct fhc_regs {
90#define FHC_JTAG_CTRL_MENAB 0x80000000 /* Indicates this is JTAG Master */ 67#define FHC_JTAG_CTRL_MENAB 0x80000000 /* Indicates this is JTAG Master */
91#define FHC_JTAG_CTRL_MNONE 0x40000000 /* Indicates no JTAG Master present */ 68#define FHC_JTAG_CTRL_MNONE 0x40000000 /* Indicates no JTAG Master present */
92#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */ 69#define FHC_PREGS_JCMD 0x100UL /* FHC JTAG Command Register */
93 unsigned long ireg; /* FHC IGN reg */
94#define FHC_IREG_IGN 0x00UL /* This FHC's IGN */ 70#define FHC_IREG_IGN 0x00UL /* This FHC's IGN */
95 unsigned long ffregs; /* FHC fanfail regs */
96#define FHC_FFREGS_IMAP 0x00UL /* FHC Fanfail IMAP */ 71#define FHC_FFREGS_IMAP 0x00UL /* FHC Fanfail IMAP */
97#define FHC_FFREGS_ICLR 0x10UL /* FHC Fanfail ICLR */ 72#define FHC_FFREGS_ICLR 0x10UL /* FHC Fanfail ICLR */
98 unsigned long sregs; /* FHC system regs */
99#define FHC_SREGS_IMAP 0x00UL /* FHC System IMAP */ 73#define FHC_SREGS_IMAP 0x00UL /* FHC System IMAP */
100#define FHC_SREGS_ICLR 0x10UL /* FHC System ICLR */ 74#define FHC_SREGS_ICLR 0x10UL /* FHC System ICLR */
101 unsigned long uregs; /* FHC uart regs */
102#define FHC_UREGS_IMAP 0x00UL /* FHC Uart IMAP */ 75#define FHC_UREGS_IMAP 0x00UL /* FHC Uart IMAP */
103#define FHC_UREGS_ICLR 0x10UL /* FHC Uart ICLR */ 76#define FHC_UREGS_ICLR 0x10UL /* FHC Uart ICLR */
104 unsigned long tregs; /* FHC TOD regs */
105#define FHC_TREGS_IMAP 0x00UL /* FHC TOD IMAP */ 77#define FHC_TREGS_IMAP 0x00UL /* FHC TOD IMAP */
106#define FHC_TREGS_ICLR 0x10UL /* FHC TOD ICLR */ 78#define FHC_TREGS_ICLR 0x10UL /* FHC TOD ICLR */
107};
108
109struct linux_fhc {
110 struct linux_fhc *next;
111 struct linux_central *parent; /* NULL if not central FHC */
112 struct fhc_regs fhc_regs;
113 int board;
114 int jtag_master;
115 struct device_node *prom_node;
116
117 struct linux_prom_ranges fhc_ranges[PROMREG_MAX];
118 int num_fhc_ranges;
119};
120 79
121#endif /* !(_SPARC64_FHC_H) */ 80#endif /* !(_SPARC64_FHC_H) */
diff --git a/arch/sparc/include/asm/floppy_32.h b/arch/sparc/include/asm/floppy_32.h
index ae3f00bf22ff..c792830636de 100644
--- a/arch/sparc/include/asm/floppy_32.h
+++ b/arch/sparc/include/asm/floppy_32.h
@@ -6,6 +6,9 @@
6#ifndef __ASM_SPARC_FLOPPY_H 6#ifndef __ASM_SPARC_FLOPPY_H
7#define __ASM_SPARC_FLOPPY_H 7#define __ASM_SPARC_FLOPPY_H
8 8
9#include <linux/of.h>
10#include <linux/of_device.h>
11
9#include <asm/page.h> 12#include <asm/page.h>
10#include <asm/pgtable.h> 13#include <asm/pgtable.h>
11#include <asm/system.h> 14#include <asm/system.h>
@@ -343,7 +346,7 @@ static int sun_floppy_init(void)
343 r.flags = fd_regs[0].which_io; 346 r.flags = fd_regs[0].which_io;
344 r.start = fd_regs[0].phys_addr; 347 r.start = fd_regs[0].phys_addr;
345 sun_fdc = (struct sun_flpy_controller *) 348 sun_fdc = (struct sun_flpy_controller *)
346 sbus_ioremap(&r, 0, fd_regs[0].reg_size, "floppy"); 349 of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
347 350
348 /* Last minute sanity check... */ 351 /* Last minute sanity check... */
349 if(sun_fdc->status_82072 == 0xff) { 352 if(sun_fdc->status_82072 == 0xff) {
@@ -385,4 +388,15 @@ static int sparc_eject(void)
385 388
386#define EXTRA_FLOPPY_PARAMS 389#define EXTRA_FLOPPY_PARAMS
387 390
391static DEFINE_SPINLOCK(dma_spin_lock);
392
393#define claim_dma_lock() \
394({ unsigned long flags; \
395 spin_lock_irqsave(&dma_spin_lock, flags); \
396 flags; \
397})
398
399#define release_dma_lock(__flags) \
400 spin_unlock_irqrestore(&dma_spin_lock, __flags);
401
388#endif /* !(__ASM_SPARC_FLOPPY_H) */ 402#endif /* !(__ASM_SPARC_FLOPPY_H) */
diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h
index c39db1060bc7..36439d67ad71 100644
--- a/arch/sparc/include/asm/floppy_64.h
+++ b/arch/sparc/include/asm/floppy_64.h
@@ -1,6 +1,6 @@
1/* floppy.h: Sparc specific parts of the Floppy driver. 1/* floppy.h: Sparc specific parts of the Floppy driver.
2 * 2 *
3 * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net) 3 * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) 4 * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * 5 *
6 * Ultra/PCI support added: Sep 1997 Eddie C. Dost (ecd@skynet.be) 6 * Ultra/PCI support added: Sep 1997 Eddie C. Dost (ecd@skynet.be)
@@ -9,18 +9,11 @@
9#ifndef __ASM_SPARC64_FLOPPY_H 9#ifndef __ASM_SPARC64_FLOPPY_H
10#define __ASM_SPARC64_FLOPPY_H 10#define __ASM_SPARC64_FLOPPY_H
11 11
12#include <linux/init.h> 12#include <linux/of.h>
13#include <linux/pci.h> 13#include <linux/of_device.h>
14#include <linux/dma-mapping.h>
14 15
15#include <asm/page.h>
16#include <asm/pgtable.h>
17#include <asm/system.h>
18#include <asm/idprom.h>
19#include <asm/oplib.h>
20#include <asm/auxio.h> 16#include <asm/auxio.h>
21#include <asm/sbus.h>
22#include <asm/irq.h>
23
24 17
25/* 18/*
26 * Define this to enable exchanging drive 0 and 1 if only drive 1 is 19 * Define this to enable exchanging drive 0 and 1 if only drive 1 is
@@ -50,7 +43,7 @@ struct sun_flpy_controller {
50/* You'll only ever find one controller on an Ultra anyways. */ 43/* You'll only ever find one controller on an Ultra anyways. */
51static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; 44static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1;
52unsigned long fdc_status; 45unsigned long fdc_status;
53static struct sbus_dev *floppy_sdev = NULL; 46static struct of_device *floppy_op = NULL;
54 47
55struct sun_floppy_ops { 48struct sun_floppy_ops {
56 unsigned char (*fd_inb) (unsigned long port); 49 unsigned char (*fd_inb) (unsigned long port);
@@ -291,12 +284,11 @@ static int sun_fd_eject(int drive)
291 return 0; 284 return 0;
292} 285}
293 286
294#ifdef CONFIG_PCI 287#include <asm/ebus_dma.h>
295#include <asm/ebus.h>
296#include <asm/ns87303.h> 288#include <asm/ns87303.h>
297 289
298static struct ebus_dma_info sun_pci_fd_ebus_dma; 290static struct ebus_dma_info sun_pci_fd_ebus_dma;
299static struct pci_dev *sun_pci_ebus_dev; 291static struct device *sun_floppy_dev;
300static int sun_pci_broken_drive = -1; 292static int sun_pci_broken_drive = -1;
301 293
302struct sun_pci_dma_op { 294struct sun_pci_dma_op {
@@ -377,7 +369,7 @@ static void sun_pci_fd_enable_dma(void)
377 sun_pci_dma_pending.addr = -1U; 369 sun_pci_dma_pending.addr = -1U;
378 370
379 sun_pci_dma_current.addr = 371 sun_pci_dma_current.addr =
380 pci_map_single(sun_pci_ebus_dev, 372 dma_map_single(sun_floppy_dev,
381 sun_pci_dma_current.buf, 373 sun_pci_dma_current.buf,
382 sun_pci_dma_current.len, 374 sun_pci_dma_current.len,
383 sun_pci_dma_current.direction); 375 sun_pci_dma_current.direction);
@@ -394,7 +386,7 @@ static void sun_pci_fd_disable_dma(void)
394{ 386{
395 ebus_dma_enable(&sun_pci_fd_ebus_dma, 0); 387 ebus_dma_enable(&sun_pci_fd_ebus_dma, 0);
396 if (sun_pci_dma_current.addr != -1U) 388 if (sun_pci_dma_current.addr != -1U)
397 pci_unmap_single(sun_pci_ebus_dev, 389 dma_unmap_single(sun_floppy_dev,
398 sun_pci_dma_current.addr, 390 sun_pci_dma_current.addr,
399 sun_pci_dma_current.len, 391 sun_pci_dma_current.len,
400 sun_pci_dma_current.direction); 392 sun_pci_dma_current.direction);
@@ -404,9 +396,9 @@ static void sun_pci_fd_disable_dma(void)
404static void sun_pci_fd_set_dma_mode(int mode) 396static void sun_pci_fd_set_dma_mode(int mode)
405{ 397{
406 if (mode == DMA_MODE_WRITE) 398 if (mode == DMA_MODE_WRITE)
407 sun_pci_dma_pending.direction = PCI_DMA_TODEVICE; 399 sun_pci_dma_pending.direction = DMA_TO_DEVICE;
408 else 400 else
409 sun_pci_dma_pending.direction = PCI_DMA_FROMDEVICE; 401 sun_pci_dma_pending.direction = DMA_FROM_DEVICE;
410 402
411 ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE); 403 ebus_dma_prepare(&sun_pci_fd_ebus_dma, mode != DMA_MODE_WRITE);
412} 404}
@@ -538,80 +530,84 @@ static int sun_pci_fd_test_drive(unsigned long port, int drive)
538#undef MSR 530#undef MSR
539#undef DOR 531#undef DOR
540 532
541#endif /* CONFIG_PCI */ 533static int __init ebus_fdthree_p(struct device_node *dp)
542
543#ifdef CONFIG_PCI
544static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
545{ 534{
546 if (!strcmp(edev->prom_node->name, "fdthree")) 535 if (!strcmp(dp->name, "fdthree"))
547 return 1; 536 return 1;
548 if (!strcmp(edev->prom_node->name, "floppy")) { 537 if (!strcmp(dp->name, "floppy")) {
549 const char *compat; 538 const char *compat;
550 539
551 compat = of_get_property(edev->prom_node, 540 compat = of_get_property(dp, "compatible", NULL);
552 "compatible", NULL);
553 if (compat && !strcmp(compat, "fdthree")) 541 if (compat && !strcmp(compat, "fdthree"))
554 return 1; 542 return 1;
555 } 543 }
556 return 0; 544 return 0;
557} 545}
558#endif
559 546
560static unsigned long __init sun_floppy_init(void) 547static unsigned long __init sun_floppy_init(void)
561{ 548{
562 char state[128];
563 struct sbus_bus *bus;
564 struct sbus_dev *sdev = NULL;
565 static int initialized = 0; 549 static int initialized = 0;
550 struct device_node *dp;
551 struct of_device *op;
552 const char *prop;
553 char state[128];
566 554
567 if (initialized) 555 if (initialized)
568 return sun_floppy_types[0]; 556 return sun_floppy_types[0];
569 initialized = 1; 557 initialized = 1;
570 558
571 for_all_sbusdev (sdev, bus) { 559 op = NULL;
572 if (!strcmp(sdev->prom_name, "SUNW,fdtwo")) 560
561 for_each_node_by_name(dp, "SUNW,fdtwo") {
562 if (strcmp(dp->parent->name, "sbus"))
563 continue;
564 op = of_find_device_by_node(dp);
565 if (op)
573 break; 566 break;
574 } 567 }
575 if(sdev) { 568 if (op) {
576 floppy_sdev = sdev; 569 floppy_op = op;
577 FLOPPY_IRQ = sdev->irqs[0]; 570 FLOPPY_IRQ = op->irqs[0];
578 } else { 571 } else {
579#ifdef CONFIG_PCI 572 struct device_node *ebus_dp;
580 struct linux_ebus *ebus;
581 struct linux_ebus_device *edev = NULL;
582 unsigned long config = 0;
583 void __iomem *auxio_reg; 573 void __iomem *auxio_reg;
584 const char *state_prop; 574 const char *state_prop;
575 unsigned long config;
585 576
586 for_each_ebus(ebus) { 577 dp = NULL;
587 for_each_ebusdev(edev, ebus) { 578 for_each_node_by_name(ebus_dp, "ebus") {
588 if (ebus_fdthree_p(edev)) 579 for (dp = ebus_dp->child; dp; dp = dp->sibling) {
589 goto ebus_done; 580 if (ebus_fdthree_p(dp))
581 goto found_fdthree;
590 } 582 }
591 } 583 }
592 ebus_done: 584 found_fdthree:
593 if (!edev) 585 if (!dp)
586 return 0;
587
588 op = of_find_device_by_node(dp);
589 if (!op)
594 return 0; 590 return 0;
595 591
596 state_prop = of_get_property(edev->prom_node, "status", NULL); 592 state_prop = of_get_property(op->node, "status", NULL);
597 if (state_prop && !strncmp(state_prop, "disabled", 8)) 593 if (state_prop && !strncmp(state_prop, "disabled", 8))
598 return 0; 594 return 0;
599 595
600 FLOPPY_IRQ = edev->irqs[0]; 596 FLOPPY_IRQ = op->irqs[0];
601 597
602 /* Make sure the high density bit is set, some systems 598 /* Make sure the high density bit is set, some systems
603 * (most notably Ultra5/Ultra10) come up with it clear. 599 * (most notably Ultra5/Ultra10) come up with it clear.
604 */ 600 */
605 auxio_reg = (void __iomem *) edev->resource[2].start; 601 auxio_reg = (void __iomem *) op->resource[2].start;
606 writel(readl(auxio_reg)|0x2, auxio_reg); 602 writel(readl(auxio_reg)|0x2, auxio_reg);
607 603
608 sun_pci_ebus_dev = ebus->self; 604 sun_floppy_dev = &op->dev;
609 605
610 spin_lock_init(&sun_pci_fd_ebus_dma.lock); 606 spin_lock_init(&sun_pci_fd_ebus_dma.lock);
611 607
612 /* XXX ioremap */ 608 /* XXX ioremap */
613 sun_pci_fd_ebus_dma.regs = (void __iomem *) 609 sun_pci_fd_ebus_dma.regs = (void __iomem *)
614 edev->resource[1].start; 610 op->resource[1].start;
615 if (!sun_pci_fd_ebus_dma.regs) 611 if (!sun_pci_fd_ebus_dma.regs)
616 return 0; 612 return 0;
617 613
@@ -625,7 +621,7 @@ static unsigned long __init sun_floppy_init(void)
625 return 0; 621 return 0;
626 622
627 /* XXX ioremap */ 623 /* XXX ioremap */
628 sun_fdc = (struct sun_flpy_controller *)edev->resource[0].start; 624 sun_fdc = (struct sun_flpy_controller *) op->resource[0].start;
629 625
630 sun_fdops.fd_inb = sun_pci_fd_inb; 626 sun_fdops.fd_inb = sun_pci_fd_inb;
631 sun_fdops.fd_outb = sun_pci_fd_outb; 627 sun_fdops.fd_outb = sun_pci_fd_outb;
@@ -662,12 +658,15 @@ static unsigned long __init sun_floppy_init(void)
662 /* 658 /*
663 * Find NS87303 SuperIO config registers (through ecpp). 659 * Find NS87303 SuperIO config registers (through ecpp).
664 */ 660 */
665 for_each_ebus(ebus) { 661 config = 0;
666 for_each_ebusdev(edev, ebus) { 662 for (dp = ebus_dp->child; dp; dp = dp->sibling) {
667 if (!strcmp(edev->prom_node->name, "ecpp")) { 663 if (!strcmp(dp->name, "ecpp")) {
668 config = edev->resource[1].start; 664 struct of_device *ecpp_op;
669 goto config_done; 665
670 } 666 ecpp_op = of_find_device_by_node(dp);
667 if (ecpp_op)
668 config = ecpp_op->resource[1].start;
669 goto config_done;
671 } 670 }
672 } 671 }
673 config_done: 672 config_done:
@@ -716,26 +715,23 @@ static unsigned long __init sun_floppy_init(void)
716#endif /* PCI_FDC_SWAP_DRIVES */ 715#endif /* PCI_FDC_SWAP_DRIVES */
717 716
718 return sun_floppy_types[0]; 717 return sun_floppy_types[0];
719#else
720 return 0;
721#endif
722 } 718 }
723 prom_getproperty(sdev->prom_node, "status", state, sizeof(state)); 719 prop = of_get_property(op->node, "status", NULL);
724 if(!strncmp(state, "disabled", 8)) 720 if (prop && !strncmp(state, "disabled", 8))
725 return 0; 721 return 0;
726 722
727 /* 723 /*
728 * We cannot do sbus_ioremap here: it does request_region, 724 * We cannot do of_ioremap here: it does request_region,
729 * which the generic floppy driver tries to do once again. 725 * which the generic floppy driver tries to do once again.
730 * But we must use the sdev resource values as they have 726 * But we must use the sdev resource values as they have
731 * had parent ranges applied. 727 * had parent ranges applied.
732 */ 728 */
733 sun_fdc = (struct sun_flpy_controller *) 729 sun_fdc = (struct sun_flpy_controller *)
734 (sdev->resource[0].start + 730 (op->resource[0].start +
735 ((sdev->resource[0].flags & 0x1ffUL) << 32UL)); 731 ((op->resource[0].flags & 0x1ffUL) << 32UL));
736 732
737 /* Last minute sanity check... */ 733 /* Last minute sanity check... */
738 if(sbus_readb(&sun_fdc->status1_82077) == 0xff) { 734 if (sbus_readb(&sun_fdc->status1_82077) == 0xff) {
739 sun_fdc = (struct sun_flpy_controller *)-1; 735 sun_fdc = (struct sun_flpy_controller *)-1;
740 return 0; 736 return 0;
741 } 737 }
diff --git a/arch/sparc/include/asm/gpio.h b/arch/sparc/include/asm/gpio.h
new file mode 100644
index 000000000000..a0e3ac0af599
--- /dev/null
+++ b/arch/sparc/include/asm/gpio.h
@@ -0,0 +1,36 @@
1#ifndef __ASM_SPARC_GPIO_H
2#define __ASM_SPARC_GPIO_H
3
4#include <linux/errno.h>
5#include <asm-generic/gpio.h>
6
7#ifdef CONFIG_GPIOLIB
8
9static inline int gpio_get_value(unsigned int gpio)
10{
11 return __gpio_get_value(gpio);
12}
13
14static inline void gpio_set_value(unsigned int gpio, int value)
15{
16 __gpio_set_value(gpio, value);
17}
18
19static inline int gpio_cansleep(unsigned int gpio)
20{
21 return __gpio_cansleep(gpio);
22}
23
24static inline int gpio_to_irq(unsigned int gpio)
25{
26 return -ENOSYS;
27}
28
29static inline int irq_to_gpio(unsigned int irq)
30{
31 return -EINVAL;
32}
33
34#endif /* CONFIG_GPIOLIB */
35
36#endif /* __ASM_SPARC_GPIO_H */
diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h
index 96823b47fd45..01ab2f613e91 100644
--- a/arch/sparc/include/asm/io-unit.h
+++ b/arch/sparc/include/asm/io-unit.h
@@ -55,8 +55,4 @@ struct iounit_struct {
55#define IOUNIT_BMAPM_START IOUNIT_BMAP2_END 55#define IOUNIT_BMAPM_START IOUNIT_BMAP2_END
56#define IOUNIT_BMAPM_END ((IOUNIT_DMA_SIZE - IOUNIT_DVMA_SIZE) >> PAGE_SHIFT) 56#define IOUNIT_BMAPM_END ((IOUNIT_DMA_SIZE - IOUNIT_DVMA_SIZE) >> PAGE_SHIFT)
57 57
58extern __u32 iounit_map_dma_init(struct sbus_bus *, int);
59#define iounit_map_dma_finish(sbus, addr, len) mmu_release_scsi_one(addr, len, sbus)
60extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *);
61
62#endif /* !(_SPARC_IO_UNIT_H) */ 58#endif /* !(_SPARC_IO_UNIT_H) */
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 10d7da450070..93fe21e02c86 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -293,14 +293,6 @@ extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
293extern void pci_iounmap(struct pci_dev *dev, void __iomem *); 293extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
294 294
295/* 295/*
296 * Bus number may be in res->flags... somewhere.
297 */
298extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset,
299 unsigned long size, char *name);
300extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
301
302
303/*
304 * At the moment, we do not use CMOS_READ anywhere outside of rtc.c, 296 * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
305 * so rtc_port is static in it. This should not change unless a new 297 * so rtc_port is static in it. This should not change unless a new
306 * hardware pops up. 298 * hardware pops up.
@@ -308,6 +300,17 @@ extern void sbus_iounmap(volatile void __iomem *vaddr, unsigned long size);
308#define RTC_PORT(x) (rtc_port + (x)) 300#define RTC_PORT(x) (rtc_port + (x))
309#define RTC_ALWAYS_BCD 0 301#define RTC_ALWAYS_BCD 0
310 302
303static inline int sbus_can_dma_64bit(void)
304{
305 return 0; /* actually, sparc_cpu_model==sun4d */
306}
307static inline int sbus_can_burst64(void)
308{
309 return 0; /* actually, sparc_cpu_model==sun4d */
310}
311struct device;
312extern void sbus_set_sbus64(struct device *, int);
313
311#endif 314#endif
312 315
313#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1 316#define __ARCH_HAS_NO_PAGE_ZERO_MAPPED 1
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index 0bff078ffdd0..4aee21dc9c6f 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -482,18 +482,16 @@ struct pci_dev;
482extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); 482extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
483extern void pci_iounmap(struct pci_dev *dev, void __iomem *); 483extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
484 484
485/* Similarly for SBUS. */ 485static inline int sbus_can_dma_64bit(void)
486#define sbus_ioremap(__res, __offset, __size, __name) \ 486{
487({ unsigned long __ret; \ 487 return 1;
488 __ret = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \ 488}
489 __ret += (unsigned long) (__offset); \ 489static inline int sbus_can_burst64(void)
490 if (! request_region((__ret), (__size), (__name))) \ 490{
491 __ret = 0UL; \ 491 return 1;
492 (void __iomem *) __ret; \ 492}
493}) 493struct device;
494 494extern void sbus_set_sbus64(struct device *, int);
495#define sbus_iounmap(__addr, __size) \
496 release_region((unsigned long)(__addr), (__size))
497 495
498/* 496/*
499 * Convert a physical pointer to a virtual kernel pointer for /dev/mem 497 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/sparc/include/asm/iommu_64.h b/arch/sparc/include/asm/iommu_64.h
index d7b9afcba08b..caf798b56191 100644
--- a/arch/sparc/include/asm/iommu_64.h
+++ b/arch/sparc/include/asm/iommu_64.h
@@ -48,6 +48,9 @@ struct strbuf {
48 unsigned long strbuf_control; 48 unsigned long strbuf_control;
49 unsigned long strbuf_pflush; 49 unsigned long strbuf_pflush;
50 unsigned long strbuf_fsync; 50 unsigned long strbuf_fsync;
51 unsigned long strbuf_err_stat;
52 unsigned long strbuf_tag_diag;
53 unsigned long strbuf_line_diag;
51 unsigned long strbuf_ctxflush; 54 unsigned long strbuf_ctxflush;
52 unsigned long strbuf_ctxmatch_base; 55 unsigned long strbuf_ctxmatch_base;
53 unsigned long strbuf_flushflag_pa; 56 unsigned long strbuf_flushflag_pa;
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h
index e3dd9303643d..71673eca3660 100644
--- a/arch/sparc/include/asm/irq_64.h
+++ b/arch/sparc/include/asm/irq_64.h
@@ -56,7 +56,6 @@ extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p,
56 unsigned long imap_base, 56 unsigned long imap_base,
57 unsigned long iclr_base); 57 unsigned long iclr_base);
58extern void sun4u_destroy_msi(unsigned int virt_irq); 58extern void sun4u_destroy_msi(unsigned int virt_irq);
59extern unsigned int sbus_build_irq(void *sbus, unsigned int ino);
60 59
61extern unsigned char virt_irq_alloc(unsigned int dev_handle, 60extern unsigned char virt_irq_alloc(unsigned int dev_handle,
62 unsigned int dev_ino); 61 unsigned int dev_ino);
diff --git a/arch/sparc/include/asm/mc146818rtc_64.h b/arch/sparc/include/asm/mc146818rtc_64.h
index e9c0fcc25c6f..7238d174e0e3 100644
--- a/arch/sparc/include/asm/mc146818rtc_64.h
+++ b/arch/sparc/include/asm/mc146818rtc_64.h
@@ -7,12 +7,8 @@
7#include <asm/io.h> 7#include <asm/io.h>
8 8
9#ifndef RTC_PORT 9#ifndef RTC_PORT
10#ifdef CONFIG_PCI 10extern unsigned long cmos_regs;
11extern unsigned long ds1287_regs; 11#define RTC_PORT(x) (cmos_regs + (x))
12#else
13#define ds1287_regs (0UL)
14#endif
15#define RTC_PORT(x) (ds1287_regs + (x))
16#define RTC_ALWAYS_BCD 0 12#define RTC_ALWAYS_BCD 0
17#endif 13#endif
18 14
@@ -29,6 +25,4 @@ outb_p((addr),RTC_PORT(0)); \
29outb_p((val),RTC_PORT(1)); \ 25outb_p((val),RTC_PORT(1)); \
30}) 26})
31 27
32#define RTC_IRQ 8
33
34#endif /* __ASM_SPARC64_MC146818RTC_H */ 28#endif /* __ASM_SPARC64_MC146818RTC_H */
diff --git a/arch/sparc/include/asm/memctrl.h b/arch/sparc/include/asm/memctrl.h
new file mode 100644
index 000000000000..4065c56af7b6
--- /dev/null
+++ b/arch/sparc/include/asm/memctrl.h
@@ -0,0 +1,9 @@
1#ifndef _SPARC_MEMCTRL_H
2#define _SPARC_MEMCTRL_H
3
4typedef int (*dimm_printer_t)(int synd_code, unsigned long paddr, char *buf, int buflen);
5
6int register_dimm_printer(dimm_printer_t func);
7void unregister_dimm_printer(dimm_printer_t func);
8
9#endif /* _SPARC_MEMCTRL_H */
diff --git a/arch/sparc/include/asm/mostek.h b/arch/sparc/include/asm/mostek.h
deleted file mode 100644
index 433be3e0a69b..000000000000
--- a/arch/sparc/include/asm/mostek.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef ___ASM_SPARC_MOSTEK_H
2#define ___ASM_SPARC_MOSTEK_H
3#if defined(__sparc__) && defined(__arch64__)
4#include <asm/mostek_64.h>
5#else
6#include <asm/mostek_32.h>
7#endif
8#endif
diff --git a/arch/sparc/include/asm/mostek_32.h b/arch/sparc/include/asm/mostek_32.h
deleted file mode 100644
index a99590c4c507..000000000000
--- a/arch/sparc/include/asm/mostek_32.h
+++ /dev/null
@@ -1,171 +0,0 @@
1/*
2 * mostek.h: Describes the various Mostek time of day clock registers.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
6 * Added intersil code 05/25/98 Chris Davis (cdavis@cois.on.ca)
7 */
8
9#ifndef _SPARC_MOSTEK_H
10#define _SPARC_MOSTEK_H
11
12#include <asm/idprom.h>
13#include <asm/io.h>
14
15/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
16 *
17 * Data
18 * Address Function
19 * Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
20 * 7ff - - - - - - - - Year 00-99
21 * 7fe 0 0 0 - - - - - Month 01-12
22 * 7fd 0 0 - - - - - - Date 01-31
23 * 7fc 0 FT 0 0 0 - - - Day 01-07
24 * 7fb KS 0 - - - - - - Hours 00-23
25 * 7fa 0 - - - - - - - Minutes 00-59
26 * 7f9 ST - - - - - - - Seconds 00-59
27 * 7f8 W R S - - - - - Control
28 *
29 * * ST is STOP BIT
30 * * W is WRITE BIT
31 * * R is READ BIT
32 * * S is SIGN BIT
33 * * FT is FREQ TEST BIT
34 * * KS is KICK START BIT
35 */
36
37/* The Mostek 48t02 real time clock and NVRAM chip. The registers
38 * other than the control register are in binary coded decimal. Some
39 * control bits also live outside the control register.
40 */
41#define mostek_read(_addr) readb(_addr)
42#define mostek_write(_addr,_val) writeb(_val, _addr)
43#define MOSTEK_EEPROM 0x0000UL
44#define MOSTEK_IDPROM 0x07d8UL
45#define MOSTEK_CREG 0x07f8UL
46#define MOSTEK_SEC 0x07f9UL
47#define MOSTEK_MIN 0x07faUL
48#define MOSTEK_HOUR 0x07fbUL
49#define MOSTEK_DOW 0x07fcUL
50#define MOSTEK_DOM 0x07fdUL
51#define MOSTEK_MONTH 0x07feUL
52#define MOSTEK_YEAR 0x07ffUL
53
54struct mostek48t02 {
55 volatile char eeprom[2008]; /* This is the eeprom, don't touch! */
56 struct idprom idprom; /* The idprom lives here. */
57 volatile unsigned char creg; /* Control register */
58 volatile unsigned char sec; /* Seconds (0-59) */
59 volatile unsigned char min; /* Minutes (0-59) */
60 volatile unsigned char hour; /* Hour (0-23) */
61 volatile unsigned char dow; /* Day of the week (1-7) */
62 volatile unsigned char dom; /* Day of the month (1-31) */
63 volatile unsigned char month; /* Month of year (1-12) */
64 volatile unsigned char year; /* Year (0-99) */
65};
66
67extern spinlock_t mostek_lock;
68extern void __iomem *mstk48t02_regs;
69
70/* Control register values. */
71#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */
72#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */
73#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */
74
75/* Control bits that live in the other registers. */
76#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */
77#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */
78#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */
79
80#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */
81#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO)
82
83/* Masks that define how much space each value takes up. */
84#define MSTK_SEC_MASK 0x7f
85#define MSTK_MIN_MASK 0x7f
86#define MSTK_HOUR_MASK 0x3f
87#define MSTK_DOW_MASK 0x07
88#define MSTK_DOM_MASK 0x3f
89#define MSTK_MONTH_MASK 0x1f
90#define MSTK_YEAR_MASK 0xffU
91
92/* Binary coded decimal conversion macros. */
93#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
94#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
95
96/* Generic register set and get macros for internal use. */
97#define MSTK_GET(regs,var,mask) (MSTK_REGVAL_TO_DECIMAL(((struct mostek48t02 *)regs)->var & MSTK_ ## mask ## _MASK))
98#define MSTK_SET(regs,var,value,mask) do { ((struct mostek48t02 *)regs)->var &= ~(MSTK_ ## mask ## _MASK); ((struct mostek48t02 *)regs)->var |= MSTK_DECIMAL_TO_REGVAL(value) & (MSTK_ ## mask ## _MASK); } while (0)
99
100/* Macros to make register access easier on our fingers. These give you
101 * the decimal value of the register requested if applicable. You pass
102 * the a pointer to a 'struct mostek48t02'.
103 */
104#define MSTK_REG_CREG(regs) (((struct mostek48t02 *)regs)->creg)
105#define MSTK_REG_SEC(regs) MSTK_GET(regs,sec,SEC)
106#define MSTK_REG_MIN(regs) MSTK_GET(regs,min,MIN)
107#define MSTK_REG_HOUR(regs) MSTK_GET(regs,hour,HOUR)
108#define MSTK_REG_DOW(regs) MSTK_GET(regs,dow,DOW)
109#define MSTK_REG_DOM(regs) MSTK_GET(regs,dom,DOM)
110#define MSTK_REG_MONTH(regs) MSTK_GET(regs,month,MONTH)
111#define MSTK_REG_YEAR(regs) MSTK_GET(regs,year,YEAR)
112
113#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,sec,value,SEC)
114#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,min,value,MIN)
115#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,hour,value,HOUR)
116#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,dow,value,DOW)
117#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,dom,value,DOM)
118#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,month,value,MONTH)
119#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,year,value,YEAR)
120
121
122/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
123 * same (basically) layout of the 48t02 chip except for the extra
124 * NVRAM on board (8 KB against the 48t02's 2 KB).
125 */
126struct mostek48t08 {
127 char offset[6*1024]; /* Magic things may be here, who knows? */
128 struct mostek48t02 regs; /* Here is what we are interested in. */
129};
130
131#ifdef CONFIG_SUN4
132enum sparc_clock_type { MSTK48T02, MSTK48T08, \
133INTERSIL, MSTK_INVALID };
134#else
135enum sparc_clock_type { MSTK48T02, MSTK48T08, \
136MSTK_INVALID };
137#endif
138
139#ifdef CONFIG_SUN4
140/* intersil on a sun 4/260 code data from harris doc */
141struct intersil_dt {
142 volatile unsigned char int_csec;
143 volatile unsigned char int_hour;
144 volatile unsigned char int_min;
145 volatile unsigned char int_sec;
146 volatile unsigned char int_month;
147 volatile unsigned char int_day;
148 volatile unsigned char int_year;
149 volatile unsigned char int_dow;
150};
151
152struct intersil {
153 struct intersil_dt clk;
154 struct intersil_dt cmp;
155 volatile unsigned char int_intr_reg;
156 volatile unsigned char int_cmd_reg;
157};
158
159#define INTERSIL_STOP 0x0
160#define INTERSIL_START 0x8
161#define INTERSIL_INTR_DISABLE 0x0
162#define INTERSIL_INTR_ENABLE 0x10
163#define INTERSIL_32K 0x0
164#define INTERSIL_NORMAL 0x0
165#define INTERSIL_24H 0x4
166#define INTERSIL_INT_100HZ 0x2
167
168/* end of intersil info */
169#endif
170
171#endif /* !(_SPARC_MOSTEK_H) */
diff --git a/arch/sparc/include/asm/mostek_64.h b/arch/sparc/include/asm/mostek_64.h
deleted file mode 100644
index c5652de2ace2..000000000000
--- a/arch/sparc/include/asm/mostek_64.h
+++ /dev/null
@@ -1,143 +0,0 @@
1/* mostek.h: Describes the various Mostek time of day clock registers.
2 *
3 * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
4 * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
5 */
6
7#ifndef _SPARC64_MOSTEK_H
8#define _SPARC64_MOSTEK_H
9
10#include <asm/idprom.h>
11
12/* M48T02 Register Map (adapted from Sun NVRAM/Hostid FAQ)
13 *
14 * Data
15 * Address Function
16 * Bit 7 Bit 6 Bit 5 Bit 4Bit 3 Bit 2 Bit 1 Bit 0
17 * 7ff - - - - - - - - Year 00-99
18 * 7fe 0 0 0 - - - - - Month 01-12
19 * 7fd 0 0 - - - - - - Date 01-31
20 * 7fc 0 FT 0 0 0 - - - Day 01-07
21 * 7fb KS 0 - - - - - - Hours 00-23
22 * 7fa 0 - - - - - - - Minutes 00-59
23 * 7f9 ST - - - - - - - Seconds 00-59
24 * 7f8 W R S - - - - - Control
25 *
26 * * ST is STOP BIT
27 * * W is WRITE BIT
28 * * R is READ BIT
29 * * S is SIGN BIT
30 * * FT is FREQ TEST BIT
31 * * KS is KICK START BIT
32 */
33
34/* The Mostek 48t02 real time clock and NVRAM chip. The registers
35 * other than the control register are in binary coded decimal. Some
36 * control bits also live outside the control register.
37 *
38 * We now deal with physical addresses for I/O to the chip. -DaveM
39 */
40static inline u8 mostek_read(void __iomem *addr)
41{
42 u8 ret;
43
44 __asm__ __volatile__("lduba [%1] %2, %0"
45 : "=r" (ret)
46 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
47 return ret;
48}
49
50static inline void mostek_write(void __iomem *addr, u8 val)
51{
52 __asm__ __volatile__("stba %0, [%1] %2"
53 : /* no outputs */
54 : "r" (val), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
55}
56
57#define MOSTEK_EEPROM 0x0000UL
58#define MOSTEK_IDPROM 0x07d8UL
59#define MOSTEK_CREG 0x07f8UL
60#define MOSTEK_SEC 0x07f9UL
61#define MOSTEK_MIN 0x07faUL
62#define MOSTEK_HOUR 0x07fbUL
63#define MOSTEK_DOW 0x07fcUL
64#define MOSTEK_DOM 0x07fdUL
65#define MOSTEK_MONTH 0x07feUL
66#define MOSTEK_YEAR 0x07ffUL
67
68extern spinlock_t mostek_lock;
69extern void __iomem *mstk48t02_regs;
70
71/* Control register values. */
72#define MSTK_CREG_WRITE 0x80 /* Must set this before placing values. */
73#define MSTK_CREG_READ 0x40 /* Stop updates to allow a clean read. */
74#define MSTK_CREG_SIGN 0x20 /* Slow/speed clock in calibration mode. */
75
76/* Control bits that live in the other registers. */
77#define MSTK_STOP 0x80 /* Stop the clock oscillator. (sec) */
78#define MSTK_KICK_START 0x80 /* Kick start the clock chip. (hour) */
79#define MSTK_FREQ_TEST 0x40 /* Frequency test mode. (day) */
80
81#define MSTK_YEAR_ZERO 1968 /* If year reg has zero, it is 1968. */
82#define MSTK_CVT_YEAR(yr) ((yr) + MSTK_YEAR_ZERO)
83
84/* Masks that define how much space each value takes up. */
85#define MSTK_SEC_MASK 0x7f
86#define MSTK_MIN_MASK 0x7f
87#define MSTK_HOUR_MASK 0x3f
88#define MSTK_DOW_MASK 0x07
89#define MSTK_DOM_MASK 0x3f
90#define MSTK_MONTH_MASK 0x1f
91#define MSTK_YEAR_MASK 0xffU
92
93/* Binary coded decimal conversion macros. */
94#define MSTK_REGVAL_TO_DECIMAL(x) (((x) & 0x0F) + 0x0A * ((x) >> 0x04))
95#define MSTK_DECIMAL_TO_REGVAL(x) ((((x) / 0x0A) << 0x04) + ((x) % 0x0A))
96
97/* Generic register set and get macros for internal use. */
98#define MSTK_GET(regs,name) \
99 (MSTK_REGVAL_TO_DECIMAL(mostek_read(regs + MOSTEK_ ## name) & MSTK_ ## name ## _MASK))
100#define MSTK_SET(regs,name,value) \
101do { u8 __val = mostek_read(regs + MOSTEK_ ## name); \
102 __val &= ~(MSTK_ ## name ## _MASK); \
103 __val |= (MSTK_DECIMAL_TO_REGVAL(value) & \
104 (MSTK_ ## name ## _MASK)); \
105 mostek_write(regs + MOSTEK_ ## name, __val); \
106} while(0)
107
108/* Macros to make register access easier on our fingers. These give you
109 * the decimal value of the register requested if applicable. You pass
110 * the a pointer to a 'struct mostek48t02'.
111 */
112#define MSTK_REG_CREG(regs) (mostek_read((regs) + MOSTEK_CREG))
113#define MSTK_REG_SEC(regs) MSTK_GET(regs,SEC)
114#define MSTK_REG_MIN(regs) MSTK_GET(regs,MIN)
115#define MSTK_REG_HOUR(regs) MSTK_GET(regs,HOUR)
116#define MSTK_REG_DOW(regs) MSTK_GET(regs,DOW)
117#define MSTK_REG_DOM(regs) MSTK_GET(regs,DOM)
118#define MSTK_REG_MONTH(regs) MSTK_GET(regs,MONTH)
119#define MSTK_REG_YEAR(regs) MSTK_GET(regs,YEAR)
120
121#define MSTK_SET_REG_SEC(regs,value) MSTK_SET(regs,SEC,value)
122#define MSTK_SET_REG_MIN(regs,value) MSTK_SET(regs,MIN,value)
123#define MSTK_SET_REG_HOUR(regs,value) MSTK_SET(regs,HOUR,value)
124#define MSTK_SET_REG_DOW(regs,value) MSTK_SET(regs,DOW,value)
125#define MSTK_SET_REG_DOM(regs,value) MSTK_SET(regs,DOM,value)
126#define MSTK_SET_REG_MONTH(regs,value) MSTK_SET(regs,MONTH,value)
127#define MSTK_SET_REG_YEAR(regs,value) MSTK_SET(regs,YEAR,value)
128
129
130/* The Mostek 48t08 clock chip. Found on Sun4m's I think. It has the
131 * same (basically) layout of the 48t02 chip except for the extra
132 * NVRAM on board (8 KB against the 48t02's 2 KB).
133 */
134#define MOSTEK_48T08_OFFSET 0x0000UL /* Lower NVRAM portions */
135#define MOSTEK_48T08_48T02 0x1800UL /* Offset to 48T02 chip */
136
137/* SUN5 systems usually have 48t59 model clock chipsets. But we keep the older
138 * clock chip definitions around just in case.
139 */
140#define MOSTEK_48T59_OFFSET 0x0000UL /* Lower NVRAM portions */
141#define MOSTEK_48T59_48T02 0x1800UL /* Offset to 48T02 chip */
142
143#endif /* !(_SPARC64_MOSTEK_H) */
diff --git a/arch/sparc/include/asm/obio.h b/arch/sparc/include/asm/obio.h
index 1a7544ceb574..4ade0c8a2c79 100644
--- a/arch/sparc/include/asm/obio.h
+++ b/arch/sparc/include/asm/obio.h
@@ -155,17 +155,6 @@ static inline void bw_set_ctrl(int cpu, unsigned ctrl)
155 "i" (ASI_M_CTL)); 155 "i" (ASI_M_CTL));
156} 156}
157 157
158extern unsigned char cpu_leds[32];
159
160static inline void show_leds(int cpuid)
161{
162 cpuid &= 0x1e;
163 __asm__ __volatile__ ("stba %0, [%1] %2" : :
164 "r" ((cpu_leds[cpuid] << 4) | cpu_leds[cpuid+1]),
165 "r" (ECSR_BASE(cpuid) | BB_LEDS),
166 "i" (ASI_M_CTL));
167}
168
169static inline unsigned cc_get_ipen(void) 158static inline unsigned cc_get_ipen(void)
170{ 159{
171 unsigned pending; 160 unsigned pending;
diff --git a/arch/sparc/include/asm/of_device.h b/arch/sparc/include/asm/of_device.h
index bba777a416d3..a5d9811f9697 100644
--- a/arch/sparc/include/asm/of_device.h
+++ b/arch/sparc/include/asm/of_device.h
@@ -30,6 +30,8 @@ struct of_device
30extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); 30extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
31extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); 31extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
32 32
33extern void of_propagate_archdata(struct of_device *bus);
34
33/* This is just here during the transition */ 35/* This is just here during the transition */
34#include <linux/of_platform.h> 36#include <linux/of_platform.h>
35 37
diff --git a/arch/sparc/include/asm/of_platform.h b/arch/sparc/include/asm/of_platform.h
index 2348ab90a57c..90da99059f83 100644
--- a/arch/sparc/include/asm/of_platform.h
+++ b/arch/sparc/include/asm/of_platform.h
@@ -13,9 +13,6 @@
13 * 13 *
14 */ 14 */
15 15
16extern struct bus_type ebus_bus_type;
17extern struct bus_type sbus_bus_type;
18
19#define of_bus_type of_platform_bus_type /* for compatibility */ 16#define of_bus_type of_platform_bus_type /* for compatibility */
20 17
21#endif 18#endif
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index b2631da259e0..699da05235c8 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -21,7 +21,6 @@ enum prom_major_version {
21 PROM_V2, /* sun4c and early sun4m V2 prom */ 21 PROM_V2, /* sun4c and early sun4m V2 prom */
22 PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */ 22 PROM_V3, /* sun4m and later, up to sun4d/sun4e machines V3 */
23 PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */ 23 PROM_P1275, /* IEEE compliant ISA based Sun PROM, only sun4u */
24 PROM_SUN4, /* Old sun4 proms are totally different, but we'll shoehorn it to make it fit */
25}; 24};
26 25
27extern enum prom_major_version prom_vers; 26extern enum prom_major_version prom_vers;
diff --git a/arch/sparc/include/asm/page_32.h b/arch/sparc/include/asm/page_32.h
index cf5fb70ca1c1..d1806edc0958 100644
--- a/arch/sparc/include/asm/page_32.h
+++ b/arch/sparc/include/asm/page_32.h
@@ -8,11 +8,8 @@
8#ifndef _SPARC_PAGE_H 8#ifndef _SPARC_PAGE_H
9#define _SPARC_PAGE_H 9#define _SPARC_PAGE_H
10 10
11#ifdef CONFIG_SUN4
12#define PAGE_SHIFT 13
13#else
14#define PAGE_SHIFT 12 11#define PAGE_SHIFT 12
15#endif 12
16#ifndef __ASSEMBLY__ 13#ifndef __ASSEMBLY__
17/* I have my suspicions... -DaveM */ 14/* I have my suspicions... -DaveM */
18#define PAGE_SIZE (1UL << PAGE_SHIFT) 15#define PAGE_SIZE (1UL << PAGE_SHIFT)
diff --git a/arch/sparc/include/asm/page_64.h b/arch/sparc/include/asm/page_64.h
index b579b910ef51..4274ed13ddb2 100644
--- a/arch/sparc/include/asm/page_64.h
+++ b/arch/sparc/include/asm/page_64.h
@@ -38,6 +38,8 @@
38 38
39#ifndef __ASSEMBLY__ 39#ifndef __ASSEMBLY__
40 40
41#define WANT_PAGE_VIRTUAL
42
41extern void _clear_page(void *page); 43extern void _clear_page(void *page);
42#define clear_page(X) _clear_page((void *)(X)) 44#define clear_page(X) _clear_page((void *)(X))
43struct page; 45struct page;
diff --git a/arch/sparc/include/asm/parport.h b/arch/sparc/include/asm/parport.h
index d9830621c906..dff3f0253aa8 100644
--- a/arch/sparc/include/asm/parport.h
+++ b/arch/sparc/include/asm/parport.h
@@ -8,7 +8,7 @@
8 8
9#include <linux/of_device.h> 9#include <linux/of_device.h>
10 10
11#include <asm/ebus.h> 11#include <asm/ebus_dma.h>
12#include <asm/ns87303.h> 12#include <asm/ns87303.h>
13#include <asm/prom.h> 13#include <asm/prom.h>
14 14
@@ -215,7 +215,7 @@ static int __devexit ecpp_remove(struct of_device *op)
215 return 0; 215 return 0;
216} 216}
217 217
218static struct of_device_id ecpp_match[] = { 218static const struct of_device_id ecpp_match[] = {
219 { 219 {
220 .name = "ecpp", 220 .name = "ecpp",
221 }, 221 },
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h
index 0ee949d220c0..b41c4c198159 100644
--- a/arch/sparc/include/asm/pci_32.h
+++ b/arch/sparc/include/asm/pci_32.h
@@ -3,6 +3,8 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/dma-mapping.h>
7
6/* Can be used to override the logic in pci_scan_bus for skipping 8/* Can be used to override the logic in pci_scan_bus for skipping
7 * already-configured bus numbers - to be used for buggy BIOSes 9 * already-configured bus numbers - to be used for buggy BIOSes
8 * or architectures with incomplete PCI setup by the loader. 10 * or architectures with incomplete PCI setup by the loader.
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 08237fda8874..e0cabe790ec1 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -14,11 +14,7 @@
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/swap.h> 15#include <linux/swap.h>
16#include <asm/types.h> 16#include <asm/types.h>
17#ifdef CONFIG_SUN4
18#include <asm/pgtsun4.h>
19#else
20#include <asm/pgtsun4c.h> 17#include <asm/pgtsun4c.h>
21#endif
22#include <asm/pgtsrmmu.h> 18#include <asm/pgtsrmmu.h>
23#include <asm/vac-ops.h> 19#include <asm/vac-ops.h>
24#include <asm/oplib.h> 20#include <asm/oplib.h>
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
index bb9ec2cce355..b049abf9902f 100644
--- a/arch/sparc/include/asm/pgtable_64.h
+++ b/arch/sparc/include/asm/pgtable_64.h
@@ -770,6 +770,8 @@ extern void sun4v_patch_tlb_handlers(void);
770 770
771extern unsigned long cmdline_memory_size; 771extern unsigned long cmdline_memory_size;
772 772
773extern asmlinkage void do_sparc64_fault(struct pt_regs *regs);
774
773#endif /* !(__ASSEMBLY__) */ 775#endif /* !(__ASSEMBLY__) */
774 776
775#endif /* !(_SPARC64_PGTABLE_H) */ 777#endif /* !(_SPARC64_PGTABLE_H) */
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index fd55522481cd..900d44714f8d 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -18,6 +18,7 @@
18 */ 18 */
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
21#include <linux/mutex.h>
21#include <asm/atomic.h> 22#include <asm/atomic.h>
22 23
23#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2 24#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
@@ -73,6 +74,7 @@ struct of_irq_controller {
73 74
74extern struct device_node *of_find_node_by_cpuid(int cpuid); 75extern struct device_node *of_find_node_by_cpuid(int cpuid);
75extern int of_set_property(struct device_node *node, const char *name, void *val, int len); 76extern int of_set_property(struct device_node *node, const char *name, void *val, int len);
77extern struct mutex of_set_property_mutex;
76extern int of_getintprop_default(struct device_node *np, 78extern int of_getintprop_default(struct device_node *np,
77 const char *name, 79 const char *name,
78 int def); 80 int def);
@@ -94,6 +96,16 @@ static inline void of_node_put(struct device_node *node)
94{ 96{
95} 97}
96 98
99/* These routines are here to provide compatibility with how powerpc
100 * handles IRQ mapping for OF device nodes. We precompute and permanently
101 * register them in the of_device objects, whereas powerpc computes them
102 * on request.
103 */
104extern unsigned int irq_of_parse_and_map(struct device_node *node, int index);
105static inline void irq_dispose_mapping(unsigned int virq)
106{
107}
108
97/* 109/*
98 * NB: This is here while we transition from using asm/prom.h 110 * NB: This is here while we transition from using asm/prom.h
99 * to linux/of.h 111 * to linux/of.h
diff --git a/arch/sparc/include/asm/ptrace_64.h b/arch/sparc/include/asm/ptrace_64.h
index 06e4914c13f4..3d3e9c161d8b 100644
--- a/arch/sparc/include/asm/ptrace_64.h
+++ b/arch/sparc/include/asm/ptrace_64.h
@@ -113,6 +113,8 @@ struct sparc_trapf {
113 113
114#ifdef __KERNEL__ 114#ifdef __KERNEL__
115 115
116#include <linux/threads.h>
117
116static inline int pt_regs_trap_type(struct pt_regs *regs) 118static inline int pt_regs_trap_type(struct pt_regs *regs)
117{ 119{
118 return regs->magic & 0x1ff; 120 return regs->magic & 0x1ff;
@@ -138,6 +140,7 @@ struct global_reg_snapshot {
138 struct thread_info *thread; 140 struct thread_info *thread;
139 unsigned long pad1; 141 unsigned long pad1;
140}; 142};
143extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
141 144
142#define __ARCH_WANT_COMPAT_SYS_PTRACE 145#define __ARCH_WANT_COMPAT_SYS_PTRACE
143 146
diff --git a/arch/sparc/include/asm/reboot.h b/arch/sparc/include/asm/reboot.h
deleted file mode 100644
index 3f3f43f5be5e..000000000000
--- a/arch/sparc/include/asm/reboot.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef _SPARC64_REBOOT_H
2#define _SPARC64_REBOOT_H
3
4extern void machine_alt_power_off(void);
5
6#endif /* _SPARC64_REBOOT_H */
diff --git a/arch/sparc/include/asm/rtc.h b/arch/sparc/include/asm/rtc.h
deleted file mode 100644
index f9ecb1fe2ecd..000000000000
--- a/arch/sparc/include/asm/rtc.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * rtc.h: Definitions for access to the Mostek real time clock
3 *
4 * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
5 */
6
7#ifndef _RTC_H
8#define _RTC_H
9
10#include <linux/ioctl.h>
11
12struct rtc_time
13{
14 int sec; /* Seconds (0-59) */
15 int min; /* Minutes (0-59) */
16 int hour; /* Hour (0-23) */
17 int dow; /* Day of the week (1-7) */
18 int dom; /* Day of the month (1-31) */
19 int month; /* Month of year (1-12) */
20 int year; /* Year (0-99) */
21};
22
23#define RTCGET _IOR('p', 20, struct rtc_time)
24#define RTCSET _IOW('p', 21, struct rtc_time)
25
26#endif
diff --git a/arch/sparc/include/asm/sbus.h b/arch/sparc/include/asm/sbus.h
deleted file mode 100644
index f82481ab44db..000000000000
--- a/arch/sparc/include/asm/sbus.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef ___ASM_SPARC_SBUS_H
2#define ___ASM_SPARC_SBUS_H
3#if defined(__sparc__) && defined(__arch64__)
4#include <asm/sbus_64.h>
5#else
6#include <asm/sbus_32.h>
7#endif
8#endif
diff --git a/arch/sparc/include/asm/sbus_32.h b/arch/sparc/include/asm/sbus_32.h
deleted file mode 100644
index a7b4fa21931d..000000000000
--- a/arch/sparc/include/asm/sbus_32.h
+++ /dev/null
@@ -1,153 +0,0 @@
1/*
2 * sbus.h: Defines for the Sun SBus.
3 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5 */
6
7#ifndef _SPARC_SBUS_H
8#define _SPARC_SBUS_H
9
10#include <linux/dma-mapping.h>
11#include <linux/ioport.h>
12#include <linux/of_device.h>
13
14#include <asm/oplib.h>
15#include <asm/prom.h>
16#include <asm/scatterlist.h>
17
18/* We scan which devices are on the SBus using the PROM node device
19 * tree. SBus devices are described in two different ways. You can
20 * either get an absolute address at which to access the device, or
21 * you can get a SBus 'slot' number and an offset within that slot.
22 */
23
24/* The base address at which to calculate device OBIO addresses. */
25#define SUN_SBUS_BVADDR 0xf8000000
26#define SBUS_OFF_MASK 0x01ffffff
27
28/* These routines are used to calculate device address from slot
29 * numbers + offsets, and vice versa.
30 */
31
32static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
33{
34 return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset));
35}
36
37static inline int sbus_dev_slot(unsigned long dev_addr)
38{
39 return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25);
40}
41
42struct sbus_bus;
43
44/* Linux SBUS device tables */
45struct sbus_dev {
46 struct of_device ofdev;
47 struct sbus_bus *bus;
48 struct sbus_dev *next;
49 struct sbus_dev *child;
50 struct sbus_dev *parent;
51 int prom_node;
52 char prom_name[64];
53 int slot;
54
55 struct resource resource[PROMREG_MAX];
56
57 struct linux_prom_registers reg_addrs[PROMREG_MAX];
58 int num_registers;
59
60 struct linux_prom_ranges device_ranges[PROMREG_MAX];
61 int num_device_ranges;
62
63 unsigned int irqs[4];
64 int num_irqs;
65};
66#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
67
68/* This struct describes the SBus(s) found on this machine. */
69struct sbus_bus {
70 struct of_device ofdev;
71 struct sbus_dev *devices; /* Link to devices on this SBus */
72 struct sbus_bus *next; /* next SBus, if more than one SBus */
73 int prom_node; /* PROM device tree node for this SBus */
74 char prom_name[64]; /* Usually "sbus" or "sbi" */
75 int clock_freq;
76
77 struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
78 int num_sbus_ranges;
79
80 int devid;
81 int board;
82};
83#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
84
85extern struct sbus_bus *sbus_root;
86
87static inline int
88sbus_is_slave(struct sbus_dev *dev)
89{
90 /* XXX Have to write this for sun4c's */
91 return 0;
92}
93
94/* Device probing routines could find these handy */
95#define for_each_sbus(bus) \
96 for((bus) = sbus_root; (bus); (bus)=(bus)->next)
97
98#define for_each_sbusdev(device, bus) \
99 for((device) = (bus)->devices; (device); (device)=(device)->next)
100
101#define for_all_sbusdev(device, bus) \
102 for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
103 for ((device) = (bus)->devices; (device); (device) = (device)->next)
104
105/* Driver DVMA interfaces. */
106#define sbus_can_dma_64bit(sdev) (0) /* actually, sparc_cpu_model==sun4d */
107#define sbus_can_burst64(sdev) (0) /* actually, sparc_cpu_model==sun4d */
108extern void sbus_set_sbus64(struct sbus_dev *, int);
109extern void sbus_fill_device_irq(struct sbus_dev *);
110
111/* These yield IOMMU mappings in consistent mode. */
112extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
113extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32);
114void prom_adjust_ranges(struct linux_prom_ranges *, int,
115 struct linux_prom_ranges *, int);
116
117#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
118#define SBUS_DMA_TODEVICE DMA_TO_DEVICE
119#define SBUS_DMA_FROMDEVICE DMA_FROM_DEVICE
120#define SBUS_DMA_NONE DMA_NONE
121
122/* All the rest use streaming mode mappings. */
123extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int);
124extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int);
125extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int);
126extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int);
127
128/* Finally, allow explicit synchronization of streamable mappings. */
129extern void sbus_dma_sync_single_for_cpu(struct sbus_dev *, dma_addr_t, size_t, int);
130#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu
131extern void sbus_dma_sync_single_for_device(struct sbus_dev *, dma_addr_t, size_t, int);
132extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int);
133#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
134extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int);
135
136/* Eric Brower (ebrower@usa.net)
137 * Translate SBus interrupt levels to ino values--
138 * this is used when converting sbus "interrupts" OBP
139 * node values to "intr" node values, and is platform
140 * dependent. If only we could call OBP with
141 * "sbus-intr>cpu (sbint -- ino)" from kernel...
142 * See .../drivers/sbus/sbus.c for details.
143 */
144BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int)
145#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint)
146
147extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
148extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
149extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
150extern int sbus_arch_preinit(void);
151extern void sbus_arch_postinit(void);
152
153#endif /* !(_SPARC_SBUS_H) */
diff --git a/arch/sparc/include/asm/sbus_64.h b/arch/sparc/include/asm/sbus_64.h
deleted file mode 100644
index b606c14343fb..000000000000
--- a/arch/sparc/include/asm/sbus_64.h
+++ /dev/null
@@ -1,190 +0,0 @@
1/* sbus.h: Defines for the Sun SBus.
2 *
3 * Copyright (C) 1996, 1999, 2007 David S. Miller (davem@davemloft.net)
4 */
5
6#ifndef _SPARC64_SBUS_H
7#define _SPARC64_SBUS_H
8
9#include <linux/dma-mapping.h>
10#include <linux/ioport.h>
11#include <linux/of_device.h>
12
13#include <asm/oplib.h>
14#include <asm/prom.h>
15#include <asm/iommu.h>
16#include <asm/scatterlist.h>
17
18/* We scan which devices are on the SBus using the PROM node device
19 * tree. SBus devices are described in two different ways. You can
20 * either get an absolute address at which to access the device, or
21 * you can get a SBus 'slot' number and an offset within that slot.
22 */
23
24/* The base address at which to calculate device OBIO addresses. */
25#define SUN_SBUS_BVADDR 0x00000000
26#define SBUS_OFF_MASK 0x0fffffff
27
28/* These routines are used to calculate device address from slot
29 * numbers + offsets, and vice versa.
30 */
31
32static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
33{
34 return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset));
35}
36
37static inline int sbus_dev_slot(unsigned long dev_addr)
38{
39 return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28);
40}
41
42struct sbus_bus;
43
44/* Linux SBUS device tables */
45struct sbus_dev {
46 struct of_device ofdev;
47 struct sbus_bus *bus;
48 struct sbus_dev *next;
49 struct sbus_dev *child;
50 struct sbus_dev *parent;
51 int prom_node;
52 char prom_name[64];
53 int slot;
54
55 struct resource resource[PROMREG_MAX];
56
57 struct linux_prom_registers reg_addrs[PROMREG_MAX];
58 int num_registers;
59
60 struct linux_prom_ranges device_ranges[PROMREG_MAX];
61 int num_device_ranges;
62
63 unsigned int irqs[4];
64 int num_irqs;
65};
66#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
67
68/* This struct describes the SBus(s) found on this machine. */
69struct sbus_bus {
70 struct of_device ofdev;
71 struct sbus_dev *devices; /* Tree of SBUS devices */
72 struct sbus_bus *next; /* Next SBUS in system */
73 int prom_node; /* OBP node of SBUS */
74 char prom_name[64]; /* Usually "sbus" or "sbi" */
75 int clock_freq;
76
77 struct linux_prom_ranges sbus_ranges[PROMREG_MAX];
78 int num_sbus_ranges;
79
80 int portid;
81};
82#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
83
84extern struct sbus_bus *sbus_root;
85
86/* Device probing routines could find these handy */
87#define for_each_sbus(bus) \
88 for((bus) = sbus_root; (bus); (bus)=(bus)->next)
89
90#define for_each_sbusdev(device, bus) \
91 for((device) = (bus)->devices; (device); (device)=(device)->next)
92
93#define for_all_sbusdev(device, bus) \
94 for ((bus) = sbus_root; (bus); (bus) = (bus)->next) \
95 for ((device) = (bus)->devices; (device); (device) = (device)->next)
96
97/* Driver DVMA interfaces. */
98#define sbus_can_dma_64bit(sdev) (1)
99#define sbus_can_burst64(sdev) (1)
100extern void sbus_set_sbus64(struct sbus_dev *, int);
101extern void sbus_fill_device_irq(struct sbus_dev *);
102
103static inline void *sbus_alloc_consistent(struct sbus_dev *sdev , size_t size,
104 dma_addr_t *dma_handle)
105{
106 return dma_alloc_coherent(&sdev->ofdev.dev, size,
107 dma_handle, GFP_ATOMIC);
108}
109
110static inline void sbus_free_consistent(struct sbus_dev *sdev, size_t size,
111 void *vaddr, dma_addr_t dma_handle)
112{
113 return dma_free_coherent(&sdev->ofdev.dev, size, vaddr, dma_handle);
114}
115
116#define SBUS_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
117#define SBUS_DMA_TODEVICE DMA_TO_DEVICE
118#define SBUS_DMA_FROMDEVICE DMA_FROM_DEVICE
119#define SBUS_DMA_NONE DMA_NONE
120
121/* All the rest use streaming mode mappings. */
122static inline dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr,
123 size_t size, int direction)
124{
125 return dma_map_single(&sdev->ofdev.dev, ptr, size,
126 (enum dma_data_direction) direction);
127}
128
129static inline void sbus_unmap_single(struct sbus_dev *sdev,
130 dma_addr_t dma_addr, size_t size,
131 int direction)
132{
133 dma_unmap_single(&sdev->ofdev.dev, dma_addr, size,
134 (enum dma_data_direction) direction);
135}
136
137static inline int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg,
138 int nents, int direction)
139{
140 return dma_map_sg(&sdev->ofdev.dev, sg, nents,
141 (enum dma_data_direction) direction);
142}
143
144static inline void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg,
145 int nents, int direction)
146{
147 dma_unmap_sg(&sdev->ofdev.dev, sg, nents,
148 (enum dma_data_direction) direction);
149}
150
151/* Finally, allow explicit synchronization of streamable mappings. */
152static inline void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev,
153 dma_addr_t dma_handle,
154 size_t size, int direction)
155{
156 dma_sync_single_for_cpu(&sdev->ofdev.dev, dma_handle, size,
157 (enum dma_data_direction) direction);
158}
159#define sbus_dma_sync_single sbus_dma_sync_single_for_cpu
160
161static inline void sbus_dma_sync_single_for_device(struct sbus_dev *sdev,
162 dma_addr_t dma_handle,
163 size_t size, int direction)
164{
165 /* No flushing needed to sync cpu writes to the device. */
166}
167
168static inline void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev,
169 struct scatterlist *sg,
170 int nents, int direction)
171{
172 dma_sync_sg_for_cpu(&sdev->ofdev.dev, sg, nents,
173 (enum dma_data_direction) direction);
174}
175#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
176
177static inline void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev,
178 struct scatterlist *sg,
179 int nents, int direction)
180{
181 /* No flushing needed to sync cpu writes to the device. */
182}
183
184extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
185extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
186extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
187extern int sbus_arch_preinit(void);
188extern void sbus_arch_postinit(void);
189
190#endif /* !(_SPARC64_SBUS_H) */
diff --git a/arch/sparc/include/asm/spinlock_32.h b/arch/sparc/include/asm/spinlock_32.h
index de2249b267c6..bf2d532593e3 100644
--- a/arch/sparc/include/asm/spinlock_32.h
+++ b/arch/sparc/include/asm/spinlock_32.h
@@ -6,8 +6,6 @@
6#ifndef __SPARC_SPINLOCK_H 6#ifndef __SPARC_SPINLOCK_H
7#define __SPARC_SPINLOCK_H 7#define __SPARC_SPINLOCK_H
8 8
9#include <linux/threads.h> /* For NR_CPUS */
10
11#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
12 10
13#include <asm/psr.h> 11#include <asm/psr.h>
diff --git a/arch/sparc/include/asm/spinlock_64.h b/arch/sparc/include/asm/spinlock_64.h
index 0006fe9f8c7a..120cfe4577c7 100644
--- a/arch/sparc/include/asm/spinlock_64.h
+++ b/arch/sparc/include/asm/spinlock_64.h
@@ -6,8 +6,6 @@
6#ifndef __SPARC64_SPINLOCK_H 6#ifndef __SPARC64_SPINLOCK_H
7#define __SPARC64_SPINLOCK_H 7#define __SPARC64_SPINLOCK_H
8 8
9#include <linux/threads.h> /* For NR_CPUS */
10
11#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
12 10
13/* To get debugging spinlocks which detect and catch 11/* To get debugging spinlocks which detect and catch
diff --git a/arch/sparc/include/asm/sstate.h b/arch/sparc/include/asm/sstate.h
deleted file mode 100644
index a7c35dbcb281..000000000000
--- a/arch/sparc/include/asm/sstate.h
+++ /dev/null
@@ -1,13 +0,0 @@
1#ifndef _SPARC64_SSTATE_H
2#define _SPARC64_SSTATE_H
3
4extern void sstate_booting(void);
5extern void sstate_running(void);
6extern void sstate_halt(void);
7extern void sstate_poweroff(void);
8extern void sstate_panic(void);
9extern void sstate_reboot(void);
10
11extern void sun4v_sstate_init(void);
12
13#endif /* _SPARC64_SSTATE_H */
diff --git a/arch/sparc/include/asm/starfire.h b/arch/sparc/include/asm/starfire.h
index 07bafd31e33c..d56ce60a5992 100644
--- a/arch/sparc/include/asm/starfire.h
+++ b/arch/sparc/include/asm/starfire.h
@@ -12,7 +12,6 @@
12extern int this_is_starfire; 12extern int this_is_starfire;
13 13
14extern void check_if_starfire(void); 14extern void check_if_starfire(void);
15extern void starfire_cpu_setup(void);
16extern int starfire_hard_smp_processor_id(void); 15extern int starfire_hard_smp_processor_id(void);
17extern void starfire_hookup(int); 16extern void starfire_hookup(int);
18extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid); 17extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid);
diff --git a/arch/sparc/include/asm/sun4paddr.h b/arch/sparc/include/asm/sun4paddr.h
deleted file mode 100644
index d52985f19f42..000000000000
--- a/arch/sparc/include/asm/sun4paddr.h
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * sun4paddr.h: Various physical addresses on sun4 machines
3 *
4 * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au)
5 * Copyright (C) 1998 Chris Davis (cdavis@cois.on.ca)
6 *
7 * Now supports more sun4's
8 */
9
10#ifndef _SPARC_SUN4PADDR_H
11#define _SPARC_SUN4PADDR_H
12
13#define SUN4_IE_PHYSADDR 0xf5000000
14#define SUN4_UNUSED_PHYSADDR 0
15
16/* these work for me */
17#define SUN4_200_MEMREG_PHYSADDR 0xf4000000
18#define SUN4_200_CLOCK_PHYSADDR 0xf3000000
19#define SUN4_200_BWTWO_PHYSADDR 0xfd000000
20#define SUN4_200_ETH_PHYSADDR 0xf6000000
21#define SUN4_200_SI_PHYSADDR 0xff200000
22
23/* these were here before */
24#define SUN4_300_MEMREG_PHYSADDR 0xf4000000
25#define SUN4_300_CLOCK_PHYSADDR 0xf2000000
26#define SUN4_300_TIMER_PHYSADDR 0xef000000
27#define SUN4_300_ETH_PHYSADDR 0xf9000000
28#define SUN4_300_BWTWO_PHYSADDR 0xfb400000
29#define SUN4_300_DMA_PHYSADDR 0xfa001000
30#define SUN4_300_ESP_PHYSADDR 0xfa000000
31
32/* Are these right? */
33#define SUN4_400_MEMREG_PHYSADDR 0xf4000000
34#define SUN4_400_CLOCK_PHYSADDR 0xf2000000
35#define SUN4_400_TIMER_PHYSADDR 0xef000000
36#define SUN4_400_ETH_PHYSADDR 0xf9000000
37#define SUN4_400_BWTWO_PHYSADDR 0xfb400000
38#define SUN4_400_DMA_PHYSADDR 0xfa001000
39#define SUN4_400_ESP_PHYSADDR 0xfa000000
40
41/*
42 these are the actual values set and used in the code. Unused items set
43 to SUN_UNUSED_PHYSADDR
44 */
45
46extern int sun4_memreg_physaddr; /* memory register (ecc?) */
47extern int sun4_clock_physaddr; /* system clock */
48extern int sun4_timer_physaddr; /* timer, where applicable */
49extern int sun4_eth_physaddr; /* onboard ethernet (ie/le) */
50extern int sun4_si_physaddr; /* sun3 scsi adapter */
51extern int sun4_bwtwo_physaddr; /* onboard bw2 */
52extern int sun4_dma_physaddr; /* scsi dma */
53extern int sun4_esp_physaddr; /* esp scsi */
54extern int sun4_ie_physaddr; /* interrupt enable */
55
56#endif /* !(_SPARC_SUN4PADDR_H) */
diff --git a/arch/sparc/include/asm/sun4prom.h b/arch/sparc/include/asm/sun4prom.h
deleted file mode 100644
index 9c8b4cbf629a..000000000000
--- a/arch/sparc/include/asm/sun4prom.h
+++ /dev/null
@@ -1,83 +0,0 @@
1/*
2 * sun4prom.h -- interface to sun4 PROM monitor. We don't use most of this,
3 * so most of these are just placeholders.
4 */
5
6#ifndef _SUN4PROM_H_
7#define _SUN4PROM_H_
8
9/*
10 * Although this looks similar to an romvec for a OpenProm machine, it is
11 * actually closer to what was used in the Sun2 and Sun3.
12 *
13 * V2 entries exist only in version 2 PROMs and later, V3 in version 3 and later.
14 *
15 * Many of the function prototypes are guesses. Some are certainly wrong.
16 * Use with care.
17 */
18
19typedef struct {
20 char *initSP; /* Initial system stack ptr */
21 void (*startmon)(void); /* Initial PC for hardware */
22 int *diagberr; /* Bus err handler for diags */
23 struct linux_arguments_v0 **bootParam; /* Info for bootstrapped pgm */
24 unsigned int *memorysize; /* Usable memory in bytes */
25 unsigned char (*getchar)(void); /* Get char from input device */
26 void (*putchar)(char); /* Put char to output device */
27 int (*mayget)(void); /* Maybe get char, or -1 */
28 int (*mayput)(int); /* Maybe put char, or -1 */
29 unsigned char *echo; /* Should getchar echo? */
30 unsigned char *insource; /* Input source selector */
31 unsigned char *outsink; /* Output sink selector */
32 int (*getkey)(void); /* Get next key if one exists */
33 void (*initgetkey)(void); /* Initialize get key */
34 unsigned int *translation; /* Kbd translation selector */
35 unsigned char *keybid; /* Keyboard ID byte */
36 int *screen_x; /* V2: Screen x pos (r/o) */
37 int *screen_y; /* V2: Screen y pos (r/o) */
38 struct keybuf *keybuf; /* Up/down keycode buffer */
39 char *monid; /* Monitor version ID */
40 void (*fbwritechar)(char); /* Write a character to FB */
41 int *fbAddr; /* Address of frame buffer */
42 char **font; /* Font table for FB */
43 void (*fbwritestr)(char *); /* Write string to FB */
44 void (*reboot)(char *); /* e.g. reboot("sd()vmlinux") */
45 unsigned char *linebuf; /* The line input buffer */
46 unsigned char **lineptr; /* Cur pointer into linebuf */
47 int *linesize; /* length of line in linebuf */
48 void (*getline)(char *); /* Get line from user */
49 unsigned char (*getnextchar)(void); /* Get next char from linebuf */
50 unsigned char (*peeknextchar)(void); /* Peek at next char */
51 int *fbthere; /* =1 if frame buffer there */
52 int (*getnum)(void); /* Grab hex num from line */
53 int (*printf)(char *, ...); /* See prom_printf() instead */
54 void (*printhex)(int); /* Format N digits in hex */
55 unsigned char *leds; /* RAM copy of LED register */
56 void (*setLEDs)(unsigned char *); /* Sets LED's and RAM copy */
57 void (*NMIaddr)(void *); /* Addr for level 7 vector */
58 void (*abortentry)(void); /* Entry for keyboard abort */
59 int *nmiclock; /* Counts up in msec */
60 int *FBtype; /* Frame buffer type */
61 unsigned int romvecversion; /* Version number for this romvec */
62 struct globram *globram; /* monitor global variables ??? */
63 void * kbdaddr; /* Addr of keyboard in use */
64 int *keyrinit; /* ms before kbd repeat */
65 unsigned char *keyrtick; /* ms between repetitions */
66 unsigned int *memoryavail; /* V1: Main mem usable size */
67 long *resetaddr; /* where to jump on a reset */
68 long *resetmap; /* pgmap entry for resetaddr */
69 void (*exittomon)(void); /* Exit from user program */
70 unsigned char **memorybitmap; /* V1: &{0 or &bits} */
71 void (*setcxsegmap)(int ctxt, char *va, int pmeg); /* Set seg in any context */
72 void (**vector_cmd)(void *); /* V2: Handler for 'v' cmd */
73 unsigned long *expectedtrapsig; /* V3: Location of the expected trap signal */
74 unsigned long *trapvectorbasetable; /* V3: Address of the trap vector table */
75 int unused1;
76 int unused2;
77 int unused3;
78 int unused4;
79} linux_sun4_romvec;
80
81extern linux_sun4_romvec *sun4_romvec;
82
83#endif /* _SUN4PROM_H_ */
diff --git a/arch/sparc/include/asm/system_32.h b/arch/sparc/include/asm/system_32.h
index b4b024445fc9..8623fc48fe24 100644
--- a/arch/sparc/include/asm/system_32.h
+++ b/arch/sparc/include/asm/system_32.h
@@ -34,13 +34,7 @@ enum sparc_cpu {
34 34
35extern enum sparc_cpu sparc_cpu_model; 35extern enum sparc_cpu sparc_cpu_model;
36 36
37#ifndef CONFIG_SUN4 37#define ARCH_SUN4C (sparc_cpu_model==sun4c)
38#define ARCH_SUN4C_SUN4 (sparc_cpu_model==sun4c)
39#define ARCH_SUN4 0
40#else
41#define ARCH_SUN4C_SUN4 1
42#define ARCH_SUN4 1
43#endif
44 38
45#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */ 39#define SUN4M_NCPUS 4 /* Architectural limit of sun4m. */
46 40
@@ -55,6 +49,7 @@ extern unsigned long empty_zero_page;
55extern void sun_do_break(void); 49extern void sun_do_break(void);
56extern int serial_console; 50extern int serial_console;
57extern int stop_a_enabled; 51extern int stop_a_enabled;
52extern int scons_pwroff;
58 53
59static inline int con_is_present(void) 54static inline int con_is_present(void)
60{ 55{
diff --git a/arch/sparc/include/asm/system_64.h b/arch/sparc/include/asm/system_64.h
index db9e742a406a..8759f2a1b837 100644
--- a/arch/sparc/include/asm/system_64.h
+++ b/arch/sparc/include/asm/system_64.h
@@ -26,9 +26,8 @@ enum sparc_cpu {
26 26
27#define sparc_cpu_model sun4u 27#define sparc_cpu_model sun4u
28 28
29/* This cannot ever be a sun4c nor sun4 :) That's just history. */ 29/* This cannot ever be a sun4c :) That's just history. */
30#define ARCH_SUN4C_SUN4 0 30#define ARCH_SUN4C 0
31#define ARCH_SUN4 0
32 31
33extern char reboot_command[]; 32extern char reboot_command[];
34 33
@@ -118,6 +117,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \
118 117
119extern void sun_do_break(void); 118extern void sun_do_break(void);
120extern int stop_a_enabled; 119extern int stop_a_enabled;
120extern int scons_pwroff;
121 121
122extern void fault_in_user_windows(void); 122extern void fault_in_user_windows(void);
123extern void synchronize_user_stack(void); 123extern void synchronize_user_stack(void);
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index cbb892d0dff0..29899fd5b1b2 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -80,11 +80,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
80/* 80/*
81 * thread information allocation 81 * thread information allocation
82 */ 82 */
83#if PAGE_SHIFT == 13
84#define THREAD_INFO_ORDER 0
85#else /* PAGE_SHIFT */
86#define THREAD_INFO_ORDER 1 83#define THREAD_INFO_ORDER 1
87#endif
88 84
89#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR 85#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
90 86
diff --git a/arch/sparc/include/asm/timer_32.h b/arch/sparc/include/asm/timer_32.h
index 361e53898dd7..2ec030ef3810 100644
--- a/arch/sparc/include/asm/timer_32.h
+++ b/arch/sparc/include/asm/timer_32.h
@@ -9,96 +9,9 @@
9#define _SPARC_TIMER_H 9#define _SPARC_TIMER_H
10 10
11#include <asm/system.h> /* For SUN4M_NCPUS */ 11#include <asm/system.h> /* For SUN4M_NCPUS */
12#include <asm/sun4paddr.h>
13#include <asm/btfixup.h> 12#include <asm/btfixup.h>
14 13
15/* Timer structures. The interrupt timer has two properties which
16 * are the counter (which is handled in do_timer in sched.c) and the limit.
17 * This limit is where the timer's counter 'wraps' around. Oddly enough,
18 * the sun4c timer when it hits the limit wraps back to 1 and not zero
19 * thus when calculating the value at which it will fire a microsecond you
20 * must adjust by one. Thanks SUN for designing such great hardware ;(
21 */
22
23/* Note that I am only going to use the timer that interrupts at
24 * Sparc IRQ 10. There is another one available that can fire at
25 * IRQ 14. Currently it is left untouched, we keep the PROM's limit
26 * register value and let the prom take these interrupts. This allows
27 * L1-A to work.
28 */
29
30struct sun4c_timer_info {
31 __volatile__ unsigned int cur_count10;
32 __volatile__ unsigned int timer_limit10;
33 __volatile__ unsigned int cur_count14;
34 __volatile__ unsigned int timer_limit14;
35};
36
37#define SUN4C_TIMER_PHYSADDR 0xf3000000
38#ifdef CONFIG_SUN4
39#define SUN_TIMER_PHYSADDR SUN4_300_TIMER_PHYSADDR
40#else
41#define SUN_TIMER_PHYSADDR SUN4C_TIMER_PHYSADDR
42#endif
43
44/* A sun4m has two blocks of registers which are probably of the same
45 * structure. LSI Logic's L64851 is told to _decrement_ from the limit
46 * value. Aurora behaves similarly but its limit value is compacted in
47 * other fashion (it's wider). Documented fields are defined here.
48 */
49
50/* As with the interrupt register, we have two classes of timer registers
51 * which are per-cpu and master. Per-cpu timers only hit that cpu and are
52 * only level 14 ticks, master timer hits all cpus and is level 10.
53 */
54
55#define SUN4M_PRM_CNT_L 0x80000000
56#define SUN4M_PRM_CNT_LVALUE 0x7FFFFC00
57
58struct sun4m_timer_percpu_info {
59 __volatile__ unsigned int l14_timer_limit; /* Initial value is 0x009c4000 */
60 __volatile__ unsigned int l14_cur_count;
61
62 /* This register appears to be write only and/or inaccessible
63 * on Uni-Processor sun4m machines.
64 */
65 __volatile__ unsigned int l14_limit_noclear; /* Data access error is here */
66
67 __volatile__ unsigned int cntrl; /* =1 after POST on Aurora */
68 __volatile__ unsigned char space[PAGE_SIZE - 16];
69};
70
71struct sun4m_timer_regs {
72 struct sun4m_timer_percpu_info cpu_timers[SUN4M_NCPUS];
73 volatile unsigned int l10_timer_limit;
74 volatile unsigned int l10_cur_count;
75
76 /* Again, this appears to be write only and/or inaccessible
77 * on uni-processor sun4m machines.
78 */
79 volatile unsigned int l10_limit_noclear;
80
81 /* This register too, it must be magic. */
82 volatile unsigned int foobar;
83
84 volatile unsigned int cfg; /* equals zero at boot time... */
85};
86
87#define SUN4D_PRM_CNT_L 0x80000000
88#define SUN4D_PRM_CNT_LVALUE 0x7FFFFC00
89
90struct sun4d_timer_regs {
91 volatile unsigned int l10_timer_limit;
92 volatile unsigned int l10_cur_countx;
93 volatile unsigned int l10_limit_noclear;
94 volatile unsigned int ctrl;
95 volatile unsigned int l10_cur_count;
96};
97
98extern struct sun4d_timer_regs *sun4d_timers;
99
100extern __volatile__ unsigned int *master_l10_counter; 14extern __volatile__ unsigned int *master_l10_counter;
101extern __volatile__ unsigned int *master_l10_limit;
102 15
103/* FIXME: Make do_[gs]ettimeofday btfixup calls */ 16/* FIXME: Make do_[gs]ettimeofday btfixup calls */
104BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv) 17BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv)
diff --git a/arch/sparc/include/asm/vac-ops.h b/arch/sparc/include/asm/vac-ops.h
index d10527611f11..a63e88ef0426 100644
--- a/arch/sparc/include/asm/vac-ops.h
+++ b/arch/sparc/include/asm/vac-ops.h
@@ -76,11 +76,7 @@
76 * cacheable bit in the pte's of all such pages. 76 * cacheable bit in the pte's of all such pages.
77 */ 77 */
78 78
79#ifdef CONFIG_SUN4
80#define S4CVAC_BADBITS 0x0001e000
81#else
82#define S4CVAC_BADBITS 0x0000f000 79#define S4CVAC_BADBITS 0x0000f000
83#endif
84 80
85/* The following is true if vaddr1 and vaddr2 would cause 81/* The following is true if vaddr1 and vaddr2 would cause
86 * a 'bad alias'. 82 * a 'bad alias'.
@@ -94,10 +90,7 @@
94 */ 90 */
95struct sun4c_vac_props { 91struct sun4c_vac_props {
96 unsigned int num_bytes; /* Size of the cache */ 92 unsigned int num_bytes; /* Size of the cache */
97 unsigned int num_lines; /* Number of cache lines */
98 unsigned int do_hwflushes; /* Hardware flushing available? */ 93 unsigned int do_hwflushes; /* Hardware flushing available? */
99 enum { VAC_NONE, VAC_WRITE_THROUGH,
100 VAC_WRITE_BACK } type; /* What type of VAC? */
101 unsigned int linesize; /* Size of each line in bytes */ 94 unsigned int linesize; /* Size of each line in bytes */
102 unsigned int log2lsize; /* log2(linesize) */ 95 unsigned int log2lsize; /* log2(linesize) */
103 unsigned int on; /* VAC is enabled */ 96 unsigned int on; /* VAC is enabled */
diff --git a/arch/sparc/include/asm/vfc_ioctls.h b/arch/sparc/include/asm/vfc_ioctls.h
deleted file mode 100644
index af8b69007b22..000000000000
--- a/arch/sparc/include/asm/vfc_ioctls.h
+++ /dev/null
@@ -1,58 +0,0 @@
1/* Copyright (c) 1996 by Manish Vachharajani */
2
3#ifndef _LINUX_VFC_IOCTLS_H_
4#define _LINUX_VFC_IOCTLS_H_
5
6 /* IOCTLs */
7#define VFC_IOCTL(a) (('j' << 8) | a)
8#define VFCGCTRL (VFC_IOCTL (0)) /* get vfc attributes */
9#define VFCSCTRL (VFC_IOCTL (1)) /* set vfc attributes */
10#define VFCGVID (VFC_IOCTL (2)) /* get video decoder attributes */
11#define VFCSVID (VFC_IOCTL (3)) /* set video decoder attributes */
12#define VFCHUE (VFC_IOCTL (4)) /* set hue */
13#define VFCPORTCHG (VFC_IOCTL (5)) /* change port */
14#define VFCRDINFO (VFC_IOCTL (6)) /* read info */
15
16 /* Options for setting the vfc attributes and status */
17#define MEMPRST 0x1 /* reset FIFO ptr. */
18#define CAPTRCMD 0x2 /* start capture and wait */
19#define DIAGMODE 0x3 /* diag mode */
20#define NORMMODE 0x4 /* normal mode */
21#define CAPTRSTR 0x5 /* start capture */
22#define CAPTRWAIT 0x6 /* wait for capture to finish */
23
24
25 /* Options for the decoder */
26#define STD_NTSC 0x1 /* NTSC mode */
27#define STD_PAL 0x2 /* PAL mode */
28#define COLOR_ON 0x3 /* force color ON */
29#define MONO 0x4 /* force color OFF */
30
31 /* Values returned by ioctl 2 */
32
33#define NO_LOCK 1
34#define NTSC_COLOR 2
35#define NTSC_NOCOLOR 3
36#define PAL_COLOR 4
37#define PAL_NOCOLOR 5
38
39/* Not too sure what this does yet */
40 /* Options for setting Field number */
41#define ODD_FIELD 0x1
42#define EVEN_FIELD 0x0
43#define ACTIVE_ONLY 0x2
44#define NON_ACTIVE 0x0
45
46/* Debug options */
47#define VFC_I2C_SEND 0
48#define VFC_I2C_RECV 1
49
50struct vfc_debug_inout
51{
52 unsigned long addr;
53 unsigned long ret;
54 unsigned long len;
55 unsigned char __user *buffer;
56};
57
58#endif /* _LINUX_VFC_IOCTLS_H_ */
diff --git a/arch/sparc/include/asm/visasm.h b/arch/sparc/include/asm/visasm.h
index de797b9bf552..39ca301920db 100644
--- a/arch/sparc/include/asm/visasm.h
+++ b/arch/sparc/include/asm/visasm.h
@@ -57,6 +57,7 @@ static inline void save_and_clear_fpu(void) {
57" " : : "i" (FPRS_FEF|FPRS_DU) : 57" " : : "i" (FPRS_FEF|FPRS_DU) :
58 "o5", "g1", "g2", "g3", "g7", "cc"); 58 "o5", "g1", "g2", "g3", "g7", "cc");
59} 59}
60extern int vis_emul(struct pt_regs *, unsigned int);
60#endif 61#endif
61 62
62#endif /* _SPARC64_ASI_H */ 63#endif /* _SPARC64_ASI_H */
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 6e03a2a7863c..2d6582095099 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -13,15 +13,13 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
13 time.o windows.o cpu.o devices.o \ 13 time.o windows.o cpu.o devices.o \
14 tadpole.o tick14.o ptrace.o \ 14 tadpole.o tick14.o ptrace.o \
15 unaligned.o una_asm.o muldiv.o \ 15 unaligned.o una_asm.o muldiv.o \
16 prom.o of_device.o devres.o 16 prom.o of_device.o devres.o dma.o
17 17
18devres-y = ../../../kernel/irq/devres.o 18devres-y = ../../../kernel/irq/devres.o
19 19
20obj-$(CONFIG_PCI) += pcic.o 20obj-$(CONFIG_PCI) += pcic.o
21obj-$(CONFIG_SUN4) += sun4setup.o
22obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o 21obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o
23obj-$(CONFIG_SUN_AUXIO) += auxio.o 22obj-$(CONFIG_SUN_AUXIO) += auxio.o
24obj-$(CONFIG_PCI) += ebus.o
25obj-$(CONFIG_SUN_PM) += apc.o pmc.o 23obj-$(CONFIG_SUN_PM) += apc.o pmc.o
26obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o 24obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o
27obj-$(CONFIG_SPARC_LED) += led.o 25obj-$(CONFIG_SPARC_LED) += led.o
diff --git a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
index 5267d48fb2c6..4dd1ba752ce6 100644
--- a/arch/sparc/kernel/apc.c
+++ b/arch/sparc/kernel/apc.c
@@ -12,9 +12,10 @@
12#include <linux/miscdevice.h> 12#include <linux/miscdevice.h>
13#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
14#include <linux/pm.h> 14#include <linux/pm.h>
15#include <linux/of.h>
16#include <linux/of_device.h>
15 17
16#include <asm/io.h> 18#include <asm/io.h>
17#include <asm/sbus.h>
18#include <asm/oplib.h> 19#include <asm/oplib.h>
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20#include <asm/auxio.h> 21#include <asm/auxio.h>
@@ -29,11 +30,10 @@
29#define APC_OBPNAME "power-management" 30#define APC_OBPNAME "power-management"
30#define APC_DEVNAME "apc" 31#define APC_DEVNAME "apc"
31 32
32volatile static u8 __iomem *regs; 33static u8 __iomem *regs;
33static int apc_regsize;
34static int apc_no_idle __initdata = 0; 34static int apc_no_idle __initdata = 0;
35 35
36#define apc_readb(offs) (sbus_readb(regs+offs)) 36#define apc_readb(offs) (sbus_readb(regs+offs))
37#define apc_writeb(val, offs) (sbus_writeb(val, regs+offs)) 37#define apc_writeb(val, offs) (sbus_writeb(val, regs+offs))
38 38
39/* Specify "apc=noidle" on the kernel command line to 39/* Specify "apc=noidle" on the kernel command line to
@@ -69,9 +69,9 @@ static void apc_swift_idle(void)
69#endif 69#endif
70} 70}
71 71
72static inline void apc_free(void) 72static inline void apc_free(struct of_device *op)
73{ 73{
74 sbus_iounmap(regs, apc_regsize); 74 of_iounmap(&op->resource[0], regs, resource_size(&op->resource[0]));
75} 75}
76 76
77static int apc_open(struct inode *inode, struct file *f) 77static int apc_open(struct inode *inode, struct file *f)
@@ -153,52 +153,56 @@ static const struct file_operations apc_fops = {
153 153
154static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; 154static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
155 155
156static int __init apc_probe(void) 156static int __devinit apc_probe(struct of_device *op,
157 const struct of_device_id *match)
157{ 158{
158 struct sbus_bus *sbus = NULL; 159 int err;
159 struct sbus_dev *sdev = NULL;
160 int iTmp = 0;
161
162 for_each_sbus(sbus) {
163 for_each_sbusdev(sdev, sbus) {
164 if (!strcmp(sdev->prom_name, APC_OBPNAME)) {
165 goto sbus_done;
166 }
167 }
168 }
169 160
170sbus_done: 161 regs = of_ioremap(&op->resource[0], 0,
171 if (!sdev) { 162 resource_size(&op->resource[0]), APC_OBPNAME);
172 return -ENODEV; 163 if (!regs) {
173 }
174
175 apc_regsize = sdev->reg_addrs[0].reg_size;
176 regs = sbus_ioremap(&sdev->resource[0], 0,
177 apc_regsize, APC_OBPNAME);
178 if(!regs) {
179 printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME); 164 printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME);
180 return -ENODEV; 165 return -ENODEV;
181 } 166 }
182 167
183 iTmp = misc_register(&apc_miscdev); 168 err = misc_register(&apc_miscdev);
184 if (iTmp != 0) { 169 if (err) {
185 printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME); 170 printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME);
186 apc_free(); 171 apc_free(op);
187 return -ENODEV; 172 return -ENODEV;
188 } 173 }
189 174
190 /* Assign power management IDLE handler */ 175 /* Assign power management IDLE handler */
191 if(!apc_no_idle) 176 if (!apc_no_idle)
192 pm_idle = apc_swift_idle; 177 pm_idle = apc_swift_idle;
193 178
194 printk(KERN_INFO "%s: power management initialized%s\n", 179 printk(KERN_INFO "%s: power management initialized%s\n",
195 APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : ""); 180 APC_DEVNAME, apc_no_idle ? " (CPU idle disabled)" : "");
181
196 return 0; 182 return 0;
197} 183}
198 184
185static struct of_device_id __initdata apc_match[] = {
186 {
187 .name = APC_OBPNAME,
188 },
189 {},
190};
191MODULE_DEVICE_TABLE(of, apc_match);
192
193static struct of_platform_driver apc_driver = {
194 .name = "apc",
195 .match_table = apc_match,
196 .probe = apc_probe,
197};
198
199static int __init apc_init(void)
200{
201 return of_register_driver(&apc_driver, &of_bus_type);
202}
203
199/* This driver is not critical to the boot process 204/* This driver is not critical to the boot process
200 * and is easiest to ioremap when SBus is already 205 * and is easiest to ioremap when SBus is already
201 * initialized, so we install ourselves thusly: 206 * initialized, so we install ourselves thusly:
202 */ 207 */
203__initcall(apc_probe); 208__initcall(apc_init);
204
diff --git a/arch/sparc/kernel/auxio.c b/arch/sparc/kernel/auxio.c
index baf4ed3fb0f3..09c857215a52 100644
--- a/arch/sparc/kernel/auxio.c
+++ b/arch/sparc/kernel/auxio.c
@@ -6,6 +6,8 @@
6#include <linux/stddef.h> 6#include <linux/stddef.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/spinlock.h> 8#include <linux/spinlock.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
9#include <asm/oplib.h> 11#include <asm/oplib.h>
10#include <asm/io.h> 12#include <asm/io.h>
11#include <asm/auxio.h> 13#include <asm/auxio.h>
@@ -59,7 +61,7 @@ void __init auxio_probe(void)
59 r.flags = auxregs[0].which_io & 0xF; 61 r.flags = auxregs[0].which_io & 0xF;
60 r.start = auxregs[0].phys_addr; 62 r.start = auxregs[0].phys_addr;
61 r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1; 63 r.end = auxregs[0].phys_addr + auxregs[0].reg_size - 1;
62 auxio_register = sbus_ioremap(&r, 0, auxregs[0].reg_size, "auxio"); 64 auxio_register = of_ioremap(&r, 0, auxregs[0].reg_size, "auxio");
63 /* Fix the address on sun4m and sun4c. */ 65 /* Fix the address on sun4m and sun4c. */
64 if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 || 66 if((((unsigned long) auxregs[0].phys_addr) & 3) == 3 ||
65 sparc_cpu_model == sun4c) 67 sparc_cpu_model == sun4c)
@@ -128,7 +130,7 @@ void __init auxio_power_probe(void)
128 r.flags = regs.which_io & 0xF; 130 r.flags = regs.which_io & 0xF;
129 r.start = regs.phys_addr; 131 r.start = regs.phys_addr;
130 r.end = regs.phys_addr + regs.reg_size - 1; 132 r.end = regs.phys_addr + regs.reg_size - 1;
131 auxio_power_register = (unsigned char *) sbus_ioremap(&r, 0, 133 auxio_power_register = (unsigned char *) of_ioremap(&r, 0,
132 regs.reg_size, "auxpower"); 134 regs.reg_size, "auxpower");
133 135
134 /* Display a quick message on the console. */ 136 /* Display a quick message on the console. */
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c
index b240b8863fd0..ad656b044b8c 100644
--- a/arch/sparc/kernel/devices.c
+++ b/arch/sparc/kernel/devices.c
@@ -143,7 +143,7 @@ void __init device_scan(void)
143#endif 143#endif
144 clock_stop_probe(); 144 clock_stop_probe();
145 145
146 if (ARCH_SUN4C_SUN4) 146 if (ARCH_SUN4C)
147 sun4c_probe_memerr_reg(); 147 sun4c_probe_memerr_reg();
148 148
149 return; 149 return;
diff --git a/arch/sparc/kernel/dma.c b/arch/sparc/kernel/dma.c
new file mode 100644
index 000000000000..ebc8403b035e
--- /dev/null
+++ b/arch/sparc/kernel/dma.c
@@ -0,0 +1,227 @@
1/* dma.c: PCI and SBUS DMA accessors for 32-bit sparc.
2 *
3 * Copyright (C) 2008 David S. Miller <davem@davemloft.net>
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/dma-mapping.h>
9#include <linux/scatterlist.h>
10#include <linux/mm.h>
11
12#ifdef CONFIG_PCI
13#include <linux/pci.h>
14#endif
15
16#include "dma.h"
17
18int dma_supported(struct device *dev, u64 mask)
19{
20#ifdef CONFIG_PCI
21 if (dev->bus == &pci_bus_type)
22 return pci_dma_supported(to_pci_dev(dev), mask);
23#endif
24 return 0;
25}
26EXPORT_SYMBOL(dma_supported);
27
28int dma_set_mask(struct device *dev, u64 dma_mask)
29{
30#ifdef CONFIG_PCI
31 if (dev->bus == &pci_bus_type)
32 return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
33#endif
34 return -EOPNOTSUPP;
35}
36EXPORT_SYMBOL(dma_set_mask);
37
38void *dma_alloc_coherent(struct device *dev, size_t size,
39 dma_addr_t *dma_handle, gfp_t flag)
40{
41#ifdef CONFIG_PCI
42 if (dev->bus == &pci_bus_type)
43 return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
44#endif
45 return sbus_alloc_consistent(dev, size, dma_handle);
46}
47EXPORT_SYMBOL(dma_alloc_coherent);
48
49void dma_free_coherent(struct device *dev, size_t size,
50 void *cpu_addr, dma_addr_t dma_handle)
51{
52#ifdef CONFIG_PCI
53 if (dev->bus == &pci_bus_type) {
54 pci_free_consistent(to_pci_dev(dev), size,
55 cpu_addr, dma_handle);
56 return;
57 }
58#endif
59 sbus_free_consistent(dev, size, cpu_addr, dma_handle);
60}
61EXPORT_SYMBOL(dma_free_coherent);
62
63dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
64 size_t size, enum dma_data_direction direction)
65{
66#ifdef CONFIG_PCI
67 if (dev->bus == &pci_bus_type)
68 return pci_map_single(to_pci_dev(dev), cpu_addr,
69 size, (int)direction);
70#endif
71 return sbus_map_single(dev, cpu_addr, size, (int)direction);
72}
73EXPORT_SYMBOL(dma_map_single);
74
75void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
76 size_t size,
77 enum dma_data_direction direction)
78{
79#ifdef CONFIG_PCI
80 if (dev->bus == &pci_bus_type) {
81 pci_unmap_single(to_pci_dev(dev), dma_addr,
82 size, (int)direction);
83 return;
84 }
85#endif
86 sbus_unmap_single(dev, dma_addr, size, (int)direction);
87}
88EXPORT_SYMBOL(dma_unmap_single);
89
90dma_addr_t dma_map_page(struct device *dev, struct page *page,
91 unsigned long offset, size_t size,
92 enum dma_data_direction direction)
93{
94#ifdef CONFIG_PCI
95 if (dev->bus == &pci_bus_type)
96 return pci_map_page(to_pci_dev(dev), page, offset,
97 size, (int)direction);
98#endif
99 return sbus_map_single(dev, page_address(page) + offset,
100 size, (int)direction);
101}
102EXPORT_SYMBOL(dma_map_page);
103
104void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
105 size_t size, enum dma_data_direction direction)
106{
107#ifdef CONFIG_PCI
108 if (dev->bus == &pci_bus_type) {
109 pci_unmap_page(to_pci_dev(dev), dma_address,
110 size, (int)direction);
111 return;
112 }
113#endif
114 sbus_unmap_single(dev, dma_address, size, (int)direction);
115}
116EXPORT_SYMBOL(dma_unmap_page);
117
118int dma_map_sg(struct device *dev, struct scatterlist *sg,
119 int nents, enum dma_data_direction direction)
120{
121#ifdef CONFIG_PCI
122 if (dev->bus == &pci_bus_type)
123 return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
124#endif
125 return sbus_map_sg(dev, sg, nents, direction);
126}
127EXPORT_SYMBOL(dma_map_sg);
128
129void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
130 int nents, enum dma_data_direction direction)
131{
132#ifdef CONFIG_PCI
133 if (dev->bus == &pci_bus_type) {
134 pci_unmap_sg(to_pci_dev(dev), sg, nents, (int)direction);
135 return;
136 }
137#endif
138 sbus_unmap_sg(dev, sg, nents, (int)direction);
139}
140EXPORT_SYMBOL(dma_unmap_sg);
141
142void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
143 size_t size, enum dma_data_direction direction)
144{
145#ifdef CONFIG_PCI
146 if (dev->bus == &pci_bus_type) {
147 pci_dma_sync_single_for_cpu(to_pci_dev(dev), dma_handle,
148 size, (int)direction);
149 return;
150 }
151#endif
152 sbus_dma_sync_single_for_cpu(dev, dma_handle, size, (int) direction);
153}
154EXPORT_SYMBOL(dma_sync_single_for_cpu);
155
156void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
157 size_t size, enum dma_data_direction direction)
158{
159#ifdef CONFIG_PCI
160 if (dev->bus == &pci_bus_type) {
161 pci_dma_sync_single_for_device(to_pci_dev(dev), dma_handle,
162 size, (int)direction);
163 return;
164 }
165#endif
166 sbus_dma_sync_single_for_device(dev, dma_handle, size, (int) direction);
167}
168EXPORT_SYMBOL(dma_sync_single_for_device);
169
170void dma_sync_single_range_for_cpu(struct device *dev,
171 dma_addr_t dma_handle,
172 unsigned long offset,
173 size_t size,
174 enum dma_data_direction direction)
175{
176 dma_sync_single_for_cpu(dev, dma_handle+offset, size, direction);
177}
178EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
179
180void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
181 unsigned long offset, size_t size,
182 enum dma_data_direction direction)
183{
184 dma_sync_single_for_device(dev, dma_handle+offset, size, direction);
185}
186EXPORT_SYMBOL(dma_sync_single_range_for_device);
187
188void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
189 int nelems, enum dma_data_direction direction)
190{
191#ifdef CONFIG_PCI
192 if (dev->bus == &pci_bus_type) {
193 pci_dma_sync_sg_for_cpu(to_pci_dev(dev), sg,
194 nelems, (int)direction);
195 return;
196 }
197#endif
198 BUG();
199}
200EXPORT_SYMBOL(dma_sync_sg_for_cpu);
201
202void dma_sync_sg_for_device(struct device *dev,
203 struct scatterlist *sg, int nelems,
204 enum dma_data_direction direction)
205{
206#ifdef CONFIG_PCI
207 if (dev->bus == &pci_bus_type) {
208 pci_dma_sync_sg_for_device(to_pci_dev(dev), sg,
209 nelems, (int)direction);
210 return;
211 }
212#endif
213 BUG();
214}
215EXPORT_SYMBOL(dma_sync_sg_for_device);
216
217int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
218{
219 return (dma_addr == DMA_ERROR_CODE);
220}
221EXPORT_SYMBOL(dma_mapping_error);
222
223int dma_get_cache_alignment(void)
224{
225 return 32;
226}
227EXPORT_SYMBOL(dma_get_cache_alignment);
diff --git a/arch/sparc/kernel/dma.h b/arch/sparc/kernel/dma.h
new file mode 100644
index 000000000000..f8d8951adb53
--- /dev/null
+++ b/arch/sparc/kernel/dma.h
@@ -0,0 +1,14 @@
1void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp);
2void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba);
3dma_addr_t sbus_map_single(struct device *dev, void *va,
4 size_t len, int direction);
5void sbus_unmap_single(struct device *dev, dma_addr_t ba,
6 size_t n, int direction);
7int sbus_map_sg(struct device *dev, struct scatterlist *sg,
8 int n, int direction);
9void sbus_unmap_sg(struct device *dev, struct scatterlist *sg,
10 int n, int direction);
11void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba,
12 size_t size, int direction);
13void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba,
14 size_t size, int direction);
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
deleted file mode 100644
index 97294232259c..000000000000
--- a/arch/sparc/kernel/ebus.c
+++ /dev/null
@@ -1,393 +0,0 @@
1/*
2 * ebus.c: PCI to EBus bridge device.
3 *
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 *
6 * Adopted for sparc by V. Roganov and G. Raiko.
7 * Fixes for different platforms by Pete Zaitcev.
8 */
9
10#include <linux/kernel.h>
11#include <linux/types.h>
12#include <linux/init.h>
13#include <linux/slab.h>
14#include <linux/string.h>
15
16#include <asm/system.h>
17#include <asm/page.h>
18#include <asm/pbm.h>
19#include <asm/ebus.h>
20#include <asm/io.h>
21#include <asm/oplib.h>
22#include <asm/prom.h>
23#include <asm/bpp.h>
24
25struct linux_ebus *ebus_chain = NULL;
26
27/* We are together with pcic.c under CONFIG_PCI. */
28extern unsigned int pcic_pin_to_irq(unsigned int, const char *name);
29
30/*
31 * IRQ Blacklist
32 * Here we list PROMs and systems that are known to supply crap as IRQ numbers.
33 */
34struct ebus_device_irq {
35 char *name;
36 unsigned int pin;
37};
38
39struct ebus_system_entry {
40 char *esname;
41 struct ebus_device_irq *ipt;
42};
43
44static struct ebus_device_irq je1_1[] = {
45 { "8042", 3 },
46 { "SUNW,CS4231", 0 },
47 { "parallel", 0 },
48 { "se", 2 },
49 { NULL, 0 }
50};
51
52/*
53 * Gleb's JE1 supplied reasonable pin numbers, but mine did not (OBP 2.32).
54 * Blacklist the sucker... Note that Gleb's system will work.
55 */
56static struct ebus_system_entry ebus_blacklist[] = {
57 { "SUNW,JavaEngine1", je1_1 },
58 { NULL, NULL }
59};
60
61static struct ebus_device_irq *ebus_blackp = NULL;
62
63/*
64 */
65static inline unsigned long ebus_alloc(size_t size)
66{
67 return (unsigned long)kmalloc(size, GFP_ATOMIC);
68}
69
70/*
71 */
72static int __init ebus_blacklist_irq(const char *name)
73{
74 struct ebus_device_irq *dp;
75
76 if ((dp = ebus_blackp) != NULL) {
77 for (; dp->name != NULL; dp++) {
78 if (strcmp(name, dp->name) == 0) {
79 return pcic_pin_to_irq(dp->pin, name);
80 }
81 }
82 }
83 return 0;
84}
85
86static void __init fill_ebus_child(struct device_node *dp,
87 struct linux_ebus_child *dev)
88{
89 const int *regs;
90 const int *irqs;
91 int i, len;
92
93 dev->prom_node = dp;
94 regs = of_get_property(dp, "reg", &len);
95 if (!regs)
96 len = 0;
97 dev->num_addrs = len / sizeof(regs[0]);
98
99 for (i = 0; i < dev->num_addrs; i++) {
100 if (regs[i] >= dev->parent->num_addrs) {
101 prom_printf("UGH: property for %s was %d, need < %d\n",
102 dev->prom_node->name, len,
103 dev->parent->num_addrs);
104 panic(__func__);
105 }
106
107 /* XXX resource */
108 dev->resource[i].start =
109 dev->parent->resource[regs[i]].start;
110 }
111
112 for (i = 0; i < PROMINTR_MAX; i++)
113 dev->irqs[i] = PCI_IRQ_NONE;
114
115 if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
116 dev->num_irqs = 1;
117 } else {
118 irqs = of_get_property(dp, "interrupts", &len);
119 if (!irqs) {
120 dev->num_irqs = 0;
121 dev->irqs[0] = 0;
122 if (dev->parent->num_irqs != 0) {
123 dev->num_irqs = 1;
124 dev->irqs[0] = dev->parent->irqs[0];
125 }
126 } else {
127 dev->num_irqs = len / sizeof(irqs[0]);
128 if (irqs[0] == 0 || irqs[0] >= 8) {
129 /*
130 * XXX Zero is a valid pin number...
131 * This works as long as Ebus is not wired
132 * to INTA#.
133 */
134 printk("EBUS: %s got bad irq %d from PROM\n",
135 dev->prom_node->name, irqs[0]);
136 dev->num_irqs = 0;
137 dev->irqs[0] = 0;
138 } else {
139 dev->irqs[0] =
140 pcic_pin_to_irq(irqs[0],
141 dev->prom_node->name);
142 }
143 }
144 }
145}
146
147static void __init fill_ebus_device(struct device_node *dp,
148 struct linux_ebus_device *dev)
149{
150 const struct linux_prom_registers *regs;
151 struct linux_ebus_child *child;
152 struct dev_archdata *sd;
153 const int *irqs;
154 int i, n, len;
155 unsigned long baseaddr;
156
157 dev->prom_node = dp;
158
159 regs = of_get_property(dp, "reg", &len);
160 if (!regs)
161 len = 0;
162 if (len % sizeof(struct linux_prom_registers)) {
163 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
164 dev->prom_node->name, len,
165 (int)sizeof(struct linux_prom_registers));
166 panic(__func__);
167 }
168 dev->num_addrs = len / sizeof(struct linux_prom_registers);
169
170 for (i = 0; i < dev->num_addrs; i++) {
171 /*
172 * XXX Collect JE-1 PROM
173 *
174 * Example - JS-E with 3.11:
175 * /ebus
176 * regs
177 * 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000,
178 * 0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000,
179 * 0x82000014, 0x0, 0x38800000, 0x0, 0x00800000,
180 * ranges
181 * 0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000,
182 * 0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000,
183 * /ebus/8042
184 * regs
185 * 0x00000001, 0x00300060, 0x00000008,
186 * 0x00000001, 0x00300060, 0x00000008,
187 */
188 n = regs[i].which_io;
189 if (n >= 4) {
190 /* XXX This is copied from old JE-1 by Gleb. */
191 n = (regs[i].which_io - 0x10) >> 2;
192 } else {
193 ;
194 }
195
196/*
197 * XXX Now as we have regions, why don't we make an on-demand allocation...
198 */
199 dev->resource[i].start = 0;
200 if ((baseaddr = dev->bus->self->resource[n].start +
201 regs[i].phys_addr) != 0) {
202 /* dev->resource[i].name = dev->prom_name; */
203 if ((baseaddr = (unsigned long) ioremap(baseaddr,
204 regs[i].reg_size)) == 0) {
205 panic("ebus: unable to remap dev %s",
206 dev->prom_node->name);
207 }
208 }
209 dev->resource[i].start = baseaddr; /* XXX Unaligned */
210 }
211
212 for (i = 0; i < PROMINTR_MAX; i++)
213 dev->irqs[i] = PCI_IRQ_NONE;
214
215 if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
216 dev->num_irqs = 1;
217 } else {
218 irqs = of_get_property(dp, "interrupts", &len);
219 if (!irqs) {
220 dev->num_irqs = 0;
221 if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
222 dev->num_irqs = 1;
223/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */
224 }
225 } else {
226 dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */
227 if (irqs[0] == 0 || irqs[0] >= 8) {
228 /* See above for the parent. XXX */
229 printk("EBUS: %s got bad irq %d from PROM\n",
230 dev->prom_node->name, irqs[0]);
231 dev->num_irqs = 0;
232 dev->irqs[0] = 0;
233 } else {
234 dev->irqs[0] =
235 pcic_pin_to_irq(irqs[0],
236 dev->prom_node->name);
237 }
238 }
239 }
240
241 sd = &dev->ofdev.dev.archdata;
242 sd->prom_node = dp;
243 sd->op = &dev->ofdev;
244 sd->iommu = dev->bus->ofdev.dev.parent->archdata.iommu;
245
246 dev->ofdev.node = dp;
247 dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
248 dev->ofdev.dev.bus = &ebus_bus_type;
249 sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
250
251 /* Register with core */
252 if (of_device_register(&dev->ofdev) != 0)
253 printk(KERN_DEBUG "ebus: device registration error for %s!\n",
254 dp->path_component_name);
255
256 if ((dp = dp->child) != NULL) {
257 dev->children = (struct linux_ebus_child *)
258 ebus_alloc(sizeof(struct linux_ebus_child));
259
260 child = dev->children;
261 child->next = NULL;
262 child->parent = dev;
263 child->bus = dev->bus;
264 fill_ebus_child(dp, child);
265
266 while ((dp = dp->sibling) != NULL) {
267 child->next = (struct linux_ebus_child *)
268 ebus_alloc(sizeof(struct linux_ebus_child));
269
270 child = child->next;
271 child->next = NULL;
272 child->parent = dev;
273 child->bus = dev->bus;
274 fill_ebus_child(dp, child);
275 }
276 }
277}
278
279void __init ebus_init(void)
280{
281 const struct linux_prom_pci_registers *regs;
282 struct linux_pbm_info *pbm;
283 struct linux_ebus_device *dev;
284 struct linux_ebus *ebus;
285 struct ebus_system_entry *sp;
286 struct pci_dev *pdev;
287 struct pcidev_cookie *cookie;
288 struct device_node *dp;
289 struct resource *p;
290 unsigned short pci_command;
291 int len, reg, nreg;
292 int num_ebus = 0;
293
294 dp = of_find_node_by_path("/");
295 for (sp = ebus_blacklist; sp->esname != NULL; sp++) {
296 if (strcmp(dp->name, sp->esname) == 0) {
297 ebus_blackp = sp->ipt;
298 break;
299 }
300 }
301
302 pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL);
303 if (!pdev)
304 return;
305
306 cookie = pdev->sysdata;
307 dp = cookie->prom_node;
308
309 ebus_chain = ebus = (struct linux_ebus *)
310 ebus_alloc(sizeof(struct linux_ebus));
311 ebus->next = NULL;
312
313 while (dp) {
314 struct device_node *nd;
315
316 ebus->prom_node = dp;
317 ebus->self = pdev;
318 ebus->parent = pbm = cookie->pbm;
319
320 /* Enable BUS Master. */
321 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
322 pci_command |= PCI_COMMAND_MASTER;
323 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
324
325 regs = of_get_property(dp, "reg", &len);
326 if (!regs) {
327 prom_printf("%s: can't find reg property\n",
328 __func__);
329 prom_halt();
330 }
331 nreg = len / sizeof(struct linux_prom_pci_registers);
332
333 p = &ebus->self->resource[0];
334 for (reg = 0; reg < nreg; reg++) {
335 if (!(regs[reg].which_io & 0x03000000))
336 continue;
337
338 (p++)->start = regs[reg].phys_lo;
339 }
340
341 ebus->ofdev.node = dp;
342 ebus->ofdev.dev.parent = &pdev->dev;
343 ebus->ofdev.dev.bus = &ebus_bus_type;
344 sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
345
346 /* Register with core */
347 if (of_device_register(&ebus->ofdev) != 0)
348 printk(KERN_DEBUG "ebus: device registration error for %s!\n",
349 dp->path_component_name);
350
351
352 nd = dp->child;
353 if (!nd)
354 goto next_ebus;
355
356 ebus->devices = (struct linux_ebus_device *)
357 ebus_alloc(sizeof(struct linux_ebus_device));
358
359 dev = ebus->devices;
360 dev->next = NULL;
361 dev->children = NULL;
362 dev->bus = ebus;
363 fill_ebus_device(nd, dev);
364
365 while ((nd = nd->sibling) != NULL) {
366 dev->next = (struct linux_ebus_device *)
367 ebus_alloc(sizeof(struct linux_ebus_device));
368
369 dev = dev->next;
370 dev->next = NULL;
371 dev->children = NULL;
372 dev->bus = ebus;
373 fill_ebus_device(nd, dev);
374 }
375
376 next_ebus:
377 pdev = pci_get_device(PCI_VENDOR_ID_SUN,
378 PCI_DEVICE_ID_SUN_EBUS, pdev);
379 if (!pdev)
380 break;
381
382 cookie = pdev->sysdata;
383 dp = cookie->prom_node;
384
385 ebus->next = (struct linux_ebus *)
386 ebus_alloc(sizeof(struct linux_ebus));
387 ebus = ebus->next;
388 ebus->next = NULL;
389 ++num_ebus;
390 }
391 if (pdev)
392 pci_dev_put(pdev);
393}
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index e8cdf715a546..faf9ccd9ef5d 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -20,11 +20,7 @@
20#include <asm/memreg.h> 20#include <asm/memreg.h>
21#include <asm/page.h> 21#include <asm/page.h>
22#include <asm/pgtable.h> 22#include <asm/pgtable.h>
23#ifdef CONFIG_SUN4
24#include <asm/pgtsun4.h>
25#else
26#include <asm/pgtsun4c.h> 23#include <asm/pgtsun4c.h>
27#endif
28#include <asm/winmacro.h> 24#include <asm/winmacro.h>
29#include <asm/signal.h> 25#include <asm/signal.h>
30#include <asm/obio.h> 26#include <asm/obio.h>
@@ -276,17 +272,18 @@ smp4m_ticker:
276 */ 272 */
277maybe_smp4m_msg: 273maybe_smp4m_msg:
278 GET_PROCESSOR4M_ID(o3) 274 GET_PROCESSOR4M_ID(o3)
279 set sun4m_interrupts, %l5 275 sethi %hi(sun4m_irq_percpu), %l5
280 ld [%l5], %o5 276 sll %o3, 2, %o3
277 or %l5, %lo(sun4m_irq_percpu), %o5
281 sethi %hi(0x40000000), %o2 278 sethi %hi(0x40000000), %o2
282 sll %o3, 12, %o3
283 ld [%o5 + %o3], %o1 279 ld [%o5 + %o3], %o1
284 andcc %o1, %o2, %g0 280 ld [%o1 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending
281 andcc %o3, %o2, %g0
285 be,a smp4m_ticker 282 be,a smp4m_ticker
286 cmp %l7, 14 283 cmp %l7, 14
287 st %o2, [%o5 + 0x4] 284 st %o2, [%o1 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x40000000
288 WRITE_PAUSE 285 WRITE_PAUSE
289 ld [%o5], %g0 286 ld [%o1 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending
290 WRITE_PAUSE 287 WRITE_PAUSE
291 or %l0, PSR_PIL, %l4 288 or %l0, PSR_PIL, %l4
292 wr %l4, 0x0, %psr 289 wr %l4, 0x0, %psr
@@ -304,16 +301,16 @@ linux_trap_ipi15_sun4m:
304 SAVE_ALL 301 SAVE_ALL
305 sethi %hi(0x80000000), %o2 302 sethi %hi(0x80000000), %o2
306 GET_PROCESSOR4M_ID(o0) 303 GET_PROCESSOR4M_ID(o0)
307 set sun4m_interrupts, %l5 304 sethi %hi(sun4m_irq_percpu), %l5
308 ld [%l5], %o5 305 or %l5, %lo(sun4m_irq_percpu), %o5
309 sll %o0, 12, %o0 306 sll %o0, 2, %o0
310 add %o5, %o0, %o5 307 ld [%o5 + %o0], %o5
311 ld [%o5], %o3 308 ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending
312 andcc %o3, %o2, %g0 309 andcc %o3, %o2, %g0
313 be 1f ! Must be an NMI async memory error 310 be 1f ! Must be an NMI async memory error
314 st %o2, [%o5 + 4] 311 st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000
315 WRITE_PAUSE 312 WRITE_PAUSE
316 ld [%o5], %g0 313 ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending
317 WRITE_PAUSE 314 WRITE_PAUSE
318 or %l0, PSR_PIL, %l4 315 or %l0, PSR_PIL, %l4
319 wr %l4, 0x0, %psr 316 wr %l4, 0x0, %psr
@@ -327,12 +324,11 @@ linux_trap_ipi15_sun4m:
3271: 3241:
328 /* NMI async memory error handling. */ 325 /* NMI async memory error handling. */
329 sethi %hi(0x80000000), %l4 326 sethi %hi(0x80000000), %l4
330 sethi %hi(0x4000), %o3 327 sethi %hi(sun4m_irq_global), %o5
331 sub %o5, %o0, %o5 328 ld [%o5 + %lo(sun4m_irq_global)], %l5
332 add %o5, %o3, %l5 329 st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000
333 st %l4, [%l5 + 0xc]
334 WRITE_PAUSE 330 WRITE_PAUSE
335 ld [%l5], %g0 331 ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending
336 WRITE_PAUSE 332 WRITE_PAUSE
337 or %l0, PSR_PIL, %l4 333 or %l0, PSR_PIL, %l4
338 wr %l4, 0x0, %psr 334 wr %l4, 0x0, %psr
@@ -341,9 +337,9 @@ linux_trap_ipi15_sun4m:
341 WRITE_PAUSE 337 WRITE_PAUSE
342 call sun4m_nmi 338 call sun4m_nmi
343 nop 339 nop
344 st %l4, [%l5 + 0x8] 340 st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000
345 WRITE_PAUSE 341 WRITE_PAUSE
346 ld [%l5], %g0 342 ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending
347 WRITE_PAUSE 343 WRITE_PAUSE
348 RESTORE_ALL 344 RESTORE_ALL
349 345
@@ -775,11 +771,7 @@ vac_linesize_patch_32: subcc %l7, 32, %l7
775 * Ugly, but we cant use hardware flushing on the sun4 and we'd require 771 * Ugly, but we cant use hardware flushing on the sun4 and we'd require
776 * two instructions (Anton) 772 * two instructions (Anton)
777 */ 773 */
778#ifdef CONFIG_SUN4
779vac_hwflush_patch1_on: nop
780#else
781vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 774vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7
782#endif
783 775
784vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG 776vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG
785 777
@@ -798,42 +790,10 @@ vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG
798! %l7 = 1 for textfault 790! %l7 = 1 for textfault
799! We want error in %l5, vaddr in %l6 791! We want error in %l5, vaddr in %l6
800sun4c_fault: 792sun4c_fault:
801#ifdef CONFIG_SUN4
802 sethi %hi(sun4c_memerr_reg), %l4
803 ld [%l4+%lo(sun4c_memerr_reg)], %l4 ! memerr ctrl reg addr
804 ld [%l4], %l6 ! memerr ctrl reg
805 ld [%l4 + 4], %l5 ! memerr vaddr reg
806 andcc %l6, 0x80, %g0 ! check for error type
807 st %g0, [%l4 + 4] ! clear the error
808 be 0f ! normal error
809 sethi %hi(AC_BUS_ERROR), %l4 ! bus err reg addr
810
811 call prom_halt ! something weird happened
812 ! what exactly did happen?
813 ! what should we do here?
814
8150: or %l4, %lo(AC_BUS_ERROR), %l4 ! bus err reg addr
816 lduba [%l4] ASI_CONTROL, %l6 ! bus err reg
817
818 cmp %l7, 1 ! text fault?
819 be 1f ! yes
820 nop
821
822 ld [%l1], %l4 ! load instruction that caused fault
823 srl %l4, 21, %l4
824 andcc %l4, 1, %g0 ! store instruction?
825
826 be 1f ! no
827 sethi %hi(SUN4C_SYNC_BADWRITE), %l4 ! yep
828 ! %lo(SUN4C_SYNC_BADWRITE) = 0
829 or %l4, %l6, %l6 ! set write bit to emulate sun4c
8301:
831#else
832 sethi %hi(AC_SYNC_ERR), %l4 793 sethi %hi(AC_SYNC_ERR), %l4
833 add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6 794 add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6
834 lda [%l6] ASI_CONTROL, %l5 ! Address 795 lda [%l6] ASI_CONTROL, %l5 ! Address
835 lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit 796 lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit
836#endif
837 797
838 andn %l5, 0xfff, %l5 ! Encode all info into l7 798 andn %l5, 0xfff, %l5 ! Encode all info into l7
839 srl %l6, 14, %l4 799 srl %l6, 14, %l4
@@ -880,12 +840,7 @@ sun4c_fault:
880 or %l4, %lo(swapper_pg_dir), %l4 840 or %l4, %lo(swapper_pg_dir), %l4
881 sll %l6, 2, %l6 841 sll %l6, 2, %l6
882 ld [%l4 + %l6], %l4 842 ld [%l4 + %l6], %l4
883#ifdef CONFIG_SUN4
884 sethi %hi(PAGE_MASK), %l6
885 andcc %l4, %l6, %g0
886#else
887 andcc %l4, PAGE_MASK, %g0 843 andcc %l4, PAGE_MASK, %g0
888#endif
889 be sun4c_fault_fromuser 844 be sun4c_fault_fromuser
890 lduXa [%l5] ASI_SEGMAP, %l4 845 lduXa [%l5] ASI_SEGMAP, %l4
891 846
@@ -937,11 +892,7 @@ invalid_segment_patch1:
937 ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr 892 ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr
938 893
939 ! Flush segment from the cache. 894 ! Flush segment from the cache.
940#ifdef CONFIG_SUN4
941 sethi %hi((128 * 1024)), %l7
942#else
943 sethi %hi((64 * 1024)), %l7 895 sethi %hi((64 * 1024)), %l7
944#endif
9459: 8969:
946vac_hwflush_patch1: 897vac_hwflush_patch1:
947vac_linesize_patch: 898vac_linesize_patch:
@@ -1029,12 +980,7 @@ invalid_segment_patch2:
1029 or %l4, %lo(swapper_pg_dir), %l4 980 or %l4, %lo(swapper_pg_dir), %l4
1030 sll %l3, 2, %l3 981 sll %l3, 2, %l3
1031 ld [%l4 + %l3], %l4 982 ld [%l4 + %l3], %l4
1032#ifndef CONFIG_SUN4
1033 and %l4, PAGE_MASK, %l4 983 and %l4, PAGE_MASK, %l4
1034#else
1035 sethi %hi(PAGE_MASK), %l6
1036 and %l4, %l6, %l4
1037#endif
1038 984
1039 srl %l5, (PAGE_SHIFT - 2), %l6 985 srl %l5, (PAGE_SHIFT - 2), %l6
1040 and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 986 and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6
diff --git a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S
index 50d9a16af795..2d325fd84579 100644
--- a/arch/sparc/kernel/head.S
+++ b/arch/sparc/kernel/head.S
@@ -63,15 +63,9 @@ cputypvar_sun4m:
63 63
64 .align 4 64 .align 4
65 65
66#ifndef CONFIG_SUN4
67sun4_notsup: 66sun4_notsup:
68 .asciz "Sparc-Linux sun4 needs a specially compiled kernel, turn CONFIG_SUN4 on.\n\n" 67 .asciz "Sparc-Linux sun4 support does no longer exist.\n\n"
69 .align 4 68 .align 4
70#else
71sun4cdm_notsup:
72 .asciz "Kernel compiled with CONFIG_SUN4 cannot run on SUN4C/SUN4M/SUN4D\nTurn CONFIG_SUN4 off.\n\n"
73 .align 4
74#endif
75 69
76sun4e_notsup: 70sun4e_notsup:
77 .asciz "Sparc-Linux sun4e support does not exist\n\n" 71 .asciz "Sparc-Linux sun4e support does not exist\n\n"
@@ -780,15 +774,6 @@ execute_in_high_mem:
780 nop 774 nop
781 775
782found_version: 776found_version:
783#ifdef CONFIG_SUN4
784/* For people who try sun4 kernels, even if Configure.help advises them. */
785 ld [%g7 + 0x68], %o1
786 set sun4cdm_notsup, %o0
787 call %o1
788 nop
789 b halt_me
790 nop
791#endif
792/* Get the machine type via the mysterious romvec node operations. */ 777/* Get the machine type via the mysterious romvec node operations. */
793 778
794 add %g7, 0x1c, %l1 779 add %g7, 0x1c, %l1
@@ -1150,15 +1135,6 @@ sun4c_continue_boot:
1150 nop 1135 nop
1151 1136
1152sun4_init: 1137sun4_init:
1153#ifdef CONFIG_SUN4
1154/* There, happy now Adrian? */
1155 set cputypval, %o2 ! Let everyone know we
1156 set ' ', %o0 ! are a "sun4 " architecture
1157 stb %o0, [%o2 + 0x4]
1158
1159 b got_prop
1160 nop
1161#else
1162 sethi %hi(SUN4_PROM_VECTOR+0x84), %o1 1138 sethi %hi(SUN4_PROM_VECTOR+0x84), %o1
1163 ld [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1 1139 ld [%o1 + %lo(SUN4_PROM_VECTOR+0x84)], %o1
1164 set sun4_notsup, %o0 1140 set sun4_notsup, %o0
@@ -1170,7 +1146,7 @@ sun4_init:
1170 nop 1146 nop
11711: ba 1b ! Cannot exit into KMON 11471: ba 1b ! Cannot exit into KMON
1172 nop 1148 nop
1173#endif 1149
1174no_sun4e_here: 1150no_sun4e_here:
1175 ld [%g7 + 0x68], %o1 1151 ld [%g7 + 0x68], %o1
1176 set sun4e_notsup, %o0 1152 set sun4e_notsup, %o0
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
index fc511f3c4c18..223a6582e1e2 100644
--- a/arch/sparc/kernel/idprom.c
+++ b/arch/sparc/kernel/idprom.c
@@ -12,10 +12,6 @@
12#include <asm/oplib.h> 12#include <asm/oplib.h>
13#include <asm/idprom.h> 13#include <asm/idprom.h>
14#include <asm/machines.h> /* Fun with Sun released architectures. */ 14#include <asm/machines.h> /* Fun with Sun released architectures. */
15#ifdef CONFIG_SUN4
16#include <asm/sun4paddr.h>
17extern void sun4setup(void);
18#endif
19 15
20struct idprom *idprom; 16struct idprom *idprom;
21static struct idprom idprom_buffer; 17static struct idprom idprom_buffer;
@@ -101,7 +97,4 @@ void __init idprom_init(void)
101 idprom->id_ethaddr[0], idprom->id_ethaddr[1], 97 idprom->id_ethaddr[0], idprom->id_ethaddr[1],
102 idprom->id_ethaddr[2], idprom->id_ethaddr[3], 98 idprom->id_ethaddr[2], idprom->id_ethaddr[3],
103 idprom->id_ethaddr[4], idprom->id_ethaddr[5]); 99 idprom->id_ethaddr[4], idprom->id_ethaddr[5]);
104#ifdef CONFIG_SUN4
105 sun4setup();
106#endif
107} 100}
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 2a8a847764d8..4f025b36934b 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -42,10 +42,13 @@
42#include <asm/vaddrs.h> 42#include <asm/vaddrs.h>
43#include <asm/oplib.h> 43#include <asm/oplib.h>
44#include <asm/prom.h> 44#include <asm/prom.h>
45#include <asm/sbus.h>
46#include <asm/page.h> 45#include <asm/page.h>
47#include <asm/pgalloc.h> 46#include <asm/pgalloc.h>
48#include <asm/dma.h> 47#include <asm/dma.h>
48#include <asm/iommu.h>
49#include <asm/io-unit.h>
50
51#include "dma.h"
49 52
50#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ 53#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */
51 54
@@ -139,15 +142,6 @@ void iounmap(volatile void __iomem *virtual)
139 } 142 }
140} 143}
141 144
142/*
143 */
144void __iomem *sbus_ioremap(struct resource *phyres, unsigned long offset,
145 unsigned long size, char *name)
146{
147 return _sparc_alloc_io(phyres->flags & 0xF,
148 phyres->start + offset, size, name);
149}
150
151void __iomem *of_ioremap(struct resource *res, unsigned long offset, 145void __iomem *of_ioremap(struct resource *res, unsigned long offset,
152 unsigned long size, char *name) 146 unsigned long size, char *name)
153{ 147{
@@ -164,13 +158,6 @@ void of_iounmap(struct resource *res, void __iomem *base, unsigned long size)
164EXPORT_SYMBOL(of_iounmap); 158EXPORT_SYMBOL(of_iounmap);
165 159
166/* 160/*
167 */
168void sbus_iounmap(volatile void __iomem *addr, unsigned long size)
169{
170 iounmap(addr);
171}
172
173/*
174 * Meat of mapping 161 * Meat of mapping
175 */ 162 */
176static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, 163static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
@@ -246,63 +233,19 @@ static void _sparc_free_io(struct resource *res)
246 233
247#ifdef CONFIG_SBUS 234#ifdef CONFIG_SBUS
248 235
249void sbus_set_sbus64(struct sbus_dev *sdev, int x) 236void sbus_set_sbus64(struct device *dev, int x)
250{ 237{
251 printk("sbus_set_sbus64: unsupported\n"); 238 printk("sbus_set_sbus64: unsupported\n");
252} 239}
253 240
254extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
255void __init sbus_fill_device_irq(struct sbus_dev *sdev)
256{
257 struct linux_prom_irqs irqs[PROMINTR_MAX];
258 int len;
259
260 len = prom_getproperty(sdev->prom_node, "intr",
261 (char *)irqs, sizeof(irqs));
262 if (len != -1) {
263 sdev->num_irqs = len / 8;
264 if (sdev->num_irqs == 0) {
265 sdev->irqs[0] = 0;
266 } else if (sparc_cpu_model == sun4d) {
267 for (len = 0; len < sdev->num_irqs; len++)
268 sdev->irqs[len] =
269 sun4d_build_irq(sdev, irqs[len].pri);
270 } else {
271 for (len = 0; len < sdev->num_irqs; len++)
272 sdev->irqs[len] = irqs[len].pri;
273 }
274 } else {
275 int interrupts[PROMINTR_MAX];
276
277 /* No "intr" node found-- check for "interrupts" node.
278 * This node contains SBus interrupt levels, not IPLs
279 * as in "intr", and no vector values. We convert
280 * SBus interrupt levels to PILs (platform specific).
281 */
282 len = prom_getproperty(sdev->prom_node, "interrupts",
283 (char *)interrupts, sizeof(interrupts));
284 if (len == -1) {
285 sdev->irqs[0] = 0;
286 sdev->num_irqs = 0;
287 } else {
288 sdev->num_irqs = len / sizeof(int);
289 for (len = 0; len < sdev->num_irqs; len++) {
290 sdev->irqs[len] =
291 sbint_to_irq(sdev, interrupts[len]);
292 }
293 }
294 }
295}
296
297/* 241/*
298 * Allocate a chunk of memory suitable for DMA. 242 * Allocate a chunk of memory suitable for DMA.
299 * Typically devices use them for control blocks. 243 * Typically devices use them for control blocks.
300 * CPU may access them without any explicit flushing. 244 * CPU may access them without any explicit flushing.
301 *
302 * XXX Some clever people know that sdev is not used and supply NULL. Watch.
303 */ 245 */
304void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) 246void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp)
305{ 247{
248 struct of_device *op = to_of_device(dev);
306 unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK; 249 unsigned long len_total = (len + PAGE_SIZE-1) & PAGE_MASK;
307 unsigned long va; 250 unsigned long va;
308 struct resource *res; 251 struct resource *res;
@@ -336,13 +279,10 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp)
336 * XXX That's where sdev would be used. Currently we load 279 * XXX That's where sdev would be used. Currently we load
337 * all iommu tables with the same translations. 280 * all iommu tables with the same translations.
338 */ 281 */
339 if (mmu_map_dma_area(dma_addrp, va, res->start, len_total) != 0) 282 if (mmu_map_dma_area(dev, dma_addrp, va, res->start, len_total) != 0)
340 goto err_noiommu; 283 goto err_noiommu;
341 284
342 /* Set the resource name, if known. */ 285 res->name = op->node->name;
343 if (sdev) {
344 res->name = sdev->prom_name;
345 }
346 286
347 return (void *)(unsigned long)res->start; 287 return (void *)(unsigned long)res->start;
348 288
@@ -356,7 +296,7 @@ err_nopages:
356 return NULL; 296 return NULL;
357} 297}
358 298
359void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba) 299void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba)
360{ 300{
361 struct resource *res; 301 struct resource *res;
362 struct page *pgv; 302 struct page *pgv;
@@ -383,8 +323,8 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)
383 kfree(res); 323 kfree(res);
384 324
385 /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */ 325 /* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */
386 pgv = mmu_translate_dvma(ba); 326 pgv = virt_to_page(p);
387 mmu_unmap_dma_area(ba, n); 327 mmu_unmap_dma_area(dev, ba, n);
388 328
389 __free_pages(pgv, get_order(n)); 329 __free_pages(pgv, get_order(n));
390} 330}
@@ -394,7 +334,7 @@ void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba)
394 * CPU view of this memory may be inconsistent with 334 * CPU view of this memory may be inconsistent with
395 * a device view and explicit flushing is necessary. 335 * a device view and explicit flushing is necessary.
396 */ 336 */
397dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int direction) 337dma_addr_t sbus_map_single(struct device *dev, void *va, size_t len, int direction)
398{ 338{
399 /* XXX why are some lengths signed, others unsigned? */ 339 /* XXX why are some lengths signed, others unsigned? */
400 if (len <= 0) { 340 if (len <= 0) {
@@ -404,17 +344,17 @@ dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int dire
404 if (len > 256*1024) { /* __get_free_pages() limit */ 344 if (len > 256*1024) { /* __get_free_pages() limit */
405 return 0; 345 return 0;
406 } 346 }
407 return mmu_get_scsi_one(va, len, sdev->bus); 347 return mmu_get_scsi_one(dev, va, len);
408} 348}
409 349
410void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t ba, size_t n, int direction) 350void sbus_unmap_single(struct device *dev, dma_addr_t ba, size_t n, int direction)
411{ 351{
412 mmu_release_scsi_one(ba, n, sdev->bus); 352 mmu_release_scsi_one(dev, ba, n);
413} 353}
414 354
415int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) 355int sbus_map_sg(struct device *dev, struct scatterlist *sg, int n, int direction)
416{ 356{
417 mmu_get_scsi_sgl(sg, n, sdev->bus); 357 mmu_get_scsi_sgl(dev, sg, n);
418 358
419 /* 359 /*
420 * XXX sparc64 can return a partial length here. sun4c should do this 360 * XXX sparc64 can return a partial length here. sun4c should do this
@@ -423,145 +363,28 @@ int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direct
423 return n; 363 return n;
424} 364}
425 365
426void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) 366void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, int n, int direction)
427{
428 mmu_release_scsi_sgl(sg, n, sdev->bus);
429}
430
431/*
432 */
433void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction)
434{
435#if 0
436 unsigned long va;
437 struct resource *res;
438
439 /* We do not need the resource, just print a message if invalid. */
440 res = _sparc_find_resource(&_sparc_dvma, ba);
441 if (res == NULL)
442 panic("sbus_dma_sync_single: 0x%x\n", ba);
443
444 va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */
445 /*
446 * XXX This bogosity will be fixed with the iommu rewrite coming soon
447 * to a kernel near you. - Anton
448 */
449 /* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */
450#endif
451}
452
453void sbus_dma_sync_single_for_device(struct sbus_dev *sdev, dma_addr_t ba, size_t size, int direction)
454{ 367{
455#if 0 368 mmu_release_scsi_sgl(dev, sg, n);
456 unsigned long va;
457 struct resource *res;
458
459 /* We do not need the resource, just print a message if invalid. */
460 res = _sparc_find_resource(&_sparc_dvma, ba);
461 if (res == NULL)
462 panic("sbus_dma_sync_single: 0x%x\n", ba);
463
464 va = page_address(mmu_translate_dvma(ba)); /* XXX higmem */
465 /*
466 * XXX This bogosity will be fixed with the iommu rewrite coming soon
467 * to a kernel near you. - Anton
468 */
469 /* mmu_inval_dma_area(va, (size + PAGE_SIZE-1) & PAGE_MASK); */
470#endif
471} 369}
472 370
473void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) 371void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, size_t size, int direction)
474{ 372{
475 printk("sbus_dma_sync_sg_for_cpu: not implemented yet\n");
476} 373}
477 374
478void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) 375void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t size, int direction)
479{ 376{
480 printk("sbus_dma_sync_sg_for_device: not implemented yet\n");
481}
482
483/* Support code for sbus_init(). */
484/*
485 * XXX This functions appears to be a distorted version of
486 * prom_sbus_ranges_init(), with all sun4d stuff cut away.
487 * Ask DaveM what is going on here, how is sun4d supposed to work... XXX
488 */
489/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */
490void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus)
491{
492 int parent_node = pn->node;
493
494 if (sparc_cpu_model == sun4d) {
495 struct linux_prom_ranges iounit_ranges[PROMREG_MAX];
496 int num_iounit_ranges, len;
497
498 len = prom_getproperty(parent_node, "ranges",
499 (char *) iounit_ranges,
500 sizeof (iounit_ranges));
501 if (len != -1) {
502 num_iounit_ranges =
503 (len / sizeof(struct linux_prom_ranges));
504 prom_adjust_ranges(sbus->sbus_ranges,
505 sbus->num_sbus_ranges,
506 iounit_ranges, num_iounit_ranges);
507 }
508 }
509} 377}
510 378
511void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) 379static int __init sparc_register_ioport(void)
512{
513#ifndef CONFIG_SUN4
514 struct device_node *parent = dp->parent;
515
516 if (sparc_cpu_model != sun4d &&
517 parent != NULL &&
518 !strcmp(parent->name, "iommu")) {
519 extern void iommu_init(int iommu_node, struct sbus_bus *sbus);
520
521 iommu_init(parent->node, sbus);
522 }
523
524 if (sparc_cpu_model == sun4d) {
525 extern void iounit_init(int sbi_node, int iounit_node,
526 struct sbus_bus *sbus);
527
528 iounit_init(dp->node, parent->node, sbus);
529 }
530#endif
531}
532
533void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
534{
535 if (sparc_cpu_model == sun4d) {
536 struct device_node *parent = dp->parent;
537
538 sbus->devid = of_getintprop_default(parent, "device-id", 0);
539 sbus->board = of_getintprop_default(parent, "board#", 0);
540 }
541}
542
543int __init sbus_arch_preinit(void)
544{ 380{
545 register_proc_sparc_ioport(); 381 register_proc_sparc_ioport();
546 382
547#ifdef CONFIG_SUN4
548 {
549 extern void sun4_dvma_init(void);
550 sun4_dvma_init();
551 }
552 return 1;
553#else
554 return 0; 383 return 0;
555#endif
556} 384}
557 385
558void __init sbus_arch_postinit(void) 386arch_initcall(sparc_register_ioport);
559{ 387
560 if (sparc_cpu_model == sun4d) {
561 extern void sun4d_init_sbi_irq(void);
562 sun4d_init_sbi_irq();
563 }
564}
565#endif /* CONFIG_SBUS */ 388#endif /* CONFIG_SBUS */
566 389
567#ifdef CONFIG_PCI 390#ifdef CONFIG_PCI
diff --git a/arch/sparc/kernel/irq.h b/arch/sparc/kernel/irq.h
index 32ef3ebd0a88..db7513881530 100644
--- a/arch/sparc/kernel/irq.h
+++ b/arch/sparc/kernel/irq.h
@@ -13,7 +13,6 @@ BTFIXUPDEF_CALL(void, enable_irq, unsigned int)
13BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int) 13BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int)
14BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int) 14BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int)
15BTFIXUPDEF_CALL(void, clear_clock_irq, void) 15BTFIXUPDEF_CALL(void, clear_clock_irq, void)
16BTFIXUPDEF_CALL(void, clear_profile_irq, int)
17BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) 16BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
18 17
19static inline void __disable_irq(unsigned int irq) 18static inline void __disable_irq(unsigned int irq)
@@ -41,11 +40,6 @@ static inline void clear_clock_irq(void)
41 BTFIXUP_CALL(clear_clock_irq)(); 40 BTFIXUP_CALL(clear_clock_irq)();
42} 41}
43 42
44static inline void clear_profile_irq(int irq)
45{
46 BTFIXUP_CALL(clear_profile_irq)(irq);
47}
48
49static inline void load_profile_irq(int cpu, int limit) 43static inline void load_profile_irq(int cpu, int limit)
50{ 44{
51 BTFIXUP_CALL(load_profile_irq)(cpu, limit); 45 BTFIXUP_CALL(load_profile_irq)(cpu, limit);
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index f58c537446a8..0837bd52e28f 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -29,15 +29,38 @@ struct of_device *of_find_device_by_node(struct device_node *dp)
29} 29}
30EXPORT_SYMBOL(of_find_device_by_node); 30EXPORT_SYMBOL(of_find_device_by_node);
31 31
32#ifdef CONFIG_PCI 32unsigned int irq_of_parse_and_map(struct device_node *node, int index)
33struct bus_type ebus_bus_type; 33{
34EXPORT_SYMBOL(ebus_bus_type); 34 struct of_device *op = of_find_device_by_node(node);
35#endif 35
36 if (!op || index >= op->num_irqs)
37 return 0;
38
39 return op->irqs[index];
40}
41EXPORT_SYMBOL(irq_of_parse_and_map);
42
43/* Take the archdata values for IOMMU, STC, and HOSTDATA found in
44 * BUS and propagate to all child of_device objects.
45 */
46void of_propagate_archdata(struct of_device *bus)
47{
48 struct dev_archdata *bus_sd = &bus->dev.archdata;
49 struct device_node *bus_dp = bus->node;
50 struct device_node *dp;
51
52 for (dp = bus_dp->child; dp; dp = dp->sibling) {
53 struct of_device *op = of_find_device_by_node(dp);
36 54
37#ifdef CONFIG_SBUS 55 op->dev.archdata.iommu = bus_sd->iommu;
38struct bus_type sbus_bus_type; 56 op->dev.archdata.stc = bus_sd->stc;
39EXPORT_SYMBOL(sbus_bus_type); 57 op->dev.archdata.host_controller = bus_sd->host_controller;
40#endif 58 op->dev.archdata.numa_node = bus_sd->numa_node;
59
60 if (dp->child)
61 of_propagate_archdata(op);
62 }
63}
41 64
42struct bus_type of_platform_bus_type; 65struct bus_type of_platform_bus_type;
43EXPORT_SYMBOL(of_platform_bus_type); 66EXPORT_SYMBOL(of_platform_bus_type);
@@ -327,6 +350,27 @@ static int __init build_one_resource(struct device_node *parent,
327 return 1; 350 return 1;
328} 351}
329 352
353static int __init use_1to1_mapping(struct device_node *pp)
354{
355 /* If we have a ranges property in the parent, use it. */
356 if (of_find_property(pp, "ranges", NULL) != NULL)
357 return 0;
358
359 /* Some SBUS devices use intermediate nodes to express
360 * hierarchy within the device itself. These aren't
361 * real bus nodes, and don't have a 'ranges' property.
362 * But, we should still pass the translation work up
363 * to the SBUS itself.
364 */
365 if (!strcmp(pp->name, "dma") ||
366 !strcmp(pp->name, "espdma") ||
367 !strcmp(pp->name, "ledma") ||
368 !strcmp(pp->name, "lebuffer"))
369 return 0;
370
371 return 1;
372}
373
330static int of_resource_verbose; 374static int of_resource_verbose;
331 375
332static void __init build_device_resources(struct of_device *op, 376static void __init build_device_resources(struct of_device *op,
@@ -373,10 +417,7 @@ static void __init build_device_resources(struct of_device *op,
373 417
374 flags = bus->get_flags(reg, 0); 418 flags = bus->get_flags(reg, 0);
375 419
376 /* If the immediate parent has no ranges property to apply, 420 if (use_1to1_mapping(pp)) {
377 * just use a 1<->1 mapping.
378 */
379 if (of_find_property(pp, "ranges", NULL) == NULL) {
380 result = of_read_addr(addr, na); 421 result = of_read_addr(addr, na);
381 goto build_res; 422 goto build_res;
382 } 423 }
@@ -565,15 +606,6 @@ static int __init of_bus_driver_init(void)
565 int err; 606 int err;
566 607
567 err = of_bus_type_init(&of_platform_bus_type, "of"); 608 err = of_bus_type_init(&of_platform_bus_type, "of");
568#ifdef CONFIG_PCI
569 if (!err)
570 err = of_bus_type_init(&ebus_bus_type, "ebus");
571#endif
572#ifdef CONFIG_SBUS
573 if (!err)
574 err = of_bus_type_init(&sbus_bus_type, "sbus");
575#endif
576
577 if (!err) 609 if (!err)
578 scan_of_devices(); 610 scan_of_devices();
579 611
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index a6a6f9823370..462584e55fba 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -17,8 +17,6 @@
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/jiffies.h> 18#include <linux/jiffies.h>
19 19
20#include <asm/ebus.h>
21#include <asm/sbus.h> /* for sanity check... */
22#include <asm/swift.h> /* for cache flushing. */ 20#include <asm/swift.h> /* for cache flushing. */
23#include <asm/io.h> 21#include <asm/io.h>
24 22
@@ -430,7 +428,6 @@ static int __init pcic_init(void)
430 428
431 pcic_pbm_scan_bus(pcic); 429 pcic_pbm_scan_bus(pcic);
432 430
433 ebus_init();
434 return 0; 431 return 0;
435} 432}
436 433
@@ -493,10 +490,6 @@ static void pcic_map_pci_device(struct linux_pcic *pcic,
493 * do ioremap() before accessing PC-style I/O, 490 * do ioremap() before accessing PC-style I/O,
494 * we supply virtual, ready to access address. 491 * we supply virtual, ready to access address.
495 * 492 *
496 * Ebus devices do not come here even if
497 * CheerIO makes a similar conversion.
498 * See ebus.c for details.
499 *
500 * Note that request_region() 493 * Note that request_region()
501 * works for these devices. 494 * works for these devices.
502 * 495 *
@@ -677,7 +670,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
677} 670}
678 671
679/* 672/*
680 * pcic_pin_to_irq() is exported to ebus.c. 673 * pcic_pin_to_irq() is exported to bus probing code
681 */ 674 */
682unsigned int 675unsigned int
683pcic_pin_to_irq(unsigned int pin, const char *name) 676pcic_pin_to_irq(unsigned int pin, const char *name)
@@ -904,11 +897,6 @@ static void pcic_enable_irq(unsigned int irq_nr)
904 local_irq_restore(flags); 897 local_irq_restore(flags);
905} 898}
906 899
907static void pcic_clear_profile_irq(int cpu)
908{
909 printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
910}
911
912static void pcic_load_profile_irq(int cpu, unsigned int limit) 900static void pcic_load_profile_irq(int cpu, unsigned int limit)
913{ 901{
914 printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__); 902 printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
@@ -934,7 +922,6 @@ void __init sun4m_pci_init_IRQ(void)
934 BTFIXUPSET_CALL(enable_pil_irq, pcic_enable_pil_irq, BTFIXUPCALL_NORM); 922 BTFIXUPSET_CALL(enable_pil_irq, pcic_enable_pil_irq, BTFIXUPCALL_NORM);
935 BTFIXUPSET_CALL(disable_pil_irq, pcic_disable_pil_irq, BTFIXUPCALL_NORM); 923 BTFIXUPSET_CALL(disable_pil_irq, pcic_disable_pil_irq, BTFIXUPCALL_NORM);
936 BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM); 924 BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM);
937 BTFIXUPSET_CALL(clear_profile_irq, pcic_clear_profile_irq, BTFIXUPCALL_NORM);
938 BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM); 925 BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM);
939} 926}
940 927
diff --git a/arch/sparc/kernel/pmc.c b/arch/sparc/kernel/pmc.c
index 7eca8871ff47..2afcfab4f11c 100644
--- a/arch/sparc/kernel/pmc.c
+++ b/arch/sparc/kernel/pmc.c
@@ -8,11 +8,11 @@
8#include <linux/fs.h> 8#include <linux/fs.h>
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/miscdevice.h>
12#include <linux/pm.h> 11#include <linux/pm.h>
12#include <linux/of.h>
13#include <linux/of_device.h>
13 14
14#include <asm/io.h> 15#include <asm/io.h>
15#include <asm/sbus.h>
16#include <asm/oplib.h> 16#include <asm/oplib.h>
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18#include <asm/auxio.h> 18#include <asm/auxio.h>
@@ -23,17 +23,15 @@
23 * #define PMC_NO_IDLE 23 * #define PMC_NO_IDLE
24 */ 24 */
25 25
26#define PMC_MINOR MISC_DYNAMIC_MINOR
27#define PMC_OBPNAME "SUNW,pmc" 26#define PMC_OBPNAME "SUNW,pmc"
28#define PMC_DEVNAME "pmc" 27#define PMC_DEVNAME "pmc"
29 28
30#define PMC_IDLE_REG 0x00 29#define PMC_IDLE_REG 0x00
31#define PMC_IDLE_ON 0x01 30#define PMC_IDLE_ON 0x01
32 31
33volatile static u8 __iomem *regs; 32static u8 __iomem *regs;
34static int pmc_regsize;
35 33
36#define pmc_readb(offs) (sbus_readb(regs+offs)) 34#define pmc_readb(offs) (sbus_readb(regs+offs))
37#define pmc_writeb(val, offs) (sbus_writeb(val, regs+offs)) 35#define pmc_writeb(val, offs) (sbus_writeb(val, regs+offs))
38 36
39/* 37/*
@@ -53,31 +51,11 @@ void pmc_swift_idle(void)
53#endif 51#endif
54} 52}
55 53
56static inline void pmc_free(void) 54static int __devinit pmc_probe(struct of_device *op,
55 const struct of_device_id *match)
57{ 56{
58 sbus_iounmap(regs, pmc_regsize); 57 regs = of_ioremap(&op->resource[0], 0,
59} 58 resource_size(&op->resource[0]), PMC_OBPNAME);
60
61static int __init pmc_probe(void)
62{
63 struct sbus_bus *sbus = NULL;
64 struct sbus_dev *sdev = NULL;
65 for_each_sbus(sbus) {
66 for_each_sbusdev(sdev, sbus) {
67 if (!strcmp(sdev->prom_name, PMC_OBPNAME)) {
68 goto sbus_done;
69 }
70 }
71 }
72
73sbus_done:
74 if (!sdev) {
75 return -ENODEV;
76 }
77
78 pmc_regsize = sdev->reg_addrs[0].reg_size;
79 regs = sbus_ioremap(&sdev->resource[0], 0,
80 pmc_regsize, PMC_OBPNAME);
81 if (!regs) { 59 if (!regs) {
82 printk(KERN_ERR "%s: unable to map registers\n", PMC_DEVNAME); 60 printk(KERN_ERR "%s: unable to map registers\n", PMC_DEVNAME);
83 return -ENODEV; 61 return -ENODEV;
@@ -92,8 +70,27 @@ sbus_done:
92 return 0; 70 return 0;
93} 71}
94 72
73static struct of_device_id __initdata pmc_match[] = {
74 {
75 .name = PMC_OBPNAME,
76 },
77 {},
78};
79MODULE_DEVICE_TABLE(of, pmc_match);
80
81static struct of_platform_driver pmc_driver = {
82 .name = "pmc",
83 .match_table = pmc_match,
84 .probe = pmc_probe,
85};
86
87static int __init pmc_init(void)
88{
89 return of_register_driver(&pmc_driver, &of_bus_type);
90}
91
95/* This driver is not critical to the boot process 92/* This driver is not critical to the boot process
96 * and is easiest to ioremap when SBus is already 93 * and is easiest to ioremap when SBus is already
97 * initialized, so we install ourselves thusly: 94 * initialized, so we install ourselves thusly:
98 */ 95 */
99__initcall(pmc_probe); 96__initcall(pmc_init);
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 4bb430940a61..e8c43ffe317e 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -75,7 +75,7 @@ void cpu_idle(void)
75{ 75{
76 /* endless idle loop with no priority at all */ 76 /* endless idle loop with no priority at all */
77 for (;;) { 77 for (;;) {
78 if (ARCH_SUN4C_SUN4) { 78 if (ARCH_SUN4C) {
79 static int count = HZ; 79 static int count = HZ;
80 static unsigned long last_jiffies; 80 static unsigned long last_jiffies;
81 static unsigned long last_faults; 81 static unsigned long last_faults;
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
index cd4fb79aa3a8..eee5efcfe50e 100644
--- a/arch/sparc/kernel/prom.c
+++ b/arch/sparc/kernel/prom.c
@@ -54,6 +54,9 @@ int of_getintprop_default(struct device_node *np, const char *name, int def)
54} 54}
55EXPORT_SYMBOL(of_getintprop_default); 55EXPORT_SYMBOL(of_getintprop_default);
56 56
57DEFINE_MUTEX(of_set_property_mutex);
58EXPORT_SYMBOL(of_set_property_mutex);
59
57int of_set_property(struct device_node *dp, const char *name, void *val, int len) 60int of_set_property(struct device_node *dp, const char *name, void *val, int len)
58{ 61{
59 struct property **prevp; 62 struct property **prevp;
@@ -77,7 +80,10 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
77 void *old_val = prop->value; 80 void *old_val = prop->value;
78 int ret; 81 int ret;
79 82
83 mutex_lock(&of_set_property_mutex);
80 ret = prom_setprop(dp->node, (char *) name, val, len); 84 ret = prom_setprop(dp->node, (char *) name, val, len);
85 mutex_unlock(&of_set_property_mutex);
86
81 err = -EINVAL; 87 err = -EINVAL;
82 if (ret >= 0) { 88 if (ret >= 0) {
83 prop->value = new_val; 89 prop->value = new_val;
@@ -436,7 +442,6 @@ static void __init of_console_init(void)
436 442
437 switch (prom_vers) { 443 switch (prom_vers) {
438 case PROM_V0: 444 case PROM_V0:
439 case PROM_SUN4:
440 skip = 0; 445 skip = 0;
441 switch (*romvec->pv_stdout) { 446 switch (*romvec->pv_stdout) {
442 case PROMDEV_SCREEN: 447 case PROMDEV_SCREEN:
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 9e451b21202e..24fe3078bd4b 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -213,23 +213,25 @@ void __init setup_arch(char **cmdline_p)
213 /* Initialize PROM console and command line. */ 213 /* Initialize PROM console and command line. */
214 *cmdline_p = prom_getbootargs(); 214 *cmdline_p = prom_getbootargs();
215 strcpy(boot_command_line, *cmdline_p); 215 strcpy(boot_command_line, *cmdline_p);
216 parse_early_param();
216 217
217 /* Set sparc_cpu_model */ 218 /* Set sparc_cpu_model */
218 sparc_cpu_model = sun_unknown; 219 sparc_cpu_model = sun_unknown;
219 if(!strcmp(&cputypval,"sun4 ")) { sparc_cpu_model=sun4; } 220 if (!strcmp(&cputypval,"sun4 "))
220 if(!strcmp(&cputypval,"sun4c")) { sparc_cpu_model=sun4c; } 221 sparc_cpu_model = sun4;
221 if(!strcmp(&cputypval,"sun4m")) { sparc_cpu_model=sun4m; } 222 if (!strcmp(&cputypval,"sun4c"))
222 if(!strcmp(&cputypval,"sun4s")) { sparc_cpu_model=sun4m; } /* CP-1200 with PROM 2.30 -E */ 223 sparc_cpu_model = sun4c;
223 if(!strcmp(&cputypval,"sun4d")) { sparc_cpu_model=sun4d; } 224 if (!strcmp(&cputypval,"sun4m"))
224 if(!strcmp(&cputypval,"sun4e")) { sparc_cpu_model=sun4e; } 225 sparc_cpu_model = sun4m;
225 if(!strcmp(&cputypval,"sun4u")) { sparc_cpu_model=sun4u; } 226 if (!strcmp(&cputypval,"sun4s"))
226 227 sparc_cpu_model = sun4m; /* CP-1200 with PROM 2.30 -E */
227#ifdef CONFIG_SUN4 228 if (!strcmp(&cputypval,"sun4d"))
228 if (sparc_cpu_model != sun4) { 229 sparc_cpu_model = sun4d;
229 prom_printf("This kernel is for Sun4 architecture only.\n"); 230 if (!strcmp(&cputypval,"sun4e"))
230 prom_halt(); 231 sparc_cpu_model = sun4e;
231 } 232 if (!strcmp(&cputypval,"sun4u"))
232#endif 233 sparc_cpu_model = sun4u;
234
233 printk("ARCH: "); 235 printk("ARCH: ");
234 switch(sparc_cpu_model) { 236 switch(sparc_cpu_model) {
235 case sun4: 237 case sun4:
@@ -263,7 +265,7 @@ void __init setup_arch(char **cmdline_p)
263 boot_flags_init(*cmdline_p); 265 boot_flags_init(*cmdline_p);
264 266
265 idprom_init(); 267 idprom_init();
266 if (ARCH_SUN4C_SUN4) 268 if (ARCH_SUN4C)
267 sun4c_probe_vac(); 269 sun4c_probe_vac();
268 load_mmu(); 270 load_mmu();
269 271
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index b23cea5ca5d1..b0dfff848653 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -38,17 +38,12 @@
38#include <asm/idprom.h> 38#include <asm/idprom.h>
39#include <asm/head.h> 39#include <asm/head.h>
40#include <asm/smp.h> 40#include <asm/smp.h>
41#include <asm/mostek.h>
42#include <asm/ptrace.h> 41#include <asm/ptrace.h>
43#include <asm/uaccess.h> 42#include <asm/uaccess.h>
44#include <asm/checksum.h> 43#include <asm/checksum.h>
45#ifdef CONFIG_SBUS 44#ifdef CONFIG_SBUS
46#include <asm/sbus.h>
47#include <asm/dma.h> 45#include <asm/dma.h>
48#endif 46#endif
49#ifdef CONFIG_PCI
50#include <asm/ebus.h>
51#endif
52#include <asm/io-unit.h> 47#include <asm/io-unit.h>
53#include <asm/bug.h> 48#include <asm/bug.h>
54 49
@@ -127,16 +122,11 @@ EXPORT_SYMBOL(phys_cpu_present_map);
127EXPORT_SYMBOL(__udelay); 122EXPORT_SYMBOL(__udelay);
128EXPORT_SYMBOL(__ndelay); 123EXPORT_SYMBOL(__ndelay);
129EXPORT_SYMBOL(rtc_lock); 124EXPORT_SYMBOL(rtc_lock);
130EXPORT_SYMBOL(mostek_lock);
131EXPORT_SYMBOL(mstk48t02_regs);
132#ifdef CONFIG_SUN_AUXIO 125#ifdef CONFIG_SUN_AUXIO
133EXPORT_SYMBOL(set_auxio); 126EXPORT_SYMBOL(set_auxio);
134EXPORT_SYMBOL(get_auxio); 127EXPORT_SYMBOL(get_auxio);
135#endif 128#endif
136EXPORT_SYMBOL(io_remap_pfn_range); 129EXPORT_SYMBOL(io_remap_pfn_range);
137 /* P3: iounit_xxx may be needed, sun4d users */
138/* EXPORT_SYMBOL(iounit_map_dma_init); */
139/* EXPORT_SYMBOL(iounit_map_dma_page); */
140 130
141#ifndef CONFIG_SMP 131#ifndef CONFIG_SMP
142EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); 132EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32));
@@ -153,24 +143,9 @@ EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one));
153EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached)); 143EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached));
154 144
155#ifdef CONFIG_SBUS 145#ifdef CONFIG_SBUS
156EXPORT_SYMBOL(sbus_root);
157EXPORT_SYMBOL(dma_chain);
158EXPORT_SYMBOL(sbus_set_sbus64); 146EXPORT_SYMBOL(sbus_set_sbus64);
159EXPORT_SYMBOL(sbus_alloc_consistent);
160EXPORT_SYMBOL(sbus_free_consistent);
161EXPORT_SYMBOL(sbus_map_single);
162EXPORT_SYMBOL(sbus_unmap_single);
163EXPORT_SYMBOL(sbus_map_sg);
164EXPORT_SYMBOL(sbus_unmap_sg);
165EXPORT_SYMBOL(sbus_dma_sync_single_for_cpu);
166EXPORT_SYMBOL(sbus_dma_sync_single_for_device);
167EXPORT_SYMBOL(sbus_dma_sync_sg_for_cpu);
168EXPORT_SYMBOL(sbus_dma_sync_sg_for_device);
169EXPORT_SYMBOL(sbus_iounmap);
170EXPORT_SYMBOL(sbus_ioremap);
171#endif 147#endif
172#ifdef CONFIG_PCI 148#ifdef CONFIG_PCI
173EXPORT_SYMBOL(ebus_chain);
174EXPORT_SYMBOL(insb); 149EXPORT_SYMBOL(insb);
175EXPORT_SYMBOL(outsb); 150EXPORT_SYMBOL(outsb);
176EXPORT_SYMBOL(insw); 151EXPORT_SYMBOL(insw);
diff --git a/arch/sparc/kernel/sun4c_irq.c b/arch/sparc/kernel/sun4c_irq.c
index 340fc395fe2d..5dc8a5769489 100644
--- a/arch/sparc/kernel/sun4c_irq.c
+++ b/arch/sparc/kernel/sun4c_irq.c
@@ -18,6 +18,8 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
21#include "irq.h" 23#include "irq.h"
22 24
23#include <asm/ptrace.h> 25#include <asm/ptrace.h>
@@ -31,15 +33,8 @@
31#include <asm/traps.h> 33#include <asm/traps.h>
32#include <asm/irq.h> 34#include <asm/irq.h>
33#include <asm/io.h> 35#include <asm/io.h>
34#include <asm/sun4paddr.h>
35#include <asm/idprom.h> 36#include <asm/idprom.h>
36#include <asm/machines.h> 37#include <asm/machines.h>
37#include <asm/sbus.h>
38
39#if 0
40static struct resource sun4c_timer_eb = { "sun4c_timer" };
41static struct resource sun4c_intr_eb = { "sun4c_intr" };
42#endif
43 38
44/* 39/*
45 * Bit field defines for the interrupt registers on various 40 * Bit field defines for the interrupt registers on various
@@ -64,19 +59,7 @@ static struct resource sun4c_intr_eb = { "sun4c_intr" };
64 * 59 *
65 * so don't go making it static, like I tried. sigh. 60 * so don't go making it static, like I tried. sigh.
66 */ 61 */
67unsigned char *interrupt_enable = NULL; 62unsigned char __iomem *interrupt_enable = NULL;
68
69static int sun4c_pil_map[] = { 0, 1, 2, 3, 5, 7, 8, 9 };
70
71static unsigned int sun4c_sbint_to_irq(struct sbus_dev *sdev,
72 unsigned int sbint)
73{
74 if (sbint >= sizeof(sun4c_pil_map)) {
75 printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
76 BUG();
77 }
78 return sun4c_pil_map[sbint];
79}
80 63
81static void sun4c_disable_irq(unsigned int irq_nr) 64static void sun4c_disable_irq(unsigned int irq_nr)
82{ 65{
@@ -85,7 +68,7 @@ static void sun4c_disable_irq(unsigned int irq_nr)
85 68
86 local_irq_save(flags); 69 local_irq_save(flags);
87 irq_nr &= (NR_IRQS - 1); 70 irq_nr &= (NR_IRQS - 1);
88 current_mask = *interrupt_enable; 71 current_mask = sbus_readb(interrupt_enable);
89 switch(irq_nr) { 72 switch(irq_nr) {
90 case 1: 73 case 1:
91 new_mask = ((current_mask) & (~(SUN4C_INT_E1))); 74 new_mask = ((current_mask) & (~(SUN4C_INT_E1)));
@@ -103,7 +86,7 @@ static void sun4c_disable_irq(unsigned int irq_nr)
103 local_irq_restore(flags); 86 local_irq_restore(flags);
104 return; 87 return;
105 } 88 }
106 *interrupt_enable = new_mask; 89 sbus_writeb(new_mask, interrupt_enable);
107 local_irq_restore(flags); 90 local_irq_restore(flags);
108} 91}
109 92
@@ -114,7 +97,7 @@ static void sun4c_enable_irq(unsigned int irq_nr)
114 97
115 local_irq_save(flags); 98 local_irq_save(flags);
116 irq_nr &= (NR_IRQS - 1); 99 irq_nr &= (NR_IRQS - 1);
117 current_mask = *interrupt_enable; 100 current_mask = sbus_readb(interrupt_enable);
118 switch(irq_nr) { 101 switch(irq_nr) {
119 case 1: 102 case 1:
120 new_mask = ((current_mask) | SUN4C_INT_E1); 103 new_mask = ((current_mask) | SUN4C_INT_E1);
@@ -132,37 +115,22 @@ static void sun4c_enable_irq(unsigned int irq_nr)
132 local_irq_restore(flags); 115 local_irq_restore(flags);
133 return; 116 return;
134 } 117 }
135 *interrupt_enable = new_mask; 118 sbus_writeb(new_mask, interrupt_enable);
136 local_irq_restore(flags); 119 local_irq_restore(flags);
137} 120}
138 121
139#define TIMER_IRQ 10 /* Also at level 14, but we ignore that one. */ 122struct sun4c_timer_info {
140#define PROFILE_IRQ 14 /* Level14 ticker.. used by OBP for polling */ 123 u32 l10_count;
141 124 u32 l10_limit;
142volatile struct sun4c_timer_info *sun4c_timers; 125 u32 l14_count;
126 u32 l14_limit;
127};
143 128
144#ifdef CONFIG_SUN4 129static struct sun4c_timer_info __iomem *sun4c_timers;
145/* This is an ugly hack to work around the
146 current timer code, and make it work with
147 the sun4/260 intersil
148 */
149volatile struct sun4c_timer_info sun4_timer;
150#endif
151 130
152static void sun4c_clear_clock_irq(void) 131static void sun4c_clear_clock_irq(void)
153{ 132{
154 volatile unsigned int clear_intr; 133 sbus_readl(&sun4c_timers->l10_limit);
155#ifdef CONFIG_SUN4
156 if (idprom->id_machtype == (SM_SUN4 | SM_4_260))
157 clear_intr = sun4_timer.timer_limit10;
158 else
159#endif
160 clear_intr = sun4c_timers->timer_limit10;
161}
162
163static void sun4c_clear_profile_irq(int cpu)
164{
165 /* Errm.. not sure how to do this.. */
166} 134}
167 135
168static void sun4c_load_profile_irq(int cpu, unsigned int limit) 136static void sun4c_load_profile_irq(int cpu, unsigned int limit)
@@ -172,41 +140,48 @@ static void sun4c_load_profile_irq(int cpu, unsigned int limit)
172 140
173static void __init sun4c_init_timers(irq_handler_t counter_fn) 141static void __init sun4c_init_timers(irq_handler_t counter_fn)
174{ 142{
175 int irq; 143 const struct linux_prom_irqs *irq;
144 struct device_node *dp;
145 const u32 *addr;
146 int err;
147
148 dp = of_find_node_by_name(NULL, "counter-timer");
149 if (!dp) {
150 prom_printf("sun4c_init_timers: Unable to find counter-timer\n");
151 prom_halt();
152 }
176 153
177 /* Map the Timer chip, this is implemented in hardware inside 154 addr = of_get_property(dp, "address", NULL);
178 * the cache chip on the sun4c. 155 if (!addr) {
179 */ 156 prom_printf("sun4c_init_timers: No address property\n");
180#ifdef CONFIG_SUN4 157 prom_halt();
181 if (idprom->id_machtype == (SM_SUN4 | SM_4_260)) 158 }
182 sun4c_timers = &sun4_timer; 159
183 else 160 sun4c_timers = (void __iomem *) (unsigned long) addr[0];
184#endif 161
185 sun4c_timers = ioremap(SUN_TIMER_PHYSADDR, 162 irq = of_get_property(dp, "intr", NULL);
186 sizeof(struct sun4c_timer_info)); 163 if (!irq) {
164 prom_printf("sun4c_init_timers: No intr property\n");
165 prom_halt();
166 }
187 167
188 /* Have the level 10 timer tick at 100HZ. We don't touch the 168 /* Have the level 10 timer tick at 100HZ. We don't touch the
189 * level 14 timer limit since we are letting the prom handle 169 * level 14 timer limit since we are letting the prom handle
190 * them until we have a real console driver so L1-A works. 170 * them until we have a real console driver so L1-A works.
191 */ 171 */
192 sun4c_timers->timer_limit10 = (((1000000/HZ) + 1) << 10); 172 sbus_writel((((1000000/HZ) + 1) << 10), &sun4c_timers->l10_limit);
193 master_l10_counter = &sun4c_timers->cur_count10;
194 master_l10_limit = &sun4c_timers->timer_limit10;
195 173
196 irq = request_irq(TIMER_IRQ, 174 master_l10_counter = &sun4c_timers->l10_count;
197 counter_fn, 175
176 err = request_irq(irq[0].pri, counter_fn,
198 (IRQF_DISABLED | SA_STATIC_ALLOC), 177 (IRQF_DISABLED | SA_STATIC_ALLOC),
199 "timer", NULL); 178 "timer", NULL);
200 if (irq) { 179 if (err) {
201 prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); 180 prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err);
202 prom_halt(); 181 prom_halt();
203 } 182 }
204 183
205#if 0 184 sun4c_disable_irq(irq[1].pri);
206 /* This does not work on 4/330 */
207 sun4c_enable_irq(10);
208#endif
209 claim_ticker14(NULL, PROFILE_IRQ, 0);
210} 185}
211 186
212#ifdef CONFIG_SMP 187#ifdef CONFIG_SMP
@@ -215,41 +190,28 @@ static void sun4c_nop(void) {}
215 190
216void __init sun4c_init_IRQ(void) 191void __init sun4c_init_IRQ(void)
217{ 192{
218 struct linux_prom_registers int_regs[2]; 193 struct device_node *dp;
219 int ie_node; 194 const u32 *addr;
220 195
221 if (ARCH_SUN4) { 196 dp = of_find_node_by_name(NULL, "interrupt-enable");
222 interrupt_enable = (char *) 197 if (!dp) {
223 ioremap(sun4_ie_physaddr, PAGE_SIZE); 198 prom_printf("sun4c_init_IRQ: Unable to find interrupt-enable\n");
224 } else { 199 prom_halt();
225 struct resource phyres; 200 }
226
227 ie_node = prom_searchsiblings (prom_getchild(prom_root_node),
228 "interrupt-enable");
229 if(ie_node == 0)
230 panic("Cannot find /interrupt-enable node");
231 201
232 /* Depending on the "address" property is bad news... */ 202 addr = of_get_property(dp, "address", NULL);
233 interrupt_enable = NULL; 203 if (!addr) {
234 if (prom_getproperty(ie_node, "reg", (char *) int_regs, 204 prom_printf("sun4c_init_IRQ: No address property\n");
235 sizeof(int_regs)) != -1) { 205 prom_halt();
236 memset(&phyres, 0, sizeof(struct resource));
237 phyres.flags = int_regs[0].which_io;
238 phyres.start = int_regs[0].phys_addr;
239 interrupt_enable = (char *) sbus_ioremap(&phyres, 0,
240 int_regs[0].reg_size, "sun4c_intr");
241 }
242 } 206 }
243 if (!interrupt_enable)
244 panic("Cannot map interrupt_enable");
245 207
246 BTFIXUPSET_CALL(sbint_to_irq, sun4c_sbint_to_irq, BTFIXUPCALL_NORM); 208 interrupt_enable = (void __iomem *) (unsigned long) addr[0];
209
247 BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM); 210 BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
248 BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM); 211 BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
249 BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM); 212 BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
250 BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM); 213 BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
251 BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM); 214 BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM);
252 BTFIXUPSET_CALL(clear_profile_irq, sun4c_clear_profile_irq, BTFIXUPCALL_NOP);
253 BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP); 215 BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP);
254 sparc_init_timers = sun4c_init_timers; 216 sparc_init_timers = sun4c_init_timers;
255#ifdef CONFIG_SMP 217#ifdef CONFIG_SMP
@@ -257,6 +219,6 @@ void __init sun4c_init_IRQ(void)
257 BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP); 219 BTFIXUPSET_CALL(clear_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
258 BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP); 220 BTFIXUPSET_CALL(set_irq_udt, sun4c_nop, BTFIXUPCALL_NOP);
259#endif 221#endif
260 *interrupt_enable = (SUN4C_INT_ENABLE); 222 sbus_writeb(SUN4C_INT_ENABLE, interrupt_enable);
261 /* Cannot enable interrupts until OBP ticker is disabled. */ 223 /* Cannot enable interrupts until OBP ticker is disabled. */
262} 224}
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 1290b5998f83..d3cb76ce418b 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -19,6 +19,8 @@
19#include <linux/smp.h> 19#include <linux/smp.h>
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21#include <linux/seq_file.h> 21#include <linux/seq_file.h>
22#include <linux/of.h>
23#include <linux/of_device.h>
22 24
23#include <asm/ptrace.h> 25#include <asm/ptrace.h>
24#include <asm/processor.h> 26#include <asm/processor.h>
@@ -34,7 +36,6 @@
34#include <asm/io.h> 36#include <asm/io.h>
35#include <asm/pgalloc.h> 37#include <asm/pgalloc.h>
36#include <asm/pgtable.h> 38#include <asm/pgtable.h>
37#include <asm/sbus.h>
38#include <asm/sbi.h> 39#include <asm/sbi.h>
39#include <asm/cacheflush.h> 40#include <asm/cacheflush.h>
40#include <asm/irq_regs.h> 41#include <asm/irq_regs.h>
@@ -44,16 +45,22 @@
44/* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */ 45/* If you trust current SCSI layer to handle different SCSI IRQs, enable this. I don't trust it... -jj */
45/* #define DISTRIBUTE_IRQS */ 46/* #define DISTRIBUTE_IRQS */
46 47
47struct sun4d_timer_regs *sun4d_timers; 48struct sun4d_timer_regs {
49 u32 l10_timer_limit;
50 u32 l10_cur_countx;
51 u32 l10_limit_noclear;
52 u32 ctrl;
53 u32 l10_cur_count;
54};
55
56static struct sun4d_timer_regs __iomem *sun4d_timers;
57
48#define TIMER_IRQ 10 58#define TIMER_IRQ 10
49 59
50#define MAX_STATIC_ALLOC 4 60#define MAX_STATIC_ALLOC 4
51extern struct irqaction static_irqaction[MAX_STATIC_ALLOC]; 61extern struct irqaction static_irqaction[MAX_STATIC_ALLOC];
52extern int static_irq_count; 62extern int static_irq_count;
53unsigned char cpu_leds[32];
54#ifdef CONFIG_SMP
55static unsigned char sbus_tid[32]; 63static unsigned char sbus_tid[32];
56#endif
57 64
58static struct irqaction *irq_action[NR_IRQS]; 65static struct irqaction *irq_action[NR_IRQS];
59extern spinlock_t irq_action_lock; 66extern spinlock_t irq_action_lock;
@@ -72,9 +79,9 @@ static int sbus_to_pil[] = {
72}; 79};
73 80
74static int nsbi; 81static int nsbi;
75#ifdef CONFIG_SMP 82
83/* Exported for sun4d_smp.c */
76DEFINE_SPINLOCK(sun4d_imsk_lock); 84DEFINE_SPINLOCK(sun4d_imsk_lock);
77#endif
78 85
79int show_sun4d_interrupts(struct seq_file *p, void *v) 86int show_sun4d_interrupts(struct seq_file *p, void *v)
80{ 87{
@@ -257,26 +264,6 @@ void sun4d_handler_irq(int irq, struct pt_regs * regs)
257 set_irq_regs(old_regs); 264 set_irq_regs(old_regs);
258} 265}
259 266
260unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq)
261{
262 int sbusl = pil_to_sbus[irq];
263
264 if (sbusl)
265 return ((sdev->bus->board + 1) << 5) + (sbusl << 2) + sdev->slot;
266 else
267 return irq;
268}
269
270static unsigned int sun4d_sbint_to_irq(struct sbus_dev *sdev,
271 unsigned int sbint)
272{
273 if (sbint >= sizeof(sbus_to_pil)) {
274 printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
275 BUG();
276 }
277 return sun4d_build_irq(sdev, sbus_to_pil[sbint]);
278}
279
280int sun4d_request_irq(unsigned int irq, 267int sun4d_request_irq(unsigned int irq,
281 irq_handler_t handler, 268 irq_handler_t handler,
282 unsigned long irqflags, const char * devname, void *dev_id) 269 unsigned long irqflags, const char * devname, void *dev_id)
@@ -360,36 +347,28 @@ out:
360 347
361static void sun4d_disable_irq(unsigned int irq) 348static void sun4d_disable_irq(unsigned int irq)
362{ 349{
363#ifdef CONFIG_SMP
364 int tid = sbus_tid[(irq >> 5) - 1]; 350 int tid = sbus_tid[(irq >> 5) - 1];
365 unsigned long flags; 351 unsigned long flags;
366#endif
367 352
368 if (irq < NR_IRQS) return; 353 if (irq < NR_IRQS)
369#ifdef CONFIG_SMP 354 return;
355
370 spin_lock_irqsave(&sun4d_imsk_lock, flags); 356 spin_lock_irqsave(&sun4d_imsk_lock, flags);
371 cc_set_imsk_other(tid, cc_get_imsk_other(tid) | (1 << sbus_to_pil[(irq >> 2) & 7])); 357 cc_set_imsk_other(tid, cc_get_imsk_other(tid) | (1 << sbus_to_pil[(irq >> 2) & 7]));
372 spin_unlock_irqrestore(&sun4d_imsk_lock, flags); 358 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
373#else
374 cc_set_imsk(cc_get_imsk() | (1 << sbus_to_pil[(irq >> 2) & 7]));
375#endif
376} 359}
377 360
378static void sun4d_enable_irq(unsigned int irq) 361static void sun4d_enable_irq(unsigned int irq)
379{ 362{
380#ifdef CONFIG_SMP
381 int tid = sbus_tid[(irq >> 5) - 1]; 363 int tid = sbus_tid[(irq >> 5) - 1];
382 unsigned long flags; 364 unsigned long flags;
383#endif
384 365
385 if (irq < NR_IRQS) return; 366 if (irq < NR_IRQS)
386#ifdef CONFIG_SMP 367 return;
368
387 spin_lock_irqsave(&sun4d_imsk_lock, flags); 369 spin_lock_irqsave(&sun4d_imsk_lock, flags);
388 cc_set_imsk_other(tid, cc_get_imsk_other(tid) & ~(1 << sbus_to_pil[(irq >> 2) & 7])); 370 cc_set_imsk_other(tid, cc_get_imsk_other(tid) & ~(1 << sbus_to_pil[(irq >> 2) & 7]));
389 spin_unlock_irqrestore(&sun4d_imsk_lock, flags); 371 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
390#else
391 cc_set_imsk(cc_get_imsk() & ~(1 << sbus_to_pil[(irq >> 2) & 7]));
392#endif
393} 372}
394 373
395#ifdef CONFIG_SMP 374#ifdef CONFIG_SMP
@@ -409,47 +388,55 @@ static void sun4d_set_udt(int cpu)
409/* Setup IRQ distribution scheme. */ 388/* Setup IRQ distribution scheme. */
410void __init sun4d_distribute_irqs(void) 389void __init sun4d_distribute_irqs(void)
411{ 390{
391 struct device_node *dp;
392
412#ifdef DISTRIBUTE_IRQS 393#ifdef DISTRIBUTE_IRQS
413 struct sbus_bus *sbus; 394 cpumask_t sbus_serving_map;
414 unsigned long sbus_serving_map;
415 395
416 sbus_serving_map = cpu_present_map; 396 sbus_serving_map = cpu_present_map;
417 for_each_sbus(sbus) { 397 for_each_node_by_name(dp, "sbi") {
418 if ((sbus->board * 2) == boot_cpu_id && (cpu_present_map & (1 << (sbus->board * 2 + 1)))) 398 int board = of_getintprop_default(dp, "board#", 0);
419 sbus_tid[sbus->board] = (sbus->board * 2 + 1); 399
420 else if (cpu_present_map & (1 << (sbus->board * 2))) 400 if ((board * 2) == boot_cpu_id && cpu_isset(board * 2 + 1, cpu_present_map))
421 sbus_tid[sbus->board] = (sbus->board * 2); 401 sbus_tid[board] = (board * 2 + 1);
422 else if (cpu_present_map & (1 << (sbus->board * 2 + 1))) 402 else if (cpu_isset(board * 2, cpu_present_map))
423 sbus_tid[sbus->board] = (sbus->board * 2 + 1); 403 sbus_tid[board] = (board * 2);
404 else if (cpu_isset(board * 2 + 1, cpu_present_map))
405 sbus_tid[board] = (board * 2 + 1);
424 else 406 else
425 sbus_tid[sbus->board] = 0xff; 407 sbus_tid[board] = 0xff;
426 if (sbus_tid[sbus->board] != 0xff) 408 if (sbus_tid[board] != 0xff)
427 sbus_serving_map &= ~(1 << sbus_tid[sbus->board]); 409 cpu_clear(sbus_tid[board], sbus_serving_map);
428 } 410 }
429 for_each_sbus(sbus) 411 for_each_node_by_name(dp, "sbi") {
430 if (sbus_tid[sbus->board] == 0xff) { 412 int board = of_getintprop_default(dp, "board#", 0);
413 if (sbus_tid[board] == 0xff) {
431 int i = 31; 414 int i = 31;
432 415
433 if (!sbus_serving_map) 416 if (cpus_empty(sbus_serving_map))
434 sbus_serving_map = cpu_present_map; 417 sbus_serving_map = cpu_present_map;
435 while (!(sbus_serving_map & (1 << i))) 418 while (cpu_isset(i, sbus_serving_map))
436 i--; 419 i--;
437 sbus_tid[sbus->board] = i; 420 sbus_tid[board] = i;
438 sbus_serving_map &= ~(1 << i); 421 cpu_clear(i, sbus_serving_map);
439 } 422 }
440 for_each_sbus(sbus) { 423 }
441 printk("sbus%d IRQs directed to CPU%d\n", sbus->board, sbus_tid[sbus->board]); 424 for_each_node_by_name(dp, "sbi") {
442 set_sbi_tid(sbus->devid, sbus_tid[sbus->board] << 3); 425 int devid = of_getintprop_default(dp, "device-id", 0);
426 int board = of_getintprop_default(dp, "board#", 0);
427 printk("sbus%d IRQs directed to CPU%d\n", board, sbus_tid[board]);
428 set_sbi_tid(devid, sbus_tid[board] << 3);
443 } 429 }
444#else 430#else
445 struct sbus_bus *sbus;
446 int cpuid = cpu_logical_map(1); 431 int cpuid = cpu_logical_map(1);
447 432
448 if (cpuid == -1) 433 if (cpuid == -1)
449 cpuid = cpu_logical_map(0); 434 cpuid = cpu_logical_map(0);
450 for_each_sbus(sbus) { 435 for_each_node_by_name(dp, "sbi") {
451 sbus_tid[sbus->board] = cpuid; 436 int devid = of_getintprop_default(dp, "device-id", 0);
452 set_sbi_tid(sbus->devid, cpuid << 3); 437 int board = of_getintprop_default(dp, "board#", 0);
438 sbus_tid[board] = cpuid;
439 set_sbi_tid(devid, cpuid << 3);
453 } 440 }
454 printk("All sbus IRQs directed to CPU%d\n", cpuid); 441 printk("All sbus IRQs directed to CPU%d\n", cpuid);
455#endif 442#endif
@@ -458,13 +445,7 @@ void __init sun4d_distribute_irqs(void)
458 445
459static void sun4d_clear_clock_irq(void) 446static void sun4d_clear_clock_irq(void)
460{ 447{
461 volatile unsigned int clear_intr; 448 sbus_readl(&sun4d_timers->l10_timer_limit);
462 clear_intr = sun4d_timers->l10_timer_limit;
463}
464
465static void sun4d_clear_profile_irq(int cpu)
466{
467 bw_get_prof_limit(cpu);
468} 449}
469 450
470static void sun4d_load_profile_irq(int cpu, unsigned int limit) 451static void sun4d_load_profile_irq(int cpu, unsigned int limit)
@@ -472,98 +453,121 @@ static void sun4d_load_profile_irq(int cpu, unsigned int limit)
472 bw_set_prof_limit(cpu, limit); 453 bw_set_prof_limit(cpu, limit);
473} 454}
474 455
475static void __init sun4d_init_timers(irq_handler_t counter_fn) 456static void __init sun4d_load_profile_irqs(void)
476{ 457{
477 int irq; 458 int cpu = 0, mid;
478 int cpu;
479 struct resource r;
480 int mid;
481 459
482 /* Map the User Timer registers. */ 460 while (!cpu_find_by_instance(cpu, NULL, &mid)) {
483 memset(&r, 0, sizeof(r)); 461 sun4d_load_profile_irq(mid >> 3, 0);
462 cpu++;
463 }
464}
465
466static void __init sun4d_fixup_trap_table(void)
467{
484#ifdef CONFIG_SMP 468#ifdef CONFIG_SMP
485 r.start = CSR_BASE(boot_cpu_id)+BW_TIMER_LIMIT; 469 unsigned long flags;
486#else 470 extern unsigned long lvl14_save[4];
487 r.start = CSR_BASE(0)+BW_TIMER_LIMIT; 471 struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
472 extern unsigned int real_irq_entry[], smp4d_ticker[];
473 extern unsigned int patchme_maybe_smp_msg[];
474
475 /* Adjust so that we jump directly to smp4d_ticker */
476 lvl14_save[2] += smp4d_ticker - real_irq_entry;
477
478 /* For SMP we use the level 14 ticker, however the bootup code
479 * has copied the firmware's level 14 vector into the boot cpu's
480 * trap table, we must fix this now or we get squashed.
481 */
482 local_irq_save(flags);
483 patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
484 trap_table->inst_one = lvl14_save[0];
485 trap_table->inst_two = lvl14_save[1];
486 trap_table->inst_three = lvl14_save[2];
487 trap_table->inst_four = lvl14_save[3];
488 local_flush_cache_all();
489 local_irq_restore(flags);
488#endif 490#endif
489 r.flags = 0xf; 491}
490 sun4d_timers = (struct sun4d_timer_regs *) sbus_ioremap(&r, 0,
491 PAGE_SIZE, "user timer");
492 492
493 sun4d_timers->l10_timer_limit = (((1000000/HZ) + 1) << 10); 493static void __init sun4d_init_timers(irq_handler_t counter_fn)
494 master_l10_counter = &sun4d_timers->l10_cur_count; 494{
495 master_l10_limit = &sun4d_timers->l10_timer_limit; 495 struct device_node *dp;
496 struct resource res;
497 const u32 *reg;
498 int err;
499
500 dp = of_find_node_by_name(NULL, "cpu-unit");
501 if (!dp) {
502 prom_printf("sun4d_init_timers: Unable to find cpu-unit\n");
503 prom_halt();
504 }
496 505
497 irq = request_irq(TIMER_IRQ, 506 /* Which cpu-unit we use is arbitrary, we can view the bootbus timer
498 counter_fn, 507 * registers via any cpu's mapping. The first 'reg' property is the
499 (IRQF_DISABLED | SA_STATIC_ALLOC), 508 * bootbus.
500 "timer", NULL); 509 */
501 if (irq) { 510 reg = of_get_property(dp, "reg", NULL);
502 prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ); 511 if (!reg) {
512 prom_printf("sun4d_init_timers: No reg property\n");
503 prom_halt(); 513 prom_halt();
504 } 514 }
505
506 /* Enable user timer free run for CPU 0 in BW */
507 /* bw_set_ctrl(0, bw_get_ctrl(0) | BW_CTRL_USER_TIMER); */
508 515
509 cpu = 0; 516 res.start = reg[1];
510 while (!cpu_find_by_instance(cpu, NULL, &mid)) { 517 res.end = reg[2] - 1;
511 sun4d_load_profile_irq(mid >> 3, 0); 518 res.flags = reg[0] & 0xff;
512 cpu++; 519 sun4d_timers = of_ioremap(&res, BW_TIMER_LIMIT,
520 sizeof(struct sun4d_timer_regs), "user timer");
521 if (!sun4d_timers) {
522 prom_printf("sun4d_init_timers: Can't map timer regs\n");
523 prom_halt();
513 } 524 }
514 525
515#ifdef CONFIG_SMP 526 sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit);
516 { 527
517 unsigned long flags; 528 master_l10_counter = &sun4d_timers->l10_cur_count;
518 extern unsigned long lvl14_save[4]; 529
519 struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)]; 530 err = request_irq(TIMER_IRQ, counter_fn,
520 extern unsigned int real_irq_entry[], smp4d_ticker[]; 531 (IRQF_DISABLED | SA_STATIC_ALLOC),
521 extern unsigned int patchme_maybe_smp_msg[]; 532 "timer", NULL);
522 533 if (err) {
523 /* Adjust so that we jump directly to smp4d_ticker */ 534 prom_printf("sun4d_init_timers: request_irq() failed with %d\n", err);
524 lvl14_save[2] += smp4d_ticker - real_irq_entry; 535 prom_halt();
525
526 /* For SMP we use the level 14 ticker, however the bootup code
527 * has copied the firmware's level 14 vector into the boot cpu's
528 * trap table, we must fix this now or we get squashed.
529 */
530 local_irq_save(flags);
531 patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
532 trap_table->inst_one = lvl14_save[0];
533 trap_table->inst_two = lvl14_save[1];
534 trap_table->inst_three = lvl14_save[2];
535 trap_table->inst_four = lvl14_save[3];
536 local_flush_cache_all();
537 local_irq_restore(flags);
538 } 536 }
539#endif 537 sun4d_load_profile_irqs();
538 sun4d_fixup_trap_table();
540} 539}
541 540
542void __init sun4d_init_sbi_irq(void) 541void __init sun4d_init_sbi_irq(void)
543{ 542{
544 struct sbus_bus *sbus; 543 struct device_node *dp;
545 unsigned mask; 544 int target_cpu = 0;
545
546#ifdef CONFIG_SMP
547 target_cpu = boot_cpu_id;
548#endif
546 549
547 nsbi = 0; 550 nsbi = 0;
548 for_each_sbus(sbus) 551 for_each_node_by_name(dp, "sbi")
549 nsbi++; 552 nsbi++;
550 sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); 553 sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
551 if (!sbus_actions) { 554 if (!sbus_actions) {
552 prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n"); 555 prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");
553 prom_halt(); 556 prom_halt();
554 } 557 }
555 for_each_sbus(sbus) { 558 for_each_node_by_name(dp, "sbi") {
556#ifdef CONFIG_SMP 559 int devid = of_getintprop_default(dp, "device-id", 0);
557 extern unsigned char boot_cpu_id; 560 int board = of_getintprop_default(dp, "board#", 0);
558 561 unsigned int mask;
559 set_sbi_tid(sbus->devid, boot_cpu_id << 3); 562
560 sbus_tid[sbus->board] = boot_cpu_id; 563 set_sbi_tid(devid, target_cpu << 3);
561#endif 564 sbus_tid[board] = target_cpu;
565
562 /* Get rid of pending irqs from PROM */ 566 /* Get rid of pending irqs from PROM */
563 mask = acquire_sbi(sbus->devid, 0xffffffff); 567 mask = acquire_sbi(devid, 0xffffffff);
564 if (mask) { 568 if (mask) {
565 printk ("Clearing pending IRQs %08x on SBI %d\n", mask, sbus->board); 569 printk ("Clearing pending IRQs %08x on SBI %d\n", mask, board);
566 release_sbi(sbus->devid, mask); 570 release_sbi(devid, mask);
567 } 571 }
568 } 572 }
569} 573}
@@ -572,11 +576,9 @@ void __init sun4d_init_IRQ(void)
572{ 576{
573 local_irq_disable(); 577 local_irq_disable();
574 578
575 BTFIXUPSET_CALL(sbint_to_irq, sun4d_sbint_to_irq, BTFIXUPCALL_NORM);
576 BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM); 579 BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);
577 BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM); 580 BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);
578 BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM); 581 BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM);
579 BTFIXUPSET_CALL(clear_profile_irq, sun4d_clear_profile_irq, BTFIXUPCALL_NORM);
580 BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM); 582 BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);
581 sparc_init_timers = sun4d_init_timers; 583 sparc_init_timers = sun4d_init_timers;
582#ifdef CONFIG_SMP 584#ifdef CONFIG_SMP
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 69596402a500..ce3d45db94e9 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -30,7 +30,6 @@
30#include <asm/pgalloc.h> 30#include <asm/pgalloc.h>
31#include <asm/pgtable.h> 31#include <asm/pgtable.h>
32#include <asm/oplib.h> 32#include <asm/oplib.h>
33#include <asm/sbus.h>
34#include <asm/sbi.h> 33#include <asm/sbi.h>
35#include <asm/tlbflush.h> 34#include <asm/tlbflush.h>
36#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
@@ -72,6 +71,17 @@ static void smp_setup_percpu_timer(void);
72extern void cpu_probe(void); 71extern void cpu_probe(void);
73extern void sun4d_distribute_irqs(void); 72extern void sun4d_distribute_irqs(void);
74 73
74static unsigned char cpu_leds[32];
75
76static inline void show_leds(int cpuid)
77{
78 cpuid &= 0x1e;
79 __asm__ __volatile__ ("stba %0, [%1] %2" : :
80 "r" ((cpu_leds[cpuid] << 4) | cpu_leds[cpuid+1]),
81 "r" (ECSR_BASE(cpuid) | BB_LEDS),
82 "i" (ASI_M_CTL));
83}
84
75void __init smp4d_callin(void) 85void __init smp4d_callin(void)
76{ 86{
77 int cpuid = hard_smp4d_processor_id(); 87 int cpuid = hard_smp4d_processor_id();
@@ -88,6 +98,7 @@ void __init smp4d_callin(void)
88 local_flush_cache_all(); 98 local_flush_cache_all();
89 local_flush_tlb_all(); 99 local_flush_tlb_all();
90 100
101 notify_cpu_starting(cpuid);
91 /* 102 /*
92 * Unblock the master CPU _only_ when the scheduler state 103 * Unblock the master CPU _only_ when the scheduler state
93 * of all secondary CPUs will be up-to-date, so after 104 * of all secondary CPUs will be up-to-date, so after
diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c
index 94e02de960ea..f10317179ee6 100644
--- a/arch/sparc/kernel/sun4m_irq.c
+++ b/arch/sparc/kernel/sun4m_irq.c
@@ -20,6 +20,8 @@
20#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/ioport.h> 22#include <linux/ioport.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
23 25
24#include <asm/ptrace.h> 26#include <asm/ptrace.h>
25#include <asm/processor.h> 27#include <asm/processor.h>
@@ -35,59 +37,27 @@
35#include <asm/smp.h> 37#include <asm/smp.h>
36#include <asm/irq.h> 38#include <asm/irq.h>
37#include <asm/io.h> 39#include <asm/io.h>
38#include <asm/sbus.h>
39#include <asm/cacheflush.h> 40#include <asm/cacheflush.h>
40 41
41#include "irq.h" 42#include "irq.h"
42 43
43/* On the sun4m, just like the timers, we have both per-cpu and master 44struct sun4m_irq_percpu {
44 * interrupt registers. 45 u32 pending;
45 */ 46 u32 clear;
46 47 u32 set;
47/* These registers are used for sending/receiving irqs from/to
48 * different cpu's.
49 */
50struct sun4m_intreg_percpu {
51 unsigned int tbt; /* Interrupts still pending for this cpu. */
52
53 /* These next two registers are WRITE-ONLY and are only
54 * "on bit" sensitive, "off bits" written have NO affect.
55 */
56 unsigned int clear; /* Clear this cpus irqs here. */
57 unsigned int set; /* Set this cpus irqs here. */
58 unsigned char space[PAGE_SIZE - 12];
59}; 48};
60 49
61/* 50struct sun4m_irq_global {
62 * djhr 51 u32 pending;
63 * Actually the clear and set fields in this struct are misleading.. 52 u32 mask;
64 * according to the SLAVIO manual (and the same applies for the SEC) 53 u32 mask_clear;
65 * the clear field clears bits in the mask which will ENABLE that IRQ 54 u32 mask_set;
66 * the set field sets bits in the mask to DISABLE the IRQ. 55 u32 interrupt_target;
67 *
68 * Also the undirected_xx address in the SLAVIO is defined as
69 * RESERVED and write only..
70 *
71 * DAVEM_NOTE: The SLAVIO only specifies behavior on uniprocessor
72 * sun4m machines, for MP the layout makes more sense.
73 */
74struct sun4m_intregs {
75 struct sun4m_intreg_percpu cpu_intregs[SUN4M_NCPUS];
76 unsigned int tbt; /* IRQ's that are still pending. */
77 unsigned int irqs; /* Master IRQ bits. */
78
79 /* Again, like the above, two these registers are WRITE-ONLY. */
80 unsigned int clear; /* Clear master IRQ's by setting bits here. */
81 unsigned int set; /* Set master IRQ's by setting bits here. */
82
83 /* This register is both READ and WRITE. */
84 unsigned int undirected_target; /* Which cpu gets undirected irqs. */
85}; 56};
86 57
87static unsigned long dummy; 58/* Code in entry.S needs to get at these register mappings. */
88 59struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
89struct sun4m_intregs *sun4m_interrupts; 60struct sun4m_irq_global __iomem *sun4m_irq_global;
90unsigned long *irq_rcvreg = &dummy;
91 61
92/* Dave Redman (djhr@tadpole.co.uk) 62/* Dave Redman (djhr@tadpole.co.uk)
93 * The sun4m interrupt registers. 63 * The sun4m interrupt registers.
@@ -101,8 +71,9 @@ unsigned long *irq_rcvreg = &dummy;
101 71
102#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */ 72#define SUN4M_INT_MASKALL 0x80000000 /* mask all interrupts */
103#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */ 73#define SUN4M_INT_MODULE_ERR 0x40000000 /* module error */
104#define SUN4M_INT_M2S_WRITE 0x20000000 /* write buffer error */ 74#define SUN4M_INT_M2S_WRITE_ERR 0x20000000 /* write buffer error */
105#define SUN4M_INT_ECC 0x10000000 /* ecc memory error */ 75#define SUN4M_INT_ECC_ERR 0x10000000 /* ecc memory error */
76#define SUN4M_INT_VME_ERR 0x08000000 /* vme async error */
106#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */ 77#define SUN4M_INT_FLOPPY 0x00400000 /* floppy disk */
107#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */ 78#define SUN4M_INT_MODULE 0x00200000 /* module interrupt */
108#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */ 79#define SUN4M_INT_VIDEO 0x00100000 /* onboard video */
@@ -113,75 +84,126 @@ unsigned long *irq_rcvreg = &dummy;
113#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */ 84#define SUN4M_INT_SERIAL 0x00008000 /* serial ports */
114#define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */ 85#define SUN4M_INT_KBDMS 0x00004000 /* keyboard/mouse */
115#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */ 86#define SUN4M_INT_SBUSBITS 0x00003F80 /* sbus int bits */
87#define SUN4M_INT_VMEBITS 0x0000007F /* vme int bits */
88
89#define SUN4M_INT_ERROR (SUN4M_INT_MODULE_ERR | \
90 SUN4M_INT_M2S_WRITE_ERR | \
91 SUN4M_INT_ECC_ERR | \
92 SUN4M_INT_VME_ERR)
116 93
117#define SUN4M_INT_SBUS(x) (1 << (x+7)) 94#define SUN4M_INT_SBUS(x) (1 << (x+7))
118#define SUN4M_INT_VME(x) (1 << (x)) 95#define SUN4M_INT_VME(x) (1 << (x))
119 96
120/* These tables only apply for interrupts greater than 15.. 97/* Interrupt levels used by OBP */
121 * 98#define OBP_INT_LEVEL_SOFT 0x10
122 * any intr value below 0x10 is considered to be a soft-int 99#define OBP_INT_LEVEL_ONBOARD 0x20
123 * this may be useful or it may not.. but that's how I've done it. 100#define OBP_INT_LEVEL_SBUS 0x30
124 * and it won't clash with what OBP is telling us about devices. 101#define OBP_INT_LEVEL_VME 0x40
102
103/* Interrupt level assignment on sun4m:
104 *
105 * level source
106 * ------------------------------------------------------------
107 * 1 softint-1
108 * 2 softint-2, VME/SBUS level 1
109 * 3 softint-3, VME/SBUS level 2
110 * 4 softint-4, onboard SCSI
111 * 5 softint-5, VME/SBUS level 3
112 * 6 softint-6, onboard ETHERNET
113 * 7 softint-7, VME/SBUS level 4
114 * 8 softint-8, onboard VIDEO
115 * 9 softint-9, VME/SBUS level 5, Module Interrupt
116 * 10 softint-10, system counter/timer
117 * 11 softint-11, VME/SBUS level 6, Floppy
118 * 12 softint-12, Keyboard/Mouse, Serial
119 * 13 softint-13, VME/SBUS level 7, ISDN Audio
120 * 14 softint-14, per-processor counter/timer
121 * 15 softint-15, Asynchronous Errors (broadcast)
125 * 122 *
126 * take an encoded intr value and lookup if it's valid 123 * Each interrupt source is masked distinctly in the sun4m interrupt
127 * then get the mask bits that match from irq_mask 124 * registers. The PIL level alone is therefore ambiguous, since multiple
125 * interrupt sources map to a single PIL.
128 * 126 *
129 * P3: Translation from irq 0x0d to mask 0x2000 is for MrCoffee. 127 * This ambiguity is resolved in the 'intr' property for device nodes
128 * in the OF device tree. Each 'intr' property entry is composed of
129 * two 32-bit words. The first word is the IRQ priority value, which
130 * is what we're intersted in. The second word is the IRQ vector, which
131 * is unused.
132 *
133 * The low 4 bits of the IRQ priority indicate the PIL, and the upper
134 * 4 bits indicate onboard vs. SBUS leveled vs. VME leveled. 0x20
135 * means onboard, 0x30 means SBUS leveled, and 0x40 means VME leveled.
136 *
137 * For example, an 'intr' IRQ priority value of 0x24 is onboard SCSI
138 * whereas a value of 0x33 is SBUS level 2. Here are some sample
139 * 'intr' property IRQ priority values from ss4, ss5, ss10, ss20, and
140 * Tadpole S3 GX systems.
141 *
142 * esp: 0x24 onboard ESP SCSI
143 * le: 0x26 onboard Lance ETHERNET
144 * p9100: 0x32 SBUS level 1 P9100 video
145 * bpp: 0x33 SBUS level 2 BPP parallel port device
146 * DBRI: 0x39 SBUS level 5 DBRI ISDN audio
147 * SUNW,leo: 0x39 SBUS level 5 LEO video
148 * pcmcia: 0x3b SBUS level 6 PCMCIA controller
149 * uctrl: 0x3b SBUS level 6 UCTRL device
150 * modem: 0x3d SBUS level 7 MODEM
151 * zs: 0x2c onboard keyboard/mouse/serial
152 * floppy: 0x2b onboard Floppy
153 * power: 0x22 onboard power device (XXX unknown mask bit XXX)
130 */ 154 */
131static unsigned char irq_xlate[32] = {
132 /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f */
133 0, 0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 5, 6, 14, 0, 7,
134 0, 0, 8, 9, 0, 10, 0, 11, 0, 12, 0, 13, 0, 14, 0, 0
135};
136 155
137static unsigned long irq_mask[] = { 156static unsigned long irq_mask[0x50] = {
138 0, /* illegal index */ 157 /* SMP */
139 SUN4M_INT_SCSI, /* 1 irq 4 */ 158 0, SUN4M_SOFT_INT(1),
140 SUN4M_INT_ETHERNET, /* 2 irq 6 */ 159 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
141 SUN4M_INT_VIDEO, /* 3 irq 8 */ 160 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
142 SUN4M_INT_REALTIME, /* 4 irq 10 */ 161 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
143 SUN4M_INT_FLOPPY, /* 5 irq 11 */ 162 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
144 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS), /* 6 irq 12 */ 163 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
145 SUN4M_INT_MODULE_ERR, /* 7 irq 15 */ 164 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
146 SUN4M_INT_SBUS(0), /* 8 irq 2 */ 165 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
147 SUN4M_INT_SBUS(1), /* 9 irq 3 */ 166 /* soft */
148 SUN4M_INT_SBUS(2), /* 10 irq 5 */ 167 0, SUN4M_SOFT_INT(1),
149 SUN4M_INT_SBUS(3), /* 11 irq 7 */ 168 SUN4M_SOFT_INT(2), SUN4M_SOFT_INT(3),
150 SUN4M_INT_SBUS(4), /* 12 irq 9 */ 169 SUN4M_SOFT_INT(4), SUN4M_SOFT_INT(5),
151 SUN4M_INT_SBUS(5), /* 13 irq 11 */ 170 SUN4M_SOFT_INT(6), SUN4M_SOFT_INT(7),
152 SUN4M_INT_SBUS(6) /* 14 irq 13 */ 171 SUN4M_SOFT_INT(8), SUN4M_SOFT_INT(9),
172 SUN4M_SOFT_INT(10), SUN4M_SOFT_INT(11),
173 SUN4M_SOFT_INT(12), SUN4M_SOFT_INT(13),
174 SUN4M_SOFT_INT(14), SUN4M_SOFT_INT(15),
175 /* onboard */
176 0, 0, 0, 0,
177 SUN4M_INT_SCSI, 0, SUN4M_INT_ETHERNET, 0,
178 SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
179 SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
180 (SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
181 SUN4M_INT_AUDIO, 0, SUN4M_INT_MODULE_ERR,
182 /* sbus */
183 0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
184 0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
185 0, SUN4M_INT_SBUS(4), 0, SUN4M_INT_SBUS(5),
186 0, SUN4M_INT_SBUS(6), 0, 0,
187 /* vme */
188 0, 0, SUN4M_INT_VME(0), SUN4M_INT_VME(1),
189 0, SUN4M_INT_VME(2), 0, SUN4M_INT_VME(3),
190 0, SUN4M_INT_VME(4), 0, SUN4M_INT_VME(5),
191 0, SUN4M_INT_VME(6), 0, 0
153}; 192};
154 193
155static int sun4m_pil_map[] = { 0, 2, 3, 5, 7, 9, 11, 13 };
156
157static unsigned int sun4m_sbint_to_irq(struct sbus_dev *sdev,
158 unsigned int sbint)
159{
160 if (sbint >= sizeof(sun4m_pil_map)) {
161 printk(KERN_ERR "%s: bogus SBINT %d\n", sdev->prom_name, sbint);
162 BUG();
163 }
164 return sun4m_pil_map[sbint] | 0x30;
165}
166
167static unsigned long sun4m_get_irqmask(unsigned int irq) 194static unsigned long sun4m_get_irqmask(unsigned int irq)
168{ 195{
169 unsigned long mask; 196 unsigned long mask;
170 197
171 if (irq > 0x20) { 198 if (irq < 0x50)
172 /* OBIO/SBUS interrupts */ 199 mask = irq_mask[irq];
173 irq &= 0x1f; 200 else
174 mask = irq_mask[irq_xlate[irq]]; 201 mask = 0;
175 if (!mask) 202
176 printk("sun4m_get_irqmask: IRQ%d has no valid mask!\n",irq); 203 if (!mask)
177 } else { 204 printk(KERN_ERR "sun4m_get_irqmask: IRQ%d has no valid mask!\n",
178 /* Soft Interrupts will come here. 205 irq);
179 * Currently there is no way to trigger them but I'm sure 206
180 * something could be cooked up.
181 */
182 irq &= 0xf;
183 mask = SUN4M_SOFT_INT(irq);
184 }
185 return mask; 207 return mask;
186} 208}
187 209
@@ -193,9 +215,9 @@ static void sun4m_disable_irq(unsigned int irq_nr)
193 mask = sun4m_get_irqmask(irq_nr); 215 mask = sun4m_get_irqmask(irq_nr);
194 local_irq_save(flags); 216 local_irq_save(flags);
195 if (irq_nr > 15) 217 if (irq_nr > 15)
196 sun4m_interrupts->set = mask; 218 sbus_writel(mask, &sun4m_irq_global->mask_set);
197 else 219 else
198 sun4m_interrupts->cpu_intregs[cpu].set = mask; 220 sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
199 local_irq_restore(flags); 221 local_irq_restore(flags);
200} 222}
201 223
@@ -212,13 +234,13 @@ static void sun4m_enable_irq(unsigned int irq_nr)
212 mask = sun4m_get_irqmask(irq_nr); 234 mask = sun4m_get_irqmask(irq_nr);
213 local_irq_save(flags); 235 local_irq_save(flags);
214 if (irq_nr > 15) 236 if (irq_nr > 15)
215 sun4m_interrupts->clear = mask; 237 sbus_writel(mask, &sun4m_irq_global->mask_clear);
216 else 238 else
217 sun4m_interrupts->cpu_intregs[cpu].clear = mask; 239 sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
218 local_irq_restore(flags); 240 local_irq_restore(flags);
219 } else { 241 } else {
220 local_irq_save(flags); 242 local_irq_save(flags);
221 sun4m_interrupts->clear = SUN4M_INT_FLOPPY; 243 sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear);
222 local_irq_restore(flags); 244 local_irq_restore(flags);
223 } 245 }
224} 246}
@@ -236,10 +258,10 @@ static unsigned long cpu_pil_to_imask[16] = {
236/*9*/ SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR, 258/*9*/ SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR,
237/*10*/ SUN4M_INT_REALTIME, 259/*10*/ SUN4M_INT_REALTIME,
238/*11*/ SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY, 260/*11*/ SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY,
239/*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS, 261/*12*/ SUN4M_INT_SERIAL | SUN4M_INT_KBDMS,
240/*13*/ SUN4M_INT_AUDIO, 262/*13*/ SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO,
241/*14*/ SUN4M_INT_E14, 263/*14*/ SUN4M_INT_E14,
242/*15*/ 0x00000000 264/*15*/ SUN4M_INT_ERROR
243}; 265};
244 266
245/* We assume the caller has disabled local interrupts when these are called, 267/* We assume the caller has disabled local interrupts when these are called,
@@ -247,126 +269,141 @@ static unsigned long cpu_pil_to_imask[16] = {
247 */ 269 */
248static void sun4m_disable_pil_irq(unsigned int pil) 270static void sun4m_disable_pil_irq(unsigned int pil)
249{ 271{
250 sun4m_interrupts->set = cpu_pil_to_imask[pil]; 272 sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_set);
251} 273}
252 274
253static void sun4m_enable_pil_irq(unsigned int pil) 275static void sun4m_enable_pil_irq(unsigned int pil)
254{ 276{
255 sun4m_interrupts->clear = cpu_pil_to_imask[pil]; 277 sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_clear);
256} 278}
257 279
258#ifdef CONFIG_SMP 280#ifdef CONFIG_SMP
259static void sun4m_send_ipi(int cpu, int level) 281static void sun4m_send_ipi(int cpu, int level)
260{ 282{
261 unsigned long mask; 283 unsigned long mask = sun4m_get_irqmask(level);
262 284 sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
263 mask = sun4m_get_irqmask(level);
264 sun4m_interrupts->cpu_intregs[cpu].set = mask;
265} 285}
266 286
267static void sun4m_clear_ipi(int cpu, int level) 287static void sun4m_clear_ipi(int cpu, int level)
268{ 288{
269 unsigned long mask; 289 unsigned long mask = sun4m_get_irqmask(level);
270 290 sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
271 mask = sun4m_get_irqmask(level);
272 sun4m_interrupts->cpu_intregs[cpu].clear = mask;
273} 291}
274 292
275static void sun4m_set_udt(int cpu) 293static void sun4m_set_udt(int cpu)
276{ 294{
277 sun4m_interrupts->undirected_target = cpu; 295 sbus_writel(cpu, &sun4m_irq_global->interrupt_target);
278} 296}
279#endif 297#endif
280 298
281#define OBIO_INTR 0x20 299struct sun4m_timer_percpu {
282#define TIMER_IRQ (OBIO_INTR | 10) 300 u32 l14_limit;
283#define PROFILE_IRQ (OBIO_INTR | 14) 301 u32 l14_count;
302 u32 l14_limit_noclear;
303 u32 user_timer_start_stop;
304};
305
306static struct sun4m_timer_percpu __iomem *timers_percpu[SUN4M_NCPUS];
307
308struct sun4m_timer_global {
309 u32 l10_limit;
310 u32 l10_count;
311 u32 l10_limit_noclear;
312 u32 reserved;
313 u32 timer_config;
314};
315
316static struct sun4m_timer_global __iomem *timers_global;
317
318#define TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10)
284 319
285static struct sun4m_timer_regs *sun4m_timers;
286unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); 320unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10);
287 321
288static void sun4m_clear_clock_irq(void) 322static void sun4m_clear_clock_irq(void)
289{ 323{
290 volatile unsigned int clear_intr; 324 sbus_readl(&timers_global->l10_limit);
291 clear_intr = sun4m_timers->l10_timer_limit;
292} 325}
293 326
294static void sun4m_clear_profile_irq(int cpu) 327void sun4m_nmi(struct pt_regs *regs)
295{ 328{
296 volatile unsigned int clear; 329 unsigned long afsr, afar, si;
297 330
298 clear = sun4m_timers->cpu_timers[cpu].l14_timer_limit; 331 printk(KERN_ERR "Aieee: sun4m NMI received!\n");
332 /* XXX HyperSparc hack XXX */
333 __asm__ __volatile__("mov 0x500, %%g1\n\t"
334 "lda [%%g1] 0x4, %0\n\t"
335 "mov 0x600, %%g1\n\t"
336 "lda [%%g1] 0x4, %1\n\t" :
337 "=r" (afsr), "=r" (afar));
338 printk(KERN_ERR "afsr=%08lx afar=%08lx\n", afsr, afar);
339 si = sbus_readl(&sun4m_irq_global->pending);
340 printk(KERN_ERR "si=%08lx\n", si);
341 if (si & SUN4M_INT_MODULE_ERR)
342 printk(KERN_ERR "Module async error\n");
343 if (si & SUN4M_INT_M2S_WRITE_ERR)
344 printk(KERN_ERR "MBus/SBus async error\n");
345 if (si & SUN4M_INT_ECC_ERR)
346 printk(KERN_ERR "ECC memory error\n");
347 if (si & SUN4M_INT_VME_ERR)
348 printk(KERN_ERR "VME async error\n");
349 printk(KERN_ERR "you lose buddy boy...\n");
350 show_regs(regs);
351 prom_halt();
352}
353
354/* Exported for sun4m_smp.c */
355void sun4m_clear_profile_irq(int cpu)
356{
357 sbus_readl(&timers_percpu[cpu]->l14_limit);
299} 358}
300 359
301static void sun4m_load_profile_irq(int cpu, unsigned int limit) 360static void sun4m_load_profile_irq(int cpu, unsigned int limit)
302{ 361{
303 sun4m_timers->cpu_timers[cpu].l14_timer_limit = limit; 362 sbus_writel(limit, &timers_percpu[cpu]->l14_limit);
304} 363}
305 364
306static void __init sun4m_init_timers(irq_handler_t counter_fn) 365static void __init sun4m_init_timers(irq_handler_t counter_fn)
307{ 366{
308 int reg_count, irq, cpu; 367 struct device_node *dp = of_find_node_by_name(NULL, "counter");
309 struct linux_prom_registers cnt_regs[PROMREG_MAX]; 368 int i, err, len, num_cpu_timers;
310 int obio_node, cnt_node; 369 const u32 *addr;
311 struct resource r; 370
312 371 if (!dp) {
313 cnt_node = 0; 372 printk(KERN_ERR "sun4m_init_timers: No 'counter' node.\n");
314 if((obio_node = 373 return;
315 prom_searchsiblings (prom_getchild(prom_root_node), "obio")) == 0 ||
316 (obio_node = prom_getchild (obio_node)) == 0 ||
317 (cnt_node = prom_searchsiblings (obio_node, "counter")) == 0) {
318 prom_printf("Cannot find /obio/counter node\n");
319 prom_halt();
320 } 374 }
321 reg_count = prom_getproperty(cnt_node, "reg", 375
322 (void *) cnt_regs, sizeof(cnt_regs)); 376 addr = of_get_property(dp, "address", &len);
323 reg_count = (reg_count/sizeof(struct linux_prom_registers)); 377 if (!addr) {
324 378 printk(KERN_ERR "sun4m_init_timers: No 'address' prop.\n");
325 /* Apply the obio ranges to the timer registers. */ 379 return;
326 prom_apply_obio_ranges(cnt_regs, reg_count);
327
328 cnt_regs[4].phys_addr = cnt_regs[reg_count-1].phys_addr;
329 cnt_regs[4].reg_size = cnt_regs[reg_count-1].reg_size;
330 cnt_regs[4].which_io = cnt_regs[reg_count-1].which_io;
331 for(obio_node = 1; obio_node < 4; obio_node++) {
332 cnt_regs[obio_node].phys_addr =
333 cnt_regs[obio_node-1].phys_addr + PAGE_SIZE;
334 cnt_regs[obio_node].reg_size = cnt_regs[obio_node-1].reg_size;
335 cnt_regs[obio_node].which_io = cnt_regs[obio_node-1].which_io;
336 } 380 }
337 381
338 memset((char*)&r, 0, sizeof(struct resource)); 382 num_cpu_timers = (len / sizeof(u32)) - 1;
339 /* Map the per-cpu Counter registers. */ 383 for (i = 0; i < num_cpu_timers; i++) {
340 r.flags = cnt_regs[0].which_io; 384 timers_percpu[i] = (void __iomem *)
341 r.start = cnt_regs[0].phys_addr; 385 (unsigned long) addr[i];
342 sun4m_timers = (struct sun4m_timer_regs *) sbus_ioremap(&r, 0,
343 PAGE_SIZE*SUN4M_NCPUS, "sun4m_cpu_cnt");
344 /* Map the system Counter register. */
345 /* XXX Here we expect consequent calls to yeld adjusent maps. */
346 r.flags = cnt_regs[4].which_io;
347 r.start = cnt_regs[4].phys_addr;
348 sbus_ioremap(&r, 0, cnt_regs[4].reg_size, "sun4m_sys_cnt");
349
350 sun4m_timers->l10_timer_limit = (((1000000/HZ) + 1) << 10);
351 master_l10_counter = &sun4m_timers->l10_cur_count;
352 master_l10_limit = &sun4m_timers->l10_timer_limit;
353
354 irq = request_irq(TIMER_IRQ,
355 counter_fn,
356 (IRQF_DISABLED | SA_STATIC_ALLOC),
357 "timer", NULL);
358 if (irq) {
359 prom_printf("time_init: unable to attach IRQ%d\n",TIMER_IRQ);
360 prom_halt();
361 } 386 }
362 387 timers_global = (void __iomem *)
363 if (!cpu_find_by_instance(1, NULL, NULL)) { 388 (unsigned long) addr[num_cpu_timers];
364 for(cpu = 0; cpu < 4; cpu++) 389
365 sun4m_timers->cpu_timers[cpu].l14_timer_limit = 0; 390 sbus_writel((((1000000/HZ) + 1) << 10), &timers_global->l10_limit);
366 sun4m_interrupts->set = SUN4M_INT_E14; 391
367 } else { 392 master_l10_counter = &timers_global->l10_count;
368 sun4m_timers->cpu_timers[0].l14_timer_limit = 0; 393
394 err = request_irq(TIMER_IRQ, counter_fn,
395 (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
396 if (err) {
397 printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
398 err);
399 return;
369 } 400 }
401
402 for (i = 0; i < num_cpu_timers; i++)
403 sbus_writel(0, &timers_percpu[i]->l14_limit);
404 if (num_cpu_timers == 4)
405 sbus_writel(SUN4M_INT_E14, &sun4m_irq_global->mask_set);
406
370#ifdef CONFIG_SMP 407#ifdef CONFIG_SMP
371 { 408 {
372 unsigned long flags; 409 unsigned long flags;
@@ -390,70 +427,43 @@ static void __init sun4m_init_timers(irq_handler_t counter_fn)
390 427
391void __init sun4m_init_IRQ(void) 428void __init sun4m_init_IRQ(void)
392{ 429{
393 int ie_node,i; 430 struct device_node *dp = of_find_node_by_name(NULL, "interrupt");
394 struct linux_prom_registers int_regs[PROMREG_MAX]; 431 int len, i, mid, num_cpu_iregs;
395 int num_regs; 432 const u32 *addr;
396 struct resource r; 433
397 int mid; 434 if (!dp) {
398 435 printk(KERN_ERR "sun4m_init_IRQ: No 'interrupt' node.\n");
399 local_irq_disable(); 436 return;
400 if((ie_node = prom_searchsiblings(prom_getchild(prom_root_node), "obio")) == 0 ||
401 (ie_node = prom_getchild (ie_node)) == 0 ||
402 (ie_node = prom_searchsiblings (ie_node, "interrupt")) == 0) {
403 prom_printf("Cannot find /obio/interrupt node\n");
404 prom_halt();
405 } 437 }
406 num_regs = prom_getproperty(ie_node, "reg", (char *) int_regs, 438
407 sizeof(int_regs)); 439 addr = of_get_property(dp, "address", &len);
408 num_regs = (num_regs/sizeof(struct linux_prom_registers)); 440 if (!addr) {
409 441 printk(KERN_ERR "sun4m_init_IRQ: No 'address' prop.\n");
410 /* Apply the obio ranges to these registers. */ 442 return;
411 prom_apply_obio_ranges(int_regs, num_regs);
412
413 int_regs[4].phys_addr = int_regs[num_regs-1].phys_addr;
414 int_regs[4].reg_size = int_regs[num_regs-1].reg_size;
415 int_regs[4].which_io = int_regs[num_regs-1].which_io;
416 for(ie_node = 1; ie_node < 4; ie_node++) {
417 int_regs[ie_node].phys_addr = int_regs[ie_node-1].phys_addr + PAGE_SIZE;
418 int_regs[ie_node].reg_size = int_regs[ie_node-1].reg_size;
419 int_regs[ie_node].which_io = int_regs[ie_node-1].which_io;
420 } 443 }
421 444
422 memset((char *)&r, 0, sizeof(struct resource)); 445 num_cpu_iregs = (len / sizeof(u32)) - 1;
423 /* Map the interrupt registers for all possible cpus. */ 446 for (i = 0; i < num_cpu_iregs; i++) {
424 r.flags = int_regs[0].which_io; 447 sun4m_irq_percpu[i] = (void __iomem *)
425 r.start = int_regs[0].phys_addr; 448 (unsigned long) addr[i];
426 sun4m_interrupts = (struct sun4m_intregs *) sbus_ioremap(&r, 0, 449 }
427 PAGE_SIZE*SUN4M_NCPUS, "interrupts_percpu"); 450 sun4m_irq_global = (void __iomem *)
451 (unsigned long) addr[num_cpu_iregs];
428 452
429 /* Map the system interrupt control registers. */ 453 local_irq_disable();
430 r.flags = int_regs[4].which_io;
431 r.start = int_regs[4].phys_addr;
432 sbus_ioremap(&r, 0, int_regs[4].reg_size, "interrupts_system");
433 454
434 sun4m_interrupts->set = ~SUN4M_INT_MASKALL; 455 sbus_writel(~SUN4M_INT_MASKALL, &sun4m_irq_global->mask_set);
435 for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++) 456 for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++)
436 sun4m_interrupts->cpu_intregs[mid].clear = ~0x17fff; 457 sbus_writel(~0x17fff, &sun4m_irq_percpu[mid]->clear);
437 458
438 if (!cpu_find_by_instance(1, NULL, NULL)) { 459 if (num_cpu_iregs == 4)
439 /* system wide interrupts go to cpu 0, this should always 460 sbus_writel(0, &sun4m_irq_global->interrupt_target);
440 * be safe because it is guaranteed to be fitted or OBP doesn't 461
441 * come up
442 *
443 * Not sure, but writing here on SLAVIO systems may puke
444 * so I don't do it unless there is more than 1 cpu.
445 */
446 irq_rcvreg = (unsigned long *)
447 &sun4m_interrupts->undirected_target;
448 sun4m_interrupts->undirected_target = 0;
449 }
450 BTFIXUPSET_CALL(sbint_to_irq, sun4m_sbint_to_irq, BTFIXUPCALL_NORM);
451 BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM); 462 BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
452 BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM); 463 BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
453 BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM); 464 BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
454 BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM); 465 BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);
455 BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM); 466 BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
456 BTFIXUPSET_CALL(clear_profile_irq, sun4m_clear_profile_irq, BTFIXUPCALL_NORM);
457 BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM); 467 BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
458 sparc_init_timers = sun4m_init_timers; 468 sparc_init_timers = sun4m_init_timers;
459#ifdef CONFIG_SMP 469#ifdef CONFIG_SMP
@@ -461,5 +471,6 @@ void __init sun4m_init_IRQ(void)
461 BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM); 471 BTFIXUPSET_CALL(clear_cpu_int, sun4m_clear_ipi, BTFIXUPCALL_NORM);
462 BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM); 472 BTFIXUPSET_CALL(set_irq_udt, sun4m_set_udt, BTFIXUPCALL_NORM);
463#endif 473#endif
474
464 /* Cannot enable interrupts until OBP ticker is disabled. */ 475 /* Cannot enable interrupts until OBP ticker is disabled. */
465} 476}
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index a14a76ac7f36..0c564ba9e709 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -71,6 +71,8 @@ void __cpuinit smp4m_callin(void)
71 local_flush_cache_all(); 71 local_flush_cache_all();
72 local_flush_tlb_all(); 72 local_flush_tlb_all();
73 73
74 notify_cpu_starting(cpuid);
75
74 /* Get our local ticker going. */ 76 /* Get our local ticker going. */
75 smp_setup_percpu_timer(); 77 smp_setup_percpu_timer();
76 78
@@ -313,6 +315,8 @@ void smp4m_cross_call_irq(void)
313 ccall_info.processors_out[i] = 1; 315 ccall_info.processors_out[i] = 1;
314} 316}
315 317
318extern void sun4m_clear_profile_irq(int cpu);
319
316void smp4m_percpu_timer_interrupt(struct pt_regs *regs) 320void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
317{ 321{
318 struct pt_regs *old_regs; 322 struct pt_regs *old_regs;
@@ -320,7 +324,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
320 324
321 old_regs = set_irq_regs(regs); 325 old_regs = set_irq_regs(regs);
322 326
323 clear_profile_irq(cpu); 327 sun4m_clear_profile_irq(cpu);
324 328
325 profile_tick(CPU_PROFILING); 329 profile_tick(CPU_PROFILING);
326 330
diff --git a/arch/sparc/kernel/sun4setup.c b/arch/sparc/kernel/sun4setup.c
deleted file mode 100644
index 229a52f55f16..000000000000
--- a/arch/sparc/kernel/sun4setup.c
+++ /dev/null
@@ -1,75 +0,0 @@
1/* sun4setup.c: Setup the hardware address of various items in the sun4
2 * architecture. Called from idprom_init
3 *
4 * Copyright (C) 1998 Chris G. Davis (cdavis@cois.on.ca)
5 */
6
7#include <asm/page.h>
8#include <asm/oplib.h>
9#include <asm/idprom.h>
10#include <asm/sun4paddr.h>
11#include <asm/machines.h>
12
13int sun4_memreg_physaddr;
14int sun4_ie_physaddr;
15int sun4_clock_physaddr;
16int sun4_timer_physaddr;
17int sun4_eth_physaddr;
18int sun4_si_physaddr;
19int sun4_bwtwo_physaddr;
20int sun4_zs0_physaddr;
21int sun4_zs1_physaddr;
22int sun4_dma_physaddr;
23int sun4_esp_physaddr;
24int sun4_ie_physaddr;
25
26void __init sun4setup(void)
27{
28 printk("Sun4 Hardware Setup v1.0 18/May/98 Chris Davis (cdavis@cois.on.ca). ");
29 /*
30 setup standard sun4 info
31 */
32 sun4_ie_physaddr=SUN4_IE_PHYSADDR;
33
34 /*
35 setup model specific info
36 */
37 switch(idprom->id_machtype) {
38 case (SM_SUN4 | SM_4_260 ):
39 printk("Setup for a SUN4/260\n");
40 sun4_memreg_physaddr=SUN4_200_MEMREG_PHYSADDR;
41 sun4_clock_physaddr=SUN4_200_CLOCK_PHYSADDR;
42 sun4_timer_physaddr=SUN4_UNUSED_PHYSADDR;
43 sun4_eth_physaddr=SUN4_200_ETH_PHYSADDR;
44 sun4_si_physaddr=SUN4_200_SI_PHYSADDR;
45 sun4_bwtwo_physaddr=SUN4_200_BWTWO_PHYSADDR;
46 sun4_dma_physaddr=SUN4_UNUSED_PHYSADDR;
47 sun4_esp_physaddr=SUN4_UNUSED_PHYSADDR;
48 break;
49 case (SM_SUN4 | SM_4_330 ):
50 printk("Setup for a SUN4/330\n");
51 sun4_memreg_physaddr=SUN4_300_MEMREG_PHYSADDR;
52 sun4_clock_physaddr=SUN4_300_CLOCK_PHYSADDR;
53 sun4_timer_physaddr=SUN4_300_TIMER_PHYSADDR;
54 sun4_eth_physaddr=SUN4_300_ETH_PHYSADDR;
55 sun4_si_physaddr=SUN4_UNUSED_PHYSADDR;
56 sun4_bwtwo_physaddr=SUN4_300_BWTWO_PHYSADDR;
57 sun4_dma_physaddr=SUN4_300_DMA_PHYSADDR;
58 sun4_esp_physaddr=SUN4_300_ESP_PHYSADDR;
59 break;
60 case (SM_SUN4 | SM_4_470 ):
61 printk("Setup for a SUN4/470\n");
62 sun4_memreg_physaddr=SUN4_400_MEMREG_PHYSADDR;
63 sun4_clock_physaddr=SUN4_400_CLOCK_PHYSADDR;
64 sun4_timer_physaddr=SUN4_400_TIMER_PHYSADDR;
65 sun4_eth_physaddr=SUN4_400_ETH_PHYSADDR;
66 sun4_si_physaddr=SUN4_UNUSED_PHYSADDR;
67 sun4_bwtwo_physaddr=SUN4_400_BWTWO_PHYSADDR;
68 sun4_dma_physaddr=SUN4_400_DMA_PHYSADDR;
69 sun4_esp_physaddr=SUN4_400_ESP_PHYSADDR;
70 break;
71 default:
72 ;
73 }
74}
75
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c
index 4d73421559c3..03035c852a43 100644
--- a/arch/sparc/kernel/sys_sparc.c
+++ b/arch/sparc/kernel/sys_sparc.c
@@ -53,7 +53,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
53 /* See asm-sparc/uaccess.h */ 53 /* See asm-sparc/uaccess.h */
54 if (len > TASK_SIZE - PAGE_SIZE) 54 if (len > TASK_SIZE - PAGE_SIZE)
55 return -ENOMEM; 55 return -ENOMEM;
56 if (ARCH_SUN4C_SUN4 && len > 0x20000000) 56 if (ARCH_SUN4C && len > 0x20000000)
57 return -ENOMEM; 57 return -ENOMEM;
58 if (!addr) 58 if (!addr)
59 addr = TASK_UNMAPPED_BASE; 59 addr = TASK_UNMAPPED_BASE;
@@ -65,7 +65,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
65 65
66 for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { 66 for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
67 /* At this point: (!vmm || addr < vmm->vm_end). */ 67 /* At this point: (!vmm || addr < vmm->vm_end). */
68 if (ARCH_SUN4C_SUN4 && addr < 0xe0000000 && 0x20000000 - len < addr) { 68 if (ARCH_SUN4C && addr < 0xe0000000 && 0x20000000 - len < addr) {
69 addr = PAGE_OFFSET; 69 addr = PAGE_OFFSET;
70 vmm = find_vma(current->mm, PAGE_OFFSET); 70 vmm = find_vma(current->mm, PAGE_OFFSET);
71 } 71 }
@@ -81,7 +81,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsi
81 81
82asmlinkage unsigned long sparc_brk(unsigned long brk) 82asmlinkage unsigned long sparc_brk(unsigned long brk)
83{ 83{
84 if(ARCH_SUN4C_SUN4) { 84 if(ARCH_SUN4C) {
85 if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000)) 85 if ((brk & 0xe0000000) != (current->mm->brk & 0xe0000000))
86 return current->mm->brk; 86 return current->mm->brk;
87 } 87 }
@@ -221,7 +221,7 @@ out:
221 221
222int sparc_mmap_check(unsigned long addr, unsigned long len) 222int sparc_mmap_check(unsigned long addr, unsigned long len)
223{ 223{
224 if (ARCH_SUN4C_SUN4 && 224 if (ARCH_SUN4C &&
225 (len > 0x20000000 || 225 (len > 0x20000000 ||
226 (addr < 0xe0000000 && addr + len > 0x20000000))) 226 (addr < 0xe0000000 && addr + len > 0x20000000)))
227 return -EINVAL; 227 return -EINVAL;
diff --git a/arch/sparc/kernel/tick14.c b/arch/sparc/kernel/tick14.c
index 707bfda86570..138bbf5f8724 100644
--- a/arch/sparc/kernel/tick14.c
+++ b/arch/sparc/kernel/tick14.c
@@ -1,31 +1,12 @@
1/* tick14.c 1/* tick14.c
2 * linux/arch/sparc/kernel/tick14.c
3 * 2 *
4 * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk) 3 * Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
5 * 4 *
6 * This file handles the Sparc specific level14 ticker 5 * This file handles the Sparc specific level14 ticker
7 * This is really useful for profiling OBP uses it for keyboard 6 * This is really useful for profiling OBP uses it for keyboard
8 * aborts and other stuff. 7 * aborts and other stuff.
9 *
10 *
11 */ 8 */
12#include <linux/errno.h>
13#include <linux/sched.h>
14#include <linux/kernel.h> 9#include <linux/kernel.h>
15#include <linux/param.h>
16#include <linux/string.h>
17#include <linux/mm.h>
18#include <linux/timex.h>
19#include <linux/interrupt.h>
20
21#include <asm/oplib.h>
22#include <asm/timer.h>
23#include <asm/mostek.h>
24#include <asm/system.h>
25#include <asm/irq.h>
26#include <asm/io.h>
27
28#include "irq.h"
29 10
30extern unsigned long lvl14_save[5]; 11extern unsigned long lvl14_save[5];
31static unsigned long *linux_lvl14 = NULL; 12static unsigned long *linux_lvl14 = NULL;
@@ -56,31 +37,3 @@ void install_obp_ticker(void)
56 linux_lvl14[2] = obp_lvl14[2]; 37 linux_lvl14[2] = obp_lvl14[2];
57 linux_lvl14[3] = obp_lvl14[3]; 38 linux_lvl14[3] = obp_lvl14[3];
58} 39}
59
60void claim_ticker14(irq_handler_t handler,
61 int irq_nr, unsigned int timeout )
62{
63 int cpu = smp_processor_id();
64
65 /* first we copy the obp handler instructions
66 */
67 __disable_irq(irq_nr);
68 if (!handler)
69 return;
70
71 linux_lvl14 = (unsigned long *)lvl14_save[4];
72 obp_lvl14[0] = linux_lvl14[0];
73 obp_lvl14[1] = linux_lvl14[1];
74 obp_lvl14[2] = linux_lvl14[2];
75 obp_lvl14[3] = linux_lvl14[3];
76
77 if (!request_irq(irq_nr,
78 handler,
79 (IRQF_DISABLED | SA_STATIC_ALLOC),
80 "counter14",
81 NULL)) {
82 install_linux_ticker();
83 load_profile_irq(cpu, timeout);
84 __enable_irq(irq_nr);
85 }
86}
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 0762f5db1924..62c1d94cb434 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -23,22 +23,24 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/time.h> 25#include <linux/time.h>
26#include <linux/rtc.h>
27#include <linux/rtc/m48t59.h>
26#include <linux/timex.h> 28#include <linux/timex.h>
27#include <linux/init.h> 29#include <linux/init.h>
28#include <linux/pci.h> 30#include <linux/pci.h>
29#include <linux/ioport.h> 31#include <linux/ioport.h>
30#include <linux/profile.h> 32#include <linux/profile.h>
33#include <linux/of.h>
31#include <linux/of_device.h> 34#include <linux/of_device.h>
35#include <linux/platform_device.h>
32 36
33#include <asm/oplib.h> 37#include <asm/oplib.h>
34#include <asm/timer.h> 38#include <asm/timer.h>
35#include <asm/mostek.h>
36#include <asm/system.h> 39#include <asm/system.h>
37#include <asm/irq.h> 40#include <asm/irq.h>
38#include <asm/io.h> 41#include <asm/io.h>
39#include <asm/idprom.h> 42#include <asm/idprom.h>
40#include <asm/machines.h> 43#include <asm/machines.h>
41#include <asm/sun4paddr.h>
42#include <asm/page.h> 44#include <asm/page.h>
43#include <asm/pcic.h> 45#include <asm/pcic.h>
44#include <asm/irq_regs.h> 46#include <asm/irq_regs.h>
@@ -46,34 +48,9 @@
46#include "irq.h" 48#include "irq.h"
47 49
48DEFINE_SPINLOCK(rtc_lock); 50DEFINE_SPINLOCK(rtc_lock);
49static enum sparc_clock_type sp_clock_typ;
50DEFINE_SPINLOCK(mostek_lock);
51void __iomem *mstk48t02_regs = NULL;
52static struct mostek48t08 __iomem *mstk48t08_regs = NULL;
53static int set_rtc_mmss(unsigned long); 51static int set_rtc_mmss(unsigned long);
54static int sbus_do_settimeofday(struct timespec *tv); 52static int sbus_do_settimeofday(struct timespec *tv);
55 53
56#ifdef CONFIG_SUN4
57struct intersil *intersil_clock;
58#define intersil_cmd(intersil_reg, intsil_cmd) intersil_reg->int_cmd_reg = \
59 (intsil_cmd)
60
61#define intersil_intr(intersil_reg, intsil_cmd) intersil_reg->int_intr_reg = \
62 (intsil_cmd)
63
64#define intersil_start(intersil_reg) intersil_cmd(intersil_reg, \
65 ( INTERSIL_START | INTERSIL_32K | INTERSIL_NORMAL | INTERSIL_24H |\
66 INTERSIL_INTR_ENABLE))
67
68#define intersil_stop(intersil_reg) intersil_cmd(intersil_reg, \
69 ( INTERSIL_STOP | INTERSIL_32K | INTERSIL_NORMAL | INTERSIL_24H |\
70 INTERSIL_INTR_ENABLE))
71
72#define intersil_read_intr(intersil_reg, towhere) towhere = \
73 intersil_reg->int_intr_reg
74
75#endif
76
77unsigned long profile_pc(struct pt_regs *regs) 54unsigned long profile_pc(struct pt_regs *regs)
78{ 55{
79 extern char __copy_user_begin[], __copy_user_end[]; 56 extern char __copy_user_begin[], __copy_user_end[];
@@ -96,7 +73,6 @@ unsigned long profile_pc(struct pt_regs *regs)
96EXPORT_SYMBOL(profile_pc); 73EXPORT_SYMBOL(profile_pc);
97 74
98__volatile__ unsigned int *master_l10_counter; 75__volatile__ unsigned int *master_l10_counter;
99__volatile__ unsigned int *master_l10_limit;
100 76
101/* 77/*
102 * timer_interrupt() needs to keep up the real-time clock, 78 * timer_interrupt() needs to keep up the real-time clock,
@@ -116,15 +92,7 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)
116 92
117 /* Protect counter clear so that do_gettimeoffset works */ 93 /* Protect counter clear so that do_gettimeoffset works */
118 write_seqlock(&xtime_lock); 94 write_seqlock(&xtime_lock);
119#ifdef CONFIG_SUN4 95
120 if((idprom->id_machtype == (SM_SUN4 | SM_4_260)) ||
121 (idprom->id_machtype == (SM_SUN4 | SM_4_110))) {
122 int temp;
123 intersil_read_intr(intersil_clock, temp);
124 /* re-enable the irq */
125 enable_pil_irq(10);
126 }
127#endif
128 clear_clock_irq(); 96 clear_clock_irq();
129 97
130 do_timer(1); 98 do_timer(1);
@@ -147,157 +115,56 @@ static irqreturn_t timer_interrupt(int dummy, void *dev_id)
147 return IRQ_HANDLED; 115 return IRQ_HANDLED;
148} 116}
149 117
150/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */ 118static unsigned char mostek_read_byte(struct device *dev, u32 ofs)
151static void __devinit kick_start_clock(void)
152{ 119{
153 struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; 120 struct platform_device *pdev = to_platform_device(dev);
154 unsigned char sec; 121 struct m48t59_plat_data *pdata = pdev->dev.platform_data;
155 int i, count; 122 void __iomem *regs = pdata->ioaddr;
156 123 unsigned char val = readb(regs + ofs);
157 prom_printf("CLOCK: Clock was stopped. Kick start "); 124
158 125 /* the year 0 is 1968 */
159 spin_lock_irq(&mostek_lock); 126 if (ofs == pdata->offset + M48T59_YEAR) {
160 127 val += 0x68;
161 /* Turn on the kick start bit to start the oscillator. */ 128 if ((val & 0xf) > 9)
162 regs->creg |= MSTK_CREG_WRITE; 129 val += 6;
163 regs->sec &= ~MSTK_STOP;
164 regs->hour |= MSTK_KICK_START;
165 regs->creg &= ~MSTK_CREG_WRITE;
166
167 spin_unlock_irq(&mostek_lock);
168
169 /* Delay to allow the clock oscillator to start. */
170 sec = MSTK_REG_SEC(regs);
171 for (i = 0; i < 3; i++) {
172 while (sec == MSTK_REG_SEC(regs))
173 for (count = 0; count < 100000; count++)
174 /* nothing */ ;
175 prom_printf(".");
176 sec = regs->sec;
177 }
178 prom_printf("\n");
179
180 spin_lock_irq(&mostek_lock);
181
182 /* Turn off kick start and set a "valid" time and date. */
183 regs->creg |= MSTK_CREG_WRITE;
184 regs->hour &= ~MSTK_KICK_START;
185 MSTK_SET_REG_SEC(regs,0);
186 MSTK_SET_REG_MIN(regs,0);
187 MSTK_SET_REG_HOUR(regs,0);
188 MSTK_SET_REG_DOW(regs,5);
189 MSTK_SET_REG_DOM(regs,1);
190 MSTK_SET_REG_MONTH(regs,8);
191 MSTK_SET_REG_YEAR(regs,1996 - MSTK_YEAR_ZERO);
192 regs->creg &= ~MSTK_CREG_WRITE;
193
194 spin_unlock_irq(&mostek_lock);
195
196 /* Ensure the kick start bit is off. If it isn't, turn it off. */
197 while (regs->hour & MSTK_KICK_START) {
198 prom_printf("CLOCK: Kick start still on!\n");
199
200 spin_lock_irq(&mostek_lock);
201 regs->creg |= MSTK_CREG_WRITE;
202 regs->hour &= ~MSTK_KICK_START;
203 regs->creg &= ~MSTK_CREG_WRITE;
204 spin_unlock_irq(&mostek_lock);
205 } 130 }
206 131 return val;
207 prom_printf("CLOCK: Kick start procedure successful.\n");
208}
209
210/* Return nonzero if the clock chip battery is low. */
211static inline int has_low_battery(void)
212{
213 struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
214 unsigned char data1, data2;
215
216 spin_lock_irq(&mostek_lock);
217 data1 = regs->eeprom[0]; /* Read some data. */
218 regs->eeprom[0] = ~data1; /* Write back the complement. */
219 data2 = regs->eeprom[0]; /* Read back the complement. */
220 regs->eeprom[0] = data1; /* Restore the original value. */
221 spin_unlock_irq(&mostek_lock);
222
223 return (data1 == data2); /* Was the write blocked? */
224} 132}
225 133
226static void __devinit mostek_set_system_time(void) 134static void mostek_write_byte(struct device *dev, u32 ofs, u8 val)
227{ 135{
228 unsigned int year, mon, day, hour, min, sec; 136 struct platform_device *pdev = to_platform_device(dev);
229 struct mostek48t02 *mregs; 137 struct m48t59_plat_data *pdata = pdev->dev.platform_data;
230 138 void __iomem *regs = pdata->ioaddr;
231 mregs = (struct mostek48t02 *)mstk48t02_regs; 139
232 if(!mregs) { 140 if (ofs == pdata->offset + M48T59_YEAR) {
233 prom_printf("Something wrong, clock regs not mapped yet.\n"); 141 if (val < 0x68)
234 prom_halt(); 142 val += 0x32;
235 } 143 else
236 spin_lock_irq(&mostek_lock); 144 val -= 0x68;
237 mregs->creg |= MSTK_CREG_READ; 145 if ((val & 0xf) > 9)
238 sec = MSTK_REG_SEC(mregs); 146 val += 6;
239 min = MSTK_REG_MIN(mregs); 147 if ((val & 0xf0) > 0x9A)
240 hour = MSTK_REG_HOUR(mregs); 148 val += 0x60;
241 day = MSTK_REG_DOM(mregs); 149 }
242 mon = MSTK_REG_MONTH(mregs); 150 writeb(val, regs + ofs);
243 year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
244 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
245 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
246 set_normalized_timespec(&wall_to_monotonic,
247 -xtime.tv_sec, -xtime.tv_nsec);
248 mregs->creg &= ~MSTK_CREG_READ;
249 spin_unlock_irq(&mostek_lock);
250} 151}
251 152
252/* Probe for the real time clock chip on Sun4 */ 153static struct m48t59_plat_data m48t59_data = {
253static inline void sun4_clock_probe(void) 154 .read_byte = mostek_read_byte,
254{ 155 .write_byte = mostek_write_byte,
255#ifdef CONFIG_SUN4 156};
256 int temp;
257 struct resource r;
258
259 memset(&r, 0, sizeof(r));
260 if( idprom->id_machtype == (SM_SUN4 | SM_4_330) ) {
261 sp_clock_typ = MSTK48T02;
262 r.start = sun4_clock_physaddr;
263 mstk48t02_regs = sbus_ioremap(&r, 0,
264 sizeof(struct mostek48t02), NULL);
265 mstk48t08_regs = NULL; /* To catch weirdness */
266 intersil_clock = NULL; /* just in case */
267
268 /* Kick start the clock if it is completely stopped. */
269 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
270 kick_start_clock();
271 } else if( idprom->id_machtype == (SM_SUN4 | SM_4_260)) {
272 /* intersil setup code */
273 printk("Clock: INTERSIL at %8x ",sun4_clock_physaddr);
274 sp_clock_typ = INTERSIL;
275 r.start = sun4_clock_physaddr;
276 intersil_clock = (struct intersil *)
277 sbus_ioremap(&r, 0, sizeof(*intersil_clock), "intersil");
278 mstk48t02_regs = 0; /* just be sure */
279 mstk48t08_regs = NULL; /* ditto */
280 /* initialise the clock */
281
282 intersil_intr(intersil_clock,INTERSIL_INT_100HZ);
283
284 intersil_start(intersil_clock);
285
286 intersil_read_intr(intersil_clock, temp);
287 while (!(temp & 0x80))
288 intersil_read_intr(intersil_clock, temp);
289
290 intersil_read_intr(intersil_clock, temp);
291 while (!(temp & 0x80))
292 intersil_read_intr(intersil_clock, temp);
293
294 intersil_stop(intersil_clock);
295 157
296 } 158/* resource is set at runtime */
297#endif 159static struct platform_device m48t59_rtc = {
298} 160 .name = "rtc-m48t59",
161 .id = 0,
162 .num_resources = 1,
163 .dev = {
164 .platform_data = &m48t59_data,
165 },
166};
299 167
300#ifndef CONFIG_SUN4
301static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) 168static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match)
302{ 169{
303 struct device_node *dp = op->node; 170 struct device_node *dp = op->node;
@@ -306,38 +173,26 @@ static int __devinit clock_probe(struct of_device *op, const struct of_device_id
306 if (!model) 173 if (!model)
307 return -ENODEV; 174 return -ENODEV;
308 175
176 m48t59_rtc.resource = &op->resource[0];
309 if (!strcmp(model, "mk48t02")) { 177 if (!strcmp(model, "mk48t02")) {
310 sp_clock_typ = MSTK48T02;
311
312 /* Map the clock register io area read-only */ 178 /* Map the clock register io area read-only */
313 mstk48t02_regs = of_ioremap(&op->resource[0], 0, 179 m48t59_data.ioaddr = of_ioremap(&op->resource[0], 0,
314 sizeof(struct mostek48t02), 180 2048, "rtc-m48t59");
315 "mk48t02"); 181 m48t59_data.type = M48T59RTC_TYPE_M48T02;
316 mstk48t08_regs = NULL; /* To catch weirdness */
317 } else if (!strcmp(model, "mk48t08")) { 182 } else if (!strcmp(model, "mk48t08")) {
318 sp_clock_typ = MSTK48T08; 183 m48t59_data.ioaddr = of_ioremap(&op->resource[0], 0,
319 mstk48t08_regs = of_ioremap(&op->resource[0], 0, 184 8192, "rtc-m48t59");
320 sizeof(struct mostek48t08), 185 m48t59_data.type = M48T59RTC_TYPE_M48T08;
321 "mk48t08");
322
323 mstk48t02_regs = &mstk48t08_regs->regs;
324 } else 186 } else
325 return -ENODEV; 187 return -ENODEV;
326 188
327 /* Report a low battery voltage condition. */ 189 if (platform_device_register(&m48t59_rtc) < 0)
328 if (has_low_battery()) 190 printk(KERN_ERR "Registering RTC device failed\n");
329 printk(KERN_CRIT "NVRAM: Low battery voltage!\n");
330
331 /* Kick start the clock if it is completely stopped. */
332 if (mostek_read(mstk48t02_regs + MOSTEK_SEC) & MSTK_STOP)
333 kick_start_clock();
334
335 mostek_set_system_time();
336 191
337 return 0; 192 return 0;
338} 193}
339 194
340static struct of_device_id clock_match[] = { 195static struct of_device_id __initdata clock_match[] = {
341 { 196 {
342 .name = "eeprom", 197 .name = "eeprom",
343 }, 198 },
@@ -348,7 +203,7 @@ static struct of_platform_driver clock_driver = {
348 .match_table = clock_match, 203 .match_table = clock_match,
349 .probe = clock_probe, 204 .probe = clock_probe,
350 .driver = { 205 .driver = {
351 .name = "clock", 206 .name = "rtc",
352 }, 207 },
353}; 208};
354 209
@@ -364,7 +219,6 @@ static int __init clock_init(void)
364 * need to see the clock registers. 219 * need to see the clock registers.
365 */ 220 */
366fs_initcall(clock_init); 221fs_initcall(clock_init);
367#endif /* !CONFIG_SUN4 */
368 222
369static void __init sbus_time_init(void) 223static void __init sbus_time_init(void)
370{ 224{
@@ -372,51 +226,8 @@ static void __init sbus_time_init(void)
372 BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM); 226 BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM);
373 btfixup(); 227 btfixup();
374 228
375 if (ARCH_SUN4)
376 sun4_clock_probe();
377
378 sparc_init_timers(timer_interrupt); 229 sparc_init_timers(timer_interrupt);
379 230
380#ifdef CONFIG_SUN4
381 if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) {
382 mostek_set_system_time();
383 } else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) {
384 /* initialise the intersil on sun4 */
385 unsigned int year, mon, day, hour, min, sec;
386 int temp;
387 struct intersil *iregs;
388
389 iregs=intersil_clock;
390 if(!iregs) {
391 prom_printf("Something wrong, clock regs not mapped yet.\n");
392 prom_halt();
393 }
394
395 intersil_intr(intersil_clock,INTERSIL_INT_100HZ);
396 disable_pil_irq(10);
397 intersil_stop(iregs);
398 intersil_read_intr(intersil_clock, temp);
399
400 temp = iregs->clk.int_csec;
401
402 sec = iregs->clk.int_sec;
403 min = iregs->clk.int_min;
404 hour = iregs->clk.int_hour;
405 day = iregs->clk.int_day;
406 mon = iregs->clk.int_month;
407 year = MSTK_CVT_YEAR(iregs->clk.int_year);
408
409 enable_pil_irq(10);
410 intersil_start(iregs);
411
412 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
413 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
414 set_normalized_timespec(&wall_to_monotonic,
415 -xtime.tv_sec, -xtime.tv_nsec);
416 printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
417 }
418#endif
419
420 /* Now that OBP ticker has been silenced, it is safe to enable IRQ. */ 231 /* Now that OBP ticker has been silenced, it is safe to enable IRQ. */
421 local_irq_enable(); 232 local_irq_enable();
422} 233}
@@ -522,80 +333,15 @@ static int sbus_do_settimeofday(struct timespec *tv)
522 return 0; 333 return 0;
523} 334}
524 335
525/* 336static int set_rtc_mmss(unsigned long secs)
526 * BUG: This routine does not handle hour overflow properly; it just
527 * sets the minutes. Usually you won't notice until after reboot!
528 */
529static int set_rtc_mmss(unsigned long nowtime)
530{ 337{
531 int real_seconds, real_minutes, mostek_minutes; 338 struct rtc_device *rtc = rtc_class_open("rtc0");
532 struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; 339 int err = -1;
533 unsigned long flags;
534#ifdef CONFIG_SUN4
535 struct intersil *iregs = intersil_clock;
536 int temp;
537#endif
538 340
539 /* Not having a register set can lead to trouble. */ 341 if (rtc) {
540 if (!regs) { 342 err = rtc_set_mmss(rtc, secs);
541#ifdef CONFIG_SUN4 343 rtc_class_close(rtc);
542 if(!iregs)
543 return -1;
544 else {
545 temp = iregs->clk.int_csec;
546
547 mostek_minutes = iregs->clk.int_min;
548
549 real_seconds = nowtime % 60;
550 real_minutes = nowtime / 60;
551 if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
552 real_minutes += 30; /* correct for half hour time zone */
553 real_minutes %= 60;
554
555 if (abs(real_minutes - mostek_minutes) < 30) {
556 intersil_stop(iregs);
557 iregs->clk.int_sec=real_seconds;
558 iregs->clk.int_min=real_minutes;
559 intersil_start(iregs);
560 } else {
561 printk(KERN_WARNING
562 "set_rtc_mmss: can't update from %d to %d\n",
563 mostek_minutes, real_minutes);
564 return -1;
565 }
566
567 return 0;
568 }
569#endif
570 } 344 }
571 345
572 spin_lock_irqsave(&mostek_lock, flags); 346 return err;
573 /* Read the current RTC minutes. */
574 regs->creg |= MSTK_CREG_READ;
575 mostek_minutes = MSTK_REG_MIN(regs);
576 regs->creg &= ~MSTK_CREG_READ;
577
578 /*
579 * since we're only adjusting minutes and seconds,
580 * don't interfere with hour overflow. This avoids
581 * messing with unknown time zones but requires your
582 * RTC not to be off by more than 15 minutes
583 */
584 real_seconds = nowtime % 60;
585 real_minutes = nowtime / 60;
586 if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
587 real_minutes += 30; /* correct for half hour time zone */
588 real_minutes %= 60;
589
590 if (abs(real_minutes - mostek_minutes) < 30) {
591 regs->creg |= MSTK_CREG_WRITE;
592 MSTK_SET_REG_SEC(regs,real_seconds);
593 MSTK_SET_REG_MIN(regs,real_minutes);
594 regs->creg &= ~MSTK_CREG_WRITE;
595 spin_unlock_irqrestore(&mostek_lock, flags);
596 return 0;
597 } else {
598 spin_unlock_irqrestore(&mostek_lock, flags);
599 return -1;
600 }
601} 347}
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 5d45d5fd8c99..2b7d50659036 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -43,23 +43,6 @@ void syscall_trace_exit(struct pt_regs *regs)
43{ 43{
44} 44}
45 45
46void sun4m_nmi(struct pt_regs *regs)
47{
48 unsigned long afsr, afar;
49
50 printk("Aieee: sun4m NMI received!\n");
51 /* XXX HyperSparc hack XXX */
52 __asm__ __volatile__("mov 0x500, %%g1\n\t"
53 "lda [%%g1] 0x4, %0\n\t"
54 "mov 0x600, %%g1\n\t"
55 "lda [%%g1] 0x4, %1\n\t" :
56 "=r" (afsr), "=r" (afar));
57 printk("afsr=%08lx afar=%08lx\n", afsr, afar);
58 printk("you lose buddy boy...\n");
59 show_regs(regs);
60 prom_halt();
61}
62
63void sun4d_nmi(struct pt_regs *regs) 46void sun4d_nmi(struct pt_regs *regs)
64{ 47{
65 printk("Aieee: sun4d NMI received!\n"); 48 printk("Aieee: sun4d NMI received!\n");
diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile
index 109c8b22cb38..ea88955d97ff 100644
--- a/arch/sparc/mm/Makefile
+++ b/arch/sparc/mm/Makefile
@@ -3,13 +3,8 @@
3 3
4EXTRA_AFLAGS := -ansi 4EXTRA_AFLAGS := -ansi
5 5
6obj-y := fault.o init.o loadmmu.o generic.o extable.o btfixup.o 6obj-y := fault.o init.o loadmmu.o generic.o extable.o btfixup.o \
7 7 srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o
8ifeq ($(CONFIG_SUN4),y)
9obj-y += nosrmmu.o
10else
11obj-y += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o
12endif
13 8
14ifdef CONFIG_HIGHMEM 9ifdef CONFIG_HIGHMEM
15obj-y += highmem.o 10obj-y += highmem.o
diff --git a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c
index a312d127d47a..5175ac2f4820 100644
--- a/arch/sparc/mm/btfixup.c
+++ b/arch/sparc/mm/btfixup.c
@@ -20,11 +20,7 @@
20 20
21extern char *srmmu_name; 21extern char *srmmu_name;
22static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; 22static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for ";
23#ifdef CONFIG_SUN4
24static char str_sun4c[] __initdata = "sun4\n";
25#else
26static char str_sun4c[] __initdata = "sun4c\n"; 23static char str_sun4c[] __initdata = "sun4c\n";
27#endif
28static char str_srmmu[] __initdata = "srmmu[%s]/"; 24static char str_srmmu[] __initdata = "srmmu[%s]/";
29static char str_iommu[] __initdata = "iommu\n"; 25static char str_iommu[] __initdata = "iommu\n";
30static char str_iounit[] __initdata = "io-unit\n"; 26static char str_iounit[] __initdata = "io-unit\n";
@@ -86,7 +82,7 @@ void __init btfixup(void)
86 if (!visited) { 82 if (!visited) {
87 visited++; 83 visited++;
88 printk(version); 84 printk(version);
89 if (ARCH_SUN4C_SUN4) 85 if (ARCH_SUN4C)
90 printk(str_sun4c); 86 printk(str_sun4c);
91 else { 87 else {
92 printk(str_srmmu, srmmu_name); 88 printk(str_srmmu, srmmu_name);
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 3604c2e86709..a507e1174662 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -191,7 +191,7 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
191 * only copy the information from the master page table, 191 * only copy the information from the master page table,
192 * nothing more. 192 * nothing more.
193 */ 193 */
194 if (!ARCH_SUN4C_SUN4 && address >= TASK_SIZE) 194 if (!ARCH_SUN4C && address >= TASK_SIZE)
195 goto vmalloc_fault; 195 goto vmalloc_fault;
196 196
197 info.si_code = SEGV_MAPERR; 197 info.si_code = SEGV_MAPERR;
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index e103f1bb3777..677c1e187a23 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -23,6 +23,7 @@
23#include <linux/highmem.h> 23#include <linux/highmem.h>
24#include <linux/bootmem.h> 24#include <linux/bootmem.h>
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26#include <linux/poison.h>
26 27
27#include <asm/system.h> 28#include <asm/system.h>
28#include <asm/vac-ops.h> 29#include <asm/vac-ops.h>
@@ -480,6 +481,7 @@ void free_initmem (void)
480 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { 481 for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
481 struct page *p; 482 struct page *p;
482 483
484 memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
483 p = virt_to_page(addr); 485 p = virt_to_page(addr);
484 486
485 ClearPageReserved(p); 487 ClearPageReserved(p);
@@ -488,20 +490,26 @@ void free_initmem (void)
488 totalram_pages++; 490 totalram_pages++;
489 num_physpages++; 491 num_physpages++;
490 } 492 }
491 printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); 493 printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n",
494 (&__init_end - &__init_begin) >> 10);
492} 495}
493 496
494#ifdef CONFIG_BLK_DEV_INITRD 497#ifdef CONFIG_BLK_DEV_INITRD
495void free_initrd_mem(unsigned long start, unsigned long end) 498void free_initrd_mem(unsigned long start, unsigned long end)
496{ 499{
497 if (start < end) 500 if (start < end)
498 printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10); 501 printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
502 (end - start) >> 10);
499 for (; start < end; start += PAGE_SIZE) { 503 for (; start < end; start += PAGE_SIZE) {
500 struct page *p = virt_to_page(start); 504 struct page *p;
505
506 memset((void *)start, POISON_FREE_INITMEM, PAGE_SIZE);
507 p = virt_to_page(start);
501 508
502 ClearPageReserved(p); 509 ClearPageReserved(p);
503 init_page_count(p); 510 init_page_count(p);
504 __free_page(p); 511 __free_page(p);
512 totalram_pages++;
505 num_physpages++; 513 num_physpages++;
506 } 514 }
507} 515}
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index f167835db3df..daadf5f88050 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -12,10 +12,11 @@
12#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ 12#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14#include <linux/scatterlist.h> 14#include <linux/scatterlist.h>
15#include <linux/of.h>
16#include <linux/of_device.h>
15 17
16#include <asm/pgalloc.h> 18#include <asm/pgalloc.h>
17#include <asm/pgtable.h> 19#include <asm/pgtable.h>
18#include <asm/sbus.h>
19#include <asm/io.h> 20#include <asm/io.h>
20#include <asm/io-unit.h> 21#include <asm/io-unit.h>
21#include <asm/mxcc.h> 22#include <asm/mxcc.h>
@@ -34,13 +35,10 @@
34#define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID) 35#define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID)
35#define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) 36#define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM)
36 37
37void __init 38static void __init iounit_iommu_init(struct of_device *op)
38iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
39{ 39{
40 iopte_t *xpt, *xptend;
41 struct iounit_struct *iounit; 40 struct iounit_struct *iounit;
42 struct linux_prom_registers iommu_promregs[PROMREG_MAX]; 41 iopte_t *xpt, *xptend;
43 struct resource r;
44 42
45 iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); 43 iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
46 if (!iounit) { 44 if (!iounit) {
@@ -55,18 +53,13 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
55 iounit->rotor[1] = IOUNIT_BMAP2_START; 53 iounit->rotor[1] = IOUNIT_BMAP2_START;
56 iounit->rotor[2] = IOUNIT_BMAPM_START; 54 iounit->rotor[2] = IOUNIT_BMAPM_START;
57 55
58 xpt = NULL; 56 xpt = of_ioremap(&op->resource[2], 0, PAGE_SIZE * 16, "XPT");
59 if(prom_getproperty(sbi_node, "reg", (void *) iommu_promregs, 57 if (!xpt) {
60 sizeof(iommu_promregs)) != -1) { 58 prom_printf("SUN4D: Cannot map External Page Table.");
61 prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3); 59 prom_halt();
62 memset(&r, 0, sizeof(r));
63 r.flags = iommu_promregs[2].which_io;
64 r.start = iommu_promregs[2].phys_addr;
65 xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT");
66 } 60 }
67 if(!xpt) panic("Cannot map External Page Table.");
68 61
69 sbus->ofdev.dev.archdata.iommu = iounit; 62 op->dev.archdata.iommu = iounit;
70 iounit->page_table = xpt; 63 iounit->page_table = xpt;
71 spin_lock_init(&iounit->lock); 64 spin_lock_init(&iounit->lock);
72 65
@@ -75,6 +68,25 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
75 iopte_val(*xpt++) = 0; 68 iopte_val(*xpt++) = 0;
76} 69}
77 70
71static int __init iounit_init(void)
72{
73 extern void sun4d_init_sbi_irq(void);
74 struct device_node *dp;
75
76 for_each_node_by_name(dp, "sbi") {
77 struct of_device *op = of_find_device_by_node(dp);
78
79 iounit_iommu_init(op);
80 of_propagate_archdata(op);
81 }
82
83 sun4d_init_sbi_irq();
84
85 return 0;
86}
87
88subsys_initcall(iounit_init);
89
78/* One has to hold iounit->lock to call this */ 90/* One has to hold iounit->lock to call this */
79static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) 91static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size)
80{ 92{
@@ -124,10 +136,10 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan);
124 return vaddr; 136 return vaddr;
125} 137}
126 138
127static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus) 139static __u32 iounit_get_scsi_one(struct device *dev, char *vaddr, unsigned long len)
128{ 140{
141 struct iounit_struct *iounit = dev->archdata.iommu;
129 unsigned long ret, flags; 142 unsigned long ret, flags;
130 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
131 143
132 spin_lock_irqsave(&iounit->lock, flags); 144 spin_lock_irqsave(&iounit->lock, flags);
133 ret = iounit_get_area(iounit, (unsigned long)vaddr, len); 145 ret = iounit_get_area(iounit, (unsigned long)vaddr, len);
@@ -135,10 +147,10 @@ static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus
135 return ret; 147 return ret;
136} 148}
137 149
138static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 150static void iounit_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
139{ 151{
152 struct iounit_struct *iounit = dev->archdata.iommu;
140 unsigned long flags; 153 unsigned long flags;
141 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
142 154
143 /* FIXME: Cache some resolved pages - often several sg entries are to the same page */ 155 /* FIXME: Cache some resolved pages - often several sg entries are to the same page */
144 spin_lock_irqsave(&iounit->lock, flags); 156 spin_lock_irqsave(&iounit->lock, flags);
@@ -151,10 +163,10 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
151 spin_unlock_irqrestore(&iounit->lock, flags); 163 spin_unlock_irqrestore(&iounit->lock, flags);
152} 164}
153 165
154static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) 166static void iounit_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)
155{ 167{
168 struct iounit_struct *iounit = dev->archdata.iommu;
156 unsigned long flags; 169 unsigned long flags;
157 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
158 170
159 spin_lock_irqsave(&iounit->lock, flags); 171 spin_lock_irqsave(&iounit->lock, flags);
160 len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; 172 len = ((vaddr & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
@@ -165,11 +177,11 @@ static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_
165 spin_unlock_irqrestore(&iounit->lock, flags); 177 spin_unlock_irqrestore(&iounit->lock, flags);
166} 178}
167 179
168static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 180static void iounit_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
169{ 181{
182 struct iounit_struct *iounit = dev->archdata.iommu;
170 unsigned long flags; 183 unsigned long flags;
171 unsigned long vaddr, len; 184 unsigned long vaddr, len;
172 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
173 185
174 spin_lock_irqsave(&iounit->lock, flags); 186 spin_lock_irqsave(&iounit->lock, flags);
175 while (sz != 0) { 187 while (sz != 0) {
@@ -185,12 +197,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_
185} 197}
186 198
187#ifdef CONFIG_SBUS 199#ifdef CONFIG_SBUS
188static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, int len) 200static int iounit_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va, __u32 addr, int len)
189{ 201{
202 struct iounit_struct *iounit = dev->archdata.iommu;
190 unsigned long page, end; 203 unsigned long page, end;
191 pgprot_t dvma_prot; 204 pgprot_t dvma_prot;
192 iopte_t *iopte; 205 iopte_t *iopte;
193 struct sbus_bus *sbus;
194 206
195 *pba = addr; 207 *pba = addr;
196 208
@@ -212,12 +224,8 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in
212 224
213 i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); 225 i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT);
214 226
215 for_each_sbus(sbus) { 227 iopte = (iopte_t *)(iounit->page_table + i);
216 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu; 228 *iopte = MKIOPTE(__pa(page));
217
218 iopte = (iopte_t *)(iounit->page_table + i);
219 *iopte = MKIOPTE(__pa(page));
220 }
221 } 229 }
222 addr += PAGE_SIZE; 230 addr += PAGE_SIZE;
223 va += PAGE_SIZE; 231 va += PAGE_SIZE;
@@ -228,23 +236,10 @@ static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, in
228 return 0; 236 return 0;
229} 237}
230 238
231static void iounit_unmap_dma_area(unsigned long addr, int len) 239static void iounit_unmap_dma_area(struct device *dev, unsigned long addr, int len)
232{ 240{
233 /* XXX Somebody please fill this in */ 241 /* XXX Somebody please fill this in */
234} 242}
235
236/* XXX We do not pass sbus device here, bad. */
237static struct page *iounit_translate_dvma(unsigned long addr)
238{
239 struct sbus_bus *sbus = sbus_root; /* They are all the same */
240 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
241 int i;
242 iopte_t *iopte;
243
244 i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT);
245 iopte = (iopte_t *)(iounit->page_table + i);
246 return pfn_to_page(iopte_val(*iopte) >> (PAGE_SHIFT-4)); /* XXX sun4d guru, help */
247}
248#endif 243#endif
249 244
250static char *iounit_lockarea(char *vaddr, unsigned long len) 245static char *iounit_lockarea(char *vaddr, unsigned long len)
@@ -271,54 +266,5 @@ void __init ld_mmu_iounit(void)
271#ifdef CONFIG_SBUS 266#ifdef CONFIG_SBUS
272 BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM); 267 BTFIXUPSET_CALL(mmu_map_dma_area, iounit_map_dma_area, BTFIXUPCALL_NORM);
273 BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM); 268 BTFIXUPSET_CALL(mmu_unmap_dma_area, iounit_unmap_dma_area, BTFIXUPCALL_NORM);
274 BTFIXUPSET_CALL(mmu_translate_dvma, iounit_translate_dvma, BTFIXUPCALL_NORM);
275#endif 269#endif
276} 270}
277
278__u32 iounit_map_dma_init(struct sbus_bus *sbus, int size)
279{
280 int i, j, k, npages;
281 unsigned long rotor, scan, limit;
282 unsigned long flags;
283 __u32 ret;
284 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
285
286 npages = (size + (PAGE_SIZE-1)) >> PAGE_SHIFT;
287 i = 0x0213;
288 spin_lock_irqsave(&iounit->lock, flags);
289next: j = (i & 15);
290 rotor = iounit->rotor[j - 1];
291 limit = iounit->limit[j];
292 scan = rotor;
293nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan);
294 if (scan + npages > limit) {
295 if (limit != rotor) {
296 limit = rotor;
297 scan = iounit->limit[j - 1];
298 goto nexti;
299 }
300 i >>= 4;
301 if (!(i & 15))
302 panic("iounit_map_dma_init: Couldn't find free iopte slots for %d bytes\n", size);
303 goto next;
304 }
305 for (k = 1, scan++; k < npages; k++)
306 if (test_bit(scan++, iounit->bmap))
307 goto nexti;
308 iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1];
309 scan -= npages;
310 ret = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT);
311 for (k = 0; k < npages; k++, scan++)
312 set_bit(scan, iounit->bmap);
313 spin_unlock_irqrestore(&iounit->lock, flags);
314 return ret;
315}
316
317__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus)
318{
319 int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
320 struct iounit_struct *iounit = sbus->ofdev.dev.archdata.iommu;
321
322 iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK));
323 return vaddr + (((unsigned long)addr) & ~PAGE_MASK);
324}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 4b934270f05e..e7a499e3aa3c 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -13,10 +13,11 @@
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ 14#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
15#include <linux/scatterlist.h> 15#include <linux/scatterlist.h>
16#include <linux/of.h>
17#include <linux/of_device.h>
16 18
17#include <asm/pgalloc.h> 19#include <asm/pgalloc.h>
18#include <asm/pgtable.h> 20#include <asm/pgtable.h>
19#include <asm/sbus.h>
20#include <asm/io.h> 21#include <asm/io.h>
21#include <asm/mxcc.h> 22#include <asm/mxcc.h>
22#include <asm/mbus.h> 23#include <asm/mbus.h>
@@ -55,30 +56,21 @@ static pgprot_t dvma_prot; /* Consistent mapping pte flags */
55#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID) 56#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)
56#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ) 57#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ)
57 58
58void __init 59static void __init sbus_iommu_init(struct of_device *op)
59iommu_init(int iommund, struct sbus_bus *sbus)
60{ 60{
61 unsigned int impl, vers;
62 unsigned long tmp;
63 struct iommu_struct *iommu; 61 struct iommu_struct *iommu;
64 struct linux_prom_registers iommu_promregs[PROMREG_MAX]; 62 unsigned int impl, vers;
65 struct resource r;
66 unsigned long *bitmap; 63 unsigned long *bitmap;
64 unsigned long tmp;
67 65
68 iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC); 66 iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC);
69 if (!iommu) { 67 if (!iommu) {
70 prom_printf("Unable to allocate iommu structure\n"); 68 prom_printf("Unable to allocate iommu structure\n");
71 prom_halt(); 69 prom_halt();
72 } 70 }
73 iommu->regs = NULL; 71
74 if (prom_getproperty(iommund, "reg", (void *) iommu_promregs, 72 iommu->regs = of_ioremap(&op->resource[0], 0, PAGE_SIZE * 3,
75 sizeof(iommu_promregs)) != -1) { 73 "iommu_regs");
76 memset(&r, 0, sizeof(r));
77 r.flags = iommu_promregs[0].which_io;
78 r.start = iommu_promregs[0].phys_addr;
79 iommu->regs = (struct iommu_regs *)
80 sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs");
81 }
82 if (!iommu->regs) { 74 if (!iommu->regs) {
83 prom_printf("Cannot map IOMMU registers\n"); 75 prom_printf("Cannot map IOMMU registers\n");
84 prom_halt(); 76 prom_halt();
@@ -128,13 +120,29 @@ iommu_init(int iommund, struct sbus_bus *sbus)
128 else 120 else
129 iommu->usemap.num_colors = 1; 121 iommu->usemap.num_colors = 1;
130 122
131 printk("IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n", 123 printk(KERN_INFO "IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n",
132 impl, vers, iommu->page_table, 124 impl, vers, iommu->page_table,
133 (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); 125 (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES);
126
127 op->dev.archdata.iommu = iommu;
128}
129
130static int __init iommu_init(void)
131{
132 struct device_node *dp;
133
134 for_each_node_by_name(dp, "iommu") {
135 struct of_device *op = of_find_device_by_node(dp);
136
137 sbus_iommu_init(op);
138 of_propagate_archdata(op);
139 }
134 140
135 sbus->ofdev.dev.archdata.iommu = iommu; 141 return 0;
136} 142}
137 143
144subsys_initcall(iommu_init);
145
138/* This begs to be btfixup-ed by srmmu. */ 146/* This begs to be btfixup-ed by srmmu. */
139/* Flush the iotlb entries to ram. */ 147/* Flush the iotlb entries to ram. */
140/* This could be better if we didn't have to flush whole pages. */ 148/* This could be better if we didn't have to flush whole pages. */
@@ -164,9 +172,9 @@ static void iommu_flush_iotlb(iopte_t *iopte, unsigned int niopte)
164 } 172 }
165} 173}
166 174
167static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) 175static u32 iommu_get_one(struct device *dev, struct page *page, int npages)
168{ 176{
169 struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; 177 struct iommu_struct *iommu = dev->archdata.iommu;
170 int ioptex; 178 int ioptex;
171 iopte_t *iopte, *iopte0; 179 iopte_t *iopte, *iopte0;
172 unsigned int busa, busa0; 180 unsigned int busa, busa0;
@@ -194,8 +202,7 @@ static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus)
194 return busa0; 202 return busa0;
195} 203}
196 204
197static u32 iommu_get_scsi_one(char *vaddr, unsigned int len, 205static u32 iommu_get_scsi_one(struct device *dev, char *vaddr, unsigned int len)
198 struct sbus_bus *sbus)
199{ 206{
200 unsigned long off; 207 unsigned long off;
201 int npages; 208 int npages;
@@ -205,22 +212,22 @@ static u32 iommu_get_scsi_one(char *vaddr, unsigned int len,
205 off = (unsigned long)vaddr & ~PAGE_MASK; 212 off = (unsigned long)vaddr & ~PAGE_MASK;
206 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT; 213 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT;
207 page = virt_to_page((unsigned long)vaddr & PAGE_MASK); 214 page = virt_to_page((unsigned long)vaddr & PAGE_MASK);
208 busa = iommu_get_one(page, npages, sbus); 215 busa = iommu_get_one(dev, page, npages);
209 return busa + off; 216 return busa + off;
210} 217}
211 218
212static __u32 iommu_get_scsi_one_noflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) 219static __u32 iommu_get_scsi_one_noflush(struct device *dev, char *vaddr, unsigned long len)
213{ 220{
214 return iommu_get_scsi_one(vaddr, len, sbus); 221 return iommu_get_scsi_one(dev, vaddr, len);
215} 222}
216 223
217static __u32 iommu_get_scsi_one_gflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) 224static __u32 iommu_get_scsi_one_gflush(struct device *dev, char *vaddr, unsigned long len)
218{ 225{
219 flush_page_for_dma(0); 226 flush_page_for_dma(0);
220 return iommu_get_scsi_one(vaddr, len, sbus); 227 return iommu_get_scsi_one(dev, vaddr, len);
221} 228}
222 229
223static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) 230static __u32 iommu_get_scsi_one_pflush(struct device *dev, char *vaddr, unsigned long len)
224{ 231{
225 unsigned long page = ((unsigned long) vaddr) & PAGE_MASK; 232 unsigned long page = ((unsigned long) vaddr) & PAGE_MASK;
226 233
@@ -228,23 +235,23 @@ static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sb
228 flush_page_for_dma(page); 235 flush_page_for_dma(page);
229 page += PAGE_SIZE; 236 page += PAGE_SIZE;
230 } 237 }
231 return iommu_get_scsi_one(vaddr, len, sbus); 238 return iommu_get_scsi_one(dev, vaddr, len);
232} 239}
233 240
234static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 241static void iommu_get_scsi_sgl_noflush(struct device *dev, struct scatterlist *sg, int sz)
235{ 242{
236 int n; 243 int n;
237 244
238 while (sz != 0) { 245 while (sz != 0) {
239 --sz; 246 --sz;
240 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 247 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
241 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; 248 sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
242 sg->dvma_length = (__u32) sg->length; 249 sg->dvma_length = (__u32) sg->length;
243 sg = sg_next(sg); 250 sg = sg_next(sg);
244 } 251 }
245} 252}
246 253
247static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 254static void iommu_get_scsi_sgl_gflush(struct device *dev, struct scatterlist *sg, int sz)
248{ 255{
249 int n; 256 int n;
250 257
@@ -252,13 +259,13 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
252 while (sz != 0) { 259 while (sz != 0) {
253 --sz; 260 --sz;
254 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 261 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
255 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; 262 sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
256 sg->dvma_length = (__u32) sg->length; 263 sg->dvma_length = (__u32) sg->length;
257 sg = sg_next(sg); 264 sg = sg_next(sg);
258 } 265 }
259} 266}
260 267
261static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 268static void iommu_get_scsi_sgl_pflush(struct device *dev, struct scatterlist *sg, int sz)
262{ 269{
263 unsigned long page, oldpage = 0; 270 unsigned long page, oldpage = 0;
264 int n, i; 271 int n, i;
@@ -283,15 +290,15 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
283 } 290 }
284 } 291 }
285 292
286 sg->dvma_address = iommu_get_one(sg_page(sg), n, sbus) + sg->offset; 293 sg->dvma_address = iommu_get_one(dev, sg_page(sg), n) + sg->offset;
287 sg->dvma_length = (__u32) sg->length; 294 sg->dvma_length = (__u32) sg->length;
288 sg = sg_next(sg); 295 sg = sg_next(sg);
289 } 296 }
290} 297}
291 298
292static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) 299static void iommu_release_one(struct device *dev, u32 busa, int npages)
293{ 300{
294 struct iommu_struct *iommu = sbus->ofdev.dev.archdata.iommu; 301 struct iommu_struct *iommu = dev->archdata.iommu;
295 int ioptex; 302 int ioptex;
296 int i; 303 int i;
297 304
@@ -305,17 +312,17 @@ static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus)
305 bit_map_clear(&iommu->usemap, ioptex, npages); 312 bit_map_clear(&iommu->usemap, ioptex, npages);
306} 313}
307 314
308static void iommu_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) 315static void iommu_release_scsi_one(struct device *dev, __u32 vaddr, unsigned long len)
309{ 316{
310 unsigned long off; 317 unsigned long off;
311 int npages; 318 int npages;
312 319
313 off = vaddr & ~PAGE_MASK; 320 off = vaddr & ~PAGE_MASK;
314 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT; 321 npages = (off + len + PAGE_SIZE-1) >> PAGE_SHIFT;
315 iommu_release_one(vaddr & PAGE_MASK, npages, sbus); 322 iommu_release_one(dev, vaddr & PAGE_MASK, npages);
316} 323}
317 324
318static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 325static void iommu_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
319{ 326{
320 int n; 327 int n;
321 328
@@ -323,18 +330,18 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b
323 --sz; 330 --sz;
324 331
325 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 332 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
326 iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); 333 iommu_release_one(dev, sg->dvma_address & PAGE_MASK, n);
327 sg->dvma_address = 0x21212121; 334 sg->dvma_address = 0x21212121;
328 sg = sg_next(sg); 335 sg = sg_next(sg);
329 } 336 }
330} 337}
331 338
332#ifdef CONFIG_SBUS 339#ifdef CONFIG_SBUS
333static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, 340static int iommu_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va,
334 unsigned long addr, int len) 341 unsigned long addr, int len)
335{ 342{
343 struct iommu_struct *iommu = dev->archdata.iommu;
336 unsigned long page, end; 344 unsigned long page, end;
337 struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
338 iopte_t *iopte = iommu->page_table; 345 iopte_t *iopte = iommu->page_table;
339 iopte_t *first; 346 iopte_t *first;
340 int ioptex; 347 int ioptex;
@@ -397,9 +404,9 @@ static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va,
397 return 0; 404 return 0;
398} 405}
399 406
400static void iommu_unmap_dma_area(unsigned long busa, int len) 407static void iommu_unmap_dma_area(struct device *dev, unsigned long busa, int len)
401{ 408{
402 struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu; 409 struct iommu_struct *iommu = dev->archdata.iommu;
403 iopte_t *iopte = iommu->page_table; 410 iopte_t *iopte = iommu->page_table;
404 unsigned long end; 411 unsigned long end;
405 int ioptex = (busa - iommu->start) >> PAGE_SHIFT; 412 int ioptex = (busa - iommu->start) >> PAGE_SHIFT;
@@ -417,15 +424,6 @@ static void iommu_unmap_dma_area(unsigned long busa, int len)
417 iommu_invalidate(iommu->regs); 424 iommu_invalidate(iommu->regs);
418 bit_map_clear(&iommu->usemap, ioptex, len >> PAGE_SHIFT); 425 bit_map_clear(&iommu->usemap, ioptex, len >> PAGE_SHIFT);
419} 426}
420
421static struct page *iommu_translate_dvma(unsigned long busa)
422{
423 struct iommu_struct *iommu = sbus_root->ofdev.dev.archdata.iommu;
424 iopte_t *iopte = iommu->page_table;
425
426 iopte += ((busa - iommu->start) >> PAGE_SHIFT);
427 return pfn_to_page((iopte_val(*iopte) & IOPTE_PAGE) >> (PAGE_SHIFT-4));
428}
429#endif 427#endif
430 428
431static char *iommu_lockarea(char *vaddr, unsigned long len) 429static char *iommu_lockarea(char *vaddr, unsigned long len)
@@ -461,7 +459,6 @@ void __init ld_mmu_iommu(void)
461#ifdef CONFIG_SBUS 459#ifdef CONFIG_SBUS
462 BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM); 460 BTFIXUPSET_CALL(mmu_map_dma_area, iommu_map_dma_area, BTFIXUPCALL_NORM);
463 BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM); 461 BTFIXUPSET_CALL(mmu_unmap_dma_area, iommu_unmap_dma_area, BTFIXUPCALL_NORM);
464 BTFIXUPSET_CALL(mmu_translate_dvma, iommu_translate_dvma, BTFIXUPCALL_NORM);
465#endif 462#endif
466 463
467 if (viking_mxcc_present || srmmu_modtype == HyperSparc) { 464 if (viking_mxcc_present || srmmu_modtype == HyperSparc) {
diff --git a/arch/sparc/mm/nosrmmu.c b/arch/sparc/mm/nosrmmu.c
deleted file mode 100644
index 3701f70fc30a..000000000000
--- a/arch/sparc/mm/nosrmmu.c
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * nosrmmu.c: This file is a bunch of dummies for sun4 compiles,
3 * so that it does not need srmmu and avoid ifdefs.
4 *
5 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6 */
7
8#include <linux/kernel.h>
9#include <linux/mm.h>
10#include <linux/init.h>
11#include <asm/mbus.h>
12#include <asm/sbus.h>
13
14static char shouldnothappen[] __initdata = "SUN4 kernel can only run on SUN4\n";
15
16enum mbus_module srmmu_modtype;
17void *srmmu_nocache_pool;
18
19int vac_cache_size = 0;
20
21static void __init should_not_happen(void)
22{
23 prom_printf(shouldnothappen);
24 prom_halt();
25}
26
27void __init srmmu_frob_mem_map(unsigned long start_mem)
28{
29 should_not_happen();
30}
31
32unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long end_mem)
33{
34 should_not_happen();
35 return 0;
36}
37
38void __init ld_mmu_srmmu(void)
39{
40 should_not_happen();
41}
42
43void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly)
44{
45}
46
47void srmmu_unmapioaddr(unsigned long virt_addr)
48{
49}
50
51__u32 iounit_map_dma_init(struct sbus_bus *sbus, int size)
52{
53 return 0;
54}
55
56__u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus)
57{
58 return 0;
59}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index ee30462598fc..6a5d7cabc044 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -31,7 +31,6 @@
31#include <asm/mbus.h> 31#include <asm/mbus.h>
32#include <asm/cache.h> 32#include <asm/cache.h>
33#include <asm/oplib.h> 33#include <asm/oplib.h>
34#include <asm/sbus.h>
35#include <asm/asi.h> 34#include <asm/asi.h>
36#include <asm/msi.h> 35#include <asm/msi.h>
37#include <asm/mmu_context.h> 36#include <asm/mmu_context.h>
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index d1782f6368be..fe65aeeb3947 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -31,7 +31,6 @@
31#include <asm/oplib.h> 31#include <asm/oplib.h>
32#include <asm/openprom.h> 32#include <asm/openprom.h>
33#include <asm/mmu_context.h> 33#include <asm/mmu_context.h>
34#include <asm/sun4paddr.h>
35#include <asm/highmem.h> 34#include <asm/highmem.h>
36#include <asm/btfixup.h> 35#include <asm/btfixup.h>
37#include <asm/cacheflush.h> 36#include <asm/cacheflush.h>
@@ -52,15 +51,11 @@ extern int num_segmaps, num_contexts;
52 51
53extern unsigned long page_kernel; 52extern unsigned long page_kernel;
54 53
55#ifdef CONFIG_SUN4
56#define SUN4C_VAC_SIZE sun4c_vacinfo.num_bytes
57#else
58/* That's it, we prom_halt() on sun4c if the cache size is something other than 65536. 54/* That's it, we prom_halt() on sun4c if the cache size is something other than 65536.
59 * So let's save some cycles and just use that everywhere except for that bootup 55 * So let's save some cycles and just use that everywhere except for that bootup
60 * sanity check. 56 * sanity check.
61 */ 57 */
62#define SUN4C_VAC_SIZE 65536 58#define SUN4C_VAC_SIZE 65536
63#endif
64 59
65#define SUN4C_KERNEL_BUCKETS 32 60#define SUN4C_KERNEL_BUCKETS 32
66 61
@@ -285,75 +280,32 @@ void __init sun4c_probe_vac(void)
285{ 280{
286 sun4c_disable_vac(); 281 sun4c_disable_vac();
287 282
288 if (ARCH_SUN4) { 283 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
289 switch (idprom->id_machtype) { 284 (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
290 285 /* PROM on SS1 lacks this info, to be super safe we
291 case (SM_SUN4|SM_4_110): 286 * hard code it here since this arch is cast in stone.
292 sun4c_vacinfo.type = VAC_NONE; 287 */
293 sun4c_vacinfo.num_bytes = 0; 288 sun4c_vacinfo.num_bytes = 65536;
294 sun4c_vacinfo.linesize = 0; 289 sun4c_vacinfo.linesize = 16;
295 sun4c_vacinfo.do_hwflushes = 0;
296 prom_printf("No VAC. Get some bucks and buy a real computer.");
297 prom_halt();
298 break;
299
300 case (SM_SUN4|SM_4_260):
301 sun4c_vacinfo.type = VAC_WRITE_BACK;
302 sun4c_vacinfo.num_bytes = 128 * 1024;
303 sun4c_vacinfo.linesize = 16;
304 sun4c_vacinfo.do_hwflushes = 0;
305 break;
306
307 case (SM_SUN4|SM_4_330):
308 sun4c_vacinfo.type = VAC_WRITE_THROUGH;
309 sun4c_vacinfo.num_bytes = 128 * 1024;
310 sun4c_vacinfo.linesize = 16;
311 sun4c_vacinfo.do_hwflushes = 0;
312 break;
313
314 case (SM_SUN4|SM_4_470):
315 sun4c_vacinfo.type = VAC_WRITE_BACK;
316 sun4c_vacinfo.num_bytes = 128 * 1024;
317 sun4c_vacinfo.linesize = 32;
318 sun4c_vacinfo.do_hwflushes = 0;
319 break;
320
321 default:
322 prom_printf("Cannot initialize VAC - weird sun4 model idprom->id_machtype = %d", idprom->id_machtype);
323 prom_halt();
324 };
325 } else { 290 } else {
326 sun4c_vacinfo.type = VAC_WRITE_THROUGH; 291 sun4c_vacinfo.num_bytes =
292 prom_getintdefault(prom_root_node, "vac-size", 65536);
293 sun4c_vacinfo.linesize =
294 prom_getintdefault(prom_root_node, "vac-linesize", 16);
295 }
296 sun4c_vacinfo.do_hwflushes =
297 prom_getintdefault(prom_root_node, "vac-hwflush", 0);
327 298
328 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || 299 if (sun4c_vacinfo.do_hwflushes == 0)
329 (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
330 /* PROM on SS1 lacks this info, to be super safe we
331 * hard code it here since this arch is cast in stone.
332 */
333 sun4c_vacinfo.num_bytes = 65536;
334 sun4c_vacinfo.linesize = 16;
335 } else {
336 sun4c_vacinfo.num_bytes =
337 prom_getintdefault(prom_root_node, "vac-size", 65536);
338 sun4c_vacinfo.linesize =
339 prom_getintdefault(prom_root_node, "vac-linesize", 16);
340 }
341 sun4c_vacinfo.do_hwflushes = 300 sun4c_vacinfo.do_hwflushes =
342 prom_getintdefault(prom_root_node, "vac-hwflush", 0); 301 prom_getintdefault(prom_root_node, "vac_hwflush", 0);
343
344 if (sun4c_vacinfo.do_hwflushes == 0)
345 sun4c_vacinfo.do_hwflushes =
346 prom_getintdefault(prom_root_node, "vac_hwflush", 0);
347 302
348 if (sun4c_vacinfo.num_bytes != 65536) { 303 if (sun4c_vacinfo.num_bytes != 65536) {
349 prom_printf("WEIRD Sun4C VAC cache size, " 304 prom_printf("WEIRD Sun4C VAC cache size, "
350 "tell sparclinux@vger.kernel.org"); 305 "tell sparclinux@vger.kernel.org");
351 prom_halt(); 306 prom_halt();
352 }
353 } 307 }
354 308
355 sun4c_vacinfo.num_lines =
356 (sun4c_vacinfo.num_bytes / sun4c_vacinfo.linesize);
357 switch (sun4c_vacinfo.linesize) { 309 switch (sun4c_vacinfo.linesize) {
358 case 16: 310 case 16:
359 sun4c_vacinfo.log2lsize = 4; 311 sun4c_vacinfo.log2lsize = 4;
@@ -447,49 +399,18 @@ static void __init patch_kernel_fault_handler(void)
447 399
448static void __init sun4c_probe_mmu(void) 400static void __init sun4c_probe_mmu(void)
449{ 401{
450 if (ARCH_SUN4) { 402 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) ||
451 switch (idprom->id_machtype) { 403 (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) {
452 case (SM_SUN4|SM_4_110): 404 /* Hardcode these just to be safe, PROM on SS1 does
453 prom_printf("No support for 4100 yet\n"); 405 * not have this info available in the root node.
454 prom_halt(); 406 */
455 num_segmaps = 256; 407 num_segmaps = 128;
456 num_contexts = 8; 408 num_contexts = 8;
457 break;
458
459 case (SM_SUN4|SM_4_260):
460 /* should be 512 segmaps. when it get fixed */
461 num_segmaps = 256;
462 num_contexts = 16;
463 break;
464
465 case (SM_SUN4|SM_4_330):
466 num_segmaps = 256;
467 num_contexts = 16;
468 break;
469
470 case (SM_SUN4|SM_4_470):
471 /* should be 1024 segmaps. when it get fixed */
472 num_segmaps = 256;
473 num_contexts = 64;
474 break;
475 default:
476 prom_printf("Invalid SUN4 model\n");
477 prom_halt();
478 };
479 } else { 409 } else {
480 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS1)) || 410 num_segmaps =
481 (idprom->id_machtype == (SM_SUN4C | SM_4C_SS1PLUS))) { 411 prom_getintdefault(prom_root_node, "mmu-npmg", 128);
482 /* Hardcode these just to be safe, PROM on SS1 does 412 num_contexts =
483 * not have this info available in the root node. 413 prom_getintdefault(prom_root_node, "mmu-nctx", 0x8);
484 */
485 num_segmaps = 128;
486 num_contexts = 8;
487 } else {
488 num_segmaps =
489 prom_getintdefault(prom_root_node, "mmu-npmg", 128);
490 num_contexts =
491 prom_getintdefault(prom_root_node, "mmu-nctx", 0x8);
492 }
493 } 414 }
494 patch_kernel_fault_handler(); 415 patch_kernel_fault_handler();
495} 416}
@@ -501,18 +422,14 @@ void __init sun4c_probe_memerr_reg(void)
501 int node; 422 int node;
502 struct linux_prom_registers regs[1]; 423 struct linux_prom_registers regs[1];
503 424
504 if (ARCH_SUN4) { 425 node = prom_getchild(prom_root_node);
505 sun4c_memerr_reg = ioremap(sun4_memreg_physaddr, PAGE_SIZE); 426 node = prom_searchsiblings(prom_root_node, "memory-error");
506 } else { 427 if (!node)
507 node = prom_getchild(prom_root_node); 428 return;
508 node = prom_searchsiblings(prom_root_node, "memory-error"); 429 if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0)
509 if (!node) 430 return;
510 return; 431 /* hmm I think regs[0].which_io is zero here anyways */
511 if (prom_getproperty(node, "reg", (char *)regs, sizeof(regs)) <= 0) 432 sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size);
512 return;
513 /* hmm I think regs[0].which_io is zero here anyways */
514 sun4c_memerr_reg = ioremap(regs[0].phys_addr, regs[0].reg_size);
515 }
516} 433}
517 434
518static inline void sun4c_init_ss2_cache_bug(void) 435static inline void sun4c_init_ss2_cache_bug(void)
@@ -521,7 +438,6 @@ static inline void sun4c_init_ss2_cache_bug(void)
521 438
522 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) || 439 if ((idprom->id_machtype == (SM_SUN4C | SM_4C_SS2)) ||
523 (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) || 440 (idprom->id_machtype == (SM_SUN4C | SM_4C_IPX)) ||
524 (idprom->id_machtype == (SM_SUN4 | SM_4_330)) ||
525 (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) { 441 (idprom->id_machtype == (SM_SUN4C | SM_4C_ELC))) {
526 /* Whee.. */ 442 /* Whee.. */
527 printk("SS2 cache bug detected, uncaching trap table page\n"); 443 printk("SS2 cache bug detected, uncaching trap table page\n");
@@ -532,8 +448,8 @@ static inline void sun4c_init_ss2_cache_bug(void)
532} 448}
533 449
534/* Addr is always aligned on a page boundary for us already. */ 450/* Addr is always aligned on a page boundary for us already. */
535static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va, 451static int sun4c_map_dma_area(struct device *dev, dma_addr_t *pba, unsigned long va,
536 unsigned long addr, int len) 452 unsigned long addr, int len)
537{ 453{
538 unsigned long page, end; 454 unsigned long page, end;
539 455
@@ -555,14 +471,7 @@ static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va,
555 return 0; 471 return 0;
556} 472}
557 473
558static struct page *sun4c_translate_dvma(unsigned long busa) 474static void sun4c_unmap_dma_area(struct device *dev, unsigned long busa, int len)
559{
560 /* Fortunately for us, bus_addr == uncached_virt in sun4c. */
561 unsigned long pte = sun4c_get_pte(busa);
562 return pfn_to_page(pte & SUN4C_PFN_MASK);
563}
564
565static void sun4c_unmap_dma_area(unsigned long busa, int len)
566{ 475{
567 /* Fortunately for us, bus_addr == uncached_virt in sun4c. */ 476 /* Fortunately for us, bus_addr == uncached_virt in sun4c. */
568 /* XXX Implement this */ 477 /* XXX Implement this */
@@ -624,11 +533,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
624{ 533{
625 unsigned long vaddr; 534 unsigned long vaddr;
626 unsigned char pseg, ctx; 535 unsigned char pseg, ctx;
627#ifdef CONFIG_SUN4 536
628 /* sun4/110 and 260 have no kadb. */
629 if ((idprom->id_machtype != (SM_SUN4 | SM_4_260)) &&
630 (idprom->id_machtype != (SM_SUN4 | SM_4_110))) {
631#endif
632 for (vaddr = KADB_DEBUGGER_BEGVM; 537 for (vaddr = KADB_DEBUGGER_BEGVM;
633 vaddr < LINUX_OPPROM_ENDVM; 538 vaddr < LINUX_OPPROM_ENDVM;
634 vaddr += SUN4C_REAL_PGDIR_SIZE) { 539 vaddr += SUN4C_REAL_PGDIR_SIZE) {
@@ -640,9 +545,7 @@ static inline void sun4c_init_map_kernelprom(unsigned long kernel_end)
640 fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0); 545 fix_permissions(vaddr, _SUN4C_PAGE_PRIV, 0);
641 } 546 }
642 } 547 }
643#ifdef CONFIG_SUN4 548
644 }
645#endif
646 for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) { 549 for (vaddr = KERNBASE; vaddr < kernel_end; vaddr += SUN4C_REAL_PGDIR_SIZE) {
647 pseg = sun4c_get_segmap(vaddr); 550 pseg = sun4c_get_segmap(vaddr);
648 mmu_entry_pool[pseg].locked = 1; 551 mmu_entry_pool[pseg].locked = 1;
@@ -1048,14 +951,10 @@ static struct thread_info *sun4c_alloc_thread_info(void)
1048 * so we must flush the cache to guarantee consistency. 951 * so we must flush the cache to guarantee consistency.
1049 */ 952 */
1050 sun4c_flush_page(pages); 953 sun4c_flush_page(pages);
1051#ifndef CONFIG_SUN4
1052 sun4c_flush_page(pages + PAGE_SIZE); 954 sun4c_flush_page(pages + PAGE_SIZE);
1053#endif
1054 955
1055 sun4c_put_pte(addr, BUCKET_PTE(pages)); 956 sun4c_put_pte(addr, BUCKET_PTE(pages));
1056#ifndef CONFIG_SUN4
1057 sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE)); 957 sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE));
1058#endif
1059 958
1060#ifdef CONFIG_DEBUG_STACK_USAGE 959#ifdef CONFIG_DEBUG_STACK_USAGE
1061 memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER); 960 memset((void *)addr, 0, PAGE_SIZE << THREAD_INFO_ORDER);
@@ -1072,13 +971,11 @@ static void sun4c_free_thread_info(struct thread_info *ti)
1072 971
1073 /* We are deleting a mapping, so the flush here is mandatory. */ 972 /* We are deleting a mapping, so the flush here is mandatory. */
1074 sun4c_flush_page(tiaddr); 973 sun4c_flush_page(tiaddr);
1075#ifndef CONFIG_SUN4
1076 sun4c_flush_page(tiaddr + PAGE_SIZE); 974 sun4c_flush_page(tiaddr + PAGE_SIZE);
1077#endif 975
1078 sun4c_put_pte(tiaddr, 0); 976 sun4c_put_pte(tiaddr, 0);
1079#ifndef CONFIG_SUN4
1080 sun4c_put_pte(tiaddr + PAGE_SIZE, 0); 977 sun4c_put_pte(tiaddr + PAGE_SIZE, 0);
1081#endif 978
1082 sun4c_bucket[entry] = BUCKET_EMPTY; 979 sun4c_bucket[entry] = BUCKET_EMPTY;
1083 if (entry < sun4c_lowbucket_avail) 980 if (entry < sun4c_lowbucket_avail)
1084 sun4c_lowbucket_avail = entry; 981 sun4c_lowbucket_avail = entry;
@@ -1211,7 +1108,7 @@ static void sun4c_unlockarea(char *vaddr, unsigned long size)
1211 * by implication and fool the page locking code above 1108 * by implication and fool the page locking code above
1212 * if passed to by mistake. 1109 * if passed to by mistake.
1213 */ 1110 */
1214static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus *sbus) 1111static __u32 sun4c_get_scsi_one(struct device *dev, char *bufptr, unsigned long len)
1215{ 1112{
1216 unsigned long page; 1113 unsigned long page;
1217 1114
@@ -1223,7 +1120,7 @@ static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus
1223 return (__u32)sun4c_lockarea(bufptr, len); 1120 return (__u32)sun4c_lockarea(bufptr, len);
1224} 1121}
1225 1122
1226static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 1123static void sun4c_get_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
1227{ 1124{
1228 while (sz != 0) { 1125 while (sz != 0) {
1229 --sz; 1126 --sz;
@@ -1233,14 +1130,14 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
1233 } 1130 }
1234} 1131}
1235 1132
1236static void sun4c_release_scsi_one(__u32 bufptr, unsigned long len, struct sbus_bus *sbus) 1133static void sun4c_release_scsi_one(struct device *dev, __u32 bufptr, unsigned long len)
1237{ 1134{
1238 if (bufptr < sun4c_iobuffer_start) 1135 if (bufptr < sun4c_iobuffer_start)
1239 return; /* On kernel stack or similar, see above */ 1136 return; /* On kernel stack or similar, see above */
1240 sun4c_unlockarea((char *)bufptr, len); 1137 sun4c_unlockarea((char *)bufptr, len);
1241} 1138}
1242 1139
1243static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) 1140static void sun4c_release_scsi_sgl(struct device *dev, struct scatterlist *sg, int sz)
1244{ 1141{
1245 while (sz != 0) { 1142 while (sz != 0) {
1246 --sz; 1143 --sz;
@@ -2263,7 +2160,6 @@ void __init ld_mmu_sun4c(void)
2263 2160
2264 BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM); 2161 BTFIXUPSET_CALL(mmu_map_dma_area, sun4c_map_dma_area, BTFIXUPCALL_NORM);
2265 BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM); 2162 BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM);
2266 BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM);
2267 2163
2268 BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM); 2164 BTFIXUPSET_CALL(sparc_mapiorange, sun4c_mapiorange, BTFIXUPCALL_NORM);
2269 BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM); 2165 BTFIXUPSET_CALL(sparc_unmapiorange, sun4c_unmapiorange, BTFIXUPCALL_NORM);
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile
index 7f5eacfcfbcf..8f7e18546c97 100644
--- a/arch/sparc/prom/Makefile
+++ b/arch/sparc/prom/Makefile
@@ -4,5 +4,3 @@
4 4
5lib-y := bootstr.o devmap.o devops.o init.o memory.o misc.o mp.o \ 5lib-y := bootstr.o devmap.o devops.o init.o memory.o misc.o mp.o \
6 palloc.o ranges.o segment.o console.o printf.o tree.o 6 palloc.o ranges.o segment.o console.o printf.o tree.o
7
8lib-$(CONFIG_SUN4) += sun4prom.o
diff --git a/arch/sparc/prom/bootstr.c b/arch/sparc/prom/bootstr.c
index 5a35c768ff7c..916831da7e67 100644
--- a/arch/sparc/prom/bootstr.c
+++ b/arch/sparc/prom/bootstr.c
@@ -6,15 +6,12 @@
6 6
7#include <linux/string.h> 7#include <linux/string.h>
8#include <asm/oplib.h> 8#include <asm/oplib.h>
9#include <asm/sun4prom.h>
10#include <linux/init.h> 9#include <linux/init.h>
11 10
12#define BARG_LEN 256 11#define BARG_LEN 256
13static char barg_buf[BARG_LEN] = { 0 }; 12static char barg_buf[BARG_LEN] = { 0 };
14static char fetched __initdata = 0; 13static char fetched __initdata = 0;
15 14
16extern linux_sun4_romvec *sun4_romvec;
17
18char * __init 15char * __init
19prom_getbootargs(void) 16prom_getbootargs(void)
20{ 17{
@@ -28,7 +25,6 @@ prom_getbootargs(void)
28 25
29 switch(prom_vers) { 26 switch(prom_vers) {
30 case PROM_V0: 27 case PROM_V0:
31 case PROM_SUN4:
32 cp = barg_buf; 28 cp = barg_buf;
33 /* Start from 1 and go over fd(0,0,0)kernel */ 29 /* Start from 1 and go over fd(0,0,0)kernel */
34 for(iter = 1; iter < 8; iter++) { 30 for(iter = 1; iter < 8; iter++) {
diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c
index 790057a34616..b3075d73fc19 100644
--- a/arch/sparc/prom/console.c
+++ b/arch/sparc/prom/console.c
@@ -10,7 +10,6 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <asm/openprom.h> 12#include <asm/openprom.h>
13#include <asm/sun4prom.h>
14#include <asm/oplib.h> 13#include <asm/oplib.h>
15#include <asm/system.h> 14#include <asm/system.h>
16#include <linux/string.h> 15#include <linux/string.h>
@@ -30,7 +29,6 @@ prom_nbgetchar(void)
30 spin_lock_irqsave(&prom_lock, flags); 29 spin_lock_irqsave(&prom_lock, flags);
31 switch(prom_vers) { 30 switch(prom_vers) {
32 case PROM_V0: 31 case PROM_V0:
33 case PROM_SUN4:
34 i = (*(romvec->pv_nbgetchar))(); 32 i = (*(romvec->pv_nbgetchar))();
35 break; 33 break;
36 case PROM_V2: 34 case PROM_V2:
@@ -63,7 +61,6 @@ prom_nbputchar(char c)
63 spin_lock_irqsave(&prom_lock, flags); 61 spin_lock_irqsave(&prom_lock, flags);
64 switch(prom_vers) { 62 switch(prom_vers) {
65 case PROM_V0: 63 case PROM_V0:
66 case PROM_SUN4:
67 i = (*(romvec->pv_nbputchar))(c); 64 i = (*(romvec->pv_nbputchar))(c);
68 break; 65 break;
69 case PROM_V2: 66 case PROM_V2:
diff --git a/arch/sparc/prom/init.c b/arch/sparc/prom/init.c
index 729f87066945..873217c6d823 100644
--- a/arch/sparc/prom/init.c
+++ b/arch/sparc/prom/init.c
@@ -11,12 +11,10 @@
11 11
12#include <asm/openprom.h> 12#include <asm/openprom.h>
13#include <asm/oplib.h> 13#include <asm/oplib.h>
14#include <asm/sun4prom.h>
15 14
16struct linux_romvec *romvec; 15struct linux_romvec *romvec;
17enum prom_major_version prom_vers; 16enum prom_major_version prom_vers;
18unsigned int prom_rev, prom_prev; 17unsigned int prom_rev, prom_prev;
19linux_sun4_romvec *sun4_romvec;
20 18
21/* The root node of the prom device tree. */ 19/* The root node of the prom device tree. */
22int prom_root_node; 20int prom_root_node;
@@ -34,10 +32,6 @@ extern void prom_ranges_init(void);
34 32
35void __init prom_init(struct linux_romvec *rp) 33void __init prom_init(struct linux_romvec *rp)
36{ 34{
37#ifdef CONFIG_SUN4
38 extern struct linux_romvec *sun4_prom_init(void);
39 rp = sun4_prom_init();
40#endif
41 romvec = rp; 35 romvec = rp;
42 36
43 switch(romvec->pv_romvers) { 37 switch(romvec->pv_romvers) {
@@ -50,9 +44,6 @@ void __init prom_init(struct linux_romvec *rp)
50 case 3: 44 case 3:
51 prom_vers = PROM_V3; 45 prom_vers = PROM_V3;
52 break; 46 break;
53 case 40:
54 prom_vers = PROM_SUN4;
55 break;
56 default: 47 default:
57 prom_printf("PROMLIB: Bad PROM version %d\n", 48 prom_printf("PROMLIB: Bad PROM version %d\n",
58 romvec->pv_romvers); 49 romvec->pv_romvers);
@@ -76,11 +67,8 @@ void __init prom_init(struct linux_romvec *rp)
76 67
77 prom_ranges_init(); 68 prom_ranges_init();
78 69
79#ifndef CONFIG_SUN4
80 /* SUN4 prints this in sun4_prom_init */
81 printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n", 70 printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n",
82 romvec->pv_romvers, prom_rev); 71 romvec->pv_romvers, prom_rev);
83#endif
84 72
85 /* Initialization successful. */ 73 /* Initialization successful. */
86 return; 74 return;
diff --git a/arch/sparc/prom/memory.c b/arch/sparc/prom/memory.c
index 947f047dc95a..fac7899a29c3 100644
--- a/arch/sparc/prom/memory.c
+++ b/arch/sparc/prom/memory.c
@@ -10,7 +10,6 @@
10#include <linux/init.h> 10#include <linux/init.h>
11 11
12#include <asm/openprom.h> 12#include <asm/openprom.h>
13#include <asm/sun4prom.h>
14#include <asm/oplib.h> 13#include <asm/oplib.h>
15#include <asm/page.h> 14#include <asm/page.h>
16 15
@@ -46,15 +45,6 @@ static int __init prom_meminit_v2(void)
46 return num_ents; 45 return num_ents;
47} 46}
48 47
49static int __init prom_meminit_sun4(void)
50{
51#ifdef CONFIG_SUN4
52 sp_banks[0].base_addr = 0;
53 sp_banks[0].num_bytes = *(sun4_romvec->memoryavail);
54#endif
55 return 1;
56}
57
58static int sp_banks_cmp(const void *a, const void *b) 48static int sp_banks_cmp(const void *a, const void *b)
59{ 49{
60 const struct sparc_phys_banks *x = a, *y = b; 50 const struct sparc_phys_banks *x = a, *y = b;
@@ -81,10 +71,6 @@ void __init prom_meminit(void)
81 num_ents = prom_meminit_v2(); 71 num_ents = prom_meminit_v2();
82 break; 72 break;
83 73
84 case PROM_SUN4:
85 num_ents = prom_meminit_sun4();
86 break;
87
88 default: 74 default:
89 break; 75 break;
90 } 76 }
diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c
index f9b7def35f6e..64579a376419 100644
--- a/arch/sparc/prom/ranges.c
+++ b/arch/sparc/prom/ranges.c
@@ -9,7 +9,6 @@
9#include <asm/openprom.h> 9#include <asm/openprom.h>
10#include <asm/oplib.h> 10#include <asm/oplib.h>
11#include <asm/types.h> 11#include <asm/types.h>
12#include <asm/sbus.h>
13#include <asm/system.h> 12#include <asm/system.h>
14 13
15struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX]; 14struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX];
diff --git a/arch/sparc/prom/sun4prom.c b/arch/sparc/prom/sun4prom.c
deleted file mode 100644
index 00390a2652aa..000000000000
--- a/arch/sparc/prom/sun4prom.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/*
2 * Copyright (C) 1996 The Australian National University.
3 * Copyright (C) 1996 Fujitsu Laboratories Limited
4 * Copyright (C) 1997 Michael A. Griffith (grif@acm.org)
5 * Copyright (C) 1997 Sun Weenie (ko@ko.reno.nv.us)
6 * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
7 *
8 * This software may be distributed under the terms of the Gnu
9 * Public License version 2 or later
10 *
11 * fake a really simple Sun prom for the SUN4
12 */
13
14#include <linux/kernel.h>
15#include <linux/string.h>
16#include <asm/oplib.h>
17#include <asm/idprom.h>
18#include <asm/machines.h>
19#include <asm/sun4prom.h>
20#include <asm/asi.h>
21#include <asm/contregs.h>
22#include <linux/init.h>
23
24static struct linux_romvec sun4romvec;
25static struct idprom sun4_idprom;
26
27struct property {
28 char *name;
29 char *value;
30 int length;
31};
32
33struct node {
34 int level;
35 struct property *properties;
36};
37
38struct property null_properties = { NULL, NULL, -1 };
39
40struct property root_properties[] = {
41 {"device_type", "cpu", 4},
42 {"idprom", (char *)&sun4_idprom, sizeof(struct idprom)},
43 {NULL, NULL, -1}
44};
45
46struct node nodes[] = {
47 { 0, &null_properties },
48 { 0, root_properties },
49 { -1,&null_properties }
50};
51
52
53static int no_nextnode(int node)
54{
55 if (nodes[node].level == nodes[node+1].level)
56 return node+1;
57 return -1;
58}
59
60static int no_child(int node)
61{
62 if (nodes[node].level == nodes[node+1].level-1)
63 return node+1;
64 return -1;
65}
66
67static struct property *find_property(int node,char *name)
68{
69 struct property *prop = &nodes[node].properties[0];
70 while (prop && prop->name) {
71 if (strcmp(prop->name,name) == 0) return prop;
72 prop++;
73 }
74 return NULL;
75}
76
77static int no_proplen(int node,char *name)
78{
79 struct property *prop = find_property(node,name);
80 if (prop) return prop->length;
81 return -1;
82}
83
84static int no_getprop(int node,char *name,char *value)
85{
86 struct property *prop = find_property(node,name);
87 if (prop) {
88 memcpy(value,prop->value,prop->length);
89 return 1;
90 }
91 return -1;
92}
93
94static int no_setprop(int node,char *name,char *value,int len)
95{
96 return -1;
97}
98
99static char *no_nextprop(int node,char *name)
100{
101 struct property *prop = find_property(node,name);
102 if (prop) return prop[1].name;
103 return NULL;
104}
105
106static struct linux_nodeops sun4_nodeops = {
107 no_nextnode,
108 no_child,
109 no_proplen,
110 no_getprop,
111 no_setprop,
112 no_nextprop
113};
114
115static int synch_hook;
116
117struct linux_romvec * __init sun4_prom_init(void)
118{
119 int i;
120 unsigned char x;
121 char *p;
122
123 p = (char *)&sun4_idprom;
124 for (i = 0; i < sizeof(sun4_idprom); i++) {
125 __asm__ __volatile__ ("lduba [%1] %2, %0" : "=r" (x) :
126 "r" (AC_IDPROM + i), "i" (ASI_CONTROL));
127 *p++ = x;
128 }
129
130 memset(&sun4romvec,0,sizeof(sun4romvec));
131
132 sun4_romvec = (linux_sun4_romvec *) SUN4_PROM_VECTOR;
133
134 sun4romvec.pv_romvers = 40;
135 sun4romvec.pv_nodeops = &sun4_nodeops;
136 sun4romvec.pv_reboot = sun4_romvec->reboot;
137 sun4romvec.pv_abort = sun4_romvec->abortentry;
138 sun4romvec.pv_halt = sun4_romvec->exittomon;
139 sun4romvec.pv_synchook = (void (**)(void))&synch_hook;
140 sun4romvec.pv_setctxt = sun4_romvec->setcxsegmap;
141 sun4romvec.pv_v0bootargs = sun4_romvec->bootParam;
142 sun4romvec.pv_nbgetchar = sun4_romvec->mayget;
143 sun4romvec.pv_nbputchar = sun4_romvec->mayput;
144 sun4romvec.pv_stdin = sun4_romvec->insource;
145 sun4romvec.pv_stdout = sun4_romvec->outsink;
146
147 /*
148 * We turn on the LEDs to let folks without monitors or
149 * terminals know we booted. Nothing too fancy now. They
150 * are all on, except for LED 5, which blinks. When we
151 * have more time, we can teach the penguin to say "By your
152 * command" or "Activating turbo boost, Michael". :-)
153 */
154 sun4_romvec->setLEDs(NULL);
155
156 printk("PROMLIB: Old Sun4 boot PROM monitor %s, romvec version %d\n",
157 sun4_romvec->monid,
158 sun4_romvec->romvecversion);
159
160 return &sun4romvec;
161}