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 * __ref
 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 * __ref
 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
 304struct clk_lookup *
 305clkdev_hw_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, ...)
 306{
 307        struct clk_lookup *cl;
 308        va_list ap;
 309
 310        va_start(ap, dev_fmt);
 311        cl = vclkdev_alloc(hw, con_id, dev_fmt, ap);
 312        va_end(ap);
 313
 314        return cl;
 315}
 316EXPORT_SYMBOL(clkdev_hw_alloc);
 317
 318/**
 319 * clkdev_create - allocate and add a clkdev lookup structure
 320 * @clk: struct clk to associate with all clk_lookups
 321 * @con_id: connection ID string on device
 322 * @dev_fmt: format string describing device name
 323 *
 324 * Returns a clk_lookup structure, which can be later unregistered and
 325 * freed.
 326 */
 327struct clk_lookup *clkdev_create(struct clk *clk, const char *con_id,
 328        const char *dev_fmt, ...)
 329{
 330        struct clk_lookup *cl;
 331        va_list ap;
 332
 333        va_start(ap, dev_fmt);
 334        cl = vclkdev_create(__clk_get_hw(clk), con_id, dev_fmt, ap);
 335        va_end(ap);
 336
 337        return cl;
 338}
 339EXPORT_SYMBOL_GPL(clkdev_create);
 340
 341/**
 342 * clkdev_hw_create - allocate and add a clkdev lookup structure
 343 * @hw: struct clk_hw to associate with all clk_lookups
 344 * @con_id: connection ID string on device
 345 * @dev_fmt: format string describing device name
 346 *
 347 * Returns a clk_lookup structure, which can be later unregistered and
 348 * freed.
 349 */
 350struct clk_lookup *clkdev_hw_create(struct clk_hw *hw, const char *con_id,
 351        const char *dev_fmt, ...)
 352{
 353        struct clk_lookup *cl;
 354        va_list ap;
 355
 356        va_start(ap, dev_fmt);
 357        cl = vclkdev_create(hw, con_id, dev_fmt, ap);
 358        va_end(ap);
 359
 360        return cl;
 361}
 362EXPORT_SYMBOL_GPL(clkdev_hw_create);
 363
 364int clk_add_alias(const char *alias, const char *alias_dev_name,
 365        const char *con_id, struct device *dev)
 366{
 367        struct clk *r = clk_get(dev, con_id);
 368        struct clk_lookup *l;
 369
 370        if (IS_ERR(r))
 371                return PTR_ERR(r);
 372
 373        l = clkdev_create(r, alias, alias_dev_name ? "%s" : NULL,
 374                          alias_dev_name);
 375        clk_put(r);
 376
 377        return l ? 0 : -ENODEV;
 378}
 379EXPORT_SYMBOL(clk_add_alias);
 380
 381/*
 382 * clkdev_drop - remove a clock dynamically allocated
 383 */
 384void clkdev_drop(struct clk_lookup *cl)
 385{
 386        mutex_lock(&clocks_mutex);
 387        list_del(&cl->node);
 388        mutex_unlock(&clocks_mutex);
 389        kfree(cl);
 390}
 391EXPORT_SYMBOL(clkdev_drop);
 392
 393static struct clk_lookup *__clk_register_clkdev(struct clk_hw *hw,
 394                                                const char *con_id,
 395                                                const char *dev_id, ...)
 396{
 397        struct clk_lookup *cl;
 398        va_list ap;
 399
 400        va_start(ap, dev_id);
 401        cl = vclkdev_create(hw, con_id, dev_id, ap);
 402        va_end(ap);
 403
 404        return cl;
 405}
 406
 407/**
 408 * clk_register_clkdev - register one clock lookup for a struct clk
 409 * @clk: struct clk to associate with all clk_lookups
 410 * @con_id: connection ID string on device
 411 * @dev_id: string describing device name
 412 *
 413 * con_id or dev_id may be NULL as a wildcard, just as in the rest of
 414 * clkdev.
 415 *
 416 * To make things easier for mass registration, we detect error clks
 417 * from a previous clk_register() call, and return the error code for
 418 * those.  This is to permit this function to be called immediately
 419 * after clk_register().
 420 */
 421int clk_register_clkdev(struct clk *clk, const char *con_id,
 422        const char *dev_id)
 423{
 424        struct clk_lookup *cl;
 425
 426        if (IS_ERR(clk))
 427                return PTR_ERR(clk);
 428
 429        /*
 430         * Since dev_id can be NULL, and NULL is handled specially, we must
 431         * pass it as either a NULL format string, or with "%s".
 432         */
 433        if (dev_id)
 434                cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, "%s",
 435                                           dev_id);
 436        else
 437                cl = __clk_register_clkdev(__clk_get_hw(clk), con_id, NULL);
 438
 439        return cl ? 0 : -ENOMEM;
 440}
 441EXPORT_SYMBOL(clk_register_clkdev);
 442
 443/**
 444 * clk_hw_register_clkdev - register one clock lookup for a struct clk_hw
 445 * @hw: struct clk_hw to associate with all clk_lookups
 446 * @con_id: connection ID string on device
 447 * @dev_id: format string describing device name
 448 *
 449 * con_id or dev_id may be NULL as a wildcard, just as in the rest of
 450 * clkdev.
 451 *
 452 * To make things easier for mass registration, we detect error clk_hws
 453 * from a previous clk_hw_register_*() call, and return the error code for
 454 * those.  This is to permit this function to be called immediately
 455 * after clk_hw_register_*().
 456 */
 457int clk_hw_register_clkdev(struct clk_hw *hw, const char *con_id,
 458        const char *dev_id)
 459{
 460        struct clk_lookup *cl;
 461
 462        if (IS_ERR(hw))
 463                return PTR_ERR(hw);
 464
 465        /*
 466         * Since dev_id can be NULL, and NULL is handled specially, we must
 467         * pass it as either a NULL format string, or with "%s".
 468         */
 469        if (dev_id)
 470                cl = __clk_register_clkdev(hw, con_id, "%s", dev_id);
 471        else
 472                cl = __clk_register_clkdev(hw, con_id, NULL);
 473
 474        return cl ? 0 : -ENOMEM;
 475}
 476EXPORT_SYMBOL(clk_hw_register_clkdev);
 477