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_HIBERNATE_CALLBACKS 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_HIBERNATE_CALLBACKS */ 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_HIBERNATE_CALLBACKS */ 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 /* Hard-coded primecell ID instead of plug-n-play */ 607 if (dev->periphid != 0) 608 goto skip_probe; 609 610 /* 611 * Dynamically calculate the size of the resource 612 * and use this for iomap 613 */ 614 size = resource_size(&dev->res); 615 tmp = ioremap(dev->res.start, size); 616 if (!tmp) { 617 ret = -ENOMEM; 618 goto err_release; 619 } 620 621 ret = amba_get_enable_pclk(dev); 622 if (ret == 0) { 623 u32 pid, cid; 624 625 /* 626 * Read pid and cid based on size of resource 627 * they are located at end of region 628 */ 629 for (pid = 0, i = 0; i < 4; i++) 630 pid |= (readl(tmp + size - 0x20 + 4 * i) & 255) << 631 (i * 8); 632 for (cid = 0, i = 0; i < 4; i++) 633 cid |= (readl(tmp + size - 0x10 + 4 * i) & 255) << 634 (i * 8); 635 636 amba_put_disable_pclk(dev); 637 638 if (cid == AMBA_CID) 639 dev->periphid = pid; 640 641 if (!dev->periphid) 642 ret = -ENODEV; 643 } 644 645 iounmap(tmp); 646 647 if (ret) 648 goto err_release; 649 650 skip_probe: 651 ret = device_add(&dev->dev); 652 if (ret) 653 goto err_release; 654 655 if (dev->irq[0] != NO_IRQ) 656 ret = device_create_file(&dev->dev, &dev_attr_irq0); 657 if (ret == 0 && dev->irq[1] != NO_IRQ) 658 ret = device_create_file(&dev->dev, &dev_attr_irq1); 659 if (ret == 0) 660 return ret; 661 662 device_unregister(&dev->dev); 663 664 err_release: 665 release_resource(&dev->res); 666 err_out: 667 return ret; 668 } 669 670 /** 671 * amba_device_unregister - unregister an AMBA device 672 * @dev: AMBA device to remove 673 * 674 * Remove the specified AMBA device from the Linux device 675 * manager. All files associated with this object will be 676 * destroyed, and device drivers notified that the device has 677 * been removed. The AMBA device's resources including 678 * the amba_device structure will be freed once all 679 * references to it have been dropped. 680 */ 681 void amba_device_unregister(struct amba_device *dev) 682 { 683 device_unregister(&dev->dev); 684 } 685 686 687 struct find_data { 688 struct amba_device *dev; 689 struct device *parent; 690 const char *busid; 691 unsigned int id; 692 unsigned int mask; 693 }; 694 695 static int amba_find_match(struct device *dev, void *data) 696 { 697 struct find_data *d = data; 698 struct amba_device *pcdev = to_amba_device(dev); 699 int r; 700 701 r = (pcdev->periphid & d->mask) == d->id; 702 if (d->parent) 703 r &= d->parent == dev->parent; 704 if (d->busid) 705 r &= strcmp(dev_name(dev), d->busid) == 0; 706 707 if (r) { 708 get_device(dev); 709 d->dev = pcdev; 710 } 711 712 return r; 713 } 714 715 /** 716 * amba_find_device - locate an AMBA device given a bus id 717 * @busid: bus id for device (or NULL) 718 * @parent: parent device (or NULL) 719 * @id: peripheral ID (or 0) 720 * @mask: peripheral ID mask (or 0) 721 * 722 * Return the AMBA device corresponding to the supplied parameters. 723 * If no device matches, returns NULL. 724 * 725 * NOTE: When a valid device is found, its refcount is 726 * incremented, and must be decremented before the returned 727 * reference. 728 */ 729 struct amba_device * 730 amba_find_device(const char *busid, struct device *parent, unsigned int id, 731 unsigned int mask) 732 { 733 struct find_data data; 734 735 data.dev = NULL; 736 data.parent = parent; 737 data.busid = busid; 738 data.id = id; 739 data.mask = mask; 740 741 bus_for_each_dev(&amba_bustype, NULL, &data, amba_find_match); 742 743 return data.dev; 744 } 745 746 /** 747 * amba_request_regions - request all mem regions associated with device 748 * @dev: amba_device structure for device 749 * @name: name, or NULL to use driver name 750 */ 751 int amba_request_regions(struct amba_device *dev, const char *name) 752 { 753 int ret = 0; 754 u32 size; 755 756 if (!name) 757 name = dev->dev.driver->name; 758 759 size = resource_size(&dev->res); 760 761 if (!request_mem_region(dev->res.start, size, name)) 762 ret = -EBUSY; 763 764 return ret; 765 } 766 767 /** 768 * amba_release_regions - release mem regions associated with device 769 * @dev: amba_device structure for device 770 * 771 * Release regions claimed by a successful call to amba_request_regions. 772 */ 773 void amba_release_regions(struct amba_device *dev) 774 { 775 u32 size; 776 777 size = resource_size(&dev->res); 778 release_mem_region(dev->res.start, size); 779 } 780 781 EXPORT_SYMBOL(amba_driver_register); 782 EXPORT_SYMBOL(amba_driver_unregister); 783 EXPORT_SYMBOL(amba_device_register); 784 EXPORT_SYMBOL(amba_device_unregister); 785 EXPORT_SYMBOL(amba_find_device); 786 EXPORT_SYMBOL(amba_request_regions); 787 EXPORT_SYMBOL(amba_release_regions); 788