* [PATCH 09/10] watchdog: xilinx: Add missing binding
From: Arnd Bergmann @ 2014-02-05 9:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <52F20387.3090709@monstr.eu>
On Wednesday 05 February 2014, Michal Simek wrote:
> I am not quite sure what you mean by reports to user space.
> If you mean to get timeout through ioctl for example - then yes it is working
> through standard watchdog ioctl interface and timeout is calculated
> from hardware setup.
Yes, that is what I meant. I believe most other watchdogs let
you program the timeout, but I don't see anything wrong with
having that fixed in the FPGA in your case.
Still, the choice of putting the timeout into DT in terms of
cycles rather than miliseconds wasn't ideal from an interface
perspective and we should change that if/when we do a generic
binding. I can definitely see where it's coming from for your
case, as the cycle count totally makes sense from an FPGA
tool perspective...
Arnd
^ permalink raw reply
* [PATCH] arm64: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-02-05 9:34 UTC (permalink / raw)
To: linux-arm-kernel
Add DSB after icache flush to complete the cache maintenance operation.
The function __flush_icache_all() is used only for user space mappings
and an ISB is not required because of an exception return before executing
user instructions. An exception return would behave like an ISB.
Signed-off-by: Vinayak Kale <vkale@apm.com>
---
arch/arm64/include/asm/cacheflush.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/include/asm/cacheflush.h b/arch/arm64/include/asm/cacheflush.h
index fea9ee3..88932498 100644
--- a/arch/arm64/include/asm/cacheflush.h
+++ b/arch/arm64/include/asm/cacheflush.h
@@ -116,6 +116,7 @@ extern void flush_dcache_page(struct page *);
static inline void __flush_icache_all(void)
{
asm("ic ialluis");
+ dsb();
}
#define flush_dcache_mmap_lock(mapping) \
--
1.7.9.5
^ permalink raw reply related
* [PATCH] arm: add DSB after icache flush in __flush_icache_all()
From: Vinayak Kale @ 2014-02-05 9:33 UTC (permalink / raw)
To: linux-arm-kernel
Add DSB after icache flush to complete the cache maintenance operation.
Signed-off-by: Vinayak Kale <vkale@apm.com>
---
PS:
- This patch is tested for ARM-v7.
arch/arm/include/asm/cacheflush.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index ee753f1..ab91ebb 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -212,6 +212,7 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
static inline void __flush_icache_all(void)
{
__flush_icache_preferred();
+ dsb();
}
/*
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 0/6] ARM: STi reset controller support
From: Philipp Zabel @ 2014-02-05 9:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391437665-11913-1-git-send-email-srinivas.kandagatla@st.com>
Hi Srinivas,
Am Montag, den 03.02.2014, 14:27 +0000 schrieb
srinivas.kandagatla at st.com:
> From: Srinivas Kandagatla <srinivas.kandagatla@st.com>
>
> Hi All,
>
> This patch series adds reset controller support for STi SOC series STiH415 and
> STiH416. It adds support for both power down reset and soft reset controllers.
> On STi series SOCs reset lines are wired up to system configuration registers.
> Most of the IPs on STi SOCs are left in reset state, so this driver is very
> important for other drivers to use the IPs.
>
> Patch 01: Adds reset controller based on system configuration registers via
> regmap.
>
> Patch 02, 03: adds STiH415 and STiH416 reset controller drivers.
>
> Patch 04, 05: adds STiH415 and STiH416 soft reset controllers.
>
> The final patch 06 selects reset controller in mach-sti Kconfig.
>
> I would like get this driver in to 3.15, so that its possible to add dt
> support for other IPs with reset lines. Without this patchset its impossible
> to add DT support to IPs with reset lines as reset line definition is in
> common header file in include/dt-bindings/.
>
> This reset controller will be used by gmac, i2c and st-ir drivers.
>
>
> Comments?
the patchset looks good to me for the soft resets. But for the powerdown
bits I am wondering whether the reset controller API is the right
abstraction. Depending on whether those bits really just put the IPs
into reset or there is some power gating / sequencing involved,
shouldn't this rather be handled as a set of pm domains?
I see that for example on STiH415 there are both soft resets and
powerdown bits for USB[012].
regards
Philipp
^ permalink raw reply
* [PATCH] security: select correct default LSM_MMAP_MIN_ADDR on arm on arm64
From: Eric Paris @ 2014-02-05 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204093843.GB16708@mudshark.cambridge.arm.com>
Acked-by: Eric Paris <eparis@redhat.com>
On Tue, Feb 4, 2014 at 4:38 AM, Will Deacon <will.deacon@arm.com> wrote:
> On Tue, Feb 04, 2014 at 02:15:32AM +0000, Colin Cross wrote:
>> Binaries compiled for arm may run on arm64 if CONFIG_COMPAT is
>> selected. Set LSM_MMAP_MIN_ADDR to 32768 if ARM64 && COMPAT to
>> prevent selinux failures launching 32-bit static executables that
>> are mapped at 0x8000.
>>
>> Signed-off-by: Colin Cross <ccross@android.com>
>> ---
>> security/Kconfig | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/security/Kconfig b/security/Kconfig
>> index e9c6ac724fef..beb86b500adf 100644
>> --- a/security/Kconfig
>> +++ b/security/Kconfig
>> @@ -103,7 +103,7 @@ config INTEL_TXT
>> config LSM_MMAP_MIN_ADDR
>> int "Low address space for LSM to protect from user allocation"
>> depends on SECURITY && SECURITY_SELINUX
>> - default 32768 if ARM
>> + default 32768 if ARM || (ARM64 && COMPAT)
>> default 65536
>> help
>> This is the portion of low virtual memory which should be protected
>
> Since ARM64 && COMPAT implies 4k pages, this change looks ok to me.
>
> Acked-by: Will Deacon <will.deacon@arm.com>
>
> Will
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 09/10] watchdog: xilinx: Add missing binding
From: Michal Simek @ 2014-02-05 9:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402042027.15898.arnd@arndb.de>
On 02/04/2014 08:27 PM, Arnd Bergmann wrote:
> On Monday 03 February 2014, Michal Simek wrote:
>> On 02/03/2014 04:32 PM, Arnd Bergmann wrote:
>>> On Monday 03 February 2014 16:13:47 Michal Simek wrote:
>>>> Intention wasn't to fix binding but document current one
>>>> which is in mainline for a long time.
>>>
>>> Ok, I see.
>>>
>>>> Apart of this - yes, wdt-enable-once is nowayout and wdt-interval should be timeout
>>>> is seconds, and clock-frequency should go out and use CCF for getting clock.
>>>
>>> Could we make a common binding then, and document that the xilinx
>>> watchdog can optionally provide either one?
>>
>> Do you mean to have 2 DT bindings?
>>
>> This binding is used from 2011-07.
>> It means it was generated for all hw designs at least from this time.
>> I would say from DT usage on Microblaze because it is not special case
>> in our dt generator.
>
> I certainly wasn't suggesting to break the binding, quite the contrary.
> What I tried to say is that the properties look like they should be
> useful for different kinds of watchdogs, not just xilinx, so it would
> be good to have a common definition using generic strings.
>
> The xilinx driver would definitely have to keep supporting the traditional
> property names, but it could also support the generic names in the
> future.
No problem with to do in future.
>> xlnx,XXX are XXX parameters which you have to setup in tools
>> and get synthesized. This is valid for all xilinx IPs. We have full
>> IP description by generating xlnx,XXX parameters directly from tools
>> because we know all variants which can happen.
>>
>> Just back to your previous post:
>> "I'm not sure about the enable-once flag, which seems to just map to the
>> "nowayout" watchdog option that is not a hardware feature at all"
>> this is hw feature which you can select in tools because this is fpga. :-)
>
> Ah, so you mean the properties are not settings that the driver
> programs into the hardware, but they are hardware properties that the
> driver reports to user space?
yes, they are hardware properties which you can choose based on your
configuration. Every user just decides if this watchdog can be started just
once and how long it takes in synthesis time. There is no option to program
this by software.
I am not quite sure what you mean by reports to user space.
If you mean to get timeout through ioctl for example - then yes it is working
through standard watchdog ioctl interface and timeout is calculated
from hardware setup.
Thanks,
Michal
--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 263 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140205/99e851c4/attachment-0001.sig>
^ permalink raw reply
* [alsa-devel] [PATCH v3 4/5] ASoC: tda998x: adjust the audio hw parameters from EDID
From: Lars-Peter Clausen @ 2014-02-05 9:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140205101134.4591e5c3@armhf>
On 02/05/2014 10:11 AM, Jean-Francois Moine wrote:
> On Tue, 4 Feb 2014 18:06:25 +0000
> Mark Brown <broonie@kernel.org> wrote:
>
>> On Mon, Jan 27, 2014 at 09:48:54AM +0100, Jean-Francois Moine wrote:
>>
>>> + /* change the snd_soc_pcm_stream values of the driver */
>>> + stream->rates = rate_mask;
>>> + stream->channels_max = max_channels;
>>> + stream->formats = formats;
>>
>>> + /* copy the DAI driver to a writable area */
>>> + dai_drv = devm_kzalloc(&pdev->dev, sizeof(tda998x_dai), GFP_KERNEL);
>>> + if (!dai_drv)
>>> + return -ENOMEM;
>>> + memcpy(dai_drv, tda998x_dai, sizeof(tda998x_dai));
>>> +
>>
>> The code should be doing this by setting constraints based on the
>> current setup rather than by editing the data structure - the expecation
>> is very much that the data won't change so this prevents surprises with
>> future work on the core.
>
> As it is done in the soc core, in soc_pcm_open(), the runtime hw_params
> are initialized after the call to the CODEC startup, and the next CODEC
> event is hw_params() when the user has already chosen all the parameters.
>
> So, in the CODEC, I don't see how I could update the parameters
> dictated by the EDID otherwise in changing the DAI driver parameters.
>
The startup function is the right place. But instead of modifying the DAI
use snd_pcm_hw_constraint_mask64(), snd_pcm_hw_constraint_list(), etc. to
setup the additional constraints that come from the EDID.
Bonus points for making this a generic helper function that takes a runtime
and a EDID and then applies the EDID constraints on the runtime.
- Lars
^ permalink raw reply
* [PATCH v5] ARM: davinci: aemif: get rid of davinci-nand driver dependency on aemif
From: Sekhar Nori @ 2014-02-05 9:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391079820-13018-1-git-send-email-ivan.khoronzhuk@ti.com>
Hi Brian,
On Thursday 30 January 2014 04:33 PM, Ivan Khoronzhuk wrote:
> The problem that the set timings code contains the call of Davinci
> platform function davinci_aemif_setup_timing() which is not
> accessible if kernel is built for another platform like Keystone.
>
> The Keysone platform is going to use TI AEMIF driver.
> If TI AEMIF is used we don't need to set timings and bus width.
> It is done by AEMIF driver.
>
> To get rid of davinci-nand driver dependency on aemif platform code
> we moved aemif code to davinci platform.
>
> The platform AEMIF code (aemif.c) has to be removed once Davinci
> will be converted to DT and use ti-aemif.c driver.
>
> Acked-by: Brian Norris <computersforpeace@gmail.com>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
> [nsekhar at ti.com: fixed checkpatch error and a build breakage due to
> missing include, rebased onto l2-mtd/master]
> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Hope this patch looks good to you now. I would like to take it for v3.15
via DaVinci tree.
Thanks,
Sekhar
^ permalink raw reply
* [Linux-kernel] [PATCH 2/3] ARM: shmobile: r8a7790: specify multiple parents for cpg_clks
From: Ben Dooks @ 2014-02-05 9:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391537858-28593-3-git-send-email-william.towle@codethink.co.uk>
On 04/02/14 18:17, William Towle wrote:
> The current drivers/clk/shmobile/clk-rcar-gen2.c uses the
> extal_clk reference for the parent of all the clocks that
> it registers. However the lb, qspi, sdh, sd0 and sd1 clocks
> are all parented to either pll1 or pll1_div2 which means
> that the clock rates are incorrect.
>
> This is part of the fix that corrects the SDHI0 clock
> rate error where it reports 1MHz instead of 97.5:
> sh_mobile_sdhi ee100000.sd: mmc0 base at 0xee100000 clock rate 1 MHz
>
> Notes:
> - May require cross-merge with clk-rcar-gen2.c fix
> - Also not clear which clock "z" is to fix it.
Laurent, if you could give us an idea of how to fix this then
it would be helpful to get this patch fully fixed.
>
> [ben.dooks at codethink.co.uk: updated patch description]
> Signed-off-by: William Towle <william.towle@codethink.co.uk>
> Reviewed-by: Ben Dooks <ben.dooks@codethink.co.uk>
> ---
> arch/arm/boot/dts/r8a7790.dtsi | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
> index ff55c6e..242e6e2 100644
> --- a/arch/arm/boot/dts/r8a7790.dtsi
> +++ b/arch/arm/boot/dts/r8a7790.dtsi
> @@ -446,7 +446,13 @@
> compatible = "renesas,r8a7790-cpg-clocks",
> "renesas,rcar-gen2-cpg-clocks";
> reg = <0 0xe6150000 0 0x1000>;
> - clocks = <&extal_clk>;
> + clocks = <&extal_clk>, <&extal_clk>, <&extal_clk>, <&extal_clk>,
> + <&cpg_clocks R8A7790_CLK_PLL1>,
> + <&pll1_div2_clk>,
> + <&cpg_clocks R8A7790_CLK_PLL1>,
> + <&cpg_clocks R8A7790_CLK_PLL1>,
> + <&cpg_clocks R8A7790_CLK_PLL1>
Should we add a pll1_clk node, or leave this as is?
> + /* not known for "z" ...,<> */;
> #clock-cells = <1>;
> clock-output-names = "main", "pll0", "pll1", "pll3",
> "lb", "qspi", "sdh", "sd0", "sd1",
>
--
Ben Dooks http://www.codethink.co.uk/
Senior Engineer Codethink - Providing Genius
^ permalink raw reply
* [PATCH v3 4/5] ASoC: tda998x: adjust the audio hw parameters from EDID
From: Jean-Francois Moine @ 2014-02-05 9:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204180625.GM22609@sirena.org.uk>
On Tue, 4 Feb 2014 18:06:25 +0000
Mark Brown <broonie@kernel.org> wrote:
> On Mon, Jan 27, 2014 at 09:48:54AM +0100, Jean-Francois Moine wrote:
>
> > + /* change the snd_soc_pcm_stream values of the driver */
> > + stream->rates = rate_mask;
> > + stream->channels_max = max_channels;
> > + stream->formats = formats;
>
> > + /* copy the DAI driver to a writable area */
> > + dai_drv = devm_kzalloc(&pdev->dev, sizeof(tda998x_dai), GFP_KERNEL);
> > + if (!dai_drv)
> > + return -ENOMEM;
> > + memcpy(dai_drv, tda998x_dai, sizeof(tda998x_dai));
> > +
>
> The code should be doing this by setting constraints based on the
> current setup rather than by editing the data structure - the expecation
> is very much that the data won't change so this prevents surprises with
> future work on the core.
As it is done in the soc core, in soc_pcm_open(), the runtime hw_params
are initialized after the call to the CODEC startup, and the next CODEC
event is hw_params() when the user has already chosen all the parameters.
So, in the CODEC, I don't see how I could update the parameters
dictated by the EDID otherwise in changing the DAI driver parameters.
--
Ken ar c'henta? | ** Breizh ha Linux atav! **
Jef | http://moinejf.free.fr/
^ permalink raw reply
* [PATCH 1/6] i2c: bcm-kona: register with subsys_initcall
From: Wolfram Sang @ 2014-02-05 9:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391516352-32359-2-git-send-email-mporter@linaro.org>
On Tue, Feb 04, 2014 at 07:19:07AM -0500, Matt Porter wrote:
> Voltage regulators are needed very early due to deferred probe
> being incompatible with built-in USB gadget drivers.
What does it need to fix those instead?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140205/9c9b7759/attachment.sig>
^ permalink raw reply
* [PATCH] ARM: OMAP3+: DPLL: stop reparenting to same parent if already done
From: Nishanth Menon @ 2014-02-05 9:04 UTC (permalink / raw)
To: linux-arm-kernel
omap3_noncore_dpll_set_rate forces a reparent to the same clk_ref
for every call that takes place. This is an can be done only if a change
is detected.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
arch/arm/mach-omap2/dpll3xxx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
index 3185ced..d9bcbf7 100644
--- a/arch/arm/mach-omap2/dpll3xxx.c
+++ b/arch/arm/mach-omap2/dpll3xxx.c
@@ -525,7 +525,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
* stuff is inherited for free
*/
- if (!ret)
+ if (!ret && clk_get_parent(hw->clk) != new_parent)
__clk_reparent(hw->clk, new_parent);
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH] backlight: add PWM dependencies
From: Linus Walleij @ 2014-02-05 8:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <000401cf222f$43263b20$c972b160$%han@samsung.com>
On Wed, Feb 5, 2014 at 6:01 AM, Jingoo Han <jg1.han@samsung.com> wrote:
> On Tuesday, February 04, 2014 9:57 PM, Linus Walleij wrote:
>>
>> In some compilations the LM3630A and LP855X backlight drivers
>> fail like this:
>>
>> drivers/built-in.o: In function `lm3630a_pwm_ctrl':
>> drivers/video/backlight/lm3630a_bl.c:168: undefined reference to `pwm_config'
>> drivers/video/backlight/lm3630a_bl.c:172: undefined reference to `pwm_disable'
>> drivers/video/backlight/lm3630a_bl.c:170: undefined reference to `pwm_enable'
>> drivers/built-in.o: In function `lp855x_pwm_ctrl':
>> drivers/video/backlight/lp855x_bl.c:249: undefined reference to `pwm_config'
>> drivers/video/backlight/lp855x_bl.c:253: undefined reference to `pwm_disable'
>> drivers/video/backlight/lp855x_bl.c:251: undefined reference to `pwm_enable'
>>
>> This is because both drivers depend on the PWM framework, so
>> add this dependency to their Kconfig entries.
>
> However, even though, when CONFIG_PWM is not enabled, the problem
> should not happen. pwm_config(),pwm_disable(), and pwm_enable()
> are already defined for CONFIG_PWM=n case as below.
So you may think but it does happen :-)
I reproduced this with the defconfig for ARM pxa255-idp and enabling
all boards for that platform, then enabling all available backlight drivers
as compiled-in objects (y).
> ./include/linux/pwm.h
> #if IS_ENABLED(CONFIG_PWM) || IS_ENABLED(CONFIG_HAVE_PWM)
> .....
> #else
Hm PXA that I am using defines CONFIG_HAVE_PWM, but doesn't
provide the required signatures (pwm_config/pwm_disable/pwm_enable).
One of two things is wrong:
- Either the PXA platform is breaking the CONFIG_HAVE_PWM
contract by not providing pwm_config/pwm_disable/pwm_enable
functions. Then HAVE_PWM should be removed from the PXA
Kconfig selects.
Or:
- There is no such contract that these functions must exist if
CONFIG_HAVE_PWM is defined, and the
#if IS_ENABLED(CONFIG_HAVE_PWM)
should be removed from <linux/pwm.h>
Does anyone know which one it is?
PWM subsystem maintainer? :-)
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2 4/4] clk: at91: optimization of the determine_rate callback
From: Boris BREZILLON @ 2014-02-05 8:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391589458-28018-5-git-send-email-jjhiblot@traphandler.com>
Hi JJ,
I guess you're commit message is wrong: you're optimizing set_rate not
determine_rate.
Best Regards,
Boris
On 05/02/2014 09:37, Jean-Jacques Hiblot wrote:
> Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
> Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> ---
> drivers/clk/at91/clk-programmable.c | 38 ++++++++-----------------------------
> 1 file changed, 8 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
> index 7bcc725..62e2509 100644
> --- a/drivers/clk/at91/clk-programmable.c
> +++ b/drivers/clk/at91/clk-programmable.c
> @@ -139,43 +139,21 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
> struct clk_programmable *prog = to_clk_programmable(hw);
> struct at91_pmc *pmc = prog->pmc;
> const struct clk_programmable_layout *layout = prog->layout;
> - unsigned long best_rate = parent_rate;
> - unsigned long best_diff;
> - unsigned long new_diff;
> - unsigned long cur_rate;
> + unsigned long div = parent_rate / rate;
> int shift = 0;
> u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
> ~(PROG_PRES_MASK << layout->pres_shift);
>
> - if (rate > parent_rate)
> - return parent_rate;
> - else
> - best_diff = parent_rate - rate;
> + if (!div)
> + return -EINVAL;
>
> - if (!best_diff) {
> - pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | shift);
> - return 0;
> - }
> -
> - for (shift = 1; shift < PROG_PRES_MASK; shift++) {
> - cur_rate = parent_rate >> shift;
> -
> - if (cur_rate > rate)
> - new_diff = cur_rate - rate;
> - else
> - new_diff = rate - cur_rate;
> -
> - if (!new_diff)
> - break;
> + shift = fls(div) - 1;
>
> - if (new_diff < best_diff) {
> - best_diff = new_diff;
> - best_rate = cur_rate;
> - }
> + if (div != (1<<shift))
> + return -EINVAL;
>
> - if (rate > cur_rate)
> - break;
> - }
> + if (shift >= PROG_PRES_MASK)
> + return -EINVAL;
>
> pmc_write(pmc, AT91_PMC_PCKR(prog->id),
> tmp | (shift << layout->pres_shift));
^ permalink raw reply
* [PATCH] clk: respect the clock dependencies in of_clk_init
From: Boris BREZILLON @ 2014-02-05 8:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391554766-11285-1-git-send-email-gregory.clement@free-electrons.com>
Hi Greg,
On 04/02/2014 23:59, Gregory CLEMENT wrote:
> Until now the clock providers were initialized in the order found in
> the device tree. This led to have the dependencies between the clocks
> not respected: children clocks could be initialized before their
> parent clocks.
>
> Instead of forcing each platform to manage its own initialization order,
> this patch adds this work inside the framework itself.
>
> Using the data of the device tree the of_clk_init function now delayed
> the initialization of a clock provider if its parent provider was not
> ready yet.
>
Great! I remember having some trouble with this "parent is not
registered yet" issue (but I don't recall how I solved it, maybe in
reordering clk nodes).
Anyway, this will help other platforms too (at least the at91 one).
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> ---
> Mike,
>
> this patch could solve the issues we get on severals mvebu platform
> since 3.14-rc1. This is an alternate solution of the patch set sent by
> Sebastian. However as it modifies the clock framework itself, it is
> more sensible.
>
> I find this solution more elegant than changing the order of the
> initialization of the clock at the platform level. However as it
> should be tested on more platforms that only the mvebu ones, it would
> take some time, and I don't want to still have "broken" platform
> during more release candidate. So at the end this patch should be part
> of the 3.15 kernel.
>
> Thanks,
>
> Gregory
>
> drivers/clk/clk.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 91 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> index 5517944495d8..beb0f8b0c2a0 100644
> --- a/drivers/clk/clk.c
> +++ b/drivers/clk/clk.c
> @@ -2526,24 +2526,112 @@ const char *of_clk_get_parent_name(struct device_node *np, int index)
> }
> EXPORT_SYMBOL_GPL(of_clk_get_parent_name);
>
> +struct clock_provider {
> + of_clk_init_cb_t clk_init_cb;
> + struct device_node *np;
> + struct list_head node;
> +};
> +
> +static LIST_HEAD(clk_provider_list);
> +
> +/*
> + * This function looks for a parent clock. If there is one, then it
> + * checks that the provider for this parent clock was initialized, in
> + * this case the parent clock will be ready.
> + */
> +static int parent_ready(struct device_node *np)
> +{
> + struct of_phandle_args clkspec;
> + struct of_clk_provider *provider;
> +
> + /*
> + * If there is no clock parent, no need to wait for them, then
> + * we can consider their absence as being ready
> + */
> + if (of_parse_phandle_with_args(np, "clocks", "#clock-cells", 0,
> + &clkspec))
> + return 1;
> +
> + /* Check if we have such a provider in our array */
> + list_for_each_entry(provider, &of_clk_providers, link) {
> + if (provider->node == clkspec.np)
> + return 1;
> + }
Shouldn't we wait for all parents to be ready (If I'm right, you're only
waiting for the first parent...) ?
And if you only request for one clk to be ready, why the first one (you
could loop over parent clks and stop when one of its parent is ready) ?
Best Regards,
Boris
> +
> + return 0;
> +}
> +
> /**
> * of_clk_init() - Scan and init clock providers from the DT
> * @matches: array of compatible values and init functions for providers.
> *
> - * This function scans the device tree for matching clock providers and
> - * calls their initialization functions
> + * This function scans the device tree for matching clock providers
> + * and calls their initialization functions. It also do it by trying
> + * to follow the dependencies.
> */
> void __init of_clk_init(const struct of_device_id *matches)
> {
> const struct of_device_id *match;
> struct device_node *np;
> + struct clock_provider *clk_provider, *next;
> + bool is_init_done;
>
> if (!matches)
> matches = &__clk_of_table;
>
> for_each_matching_node_and_match(np, matches, &match) {
> of_clk_init_cb_t clk_init_cb = match->data;
> - clk_init_cb(np);
> +
> +
> + if (parent_ready(np)) {
> + /*
> + * The parent clock is ready or there is no
> + * clock parent at all, in this case the
> + * provider can be initialize immediately.
> + */
> + clk_init_cb(np);
> + } else {
> + /*
> + * The parent clock is not ready, this
> + * provider is moved to a list to be
> + * initialized later
> + */
> + struct clock_provider *parent = kzalloc(sizeof(struct clock_provider),
> + GFP_KERNEL);
> +
> + parent->clk_init_cb = match->data;
> + parent->np = np;
> + list_add(&parent->node, &clk_provider_list);
> + }
> + }
> +
> + while (!list_empty(&clk_provider_list)) {
> + is_init_done = false;
> + list_for_each_entry_safe(clk_provider, next,
> + &clk_provider_list, node) {
> + if (parent_ready(clk_provider->np)) {
> + clk_provider->clk_init_cb(clk_provider->np);
> + list_del(&clk_provider->node);
> + kfree(clk_provider);
> + is_init_done = true;
> + }
> + }
> +
> + if (!is_init_done) {
> + /*
> + * We didn't managed to initialize any of the
> + * remaining providers during the last loop,
> + * so now we initialize all the remaining ones
> + * unconditionally in case the clock parent
> + * was not mandatory
> + */
> + list_for_each_entry_safe(clk_provider, next,
> + &clk_provider_list, node) {
> + clk_provider->clk_init_cb(clk_provider->np);
> + list_del(&clk_provider->node);
> + kfree(clk_provider);
> + }
> + }
> }
> }
> #endif
>
^ permalink raw reply
* [PATCH v2 4/4] clk: at91: optimization of the determine_rate callback
From: Jean-Jacques Hiblot @ 2014-02-05 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---
drivers/clk/at91/clk-programmable.c | 38 ++++++++-----------------------------
1 file changed, 8 insertions(+), 30 deletions(-)
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index 7bcc725..62e2509 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -139,43 +139,21 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
struct clk_programmable *prog = to_clk_programmable(hw);
struct at91_pmc *pmc = prog->pmc;
const struct clk_programmable_layout *layout = prog->layout;
- unsigned long best_rate = parent_rate;
- unsigned long best_diff;
- unsigned long new_diff;
- unsigned long cur_rate;
+ unsigned long div = parent_rate / rate;
int shift = 0;
u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
~(PROG_PRES_MASK << layout->pres_shift);
- if (rate > parent_rate)
- return parent_rate;
- else
- best_diff = parent_rate - rate;
+ if (!div)
+ return -EINVAL;
- if (!best_diff) {
- pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | shift);
- return 0;
- }
-
- for (shift = 1; shift < PROG_PRES_MASK; shift++) {
- cur_rate = parent_rate >> shift;
-
- if (cur_rate > rate)
- new_diff = cur_rate - rate;
- else
- new_diff = rate - cur_rate;
-
- if (!new_diff)
- break;
+ shift = fls(div) - 1;
- if (new_diff < best_diff) {
- best_diff = new_diff;
- best_rate = cur_rate;
- }
+ if (div != (1<<shift))
+ return -EINVAL;
- if (rate > cur_rate)
- break;
- }
+ if (shift >= PROG_PRES_MASK)
+ return -EINVAL;
pmc_write(pmc, AT91_PMC_PCKR(prog->id),
tmp | (shift << layout->pres_shift));
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 3/4] clk: at91: fix programmable clk irq handling
From: Jean-Jacques Hiblot @ 2014-02-05 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>
The PCKRDY bit is not set until the system clock is enabled.
This patch moves the management of the ready status in the system clock
driver.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
---
drivers/clk/at91/clk-programmable.c | 108 +++++++++---------------------------
drivers/clk/at91/clk-system.c | 74 ++++++++++++++++++++----
2 files changed, 89 insertions(+), 93 deletions(-)
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index eff7016..7bcc725 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -13,12 +13,9 @@
#include <linux/clk/at91_pmc.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/of_irq.h>
#include <linux/io.h>
#include <linux/wait.h>
#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
#include "pmc.h"
@@ -38,68 +35,23 @@ struct clk_programmable_layout {
struct clk_programmable {
struct clk_hw hw;
struct at91_pmc *pmc;
- unsigned int irq;
- wait_queue_head_t wait;
u8 id;
- u8 css;
- u8 pres;
- u8 slckmck;
const struct clk_programmable_layout *layout;
};
#define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw)
-
-static irqreturn_t clk_programmable_irq_handler(int irq, void *dev_id)
-{
- struct clk_programmable *prog = (struct clk_programmable *)dev_id;
-
- wake_up(&prog->wait);
-
- return IRQ_HANDLED;
-}
-
-static int clk_programmable_prepare(struct clk_hw *hw)
-{
- u32 tmp;
- struct clk_programmable *prog = to_clk_programmable(hw);
- struct at91_pmc *pmc = prog->pmc;
- const struct clk_programmable_layout *layout = prog->layout;
- u8 id = prog->id;
- u32 mask = PROG_STATUS_MASK(id);
-
- tmp = prog->css | (prog->pres << layout->pres_shift);
- if (layout->have_slck_mck && prog->slckmck)
- tmp |= AT91_PMC_CSSMCK_MCK;
-
- pmc_write(pmc, AT91_PMC_PCKR(id), tmp);
-
- while (!(pmc_read(pmc, AT91_PMC_SR) & mask))
- wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask);
-
- return 0;
-}
-
-static int clk_programmable_is_ready(struct clk_hw *hw)
-{
- struct clk_programmable *prog = to_clk_programmable(hw);
- struct at91_pmc *pmc = prog->pmc;
-
- return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id));
-}
-
static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
- u32 tmp;
+ u32 pres;
struct clk_programmable *prog = to_clk_programmable(hw);
struct at91_pmc *pmc = prog->pmc;
const struct clk_programmable_layout *layout = prog->layout;
- tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
- prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK;
-
- return parent_rate >> prog->pres;
+ pres = (pmc_read(pmc, AT91_PMC_PCKR(prog->id)) >> layout->pres_shift) &
+ PROG_PRES_MASK;
+ return parent_rate >> pres;
}
static long clk_programmable_determine_rate(struct clk_hw *hw,
@@ -146,17 +98,22 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_programmable *prog = to_clk_programmable(hw);
const struct clk_programmable_layout *layout = prog->layout;
+ struct at91_pmc *pmc = prog->pmc;
+ u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) & ~layout->css_mask;
+
+ if (layout->have_slck_mck)
+ tmp &= AT91_PMC_CSSMCK_MCK;
+
if (index > layout->css_mask) {
if (index > PROG_MAX_RM9200_CSS && layout->have_slck_mck) {
- prog->css = 0;
- prog->slckmck = 1;
+ tmp |= AT91_PMC_CSSMCK_MCK;
return 0;
} else {
return -EINVAL;
}
}
- prog->css = index;
+ pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | index);
return 0;
}
@@ -169,13 +126,9 @@ static u8 clk_programmable_get_parent(struct clk_hw *hw)
const struct clk_programmable_layout *layout = prog->layout;
tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
- prog->css = tmp & layout->css_mask;
- ret = prog->css;
- if (layout->have_slck_mck) {
- prog->slckmck = !!(tmp & AT91_PMC_CSSMCK_MCK);
- if (prog->slckmck && !ret)
- ret = PROG_MAX_RM9200_CSS + 1;
- }
+ ret = tmp & layout->css_mask;
+ if (layout->have_slck_mck && (tmp & AT91_PMC_CSSMCK_MCK) && !ret)
+ ret = PROG_MAX_RM9200_CSS + 1;
return ret;
}
@@ -184,11 +137,15 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_programmable *prog = to_clk_programmable(hw);
+ struct at91_pmc *pmc = prog->pmc;
+ const struct clk_programmable_layout *layout = prog->layout;
unsigned long best_rate = parent_rate;
unsigned long best_diff;
unsigned long new_diff;
unsigned long cur_rate;
int shift = 0;
+ u32 tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id)) &
+ ~(PROG_PRES_MASK << layout->pres_shift);
if (rate > parent_rate)
return parent_rate;
@@ -196,7 +153,7 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
best_diff = parent_rate - rate;
if (!best_diff) {
- prog->pres = shift;
+ pmc_write(pmc, AT91_PMC_PCKR(prog->id), tmp | shift);
return 0;
}
@@ -220,13 +177,13 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate,
break;
}
- prog->pres = shift;
+ pmc_write(pmc, AT91_PMC_PCKR(prog->id),
+ tmp | (shift << layout->pres_shift));
+
return 0;
}
static const struct clk_ops programmable_ops = {
- .prepare = clk_programmable_prepare,
- .is_prepared = clk_programmable_is_ready,
.recalc_rate = clk_programmable_recalc_rate,
.determine_rate = clk_programmable_determine_rate,
.get_parent = clk_programmable_get_parent,
@@ -235,16 +192,14 @@ static const struct clk_ops programmable_ops = {
};
static struct clk * __init
-at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
+at91_clk_register_programmable(struct at91_pmc *pmc,
const char *name, const char **parent_names,
u8 num_parents, u8 id,
const struct clk_programmable_layout *layout)
{
- int ret;
struct clk_programmable *prog;
struct clk *clk = NULL;
struct clk_init_data init;
- char irq_name[11];
if (id > PROG_ID_MAX)
return ERR_PTR(-EINVAL);
@@ -263,14 +218,6 @@ at91_clk_register_programmable(struct at91_pmc *pmc, unsigned int irq,
prog->layout = layout;
prog->hw.init = &init;
prog->pmc = pmc;
- prog->irq = irq;
- init_waitqueue_head(&prog->wait);
- irq_set_status_flags(prog->irq, IRQ_NOAUTOEN);
- snprintf(irq_name, sizeof(irq_name), "clk-prog%d", id);
- ret = request_irq(prog->irq, clk_programmable_irq_handler,
- IRQF_TRIGGER_HIGH, irq_name, prog);
- if (ret)
- return ERR_PTR(ret);
clk = clk_register(NULL, &prog->hw);
if (IS_ERR(clk))
@@ -304,7 +251,6 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
int num;
u32 id;
int i;
- unsigned int irq;
struct clk *clk;
int num_parents;
const char *parent_names[PROG_SOURCE_MAX];
@@ -332,11 +278,7 @@ of_at91_clk_prog_setup(struct device_node *np, struct at91_pmc *pmc,
if (of_property_read_string(np, "clock-output-names", &name))
name = progclknp->name;
- irq = irq_of_parse_and_map(progclknp, 0);
- if (!irq)
- continue;
-
- clk = at91_clk_register_programmable(pmc, irq, name,
+ clk = at91_clk_register_programmable(pmc, name,
parent_names, num_parents,
id, layout);
if (IS_ERR(clk))
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index a98557b..82c5f44 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -14,6 +14,11 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of_irq.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
#include "pmc.h"
@@ -25,19 +30,48 @@
struct clk_system {
struct clk_hw hw;
struct at91_pmc *pmc;
+ unsigned int irq;
+ wait_queue_head_t wait;
u8 id;
};
-static int clk_system_enable(struct clk_hw *hw)
+static inline int is_pck(int id)
+{
+ return (id >= 8) && (id <= 15);
+}
+static irqreturn_t clk_system_irq_handler(int irq, void *dev_id)
+{
+ struct clk_system *sys = (struct clk_system *)dev_id;
+
+ wake_up(&sys->wait);
+ disable_irq_nosync(sys->irq);
+
+ return IRQ_HANDLED;
+}
+
+static int clk_system_prepare(struct clk_hw *hw)
{
struct clk_system *sys = to_clk_system(hw);
struct at91_pmc *pmc = sys->pmc;
+ u32 mask = 1 << sys->id;
- pmc_write(pmc, AT91_PMC_SCER, 1 << sys->id);
+ pmc_write(pmc, AT91_PMC_SCER, mask);
+
+ if (!is_pck(sys->id))
+ return 0;
+
+ while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
+ if (sys->irq) {
+ enable_irq(sys->irq);
+ wait_event(sys->wait,
+ pmc_read(pmc, AT91_PMC_SR) & mask);
+ } else
+ cpu_relax();
+ }
return 0;
}
-static void clk_system_disable(struct clk_hw *hw)
+static void clk_system_unprepare(struct clk_hw *hw)
{
struct clk_system *sys = to_clk_system(hw);
struct at91_pmc *pmc = sys->pmc;
@@ -45,27 +79,34 @@ static void clk_system_disable(struct clk_hw *hw)
pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
}
-static int clk_system_is_enabled(struct clk_hw *hw)
+static int clk_system_is_prepared(struct clk_hw *hw)
{
struct clk_system *sys = to_clk_system(hw);
struct at91_pmc *pmc = sys->pmc;
- return !!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id));
+ if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)))
+ return 0;
+
+ if (!is_pck(sys->id))
+ return 1;
+
+ return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id));
}
static const struct clk_ops system_ops = {
- .enable = clk_system_enable,
- .disable = clk_system_disable,
- .is_enabled = clk_system_is_enabled,
+ .prepare = clk_system_prepare,
+ .unprepare = clk_system_unprepare,
+ .is_prepared = clk_system_is_prepared,
};
static struct clk * __init
at91_clk_register_system(struct at91_pmc *pmc, const char *name,
- const char *parent_name, u8 id)
+ const char *parent_name, u8 id, int irq)
{
struct clk_system *sys;
struct clk *clk = NULL;
struct clk_init_data init;
+ int ret;
if (!parent_name || id > SYSTEM_MAX_ID)
return ERR_PTR(-EINVAL);
@@ -90,6 +131,15 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
sys->id = id;
sys->hw.init = &init;
sys->pmc = pmc;
+ sys->irq = irq;
+ if (irq) {
+ init_waitqueue_head(&sys->wait);
+ irq_set_status_flags(sys->irq, IRQ_NOAUTOEN);
+ ret = request_irq(sys->irq, clk_system_irq_handler,
+ IRQF_TRIGGER_HIGH, name, sys);
+ if (ret)
+ return ERR_PTR(ret);
+ }
clk = clk_register(NULL, &sys->hw);
if (IS_ERR(clk))
@@ -102,6 +152,7 @@ static void __init
of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
{
int num;
+ int irq = 0;
u32 id;
struct clk *clk;
const char *name;
@@ -119,9 +170,12 @@ of_at91_clk_sys_setup(struct device_node *np, struct at91_pmc *pmc)
if (of_property_read_string(np, "clock-output-names", &name))
name = sysclknp->name;
+ if (is_pck(id))
+ irq = irq_of_parse_and_map(sysclknp, 0);
+
parent_name = of_clk_get_parent_name(sysclknp, 0);
- clk = at91_clk_register_system(pmc, name, parent_name, id);
+ clk = at91_clk_register_system(pmc, name, parent_name, id, irq);
if (IS_ERR(clk))
continue;
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 2/4] clk: at91: propagate rate change on system clks
From: Jean-Jacques Hiblot @ 2014-02-05 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>
From: Boris BREZILLON <b.brezillon@overkiz.com>
System clks are just gates, and thus do not provide any rate operations.
Authorize clk rate change to be propagated to system clk parents.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
drivers/clk/at91/clk-system.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c
index 8f7c043..a98557b 100644
--- a/drivers/clk/at91/clk-system.c
+++ b/drivers/clk/at91/clk-system.c
@@ -84,7 +84,8 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name,
* (see drivers/memory) which would request and enable the ddrck clock.
* When this is done we will be able to remove CLK_IGNORE_UNUSED flag.
*/
- init.flags = CLK_IGNORE_UNUSED;
+ init.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT |
+ CLK_IGNORE_UNUSED;
sys->id = id;
sys->hw.init = &init;
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 1/4] clk: at91: replace prog clk round_rate with determine_rate
From: Jean-Jacques Hiblot @ 2014-02-05 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391589458-28018-1-git-send-email-jjhiblot@traphandler.com>
From: Boris BREZILLON <b.brezillon@overkiz.com>
Implement the determine_rate callback to choose the best parent clk that
fulfills the requested rate.
Signed-off-by: Boris BREZILLON <b.brezillon@overkiz.com>
---
drivers/clk/at91/clk-programmable.c | 56 ++++++++++++++++++-------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
index fd792b2..eff7016 100644
--- a/drivers/clk/at91/clk-programmable.c
+++ b/drivers/clk/at91/clk-programmable.c
@@ -102,40 +102,40 @@ static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
return parent_rate >> prog->pres;
}
-static long clk_programmable_round_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *parent_rate)
+static long clk_programmable_determine_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *best_parent_rate,
+ struct clk **best_parent_clk)
{
- unsigned long best_rate = *parent_rate;
- unsigned long best_diff;
- unsigned long new_diff;
- unsigned long cur_rate;
- int shift = shift;
-
- if (rate > *parent_rate)
- return *parent_rate;
- else
- best_diff = *parent_rate - rate;
-
- if (!best_diff)
- return best_rate;
+ struct clk *parent = NULL;
+ long best_rate = -EINVAL;
+ unsigned long parent_rate;
+ unsigned long tmp_rate;
+ int shift;
+ int i;
- for (shift = 1; shift < PROG_PRES_MASK; shift++) {
- cur_rate = *parent_rate >> shift;
+ for (i = 0; i < __clk_get_num_parents(hw->clk); i++) {
+ parent = clk_get_parent_by_index(hw->clk, i);
+ if (!parent)
+ continue;
- if (cur_rate > rate)
- new_diff = cur_rate - rate;
- else
- new_diff = rate - cur_rate;
+ parent_rate = __clk_get_rate(parent);
+ for (shift = 0; shift < PROG_PRES_MASK; shift++) {
+ tmp_rate = parent_rate >> shift;
+ if (tmp_rate <= rate)
+ break;
+ }
- if (!new_diff)
- return cur_rate;
+ if (tmp_rate > rate)
+ continue;
- if (new_diff < best_diff) {
- best_diff = new_diff;
- best_rate = cur_rate;
+ if (best_rate < 0 || (rate - tmp_rate) < (rate - best_rate)) {
+ best_rate = tmp_rate;
+ *best_parent_rate = parent_rate;
+ *best_parent_clk = parent;
}
- if (rate > cur_rate)
+ if (!best_rate)
break;
}
@@ -228,7 +228,7 @@ static const struct clk_ops programmable_ops = {
.prepare = clk_programmable_prepare,
.is_prepared = clk_programmable_is_ready,
.recalc_rate = clk_programmable_recalc_rate,
- .round_rate = clk_programmable_round_rate,
+ .determine_rate = clk_programmable_determine_rate,
.get_parent = clk_programmable_get_parent,
.set_parent = clk_programmable_set_parent,
.set_rate = clk_programmable_set_rate,
--
1.8.5.2
^ permalink raw reply related
* [PATCH v2 0/4] clk: at91: better support for the PCKs
From: Jean-Jacques Hiblot @ 2014-02-05 8:37 UTC (permalink / raw)
To: linux-arm-kernel
This serie implements a better support for the Programmable Clocks.
The first two patch are related to changing the rate of the PCKs.
The 3rd patch is a fix to handle properly the PCKRDY interrupt.
The last patch is a small optimzation/simplification of the determine_rate
algorithm for the PCK.
This has been tested on a 9261ek
Boris BREZILLON (2):
clk: at91: replace prog clk round_rate with determine_rate
clk: at91: propagate rate change on system clks
Jean-Jacques Hiblot (2):
clk: at91: fix programmable clk irq handling
clk: at91: optimization of the determine_rate callback
drivers/clk/at91/clk-programmable.c | 202 +++++++++++-------------------------
drivers/clk/at91/clk-system.c | 77 ++++++++++++--
2 files changed, 127 insertions(+), 152 deletions(-)
--
1.8.5.2
^ permalink raw reply
* [PATCH v2] ARM: at91: add Atmel's SAMA5D3 Xplained board
From: Nicolas Ferre @ 2014-02-05 8:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140204203054.GA21958@ldesroches-Latitude-E6320>
Add DT file for new SAMA5D3 Xpained board.
This board is based on Atmel's SAMA5D36 Cortex-A5 SoC.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/boot/dts/Makefile | 1 +
arch/arm/boot/dts/at91-sama5d3_xplained.dts | 233 ++++++++++++++++++++++++++++
2 files changed, 234 insertions(+)
create mode 100644 arch/arm/boot/dts/at91-sama5d3_xplained.dts
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index b9d6a8b485e0..6d1e43d46187 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -38,6 +38,7 @@ dtb-$(CONFIG_ARCH_AT91) += at91sam9g35ek.dtb
dtb-$(CONFIG_ARCH_AT91) += at91sam9x25ek.dtb
dtb-$(CONFIG_ARCH_AT91) += at91sam9x35ek.dtb
# sama5d3
+dtb-$(CONFIG_ARCH_AT91) += at91-sama5d3_xplained.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d31ek.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb
dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb
diff --git a/arch/arm/boot/dts/at91-sama5d3_xplained.dts b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
new file mode 100644
index 000000000000..fb1349ca60a4
--- /dev/null
+++ b/arch/arm/boot/dts/at91-sama5d3_xplained.dts
@@ -0,0 +1,233 @@
+/*
+ * at91-sama5d3_xplained.dts - Device Tree file for the SAMA5D3 Xplained board
+ *
+ * Copyright (C) 2014 Atmel,
+ * 2014 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+#include "sama5d36.dtsi"
+
+/ {
+ model = "SAMA5D3 Xplained";
+ compatible = "atmel,sama5d3-xplained", "atmel,sama5d3", "atmel,sama5";
+
+ chosen {
+ bootargs = "console=ttyS0,115200";
+ };
+
+ memory {
+ reg = <0x20000000 0x10000000>;
+ };
+
+ ahb {
+ apb {
+ mmc0: mmc at f0000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc0_clk_cmd_dat0 &pinctrl_mmc0_dat1_3 &pinctrl_mmc0_dat4_7 &pinctrl_mmc0_cd>;
+ status = "okay";
+ slot at 0 {
+ reg = <0>;
+ bus-width = <8>;
+ cd-gpios = <&pioE 0 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ spi0: spi at f0004000 {
+ cs-gpios = <&pioD 13 0>, <0>, <0>, <0>;
+ status = "okay";
+ };
+
+ can0: can at f000c000 {
+ status = "okay";
+ };
+
+ i2c0: i2c at f0014000 {
+ status = "okay";
+ };
+
+ i2c1: i2c at f0018000 {
+ status = "okay";
+ };
+
+ macb0: ethernet at f0028000 {
+ phy-mode = "rgmii";
+ status = "okay";
+ };
+
+ usart0: serial at f001c000 {
+ status = "okay";
+ };
+
+ usart1: serial at f0020000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usart1 &pinctrl_usart1_rts_cts>;
+ status = "okay";
+ };
+
+ uart0: serial at f0024000 {
+ status = "okay";
+ };
+
+ mmc1: mmc at f8000000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_mmc1_clk_cmd_dat0 &pinctrl_mmc1_dat1_3 &pinctrl_mmc1_cd>;
+ status = "okay";
+ slot at 0 {
+ reg = <0>;
+ bus-width = <4>;
+ cd-gpios = <&pioE 1 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ spi1: spi at f8008000 {
+ cs-gpios = <&pioC 25 0>, <0>, <0>, <&pioD 16 0>;
+ status = "okay";
+ };
+
+ adc0: adc at f8018000 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &pinctrl_adc0_adtrg
+ &pinctrl_adc0_ad0
+ &pinctrl_adc0_ad1
+ &pinctrl_adc0_ad2
+ &pinctrl_adc0_ad3
+ &pinctrl_adc0_ad4
+ &pinctrl_adc0_ad5
+ &pinctrl_adc0_ad6
+ &pinctrl_adc0_ad7
+ &pinctrl_adc0_ad8
+ &pinctrl_adc0_ad9
+ >;
+ status = "okay";
+ };
+
+ i2c2: i2c at f801c000 {
+ dmas = <0>, <0>; /* Do not use DMA for i2c2 */
+ status = "okay";
+ };
+
+ macb1: ethernet at f802c000 {
+ phy-mode = "rmii";
+ status = "okay";
+ };
+
+ dbgu: serial at ffffee00 {
+ status = "okay";
+ };
+
+ pinctrl at fffff200 {
+ board {
+ pinctrl_mmc0_cd: mmc0_cd {
+ atmel,pins =
+ <AT91_PIOE 0 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_mmc1_cd: mmc1_cd {
+ atmel,pins =
+ <AT91_PIOE 1 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+ };
+
+ pinctrl_usba_vbus: usba_vbus {
+ atmel,pins =
+ <AT91_PIOE 9 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>; /* PE9, conflicts with A9 */
+ };
+ };
+ };
+
+ pmc: pmc at fffffc00 {
+ main: mainck {
+ clock-frequency = <12000000>;
+ };
+ };
+ };
+
+ nand0: nand at 60000000 {
+ nand-bus-width = <8>;
+ nand-ecc-mode = "hw";
+ atmel,has-pmecc;
+ atmel,pmecc-cap = <4>;
+ atmel,pmecc-sector-size = <512>;
+ nand-on-flash-bbt;
+ status = "okay";
+
+ at91bootstrap at 0 {
+ label = "at91bootstrap";
+ reg = <0x0 0x40000>;
+ };
+
+ bootloader at 40000 {
+ label = "bootloader";
+ reg = <0x40000 0x80000>;
+ };
+
+ bootloaderenv at c0000 {
+ label = "bootloader env";
+ reg = <0xc0000 0xc0000>;
+ };
+
+ dtb at 180000 {
+ label = "device tree";
+ reg = <0x180000 0x80000>;
+ };
+
+ kernel at 200000 {
+ label = "kernel";
+ reg = <0x200000 0x600000>;
+ };
+
+ rootfs at 800000 {
+ label = "rootfs";
+ reg = <0x800000 0x0f800000>;
+ };
+ };
+
+ usb0: gadget at 00500000 {
+ atmel,vbus-gpio = <&pioE 9 GPIO_ACTIVE_HIGH>; /* PE9, conflicts with A9 */
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usba_vbus>;
+ status = "okay";
+ };
+
+ usb1: ohci at 00600000 {
+ num-ports = <3>;
+ atmel,vbus-gpio = <0
+ &pioE 3 GPIO_ACTIVE_LOW
+ &pioE 4 GPIO_ACTIVE_LOW
+ >;
+ status = "okay";
+ };
+
+ usb2: ehci at 00700000 {
+ status = "okay";
+ };
+ };
+
+ gpio_keys {
+ compatible = "gpio-keys";
+
+ bp3 {
+ label = "PB_USER";
+ gpios = <&pioE 29 GPIO_ACTIVE_LOW>;
+ linux,code = <0x104>;
+ gpio-key,wakeup;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ d2 {
+ label = "d2";
+ gpios = <&pioE 23 GPIO_ACTIVE_LOW>; /* PE23, conflicts with A23, CTS2 */
+ linux,default-trigger = "heartbeat";
+ };
+
+ d3 {
+ label = "d3";
+ gpios = <&pioE 24 GPIO_ACTIVE_HIGH>;
+ };
+ };
+};
--
1.8.2.2
^ permalink raw reply related
* [PATCH 1/3] ARM: dts: imx27-phytec-phycard-s-som: Sort entries
From: Sascha Hauer @ 2014-02-05 8:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1391525972-15810-1-git-send-email-shc_work@mail.ru>
On Tue, Feb 04, 2014 at 06:59:30PM +0400, Alexander Shiyan wrote:
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
This series:
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 0/2] Add Ether's PHY IRQ support for Lager/Koelsh boards
From: Magnus Damm @ 2014-02-05 7:25 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <201402041851.47198.sergei.shtylyov@cogentembedded.com>
Hi Sergei,
On Wed, Feb 5, 2014 at 12:51 AM, Sergei Shtylyov
<sergei.shtylyov@cogentembedded.com> wrote:
> Hello.
>
> Here's the set of 2 patches against Simon Horman's 'renesas.git' repo,
> 'renesas-devel-v3.14-rc1-20130204' tag. Here we add support for the Ether's PHY
> IRQ to the R8A7790/Lager and R8A7791/Koelsch boards.
>
> [1/2] ARM: shmobile: Lager: pass Ether PHY IRQ
> [1/2] ARM: shmobile: Koelsch: pass Ether PHY IRQ
Thanks, looking good!
/ magnus
^ permalink raw reply
* [GIT PULL] tree-wide: clean up no longer required #include <linux/init.h>
From: Ingo Molnar @ 2014-02-05 6:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140205172723.3fa841793b3fa3f3f534937f@canb.auug.org.au>
* Stephen Rothwell <sfr@canb.auug.org.au> wrote:
> Hi Ingo,
>
> On Wed, 5 Feb 2014 07:06:33 +0100 Ingo Molnar <mingo@kernel.org> wrote:
> >
> > So, if you meant Linus to pull it, you probably want to cite a real
> > Git URI along the lines of:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git
>
> Paul provided the proper git url further down in the mail along with the
> usual pull request message (I guess he should have put that bit at the
> top).
Yeah, indeed, and it even comes with a signed tag, which is an extra
nice touch:
git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux.git tags/init-cleanup
(I guess the https was mentioned first to lower expectations.)
Thanks,
Ingo
^ permalink raw reply
* [GIT PULL] tree-wide: clean up no longer required #include <linux/init.h>
From: Stephen Rothwell @ 2014-02-05 6:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140205060633.GE30094@gmail.com>
Hi Ingo,
On Wed, 5 Feb 2014 07:06:33 +0100 Ingo Molnar <mingo@kernel.org> wrote:
>
> So, if you meant Linus to pull it, you probably want to cite a real
> Git URI along the lines of:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/paulg/init.git
Paul provided the proper git url further down in the mail along with the
usual pull request message (I guess he should have put that bit at the
top).
--
Cheers,
Stephen Rothwell sfr at canb.auug.org.au
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140205/99085ec1/attachment.sig>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox