1 /* 2 * linux/arch/arm/common/amba.c 3 * 4 * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 #include <linux/module.h> 11 #include <linux/init.h> 12 #include <linux/device.h> 13 #include <linux/string.h> 14 #include <linux/slab.h> 15 #include <linux/io.h> 16 #include <linux/pm.h> 17 #include <linux/pm_runtime.h> 18 #include <linux/amba/bus.h> 19 20 #include <asm/irq.h> 21 #include <asm/sizes.h> 22 23 #define to_amba_driver(d) container_of(d, struct amba_driver, drv) 24 25 static const struct amba_id * 26 amba_lookup(const struct amba_id *table, struct amba_device *dev) 27 { 28 int ret = 0; 29 30 while (table->mask) { 31 ret = (dev->periphid & table->mask) == table->id; 32 if (ret) 33 break; 34 table++; 35 } 36 37 return ret ? table : NULL; 38 } 39 40 static int amba_match(struct device *dev, struct device_driver *drv) 41 { 42 struct amba_device *pcdev = to_amba_device(dev); 43 struct amba_driver *pcdrv = to_amba_driver(drv); 44 45 return amba_lookup(pcdrv->id_table, pcdev) != NULL; 46 } 47 48 #ifdef CONFIG_HOTPLUG 49 static int amba_uevent(struct device *dev, struct kobj_uevent_env *env) 50 { 51 struct amba_device *pcdev = to_amba_device(dev); 52 int retval = 0; 53 54 retval = add_uevent_var(env, "AMBA_ID=%08x", pcdev->periphid); 55 return retval; 56 } 57 #else 58 #define amba_uevent NULL 59 #endif 60 61 #define amba_attr_func(name,fmt,arg...) \ 62 static ssize_t name##_show(struct device *_dev, \ 63 struct device_attribute *attr, char *buf) \ 64 { \ 65 struct amba_device *dev = to_amba_device(_dev); \ 66 return sprintf(buf, fmt, arg); \ 67 } 68 69 #define amba_attr(name,fmt,arg...) \ 70 amba_attr_func(name,fmt,arg) \ 71 static DEVICE_ATTR(name, S_IRUGO, name##_show, NULL) 72 73 amba_attr_func(id, "%08x\n", dev->periphid); 74 amba_attr(irq0, "%u\n", dev->irq[0]); 75 amba_attr(irq1, "%u\n", dev->irq[1]); 76 amba_attr_func(resource, "\t%016llx\t%016llx\t%016lx\n", 77 (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, 78 dev->res.flags); 79 80 static struct device_attribute amba_dev_attrs[] = { 81 __ATTR_RO(id), 82 __ATTR_RO(resource), 83 __ATTR_NULL, 84 }; 85 86 #ifdef CONFIG_PM_SLEEP 87 88 static int amba_legacy_suspend(struct device *dev, pm_message_t mesg) 89 { 90 struct amba_driver *adrv = to_amba_driver(dev->driver); 91 struct amba_device *adev = to_amba_device(dev); 92 int ret = 0; 93 94 if (dev->driver && adrv->suspend) 95 ret = adrv->suspend(adev, mesg); 96 97 return ret; 98 } 99 100 static int amba_legacy_resume(struct device *dev) 101 { 102 struct amba_driver *adrv = to_amba_driver(dev->driver); 103 struct amba_device *adev = to_amba_device(dev); 104 int ret = 0; 105 106 if (dev->driver && adrv->resume) 107 ret = adrv->resume(adev); 108 109 return ret; 110 } 111 112 static int amba_pm_prepare(struct device *dev) 113 { 114 struct device_driver *drv = dev->driver; 115 int ret = 0; 116 117 if (drv && drv->pm && drv->pm->prepare) 118 ret = drv->pm->prepare(dev); 119 120 return ret; 121 } 122 123 static void amba_pm_complete(struct device *dev) 124 { 125 struct device_driver *drv = dev->driver; 126 127 if (drv && drv->pm && drv->pm->complete) 128 drv->pm->complete(dev); 129 } 130 131 #else /* !CONFIG_PM_SLEEP */ 132 133 #define amba_pm_prepare NULL 134 #define amba_pm_complete NULL 135 136 #endif /* !CONFIG_PM_SLEEP */ 137 138 #ifdef CONFIG_SUSPEND 139 140 static int amba_pm_suspend(struct device *dev) 141 { 142 struct device_driver *drv = dev->driver; 143 int ret = 0; 144 145 if (!drv) 146 return 0; 147 148 if (drv->pm) { 149 if (drv->pm->suspend) 150 ret = drv->pm->suspend(dev); 151 } else { 152 ret = amba_legacy_suspend(dev, PMSG_SUSPEND); 153 } 154 155 return ret; 156 } 157 158 static int amba_pm_suspend_noirq(struct device *dev) 159 { 160 struct device_driver *drv = dev->driver; 161 int ret = 0; 162 163 if (!drv) 164 return 0; 165 166 if (drv->pm) { 167 if (drv->pm->suspend_noirq) 168 ret = drv->pm->suspend_noirq(dev); 169 } 170 171 return ret; 172 } 173 174 static int amba_pm_resume(struct device *dev) 175 { 176 struct device_driver *drv = dev->driver; 177 int ret = 0; 178 179 if (!drv) 180 return 0; 181 182 if (drv->pm) { 183 if (drv->pm->resume) 184 ret = drv->pm->resume(dev); 185 } else { 186 ret = amba_legacy_resume(dev); 187 } 188 189 return ret; 190 } 191 192 static int amba_pm_resume_noirq(struct device *dev) 193 { 194 struct device_driver *drv = dev->driver; 195 int ret = 0; 196 197 if (!drv) 198 return 0; 199 200 if (drv->pm) { 201 if (drv->pm->resume_noirq) 202 ret = drv->pm->resume_noirq(dev); 203 } 204 205 return ret; 206 } 207 208 #else /* !CONFIG_SUSPEND */ 209 210 #define amba_pm_suspend NULL 211 #define amba_pm_resume NULL 212 #define amba_pm_suspend_noirq NULL 213 #define amba_pm_resume_noirq NULL 214 215 #endif /* !CONFIG_SUSPEND */ 216 217 #ifdef CONFIG_HIBERNATION 218 219 static int amba_pm_freeze(struct device *dev) 220 { 221 struct device_driver *drv = dev->driver; 222 int ret = 0; 223 224 if (!drv) 225 return 0; 226 227 if (drv->pm) { 228 if (drv->pm->freeze) 229 ret = drv->pm->freeze(dev); 230 } else { 231 ret = amba_legacy_suspend(dev, PMSG_FREEZE); 232 } 233 234 return ret; 235 } 236 237 static int amba_pm_freeze_noirq(struct device *dev) 238 { 239 struct device_driver *drv = dev->driver; 240 int ret = 0; 241 242 if (!drv) 243 return 0; 244 245 if (drv->pm) { 246 if (drv->pm->freeze_noirq) 247 ret = drv->pm->freeze_noirq(dev); 248 } 249 250 return ret; 251 } 252 253 static int amba_pm_thaw(struct device *dev) 254 { 255 struct device_driver *drv = dev->driver; 256 int ret = 0; 257 258 if (!drv) 259 return 0; 260 261 if (drv->pm) { 262 if (drv->pm->thaw) 263 ret = drv->pm->thaw(dev); 264 } else { 265 ret = amba_legacy_resume(dev); 266 } 267 268 return ret; 269 } 270 271 static int amba_pm_thaw_noirq(struct device *dev) 272 { 273 struct device_driver *drv = dev->driver; 274 int ret = 0; 275 276 if (!drv) 277 return 0; 278 279 if (drv->pm) { 280 if (drv->pm->thaw_noirq) 281 ret = drv->pm->thaw_noirq(dev); 282 } 283 284 return ret; 285 } 286 287 static int amba_pm_poweroff(struct device *dev) 288 { 289 struct device_driver *drv = dev->driver; 290 int ret = 0; 291 292 if (!drv) 293 return 0; 294 295 if (drv->pm) { 296 if (drv->pm->poweroff) 297 ret = drv->pm->poweroff(dev); 298 } else { 299 ret = amba_legacy_suspend(dev, PMSG_HIBERNATE); 300 } 301 302 return ret; 303 } 304 305 static int amba_pm_poweroff_noirq(struct device *dev) 306 { 307 struct device_driver *drv = dev->driver; 308 int ret = 0; 309 310 if (!drv) 311 return 0; 312 313 if (drv->pm) { 314 if (drv->pm->poweroff_noirq) 315 ret = drv->pm->poweroff_noirq(dev); 316 } 317 318 return ret; 319 } 320 321 static int amba_pm_restore(struct device *dev) 322 { 323 struct device_driver *drv = dev->driver; 324 int ret = 0; 325 326 if (!drv) 327 return 0; 328 329 if (drv->pm) { 330 if (drv->pm->restore) 331 ret = drv->pm->restore(dev); 332 } else { 333 ret = amba_legacy_resume(dev); 334 } 335 336 return ret; 337 } 338 339 static int amba_pm_restore_noirq(struct device *dev) 340 { 341 struct device_driver *drv = dev->driver; 342 int ret = 0; 343 344 if (!drv) 345 return 0; 346 347 if (drv->pm) { 348 if (drv->pm->restore_noirq) 349 ret = drv->pm->restore_noirq(dev); 350 } 351 352 return ret; 353 } 354 355 #else /* !CONFIG_HIBERNATION */ 356 357 #define amba_pm_freeze NULL 358 #define amba_pm_thaw NULL 359 #define amba_pm_poweroff NULL 360 #define amba_pm_restore NULL 361 #define amba_pm_freeze_noirq NULL 362 #define amba_pm_thaw_noirq NULL 363 #define amba_pm_poweroff_noirq NULL 364 #define amba_pm_restore_noirq NULL 365 366 #endif /* !CONFIG_HIBERNATION */ 367 368 #ifdef CONFIG_PM 369 370 static const struct dev_pm_ops amba_pm = { 371 .prepare = amba_pm_prepare, 372 .complete = amba_pm_complete, 373 .suspend = amba_pm_suspend, 374 .resume = amba_pm_resume, 375 .freeze = amba_pm_freeze, 376 .thaw = amba_pm_thaw, 377 .poweroff = amba_pm_poweroff, 378 .restore = amba_pm_restore, 379 .suspend_noirq = amba_pm_suspend_noirq, 380 .resume_noirq = amba_pm_resume_noirq, 381 .freeze_noirq = amba_pm_freeze_noirq, 382 .thaw_noirq = amba_pm_thaw_noirq, 383 .poweroff_noirq = amba_pm_poweroff_noirq, 384 .restore_noirq = amba_pm_restore_noirq, 385 SET_RUNTIME_PM_OPS( 386 pm_generic_runtime_suspend, 387 pm_generic_runtime_resume, 388 pm_generic_runtime_idle 389 ) 390 }; 391 392 #define AMBA_PM (&amba_pm) 393 394 #else /* !CONFIG_PM */ 395 396 #define AMBA_PM NULL 397 398 #endif /* !CONFIG_PM */ 399 400 /* 401 * Primecells are part of the Advanced Microcontroller Bus Architecture, 402 * so we call the bus "amba". 403 */ 404 struct bus_type amba_bustype = { 405 .name = "amba", 406 .dev_attrs = amba_dev_attrs, 407 .match = amba_match, 408 .uevent = amba_uevent, 409 .pm = AMBA_PM, 410 }; 411 412 static int __init amba_init(void) 413 { 414 return bus_register(&amba_bustype); 415 } 416 417 postcore_initcall(amba_init); 418 419 static int amba_get_enable_pclk(struct amba_device *pcdev) 420 { 421 struct clk *pclk = clk_get(&pcdev->dev, "apb_pclk"); 422 int ret; 423 424 pcdev->pclk = pclk; 425 426 if (IS_ERR(pclk)) 427 return PTR_ERR(pclk); 428 429 ret = clk_enable(pclk); 430 if (ret) 431 clk_put(pclk); 432 433 return ret; 434 } 435 436 static void amba_put_disable_pclk(struct amba_device *pcdev) 437 { 438 struct clk *pclk = pcdev->pclk; 439 440 clk_disable(pclk); 441 clk_put(pclk); 442 } 443 444 static int amba_get_enable_vcore(struct amba_device *pcdev) 445 { 446 struct regulator *vcore = regulator_get(&pcdev->dev, "vcore"); 447 int ret; 448 449 pcdev->vcore = vcore; 450 451 if (IS_ERR(vcore)) { 452 /* It is OK not to supply a vcore regulator */ 453 if (PTR_ERR(vcore) == -ENODEV) 454 return 0; 455 return PTR_ERR(vcore); 456 } 457 458 ret = regulator_enable(vcore); 459 if (ret) { 460 regulator_put(vcore); 461 pcdev->vcore = ERR_PTR(-ENODEV); 462 } 463 464 return ret; 465 } 466 467 static void amba_put_disable_vcore(struct amba_device *pcdev) 468 { 469 struct regulator *vcore = pcdev->vcore; 470 471 if (!IS_ERR(vcore)) { 472 regulator_disable(vcore); 473 regulator_put(vcore); 474 } 475 } 476 477 /* 478 * These are the device model conversion veneers; they convert the 479 * device model structures to our more specific structures. 480 */ 481 static int amba_probe(struct device *dev) 482 { 483 struct amba_device *pcdev = to_amba_device(dev); 484 struct amba_driver *pcdrv = to_amba_driver(dev->driver); 485 const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev); 486 int ret; 487 488 do { 489 ret = amba_get_enable_vcore(pcdev); 490 if (ret) 491 break; 492 493 ret = amba_get_enable_pclk(pcdev); 494 if (ret) 495 break; 496 497 ret = pcdrv->probe(pcdev, id); 498 if (ret == 0) 499 break; 500 501 amba_put_disable_pclk(pcdev); 502 amba_put_disable_vcore(pcdev); 503 } while (0); 504 505 return ret; 506 } 507 508 static int amba_remove(struct device *dev) 509 { 510 struct amba_device *pcdev = to_amba_device(dev); 511 struct amba_driver *drv = to_amba_driver(dev->driver); 512 int ret = drv->remove(pcdev); 513 514 amba_put_disable_pclk(pcdev); 515 amba_put_disable_vcore(pcdev); 516 517 return ret; 518 } 519 520 static void amba_shutdown(struct device *dev) 521 { 522 struct amba_driver *drv = to_amba_driver(dev->driver); 523 drv->shutdown(to_amba_device(dev)); 524 } 525 526 /** 527 * amba_driver_register - register an AMBA device driver 528 * @drv: amba device driver structure 529 * 530 * Register an AMBA device driver with the Linux device model 531 * core. If devices pre-exist, the drivers probe function will 532 * be called. 533 */ 534 int amba_driver_register(struct amba_driver *drv) 535 { 536 drv->drv.bus = &amba_bustype; 537 538 #define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn 539 SETFN(probe); 540 SETFN(remove); 541 SETFN(shutdown); 542 543 return driver_register(&drv->drv); 544 } 545 546 /** 547 * amba_driver_unregister - remove an AMBA device driver 548 * @drv: AMBA device driver structure to remove 549 * 550 * Unregister an AMBA device driver from the Linux device 551 * model. The device model will call the drivers remove function 552 * for each device the device driver is currently handling. 553 */ 554 void amba_driver_unregister(struct amba_driver *drv) 555 { 556 driver_unregister(&drv->drv); 557 } 558 559 560 static void amba_device_release(struct device *dev) 561 { 562 struct amba_device *d = to_amba_device(dev); 563 564 if (d->res.parent) 565 release_resource(&d->res); 566 kfree(d); 567 } 568 569 /** 570 * amba_device_register - register an AMBA device 571 * @dev: AMBA device to register 572 * @parent: parent memory resource 573 * 574 * Setup the AMBA device, reading the cell ID if present. 575 * Claim the resource, and register the AMBA device with 576 * the Linux device manager. 577 */ 578 int amba_device_register(struct amba_device *dev, struct resource *parent) 579 { 580 u32 size; 581 void __iomem *tmp; 582 int i, ret; 583 584 device_initialize(&dev->dev); 585 586 /* 587 * Copy from device_add 588 */ 589 if (dev->dev.init_name) { 590 dev_set_name(&dev->dev, "%s", dev->dev.init_name); 591 dev->dev.init_name = NULL; 592 } 593 594 dev->dev.release = amba_device_release; 595 dev->dev.bus = &amba_bustype; 596 dev->dev.dma_mask = &dev->dma_mask; 597 dev->res.name = dev_name(&dev->dev); 598 599 if (!dev->dev.coherent_dma_mask && dev->dma_mask) 600 dev_warn(&dev->dev, "coherent dma mask is unset\n"); 601 602 ret = request_resource(parent, &dev->res); 603 if (ret) 604 goto err_out; 605 606 /* 607 * Dynamically calculate the size of the resource 608 * and use this for iomap 609 */ 610 size = resource_size(&dev->res); 611 tmp = ioremap(dev->res.start, size); 612 if (!tmp) { 613 ret = -ENOMEM; 614 goto err_release; 615 } 616 617 ret = amba_get_enable_pclk(dev); 618 if (ret == 0) { 619 u32 pid, cid; 620 621 /* 622 * Read pid and cid based on size of resource 623 * they are located at end of region 624 */ 625 for (pid = 0, i = 0; i < 4; i++) 626 pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << 627 (i * 8); 628 for (cid = 0, i = 0; i < 4; i++) 629 cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << 630 (i * 8); 631 632 amba_put_disable_pclk(dev); 633 634 if (cid == AMBA_CID) 635 dev->periphid = pid; 636 637 if (!dev->periphid) 638 ret = -ENODEV; 639 } 640 641 iounmap(tmp); 642 643 if (ret) 644 goto err_release; 645 646 ret = device_add(&dev->dev); 647 if (ret) 648 goto err_release; 649 650 if (dev->irq[0] != NO_IRQ) 651 ret = device_create_file(&dev->dev, &dev_attr_irq0); 652 if (ret == 0 && dev->irq[1] != NO_IRQ) 653 ret = device_create_file(&dev->dev, &dev_attr_irq1); 654 if (ret == 0) 655 return ret; 656 657 device_unregister(&dev->dev); 658 659 err_release: 660 release_resource(&dev->res); 661 err_out: 662 return ret; 663 } 664 665 /** 666 * amba_device_unregister - unregister an AMBA device 667 * @dev: AMBA device to remove 668 * 669 * Remove the specified AMBA device from the Linux device 670 * manager. All files associated with this object will be 671 * destroyed, and device drivers notified that the device has 672 * been removed. The AMBA device's resources including 673 * the amba_device structure will be freed once all 674 * references to it have been dropped. 675 */ 676 void amba_device_unregister(struct amba_device *dev) 677 { 678 device_unregister(&dev->dev); 679 } 680 681 682 struct find_data { 683 struct amba_device *dev; 684 struct device *parent; 685 const char *busid; 686 unsigned int id; 687 unsigned int mask; 688 }; 689 690 static int amba_find_match(struct device *dev, void *data) 691 { 692 struct find_data *d = data; 693 struct amba_device *pcdev = to_amba_device(dev); 694 int r; 695 696 r = (pcdev->periphid & d->mask) == d->id; 697 if (d->parent) 698 r &= d->parent == dev->parent; 699 if (d->busid) 700 r &= strcmp(dev_name(dev), d->busid) == 0; 701 702 if (r) { 703 get_device(dev); 704 d->dev = pcdev; 705 } 706 707 return r; 708 } 709 710 /** 711 * amba_find_device - locate an AMBA device given a bus id 712 * @busid: bus id for device (or NULL) 713 * @parent: parent device (or NULL) 714 * @id: peripheral ID (or 0) 715 * @mask: peripheral ID mask (or 0) 716 * 717 * Return the AMBA device corresponding to the supplied parameters. 718 * If no device matches, returns NULL. 719 * 720 * NOTE: When a valid device is found, its refcount is 721 * incremented, and must be decremented before the returned 722 * reference. 723 */ 724 struct amba_device * 725 amba_find_device(const char *busid, struct device *parent, unsigned int id, 726 unsigned int mask) 727 { 728 struct find_data data; 729 730 data.dev = NULL; 731 data.parent = parent; 732 data.busid = busid; 733 data.id = id; 734 data.mask = mask; 735 736 bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match); 737 738 return data.dev; 739 } 740 741 /** 742 * amba_request_regions - request all mem regions associated with device 743 * @dev: amba_device structure for device 744 * @name: name, or NULL to use driver name 745 */ 746 int amba_request_regions(struct amba_device *dev, const char *name) 747 { 748 int ret = 0; 749 u32 size; 750 751 if (!name) 752 name = dev->dev.driver->name; 753 754 size = resource_size(&dev->res); 755 756 if (!request_mem_region(dev->res.start, size, name)) 757 ret = -EBUSY; 758 759 return ret; 760 } 761 762 /** 763 * amba_release_regions - release mem regions assoicated with device 764 * @dev: amba_device structure for device 765 * 766 * Release regions claimed by a successful call to amba_request_regions. 767 */ 768 void amba_release_regions(struct amba_device *dev) 769 { 770 u32 size; 771 772 size = resource_size(&dev->res); 773 release_mem_region(dev->res.start, size); 774 } 775 776 EXPORT_SYMBOL(amba_driver_register); 777 EXPORT_SYMBOL(amba_driver_unregister); 778 EXPORT_SYMBOL(amba_device_register); 779 EXPORT_SYMBOL(amba_device_unregister); 780 EXPORT_SYMBOL(amba_find_device); 781 EXPORT_SYMBOL(amba_request_regions); 782 EXPORT_SYMBOL(amba_release_regions); 783