1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * OMAP clkctrl clock support 4 * 5 * Copyright (C) 2017 Texas Instruments, Inc. 6 * 7 * Tero Kristo <t-kristo@ti.com> 8 */ 9 10 #include <linux/clk-provider.h> 11 #include <linux/slab.h> 12 #include <linux/of.h> 13 #include <linux/of_address.h> 14 #include <linux/clk/ti.h> 15 #include <linux/delay.h> 16 #include <linux/timekeeping.h> 17 #include "clock.h" 18 19 #define NO_IDLEST 0 20 21 #define OMAP4_MODULEMODE_MASK 0x3 22 23 #define MODULEMODE_HWCTRL 0x1 24 #define MODULEMODE_SWCTRL 0x2 25 26 #define OMAP4_IDLEST_MASK (0x3 << 16) 27 #define OMAP4_IDLEST_SHIFT 16 28 29 #define OMAP4_STBYST_MASK BIT(18) 30 #define OMAP4_STBYST_SHIFT 18 31 32 #define CLKCTRL_IDLEST_FUNCTIONAL 0x0 33 #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 34 #define CLKCTRL_IDLEST_DISABLED 0x3 35 36 /* These timeouts are in us */ 37 #define OMAP4_MAX_MODULE_READY_TIME 2000 38 #define OMAP4_MAX_MODULE_DISABLE_TIME 5000 39 40 static bool _early_timeout = true; 41 42 struct omap_clkctrl_provider { 43 void __iomem *base; 44 struct list_head clocks; 45 char *clkdm_name; 46 }; 47 48 struct omap_clkctrl_clk { 49 struct clk_hw *clk; 50 u16 reg_offset; 51 int bit_offset; 52 struct list_head node; 53 }; 54 55 union omap4_timeout { 56 u32 cycles; 57 ktime_t start; 58 }; 59 60 static const struct omap_clkctrl_data default_clkctrl_data[] __initconst = { 61 { 0 }, 62 }; 63 64 static u32 _omap4_idlest(u32 val) 65 { 66 val &= OMAP4_IDLEST_MASK; 67 val >>= OMAP4_IDLEST_SHIFT; 68 69 return val; 70 } 71 72 static bool _omap4_is_idle(u32 val) 73 { 74 val = _omap4_idlest(val); 75 76 return val == CLKCTRL_IDLEST_DISABLED; 77 } 78 79 static bool _omap4_is_ready(u32 val) 80 { 81 val = _omap4_idlest(val); 82 83 return val == CLKCTRL_IDLEST_FUNCTIONAL || 84 val == CLKCTRL_IDLEST_INTERFACE_IDLE; 85 } 86 87 static bool _omap4_is_timeout(union omap4_timeout *time, u32 timeout) 88 { 89 /* 90 * There are two special cases where ktime_to_ns() can't be 91 * used to track the timeouts. First one is during early boot 92 * when the timers haven't been initialized yet. The second 93 * one is during suspend-resume cycle while timekeeping is 94 * being suspended / resumed. Clocksource for the system 95 * can be from a timer that requires pm_runtime access, which 96 * will eventually bring us here with timekeeping_suspended, 97 * during both suspend entry and resume paths. This happens 98 * at least on am43xx platform. Account for flakeyness 99 * with udelay() by multiplying the timeout value by 2. 100 */ 101 if (unlikely(_early_timeout || timekeeping_suspended)) { 102 if (time->cycles++ < timeout) { 103 udelay(1 * 2); 104 return false; 105 } 106 } else { 107 if (!ktime_to_ns(time->start)) { 108 time->start = ktime_get(); 109 return false; 110 } 111 112 if (ktime_us_delta(ktime_get(), time->start) < timeout) { 113 cpu_relax(); 114 return false; 115 } 116 } 117 118 return true; 119 } 120 121 static int __init _omap4_disable_early_timeout(void) 122 { 123 _early_timeout = false; 124 125 return 0; 126 } 127 arch_initcall(_omap4_disable_early_timeout); 128 129 static int _omap4_clkctrl_clk_enable(struct clk_hw *hw) 130 { 131 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 132 u32 val; 133 int ret; 134 union omap4_timeout timeout = { 0 }; 135 136 if (clk->clkdm) { 137 ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk); 138 if (ret) { 139 WARN(1, 140 "%s: could not enable %s's clockdomain %s: %d\n", 141 __func__, clk_hw_get_name(hw), 142 clk->clkdm_name, ret); 143 return ret; 144 } 145 } 146 147 if (!clk->enable_bit) 148 return 0; 149 150 val = ti_clk_ll_ops->clk_readl(&clk->enable_reg); 151 152 val &= ~OMAP4_MODULEMODE_MASK; 153 val |= clk->enable_bit; 154 155 ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); 156 157 if (test_bit(NO_IDLEST, &clk->flags)) 158 return 0; 159 160 /* Wait until module is enabled */ 161 while (!_omap4_is_ready(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) { 162 if (_omap4_is_timeout(&timeout, OMAP4_MAX_MODULE_READY_TIME)) { 163 pr_err("%s: failed to enable\n", clk_hw_get_name(hw)); 164 return -EBUSY; 165 } 166 } 167 168 return 0; 169 } 170 171 static void _omap4_clkctrl_clk_disable(struct clk_hw *hw) 172 { 173 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 174 u32 val; 175 union omap4_timeout timeout = { 0 }; 176 177 if (!clk->enable_bit) 178 goto exit; 179 180 val = ti_clk_ll_ops->clk_readl(&clk->enable_reg); 181 182 val &= ~OMAP4_MODULEMODE_MASK; 183 184 ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); 185 186 if (test_bit(NO_IDLEST, &clk->flags)) 187 goto exit; 188 189 /* Wait until module is disabled */ 190 while (!_omap4_is_idle(ti_clk_ll_ops->clk_readl(&clk->enable_reg))) { 191 if (_omap4_is_timeout(&timeout, 192 OMAP4_MAX_MODULE_DISABLE_TIME)) { 193 pr_err("%s: failed to disable\n", clk_hw_get_name(hw)); 194 break; 195 } 196 } 197 198 exit: 199 if (clk->clkdm) 200 ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk); 201 } 202 203 static int _omap4_clkctrl_clk_is_enabled(struct clk_hw *hw) 204 { 205 struct clk_hw_omap *clk = to_clk_hw_omap(hw); 206 u32 val; 207 208 val = ti_clk_ll_ops->clk_readl(&clk->enable_reg); 209 210 if (val & clk->enable_bit) 211 return 1; 212 213 return 0; 214 } 215 216 static const struct clk_ops omap4_clkctrl_clk_ops = { 217 .enable = _omap4_clkctrl_clk_enable, 218 .disable = _omap4_clkctrl_clk_disable, 219 .is_enabled = _omap4_clkctrl_clk_is_enabled, 220 .init = omap2_init_clk_clkdm, 221 }; 222 223 static struct clk_hw *_ti_omap4_clkctrl_xlate(struct of_phandle_args *clkspec, 224 void *data) 225 { 226 struct omap_clkctrl_provider *provider = data; 227 struct omap_clkctrl_clk *entry = NULL, *iter; 228 229 if (clkspec->args_count != 2) 230 return ERR_PTR(-EINVAL); 231 232 pr_debug("%s: looking for %x:%x\n", __func__, 233 clkspec->args[0], clkspec->args[1]); 234 235 list_for_each_entry(iter, &provider->clocks, node) { 236 if (iter->reg_offset == clkspec->args[0] && 237 iter->bit_offset == clkspec->args[1]) { 238 entry = iter; 239 break; 240 } 241 } 242 243 if (!entry) 244 return ERR_PTR(-EINVAL); 245 246 return entry->clk; 247 } 248 249 /* Get clkctrl clock base name based on clkctrl_name or dts node */ 250 static const char * __init clkctrl_get_clock_name(struct device_node *np, 251 const char *clkctrl_name, 252 int offset, int index, 253 bool legacy_naming) 254 { 255 char *clock_name; 256 257 /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */ 258 if (clkctrl_name && !legacy_naming) { 259 clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", 260 clkctrl_name, offset, index); 261 if (!clock_name) 262 return NULL; 263 264 strreplace(clock_name, '_', '-'); 265 266 return clock_name; 267 } 268 269 /* l4per:1234:0 old style naming based on clkctrl_name */ 270 if (clkctrl_name) 271 return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d", 272 clkctrl_name, offset, index); 273 274 /* l4per_cm:1234:0 old style naming based on parent node name */ 275 if (legacy_naming) 276 return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d", 277 np->parent, offset, index); 278 279 /* l4per-clkctrl:1234:0 style naming based on node name */ 280 return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index); 281 } 282 283 static int __init 284 _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, 285 struct device_node *node, struct clk_hw *clk_hw, 286 u16 offset, u8 bit, const char * const *parents, 287 int num_parents, const struct clk_ops *ops, 288 const char *clkctrl_name) 289 { 290 struct clk_init_data init = { NULL }; 291 struct clk *clk; 292 struct omap_clkctrl_clk *clkctrl_clk; 293 int ret = 0; 294 295 init.name = clkctrl_get_clock_name(node, clkctrl_name, offset, bit, 296 ti_clk_get_features()->flags & 297 TI_CLK_CLKCTRL_COMPAT); 298 299 clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); 300 if (!init.name || !clkctrl_clk) { 301 ret = -ENOMEM; 302 goto cleanup; 303 } 304 305 clk_hw->init = &init; 306 init.parent_names = parents; 307 init.num_parents = num_parents; 308 init.ops = ops; 309 init.flags = 0; 310 311 clk = of_ti_clk_register(node, clk_hw, init.name); 312 if (IS_ERR_OR_NULL(clk)) { 313 ret = -EINVAL; 314 goto cleanup; 315 } 316 317 clkctrl_clk->reg_offset = offset; 318 clkctrl_clk->bit_offset = bit; 319 clkctrl_clk->clk = clk_hw; 320 321 list_add(&clkctrl_clk->node, &provider->clocks); 322 323 return 0; 324 325 cleanup: 326 kfree(init.name); 327 kfree(clkctrl_clk); 328 return ret; 329 } 330 331 static void __init 332 _ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider, 333 struct device_node *node, u16 offset, 334 const struct omap_clkctrl_bit_data *data, 335 void __iomem *reg, const char *clkctrl_name) 336 { 337 struct clk_hw_omap *clk_hw; 338 339 clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); 340 if (!clk_hw) 341 return; 342 343 clk_hw->enable_bit = data->bit; 344 clk_hw->enable_reg.ptr = reg; 345 346 if (_ti_clkctrl_clk_register(provider, node, &clk_hw->hw, offset, 347 data->bit, data->parents, 1, 348 &omap_gate_clk_ops, clkctrl_name)) 349 kfree(clk_hw); 350 } 351 352 static void __init 353 _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider, 354 struct device_node *node, u16 offset, 355 const struct omap_clkctrl_bit_data *data, 356 void __iomem *reg, const char *clkctrl_name) 357 { 358 struct clk_omap_mux *mux; 359 int num_parents = 0; 360 const char * const *pname; 361 362 mux = kzalloc(sizeof(*mux), GFP_KERNEL); 363 if (!mux) 364 return; 365 366 pname = data->parents; 367 while (*pname) { 368 num_parents++; 369 pname++; 370 } 371 372 mux->mask = num_parents; 373 if (!(mux->flags & CLK_MUX_INDEX_ONE)) 374 mux->mask--; 375 376 mux->mask = (1 << fls(mux->mask)) - 1; 377 378 mux->shift = data->bit; 379 mux->reg.ptr = reg; 380 381 if (_ti_clkctrl_clk_register(provider, node, &mux->hw, offset, 382 data->bit, data->parents, num_parents, 383 &ti_clk_mux_ops, clkctrl_name)) 384 kfree(mux); 385 } 386 387 static void __init 388 _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, 389 struct device_node *node, u16 offset, 390 const struct omap_clkctrl_bit_data *data, 391 void __iomem *reg, const char *clkctrl_name) 392 { 393 struct clk_omap_divider *div; 394 const struct omap_clkctrl_div_data *div_data = data->data; 395 u8 div_flags = 0; 396 397 div = kzalloc(sizeof(*div), GFP_KERNEL); 398 if (!div) 399 return; 400 401 div->reg.ptr = reg; 402 div->shift = data->bit; 403 div->flags = div_data->flags; 404 405 if (div->flags & CLK_DIVIDER_POWER_OF_TWO) 406 div_flags |= CLKF_INDEX_POWER_OF_TWO; 407 408 if (ti_clk_parse_divider_data((int *)div_data->dividers, 0, 409 div_data->max_div, div_flags, 410 div)) { 411 pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__, 412 node, offset, data->bit); 413 kfree(div); 414 return; 415 } 416 417 if (_ti_clkctrl_clk_register(provider, node, &div->hw, offset, 418 data->bit, data->parents, 1, 419 &ti_clk_divider_ops, clkctrl_name)) 420 kfree(div); 421 } 422 423 static void __init 424 _ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider, 425 struct device_node *node, 426 const struct omap_clkctrl_reg_data *data, 427 void __iomem *reg, const char *clkctrl_name) 428 { 429 const struct omap_clkctrl_bit_data *bits = data->bit_data; 430 431 if (!bits) 432 return; 433 434 while (bits->bit) { 435 switch (bits->type) { 436 case TI_CLK_GATE: 437 _ti_clkctrl_setup_gate(provider, node, data->offset, 438 bits, reg, clkctrl_name); 439 break; 440 441 case TI_CLK_DIVIDER: 442 _ti_clkctrl_setup_div(provider, node, data->offset, 443 bits, reg, clkctrl_name); 444 break; 445 446 case TI_CLK_MUX: 447 _ti_clkctrl_setup_mux(provider, node, data->offset, 448 bits, reg, clkctrl_name); 449 break; 450 451 default: 452 pr_err("%s: bad subclk type: %d\n", __func__, 453 bits->type); 454 return; 455 } 456 bits++; 457 } 458 } 459 460 static void __init _clkctrl_add_provider(void *data, 461 struct device_node *np) 462 { 463 of_clk_add_hw_provider(np, _ti_omap4_clkctrl_xlate, data); 464 } 465 466 /* 467 * Get clock name based on "clock-output-names" property or the 468 * compatible property for clkctrl. 469 */ 470 static const char * __init clkctrl_get_name(struct device_node *np) 471 { 472 struct property *prop; 473 const int prefix_len = 11; 474 const char *compat; 475 const char *output; 476 char *name; 477 478 if (!of_property_read_string_index(np, "clock-output-names", 0, 479 &output)) { 480 const char *end; 481 int len; 482 483 len = strlen(output); 484 end = strstr(output, "_clkctrl"); 485 if (end) 486 len -= strlen(end); 487 name = kstrndup(output, len, GFP_KERNEL); 488 489 return name; 490 } 491 492 of_property_for_each_string(np, "compatible", prop, compat) { 493 if (!strncmp("ti,clkctrl-", compat, prefix_len)) { 494 /* Two letter minimum name length for l3, l4 etc */ 495 if (strnlen(compat + prefix_len, 16) < 2) 496 continue; 497 name = kasprintf(GFP_KERNEL, "%s", compat + prefix_len); 498 if (!name) 499 continue; 500 strreplace(name, '-', '_'); 501 502 return name; 503 } 504 } 505 506 return NULL; 507 } 508 509 static void __init _ti_omap4_clkctrl_setup(struct device_node *node) 510 { 511 struct omap_clkctrl_provider *provider; 512 const struct omap_clkctrl_data *data = default_clkctrl_data; 513 const struct omap_clkctrl_reg_data *reg_data; 514 struct clk_init_data init = { NULL }; 515 struct clk_hw_omap *hw; 516 struct clk *clk; 517 struct omap_clkctrl_clk *clkctrl_clk = NULL; 518 bool legacy_naming; 519 const char *clkctrl_name; 520 u32 addr; 521 int ret; 522 char *c; 523 u16 soc_mask = 0; 524 struct resource res; 525 526 of_address_to_resource(node, 0, &res); 527 addr = (u32)res.start; 528 529 #ifdef CONFIG_ARCH_OMAP4 530 if (of_machine_is_compatible("ti,omap4")) 531 data = omap4_clkctrl_data; 532 #endif 533 #ifdef CONFIG_SOC_OMAP5 534 if (of_machine_is_compatible("ti,omap5")) 535 data = omap5_clkctrl_data; 536 #endif 537 #ifdef CONFIG_SOC_DRA7XX 538 if (of_machine_is_compatible("ti,dra7")) 539 data = dra7_clkctrl_data; 540 if (of_machine_is_compatible("ti,dra72")) 541 soc_mask = CLKF_SOC_DRA72; 542 if (of_machine_is_compatible("ti,dra74")) 543 soc_mask = CLKF_SOC_DRA74; 544 if (of_machine_is_compatible("ti,dra76")) 545 soc_mask = CLKF_SOC_DRA76; 546 #endif 547 #ifdef CONFIG_SOC_AM33XX 548 if (of_machine_is_compatible("ti,am33xx")) 549 data = am3_clkctrl_data; 550 #endif 551 #ifdef CONFIG_SOC_AM43XX 552 if (of_machine_is_compatible("ti,am4372")) 553 data = am4_clkctrl_data; 554 555 if (of_machine_is_compatible("ti,am438x")) 556 data = am438x_clkctrl_data; 557 #endif 558 #ifdef CONFIG_SOC_TI81XX 559 if (of_machine_is_compatible("ti,dm814")) 560 data = dm814_clkctrl_data; 561 562 if (of_machine_is_compatible("ti,dm816")) 563 data = dm816_clkctrl_data; 564 #endif 565 566 if (ti_clk_get_features()->flags & TI_CLK_DEVICE_TYPE_GP) 567 soc_mask |= CLKF_SOC_NONSEC; 568 569 while (data->addr) { 570 if (addr == data->addr) 571 break; 572 573 data++; 574 } 575 576 if (!data->addr) { 577 pr_err("%pOF not found from clkctrl data.\n", node); 578 return; 579 } 580 581 provider = kzalloc(sizeof(*provider), GFP_KERNEL); 582 if (!provider) 583 return; 584 585 provider->base = of_iomap(node, 0); 586 587 legacy_naming = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT; 588 clkctrl_name = clkctrl_get_name(node); 589 if (clkctrl_name) { 590 provider->clkdm_name = kasprintf(GFP_KERNEL, 591 "%s_clkdm", clkctrl_name); 592 if (!provider->clkdm_name) { 593 kfree(provider); 594 return; 595 } 596 goto clkdm_found; 597 } 598 599 /* 600 * The code below can be removed when all clkctrl nodes use domain 601 * specific compatible property and standard clock node naming 602 */ 603 if (legacy_naming) { 604 provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent); 605 if (!provider->clkdm_name) { 606 kfree(provider); 607 return; 608 } 609 610 /* 611 * Create default clkdm name, replace _cm from end of parent 612 * node name with _clkdm 613 */ 614 provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0; 615 } else { 616 provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFn", node); 617 if (!provider->clkdm_name) { 618 kfree(provider); 619 return; 620 } 621 622 /* 623 * Create default clkdm name, replace _clkctrl from end of 624 * node name with _clkdm 625 */ 626 provider->clkdm_name[strlen(provider->clkdm_name) - 7] = 0; 627 } 628 629 strcat(provider->clkdm_name, "clkdm"); 630 631 /* Replace any dash from the clkdm name with underscore */ 632 c = provider->clkdm_name; 633 634 while (*c) { 635 if (*c == '-') 636 *c = '_'; 637 c++; 638 } 639 clkdm_found: 640 INIT_LIST_HEAD(&provider->clocks); 641 642 /* Generate clocks */ 643 reg_data = data->regs; 644 645 while (reg_data->parent) { 646 if ((reg_data->flags & CLKF_SOC_MASK) && 647 (reg_data->flags & soc_mask) == 0) { 648 reg_data++; 649 continue; 650 } 651 652 hw = kzalloc(sizeof(*hw), GFP_KERNEL); 653 if (!hw) 654 return; 655 656 hw->enable_reg.ptr = provider->base + reg_data->offset; 657 658 _ti_clkctrl_setup_subclks(provider, node, reg_data, 659 hw->enable_reg.ptr, clkctrl_name); 660 661 if (reg_data->flags & CLKF_SW_SUP) 662 hw->enable_bit = MODULEMODE_SWCTRL; 663 if (reg_data->flags & CLKF_HW_SUP) 664 hw->enable_bit = MODULEMODE_HWCTRL; 665 if (reg_data->flags & CLKF_NO_IDLEST) 666 set_bit(NO_IDLEST, &hw->flags); 667 668 if (reg_data->clkdm_name) 669 hw->clkdm_name = reg_data->clkdm_name; 670 else 671 hw->clkdm_name = provider->clkdm_name; 672 673 init.parent_names = ®_data->parent; 674 init.num_parents = 1; 675 init.flags = 0; 676 if (reg_data->flags & CLKF_SET_RATE_PARENT) 677 init.flags |= CLK_SET_RATE_PARENT; 678 679 init.name = clkctrl_get_clock_name(node, clkctrl_name, 680 reg_data->offset, 0, 681 legacy_naming); 682 if (!init.name) 683 goto cleanup; 684 685 clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); 686 if (!clkctrl_clk) 687 goto cleanup; 688 689 init.ops = &omap4_clkctrl_clk_ops; 690 hw->hw.init = &init; 691 692 clk = of_ti_clk_register_omap_hw(node, &hw->hw, init.name); 693 if (IS_ERR_OR_NULL(clk)) 694 goto cleanup; 695 696 clkctrl_clk->reg_offset = reg_data->offset; 697 clkctrl_clk->clk = &hw->hw; 698 699 list_add(&clkctrl_clk->node, &provider->clocks); 700 701 reg_data++; 702 } 703 704 ret = of_clk_add_hw_provider(node, _ti_omap4_clkctrl_xlate, provider); 705 if (ret == -EPROBE_DEFER) 706 ti_clk_retry_init(node, provider, _clkctrl_add_provider); 707 708 kfree(clkctrl_name); 709 710 return; 711 712 cleanup: 713 kfree(hw); 714 kfree(init.name); 715 kfree(clkctrl_name); 716 kfree(clkctrl_clk); 717 } 718 CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl", 719 _ti_omap4_clkctrl_setup); 720 721 /** 722 * ti_clk_is_in_standby - Check if clkctrl clock is in standby or not 723 * @clk: clock to check standby status for 724 * 725 * Finds whether the provided clock is in standby mode or not. Returns 726 * true if the provided clock is a clkctrl type clock and it is in standby, 727 * false otherwise. 728 */ 729 bool ti_clk_is_in_standby(struct clk *clk) 730 { 731 struct clk_hw *hw; 732 struct clk_hw_omap *hwclk; 733 u32 val; 734 735 hw = __clk_get_hw(clk); 736 737 if (!omap2_clk_is_hw_omap(hw)) 738 return false; 739 740 hwclk = to_clk_hw_omap(hw); 741 742 val = ti_clk_ll_ops->clk_readl(&hwclk->enable_reg); 743 744 if (val & OMAP4_STBYST_MASK) 745 return true; 746 747 return false; 748 } 749 EXPORT_SYMBOL_GPL(ti_clk_is_in_standby); 750