linux/drivers/base/power/clock_ops.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks
   4 *
   5 * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/device.h>
  10#include <linux/io.h>
  11#include <linux/pm.h>
  12#include <linux/pm_clock.h>
  13#include <linux/clk.h>
  14#include <linux/clkdev.h>
  15#include <linux/of_clk.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
  23enum pce_status {
  24        PCE_STATUS_NONE = 0,
  25        PCE_STATUS_ACQUIRED,
  26        PCE_STATUS_PREPARED,
  27        PCE_STATUS_ENABLED,
  28        PCE_STATUS_ERROR,
  29};
  30
  31struct pm_clock_entry {
  32        struct list_head node;
  33        char *con_id;
  34        struct clk *clk;
  35        enum pce_status status;
  36        bool enabled_when_prepared;
  37};
  38
  39/**
  40 * pm_clk_list_lock - ensure exclusive access for modifying the PM clock
  41 *                    entry list.
  42 * @psd: pm_subsys_data instance corresponding to the PM clock entry list
  43 *       and clk_op_might_sleep count to be modified.
  44 *
  45 * Get exclusive access before modifying the PM clock entry list and the
  46 * clock_op_might_sleep count to guard against concurrent modifications.
  47 * This also protects against a concurrent clock_op_might_sleep and PM clock
  48 * entry list usage in pm_clk_suspend()/pm_clk_resume() that may or may not
  49 * happen in atomic context, hence both the mutex and the spinlock must be
  50 * taken here.
  51 */
  52static void pm_clk_list_lock(struct pm_subsys_data *psd)
  53        __acquires(&psd->lock)
  54{
  55        mutex_lock(&psd->clock_mutex);
  56        spin_lock_irq(&psd->lock);
  57}
  58
  59/**
  60 * pm_clk_list_unlock - counterpart to pm_clk_list_lock().
  61 * @psd: the same pm_subsys_data instance previously passed to
  62 *       pm_clk_list_lock().
  63 */
  64static void pm_clk_list_unlock(struct pm_subsys_data *psd)
  65        __releases(&psd->lock)
  66{
  67        spin_unlock_irq(&psd->lock);
  68        mutex_unlock(&psd->clock_mutex);
  69}
  70
  71/**
  72 * pm_clk_op_lock - ensure exclusive access for performing clock operations.
  73 * @psd: pm_subsys_data instance corresponding to the PM clock entry list
  74 *       and clk_op_might_sleep count being used.
  75 * @flags: stored irq flags.
  76 * @fn: string for the caller function's name.
  77 *
  78 * This is used by pm_clk_suspend() and pm_clk_resume() to guard
  79 * against concurrent modifications to the clock entry list and the
  80 * clock_op_might_sleep count. If clock_op_might_sleep is != 0 then
  81 * only the mutex can be locked and those functions can only be used in
  82 * non atomic context. If clock_op_might_sleep == 0 then these functions
  83 * may be used in any context and only the spinlock can be locked.
  84 * Returns -EINVAL if called in atomic context when clock ops might sleep.
  85 */
  86static int pm_clk_op_lock(struct pm_subsys_data *psd, unsigned long *flags,
  87                          const char *fn)
  88        /* sparse annotations don't work here as exit state isn't static */
  89{
  90        bool atomic_context = in_atomic() || irqs_disabled();
  91
  92try_again:
  93        spin_lock_irqsave(&psd->lock, *flags);
  94        if (!psd->clock_op_might_sleep) {
  95                /* the __release is there to work around sparse limitations */
  96                __release(&psd->lock);
  97                return 0;
  98        }
  99
 100        /* bail out if in atomic context */
 101        if (atomic_context) {
 102                pr_err("%s: atomic context with clock_ops_might_sleep = %d",
 103                       fn, psd->clock_op_might_sleep);
 104                spin_unlock_irqrestore(&psd->lock, *flags);
 105                might_sleep();
 106                return -EPERM;
 107        }
 108
 109        /* we must switch to the mutex */
 110        spin_unlock_irqrestore(&psd->lock, *flags);
 111        mutex_lock(&psd->clock_mutex);
 112
 113        /*
 114         * There was a possibility for psd->clock_op_might_sleep
 115         * to become 0 above. Keep the mutex only if not the case.
 116         */
 117        if (likely(psd->clock_op_might_sleep))
 118                return 0;
 119
 120        mutex_unlock(&psd->clock_mutex);
 121        goto try_again;
 122}
 123
 124/**
 125 * pm_clk_op_unlock - counterpart to pm_clk_op_lock().
 126 * @psd: the same pm_subsys_data instance previously passed to
 127 *       pm_clk_op_lock().
 128 * @flags: irq flags provided by pm_clk_op_lock().
 129 */
 130static void pm_clk_op_unlock(struct pm_subsys_data *psd, unsigned long *flags)
 131        /* sparse annotations don't work here as entry state isn't static */
 132{
 133        if (psd->clock_op_might_sleep) {
 134                mutex_unlock(&psd->clock_mutex);
 135        } else {
 136                /* the __acquire is there to work around sparse limitations */
 137                __acquire(&psd->lock);
 138                spin_unlock_irqrestore(&psd->lock, *flags);
 139        }
 140}
 141
 142/**
 143 * __pm_clk_enable - Enable a clock, reporting any errors
 144 * @dev: The device for the given clock
 145 * @ce: PM clock entry corresponding to the clock.
 146 */
 147static inline void __pm_clk_enable(struct device *dev, struct pm_clock_entry *ce)
 148{
 149        int ret;
 150
 151        switch (ce->status) {
 152        case PCE_STATUS_ACQUIRED:
 153                ret = clk_prepare_enable(ce->clk);
 154                break;
 155        case PCE_STATUS_PREPARED:
 156                ret = clk_enable(ce->clk);
 157                break;
 158        default:
 159                return;
 160        }
 161        if (!ret)
 162                ce->status = PCE_STATUS_ENABLED;
 163        else
 164                dev_err(dev, "%s: failed to enable clk %p, error %d\n",
 165                        __func__, ce->clk, ret);
 166}
 167
 168/**
 169 * pm_clk_acquire - Acquire a device clock.
 170 * @dev: Device whose clock is to be acquired.
 171 * @ce: PM clock entry corresponding to the clock.
 172 */
 173static void pm_clk_acquire(struct device *dev, struct pm_clock_entry *ce)
 174{
 175        if (!ce->clk)
 176                ce->clk = clk_get(dev, ce->con_id);
 177        if (IS_ERR(ce->clk)) {
 178                ce->status = PCE_STATUS_ERROR;
 179                return;
 180        } else if (clk_is_enabled_when_prepared(ce->clk)) {
 181                /* we defer preparing the clock in that case */
 182                ce->status = PCE_STATUS_ACQUIRED;
 183                ce->enabled_when_prepared = true;
 184        } else if (clk_prepare(ce->clk)) {
 185                ce->status = PCE_STATUS_ERROR;
 186                dev_err(dev, "clk_prepare() failed\n");
 187                return;
 188        } else {
 189                ce->status = PCE_STATUS_PREPARED;
 190        }
 191        dev_dbg(dev, "Clock %pC con_id %s managed by runtime PM.\n",
 192                ce->clk, ce->con_id);
 193}
 194
 195static int __pm_clk_add(struct device *dev, const char *con_id,
 196                        struct clk *clk)
 197{
 198        struct pm_subsys_data *psd = dev_to_psd(dev);
 199        struct pm_clock_entry *ce;
 200
 201        if (!psd)
 202                return -EINVAL;
 203
 204        ce = kzalloc(sizeof(*ce), GFP_KERNEL);
 205        if (!ce)
 206                return -ENOMEM;
 207
 208        if (con_id) {
 209                ce->con_id = kstrdup(con_id, GFP_KERNEL);
 210                if (!ce->con_id) {
 211                        kfree(ce);
 212                        return -ENOMEM;
 213                }
 214        } else {
 215                if (IS_ERR(clk)) {
 216                        kfree(ce);
 217                        return -ENOENT;
 218                }
 219                ce->clk = clk;
 220        }
 221
 222        pm_clk_acquire(dev, ce);
 223
 224        pm_clk_list_lock(psd);
 225        list_add_tail(&ce->node, &psd->clock_list);
 226        if (ce->enabled_when_prepared)
 227                psd->clock_op_might_sleep++;
 228        pm_clk_list_unlock(psd);
 229        return 0;
 230}
 231
 232/**
 233 * pm_clk_add - Start using a device clock for power management.
 234 * @dev: Device whose clock is going to be used for power management.
 235 * @con_id: Connection ID of the clock.
 236 *
 237 * Add the clock represented by @con_id to the list of clocks used for
 238 * the power management of @dev.
 239 */
 240int pm_clk_add(struct device *dev, const char *con_id)
 241{
 242        return __pm_clk_add(dev, con_id, NULL);
 243}
 244EXPORT_SYMBOL_GPL(pm_clk_add);
 245
 246/**
 247 * pm_clk_add_clk - Start using a device clock for power management.
 248 * @dev: Device whose clock is going to be used for power management.
 249 * @clk: Clock pointer
 250 *
 251 * Add the clock to the list of clocks used for the power management of @dev.
 252 * The power-management code will take control of the clock reference, so
 253 * callers should not call clk_put() on @clk after this function sucessfully
 254 * returned.
 255 */
 256int pm_clk_add_clk(struct device *dev, struct clk *clk)
 257{
 258        return __pm_clk_add(dev, NULL, clk);
 259}
 260EXPORT_SYMBOL_GPL(pm_clk_add_clk);
 261
 262
 263/**
 264 * of_pm_clk_add_clk - Start using a device clock for power management.
 265 * @dev: Device whose clock is going to be used for power management.
 266 * @name: Name of clock that is going to be used for power management.
 267 *
 268 * Add the clock described in the 'clocks' device-tree node that matches
 269 * with the 'name' provided, to the list of clocks used for the power
 270 * management of @dev. On success, returns 0. Returns a negative error
 271 * code if the clock is not found or cannot be added.
 272 */
 273int of_pm_clk_add_clk(struct device *dev, const char *name)
 274{
 275        struct clk *clk;
 276        int ret;
 277
 278        if (!dev || !dev->of_node || !name)
 279                return -EINVAL;
 280
 281        clk = of_clk_get_by_name(dev->of_node, name);
 282        if (IS_ERR(clk))
 283                return PTR_ERR(clk);
 284
 285        ret = pm_clk_add_clk(dev, clk);
 286        if (ret) {
 287                clk_put(clk);
 288                return ret;
 289        }
 290
 291        return 0;
 292}
 293EXPORT_SYMBOL_GPL(of_pm_clk_add_clk);
 294
 295/**
 296 * of_pm_clk_add_clks - Start using device clock(s) for power management.
 297 * @dev: Device whose clock(s) is going to be used for power management.
 298 *
 299 * Add a series of clocks described in the 'clocks' device-tree node for
 300 * a device to the list of clocks used for the power management of @dev.
 301 * On success, returns the number of clocks added. Returns a negative
 302 * error code if there are no clocks in the device node for the device
 303 * or if adding a clock fails.
 304 */
 305int of_pm_clk_add_clks(struct device *dev)
 306{
 307        struct clk **clks;
 308        int i, count;
 309        int ret;
 310
 311        if (!dev || !dev->of_node)
 312                return -EINVAL;
 313
 314        count = of_clk_get_parent_count(dev->of_node);
 315        if (count <= 0)
 316                return -ENODEV;
 317
 318        clks = kcalloc(count, sizeof(*clks), GFP_KERNEL);
 319        if (!clks)
 320                return -ENOMEM;
 321
 322        for (i = 0; i < count; i++) {
 323                clks[i] = of_clk_get(dev->of_node, i);
 324                if (IS_ERR(clks[i])) {
 325                        ret = PTR_ERR(clks[i]);
 326                        goto error;
 327                }
 328
 329                ret = pm_clk_add_clk(dev, clks[i]);
 330                if (ret) {
 331                        clk_put(clks[i]);
 332                        goto error;
 333                }
 334        }
 335
 336        kfree(clks);
 337
 338        return i;
 339
 340error:
 341        while (i--)
 342                pm_clk_remove_clk(dev, clks[i]);
 343
 344        kfree(clks);
 345
 346        return ret;
 347}
 348EXPORT_SYMBOL_GPL(of_pm_clk_add_clks);
 349
 350/**
 351 * __pm_clk_remove - Destroy PM clock entry.
 352 * @ce: PM clock entry to destroy.
 353 */
 354static void __pm_clk_remove(struct pm_clock_entry *ce)
 355{
 356        if (!ce)
 357                return;
 358
 359        switch (ce->status) {
 360        case PCE_STATUS_ENABLED:
 361                clk_disable(ce->clk);
 362                fallthrough;
 363        case PCE_STATUS_PREPARED:
 364                clk_unprepare(ce->clk);
 365                fallthrough;
 366        case PCE_STATUS_ACQUIRED:
 367        case PCE_STATUS_ERROR:
 368                if (!IS_ERR(ce->clk))
 369                        clk_put(ce->clk);
 370                break;
 371        default:
 372                break;
 373        }
 374
 375        kfree(ce->con_id);
 376        kfree(ce);
 377}
 378
 379/**
 380 * pm_clk_remove - Stop using a device clock for power management.
 381 * @dev: Device whose clock should not be used for PM any more.
 382 * @con_id: Connection ID of the clock.
 383 *
 384 * Remove the clock represented by @con_id from the list of clocks used for
 385 * the power management of @dev.
 386 */
 387void pm_clk_remove(struct device *dev, const char *con_id)
 388{
 389        struct pm_subsys_data *psd = dev_to_psd(dev);
 390        struct pm_clock_entry *ce;
 391
 392        if (!psd)
 393                return;
 394
 395        pm_clk_list_lock(psd);
 396
 397        list_for_each_entry(ce, &psd->clock_list, node) {
 398                if (!con_id && !ce->con_id)
 399                        goto remove;
 400                else if (!con_id || !ce->con_id)
 401                        continue;
 402                else if (!strcmp(con_id, ce->con_id))
 403                        goto remove;
 404        }
 405
 406        pm_clk_list_unlock(psd);
 407        return;
 408
 409 remove:
 410        list_del(&ce->node);
 411        if (ce->enabled_when_prepared)
 412                psd->clock_op_might_sleep--;
 413        pm_clk_list_unlock(psd);
 414
 415        __pm_clk_remove(ce);
 416}
 417EXPORT_SYMBOL_GPL(pm_clk_remove);
 418
 419/**
 420 * pm_clk_remove_clk - Stop using a device clock for power management.
 421 * @dev: Device whose clock should not be used for PM any more.
 422 * @clk: Clock pointer
 423 *
 424 * Remove the clock pointed to by @clk from the list of clocks used for
 425 * the power management of @dev.
 426 */
 427void pm_clk_remove_clk(struct device *dev, struct clk *clk)
 428{
 429        struct pm_subsys_data *psd = dev_to_psd(dev);
 430        struct pm_clock_entry *ce;
 431
 432        if (!psd || !clk)
 433                return;
 434
 435        pm_clk_list_lock(psd);
 436
 437        list_for_each_entry(ce, &psd->clock_list, node) {
 438                if (clk == ce->clk)
 439                        goto remove;
 440        }
 441
 442        pm_clk_list_unlock(psd);
 443        return;
 444
 445 remove:
 446        list_del(&ce->node);
 447        if (ce->enabled_when_prepared)
 448                psd->clock_op_might_sleep--;
 449        pm_clk_list_unlock(psd);
 450
 451        __pm_clk_remove(ce);
 452}
 453EXPORT_SYMBOL_GPL(pm_clk_remove_clk);
 454
 455/**
 456 * pm_clk_init - Initialize a device's list of power management clocks.
 457 * @dev: Device to initialize the list of PM clocks for.
 458 *
 459 * Initialize the lock and clock_list members of the device's pm_subsys_data
 460 * object, set the count of clocks that might sleep to 0.
 461 */
 462void pm_clk_init(struct device *dev)
 463{
 464        struct pm_subsys_data *psd = dev_to_psd(dev);
 465        if (psd) {
 466                INIT_LIST_HEAD(&psd->clock_list);
 467                mutex_init(&psd->clock_mutex);
 468                psd->clock_op_might_sleep = 0;
 469        }
 470}
 471EXPORT_SYMBOL_GPL(pm_clk_init);
 472
 473/**
 474 * pm_clk_create - Create and initialize a device's list of PM clocks.
 475 * @dev: Device to create and initialize the list of PM clocks for.
 476 *
 477 * Allocate a struct pm_subsys_data object, initialize its lock and clock_list
 478 * members and make the @dev's power.subsys_data field point to it.
 479 */
 480int pm_clk_create(struct device *dev)
 481{
 482        return dev_pm_get_subsys_data(dev);
 483}
 484EXPORT_SYMBOL_GPL(pm_clk_create);
 485
 486/**
 487 * pm_clk_destroy - Destroy a device's list of power management clocks.
 488 * @dev: Device to destroy the list of PM clocks for.
 489 *
 490 * Clear the @dev's power.subsys_data field, remove the list of clock entries
 491 * from the struct pm_subsys_data object pointed to by it before and free
 492 * that object.
 493 */
 494void pm_clk_destroy(struct device *dev)
 495{
 496        struct pm_subsys_data *psd = dev_to_psd(dev);
 497        struct pm_clock_entry *ce, *c;
 498        struct list_head list;
 499
 500        if (!psd)
 501                return;
 502
 503        INIT_LIST_HEAD(&list);
 504
 505        pm_clk_list_lock(psd);
 506
 507        list_for_each_entry_safe_reverse(ce, c, &psd->clock_list, node)
 508                list_move(&ce->node, &list);
 509        psd->clock_op_might_sleep = 0;
 510
 511        pm_clk_list_unlock(psd);
 512
 513        dev_pm_put_subsys_data(dev);
 514
 515        list_for_each_entry_safe_reverse(ce, c, &list, node) {
 516                list_del(&ce->node);
 517                __pm_clk_remove(ce);
 518        }
 519}
 520EXPORT_SYMBOL_GPL(pm_clk_destroy);
 521
 522/**
 523 * pm_clk_suspend - Disable clocks in a device's PM clock list.
 524 * @dev: Device to disable the clocks for.
 525 */
 526int pm_clk_suspend(struct device *dev)
 527{
 528        struct pm_subsys_data *psd = dev_to_psd(dev);
 529        struct pm_clock_entry *ce;
 530        unsigned long flags;
 531        int ret;
 532
 533        dev_dbg(dev, "%s()\n", __func__);
 534
 535        if (!psd)
 536                return 0;
 537
 538        ret = pm_clk_op_lock(psd, &flags, __func__);
 539        if (ret)
 540                return ret;
 541
 542        list_for_each_entry_reverse(ce, &psd->clock_list, node) {
 543                if (ce->status == PCE_STATUS_ENABLED) {
 544                        if (ce->enabled_when_prepared) {
 545                                clk_disable_unprepare(ce->clk);
 546                                ce->status = PCE_STATUS_ACQUIRED;
 547                        } else {
 548                                clk_disable(ce->clk);
 549                                ce->status = PCE_STATUS_PREPARED;
 550                        }
 551                }
 552        }
 553
 554        pm_clk_op_unlock(psd, &flags);
 555
 556        return 0;
 557}
 558EXPORT_SYMBOL_GPL(pm_clk_suspend);
 559
 560/**
 561 * pm_clk_resume - Enable clocks in a device's PM clock list.
 562 * @dev: Device to enable the clocks for.
 563 */
 564int pm_clk_resume(struct device *dev)
 565{
 566        struct pm_subsys_data *psd = dev_to_psd(dev);
 567        struct pm_clock_entry *ce;
 568        unsigned long flags;
 569        int ret;
 570
 571        dev_dbg(dev, "%s()\n", __func__);
 572
 573        if (!psd)
 574                return 0;
 575
 576        ret = pm_clk_op_lock(psd, &flags, __func__);
 577        if (ret)
 578                return ret;
 579
 580        list_for_each_entry(ce, &psd->clock_list, node)
 581                __pm_clk_enable(dev, ce);
 582
 583        pm_clk_op_unlock(psd, &flags);
 584
 585        return 0;
 586}
 587EXPORT_SYMBOL_GPL(pm_clk_resume);
 588
 589/**
 590 * pm_clk_notify - Notify routine for device addition and removal.
 591 * @nb: Notifier block object this function is a member of.
 592 * @action: Operation being carried out by the caller.
 593 * @data: Device the routine is being run for.
 594 *
 595 * For this function to work, @nb must be a member of an object of type
 596 * struct pm_clk_notifier_block containing all of the requisite data.
 597 * Specifically, the pm_domain member of that object is copied to the device's
 598 * pm_domain field and its con_ids member is used to populate the device's list
 599 * of PM clocks, depending on @action.
 600 *
 601 * If the device's pm_domain field is already populated with a value different
 602 * from the one stored in the struct pm_clk_notifier_block object, the function
 603 * does nothing.
 604 */
 605static int pm_clk_notify(struct notifier_block *nb,
 606                                 unsigned long action, void *data)
 607{
 608        struct pm_clk_notifier_block *clknb;
 609        struct device *dev = data;
 610        char **con_id;
 611        int error;
 612
 613        dev_dbg(dev, "%s() %ld\n", __func__, action);
 614
 615        clknb = container_of(nb, struct pm_clk_notifier_block, nb);
 616
 617        switch (action) {
 618        case BUS_NOTIFY_ADD_DEVICE:
 619                if (dev->pm_domain)
 620                        break;
 621
 622                error = pm_clk_create(dev);
 623                if (error)
 624                        break;
 625
 626                dev_pm_domain_set(dev, clknb->pm_domain);
 627                if (clknb->con_ids[0]) {
 628                        for (con_id = clknb->con_ids; *con_id; con_id++)
 629                                pm_clk_add(dev, *con_id);
 630                } else {
 631                        pm_clk_add(dev, NULL);
 632                }
 633
 634                break;
 635        case BUS_NOTIFY_DEL_DEVICE:
 636                if (dev->pm_domain != clknb->pm_domain)
 637                        break;
 638
 639                dev_pm_domain_set(dev, NULL);
 640                pm_clk_destroy(dev);
 641                break;
 642        }
 643
 644        return 0;
 645}
 646
 647int pm_clk_runtime_suspend(struct device *dev)
 648{
 649        int ret;
 650
 651        dev_dbg(dev, "%s\n", __func__);
 652
 653        ret = pm_generic_runtime_suspend(dev);
 654        if (ret) {
 655                dev_err(dev, "failed to suspend device\n");
 656                return ret;
 657        }
 658
 659        ret = pm_clk_suspend(dev);
 660        if (ret) {
 661                dev_err(dev, "failed to suspend clock\n");
 662                pm_generic_runtime_resume(dev);
 663                return ret;
 664        }
 665
 666        return 0;
 667}
 668EXPORT_SYMBOL_GPL(pm_clk_runtime_suspend);
 669
 670int pm_clk_runtime_resume(struct device *dev)
 671{
 672        int ret;
 673
 674        dev_dbg(dev, "%s\n", __func__);
 675
 676        ret = pm_clk_resume(dev);
 677        if (ret) {
 678                dev_err(dev, "failed to resume clock\n");
 679                return ret;
 680        }
 681
 682        return pm_generic_runtime_resume(dev);
 683}
 684EXPORT_SYMBOL_GPL(pm_clk_runtime_resume);
 685
 686#else /* !CONFIG_PM_CLK */
 687
 688/**
 689 * enable_clock - Enable a device clock.
 690 * @dev: Device whose clock is to be enabled.
 691 * @con_id: Connection ID of the clock.
 692 */
 693static void enable_clock(struct device *dev, const char *con_id)
 694{
 695        struct clk *clk;
 696
 697        clk = clk_get(dev, con_id);
 698        if (!IS_ERR(clk)) {
 699                clk_prepare_enable(clk);
 700                clk_put(clk);
 701                dev_info(dev, "Runtime PM disabled, clock forced on.\n");
 702        }
 703}
 704
 705/**
 706 * disable_clock - Disable a device clock.
 707 * @dev: Device whose clock is to be disabled.
 708 * @con_id: Connection ID of the clock.
 709 */
 710static void disable_clock(struct device *dev, const char *con_id)
 711{
 712        struct clk *clk;
 713
 714        clk = clk_get(dev, con_id);
 715        if (!IS_ERR(clk)) {
 716                clk_disable_unprepare(clk);
 717                clk_put(clk);
 718                dev_info(dev, "Runtime PM disabled, clock forced off.\n");
 719        }
 720}
 721
 722/**
 723 * pm_clk_notify - Notify routine for device addition and removal.
 724 * @nb: Notifier block object this function is a member of.
 725 * @action: Operation being carried out by the caller.
 726 * @data: Device the routine is being run for.
 727 *
 728 * For this function to work, @nb must be a member of an object of type
 729 * struct pm_clk_notifier_block containing all of the requisite data.
 730 * Specifically, the con_ids member of that object is used to enable or disable
 731 * the device's clocks, depending on @action.
 732 */
 733static int pm_clk_notify(struct notifier_block *nb,
 734                                 unsigned long action, void *data)
 735{
 736        struct pm_clk_notifier_block *clknb;
 737        struct device *dev = data;
 738        char **con_id;
 739
 740        dev_dbg(dev, "%s() %ld\n", __func__, action);
 741
 742        clknb = container_of(nb, struct pm_clk_notifier_block, nb);
 743
 744        switch (action) {
 745        case BUS_NOTIFY_BIND_DRIVER:
 746                if (clknb->con_ids[0]) {
 747                        for (con_id = clknb->con_ids; *con_id; con_id++)
 748                                enable_clock(dev, *con_id);
 749                } else {
 750                        enable_clock(dev, NULL);
 751                }
 752                break;
 753        case BUS_NOTIFY_DRIVER_NOT_BOUND:
 754        case BUS_NOTIFY_UNBOUND_DRIVER:
 755                if (clknb->con_ids[0]) {
 756                        for (con_id = clknb->con_ids; *con_id; con_id++)
 757                                disable_clock(dev, *con_id);
 758                } else {
 759                        disable_clock(dev, NULL);
 760                }
 761                break;
 762        }
 763
 764        return 0;
 765}
 766
 767#endif /* !CONFIG_PM_CLK */
 768
 769/**
 770 * pm_clk_add_notifier - Add bus type notifier for power management clocks.
 771 * @bus: Bus type to add the notifier to.
 772 * @clknb: Notifier to be added to the given bus type.
 773 *
 774 * The nb member of @clknb is not expected to be initialized and its
 775 * notifier_call member will be replaced with pm_clk_notify().  However,
 776 * the remaining members of @clknb should be populated prior to calling this
 777 * routine.
 778 */
 779void pm_clk_add_notifier(struct bus_type *bus,
 780                                 struct pm_clk_notifier_block *clknb)
 781{
 782        if (!bus || !clknb)
 783                return;
 784
 785        clknb->nb.notifier_call = pm_clk_notify;
 786        bus_register_notifier(bus, &clknb->nb);
 787}
 788EXPORT_SYMBOL_GPL(pm_clk_add_notifier);
 789