aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-25 06:44:44 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-25 06:44:44 -0400
commit76a9f26c9e40e9c0ed5dc8f0cedd74e733f0088d (patch)
tree8e2db4ba9263e92d264ef469c7dac28078f63874
parent9bf2aa129a107a0e9e2a5318d35aca731ae7e666 (diff)
parentdfd8317d3340f03bc06eba6b58f0ec0861da4a13 (diff)
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/
-rw-r--r--Documentation/sparc/sbus_drivers.txt95
-rw-r--r--arch/arm/kernel/iwmmxt.S2
-rw-r--r--arch/arm/kernel/signal.c207
-rw-r--r--arch/arm/mach-ep93xx/Makefile2
-rw-r--r--arch/arm/mach-ep93xx/clock.c156
-rw-r--r--arch/arm/mach-ep93xx/core.c28
-rw-r--r--arch/arm/mach-ixp2000/core.c1
-rw-r--r--arch/arm/mach-s3c2410/Kconfig20
-rw-r--r--arch/arm/mach-s3c2410/Makefile6
-rw-r--r--arch/arm/mach-s3c2410/clock.c21
-rw-r--r--arch/arm/mach-s3c2410/clock.h2
-rw-r--r--arch/arm/mach-s3c2410/cpu.c37
-rw-r--r--arch/arm/mach-s3c2410/cpu.h1
-rw-r--r--arch/arm/mach-s3c2410/irq.c57
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2413.c126
-rw-r--r--arch/arm/mach-s3c2410/pm-simtec.c3
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-clock.c10
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-gpio.c13
-rw-r--r--arch/arm/mach-s3c2410/s3c2412-clock.c711
-rw-r--r--arch/arm/mach-s3c2410/s3c2412.c195
-rw-r--r--arch/arm/mach-s3c2410/s3c2412.h29
-rw-r--r--arch/arm/mm/Kconfig10
-rw-r--r--arch/i386/kernel/vmlinux.lds.S7
-rw-r--r--arch/sparc/kernel/Makefile2
-rw-r--r--arch/sparc/kernel/ebus.c185
-rw-r--r--arch/sparc/kernel/ioport.c131
-rw-r--r--arch/sparc/kernel/of_device.c268
-rw-r--r--arch/sparc/kernel/pcic.c3
-rw-r--r--arch/sparc/kernel/prom.c474
-rw-r--r--arch/sparc/mm/init.c2
-rw-r--r--arch/sparc64/defconfig12
-rw-r--r--arch/sparc64/kernel/Makefile2
-rw-r--r--arch/sparc64/kernel/auxio.c109
-rw-r--r--arch/sparc64/kernel/central.c127
-rw-r--r--arch/sparc64/kernel/chmc.c69
-rw-r--r--arch/sparc64/kernel/devices.c222
-rw-r--r--arch/sparc64/kernel/ebus.c197
-rw-r--r--arch/sparc64/kernel/irq.c19
-rw-r--r--arch/sparc64/kernel/isa.c183
-rw-r--r--arch/sparc64/kernel/of_device.c279
-rw-r--r--arch/sparc64/kernel/pci.c59
-rw-r--r--arch/sparc64/kernel/pci_common.c227
-rw-r--r--arch/sparc64/kernel/pci_impl.h3
-rw-r--r--arch/sparc64/kernel/pci_psycho.c106
-rw-r--r--arch/sparc64/kernel/pci_sabre.c195
-rw-r--r--arch/sparc64/kernel/pci_schizo.c171
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c160
-rw-r--r--arch/sparc64/kernel/power.c113
-rw-r--r--arch/sparc64/kernel/prom.c650
-rw-r--r--arch/sparc64/kernel/sbus.c67
-rw-r--r--arch/sparc64/kernel/setup.c4
-rw-r--r--arch/sparc64/kernel/smp.c41
-rw-r--r--arch/sparc64/kernel/time.c386
-rw-r--r--arch/sparc64/kernel/traps.c18
-rw-r--r--arch/sparc64/kernel/unaligned.c9
-rw-r--r--arch/sparc64/mm/init.c52
-rw-r--r--arch/sparc64/solaris/misc.c34
-rw-r--r--drivers/base/power/Makefile1
-rw-r--r--drivers/base/power/resume.c4
-rw-r--r--drivers/base/power/trace.c228
-rw-r--r--drivers/char/drm/i915_dma.c4
-rw-r--r--drivers/char/drm/i915_drm.h13
-rw-r--r--drivers/char/drm/i915_drv.h6
-rw-r--r--drivers/char/drm/i915_irq.c69
-rw-r--r--drivers/char/drm/radeon_cp.c6
-rw-r--r--drivers/char/drm/radeon_drm.h7
-rw-r--r--drivers/char/drm/radeon_drv.h10
-rw-r--r--drivers/char/drm/radeon_state.c39
-rw-r--r--drivers/char/rtc.c4
-rw-r--r--drivers/input/misc/Kconfig2
-rw-r--r--drivers/input/misc/sparcspkr.c218
-rw-r--r--drivers/input/serio/i8042-sparcio.h10
-rw-r--r--drivers/net/myri_sbus.c116
-rw-r--r--drivers/net/myri_sbus.h1
-rw-r--r--drivers/net/sunbmac.c127
-rw-r--r--drivers/net/sunbmac.h1
-rw-r--r--drivers/net/sungem.c19
-rw-r--r--drivers/net/sunhme.c417
-rw-r--r--drivers/net/sunhme.h1
-rw-r--r--drivers/net/sunlance.c173
-rw-r--r--drivers/net/sunqe.c468
-rw-r--r--drivers/net/tg3.c10
-rw-r--r--drivers/net/tulip/tulip_core.c12
-rw-r--r--drivers/parport/parport_sunbpp.c134
-rw-r--r--drivers/sbus/char/bbc_envctrl.c4
-rw-r--r--drivers/sbus/char/bbc_i2c.c4
-rw-r--r--drivers/sbus/char/display7seg.c2
-rw-r--r--drivers/sbus/char/envctrl.c71
-rw-r--r--drivers/sbus/char/flash.c16
-rw-r--r--drivers/sbus/char/openprom.c4
-rw-r--r--drivers/sbus/sbus.c582
-rw-r--r--drivers/scsi/esp.c315
-rw-r--r--drivers/scsi/esp.h4
-rw-r--r--drivers/scsi/qlogicpti.c361
-rw-r--r--drivers/serial/Kconfig9
-rw-r--r--drivers/serial/s3c2410.c143
-rw-r--r--drivers/serial/sunhv.c35
-rw-r--r--drivers/serial/sunsab.c12
-rw-r--r--drivers/serial/sunsu.c4
-rw-r--r--drivers/serial/sunzilog.c2
-rw-r--r--drivers/usb/core/devio.c8
-rw-r--r--drivers/video/aty/atyfb_base.c2
-rw-r--r--drivers/video/intelfb/intelfb.h2
-rw-r--r--drivers/video/intelfb/intelfbdrv.c18
-rw-r--r--drivers/video/intelfb/intelfbhw.c24
-rw-r--r--include/asm-arm/arch-aaec2000/io.h1
-rw-r--r--include/asm-arm/arch-clps711x/io.h1
-rw-r--r--include/asm-arm/arch-ebsa285/io.h8
-rw-r--r--include/asm-arm/arch-ep93xx/ep93xx-regs.h2
-rw-r--r--include/asm-arm/arch-ep93xx/platform.h1
-rw-r--r--include/asm-arm/arch-integrator/io.h1
-rw-r--r--include/asm-arm/arch-iop3xx/io.h1
-rw-r--r--include/asm-arm/arch-l7200/io.h1
-rw-r--r--include/asm-arm/arch-lh7a40x/io.h1
-rw-r--r--include/asm-arm/arch-netx/io.h1
-rw-r--r--include/asm-arm/arch-omap/io.h1
-rw-r--r--include/asm-arm/arch-pxa/io.h1
-rw-r--r--include/asm-arm/arch-realview/io.h1
-rw-r--r--include/asm-arm/arch-s3c2410/debug-macro.S10
-rw-r--r--include/asm-arm/arch-s3c2410/entry-macro.S30
-rw-r--r--include/asm-arm/arch-s3c2410/map.h16
-rw-r--r--include/asm-arm/arch-s3c2410/regs-clock.h63
-rw-r--r--include/asm-arm/arch-s3c2410/regs-dsc.h3
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpio.h63
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpioj.h5
-rw-r--r--include/asm-arm/arch-s3c2410/regs-irq.h6
-rw-r--r--include/asm-arm/arch-s3c2410/regs-serial.h15
-rw-r--r--include/asm-arm/arch-sa1100/io.h1
-rw-r--r--include/asm-arm/arch-versatile/io.h1
-rw-r--r--include/asm-arm/ucontext.h79
-rw-r--r--include/asm-generic/rtc.h7
-rw-r--r--include/asm-sparc/ebus.h17
-rw-r--r--include/asm-sparc/of_device.h63
-rw-r--r--include/asm-sparc/pbm.h3
-rw-r--r--include/asm-sparc/prom.h98
-rw-r--r--include/asm-sparc/sbus.h28
-rw-r--r--include/asm-sparc64/ebus.h20
-rw-r--r--include/asm-sparc64/fhc.h7
-rw-r--r--include/asm-sparc64/floppy.h27
-rw-r--r--include/asm-sparc64/isa.h21
-rw-r--r--include/asm-sparc64/of_device.h64
-rw-r--r--include/asm-sparc64/oplib.h5
-rw-r--r--include/asm-sparc64/parport.h25
-rw-r--r--include/asm-sparc64/pbm.h15
-rw-r--r--include/asm-sparc64/pgtable.h2
-rw-r--r--include/asm-sparc64/prom.h98
-rw-r--r--include/asm-sparc64/sbus.h29
-rw-r--r--include/asm-sparc64/vdev.h5
-rw-r--r--include/linux/resume-trace.h30
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--kernel/power/Kconfig9
-rw-r--r--sound/sparc/amd7930.c138
-rw-r--r--sound/sparc/cs4231.c13
153 files changed, 7586 insertions, 3494 deletions
diff --git a/Documentation/sparc/sbus_drivers.txt b/Documentation/sparc/sbus_drivers.txt
index 876195dc2aef..4b9351624f13 100644
--- a/Documentation/sparc/sbus_drivers.txt
+++ b/Documentation/sparc/sbus_drivers.txt
@@ -25,42 +25,84 @@ the bits necessary to run your device. The most commonly
25used members of this structure, and their typical usage, 25used members of this structure, and their typical usage,
26will be detailed below. 26will be detailed below.
27 27
28 Here is how probing is performed by an SBUS driver 28 Here is a piece of skeleton code for perofming a device
29under Linux: 29probe in an SBUS driverunder Linux:
30 30
31 static void init_one_mydevice(struct sbus_dev *sdev) 31 static int __devinit mydevice_probe_one(struct sbus_dev *sdev)
32 { 32 {
33 struct mysdevice *mp = kzalloc(sizeof(*mp), GFP_KERNEL);
34
35 if (!mp)
36 return -ENODEV;
37
38 ...
39 dev_set_drvdata(&sdev->ofdev.dev, mp);
40 return 0;
33 ... 41 ...
34 } 42 }
35 43
36 static int mydevice_match(struct sbus_dev *sdev) 44 static int __devinit mydevice_probe(struct of_device *dev,
45 const struct of_device_id *match)
37 { 46 {
38 if (some_criteria(sdev)) 47 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
39 return 1; 48
40 return 0; 49 return mydevice_probe_one(sdev);
41 } 50 }
42 51
43 static void mydevice_probe(void) 52 static int __devexit mydevice_remove(struct of_device *dev)
44 { 53 {
45 struct sbus_bus *sbus; 54 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
46 struct sbus_dev *sdev; 55 struct mydevice *mp = dev_get_drvdata(&dev->dev);
47 56
48 for_each_sbus(sbus) { 57 return mydevice_remove_one(sdev, mp);
49 for_each_sbusdev(sdev, sbus) {
50 if (mydevice_match(sdev))
51 init_one_mydevice(sdev);
52 }
53 }
54 } 58 }
55 59
56 All this does is walk through all SBUS devices in the 60 static struct of_device_id mydevice_match[] = {
57system, checks each to see if it is of the type which 61 {
58your driver is written for, and if so it calls the init 62 .name = "mydevice",
59routine to attach the device and prepare to drive it. 63 },
64 {},
65 };
66
67 MODULE_DEVICE_TABLE(of, mydevice_match);
60 68
61 "init_one_mydevice" might do things like allocate software 69 static struct of_platform_driver mydevice_driver = {
62state structures, map in I/O registers, place the hardware 70 .name = "mydevice",
63into an initialized state, etc. 71 .match_table = mydevice_match,
72 .probe = mydevice_probe,
73 .remove = __devexit_p(mydevice_remove),
74 };
75
76 static int __init mydevice_init(void)
77 {
78 return of_register_driver(&mydevice_driver, &sbus_bus_type);
79 }
80
81 static void __exit mydevice_exit(void)
82 {
83 of_unregister_driver(&mydevice_driver);
84 }
85
86 module_init(mydevice_init);
87 module_exit(mydevice_exit);
88
89 The mydevice_match table is a series of entries which
90describes what SBUS devices your driver is meant for. In the
91simplest case you specify a string for the 'name' field. Every
92SBUS device with a 'name' property matching your string will
93be passed one-by-one to your .probe method.
94
95 You should store away your device private state structure
96pointer in the drvdata area so that you can retrieve it later on
97in your .remove method.
98
99 Any memory allocated, registers mapped, IRQs registered,
100etc. must be undone by your .remove method so that all resources
101of your device are relased by the time it returns.
102
103 You should _NOT_ use the for_each_sbus(), for_each_sbusdev(),
104and for_all_sbusdev() interfaces. They are deprecated, will be
105removed, and no new driver should reference them ever.
64 106
65 Mapping and Accessing I/O Registers 107 Mapping and Accessing I/O Registers
66 108
@@ -263,10 +305,3 @@ discussed above and plus it handles both PCI and SBUS boards.
263 Lance driver abuses consistent mappings for data transfer. 305 Lance driver abuses consistent mappings for data transfer.
264It is a nifty trick which we do not particularly recommend... 306It is a nifty trick which we do not particularly recommend...
265Just check it out and know that it's legal. 307Just check it out and know that it's legal.
266
267 Bad examples, do NOT use
268
269 drivers/video/cgsix.c
270 This one uses result of sbus_ioremap as if it is an address.
271This does NOT work on sparc64 and therefore is broken. We will
272convert it at a later date.
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index af9e0ae952d5..a3bae95e536c 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -273,7 +273,7 @@ ENTRY(iwmmxt_task_restore)
273 * 273 *
274 * r0 = previous task_struct pointer (must be preserved) 274 * r0 = previous task_struct pointer (must be preserved)
275 * r1 = previous thread_info pointer 275 * r1 = previous thread_info pointer
276 * r2 = next thread_info.cpu_domain pointer (must be preserved) 276 * r2 = next thread_info pointer (must be preserved)
277 * 277 *
278 * Called only from __switch_to with task preemption disabled. 278 * Called only from __switch_to with task preemption disabled.
279 * No need to care about preserving r4 and above. 279 * No need to care about preserving r4 and above.
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index f094277485c8..1ce05ec086c6 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -134,17 +134,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
134 134
135#ifdef CONFIG_IWMMXT 135#ifdef CONFIG_IWMMXT
136 136
137/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
138#define IWMMXT_STORAGE_SIZE (0x98 + 8)
139#define IWMMXT_MAGIC0 0x12ef842a
140#define IWMMXT_MAGIC1 0x1c07ca71
141
142struct iwmmxt_sigframe {
143 unsigned long magic0;
144 unsigned long magic1;
145 unsigned long storage[0x98/4];
146};
147
148static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) 137static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
149{ 138{
150 char kbuf[sizeof(*frame) + 8]; 139 char kbuf[sizeof(*frame) + 8];
@@ -152,8 +141,8 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame)
152 141
153 /* the iWMMXt context must be 64 bit aligned */ 142 /* the iWMMXt context must be 64 bit aligned */
154 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); 143 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
155 kframe->magic0 = IWMMXT_MAGIC0; 144 kframe->magic = IWMMXT_MAGIC;
156 kframe->magic1 = IWMMXT_MAGIC1; 145 kframe->size = IWMMXT_STORAGE_SIZE;
157 iwmmxt_task_copy(current_thread_info(), &kframe->storage); 146 iwmmxt_task_copy(current_thread_info(), &kframe->storage);
158 return __copy_to_user(frame, kframe, sizeof(*frame)); 147 return __copy_to_user(frame, kframe, sizeof(*frame));
159} 148}
@@ -167,8 +156,8 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
167 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); 156 kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7);
168 if (__copy_from_user(kframe, frame, sizeof(*frame))) 157 if (__copy_from_user(kframe, frame, sizeof(*frame)))
169 return -1; 158 return -1;
170 if (kframe->magic0 != IWMMXT_MAGIC0 || 159 if (kframe->magic != IWMMXT_MAGIC ||
171 kframe->magic1 != IWMMXT_MAGIC1) 160 kframe->size != IWMMXT_STORAGE_SIZE)
172 return -1; 161 return -1;
173 iwmmxt_task_restore(current_thread_info(), &kframe->storage); 162 iwmmxt_task_restore(current_thread_info(), &kframe->storage);
174 return 0; 163 return 0;
@@ -177,70 +166,61 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame)
177#endif 166#endif
178 167
179/* 168/*
180 * Auxiliary signal frame. This saves stuff like FP state.
181 * The layout of this structure is not part of the user ABI.
182 */
183struct aux_sigframe {
184#ifdef CONFIG_IWMMXT
185 struct iwmmxt_sigframe iwmmxt;
186#endif
187#ifdef CONFIG_VFP
188 union vfp_state vfp;
189#endif
190};
191
192/*
193 * Do a signal return; undo the signal stack. These are aligned to 64-bit. 169 * Do a signal return; undo the signal stack. These are aligned to 64-bit.
194 */ 170 */
195struct sigframe { 171struct sigframe {
196 struct sigcontext sc; 172 struct ucontext uc;
197 unsigned long extramask[_NSIG_WORDS-1];
198 unsigned long retcode[2]; 173 unsigned long retcode[2];
199 struct aux_sigframe aux __attribute__((aligned(8)));
200}; 174};
201 175
202struct rt_sigframe { 176struct rt_sigframe {
203 struct siginfo __user *pinfo;
204 void __user *puc;
205 struct siginfo info; 177 struct siginfo info;
206 struct ucontext uc; 178 struct sigframe sig;
207 unsigned long retcode[2];
208 struct aux_sigframe aux __attribute__((aligned(8)));
209}; 179};
210 180
211static int 181static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
212restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
213 struct aux_sigframe __user *aux)
214{ 182{
215 int err = 0; 183 struct aux_sigframe __user *aux;
184 sigset_t set;
185 int err;
186
187 err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
188 if (err == 0) {
189 sigdelsetmask(&set, ~_BLOCKABLE);
190 spin_lock_irq(&current->sighand->siglock);
191 current->blocked = set;
192 recalc_sigpending();
193 spin_unlock_irq(&current->sighand->siglock);
194 }
216 195
217 __get_user_error(regs->ARM_r0, &sc->arm_r0, err); 196 __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
218 __get_user_error(regs->ARM_r1, &sc->arm_r1, err); 197 __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
219 __get_user_error(regs->ARM_r2, &sc->arm_r2, err); 198 __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
220 __get_user_error(regs->ARM_r3, &sc->arm_r3, err); 199 __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
221 __get_user_error(regs->ARM_r4, &sc->arm_r4, err); 200 __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
222 __get_user_error(regs->ARM_r5, &sc->arm_r5, err); 201 __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
223 __get_user_error(regs->ARM_r6, &sc->arm_r6, err); 202 __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
224 __get_user_error(regs->ARM_r7, &sc->arm_r7, err); 203 __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
225 __get_user_error(regs->ARM_r8, &sc->arm_r8, err); 204 __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
226 __get_user_error(regs->ARM_r9, &sc->arm_r9, err); 205 __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
227 __get_user_error(regs->ARM_r10, &sc->arm_r10, err); 206 __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
228 __get_user_error(regs->ARM_fp, &sc->arm_fp, err); 207 __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
229 __get_user_error(regs->ARM_ip, &sc->arm_ip, err); 208 __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
230 __get_user_error(regs->ARM_sp, &sc->arm_sp, err); 209 __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
231 __get_user_error(regs->ARM_lr, &sc->arm_lr, err); 210 __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
232 __get_user_error(regs->ARM_pc, &sc->arm_pc, err); 211 __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
233 __get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); 212 __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
234 213
235 err |= !valid_user_regs(regs); 214 err |= !valid_user_regs(regs);
236 215
216 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
237#ifdef CONFIG_IWMMXT 217#ifdef CONFIG_IWMMXT
238 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) 218 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
239 err |= restore_iwmmxt_context(&aux->iwmmxt); 219 err |= restore_iwmmxt_context(&aux->iwmmxt);
240#endif 220#endif
241#ifdef CONFIG_VFP 221#ifdef CONFIG_VFP
242// if (err == 0) 222// if (err == 0)
243// err |= vfp_restore_state(&aux->vfp); 223// err |= vfp_restore_state(&sf->aux.vfp);
244#endif 224#endif
245 225
246 return err; 226 return err;
@@ -249,7 +229,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
249asmlinkage int sys_sigreturn(struct pt_regs *regs) 229asmlinkage int sys_sigreturn(struct pt_regs *regs)
250{ 230{
251 struct sigframe __user *frame; 231 struct sigframe __user *frame;
252 sigset_t set;
253 232
254 /* Always make any pending restarted system calls return -EINTR */ 233 /* Always make any pending restarted system calls return -EINTR */
255 current_thread_info()->restart_block.fn = do_no_restart_syscall; 234 current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -266,19 +245,8 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
266 245
267 if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) 246 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
268 goto badframe; 247 goto badframe;
269 if (__get_user(set.sig[0], &frame->sc.oldmask)
270 || (_NSIG_WORDS > 1
271 && __copy_from_user(&set.sig[1], &frame->extramask,
272 sizeof(frame->extramask))))
273 goto badframe;
274
275 sigdelsetmask(&set, ~_BLOCKABLE);
276 spin_lock_irq(&current->sighand->siglock);
277 current->blocked = set;
278 recalc_sigpending();
279 spin_unlock_irq(&current->sighand->siglock);
280 248
281 if (restore_sigcontext(regs, &frame->sc, &frame->aux)) 249 if (restore_sigframe(regs, frame))
282 goto badframe; 250 goto badframe;
283 251
284 /* Send SIGTRAP if we're single-stepping */ 252 /* Send SIGTRAP if we're single-stepping */
@@ -297,7 +265,6 @@ badframe:
297asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) 265asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
298{ 266{
299 struct rt_sigframe __user *frame; 267 struct rt_sigframe __user *frame;
300 sigset_t set;
301 268
302 /* Always make any pending restarted system calls return -EINTR */ 269 /* Always make any pending restarted system calls return -EINTR */
303 current_thread_info()->restart_block.fn = do_no_restart_syscall; 270 current_thread_info()->restart_block.fn = do_no_restart_syscall;
@@ -314,19 +281,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
314 281
315 if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) 282 if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
316 goto badframe; 283 goto badframe;
317 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
318 goto badframe;
319 284
320 sigdelsetmask(&set, ~_BLOCKABLE); 285 if (restore_sigframe(regs, &frame->sig))
321 spin_lock_irq(&current->sighand->siglock);
322 current->blocked = set;
323 recalc_sigpending();
324 spin_unlock_irq(&current->sighand->siglock);
325
326 if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux))
327 goto badframe; 286 goto badframe;
328 287
329 if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) 288 if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
330 goto badframe; 289 goto badframe;
331 290
332 /* Send SIGTRAP if we're single-stepping */ 291 /* Send SIGTRAP if we're single-stepping */
@@ -343,42 +302,46 @@ badframe:
343} 302}
344 303
345static int 304static int
346setup_sigcontext(struct sigcontext __user *sc, struct aux_sigframe __user *aux, 305setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set)
347 struct pt_regs *regs, unsigned long mask)
348{ 306{
307 struct aux_sigframe __user *aux;
349 int err = 0; 308 int err = 0;
350 309
351 __put_user_error(regs->ARM_r0, &sc->arm_r0, err); 310 __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err);
352 __put_user_error(regs->ARM_r1, &sc->arm_r1, err); 311 __put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err);
353 __put_user_error(regs->ARM_r2, &sc->arm_r2, err); 312 __put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err);
354 __put_user_error(regs->ARM_r3, &sc->arm_r3, err); 313 __put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err);
355 __put_user_error(regs->ARM_r4, &sc->arm_r4, err); 314 __put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err);
356 __put_user_error(regs->ARM_r5, &sc->arm_r5, err); 315 __put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err);
357 __put_user_error(regs->ARM_r6, &sc->arm_r6, err); 316 __put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err);
358 __put_user_error(regs->ARM_r7, &sc->arm_r7, err); 317 __put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err);
359 __put_user_error(regs->ARM_r8, &sc->arm_r8, err); 318 __put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err);
360 __put_user_error(regs->ARM_r9, &sc->arm_r9, err); 319 __put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err);
361 __put_user_error(regs->ARM_r10, &sc->arm_r10, err); 320 __put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err);
362 __put_user_error(regs->ARM_fp, &sc->arm_fp, err); 321 __put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err);
363 __put_user_error(regs->ARM_ip, &sc->arm_ip, err); 322 __put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err);
364 __put_user_error(regs->ARM_sp, &sc->arm_sp, err); 323 __put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err);
365 __put_user_error(regs->ARM_lr, &sc->arm_lr, err); 324 __put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err);
366 __put_user_error(regs->ARM_pc, &sc->arm_pc, err); 325 __put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err);
367 __put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); 326 __put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err);
368 327
369 __put_user_error(current->thread.trap_no, &sc->trap_no, err); 328 __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err);
370 __put_user_error(current->thread.error_code, &sc->error_code, err); 329 __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err);
371 __put_user_error(current->thread.address, &sc->fault_address, err); 330 __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err);
372 __put_user_error(mask, &sc->oldmask, err); 331 __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err);
373 332
333 err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set));
334
335 aux = (struct aux_sigframe __user *) sf->uc.uc_regspace;
374#ifdef CONFIG_IWMMXT 336#ifdef CONFIG_IWMMXT
375 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) 337 if (err == 0 && test_thread_flag(TIF_USING_IWMMXT))
376 err |= preserve_iwmmxt_context(&aux->iwmmxt); 338 err |= preserve_iwmmxt_context(&aux->iwmmxt);
377#endif 339#endif
378#ifdef CONFIG_VFP 340#ifdef CONFIG_VFP
379// if (err == 0) 341// if (err == 0)
380// err |= vfp_save_state(&aux->vfp); 342// err |= vfp_save_state(&sf->aux.vfp);
381#endif 343#endif
344 __put_user_error(0, &aux->end_magic, err);
382 345
383 return err; 346 return err;
384} 347}
@@ -487,13 +450,12 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
487 if (!frame) 450 if (!frame)
488 return 1; 451 return 1;
489 452
490 err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]); 453 /*
491 454 * Set uc.uc_flags to a value which sc.trap_no would never have.
492 if (_NSIG_WORDS > 1) { 455 */
493 err |= __copy_to_user(frame->extramask, &set->sig[1], 456 __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err);
494 sizeof(frame->extramask));
495 }
496 457
458 err |= setup_sigframe(frame, regs, set);
497 if (err == 0) 459 if (err == 0)
498 err = setup_return(regs, ka, frame->retcode, frame, usig); 460 err = setup_return(regs, ka, frame->retcode, frame, usig);
499 461
@@ -511,25 +473,20 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
511 if (!frame) 473 if (!frame)
512 return 1; 474 return 1;
513 475
514 __put_user_error(&frame->info, &frame->pinfo, err);
515 __put_user_error(&frame->uc, &frame->puc, err);
516 err |= copy_siginfo_to_user(&frame->info, info); 476 err |= copy_siginfo_to_user(&frame->info, info);
517 477
518 __put_user_error(0, &frame->uc.uc_flags, err); 478 __put_user_error(0, &frame->sig.uc.uc_flags, err);
519 __put_user_error(NULL, &frame->uc.uc_link, err); 479 __put_user_error(NULL, &frame->sig.uc.uc_link, err);
520 480
521 memset(&stack, 0, sizeof(stack)); 481 memset(&stack, 0, sizeof(stack));
522 stack.ss_sp = (void __user *)current->sas_ss_sp; 482 stack.ss_sp = (void __user *)current->sas_ss_sp;
523 stack.ss_flags = sas_ss_flags(regs->ARM_sp); 483 stack.ss_flags = sas_ss_flags(regs->ARM_sp);
524 stack.ss_size = current->sas_ss_size; 484 stack.ss_size = current->sas_ss_size;
525 err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); 485 err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack));
526
527 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux,
528 regs, set->sig[0]);
529 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
530 486
487 err |= setup_sigframe(&frame->sig, regs, set);
531 if (err == 0) 488 if (err == 0)
532 err = setup_return(regs, ka, frame->retcode, frame, usig); 489 err = setup_return(regs, ka, frame->sig.retcode, frame, usig);
533 490
534 if (err == 0) { 491 if (err == 0) {
535 /* 492 /*
@@ -538,7 +495,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
538 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06 495 * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06
539 */ 496 */
540 regs->ARM_r1 = (unsigned long)&frame->info; 497 regs->ARM_r1 = (unsigned long)&frame->info;
541 regs->ARM_r2 = (unsigned long)&frame->uc; 498 regs->ARM_r2 = (unsigned long)&frame->sig.uc;
542 } 499 }
543 500
544 return err; 501 return err;
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index 5393af989e94..05a48a21038e 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4obj-y := core.o 4obj-y := core.o clock.o
5obj-m := 5obj-m :=
6obj-n := 6obj-n :=
7obj- := 7obj- :=
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
new file mode 100644
index 000000000000..08ad782c1649
--- /dev/null
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -0,0 +1,156 @@
1/*
2 * arch/arm/mach-ep93xx/clock.c
3 * Clock control for Cirrus EP93xx chips.
4 *
5 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or (at
10 * your option) any later version.
11 */
12
13#include <linux/kernel.h>
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/string.h>
17#include <asm/div64.h>
18#include <asm/hardware.h>
19#include <asm/io.h>
20
21struct clk {
22 char *name;
23 unsigned long rate;
24 int users;
25 u32 enable_reg;
26 u32 enable_mask;
27};
28
29static struct clk clk_pll1 = {
30 .name = "pll1",
31};
32static struct clk clk_f = {
33 .name = "fclk",
34};
35static struct clk clk_h = {
36 .name = "hclk",
37};
38static struct clk clk_p = {
39 .name = "pclk",
40};
41static struct clk clk_pll2 = {
42 .name = "pll2",
43};
44static struct clk clk_usb_host = {
45 .name = "usb_host",
46 .enable_reg = EP93XX_SYSCON_CLOCK_CONTROL,
47 .enable_mask = EP93XX_SYSCON_CLOCK_USH_EN,
48};
49
50
51static struct clk *clocks[] = {
52 &clk_pll1,
53 &clk_f,
54 &clk_h,
55 &clk_p,
56 &clk_pll2,
57 &clk_usb_host,
58};
59
60struct clk *clk_get(struct device *dev, const char *id)
61{
62 int i;
63
64 for (i = 0; i < ARRAY_SIZE(clocks); i++) {
65 if (!strcmp(clocks[i]->name, id))
66 return clocks[i];
67 }
68
69 return ERR_PTR(-ENOENT);
70}
71
72int clk_enable(struct clk *clk)
73{
74 if (!clk->users++ && clk->enable_reg) {
75 u32 value;
76
77 value = __raw_readl(clk->enable_reg);
78 __raw_writel(value | clk->enable_mask, clk->enable_reg);
79 }
80
81 return 0;
82}
83
84void clk_disable(struct clk *clk)
85{
86 if (!--clk->users && clk->enable_reg) {
87 u32 value;
88
89 value = __raw_readl(clk->enable_reg);
90 __raw_writel(value & ~clk->enable_mask, clk->enable_reg);
91 }
92}
93
94unsigned long clk_get_rate(struct clk *clk)
95{
96 return clk->rate;
97}
98
99void clk_put(struct clk *clk)
100{
101}
102
103
104
105static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
106static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
107static char pclk_divisors[] = { 1, 2, 4, 8 };
108
109/*
110 * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS
111 */
112static unsigned long calc_pll_rate(u32 config_word)
113{
114 unsigned long long rate;
115 int i;
116
117 rate = 14745600;
118 rate *= ((config_word >> 11) & 0x1f) + 1; /* X1FBD */
119 rate *= ((config_word >> 5) & 0x3f) + 1; /* X2FBD */
120 do_div(rate, (config_word & 0x1f) + 1); /* X2IPD */
121 for (i = 0; i < ((config_word >> 16) & 3); i++) /* PS */
122 rate >>= 1;
123
124 return (unsigned long)rate;
125}
126
127void ep93xx_clock_init(void)
128{
129 u32 value;
130
131 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET1);
132 if (!(value & 0x00800000)) { /* PLL1 bypassed? */
133 clk_pll1.rate = 14745600;
134 } else {
135 clk_pll1.rate = calc_pll_rate(value);
136 }
137 clk_f.rate = clk_pll1.rate / fclk_divisors[(value >> 25) & 0x7];
138 clk_h.rate = clk_pll1.rate / hclk_divisors[(value >> 20) & 0x7];
139 clk_p.rate = clk_h.rate / pclk_divisors[(value >> 18) & 0x3];
140
141 value = __raw_readl(EP93XX_SYSCON_CLOCK_SET2);
142 if (!(value & 0x00080000)) { /* PLL2 bypassed? */
143 clk_pll2.rate = 14745600;
144 } else if (value & 0x00040000) { /* PLL2 enabled? */
145 clk_pll2.rate = calc_pll_rate(value);
146 } else {
147 clk_pll2.rate = 0;
148 }
149 clk_usb_host.rate = clk_pll2.rate / (((value >> 28) & 0xf) + 1);
150
151 printk(KERN_INFO "ep93xx: PLL1 running at %ld MHz, PLL2 at %ld MHz\n",
152 clk_pll1.rate / 1000000, clk_pll2.rate / 1000000);
153 printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
154 clk_f.rate / 1000000, clk_h.rate / 1000000,
155 clk_p.rate / 1000000);
156}
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index bf6bd71bdd08..1fe73c0a9d01 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -433,10 +433,37 @@ static struct platform_device ep93xx_rtc_device = {
433}; 433};
434 434
435 435
436static struct resource ep93xx_ohci_resources[] = {
437 [0] = {
438 .start = EP93XX_USB_PHYS_BASE,
439 .end = EP93XX_USB_PHYS_BASE + 0x0fff,
440 .flags = IORESOURCE_MEM,
441 },
442 [1] = {
443 .start = IRQ_EP93XX_USB,
444 .end = IRQ_EP93XX_USB,
445 .flags = IORESOURCE_IRQ,
446 },
447};
448
449static struct platform_device ep93xx_ohci_device = {
450 .name = "ep93xx-ohci",
451 .id = -1,
452 .dev = {
453 .dma_mask = (void *)0xffffffff,
454 .coherent_dma_mask = 0xffffffff,
455 },
456 .num_resources = ARRAY_SIZE(ep93xx_ohci_resources),
457 .resource = ep93xx_ohci_resources,
458};
459
460
436void __init ep93xx_init_devices(void) 461void __init ep93xx_init_devices(void)
437{ 462{
438 unsigned int v; 463 unsigned int v;
439 464
465 ep93xx_clock_init();
466
440 /* 467 /*
441 * Disallow access to MaverickCrunch initially. 468 * Disallow access to MaverickCrunch initially.
442 */ 469 */
@@ -450,4 +477,5 @@ void __init ep93xx_init_devices(void)
450 amba_device_register(&uart3_device, &iomem_resource); 477 amba_device_register(&uart3_device, &iomem_resource);
451 478
452 platform_device_register(&ep93xx_rtc_device); 479 platform_device_register(&ep93xx_rtc_device);
480 platform_device_register(&ep93xx_ohci_device);
453} 481}
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 186f632035b8..ebe4391dd7f9 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -302,6 +302,7 @@ void gpio_line_config(int line, int direction)
302 } 302 }
303 local_irq_restore(flags); 303 local_irq_restore(flags);
304} 304}
305EXPORT_SYMBOL(gpio_line_config);
305 306
306 307
307/************************************************************************* 308/*************************************************************************
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index 7b786d725636..f5d9cd498a5f 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -81,6 +81,12 @@ config SMDK2440_CPU2442
81 depends on ARCH_S3C2440 81 depends on ARCH_S3C2440
82 select CPU_S3C2442 82 select CPU_S3C2442
83 83
84config MACH_SMDK2413
85 bool "SMDK2413"
86 select CPU_S3C2412
87 select MACH_SMDK
88 help
89 Say Y here if you are using an SMDK2413
84 90
85config MACH_VR1000 91config MACH_VR1000
86 bool "Thorcom VR1000" 92 bool "Thorcom VR1000"
@@ -127,6 +133,20 @@ config CPU_S3C2410
127 Support for S3C2410 and S3C2410A family from the S3C24XX line 133 Support for S3C2410 and S3C2410A family from the S3C24XX line
128 of Samsung Mobile CPUs. 134 of Samsung Mobile CPUs.
129 135
136# internal node to signify if we are only dealing with an S3C2412
137
138config CPU_S3C2412_ONLY
139 bool
140 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
141 !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
142 default y if CPU_S3C2412
143
144config CPU_S3C2412
145 bool
146 depends on ARCH_S3C2410
147 help
148 Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
149
130config CPU_S3C244X 150config CPU_S3C244X
131 bool 151 bool
132 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442) 152 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 372dbcea1434..0c7938645df6 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -24,6 +24,11 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o
24obj-$(CONFIG_PM) += pm.o sleep.o 24obj-$(CONFIG_PM) += pm.o sleep.o
25obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o 25obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
26 26
27# S3C2412 support
28obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
29obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
30
31#
27# S3C244X support 32# S3C244X support
28 33
29obj-$(CONFIG_CPU_S3C244X) += s3c244x.o 34obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
@@ -57,6 +62,7 @@ obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
57obj-$(CONFIG_ARCH_H1940) += mach-h1940.o 62obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
58obj-$(CONFIG_MACH_N30) += mach-n30.o 63obj-$(CONFIG_MACH_N30) += mach-n30.o
59obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o 64obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
65obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
60obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o 66obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
61obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o 67obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
62obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o 68obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index c5c93c333ac6..e13fb6778890 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -213,7 +213,7 @@ EXPORT_SYMBOL(clk_set_parent);
213 213
214/* base clocks */ 214/* base clocks */
215 215
216static struct clk clk_xtal = { 216struct clk clk_xtal = {
217 .name = "xtal", 217 .name = "xtal",
218 .id = -1, 218 .id = -1,
219 .rate = 0, 219 .rate = 0,
@@ -221,6 +221,11 @@ static struct clk clk_xtal = {
221 .ctrlbit = 0, 221 .ctrlbit = 0,
222}; 222};
223 223
224struct clk clk_mpll = {
225 .name = "mpll",
226 .id = -1,
227};
228
224struct clk clk_upll = { 229struct clk clk_upll = {
225 .name = "upll", 230 .name = "upll",
226 .id = -1, 231 .id = -1,
@@ -232,7 +237,7 @@ struct clk clk_f = {
232 .name = "fclk", 237 .name = "fclk",
233 .id = -1, 238 .id = -1,
234 .rate = 0, 239 .rate = 0,
235 .parent = NULL, 240 .parent = &clk_mpll,
236 .ctrlbit = 0, 241 .ctrlbit = 0,
237}; 242};
238 243
@@ -263,14 +268,14 @@ struct clk clk_usb_bus = {
263 268
264static int s3c24xx_dclk_enable(struct clk *clk, int enable) 269static int s3c24xx_dclk_enable(struct clk *clk, int enable)
265{ 270{
266 unsigned long dclkcon = __raw_readl(S3C2410_DCLKCON); 271 unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
267 272
268 if (enable) 273 if (enable)
269 dclkcon |= clk->ctrlbit; 274 dclkcon |= clk->ctrlbit;
270 else 275 else
271 dclkcon &= ~clk->ctrlbit; 276 dclkcon &= ~clk->ctrlbit;
272 277
273 __raw_writel(dclkcon, S3C2410_DCLKCON); 278 __raw_writel(dclkcon, S3C24XX_DCLKCON);
274 279
275 return 0; 280 return 0;
276} 281}
@@ -289,7 +294,7 @@ static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
289 294
290 clk->parent = parent; 295 clk->parent = parent;
291 296
292 dclkcon = __raw_readl(S3C2410_DCLKCON); 297 dclkcon = __raw_readl(S3C24XX_DCLKCON);
293 298
294 if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) { 299 if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
295 if (uclk) 300 if (uclk)
@@ -303,7 +308,7 @@ static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
303 dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK; 308 dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
304 } 309 }
305 310
306 __raw_writel(dclkcon, S3C2410_DCLKCON); 311 __raw_writel(dclkcon, S3C24XX_DCLKCON);
307 312
308 return 0; 313 return 0;
309} 314}
@@ -413,6 +418,7 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
413 clk_xtal.rate = xtal; 418 clk_xtal.rate = xtal;
414 clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal); 419 clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
415 420
421 clk_mpll.rate = fclk;
416 clk_h.rate = hclk; 422 clk_h.rate = hclk;
417 clk_p.rate = pclk; 423 clk_p.rate = pclk;
418 clk_f.rate = fclk; 424 clk_f.rate = fclk;
@@ -424,6 +430,9 @@ int __init s3c24xx_setup_clocks(unsigned long xtal,
424 if (s3c24xx_register_clock(&clk_xtal) < 0) 430 if (s3c24xx_register_clock(&clk_xtal) < 0)
425 printk(KERN_ERR "failed to register master xtal\n"); 431 printk(KERN_ERR "failed to register master xtal\n");
426 432
433 if (s3c24xx_register_clock(&clk_mpll) < 0)
434 printk(KERN_ERR "failed to register mpll clock\n");
435
427 if (s3c24xx_register_clock(&clk_upll) < 0) 436 if (s3c24xx_register_clock(&clk_upll) < 0)
428 printk(KERN_ERR "failed to register upll clock\n"); 437 printk(KERN_ERR "failed to register upll clock\n");
429 438
diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h
index 9456c81eb5d3..7f0ea03e1d49 100644
--- a/arch/arm/mach-s3c2410/clock.h
+++ b/arch/arm/mach-s3c2410/clock.h
@@ -42,7 +42,9 @@ extern struct clk clk_usb_bus;
42extern struct clk clk_f; 42extern struct clk clk_f;
43extern struct clk clk_h; 43extern struct clk clk_h;
44extern struct clk clk_p; 44extern struct clk clk_p;
45extern struct clk clk_mpll;
45extern struct clk clk_upll; 46extern struct clk clk_upll;
47extern struct clk clk_xtal;
46 48
47/* exports for arch/arm/mach-s3c2410 49/* exports for arch/arm/mach-s3c2410
48 * 50 *
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c
index 52842e6e86e6..1c3c6adae6c4 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/mach-s3c2410/cpu.c
@@ -44,6 +44,7 @@
44#include "clock.h" 44#include "clock.h"
45#include "s3c2400.h" 45#include "s3c2400.h"
46#include "s3c2410.h" 46#include "s3c2410.h"
47#include "s3c2412.h"
47#include "s3c244x.h" 48#include "s3c244x.h"
48#include "s3c2440.h" 49#include "s3c2440.h"
49#include "s3c2442.h" 50#include "s3c2442.h"
@@ -62,6 +63,7 @@ struct cpu_table {
62 63
63static const char name_s3c2400[] = "S3C2400"; 64static const char name_s3c2400[] = "S3C2400";
64static const char name_s3c2410[] = "S3C2410"; 65static const char name_s3c2410[] = "S3C2410";
66static const char name_s3c2412[] = "S3C2412";
65static const char name_s3c2440[] = "S3C2440"; 67static const char name_s3c2440[] = "S3C2440";
66static const char name_s3c2442[] = "S3C2442"; 68static const char name_s3c2442[] = "S3C2442";
67static const char name_s3c2410a[] = "S3C2410A"; 69static const char name_s3c2410a[] = "S3C2410A";
@@ -114,6 +116,15 @@ static struct cpu_table cpu_ids[] __initdata = {
114 .name = name_s3c2442 116 .name = name_s3c2442
115 }, 117 },
116 { 118 {
119 .idcode = 0x32412001,
120 .idmask = 0xffffffff,
121 .map_io = s3c2412_map_io,
122 .init_clocks = s3c2412_init_clocks,
123 .init_uarts = s3c2412_init_uarts,
124 .init = s3c2412_init,
125 .name = name_s3c2412,
126 },
127 {
117 .idcode = 0x0, /* S3C2400 doesn't have an idcode */ 128 .idcode = 0x0, /* S3C2400 doesn't have an idcode */
118 .idmask = 0xffffffff, 129 .idmask = 0xffffffff,
119 .map_io = s3c2400_map_io, 130 .map_io = s3c2400_map_io,
@@ -171,6 +182,24 @@ void s3c24xx_set_board(struct s3c24xx_board *b)
171 182
172static struct cpu_table *cpu; 183static struct cpu_table *cpu;
173 184
185static unsigned long s3c24xx_read_idcode_v5(void)
186{
187#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
188 return __raw_readl(S3C2412_GSTATUS1);
189#else
190 return 1UL; /* don't look like an 2400 */
191#endif
192}
193
194static unsigned long s3c24xx_read_idcode_v4(void)
195{
196#ifndef CONFIG_CPU_S3C2400
197 return __raw_readl(S3C2410_GSTATUS1);
198#else
199 return 0UL;
200#endif
201}
202
174void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) 203void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
175{ 204{
176 unsigned long idcode = 0x0; 205 unsigned long idcode = 0x0;
@@ -178,9 +207,11 @@ void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
178 /* initialise the io descriptors we need for initialisation */ 207 /* initialise the io descriptors we need for initialisation */
179 iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); 208 iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
180 209
181#ifndef CONFIG_CPU_S3C2400 210 if (cpu_architecture() >= CPU_ARCH_ARMv5) {
182 idcode = __raw_readl(S3C2410_GSTATUS1); 211 idcode = s3c24xx_read_idcode_v5();
183#endif 212 } else {
213 idcode = s3c24xx_read_idcode_v4();
214 }
184 215
185 cpu = s3c_lookup_cpu(idcode); 216 cpu = s3c_lookup_cpu(idcode);
186 217
diff --git a/arch/arm/mach-s3c2410/cpu.h b/arch/arm/mach-s3c2410/cpu.h
index 21c62dc29bb2..b0ed9d2d141b 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/arch/arm/mach-s3c2410/cpu.h
@@ -74,5 +74,6 @@ extern struct sys_timer s3c24xx_timer;
74/* system device classes */ 74/* system device classes */
75 75
76extern struct sysdev_class s3c2410_sysclass; 76extern struct sysdev_class s3c2410_sysclass;
77extern struct sysdev_class s3c2412_sysclass;
77extern struct sysdev_class s3c2440_sysclass; 78extern struct sysdev_class s3c2440_sysclass;
78extern struct sysdev_class s3c2442_sysclass; 79extern struct sysdev_class s3c2442_sysclass;
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 66d8c068e940..6822dc7f7799 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -191,13 +191,9 @@ static struct irqchip s3c_irq_chip = {
191 .ack = s3c_irq_ack, 191 .ack = s3c_irq_ack,
192 .mask = s3c_irq_mask, 192 .mask = s3c_irq_mask,
193 .unmask = s3c_irq_unmask, 193 .unmask = s3c_irq_unmask,
194 .set_wake = s3c_irq_wake 194 .set_wake = s3c_irq_wake
195}; 195};
196 196
197/* S3C2410_EINTMASK
198 * S3C2410_EINTPEND
199 */
200
201static void 197static void
202s3c_irqext_mask(unsigned int irqno) 198s3c_irqext_mask(unsigned int irqno)
203{ 199{
@@ -205,9 +201,9 @@ s3c_irqext_mask(unsigned int irqno)
205 201
206 irqno -= EXTINT_OFF; 202 irqno -= EXTINT_OFF;
207 203
208 mask = __raw_readl(S3C2410_EINTMASK); 204 mask = __raw_readl(S3C24XX_EINTMASK);
209 mask |= ( 1UL << irqno); 205 mask |= ( 1UL << irqno);
210 __raw_writel(mask, S3C2410_EINTMASK); 206 __raw_writel(mask, S3C24XX_EINTMASK);
211 207
212 if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) { 208 if (irqno <= (IRQ_EINT7 - EXTINT_OFF)) {
213 /* check to see if all need masking */ 209 /* check to see if all need masking */
@@ -232,11 +228,11 @@ s3c_irqext_ack(unsigned int irqno)
232 bit = 1UL << (irqno - EXTINT_OFF); 228 bit = 1UL << (irqno - EXTINT_OFF);
233 229
234 230
235 mask = __raw_readl(S3C2410_EINTMASK); 231 mask = __raw_readl(S3C24XX_EINTMASK);
236 232
237 __raw_writel(bit, S3C2410_EINTPEND); 233 __raw_writel(bit, S3C24XX_EINTPEND);
238 234
239 req = __raw_readl(S3C2410_EINTPEND); 235 req = __raw_readl(S3C24XX_EINTPEND);
240 req &= ~mask; 236 req &= ~mask;
241 237
242 /* not sure if we should be acking the parent irq... */ 238 /* not sure if we should be acking the parent irq... */
@@ -257,9 +253,9 @@ s3c_irqext_unmask(unsigned int irqno)
257 253
258 irqno -= EXTINT_OFF; 254 irqno -= EXTINT_OFF;
259 255
260 mask = __raw_readl(S3C2410_EINTMASK); 256 mask = __raw_readl(S3C24XX_EINTMASK);
261 mask &= ~( 1UL << irqno); 257 mask &= ~( 1UL << irqno);
262 __raw_writel(mask, S3C2410_EINTMASK); 258 __raw_writel(mask, S3C24XX_EINTMASK);
263 259
264 s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23); 260 s3c_irq_unmask((irqno <= (IRQ_EINT7 - EXTINT_OFF)) ? IRQ_EINT4t7 : IRQ_EINT8t23);
265} 261}
@@ -275,28 +271,28 @@ s3c_irqext_type(unsigned int irq, unsigned int type)
275 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3)) 271 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
276 { 272 {
277 gpcon_reg = S3C2410_GPFCON; 273 gpcon_reg = S3C2410_GPFCON;
278 extint_reg = S3C2410_EXTINT0; 274 extint_reg = S3C24XX_EXTINT0;
279 gpcon_offset = (irq - IRQ_EINT0) * 2; 275 gpcon_offset = (irq - IRQ_EINT0) * 2;
280 extint_offset = (irq - IRQ_EINT0) * 4; 276 extint_offset = (irq - IRQ_EINT0) * 4;
281 } 277 }
282 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7)) 278 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
283 { 279 {
284 gpcon_reg = S3C2410_GPFCON; 280 gpcon_reg = S3C2410_GPFCON;
285 extint_reg = S3C2410_EXTINT0; 281 extint_reg = S3C24XX_EXTINT0;
286 gpcon_offset = (irq - (EXTINT_OFF)) * 2; 282 gpcon_offset = (irq - (EXTINT_OFF)) * 2;
287 extint_offset = (irq - (EXTINT_OFF)) * 4; 283 extint_offset = (irq - (EXTINT_OFF)) * 4;
288 } 284 }
289 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15)) 285 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
290 { 286 {
291 gpcon_reg = S3C2410_GPGCON; 287 gpcon_reg = S3C2410_GPGCON;
292 extint_reg = S3C2410_EXTINT1; 288 extint_reg = S3C24XX_EXTINT1;
293 gpcon_offset = (irq - IRQ_EINT8) * 2; 289 gpcon_offset = (irq - IRQ_EINT8) * 2;
294 extint_offset = (irq - IRQ_EINT8) * 4; 290 extint_offset = (irq - IRQ_EINT8) * 4;
295 } 291 }
296 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23)) 292 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
297 { 293 {
298 gpcon_reg = S3C2410_GPGCON; 294 gpcon_reg = S3C2410_GPGCON;
299 extint_reg = S3C2410_EXTINT2; 295 extint_reg = S3C24XX_EXTINT2;
300 gpcon_offset = (irq - IRQ_EINT8) * 2; 296 gpcon_offset = (irq - IRQ_EINT8) * 2;
301 extint_offset = (irq - IRQ_EINT16) * 4; 297 extint_offset = (irq - IRQ_EINT16) * 4;
302 } else 298 } else
@@ -572,6 +568,23 @@ s3c_irq_demux_uart2(unsigned int irq,
572 s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs); 568 s3c_irq_demux_uart(IRQ_S3CUART_RX2, regs);
573} 569}
574 570
571static void
572s3c_irq_demux_extint(unsigned int irq,
573 struct irqdesc *desc,
574 struct pt_regs *regs)
575{
576 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
577 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
578
579 eintpnd &= ~eintmsk;
580
581 if (eintpnd) {
582 irq = fls(eintpnd);
583 irq += (IRQ_EINT4 - (4 + 1));
584
585 desc_handle_irq(irq, irq_desc + irq, regs);
586 }
587}
575 588
576/* s3c24xx_init_irq 589/* s3c24xx_init_irq
577 * 590 *
@@ -591,12 +604,12 @@ void __init s3c24xx_init_irq(void)
591 604
592 last = 0; 605 last = 0;
593 for (i = 0; i < 4; i++) { 606 for (i = 0; i < 4; i++) {
594 pend = __raw_readl(S3C2410_EINTPEND); 607 pend = __raw_readl(S3C24XX_EINTPEND);
595 608
596 if (pend == 0 || pend == last) 609 if (pend == 0 || pend == last)
597 break; 610 break;
598 611
599 __raw_writel(pend, S3C2410_EINTPEND); 612 __raw_writel(pend, S3C24XX_EINTPEND);
600 printk("irq: clearing pending ext status %08x\n", (int)pend); 613 printk("irq: clearing pending ext status %08x\n", (int)pend);
601 last = pend; 614 last = pend;
602 } 615 }
@@ -630,12 +643,14 @@ void __init s3c24xx_init_irq(void)
630 643
631 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n"); 644 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
632 645
633 for (irqno = IRQ_BATT_FLT; irqno <= IRQ_ADCPARENT; irqno++) { 646 for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
634 /* set all the s3c2410 internal irqs */ 647 /* set all the s3c2410 internal irqs */
635 648
636 switch (irqno) { 649 switch (irqno) {
637 /* deal with the special IRQs (cascaded) */ 650 /* deal with the special IRQs (cascaded) */
638 651
652 case IRQ_EINT4t7:
653 case IRQ_EINT8t23:
639 case IRQ_UART0: 654 case IRQ_UART0:
640 case IRQ_UART1: 655 case IRQ_UART1:
641 case IRQ_UART2: 656 case IRQ_UART2:
@@ -659,12 +674,14 @@ void __init s3c24xx_init_irq(void)
659 674
660 /* setup the cascade irq handlers */ 675 /* setup the cascade irq handlers */
661 676
677 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint);
678 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint);
679
662 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0); 680 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
663 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1); 681 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
664 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2); 682 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
665 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc); 683 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
666 684
667
668 /* external interrupts */ 685 /* external interrupts */
669 686
670 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) { 687 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
diff --git a/arch/arm/mach-s3c2410/mach-smdk2413.c b/arch/arm/mach-s3c2410/mach-smdk2413.c
new file mode 100644
index 000000000000..b7ef7d3c54a9
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-smdk2413.c
@@ -0,0 +1,126 @@
1/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Thanks to Dimity Andric (TomTom) and Steven Ryu (Samsung) for the
7 * loans of SMDK2413 to work with.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/timer.h>
19#include <linux/init.h>
20#include <linux/platform_device.h>
21
22#include <asm/mach/arch.h>
23#include <asm/mach/map.h>
24#include <asm/mach/irq.h>
25
26#include <asm/hardware.h>
27#include <asm/hardware/iomd.h>
28#include <asm/setup.h>
29#include <asm/io.h>
30#include <asm/irq.h>
31#include <asm/mach-types.h>
32
33//#include <asm/debug-ll.h>
34#include <asm/arch/regs-serial.h>
35#include <asm/arch/regs-gpio.h>
36#include <asm/arch/regs-lcd.h>
37
38#include <asm/arch/idle.h>
39#include <asm/arch/fb.h>
40
41#include "s3c2410.h"
42#include "s3c2412.h"
43#include "clock.h"
44#include "devs.h"
45#include "cpu.h"
46
47#include "common-smdk.h"
48
49static struct map_desc smdk2413_iodesc[] __initdata = {
50};
51
52static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
53 [0] = {
54 .hwport = 0,
55 .flags = 0,
56 .ucon = 0x3c5,
57 .ulcon = 0x03,
58 .ufcon = 0x51,
59 },
60 [1] = {
61 .hwport = 1,
62 .flags = 0,
63 .ucon = 0x3c5,
64 .ulcon = 0x03,
65 .ufcon = 0x51,
66 },
67 /* IR port */
68 [2] = {
69 .hwport = 2,
70 .flags = 0,
71 .ucon = 0x3c5,
72 .ulcon = 0x43,
73 .ufcon = 0x51,
74 }
75};
76
77static struct platform_device *smdk2413_devices[] __initdata = {
78 &s3c_device_usb,
79 //&s3c_device_lcd,
80 &s3c_device_wdt,
81 &s3c_device_i2c,
82 &s3c_device_iis,
83};
84
85static struct s3c24xx_board smdk2413_board __initdata = {
86 .devices = smdk2413_devices,
87 .devices_count = ARRAY_SIZE(smdk2413_devices)
88};
89
90static void __init smdk2413_fixup(struct machine_desc *desc,
91 struct tag *tags, char **cmdline,
92 struct meminfo *mi)
93{
94 if (tags != phys_to_virt(S3C2410_SDRAM_PA + 0x100)) {
95 mi->nr_banks=1;
96 mi->bank[0].start = 0x30000000;
97 mi->bank[0].size = SZ_64M;
98 mi->bank[0].node = 0;
99 }
100}
101
102static void __init smdk2413_map_io(void)
103{
104 s3c24xx_init_io(smdk2413_iodesc, ARRAY_SIZE(smdk2413_iodesc));
105 s3c24xx_init_clocks(12000000);
106 s3c24xx_init_uarts(smdk2413_uartcfgs, ARRAY_SIZE(smdk2413_uartcfgs));
107 s3c24xx_set_board(&smdk2413_board);
108}
109
110static void __init smdk2413_machine_init(void)
111{
112 smdk_machine_init();
113}
114
115MACHINE_START(S3C2413, "SMDK2413")
116 /* Maintainer: Ben Dooks <ben@fluff.org> */
117 .phys_io = S3C2410_PA_UART,
118 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
119 .boot_params = S3C2410_SDRAM_PA + 0x100,
120
121 .fixup = smdk2413_fixup,
122 .init_irq = s3c24xx_init_irq,
123 .map_io = smdk2413_map_io,
124 .init_machine = smdk2413_machine_init,
125 .timer = &s3c24xx_timer,
126MACHINE_END
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c
index 4c7ccef6c207..7b244566a436 100644
--- a/arch/arm/mach-s3c2410/pm-simtec.c
+++ b/arch/arm/mach-s3c2410/pm-simtec.c
@@ -48,7 +48,8 @@ static __init int pm_simtec_init(void)
48 48
49 /* check which machine we are running on */ 49 /* check which machine we are running on */
50 50
51 if (!machine_is_bast() && !machine_is_vr1000() && !machine_is_anubis()) 51 if (!machine_is_bast() && !machine_is_vr1000() &&
52 !machine_is_anubis() && !machine_is_osiris())
52 return 0; 53 return 0;
53 54
54 printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); 55 printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n");
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
index fd17c60e1132..99718663318e 100644
--- a/arch/arm/mach-s3c2410/s3c2410-clock.c
+++ b/arch/arm/mach-s3c2410/s3c2410-clock.c
@@ -182,7 +182,15 @@ static struct clk init_clocks[] = {
182 .id = -1, 182 .id = -1,
183 .parent = &clk_p, 183 .parent = &clk_p,
184 .ctrlbit = 0, 184 .ctrlbit = 0,
185 } 185 }, {
186 .name = "usb-bus-host",
187 .id = -1,
188 .parent = &clk_usb_bus,
189 }, {
190 .name = "usb-bus-gadget",
191 .id = -1,
192 .parent = &clk_usb_bus,
193 },
186}; 194};
187 195
188/* s3c2410_baseclk_add() 196/* s3c2410_baseclk_add()
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
index d5e1caea1d23..471a71490010 100644
--- a/arch/arm/mach-s3c2410/s3c2410-gpio.c
+++ b/arch/arm/mach-s3c2410/s3c2410-gpio.c
@@ -18,9 +18,6 @@
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Changelog
23 * 15-Jan-2006 LCVR Splitted from gpio.c
24 */ 21 */
25 22
26#include <linux/kernel.h> 23#include <linux/kernel.h>
@@ -38,7 +35,7 @@
38int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, 35int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
39 unsigned int config) 36 unsigned int config)
40{ 37{
41 void __iomem *reg = S3C2410_EINFLT0; 38 void __iomem *reg = S3C24XX_EINFLT0;
42 unsigned long flags; 39 unsigned long flags;
43 unsigned long val; 40 unsigned long val;
44 41
@@ -47,7 +44,7 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
47 44
48 config &= 0xff; 45 config &= 0xff;
49 46
50 pin -= S3C2410_GPG8_EINT16; 47 pin -= S3C2410_GPG8;
51 reg += pin & ~3; 48 reg += pin & ~3;
52 49
53 local_irq_save(flags); 50 local_irq_save(flags);
@@ -61,10 +58,10 @@ int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
61 58
62 /* update filter enable */ 59 /* update filter enable */
63 60
64 val = __raw_readl(S3C2410_EXTINT2); 61 val = __raw_readl(S3C24XX_EXTINT2);
65 val &= ~(1 << ((pin * 4) + 3)); 62 val &= ~(1 << ((pin * 4) + 3));
66 val |= on << ((pin * 4) + 3); 63 val |= on << ((pin * 4) + 3);
67 __raw_writel(val, S3C2410_EXTINT2); 64 __raw_writel(val, S3C24XX_EXTINT2);
68 65
69 local_irq_restore(flags); 66 local_irq_restore(flags);
70 67
@@ -75,7 +72,7 @@ EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
75 72
76int s3c2410_gpio_getirq(unsigned int pin) 73int s3c2410_gpio_getirq(unsigned int pin)
77{ 74{
78 if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23) 75 if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
79 return -1; /* not valid interrupts */ 76 return -1; /* not valid interrupts */
80 77
81 if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) 78 if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
diff --git a/arch/arm/mach-s3c2410/s3c2412-clock.c b/arch/arm/mach-s3c2410/s3c2412-clock.c
new file mode 100644
index 000000000000..c95ed3e18580
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412-clock.c
@@ -0,0 +1,711 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2412,S3C2413 Clock control support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/list.h>
27#include <linux/errno.h>
28#include <linux/err.h>
29#include <linux/sysdev.h>
30#include <linux/clk.h>
31#include <linux/mutex.h>
32#include <linux/delay.h>
33
34#include <asm/hardware.h>
35#include <asm/io.h>
36
37#include <asm/arch/regs-clock.h>
38#include <asm/arch/regs-gpio.h>
39
40#include "clock.h"
41#include "cpu.h"
42
43/* We currently have to assume that the system is running
44 * from the XTPll input, and that all ***REFCLKs are being
45 * fed from it, as we cannot read the state of OM[4] from
46 * software.
47 *
48 * It would be possible for each board initialisation to
49 * set the correct muxing at initialisation
50*/
51
52int s3c2412_clkcon_enable(struct clk *clk, int enable)
53{
54 unsigned int clocks = clk->ctrlbit;
55 unsigned long clkcon;
56
57 clkcon = __raw_readl(S3C2410_CLKCON);
58
59 if (enable)
60 clkcon |= clocks;
61 else
62 clkcon &= ~clocks;
63
64 __raw_writel(clkcon, S3C2410_CLKCON);
65
66 return 0;
67}
68
69static int s3c2412_upll_enable(struct clk *clk, int enable)
70{
71 unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
72 unsigned long orig = upllcon;
73
74 if (!enable)
75 upllcon |= S3C2412_PLLCON_OFF;
76 else
77 upllcon &= ~S3C2412_PLLCON_OFF;
78
79 __raw_writel(upllcon, S3C2410_UPLLCON);
80
81 /* allow ~150uS for the PLL to settle and lock */
82
83 if (enable && (orig & S3C2412_PLLCON_OFF))
84 udelay(150);
85
86 return 0;
87}
88
89/* clock selections */
90
91/* CPU EXTCLK input */
92static struct clk clk_ext = {
93 .name = "extclk",
94 .id = -1,
95};
96
97static struct clk clk_erefclk = {
98 .name = "erefclk",
99 .id = -1,
100};
101
102static struct clk clk_urefclk = {
103 .name = "urefclk",
104 .id = -1,
105};
106
107static int s3c2412_setparent_usysclk(struct clk *clk, struct clk *parent)
108{
109 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
110
111 if (parent == &clk_urefclk)
112 clksrc &= ~S3C2412_CLKSRC_USYSCLK_UPLL;
113 else if (parent == &clk_upll)
114 clksrc |= S3C2412_CLKSRC_USYSCLK_UPLL;
115 else
116 return -EINVAL;
117
118 clk->parent = parent;
119
120 __raw_writel(clksrc, S3C2412_CLKSRC);
121 return 0;
122}
123
124static struct clk clk_usysclk = {
125 .name = "usysclk",
126 .id = -1,
127 .parent = &clk_xtal,
128 .set_parent = s3c2412_setparent_usysclk,
129};
130
131static struct clk clk_mrefclk = {
132 .name = "mrefclk",
133 .parent = &clk_xtal,
134 .id = -1,
135};
136
137static struct clk clk_mdivclk = {
138 .name = "mdivclk",
139 .parent = &clk_xtal,
140 .id = -1,
141};
142
143static int s3c2412_setparent_usbsrc(struct clk *clk, struct clk *parent)
144{
145 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
146
147 if (parent == &clk_usysclk)
148 clksrc &= ~S3C2412_CLKSRC_USBCLK_HCLK;
149 else if (parent == &clk_h)
150 clksrc |= S3C2412_CLKSRC_USBCLK_HCLK;
151 else
152 return -EINVAL;
153
154 clk->parent = parent;
155
156 __raw_writel(clksrc, S3C2412_CLKSRC);
157 return 0;
158}
159
160static unsigned long s3c2412_roundrate_usbsrc(struct clk *clk,
161 unsigned long rate)
162{
163 unsigned long parent_rate = clk_get_rate(clk->parent);
164 int div;
165
166 if (rate > parent_rate)
167 return parent_rate;
168
169 div = parent_rate / rate;
170 if (div > 2)
171 div = 2;
172
173 return parent_rate / div;
174}
175
176static unsigned long s3c2412_getrate_usbsrc(struct clk *clk)
177{
178 unsigned long parent_rate = clk_get_rate(clk->parent);
179 unsigned long div = __raw_readl(S3C2410_CLKDIVN);
180
181 return parent_rate / ((div & S3C2412_CLKDIVN_USB48DIV) ? 2 : 1);
182}
183
184static int s3c2412_setrate_usbsrc(struct clk *clk, unsigned long rate)
185{
186 unsigned long parent_rate = clk_get_rate(clk->parent);
187 unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
188
189 rate = s3c2412_roundrate_usbsrc(clk, rate);
190
191 if ((parent_rate / rate) == 2)
192 clkdivn |= S3C2412_CLKDIVN_USB48DIV;
193 else
194 clkdivn &= ~S3C2412_CLKDIVN_USB48DIV;
195
196 __raw_writel(clkdivn, S3C2410_CLKDIVN);
197 return 0;
198}
199
200static struct clk clk_usbsrc = {
201 .name = "usbsrc",
202 .id = -1,
203 .get_rate = s3c2412_getrate_usbsrc,
204 .set_rate = s3c2412_setrate_usbsrc,
205 .round_rate = s3c2412_roundrate_usbsrc,
206 .set_parent = s3c2412_setparent_usbsrc,
207};
208
209static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent)
210{
211 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
212
213 if (parent == &clk_mdivclk)
214 clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL;
215 else if (parent == &clk_upll)
216 clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL;
217 else
218 return -EINVAL;
219
220 clk->parent = parent;
221
222 __raw_writel(clksrc, S3C2412_CLKSRC);
223 return 0;
224}
225
226static struct clk clk_msysclk = {
227 .name = "msysclk",
228 .id = -1,
229 .set_parent = s3c2412_setparent_msysclk,
230};
231
232/* these next clocks have an divider immediately after them,
233 * so we can register them with their divider and leave out the
234 * intermediate clock stage
235*/
236static unsigned long s3c2412_roundrate_clksrc(struct clk *clk,
237 unsigned long rate)
238{
239 unsigned long parent_rate = clk_get_rate(clk->parent);
240 int div;
241
242 if (rate > parent_rate)
243 return parent_rate;
244
245 /* note, we remove the +/- 1 calculations as they cancel out */
246
247 div = (rate / parent_rate);
248
249 if (div < 1)
250 div = 1;
251 else if (div > 16)
252 div = 16;
253
254 return parent_rate / div;
255}
256
257static int s3c2412_setparent_uart(struct clk *clk, struct clk *parent)
258{
259 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
260
261 if (parent == &clk_erefclk)
262 clksrc &= ~S3C2412_CLKSRC_UARTCLK_MPLL;
263 else if (parent == &clk_mpll)
264 clksrc |= S3C2412_CLKSRC_UARTCLK_MPLL;
265 else
266 return -EINVAL;
267
268 clk->parent = parent;
269
270 __raw_writel(clksrc, S3C2412_CLKSRC);
271 return 0;
272}
273
274static unsigned long s3c2412_getrate_uart(struct clk *clk)
275{
276 unsigned long parent_rate = clk_get_rate(clk->parent);
277 unsigned long div = __raw_readl(S3C2410_CLKDIVN);
278
279 div &= S3C2412_CLKDIVN_UARTDIV_MASK;
280 div >>= S3C2412_CLKDIVN_UARTDIV_SHIFT;
281
282 return parent_rate / (div + 1);
283}
284
285static int s3c2412_setrate_uart(struct clk *clk, unsigned long rate)
286{
287 unsigned long parent_rate = clk_get_rate(clk->parent);
288 unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
289
290 rate = s3c2412_roundrate_clksrc(clk, rate);
291
292 clkdivn &= ~S3C2412_CLKDIVN_UARTDIV_MASK;
293 clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_UARTDIV_SHIFT;
294
295 __raw_writel(clkdivn, S3C2410_CLKDIVN);
296 return 0;
297}
298
299static struct clk clk_uart = {
300 .name = "uartclk",
301 .id = -1,
302 .get_rate = s3c2412_getrate_uart,
303 .set_rate = s3c2412_setrate_uart,
304 .set_parent = s3c2412_setparent_uart,
305 .round_rate = s3c2412_roundrate_clksrc,
306};
307
308static int s3c2412_setparent_i2s(struct clk *clk, struct clk *parent)
309{
310 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
311
312 if (parent == &clk_erefclk)
313 clksrc &= ~S3C2412_CLKSRC_I2SCLK_MPLL;
314 else if (parent == &clk_mpll)
315 clksrc |= S3C2412_CLKSRC_I2SCLK_MPLL;
316 else
317 return -EINVAL;
318
319 clk->parent = parent;
320
321 __raw_writel(clksrc, S3C2412_CLKSRC);
322 return 0;
323}
324
325static unsigned long s3c2412_getrate_i2s(struct clk *clk)
326{
327 unsigned long parent_rate = clk_get_rate(clk->parent);
328 unsigned long div = __raw_readl(S3C2410_CLKDIVN);
329
330 div &= S3C2412_CLKDIVN_I2SDIV_MASK;
331 div >>= S3C2412_CLKDIVN_I2SDIV_SHIFT;
332
333 return parent_rate / (div + 1);
334}
335
336static int s3c2412_setrate_i2s(struct clk *clk, unsigned long rate)
337{
338 unsigned long parent_rate = clk_get_rate(clk->parent);
339 unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
340
341 rate = s3c2412_roundrate_clksrc(clk, rate);
342
343 clkdivn &= ~S3C2412_CLKDIVN_I2SDIV_MASK;
344 clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_I2SDIV_SHIFT;
345
346 __raw_writel(clkdivn, S3C2410_CLKDIVN);
347 return 0;
348}
349
350static struct clk clk_i2s = {
351 .name = "i2sclk",
352 .id = -1,
353 .get_rate = s3c2412_getrate_i2s,
354 .set_rate = s3c2412_setrate_i2s,
355 .set_parent = s3c2412_setparent_i2s,
356 .round_rate = s3c2412_roundrate_clksrc,
357};
358
359static int s3c2412_setparent_cam(struct clk *clk, struct clk *parent)
360{
361 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
362
363 if (parent == &clk_usysclk)
364 clksrc &= ~S3C2412_CLKSRC_CAMCLK_HCLK;
365 else if (parent == &clk_h)
366 clksrc |= S3C2412_CLKSRC_CAMCLK_HCLK;
367 else
368 return -EINVAL;
369
370 clk->parent = parent;
371
372 __raw_writel(clksrc, S3C2412_CLKSRC);
373 return 0;
374}
375static unsigned long s3c2412_getrate_cam(struct clk *clk)
376{
377 unsigned long parent_rate = clk_get_rate(clk->parent);
378 unsigned long div = __raw_readl(S3C2410_CLKDIVN);
379
380 div &= S3C2412_CLKDIVN_CAMDIV_MASK;
381 div >>= S3C2412_CLKDIVN_CAMDIV_SHIFT;
382
383 return parent_rate / (div + 1);
384}
385
386static int s3c2412_setrate_cam(struct clk *clk, unsigned long rate)
387{
388 unsigned long parent_rate = clk_get_rate(clk->parent);
389 unsigned long clkdivn = __raw_readl(S3C2410_CLKDIVN);
390
391 rate = s3c2412_roundrate_clksrc(clk, rate);
392
393 clkdivn &= ~S3C2412_CLKDIVN_CAMDIV_MASK;
394 clkdivn |= ((parent_rate / rate) - 1) << S3C2412_CLKDIVN_CAMDIV_SHIFT;
395
396 __raw_writel(clkdivn, S3C2410_CLKDIVN);
397 return 0;
398}
399
400static struct clk clk_cam = {
401 .name = "camif-upll", /* same as 2440 name */
402 .id = -1,
403 .get_rate = s3c2412_getrate_cam,
404 .set_rate = s3c2412_setrate_cam,
405 .set_parent = s3c2412_setparent_cam,
406 .round_rate = s3c2412_roundrate_clksrc,
407};
408
409/* standard clock definitions */
410
411static struct clk init_clocks_disable[] = {
412 {
413 .name = "nand",
414 .id = -1,
415 .parent = &clk_h,
416 .enable = s3c2412_clkcon_enable,
417 .ctrlbit = S3C2412_CLKCON_NAND,
418 }, {
419 .name = "sdi",
420 .id = -1,
421 .parent = &clk_p,
422 .enable = s3c2412_clkcon_enable,
423 .ctrlbit = S3C2412_CLKCON_SDI,
424 }, {
425 .name = "adc",
426 .id = -1,
427 .parent = &clk_p,
428 .enable = s3c2412_clkcon_enable,
429 .ctrlbit = S3C2412_CLKCON_ADC,
430 }, {
431 .name = "i2c",
432 .id = -1,
433 .parent = &clk_p,
434 .enable = s3c2412_clkcon_enable,
435 .ctrlbit = S3C2412_CLKCON_IIC,
436 }, {
437 .name = "iis",
438 .id = -1,
439 .parent = &clk_p,
440 .enable = s3c2412_clkcon_enable,
441 .ctrlbit = S3C2412_CLKCON_IIS,
442 }, {
443 .name = "spi",
444 .id = -1,
445 .parent = &clk_p,
446 .enable = s3c2412_clkcon_enable,
447 .ctrlbit = S3C2412_CLKCON_SPI,
448 }
449};
450
451static struct clk init_clocks[] = {
452 {
453 .name = "dma",
454 .id = 0,
455 .parent = &clk_h,
456 .enable = s3c2412_clkcon_enable,
457 .ctrlbit = S3C2412_CLKCON_DMA0,
458 }, {
459 .name = "dma",
460 .id = 1,
461 .parent = &clk_h,
462 .enable = s3c2412_clkcon_enable,
463 .ctrlbit = S3C2412_CLKCON_DMA1,
464 }, {
465 .name = "dma",
466 .id = 2,
467 .parent = &clk_h,
468 .enable = s3c2412_clkcon_enable,
469 .ctrlbit = S3C2412_CLKCON_DMA2,
470 }, {
471 .name = "dma",
472 .id = 3,
473 .parent = &clk_h,
474 .enable = s3c2412_clkcon_enable,
475 .ctrlbit = S3C2412_CLKCON_DMA3,
476 }, {
477 .name = "lcd",
478 .id = -1,
479 .parent = &clk_h,
480 .enable = s3c2412_clkcon_enable,
481 .ctrlbit = S3C2412_CLKCON_LCDC,
482 }, {
483 .name = "gpio",
484 .id = -1,
485 .parent = &clk_p,
486 .enable = s3c2412_clkcon_enable,
487 .ctrlbit = S3C2412_CLKCON_GPIO,
488 }, {
489 .name = "usb-host",
490 .id = -1,
491 .parent = &clk_h,
492 .enable = s3c2412_clkcon_enable,
493 .ctrlbit = S3C2412_CLKCON_USBH,
494 }, {
495 .name = "usb-device",
496 .id = -1,
497 .parent = &clk_h,
498 .enable = s3c2412_clkcon_enable,
499 .ctrlbit = S3C2412_CLKCON_USBD,
500 }, {
501 .name = "timers",
502 .id = -1,
503 .parent = &clk_p,
504 .enable = s3c2412_clkcon_enable,
505 .ctrlbit = S3C2412_CLKCON_PWMT,
506 }, {
507 .name = "uart",
508 .id = 0,
509 .parent = &clk_p,
510 .enable = s3c2412_clkcon_enable,
511 .ctrlbit = S3C2412_CLKCON_UART0,
512 }, {
513 .name = "uart",
514 .id = 1,
515 .parent = &clk_p,
516 .enable = s3c2412_clkcon_enable,
517 .ctrlbit = S3C2412_CLKCON_UART1,
518 }, {
519 .name = "uart",
520 .id = 2,
521 .parent = &clk_p,
522 .enable = s3c2412_clkcon_enable,
523 .ctrlbit = S3C2412_CLKCON_UART2,
524 }, {
525 .name = "rtc",
526 .id = -1,
527 .parent = &clk_p,
528 .enable = s3c2412_clkcon_enable,
529 .ctrlbit = S3C2412_CLKCON_RTC,
530 }, {
531 .name = "watchdog",
532 .id = -1,
533 .parent = &clk_p,
534 .ctrlbit = 0,
535 }, {
536 .name = "usb-bus-gadget",
537 .id = -1,
538 .parent = &clk_usb_bus,
539 .enable = s3c2412_clkcon_enable,
540 .ctrlbit = S3C2412_CLKCON_USB_DEV48,
541 }, {
542 .name = "usb-bus-host",
543 .id = -1,
544 .parent = &clk_usb_bus,
545 .enable = s3c2412_clkcon_enable,
546 .ctrlbit = S3C2412_CLKCON_USB_HOST48,
547 }
548};
549
550/* clocks to add where we need to check their parentage */
551
552struct clk_init {
553 struct clk *clk;
554 unsigned int bit;
555 struct clk *src_0;
556 struct clk *src_1;
557};
558
559struct clk_init clks_src[] __initdata = {
560 {
561 .clk = &clk_usysclk,
562 .bit = S3C2412_CLKSRC_USBCLK_HCLK,
563 .src_0 = &clk_urefclk,
564 .src_1 = &clk_upll,
565 }, {
566 .clk = &clk_i2s,
567 .bit = S3C2412_CLKSRC_I2SCLK_MPLL,
568 .src_0 = &clk_erefclk,
569 .src_1 = &clk_mpll,
570 }, {
571 .clk = &clk_cam,
572 .bit = S3C2412_CLKSRC_CAMCLK_HCLK,
573 .src_0 = &clk_usysclk,
574 .src_1 = &clk_h,
575 }, {
576 .clk = &clk_msysclk,
577 .bit = S3C2412_CLKSRC_MSYSCLK_MPLL,
578 .src_0 = &clk_mdivclk,
579 .src_1 = &clk_mpll,
580 }, {
581 .clk = &clk_uart,
582 .bit = S3C2412_CLKSRC_UARTCLK_MPLL,
583 .src_0 = &clk_erefclk,
584 .src_1 = &clk_mpll,
585 }, {
586 .clk = &clk_usbsrc,
587 .bit = S3C2412_CLKSRC_USBCLK_HCLK,
588 .src_0 = &clk_usysclk,
589 .src_1 = &clk_h,
590 },
591};
592
593/* s3c2412_clk_initparents
594 *
595 * Initialise the parents for the clocks that we get at start-time
596*/
597
598static void __init s3c2412_clk_initparents(void)
599{
600 unsigned long clksrc = __raw_readl(S3C2412_CLKSRC);
601 struct clk_init *cip = clks_src;
602 struct clk *src;
603 int ptr;
604 int ret;
605
606 for (ptr = 0; ptr < ARRAY_SIZE(clks_src); ptr++, cip++) {
607 ret = s3c24xx_register_clock(cip->clk);
608 if (ret < 0) {
609 printk(KERN_ERR "Failed to register clock %s (%d)\n",
610 cip->clk->name, ret);
611 }
612
613 src = (clksrc & cip->bit) ? cip->src_1 : cip->src_0;
614
615 printk(KERN_INFO "%s: parent %s\n", cip->clk->name, src->name);
616 clk_set_parent(cip->clk, src);
617 }
618}
619
620/* clocks to add straight away */
621
622struct clk *clks[] __initdata = {
623 &clk_ext,
624 &clk_usb_bus,
625 &clk_erefclk,
626 &clk_urefclk,
627 &clk_mrefclk,
628};
629
630int __init s3c2412_baseclk_add(void)
631{
632 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
633 struct clk *clkp;
634 int ret;
635 int ptr;
636
637 clk_upll.enable = s3c2412_upll_enable;
638 clk_usb_bus.parent = &clk_usbsrc;
639 clk_usb_bus.rate = 0x0;
640
641 s3c2412_clk_initparents();
642
643 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
644 clkp = clks[ptr];
645
646 ret = s3c24xx_register_clock(clkp);
647 if (ret < 0) {
648 printk(KERN_ERR "Failed to register clock %s (%d)\n",
649 clkp->name, ret);
650 }
651 }
652
653 /* ensure usb bus clock is within correct rate of 48MHz */
654
655 if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) {
656 printk(KERN_INFO "Warning: USB bus clock not at 48MHz\n");
657
658 /* for the moment, let's use the UPLL, and see if we can
659 * get 48MHz */
660
661 clk_set_parent(&clk_usysclk, &clk_upll);
662 clk_set_parent(&clk_usbsrc, &clk_usysclk);
663 clk_set_rate(&clk_usbsrc, 48*1000*1000);
664 }
665
666 printk("S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
667 (__raw_readl(S3C2410_UPLLCON) & S3C2412_PLLCON_OFF) ? "off":"on",
668 print_mhz(clk_get_rate(&clk_upll)),
669 print_mhz(clk_get_rate(&clk_usb_bus)));
670
671 /* register clocks from clock array */
672
673 clkp = init_clocks;
674 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
675 /* ensure that we note the clock state */
676
677 clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
678
679 ret = s3c24xx_register_clock(clkp);
680 if (ret < 0) {
681 printk(KERN_ERR "Failed to register clock %s (%d)\n",
682 clkp->name, ret);
683 }
684 }
685
686 /* We must be careful disabling the clocks we are not intending to
687 * be using at boot time, as subsytems such as the LCD which do
688 * their own DMA requests to the bus can cause the system to lockup
689 * if they where in the middle of requesting bus access.
690 *
691 * Disabling the LCD clock if the LCD is active is very dangerous,
692 * and therefore the bootloader should be careful to not enable
693 * the LCD clock if it is not needed.
694 */
695
696 /* install (and disable) the clocks we do not need immediately */
697
698 clkp = init_clocks_disable;
699 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
700
701 ret = s3c24xx_register_clock(clkp);
702 if (ret < 0) {
703 printk(KERN_ERR "Failed to register clock %s (%d)\n",
704 clkp->name, ret);
705 }
706
707 s3c2412_clkcon_enable(clkp, 0);
708 }
709
710 return 0;
711}
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2410/s3c2412.c
new file mode 100644
index 000000000000..e24ffd5e478b
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412.c
@@ -0,0 +1,195 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://armlinux.simtec.co.uk/.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Modifications:
13 * 16-May-2003 BJD Created initial version
14 * 16-Aug-2003 BJD Fixed header files and copyright, added URL
15 * 05-Sep-2003 BJD Moved to kernel v2.6
16 * 18-Jan-2004 BJD Added serial port configuration
17 * 21-Aug-2004 BJD Added new struct s3c2410_board handler
18 * 28-Sep-2004 BJD Updates for new serial port bits
19 * 04-Nov-2004 BJD Updated UART configuration process
20 * 10-Jan-2005 BJD Removed s3c2410_clock_tick_rate
21 * 13-Aug-2005 DA Removed UART from initial I/O mappings
22*/
23
24#include <linux/kernel.h>
25#include <linux/types.h>
26#include <linux/interrupt.h>
27#include <linux/list.h>
28#include <linux/timer.h>
29#include <linux/init.h>
30#include <linux/sysdev.h>
31#include <linux/platform_device.h>
32
33#include <asm/mach/arch.h>
34#include <asm/mach/map.h>
35#include <asm/mach/irq.h>
36
37#include <asm/hardware.h>
38#include <asm/io.h>
39#include <asm/irq.h>
40
41#include <asm/arch/regs-clock.h>
42#include <asm/arch/regs-serial.h>
43#include <asm/arch/regs-gpio.h>
44#include <asm/arch/regs-gpioj.h>
45#include <asm/arch/regs-dsc.h>
46
47#include "s3c2412.h"
48#include "cpu.h"
49#include "devs.h"
50#include "clock.h"
51#include "pm.h"
52
53#ifndef CONFIG_CPU_S3C2412_ONLY
54void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
55#endif
56
57/* Initial IO mappings */
58
59static struct map_desc s3c2412_iodesc[] __initdata = {
60 IODESC_ENT(CLKPWR),
61 IODESC_ENT(LCD),
62 IODESC_ENT(TIMER),
63 IODESC_ENT(ADC),
64 IODESC_ENT(WATCHDOG),
65};
66
67/* uart registration process */
68
69void __init s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no)
70{
71 s3c24xx_init_uartdevs("s3c2412-uart", s3c2410_uart_resources, cfg, no);
72
73 /* rename devices that are s3c2412/s3c2413 specific */
74 s3c_device_sdi.name = "s3c2412-sdi";
75 s3c_device_nand.name = "s3c2412-nand";
76}
77
78/* s3c2412_map_io
79 *
80 * register the standard cpu IO areas, and any passed in from the
81 * machine specific initialisation.
82*/
83
84void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
85{
86 /* move base of IO */
87
88 s3c24xx_va_gpio2 = S3C24XX_VA_GPIO + 0x10;
89
90 /* register our io-tables */
91
92 iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
93 iotable_init(mach_desc, mach_size);
94}
95
96void __init s3c2412_init_clocks(int xtal)
97{
98 unsigned long tmp;
99 unsigned long fclk;
100 unsigned long hclk;
101 unsigned long pclk;
102
103 /* now we've got our machine bits initialised, work out what
104 * clocks we've got */
105
106 fclk = s3c2410_get_pll(__raw_readl(S3C2410_MPLLCON), xtal*2);
107
108 tmp = __raw_readl(S3C2410_CLKDIVN);
109
110 /* work out clock scalings */
111
112 hclk = fclk / ((tmp & S3C2412_CLKDIVN_HDIVN_MASK) + 1);
113 hclk /= ((tmp & S3C2421_CLKDIVN_ARMDIVN) ? 2 : 1);
114 pclk = hclk / ((tmp & S3C2412_CLKDIVN_PDIVN) ? 2 : 1);
115
116 /* print brieft summary of clocks, etc */
117
118 printk("S3C2412: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
119 print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
120
121 /* initialise the clocks here, to allow other things like the
122 * console to use them
123 */
124
125 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
126 s3c2412_baseclk_add();
127}
128
129/* need to register class before we actually register the device, and
130 * we also need to ensure that it has been initialised before any of the
131 * drivers even try to use it (even if not on an s3c2412 based system)
132 * as a driver which may support both 2410 and 2440 may try and use it.
133*/
134
135#ifdef CONFIG_PM
136static struct sleep_save s3c2412_sleep[] = {
137 SAVE_ITEM(S3C2412_DSC0),
138 SAVE_ITEM(S3C2412_DSC1),
139 SAVE_ITEM(S3C2413_GPJDAT),
140 SAVE_ITEM(S3C2413_GPJCON),
141 SAVE_ITEM(S3C2413_GPJUP),
142
143 /* save the sleep configuration anyway, just in case these
144 * get damaged during wakeup */
145
146 SAVE_ITEM(S3C2412_GPBSLPCON),
147 SAVE_ITEM(S3C2412_GPCSLPCON),
148 SAVE_ITEM(S3C2412_GPDSLPCON),
149 SAVE_ITEM(S3C2412_GPESLPCON),
150 SAVE_ITEM(S3C2412_GPFSLPCON),
151 SAVE_ITEM(S3C2412_GPGSLPCON),
152 SAVE_ITEM(S3C2412_GPHSLPCON),
153 SAVE_ITEM(S3C2413_GPJSLPCON),
154};
155
156static int s3c2412_suspend(struct sys_device *dev, pm_message_t state)
157{
158 s3c2410_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
159 return 0;
160}
161
162static int s3c2412_resume(struct sys_device *dev)
163{
164 s3c2410_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
165 return 0;
166}
167
168#else
169#define s3c2412_suspend NULL
170#define s3c2412_resume NULL
171#endif
172
173struct sysdev_class s3c2412_sysclass = {
174 set_kset_name("s3c2412-core"),
175 .suspend = s3c2412_suspend,
176 .resume = s3c2412_resume
177};
178
179static int __init s3c2412_core_init(void)
180{
181 return sysdev_class_register(&s3c2412_sysclass);
182}
183
184core_initcall(s3c2412_core_init);
185
186static struct sys_device s3c2412_sysdev = {
187 .cls = &s3c2412_sysclass,
188};
189
190int __init s3c2412_init(void)
191{
192 printk("S3C2412: Initialising architecture\n");
193
194 return sysdev_register(&s3c2412_sysdev);
195}
diff --git a/arch/arm/mach-s3c2410/s3c2412.h b/arch/arm/mach-s3c2410/s3c2412.h
new file mode 100644
index 000000000000..c6e56032a6e7
--- /dev/null
+++ b/arch/arm/mach-s3c2410/s3c2412.h
@@ -0,0 +1,29 @@
1/* arch/arm/mach-s3c2410/s3c2412.h
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Header file for s3c2412 cpu support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifdef CONFIG_CPU_S3C2412
14
15extern int s3c2412_init(void);
16
17extern void s3c2412_map_io(struct map_desc *mach_desc, int size);
18
19extern void s3c2412_init_uarts(struct s3c2410_uartcfg *cfg, int no);
20
21extern void s3c2412_init_clocks(int xtal);
22
23extern int s3c2412_baseclk_add(void);
24#else
25#define s3c2412_init_clocks NULL
26#define s3c2412_init_uarts NULL
27#define s3c2412_map_io NULL
28#define s3c2412_init NULL
29#endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 4221d054a1e9..ecf5e232a6fc 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -61,9 +61,9 @@ config CPU_ARM720T
61 61
62# ARM920T 62# ARM920T
63config CPU_ARM920T 63config CPU_ARM920T
64 bool "Support ARM920T processor" if !ARCH_S3C2410 64 bool "Support ARM920T processor"
65 depends on ARCH_EP93XX || ARCH_INTEGRATOR || ARCH_S3C2410 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200 65 depends on ARCH_EP93XX || ARCH_INTEGRATOR || CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_IMX || ARCH_AAEC2000 || ARCH_AT91RM9200
66 default y if ARCH_S3C2410 || ARCH_AT91RM9200 66 default y if CPU_S3C2410 || CPU_S3C2440 || CPU_S3C2442 || ARCH_AT91RM9200
67 select CPU_32v4 67 select CPU_32v4
68 select CPU_ABRT_EV4T 68 select CPU_ABRT_EV4T
69 select CPU_CACHE_V4WT 69 select CPU_CACHE_V4WT
@@ -121,8 +121,8 @@ config CPU_ARM925T
121# ARM926T 121# ARM926T
122config CPU_ARM926T 122config CPU_ARM926T
123 bool "Support ARM926T processor" 123 bool "Support ARM926T processor"
124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX 124 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412
125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX 125 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412
126 select CPU_32v5 126 select CPU_32v5
127 select CPU_ABRT_EV5TJ 127 select CPU_ABRT_EV5TJ
128 select CPU_CACHE_VIVT 128 select CPU_CACHE_VIVT
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 8831303a473f..7512f39c9f25 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -37,6 +37,13 @@ SECTIONS
37 37
38 RODATA 38 RODATA
39 39
40 . = ALIGN(4);
41 __tracedata_start = .;
42 .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
43 *(.tracedata)
44 }
45 __tracedata_end = .;
46
40 /* writeable */ 47 /* writeable */
41 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ 48 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
42 *(.data) 49 *(.data)
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 1b83e21841b5..6616ee05c313 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -12,7 +12,7 @@ obj-y := entry.o wof.o wuf.o etrap.o rtrap.o traps.o $(IRQ_OBJS) \
12 sys_sparc.o sunos_asm.o systbls.o \ 12 sys_sparc.o sunos_asm.o systbls.o \
13 time.o windows.o cpu.o devices.o sclow.o \ 13 time.o windows.o cpu.o devices.o sclow.o \
14 tadpole.o tick14.o ptrace.o sys_solaris.o \ 14 tadpole.o tick14.o ptrace.o sys_solaris.o \
15 unaligned.o muldiv.o semaphore.o 15 unaligned.o muldiv.o semaphore.o prom.o of_device.o
16 16
17obj-$(CONFIG_PCI) += pcic.o 17obj-$(CONFIG_PCI) += pcic.o
18obj-$(CONFIG_SUN4) += sun4setup.o 18obj-$(CONFIG_SUN4) += sun4setup.o
diff --git a/arch/sparc/kernel/ebus.c b/arch/sparc/kernel/ebus.c
index 5c3529ceb5d6..a7a4892956c8 100644
--- a/arch/sparc/kernel/ebus.c
+++ b/arch/sparc/kernel/ebus.c
@@ -20,6 +20,7 @@
20#include <asm/ebus.h> 20#include <asm/ebus.h>
21#include <asm/io.h> 21#include <asm/io.h>
22#include <asm/oplib.h> 22#include <asm/oplib.h>
23#include <asm/prom.h>
23#include <asm/bpp.h> 24#include <asm/bpp.h>
24 25
25struct linux_ebus *ebus_chain = NULL; 26struct linux_ebus *ebus_chain = NULL;
@@ -83,79 +84,81 @@ int __init ebus_blacklist_irq(char *name)
83 return 0; 84 return 0;
84} 85}
85 86
86void __init fill_ebus_child(int node, struct linux_prom_registers *preg, 87void __init fill_ebus_child(struct device_node *dp,
87 struct linux_ebus_child *dev) 88 struct linux_ebus_child *dev)
88{ 89{
89 int regs[PROMREG_MAX]; 90 int *regs;
90 int irqs[PROMREG_MAX]; 91 int *irqs;
91 char lbuf[128];
92 int i, len; 92 int i, len;
93 93
94 dev->prom_node = node; 94 dev->prom_node = dp;
95 prom_getstring(node, "name", lbuf, sizeof(lbuf)); 95 regs = of_get_property(dp, "reg", &len);
96 strcpy(dev->prom_name, lbuf); 96 if (!regs)
97 97 len = 0;
98 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
99 if (len == -1) len = 0;
100 dev->num_addrs = len / sizeof(regs[0]); 98 dev->num_addrs = len / sizeof(regs[0]);
101 99
102 for (i = 0; i < dev->num_addrs; i++) { 100 for (i = 0; i < dev->num_addrs; i++) {
103 if (regs[i] >= dev->parent->num_addrs) { 101 if (regs[i] >= dev->parent->num_addrs) {
104 prom_printf("UGH: property for %s was %d, need < %d\n", 102 prom_printf("UGH: property for %s was %d, need < %d\n",
105 dev->prom_name, len, dev->parent->num_addrs); 103 dev->prom_node->name, len,
104 dev->parent->num_addrs);
106 panic(__FUNCTION__); 105 panic(__FUNCTION__);
107 } 106 }
108 dev->resource[i].start = dev->parent->resource[regs[i]].start; /* XXX resource */ 107
108 /* XXX resource */
109 dev->resource[i].start =
110 dev->parent->resource[regs[i]].start;
109 } 111 }
110 112
111 for (i = 0; i < PROMINTR_MAX; i++) 113 for (i = 0; i < PROMINTR_MAX; i++)
112 dev->irqs[i] = PCI_IRQ_NONE; 114 dev->irqs[i] = PCI_IRQ_NONE;
113 115
114 if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) { 116 if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
115 dev->num_irqs = 1; 117 dev->num_irqs = 1;
116 } else if ((len = prom_getproperty(node, "interrupts",
117 (char *)&irqs, sizeof(irqs))) == -1 || len == 0) {
118 dev->num_irqs = 0;
119 dev->irqs[0] = 0;
120 if (dev->parent->num_irqs != 0) {
121 dev->num_irqs = 1;
122 dev->irqs[0] = dev->parent->irqs[0];
123/* P3 */ /* printk("EBUS: dev %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */
124 }
125 } else { 118 } else {
126 dev->num_irqs = len / sizeof(irqs[0]); 119 irqs = of_get_property(dp, "interrupts", &len);
127 if (irqs[0] == 0 || irqs[0] >= 8) { 120 if (!irqs) {
128 /*
129 * XXX Zero is a valid pin number...
130 * This works as long as Ebus is not wired to INTA#.
131 */
132 printk("EBUS: %s got bad irq %d from PROM\n",
133 dev->prom_name, irqs[0]);
134 dev->num_irqs = 0; 121 dev->num_irqs = 0;
135 dev->irqs[0] = 0; 122 dev->irqs[0] = 0;
123 if (dev->parent->num_irqs != 0) {
124 dev->num_irqs = 1;
125 dev->irqs[0] = dev->parent->irqs[0];
126 }
136 } else { 127 } else {
137 dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name); 128 dev->num_irqs = len / sizeof(irqs[0]);
129 if (irqs[0] == 0 || irqs[0] >= 8) {
130 /*
131 * XXX Zero is a valid pin number...
132 * This works as long as Ebus is not wired
133 * to INTA#.
134 */
135 printk("EBUS: %s got bad irq %d from PROM\n",
136 dev->prom_node->name, irqs[0]);
137 dev->num_irqs = 0;
138 dev->irqs[0] = 0;
139 } else {
140 dev->irqs[0] =
141 pcic_pin_to_irq(irqs[0],
142 dev->prom_node->name);
143 }
138 } 144 }
139 } 145 }
140} 146}
141 147
142void __init fill_ebus_device(int node, struct linux_ebus_device *dev) 148void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
143{ 149{
144 struct linux_prom_registers regs[PROMREG_MAX]; 150 struct linux_prom_registers *regs;
145 struct linux_ebus_child *child; 151 struct linux_ebus_child *child;
146 int irqs[PROMINTR_MAX]; 152 int *irqs;
147 char lbuf[128];
148 int i, n, len; 153 int i, n, len;
149 unsigned long baseaddr; 154 unsigned long baseaddr;
150 155
151 dev->prom_node = node; 156 dev->prom_node = dp;
152 prom_getstring(node, "name", lbuf, sizeof(lbuf));
153 strcpy(dev->prom_name, lbuf);
154 157
155 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 158 regs = of_get_property(dp, "reg", &len);
156 if (len % sizeof(struct linux_prom_registers)) { 159 if (len % sizeof(struct linux_prom_registers)) {
157 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", 160 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
158 dev->prom_name, len, 161 dev->prom_node->name, len,
159 (int)sizeof(struct linux_prom_registers)); 162 (int)sizeof(struct linux_prom_registers));
160 panic(__FUNCTION__); 163 panic(__FUNCTION__);
161 } 164 }
@@ -197,7 +200,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
197 if ((baseaddr = (unsigned long) ioremap(baseaddr, 200 if ((baseaddr = (unsigned long) ioremap(baseaddr,
198 regs[i].reg_size)) == 0) { 201 regs[i].reg_size)) == 0) {
199 panic("ebus: unable to remap dev %s", 202 panic("ebus: unable to remap dev %s",
200 dev->prom_name); 203 dev->prom_node->name);
201 } 204 }
202 } 205 }
203 dev->resource[i].start = baseaddr; /* XXX Unaligned */ 206 dev->resource[i].start = baseaddr; /* XXX Unaligned */
@@ -206,29 +209,43 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
206 for (i = 0; i < PROMINTR_MAX; i++) 209 for (i = 0; i < PROMINTR_MAX; i++)
207 dev->irqs[i] = PCI_IRQ_NONE; 210 dev->irqs[i] = PCI_IRQ_NONE;
208 211
209 if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_name)) != 0) { 212 if ((dev->irqs[0] = ebus_blacklist_irq(dev->prom_node->name)) != 0) {
210 dev->num_irqs = 1; 213 dev->num_irqs = 1;
211 } else if ((len = prom_getproperty(node, "interrupts",
212 (char *)&irqs, sizeof(irqs))) == -1 || len == 0) {
213 dev->num_irqs = 0;
214 if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
215 dev->num_irqs = 1;
216/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */
217 }
218 } else { 214 } else {
219 dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */ 215 irqs = of_get_property(dp, "interrupts", &len);
220 if (irqs[0] == 0 || irqs[0] >= 8) { 216 if (!irqs) {
221 /* See above for the parent. XXX */
222 printk("EBUS: %s got bad irq %d from PROM\n",
223 dev->prom_name, irqs[0]);
224 dev->num_irqs = 0; 217 dev->num_irqs = 0;
225 dev->irqs[0] = 0; 218 if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
219 dev->num_irqs = 1;
220/* P3 */ /* printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]); */
221 }
226 } else { 222 } else {
227 dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name); 223 dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */
224 if (irqs[0] == 0 || irqs[0] >= 8) {
225 /* See above for the parent. XXX */
226 printk("EBUS: %s got bad irq %d from PROM\n",
227 dev->prom_node->name, irqs[0]);
228 dev->num_irqs = 0;
229 dev->irqs[0] = 0;
230 } else {
231 dev->irqs[0] =
232 pcic_pin_to_irq(irqs[0],
233 dev->prom_node->name);
234 }
228 } 235 }
229 } 236 }
230 237
231 if ((node = prom_getchild(node))) { 238 dev->ofdev.node = dp;
239 dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
240 dev->ofdev.dev.bus = &ebus_bus_type;
241 strcpy(dev->ofdev.dev.bus_id, dp->path_component_name);
242
243 /* Register with core */
244 if (of_device_register(&dev->ofdev) != 0)
245 printk(KERN_DEBUG "ebus: device registration error for %s!\n",
246 dev->ofdev.dev.bus_id);
247
248 if ((dp = dp->child) != NULL) {
232 dev->children = (struct linux_ebus_child *) 249 dev->children = (struct linux_ebus_child *)
233 ebus_alloc(sizeof(struct linux_ebus_child)); 250 ebus_alloc(sizeof(struct linux_ebus_child));
234 251
@@ -236,9 +253,9 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
236 child->next = NULL; 253 child->next = NULL;
237 child->parent = dev; 254 child->parent = dev;
238 child->bus = dev->bus; 255 child->bus = dev->bus;
239 fill_ebus_child(node, &regs[0], child); 256 fill_ebus_child(dp, child);
240 257
241 while ((node = prom_getsibling(node)) != 0) { 258 while ((dp = dp->sibling) != NULL) {
242 child->next = (struct linux_ebus_child *) 259 child->next = (struct linux_ebus_child *)
243 ebus_alloc(sizeof(struct linux_ebus_child)); 260 ebus_alloc(sizeof(struct linux_ebus_child));
244 261
@@ -246,51 +263,49 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
246 child->next = NULL; 263 child->next = NULL;
247 child->parent = dev; 264 child->parent = dev;
248 child->bus = dev->bus; 265 child->bus = dev->bus;
249 fill_ebus_child(node, &regs[0], child); 266 fill_ebus_child(dp, child);
250 } 267 }
251 } 268 }
252} 269}
253 270
254void __init ebus_init(void) 271void __init ebus_init(void)
255{ 272{
256 struct linux_prom_pci_registers regs[PROMREG_MAX]; 273 struct linux_prom_pci_registers *regs;
257 struct linux_pbm_info *pbm; 274 struct linux_pbm_info *pbm;
258 struct linux_ebus_device *dev; 275 struct linux_ebus_device *dev;
259 struct linux_ebus *ebus; 276 struct linux_ebus *ebus;
260 struct ebus_system_entry *sp; 277 struct ebus_system_entry *sp;
261 struct pci_dev *pdev; 278 struct pci_dev *pdev;
262 struct pcidev_cookie *cookie; 279 struct pcidev_cookie *cookie;
263 char lbuf[128]; 280 struct device_node *dp;
264 unsigned long addr, *base; 281 unsigned long addr, *base;
265 unsigned short pci_command; 282 unsigned short pci_command;
266 int nd, len, ebusnd; 283 int len, reg, nreg;
267 int reg, nreg;
268 int num_ebus = 0; 284 int num_ebus = 0;
269 285
270 prom_getstring(prom_root_node, "name", lbuf, sizeof(lbuf)); 286 dp = of_find_node_by_path("/");
271 for (sp = ebus_blacklist; sp->esname != NULL; sp++) { 287 for (sp = ebus_blacklist; sp->esname != NULL; sp++) {
272 if (strcmp(lbuf, sp->esname) == 0) { 288 if (strcmp(dp->name, sp->esname) == 0) {
273 ebus_blackp = sp->ipt; 289 ebus_blackp = sp->ipt;
274 break; 290 break;
275 } 291 }
276 } 292 }
277 293
278 pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL); 294 pdev = pci_get_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, NULL);
279 if (!pdev) { 295 if (!pdev)
280 return; 296 return;
281 } 297
282 cookie = pdev->sysdata; 298 cookie = pdev->sysdata;
283 ebusnd = cookie->prom_node; 299 dp = cookie->prom_node;
284 300
285 ebus_chain = ebus = (struct linux_ebus *) 301 ebus_chain = ebus = (struct linux_ebus *)
286 ebus_alloc(sizeof(struct linux_ebus)); 302 ebus_alloc(sizeof(struct linux_ebus));
287 ebus->next = NULL; 303 ebus->next = NULL;
288 304
289 while (ebusnd) { 305 while (dp) {
306 struct device_node *nd;
290 307
291 prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf)); 308 ebus->prom_node = dp;
292 ebus->prom_node = ebusnd;
293 strcpy(ebus->prom_name, lbuf);
294 ebus->self = pdev; 309 ebus->self = pdev;
295 ebus->parent = pbm = cookie->pbm; 310 ebus->parent = pbm = cookie->pbm;
296 311
@@ -299,9 +314,8 @@ void __init ebus_init(void)
299 pci_command |= PCI_COMMAND_MASTER; 314 pci_command |= PCI_COMMAND_MASTER;
300 pci_write_config_word(pdev, PCI_COMMAND, pci_command); 315 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
301 316
302 len = prom_getproperty(ebusnd, "reg", (void *)regs, 317 regs = of_get_property(dp, "reg", &len);
303 sizeof(regs)); 318 if (!regs) {
304 if (len == 0 || len == -1) {
305 prom_printf("%s: can't find reg property\n", 319 prom_printf("%s: can't find reg property\n",
306 __FUNCTION__); 320 __FUNCTION__);
307 prom_halt(); 321 prom_halt();
@@ -317,7 +331,18 @@ void __init ebus_init(void)
317 *base++ = addr; 331 *base++ = addr;
318 } 332 }
319 333
320 nd = prom_getchild(ebusnd); 334 ebus->ofdev.node = dp;
335 ebus->ofdev.dev.parent = &pdev->dev;
336 ebus->ofdev.dev.bus = &ebus_bus_type;
337 strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name);
338
339 /* Register with core */
340 if (of_device_register(&ebus->ofdev) != 0)
341 printk(KERN_DEBUG "ebus: device registration error for %s!\n",
342 ebus->ofdev.dev.bus_id);
343
344
345 nd = dp->child;
321 if (!nd) 346 if (!nd)
322 goto next_ebus; 347 goto next_ebus;
323 348
@@ -330,7 +355,7 @@ void __init ebus_init(void)
330 dev->bus = ebus; 355 dev->bus = ebus;
331 fill_ebus_device(nd, dev); 356 fill_ebus_device(nd, dev);
332 357
333 while ((nd = prom_getsibling(nd)) != 0) { 358 while ((nd = nd->sibling) != NULL) {
334 dev->next = (struct linux_ebus_device *) 359 dev->next = (struct linux_ebus_device *)
335 ebus_alloc(sizeof(struct linux_ebus_device)); 360 ebus_alloc(sizeof(struct linux_ebus_device));
336 361
@@ -348,7 +373,7 @@ void __init ebus_init(void)
348 break; 373 break;
349 374
350 cookie = pdev->sysdata; 375 cookie = pdev->sysdata;
351 ebusnd = cookie->prom_node; 376 dp = cookie->prom_node;
352 377
353 ebus->next = (struct linux_ebus *) 378 ebus->next = (struct linux_ebus *)
354 ebus_alloc(sizeof(struct linux_ebus)); 379 ebus_alloc(sizeof(struct linux_ebus));
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index f9ff29734848..ae4c667c906f 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -39,6 +39,8 @@
39#include <asm/io.h> 39#include <asm/io.h>
40#include <asm/vaddrs.h> 40#include <asm/vaddrs.h>
41#include <asm/oplib.h> 41#include <asm/oplib.h>
42#include <asm/prom.h>
43#include <asm/sbus.h>
42#include <asm/page.h> 44#include <asm/page.h>
43#include <asm/pgalloc.h> 45#include <asm/pgalloc.h>
44#include <asm/dma.h> 46#include <asm/dma.h>
@@ -224,10 +226,54 @@ static void _sparc_free_io(struct resource *res)
224 226
225#ifdef CONFIG_SBUS 227#ifdef CONFIG_SBUS
226 228
227void sbus_set_sbus64(struct sbus_dev *sdev, int x) { 229void sbus_set_sbus64(struct sbus_dev *sdev, int x)
230{
228 printk("sbus_set_sbus64: unsupported\n"); 231 printk("sbus_set_sbus64: unsupported\n");
229} 232}
230 233
234extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
235void __init sbus_fill_device_irq(struct sbus_dev *sdev)
236{
237 struct linux_prom_irqs irqs[PROMINTR_MAX];
238 int len;
239
240 len = prom_getproperty(sdev->prom_node, "intr",
241 (char *)irqs, sizeof(irqs));
242 if (len != -1) {
243 sdev->num_irqs = len / 8;
244 if (sdev->num_irqs == 0) {
245 sdev->irqs[0] = 0;
246 } else if (sparc_cpu_model == sun4d) {
247 for (len = 0; len < sdev->num_irqs; len++)
248 sdev->irqs[len] =
249 sun4d_build_irq(sdev, irqs[len].pri);
250 } else {
251 for (len = 0; len < sdev->num_irqs; len++)
252 sdev->irqs[len] = irqs[len].pri;
253 }
254 } else {
255 int interrupts[PROMINTR_MAX];
256
257 /* No "intr" node found-- check for "interrupts" node.
258 * This node contains SBus interrupt levels, not IPLs
259 * as in "intr", and no vector values. We convert
260 * SBus interrupt levels to PILs (platform specific).
261 */
262 len = prom_getproperty(sdev->prom_node, "interrupts",
263 (char *)interrupts, sizeof(interrupts));
264 if (len == -1) {
265 sdev->irqs[0] = 0;
266 sdev->num_irqs = 0;
267 } else {
268 sdev->num_irqs = len / sizeof(int);
269 for (len = 0; len < sdev->num_irqs; len++) {
270 sdev->irqs[len] =
271 sbint_to_irq(sdev, interrupts[len]);
272 }
273 }
274 }
275}
276
231/* 277/*
232 * Allocate a chunk of memory suitable for DMA. 278 * Allocate a chunk of memory suitable for DMA.
233 * Typically devices use them for control blocks. 279 * Typically devices use them for control blocks.
@@ -414,6 +460,89 @@ void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg,
414{ 460{
415 printk("sbus_dma_sync_sg_for_device: not implemented yet\n"); 461 printk("sbus_dma_sync_sg_for_device: not implemented yet\n");
416} 462}
463
464/* Support code for sbus_init(). */
465/*
466 * XXX This functions appears to be a distorted version of
467 * prom_sbus_ranges_init(), with all sun4d stuff cut away.
468 * Ask DaveM what is going on here, how is sun4d supposed to work... XXX
469 */
470/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */
471void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus)
472{
473 int parent_node = pn->node;
474
475 if (sparc_cpu_model == sun4d) {
476 struct linux_prom_ranges iounit_ranges[PROMREG_MAX];
477 int num_iounit_ranges, len;
478
479 len = prom_getproperty(parent_node, "ranges",
480 (char *) iounit_ranges,
481 sizeof (iounit_ranges));
482 if (len != -1) {
483 num_iounit_ranges =
484 (len / sizeof(struct linux_prom_ranges));
485 prom_adjust_ranges(sbus->sbus_ranges,
486 sbus->num_sbus_ranges,
487 iounit_ranges, num_iounit_ranges);
488 }
489 }
490}
491
492void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
493{
494 struct device_node *parent = dp->parent;
495
496 if (sparc_cpu_model != sun4d &&
497 parent != NULL &&
498 !strcmp(parent->name, "iommu")) {
499 extern void iommu_init(int iommu_node, struct sbus_bus *sbus);
500
501 iommu_init(parent->node, sbus);
502 }
503
504 if (sparc_cpu_model == sun4d) {
505 extern void iounit_init(int sbi_node, int iounit_node,
506 struct sbus_bus *sbus);
507
508 iounit_init(dp->node, parent->node, sbus);
509 }
510}
511
512void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
513{
514 if (sparc_cpu_model == sun4d) {
515 struct device_node *parent = dp->parent;
516
517 sbus->devid = of_getintprop_default(parent, "device-id", 0);
518 sbus->board = of_getintprop_default(parent, "board#", 0);
519 }
520}
521
522int __init sbus_arch_preinit(void)
523{
524 extern void register_proc_sparc_ioport(void);
525
526 register_proc_sparc_ioport();
527
528#ifdef CONFIG_SUN4
529 {
530 extern void sun4_dvma_init(void);
531 sun4_dvma_init();
532 }
533 return 1;
534#else
535 return 0;
536#endif
537}
538
539void __init sbus_arch_postinit(void)
540{
541 if (sparc_cpu_model == sun4d) {
542 extern void sun4d_init_sbi_irq(void);
543 sun4d_init_sbi_irq();
544 }
545}
417#endif /* CONFIG_SBUS */ 546#endif /* CONFIG_SBUS */
418 547
419#ifdef CONFIG_PCI 548#ifdef CONFIG_PCI
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
new file mode 100644
index 000000000000..001b8673b4bd
--- /dev/null
+++ b/arch/sparc/kernel/of_device.c
@@ -0,0 +1,268 @@
1#include <linux/config.h>
2#include <linux/string.h>
3#include <linux/kernel.h>
4#include <linux/init.h>
5#include <linux/module.h>
6#include <linux/mod_devicetable.h>
7#include <linux/slab.h>
8
9#include <asm/errno.h>
10#include <asm/of_device.h>
11
12/**
13 * of_match_device - Tell if an of_device structure has a matching
14 * of_match structure
15 * @ids: array of of device match structures to search in
16 * @dev: the of device structure to match against
17 *
18 * Used by a driver to check whether an of_device present in the
19 * system is in its list of supported devices.
20 */
21const struct of_device_id *of_match_device(const struct of_device_id *matches,
22 const struct of_device *dev)
23{
24 if (!dev->node)
25 return NULL;
26 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
27 int match = 1;
28 if (matches->name[0])
29 match &= dev->node->name
30 && !strcmp(matches->name, dev->node->name);
31 if (matches->type[0])
32 match &= dev->node->type
33 && !strcmp(matches->type, dev->node->type);
34 if (matches->compatible[0])
35 match &= of_device_is_compatible(dev->node,
36 matches->compatible);
37 if (match)
38 return matches;
39 matches++;
40 }
41 return NULL;
42}
43
44static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
45{
46 struct of_device * of_dev = to_of_device(dev);
47 struct of_platform_driver * of_drv = to_of_platform_driver(drv);
48 const struct of_device_id * matches = of_drv->match_table;
49
50 if (!matches)
51 return 0;
52
53 return of_match_device(matches, of_dev) != NULL;
54}
55
56struct of_device *of_dev_get(struct of_device *dev)
57{
58 struct device *tmp;
59
60 if (!dev)
61 return NULL;
62 tmp = get_device(&dev->dev);
63 if (tmp)
64 return to_of_device(tmp);
65 else
66 return NULL;
67}
68
69void of_dev_put(struct of_device *dev)
70{
71 if (dev)
72 put_device(&dev->dev);
73}
74
75
76static int of_device_probe(struct device *dev)
77{
78 int error = -ENODEV;
79 struct of_platform_driver *drv;
80 struct of_device *of_dev;
81 const struct of_device_id *match;
82
83 drv = to_of_platform_driver(dev->driver);
84 of_dev = to_of_device(dev);
85
86 if (!drv->probe)
87 return error;
88
89 of_dev_get(of_dev);
90
91 match = of_match_device(drv->match_table, of_dev);
92 if (match)
93 error = drv->probe(of_dev, match);
94 if (error)
95 of_dev_put(of_dev);
96
97 return error;
98}
99
100static int of_device_remove(struct device *dev)
101{
102 struct of_device * of_dev = to_of_device(dev);
103 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
104
105 if (dev->driver && drv->remove)
106 drv->remove(of_dev);
107 return 0;
108}
109
110static int of_device_suspend(struct device *dev, pm_message_t state)
111{
112 struct of_device * of_dev = to_of_device(dev);
113 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
114 int error = 0;
115
116 if (dev->driver && drv->suspend)
117 error = drv->suspend(of_dev, state);
118 return error;
119}
120
121static int of_device_resume(struct device * dev)
122{
123 struct of_device * of_dev = to_of_device(dev);
124 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
125 int error = 0;
126
127 if (dev->driver && drv->resume)
128 error = drv->resume(of_dev);
129 return error;
130}
131
132#ifdef CONFIG_PCI
133struct bus_type ebus_bus_type = {
134 .name = "ebus",
135 .match = of_platform_bus_match,
136 .probe = of_device_probe,
137 .remove = of_device_remove,
138 .suspend = of_device_suspend,
139 .resume = of_device_resume,
140};
141#endif
142
143#ifdef CONFIG_SBUS
144struct bus_type sbus_bus_type = {
145 .name = "sbus",
146 .match = of_platform_bus_match,
147 .probe = of_device_probe,
148 .remove = of_device_remove,
149 .suspend = of_device_suspend,
150 .resume = of_device_resume,
151};
152#endif
153
154static int __init of_bus_driver_init(void)
155{
156 int err = 0;
157
158#ifdef CONFIG_PCI
159 if (!err)
160 err = bus_register(&ebus_bus_type);
161#endif
162#ifdef CONFIG_SBUS
163 if (!err)
164 err = bus_register(&sbus_bus_type);
165#endif
166 return 0;
167}
168
169postcore_initcall(of_bus_driver_init);
170
171int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
172{
173 /* initialize common driver fields */
174 drv->driver.name = drv->name;
175 drv->driver.bus = bus;
176
177 /* register with core */
178 return driver_register(&drv->driver);
179}
180
181void of_unregister_driver(struct of_platform_driver *drv)
182{
183 driver_unregister(&drv->driver);
184}
185
186
187static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
188{
189 struct of_device *ofdev;
190
191 ofdev = to_of_device(dev);
192 return sprintf(buf, "%s", ofdev->node->full_name);
193}
194
195static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
196
197/**
198 * of_release_dev - free an of device structure when all users of it are finished.
199 * @dev: device that's been disconnected
200 *
201 * Will be called only by the device core when all users of this of device are
202 * done.
203 */
204void of_release_dev(struct device *dev)
205{
206 struct of_device *ofdev;
207
208 ofdev = to_of_device(dev);
209
210 kfree(ofdev);
211}
212
213int of_device_register(struct of_device *ofdev)
214{
215 int rc;
216
217 BUG_ON(ofdev->node == NULL);
218
219 rc = device_register(&ofdev->dev);
220 if (rc)
221 return rc;
222
223 device_create_file(&ofdev->dev, &dev_attr_devspec);
224
225 return 0;
226}
227
228void of_device_unregister(struct of_device *ofdev)
229{
230 device_remove_file(&ofdev->dev, &dev_attr_devspec);
231 device_unregister(&ofdev->dev);
232}
233
234struct of_device* of_platform_device_create(struct device_node *np,
235 const char *bus_id,
236 struct device *parent,
237 struct bus_type *bus)
238{
239 struct of_device *dev;
240
241 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
242 if (!dev)
243 return NULL;
244 memset(dev, 0, sizeof(*dev));
245
246 dev->dev.parent = parent;
247 dev->dev.bus = bus;
248 dev->dev.release = of_release_dev;
249
250 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
251
252 if (of_device_register(dev) != 0) {
253 kfree(dev);
254 return NULL;
255 }
256
257 return dev;
258}
259
260EXPORT_SYMBOL(of_match_device);
261EXPORT_SYMBOL(of_register_driver);
262EXPORT_SYMBOL(of_unregister_driver);
263EXPORT_SYMBOL(of_device_register);
264EXPORT_SYMBOL(of_device_unregister);
265EXPORT_SYMBOL(of_dev_get);
266EXPORT_SYMBOL(of_dev_put);
267EXPORT_SYMBOL(of_platform_device_create);
268EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index bcdf5ad0f035..bcfdddd0418a 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -31,6 +31,7 @@
31 31
32#include <asm/irq.h> 32#include <asm/irq.h>
33#include <asm/oplib.h> 33#include <asm/oplib.h>
34#include <asm/prom.h>
34#include <asm/pcic.h> 35#include <asm/pcic.h>
35#include <asm/timer.h> 36#include <asm/timer.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -665,7 +666,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
665 /* cookies */ 666 /* cookies */
666 pcp = pci_devcookie_alloc(); 667 pcp = pci_devcookie_alloc();
667 pcp->pbm = &pcic->pbm; 668 pcp->pbm = &pcic->pbm;
668 pcp->prom_node = node; 669 pcp->prom_node = of_find_node_by_phandle(node);
669 dev->sysdata = pcp; 670 dev->sysdata = pcp;
670 671
671 /* fixing I/O to look like memory */ 672 /* fixing I/O to look like memory */
diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c
new file mode 100644
index 000000000000..63b2b9bd778e
--- /dev/null
+++ b/arch/sparc/kernel/prom.c
@@ -0,0 +1,474 @@
1/*
2 * Procedures for creating, accessing and interpreting the device tree.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * Adapted for sparc32 by David S. Miller davem@davemloft.net
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/bootmem.h>
23#include <linux/module.h>
24
25#include <asm/prom.h>
26#include <asm/oplib.h>
27
28static struct device_node *allnodes;
29
30int of_device_is_compatible(struct device_node *device, const char *compat)
31{
32 const char* cp;
33 int cplen, l;
34
35 cp = (char *) of_get_property(device, "compatible", &cplen);
36 if (cp == NULL)
37 return 0;
38 while (cplen > 0) {
39 if (strncmp(cp, compat, strlen(compat)) == 0)
40 return 1;
41 l = strlen(cp) + 1;
42 cp += l;
43 cplen -= l;
44 }
45
46 return 0;
47}
48EXPORT_SYMBOL(of_device_is_compatible);
49
50struct device_node *of_get_parent(const struct device_node *node)
51{
52 struct device_node *np;
53
54 if (!node)
55 return NULL;
56
57 np = node->parent;
58
59 return np;
60}
61EXPORT_SYMBOL(of_get_parent);
62
63struct device_node *of_get_next_child(const struct device_node *node,
64 struct device_node *prev)
65{
66 struct device_node *next;
67
68 next = prev ? prev->sibling : node->child;
69 for (; next != 0; next = next->sibling) {
70 break;
71 }
72
73 return next;
74}
75EXPORT_SYMBOL(of_get_next_child);
76
77struct device_node *of_find_node_by_path(const char *path)
78{
79 struct device_node *np = allnodes;
80
81 for (; np != 0; np = np->allnext) {
82 if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
83 break;
84 }
85
86 return np;
87}
88EXPORT_SYMBOL(of_find_node_by_path);
89
90struct device_node *of_find_node_by_phandle(phandle handle)
91{
92 struct device_node *np;
93
94 for (np = allnodes; np != 0; np = np->allnext)
95 if (np->node == handle)
96 break;
97
98 return np;
99}
100EXPORT_SYMBOL(of_find_node_by_phandle);
101
102struct device_node *of_find_node_by_name(struct device_node *from,
103 const char *name)
104{
105 struct device_node *np;
106
107 np = from ? from->allnext : allnodes;
108 for (; np != NULL; np = np->allnext)
109 if (np->name != NULL && strcmp(np->name, name) == 0)
110 break;
111
112 return np;
113}
114EXPORT_SYMBOL(of_find_node_by_name);
115
116struct device_node *of_find_node_by_type(struct device_node *from,
117 const char *type)
118{
119 struct device_node *np;
120
121 np = from ? from->allnext : allnodes;
122 for (; np != 0; np = np->allnext)
123 if (np->type != 0 && strcmp(np->type, type) == 0)
124 break;
125
126 return np;
127}
128EXPORT_SYMBOL(of_find_node_by_type);
129
130struct device_node *of_find_compatible_node(struct device_node *from,
131 const char *type, const char *compatible)
132{
133 struct device_node *np;
134
135 np = from ? from->allnext : allnodes;
136 for (; np != 0; np = np->allnext) {
137 if (type != NULL
138 && !(np->type != 0 && strcmp(np->type, type) == 0))
139 continue;
140 if (of_device_is_compatible(np, compatible))
141 break;
142 }
143
144 return np;
145}
146EXPORT_SYMBOL(of_find_compatible_node);
147
148struct property *of_find_property(struct device_node *np, const char *name,
149 int *lenp)
150{
151 struct property *pp;
152
153 for (pp = np->properties; pp != 0; pp = pp->next) {
154 if (strcmp(pp->name, name) == 0) {
155 if (lenp != 0)
156 *lenp = pp->length;
157 break;
158 }
159 }
160 return pp;
161}
162EXPORT_SYMBOL(of_find_property);
163
164/*
165 * Find a property with a given name for a given node
166 * and return the value.
167 */
168void *of_get_property(struct device_node *np, const char *name, int *lenp)
169{
170 struct property *pp = of_find_property(np,name,lenp);
171 return pp ? pp->value : NULL;
172}
173EXPORT_SYMBOL(of_get_property);
174
175int of_getintprop_default(struct device_node *np, const char *name, int def)
176{
177 struct property *prop;
178 int len;
179
180 prop = of_find_property(np, name, &len);
181 if (!prop || len != 4)
182 return def;
183
184 return *(int *) prop->value;
185}
186EXPORT_SYMBOL(of_getintprop_default);
187
188static unsigned int prom_early_allocated;
189
190static void * __init prom_early_alloc(unsigned long size)
191{
192 void *ret;
193
194 ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
195 if (ret != NULL)
196 memset(ret, 0, size);
197
198 prom_early_allocated += size;
199
200 return ret;
201}
202
203static int is_root_node(const struct device_node *dp)
204{
205 if (!dp)
206 return 0;
207
208 return (dp->parent == NULL);
209}
210
211/* The following routines deal with the black magic of fully naming a
212 * node.
213 *
214 * Certain well known named nodes are just the simple name string.
215 *
216 * Actual devices have an address specifier appended to the base name
217 * string, like this "foo@addr". The "addr" can be in any number of
218 * formats, and the platform plus the type of the node determine the
219 * format and how it is constructed.
220 *
221 * For children of the ROOT node, the naming convention is fixed and
222 * determined by whether this is a sun4u or sun4v system.
223 *
224 * For children of other nodes, it is bus type specific. So
225 * we walk up the tree until we discover a "device_type" property
226 * we recognize and we go from there.
227 */
228static void __init sparc32_path_component(struct device_node *dp, char *tmp_buf)
229{
230 struct linux_prom_registers *regs;
231 struct property *rprop;
232
233 rprop = of_find_property(dp, "reg", NULL);
234 if (!rprop)
235 return;
236
237 regs = rprop->value;
238 sprintf(tmp_buf, "%s@%x,%x",
239 dp->name,
240 regs->which_io, regs->phys_addr);
241}
242
243/* "name@slot,offset" */
244static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
245{
246 struct linux_prom_registers *regs;
247 struct property *prop;
248
249 prop = of_find_property(dp, "reg", NULL);
250 if (!prop)
251 return;
252
253 regs = prop->value;
254 sprintf(tmp_buf, "%s@%x,%x",
255 dp->name,
256 regs->which_io,
257 regs->phys_addr);
258}
259
260/* "name@devnum[,func]" */
261static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
262{
263 struct linux_prom_pci_registers *regs;
264 struct property *prop;
265 unsigned int devfn;
266
267 prop = of_find_property(dp, "reg", NULL);
268 if (!prop)
269 return;
270
271 regs = prop->value;
272 devfn = (regs->phys_hi >> 8) & 0xff;
273 if (devfn & 0x07) {
274 sprintf(tmp_buf, "%s@%x,%x",
275 dp->name,
276 devfn >> 3,
277 devfn & 0x07);
278 } else {
279 sprintf(tmp_buf, "%s@%x",
280 dp->name,
281 devfn >> 3);
282 }
283}
284
285/* "name@addrhi,addrlo" */
286static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
287{
288 struct linux_prom_registers *regs;
289 struct property *prop;
290
291 prop = of_find_property(dp, "reg", NULL);
292 if (!prop)
293 return;
294
295 regs = prop->value;
296
297 sprintf(tmp_buf, "%s@%x,%x",
298 dp->name,
299 regs->which_io, regs->phys_addr);
300}
301
302static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
303{
304 struct device_node *parent = dp->parent;
305
306 if (parent != NULL) {
307 if (!strcmp(parent->type, "pci") ||
308 !strcmp(parent->type, "pciex"))
309 return pci_path_component(dp, tmp_buf);
310 if (!strcmp(parent->type, "sbus"))
311 return sbus_path_component(dp, tmp_buf);
312 if (!strcmp(parent->type, "ebus"))
313 return ebus_path_component(dp, tmp_buf);
314
315 /* "isa" is handled with platform naming */
316 }
317
318 /* Use platform naming convention. */
319 return sparc32_path_component(dp, tmp_buf);
320}
321
322static char * __init build_path_component(struct device_node *dp)
323{
324 char tmp_buf[64], *n;
325
326 tmp_buf[0] = '\0';
327 __build_path_component(dp, tmp_buf);
328 if (tmp_buf[0] == '\0')
329 strcpy(tmp_buf, dp->name);
330
331 n = prom_early_alloc(strlen(tmp_buf) + 1);
332 strcpy(n, tmp_buf);
333
334 return n;
335}
336
337static char * __init build_full_name(struct device_node *dp)
338{
339 int len, ourlen, plen;
340 char *n;
341
342 plen = strlen(dp->parent->full_name);
343 ourlen = strlen(dp->path_component_name);
344 len = ourlen + plen + 2;
345
346 n = prom_early_alloc(len);
347 strcpy(n, dp->parent->full_name);
348 if (!is_root_node(dp->parent)) {
349 strcpy(n + plen, "/");
350 plen++;
351 }
352 strcpy(n + plen, dp->path_component_name);
353
354 return n;
355}
356
357static struct property * __init build_one_prop(phandle node, char *prev)
358{
359 static struct property *tmp = NULL;
360 struct property *p;
361 int len;
362
363 if (tmp) {
364 p = tmp;
365 memset(p, 0, sizeof(*p) + 32);
366 tmp = NULL;
367 } else
368 p = prom_early_alloc(sizeof(struct property) + 32);
369
370 p->name = (char *) (p + 1);
371 if (prev == NULL) {
372 prom_firstprop(node, p->name);
373 } else {
374 prom_nextprop(node, prev, p->name);
375 }
376 if (strlen(p->name) == 0) {
377 tmp = p;
378 return NULL;
379 }
380 p->length = prom_getproplen(node, p->name);
381 if (p->length <= 0) {
382 p->length = 0;
383 } else {
384 p->value = prom_early_alloc(p->length);
385 len = prom_getproperty(node, p->name, p->value, p->length);
386 }
387 return p;
388}
389
390static struct property * __init build_prop_list(phandle node)
391{
392 struct property *head, *tail;
393
394 head = tail = build_one_prop(node, NULL);
395 while(tail) {
396 tail->next = build_one_prop(node, tail->name);
397 tail = tail->next;
398 }
399
400 return head;
401}
402
403static char * __init get_one_property(phandle node, char *name)
404{
405 char *buf = "<NULL>";
406 int len;
407
408 len = prom_getproplen(node, name);
409 if (len > 0) {
410 buf = prom_early_alloc(len);
411 len = prom_getproperty(node, name, buf, len);
412 }
413
414 return buf;
415}
416
417static struct device_node * __init create_node(phandle node)
418{
419 struct device_node *dp;
420
421 if (!node)
422 return NULL;
423
424 dp = prom_early_alloc(sizeof(*dp));
425
426 kref_init(&dp->kref);
427
428 dp->name = get_one_property(node, "name");
429 dp->type = get_one_property(node, "device_type");
430 dp->node = node;
431
432 /* Build interrupts later... */
433
434 dp->properties = build_prop_list(node);
435
436 return dp;
437}
438
439static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
440{
441 struct device_node *dp;
442
443 dp = create_node(node);
444 if (dp) {
445 *(*nextp) = dp;
446 *nextp = &dp->allnext;
447
448 dp->parent = parent;
449 dp->path_component_name = build_path_component(dp);
450 dp->full_name = build_full_name(dp);
451
452 dp->child = build_tree(dp, prom_getchild(node), nextp);
453
454 dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
455 }
456
457 return dp;
458}
459
460void __init prom_build_devicetree(void)
461{
462 struct device_node **nextp;
463
464 allnodes = create_node(prom_root_node);
465 allnodes->path_component_name = "";
466 allnodes->full_name = "/";
467
468 nextp = &allnodes->allnext;
469 allnodes->child = build_tree(allnodes,
470 prom_getchild(allnodes->node),
471 &nextp);
472 printk("PROM: Built device tree with %u bytes of memory.\n",
473 prom_early_allocated);
474}
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index 898669732466..cfa7d3456634 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -31,6 +31,7 @@
31#include <asm/vaddrs.h> 31#include <asm/vaddrs.h>
32#include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */ 32#include <asm/pgalloc.h> /* bug in asm-generic/tlb.h: check_pgt_cache */
33#include <asm/tlb.h> 33#include <asm/tlb.h>
34#include <asm/prom.h>
34 35
35DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); 36DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
36 37
@@ -349,6 +350,7 @@ void __init paging_init(void)
349 protection_map[14] = PAGE_SHARED; 350 protection_map[14] = PAGE_SHARED;
350 protection_map[15] = PAGE_SHARED; 351 protection_map[15] = PAGE_SHARED;
351 btfixup(); 352 btfixup();
353 prom_build_devicetree();
352 device_scan(); 354 device_scan();
353} 355}
354 356
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 9da75f89fe2c..b2f41147d0e4 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.17 3# Linux kernel version: 2.6.17
4# Tue Jun 20 01:26:43 2006 4# Fri Jun 23 23:17:09 2006
5# 5#
6CONFIG_SPARC=y 6CONFIG_SPARC=y
7CONFIG_SPARC64=y 7CONFIG_SPARC64=y
@@ -286,6 +286,7 @@ CONFIG_STANDALONE=y
286# CONFIG_PREVENT_FIRMWARE_BUILD is not set 286# CONFIG_PREVENT_FIRMWARE_BUILD is not set
287CONFIG_FW_LOADER=y 287CONFIG_FW_LOADER=y
288# CONFIG_DEBUG_DRIVER is not set 288# CONFIG_DEBUG_DRIVER is not set
289# CONFIG_SYS_HYPERVISOR is not set
289 290
290# 291#
291# Connector - unified userspace <-> kernelspace linker 292# Connector - unified userspace <-> kernelspace linker
@@ -434,6 +435,7 @@ CONFIG_ISCSI_TCP=m
434# CONFIG_MEGARAID_LEGACY is not set 435# CONFIG_MEGARAID_LEGACY is not set
435# CONFIG_MEGARAID_SAS is not set 436# CONFIG_MEGARAID_SAS is not set
436# CONFIG_SCSI_SATA is not set 437# CONFIG_SCSI_SATA is not set
438# CONFIG_SCSI_HPTIOP is not set
437# CONFIG_SCSI_DMX3191D is not set 439# CONFIG_SCSI_DMX3191D is not set
438# CONFIG_SCSI_FUTURE_DOMAIN is not set 440# CONFIG_SCSI_FUTURE_DOMAIN is not set
439# CONFIG_SCSI_IPS is not set 441# CONFIG_SCSI_IPS is not set
@@ -733,6 +735,7 @@ CONFIG_I2C_ALGOBIT=y
733# CONFIG_I2C_I810 is not set 735# CONFIG_I2C_I810 is not set
734# CONFIG_I2C_PIIX4 is not set 736# CONFIG_I2C_PIIX4 is not set
735# CONFIG_I2C_NFORCE2 is not set 737# CONFIG_I2C_NFORCE2 is not set
738# CONFIG_I2C_OCORES is not set
736# CONFIG_I2C_PARPORT_LIGHT is not set 739# CONFIG_I2C_PARPORT_LIGHT is not set
737# CONFIG_I2C_PROSAVAGE is not set 740# CONFIG_I2C_PROSAVAGE is not set
738# CONFIG_I2C_SAVAGE4 is not set 741# CONFIG_I2C_SAVAGE4 is not set
@@ -776,6 +779,7 @@ CONFIG_I2C_ALGOBIT=y
776# 779#
777CONFIG_HWMON=y 780CONFIG_HWMON=y
778# CONFIG_HWMON_VID is not set 781# CONFIG_HWMON_VID is not set
782# CONFIG_SENSORS_ABITUGURU is not set
779# CONFIG_SENSORS_ADM1021 is not set 783# CONFIG_SENSORS_ADM1021 is not set
780# CONFIG_SENSORS_ADM1025 is not set 784# CONFIG_SENSORS_ADM1025 is not set
781# CONFIG_SENSORS_ADM1026 is not set 785# CONFIG_SENSORS_ADM1026 is not set
@@ -804,10 +808,12 @@ CONFIG_HWMON=y
804# CONFIG_SENSORS_PC87360 is not set 808# CONFIG_SENSORS_PC87360 is not set
805# CONFIG_SENSORS_SIS5595 is not set 809# CONFIG_SENSORS_SIS5595 is not set
806# CONFIG_SENSORS_SMSC47M1 is not set 810# CONFIG_SENSORS_SMSC47M1 is not set
811# CONFIG_SENSORS_SMSC47M192 is not set
807# CONFIG_SENSORS_SMSC47B397 is not set 812# CONFIG_SENSORS_SMSC47B397 is not set
808# CONFIG_SENSORS_VIA686A is not set 813# CONFIG_SENSORS_VIA686A is not set
809# CONFIG_SENSORS_VT8231 is not set 814# CONFIG_SENSORS_VT8231 is not set
810# CONFIG_SENSORS_W83781D is not set 815# CONFIG_SENSORS_W83781D is not set
816# CONFIG_SENSORS_W83791D is not set
811# CONFIG_SENSORS_W83792D is not set 817# CONFIG_SENSORS_W83792D is not set
812# CONFIG_SENSORS_W83L785TS is not set 818# CONFIG_SENSORS_W83L785TS is not set
813# CONFIG_SENSORS_W83627HF is not set 819# CONFIG_SENSORS_W83627HF is not set
@@ -1018,6 +1024,7 @@ CONFIG_USB_DEVICEFS=y
1018CONFIG_USB_EHCI_HCD=m 1024CONFIG_USB_EHCI_HCD=m
1019# CONFIG_USB_EHCI_SPLIT_ISO is not set 1025# CONFIG_USB_EHCI_SPLIT_ISO is not set
1020# CONFIG_USB_EHCI_ROOT_HUB_TT is not set 1026# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1027# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1021# CONFIG_USB_ISP116X_HCD is not set 1028# CONFIG_USB_ISP116X_HCD is not set
1022CONFIG_USB_OHCI_HCD=y 1029CONFIG_USB_OHCI_HCD=y
1023# CONFIG_USB_OHCI_BIG_ENDIAN is not set 1030# CONFIG_USB_OHCI_BIG_ENDIAN is not set
@@ -1097,10 +1104,12 @@ CONFIG_USB_HIDDEV=y
1097# CONFIG_USB_LEGOTOWER is not set 1104# CONFIG_USB_LEGOTOWER is not set
1098# CONFIG_USB_LCD is not set 1105# CONFIG_USB_LCD is not set
1099# CONFIG_USB_LED is not set 1106# CONFIG_USB_LED is not set
1107# CONFIG_USB_CY7C63 is not set
1100# CONFIG_USB_CYTHERM is not set 1108# CONFIG_USB_CYTHERM is not set
1101# CONFIG_USB_PHIDGETKIT is not set 1109# CONFIG_USB_PHIDGETKIT is not set
1102# CONFIG_USB_PHIDGETSERVO is not set 1110# CONFIG_USB_PHIDGETSERVO is not set
1103# CONFIG_USB_IDMOUSE is not set 1111# CONFIG_USB_IDMOUSE is not set
1112# CONFIG_USB_APPLEDISPLAY is not set
1104# CONFIG_USB_SISUSBVGA is not set 1113# CONFIG_USB_SISUSBVGA is not set
1105# CONFIG_USB_LD is not set 1114# CONFIG_USB_LD is not set
1106# CONFIG_USB_TEST is not set 1115# CONFIG_USB_TEST is not set
@@ -1198,6 +1207,7 @@ CONFIG_FS_POSIX_ACL=y
1198# CONFIG_MINIX_FS is not set 1207# CONFIG_MINIX_FS is not set
1199# CONFIG_ROMFS_FS is not set 1208# CONFIG_ROMFS_FS is not set
1200CONFIG_INOTIFY=y 1209CONFIG_INOTIFY=y
1210CONFIG_INOTIFY_USER=y
1201# CONFIG_QUOTA is not set 1211# CONFIG_QUOTA is not set
1202CONFIG_DNOTIFY=y 1212CONFIG_DNOTIFY=y
1203# CONFIG_AUTOFS_FS is not set 1213# CONFIG_AUTOFS_FS is not set
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile
index 6f6816488b04..86c9fe3f3e4a 100644
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -12,7 +12,7 @@ obj-y := process.o setup.o cpu.o idprom.o \
12 irq.o ptrace.o time.o sys_sparc.o signal.o \ 12 irq.o ptrace.o time.o sys_sparc.o signal.o \
13 unaligned.o central.o pci.o starfire.o semaphore.o \ 13 unaligned.o central.o pci.o starfire.o semaphore.o \
14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ 14 power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \
15 visemul.o 15 visemul.o prom.o of_device.o
16 16
17obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \ 17obj-$(CONFIG_PCI) += ebus.o isa.o pci_common.o pci_iommu.o \
18 pci_psycho.o pci_sabre.o pci_schizo.o \ 18 pci_psycho.o pci_sabre.o pci_schizo.o \
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
index 8852c20c8d99..2c42894b188f 100644
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -110,43 +110,82 @@ void auxio_set_lte(int on)
110 } 110 }
111} 111}
112 112
113void __init auxio_probe(void) 113static void __devinit auxio_report_dev(struct device_node *dp)
114{ 114{
115 struct sbus_bus *sbus; 115 printk(KERN_INFO "AUXIO: Found device at %s\n",
116 struct sbus_dev *sdev = NULL; 116 dp->full_name);
117 117}
118 for_each_sbus(sbus) { 118
119 for_each_sbusdev(sdev, sbus) { 119static struct of_device_id auxio_match[] = {
120 if(!strcmp(sdev->prom_name, "auxio")) 120 {
121 goto found_sdev; 121 .name = "auxio",
122 } 122 },
123 } 123 {},
124 124};
125found_sdev: 125
126 if (sdev) { 126MODULE_DEVICE_TABLE(of, auxio_match);
127 auxio_devtype = AUXIO_TYPE_SBUS; 127
128 auxio_register = sbus_ioremap(&sdev->resource[0], 0, 128#ifdef CONFIG_SBUS
129 sdev->reg_addrs[0].reg_size, 129static int __devinit auxio_sbus_probe(struct of_device *dev, const struct of_device_id *match)
130 "auxiliaryIO"); 130{
131 } 131 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
132
133 auxio_devtype = AUXIO_TYPE_SBUS;
134 auxio_register = sbus_ioremap(&sdev->resource[0], 0,
135 sdev->reg_addrs[0].reg_size,
136 "auxiliaryIO");
137 if (!auxio_register)
138 return -ENODEV;
139
140 auxio_report_dev(dev->node);
141 return 0;
142}
143
144static struct of_platform_driver auxio_sbus_driver = {
145 .name = "auxio",
146 .match_table = auxio_match,
147 .probe = auxio_sbus_probe,
148};
149#endif
150
132#ifdef CONFIG_PCI 151#ifdef CONFIG_PCI
133 else { 152static int __devinit auxio_ebus_probe(struct of_device *dev, const struct of_device_id *match)
134 struct linux_ebus *ebus; 153{
135 struct linux_ebus_device *edev = NULL; 154 struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
136 155
137 for_each_ebus(ebus) { 156 auxio_devtype = AUXIO_TYPE_EBUS;
138 for_each_ebusdev(edev, ebus) { 157 auxio_register = ioremap(edev->resource[0].start, sizeof(u32));
139 if (!strcmp(edev->prom_name, "auxio")) 158 if (!auxio_register)
140 goto ebus_done; 159 return -ENODEV;
141 } 160
142 } 161 auxio_report_dev(dev->node);
143 ebus_done: 162
144 if (edev) {
145 auxio_devtype = AUXIO_TYPE_EBUS;
146 auxio_register =
147 ioremap(edev->resource[0].start, sizeof(u32));
148 }
149 }
150 auxio_set_led(AUXIO_LED_ON); 163 auxio_set_led(AUXIO_LED_ON);
164
165 return 0;
166}
167
168static struct of_platform_driver auxio_ebus_driver = {
169 .name = "auxio",
170 .match_table = auxio_match,
171 .probe = auxio_ebus_probe,
172};
151#endif 173#endif
174
175static int __init auxio_probe(void)
176{
177#ifdef CONFIG_SBUS
178 of_register_driver(&auxio_sbus_driver, &sbus_bus_type);
179#endif
180#ifdef CONFIG_PCI
181 of_register_driver(&auxio_ebus_driver, &ebus_bus_type);
182#endif
183
184 return 0;
152} 185}
186
187/* Must be after subsys_initcall() so that busses are probed. Must
188 * be before device_initcall() because things like the floppy driver
189 * need to use the AUXIO register.
190 */
191fs_initcall(auxio_probe);
diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c
index 3d184a784968..b66336db00ee 100644
--- a/arch/sparc64/kernel/central.c
+++ b/arch/sparc64/kernel/central.c
@@ -29,28 +29,34 @@ static void central_probe_failure(int line)
29 prom_halt(); 29 prom_halt();
30} 30}
31 31
32static void central_ranges_init(int cnode, struct linux_central *central) 32static void central_ranges_init(struct linux_central *central)
33{ 33{
34 int success; 34 struct device_node *dp = central->prom_node;
35 void *pval;
36 int len;
35 37
36 central->num_central_ranges = 0; 38 central->num_central_ranges = 0;
37 success = prom_getproperty(central->prom_node, "ranges", 39 pval = of_get_property(dp, "ranges", &len);
38 (char *) central->central_ranges, 40 if (pval) {
39 sizeof (central->central_ranges)); 41 memcpy(central->central_ranges, pval, len);
40 if (success != -1) 42 central->num_central_ranges =
41 central->num_central_ranges = (success/sizeof(struct linux_prom_ranges)); 43 (len / sizeof(struct linux_prom_ranges));
44 }
42} 45}
43 46
44static void fhc_ranges_init(int fnode, struct linux_fhc *fhc) 47static void fhc_ranges_init(struct linux_fhc *fhc)
45{ 48{
46 int success; 49 struct device_node *dp = fhc->prom_node;
50 void *pval;
51 int len;
47 52
48 fhc->num_fhc_ranges = 0; 53 fhc->num_fhc_ranges = 0;
49 success = prom_getproperty(fhc->prom_node, "ranges", 54 pval = of_get_property(dp, "ranges", &len);
50 (char *) fhc->fhc_ranges, 55 if (pval) {
51 sizeof (fhc->fhc_ranges)); 56 memcpy(fhc->fhc_ranges, pval, len);
52 if (success != -1) 57 fhc->num_fhc_ranges =
53 fhc->num_fhc_ranges = (success/sizeof(struct linux_prom_ranges)); 58 (len / sizeof(struct linux_prom_ranges));
59 }
54} 60}
55 61
56/* Range application routines are exported to various drivers, 62/* Range application routines are exported to various drivers,
@@ -112,15 +118,10 @@ static unsigned long prom_reg_to_paddr(struct linux_prom_registers *r)
112 118
113static void probe_other_fhcs(void) 119static void probe_other_fhcs(void)
114{ 120{
115 struct linux_prom64_registers fpregs[6]; 121 struct device_node *dp;
116 char namebuf[128]; 122 struct linux_prom64_registers *fpregs;
117 int node;
118 123
119 node = prom_getchild(prom_root_node); 124 for_each_node_by_name(dp, "fhc") {
120 node = prom_searchsiblings(node, "fhc");
121 if (node == 0)
122 central_probe_failure(__LINE__);
123 while (node) {
124 struct linux_fhc *fhc; 125 struct linux_fhc *fhc;
125 int board; 126 int board;
126 u32 tmp; 127 u32 tmp;
@@ -137,14 +138,12 @@ static void probe_other_fhcs(void)
137 /* Toplevel FHCs have no parent. */ 138 /* Toplevel FHCs have no parent. */
138 fhc->parent = NULL; 139 fhc->parent = NULL;
139 140
140 fhc->prom_node = node; 141 fhc->prom_node = dp;
141 prom_getstring(node, "name", namebuf, sizeof(namebuf)); 142 fhc_ranges_init(fhc);
142 strcpy(fhc->prom_name, namebuf);
143 fhc_ranges_init(node, fhc);
144 143
145 /* Non-central FHC's have 64-bit OBP format registers. */ 144 /* Non-central FHC's have 64-bit OBP format registers. */
146 if (prom_getproperty(node, "reg", 145 fpregs = of_get_property(dp, "reg", NULL);
147 (char *)&fpregs[0], sizeof(fpregs)) == -1) 146 if (!fpregs)
148 central_probe_failure(__LINE__); 147 central_probe_failure(__LINE__);
149 148
150 /* Only central FHC needs special ranges applied. */ 149 /* Only central FHC needs special ranges applied. */
@@ -155,7 +154,7 @@ static void probe_other_fhcs(void)
155 fhc->fhc_regs.uregs = fpregs[4].phys_addr; 154 fhc->fhc_regs.uregs = fpregs[4].phys_addr;
156 fhc->fhc_regs.tregs = fpregs[5].phys_addr; 155 fhc->fhc_regs.tregs = fpregs[5].phys_addr;
157 156
158 board = prom_getintdefault(node, "board#", -1); 157 board = of_getintprop_default(dp, "board#", -1);
159 fhc->board = board; 158 fhc->board = board;
160 159
161 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL); 160 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_JCTRL);
@@ -179,33 +178,33 @@ static void probe_other_fhcs(void)
179 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL); 178 tmp = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
180 tmp |= FHC_CONTROL_IXIST; 179 tmp |= FHC_CONTROL_IXIST;
181 upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL); 180 upa_writel(tmp, fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
182
183 /* Look for the next FHC. */
184 node = prom_getsibling(node);
185 if (node == 0)
186 break;
187 node = prom_searchsiblings(node, "fhc");
188 if (node == 0)
189 break;
190 } 181 }
191} 182}
192 183
193static void probe_clock_board(struct linux_central *central, 184static void probe_clock_board(struct linux_central *central,
194 struct linux_fhc *fhc, 185 struct linux_fhc *fhc,
195 int cnode, int fnode) 186 struct device_node *fp)
196{ 187{
197 struct linux_prom_registers cregs[3]; 188 struct device_node *dp;
198 int clknode, nslots, tmp, nregs; 189 struct linux_prom_registers cregs[3], *pr;
190 int nslots, tmp, nregs;
199 191
200 clknode = prom_searchsiblings(prom_getchild(fnode), "clock-board"); 192 dp = fp->child;
201 if (clknode == 0 || clknode == -1) 193 while (dp) {
194 if (!strcmp(dp->name, "clock-board"))
195 break;
196 dp = dp->sibling;
197 }
198 if (!dp)
202 central_probe_failure(__LINE__); 199 central_probe_failure(__LINE__);
203 200
204 nregs = prom_getproperty(clknode, "reg", (char *)&cregs[0], sizeof(cregs)); 201 pr = of_get_property(dp, "reg", &nregs);
205 if (nregs == -1) 202 if (!pr)
206 central_probe_failure(__LINE__); 203 central_probe_failure(__LINE__);
207 204
205 memcpy(cregs, pr, nregs);
208 nregs /= sizeof(struct linux_prom_registers); 206 nregs /= sizeof(struct linux_prom_registers);
207
209 apply_fhc_ranges(fhc, &cregs[0], nregs); 208 apply_fhc_ranges(fhc, &cregs[0], nregs);
210 apply_central_ranges(central, &cregs[0], nregs); 209 apply_central_ranges(central, &cregs[0], nregs);
211 central->cfreg = prom_reg_to_paddr(&cregs[0]); 210 central->cfreg = prom_reg_to_paddr(&cregs[0]);
@@ -296,13 +295,13 @@ static void init_all_fhc_hw(void)
296 295
297void central_probe(void) 296void central_probe(void)
298{ 297{
299 struct linux_prom_registers fpregs[6]; 298 struct linux_prom_registers fpregs[6], *pr;
300 struct linux_fhc *fhc; 299 struct linux_fhc *fhc;
301 char namebuf[128]; 300 struct device_node *dp, *fp;
302 int cnode, fnode, err; 301 int err;
303 302
304 cnode = prom_finddevice("/central"); 303 dp = of_find_node_by_name(NULL, "central");
305 if (cnode == 0 || cnode == -1) { 304 if (!dp) {
306 if (this_is_starfire) 305 if (this_is_starfire)
307 starfire_cpu_setup(); 306 starfire_cpu_setup();
308 return; 307 return;
@@ -321,31 +320,31 @@ void central_probe(void)
321 320
322 /* First init central. */ 321 /* First init central. */
323 central_bus->child = fhc; 322 central_bus->child = fhc;
324 central_bus->prom_node = cnode; 323 central_bus->prom_node = dp;
325 324 central_ranges_init(central_bus);
326 prom_getstring(cnode, "name", namebuf, sizeof(namebuf));
327 strcpy(central_bus->prom_name, namebuf);
328
329 central_ranges_init(cnode, central_bus);
330 325
331 /* And then central's FHC. */ 326 /* And then central's FHC. */
332 fhc->next = fhc_list; 327 fhc->next = fhc_list;
333 fhc_list = fhc; 328 fhc_list = fhc;
334 329
335 fhc->parent = central_bus; 330 fhc->parent = central_bus;
336 fnode = prom_searchsiblings(prom_getchild(cnode), "fhc"); 331 fp = dp->child;
337 if (fnode == 0 || fnode == -1) 332 while (fp) {
333 if (!strcmp(fp->name, "fhc"))
334 break;
335 fp = fp->sibling;
336 }
337 if (!fp)
338 central_probe_failure(__LINE__); 338 central_probe_failure(__LINE__);
339 339
340 fhc->prom_node = fnode; 340 fhc->prom_node = fp;
341 prom_getstring(fnode, "name", namebuf, sizeof(namebuf)); 341 fhc_ranges_init(fhc);
342 strcpy(fhc->prom_name, namebuf);
343
344 fhc_ranges_init(fnode, fhc);
345 342
346 /* Now, map in FHC register set. */ 343 /* Now, map in FHC register set. */
347 if (prom_getproperty(fnode, "reg", (char *)&fpregs[0], sizeof(fpregs)) == -1) 344 pr = of_get_property(fp, "reg", NULL);
345 if (!pr)
348 central_probe_failure(__LINE__); 346 central_probe_failure(__LINE__);
347 memcpy(fpregs, pr, sizeof(fpregs));
349 348
350 apply_central_ranges(central_bus, &fpregs[0], 6); 349 apply_central_ranges(central_bus, &fpregs[0], 6);
351 350
@@ -366,7 +365,7 @@ void central_probe(void)
366 fhc->jtag_master = 0; 365 fhc->jtag_master = 0;
367 366
368 /* Attach the clock board registers for CENTRAL. */ 367 /* Attach the clock board registers for CENTRAL. */
369 probe_clock_board(central_bus, fhc, cnode, fnode); 368 probe_clock_board(central_bus, fhc, fp);
370 369
371 err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID); 370 err = upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_ID);
372 printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n", 371 printk("FHC(board %d): Version[%x] PartID[%x] Manuf[%x] (CENTRAL)\n",
diff --git a/arch/sparc64/kernel/chmc.c b/arch/sparc64/kernel/chmc.c
index 97cf912f0853..259f37e516f5 100644
--- a/arch/sparc64/kernel/chmc.c
+++ b/arch/sparc64/kernel/chmc.c
@@ -17,6 +17,7 @@
17#include <asm/spitfire.h> 17#include <asm/spitfire.h>
18#include <asm/chmctrl.h> 18#include <asm/chmctrl.h>
19#include <asm/oplib.h> 19#include <asm/oplib.h>
20#include <asm/prom.h>
20#include <asm/io.h> 21#include <asm/io.h>
21 22
22#define CHMCTRL_NDGRPS 2 23#define CHMCTRL_NDGRPS 2
@@ -67,7 +68,6 @@ struct bank_info {
67struct mctrl_info { 68struct mctrl_info {
68 struct list_head list; 69 struct list_head list;
69 int portid; 70 int portid;
70 int index;
71 71
72 struct obp_mem_layout layout_prop; 72 struct obp_mem_layout layout_prop;
73 int layout_size; 73 int layout_size;
@@ -339,12 +339,13 @@ static void fetch_decode_regs(struct mctrl_info *mp)
339 read_mcreg(mp, CHMCTRL_DECODE4)); 339 read_mcreg(mp, CHMCTRL_DECODE4));
340} 340}
341 341
342static int init_one_mctrl(int node, int index) 342static int init_one_mctrl(struct device_node *dp)
343{ 343{
344 struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL); 344 struct mctrl_info *mp = kmalloc(sizeof(*mp), GFP_KERNEL);
345 int portid = prom_getintdefault(node, "portid", -1); 345 int portid = of_getintprop_default(dp, "portid", -1);
346 struct linux_prom64_registers p_reg_prop; 346 struct linux_prom64_registers *regs;
347 int t; 347 void *pval;
348 int len;
348 349
349 if (!mp) 350 if (!mp)
350 return -1; 351 return -1;
@@ -353,24 +354,21 @@ static int init_one_mctrl(int node, int index)
353 goto fail; 354 goto fail;
354 355
355 mp->portid = portid; 356 mp->portid = portid;
356 mp->layout_size = prom_getproplen(node, "memory-layout"); 357 pval = of_get_property(dp, "memory-layout", &len);
357 if (mp->layout_size < 0) 358 mp->layout_size = len;
359 if (!pval)
358 mp->layout_size = 0; 360 mp->layout_size = 0;
359 if (mp->layout_size > sizeof(mp->layout_prop)) 361 else {
360 goto fail; 362 if (mp->layout_size > sizeof(mp->layout_prop))
361 363 goto fail;
362 if (mp->layout_size > 0) 364 memcpy(&mp->layout_prop, pval, len);
363 prom_getproperty(node, "memory-layout", 365 }
364 (char *) &mp->layout_prop,
365 mp->layout_size);
366 366
367 t = prom_getproperty(node, "reg", 367 regs = of_get_property(dp, "reg", NULL);
368 (char *) &p_reg_prop, 368 if (!regs || regs->reg_size != 0x48)
369 sizeof(p_reg_prop));
370 if (t < 0 || p_reg_prop.reg_size != 0x48)
371 goto fail; 369 goto fail;
372 370
373 mp->regs = ioremap(p_reg_prop.phys_addr, p_reg_prop.reg_size); 371 mp->regs = ioremap(regs->phys_addr, regs->reg_size);
374 if (mp->regs == NULL) 372 if (mp->regs == NULL)
375 goto fail; 373 goto fail;
376 374
@@ -384,13 +382,11 @@ static int init_one_mctrl(int node, int index)
384 382
385 fetch_decode_regs(mp); 383 fetch_decode_regs(mp);
386 384
387 mp->index = index;
388
389 list_add(&mp->list, &mctrl_list); 385 list_add(&mp->list, &mctrl_list);
390 386
391 /* Report the device. */ 387 /* Report the device. */
392 printk(KERN_INFO "chmc%d: US3 memory controller at %p [%s]\n", 388 printk(KERN_INFO "%s: US3 memory controller at %p [%s]\n",
393 mp->index, 389 dp->full_name,
394 mp->regs, (mp->layout_size ? "ACTIVE" : "INACTIVE")); 390 mp->regs, (mp->layout_size ? "ACTIVE" : "INACTIVE"));
395 391
396 return 0; 392 return 0;
@@ -404,34 +400,19 @@ fail:
404 return -1; 400 return -1;
405} 401}
406 402
407static int __init probe_for_string(char *name, int index)
408{
409 int node = prom_getchild(prom_root_node);
410
411 while ((node = prom_searchsiblings(node, name)) != 0) {
412 int ret = init_one_mctrl(node, index);
413
414 if (!ret)
415 index++;
416
417 node = prom_getsibling(node);
418 if (!node)
419 break;
420 }
421
422 return index;
423}
424
425static int __init chmc_init(void) 403static int __init chmc_init(void)
426{ 404{
427 int index; 405 struct device_node *dp;
428 406
429 /* This driver is only for cheetah platforms. */ 407 /* This driver is only for cheetah platforms. */
430 if (tlb_type != cheetah && tlb_type != cheetah_plus) 408 if (tlb_type != cheetah && tlb_type != cheetah_plus)
431 return -ENODEV; 409 return -ENODEV;
432 410
433 index = probe_for_string("memory-controller", 0); 411 for_each_node_by_name(dp, "memory-controller")
434 index = probe_for_string("mc-us3", index); 412 init_one_mctrl(dp);
413
414 for_each_node_by_name(dp, "mc-us3")
415 init_one_mctrl(dp);
435 416
436 return 0; 417 return 0;
437} 418}
diff --git a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
index 0dd95ae50e12..389301c95cb2 100644
--- a/arch/sparc64/kernel/devices.c
+++ b/arch/sparc64/kernel/devices.c
@@ -33,7 +33,7 @@ extern void cpu_probe(void);
33extern void central_probe(void); 33extern void central_probe(void);
34 34
35u32 sun4v_vdev_devhandle; 35u32 sun4v_vdev_devhandle;
36int sun4v_vdev_root; 36struct device_node *sun4v_vdev_root;
37 37
38struct vdev_intmap { 38struct vdev_intmap {
39 unsigned int phys; 39 unsigned int phys;
@@ -50,102 +50,68 @@ struct vdev_intmask {
50 50
51static struct vdev_intmap *vdev_intmap; 51static struct vdev_intmap *vdev_intmap;
52static int vdev_num_intmap; 52static int vdev_num_intmap;
53static struct vdev_intmask vdev_intmask; 53static struct vdev_intmask *vdev_intmask;
54 54
55static void __init sun4v_virtual_device_probe(void) 55static void __init sun4v_virtual_device_probe(void)
56{ 56{
57 struct linux_prom64_registers regs; 57 struct linux_prom64_registers *regs;
58 struct vdev_intmap *ip; 58 struct property *prop;
59 int node, sz, err; 59 struct device_node *dp;
60 int sz;
60 61
61 if (tlb_type != hypervisor) 62 if (tlb_type != hypervisor)
62 return; 63 return;
63 64
64 node = prom_getchild(prom_root_node); 65 dp = of_find_node_by_name(NULL, "virtual-devices");
65 node = prom_searchsiblings(node, "virtual-devices"); 66 if (!dp) {
66 if (!node) {
67 prom_printf("SUN4V: Fatal error, no virtual-devices node.\n"); 67 prom_printf("SUN4V: Fatal error, no virtual-devices node.\n");
68 prom_halt(); 68 prom_halt();
69 } 69 }
70 70
71 sun4v_vdev_root = node; 71 sun4v_vdev_root = dp;
72 72
73 prom_getproperty(node, "reg", (char *)&regs, sizeof(regs)); 73 prop = of_find_property(dp, "reg", NULL);
74 sun4v_vdev_devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; 74 regs = prop->value;
75 sun4v_vdev_devhandle = (regs[0].phys_addr >> 32UL) & 0x0fffffff;
75 76
76 sz = prom_getproplen(node, "interrupt-map"); 77 prop = of_find_property(dp, "interrupt-map", &sz);
77 if (sz <= 0) { 78 vdev_intmap = prop->value;
78 prom_printf("SUN4V: Error, no vdev interrupt-map.\n"); 79 vdev_num_intmap = sz / sizeof(struct vdev_intmap);
79 prom_halt();
80 }
81
82 if ((sz % sizeof(*ip)) != 0) {
83 prom_printf("SUN4V: Bogus interrupt-map property size %d\n",
84 sz);
85 prom_halt();
86 }
87
88 vdev_intmap = ip = alloc_bootmem_low_pages(sz);
89 if (!vdev_intmap) {
90 prom_printf("SUN4V: Error, cannot allocate vdev_intmap.\n");
91 prom_halt();
92 }
93
94 err = prom_getproperty(node, "interrupt-map", (char *) ip, sz);
95 if (err == -1) {
96 prom_printf("SUN4V: Fatal error, no vdev interrupt-map.\n");
97 prom_halt();
98 }
99 if (err != sz) {
100 prom_printf("SUN4V: Inconsistent interrupt-map size, "
101 "proplen(%d) vs getprop(%d).\n", sz,err);
102 prom_halt();
103 }
104
105 vdev_num_intmap = err / sizeof(*ip);
106 80
107 err = prom_getproperty(node, "interrupt-map-mask", 81 prop = of_find_property(dp, "interrupt-map-mask", NULL);
108 (char *) &vdev_intmask, 82 vdev_intmask = prop->value;
109 sizeof(vdev_intmask));
110 if (err <= 0) {
111 prom_printf("SUN4V: Fatal error, no vdev "
112 "interrupt-map-mask.\n");
113 prom_halt();
114 }
115 if (err % sizeof(vdev_intmask)) {
116 prom_printf("SUN4V: Bogus interrupt-map-mask "
117 "property size %d\n", err);
118 prom_halt();
119 }
120 83
121 printk("SUN4V: virtual-devices devhandle[%x]\n", 84 printk("%s: Virtual Device Bus devhandle[%x]\n",
122 sun4v_vdev_devhandle); 85 dp->full_name, sun4v_vdev_devhandle);
123} 86}
124 87
125unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node) 88unsigned int sun4v_vdev_device_interrupt(struct device_node *dev_node)
126{ 89{
90 struct property *prop;
127 unsigned int irq, reg; 91 unsigned int irq, reg;
128 int err, i; 92 int i;
129 93
130 err = prom_getproperty(dev_node, "interrupts", 94 prop = of_find_property(dev_node, "interrupts", NULL);
131 (char *) &irq, sizeof(irq)); 95 if (!prop) {
132 if (err <= 0) {
133 printk("VDEV: Cannot get \"interrupts\" " 96 printk("VDEV: Cannot get \"interrupts\" "
134 "property for OBP node %x\n", dev_node); 97 "property for OBP node %s\n",
98 dev_node->full_name);
135 return 0; 99 return 0;
136 } 100 }
101 irq = *(unsigned int *) prop->value;
137 102
138 err = prom_getproperty(dev_node, "reg", 103 prop = of_find_property(dev_node, "reg", NULL);
139 (char *) &reg, sizeof(reg)); 104 if (!prop) {
140 if (err <= 0) {
141 printk("VDEV: Cannot get \"reg\" " 105 printk("VDEV: Cannot get \"reg\" "
142 "property for OBP node %x\n", dev_node); 106 "property for OBP node %s\n",
107 dev_node->full_name);
143 return 0; 108 return 0;
144 } 109 }
110 reg = *(unsigned int *) prop->value;
145 111
146 for (i = 0; i < vdev_num_intmap; i++) { 112 for (i = 0; i < vdev_num_intmap; i++) {
147 if (vdev_intmap[i].phys == (reg & vdev_intmask.phys) && 113 if (vdev_intmap[i].phys == (reg & vdev_intmask->phys) &&
148 vdev_intmap[i].irq == (irq & vdev_intmask.interrupt)) { 114 vdev_intmap[i].irq == (irq & vdev_intmask->interrupt)) {
149 irq = vdev_intmap[i].cinterrupt; 115 irq = vdev_intmap[i].cinterrupt;
150 break; 116 break;
151 } 117 }
@@ -153,7 +119,7 @@ unsigned int sun4v_vdev_device_interrupt(unsigned int dev_node)
153 119
154 if (i == vdev_num_intmap) { 120 if (i == vdev_num_intmap) {
155 printk("VDEV: No matching interrupt map entry " 121 printk("VDEV: No matching interrupt map entry "
156 "for OBP node %x\n", dev_node); 122 "for OBP node %s\n", dev_node->full_name);
157 return 0; 123 return 0;
158 } 124 }
159 125
@@ -167,38 +133,44 @@ static const char *cpu_mid_prop(void)
167 return "portid"; 133 return "portid";
168} 134}
169 135
170static int get_cpu_mid(int prom_node) 136static int get_cpu_mid(struct device_node *dp)
171{ 137{
138 struct property *prop;
139
172 if (tlb_type == hypervisor) { 140 if (tlb_type == hypervisor) {
173 struct linux_prom64_registers reg; 141 struct linux_prom64_registers *reg;
142 int len;
174 143
175 if (prom_getproplen(prom_node, "cpuid") == 4) 144 prop = of_find_property(dp, "cpuid", &len);
176 return prom_getintdefault(prom_node, "cpuid", 0); 145 if (prop && len == 4)
146 return *(int *) prop->value;
177 147
178 prom_getproperty(prom_node, "reg", (char *) &reg, sizeof(reg)); 148 prop = of_find_property(dp, "reg", NULL);
179 return (reg.phys_addr >> 32) & 0x0fffffffUL; 149 reg = prop->value;
150 return (reg[0].phys_addr >> 32) & 0x0fffffffUL;
180 } else { 151 } else {
181 const char *prop_name = cpu_mid_prop(); 152 const char *prop_name = cpu_mid_prop();
182 153
183 return prom_getintdefault(prom_node, prop_name, 0); 154 prop = of_find_property(dp, prop_name, NULL);
155 if (prop)
156 return *(int *) prop->value;
157 return 0;
184 } 158 }
185} 159}
186 160
187static int check_cpu_node(int nd, int *cur_inst, 161static int check_cpu_node(struct device_node *dp, int *cur_inst,
188 int (*compare)(int, int, void *), void *compare_arg, 162 int (*compare)(struct device_node *, int, void *),
189 int *prom_node, int *mid) 163 void *compare_arg,
164 struct device_node **dev_node, int *mid)
190{ 165{
191 char node_str[128]; 166 if (strcmp(dp->type, "cpu"))
192
193 prom_getstring(nd, "device_type", node_str, sizeof(node_str));
194 if (strcmp(node_str, "cpu"))
195 return -ENODEV; 167 return -ENODEV;
196 168
197 if (!compare(nd, *cur_inst, compare_arg)) { 169 if (!compare(dp, *cur_inst, compare_arg)) {
198 if (prom_node) 170 if (dev_node)
199 *prom_node = nd; 171 *dev_node = dp;
200 if (mid) 172 if (mid)
201 *mid = get_cpu_mid(nd); 173 *mid = get_cpu_mid(dp);
202 return 0; 174 return 0;
203 } 175 }
204 176
@@ -207,25 +179,18 @@ static int check_cpu_node(int nd, int *cur_inst,
207 return -ENODEV; 179 return -ENODEV;
208} 180}
209 181
210static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, 182static int __cpu_find_by(int (*compare)(struct device_node *, int, void *),
211 int *prom_node, int *mid) 183 void *compare_arg,
184 struct device_node **dev_node, int *mid)
212{ 185{
213 int nd, cur_inst, err; 186 struct device_node *dp;
187 int cur_inst;
214 188
215 nd = prom_root_node;
216 cur_inst = 0; 189 cur_inst = 0;
217 190 for_each_node_by_type(dp, "cpu") {
218 err = check_cpu_node(nd, &cur_inst, 191 int err = check_cpu_node(dp, &cur_inst,
219 compare, compare_arg, 192 compare, compare_arg,
220 prom_node, mid); 193 dev_node, mid);
221 if (err == 0)
222 return 0;
223
224 nd = prom_getchild(nd);
225 while ((nd = prom_getsibling(nd)) != 0) {
226 err = check_cpu_node(nd, &cur_inst,
227 compare, compare_arg,
228 prom_node, mid);
229 if (err == 0) 194 if (err == 0)
230 return 0; 195 return 0;
231 } 196 }
@@ -233,7 +198,7 @@ static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg,
233 return -ENODEV; 198 return -ENODEV;
234} 199}
235 200
236static int cpu_instance_compare(int nd, int instance, void *_arg) 201static int cpu_instance_compare(struct device_node *dp, int instance, void *_arg)
237{ 202{
238 int desired_instance = (int) (long) _arg; 203 int desired_instance = (int) (long) _arg;
239 204
@@ -242,27 +207,27 @@ static int cpu_instance_compare(int nd, int instance, void *_arg)
242 return -ENODEV; 207 return -ENODEV;
243} 208}
244 209
245int cpu_find_by_instance(int instance, int *prom_node, int *mid) 210int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid)
246{ 211{
247 return __cpu_find_by(cpu_instance_compare, (void *)(long)instance, 212 return __cpu_find_by(cpu_instance_compare, (void *)(long)instance,
248 prom_node, mid); 213 dev_node, mid);
249} 214}
250 215
251static int cpu_mid_compare(int nd, int instance, void *_arg) 216static int cpu_mid_compare(struct device_node *dp, int instance, void *_arg)
252{ 217{
253 int desired_mid = (int) (long) _arg; 218 int desired_mid = (int) (long) _arg;
254 int this_mid; 219 int this_mid;
255 220
256 this_mid = get_cpu_mid(nd); 221 this_mid = get_cpu_mid(dp);
257 if (this_mid == desired_mid) 222 if (this_mid == desired_mid)
258 return 0; 223 return 0;
259 return -ENODEV; 224 return -ENODEV;
260} 225}
261 226
262int cpu_find_by_mid(int mid, int *prom_node) 227int cpu_find_by_mid(int mid, struct device_node **dev_node)
263{ 228{
264 return __cpu_find_by(cpu_mid_compare, (void *)(long)mid, 229 return __cpu_find_by(cpu_mid_compare, (void *)(long)mid,
265 prom_node, NULL); 230 dev_node, NULL);
266} 231}
267 232
268void __init device_scan(void) 233void __init device_scan(void)
@@ -274,50 +239,47 @@ void __init device_scan(void)
274 239
275#ifndef CONFIG_SMP 240#ifndef CONFIG_SMP
276 { 241 {
277 int err, cpu_node, def; 242 struct device_node *dp;
243 int err, def;
278 244
279 err = cpu_find_by_instance(0, &cpu_node, NULL); 245 err = cpu_find_by_instance(0, &dp, NULL);
280 if (err) { 246 if (err) {
281 prom_printf("No cpu nodes, cannot continue\n"); 247 prom_printf("No cpu nodes, cannot continue\n");
282 prom_halt(); 248 prom_halt();
283 } 249 }
284 cpu_data(0).clock_tick = prom_getintdefault(cpu_node, 250 cpu_data(0).clock_tick =
285 "clock-frequency", 251 of_getintprop_default(dp, "clock-frequency", 0);
286 0);
287 252
288 def = ((tlb_type == hypervisor) ? 253 def = ((tlb_type == hypervisor) ?
289 (8 * 1024) : 254 (8 * 1024) :
290 (16 * 1024)); 255 (16 * 1024));
291 cpu_data(0).dcache_size = prom_getintdefault(cpu_node, 256 cpu_data(0).dcache_size = of_getintprop_default(dp,
292 "dcache-size", 257 "dcache-size",
293 def); 258 def);
294 259
295 def = 32; 260 def = 32;
296 cpu_data(0).dcache_line_size = 261 cpu_data(0).dcache_line_size =
297 prom_getintdefault(cpu_node, "dcache-line-size", 262 of_getintprop_default(dp, "dcache-line-size", def);
298 def);
299 263
300 def = 16 * 1024; 264 def = 16 * 1024;
301 cpu_data(0).icache_size = prom_getintdefault(cpu_node, 265 cpu_data(0).icache_size = of_getintprop_default(dp,
302 "icache-size", 266 "icache-size",
303 def); 267 def);
304 268
305 def = 32; 269 def = 32;
306 cpu_data(0).icache_line_size = 270 cpu_data(0).icache_line_size =
307 prom_getintdefault(cpu_node, "icache-line-size", 271 of_getintprop_default(dp, "icache-line-size", def);
308 def);
309 272
310 def = ((tlb_type == hypervisor) ? 273 def = ((tlb_type == hypervisor) ?
311 (3 * 1024 * 1024) : 274 (3 * 1024 * 1024) :
312 (4 * 1024 * 1024)); 275 (4 * 1024 * 1024));
313 cpu_data(0).ecache_size = prom_getintdefault(cpu_node, 276 cpu_data(0).ecache_size = of_getintprop_default(dp,
314 "ecache-size", 277 "ecache-size",
315 def); 278 def);
316 279
317 def = 64; 280 def = 64;
318 cpu_data(0).ecache_line_size = 281 cpu_data(0).ecache_line_size =
319 prom_getintdefault(cpu_node, "ecache-line-size", 282 of_getintprop_default(dp, "ecache-line-size", def);
320 def);
321 printk("CPU[0]: Caches " 283 printk("CPU[0]: Caches "
322 "D[sz(%d):line_sz(%d)] " 284 "D[sz(%d):line_sz(%d)] "
323 "I[sz(%d):line_sz(%d)] " 285 "I[sz(%d):line_sz(%d)] "
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
index c69504aa638f..98e0a8cbeecd 100644
--- a/arch/sparc64/kernel/ebus.c
+++ b/arch/sparc64/kernel/ebus.c
@@ -269,10 +269,6 @@ EXPORT_SYMBOL(ebus_dma_enable);
269 269
270struct linux_ebus *ebus_chain = NULL; 270struct linux_ebus *ebus_chain = NULL;
271 271
272#ifdef CONFIG_SUN_AUXIO
273extern void auxio_probe(void);
274#endif
275
276static inline void *ebus_alloc(size_t size) 272static inline void *ebus_alloc(size_t size)
277{ 273{
278 void *mem; 274 void *mem;
@@ -283,77 +279,55 @@ static inline void *ebus_alloc(size_t size)
283 return mem; 279 return mem;
284} 280}
285 281
286static void __init ebus_ranges_init(struct linux_ebus *ebus)
287{
288 int success;
289
290 ebus->num_ebus_ranges = 0;
291 success = prom_getproperty(ebus->prom_node, "ranges",
292 (char *)ebus->ebus_ranges,
293 sizeof(ebus->ebus_ranges));
294 if (success != -1)
295 ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges));
296}
297
298static void __init ebus_intmap_init(struct linux_ebus *ebus)
299{
300 int success;
301
302 ebus->num_ebus_intmap = 0;
303 success = prom_getproperty(ebus->prom_node, "interrupt-map",
304 (char *)ebus->ebus_intmap,
305 sizeof(ebus->ebus_intmap));
306 if (success == -1)
307 return;
308
309 ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap));
310
311 success = prom_getproperty(ebus->prom_node, "interrupt-map-mask",
312 (char *)&ebus->ebus_intmask,
313 sizeof(ebus->ebus_intmask));
314 if (success == -1) {
315 prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
316 prom_halt();
317 }
318}
319
320int __init ebus_intmap_match(struct linux_ebus *ebus, 282int __init ebus_intmap_match(struct linux_ebus *ebus,
321 struct linux_prom_registers *reg, 283 struct linux_prom_registers *reg,
322 int *interrupt) 284 int *interrupt)
323{ 285{
286 struct linux_prom_ebus_intmap *imap;
287 struct linux_prom_ebus_intmask *imask;
324 unsigned int hi, lo, irq; 288 unsigned int hi, lo, irq;
325 int i; 289 int i, len, n_imap;
290
291 imap = of_get_property(ebus->prom_node, "interrupt-map", &len);
292 if (!imap)
293 return 0;
294 n_imap = len / sizeof(imap[0]);
326 295
327 if (!ebus->num_ebus_intmap) 296 imask = of_get_property(ebus->prom_node, "interrupt-map-mask", NULL);
297 if (!imask)
328 return 0; 298 return 0;
329 299
330 hi = reg->which_io & ebus->ebus_intmask.phys_hi; 300 hi = reg->which_io & imask->phys_hi;
331 lo = reg->phys_addr & ebus->ebus_intmask.phys_lo; 301 lo = reg->phys_addr & imask->phys_lo;
332 irq = *interrupt & ebus->ebus_intmask.interrupt; 302 irq = *interrupt & imask->interrupt;
333 for (i = 0; i < ebus->num_ebus_intmap; i++) { 303 for (i = 0; i < n_imap; i++) {
334 if ((ebus->ebus_intmap[i].phys_hi == hi) && 304 if ((imap[i].phys_hi == hi) &&
335 (ebus->ebus_intmap[i].phys_lo == lo) && 305 (imap[i].phys_lo == lo) &&
336 (ebus->ebus_intmap[i].interrupt == irq)) { 306 (imap[i].interrupt == irq)) {
337 *interrupt = ebus->ebus_intmap[i].cinterrupt; 307 *interrupt = imap[i].cinterrupt;
338 return 0; 308 return 0;
339 } 309 }
340 } 310 }
341 return -1; 311 return -1;
342} 312}
343 313
344void __init fill_ebus_child(int node, struct linux_prom_registers *preg, 314void __init fill_ebus_child(struct device_node *dp,
345 struct linux_ebus_child *dev, int non_standard_regs) 315 struct linux_prom_registers *preg,
316 struct linux_ebus_child *dev,
317 int non_standard_regs)
346{ 318{
347 int regs[PROMREG_MAX]; 319 int *regs;
348 int irqs[PROMREG_MAX]; 320 int *irqs;
349 int i, len; 321 int i, len;
350 322
351 dev->prom_node = node; 323 dev->prom_node = dp;
352 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); 324 printk(" (%s)", dp->name);
353 printk(" (%s)", dev->prom_name);
354 325
355 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 326 regs = of_get_property(dp, "reg", &len);
356 dev->num_addrs = len / sizeof(regs[0]); 327 if (!regs)
328 dev->num_addrs = 0;
329 else
330 dev->num_addrs = len / sizeof(regs[0]);
357 331
358 if (non_standard_regs) { 332 if (non_standard_regs) {
359 /* This is to handle reg properties which are not 333 /* This is to handle reg properties which are not
@@ -370,21 +344,21 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
370 int rnum = regs[i]; 344 int rnum = regs[i];
371 if (rnum >= dev->parent->num_addrs) { 345 if (rnum >= dev->parent->num_addrs) {
372 prom_printf("UGH: property for %s was %d, need < %d\n", 346 prom_printf("UGH: property for %s was %d, need < %d\n",
373 dev->prom_name, len, dev->parent->num_addrs); 347 dp->name, len, dev->parent->num_addrs);
374 panic(__FUNCTION__); 348 prom_halt();
375 } 349 }
376 dev->resource[i].start = dev->parent->resource[i].start; 350 dev->resource[i].start = dev->parent->resource[i].start;
377 dev->resource[i].end = dev->parent->resource[i].end; 351 dev->resource[i].end = dev->parent->resource[i].end;
378 dev->resource[i].flags = IORESOURCE_MEM; 352 dev->resource[i].flags = IORESOURCE_MEM;
379 dev->resource[i].name = dev->prom_name; 353 dev->resource[i].name = dp->name;
380 } 354 }
381 } 355 }
382 356
383 for (i = 0; i < PROMINTR_MAX; i++) 357 for (i = 0; i < PROMINTR_MAX; i++)
384 dev->irqs[i] = PCI_IRQ_NONE; 358 dev->irqs[i] = PCI_IRQ_NONE;
385 359
386 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 360 irqs = of_get_property(dp, "interrupts", &len);
387 if ((len == -1) || (len == 0)) { 361 if (!irqs) {
388 dev->num_irqs = 0; 362 dev->num_irqs = 0;
389 /* 363 /*
390 * Oh, well, some PROMs don't export interrupts 364 * Oh, well, some PROMs don't export interrupts
@@ -392,8 +366,8 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
392 * 366 *
393 * Be smart about PS/2 keyboard and mouse. 367 * Be smart about PS/2 keyboard and mouse.
394 */ 368 */
395 if (!strcmp(dev->parent->prom_name, "8042")) { 369 if (!strcmp(dev->parent->prom_node->name, "8042")) {
396 if (!strcmp(dev->prom_name, "kb_ps2")) { 370 if (!strcmp(dev->prom_node->name, "kb_ps2")) {
397 dev->num_irqs = 1; 371 dev->num_irqs = 1;
398 dev->irqs[0] = dev->parent->irqs[0]; 372 dev->irqs[0] = dev->parent->irqs[0];
399 } else { 373 } else {
@@ -423,32 +397,32 @@ void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
423 397
424static int __init child_regs_nonstandard(struct linux_ebus_device *dev) 398static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
425{ 399{
426 if (!strcmp(dev->prom_name, "i2c") || 400 if (!strcmp(dev->prom_node->name, "i2c") ||
427 !strcmp(dev->prom_name, "SUNW,lombus")) 401 !strcmp(dev->prom_node->name, "SUNW,lombus"))
428 return 1; 402 return 1;
429 return 0; 403 return 0;
430} 404}
431 405
432void __init fill_ebus_device(int node, struct linux_ebus_device *dev) 406void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_device *dev)
433{ 407{
434 struct linux_prom_registers regs[PROMREG_MAX]; 408 struct linux_prom_registers *regs;
435 struct linux_ebus_child *child; 409 struct linux_ebus_child *child;
436 int irqs[PROMINTR_MAX]; 410 int *irqs;
437 int i, n, len; 411 int i, n, len;
438 412
439 dev->prom_node = node; 413 dev->prom_node = dp;
440 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name)); 414
441 printk(" [%s", dev->prom_name); 415 printk(" [%s", dp->name);
442 416
443 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs)); 417 regs = of_get_property(dp, "reg", &len);
444 if (len == -1) { 418 if (!regs) {
445 dev->num_addrs = 0; 419 dev->num_addrs = 0;
446 goto probe_interrupts; 420 goto probe_interrupts;
447 } 421 }
448 422
449 if (len % sizeof(struct linux_prom_registers)) { 423 if (len % sizeof(struct linux_prom_registers)) {
450 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n", 424 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
451 dev->prom_name, len, 425 dev->prom_node->name, len,
452 (int)sizeof(struct linux_prom_registers)); 426 (int)sizeof(struct linux_prom_registers));
453 prom_halt(); 427 prom_halt();
454 } 428 }
@@ -466,7 +440,7 @@ void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
466 dev->resource[i].end = 440 dev->resource[i].end =
467 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL); 441 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
468 dev->resource[i].flags = IORESOURCE_MEM; 442 dev->resource[i].flags = IORESOURCE_MEM;
469 dev->resource[i].name = dev->prom_name; 443 dev->resource[i].name = dev->prom_node->name;
470 request_resource(&dev->bus->self->resource[n], 444 request_resource(&dev->bus->self->resource[n],
471 &dev->resource[i]); 445 &dev->resource[i]);
472 } 446 }
@@ -475,8 +449,8 @@ probe_interrupts:
475 for (i = 0; i < PROMINTR_MAX; i++) 449 for (i = 0; i < PROMINTR_MAX; i++)
476 dev->irqs[i] = PCI_IRQ_NONE; 450 dev->irqs[i] = PCI_IRQ_NONE;
477 451
478 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs)); 452 irqs = of_get_property(dp, "interrupts", &len);
479 if ((len == -1) || (len == 0)) { 453 if (!irqs) {
480 dev->num_irqs = 0; 454 dev->num_irqs = 0;
481 } else { 455 } else {
482 dev->num_irqs = len / sizeof(irqs[0]); 456 dev->num_irqs = len / sizeof(irqs[0]);
@@ -497,7 +471,18 @@ probe_interrupts:
497 } 471 }
498 } 472 }
499 473
500 if ((node = prom_getchild(node))) { 474 dev->ofdev.node = dp;
475 dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
476 dev->ofdev.dev.bus = &ebus_bus_type;
477 strcpy(dev->ofdev.dev.bus_id, dp->path_component_name);
478
479 /* Register with core */
480 if (of_device_register(&dev->ofdev) != 0)
481 printk(KERN_DEBUG "ebus: device registration error for %s!\n",
482 dev->ofdev.dev.bus_id);
483
484 dp = dp->child;
485 if (dp) {
501 printk(" ->"); 486 printk(" ->");
502 dev->children = ebus_alloc(sizeof(struct linux_ebus_child)); 487 dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
503 488
@@ -505,18 +490,18 @@ probe_interrupts:
505 child->next = NULL; 490 child->next = NULL;
506 child->parent = dev; 491 child->parent = dev;
507 child->bus = dev->bus; 492 child->bus = dev->bus;
508 fill_ebus_child(node, &regs[0], 493 fill_ebus_child(dp, regs, child,
509 child, child_regs_nonstandard(dev)); 494 child_regs_nonstandard(dev));
510 495
511 while ((node = prom_getsibling(node)) != 0) { 496 while ((dp = dp->sibling) != NULL) {
512 child->next = ebus_alloc(sizeof(struct linux_ebus_child)); 497 child->next = ebus_alloc(sizeof(struct linux_ebus_child));
513 498
514 child = child->next; 499 child = child->next;
515 child->next = NULL; 500 child->next = NULL;
516 child->parent = dev; 501 child->parent = dev;
517 child->bus = dev->bus; 502 child->bus = dev->bus;
518 fill_ebus_child(node, &regs[0], 503 fill_ebus_child(dp, regs, child,
519 child, child_regs_nonstandard(dev)); 504 child_regs_nonstandard(dev));
520 } 505 }
521 } 506 }
522 printk("]"); 507 printk("]");
@@ -543,7 +528,8 @@ void __init ebus_init(void)
543 struct linux_ebus *ebus; 528 struct linux_ebus *ebus;
544 struct pci_dev *pdev; 529 struct pci_dev *pdev;
545 struct pcidev_cookie *cookie; 530 struct pcidev_cookie *cookie;
546 int nd, ebusnd, is_rio; 531 struct device_node *dp;
532 int is_rio;
547 int num_ebus = 0; 533 int num_ebus = 0;
548 534
549 pdev = find_next_ebus(NULL, &is_rio); 535 pdev = find_next_ebus(NULL, &is_rio);
@@ -553,20 +539,22 @@ void __init ebus_init(void)
553 } 539 }
554 540
555 cookie = pdev->sysdata; 541 cookie = pdev->sysdata;
556 ebusnd = cookie->prom_node; 542 dp = cookie->prom_node;
557 543
558 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); 544 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
559 ebus->next = NULL; 545 ebus->next = NULL;
560 ebus->is_rio = is_rio; 546 ebus->is_rio = is_rio;
561 547
562 while (ebusnd) { 548 while (dp) {
549 struct device_node *child;
550
563 /* SUNW,pci-qfe uses four empty ebuses on it. 551 /* SUNW,pci-qfe uses four empty ebuses on it.
564 I think we should not consider them here, 552 I think we should not consider them here,
565 as they have half of the properties this 553 as they have half of the properties this
566 code expects and once we do PCI hot-plug, 554 code expects and once we do PCI hot-plug,
567 we'd have to tweak with the ebus_chain 555 we'd have to tweak with the ebus_chain
568 in the runtime after initialization. -jj */ 556 in the runtime after initialization. -jj */
569 if (!prom_getchild (ebusnd)) { 557 if (!dp->child) {
570 pdev = find_next_ebus(pdev, &is_rio); 558 pdev = find_next_ebus(pdev, &is_rio);
571 if (!pdev) { 559 if (!pdev) {
572 if (ebus == ebus_chain) { 560 if (ebus == ebus_chain) {
@@ -578,22 +566,29 @@ void __init ebus_init(void)
578 } 566 }
579 ebus->is_rio = is_rio; 567 ebus->is_rio = is_rio;
580 cookie = pdev->sysdata; 568 cookie = pdev->sysdata;
581 ebusnd = cookie->prom_node; 569 dp = cookie->prom_node;
582 continue; 570 continue;
583 } 571 }
584 printk("ebus%d:", num_ebus); 572 printk("ebus%d:", num_ebus);
585 573
586 prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
587 ebus->index = num_ebus; 574 ebus->index = num_ebus;
588 ebus->prom_node = ebusnd; 575 ebus->prom_node = dp;
589 ebus->self = pdev; 576 ebus->self = pdev;
590 ebus->parent = pbm = cookie->pbm; 577 ebus->parent = pbm = cookie->pbm;
591 578
592 ebus_ranges_init(ebus); 579 ebus->ofdev.node = dp;
593 ebus_intmap_init(ebus); 580 ebus->ofdev.dev.parent = &pdev->dev;
581 ebus->ofdev.dev.bus = &ebus_bus_type;
582 strcpy(ebus->ofdev.dev.bus_id, dp->path_component_name);
594 583
595 nd = prom_getchild(ebusnd); 584 /* Register with core */
596 if (!nd) 585 if (of_device_register(&ebus->ofdev) != 0)
586 printk(KERN_DEBUG "ebus: device registration error for %s!\n",
587 ebus->ofdev.dev.bus_id);
588
589
590 child = dp->child;
591 if (!child)
597 goto next_ebus; 592 goto next_ebus;
598 593
599 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); 594 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
@@ -602,16 +597,16 @@ void __init ebus_init(void)
602 dev->next = NULL; 597 dev->next = NULL;
603 dev->children = NULL; 598 dev->children = NULL;
604 dev->bus = ebus; 599 dev->bus = ebus;
605 fill_ebus_device(nd, dev); 600 fill_ebus_device(child, dev);
606 601
607 while ((nd = prom_getsibling(nd)) != 0) { 602 while ((child = child->sibling) != NULL) {
608 dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); 603 dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
609 604
610 dev = dev->next; 605 dev = dev->next;
611 dev->next = NULL; 606 dev->next = NULL;
612 dev->children = NULL; 607 dev->children = NULL;
613 dev->bus = ebus; 608 dev->bus = ebus;
614 fill_ebus_device(nd, dev); 609 fill_ebus_device(child, dev);
615 } 610 }
616 611
617 next_ebus: 612 next_ebus:
@@ -622,7 +617,7 @@ void __init ebus_init(void)
622 break; 617 break;
623 618
624 cookie = pdev->sysdata; 619 cookie = pdev->sysdata;
625 ebusnd = cookie->prom_node; 620 dp = cookie->prom_node;
626 621
627 ebus->next = ebus_alloc(sizeof(struct linux_ebus)); 622 ebus->next = ebus_alloc(sizeof(struct linux_ebus));
628 ebus = ebus->next; 623 ebus = ebus->next;
@@ -631,8 +626,4 @@ void __init ebus_init(void)
631 ++num_ebus; 626 ++num_ebus;
632 } 627 }
633 pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */ 628 pci_dev_put(pdev); /* XXX for the case, when ebusnd is 0, is it OK? */
634
635#ifdef CONFIG_SUN_AUXIO
636 auxio_probe();
637#endif
638} 629}
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index a8c9dc8d1958..31e0fbb0d82c 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -34,6 +34,7 @@
34#include <asm/iommu.h> 34#include <asm/iommu.h>
35#include <asm/upa.h> 35#include <asm/upa.h>
36#include <asm/oplib.h> 36#include <asm/oplib.h>
37#include <asm/prom.h>
37#include <asm/timer.h> 38#include <asm/timer.h>
38#include <asm/smp.h> 39#include <asm/smp.h>
39#include <asm/starfire.h> 40#include <asm/starfire.h>
@@ -635,23 +636,29 @@ static u64 prom_limit0, prom_limit1;
635 636
636static void map_prom_timers(void) 637static void map_prom_timers(void)
637{ 638{
638 unsigned int addr[3]; 639 struct device_node *dp;
639 int tnode, err; 640 unsigned int *addr;
640 641
641 /* PROM timer node hangs out in the top level of device siblings... */ 642 /* PROM timer node hangs out in the top level of device siblings... */
642 tnode = prom_finddevice("/counter-timer"); 643 dp = of_find_node_by_path("/");
644 dp = dp->child;
645 while (dp) {
646 if (!strcmp(dp->name, "counter-timer"))
647 break;
648 dp = dp->sibling;
649 }
643 650
644 /* Assume if node is not present, PROM uses different tick mechanism 651 /* Assume if node is not present, PROM uses different tick mechanism
645 * which we should not care about. 652 * which we should not care about.
646 */ 653 */
647 if (tnode == 0 || tnode == -1) { 654 if (!dp) {
648 prom_timers = (struct sun5_timer *) 0; 655 prom_timers = (struct sun5_timer *) 0;
649 return; 656 return;
650 } 657 }
651 658
652 /* If PROM is really using this, it must be mapped by him. */ 659 /* If PROM is really using this, it must be mapped by him. */
653 err = prom_getproperty(tnode, "address", (char *)addr, sizeof(addr)); 660 addr = of_get_property(dp, "address", NULL);
654 if (err == -1) { 661 if (!addr) {
655 prom_printf("PROM does not have timer mapped, trying to continue.\n"); 662 prom_printf("PROM does not have timer mapped, trying to continue.\n");
656 prom_timers = (struct sun5_timer *) 0; 663 prom_timers = (struct sun5_timer *) 0;
657 return; 664 return;
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index 30862abee611..6f16dee280a8 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -15,23 +15,19 @@ static void __init fatal_err(const char *reason)
15static void __init report_dev(struct sparc_isa_device *isa_dev, int child) 15static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
16{ 16{
17 if (child) 17 if (child)
18 printk(" (%s)", isa_dev->prom_name); 18 printk(" (%s)", isa_dev->prom_node->name);
19 else 19 else
20 printk(" [%s", isa_dev->prom_name); 20 printk(" [%s", isa_dev->prom_node->name);
21} 21}
22 22
23static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev, 23static struct linux_prom_registers * __init
24 struct linux_prom_registers *pregs, 24isa_dev_get_resource(struct sparc_isa_device *isa_dev)
25 int pregs_size)
26{ 25{
26 struct linux_prom_registers *pregs;
27 unsigned long base, len; 27 unsigned long base, len;
28 int prop_len; 28 int prop_len;
29 29
30 prop_len = prom_getproperty(isa_dev->prom_node, "reg", 30 pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
31 (char *) pregs, pregs_size);
32
33 if (prop_len <= 0)
34 return;
35 31
36 /* Only the first one is interesting. */ 32 /* Only the first one is interesting. */
37 len = pregs[0].reg_size; 33 len = pregs[0].reg_size;
@@ -42,10 +38,12 @@ static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
42 isa_dev->resource.start = base; 38 isa_dev->resource.start = base;
43 isa_dev->resource.end = (base + len - 1UL); 39 isa_dev->resource.end = (base + len - 1UL);
44 isa_dev->resource.flags = IORESOURCE_IO; 40 isa_dev->resource.flags = IORESOURCE_IO;
45 isa_dev->resource.name = isa_dev->prom_name; 41 isa_dev->resource.name = isa_dev->prom_node->name;
46 42
47 request_resource(&isa_dev->bus->parent->io_space, 43 request_resource(&isa_dev->bus->parent->io_space,
48 &isa_dev->resource); 44 &isa_dev->resource);
45
46 return pregs;
49} 47}
50 48
51/* I can't believe they didn't put a real INO in the isa device 49/* I can't believe they didn't put a real INO in the isa device
@@ -74,19 +72,30 @@ static struct {
74static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev, 72static int __init isa_dev_get_irq_using_imap(struct sparc_isa_device *isa_dev,
75 struct sparc_isa_bridge *isa_br, 73 struct sparc_isa_bridge *isa_br,
76 int *interrupt, 74 int *interrupt,
77 struct linux_prom_registers *pregs) 75 struct linux_prom_registers *reg)
78{ 76{
77 struct linux_prom_ebus_intmap *imap;
78 struct linux_prom_ebus_intmap *imask;
79 unsigned int hi, lo, irq; 79 unsigned int hi, lo, irq;
80 int i; 80 int i, len, n_imap;
81 81
82 hi = pregs->which_io & isa_br->isa_intmask.phys_hi; 82 imap = of_get_property(isa_br->prom_node, "interrupt-map", &len);
83 lo = pregs->phys_addr & isa_br->isa_intmask.phys_lo; 83 if (!imap)
84 irq = *interrupt & isa_br->isa_intmask.interrupt; 84 return 0;
85 for (i = 0; i < isa_br->num_isa_intmap; i++) { 85 n_imap = len / sizeof(imap[0]);
86 if ((isa_br->isa_intmap[i].phys_hi == hi) && 86
87 (isa_br->isa_intmap[i].phys_lo == lo) && 87 imask = of_get_property(isa_br->prom_node, "interrupt-map-mask", NULL);
88 (isa_br->isa_intmap[i].interrupt == irq)) { 88 if (!imask)
89 *interrupt = isa_br->isa_intmap[i].cinterrupt; 89 return 0;
90
91 hi = reg->which_io & imask->phys_hi;
92 lo = reg->phys_addr & imask->phys_lo;
93 irq = *interrupt & imask->interrupt;
94 for (i = 0; i < n_imap; i++) {
95 if ((imap[i].phys_hi == hi) &&
96 (imap[i].phys_lo == lo) &&
97 (imap[i].interrupt == irq)) {
98 *interrupt = imap[i].cinterrupt;
90 return 0; 99 return 0;
91 } 100 }
92 } 101 }
@@ -98,8 +107,8 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
98{ 107{
99 int irq_prop; 108 int irq_prop;
100 109
101 irq_prop = prom_getintdefault(isa_dev->prom_node, 110 irq_prop = of_getintprop_default(isa_dev->prom_node,
102 "interrupts", -1); 111 "interrupts", -1);
103 if (irq_prop <= 0) { 112 if (irq_prop <= 0) {
104 goto no_irq; 113 goto no_irq;
105 } else { 114 } else {
@@ -107,7 +116,8 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
107 struct pci_pbm_info *pbm; 116 struct pci_pbm_info *pbm;
108 int i; 117 int i;
109 118
110 if (isa_dev->bus->num_isa_intmap) { 119 if (of_find_property(isa_dev->bus->prom_node,
120 "interrupt-map", NULL)) {
111 if (!isa_dev_get_irq_using_imap(isa_dev, 121 if (!isa_dev_get_irq_using_imap(isa_dev,
112 isa_dev->bus, 122 isa_dev->bus,
113 &irq_prop, 123 &irq_prop,
@@ -141,16 +151,15 @@ no_irq:
141 151
142static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) 152static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
143{ 153{
144 int node = prom_getchild(parent_isa_dev->prom_node); 154 struct device_node *dp = parent_isa_dev->prom_node->child;
145 155
146 if (node == 0) 156 if (!dp)
147 return; 157 return;
148 158
149 printk(" ->"); 159 printk(" ->");
150 while (node != 0) { 160 while (dp) {
151 struct linux_prom_registers regs[PROMREG_MAX]; 161 struct linux_prom_registers *regs;
152 struct sparc_isa_device *isa_dev; 162 struct sparc_isa_device *isa_dev;
153 int prop_len;
154 163
155 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); 164 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
156 if (!isa_dev) { 165 if (!isa_dev) {
@@ -165,49 +174,46 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
165 parent_isa_dev->child = isa_dev; 174 parent_isa_dev->child = isa_dev;
166 175
167 isa_dev->bus = parent_isa_dev->bus; 176 isa_dev->bus = parent_isa_dev->bus;
168 isa_dev->prom_node = node; 177 isa_dev->prom_node = dp;
169 prop_len = prom_getproperty(node, "name",
170 (char *) isa_dev->prom_name,
171 sizeof(isa_dev->prom_name));
172 if (prop_len <= 0) {
173 fatal_err("cannot get child isa_dev OBP node name");
174 prom_halt();
175 }
176 178
177 prop_len = prom_getproperty(node, "compatible", 179 regs = isa_dev_get_resource(isa_dev);
178 (char *) isa_dev->compatible,
179 sizeof(isa_dev->compatible));
180
181 /* Not having this is OK. */
182 if (prop_len <= 0)
183 isa_dev->compatible[0] = '\0';
184
185 isa_dev_get_resource(isa_dev, regs, sizeof(regs));
186 isa_dev_get_irq(isa_dev, regs); 180 isa_dev_get_irq(isa_dev, regs);
187 181
188 report_dev(isa_dev, 1); 182 report_dev(isa_dev, 1);
189 183
190 node = prom_getsibling(node); 184 dp = dp->sibling;
191 } 185 }
192} 186}
193 187
194static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) 188static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
195{ 189{
196 int node = prom_getchild(isa_br->prom_node); 190 struct device_node *dp = isa_br->prom_node->child;
197 191
198 while (node != 0) { 192 while (dp) {
199 struct linux_prom_registers regs[PROMREG_MAX]; 193 struct linux_prom_registers *regs;
200 struct sparc_isa_device *isa_dev; 194 struct sparc_isa_device *isa_dev;
201 int prop_len;
202 195
203 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); 196 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
204 if (!isa_dev) { 197 if (!isa_dev) {
205 fatal_err("cannot allocate isa_dev"); 198 printk(KERN_DEBUG "ISA: cannot allocate isa_dev");
206 prom_halt(); 199 return;
207 } 200 }
208 201
209 memset(isa_dev, 0, sizeof(*isa_dev)); 202 memset(isa_dev, 0, sizeof(*isa_dev));
210 203
204 isa_dev->ofdev.node = dp;
205 isa_dev->ofdev.dev.parent = &isa_br->ofdev.dev;
206 isa_dev->ofdev.dev.bus = &isa_bus_type;
207 strcpy(isa_dev->ofdev.dev.bus_id, dp->path_component_name);
208
209 /* Register with core */
210 if (of_device_register(&isa_dev->ofdev) != 0) {
211 printk(KERN_DEBUG "isa: device registration error for %s!\n",
212 isa_dev->ofdev.dev.bus_id);
213 kfree(isa_dev);
214 goto next_sibling;
215 }
216
211 /* Link it in. */ 217 /* Link it in. */
212 isa_dev->next = NULL; 218 isa_dev->next = NULL;
213 if (isa_br->devices == NULL) { 219 if (isa_br->devices == NULL) {
@@ -222,24 +228,9 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
222 } 228 }
223 229
224 isa_dev->bus = isa_br; 230 isa_dev->bus = isa_br;
225 isa_dev->prom_node = node; 231 isa_dev->prom_node = dp;
226 prop_len = prom_getproperty(node, "name",
227 (char *) isa_dev->prom_name,
228 sizeof(isa_dev->prom_name));
229 if (prop_len <= 0) {
230 fatal_err("cannot get isa_dev OBP node name");
231 prom_halt();
232 }
233
234 prop_len = prom_getproperty(node, "compatible",
235 (char *) isa_dev->compatible,
236 sizeof(isa_dev->compatible));
237 232
238 /* Not having this is OK. */ 233 regs = isa_dev_get_resource(isa_dev);
239 if (prop_len <= 0)
240 isa_dev->compatible[0] = '\0';
241
242 isa_dev_get_resource(isa_dev, regs, sizeof(regs));
243 isa_dev_get_irq(isa_dev, regs); 234 isa_dev_get_irq(isa_dev, regs);
244 235
245 report_dev(isa_dev, 0); 236 report_dev(isa_dev, 0);
@@ -248,7 +239,8 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
248 239
249 printk("]"); 240 printk("]");
250 241
251 node = prom_getsibling(node); 242 next_sibling:
243 dp = dp->sibling;
252 } 244 }
253} 245}
254 246
@@ -266,7 +258,7 @@ void __init isa_init(void)
266 struct pcidev_cookie *pdev_cookie; 258 struct pcidev_cookie *pdev_cookie;
267 struct pci_pbm_info *pbm; 259 struct pci_pbm_info *pbm;
268 struct sparc_isa_bridge *isa_br; 260 struct sparc_isa_bridge *isa_br;
269 int prop_len; 261 struct device_node *dp;
270 262
271 pdev_cookie = pdev->sysdata; 263 pdev_cookie = pdev->sysdata;
272 if (!pdev_cookie) { 264 if (!pdev_cookie) {
@@ -275,15 +267,29 @@ void __init isa_init(void)
275 continue; 267 continue;
276 } 268 }
277 pbm = pdev_cookie->pbm; 269 pbm = pdev_cookie->pbm;
270 dp = pdev_cookie->prom_node;
278 271
279 isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL); 272 isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
280 if (!isa_br) { 273 if (!isa_br) {
281 fatal_err("cannot allocate sparc_isa_bridge"); 274 printk(KERN_DEBUG "isa: cannot allocate sparc_isa_bridge");
282 prom_halt(); 275 return;
283 } 276 }
284 277
285 memset(isa_br, 0, sizeof(*isa_br)); 278 memset(isa_br, 0, sizeof(*isa_br));
286 279
280 isa_br->ofdev.node = dp;
281 isa_br->ofdev.dev.parent = &pdev->dev;
282 isa_br->ofdev.dev.bus = &isa_bus_type;
283 strcpy(isa_br->ofdev.dev.bus_id, dp->path_component_name);
284
285 /* Register with core */
286 if (of_device_register(&isa_br->ofdev) != 0) {
287 printk(KERN_DEBUG "isa: device registration error for %s!\n",
288 isa_br->ofdev.dev.bus_id);
289 kfree(isa_br);
290 return;
291 }
292
287 /* Link it in. */ 293 /* Link it in. */
288 isa_br->next = isa_chain; 294 isa_br->next = isa_chain;
289 isa_chain = isa_br; 295 isa_chain = isa_br;
@@ -292,33 +298,6 @@ void __init isa_init(void)
292 isa_br->self = pdev; 298 isa_br->self = pdev;
293 isa_br->index = index++; 299 isa_br->index = index++;
294 isa_br->prom_node = pdev_cookie->prom_node; 300 isa_br->prom_node = pdev_cookie->prom_node;
295 strncpy(isa_br->prom_name, pdev_cookie->prom_name,
296 sizeof(isa_br->prom_name));
297
298 prop_len = prom_getproperty(isa_br->prom_node,
299 "ranges",
300 (char *) isa_br->isa_ranges,
301 sizeof(isa_br->isa_ranges));
302 if (prop_len <= 0)
303 isa_br->num_isa_ranges = 0;
304 else
305 isa_br->num_isa_ranges =
306 (prop_len / sizeof(struct linux_prom_isa_ranges));
307
308 prop_len = prom_getproperty(isa_br->prom_node,
309 "interrupt-map",
310 (char *) isa_br->isa_intmap,
311 sizeof(isa_br->isa_intmap));
312 if (prop_len <= 0)
313 isa_br->num_isa_intmap = 0;
314 else
315 isa_br->num_isa_intmap =
316 (prop_len / sizeof(struct linux_prom_isa_intmap));
317
318 prop_len = prom_getproperty(isa_br->prom_node,
319 "interrupt-map-mask",
320 (char *) &(isa_br->isa_intmask),
321 sizeof(isa_br->isa_intmask));
322 301
323 printk("isa%d:", isa_br->index); 302 printk("isa%d:", isa_br->index);
324 303
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
new file mode 100644
index 000000000000..566aa343aa62
--- /dev/null
+++ b/arch/sparc64/kernel/of_device.c
@@ -0,0 +1,279 @@
1#include <linux/config.h>
2#include <linux/string.h>
3#include <linux/kernel.h>
4#include <linux/init.h>
5#include <linux/module.h>
6#include <linux/mod_devicetable.h>
7#include <linux/slab.h>
8
9#include <asm/errno.h>
10#include <asm/of_device.h>
11
12/**
13 * of_match_device - Tell if an of_device structure has a matching
14 * of_match structure
15 * @ids: array of of device match structures to search in
16 * @dev: the of device structure to match against
17 *
18 * Used by a driver to check whether an of_device present in the
19 * system is in its list of supported devices.
20 */
21const struct of_device_id *of_match_device(const struct of_device_id *matches,
22 const struct of_device *dev)
23{
24 if (!dev->node)
25 return NULL;
26 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
27 int match = 1;
28 if (matches->name[0])
29 match &= dev->node->name
30 && !strcmp(matches->name, dev->node->name);
31 if (matches->type[0])
32 match &= dev->node->type
33 && !strcmp(matches->type, dev->node->type);
34 if (matches->compatible[0])
35 match &= of_device_is_compatible(dev->node,
36 matches->compatible);
37 if (match)
38 return matches;
39 matches++;
40 }
41 return NULL;
42}
43
44static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
45{
46 struct of_device * of_dev = to_of_device(dev);
47 struct of_platform_driver * of_drv = to_of_platform_driver(drv);
48 const struct of_device_id * matches = of_drv->match_table;
49
50 if (!matches)
51 return 0;
52
53 return of_match_device(matches, of_dev) != NULL;
54}
55
56struct of_device *of_dev_get(struct of_device *dev)
57{
58 struct device *tmp;
59
60 if (!dev)
61 return NULL;
62 tmp = get_device(&dev->dev);
63 if (tmp)
64 return to_of_device(tmp);
65 else
66 return NULL;
67}
68
69void of_dev_put(struct of_device *dev)
70{
71 if (dev)
72 put_device(&dev->dev);
73}
74
75
76static int of_device_probe(struct device *dev)
77{
78 int error = -ENODEV;
79 struct of_platform_driver *drv;
80 struct of_device *of_dev;
81 const struct of_device_id *match;
82
83 drv = to_of_platform_driver(dev->driver);
84 of_dev = to_of_device(dev);
85
86 if (!drv->probe)
87 return error;
88
89 of_dev_get(of_dev);
90
91 match = of_match_device(drv->match_table, of_dev);
92 if (match)
93 error = drv->probe(of_dev, match);
94 if (error)
95 of_dev_put(of_dev);
96
97 return error;
98}
99
100static int of_device_remove(struct device *dev)
101{
102 struct of_device * of_dev = to_of_device(dev);
103 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
104
105 if (dev->driver && drv->remove)
106 drv->remove(of_dev);
107 return 0;
108}
109
110static int of_device_suspend(struct device *dev, pm_message_t state)
111{
112 struct of_device * of_dev = to_of_device(dev);
113 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
114 int error = 0;
115
116 if (dev->driver && drv->suspend)
117 error = drv->suspend(of_dev, state);
118 return error;
119}
120
121static int of_device_resume(struct device * dev)
122{
123 struct of_device * of_dev = to_of_device(dev);
124 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
125 int error = 0;
126
127 if (dev->driver && drv->resume)
128 error = drv->resume(of_dev);
129 return error;
130}
131
132#ifdef CONFIG_PCI
133struct bus_type isa_bus_type = {
134 .name = "isa",
135 .match = of_platform_bus_match,
136 .probe = of_device_probe,
137 .remove = of_device_remove,
138 .suspend = of_device_suspend,
139 .resume = of_device_resume,
140};
141
142struct bus_type ebus_bus_type = {
143 .name = "ebus",
144 .match = of_platform_bus_match,
145 .probe = of_device_probe,
146 .remove = of_device_remove,
147 .suspend = of_device_suspend,
148 .resume = of_device_resume,
149};
150#endif
151
152#ifdef CONFIG_SBUS
153struct bus_type sbus_bus_type = {
154 .name = "sbus",
155 .match = of_platform_bus_match,
156 .probe = of_device_probe,
157 .remove = of_device_remove,
158 .suspend = of_device_suspend,
159 .resume = of_device_resume,
160};
161#endif
162
163static int __init of_bus_driver_init(void)
164{
165 int err = 0;
166
167#ifdef CONFIG_PCI
168 if (!err)
169 err = bus_register(&isa_bus_type);
170 if (!err)
171 err = bus_register(&ebus_bus_type);
172#endif
173#ifdef CONFIG_SBUS
174 if (!err)
175 err = bus_register(&sbus_bus_type);
176#endif
177 return 0;
178}
179
180postcore_initcall(of_bus_driver_init);
181
182int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus)
183{
184 /* initialize common driver fields */
185 drv->driver.name = drv->name;
186 drv->driver.bus = bus;
187
188 /* register with core */
189 return driver_register(&drv->driver);
190}
191
192void of_unregister_driver(struct of_platform_driver *drv)
193{
194 driver_unregister(&drv->driver);
195}
196
197
198static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
199{
200 struct of_device *ofdev;
201
202 ofdev = to_of_device(dev);
203 return sprintf(buf, "%s", ofdev->node->full_name);
204}
205
206static DEVICE_ATTR(devspec, S_IRUGO, dev_show_devspec, NULL);
207
208/**
209 * of_release_dev - free an of device structure when all users of it are finished.
210 * @dev: device that's been disconnected
211 *
212 * Will be called only by the device core when all users of this of device are
213 * done.
214 */
215void of_release_dev(struct device *dev)
216{
217 struct of_device *ofdev;
218
219 ofdev = to_of_device(dev);
220
221 kfree(ofdev);
222}
223
224int of_device_register(struct of_device *ofdev)
225{
226 int rc;
227
228 BUG_ON(ofdev->node == NULL);
229
230 rc = device_register(&ofdev->dev);
231 if (rc)
232 return rc;
233
234 device_create_file(&ofdev->dev, &dev_attr_devspec);
235
236 return 0;
237}
238
239void of_device_unregister(struct of_device *ofdev)
240{
241 device_remove_file(&ofdev->dev, &dev_attr_devspec);
242 device_unregister(&ofdev->dev);
243}
244
245struct of_device* of_platform_device_create(struct device_node *np,
246 const char *bus_id,
247 struct device *parent,
248 struct bus_type *bus)
249{
250 struct of_device *dev;
251
252 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
253 if (!dev)
254 return NULL;
255 memset(dev, 0, sizeof(*dev));
256
257 dev->dev.parent = parent;
258 dev->dev.bus = bus;
259 dev->dev.release = of_release_dev;
260
261 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
262
263 if (of_device_register(dev) != 0) {
264 kfree(dev);
265 return NULL;
266 }
267
268 return dev;
269}
270
271EXPORT_SYMBOL(of_match_device);
272EXPORT_SYMBOL(of_register_driver);
273EXPORT_SYMBOL(of_unregister_driver);
274EXPORT_SYMBOL(of_device_register);
275EXPORT_SYMBOL(of_device_unregister);
276EXPORT_SYMBOL(of_dev_get);
277EXPORT_SYMBOL(of_dev_put);
278EXPORT_SYMBOL(of_platform_device_create);
279EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index 9472580a4319..6c9e3e94abaa 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -22,6 +22,7 @@
22#include <asm/irq.h> 22#include <asm/irq.h>
23#include <asm/ebus.h> 23#include <asm/ebus.h>
24#include <asm/isa.h> 24#include <asm/isa.h>
25#include <asm/prom.h>
25 26
26unsigned long pci_memspace_mask = 0xffffffffUL; 27unsigned long pci_memspace_mask = 0xffffffffUL;
27 28
@@ -177,16 +178,16 @@ void pci_config_write32(u32 *addr, u32 val)
177} 178}
178 179
179/* Probe for all PCI controllers in the system. */ 180/* Probe for all PCI controllers in the system. */
180extern void sabre_init(int, char *); 181extern void sabre_init(struct device_node *, const char *);
181extern void psycho_init(int, char *); 182extern void psycho_init(struct device_node *, const char *);
182extern void schizo_init(int, char *); 183extern void schizo_init(struct device_node *, const char *);
183extern void schizo_plus_init(int, char *); 184extern void schizo_plus_init(struct device_node *, const char *);
184extern void tomatillo_init(int, char *); 185extern void tomatillo_init(struct device_node *, const char *);
185extern void sun4v_pci_init(int, char *); 186extern void sun4v_pci_init(struct device_node *, const char *);
186 187
187static struct { 188static struct {
188 char *model_name; 189 char *model_name;
189 void (*init)(int, char *); 190 void (*init)(struct device_node *, const char *);
190} pci_controller_table[] __initdata = { 191} pci_controller_table[] __initdata = {
191 { "SUNW,sabre", sabre_init }, 192 { "SUNW,sabre", sabre_init },
192 { "pci108e,a000", sabre_init }, 193 { "pci108e,a000", sabre_init },
@@ -204,7 +205,7 @@ static struct {
204#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ 205#define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \
205 sizeof(pci_controller_table[0])) 206 sizeof(pci_controller_table[0]))
206 207
207static int __init pci_controller_init(char *model_name, int namelen, int node) 208static int __init pci_controller_init(const char *model_name, int namelen, struct device_node *dp)
208{ 209{
209 int i; 210 int i;
210 211
@@ -212,18 +213,15 @@ static int __init pci_controller_init(char *model_name, int namelen, int node)
212 if (!strncmp(model_name, 213 if (!strncmp(model_name,
213 pci_controller_table[i].model_name, 214 pci_controller_table[i].model_name,
214 namelen)) { 215 namelen)) {
215 pci_controller_table[i].init(node, model_name); 216 pci_controller_table[i].init(dp, model_name);
216 return 1; 217 return 1;
217 } 218 }
218 } 219 }
219 printk("PCI: Warning unknown controller, model name [%s]\n",
220 model_name);
221 printk("PCI: Ignoring controller...\n");
222 220
223 return 0; 221 return 0;
224} 222}
225 223
226static int __init pci_is_controller(char *model_name, int namelen, int node) 224static int __init pci_is_controller(const char *model_name, int namelen, struct device_node *dp)
227{ 225{
228 int i; 226 int i;
229 227
@@ -237,36 +235,35 @@ static int __init pci_is_controller(char *model_name, int namelen, int node)
237 return 0; 235 return 0;
238} 236}
239 237
240static int __init pci_controller_scan(int (*handler)(char *, int, int)) 238static int __init pci_controller_scan(int (*handler)(const char *, int, struct device_node *))
241{ 239{
242 char namebuf[64]; 240 struct device_node *dp;
243 int node;
244 int count = 0; 241 int count = 0;
245 242
246 node = prom_getchild(prom_root_node); 243 for_each_node_by_name(dp, "pci") {
247 while ((node = prom_searchsiblings(node, "pci")) != 0) { 244 struct property *prop;
248 int len; 245 int len;
249 246
250 if ((len = prom_getproperty(node, "model", namebuf, sizeof(namebuf))) > 0 || 247 prop = of_find_property(dp, "model", &len);
251 (len = prom_getproperty(node, "compatible", namebuf, sizeof(namebuf))) > 0) { 248 if (!prop)
249 prop = of_find_property(dp, "compatible", &len);
250
251 if (prop) {
252 const char *model = prop->value;
252 int item_len = 0; 253 int item_len = 0;
253 254
254 /* Our value may be a multi-valued string in the 255 /* Our value may be a multi-valued string in the
255 * case of some compatible properties. For sanity, 256 * case of some compatible properties. For sanity,
256 * only try the first one. */ 257 * only try the first one.
257 258 */
258 while (namebuf[item_len] && len) { 259 while (model[item_len] && len) {
259 len--; 260 len--;
260 item_len++; 261 item_len++;
261 } 262 }
262 263
263 if (handler(namebuf, item_len, node)) 264 if (handler(model, item_len, dp))
264 count++; 265 count++;
265 } 266 }
266
267 node = prom_getsibling(node);
268 if (!node)
269 break;
270 } 267 }
271 268
272 return count; 269 return count;
@@ -409,8 +406,14 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res,
409} 406}
410EXPORT_SYMBOL(pcibios_bus_to_resource); 407EXPORT_SYMBOL(pcibios_bus_to_resource);
411 408
409extern int pci_irq_verbose;
410
412char * __init pcibios_setup(char *str) 411char * __init pcibios_setup(char *str)
413{ 412{
413 if (!strcmp(str, "irq_verbose")) {
414 pci_irq_verbose = 1;
415 return NULL;
416 }
414 return str; 417 return str;
415} 418}
416 419
diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c
index 33dedb1aacd4..b06a2955bf5f 100644
--- a/arch/sparc64/kernel/pci_common.c
+++ b/arch/sparc64/kernel/pci_common.c
@@ -9,6 +9,12 @@
9#include <linux/init.h> 9#include <linux/init.h>
10 10
11#include <asm/pbm.h> 11#include <asm/pbm.h>
12#include <asm/prom.h>
13
14#include "pci_impl.h"
15
16/* Pass "pci=irq_verbose" on the kernel command line to enable this. */
17int pci_irq_verbose;
12 18
13/* Fix self device of BUS and hook it into BUS->self. 19/* Fix self device of BUS and hook it into BUS->self.
14 * The pci_scan_bus does not do this for the host bridge. 20 * The pci_scan_bus does not do this for the host bridge.
@@ -28,16 +34,14 @@ void __init pci_fixup_host_bridge_self(struct pci_bus *pbus)
28 prom_halt(); 34 prom_halt();
29} 35}
30 36
31/* Find the OBP PROM device tree node for a PCI device. 37/* Find the OBP PROM device tree node for a PCI device. */
32 * Return zero if not found. 38static struct device_node * __init
33 */ 39find_device_prom_node(struct pci_pbm_info *pbm, struct pci_dev *pdev,
34static int __init find_device_prom_node(struct pci_pbm_info *pbm, 40 struct device_node *bus_node,
35 struct pci_dev *pdev, 41 struct linux_prom_pci_registers **pregs,
36 int bus_prom_node, 42 int *nregs)
37 struct linux_prom_pci_registers *pregs,
38 int *nregs)
39{ 43{
40 int node; 44 struct device_node *dp;
41 45
42 *nregs = 0; 46 *nregs = 0;
43 47
@@ -54,24 +58,30 @@ static int __init find_device_prom_node(struct pci_pbm_info *pbm,
54 pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO || 58 pdev->device == PCI_DEVICE_ID_SUN_TOMATILLO ||
55 pdev->device == PCI_DEVICE_ID_SUN_SABRE || 59 pdev->device == PCI_DEVICE_ID_SUN_SABRE ||
56 pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) 60 pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD))
57 return bus_prom_node; 61 return bus_node;
58 62
59 node = prom_getchild(bus_prom_node); 63 dp = bus_node->child;
60 while (node != 0) { 64 while (dp) {
61 int err = prom_getproperty(node, "reg", 65 struct linux_prom_pci_registers *regs;
62 (char *)pregs, 66 struct property *prop;
63 sizeof(*pregs) * PROMREG_MAX); 67 int len;
64 if (err == 0 || err == -1) 68
69 prop = of_find_property(dp, "reg", &len);
70 if (!prop)
65 goto do_next_sibling; 71 goto do_next_sibling;
66 if (((pregs[0].phys_hi >> 8) & 0xff) == pdev->devfn) { 72
67 *nregs = err / sizeof(*pregs); 73 regs = prop->value;
68 return node; 74 if (((regs[0].phys_hi >> 8) & 0xff) == pdev->devfn) {
75 *pregs = regs;
76 *nregs = len / sizeof(struct linux_prom_pci_registers);
77 return dp;
69 } 78 }
70 79
71 do_next_sibling: 80 do_next_sibling:
72 node = prom_getsibling(node); 81 dp = dp->sibling;
73 } 82 }
74 return 0; 83
84 return NULL;
75} 85}
76 86
77/* Older versions of OBP on PCI systems encode 64-bit MEM 87/* Older versions of OBP on PCI systems encode 64-bit MEM
@@ -128,15 +138,17 @@ static void __init fixup_obp_assignments(struct pci_dev *pdev,
128 */ 138 */
129static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm, 139static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
130 struct pci_dev *pdev, 140 struct pci_dev *pdev,
131 int bus_prom_node) 141 struct device_node *bus_node)
132{ 142{
133 struct linux_prom_pci_registers pregs[PROMREG_MAX]; 143 struct linux_prom_pci_registers *pregs = NULL;
134 struct pcidev_cookie *pcp; 144 struct pcidev_cookie *pcp;
135 int device_prom_node, nregs, err; 145 struct device_node *dp;
146 struct property *prop;
147 int nregs, len;
136 148
137 device_prom_node = find_device_prom_node(pbm, pdev, bus_prom_node, 149 dp = find_device_prom_node(pbm, pdev, bus_node,
138 pregs, &nregs); 150 &pregs, &nregs);
139 if (device_prom_node == 0) { 151 if (!dp) {
140 /* If it is not in the OBP device tree then 152 /* If it is not in the OBP device tree then
141 * there must be a damn good reason for it. 153 * there must be a damn good reason for it.
142 * 154 *
@@ -150,45 +162,43 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
150 return; 162 return;
151 } 163 }
152 164
153 pcp = kmalloc(sizeof(*pcp), GFP_ATOMIC); 165 pcp = kzalloc(sizeof(*pcp), GFP_ATOMIC);
154 if (pcp == NULL) { 166 if (pcp == NULL) {
155 prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n"); 167 prom_printf("PCI_COOKIE: Fatal malloc error, aborting...\n");
156 prom_halt(); 168 prom_halt();
157 } 169 }
158 pcp->pbm = pbm; 170 pcp->pbm = pbm;
159 pcp->prom_node = device_prom_node; 171 pcp->prom_node = dp;
160 memcpy(pcp->prom_regs, pregs, sizeof(pcp->prom_regs)); 172 memcpy(pcp->prom_regs, pregs,
173 nregs * sizeof(struct linux_prom_pci_registers));
161 pcp->num_prom_regs = nregs; 174 pcp->num_prom_regs = nregs;
162 err = prom_getproperty(device_prom_node, "name", 175
163 pcp->prom_name, sizeof(pcp->prom_name)); 176 /* We can't have the pcidev_cookie assignments be just
164 if (err > 0) 177 * direct pointers into the property value, since they
165 pcp->prom_name[err] = 0; 178 * are potentially modified by the probing process.
166 else 179 */
167 pcp->prom_name[0] = 0; 180 prop = of_find_property(dp, "assigned-addresses", &len);
168 181 if (!prop) {
169 err = prom_getproperty(device_prom_node,
170 "assigned-addresses",
171 (char *)pcp->prom_assignments,
172 sizeof(pcp->prom_assignments));
173 if (err == 0 || err == -1)
174 pcp->num_prom_assignments = 0; 182 pcp->num_prom_assignments = 0;
175 else 183 } else {
184 memcpy(pcp->prom_assignments, prop->value, len);
176 pcp->num_prom_assignments = 185 pcp->num_prom_assignments =
177 (err / sizeof(pcp->prom_assignments[0])); 186 (len / sizeof(pcp->prom_assignments[0]));
187 }
178 188
179 if (strcmp(pcp->prom_name, "ebus") == 0) { 189 if (strcmp(dp->name, "ebus") == 0) {
180 struct linux_prom_ebus_ranges erng[PROM_PCIRNG_MAX]; 190 struct linux_prom_ebus_ranges *erng;
181 int iter; 191 int iter;
182 192
183 /* EBUS is special... */ 193 /* EBUS is special... */
184 err = prom_getproperty(device_prom_node, "ranges", 194 prop = of_find_property(dp, "ranges", &len);
185 (char *)&erng[0], sizeof(erng)); 195 if (!prop) {
186 if (err == 0 || err == -1) {
187 prom_printf("EBUS: Fatal error, no range property\n"); 196 prom_printf("EBUS: Fatal error, no range property\n");
188 prom_halt(); 197 prom_halt();
189 } 198 }
190 err = (err / sizeof(erng[0])); 199 erng = prop->value;
191 for(iter = 0; iter < err; iter++) { 200 len = (len / sizeof(erng[0]));
201 for (iter = 0; iter < len; iter++) {
192 struct linux_prom_ebus_ranges *ep = &erng[iter]; 202 struct linux_prom_ebus_ranges *ep = &erng[iter];
193 struct linux_prom_pci_registers *ap; 203 struct linux_prom_pci_registers *ap;
194 204
@@ -200,7 +210,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
200 ap->size_hi = 0; 210 ap->size_hi = 0;
201 ap->size_lo = ep->size; 211 ap->size_lo = ep->size;
202 } 212 }
203 pcp->num_prom_assignments = err; 213 pcp->num_prom_assignments = len;
204 } 214 }
205 215
206 fixup_obp_assignments(pdev, pcp); 216 fixup_obp_assignments(pdev, pcp);
@@ -210,7 +220,7 @@ static void __init pdev_cookie_fillin(struct pci_pbm_info *pbm,
210 220
211void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus, 221void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
212 struct pci_pbm_info *pbm, 222 struct pci_pbm_info *pbm,
213 int prom_node) 223 struct device_node *dp)
214{ 224{
215 struct pci_dev *pdev, *pdev_next; 225 struct pci_dev *pdev, *pdev_next;
216 struct pci_bus *this_pbus, *pbus_next; 226 struct pci_bus *this_pbus, *pbus_next;
@@ -218,7 +228,7 @@ void __init pci_fill_in_pbm_cookies(struct pci_bus *pbus,
218 /* This must be _safe because the cookie fillin 228 /* This must be _safe because the cookie fillin
219 routine can delete devices from the tree. */ 229 routine can delete devices from the tree. */
220 list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list) 230 list_for_each_entry_safe(pdev, pdev_next, &pbus->devices, bus_list)
221 pdev_cookie_fillin(pbm, pdev, prom_node); 231 pdev_cookie_fillin(pbm, pdev, dp);
222 232
223 list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) { 233 list_for_each_entry_safe(this_pbus, pbus_next, &pbus->children, node) {
224 struct pcidev_cookie *pcp = this_pbus->self->sysdata; 234 struct pcidev_cookie *pcp = this_pbus->self->sysdata;
@@ -241,7 +251,6 @@ static void __init bad_assignment(struct pci_dev *pdev,
241 if (res) 251 if (res)
242 prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n", 252 prom_printf("PCI: RES[%016lx-->%016lx:(%lx)]\n",
243 res->start, res->end, res->flags); 253 res->start, res->end, res->flags);
244 prom_printf("Please email this information to davem@redhat.com\n");
245 if (do_prom_halt) 254 if (do_prom_halt)
246 prom_halt(); 255 prom_halt();
247} 256}
@@ -273,8 +282,7 @@ __init get_root_resource(struct linux_prom_pci_registers *ap,
273 return &pbm->mem_space; 282 return &pbm->mem_space;
274 283
275 default: 284 default:
276 printk("PCI: What is resource space %x? " 285 printk("PCI: What is resource space %x?\n", space);
277 "Tell davem@redhat.com about it!\n", space);
278 return NULL; 286 return NULL;
279 }; 287 };
280} 288}
@@ -556,9 +564,10 @@ static inline unsigned int pci_slot_swivel(struct pci_pbm_info *pbm,
556 564
557 ret = ((interrupt - 1 + (PCI_SLOT(pdev->devfn) & 3)) & 3) + 1; 565 ret = ((interrupt - 1 + (PCI_SLOT(pdev->devfn) & 3)) & 3) + 1;
558 566
559 printk("%s: %s IRQ Swivel %s [%x:%x] -> [%x]\n", 567 if (pci_irq_verbose)
560 pbm->name, pci_name(toplevel_pdev), pci_name(pdev), 568 printk("%s: %s IRQ Swivel %s [%x:%x] -> [%x]\n",
561 interrupt, PCI_SLOT(pdev->devfn), ret); 569 pbm->name, pci_name(toplevel_pdev), pci_name(pdev),
570 interrupt, PCI_SLOT(pdev->devfn), ret);
562 571
563 return ret; 572 return ret;
564} 573}
@@ -568,58 +577,60 @@ static inline unsigned int pci_apply_intmap(struct pci_pbm_info *pbm,
568 struct pci_dev *pbus, 577 struct pci_dev *pbus,
569 struct pci_dev *pdev, 578 struct pci_dev *pdev,
570 unsigned int interrupt, 579 unsigned int interrupt,
571 unsigned int *cnode) 580 struct device_node **cnode)
572{ 581{
573 struct linux_prom_pci_intmap imap[PROM_PCIIMAP_MAX]; 582 struct linux_prom_pci_intmap *imap;
574 struct linux_prom_pci_intmask imask; 583 struct linux_prom_pci_intmask *imask;
575 struct pcidev_cookie *pbus_pcp = pbus->sysdata; 584 struct pcidev_cookie *pbus_pcp = pbus->sysdata;
576 struct pcidev_cookie *pdev_pcp = pdev->sysdata; 585 struct pcidev_cookie *pdev_pcp = pdev->sysdata;
577 struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs; 586 struct linux_prom_pci_registers *pregs = pdev_pcp->prom_regs;
587 struct property *prop;
578 int plen, num_imap, i; 588 int plen, num_imap, i;
579 unsigned int hi, mid, lo, irq, orig_interrupt; 589 unsigned int hi, mid, lo, irq, orig_interrupt;
580 590
581 *cnode = pbus_pcp->prom_node; 591 *cnode = pbus_pcp->prom_node;
582 592
583 plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map", 593 prop = of_find_property(pbus_pcp->prom_node, "interrupt-map", &plen);
584 (char *) &imap[0], sizeof(imap)); 594 if (!prop ||
585 if (plen <= 0 ||
586 (plen % sizeof(struct linux_prom_pci_intmap)) != 0) { 595 (plen % sizeof(struct linux_prom_pci_intmap)) != 0) {
587 printk("%s: Device %s interrupt-map has bad len %d\n", 596 printk("%s: Device %s interrupt-map has bad len %d\n",
588 pbm->name, pci_name(pbus), plen); 597 pbm->name, pci_name(pbus), plen);
589 goto no_intmap; 598 goto no_intmap;
590 } 599 }
600 imap = prop->value;
591 num_imap = plen / sizeof(struct linux_prom_pci_intmap); 601 num_imap = plen / sizeof(struct linux_prom_pci_intmap);
592 602
593 plen = prom_getproperty(pbus_pcp->prom_node, "interrupt-map-mask", 603 prop = of_find_property(pbus_pcp->prom_node, "interrupt-map-mask", &plen);
594 (char *) &imask, sizeof(imask)); 604 if (!prop ||
595 if (plen <= 0 ||
596 (plen % sizeof(struct linux_prom_pci_intmask)) != 0) { 605 (plen % sizeof(struct linux_prom_pci_intmask)) != 0) {
597 printk("%s: Device %s interrupt-map-mask has bad len %d\n", 606 printk("%s: Device %s interrupt-map-mask has bad len %d\n",
598 pbm->name, pci_name(pbus), plen); 607 pbm->name, pci_name(pbus), plen);
599 goto no_intmap; 608 goto no_intmap;
600 } 609 }
610 imask = prop->value;
601 611
602 orig_interrupt = interrupt; 612 orig_interrupt = interrupt;
603 613
604 hi = pregs->phys_hi & imask.phys_hi; 614 hi = pregs->phys_hi & imask->phys_hi;
605 mid = pregs->phys_mid & imask.phys_mid; 615 mid = pregs->phys_mid & imask->phys_mid;
606 lo = pregs->phys_lo & imask.phys_lo; 616 lo = pregs->phys_lo & imask->phys_lo;
607 irq = interrupt & imask.interrupt; 617 irq = interrupt & imask->interrupt;
608 618
609 for (i = 0; i < num_imap; i++) { 619 for (i = 0; i < num_imap; i++) {
610 if (imap[i].phys_hi == hi && 620 if (imap[i].phys_hi == hi &&
611 imap[i].phys_mid == mid && 621 imap[i].phys_mid == mid &&
612 imap[i].phys_lo == lo && 622 imap[i].phys_lo == lo &&
613 imap[i].interrupt == irq) { 623 imap[i].interrupt == irq) {
614 *cnode = imap[i].cnode; 624 *cnode = of_find_node_by_phandle(imap[i].cnode);
615 interrupt = imap[i].cinterrupt; 625 interrupt = imap[i].cinterrupt;
616 } 626 }
617 } 627 }
618 628
619 printk("%s: %s MAP BUS %s DEV %s [%x] -> [%x]\n", 629 if (pci_irq_verbose)
620 pbm->name, pci_name(toplevel_pdev), 630 printk("%s: %s MAP BUS %s DEV %s [%x] -> [%x]\n",
621 pci_name(pbus), pci_name(pdev), 631 pbm->name, pci_name(toplevel_pdev),
622 orig_interrupt, interrupt); 632 pci_name(pbus), pci_name(pdev),
633 orig_interrupt, interrupt);
623 634
624no_intmap: 635no_intmap:
625 return interrupt; 636 return interrupt;
@@ -633,21 +644,22 @@ no_intmap:
633 * all interrupt translations are complete, else we should use that node's 644 * all interrupt translations are complete, else we should use that node's
634 * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt. 645 * "reg" property to apply the PBM's "interrupt-{map,mask}" to the interrupt.
635 */ 646 */
636static unsigned int __init pci_intmap_match_to_root(struct pci_pbm_info *pbm, 647static struct device_node * __init
637 struct pci_dev *pdev, 648pci_intmap_match_to_root(struct pci_pbm_info *pbm,
638 unsigned int *interrupt) 649 struct pci_dev *pdev,
650 unsigned int *interrupt)
639{ 651{
640 struct pci_dev *toplevel_pdev = pdev; 652 struct pci_dev *toplevel_pdev = pdev;
641 struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata; 653 struct pcidev_cookie *toplevel_pcp = toplevel_pdev->sysdata;
642 unsigned int cnode = toplevel_pcp->prom_node; 654 struct device_node *cnode = toplevel_pcp->prom_node;
643 655
644 while (pdev->bus->number != pbm->pci_first_busno) { 656 while (pdev->bus->number != pbm->pci_first_busno) {
645 struct pci_dev *pbus = pdev->bus->self; 657 struct pci_dev *pbus = pdev->bus->self;
646 struct pcidev_cookie *pcp = pbus->sysdata; 658 struct pcidev_cookie *pcp = pbus->sysdata;
647 int plen; 659 struct property *prop;
648 660
649 plen = prom_getproplen(pcp->prom_node, "interrupt-map"); 661 prop = of_find_property(pcp->prom_node, "interrupt-map", NULL);
650 if (plen <= 0) { 662 if (!prop) {
651 *interrupt = pci_slot_swivel(pbm, toplevel_pdev, 663 *interrupt = pci_slot_swivel(pbm, toplevel_pdev,
652 pdev, *interrupt); 664 pdev, *interrupt);
653 cnode = pcp->prom_node; 665 cnode = pcp->prom_node;
@@ -675,26 +687,29 @@ static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt
675{ 687{
676 struct pcidev_cookie *dev_pcp = pdev->sysdata; 688 struct pcidev_cookie *dev_pcp = pdev->sysdata;
677 struct pci_pbm_info *pbm = dev_pcp->pbm; 689 struct pci_pbm_info *pbm = dev_pcp->pbm;
678 struct linux_prom_pci_registers reg[PROMREG_MAX]; 690 struct linux_prom_pci_registers *reg;
691 struct device_node *cnode;
692 struct property *prop;
679 unsigned int hi, mid, lo, irq; 693 unsigned int hi, mid, lo, irq;
680 int i, cnode, plen; 694 int i, plen;
681 695
682 cnode = pci_intmap_match_to_root(pbm, pdev, interrupt); 696 cnode = pci_intmap_match_to_root(pbm, pdev, interrupt);
683 if (cnode == pbm->prom_node) 697 if (cnode == pbm->prom_node)
684 goto success; 698 goto success;
685 699
686 plen = prom_getproperty(cnode, "reg", (char *) reg, sizeof(reg)); 700 prop = of_find_property(cnode, "reg", &plen);
687 if (plen <= 0 || 701 if (!prop ||
688 (plen % sizeof(struct linux_prom_pci_registers)) != 0) { 702 (plen % sizeof(struct linux_prom_pci_registers)) != 0) {
689 printk("%s: OBP node %x reg property has bad len %d\n", 703 printk("%s: OBP node %s reg property has bad len %d\n",
690 pbm->name, cnode, plen); 704 pbm->name, cnode->full_name, plen);
691 goto fail; 705 goto fail;
692 } 706 }
707 reg = prop->value;
693 708
694 hi = reg[0].phys_hi & pbm->pbm_intmask.phys_hi; 709 hi = reg[0].phys_hi & pbm->pbm_intmask->phys_hi;
695 mid = reg[0].phys_mid & pbm->pbm_intmask.phys_mid; 710 mid = reg[0].phys_mid & pbm->pbm_intmask->phys_mid;
696 lo = reg[0].phys_lo & pbm->pbm_intmask.phys_lo; 711 lo = reg[0].phys_lo & pbm->pbm_intmask->phys_lo;
697 irq = *interrupt & pbm->pbm_intmask.interrupt; 712 irq = *interrupt & pbm->pbm_intmask->interrupt;
698 713
699 for (i = 0; i < pbm->num_pbm_intmap; i++) { 714 for (i = 0; i < pbm->num_pbm_intmap; i++) {
700 struct linux_prom_pci_intmap *intmap; 715 struct linux_prom_pci_intmap *intmap;
@@ -714,9 +729,11 @@ fail:
714 return 0; 729 return 0;
715 730
716success: 731success:
717 printk("PCI-IRQ: Routing bus[%2x] slot[%2x] to INO[%02x]\n", 732 if (pci_irq_verbose)
718 pdev->bus->number, PCI_SLOT(pdev->devfn), 733 printk("%s: Routing bus[%2x] slot[%2x] to INO[%02x]\n",
719 *interrupt); 734 pbm->name,
735 pdev->bus->number, PCI_SLOT(pdev->devfn),
736 *interrupt);
720 return 1; 737 return 1;
721} 738}
722 739
@@ -727,8 +744,8 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
727 struct pci_controller_info *p = pbm->parent; 744 struct pci_controller_info *p = pbm->parent;
728 unsigned int portid = pbm->portid; 745 unsigned int portid = pbm->portid;
729 unsigned int prom_irq; 746 unsigned int prom_irq;
730 int prom_node = pcp->prom_node; 747 struct device_node *dp = pcp->prom_node;
731 int err; 748 struct property *prop;
732 749
733 /* If this is an empty EBUS device, sometimes OBP fails to 750 /* If this is an empty EBUS device, sometimes OBP fails to
734 * give it a valid fully specified interrupts property. 751 * give it a valid fully specified interrupts property.
@@ -739,17 +756,17 @@ static void __init pdev_fixup_irq(struct pci_dev *pdev)
739 */ 756 */
740 if (pdev->vendor == PCI_VENDOR_ID_SUN && 757 if (pdev->vendor == PCI_VENDOR_ID_SUN &&
741 pdev->device == PCI_DEVICE_ID_SUN_EBUS && 758 pdev->device == PCI_DEVICE_ID_SUN_EBUS &&
742 !prom_getchild(prom_node)) { 759 !dp->child) {
743 pdev->irq = 0; 760 pdev->irq = 0;
744 return; 761 return;
745 } 762 }
746 763
747 err = prom_getproperty(prom_node, "interrupts", 764 prop = of_find_property(dp, "interrupts", NULL);
748 (char *)&prom_irq, sizeof(prom_irq)); 765 if (!prop) {
749 if (err == 0 || err == -1) {
750 pdev->irq = 0; 766 pdev->irq = 0;
751 return; 767 return;
752 } 768 }
769 prom_irq = *(unsigned int *) prop->value;
753 770
754 if (tlb_type != hypervisor) { 771 if (tlb_type != hypervisor) {
755 /* Fully specified already? */ 772 /* Fully specified already? */
diff --git a/arch/sparc64/kernel/pci_impl.h b/arch/sparc64/kernel/pci_impl.h
index 6c3205962544..971e2bea30b4 100644
--- a/arch/sparc64/kernel/pci_impl.h
+++ b/arch/sparc64/kernel/pci_impl.h
@@ -10,6 +10,7 @@
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/spinlock.h> 11#include <linux/spinlock.h>
12#include <asm/io.h> 12#include <asm/io.h>
13#include <asm/prom.h>
13 14
14extern struct pci_controller_info *pci_controller_root; 15extern struct pci_controller_info *pci_controller_root;
15 16
@@ -19,7 +20,7 @@ extern int pci_num_controllers;
19extern void pci_fixup_host_bridge_self(struct pci_bus *pbus); 20extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
20extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus, 21extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
21 struct pci_pbm_info *pbm, 22 struct pci_pbm_info *pbm,
22 int prom_node); 23 struct device_node *prom_node);
23extern void pci_record_assignments(struct pci_pbm_info *pbm, 24extern void pci_record_assignments(struct pci_pbm_info *pbm,
24 struct pci_bus *pbus); 25 struct pci_bus *pbus);
25extern void pci_assign_unassigned(struct pci_pbm_info *pbm, 26extern void pci_assign_unassigned(struct pci_pbm_info *pbm,
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 24db22aa9728..5b2261ebda6f 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -17,6 +17,7 @@
17#include <asm/iommu.h> 17#include <asm/iommu.h>
18#include <asm/irq.h> 18#include <asm/irq.h>
19#include <asm/starfire.h> 19#include <asm/starfire.h>
20#include <asm/prom.h>
20 21
21#include "pci_impl.h" 22#include "pci_impl.h"
22#include "iommu_common.h" 23#include "iommu_common.h"
@@ -1291,11 +1292,12 @@ static void psycho_pbm_strbuf_init(struct pci_controller_info *p,
1291#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL 1292#define PSYCHO_MEMSPACE_SIZE 0x07fffffffUL
1292 1293
1293static void psycho_pbm_init(struct pci_controller_info *p, 1294static void psycho_pbm_init(struct pci_controller_info *p,
1294 int prom_node, int is_pbm_a) 1295 struct device_node *dp, int is_pbm_a)
1295{ 1296{
1296 unsigned int busrange[2]; 1297 unsigned int *busrange;
1298 struct property *prop;
1297 struct pci_pbm_info *pbm; 1299 struct pci_pbm_info *pbm;
1298 int err; 1300 int len;
1299 1301
1300 if (is_pbm_a) { 1302 if (is_pbm_a) {
1301 pbm = &p->pbm_A; 1303 pbm = &p->pbm_A;
@@ -1310,10 +1312,14 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1310 } 1312 }
1311 1313
1312 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO; 1314 pbm->chip_type = PBM_CHIP_TYPE_PSYCHO;
1313 pbm->chip_version = 1315 pbm->chip_version = 0;
1314 prom_getintdefault(prom_node, "version#", 0); 1316 prop = of_find_property(dp, "version#", NULL);
1315 pbm->chip_revision = 1317 if (prop)
1316 prom_getintdefault(prom_node, "module-revision#", 0); 1318 pbm->chip_version = *(int *) prop->value;
1319 pbm->chip_revision = 0;
1320 prop = of_find_property(dp, "module-revision#", NULL);
1321 if (prop)
1322 pbm->chip_revision = *(int *) prop->value;
1317 1323
1318 pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE; 1324 pbm->io_space.end = pbm->io_space.start + PSYCHO_IOSPACE_SIZE;
1319 pbm->io_space.flags = IORESOURCE_IO; 1325 pbm->io_space.flags = IORESOURCE_IO;
@@ -1322,45 +1328,36 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1322 pbm_register_toplevel_resources(p, pbm); 1328 pbm_register_toplevel_resources(p, pbm);
1323 1329
1324 pbm->parent = p; 1330 pbm->parent = p;
1325 pbm->prom_node = prom_node; 1331 pbm->prom_node = dp;
1326 prom_getstring(prom_node, "name", 1332 pbm->name = dp->full_name;
1327 pbm->prom_name, 1333
1328 sizeof(pbm->prom_name)); 1334 printk("%s: PSYCHO PCI Bus Module ver[%x:%x]\n",
1329 1335 pbm->name,
1330 err = prom_getproperty(prom_node, "ranges", 1336 pbm->chip_version, pbm->chip_revision);
1331 (char *)pbm->pbm_ranges, 1337
1332 sizeof(pbm->pbm_ranges)); 1338 prop = of_find_property(dp, "ranges", &len);
1333 if (err != -1) 1339 if (prop) {
1340 pbm->pbm_ranges = prop->value;
1334 pbm->num_pbm_ranges = 1341 pbm->num_pbm_ranges =
1335 (err / sizeof(struct linux_prom_pci_ranges)); 1342 (len / sizeof(struct linux_prom_pci_ranges));
1336 else 1343 } else {
1337 pbm->num_pbm_ranges = 0; 1344 pbm->num_pbm_ranges = 0;
1345 }
1338 1346
1339 err = prom_getproperty(prom_node, "interrupt-map", 1347 prop = of_find_property(dp, "interrupt-map", &len);
1340 (char *)pbm->pbm_intmap, 1348 if (prop) {
1341 sizeof(pbm->pbm_intmap)); 1349 pbm->pbm_intmap = prop->value;
1342 if (err != -1) { 1350 pbm->num_pbm_intmap =
1343 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1351 (len / sizeof(struct linux_prom_pci_intmap));
1344 err = prom_getproperty(prom_node, "interrupt-map-mask", 1352
1345 (char *)&pbm->pbm_intmask, 1353 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1346 sizeof(pbm->pbm_intmask)); 1354 pbm->pbm_intmask = prop->value;
1347 if (err == -1) {
1348 prom_printf("PSYCHO-PBM: Fatal error, no "
1349 "interrupt-map-mask.\n");
1350 prom_halt();
1351 }
1352 } else { 1355 } else {
1353 pbm->num_pbm_intmap = 0; 1356 pbm->num_pbm_intmap = 0;
1354 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1355 } 1357 }
1356 1358
1357 err = prom_getproperty(prom_node, "bus-range", 1359 prop = of_find_property(dp, "bus-range", NULL);
1358 (char *)&busrange[0], 1360 busrange = prop->value;
1359 sizeof(busrange));
1360 if (err == 0 || err == -1) {
1361 prom_printf("PSYCHO-PBM: Fatal error, no bus-range.\n");
1362 prom_halt();
1363 }
1364 pbm->pci_first_busno = busrange[0]; 1361 pbm->pci_first_busno = busrange[0];
1365 pbm->pci_last_busno = busrange[1]; 1362 pbm->pci_last_busno = busrange[1];
1366 1363
@@ -1369,20 +1366,24 @@ static void psycho_pbm_init(struct pci_controller_info *p,
1369 1366
1370#define PSYCHO_CONFIGSPACE 0x001000000UL 1367#define PSYCHO_CONFIGSPACE 0x001000000UL
1371 1368
1372void psycho_init(int node, char *model_name) 1369void psycho_init(struct device_node *dp, char *model_name)
1373{ 1370{
1374 struct linux_prom64_registers pr_regs[3]; 1371 struct linux_prom64_registers *pr_regs;
1375 struct pci_controller_info *p; 1372 struct pci_controller_info *p;
1376 struct pci_iommu *iommu; 1373 struct pci_iommu *iommu;
1374 struct property *prop;
1377 u32 upa_portid; 1375 u32 upa_portid;
1378 int is_pbm_a, err; 1376 int is_pbm_a;
1379 1377
1380 upa_portid = prom_getintdefault(node, "upa-portid", 0xff); 1378 upa_portid = 0xff;
1379 prop = of_find_property(dp, "upa-portid", NULL);
1380 if (prop)
1381 upa_portid = *(u32 *) prop->value;
1381 1382
1382 for(p = pci_controller_root; p; p = p->next) { 1383 for(p = pci_controller_root; p; p = p->next) {
1383 if (p->pbm_A.portid == upa_portid) { 1384 if (p->pbm_A.portid == upa_portid) {
1384 is_pbm_a = (p->pbm_A.prom_node == 0); 1385 is_pbm_a = (p->pbm_A.prom_node == NULL);
1385 psycho_pbm_init(p, node, is_pbm_a); 1386 psycho_pbm_init(p, dp, is_pbm_a);
1386 return; 1387 return;
1387 } 1388 }
1388 } 1389 }
@@ -1412,23 +1413,14 @@ void psycho_init(int node, char *model_name)
1412 p->resource_adjust = psycho_resource_adjust; 1413 p->resource_adjust = psycho_resource_adjust;
1413 p->pci_ops = &psycho_ops; 1414 p->pci_ops = &psycho_ops;
1414 1415
1415 err = prom_getproperty(node, "reg", 1416 prop = of_find_property(dp, "reg", NULL);
1416 (char *)&pr_regs[0], 1417 pr_regs = prop->value;
1417 sizeof(pr_regs));
1418 if (err == 0 || err == -1) {
1419 prom_printf("PSYCHO: Fatal error, no reg property.\n");
1420 prom_halt();
1421 }
1422 1418
1423 p->pbm_A.controller_regs = pr_regs[2].phys_addr; 1419 p->pbm_A.controller_regs = pr_regs[2].phys_addr;
1424 p->pbm_B.controller_regs = pr_regs[2].phys_addr; 1420 p->pbm_B.controller_regs = pr_regs[2].phys_addr;
1425 printk("PCI: Found PSYCHO, control regs at %016lx\n",
1426 p->pbm_A.controller_regs);
1427 1421
1428 p->pbm_A.config_space = p->pbm_B.config_space = 1422 p->pbm_A.config_space = p->pbm_B.config_space =
1429 (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE); 1423 (pr_regs[2].phys_addr + PSYCHO_CONFIGSPACE);
1430 printk("PSYCHO: Shared PCI config space at %016lx\n",
1431 p->pbm_A.config_space);
1432 1424
1433 /* 1425 /*
1434 * Psycho's PCI MEM space is mapped to a 2GB aligned area, so 1426 * Psycho's PCI MEM space is mapped to a 2GB aligned area, so
@@ -1441,5 +1433,5 @@ void psycho_init(int node, char *model_name)
1441 psycho_iommu_init(p); 1433 psycho_iommu_init(p);
1442 1434
1443 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000); 1435 is_pbm_a = ((pr_regs[0].phys_addr & 0x6000) == 0x2000);
1444 psycho_pbm_init(p, node, is_pbm_a); 1436 psycho_pbm_init(p, dp, is_pbm_a);
1445} 1437}
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index b7d997b55f0a..26f194ce4400 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -19,6 +19,7 @@
19#include <asm/irq.h> 19#include <asm/irq.h>
20#include <asm/smp.h> 20#include <asm/smp.h>
21#include <asm/oplib.h> 21#include <asm/oplib.h>
22#include <asm/prom.h>
22 23
23#include "pci_impl.h" 24#include "pci_impl.h"
24#include "iommu_common.h" 25#include "iommu_common.h"
@@ -1306,34 +1307,36 @@ static void pbm_register_toplevel_resources(struct pci_controller_info *p,
1306 &pbm->mem_space); 1307 &pbm->mem_space);
1307} 1308}
1308 1309
1309static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dma_begin) 1310static void sabre_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 dma_begin)
1310{ 1311{
1311 struct pci_pbm_info *pbm; 1312 struct pci_pbm_info *pbm;
1312 char namebuf[128]; 1313 struct device_node *node;
1313 u32 busrange[2]; 1314 struct property *prop;
1314 int node, simbas_found; 1315 u32 *busrange;
1316 int len, simbas_found;
1315 1317
1316 simbas_found = 0; 1318 simbas_found = 0;
1317 node = prom_getchild(sabre_node); 1319 node = dp->child;
1318 while ((node = prom_searchsiblings(node, "pci")) != 0) { 1320 while (node != NULL) {
1319 int err; 1321 if (strcmp(node->name, "pci"))
1320
1321 err = prom_getproperty(node, "model", namebuf, sizeof(namebuf));
1322 if ((err <= 0) || strncmp(namebuf, "SUNW,simba", err))
1323 goto next_pci; 1322 goto next_pci;
1324 1323
1325 err = prom_getproperty(node, "bus-range", 1324 prop = of_find_property(node, "model", NULL);
1326 (char *)&busrange[0], sizeof(busrange)); 1325 if (!prop || strncmp(prop->value, "SUNW,simba", prop->length))
1327 if (err == 0 || err == -1) { 1326 goto next_pci;
1328 prom_printf("APB: Error, cannot get PCI bus-range.\n");
1329 prom_halt();
1330 }
1331 1327
1332 simbas_found++; 1328 simbas_found++;
1329
1330 prop = of_find_property(node, "bus-range", NULL);
1331 busrange = prop->value;
1333 if (busrange[0] == 1) 1332 if (busrange[0] == 1)
1334 pbm = &p->pbm_B; 1333 pbm = &p->pbm_B;
1335 else 1334 else
1336 pbm = &p->pbm_A; 1335 pbm = &p->pbm_A;
1336
1337 pbm->name = node->full_name;
1338 printk("%s: SABRE PCI Bus Module\n", pbm->name);
1339
1337 pbm->chip_type = PBM_CHIP_TYPE_SABRE; 1340 pbm->chip_type = PBM_CHIP_TYPE_SABRE;
1338 pbm->parent = p; 1341 pbm->parent = p;
1339 pbm->prom_node = node; 1342 pbm->prom_node = node;
@@ -1341,83 +1344,68 @@ static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dm
1341 pbm->pci_first_busno = busrange[0]; 1344 pbm->pci_first_busno = busrange[0];
1342 pbm->pci_last_busno = busrange[1]; 1345 pbm->pci_last_busno = busrange[1];
1343 1346
1344 prom_getstring(node, "name", pbm->prom_name, sizeof(pbm->prom_name)); 1347 prop = of_find_property(node, "ranges", &len);
1345 err = prom_getproperty(node, "ranges", 1348 if (prop) {
1346 (char *)pbm->pbm_ranges, 1349 pbm->pbm_ranges = prop->value;
1347 sizeof(pbm->pbm_ranges));
1348 if (err != -1)
1349 pbm->num_pbm_ranges = 1350 pbm->num_pbm_ranges =
1350 (err / sizeof(struct linux_prom_pci_ranges)); 1351 (len / sizeof(struct linux_prom_pci_ranges));
1351 else 1352 } else {
1352 pbm->num_pbm_ranges = 0; 1353 pbm->num_pbm_ranges = 0;
1354 }
1353 1355
1354 err = prom_getproperty(node, "interrupt-map", 1356 prop = of_find_property(node, "interrupt-map", &len);
1355 (char *)pbm->pbm_intmap, 1357 if (prop) {
1356 sizeof(pbm->pbm_intmap)); 1358 pbm->pbm_intmap = prop->value;
1357 if (err != -1) { 1359 pbm->num_pbm_intmap =
1358 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1360 (len / sizeof(struct linux_prom_pci_intmap));
1359 err = prom_getproperty(node, "interrupt-map-mask", 1361
1360 (char *)&pbm->pbm_intmask, 1362 prop = of_find_property(node, "interrupt-map-mask",
1361 sizeof(pbm->pbm_intmask)); 1363 NULL);
1362 if (err == -1) { 1364 pbm->pbm_intmask = prop->value;
1363 prom_printf("APB: Fatal error, no interrupt-map-mask.\n");
1364 prom_halt();
1365 }
1366 } else { 1365 } else {
1367 pbm->num_pbm_intmap = 0; 1366 pbm->num_pbm_intmap = 0;
1368 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1369 } 1367 }
1370 1368
1371 pbm_register_toplevel_resources(p, pbm); 1369 pbm_register_toplevel_resources(p, pbm);
1372 1370
1373 next_pci: 1371 next_pci:
1374 node = prom_getsibling(node); 1372 node = node->sibling;
1375 if (!node)
1376 break;
1377 } 1373 }
1378 if (simbas_found == 0) { 1374 if (simbas_found == 0) {
1379 int err;
1380
1381 /* No APBs underneath, probably this is a hummingbird 1375 /* No APBs underneath, probably this is a hummingbird
1382 * system. 1376 * system.
1383 */ 1377 */
1384 pbm = &p->pbm_A; 1378 pbm = &p->pbm_A;
1385 pbm->parent = p; 1379 pbm->parent = p;
1386 pbm->prom_node = sabre_node; 1380 pbm->prom_node = dp;
1387 pbm->pci_first_busno = p->pci_first_busno; 1381 pbm->pci_first_busno = p->pci_first_busno;
1388 pbm->pci_last_busno = p->pci_last_busno; 1382 pbm->pci_last_busno = p->pci_last_busno;
1389 1383
1390 prom_getstring(sabre_node, "name", pbm->prom_name, sizeof(pbm->prom_name)); 1384 prop = of_find_property(dp, "ranges", &len);
1391 err = prom_getproperty(sabre_node, "ranges", 1385 if (prop) {
1392 (char *) pbm->pbm_ranges, 1386 pbm->pbm_ranges = prop->value;
1393 sizeof(pbm->pbm_ranges));
1394 if (err != -1)
1395 pbm->num_pbm_ranges = 1387 pbm->num_pbm_ranges =
1396 (err / sizeof(struct linux_prom_pci_ranges)); 1388 (len / sizeof(struct linux_prom_pci_ranges));
1397 else 1389 } else {
1398 pbm->num_pbm_ranges = 0; 1390 pbm->num_pbm_ranges = 0;
1391 }
1399 1392
1400 err = prom_getproperty(sabre_node, "interrupt-map", 1393 prop = of_find_property(dp, "interrupt-map", &len);
1401 (char *) pbm->pbm_intmap, 1394 if (prop) {
1402 sizeof(pbm->pbm_intmap)); 1395 pbm->pbm_intmap = prop->value;
1403 1396 pbm->num_pbm_intmap =
1404 if (err != -1) { 1397 (len / sizeof(struct linux_prom_pci_intmap));
1405 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1398
1406 err = prom_getproperty(sabre_node, "interrupt-map-mask", 1399 prop = of_find_property(dp, "interrupt-map-mask",
1407 (char *)&pbm->pbm_intmask, 1400 NULL);
1408 sizeof(pbm->pbm_intmask)); 1401 pbm->pbm_intmask = prop->value;
1409 if (err == -1) {
1410 prom_printf("Hummingbird: Fatal error, no interrupt-map-mask.\n");
1411 prom_halt();
1412 }
1413 } else { 1402 } else {
1414 pbm->num_pbm_intmap = 0; 1403 pbm->num_pbm_intmap = 0;
1415 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1416 } 1404 }
1417 1405
1406 pbm->name = dp->full_name;
1407 printk("%s: SABRE PCI Bus Module\n", pbm->name);
1418 1408
1419 sprintf(pbm->name, "SABRE%d PBM%c", p->index,
1420 (pbm == &p->pbm_A ? 'A' : 'B'));
1421 pbm->io_space.name = pbm->mem_space.name = pbm->name; 1409 pbm->io_space.name = pbm->mem_space.name = pbm->name;
1422 1410
1423 /* Hack up top-level resources. */ 1411 /* Hack up top-level resources. */
@@ -1443,14 +1431,15 @@ static void sabre_pbm_init(struct pci_controller_info *p, int sabre_node, u32 dm
1443 } 1431 }
1444} 1432}
1445 1433
1446void sabre_init(int pnode, char *model_name) 1434void sabre_init(struct device_node *dp, char *model_name)
1447{ 1435{
1448 struct linux_prom64_registers pr_regs[2]; 1436 struct linux_prom64_registers *pr_regs;
1449 struct pci_controller_info *p; 1437 struct pci_controller_info *p;
1450 struct pci_iommu *iommu; 1438 struct pci_iommu *iommu;
1451 int tsbsize, err; 1439 struct property *prop;
1452 u32 busrange[2]; 1440 int tsbsize;
1453 u32 vdma[2]; 1441 u32 *busrange;
1442 u32 *vdma;
1454 u32 upa_portid, dma_mask; 1443 u32 upa_portid, dma_mask;
1455 u64 clear_irq; 1444 u64 clear_irq;
1456 1445
@@ -1458,22 +1447,21 @@ void sabre_init(int pnode, char *model_name)
1458 if (!strcmp(model_name, "pci108e,a001")) 1447 if (!strcmp(model_name, "pci108e,a001"))
1459 hummingbird_p = 1; 1448 hummingbird_p = 1;
1460 else if (!strcmp(model_name, "SUNW,sabre")) { 1449 else if (!strcmp(model_name, "SUNW,sabre")) {
1461 char compat[64]; 1450 prop = of_find_property(dp, "compatible", NULL);
1451 if (prop) {
1452 const char *compat = prop->value;
1462 1453
1463 if (prom_getproperty(pnode, "compatible", 1454 if (!strcmp(compat, "pci108e,a001"))
1464 compat, sizeof(compat)) > 0 && 1455 hummingbird_p = 1;
1465 !strcmp(compat, "pci108e,a001")) { 1456 }
1466 hummingbird_p = 1; 1457 if (!hummingbird_p) {
1467 } else { 1458 struct device_node *dp;
1468 int cpu_node;
1469 1459
1470 /* Of course, Sun has to encode things a thousand 1460 /* Of course, Sun has to encode things a thousand
1471 * different ways, inconsistently. 1461 * different ways, inconsistently.
1472 */ 1462 */
1473 cpu_find_by_instance(0, &cpu_node, NULL); 1463 cpu_find_by_instance(0, &dp, NULL);
1474 if (prom_getproperty(cpu_node, "name", 1464 if (!strcmp(dp->name, "SUNW,UltraSPARC-IIe"))
1475 compat, sizeof(compat)) > 0 &&
1476 !strcmp(compat, "SUNW,UltraSPARC-IIe"))
1477 hummingbird_p = 1; 1465 hummingbird_p = 1;
1478 } 1466 }
1479 } 1467 }
@@ -1491,7 +1479,10 @@ void sabre_init(int pnode, char *model_name)
1491 } 1479 }
1492 p->pbm_A.iommu = p->pbm_B.iommu = iommu; 1480 p->pbm_A.iommu = p->pbm_B.iommu = iommu;
1493 1481
1494 upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff); 1482 upa_portid = 0xff;
1483 prop = of_find_property(dp, "upa-portid", NULL);
1484 if (prop)
1485 upa_portid = *(u32 *) prop->value;
1495 1486
1496 p->next = pci_controller_root; 1487 p->next = pci_controller_root;
1497 pci_controller_root = p; 1488 pci_controller_root = p;
@@ -1509,13 +1500,9 @@ void sabre_init(int pnode, char *model_name)
1509 /* 1500 /*
1510 * Map in SABRE register set and report the presence of this SABRE. 1501 * Map in SABRE register set and report the presence of this SABRE.
1511 */ 1502 */
1512 err = prom_getproperty(pnode, "reg", 1503
1513 (char *)&pr_regs[0], sizeof(pr_regs)); 1504 prop = of_find_property(dp, "reg", NULL);
1514 if(err == 0 || err == -1) { 1505 pr_regs = prop->value;
1515 prom_printf("SABRE: Error, cannot get U2P registers "
1516 "from PROM.\n");
1517 prom_halt();
1518 }
1519 1506
1520 /* 1507 /*
1521 * First REG in property is base of entire SABRE register space. 1508 * First REG in property is base of entire SABRE register space.
@@ -1523,9 +1510,6 @@ void sabre_init(int pnode, char *model_name)
1523 p->pbm_A.controller_regs = pr_regs[0].phys_addr; 1510 p->pbm_A.controller_regs = pr_regs[0].phys_addr;
1524 p->pbm_B.controller_regs = pr_regs[0].phys_addr; 1511 p->pbm_B.controller_regs = pr_regs[0].phys_addr;
1525 1512
1526 printk("PCI: Found SABRE, main regs at %016lx\n",
1527 p->pbm_A.controller_regs);
1528
1529 /* Clear interrupts */ 1513 /* Clear interrupts */
1530 1514
1531 /* PCI first */ 1515 /* PCI first */
@@ -1544,16 +1528,9 @@ void sabre_init(int pnode, char *model_name)
1544 /* Now map in PCI config space for entire SABRE. */ 1528 /* Now map in PCI config space for entire SABRE. */
1545 p->pbm_A.config_space = p->pbm_B.config_space = 1529 p->pbm_A.config_space = p->pbm_B.config_space =
1546 (p->pbm_A.controller_regs + SABRE_CONFIGSPACE); 1530 (p->pbm_A.controller_regs + SABRE_CONFIGSPACE);
1547 printk("SABRE: Shared PCI config space at %016lx\n", 1531
1548 p->pbm_A.config_space); 1532 prop = of_find_property(dp, "virtual-dma", NULL);
1549 1533 vdma = prop->value;
1550 err = prom_getproperty(pnode, "virtual-dma",
1551 (char *)&vdma[0], sizeof(vdma));
1552 if(err == 0 || err == -1) {
1553 prom_printf("SABRE: Error, cannot get virtual-dma property "
1554 "from PROM.\n");
1555 prom_halt();
1556 }
1557 1534
1558 dma_mask = vdma[0]; 1535 dma_mask = vdma[0];
1559 switch(vdma[1]) { 1536 switch(vdma[1]) {
@@ -1577,21 +1554,13 @@ void sabre_init(int pnode, char *model_name)
1577 1554
1578 sabre_iommu_init(p, tsbsize, vdma[0], dma_mask); 1555 sabre_iommu_init(p, tsbsize, vdma[0], dma_mask);
1579 1556
1580 printk("SABRE: DVMA at %08x [%08x]\n", vdma[0], vdma[1]); 1557 prop = of_find_property(dp, "bus-range", NULL);
1581 1558 busrange = prop->value;
1582 err = prom_getproperty(pnode, "bus-range",
1583 (char *)&busrange[0], sizeof(busrange));
1584 if(err == 0 || err == -1) {
1585 prom_printf("SABRE: Error, cannot get PCI bus-range "
1586 " from PROM.\n");
1587 prom_halt();
1588 }
1589
1590 p->pci_first_busno = busrange[0]; 1559 p->pci_first_busno = busrange[0];
1591 p->pci_last_busno = busrange[1]; 1560 p->pci_last_busno = busrange[1];
1592 1561
1593 /* 1562 /*
1594 * Look for APB underneath. 1563 * Look for APB underneath.
1595 */ 1564 */
1596 sabre_pbm_init(p, pnode, vdma[0]); 1565 sabre_pbm_init(p, dp, vdma[0]);
1597} 1566}
diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c
index cc662e915d32..f16449ccd7bc 100644
--- a/arch/sparc64/kernel/pci_schizo.c
+++ b/arch/sparc64/kernel/pci_schizo.c
@@ -16,6 +16,7 @@
16#include <asm/irq.h> 16#include <asm/irq.h>
17#include <asm/upa.h> 17#include <asm/upa.h>
18#include <asm/pstate.h> 18#include <asm/pstate.h>
19#include <asm/prom.h>
19 20
20#include "pci_impl.h" 21#include "pci_impl.h"
21#include "iommu_common.h" 22#include "iommu_common.h"
@@ -1456,10 +1457,12 @@ static void __schizo_scan_bus(struct pci_controller_info *p,
1456 1457
1457 pbm_config_busmastering(&p->pbm_B); 1458 pbm_config_busmastering(&p->pbm_B);
1458 p->pbm_B.is_66mhz_capable = 1459 p->pbm_B.is_66mhz_capable =
1459 prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); 1460 (of_find_property(p->pbm_B.prom_node, "66mhz-capable", NULL)
1461 != NULL);
1460 pbm_config_busmastering(&p->pbm_A); 1462 pbm_config_busmastering(&p->pbm_A);
1461 p->pbm_A.is_66mhz_capable = 1463 p->pbm_A.is_66mhz_capable =
1462 prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); 1464 (of_find_property(p->pbm_A.prom_node, "66mhz-capable", NULL)
1465 != NULL);
1463 pbm_scan_bus(p, &p->pbm_B); 1466 pbm_scan_bus(p, &p->pbm_B);
1464 pbm_scan_bus(p, &p->pbm_A); 1467 pbm_scan_bus(p, &p->pbm_A);
1465 1468
@@ -1661,13 +1664,18 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1661{ 1664{
1662 struct pci_iommu *iommu = pbm->iommu; 1665 struct pci_iommu *iommu = pbm->iommu;
1663 unsigned long i, tagbase, database; 1666 unsigned long i, tagbase, database;
1667 struct property *prop;
1664 u32 vdma[2], dma_mask; 1668 u32 vdma[2], dma_mask;
1665 u64 control; 1669 u64 control;
1666 int err, tsbsize; 1670 int tsbsize;
1667 1671
1668 err = prom_getproperty(pbm->prom_node, "virtual-dma", 1672 prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
1669 (char *)&vdma[0], sizeof(vdma)); 1673 if (prop) {
1670 if (err == 0 || err == -1) { 1674 u32 *val = prop->value;
1675
1676 vdma[0] = val[0];
1677 vdma[1] = val[1];
1678 } else {
1671 /* No property, use default values. */ 1679 /* No property, use default values. */
1672 vdma[0] = 0xc0000000; 1680 vdma[0] = 0xc0000000;
1673 vdma[1] = 0x40000000; 1681 vdma[1] = 0x40000000;
@@ -1778,6 +1786,7 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
1778 1786
1779static void schizo_pbm_hw_init(struct pci_pbm_info *pbm) 1787static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1780{ 1788{
1789 struct property *prop;
1781 u64 tmp; 1790 u64 tmp;
1782 1791
1783 schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); 1792 schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5);
@@ -1791,7 +1800,8 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1791 pbm->chip_version >= 0x2) 1800 pbm->chip_version >= 0x2)
1792 tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; 1801 tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT;
1793 1802
1794 if (!prom_getbool(pbm->prom_node, "no-bus-parking")) 1803 prop = of_find_property(pbm->prom_node, "no-bus-parking", NULL);
1804 if (!prop)
1795 tmp |= SCHIZO_PCICTRL_PARK; 1805 tmp |= SCHIZO_PCICTRL_PARK;
1796 else 1806 else
1797 tmp &= ~SCHIZO_PCICTRL_PARK; 1807 tmp &= ~SCHIZO_PCICTRL_PARK;
@@ -1831,16 +1841,17 @@ static void schizo_pbm_hw_init(struct pci_pbm_info *pbm)
1831} 1841}
1832 1842
1833static void schizo_pbm_init(struct pci_controller_info *p, 1843static void schizo_pbm_init(struct pci_controller_info *p,
1834 int prom_node, u32 portid, 1844 struct device_node *dp, u32 portid,
1835 int chip_type) 1845 int chip_type)
1836{ 1846{
1837 struct linux_prom64_registers pr_regs[4]; 1847 struct linux_prom64_registers *regs;
1838 unsigned int busrange[2]; 1848 struct property *prop;
1849 unsigned int *busrange;
1839 struct pci_pbm_info *pbm; 1850 struct pci_pbm_info *pbm;
1840 const char *chipset_name; 1851 const char *chipset_name;
1841 u32 ino_bitmap[2]; 1852 u32 *ino_bitmap;
1842 int is_pbm_a; 1853 int is_pbm_a;
1843 int err; 1854 int len;
1844 1855
1845 switch (chip_type) { 1856 switch (chip_type) {
1846 case PBM_CHIP_TYPE_TOMATILLO: 1857 case PBM_CHIP_TYPE_TOMATILLO:
@@ -1868,16 +1879,10 @@ static void schizo_pbm_init(struct pci_controller_info *p,
1868 * 3) PBM PCI config space 1879 * 3) PBM PCI config space
1869 * 4) Ichip regs 1880 * 4) Ichip regs
1870 */ 1881 */
1871 err = prom_getproperty(prom_node, "reg", 1882 prop = of_find_property(dp, "reg", NULL);
1872 (char *)&pr_regs[0], 1883 regs = prop->value;
1873 sizeof(pr_regs));
1874 if (err == 0 || err == -1) {
1875 prom_printf("%s: Fatal error, no reg property.\n",
1876 chipset_name);
1877 prom_halt();
1878 }
1879 1884
1880 is_pbm_a = ((pr_regs[0].phys_addr & 0x00700000) == 0x00600000); 1885 is_pbm_a = ((regs[0].phys_addr & 0x00700000) == 0x00600000);
1881 1886
1882 if (is_pbm_a) 1887 if (is_pbm_a)
1883 pbm = &p->pbm_A; 1888 pbm = &p->pbm_A;
@@ -1886,92 +1891,62 @@ static void schizo_pbm_init(struct pci_controller_info *p,
1886 1891
1887 pbm->portid = portid; 1892 pbm->portid = portid;
1888 pbm->parent = p; 1893 pbm->parent = p;
1889 pbm->prom_node = prom_node; 1894 pbm->prom_node = dp;
1890 pbm->pci_first_slot = 1; 1895 pbm->pci_first_slot = 1;
1891 1896
1892 pbm->chip_type = chip_type; 1897 pbm->chip_type = chip_type;
1893 pbm->chip_version = 1898 pbm->chip_version = 0;
1894 prom_getintdefault(prom_node, "version#", 0); 1899 prop = of_find_property(dp, "version#", NULL);
1895 pbm->chip_revision = 1900 if (prop)
1896 prom_getintdefault(prom_node, "module-revision#", 0); 1901 pbm->chip_version = *(int *) prop->value;
1897 1902 pbm->chip_revision = 0;
1898 pbm->pbm_regs = pr_regs[0].phys_addr; 1903 prop = of_find_property(dp, "module-revision#", NULL);
1899 pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; 1904 if (prop)
1905 pbm->chip_revision = *(int *) prop->value;
1906
1907 pbm->pbm_regs = regs[0].phys_addr;
1908 pbm->controller_regs = regs[1].phys_addr - 0x10000UL;
1900 1909
1901 if (chip_type == PBM_CHIP_TYPE_TOMATILLO) 1910 if (chip_type == PBM_CHIP_TYPE_TOMATILLO)
1902 pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; 1911 pbm->sync_reg = regs[3].phys_addr + 0x1a18UL;
1903 1912
1904 sprintf(pbm->name, 1913 pbm->name = dp->full_name;
1905 (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
1906 "TOMATILLO%d PBM%c" :
1907 "SCHIZO%d PBM%c"),
1908 p->index,
1909 (pbm == &p->pbm_A ? 'A' : 'B'));
1910 1914
1911 printk("%s: ver[%x:%x], portid %x, " 1915 printk("%s: %s PCI Bus Module ver[%x:%x]\n",
1912 "cregs[%lx] pregs[%lx]\n",
1913 pbm->name, 1916 pbm->name,
1914 pbm->chip_version, pbm->chip_revision, 1917 (chip_type == PBM_CHIP_TYPE_TOMATILLO ?
1915 pbm->portid, 1918 "TOMATILLO" : "SCHIZO"),
1916 pbm->controller_regs, 1919 pbm->chip_version, pbm->chip_revision);
1917 pbm->pbm_regs);
1918 1920
1919 schizo_pbm_hw_init(pbm); 1921 schizo_pbm_hw_init(pbm);
1920 1922
1921 prom_getstring(prom_node, "name", 1923 prop = of_find_property(dp, "ranges", &len);
1922 pbm->prom_name, 1924 pbm->pbm_ranges = prop->value;
1923 sizeof(pbm->prom_name));
1924
1925 err = prom_getproperty(prom_node, "ranges",
1926 (char *) pbm->pbm_ranges,
1927 sizeof(pbm->pbm_ranges));
1928 if (err == 0 || err == -1) {
1929 prom_printf("%s: Fatal error, no ranges property.\n",
1930 pbm->name);
1931 prom_halt();
1932 }
1933
1934 pbm->num_pbm_ranges = 1925 pbm->num_pbm_ranges =
1935 (err / sizeof(struct linux_prom_pci_ranges)); 1926 (len / sizeof(struct linux_prom_pci_ranges));
1936 1927
1937 schizo_determine_mem_io_space(pbm); 1928 schizo_determine_mem_io_space(pbm);
1938 pbm_register_toplevel_resources(p, pbm); 1929 pbm_register_toplevel_resources(p, pbm);
1939 1930
1940 err = prom_getproperty(prom_node, "interrupt-map", 1931 prop = of_find_property(dp, "interrupt-map", &len);
1941 (char *)pbm->pbm_intmap, 1932 if (prop) {
1942 sizeof(pbm->pbm_intmap)); 1933 pbm->pbm_intmap = prop->value;
1943 if (err != -1) { 1934 pbm->num_pbm_intmap =
1944 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1935 (len / sizeof(struct linux_prom_pci_intmap));
1945 err = prom_getproperty(prom_node, "interrupt-map-mask", 1936
1946 (char *)&pbm->pbm_intmask, 1937 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1947 sizeof(pbm->pbm_intmask)); 1938 pbm->pbm_intmask = prop->value;
1948 if (err == -1) {
1949 prom_printf("%s: Fatal error, no "
1950 "interrupt-map-mask.\n", pbm->name);
1951 prom_halt();
1952 }
1953 } else { 1939 } else {
1954 pbm->num_pbm_intmap = 0; 1940 pbm->num_pbm_intmap = 0;
1955 memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
1956 } 1941 }
1957 1942
1958 err = prom_getproperty(prom_node, "ino-bitmap", 1943 prop = of_find_property(dp, "ino-bitmap", NULL);
1959 (char *) &ino_bitmap[0], 1944 ino_bitmap = prop->value;
1960 sizeof(ino_bitmap));
1961 if (err == 0 || err == -1) {
1962 prom_printf("%s: Fatal error, no ino-bitmap.\n", pbm->name);
1963 prom_halt();
1964 }
1965 pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) | 1945 pbm->ino_bitmap = (((u64)ino_bitmap[1] << 32UL) |
1966 ((u64)ino_bitmap[0] << 0UL)); 1946 ((u64)ino_bitmap[0] << 0UL));
1967 1947
1968 err = prom_getproperty(prom_node, "bus-range", 1948 prop = of_find_property(dp, "bus-range", NULL);
1969 (char *)&busrange[0], 1949 busrange = prop->value;
1970 sizeof(busrange));
1971 if (err == 0 || err == -1) {
1972 prom_printf("%s: Fatal error, no bus-range.\n", pbm->name);
1973 prom_halt();
1974 }
1975 pbm->pci_first_busno = busrange[0]; 1950 pbm->pci_first_busno = busrange[0];
1976 pbm->pci_last_busno = busrange[1]; 1951 pbm->pci_last_busno = busrange[1];
1977 1952
@@ -1989,16 +1964,20 @@ static inline int portid_compare(u32 x, u32 y, int chip_type)
1989 return (x == y); 1964 return (x == y);
1990} 1965}
1991 1966
1992static void __schizo_init(int node, char *model_name, int chip_type) 1967static void __schizo_init(struct device_node *dp, char *model_name, int chip_type)
1993{ 1968{
1994 struct pci_controller_info *p; 1969 struct pci_controller_info *p;
1995 struct pci_iommu *iommu; 1970 struct pci_iommu *iommu;
1971 struct property *prop;
1996 int is_pbm_a; 1972 int is_pbm_a;
1997 u32 portid; 1973 u32 portid;
1998 1974
1999 portid = prom_getintdefault(node, "portid", 0xff); 1975 portid = 0xff;
1976 prop = of_find_property(dp, "portid", NULL);
1977 if (prop)
1978 portid = *(u32 *) prop->value;
2000 1979
2001 for(p = pci_controller_root; p; p = p->next) { 1980 for (p = pci_controller_root; p; p = p->next) {
2002 struct pci_pbm_info *pbm; 1981 struct pci_pbm_info *pbm;
2003 1982
2004 if (p->pbm_A.prom_node && p->pbm_B.prom_node) 1983 if (p->pbm_A.prom_node && p->pbm_B.prom_node)
@@ -2009,8 +1988,8 @@ static void __schizo_init(int node, char *model_name, int chip_type)
2009 &p->pbm_B); 1988 &p->pbm_B);
2010 1989
2011 if (portid_compare(pbm->portid, portid, chip_type)) { 1990 if (portid_compare(pbm->portid, portid, chip_type)) {
2012 is_pbm_a = (p->pbm_A.prom_node == 0); 1991 is_pbm_a = (p->pbm_A.prom_node == NULL);
2013 schizo_pbm_init(p, node, portid, chip_type); 1992 schizo_pbm_init(p, dp, portid, chip_type);
2014 return; 1993 return;
2015 } 1994 }
2016 } 1995 }
@@ -2051,20 +2030,20 @@ static void __schizo_init(int node, char *model_name, int chip_type)
2051 /* Like PSYCHO we have a 2GB aligned area for memory space. */ 2030 /* Like PSYCHO we have a 2GB aligned area for memory space. */
2052 pci_memspace_mask = 0x7fffffffUL; 2031 pci_memspace_mask = 0x7fffffffUL;
2053 2032
2054 schizo_pbm_init(p, node, portid, chip_type); 2033 schizo_pbm_init(p, dp, portid, chip_type);
2055} 2034}
2056 2035
2057void schizo_init(int node, char *model_name) 2036void schizo_init(struct device_node *dp, char *model_name)
2058{ 2037{
2059 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO); 2038 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO);
2060} 2039}
2061 2040
2062void schizo_plus_init(int node, char *model_name) 2041void schizo_plus_init(struct device_node *dp, char *model_name)
2063{ 2042{
2064 __schizo_init(node, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS); 2043 __schizo_init(dp, model_name, PBM_CHIP_TYPE_SCHIZO_PLUS);
2065} 2044}
2066 2045
2067void tomatillo_init(int node, char *model_name) 2046void tomatillo_init(struct device_node *dp, char *model_name)
2068{ 2047{
2069 __schizo_init(node, model_name, PBM_CHIP_TYPE_TOMATILLO); 2048 __schizo_init(dp, model_name, PBM_CHIP_TYPE_TOMATILLO);
2070} 2049}
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 5419480edf41..b69e2270a721 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -18,6 +18,7 @@
18#include <asm/pstate.h> 18#include <asm/pstate.h>
19#include <asm/oplib.h> 19#include <asm/oplib.h>
20#include <asm/hypervisor.h> 20#include <asm/hypervisor.h>
21#include <asm/prom.h>
21 22
22#include "pci_impl.h" 23#include "pci_impl.h"
23#include "iommu_common.h" 24#include "iommu_common.h"
@@ -646,35 +647,37 @@ static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, u
646/* Recursively descend into the OBP device tree, rooted at toplevel_node, 647/* Recursively descend into the OBP device tree, rooted at toplevel_node,
647 * looking for a PCI device matching bus and devfn. 648 * looking for a PCI device matching bus and devfn.
648 */ 649 */
649static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) 650static int obp_find(struct device_node *toplevel_node, unsigned int bus, unsigned int devfn)
650{ 651{
651 toplevel_node = prom_getchild(toplevel_node); 652 toplevel_node = toplevel_node->child;
652 653
653 while (toplevel_node != 0) { 654 while (toplevel_node != NULL) {
654 int ret = obp_find(pregs, toplevel_node, bus, devfn); 655 struct linux_prom_pci_registers *regs;
656 struct property *prop;
657 int ret;
655 658
659 ret = obp_find(toplevel_node, bus, devfn);
656 if (ret != 0) 660 if (ret != 0)
657 return ret; 661 return ret;
658 662
659 ret = prom_getproperty(toplevel_node, "reg", (char *) pregs, 663 prop = of_find_property(toplevel_node, "reg", NULL);
660 sizeof(*pregs) * PROMREG_MAX); 664 if (!prop)
661 if (ret == 0 || ret == -1)
662 goto next_sibling; 665 goto next_sibling;
663 666
664 if (((pregs[0].phys_hi >> 16) & 0xff) == bus && 667 regs = prop->value;
665 ((pregs[0].phys_hi >> 8) & 0xff) == devfn) 668 if (((regs->phys_hi >> 16) & 0xff) == bus &&
669 ((regs->phys_hi >> 8) & 0xff) == devfn)
666 break; 670 break;
667 671
668 next_sibling: 672 next_sibling:
669 toplevel_node = prom_getsibling(toplevel_node); 673 toplevel_node = toplevel_node->sibling;
670 } 674 }
671 675
672 return toplevel_node; 676 return toplevel_node != NULL;
673} 677}
674 678
675static int pdev_htab_populate(struct pci_pbm_info *pbm) 679static int pdev_htab_populate(struct pci_pbm_info *pbm)
676{ 680{
677 struct linux_prom_pci_registers pr[PROMREG_MAX];
678 u32 devhandle = pbm->devhandle; 681 u32 devhandle = pbm->devhandle;
679 unsigned int bus; 682 unsigned int bus;
680 683
@@ -685,7 +688,7 @@ static int pdev_htab_populate(struct pci_pbm_info *pbm)
685 unsigned int device = PCI_SLOT(devfn); 688 unsigned int device = PCI_SLOT(devfn);
686 unsigned int func = PCI_FUNC(devfn); 689 unsigned int func = PCI_FUNC(devfn);
687 690
688 if (obp_find(pr, pbm->prom_node, bus, devfn)) { 691 if (obp_find(pbm->prom_node, bus, devfn)) {
689 int err = pdev_htab_add(devhandle, bus, 692 int err = pdev_htab_add(devhandle, bus,
690 device, func); 693 device, func);
691 if (err) 694 if (err)
@@ -811,8 +814,7 @@ static void pbm_scan_bus(struct pci_controller_info *p,
811 pci_fixup_host_bridge_self(pbm->pci_bus); 814 pci_fixup_host_bridge_self(pbm->pci_bus);
812 pbm->pci_bus->self->sysdata = cookie; 815 pbm->pci_bus->self->sysdata = cookie;
813#endif 816#endif
814 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, 817 pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
815 pbm->prom_node);
816 pci_record_assignments(pbm, pbm->pci_bus); 818 pci_record_assignments(pbm, pbm->pci_bus);
817 pci_assign_unassigned(pbm, pbm->pci_bus); 819 pci_assign_unassigned(pbm, pbm->pci_bus);
818 pci_fixup_irq(pbm, pbm->pci_bus); 820 pci_fixup_irq(pbm, pbm->pci_bus);
@@ -822,15 +824,18 @@ static void pbm_scan_bus(struct pci_controller_info *p,
822 824
823static void pci_sun4v_scan_bus(struct pci_controller_info *p) 825static void pci_sun4v_scan_bus(struct pci_controller_info *p)
824{ 826{
825 if (p->pbm_A.prom_node) { 827 struct property *prop;
826 p->pbm_A.is_66mhz_capable = 828 struct device_node *dp;
827 prom_getbool(p->pbm_A.prom_node, "66mhz-capable"); 829
830 if ((dp = p->pbm_A.prom_node) != NULL) {
831 prop = of_find_property(dp, "66mhz-capable", NULL);
832 p->pbm_A.is_66mhz_capable = (prop != NULL);
828 833
829 pbm_scan_bus(p, &p->pbm_A); 834 pbm_scan_bus(p, &p->pbm_A);
830 } 835 }
831 if (p->pbm_B.prom_node) { 836 if ((dp = p->pbm_B.prom_node) != NULL) {
832 p->pbm_B.is_66mhz_capable = 837 prop = of_find_property(dp, "66mhz-capable", NULL);
833 prom_getbool(p->pbm_B.prom_node, "66mhz-capable"); 838 p->pbm_B.is_66mhz_capable = (prop != NULL);
834 839
835 pbm_scan_bus(p, &p->pbm_B); 840 pbm_scan_bus(p, &p->pbm_B);
836 } 841 }
@@ -982,8 +987,13 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
982 HV_PCI_TSBID(0, i), 987 HV_PCI_TSBID(0, i),
983 &io_attrs, &ra); 988 &io_attrs, &ra);
984 if (ret == HV_EOK) { 989 if (ret == HV_EOK) {
985 cnt++; 990 if (page_in_phys_avail(ra)) {
986 __set_bit(i, arena->map); 991 pci_sun4v_iommu_demap(devhandle,
992 HV_PCI_TSBID(0, i), 1);
993 } else {
994 cnt++;
995 __set_bit(i, arena->map);
996 }
987 } 997 }
988 } 998 }
989 999
@@ -993,13 +1003,18 @@ static unsigned long probe_existing_entries(struct pci_pbm_info *pbm,
993static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm) 1003static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
994{ 1004{
995 struct pci_iommu *iommu = pbm->iommu; 1005 struct pci_iommu *iommu = pbm->iommu;
1006 struct property *prop;
996 unsigned long num_tsb_entries, sz; 1007 unsigned long num_tsb_entries, sz;
997 u32 vdma[2], dma_mask, dma_offset; 1008 u32 vdma[2], dma_mask, dma_offset;
998 int err, tsbsize; 1009 int tsbsize;
1010
1011 prop = of_find_property(pbm->prom_node, "virtual-dma", NULL);
1012 if (prop) {
1013 u32 *val = prop->value;
999 1014
1000 err = prom_getproperty(pbm->prom_node, "virtual-dma", 1015 vdma[0] = val[0];
1001 (char *)&vdma[0], sizeof(vdma)); 1016 vdma[1] = val[1];
1002 if (err == 0 || err == -1) { 1017 } else {
1003 /* No property, use default values. */ 1018 /* No property, use default values. */
1004 vdma[0] = 0x80000000; 1019 vdma[0] = 0x80000000;
1005 vdma[1] = 0x80000000; 1020 vdma[1] = 0x80000000;
@@ -1051,34 +1066,30 @@ static void pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
1051 iommu->arena.limit = num_tsb_entries; 1066 iommu->arena.limit = num_tsb_entries;
1052 1067
1053 sz = probe_existing_entries(pbm, iommu); 1068 sz = probe_existing_entries(pbm, iommu);
1054 1069 if (sz)
1055 printk("%s: TSB entries [%lu], existing mapings [%lu]\n", 1070 printk("%s: Imported %lu TSB entries from OBP\n",
1056 pbm->name, num_tsb_entries, sz); 1071 pbm->name, sz);
1057} 1072}
1058 1073
1059static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm) 1074static void pci_sun4v_get_bus_range(struct pci_pbm_info *pbm)
1060{ 1075{
1061 unsigned int busrange[2]; 1076 struct property *prop;
1062 int prom_node = pbm->prom_node; 1077 unsigned int *busrange;
1063 int err; 1078
1064 1079 prop = of_find_property(pbm->prom_node, "bus-range", NULL);
1065 err = prom_getproperty(prom_node, "bus-range", 1080
1066 (char *)&busrange[0], 1081 busrange = prop->value;
1067 sizeof(busrange));
1068 if (err == 0 || err == -1) {
1069 prom_printf("%s: Fatal error, no bus-range.\n", pbm->name);
1070 prom_halt();
1071 }
1072 1082
1073 pbm->pci_first_busno = busrange[0]; 1083 pbm->pci_first_busno = busrange[0];
1074 pbm->pci_last_busno = busrange[1]; 1084 pbm->pci_last_busno = busrange[1];
1075 1085
1076} 1086}
1077 1087
1078static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 devhandle) 1088static void pci_sun4v_pbm_init(struct pci_controller_info *p, struct device_node *dp, u32 devhandle)
1079{ 1089{
1080 struct pci_pbm_info *pbm; 1090 struct pci_pbm_info *pbm;
1081 int err, i; 1091 struct property *prop;
1092 int len, i;
1082 1093
1083 if (devhandle & 0x40) 1094 if (devhandle & 0x40)
1084 pbm = &p->pbm_B; 1095 pbm = &p->pbm_B;
@@ -1086,32 +1097,19 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
1086 pbm = &p->pbm_A; 1097 pbm = &p->pbm_A;
1087 1098
1088 pbm->parent = p; 1099 pbm->parent = p;
1089 pbm->prom_node = prom_node; 1100 pbm->prom_node = dp;
1090 pbm->pci_first_slot = 1; 1101 pbm->pci_first_slot = 1;
1091 1102
1092 pbm->devhandle = devhandle; 1103 pbm->devhandle = devhandle;
1093 1104
1094 sprintf(pbm->name, "SUN4V-PCI%d PBM%c", 1105 pbm->name = dp->full_name;
1095 p->index, (pbm == &p->pbm_A ? 'A' : 'B'));
1096 1106
1097 printk("%s: devhandle[%x] prom_node[%x:%x]\n", 1107 printk("%s: SUN4V PCI Bus Module\n", pbm->name);
1098 pbm->name, pbm->devhandle,
1099 pbm->prom_node, prom_getchild(pbm->prom_node));
1100
1101 prom_getstring(prom_node, "name",
1102 pbm->prom_name, sizeof(pbm->prom_name));
1103
1104 err = prom_getproperty(prom_node, "ranges",
1105 (char *) pbm->pbm_ranges,
1106 sizeof(pbm->pbm_ranges));
1107 if (err == 0 || err == -1) {
1108 prom_printf("%s: Fatal error, no ranges property.\n",
1109 pbm->name);
1110 prom_halt();
1111 }
1112 1108
1109 prop = of_find_property(dp, "ranges", &len);
1110 pbm->pbm_ranges = prop->value;
1113 pbm->num_pbm_ranges = 1111 pbm->num_pbm_ranges =
1114 (err / sizeof(struct linux_prom_pci_ranges)); 1112 (len / sizeof(struct linux_prom_pci_ranges));
1115 1113
1116 /* Mask out the top 8 bits of the ranges, leaving the real 1114 /* Mask out the top 8 bits of the ranges, leaving the real
1117 * physical address. 1115 * physical address.
@@ -1122,24 +1120,13 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
1122 pci_sun4v_determine_mem_io_space(pbm); 1120 pci_sun4v_determine_mem_io_space(pbm);
1123 pbm_register_toplevel_resources(p, pbm); 1121 pbm_register_toplevel_resources(p, pbm);
1124 1122
1125 err = prom_getproperty(prom_node, "interrupt-map", 1123 prop = of_find_property(dp, "interrupt-map", &len);
1126 (char *)pbm->pbm_intmap, 1124 pbm->pbm_intmap = prop->value;
1127 sizeof(pbm->pbm_intmap)); 1125 pbm->num_pbm_intmap =
1128 if (err == 0 || err == -1) { 1126 (len / sizeof(struct linux_prom_pci_intmap));
1129 prom_printf("%s: Fatal error, no interrupt-map property.\n",
1130 pbm->name);
1131 prom_halt();
1132 }
1133 1127
1134 pbm->num_pbm_intmap = (err / sizeof(struct linux_prom_pci_intmap)); 1128 prop = of_find_property(dp, "interrupt-map-mask", NULL);
1135 err = prom_getproperty(prom_node, "interrupt-map-mask", 1129 pbm->pbm_intmask = prop->value;
1136 (char *)&pbm->pbm_intmask,
1137 sizeof(pbm->pbm_intmask));
1138 if (err == 0 || err == -1) {
1139 prom_printf("%s: Fatal error, no interrupt-map-mask.\n",
1140 pbm->name);
1141 prom_halt();
1142 }
1143 1130
1144 pci_sun4v_get_bus_range(pbm); 1131 pci_sun4v_get_bus_range(pbm);
1145 pci_sun4v_iommu_init(pbm); 1132 pci_sun4v_iommu_init(pbm);
@@ -1147,16 +1134,19 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32
1147 pdev_htab_populate(pbm); 1134 pdev_htab_populate(pbm);
1148} 1135}
1149 1136
1150void sun4v_pci_init(int node, char *model_name) 1137void sun4v_pci_init(struct device_node *dp, char *model_name)
1151{ 1138{
1152 struct pci_controller_info *p; 1139 struct pci_controller_info *p;
1153 struct pci_iommu *iommu; 1140 struct pci_iommu *iommu;
1154 struct linux_prom64_registers regs; 1141 struct property *prop;
1142 struct linux_prom64_registers *regs;
1155 u32 devhandle; 1143 u32 devhandle;
1156 int i; 1144 int i;
1157 1145
1158 prom_getproperty(node, "reg", (char *)&regs, sizeof(regs)); 1146 prop = of_find_property(dp, "reg", NULL);
1159 devhandle = (regs.phys_addr >> 32UL) & 0x0fffffff; 1147 regs = prop->value;
1148
1149 devhandle = (regs->phys_addr >> 32UL) & 0x0fffffff;
1160 1150
1161 for (p = pci_controller_root; p; p = p->next) { 1151 for (p = pci_controller_root; p; p = p->next) {
1162 struct pci_pbm_info *pbm; 1152 struct pci_pbm_info *pbm;
@@ -1169,7 +1159,7 @@ void sun4v_pci_init(int node, char *model_name)
1169 &p->pbm_B); 1159 &p->pbm_B);
1170 1160
1171 if (pbm->devhandle == (devhandle ^ 0x40)) { 1161 if (pbm->devhandle == (devhandle ^ 0x40)) {
1172 pci_sun4v_pbm_init(p, node, devhandle); 1162 pci_sun4v_pbm_init(p, dp, devhandle);
1173 return; 1163 return;
1174 } 1164 }
1175 } 1165 }
@@ -1220,7 +1210,7 @@ void sun4v_pci_init(int node, char *model_name)
1220 */ 1210 */
1221 pci_memspace_mask = 0x7fffffffUL; 1211 pci_memspace_mask = 0x7fffffffUL;
1222 1212
1223 pci_sun4v_pbm_init(p, node, devhandle); 1213 pci_sun4v_pbm_init(p, dp, devhandle);
1224 return; 1214 return;
1225 1215
1226fatal_memory_error: 1216fatal_memory_error:
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c
index 30bcaf58e3ab..9496c7734014 100644
--- a/arch/sparc64/kernel/power.c
+++ b/arch/sparc64/kernel/power.c
@@ -105,76 +105,25 @@ again:
105 return 0; 105 return 0;
106} 106}
107 107
108static int __init has_button_interrupt(unsigned int irq, int prom_node) 108static int __init has_button_interrupt(unsigned int irq, struct device_node *dp)
109{ 109{
110 if (irq == PCI_IRQ_NONE) 110 if (irq == PCI_IRQ_NONE)
111 return 0; 111 return 0;
112 if (!prom_node_has_property(prom_node, "button")) 112 if (!of_find_property(dp, "button", NULL))
113 return 0; 113 return 0;
114 114
115 return 1; 115 return 1;
116} 116}
117 117
118static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p) 118static void __devinit power_probe_common(struct of_device *dev, struct resource *res, unsigned int irq)
119{ 119{
120 struct linux_ebus *ebus;
121 struct linux_ebus_device *edev;
122
123 for_each_ebus(ebus) {
124 for_each_ebusdev(edev, ebus) {
125 if (!strcmp(edev->prom_name, "power")) {
126 *resp = &edev->resource[0];
127 *irq_p = edev->irqs[0];
128 *prom_node_p = edev->prom_node;
129 return 0;
130 }
131 }
132 }
133 return -ENODEV;
134}
135
136static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p)
137{
138 struct sparc_isa_bridge *isa_bus;
139 struct sparc_isa_device *isa_dev;
140
141 for_each_isa(isa_bus) {
142 for_each_isadev(isa_dev, isa_bus) {
143 if (!strcmp(isa_dev->prom_name, "power")) {
144 *resp = &isa_dev->resource;
145 *irq_p = isa_dev->irq;
146 *prom_node_p = isa_dev->prom_node;
147 return 0;
148 }
149 }
150 }
151 return -ENODEV;
152}
153
154void __init power_init(void)
155{
156 struct resource *res = NULL;
157 unsigned int irq;
158 int prom_node;
159 static int invoked;
160
161 if (invoked)
162 return;
163 invoked = 1;
164
165 if (!power_probe_ebus(&res, &irq, &prom_node))
166 goto found;
167
168 if (!power_probe_isa(&res, &irq, &prom_node))
169 goto found;
170
171 return;
172
173found:
174 power_reg = ioremap(res->start, 0x4); 120 power_reg = ioremap(res->start, 0x4);
121
175 printk("power: Control reg at %p ... ", power_reg); 122 printk("power: Control reg at %p ... ", power_reg);
123
176 poweroff_method = machine_halt; /* able to use the standard halt */ 124 poweroff_method = machine_halt; /* able to use the standard halt */
177 if (has_button_interrupt(irq, prom_node)) { 125
126 if (has_button_interrupt(irq, dev->node)) {
178 if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { 127 if (kernel_thread(powerd, NULL, CLONE_FS) < 0) {
179 printk("Failed to start power daemon.\n"); 128 printk("Failed to start power daemon.\n");
180 return; 129 return;
@@ -188,4 +137,52 @@ found:
188 printk("not using powerd.\n"); 137 printk("not using powerd.\n");
189 } 138 }
190} 139}
140
141static struct of_device_id power_match[] = {
142 {
143 .name = "power",
144 },
145 {},
146};
147
148static int __devinit ebus_power_probe(struct of_device *dev, const struct of_device_id *match)
149{
150 struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
151 struct resource *res = &edev->resource[0];
152 unsigned int irq = edev->irqs[0];
153
154 power_probe_common(dev, res,irq);
155
156 return 0;
157}
158
159static struct of_platform_driver ebus_power_driver = {
160 .name = "power",
161 .match_table = power_match,
162 .probe = ebus_power_probe,
163};
164
165static int __devinit isa_power_probe(struct of_device *dev, const struct of_device_id *match)
166{
167 struct sparc_isa_device *idev = to_isa_device(&dev->dev);
168 struct resource *res = &idev->resource;
169 unsigned int irq = idev->irq;
170
171 power_probe_common(dev, res,irq);
172
173 return 0;
174}
175
176static struct of_platform_driver isa_power_driver = {
177 .name = "power",
178 .match_table = power_match,
179 .probe = isa_power_probe,
180};
181
182void __init power_init(void)
183{
184 of_register_driver(&ebus_power_driver, &ebus_bus_type);
185 of_register_driver(&isa_power_driver, &isa_bus_type);
186 return;
187}
191#endif /* CONFIG_PCI */ 188#endif /* CONFIG_PCI */
diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c
new file mode 100644
index 000000000000..e9d703eea806
--- /dev/null
+++ b/arch/sparc64/kernel/prom.c
@@ -0,0 +1,650 @@
1/*
2 * Procedures for creating, accessing and interpreting the device tree.
3 *
4 * Paul Mackerras August 1996.
5 * Copyright (C) 1996-2005 Paul Mackerras.
6 *
7 * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner.
8 * {engebret|bergner}@us.ibm.com
9 *
10 * Adapted for sparc64 by David S. Miller davem@davemloft.net
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version
15 * 2 of the License, or (at your option) any later version.
16 */
17
18#include <linux/kernel.h>
19#include <linux/types.h>
20#include <linux/string.h>
21#include <linux/mm.h>
22#include <linux/bootmem.h>
23#include <linux/module.h>
24
25#include <asm/prom.h>
26#include <asm/oplib.h>
27
28static struct device_node *allnodes;
29
30int of_device_is_compatible(struct device_node *device, const char *compat)
31{
32 const char* cp;
33 int cplen, l;
34
35 cp = (char *) of_get_property(device, "compatible", &cplen);
36 if (cp == NULL)
37 return 0;
38 while (cplen > 0) {
39 if (strncmp(cp, compat, strlen(compat)) == 0)
40 return 1;
41 l = strlen(cp) + 1;
42 cp += l;
43 cplen -= l;
44 }
45
46 return 0;
47}
48EXPORT_SYMBOL(of_device_is_compatible);
49
50struct device_node *of_get_parent(const struct device_node *node)
51{
52 struct device_node *np;
53
54 if (!node)
55 return NULL;
56
57 np = node->parent;
58
59 return np;
60}
61EXPORT_SYMBOL(of_get_parent);
62
63struct device_node *of_get_next_child(const struct device_node *node,
64 struct device_node *prev)
65{
66 struct device_node *next;
67
68 next = prev ? prev->sibling : node->child;
69 for (; next != 0; next = next->sibling) {
70 break;
71 }
72
73 return next;
74}
75EXPORT_SYMBOL(of_get_next_child);
76
77struct device_node *of_find_node_by_path(const char *path)
78{
79 struct device_node *np = allnodes;
80
81 for (; np != 0; np = np->allnext) {
82 if (np->full_name != 0 && strcmp(np->full_name, path) == 0)
83 break;
84 }
85
86 return np;
87}
88EXPORT_SYMBOL(of_find_node_by_path);
89
90struct device_node *of_find_node_by_phandle(phandle handle)
91{
92 struct device_node *np;
93
94 for (np = allnodes; np != 0; np = np->allnext)
95 if (np->node == handle)
96 break;
97
98 return np;
99}
100EXPORT_SYMBOL(of_find_node_by_phandle);
101
102struct device_node *of_find_node_by_name(struct device_node *from,
103 const char *name)
104{
105 struct device_node *np;
106
107 np = from ? from->allnext : allnodes;
108 for (; np != NULL; np = np->allnext)
109 if (np->name != NULL && strcmp(np->name, name) == 0)
110 break;
111
112 return np;
113}
114EXPORT_SYMBOL(of_find_node_by_name);
115
116struct device_node *of_find_node_by_type(struct device_node *from,
117 const char *type)
118{
119 struct device_node *np;
120
121 np = from ? from->allnext : allnodes;
122 for (; np != 0; np = np->allnext)
123 if (np->type != 0 && strcmp(np->type, type) == 0)
124 break;
125
126 return np;
127}
128EXPORT_SYMBOL(of_find_node_by_type);
129
130struct device_node *of_find_compatible_node(struct device_node *from,
131 const char *type, const char *compatible)
132{
133 struct device_node *np;
134
135 np = from ? from->allnext : allnodes;
136 for (; np != 0; np = np->allnext) {
137 if (type != NULL
138 && !(np->type != 0 && strcmp(np->type, type) == 0))
139 continue;
140 if (of_device_is_compatible(np, compatible))
141 break;
142 }
143
144 return np;
145}
146EXPORT_SYMBOL(of_find_compatible_node);
147
148struct property *of_find_property(struct device_node *np, const char *name,
149 int *lenp)
150{
151 struct property *pp;
152
153 for (pp = np->properties; pp != 0; pp = pp->next) {
154 if (strcmp(pp->name, name) == 0) {
155 if (lenp != 0)
156 *lenp = pp->length;
157 break;
158 }
159 }
160 return pp;
161}
162EXPORT_SYMBOL(of_find_property);
163
164/*
165 * Find a property with a given name for a given node
166 * and return the value.
167 */
168void *of_get_property(struct device_node *np, const char *name, int *lenp)
169{
170 struct property *pp = of_find_property(np,name,lenp);
171 return pp ? pp->value : NULL;
172}
173EXPORT_SYMBOL(of_get_property);
174
175int of_getintprop_default(struct device_node *np, const char *name, int def)
176{
177 struct property *prop;
178 int len;
179
180 prop = of_find_property(np, name, &len);
181 if (!prop || len != 4)
182 return def;
183
184 return *(int *) prop->value;
185}
186EXPORT_SYMBOL(of_getintprop_default);
187
188static unsigned int prom_early_allocated;
189
190static void * __init prom_early_alloc(unsigned long size)
191{
192 void *ret;
193
194 ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
195 if (ret != NULL)
196 memset(ret, 0, size);
197
198 prom_early_allocated += size;
199
200 return ret;
201}
202
203static int is_root_node(const struct device_node *dp)
204{
205 if (!dp)
206 return 0;
207
208 return (dp->parent == NULL);
209}
210
211/* The following routines deal with the black magic of fully naming a
212 * node.
213 *
214 * Certain well known named nodes are just the simple name string.
215 *
216 * Actual devices have an address specifier appended to the base name
217 * string, like this "foo@addr". The "addr" can be in any number of
218 * formats, and the platform plus the type of the node determine the
219 * format and how it is constructed.
220 *
221 * For children of the ROOT node, the naming convention is fixed and
222 * determined by whether this is a sun4u or sun4v system.
223 *
224 * For children of other nodes, it is bus type specific. So
225 * we walk up the tree until we discover a "device_type" property
226 * we recognize and we go from there.
227 *
228 * As an example, the boot device on my workstation has a full path:
229 *
230 * /pci@1e,600000/ide@d/disk@0,0:c
231 */
232static void __init sun4v_path_component(struct device_node *dp, char *tmp_buf)
233{
234 struct linux_prom64_registers *regs;
235 struct property *rprop;
236 u32 high_bits, low_bits, type;
237
238 rprop = of_find_property(dp, "reg", NULL);
239 if (!rprop)
240 return;
241
242 regs = rprop->value;
243 if (!is_root_node(dp->parent)) {
244 sprintf(tmp_buf, "%s@%x,%x",
245 dp->name,
246 (unsigned int) (regs->phys_addr >> 32UL),
247 (unsigned int) (regs->phys_addr & 0xffffffffUL));
248 return;
249 }
250
251 type = regs->phys_addr >> 60UL;
252 high_bits = (regs->phys_addr >> 32UL) & 0x0fffffffUL;
253 low_bits = (regs->phys_addr & 0xffffffffUL);
254
255 if (type == 0 || type == 8) {
256 const char *prefix = (type == 0) ? "m" : "i";
257
258 if (low_bits)
259 sprintf(tmp_buf, "%s@%s%x,%x",
260 dp->name, prefix,
261 high_bits, low_bits);
262 else
263 sprintf(tmp_buf, "%s@%s%x",
264 dp->name,
265 prefix,
266 high_bits);
267 } else if (type == 12) {
268 sprintf(tmp_buf, "%s@%x",
269 dp->name, high_bits);
270 }
271}
272
273static void __init sun4u_path_component(struct device_node *dp, char *tmp_buf)
274{
275 struct linux_prom64_registers *regs;
276 struct property *prop;
277
278 prop = of_find_property(dp, "reg", NULL);
279 if (!prop)
280 return;
281
282 regs = prop->value;
283 if (!is_root_node(dp->parent)) {
284 sprintf(tmp_buf, "%s@%x,%x",
285 dp->name,
286 (unsigned int) (regs->phys_addr >> 32UL),
287 (unsigned int) (regs->phys_addr & 0xffffffffUL));
288 return;
289 }
290
291 prop = of_find_property(dp, "upa-portid", NULL);
292 if (!prop)
293 prop = of_find_property(dp, "portid", NULL);
294 if (prop) {
295 unsigned long mask = 0xffffffffUL;
296
297 if (tlb_type >= cheetah)
298 mask = 0x7fffff;
299
300 sprintf(tmp_buf, "%s@%x,%x",
301 dp->name,
302 *(u32 *)prop->value,
303 (unsigned int) (regs->phys_addr & mask));
304 }
305}
306
307/* "name@slot,offset" */
308static void __init sbus_path_component(struct device_node *dp, char *tmp_buf)
309{
310 struct linux_prom_registers *regs;
311 struct property *prop;
312
313 prop = of_find_property(dp, "reg", NULL);
314 if (!prop)
315 return;
316
317 regs = prop->value;
318 sprintf(tmp_buf, "%s@%x,%x",
319 dp->name,
320 regs->which_io,
321 regs->phys_addr);
322}
323
324/* "name@devnum[,func]" */
325static void __init pci_path_component(struct device_node *dp, char *tmp_buf)
326{
327 struct linux_prom_pci_registers *regs;
328 struct property *prop;
329 unsigned int devfn;
330
331 prop = of_find_property(dp, "reg", NULL);
332 if (!prop)
333 return;
334
335 regs = prop->value;
336 devfn = (regs->phys_hi >> 8) & 0xff;
337 if (devfn & 0x07) {
338 sprintf(tmp_buf, "%s@%x,%x",
339 dp->name,
340 devfn >> 3,
341 devfn & 0x07);
342 } else {
343 sprintf(tmp_buf, "%s@%x",
344 dp->name,
345 devfn >> 3);
346 }
347}
348
349/* "name@UPA_PORTID,offset" */
350static void __init upa_path_component(struct device_node *dp, char *tmp_buf)
351{
352 struct linux_prom64_registers *regs;
353 struct property *prop;
354
355 prop = of_find_property(dp, "reg", NULL);
356 if (!prop)
357 return;
358
359 regs = prop->value;
360
361 prop = of_find_property(dp, "upa-portid", NULL);
362 if (!prop)
363 return;
364
365 sprintf(tmp_buf, "%s@%x,%x",
366 dp->name,
367 *(u32 *) prop->value,
368 (unsigned int) (regs->phys_addr & 0xffffffffUL));
369}
370
371/* "name@reg" */
372static void __init vdev_path_component(struct device_node *dp, char *tmp_buf)
373{
374 struct property *prop;
375 u32 *regs;
376
377 prop = of_find_property(dp, "reg", NULL);
378 if (!prop)
379 return;
380
381 regs = prop->value;
382
383 sprintf(tmp_buf, "%s@%x", dp->name, *regs);
384}
385
386/* "name@addrhi,addrlo" */
387static void __init ebus_path_component(struct device_node *dp, char *tmp_buf)
388{
389 struct linux_prom64_registers *regs;
390 struct property *prop;
391
392 prop = of_find_property(dp, "reg", NULL);
393 if (!prop)
394 return;
395
396 regs = prop->value;
397
398 sprintf(tmp_buf, "%s@%x,%x",
399 dp->name,
400 (unsigned int) (regs->phys_addr >> 32UL),
401 (unsigned int) (regs->phys_addr & 0xffffffffUL));
402}
403
404/* "name@bus,addr" */
405static void __init i2c_path_component(struct device_node *dp, char *tmp_buf)
406{
407 struct property *prop;
408 u32 *regs;
409
410 prop = of_find_property(dp, "reg", NULL);
411 if (!prop)
412 return;
413
414 regs = prop->value;
415
416 /* This actually isn't right... should look at the #address-cells
417 * property of the i2c bus node etc. etc.
418 */
419 sprintf(tmp_buf, "%s@%x,%x",
420 dp->name, regs[0], regs[1]);
421}
422
423/* "name@reg0[,reg1]" */
424static void __init usb_path_component(struct device_node *dp, char *tmp_buf)
425{
426 struct property *prop;
427 u32 *regs;
428
429 prop = of_find_property(dp, "reg", NULL);
430 if (!prop)
431 return;
432
433 regs = prop->value;
434
435 if (prop->length == sizeof(u32) || regs[1] == 1) {
436 sprintf(tmp_buf, "%s@%x",
437 dp->name, regs[0]);
438 } else {
439 sprintf(tmp_buf, "%s@%x,%x",
440 dp->name, regs[0], regs[1]);
441 }
442}
443
444/* "name@reg0reg1[,reg2reg3]" */
445static void __init ieee1394_path_component(struct device_node *dp, char *tmp_buf)
446{
447 struct property *prop;
448 u32 *regs;
449
450 prop = of_find_property(dp, "reg", NULL);
451 if (!prop)
452 return;
453
454 regs = prop->value;
455
456 if (regs[2] || regs[3]) {
457 sprintf(tmp_buf, "%s@%08x%08x,%04x%08x",
458 dp->name, regs[0], regs[1], regs[2], regs[3]);
459 } else {
460 sprintf(tmp_buf, "%s@%08x%08x",
461 dp->name, regs[0], regs[1]);
462 }
463}
464
465static void __init __build_path_component(struct device_node *dp, char *tmp_buf)
466{
467 struct device_node *parent = dp->parent;
468
469 if (parent != NULL) {
470 if (!strcmp(parent->type, "pci") ||
471 !strcmp(parent->type, "pciex"))
472 return pci_path_component(dp, tmp_buf);
473 if (!strcmp(parent->type, "sbus"))
474 return sbus_path_component(dp, tmp_buf);
475 if (!strcmp(parent->type, "upa"))
476 return upa_path_component(dp, tmp_buf);
477 if (!strcmp(parent->type, "ebus"))
478 return ebus_path_component(dp, tmp_buf);
479 if (!strcmp(parent->name, "usb") ||
480 !strcmp(parent->name, "hub"))
481 return usb_path_component(dp, tmp_buf);
482 if (!strcmp(parent->type, "i2c"))
483 return i2c_path_component(dp, tmp_buf);
484 if (!strcmp(parent->type, "firewire"))
485 return ieee1394_path_component(dp, tmp_buf);
486 if (!strcmp(parent->type, "virtual-devices"))
487 return vdev_path_component(dp, tmp_buf);
488
489 /* "isa" is handled with platform naming */
490 }
491
492 /* Use platform naming convention. */
493 if (tlb_type == hypervisor)
494 return sun4v_path_component(dp, tmp_buf);
495 else
496 return sun4u_path_component(dp, tmp_buf);
497}
498
499static char * __init build_path_component(struct device_node *dp)
500{
501 char tmp_buf[64], *n;
502
503 tmp_buf[0] = '\0';
504 __build_path_component(dp, tmp_buf);
505 if (tmp_buf[0] == '\0')
506 strcpy(tmp_buf, dp->name);
507
508 n = prom_early_alloc(strlen(tmp_buf) + 1);
509 strcpy(n, tmp_buf);
510
511 return n;
512}
513
514static char * __init build_full_name(struct device_node *dp)
515{
516 int len, ourlen, plen;
517 char *n;
518
519 plen = strlen(dp->parent->full_name);
520 ourlen = strlen(dp->path_component_name);
521 len = ourlen + plen + 2;
522
523 n = prom_early_alloc(len);
524 strcpy(n, dp->parent->full_name);
525 if (!is_root_node(dp->parent)) {
526 strcpy(n + plen, "/");
527 plen++;
528 }
529 strcpy(n + plen, dp->path_component_name);
530
531 return n;
532}
533
534static struct property * __init build_one_prop(phandle node, char *prev)
535{
536 static struct property *tmp = NULL;
537 struct property *p;
538
539 if (tmp) {
540 p = tmp;
541 memset(p, 0, sizeof(*p) + 32);
542 tmp = NULL;
543 } else
544 p = prom_early_alloc(sizeof(struct property) + 32);
545
546 p->name = (char *) (p + 1);
547 if (prev == NULL) {
548 prom_firstprop(node, p->name);
549 } else {
550 prom_nextprop(node, prev, p->name);
551 }
552 if (strlen(p->name) == 0) {
553 tmp = p;
554 return NULL;
555 }
556 p->length = prom_getproplen(node, p->name);
557 if (p->length <= 0) {
558 p->length = 0;
559 } else {
560 p->value = prom_early_alloc(p->length);
561 prom_getproperty(node, p->name, p->value, p->length);
562 }
563 return p;
564}
565
566static struct property * __init build_prop_list(phandle node)
567{
568 struct property *head, *tail;
569
570 head = tail = build_one_prop(node, NULL);
571 while(tail) {
572 tail->next = build_one_prop(node, tail->name);
573 tail = tail->next;
574 }
575
576 return head;
577}
578
579static char * __init get_one_property(phandle node, const char *name)
580{
581 char *buf = "<NULL>";
582 int len;
583
584 len = prom_getproplen(node, name);
585 if (len > 0) {
586 buf = prom_early_alloc(len);
587 prom_getproperty(node, name, buf, len);
588 }
589
590 return buf;
591}
592
593static struct device_node * __init create_node(phandle node)
594{
595 struct device_node *dp;
596
597 if (!node)
598 return NULL;
599
600 dp = prom_early_alloc(sizeof(*dp));
601
602 kref_init(&dp->kref);
603
604 dp->name = get_one_property(node, "name");
605 dp->type = get_one_property(node, "device_type");
606 dp->node = node;
607
608 /* Build interrupts later... */
609
610 dp->properties = build_prop_list(node);
611
612 return dp;
613}
614
615static struct device_node * __init build_tree(struct device_node *parent, phandle node, struct device_node ***nextp)
616{
617 struct device_node *dp;
618
619 dp = create_node(node);
620 if (dp) {
621 *(*nextp) = dp;
622 *nextp = &dp->allnext;
623
624 dp->parent = parent;
625 dp->path_component_name = build_path_component(dp);
626 dp->full_name = build_full_name(dp);
627
628 dp->child = build_tree(dp, prom_getchild(node), nextp);
629
630 dp->sibling = build_tree(parent, prom_getsibling(node), nextp);
631 }
632
633 return dp;
634}
635
636void __init prom_build_devicetree(void)
637{
638 struct device_node **nextp;
639
640 allnodes = create_node(prom_root_node);
641 allnodes->path_component_name = "";
642 allnodes->full_name = "/";
643
644 nextp = &allnodes->allnext;
645 allnodes->child = build_tree(allnodes,
646 prom_getchild(allnodes->node),
647 &nextp);
648 printk("PROM: Built device tree with %u bytes of memory.\n",
649 prom_early_allocated);
650}
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 8812417247d4..ac05e0f692ef 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -19,6 +19,7 @@
19#include <asm/cache.h> 19#include <asm/cache.h>
20#include <asm/dma.h> 20#include <asm/dma.h>
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/prom.h>
22#include <asm/starfire.h> 23#include <asm/starfire.h>
23 24
24#include "iommu_common.h" 25#include "iommu_common.h"
@@ -1098,24 +1099,25 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus)
1098} 1099}
1099 1100
1100/* Boot time initialization. */ 1101/* Boot time initialization. */
1101void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus) 1102static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus)
1102{ 1103{
1103 struct linux_prom64_registers rprop; 1104 struct linux_prom64_registers *pr;
1105 struct device_node *dp;
1104 struct sbus_iommu *iommu; 1106 struct sbus_iommu *iommu;
1105 unsigned long regs, tsb_base; 1107 unsigned long regs, tsb_base;
1106 u64 control; 1108 u64 control;
1107 int err, i; 1109 int i;
1110
1111 dp = of_find_node_by_phandle(__node);
1108 1112
1109 sbus->portid = prom_getintdefault(sbus->prom_node, 1113 sbus->portid = of_getintprop_default(dp, "upa-portid", -1);
1110 "upa-portid", -1);
1111 1114
1112 err = prom_getproperty(prom_node, "reg", 1115 pr = of_get_property(dp, "reg", NULL);
1113 (char *)&rprop, sizeof(rprop)); 1116 if (!pr) {
1114 if (err < 0) {
1115 prom_printf("sbus_iommu_init: Cannot map SYSIO control registers.\n"); 1117 prom_printf("sbus_iommu_init: Cannot map SYSIO control registers.\n");
1116 prom_halt(); 1118 prom_halt();
1117 } 1119 }
1118 regs = rprop.phys_addr; 1120 regs = pr->phys_addr;
1119 1121
1120 iommu = kmalloc(sizeof(*iommu) + SMP_CACHE_BYTES, GFP_ATOMIC); 1122 iommu = kmalloc(sizeof(*iommu) + SMP_CACHE_BYTES, GFP_ATOMIC);
1121 if (iommu == NULL) { 1123 if (iommu == NULL) {
@@ -1225,3 +1227,50 @@ void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus)
1225 1227
1226 sysio_register_error_handlers(sbus); 1228 sysio_register_error_handlers(sbus);
1227} 1229}
1230
1231void sbus_fill_device_irq(struct sbus_dev *sdev)
1232{
1233 struct device_node *dp = of_find_node_by_phandle(sdev->prom_node);
1234 struct linux_prom_irqs *irqs;
1235
1236 irqs = of_get_property(dp, "interrupts", NULL);
1237 if (!irqs) {
1238 sdev->irqs[0] = 0;
1239 sdev->num_irqs = 0;
1240 } else {
1241 unsigned int pri = irqs[0].pri;
1242
1243 sdev->num_irqs = 1;
1244 if (pri < 0x20)
1245 pri += sdev->slot * 8;
1246
1247 sdev->irqs[0] = sbus_build_irq(sdev->bus, pri);
1248 }
1249}
1250
1251void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus)
1252{
1253}
1254
1255void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
1256{
1257 sbus_iommu_init(dp->node, sbus);
1258}
1259
1260void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp)
1261{
1262}
1263
1264int __init sbus_arch_preinit(void)
1265{
1266 return 0;
1267}
1268
1269void __init sbus_arch_postinit(void)
1270{
1271 extern void firetruck_init(void);
1272 extern void clock_probe(void);
1273
1274 firetruck_init();
1275 clock_probe();
1276}
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 9cf1c88cd774..a6a7d8168346 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -376,12 +376,12 @@ void __init setup_arch(char **cmdline_p)
376 } 376 }
377#endif 377#endif
378 378
379 smp_setup_cpu_possible_map();
380
381 /* Get boot processor trap_block[] setup. */ 379 /* Get boot processor trap_block[] setup. */
382 init_cur_cpu_trap(current_thread_info()); 380 init_cur_cpu_trap(current_thread_info());
383 381
384 paging_init(); 382 paging_init();
383
384 smp_setup_cpu_possible_map();
385} 385}
386 386
387static int __init set_preferred_console(void) 387static int __init set_preferred_console(void)
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index f03d52d0b88d..f62bf3a2de1a 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -39,6 +39,7 @@
39#include <asm/starfire.h> 39#include <asm/starfire.h>
40#include <asm/tlb.h> 40#include <asm/tlb.h>
41#include <asm/sections.h> 41#include <asm/sections.h>
42#include <asm/prom.h>
42 43
43extern void calibrate_delay(void); 44extern void calibrate_delay(void);
44 45
@@ -76,41 +77,42 @@ void smp_bogo(struct seq_file *m)
76 77
77void __init smp_store_cpu_info(int id) 78void __init smp_store_cpu_info(int id)
78{ 79{
79 int cpu_node, def; 80 struct device_node *dp;
81 int def;
80 82
81 /* multiplier and counter set by 83 /* multiplier and counter set by
82 smp_setup_percpu_timer() */ 84 smp_setup_percpu_timer() */
83 cpu_data(id).udelay_val = loops_per_jiffy; 85 cpu_data(id).udelay_val = loops_per_jiffy;
84 86
85 cpu_find_by_mid(id, &cpu_node); 87 cpu_find_by_mid(id, &dp);
86 cpu_data(id).clock_tick = prom_getintdefault(cpu_node, 88 cpu_data(id).clock_tick =
87 "clock-frequency", 0); 89 of_getintprop_default(dp, "clock-frequency", 0);
88 90
89 def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024)); 91 def = ((tlb_type == hypervisor) ? (8 * 1024) : (16 * 1024));
90 cpu_data(id).dcache_size = prom_getintdefault(cpu_node, "dcache-size", 92 cpu_data(id).dcache_size =
91 def); 93 of_getintprop_default(dp, "dcache-size", def);
92 94
93 def = 32; 95 def = 32;
94 cpu_data(id).dcache_line_size = 96 cpu_data(id).dcache_line_size =
95 prom_getintdefault(cpu_node, "dcache-line-size", def); 97 of_getintprop_default(dp, "dcache-line-size", def);
96 98
97 def = 16 * 1024; 99 def = 16 * 1024;
98 cpu_data(id).icache_size = prom_getintdefault(cpu_node, "icache-size", 100 cpu_data(id).icache_size =
99 def); 101 of_getintprop_default(dp, "icache-size", def);
100 102
101 def = 32; 103 def = 32;
102 cpu_data(id).icache_line_size = 104 cpu_data(id).icache_line_size =
103 prom_getintdefault(cpu_node, "icache-line-size", def); 105 of_getintprop_default(dp, "icache-line-size", def);
104 106
105 def = ((tlb_type == hypervisor) ? 107 def = ((tlb_type == hypervisor) ?
106 (3 * 1024 * 1024) : 108 (3 * 1024 * 1024) :
107 (4 * 1024 * 1024)); 109 (4 * 1024 * 1024));
108 cpu_data(id).ecache_size = prom_getintdefault(cpu_node, "ecache-size", 110 cpu_data(id).ecache_size =
109 def); 111 of_getintprop_default(dp, "ecache-size", def);
110 112
111 def = 64; 113 def = 64;
112 cpu_data(id).ecache_line_size = 114 cpu_data(id).ecache_line_size =
113 prom_getintdefault(cpu_node, "ecache-line-size", def); 115 of_getintprop_default(dp, "ecache-line-size", def);
114 116
115 printk("CPU[%d]: Caches " 117 printk("CPU[%d]: Caches "
116 "D[sz(%d):line_sz(%d)] " 118 "D[sz(%d):line_sz(%d)] "
@@ -342,10 +344,10 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu)
342 344
343 prom_startcpu_cpuid(cpu, entry, cookie); 345 prom_startcpu_cpuid(cpu, entry, cookie);
344 } else { 346 } else {
345 int cpu_node; 347 struct device_node *dp;
346 348
347 cpu_find_by_mid(cpu, &cpu_node); 349 cpu_find_by_mid(cpu, &dp);
348 prom_startcpu(cpu_node, entry, cookie); 350 prom_startcpu(dp->node, entry, cookie);
349 } 351 }
350 352
351 for (timeout = 0; timeout < 5000000; timeout++) { 353 for (timeout = 0; timeout < 5000000; timeout++) {
@@ -1289,7 +1291,8 @@ int setup_profiling_timer(unsigned int multiplier)
1289 1291
1290static void __init smp_tune_scheduling(void) 1292static void __init smp_tune_scheduling(void)
1291{ 1293{
1292 int instance, node; 1294 struct device_node *dp;
1295 int instance;
1293 unsigned int def, smallest = ~0U; 1296 unsigned int def, smallest = ~0U;
1294 1297
1295 def = ((tlb_type == hypervisor) ? 1298 def = ((tlb_type == hypervisor) ?
@@ -1297,10 +1300,10 @@ static void __init smp_tune_scheduling(void)
1297 (4 * 1024 * 1024)); 1300 (4 * 1024 * 1024));
1298 1301
1299 instance = 0; 1302 instance = 0;
1300 while (!cpu_find_by_instance(instance, &node, NULL)) { 1303 while (!cpu_find_by_instance(instance, &dp, NULL)) {
1301 unsigned int val; 1304 unsigned int val;
1302 1305
1303 val = prom_getintdefault(node, "ecache-size", def); 1306 val = of_getintprop_default(dp, "ecache-size", def);
1304 if (val < smallest) 1307 if (val < smallest)
1305 smallest = val; 1308 smallest = val;
1306 1309
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index 0f00a99927e9..348b82035561 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -48,6 +48,7 @@
48#include <asm/sections.h> 48#include <asm/sections.h>
49#include <asm/cpudata.h> 49#include <asm/cpudata.h>
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
51#include <asm/prom.h>
51 52
52DEFINE_SPINLOCK(mostek_lock); 53DEFINE_SPINLOCK(mostek_lock);
53DEFINE_SPINLOCK(rtc_lock); 54DEFINE_SPINLOCK(rtc_lock);
@@ -755,24 +756,200 @@ retry:
755 return -EOPNOTSUPP; 756 return -EOPNOTSUPP;
756} 757}
757 758
758void __init clock_probe(void) 759static int __init clock_model_matches(char *model)
759{ 760{
760 struct linux_prom_registers clk_reg[2]; 761 if (strcmp(model, "mk48t02") &&
761 char model[128]; 762 strcmp(model, "mk48t08") &&
762 int node, busnd = -1, err; 763 strcmp(model, "mk48t59") &&
763 unsigned long flags; 764 strcmp(model, "m5819") &&
764 struct linux_central *cbus; 765 strcmp(model, "m5819p") &&
766 strcmp(model, "m5823") &&
767 strcmp(model, "ds1287"))
768 return 0;
769
770 return 1;
771}
772
773static void __init __clock_assign_common(void __iomem *addr, char *model)
774{
775 if (model[5] == '0' && model[6] == '2') {
776 mstk48t02_regs = addr;
777 } else if(model[5] == '0' && model[6] == '8') {
778 mstk48t08_regs = addr;
779 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
780 } else {
781 mstk48t59_regs = addr;
782 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
783 }
784}
785
786static void __init clock_assign_clk_reg(struct linux_prom_registers *clk_reg,
787 char *model)
788{
789 unsigned long addr;
790
791 addr = ((unsigned long) clk_reg[0].phys_addr |
792 (((unsigned long) clk_reg[0].which_io) << 32UL));
793
794 __clock_assign_common((void __iomem *) addr, model);
795}
796
797static int __init clock_probe_central(void)
798{
799 struct linux_prom_registers clk_reg[2], *pr;
800 struct device_node *dp;
801 char *model;
802
803 if (!central_bus)
804 return 0;
805
806 /* Get Central FHC's prom node. */
807 dp = central_bus->child->prom_node;
808
809 /* Then get the first child device below it. */
810 dp = dp->child;
811
812 while (dp) {
813 model = of_get_property(dp, "model", NULL);
814 if (!model || !clock_model_matches(model))
815 goto next_sibling;
816
817 pr = of_get_property(dp, "reg", NULL);
818 memcpy(clk_reg, pr, sizeof(clk_reg));
819
820 apply_fhc_ranges(central_bus->child, clk_reg, 1);
821 apply_central_ranges(central_bus, clk_reg, 1);
822
823 clock_assign_clk_reg(clk_reg, model);
824 return 1;
825
826 next_sibling:
827 dp = dp->sibling;
828 }
829
830 return 0;
831}
832
765#ifdef CONFIG_PCI 833#ifdef CONFIG_PCI
766 struct linux_ebus *ebus = NULL; 834static void __init clock_isa_ebus_assign_regs(struct resource *res, char *model)
767 struct sparc_isa_bridge *isa_br = NULL; 835{
836 if (!strcmp(model, "ds1287") ||
837 !strcmp(model, "m5819") ||
838 !strcmp(model, "m5819p") ||
839 !strcmp(model, "m5823")) {
840 ds1287_regs = res->start;
841 } else {
842 mstk48t59_regs = (void __iomem *) res->start;
843 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
844 }
845}
846
847static int __init clock_probe_one_ebus_dev(struct linux_ebus_device *edev)
848{
849 struct device_node *dp = edev->prom_node;
850 char *model;
851
852 model = of_get_property(dp, "model", NULL);
853 if (!clock_model_matches(model))
854 return 0;
855
856 clock_isa_ebus_assign_regs(&edev->resource[0], model);
857
858 return 1;
859}
860
861static int __init clock_probe_ebus(void)
862{
863 struct linux_ebus *ebus;
864
865 for_each_ebus(ebus) {
866 struct linux_ebus_device *edev;
867
868 for_each_ebusdev(edev, ebus) {
869 if (clock_probe_one_ebus_dev(edev))
870 return 1;
871 }
872 }
873
874 return 0;
875}
876
877static int __init clock_probe_one_isa_dev(struct sparc_isa_device *idev)
878{
879 struct device_node *dp = idev->prom_node;
880 char *model;
881
882 model = of_get_property(dp, "model", NULL);
883 if (!clock_model_matches(model))
884 return 0;
885
886 clock_isa_ebus_assign_regs(&idev->resource, model);
887
888 return 1;
889}
890
891static int __init clock_probe_isa(void)
892{
893 struct sparc_isa_bridge *isa_br;
894
895 for_each_isa(isa_br) {
896 struct sparc_isa_device *isa_dev;
897
898 for_each_isadev(isa_dev, isa_br) {
899 if (clock_probe_one_isa_dev(isa_dev))
900 return 1;
901 }
902 }
903
904 return 0;
905}
906#endif /* CONFIG_PCI */
907
908#ifdef CONFIG_SBUS
909static int __init clock_probe_one_sbus_dev(struct sbus_bus *sbus, struct sbus_dev *sdev)
910{
911 struct resource *res;
912 char model[64];
913 void __iomem *addr;
914
915 prom_getstring(sdev->prom_node, "model", model, sizeof(model));
916 if (!clock_model_matches(model))
917 return 0;
918
919 res = &sdev->resource[0];
920 addr = sbus_ioremap(res, 0, 0x800UL, "eeprom");
921
922 __clock_assign_common(addr, model);
923
924 return 1;
925}
926
927static int __init clock_probe_sbus(void)
928{
929 struct sbus_bus *sbus;
930
931 for_each_sbus(sbus) {
932 struct sbus_dev *sdev;
933
934 for_each_sbusdev(sdev, sbus) {
935 if (clock_probe_one_sbus_dev(sbus, sdev))
936 return 1;
937 }
938 }
939
940 return 0;
941}
768#endif 942#endif
943
944void __init clock_probe(void)
945{
769 static int invoked; 946 static int invoked;
947 unsigned long flags;
770 948
771 if (invoked) 949 if (invoked)
772 return; 950 return;
773 invoked = 1; 951 invoked = 1;
774 952
775
776 if (this_is_starfire) { 953 if (this_is_starfire) {
777 xtime.tv_sec = starfire_get_time(); 954 xtime.tv_sec = starfire_get_time();
778 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); 955 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
@@ -788,183 +965,27 @@ void __init clock_probe(void)
788 return; 965 return;
789 } 966 }
790 967
791 local_irq_save(flags);
792
793 cbus = central_bus;
794 if (cbus != NULL)
795 busnd = central_bus->child->prom_node;
796
797 /* Check FHC Central then EBUSs then ISA bridges then SBUSs. 968 /* Check FHC Central then EBUSs then ISA bridges then SBUSs.
798 * That way we handle the presence of multiple properly. 969 * That way we handle the presence of multiple properly.
799 * 970 *
800 * As a special case, machines with Central must provide the 971 * As a special case, machines with Central must provide the
801 * timer chip there. 972 * timer chip there.
802 */ 973 */
974 if (!clock_probe_central() &&
803#ifdef CONFIG_PCI 975#ifdef CONFIG_PCI
804 if (ebus_chain != NULL) { 976 !clock_probe_ebus() &&
805 ebus = ebus_chain; 977 !clock_probe_isa() &&
806 if (busnd == -1)
807 busnd = ebus->prom_node;
808 }
809 if (isa_chain != NULL) {
810 isa_br = isa_chain;
811 if (busnd == -1)
812 busnd = isa_br->prom_node;
813 }
814#endif
815 if (sbus_root != NULL && busnd == -1)
816 busnd = sbus_root->prom_node;
817
818 if (busnd == -1) {
819 prom_printf("clock_probe: problem, cannot find bus to search.\n");
820 prom_halt();
821 }
822
823 node = prom_getchild(busnd);
824
825 while (1) {
826 if (!node)
827 model[0] = 0;
828 else
829 prom_getstring(node, "model", model, sizeof(model));
830 if (strcmp(model, "mk48t02") &&
831 strcmp(model, "mk48t08") &&
832 strcmp(model, "mk48t59") &&
833 strcmp(model, "m5819") &&
834 strcmp(model, "m5819p") &&
835 strcmp(model, "m5823") &&
836 strcmp(model, "ds1287")) {
837 if (cbus != NULL) {
838 prom_printf("clock_probe: Central bus lacks timer chip.\n");
839 prom_halt();
840 }
841
842 if (node != 0)
843 node = prom_getsibling(node);
844#ifdef CONFIG_PCI
845 while ((node == 0) && ebus != NULL) {
846 ebus = ebus->next;
847 if (ebus != NULL) {
848 busnd = ebus->prom_node;
849 node = prom_getchild(busnd);
850 }
851 }
852 while ((node == 0) && isa_br != NULL) {
853 isa_br = isa_br->next;
854 if (isa_br != NULL) {
855 busnd = isa_br->prom_node;
856 node = prom_getchild(busnd);
857 }
858 }
859#endif 978#endif
860 if (node == 0) { 979#ifdef CONFIG_SBUS
861 prom_printf("clock_probe: Cannot find timer chip\n"); 980 !clock_probe_sbus()
862 prom_halt();
863 }
864 continue;
865 }
866
867 err = prom_getproperty(node, "reg", (char *)clk_reg,
868 sizeof(clk_reg));
869 if(err == -1) {
870 prom_printf("clock_probe: Cannot get Mostek reg property\n");
871 prom_halt();
872 }
873
874 if (cbus != NULL) {
875 apply_fhc_ranges(central_bus->child, clk_reg, 1);
876 apply_central_ranges(central_bus, clk_reg, 1);
877 }
878#ifdef CONFIG_PCI
879 else if (ebus != NULL) {
880 struct linux_ebus_device *edev;
881
882 for_each_ebusdev(edev, ebus)
883 if (edev->prom_node == node)
884 break;
885 if (edev == NULL) {
886 if (isa_chain != NULL)
887 goto try_isa_clock;
888 prom_printf("%s: Mostek not probed by EBUS\n",
889 __FUNCTION__);
890 prom_halt();
891 }
892
893 if (!strcmp(model, "ds1287") ||
894 !strcmp(model, "m5819") ||
895 !strcmp(model, "m5819p") ||
896 !strcmp(model, "m5823")) {
897 ds1287_regs = edev->resource[0].start;
898 } else {
899 mstk48t59_regs = (void __iomem *)
900 edev->resource[0].start;
901 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
902 }
903 break;
904 }
905 else if (isa_br != NULL) {
906 struct sparc_isa_device *isadev;
907
908try_isa_clock:
909 for_each_isadev(isadev, isa_br)
910 if (isadev->prom_node == node)
911 break;
912 if (isadev == NULL) {
913 prom_printf("%s: Mostek not probed by ISA\n");
914 prom_halt();
915 }
916 if (!strcmp(model, "ds1287") ||
917 !strcmp(model, "m5819") ||
918 !strcmp(model, "m5819p") ||
919 !strcmp(model, "m5823")) {
920 ds1287_regs = isadev->resource.start;
921 } else {
922 mstk48t59_regs = (void __iomem *)
923 isadev->resource.start;
924 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
925 }
926 break;
927 }
928#endif 981#endif
929 else { 982 ) {
930 if (sbus_root->num_sbus_ranges) { 983 printk(KERN_WARNING "No clock chip found.\n");
931 int nranges = sbus_root->num_sbus_ranges; 984 return;
932 int rngc;
933
934 for (rngc = 0; rngc < nranges; rngc++)
935 if (clk_reg[0].which_io ==
936 sbus_root->sbus_ranges[rngc].ot_child_space)
937 break;
938 if (rngc == nranges) {
939 prom_printf("clock_probe: Cannot find ranges for "
940 "clock regs.\n");
941 prom_halt();
942 }
943 clk_reg[0].which_io =
944 sbus_root->sbus_ranges[rngc].ot_parent_space;
945 clk_reg[0].phys_addr +=
946 sbus_root->sbus_ranges[rngc].ot_parent_base;
947 }
948 }
949
950 if(model[5] == '0' && model[6] == '2') {
951 mstk48t02_regs = (void __iomem *)
952 (((u64)clk_reg[0].phys_addr) |
953 (((u64)clk_reg[0].which_io)<<32UL));
954 } else if(model[5] == '0' && model[6] == '8') {
955 mstk48t08_regs = (void __iomem *)
956 (((u64)clk_reg[0].phys_addr) |
957 (((u64)clk_reg[0].which_io)<<32UL));
958 mstk48t02_regs = mstk48t08_regs + MOSTEK_48T08_48T02;
959 } else {
960 mstk48t59_regs = (void __iomem *)
961 (((u64)clk_reg[0].phys_addr) |
962 (((u64)clk_reg[0].which_io)<<32UL));
963 mstk48t02_regs = mstk48t59_regs + MOSTEK_48T59_48T02;
964 }
965 break;
966 } 985 }
967 986
987 local_irq_save(flags);
988
968 if (mstk48t02_regs != NULL) { 989 if (mstk48t02_regs != NULL) {
969 /* Report a low battery voltage condition. */ 990 /* Report a low battery voltage condition. */
970 if (has_low_battery()) 991 if (has_low_battery())
@@ -983,12 +1004,14 @@ try_isa_clock:
983/* This is gets the master TICK_INT timer going. */ 1004/* This is gets the master TICK_INT timer going. */
984static unsigned long sparc64_init_timers(void) 1005static unsigned long sparc64_init_timers(void)
985{ 1006{
1007 struct device_node *dp;
1008 struct property *prop;
986 unsigned long clock; 1009 unsigned long clock;
987 int node;
988#ifdef CONFIG_SMP 1010#ifdef CONFIG_SMP
989 extern void smp_tick_init(void); 1011 extern void smp_tick_init(void);
990#endif 1012#endif
991 1013
1014 dp = of_find_node_by_path("/");
992 if (tlb_type == spitfire) { 1015 if (tlb_type == spitfire) {
993 unsigned long ver, manuf, impl; 1016 unsigned long ver, manuf, impl;
994 1017
@@ -999,18 +1022,17 @@ static unsigned long sparc64_init_timers(void)
999 if (manuf == 0x17 && impl == 0x13) { 1022 if (manuf == 0x17 && impl == 0x13) {
1000 /* Hummingbird, aka Ultra-IIe */ 1023 /* Hummingbird, aka Ultra-IIe */
1001 tick_ops = &hbtick_operations; 1024 tick_ops = &hbtick_operations;
1002 node = prom_root_node; 1025 prop = of_find_property(dp, "stick-frequency", NULL);
1003 clock = prom_getint(node, "stick-frequency");
1004 } else { 1026 } else {
1005 tick_ops = &tick_operations; 1027 tick_ops = &tick_operations;
1006 cpu_find_by_instance(0, &node, NULL); 1028 cpu_find_by_instance(0, &dp, NULL);
1007 clock = prom_getint(node, "clock-frequency"); 1029 prop = of_find_property(dp, "clock-frequency", NULL);
1008 } 1030 }
1009 } else { 1031 } else {
1010 tick_ops = &stick_operations; 1032 tick_ops = &stick_operations;
1011 node = prom_root_node; 1033 prop = of_find_property(dp, "stick-frequency", NULL);
1012 clock = prom_getint(node, "stick-frequency");
1013 } 1034 }
1035 clock = *(unsigned int *) prop->value;
1014 timer_tick_offset = clock / HZ; 1036 timer_tick_offset = clock / HZ;
1015 1037
1016#ifdef CONFIG_SMP 1038#ifdef CONFIG_SMP
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 5059cbd4feee..1ff34b019f3f 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -42,6 +42,7 @@
42#ifdef CONFIG_KMOD 42#ifdef CONFIG_KMOD
43#include <linux/kmod.h> 43#include <linux/kmod.h>
44#endif 44#endif
45#include <asm/prom.h>
45 46
46ATOMIC_NOTIFIER_HEAD(sparc64die_chain); 47ATOMIC_NOTIFIER_HEAD(sparc64die_chain);
47 48
@@ -807,7 +808,8 @@ extern unsigned int cheetah_deferred_trap_vector[], cheetah_deferred_trap_vector
807void __init cheetah_ecache_flush_init(void) 808void __init cheetah_ecache_flush_init(void)
808{ 809{
809 unsigned long largest_size, smallest_linesize, order, ver; 810 unsigned long largest_size, smallest_linesize, order, ver;
810 int node, i, instance; 811 struct device_node *dp;
812 int i, instance, sz;
811 813
812 /* Scan all cpu device tree nodes, note two values: 814 /* Scan all cpu device tree nodes, note two values:
813 * 1) largest E-cache size 815 * 1) largest E-cache size
@@ -817,14 +819,14 @@ void __init cheetah_ecache_flush_init(void)
817 smallest_linesize = ~0UL; 819 smallest_linesize = ~0UL;
818 820
819 instance = 0; 821 instance = 0;
820 while (!cpu_find_by_instance(instance, &node, NULL)) { 822 while (!cpu_find_by_instance(instance, &dp, NULL)) {
821 unsigned long val; 823 unsigned long val;
822 824
823 val = prom_getintdefault(node, "ecache-size", 825 val = of_getintprop_default(dp, "ecache-size",
824 (2 * 1024 * 1024)); 826 (2 * 1024 * 1024));
825 if (val > largest_size) 827 if (val > largest_size)
826 largest_size = val; 828 largest_size = val;
827 val = prom_getintdefault(node, "ecache-line-size", 64); 829 val = of_getintprop_default(dp, "ecache-line-size", 64);
828 if (val < smallest_linesize) 830 if (val < smallest_linesize)
829 smallest_linesize = val; 831 smallest_linesize = val;
830 instance++; 832 instance++;
@@ -849,16 +851,16 @@ void __init cheetah_ecache_flush_init(void)
849 } 851 }
850 852
851 /* Now allocate error trap reporting scoreboard. */ 853 /* Now allocate error trap reporting scoreboard. */
852 node = NR_CPUS * (2 * sizeof(struct cheetah_err_info)); 854 sz = NR_CPUS * (2 * sizeof(struct cheetah_err_info));
853 for (order = 0; order < MAX_ORDER; order++) { 855 for (order = 0; order < MAX_ORDER; order++) {
854 if ((PAGE_SIZE << order) >= node) 856 if ((PAGE_SIZE << order) >= sz)
855 break; 857 break;
856 } 858 }
857 cheetah_error_log = (struct cheetah_err_info *) 859 cheetah_error_log = (struct cheetah_err_info *)
858 __get_free_pages(GFP_KERNEL, order); 860 __get_free_pages(GFP_KERNEL, order);
859 if (!cheetah_error_log) { 861 if (!cheetah_error_log) {
860 prom_printf("cheetah_ecache_flush_init: Failed to allocate " 862 prom_printf("cheetah_ecache_flush_init: Failed to allocate "
861 "error logging scoreboard (%d bytes).\n", node); 863 "error logging scoreboard (%d bytes).\n", sz);
862 prom_halt(); 864 prom_halt();
863 } 865 }
864 memset(cheetah_error_log, 0, PAGE_SIZE << order); 866 memset(cheetah_error_log, 0, PAGE_SIZE << order);
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
index 001e8518331f..bb2d68577855 100644
--- a/arch/sparc64/kernel/unaligned.c
+++ b/arch/sparc64/kernel/unaligned.c
@@ -279,12 +279,21 @@ static void kernel_mna_trap_fault(void)
279 279
280asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) 280asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn)
281{ 281{
282 static unsigned long count, last_time;
282 enum direction dir = decode_direction(insn); 283 enum direction dir = decode_direction(insn);
283 int size = decode_access_size(insn); 284 int size = decode_access_size(insn);
284 285
285 current_thread_info()->kern_una_regs = regs; 286 current_thread_info()->kern_una_regs = regs;
286 current_thread_info()->kern_una_insn = insn; 287 current_thread_info()->kern_una_insn = insn;
287 288
289 if (jiffies - last_time > 5 * HZ)
290 count = 0;
291 if (count < 5) {
292 last_time = jiffies;
293 count++;
294 printk("Kernel unaligned access at TPC[%lx]\n", regs->tpc);
295 }
296
288 if (!ok_for_kernel(insn) || dir == both) { 297 if (!ok_for_kernel(insn) || dir == both) {
289 printk("Unsupported unaligned load/store trap for kernel " 298 printk("Unsupported unaligned load/store trap for kernel "
290 "at <%016lx>.\n", regs->tpc); 299 "at <%016lx>.\n", regs->tpc);
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 1539a8362b6f..513993414747 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -42,6 +42,7 @@
42#include <asm/sections.h> 42#include <asm/sections.h>
43#include <asm/tsb.h> 43#include <asm/tsb.h>
44#include <asm/hypervisor.h> 44#include <asm/hypervisor.h>
45#include <asm/prom.h>
45 46
46extern void device_scan(void); 47extern void device_scan(void);
47 48
@@ -101,8 +102,6 @@ static void __init read_obp_memory(const char *property,
101 prom_halt(); 102 prom_halt();
102 } 103 }
103 104
104 *num_ents = ents;
105
106 /* Sanitize what we got from the firmware, by page aligning 105 /* Sanitize what we got from the firmware, by page aligning
107 * everything. 106 * everything.
108 */ 107 */
@@ -124,6 +123,25 @@ static void __init read_obp_memory(const char *property,
124 regs[i].phys_addr = base; 123 regs[i].phys_addr = base;
125 regs[i].reg_size = size; 124 regs[i].reg_size = size;
126 } 125 }
126
127 for (i = 0; i < ents; i++) {
128 if (regs[i].reg_size == 0UL) {
129 int j;
130
131 for (j = i; j < ents - 1; j++) {
132 regs[j].phys_addr =
133 regs[j+1].phys_addr;
134 regs[j].reg_size =
135 regs[j+1].reg_size;
136 }
137
138 ents--;
139 i--;
140 }
141 }
142
143 *num_ents = ents;
144
127 sort(regs, ents, sizeof(struct linux_prom64_registers), 145 sort(regs, ents, sizeof(struct linux_prom64_registers),
128 cmp_p64, NULL); 146 cmp_p64, NULL);
129} 147}
@@ -1339,6 +1357,8 @@ void __init paging_init(void)
1339 1357
1340 kernel_physical_mapping_init(); 1358 kernel_physical_mapping_init();
1341 1359
1360 prom_build_devicetree();
1361
1342 { 1362 {
1343 unsigned long zones_size[MAX_NR_ZONES]; 1363 unsigned long zones_size[MAX_NR_ZONES];
1344 unsigned long zholes_size[MAX_NR_ZONES]; 1364 unsigned long zholes_size[MAX_NR_ZONES];
@@ -1376,7 +1396,7 @@ static void __init taint_real_pages(void)
1376 while (old_start < old_end) { 1396 while (old_start < old_end) {
1377 int n; 1397 int n;
1378 1398
1379 for (n = 0; pavail_rescan_ents; n++) { 1399 for (n = 0; n < pavail_rescan_ents; n++) {
1380 unsigned long new_start, new_end; 1400 unsigned long new_start, new_end;
1381 1401
1382 new_start = pavail_rescan[n].phys_addr; 1402 new_start = pavail_rescan[n].phys_addr;
@@ -1398,6 +1418,32 @@ static void __init taint_real_pages(void)
1398 } 1418 }
1399} 1419}
1400 1420
1421int __init page_in_phys_avail(unsigned long paddr)
1422{
1423 int i;
1424
1425 paddr &= PAGE_MASK;
1426
1427 for (i = 0; i < pavail_rescan_ents; i++) {
1428 unsigned long start, end;
1429
1430 start = pavail_rescan[i].phys_addr;
1431 end = start + pavail_rescan[i].reg_size;
1432
1433 if (paddr >= start && paddr < end)
1434 return 1;
1435 }
1436 if (paddr >= kern_base && paddr < (kern_base + kern_size))
1437 return 1;
1438#ifdef CONFIG_BLK_DEV_INITRD
1439 if (paddr >= __pa(initrd_start) &&
1440 paddr < __pa(PAGE_ALIGN(initrd_end)))
1441 return 1;
1442#endif
1443
1444 return 0;
1445}
1446
1401void __init mem_init(void) 1447void __init mem_init(void)
1402{ 1448{
1403 unsigned long codepages, datapages, initpages; 1449 unsigned long codepages, datapages, initpages;
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index 5284996780a7..719c90905a1e 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -23,6 +23,7 @@
23#include <asm/oplib.h> 23#include <asm/oplib.h>
24#include <asm/idprom.h> 24#include <asm/idprom.h>
25#include <asm/smp.h> 25#include <asm/smp.h>
26#include <asm/prom.h>
26 27
27#include "conv.h" 28#include "conv.h"
28 29
@@ -194,14 +195,17 @@ static char *machine(void)
194 } 195 }
195} 196}
196 197
197static char *platform(char *buffer) 198static char *platform(char *buffer, int sz)
198{ 199{
200 struct device_node *dp = of_find_node_by_path("/");
199 int len; 201 int len;
200 202
201 *buffer = 0; 203 *buffer = 0;
202 len = prom_getproperty(prom_root_node, "name", buffer, 256); 204 len = strlen(dp->name);
203 if(len > 0) 205 if (len > sz)
204 buffer[len] = 0; 206 len = sz;
207 memcpy(buffer, dp->name, len);
208 buffer[len] = 0;
205 if (*buffer) { 209 if (*buffer) {
206 char *p; 210 char *p;
207 211
@@ -213,16 +217,22 @@ static char *platform(char *buffer)
213 return "sun4u"; 217 return "sun4u";
214} 218}
215 219
216static char *serial(char *buffer) 220static char *serial(char *buffer, int sz)
217{ 221{
218 int node = prom_getchild(prom_root_node); 222 struct device_node *dp = of_find_node_by_path("/options");
219 int len; 223 int len;
220 224
221 node = prom_searchsiblings(node, "options");
222 *buffer = 0; 225 *buffer = 0;
223 len = prom_getproperty(node, "system-board-serial#", buffer, 256); 226 if (dp) {
224 if(len > 0) 227 char *val = of_get_property(dp, "system-board-serial#", &len);
225 buffer[len] = 0; 228
229 if (val && len > 0) {
230 if (len > sz)
231 len = sz;
232 memcpy(buffer, val, len);
233 buffer[len] = 0;
234 }
235 }
226 if (!*buffer) 236 if (!*buffer)
227 return "4512348717234"; 237 return "4512348717234";
228 else 238 else
@@ -305,8 +315,8 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
305 case SI_MACHINE: r = machine(); break; 315 case SI_MACHINE: r = machine(); break;
306 case SI_ARCHITECTURE: r = "sparc"; break; 316 case SI_ARCHITECTURE: r = "sparc"; break;
307 case SI_HW_PROVIDER: r = "Sun_Microsystems"; break; 317 case SI_HW_PROVIDER: r = "Sun_Microsystems"; break;
308 case SI_HW_SERIAL: r = serial(buffer); break; 318 case SI_HW_SERIAL: r = serial(buffer, sizeof(buffer)); break;
309 case SI_PLATFORM: r = platform(buffer); break; 319 case SI_PLATFORM: r = platform(buffer, sizeof(buffer)); break;
310 case SI_SRPC_DOMAIN: r = ""; break; 320 case SI_SRPC_DOMAIN: r = ""; break;
311 case SI_VERSION: r = "Generic"; break; 321 case SI_VERSION: r = "Generic"; break;
312 default: return -EINVAL; 322 default: return -EINVAL;
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index ceeeba2c56c7..91f230939c1e 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -1,5 +1,6 @@
1obj-y := shutdown.o 1obj-y := shutdown.o
2obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o 2obj-$(CONFIG_PM) += main.o suspend.o resume.o runtime.o sysfs.o
3obj-$(CONFIG_PM_TRACE) += trace.o
3 4
4ifeq ($(CONFIG_DEBUG_DRIVER),y) 5ifeq ($(CONFIG_DEBUG_DRIVER),y)
5EXTRA_CFLAGS += -DDEBUG 6EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c
index 317edbf0feca..520679ce53a8 100644
--- a/drivers/base/power/resume.c
+++ b/drivers/base/power/resume.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/resume-trace.h>
12#include "../base.h" 13#include "../base.h"
13#include "power.h" 14#include "power.h"
14 15
@@ -23,6 +24,8 @@ int resume_device(struct device * dev)
23{ 24{
24 int error = 0; 25 int error = 0;
25 26
27 TRACE_DEVICE(dev);
28 TRACE_RESUME(0);
26 down(&dev->sem); 29 down(&dev->sem);
27 if (dev->power.pm_parent 30 if (dev->power.pm_parent
28 && dev->power.pm_parent->power.power_state.event) { 31 && dev->power.pm_parent->power.power_state.event) {
@@ -36,6 +39,7 @@ int resume_device(struct device * dev)
36 error = dev->bus->resume(dev); 39 error = dev->bus->resume(dev);
37 } 40 }
38 up(&dev->sem); 41 up(&dev->sem);
42 TRACE_RESUME(error);
39 return error; 43 return error;
40} 44}
41 45
diff --git a/drivers/base/power/trace.c b/drivers/base/power/trace.c
new file mode 100644
index 000000000000..a9ab30fefffc
--- /dev/null
+++ b/drivers/base/power/trace.c
@@ -0,0 +1,228 @@
1/*
2 * drivers/base/power/trace.c
3 *
4 * Copyright (C) 2006 Linus Torvalds
5 *
6 * Trace facility for suspend/resume problems, when none of the
7 * devices may be working.
8 */
9
10#include <linux/resume-trace.h>
11#include <linux/rtc.h>
12
13#include <asm/rtc.h>
14
15#include "power.h"
16
17/*
18 * Horrid, horrid, horrid.
19 *
20 * It turns out that the _only_ piece of hardware that actually
21 * keeps its value across a hard boot (and, more importantly, the
22 * POST init sequence) is literally the realtime clock.
23 *
24 * Never mind that an RTC chip has 114 bytes (and often a whole
25 * other bank of an additional 128 bytes) of nice SRAM that is
26 * _designed_ to keep data - the POST will clear it. So we literally
27 * can just use the few bytes of actual time data, which means that
28 * we're really limited.
29 *
30 * It means, for example, that we can't use the seconds at all
31 * (since the time between the hang and the boot might be more
32 * than a minute), and we'd better not depend on the low bits of
33 * the minutes either.
34 *
35 * There are the wday fields etc, but I wouldn't guarantee those
36 * are dependable either. And if the date isn't valid, either the
37 * hw or POST will do strange things.
38 *
39 * So we're left with:
40 * - year: 0-99
41 * - month: 0-11
42 * - day-of-month: 1-28
43 * - hour: 0-23
44 * - min: (0-30)*2
45 *
46 * Giving us a total range of 0-16128000 (0xf61800), ie less
47 * than 24 bits of actual data we can save across reboots.
48 *
49 * And if your box can't boot in less than three minutes,
50 * you're screwed.
51 *
52 * Now, almost 24 bits of data is pitifully small, so we need
53 * to be pretty dense if we want to use it for anything nice.
54 * What we do is that instead of saving off nice readable info,
55 * we save off _hashes_ of information that we can hopefully
56 * regenerate after the reboot.
57 *
58 * In particular, this means that we might be unlucky, and hit
59 * a case where we have a hash collision, and we end up not
60 * being able to tell for certain exactly which case happened.
61 * But that's hopefully unlikely.
62 *
63 * What we do is to take the bits we can fit, and split them
64 * into three parts (16*997*1009 = 16095568), and use the values
65 * for:
66 * - 0-15: user-settable
67 * - 0-996: file + line number
68 * - 0-1008: device
69 */
70#define USERHASH (16)
71#define FILEHASH (997)
72#define DEVHASH (1009)
73
74#define DEVSEED (7919)
75
76static unsigned int dev_hash_value;
77
78static int set_magic_time(unsigned int user, unsigned int file, unsigned int device)
79{
80 unsigned int n = user + USERHASH*(file + FILEHASH*device);
81
82 // June 7th, 2006
83 static struct rtc_time time = {
84 .tm_sec = 0,
85 .tm_min = 0,
86 .tm_hour = 0,
87 .tm_mday = 7,
88 .tm_mon = 5, // June - counting from zero
89 .tm_year = 106,
90 .tm_wday = 3,
91 .tm_yday = 160,
92 .tm_isdst = 1
93 };
94
95 time.tm_year = (n % 100);
96 n /= 100;
97 time.tm_mon = (n % 12);
98 n /= 12;
99 time.tm_mday = (n % 28) + 1;
100 n /= 28;
101 time.tm_hour = (n % 24);
102 n /= 24;
103 time.tm_min = (n % 20) * 3;
104 n /= 20;
105 set_rtc_time(&time);
106 return n ? -1 : 0;
107}
108
109static unsigned int read_magic_time(void)
110{
111 struct rtc_time time;
112 unsigned int val;
113
114 get_rtc_time(&time);
115 printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n",
116 time.tm_hour, time.tm_min, time.tm_sec,
117 time.tm_mon, time.tm_mday, time.tm_year);
118 val = time.tm_year; /* 100 years */
119 if (val > 100)
120 val -= 100;
121 val += time.tm_mon * 100; /* 12 months */
122 val += (time.tm_mday-1) * 100 * 12; /* 28 month-days */
123 val += time.tm_hour * 100 * 12 * 28; /* 24 hours */
124 val += (time.tm_min / 3) * 100 * 12 * 28 * 24; /* 20 3-minute intervals */
125 return val;
126}
127
128/*
129 * This is just the sdbm hash function with a user-supplied
130 * seed and final size parameter.
131 */
132static unsigned int hash_string(unsigned int seed, const char *data, unsigned int mod)
133{
134 unsigned char c;
135 while ((c = *data++) != 0) {
136 seed = (seed << 16) + (seed << 6) - seed + c;
137 }
138 return seed % mod;
139}
140
141void set_trace_device(struct device *dev)
142{
143 dev_hash_value = hash_string(DEVSEED, dev->bus_id, DEVHASH);
144}
145
146/*
147 * We could just take the "tracedata" index into the .tracedata
148 * section instead. Generating a hash of the data gives us a
149 * chance to work across kernel versions, and perhaps more
150 * importantly it also gives us valid/invalid check (ie we will
151 * likely not give totally bogus reports - if the hash matches,
152 * it's not any guarantee, but it's a high _likelihood_ that
153 * the match is valid).
154 */
155void generate_resume_trace(void *tracedata, unsigned int user)
156{
157 unsigned short lineno = *(unsigned short *)tracedata;
158 const char *file = *(const char **)(tracedata + 2);
159 unsigned int user_hash_value, file_hash_value;
160
161 user_hash_value = user % USERHASH;
162 file_hash_value = hash_string(lineno, file, FILEHASH);
163 set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
164}
165
166extern char __tracedata_start, __tracedata_end;
167static int show_file_hash(unsigned int value)
168{
169 int match;
170 char *tracedata;
171
172 match = 0;
173 for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ; tracedata += 6) {
174 unsigned short lineno = *(unsigned short *)tracedata;
175 const char *file = *(const char **)(tracedata + 2);
176 unsigned int hash = hash_string(lineno, file, FILEHASH);
177 if (hash != value)
178 continue;
179 printk(" hash matches %s:%u\n", file, lineno);
180 match++;
181 }
182 return match;
183}
184
185static int show_dev_hash(unsigned int value)
186{
187 int match = 0;
188 struct list_head * entry = dpm_active.prev;
189
190 while (entry != &dpm_active) {
191 struct device * dev = to_device(entry);
192 unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH);
193 if (hash == value) {
194 printk(" hash matches device %s\n", dev->bus_id);
195 match++;
196 }
197 entry = entry->prev;
198 }
199 return match;
200}
201
202static unsigned int hash_value_early_read;
203
204static int early_resume_init(void)
205{
206 hash_value_early_read = read_magic_time();
207 return 0;
208}
209
210static int late_resume_init(void)
211{
212 unsigned int val = hash_value_early_read;
213 unsigned int user, file, dev;
214
215 user = val % USERHASH;
216 val = val / USERHASH;
217 file = val % FILEHASH;
218 val = val / FILEHASH;
219 dev = val /* % DEVHASH */;
220
221 printk(" Magic number: %d:%d:%d\n", user, file, dev);
222 show_file_hash(file);
223 show_dev_hash(dev);
224 return 0;
225}
226
227core_initcall(early_resume_init);
228late_initcall(late_resume_init);
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index 9f4b8ce4c05e..a94233bdbc0e 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -758,7 +758,9 @@ drm_ioctl_desc_t i915_ioctls[] = {
758 [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, 758 [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH},
759 [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, 759 [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
760 [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, 760 [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH},
761 [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY } 761 [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
762 [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] = { i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY },
763 [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] = { i915_vblank_pipe_get, DRM_AUTH },
762}; 764};
763 765
764int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 766int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
index 4cb3da578330..5aa3e0e3bb45 100644
--- a/drivers/char/drm/i915_drm.h
+++ b/drivers/char/drm/i915_drm.h
@@ -124,6 +124,8 @@ typedef struct _drm_i915_sarea {
124#define DRM_I915_INIT_HEAP 0x0a 124#define DRM_I915_INIT_HEAP 0x0a
125#define DRM_I915_CMDBUFFER 0x0b 125#define DRM_I915_CMDBUFFER 0x0b
126#define DRM_I915_DESTROY_HEAP 0x0c 126#define DRM_I915_DESTROY_HEAP 0x0c
127#define DRM_I915_SET_VBLANK_PIPE 0x0d
128#define DRM_I915_GET_VBLANK_PIPE 0x0e
127 129
128#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) 130#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
129#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) 131#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -138,6 +140,8 @@ typedef struct _drm_i915_sarea {
138#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) 140#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
139#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) 141#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
140#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) 142#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
143#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
144#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
141 145
142/* Allow drivers to submit batchbuffers directly to hardware, relying 146/* Allow drivers to submit batchbuffers directly to hardware, relying
143 * on the security mechanisms provided by hardware. 147 * on the security mechanisms provided by hardware.
@@ -224,4 +228,13 @@ typedef struct drm_i915_mem_destroy_heap {
224 int region; 228 int region;
225} drm_i915_mem_destroy_heap_t; 229} drm_i915_mem_destroy_heap_t;
226 230
231/* Allow X server to configure which pipes to monitor for vblank signals
232 */
233#define DRM_I915_VBLANK_PIPE_A 1
234#define DRM_I915_VBLANK_PIPE_B 2
235
236typedef struct drm_i915_vblank_pipe {
237 int pipe;
238} drm_i915_vblank_pipe_t;
239
227#endif /* _I915_DRM_H_ */ 240#endif /* _I915_DRM_H_ */
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 7a65666899e4..2d565031c002 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -45,9 +45,10 @@
45 * 1.2: Add Power Management 45 * 1.2: Add Power Management
46 * 1.3: Add vblank support 46 * 1.3: Add vblank support
47 * 1.4: Fix cmdbuffer path, add heap destroy 47 * 1.4: Fix cmdbuffer path, add heap destroy
48 * 1.5: Add vblank pipe configuration
48 */ 49 */
49#define DRIVER_MAJOR 1 50#define DRIVER_MAJOR 1
50#define DRIVER_MINOR 4 51#define DRIVER_MINOR 5
51#define DRIVER_PATCHLEVEL 0 52#define DRIVER_PATCHLEVEL 0
52 53
53typedef struct _drm_i915_ring_buffer { 54typedef struct _drm_i915_ring_buffer {
@@ -96,6 +97,7 @@ typedef struct drm_i915_private {
96 int allow_batchbuffer; 97 int allow_batchbuffer;
97 struct mem_block *agp_heap; 98 struct mem_block *agp_heap;
98 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; 99 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
100 int vblank_pipe;
99} drm_i915_private_t; 101} drm_i915_private_t;
100 102
101extern drm_ioctl_desc_t i915_ioctls[]; 103extern drm_ioctl_desc_t i915_ioctls[];
@@ -119,6 +121,8 @@ extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
119extern void i915_driver_irq_preinstall(drm_device_t * dev); 121extern void i915_driver_irq_preinstall(drm_device_t * dev);
120extern void i915_driver_irq_postinstall(drm_device_t * dev); 122extern void i915_driver_irq_postinstall(drm_device_t * dev);
121extern void i915_driver_irq_uninstall(drm_device_t * dev); 123extern void i915_driver_irq_uninstall(drm_device_t * dev);
124extern int i915_vblank_pipe_set(DRM_IOCTL_ARGS);
125extern int i915_vblank_pipe_get(DRM_IOCTL_ARGS);
122 126
123/* i915_mem.c */ 127/* i915_mem.c */
124extern int i915_mem_alloc(DRM_IOCTL_ARGS); 128extern int i915_mem_alloc(DRM_IOCTL_ARGS);
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
index a752afd86ab8..cd96cfa430db 100644
--- a/drivers/char/drm/i915_irq.c
+++ b/drivers/char/drm/i915_irq.c
@@ -44,7 +44,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
44 u16 temp; 44 u16 temp;
45 45
46 temp = I915_READ16(I915REG_INT_IDENTITY_R); 46 temp = I915_READ16(I915REG_INT_IDENTITY_R);
47 temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG); 47
48 temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
48 49
49 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp); 50 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
50 51
@@ -58,7 +59,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
58 if (temp & USER_INT_FLAG) 59 if (temp & USER_INT_FLAG)
59 DRM_WAKEUP(&dev_priv->irq_queue); 60 DRM_WAKEUP(&dev_priv->irq_queue);
60 61
61 if (temp & VSYNC_PIPEA_FLAG) { 62 if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
62 atomic_inc(&dev->vbl_received); 63 atomic_inc(&dev->vbl_received);
63 DRM_WAKEUP(&dev->vbl_queue); 64 DRM_WAKEUP(&dev->vbl_queue);
64 drm_vbl_send_signals(dev); 65 drm_vbl_send_signals(dev);
@@ -182,6 +183,68 @@ int i915_irq_wait(DRM_IOCTL_ARGS)
182 return i915_wait_irq(dev, irqwait.irq_seq); 183 return i915_wait_irq(dev, irqwait.irq_seq);
183} 184}
184 185
186static int i915_enable_interrupt (drm_device_t *dev)
187{
188 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
189 u16 flag;
190
191 flag = 0;
192 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
193 flag |= VSYNC_PIPEA_FLAG;
194 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
195 flag |= VSYNC_PIPEB_FLAG;
196 if (dev_priv->vblank_pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
197 DRM_ERROR("%s called with invalid pipe 0x%x\n",
198 __FUNCTION__, dev_priv->vblank_pipe);
199 return DRM_ERR(EINVAL);
200 }
201 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
202 return 0;
203}
204
205/* Set the vblank monitor pipe
206 */
207int i915_vblank_pipe_set(DRM_IOCTL_ARGS)
208{
209 DRM_DEVICE;
210 drm_i915_private_t *dev_priv = dev->dev_private;
211 drm_i915_vblank_pipe_t pipe;
212
213 if (!dev_priv) {
214 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
215 return DRM_ERR(EINVAL);
216 }
217
218 DRM_COPY_FROM_USER_IOCTL(pipe, (drm_i915_vblank_pipe_t __user *) data,
219 sizeof(pipe));
220
221 dev_priv->vblank_pipe = pipe.pipe;
222 return i915_enable_interrupt (dev);
223}
224
225int i915_vblank_pipe_get(DRM_IOCTL_ARGS)
226{
227 DRM_DEVICE;
228 drm_i915_private_t *dev_priv = dev->dev_private;
229 drm_i915_vblank_pipe_t pipe;
230 u16 flag;
231
232 if (!dev_priv) {
233 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
234 return DRM_ERR(EINVAL);
235 }
236
237 flag = I915_READ(I915REG_INT_ENABLE_R);
238 pipe.pipe = 0;
239 if (flag & VSYNC_PIPEA_FLAG)
240 pipe.pipe |= DRM_I915_VBLANK_PIPE_A;
241 if (flag & VSYNC_PIPEB_FLAG)
242 pipe.pipe |= DRM_I915_VBLANK_PIPE_B;
243 DRM_COPY_TO_USER_IOCTL((drm_i915_vblank_pipe_t __user *) data, pipe,
244 sizeof(pipe));
245 return 0;
246}
247
185/* drm_dma.h hooks 248/* drm_dma.h hooks
186*/ 249*/
187void i915_driver_irq_preinstall(drm_device_t * dev) 250void i915_driver_irq_preinstall(drm_device_t * dev)
@@ -197,7 +260,7 @@ void i915_driver_irq_postinstall(drm_device_t * dev)
197{ 260{
198 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 261 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
199 262
200 I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | VSYNC_PIPEA_FLAG); 263 i915_enable_interrupt(dev);
201 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue); 264 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
202} 265}
203 266
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 7f949c9c9691..5ad43ba7b5aa 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -39,7 +39,7 @@
39static int radeon_do_cleanup_cp(drm_device_t * dev); 39static int radeon_do_cleanup_cp(drm_device_t * dev);
40 40
41/* CP microcode (from ATI) */ 41/* CP microcode (from ATI) */
42static u32 R200_cp_microcode[][2] = { 42static const u32 R200_cp_microcode[][2] = {
43 {0x21007000, 0000000000}, 43 {0x21007000, 0000000000},
44 {0x20007000, 0000000000}, 44 {0x20007000, 0000000000},
45 {0x000000ab, 0x00000004}, 45 {0x000000ab, 0x00000004},
@@ -298,7 +298,7 @@ static u32 R200_cp_microcode[][2] = {
298 {0000000000, 0000000000}, 298 {0000000000, 0000000000},
299}; 299};
300 300
301static u32 radeon_cp_microcode[][2] = { 301static const u32 radeon_cp_microcode[][2] = {
302 {0x21007000, 0000000000}, 302 {0x21007000, 0000000000},
303 {0x20007000, 0000000000}, 303 {0x20007000, 0000000000},
304 {0x000000b4, 0x00000004}, 304 {0x000000b4, 0x00000004},
@@ -557,7 +557,7 @@ static u32 radeon_cp_microcode[][2] = {
557 {0000000000, 0000000000}, 557 {0000000000, 0000000000},
558}; 558};
559 559
560static u32 R300_cp_microcode[][2] = { 560static const u32 R300_cp_microcode[][2] = {
561 {0x4200e000, 0000000000}, 561 {0x4200e000, 0000000000},
562 {0x4000e000, 0000000000}, 562 {0x4000e000, 0000000000},
563 {0x000000af, 0x00000008}, 563 {0x000000af, 0x00000008},
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
index c8e279e89c2e..8d6350dd5360 100644
--- a/drivers/char/drm/radeon_drm.h
+++ b/drivers/char/drm/radeon_drm.h
@@ -161,7 +161,8 @@
161#define R200_EMIT_PP_TXCTLALL_3 91 161#define R200_EMIT_PP_TXCTLALL_3 91
162#define R200_EMIT_PP_TXCTLALL_4 92 162#define R200_EMIT_PP_TXCTLALL_4 92
163#define R200_EMIT_PP_TXCTLALL_5 93 163#define R200_EMIT_PP_TXCTLALL_5 93
164#define RADEON_MAX_STATE_PACKETS 94 164#define R200_EMIT_VAP_PVS_CNTL 94
165#define RADEON_MAX_STATE_PACKETS 95
165 166
166/* Commands understood by cmd_buffer ioctl. More can be added but 167/* Commands understood by cmd_buffer ioctl. More can be added but
167 * obviously these can't be removed or changed: 168 * obviously these can't be removed or changed:
@@ -176,6 +177,7 @@
176#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note: 177#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
177 * doesn't make the cpu wait, just 178 * doesn't make the cpu wait, just
178 * the graphics hardware */ 179 * the graphics hardware */
180#define RADEON_CMD_VECLINEAR 9 /* another r200 stopgap */
179 181
180typedef union { 182typedef union {
181 int i; 183 int i;
@@ -192,6 +194,9 @@ typedef union {
192 unsigned char cmd_type, offset, stride, count; 194 unsigned char cmd_type, offset, stride, count;
193 } vectors; 195 } vectors;
194 struct { 196 struct {
197 unsigned char cmd_type, addr_lo, addr_hi, count;
198 } veclinear;
199 struct {
195 unsigned char cmd_type, buf_idx, pad0, pad1; 200 unsigned char cmd_type, buf_idx, pad0, pad1;
196 } dma; 201 } dma;
197 struct { 202 struct {
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 78345cee8f8e..e5a256f5429c 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -38,7 +38,7 @@
38 38
39#define DRIVER_NAME "radeon" 39#define DRIVER_NAME "radeon"
40#define DRIVER_DESC "ATI Radeon" 40#define DRIVER_DESC "ATI Radeon"
41#define DRIVER_DATE "20060225" 41#define DRIVER_DATE "20060524"
42 42
43/* Interface history: 43/* Interface history:
44 * 44 *
@@ -93,9 +93,11 @@
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL) 93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
94 * 1.23- Add new radeon memory map work from benh 94 * 1.23- Add new radeon memory map work from benh
95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300) 95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
96 * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
97 * new packet type)
96 */ 98 */
97#define DRIVER_MAJOR 1 99#define DRIVER_MAJOR 1
98#define DRIVER_MINOR 24 100#define DRIVER_MINOR 25
99#define DRIVER_PATCHLEVEL 0 101#define DRIVER_PATCHLEVEL 0
100 102
101/* 103/*
@@ -884,6 +886,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
884#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00 886#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00
885#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14 887#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14
886 888
889#define RADEON_SE_TCL_STATE_FLUSH 0x2284
890
887#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 891#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001
888#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 892#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000
889#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012 893#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012
@@ -905,6 +909,8 @@ extern int r300_do_cp_cmdbuf(drm_device_t * dev, DRMFILE filp,
905#define R200_PP_AFS_0 0x2f80 909#define R200_PP_AFS_0 0x2f80
906#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */ 910#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */
907 911
912#define R200_VAP_PVS_CNTL_1 0x22D0
913
908/* Constants */ 914/* Constants */
909#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ 915#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
910 916
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index c5b8f774a599..5bb2234a9094 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -249,6 +249,7 @@ static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
249 case R200_EMIT_PP_TXCTLALL_3: 249 case R200_EMIT_PP_TXCTLALL_3:
250 case R200_EMIT_PP_TXCTLALL_4: 250 case R200_EMIT_PP_TXCTLALL_4:
251 case R200_EMIT_PP_TXCTLALL_5: 251 case R200_EMIT_PP_TXCTLALL_5:
252 case R200_EMIT_VAP_PVS_CNTL:
252 /* These packets don't contain memory offsets */ 253 /* These packets don't contain memory offsets */
253 break; 254 break;
254 255
@@ -626,6 +627,7 @@ static struct {
626 {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"}, 627 {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
627 {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"}, 628 {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
628 {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"}, 629 {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
630 {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},
629}; 631};
630 632
631/* ================================================================ 633/* ================================================================
@@ -2595,7 +2597,8 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2595 int stride = header.vectors.stride; 2597 int stride = header.vectors.stride;
2596 RING_LOCALS; 2598 RING_LOCALS;
2597 2599
2598 BEGIN_RING(3 + sz); 2600 BEGIN_RING(5 + sz);
2601 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2599 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0)); 2602 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2600 OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); 2603 OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2601 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1))); 2604 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
@@ -2607,6 +2610,32 @@ static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2607 return 0; 2610 return 0;
2608} 2611}
2609 2612
2613static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv,
2614 drm_radeon_cmd_header_t header,
2615 drm_radeon_kcmd_buffer_t *cmdbuf)
2616{
2617 int sz = header.veclinear.count * 4;
2618 int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8);
2619 RING_LOCALS;
2620
2621 if (!sz)
2622 return 0;
2623 if (sz * 4 > cmdbuf->bufsz)
2624 return DRM_ERR(EINVAL);
2625
2626 BEGIN_RING(5 + sz);
2627 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2628 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2629 OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2630 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2631 OUT_RING_TABLE(cmdbuf->buf, sz);
2632 ADVANCE_RING();
2633
2634 cmdbuf->buf += sz * sizeof(int);
2635 cmdbuf->bufsz -= sz * sizeof(int);
2636 return 0;
2637}
2638
2610static int radeon_emit_packet3(drm_device_t * dev, 2639static int radeon_emit_packet3(drm_device_t * dev,
2611 drm_file_t * filp_priv, 2640 drm_file_t * filp_priv,
2612 drm_radeon_kcmd_buffer_t *cmdbuf) 2641 drm_radeon_kcmd_buffer_t *cmdbuf)
@@ -2865,6 +2894,14 @@ static int radeon_cp_cmdbuf(DRM_IOCTL_ARGS)
2865 goto err; 2894 goto err;
2866 } 2895 }
2867 break; 2896 break;
2897 case RADEON_CMD_VECLINEAR:
2898 DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
2899 if (radeon_emit_veclinear(dev_priv, header, &cmdbuf)) {
2900 DRM_ERROR("radeon_emit_veclinear failed\n");
2901 goto err;
2902 }
2903 break;
2904
2868 default: 2905 default:
2869 DRM_ERROR("bad cmd_type %d at %p\n", 2906 DRM_ERROR("bad cmd_type %d at %p\n",
2870 header.header.cmd_type, 2907 header.header.cmd_type,
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index f6686fcce809..0897b0c8d528 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -928,7 +928,7 @@ static int __init rtc_init(void)
928#ifdef __sparc__ 928#ifdef __sparc__
929 for_each_ebus(ebus) { 929 for_each_ebus(ebus) {
930 for_each_ebusdev(edev, ebus) { 930 for_each_ebusdev(edev, ebus) {
931 if(strcmp(edev->prom_name, "rtc") == 0) { 931 if(strcmp(edev->prom_node->name, "rtc") == 0) {
932 rtc_port = edev->resource[0].start; 932 rtc_port = edev->resource[0].start;
933 rtc_irq = edev->irqs[0]; 933 rtc_irq = edev->irqs[0];
934 goto found; 934 goto found;
@@ -938,7 +938,7 @@ static int __init rtc_init(void)
938#ifdef __sparc_v9__ 938#ifdef __sparc_v9__
939 for_each_isa(isa_br) { 939 for_each_isa(isa_br) {
940 for_each_isadev(isa_dev, isa_br) { 940 for_each_isadev(isa_dev, isa_br) {
941 if (strcmp(isa_dev->prom_name, "rtc") == 0) { 941 if (strcmp(isa_dev->prom_node->name, "rtc") == 0) {
942 rtc_port = isa_dev->resource.start; 942 rtc_port = isa_dev->resource.start;
943 rtc_irq = isa_dev->irq; 943 rtc_irq = isa_dev->irq;
944 goto found; 944 goto found;
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 4bad588d0e5d..a6dfc7455733 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -26,7 +26,7 @@ config INPUT_PCSPKR
26 26
27config INPUT_SPARCSPKR 27config INPUT_SPARCSPKR
28 tristate "SPARC Speaker support" 28 tristate "SPARC Speaker support"
29 depends on PCI && SPARC 29 depends on PCI && SPARC64
30 help 30 help
31 Say Y here if you want the standard Speaker on Sparc PCI systems 31 Say Y here if you want the standard Speaker on Sparc PCI systems
32 to be used for bells and whistles. 32 to be used for bells and whistles.
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index f0fd2c4740f1..42c11fbf3c79 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -2,7 +2,7 @@
2 * Driver for PC-speaker like devices found on various Sparc systems. 2 * Driver for PC-speaker like devices found on various Sparc systems.
3 * 3 *
4 * Copyright (c) 2002 Vojtech Pavlik 4 * Copyright (c) 2002 Vojtech Pavlik
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com) 5 * Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net)
6 */ 6 */
7#include <linux/config.h> 7#include <linux/config.h>
8#include <linux/kernel.h> 8#include <linux/kernel.h>
@@ -13,21 +13,23 @@
13 13
14#include <asm/io.h> 14#include <asm/io.h>
15#include <asm/ebus.h> 15#include <asm/ebus.h>
16#ifdef CONFIG_SPARC64
17#include <asm/isa.h> 16#include <asm/isa.h>
18#endif
19 17
20MODULE_AUTHOR("David S. Miller <davem@redhat.com>"); 18MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
21MODULE_DESCRIPTION("Sparc Speaker beeper driver"); 19MODULE_DESCRIPTION("Sparc Speaker beeper driver");
22MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
23 21
24const char *beep_name; 22struct sparcspkr_state {
25static unsigned long beep_iobase; 23 const char *name;
26static int (*beep_event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 24 unsigned long iobase;
27static DEFINE_SPINLOCK(beep_lock); 25 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
26 spinlock_t lock;
27 struct input_dev *input_dev;
28};
28 29
29static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 30static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
30{ 31{
32 struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev);
31 unsigned int count = 0; 33 unsigned int count = 0;
32 unsigned long flags; 34 unsigned long flags;
33 35
@@ -43,24 +45,24 @@ static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned in
43 if (value > 20 && value < 32767) 45 if (value > 20 && value < 32767)
44 count = 1193182 / value; 46 count = 1193182 / value;
45 47
46 spin_lock_irqsave(&beep_lock, flags); 48 spin_lock_irqsave(&state->lock, flags);
47 49
48 /* EBUS speaker only has on/off state, the frequency does not 50 /* EBUS speaker only has on/off state, the frequency does not
49 * appear to be programmable. 51 * appear to be programmable.
50 */ 52 */
51 if (beep_iobase & 0x2UL) 53 if (state->iobase & 0x2UL)
52 outb(!!count, beep_iobase); 54 outb(!!count, state->iobase);
53 else 55 else
54 outl(!!count, beep_iobase); 56 outl(!!count, state->iobase);
55 57
56 spin_unlock_irqrestore(&beep_lock, flags); 58 spin_unlock_irqrestore(&state->lock, flags);
57 59
58 return 0; 60 return 0;
59} 61}
60 62
61#ifdef CONFIG_SPARC64
62static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 63static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
63{ 64{
65 struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev);
64 unsigned int count = 0; 66 unsigned int count = 0;
65 unsigned long flags; 67 unsigned long flags;
66 68
@@ -76,29 +78,29 @@ static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int
76 if (value > 20 && value < 32767) 78 if (value > 20 && value < 32767)
77 count = 1193182 / value; 79 count = 1193182 / value;
78 80
79 spin_lock_irqsave(&beep_lock, flags); 81 spin_lock_irqsave(&state->lock, flags);
80 82
81 if (count) { 83 if (count) {
82 /* enable counter 2 */ 84 /* enable counter 2 */
83 outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61); 85 outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61);
84 /* set command for counter 2, 2 byte write */ 86 /* set command for counter 2, 2 byte write */
85 outb(0xB6, beep_iobase + 0x43); 87 outb(0xB6, state->iobase + 0x43);
86 /* select desired HZ */ 88 /* select desired HZ */
87 outb(count & 0xff, beep_iobase + 0x42); 89 outb(count & 0xff, state->iobase + 0x42);
88 outb((count >> 8) & 0xff, beep_iobase + 0x42); 90 outb((count >> 8) & 0xff, state->iobase + 0x42);
89 } else { 91 } else {
90 /* disable counter 2 */ 92 /* disable counter 2 */
91 outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61); 93 outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61);
92 } 94 }
93 95
94 spin_unlock_irqrestore(&beep_lock, flags); 96 spin_unlock_irqrestore(&state->lock, flags);
95 97
96 return 0; 98 return 0;
97} 99}
98#endif
99 100
100static int __devinit sparcspkr_probe(struct platform_device *dev) 101static int __devinit sparcspkr_probe(struct device *dev)
101{ 102{
103 struct sparcspkr_state *state = dev_get_drvdata(dev);
102 struct input_dev *input_dev; 104 struct input_dev *input_dev;
103 int error; 105 int error;
104 106
@@ -106,18 +108,18 @@ static int __devinit sparcspkr_probe(struct platform_device *dev)
106 if (!input_dev) 108 if (!input_dev)
107 return -ENOMEM; 109 return -ENOMEM;
108 110
109 input_dev->name = beep_name; 111 input_dev->name = state->name;
110 input_dev->phys = "sparc/input0"; 112 input_dev->phys = "sparc/input0";
111 input_dev->id.bustype = BUS_ISA; 113 input_dev->id.bustype = BUS_ISA;
112 input_dev->id.vendor = 0x001f; 114 input_dev->id.vendor = 0x001f;
113 input_dev->id.product = 0x0001; 115 input_dev->id.product = 0x0001;
114 input_dev->id.version = 0x0100; 116 input_dev->id.version = 0x0100;
115 input_dev->cdev.dev = &dev->dev; 117 input_dev->cdev.dev = dev;
116 118
117 input_dev->evbit[0] = BIT(EV_SND); 119 input_dev->evbit[0] = BIT(EV_SND);
118 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 120 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
119 121
120 input_dev->event = beep_event; 122 input_dev->event = state->event;
121 123
122 error = input_register_device(input_dev); 124 error = input_register_device(input_dev);
123 if (error) { 125 if (error) {
@@ -125,111 +127,137 @@ static int __devinit sparcspkr_probe(struct platform_device *dev)
125 return error; 127 return error;
126 } 128 }
127 129
128 platform_set_drvdata(dev, input_dev); 130 state->input_dev = input_dev;
129 131
130 return 0; 132 return 0;
131} 133}
132 134
133static int __devexit sparcspkr_remove(struct platform_device *dev) 135static int __devexit sparcspkr_remove(struct of_device *dev)
134{ 136{
135 struct input_dev *input_dev = platform_get_drvdata(dev); 137 struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
138 struct input_dev *input_dev = state->input_dev;
136 139
137 input_unregister_device(input_dev);
138 platform_set_drvdata(dev, NULL);
139 /* turn off the speaker */ 140 /* turn off the speaker */
140 beep_event(NULL, EV_SND, SND_BELL, 0); 141 state->event(input_dev, EV_SND, SND_BELL, 0);
142
143 input_unregister_device(input_dev);
144
145 dev_set_drvdata(&dev->dev, NULL);
146 kfree(state);
141 147
142 return 0; 148 return 0;
143} 149}
144 150
145static void sparcspkr_shutdown(struct platform_device *dev) 151static int sparcspkr_shutdown(struct of_device *dev)
146{ 152{
153 struct sparcspkr_state *state = dev_get_drvdata(&dev->dev);
154 struct input_dev *input_dev = state->input_dev;
155
147 /* turn off the speaker */ 156 /* turn off the speaker */
148 beep_event(NULL, EV_SND, SND_BELL, 0); 157 state->event(input_dev, EV_SND, SND_BELL, 0);
158
159 return 0;
160}
161
162static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match)
163{
164 struct linux_ebus_device *edev = to_ebus_device(&dev->dev);
165 struct sparcspkr_state *state;
166 int err;
167
168 state = kzalloc(sizeof(*state), GFP_KERNEL);
169 if (!state)
170 return -ENOMEM;
171
172 state->name = "Sparc EBUS Speaker";
173 state->iobase = edev->resource[0].start;
174 state->event = ebus_spkr_event;
175 spin_lock_init(&state->lock);
176
177 dev_set_drvdata(&dev->dev, state);
178
179 err = sparcspkr_probe(&dev->dev);
180 if (err) {
181 dev_set_drvdata(&dev->dev, NULL);
182 kfree(state);
183 }
184
185 return 0;
149} 186}
150 187
151static struct platform_driver sparcspkr_platform_driver = { 188static struct of_device_id ebus_beep_match[] = {
152 .driver = { 189 {
153 .name = "sparcspkr", 190 .name = "beep",
154 .owner = THIS_MODULE,
155 }, 191 },
156 .probe = sparcspkr_probe, 192 {},
157 .remove = __devexit_p(sparcspkr_remove),
158 .shutdown = sparcspkr_shutdown,
159}; 193};
160 194
161static struct platform_device *sparcspkr_platform_device; 195static struct of_platform_driver ebus_beep_driver = {
196 .name = "beep",
197 .match_table = ebus_beep_match,
198 .probe = ebus_beep_probe,
199 .remove = sparcspkr_remove,
200 .shutdown = sparcspkr_shutdown,
201};
162 202
163static int __init sparcspkr_drv_init(void) 203static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match)
164{ 204{
165 int error; 205 struct sparc_isa_device *idev = to_isa_device(&dev->dev);
206 struct sparcspkr_state *state;
207 int err;
166 208
167 error = platform_driver_register(&sparcspkr_platform_driver); 209 state = kzalloc(sizeof(*state), GFP_KERNEL);
168 if (error) 210 if (!state)
169 return error; 211 return -ENOMEM;
170 212
171 sparcspkr_platform_device = platform_device_alloc("sparcspkr", -1); 213 state->name = "Sparc ISA Speaker";
172 if (!sparcspkr_platform_device) { 214 state->iobase = idev->resource.start;
173 error = -ENOMEM; 215 state->event = isa_spkr_event;
174 goto err_unregister_driver; 216 spin_lock_init(&state->lock);
175 } 217
218 dev_set_drvdata(&dev->dev, state);
176 219
177 error = platform_device_add(sparcspkr_platform_device); 220 err = sparcspkr_probe(&dev->dev);
178 if (error) 221 if (err) {
179 goto err_free_device; 222 dev_set_drvdata(&dev->dev, NULL);
223 kfree(state);
224 }
180 225
181 return 0; 226 return 0;
227}
182 228
183 err_free_device: 229static struct of_device_id isa_beep_match[] = {
184 platform_device_put(sparcspkr_platform_device); 230 {
185 err_unregister_driver: 231 .name = "dma",
186 platform_driver_unregister(&sparcspkr_platform_driver); 232 },
233 {},
234};
187 235
188 return error; 236static struct of_platform_driver isa_beep_driver = {
189} 237 .name = "beep",
238 .match_table = isa_beep_match,
239 .probe = isa_beep_probe,
240 .remove = sparcspkr_remove,
241 .shutdown = sparcspkr_shutdown,
242};
190 243
191static int __init sparcspkr_init(void) 244static int __init sparcspkr_init(void)
192{ 245{
193 struct linux_ebus *ebus; 246 int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type);
194 struct linux_ebus_device *edev; 247
195#ifdef CONFIG_SPARC64 248 if (!err) {
196 struct sparc_isa_bridge *isa_br; 249 err = of_register_driver(&isa_beep_driver, &isa_bus_type);
197 struct sparc_isa_device *isa_dev; 250 if (err)
198#endif 251 of_unregister_driver(&ebus_beep_driver);
199
200 for_each_ebus(ebus) {
201 for_each_ebusdev(edev, ebus) {
202 if (!strcmp(edev->prom_name, "beep")) {
203 beep_name = "Sparc EBUS Speaker";
204 beep_event = ebus_spkr_event;
205 beep_iobase = edev->resource[0].start;
206 return sparcspkr_drv_init();
207 }
208 }
209 }
210#ifdef CONFIG_SPARC64
211 for_each_isa(isa_br) {
212 for_each_isadev(isa_dev, isa_br) {
213 /* A hack, the beep device's base lives in
214 * the DMA isa node.
215 */
216 if (!strcmp(isa_dev->prom_name, "dma")) {
217 beep_name = "Sparc ISA Speaker";
218 beep_event = isa_spkr_event,
219 beep_iobase = isa_dev->resource.start;
220 return sparcspkr_drv_init();
221 }
222 }
223 } 252 }
224#endif
225 253
226 return -ENODEV; 254 return err;
227} 255}
228 256
229static void __exit sparcspkr_exit(void) 257static void __exit sparcspkr_exit(void)
230{ 258{
231 platform_device_unregister(sparcspkr_platform_device); 259 of_unregister_driver(&ebus_beep_driver);
232 platform_driver_unregister(&sparcspkr_platform_driver); 260 of_unregister_driver(&isa_beep_driver);
233} 261}
234 262
235module_init(sparcspkr_init); 263module_init(sparcspkr_init);
diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
index ed9446f6d7e3..6d66351805a2 100644
--- a/drivers/input/serio/i8042-sparcio.h
+++ b/drivers/input/serio/i8042-sparcio.h
@@ -74,7 +74,7 @@ static int __init i8042_platform_init(void)
74 74
75 for_each_ebus(ebus) { 75 for_each_ebus(ebus) {
76 for_each_ebusdev(edev, ebus) { 76 for_each_ebusdev(edev, ebus) {
77 if (!strcmp(edev->prom_name, "8042")) 77 if (!strcmp(edev->prom_node->name, "8042"))
78 goto edev_found; 78 goto edev_found;
79 } 79 }
80 } 80 }
@@ -82,14 +82,14 @@ static int __init i8042_platform_init(void)
82 82
83 edev_found: 83 edev_found:
84 for_each_edevchild(edev, child) { 84 for_each_edevchild(edev, child) {
85 if (!strcmp(child->prom_name, OBP_PS2KBD_NAME1) || 85 if (!strcmp(child->prom_node->name, OBP_PS2KBD_NAME1) ||
86 !strcmp(child->prom_name, OBP_PS2KBD_NAME2)) { 86 !strcmp(child->prom_node->name, OBP_PS2KBD_NAME2)) {
87 i8042_kbd_irq = child->irqs[0]; 87 i8042_kbd_irq = child->irqs[0];
88 kbd_iobase = 88 kbd_iobase =
89 ioremap(child->resource[0].start, 8); 89 ioremap(child->resource[0].start, 8);
90 } 90 }
91 if (!strcmp(child->prom_name, OBP_PS2MS_NAME1) || 91 if (!strcmp(child->prom_node->name, OBP_PS2MS_NAME1) ||
92 !strcmp(child->prom_name, OBP_PS2MS_NAME2)) 92 !strcmp(child->prom_node->name, OBP_PS2MS_NAME2))
93 i8042_aux_irq = child->irqs[0]; 93 i8042_aux_irq = child->irqs[0];
94 } 94 }
95 if (i8042_kbd_irq == -1 || 95 if (i8042_kbd_irq == -1 ||
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 6c86dca62e2a..d9f616fea3d9 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -1,10 +1,10 @@
1/* myri_sbus.h: MyriCOM MyriNET SBUS card driver. 1/* myri_sbus.c: MyriCOM MyriNET SBUS card driver.
2 * 2 *
3 * Copyright (C) 1996, 1999 David S. Miller (davem@redhat.com) 3 * Copyright (C) 1996, 1999, 2006 David S. Miller (davem@davemloft.net)
4 */ 4 */
5 5
6static char version[] = 6static char version[] =
7 "myri_sbus.c:v1.9 12/Sep/99 David S. Miller (davem@redhat.com)\n"; 7 "myri_sbus.c:v2.0 June 23, 2006 David S. Miller (davem@davemloft.net)\n";
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/config.h> 10#include <linux/config.h>
@@ -81,10 +81,6 @@ static char version[] =
81#define DHDR(x) 81#define DHDR(x)
82#endif 82#endif
83 83
84#ifdef MODULE
85static struct myri_eth *root_myri_dev;
86#endif
87
88static void myri_reset_off(void __iomem *lp, void __iomem *cregs) 84static void myri_reset_off(void __iomem *lp, void __iomem *cregs)
89{ 85{
90 /* Clear IRQ mask. */ 86 /* Clear IRQ mask. */
@@ -896,8 +892,9 @@ static void dump_eeprom(struct myri_eth *mp)
896} 892}
897#endif 893#endif
898 894
899static int __init myri_ether_init(struct sbus_dev *sdev, int num) 895static int __init myri_ether_init(struct sbus_dev *sdev)
900{ 896{
897 static int num;
901 static unsigned version_printed; 898 static unsigned version_printed;
902 struct net_device *dev; 899 struct net_device *dev;
903 struct myri_eth *mp; 900 struct myri_eth *mp;
@@ -913,6 +910,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num)
913 if (version_printed++ == 0) 910 if (version_printed++ == 0)
914 printk(version); 911 printk(version);
915 912
913 SET_MODULE_OWNER(dev);
914 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
915
916 mp = (struct myri_eth *) dev->priv; 916 mp = (struct myri_eth *) dev->priv;
917 spin_lock_init(&mp->irq_lock); 917 spin_lock_init(&mp->irq_lock);
918 mp->myri_sdev = sdev; 918 mp->myri_sdev = sdev;
@@ -1092,10 +1092,9 @@ static int __init myri_ether_init(struct sbus_dev *sdev, int num)
1092 goto err_free_irq; 1092 goto err_free_irq;
1093 } 1093 }
1094 1094
1095#ifdef MODULE 1095 dev_set_drvdata(&sdev->ofdev.dev, mp);
1096 mp->next_module = root_myri_dev; 1096
1097 root_myri_dev = mp; 1097 num++;
1098#endif
1099 1098
1100 printk("%s: MyriCOM MyriNET Ethernet ", dev->name); 1099 printk("%s: MyriCOM MyriNET Ethernet ", dev->name);
1101 1100
@@ -1114,61 +1113,68 @@ err:
1114 return -ENODEV; 1113 return -ENODEV;
1115} 1114}
1116 1115
1117static int __init myri_sbus_match(struct sbus_dev *sdev)
1118{
1119 char *name = sdev->prom_name;
1120 1116
1121 if (!strcmp(name, "MYRICOM,mlanai") || 1117static int __devinit myri_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1122 !strcmp(name, "myri")) 1118{
1123 return 1; 1119 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1124 1120
1125 return 0; 1121 return myri_ether_init(sdev);
1126} 1122}
1127 1123
1128static int __init myri_sbus_probe(void) 1124static int __devexit myri_sbus_remove(struct of_device *dev)
1129{ 1125{
1130 struct sbus_bus *bus; 1126 struct myri_eth *mp = dev_get_drvdata(&dev->dev);
1131 struct sbus_dev *sdev = NULL; 1127 struct net_device *net_dev = mp->dev;
1132 static int called;
1133 int cards = 0, v;
1134 1128
1135#ifdef MODULE 1129 unregister_netdevice(net_dev);
1136 root_myri_dev = NULL;
1137#endif
1138 1130
1139 if (called) 1131 free_irq(net_dev->irq, net_dev);
1140 return -ENODEV; 1132
1141 called++; 1133 if (mp->eeprom.cpuvers < CPUVERS_4_0) {
1142 1134 sbus_iounmap(mp->regs, mp->reg_size);
1143 for_each_sbus(bus) { 1135 } else {
1144 for_each_sbusdev(sdev, bus) { 1136 sbus_iounmap(mp->cregs, PAGE_SIZE);
1145 if (myri_sbus_match(sdev)) { 1137 sbus_iounmap(mp->lregs, (256 * 1024));
1146 cards++; 1138 sbus_iounmap(mp->lanai, (512 * 1024));
1147 DET(("Found myricom myrinet as %s\n", sdev->prom_name));
1148 if ((v = myri_ether_init(sdev, (cards - 1))))
1149 return v;
1150 }
1151 }
1152 } 1139 }
1153 if (!cards) 1140
1154 return -ENODEV; 1141 free_netdev(net_dev);
1142
1143 dev_set_drvdata(&dev->dev, NULL);
1144
1155 return 0; 1145 return 0;
1156} 1146}
1157 1147
1158static void __exit myri_sbus_cleanup(void) 1148static struct of_device_id myri_sbus_match[] = {
1149 {
1150 .name = "MYRICOM,mlanai",
1151 },
1152 {
1153 .name = "myri",
1154 },
1155 {},
1156};
1157
1158MODULE_DEVICE_TABLE(of, myri_sbus_match);
1159
1160static struct of_platform_driver myri_sbus_driver = {
1161 .name = "myri",
1162 .match_table = myri_sbus_match,
1163 .probe = myri_sbus_probe,
1164 .remove = __devexit_p(myri_sbus_remove),
1165};
1166
1167static int __init myri_sbus_init(void)
1168{
1169 return of_register_driver(&myri_sbus_driver, &sbus_bus_type);
1170}
1171
1172static void __exit myri_sbus_exit(void)
1159{ 1173{
1160#ifdef MODULE 1174 of_unregister_driver(&myri_sbus_driver);
1161 while (root_myri_dev) {
1162 struct myri_eth *next = root_myri_dev->next_module;
1163
1164 unregister_netdev(root_myri_dev->dev);
1165 /* this will also free the co-allocated 'root_myri_dev' */
1166 free_netdev(root_myri_dev->dev);
1167 root_myri_dev = next;
1168 }
1169#endif /* MODULE */
1170} 1175}
1171 1176
1172module_init(myri_sbus_probe); 1177module_init(myri_sbus_init);
1173module_exit(myri_sbus_cleanup); 1178module_exit(myri_sbus_exit);
1179
1174MODULE_LICENSE("GPL"); 1180MODULE_LICENSE("GPL");
diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
index 47722f708a41..2f69ef7cdccb 100644
--- a/drivers/net/myri_sbus.h
+++ b/drivers/net/myri_sbus.h
@@ -290,7 +290,6 @@ struct myri_eth {
290 unsigned int reg_size; /* Size of register space. */ 290 unsigned int reg_size; /* Size of register space. */
291 unsigned int shmem_base; /* Offset to shared ram. */ 291 unsigned int shmem_base; /* Offset to shared ram. */
292 struct sbus_dev *myri_sdev; /* Our SBUS device struct. */ 292 struct sbus_dev *myri_sdev; /* Our SBUS device struct. */
293 struct myri_eth *next_module; /* Next in adapter chain. */
294}; 293};
295 294
296/* We use this to acquire receive skb's that we can DMA directly into. */ 295/* We use this to acquire receive skb's that we can DMA directly into. */
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index cfaf47c63c58..7127f0f36f0e 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -72,8 +72,6 @@ MODULE_LICENSE("GPL");
72#define DIRQ(x) 72#define DIRQ(x)
73#endif 73#endif
74 74
75static struct bigmac *root_bigmac_dev;
76
77#define DEFAULT_JAMSIZE 4 /* Toe jam */ 75#define DEFAULT_JAMSIZE 4 /* Toe jam */
78 76
79#define QEC_RESET_TRIES 200 77#define QEC_RESET_TRIES 200
@@ -491,7 +489,7 @@ static void bigmac_tcvr_init(struct bigmac *bp)
491 } 489 }
492} 490}
493 491
494static int bigmac_init(struct bigmac *, int); 492static int bigmac_init_hw(struct bigmac *, int);
495 493
496static int try_next_permutation(struct bigmac *bp, void __iomem *tregs) 494static int try_next_permutation(struct bigmac *bp, void __iomem *tregs)
497{ 495{
@@ -551,7 +549,7 @@ static void bigmac_timer(unsigned long data)
551 if (ret == -1) { 549 if (ret == -1) {
552 printk(KERN_ERR "%s: Link down, cable problem?\n", 550 printk(KERN_ERR "%s: Link down, cable problem?\n",
553 bp->dev->name); 551 bp->dev->name);
554 ret = bigmac_init(bp, 0); 552 ret = bigmac_init_hw(bp, 0);
555 if (ret) { 553 if (ret) {
556 printk(KERN_ERR "%s: Error, cannot re-init the " 554 printk(KERN_ERR "%s: Error, cannot re-init the "
557 "BigMAC.\n", bp->dev->name); 555 "BigMAC.\n", bp->dev->name);
@@ -621,7 +619,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp)
621 add_timer(&bp->bigmac_timer); 619 add_timer(&bp->bigmac_timer);
622} 620}
623 621
624static int bigmac_init(struct bigmac *bp, int from_irq) 622static int bigmac_init_hw(struct bigmac *bp, int from_irq)
625{ 623{
626 void __iomem *gregs = bp->gregs; 624 void __iomem *gregs = bp->gregs;
627 void __iomem *cregs = bp->creg; 625 void __iomem *cregs = bp->creg;
@@ -752,7 +750,7 @@ static void bigmac_is_medium_rare(struct bigmac *bp, u32 qec_status, u32 bmac_st
752 } 750 }
753 751
754 printk(" RESET\n"); 752 printk(" RESET\n");
755 bigmac_init(bp, 1); 753 bigmac_init_hw(bp, 1);
756} 754}
757 755
758/* BigMAC transmit complete service routines. */ 756/* BigMAC transmit complete service routines. */
@@ -926,7 +924,7 @@ static int bigmac_open(struct net_device *dev)
926 return ret; 924 return ret;
927 } 925 }
928 init_timer(&bp->bigmac_timer); 926 init_timer(&bp->bigmac_timer);
929 ret = bigmac_init(bp, 0); 927 ret = bigmac_init_hw(bp, 0);
930 if (ret) 928 if (ret)
931 free_irq(dev->irq, bp); 929 free_irq(dev->irq, bp);
932 return ret; 930 return ret;
@@ -950,7 +948,7 @@ static void bigmac_tx_timeout(struct net_device *dev)
950{ 948{
951 struct bigmac *bp = (struct bigmac *) dev->priv; 949 struct bigmac *bp = (struct bigmac *) dev->priv;
952 950
953 bigmac_init(bp, 0); 951 bigmac_init_hw(bp, 0);
954 netif_wake_queue(dev); 952 netif_wake_queue(dev);
955} 953}
956 954
@@ -1104,6 +1102,8 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev)
1104 bp->qec_sdev = qec_sdev; 1102 bp->qec_sdev = qec_sdev;
1105 bp->bigmac_sdev = qec_sdev->child; 1103 bp->bigmac_sdev = qec_sdev->child;
1106 1104
1105 SET_NETDEV_DEV(dev, &bp->bigmac_sdev->ofdev.dev);
1106
1107 spin_lock_init(&bp->lock); 1107 spin_lock_init(&bp->lock);
1108 1108
1109 /* Verify the registers we expect, are actually there. */ 1109 /* Verify the registers we expect, are actually there. */
@@ -1226,11 +1226,7 @@ static int __init bigmac_ether_init(struct sbus_dev *qec_sdev)
1226 goto fail_and_cleanup; 1226 goto fail_and_cleanup;
1227 } 1227 }
1228 1228
1229 /* Put us into the list of instances attached for later driver 1229 dev_set_drvdata(&bp->bigmac_sdev->ofdev.dev, bp);
1230 * exit.
1231 */
1232 bp->next_module = root_bigmac_dev;
1233 root_bigmac_dev = bp;
1234 1230
1235 printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); 1231 printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name);
1236 for (i = 0; i < 6; i++) 1232 for (i = 0; i < 6; i++)
@@ -1266,69 +1262,68 @@ fail_and_cleanup:
1266/* QEC can be the parent of either QuadEthernet or 1262/* QEC can be the parent of either QuadEthernet or
1267 * a BigMAC. We want the latter. 1263 * a BigMAC. We want the latter.
1268 */ 1264 */
1269static int __init bigmac_match(struct sbus_dev *sdev) 1265static int __devinit bigmac_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1270{ 1266{
1271 struct sbus_dev *child = sdev->child; 1267 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1268 struct device_node *dp = dev->node;
1272 1269
1273 if (strcmp(sdev->prom_name, "qec") != 0) 1270 if (!strcmp(dp->name, "be"))
1274 return 0; 1271 sdev = sdev->parent;
1275 1272
1276 if (child == NULL) 1273 return bigmac_ether_init(sdev);
1277 return 0;
1278
1279 if (strcmp(child->prom_name, "be") != 0)
1280 return 0;
1281
1282 return 1;
1283} 1274}
1284 1275
1285static int __init bigmac_probe(void) 1276static int __devexit bigmac_sbus_remove(struct of_device *dev)
1286{ 1277{
1287 struct sbus_bus *sbus; 1278 struct bigmac *bp = dev_get_drvdata(&dev->dev);
1288 struct sbus_dev *sdev = NULL; 1279 struct net_device *net_dev = bp->dev;
1289 static int called; 1280
1290 int cards = 0, v; 1281 unregister_netdevice(net_dev);
1291 1282
1292 root_bigmac_dev = NULL; 1283 sbus_iounmap(bp->gregs, GLOB_REG_SIZE);
1293 1284 sbus_iounmap(bp->creg, CREG_REG_SIZE);
1294 if (called) 1285 sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
1295 return -ENODEV; 1286 sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
1296 called++; 1287 sbus_free_consistent(bp->bigmac_sdev,
1297 1288 PAGE_SIZE,
1298 for_each_sbus(sbus) { 1289 bp->bmac_block,
1299 for_each_sbusdev(sdev, sbus) { 1290 bp->bblock_dvma);
1300 if (bigmac_match(sdev)) { 1291
1301 cards++; 1292 free_netdev(net_dev);
1302 if ((v = bigmac_ether_init(sdev))) 1293
1303 return v; 1294 dev_set_drvdata(&dev->dev, NULL);
1304 } 1295
1305 }
1306 }
1307 if (!cards)
1308 return -ENODEV;
1309 return 0; 1296 return 0;
1310} 1297}
1311 1298
1312static void __exit bigmac_cleanup(void) 1299static struct of_device_id bigmac_sbus_match[] = {
1313{ 1300 {
1314 while (root_bigmac_dev) { 1301 .name = "qec",
1315 struct bigmac *bp = root_bigmac_dev; 1302 },
1316 struct bigmac *bp_nxt = root_bigmac_dev->next_module; 1303 {
1304 .name = "be",
1305 },
1306 {},
1307};
1317 1308
1318 sbus_iounmap(bp->gregs, GLOB_REG_SIZE); 1309MODULE_DEVICE_TABLE(of, bigmac_sbus_match);
1319 sbus_iounmap(bp->creg, CREG_REG_SIZE);
1320 sbus_iounmap(bp->bregs, BMAC_REG_SIZE);
1321 sbus_iounmap(bp->tregs, TCVR_REG_SIZE);
1322 sbus_free_consistent(bp->bigmac_sdev,
1323 PAGE_SIZE,
1324 bp->bmac_block,
1325 bp->bblock_dvma);
1326 1310
1327 unregister_netdev(bp->dev); 1311static struct of_platform_driver bigmac_sbus_driver = {
1328 free_netdev(bp->dev); 1312 .name = "sunbmac",
1329 root_bigmac_dev = bp_nxt; 1313 .match_table = bigmac_sbus_match,
1330 } 1314 .probe = bigmac_sbus_probe,
1315 .remove = __devexit_p(bigmac_sbus_remove),
1316};
1317
1318static int __init bigmac_init(void)
1319{
1320 return of_register_driver(&bigmac_sbus_driver, &sbus_bus_type);
1321}
1322
1323static void __exit bigmac_exit(void)
1324{
1325 of_unregister_driver(&bigmac_sbus_driver);
1331} 1326}
1332 1327
1333module_init(bigmac_probe); 1328module_init(bigmac_init);
1334module_exit(bigmac_cleanup); 1329module_exit(bigmac_exit);
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
index b0dbc5187143..b563d3c2993e 100644
--- a/drivers/net/sunbmac.h
+++ b/drivers/net/sunbmac.h
@@ -332,7 +332,6 @@ struct bigmac {
332 struct sbus_dev *qec_sdev; 332 struct sbus_dev *qec_sdev;
333 struct sbus_dev *bigmac_sdev; 333 struct sbus_dev *bigmac_sdev;
334 struct net_device *dev; 334 struct net_device *dev;
335 struct bigmac *next_module;
336}; 335};
337 336
338/* We use this to acquire receive skb's that we can DMA directly into. */ 337/* We use this to acquire receive skb's that we can DMA directly into. */
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index 38cd30cb7c75..5248670d29f7 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -2880,17 +2880,20 @@ static int __devinit gem_get_device_address(struct gem *gp)
2880#if defined(__sparc__) 2880#if defined(__sparc__)
2881 struct pci_dev *pdev = gp->pdev; 2881 struct pci_dev *pdev = gp->pdev;
2882 struct pcidev_cookie *pcp = pdev->sysdata; 2882 struct pcidev_cookie *pcp = pdev->sysdata;
2883 int node = -1; 2883 int use_idprom = 1;
2884 2884
2885 if (pcp != NULL) { 2885 if (pcp != NULL) {
2886 node = pcp->prom_node; 2886 unsigned char *addr;
2887 if (prom_getproplen(node, "local-mac-address") == 6) 2887 int len;
2888 prom_getproperty(node, "local-mac-address", 2888
2889 dev->dev_addr, 6); 2889 addr = of_get_property(pcp->prom_node, "local-mac-address",
2890 else 2890 &len);
2891 node = -1; 2891 if (addr && len == 6) {
2892 use_idprom = 0;
2893 memcpy(dev->dev_addr, addr, 6);
2894 }
2892 } 2895 }
2893 if (node == -1) 2896 if (use_idprom)
2894 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2897 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2895#elif defined(CONFIG_PPC_PMAC) 2898#elif defined(CONFIG_PPC_PMAC)
2896 unsigned char *addr; 2899 unsigned char *addr;
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index bd5d2668a362..c33ead3470db 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -1,9 +1,9 @@
1/* $Id: sunhme.c,v 1.124 2002/01/15 06:25:51 davem Exp $ 1/* sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching,
2 * sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching,
3 * auto carrier detecting ethernet driver. Also known as the 2 * auto carrier detecting ethernet driver. Also known as the
4 * "Happy Meal Ethernet" found on SunSwift SBUS cards. 3 * "Happy Meal Ethernet" found on SunSwift SBUS cards.
5 * 4 *
6 * Copyright (C) 1996, 1998, 1999, 2002, 2003 David S. Miller (davem@redhat.com) 5 * Copyright (C) 1996, 1998, 1999, 2002, 2003,
6 2006 David S. Miller (davem@davemloft.net)
7 * 7 *
8 * Changes : 8 * Changes :
9 * 2000/11/11 Willy Tarreau <willy AT meta-x.org> 9 * 2000/11/11 Willy Tarreau <willy AT meta-x.org>
@@ -40,15 +40,13 @@
40#include <asm/dma.h> 40#include <asm/dma.h>
41#include <asm/byteorder.h> 41#include <asm/byteorder.h>
42 42
43#ifdef __sparc__ 43#ifdef CONFIG_SPARC
44#include <asm/idprom.h> 44#include <asm/idprom.h>
45#include <asm/sbus.h> 45#include <asm/sbus.h>
46#include <asm/openprom.h> 46#include <asm/openprom.h>
47#include <asm/oplib.h> 47#include <asm/oplib.h>
48#include <asm/prom.h>
48#include <asm/auxio.h> 49#include <asm/auxio.h>
49#ifndef __sparc_v9__
50#include <asm/io-unit.h>
51#endif
52#endif 50#endif
53#include <asm/uaccess.h> 51#include <asm/uaccess.h>
54 52
@@ -57,7 +55,7 @@
57 55
58#ifdef CONFIG_PCI 56#ifdef CONFIG_PCI
59#include <linux/pci.h> 57#include <linux/pci.h>
60#ifdef __sparc__ 58#ifdef CONFIG_SPARC
61#include <asm/pbm.h> 59#include <asm/pbm.h>
62#endif 60#endif
63#endif 61#endif
@@ -65,9 +63,9 @@
65#include "sunhme.h" 63#include "sunhme.h"
66 64
67#define DRV_NAME "sunhme" 65#define DRV_NAME "sunhme"
68#define DRV_VERSION "2.02" 66#define DRV_VERSION "3.00"
69#define DRV_RELDATE "8/24/03" 67#define DRV_RELDATE "June 23, 2006"
70#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" 68#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
71 69
72static char version[] = 70static char version[] =
73 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; 71 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
@@ -83,8 +81,6 @@ static int macaddr[6];
83module_param_array(macaddr, int, NULL, 0); 81module_param_array(macaddr, int, NULL, 0);
84MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set"); 82MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
85 83
86static struct happy_meal *root_happy_dev;
87
88#ifdef CONFIG_SBUS 84#ifdef CONFIG_SBUS
89static struct quattro *qfe_sbus_list; 85static struct quattro *qfe_sbus_list;
90#endif 86#endif
@@ -181,26 +177,6 @@ static __inline__ void tx_dump_ring(struct happy_meal *hp)
181#define DEFAULT_IPG2 4 /* For all modes */ 177#define DEFAULT_IPG2 4 /* For all modes */
182#define DEFAULT_JAMSIZE 4 /* Toe jam */ 178#define DEFAULT_JAMSIZE 4 /* Toe jam */
183 179
184#if defined(CONFIG_PCI) && defined(MODULE)
185/* This happy_pci_ids is declared __initdata because it is only used
186 as an advisory to depmod. If this is ported to the new PCI interface
187 where it could be referenced at any time due to hot plugging,
188 the __initdata reference should be removed. */
189
190static struct pci_device_id happymeal_pci_ids[] = {
191 {
192 .vendor = PCI_VENDOR_ID_SUN,
193 .device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
194 .subvendor = PCI_ANY_ID,
195 .subdevice = PCI_ANY_ID,
196 },
197 { } /* Terminating entry */
198};
199
200MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
201
202#endif
203
204/* NOTE: In the descriptor writes one _must_ write the address 180/* NOTE: In the descriptor writes one _must_ write the address
205 * member _first_. The card must not be allowed to see 181 * member _first_. The card must not be allowed to see
206 * the updated descriptor flags until the address is 182 * the updated descriptor flags until the address is
@@ -1610,7 +1586,7 @@ static int happy_meal_init(struct happy_meal *hp)
1610 HMD(("happy_meal_init: old[%08x] bursts<", 1586 HMD(("happy_meal_init: old[%08x] bursts<",
1611 hme_read32(hp, gregs + GREG_CFG))); 1587 hme_read32(hp, gregs + GREG_CFG)));
1612 1588
1613#ifndef __sparc__ 1589#ifndef CONFIG_SPARC
1614 /* It is always PCI and can handle 64byte bursts. */ 1590 /* It is always PCI and can handle 64byte bursts. */
1615 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64); 1591 hme_write32(hp, gregs + GREG_CFG, GREG_CFG_BURST64);
1616#else 1592#else
@@ -1647,7 +1623,7 @@ static int happy_meal_init(struct happy_meal *hp)
1647 HMD(("XXX>")); 1623 HMD(("XXX>"));
1648 hme_write32(hp, gregs + GREG_CFG, 0); 1624 hme_write32(hp, gregs + GREG_CFG, 0);
1649 } 1625 }
1650#endif /* __sparc__ */ 1626#endif /* CONFIG_SPARC */
1651 1627
1652 /* Turn off interrupts we do not want to hear. */ 1628 /* Turn off interrupts we do not want to hear. */
1653 HMD((", enable global interrupts, ")); 1629 HMD((", enable global interrupts, "));
@@ -2592,14 +2568,10 @@ static void __init quattro_apply_ranges(struct quattro *qp, struct happy_meal *h
2592 */ 2568 */
2593static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev) 2569static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev)
2594{ 2570{
2595 struct sbus_bus *sbus;
2596 struct sbus_dev *sdev; 2571 struct sbus_dev *sdev;
2597 struct quattro *qp; 2572 struct quattro *qp;
2598 int i; 2573 int i;
2599 2574
2600 if (qfe_sbus_list == NULL)
2601 goto found;
2602
2603 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) { 2575 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2604 for (i = 0, sdev = qp->quattro_dev; 2576 for (i = 0, sdev = qp->quattro_dev;
2605 (sdev != NULL) && (i < 4); 2577 (sdev != NULL) && (i < 4);
@@ -2608,17 +2580,7 @@ static struct quattro * __init quattro_sbus_find(struct sbus_dev *goal_sdev)
2608 return qp; 2580 return qp;
2609 } 2581 }
2610 } 2582 }
2611 for_each_sbus(sbus) {
2612 for_each_sbusdev(sdev, sbus) {
2613 if (sdev == goal_sdev)
2614 goto found;
2615 }
2616 }
2617
2618 /* Cannot find quattro parent, fail. */
2619 return NULL;
2620 2583
2621found:
2622 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); 2584 qp = kmalloc(sizeof(struct quattro), GFP_KERNEL);
2623 if (qp != NULL) { 2585 if (qp != NULL) {
2624 int i; 2586 int i;
@@ -2655,6 +2617,17 @@ static void __init quattro_sbus_register_irqs(void)
2655 } 2617 }
2656 } 2618 }
2657} 2619}
2620
2621static void __devexit quattro_sbus_free_irqs(void)
2622{
2623 struct quattro *qp;
2624
2625 for (qp = qfe_sbus_list; qp != NULL; qp = qp->next) {
2626 struct sbus_dev *sdev = qp->quattro_dev;
2627
2628 free_irq(sdev->irqs[0], qp);
2629 }
2630}
2658#endif /* CONFIG_SBUS */ 2631#endif /* CONFIG_SBUS */
2659 2632
2660#ifdef CONFIG_PCI 2633#ifdef CONFIG_PCI
@@ -2689,8 +2662,9 @@ static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
2689#endif /* CONFIG_PCI */ 2662#endif /* CONFIG_PCI */
2690 2663
2691#ifdef CONFIG_SBUS 2664#ifdef CONFIG_SBUS
2692static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) 2665static int __init happy_meal_sbus_probe_one(struct sbus_dev *sdev, int is_qfe)
2693{ 2666{
2667 struct device_node *dp = sdev->ofdev.node;
2694 struct quattro *qp = NULL; 2668 struct quattro *qp = NULL;
2695 struct happy_meal *hp; 2669 struct happy_meal *hp;
2696 struct net_device *dev; 2670 struct net_device *dev;
@@ -2713,6 +2687,7 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2713 if (!dev) 2687 if (!dev)
2714 goto err_out; 2688 goto err_out;
2715 SET_MODULE_OWNER(dev); 2689 SET_MODULE_OWNER(dev);
2690 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
2716 2691
2717 if (hme_version_printed++ == 0) 2692 if (hme_version_printed++ == 0)
2718 printk(KERN_INFO "%s", version); 2693 printk(KERN_INFO "%s", version);
@@ -2728,13 +2703,16 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2728 for (i = 0; i < 6; i++) 2703 for (i = 0; i < 6; i++)
2729 dev->dev_addr[i] = macaddr[i]; 2704 dev->dev_addr[i] = macaddr[i];
2730 macaddr[5]++; 2705 macaddr[5]++;
2731 } else if (qfe_slot != -1 &&
2732 prom_getproplen(sdev->prom_node,
2733 "local-mac-address") == 6) {
2734 prom_getproperty(sdev->prom_node, "local-mac-address",
2735 dev->dev_addr, 6);
2736 } else { 2706 } else {
2737 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 2707 unsigned char *addr;
2708 int len;
2709
2710 addr = of_get_property(dp, "local-mac-address", &len);
2711
2712 if (qfe_slot != -1 && addr && len == 6)
2713 memcpy(dev->dev_addr, addr, 6);
2714 else
2715 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
2738 } 2716 }
2739 2717
2740 hp = dev->priv; 2718 hp = dev->priv;
@@ -2745,9 +2723,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2745 2723
2746 err = -ENODEV; 2724 err = -ENODEV;
2747 if (sdev->num_registers != 5) { 2725 if (sdev->num_registers != 5) {
2748 printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", 2726 printk(KERN_ERR "happymeal: Device needs 5 regs, has %d.\n",
2749 sdev->num_registers); 2727 sdev->num_registers);
2750 printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
2751 goto err_out_free_netdev; 2728 goto err_out_free_netdev;
2752 } 2729 }
2753 2730
@@ -2761,39 +2738,39 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2761 hp->gregs = sbus_ioremap(&sdev->resource[0], 0, 2738 hp->gregs = sbus_ioremap(&sdev->resource[0], 0,
2762 GREG_REG_SIZE, "HME Global Regs"); 2739 GREG_REG_SIZE, "HME Global Regs");
2763 if (!hp->gregs) { 2740 if (!hp->gregs) {
2764 printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); 2741 printk(KERN_ERR "happymeal: Cannot map global registers.\n");
2765 goto err_out_free_netdev; 2742 goto err_out_free_netdev;
2766 } 2743 }
2767 2744
2768 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, 2745 hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
2769 ETX_REG_SIZE, "HME TX Regs"); 2746 ETX_REG_SIZE, "HME TX Regs");
2770 if (!hp->etxregs) { 2747 if (!hp->etxregs) {
2771 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); 2748 printk(KERN_ERR "happymeal: Cannot map MAC TX registers.\n");
2772 goto err_out_iounmap; 2749 goto err_out_iounmap;
2773 } 2750 }
2774 2751
2775 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, 2752 hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
2776 ERX_REG_SIZE, "HME RX Regs"); 2753 ERX_REG_SIZE, "HME RX Regs");
2777 if (!hp->erxregs) { 2754 if (!hp->erxregs) {
2778 printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); 2755 printk(KERN_ERR "happymeal: Cannot map MAC RX registers.\n");
2779 goto err_out_iounmap; 2756 goto err_out_iounmap;
2780 } 2757 }
2781 2758
2782 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, 2759 hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
2783 BMAC_REG_SIZE, "HME BIGMAC Regs"); 2760 BMAC_REG_SIZE, "HME BIGMAC Regs");
2784 if (!hp->bigmacregs) { 2761 if (!hp->bigmacregs) {
2785 printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); 2762 printk(KERN_ERR "happymeal: Cannot map BIGMAC registers.\n");
2786 goto err_out_iounmap; 2763 goto err_out_iounmap;
2787 } 2764 }
2788 2765
2789 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, 2766 hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
2790 TCVR_REG_SIZE, "HME Tranceiver Regs"); 2767 TCVR_REG_SIZE, "HME Tranceiver Regs");
2791 if (!hp->tcvregs) { 2768 if (!hp->tcvregs) {
2792 printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); 2769 printk(KERN_ERR "happymeal: Cannot map TCVR registers.\n");
2793 goto err_out_iounmap; 2770 goto err_out_iounmap;
2794 } 2771 }
2795 2772
2796 hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); 2773 hp->hm_revision = of_getintprop_default(dp, "hm-rev", 0xff);
2797 if (hp->hm_revision == 0xff) 2774 if (hp->hm_revision == 0xff)
2798 hp->hm_revision = 0xa0; 2775 hp->hm_revision = 0xa0;
2799 2776
@@ -2807,8 +2784,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2807 hp->happy_flags |= HFLAG_QUATTRO; 2784 hp->happy_flags |= HFLAG_QUATTRO;
2808 2785
2809 /* Get the supported DVMA burst sizes from our Happy SBUS. */ 2786 /* Get the supported DVMA burst sizes from our Happy SBUS. */
2810 hp->happy_bursts = prom_getintdefault(sdev->bus->prom_node, 2787 hp->happy_bursts = of_getintprop_default(sdev->bus->ofdev.node,
2811 "burst-sizes", 0x00); 2788 "burst-sizes", 0x00);
2812 2789
2813 hp->happy_block = sbus_alloc_consistent(hp->happy_dev, 2790 hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
2814 PAGE_SIZE, 2791 PAGE_SIZE,
@@ -2871,6 +2848,8 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2871 goto err_out_free_consistent; 2848 goto err_out_free_consistent;
2872 } 2849 }
2873 2850
2851 dev_set_drvdata(&sdev->ofdev.dev, hp);
2852
2874 if (qfe_slot != -1) 2853 if (qfe_slot != -1)
2875 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ", 2854 printk(KERN_INFO "%s: Quattro HME slot %d (SBUS) 10/100baseT Ethernet ",
2876 dev->name, qfe_slot); 2855 dev->name, qfe_slot);
@@ -2883,12 +2862,6 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
2883 dev->dev_addr[i], i == 5 ? ' ' : ':'); 2862 dev->dev_addr[i], i == 5 ? ' ' : ':');
2884 printk("\n"); 2863 printk("\n");
2885 2864
2886 /* We are home free at this point, link us in to the happy
2887 * device list.
2888 */
2889 hp->next_module = root_happy_dev;
2890 root_happy_dev = hp;
2891
2892 return 0; 2865 return 0;
2893 2866
2894err_out_free_consistent: 2867err_out_free_consistent:
@@ -2918,7 +2891,7 @@ err_out:
2918#endif 2891#endif
2919 2892
2920#ifdef CONFIG_PCI 2893#ifdef CONFIG_PCI
2921#ifndef __sparc__ 2894#ifndef CONFIG_SPARC
2922static int is_quattro_p(struct pci_dev *pdev) 2895static int is_quattro_p(struct pci_dev *pdev)
2923{ 2896{
2924 struct pci_dev *busdev = pdev->bus->self; 2897 struct pci_dev *busdev = pdev->bus->self;
@@ -3006,14 +2979,14 @@ static void get_hme_mac_nonsparc(struct pci_dev *pdev, unsigned char *dev_addr)
3006 get_random_bytes(&dev_addr[3], 3); 2979 get_random_bytes(&dev_addr[3], 3);
3007 return; 2980 return;
3008} 2981}
3009#endif /* !(__sparc__) */ 2982#endif /* !(CONFIG_SPARC) */
3010 2983
3011static int __init happy_meal_pci_init(struct pci_dev *pdev) 2984static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
2985 const struct pci_device_id *ent)
3012{ 2986{
3013 struct quattro *qp = NULL; 2987 struct quattro *qp = NULL;
3014#ifdef __sparc__ 2988#ifdef CONFIG_SPARC
3015 struct pcidev_cookie *pcp; 2989 struct pcidev_cookie *pcp;
3016 int node;
3017#endif 2990#endif
3018 struct happy_meal *hp; 2991 struct happy_meal *hp;
3019 struct net_device *dev; 2992 struct net_device *dev;
@@ -3024,15 +2997,14 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3024 int err; 2997 int err;
3025 2998
3026 /* Now make sure pci_dev cookie is there. */ 2999 /* Now make sure pci_dev cookie is there. */
3027#ifdef __sparc__ 3000#ifdef CONFIG_SPARC
3028 pcp = pdev->sysdata; 3001 pcp = pdev->sysdata;
3029 if (pcp == NULL || pcp->prom_node == -1) { 3002 if (pcp == NULL) {
3030 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n"); 3003 printk(KERN_ERR "happymeal(PCI): Some PCI device info missing\n");
3031 return -ENODEV; 3004 return -ENODEV;
3032 } 3005 }
3033 node = pcp->prom_node;
3034 3006
3035 prom_getstring(node, "name", prom_name, sizeof(prom_name)); 3007 strcpy(prom_name, pcp->prom_node->name);
3036#else 3008#else
3037 if (is_quattro_p(pdev)) 3009 if (is_quattro_p(pdev))
3038 strcpy(prom_name, "SUNW,qfe"); 3010 strcpy(prom_name, "SUNW,qfe");
@@ -3103,11 +3075,15 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3103 dev->dev_addr[i] = macaddr[i]; 3075 dev->dev_addr[i] = macaddr[i];
3104 macaddr[5]++; 3076 macaddr[5]++;
3105 } else { 3077 } else {
3106#ifdef __sparc__ 3078#ifdef CONFIG_SPARC
3079 unsigned char *addr;
3080 int len;
3081
3107 if (qfe_slot != -1 && 3082 if (qfe_slot != -1 &&
3108 prom_getproplen(node, "local-mac-address") == 6) { 3083 (addr = of_get_property(pcp->prom_node,
3109 prom_getproperty(node, "local-mac-address", 3084 "local-mac-address", &len)) != NULL
3110 dev->dev_addr, 6); 3085 && len == 6) {
3086 memcpy(dev->dev_addr, addr, 6);
3111 } else { 3087 } else {
3112 memcpy(dev->dev_addr, idprom->id_ethaddr, 6); 3088 memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
3113 } 3089 }
@@ -3123,8 +3099,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3123 hp->bigmacregs = (hpreg_base + 0x6000UL); 3099 hp->bigmacregs = (hpreg_base + 0x6000UL);
3124 hp->tcvregs = (hpreg_base + 0x7000UL); 3100 hp->tcvregs = (hpreg_base + 0x7000UL);
3125 3101
3126#ifdef __sparc__ 3102#ifdef CONFIG_SPARC
3127 hp->hm_revision = prom_getintdefault(node, "hm-rev", 0xff); 3103 hp->hm_revision = of_getintprop_default(pcp->prom_node, "hm-rev", 0xff);
3128 if (hp->hm_revision == 0xff) { 3104 if (hp->hm_revision == 0xff) {
3129 unsigned char prev; 3105 unsigned char prev;
3130 3106
@@ -3148,7 +3124,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3148 /* And of course, indicate this is PCI. */ 3124 /* And of course, indicate this is PCI. */
3149 hp->happy_flags |= HFLAG_PCI; 3125 hp->happy_flags |= HFLAG_PCI;
3150 3126
3151#ifdef __sparc__ 3127#ifdef CONFIG_SPARC
3152 /* Assume PCI happy meals can handle all burst sizes. */ 3128 /* Assume PCI happy meals can handle all burst sizes. */
3153 hp->happy_bursts = DMA_BURSTBITS; 3129 hp->happy_bursts = DMA_BURSTBITS;
3154#endif 3130#endif
@@ -3211,6 +3187,8 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3211 goto err_out_iounmap; 3187 goto err_out_iounmap;
3212 } 3188 }
3213 3189
3190 dev_set_drvdata(&pdev->dev, hp);
3191
3214 if (!qfe_slot) { 3192 if (!qfe_slot) {
3215 struct pci_dev *qpdev = qp->quattro_dev; 3193 struct pci_dev *qpdev = qp->quattro_dev;
3216 3194
@@ -3240,12 +3218,6 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
3240 3218
3241 printk("\n"); 3219 printk("\n");
3242 3220
3243 /* We are home free at this point, link us in to the happy
3244 * device list.
3245 */
3246 hp->next_module = root_happy_dev;
3247 root_happy_dev = hp;
3248
3249 return 0; 3221 return 0;
3250 3222
3251err_out_iounmap: 3223err_out_iounmap:
@@ -3263,136 +3235,146 @@ err_out_clear_quattro:
3263err_out: 3235err_out:
3264 return err; 3236 return err;
3265} 3237}
3266#endif
3267 3238
3268#ifdef CONFIG_SBUS 3239static void __devexit happy_meal_pci_remove(struct pci_dev *pdev)
3269static int __init happy_meal_sbus_probe(void)
3270{ 3240{
3271 struct sbus_bus *sbus; 3241 struct happy_meal *hp = dev_get_drvdata(&pdev->dev);
3272 struct sbus_dev *sdev; 3242 struct net_device *net_dev = hp->dev;
3273 int cards = 0; 3243
3274 char model[128]; 3244 unregister_netdev(net_dev);
3275 3245
3276 for_each_sbus(sbus) { 3246 pci_free_consistent(hp->happy_dev,
3277 for_each_sbusdev(sdev, sbus) { 3247 PAGE_SIZE,
3278 char *name = sdev->prom_name; 3248 hp->happy_block,
3279 3249 hp->hblock_dvma);
3280 if (!strcmp(name, "SUNW,hme")) { 3250 iounmap(hp->gregs);
3281 cards++; 3251 pci_release_regions(hp->happy_dev);
3282 prom_getstring(sdev->prom_node, "model", 3252
3283 model, sizeof(model)); 3253 free_netdev(net_dev);
3284 if (!strcmp(model, "SUNW,sbus-qfe")) 3254
3285 happy_meal_sbus_init(sdev, 1); 3255 dev_set_drvdata(&pdev->dev, NULL);
3286 else
3287 happy_meal_sbus_init(sdev, 0);
3288 } else if (!strcmp(name, "qfe") ||
3289 !strcmp(name, "SUNW,qfe")) {
3290 cards++;
3291 happy_meal_sbus_init(sdev, 1);
3292 }
3293 }
3294 }
3295 if (cards != 0)
3296 quattro_sbus_register_irqs();
3297 return cards;
3298} 3256}
3299#endif
3300 3257
3301#ifdef CONFIG_PCI 3258static struct pci_device_id happymeal_pci_ids[] = {
3302static int __init happy_meal_pci_probe(void) 3259 {
3260 .vendor = PCI_VENDOR_ID_SUN,
3261 .device = PCI_DEVICE_ID_SUN_HAPPYMEAL,
3262 .subvendor = PCI_ANY_ID,
3263 .subdevice = PCI_ANY_ID,
3264 },
3265 { } /* Terminating entry */
3266};
3267
3268MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
3269
3270static struct pci_driver hme_pci_driver = {
3271 .name = "hme",
3272 .id_table = happymeal_pci_ids,
3273 .probe = happy_meal_pci_probe,
3274 .remove = __devexit_p(happy_meal_pci_remove),
3275};
3276
3277static int __init happy_meal_pci_init(void)
3303{ 3278{
3304 struct pci_dev *pdev = NULL; 3279 return pci_module_init(&hme_pci_driver);
3305 int cards = 0; 3280}
3306 3281
3307 while ((pdev = pci_find_device(PCI_VENDOR_ID_SUN, 3282static void happy_meal_pci_exit(void)
3308 PCI_DEVICE_ID_SUN_HAPPYMEAL, pdev)) != NULL) { 3283{
3309 if (pci_enable_device(pdev)) 3284 pci_unregister_driver(&hme_pci_driver);
3310 continue; 3285
3311 pci_set_master(pdev); 3286 while (qfe_pci_list) {
3312 cards++; 3287 struct quattro *qfe = qfe_pci_list;
3313 happy_meal_pci_init(pdev); 3288 struct quattro *next = qfe->next;
3289
3290 kfree(qfe);
3291
3292 qfe_pci_list = next;
3314 } 3293 }
3315 return cards;
3316} 3294}
3295
3317#endif 3296#endif
3318 3297
3319static int __init happy_meal_probe(void) 3298#ifdef CONFIG_SBUS
3299static int __devinit hme_sbus_probe(struct of_device *dev, const struct of_device_id *match)
3320{ 3300{
3321 static int called = 0; 3301 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
3322 int cards; 3302 struct device_node *dp = dev->node;
3303 char *model = of_get_property(dp, "model", NULL);
3304 int is_qfe = (match->data != NULL);
3323 3305
3324 root_happy_dev = NULL; 3306 if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe"))
3307 is_qfe = 1;
3325 3308
3326 if (called) 3309 return happy_meal_sbus_probe_one(sdev, is_qfe);
3327 return -ENODEV; 3310}
3328 called++; 3311
3312static int __devexit hme_sbus_remove(struct of_device *dev)
3313{
3314 struct happy_meal *hp = dev_get_drvdata(&dev->dev);
3315 struct net_device *net_dev = hp->dev;
3316
3317 unregister_netdevice(net_dev);
3318
3319 /* XXX qfe parent interrupt... */
3320
3321 sbus_iounmap(hp->gregs, GREG_REG_SIZE);
3322 sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
3323 sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
3324 sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
3325 sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
3326 sbus_free_consistent(hp->happy_dev,
3327 PAGE_SIZE,
3328 hp->happy_block,
3329 hp->hblock_dvma);
3330
3331 free_netdev(net_dev);
3332
3333 dev_set_drvdata(&dev->dev, NULL);
3329 3334
3330 cards = 0;
3331#ifdef CONFIG_SBUS
3332 cards += happy_meal_sbus_probe();
3333#endif
3334#ifdef CONFIG_PCI
3335 cards += happy_meal_pci_probe();
3336#endif
3337 if (!cards)
3338 return -ENODEV;
3339 return 0; 3335 return 0;
3340} 3336}
3341 3337
3338static struct of_device_id hme_sbus_match[] = {
3339 {
3340 .name = "SUNW,hme",
3341 },
3342 {
3343 .name = "SUNW,qfe",
3344 .data = (void *) 1,
3345 },
3346 {
3347 .name = "qfe",
3348 .data = (void *) 1,
3349 },
3350 {},
3351};
3342 3352
3343static void __exit happy_meal_cleanup_module(void) 3353MODULE_DEVICE_TABLE(of, hme_sbus_match);
3344{
3345#ifdef CONFIG_SBUS
3346 struct quattro *last_seen_qfe = NULL;
3347#endif
3348 3354
3349 while (root_happy_dev) { 3355static struct of_platform_driver hme_sbus_driver = {
3350 struct happy_meal *hp = root_happy_dev; 3356 .name = "hme",
3351 struct happy_meal *next = root_happy_dev->next_module; 3357 .match_table = hme_sbus_match,
3352 struct net_device *dev = hp->dev; 3358 .probe = hme_sbus_probe,
3359 .remove = __devexit_p(hme_sbus_remove),
3360};
3353 3361
3354 /* Unregister netdev before unmapping registers as this 3362static int __init happy_meal_sbus_init(void)
3355 * call can end up trying to access those registers. 3363{
3356 */ 3364 int err;
3357 unregister_netdev(dev);
3358 3365
3359#ifdef CONFIG_SBUS 3366 err = of_register_driver(&hme_sbus_driver, &sbus_bus_type);
3360 if (!(hp->happy_flags & HFLAG_PCI)) { 3367 if (!err)
3361 if (hp->happy_flags & HFLAG_QUATTRO) { 3368 quattro_sbus_register_irqs();
3362 if (hp->qfe_parent != last_seen_qfe) {
3363 free_irq(dev->irq, hp->qfe_parent);
3364 last_seen_qfe = hp->qfe_parent;
3365 }
3366 }
3367 3369
3368 sbus_iounmap(hp->gregs, GREG_REG_SIZE); 3370 return err;
3369 sbus_iounmap(hp->etxregs, ETX_REG_SIZE); 3371}
3370 sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
3371 sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
3372 sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
3373 sbus_free_consistent(hp->happy_dev,
3374 PAGE_SIZE,
3375 hp->happy_block,
3376 hp->hblock_dvma);
3377 }
3378#endif
3379#ifdef CONFIG_PCI
3380 if ((hp->happy_flags & HFLAG_PCI)) {
3381 pci_free_consistent(hp->happy_dev,
3382 PAGE_SIZE,
3383 hp->happy_block,
3384 hp->hblock_dvma);
3385 iounmap(hp->gregs);
3386 pci_release_regions(hp->happy_dev);
3387 }
3388#endif
3389 free_netdev(dev);
3390 3372
3391 root_happy_dev = next; 3373static void happy_meal_sbus_exit(void)
3392 } 3374{
3375 of_unregister_driver(&hme_sbus_driver);
3376 quattro_sbus_free_irqs();
3393 3377
3394 /* Now cleanup the quattro lists. */
3395#ifdef CONFIG_SBUS
3396 while (qfe_sbus_list) { 3378 while (qfe_sbus_list) {
3397 struct quattro *qfe = qfe_sbus_list; 3379 struct quattro *qfe = qfe_sbus_list;
3398 struct quattro *next = qfe->next; 3380 struct quattro *next = qfe->next;
@@ -3401,18 +3383,39 @@ static void __exit happy_meal_cleanup_module(void)
3401 3383
3402 qfe_sbus_list = next; 3384 qfe_sbus_list = next;
3403 } 3385 }
3386}
3404#endif 3387#endif
3405#ifdef CONFIG_PCI
3406 while (qfe_pci_list) {
3407 struct quattro *qfe = qfe_pci_list;
3408 struct quattro *next = qfe->next;
3409 3388
3410 kfree(qfe); 3389static int __init happy_meal_probe(void)
3390{
3391 int err = 0;
3411 3392
3412 qfe_pci_list = next; 3393#ifdef CONFIG_SBUS
3394 err = happy_meal_sbus_init();
3395#endif
3396#ifdef CONFIG_PCI
3397 if (!err) {
3398 err = happy_meal_pci_init();
3399#ifdef CONFIG_SBUS
3400 if (err)
3401 happy_meal_sbus_exit();
3402#endif
3413 } 3403 }
3414#endif 3404#endif
3405
3406 return err;
3407}
3408
3409
3410static void __exit happy_meal_exit(void)
3411{
3412#ifdef CONFIG_SBUS
3413 happy_meal_sbus_exit();
3414#endif
3415#ifdef CONFIG_PCI
3416 happy_meal_pci_exit();
3417#endif
3415} 3418}
3416 3419
3417module_init(happy_meal_probe); 3420module_init(happy_meal_probe);
3418module_exit(happy_meal_cleanup_module); 3421module_exit(happy_meal_exit);
diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h
index 34e9f953cea4..9b7ccaeeee89 100644
--- a/drivers/net/sunhme.h
+++ b/drivers/net/sunhme.h
@@ -461,7 +461,6 @@ struct happy_meal {
461 struct net_device *dev; /* Backpointer */ 461 struct net_device *dev; /* Backpointer */
462 struct quattro *qfe_parent; /* For Quattro cards */ 462 struct quattro *qfe_parent; /* For Quattro cards */
463 int qfe_ent; /* Which instance on quattro */ 463 int qfe_ent; /* Which instance on quattro */
464 struct happy_meal *next_module;
465}; 464};
466 465
467/* Here are the happy flags. */ 466/* Here are the happy flags. */
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 6381243d8d00..2c239ab63a80 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -266,7 +266,6 @@ struct lance_private {
266 char *name; 266 char *name;
267 dma_addr_t init_block_dvma; 267 dma_addr_t init_block_dvma;
268 struct net_device *dev; /* Backpointer */ 268 struct net_device *dev; /* Backpointer */
269 struct lance_private *next_module;
270 struct sbus_dev *sdev; 269 struct sbus_dev *sdev;
271 struct timer_list multicast_timer; 270 struct timer_list multicast_timer;
272}; 271};
@@ -298,8 +297,6 @@ int sparc_lance_debug = 2;
298 297
299#define LANCE_ADDR(x) ((long)(x) & ~0xff000000) 298#define LANCE_ADDR(x) ((long)(x) & ~0xff000000)
300 299
301static struct lance_private *root_lance_dev;
302
303/* Load the CSR registers */ 300/* Load the CSR registers */
304static void load_csrs(struct lance_private *lp) 301static void load_csrs(struct lance_private *lp)
305{ 302{
@@ -1327,9 +1324,9 @@ static struct ethtool_ops sparc_lance_ethtool_ops = {
1327 .get_link = sparc_lance_get_link, 1324 .get_link = sparc_lance_get_link,
1328}; 1325};
1329 1326
1330static int __init sparc_lance_init(struct sbus_dev *sdev, 1327static int __init sparc_lance_probe_one(struct sbus_dev *sdev,
1331 struct sbus_dma *ledma, 1328 struct sbus_dma *ledma,
1332 struct sbus_dev *lebuffer) 1329 struct sbus_dev *lebuffer)
1333{ 1330{
1334 static unsigned version_printed; 1331 static unsigned version_printed;
1335 struct net_device *dev; 1332 struct net_device *dev;
@@ -1473,6 +1470,7 @@ no_link_test:
1473 1470
1474 lp->dev = dev; 1471 lp->dev = dev;
1475 SET_MODULE_OWNER(dev); 1472 SET_MODULE_OWNER(dev);
1473 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
1476 dev->open = &lance_open; 1474 dev->open = &lance_open;
1477 dev->stop = &lance_close; 1475 dev->stop = &lance_close;
1478 dev->hard_start_xmit = &lance_start_xmit; 1476 dev->hard_start_xmit = &lance_start_xmit;
@@ -1500,8 +1498,7 @@ no_link_test:
1500 goto fail; 1498 goto fail;
1501 } 1499 }
1502 1500
1503 lp->next_module = root_lance_dev; 1501 dev_set_drvdata(&sdev->ofdev.dev, lp);
1504 root_lance_dev = lp;
1505 1502
1506 printk(KERN_INFO "%s: LANCE ", dev->name); 1503 printk(KERN_INFO "%s: LANCE ", dev->name);
1507 1504
@@ -1536,88 +1533,112 @@ static inline struct sbus_dma *find_ledma(struct sbus_dev *sdev)
1536#include <asm/machines.h> 1533#include <asm/machines.h>
1537 1534
1538/* Find all the lance cards on the system and initialize them */ 1535/* Find all the lance cards on the system and initialize them */
1539static int __init sparc_lance_probe(void) 1536static struct sbus_dev sun4_sdev;
1537static int __init sparc_lance_init(void)
1540{ 1538{
1541 static struct sbus_dev sdev;
1542 static int called;
1543
1544 root_lance_dev = NULL;
1545
1546 if (called)
1547 return -ENODEV;
1548 called++;
1549
1550 if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || 1539 if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) ||
1551 (idprom->id_machtype == (SM_SUN4|SM_4_470))) { 1540 (idprom->id_machtype == (SM_SUN4|SM_4_470))) {
1552 memset(&sdev, 0, sizeof(sdev)); 1541 memset(&sun4_sdev, 0, sizeof(sdev));
1553 sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; 1542 sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr;
1554 sdev.irqs[0] = 6; 1543 sun4_sdev.irqs[0] = 6;
1555 return sparc_lance_init(&sdev, NULL, NULL); 1544 return sparc_lance_probe_one(&sun4_sdev, NULL, NULL);
1556 } 1545 }
1557 return -ENODEV; 1546 return -ENODEV;
1558} 1547}
1559 1548
1560#else /* !CONFIG_SUN4 */ 1549static int __exit sunlance_sun4_remove(void)
1561
1562/* Find all the lance cards on the system and initialize them */
1563static int __init sparc_lance_probe(void)
1564{ 1550{
1565 struct sbus_bus *bus; 1551 struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev);
1566 struct sbus_dev *sdev = NULL; 1552 struct net_device *net_dev = lp->dev;
1567 struct sbus_dma *ledma = NULL; 1553
1568 static int called; 1554 unregister_netdevice(net_dev);
1569 int cards = 0, v; 1555
1570 1556 lance_free_hwresources(root_lance_dev);
1571 root_lance_dev = NULL; 1557
1572 1558 free_netdev(net_dev);
1573 if (called) 1559
1574 return -ENODEV; 1560 dev_set_drvdata(&sun4_sdev->dev, NULL);
1575 called++; 1561
1576
1577 for_each_sbus (bus) {
1578 for_each_sbusdev (sdev, bus) {
1579 if (strcmp(sdev->prom_name, "le") == 0) {
1580 cards++;
1581 if ((v = sparc_lance_init(sdev, NULL, NULL)))
1582 return v;
1583 continue;
1584 }
1585 if (strcmp(sdev->prom_name, "ledma") == 0) {
1586 cards++;
1587 ledma = find_ledma(sdev);
1588 if ((v = sparc_lance_init(sdev->child,
1589 ledma, NULL)))
1590 return v;
1591 continue;
1592 }
1593 if (strcmp(sdev->prom_name, "lebuffer") == 0){
1594 cards++;
1595 if ((v = sparc_lance_init(sdev->child,
1596 NULL, sdev)))
1597 return v;
1598 continue;
1599 }
1600 } /* for each sbusdev */
1601 } /* for each sbus */
1602 if (!cards)
1603 return -ENODEV;
1604 return 0; 1562 return 0;
1605} 1563}
1606#endif /* !CONFIG_SUN4 */
1607 1564
1608static void __exit sparc_lance_cleanup(void) 1565#else /* !CONFIG_SUN4 */
1566
1567static int __devinit sunlance_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1609{ 1568{
1610 struct lance_private *lp; 1569 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1570 struct device_node *dp = dev->node;
1571 int err;
1572
1573 if (!strcmp(dp->name, "le")) {
1574 err = sparc_lance_probe_one(sdev, NULL, NULL);
1575 } else if (!strcmp(dp->name, "ledma")) {
1576 struct sbus_dma *ledma = find_ledma(sdev);
1611 1577
1612 while (root_lance_dev) { 1578 err = sparc_lance_probe_one(sdev->child, ledma, NULL);
1613 lp = root_lance_dev->next_module; 1579 } else {
1580 BUG_ON(strcmp(dp->name, "lebuffer"));
1614 1581
1615 unregister_netdev(root_lance_dev->dev); 1582 err = sparc_lance_probe_one(sdev->child, NULL, sdev);
1616 lance_free_hwresources(root_lance_dev);
1617 free_netdev(root_lance_dev->dev);
1618 root_lance_dev = lp;
1619 } 1583 }
1584
1585 return err;
1586}
1587
1588static int __devexit sunlance_sbus_remove(struct of_device *dev)
1589{
1590 struct lance_private *lp = dev_get_drvdata(&dev->dev);
1591 struct net_device *net_dev = lp->dev;
1592
1593 unregister_netdevice(net_dev);
1594
1595 lance_free_hwresources(lp);
1596
1597 free_netdev(net_dev);
1598
1599 dev_set_drvdata(&dev->dev, NULL);
1600
1601 return 0;
1602}
1603
1604static struct of_device_id sunlance_sbus_match[] = {
1605 {
1606 .name = "le",
1607 },
1608 {
1609 .name = "ledma",
1610 },
1611 {
1612 .name = "lebuffer",
1613 },
1614 {},
1615};
1616
1617MODULE_DEVICE_TABLE(of, sunlance_sbus_match);
1618
1619static struct of_platform_driver sunlance_sbus_driver = {
1620 .name = "sunlance",
1621 .match_table = sunlance_sbus_match,
1622 .probe = sunlance_sbus_probe,
1623 .remove = __devexit_p(sunlance_sbus_remove),
1624};
1625
1626
1627/* Find all the lance cards on the system and initialize them */
1628static int __init sparc_lance_init(void)
1629{
1630 return of_register_driver(&sunlance_sbus_driver, &sbus_bus_type);
1631}
1632#endif /* !CONFIG_SUN4 */
1633
1634static void __exit sparc_lance_exit(void)
1635{
1636#ifdef CONFIG_SUN4
1637 sunlance_sun4_remove();
1638#else
1639 of_unregister_driver(&sunlance_sbus_driver);
1640#endif
1620} 1641}
1621 1642
1622module_init(sparc_lance_probe); 1643module_init(sparc_lance_init);
1623module_exit(sparc_lance_cleanup); 1644module_exit(sparc_lance_exit);
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 1f2323be60d4..9da6d5b87173 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -1,10 +1,9 @@
1/* $Id: sunqe.c,v 1.55 2002/01/15 06:48:55 davem Exp $ 1/* sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver.
2 * sunqe.c: Sparc QuadEthernet 10baseT SBUS card driver.
3 * Once again I am out to prove that every ethernet 2 * Once again I am out to prove that every ethernet
4 * controller out there can be most efficiently programmed 3 * controller out there can be most efficiently programmed
5 * if you make it look like a LANCE. 4 * if you make it look like a LANCE.
6 * 5 *
7 * Copyright (C) 1996, 1999, 2003 David S. Miller (davem@redhat.com) 6 * Copyright (C) 1996, 1999, 2003, 2006 David S. Miller (davem@davemloft.net)
8 */ 7 */
9 8
10#include <linux/module.h> 9#include <linux/module.h>
@@ -41,9 +40,9 @@
41#include "sunqe.h" 40#include "sunqe.h"
42 41
43#define DRV_NAME "sunqe" 42#define DRV_NAME "sunqe"
44#define DRV_VERSION "3.0" 43#define DRV_VERSION "4.0"
45#define DRV_RELDATE "8/24/03" 44#define DRV_RELDATE "June 23, 2006"
46#define DRV_AUTHOR "David S. Miller (davem@redhat.com)" 45#define DRV_AUTHOR "David S. Miller (davem@davemloft.net)"
47 46
48static char version[] = 47static char version[] =
49 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n"; 48 DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " " DRV_AUTHOR "\n";
@@ -755,298 +754,269 @@ static inline void qec_init_once(struct sunqec *qecp, struct sbus_dev *qsdev)
755 qecp->gregs + GLOB_RSIZE); 754 qecp->gregs + GLOB_RSIZE);
756} 755}
757 756
758/* Four QE's per QEC card. */ 757static u8 __init qec_get_burst(struct device_node *dp)
759static int __init qec_ether_init(struct net_device *dev, struct sbus_dev *sdev)
760{ 758{
761 static unsigned version_printed;
762 struct net_device *qe_devs[4];
763 struct sunqe *qeps[4];
764 struct sbus_dev *qesdevs[4];
765 struct sbus_dev *child;
766 struct sunqec *qecp = NULL;
767 u8 bsizes, bsizes_more; 759 u8 bsizes, bsizes_more;
768 int i, j, res = -ENOMEM;
769 760
770 for (i = 0; i < 4; i++) { 761 /* Find and set the burst sizes for the QEC, since it
771 qe_devs[i] = alloc_etherdev(sizeof(struct sunqe)); 762 * does the actual dma for all 4 channels.
772 if (!qe_devs[i]) 763 */
773 goto out; 764 bsizes = of_getintprop_default(dp, "burst-sizes", 0xff);
774 } 765 bsizes &= 0xff;
766 bsizes_more = of_getintprop_default(dp->parent, "burst-sizes", 0xff);
775 767
776 if (version_printed++ == 0) 768 if (bsizes_more != 0xff)
777 printk(KERN_INFO "%s", version); 769 bsizes &= bsizes_more;
770 if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 ||
771 (bsizes & DMA_BURST32)==0)
772 bsizes = (DMA_BURST32 - 1);
778 773
779 for (i = 0; i < 4; i++) { 774 return bsizes;
780 qeps[i] = (struct sunqe *) qe_devs[i]->priv; 775}
781 for (j = 0; j < 6; j++)
782 qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j];
783 qeps[i]->channel = i;
784 spin_lock_init(&qeps[i]->lock);
785 }
786 776
787 qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL); 777static struct sunqec * __init get_qec(struct sbus_dev *child_sdev)
788 if (qecp == NULL) 778{
789 goto out1; 779 struct sbus_dev *qec_sdev = child_sdev->parent;
790 qecp->qec_sdev = sdev; 780 struct sunqec *qecp;
791 781
792 for (i = 0; i < 4; i++) { 782 for (qecp = root_qec_dev; qecp; qecp = qecp->next_module) {
793 qecp->qes[i] = qeps[i]; 783 if (qecp->qec_sdev == qec_sdev)
794 qeps[i]->dev = qe_devs[i]; 784 break;
795 qeps[i]->parent = qecp;
796 } 785 }
786 if (!qecp) {
787 qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL);
788 if (qecp) {
789 u32 ctrl;
790
791 qecp->qec_sdev = qec_sdev;
792 qecp->gregs = sbus_ioremap(&qec_sdev->resource[0], 0,
793 GLOB_REG_SIZE,
794 "QEC Global Registers");
795 if (!qecp->gregs)
796 goto fail;
797
798 /* Make sure the QEC is in MACE mode. */
799 ctrl = sbus_readl(qecp->gregs + GLOB_CTRL);
800 ctrl &= 0xf0000000;
801 if (ctrl != GLOB_CTRL_MMODE) {
802 printk(KERN_ERR "qec: Not in MACE mode!\n");
803 goto fail;
804 }
797 805
798 res = -ENODEV; 806 if (qec_global_reset(qecp->gregs))
807 goto fail;
799 808
800 for (i = 0, child = sdev->child; i < 4; i++, child = child->next) { 809 qecp->qec_bursts = qec_get_burst(qec_sdev->ofdev.node);
801 /* Link in channel */
802 j = prom_getintdefault(child->prom_node, "channel#", -1);
803 if (j == -1)
804 goto out2;
805 qesdevs[j] = child;
806 }
807 810
808 for (i = 0; i < 4; i++) 811 qec_init_once(qecp, qec_sdev);
809 qeps[i]->qe_sdev = qesdevs[i];
810 812
811 /* Now map in the registers, QEC globals first. */ 813 if (request_irq(qec_sdev->irqs[0], &qec_interrupt,
812 qecp->gregs = sbus_ioremap(&sdev->resource[0], 0, 814 SA_SHIRQ, "qec", (void *) qecp)) {
813 GLOB_REG_SIZE, "QEC Global Registers"); 815 printk(KERN_ERR "qec: Can't register irq.\n");
814 if (!qecp->gregs) { 816 goto fail;
815 printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n"); 817 }
816 goto out2;
817 }
818 818
819 /* Make sure the QEC is in MACE mode. */ 819 qecp->next_module = root_qec_dev;
820 if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) { 820 root_qec_dev = qecp;
821 printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n"); 821 }
822 goto out3;
823 } 822 }
824 823
825 /* Reset the QEC. */ 824 return qecp;
826 if (qec_global_reset(qecp->gregs))
827 goto out3;
828 825
829 /* Find and set the burst sizes for the QEC, since it does 826fail:
830 * the actual dma for all 4 channels. 827 if (qecp->gregs)
831 */ 828 sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
832 bsizes = prom_getintdefault(sdev->prom_node, "burst-sizes", 0xff); 829 kfree(qecp);
833 bsizes &= 0xff; 830 return NULL;
834 bsizes_more = prom_getintdefault(sdev->bus->prom_node, "burst-sizes", 0xff); 831}
835 832
836 if (bsizes_more != 0xff) 833static int __init qec_ether_init(struct sbus_dev *sdev)
837 bsizes &= bsizes_more; 834{
838 if (bsizes == 0xff || (bsizes & DMA_BURST16) == 0 || 835 static unsigned version_printed;
839 (bsizes & DMA_BURST32)==0) 836 struct net_device *dev;
840 bsizes = (DMA_BURST32 - 1); 837 struct sunqe *qe;
838 struct sunqec *qecp;
839 int i, res;
841 840
842 qecp->qec_bursts = bsizes; 841 if (version_printed++ == 0)
842 printk(KERN_INFO "%s", version);
843 843
844 /* Perform one time QEC initialization, we never touch the QEC 844 dev = alloc_etherdev(sizeof(struct sunqe));
845 * globals again after this. 845 if (!dev)
846 */ 846 return -ENOMEM;
847 qec_init_once(qecp, sdev);
848
849 for (i = 0; i < 4; i++) {
850 struct sunqe *qe = qeps[i];
851 /* Map in QEC per-channel control registers. */
852 qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0,
853 CREG_REG_SIZE, "QEC Channel Registers");
854 if (!qe->qcregs) {
855 printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i);
856 goto out4;
857 }
858 847
859 /* Map in per-channel AMD MACE registers. */ 848 qe = netdev_priv(dev);
860 qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0,
861 MREGS_REG_SIZE, "QE MACE Registers");
862 if (!qe->mregs) {
863 printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i);
864 goto out4;
865 }
866 849
867 qe->qe_block = sbus_alloc_consistent(qe->qe_sdev, 850 i = of_getintprop_default(sdev->ofdev.node, "channel#", -1);
868 PAGE_SIZE, 851 if (i == -1) {
869 &qe->qblock_dvma); 852 struct sbus_dev *td = sdev->parent->child;
870 qe->buffers = sbus_alloc_consistent(qe->qe_sdev, 853 i = 0;
871 sizeof(struct sunqe_buffers), 854 while (td != sdev) {
872 &qe->buffers_dvma); 855 td = td->next;
873 if (qe->qe_block == NULL || qe->qblock_dvma == 0 || 856 i++;
874 qe->buffers == NULL || qe->buffers_dvma == 0) {
875 goto out4;
876 } 857 }
877
878 /* Stop this QE. */
879 qe_stop(qe);
880 } 858 }
859 qe->channel = i;
860 spin_lock_init(&qe->lock);
861
862 res = -ENODEV;
863 qecp = get_qec(sdev);
864 if (!qecp)
865 goto fail;
881 866
882 for (i = 0; i < 4; i++) { 867 qecp->qes[qe->channel] = qe;
883 SET_MODULE_OWNER(qe_devs[i]); 868 qe->dev = dev;
884 qe_devs[i]->open = qe_open; 869 qe->parent = qecp;
885 qe_devs[i]->stop = qe_close; 870 qe->qe_sdev = sdev;
886 qe_devs[i]->hard_start_xmit = qe_start_xmit;
887 qe_devs[i]->get_stats = qe_get_stats;
888 qe_devs[i]->set_multicast_list = qe_set_multicast;
889 qe_devs[i]->tx_timeout = qe_tx_timeout;
890 qe_devs[i]->watchdog_timeo = 5*HZ;
891 qe_devs[i]->irq = sdev->irqs[0];
892 qe_devs[i]->dma = 0;
893 qe_devs[i]->ethtool_ops = &qe_ethtool_ops;
894 }
895 871
896 /* QEC receives interrupts from each QE, then it sends the actual 872 res = -ENOMEM;
897 * IRQ to the cpu itself. Since QEC is the single point of 873 qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0,
898 * interrupt for all QE channels we register the IRQ handler 874 CREG_REG_SIZE, "QEC Channel Registers");
899 * for it now. 875 if (!qe->qcregs) {
900 */ 876 printk(KERN_ERR "qe: Cannot map channel registers.\n");
901 if (request_irq(sdev->irqs[0], &qec_interrupt, 877 goto fail;
902 SA_SHIRQ, "QuadEther", (void *) qecp)) {
903 printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n");
904 res = -EAGAIN;
905 goto out4;
906 } 878 }
907 879
908 for (i = 0; i < 4; i++) { 880 qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0,
909 if (register_netdev(qe_devs[i]) != 0) 881 MREGS_REG_SIZE, "QE MACE Registers");
910 goto out5; 882 if (!qe->mregs) {
883 printk(KERN_ERR "qe: Cannot map MACE registers.\n");
884 goto fail;
911 } 885 }
912 886
913 /* Report the QE channels. */ 887 qe->qe_block = sbus_alloc_consistent(qe->qe_sdev,
914 for (i = 0; i < 4; i++) { 888 PAGE_SIZE,
915 printk(KERN_INFO "%s: QuadEthernet channel[%d] ", qe_devs[i]->name, i); 889 &qe->qblock_dvma);
916 for (j = 0; j < 6; j++) 890 qe->buffers = sbus_alloc_consistent(qe->qe_sdev,
917 printk ("%2.2x%c", 891 sizeof(struct sunqe_buffers),
918 qe_devs[i]->dev_addr[j], 892 &qe->buffers_dvma);
919 j == 5 ? ' ': ':'); 893 if (qe->qe_block == NULL || qe->qblock_dvma == 0 ||
920 printk("\n"); 894 qe->buffers == NULL || qe->buffers_dvma == 0)
921 } 895 goto fail;
896
897 /* Stop this QE. */
898 qe_stop(qe);
899
900 SET_MODULE_OWNER(dev);
901 SET_NETDEV_DEV(dev, &sdev->ofdev.dev);
902
903 dev->open = qe_open;
904 dev->stop = qe_close;
905 dev->hard_start_xmit = qe_start_xmit;
906 dev->get_stats = qe_get_stats;
907 dev->set_multicast_list = qe_set_multicast;
908 dev->tx_timeout = qe_tx_timeout;
909 dev->watchdog_timeo = 5*HZ;
910 dev->irq = sdev->irqs[0];
911 dev->dma = 0;
912 dev->ethtool_ops = &qe_ethtool_ops;
913
914 res = register_netdev(dev);
915 if (res)
916 goto fail;
917
918 dev_set_drvdata(&sdev->ofdev.dev, qe);
919
920 printk(KERN_INFO "%s: qe channel[%d] ", dev->name, qe->channel);
921 for (i = 0; i < 6; i++)
922 printk ("%2.2x%c",
923 dev->dev_addr[i],
924 i == 5 ? ' ': ':');
925 printk("\n");
922 926
923 /* We are home free at this point, link the qe's into
924 * the master list for later driver exit.
925 */
926 qecp->next_module = root_qec_dev;
927 root_qec_dev = qecp;
928 927
929 return 0; 928 return 0;
930 929
931out5: 930fail:
932 while (i--) 931 if (qe->qcregs)
933 unregister_netdev(qe_devs[i]); 932 sbus_iounmap(qe->qcregs, CREG_REG_SIZE);
934 free_irq(sdev->irqs[0], (void *)qecp); 933 if (qe->mregs)
935out4: 934 sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
936 for (i = 0; i < 4; i++) { 935 if (qe->qe_block)
937 struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv; 936 sbus_free_consistent(qe->qe_sdev,
938 937 PAGE_SIZE,
939 if (qe->qcregs) 938 qe->qe_block,
940 sbus_iounmap(qe->qcregs, CREG_REG_SIZE); 939 qe->qblock_dvma);
941 if (qe->mregs) 940 if (qe->buffers)
942 sbus_iounmap(qe->mregs, MREGS_REG_SIZE); 941 sbus_free_consistent(qe->qe_sdev,
943 if (qe->qe_block) 942 sizeof(struct sunqe_buffers),
944 sbus_free_consistent(qe->qe_sdev, 943 qe->buffers,
945 PAGE_SIZE, 944 qe->buffers_dvma);
946 qe->qe_block, 945
947 qe->qblock_dvma); 946 free_netdev(dev);
948 if (qe->buffers) 947
949 sbus_free_consistent(qe->qe_sdev,
950 sizeof(struct sunqe_buffers),
951 qe->buffers,
952 qe->buffers_dvma);
953 }
954out3:
955 sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
956out2:
957 kfree(qecp);
958out1:
959 i = 4;
960out:
961 while (i--)
962 free_netdev(qe_devs[i]);
963 return res; 948 return res;
964} 949}
965 950
966static int __init qec_match(struct sbus_dev *sdev) 951static int __devinit qec_sbus_probe(struct of_device *dev, const struct of_device_id *match)
967{ 952{
968 struct sbus_dev *sibling; 953 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
969 int i;
970
971 if (strcmp(sdev->prom_name, "qec") != 0)
972 return 0;
973 954
974 /* QEC can be parent of either QuadEthernet or BigMAC 955 return qec_ether_init(sdev);
975 * children. Do not confuse this with qfe/SUNW,qfe
976 * which is a quad-happymeal card and handled by
977 * a different driver.
978 */
979 sibling = sdev->child;
980 for (i = 0; i < 4; i++) {
981 if (sibling == NULL)
982 return 0;
983 if (strcmp(sibling->prom_name, "qe") != 0)
984 return 0;
985 sibling = sibling->next;
986 }
987 return 1;
988} 956}
989 957
990static int __init qec_probe(void) 958static int __devexit qec_sbus_remove(struct of_device *dev)
991{ 959{
992 struct net_device *dev = NULL; 960 struct sunqe *qp = dev_get_drvdata(&dev->dev);
993 struct sbus_bus *bus; 961 struct net_device *net_dev = qp->dev;
994 struct sbus_dev *sdev = NULL; 962
995 static int called; 963 unregister_netdevice(net_dev);
996 int cards = 0, v; 964
997 965 sbus_iounmap(qp->qcregs, CREG_REG_SIZE);
998 root_qec_dev = NULL; 966 sbus_iounmap(qp->mregs, MREGS_REG_SIZE);
999 967 sbus_free_consistent(qp->qe_sdev,
1000 if (called) 968 PAGE_SIZE,
1001 return -ENODEV; 969 qp->qe_block,
1002 called++; 970 qp->qblock_dvma);
1003 971 sbus_free_consistent(qp->qe_sdev,
1004 for_each_sbus(bus) { 972 sizeof(struct sunqe_buffers),
1005 for_each_sbusdev(sdev, bus) { 973 qp->buffers,
1006 if (cards) 974 qp->buffers_dvma);
1007 dev = NULL; 975
1008 976 free_netdev(net_dev);
1009 if (qec_match(sdev)) { 977
1010 cards++; 978 dev_set_drvdata(&dev->dev, NULL);
1011 if ((v = qec_ether_init(dev, sdev))) 979
1012 return v;
1013 }
1014 }
1015 }
1016 if (!cards)
1017 return -ENODEV;
1018 return 0; 980 return 0;
1019} 981}
1020 982
1021static void __exit qec_cleanup(void) 983static struct of_device_id qec_sbus_match[] = {
984 {
985 .name = "qe",
986 },
987 {},
988};
989
990MODULE_DEVICE_TABLE(of, qec_sbus_match);
991
992static struct of_platform_driver qec_sbus_driver = {
993 .name = "qec",
994 .match_table = qec_sbus_match,
995 .probe = qec_sbus_probe,
996 .remove = __devexit_p(qec_sbus_remove),
997};
998
999static int __init qec_init(void)
1000{
1001 return of_register_driver(&qec_sbus_driver, &sbus_bus_type);
1002}
1003
1004static void __exit qec_exit(void)
1022{ 1005{
1023 struct sunqec *next_qec; 1006 of_unregister_driver(&qec_sbus_driver);
1024 int i;
1025 1007
1026 while (root_qec_dev) { 1008 while (root_qec_dev) {
1027 next_qec = root_qec_dev->next_module; 1009 struct sunqec *next = root_qec_dev->next_module;
1028 1010
1029 /* Release all four QE channels, then the QEC itself. */ 1011 free_irq(root_qec_dev->qec_sdev->irqs[0],
1030 for (i = 0; i < 4; i++) { 1012 (void *) root_qec_dev);
1031 unregister_netdev(root_qec_dev->qes[i]->dev);
1032 sbus_iounmap(root_qec_dev->qes[i]->qcregs, CREG_REG_SIZE);
1033 sbus_iounmap(root_qec_dev->qes[i]->mregs, MREGS_REG_SIZE);
1034 sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev,
1035 PAGE_SIZE,
1036 root_qec_dev->qes[i]->qe_block,
1037 root_qec_dev->qes[i]->qblock_dvma);
1038 sbus_free_consistent(root_qec_dev->qes[i]->qe_sdev,
1039 sizeof(struct sunqe_buffers),
1040 root_qec_dev->qes[i]->buffers,
1041 root_qec_dev->qes[i]->buffers_dvma);
1042 free_netdev(root_qec_dev->qes[i]->dev);
1043 }
1044 free_irq(root_qec_dev->qec_sdev->irqs[0], (void *)root_qec_dev);
1045 sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE); 1013 sbus_iounmap(root_qec_dev->gregs, GLOB_REG_SIZE);
1014
1046 kfree(root_qec_dev); 1015 kfree(root_qec_dev);
1047 root_qec_dev = next_qec; 1016
1017 root_qec_dev = next;
1048 } 1018 }
1049} 1019}
1050 1020
1051module_init(qec_probe); 1021module_init(qec_init);
1052module_exit(qec_cleanup); 1022module_exit(qec_exit);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index e3e380f90f86..35f931638750 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -10549,11 +10549,13 @@ static int __devinit tg3_get_macaddr_sparc(struct tg3 *tp)
10549 struct pcidev_cookie *pcp = pdev->sysdata; 10549 struct pcidev_cookie *pcp = pdev->sysdata;
10550 10550
10551 if (pcp != NULL) { 10551 if (pcp != NULL) {
10552 int node = pcp->prom_node; 10552 unsigned char *addr;
10553 int len;
10553 10554
10554 if (prom_getproplen(node, "local-mac-address") == 6) { 10555 addr = of_get_property(pcp->prom_node, "local-mac-address",
10555 prom_getproperty(node, "local-mac-address", 10556 &len);
10556 dev->dev_addr, 6); 10557 if (addr && len == 6) {
10558 memcpy(dev->dev_addr, addr, 6);
10557 memcpy(dev->perm_addr, dev->dev_addr, 6); 10559 memcpy(dev->perm_addr, dev->dev_addr, 6);
10558 return 0; 10560 return 0;
10559 } 10561 }
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index cabdf894e21e..e0de66739a42 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1550,10 +1550,14 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
1550 dev->dev_addr[i] = last_phys_addr[i]; 1550 dev->dev_addr[i] = last_phys_addr[i];
1551 dev->dev_addr[i] = last_phys_addr[i] + 1; 1551 dev->dev_addr[i] = last_phys_addr[i] + 1;
1552#if defined(__sparc__) 1552#if defined(__sparc__)
1553 if ((pcp != NULL) && prom_getproplen(pcp->prom_node, 1553 if (pcp) {
1554 "local-mac-address") == 6) { 1554 unsigned char *addr;
1555 prom_getproperty(pcp->prom_node, "local-mac-address", 1555 int len;
1556 dev->dev_addr, 6); 1556
1557 addr = of_get_property(pcp->prom_node,
1558 "local-mac-address", &len);
1559 if (addr && len == 6)
1560 memcpy(dev->dev_addr, addr, 6);
1557 } 1561 }
1558#endif 1562#endif
1559#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */ 1563#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */
diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c
index 36a1556e64c7..69a4bbd4cbee 100644
--- a/drivers/parport/parport_sunbpp.c
+++ b/drivers/parport/parport_sunbpp.c
@@ -1,5 +1,4 @@
1/* $Id: parport_sunbpp.c,v 1.12 2001/05/26 03:01:42 davem Exp $ 1/* parport_sunbpp.c: Parallel-port routines for SBUS
2 * Parallel-port routines for Sun architecture
3 * 2 *
4 * Author: Derrick J. Brashear <shadow@dementia.org> 3 * Author: Derrick J. Brashear <shadow@dementia.org>
5 * 4 *
@@ -14,6 +13,9 @@
14 * Gus Baldauf (gbaldauf@ix.netcom.com) 13 * Gus Baldauf (gbaldauf@ix.netcom.com)
15 * Peter Zaitcev 14 * Peter Zaitcev
16 * Tom Dyas 15 * Tom Dyas
16 *
17 * Updated to new SBUS device framework: David S. Miller <davem@davemloft.net>
18 *
17 */ 19 */
18 20
19#include <linux/string.h> 21#include <linux/string.h>
@@ -287,14 +289,7 @@ static struct parport_operations parport_sunbpp_ops =
287 .owner = THIS_MODULE, 289 .owner = THIS_MODULE,
288}; 290};
289 291
290typedef struct { 292static int __devinit init_one_port(struct sbus_dev *sdev)
291 struct list_head list;
292 struct parport *port;
293} Node;
294/* no locks, everything's serialized */
295static LIST_HEAD(port_list);
296
297static int __init init_one_port(struct sbus_dev *sdev)
298{ 293{
299 struct parport *p; 294 struct parport *p;
300 /* at least in theory there may be a "we don't dma" case */ 295 /* at least in theory there may be a "we don't dma" case */
@@ -303,109 +298,120 @@ static int __init init_one_port(struct sbus_dev *sdev)
303 int irq, dma, err = 0, size; 298 int irq, dma, err = 0, size;
304 struct bpp_regs __iomem *regs; 299 struct bpp_regs __iomem *regs;
305 unsigned char value_tcr; 300 unsigned char value_tcr;
306 Node *node;
307
308 dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
309 node = kmalloc(sizeof(Node), GFP_KERNEL);
310 if (!node)
311 goto out0;
312 301
313 irq = sdev->irqs[0]; 302 irq = sdev->irqs[0];
314 base = sbus_ioremap(&sdev->resource[0], 0, 303 base = sbus_ioremap(&sdev->resource[0], 0,
315 sdev->reg_addrs[0].reg_size, 304 sdev->reg_addrs[0].reg_size,
316 "sunbpp"); 305 "sunbpp");
317 if (!base) 306 if (!base)
318 goto out1; 307 return -ENODEV;
319 308
320 size = sdev->reg_addrs[0].reg_size; 309 size = sdev->reg_addrs[0].reg_size;
321 dma = PARPORT_DMA_NONE; 310 dma = PARPORT_DMA_NONE;
322 311
323 dprintk(("alloc(ppops), ")); 312 ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL);
324 ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
325 if (!ops) 313 if (!ops)
326 goto out2; 314 goto out_unmap;
327 315
328 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations)); 316 memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
329 317
330 dprintk(("register_port\n")); 318 dprintk(("register_port\n"));
331 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops))) 319 if (!(p = parport_register_port((unsigned long)base, irq, dma, ops)))
332 goto out3; 320 goto out_free_ops;
333 321
334 p->size = size; 322 p->size = size;
335 323
336 dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
337 p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
338 if ((err = request_irq(p->irq, parport_sunbpp_interrupt, 324 if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
339 SA_SHIRQ, p->name, p)) != 0) { 325 SA_SHIRQ, p->name, p)) != 0) {
340 dprintk(("ERROR %d\n", err)); 326 goto out_put_port;
341 goto out4;
342 } 327 }
343 dprintk(("OK\n")); 328
344 parport_sunbpp_enable_irq(p); 329 parport_sunbpp_enable_irq(p);
345 330
346 regs = (struct bpp_regs __iomem *)p->base; 331 regs = (struct bpp_regs __iomem *)p->base;
347 dprintk((KERN_DEBUG "forward\n")); 332
348 value_tcr = sbus_readb(&regs->p_tcr); 333 value_tcr = sbus_readb(&regs->p_tcr);
349 value_tcr &= ~P_TCR_DIR; 334 value_tcr &= ~P_TCR_DIR;
350 sbus_writeb(value_tcr, &regs->p_tcr); 335 sbus_writeb(value_tcr, &regs->p_tcr);
351 336
352 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base); 337 printk(KERN_INFO "%s: sunbpp at 0x%lx\n", p->name, p->base);
353 node->port = p;
354 list_add(&node->list, &port_list);
355 parport_announce_port (p);
356 338
357 return 1; 339 dev_set_drvdata(&sdev->ofdev.dev, p);
340
341 parport_announce_port(p);
342
343 return 0;
358 344
359out4: 345out_put_port:
360 parport_put_port(p); 346 parport_put_port(p);
361out3: 347
348out_free_ops:
362 kfree(ops); 349 kfree(ops);
363out2: 350
351out_unmap:
364 sbus_iounmap(base, size); 352 sbus_iounmap(base, size);
365out1: 353
366 kfree(node);
367out0:
368 return err; 354 return err;
369} 355}
370 356
371static int __init parport_sunbpp_init(void) 357static int __devinit bpp_probe(struct of_device *dev, const struct of_device_id *match)
372{ 358{
373 struct sbus_bus *sbus; 359 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
374 struct sbus_dev *sdev; 360
375 int count = 0; 361 return init_one_port(sdev);
376 362}
377 for_each_sbus(sbus) { 363
378 for_each_sbusdev(sdev, sbus) { 364static int __devexit bpp_remove(struct of_device *dev)
379 if (!strcmp(sdev->prom_name, "SUNW,bpp")) 365{
380 count += init_one_port(sdev); 366 struct parport *p = dev_get_drvdata(&dev->dev);
381 } 367 struct parport_operations *ops = p->ops;
368
369 parport_remove_port(p);
370
371 if (p->irq != PARPORT_IRQ_NONE) {
372 parport_sunbpp_disable_irq(p);
373 free_irq(p->irq, p);
382 } 374 }
383 return count ? 0 : -ENODEV; 375
376 sbus_iounmap((void __iomem *) p->base, p->size);
377 parport_put_port(p);
378 kfree(ops);
379
380 dev_set_drvdata(&dev->dev, NULL);
381
382 return 0;
383}
384
385static struct of_device_id bpp_match[] = {
386 {
387 .name = "SUNW,bpp",
388 },
389 {},
390};
391
392MODULE_DEVICE_TABLE(of, qec_sbus_match);
393
394static struct of_platform_driver bpp_sbus_driver = {
395 .name = "bpp",
396 .match_table = bpp_match,
397 .probe = bpp_probe,
398 .remove = __devexit_p(bpp_remove),
399};
400
401static int __init parport_sunbpp_init(void)
402{
403 return of_register_driver(&bpp_sbus_driver, &sbus_bus_type);
384} 404}
385 405
386static void __exit parport_sunbpp_exit(void) 406static void __exit parport_sunbpp_exit(void)
387{ 407{
388 while (!list_empty(&port_list)) { 408 of_unregister_driver(&bpp_sbus_driver);
389 Node *node = list_entry(port_list.next, Node, list);
390 struct parport *p = node->port;
391 struct parport_operations *ops = p->ops;
392 parport_remove_port(p);
393
394 if (p->irq != PARPORT_IRQ_NONE) {
395 parport_sunbpp_disable_irq(p);
396 free_irq(p->irq, p);
397 }
398 sbus_iounmap((void __iomem *)p->base, p->size);
399 parport_put_port(p);
400 kfree (ops);
401 list_del(&node->list);
402 kfree (node);
403 }
404} 409}
405 410
406MODULE_AUTHOR("Derrick J Brashear"); 411MODULE_AUTHOR("Derrick J Brashear");
407MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port"); 412MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
408MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port"); 413MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
414MODULE_VERSION("2.0");
409MODULE_LICENSE("GPL"); 415MODULE_LICENSE("GPL");
410 416
411module_init(parport_sunbpp_init) 417module_init(parport_sunbpp_init)
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c
index d89f83f769f5..1cc706e11119 100644
--- a/drivers/sbus/char/bbc_envctrl.c
+++ b/drivers/sbus/char/bbc_envctrl.c
@@ -575,9 +575,9 @@ int bbc_envctrl_init(void)
575 int devidx = 0; 575 int devidx = 0;
576 576
577 while ((echild = bbc_i2c_getdev(devidx++)) != NULL) { 577 while ((echild = bbc_i2c_getdev(devidx++)) != NULL) {
578 if (!strcmp(echild->prom_name, "temperature")) 578 if (!strcmp(echild->prom_node->name, "temperature"))
579 attach_one_temp(echild, temp_index++); 579 attach_one_temp(echild, temp_index++);
580 if (!strcmp(echild->prom_name, "fan-control")) 580 if (!strcmp(echild->prom_node->name, "fan-control"))
581 attach_one_fan(echild, fan_index++); 581 attach_one_fan(echild, fan_index++);
582 } 582 }
583 if (temp_index != 0 && fan_index != 0) { 583 if (temp_index != 0 && fan_index != 0) {
diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c
index 3e156e005f2e..73634371393b 100644
--- a/drivers/sbus/char/bbc_i2c.c
+++ b/drivers/sbus/char/bbc_i2c.c
@@ -423,7 +423,7 @@ static int __init bbc_present(void)
423 423
424 for_each_ebus(ebus) { 424 for_each_ebus(ebus) {
425 for_each_ebusdev(edev, ebus) { 425 for_each_ebusdev(edev, ebus) {
426 if (!strcmp(edev->prom_name, "bbc")) 426 if (!strcmp(edev->prom_node->name, "bbc"))
427 return 1; 427 return 1;
428 } 428 }
429 } 429 }
@@ -446,7 +446,7 @@ static int __init bbc_i2c_init(void)
446 446
447 for_each_ebus(ebus) { 447 for_each_ebus(ebus) {
448 for_each_ebusdev(edev, ebus) { 448 for_each_ebusdev(edev, ebus) {
449 if (!strcmp(edev->prom_name, "i2c")) { 449 if (!strcmp(edev->prom_node->name, "i2c")) {
450 if (!attach_one_i2c(edev, index)) 450 if (!attach_one_i2c(edev, index))
451 index++; 451 index++;
452 } 452 }
diff --git a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
index c3a51d1fae5d..d92bc8827a9e 100644
--- a/drivers/sbus/char/display7seg.c
+++ b/drivers/sbus/char/display7seg.c
@@ -184,7 +184,7 @@ static int __init d7s_init(void)
184 184
185 for_each_ebus(ebus) { 185 for_each_ebus(ebus) {
186 for_each_ebusdev(edev, ebus) { 186 for_each_ebusdev(edev, ebus) {
187 if (!strcmp(edev->prom_name, D7S_OBPNAME)) 187 if (!strcmp(edev->prom_node->name, D7S_OBPNAME))
188 goto ebus_done; 188 goto ebus_done;
189 } 189 }
190 } 190 }
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index 19e8eddf887a..cf97e9efe9b6 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -768,16 +768,14 @@ static void envctrl_set_mon(struct i2c_child_t *pchild,
768 * decoding tables, monitor type, optional properties. 768 * decoding tables, monitor type, optional properties.
769 * Return: None. 769 * Return: None.
770 */ 770 */
771static void envctrl_init_adc(struct i2c_child_t *pchild, int node) 771static void envctrl_init_adc(struct i2c_child_t *pchild, struct device_node *dp)
772{ 772{
773 char chnls_desc[CHANNEL_DESC_SZ];
774 int i = 0, len; 773 int i = 0, len;
775 char *pos = chnls_desc; 774 char *pos;
775 unsigned int *pval;
776 776
777 /* Firmware describe channels into a stream separated by a '\0'. */ 777 /* Firmware describe channels into a stream separated by a '\0'. */
778 len = prom_getproperty(node, "channels-description", chnls_desc, 778 pos = of_get_property(dp, "channels-description", &len);
779 CHANNEL_DESC_SZ);
780 chnls_desc[CHANNEL_DESC_SZ - 1] = '\0';
781 779
782 while (len > 0) { 780 while (len > 0) {
783 int l = strlen(pos) + 1; 781 int l = strlen(pos) + 1;
@@ -787,10 +785,13 @@ static void envctrl_init_adc(struct i2c_child_t *pchild, int node)
787 } 785 }
788 786
789 /* Get optional properties. */ 787 /* Get optional properties. */
790 len = prom_getproperty(node, "warning-temp", (char *)&warning_temperature, 788 pval = of_get_property(dp, "warning-temp", NULL);
791 sizeof(warning_temperature)); 789 if (pval)
792 len = prom_getproperty(node, "shutdown-temp", (char *)&shutdown_temperature, 790 warning_temperature = *pval;
793 sizeof(shutdown_temperature)); 791
792 pval = of_get_property(dp, "shutdown-temp", NULL);
793 if (pval)
794 shutdown_temperature = *pval;
794} 795}
795 796
796/* Function Description: Initialize child device monitoring fan status. 797/* Function Description: Initialize child device monitoring fan status.
@@ -864,21 +865,18 @@ static void envctrl_init_voltage_status(struct i2c_child_t *pchild)
864static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, 865static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
865 struct i2c_child_t *pchild) 866 struct i2c_child_t *pchild)
866{ 867{
867 int node, len, i, tbls_size = 0; 868 int len, i, tbls_size = 0;
868 869 struct device_node *dp = edev_child->prom_node;
869 node = edev_child->prom_node; 870 void *pval;
870 871
871 /* Get device address. */ 872 /* Get device address. */
872 len = prom_getproperty(node, "reg", 873 pval = of_get_property(dp, "reg", &len);
873 (char *) &(pchild->addr), 874 memcpy(&pchild->addr, pval, len);
874 sizeof(pchild->addr));
875 875
876 /* Get tables property. Read firmware temperature tables. */ 876 /* Get tables property. Read firmware temperature tables. */
877 len = prom_getproperty(node, "translation", 877 pval = of_get_property(dp, "translation", &len);
878 (char *) pchild->tblprop_array, 878 if (pval && len > 0) {
879 (PCF8584_MAX_CHANNELS * 879 memcpy(pchild->tblprop_array, pval, len);
880 sizeof(struct pcf8584_tblprop)));
881 if (len > 0) {
882 pchild->total_tbls = len / sizeof(struct pcf8584_tblprop); 880 pchild->total_tbls = len / sizeof(struct pcf8584_tblprop);
883 for (i = 0; i < pchild->total_tbls; i++) { 881 for (i = 0; i < pchild->total_tbls; i++) {
884 if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) { 882 if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) {
@@ -891,12 +889,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
891 printk("envctrl: Failed to allocate table.\n"); 889 printk("envctrl: Failed to allocate table.\n");
892 return; 890 return;
893 } 891 }
894 len = prom_getproperty(node, "tables", 892 pval = of_get_property(dp, "tables", &len);
895 (char *) pchild->tables, tbls_size); 893 if (!pval || len <= 0) {
896 if (len <= 0) {
897 printk("envctrl: Failed to get table.\n"); 894 printk("envctrl: Failed to get table.\n");
898 return; 895 return;
899 } 896 }
897 memcpy(pchild->tables, pval, len);
900 } 898 }
901 899
902 /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04) 900 /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04)
@@ -907,12 +905,11 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
907 * 'NULL' monitor type. 905 * 'NULL' monitor type.
908 */ 906 */
909 if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) { 907 if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) {
908 struct device_node *root_node;
910 int len; 909 int len;
911 char prop[56];
912 910
913 len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop)); 911 root_node = of_find_node_by_path("/");
914 if (0 < len && (0 == strncmp(prop, "SUNW,UltraSPARC-IIi-cEngine", len))) 912 if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) {
915 {
916 for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { 913 for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) {
917 pchild->mon_type[len] = ENVCTRL_NOMON; 914 pchild->mon_type[len] = ENVCTRL_NOMON;
918 } 915 }
@@ -921,16 +918,14 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
921 } 918 }
922 919
923 /* Get the monitor channels. */ 920 /* Get the monitor channels. */
924 len = prom_getproperty(node, "channels-in-use", 921 pval = of_get_property(dp, "channels-in-use", &len);
925 (char *) pchild->chnl_array, 922 memcpy(pchild->chnl_array, pval, len);
926 (PCF8584_MAX_CHANNELS *
927 sizeof(struct pcf8584_channel)));
928 pchild->total_chnls = len / sizeof(struct pcf8584_channel); 923 pchild->total_chnls = len / sizeof(struct pcf8584_channel);
929 924
930 for (i = 0; i < pchild->total_chnls; i++) { 925 for (i = 0; i < pchild->total_chnls; i++) {
931 switch (pchild->chnl_array[i].type) { 926 switch (pchild->chnl_array[i].type) {
932 case PCF8584_TEMP_TYPE: 927 case PCF8584_TEMP_TYPE:
933 envctrl_init_adc(pchild, node); 928 envctrl_init_adc(pchild, dp);
934 break; 929 break;
935 930
936 case PCF8584_GLOBALADDR_TYPE: 931 case PCF8584_GLOBALADDR_TYPE:
@@ -945,7 +940,7 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
945 940
946 case PCF8584_VOLTAGE_TYPE: 941 case PCF8584_VOLTAGE_TYPE:
947 if (pchild->i2ctype == I2C_ADC) { 942 if (pchild->i2ctype == I2C_ADC) {
948 envctrl_init_adc(pchild,node); 943 envctrl_init_adc(pchild,dp);
949 } else { 944 } else {
950 envctrl_init_voltage_status(pchild); 945 envctrl_init_voltage_status(pchild);
951 } 946 }
@@ -1046,7 +1041,7 @@ static int __init envctrl_init(void)
1046 1041
1047 for_each_ebus(ebus) { 1042 for_each_ebus(ebus) {
1048 for_each_ebusdev(edev, ebus) { 1043 for_each_ebusdev(edev, ebus) {
1049 if (!strcmp(edev->prom_name, "bbc")) { 1044 if (!strcmp(edev->prom_node->name, "bbc")) {
1050 /* If we find a boot-bus controller node, 1045 /* If we find a boot-bus controller node,
1051 * then this envctrl driver is not for us. 1046 * then this envctrl driver is not for us.
1052 */ 1047 */
@@ -1060,14 +1055,14 @@ static int __init envctrl_init(void)
1060 */ 1055 */
1061 for_each_ebus(ebus) { 1056 for_each_ebus(ebus) {
1062 for_each_ebusdev(edev, ebus) { 1057 for_each_ebusdev(edev, ebus) {
1063 if (!strcmp(edev->prom_name, "i2c")) { 1058 if (!strcmp(edev->prom_node->name, "i2c")) {
1064 i2c = ioremap(edev->resource[0].start, 0x2); 1059 i2c = ioremap(edev->resource[0].start, 0x2);
1065 for_each_edevchild(edev, edev_child) { 1060 for_each_edevchild(edev, edev_child) {
1066 if (!strcmp("gpio", edev_child->prom_name)) { 1061 if (!strcmp("gpio", edev_child->prom_node->name)) {
1067 i2c_childlist[i].i2ctype = I2C_GPIO; 1062 i2c_childlist[i].i2ctype = I2C_GPIO;
1068 envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); 1063 envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
1069 } 1064 }
1070 if (!strcmp("adc", edev_child->prom_name)) { 1065 if (!strcmp("adc", edev_child->prom_node->name)) {
1071 i2c_childlist[i].i2ctype = I2C_ADC; 1066 i2c_childlist[i].i2ctype = I2C_ADC;
1072 envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); 1067 envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
1073 } 1068 }
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 2beb3dded087..5ae684c011f8 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -192,9 +192,11 @@ static int __init flash_init(void)
192 } 192 }
193 if (!sdev) { 193 if (!sdev) {
194#ifdef CONFIG_PCI 194#ifdef CONFIG_PCI
195 struct linux_prom_registers *ebus_regs;
196
195 for_each_ebus(ebus) { 197 for_each_ebus(ebus) {
196 for_each_ebusdev(edev, ebus) { 198 for_each_ebusdev(edev, ebus) {
197 if (!strcmp(edev->prom_name, "flashprom")) 199 if (!strcmp(edev->prom_node->name, "flashprom"))
198 goto ebus_done; 200 goto ebus_done;
199 } 201 }
200 } 202 }
@@ -202,23 +204,23 @@ static int __init flash_init(void)
202 if (!edev) 204 if (!edev)
203 return -ENODEV; 205 return -ENODEV;
204 206
205 len = prom_getproperty(edev->prom_node, "reg", (void *)regs, sizeof(regs)); 207 ebus_regs = of_get_property(edev->prom_node, "reg", &len);
206 if ((len % sizeof(regs[0])) != 0) { 208 if (!ebus_regs || (len % sizeof(regs[0])) != 0) {
207 printk("flash: Strange reg property size %d\n", len); 209 printk("flash: Strange reg property size %d\n", len);
208 return -ENODEV; 210 return -ENODEV;
209 } 211 }
210 212
211 nregs = len / sizeof(regs[0]); 213 nregs = len / sizeof(ebus_regs[0]);
212 214
213 flash.read_base = edev->resource[0].start; 215 flash.read_base = edev->resource[0].start;
214 flash.read_size = regs[0].reg_size; 216 flash.read_size = ebus_regs[0].reg_size;
215 217
216 if (nregs == 1) { 218 if (nregs == 1) {
217 flash.write_base = edev->resource[0].start; 219 flash.write_base = edev->resource[0].start;
218 flash.write_size = regs[0].reg_size; 220 flash.write_size = ebus_regs[0].reg_size;
219 } else if (nregs == 2) { 221 } else if (nregs == 2) {
220 flash.write_base = edev->resource[1].start; 222 flash.write_base = edev->resource[1].start;
221 flash.write_size = regs[1].reg_size; 223 flash.write_size = ebus_regs[1].reg_size;
222 } else { 224 } else {
223 printk("flash: Strange number of regs %d\n", nregs); 225 printk("flash: Strange number of regs %d\n", nregs);
224 return -ENODEV; 226 return -ENODEV;
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 239e108b8ed1..cf5b476b5496 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -243,8 +243,8 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
243 ((int *) opp->oprom_array)[1]); 243 ((int *) opp->oprom_array)[1]);
244 244
245 pcp = pdev->sysdata; 245 pcp = pdev->sysdata;
246 if (pcp != NULL && pcp->prom_node != -1 && pcp->prom_node) { 246 if (pcp != NULL) {
247 node = pcp->prom_node; 247 node = pcp->prom_node->node;
248 data->current_node = node; 248 data->current_node = node;
249 *((int *)opp->oprom_array) = node; 249 *((int *)opp->oprom_array) = node;
250 opp->oprom_size = sizeof(int); 250 opp->oprom_size = sizeof(int);
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
index 5d30a3ebfccd..387a6aa8c020 100644
--- a/drivers/sbus/sbus.c
+++ b/drivers/sbus/sbus.c
@@ -1,7 +1,6 @@
1/* $Id: sbus.c,v 1.100 2002/01/24 15:36:24 davem Exp $ 1/* sbus.c: SBus support routines.
2 * sbus.c: SBus support routines.
3 * 2 *
4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 3 * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net)
5 */ 4 */
6 5
7#include <linux/kernel.h> 6#include <linux/kernel.h>
@@ -14,237 +13,76 @@
14#include <asm/sbus.h> 13#include <asm/sbus.h>
15#include <asm/dma.h> 14#include <asm/dma.h>
16#include <asm/oplib.h> 15#include <asm/oplib.h>
16#include <asm/prom.h>
17#include <asm/of_device.h>
17#include <asm/bpp.h> 18#include <asm/bpp.h>
18#include <asm/irq.h> 19#include <asm/irq.h>
19 20
20struct sbus_bus *sbus_root = NULL; 21struct sbus_bus *sbus_root;
21 22
22static struct linux_prom_irqs irqs[PROMINTR_MAX] __initdata = { { 0 } }; 23static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev)
23#ifdef CONFIG_SPARC32
24static int interrupts[PROMINTR_MAX] __initdata = { 0 };
25#endif
26
27#ifdef CONFIG_PCI
28extern int pcic_present(void);
29#endif
30
31/* Perhaps when I figure out more about the iommu we'll put a
32 * device registration routine here that probe_sbus() calls to
33 * setup the iommu for each Sbus.
34 */
35
36/* We call this for each SBus device, and fill the structure based
37 * upon the prom device tree. We return the start of memory after
38 * the things we have allocated.
39 */
40
41/* #define DEBUG_FILL */
42
43static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev)
44{ 24{
45 unsigned long address, base; 25 unsigned long base;
26 void *pval;
46 int len; 27 int len;
47 28
48 sdev->prom_node = prom_node; 29 sdev->prom_node = dp->node;
49 prom_getstring(prom_node, "name", 30 strcpy(sdev->prom_name, dp->name);
50 sdev->prom_name, sizeof(sdev->prom_name));
51 address = prom_getint(prom_node, "address");
52 len = prom_getproperty(prom_node, "reg",
53 (char *) sdev->reg_addrs,
54 sizeof(sdev->reg_addrs));
55 if (len == -1) {
56 sdev->num_registers = 0;
57 goto no_regs;
58 }
59 31
60 if (len % sizeof(struct linux_prom_registers)) { 32 pval = of_get_property(dp, "reg", &len);
61 prom_printf("fill_sbus_device: proplen for regs of %s " 33 sdev->num_registers = 0;
62 " was %d, need multiple of %d\n", 34 if (pval) {
63 sdev->prom_name, len, 35 memcpy(sdev->reg_addrs, pval, len);
64 (int) sizeof(struct linux_prom_registers));
65 prom_halt();
66 }
67 if (len > (sizeof(struct linux_prom_registers) * PROMREG_MAX)) {
68 prom_printf("fill_sbus_device: Too many register properties "
69 "for device %s, len=%d\n",
70 sdev->prom_name, len);
71 prom_halt();
72 }
73 sdev->num_registers = len / sizeof(struct linux_prom_registers);
74 sdev->ranges_applied = 0;
75 36
76 base = (unsigned long) sdev->reg_addrs[0].phys_addr; 37 sdev->num_registers =
38 len / sizeof(struct linux_prom_registers);
77 39
78 /* Compute the slot number. */ 40 base = (unsigned long) sdev->reg_addrs[0].phys_addr;
79 if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m) {
80 sdev->slot = sbus_dev_slot(base);
81 } else {
82 sdev->slot = sdev->reg_addrs[0].which_io;
83 }
84 41
85no_regs: 42 /* Compute the slot number. */
86 len = prom_getproperty(prom_node, "ranges", 43 if (base >= SUN_SBUS_BVADDR && sparc_cpu_model == sun4m)
87 (char *)sdev->device_ranges, 44 sdev->slot = sbus_dev_slot(base);
88 sizeof(sdev->device_ranges)); 45 else
89 if (len == -1) { 46 sdev->slot = sdev->reg_addrs[0].which_io;
90 sdev->num_device_ranges = 0;
91 goto no_ranges;
92 }
93 if (len % sizeof(struct linux_prom_ranges)) {
94 prom_printf("fill_sbus_device: proplen for ranges of %s "
95 " was %d, need multiple of %d\n",
96 sdev->prom_name, len,
97 (int) sizeof(struct linux_prom_ranges));
98 prom_halt();
99 }
100 if (len > (sizeof(struct linux_prom_ranges) * PROMREG_MAX)) {
101 prom_printf("fill_sbus_device: Too many range properties "
102 "for device %s, len=%d\n",
103 sdev->prom_name, len);
104 prom_halt();
105 } 47 }
106 sdev->num_device_ranges = 48
107 len / sizeof(struct linux_prom_ranges); 49 pval = of_get_property(dp, "ranges", &len);
108 50 sdev->num_device_ranges = 0;
109no_ranges: 51 if (pval) {
110 /* XXX Unfortunately, IRQ issues are very arch specific. 52 memcpy(sdev->device_ranges, pval, len);
111 * XXX Pull this crud out into an arch specific area 53 sdev->num_device_ranges =
112 * XXX at some point. -DaveM 54 len / sizeof(struct linux_prom_ranges);
113 */
114#ifdef CONFIG_SPARC64
115 len = prom_getproperty(prom_node, "interrupts",
116 (char *) irqs, sizeof(irqs));
117 if (len == -1 || len == 0) {
118 sdev->irqs[0] = 0;
119 sdev->num_irqs = 0;
120 } else {
121 unsigned int pri = irqs[0].pri;
122
123 sdev->num_irqs = 1;
124 if (pri < 0x20)
125 pri += sdev->slot * 8;
126
127 sdev->irqs[0] = sbus_build_irq(sdev->bus, pri);
128 } 55 }
129#endif /* CONFIG_SPARC64 */
130
131#ifdef CONFIG_SPARC32
132 len = prom_getproperty(prom_node, "intr",
133 (char *)irqs, sizeof(irqs));
134 if (len != -1) {
135 sdev->num_irqs = len / 8;
136 if (sdev->num_irqs == 0) {
137 sdev->irqs[0] = 0;
138 } else if (sparc_cpu_model == sun4d) {
139 extern unsigned int sun4d_build_irq(struct sbus_dev *sdev, int irq);
140
141 for (len = 0; len < sdev->num_irqs; len++)
142 sdev->irqs[len] = sun4d_build_irq(sdev, irqs[len].pri);
143 } else {
144 for (len = 0; len < sdev->num_irqs; len++)
145 sdev->irqs[len] = irqs[len].pri;
146 }
147 } else {
148 /* No "intr" node found-- check for "interrupts" node.
149 * This node contains SBus interrupt levels, not IPLs
150 * as in "intr", and no vector values. We convert
151 * SBus interrupt levels to PILs (platform specific).
152 */
153 len = prom_getproperty(prom_node, "interrupts",
154 (char *)interrupts, sizeof(interrupts));
155 if (len == -1) {
156 sdev->irqs[0] = 0;
157 sdev->num_irqs = 0;
158 } else {
159 sdev->num_irqs = len / sizeof(int);
160 for (len = 0; len < sdev->num_irqs; len++) {
161 sdev->irqs[len] = sbint_to_irq(sdev, interrupts[len]);
162 }
163 }
164 }
165#endif /* CONFIG_SPARC32 */
166}
167 56
168/* This routine gets called from whoever needs the sbus first, to scan 57 sbus_fill_device_irq(sdev);
169 * the SBus device tree. Currently it just prints out the devices
170 * found on the bus and builds trees of SBUS structs and attached
171 * devices.
172 */
173 58
174extern void iommu_init(int iommu_node, struct sbus_bus *sbus); 59 sdev->ofdev.node = dp;
175extern void iounit_init(int sbi_node, int iounit_node, struct sbus_bus *sbus); 60 if (sdev->parent)
176void sun4_init(void); 61 sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev;
177#ifdef CONFIG_SUN_AUXIO 62 else
178extern void auxio_probe(void); 63 sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
179#endif 64 sdev->ofdev.dev.bus = &sbus_bus_type;
180 65 strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name);
181static void __init sbus_do_child_siblings(int start_node,
182 struct sbus_dev *child,
183 struct sbus_dev *parent,
184 struct sbus_bus *sbus)
185{
186 struct sbus_dev *this_dev = child;
187 int this_node = start_node;
188
189 /* Child already filled in, just need to traverse siblings. */
190 child->child = NULL;
191 child->parent = parent;
192 while((this_node = prom_getsibling(this_node)) != 0) {
193 this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
194 this_dev = this_dev->next;
195 this_dev->next = NULL;
196 this_dev->parent = parent;
197
198 this_dev->bus = sbus;
199 fill_sbus_device(this_node, this_dev);
200
201 if(prom_getchild(this_node)) {
202 this_dev->child = kmalloc(sizeof(struct sbus_dev),
203 GFP_ATOMIC);
204 this_dev->child->bus = sbus;
205 this_dev->child->next = NULL;
206 fill_sbus_device(prom_getchild(this_node), this_dev->child);
207 sbus_do_child_siblings(prom_getchild(this_node),
208 this_dev->child, this_dev, sbus);
209 } else {
210 this_dev->child = NULL;
211 }
212 }
213}
214 66
215/* 67 if (of_device_register(&sdev->ofdev) != 0)
216 * XXX This functions appears to be a distorted version of 68 printk(KERN_DEBUG "sbus: device registration error for %s!\n",
217 * prom_sbus_ranges_init(), with all sun4d stuff cut away. 69 sdev->ofdev.dev.bus_id);
218 * Ask DaveM what is going on here, how is sun4d supposed to work... XXX 70}
219 */
220/* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */
221 71
222static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus) 72static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus)
223{ 73{
74 void *pval;
224 int len; 75 int len;
225 76
226 len = prom_getproperty(sbus->prom_node, "ranges", 77 pval = of_get_property(dp, "ranges", &len);
227 (char *) sbus->sbus_ranges, 78 sbus->num_sbus_ranges = 0;
228 sizeof(sbus->sbus_ranges)); 79 if (pval) {
229 if (len == -1 || len == 0) { 80 memcpy(sbus->sbus_ranges, pval, len);
230 sbus->num_sbus_ranges = 0; 81 sbus->num_sbus_ranges =
231 return; 82 len / sizeof(struct linux_prom_ranges);
232 } 83
233 sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges); 84 sbus_arch_bus_ranges_init(dp->parent, sbus);
234#ifdef CONFIG_SPARC32
235 if (sparc_cpu_model == sun4d) {
236 struct linux_prom_ranges iounit_ranges[PROMREG_MAX];
237 int num_iounit_ranges;
238
239 len = prom_getproperty(parent_node, "ranges",
240 (char *) iounit_ranges,
241 sizeof (iounit_ranges));
242 if (len != -1) {
243 num_iounit_ranges = (len/sizeof(struct linux_prom_ranges));
244 prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges);
245 }
246 } 85 }
247#endif
248} 86}
249 87
250static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, 88static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges,
@@ -322,241 +160,127 @@ static void __init sbus_fixup_all_regs(struct sbus_dev *first_sdev)
322 } 160 }
323} 161}
324 162
325extern void register_proc_sparc_ioport(void); 163/* We preserve the "probe order" of these bus and device lists to give
326extern void firetruck_init(void); 164 * the same ordering as the old code.
165 */
166static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root)
167{
168 while (*root)
169 root = &(*root)->next;
170 *root = sbus;
171 sbus->next = NULL;
172}
327 173
328#ifdef CONFIG_SUN4 174static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root)
329extern void sun4_dvma_init(void); 175{
330#endif 176 while (*root)
177 root = &(*root)->next;
178 *root = sdev;
179 sdev->next = NULL;
180}
331 181
332static int __init sbus_init(void) 182static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus)
333{ 183{
334 int nd, this_sbus, sbus_devs, topnd, iommund; 184 dp = dp->child;
335 unsigned int sbus_clock; 185 while (dp) {
336 struct sbus_bus *sbus; 186 struct sbus_dev *sdev;
337 struct sbus_dev *this_dev;
338 int num_sbus = 0; /* How many did we find? */
339 187
340#ifdef CONFIG_SPARC32 188 sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
341 register_proc_sparc_ioport(); 189 if (sdev) {
342#endif 190 sdev_insert(sdev, &parent->child);
343 191
344#ifdef CONFIG_SUN4 192 sdev->bus = sbus;
345 sun4_dvma_init(); 193 sdev->parent = parent;
346 return 0; 194
347#endif 195 fill_sbus_device(dp, sdev);
348 196
349 topnd = prom_getchild(prom_root_node); 197 walk_children(dp, sdev, sbus);
350
351 /* Finding the first sbus is a special case... */
352 iommund = 0;
353 if(sparc_cpu_model == sun4u) {
354 nd = prom_searchsiblings(topnd, "sbus");
355 if(nd == 0) {
356#ifdef CONFIG_PCI
357 if (!pcic_present()) {
358 prom_printf("Neither SBUS nor PCI found.\n");
359 prom_halt();
360 } else {
361#ifdef CONFIG_SPARC64
362 firetruck_init();
363#endif
364 }
365 return 0;
366#else
367 prom_printf("YEEE, UltraSparc sbus not found\n");
368 prom_halt();
369#endif
370 }
371 } else if(sparc_cpu_model == sun4d) {
372 if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 ||
373 (nd = prom_getchild(iommund)) == 0 ||
374 (nd = prom_searchsiblings(nd, "sbi")) == 0) {
375 panic("sbi not found");
376 }
377 } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) {
378 if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 ||
379 (nd = prom_getchild(iommund)) == 0 ||
380 (nd = prom_searchsiblings(nd, "sbus")) == 0) {
381#ifdef CONFIG_PCI
382 if (!pcic_present()) {
383 prom_printf("Neither SBUS nor PCI found.\n");
384 prom_halt();
385 }
386 return 0;
387#else
388 /* No reason to run further - the data access trap will occur. */
389 panic("sbus not found");
390#endif
391 } 198 }
199 dp = dp->sibling;
392 } 200 }
201}
393 202
394 /* Ok, we've found the first one, allocate first SBus struct 203static void __init build_one_sbus(struct device_node *dp, int num_sbus)
395 * and place in chain. 204{
396 */ 205 struct sbus_bus *sbus;
397 sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); 206 unsigned int sbus_clock;
398 sbus->next = NULL; 207 struct device_node *dev_dp;
399 sbus->prom_node = nd;
400 this_sbus = nd;
401 208
402 if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d) 209 sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
403 iommu_init(iommund, sbus); 210 if (!sbus)
211 return;
404 212
405 /* Loop until we find no more SBUS's */ 213 sbus_insert(sbus, &sbus_root);
406 while(this_sbus) { 214 sbus->prom_node = dp->node;
407#ifdef CONFIG_SPARC64
408 /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */
409 if(sparc_cpu_model == sun4u) {
410 extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus);
411 215
412 sbus_iommu_init(this_sbus, sbus); 216 sbus_setup_iommu(sbus, dp);
413 }
414#endif /* CONFIG_SPARC64 */
415
416#ifdef CONFIG_SPARC32
417 if (sparc_cpu_model == sun4d)
418 iounit_init(this_sbus, iommund, sbus);
419#endif /* CONFIG_SPARC32 */
420 printk("sbus%d: ", num_sbus);
421 sbus_clock = prom_getint(this_sbus, "clock-frequency");
422 if(sbus_clock == -1)
423 sbus_clock = (25*1000*1000);
424 printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),
425 (int) (((sbus_clock/1000)%1000 != 0) ?
426 (((sbus_clock/1000)%1000) + 1000) : 0));
427
428 prom_getstring(this_sbus, "name",
429 sbus->prom_name, sizeof(sbus->prom_name));
430 sbus->clock_freq = sbus_clock;
431#ifdef CONFIG_SPARC32
432 if (sparc_cpu_model == sun4d) {
433 sbus->devid = prom_getint(iommund, "device-id");
434 sbus->board = prom_getint(iommund, "board#");
435 }
436#endif
437
438 sbus_bus_ranges_init(iommund, sbus);
439
440 sbus_devs = prom_getchild(this_sbus);
441 if (!sbus_devs) {
442 sbus->devices = NULL;
443 goto next_bus;
444 }
445 217
446 sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 218 printk("sbus%d: ", num_sbus);
447
448 this_dev = sbus->devices;
449 this_dev->next = NULL;
450
451 this_dev->bus = sbus;
452 this_dev->parent = NULL;
453 fill_sbus_device(sbus_devs, this_dev);
454
455 /* Should we traverse for children? */
456 if(prom_getchild(sbus_devs)) {
457 /* Allocate device node */
458 this_dev->child = kmalloc(sizeof(struct sbus_dev),
459 GFP_ATOMIC);
460 /* Fill it */
461 this_dev->child->bus = sbus;
462 this_dev->child->next = NULL;
463 fill_sbus_device(prom_getchild(sbus_devs),
464 this_dev->child);
465 sbus_do_child_siblings(prom_getchild(sbus_devs),
466 this_dev->child,
467 this_dev,
468 sbus);
469 } else {
470 this_dev->child = NULL;
471 }
472 219
473 while((sbus_devs = prom_getsibling(sbus_devs)) != 0) { 220 sbus_clock = of_getintprop_default(dp, "clock-frequency",
474 /* Allocate device node */ 221 (25*1000*1000));
475 this_dev->next = kmalloc(sizeof(struct sbus_dev), 222 sbus->clock_freq = sbus_clock;
476 GFP_ATOMIC); 223
477 this_dev = this_dev->next; 224 printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000),
478 this_dev->next = NULL; 225 (int) (((sbus_clock/1000)%1000 != 0) ?
479 226 (((sbus_clock/1000)%1000) + 1000) : 0));
480 /* Fill it */ 227
481 this_dev->bus = sbus; 228 strcpy(sbus->prom_name, dp->name);
482 this_dev->parent = NULL; 229
483 fill_sbus_device(sbus_devs, this_dev); 230 sbus_setup_arch_props(sbus, dp);
484 231
485 /* Is there a child node hanging off of us? */ 232 sbus_bus_ranges_init(dp, sbus);
486 if(prom_getchild(sbus_devs)) { 233
487 /* Get new device struct */ 234 sbus->ofdev.node = dp;
488 this_dev->child = kmalloc(sizeof(struct sbus_dev), 235 sbus->ofdev.dev.parent = NULL;
489 GFP_ATOMIC); 236 sbus->ofdev.dev.bus = &sbus_bus_type;
490 /* Fill it */ 237 strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name);
491 this_dev->child->bus = sbus; 238
492 this_dev->child->next = NULL; 239 if (of_device_register(&sbus->ofdev) != 0)
493 fill_sbus_device(prom_getchild(sbus_devs), 240 printk(KERN_DEBUG "sbus: device registration error for %s!\n",
494 this_dev->child); 241 sbus->ofdev.dev.bus_id);
495 sbus_do_child_siblings(prom_getchild(sbus_devs), 242
496 this_dev->child, 243 dev_dp = dp->child;
497 this_dev, 244 while (dev_dp) {
498 sbus); 245 struct sbus_dev *sdev;
499 } else { 246
500 this_dev->child = NULL; 247 sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC);
501 } 248 if (sdev) {
249 sdev_insert(sdev, &sbus->devices);
250
251 sdev->bus = sbus;
252 sdev->parent = NULL;
253 fill_sbus_device(dev_dp, sdev);
254
255 walk_children(dev_dp, sdev, sbus);
502 } 256 }
257 dev_dp = dev_dp->sibling;
258 }
503 259
504 /* Walk all devices and apply parent ranges. */ 260 sbus_fixup_all_regs(sbus->devices);
505 sbus_fixup_all_regs(sbus->devices);
506 261
507 dvma_init(sbus); 262 dvma_init(sbus);
508 next_bus: 263}
264
265static int __init sbus_init(void)
266{
267 struct device_node *dp;
268 const char *sbus_name = "sbus";
269 int num_sbus = 0;
270
271 if (sbus_arch_preinit())
272 return 0;
273
274 if (sparc_cpu_model == sun4d)
275 sbus_name = "sbi";
276
277 for_each_node_by_name(dp, sbus_name) {
278 build_one_sbus(dp, num_sbus);
509 num_sbus++; 279 num_sbus++;
510 if(sparc_cpu_model == sun4u) {
511 this_sbus = prom_getsibling(this_sbus);
512 if(!this_sbus)
513 break;
514 this_sbus = prom_searchsiblings(this_sbus, "sbus");
515 } else if(sparc_cpu_model == sun4d) {
516 iommund = prom_getsibling(iommund);
517 if(!iommund)
518 break;
519 iommund = prom_searchsiblings(iommund, "io-unit");
520 if(!iommund)
521 break;
522 this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi");
523 } else {
524 this_sbus = prom_getsibling(this_sbus);
525 if(!this_sbus)
526 break;
527 this_sbus = prom_searchsiblings(this_sbus, "sbus");
528 }
529 if(this_sbus) {
530 sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC);
531 sbus = sbus->next;
532 sbus->next = NULL;
533 sbus->prom_node = this_sbus;
534 } else {
535 break;
536 }
537 } /* while(this_sbus) */
538 280
539 if (sparc_cpu_model == sun4d) {
540 extern void sun4d_init_sbi_irq(void);
541 sun4d_init_sbi_irq();
542 }
543
544#ifdef CONFIG_SPARC64
545 if (sparc_cpu_model == sun4u) {
546 firetruck_init();
547 } 281 }
548#endif 282
549#ifdef CONFIG_SUN_AUXIO 283 sbus_arch_postinit();
550 if (sparc_cpu_model == sun4u)
551 auxio_probe ();
552#endif
553#ifdef CONFIG_SPARC64
554 if (sparc_cpu_model == sun4u) {
555 extern void clock_probe(void);
556
557 clock_probe();
558 }
559#endif
560 284
561 return 0; 285 return 0;
562} 286}
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index 0a3e45d7a972..ddb512463b45 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -1,7 +1,6 @@
1/* $Id: esp.c,v 1.101 2002/01/15 06:48:55 davem Exp $ 1/* esp.c: ESP Sun SCSI driver.
2 * esp.c: EnhancedScsiProcessor Sun SCSI driver code.
3 * 2 *
4 * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) 3 * Copyright (C) 1995, 1998, 2006 David S. Miller (davem@davemloft.net)
5 */ 4 */
6 5
7/* TODO: 6/* TODO:
@@ -185,11 +184,6 @@ enum {
185/*5*/ do_intr_end 184/*5*/ do_intr_end
186}; 185};
187 186
188/* The master ring of all esp hosts we are managing in this driver. */
189static struct esp *espchain;
190static DEFINE_SPINLOCK(espchain_lock);
191static int esps_running = 0;
192
193/* Forward declarations. */ 187/* Forward declarations. */
194static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs); 188static irqreturn_t esp_intr(int irq, void *dev_id, struct pt_regs *pregs);
195 189
@@ -694,36 +688,6 @@ static void __init esp_bootup_reset(struct esp *esp)
694 sbus_readb(esp->eregs + ESP_INTRPT); 688 sbus_readb(esp->eregs + ESP_INTRPT);
695} 689}
696 690
697static void esp_chain_add(struct esp *esp)
698{
699 spin_lock_irq(&espchain_lock);
700 if (espchain) {
701 struct esp *elink = espchain;
702 while (elink->next)
703 elink = elink->next;
704 elink->next = esp;
705 } else {
706 espchain = esp;
707 }
708 esp->next = NULL;
709 spin_unlock_irq(&espchain_lock);
710}
711
712static void esp_chain_del(struct esp *esp)
713{
714 spin_lock_irq(&espchain_lock);
715 if (espchain == esp) {
716 espchain = esp->next;
717 } else {
718 struct esp *elink = espchain;
719 while (elink->next != esp)
720 elink = elink->next;
721 elink->next = esp->next;
722 }
723 esp->next = NULL;
724 spin_unlock_irq(&espchain_lock);
725}
726
727static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev) 691static int __init esp_find_dvma(struct esp *esp, struct sbus_dev *dma_sdev)
728{ 692{
729 struct sbus_dev *sdev = esp->sdev; 693 struct sbus_dev *sdev = esp->sdev;
@@ -830,19 +794,20 @@ static int __init esp_register_irq(struct esp *esp)
830static void __init esp_get_scsi_id(struct esp *esp) 794static void __init esp_get_scsi_id(struct esp *esp)
831{ 795{
832 struct sbus_dev *sdev = esp->sdev; 796 struct sbus_dev *sdev = esp->sdev;
797 struct device_node *dp = sdev->ofdev.node;
833 798
834 esp->scsi_id = prom_getintdefault(esp->prom_node, 799 esp->scsi_id = of_getintprop_default(dp,
835 "initiator-id", 800 "initiator-id",
836 -1); 801 -1);
837 if (esp->scsi_id == -1) 802 if (esp->scsi_id == -1)
838 esp->scsi_id = prom_getintdefault(esp->prom_node, 803 esp->scsi_id = of_getintprop_default(dp,
839 "scsi-initiator-id", 804 "scsi-initiator-id",
840 -1); 805 -1);
841 if (esp->scsi_id == -1) 806 if (esp->scsi_id == -1)
842 esp->scsi_id = (sdev->bus == NULL) ? 7 : 807 esp->scsi_id = (sdev->bus == NULL) ? 7 :
843 prom_getintdefault(sdev->bus->prom_node, 808 of_getintprop_default(sdev->bus->ofdev.node,
844 "scsi-initiator-id", 809 "scsi-initiator-id",
845 7); 810 7);
846 esp->ehost->this_id = esp->scsi_id; 811 esp->ehost->this_id = esp->scsi_id;
847 esp->scsi_id_mask = (1 << esp->scsi_id); 812 esp->scsi_id_mask = (1 << esp->scsi_id);
848 813
@@ -1067,28 +1032,30 @@ static void __init esp_init_swstate(struct esp *esp)
1067 esp->prev_hme_dmacsr = 0xffffffff; 1032 esp->prev_hme_dmacsr = 0xffffffff;
1068} 1033}
1069 1034
1070static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_dev *esp_dev, 1035static int __init detect_one_esp(struct scsi_host_template *tpnt,
1071 struct sbus_dev *espdma, struct sbus_bus *sbus, 1036 struct device *dev,
1072 int id, int hme) 1037 struct sbus_dev *esp_dev,
1038 struct sbus_dev *espdma,
1039 struct sbus_bus *sbus,
1040 int hme)
1073{ 1041{
1074 struct Scsi_Host *esp_host = scsi_register(tpnt, sizeof(struct esp)); 1042 static int instance;
1043 struct Scsi_Host *esp_host = scsi_host_alloc(tpnt, sizeof(struct esp));
1075 struct esp *esp; 1044 struct esp *esp;
1076 1045
1077 if (!esp_host) { 1046 if (!esp_host)
1078 printk("ESP: Cannot register SCSI host\n"); 1047 return -ENOMEM;
1079 return -1; 1048
1080 }
1081 if (hme) 1049 if (hme)
1082 esp_host->max_id = 16; 1050 esp_host->max_id = 16;
1083 esp = (struct esp *) esp_host->hostdata; 1051 esp = (struct esp *) esp_host->hostdata;
1084 esp->ehost = esp_host; 1052 esp->ehost = esp_host;
1085 esp->sdev = esp_dev; 1053 esp->sdev = esp_dev;
1086 esp->esp_id = id; 1054 esp->esp_id = instance;
1087 esp->prom_node = esp_dev->prom_node; 1055 esp->prom_node = esp_dev->prom_node;
1088 prom_getstring(esp->prom_node, "name", esp->prom_name, 1056 prom_getstring(esp->prom_node, "name", esp->prom_name,
1089 sizeof(esp->prom_name)); 1057 sizeof(esp->prom_name));
1090 1058
1091 esp_chain_add(esp);
1092 if (esp_find_dvma(esp, espdma) < 0) 1059 if (esp_find_dvma(esp, espdma) < 0)
1093 goto fail_unlink; 1060 goto fail_unlink;
1094 if (esp_map_regs(esp, hme) < 0) { 1061 if (esp_map_regs(esp, hme) < 0) {
@@ -1115,8 +1082,19 @@ static int __init detect_one_esp(struct scsi_host_template *tpnt, struct sbus_de
1115 1082
1116 esp_bootup_reset(esp); 1083 esp_bootup_reset(esp);
1117 1084
1085 if (scsi_add_host(esp_host, dev))
1086 goto fail_free_irq;
1087
1088 dev_set_drvdata(&esp_dev->ofdev.dev, esp);
1089
1090 scsi_scan_host(esp_host);
1091 instance++;
1092
1118 return 0; 1093 return 0;
1119 1094
1095fail_free_irq:
1096 free_irq(esp->ehost->irq, esp);
1097
1120fail_unmap_cmdarea: 1098fail_unmap_cmdarea:
1121 sbus_free_consistent(esp->sdev, 16, 1099 sbus_free_consistent(esp->sdev, 16,
1122 (void *) esp->esp_command, 1100 (void *) esp->esp_command,
@@ -1129,119 +1107,98 @@ fail_dvma_release:
1129 esp->dma->allocated = 0; 1107 esp->dma->allocated = 0;
1130 1108
1131fail_unlink: 1109fail_unlink:
1132 esp_chain_del(esp); 1110 scsi_host_put(esp_host);
1133 scsi_unregister(esp_host);
1134 return -1; 1111 return -1;
1135} 1112}
1136 1113
1137/* Detecting ESP chips on the machine. This is the simple and easy 1114/* Detecting ESP chips on the machine. This is the simple and easy
1138 * version. 1115 * version.
1139 */ 1116 */
1117static int __devexit esp_remove_common(struct esp *esp)
1118{
1119 unsigned int irq = esp->ehost->irq;
1120
1121 scsi_remove_host(esp->ehost);
1122
1123 ESP_INTSOFF(esp->dregs);
1124#if 0
1125 esp_reset_dma(esp);
1126 esp_reset_esp(esp);
1127#endif
1128
1129 free_irq(irq, esp);
1130 sbus_free_consistent(esp->sdev, 16,
1131 (void *) esp->esp_command, esp->esp_command_dvma);
1132 sbus_iounmap(esp->eregs, ESP_REG_SIZE);
1133 esp->dma->allocated = 0;
1134
1135 scsi_host_put(esp->ehost);
1136
1137 return 0;
1138}
1139
1140 1140
1141#ifdef CONFIG_SUN4 1141#ifdef CONFIG_SUN4
1142 1142
1143#include <asm/sun4paddr.h> 1143#include <asm/sun4paddr.h>
1144 1144
1145static int __init esp_detect(struct scsi_host_template *tpnt) 1145static struct sbus_dev sun4_esp_dev;
1146{
1147 static struct sbus_dev esp_dev;
1148 int esps_in_use = 0;
1149
1150 espchain = NULL;
1151 1146
1147static int __init esp_sun4_probe(struct scsi_host_template *tpnt)
1148{
1152 if (sun4_esp_physaddr) { 1149 if (sun4_esp_physaddr) {
1153 memset (&esp_dev, 0, sizeof(esp_dev)); 1150 memset(&sun4_esp_dev, 0, sizeof(esp_dev));
1154 esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr; 1151 sun4_esp_dev.reg_addrs[0].phys_addr = sun4_esp_physaddr;
1155 esp_dev.irqs[0] = 4; 1152 sun4_esp_dev.irqs[0] = 4;
1156 esp_dev.resource[0].start = sun4_esp_physaddr; 1153 sun4_esp_dev.resource[0].start = sun4_esp_physaddr;
1157 esp_dev.resource[0].end = sun4_esp_physaddr + ESP_REG_SIZE - 1; 1154 sun4_esp_dev.resource[0].end =
1158 esp_dev.resource[0].flags = IORESOURCE_IO; 1155 sun4_esp_physaddr + ESP_REG_SIZE - 1;
1159 1156 sun4_esp_dev.resource[0].flags = IORESOURCE_IO;
1160 if (!detect_one_esp(tpnt, &esp_dev, NULL, NULL, 0, 0)) 1157
1161 esps_in_use++; 1158 return detect_one_esp(tpnt, NULL,
1162 printk("ESP: Total of 1 ESP hosts found, %d actually in use.\n", esps_in_use); 1159 &sun4_esp_dev, NULL, NULL, 0);
1163 esps_running = esps_in_use;
1164 } 1160 }
1165 return esps_in_use; 1161 return 0;
1166} 1162}
1167 1163
1168#else /* !CONFIG_SUN4 */ 1164static int __devexit esp_sun4_remove(void)
1169
1170static int __init esp_detect(struct scsi_host_template *tpnt)
1171{ 1165{
1172 struct sbus_bus *sbus; 1166 struct esp *esp = dev_get_drvdata(&dev->dev);
1173 struct sbus_dev *esp_dev, *sbdev_iter;
1174 int nesps = 0, esps_in_use = 0;
1175 1167
1176 espchain = 0; 1168 return esp_remove_common(esp);
1177 if (!sbus_root) {
1178#ifdef CONFIG_PCI
1179 return 0;
1180#else
1181 panic("No SBUS in esp_detect()");
1182#endif
1183 }
1184 for_each_sbus(sbus) {
1185 for_each_sbusdev(sbdev_iter, sbus) {
1186 struct sbus_dev *espdma = NULL;
1187 int hme = 0;
1188
1189 /* Is it an esp sbus device? */
1190 esp_dev = sbdev_iter;
1191 if (strcmp(esp_dev->prom_name, "esp") &&
1192 strcmp(esp_dev->prom_name, "SUNW,esp")) {
1193 if (!strcmp(esp_dev->prom_name, "SUNW,fas")) {
1194 hme = 1;
1195 espdma = esp_dev;
1196 } else {
1197 if (!esp_dev->child ||
1198 (strcmp(esp_dev->prom_name, "espdma") &&
1199 strcmp(esp_dev->prom_name, "dma")))
1200 continue; /* nope... */
1201 espdma = esp_dev;
1202 esp_dev = esp_dev->child;
1203 if (strcmp(esp_dev->prom_name, "esp") &&
1204 strcmp(esp_dev->prom_name, "SUNW,esp"))
1205 continue; /* how can this happen? */
1206 }
1207 }
1208
1209 if (detect_one_esp(tpnt, esp_dev, espdma, sbus, nesps++, hme) < 0)
1210 continue;
1211
1212 esps_in_use++;
1213 } /* for each sbusdev */
1214 } /* for each sbus */
1215 printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,
1216 esps_in_use);
1217 esps_running = esps_in_use;
1218 return esps_in_use;
1219} 1169}
1220 1170
1221#endif /* !CONFIG_SUN4 */ 1171#else /* !CONFIG_SUN4 */
1222 1172
1223/* 1173static int __devinit esp_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1224 */
1225static int esp_release(struct Scsi_Host *host)
1226{ 1174{
1227 struct esp *esp = (struct esp *) host->hostdata; 1175 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1176 struct device_node *dp = dev->node;
1177 struct sbus_dev *dma_sdev = NULL;
1178 int hme = 0;
1179
1180 if (dp->parent &&
1181 (!strcmp(dp->parent->name, "espdma") ||
1182 !strcmp(dp->parent->name, "dma")))
1183 dma_sdev = sdev->parent;
1184 else if (!strcmp(dp->name, "SUNW,fas")) {
1185 dma_sdev = sdev;
1186 hme = 1;
1187 }
1228 1188
1229 ESP_INTSOFF(esp->dregs); 1189 return detect_one_esp(match->data, &dev->dev,
1230#if 0 1190 sdev, dma_sdev, sdev->bus, hme);
1231 esp_reset_dma(esp); 1191}
1232 esp_reset_esp(esp);
1233#endif
1234 1192
1235 free_irq(esp->ehost->irq, esp); 1193static int __devexit esp_sbus_remove(struct of_device *dev)
1236 sbus_free_consistent(esp->sdev, 16, 1194{
1237 (void *) esp->esp_command, esp->esp_command_dvma); 1195 struct esp *esp = dev_get_drvdata(&dev->dev);
1238 sbus_iounmap(esp->eregs, ESP_REG_SIZE);
1239 esp->dma->allocated = 0;
1240 esp_chain_del(esp);
1241 1196
1242 return 0; 1197 return esp_remove_common(esp);
1243} 1198}
1244 1199
1200#endif /* !CONFIG_SUN4 */
1201
1245/* The info function will return whatever useful 1202/* The info function will return whatever useful
1246 * information the developer sees fit. If not provided, then 1203 * information the developer sees fit. If not provided, then
1247 * the name field will be used instead. 1204 * the name field will be used instead.
@@ -1415,18 +1372,11 @@ static int esp_host_info(struct esp *esp, char *ptr, off_t offset, int len)
1415static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, 1372static int esp_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1416 int length, int inout) 1373 int length, int inout)
1417{ 1374{
1418 struct esp *esp; 1375 struct esp *esp = (struct esp *) host->hostdata;
1419 1376
1420 if (inout) 1377 if (inout)
1421 return -EINVAL; /* not yet */ 1378 return -EINVAL; /* not yet */
1422 1379
1423 for_each_esp(esp) {
1424 if (esp->ehost == host)
1425 break;
1426 }
1427 if (!esp)
1428 return -EINVAL;
1429
1430 if (start) 1380 if (start)
1431 *start = buffer; 1381 *start = buffer;
1432 1382
@@ -4377,15 +4327,12 @@ static void esp_slave_destroy(struct scsi_device *SDptr)
4377 SDptr->hostdata = NULL; 4327 SDptr->hostdata = NULL;
4378} 4328}
4379 4329
4380static struct scsi_host_template driver_template = { 4330static struct scsi_host_template esp_template = {
4381 .proc_name = "esp", 4331 .module = THIS_MODULE,
4382 .proc_info = esp_proc_info, 4332 .name = "esp",
4383 .name = "Sun ESP 100/100a/200", 4333 .info = esp_info,
4384 .detect = esp_detect,
4385 .slave_alloc = esp_slave_alloc, 4334 .slave_alloc = esp_slave_alloc,
4386 .slave_destroy = esp_slave_destroy, 4335 .slave_destroy = esp_slave_destroy,
4387 .release = esp_release,
4388 .info = esp_info,
4389 .queuecommand = esp_queue, 4336 .queuecommand = esp_queue,
4390 .eh_abort_handler = esp_abort, 4337 .eh_abort_handler = esp_abort,
4391 .eh_bus_reset_handler = esp_reset, 4338 .eh_bus_reset_handler = esp_reset,
@@ -4394,12 +4341,58 @@ static struct scsi_host_template driver_template = {
4394 .sg_tablesize = SG_ALL, 4341 .sg_tablesize = SG_ALL,
4395 .cmd_per_lun = 1, 4342 .cmd_per_lun = 1,
4396 .use_clustering = ENABLE_CLUSTERING, 4343 .use_clustering = ENABLE_CLUSTERING,
4344 .proc_name = "esp",
4345 .proc_info = esp_proc_info,
4346};
4347
4348#ifndef CONFIG_SUN4
4349static struct of_device_id esp_match[] = {
4350 {
4351 .name = "SUNW,esp",
4352 .data = &esp_template,
4353 },
4354 {
4355 .name = "SUNW,fas",
4356 .data = &esp_template,
4357 },
4358 {
4359 .name = "esp",
4360 .data = &esp_template,
4361 },
4362 {},
4363};
4364MODULE_DEVICE_TABLE(of, esp_match);
4365
4366static struct of_platform_driver esp_sbus_driver = {
4367 .name = "esp",
4368 .match_table = esp_match,
4369 .probe = esp_sbus_probe,
4370 .remove = __devexit_p(esp_sbus_remove),
4397}; 4371};
4372#endif
4373
4374static int __init esp_init(void)
4375{
4376#ifdef CONFIG_SUN4
4377 return esp_sun4_probe(&esp_template);
4378#else
4379 return of_register_driver(&esp_sbus_driver, &sbus_bus_type);
4380#endif
4381}
4398 4382
4399#include "scsi_module.c" 4383static void __exit esp_exit(void)
4384{
4385#ifdef CONFIG_SUN4
4386 esp_sun4_remove();
4387#else
4388 of_unregister_driver(&esp_sbus_driver);
4389#endif
4390}
4400 4391
4401MODULE_DESCRIPTION("EnhancedScsiProcessor Sun SCSI driver"); 4392MODULE_DESCRIPTION("ESP Sun SCSI driver");
4402MODULE_AUTHOR("David S. Miller (davem@redhat.com)"); 4393MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
4403MODULE_LICENSE("GPL"); 4394MODULE_LICENSE("GPL");
4404MODULE_VERSION(DRV_VERSION); 4395MODULE_VERSION(DRV_VERSION);
4405 4396
4397module_init(esp_init);
4398module_exit(esp_exit);
diff --git a/drivers/scsi/esp.h b/drivers/scsi/esp.h
index 73f7d6968ab6..a98cda9121fc 100644
--- a/drivers/scsi/esp.h
+++ b/drivers/scsi/esp.h
@@ -403,8 +403,4 @@ struct esp {
403#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000)) 403#define ESP_MHZ_TO_CYCLE(mhertz) ((1000000000) / ((mhertz) / 1000))
404#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000)) 404#define ESP_TICK(ccf, cycle) ((7682 * (ccf) * (cycle) / 1000))
405 405
406/* For our interrupt engine. */
407#define for_each_esp(esp) \
408 for((esp) = espchain; (esp); (esp) = (esp)->next)
409
410#endif /* !(_SPARC_ESP_H) */ 406#endif /* !(_SPARC_ESP_H) */
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 2203103adced..329ead263714 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -1,6 +1,6 @@
1/* qlogicpti.c: Performance Technologies QlogicISP sbus card driver. 1/* qlogicpti.c: Performance Technologies QlogicISP sbus card driver.
2 * 2 *
3 * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) 3 * Copyright (C) 1996, 2006 David S. Miller (davem@davemloft.net)
4 * 4 *
5 * A lot of this driver was directly stolen from Erik H. Moe's PCI 5 * A lot of this driver was directly stolen from Erik H. Moe's PCI
6 * Qlogic ISP driver. Mucho kudos to him for this code. 6 * Qlogic ISP driver. Mucho kudos to him for this code.
@@ -46,8 +46,6 @@
46#include <scsi/scsi_tcq.h> 46#include <scsi/scsi_tcq.h>
47#include <scsi/scsi_host.h> 47#include <scsi/scsi_host.h>
48 48
49
50
51#define MAX_TARGETS 16 49#define MAX_TARGETS 16
52#define MAX_LUNS 8 /* 32 for 1.31 F/W */ 50#define MAX_LUNS 8 /* 32 for 1.31 F/W */
53 51
@@ -57,7 +55,6 @@
57 55
58static struct qlogicpti *qptichain = NULL; 56static struct qlogicpti *qptichain = NULL;
59static DEFINE_SPINLOCK(qptichain_lock); 57static DEFINE_SPINLOCK(qptichain_lock);
60static int qptis_running = 0;
61 58
62#define PACKB(a, b) (((a)<<4)|(b)) 59#define PACKB(a, b) (((a)<<4)|(b))
63 60
@@ -815,173 +812,6 @@ static int __init qpti_map_queues(struct qlogicpti *qpti)
815 return 0; 812 return 0;
816} 813}
817 814
818/* Detect all PTI Qlogic ISP's in the machine. */
819static int __init qlogicpti_detect(struct scsi_host_template *tpnt)
820{
821 struct qlogicpti *qpti;
822 struct Scsi_Host *qpti_host;
823 struct sbus_bus *sbus;
824 struct sbus_dev *sdev;
825 int nqptis = 0, nqptis_in_use = 0;
826
827 tpnt->proc_name = "qlogicpti";
828 for_each_sbus(sbus) {
829 for_each_sbusdev(sdev, sbus) {
830 /* Is this a red snapper? */
831 if (strcmp(sdev->prom_name, "ptisp") &&
832 strcmp(sdev->prom_name, "PTI,ptisp") &&
833 strcmp(sdev->prom_name, "QLGC,isp") &&
834 strcmp(sdev->prom_name, "SUNW,isp"))
835 continue;
836
837 /* Sometimes Antares cards come up not completely
838 * setup, and we get a report of a zero IRQ.
839 * Skip over them in such cases so we survive.
840 */
841 if (sdev->irqs[0] == 0) {
842 printk("qpti%d: Adapter reports no interrupt, "
843 "skipping over this card.", nqptis);
844 continue;
845 }
846
847 /* Yep, register and allocate software state. */
848 qpti_host = scsi_register(tpnt, sizeof(struct qlogicpti));
849 if (!qpti_host) {
850 printk("QPTI: Cannot register PTI Qlogic ISP SCSI host");
851 continue;
852 }
853 qpti = (struct qlogicpti *) qpti_host->hostdata;
854
855 /* We are wide capable, 16 targets. */
856 qpti_host->max_id = MAX_TARGETS;
857
858 /* Setup back pointers and misc. state. */
859 qpti->qhost = qpti_host;
860 qpti->sdev = sdev;
861 qpti->qpti_id = nqptis++;
862 qpti->prom_node = sdev->prom_node;
863 prom_getstring(qpti->prom_node, "name",
864 qpti->prom_name,
865 sizeof(qpti->prom_name));
866
867 /* This is not correct, actually. There's a switch
868 * on the PTI cards that put them into "emulation"
869 * mode- i.e., report themselves as QLGC,isp
870 * instead of PTI,ptisp. The only real substantive
871 * difference between non-pti and pti cards is
872 * the tmon register. Which is possibly even
873 * there for Qlogic cards, but non-functional.
874 */
875 qpti->is_pti = (strcmp (qpti->prom_name, "QLGC,isp") != 0);
876
877 qpti_chain_add(qpti);
878 if (qpti_map_regs(qpti) < 0)
879 goto fail_unlink;
880
881 if (qpti_register_irq(qpti) < 0)
882 goto fail_unmap_regs;
883
884 qpti_get_scsi_id(qpti);
885 qpti_get_bursts(qpti);
886 qpti_get_clock(qpti);
887
888 /* Clear out scsi_cmnd array. */
889 memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots));
890
891 if (qpti_map_queues(qpti) < 0)
892 goto fail_free_irq;
893
894 /* Load the firmware. */
895 if (qlogicpti_load_firmware(qpti))
896 goto fail_unmap_queues;
897 if (qpti->is_pti) {
898 /* Check the PTI status reg. */
899 if (qlogicpti_verify_tmon(qpti))
900 goto fail_unmap_queues;
901 }
902
903 /* Reset the ISP and init res/req queues. */
904 if (qlogicpti_reset_hardware(qpti_host))
905 goto fail_unmap_queues;
906
907 printk("(Firmware v%d.%d.%d)", qpti->fware_majrev,
908 qpti->fware_minrev, qpti->fware_micrev);
909 {
910 char buffer[60];
911
912 prom_getstring (qpti->prom_node,
913 "isp-fcode", buffer, 60);
914 if (buffer[0])
915 printk("(Firmware %s)", buffer);
916 if (prom_getbool(qpti->prom_node, "differential"))
917 qpti->differential = 1;
918 }
919
920 printk (" [%s Wide, using %s interface]\n",
921 (qpti->ultra ? "Ultra" : "Fast"),
922 (qpti->differential ? "differential" : "single ended"));
923
924 nqptis_in_use++;
925 continue;
926
927 fail_unmap_queues:
928#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
929 sbus_free_consistent(qpti->sdev,
930 QSIZE(RES_QUEUE_LEN),
931 qpti->res_cpu, qpti->res_dvma);
932 sbus_free_consistent(qpti->sdev,
933 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
934 qpti->req_cpu, qpti->req_dvma);
935#undef QSIZE
936 fail_free_irq:
937 free_irq(qpti->irq, qpti);
938
939 fail_unmap_regs:
940 sbus_iounmap(qpti->qregs,
941 qpti->sdev->reg_addrs[0].reg_size);
942 if (qpti->is_pti)
943 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
944 fail_unlink:
945 qpti_chain_del(qpti);
946 scsi_unregister(qpti->qhost);
947 }
948 }
949 if (nqptis)
950 printk("QPTI: Total of %d PTI Qlogic/ISP hosts found, %d actually in use.\n",
951 nqptis, nqptis_in_use);
952 qptis_running = nqptis_in_use;
953 return nqptis;
954}
955
956static int qlogicpti_release(struct Scsi_Host *host)
957{
958 struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
959
960 /* Remove visibility from IRQ handlers. */
961 qpti_chain_del(qpti);
962
963 /* Shut up the card. */
964 sbus_writew(0, qpti->qregs + SBUS_CTRL);
965
966 /* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */
967 free_irq(qpti->irq, qpti);
968
969#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
970 sbus_free_consistent(qpti->sdev,
971 QSIZE(RES_QUEUE_LEN),
972 qpti->res_cpu, qpti->res_dvma);
973 sbus_free_consistent(qpti->sdev,
974 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
975 qpti->req_cpu, qpti->req_dvma);
976#undef QSIZE
977
978 sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size);
979 if (qpti->is_pti)
980 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
981
982 return 0;
983}
984
985const char *qlogicpti_info(struct Scsi_Host *host) 815const char *qlogicpti_info(struct Scsi_Host *host)
986{ 816{
987 static char buf[80]; 817 static char buf[80];
@@ -1551,9 +1381,9 @@ static int qlogicpti_reset(struct scsi_cmnd *Cmnd)
1551 return return_status; 1381 return return_status;
1552} 1382}
1553 1383
1554static struct scsi_host_template driver_template = { 1384static struct scsi_host_template qpti_template = {
1555 .detect = qlogicpti_detect, 1385 .module = THIS_MODULE,
1556 .release = qlogicpti_release, 1386 .name = "qlogicpti",
1557 .info = qlogicpti_info, 1387 .info = qlogicpti_info,
1558 .queuecommand = qlogicpti_queuecommand_slow, 1388 .queuecommand = qlogicpti_queuecommand_slow,
1559 .eh_abort_handler = qlogicpti_abort, 1389 .eh_abort_handler = qlogicpti_abort,
@@ -1565,8 +1395,189 @@ static struct scsi_host_template driver_template = {
1565 .use_clustering = ENABLE_CLUSTERING, 1395 .use_clustering = ENABLE_CLUSTERING,
1566}; 1396};
1567 1397
1398static int __devinit qpti_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1399{
1400 static int nqptis;
1401 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1402 struct device_node *dp = dev->node;
1403 struct scsi_host_template *tpnt = match->data;
1404 struct Scsi_Host *host;
1405 struct qlogicpti *qpti;
1406 char *fcode;
1407
1408 /* Sometimes Antares cards come up not completely
1409 * setup, and we get a report of a zero IRQ.
1410 */
1411 if (sdev->irqs[0] == 0)
1412 return -ENODEV;
1413
1414 host = scsi_host_alloc(tpnt, sizeof(struct qlogicpti));
1415 if (!host)
1416 return -ENOMEM;
1417
1418 qpti = (struct qlogicpti *) host->hostdata;
1419
1420 host->max_id = MAX_TARGETS;
1421 qpti->qhost = host;
1422 qpti->sdev = sdev;
1423 qpti->qpti_id = nqptis;
1424 qpti->prom_node = sdev->prom_node;
1425 strcpy(qpti->prom_name, sdev->ofdev.node->name);
1426 qpti->is_pti = strcmp(qpti->prom_name, "QLGC,isp");
1427
1428 if (qpti_map_regs(qpti) < 0)
1429 goto fail_unlink;
1430
1431 if (qpti_register_irq(qpti) < 0)
1432 goto fail_unmap_regs;
1433
1434 qpti_get_scsi_id(qpti);
1435 qpti_get_bursts(qpti);
1436 qpti_get_clock(qpti);
1437
1438 /* Clear out scsi_cmnd array. */
1439 memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots));
1440
1441 if (qpti_map_queues(qpti) < 0)
1442 goto fail_free_irq;
1443
1444 /* Load the firmware. */
1445 if (qlogicpti_load_firmware(qpti))
1446 goto fail_unmap_queues;
1447 if (qpti->is_pti) {
1448 /* Check the PTI status reg. */
1449 if (qlogicpti_verify_tmon(qpti))
1450 goto fail_unmap_queues;
1451 }
1452
1453 /* Reset the ISP and init res/req queues. */
1454 if (qlogicpti_reset_hardware(host))
1455 goto fail_unmap_queues;
1456
1457 if (scsi_add_host(host, &dev->dev))
1458 goto fail_unmap_queues;
1459
1460 printk("(Firmware v%d.%d.%d)", qpti->fware_majrev,
1461 qpti->fware_minrev, qpti->fware_micrev);
1462
1463 fcode = of_get_property(dp, "isp-fcode", NULL);
1464 if (fcode && fcode[0])
1465 printk("(Firmware %s)", fcode);
1466 if (of_find_property(dp, "differential", NULL) != NULL)
1467 qpti->differential = 1;
1468
1469 printk (" [%s Wide, using %s interface]\n",
1470 (qpti->ultra ? "Ultra" : "Fast"),
1471 (qpti->differential ? "differential" : "single ended"));
1472
1473 dev_set_drvdata(&sdev->ofdev.dev, qpti);
1474
1475 qpti_chain_add(qpti);
1476
1477 scsi_scan_host(host);
1478 nqptis++;
1479
1480 return 0;
1481
1482fail_unmap_queues:
1483#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
1484 sbus_free_consistent(qpti->sdev,
1485 QSIZE(RES_QUEUE_LEN),
1486 qpti->res_cpu, qpti->res_dvma);
1487 sbus_free_consistent(qpti->sdev,
1488 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
1489 qpti->req_cpu, qpti->req_dvma);
1490#undef QSIZE
1491
1492fail_unmap_regs:
1493 sbus_iounmap(qpti->qregs,
1494 qpti->sdev->reg_addrs[0].reg_size);
1495 if (qpti->is_pti)
1496 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
1497
1498fail_free_irq:
1499 free_irq(qpti->irq, qpti);
1500
1501fail_unlink:
1502 scsi_host_put(host);
1503
1504 return -ENODEV;
1505}
1506
1507static int __devexit qpti_sbus_remove(struct of_device *dev)
1508{
1509 struct qlogicpti *qpti = dev_get_drvdata(&dev->dev);
1510
1511 qpti_chain_del(qpti);
1512
1513 scsi_remove_host(qpti->qhost);
1514
1515 /* Shut up the card. */
1516 sbus_writew(0, qpti->qregs + SBUS_CTRL);
1517
1518 /* Free IRQ handler and unmap Qlogic,ISP and PTI status regs. */
1519 free_irq(qpti->irq, qpti);
1520
1521#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN)
1522 sbus_free_consistent(qpti->sdev,
1523 QSIZE(RES_QUEUE_LEN),
1524 qpti->res_cpu, qpti->res_dvma);
1525 sbus_free_consistent(qpti->sdev,
1526 QSIZE(QLOGICPTI_REQ_QUEUE_LEN),
1527 qpti->req_cpu, qpti->req_dvma);
1528#undef QSIZE
1529
1530 sbus_iounmap(qpti->qregs, qpti->sdev->reg_addrs[0].reg_size);
1531 if (qpti->is_pti)
1532 sbus_iounmap(qpti->sreg, sizeof(unsigned char));
1533
1534 scsi_host_put(qpti->qhost);
1535
1536 return 0;
1537}
1538
1539static struct of_device_id qpti_match[] = {
1540 {
1541 .name = "ptisp",
1542 .data = &qpti_template,
1543 },
1544 {
1545 .name = "PTI,ptisp",
1546 .data = &qpti_template,
1547 },
1548 {
1549 .name = "QLGC,isp",
1550 .data = &qpti_template,
1551 },
1552 {
1553 .name = "SUNW,isp",
1554 .data = &qpti_template,
1555 },
1556 {},
1557};
1558MODULE_DEVICE_TABLE(of, qpti_match);
1559
1560static struct of_platform_driver qpti_sbus_driver = {
1561 .name = "qpti",
1562 .match_table = qpti_match,
1563 .probe = qpti_sbus_probe,
1564 .remove = __devexit_p(qpti_sbus_remove),
1565};
1568 1566
1569#include "scsi_module.c" 1567static int __init qpti_init(void)
1568{
1569 return of_register_driver(&qpti_sbus_driver, &sbus_bus_type);
1570}
1571
1572static void __exit qpti_exit(void)
1573{
1574 of_unregister_driver(&qpti_sbus_driver);
1575}
1570 1576
1577MODULE_DESCRIPTION("QlogicISP SBUS driver");
1578MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
1571MODULE_LICENSE("GPL"); 1579MODULE_LICENSE("GPL");
1580MODULE_VERSION("2.0");
1572 1581
1582module_init(qpti_init);
1583module_exit(qpti_exit);
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index bef4a9622ed7..5b48ac22c9c5 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -354,21 +354,24 @@ config SERIAL_CLPS711X_CONSOLE
354 kernel at boot time.) 354 kernel at boot time.)
355 355
356config SERIAL_S3C2410 356config SERIAL_S3C2410
357 tristate "Samsung S3C2410 Serial port support" 357 tristate "Samsung S3C2410/S3C2440/S3C2442/S3C2412 Serial port support"
358 depends on ARM && ARCH_S3C2410 358 depends on ARM && ARCH_S3C2410
359 select SERIAL_CORE 359 select SERIAL_CORE
360 help 360 help
361 Support for the on-chip UARTs on the Samsung S3C2410X CPU, 361 Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
362 providing /dev/ttySAC0, 1 and 2 (note, some machines may not 362 providing /dev/ttySAC0, 1 and 2 (note, some machines may not
363 provide all of these ports, depending on how the serial port 363 provide all of these ports, depending on how the serial port
364 pins are configured. 364 pins are configured.
365 365
366 Currently this driver supports the UARTS on the S3C2410, S3C2440,
367 S3C2442, S3C2412 and S3C2413 CPUs.
368
366config SERIAL_S3C2410_CONSOLE 369config SERIAL_S3C2410_CONSOLE
367 bool "Support for console on S3C2410 serial port" 370 bool "Support for console on S3C2410 serial port"
368 depends on SERIAL_S3C2410=y 371 depends on SERIAL_S3C2410=y
369 select SERIAL_CORE_CONSOLE 372 select SERIAL_CORE_CONSOLE
370 help 373 help
371 Allow selection of the S3C2410 on-board serial ports for use as 374 Allow selection of the S3C24XX on-board serial ports for use as
372 an virtual console. 375 an virtual console.
373 376
374 Even if you say Y here, the currently visible virtual console 377 Even if you say Y here, the currently visible virtual console
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 53c2465bad2d..837b6da520b3 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -872,6 +872,8 @@ static const char *s3c24xx_serial_type(struct uart_port *port)
872 return "S3C2410"; 872 return "S3C2410";
873 case PORT_S3C2440: 873 case PORT_S3C2440:
874 return "S3C2440"; 874 return "S3C2440";
875 case PORT_S3C2412:
876 return "S3C2412";
875 default: 877 default:
876 return NULL; 878 return NULL;
877 } 879 }
@@ -1528,6 +1530,141 @@ static inline void s3c2440_serial_exit(void)
1528#define s3c2440_uart_inf_at NULL 1530#define s3c2440_uart_inf_at NULL
1529#endif /* CONFIG_CPU_S3C2440 */ 1531#endif /* CONFIG_CPU_S3C2440 */
1530 1532
1533#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
1534
1535static int s3c2412_serial_setsource(struct uart_port *port,
1536 struct s3c24xx_uart_clksrc *clk)
1537{
1538 unsigned long ucon = rd_regl(port, S3C2410_UCON);
1539
1540 ucon &= ~S3C2412_UCON_CLKMASK;
1541
1542 if (strcmp(clk->name, "uclk") == 0)
1543 ucon |= S3C2440_UCON_UCLK;
1544 else if (strcmp(clk->name, "pclk") == 0)
1545 ucon |= S3C2440_UCON_PCLK;
1546 else if (strcmp(clk->name, "usysclk") == 0)
1547 ucon |= S3C2412_UCON_USYSCLK;
1548 else {
1549 printk(KERN_ERR "unknown clock source %s\n", clk->name);
1550 return -EINVAL;
1551 }
1552
1553 wr_regl(port, S3C2410_UCON, ucon);
1554 return 0;
1555}
1556
1557
1558static int s3c2412_serial_getsource(struct uart_port *port,
1559 struct s3c24xx_uart_clksrc *clk)
1560{
1561 unsigned long ucon = rd_regl(port, S3C2410_UCON);
1562
1563 switch (ucon & S3C2412_UCON_CLKMASK) {
1564 case S3C2412_UCON_UCLK:
1565 clk->divisor = 1;
1566 clk->name = "uclk";
1567 break;
1568
1569 case S3C2412_UCON_PCLK:
1570 case S3C2412_UCON_PCLK2:
1571 clk->divisor = 1;
1572 clk->name = "pclk";
1573 break;
1574
1575 case S3C2412_UCON_USYSCLK:
1576 clk->divisor = 1;
1577 clk->name = "usysclk";
1578 break;
1579 }
1580
1581 return 0;
1582}
1583
1584static int s3c2412_serial_resetport(struct uart_port *port,
1585 struct s3c2410_uartcfg *cfg)
1586{
1587 unsigned long ucon = rd_regl(port, S3C2410_UCON);
1588
1589 dbg("%s: port=%p (%08lx), cfg=%p\n",
1590 __FUNCTION__, port, port->mapbase, cfg);
1591
1592 /* ensure we don't change the clock settings... */
1593
1594 ucon &= S3C2412_UCON_CLKMASK;
1595
1596 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
1597 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
1598
1599 /* reset both fifos */
1600
1601 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
1602 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
1603
1604 return 0;
1605}
1606
1607static struct s3c24xx_uart_info s3c2412_uart_inf = {
1608 .name = "Samsung S3C2412 UART",
1609 .type = PORT_S3C2412,
1610 .fifosize = 64,
1611 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
1612 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
1613 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
1614 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
1615 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
1616 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
1617 .get_clksrc = s3c2412_serial_getsource,
1618 .set_clksrc = s3c2412_serial_setsource,
1619 .reset_port = s3c2412_serial_resetport,
1620};
1621
1622/* device management */
1623
1624static int s3c2412_serial_probe(struct platform_device *dev)
1625{
1626 dbg("s3c2440_serial_probe: dev=%p\n", dev);
1627 return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
1628}
1629
1630static struct platform_driver s3c2412_serial_drv = {
1631 .probe = s3c2412_serial_probe,
1632 .remove = s3c24xx_serial_remove,
1633 .suspend = s3c24xx_serial_suspend,
1634 .resume = s3c24xx_serial_resume,
1635 .driver = {
1636 .name = "s3c2412-uart",
1637 .owner = THIS_MODULE,
1638 },
1639};
1640
1641
1642static inline int s3c2412_serial_init(void)
1643{
1644 return s3c24xx_serial_init(&s3c2412_serial_drv, &s3c2412_uart_inf);
1645}
1646
1647static inline void s3c2412_serial_exit(void)
1648{
1649 platform_driver_unregister(&s3c2412_serial_drv);
1650}
1651
1652#define s3c2412_uart_inf_at &s3c2412_uart_inf
1653#else
1654
1655static inline int s3c2412_serial_init(void)
1656{
1657 return 0;
1658}
1659
1660static inline void s3c2412_serial_exit(void)
1661{
1662}
1663
1664#define s3c2412_uart_inf_at NULL
1665#endif /* CONFIG_CPU_S3C2440 */
1666
1667
1531/* module initialisation code */ 1668/* module initialisation code */
1532 1669
1533static int __init s3c24xx_serial_modinit(void) 1670static int __init s3c24xx_serial_modinit(void)
@@ -1542,6 +1679,7 @@ static int __init s3c24xx_serial_modinit(void)
1542 1679
1543 s3c2400_serial_init(); 1680 s3c2400_serial_init();
1544 s3c2410_serial_init(); 1681 s3c2410_serial_init();
1682 s3c2412_serial_init();
1545 s3c2440_serial_init(); 1683 s3c2440_serial_init();
1546 1684
1547 return 0; 1685 return 0;
@@ -1551,6 +1689,7 @@ static void __exit s3c24xx_serial_modexit(void)
1551{ 1689{
1552 s3c2400_serial_exit(); 1690 s3c2400_serial_exit();
1553 s3c2410_serial_exit(); 1691 s3c2410_serial_exit();
1692 s3c2412_serial_exit();
1554 s3c2440_serial_exit(); 1693 s3c2440_serial_exit();
1555 1694
1556 uart_unregister_driver(&s3c24xx_uart_drv); 1695 uart_unregister_driver(&s3c24xx_uart_drv);
@@ -1773,6 +1912,8 @@ static int s3c24xx_serial_initconsole(void)
1773 info = s3c2410_uart_inf_at; 1912 info = s3c2410_uart_inf_at;
1774 } else if (strcmp(dev->name, "s3c2440-uart") == 0) { 1913 } else if (strcmp(dev->name, "s3c2440-uart") == 0) {
1775 info = s3c2440_uart_inf_at; 1914 info = s3c2440_uart_inf_at;
1915 } else if (strcmp(dev->name, "s3c2412-uart") == 0) {
1916 info = s3c2412_uart_inf_at;
1776 } else { 1917 } else {
1777 printk(KERN_ERR "s3c24xx: no driver for %s\n", dev->name); 1918 printk(KERN_ERR "s3c24xx: no driver for %s\n", dev->name);
1778 return 0; 1919 return 0;
@@ -1796,4 +1937,4 @@ console_initcall(s3c24xx_serial_initconsole);
1796 1937
1797MODULE_LICENSE("GPL"); 1938MODULE_LICENSE("GPL");
1798MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1939MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
1799MODULE_DESCRIPTION("Samsung S3C2410/S3C2440 Serial port driver"); 1940MODULE_DESCRIPTION("Samsung S3C2410/S3C2440/S3C2412 Serial port driver");
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c
index f137804b3133..ba22e256c6f7 100644
--- a/drivers/serial/sunhv.c
+++ b/drivers/serial/sunhv.c
@@ -427,31 +427,32 @@ static int __init hv_console_compatible(char *buf, int len)
427 427
428static unsigned int __init get_interrupt(void) 428static unsigned int __init get_interrupt(void)
429{ 429{
430 const char *cons_str = "console"; 430 struct device_node *dev_node;
431 const char *compat_str = "compatible";
432 int node = prom_getchild(sun4v_vdev_root);
433 char buf[64];
434 int err, len;
435
436 node = prom_searchsiblings(node, cons_str);
437 if (!node)
438 return 0;
439 431
440 len = prom_getproplen(node, compat_str); 432 dev_node = sun4v_vdev_root->child;
441 if (len == 0 || len == -1) 433 while (dev_node != NULL) {
442 return 0; 434 struct property *prop;
443 435
444 err = prom_getproperty(node, compat_str, buf, 64); 436 if (strcmp(dev_node->name, "console"))
445 if (err == -1) 437 goto next_sibling;
446 return 0; 438
439 prop = of_find_property(dev_node, "compatible", NULL);
440 if (!prop)
441 goto next_sibling;
447 442
448 if (!hv_console_compatible(buf, len)) 443 if (hv_console_compatible(prop->value, prop->length))
444 break;
445
446 next_sibling:
447 dev_node = dev_node->sibling;
448 }
449 if (!dev_node)
449 return 0; 450 return 0;
450 451
451 /* Ok, the this is the OBP node for the sun4v hypervisor 452 /* Ok, the this is the OBP node for the sun4v hypervisor
452 * console device. Decode the interrupt. 453 * console device. Decode the interrupt.
453 */ 454 */
454 return sun4v_vdev_device_interrupt(node); 455 return sun4v_vdev_device_interrupt(dev_node);
455} 456}
456 457
457static int __init sunhv_init(void) 458static int __init sunhv_init(void)
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
index bfbe9dc90cca..e4c0fd2d6a9d 100644
--- a/drivers/serial/sunsab.c
+++ b/drivers/serial/sunsab.c
@@ -984,19 +984,19 @@ static void __init for_each_sab_edev(void (*callback)(struct linux_ebus_device *
984 984
985 for_each_ebus(ebus) { 985 for_each_ebus(ebus) {
986 for_each_ebusdev(edev, ebus) { 986 for_each_ebusdev(edev, ebus) {
987 if (!strcmp(edev->prom_name, "se")) { 987 if (!strcmp(edev->prom_node->name, "se")) {
988 callback(edev, arg); 988 callback(edev, arg);
989 continue; 989 continue;
990 } else if (!strcmp(edev->prom_name, "serial")) { 990 } else if (!strcmp(edev->prom_node->name, "serial")) {
991 char compat[32]; 991 char *compat;
992 int clen; 992 int clen;
993 993
994 /* On RIO this can be an SE, check it. We could 994 /* On RIO this can be an SE, check it. We could
995 * just check ebus->is_rio, but this is more portable. 995 * just check ebus->is_rio, but this is more portable.
996 */ 996 */
997 clen = prom_getproperty(edev->prom_node, "compatible", 997 compat = of_get_property(edev->prom_node,
998 compat, sizeof(compat)); 998 "compatible", &clen);
999 if (clen > 0) { 999 if (compat && clen > 0) {
1000 if (strncmp(compat, "sab82532", 8) == 0) { 1000 if (strncmp(compat, "sab82532", 8) == 0) {
1001 callback(edev, arg); 1001 callback(edev, arg);
1002 continue; 1002 continue;
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 4cdb610cdd37..0268b307c01e 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1053,7 +1053,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
1053 */ 1053 */
1054 for_each_ebus(ebus) { 1054 for_each_ebus(ebus) {
1055 for_each_ebusdev(dev, ebus) { 1055 for_each_ebusdev(dev, ebus) {
1056 if (dev->prom_node == up->port_node) { 1056 if (dev->prom_node->node == up->port_node) {
1057 /* 1057 /*
1058 * The EBus is broken on sparc; it delivers 1058 * The EBus is broken on sparc; it delivers
1059 * virtual addresses in resources. Oh well... 1059 * virtual addresses in resources. Oh well...
@@ -1073,7 +1073,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up)
1073#ifdef CONFIG_SPARC64 1073#ifdef CONFIG_SPARC64
1074 for_each_isa(isa_br) { 1074 for_each_isa(isa_br) {
1075 for_each_isadev(isa_dev, isa_br) { 1075 for_each_isadev(isa_dev, isa_br) {
1076 if (isa_dev->prom_node == up->port_node) { 1076 if (isa_dev->prom_node->node == up->port_node) {
1077 /* Same on sparc64. Cool architecure... */ 1077 /* Same on sparc64. Cool architecure... */
1078 up->port.membase = (char *) isa_dev->resource.start; 1078 up->port.membase = (char *) isa_dev->resource.start;
1079 up->port.mapbase = isa_dev->resource.start; 1079 up->port.mapbase = isa_dev->resource.start;
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
index 5b6569728a9c..76c9bac9271f 100644
--- a/drivers/serial/sunzilog.c
+++ b/drivers/serial/sunzilog.c
@@ -1106,7 +1106,7 @@ static struct zilog_layout __iomem * __init get_zs_sun4u(int chip, int zsnode)
1106 + FHC_UREGS_ICLR; 1106 + FHC_UREGS_ICLR;
1107 imap = central_bus->child->fhc_regs.uregs 1107 imap = central_bus->child->fhc_regs.uregs
1108 + FHC_UREGS_IMAP; 1108 + FHC_UREGS_IMAP;
1109 zilog_irq = build_irq(12, 0, iclr, imap); 1109 zilog_irq = build_irq(0, iclr, imap);
1110 } else { 1110 } else {
1111 err = prom_getproperty(zsnode, "interrupts", 1111 err = prom_getproperty(zsnode, "interrupts",
1112 (char *) &sun4u_ino, 1112 (char *) &sun4u_ino,
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 3f8e06279c92..bcbeaf7101d1 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1078,9 +1078,7 @@ static int proc_submiturb(struct dev_state *ps, void __user *arg)
1078 if (copy_from_user(&uurb, arg, sizeof(uurb))) 1078 if (copy_from_user(&uurb, arg, sizeof(uurb)))
1079 return -EFAULT; 1079 return -EFAULT;
1080 1080
1081 return proc_do_submiturb(ps, &uurb, 1081 return proc_do_submiturb(ps, &uurb, (((struct usbdevfs_urb __user *)arg)->iso_frame_desc), arg);
1082 (struct usbdevfs_iso_packet_desc __user *)uurb.iso_frame_desc,
1083 arg);
1084} 1082}
1085 1083
1086static int proc_unlinkurb(struct dev_state *ps, void __user *arg) 1084static int proc_unlinkurb(struct dev_state *ps, void __user *arg)
@@ -1205,9 +1203,7 @@ static int proc_submiturb_compat(struct dev_state *ps, void __user *arg)
1205 if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg)) 1203 if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg))
1206 return -EFAULT; 1204 return -EFAULT;
1207 1205
1208 return proc_do_submiturb(ps, &uurb, 1206 return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg);
1209 (struct usbdevfs_iso_packet_desc __user *)uurb.iso_frame_desc,
1210 arg);
1211} 1207}
1212 1208
1213static int processcompl_compat(struct async *as, void __user * __user *arg) 1209static int processcompl_compat(struct async *as, void __user * __user *arg)
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index eb6aa42be60e..c054bb28b1c4 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -2966,7 +2966,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev,
2966 } 2966 }
2967 2967
2968 pcp = pdev->sysdata; 2968 pcp = pdev->sysdata;
2969 if (node == pcp->prom_node) { 2969 if (node == pcp->prom_node->node) {
2970 struct fb_var_screeninfo *var = &default_var; 2970 struct fb_var_screeninfo *var = &default_var;
2971 unsigned int N, P, Q, M, T, R; 2971 unsigned int N, P, Q, M, T, R;
2972 u32 v_total, h_total; 2972 u32 v_total, h_total;
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 469b06c29180..e290d7460e1b 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -237,7 +237,7 @@ struct intelfb_info {
237 u32 fb_start; 237 u32 fb_start;
238 238
239 /* ring buffer */ 239 /* ring buffer */
240 u8 __iomem *ring_head; 240 u32 ring_head;
241 u32 ring_tail; 241 u32 ring_tail;
242 u32 ring_tail_mask; 242 u32 ring_tail_mask;
243 u32 ring_space; 243 u32 ring_space;
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 076fa56be192..0a0a8b199ecc 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -707,7 +707,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
707 + (dinfo->ring.offset << 12); 707 + (dinfo->ring.offset << 12);
708 dinfo->ring.virtual = dinfo->aperture.virtual 708 dinfo->ring.virtual = dinfo->aperture.virtual
709 + (dinfo->ring.offset << 12); 709 + (dinfo->ring.offset << 12);
710 dinfo->ring_head = dinfo->ring.virtual; 710 dinfo->ring_head = 0;
711 } 711 }
712 if (dinfo->hwcursor) { 712 if (dinfo->hwcursor) {
713 agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY 713 agp_memtype = dinfo->mobile ? AGP_PHYSICAL_MEMORY
@@ -766,18 +766,18 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
766 if (mtrr) 766 if (mtrr)
767 set_mtrr(dinfo); 767 set_mtrr(dinfo);
768 768
769 DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%x)\n", 769 DBG_MSG("fb: 0x%x(+ 0x%x)/0x%x (0x%p)\n",
770 dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size, 770 dinfo->fb.physical, dinfo->fb.offset, dinfo->fb.size,
771 (u32 __iomem ) dinfo->fb.virtual); 771 dinfo->fb.virtual);
772 DBG_MSG("MMIO: 0x%x/0x%x (0x%x)\n", 772 DBG_MSG("MMIO: 0x%x/0x%x (0x%p)\n",
773 dinfo->mmio_base_phys, INTEL_REG_SIZE, 773 dinfo->mmio_base_phys, INTEL_REG_SIZE,
774 (u32 __iomem) dinfo->mmio_base); 774 dinfo->mmio_base);
775 DBG_MSG("ring buffer: 0x%x/0x%x (0x%x)\n", 775 DBG_MSG("ring buffer: 0x%x/0x%x (0x%p)\n",
776 dinfo->ring.physical, dinfo->ring.size, 776 dinfo->ring.physical, dinfo->ring.size,
777 (u32 __iomem ) dinfo->ring.virtual); 777 dinfo->ring.virtual);
778 DBG_MSG("HW cursor: 0x%x/0x%x (0x%x) (offset 0x%x) (phys 0x%x)\n", 778 DBG_MSG("HW cursor: 0x%x/0x%x (0x%p) (offset 0x%x) (phys 0x%x)\n",
779 dinfo->cursor.physical, dinfo->cursor.size, 779 dinfo->cursor.physical, dinfo->cursor.size,
780 (u32 __iomem ) dinfo->cursor.virtual, dinfo->cursor.offset, 780 dinfo->cursor.virtual, dinfo->cursor.offset,
781 dinfo->cursor.physical); 781 dinfo->cursor.physical);
782 782
783 DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, " 783 DBG_MSG("options: vram = %d, accel = %d, hwcursor = %d, fixed = %d, "
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 426b7430b125..7533b3dd08ac 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -1423,19 +1423,17 @@ wait_ring(struct intelfb_info *dinfo, int n)
1423 1423
1424 end = jiffies + (HZ * 3); 1424 end = jiffies + (HZ * 3);
1425 while (dinfo->ring_space < n) { 1425 while (dinfo->ring_space < n) {
1426 dinfo->ring_head = (u8 __iomem *)(INREG(PRI_RING_HEAD) & 1426 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1427 RING_HEAD_MASK); 1427 if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
1428 if (dinfo->ring_tail + RING_MIN_FREE < 1428 dinfo->ring_space = dinfo->ring_head
1429 (u32 __iomem) dinfo->ring_head)
1430 dinfo->ring_space = (u32 __iomem) dinfo->ring_head
1431 - (dinfo->ring_tail + RING_MIN_FREE); 1429 - (dinfo->ring_tail + RING_MIN_FREE);
1432 else 1430 else
1433 dinfo->ring_space = (dinfo->ring.size + 1431 dinfo->ring_space = (dinfo->ring.size +
1434 (u32 __iomem) dinfo->ring_head) 1432 dinfo->ring_head)
1435 - (dinfo->ring_tail + RING_MIN_FREE); 1433 - (dinfo->ring_tail + RING_MIN_FREE);
1436 if ((u32 __iomem) dinfo->ring_head != last_head) { 1434 if (dinfo->ring_head != last_head) {
1437 end = jiffies + (HZ * 3); 1435 end = jiffies + (HZ * 3);
1438 last_head = (u32 __iomem) dinfo->ring_head; 1436 last_head = dinfo->ring_head;
1439 } 1437 }
1440 i++; 1438 i++;
1441 if (time_before(end, jiffies)) { 1439 if (time_before(end, jiffies)) {
@@ -1495,15 +1493,13 @@ refresh_ring(struct intelfb_info *dinfo)
1495 DBG_MSG("refresh_ring\n"); 1493 DBG_MSG("refresh_ring\n");
1496#endif 1494#endif
1497 1495
1498 dinfo->ring_head = (u8 __iomem *) (INREG(PRI_RING_HEAD) & 1496 dinfo->ring_head = INREG(PRI_RING_HEAD) & RING_HEAD_MASK;
1499 RING_HEAD_MASK);
1500 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK; 1497 dinfo->ring_tail = INREG(PRI_RING_TAIL) & RING_TAIL_MASK;
1501 if (dinfo->ring_tail + RING_MIN_FREE < (u32 __iomem)dinfo->ring_head) 1498 if (dinfo->ring_tail + RING_MIN_FREE < dinfo->ring_head)
1502 dinfo->ring_space = (u32 __iomem) dinfo->ring_head 1499 dinfo->ring_space = dinfo->ring_head
1503 - (dinfo->ring_tail + RING_MIN_FREE); 1500 - (dinfo->ring_tail + RING_MIN_FREE);
1504 else 1501 else
1505 dinfo->ring_space = (dinfo->ring.size + 1502 dinfo->ring_space = (dinfo->ring.size + dinfo->ring_head)
1506 (u32 __iomem) dinfo->ring_head)
1507 - (dinfo->ring_tail + RING_MIN_FREE); 1503 - (dinfo->ring_tail + RING_MIN_FREE);
1508} 1504}
1509 1505
diff --git a/include/asm-arm/arch-aaec2000/io.h b/include/asm-arm/arch-aaec2000/io.h
index 8d67907fd4f0..d710204ac747 100644
--- a/include/asm-arm/arch-aaec2000/io.h
+++ b/include/asm-arm/arch-aaec2000/io.h
@@ -16,6 +16,5 @@
16 */ 16 */
17#define __io(a) ((void __iomem *)(a)) 17#define __io(a) ((void __iomem *)(a))
18#define __mem_pci(a) (a) 18#define __mem_pci(a) (a)
19#define __mem_isa(a) (a)
20 19
21#endif 20#endif
diff --git a/include/asm-arm/arch-clps711x/io.h b/include/asm-arm/arch-clps711x/io.h
index 62613b0e2d96..53d790202c19 100644
--- a/include/asm-arm/arch-clps711x/io.h
+++ b/include/asm-arm/arch-clps711x/io.h
@@ -26,7 +26,6 @@
26 26
27#define __io(a) ((void __iomem *)(a)) 27#define __io(a) ((void __iomem *)(a))
28#define __mem_pci(a) (a) 28#define __mem_pci(a) (a)
29#define __mem_isa(a) (a)
30 29
31/* 30/*
32 * We don't support ins[lb]/outs[lb]. Make them fault. 31 * We don't support ins[lb]/outs[lb]. Make them fault.
diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h
index 776f9d377057..f9c729141860 100644
--- a/include/asm-arm/arch-ebsa285/io.h
+++ b/include/asm-arm/arch-ebsa285/io.h
@@ -24,7 +24,6 @@
24#define __io(a) ((void __iomem *)(PCIO_BASE + (a))) 24#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
25#if 1 25#if 1
26#define __mem_pci(a) (a) 26#define __mem_pci(a) (a)
27#define __mem_isa(a) ((a) + PCIMEM_BASE)
28#else 27#else
29 28
30static inline void __iomem *___mem_pci(void __iomem *p) 29static inline void __iomem *___mem_pci(void __iomem *p)
@@ -34,14 +33,7 @@ static inline void __iomem *___mem_pci(void __iomem *p)
34 return p; 33 return p;
35} 34}
36 35
37static inline void __iomem *___mem_isa(void __iomem *p)
38{
39 unsigned long a = (unsigned long)p;
40 BUG_ON(a >= 16*1048576);
41 return p + PCIMEM_BASE;
42}
43#define __mem_pci(a) ___mem_pci(a) 36#define __mem_pci(a) ___mem_pci(a)
44#define __mem_isa(a) ___mem_isa(a)
45#endif 37#endif
46 38
47#endif 39#endif
diff --git a/include/asm-arm/arch-ep93xx/ep93xx-regs.h b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
index 71cea0b5841b..8c322975f96e 100644
--- a/include/asm-arm/arch-ep93xx/ep93xx-regs.h
+++ b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
@@ -115,6 +115,8 @@
115#define EP93XX_SYSCON_CLOCK_USH_EN 0x10000000 115#define EP93XX_SYSCON_CLOCK_USH_EN 0x10000000
116#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08) 116#define EP93XX_SYSCON_HALT EP93XX_SYSCON_REG(0x08)
117#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c) 117#define EP93XX_SYSCON_STANDBY EP93XX_SYSCON_REG(0x0c)
118#define EP93XX_SYSCON_CLOCK_SET1 EP93XX_SYSCON_REG(0x20)
119#define EP93XX_SYSCON_CLOCK_SET2 EP93XX_SYSCON_REG(0x24)
118#define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80) 120#define EP93XX_SYSCON_DEVICE_CONFIG EP93XX_SYSCON_REG(0x80)
119#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE 0x00800000 121#define EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE 0x00800000
120#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0) 122#define EP93XX_SYSCON_SWLOCK EP93XX_SYSCON_REG(0xc0)
diff --git a/include/asm-arm/arch-ep93xx/platform.h b/include/asm-arm/arch-ep93xx/platform.h
index df9cbb6ef660..d7a34ce20293 100644
--- a/include/asm-arm/arch-ep93xx/platform.h
+++ b/include/asm-arm/arch-ep93xx/platform.h
@@ -8,6 +8,7 @@ void ep93xx_map_io(void);
8void ep93xx_init_irq(void); 8void ep93xx_init_irq(void);
9void ep93xx_init_time(unsigned long); 9void ep93xx_init_time(unsigned long);
10void ep93xx_init_devices(void); 10void ep93xx_init_devices(void);
11void ep93xx_clock_init(void);
11extern struct sys_timer ep93xx_timer; 12extern struct sys_timer ep93xx_timer;
12 13
13 14
diff --git a/include/asm-arm/arch-integrator/io.h b/include/asm-arm/arch-integrator/io.h
index 31f2deab51b0..c8f2175948bd 100644
--- a/include/asm-arm/arch-integrator/io.h
+++ b/include/asm-arm/arch-integrator/io.h
@@ -32,6 +32,5 @@
32 32
33#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a))) 33#define __io(a) ((void __iomem *)(PCI_IO_VADDR + (a)))
34#define __mem_pci(a) (a) 34#define __mem_pci(a) (a)
35#define __mem_isa(a) ((a) + PCI_MEMORY_VADDR)
36 35
37#endif 36#endif
diff --git a/include/asm-arm/arch-iop3xx/io.h b/include/asm-arm/arch-iop3xx/io.h
index f39046a6ab14..36adbdf5055a 100644
--- a/include/asm-arm/arch-iop3xx/io.h
+++ b/include/asm-arm/arch-iop3xx/io.h
@@ -17,6 +17,5 @@
17 17
18#define __io(p) ((void __iomem *)(p)) 18#define __io(p) ((void __iomem *)(p))
19#define __mem_pci(a) (a) 19#define __mem_pci(a) (a)
20#define __mem_isa(a) (a)
21 20
22#endif 21#endif
diff --git a/include/asm-arm/arch-l7200/io.h b/include/asm-arm/arch-l7200/io.h
index cab8ad0adf09..cd080d8384d9 100644
--- a/include/asm-arm/arch-l7200/io.h
+++ b/include/asm-arm/arch-l7200/io.h
@@ -19,7 +19,6 @@
19 */ 19 */
20#define __io_pci(a) ((void __iomem *)(PCIO_BASE + (a))) 20#define __io_pci(a) ((void __iomem *)(PCIO_BASE + (a)))
21#define __mem_pci(a) (a) 21#define __mem_pci(a) (a)
22#define __mem_isa(a) (a)
23 22
24#define __ioaddr(p) __io_pci(p) 23#define __ioaddr(p) __io_pci(p)
25 24
diff --git a/include/asm-arm/arch-lh7a40x/io.h b/include/asm-arm/arch-lh7a40x/io.h
index bbcd4335f441..17bc94097481 100644
--- a/include/asm-arm/arch-lh7a40x/io.h
+++ b/include/asm-arm/arch-lh7a40x/io.h
@@ -18,6 +18,5 @@
18/* No ISA or PCI bus on this machine. */ 18/* No ISA or PCI bus on this machine. */
19#define __io(a) ((void __iomem *)(a)) 19#define __io(a) ((void __iomem *)(a))
20#define __mem_pci(a) (a) 20#define __mem_pci(a) (a)
21#define __mem_isa(a) (a)
22 21
23#endif /* __ASM_ARCH_IO_H */ 22#endif /* __ASM_ARCH_IO_H */
diff --git a/include/asm-arm/arch-netx/io.h b/include/asm-arm/arch-netx/io.h
index 81b7bc47747e..a7a53f80165d 100644
--- a/include/asm-arm/arch-netx/io.h
+++ b/include/asm-arm/arch-netx/io.h
@@ -24,6 +24,5 @@
24 24
25#define __io(a) ((void __iomem *)(a)) 25#define __io(a) ((void __iomem *)(a))
26#define __mem_pci(a) (a) 26#define __mem_pci(a) (a)
27#define __mem_isa(a) (a)
28 27
29#endif 28#endif
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h
index b726acfcab14..78f68e6a4f0c 100644
--- a/include/asm-arm/arch-omap/io.h
+++ b/include/asm-arm/arch-omap/io.h
@@ -44,7 +44,6 @@
44 */ 44 */
45#define __io(a) ((void __iomem *)(PCIO_BASE + (a))) 45#define __io(a) ((void __iomem *)(PCIO_BASE + (a)))
46#define __mem_pci(a) (a) 46#define __mem_pci(a) (a)
47#define __mem_isa(a) (a)
48 47
49/* 48/*
50 * ---------------------------------------------------------------------------- 49 * ----------------------------------------------------------------------------
diff --git a/include/asm-arm/arch-pxa/io.h b/include/asm-arm/arch-pxa/io.h
index eb2dd58d397f..7f8d817b446f 100644
--- a/include/asm-arm/arch-pxa/io.h
+++ b/include/asm-arm/arch-pxa/io.h
@@ -16,6 +16,5 @@
16 */ 16 */
17#define __io(a) ((void __iomem *)(a)) 17#define __io(a) ((void __iomem *)(a))
18#define __mem_pci(a) (a) 18#define __mem_pci(a) (a)
19#define __mem_isa(a) (a)
20 19
21#endif 20#endif
diff --git a/include/asm-arm/arch-realview/io.h b/include/asm-arm/arch-realview/io.h
index d444a68ac330..c70f1dfbe135 100644
--- a/include/asm-arm/arch-realview/io.h
+++ b/include/asm-arm/arch-realview/io.h
@@ -29,6 +29,5 @@ static inline void __iomem *__io(unsigned long addr)
29 29
30#define __io(a) __io(a) 30#define __io(a) __io(a)
31#define __mem_pci(a) (a) 31#define __mem_pci(a) (a)
32#define __mem_isa(a) (a)
33 32
34#endif 33#endif
diff --git a/include/asm-arm/arch-s3c2410/debug-macro.S b/include/asm-arm/arch-s3c2410/debug-macro.S
index 5f8223e700d3..b7d15d125458 100644
--- a/include/asm-arm/arch-s3c2410/debug-macro.S
+++ b/include/asm-arm/arch-s3c2410/debug-macro.S
@@ -33,7 +33,7 @@
33 .endm 33 .endm
34 34
35 .macro senduart,rd,rx 35 .macro senduart,rd,rx
36 str \rd, [\rx, # S3C2410_UTXH ] 36 strb \rd, [\rx, # S3C2410_UTXH ]
37 .endm 37 .endm
38 38
39 .macro busyuart, rd, rx 39 .macro busyuart, rd, rx
@@ -42,6 +42,12 @@
42 beq 1001f @ 42 beq 1001f @
43 @ FIFO enabled... 43 @ FIFO enabled...
441003: 441003:
45 @ check for arm920 vs arm926. currently assume all arm926
46 @ devices have an 64 byte FIFO identical to the s3c2440
47 mrc p15, 0, \rd, c0, c0
48 and \rd, \rd, #0xff0
49 teq \rd, #0x260
50 beq 1004f
45 mrc p15, 0, \rd, c1, c0 51 mrc p15, 0, \rd, c1, c0
46 tst \rd, #1 52 tst \rd, #1
47 addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART) 53 addeq \rd, \rx, #(S3C24XX_PA_GPIO - S3C24XX_PA_UART)
@@ -50,7 +56,7 @@
50 ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ] 56 ldr \rd, [ \rd, # S3C2410_GSTATUS1 - S3C2410_GPIOREG(0) ]
51 and \rd, \rd, #0x00ff0000 57 and \rd, \rd, #0x00ff0000
52 teq \rd, #0x00440000 @ is it 2440? 58 teq \rd, #0x00440000 @ is it 2440?
53 591004:
54 ldr \rd, [ \rx, # S3C2410_UFSTAT ] 60 ldr \rd, [ \rx, # S3C2410_UFSTAT ]
55 moveq \rd, \rd, lsr #SHIFT_2440TXF 61 moveq \rd, \rd, lsr #SHIFT_2440TXF
56 tst \rd, #S3C2410_UFSTAT_TXFULL 62 tst \rd, #S3C2410_UFSTAT_TXFULL
diff --git a/include/asm-arm/arch-s3c2410/entry-macro.S b/include/asm-arm/arch-s3c2410/entry-macro.S
index 894c35cf3b1e..e09a6b8ec153 100644
--- a/include/asm-arm/arch-s3c2410/entry-macro.S
+++ b/include/asm-arm/arch-s3c2410/entry-macro.S
@@ -18,8 +18,6 @@
18 18
19#define INTPND (0x10) 19#define INTPND (0x10)
20#define INTOFFSET (0x14) 20#define INTOFFSET (0x14)
21#define EXTINTPEND (0xa8)
22#define EXTINTMASK (0xa4)
23 21
24#include <asm/hardware.h> 22#include <asm/hardware.h>
25#include <asm/arch/irqs.h> 23#include <asm/arch/irqs.h>
@@ -28,37 +26,23 @@
28 26
29 mov \base, #S3C24XX_VA_IRQ 27 mov \base, #S3C24XX_VA_IRQ
30 28
31 ldr \irqstat, [ \base, #INTPND]
32 bics \irqnr, \irqstat, #3<<4 @@ only an GPIO IRQ
33 beq 2000f
34
35 @@ try the interrupt offset register, since it is there 29 @@ try the interrupt offset register, since it is there
36 30
31 ldr \irqstat, [ \base, #INTPND ]
32 teq \irqstat, #0
33 beq 1002f
37 ldr \irqnr, [ \base, #INTOFFSET ] 34 ldr \irqnr, [ \base, #INTOFFSET ]
38 mov \tmp, #1 35 mov \tmp, #1
39 tst \irqstat, \tmp, lsl \irqnr 36 tst \irqstat, \tmp, lsl \irqnr
40 addne \irqnr, \irqnr, #IRQ_EINT0
41 bne 1001f 37 bne 1001f
42 38
43 @@ the number specified is not a valid irq, so try 39 @@ the number specified is not a valid irq, so try
44 @@ and work it out for ourselves 40 @@ and work it out for ourselves
45 41
46 mov \irqnr, #IRQ_EINT0 @@ start here 42 mov \irqnr, #0 @@ start here
47 b 3000f
48
492000:
50 @@ load the GPIO interrupt register, and check it
51
52 add \tmp, \base, #S3C24XX_VA_GPIO - S3C24XX_VA_IRQ
53 ldr \irqstat, [ \tmp, # EXTINTPEND ]
54 ldr \irqnr, [ \tmp, # EXTINTMASK ]
55 bics \irqstat, \irqstat, \irqnr
56 beq 1001f
57
58 mov \irqnr, #(IRQ_EINT4 - 4)
59 43
60 @@ work out which irq (if any) we got 44 @@ work out which irq (if any) we got
613000: 45
62 movs \tmp, \irqstat, lsl#16 46 movs \tmp, \irqstat, lsl#16
63 addeq \irqnr, \irqnr, #16 47 addeq \irqnr, \irqnr, #16
64 moveq \irqstat, \irqstat, lsr#16 48 moveq \irqstat, \irqstat, lsr#16
@@ -75,9 +59,9 @@
75 addeq \irqnr, \irqnr, #1 59 addeq \irqnr, \irqnr, #1
76 60
77 @@ we have the value 61 @@ we have the value
78 movs \irqnr, \irqnr
79
801001: 621001:
63 adds \irqnr, \irqnr, #IRQ_EINT0
641002:
81 @@ exit here, Z flag unset if IRQ 65 @@ exit here, Z flag unset if IRQ
82 66
83 .endm 67 .endm
diff --git a/include/asm-arm/arch-s3c2410/map.h b/include/asm-arm/arch-s3c2410/map.h
index 5e4c8c37bc66..fae2766ff32b 100644
--- a/include/asm-arm/arch-s3c2410/map.h
+++ b/include/asm-arm/arch-s3c2410/map.h
@@ -236,4 +236,20 @@
236#define S3C24XX_PA_SPI S3C2410_PA_SPI 236#define S3C24XX_PA_SPI S3C2410_PA_SPI
237#endif 237#endif
238 238
239/* deal with the registers that move under the 2412/2413 */
240
241#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
242#ifndef __ASSEMBLY__
243extern void __iomem *s3c24xx_va_gpio2;
244#endif
245#ifdef CONFIG_CPU_S3C2412_ONLY
246#define S3C24XX_VA_GPIO2 (S3C24XX_VA_GPIO + 0x10)
247#else
248#define S3C24XX_VA_GPIO2 s3c24xx_va_gpio2
249#endif
250#else
251#define s3c24xx_va_gpio2 S3C24XX_VA_GPIO
252#define S3C24XX_VA_GPIO2 S3C24XX_VA_GPIO
253#endif
254
239#endif /* __ASM_ARCH_MAP_H */ 255#endif /* __ASM_ARCH_MAP_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-clock.h b/include/asm-arm/arch-s3c2410/regs-clock.h
index 6c92faffe985..a7c61feb8433 100644
--- a/include/asm-arm/arch-s3c2410/regs-clock.h
+++ b/include/asm-arm/arch-s3c2410/regs-clock.h
@@ -1,6 +1,6 @@
1/* linux/include/asm/arch-s3c2410/regs-clock.h 1/* linux/include/asm/arch-s3c2410/regs-clock.h
2 * 2 *
3 * Copyright (c) 2003,2004,2005 Simtec Electronics <linux@simtec.co.uk> 3 * Copyright (c) 2003,2004,2005,2006 Simtec Electronics <linux@simtec.co.uk>
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
@@ -140,5 +140,66 @@ s3c2410_get_pll(unsigned int pllval, unsigned int baseclk)
140 140
141#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */ 141#endif /* CONFIG_CPU_S3C2440 or CONFIG_CPU_S3C2442 */
142 142
143#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413)
144
145#define S3C2412_OSCSET S3C2410_CLKREG(0x18)
146#define S3C2412_CLKSRC S3C2410_CLKREG(0x1C)
147
148#define S3C2412_PLLCON_OFF (1<<20)
149
150#define S3C2412_CLKDIVN_PDIVN (1<<2)
151#define S3C2412_CLKDIVN_HDIVN_MASK (3<<0)
152#define S3C2421_CLKDIVN_ARMDIVN (1<<3)
153#define S3C2412_CLKDIVN_USB48DIV (1<<6)
154#define S3C2412_CLKDIVN_UARTDIV_MASK (15<<8)
155#define S3C2412_CLKDIVN_UARTDIV_SHIFT (8)
156#define S3C2412_CLKDIVN_I2SDIV_MASK (15<<12)
157#define S3C2412_CLKDIVN_I2SDIV_SHIFT (12)
158#define S3C2412_CLKDIVN_CAMDIV_MASK (15<<16)
159#define S3C2412_CLKDIVN_CAMDIV_SHIFT (16)
160
161#define S3C2412_CLKCON_WDT (1<<28)
162#define S3C2412_CLKCON_SPI (1<<27)
163#define S3C2412_CLKCON_IIS (1<<26)
164#define S3C2412_CLKCON_IIC (1<<25)
165#define S3C2412_CLKCON_ADC (1<<24)
166#define S3C2412_CLKCON_RTC (1<<23)
167#define S3C2412_CLKCON_GPIO (1<<22)
168#define S3C2412_CLKCON_UART2 (1<<21)
169#define S3C2412_CLKCON_UART1 (1<<20)
170#define S3C2412_CLKCON_UART0 (1<<19)
171#define S3C2412_CLKCON_SDI (1<<18)
172#define S3C2412_CLKCON_PWMT (1<<17)
173#define S3C2412_CLKCON_USBD (1<<16)
174#define S3C2412_CLKCON_CAMCLK (1<<15)
175#define S3C2412_CLKCON_UARTCLK (1<<14)
176/* missing 13 */
177#define S3C2412_CLKCON_USB_HOST48 (1<<12)
178#define S3C2412_CLKCON_USB_DEV48 (1<<11)
179#define S3C2412_CLKCON_HCLKdiv2 (1<<10)
180#define S3C2412_CLKCON_HCLKx2 (1<<9)
181#define S3C2412_CLKCON_SDRAM (1<<8)
182/* missing 7 */
183#define S3C2412_CLKCON_USBH S3C2410_CLKCON_USBH
184#define S3C2412_CLKCON_LCDC S3C2410_CLKCON_LCDC
185#define S3C2412_CLKCON_NAND S3C2410_CLKCON_NAND
186#define S3C2412_CLKCON_DMA3 (1<<3)
187#define S3C2412_CLKCON_DMA2 (1<<2)
188#define S3C2412_CLKCON_DMA1 (1<<1)
189#define S3C2412_CLKCON_DMA0 (1<<0)
190
191/* clock sourec controls */
192
193#define S3C2412_CLKSRC_EXTCLKDIV_MASK (7 << 0)
194#define S3C2412_CLKSRC_EXTCLKDIV_SHIFT (0)
195#define S3C2412_CLKSRC_MDIVCLK_EXTCLKDIV (1<<3)
196#define S3C2412_CLKSRC_MSYSCLK_MPLL (1<<4)
197#define S3C2412_CLKSRC_USYSCLK_UPLL (1<<5)
198#define S3C2412_CLKSRC_UARTCLK_MPLL (1<<8)
199#define S3C2412_CLKSRC_I2SCLK_MPLL (1<<9)
200#define S3C2412_CLKSRC_USBCLK_HCLK (1<<10)
201#define S3C2412_CLKSRC_CAMCLK_HCLK (1<<11)
202
203#endif /* CONFIG_CPU_S3C2412 | CONFIG_CPU_S3C2413 */
143 204
144#endif /* __ASM_ARM_REGS_CLOCK */ 205#endif /* __ASM_ARM_REGS_CLOCK */
diff --git a/include/asm-arm/arch-s3c2410/regs-dsc.h b/include/asm-arm/arch-s3c2410/regs-dsc.h
index ba13a2c9e547..84aca61cbaa3 100644
--- a/include/asm-arm/arch-s3c2410/regs-dsc.h
+++ b/include/asm-arm/arch-s3c2410/regs-dsc.h
@@ -23,6 +23,9 @@
23#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4) 23#define S3C2440_DSC0 S3C2410_GPIOREG(0xc4)
24#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8) 24#define S3C2440_DSC1 S3C2410_GPIOREG(0xc8)
25 25
26#define S3C2412_DSC0 S3C2410_GPIOREG(0xdc)
27#define S3C2412_DSC1 S3C2410_GPIOREG(0xe0)
28
26#define S3C2440_SELECT_DSC0 (0) 29#define S3C2440_SELECT_DSC0 (0)
27#define S3C2440_SELECT_DSC1 (1<<31) 30#define S3C2440_SELECT_DSC1 (1<<31)
28 31
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index 5f10334f06bf..6dd17f0f84e0 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -45,7 +45,7 @@
45#define S3C24XX_MISCCR S3C2400_MISCCR 45#define S3C24XX_MISCCR S3C2400_MISCCR
46#else 46#else
47#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x) 47#define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x)
48#define S3C24XX_MISCCR S3C2410_MISCCR 48#define S3C24XX_MISCCR S3C24XX_GPIOREG2(0x80)
49#endif /* CONFIG_CPU_S3C2400 */ 49#endif /* CONFIG_CPU_S3C2400 */
50 50
51 51
@@ -73,9 +73,15 @@
73#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* not available on A */ 73#define S3C2410_GPIO_SFN2 (0xFFFFFFF2) /* not available on A */
74#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */ 74#define S3C2410_GPIO_SFN3 (0xFFFFFFF3) /* not available on A */
75 75
76/* configure GPIO ports A..G */ 76/* register address for the GPIO registers.
77 * S3C24XX_GPIOREG2 is for the second set of registers in the
78 * GPIO which move between s3c2410 and s3c2412 type systems */
77 79
78#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO) 80#define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO)
81#define S3C24XX_GPIOREG2(x) ((x) + S3C24XX_VA_GPIO2)
82
83
84/* configure GPIO ports A..G */
79 85
80/* port A - S3C2410: 22bits, zero in bit X makes pin X output 86/* port A - S3C2410: 22bits, zero in bit X makes pin X output
81 * S3C2400: 18bits, zero in bit X makes pin X output 87 * S3C2400: 18bits, zero in bit X makes pin X output
@@ -953,11 +959,18 @@
953#define S3C2410_GPH10_OUTP (0x01 << 20) 959#define S3C2410_GPH10_OUTP (0x01 << 20)
954#define S3C2410_GPH10_CLKOUT1 (0x02 << 20) 960#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
955 961
962/* The S3C2412 and S3C2413 move the GPJ register set to after
963 * GPH, which means all registers after 0x80 are now offset by 0x10
964 * for the 2412/2413 from the 2410/2440/2442
965*/
966
956/* miscellaneous control */ 967/* miscellaneous control */
957#define S3C2400_MISCCR S3C2410_GPIOREG(0x54) 968#define S3C2400_MISCCR S3C2410_GPIOREG(0x54)
958#define S3C2410_MISCCR S3C2410_GPIOREG(0x80) 969#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
959#define S3C2410_DCLKCON S3C2410_GPIOREG(0x84) 970#define S3C2410_DCLKCON S3C2410_GPIOREG(0x84)
960 971
972#define S3C24XX_DCLKCON S3C24XX_GPIOREG2(0x84)
973
961/* see clock.h for dclk definitions */ 974/* see clock.h for dclk definitions */
962 975
963/* pullup control on databus */ 976/* pullup control on databus */
@@ -985,6 +998,8 @@
985#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4) 998#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4)
986#define S3C2410_MISCCR_CLK0_MASK (7<<4) 999#define S3C2410_MISCCR_CLK0_MASK (7<<4)
987 1000
1001#define S3C2412_MISCCR_CLK0_RTC (2<<4)
1002
988#define S3C2410_MISCCR_CLK1_MPLL (0<<8) 1003#define S3C2410_MISCCR_CLK1_MPLL (0<<8)
989#define S3C2410_MISCCR_CLK1_UPLL (1<<8) 1004#define S3C2410_MISCCR_CLK1_UPLL (1<<8)
990#define S3C2410_MISCCR_CLK1_FCLK (2<<8) 1005#define S3C2410_MISCCR_CLK1_FCLK (2<<8)
@@ -993,6 +1008,8 @@
993#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8) 1008#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8)
994#define S3C2410_MISCCR_CLK1_MASK (7<<8) 1009#define S3C2410_MISCCR_CLK1_MASK (7<<8)
995 1010
1011#define S3C2412_MISCCR_CLK1_CLKsrc (0<<8)
1012
996#define S3C2410_MISCCR_USBSUSPND0 (1<<12) 1013#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
997#define S3C2410_MISCCR_USBSUSPND1 (1<<13) 1014#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
998 1015
@@ -1000,7 +1017,7 @@
1000 1017
1001#define S3C2410_MISCCR_nEN_SCLK0 (1<<17) 1018#define S3C2410_MISCCR_nEN_SCLK0 (1<<17)
1002#define S3C2410_MISCCR_nEN_SCLK1 (1<<18) 1019#define S3C2410_MISCCR_nEN_SCLK1 (1<<18)
1003#define S3C2410_MISCCR_nEN_SCLKE (1<<19) 1020#define S3C2410_MISCCR_nEN_SCLKE (1<<19) /* not 2412 */
1004#define S3C2410_MISCCR_SDSLEEP (7<<17) 1021#define S3C2410_MISCCR_SDSLEEP (7<<17)
1005 1022
1006/* external interrupt control... */ 1023/* external interrupt control... */
@@ -1017,6 +1034,10 @@
1017#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C) 1034#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C)
1018#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90) 1035#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90)
1019 1036
1037#define S3C24XX_EXTINT0 S3C24XX_GPIOREG2(0x88)
1038#define S3C24XX_EXTINT1 S3C24XX_GPIOREG2(0x8C)
1039#define S3C24XX_EXTINT2 S3C24XX_GPIOREG2(0x90)
1040
1020/* values for S3C2410_EXTINT0/1/2 */ 1041/* values for S3C2410_EXTINT0/1/2 */
1021#define S3C2410_EXTINT_LOWLEV (0x00) 1042#define S3C2410_EXTINT_LOWLEV (0x00)
1022#define S3C2410_EXTINT_HILEV (0x01) 1043#define S3C2410_EXTINT_HILEV (0x01)
@@ -1030,6 +1051,11 @@
1030#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C) 1051#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C)
1031#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0) 1052#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0)
1032 1053
1054#define S3C24XX_EINFLT0 S3C24XX_GPIOREG2(0x94)
1055#define S3C24XX_EINFLT1 S3C24XX_GPIOREG2(0x98)
1056#define S3C24XX_EINFLT2 S3C24XX_GPIOREG2(0x9C)
1057#define S3C24XX_EINFLT3 S3C24XX_GPIOREG2(0xA0)
1058
1033/* values for interrupt filtering */ 1059/* values for interrupt filtering */
1034#define S3C2410_EINTFLT_PCLK (0x00) 1060#define S3C2410_EINTFLT_PCLK (0x00)
1035#define S3C2410_EINTFLT_EXTCLK (1<<7) 1061#define S3C2410_EINTFLT_EXTCLK (1<<7)
@@ -1039,6 +1065,7 @@
1039 1065
1040/* GSTATUS have miscellaneous information in them 1066/* GSTATUS have miscellaneous information in them
1041 * 1067 *
1068 * These move between s3c2410 and s3c2412 style systems.
1042 */ 1069 */
1043 1070
1044#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC) 1071#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC)
@@ -1047,6 +1074,18 @@
1047#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8) 1074#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8)
1048#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC) 1075#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC)
1049 1076
1077#define S3C2412_GSTATUS0 S3C2410_GPIOREG(0x0BC)
1078#define S3C2412_GSTATUS1 S3C2410_GPIOREG(0x0C0)
1079#define S3C2412_GSTATUS2 S3C2410_GPIOREG(0x0C4)
1080#define S3C2412_GSTATUS3 S3C2410_GPIOREG(0x0C8)
1081#define S3C2412_GSTATUS4 S3C2410_GPIOREG(0x0CC)
1082
1083#define S3C24XX_GSTATUS0 S3C24XX_GPIOREG2(0x0AC)
1084#define S3C24XX_GSTATUS1 S3C24XX_GPIOREG2(0x0B0)
1085#define S3C24XX_GSTATUS2 S3C24XX_GPIOREG2(0x0B4)
1086#define S3C24XX_GSTATUS3 S3C24XX_GPIOREG2(0x0B8)
1087#define S3C24XX_GSTATUS4 S3C24XX_GPIOREG2(0x0BC)
1088
1050#define S3C2410_GSTATUS0_nWAIT (1<<3) 1089#define S3C2410_GSTATUS0_nWAIT (1<<3)
1051#define S3C2410_GSTATUS0_NCON (1<<2) 1090#define S3C2410_GSTATUS0_NCON (1<<2)
1052#define S3C2410_GSTATUS0_RnB (1<<1) 1091#define S3C2410_GSTATUS0_RnB (1<<1)
@@ -1054,6 +1093,7 @@
1054 1093
1055#define S3C2410_GSTATUS1_IDMASK (0xffff0000) 1094#define S3C2410_GSTATUS1_IDMASK (0xffff0000)
1056#define S3C2410_GSTATUS1_2410 (0x32410000) 1095#define S3C2410_GSTATUS1_2410 (0x32410000)
1096#define S3C2410_GSTATUS1_2412 (0x32412001)
1057#define S3C2410_GSTATUS1_2440 (0x32440000) 1097#define S3C2410_GSTATUS1_2440 (0x32440000)
1058#define S3C2410_GSTATUS1_2442 (0x32440aaa) 1098#define S3C2410_GSTATUS1_2442 (0x32440aaa)
1059 1099
@@ -1077,5 +1117,22 @@
1077#define S3C2400_OPENCR_OPC_MOSIDIS (0<<5) 1117#define S3C2400_OPENCR_OPC_MOSIDIS (0<<5)
1078#define S3C2400_OPENCR_OPC_MOSIEN (1<<5) 1118#define S3C2400_OPENCR_OPC_MOSIEN (1<<5)
1079 1119
1120/* 2412/2413 sleep configuration registers */
1121
1122#define S3C2412_GPBSLPCON S3C2410_GPIOREG(0x1C)
1123#define S3C2412_GPCSLPCON S3C2410_GPIOREG(0x2C)
1124#define S3C2412_GPDSLPCON S3C2410_GPIOREG(0x3C)
1125#define S3C2412_GPESLPCON S3C2410_GPIOREG(0x4C)
1126#define S3C2412_GPFSLPCON S3C2410_GPIOREG(0x5C)
1127#define S3C2412_GPGSLPCON S3C2410_GPIOREG(0x6C)
1128#define S3C2412_GPHSLPCON S3C2410_GPIOREG(0x7C)
1129
1130/* definitions for each pin bit */
1131#define S3C2412_SLPCON_LOW(x) ( 0x00 << ((x) * 2))
1132#define S3C2412_SLPCON_HI(x) ( 0x01 << ((x) * 2))
1133#define S3C2412_SLPCON_IN(x) ( 0x02 << ((x) * 2))
1134#define S3C2412_SLPCON_PDWN(x) ( 0x03 << ((x) * 2))
1135#define S3C2412_SLPCON_MASK(x) ( 0x03 << ((x) * 2))
1136
1080#endif /* __ASM_ARCH_REGS_GPIO_H */ 1137#endif /* __ASM_ARCH_REGS_GPIO_H */
1081 1138
diff --git a/include/asm-arm/arch-s3c2410/regs-gpioj.h b/include/asm-arm/arch-s3c2410/regs-gpioj.h
index 3ad2324acc39..18edae50d0b8 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpioj.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpioj.h
@@ -32,6 +32,11 @@
32#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4) 32#define S3C2440_GPJDAT S3C2410_GPIOREG(0xd4)
33#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8) 33#define S3C2440_GPJUP S3C2410_GPIOREG(0xd8)
34 34
35#define S3C2413_GPJCON S3C2410_GPIOREG(0x80)
36#define S3C2413_GPJDAT S3C2410_GPIOREG(0x84)
37#define S3C2413_GPJUP S3C2410_GPIOREG(0x88)
38#define S3C2413_GPJSLPCON S3C2410_GPIOREG(0x8C)
39
35#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0) 40#define S3C2440_GPJ0 S3C2410_GPIONO(S3C2440_GPIO_BANKJ, 0)
36#define S3C2440_GPJ0_INP (0x00 << 0) 41#define S3C2440_GPJ0_INP (0x00 << 0)
37#define S3C2440_GPJ0_OUTP (0x01 << 0) 42#define S3C2440_GPJ0_OUTP (0x01 << 0)
diff --git a/include/asm-arm/arch-s3c2410/regs-irq.h b/include/asm-arm/arch-s3c2410/regs-irq.h
index 24b7292df79e..572fca5d9acf 100644
--- a/include/asm-arm/arch-s3c2410/regs-irq.h
+++ b/include/asm-arm/arch-s3c2410/regs-irq.h
@@ -23,6 +23,7 @@
23 23
24#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ) 24#define S3C2410_IRQREG(x) ((x) + S3C24XX_VA_IRQ)
25#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO) 25#define S3C2410_EINTREG(x) ((x) + S3C24XX_VA_GPIO)
26#define S3C24XX_EINTREG(x) ((x) + S3C24XX_VA_GPIO2)
26 27
27#define S3C2410_SRCPND S3C2410_IRQREG(0x000) 28#define S3C2410_SRCPND S3C2410_IRQREG(0x000)
28#define S3C2410_INTMOD S3C2410_IRQREG(0x004) 29#define S3C2410_INTMOD S3C2410_IRQREG(0x004)
@@ -40,5 +41,10 @@
40 41
41#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4) 42#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4)
42#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8) 43#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8)
44#define S3C2412_EINTMASK S3C2410_EINTREG(0x0B4)
45#define S3C2412_EINTPEND S3C2410_EINTREG(0X0B8)
46
47#define S3C24XX_EINTMASK S3C24XX_EINTREG(0x0A4)
48#define S3C24XX_EINTPEND S3C24XX_EINTREG(0X0A8)
43 49
44#endif /* ___ASM_ARCH_REGS_IRQ_H */ 50#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
index 83b01254c4ac..93f651ae2967 100644
--- a/include/asm-arm/arch-s3c2410/regs-serial.h
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h
@@ -82,6 +82,12 @@
82#define S3C2440_UCON2_DIVMASK (7 << 12) 82#define S3C2440_UCON2_DIVMASK (7 << 12)
83#define S3C2440_UCON_DIVSHIFT (12) 83#define S3C2440_UCON_DIVSHIFT (12)
84 84
85#define S3C2412_UCON_CLKMASK (3<<10)
86#define S3C2412_UCON_UCLK (1<<10)
87#define S3C2412_UCON_USYSCLK (3<<10)
88#define S3C2412_UCON_PCLK (0<<10)
89#define S3C2412_UCON_PCLK2 (2<<10)
90
85#define S3C2410_UCON_UCLK (1<<10) 91#define S3C2410_UCON_UCLK (1<<10)
86#define S3C2410_UCON_SBREAK (1<<4) 92#define S3C2410_UCON_SBREAK (1<<4)
87 93
@@ -124,6 +130,15 @@
124#define S3C2410_UMCOM_AFC (1<<4) 130#define S3C2410_UMCOM_AFC (1<<4)
125#define S3C2410_UMCOM_RTS_LOW (1<<0) 131#define S3C2410_UMCOM_RTS_LOW (1<<0)
126 132
133#define S3C2412_UMCON_AFC_63 (0<<5)
134#define S3C2412_UMCON_AFC_56 (1<<5)
135#define S3C2412_UMCON_AFC_48 (2<<5)
136#define S3C2412_UMCON_AFC_40 (3<<5)
137#define S3C2412_UMCON_AFC_32 (4<<5)
138#define S3C2412_UMCON_AFC_24 (5<<5)
139#define S3C2412_UMCON_AFC_16 (6<<5)
140#define S3C2412_UMCON_AFC_8 (7<<5)
141
127#define S3C2410_UFSTAT_TXFULL (1<<9) 142#define S3C2410_UFSTAT_TXFULL (1<<9)
128#define S3C2410_UFSTAT_RXFULL (1<<8) 143#define S3C2410_UFSTAT_RXFULL (1<<8)
129#define S3C2410_UFSTAT_TXMASK (15<<4) 144#define S3C2410_UFSTAT_TXMASK (15<<4)
diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h
index 040ccde7a11e..0756269404b1 100644
--- a/include/asm-arm/arch-sa1100/io.h
+++ b/include/asm-arm/arch-sa1100/io.h
@@ -22,6 +22,5 @@ static inline void __iomem *__io(unsigned long addr)
22} 22}
23#define __io(a) __io(a) 23#define __io(a) __io(a)
24#define __mem_pci(a) (a) 24#define __mem_pci(a) (a)
25#define __mem_isa(a) (a)
26 25
27#endif 26#endif
diff --git a/include/asm-arm/arch-versatile/io.h b/include/asm-arm/arch-versatile/io.h
index 47e904cf25c7..c4d01948e00b 100644
--- a/include/asm-arm/arch-versatile/io.h
+++ b/include/asm-arm/arch-versatile/io.h
@@ -28,6 +28,5 @@ static inline void __iomem *__io(unsigned long addr)
28} 28}
29#define __io(a) __io(a) 29#define __io(a) __io(a)
30#define __mem_pci(a) (a) 30#define __mem_pci(a) (a)
31#define __mem_isa(a) (a)
32 31
33#endif 32#endif
diff --git a/include/asm-arm/ucontext.h b/include/asm-arm/ucontext.h
index f853130137cc..9e6f7ca9f5ae 100644
--- a/include/asm-arm/ucontext.h
+++ b/include/asm-arm/ucontext.h
@@ -1,12 +1,89 @@
1#ifndef _ASMARM_UCONTEXT_H 1#ifndef _ASMARM_UCONTEXT_H
2#define _ASMARM_UCONTEXT_H 2#define _ASMARM_UCONTEXT_H
3 3
4#include <asm/fpstate.h>
5
6/*
7 * struct sigcontext only has room for the basic registers, but struct
8 * ucontext now has room for all registers which need to be saved and
9 * restored. Coprocessor registers are stored in uc_regspace. Each
10 * coprocessor's saved state should start with a documented 32-bit magic
11 * number, followed by a 32-bit word giving the coproccesor's saved size.
12 * uc_regspace may be expanded if necessary, although this takes some
13 * coordination with glibc.
14 */
15
4struct ucontext { 16struct ucontext {
5 unsigned long uc_flags; 17 unsigned long uc_flags;
6 struct ucontext *uc_link; 18 struct ucontext *uc_link;
7 stack_t uc_stack; 19 stack_t uc_stack;
8 struct sigcontext uc_mcontext; 20 struct sigcontext uc_mcontext;
9 sigset_t uc_sigmask; /* mask last for extensibility */ 21 sigset_t uc_sigmask;
22 /* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
23 int __unused[32 - (sizeof (sigset_t) / sizeof (int))];
24 /* Last for extensibility. Eight byte aligned because some
25 coprocessors require eight byte alignment. */
26 unsigned long uc_regspace[128] __attribute__((__aligned__(8)));
10}; 27};
11 28
29#ifdef __KERNEL__
30
31/*
32 * Coprocessor save state. The magic values and specific
33 * coprocessor's layouts are part of the userspace ABI. Each one of
34 * these should be a multiple of eight bytes and aligned to eight
35 * bytes, to prevent unpredictable padding in the signal frame.
36 */
37
38#ifdef CONFIG_IWMMXT
39/* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */
40#define IWMMXT_MAGIC 0x12ef842a
41#define IWMMXT_STORAGE_SIZE (IWMMXT_SIZE + 8)
42
43struct iwmmxt_sigframe {
44 unsigned long magic;
45 unsigned long size;
46 struct iwmmxt_struct storage;
47} __attribute__((__aligned__(8)));
48#endif /* CONFIG_IWMMXT */
49
50#ifdef CONFIG_VFP
51#if __LINUX_ARM_ARCH__ < 6
52/* For ARM pre-v6, we use fstmiax and fldmiax. This adds one extra
53 * word after the registers, and a word of padding at the end for
54 * alignment. */
55#define VFP_MAGIC 0x56465001
56#define VFP_STORAGE_SIZE 152
57#else
58#define VFP_MAGIC 0x56465002
59#define VFP_STORAGE_SIZE 144
60#endif
61
62struct vfp_sigframe
63{
64 unsigned long magic;
65 unsigned long size;
66 union vfp_state storage;
67};
68#endif /* CONFIG_VFP */
69
70/*
71 * Auxiliary signal frame. This saves stuff like FP state.
72 * The layout of this structure is not part of the user ABI,
73 * because the config options aren't. uc_regspace is really
74 * one of these.
75 */
76struct aux_sigframe {
77#ifdef CONFIG_IWMMXT
78 struct iwmmxt_sigframe iwmmxt;
79#endif
80#if 0 && defined CONFIG_VFP /* Not yet saved. */
81 struct vfp_sigframe vfp;
82#endif
83 /* Something that isn't a valid magic number for any coprocessor. */
84 unsigned long end_magic;
85} __attribute__((__aligned__(8)));
86
87#endif
88
12#endif /* !_ASMARM_UCONTEXT_H */ 89#endif /* !_ASMARM_UCONTEXT_H */
diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
index cef08db34ada..4087037a4225 100644
--- a/include/asm-generic/rtc.h
+++ b/include/asm-generic/rtc.h
@@ -114,6 +114,7 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
114/* Set the current date and time in the real time clock. */ 114/* Set the current date and time in the real time clock. */
115static inline int set_rtc_time(struct rtc_time *time) 115static inline int set_rtc_time(struct rtc_time *time)
116{ 116{
117 unsigned long flags;
117 unsigned char mon, day, hrs, min, sec; 118 unsigned char mon, day, hrs, min, sec;
118 unsigned char save_control, save_freq_select; 119 unsigned char save_control, save_freq_select;
119 unsigned int yrs; 120 unsigned int yrs;
@@ -131,7 +132,7 @@ static inline int set_rtc_time(struct rtc_time *time)
131 if (yrs > 255) /* They are unsigned */ 132 if (yrs > 255) /* They are unsigned */
132 return -EINVAL; 133 return -EINVAL;
133 134
134 spin_lock_irq(&rtc_lock); 135 spin_lock_irqsave(&rtc_lock, flags);
135#ifdef CONFIG_MACH_DECSTATION 136#ifdef CONFIG_MACH_DECSTATION
136 real_yrs = yrs; 137 real_yrs = yrs;
137 leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) || 138 leap_yr = ((!((yrs + 1900) % 4) && ((yrs + 1900) % 100)) ||
@@ -152,7 +153,7 @@ static inline int set_rtc_time(struct rtc_time *time)
152 * whether the chip is in binary mode or not. 153 * whether the chip is in binary mode or not.
153 */ 154 */
154 if (yrs > 169) { 155 if (yrs > 169) {
155 spin_unlock_irq(&rtc_lock); 156 spin_unlock_irqrestore(&rtc_lock, flags);
156 return -EINVAL; 157 return -EINVAL;
157 } 158 }
158 159
@@ -187,7 +188,7 @@ static inline int set_rtc_time(struct rtc_time *time)
187 CMOS_WRITE(save_control, RTC_CONTROL); 188 CMOS_WRITE(save_control, RTC_CONTROL);
188 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 189 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
189 190
190 spin_unlock_irq(&rtc_lock); 191 spin_unlock_irqrestore(&rtc_lock, flags);
191 192
192 return 0; 193 return 0;
193} 194}
diff --git a/include/asm-sparc/ebus.h b/include/asm-sparc/ebus.h
index 2d6a997c5b0c..54652887c127 100644
--- a/include/asm-sparc/ebus.h
+++ b/include/asm-sparc/ebus.h
@@ -13,13 +13,14 @@
13#include <linux/ioport.h> 13#include <linux/ioport.h>
14#endif 14#endif
15#include <asm/oplib.h> 15#include <asm/oplib.h>
16#include <asm/prom.h>
17#include <asm/of_device.h>
16 18
17struct linux_ebus_child { 19struct linux_ebus_child {
18 struct linux_ebus_child *next; 20 struct linux_ebus_child *next;
19 struct linux_ebus_device *parent; 21 struct linux_ebus_device *parent;
20 struct linux_ebus *bus; 22 struct linux_ebus *bus;
21 int prom_node; 23 struct device_node *prom_node;
22 char prom_name[64];
23 struct resource resource[PROMREG_MAX]; 24 struct resource resource[PROMREG_MAX];
24 int num_addrs; 25 int num_addrs;
25 unsigned int irqs[PROMINTR_MAX]; 26 unsigned int irqs[PROMINTR_MAX];
@@ -27,27 +28,27 @@ struct linux_ebus_child {
27}; 28};
28 29
29struct linux_ebus_device { 30struct linux_ebus_device {
31 struct of_device ofdev;
30 struct linux_ebus_device *next; 32 struct linux_ebus_device *next;
31 struct linux_ebus_child *children; 33 struct linux_ebus_child *children;
32 struct linux_ebus *bus; 34 struct linux_ebus *bus;
33 int prom_node; 35 struct device_node *prom_node;
34 char prom_name[64];
35 struct resource resource[PROMREG_MAX]; 36 struct resource resource[PROMREG_MAX];
36 int num_addrs; 37 int num_addrs;
37 unsigned int irqs[PROMINTR_MAX]; 38 unsigned int irqs[PROMINTR_MAX];
38 int num_irqs; 39 int num_irqs;
39}; 40};
41#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
40 42
41struct linux_ebus { 43struct linux_ebus {
44 struct of_device ofdev;
42 struct linux_ebus *next; 45 struct linux_ebus *next;
43 struct linux_ebus_device *devices; 46 struct linux_ebus_device *devices;
44 struct linux_pbm_info *parent; 47 struct linux_pbm_info *parent;
45 struct pci_dev *self; 48 struct pci_dev *self;
46 int prom_node; 49 struct device_node *prom_node;
47 char prom_name[64];
48 struct linux_prom_ebus_ranges ebus_ranges[PROMREG_MAX];
49 int num_ebus_ranges;
50}; 50};
51#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
51 52
52struct linux_ebus_dma { 53struct linux_ebus_dma {
53 unsigned int dcsr; 54 unsigned int dcsr;
diff --git a/include/asm-sparc/of_device.h b/include/asm-sparc/of_device.h
new file mode 100644
index 000000000000..4816d102f918
--- /dev/null
+++ b/include/asm-sparc/of_device.h
@@ -0,0 +1,63 @@
1#ifndef _ASM_SPARC_OF_DEVICE_H
2#define _ASM_SPARC_OF_DEVICE_H
3#ifdef __KERNEL__
4
5#include <linux/device.h>
6#include <linux/mod_devicetable.h>
7#include <asm/prom.h>
8
9extern struct bus_type ebus_bus_type;
10extern struct bus_type sbus_bus_type;
11
12/*
13 * The of_device is a kind of "base class" that is a superset of
14 * struct device for use by devices attached to an OF node and
15 * probed using OF properties.
16 */
17struct of_device
18{
19 struct device_node *node; /* OF device node */
20 struct device dev; /* Generic device interface */
21};
22#define to_of_device(d) container_of(d, struct of_device, dev)
23
24extern const struct of_device_id *of_match_device(
25 const struct of_device_id *matches, const struct of_device *dev);
26
27extern struct of_device *of_dev_get(struct of_device *dev);
28extern void of_dev_put(struct of_device *dev);
29
30/*
31 * An of_platform_driver driver is attached to a basic of_device on
32 * the ISA, EBUS, and SBUS busses on sparc64.
33 */
34struct of_platform_driver
35{
36 char *name;
37 struct of_device_id *match_table;
38 struct module *owner;
39
40 int (*probe)(struct of_device* dev, const struct of_device_id *match);
41 int (*remove)(struct of_device* dev);
42
43 int (*suspend)(struct of_device* dev, pm_message_t state);
44 int (*resume)(struct of_device* dev);
45 int (*shutdown)(struct of_device* dev);
46
47 struct device_driver driver;
48};
49#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
50
51extern int of_register_driver(struct of_platform_driver *drv,
52 struct bus_type *bus);
53extern void of_unregister_driver(struct of_platform_driver *drv);
54extern int of_device_register(struct of_device *ofdev);
55extern void of_device_unregister(struct of_device *ofdev);
56extern struct of_device *of_platform_device_create(struct device_node *np,
57 const char *bus_id,
58 struct device *parent,
59 struct bus_type *bus);
60extern void of_release_dev(struct device *dev);
61
62#endif /* __KERNEL__ */
63#endif /* _ASM_SPARC_OF_DEVICE_H */
diff --git a/include/asm-sparc/pbm.h b/include/asm-sparc/pbm.h
index 0aba3a82c2eb..fedd9c6e875c 100644
--- a/include/asm-sparc/pbm.h
+++ b/include/asm-sparc/pbm.h
@@ -22,6 +22,7 @@
22 22
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <asm/oplib.h> 24#include <asm/oplib.h>
25#include <asm/prom.h>
25 26
26struct linux_pbm_info { 27struct linux_pbm_info {
27 int prom_node; 28 int prom_node;
@@ -40,7 +41,7 @@ struct linux_pbm_info {
40 */ 41 */
41struct pcidev_cookie { 42struct pcidev_cookie {
42 struct linux_pbm_info *pbm; 43 struct linux_pbm_info *pbm;
43 int prom_node; 44 struct device_node *prom_node;
44}; 45};
45 46
46#endif /* !(__SPARC_PBM_H) */ 47#endif /* !(__SPARC_PBM_H) */
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
new file mode 100644
index 000000000000..c5e3d26eabd3
--- /dev/null
+++ b/include/asm-sparc/prom.h
@@ -0,0 +1,98 @@
1#ifndef _SPARC_PROM_H
2#define _SPARC_PROM_H
3#ifdef __KERNEL__
4
5
6/*
7 * Definitions for talking to the Open Firmware PROM on
8 * Power Macintosh computers.
9 *
10 * Copyright (C) 1996-2005 Paul Mackerras.
11 *
12 * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
13 * Updates for SPARC32 by David S. Miller
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 */
20
21#include <linux/types.h>
22#include <linux/proc_fs.h>
23#include <asm/atomic.h>
24
25typedef u32 phandle;
26typedef u32 ihandle;
27
28struct interrupt_info {
29 int line;
30 int sense; /* +ve/-ve logic, edge or level, etc. */
31};
32
33struct property {
34 char *name;
35 int length;
36 void *value;
37 struct property *next;
38};
39
40struct device_node {
41 char *name;
42 char *type;
43 phandle node;
44 phandle linux_phandle;
45 int n_intrs;
46 struct interrupt_info *intrs;
47 char *path_component_name;
48 char *full_name;
49
50 struct property *properties;
51 struct property *deadprops; /* removed properties */
52 struct device_node *parent;
53 struct device_node *child;
54 struct device_node *sibling;
55 struct device_node *next; /* next device of same type */
56 struct device_node *allnext; /* next in list of all nodes */
57 struct proc_dir_entry *pde; /* this node's proc directory */
58 struct kref kref;
59 unsigned long _flags;
60 void *data;
61};
62
63static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
64{
65 dn->pde = de;
66}
67
68extern struct device_node *of_find_node_by_name(struct device_node *from,
69 const char *name);
70#define for_each_node_by_name(dn, name) \
71 for (dn = of_find_node_by_name(NULL, name); dn; \
72 dn = of_find_node_by_name(dn, name))
73extern struct device_node *of_find_node_by_type(struct device_node *from,
74 const char *type);
75#define for_each_node_by_type(dn, type) \
76 for (dn = of_find_node_by_type(NULL, type); dn; \
77 dn = of_find_node_by_type(dn, type))
78extern struct device_node *of_find_compatible_node(struct device_node *from,
79 const char *type, const char *compat);
80extern struct device_node *of_find_node_by_path(const char *path);
81extern struct device_node *of_find_node_by_phandle(phandle handle);
82extern struct device_node *of_get_parent(const struct device_node *node);
83extern struct device_node *of_get_next_child(const struct device_node *node,
84 struct device_node *prev);
85extern struct property *of_find_property(struct device_node *np,
86 const char *name,
87 int *lenp);
88extern int of_device_is_compatible(struct device_node *device, const char *);
89extern void *of_get_property(struct device_node *node, const char *name,
90 int *lenp);
91extern int of_getintprop_default(struct device_node *np,
92 const char *name,
93 int def);
94
95extern void prom_build_devicetree(void);
96
97#endif /* __KERNEL__ */
98#endif /* _SPARC_PROM_H */
diff --git a/include/asm-sparc/sbus.h b/include/asm-sparc/sbus.h
index a13cddcecec5..d036e4419d79 100644
--- a/include/asm-sparc/sbus.h
+++ b/include/asm-sparc/sbus.h
@@ -11,7 +11,8 @@
11#include <linux/ioport.h> 11#include <linux/ioport.h>
12 12
13#include <asm/oplib.h> 13#include <asm/oplib.h>
14/* #include <asm/iommu.h> */ /* Unused since we use opaque iommu (|io-unit) */ 14#include <asm/prom.h>
15#include <asm/of_device.h>
15#include <asm/scatterlist.h> 16#include <asm/scatterlist.h>
16 17
17/* We scan which devices are on the SBus using the PROM node device 18/* We scan which devices are on the SBus using the PROM node device
@@ -42,18 +43,19 @@ struct sbus_bus;
42 43
43/* Linux SBUS device tables */ 44/* Linux SBUS device tables */
44struct sbus_dev { 45struct sbus_dev {
45 struct sbus_bus *bus; /* Back ptr to sbus */ 46 struct of_device ofdev;
46 struct sbus_dev *next; /* next device on this SBus or null */ 47 struct sbus_bus *bus;
47 struct sbus_dev *child; /* For ledma and espdma on sun4m */ 48 struct sbus_dev *next;
48 struct sbus_dev *parent; /* Parent device if not toplevel */ 49 struct sbus_dev *child;
49 int prom_node; /* PROM device tree node for this device */ 50 struct sbus_dev *parent;
50 char prom_name[64]; /* PROM device name */ 51 int prom_node;
52 char prom_name[64];
51 int slot; 53 int slot;
52 54
53 struct resource resource[PROMREG_MAX]; 55 struct resource resource[PROMREG_MAX];
54 56
55 struct linux_prom_registers reg_addrs[PROMREG_MAX]; 57 struct linux_prom_registers reg_addrs[PROMREG_MAX];
56 int num_registers, ranges_applied; 58 int num_registers;
57 59
58 struct linux_prom_ranges device_ranges[PROMREG_MAX]; 60 struct linux_prom_ranges device_ranges[PROMREG_MAX];
59 int num_device_ranges; 61 int num_device_ranges;
@@ -61,9 +63,11 @@ struct sbus_dev {
61 unsigned int irqs[4]; 63 unsigned int irqs[4];
62 int num_irqs; 64 int num_irqs;
63}; 65};
66#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
64 67
65/* This struct describes the SBus(s) found on this machine. */ 68/* This struct describes the SBus(s) found on this machine. */
66struct sbus_bus { 69struct sbus_bus {
70 struct of_device ofdev;
67 void *iommu; /* Opaque IOMMU cookie */ 71 void *iommu; /* Opaque IOMMU cookie */
68 struct sbus_dev *devices; /* Link to devices on this SBus */ 72 struct sbus_dev *devices; /* Link to devices on this SBus */
69 struct sbus_bus *next; /* next SBus, if more than one SBus */ 73 struct sbus_bus *next; /* next SBus, if more than one SBus */
@@ -77,6 +81,7 @@ struct sbus_bus {
77 int devid; 81 int devid;
78 int board; 82 int board;
79}; 83};
84#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
80 85
81extern struct sbus_bus *sbus_root; 86extern struct sbus_bus *sbus_root;
82 87
@@ -102,6 +107,7 @@ sbus_is_slave(struct sbus_dev *dev)
102#define sbus_can_dma_64bit(sdev) (0) /* actually, sparc_cpu_model==sun4d */ 107#define sbus_can_dma_64bit(sdev) (0) /* actually, sparc_cpu_model==sun4d */
103#define sbus_can_burst64(sdev) (0) /* actually, sparc_cpu_model==sun4d */ 108#define sbus_can_burst64(sdev) (0) /* actually, sparc_cpu_model==sun4d */
104extern void sbus_set_sbus64(struct sbus_dev *, int); 109extern void sbus_set_sbus64(struct sbus_dev *, int);
110extern void sbus_fill_device_irq(struct sbus_dev *);
105 111
106/* These yield IOMMU mappings in consistent mode. */ 112/* These yield IOMMU mappings in consistent mode. */
107extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp); 113extern void *sbus_alloc_consistent(struct sbus_dev *, long, u32 *dma_addrp);
@@ -139,4 +145,10 @@ extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *,
139BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int) 145BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int)
140#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint) 146#define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint)
141 147
148extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
149extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
150extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
151extern int sbus_arch_preinit(void);
152extern void sbus_arch_postinit(void);
153
142#endif /* !(_SPARC_SBUS_H) */ 154#endif /* !(_SPARC_SBUS_H) */
diff --git a/include/asm-sparc64/ebus.h b/include/asm-sparc64/ebus.h
index 7a408a030f52..a4afe9d5703a 100644
--- a/include/asm-sparc64/ebus.h
+++ b/include/asm-sparc64/ebus.h
@@ -10,13 +10,14 @@
10 10
11#include <asm/pbm.h> 11#include <asm/pbm.h>
12#include <asm/oplib.h> 12#include <asm/oplib.h>
13#include <asm/prom.h>
14#include <asm/of_device.h>
13 15
14struct linux_ebus_child { 16struct linux_ebus_child {
15 struct linux_ebus_child *next; 17 struct linux_ebus_child *next;
16 struct linux_ebus_device *parent; 18 struct linux_ebus_device *parent;
17 struct linux_ebus *bus; 19 struct linux_ebus *bus;
18 int prom_node; 20 struct device_node *prom_node;
19 char prom_name[64];
20 struct resource resource[PROMREG_MAX]; 21 struct resource resource[PROMREG_MAX];
21 int num_addrs; 22 int num_addrs;
22 unsigned int irqs[PROMINTR_MAX]; 23 unsigned int irqs[PROMINTR_MAX];
@@ -24,32 +25,29 @@ struct linux_ebus_child {
24}; 25};
25 26
26struct linux_ebus_device { 27struct linux_ebus_device {
28 struct of_device ofdev;
27 struct linux_ebus_device *next; 29 struct linux_ebus_device *next;
28 struct linux_ebus_child *children; 30 struct linux_ebus_child *children;
29 struct linux_ebus *bus; 31 struct linux_ebus *bus;
30 int prom_node; 32 struct device_node *prom_node;
31 char prom_name[64];
32 struct resource resource[PROMREG_MAX]; 33 struct resource resource[PROMREG_MAX];
33 int num_addrs; 34 int num_addrs;
34 unsigned int irqs[PROMINTR_MAX]; 35 unsigned int irqs[PROMINTR_MAX];
35 int num_irqs; 36 int num_irqs;
36}; 37};
38#define to_ebus_device(d) container_of(d, struct linux_ebus_device, ofdev.dev)
37 39
38struct linux_ebus { 40struct linux_ebus {
41 struct of_device ofdev;
39 struct linux_ebus *next; 42 struct linux_ebus *next;
40 struct linux_ebus_device *devices; 43 struct linux_ebus_device *devices;
41 struct pci_pbm_info *parent; 44 struct pci_pbm_info *parent;
42 struct pci_dev *self; 45 struct pci_dev *self;
43 int index; 46 int index;
44 int is_rio; 47 int is_rio;
45 int prom_node; 48 struct device_node *prom_node;
46 char prom_name[64];
47 struct linux_prom_ebus_ranges ebus_ranges[PROMREG_MAX];
48 int num_ebus_ranges;
49 struct linux_prom_ebus_intmap ebus_intmap[PROMREG_MAX];
50 int num_ebus_intmap;
51 struct linux_prom_ebus_intmask ebus_intmask;
52}; 49};
50#define to_ebus(d) container_of(d, struct linux_ebus, ofdev.dev)
53 51
54struct ebus_dma_info { 52struct ebus_dma_info {
55 spinlock_t lock; 53 spinlock_t lock;
diff --git a/include/asm-sparc64/fhc.h b/include/asm-sparc64/fhc.h
index f29eaa254055..9e7f1b0d78b9 100644
--- a/include/asm-sparc64/fhc.h
+++ b/include/asm-sparc64/fhc.h
@@ -10,6 +10,7 @@
10#include <linux/timer.h> 10#include <linux/timer.h>
11 11
12#include <asm/oplib.h> 12#include <asm/oplib.h>
13#include <asm/prom.h>
13#include <asm/upa.h> 14#include <asm/upa.h>
14 15
15struct linux_fhc; 16struct linux_fhc;
@@ -34,8 +35,7 @@ struct linux_central {
34 unsigned long clkregs; 35 unsigned long clkregs;
35 unsigned long clkver; 36 unsigned long clkver;
36 int slots; 37 int slots;
37 int prom_node; 38 struct device_node *prom_node;
38 char prom_name[64];
39 39
40 struct linux_prom_ranges central_ranges[PROMREG_MAX]; 40 struct linux_prom_ranges central_ranges[PROMREG_MAX];
41 int num_central_ranges; 41 int num_central_ranges;
@@ -112,8 +112,7 @@ struct linux_fhc {
112 struct fhc_regs fhc_regs; 112 struct fhc_regs fhc_regs;
113 int board; 113 int board;
114 int jtag_master; 114 int jtag_master;
115 int prom_node; 115 struct device_node *prom_node;
116 char prom_name[64];
117 116
118 struct linux_prom_ranges fhc_ranges[PROMREG_MAX]; 117 struct linux_prom_ranges fhc_ranges[PROMREG_MAX];
119 int num_fhc_ranges; 118 int num_fhc_ranges;
diff --git a/include/asm-sparc64/floppy.h b/include/asm-sparc64/floppy.h
index 07ccd6f04b52..f8d57bb5570c 100644
--- a/include/asm-sparc64/floppy.h
+++ b/include/asm-sparc64/floppy.h
@@ -498,15 +498,14 @@ static int sun_pci_fd_test_drive(unsigned long port, int drive)
498#ifdef CONFIG_PCI 498#ifdef CONFIG_PCI
499static int __init ebus_fdthree_p(struct linux_ebus_device *edev) 499static int __init ebus_fdthree_p(struct linux_ebus_device *edev)
500{ 500{
501 if (!strcmp(edev->prom_name, "fdthree")) 501 if (!strcmp(edev->prom_node->name, "fdthree"))
502 return 1; 502 return 1;
503 if (!strcmp(edev->prom_name, "floppy")) { 503 if (!strcmp(edev->prom_node->name, "floppy")) {
504 char compat[16]; 504 char *compat;
505 prom_getstring(edev->prom_node, 505
506 "compatible", 506 compat = of_get_property(edev->prom_node,
507 compat, sizeof(compat)); 507 "compatible", NULL);
508 compat[15] = '\0'; 508 if (compat && !strcmp(compat, "fdthree"))
509 if (!strcmp(compat, "fdthree"))
510 return 1; 509 return 1;
511 } 510 }
512 return 0; 511 return 0;
@@ -524,12 +523,12 @@ static unsigned long __init isa_floppy_init(void)
524 523
525 for_each_isa(isa_br) { 524 for_each_isa(isa_br) {
526 for_each_isadev(isa_dev, isa_br) { 525 for_each_isadev(isa_dev, isa_br) {
527 if (!strcmp(isa_dev->prom_name, "dma")) { 526 if (!strcmp(isa_dev->prom_node->name, "dma")) {
528 struct sparc_isa_device *child = 527 struct sparc_isa_device *child =
529 isa_dev->child; 528 isa_dev->child;
530 529
531 while (child) { 530 while (child) {
532 if (!strcmp(child->prom_name, 531 if (!strcmp(child->prom_node->name,
533 "floppy")) { 532 "floppy")) {
534 isa_dev = child; 533 isa_dev = child;
535 goto isa_done; 534 goto isa_done;
@@ -614,6 +613,7 @@ static unsigned long __init sun_floppy_init(void)
614 struct linux_ebus_device *edev = NULL; 613 struct linux_ebus_device *edev = NULL;
615 unsigned long config = 0; 614 unsigned long config = 0;
616 void __iomem *auxio_reg; 615 void __iomem *auxio_reg;
616 char *state_prop;
617 617
618 for_each_ebus(ebus) { 618 for_each_ebus(ebus) {
619 for_each_ebusdev(edev, ebus) { 619 for_each_ebusdev(edev, ebus) {
@@ -630,9 +630,8 @@ static unsigned long __init sun_floppy_init(void)
630#endif 630#endif
631 } 631 }
632 632
633 prom_getproperty(edev->prom_node, "status", 633 state_prop = of_get_property(edev->prom_node, "status", NULL);
634 state, sizeof(state)); 634 if (state_prop && !strncmp(state_prop, "disabled", 8))
635 if (!strncmp(state, "disabled", 8))
636 return 0; 635 return 0;
637 636
638 FLOPPY_IRQ = edev->irqs[0]; 637 FLOPPY_IRQ = edev->irqs[0];
@@ -703,7 +702,7 @@ static unsigned long __init sun_floppy_init(void)
703 */ 702 */
704 for_each_ebus(ebus) { 703 for_each_ebus(ebus) {
705 for_each_ebusdev(edev, ebus) { 704 for_each_ebusdev(edev, ebus) {
706 if (!strcmp(edev->prom_name, "ecpp")) { 705 if (!strcmp(edev->prom_node->name, "ecpp")) {
707 config = edev->resource[1].start; 706 config = edev->resource[1].start;
708 goto config_done; 707 goto config_done;
709 } 708 }
diff --git a/include/asm-sparc64/isa.h b/include/asm-sparc64/isa.h
index 4601bbfc3e7b..d9728b9031fc 100644
--- a/include/asm-sparc64/isa.h
+++ b/include/asm-sparc64/isa.h
@@ -9,37 +9,32 @@
9 9
10#include <asm/pbm.h> 10#include <asm/pbm.h>
11#include <asm/oplib.h> 11#include <asm/oplib.h>
12#include <asm/prom.h>
13#include <asm/of_device.h>
12 14
13struct sparc_isa_bridge; 15struct sparc_isa_bridge;
14 16
15struct sparc_isa_device { 17struct sparc_isa_device {
18 struct of_device ofdev;
16 struct sparc_isa_device *next; 19 struct sparc_isa_device *next;
17 struct sparc_isa_device *child; 20 struct sparc_isa_device *child;
18 struct sparc_isa_bridge *bus; 21 struct sparc_isa_bridge *bus;
19 int prom_node; 22 struct device_node *prom_node;
20 char prom_name[64];
21 char compatible[64];
22 struct resource resource; 23 struct resource resource;
23 unsigned int irq; 24 unsigned int irq;
24}; 25};
26#define to_isa_device(d) container_of(d, struct sparc_isa_device, ofdev.dev)
25 27
26struct sparc_isa_bridge { 28struct sparc_isa_bridge {
29 struct of_device ofdev;
27 struct sparc_isa_bridge *next; 30 struct sparc_isa_bridge *next;
28 struct sparc_isa_device *devices; 31 struct sparc_isa_device *devices;
29 struct pci_pbm_info *parent; 32 struct pci_pbm_info *parent;
30 struct pci_dev *self; 33 struct pci_dev *self;
31 int index; 34 int index;
32 int prom_node; 35 struct device_node *prom_node;
33 char prom_name[64];
34#define linux_prom_isa_ranges linux_prom_ebus_ranges
35 struct linux_prom_isa_ranges isa_ranges[PROMREG_MAX];
36 int num_isa_ranges;
37#define linux_prom_isa_intmap linux_prom_ebus_intmap
38 struct linux_prom_isa_intmap isa_intmap[PROMREG_MAX];
39 int num_isa_intmap;
40#define linux_prom_isa_intmask linux_prom_ebus_intmask
41 struct linux_prom_isa_intmap isa_intmask;
42}; 36};
37#define to_isa_bridge(d) container_of(d, struct sparc_isa_bridge, ofdev.dev)
43 38
44extern struct sparc_isa_bridge *isa_chain; 39extern struct sparc_isa_bridge *isa_chain;
45 40
diff --git a/include/asm-sparc64/of_device.h b/include/asm-sparc64/of_device.h
new file mode 100644
index 000000000000..024088ef9d27
--- /dev/null
+++ b/include/asm-sparc64/of_device.h
@@ -0,0 +1,64 @@
1#ifndef _ASM_SPARC64_OF_DEVICE_H
2#define _ASM_SPARC64_OF_DEVICE_H
3#ifdef __KERNEL__
4
5#include <linux/device.h>
6#include <linux/mod_devicetable.h>
7#include <asm/prom.h>
8
9extern struct bus_type isa_bus_type;
10extern struct bus_type ebus_bus_type;
11extern struct bus_type sbus_bus_type;
12
13/*
14 * The of_device is a kind of "base class" that is a superset of
15 * struct device for use by devices attached to an OF node and
16 * probed using OF properties.
17 */
18struct of_device
19{
20 struct device_node *node; /* OF device node */
21 struct device dev; /* Generic device interface */
22};
23#define to_of_device(d) container_of(d, struct of_device, dev)
24
25extern const struct of_device_id *of_match_device(
26 const struct of_device_id *matches, const struct of_device *dev);
27
28extern struct of_device *of_dev_get(struct of_device *dev);
29extern void of_dev_put(struct of_device *dev);
30
31/*
32 * An of_platform_driver driver is attached to a basic of_device on
33 * the ISA, EBUS, and SBUS busses on sparc64.
34 */
35struct of_platform_driver
36{
37 char *name;
38 struct of_device_id *match_table;
39 struct module *owner;
40
41 int (*probe)(struct of_device* dev, const struct of_device_id *match);
42 int (*remove)(struct of_device* dev);
43
44 int (*suspend)(struct of_device* dev, pm_message_t state);
45 int (*resume)(struct of_device* dev);
46 int (*shutdown)(struct of_device* dev);
47
48 struct device_driver driver;
49};
50#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
51
52extern int of_register_driver(struct of_platform_driver *drv,
53 struct bus_type *bus);
54extern void of_unregister_driver(struct of_platform_driver *drv);
55extern int of_device_register(struct of_device *ofdev);
56extern void of_device_unregister(struct of_device *ofdev);
57extern struct of_device *of_platform_device_create(struct device_node *np,
58 const char *bus_id,
59 struct device *parent,
60 struct bus_type *bus);
61extern void of_release_dev(struct device *dev);
62
63#endif /* __KERNEL__ */
64#endif /* _ASM_SPARC64_OF_DEVICE_H */
diff --git a/include/asm-sparc64/oplib.h b/include/asm-sparc64/oplib.h
index dea3e73f0955..a68b0bb05958 100644
--- a/include/asm-sparc64/oplib.h
+++ b/include/asm-sparc64/oplib.h
@@ -323,8 +323,9 @@ extern int prom_pathtoinode(const char *path);
323extern int prom_inst2pkg(int); 323extern int prom_inst2pkg(int);
324 324
325/* CPU probing helpers. */ 325/* CPU probing helpers. */
326int cpu_find_by_instance(int instance, int *prom_node, int *mid); 326struct device_node;
327int cpu_find_by_mid(int mid, int *prom_node); 327int cpu_find_by_instance(int instance, struct device_node **dev_node, int *mid);
328int cpu_find_by_mid(int mid, struct device_node **prom_node);
328 329
329/* Client interface level routines. */ 330/* Client interface level routines. */
330extern void prom_set_trap_table(unsigned long tba); 331extern void prom_set_trap_table(unsigned long tba);
diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h
index 56b5197d7898..d3895873e4c7 100644
--- a/include/asm-sparc64/parport.h
+++ b/include/asm-sparc64/parport.h
@@ -67,18 +67,17 @@ static __inline__ unsigned int get_dma_residue(unsigned int dmanr)
67 67
68static int ebus_ecpp_p(struct linux_ebus_device *edev) 68static int ebus_ecpp_p(struct linux_ebus_device *edev)
69{ 69{
70 if (!strcmp(edev->prom_name, "ecpp")) 70 if (!strcmp(edev->prom_node->name, "ecpp"))
71 return 1; 71 return 1;
72 if (!strcmp(edev->prom_name, "parallel")) { 72 if (!strcmp(edev->prom_node->name, "parallel")) {
73 char compat[19]; 73 char *compat;
74 prom_getstring(edev->prom_node, 74
75 "compatible", 75 compat = of_get_property(edev->prom_node,
76 compat, sizeof(compat)); 76 "compatible", NULL);
77 compat[18] = '\0'; 77 if (compat &&
78 if (!strcmp(compat, "ecpp")) 78 (!strcmp(compat, "ecpp") ||
79 return 1; 79 !strcmp(compat, "ns87317-ecpp") ||
80 if (!strcmp(compat, "ns87317-ecpp") && 80 !strcmp(compat + 13, "ecpp")))
81 !strcmp(compat + 13, "ecpp"))
82 return 1; 81 return 1;
83 } 82 }
84 return 0; 83 return 0;
@@ -94,12 +93,12 @@ static int parport_isa_probe(int count)
94 struct sparc_isa_device *child; 93 struct sparc_isa_device *child;
95 unsigned long base; 94 unsigned long base;
96 95
97 if (strcmp(isa_dev->prom_name, "dma")) 96 if (strcmp(isa_dev->prom_node->name, "dma"))
98 continue; 97 continue;
99 98
100 child = isa_dev->child; 99 child = isa_dev->child;
101 while (child) { 100 while (child) {
102 if (!strcmp(child->prom_name, "parallel")) 101 if (!strcmp(child->prom_node->name, "parallel"))
103 break; 102 break;
104 child = child->next; 103 child = child->next;
105 } 104 }
diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h
index 1396f110939a..cebe80b1da6c 100644
--- a/include/asm-sparc64/pbm.h
+++ b/include/asm-sparc64/pbm.h
@@ -15,6 +15,7 @@
15#include <asm/io.h> 15#include <asm/io.h>
16#include <asm/page.h> 16#include <asm/page.h>
17#include <asm/oplib.h> 17#include <asm/oplib.h>
18#include <asm/prom.h>
18#include <asm/iommu.h> 19#include <asm/iommu.h>
19 20
20/* The abstraction used here is that there are PCI controllers, 21/* The abstraction used here is that there are PCI controllers,
@@ -153,16 +154,15 @@ struct pci_pbm_info {
153 int chip_revision; 154 int chip_revision;
154 155
155 /* Name used for top-level resources. */ 156 /* Name used for top-level resources. */
156 char name[64]; 157 char *name;
157 158
158 /* OBP specific information. */ 159 /* OBP specific information. */
159 int prom_node; 160 struct device_node *prom_node;
160 char prom_name[64]; 161 struct linux_prom_pci_ranges *pbm_ranges;
161 struct linux_prom_pci_ranges pbm_ranges[PROM_PCIRNG_MAX];
162 int num_pbm_ranges; 162 int num_pbm_ranges;
163 struct linux_prom_pci_intmap pbm_intmap[PROM_PCIIMAP_MAX]; 163 struct linux_prom_pci_intmap *pbm_intmap;
164 int num_pbm_intmap; 164 int num_pbm_intmap;
165 struct linux_prom_pci_intmask pbm_intmask; 165 struct linux_prom_pci_intmask *pbm_intmask;
166 u64 ino_bitmap; 166 u64 ino_bitmap;
167 167
168 /* PBM I/O and Memory space resources. */ 168 /* PBM I/O and Memory space resources. */
@@ -227,8 +227,7 @@ struct pci_controller_info {
227 */ 227 */
228struct pcidev_cookie { 228struct pcidev_cookie {
229 struct pci_pbm_info *pbm; 229 struct pci_pbm_info *pbm;
230 char prom_name[64]; 230 struct device_node *prom_node;
231 int prom_node;
232 struct linux_prom_pci_registers prom_regs[PROMREG_MAX]; 231 struct linux_prom_pci_registers prom_regs[PROMREG_MAX];
233 int num_prom_regs; 232 int num_prom_regs;
234 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX]; 233 struct linux_prom_pci_registers prom_assignments[PROMREG_MAX];
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 4e218814bb3c..03f5bc9b6bec 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -756,6 +756,8 @@ extern unsigned long *sparc64_valid_addr_bitmap;
756#define kern_addr_valid(addr) \ 756#define kern_addr_valid(addr) \
757 (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap)) 757 (test_bit(__pa((unsigned long)(addr))>>22, sparc64_valid_addr_bitmap))
758 758
759extern int page_in_phys_avail(unsigned long paddr);
760
759extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, 761extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
760 unsigned long pfn, 762 unsigned long pfn,
761 unsigned long size, pgprot_t prot); 763 unsigned long size, pgprot_t prot);
diff --git a/include/asm-sparc64/prom.h b/include/asm-sparc64/prom.h
new file mode 100644
index 000000000000..6d1556c0c263
--- /dev/null
+++ b/include/asm-sparc64/prom.h
@@ -0,0 +1,98 @@
1#ifndef _SPARC64_PROM_H
2#define _SPARC64_PROM_H
3#ifdef __KERNEL__
4
5
6/*
7 * Definitions for talking to the Open Firmware PROM on
8 * Power Macintosh computers.
9 *
10 * Copyright (C) 1996-2005 Paul Mackerras.
11 *
12 * Updates for PPC64 by Peter Bergner & David Engebretsen, IBM Corp.
13 * Updates for SPARC64 by David S. Miller
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 */
20
21#include <linux/types.h>
22#include <linux/proc_fs.h>
23#include <asm/atomic.h>
24
25typedef u32 phandle;
26typedef u32 ihandle;
27
28struct interrupt_info {
29 int line;
30 int sense; /* +ve/-ve logic, edge or level, etc. */
31};
32
33struct property {
34 char *name;
35 int length;
36 void *value;
37 struct property *next;
38};
39
40struct device_node {
41 char *name;
42 char *type;
43 phandle node;
44 phandle linux_phandle;
45 int n_intrs;
46 struct interrupt_info *intrs;
47 char *path_component_name;
48 char *full_name;
49
50 struct property *properties;
51 struct property *deadprops; /* removed properties */
52 struct device_node *parent;
53 struct device_node *child;
54 struct device_node *sibling;
55 struct device_node *next; /* next device of same type */
56 struct device_node *allnext; /* next in list of all nodes */
57 struct proc_dir_entry *pde; /* this node's proc directory */
58 struct kref kref;
59 unsigned long _flags;
60 void *data;
61};
62
63static inline void set_node_proc_entry(struct device_node *dn, struct proc_dir_entry *de)
64{
65 dn->pde = de;
66}
67
68extern struct device_node *of_find_node_by_name(struct device_node *from,
69 const char *name);
70#define for_each_node_by_name(dn, name) \
71 for (dn = of_find_node_by_name(NULL, name); dn; \
72 dn = of_find_node_by_name(dn, name))
73extern struct device_node *of_find_node_by_type(struct device_node *from,
74 const char *type);
75#define for_each_node_by_type(dn, type) \
76 for (dn = of_find_node_by_type(NULL, type); dn; \
77 dn = of_find_node_by_type(dn, type))
78extern struct device_node *of_find_compatible_node(struct device_node *from,
79 const char *type, const char *compat);
80extern struct device_node *of_find_node_by_path(const char *path);
81extern struct device_node *of_find_node_by_phandle(phandle handle);
82extern struct device_node *of_get_parent(const struct device_node *node);
83extern struct device_node *of_get_next_child(const struct device_node *node,
84 struct device_node *prev);
85extern struct property *of_find_property(struct device_node *np,
86 const char *name,
87 int *lenp);
88extern int of_device_is_compatible(struct device_node *device, const char *);
89extern void *of_get_property(struct device_node *node, const char *name,
90 int *lenp);
91extern int of_getintprop_default(struct device_node *np,
92 const char *name,
93 int def);
94
95extern void prom_build_devicetree(void);
96
97#endif /* __KERNEL__ */
98#endif /* _SPARC64_PROM_H */
diff --git a/include/asm-sparc64/sbus.h b/include/asm-sparc64/sbus.h
index 48279e10f385..56ee985e4605 100644
--- a/include/asm-sparc64/sbus.h
+++ b/include/asm-sparc64/sbus.h
@@ -11,6 +11,8 @@
11#include <linux/ioport.h> 11#include <linux/ioport.h>
12 12
13#include <asm/oplib.h> 13#include <asm/oplib.h>
14#include <asm/prom.h>
15#include <asm/of_device.h>
14#include <asm/iommu.h> 16#include <asm/iommu.h>
15#include <asm/scatterlist.h> 17#include <asm/scatterlist.h>
16 18
@@ -42,18 +44,19 @@ struct sbus_bus;
42 44
43/* Linux SBUS device tables */ 45/* Linux SBUS device tables */
44struct sbus_dev { 46struct sbus_dev {
45 struct sbus_bus *bus; /* Our toplevel parent SBUS */ 47 struct of_device ofdev;
46 struct sbus_dev *next; /* Chain of siblings */ 48 struct sbus_bus *bus;
47 struct sbus_dev *child; /* Chain of children */ 49 struct sbus_dev *next;
48 struct sbus_dev *parent;/* Parent device if not toplevel*/ 50 struct sbus_dev *child;
49 int prom_node; /* OBP node of this device */ 51 struct sbus_dev *parent;
50 char prom_name[64]; /* OBP device name property */ 52 int prom_node;
51 int slot; /* SBUS slot number */ 53 char prom_name[64];
54 int slot;
52 55
53 struct resource resource[PROMREG_MAX]; 56 struct resource resource[PROMREG_MAX];
54 57
55 struct linux_prom_registers reg_addrs[PROMREG_MAX]; 58 struct linux_prom_registers reg_addrs[PROMREG_MAX];
56 int num_registers, ranges_applied; 59 int num_registers;
57 60
58 struct linux_prom_ranges device_ranges[PROMREG_MAX]; 61 struct linux_prom_ranges device_ranges[PROMREG_MAX];
59 int num_device_ranges; 62 int num_device_ranges;
@@ -61,9 +64,11 @@ struct sbus_dev {
61 unsigned int irqs[4]; 64 unsigned int irqs[4];
62 int num_irqs; 65 int num_irqs;
63}; 66};
67#define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev)
64 68
65/* This struct describes the SBus(s) found on this machine. */ 69/* This struct describes the SBus(s) found on this machine. */
66struct sbus_bus { 70struct sbus_bus {
71 struct of_device ofdev;
67 void *iommu; /* Opaque IOMMU cookie */ 72 void *iommu; /* Opaque IOMMU cookie */
68 struct sbus_dev *devices; /* Tree of SBUS devices */ 73 struct sbus_dev *devices; /* Tree of SBUS devices */
69 struct sbus_bus *next; /* Next SBUS in system */ 74 struct sbus_bus *next; /* Next SBUS in system */
@@ -77,6 +82,7 @@ struct sbus_bus {
77 int portid; 82 int portid;
78 void *starfire_cookie; 83 void *starfire_cookie;
79}; 84};
85#define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev)
80 86
81extern struct sbus_bus *sbus_root; 87extern struct sbus_bus *sbus_root;
82 88
@@ -95,6 +101,7 @@ extern struct sbus_bus *sbus_root;
95#define sbus_can_dma_64bit(sdev) (1) 101#define sbus_can_dma_64bit(sdev) (1)
96#define sbus_can_burst64(sdev) (1) 102#define sbus_can_burst64(sdev) (1)
97extern void sbus_set_sbus64(struct sbus_dev *, int); 103extern void sbus_set_sbus64(struct sbus_dev *, int);
104extern void sbus_fill_device_irq(struct sbus_dev *);
98 105
99/* These yield IOMMU mappings in consistent mode. */ 106/* These yield IOMMU mappings in consistent mode. */
100extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp); 107extern void *sbus_alloc_consistent(struct sbus_dev *, size_t, dma_addr_t *dma_addrp);
@@ -119,4 +126,10 @@ extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, in
119#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu 126#define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu
120extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int); 127extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int);
121 128
129extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *);
130extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *);
131extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *);
132extern int sbus_arch_preinit(void);
133extern void sbus_arch_postinit(void);
134
122#endif /* !(_SPARC64_SBUS_H) */ 135#endif /* !(_SPARC64_SBUS_H) */
diff --git a/include/asm-sparc64/vdev.h b/include/asm-sparc64/vdev.h
index 996e6be7b976..25637c57675d 100644
--- a/include/asm-sparc64/vdev.h
+++ b/include/asm-sparc64/vdev.h
@@ -7,10 +7,11 @@
7#define _SPARC64_VDEV_H 7#define _SPARC64_VDEV_H
8 8
9#include <linux/types.h> 9#include <linux/types.h>
10#include <asm/prom.h>
10 11
11extern u32 sun4v_vdev_devhandle; 12extern u32 sun4v_vdev_devhandle;
12extern int sun4v_vdev_root; 13extern struct device_node *sun4v_vdev_root;
13 14
14extern unsigned int sun4v_vdev_device_interrupt(unsigned int); 15extern unsigned int sun4v_vdev_device_interrupt(struct device_node *dev_node);
15 16
16#endif /* !(_SPARC64_VDEV_H) */ 17#endif /* !(_SPARC64_VDEV_H) */
diff --git a/include/linux/resume-trace.h b/include/linux/resume-trace.h
new file mode 100644
index 000000000000..a376bd4ade39
--- /dev/null
+++ b/include/linux/resume-trace.h
@@ -0,0 +1,30 @@
1#ifndef RESUME_TRACE_H
2#define RESUME_TRACE_H
3
4#ifdef CONFIG_PM_TRACE
5
6struct device;
7extern void set_trace_device(struct device *);
8extern void generate_resume_trace(void *tracedata, unsigned int user);
9
10#define TRACE_DEVICE(dev) set_trace_device(dev)
11#define TRACE_RESUME(user) do { \
12 void *tracedata; \
13 asm volatile("movl $1f,%0\n" \
14 ".section .tracedata,\"a\"\n" \
15 "1:\t.word %c1\n" \
16 "\t.long %c2\n" \
17 ".previous" \
18 :"=r" (tracedata) \
19 : "i" (__LINE__), "i" (__FILE__)); \
20 generate_resume_trace(tracedata, user); \
21} while (0)
22
23#else
24
25#define TRACE_DEVICE(dev) do { } while (0)
26#define TRACE_RESUME(dev) do { } while (0)
27
28#endif
29
30#endif
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 0ef50baa7da6..951c4e858274 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -130,6 +130,9 @@
130/* SUN4V Hypervisor Console */ 130/* SUN4V Hypervisor Console */
131#define PORT_SUNHV 72 131#define PORT_SUNHV 72
132 132
133#define PORT_S3C2412 73
134
135
133#ifdef __KERNEL__ 136#ifdef __KERNEL__
134 137
135#include <linux/compiler.h> 138#include <linux/compiler.h>
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index ce0dfb8f4a4e..cdf315e794ff 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -36,6 +36,15 @@ config PM_DEBUG
36 code. This is helpful when debugging and reporting various PM bugs, 36 code. This is helpful when debugging and reporting various PM bugs,
37 like suspend support. 37 like suspend support.
38 38
39config PM_TRACE
40 bool "Suspend/resume event tracing"
41 depends on PM && PM_DEBUG && X86
42 default y
43 ---help---
44 This enables some cheesy code to save the last PM event point in the
45 RTC across reboots, so that you can debug a machine that just hangs
46 during suspend (or more commonly, during resume).
47
39config SOFTWARE_SUSPEND 48config SOFTWARE_SUSPEND
40 bool "Software Suspend" 49 bool "Software Suspend"
41 depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP) 50 depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index dfe9bac7fa32..ba1b2a3443d3 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -46,6 +46,7 @@
46#include <asm/io.h> 46#include <asm/io.h>
47#include <asm/irq.h> 47#include <asm/irq.h>
48#include <asm/sbus.h> 48#include <asm/sbus.h>
49#include <asm/prom.h>
49 50
50static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
51static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
@@ -335,7 +336,6 @@ struct snd_amd7930 {
335 int pgain; 336 int pgain;
336 int mgain; 337 int mgain;
337 338
338 struct sbus_dev *sdev;
339 unsigned int irq; 339 unsigned int irq;
340 unsigned int regs_size; 340 unsigned int regs_size;
341 struct snd_amd7930 *next; 341 struct snd_amd7930 *next;
@@ -946,11 +946,9 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
946}; 946};
947 947
948static int __init snd_amd7930_create(struct snd_card *card, 948static int __init snd_amd7930_create(struct snd_card *card,
949 struct sbus_dev *sdev,
950 struct resource *rp, 949 struct resource *rp,
951 unsigned int reg_size, 950 unsigned int reg_size,
952 struct linux_prom_irqs *irq_prop, 951 int irq, int dev,
953 int dev,
954 struct snd_amd7930 **ramd) 952 struct snd_amd7930 **ramd)
955{ 953{
956 unsigned long flags; 954 unsigned long flags;
@@ -964,7 +962,6 @@ static int __init snd_amd7930_create(struct snd_card *card,
964 962
965 spin_lock_init(&amd->lock); 963 spin_lock_init(&amd->lock);
966 amd->card = card; 964 amd->card = card;
967 amd->sdev = sdev;
968 amd->regs_size = reg_size; 965 amd->regs_size = reg_size;
969 966
970 amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); 967 amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930");
@@ -975,15 +972,14 @@ static int __init snd_amd7930_create(struct snd_card *card,
975 972
976 amd7930_idle(amd); 973 amd7930_idle(amd);
977 974
978 if (request_irq(irq_prop->pri, snd_amd7930_interrupt, 975 if (request_irq(irq, snd_amd7930_interrupt,
979 SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) { 976 SA_INTERRUPT | SA_SHIRQ, "amd7930", amd)) {
980 snd_printk("amd7930-%d: Unable to grab IRQ %d\n", 977 snd_printk("amd7930-%d: Unable to grab IRQ %d\n",
981 dev, 978 dev, irq);
982 irq_prop->pri);
983 snd_amd7930_free(amd); 979 snd_amd7930_free(amd);
984 return -EBUSY; 980 return -EBUSY;
985 } 981 }
986 amd->irq = irq_prop->pri; 982 amd->irq = irq;
987 983
988 amd7930_enable_ints(amd); 984 amd7930_enable_ints(amd);
989 985
@@ -1017,47 +1013,21 @@ static int __init snd_amd7930_create(struct snd_card *card,
1017 return 0; 1013 return 0;
1018} 1014}
1019 1015
1020static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev) 1016static int __init amd7930_attach_common(struct resource *rp, int irq)
1021{ 1017{
1022 static int dev; 1018 static int dev_num;
1023 struct linux_prom_registers reg_prop;
1024 struct linux_prom_irqs irq_prop;
1025 struct resource res, *rp;
1026 struct snd_card *card; 1019 struct snd_card *card;
1027 struct snd_amd7930 *amd; 1020 struct snd_amd7930 *amd;
1028 int err; 1021 int err;
1029 1022
1030 if (dev >= SNDRV_CARDS) 1023 if (dev_num >= SNDRV_CARDS)
1031 return -ENODEV; 1024 return -ENODEV;
1032 if (!enable[dev]) { 1025 if (!enable[dev_num]) {
1033 dev++; 1026 dev_num++;
1034 return -ENOENT; 1027 return -ENOENT;
1035 } 1028 }
1036 1029
1037 err = prom_getproperty(prom_node, "intr", 1030 card = snd_card_new(index[dev_num], id[dev_num], THIS_MODULE, 0);
1038 (char *) &irq_prop, sizeof(irq_prop));
1039 if (err < 0) {
1040 snd_printk("amd7930-%d: Firmware node lacks IRQ property.\n", dev);
1041 return -ENODEV;
1042 }
1043
1044 err = prom_getproperty(prom_node, "reg",
1045 (char *) &reg_prop, sizeof(reg_prop));
1046 if (err < 0) {
1047 snd_printk("amd7930-%d: Firmware node lacks register property.\n", dev);
1048 return -ENODEV;
1049 }
1050
1051 if (sdev) {
1052 rp = &sdev->resource[0];
1053 } else {
1054 rp = &res;
1055 rp->start = reg_prop.phys_addr;
1056 rp->end = rp->start + reg_prop.reg_size - 1;
1057 rp->flags = IORESOURCE_IO | (reg_prop.which_io & 0xff);
1058 }
1059
1060 card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
1061 if (card == NULL) 1031 if (card == NULL)
1062 return -ENOMEM; 1032 return -ENOMEM;
1063 1033
@@ -1067,10 +1037,11 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
1067 card->shortname, 1037 card->shortname,
1068 rp->flags & 0xffL, 1038 rp->flags & 0xffL,
1069 rp->start, 1039 rp->start,
1070 irq_prop.pri); 1040 irq);
1071 1041
1072 if ((err = snd_amd7930_create(card, sdev, rp, reg_prop.reg_size, 1042 if ((err = snd_amd7930_create(card, rp,
1073 &irq_prop, dev, &amd)) < 0) 1043 (rp->end - rp->start) + 1,
1044 irq, dev_num, &amd)) < 0)
1074 goto out_err; 1045 goto out_err;
1075 1046
1076 if ((err = snd_amd7930_pcm(amd)) < 0) 1047 if ((err = snd_amd7930_pcm(amd)) < 0)
@@ -1085,7 +1056,8 @@ static int __init amd7930_attach(int prom_node, struct sbus_dev *sdev)
1085 amd->next = amd7930_list; 1056 amd->next = amd7930_list;
1086 amd7930_list = amd; 1057 amd7930_list = amd;
1087 1058
1088 dev++; 1059 dev_num++;
1060
1089 return 0; 1061 return 0;
1090 1062
1091out_err: 1063out_err:
@@ -1093,29 +1065,71 @@ out_err:
1093 return err; 1065 return err;
1094} 1066}
1095 1067
1096static int __init amd7930_init(void) 1068static int __init amd7930_obio_attach(struct device_node *dp)
1069{
1070 struct linux_prom_registers *regs;
1071 struct linux_prom_irqs *irqp;
1072 struct resource res, *rp;
1073 int len;
1074
1075 irqp = of_get_property(dp, "intr", &len);
1076 if (!irqp) {
1077 snd_printk("%s: Firmware node lacks IRQ property.\n",
1078 dp->full_name);
1079 return -ENODEV;
1080 }
1081
1082 regs = of_get_property(dp, "reg", &len);
1083 if (!regs) {
1084 snd_printk("%s: Firmware node lacks register property.\n",
1085 dp->full_name);
1086 return -ENODEV;
1087 }
1088
1089 rp = &res;
1090 rp->start = regs->phys_addr;
1091 rp->end = rp->start + regs->reg_size - 1;
1092 rp->flags = IORESOURCE_IO | (regs->which_io & 0xff);
1093
1094 return amd7930_attach_common(rp, irqp->pri);
1095}
1096
1097static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1097{ 1098{
1098 struct sbus_bus *sbus; 1099 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1099 struct sbus_dev *sdev;
1100 int node, found;
1101 1100
1102 found = 0; 1101 return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
1102}
1103
1104static struct of_device_id amd7930_match[] = {
1105 {
1106 .name = "audio",
1107 },
1108 {},
1109};
1110
1111static struct of_platform_driver amd7930_sbus_driver = {
1112 .name = "audio",
1113 .match_table = amd7930_match,
1114 .probe = amd7930_sbus_probe,
1115};
1116
1117static int __init amd7930_init(void)
1118{
1119 struct device_node *dp;
1103 1120
1104 /* Try to find the sun4c "audio" node first. */ 1121 /* Try to find the sun4c "audio" node first. */
1105 node = prom_getchild(prom_root_node); 1122 dp = of_find_node_by_path("/");
1106 node = prom_searchsiblings(node, "audio"); 1123 dp = dp->child;
1107 if (node && amd7930_attach(node, NULL) == 0) 1124 while (dp) {
1108 found++; 1125 if (!strcmp(dp->name, "audio"))
1126 amd7930_obio_attach(dp);
1109 1127
1110 /* Probe each SBUS for amd7930 chips. */ 1128 dp = dp->sibling;
1111 for_all_sbusdev(sdev, sbus) {
1112 if (!strcmp(sdev->prom_name, "audio")) {
1113 if (amd7930_attach(sdev->prom_node, sdev) == 0)
1114 found++;
1115 }
1116 } 1129 }
1117 1130
1118 return (found > 0) ? 0 : -EIO; 1131 /* Probe each SBUS for amd7930 chips. */
1132 return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
1119} 1133}
1120 1134
1121static void __exit amd7930_exit(void) 1135static void __exit amd7930_exit(void)
@@ -1131,6 +1145,8 @@ static void __exit amd7930_exit(void)
1131 } 1145 }
1132 1146
1133 amd7930_list = NULL; 1147 amd7930_list = NULL;
1148
1149 of_unregister_driver(&amd7930_sbus_driver);
1134} 1150}
1135 1151
1136module_init(amd7930_init); 1152module_init(amd7930_init);
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index b3efc9aa2916..da54d04a3e3a 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -2284,15 +2284,14 @@ static int __init cs4231_init(void)
2284 for_each_ebusdev(edev, ebus) { 2284 for_each_ebusdev(edev, ebus) {
2285 int match = 0; 2285 int match = 0;
2286 2286
2287 if (!strcmp(edev->prom_name, "SUNW,CS4231")) { 2287 if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) {
2288 match = 1; 2288 match = 1;
2289 } else if (!strcmp(edev->prom_name, "audio")) { 2289 } else if (!strcmp(edev->prom_node->name, "audio")) {
2290 char compat[16]; 2290 char *compat;
2291 2291
2292 prom_getstring(edev->prom_node, "compatible", 2292 compat = of_get_property(edev->prom_node,
2293 compat, sizeof(compat)); 2293 "compatible", NULL);
2294 compat[15] = '\0'; 2294 if (compat && !strcmp(compat, "SUNW,CS4231"))
2295 if (!strcmp(compat, "SUNW,CS4231"))
2296 match = 1; 2295 match = 1;
2297 } 2296 }
2298 2297