aboutsummaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/drivers.c
diff options
context:
space:
mode:
authorMatthew Wilcox <willy@parisc-linux.org>2005-10-21 22:33:38 -0400
committerKyle McMartin <kyle@parisc-linux.org>2005-10-21 22:33:38 -0400
commit5658374766d9e0249bd04e9d62bdb8456b916b64 (patch)
tree61ae77a2c8faf7bb420be00d989b89c5ffd1f4ee /arch/parisc/kernel/drivers.c
parent63172cb3d5ef762dcb60a292bc7f016b85cf6e1f (diff)
[PARISC] Convert parisc_device tree to use struct device klists
Fix parse_tree_node. much more needs to be done to fix this file. Signed-off-by: Matthew Wilcox <willy@parisc-linux.org> Make drivers.c compile based on a patch from Pat Mochel. From: Patrick Mochel <mochel@digitalimplant.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org> Fix drivers.c to create new device tree nodes when no match is found. Signed-off-by: Richard Hirst <rhirst@parisc-linux.org> Do a proper depth-first search returning parents before children, using the new klist infrastructure. Signed-off-by: Richard Hirst <rhirst@parisc-linux.org> Fixed parisc_device traversal so that pdc_stable works again Fixed check_dev so it doesn't dereference a parisc_device until it has verified the bus type Signed-off-by: Randolph Chung <tausq@parisc-linux.org> Convert pa_dev->hpa from an unsigned long to a struct resource. Use insert_resource() instead of request_mem_region(). Request resources at bus walk time instead of driver probe time. Don't release the resources as we don't have any hotplug parisc_device support yet. Add parisc_pathname() to conveniently get the textual representation of the hwpath used in sysfs. Inline the remnants of claim_device() into its caller. Signed-off-by: Matthew Wilcox <willy@parisc-linux.org> I noticed that some of the STI regions weren't showing up in iomem. Reading the STI spec indicated that all STI devices occupy at least 32MB. So check for STI HPAs and give them 32MB instead of 4kB. Signed-off-by: Matthew Wilcox <willy@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel/drivers.c')
-rw-r--r--arch/parisc/kernel/drivers.c273
1 files changed, 187 insertions, 86 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}