mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 19:00:25 +00:00
![Mike Turquette](/assets/img/avatar_default.png)
The common clock framework defines a common struct clk useful across most platforms as well as an implementation of the clk api that drivers can use safely for managing clocks. The net result is consolidation of many different struct clk definitions and platform-specific clock framework implementations. This patch introduces the common struct clk, struct clk_ops and an implementation of the well-known clock api in include/clk/clk.h. Platforms may define their own hardware-specific clock structure and their own clock operation callbacks, so long as it wraps an instance of struct clk_hw. See Documentation/clk.txt for more details. This patch is based on the work of Jeremy Kerr, which in turn was based on the work of Ben Herrenschmidt. Signed-off-by: Mike Turquette <mturquette@linaro.org> Signed-off-by: Mike Turquette <mturquette@ti.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Andrew Lunn <andrew@lunn.ch> Reviewed-by: Rob Herring <rob.herring <at> calxeda.com> Cc: Russell King <linux@arm.linux.org.uk> Cc: Jeremy Kerr <jeremy.kerr@canonical.com> Cc: Arnd Bergman <arnd.bergmann@linaro.org> Cc: Paul Walmsley <paul@pwsan.com> Cc: Shawn Guo <shawn.guo@freescale.com> Cc: Sascha Hauer <s.hauer@pengutronix.de> Cc: Richard Zhao <richard.zhao@linaro.org> Cc: Saravana Kannan <skannan@codeaurora.org> Cc: Magnus Damm <magnus.damm@gmail.com> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com> Cc: Linus Walleij <linus.walleij@stericsson.com> Cc: Stephen Boyd <sboyd@codeaurora.org> Cc: Amit Kucheria <amit.kucheria@linaro.org> Cc: Deepak Saxena <dsaxena@linaro.org> Cc: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
281 lines
7.7 KiB
C
281 lines
7.7 KiB
C
/*
|
|
* linux/include/linux/clk.h
|
|
*
|
|
* Copyright (C) 2004 ARM Limited.
|
|
* Written by Deep Blue Solutions Limited.
|
|
* Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
#ifndef __LINUX_CLK_H
|
|
#define __LINUX_CLK_H
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/notifier.h>
|
|
|
|
struct device;
|
|
|
|
struct clk;
|
|
|
|
#ifdef CONFIG_COMMON_CLK
|
|
|
|
/**
|
|
* DOC: clk notifier callback types
|
|
*
|
|
* PRE_RATE_CHANGE - called immediately before the clk rate is changed,
|
|
* to indicate that the rate change will proceed. Drivers must
|
|
* immediately terminate any operations that will be affected by the
|
|
* rate change. Callbacks may either return NOTIFY_DONE or
|
|
* NOTIFY_STOP.
|
|
*
|
|
* ABORT_RATE_CHANGE: called if the rate change failed for some reason
|
|
* after PRE_RATE_CHANGE. In this case, all registered notifiers on
|
|
* the clk will be called with ABORT_RATE_CHANGE. Callbacks must
|
|
* always return NOTIFY_DONE.
|
|
*
|
|
* POST_RATE_CHANGE - called after the clk rate change has successfully
|
|
* completed. Callbacks must always return NOTIFY_DONE.
|
|
*
|
|
*/
|
|
#define PRE_RATE_CHANGE BIT(0)
|
|
#define POST_RATE_CHANGE BIT(1)
|
|
#define ABORT_RATE_CHANGE BIT(2)
|
|
|
|
/**
|
|
* struct clk_notifier - associate a clk with a notifier
|
|
* @clk: struct clk * to associate the notifier with
|
|
* @notifier_head: a blocking_notifier_head for this clk
|
|
* @node: linked list pointers
|
|
*
|
|
* A list of struct clk_notifier is maintained by the notifier code.
|
|
* An entry is created whenever code registers the first notifier on a
|
|
* particular @clk. Future notifiers on that @clk are added to the
|
|
* @notifier_head.
|
|
*/
|
|
struct clk_notifier {
|
|
struct clk *clk;
|
|
struct srcu_notifier_head notifier_head;
|
|
struct list_head node;
|
|
};
|
|
|
|
/**
|
|
* struct clk_notifier_data - rate data to pass to the notifier callback
|
|
* @clk: struct clk * being changed
|
|
* @old_rate: previous rate of this clk
|
|
* @new_rate: new rate of this clk
|
|
*
|
|
* For a pre-notifier, old_rate is the clk's rate before this rate
|
|
* change, and new_rate is what the rate will be in the future. For a
|
|
* post-notifier, old_rate and new_rate are both set to the clk's
|
|
* current rate (this was done to optimize the implementation).
|
|
*/
|
|
struct clk_notifier_data {
|
|
struct clk *clk;
|
|
unsigned long old_rate;
|
|
unsigned long new_rate;
|
|
};
|
|
|
|
int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
|
|
|
|
int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
|
|
|
|
#endif /* !CONFIG_COMMON_CLK */
|
|
|
|
/**
|
|
* clk_get - lookup and obtain a reference to a clock producer.
|
|
* @dev: device for clock "consumer"
|
|
* @id: clock comsumer ID
|
|
*
|
|
* Returns a struct clk corresponding to the clock producer, or
|
|
* valid IS_ERR() condition containing errno. The implementation
|
|
* uses @dev and @id to determine the clock consumer, and thereby
|
|
* the clock producer. (IOW, @id may be identical strings, but
|
|
* clk_get may return different clock producers depending on @dev.)
|
|
*
|
|
* Drivers must assume that the clock source is not enabled.
|
|
*
|
|
* clk_get should not be called from within interrupt context.
|
|
*/
|
|
struct clk *clk_get(struct device *dev, const char *id);
|
|
|
|
/**
|
|
* clk_prepare - prepare a clock source
|
|
* @clk: clock source
|
|
*
|
|
* This prepares the clock source for use.
|
|
*
|
|
* Must not be called from within atomic context.
|
|
*/
|
|
#ifdef CONFIG_HAVE_CLK_PREPARE
|
|
int clk_prepare(struct clk *clk);
|
|
#else
|
|
static inline int clk_prepare(struct clk *clk)
|
|
{
|
|
might_sleep();
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* clk_enable - inform the system when the clock source should be running.
|
|
* @clk: clock source
|
|
*
|
|
* If the clock can not be enabled/disabled, this should return success.
|
|
*
|
|
* May be called from atomic contexts.
|
|
*
|
|
* Returns success (0) or negative errno.
|
|
*/
|
|
int clk_enable(struct clk *clk);
|
|
|
|
/**
|
|
* clk_disable - inform the system when the clock source is no longer required.
|
|
* @clk: clock source
|
|
*
|
|
* Inform the system that a clock source is no longer required by
|
|
* a driver and may be shut down.
|
|
*
|
|
* May be called from atomic contexts.
|
|
*
|
|
* Implementation detail: if the clock source is shared between
|
|
* multiple drivers, clk_enable() calls must be balanced by the
|
|
* same number of clk_disable() calls for the clock source to be
|
|
* disabled.
|
|
*/
|
|
void clk_disable(struct clk *clk);
|
|
|
|
|
|
/**
|
|
* clk_unprepare - undo preparation of a clock source
|
|
* @clk: clock source
|
|
*
|
|
* This undoes a previously prepared clock. The caller must balance
|
|
* the number of prepare and unprepare calls.
|
|
*
|
|
* Must not be called from within atomic context.
|
|
*/
|
|
#ifdef CONFIG_HAVE_CLK_PREPARE
|
|
void clk_unprepare(struct clk *clk);
|
|
#else
|
|
static inline void clk_unprepare(struct clk *clk)
|
|
{
|
|
might_sleep();
|
|
}
|
|
#endif
|
|
|
|
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
|
|
static inline int clk_prepare_enable(struct clk *clk)
|
|
{
|
|
int ret;
|
|
|
|
ret = clk_prepare(clk);
|
|
if (ret)
|
|
return ret;
|
|
ret = clk_enable(clk);
|
|
if (ret)
|
|
clk_unprepare(clk);
|
|
|
|
return ret;
|
|
}
|
|
|
|
/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
|
|
static inline void clk_disable_unprepare(struct clk *clk)
|
|
{
|
|
clk_disable(clk);
|
|
clk_unprepare(clk);
|
|
}
|
|
|
|
/**
|
|
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
|
|
* This is only valid once the clock source has been enabled.
|
|
* @clk: clock source
|
|
*/
|
|
unsigned long clk_get_rate(struct clk *clk);
|
|
|
|
/**
|
|
* clk_put - "free" the clock source
|
|
* @clk: clock source
|
|
*
|
|
* Note: drivers must ensure that all clk_enable calls made on this
|
|
* clock source are balanced by clk_disable calls prior to calling
|
|
* this function.
|
|
*
|
|
* clk_put should not be called from within interrupt context.
|
|
*/
|
|
void clk_put(struct clk *clk);
|
|
|
|
|
|
/*
|
|
* The remaining APIs are optional for machine class support.
|
|
*/
|
|
|
|
|
|
/**
|
|
* clk_round_rate - adjust a rate to the exact rate a clock can provide
|
|
* @clk: clock source
|
|
* @rate: desired clock rate in Hz
|
|
*
|
|
* Returns rounded clock rate in Hz, or negative errno.
|
|
*/
|
|
long clk_round_rate(struct clk *clk, unsigned long rate);
|
|
|
|
/**
|
|
* clk_set_rate - set the clock rate for a clock source
|
|
* @clk: clock source
|
|
* @rate: desired clock rate in Hz
|
|
*
|
|
* Returns success (0) or negative errno.
|
|
*/
|
|
int clk_set_rate(struct clk *clk, unsigned long rate);
|
|
|
|
/**
|
|
* clk_set_parent - set the parent clock source for this clock
|
|
* @clk: clock source
|
|
* @parent: parent clock source
|
|
*
|
|
* Returns success (0) or negative errno.
|
|
*/
|
|
int clk_set_parent(struct clk *clk, struct clk *parent);
|
|
|
|
/**
|
|
* clk_get_parent - get the parent clock source for this clock
|
|
* @clk: clock source
|
|
*
|
|
* Returns struct clk corresponding to parent clock source, or
|
|
* valid IS_ERR() condition containing errno.
|
|
*/
|
|
struct clk *clk_get_parent(struct clk *clk);
|
|
|
|
/**
|
|
* clk_get_sys - get a clock based upon the device name
|
|
* @dev_id: device name
|
|
* @con_id: connection ID
|
|
*
|
|
* Returns a struct clk corresponding to the clock producer, or
|
|
* valid IS_ERR() condition containing errno. The implementation
|
|
* uses @dev_id and @con_id to determine the clock consumer, and
|
|
* thereby the clock producer. In contrast to clk_get() this function
|
|
* takes the device name instead of the device itself for identification.
|
|
*
|
|
* Drivers must assume that the clock source is not enabled.
|
|
*
|
|
* clk_get_sys should not be called from within interrupt context.
|
|
*/
|
|
struct clk *clk_get_sys(const char *dev_id, const char *con_id);
|
|
|
|
/**
|
|
* clk_add_alias - add a new clock alias
|
|
* @alias: name for clock alias
|
|
* @alias_dev_name: device name
|
|
* @id: platform specific clock name
|
|
* @dev: device
|
|
*
|
|
* Allows using generic clock names for drivers by adding a new alias.
|
|
* Assumes clkdev, see clkdev.h for more info.
|
|
*/
|
|
int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
|
|
struct device *dev);
|
|
|
|
#endif
|