1 /* 2 * Bus & driver management routines for devices within 3 * a MacIO ASIC. Interface to new driver model mostly 4 * stolen from the PCI version. 5 * 6 * Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org) 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * as published by the Free Software Foundation; either version 11 * 2 of the License, or (at your option) any later version. 12 * 13 * TODO: 14 * 15 * - Don't probe below media bay by default, but instead provide 16 * some hooks for media bay to dynamically add/remove it's own 17 * sub-devices. 18 */ 19 20 #include <linux/config.h> 21 #include <linux/string.h> 22 #include <linux/kernel.h> 23 #include <linux/pci.h> 24 #include <linux/pci_ids.h> 25 #include <linux/init.h> 26 #include <linux/module.h> 27 #include <linux/slab.h> 28 29 #include <asm/machdep.h> 30 #include <asm/macio.h> 31 #include <asm/pmac_feature.h> 32 #include <asm/prom.h> 33 #include <asm/pci-bridge.h> 34 35 #undef DEBUG 36 37 #define MAX_NODE_NAME_SIZE (BUS_ID_SIZE - 12) 38 39 static struct macio_chip *macio_on_hold; 40 41 static int macio_bus_match(struct device *dev, struct device_driver *drv) 42 { 43 struct macio_dev * macio_dev = to_macio_device(dev); 44 struct macio_driver * macio_drv = to_macio_driver(drv); 45 const struct of_device_id * matches = macio_drv->match_table; 46 47 if (!matches) 48 return 0; 49 50 return of_match_device(matches, &macio_dev->ofdev) != NULL; 51 } 52 53 struct macio_dev *macio_dev_get(struct macio_dev *dev) 54 { 55 struct device *tmp; 56 57 if (!dev) 58 return NULL; 59 tmp = get_device(&dev->ofdev.dev); 60 if (tmp) 61 return to_macio_device(tmp); 62 else 63 return NULL; 64 } 65 66 void macio_dev_put(struct macio_dev *dev) 67 { 68 if (dev) 69 put_device(&dev->ofdev.dev); 70 } 71 72 73 static int macio_device_probe(struct device *dev) 74 { 75 int error = -ENODEV; 76 struct macio_driver *drv; 77 struct macio_dev *macio_dev; 78 const struct of_device_id *match; 79 80 drv = to_macio_driver(dev->driver); 81 macio_dev = to_macio_device(dev); 82 83 if (!drv->probe) 84 return error; 85 86 macio_dev_get(macio_dev); 87 88 match = of_match_device(drv->match_table, &macio_dev->ofdev); 89 if (match) 90 error = drv->probe(macio_dev, match); 91 if (error) 92 macio_dev_put(macio_dev); 93 94 return error; 95 } 96 97 static int macio_device_remove(struct device *dev) 98 { 99 struct macio_dev * macio_dev = to_macio_device(dev); 100 struct macio_driver * drv = to_macio_driver(dev->driver); 101 102 if (dev->driver && drv->remove) 103 drv->remove(macio_dev); 104 macio_dev_put(macio_dev); 105 106 return 0; 107 } 108 109 static void macio_device_shutdown(struct device *dev) 110 { 111 struct macio_dev * macio_dev = to_macio_device(dev); 112 struct macio_driver * drv = to_macio_driver(dev->driver); 113 114 if (dev->driver && drv->shutdown) 115 drv->shutdown(macio_dev); 116 } 117 118 static int macio_device_suspend(struct device *dev, pm_message_t state) 119 { 120 struct macio_dev * macio_dev = to_macio_device(dev); 121 struct macio_driver * drv = to_macio_driver(dev->driver); 122 123 if (dev->driver && drv->suspend) 124 return drv->suspend(macio_dev, state); 125 return 0; 126 } 127 128 static int macio_device_resume(struct device * dev) 129 { 130 struct macio_dev * macio_dev = to_macio_device(dev); 131 struct macio_driver * drv = to_macio_driver(dev->driver); 132 133 if (dev->driver && drv->resume) 134 return drv->resume(macio_dev); 135 return 0; 136 } 137 138 static int macio_uevent(struct device *dev, char **envp, int num_envp, 139 char *buffer, int buffer_size) 140 { 141 struct macio_dev * macio_dev; 142 struct of_device * of; 143 char *scratch, *compat, *compat2; 144 int i = 0; 145 int length, cplen, cplen2, seen = 0; 146 147 if (!dev) 148 return -ENODEV; 149 150 macio_dev = to_macio_device(dev); 151 if (!macio_dev) 152 return -ENODEV; 153 154 of = &macio_dev->ofdev; 155 156 /* stuff we want to pass to /sbin/hotplug */ 157 envp[i++] = scratch = buffer; 158 length = scnprintf (scratch, buffer_size, "OF_NAME=%s", of->node->name); 159 ++length; 160 buffer_size -= length; 161 if ((buffer_size <= 0) || (i >= num_envp)) 162 return -ENOMEM; 163 scratch += length; 164 165 envp[i++] = scratch; 166 length = scnprintf (scratch, buffer_size, "OF_TYPE=%s", of->node->type); 167 ++length; 168 buffer_size -= length; 169 if ((buffer_size <= 0) || (i >= num_envp)) 170 return -ENOMEM; 171 scratch += length; 172 173 /* Since the compatible field can contain pretty much anything 174 * it's not really legal to split it out with commas. We split it 175 * up using a number of environment variables instead. */ 176 177 compat = (char *) get_property(of->node, "compatible", &cplen); 178 compat2 = compat; 179 cplen2= cplen; 180 while (compat && cplen > 0) { 181 envp[i++] = scratch; 182 length = scnprintf (scratch, buffer_size, 183 "OF_COMPATIBLE_%d=%s", seen, compat); 184 ++length; 185 buffer_size -= length; 186 if ((buffer_size <= 0) || (i >= num_envp)) 187 return -ENOMEM; 188 scratch += length; 189 length = strlen (compat) + 1; 190 compat += length; 191 cplen -= length; 192 seen++; 193 } 194 195 envp[i++] = scratch; 196 length = scnprintf (scratch, buffer_size, "OF_COMPATIBLE_N=%d", seen); 197 ++length; 198 buffer_size -= length; 199 if ((buffer_size <= 0) || (i >= num_envp)) 200 return -ENOMEM; 201 scratch += length; 202 203 envp[i++] = scratch; 204 length = scnprintf (scratch, buffer_size, "MODALIAS=of:N%sT%s", 205 of->node->name, of->node->type); 206 /* overwrite '\0' */ 207 buffer_size -= length; 208 if ((buffer_size <= 0) || (i >= num_envp)) 209 return -ENOMEM; 210 scratch += length; 211 212 if (!compat2) { 213 compat2 = ""; 214 cplen2 = 1; 215 } 216 while (cplen2 > 0) { 217 length = snprintf (scratch, buffer_size, "C%s", compat2); 218 buffer_size -= length; 219 if (buffer_size <= 0) 220 return -ENOMEM; 221 scratch += length; 222 length = strlen (compat2) + 1; 223 compat2 += length; 224 cplen2 -= length; 225 } 226 227 envp[i] = NULL; 228 229 return 0; 230 } 231 232 extern struct device_attribute macio_dev_attrs[]; 233 234 struct bus_type macio_bus_type = { 235 .name = "macio", 236 .match = macio_bus_match, 237 .uevent = macio_uevent, 238 .probe = macio_device_probe, 239 .remove = macio_device_remove, 240 .shutdown = macio_device_shutdown, 241 .suspend = macio_device_suspend, 242 .resume = macio_device_resume, 243 .dev_attrs = macio_dev_attrs, 244 }; 245 246 static int __init macio_bus_driver_init(void) 247 { 248 return bus_register(&macio_bus_type); 249 } 250 251 postcore_initcall(macio_bus_driver_init); 252 253 254 /** 255 * macio_release_dev - free a macio device structure when all users of it are 256 * finished. 257 * @dev: device that's been disconnected 258 * 259 * Will be called only by the device core when all users of this macio device 260 * are done. This currently means never as we don't hot remove any macio 261 * device yet, though that will happen with mediabay based devices in a later 262 * implementation. 263 */ 264 static void macio_release_dev(struct device *dev) 265 { 266 struct macio_dev *mdev; 267 268 mdev = to_macio_device(dev); 269 kfree(mdev); 270 } 271 272 /** 273 * macio_resource_quirks - tweak or skip some resources for a device 274 * @np: pointer to the device node 275 * @res: resulting resource 276 * @index: index of resource in node 277 * 278 * If this routine returns non-null, then the resource is completely 279 * skipped. 280 */ 281 static int macio_resource_quirks(struct device_node *np, struct resource *res, 282 int index) 283 { 284 if (res->flags & IORESOURCE_MEM) { 285 /* Grand Central has too large resource 0 on some machines */ 286 if (index == 0 && !strcmp(np->name, "gc")) 287 res->end = res->start + 0x1ffff; 288 289 /* Airport has bogus resource 2 */ 290 if (index >= 2 && !strcmp(np->name, "radio")) 291 return 1; 292 293 #ifndef CONFIG_PPC64 294 /* DBDMAs may have bogus sizes */ 295 if ((res->start & 0x0001f000) == 0x00008000) 296 res->end = res->start + 0xff; 297 #endif /* CONFIG_PPC64 */ 298 299 /* ESCC parent eats child resources. We could have added a 300 * level of hierarchy, but I don't really feel the need 301 * for it 302 */ 303 if (!strcmp(np->name, "escc")) 304 return 1; 305 306 /* ESCC has bogus resources >= 3 */ 307 if (index >= 3 && !(strcmp(np->name, "ch-a") && 308 strcmp(np->name, "ch-b"))) 309 return 1; 310 311 /* Media bay has too many resources, keep only first one */ 312 if (index > 0 && !strcmp(np->name, "media-bay")) 313 return 1; 314 315 /* Some older IDE resources have bogus sizes */ 316 if (!(strcmp(np->name, "IDE") && strcmp(np->name, "ATA") && 317 strcmp(np->type, "ide") && strcmp(np->type, "ata"))) { 318 if (index == 0 && (res->end - res->start) > 0xfff) 319 res->end = res->start + 0xfff; 320 if (index == 1 && (res->end - res->start) > 0xff) 321 res->end = res->start + 0xff; 322 } 323 } 324 return 0; 325 } 326 327 328 static void macio_setup_interrupts(struct macio_dev *dev) 329 { 330 struct device_node *np = dev->ofdev.node; 331 int i,j; 332 333 /* For now, we use pre-parsed entries in the device-tree for 334 * interrupt routing and addresses, but we should change that 335 * to dynamically parsed entries and so get rid of most of the 336 * clutter in struct device_node 337 */ 338 for (i = j = 0; i < np->n_intrs; i++) { 339 struct resource *res = &dev->interrupt[j]; 340 341 if (j >= MACIO_DEV_COUNT_IRQS) 342 break; 343 res->start = np->intrs[i].line; 344 res->flags = IORESOURCE_IO; 345 if (np->intrs[j].sense) 346 res->flags |= IORESOURCE_IRQ_LOWLEVEL; 347 else 348 res->flags |= IORESOURCE_IRQ_HIGHEDGE; 349 res->name = dev->ofdev.dev.bus_id; 350 if (macio_resource_quirks(np, res, i)) 351 memset(res, 0, sizeof(struct resource)); 352 else 353 j++; 354 } 355 dev->n_interrupts = j; 356 } 357 358 static void macio_setup_resources(struct macio_dev *dev, 359 struct resource *parent_res) 360 { 361 struct device_node *np = dev->ofdev.node; 362 struct resource r; 363 int index; 364 365 for (index = 0; of_address_to_resource(np, index, &r) == 0; index++) { 366 struct resource *res = &dev->resource[index]; 367 if (index >= MACIO_DEV_COUNT_RESOURCES) 368 break; 369 *res = r; 370 res->name = dev->ofdev.dev.bus_id; 371 372 if (macio_resource_quirks(np, res, index)) { 373 memset(res, 0, sizeof(struct resource)); 374 continue; 375 } 376 /* Currently, we consider failure as harmless, this may 377 * change in the future, once I've found all the device 378 * tree bugs in older machines & worked around them 379 */ 380 if (insert_resource(parent_res, res)) { 381 printk(KERN_WARNING "Can't request resource " 382 "%d for MacIO device %s\n", 383 index, dev->ofdev.dev.bus_id); 384 } 385 } 386 dev->n_resources = index; 387 } 388 389 /** 390 * macio_add_one_device - Add one device from OF node to the device tree 391 * @chip: pointer to the macio_chip holding the device 392 * @np: pointer to the device node in the OF tree 393 * @in_bay: set to 1 if device is part of a media-bay 394 * 395 * When media-bay is changed to hotswap drivers, this function will 396 * be exposed to the bay driver some way... 397 */ 398 static struct macio_dev * macio_add_one_device(struct macio_chip *chip, 399 struct device *parent, 400 struct device_node *np, 401 struct macio_dev *in_bay, 402 struct resource *parent_res) 403 { 404 struct macio_dev *dev; 405 u32 *reg; 406 407 if (np == NULL) 408 return NULL; 409 410 dev = kmalloc(sizeof(*dev), GFP_KERNEL); 411 if (!dev) 412 return NULL; 413 memset(dev, 0, sizeof(*dev)); 414 415 dev->bus = &chip->lbus; 416 dev->media_bay = in_bay; 417 dev->ofdev.node = np; 418 dev->ofdev.dma_mask = 0xffffffffUL; 419 dev->ofdev.dev.dma_mask = &dev->ofdev.dma_mask; 420 dev->ofdev.dev.parent = parent; 421 dev->ofdev.dev.bus = &macio_bus_type; 422 dev->ofdev.dev.release = macio_release_dev; 423 424 #ifdef DEBUG 425 printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", 426 dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); 427 #endif 428 429 /* MacIO itself has a different reg, we use it's PCI base */ 430 if (np == chip->of_node) { 431 sprintf(dev->ofdev.dev.bus_id, "%1d.%016llx:%.*s", 432 chip->lbus.index, 433 #ifdef CONFIG_PCI 434 (unsigned long long)pci_resource_start(chip->lbus.pdev, 0), 435 #else 436 0, /* NuBus may want to do something better here */ 437 #endif 438 MAX_NODE_NAME_SIZE, np->name); 439 } else { 440 reg = (u32 *)get_property(np, "reg", NULL); 441 sprintf(dev->ofdev.dev.bus_id, "%1d.%08x:%.*s", 442 chip->lbus.index, 443 reg ? *reg : 0, MAX_NODE_NAME_SIZE, np->name); 444 } 445 446 /* Setup interrupts & resources */ 447 macio_setup_interrupts(dev); 448 macio_setup_resources(dev, parent_res); 449 450 /* Register with core */ 451 if (of_device_register(&dev->ofdev) != 0) { 452 printk(KERN_DEBUG"macio: device registration error for %s!\n", 453 dev->ofdev.dev.bus_id); 454 kfree(dev); 455 return NULL; 456 } 457 458 return dev; 459 } 460 461 static int macio_skip_device(struct device_node *np) 462 { 463 if (strncmp(np->name, "battery", 7) == 0) 464 return 1; 465 if (strncmp(np->name, "escc-legacy", 11) == 0) 466 return 1; 467 return 0; 468 } 469 470 /** 471 * macio_pci_add_devices - Adds sub-devices of mac-io to the device tree 472 * @chip: pointer to the macio_chip holding the devices 473 * 474 * This function will do the job of extracting devices from the 475 * Open Firmware device tree, build macio_dev structures and add 476 * them to the Linux device tree. 477 * 478 * For now, childs of media-bay are added now as well. This will 479 * change rsn though. 480 */ 481 static void macio_pci_add_devices(struct macio_chip *chip) 482 { 483 struct device_node *np, *pnode; 484 struct macio_dev *rdev, *mdev, *mbdev = NULL, *sdev = NULL; 485 struct device *parent = NULL; 486 struct resource *root_res = &iomem_resource; 487 488 /* Add a node for the macio bus itself */ 489 #ifdef CONFIG_PCI 490 if (chip->lbus.pdev) { 491 parent = &chip->lbus.pdev->dev; 492 root_res = &chip->lbus.pdev->resource[0]; 493 } 494 #endif 495 pnode = of_node_get(chip->of_node); 496 if (pnode == NULL) 497 return; 498 499 /* Add macio itself to hierarchy */ 500 rdev = macio_add_one_device(chip, parent, pnode, NULL, root_res); 501 if (rdev == NULL) 502 return; 503 root_res = &rdev->resource[0]; 504 505 /* First scan 1st level */ 506 for (np = NULL; (np = of_get_next_child(pnode, np)) != NULL;) { 507 if (macio_skip_device(np)) 508 continue; 509 of_node_get(np); 510 mdev = macio_add_one_device(chip, &rdev->ofdev.dev, np, NULL, 511 root_res); 512 if (mdev == NULL) 513 of_node_put(np); 514 else if (strncmp(np->name, "media-bay", 9) == 0) 515 mbdev = mdev; 516 else if (strncmp(np->name, "escc", 4) == 0) 517 sdev = mdev; 518 } 519 520 /* Add media bay devices if any */ 521 if (mbdev) 522 for (np = NULL; (np = of_get_next_child(mbdev->ofdev.node, np)) 523 != NULL;) { 524 if (macio_skip_device(np)) 525 continue; 526 of_node_get(np); 527 if (macio_add_one_device(chip, &mbdev->ofdev.dev, np, 528 mbdev, root_res) == NULL) 529 of_node_put(np); 530 } 531 532 /* Add serial ports if any */ 533 if (sdev) { 534 for (np = NULL; (np = of_get_next_child(sdev->ofdev.node, np)) 535 != NULL;) { 536 if (macio_skip_device(np)) 537 continue; 538 of_node_get(np); 539 if (macio_add_one_device(chip, &sdev->ofdev.dev, np, 540 NULL, root_res) == NULL) 541 of_node_put(np); 542 } 543 } 544 } 545 546 547 /** 548 * macio_register_driver - Registers a new MacIO device driver 549 * @drv: pointer to the driver definition structure 550 */ 551 int macio_register_driver(struct macio_driver *drv) 552 { 553 /* initialize common driver fields */ 554 drv->driver.name = drv->name; 555 drv->driver.bus = &macio_bus_type; 556 557 /* register with core */ 558 return driver_register(&drv->driver); 559 } 560 561 /** 562 * macio_unregister_driver - Unregisters a new MacIO device driver 563 * @drv: pointer to the driver definition structure 564 */ 565 void macio_unregister_driver(struct macio_driver *drv) 566 { 567 driver_unregister(&drv->driver); 568 } 569 570 /** 571 * macio_request_resource - Request an MMIO resource 572 * @dev: pointer to the device holding the resource 573 * @resource_no: resource number to request 574 * @name: resource name 575 * 576 * Mark memory region number @resource_no associated with MacIO 577 * device @dev as being reserved by owner @name. Do not access 578 * any address inside the memory regions unless this call returns 579 * successfully. 580 * 581 * Returns 0 on success, or %EBUSY on error. A warning 582 * message is also printed on failure. 583 */ 584 int macio_request_resource(struct macio_dev *dev, int resource_no, 585 const char *name) 586 { 587 if (macio_resource_len(dev, resource_no) == 0) 588 return 0; 589 590 if (!request_mem_region(macio_resource_start(dev, resource_no), 591 macio_resource_len(dev, resource_no), 592 name)) 593 goto err_out; 594 595 return 0; 596 597 err_out: 598 printk (KERN_WARNING "MacIO: Unable to reserve resource #%d:%lx@%lx" 599 " for device %s\n", 600 resource_no, 601 macio_resource_len(dev, resource_no), 602 macio_resource_start(dev, resource_no), 603 dev->ofdev.dev.bus_id); 604 return -EBUSY; 605 } 606 607 /** 608 * macio_release_resource - Release an MMIO resource 609 * @dev: pointer to the device holding the resource 610 * @resource_no: resource number to release 611 */ 612 void macio_release_resource(struct macio_dev *dev, int resource_no) 613 { 614 if (macio_resource_len(dev, resource_no) == 0) 615 return; 616 release_mem_region(macio_resource_start(dev, resource_no), 617 macio_resource_len(dev, resource_no)); 618 } 619 620 /** 621 * macio_request_resources - Reserve all memory resources 622 * @dev: MacIO device whose resources are to be reserved 623 * @name: Name to be associated with resource. 624 * 625 * Mark all memory regions associated with MacIO device @dev as 626 * being reserved by owner @name. Do not access any address inside 627 * the memory regions unless this call returns successfully. 628 * 629 * Returns 0 on success, or %EBUSY on error. A warning 630 * message is also printed on failure. 631 */ 632 int macio_request_resources(struct macio_dev *dev, const char *name) 633 { 634 int i; 635 636 for (i = 0; i < dev->n_resources; i++) 637 if (macio_request_resource(dev, i, name)) 638 goto err_out; 639 return 0; 640 641 err_out: 642 while(--i >= 0) 643 macio_release_resource(dev, i); 644 645 return -EBUSY; 646 } 647 648 /** 649 * macio_release_resources - Release reserved memory resources 650 * @dev: MacIO device whose resources were previously reserved 651 */ 652 653 void macio_release_resources(struct macio_dev *dev) 654 { 655 int i; 656 657 for (i = 0; i < dev->n_resources; i++) 658 macio_release_resource(dev, i); 659 } 660 661 662 #ifdef CONFIG_PCI 663 664 static int __devinit macio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 665 { 666 struct device_node* np; 667 struct macio_chip* chip; 668 669 if (ent->vendor != PCI_VENDOR_ID_APPLE) 670 return -ENODEV; 671 672 /* Note regarding refcounting: We assume pci_device_to_OF_node() is 673 * ported to new OF APIs and returns a node with refcount incremented. 674 */ 675 np = pci_device_to_OF_node(pdev); 676 if (np == NULL) 677 return -ENODEV; 678 679 /* The above assumption is wrong !!! 680 * fix that here for now until I fix the arch code 681 */ 682 of_node_get(np); 683 684 /* We also assume that pmac_feature will have done a get() on nodes 685 * stored in the macio chips array 686 */ 687 chip = macio_find(np, macio_unknown); 688 of_node_put(np); 689 if (chip == NULL) 690 return -ENODEV; 691 692 /* XXX Need locking ??? */ 693 if (chip->lbus.pdev == NULL) { 694 chip->lbus.pdev = pdev; 695 chip->lbus.chip = chip; 696 pci_set_drvdata(pdev, &chip->lbus); 697 pci_set_master(pdev); 698 } 699 700 printk(KERN_INFO "MacIO PCI driver attached to %s chipset\n", 701 chip->name); 702 703 /* 704 * HACK ALERT: The WallStreet PowerBook and some OHare based machines 705 * have 2 macio ASICs. I must probe the "main" one first or IDE 706 * ordering will be incorrect. So I put on "hold" the second one since 707 * it seem to appear first on PCI 708 */ 709 if (chip->type == macio_gatwick || chip->type == macio_ohareII) 710 if (macio_chips[0].lbus.pdev == NULL) { 711 macio_on_hold = chip; 712 return 0; 713 } 714 715 macio_pci_add_devices(chip); 716 if (macio_on_hold && macio_chips[0].lbus.pdev != NULL) { 717 macio_pci_add_devices(macio_on_hold); 718 macio_on_hold = NULL; 719 } 720 721 return 0; 722 } 723 724 static void __devexit macio_pci_remove(struct pci_dev* pdev) 725 { 726 panic("removing of macio-asic not supported !\n"); 727 } 728 729 /* 730 * MacIO is matched against any Apple ID, it's probe() function 731 * will then decide wether it applies or not 732 */ 733 static const struct pci_device_id __devinitdata pci_ids [] = { { 734 .vendor = PCI_VENDOR_ID_APPLE, 735 .device = PCI_ANY_ID, 736 .subvendor = PCI_ANY_ID, 737 .subdevice = PCI_ANY_ID, 738 739 }, { /* end: all zeroes */ } 740 }; 741 MODULE_DEVICE_TABLE (pci, pci_ids); 742 743 /* pci driver glue; this is a "new style" PCI driver module */ 744 static struct pci_driver macio_pci_driver = { 745 .name = (char *) "macio", 746 .id_table = pci_ids, 747 748 .probe = macio_pci_probe, 749 .remove = macio_pci_remove, 750 }; 751 752 #endif /* CONFIG_PCI */ 753 754 static int __init macio_module_init (void) 755 { 756 #ifdef CONFIG_PCI 757 int rc; 758 759 rc = pci_register_driver(&macio_pci_driver); 760 if (rc) 761 return rc; 762 #endif /* CONFIG_PCI */ 763 return 0; 764 } 765 766 module_init(macio_module_init); 767 768 EXPORT_SYMBOL(macio_register_driver); 769 EXPORT_SYMBOL(macio_unregister_driver); 770 EXPORT_SYMBOL(macio_dev_get); 771 EXPORT_SYMBOL(macio_dev_put); 772 EXPORT_SYMBOL(macio_request_resource); 773 EXPORT_SYMBOL(macio_release_resource); 774 EXPORT_SYMBOL(macio_request_resources); 775 EXPORT_SYMBOL(macio_release_resources); 776