Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: ti: add support for clock latching to divider clocks

Latching the clock settings is needed with certain clocks, where
the setting is "cached" in HW before doing the actual re-programming
of the clock source. This patch adds support for clock latching to
the divider clock.

Signed-off-by: Tero Kristo <t-kristo@ti.com>

+21 -6
+1
drivers/clk/ti/clock.h
··· 22 22 u8 shift; 23 23 u8 width; 24 24 u8 flags; 25 + s8 latch; 25 26 const struct clk_div_table *table; 26 27 }; 27 28
+20 -6
drivers/clk/ti/divider.c
··· 263 263 val |= value << divider->shift; 264 264 ti_clk_ll_ops->clk_writel(val, &divider->reg); 265 265 266 + ti_clk_latch(&divider->reg, divider->latch); 267 + 266 268 return 0; 267 269 } 268 270 ··· 278 276 const char *parent_name, 279 277 unsigned long flags, 280 278 struct clk_omap_reg *reg, 281 - u8 shift, u8 width, u8 clk_divider_flags, 279 + u8 shift, u8 width, s8 latch, 280 + u8 clk_divider_flags, 282 281 const struct clk_div_table *table) 283 282 { 284 283 struct clk_omap_divider *div; ··· 308 305 memcpy(&div->reg, reg, sizeof(*reg)); 309 306 div->shift = shift; 310 307 div->width = width; 308 + div->latch = latch; 311 309 div->flags = clk_divider_flags; 312 310 div->hw.init = &init; 313 311 div->table = table; ··· 424 420 div->table = _get_div_table_from_setup(setup, &div->width); 425 421 426 422 div->shift = setup->bit_shift; 423 + div->latch = -EINVAL; 427 424 428 425 return &div->hw; 429 426 } ··· 457 452 458 453 clk = _register_divider(NULL, setup->name, div->parent, 459 454 flags, &reg, div->bit_shift, 460 - width, div_flags, table); 455 + width, -EINVAL, div_flags, table); 461 456 462 457 if (IS_ERR(clk)) 463 458 kfree(table); ··· 561 556 562 557 static int __init ti_clk_divider_populate(struct device_node *node, 563 558 struct clk_omap_reg *reg, const struct clk_div_table **table, 564 - u32 *flags, u8 *div_flags, u8 *width, u8 *shift) 559 + u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch) 565 560 { 566 561 u32 val; 567 562 int ret; ··· 574 569 *shift = val; 575 570 else 576 571 *shift = 0; 572 + 573 + if (latch) { 574 + if (!of_property_read_u32(node, "ti,latch-bit", &val)) 575 + *latch = val; 576 + else 577 + *latch = -EINVAL; 578 + } 577 579 578 580 *flags = 0; 579 581 *div_flags = 0; ··· 618 606 u8 clk_divider_flags = 0; 619 607 u8 width = 0; 620 608 u8 shift = 0; 609 + s8 latch = -EINVAL; 621 610 const struct clk_div_table *table = NULL; 622 611 u32 flags = 0; 623 612 624 613 parent_name = of_clk_get_parent_name(node, 0); 625 614 626 615 if (ti_clk_divider_populate(node, &reg, &table, &flags, 627 - &clk_divider_flags, &width, &shift)) 616 + &clk_divider_flags, &width, &shift, &latch)) 628 617 goto cleanup; 629 618 630 619 clk = _register_divider(NULL, node->name, parent_name, flags, &reg, 631 - shift, width, clk_divider_flags, table); 620 + shift, width, latch, clk_divider_flags, table); 632 621 633 622 if (!IS_ERR(clk)) { 634 623 of_clk_add_provider(node, of_clk_src_simple_get, clk); ··· 652 639 return; 653 640 654 641 if (ti_clk_divider_populate(node, &div->reg, &div->table, &val, 655 - &div->flags, &div->width, &div->shift) < 0) 642 + &div->flags, &div->width, &div->shift, 643 + NULL) < 0) 656 644 goto cleanup; 657 645 658 646 if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))