1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * omap_device implementation 4 * 5 * Copyright (C) 2009-2010 Nokia Corporation 6 * Paul Walmsley, Kevin Hilman 7 * 8 * Developed in collaboration with (alphabetical order): Benoit 9 * Cousson, Thara Gopinath, Tony Lindgren, Rajendra Nayak, Vikram 10 * Pandita, Sakari Poussa, Anand Sawant, Santosh Shilimkar, Richard 11 * Woodruff 12 * 13 * This code provides a consistent interface for OMAP device drivers 14 * to control power management and interconnect properties of their 15 * devices. 16 * 17 * In the medium- to long-term, this code should be implemented as a 18 * proper omap_bus/omap_device in Linux, no more platform_data func 19 * pointers 20 */ 21#undef DEBUG 22 23#include <linux/kernel.h> 24#include <linux/platform_device.h> 25#include <linux/slab.h> 26#include <linux/err.h> 27#include <linux/io.h> 28#include <linux/clk.h> 29#include <linux/clkdev.h> 30#include <linux/pm_domain.h> 31#include <linux/pm_runtime.h> 32#include <linux/of.h> 33#include <linux/of_address.h> 34#include <linux/of_irq.h> 35#include <linux/notifier.h> 36 37#include "common.h" 38#include "soc.h" 39#include "omap_device.h" 40#include "omap_hwmod.h" 41 42/* Private functions */ 43 44static void _add_clkdev(struct omap_device *od, const char *clk_alias, 45 const char *clk_name) 46{ 47 struct clk *r; 48 int rc; 49 50 if (!clk_alias || !clk_name) 51 return; 52 53 dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name); 54 55 r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias); 56 if (!IS_ERR(r)) { 57 dev_dbg(&od->pdev->dev, 58 "alias %s already exists\n", clk_alias); 59 clk_put(r); 60 return; 61 } 62 63 r = clk_get_sys(NULL, clk_name); 64 65 if (IS_ERR(r)) { 66 struct of_phandle_args clkspec; 67 68 clkspec.np = of_find_node_by_name(NULL, clk_name); 69 70 r = of_clk_get_from_provider(&clkspec); 71 72 rc = clk_register_clkdev(r, clk_alias, 73 dev_name(&od->pdev->dev)); 74 } else { 75 rc = clk_add_alias(clk_alias, dev_name(&od->pdev->dev), 76 clk_name, NULL); 77 } 78 79 if (rc) { 80 if (rc == -ENODEV || rc == -ENOMEM) 81 dev_err(&od->pdev->dev, 82 "clkdev_alloc for %s failed\n", clk_alias); 83 else 84 dev_err(&od->pdev->dev, 85 "clk_get for %s failed\n", clk_name); 86 } 87} 88 89/** 90 * _add_hwmod_clocks_clkdev - Add clkdev entry for hwmod optional clocks 91 * and main clock 92 * @od: struct omap_device *od 93 * @oh: struct omap_hwmod *oh 94 * 95 * For the main clock and every optional clock present per hwmod per 96 * omap_device, this function adds an entry in the clkdev table of the 97 * form <dev-id=dev_name, con-id=role> if it does not exist already. 98 * 99 * The function is called from inside omap_device_build_ss(), after 100 * omap_device_register. 101 * 102 * This allows drivers to get a pointer to its optional clocks based on its role 103 * by calling clk_get(<dev*>, <role>). 104 * In the case of the main clock, a "fck" alias is used. 105 * 106 * No return value. 107 */ 108static void _add_hwmod_clocks_clkdev(struct omap_device *od, 109 struct omap_hwmod *oh) 110{ 111 int i; 112 113 _add_clkdev(od, "fck", oh->main_clk); 114 115 for (i = 0; i < oh->opt_clks_cnt; i++) 116 _add_clkdev(od, oh->opt_clks[i].role, oh->opt_clks[i].clk); 117} 118 119 120/** 121 * omap_device_build_from_dt - build an omap_device with multiple hwmods 122 * @pdev: The platform device to update. 123 * 124 * Function for building an omap_device already registered from device-tree 125 * 126 * Returns 0 or PTR_ERR() on error. 127 */ 128static int omap_device_build_from_dt(struct platform_device *pdev) 129{ 130 struct omap_hwmod **hwmods; 131 struct omap_device *od; 132 struct omap_hwmod *oh; 133 struct device_node *node = pdev->dev.of_node; 134 struct resource res; 135 const char *oh_name; 136 int oh_cnt, i, ret = 0; 137 bool device_active = false, skip_pm_domain = false; 138 139 oh_cnt = of_property_count_strings(node, "ti,hwmods"); 140 if (oh_cnt <= 0) { 141 dev_dbg(&pdev->dev, "No 'hwmods' to build omap_device\n"); 142 return -ENODEV; 143 } 144 145 /* SDMA still needs special handling for omap_device_build() */ 146 ret = of_property_read_string_index(node, "ti,hwmods", 0, &oh_name); 147 if (!ret && (!strncmp("dma_system", oh_name, 10) || 148 !strncmp("dma", oh_name, 3))) 149 skip_pm_domain = true; 150 151 /* Use ti-sysc driver instead of omap_device? */ 152 if (!skip_pm_domain && 153 !omap_hwmod_parse_module_range(NULL, node, &res)) 154 return -ENODEV; 155 156 hwmods = kcalloc(oh_cnt, sizeof(struct omap_hwmod *), GFP_KERNEL); 157 if (!hwmods) { 158 ret = -ENOMEM; 159 goto odbfd_exit; 160 } 161 162 for (i = 0; i < oh_cnt; i++) { 163 of_property_read_string_index(node, "ti,hwmods", i, &oh_name); 164 oh = omap_hwmod_lookup(oh_name); 165 if (!oh) { 166 dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n", 167 oh_name); 168 ret = -EINVAL; 169 goto odbfd_exit1; 170 } 171 hwmods[i] = oh; 172 if (oh->flags & HWMOD_INIT_NO_IDLE) 173 device_active = true; 174 } 175 176 od = omap_device_alloc(pdev, hwmods, oh_cnt); 177 if (IS_ERR(od)) { 178 dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n", 179 oh_name); 180 ret = PTR_ERR(od); 181 goto odbfd_exit1; 182 } 183 184 /* Fix up missing resource names */ 185 for (i = 0; i < pdev->num_resources; i++) { 186 struct resource *r = &pdev->resource[i]; 187 188 if (r->name == NULL) 189 r->name = dev_name(&pdev->dev); 190 } 191 192 if (!skip_pm_domain) { 193 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain); 194 if (device_active) { 195 omap_device_enable(pdev); 196 pm_runtime_set_active(&pdev->dev); 197 } 198 } 199 200odbfd_exit1: 201 kfree(hwmods); 202odbfd_exit: 203 /* if data/we are at fault.. load up a fail handler */ 204 if (ret) 205 dev_pm_domain_set(&pdev->dev, &omap_device_fail_pm_domain); 206 207 return ret; 208} 209 210static int _omap_device_notifier_call(struct notifier_block *nb, 211 unsigned long event, void *dev) 212{ 213 struct platform_device *pdev = to_platform_device(dev); 214 struct omap_device *od; 215 int err; 216 217 switch (event) { 218 case BUS_NOTIFY_REMOVED_DEVICE: 219 if (pdev->archdata.od) 220 omap_device_delete(pdev->archdata.od); 221 break; 222 case BUS_NOTIFY_UNBOUND_DRIVER: 223 od = to_omap_device(pdev); 224 if (od && (od->_state == OMAP_DEVICE_STATE_ENABLED)) { 225 dev_info(dev, "enabled after unload, idling\n"); 226 err = omap_device_idle(pdev); 227 if (err) 228 dev_err(dev, "failed to idle\n"); 229 } 230 break; 231 case BUS_NOTIFY_BIND_DRIVER: 232 od = to_omap_device(pdev); 233 if (od) { 234 od->_driver_status = BUS_NOTIFY_BIND_DRIVER; 235 if (od->_state == OMAP_DEVICE_STATE_ENABLED && 236 pm_runtime_status_suspended(dev)) { 237 pm_runtime_set_active(dev); 238 } 239 } 240 break; 241 case BUS_NOTIFY_ADD_DEVICE: 242 if (pdev->dev.of_node) 243 omap_device_build_from_dt(pdev); 244 omap_auxdata_legacy_init(dev); 245 fallthrough; 246 default: 247 od = to_omap_device(pdev); 248 if (od) 249 od->_driver_status = event; 250 } 251 252 return NOTIFY_DONE; 253} 254 255/** 256 * _omap_device_enable_hwmods - call omap_hwmod_enable() on all hwmods 257 * @od: struct omap_device *od 258 * 259 * Enable all underlying hwmods. Returns 0. 260 */ 261static int _omap_device_enable_hwmods(struct omap_device *od) 262{ 263 int ret = 0; 264 int i; 265 266 for (i = 0; i < od->hwmods_cnt; i++) 267 ret |= omap_hwmod_enable(od->hwmods[i]); 268 269 return ret; 270} 271 272/** 273 * _omap_device_idle_hwmods - call omap_hwmod_idle() on all hwmods 274 * @od: struct omap_device *od 275 * 276 * Idle all underlying hwmods. Returns 0. 277 */ 278static int _omap_device_idle_hwmods(struct omap_device *od) 279{ 280 int ret = 0; 281 int i; 282 283 for (i = 0; i < od->hwmods_cnt; i++) 284 ret |= omap_hwmod_idle(od->hwmods[i]); 285 286 return ret; 287} 288 289/* Public functions for use by core code */ 290 291/** 292 * omap_device_get_context_loss_count - get lost context count 293 * @pdev: The platform device to update. 294 * 295 * Using the primary hwmod, query the context loss count for this 296 * device. 297 * 298 * Callers should consider context for this device lost any time this 299 * function returns a value different than the value the caller got 300 * the last time it called this function. 301 * 302 * If any hwmods exist for the omap_device associated with @pdev, 303 * return the context loss counter for that hwmod, otherwise return 304 * zero. 305 */ 306int omap_device_get_context_loss_count(struct platform_device *pdev) 307{ 308 struct omap_device *od; 309 u32 ret = 0; 310 311 od = to_omap_device(pdev); 312 313 if (od->hwmods_cnt) 314 ret = omap_hwmod_get_context_loss_count(od->hwmods[0]); 315 316 return ret; 317} 318 319/** 320 * omap_device_alloc - allocate an omap_device 321 * @pdev: platform_device that will be included in this omap_device 322 * @ohs: ptr to the omap_hwmod for this omap_device 323 * @oh_cnt: the size of the ohs list 324 * 325 * Convenience function for allocating an omap_device structure and filling 326 * hwmods, and resources. 327 * 328 * Returns an struct omap_device pointer or ERR_PTR() on error; 329 */ 330struct omap_device *omap_device_alloc(struct platform_device *pdev, 331 struct omap_hwmod **ohs, int oh_cnt) 332{ 333 int ret = -ENOMEM; 334 struct omap_device *od; 335 int i; 336 struct omap_hwmod **hwmods; 337 338 od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); 339 if (!od) { 340 ret = -ENOMEM; 341 goto oda_exit1; 342 } 343 od->hwmods_cnt = oh_cnt; 344 345 hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL); 346 if (!hwmods) 347 goto oda_exit2; 348 349 od->hwmods = hwmods; 350 od->pdev = pdev; 351 pdev->archdata.od = od; 352 353 for (i = 0; i < oh_cnt; i++) { 354 hwmods[i]->od = od; 355 _add_hwmod_clocks_clkdev(od, hwmods[i]); 356 } 357 358 return od; 359 360oda_exit2: 361 kfree(od); 362oda_exit1: 363 dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret); 364 365 return ERR_PTR(ret); 366} 367 368void omap_device_delete(struct omap_device *od) 369{ 370 if (!od) 371 return; 372 373 od->pdev->archdata.od = NULL; 374 kfree(od->hwmods); 375 kfree(od); 376} 377 378#ifdef CONFIG_PM 379static int _od_runtime_suspend(struct device *dev) 380{ 381 struct platform_device *pdev = to_platform_device(dev); 382 int ret; 383 384 ret = pm_generic_runtime_suspend(dev); 385 if (ret) 386 return ret; 387 388 return omap_device_idle(pdev); 389} 390 391static int _od_runtime_resume(struct device *dev) 392{ 393 struct platform_device *pdev = to_platform_device(dev); 394 int ret; 395 396 ret = omap_device_enable(pdev); 397 if (ret) { 398 dev_err(dev, "use pm_runtime_put_sync_suspend() in driver?\n"); 399 return ret; 400 } 401 402 return pm_generic_runtime_resume(dev); 403} 404 405static int _od_fail_runtime_suspend(struct device *dev) 406{ 407 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__); 408 return -ENODEV; 409} 410 411static int _od_fail_runtime_resume(struct device *dev) 412{ 413 dev_warn(dev, "%s: FIXME: missing hwmod/omap_dev info\n", __func__); 414 return -ENODEV; 415} 416 417#endif 418 419#ifdef CONFIG_SUSPEND 420static int _od_suspend_noirq(struct device *dev) 421{ 422 struct platform_device *pdev = to_platform_device(dev); 423 struct omap_device *od = to_omap_device(pdev); 424 int ret; 425 426 /* Don't attempt late suspend on a driver that is not bound */ 427 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER) 428 return 0; 429 430 ret = pm_generic_suspend_noirq(dev); 431 432 if (!ret && !pm_runtime_status_suspended(dev)) { 433 if (pm_generic_runtime_suspend(dev) == 0) { 434 omap_device_idle(pdev); 435 od->flags |= OMAP_DEVICE_SUSPENDED; 436 } 437 } 438 439 return ret; 440} 441 442static int _od_resume_noirq(struct device *dev) 443{ 444 struct platform_device *pdev = to_platform_device(dev); 445 struct omap_device *od = to_omap_device(pdev); 446 447 if (od->flags & OMAP_DEVICE_SUSPENDED) { 448 od->flags &= ~OMAP_DEVICE_SUSPENDED; 449 omap_device_enable(pdev); 450 pm_generic_runtime_resume(dev); 451 } 452 453 return pm_generic_resume_noirq(dev); 454} 455#else 456#define _od_suspend_noirq NULL 457#define _od_resume_noirq NULL 458#endif 459 460struct dev_pm_domain omap_device_fail_pm_domain = { 461 .ops = { 462 SET_RUNTIME_PM_OPS(_od_fail_runtime_suspend, 463 _od_fail_runtime_resume, NULL) 464 } 465}; 466 467struct dev_pm_domain omap_device_pm_domain = { 468 .ops = { 469 SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, 470 NULL) 471 USE_PLATFORM_PM_SLEEP_OPS 472 SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, 473 _od_resume_noirq) 474 } 475}; 476 477/** 478 * omap_device_register - register an omap_device with one omap_hwmod 479 * @pdev: the platform device (omap_device) to register. 480 * 481 * Register the omap_device structure. This currently just calls 482 * platform_device_register() on the underlying platform_device. 483 * Returns the return value of platform_device_register(). 484 */ 485int omap_device_register(struct platform_device *pdev) 486{ 487 pr_debug("omap_device: %s: registering\n", pdev->name); 488 489 dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain); 490 return platform_device_add(pdev); 491} 492 493 494/* Public functions for use by device drivers through struct platform_data */ 495 496/** 497 * omap_device_enable - fully activate an omap_device 498 * @pdev: the platform device to activate 499 * 500 * Do whatever is necessary for the hwmods underlying omap_device @od 501 * to be accessible and ready to operate. This generally involves 502 * enabling clocks, setting SYSCONFIG registers; and in the future may 503 * involve remuxing pins. Device drivers should call this function 504 * indirectly via pm_runtime_get*(). Returns -EINVAL if called when 505 * the omap_device is already enabled, or passes along the return 506 * value of _omap_device_enable_hwmods(). 507 */ 508int omap_device_enable(struct platform_device *pdev) 509{ 510 int ret; 511 struct omap_device *od; 512 513 od = to_omap_device(pdev); 514 515 if (od->_state == OMAP_DEVICE_STATE_ENABLED) { 516 dev_warn(&pdev->dev, 517 "omap_device: %s() called from invalid state %d\n", 518 __func__, od->_state); 519 return -EINVAL; 520 } 521 522 ret = _omap_device_enable_hwmods(od); 523 524 if (ret == 0) 525 od->_state = OMAP_DEVICE_STATE_ENABLED; 526 527 return ret; 528} 529 530/** 531 * omap_device_idle - idle an omap_device 532 * @pdev: The platform_device (omap_device) to idle 533 * 534 * Idle omap_device @od. Device drivers call this function indirectly 535 * via pm_runtime_put*(). Returns -EINVAL if the omap_device is not 536 * currently enabled, or passes along the return value of 537 * _omap_device_idle_hwmods(). 538 */ 539int omap_device_idle(struct platform_device *pdev) 540{ 541 int ret; 542 struct omap_device *od; 543 544 od = to_omap_device(pdev); 545 546 if (od->_state != OMAP_DEVICE_STATE_ENABLED) { 547 dev_warn(&pdev->dev, 548 "omap_device: %s() called from invalid state %d\n", 549 __func__, od->_state); 550 return -EINVAL; 551 } 552 553 ret = _omap_device_idle_hwmods(od); 554 555 if (ret == 0) 556 od->_state = OMAP_DEVICE_STATE_IDLE; 557 558 return ret; 559} 560 561/** 562 * omap_device_assert_hardreset - set a device's hardreset line 563 * @pdev: struct platform_device * to reset 564 * @name: const char * name of the reset line 565 * 566 * Set the hardreset line identified by @name on the IP blocks 567 * associated with the hwmods backing the platform_device @pdev. All 568 * of the hwmods associated with @pdev must have the same hardreset 569 * line linked to them for this to work. Passes along the return value 570 * of omap_hwmod_assert_hardreset() in the event of any failure, or 571 * returns 0 upon success. 572 */ 573int omap_device_assert_hardreset(struct platform_device *pdev, const char *name) 574{ 575 struct omap_device *od = to_omap_device(pdev); 576 int ret = 0; 577 int i; 578 579 for (i = 0; i < od->hwmods_cnt; i++) { 580 ret = omap_hwmod_assert_hardreset(od->hwmods[i], name); 581 if (ret) 582 break; 583 } 584 585 return ret; 586} 587 588/** 589 * omap_device_deassert_hardreset - release a device's hardreset line 590 * @pdev: struct platform_device * to reset 591 * @name: const char * name of the reset line 592 * 593 * Release the hardreset line identified by @name on the IP blocks 594 * associated with the hwmods backing the platform_device @pdev. All 595 * of the hwmods associated with @pdev must have the same hardreset 596 * line linked to them for this to work. Passes along the return 597 * value of omap_hwmod_deassert_hardreset() in the event of any 598 * failure, or returns 0 upon success. 599 */ 600int omap_device_deassert_hardreset(struct platform_device *pdev, 601 const char *name) 602{ 603 struct omap_device *od = to_omap_device(pdev); 604 int ret = 0; 605 int i; 606 607 for (i = 0; i < od->hwmods_cnt; i++) { 608 ret = omap_hwmod_deassert_hardreset(od->hwmods[i], name); 609 if (ret) 610 break; 611 } 612 613 return ret; 614} 615 616/** 617 * omap_device_get_by_hwmod_name() - convert a hwmod name to 618 * device pointer. 619 * @oh_name: name of the hwmod device 620 * 621 * Returns back a struct device * pointer associated with a hwmod 622 * device represented by a hwmod_name 623 */ 624struct device *omap_device_get_by_hwmod_name(const char *oh_name) 625{ 626 struct omap_hwmod *oh; 627 628 if (!oh_name) { 629 WARN(1, "%s: no hwmod name!\n", __func__); 630 return ERR_PTR(-EINVAL); 631 } 632 633 oh = omap_hwmod_lookup(oh_name); 634 if (!oh) { 635 WARN(1, "%s: no hwmod for %s\n", __func__, 636 oh_name); 637 return ERR_PTR(-ENODEV); 638 } 639 if (!oh->od) { 640 WARN(1, "%s: no omap_device for %s\n", __func__, 641 oh_name); 642 return ERR_PTR(-ENODEV); 643 } 644 645 return &oh->od->pdev->dev; 646} 647 648static struct notifier_block platform_nb = { 649 .notifier_call = _omap_device_notifier_call, 650}; 651 652static int __init omap_device_init(void) 653{ 654 bus_register_notifier(&platform_bus_type, &platform_nb); 655 return 0; 656} 657omap_postcore_initcall(omap_device_init); 658 659/** 660 * omap_device_late_idle - idle devices without drivers 661 * @dev: struct device * associated with omap_device 662 * @data: unused 663 * 664 * Check the driver bound status of this device, and idle it 665 * if there is no driver attached. 666 */ 667static int __init omap_device_late_idle(struct device *dev, void *data) 668{ 669 struct platform_device *pdev = to_platform_device(dev); 670 struct omap_device *od = to_omap_device(pdev); 671 int i; 672 673 if (!od) 674 return 0; 675 676 /* 677 * If omap_device state is enabled, but has no driver bound, 678 * idle it. 679 */ 680 681 /* 682 * Some devices (like memory controllers) are always kept 683 * enabled, and should not be idled even with no drivers. 684 */ 685 for (i = 0; i < od->hwmods_cnt; i++) 686 if (od->hwmods[i]->flags & HWMOD_INIT_NO_IDLE) 687 return 0; 688 689 if (od->_driver_status != BUS_NOTIFY_BOUND_DRIVER && 690 od->_driver_status != BUS_NOTIFY_BIND_DRIVER) { 691 if (od->_state == OMAP_DEVICE_STATE_ENABLED) { 692 dev_warn(dev, "%s: enabled but no driver. Idling\n", 693 __func__); 694 omap_device_idle(pdev); 695 } 696 } 697 698 return 0; 699} 700 701static int __init omap_device_late_init(void) 702{ 703 bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); 704 705 return 0; 706} 707omap_late_initcall_sync(omap_device_late_init); 708