linux/drivers/clk/at91/dt-compat.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/clk-provider.h>
   3#include <linux/clk/at91_pmc.h>
   4#include <linux/of.h>
   5#include <linux/mfd/syscon.h>
   6#include <linux/regmap.h>
   7#include <linux/slab.h>
   8
   9#include "pmc.h"
  10
  11#define MASTER_SOURCE_MAX       4
  12
  13#define PERIPHERAL_AT91RM9200   0
  14#define PERIPHERAL_AT91SAM9X5   1
  15
  16#define PERIPHERAL_MAX          64
  17
  18#define PERIPHERAL_ID_MIN       2
  19
  20#define PROG_SOURCE_MAX         5
  21#define PROG_ID_MAX             7
  22
  23#define SYSTEM_MAX_ID           31
  24
  25#ifdef CONFIG_HAVE_AT91_AUDIO_PLL
  26static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
  27{
  28        struct clk_hw *hw;
  29        const char *name = np->name;
  30        const char *parent_name;
  31        struct regmap *regmap;
  32
  33        regmap = syscon_node_to_regmap(of_get_parent(np));
  34        if (IS_ERR(regmap))
  35                return;
  36
  37        parent_name = of_clk_get_parent_name(np, 0);
  38
  39        hw = at91_clk_register_audio_pll_frac(regmap, name, parent_name);
  40        if (IS_ERR(hw))
  41                return;
  42
  43        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
  44}
  45CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
  46               "atmel,sama5d2-clk-audio-pll-frac",
  47               of_sama5d2_clk_audio_pll_frac_setup);
  48
  49static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
  50{
  51        struct clk_hw *hw;
  52        const char *name = np->name;
  53        const char *parent_name;
  54        struct regmap *regmap;
  55
  56        regmap = syscon_node_to_regmap(of_get_parent(np));
  57        if (IS_ERR(regmap))
  58                return;
  59
  60        parent_name = of_clk_get_parent_name(np, 0);
  61
  62        hw = at91_clk_register_audio_pll_pad(regmap, name, parent_name);
  63        if (IS_ERR(hw))
  64                return;
  65
  66        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
  67}
  68CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
  69               "atmel,sama5d2-clk-audio-pll-pad",
  70               of_sama5d2_clk_audio_pll_pad_setup);
  71
  72static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
  73{
  74        struct clk_hw *hw;
  75        const char *name = np->name;
  76        const char *parent_name;
  77        struct regmap *regmap;
  78
  79        regmap = syscon_node_to_regmap(of_get_parent(np));
  80        if (IS_ERR(regmap))
  81                return;
  82
  83        parent_name = of_clk_get_parent_name(np, 0);
  84
  85        hw = at91_clk_register_audio_pll_pmc(regmap, name, parent_name);
  86        if (IS_ERR(hw))
  87                return;
  88
  89        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
  90}
  91CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
  92               "atmel,sama5d2-clk-audio-pll-pmc",
  93               of_sama5d2_clk_audio_pll_pmc_setup);
  94#endif /* CONFIG_HAVE_AT91_AUDIO_PLL */
  95
  96static const struct clk_pcr_layout dt_pcr_layout = {
  97        .offset = 0x10c,
  98        .cmd = BIT(12),
  99        .pid_mask = GENMASK(5, 0),
 100        .div_mask = GENMASK(17, 16),
 101        .gckcss_mask = GENMASK(10, 8),
 102};
 103
 104#ifdef CONFIG_HAVE_AT91_GENERATED_CLK
 105#define GENERATED_SOURCE_MAX    6
 106
 107#define GCK_ID_I2S0             54
 108#define GCK_ID_I2S1             55
 109#define GCK_ID_CLASSD           59
 110
 111static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
 112{
 113        int num;
 114        u32 id;
 115        const char *name;
 116        struct clk_hw *hw;
 117        unsigned int num_parents;
 118        const char *parent_names[GENERATED_SOURCE_MAX];
 119        struct device_node *gcknp;
 120        struct clk_range range = CLK_RANGE(0, 0);
 121        struct regmap *regmap;
 122
 123        num_parents = of_clk_get_parent_count(np);
 124        if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
 125                return;
 126
 127        of_clk_parent_fill(np, parent_names, num_parents);
 128
 129        num = of_get_child_count(np);
 130        if (!num || num > PERIPHERAL_MAX)
 131                return;
 132
 133        regmap = syscon_node_to_regmap(of_get_parent(np));
 134        if (IS_ERR(regmap))
 135                return;
 136
 137        for_each_child_of_node(np, gcknp) {
 138                bool pll_audio = false;
 139
 140                if (of_property_read_u32(gcknp, "reg", &id))
 141                        continue;
 142
 143                if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
 144                        continue;
 145
 146                if (of_property_read_string(np, "clock-output-names", &name))
 147                        name = gcknp->name;
 148
 149                of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
 150                                      &range);
 151
 152                if (of_device_is_compatible(np, "atmel,sama5d2-clk-generated") &&
 153                    (id == GCK_ID_I2S0 || id == GCK_ID_I2S1 ||
 154                     id == GCK_ID_CLASSD))
 155                        pll_audio = true;
 156
 157                hw = at91_clk_register_generated(regmap, &pmc_pcr_lock,
 158                                                 &dt_pcr_layout, name,
 159                                                 parent_names, num_parents,
 160                                                 id, pll_audio, &range);
 161                if (IS_ERR(hw))
 162                        continue;
 163
 164                of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
 165        }
 166}
 167CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
 168               of_sama5d2_clk_generated_setup);
 169#endif /* CONFIG_HAVE_AT91_GENERATED_CLK */
 170
 171#ifdef CONFIG_HAVE_AT91_H32MX
 172static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
 173{
 174        struct clk_hw *hw;
 175        const char *name = np->name;
 176        const char *parent_name;
 177        struct regmap *regmap;
 178
 179        regmap = syscon_node_to_regmap(of_get_parent(np));
 180        if (IS_ERR(regmap))
 181                return;
 182
 183        parent_name = of_clk_get_parent_name(np, 0);
 184
 185        hw = at91_clk_register_h32mx(regmap, name, parent_name);
 186        if (IS_ERR(hw))
 187                return;
 188
 189        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 190}
 191CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
 192               of_sama5d4_clk_h32mx_setup);
 193#endif /* CONFIG_HAVE_AT91_H32MX */
 194
 195#ifdef CONFIG_HAVE_AT91_I2S_MUX_CLK
 196#define I2S_BUS_NR      2
 197
 198static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
 199{
 200        struct regmap *regmap_sfr;
 201        u8 bus_id;
 202        const char *parent_names[2];
 203        struct device_node *i2s_mux_np;
 204        struct clk_hw *hw;
 205        int ret;
 206
 207        regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
 208        if (IS_ERR(regmap_sfr))
 209                return;
 210
 211        for_each_child_of_node(np, i2s_mux_np) {
 212                if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
 213                        continue;
 214
 215                if (bus_id > I2S_BUS_NR)
 216                        continue;
 217
 218                ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
 219                if (ret != 2)
 220                        continue;
 221
 222                hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
 223                                               parent_names, 2, bus_id);
 224                if (IS_ERR(hw))
 225                        continue;
 226
 227                of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
 228        }
 229}
 230CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
 231               of_sama5d2_clk_i2s_mux_setup);
 232#endif /* CONFIG_HAVE_AT91_I2S_MUX_CLK */
 233
 234static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
 235{
 236        struct clk_hw *hw;
 237        const char *name = np->name;
 238        const char *parent_name;
 239        struct regmap *regmap;
 240        bool bypass;
 241
 242        of_property_read_string(np, "clock-output-names", &name);
 243        bypass = of_property_read_bool(np, "atmel,osc-bypass");
 244        parent_name = of_clk_get_parent_name(np, 0);
 245
 246        regmap = syscon_node_to_regmap(of_get_parent(np));
 247        if (IS_ERR(regmap))
 248                return;
 249
 250        hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
 251        if (IS_ERR(hw))
 252                return;
 253
 254        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 255}
 256CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
 257               of_at91rm9200_clk_main_osc_setup);
 258
 259static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
 260{
 261        struct clk_hw *hw;
 262        u32 frequency = 0;
 263        u32 accuracy = 0;
 264        const char *name = np->name;
 265        struct regmap *regmap;
 266
 267        of_property_read_string(np, "clock-output-names", &name);
 268        of_property_read_u32(np, "clock-frequency", &frequency);
 269        of_property_read_u32(np, "clock-accuracy", &accuracy);
 270
 271        regmap = syscon_node_to_regmap(of_get_parent(np));
 272        if (IS_ERR(regmap))
 273                return;
 274
 275        hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
 276        if (IS_ERR(hw))
 277                return;
 278
 279        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 280}
 281CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
 282               of_at91sam9x5_clk_main_rc_osc_setup);
 283
 284static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
 285{
 286        struct clk_hw *hw;
 287        const char *parent_name;
 288        const char *name = np->name;
 289        struct regmap *regmap;
 290
 291        parent_name = of_clk_get_parent_name(np, 0);
 292        of_property_read_string(np, "clock-output-names", &name);
 293
 294        regmap = syscon_node_to_regmap(of_get_parent(np));
 295        if (IS_ERR(regmap))
 296                return;
 297
 298        hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
 299        if (IS_ERR(hw))
 300                return;
 301
 302        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 303}
 304CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
 305               of_at91rm9200_clk_main_setup);
 306
 307static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
 308{
 309        struct clk_hw *hw;
 310        const char *parent_names[2];
 311        unsigned int num_parents;
 312        const char *name = np->name;
 313        struct regmap *regmap;
 314
 315        num_parents = of_clk_get_parent_count(np);
 316        if (num_parents == 0 || num_parents > 2)
 317                return;
 318
 319        of_clk_parent_fill(np, parent_names, num_parents);
 320        regmap = syscon_node_to_regmap(of_get_parent(np));
 321        if (IS_ERR(regmap))
 322                return;
 323
 324        of_property_read_string(np, "clock-output-names", &name);
 325
 326        hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
 327                                           num_parents);
 328        if (IS_ERR(hw))
 329                return;
 330
 331        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 332}
 333CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
 334               of_at91sam9x5_clk_main_setup);
 335
 336static struct clk_master_characteristics * __init
 337of_at91_clk_master_get_characteristics(struct device_node *np)
 338{
 339        struct clk_master_characteristics *characteristics;
 340
 341        characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
 342        if (!characteristics)
 343                return NULL;
 344
 345        if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
 346                goto out_free_characteristics;
 347
 348        of_property_read_u32_array(np, "atmel,clk-divisors",
 349                                   characteristics->divisors, 4);
 350
 351        characteristics->have_div3_pres =
 352                of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
 353
 354        return characteristics;
 355
 356out_free_characteristics:
 357        kfree(characteristics);
 358        return NULL;
 359}
 360
 361static void __init
 362of_at91_clk_master_setup(struct device_node *np,
 363                         const struct clk_master_layout *layout)
 364{
 365        struct clk_hw *hw;
 366        unsigned int num_parents;
 367        const char *parent_names[MASTER_SOURCE_MAX];
 368        const char *name = np->name;
 369        struct clk_master_characteristics *characteristics;
 370        struct regmap *regmap;
 371
 372        num_parents = of_clk_get_parent_count(np);
 373        if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
 374                return;
 375
 376        of_clk_parent_fill(np, parent_names, num_parents);
 377
 378        of_property_read_string(np, "clock-output-names", &name);
 379
 380        characteristics = of_at91_clk_master_get_characteristics(np);
 381        if (!characteristics)
 382                return;
 383
 384        regmap = syscon_node_to_regmap(of_get_parent(np));
 385        if (IS_ERR(regmap))
 386                return;
 387
 388        hw = at91_clk_register_master(regmap, name, num_parents,
 389                                      parent_names, layout,
 390                                      characteristics);
 391        if (IS_ERR(hw))
 392                goto out_free_characteristics;
 393
 394        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 395        return;
 396
 397out_free_characteristics:
 398        kfree(characteristics);
 399}
 400
 401static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
 402{
 403        of_at91_clk_master_setup(np, &at91rm9200_master_layout);
 404}
 405CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
 406               of_at91rm9200_clk_master_setup);
 407
 408static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
 409{
 410        of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
 411}
 412CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
 413               of_at91sam9x5_clk_master_setup);
 414
 415static void __init
 416of_at91_clk_periph_setup(struct device_node *np, u8 type)
 417{
 418        int num;
 419        u32 id;
 420        struct clk_hw *hw;
 421        const char *parent_name;
 422        const char *name;
 423        struct device_node *periphclknp;
 424        struct regmap *regmap;
 425
 426        parent_name = of_clk_get_parent_name(np, 0);
 427        if (!parent_name)
 428                return;
 429
 430        num = of_get_child_count(np);
 431        if (!num || num > PERIPHERAL_MAX)
 432                return;
 433
 434        regmap = syscon_node_to_regmap(of_get_parent(np));
 435        if (IS_ERR(regmap))
 436                return;
 437
 438        for_each_child_of_node(np, periphclknp) {
 439                if (of_property_read_u32(periphclknp, "reg", &id))
 440                        continue;
 441
 442                if (id >= PERIPHERAL_MAX)
 443                        continue;
 444
 445                if (of_property_read_string(np, "clock-output-names", &name))
 446                        name = periphclknp->name;
 447
 448                if (type == PERIPHERAL_AT91RM9200) {
 449                        hw = at91_clk_register_peripheral(regmap, name,
 450                                                          parent_name, id);
 451                } else {
 452                        struct clk_range range = CLK_RANGE(0, 0);
 453
 454                        of_at91_get_clk_range(periphclknp,
 455                                              "atmel,clk-output-range",
 456                                              &range);
 457
 458                        hw = at91_clk_register_sam9x5_peripheral(regmap,
 459                                                                 &pmc_pcr_lock,
 460                                                                 &dt_pcr_layout,
 461                                                                 name,
 462                                                                 parent_name,
 463                                                                 id, &range);
 464                }
 465
 466                if (IS_ERR(hw))
 467                        continue;
 468
 469                of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
 470        }
 471}
 472
 473static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
 474{
 475        of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
 476}
 477CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
 478               of_at91rm9200_clk_periph_setup);
 479
 480static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
 481{
 482        of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
 483}
 484CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
 485               of_at91sam9x5_clk_periph_setup);
 486
 487static struct clk_pll_characteristics * __init
 488of_at91_clk_pll_get_characteristics(struct device_node *np)
 489{
 490        int i;
 491        int offset;
 492        u32 tmp;
 493        int num_output;
 494        u32 num_cells;
 495        struct clk_range input;
 496        struct clk_range *output;
 497        u8 *out = NULL;
 498        u16 *icpll = NULL;
 499        struct clk_pll_characteristics *characteristics;
 500
 501        if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
 502                return NULL;
 503
 504        if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
 505                                 &num_cells))
 506                return NULL;
 507
 508        if (num_cells < 2 || num_cells > 4)
 509                return NULL;
 510
 511        if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
 512                return NULL;
 513        num_output = tmp / (sizeof(u32) * num_cells);
 514
 515        characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
 516        if (!characteristics)
 517                return NULL;
 518
 519        output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
 520        if (!output)
 521                goto out_free_characteristics;
 522
 523        if (num_cells > 2) {
 524                out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
 525                if (!out)
 526                        goto out_free_output;
 527        }
 528
 529        if (num_cells > 3) {
 530                icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
 531                if (!icpll)
 532                        goto out_free_output;
 533        }
 534
 535        for (i = 0; i < num_output; i++) {
 536                offset = i * num_cells;
 537                if (of_property_read_u32_index(np,
 538                                               "atmel,pll-clk-output-ranges",
 539                                               offset, &tmp))
 540                        goto out_free_output;
 541                output[i].min = tmp;
 542                if (of_property_read_u32_index(np,
 543                                               "atmel,pll-clk-output-ranges",
 544                                               offset + 1, &tmp))
 545                        goto out_free_output;
 546                output[i].max = tmp;
 547
 548                if (num_cells == 2)
 549                        continue;
 550
 551                if (of_property_read_u32_index(np,
 552                                               "atmel,pll-clk-output-ranges",
 553                                               offset + 2, &tmp))
 554                        goto out_free_output;
 555                out[i] = tmp;
 556
 557                if (num_cells == 3)
 558                        continue;
 559
 560                if (of_property_read_u32_index(np,
 561                                               "atmel,pll-clk-output-ranges",
 562                                               offset + 3, &tmp))
 563                        goto out_free_output;
 564                icpll[i] = tmp;
 565        }
 566
 567        characteristics->input = input;
 568        characteristics->num_output = num_output;
 569        characteristics->output = output;
 570        characteristics->out = out;
 571        characteristics->icpll = icpll;
 572        return characteristics;
 573
 574out_free_output:
 575        kfree(icpll);
 576        kfree(out);
 577        kfree(output);
 578out_free_characteristics:
 579        kfree(characteristics);
 580        return NULL;
 581}
 582
 583static void __init
 584of_at91_clk_pll_setup(struct device_node *np,
 585                      const struct clk_pll_layout *layout)
 586{
 587        u32 id;
 588        struct clk_hw *hw;
 589        struct regmap *regmap;
 590        const char *parent_name;
 591        const char *name = np->name;
 592        struct clk_pll_characteristics *characteristics;
 593
 594        if (of_property_read_u32(np, "reg", &id))
 595                return;
 596
 597        parent_name = of_clk_get_parent_name(np, 0);
 598
 599        of_property_read_string(np, "clock-output-names", &name);
 600
 601        regmap = syscon_node_to_regmap(of_get_parent(np));
 602        if (IS_ERR(regmap))
 603                return;
 604
 605        characteristics = of_at91_clk_pll_get_characteristics(np);
 606        if (!characteristics)
 607                return;
 608
 609        hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
 610                                   characteristics);
 611        if (IS_ERR(hw))
 612                goto out_free_characteristics;
 613
 614        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 615        return;
 616
 617out_free_characteristics:
 618        kfree(characteristics);
 619}
 620
 621static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
 622{
 623        of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
 624}
 625CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
 626               of_at91rm9200_clk_pll_setup);
 627
 628static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
 629{
 630        of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
 631}
 632CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
 633               of_at91sam9g45_clk_pll_setup);
 634
 635static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
 636{
 637        of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
 638}
 639CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
 640               of_at91sam9g20_clk_pllb_setup);
 641
 642static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
 643{
 644        of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
 645}
 646CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
 647               of_sama5d3_clk_pll_setup);
 648
 649static void __init
 650of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
 651{
 652        struct clk_hw *hw;
 653        const char *parent_name;
 654        const char *name = np->name;
 655        struct regmap *regmap;
 656
 657        parent_name = of_clk_get_parent_name(np, 0);
 658
 659        of_property_read_string(np, "clock-output-names", &name);
 660
 661        regmap = syscon_node_to_regmap(of_get_parent(np));
 662        if (IS_ERR(regmap))
 663                return;
 664
 665        hw = at91_clk_register_plldiv(regmap, name, parent_name);
 666        if (IS_ERR(hw))
 667                return;
 668
 669        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 670}
 671CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
 672               of_at91sam9x5_clk_plldiv_setup);
 673
 674static void __init
 675of_at91_clk_prog_setup(struct device_node *np,
 676                       const struct clk_programmable_layout *layout)
 677{
 678        int num;
 679        u32 id;
 680        struct clk_hw *hw;
 681        unsigned int num_parents;
 682        const char *parent_names[PROG_SOURCE_MAX];
 683        const char *name;
 684        struct device_node *progclknp;
 685        struct regmap *regmap;
 686
 687        num_parents = of_clk_get_parent_count(np);
 688        if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
 689                return;
 690
 691        of_clk_parent_fill(np, parent_names, num_parents);
 692
 693        num = of_get_child_count(np);
 694        if (!num || num > (PROG_ID_MAX + 1))
 695                return;
 696
 697        regmap = syscon_node_to_regmap(of_get_parent(np));
 698        if (IS_ERR(regmap))
 699                return;
 700
 701        for_each_child_of_node(np, progclknp) {
 702                if (of_property_read_u32(progclknp, "reg", &id))
 703                        continue;
 704
 705                if (of_property_read_string(np, "clock-output-names", &name))
 706                        name = progclknp->name;
 707
 708                hw = at91_clk_register_programmable(regmap, name,
 709                                                    parent_names, num_parents,
 710                                                    id, layout);
 711                if (IS_ERR(hw))
 712                        continue;
 713
 714                of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
 715        }
 716}
 717
 718static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
 719{
 720        of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
 721}
 722CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
 723               of_at91rm9200_clk_prog_setup);
 724
 725static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
 726{
 727        of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
 728}
 729CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
 730               of_at91sam9g45_clk_prog_setup);
 731
 732static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
 733{
 734        of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
 735}
 736CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
 737               of_at91sam9x5_clk_prog_setup);
 738
 739static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
 740{
 741        struct clk_hw *hw;
 742        const char *parent_names[2];
 743        unsigned int num_parents;
 744        const char *name = np->name;
 745        struct regmap *regmap;
 746
 747        num_parents = of_clk_get_parent_count(np);
 748        if (num_parents != 2)
 749                return;
 750
 751        of_clk_parent_fill(np, parent_names, num_parents);
 752        regmap = syscon_node_to_regmap(of_get_parent(np));
 753        if (IS_ERR(regmap))
 754                return;
 755
 756        of_property_read_string(np, "clock-output-names", &name);
 757
 758        hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
 759                                            num_parents);
 760        if (IS_ERR(hw))
 761                return;
 762
 763        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 764}
 765CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
 766               of_at91sam9260_clk_slow_setup);
 767
 768#ifdef CONFIG_HAVE_AT91_SMD
 769#define SMD_SOURCE_MAX          2
 770
 771static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
 772{
 773        struct clk_hw *hw;
 774        unsigned int num_parents;
 775        const char *parent_names[SMD_SOURCE_MAX];
 776        const char *name = np->name;
 777        struct regmap *regmap;
 778
 779        num_parents = of_clk_get_parent_count(np);
 780        if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
 781                return;
 782
 783        of_clk_parent_fill(np, parent_names, num_parents);
 784
 785        of_property_read_string(np, "clock-output-names", &name);
 786
 787        regmap = syscon_node_to_regmap(of_get_parent(np));
 788        if (IS_ERR(regmap))
 789                return;
 790
 791        hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
 792                                         num_parents);
 793        if (IS_ERR(hw))
 794                return;
 795
 796        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 797}
 798CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
 799               of_at91sam9x5_clk_smd_setup);
 800#endif /* CONFIG_HAVE_AT91_SMD */
 801
 802static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
 803{
 804        int num;
 805        u32 id;
 806        struct clk_hw *hw;
 807        const char *name;
 808        struct device_node *sysclknp;
 809        const char *parent_name;
 810        struct regmap *regmap;
 811
 812        num = of_get_child_count(np);
 813        if (num > (SYSTEM_MAX_ID + 1))
 814                return;
 815
 816        regmap = syscon_node_to_regmap(of_get_parent(np));
 817        if (IS_ERR(regmap))
 818                return;
 819
 820        for_each_child_of_node(np, sysclknp) {
 821                if (of_property_read_u32(sysclknp, "reg", &id))
 822                        continue;
 823
 824                if (of_property_read_string(np, "clock-output-names", &name))
 825                        name = sysclknp->name;
 826
 827                parent_name = of_clk_get_parent_name(sysclknp, 0);
 828
 829                hw = at91_clk_register_system(regmap, name, parent_name, id);
 830                if (IS_ERR(hw))
 831                        continue;
 832
 833                of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
 834        }
 835}
 836CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
 837               of_at91rm9200_clk_sys_setup);
 838
 839#ifdef CONFIG_HAVE_AT91_USB_CLK
 840#define USB_SOURCE_MAX          2
 841
 842static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
 843{
 844        struct clk_hw *hw;
 845        unsigned int num_parents;
 846        const char *parent_names[USB_SOURCE_MAX];
 847        const char *name = np->name;
 848        struct regmap *regmap;
 849
 850        num_parents = of_clk_get_parent_count(np);
 851        if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
 852                return;
 853
 854        of_clk_parent_fill(np, parent_names, num_parents);
 855
 856        of_property_read_string(np, "clock-output-names", &name);
 857
 858        regmap = syscon_node_to_regmap(of_get_parent(np));
 859        if (IS_ERR(regmap))
 860                return;
 861
 862        hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
 863                                         num_parents);
 864        if (IS_ERR(hw))
 865                return;
 866
 867        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 868}
 869CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
 870               of_at91sam9x5_clk_usb_setup);
 871
 872static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
 873{
 874        struct clk_hw *hw;
 875        const char *parent_name;
 876        const char *name = np->name;
 877        struct regmap *regmap;
 878
 879        parent_name = of_clk_get_parent_name(np, 0);
 880        if (!parent_name)
 881                return;
 882
 883        of_property_read_string(np, "clock-output-names", &name);
 884
 885        regmap = syscon_node_to_regmap(of_get_parent(np));
 886        if (IS_ERR(regmap))
 887                return;
 888
 889        hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
 890        if (IS_ERR(hw))
 891                return;
 892
 893        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 894}
 895CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
 896               of_at91sam9n12_clk_usb_setup);
 897
 898static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
 899{
 900        struct clk_hw *hw;
 901        const char *parent_name;
 902        const char *name = np->name;
 903        u32 divisors[4] = {0, 0, 0, 0};
 904        struct regmap *regmap;
 905
 906        parent_name = of_clk_get_parent_name(np, 0);
 907        if (!parent_name)
 908                return;
 909
 910        of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
 911        if (!divisors[0])
 912                return;
 913
 914        of_property_read_string(np, "clock-output-names", &name);
 915
 916        regmap = syscon_node_to_regmap(of_get_parent(np));
 917        if (IS_ERR(regmap))
 918                return;
 919        hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
 920        if (IS_ERR(hw))
 921                return;
 922
 923        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 924}
 925CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
 926               of_at91rm9200_clk_usb_setup);
 927#endif /* CONFIG_HAVE_AT91_USB_CLK */
 928
 929#ifdef CONFIG_HAVE_AT91_UTMI
 930static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
 931{
 932        struct clk_hw *hw;
 933        const char *parent_name;
 934        const char *name = np->name;
 935        struct regmap *regmap_pmc, *regmap_sfr;
 936
 937        parent_name = of_clk_get_parent_name(np, 0);
 938
 939        of_property_read_string(np, "clock-output-names", &name);
 940
 941        regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
 942        if (IS_ERR(regmap_pmc))
 943                return;
 944
 945        /*
 946         * If the device supports different mainck rates, this value has to be
 947         * set in the UTMI Clock Trimming register.
 948         * - 9x5: mainck supports several rates but it is indicated that a
 949         *   12 MHz is needed in case of USB.
 950         * - sama5d3 and sama5d2: mainck supports several rates. Configuring
 951         *   the FREQ field of the UTMI Clock Trimming register is mandatory.
 952         * - sama5d4: mainck is at 12 MHz.
 953         *
 954         * We only need to retrieve sama5d3 or sama5d2 sfr regmap.
 955         */
 956        regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
 957        if (IS_ERR(regmap_sfr)) {
 958                regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
 959                if (IS_ERR(regmap_sfr))
 960                        regmap_sfr = NULL;
 961        }
 962
 963        hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
 964        if (IS_ERR(hw))
 965                return;
 966
 967        of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
 968}
 969CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
 970               of_at91sam9x5_clk_utmi_setup);
 971#endif /* CONFIG_HAVE_AT91_UTMI */
 972