From f479db44d2e3d4a969897e1f5e331e5ed4ac4968 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 19 Jul 2012 08:58:08 +0200 Subject: ARM: Kirkwood: Ensure runit clock always ticks. Marvell engineers tell us: It seems that many units use the RUNIT clock. SPI, UART, NAND, TWSI, ... So it's not possible to clock gate it. Currently the SPI, NAND and TWSI driver will clk_prepaure_enable() this clk, but since we have no idea what ... is, and turning this clk off results in a hard lock, unconditionally enable runit. Signed-off-by: Andrew Lunn Tested-by: Simon Baatz --- arch/arm/mach-kirkwood/common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index f261cd242643..3de2d6df58e1 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -241,6 +241,11 @@ void __init kirkwood_clk_init(void) orion_clkdev_add("0", "pcie", pex0); orion_clkdev_add("1", "pcie", pex1); orion_clkdev_add(NULL, "kirkwood-i2s", audio); + + /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., + * so should never be gated. + */ + clk_prepare_enable(runit); } /***************************************************************************** -- cgit v1.2.1 From b5409430ffaef1ed282d20cab868ee692df6dbff Mon Sep 17 00:00:00 2001 From: Simon Baatz Date: Fri, 6 Jul 2012 20:42:38 +0200 Subject: ARM: Kirkwood: Fix PHY disable clk problems Commit 98d9986 (ARM: Kirkwood: Replace clock gating) and the fix 5fb2ce (ARM: Kirkwood: clk_register_gate_fn: add fn assignment) introduced a custom variant of clock gating which allows to define a function to be called before gating the clock off. This is used to disable the SATA and PCIe PHYs if the respective clocks are unused after initialization. However, of these two drivers, the SATA driver may be compiled as a module. The driver re-enables the clocks at module init but the PHYs stay disabled. Since the custom clock gating disabled the PHYs when gating the clock off, it should also re-enable them when enabling the clock gate. This is done by adding a second function that may be used to enable the PHYs. Signed-off-by: Simon Baatz Signed-off-by: Andrew Lunn --- arch/arm/mach-kirkwood/common.c | 65 +++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 3de2d6df58e1..c9201539ffbd 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -67,6 +67,14 @@ void __init kirkwood_map_io(void) * CLK tree ****************************************************************************/ +static void enable_sata0(void) +{ + /* Enable PLL and IVREF */ + writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2); + /* Enable PHY */ + writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL); +} + static void disable_sata0(void) { /* Disable PLL and IVREF */ @@ -75,6 +83,14 @@ static void disable_sata0(void) writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); } +static void enable_sata1(void) +{ + /* Enable PLL and IVREF */ + writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2); + /* Enable PHY */ + writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL); +} + static void disable_sata1(void) { /* Disable PLL and IVREF */ @@ -107,23 +123,38 @@ static void disable_pcie1(void) } } -/* An extended version of the gated clk. This calls fn() before - * disabling the clock. We use this to turn off PHYs etc. */ +/* An extended version of the gated clk. This calls fn_en()/fn_dis + * before enabling/disabling the clock. We use this to turn on/off + * PHYs etc. */ struct clk_gate_fn { struct clk_gate gate; - void (*fn)(void); + void (*fn_en)(void); + void (*fn_dis)(void); }; #define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) #define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) +static int clk_gate_fn_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); + int ret; + + ret = clk_gate_ops.enable(hw); + if (!ret && gate_fn->fn_en) + gate_fn->fn_en(); + + return ret; +} + static void clk_gate_fn_disable(struct clk_hw *hw) { struct clk_gate *gate = to_clk_gate(hw); struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); - if (gate_fn->fn) - gate_fn->fn(); + if (gate_fn->fn_dis) + gate_fn->fn_dis(); clk_gate_ops.disable(hw); } @@ -135,7 +166,7 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, const char *parent_name, unsigned long flags, void __iomem *reg, u8 bit_idx, u8 clk_gate_flags, spinlock_t *lock, - void (*fn)(void)) + void (*fn_en)(void), void (*fn_dis)(void)) { struct clk_gate_fn *gate_fn; struct clk *clk; @@ -159,11 +190,14 @@ static struct clk __init *clk_register_gate_fn(struct device *dev, gate_fn->gate.flags = clk_gate_flags; gate_fn->gate.lock = lock; gate_fn->gate.hw.init = &init; - gate_fn->fn = fn; + gate_fn->fn_en = fn_en; + gate_fn->fn_dis = fn_dis; - /* ops is the gate ops, but with our disable function */ - if (clk_gate_fn_ops.disable != clk_gate_fn_disable) { + /* ops is the gate ops, but with our enable/disable functions */ + if (clk_gate_fn_ops.enable != clk_gate_fn_enable || + clk_gate_fn_ops.disable != clk_gate_fn_disable) { clk_gate_fn_ops = clk_gate_ops; + clk_gate_fn_ops.enable = clk_gate_fn_enable; clk_gate_fn_ops.disable = clk_gate_fn_disable; } @@ -187,11 +221,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) static struct clk __init *kirkwood_register_gate_fn(const char *name, u8 bit_idx, - void (*fn)(void)) + void (*fn_en)(void), + void (*fn_dis)(void)) { return clk_register_gate_fn(NULL, name, "tclk", 0, (void __iomem *)CLOCK_GATING_CTRL, - bit_idx, 0, &gating_lock, fn); + bit_idx, 0, &gating_lock, fn_en, fn_dis); } static struct clk *ge0, *ge1; @@ -208,18 +243,18 @@ void __init kirkwood_clk_init(void) ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, - disable_sata0); + enable_sata0, disable_sata0); sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, - disable_sata1); + enable_sata1, disable_sata1); usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, - disable_pcie0); + NULL, disable_pcie0); pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, - disable_pcie1); + NULL, disable_pcie1); audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); kirkwood_register_gate("tdm", CGC_BIT_TDM); kirkwood_register_gate("tsu", CGC_BIT_TSU); -- cgit v1.2.1 From 30e0f58035073c895a8d33e1521e412be73e02bc Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 12 Jun 2012 15:59:45 +0200 Subject: ARM: Dove: Fixup ge00 initialisation The last argument of orion_ge00_init() is actually the error interrupt, so we should be using the correct value here. Signed-off-by: Hannes Reinecke Signed-off-by: Andrew Lunn --- arch/arm/mach-dove/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 9493076fc594..4db5de54b6a7 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -101,8 +101,8 @@ void __init dove_ehci1_init(void) ****************************************************************************/ void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data) { - orion_ge00_init(eth_data, - DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0); + orion_ge00_init(eth_data, DOVE_GE00_PHYS_BASE, + IRQ_DOVE_GE00_SUM, IRQ_DOVE_GE00_ERR); } /***************************************************************************** -- cgit v1.2.1 From baffab28b13120694fa3ebab08d3e99667a851d2 Mon Sep 17 00:00:00 2001 From: Simon Baatz Date: Thu, 19 Jul 2012 00:04:09 +0200 Subject: ARM: Orion: fix driver probe error handling with respect to clk The clk patches added code to get and enable clocks in the respective driver probe functions. If the probe function failed for some reason after enabling the clock, the clock was not disabled again in many cases. Signed-off-by: Simon Baatz Signed-off-by: Andrew Lumm --- drivers/crypto/mv_cesa.c | 4 ++++ drivers/mmc/host/mvsdio.c | 4 ++++ drivers/mtd/nand/orion_nand.c | 4 ++++ drivers/net/ethernet/marvell/mv643xx_eth.c | 6 ++++++ drivers/usb/host/ehci-orion.c | 4 ++++ sound/soc/kirkwood/kirkwood-i2s.c | 8 +++++++- 6 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 1cc6b3f3e262..a4faa893199c 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -1098,6 +1098,10 @@ err_unreg_ecb: crypto_unregister_alg(&mv_aes_alg_ecb); err_irq: free_irq(irq, cp); + if (!IS_ERR(cp->clk)) { + clk_disable_unprepare(cp->clk); + clk_put(cp->clk); + } err_thread: kthread_stop(cp->queue_th); err_unmap_sram: diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index 3b9136c1a475..a61cb5fca22d 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -839,6 +839,10 @@ out: if (r) release_resource(r); if (mmc) + if (!IS_ERR_OR_NULL(host->clk)) { + clk_disable_unprepare(host->clk); + clk_put(host->clk); + } mmc_free_host(mmc); return ret; diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 513dc88a05ca..9b8fd3d77168 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -183,6 +183,10 @@ static int __init orion_nand_probe(struct platform_device *pdev) return 0; no_dev: + if (!IS_ERR(clk)) { + clk_disable_unprepare(clk); + clk_put(clk); + } platform_set_drvdata(pdev, NULL); iounmap(io_base); no_res: diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index f0f06b2bc28b..4fbba57b8ff4 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -2983,6 +2983,12 @@ static int mv643xx_eth_probe(struct platform_device *pdev) return 0; out: +#if defined(CONFIG_HAVE_CLK) + if (!IS_ERR(mp->clk)) { + clk_disable_unprepare(mp->clk); + clk_put(mp->clk); + } +#endif free_netdev(dev); return err; diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 82de1073aa52..c6903e3af29c 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -298,6 +298,10 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) err4: usb_put_hcd(hcd); err3: + if (!IS_ERR(clk)) { + clk_disable_unprepare(clk); + clk_put(clk); + } iounmap(regs); err2: release_mem_region(res->start, resource_size(res)); diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index fa4556750451..7646dd7f30cb 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c @@ -458,7 +458,13 @@ static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) } clk_prepare_enable(priv->clk); - return snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); + err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); + if (!err) + return 0; + dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); + + clk_disable_unprepare(priv->clk); + clk_put(priv->clk); err_ioremap: iounmap(priv->io); -- cgit v1.2.1 From 778435045a416da71f1757a80e37200a5ea5af70 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Wed, 18 Jul 2012 19:22:54 +0200 Subject: ARM: Kirkwood: Replace mrvl with marvell It has been decided to use marvell, not mrvl, in the compatibility property. Search & replace. Signed-off-by: Andrew Lunn --- Documentation/devicetree/bindings/mtd/orion-nand.txt | 4 ++-- arch/arm/boot/dts/kirkwood-dns320.dts | 2 +- arch/arm/boot/dts/kirkwood-dns325.dts | 2 +- arch/arm/boot/dts/kirkwood-dreamplug.dts | 2 +- arch/arm/boot/dts/kirkwood-ib62x0.dts | 2 +- arch/arm/boot/dts/kirkwood-iconnect.dts | 2 +- arch/arm/boot/dts/kirkwood.dtsi | 6 +++--- drivers/mtd/nand/orion_nand.c | 2 +- drivers/rtc/rtc-mv.c | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/devicetree/bindings/mtd/orion-nand.txt b/Documentation/devicetree/bindings/mtd/orion-nand.txt index b2356b7d2fa4..2d6ab660e603 100644 --- a/Documentation/devicetree/bindings/mtd/orion-nand.txt +++ b/Documentation/devicetree/bindings/mtd/orion-nand.txt @@ -1,7 +1,7 @@ NAND support for Marvell Orion SoC platforms Required properties: -- compatible : "mrvl,orion-nand". +- compatible : "marvell,orion-nand". - reg : Base physical address of the NAND and length of memory mapped region @@ -24,7 +24,7 @@ nand@f4000000 { ale = <1>; bank-width = <1>; chip-delay = <25>; - compatible = "mrvl,orion-nand"; + compatible = "marvell,orion-nand"; reg = <0xf4000000 0x400>; partition@0 { diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts index dc09a735b04a..9a33077130e8 100644 --- a/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/arch/arm/boot/dts/kirkwood-dns320.dts @@ -4,7 +4,7 @@ / { model = "D-Link DNS-320 NAS (Rev A1)"; - compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; + compatible = "dlink,dns-320-a1", "dlink,dns-320", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; memory { device_type = "memory"; diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts index c2a5562525d2..16734c1b5dfe 100644 --- a/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/arch/arm/boot/dts/kirkwood-dns325.dts @@ -4,7 +4,7 @@ / { model = "D-Link DNS-325 NAS (Rev A1)"; - compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; + compatible = "dlink,dns-325-a1", "dlink,dns-325", "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; memory { device_type = "memory"; diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index a5376b84227f..78b0f06a09a2 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -4,7 +4,7 @@ / { model = "Globalscale Technologies Dreamplug"; - compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; + compatible = "globalscale,dreamplug-003-ds2001", "globalscale,dreamplug", "marvell,kirkwood-88f6281", "marvell,kirkwood"; memory { device_type = "memory"; diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index ada0f0c23085..f59dcf6dc45f 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts @@ -4,7 +4,7 @@ / { model = "RaidSonic ICY BOX IB-NAS62x0 (Rev B)"; - compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; + compatible = "raidsonic,ib-nas6210-b", "raidsonic,ib-nas6220-b", "raidsonic,ib-nas6210", "raidsonic,ib-nas6220", "raidsonic,ib-nas62x0", "marvell,kirkwood-88f6281", "marvell,kirkwood"; memory { device_type = "memory"; diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 1ba75d4adecc..026a1f82d813 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts @@ -4,7 +4,7 @@ / { model = "Iomega Iconnect"; - compatible = "iom,iconnect-1.1", "iom,iconnect", "mrvl,kirkwood-88f6281", "mrvl,kirkwood"; + compatible = "iom,iconnect-1.1", "iom,iconnect", "marvell,kirkwood-88f6281", "marvell,kirkwood"; memory { device_type = "memory"; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 926528b81baa..f95dbc190ab6 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -1,7 +1,7 @@ /include/ "skeleton.dtsi" / { - compatible = "mrvl,kirkwood"; + compatible = "marvell,kirkwood"; ocp@f1000000 { compatible = "simple-bus"; @@ -28,7 +28,7 @@ }; rtc@10300 { - compatible = "mrvl,kirkwood-rtc", "mrvl,orion-rtc"; + compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc"; reg = <0x10300 0x20>; interrupts = <53>; }; @@ -39,7 +39,7 @@ cle = <0>; ale = <1>; bank-width = <1>; - compatible = "mrvl,orion-nand"; + compatible = "marvell,orion-nand"; reg = <0x3000000 0x400>; chip-delay = <25>; /* set partition map and/or chip-delay in board dts */ diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 9b8fd3d77168..fc5a868c436e 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -218,7 +218,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev) #ifdef CONFIG_OF static struct of_device_id orion_nand_of_match_table[] = { - { .compatible = "mrvl,orion-nand", }, + { .compatible = "marvell,orion-nand", }, {}, }; #endif diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index b2185f4255aa..ebc1649d45d6 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -297,7 +297,7 @@ static int __exit mv_rtc_remove(struct platform_device *pdev) #ifdef CONFIG_OF static struct of_device_id rtc_mv_of_match_table[] = { - { .compatible = "mrvl,orion-rtc", }, + { .compatible = "marvell,orion-rtc", }, {} }; #endif -- cgit v1.2.1