diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-13 12:13:56 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-13 12:13:56 -0400 |
commit | e758936e02700ff88a0b08b722a3847b95283ef2 (patch) | |
tree | 50c919bef1b459a778b85159d5929de95b6c4a01 /arch/sparc | |
parent | 239cfbde1f5843c4a24199f117d5f67f637d72d5 (diff) | |
parent | 4480f15b3306f43bbb0310d461142b4e897ca45b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
include/asm-x86/statfs.h
Diffstat (limited to 'arch/sparc')
105 files changed, 1560 insertions, 4395 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 | ||
23 | config GENERIC_GPIO | ||
24 | bool | ||
25 | help | ||
26 | Generic GPIO API support | ||
27 | |||
23 | config ARCH_NO_VIRT_TO_BUS | 28 | config 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 |
74 | config SPARC32 | 82 | config 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 | ||
207 | config 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 | |||
216 | if !SUN4 | ||
217 | |||
218 | config PCI | 215 | config 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 | ||
228 | source "drivers/pci/Kconfig" | 225 | source "drivers/pci/Kconfig" |
229 | 226 | ||
230 | endif | ||
231 | |||
232 | config NO_DMA | ||
233 | def_bool !PCI | ||
234 | |||
235 | config SUN_OPENPROMFS | 227 | config 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 | ||
264 | source "drivers/Kconfig" | 256 | source "drivers/Kconfig" |
265 | 257 | ||
266 | if !SUN4 | ||
267 | source "drivers/sbus/char/Kconfig" | 258 | source "drivers/sbus/char/Kconfig" |
268 | endif | ||
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 3f1cb7ad0d67..2d2769d766ec 100644 --- a/arch/sparc/include/asm/Kbuild +++ b/arch/sparc/include/asm/Kbuild | |||
@@ -20,7 +20,6 @@ header-y += unistd_64.h | |||
20 | 20 | ||
21 | header-y += apc.h | 21 | header-y += apc.h |
22 | header-y += asi.h | 22 | header-y += asi.h |
23 | header-y += bpp.h | ||
24 | header-y += display7seg.h | 23 | header-y += display7seg.h |
25 | header-y += envctrl.h | 24 | header-y += envctrl.h |
26 | header-y += fbio.h | 25 | header-y += fbio.h |
@@ -39,5 +38,4 @@ header-y += reg_64.h | |||
39 | header-y += traps.h | 38 | header-y += traps.h |
40 | header-y += uctx.h | 39 | header-y += uctx.h |
41 | header-y += utrap.h | 40 | header-y += utrap.h |
42 | header-y += vfc_ioctls.h | ||
43 | header-y += watchdog.h | 41 | header-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 | |||
14 | extern unsigned long loops_per_jiffy; | 10 | extern unsigned long loops_per_jiffy; |
15 | 11 | ||
16 | static void __init check_bugs(void) | 12 | static 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]; | |||
86 | extern void init_cur_cpu_trap(struct thread_info *); | 86 | extern void init_cur_cpu_trap(struct thread_info *); |
87 | extern void setup_tba(void); | 87 | extern void setup_tba(void); |
88 | extern int ncpus_probed; | 88 | extern int ncpus_probed; |
89 | extern void __init cpu_probe(void); | ||
90 | extern const struct seq_operations cpuinfo_op; | 89 | extern const struct seq_operations cpuinfo_op; |
91 | 90 | ||
92 | extern unsigned long real_hard_smp_processor_id(void); | 91 | extern 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 | 6 | struct device; |
6 | #include <asm-generic/dma-mapping.h> | 7 | struct scatterlist; |
7 | #else | 8 | struct page; |
8 | #include <asm-generic/dma-mapping-broken.h> | 9 | |
9 | #endif /* PCI */ | 10 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) |
11 | |||
12 | extern int dma_supported(struct device *dev, u64 mask); | ||
13 | extern int dma_set_mask(struct device *dev, u64 dma_mask); | ||
14 | extern void *dma_alloc_coherent(struct device *dev, size_t size, | ||
15 | dma_addr_t *dma_handle, gfp_t flag); | ||
16 | extern void dma_free_coherent(struct device *dev, size_t size, | ||
17 | void *cpu_addr, dma_addr_t dma_handle); | ||
18 | extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | ||
19 | size_t size, | ||
20 | enum dma_data_direction direction); | ||
21 | extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, | ||
22 | size_t size, | ||
23 | enum dma_data_direction direction); | ||
24 | extern 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); | ||
27 | extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address, | ||
28 | size_t size, enum dma_data_direction direction); | ||
29 | extern int dma_map_sg(struct device *dev, struct scatterlist *sg, | ||
30 | int nents, enum dma_data_direction direction); | ||
31 | extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
32 | int nents, enum dma_data_direction direction); | ||
33 | extern void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, | ||
34 | size_t size, | ||
35 | enum dma_data_direction direction); | ||
36 | extern 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); | ||
40 | extern 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); | ||
45 | extern 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); | ||
49 | extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, | ||
50 | int nelems, enum dma_data_direction direction); | ||
51 | extern void dma_sync_sg_for_device(struct device *dev, | ||
52 | struct scatterlist *sg, int nelems, | ||
53 | enum dma_data_direction direction); | ||
54 | extern int dma_mapping_error(struct device *dev, dma_addr_t dma_addr); | ||
55 | extern 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 | ||
87 | extern 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. */ | ||
95 | BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long) | ||
96 | BTFIXUPDEF_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 | |||
101 | struct page; | ||
102 | struct device; | ||
103 | struct scatterlist; | ||
104 | |||
105 | /* These are implementations for sbus_map_sg/sbus_unmap_sg... collapse later */ | ||
106 | BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, struct device *, char *, unsigned long) | ||
107 | BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct device *, struct scatterlist *, int) | ||
108 | BTFIXUPDEF_CALL(void, mmu_release_scsi_one, struct device *, __u32, unsigned long) | ||
109 | BTFIXUPDEF_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 | */ | ||
132 | BTFIXUPDEF_CALL(int, mmu_map_dma_area, struct device *, dma_addr_t *, unsigned long, unsigned long, int len) | ||
133 | BTFIXUPDEF_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 | |||
20 | struct page; | ||
21 | extern spinlock_t dma_spin_lock; | ||
22 | |||
23 | static 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 | |||
30 | static 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 */ | ||
54 | enum 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. */ | ||
67 | struct 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 | |||
86 | extern 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 */ | ||
99 | extern 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 | */ | ||
199 | static 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 | |||
234 | extern int get_dma_list(char *); | ||
235 | extern int request_dma(unsigned int, __const__ char *); | ||
236 | extern void free_dma(unsigned int); | ||
237 | |||
238 | /* From PCI */ | ||
239 | |||
240 | #ifdef CONFIG_PCI | ||
241 | extern int isa_dma_bridge_buggy; | ||
242 | #else | ||
243 | #define isa_dma_bridge_buggy (0) | ||
244 | #endif | ||
245 | |||
246 | /* Routines for data transfer buffers. */ | ||
247 | BTFIXUPDEF_CALL(char *, mmu_lockarea, char *, unsigned long) | ||
248 | BTFIXUPDEF_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 */ | ||
254 | BTFIXUPDEF_CALL(__u32, mmu_get_scsi_one, char *, unsigned long, struct sbus_bus *sbus) | ||
255 | BTFIXUPDEF_CALL(void, mmu_get_scsi_sgl, struct scatterlist *, int, struct sbus_bus *sbus) | ||
256 | BTFIXUPDEF_CALL(void, mmu_release_scsi_one, __u32, unsigned long, struct sbus_bus *sbus) | ||
257 | BTFIXUPDEF_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 | */ | ||
280 | BTFIXUPDEF_CALL(int, mmu_map_dma_area, dma_addr_t *, unsigned long, unsigned long, int len) | ||
281 | BTFIXUPDEF_CALL(struct page *, mmu_translate_dvma, unsigned long busa) | ||
282 | BTFIXUPDEF_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 */ | ||
37 | enum 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. */ | ||
50 | struct 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 | |||
69 | extern 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 */ | ||
76 | extern 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) \ | ||
148 | do { 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) \ | ||
153 | do { 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) \ | ||
158 | do { 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) \ | ||
163 | do { 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) \ | ||
170 | do { 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) \ | ||
175 | do { 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 | ||
200 | extern 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 | |||
19 | struct 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 | |||
30 | struct 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 | |||
43 | struct 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 | |||
53 | struct 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 | |||
86 | extern struct linux_ebus *ebus_chain; | ||
87 | |||
88 | extern 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 | |||
16 | struct 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 | |||
27 | struct 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 | |||
40 | struct 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 | |||
51 | struct 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 | |||
72 | extern int ebus_dma_register(struct ebus_dma_info *p); | ||
73 | extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on); | ||
74 | extern void ebus_dma_unregister(struct ebus_dma_info *p); | ||
75 | extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, | ||
76 | size_t len); | ||
77 | extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); | ||
78 | extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); | ||
79 | extern unsigned int ebus_dma_addr(struct ebus_dma_info *p); | ||
80 | extern void ebus_dma_enable(struct ebus_dma_info *p, int on); | ||
81 | |||
82 | extern struct linux_ebus *ebus_chain; | ||
83 | |||
84 | extern 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 | |||
4 | struct 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 | |||
25 | extern int ebus_dma_register(struct ebus_dma_info *p); | ||
26 | extern int ebus_dma_irq_enable(struct ebus_dma_info *p, int on); | ||
27 | extern void ebus_dma_unregister(struct ebus_dma_info *p); | ||
28 | extern int ebus_dma_request(struct ebus_dma_info *p, dma_addr_t bus_addr, | ||
29 | size_t len); | ||
30 | extern void ebus_dma_prepare(struct ebus_dma_info *p, int write); | ||
31 | extern unsigned int ebus_dma_residue(struct ebus_dma_info *p); | ||
32 | extern unsigned int ebus_dma_addr(struct ebus_dma_info *p); | ||
33 | extern 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 | |||
16 | struct 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 | ||
32 | struct 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 */ |
45 | struct 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 | |||
109 | struct 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 | ||
391 | static 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. */ |
51 | static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; | 44 | static struct sun_flpy_controller *sun_fdc = (struct sun_flpy_controller *)-1; |
52 | unsigned long fdc_status; | 45 | unsigned long fdc_status; |
53 | static struct sbus_dev *floppy_sdev = NULL; | 46 | static struct of_device *floppy_op = NULL; |
54 | 47 | ||
55 | struct sun_floppy_ops { | 48 | struct 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 | ||
298 | static struct ebus_dma_info sun_pci_fd_ebus_dma; | 290 | static struct ebus_dma_info sun_pci_fd_ebus_dma; |
299 | static struct pci_dev *sun_pci_ebus_dev; | 291 | static struct device *sun_floppy_dev; |
300 | static int sun_pci_broken_drive = -1; | 292 | static int sun_pci_broken_drive = -1; |
301 | 293 | ||
302 | struct sun_pci_dma_op { | 294 | struct 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) | |||
404 | static void sun_pci_fd_set_dma_mode(int mode) | 396 | static 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 */ | 533 | static int __init ebus_fdthree_p(struct device_node *dp) |
542 | |||
543 | #ifdef CONFIG_PCI | ||
544 | static 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 | ||
560 | static unsigned long __init sun_floppy_init(void) | 547 | static 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 | |||
9 | static inline int gpio_get_value(unsigned int gpio) | ||
10 | { | ||
11 | return __gpio_get_value(gpio); | ||
12 | } | ||
13 | |||
14 | static inline void gpio_set_value(unsigned int gpio, int value) | ||
15 | { | ||
16 | __gpio_set_value(gpio, value); | ||
17 | } | ||
18 | |||
19 | static inline int gpio_cansleep(unsigned int gpio) | ||
20 | { | ||
21 | return __gpio_cansleep(gpio); | ||
22 | } | ||
23 | |||
24 | static inline int gpio_to_irq(unsigned int gpio) | ||
25 | { | ||
26 | return -ENOSYS; | ||
27 | } | ||
28 | |||
29 | static 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 | ||
58 | extern __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) | ||
60 | extern __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); | |||
293 | extern void pci_iounmap(struct pci_dev *dev, void __iomem *); | 293 | extern void pci_iounmap(struct pci_dev *dev, void __iomem *); |
294 | 294 | ||
295 | /* | 295 | /* |
296 | * Bus number may be in res->flags... somewhere. | ||
297 | */ | ||
298 | extern void __iomem *sbus_ioremap(struct resource *res, unsigned long offset, | ||
299 | unsigned long size, char *name); | ||
300 | extern 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 | ||
303 | static inline int sbus_can_dma_64bit(void) | ||
304 | { | ||
305 | return 0; /* actually, sparc_cpu_model==sun4d */ | ||
306 | } | ||
307 | static inline int sbus_can_burst64(void) | ||
308 | { | ||
309 | return 0; /* actually, sparc_cpu_model==sun4d */ | ||
310 | } | ||
311 | struct device; | ||
312 | extern 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; | |||
482 | extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); | 482 | extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); |
483 | extern void pci_iounmap(struct pci_dev *dev, void __iomem *); | 483 | extern void pci_iounmap(struct pci_dev *dev, void __iomem *); |
484 | 484 | ||
485 | /* Similarly for SBUS. */ | 485 | static 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); \ | 489 | static 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 | }) | 493 | struct device; |
494 | 494 | extern 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); |
58 | extern void sun4u_destroy_msi(unsigned int virt_irq); | 58 | extern void sun4u_destroy_msi(unsigned int virt_irq); |
59 | extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); | ||
60 | 59 | ||
61 | extern unsigned char virt_irq_alloc(unsigned int dev_handle, | 60 | extern 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 | 10 | extern unsigned long cmos_regs; |
11 | extern 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)); \ | |||
29 | outb_p((val),RTC_PORT(1)); \ | 25 | outb_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 | |||
4 | typedef int (*dimm_printer_t)(int synd_code, unsigned long paddr, char *buf, int buflen); | ||
5 | |||
6 | int register_dimm_printer(dimm_printer_t func); | ||
7 | void 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 | |||
54 | struct 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 | |||
67 | extern spinlock_t mostek_lock; | ||
68 | extern 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 | */ | ||
126 | struct 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 | ||
132 | enum sparc_clock_type { MSTK48T02, MSTK48T08, \ | ||
133 | INTERSIL, MSTK_INVALID }; | ||
134 | #else | ||
135 | enum sparc_clock_type { MSTK48T02, MSTK48T08, \ | ||
136 | MSTK_INVALID }; | ||
137 | #endif | ||
138 | |||
139 | #ifdef CONFIG_SUN4 | ||
140 | /* intersil on a sun 4/260 code data from harris doc */ | ||
141 | struct 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 | |||
152 | struct 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 | */ | ||
40 | static 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 | |||
50 | static 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 | |||
68 | extern spinlock_t mostek_lock; | ||
69 | extern 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) \ | ||
101 | do { 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 | ||
158 | extern unsigned char cpu_leds[32]; | ||
159 | |||
160 | static 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 | |||
169 | static inline unsigned cc_get_ipen(void) | 158 | static 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 | |||
30 | extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); | 30 | extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name); |
31 | extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); | 31 | extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size); |
32 | 32 | ||
33 | extern 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 | ||
16 | extern struct bus_type ebus_bus_type; | ||
17 | extern 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 | ||
27 | extern enum prom_major_version prom_vers; | 26 | extern 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 | |||
41 | extern void _clear_page(void *page); | 43 | extern void _clear_page(void *page); |
42 | #define clear_page(X) _clear_page((void *)(X)) | 44 | #define clear_page(X) _clear_page((void *)(X)) |
43 | struct page; | 45 | struct 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 | ||
218 | static struct of_device_id ecpp_match[] = { | 218 | static 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 | ||
771 | extern unsigned long cmdline_memory_size; | 771 | extern unsigned long cmdline_memory_size; |
772 | 772 | ||
773 | extern 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 | ||
74 | extern struct device_node *of_find_node_by_cpuid(int cpuid); | 75 | extern struct device_node *of_find_node_by_cpuid(int cpuid); |
75 | extern int of_set_property(struct device_node *node, const char *name, void *val, int len); | 76 | extern int of_set_property(struct device_node *node, const char *name, void *val, int len); |
77 | extern struct mutex of_set_property_mutex; | ||
76 | extern int of_getintprop_default(struct device_node *np, | 78 | extern 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 | */ | ||
104 | extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); | ||
105 | static 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 | |||
116 | static inline int pt_regs_trap_type(struct pt_regs *regs) | 118 | static 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 | }; |
143 | extern 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 | |||
4 | extern 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 | |||
12 | struct 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 | |||
32 | static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset) | ||
33 | { | ||
34 | return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<25)+(offset)); | ||
35 | } | ||
36 | |||
37 | static inline int sbus_dev_slot(unsigned long dev_addr) | ||
38 | { | ||
39 | return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>25); | ||
40 | } | ||
41 | |||
42 | struct sbus_bus; | ||
43 | |||
44 | /* Linux SBUS device tables */ | ||
45 | struct 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. */ | ||
69 | struct 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 | |||
85 | extern struct sbus_bus *sbus_root; | ||
86 | |||
87 | static inline int | ||
88 | sbus_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 */ | ||
108 | extern void sbus_set_sbus64(struct sbus_dev *, int); | ||
109 | extern void sbus_fill_device_irq(struct sbus_dev *); | ||
110 | |||
111 | /* These yield IOMMU mappings in consistent mode. */ | ||
112 | extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp); | ||
113 | extern void sbus_free_consistent(struct sbus_dev *, long, void *, u32); | ||
114 | void 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. */ | ||
123 | extern dma_addr_t sbus_map_single(struct sbus_dev *, void *, size_t, int); | ||
124 | extern void sbus_unmap_single(struct sbus_dev *, dma_addr_t, size_t, int); | ||
125 | extern int sbus_map_sg(struct sbus_dev *, struct scatterlist *, int, int); | ||
126 | extern void sbus_unmap_sg(struct sbus_dev *, struct scatterlist *, int, int); | ||
127 | |||
128 | /* Finally, allow explicit synchronization of streamable mappings. */ | ||
129 | extern 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 | ||
131 | extern void sbus_dma_sync_single_for_device(struct sbus_dev *, dma_addr_t, size_t, int); | ||
132 | extern 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 | ||
134 | extern 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 | */ | ||
144 | BTFIXUPDEF_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 | |||
147 | extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *); | ||
148 | extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *); | ||
149 | extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *); | ||
150 | extern int sbus_arch_preinit(void); | ||
151 | extern 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 | |||
32 | static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset) | ||
33 | { | ||
34 | return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset)); | ||
35 | } | ||
36 | |||
37 | static inline int sbus_dev_slot(unsigned long dev_addr) | ||
38 | { | ||
39 | return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28); | ||
40 | } | ||
41 | |||
42 | struct sbus_bus; | ||
43 | |||
44 | /* Linux SBUS device tables */ | ||
45 | struct 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. */ | ||
69 | struct 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 | |||
84 | extern 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) | ||
100 | extern void sbus_set_sbus64(struct sbus_dev *, int); | ||
101 | extern void sbus_fill_device_irq(struct sbus_dev *); | ||
102 | |||
103 | static 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 | |||
110 | static 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. */ | ||
122 | static 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 | |||
129 | static 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 | |||
137 | static 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 | |||
144 | static 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. */ | ||
152 | static 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 | |||
161 | static 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 | |||
168 | static 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 | |||
177 | static 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 | |||
184 | extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *); | ||
185 | extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *); | ||
186 | extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *); | ||
187 | extern int sbus_arch_preinit(void); | ||
188 | extern 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 | |||
4 | extern void sstate_booting(void); | ||
5 | extern void sstate_running(void); | ||
6 | extern void sstate_halt(void); | ||
7 | extern void sstate_poweroff(void); | ||
8 | extern void sstate_panic(void); | ||
9 | extern void sstate_reboot(void); | ||
10 | |||
11 | extern 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 @@ | |||
12 | extern int this_is_starfire; | 12 | extern int this_is_starfire; |
13 | 13 | ||
14 | extern void check_if_starfire(void); | 14 | extern void check_if_starfire(void); |
15 | extern void starfire_cpu_setup(void); | ||
16 | extern int starfire_hard_smp_processor_id(void); | 15 | extern int starfire_hard_smp_processor_id(void); |
17 | extern void starfire_hookup(int); | 16 | extern void starfire_hookup(int); |
18 | extern unsigned int starfire_translate(unsigned long imap, unsigned int upaid); | 17 | extern 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 | |||
46 | extern int sun4_memreg_physaddr; /* memory register (ecc?) */ | ||
47 | extern int sun4_clock_physaddr; /* system clock */ | ||
48 | extern int sun4_timer_physaddr; /* timer, where applicable */ | ||
49 | extern int sun4_eth_physaddr; /* onboard ethernet (ie/le) */ | ||
50 | extern int sun4_si_physaddr; /* sun3 scsi adapter */ | ||
51 | extern int sun4_bwtwo_physaddr; /* onboard bw2 */ | ||
52 | extern int sun4_dma_physaddr; /* scsi dma */ | ||
53 | extern int sun4_esp_physaddr; /* esp scsi */ | ||
54 | extern 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 | |||
19 | typedef 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 | |||
81 | extern 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 | ||
35 | extern enum sparc_cpu sparc_cpu_model; | 35 | extern 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; | |||
55 | extern void sun_do_break(void); | 49 | extern void sun_do_break(void); |
56 | extern int serial_console; | 50 | extern int serial_console; |
57 | extern int stop_a_enabled; | 51 | extern int stop_a_enabled; |
52 | extern int scons_pwroff; | ||
58 | 53 | ||
59 | static inline int con_is_present(void) | 54 | static 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 | ||
33 | extern char reboot_command[]; | 32 | extern char reboot_command[]; |
34 | 33 | ||
@@ -118,6 +117,7 @@ do { __asm__ __volatile__("ba,pt %%xcc, 1f\n\t" \ | |||
118 | 117 | ||
119 | extern void sun_do_break(void); | 118 | extern void sun_do_break(void); |
120 | extern int stop_a_enabled; | 119 | extern int stop_a_enabled; |
120 | extern int scons_pwroff; | ||
121 | 121 | ||
122 | extern void fault_in_user_windows(void); | 122 | extern void fault_in_user_windows(void); |
123 | extern void synchronize_user_stack(void); | 123 | extern 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 | |||
30 | struct 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 | |||
58 | struct 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 | |||
71 | struct 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 | |||
90 | struct 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 | |||
98 | extern struct sun4d_timer_regs *sun4d_timers; | ||
99 | |||
100 | extern __volatile__ unsigned int *master_l10_counter; | 14 | extern __volatile__ unsigned int *master_l10_counter; |
101 | extern __volatile__ unsigned int *master_l10_limit; | ||
102 | 15 | ||
103 | /* FIXME: Make do_[gs]ettimeofday btfixup calls */ | 16 | /* FIXME: Make do_[gs]ettimeofday btfixup calls */ |
104 | BTFIXUPDEF_CALL(int, bus_do_settimeofday, struct timespec *tv) | 17 | BTFIXUPDEF_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 | */ |
95 | struct sun4c_vac_props { | 91 | struct 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 | |||
50 | struct 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 | } |
60 | extern 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 | ||
18 | devres-y = ../../../kernel/irq/devres.o | 18 | devres-y = ../../../kernel/irq/devres.o |
19 | 19 | ||
20 | obj-$(CONFIG_PCI) += pcic.o | 20 | obj-$(CONFIG_PCI) += pcic.o |
21 | obj-$(CONFIG_SUN4) += sun4setup.o | ||
22 | obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o | 21 | obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o |
23 | obj-$(CONFIG_SUN_AUXIO) += auxio.o | 22 | obj-$(CONFIG_SUN_AUXIO) += auxio.o |
24 | obj-$(CONFIG_PCI) += ebus.o | ||
25 | obj-$(CONFIG_SUN_PM) += apc.o pmc.o | 23 | obj-$(CONFIG_SUN_PM) += apc.o pmc.o |
26 | obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o | 24 | obj-$(CONFIG_MODULES) += module.o sparc_ksyms.o |
27 | obj-$(CONFIG_SPARC_LED) += led.o | 25 | obj-$(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 | ||
32 | volatile static u8 __iomem *regs; | 33 | static u8 __iomem *regs; |
33 | static int apc_regsize; | ||
34 | static int apc_no_idle __initdata = 0; | 34 | static 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 | ||
72 | static inline void apc_free(void) | 72 | static 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 | ||
77 | static int apc_open(struct inode *inode, struct file *f) | 77 | static int apc_open(struct inode *inode, struct file *f) |
@@ -153,52 +153,56 @@ static const struct file_operations apc_fops = { | |||
153 | 153 | ||
154 | static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; | 154 | static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops }; |
155 | 155 | ||
156 | static int __init apc_probe(void) | 156 | static 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 | ||
170 | sbus_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 | ||
185 | static struct of_device_id __initdata apc_match[] = { | ||
186 | { | ||
187 | .name = APC_OBPNAME, | ||
188 | }, | ||
189 | {}, | ||
190 | }; | ||
191 | MODULE_DEVICE_TABLE(of, apc_match); | ||
192 | |||
193 | static struct of_platform_driver apc_driver = { | ||
194 | .name = "apc", | ||
195 | .match_table = apc_match, | ||
196 | .probe = apc_probe, | ||
197 | }; | ||
198 | |||
199 | static 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 | |||
18 | int 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 | } | ||
26 | EXPORT_SYMBOL(dma_supported); | ||
27 | |||
28 | int 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 | } | ||
36 | EXPORT_SYMBOL(dma_set_mask); | ||
37 | |||
38 | void *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 | } | ||
47 | EXPORT_SYMBOL(dma_alloc_coherent); | ||
48 | |||
49 | void 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 | } | ||
61 | EXPORT_SYMBOL(dma_free_coherent); | ||
62 | |||
63 | dma_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 | } | ||
73 | EXPORT_SYMBOL(dma_map_single); | ||
74 | |||
75 | void 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 | } | ||
88 | EXPORT_SYMBOL(dma_unmap_single); | ||
89 | |||
90 | dma_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 | } | ||
102 | EXPORT_SYMBOL(dma_map_page); | ||
103 | |||
104 | void 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 | } | ||
116 | EXPORT_SYMBOL(dma_unmap_page); | ||
117 | |||
118 | int 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 | } | ||
127 | EXPORT_SYMBOL(dma_map_sg); | ||
128 | |||
129 | void 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 | } | ||
140 | EXPORT_SYMBOL(dma_unmap_sg); | ||
141 | |||
142 | void 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 | } | ||
154 | EXPORT_SYMBOL(dma_sync_single_for_cpu); | ||
155 | |||
156 | void 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 | } | ||
168 | EXPORT_SYMBOL(dma_sync_single_for_device); | ||
169 | |||
170 | void 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 | } | ||
178 | EXPORT_SYMBOL(dma_sync_single_range_for_cpu); | ||
179 | |||
180 | void 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 | } | ||
186 | EXPORT_SYMBOL(dma_sync_single_range_for_device); | ||
187 | |||
188 | void 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 | } | ||
200 | EXPORT_SYMBOL(dma_sync_sg_for_cpu); | ||
201 | |||
202 | void 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 | } | ||
215 | EXPORT_SYMBOL(dma_sync_sg_for_device); | ||
216 | |||
217 | int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) | ||
218 | { | ||
219 | return (dma_addr == DMA_ERROR_CODE); | ||
220 | } | ||
221 | EXPORT_SYMBOL(dma_mapping_error); | ||
222 | |||
223 | int dma_get_cache_alignment(void) | ||
224 | { | ||
225 | return 32; | ||
226 | } | ||
227 | EXPORT_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 @@ | |||
1 | void *sbus_alloc_consistent(struct device *dev, long len, u32 *dma_addrp); | ||
2 | void sbus_free_consistent(struct device *dev, long n, void *p, u32 ba); | ||
3 | dma_addr_t sbus_map_single(struct device *dev, void *va, | ||
4 | size_t len, int direction); | ||
5 | void sbus_unmap_single(struct device *dev, dma_addr_t ba, | ||
6 | size_t n, int direction); | ||
7 | int sbus_map_sg(struct device *dev, struct scatterlist *sg, | ||
8 | int n, int direction); | ||
9 | void sbus_unmap_sg(struct device *dev, struct scatterlist *sg, | ||
10 | int n, int direction); | ||
11 | void sbus_dma_sync_single_for_cpu(struct device *dev, dma_addr_t ba, | ||
12 | size_t size, int direction); | ||
13 | void 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 | |||
25 | struct linux_ebus *ebus_chain = NULL; | ||
26 | |||
27 | /* We are together with pcic.c under CONFIG_PCI. */ | ||
28 | extern 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 | */ | ||
34 | struct ebus_device_irq { | ||
35 | char *name; | ||
36 | unsigned int pin; | ||
37 | }; | ||
38 | |||
39 | struct ebus_system_entry { | ||
40 | char *esname; | ||
41 | struct ebus_device_irq *ipt; | ||
42 | }; | ||
43 | |||
44 | static 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 | */ | ||
56 | static struct ebus_system_entry ebus_blacklist[] = { | ||
57 | { "SUNW,JavaEngine1", je1_1 }, | ||
58 | { NULL, NULL } | ||
59 | }; | ||
60 | |||
61 | static struct ebus_device_irq *ebus_blackp = NULL; | ||
62 | |||
63 | /* | ||
64 | */ | ||
65 | static inline unsigned long ebus_alloc(size_t size) | ||
66 | { | ||
67 | return (unsigned long)kmalloc(size, GFP_ATOMIC); | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | */ | ||
72 | static 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 | |||
86 | static 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 | |||
147 | static 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 | |||
279 | void __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 | */ |
277 | maybe_smp4m_msg: | 273 | maybe_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: | |||
327 | 1: | 324 | 1: |
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 | ||
779 | vac_hwflush_patch1_on: nop | ||
780 | #else | ||
781 | vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 | 774 | vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 |
782 | #endif | ||
783 | 775 | ||
784 | vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG | 776 | vac_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 |
800 | sun4c_fault: | 792 | sun4c_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 | |||
815 | 0: 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 | ||
830 | 1: | ||
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 | ||
945 | 9: | 896 | 9: |
946 | vac_hwflush_patch1: | 897 | vac_hwflush_patch1: |
947 | vac_linesize_patch: | 898 | vac_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 | ||
67 | sun4_notsup: | 66 | sun4_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 | ||
71 | sun4cdm_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 | ||
76 | sun4e_notsup: | 70 | sun4e_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 | ||
782 | found_version: | 776 | found_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 | ||
1152 | sun4_init: | 1137 | sun4_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 |
1171 | 1: ba 1b ! Cannot exit into KMON | 1147 | 1: ba 1b ! Cannot exit into KMON |
1172 | nop | 1148 | nop |
1173 | #endif | 1149 | |
1174 | no_sun4e_here: | 1150 | no_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> | ||
17 | extern void sun4setup(void); | ||
18 | #endif | ||
19 | 15 | ||
20 | struct idprom *idprom; | 16 | struct idprom *idprom; |
21 | static struct idprom idprom_buffer; | 17 | static 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 | */ | ||
144 | void __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 | |||
151 | void __iomem *of_ioremap(struct resource *res, unsigned long offset, | 145 | void __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) | |||
164 | EXPORT_SYMBOL(of_iounmap); | 158 | EXPORT_SYMBOL(of_iounmap); |
165 | 159 | ||
166 | /* | 160 | /* |
167 | */ | ||
168 | void 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 | */ |
176 | static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, | 163 | static 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 | ||
249 | void sbus_set_sbus64(struct sbus_dev *sdev, int x) | 236 | void 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 | ||
254 | extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq); | ||
255 | void __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 | */ |
304 | void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) | 246 | void *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 | ||
359 | void sbus_free_consistent(struct sbus_dev *sdev, long n, void *p, u32 ba) | 299 | void 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 | */ |
397 | dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *va, size_t len, int direction) | 337 | dma_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 | ||
410 | void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t ba, size_t n, int direction) | 350 | void 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 | ||
415 | int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) | 355 | int 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 | ||
426 | void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) | 366 | void 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 | */ | ||
433 | void 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 | |||
453 | void 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 | ||
473 | void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) | 371 | void 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 | ||
478 | void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) | 375 | void 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) */ | ||
490 | void __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 | ||
511 | void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) | 379 | static 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 | |||
533 | void __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 | |||
543 | int __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 | ||
558 | void __init sbus_arch_postinit(void) | 386 | arch_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) | |||
13 | BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int) | 13 | BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int) |
14 | BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int) | 14 | BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int) |
15 | BTFIXUPDEF_CALL(void, clear_clock_irq, void) | 15 | BTFIXUPDEF_CALL(void, clear_clock_irq, void) |
16 | BTFIXUPDEF_CALL(void, clear_profile_irq, int) | ||
17 | BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) | 16 | BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int) |
18 | 17 | ||
19 | static inline void __disable_irq(unsigned int irq) | 18 | static 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 | ||
44 | static inline void clear_profile_irq(int irq) | ||
45 | { | ||
46 | BTFIXUP_CALL(clear_profile_irq)(irq); | ||
47 | } | ||
48 | |||
49 | static inline void load_profile_irq(int cpu, int limit) | 43 | static 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 c481d45f97b7..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 | } |
30 | EXPORT_SYMBOL(of_find_device_by_node); | 30 | EXPORT_SYMBOL(of_find_device_by_node); |
31 | 31 | ||
32 | #ifdef CONFIG_PCI | 32 | unsigned int irq_of_parse_and_map(struct device_node *node, int index) |
33 | struct bus_type ebus_bus_type; | 33 | { |
34 | EXPORT_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 | } | ||
41 | EXPORT_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 | */ | ||
46 | void 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; |
38 | struct bus_type sbus_bus_type; | 56 | op->dev.archdata.stc = bus_sd->stc; |
39 | EXPORT_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 | ||
42 | struct bus_type of_platform_bus_type; | 65 | struct bus_type of_platform_bus_type; |
43 | EXPORT_SYMBOL(of_platform_bus_type); | 66 | EXPORT_SYMBOL(of_platform_bus_type); |
@@ -241,7 +264,7 @@ static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) | |||
241 | return of_bus_default_map(addr, range, na, ns, pna); | 264 | return of_bus_default_map(addr, range, na, ns, pna); |
242 | } | 265 | } |
243 | 266 | ||
244 | static unsigned int of_bus_sbus_get_flags(const u32 *addr) | 267 | static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags) |
245 | { | 268 | { |
246 | return IORESOURCE_MEM; | 269 | return IORESOURCE_MEM; |
247 | } | 270 | } |
@@ -327,6 +350,27 @@ static int __init build_one_resource(struct device_node *parent, | |||
327 | return 1; | 350 | return 1; |
328 | } | 351 | } |
329 | 352 | ||
353 | static 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 | |||
330 | static int of_resource_verbose; | 374 | static int of_resource_verbose; |
331 | 375 | ||
332 | static void __init build_device_resources(struct of_device *op, | 376 | static 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 | */ |
682 | unsigned int | 675 | unsigned int |
683 | pcic_pin_to_irq(unsigned int pin, const char *name) | 676 | pcic_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 | ||
907 | static void pcic_clear_profile_irq(int cpu) | ||
908 | { | ||
909 | printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__); | ||
910 | } | ||
911 | |||
912 | static void pcic_load_profile_irq(int cpu, unsigned int limit) | 900 | static 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 | ||
33 | volatile static u8 __iomem *regs; | 32 | static u8 __iomem *regs; |
34 | static 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 | ||
56 | static inline void pmc_free(void) | 54 | static 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 | |||
61 | static 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 | |||
73 | sbus_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 | ||
73 | static struct of_device_id __initdata pmc_match[] = { | ||
74 | { | ||
75 | .name = PMC_OBPNAME, | ||
76 | }, | ||
77 | {}, | ||
78 | }; | ||
79 | MODULE_DEVICE_TABLE(of, pmc_match); | ||
80 | |||
81 | static struct of_platform_driver pmc_driver = { | ||
82 | .name = "pmc", | ||
83 | .match_table = pmc_match, | ||
84 | .probe = pmc_probe, | ||
85 | }; | ||
86 | |||
87 | static 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 | } |
55 | EXPORT_SYMBOL(of_getintprop_default); | 55 | EXPORT_SYMBOL(of_getintprop_default); |
56 | 56 | ||
57 | DEFINE_MUTEX(of_set_property_mutex); | ||
58 | EXPORT_SYMBOL(of_set_property_mutex); | ||
59 | |||
57 | int of_set_property(struct device_node *dp, const char *name, void *val, int len) | 60 | int 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/ptrace.c b/arch/sparc/kernel/ptrace.c index 20699c701412..8ce6285a06d5 100644 --- a/arch/sparc/kernel/ptrace.c +++ b/arch/sparc/kernel/ptrace.c | |||
@@ -288,7 +288,7 @@ static const struct user_regset sparc32_regsets[] = { | |||
288 | */ | 288 | */ |
289 | [REGSET_GENERAL] = { | 289 | [REGSET_GENERAL] = { |
290 | .core_note_type = NT_PRSTATUS, | 290 | .core_note_type = NT_PRSTATUS, |
291 | .n = 38 * sizeof(u32), | 291 | .n = 38, |
292 | .size = sizeof(u32), .align = sizeof(u32), | 292 | .size = sizeof(u32), .align = sizeof(u32), |
293 | .get = genregs32_get, .set = genregs32_set | 293 | .get = genregs32_get, .set = genregs32_set |
294 | }, | 294 | }, |
@@ -304,7 +304,7 @@ static const struct user_regset sparc32_regsets[] = { | |||
304 | */ | 304 | */ |
305 | [REGSET_FP] = { | 305 | [REGSET_FP] = { |
306 | .core_note_type = NT_PRFPREG, | 306 | .core_note_type = NT_PRFPREG, |
307 | .n = 99 * sizeof(u32), | 307 | .n = 99, |
308 | .size = sizeof(u32), .align = sizeof(u32), | 308 | .size = sizeof(u32), .align = sizeof(u32), |
309 | .get = fpregs32_get, .set = fpregs32_set | 309 | .get = fpregs32_get, .set = fpregs32_set |
310 | }, | 310 | }, |
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); | |||
127 | EXPORT_SYMBOL(__udelay); | 122 | EXPORT_SYMBOL(__udelay); |
128 | EXPORT_SYMBOL(__ndelay); | 123 | EXPORT_SYMBOL(__ndelay); |
129 | EXPORT_SYMBOL(rtc_lock); | 124 | EXPORT_SYMBOL(rtc_lock); |
130 | EXPORT_SYMBOL(mostek_lock); | ||
131 | EXPORT_SYMBOL(mstk48t02_regs); | ||
132 | #ifdef CONFIG_SUN_AUXIO | 125 | #ifdef CONFIG_SUN_AUXIO |
133 | EXPORT_SYMBOL(set_auxio); | 126 | EXPORT_SYMBOL(set_auxio); |
134 | EXPORT_SYMBOL(get_auxio); | 127 | EXPORT_SYMBOL(get_auxio); |
135 | #endif | 128 | #endif |
136 | EXPORT_SYMBOL(io_remap_pfn_range); | 129 | EXPORT_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 |
142 | EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); | 132 | EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32)); |
@@ -153,24 +143,9 @@ EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one)); | |||
153 | EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached)); | 143 | EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached)); |
154 | 144 | ||
155 | #ifdef CONFIG_SBUS | 145 | #ifdef CONFIG_SBUS |
156 | EXPORT_SYMBOL(sbus_root); | ||
157 | EXPORT_SYMBOL(dma_chain); | ||
158 | EXPORT_SYMBOL(sbus_set_sbus64); | 146 | EXPORT_SYMBOL(sbus_set_sbus64); |
159 | EXPORT_SYMBOL(sbus_alloc_consistent); | ||
160 | EXPORT_SYMBOL(sbus_free_consistent); | ||
161 | EXPORT_SYMBOL(sbus_map_single); | ||
162 | EXPORT_SYMBOL(sbus_unmap_single); | ||
163 | EXPORT_SYMBOL(sbus_map_sg); | ||
164 | EXPORT_SYMBOL(sbus_unmap_sg); | ||
165 | EXPORT_SYMBOL(sbus_dma_sync_single_for_cpu); | ||
166 | EXPORT_SYMBOL(sbus_dma_sync_single_for_device); | ||
167 | EXPORT_SYMBOL(sbus_dma_sync_sg_for_cpu); | ||
168 | EXPORT_SYMBOL(sbus_dma_sync_sg_for_device); | ||
169 | EXPORT_SYMBOL(sbus_iounmap); | ||
170 | EXPORT_SYMBOL(sbus_ioremap); | ||
171 | #endif | 147 | #endif |
172 | #ifdef CONFIG_PCI | 148 | #ifdef CONFIG_PCI |
173 | EXPORT_SYMBOL(ebus_chain); | ||
174 | EXPORT_SYMBOL(insb); | 149 | EXPORT_SYMBOL(insb); |
175 | EXPORT_SYMBOL(outsb); | 150 | EXPORT_SYMBOL(outsb); |
176 | EXPORT_SYMBOL(insw); | 151 | EXPORT_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 | ||
40 | static struct resource sun4c_timer_eb = { "sun4c_timer" }; | ||
41 | static 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 | */ |
67 | unsigned char *interrupt_enable = NULL; | 62 | unsigned char __iomem *interrupt_enable = NULL; |
68 | |||
69 | static int sun4c_pil_map[] = { 0, 1, 2, 3, 5, 7, 8, 9 }; | ||
70 | |||
71 | static 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 | ||
81 | static void sun4c_disable_irq(unsigned int irq_nr) | 64 | static 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. */ | 122 | struct sun4c_timer_info { |
140 | #define PROFILE_IRQ 14 /* Level14 ticker.. used by OBP for polling */ | 123 | u32 l10_count; |
141 | 124 | u32 l10_limit; | |
142 | volatile struct sun4c_timer_info *sun4c_timers; | 125 | u32 l14_count; |
126 | u32 l14_limit; | ||
127 | }; | ||
143 | 128 | ||
144 | #ifdef CONFIG_SUN4 | 129 | static 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 | */ | ||
149 | volatile struct sun4c_timer_info sun4_timer; | ||
150 | #endif | ||
151 | 130 | ||
152 | static void sun4c_clear_clock_irq(void) | 131 | static 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 | |||
163 | static void sun4c_clear_profile_irq(int cpu) | ||
164 | { | ||
165 | /* Errm.. not sure how to do this.. */ | ||
166 | } | 134 | } |
167 | 135 | ||
168 | static void sun4c_load_profile_irq(int cpu, unsigned int limit) | 136 | static 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 | ||
173 | static void __init sun4c_init_timers(irq_handler_t counter_fn) | 141 | static 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 | ||
216 | void __init sun4c_init_IRQ(void) | 191 | void __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 | ||
47 | struct sun4d_timer_regs *sun4d_timers; | 48 | struct 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 | |||
56 | static 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 |
51 | extern struct irqaction static_irqaction[MAX_STATIC_ALLOC]; | 61 | extern struct irqaction static_irqaction[MAX_STATIC_ALLOC]; |
52 | extern int static_irq_count; | 62 | extern int static_irq_count; |
53 | unsigned char cpu_leds[32]; | ||
54 | #ifdef CONFIG_SMP | ||
55 | static unsigned char sbus_tid[32]; | 63 | static unsigned char sbus_tid[32]; |
56 | #endif | ||
57 | 64 | ||
58 | static struct irqaction *irq_action[NR_IRQS]; | 65 | static struct irqaction *irq_action[NR_IRQS]; |
59 | extern spinlock_t irq_action_lock; | 66 | extern spinlock_t irq_action_lock; |
@@ -72,9 +79,9 @@ static int sbus_to_pil[] = { | |||
72 | }; | 79 | }; |
73 | 80 | ||
74 | static int nsbi; | 81 | static int nsbi; |
75 | #ifdef CONFIG_SMP | 82 | |
83 | /* Exported for sun4d_smp.c */ | ||
76 | DEFINE_SPINLOCK(sun4d_imsk_lock); | 84 | DEFINE_SPINLOCK(sun4d_imsk_lock); |
77 | #endif | ||
78 | 85 | ||
79 | int show_sun4d_interrupts(struct seq_file *p, void *v) | 86 | int 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 | ||
260 | unsigned 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 | |||
270 | static 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 | |||
280 | int sun4d_request_irq(unsigned int irq, | 267 | int 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 | ||
361 | static void sun4d_disable_irq(unsigned int irq) | 348 | static 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 | ||
378 | static void sun4d_enable_irq(unsigned int irq) | 361 | static 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. */ |
410 | void __init sun4d_distribute_irqs(void) | 389 | void __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 | ||
459 | static void sun4d_clear_clock_irq(void) | 446 | static 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 | |||
465 | static void sun4d_clear_profile_irq(int cpu) | ||
466 | { | ||
467 | bw_get_prof_limit(cpu); | ||
468 | } | 449 | } |
469 | 450 | ||
470 | static void sun4d_load_profile_irq(int cpu, unsigned int limit) | 451 | static 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 | ||
475 | static void __init sun4d_init_timers(irq_handler_t counter_fn) | 456 | static 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 | |||
466 | static 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); | 493 | static 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 | ||
542 | void __init sun4d_init_sbi_irq(void) | 541 | void __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); | |||
72 | extern void cpu_probe(void); | 71 | extern void cpu_probe(void); |
73 | extern void sun4d_distribute_irqs(void); | 72 | extern void sun4d_distribute_irqs(void); |
74 | 73 | ||
74 | static unsigned char cpu_leds[32]; | ||
75 | |||
76 | static 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 | |||
75 | void __init smp4d_callin(void) | 85 | void __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 | 44 | struct 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 | */ | ||
50 | struct 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 | /* | 50 | struct 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 | */ | ||
74 | struct 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 | ||
87 | static unsigned long dummy; | 58 | /* Code in entry.S needs to get at these register mappings. */ |
88 | 59 | struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS]; | |
89 | struct sun4m_intregs *sun4m_interrupts; | 60 | struct sun4m_irq_global __iomem *sun4m_irq_global; |
90 | unsigned 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 | */ |
131 | static 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 | ||
137 | static unsigned long irq_mask[] = { | 156 | static 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 | ||
155 | static int sun4m_pil_map[] = { 0, 2, 3, 5, 7, 9, 11, 13 }; | ||
156 | |||
157 | static 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 | |||
167 | static unsigned long sun4m_get_irqmask(unsigned int irq) | 194 | static 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 | */ |
248 | static void sun4m_disable_pil_irq(unsigned int pil) | 270 | static 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 | ||
253 | static void sun4m_enable_pil_irq(unsigned int pil) | 275 | static 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 |
259 | static void sun4m_send_ipi(int cpu, int level) | 281 | static 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 | ||
267 | static void sun4m_clear_ipi(int cpu, int level) | 287 | static 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 | ||
275 | static void sun4m_set_udt(int cpu) | 293 | static 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 | 299 | struct 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 | |||
306 | static struct sun4m_timer_percpu __iomem *timers_percpu[SUN4M_NCPUS]; | ||
307 | |||
308 | struct 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 | |||
316 | static struct sun4m_timer_global __iomem *timers_global; | ||
317 | |||
318 | #define TIMER_IRQ (OBP_INT_LEVEL_ONBOARD | 10) | ||
284 | 319 | ||
285 | static struct sun4m_timer_regs *sun4m_timers; | ||
286 | unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); | 320 | unsigned int lvl14_resolution = (((1000000/HZ) + 1) << 10); |
287 | 321 | ||
288 | static void sun4m_clear_clock_irq(void) | 322 | static 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 | ||
294 | static void sun4m_clear_profile_irq(int cpu) | 327 | void 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 */ | ||
355 | void sun4m_clear_profile_irq(int cpu) | ||
356 | { | ||
357 | sbus_readl(&timers_percpu[cpu]->l14_limit); | ||
299 | } | 358 | } |
300 | 359 | ||
301 | static void sun4m_load_profile_irq(int cpu, unsigned int limit) | 360 | static 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 | ||
306 | static void __init sun4m_init_timers(irq_handler_t counter_fn) | 365 | static 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 | ||
391 | void __init sun4m_init_IRQ(void) | 428 | void __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 | ||
318 | extern void sun4m_clear_profile_irq(int cpu); | ||
319 | |||
316 | void smp4m_percpu_timer_interrupt(struct pt_regs *regs) | 320 | void 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 | |||
13 | int sun4_memreg_physaddr; | ||
14 | int sun4_ie_physaddr; | ||
15 | int sun4_clock_physaddr; | ||
16 | int sun4_timer_physaddr; | ||
17 | int sun4_eth_physaddr; | ||
18 | int sun4_si_physaddr; | ||
19 | int sun4_bwtwo_physaddr; | ||
20 | int sun4_zs0_physaddr; | ||
21 | int sun4_zs1_physaddr; | ||
22 | int sun4_dma_physaddr; | ||
23 | int sun4_esp_physaddr; | ||
24 | int sun4_ie_physaddr; | ||
25 | |||
26 | void __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 | ||
82 | asmlinkage unsigned long sparc_brk(unsigned long brk) | 82 | asmlinkage 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 | ||
222 | int sparc_mmap_check(unsigned long addr, unsigned long len) | 222 | int 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 | ||
30 | extern unsigned long lvl14_save[5]; | 11 | extern unsigned long lvl14_save[5]; |
31 | static unsigned long *linux_lvl14 = NULL; | 12 | static 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 | |||
60 | void 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 | ||
48 | DEFINE_SPINLOCK(rtc_lock); | 50 | DEFINE_SPINLOCK(rtc_lock); |
49 | static enum sparc_clock_type sp_clock_typ; | ||
50 | DEFINE_SPINLOCK(mostek_lock); | ||
51 | void __iomem *mstk48t02_regs = NULL; | ||
52 | static struct mostek48t08 __iomem *mstk48t08_regs = NULL; | ||
53 | static int set_rtc_mmss(unsigned long); | 51 | static int set_rtc_mmss(unsigned long); |
54 | static int sbus_do_settimeofday(struct timespec *tv); | 52 | static int sbus_do_settimeofday(struct timespec *tv); |
55 | 53 | ||
56 | #ifdef CONFIG_SUN4 | ||
57 | struct 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 | |||
77 | unsigned long profile_pc(struct pt_regs *regs) | 54 | unsigned 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) | |||
96 | EXPORT_SYMBOL(profile_pc); | 73 | EXPORT_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). */ | 118 | static unsigned char mostek_read_byte(struct device *dev, u32 ofs) |
151 | static 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. */ | ||
211 | static 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 | ||
226 | static void __devinit mostek_set_system_time(void) | 134 | static 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 */ | 153 | static struct m48t59_plat_data m48t59_data = { |
253 | static 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 | 159 | static 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 | ||
301 | static int __devinit clock_probe(struct of_device *op, const struct of_device_id *match) | 168 | static 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 | ||
340 | static struct of_device_id clock_match[] = { | 195 | static 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 | */ |
366 | fs_initcall(clock_init); | 221 | fs_initcall(clock_init); |
367 | #endif /* !CONFIG_SUN4 */ | ||
368 | 222 | ||
369 | static void __init sbus_time_init(void) | 223 | static 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 | /* | 336 | static 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 | */ | ||
529 | static 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 | ||
46 | void 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 | |||
63 | void sun4d_nmi(struct pt_regs *regs) | 46 | void 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 | ||
4 | EXTRA_AFLAGS := -ansi | 4 | EXTRA_AFLAGS := -ansi |
5 | 5 | ||
6 | obj-y := fault.o init.o loadmmu.o generic.o extable.o btfixup.o | 6 | obj-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 | |
8 | ifeq ($(CONFIG_SUN4),y) | ||
9 | obj-y += nosrmmu.o | ||
10 | else | ||
11 | obj-y += srmmu.o iommu.o io-unit.o hypersparc.o viking.o tsunami.o swift.o | ||
12 | endif | ||
13 | 8 | ||
14 | ifdef CONFIG_HIGHMEM | 9 | ifdef CONFIG_HIGHMEM |
15 | obj-y += highmem.o | 10 | obj-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 | ||
21 | extern char *srmmu_name; | 21 | extern char *srmmu_name; |
22 | static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; | 22 | static char version[] __initdata = "Boot time fixup v1.6. 4/Mar/98 Jakub Jelinek (jj@ultra.linux.cz). Patching kernel for "; |
23 | #ifdef CONFIG_SUN4 | ||
24 | static char str_sun4c[] __initdata = "sun4\n"; | ||
25 | #else | ||
26 | static char str_sun4c[] __initdata = "sun4c\n"; | 23 | static char str_sun4c[] __initdata = "sun4c\n"; |
27 | #endif | ||
28 | static char str_srmmu[] __initdata = "srmmu[%s]/"; | 24 | static char str_srmmu[] __initdata = "srmmu[%s]/"; |
29 | static char str_iommu[] __initdata = "iommu\n"; | 25 | static char str_iommu[] __initdata = "iommu\n"; |
30 | static char str_iounit[] __initdata = "io-unit\n"; | 26 | static 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 |
495 | void free_initrd_mem(unsigned long start, unsigned long end) | 498 | void 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 | ||
37 | void __init | 38 | static void __init iounit_iommu_init(struct of_device *op) |
38 | iounit_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 | ||
71 | static 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 | |||
88 | subsys_initcall(iounit_init); | ||
89 | |||
78 | /* One has to hold iounit->lock to call this */ | 90 | /* One has to hold iounit->lock to call this */ |
79 | static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) | 91 | static 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 | ||
127 | static __u32 iounit_get_scsi_one(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 139 | static __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 | ||
138 | static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 150 | static 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 | ||
154 | static void iounit_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) | 166 | static 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 | ||
168 | static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 180 | static 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 |
188 | static int iounit_map_dma_area(dma_addr_t *pba, unsigned long va, __u32 addr, int len) | 200 | static 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 | ||
231 | static void iounit_unmap_dma_area(unsigned long addr, int len) | 239 | static 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. */ | ||
237 | static 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 | ||
250 | static char *iounit_lockarea(char *vaddr, unsigned long len) | 245 | static 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); | ||
289 | next: j = (i & 15); | ||
290 | rotor = iounit->rotor[j - 1]; | ||
291 | limit = iounit->limit[j]; | ||
292 | scan = rotor; | ||
293 | nexti: 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 | ||
58 | void __init | 59 | static void __init sbus_iommu_init(struct of_device *op) |
59 | iommu_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 | |||
130 | static 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 | ||
144 | subsys_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 | ||
167 | static u32 iommu_get_one(struct page *page, int npages, struct sbus_bus *sbus) | 175 | static 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 | ||
197 | static u32 iommu_get_scsi_one(char *vaddr, unsigned int len, | 205 | static 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 | ||
212 | static __u32 iommu_get_scsi_one_noflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 219 | static __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 | ||
217 | static __u32 iommu_get_scsi_one_gflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 224 | static __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 | ||
223 | static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sbus_bus *sbus) | 230 | static __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 | ||
234 | static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 241 | static 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 | ||
247 | static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 254 | static 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 | ||
261 | static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 268 | static 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 | ||
292 | static void iommu_release_one(u32 busa, int npages, struct sbus_bus *sbus) | 299 | static 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 | ||
308 | static void iommu_release_scsi_one(__u32 vaddr, unsigned long len, struct sbus_bus *sbus) | 315 | static 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 | ||
318 | static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 325 | static 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 |
333 | static int iommu_map_dma_area(dma_addr_t *pba, unsigned long va, | 340 | static 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 | ||
400 | static void iommu_unmap_dma_area(unsigned long busa, int len) | 407 | static 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 | |||
421 | static 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 | ||
431 | static char *iommu_lockarea(char *vaddr, unsigned long len) | 429 | static 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 | |||
14 | static char shouldnothappen[] __initdata = "SUN4 kernel can only run on SUN4\n"; | ||
15 | |||
16 | enum mbus_module srmmu_modtype; | ||
17 | void *srmmu_nocache_pool; | ||
18 | |||
19 | int vac_cache_size = 0; | ||
20 | |||
21 | static void __init should_not_happen(void) | ||
22 | { | ||
23 | prom_printf(shouldnothappen); | ||
24 | prom_halt(); | ||
25 | } | ||
26 | |||
27 | void __init srmmu_frob_mem_map(unsigned long start_mem) | ||
28 | { | ||
29 | should_not_happen(); | ||
30 | } | ||
31 | |||
32 | unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long end_mem) | ||
33 | { | ||
34 | should_not_happen(); | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | void __init ld_mmu_srmmu(void) | ||
39 | { | ||
40 | should_not_happen(); | ||
41 | } | ||
42 | |||
43 | void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_type, int rdonly) | ||
44 | { | ||
45 | } | ||
46 | |||
47 | void 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 | ||
53 | extern unsigned long page_kernel; | 52 | extern 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 | ||
448 | static void __init sun4c_probe_mmu(void) | 400 | static 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 | ||
518 | static inline void sun4c_init_ss2_cache_bug(void) | 435 | static 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. */ |
535 | static int sun4c_map_dma_area(dma_addr_t *pba, unsigned long va, | 451 | static 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 | ||
558 | static struct page *sun4c_translate_dvma(unsigned long busa) | 474 | static 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 | |||
565 | static 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 | */ |
1214 | static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus *sbus) | 1111 | static __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 | ||
1226 | static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 1123 | static 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 | ||
1236 | static void sun4c_release_scsi_one(__u32 bufptr, unsigned long len, struct sbus_bus *sbus) | 1133 | static 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 | ||
1243 | static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus) | 1140 | static 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 | ||
5 | lib-y := bootstr.o devmap.o devops.o init.o memory.o misc.o mp.o \ | 5 | lib-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 | |||
8 | lib-$(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 |
13 | static char barg_buf[BARG_LEN] = { 0 }; | 12 | static char barg_buf[BARG_LEN] = { 0 }; |
14 | static char fetched __initdata = 0; | 13 | static char fetched __initdata = 0; |
15 | 14 | ||
16 | extern linux_sun4_romvec *sun4_romvec; | ||
17 | |||
18 | char * __init | 15 | char * __init |
19 | prom_getbootargs(void) | 16 | prom_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 | ||
16 | struct linux_romvec *romvec; | 15 | struct linux_romvec *romvec; |
17 | enum prom_major_version prom_vers; | 16 | enum prom_major_version prom_vers; |
18 | unsigned int prom_rev, prom_prev; | 17 | unsigned int prom_rev, prom_prev; |
19 | linux_sun4_romvec *sun4_romvec; | ||
20 | 18 | ||
21 | /* The root node of the prom device tree. */ | 19 | /* The root node of the prom device tree. */ |
22 | int prom_root_node; | 20 | int prom_root_node; |
@@ -34,10 +32,6 @@ extern void prom_ranges_init(void); | |||
34 | 32 | ||
35 | void __init prom_init(struct linux_romvec *rp) | 33 | void __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 | ||
49 | static 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 | |||
58 | static int sp_banks_cmp(const void *a, const void *b) | 48 | static 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 | ||
15 | struct linux_prom_ranges promlib_obio_ranges[PROMREG_MAX]; | 14 | struct 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 | |||
24 | static struct linux_romvec sun4romvec; | ||
25 | static struct idprom sun4_idprom; | ||
26 | |||
27 | struct property { | ||
28 | char *name; | ||
29 | char *value; | ||
30 | int length; | ||
31 | }; | ||
32 | |||
33 | struct node { | ||
34 | int level; | ||
35 | struct property *properties; | ||
36 | }; | ||
37 | |||
38 | struct property null_properties = { NULL, NULL, -1 }; | ||
39 | |||
40 | struct property root_properties[] = { | ||
41 | {"device_type", "cpu", 4}, | ||
42 | {"idprom", (char *)&sun4_idprom, sizeof(struct idprom)}, | ||
43 | {NULL, NULL, -1} | ||
44 | }; | ||
45 | |||
46 | struct node nodes[] = { | ||
47 | { 0, &null_properties }, | ||
48 | { 0, root_properties }, | ||
49 | { -1,&null_properties } | ||
50 | }; | ||
51 | |||
52 | |||
53 | static int no_nextnode(int node) | ||
54 | { | ||
55 | if (nodes[node].level == nodes[node+1].level) | ||
56 | return node+1; | ||
57 | return -1; | ||
58 | } | ||
59 | |||
60 | static 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 | |||
67 | static 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 | |||
77 | static 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 | |||
84 | static 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 | |||
94 | static int no_setprop(int node,char *name,char *value,int len) | ||
95 | { | ||
96 | return -1; | ||
97 | } | ||
98 | |||
99 | static 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 | |||
106 | static 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 | |||
115 | static int synch_hook; | ||
116 | |||
117 | struct 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 | } | ||