From 4574b886698dfad6209102fed6136622b5fe1c21 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Fri, 6 Apr 2012 17:17:26 +0200 Subject: 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 --- drivers/spi/spi-orion.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index e496f799b7a..dfd04e91fa6 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)); -- cgit v1.2.3-70-g09d2 From 452503ebc7cc4cce5b9e52cf2f03255365a53234 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 24 Dec 2011 01:24:24 +0100 Subject: 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(-) (limited to 'drivers') diff --git a/arch/arm/mach-dove/common.c b/arch/arm/mach-dove/common.c index da5b4047464..02766960480 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 476e0b941db..c2235440529 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 4c24b46520a..ad4d037bbcd 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 2ef82e2f511..3fc731824e9 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 bbe50a94871..a33733bb380 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 d188a1aa6f5..00d8761c7d2 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 5e1ca0f0509..99cd233266a 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 30b0c4e78f9..51bf8ada6dc 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. -- cgit v1.2.3-70-g09d2 From 4f04be62af95119d258b8035f498100e43c8c527 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 4 Mar 2012 16:57:31 +0100 Subject: 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 (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c2235440529..880f3667a2e 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 3fc731824e9..067bdd7c06d 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 a33733bb380..d349998f72e 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 00d8761c7d2..c3bfa91bfaa 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 665c362a2fb..00000000000 --- 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 788aa158e78..0f5736949c6 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; } -- cgit v1.2.3-70-g09d2 From eee989902aab45f0ca2739727ef615420802649c Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 18 Feb 2012 22:26:42 +0100 Subject: 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(-) (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 46d7b437490..c9fef5b7c56 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 7336d4a7ab3..24712adf69d 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; } -- cgit v1.2.3-70-g09d2 From 8c869edaee07c623066266827371235fb9c12e01 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 15 Apr 2012 12:53:47 +0200 Subject: 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(-) (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c9fef5b7c56..b0f20c0c7d5 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 6c6a5a3b4ea..82de1073aa5 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; } -- cgit v1.2.3-70-g09d2 From 9c2bd504b55ce3e680ae0d3768e78c15fef3448d Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 11:01:22 +0100 Subject: 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(+) (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b0f20c0c7d5..99adebce707 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 1d3bfb26080..fdc4786ea3e 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; } -- cgit v1.2.3-70-g09d2 From f4f7561e032777cd7376800ac97352d5b1684d8f Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 11:39:27 +0100 Subject: 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(-) (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 99adebce707..88a1667af4c 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 eeb8cd125b0..3b9136c1a47 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); -- cgit v1.2.3-70-g09d2 From 1f80b126d06cf5c88b7f03a80c79ffd85053688a Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 11:56:19 +0100 Subject: 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(-) (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 88a1667af4c..b9b341ff91b 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 e6ecc5f2394..1cc6b3f3e26 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; -- cgit v1.2.3-70-g09d2 From c510182b1c68e2f2bf61e69f6c65bcf61a188809 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 19 Feb 2012 13:30:26 +0100 Subject: 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(-) (limited to 'drivers') diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index b9b341ff91b..ab27d06ac4a 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 fa5d55fea46..0b12e68bf79 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 654876b7ba1..a5b422f5a8a 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; }; -- cgit v1.2.3-70-g09d2 From 1df5c939f6d9dff7dfbe108d93133b9636baa607 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Apr 2012 09:07:12 +0100 Subject: clk: Provide dummy clk_unregister() While there's no actual implementation behind it having the call to use in drivers makes them feel neater from a driver author point of view. An actual implementation can wait for someone who needs to use the function in a real system. Signed-off-by: Mark Brown [mturquette@linaro.org: void return type instead of int -EINVAL] Signed-off-by: Mike Turquette --- drivers/clk/clk.c | 9 +++++++++ include/linux/clk-provider.h | 2 ++ 2 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index e5d5dc13bcf..a7e5dd59e19 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -1420,6 +1420,15 @@ fail_out: } EXPORT_SYMBOL_GPL(clk_register); +/** + * clk_unregister - unregister a currently registered clock + * @clk: clock to unregister + * + * Currently unimplemented. + */ +void clk_unregister(struct clk *clk) {} +EXPORT_SYMBOL_GPL(clk_unregister); + /*** clk rate change notifiers ***/ /** diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index c1c23b9ec36..4a0b483986c 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -312,6 +312,8 @@ struct clk *clk_register_fixed_factor(struct device *dev, const char *name, */ struct clk *clk_register(struct device *dev, struct clk_hw *hw); +void clk_unregister(struct clk *clk); + /* helper functions */ const char *__clk_get_name(struct clk *clk); struct clk_hw *__clk_get_hw(struct clk *clk); -- cgit v1.2.3-70-g09d2 From 7e0fa1b5fa91d9aa456d102c273b2cf0f2e95d39 Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Tue, 15 May 2012 13:43:42 -0700 Subject: clk: Fix CLK_SET_RATE_GATE flag validation in clk_set_rate(). The clk_set_rate() code shouldn't check the clock's enable count when validating CLK_SET_RATE_GATE flag since the enable count could change after the validation. Similar to clk_set_parent(), it should instead check the prepare count. The prepare count should go to zero only when the end user expects the clock to not be enabled in the future. Since the code already grabs the prepare count before validation, it's not possible for prepare count to change after validation and by association not possible for a well behaving end user to enable the clock while the set rate is in progress. Signed-off-by: Saravana Kannan Reviewed-by: Richard Zhao Signed-off-by: Mike Turquette --- drivers/clk/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index a7e5dd59e19..687b00d67c8 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -903,7 +903,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate) if (rate == clk->rate) goto out; - if ((clk->flags & CLK_SET_RATE_GATE) && __clk_is_enabled(clk)) { + if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) { ret = -EBUSY; goto out; } -- cgit v1.2.3-70-g09d2