clkgen-mux.c (527c465a3c8716d93201ae34b7fc52679610596d) | clkgen-mux.c (0b4e7f0842fe5c8bd19654999f6c41c4119e7c90) |
---|---|
1/* 2 * clkgen-mux.c: ST GEN-MUX Clock driver 3 * 4 * Copyright (C) 2014 STMicroelectronics (R&D) Limited 5 * 6 * Authors: Stephen Gallimore <stephen.gallimore@st.com> 7 * Pankaj Dev <pankaj.dev@st.com> 8 * --- 10 unchanged lines hidden (view full) --- 19 20static DEFINE_SPINLOCK(clkgena_divmux_lock); 21static DEFINE_SPINLOCK(clkgenf_lock); 22 23static const char ** __init clkgen_mux_get_parents(struct device_node *np, 24 int *num_parents) 25{ 26 const char **parents; | 1/* 2 * clkgen-mux.c: ST GEN-MUX Clock driver 3 * 4 * Copyright (C) 2014 STMicroelectronics (R&D) Limited 5 * 6 * Authors: Stephen Gallimore <stephen.gallimore@st.com> 7 * Pankaj Dev <pankaj.dev@st.com> 8 * --- 10 unchanged lines hidden (view full) --- 19 20static DEFINE_SPINLOCK(clkgena_divmux_lock); 21static DEFINE_SPINLOCK(clkgenf_lock); 22 23static const char ** __init clkgen_mux_get_parents(struct device_node *np, 24 int *num_parents) 25{ 26 const char **parents; |
27 int nparents, i; | 27 int nparents; |
28 29 nparents = of_clk_get_parent_count(np); 30 if (WARN_ON(nparents <= 0)) 31 return ERR_PTR(-EINVAL); 32 | 28 29 nparents = of_clk_get_parent_count(np); 30 if (WARN_ON(nparents <= 0)) 31 return ERR_PTR(-EINVAL); 32 |
33 parents = kzalloc(nparents * sizeof(const char *), GFP_KERNEL); | 33 parents = kcalloc(nparents, sizeof(const char *), GFP_KERNEL); |
34 if (!parents) 35 return ERR_PTR(-ENOMEM); 36 | 34 if (!parents) 35 return ERR_PTR(-ENOMEM); 36 |
37 for (i = 0; i < nparents; i++) 38 parents[i] = of_clk_get_parent_name(np, i); 39 40 *num_parents = nparents; | 37 *num_parents = of_clk_parent_fill(np, parents, nparents); |
41 return parents; 42} 43 44/** 45 * DOC: Clock mux with a programmable divider on each of its three inputs. 46 * The mux has an input setting which effectively gates its output. 47 * 48 * Traits of this clock: --- 161 unchanged lines hidden (view full) --- 210 .round_rate = clkgena_divmux_round_rate, 211 .recalc_rate = clkgena_divmux_recalc_rate, 212 .set_rate = clkgena_divmux_set_rate, 213}; 214 215/** 216 * clk_register_genamux - register a genamux clock with the clock framework 217 */ | 38 return parents; 39} 40 41/** 42 * DOC: Clock mux with a programmable divider on each of its three inputs. 43 * The mux has an input setting which effectively gates its output. 44 * 45 * Traits of this clock: --- 161 unchanged lines hidden (view full) --- 207 .round_rate = clkgena_divmux_round_rate, 208 .recalc_rate = clkgena_divmux_recalc_rate, 209 .set_rate = clkgena_divmux_set_rate, 210}; 211 212/** 213 * clk_register_genamux - register a genamux clock with the clock framework 214 */ |
218static struct clk *clk_register_genamux(const char *name, | 215static struct clk * __init clk_register_genamux(const char *name, |
219 const char **parent_names, u8 num_parents, 220 void __iomem *reg, 221 const struct clkgena_divmux_data *muxdata, 222 u32 idx) 223{ 224 /* 225 * Fixed constants across all ClockgenA variants 226 */ --- 137 unchanged lines hidden (view full) --- 364 }, 365 { 366 .compatible = "st,clkgena-divmux-c32-odf3", 367 .data = &st_divmux_c32odf3, 368 }, 369 {} 370}; 371 | 216 const char **parent_names, u8 num_parents, 217 void __iomem *reg, 218 const struct clkgena_divmux_data *muxdata, 219 u32 idx) 220{ 221 /* 222 * Fixed constants across all ClockgenA variants 223 */ --- 137 unchanged lines hidden (view full) --- 361 }, 362 { 363 .compatible = "st,clkgena-divmux-c32-odf3", 364 .data = &st_divmux_c32odf3, 365 }, 366 {} 367}; 368 |
372static void __iomem * __init clkgen_get_register_base( 373 struct device_node *np) | 369static void __iomem * __init clkgen_get_register_base(struct device_node *np) |
374{ 375 struct device_node *pnode; | 370{ 371 struct device_node *pnode; |
376 void __iomem *reg = NULL; | 372 void __iomem *reg; |
377 378 pnode = of_get_parent(np); 379 if (!pnode) 380 return NULL; 381 382 reg = of_iomap(pnode, 0); 383 384 of_node_put(pnode); --- 8 unchanged lines hidden (view full) --- 393 void __iomem *reg; 394 const char **parents; 395 int num_parents = 0, i; 396 397 match = of_match_node(clkgena_divmux_of_match, np); 398 if (WARN_ON(!match)) 399 return; 400 | 373 374 pnode = of_get_parent(np); 375 if (!pnode) 376 return NULL; 377 378 reg = of_iomap(pnode, 0); 379 380 of_node_put(pnode); --- 8 unchanged lines hidden (view full) --- 389 void __iomem *reg; 390 const char **parents; 391 int num_parents = 0, i; 392 393 match = of_match_node(clkgena_divmux_of_match, np); 394 if (WARN_ON(!match)) 395 return; 396 |
401 data = (struct clkgena_divmux_data *)match->data; | 397 data = match->data; |
402 403 reg = clkgen_get_register_base(np); 404 if (!reg) 405 return; 406 407 parents = clkgen_mux_get_parents(np, &num_parents); 408 if (IS_ERR(parents)) | 398 399 reg = clkgen_get_register_base(np); 400 if (!reg) 401 return; 402 403 parents = clkgen_mux_get_parents(np, &num_parents); 404 if (IS_ERR(parents)) |
409 return; | 405 goto err_parents; |
410 411 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 412 if (!clk_data) | 406 407 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 408 if (!clk_data) |
413 goto err; | 409 goto err_alloc; |
414 415 clk_data->clk_num = data->num_outputs; | 410 411 clk_data->clk_num = data->num_outputs; |
416 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), | 412 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), |
417 GFP_KERNEL); 418 419 if (!clk_data->clks) | 413 GFP_KERNEL); 414 415 if (!clk_data->clks) |
420 goto err; | 416 goto err_alloc_clks; |
421 422 for (i = 0; i < clk_data->clk_num; i++) { 423 struct clk *clk; 424 const char *clk_name; 425 426 if (of_property_read_string_index(np, "clock-output-names", 427 i, &clk_name)) 428 break; --- 13 unchanged lines hidden (view full) --- 442 clk_data->clks[i] = clk; 443 } 444 445 kfree(parents); 446 447 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 448 return; 449err: | 417 418 for (i = 0; i < clk_data->clk_num; i++) { 419 struct clk *clk; 420 const char *clk_name; 421 422 if (of_property_read_string_index(np, "clock-output-names", 423 i, &clk_name)) 424 break; --- 13 unchanged lines hidden (view full) --- 438 clk_data->clks[i] = clk; 439 } 440 441 kfree(parents); 442 443 of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); 444 return; 445err: |
450 if (clk_data) 451 kfree(clk_data->clks); 452 | 446 kfree(clk_data->clks); 447err_alloc_clks: |
453 kfree(clk_data); | 448 kfree(clk_data); |
449err_alloc: |
|
454 kfree(parents); | 450 kfree(parents); |
451err_parents: 452 iounmap(reg); |
|
455} 456CLK_OF_DECLARE(clkgenadivmux, "st,clkgena-divmux", st_of_clkgena_divmux_setup); 457 458struct clkgena_prediv_data { 459 u32 offset; 460 u8 shift; 461 struct clk_div_table *table; 462}; --- 23 unchanged lines hidden (view full) --- 486}; 487 488static void __init st_of_clkgena_prediv_setup(struct device_node *np) 489{ 490 const struct of_device_id *match; 491 void __iomem *reg; 492 const char *parent_name, *clk_name; 493 struct clk *clk; | 453} 454CLK_OF_DECLARE(clkgenadivmux, "st,clkgena-divmux", st_of_clkgena_divmux_setup); 455 456struct clkgena_prediv_data { 457 u32 offset; 458 u8 shift; 459 struct clk_div_table *table; 460}; --- 23 unchanged lines hidden (view full) --- 484}; 485 486static void __init st_of_clkgena_prediv_setup(struct device_node *np) 487{ 488 const struct of_device_id *match; 489 void __iomem *reg; 490 const char *parent_name, *clk_name; 491 struct clk *clk; |
494 struct clkgena_prediv_data *data; | 492 const struct clkgena_prediv_data *data; |
495 496 match = of_match_node(clkgena_prediv_of_match, np); 497 if (!match) { 498 pr_err("%s: No matching data\n", __func__); 499 return; 500 } 501 | 493 494 match = of_match_node(clkgena_prediv_of_match, np); 495 if (!match) { 496 pr_err("%s: No matching data\n", __func__); 497 return; 498 } 499 |
502 data = (struct clkgena_prediv_data *)match->data; | 500 data = match->data; |
503 504 reg = clkgen_get_register_base(np); 505 if (!reg) 506 return; 507 508 parent_name = of_clk_get_parent_name(np, 0); 509 if (!parent_name) | 501 502 reg = clkgen_get_register_base(np); 503 if (!reg) 504 return; 505 506 parent_name = of_clk_get_parent_name(np, 0); 507 if (!parent_name) |
510 return; | 508 goto err; |
511 512 if (of_property_read_string_index(np, "clock-output-names", 513 0, &clk_name)) | 509 510 if (of_property_read_string_index(np, "clock-output-names", 511 0, &clk_name)) |
514 return; | 512 goto err; |
515 516 clk = clk_register_divider_table(NULL, clk_name, parent_name, 517 CLK_GET_RATE_NOCACHE, 518 reg + data->offset, data->shift, 1, 519 0, data->table, NULL); 520 if (IS_ERR(clk)) | 513 514 clk = clk_register_divider_table(NULL, clk_name, parent_name, 515 CLK_GET_RATE_NOCACHE, 516 reg + data->offset, data->shift, 1, 517 0, data->table, NULL); 518 if (IS_ERR(clk)) |
521 return; | 519 goto err; |
522 523 of_clk_add_provider(np, of_clk_src_simple_get, clk); 524 pr_debug("%s: parent %s rate %u\n", 525 __clk_get_name(clk), 526 __clk_get_name(clk_get_parent(clk)), 527 (unsigned int)clk_get_rate(clk)); 528 529 return; | 520 521 of_clk_add_provider(np, of_clk_src_simple_get, clk); 522 pr_debug("%s: parent %s rate %u\n", 523 __clk_get_name(clk), 524 __clk_get_name(clk_get_parent(clk)), 525 (unsigned int)clk_get_rate(clk)); 526 527 return; |
528err: 529 iounmap(reg); |
|
530} 531CLK_OF_DECLARE(clkgenaprediv, "st,clkgena-prediv", st_of_clkgena_prediv_setup); 532 533struct clkgen_mux_data { 534 u32 offset; 535 u8 shift; 536 u8 width; 537 spinlock_t *lock; --- 87 unchanged lines hidden (view full) --- 625 626static void __init st_of_clkgen_mux_setup(struct device_node *np) 627{ 628 const struct of_device_id *match; 629 struct clk *clk; 630 void __iomem *reg; 631 const char **parents; 632 int num_parents; | 530} 531CLK_OF_DECLARE(clkgenaprediv, "st,clkgena-prediv", st_of_clkgena_prediv_setup); 532 533struct clkgen_mux_data { 534 u32 offset; 535 u8 shift; 536 u8 width; 537 spinlock_t *lock; --- 87 unchanged lines hidden (view full) --- 625 626static void __init st_of_clkgen_mux_setup(struct device_node *np) 627{ 628 const struct of_device_id *match; 629 struct clk *clk; 630 void __iomem *reg; 631 const char **parents; 632 int num_parents; |
633 struct clkgen_mux_data *data; | 633 const struct clkgen_mux_data *data; |
634 635 match = of_match_node(mux_of_match, np); 636 if (!match) { 637 pr_err("%s: No matching data\n", __func__); 638 return; 639 } 640 | 634 635 match = of_match_node(mux_of_match, np); 636 if (!match) { 637 pr_err("%s: No matching data\n", __func__); 638 return; 639 } 640 |
641 data = (struct clkgen_mux_data *)match->data; | 641 data = match->data; |
642 643 reg = of_iomap(np, 0); 644 if (!reg) { 645 pr_err("%s: Failed to get base address\n", __func__); 646 return; 647 } 648 649 parents = clkgen_mux_get_parents(np, &num_parents); 650 if (IS_ERR(parents)) { 651 pr_err("%s: Failed to get parents (%ld)\n", 652 __func__, PTR_ERR(parents)); | 642 643 reg = of_iomap(np, 0); 644 if (!reg) { 645 pr_err("%s: Failed to get base address\n", __func__); 646 return; 647 } 648 649 parents = clkgen_mux_get_parents(np, &num_parents); 650 if (IS_ERR(parents)) { 651 pr_err("%s: Failed to get parents (%ld)\n", 652 __func__, PTR_ERR(parents)); |
653 return; | 653 goto err_parents; |
654 } 655 656 clk = clk_register_mux(NULL, np->name, parents, num_parents, 657 data->clk_flags | CLK_SET_RATE_PARENT, 658 reg + data->offset, 659 data->shift, data->width, data->mux_flags, 660 data->lock); 661 if (IS_ERR(clk)) 662 goto err; 663 664 pr_debug("%s: parent %s rate %u\n", 665 __clk_get_name(clk), 666 __clk_get_name(clk_get_parent(clk)), 667 (unsigned int)clk_get_rate(clk)); 668 | 654 } 655 656 clk = clk_register_mux(NULL, np->name, parents, num_parents, 657 data->clk_flags | CLK_SET_RATE_PARENT, 658 reg + data->offset, 659 data->shift, data->width, data->mux_flags, 660 data->lock); 661 if (IS_ERR(clk)) 662 goto err; 663 664 pr_debug("%s: parent %s rate %u\n", 665 __clk_get_name(clk), 666 __clk_get_name(clk_get_parent(clk)), 667 (unsigned int)clk_get_rate(clk)); 668 |
669 kfree(parents); |
|
669 of_clk_add_provider(np, of_clk_src_simple_get, clk); | 670 of_clk_add_provider(np, of_clk_src_simple_get, clk); |
671 return; |
|
670 671err: 672 kfree(parents); | 672 673err: 674 kfree(parents); |
673 674 return; | 675err_parents: 676 iounmap(reg); |
675} 676CLK_OF_DECLARE(clkgen_mux, "st,clkgen-mux", st_of_clkgen_mux_setup); 677 678#define VCC_MAX_CHANNELS 16 679 680#define VCC_GATE_OFFSET 0x0 681#define VCC_MUX_OFFSET 0x4 682#define VCC_DIV_OFFSET 0x8 --- 19 unchanged lines hidden (view full) --- 702 703static void __init st_of_clkgen_vcc_setup(struct device_node *np) 704{ 705 const struct of_device_id *match; 706 void __iomem *reg; 707 const char **parents; 708 int num_parents, i; 709 struct clk_onecell_data *clk_data; | 677} 678CLK_OF_DECLARE(clkgen_mux, "st,clkgen-mux", st_of_clkgen_mux_setup); 679 680#define VCC_MAX_CHANNELS 16 681 682#define VCC_GATE_OFFSET 0x0 683#define VCC_MUX_OFFSET 0x4 684#define VCC_DIV_OFFSET 0x8 --- 19 unchanged lines hidden (view full) --- 704 705static void __init st_of_clkgen_vcc_setup(struct device_node *np) 706{ 707 const struct of_device_id *match; 708 void __iomem *reg; 709 const char **parents; 710 int num_parents, i; 711 struct clk_onecell_data *clk_data; |
710 struct clkgen_vcc_data *data; | 712 const struct clkgen_vcc_data *data; |
711 712 match = of_match_node(vcc_of_match, np); 713 if (WARN_ON(!match)) 714 return; | 713 714 match = of_match_node(vcc_of_match, np); 715 if (WARN_ON(!match)) 716 return; |
715 data = (struct clkgen_vcc_data *)match->data; | 717 data = match->data; |
716 717 reg = of_iomap(np, 0); 718 if (!reg) 719 return; 720 721 parents = clkgen_mux_get_parents(np, &num_parents); 722 if (IS_ERR(parents)) | 718 719 reg = of_iomap(np, 0); 720 if (!reg) 721 return; 722 723 parents = clkgen_mux_get_parents(np, &num_parents); 724 if (IS_ERR(parents)) |
723 return; | 725 goto err_parents; |
724 725 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 726 if (!clk_data) | 726 727 clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); 728 if (!clk_data) |
727 goto err; | 729 goto err_alloc; |
728 729 clk_data->clk_num = VCC_MAX_CHANNELS; | 730 731 clk_data->clk_num = VCC_MAX_CHANNELS; |
730 clk_data->clks = kzalloc(clk_data->clk_num * sizeof(struct clk *), | 732 clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), |
731 GFP_KERNEL); 732 733 if (!clk_data->clks) | 733 GFP_KERNEL); 734 735 if (!clk_data->clks) |
734 goto err; | 736 goto err_alloc_clks; |
735 736 for (i = 0; i < clk_data->clk_num; i++) { 737 struct clk *clk; 738 const char *clk_name; 739 struct clk_gate *gate; 740 struct clk_divider *div; 741 struct clk_mux *mux; 742 743 if (of_property_read_string_index(np, "clock-output-names", 744 i, &clk_name)) 745 break; 746 747 /* 748 * If we read an empty clock name then the output is unused 749 */ 750 if (*clk_name == '\0') 751 continue; 752 | 737 738 for (i = 0; i < clk_data->clk_num; i++) { 739 struct clk *clk; 740 const char *clk_name; 741 struct clk_gate *gate; 742 struct clk_divider *div; 743 struct clk_mux *mux; 744 745 if (of_property_read_string_index(np, "clock-output-names", 746 i, &clk_name)) 747 break; 748 749 /* 750 * If we read an empty clock name then the output is unused 751 */ 752 if (*clk_name == '\0') 753 continue; 754 |
753 gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | 755 gate = kzalloc(sizeof(*gate), GFP_KERNEL); |
754 if (!gate) | 756 if (!gate) |
755 break; | 757 goto err; |
756 | 758 |
757 div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); | 759 div = kzalloc(sizeof(*div), GFP_KERNEL); |
758 if (!div) { 759 kfree(gate); | 760 if (!div) { 761 kfree(gate); |
760 break; | 762 goto err; |
761 } 762 | 763 } 764 |
763 mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); | 765 mux = kzalloc(sizeof(*mux), GFP_KERNEL); |
764 if (!mux) { 765 kfree(gate); 766 kfree(div); | 766 if (!mux) { 767 kfree(gate); 768 kfree(div); |
767 break; | 769 goto err; |
768 } 769 770 gate->reg = reg + VCC_GATE_OFFSET; 771 gate->bit_idx = i; 772 gate->flags = CLK_GATE_SET_TO_DISABLE; 773 gate->lock = data->lock; 774 775 div->reg = reg + VCC_DIV_OFFSET; --- 42 unchanged lines hidden (view full) --- 818 819 composite = container_of(__clk_get_hw(clk_data->clks[i]), 820 struct clk_composite, hw); 821 kfree(container_of(composite->gate_hw, struct clk_gate, hw)); 822 kfree(container_of(composite->rate_hw, struct clk_divider, hw)); 823 kfree(container_of(composite->mux_hw, struct clk_mux, hw)); 824 } 825 | 770 } 771 772 gate->reg = reg + VCC_GATE_OFFSET; 773 gate->bit_idx = i; 774 gate->flags = CLK_GATE_SET_TO_DISABLE; 775 gate->lock = data->lock; 776 777 div->reg = reg + VCC_DIV_OFFSET; --- 42 unchanged lines hidden (view full) --- 820 821 composite = container_of(__clk_get_hw(clk_data->clks[i]), 822 struct clk_composite, hw); 823 kfree(container_of(composite->gate_hw, struct clk_gate, hw)); 824 kfree(container_of(composite->rate_hw, struct clk_divider, hw)); 825 kfree(container_of(composite->mux_hw, struct clk_mux, hw)); 826 } 827 |
826 if (clk_data) 827 kfree(clk_data->clks); 828 | 828 kfree(clk_data->clks); 829err_alloc_clks: |
829 kfree(clk_data); | 830 kfree(clk_data); |
831err_alloc: |
|
830 kfree(parents); | 832 kfree(parents); |
833err_parents: 834 iounmap(reg); |
|
831} 832CLK_OF_DECLARE(clkgen_vcc, "st,clkgen-vcc", st_of_clkgen_vcc_setup); | 835} 836CLK_OF_DECLARE(clkgen_vcc, "st,clkgen-vcc", st_of_clkgen_vcc_setup); |