root/drivers/clk/uniphier/clk-uniphier-core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. uniphier_clk_register
  2. uniphier_clk_probe
  3. uniphier_clk_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2016 Socionext Inc.
   4  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
   5  */
   6 
   7 #include <linux/clk-provider.h>
   8 #include <linux/init.h>
   9 #include <linux/mfd/syscon.h>
  10 #include <linux/of.h>
  11 #include <linux/of_device.h>
  12 #include <linux/platform_device.h>
  13 
  14 #include "clk-uniphier.h"
  15 
  16 static struct clk_hw *uniphier_clk_register(struct device *dev,
  17                                             struct regmap *regmap,
  18                                         const struct uniphier_clk_data *data)
  19 {
  20         switch (data->type) {
  21         case UNIPHIER_CLK_TYPE_CPUGEAR:
  22                 return uniphier_clk_register_cpugear(dev, regmap, data->name,
  23                                                      &data->data.cpugear);
  24         case UNIPHIER_CLK_TYPE_FIXED_FACTOR:
  25                 return uniphier_clk_register_fixed_factor(dev, data->name,
  26                                                           &data->data.factor);
  27         case UNIPHIER_CLK_TYPE_FIXED_RATE:
  28                 return uniphier_clk_register_fixed_rate(dev, data->name,
  29                                                         &data->data.rate);
  30         case UNIPHIER_CLK_TYPE_GATE:
  31                 return uniphier_clk_register_gate(dev, regmap, data->name,
  32                                                   &data->data.gate);
  33         case UNIPHIER_CLK_TYPE_MUX:
  34                 return uniphier_clk_register_mux(dev, regmap, data->name,
  35                                                  &data->data.mux);
  36         default:
  37                 dev_err(dev, "unsupported clock type\n");
  38                 return ERR_PTR(-EINVAL);
  39         }
  40 }
  41 
  42 static int uniphier_clk_probe(struct platform_device *pdev)
  43 {
  44         struct device *dev = &pdev->dev;
  45         struct clk_hw_onecell_data *hw_data;
  46         const struct uniphier_clk_data *p, *data;
  47         struct regmap *regmap;
  48         struct device_node *parent;
  49         int clk_num = 0;
  50 
  51         data = of_device_get_match_data(dev);
  52         if (WARN_ON(!data))
  53                 return -EINVAL;
  54 
  55         parent = of_get_parent(dev->of_node); /* parent should be syscon node */
  56         regmap = syscon_node_to_regmap(parent);
  57         of_node_put(parent);
  58         if (IS_ERR(regmap)) {
  59                 dev_err(dev, "failed to get regmap (error %ld)\n",
  60                         PTR_ERR(regmap));
  61                 return PTR_ERR(regmap);
  62         }
  63 
  64         for (p = data; p->name; p++)
  65                 clk_num = max(clk_num, p->idx + 1);
  66 
  67         hw_data = devm_kzalloc(dev,
  68                         sizeof(*hw_data) + clk_num * sizeof(struct clk_hw *),
  69                         GFP_KERNEL);
  70         if (!hw_data)
  71                 return -ENOMEM;
  72 
  73         hw_data->num = clk_num;
  74 
  75         /* avoid returning NULL for unused idx */
  76         while (--clk_num >= 0)
  77                 hw_data->hws[clk_num] = ERR_PTR(-EINVAL);
  78 
  79         for (p = data; p->name; p++) {
  80                 struct clk_hw *hw;
  81 
  82                 dev_dbg(dev, "register %s (index=%d)\n", p->name, p->idx);
  83                 hw = uniphier_clk_register(dev, regmap, p);
  84                 if (WARN(IS_ERR(hw), "failed to register %s", p->name))
  85                         continue;
  86 
  87                 if (p->idx >= 0)
  88                         hw_data->hws[p->idx] = hw;
  89         }
  90 
  91         return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
  92                                       hw_data);
  93 }
  94 
  95 static int uniphier_clk_remove(struct platform_device *pdev)
  96 {
  97         of_clk_del_provider(pdev->dev.of_node);
  98 
  99         return 0;
 100 }
 101 
 102 static const struct of_device_id uniphier_clk_match[] = {
 103         /* System clock */
 104         {
 105                 .compatible = "socionext,uniphier-ld4-clock",
 106                 .data = uniphier_ld4_sys_clk_data,
 107         },
 108         {
 109                 .compatible = "socionext,uniphier-pro4-clock",
 110                 .data = uniphier_pro4_sys_clk_data,
 111         },
 112         {
 113                 .compatible = "socionext,uniphier-sld8-clock",
 114                 .data = uniphier_sld8_sys_clk_data,
 115         },
 116         {
 117                 .compatible = "socionext,uniphier-pro5-clock",
 118                 .data = uniphier_pro5_sys_clk_data,
 119         },
 120         {
 121                 .compatible = "socionext,uniphier-pxs2-clock",
 122                 .data = uniphier_pxs2_sys_clk_data,
 123         },
 124         {
 125                 .compatible = "socionext,uniphier-ld11-clock",
 126                 .data = uniphier_ld11_sys_clk_data,
 127         },
 128         {
 129                 .compatible = "socionext,uniphier-ld20-clock",
 130                 .data = uniphier_ld20_sys_clk_data,
 131         },
 132         {
 133                 .compatible = "socionext,uniphier-pxs3-clock",
 134                 .data = uniphier_pxs3_sys_clk_data,
 135         },
 136         /* Media I/O clock, SD clock */
 137         {
 138                 .compatible = "socionext,uniphier-ld4-mio-clock",
 139                 .data = uniphier_ld4_mio_clk_data,
 140         },
 141         {
 142                 .compatible = "socionext,uniphier-pro4-mio-clock",
 143                 .data = uniphier_ld4_mio_clk_data,
 144         },
 145         {
 146                 .compatible = "socionext,uniphier-sld8-mio-clock",
 147                 .data = uniphier_ld4_mio_clk_data,
 148         },
 149         {
 150                 .compatible = "socionext,uniphier-pro5-sd-clock",
 151                 .data = uniphier_pro5_sd_clk_data,
 152         },
 153         {
 154                 .compatible = "socionext,uniphier-pxs2-sd-clock",
 155                 .data = uniphier_pro5_sd_clk_data,
 156         },
 157         {
 158                 .compatible = "socionext,uniphier-ld11-mio-clock",
 159                 .data = uniphier_ld4_mio_clk_data,
 160         },
 161         {
 162                 .compatible = "socionext,uniphier-ld20-sd-clock",
 163                 .data = uniphier_pro5_sd_clk_data,
 164         },
 165         {
 166                 .compatible = "socionext,uniphier-pxs3-sd-clock",
 167                 .data = uniphier_pro5_sd_clk_data,
 168         },
 169         /* Peripheral clock */
 170         {
 171                 .compatible = "socionext,uniphier-ld4-peri-clock",
 172                 .data = uniphier_ld4_peri_clk_data,
 173         },
 174         {
 175                 .compatible = "socionext,uniphier-pro4-peri-clock",
 176                 .data = uniphier_pro4_peri_clk_data,
 177         },
 178         {
 179                 .compatible = "socionext,uniphier-sld8-peri-clock",
 180                 .data = uniphier_ld4_peri_clk_data,
 181         },
 182         {
 183                 .compatible = "socionext,uniphier-pro5-peri-clock",
 184                 .data = uniphier_pro4_peri_clk_data,
 185         },
 186         {
 187                 .compatible = "socionext,uniphier-pxs2-peri-clock",
 188                 .data = uniphier_pro4_peri_clk_data,
 189         },
 190         {
 191                 .compatible = "socionext,uniphier-ld11-peri-clock",
 192                 .data = uniphier_pro4_peri_clk_data,
 193         },
 194         {
 195                 .compatible = "socionext,uniphier-ld20-peri-clock",
 196                 .data = uniphier_pro4_peri_clk_data,
 197         },
 198         {
 199                 .compatible = "socionext,uniphier-pxs3-peri-clock",
 200                 .data = uniphier_pro4_peri_clk_data,
 201         },
 202         { /* sentinel */ }
 203 };
 204 
 205 static struct platform_driver uniphier_clk_driver = {
 206         .probe = uniphier_clk_probe,
 207         .remove = uniphier_clk_remove,
 208         .driver = {
 209                 .name = "uniphier-clk",
 210                 .of_match_table = uniphier_clk_match,
 211         },
 212 };
 213 builtin_platform_driver(uniphier_clk_driver);

/* [<][>][^][v][top][bottom][index][help] */