From 2f129bf4aab684bef1e82e747b709a5025ecb698 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 15 Dec 2011 08:15:07 +0100 Subject: [PATCH 01/16] ARM: Orion: Add clocks using the generic clk infrastructure. Add tclk as a fixed rate clock for all platforms. In addition, on kirkwood, add a gated clock for most of the clocks which can be gated. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin [mturquette@linaro.org: removed redundant CLKDEV_LOOKUP from Kconfig] [mturquette@linaro.org: removed redundant clk.h from mach-dove/common.c] Signed-off-by: Mike Turquette --- arch/arm/Kconfig | 1 + arch/arm/mach-dove/common.c | 22 +++++++--- arch/arm/mach-kirkwood/board-dt.c | 3 ++ arch/arm/mach-kirkwood/common.c | 41 +++++++++++++++++++ arch/arm/mach-kirkwood/common.h | 1 + .../mach-kirkwood/include/mach/bridge-regs.h | 16 ++++++++ arch/arm/mach-mv78xx0/common.c | 27 ++++++++---- arch/arm/mach-orion5x/common.c | 15 +++++++ arch/arm/plat-orion/common.c | 2 + 9 files changed, 115 insertions(+), 13 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index cf006d40342c..9be624af131f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1139,6 +1139,7 @@ config PLAT_ORION bool select CLKSRC_MMIO select GENERIC_IRQ_CHIP + select COMMON_CLK config PLAT_PXA bool diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index bda7aca04ca0..63fe6e612e98 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include #include @@ -67,6 +67,17 @@ void __init dove_map_io(void) iotable_init(dove_io_desc, ARRAY_SIZE(dove_io_desc)); } +/***************************************************************************** + * CLK tree + ****************************************************************************/ +static struct clk *tclk; + +static void __init clk_init(void) +{ + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, + get_tclk()); +} + /***************************************************************************** * EHCI0 ****************************************************************************/ @@ -272,18 +283,17 @@ void __init dove_sdio1_init(void) void __init dove_init(void) { - int tclk; - - tclk = get_tclk(); - printk(KERN_INFO "Dove 88AP510 SoC, "); - printk(KERN_INFO "TCLK = %dMHz\n", (tclk + 499999) / 1000000); + printk(KERN_INFO "TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000); #ifdef CONFIG_CACHE_TAUROS2 tauros2_init(); #endif dove_setup_cpu_mbus(); + /* Setup root of clk tree */ + clk_init(); + /* internal devices that every board has */ dove_rtc_init(); dove_xor0_init(); diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 1c672d9e6656..87856b5a397d 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -42,6 +42,9 @@ static void __init kirkwood_dt_init(void) kirkwood_l2_init(); #endif + /* Setup root of clk tree */ + kirkwood_clk_init(); + /* internal devices that every board has */ kirkwood_wdt_init(); kirkwood_xor0_init(); diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index a02cae881f2f..57b8d1ef3093 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -31,6 +33,7 @@ #include #include #include +#include #include "common.h" /***************************************************************************** @@ -68,6 +71,41 @@ void __init kirkwood_map_io(void) unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED; +/***************************************************************************** + * CLK tree + ****************************************************************************/ +static DEFINE_SPINLOCK(gating_lock); +static struct clk *tclk; + +static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) +{ + return clk_register_gate(NULL, name, "tclk", CLK_IGNORE_UNUSED, + (void __iomem *)CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock); +} + +void __init kirkwood_clk_init(void) +{ + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, + CLK_IS_ROOT, kirkwood_tclk); + + kirkwood_register_gate("runit", CGC_BIT_RUNIT); + kirkwood_register_gate("ge0", CGC_BIT_GE0); + kirkwood_register_gate("ge1", CGC_BIT_GE1); + kirkwood_register_gate("sata0", CGC_BIT_SATA0); + kirkwood_register_gate("sata1", CGC_BIT_SATA1); + kirkwood_register_gate("usb0", CGC_BIT_USB0); + kirkwood_register_gate("sdio", CGC_BIT_SDIO); + kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); + kirkwood_register_gate("xor0", CGC_BIT_XOR0); + kirkwood_register_gate("xor1", CGC_BIT_XOR1); + kirkwood_register_gate("pex0", CGC_BIT_PEX0); + kirkwood_register_gate("pex1", CGC_BIT_PEX1); + kirkwood_register_gate("audio", CGC_BIT_AUDIO); + kirkwood_register_gate("tdm", CGC_BIT_TDM); + kirkwood_register_gate("tsu", CGC_BIT_TSU); +} + /***************************************************************************** * EHCI0 ****************************************************************************/ @@ -465,6 +503,9 @@ void __init kirkwood_init(void) kirkwood_l2_init(); #endif + /* Setup root of clk tree */ + kirkwood_clk_init(); + /* internal devices that every board has */ kirkwood_rtc_init(); kirkwood_wdt_init(); diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index fa8e7689c436..0729b11a3e2a 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -50,6 +50,7 @@ void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, int (*dev_ready)(struct mtd_info *)); void kirkwood_audio_init(void); void kirkwood_restart(char, const char *); +void kirkwood_clk_init(void); /* board init functions for boards not fully converted to fdt */ #ifdef CONFIG_MACH_DREAMPLUG_DT diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 957bd7997d7e..3eee37a3b501 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -43,6 +43,22 @@ #define L2_WRITETHROUGH 0x00000010 #define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE | 0x11c) +#define CGC_BIT_GE0 (0) +#define CGC_BIT_PEX0 (2) +#define CGC_BIT_USB0 (3) +#define CGC_BIT_SDIO (4) +#define CGC_BIT_TSU (5) +#define CGC_BIT_DUNIT (6) +#define CGC_BIT_RUNIT (7) +#define CGC_BIT_XOR0 (8) +#define CGC_BIT_AUDIO (9) +#define CGC_BIT_SATA0 (14) +#define CGC_BIT_SATA1 (15) +#define CGC_BIT_XOR1 (16) +#define CGC_BIT_CRYPTO (17) +#define CGC_BIT_PEX1 (18) +#define CGC_BIT_GE1 (19) +#define CGC_BIT_TDM (20) #define CGC_GE0 (1 << 0) #define CGC_PEX0 (1 << 2) #define CGC_USB0 (1 << 3) diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index a5dcf766a3f9..73733207f5a9 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -103,24 +104,24 @@ static void get_pclk_l2clk(int hclk, int core_index, int *pclk, int *l2clk) static int get_tclk(void) { - int tclk; + int tclk_freq; /* * TCLK tick rate is configured by DEV_A[2:0] strap pins. */ switch ((readl(SAMPLE_AT_RESET_HIGH) >> 6) & 7) { case 1: - tclk = 166666667; + tclk_freq = 166666667; break; case 3: - tclk = 200000000; + tclk_freq = 200000000; break; default: panic("unknown TCLK PLL setting: %.8x\n", readl(SAMPLE_AT_RESET_HIGH)); } - return tclk; + return tclk_freq; } @@ -165,6 +166,17 @@ void __init mv78xx0_map_io(void) } +/***************************************************************************** + * CLK tree + ****************************************************************************/ +static struct clk *tclk; + +static void __init clk_init(void) +{ + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, + get_tclk()); +} + /***************************************************************************** * EHCI ****************************************************************************/ @@ -378,25 +390,26 @@ void __init mv78xx0_init(void) int hclk; int pclk; int l2clk; - int tclk; core_index = mv78xx0_core_index(); hclk = get_hclk(); get_pclk_l2clk(hclk, core_index, &pclk, &l2clk); - tclk = get_tclk(); printk(KERN_INFO "%s ", mv78xx0_id()); printk("core #%d, ", core_index); printk("PCLK = %dMHz, ", (pclk + 499999) / 1000000); printk("L2 = %dMHz, ", (l2clk + 499999) / 1000000); printk("HCLK = %dMHz, ", (hclk + 499999) / 1000000); - printk("TCLK = %dMHz\n", (tclk + 499999) / 1000000); + printk("TCLK = %dMHz\n", (get_tclk() + 499999) / 1000000); mv78xx0_setup_cpu_mbus(); #ifdef CONFIG_CACHE_FEROCEON_L2 feroceon_l2_init(is_l2_writethrough()); #endif + + /* Setup root of clk tree */ + clk_init(); } void mv78xx0_restart(char mode, const char *cmd) diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 24481666d2cd..81660522c6b4 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,17 @@ void __init orion5x_map_io(void) } +/***************************************************************************** + * CLK tree + ****************************************************************************/ +static struct clk *tclk; + +static void __init clk_init(void) +{ + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, + orion5x_tclk); +} + /***************************************************************************** * EHCI0 ****************************************************************************/ @@ -276,6 +288,9 @@ void __init orion5x_init(void) */ orion5x_setup_cpu_mbus_bridge(); + /* Setup root of clk tree */ + clk_init(); + /* * Don't issue "Wait for Interrupt" instruction if we are * running on D0 5281 silicon. diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 74daf5ed1432..4fdd2e7e74a1 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include From 4574b886698dfad6209102fed6136622b5fe1c21 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 6 Apr 2012 17:17:26 +0200 Subject: [PATCH 02/16] ARM: Orion: SPI: Add clk/clkdev support. Remove now redundant tclk from SPI platform data. This makes the platform data empty, so remove it. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-dove/common.c | 6 ++- arch/arm/mach-dove/dove-db-setup.c | 1 - arch/arm/mach-kirkwood/board-dreamplug.c | 1 - arch/arm/mach-kirkwood/common.c | 10 ++++- .../arm/mach-kirkwood/mv88f6281gtw_ge-setup.c | 1 - arch/arm/mach-kirkwood/rd88f6192-nas-setup.c | 1 - arch/arm/mach-kirkwood/t5325-setup.c | 1 - arch/arm/mach-kirkwood/tsx1x-common.c | 1 - arch/arm/mach-mv78xx0/common.c | 2 + arch/arm/mach-orion5x/common.c | 4 +- arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c | 1 - arch/arm/plat-orion/common.c | 38 +++++++++++-------- arch/arm/plat-orion/include/plat/common.h | 11 ++++-- drivers/spi/spi-orion.c | 30 +++++++++++---- include/linux/spi/orion_spi.h | 17 --------- 15 files changed, 70 insertions(+), 55 deletions(-) delete mode 100644 include/linux/spi/orion_spi.h diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 63fe6e612e98..da5b4047464d 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -76,6 +76,8 @@ static void __init clk_init(void) { tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, get_tclk()); + + orion_clkdev_init(tclk); } /***************************************************************************** @@ -162,12 +164,12 @@ void __init dove_uart3_init(void) ****************************************************************************/ void __init dove_spi0_init(void) { - orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk()); + orion_spi_init(DOVE_SPI0_PHYS_BASE); } void __init dove_spi1_init(void) { - orion_spi_1_init(DOVE_SPI1_PHYS_BASE, get_tclk()); + orion_spi_1_init(DOVE_SPI1_PHYS_BASE); } /***************************************************************************** diff --git a/arch/arm/mach-dove/dove-db-setup.c b/arch/arm/mach-dove/dove-db-setup.c index ea77ae430b2d..bc2867f11346 100644 --- a/arch/arm/mach-dove/dove-db-setup.c +++ b/arch/arm/mach-dove/dove-db-setup.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c index 985453994dd3..55e357ab2923 100644 --- a/arch/arm/mach-kirkwood/board-dreamplug.c +++ b/arch/arm/mach-kirkwood/board-dreamplug.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 57b8d1ef3093..476e0b941db7 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -86,10 +86,12 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { + struct clk *runit; + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); - kirkwood_register_gate("runit", CGC_BIT_RUNIT); + runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); kirkwood_register_gate("ge0", CGC_BIT_GE0); kirkwood_register_gate("ge1", CGC_BIT_GE1); kirkwood_register_gate("sata0", CGC_BIT_SATA0); @@ -104,6 +106,10 @@ void __init kirkwood_clk_init(void) kirkwood_register_gate("audio", CGC_BIT_AUDIO); kirkwood_register_gate("tdm", CGC_BIT_TDM); kirkwood_register_gate("tsu", CGC_BIT_TSU); + + /* clkdev entries, mapping clks to devices */ + orion_clkdev_add(NULL, "orion_spi.0", runit); + orion_clkdev_add(NULL, "orion_spi.1", runit); } /***************************************************************************** @@ -270,7 +276,7 @@ void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) void __init kirkwood_spi_init() { kirkwood_clk_ctrl |= CGC_RUNIT; - orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk); + orion_spi_init(SPI_PHYS_BASE); } diff --git a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c index 85f6169c2484..6d8364a97810 100644 --- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c +++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c index fd2c9c8b6831..f742a66a7045 100644 --- a/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6192-nas-setup.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-kirkwood/t5325-setup.c b/arch/arm/mach-kirkwood/t5325-setup.c index f9d2a11b7f96..bad738e44044 100644 --- a/arch/arm/mach-kirkwood/t5325-setup.c +++ b/arch/arm/mach-kirkwood/t5325-setup.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-kirkwood/tsx1x-common.c b/arch/arm/mach-kirkwood/tsx1x-common.c index 24294b2bc469..8943ede29b44 100644 --- a/arch/arm/mach-kirkwood/tsx1x-common.c +++ b/arch/arm/mach-kirkwood/tsx1x-common.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include "common.h" diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index 73733207f5a9..4c24b46520aa 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -175,6 +175,8 @@ static void __init clk_init(void) { tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, get_tclk()); + + orion_clkdev_init(tclk); } /***************************************************************************** diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 81660522c6b4..2ef82e2f511d 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -79,6 +79,8 @@ static void __init clk_init(void) { tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, orion5x_tclk); + + orion_clkdev_init(tclk); } /***************************************************************************** @@ -144,7 +146,7 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) ****************************************************************************/ void __init orion5x_spi_init() { - orion_spi_init(SPI_PHYS_BASE, orion5x_tclk); + orion_spi_init(SPI_PHYS_BASE); } diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c index 2c5fab00d205..7b97a9a211ed 100644 --- a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c +++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index 4fdd2e7e74a1..bbe50a948710 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -19,12 +19,32 @@ #include #include #include -#include #include #include #include #include +/* Create a clkdev entry for a given device/clk */ +void __init orion_clkdev_add(const char *con_id, const char *dev_id, + struct clk *clk) +{ + struct clk_lookup *cl; + + cl = clkdev_alloc(clk, con_id, dev_id); + if (cl) + clkdev_add(cl); +} + +/* Create clkdev entries for all orion platforms except kirkwood. + Kirkwood has gated clocks for some of its peripherals, so creates + its own clkdev entries. For all the other orion devices, create + clkdev entries to the tclk. */ +void __init orion_clkdev_init(struct clk *tclk) +{ + orion_clkdev_add(NULL, "orion_spi.0", tclk); + orion_clkdev_add(NULL, "orion_spi.1", tclk); +} + /* Fill in the resources structure and link it into the platform device structure. There is always a memory region, and nearly always an interrupt.*/ @@ -523,44 +543,32 @@ void __init orion_i2c_1_init(unsigned long mapbase, /***************************************************************************** * SPI ****************************************************************************/ -static struct orion_spi_info orion_spi_plat_data; static struct resource orion_spi_resources; static struct platform_device orion_spi = { .name = "orion_spi", .id = 0, - .dev = { - .platform_data = &orion_spi_plat_data, - }, }; -static struct orion_spi_info orion_spi_1_plat_data; static struct resource orion_spi_1_resources; static struct platform_device orion_spi_1 = { .name = "orion_spi", .id = 1, - .dev = { - .platform_data = &orion_spi_1_plat_data, - }, }; /* Note: The SPI silicon core does have interrupts. However the * current Linux software driver does not use interrupts. */ -void __init orion_spi_init(unsigned long mapbase, - unsigned long tclk) +void __init orion_spi_init(unsigned long mapbase) { - orion_spi_plat_data.tclk = tclk; fill_resources(&orion_spi, &orion_spi_resources, mapbase, SZ_512 - 1, NO_IRQ); platform_device_register(&orion_spi); } -void __init orion_spi_1_init(unsigned long mapbase, - unsigned long tclk) +void __init orion_spi_1_init(unsigned long mapbase) { - orion_spi_1_plat_data.tclk = tclk; fill_resources(&orion_spi_1, &orion_spi_1_resources, mapbase, SZ_512 - 1, NO_IRQ); platform_device_register(&orion_spi_1); diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index a7fa005a5a0e..d188a1aa6f56 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -70,11 +70,9 @@ void __init orion_i2c_1_init(unsigned long mapbase, unsigned long irq, unsigned long freq_m); -void __init orion_spi_init(unsigned long mapbase, - unsigned long tclk); +void __init orion_spi_init(unsigned long mapbase); -void __init orion_spi_1_init(unsigned long mapbase, - unsigned long tclk); +void __init orion_spi_1_init(unsigned long mapbase); void __init orion_wdt_init(unsigned long tclk); @@ -106,4 +104,9 @@ void __init orion_crypto_init(unsigned long mapbase, unsigned long srambase, unsigned long sram_size, unsigned long irq); + +void __init orion_clkdev_add(const char *con_id, const char *dev_id, + struct clk *clk); + +void __init orion_clkdev_init(struct clk *tclk); #endif diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index e496f799b7a9..dfd04e91fa6d 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -16,8 +16,8 @@ #include #include #include -#include #include +#include #include #define DRIVER_NAME "orion_spi" @@ -46,6 +46,7 @@ struct orion_spi { unsigned int max_speed; unsigned int min_speed; struct orion_spi_info *spi_info; + struct clk *clk; }; static struct workqueue_struct *orion_spi_wq; @@ -104,7 +105,7 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed) orion_spi = spi_master_get_devdata(spi->master); - tclk_hz = orion_spi->spi_info->tclk; + tclk_hz = clk_get_rate(orion_spi->clk); /* * the supported rates are: 4,6,8...30 @@ -450,6 +451,7 @@ static int __init orion_spi_probe(struct platform_device *pdev) struct orion_spi *spi; struct resource *r; struct orion_spi_info *spi_info; + unsigned long tclk_hz; int status = 0; spi_info = pdev->dev.platform_data; @@ -476,19 +478,28 @@ static int __init orion_spi_probe(struct platform_device *pdev) spi->master = master; spi->spi_info = spi_info; - spi->max_speed = DIV_ROUND_UP(spi_info->tclk, 4); - spi->min_speed = DIV_ROUND_UP(spi_info->tclk, 30); + spi->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(spi->clk)) { + status = PTR_ERR(spi->clk); + goto out; + } + + clk_prepare(spi->clk); + clk_enable(spi->clk); + tclk_hz = clk_get_rate(spi->clk); + spi->max_speed = DIV_ROUND_UP(tclk_hz, 4); + spi->min_speed = DIV_ROUND_UP(tclk_hz, 30); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { status = -ENODEV; - goto out; + goto out_rel_clk; } if (!request_mem_region(r->start, resource_size(r), dev_name(&pdev->dev))) { status = -EBUSY; - goto out; + goto out_rel_clk; } spi->base = ioremap(r->start, SZ_1K); @@ -508,7 +519,9 @@ static int __init orion_spi_probe(struct platform_device *pdev) out_rel_mem: release_mem_region(r->start, resource_size(r)); - +out_rel_clk: + clk_disable_unprepare(spi->clk); + clk_put(spi->clk); out: spi_master_put(master); return status; @@ -526,6 +539,9 @@ static int __exit orion_spi_remove(struct platform_device *pdev) cancel_work_sync(&spi->work); + clk_disable_unprepare(spi->clk); + clk_put(spi->clk); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(r->start, resource_size(r)); diff --git a/include/linux/spi/orion_spi.h b/include/linux/spi/orion_spi.h deleted file mode 100644 index b4d9fa6f797c..000000000000 --- a/include/linux/spi/orion_spi.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * orion_spi.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __LINUX_SPI_ORION_SPI_H -#define __LINUX_SPI_ORION_SPI_H - -struct orion_spi_info { - u32 tclk; /* no support yet */ -}; - - -#endif From 452503ebc7cc4cce5b9e52cf2f03255365a53234 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 24 Dec 2011 01:24:24 +0100 Subject: [PATCH 03/16] ARM: Orion: Eth: Add clk/clkdev support. The t_clk is moved from the shared part of the ethernet driver into the per port section. Each port can have its own gated clock, which it needs to enable/disable, as oppossed to there being one clock shared by all ports. In practice, only kirkwood supports this at the moment. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-dove/common.c | 3 +- arch/arm/mach-kirkwood/common.c | 12 ++++--- arch/arm/mach-mv78xx0/common.c | 8 ++--- arch/arm/mach-orion5x/common.c | 2 +- arch/arm/plat-orion/common.c | 26 +++++++------- arch/arm/plat-orion/include/plat/common.h | 13 +++---- drivers/net/ethernet/marvell/mv643xx_eth.c | 42 ++++++++++++++++------ include/linux/mv643xx_eth.h | 1 - 8 files changed, 61 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index da5b4047464d..02766960480d 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -102,8 +102,7 @@ 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, get_tclk()); + DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM, 0); } /***************************************************************************** diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 476e0b941db7..c22354405297 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -86,14 +86,14 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { - struct clk *runit; + struct clk *runit, *ge0, *ge1; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); - kirkwood_register_gate("ge0", CGC_BIT_GE0); - kirkwood_register_gate("ge1", CGC_BIT_GE1); + ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); + ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); kirkwood_register_gate("sata0", CGC_BIT_SATA0); kirkwood_register_gate("sata1", CGC_BIT_SATA1); kirkwood_register_gate("usb0", CGC_BIT_USB0); @@ -110,6 +110,8 @@ void __init kirkwood_clk_init(void) /* clkdev entries, mapping clks to devices */ orion_clkdev_add(NULL, "orion_spi.0", runit); orion_clkdev_add(NULL, "orion_spi.1", runit); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); } /***************************************************************************** @@ -131,7 +133,7 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) orion_ge00_init(eth_data, GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, - IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk); + IRQ_KIRKWOOD_GE00_ERR); } @@ -145,7 +147,7 @@ void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) orion_ge01_init(eth_data, GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, - IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk); + IRQ_KIRKWOOD_GE01_ERR); } diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index 4c24b46520aa..ad4d037bbcd3 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -213,7 +213,7 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) { orion_ge00_init(eth_data, GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM, - IRQ_MV78XX0_GE_ERR, get_tclk()); + IRQ_MV78XX0_GE_ERR); } @@ -224,7 +224,7 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data) { orion_ge01_init(eth_data, GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM, - NO_IRQ, get_tclk()); + NO_IRQ); } @@ -248,7 +248,7 @@ void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data) orion_ge10_init(eth_data, GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM, - NO_IRQ, get_tclk()); + NO_IRQ); } @@ -272,7 +272,7 @@ void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data) orion_ge11_init(eth_data, GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM, - NO_IRQ, get_tclk()); + NO_IRQ); } /***************************************************************************** diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 2ef82e2f511d..3fc731824e9c 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -109,7 +109,7 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) { orion_ge00_init(eth_data, ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM, - IRQ_ORION5X_ETH_ERR, orion5x_tclk); + IRQ_ORION5X_ETH_ERR); } diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index bbe50a948710..a33733bb380d 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -43,6 +43,10 @@ void __init orion_clkdev_init(struct clk *tclk) { orion_clkdev_add(NULL, "orion_spi.0", tclk); orion_clkdev_add(NULL, "orion_spi.1", tclk); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", tclk); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); } /* Fill in the resources structure and link it into the platform @@ -225,13 +229,11 @@ void __init orion_rtc_init(unsigned long mapbase, ****************************************************************************/ static __init void ge_complete( struct mv643xx_eth_shared_platform_data *orion_ge_shared_data, - int tclk, struct resource *orion_ge_resource, unsigned long irq, struct platform_device *orion_ge_shared, struct mv643xx_eth_platform_data *eth_data, struct platform_device *orion_ge) { - orion_ge_shared_data->t_clk = tclk; orion_ge_resource->start = irq; orion_ge_resource->end = irq; eth_data->shared = orion_ge_shared; @@ -282,12 +284,11 @@ static struct platform_device orion_ge00 = { void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk) + unsigned long irq_err) { fill_resources(&orion_ge00_shared, orion_ge00_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge00_shared_data, tclk, + ge_complete(&orion_ge00_shared_data, orion_ge00_resources, irq, &orion_ge00_shared, eth_data, &orion_ge00); } @@ -335,12 +336,11 @@ static struct platform_device orion_ge01 = { void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk) + unsigned long irq_err) { fill_resources(&orion_ge01_shared, orion_ge01_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge01_shared_data, tclk, + ge_complete(&orion_ge01_shared_data, orion_ge01_resources, irq, &orion_ge01_shared, eth_data, &orion_ge01); } @@ -388,12 +388,11 @@ static struct platform_device orion_ge10 = { void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk) + unsigned long irq_err) { fill_resources(&orion_ge10_shared, orion_ge10_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge10_shared_data, tclk, + ge_complete(&orion_ge10_shared_data, orion_ge10_resources, irq, &orion_ge10_shared, eth_data, &orion_ge10); } @@ -441,12 +440,11 @@ static struct platform_device orion_ge11 = { void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk) + unsigned long irq_err) { fill_resources(&orion_ge11_shared, orion_ge11_shared_resources, mapbase + 0x2000, SZ_16K - 1, irq_err); - ge_complete(&orion_ge11_shared_data, tclk, + ge_complete(&orion_ge11_shared_data, orion_ge11_resources, irq, &orion_ge11_shared, eth_data, &orion_ge11); } diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index d188a1aa6f56..00d8761c7d28 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -39,29 +39,26 @@ void __init orion_rtc_init(unsigned long mapbase, void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk); + unsigned long irq_err); void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk); + unsigned long irq_err); void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk); + unsigned long irq_err); void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data, unsigned long mapbase, unsigned long irq, - unsigned long irq_err, - int tclk); + unsigned long irq_err); void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq); + void __init orion_i2c_init(unsigned long mapbase, unsigned long irq, unsigned long freq_m); diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 5e1ca0f05090..99cd233266ac 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -57,6 +57,7 @@ #include #include #include +#include static char mv643xx_eth_driver_name[] = "mv643xx_eth"; static char mv643xx_eth_driver_version[] = "1.4"; @@ -289,10 +290,10 @@ struct mv643xx_eth_shared_private { /* * Hardware-specific parameters. */ - unsigned int t_clk; int extended_rx_coal_limit; int tx_bw_control; int tx_csum_limit; + }; #define TX_BW_CONTROL_ABSENT 0 @@ -431,6 +432,12 @@ struct mv643xx_eth_private { int tx_desc_sram_size; int txq_count; struct tx_queue txq[8]; + + /* + * Hardware-specific parameters. + */ + struct clk *clk; + unsigned int t_clk; }; @@ -1010,7 +1017,7 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst) int mtu; int bucket_size; - token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); + token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); if (token_rate > 1023) token_rate = 1023; @@ -1042,7 +1049,7 @@ static void txq_set_rate(struct tx_queue *txq, int rate, int burst) int token_rate; int bucket_size; - token_rate = ((rate / 1000) * 64) / (mp->shared->t_clk / 1000); + token_rate = ((rate / 1000) * 64) / (mp->t_clk / 1000); if (token_rate > 1023) token_rate = 1023; @@ -1309,7 +1316,7 @@ static unsigned int get_rx_coal(struct mv643xx_eth_private *mp) temp = (val & 0x003fff00) >> 8; temp *= 64000000; - do_div(temp, mp->shared->t_clk); + do_div(temp, mp->t_clk); return (unsigned int)temp; } @@ -1319,7 +1326,7 @@ static void set_rx_coal(struct mv643xx_eth_private *mp, unsigned int usec) u64 temp; u32 val; - temp = (u64)usec * mp->shared->t_clk; + temp = (u64)usec * mp->t_clk; temp += 31999999; do_div(temp, 64000000); @@ -1345,7 +1352,7 @@ static unsigned int get_tx_coal(struct mv643xx_eth_private *mp) temp = (rdlp(mp, TX_FIFO_URGENT_THRESHOLD) & 0x3fff0) >> 4; temp *= 64000000; - do_div(temp, mp->shared->t_clk); + do_div(temp, mp->t_clk); return (unsigned int)temp; } @@ -1354,7 +1361,7 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int usec) { u64 temp; - temp = (u64)usec * mp->shared->t_clk; + temp = (u64)usec * mp->t_clk; temp += 31999999; do_div(temp, 64000000); @@ -2662,10 +2669,6 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) if (dram) mv643xx_eth_conf_mbus_windows(msp, dram); - /* - * Detect hardware parameters. - */ - msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; msp->tx_csum_limit = (pd != NULL && pd->tx_csum_limit) ? pd->tx_csum_limit : 9 * 1024; infer_hw_params(msp); @@ -2890,6 +2893,18 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->dev = dev; + /* + * Get the clk rate, if there is one, otherwise use the default. + */ + mp->clk = clk_get(&pdev->dev, (pdev->id ? "1" : "0")); + if (!IS_ERR(mp->clk)) { + clk_prepare_enable(mp->clk); + mp->t_clk = clk_get_rate(mp->clk); + } else { + mp->t_clk = 133000000; + printk(KERN_WARNING "Unable to get clock"); + } + set_params(mp, pd); netif_set_real_num_tx_queues(dev, mp->txq_count); netif_set_real_num_rx_queues(dev, mp->rxq_count); @@ -2978,6 +2993,11 @@ static int mv643xx_eth_remove(struct platform_device *pdev) if (mp->phy != NULL) phy_detach(mp->phy); cancel_work_sync(&mp->tx_timeout_task); + + if (!IS_ERR(mp->clk)) { + clk_disable_unprepare(mp->clk); + clk_put(mp->clk); + } free_netdev(mp->dev); platform_set_drvdata(pdev, NULL); diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 30b0c4e78f91..51bf8ada6dc0 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -18,7 +18,6 @@ struct mv643xx_eth_shared_platform_data { struct mbus_dram_target_info *dram; struct platform_device *shared_smi; - unsigned int t_clk; /* * Max packet size for Tx IP/Layer 4 checksum, when set to 0, default * limit of 9KiB will be used. From 4f04be62af95119d258b8035f498100e43c8c527 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 4 Mar 2012 16:57:31 +0100 Subject: [PATCH 04/16] ARM: Orion: WDT: Add clk/clkdev support Remove tclk from platform data. This makes the platform data structure empty, so remove it. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 3 ++- arch/arm/mach-orion5x/common.c | 2 +- arch/arm/plat-orion/common.c | 12 +++--------- arch/arm/plat-orion/include/plat/common.h | 2 +- arch/arm/plat-orion/include/plat/orion_wdt.h | 18 ------------------ drivers/watchdog/orion_wdt.c | 16 ++++++++++------ 6 files changed, 17 insertions(+), 36 deletions(-) delete mode 100644 arch/arm/plat-orion/include/plat/orion_wdt.h diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c22354405297..880f3667a2eb 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -112,6 +112,7 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, "orion_spi.1", runit); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); + orion_clkdev_add(NULL, "orion_wdt", tclk); } /***************************************************************************** @@ -351,7 +352,7 @@ void __init kirkwood_xor1_init(void) ****************************************************************************/ void __init kirkwood_wdt_init(void) { - orion_wdt_init(kirkwood_tclk); + orion_wdt_init(); } diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 3fc731824e9c..067bdd7c06dd 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -193,7 +193,7 @@ static void __init orion5x_crypto_init(void) ****************************************************************************/ void __init orion5x_wdt_init(void) { - orion_wdt_init(orion5x_tclk); + orion_wdt_init(); } diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index a33733bb380d..d349998f72e5 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -47,6 +46,7 @@ void __init orion_clkdev_init(struct clk *tclk) orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", tclk); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); + orion_clkdev_add(NULL, "orion_wdt", tclk); } /* Fill in the resources structure and link it into the platform @@ -575,24 +575,18 @@ void __init orion_spi_1_init(unsigned long mapbase) /***************************************************************************** * Watchdog ****************************************************************************/ -static struct orion_wdt_platform_data orion_wdt_data; - static struct resource orion_wdt_resource = DEFINE_RES_MEM(TIMER_VIRT_BASE, 0x28); static struct platform_device orion_wdt_device = { .name = "orion_wdt", .id = -1, - .dev = { - .platform_data = &orion_wdt_data, - }, - .resource = &orion_wdt_resource, .num_resources = 1, + .resource = &orion_wdt_resource, }; -void __init orion_wdt_init(unsigned long tclk) +void __init orion_wdt_init(void) { - orion_wdt_data.tclk = tclk; platform_device_register(&orion_wdt_device); } diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index 00d8761c7d28..c3bfa91bfaa6 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -71,7 +71,7 @@ void __init orion_spi_init(unsigned long mapbase); void __init orion_spi_1_init(unsigned long mapbase); -void __init orion_wdt_init(unsigned long tclk); +void __init orion_wdt_init(void); void __init orion_xor0_init(unsigned long mapbase_low, unsigned long mapbase_high, diff --git a/arch/arm/plat-orion/include/plat/orion_wdt.h b/arch/arm/plat-orion/include/plat/orion_wdt.h deleted file mode 100644 index 665c362a2fba..000000000000 --- a/arch/arm/plat-orion/include/plat/orion_wdt.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/arm/plat-orion/include/plat/orion_wdt.h - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#ifndef __PLAT_ORION_WDT_H -#define __PLAT_ORION_WDT_H - -struct orion_wdt_platform_data { - u32 tclk; /* no support yet */ -}; - - -#endif - diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 788aa158e78c..0f5736949c61 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include /* * Watchdog timer block registers. @@ -41,6 +41,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; static int heartbeat = -1; /* module parameter (seconds) */ static unsigned int wdt_max_duration; /* (seconds) */ +static struct clk *clk; static unsigned int wdt_tclk; static void __iomem *wdt_reg; static unsigned long wdt_status; @@ -237,16 +238,16 @@ static struct miscdevice orion_wdt_miscdev = { static int __devinit orion_wdt_probe(struct platform_device *pdev) { - struct orion_wdt_platform_data *pdata = pdev->dev.platform_data; struct resource *res; int ret; - if (pdata) { - wdt_tclk = pdata->tclk; - } else { - pr_err("misses platform data\n"); + clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + printk(KERN_ERR "Orion Watchdog missing clock\n"); return -ENODEV; } + clk_prepare_enable(clk); + wdt_tclk = clk_get_rate(clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -282,6 +283,9 @@ static int __devexit orion_wdt_remove(struct platform_device *pdev) if (!ret) orion_wdt_miscdev.parent = NULL; + clk_disable_unprepare(clk); + clk_put(clk); + return ret; } From 74c335761acdfd94736d28ba0b941a2efb9c81f0 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 24 Dec 2011 03:06:34 +0100 Subject: [PATCH 05/16] ARM: Orion: UART: Get the clock rate via clk_get_rate(). Let the machine pass to the platform which clock is used by the uart. Enable the clock and use clk_get_rate() to determine its rate. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-dove/common.c | 8 +++---- arch/arm/mach-kirkwood/common.c | 4 ++-- arch/arm/mach-mv78xx0/common.c | 8 +++---- arch/arm/mach-orion5x/common.c | 4 ++-- arch/arm/plat-orion/common.c | 26 ++++++++++++++--------- arch/arm/plat-orion/include/plat/common.h | 8 +++---- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index 02766960480d..0ab0f81b661d 100644 --- a/arch/arm/mach-dove/common.c +++ b/arch/arm/mach-dove/common.c @@ -128,7 +128,7 @@ void __init dove_sata_init(struct mv_sata_platform_data *sata_data) void __init dove_uart0_init(void) { orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE, - IRQ_DOVE_UART_0, get_tclk()); + IRQ_DOVE_UART_0, tclk); } /***************************************************************************** @@ -137,7 +137,7 @@ void __init dove_uart0_init(void) void __init dove_uart1_init(void) { orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE, - IRQ_DOVE_UART_1, get_tclk()); + IRQ_DOVE_UART_1, tclk); } /***************************************************************************** @@ -146,7 +146,7 @@ void __init dove_uart1_init(void) void __init dove_uart2_init(void) { orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE, - IRQ_DOVE_UART_2, get_tclk()); + IRQ_DOVE_UART_2, tclk); } /***************************************************************************** @@ -155,7 +155,7 @@ void __init dove_uart2_init(void) void __init dove_uart3_init(void) { orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE, - IRQ_DOVE_UART_3, get_tclk()); + IRQ_DOVE_UART_3, tclk); } /***************************************************************************** diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 880f3667a2eb..46d7b4374908 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -299,7 +299,7 @@ void __init kirkwood_i2c_init(void) void __init kirkwood_uart0_init(void) { orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, - IRQ_KIRKWOOD_UART_0, kirkwood_tclk); + IRQ_KIRKWOOD_UART_0, tclk); } @@ -309,7 +309,7 @@ void __init kirkwood_uart0_init(void) void __init kirkwood_uart1_init(void) { orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, - IRQ_KIRKWOOD_UART_1, kirkwood_tclk); + IRQ_KIRKWOOD_UART_1, tclk); } /***************************************************************************** diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index ad4d037bbcd3..b4c53b846c9c 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -299,7 +299,7 @@ void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data) void __init mv78xx0_uart0_init(void) { orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, - IRQ_MV78XX0_UART_0, get_tclk()); + IRQ_MV78XX0_UART_0, tclk); } @@ -309,7 +309,7 @@ void __init mv78xx0_uart0_init(void) void __init mv78xx0_uart1_init(void) { orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, - IRQ_MV78XX0_UART_1, get_tclk()); + IRQ_MV78XX0_UART_1, tclk); } @@ -319,7 +319,7 @@ void __init mv78xx0_uart1_init(void) void __init mv78xx0_uart2_init(void) { orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE, - IRQ_MV78XX0_UART_2, get_tclk()); + IRQ_MV78XX0_UART_2, tclk); } /***************************************************************************** @@ -328,7 +328,7 @@ void __init mv78xx0_uart2_init(void) void __init mv78xx0_uart3_init(void) { orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE, - IRQ_MV78XX0_UART_3, get_tclk()); + IRQ_MV78XX0_UART_3, tclk); } /***************************************************************************** diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 067bdd7c06dd..fd36e020d09d 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -156,7 +156,7 @@ void __init orion5x_spi_init() void __init orion5x_uart0_init(void) { orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, - IRQ_ORION5X_UART0, orion5x_tclk); + IRQ_ORION5X_UART0, tclk); } /***************************************************************************** @@ -165,7 +165,7 @@ void __init orion5x_uart0_init(void) void __init orion5x_uart1_init(void) { orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, - IRQ_ORION5X_UART1, orion5x_tclk); + IRQ_ORION5X_UART1, tclk); } /***************************************************************************** diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index d349998f72e5..61fd837624a8 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c @@ -75,6 +75,12 @@ static void fill_resources(struct platform_device *device, /***************************************************************************** * UART ****************************************************************************/ +static unsigned long __init uart_get_clk_rate(struct clk *clk) +{ + clk_prepare_enable(clk); + return clk_get_rate(clk); +} + static void __init uart_complete( struct platform_device *orion_uart, struct plat_serial8250_port *data, @@ -82,12 +88,12 @@ static void __init uart_complete( unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk) + struct clk *clk) { data->mapbase = mapbase; data->membase = (void __iomem *)membase; data->irq = irq; - data->uartclk = uartclk; + data->uartclk = uart_get_clk_rate(clk); orion_uart->dev.platform_data = data; fill_resources(orion_uart, resources, mapbase, 0xff, irq); @@ -116,10 +122,10 @@ static struct platform_device orion_uart0 = { void __init orion_uart0_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk) + struct clk *clk) { uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources, - membase, mapbase, irq, uartclk); + membase, mapbase, irq, clk); } /***************************************************************************** @@ -144,10 +150,10 @@ static struct platform_device orion_uart1 = { void __init orion_uart1_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk) + struct clk *clk) { uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources, - membase, mapbase, irq, uartclk); + membase, mapbase, irq, clk); } /***************************************************************************** @@ -172,10 +178,10 @@ static struct platform_device orion_uart2 = { void __init orion_uart2_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk) + struct clk *clk) { uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources, - membase, mapbase, irq, uartclk); + membase, mapbase, irq, clk); } /***************************************************************************** @@ -200,10 +206,10 @@ static struct platform_device orion_uart3 = { void __init orion_uart3_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk) + struct clk *clk) { uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources, - membase, mapbase, irq, uartclk); + membase, mapbase, irq, clk); } /***************************************************************************** diff --git a/arch/arm/plat-orion/include/plat/common.h b/arch/arm/plat-orion/include/plat/common.h index c3bfa91bfaa6..e00fdb213609 100644 --- a/arch/arm/plat-orion/include/plat/common.h +++ b/arch/arm/plat-orion/include/plat/common.h @@ -16,22 +16,22 @@ struct dsa_platform_data; void __init orion_uart0_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk); + struct clk *clk); void __init orion_uart1_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk); + struct clk *clk); void __init orion_uart2_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk); + struct clk *clk); void __init orion_uart3_init(unsigned int membase, resource_size_t mapbase, unsigned int irq, - unsigned int uartclk); + struct clk *clk); void __init orion_rtc_init(unsigned long mapbase, unsigned long irq); From eee989902aab45f0ca2739727ef615420802649c Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 18 Feb 2012 22:26:42 +0100 Subject: [PATCH 06/16] ARM: Orion: SATA: Add per channel clk/clkdev support. The Orion kirkwood chips have a gatable clock per SATA channel. Add code to get and enable this clk if it exists. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 8 ++++--- drivers/ata/sata_mv.c | 40 +++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 46d7b4374908..c9fef5b7c56e 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -86,7 +86,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { - struct clk *runit, *ge0, *ge1; + struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); @@ -94,8 +94,8 @@ void __init kirkwood_clk_init(void) runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); - kirkwood_register_gate("sata0", CGC_BIT_SATA0); - kirkwood_register_gate("sata1", CGC_BIT_SATA1); + sata0 = kirkwood_register_gate("sata0", CGC_BIT_SATA0); + sata1 = kirkwood_register_gate("sata1", CGC_BIT_SATA1); kirkwood_register_gate("usb0", CGC_BIT_USB0); kirkwood_register_gate("sdio", CGC_BIT_SDIO); kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); @@ -113,6 +113,8 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); orion_clkdev_add(NULL, "orion_wdt", tclk); + orion_clkdev_add("0", "sata_mv.0", sata0); + orion_clkdev_add("1", "sata_mv.0", sata1); } /***************************************************************************** diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 7336d4a7ab31..24712adf69df 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -553,6 +553,7 @@ struct mv_host_priv { #if defined(CONFIG_HAVE_CLK) struct clk *clk; + struct clk **port_clks; #endif /* * These consistent DMA memory pools give us guaranteed @@ -4027,6 +4028,9 @@ static int mv_platform_probe(struct platform_device *pdev) struct resource *res; int n_ports = 0; int rc; +#if defined(CONFIG_HAVE_CLK) + int port; +#endif ata_print_version_once(&pdev->dev, DRV_VERSION); @@ -4054,6 +4058,13 @@ static int mv_platform_probe(struct platform_device *pdev) if (!host || !hpriv) return -ENOMEM; +#if defined(CONFIG_HAVE_CLK) + hpriv->port_clks = devm_kzalloc(&pdev->dev, + sizeof(struct clk *) * n_ports, + GFP_KERNEL); + if (!hpriv->port_clks) + return -ENOMEM; +#endif host->private_data = hpriv; hpriv->n_ports = n_ports; hpriv->board_idx = chip_soc; @@ -4066,9 +4077,17 @@ static int mv_platform_probe(struct platform_device *pdev) #if defined(CONFIG_HAVE_CLK) hpriv->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(hpriv->clk)) - dev_notice(&pdev->dev, "cannot get clkdev\n"); + dev_notice(&pdev->dev, "cannot get optional clkdev\n"); else - clk_enable(hpriv->clk); + clk_prepare_enable(hpriv->clk); + + for (port = 0; port < n_ports; port++) { + char port_number[16]; + sprintf(port_number, "%d", port); + hpriv->port_clks[port] = clk_get(&pdev->dev, port_number); + if (!IS_ERR(hpriv->port_clks[port])) + clk_prepare_enable(hpriv->port_clks[port]); + } #endif /* @@ -4098,9 +4117,15 @@ static int mv_platform_probe(struct platform_device *pdev) err: #if defined(CONFIG_HAVE_CLK) if (!IS_ERR(hpriv->clk)) { - clk_disable(hpriv->clk); + clk_disable_unprepare(hpriv->clk); clk_put(hpriv->clk); } + for (port = 0; port < n_ports; port++) { + if (!IS_ERR(hpriv->port_clks[port])) { + clk_disable_unprepare(hpriv->port_clks[port]); + clk_put(hpriv->port_clks[port]); + } + } #endif return rc; @@ -4119,14 +4144,21 @@ static int __devexit mv_platform_remove(struct platform_device *pdev) struct ata_host *host = platform_get_drvdata(pdev); #if defined(CONFIG_HAVE_CLK) struct mv_host_priv *hpriv = host->private_data; + int port; #endif ata_host_detach(host); #if defined(CONFIG_HAVE_CLK) if (!IS_ERR(hpriv->clk)) { - clk_disable(hpriv->clk); + clk_disable_unprepare(hpriv->clk); clk_put(hpriv->clk); } + for (port = 0; port < host->n_ports; port++) { + if (!IS_ERR(hpriv->port_clks[port])) { + clk_disable_unprepare(hpriv->port_clks[port]); + clk_put(hpriv->port_clks[port]); + } + } #endif return 0; } From 8c869edaee07c623066266827371235fb9c12e01 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 15 Apr 2012 12:53:47 +0200 Subject: [PATCH 07/16] ARM: Orion: EHCI: Add support for enabling clocks Not all platforms support gating the clock, so it is not an error if the clock does not exist. However, if it does exist, we should enable/disable it as appropriate. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 3 ++- drivers/usb/host/ehci-orion.c | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c9fef5b7c56e..b0f20c0c7d54 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -96,7 +96,7 @@ void __init kirkwood_clk_init(void) ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); sata0 = kirkwood_register_gate("sata0", CGC_BIT_SATA0); sata1 = kirkwood_register_gate("sata1", CGC_BIT_SATA1); - kirkwood_register_gate("usb0", CGC_BIT_USB0); + usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); kirkwood_register_gate("sdio", CGC_BIT_SDIO); kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); kirkwood_register_gate("xor0", CGC_BIT_XOR0); @@ -115,6 +115,7 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, "orion_wdt", tclk); orion_clkdev_add("0", "sata_mv.0", sata0); orion_clkdev_add("1", "sata_mv.0", sata1); + orion_clkdev_add(NULL, "orion-ehci.0", usb0); } /***************************************************************************** diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 6c6a5a3b4ea7..82de1073aa52 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #define rdl(off) __raw_readl(hcd->regs + (off)) @@ -198,6 +199,7 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) struct resource *res; struct usb_hcd *hcd; struct ehci_hcd *ehci; + struct clk *clk; void __iomem *regs; int irq, err; @@ -238,6 +240,14 @@ static int __devinit ehci_orion_drv_probe(struct platform_device *pdev) goto err2; } + /* Not all platforms can gate the clock, so it is not + an error if the clock does not exists. */ + clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(clk)) { + clk_prepare_enable(clk); + clk_put(clk); + } + hcd = usb_create_hcd(&ehci_orion_hc_driver, &pdev->dev, dev_name(&pdev->dev)); if (!hcd) { @@ -301,12 +311,18 @@ err1: static int __exit ehci_orion_drv_remove(struct platform_device *pdev) { struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct clk *clk; usb_remove_hcd(hcd); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); usb_put_hcd(hcd); + clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(clk)) { + clk_disable_unprepare(clk); + clk_put(clk); + } return 0; } From 9c2bd504b55ce3e680ae0d3768e78c15fef3448d Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 11:01:22 +0100 Subject: [PATCH 08/16] ARM: Orion: NAND: Add support for clk, if there is one. Not all orion platforms can gate the clock, but if it does exist, enable/disable it as appropriate. v2: Fix the name of the clkdev entry. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 1 + drivers/mtd/nand/orion_nand.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b0f20c0c7d54..99adebce7073 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -116,6 +116,7 @@ void __init kirkwood_clk_init(void) orion_clkdev_add("0", "sata_mv.0", sata0); orion_clkdev_add("1", "sata_mv.0", sata1); orion_clkdev_add(NULL, "orion-ehci.0", usb0); + orion_clkdev_add(NULL, "orion_nand", runit); } /***************************************************************************** diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 1d3bfb26080c..fdc4786ea3e5 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -77,6 +79,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) struct nand_chip *nc; struct orion_nand_data *board; struct resource *res; + struct clk *clk; void __iomem *io_base; int ret = 0; @@ -123,6 +126,14 @@ static int __init orion_nand_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mtd); + /* Not all platforms can gate the clock, so it is not + an error if the clock does not exists. */ + clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(clk)) { + clk_prepare_enable(clk); + clk_put(clk); + } + if (nand_scan(mtd, 1)) { ret = -ENXIO; goto no_dev; @@ -151,6 +162,7 @@ static int __devexit orion_nand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); struct nand_chip *nc = mtd->priv; + struct clk *clk; nand_release(mtd); @@ -158,6 +170,12 @@ static int __devexit orion_nand_remove(struct platform_device *pdev) kfree(nc); + clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(clk)) { + clk_disable_unprepare(clk); + clk_put(clk); + } + return 0; } From f4f7561e032777cd7376800ac97352d5b1684d8f Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 11:39:27 +0100 Subject: [PATCH 09/16] ARM: Orion: SDIO: Add support for clk. Some orion devices can gate the SDIO clock. If the clock exists, enable/disable it as appropriate. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 5 +++-- drivers/mmc/host/mvsdio.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 99adebce7073..88a1667af4c3 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -86,7 +86,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { - struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0; + struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); @@ -97,7 +97,7 @@ void __init kirkwood_clk_init(void) sata0 = kirkwood_register_gate("sata0", CGC_BIT_SATA0); sata1 = kirkwood_register_gate("sata1", CGC_BIT_SATA1); usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); - kirkwood_register_gate("sdio", CGC_BIT_SDIO); + sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); kirkwood_register_gate("xor0", CGC_BIT_XOR0); kirkwood_register_gate("xor1", CGC_BIT_XOR1); @@ -117,6 +117,7 @@ void __init kirkwood_clk_init(void) orion_clkdev_add("1", "sata_mv.0", sata1); orion_clkdev_add(NULL, "orion-ehci.0", usb0); orion_clkdev_add(NULL, "orion_nand", runit); + orion_clkdev_add(NULL, "mvsdio", sdio); } /***************************************************************************** diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index eeb8cd125b0c..3b9136c1a475 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,7 @@ struct mvsd_host { struct device *dev; struct resource *res; int irq; + struct clk *clk; int gpio_card_detect; int gpio_write_protect; }; @@ -770,6 +772,13 @@ static int __init mvsd_probe(struct platform_device *pdev) } else host->irq = irq; + /* Not all platforms can gate the clock, so it is not + an error if the clock does not exists. */ + host->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(host->clk)) { + clk_prepare_enable(host->clk); + } + if (mvsd_data->gpio_card_detect) { ret = gpio_request(mvsd_data->gpio_card_detect, DRIVER_NAME " cd"); @@ -854,6 +863,11 @@ static int __exit mvsd_remove(struct platform_device *pdev) mvsd_power_down(host); iounmap(host->base); release_resource(host->res); + + if (!IS_ERR(host->clk)) { + clk_disable_unprepare(host->clk); + clk_put(host->clk); + } mmc_free_host(mmc); } platform_set_drvdata(pdev, NULL); From 1f80b126d06cf5c88b7f03a80c79ffd85053688a Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 11:56:19 +0100 Subject: [PATCH 10/16] ARM: Orion: CESA: Add support for clk Some orion platforms support gating of the clock. If the clock exists enable/disbale it as appropriate. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 4 +++- drivers/crypto/mv_cesa.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 88a1667af4c3..b9b341ff91b4 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -87,6 +87,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; + struct clk *crypto; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); @@ -98,7 +99,7 @@ void __init kirkwood_clk_init(void) sata1 = kirkwood_register_gate("sata1", CGC_BIT_SATA1); usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); - kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); + crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); kirkwood_register_gate("xor0", CGC_BIT_XOR0); kirkwood_register_gate("xor1", CGC_BIT_XOR1); kirkwood_register_gate("pex0", CGC_BIT_PEX0); @@ -118,6 +119,7 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, "orion-ehci.0", usb0); orion_clkdev_add(NULL, "orion_nand", runit); orion_clkdev_add(NULL, "mvsdio", sdio); + orion_clkdev_add(NULL, "mv_crypto", crypto); } /***************************************************************************** diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index e6ecc5f23943..1cc6b3f3e262 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,7 @@ struct crypto_priv { void __iomem *reg; void __iomem *sram; int irq; + struct clk *clk; struct task_struct *queue_th; /* the lock protects queue and eng_st */ @@ -1053,6 +1055,12 @@ static int mv_probe(struct platform_device *pdev) if (ret) goto err_thread; + /* Not all platforms can gate the clock, so it is not + an error if the clock does not exists. */ + cp->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(cp->clk)) + clk_prepare_enable(cp->clk); + writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK); writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG); writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0); @@ -1118,6 +1126,12 @@ static int mv_remove(struct platform_device *pdev) memset(cp->sram, 0, cp->sram_size); iounmap(cp->sram); iounmap(cp->reg); + + if (!IS_ERR(cp->clk)) { + clk_disable_unprepare(cp->clk); + clk_put(cp->clk); + } + kfree(cp); cpg = NULL; return 0; From c510182b1c68e2f2bf61e69f6c65bcf61a188809 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 13:30:26 +0100 Subject: [PATCH 11/16] ARM: Orion: XOR: Add support for clk Some orion platforms can gate the XOR driver clock. If the clock exisits, unable/disable it as appropriate. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 10 +++++----- drivers/dma/mv_xor.c | 15 +++++++++++++++ drivers/dma/mv_xor.h | 1 + 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b9b341ff91b4..ab27d06ac4a5 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -87,7 +87,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; - struct clk *crypto; + struct clk *crypto, *xor0, *xor1; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); @@ -100,8 +100,8 @@ void __init kirkwood_clk_init(void) usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); - kirkwood_register_gate("xor0", CGC_BIT_XOR0); - kirkwood_register_gate("xor1", CGC_BIT_XOR1); + xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); + xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); kirkwood_register_gate("pex0", CGC_BIT_PEX0); kirkwood_register_gate("pex1", CGC_BIT_PEX1); kirkwood_register_gate("audio", CGC_BIT_AUDIO); @@ -120,6 +120,8 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, "orion_nand", runit); orion_clkdev_add(NULL, "mvsdio", sdio); orion_clkdev_add(NULL, "mv_crypto", crypto); + orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); + orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); } /***************************************************************************** @@ -336,7 +338,6 @@ void __init kirkwood_crypto_init(void) void __init kirkwood_xor0_init(void) { kirkwood_clk_ctrl |= CGC_XOR0; - orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); } @@ -348,7 +349,6 @@ void __init kirkwood_xor0_init(void) void __init kirkwood_xor1_init(void) { kirkwood_clk_ctrl |= CGC_XOR1; - orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); } diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index fa5d55fea46c..0b12e68bf79c 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "dmaengine.h" @@ -1307,11 +1308,25 @@ static int mv_xor_shared_probe(struct platform_device *pdev) if (dram) mv_xor_conf_mbus_windows(msp, dram); + /* Not all platforms can gate the clock, so it is not + * an error if the clock does not exists. + */ + msp->clk = clk_get(&pdev->dev, NULL); + if (!IS_ERR(msp->clk)) + clk_prepare_enable(msp->clk); + return 0; } static int mv_xor_shared_remove(struct platform_device *pdev) { + struct mv_xor_shared_private *msp = platform_get_drvdata(pdev); + + if (!IS_ERR(msp->clk)) { + clk_disable_unprepare(msp->clk); + clk_put(msp->clk); + } + return 0; } diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h index 654876b7ba1d..a5b422f5a8ab 100644 --- a/drivers/dma/mv_xor.h +++ b/drivers/dma/mv_xor.h @@ -55,6 +55,7 @@ struct mv_xor_shared_private { void __iomem *xor_base; void __iomem *xor_high_base; + struct clk *clk; }; From 27e53cfbce493bb062212263aa24bbbc5a1077f4 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 8 Mar 2012 21:45:59 +0100 Subject: [PATCH 12/16] ARM: Orion: PCIE: Add support for clk Prepare and enable the clocks when the board indicates the pcie buses will be used. Signed-off-by: Andrew Lunn Tested-by: Jamie Lentin Signed-off-by: Mike Turquette --- arch/arm/mach-kirkwood/common.c | 8 +++++--- arch/arm/mach-kirkwood/pcie.c | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index ab27d06ac4a5..aa36e1bce874 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -87,7 +87,7 @@ static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) void __init kirkwood_clk_init(void) { struct clk *runit, *ge0, *ge1, *sata0, *sata1, *usb0, *sdio; - struct clk *crypto, *xor0, *xor1; + struct clk *crypto, *xor0, *xor1, *pex0, *pex1; tclk = clk_register_fixed_rate(NULL, "tclk", NULL, CLK_IS_ROOT, kirkwood_tclk); @@ -102,8 +102,8 @@ void __init kirkwood_clk_init(void) crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); - kirkwood_register_gate("pex0", CGC_BIT_PEX0); - kirkwood_register_gate("pex1", CGC_BIT_PEX1); + pex0 = kirkwood_register_gate("pex0", CGC_BIT_PEX0); + pex1 = kirkwood_register_gate("pex1", CGC_BIT_PEX1); kirkwood_register_gate("audio", CGC_BIT_AUDIO); kirkwood_register_gate("tdm", CGC_BIT_TDM); kirkwood_register_gate("tsu", CGC_BIT_TSU); @@ -122,6 +122,8 @@ void __init kirkwood_clk_init(void) orion_clkdev_add(NULL, "mv_crypto", crypto); orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0); orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1); + orion_clkdev_add("0", "pcie", pex0); + orion_clkdev_add("1", "pcie", pex1); } /***************************************************************************** diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index f56a0118c1bb..881933a0b5eb 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -11,6 +11,7 @@ #include #include #include +#include #include