root/drivers/sh/clk/core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. clk_rate_table_build
  2. clk_rate_round_helper
  3. clk_rate_table_iter
  4. clk_rate_table_round
  5. clk_rate_div_range_iter
  6. clk_rate_div_range_round
  7. clk_rate_mult_range_iter
  8. clk_rate_mult_range_round
  9. clk_rate_table_find
  10. followparent_recalc
  11. clk_reparent
  12. propagate_rate
  13. __clk_disable
  14. clk_disable
  15. __clk_enable
  16. clk_enable
  17. recalculate_root_clocks
  18. lookup_root_clock
  19. clk_establish_mapping
  20. clk_destroy_mapping
  21. clk_teardown_mapping
  22. clk_register
  23. clk_unregister
  24. clk_enable_init_clocks
  25. clk_get_rate
  26. clk_set_rate
  27. clk_set_parent
  28. clk_get_parent
  29. clk_round_rate
  30. clks_core_resume
  31. clk_syscore_init
  32. clk_late_init

   1 /*
   2  * SuperH clock framework
   3  *
   4  *  Copyright (C) 2005 - 2010  Paul Mundt
   5  *
   6  * This clock framework is derived from the OMAP version by:
   7  *
   8  *      Copyright (C) 2004 - 2008 Nokia Corporation
   9  *      Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
  10  *
  11  *  Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
  12  *
  13  * This file is subject to the terms and conditions of the GNU General Public
  14  * License.  See the file "COPYING" in the main directory of this archive
  15  * for more details.
  16  */
  17 #define pr_fmt(fmt) "clock: " fmt
  18 
  19 #include <linux/kernel.h>
  20 #include <linux/init.h>
  21 #include <linux/module.h>
  22 #include <linux/mutex.h>
  23 #include <linux/list.h>
  24 #include <linux/syscore_ops.h>
  25 #include <linux/seq_file.h>
  26 #include <linux/err.h>
  27 #include <linux/io.h>
  28 #include <linux/cpufreq.h>
  29 #include <linux/clk.h>
  30 #include <linux/sh_clk.h>
  31 
  32 static LIST_HEAD(clock_list);
  33 static DEFINE_SPINLOCK(clock_lock);
  34 static DEFINE_MUTEX(clock_list_sem);
  35 
  36 /* clock disable operations are not passed on to hardware during boot */
  37 static int allow_disable;
  38 
  39 void clk_rate_table_build(struct clk *clk,
  40                           struct cpufreq_frequency_table *freq_table,
  41                           int nr_freqs,
  42                           struct clk_div_mult_table *src_table,
  43                           unsigned long *bitmap)
  44 {
  45         unsigned long mult, div;
  46         unsigned long freq;
  47         int i;
  48 
  49         clk->nr_freqs = nr_freqs;
  50 
  51         for (i = 0; i < nr_freqs; i++) {
  52                 div = 1;
  53                 mult = 1;
  54 
  55                 if (src_table->divisors && i < src_table->nr_divisors)
  56                         div = src_table->divisors[i];
  57 
  58                 if (src_table->multipliers && i < src_table->nr_multipliers)
  59                         mult = src_table->multipliers[i];
  60 
  61                 if (!div || !mult || (bitmap && !test_bit(i, bitmap)))
  62                         freq = CPUFREQ_ENTRY_INVALID;
  63                 else
  64                         freq = clk->parent->rate * mult / div;
  65 
  66                 freq_table[i].driver_data = i;
  67                 freq_table[i].frequency = freq;
  68         }
  69 
  70         /* Termination entry */
  71         freq_table[i].driver_data = i;
  72         freq_table[i].frequency = CPUFREQ_TABLE_END;
  73 }
  74 
  75 struct clk_rate_round_data;
  76 
  77 struct clk_rate_round_data {
  78         unsigned long rate;
  79         unsigned int min, max;
  80         long (*func)(unsigned int, struct clk_rate_round_data *);
  81         void *arg;
  82 };
  83 
  84 #define for_each_frequency(pos, r, freq)                        \
  85         for (pos = r->min, freq = r->func(pos, r);              \
  86              pos <= r->max; pos++, freq = r->func(pos, r))      \
  87                 if (unlikely(freq == 0))                        \
  88                         ;                                       \
  89                 else
  90 
  91 static long clk_rate_round_helper(struct clk_rate_round_data *rounder)
  92 {
  93         unsigned long rate_error, rate_error_prev = ~0UL;
  94         unsigned long highest, lowest, freq;
  95         long rate_best_fit = -ENOENT;
  96         int i;
  97 
  98         highest = 0;
  99         lowest = ~0UL;
 100 
 101         for_each_frequency(i, rounder, freq) {
 102                 if (freq > highest)
 103                         highest = freq;
 104                 if (freq < lowest)
 105                         lowest = freq;
 106 
 107                 rate_error = abs(freq - rounder->rate);
 108                 if (rate_error < rate_error_prev) {
 109                         rate_best_fit = freq;
 110                         rate_error_prev = rate_error;
 111                 }
 112 
 113                 if (rate_error == 0)
 114                         break;
 115         }
 116 
 117         if (rounder->rate >= highest)
 118                 rate_best_fit = highest;
 119         if (rounder->rate <= lowest)
 120                 rate_best_fit = lowest;
 121 
 122         return rate_best_fit;
 123 }
 124 
 125 static long clk_rate_table_iter(unsigned int pos,
 126                                 struct clk_rate_round_data *rounder)
 127 {
 128         struct cpufreq_frequency_table *freq_table = rounder->arg;
 129         unsigned long freq = freq_table[pos].frequency;
 130 
 131         if (freq == CPUFREQ_ENTRY_INVALID)
 132                 freq = 0;
 133 
 134         return freq;
 135 }
 136 
 137 long clk_rate_table_round(struct clk *clk,
 138                           struct cpufreq_frequency_table *freq_table,
 139                           unsigned long rate)
 140 {
 141         struct clk_rate_round_data table_round = {
 142                 .min    = 0,
 143                 .max    = clk->nr_freqs - 1,
 144                 .func   = clk_rate_table_iter,
 145                 .arg    = freq_table,
 146                 .rate   = rate,
 147         };
 148 
 149         if (clk->nr_freqs < 1)
 150                 return -ENOSYS;
 151 
 152         return clk_rate_round_helper(&table_round);
 153 }
 154 
 155 static long clk_rate_div_range_iter(unsigned int pos,
 156                                     struct clk_rate_round_data *rounder)
 157 {
 158         return clk_get_rate(rounder->arg) / pos;
 159 }
 160 
 161 long clk_rate_div_range_round(struct clk *clk, unsigned int div_min,
 162                               unsigned int div_max, unsigned long rate)
 163 {
 164         struct clk_rate_round_data div_range_round = {
 165                 .min    = div_min,
 166                 .max    = div_max,
 167                 .func   = clk_rate_div_range_iter,
 168                 .arg    = clk_get_parent(clk),
 169                 .rate   = rate,
 170         };
 171 
 172         return clk_rate_round_helper(&div_range_round);
 173 }
 174 
 175 static long clk_rate_mult_range_iter(unsigned int pos,
 176                                       struct clk_rate_round_data *rounder)
 177 {
 178         return clk_get_rate(rounder->arg) * pos;
 179 }
 180 
 181 long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min,
 182                                unsigned int mult_max, unsigned long rate)
 183 {
 184         struct clk_rate_round_data mult_range_round = {
 185                 .min    = mult_min,
 186                 .max    = mult_max,
 187                 .func   = clk_rate_mult_range_iter,
 188                 .arg    = clk_get_parent(clk),
 189                 .rate   = rate,
 190         };
 191 
 192         return clk_rate_round_helper(&mult_range_round);
 193 }
 194 
 195 int clk_rate_table_find(struct clk *clk,
 196                         struct cpufreq_frequency_table *freq_table,
 197                         unsigned long rate)
 198 {
 199         struct cpufreq_frequency_table *pos;
 200         int idx;
 201 
 202         cpufreq_for_each_valid_entry_idx(pos, freq_table, idx)
 203                 if (pos->frequency == rate)
 204                         return idx;
 205 
 206         return -ENOENT;
 207 }
 208 
 209 /* Used for clocks that always have same value as the parent clock */
 210 unsigned long followparent_recalc(struct clk *clk)
 211 {
 212         return clk->parent ? clk->parent->rate : 0;
 213 }
 214 
 215 int clk_reparent(struct clk *child, struct clk *parent)
 216 {
 217         list_del_init(&child->sibling);
 218         if (parent)
 219                 list_add(&child->sibling, &parent->children);
 220         child->parent = parent;
 221 
 222         return 0;
 223 }
 224 
 225 /* Propagate rate to children */
 226 void propagate_rate(struct clk *tclk)
 227 {
 228         struct clk *clkp;
 229 
 230         list_for_each_entry(clkp, &tclk->children, sibling) {
 231                 if (clkp->ops && clkp->ops->recalc)
 232                         clkp->rate = clkp->ops->recalc(clkp);
 233 
 234                 propagate_rate(clkp);
 235         }
 236 }
 237 
 238 static void __clk_disable(struct clk *clk)
 239 {
 240         if (WARN(!clk->usecount, "Trying to disable clock %p with 0 usecount\n",
 241                  clk))
 242                 return;
 243 
 244         if (!(--clk->usecount)) {
 245                 if (likely(allow_disable && clk->ops && clk->ops->disable))
 246                         clk->ops->disable(clk);
 247                 if (likely(clk->parent))
 248                         __clk_disable(clk->parent);
 249         }
 250 }
 251 
 252 void clk_disable(struct clk *clk)
 253 {
 254         unsigned long flags;
 255 
 256         if (!clk)
 257                 return;
 258 
 259         spin_lock_irqsave(&clock_lock, flags);
 260         __clk_disable(clk);
 261         spin_unlock_irqrestore(&clock_lock, flags);
 262 }
 263 EXPORT_SYMBOL_GPL(clk_disable);
 264 
 265 static int __clk_enable(struct clk *clk)
 266 {
 267         int ret = 0;
 268 
 269         if (clk->usecount++ == 0) {
 270                 if (clk->parent) {
 271                         ret = __clk_enable(clk->parent);
 272                         if (unlikely(ret))
 273                                 goto err;
 274                 }
 275 
 276                 if (clk->ops && clk->ops->enable) {
 277                         ret = clk->ops->enable(clk);
 278                         if (ret) {
 279                                 if (clk->parent)
 280                                         __clk_disable(clk->parent);
 281                                 goto err;
 282                         }
 283                 }
 284         }
 285 
 286         return ret;
 287 err:
 288         clk->usecount--;
 289         return ret;
 290 }
 291 
 292 int clk_enable(struct clk *clk)
 293 {
 294         unsigned long flags;
 295         int ret;
 296 
 297         if (!clk)
 298                 return -EINVAL;
 299 
 300         spin_lock_irqsave(&clock_lock, flags);
 301         ret = __clk_enable(clk);
 302         spin_unlock_irqrestore(&clock_lock, flags);
 303 
 304         return ret;
 305 }
 306 EXPORT_SYMBOL_GPL(clk_enable);
 307 
 308 static LIST_HEAD(root_clks);
 309 
 310 /**
 311  * recalculate_root_clocks - recalculate and propagate all root clocks
 312  *
 313  * Recalculates all root clocks (clocks with no parent), which if the
 314  * clock's .recalc is set correctly, should also propagate their rates.
 315  * Called at init.
 316  */
 317 void recalculate_root_clocks(void)
 318 {
 319         struct clk *clkp;
 320 
 321         list_for_each_entry(clkp, &root_clks, sibling) {
 322                 if (clkp->ops && clkp->ops->recalc)
 323                         clkp->rate = clkp->ops->recalc(clkp);
 324                 propagate_rate(clkp);
 325         }
 326 }
 327 
 328 static struct clk_mapping dummy_mapping;
 329 
 330 static struct clk *lookup_root_clock(struct clk *clk)
 331 {
 332         while (clk->parent)
 333                 clk = clk->parent;
 334 
 335         return clk;
 336 }
 337 
 338 static int clk_establish_mapping(struct clk *clk)
 339 {
 340         struct clk_mapping *mapping = clk->mapping;
 341 
 342         /*
 343          * Propagate mappings.
 344          */
 345         if (!mapping) {
 346                 struct clk *clkp;
 347 
 348                 /*
 349                  * dummy mapping for root clocks with no specified ranges
 350                  */
 351                 if (!clk->parent) {
 352                         clk->mapping = &dummy_mapping;
 353                         goto out;
 354                 }
 355 
 356                 /*
 357                  * If we're on a child clock and it provides no mapping of its
 358                  * own, inherit the mapping from its root clock.
 359                  */
 360                 clkp = lookup_root_clock(clk);
 361                 mapping = clkp->mapping;
 362                 BUG_ON(!mapping);
 363         }
 364 
 365         /*
 366          * Establish initial mapping.
 367          */
 368         if (!mapping->base && mapping->phys) {
 369                 kref_init(&mapping->ref);
 370 
 371                 mapping->base = ioremap_nocache(mapping->phys, mapping->len);
 372                 if (unlikely(!mapping->base))
 373                         return -ENXIO;
 374         } else if (mapping->base) {
 375                 /*
 376                  * Bump the refcount for an existing mapping
 377                  */
 378                 kref_get(&mapping->ref);
 379         }
 380 
 381         clk->mapping = mapping;
 382 out:
 383         clk->mapped_reg = clk->mapping->base;
 384         clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys;
 385         return 0;
 386 }
 387 
 388 static void clk_destroy_mapping(struct kref *kref)
 389 {
 390         struct clk_mapping *mapping;
 391 
 392         mapping = container_of(kref, struct clk_mapping, ref);
 393 
 394         iounmap(mapping->base);
 395 }
 396 
 397 static void clk_teardown_mapping(struct clk *clk)
 398 {
 399         struct clk_mapping *mapping = clk->mapping;
 400 
 401         /* Nothing to do */
 402         if (mapping == &dummy_mapping)
 403                 goto out;
 404 
 405         kref_put(&mapping->ref, clk_destroy_mapping);
 406         clk->mapping = NULL;
 407 out:
 408         clk->mapped_reg = NULL;
 409 }
 410 
 411 int clk_register(struct clk *clk)
 412 {
 413         int ret;
 414 
 415         if (IS_ERR_OR_NULL(clk))
 416                 return -EINVAL;
 417 
 418         /*
 419          * trap out already registered clocks
 420          */
 421         if (clk->node.next || clk->node.prev)
 422                 return 0;
 423 
 424         mutex_lock(&clock_list_sem);
 425 
 426         INIT_LIST_HEAD(&clk->children);
 427         clk->usecount = 0;
 428 
 429         ret = clk_establish_mapping(clk);
 430         if (unlikely(ret))
 431                 goto out_unlock;
 432 
 433         if (clk->parent)
 434                 list_add(&clk->sibling, &clk->parent->children);
 435         else
 436                 list_add(&clk->sibling, &root_clks);
 437 
 438         list_add(&clk->node, &clock_list);
 439 
 440 #ifdef CONFIG_SH_CLK_CPG_LEGACY
 441         if (clk->ops && clk->ops->init)
 442                 clk->ops->init(clk);
 443 #endif
 444 
 445 out_unlock:
 446         mutex_unlock(&clock_list_sem);
 447 
 448         return ret;
 449 }
 450 EXPORT_SYMBOL_GPL(clk_register);
 451 
 452 void clk_unregister(struct clk *clk)
 453 {
 454         mutex_lock(&clock_list_sem);
 455         list_del(&clk->sibling);
 456         list_del(&clk->node);
 457         clk_teardown_mapping(clk);
 458         mutex_unlock(&clock_list_sem);
 459 }
 460 EXPORT_SYMBOL_GPL(clk_unregister);
 461 
 462 void clk_enable_init_clocks(void)
 463 {
 464         struct clk *clkp;
 465 
 466         list_for_each_entry(clkp, &clock_list, node)
 467                 if (clkp->flags & CLK_ENABLE_ON_INIT)
 468                         clk_enable(clkp);
 469 }
 470 
 471 unsigned long clk_get_rate(struct clk *clk)
 472 {
 473         if (!clk)
 474                 return 0;
 475 
 476         return clk->rate;
 477 }
 478 EXPORT_SYMBOL_GPL(clk_get_rate);
 479 
 480 int clk_set_rate(struct clk *clk, unsigned long rate)
 481 {
 482         int ret = -EOPNOTSUPP;
 483         unsigned long flags;
 484 
 485         if (!clk)
 486                 return 0;
 487 
 488         spin_lock_irqsave(&clock_lock, flags);
 489 
 490         if (likely(clk->ops && clk->ops->set_rate)) {
 491                 ret = clk->ops->set_rate(clk, rate);
 492                 if (ret != 0)
 493                         goto out_unlock;
 494         } else {
 495                 clk->rate = rate;
 496                 ret = 0;
 497         }
 498 
 499         if (clk->ops && clk->ops->recalc)
 500                 clk->rate = clk->ops->recalc(clk);
 501 
 502         propagate_rate(clk);
 503 
 504 out_unlock:
 505         spin_unlock_irqrestore(&clock_lock, flags);
 506 
 507         return ret;
 508 }
 509 EXPORT_SYMBOL_GPL(clk_set_rate);
 510 
 511 int clk_set_parent(struct clk *clk, struct clk *parent)
 512 {
 513         unsigned long flags;
 514         int ret = -EINVAL;
 515 
 516         if (!parent || !clk)
 517                 return ret;
 518         if (clk->parent == parent)
 519                 return 0;
 520 
 521         spin_lock_irqsave(&clock_lock, flags);
 522         if (clk->usecount == 0) {
 523                 if (clk->ops->set_parent)
 524                         ret = clk->ops->set_parent(clk, parent);
 525                 else
 526                         ret = clk_reparent(clk, parent);
 527 
 528                 if (ret == 0) {
 529                         if (clk->ops->recalc)
 530                                 clk->rate = clk->ops->recalc(clk);
 531                         pr_debug("set parent of %p to %p (new rate %ld)\n",
 532                                  clk, clk->parent, clk->rate);
 533                         propagate_rate(clk);
 534                 }
 535         } else
 536                 ret = -EBUSY;
 537         spin_unlock_irqrestore(&clock_lock, flags);
 538 
 539         return ret;
 540 }
 541 EXPORT_SYMBOL_GPL(clk_set_parent);
 542 
 543 struct clk *clk_get_parent(struct clk *clk)
 544 {
 545         if (!clk)
 546                 return NULL;
 547 
 548         return clk->parent;
 549 }
 550 EXPORT_SYMBOL_GPL(clk_get_parent);
 551 
 552 long clk_round_rate(struct clk *clk, unsigned long rate)
 553 {
 554         if (!clk)
 555                 return 0;
 556 
 557         if (likely(clk->ops && clk->ops->round_rate)) {
 558                 unsigned long flags, rounded;
 559 
 560                 spin_lock_irqsave(&clock_lock, flags);
 561                 rounded = clk->ops->round_rate(clk, rate);
 562                 spin_unlock_irqrestore(&clock_lock, flags);
 563 
 564                 return rounded;
 565         }
 566 
 567         return clk_get_rate(clk);
 568 }
 569 EXPORT_SYMBOL_GPL(clk_round_rate);
 570 
 571 #ifdef CONFIG_PM
 572 static void clks_core_resume(void)
 573 {
 574         struct clk *clkp;
 575 
 576         list_for_each_entry(clkp, &clock_list, node) {
 577                 if (likely(clkp->usecount && clkp->ops)) {
 578                         unsigned long rate = clkp->rate;
 579 
 580                         if (likely(clkp->ops->set_parent))
 581                                 clkp->ops->set_parent(clkp,
 582                                         clkp->parent);
 583                         if (likely(clkp->ops->set_rate))
 584                                 clkp->ops->set_rate(clkp, rate);
 585                         else if (likely(clkp->ops->recalc))
 586                                 clkp->rate = clkp->ops->recalc(clkp);
 587                 }
 588         }
 589 }
 590 
 591 static struct syscore_ops clks_syscore_ops = {
 592         .resume = clks_core_resume,
 593 };
 594 
 595 static int __init clk_syscore_init(void)
 596 {
 597         register_syscore_ops(&clks_syscore_ops);
 598 
 599         return 0;
 600 }
 601 subsys_initcall(clk_syscore_init);
 602 #endif
 603 
 604 static int __init clk_late_init(void)
 605 {
 606         unsigned long flags;
 607         struct clk *clk;
 608 
 609         /* disable all clocks with zero use count */
 610         mutex_lock(&clock_list_sem);
 611         spin_lock_irqsave(&clock_lock, flags);
 612 
 613         list_for_each_entry(clk, &clock_list, node)
 614                 if (!clk->usecount && clk->ops && clk->ops->disable)
 615                         clk->ops->disable(clk);
 616 
 617         /* from now on allow clock disable operations */
 618         allow_disable = 1;
 619 
 620         spin_unlock_irqrestore(&clock_lock, flags);
 621         mutex_unlock(&clock_list_sem);
 622         return 0;
 623 }
 624 late_initcall(clk_late_init);

/* [<][>][^][v][top][bottom][index][help] */