aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/ti/divider.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clk/ti/divider.c')
-rw-r--r--drivers/clk/ti/divider.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c
index 77f93f6d2806..aaa277dd6d99 100644
--- a/drivers/clk/ti/divider.c
+++ b/drivers/clk/ti/divider.c
@@ -263,6 +263,8 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
263 val |= value << divider->shift; 263 val |= value << divider->shift;
264 ti_clk_ll_ops->clk_writel(val, &divider->reg); 264 ti_clk_ll_ops->clk_writel(val, &divider->reg);
265 265
266 ti_clk_latch(&divider->reg, divider->latch);
267
266 return 0; 268 return 0;
267} 269}
268 270
@@ -276,7 +278,8 @@ static struct clk *_register_divider(struct device *dev, const char *name,
276 const char *parent_name, 278 const char *parent_name,
277 unsigned long flags, 279 unsigned long flags,
278 struct clk_omap_reg *reg, 280 struct clk_omap_reg *reg,
279 u8 shift, u8 width, u8 clk_divider_flags, 281 u8 shift, u8 width, s8 latch,
282 u8 clk_divider_flags,
280 const struct clk_div_table *table) 283 const struct clk_div_table *table)
281{ 284{
282 struct clk_omap_divider *div; 285 struct clk_omap_divider *div;
@@ -305,6 +308,7 @@ static struct clk *_register_divider(struct device *dev, const char *name,
305 memcpy(&div->reg, reg, sizeof(*reg)); 308 memcpy(&div->reg, reg, sizeof(*reg));
306 div->shift = shift; 309 div->shift = shift;
307 div->width = width; 310 div->width = width;
311 div->latch = latch;
308 div->flags = clk_divider_flags; 312 div->flags = clk_divider_flags;
309 div->hw.init = &init; 313 div->hw.init = &init;
310 div->table = table; 314 div->table = table;
@@ -420,6 +424,7 @@ struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup)
420 div->table = _get_div_table_from_setup(setup, &div->width); 424 div->table = _get_div_table_from_setup(setup, &div->width);
421 425
422 div->shift = setup->bit_shift; 426 div->shift = setup->bit_shift;
427 div->latch = -EINVAL;
423 428
424 return &div->hw; 429 return &div->hw;
425} 430}
@@ -452,7 +457,7 @@ struct clk *ti_clk_register_divider(struct ti_clk *setup)
452 457
453 clk = _register_divider(NULL, setup->name, div->parent, 458 clk = _register_divider(NULL, setup->name, div->parent,
454 flags, &reg, div->bit_shift, 459 flags, &reg, div->bit_shift,
455 width, div_flags, table); 460 width, -EINVAL, div_flags, table);
456 461
457 if (IS_ERR(clk)) 462 if (IS_ERR(clk))
458 kfree(table); 463 kfree(table);
@@ -556,7 +561,7 @@ static int _get_divider_width(struct device_node *node,
556 561
557static int __init ti_clk_divider_populate(struct device_node *node, 562static int __init ti_clk_divider_populate(struct device_node *node,
558 struct clk_omap_reg *reg, const struct clk_div_table **table, 563 struct clk_omap_reg *reg, const struct clk_div_table **table,
559 u32 *flags, u8 *div_flags, u8 *width, u8 *shift) 564 u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch)
560{ 565{
561 u32 val; 566 u32 val;
562 int ret; 567 int ret;
@@ -570,6 +575,13 @@ static int __init ti_clk_divider_populate(struct device_node *node,
570 else 575 else
571 *shift = 0; 576 *shift = 0;
572 577
578 if (latch) {
579 if (!of_property_read_u32(node, "ti,latch-bit", &val))
580 *latch = val;
581 else
582 *latch = -EINVAL;
583 }
584
573 *flags = 0; 585 *flags = 0;
574 *div_flags = 0; 586 *div_flags = 0;
575 587
@@ -606,17 +618,18 @@ static void __init of_ti_divider_clk_setup(struct device_node *node)
606 u8 clk_divider_flags = 0; 618 u8 clk_divider_flags = 0;
607 u8 width = 0; 619 u8 width = 0;
608 u8 shift = 0; 620 u8 shift = 0;
621 s8 latch = -EINVAL;
609 const struct clk_div_table *table = NULL; 622 const struct clk_div_table *table = NULL;
610 u32 flags = 0; 623 u32 flags = 0;
611 624
612 parent_name = of_clk_get_parent_name(node, 0); 625 parent_name = of_clk_get_parent_name(node, 0);
613 626
614 if (ti_clk_divider_populate(node, &reg, &table, &flags, 627 if (ti_clk_divider_populate(node, &reg, &table, &flags,
615 &clk_divider_flags, &width, &shift)) 628 &clk_divider_flags, &width, &shift, &latch))
616 goto cleanup; 629 goto cleanup;
617 630
618 clk = _register_divider(NULL, node->name, parent_name, flags, &reg, 631 clk = _register_divider(NULL, node->name, parent_name, flags, &reg,
619 shift, width, clk_divider_flags, table); 632 shift, width, latch, clk_divider_flags, table);
620 633
621 if (!IS_ERR(clk)) { 634 if (!IS_ERR(clk)) {
622 of_clk_add_provider(node, of_clk_src_simple_get, clk); 635 of_clk_add_provider(node, of_clk_src_simple_get, clk);
@@ -639,7 +652,8 @@ static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
639 return; 652 return;
640 653
641 if (ti_clk_divider_populate(node, &div->reg, &div->table, &val, 654 if (ti_clk_divider_populate(node, &div->reg, &div->table, &val,
642 &div->flags, &div->width, &div->shift) < 0) 655 &div->flags, &div->width, &div->shift,
656 NULL) < 0)
643 goto cleanup; 657 goto cleanup;
644 658
645 if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER)) 659 if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))