From: skannan@codeaurora.org (Saravana Kannan)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 1/7] clk: Add a generic clock infrastructure
Date: Wed, 05 Oct 2011 18:17:50 -0700 [thread overview]
Message-ID: <4E8D01BE.3020202@codeaurora.org> (raw)
In-Reply-To: <1316730422-20027-2-git-send-email-mturquette@ti.com>
On 09/22/2011 03:26 PM, Mike Turquette wrote:
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 1d37f42..d6ae10b 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> +#ifdef CONFIG_GENERIC_CLK
> +
> +struct clk_hw {
> + struct clk *clk;
> +};
> +
> +/**
> + * struct clk_hw_ops - Callback operations for hardware clocks; these are to
> + * be provided by the clock implementation, and will be called by drivers
> + * through the clk_* API.
> + *
> + * @prepare: Prepare the clock for enabling. This must not return until
> + * the clock is fully prepared, and it's safe to call clk_enable.
> + * This callback is intended to allow clock implementations to
> + * do any initialisation that may sleep. Called with
> + * prepare_lock held.
> + *
> + * @unprepare: Release the clock from its prepared state. This will typically
> + * undo any work done in the @prepare callback. Called with
> + * prepare_lock held.
> + *
> + * @enable: Enable the clock atomically. This must not return until the
> + * clock is generating a valid clock signal, usable by consumer
> + * devices. Called with enable_lock held. This function must not
> + * sleep.
> + *
> + * @disable: Disable the clock atomically. Called with enable_lock held.
> + * This function must not sleep.
> + *
> + * @recalc_rate Recalculate the rate of this clock, by quering hardware
> + * and/or the clock's parent. Called with the global clock mutex
> + * held. Optional, but recommended - if this op is not set,
> + * clk_get_rate will return 0.
> + *
> + * @get_parent Query the parent of this clock; for clocks with multiple
> + * possible parents, query the hardware for the current
> + * parent. Currently only called when the clock is first
> + * registered.
> + *
> + * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
> + * implementations to split any work between atomic (enable) and sleepable
> + * (prepare) contexts. If a clock requires sleeping code to be turned on, this
> + * should be done in clk_prepare. Switching that will not sleep should be done
> + * in clk_enable.
> + *
> + * Typically, drivers will call clk_prepare when a clock may be needed later
> + * (eg. when a device is opened), and clk_enable when the clock is actually
> + * required (eg. from an interrupt). Note that clk_prepare *must* have been
> + * called before clk_enable.
> */
> +struct clk_hw_ops {
> + int (*prepare)(struct clk_hw *);
> + void (*unprepare)(struct clk_hw *);
> + int (*enable)(struct clk_hw *);
> + void (*disable)(struct clk_hw *);
> + unsigned long (*recalc_rate)(struct clk_hw *);
> + long (*round_rate)(struct clk_hw *, unsigned long);
> + struct clk * (*get_parent)(struct clk_hw *);
> +};
I would like to understand the need for recalc rate if that's something
that we want to go into the common framework (even if it's optional). I
have mostly heard only second hand explanations of the need for
recalc_rate(), so I might not have the full picture. But for all the
cases that I can think of, recalc_rate seems like a paradox.
If recalc_rate() is used to make sure the "current rate" of a "clock A"
is always known even if it's parent "clock B"'s rate is changed, then it
also means that the rate of "clock A" can change without
clk_set_rate(clock A, new rate). That in turn means that the
clk_get_rate() just gives the instantaneous snapshot of the rate. So,
any use of clk_get_rate(clock A) for anything other than
printing/logging the return value is broken code. In which case, do we
really care for recalc_rate()? We could just return the rate that it was
set to when clk_set_rate() was called and call it a day or return 0 for
such clocks to indicate that the clock rate is "unknown".
The whole concept of trying to recalculate the rate for a clock makes me
feel uneasy since it promotes misunderstanding the behavior of the clock
and writing bad code based on that misunderstanding.
I would like to hear to real usecases before I propose some alternatives
that I have in mind.
Thanks,
Saravana
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
WARNING: multiple messages have this Message-ID (diff)
From: Saravana Kannan <skannan@codeaurora.org>
To: Mike Turquette <mturquette@ti.com>,
paul@pwsan.com, grant.likely@secretlab.ca,
arnd.bergmann@linaro.org, tglx@linutronix.de,
Russell King - ARM Linux <linux@arm.linux.org.uk>
Cc: linux-kernel@vger.kernel.org, linaro-dev@lists.linaro.org,
linus.walleij@stericsson.com, patches@linaro.org,
eric.miao@linaro.org, broonie@opensource.wolfsonmicro.com,
magnus.damm@gmail.com, amit.kucheria@linaro.org,
richard.zhao@linaro.org, dsaxena@linaro.org,
shawn.guo@freescale.com, Saravana Kannan <skannan@codeaurora.org>,
linux@arm.linux.org.uk, jeremy.kerr@canonical.com,
linux-arm-kernel@lists.infradead.org,
Stephen Boyd <sboyd@codeaurora.org>
Subject: Re: [PATCH v2 1/7] clk: Add a generic clock infrastructure
Date: Wed, 05 Oct 2011 18:17:50 -0700 [thread overview]
Message-ID: <4E8D01BE.3020202@codeaurora.org> (raw)
In-Reply-To: <1316730422-20027-2-git-send-email-mturquette@ti.com>
On 09/22/2011 03:26 PM, Mike Turquette wrote:
> diff --git a/include/linux/clk.h b/include/linux/clk.h
> index 1d37f42..d6ae10b 100644
> --- a/include/linux/clk.h
> +++ b/include/linux/clk.h
> +#ifdef CONFIG_GENERIC_CLK
> +
> +struct clk_hw {
> + struct clk *clk;
> +};
> +
> +/**
> + * struct clk_hw_ops - Callback operations for hardware clocks; these are to
> + * be provided by the clock implementation, and will be called by drivers
> + * through the clk_* API.
> + *
> + * @prepare: Prepare the clock for enabling. This must not return until
> + * the clock is fully prepared, and it's safe to call clk_enable.
> + * This callback is intended to allow clock implementations to
> + * do any initialisation that may sleep. Called with
> + * prepare_lock held.
> + *
> + * @unprepare: Release the clock from its prepared state. This will typically
> + * undo any work done in the @prepare callback. Called with
> + * prepare_lock held.
> + *
> + * @enable: Enable the clock atomically. This must not return until the
> + * clock is generating a valid clock signal, usable by consumer
> + * devices. Called with enable_lock held. This function must not
> + * sleep.
> + *
> + * @disable: Disable the clock atomically. Called with enable_lock held.
> + * This function must not sleep.
> + *
> + * @recalc_rate Recalculate the rate of this clock, by quering hardware
> + * and/or the clock's parent. Called with the global clock mutex
> + * held. Optional, but recommended - if this op is not set,
> + * clk_get_rate will return 0.
> + *
> + * @get_parent Query the parent of this clock; for clocks with multiple
> + * possible parents, query the hardware for the current
> + * parent. Currently only called when the clock is first
> + * registered.
> + *
> + * The clk_enable/clk_disable and clk_prepare/clk_unprepare pairs allow
> + * implementations to split any work between atomic (enable) and sleepable
> + * (prepare) contexts. If a clock requires sleeping code to be turned on, this
> + * should be done in clk_prepare. Switching that will not sleep should be done
> + * in clk_enable.
> + *
> + * Typically, drivers will call clk_prepare when a clock may be needed later
> + * (eg. when a device is opened), and clk_enable when the clock is actually
> + * required (eg. from an interrupt). Note that clk_prepare *must* have been
> + * called before clk_enable.
> */
> +struct clk_hw_ops {
> + int (*prepare)(struct clk_hw *);
> + void (*unprepare)(struct clk_hw *);
> + int (*enable)(struct clk_hw *);
> + void (*disable)(struct clk_hw *);
> + unsigned long (*recalc_rate)(struct clk_hw *);
> + long (*round_rate)(struct clk_hw *, unsigned long);
> + struct clk * (*get_parent)(struct clk_hw *);
> +};
I would like to understand the need for recalc rate if that's something
that we want to go into the common framework (even if it's optional). I
have mostly heard only second hand explanations of the need for
recalc_rate(), so I might not have the full picture. But for all the
cases that I can think of, recalc_rate seems like a paradox.
If recalc_rate() is used to make sure the "current rate" of a "clock A"
is always known even if it's parent "clock B"'s rate is changed, then it
also means that the rate of "clock A" can change without
clk_set_rate(clock A, new rate). That in turn means that the
clk_get_rate() just gives the instantaneous snapshot of the rate. So,
any use of clk_get_rate(clock A) for anything other than
printing/logging the return value is broken code. In which case, do we
really care for recalc_rate()? We could just return the rate that it was
set to when clk_set_rate() was called and call it a day or return 0 for
such clocks to indicate that the clock rate is "unknown".
The whole concept of trying to recalculate the rate for a clock makes me
feel uneasy since it promotes misunderstanding the behavior of the clock
and writing bad code based on that misunderstanding.
I would like to hear to real usecases before I propose some alternatives
that I have in mind.
Thanks,
Saravana
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
next prev parent reply other threads:[~2011-10-06 1:17 UTC|newest]
Thread overview: 144+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-22 22:26 [PATCH v2 0/7] Add a generic struct clk Mike Turquette
2011-09-22 22:26 ` Mike Turquette
2011-09-22 22:26 ` [PATCH v2 1/7] clk: Add a generic clock infrastructure Mike Turquette
2011-09-22 22:26 ` Mike Turquette
2011-09-25 3:55 ` Grant Likely
2011-09-25 3:55 ` Grant Likely
2011-09-25 5:26 ` Turquette, Mike
2011-09-25 5:26 ` Turquette, Mike
2011-10-03 14:17 ` Rob Herring
2011-10-03 14:17 ` Rob Herring
2011-10-03 14:25 ` Mark Brown
2011-10-03 14:25 ` Mark Brown
2011-10-03 15:24 ` Rob Herring
2011-10-03 15:24 ` Rob Herring
2011-10-03 16:31 ` Mark Brown
2011-10-03 16:31 ` Mark Brown
2011-10-03 16:43 ` Russell King - ARM Linux
2011-10-03 16:43 ` Russell King - ARM Linux
2011-10-03 17:05 ` Mark Brown
2011-10-03 17:05 ` Mark Brown
2011-10-04 18:09 ` Grant Likely
2011-10-04 18:09 ` Grant Likely
2011-10-27 11:54 ` Domenico Andreoli
2011-10-27 11:54 ` Domenico Andreoli
2011-10-03 22:02 ` Rob Herring
2011-10-03 22:02 ` Rob Herring
2011-10-03 22:15 ` Turquette, Mike
2011-10-03 22:15 ` Turquette, Mike
2011-10-06 1:17 ` Saravana Kannan [this message]
2011-10-06 1:17 ` Saravana Kannan
2011-10-06 16:11 ` Turquette, Mike
2011-10-06 16:11 ` Turquette, Mike
2011-10-11 11:25 ` Richard Zhao
2011-10-11 11:25 ` Richard Zhao
2011-10-13 14:44 ` Russell King - ARM Linux
2011-10-13 14:44 ` Russell King - ARM Linux
2011-10-13 17:16 ` Turquette, Mike
2011-10-13 17:16 ` Turquette, Mike
2011-10-14 8:10 ` Richard Zhao
2011-10-14 8:10 ` Richard Zhao
2011-10-14 10:05 ` Mark Brown
2011-10-14 10:05 ` Mark Brown
2011-10-14 10:32 ` Richard Zhao
2011-10-14 10:32 ` Richard Zhao
2011-10-16 17:55 ` Sascha Hauer
2011-10-16 17:55 ` Sascha Hauer
2011-10-17 8:48 ` Richard Zhao
2011-10-17 8:48 ` Richard Zhao
2011-10-17 9:20 ` Mark Brown
2011-10-17 9:20 ` Mark Brown
2011-10-17 10:53 ` Richard Zhao
2011-10-17 10:53 ` Richard Zhao
2011-10-17 11:05 ` Sascha Hauer
2011-10-17 11:05 ` Sascha Hauer
2011-10-17 11:30 ` Russell King - ARM Linux
2011-10-17 11:30 ` Russell King - ARM Linux
2011-10-14 18:14 ` Turquette, Mike
2011-10-14 18:14 ` Turquette, Mike
2011-10-15 2:24 ` Richard Zhao
2011-10-15 2:24 ` Richard Zhao
2011-10-15 2:34 ` Richard Zhao
2011-10-15 2:34 ` Richard Zhao
2011-10-16 21:17 ` Turquette, Mike
2011-10-16 21:17 ` Turquette, Mike
2011-10-17 11:31 ` Richard Zhao
2011-10-17 11:31 ` Richard Zhao
2011-10-21 9:00 ` Richard Zhao
2011-10-21 9:00 ` Richard Zhao
2011-10-23 12:55 ` Shawn Guo
2011-10-23 12:55 ` Shawn Guo
2011-10-23 16:49 ` Turquette, Mike
2011-10-23 16:49 ` Turquette, Mike
2011-09-22 22:26 ` [PATCH v2 2/7] clk: Implement clk_set_rate Mike Turquette
2011-09-22 22:26 ` Mike Turquette
2011-10-11 11:49 ` Richard Zhao
2011-10-11 11:49 ` Richard Zhao
2011-10-23 14:24 ` Shawn Guo
2011-10-23 14:24 ` Shawn Guo
2011-10-23 16:50 ` Turquette, Mike
2011-10-23 16:50 ` Turquette, Mike
2011-09-22 22:26 ` [PATCH v2 3/7] clk: Add fixed-rate clock Mike Turquette
2011-09-22 22:26 ` Mike Turquette
2011-10-23 14:30 ` Shawn Guo
2011-10-23 14:30 ` Shawn Guo
2011-10-23 16:51 ` Turquette, Mike
2011-10-23 16:51 ` Turquette, Mike
2011-09-22 22:26 ` [PATCH v2 4/7] clk: Add simple gated clock Mike Turquette
2011-09-22 22:26 ` Mike Turquette
2011-09-25 4:02 ` Grant Likely
2011-09-25 4:02 ` Grant Likely
2011-09-25 5:27 ` Turquette, Mike
2011-09-25 5:27 ` Turquette, Mike
2011-09-26 18:33 ` Rob Herring
2011-09-26 18:33 ` Rob Herring
2011-09-26 18:40 ` Jamie Iles
2011-09-26 18:40 ` Jamie Iles
2011-09-26 19:10 ` Rob Herring
2011-09-26 19:10 ` Rob Herring
2011-09-26 19:37 ` Jamie Iles
2011-09-26 19:37 ` Jamie Iles
2011-09-26 22:37 ` Turquette, Mike
2011-09-26 22:37 ` Turquette, Mike
2011-09-26 23:30 ` Rob Herring
2011-09-26 23:30 ` Rob Herring
2011-10-05 1:41 ` Saravana Kannan
2011-10-05 1:41 ` Saravana Kannan
2011-10-12 6:46 ` Richard Zhao
2011-10-12 6:46 ` Richard Zhao
2011-10-12 14:59 ` Turquette, Mike
2011-10-12 14:59 ` Turquette, Mike
2011-10-16 18:26 ` Sascha Hauer
2011-10-16 18:26 ` Sascha Hauer
2011-10-17 6:42 ` Richard Zhao
2011-10-17 6:42 ` Richard Zhao
2011-10-17 17:46 ` Turquette, Mike
2011-10-17 17:46 ` Turquette, Mike
2011-10-13 14:45 ` Russell King - ARM Linux
2011-10-13 14:45 ` Russell King - ARM Linux
2011-10-13 17:18 ` Turquette, Mike
2011-10-13 17:18 ` Turquette, Mike
2011-09-22 22:27 ` [PATCH v2 5/7] clk: Add Kconfig option to build all generic clk drivers Mike Turquette
2011-09-22 22:27 ` Mike Turquette
2011-09-22 22:27 ` [PATCH v2 6/7] clk: Add initial WM831x clock driver Mike Turquette
2011-09-22 22:27 ` Mike Turquette
2011-09-25 4:08 ` Grant Likely
2011-09-25 4:08 ` Grant Likely
2011-09-25 5:29 ` Turquette, Mike
2011-09-25 5:29 ` Turquette, Mike
2011-09-26 9:38 ` Mark Brown
2011-09-26 9:38 ` Mark Brown
2011-10-04 18:18 ` Grant Likely
2011-10-04 18:18 ` Grant Likely
2011-10-04 20:50 ` Mark Brown
2011-10-04 20:50 ` Mark Brown
2011-10-04 23:22 ` Grant Likely
2011-10-04 23:22 ` Grant Likely
2011-09-22 22:27 ` [PATCH v2 7/7] x86: Enable generic clk API on x86 Mike Turquette
2011-09-22 22:27 ` Mike Turquette
2011-09-22 23:17 ` [PATCH v2 0/7] Add a generic struct clk Turquette, Mike
2011-09-22 23:17 ` Turquette, Mike
2011-09-25 4:10 ` Grant Likely
2011-09-25 4:10 ` Grant Likely
2011-09-29 18:54 ` Mark Brown
2011-09-29 18:54 ` Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E8D01BE.3020202@codeaurora.org \
--to=skannan@codeaurora.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.