1 /* 2 * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks 3 * 4 * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp. 5 * 6 * This file is released under the GPLv2. 7 */ 8 9 #include <linux/kernel.h> 10 #include <linux/device.h> 11 #include <linux/io.h> 12 #include <linux/pm.h> 13 #include <linux/pm_clock.h> 14 #include <linux/clk.h> 15 #include <linux/clkdev.h> 16 #include <linux/slab.h> 17 #include <linux/err.h> 18 #include <linux/pm_domain.h> 19 #include <linux/pm_runtime.h> 20 21 #ifdef CONFIG_PM_CLK 22 23 enum pce_status { 24 PCE_STATUS_NONE = 0, 25 PCE_STATUS_ACQUIRED, 26 PCE_STATUS_ENABLED, 27 PCE_STATUS_ERROR, 28 }; 29 30 struct pm_clock_entry { 31 struct list_head node; 32 char *con_id; 33 struct clk *clk; 34 enum pce_status status; 35 }; 36 37 /** 38 * pm_clk_enable - Enable a clock, reporting any errors 39 * @dev: The device for the given clock 40 * @ce: PM clock entry corresponding to the clock. 41 */ 42 static inline void __pm_clk_enable(struct device *dev, struct pm_clock_entry *ce) 43 { 44 int ret; 45 46 if (ce->status < PCE_STATUS_ERROR) { 47 ret = clk_enable(ce->clk); 48 if (!ret) 49 ce->status = PCE_STATUS_ENABLED; 50 else 51 dev_err(dev, "%s: failed to enable clk %p, error %d\n", 52 __func__, ce->clk, ret); 53 } 54 } 55 56 /** 57 * pm_clk_acquire - Acquire a device clock. 58 * @dev: Device whose clock is to be acquired. 59 * @ce: PM clock entry corresponding to the clock. 60 */ 61 static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce) 62 { 63 if (!ce->clk) 64 ce->clk = clk_get(dev, ce->con_id); 65 if (IS_ERR(ce->clk)) { 66 ce->status = PCE_STATUS_ERROR; 67 } else { 68 clk_prepare(ce->clk); 69 ce->status = PCE_STATUS_ACQUIRED; 70 dev_dbg(dev, "Clock %pC con_id %s managed by runtime PM.\n", 71 ce->clk, ce->con_id); 72 } 73 } 74 75 static int __pm_clk_add(struct device *dev, const char *con_id, 76 struct clk *clk) 77 { 78 struct pm_subsys_data *psd = dev_to_psd(dev); 79 struct pm_clock_entry *ce; 80 81 if (!psd) 82 return -EINVAL; 83 84 ce = kzalloc(sizeof(*ce), GFP_KERNEL); 85 if (!ce) 86 return -ENOMEM; 87 88 if (con_id) { 89 ce->con_id = kstrdup(con_id, GFP_KERNEL); 90 if (!ce->con_id) { 91 dev_err(dev, 92 "Not enough memory for clock connection ID.\n"); 93 kfree(ce); 94 return -ENOMEM; 95 } 96 } else { 97 if (IS_ERR(clk)) { 98 kfree(ce); 99 return -ENOENT; 100 } 101 ce->clk = clk; 102 } 103 104 pm_clk_acquire(dev, ce); 105 106 spin_lock_irq(&psd->lock); 107 list_add_tail(&ce->node, &psd->clock_list); 108 spin_unlock_irq(&psd->lock); 109 return 0; 110 } 111 112 /** 113 * pm_clk_add - Start using a device clock for power management. 114 * @dev: Device whose clock is going to be used for power management. 115 * @con_id: Connection ID of the clock. 116 * 117 * Add the clock represented by @con_id to the list of clocks used for 118 * the power management of @dev. 119 */ 120 int pm_clk_add(struct device *dev, const char *con_id) 121 { 122 return __pm_clk_add(dev, con_id, NULL); 123 } 124 EXPORT_SYMBOL_GPL(pm_clk_add); 125 126 /** 127 * pm_clk_add_clk - Start using a device clock for power management. 128 * @dev: Device whose clock is going to be used for power management. 129 * @clk: Clock pointer 130 * 131 * Add the clock to the list of clocks used for the power management of @dev. 132 * The power-management code will take control of the clock reference, so 133 * callers should not call clk_put() on @clk after this function sucessfully 134 * returned. 135 */ 136 int pm_clk_add_clk(struct device *dev, struct clk *clk) 137 { 138 return __pm_clk_add(dev, NULL, clk); 139 } 140 EXPORT_SYMBOL_GPL(pm_clk_add_clk); 141 142 143 /** 144 * of_pm_clk_add_clk - Start using a device clock for power management. 145 * @dev: Device whose clock is going to be used for power management. 146 * @name: Name of clock that is going to be used for power management. 147 * 148 * Add the clock described in the 'clocks' device-tree node that matches 149 * with the 'name' provided, to the list of clocks used for the power 150 * management of @dev. On success, returns 0. Returns a negative error 151 * code if the clock is not found or cannot be added. 152 */ 153 int of_pm_clk_add_clk(struct device *dev, const char *name) 154 { 155 struct clk *clk; 156 int ret; 157 158 if (!dev || !dev->of_node || !name) 159 return -EINVAL; 160 161 clk = of_clk_get_by_name(dev->of_node, name); 162 if (IS_ERR(clk)) 163 return PTR_ERR(clk); 164 165 ret = pm_clk_add_clk(dev, clk); 166 if (ret) { 167 clk_put(clk); 168 return ret; 169 } 170 171 return 0; 172 } 173 EXPORT_SYMBOL_GPL(of_pm_clk_add_clk); 174 175 /** 176 * of_pm_clk_add_clks - Start using device clock(s) for power management. 177 * @dev: Device whose clock(s) is going to be used for power management. 178 * 179 * Add a series of clocks described in the 'clocks' device-tree node for 180 * a device to the list of clocks used for the power management of @dev. 181 * On success, returns the number of clocks added. Returns a negative 182 * error code if there are no clocks in the device node for the device 183 * or if adding a clock fails. 184 */ 185 int of_pm_clk_add_clks(struct device *dev) 186 { 187 struct clk **clks; 188 unsigned int i, count; 189 int ret; 190 191 if (!dev || !dev->of_node) 192 return -EINVAL; 193 194 count = of_count_phandle_with_args(dev->of_node, "clocks", 195 "#clock-cells"); 196 if (count <= 0) 197 return -ENODEV; 198 199 clks = kcalloc(count, sizeof(*clks), GFP_KERNEL); 200 if (!clks) 201 return -ENOMEM; 202 203 for (i = 0; i < count; i++) { 204 clks[i] = of_clk_get(dev->of_node, i); 205 if (IS_ERR(clks[i])) { 206 ret = PTR_ERR(clks[i]); 207 goto error; 208 } 209 210 ret = pm_clk_add_clk(dev, clks[i]); 211 if (ret) { 212 clk_put(clks[i]); 213 goto error; 214 } 215 } 216 217 kfree(clks); 218 219 return i; 220 221 error: 222 while (i--) 223 pm_clk_remove_clk(dev, clks[i]); 224 225 kfree(clks); 226 227 return ret; 228 } 229 EXPORT_SYMBOL_GPL(of_pm_clk_add_clks); 230 231 /** 232 * __pm_clk_remove - Destroy PM clock entry. 233 * @ce: PM clock entry to destroy. 234 */ 235 static void __pm_clk_remove(struct pm_clock_entry *ce) 236 { 237 if (!ce) 238 return; 239 240 if (ce->status < PCE_STATUS_ERROR) { 241 if (ce->status == PCE_STATUS_ENABLED) 242 clk_disable(ce->clk); 243 244 if (ce->status >= PCE_STATUS_ACQUIRED) { 245 clk_unprepare(ce->clk); 246 clk_put(ce->clk); 247 } 248 } 249 250 kfree(ce->con_id); 251 kfree(ce); 252 } 253 254 /** 255 * pm_clk_remove - Stop using a device clock for power management. 256 * @dev: Device whose clock should not be used for PM any more. 257 * @con_id: Connection ID of the clock. 258 * 259 * Remove the clock represented by @con_id from the list of clocks used for 260 * the power management of @dev. 261 */ 262 void pm_clk_remove(struct device *dev, const char *con_id) 263 { 264 struct pm_subsys_data *psd = dev_to_psd(dev); 265 struct pm_clock_entry *ce; 266 267 if (!psd) 268 return; 269 270 spin_lock_irq(&psd->lock); 271 272 list_for_each_entry(ce, &psd->clock_list, node) { 273 if (!con_id && !ce->con_id) 274 goto remove; 275 else if (!con_id || !ce->con_id) 276 continue; 277 else if (!strcmp(con_id, ce->con_id)) 278 goto remove; 279 } 280 281 spin_unlock_irq(&psd->lock); 282 return; 283 284 remove: 285 list_del(&ce->node); 286 spin_unlock_irq(&psd->lock); 287 288 __pm_clk_remove(ce); 289 } 290 EXPORT_SYMBOL_GPL(pm_clk_remove); 291 292 /** 293 * pm_clk_remove_clk - Stop using a device clock for power management. 294 * @dev: Device whose clock should not be used for PM any more. 295 * @clk: Clock pointer 296 * 297 * Remove the clock pointed to by @clk from the list of clocks used for 298 * the power management of @dev. 299 */ 300 void pm_clk_remove_clk(struct device *dev, struct clk *clk) 301 { 302 struct pm_subsys_data *psd = dev_to_psd(dev); 303 struct pm_clock_entry *ce; 304 305 if (!psd || !clk) 306 return; 307 308 spin_lock_irq(&psd->lock); 309 310 list_for_each_entry(ce, &psd->clock_list, node) { 311 if (clk == ce->clk) 312 goto remove; 313 } 314 315 spin_unlock_irq(&psd->lock); 316 return; 317 318 remove: 319 list_del(&ce->node); 320 spin_unlock_irq(&psd->lock); 321 322 __pm_clk_remove(ce); 323 } 324 EXPORT_SYMBOL_GPL(pm_clk_remove_clk); 325 326 /** 327 * pm_clk_init - Initialize a device's list of power management clocks. 328 * @dev: Device to initialize the list of PM clocks for. 329 * 330 * Initialize the lock and clock_list members of the device's pm_subsys_data 331 * object. 332 */ 333 void pm_clk_init(struct device *dev) 334 { 335 struct pm_subsys_data *psd = dev_to_psd(dev); 336 if (psd) 337 INIT_LIST_HEAD(&psd->clock_list); 338 } 339 EXPORT_SYMBOL_GPL(pm_clk_init); 340 341 /** 342 * pm_clk_create - Create and initialize a device's list of PM clocks. 343 * @dev: Device to create and initialize the list of PM clocks for. 344 * 345 * Allocate a struct pm_subsys_data object, initialize its lock and clock_list 346 * members and make the @dev's power.subsys_data field point to it. 347 */ 348 int pm_clk_create(struct device *dev) 349 { 350 return dev_pm_get_subsys_data(dev); 351 } 352 EXPORT_SYMBOL_GPL(pm_clk_create); 353 354 /** 355 * pm_clk_destroy - Destroy a device's list of power management clocks. 356 * @dev: Device to destroy the list of PM clocks for. 357 * 358 * Clear the @dev's power.subsys_data field, remove the list of clock entries 359 * from the struct pm_subsys_data object pointed to by it before and free 360 * that object. 361 */ 362 void pm_clk_destroy(struct device *dev) 363 { 364 struct pm_subsys_data *psd = dev_to_psd(dev); 365 struct pm_clock_entry *ce, *c; 366 struct list_head list; 367 368 if (!psd) 369 return; 370 371 INIT_LIST_HEAD(&list); 372 373 spin_lock_irq(&psd->lock); 374 375 list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node) 376 list_move(&ce->node, &list); 377 378 spin_unlock_irq(&psd->lock); 379 380 dev_pm_put_subsys_data(dev); 381 382 list_for_each_entry_safe_reverse(ce, c, &list, node) { 383 list_del(&ce->node); 384 __pm_clk_remove(ce); 385 } 386 } 387 EXPORT_SYMBOL_GPL(pm_clk_destroy); 388 389 /** 390 * pm_clk_suspend - Disable clocks in a device's PM clock list. 391 * @dev: Device to disable the clocks for. 392 */ 393 int pm_clk_suspend(struct device *dev) 394 { 395 struct pm_subsys_data *psd = dev_to_psd(dev); 396 struct pm_clock_entry *ce; 397 unsigned long flags; 398 399 dev_dbg(dev, "%s()\n", __func__); 400 401 if (!psd) 402 return 0; 403 404 spin_lock_irqsave(&psd->lock, flags); 405 406 list_for_each_entry_reverse(ce, &psd->clock_list, node) { 407 if (ce->status < PCE_STATUS_ERROR) { 408 if (ce->status == PCE_STATUS_ENABLED) 409 clk_disable(ce->clk); 410 ce->status = PCE_STATUS_ACQUIRED; 411 } 412 } 413 414 spin_unlock_irqrestore(&psd->lock, flags); 415 416 return 0; 417 } 418 EXPORT_SYMBOL_GPL(pm_clk_suspend); 419 420 /** 421 * pm_clk_resume - Enable clocks in a device's PM clock list. 422 * @dev: Device to enable the clocks for. 423 */ 424 int pm_clk_resume(struct device *dev) 425 { 426 struct pm_subsys_data *psd = dev_to_psd(dev); 427 struct pm_clock_entry *ce; 428 unsigned long flags; 429 430 dev_dbg(dev, "%s()\n", __func__); 431 432 if (!psd) 433 return 0; 434 435 spin_lock_irqsave(&psd->lock, flags); 436 437 list_for_each_entry(ce, &psd->clock_list, node) 438 __pm_clk_enable(dev, ce); 439 440 spin_unlock_irqrestore(&psd->lock, flags); 441 442 return 0; 443 } 444 EXPORT_SYMBOL_GPL(pm_clk_resume); 445 446 /** 447 * pm_clk_notify - Notify routine for device addition and removal. 448 * @nb: Notifier block object this function is a member of. 449 * @action: Operation being carried out by the caller. 450 * @data: Device the routine is being run for. 451 * 452 * For this function to work, @nb must be a member of an object of type 453 * struct pm_clk_notifier_block containing all of the requisite data. 454 * Specifically, the pm_domain member of that object is copied to the device's 455 * pm_domain field and its con_ids member is used to populate the device's list 456 * of PM clocks, depending on @action. 457 * 458 * If the device's pm_domain field is already populated with a value different 459 * from the one stored in the struct pm_clk_notifier_block object, the function 460 * does nothing. 461 */ 462 static int pm_clk_notify(struct notifier_block *nb, 463 unsigned long action, void *data) 464 { 465 struct pm_clk_notifier_block *clknb; 466 struct device *dev = data; 467 char **con_id; 468 int error; 469 470 dev_dbg(dev, "%s() %ld\n", __func__, action); 471 472 clknb = container_of(nb, struct pm_clk_notifier_block, nb); 473 474 switch (action) { 475 case BUS_NOTIFY_ADD_DEVICE: 476 if (dev->pm_domain) 477 break; 478 479 error = pm_clk_create(dev); 480 if (error) 481 break; 482 483 dev_pm_domain_set(dev, clknb->pm_domain); 484 if (clknb->con_ids[0]) { 485 for (con_id = clknb->con_ids; *con_id; con_id++) 486 pm_clk_add(dev, *con_id); 487 } else { 488 pm_clk_add(dev, NULL); 489 } 490 491 break; 492 case BUS_NOTIFY_DEL_DEVICE: 493 if (dev->pm_domain != clknb->pm_domain) 494 break; 495 496 dev_pm_domain_set(dev, NULL); 497 pm_clk_destroy(dev); 498 break; 499 } 500 501 return 0; 502 } 503 504 int pm_clk_runtime_suspend(struct device *dev) 505 { 506 int ret; 507 508 dev_dbg(dev, "%s\n", __func__); 509 510 ret = pm_generic_runtime_suspend(dev); 511 if (ret) { 512 dev_err(dev, "failed to suspend device\n"); 513 return ret; 514 } 515 516 ret = pm_clk_suspend(dev); 517 if (ret) { 518 dev_err(dev, "failed to suspend clock\n"); 519 pm_generic_runtime_resume(dev); 520 return ret; 521 } 522 523 return 0; 524 } 525 EXPORT_SYMBOL_GPL(pm_clk_runtime_suspend); 526 527 int pm_clk_runtime_resume(struct device *dev) 528 { 529 int ret; 530 531 dev_dbg(dev, "%s\n", __func__); 532 533 ret = pm_clk_resume(dev); 534 if (ret) { 535 dev_err(dev, "failed to resume clock\n"); 536 return ret; 537 } 538 539 return pm_generic_runtime_resume(dev); 540 } 541 EXPORT_SYMBOL_GPL(pm_clk_runtime_resume); 542 543 #else /* !CONFIG_PM_CLK */ 544 545 /** 546 * enable_clock - Enable a device clock. 547 * @dev: Device whose clock is to be enabled. 548 * @con_id: Connection ID of the clock. 549 */ 550 static void enable_clock(struct device *dev, const char *con_id) 551 { 552 struct clk *clk; 553 554 clk = clk_get(dev, con_id); 555 if (!IS_ERR(clk)) { 556 clk_prepare_enable(clk); 557 clk_put(clk); 558 dev_info(dev, "Runtime PM disabled, clock forced on.\n"); 559 } 560 } 561 562 /** 563 * disable_clock - Disable a device clock. 564 * @dev: Device whose clock is to be disabled. 565 * @con_id: Connection ID of the clock. 566 */ 567 static void disable_clock(struct device *dev, const char *con_id) 568 { 569 struct clk *clk; 570 571 clk = clk_get(dev, con_id); 572 if (!IS_ERR(clk)) { 573 clk_disable_unprepare(clk); 574 clk_put(clk); 575 dev_info(dev, "Runtime PM disabled, clock forced off.\n"); 576 } 577 } 578 579 /** 580 * pm_clk_notify - Notify routine for device addition and removal. 581 * @nb: Notifier block object this function is a member of. 582 * @action: Operation being carried out by the caller. 583 * @data: Device the routine is being run for. 584 * 585 * For this function to work, @nb must be a member of an object of type 586 * struct pm_clk_notifier_block containing all of the requisite data. 587 * Specifically, the con_ids member of that object is used to enable or disable 588 * the device's clocks, depending on @action. 589 */ 590 static int pm_clk_notify(struct notifier_block *nb, 591 unsigned long action, void *data) 592 { 593 struct pm_clk_notifier_block *clknb; 594 struct device *dev = data; 595 char **con_id; 596 597 dev_dbg(dev, "%s() %ld\n", __func__, action); 598 599 clknb = container_of(nb, struct pm_clk_notifier_block, nb); 600 601 switch (action) { 602 case BUS_NOTIFY_BIND_DRIVER: 603 if (clknb->con_ids[0]) { 604 for (con_id = clknb->con_ids; *con_id; con_id++) 605 enable_clock(dev, *con_id); 606 } else { 607 enable_clock(dev, NULL); 608 } 609 break; 610 case BUS_NOTIFY_DRIVER_NOT_BOUND: 611 case BUS_NOTIFY_UNBOUND_DRIVER: 612 if (clknb->con_ids[0]) { 613 for (con_id = clknb->con_ids; *con_id; con_id++) 614 disable_clock(dev, *con_id); 615 } else { 616 disable_clock(dev, NULL); 617 } 618 break; 619 } 620 621 return 0; 622 } 623 624 #endif /* !CONFIG_PM_CLK */ 625 626 /** 627 * pm_clk_add_notifier - Add bus type notifier for power management clocks. 628 * @bus: Bus type to add the notifier to. 629 * @clknb: Notifier to be added to the given bus type. 630 * 631 * The nb member of @clknb is not expected to be initialized and its 632 * notifier_call member will be replaced with pm_clk_notify(). However, 633 * the remaining members of @clknb should be populated prior to calling this 634 * routine. 635 */ 636 void pm_clk_add_notifier(struct bus_type *bus, 637 struct pm_clk_notifier_block *clknb) 638 { 639 if (!bus || !clknb) 640 return; 641 642 clknb->nb.notifier_call = pm_clk_notify; 643 bus_register_notifier(bus, &clknb->nb); 644 } 645 EXPORT_SYMBOL_GPL(pm_clk_add_notifier); 646