| .. | .. |
|---|
| 24 | 24 | #include <linux/timekeeping.h> |
|---|
| 25 | 25 | #include "clock.h" |
|---|
| 26 | 26 | |
|---|
| 27 | | -#define NO_IDLEST 0x1 |
|---|
| 27 | +#define NO_IDLEST 0 |
|---|
| 28 | 28 | |
|---|
| 29 | 29 | #define OMAP4_MODULEMODE_MASK 0x3 |
|---|
| 30 | 30 | |
|---|
| .. | .. |
|---|
| 33 | 33 | |
|---|
| 34 | 34 | #define OMAP4_IDLEST_MASK (0x3 << 16) |
|---|
| 35 | 35 | #define OMAP4_IDLEST_SHIFT 16 |
|---|
| 36 | + |
|---|
| 37 | +#define OMAP4_STBYST_MASK BIT(18) |
|---|
| 38 | +#define OMAP4_STBYST_SHIFT 18 |
|---|
| 36 | 39 | |
|---|
| 37 | 40 | #define CLKCTRL_IDLEST_FUNCTIONAL 0x0 |
|---|
| 38 | 41 | #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 |
|---|
| .. | .. |
|---|
| 159 | 162 | |
|---|
| 160 | 163 | ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); |
|---|
| 161 | 164 | |
|---|
| 162 | | - if (clk->flags & NO_IDLEST) |
|---|
| 165 | + if (test_bit(NO_IDLEST, &clk->flags)) |
|---|
| 163 | 166 | return 0; |
|---|
| 164 | 167 | |
|---|
| 165 | 168 | /* Wait until module is enabled */ |
|---|
| .. | .. |
|---|
| 188 | 191 | |
|---|
| 189 | 192 | ti_clk_ll_ops->clk_writel(val, &clk->enable_reg); |
|---|
| 190 | 193 | |
|---|
| 191 | | - if (clk->flags & NO_IDLEST) |
|---|
| 194 | + if (test_bit(NO_IDLEST, &clk->flags)) |
|---|
| 192 | 195 | goto exit; |
|---|
| 193 | 196 | |
|---|
| 194 | 197 | /* Wait until module is disabled */ |
|---|
| .. | .. |
|---|
| 252 | 255 | return entry->clk; |
|---|
| 253 | 256 | } |
|---|
| 254 | 257 | |
|---|
| 258 | +/* Get clkctrl clock base name based on clkctrl_name or dts node */ |
|---|
| 259 | +static const char * __init clkctrl_get_clock_name(struct device_node *np, |
|---|
| 260 | + const char *clkctrl_name, |
|---|
| 261 | + int offset, int index, |
|---|
| 262 | + bool legacy_naming) |
|---|
| 263 | +{ |
|---|
| 264 | + char *clock_name; |
|---|
| 265 | + |
|---|
| 266 | + /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */ |
|---|
| 267 | + if (clkctrl_name && !legacy_naming) { |
|---|
| 268 | + clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d", |
|---|
| 269 | + clkctrl_name, offset, index); |
|---|
| 270 | + strreplace(clock_name, '_', '-'); |
|---|
| 271 | + |
|---|
| 272 | + return clock_name; |
|---|
| 273 | + } |
|---|
| 274 | + |
|---|
| 275 | + /* l4per:1234:0 old style naming based on clkctrl_name */ |
|---|
| 276 | + if (clkctrl_name) |
|---|
| 277 | + return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d", |
|---|
| 278 | + clkctrl_name, offset, index); |
|---|
| 279 | + |
|---|
| 280 | + /* l4per_cm:1234:0 old style naming based on parent node name */ |
|---|
| 281 | + if (legacy_naming) |
|---|
| 282 | + return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d", |
|---|
| 283 | + np->parent, offset, index); |
|---|
| 284 | + |
|---|
| 285 | + /* l4per-clkctrl:1234:0 style naming based on node name */ |
|---|
| 286 | + return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index); |
|---|
| 287 | +} |
|---|
| 288 | + |
|---|
| 255 | 289 | static int __init |
|---|
| 256 | 290 | _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, |
|---|
| 257 | 291 | struct device_node *node, struct clk_hw *clk_hw, |
|---|
| 258 | 292 | u16 offset, u8 bit, const char * const *parents, |
|---|
| 259 | | - int num_parents, const struct clk_ops *ops) |
|---|
| 293 | + int num_parents, const struct clk_ops *ops, |
|---|
| 294 | + const char *clkctrl_name) |
|---|
| 260 | 295 | { |
|---|
| 261 | 296 | struct clk_init_data init = { NULL }; |
|---|
| 262 | 297 | struct clk *clk; |
|---|
| 263 | 298 | struct omap_clkctrl_clk *clkctrl_clk; |
|---|
| 264 | 299 | int ret = 0; |
|---|
| 265 | 300 | |
|---|
| 266 | | - init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", node->parent->name, |
|---|
| 267 | | - node->name, offset, bit); |
|---|
| 301 | + init.name = clkctrl_get_clock_name(node, clkctrl_name, offset, bit, |
|---|
| 302 | + ti_clk_get_features()->flags & |
|---|
| 303 | + TI_CLK_CLKCTRL_COMPAT); |
|---|
| 304 | + |
|---|
| 268 | 305 | clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); |
|---|
| 269 | 306 | if (!init.name || !clkctrl_clk) { |
|---|
| 270 | 307 | ret = -ENOMEM; |
|---|
| .. | .. |
|---|
| 275 | 312 | init.parent_names = parents; |
|---|
| 276 | 313 | init.num_parents = num_parents; |
|---|
| 277 | 314 | init.ops = ops; |
|---|
| 278 | | - init.flags = CLK_IS_BASIC; |
|---|
| 315 | + init.flags = 0; |
|---|
| 279 | 316 | |
|---|
| 280 | 317 | clk = ti_clk_register(NULL, clk_hw, init.name); |
|---|
| 281 | 318 | if (IS_ERR_OR_NULL(clk)) { |
|---|
| .. | .. |
|---|
| 301 | 338 | _ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider, |
|---|
| 302 | 339 | struct device_node *node, u16 offset, |
|---|
| 303 | 340 | const struct omap_clkctrl_bit_data *data, |
|---|
| 304 | | - void __iomem *reg) |
|---|
| 341 | + void __iomem *reg, const char *clkctrl_name) |
|---|
| 305 | 342 | { |
|---|
| 306 | 343 | struct clk_hw_omap *clk_hw; |
|---|
| 307 | 344 | |
|---|
| .. | .. |
|---|
| 314 | 351 | |
|---|
| 315 | 352 | if (_ti_clkctrl_clk_register(provider, node, &clk_hw->hw, offset, |
|---|
| 316 | 353 | data->bit, data->parents, 1, |
|---|
| 317 | | - &omap_gate_clk_ops)) |
|---|
| 354 | + &omap_gate_clk_ops, clkctrl_name)) |
|---|
| 318 | 355 | kfree(clk_hw); |
|---|
| 319 | 356 | } |
|---|
| 320 | 357 | |
|---|
| .. | .. |
|---|
| 322 | 359 | _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider, |
|---|
| 323 | 360 | struct device_node *node, u16 offset, |
|---|
| 324 | 361 | const struct omap_clkctrl_bit_data *data, |
|---|
| 325 | | - void __iomem *reg) |
|---|
| 362 | + void __iomem *reg, const char *clkctrl_name) |
|---|
| 326 | 363 | { |
|---|
| 327 | 364 | struct clk_omap_mux *mux; |
|---|
| 328 | 365 | int num_parents = 0; |
|---|
| .. | .. |
|---|
| 349 | 386 | |
|---|
| 350 | 387 | if (_ti_clkctrl_clk_register(provider, node, &mux->hw, offset, |
|---|
| 351 | 388 | data->bit, data->parents, num_parents, |
|---|
| 352 | | - &ti_clk_mux_ops)) |
|---|
| 389 | + &ti_clk_mux_ops, clkctrl_name)) |
|---|
| 353 | 390 | kfree(mux); |
|---|
| 354 | 391 | } |
|---|
| 355 | 392 | |
|---|
| .. | .. |
|---|
| 357 | 394 | _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, |
|---|
| 358 | 395 | struct device_node *node, u16 offset, |
|---|
| 359 | 396 | const struct omap_clkctrl_bit_data *data, |
|---|
| 360 | | - void __iomem *reg) |
|---|
| 397 | + void __iomem *reg, const char *clkctrl_name) |
|---|
| 361 | 398 | { |
|---|
| 362 | 399 | struct clk_omap_divider *div; |
|---|
| 363 | 400 | const struct omap_clkctrl_div_data *div_data = data->data; |
|---|
| .. | .. |
|---|
| 376 | 413 | |
|---|
| 377 | 414 | if (ti_clk_parse_divider_data((int *)div_data->dividers, 0, |
|---|
| 378 | 415 | div_data->max_div, div_flags, |
|---|
| 379 | | - &div->width, &div->table)) { |
|---|
| 416 | + div)) { |
|---|
| 380 | 417 | pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__, |
|---|
| 381 | 418 | node, offset, data->bit); |
|---|
| 382 | 419 | kfree(div); |
|---|
| .. | .. |
|---|
| 385 | 422 | |
|---|
| 386 | 423 | if (_ti_clkctrl_clk_register(provider, node, &div->hw, offset, |
|---|
| 387 | 424 | data->bit, data->parents, 1, |
|---|
| 388 | | - &ti_clk_divider_ops)) |
|---|
| 425 | + &ti_clk_divider_ops, clkctrl_name)) |
|---|
| 389 | 426 | kfree(div); |
|---|
| 390 | 427 | } |
|---|
| 391 | 428 | |
|---|
| .. | .. |
|---|
| 393 | 430 | _ti_clkctrl_setup_subclks(struct omap_clkctrl_provider *provider, |
|---|
| 394 | 431 | struct device_node *node, |
|---|
| 395 | 432 | const struct omap_clkctrl_reg_data *data, |
|---|
| 396 | | - void __iomem *reg) |
|---|
| 433 | + void __iomem *reg, const char *clkctrl_name) |
|---|
| 397 | 434 | { |
|---|
| 398 | 435 | const struct omap_clkctrl_bit_data *bits = data->bit_data; |
|---|
| 399 | 436 | |
|---|
| .. | .. |
|---|
| 404 | 441 | switch (bits->type) { |
|---|
| 405 | 442 | case TI_CLK_GATE: |
|---|
| 406 | 443 | _ti_clkctrl_setup_gate(provider, node, data->offset, |
|---|
| 407 | | - bits, reg); |
|---|
| 444 | + bits, reg, clkctrl_name); |
|---|
| 408 | 445 | break; |
|---|
| 409 | 446 | |
|---|
| 410 | 447 | case TI_CLK_DIVIDER: |
|---|
| 411 | 448 | _ti_clkctrl_setup_div(provider, node, data->offset, |
|---|
| 412 | | - bits, reg); |
|---|
| 449 | + bits, reg, clkctrl_name); |
|---|
| 413 | 450 | break; |
|---|
| 414 | 451 | |
|---|
| 415 | 452 | case TI_CLK_MUX: |
|---|
| 416 | 453 | _ti_clkctrl_setup_mux(provider, node, data->offset, |
|---|
| 417 | | - bits, reg); |
|---|
| 454 | + bits, reg, clkctrl_name); |
|---|
| 418 | 455 | break; |
|---|
| 419 | 456 | |
|---|
| 420 | 457 | default: |
|---|
| .. | .. |
|---|
| 432 | 469 | of_clk_add_hw_provider(np, _ti_omap4_clkctrl_xlate, data); |
|---|
| 433 | 470 | } |
|---|
| 434 | 471 | |
|---|
| 472 | +/* Get clock name based on compatible string for clkctrl */ |
|---|
| 473 | +static char * __init clkctrl_get_name(struct device_node *np) |
|---|
| 474 | +{ |
|---|
| 475 | + struct property *prop; |
|---|
| 476 | + const int prefix_len = 11; |
|---|
| 477 | + const char *compat; |
|---|
| 478 | + char *name; |
|---|
| 479 | + |
|---|
| 480 | + of_property_for_each_string(np, "compatible", prop, compat) { |
|---|
| 481 | + if (!strncmp("ti,clkctrl-", compat, prefix_len)) { |
|---|
| 482 | + /* Two letter minimum name length for l3, l4 etc */ |
|---|
| 483 | + if (strnlen(compat + prefix_len, 16) < 2) |
|---|
| 484 | + continue; |
|---|
| 485 | + name = kasprintf(GFP_KERNEL, "%s", compat + prefix_len); |
|---|
| 486 | + if (!name) |
|---|
| 487 | + continue; |
|---|
| 488 | + strreplace(name, '-', '_'); |
|---|
| 489 | + |
|---|
| 490 | + return name; |
|---|
| 491 | + } |
|---|
| 492 | + } |
|---|
| 493 | + |
|---|
| 494 | + return NULL; |
|---|
| 495 | +} |
|---|
| 496 | + |
|---|
| 435 | 497 | static void __init _ti_omap4_clkctrl_setup(struct device_node *node) |
|---|
| 436 | 498 | { |
|---|
| 437 | 499 | struct omap_clkctrl_provider *provider; |
|---|
| .. | .. |
|---|
| 440 | 502 | struct clk_init_data init = { NULL }; |
|---|
| 441 | 503 | struct clk_hw_omap *hw; |
|---|
| 442 | 504 | struct clk *clk; |
|---|
| 443 | | - struct omap_clkctrl_clk *clkctrl_clk; |
|---|
| 505 | + struct omap_clkctrl_clk *clkctrl_clk = NULL; |
|---|
| 444 | 506 | const __be32 *addrp; |
|---|
| 507 | + bool legacy_naming; |
|---|
| 508 | + char *clkctrl_name; |
|---|
| 445 | 509 | u32 addr; |
|---|
| 446 | 510 | int ret; |
|---|
| 511 | + char *c; |
|---|
| 512 | + u16 soc_mask = 0; |
|---|
| 513 | + |
|---|
| 514 | + if (!(ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) && |
|---|
| 515 | + of_node_name_eq(node, "clk")) |
|---|
| 516 | + ti_clk_features.flags |= TI_CLK_CLKCTRL_COMPAT; |
|---|
| 447 | 517 | |
|---|
| 448 | 518 | addrp = of_get_address(node, 0, NULL, NULL); |
|---|
| 449 | 519 | addr = (u32)of_translate_address(node, addrp); |
|---|
| .. | .. |
|---|
| 457 | 527 | data = omap5_clkctrl_data; |
|---|
| 458 | 528 | #endif |
|---|
| 459 | 529 | #ifdef CONFIG_SOC_DRA7XX |
|---|
| 460 | | - if (of_machine_is_compatible("ti,dra7")) |
|---|
| 461 | | - data = dra7_clkctrl_data; |
|---|
| 530 | + if (of_machine_is_compatible("ti,dra7")) { |
|---|
| 531 | + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) |
|---|
| 532 | + data = dra7_clkctrl_compat_data; |
|---|
| 533 | + else |
|---|
| 534 | + data = dra7_clkctrl_data; |
|---|
| 535 | + } |
|---|
| 536 | + |
|---|
| 537 | + if (of_machine_is_compatible("ti,dra72")) |
|---|
| 538 | + soc_mask = CLKF_SOC_DRA72; |
|---|
| 539 | + if (of_machine_is_compatible("ti,dra74")) |
|---|
| 540 | + soc_mask = CLKF_SOC_DRA74; |
|---|
| 541 | + if (of_machine_is_compatible("ti,dra76")) |
|---|
| 542 | + soc_mask = CLKF_SOC_DRA76; |
|---|
| 462 | 543 | #endif |
|---|
| 463 | 544 | #ifdef CONFIG_SOC_AM33XX |
|---|
| 464 | | - if (of_machine_is_compatible("ti,am33xx")) |
|---|
| 465 | | - data = am3_clkctrl_data; |
|---|
| 545 | + if (of_machine_is_compatible("ti,am33xx")) { |
|---|
| 546 | + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) |
|---|
| 547 | + data = am3_clkctrl_compat_data; |
|---|
| 548 | + else |
|---|
| 549 | + data = am3_clkctrl_data; |
|---|
| 550 | + } |
|---|
| 466 | 551 | #endif |
|---|
| 467 | 552 | #ifdef CONFIG_SOC_AM43XX |
|---|
| 468 | | - if (of_machine_is_compatible("ti,am4372")) |
|---|
| 469 | | - data = am4_clkctrl_data; |
|---|
| 470 | | - if (of_machine_is_compatible("ti,am438x")) |
|---|
| 471 | | - data = am438x_clkctrl_data; |
|---|
| 553 | + if (of_machine_is_compatible("ti,am4372")) { |
|---|
| 554 | + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) |
|---|
| 555 | + data = am4_clkctrl_compat_data; |
|---|
| 556 | + else |
|---|
| 557 | + data = am4_clkctrl_data; |
|---|
| 558 | + } |
|---|
| 559 | + |
|---|
| 560 | + if (of_machine_is_compatible("ti,am438x")) { |
|---|
| 561 | + if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) |
|---|
| 562 | + data = am438x_clkctrl_compat_data; |
|---|
| 563 | + else |
|---|
| 564 | + data = am438x_clkctrl_data; |
|---|
| 565 | + } |
|---|
| 472 | 566 | #endif |
|---|
| 473 | 567 | #ifdef CONFIG_SOC_TI81XX |
|---|
| 474 | 568 | if (of_machine_is_compatible("ti,dm814")) |
|---|
| .. | .. |
|---|
| 477 | 571 | if (of_machine_is_compatible("ti,dm816")) |
|---|
| 478 | 572 | data = dm816_clkctrl_data; |
|---|
| 479 | 573 | #endif |
|---|
| 574 | + |
|---|
| 575 | + if (ti_clk_get_features()->flags & TI_CLK_DEVICE_TYPE_GP) |
|---|
| 576 | + soc_mask |= CLKF_SOC_NONSEC; |
|---|
| 480 | 577 | |
|---|
| 481 | 578 | while (data->addr) { |
|---|
| 482 | 579 | if (addr == data->addr) |
|---|
| .. | .. |
|---|
| 496 | 593 | |
|---|
| 497 | 594 | provider->base = of_iomap(node, 0); |
|---|
| 498 | 595 | |
|---|
| 499 | | - provider->clkdm_name = kmalloc(strlen(node->parent->name) + 3, |
|---|
| 500 | | - GFP_KERNEL); |
|---|
| 501 | | - if (!provider->clkdm_name) { |
|---|
| 502 | | - kfree(provider); |
|---|
| 503 | | - return; |
|---|
| 596 | + legacy_naming = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT; |
|---|
| 597 | + clkctrl_name = clkctrl_get_name(node); |
|---|
| 598 | + if (clkctrl_name) { |
|---|
| 599 | + provider->clkdm_name = kasprintf(GFP_KERNEL, |
|---|
| 600 | + "%s_clkdm", clkctrl_name); |
|---|
| 601 | + goto clkdm_found; |
|---|
| 504 | 602 | } |
|---|
| 505 | 603 | |
|---|
| 506 | 604 | /* |
|---|
| 507 | | - * Create default clkdm name, replace _cm from end of parent node |
|---|
| 508 | | - * name with _clkdm |
|---|
| 605 | + * The code below can be removed when all clkctrl nodes use domain |
|---|
| 606 | + * specific compatible proprerty and standard clock node naming |
|---|
| 509 | 607 | */ |
|---|
| 510 | | - strcpy(provider->clkdm_name, node->parent->name); |
|---|
| 511 | | - provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0; |
|---|
| 608 | + if (legacy_naming) { |
|---|
| 609 | + provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent); |
|---|
| 610 | + if (!provider->clkdm_name) { |
|---|
| 611 | + kfree(provider); |
|---|
| 612 | + return; |
|---|
| 613 | + } |
|---|
| 614 | + |
|---|
| 615 | + /* |
|---|
| 616 | + * Create default clkdm name, replace _cm from end of parent |
|---|
| 617 | + * node name with _clkdm |
|---|
| 618 | + */ |
|---|
| 619 | + provider->clkdm_name[strlen(provider->clkdm_name) - 2] = 0; |
|---|
| 620 | + } else { |
|---|
| 621 | + provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFn", node); |
|---|
| 622 | + if (!provider->clkdm_name) { |
|---|
| 623 | + kfree(provider); |
|---|
| 624 | + return; |
|---|
| 625 | + } |
|---|
| 626 | + |
|---|
| 627 | + /* |
|---|
| 628 | + * Create default clkdm name, replace _clkctrl from end of |
|---|
| 629 | + * node name with _clkdm |
|---|
| 630 | + */ |
|---|
| 631 | + provider->clkdm_name[strlen(provider->clkdm_name) - 7] = 0; |
|---|
| 632 | + } |
|---|
| 633 | + |
|---|
| 512 | 634 | strcat(provider->clkdm_name, "clkdm"); |
|---|
| 513 | 635 | |
|---|
| 636 | + /* Replace any dash from the clkdm name with underscore */ |
|---|
| 637 | + c = provider->clkdm_name; |
|---|
| 638 | + |
|---|
| 639 | + while (*c) { |
|---|
| 640 | + if (*c == '-') |
|---|
| 641 | + *c = '_'; |
|---|
| 642 | + c++; |
|---|
| 643 | + } |
|---|
| 644 | +clkdm_found: |
|---|
| 514 | 645 | INIT_LIST_HEAD(&provider->clocks); |
|---|
| 515 | 646 | |
|---|
| 516 | 647 | /* Generate clocks */ |
|---|
| 517 | 648 | reg_data = data->regs; |
|---|
| 518 | 649 | |
|---|
| 519 | 650 | while (reg_data->parent) { |
|---|
| 651 | + if ((reg_data->flags & CLKF_SOC_MASK) && |
|---|
| 652 | + (reg_data->flags & soc_mask) == 0) { |
|---|
| 653 | + reg_data++; |
|---|
| 654 | + continue; |
|---|
| 655 | + } |
|---|
| 656 | + |
|---|
| 520 | 657 | hw = kzalloc(sizeof(*hw), GFP_KERNEL); |
|---|
| 521 | 658 | if (!hw) |
|---|
| 522 | 659 | return; |
|---|
| .. | .. |
|---|
| 524 | 661 | hw->enable_reg.ptr = provider->base + reg_data->offset; |
|---|
| 525 | 662 | |
|---|
| 526 | 663 | _ti_clkctrl_setup_subclks(provider, node, reg_data, |
|---|
| 527 | | - hw->enable_reg.ptr); |
|---|
| 664 | + hw->enable_reg.ptr, clkctrl_name); |
|---|
| 528 | 665 | |
|---|
| 529 | 666 | if (reg_data->flags & CLKF_SW_SUP) |
|---|
| 530 | 667 | hw->enable_bit = MODULEMODE_SWCTRL; |
|---|
| 531 | 668 | if (reg_data->flags & CLKF_HW_SUP) |
|---|
| 532 | 669 | hw->enable_bit = MODULEMODE_HWCTRL; |
|---|
| 533 | 670 | if (reg_data->flags & CLKF_NO_IDLEST) |
|---|
| 534 | | - hw->flags |= NO_IDLEST; |
|---|
| 671 | + set_bit(NO_IDLEST, &hw->flags); |
|---|
| 535 | 672 | |
|---|
| 536 | 673 | if (reg_data->clkdm_name) |
|---|
| 537 | 674 | hw->clkdm_name = reg_data->clkdm_name; |
|---|
| .. | .. |
|---|
| 543 | 680 | init.flags = 0; |
|---|
| 544 | 681 | if (reg_data->flags & CLKF_SET_RATE_PARENT) |
|---|
| 545 | 682 | init.flags |= CLK_SET_RATE_PARENT; |
|---|
| 546 | | - init.name = kasprintf(GFP_KERNEL, "%s:%s:%04x:%d", |
|---|
| 547 | | - node->parent->name, node->name, |
|---|
| 548 | | - reg_data->offset, 0); |
|---|
| 683 | + |
|---|
| 684 | + init.name = clkctrl_get_clock_name(node, clkctrl_name, |
|---|
| 685 | + reg_data->offset, 0, |
|---|
| 686 | + legacy_naming); |
|---|
| 687 | + if (!init.name) |
|---|
| 688 | + goto cleanup; |
|---|
| 689 | + |
|---|
| 549 | 690 | clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); |
|---|
| 550 | | - if (!init.name || !clkctrl_clk) |
|---|
| 691 | + if (!clkctrl_clk) |
|---|
| 551 | 692 | goto cleanup; |
|---|
| 552 | 693 | |
|---|
| 553 | 694 | init.ops = &omap4_clkctrl_clk_ops; |
|---|
| 554 | 695 | hw->hw.init = &init; |
|---|
| 555 | 696 | |
|---|
| 556 | | - clk = ti_clk_register(NULL, &hw->hw, init.name); |
|---|
| 697 | + clk = ti_clk_register_omap_hw(NULL, &hw->hw, init.name); |
|---|
| 557 | 698 | if (IS_ERR_OR_NULL(clk)) |
|---|
| 558 | 699 | goto cleanup; |
|---|
| 559 | 700 | |
|---|
| .. | .. |
|---|
| 569 | 710 | if (ret == -EPROBE_DEFER) |
|---|
| 570 | 711 | ti_clk_retry_init(node, provider, _clkctrl_add_provider); |
|---|
| 571 | 712 | |
|---|
| 713 | + kfree(clkctrl_name); |
|---|
| 714 | + |
|---|
| 572 | 715 | return; |
|---|
| 573 | 716 | |
|---|
| 574 | 717 | cleanup: |
|---|
| 575 | 718 | kfree(hw); |
|---|
| 576 | 719 | kfree(init.name); |
|---|
| 720 | + kfree(clkctrl_name); |
|---|
| 577 | 721 | kfree(clkctrl_clk); |
|---|
| 578 | 722 | } |
|---|
| 579 | 723 | CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl", |
|---|
| 580 | 724 | _ti_omap4_clkctrl_setup); |
|---|
| 725 | + |
|---|
| 726 | +/** |
|---|
| 727 | + * ti_clk_is_in_standby - Check if clkctrl clock is in standby or not |
|---|
| 728 | + * @clk: clock to check standby status for |
|---|
| 729 | + * |
|---|
| 730 | + * Finds whether the provided clock is in standby mode or not. Returns |
|---|
| 731 | + * true if the provided clock is a clkctrl type clock and it is in standby, |
|---|
| 732 | + * false otherwise. |
|---|
| 733 | + */ |
|---|
| 734 | +bool ti_clk_is_in_standby(struct clk *clk) |
|---|
| 735 | +{ |
|---|
| 736 | + struct clk_hw *hw; |
|---|
| 737 | + struct clk_hw_omap *hwclk; |
|---|
| 738 | + u32 val; |
|---|
| 739 | + |
|---|
| 740 | + hw = __clk_get_hw(clk); |
|---|
| 741 | + |
|---|
| 742 | + if (!omap2_clk_is_hw_omap(hw)) |
|---|
| 743 | + return false; |
|---|
| 744 | + |
|---|
| 745 | + hwclk = to_clk_hw_omap(hw); |
|---|
| 746 | + |
|---|
| 747 | + val = ti_clk_ll_ops->clk_readl(&hwclk->enable_reg); |
|---|
| 748 | + |
|---|
| 749 | + if (val & OMAP4_STBYST_MASK) |
|---|
| 750 | + return true; |
|---|
| 751 | + |
|---|
| 752 | + return false; |
|---|
| 753 | +} |
|---|
| 754 | +EXPORT_SYMBOL_GPL(ti_clk_is_in_standby); |
|---|