aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c10
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c10
-rw-r--r--arch/arm/mach-mxs/clock.c33
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c2
-rw-r--r--arch/arm/mach-mxs/system.c2
-rw-r--r--arch/arm/mach-mxs/timer.c2
-rw-r--r--drivers/clk/Kconfig3
-rw-r--r--drivers/dma/mxs-dma.c8
-rw-r--r--drivers/mmc/host/mxs-mmc.c10
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c12
-rw-r--r--drivers/net/can/flexcan.c10
-rw-r--r--drivers/net/ethernet/freescale/fec.c10
-rw-r--r--drivers/tty/serial/mxs-auart.c8
-rw-r--r--drivers/video/mxsfb.c8
-rw-r--r--include/linux/clk.h22
-rw-r--r--sound/soc/mxs/mxs-saif.c4
17 files changed, 97 insertions, 58 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b3d7b77d2d51..9d66dfc33a5a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -447,6 +447,7 @@ config ARCH_MXS
447 select ARCH_REQUIRE_GPIOLIB 447 select ARCH_REQUIRE_GPIOLIB
448 select CLKDEV_LOOKUP 448 select CLKDEV_LOOKUP
449 select CLKSRC_MMIO 449 select CLKSRC_MMIO
450 select HAVE_CLK_PREPARE
450 help 451 help
451 Support for Freescale MXS-based family of processors 452 Support for Freescale MXS-based family of processors
452 453
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index 0163b6d83773..e12e11231dc7 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -545,11 +545,11 @@ int __init mx23_clocks_init(void)
545 */ 545 */
546 clk_set_parent(&ssp_clk, &ref_io_clk); 546 clk_set_parent(&ssp_clk, &ref_io_clk);
547 547
548 clk_enable(&cpu_clk); 548 clk_prepare_enable(&cpu_clk);
549 clk_enable(&hbus_clk); 549 clk_prepare_enable(&hbus_clk);
550 clk_enable(&xbus_clk); 550 clk_prepare_enable(&xbus_clk);
551 clk_enable(&emi_clk); 551 clk_prepare_enable(&emi_clk);
552 clk_enable(&uart_clk); 552 clk_prepare_enable(&uart_clk);
553 553
554 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 554 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
555 555
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index df0ad3ce234b..5d68e4152220 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -804,11 +804,11 @@ int __init mx28_clocks_init(void)
804 clk_set_parent(&ssp0_clk, &ref_io0_clk); 804 clk_set_parent(&ssp0_clk, &ref_io0_clk);
805 clk_set_parent(&ssp1_clk, &ref_io0_clk); 805 clk_set_parent(&ssp1_clk, &ref_io0_clk);
806 806
807 clk_enable(&cpu_clk); 807 clk_prepare_enable(&cpu_clk);
808 clk_enable(&hbus_clk); 808 clk_prepare_enable(&hbus_clk);
809 clk_enable(&xbus_clk); 809 clk_prepare_enable(&xbus_clk);
810 clk_enable(&emi_clk); 810 clk_prepare_enable(&emi_clk);
811 clk_enable(&uart_clk); 811 clk_prepare_enable(&uart_clk);
812 812
813 clk_set_parent(&lcdif_clk, &ref_pix_clk); 813 clk_set_parent(&lcdif_clk, &ref_pix_clk);
814 clk_set_parent(&saif0_clk, &pll0_clk); 814 clk_set_parent(&saif0_clk, &pll0_clk);
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
index a7093c88e6a6..97a6f4acc6cc 100644
--- a/arch/arm/mach-mxs/clock.c
+++ b/arch/arm/mach-mxs/clock.c
@@ -74,10 +74,15 @@ static int __clk_enable(struct clk *clk)
74 return 0; 74 return 0;
75} 75}
76 76
77/* This function increments the reference count on the clock and enables the 77/*
78 * clock if not already enabled. The parent clock tree is recursively enabled 78 * The clk_enable/clk_disable could be called by drivers in atomic context,
79 * so they should not really hold mutex. Instead, clk_prepare/clk_unprepare
80 * can hold a mutex, as the pair will only be called in non-atomic context.
81 * Before migrating to common clk framework, we can have __clk_enable and
82 * __clk_disable called in clk_prepare/clk_unprepare with mutex held and
83 * leave clk_enable/clk_disable as the dummy functions.
79 */ 84 */
80int clk_enable(struct clk *clk) 85int clk_prepare(struct clk *clk)
81{ 86{
82 int ret = 0; 87 int ret = 0;
83 88
@@ -90,13 +95,9 @@ int clk_enable(struct clk *clk)
90 95
91 return ret; 96 return ret;
92} 97}
93EXPORT_SYMBOL(clk_enable); 98EXPORT_SYMBOL(clk_prepare);
94 99
95/* This function decrements the reference count on the clock and disables 100void clk_unprepare(struct clk *clk)
96 * the clock when reference count is 0. The parent clock tree is
97 * recursively disabled
98 */
99void clk_disable(struct clk *clk)
100{ 101{
101 if (clk == NULL || IS_ERR(clk)) 102 if (clk == NULL || IS_ERR(clk))
102 return; 103 return;
@@ -105,6 +106,18 @@ void clk_disable(struct clk *clk)
105 __clk_disable(clk); 106 __clk_disable(clk);
106 mutex_unlock(&clocks_mutex); 107 mutex_unlock(&clocks_mutex);
107} 108}
109EXPORT_SYMBOL(clk_unprepare);
110
111int clk_enable(struct clk *clk)
112{
113 return 0;
114}
115EXPORT_SYMBOL(clk_enable);
116
117void clk_disable(struct clk *clk)
118{
119 /* nothing to do */
120}
108EXPORT_SYMBOL(clk_disable); 121EXPORT_SYMBOL(clk_disable);
109 122
110/* Retrieve the *current* clock rate. If the clock itself 123/* Retrieve the *current* clock rate. If the clock itself
@@ -166,7 +179,7 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
166 return ret; 179 return ret;
167 180
168 if (clk->usecount) 181 if (clk->usecount)
169 clk_enable(parent); 182 clk_prepare_enable(parent);
170 183
171 mutex_lock(&clocks_mutex); 184 mutex_lock(&clocks_mutex);
172 ret = clk->set_parent(clk, parent); 185 ret = clk->set_parent(clk, parent);
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index eb0597be4e23..fdb0a5664dd6 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -229,7 +229,7 @@ static void __init mx28evk_fec_reset(void)
229 /* Enable fec phy clock */ 229 /* Enable fec phy clock */
230 clk = clk_get_sys("pll2", NULL); 230 clk = clk_get_sys("pll2", NULL);
231 if (!IS_ERR(clk)) 231 if (!IS_ERR(clk))
232 clk_enable(clk); 232 clk_prepare_enable(clk);
233 233
234 /* Power up fec phy */ 234 /* Power up fec phy */
235 ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power"); 235 ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
index b936633b7682..54f91ad1c965 100644
--- a/arch/arm/mach-mxs/system.c
+++ b/arch/arm/mach-mxs/system.c
@@ -66,7 +66,7 @@ static int __init mxs_arch_reset_init(void)
66 66
67 clk = clk_get_sys("rtc", NULL); 67 clk = clk_get_sys("rtc", NULL);
68 if (!IS_ERR(clk)) 68 if (!IS_ERR(clk))
69 clk_enable(clk); 69 clk_prepare_enable(clk);
70 70
71 return 0; 71 return 0;
72} 72}
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
index cace0d2e5a55..564a63279f18 100644
--- a/arch/arm/mach-mxs/timer.c
+++ b/arch/arm/mach-mxs/timer.c
@@ -245,7 +245,7 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
245 245
246void __init mxs_timer_init(struct clk *timer_clk, int irq) 246void __init mxs_timer_init(struct clk *timer_clk, int irq)
247{ 247{
248 clk_enable(timer_clk); 248 clk_prepare_enable(timer_clk);
249 249
250 /* 250 /*
251 * Initialize timers to a known state 251 * Initialize timers to a known state
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 35309274ad68..9b3cd08cd0ed 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -3,5 +3,8 @@ config CLKDEV_LOOKUP
3 bool 3 bool
4 select HAVE_CLK 4 select HAVE_CLK
5 5
6config HAVE_CLK_PREPARE
7 bool
8
6config HAVE_MACH_CLKDEV 9config HAVE_MACH_CLKDEV
7 bool 10 bool
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index b4588bdd98bb..fc903c0ed234 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -334,7 +334,7 @@ static int mxs_dma_alloc_chan_resources(struct dma_chan *chan)
334 goto err_irq; 334 goto err_irq;
335 } 335 }
336 336
337 ret = clk_enable(mxs_dma->clk); 337 ret = clk_prepare_enable(mxs_dma->clk);
338 if (ret) 338 if (ret)
339 goto err_clk; 339 goto err_clk;
340 340
@@ -372,7 +372,7 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
372 dma_free_coherent(mxs_dma->dma_device.dev, PAGE_SIZE, 372 dma_free_coherent(mxs_dma->dma_device.dev, PAGE_SIZE,
373 mxs_chan->ccw, mxs_chan->ccw_phys); 373 mxs_chan->ccw, mxs_chan->ccw_phys);
374 374
375 clk_disable(mxs_dma->clk); 375 clk_disable_unprepare(mxs_dma->clk);
376} 376}
377 377
378static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg( 378static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
@@ -578,7 +578,7 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
578{ 578{
579 int ret; 579 int ret;
580 580
581 ret = clk_enable(mxs_dma->clk); 581 ret = clk_prepare_enable(mxs_dma->clk);
582 if (ret) 582 if (ret)
583 goto err_out; 583 goto err_out;
584 584
@@ -604,7 +604,7 @@ static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma)
604 writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS, 604 writel(MXS_DMA_CHANNELS_MASK << MXS_DMA_CHANNELS,
605 mxs_dma->base + HW_APBHX_CTRL1 + MXS_SET_ADDR); 605 mxs_dma->base + HW_APBHX_CTRL1 + MXS_SET_ADDR);
606 606
607 clk_disable(mxs_dma->clk); 607 clk_disable_unprepare(mxs_dma->clk);
608 608
609 return 0; 609 return 0;
610 610
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 99b449d26a4d..973011f9a298 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -713,7 +713,7 @@ static int mxs_mmc_probe(struct platform_device *pdev)
713 ret = PTR_ERR(host->clk); 713 ret = PTR_ERR(host->clk);
714 goto out_iounmap; 714 goto out_iounmap;
715 } 715 }
716 clk_enable(host->clk); 716 clk_prepare_enable(host->clk);
717 717
718 mxs_mmc_reset(host); 718 mxs_mmc_reset(host);
719 719
@@ -772,7 +772,7 @@ out_free_dma:
772 if (host->dmach) 772 if (host->dmach)
773 dma_release_channel(host->dmach); 773 dma_release_channel(host->dmach);
774out_clk_put: 774out_clk_put:
775 clk_disable(host->clk); 775 clk_disable_unprepare(host->clk);
776 clk_put(host->clk); 776 clk_put(host->clk);
777out_iounmap: 777out_iounmap:
778 iounmap(host->base); 778 iounmap(host->base);
@@ -798,7 +798,7 @@ static int mxs_mmc_remove(struct platform_device *pdev)
798 if (host->dmach) 798 if (host->dmach)
799 dma_release_channel(host->dmach); 799 dma_release_channel(host->dmach);
800 800
801 clk_disable(host->clk); 801 clk_disable_unprepare(host->clk);
802 clk_put(host->clk); 802 clk_put(host->clk);
803 803
804 iounmap(host->base); 804 iounmap(host->base);
@@ -819,7 +819,7 @@ static int mxs_mmc_suspend(struct device *dev)
819 819
820 ret = mmc_suspend_host(mmc); 820 ret = mmc_suspend_host(mmc);
821 821
822 clk_disable(host->clk); 822 clk_disable_unprepare(host->clk);
823 823
824 return ret; 824 return ret;
825} 825}
@@ -830,7 +830,7 @@ static int mxs_mmc_resume(struct device *dev)
830 struct mxs_mmc_host *host = mmc_priv(mmc); 830 struct mxs_mmc_host *host = mmc_priv(mmc);
831 int ret = 0; 831 int ret = 0;
832 832
833 clk_enable(host->clk); 833 clk_prepare_enable(host->clk);
834 834
835 ret = mmc_resume_host(mmc); 835 ret = mmc_resume_host(mmc);
836 836
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index de4db7604a3f..2a56fc6f399a 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -126,7 +126,7 @@ int gpmi_init(struct gpmi_nand_data *this)
126 struct resources *r = &this->resources; 126 struct resources *r = &this->resources;
127 int ret; 127 int ret;
128 128
129 ret = clk_enable(r->clock); 129 ret = clk_prepare_enable(r->clock);
130 if (ret) 130 if (ret)
131 goto err_out; 131 goto err_out;
132 ret = gpmi_reset_block(r->gpmi_regs, false); 132 ret = gpmi_reset_block(r->gpmi_regs, false);
@@ -146,7 +146,7 @@ int gpmi_init(struct gpmi_nand_data *this)
146 /* Select BCH ECC. */ 146 /* Select BCH ECC. */
147 writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET); 147 writel(BM_GPMI_CTRL1_BCH_MODE, r->gpmi_regs + HW_GPMI_CTRL1_SET);
148 148
149 clk_disable(r->clock); 149 clk_disable_unprepare(r->clock);
150 return 0; 150 return 0;
151err_out: 151err_out:
152 return ret; 152 return ret;
@@ -202,7 +202,7 @@ int bch_set_geometry(struct gpmi_nand_data *this)
202 ecc_strength = bch_geo->ecc_strength >> 1; 202 ecc_strength = bch_geo->ecc_strength >> 1;
203 page_size = bch_geo->page_size; 203 page_size = bch_geo->page_size;
204 204
205 ret = clk_enable(r->clock); 205 ret = clk_prepare_enable(r->clock);
206 if (ret) 206 if (ret)
207 goto err_out; 207 goto err_out;
208 208
@@ -229,7 +229,7 @@ int bch_set_geometry(struct gpmi_nand_data *this)
229 writel(BM_BCH_CTRL_COMPLETE_IRQ_EN, 229 writel(BM_BCH_CTRL_COMPLETE_IRQ_EN,
230 r->bch_regs + HW_BCH_CTRL_SET); 230 r->bch_regs + HW_BCH_CTRL_SET);
231 231
232 clk_disable(r->clock); 232 clk_disable_unprepare(r->clock);
233 return 0; 233 return 0;
234err_out: 234err_out:
235 return ret; 235 return ret;
@@ -704,7 +704,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
704 int ret; 704 int ret;
705 705
706 /* Enable the clock. */ 706 /* Enable the clock. */
707 ret = clk_enable(r->clock); 707 ret = clk_prepare_enable(r->clock);
708 if (ret) { 708 if (ret) {
709 pr_err("We failed in enable the clk\n"); 709 pr_err("We failed in enable the clk\n");
710 goto err_out; 710 goto err_out;
@@ -773,7 +773,7 @@ err_out:
773void gpmi_end(struct gpmi_nand_data *this) 773void gpmi_end(struct gpmi_nand_data *this)
774{ 774{
775 struct resources *r = &this->resources; 775 struct resources *r = &this->resources;
776 clk_disable(r->clock); 776 clk_disable_unprepare(r->clock);
777} 777}
778 778
779/* Clears a BCH interrupt. */ 779/* Clears a BCH interrupt. */
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 165a4c798025..7fd8089946fb 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -802,7 +802,7 @@ static int flexcan_open(struct net_device *dev)
802 struct flexcan_priv *priv = netdev_priv(dev); 802 struct flexcan_priv *priv = netdev_priv(dev);
803 int err; 803 int err;
804 804
805 clk_enable(priv->clk); 805 clk_prepare_enable(priv->clk);
806 806
807 err = open_candev(dev); 807 err = open_candev(dev);
808 if (err) 808 if (err)
@@ -824,7 +824,7 @@ static int flexcan_open(struct net_device *dev)
824 out_close: 824 out_close:
825 close_candev(dev); 825 close_candev(dev);
826 out: 826 out:
827 clk_disable(priv->clk); 827 clk_disable_unprepare(priv->clk);
828 828
829 return err; 829 return err;
830} 830}
@@ -838,7 +838,7 @@ static int flexcan_close(struct net_device *dev)
838 flexcan_chip_stop(dev); 838 flexcan_chip_stop(dev);
839 839
840 free_irq(dev->irq, dev); 840 free_irq(dev->irq, dev);
841 clk_disable(priv->clk); 841 clk_disable_unprepare(priv->clk);
842 842
843 close_candev(dev); 843 close_candev(dev);
844 844
@@ -877,7 +877,7 @@ static int __devinit register_flexcandev(struct net_device *dev)
877 struct flexcan_regs __iomem *regs = priv->base; 877 struct flexcan_regs __iomem *regs = priv->base;
878 u32 reg, err; 878 u32 reg, err;
879 879
880 clk_enable(priv->clk); 880 clk_prepare_enable(priv->clk);
881 881
882 /* select "bus clock", chip must be disabled */ 882 /* select "bus clock", chip must be disabled */
883 flexcan_chip_disable(priv); 883 flexcan_chip_disable(priv);
@@ -911,7 +911,7 @@ static int __devinit register_flexcandev(struct net_device *dev)
911 out: 911 out:
912 /* disable core and turn off clocks */ 912 /* disable core and turn off clocks */
913 flexcan_chip_disable(priv); 913 flexcan_chip_disable(priv);
914 clk_disable(priv->clk); 914 clk_disable_unprepare(priv->clk);
915 915
916 return err; 916 return err;
917} 917}
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index 20c2e3f3e18a..ddcbbb34d1b9 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -1610,7 +1610,7 @@ fec_probe(struct platform_device *pdev)
1610 ret = PTR_ERR(fep->clk); 1610 ret = PTR_ERR(fep->clk);
1611 goto failed_clk; 1611 goto failed_clk;
1612 } 1612 }
1613 clk_enable(fep->clk); 1613 clk_prepare_enable(fep->clk);
1614 1614
1615 ret = fec_enet_init(ndev); 1615 ret = fec_enet_init(ndev);
1616 if (ret) 1616 if (ret)
@@ -1633,7 +1633,7 @@ failed_register:
1633 fec_enet_mii_remove(fep); 1633 fec_enet_mii_remove(fep);
1634failed_mii_init: 1634failed_mii_init:
1635failed_init: 1635failed_init:
1636 clk_disable(fep->clk); 1636 clk_disable_unprepare(fep->clk);
1637 clk_put(fep->clk); 1637 clk_put(fep->clk);
1638failed_clk: 1638failed_clk:
1639 for (i = 0; i < FEC_IRQ_NUM; i++) { 1639 for (i = 0; i < FEC_IRQ_NUM; i++) {
@@ -1666,7 +1666,7 @@ fec_drv_remove(struct platform_device *pdev)
1666 if (irq > 0) 1666 if (irq > 0)
1667 free_irq(irq, ndev); 1667 free_irq(irq, ndev);
1668 } 1668 }
1669 clk_disable(fep->clk); 1669 clk_disable_unprepare(fep->clk);
1670 clk_put(fep->clk); 1670 clk_put(fep->clk);
1671 iounmap(fep->hwp); 1671 iounmap(fep->hwp);
1672 free_netdev(ndev); 1672 free_netdev(ndev);
@@ -1691,7 +1691,7 @@ fec_suspend(struct device *dev)
1691 fec_stop(ndev); 1691 fec_stop(ndev);
1692 netif_device_detach(ndev); 1692 netif_device_detach(ndev);
1693 } 1693 }
1694 clk_disable(fep->clk); 1694 clk_disable_unprepare(fep->clk);
1695 1695
1696 return 0; 1696 return 0;
1697} 1697}
@@ -1702,7 +1702,7 @@ fec_resume(struct device *dev)
1702 struct net_device *ndev = dev_get_drvdata(dev); 1702 struct net_device *ndev = dev_get_drvdata(dev);
1703 struct fec_enet_private *fep = netdev_priv(ndev); 1703 struct fec_enet_private *fep = netdev_priv(ndev);
1704 1704
1705 clk_enable(fep->clk); 1705 clk_prepare_enable(fep->clk);
1706 if (netif_running(ndev)) { 1706 if (netif_running(ndev)) {
1707 fec_restart(ndev, fep->full_duplex); 1707 fec_restart(ndev, fep->full_duplex);
1708 netif_device_attach(ndev); 1708 netif_device_attach(ndev);
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c
index 076169f50b01..55fd362b9879 100644
--- a/drivers/tty/serial/mxs-auart.c
+++ b/drivers/tty/serial/mxs-auart.c
@@ -425,7 +425,7 @@ static int mxs_auart_startup(struct uart_port *u)
425{ 425{
426 struct mxs_auart_port *s = to_auart_port(u); 426 struct mxs_auart_port *s = to_auart_port(u);
427 427
428 clk_enable(s->clk); 428 clk_prepare_enable(s->clk);
429 429
430 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR); 430 writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_CLR);
431 431
@@ -454,7 +454,7 @@ static void mxs_auart_shutdown(struct uart_port *u)
454 writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, 454 writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN,
455 u->membase + AUART_INTR_CLR); 455 u->membase + AUART_INTR_CLR);
456 456
457 clk_disable(s->clk); 457 clk_disable_unprepare(s->clk);
458} 458}
459 459
460static unsigned int mxs_auart_tx_empty(struct uart_port *u) 460static unsigned int mxs_auart_tx_empty(struct uart_port *u)
@@ -635,7 +635,7 @@ auart_console_setup(struct console *co, char *options)
635 if (!s) 635 if (!s)
636 return -ENODEV; 636 return -ENODEV;
637 637
638 clk_enable(s->clk); 638 clk_prepare_enable(s->clk);
639 639
640 if (options) 640 if (options)
641 uart_parse_options(options, &baud, &parity, &bits, &flow); 641 uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -644,7 +644,7 @@ auart_console_setup(struct console *co, char *options)
644 644
645 ret = uart_set_options(&s->port, co, baud, parity, bits, flow); 645 ret = uart_set_options(&s->port, co, baud, parity, bits, flow);
646 646
647 clk_disable(s->clk); 647 clk_disable_unprepare(s->clk);
648 648
649 return ret; 649 return ret;
650} 650}
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index d837d63c456f..eb3c5eea1a0f 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -328,7 +328,7 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
328 328
329 dev_dbg(&host->pdev->dev, "%s\n", __func__); 329 dev_dbg(&host->pdev->dev, "%s\n", __func__);
330 330
331 clk_enable(host->clk); 331 clk_prepare_enable(host->clk);
332 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); 332 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
333 333
334 /* if it was disabled, re-enable the mode again */ 334 /* if it was disabled, re-enable the mode again */
@@ -368,7 +368,7 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
368 368
369 writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR); 369 writel(VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4 + REG_CLR);
370 370
371 clk_disable(host->clk); 371 clk_disable_unprepare(host->clk);
372 372
373 host->enabled = 0; 373 host->enabled = 0;
374} 374}
@@ -668,7 +668,7 @@ static int __devinit mxsfb_restore_mode(struct mxsfb_info *host)
668 line_count = fb_info->fix.smem_len / fb_info->fix.line_length; 668 line_count = fb_info->fix.smem_len / fb_info->fix.line_length;
669 fb_info->fix.ypanstep = 1; 669 fb_info->fix.ypanstep = 1;
670 670
671 clk_enable(host->clk); 671 clk_prepare_enable(host->clk);
672 host->enabled = 1; 672 host->enabled = 1;
673 673
674 return 0; 674 return 0;
@@ -841,7 +841,7 @@ static int __devinit mxsfb_probe(struct platform_device *pdev)
841 841
842error_register: 842error_register:
843 if (host->enabled) 843 if (host->enabled)
844 clk_disable(host->clk); 844 clk_disable_unprepare(host->clk);
845 fb_destroy_modelist(&fb_info->modelist); 845 fb_destroy_modelist(&fb_info->modelist);
846error_init_fb: 846error_init_fb:
847 kfree(fb_info->pseudo_palette); 847 kfree(fb_info->pseudo_palette);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 7213b52b2c0e..b9d46fa154b4 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -107,6 +107,28 @@ static inline void clk_unprepare(struct clk *clk)
107} 107}
108#endif 108#endif
109 109
110/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
111static inline int clk_prepare_enable(struct clk *clk)
112{
113 int ret;
114
115 ret = clk_prepare(clk);
116 if (ret)
117 return ret;
118 ret = clk_enable(clk);
119 if (ret)
120 clk_unprepare(clk);
121
122 return ret;
123}
124
125/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
126static inline void clk_disable_unprepare(struct clk *clk)
127{
128 clk_disable(clk);
129 clk_unprepare(clk);
130}
131
110/** 132/**
111 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source. 133 * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
112 * This is only valid once the clock source has been enabled. 134 * This is only valid once the clock source has been enabled.
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c
index 1ef697fe1731..d775b0761e0a 100644
--- a/sound/soc/mxs/mxs-saif.c
+++ b/sound/soc/mxs/mxs-saif.c
@@ -210,7 +210,7 @@ int mxs_saif_put_mclk(unsigned int saif_id)
210 return -EBUSY; 210 return -EBUSY;
211 } 211 }
212 212
213 clk_disable(saif->clk); 213 clk_disable_unprepare(saif->clk);
214 214
215 /* disable MCLK output */ 215 /* disable MCLK output */
216 __raw_writel(BM_SAIF_CTRL_CLKGATE, 216 __raw_writel(BM_SAIF_CTRL_CLKGATE,
@@ -264,7 +264,7 @@ int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk,
264 if (ret) 264 if (ret)
265 return ret; 265 return ret;
266 266
267 ret = clk_enable(saif->clk); 267 ret = clk_prepare_enable(saif->clk);
268 if (ret) 268 if (ret)
269 return ret; 269 return ret;
270 270