aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/kernel/drivers.c273
-rw-r--r--drivers/parisc/gsc.c11
-rw-r--r--drivers/parisc/sba_iommu.c18
-rw-r--r--include/asm-parisc/parisc-device.h5
4 files changed, 216 insertions, 91 deletions
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c
index d34bbe7ae0e3..988844a169e6 100644
--- a/arch/parisc/kernel/drivers.c
+++ b/arch/parisc/kernel/drivers.c
@@ -46,36 +46,51 @@ static struct device root = {
46 .bus_id = "parisc", 46 .bus_id = "parisc",
47}; 47};
48 48
49#define for_each_padev(padev) \ 49static inline int check_dev(struct device *dev)
50 for (padev = next_dev(&root); padev != NULL; \ 50{
51 padev = next_dev(&padev->dev)) 51 if (dev->bus == &parisc_bus_type) {
52 struct parisc_device *pdev;
53 pdev = to_parisc_device(dev);
54 return pdev->id.hw_type != HPHW_FAULTY;
55 }
56 return 1;
57}
58
59static struct device *
60parse_tree_node(struct device *parent, int index, struct hardware_path *modpath);
52 61
53#define check_dev(padev) \ 62struct recurse_struct {
54 (padev->id.hw_type != HPHW_FAULTY) ? padev : next_dev(&padev->dev) 63 void * obj;
64 int (*fn)(struct device *, void *);
65};
66
67static int descend_children(struct device * dev, void * data)
68{
69 struct recurse_struct * recurse_data = (struct recurse_struct *)data;
70
71 if (recurse_data->fn(dev, recurse_data->obj))
72 return 1;
73 else
74 return device_for_each_child(dev, recurse_data, descend_children);
75}
55 76
56/** 77/**
57 * next_dev - enumerates registered devices 78 * for_each_padev - Iterate over all devices in the tree
58 * @dev: the previous device returned from next_dev 79 * @fn: Function to call for each device.
80 * @data: Data to pass to the called function.
59 * 81 *
60 * next_dev does a depth-first search of the tree, returning parents 82 * This performs a depth-first traversal of the tree, calling the
61 * before children. Returns NULL when there are no more devices. 83 * function passed for each node. It calls the function for parents
84 * before children.
62 */ 85 */
63static struct parisc_device *next_dev(struct device *dev)
64{
65 if (!list_empty(&dev->children)) {
66 dev = list_to_dev(dev->children.next);
67 return check_dev(to_parisc_device(dev));
68 }
69 86
70 while (dev != &root) { 87static int for_each_padev(int (*fn)(struct device *, void *), void * data)
71 if (dev->node.next != &dev->parent->children) { 88{
72 dev = list_to_dev(dev->node.next); 89 struct recurse_struct recurse_data = {
73 return to_parisc_device(dev); 90 .obj = data,
74 } 91 .fn = fn,
75 dev = dev->parent; 92 };
76 } 93 return device_for_each_child(&root, &recurse_data, descend_children);
77
78 return NULL;
79} 94}
80 95
81/** 96/**
@@ -105,12 +120,6 @@ static int match_device(struct parisc_driver *driver, struct parisc_device *dev)
105 return 0; 120 return 0;
106} 121}
107 122
108static void claim_device(struct parisc_driver *driver, struct parisc_device *dev)
109{
110 dev->driver = driver;
111 request_mem_region(dev->hpa, 0x1000, driver->name);
112}
113
114static int parisc_driver_probe(struct device *dev) 123static int parisc_driver_probe(struct device *dev)
115{ 124{
116 int rc; 125 int rc;
@@ -119,8 +128,8 @@ static int parisc_driver_probe(struct device *dev)
119 128
120 rc = pa_drv->probe(pa_dev); 129 rc = pa_drv->probe(pa_dev);
121 130
122 if(!rc) 131 if (!rc)
123 claim_device(pa_drv, pa_dev); 132 pa_dev->driver = pa_drv;
124 133
125 return rc; 134 return rc;
126} 135}
@@ -131,7 +140,6 @@ static int parisc_driver_remove(struct device *dev)
131 struct parisc_driver *pa_drv = to_parisc_driver(dev->driver); 140 struct parisc_driver *pa_drv = to_parisc_driver(dev->driver);
132 if (pa_drv->remove) 141 if (pa_drv->remove)
133 pa_drv->remove(pa_dev); 142 pa_drv->remove(pa_dev);
134 release_mem_region(pa_dev->hpa, 0x1000);
135 143
136 return 0; 144 return 0;
137} 145}
@@ -173,6 +181,24 @@ int register_parisc_driver(struct parisc_driver *driver)
173} 181}
174EXPORT_SYMBOL(register_parisc_driver); 182EXPORT_SYMBOL(register_parisc_driver);
175 183
184
185struct match_count {
186 struct parisc_driver * driver;
187 int count;
188};
189
190static int match_and_count(struct device * dev, void * data)
191{
192 struct match_count * m = data;
193 struct parisc_device * pdev = to_parisc_device(dev);
194
195 if (check_dev(dev)) {
196 if (match_device(m->driver, pdev))
197 m->count++;
198 }
199 return 0;
200}
201
176/** 202/**
177 * count_parisc_driver - count # of devices this driver would match 203 * count_parisc_driver - count # of devices this driver would match
178 * @driver: the PA-RISC driver to try 204 * @driver: the PA-RISC driver to try
@@ -182,15 +208,14 @@ EXPORT_SYMBOL(register_parisc_driver);
182 */ 208 */
183int count_parisc_driver(struct parisc_driver *driver) 209int count_parisc_driver(struct parisc_driver *driver)
184{ 210{
185 struct parisc_device *device; 211 struct match_count m = {
186 int cnt = 0; 212 .driver = driver,
213 .count = 0,
214 };
187 215
188 for_each_padev(device) { 216 for_each_padev(match_and_count, &m);
189 if (match_device(driver, device))
190 cnt++;
191 }
192 217
193 return cnt; 218 return m.count;
194} 219}
195 220
196 221
@@ -206,14 +231,34 @@ int unregister_parisc_driver(struct parisc_driver *driver)
206} 231}
207EXPORT_SYMBOL(unregister_parisc_driver); 232EXPORT_SYMBOL(unregister_parisc_driver);
208 233
209static struct parisc_device *find_device_by_addr(unsigned long hpa) 234struct find_data {
235 unsigned long hpa;
236 struct parisc_device * dev;
237};
238
239static int find_device(struct device * dev, void * data)
210{ 240{
211 struct parisc_device *dev; 241 struct parisc_device * pdev = to_parisc_device(dev);
212 for_each_padev(dev) { 242 struct find_data * d = (struct find_data*)data;
213 if (dev->hpa == hpa) 243
214 return dev; 244 if (check_dev(dev)) {
245 if (pdev->hpa.start == d->hpa) {
246 d->dev = pdev;
247 return 1;
248 }
215 } 249 }
216 return NULL; 250 return 0;
251}
252
253static struct parisc_device *find_device_by_addr(unsigned long hpa)
254{
255 struct find_data d = {
256 .hpa = hpa,
257 };
258 int ret;
259
260 ret = for_each_padev(find_device, &d);
261 return ret ? d.dev : NULL;
217} 262}
218 263
219/** 264/**
@@ -387,6 +432,23 @@ struct parisc_device * create_tree_node(char id, struct device *parent)
387 return dev; 432 return dev;
388} 433}
389 434
435struct match_id_data {
436 char id;
437 struct parisc_device * dev;
438};
439
440static int match_by_id(struct device * dev, void * data)
441{
442 struct parisc_device * pdev = to_parisc_device(dev);
443 struct match_id_data * d = data;
444
445 if (pdev->hw_path == d->id) {
446 d->dev = pdev;
447 return 1;
448 }
449 return 0;
450}
451
390/** 452/**
391 * alloc_tree_node - returns a device entry in the iotree 453 * alloc_tree_node - returns a device entry in the iotree
392 * @parent: the parent node in the tree 454 * @parent: the parent node in the tree
@@ -397,15 +459,13 @@ struct parisc_device * create_tree_node(char id, struct device *parent)
397 */ 459 */
398static struct parisc_device * alloc_tree_node(struct device *parent, char id) 460static struct parisc_device * alloc_tree_node(struct device *parent, char id)
399{ 461{
400 struct device *dev; 462 struct match_id_data d = {
401 463 .id = id,
402 list_for_each_entry(dev, &parent->children, node) { 464 };
403 struct parisc_device *padev = to_parisc_device(dev); 465 if (device_for_each_child(parent, &d, match_by_id))
404 if (padev->hw_path == id) 466 return d.dev;
405 return padev; 467 else
406 } 468 return create_tree_node(id, parent);
407
408 return create_tree_node(id, parent);
409} 469}
410 470
411static struct parisc_device *create_parisc_device(struct hardware_path *modpath) 471static struct parisc_device *create_parisc_device(struct hardware_path *modpath)
@@ -439,10 +499,8 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
439 499
440 dev = create_parisc_device(mod_path); 500 dev = create_parisc_device(mod_path);
441 if (dev->id.hw_type != HPHW_FAULTY) { 501 if (dev->id.hw_type != HPHW_FAULTY) {
442 char p[64];
443 print_pa_hwpath(dev, p);
444 printk("Two devices have hardware path %s. Please file a bug with HP.\n" 502 printk("Two devices have hardware path %s. Please file a bug with HP.\n"
445 "In the meantime, you could try rearranging your cards.\n", p); 503 "In the meantime, you could try rearranging your cards.\n", parisc_pathname(dev));
446 return NULL; 504 return NULL;
447 } 505 }
448 506
@@ -451,12 +509,27 @@ alloc_pa_dev(unsigned long hpa, struct hardware_path *mod_path)
451 dev->id.hversion_rev = iodc_data[1] & 0x0f; 509 dev->id.hversion_rev = iodc_data[1] & 0x0f;
452 dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) | 510 dev->id.sversion = ((iodc_data[4] & 0x0f) << 16) |
453 (iodc_data[5] << 8) | iodc_data[6]; 511 (iodc_data[5] << 8) | iodc_data[6];
454 dev->hpa = hpa; 512 dev->hpa.name = parisc_pathname(dev);
513 dev->hpa.start = hpa;
514 if (hpa == 0xf4000000 || hpa == 0xf6000000 ||
515 hpa == 0xf8000000 || hpa == 0xfa000000) {
516 dev->hpa.end = hpa + 0x01ffffff;
517 } else {
518 dev->hpa.end = hpa + 0xfff;
519 }
520 dev->hpa.flags = IORESOURCE_MEM;
455 name = parisc_hardware_description(&dev->id); 521 name = parisc_hardware_description(&dev->id);
456 if (name) { 522 if (name) {
457 strlcpy(dev->name, name, sizeof(dev->name)); 523 strlcpy(dev->name, name, sizeof(dev->name));
458 } 524 }
459 525
526 /* Silently fail things like mouse ports which are subsumed within
527 * the keyboard controller
528 */
529 if ((hpa & 0xfff) == 0 && insert_resource(&iomem_resource, &dev->hpa))
530 printk("Unable to claim HPA %lx for device %s\n",
531 hpa, name);
532
460 return dev; 533 return dev;
461} 534}
462 535
@@ -555,6 +628,33 @@ static int match_parisc_device(struct device *dev, int index,
555 return (curr->hw_path == id); 628 return (curr->hw_path == id);
556} 629}
557 630
631struct parse_tree_data {
632 int index;
633 struct hardware_path * modpath;
634 struct device * dev;
635};
636
637static int check_parent(struct device * dev, void * data)
638{
639 struct parse_tree_data * d = data;
640
641 if (check_dev(dev)) {
642 if (dev->bus == &parisc_bus_type) {
643 if (match_parisc_device(dev, d->index, d->modpath))
644 d->dev = dev;
645 } else if (is_pci_dev(dev)) {
646 if (match_pci_device(dev, d->index, d->modpath))
647 d->dev = dev;
648 } else if (dev->bus == NULL) {
649 /* we are on a bus bridge */
650 struct device *new = parse_tree_node(dev, d->index, d->modpath);
651 if (new)
652 d->dev = new;
653 }
654 }
655 return d->dev != NULL;
656}
657
558/** 658/**
559 * parse_tree_node - returns a device entry in the iotree 659 * parse_tree_node - returns a device entry in the iotree
560 * @parent: the parent node in the tree 660 * @parent: the parent node in the tree
@@ -568,24 +668,18 @@ static int match_parisc_device(struct device *dev, int index,
568static struct device * 668static struct device *
569parse_tree_node(struct device *parent, int index, struct hardware_path *modpath) 669parse_tree_node(struct device *parent, int index, struct hardware_path *modpath)
570{ 670{
571 struct device *device; 671 struct parse_tree_data d = {
572 672 .index = index,
573 list_for_each_entry(device, &parent->children, node) { 673 .modpath = modpath,
574 if (device->bus == &parisc_bus_type) { 674 };
575 if (match_parisc_device(device, index, modpath))
576 return device;
577 } else if (is_pci_dev(device)) {
578 if (match_pci_device(device, index, modpath))
579 return device;
580 } else if (device->bus == NULL) {
581 /* we are on a bus bridge */
582 struct device *new = parse_tree_node(device, index, modpath);
583 if (new)
584 return new;
585 }
586 }
587 675
588 return NULL; 676 struct recurse_struct recurse_data = {
677 .obj = &d,
678 .fn = check_parent,
679 };
680
681 device_for_each_child(parent, &recurse_data, descend_children);
682 return d.dev;
589} 683}
590 684
591/** 685/**
@@ -636,7 +730,7 @@ EXPORT_SYMBOL(device_to_hwpath);
636 ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT)) 730 ((dev->id.hw_type == HPHW_IOA) || (dev->id.hw_type == HPHW_BCPORT))
637 731
638#define IS_LOWER_PORT(dev) \ 732#define IS_LOWER_PORT(dev) \
639 ((gsc_readl(dev->hpa + offsetof(struct bc_module, io_status)) \ 733 ((gsc_readl(dev->hpa.start + offsetof(struct bc_module, io_status)) \
640 & BC_PORT_MASK) == BC_LOWER_PORT) 734 & BC_PORT_MASK) == BC_LOWER_PORT)
641 735
642#define MAX_NATIVE_DEVICES 64 736#define MAX_NATIVE_DEVICES 64
@@ -645,8 +739,8 @@ EXPORT_SYMBOL(device_to_hwpath);
645#define FLEX_MASK F_EXTEND(0xfffc0000) 739#define FLEX_MASK F_EXTEND(0xfffc0000)
646#define IO_IO_LOW offsetof(struct bc_module, io_io_low) 740#define IO_IO_LOW offsetof(struct bc_module, io_io_low)
647#define IO_IO_HIGH offsetof(struct bc_module, io_io_high) 741#define IO_IO_HIGH offsetof(struct bc_module, io_io_high)
648#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_LOW) 742#define READ_IO_IO_LOW(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_LOW)
649#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa + IO_IO_HIGH) 743#define READ_IO_IO_HIGH(dev) (unsigned long)(signed int)gsc_readl(dev->hpa.start + IO_IO_HIGH)
650 744
651static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high, 745static void walk_native_bus(unsigned long io_io_low, unsigned long io_io_high,
652 struct device *parent); 746 struct device *parent);
@@ -655,10 +749,10 @@ void walk_lower_bus(struct parisc_device *dev)
655{ 749{
656 unsigned long io_io_low, io_io_high; 750 unsigned long io_io_low, io_io_high;
657 751
658 if(!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev)) 752 if (!BUS_CONVERTER(dev) || IS_LOWER_PORT(dev))
659 return; 753 return;
660 754
661 if(dev->id.hw_type == HPHW_IOA) { 755 if (dev->id.hw_type == HPHW_IOA) {
662 io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16); 756 io_io_low = (unsigned long)(signed int)(READ_IO_IO_LOW(dev) << 16);
663 io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET; 757 io_io_high = io_io_low + MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET;
664 } else { 758 } else {
@@ -731,7 +825,7 @@ static void print_parisc_device(struct parisc_device *dev)
731 825
732 print_pa_hwpath(dev, hw_path); 826 print_pa_hwpath(dev, hw_path);
733 printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }", 827 printk(KERN_INFO "%d. %s at 0x%lx [%s] { %d, 0x%x, 0x%.3x, 0x%.5x }",
734 ++count, dev->name, dev->hpa, hw_path, dev->id.hw_type, 828 ++count, dev->name, dev->hpa.start, hw_path, dev->id.hw_type,
735 dev->id.hversion_rev, dev->id.hversion, dev->id.sversion); 829 dev->id.hversion_rev, dev->id.hversion, dev->id.sversion);
736 830
737 if (dev->num_addrs) { 831 if (dev->num_addrs) {
@@ -753,13 +847,20 @@ void init_parisc_bus(void)
753 get_device(&root); 847 get_device(&root);
754} 848}
755 849
850
851static int print_one_device(struct device * dev, void * data)
852{
853 struct parisc_device * pdev = to_parisc_device(dev);
854
855 if (check_dev(dev))
856 print_parisc_device(pdev);
857 return 0;
858}
859
756/** 860/**
757 * print_parisc_devices - Print out a list of devices found in this system 861 * print_parisc_devices - Print out a list of devices found in this system
758 */ 862 */
759void print_parisc_devices(void) 863void print_parisc_devices(void)
760{ 864{
761 struct parisc_device *dev; 865 for_each_padev(print_one_device, NULL);
762 for_each_padev(dev) {
763 print_parisc_device(dev);
764 }
765} 866}
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index af5e02526a18..16d40f95978d 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -183,12 +183,20 @@ void gsc_asic_assign_irq(struct gsc_asic *asic, int local_irq, int *irqp)
183 *irqp = irq; 183 *irqp = irq;
184} 184}
185 185
186static struct device *next_device(struct klist_iter *i)
187{
188 struct klist_node * n = klist_next(i);
189 return n ? container_of(n, struct device, knode_parent) : NULL;
190}
191
186void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl, 192void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
187 void (*choose_irq)(struct parisc_device *, void *)) 193 void (*choose_irq)(struct parisc_device *, void *))
188{ 194{
189 struct device *dev; 195 struct device *dev;
196 struct klist_iter i;
190 197
191 list_for_each_entry(dev, &parent->dev.children, node) { 198 klist_iter_init(&parent->dev.klist_children, &i);
199 while ((dev = next_device(&i))) {
192 struct parisc_device *padev = to_parisc_device(dev); 200 struct parisc_device *padev = to_parisc_device(dev);
193 201
194 /* work-around for 715/64 and others which have parent 202 /* work-around for 715/64 and others which have parent
@@ -197,6 +205,7 @@ void gsc_fixup_irqs(struct parisc_device *parent, void *ctrl,
197 return gsc_fixup_irqs(padev, ctrl, choose_irq); 205 return gsc_fixup_irqs(padev, ctrl, choose_irq);
198 choose_irq(padev, ctrl); 206 choose_irq(padev, ctrl);
199 } 207 }
208 klist_iter_exit(&i);
200} 209}
201 210
202int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic) 211int gsc_common_setup(struct parisc_device *parent, struct gsc_asic *gsc_asic)
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index 82ea68b55df4..a8405f05fb5f 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1322,19 +1322,29 @@ sba_alloc_pdir(unsigned int pdir_size)
1322 return (void *) pdir_base; 1322 return (void *) pdir_base;
1323} 1323}
1324 1324
1325static struct device *next_device(struct klist_iter *i)
1326{
1327 struct klist_node * n = klist_next(i);
1328 return n ? container_of(n, struct device, knode_parent) : NULL;
1329}
1330
1325/* setup Mercury or Elroy IBASE/IMASK registers. */ 1331/* setup Mercury or Elroy IBASE/IMASK registers. */
1326static void setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num) 1332static void
1333setup_ibase_imask(struct parisc_device *sba, struct ioc *ioc, int ioc_num)
1327{ 1334{
1328 /* lba_set_iregs() is in drivers/parisc/lba_pci.c */ 1335 /* lba_set_iregs() is in drivers/parisc/lba_pci.c */
1329 extern void lba_set_iregs(struct parisc_device *, u32, u32); 1336 extern void lba_set_iregs(struct parisc_device *, u32, u32);
1330 struct device *dev; 1337 struct device *dev;
1338 struct klist_iter i;
1331 1339
1332 list_for_each_entry(dev, &sba->dev.children, node) { 1340 klist_iter_init(&sba->dev.klist_children, &i);
1341 while ((dev = next_device(&i))) {
1333 struct parisc_device *lba = to_parisc_device(dev); 1342 struct parisc_device *lba = to_parisc_device(dev);
1334 int rope_num = (lba->hpa >> 13) & 0xf; 1343 int rope_num = (lba->hpa.start >> 13) & 0xf;
1335 if (rope_num >> 3 == ioc_num) 1344 if (rope_num >> 3 == ioc_num)
1336 lba_set_iregs(lba, ioc->ibase, ioc->imask); 1345 lba_set_iregs(lba, ioc->ibase, ioc->imask);
1337 } 1346 }
1347 klist_iter_exit(&i);
1338} 1348}
1339 1349
1340static void 1350static void
diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
index ef69ab4b17a9..cbde8b41c84b 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/include/asm-parisc/parisc-device.h
@@ -39,6 +39,11 @@ struct parisc_driver {
39#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv) 39#define to_parisc_driver(d) container_of(d, struct parisc_driver, drv)
40#define parisc_parent(d) to_parisc_device(d->dev.parent) 40#define parisc_parent(d) to_parisc_device(d->dev.parent)
41 41
42static inline char *parisc_pathname(struct parisc_device *d)
43{
44 return d->dev.bus_id;
45}
46
42static inline void 47static inline void
43parisc_set_drvdata(struct parisc_device *d, void *p) 48parisc_set_drvdata(struct parisc_device *d, void *p)
44{ 49{