linux/drivers/clk/clkdev.c
<<
>>
Prefs
   1/*
   2 * drivers/clk/clkdev.c
   3 *
   4 *  Copyright (C) 2008 Russell King.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 as
   8 * published by the Free Software Foundation.
   9 *
  10 * Helper for the clk API to assist looking up a struct clk.
  11 */
  12#include <linux/module.h>
  13#include <linux/kernel.h>
  14#include <linux/device.h>
  15#include <linux/list.h>
  16#include <linux/errno.h>
  17#include <linux/err.h>
  18#include <linux/string.h>
  19#include <linux/mutex.h>
  20#include <linux/clk.h>
  21#include <linux/clkdev.h>
  22#include <linux/clk-provider.h>
  23#include <linux/of.h>
  24
  25#include "clk.h"
  26
  27static LIST_HEAD(clocks);
  28static DEFINE_MUTEX(clocks_mutex);
  29
  30#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
  31static struct clk *__of_clk_get(struct device_node *np, int index,
  32                               const char *dev_id, const char *con_id)
  33{
  34        struct of_phandle_args clkspec;
  35        struct clk *clk;
  36        int rc;
  37
  38        if (index < 0)
  39                return ERR_PTR(-EINVAL);
  40
  41        rc = of_parse_phandle_with_args(np, "clocks", "#clock-cells", index,
  42                                        &clkspec);
  43        if (rc)
  44                return ERR_PTR(rc);
  45
  46        clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id);
  47        of_node_put(clkspec.np);
  48
  49        return clk;
  50}
  51
  52struct clk *of_clk_get(struct device_node *np, int index)
  53{
  54        return __of_clk_get(np, index, np->full_name, NULL);
  55}
  56EXPORT_SYMBOL(of_clk_get);
  57
  58static struct clk *__of_clk_get_by_name(struct device_node *np,
  59                                        const char *dev_id,
  60                                        const char *name)
  61{
  62        struct clk *clk = ERR_PTR(-ENOENT);
  63
  64        /* Walk up the tree of devices looking for a clock that matches */
  65        while (np) {
  66                int index = 0;
  67
  68                /*
  69                 * For named clocks, first look up the name in the
  70                 * "clock-names" property.  If it cannot be found, then
  71                 * index will be an error code, and of_clk_get() will fail.
  72                 */
  73                if (name)
  74                        index = of_property_match_string(np, "clock-names", name);
  75                clk = __of_clk_get(np, index, dev_id, name);
  76                if (!IS_ERR(clk)) {
  77                        break;
  78                } else if (name && index >= 0) {
  79                        if (PTR_ERR(clk) != -EPROBE_DEFER)
  80                                pr_err("ERROR: could not get clock %s:%s(%i)\n",
  81                                        np->full_name, name ? name : "", index);
  82                        return clk;
  83                }
  84
  85                /*
  86                 * No matching clock found on this node.  If the parent node
  87                 * has a "clock-ranges" property, then we can try one of its
  88                 * clocks.
  89                 */
  90                np = np->parent;
  91                if (np && !of_get_property(np, "clock-ranges", NULL))
  92                        break;
  93        }
  94
  95        return clk;
  96}
  97
  98/**
  99 * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
 100 * @np: pointer to clock consumer node
 101 * @name: name of consumer's clock input, or NULL for the first clock reference
 102 *
 103 * This function parses the clocks and clock-names properties,
 104 * and uses them to look up the struct clk from the registered list of clock
 105 * providers.
 106 */
 107struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
 108{
 109        if (!np)
 110                return ERR_PTR(-ENOENT);
 111
 112        return __of_clk_get_by_name(np, np->full_name, name);
 113}
 114EXPORT_SYMBOL(of_clk_get_by_name);
 115
 116#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
 117
 118static struct clk *__of_clk_get_by_name(struct device_node *np,
 119                                        const char *dev_id,
 120                                        const char *name)
 121{
 122        return ERR_PTR(-ENOENT);
 123}
 124#endif
 125
 126/*
 127 * Find the correct struct clk for the device and connection ID.
 128 * We do slightly fuzzy matching here:
 129 *  An entry with a NULL ID is assumed to be a wildcard.
 130 *  If an entry has a device ID, it must match
 131 *  If an entry has a connection ID, it must match
 132 * Then we take the most specific entry - with the following
 133 * order of precedence: dev+con > dev only > con only.
 134 */
 135static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
 136{
 137        struct clk_lookup *p, *cl = NULL;
 138        int match, best_found = 0, best_possible = 0;
 139
 140        if (dev_id)
 141                best_possible += 2;
 142        if (con_id)
 143                best_possible += 1;
 144
 145        list_for_each_entry(p, &clocks, node) {
 146                match = 0;
 147                if (p->dev_id) {
 148                        if (!dev_id || strcmp(p->dev_id, dev_id))
 149                                continue;
 150                        match += 2;
 151                }
 152                if (p->con_id) {
 153                        if (!con_id || strcmp(p->con_id, con_id))
 154                                continue;
 155                        match += 1;
 156                }
 157
 158                if (match > best_found) {
 159                        cl = p;
 160                        if (match != best_possible)
 161                                best_found = match;
 162                        else
 163                                break;
 164                }
 165        }
 166        return cl;
 167}
 168
 169struct clk *clk_get_sys(const char *dev_id, const char *con_id)
 170{
 171        struct clk_lookup *cl;
 172        struct clk *clk = NULL;
 173
 174        mutex_lock(&clocks_mutex);
 175
 176        cl = clk_find(dev_id, con_id);
 177        if (!cl)
 178                goto out;
 179
 180        clk = __clk_create_clk(cl->clk_hw, dev_id, con_id);
 181        if (IS_ERR(clk))
 182                goto out;
 183
 184        if (!__clk_get(clk)) {
 185                __clk_free_clk(clk);
 186                cl = NULL;
 187                goto out;
 188        }
 189
 190out:
 191        mutex_unlock(&clocks_mutex);
 192
 193        return cl ? clk : ERR_PTR(-ENOENT);
 194}
 195EXPORT_SYMBOL(clk_get_sys);
 196
 197struct clk *clk_get(struct device *dev, const char *con_id)
 198{
 199        const char *dev_id = dev ? dev_name(dev) : NULL;
 200        struct clk *clk;
 201
 202        if (dev) {
 203                clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
 204                if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
 205                        return clk;
 206        }
 207
 208        return clk_get_sys(dev_id, con_id);
 209}
 210EXPORT_SYMBOL(clk_get);
 211
 212void clk_put(struct clk *clk)
 213{
 214        __clk_put(clk);
 215}
 216EXPORT_SYMBOL(clk_put);
 217
 218static void __clkdev_add(struct clk_lookup *cl)
 219{
 220        mutex_lock(&clocks_mutex);
 221        list_add_tail(&cl->node, &clocks);
 222        mutex_unlock(&clocks_mutex);
 223}
 224
 225void clkdev_add(struct clk_lookup *cl)
 226{
 227        if (!cl->clk_hw)
 228                cl->clk_hw = __clk_get_hw(cl->clk);
 229        __clkdev_add(cl);
 230}
 231EXPORT_SYMBOL(clkdev_add);
 232
 233void clkdev_add_table(struct clk_lookup *cl, size_t num)
 234{
 235        mutex_lock(&clocks_mutex);
 236        while (num--) {
 237                cl->clk_hw = __clk_get_hw(cl->clk);
 238                list_add_tail(&cl->node, &clocks);
 239                cl++;
 240        }
 241        mutex_unlock(&clocks_mutex);
 242}
 243
 244#define MAX_DEV_ID      20
 245#define MAX_CON_ID      16
 246
 247struct clk_lookup_alloc {
 248        struct clk_lookup cl;
 249        char    dev_id[MAX_DEV_ID];
 250        char    con_id[MAX_CON_ID];
 251};
 252
 253static struct clk_lookup * __init_refok
 254vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
 255        va_list ap)
 256{
 257        struct clk_lookup_alloc *cla;
 258
 259        cla = __clkdev_alloc(sizeof(*cla));
 260        if (!cla)
 261                return NULL;
 262
 263        cla->cl.clk_hw = hw;
 264        if (con_id) {
 265                strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
 266                cla->cl.con_id = cla->con_id;
 267        }
 268
 269        if (dev_fmt) {
 270                vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
 271                cla->cl.dev_id = cla->dev_id;
 272        }
 273
 274        return &cla->cl;
 275}
 276
 277static struct clk_lookup *
 278vclkdev_create(struct clk_hw *hw, const char *con_id, const char *dev_fmt,
 279        va_list ap)
 280{
 281        struct clk_lookup *cl;
 282
 283        cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
 284        if (cl)
 285                __clkdev_add(cl);
 286
 287        return cl;
 288}
 289
 290struct clk_lookup * __init_refok
 291clkdev_alloc(struct clk *clk, const char *con_id, const char *dev_fmt, ...)
 292{
 293        struct clk_lookup *cl;
 294        va_list ap;
 295
 296        va_start(ap, dev_fmt);
 297        cl = vclkdev_alloc(__clk_get_hw(clk), con_id, dev_fmt, ap);
 298        va_end(ap);
 299
 300        return cl;
 301}
 302EXPORT_SYMBOL(clkdev_alloc);
 303
 304/**
 305 * clkdev_create - allocate and add a clkdev lookup structure
 306 * @clk: struct clk to associate with all clk_lookups
 307 * @con_id: connection ID string on device
 308 * @dev_fmt: format string describing device name
 309 *
 310 * Returns a clk_lookup structure, which can be later unregistered and
 311 * freed.
 312 */
 313struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
 314        const char *dev_fmt, ...)
 315{
 316        struct clk_lookup *cl;
 317        va_list ap;
 318
 319        va_start(ap, dev_fmt);
 320        cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap);
 321        va_end(ap);
 322
 323        return cl;
 324}
 325EXPORT_SYMBOL_GPL(clkdev_create);
 326
 327int clk_add_alias(const char *alias, const char *alias_dev_name,
 328        const char *con_id, struct device *dev)
 329{
 330        struct clk *r = clk_get(dev, con_id);
 331        struct clk_lookup *l;
 332
 333        if (IS_ERR(r))
 334                return PTR_ERR(r);
 335
 336        l = clkdev_create(r, alias, alias_dev_name ? "%s" : NULL,
 337                          alias_dev_name);
 338        clk_put(r);
 339
 340        return l ? 0 : -ENODEV;
 341}
 342EXPORT_SYMBOL(clk_add_alias);
 343
 344/*
 345 * clkdev_drop - remove a clock dynamically allocated
 346 */
 347void clkdev_drop(struct clk_lookup *cl)
 348{
 349        mutex_lock(&clocks_mutex);
 350        list_del(&cl->node);
 351        mutex_unlock(&clocks_mutex);
 352        kfree(cl);
 353}
 354EXPORT_SYMBOL(clkdev_drop);
 355
 356/**
 357 * clk_register_clkdev - register one clock lookup for a struct clk
 358 * @clk: struct clk to associate with all clk_lookups
 359 * @con_id: connection ID string on device
 360 * @dev_id: format string describing device name
 361 *
 362 * con_id or dev_id may be NULL as a wildcard, just as in the rest of
 363 * clkdev.
 364 *
 365 * To make things easier for mass registration, we detect error clks
 366 * from a previous clk_register() call, and return the error code for
 367 * those.  This is to permit this function to be called immediately
 368 * after clk_register().
 369 */
 370int clk_register_clkdev(struct clk *clk, const char *con_id,
 371        const char *dev_fmt, ...)
 372{
 373        struct clk_lookup *cl;
 374        va_list ap;
 375
 376        if (IS_ERR(clk))
 377                return PTR_ERR(clk);
 378
 379        va_start(ap, dev_fmt);
 380        cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap);
 381        va_end(ap);
 382
 383        return cl ? 0 : -ENOMEM;
 384}
 385EXPORT_SYMBOL(clk_register_clkdev);
 386
 387/**
 388 * clk_register_clkdevs - register a set of clk_lookup for a struct clk
 389 * @clk: struct clk to associate with all clk_lookups
 390 * @cl: array of clk_lookup structures with con_id and dev_id pre-initialized
 391 * @num: number of clk_lookup structures to register
 392 *
 393 * To make things easier for mass registration, we detect error clks
 394 * from a previous clk_register() call, and return the error code for
 395 * those.  This is to permit this function to be called immediately
 396 * after clk_register().
 397 */
 398int clk_register_clkdevs(struct clk *clk, struct clk_lookup *cl, size_t num)
 399{
 400        unsigned i;
 401
 402        if (IS_ERR(clk))
 403                return PTR_ERR(clk);
 404
 405        for (i = 0; i < num; i++, cl++) {
 406                cl->clk_hw = __clk_get_hw(clk);
 407                __clkdev_add(cl);
 408        }
 409
 410        return 0;
 411}
 412EXPORT_SYMBOL(clk_register_clkdevs);
 413