aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-27 04:13:12 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 05:15:00 -0400
commita9540d34229c0ec1fceb9a9d1e41ea45d016044d (patch)
tree0e43ae0fa7b18a0f9be60b78b270259c4771525a
parent826b6cfcd5d4c352a461b28694720ac1dcad5813 (diff)
sparc: Convert flash driver to OF device probing.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/sbus/char/flash.c130
1 files changed, 50 insertions, 80 deletions
diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
index 7d95e151513a..715996f5c538 100644
--- a/drivers/sbus/char/flash.c
+++ b/drivers/sbus/char/flash.c
@@ -1,5 +1,4 @@
1/* $Id: flash.c,v 1.25 2001/12/21 04:56:16 davem Exp $ 1/* flash.c: Allow mmap access to the OBP Flash, for OBP updates.
2 * flash.c: Allow mmap access to the OBP Flash, for OBP updates.
3 * 2 *
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) 3 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 */ 4 */
@@ -15,13 +14,13 @@
15#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
16#include <linux/spinlock.h> 15#include <linux/spinlock.h>
17#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/of.h>
18#include <linux/of_device.h>
18 19
19#include <asm/system.h> 20#include <asm/system.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/pgtable.h> 22#include <asm/pgtable.h>
22#include <asm/io.h> 23#include <asm/io.h>
23#include <asm/sbus.h>
24#include <asm/ebus.h>
25#include <asm/upa.h> 24#include <asm/upa.h>
26 25
27static DEFINE_SPINLOCK(flash_lock); 26static DEFINE_SPINLOCK(flash_lock);
@@ -161,97 +160,68 @@ static const struct file_operations flash_fops = {
161 160
162static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops }; 161static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops };
163 162
164static int __init flash_init(void) 163static int __devinit flash_probe(struct of_device *op,
164 const struct of_device_id *match)
165{ 165{
166 struct sbus_bus *sbus; 166 struct device_node *dp = op->node;
167 struct sbus_dev *sdev = NULL; 167 struct device_node *parent;
168#ifdef CONFIG_PCI
169 struct linux_ebus *ebus;
170 struct linux_ebus_device *edev = NULL;
171 struct linux_prom_registers regs[2];
172 int len, nregs;
173#endif
174 int err;
175
176 for_all_sbusdev(sdev, sbus) {
177 if (!strcmp(sdev->prom_name, "flashprom")) {
178 if (sdev->reg_addrs[0].phys_addr == sdev->reg_addrs[1].phys_addr) {
179 flash.read_base = ((unsigned long)sdev->reg_addrs[0].phys_addr) |
180 (((unsigned long)sdev->reg_addrs[0].which_io)<<32UL);
181 flash.read_size = sdev->reg_addrs[0].reg_size;
182 flash.write_base = flash.read_base;
183 flash.write_size = flash.read_size;
184 } else {
185 flash.read_base = ((unsigned long)sdev->reg_addrs[0].phys_addr) |
186 (((unsigned long)sdev->reg_addrs[0].which_io)<<32UL);
187 flash.read_size = sdev->reg_addrs[0].reg_size;
188 flash.write_base = ((unsigned long)sdev->reg_addrs[1].phys_addr) |
189 (((unsigned long)sdev->reg_addrs[1].which_io)<<32UL);
190 flash.write_size = sdev->reg_addrs[1].reg_size;
191 }
192 flash.busy = 0;
193 break;
194 }
195 }
196 if (!sdev) {
197#ifdef CONFIG_PCI
198 const struct linux_prom_registers *ebus_regs;
199
200 for_each_ebus(ebus) {
201 for_each_ebusdev(edev, ebus) {
202 if (!strcmp(edev->prom_node->name, "flashprom"))
203 goto ebus_done;
204 }
205 }
206 ebus_done:
207 if (!edev)
208 return -ENODEV;
209
210 ebus_regs = of_get_property(edev->prom_node, "reg", &len);
211 if (!ebus_regs || (len % sizeof(regs[0])) != 0) {
212 printk("flash: Strange reg property size %d\n", len);
213 return -ENODEV;
214 }
215
216 nregs = len / sizeof(ebus_regs[0]);
217 168
218 flash.read_base = edev->resource[0].start; 169 parent = dp->parent;
219 flash.read_size = ebus_regs[0].reg_size;
220 170
221 if (nregs == 1) { 171 if (strcmp(parent->name, "sbus") &&
222 flash.write_base = edev->resource[0].start; 172 strcmp(parent->name, "sbi") &&
223 flash.write_size = ebus_regs[0].reg_size; 173 strcmp(parent->name, "ebus"))
224 } else if (nregs == 2) {
225 flash.write_base = edev->resource[1].start;
226 flash.write_size = ebus_regs[1].reg_size;
227 } else {
228 printk("flash: Strange number of regs %d\n", nregs);
229 return -ENODEV;
230 }
231
232 flash.busy = 0;
233
234#else
235 return -ENODEV; 174 return -ENODEV;
236#endif 175
176 flash.read_base = op->resource[0].start;
177 flash.read_size = resource_size(&op->resource[0]);
178 if (op->resource[1].flags) {
179 flash.write_base = op->resource[1].start;
180 flash.write_size = resource_size(&op->resource[1]);
181 } else {
182 flash.write_base = op->resource[0].start;
183 flash.write_size = resource_size(&op->resource[0]);
237 } 184 }
185 flash.busy = 0;
238 186
239 printk("OBP Flash: RD %lx[%lx] WR %lx[%lx]\n", 187 printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n",
188 op->node->full_name,
240 flash.read_base, flash.read_size, 189 flash.read_base, flash.read_size,
241 flash.write_base, flash.write_size); 190 flash.write_base, flash.write_size);
242 191
243 err = misc_register(&flash_dev); 192 return misc_register(&flash_dev);
244 if (err) { 193}
245 printk(KERN_ERR "flash: unable to get misc minor\n"); 194
246 return err; 195static int __devexit flash_remove(struct of_device *op)
247 } 196{
197 misc_deregister(&flash_dev);
248 198
249 return 0; 199 return 0;
250} 200}
251 201
202static struct of_device_id flash_match[] = {
203 {
204 .name = "flashprom",
205 },
206 {},
207};
208MODULE_DEVICE_TABLE(of, flash_match);
209
210static struct of_platform_driver flash_driver = {
211 .name = "flash",
212 .match_table = flash_match,
213 .probe = flash_probe,
214 .remove = __devexit_p(flash_remove),
215};
216
217static int __init flash_init(void)
218{
219 return of_register_driver(&flash_driver, &of_bus_type);
220}
221
252static void __exit flash_cleanup(void) 222static void __exit flash_cleanup(void)
253{ 223{
254 misc_deregister(&flash_dev); 224 of_unregister_driver(&flash_driver);
255} 225}
256 226
257module_init(flash_init); 227module_init(flash_init);