Merge branch 'clk' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 27 Oct 2011 06:41:50 +0000 (08:41 +0200)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 27 Oct 2011 06:41:50 +0000 (08:41 +0200)
* 'clk' of http://ftp.arm.linux.org.uk/pub/linux/arm/kernel/git-cur/linux-2.6-arm:
  ARM: 7131/1: clkdev: Add Common Macro for clk_lookup
  clk: spi-pl022: convert to clk_prepare()/clk_unprepare()
  clk: timer-sp: convert to clk_prepare()/clk_unprepare()
  clk: sa1111: convert to clk_prepare()/clk_unprepare()
  clk: mmci: convert to clk_prepare()/clk_unprepare()
  clk: amba-pl011: convert to clk_prepare()/clk_unprepare()
  clk: amba-pl010: convert to clk_prepare()/clk_unprepare()
  clk: amba-clcd: convert to clk_prepare()/clk_unprepare()
  clk: amba bus: convert to clk_prepare()/clk_unprepare()
  clk: provide prepare/unprepare functions

arch/arm/common/sa1111.c
arch/arm/common/timer-sp.c
drivers/amba/bus.c
drivers/mmc/host/mmci.c
drivers/spi/spi-pl022.c
drivers/tty/serial/amba-pl010.c
drivers/tty/serial/amba-pl011.c
drivers/video/amba-clcd.c
include/linux/clk.h
include/linux/clkdev.h

index 0569de6..61691cd 100644 (file)
@@ -718,6 +718,10 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
                goto err_free;
        }
 
+       ret = clk_prepare(sachip->clk);
+       if (ret)
+               goto err_clkput;
+
        spin_lock_init(&sachip->lock);
 
        sachip->dev = me;
@@ -733,7 +737,7 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
        sachip->base = ioremap(mem->start, PAGE_SIZE * 2);
        if (!sachip->base) {
                ret = -ENOMEM;
-               goto err_clkput;
+               goto err_clk_unprep;
        }
 
        /*
@@ -809,6 +813,8 @@ __sa1111_probe(struct device *me, struct resource *mem, int irq)
 
  err_unmap:
        iounmap(sachip->base);
+ err_clk_unprep:
+       clk_unprepare(sachip->clk);
  err_clkput:
        clk_put(sachip->clk);
  err_free:
@@ -835,6 +841,7 @@ static void __sa1111_remove(struct sa1111 *sachip)
        sa1111_writel(0, irqbase + SA1111_WAKEEN1);
 
        clk_disable(sachip->clk);
+       clk_unprepare(sachip->clk);
 
        if (sachip->irq != NO_IRQ) {
                irq_set_chained_handler(sachip->irq, NULL);
index 41df478..2393b5b 100644 (file)
@@ -41,9 +41,17 @@ static long __init sp804_get_clock_rate(const char *name)
                return PTR_ERR(clk);
        }
 
+       err = clk_prepare(clk);
+       if (err) {
+               pr_err("sp804: %s clock failed to prepare: %d\n", name, err);
+               clk_put(clk);
+               return err;
+       }
+
        err = clk_enable(clk);
        if (err) {
                pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+               clk_unprepare(clk);
                clk_put(clk);
                return err;
        }
@@ -52,6 +60,7 @@ static long __init sp804_get_clock_rate(const char *name)
        if (rate < 0) {
                pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
                clk_disable(clk);
+               clk_unprepare(clk);
                clk_put(clk);
        }
 
index 84bdaac..bd230e8 100644 (file)
@@ -460,9 +460,17 @@ static int amba_get_enable_pclk(struct amba_device *pcdev)
        if (IS_ERR(pclk))
                return PTR_ERR(pclk);
 
+       ret = clk_prepare(pclk);
+       if (ret) {
+               clk_put(pclk);
+               return ret;
+       }
+
        ret = clk_enable(pclk);
-       if (ret)
+       if (ret) {
+               clk_unprepare(pclk);
                clk_put(pclk);
+       }
 
        return ret;
 }
@@ -472,6 +480,7 @@ static void amba_put_disable_pclk(struct amba_device *pcdev)
        struct clk *pclk = pcdev->pclk;
 
        clk_disable(pclk);
+       clk_unprepare(pclk);
        clk_put(pclk);
 }
 
index 5e142b7..7be8db0 100644 (file)
@@ -1160,10 +1160,14 @@ static int __devinit mmci_probe(struct amba_device *dev,
                goto host_free;
        }
 
-       ret = clk_enable(host->clk);
+       ret = clk_prepare(host->clk);
        if (ret)
                goto clk_free;
 
+       ret = clk_enable(host->clk);
+       if (ret)
+               goto clk_unprep;
+
        host->plat = plat;
        host->variant = variant;
        host->mclk = clk_get_rate(host->clk);
@@ -1351,6 +1355,8 @@ static int __devinit mmci_probe(struct amba_device *dev,
        iounmap(host->base);
  clk_disable:
        clk_disable(host->clk);
+ clk_unprep:
+       clk_unprepare(host->clk);
  clk_free:
        clk_put(host->clk);
  host_free:
@@ -1398,6 +1404,7 @@ static int __devexit mmci_remove(struct amba_device *dev)
 
                iounmap(host->base);
                clk_disable(host->clk);
+               clk_unprepare(host->clk);
                clk_put(host->clk);
 
                if (host->vcc)
index 3520cf9..1ab2fa0 100644 (file)
@@ -2187,6 +2187,13 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
                dev_err(&adev->dev, "could not retrieve SSP/SPI bus clock\n");
                goto err_no_clk;
        }
+
+       status = clk_prepare(pl022->clk);
+       if (status) {
+               dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n");
+               goto  err_clk_prep;
+       }
+
        /* Disable SSP */
        writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)),
               SSP_CR1(pl022->virtbase));
@@ -2238,6 +2245,8 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id)
        pl022_dma_remove(pl022);
        free_irq(adev->irq[0], pl022);
  err_no_irq:
+       clk_unprepare(pl022->clk);
+ err_clk_prep:
        clk_put(pl022->clk);
  err_no_clk:
        iounmap(pl022->virtbase);
@@ -2271,6 +2280,7 @@ pl022_remove(struct amba_device *adev)
        pl022_dma_remove(pl022);
        free_irq(adev->irq[0], pl022);
        clk_disable(pl022->clk);
+       clk_unprepare(pl022->clk);
        clk_put(pl022->clk);
        iounmap(pl022->virtbase);
        amba_release_regions(adev);
index c0d10c4..efdf92c 100644 (file)
@@ -312,12 +312,16 @@ static int pl010_startup(struct uart_port *port)
        struct uart_amba_port *uap = (struct uart_amba_port *)port;
        int retval;
 
+       retval = clk_prepare(uap->clk);
+       if (retval)
+               goto out;
+
        /*
         * Try to enable the clock producer.
         */
        retval = clk_enable(uap->clk);
        if (retval)
-               goto out;
+               goto clk_unprep;
 
        uap->port.uartclk = clk_get_rate(uap->clk);
 
@@ -343,6 +347,8 @@ static int pl010_startup(struct uart_port *port)
 
  clk_dis:
        clk_disable(uap->clk);
+ clk_unprep:
+       clk_unprepare(uap->clk);
  out:
        return retval;
 }
@@ -370,6 +376,7 @@ static void pl010_shutdown(struct uart_port *port)
         * Shut down the clock producer
         */
        clk_disable(uap->clk);
+       clk_unprepare(uap->clk);
 }
 
 static void
@@ -626,6 +633,7 @@ static int __init pl010_console_setup(struct console *co, char *options)
        int bits = 8;
        int parity = 'n';
        int flow = 'n';
+       int ret;
 
        /*
         * Check whether an invalid uart number has been specified, and
@@ -638,6 +646,10 @@ static int __init pl010_console_setup(struct console *co, char *options)
        if (!uap)
                return -ENODEV;
 
+       ret = clk_prepare(uap->clk);
+       if (ret)
+               return ret;
+
        uap->port.uartclk = clk_get_rate(uap->clk);
 
        if (options)
index f5f6831..00233af 100644 (file)
@@ -1367,12 +1367,16 @@ static int pl011_startup(struct uart_port *port)
        unsigned int cr;
        int retval;
 
+       retval = clk_prepare(uap->clk);
+       if (retval)
+               goto out;
+
        /*
         * Try to enable the clock producer.
         */
        retval = clk_enable(uap->clk);
        if (retval)
-               goto out;
+               goto clk_unprep;
 
        uap->port.uartclk = clk_get_rate(uap->clk);
 
@@ -1446,6 +1450,8 @@ static int pl011_startup(struct uart_port *port)
 
  clk_dis:
        clk_disable(uap->clk);
+ clk_unprep:
+       clk_unprepare(uap->clk);
  out:
        return retval;
 }
@@ -1497,6 +1503,7 @@ static void pl011_shutdown(struct uart_port *port)
         * Shut down the clock producer
         */
        clk_disable(uap->clk);
+       clk_unprepare(uap->clk);
 
        if (uap->port.dev->platform_data) {
                struct amba_pl011_data *plat;
@@ -1800,6 +1807,7 @@ static int __init pl011_console_setup(struct console *co, char *options)
        int bits = 8;
        int parity = 'n';
        int flow = 'n';
+       int ret;
 
        /*
         * Check whether an invalid uart number has been specified, and
@@ -1812,6 +1820,10 @@ static int __init pl011_console_setup(struct console *co, char *options)
        if (!uap)
                return -ENODEV;
 
+       ret = clk_prepare(uap->clk);
+       if (ret)
+               return ret;
+
        if (uap->port.dev->platform_data) {
                struct amba_pl011_data *plat;
 
index cf03ad0..2cda6ba 100644 (file)
@@ -447,6 +447,10 @@ static int clcdfb_register(struct clcd_fb *fb)
                goto out;
        }
 
+       ret = clk_prepare(fb->clk);
+       if (ret)
+               goto free_clk;
+
        fb->fb.device           = &fb->dev->dev;
 
        fb->fb.fix.mmio_start   = fb->dev->res.start;
@@ -456,7 +460,7 @@ static int clcdfb_register(struct clcd_fb *fb)
        if (!fb->regs) {
                printk(KERN_ERR "CLCD: unable to remap registers\n");
                ret = -ENOMEM;
-               goto free_clk;
+               goto clk_unprep;
        }
 
        fb->fb.fbops            = &clcdfb_ops;
@@ -530,6 +534,8 @@ static int clcdfb_register(struct clcd_fb *fb)
        fb_dealloc_cmap(&fb->fb.cmap);
  unmap:
        iounmap(fb->regs);
+ clk_unprep:
+       clk_unprepare(fb->clk);
  free_clk:
        clk_put(fb->clk);
  out:
@@ -595,6 +601,7 @@ static int clcdfb_remove(struct amba_device *dev)
        if (fb->fb.cmap.len)
                fb_dealloc_cmap(&fb->fb.cmap);
        iounmap(fb->regs);
+       clk_unprepare(fb->clk);
        clk_put(fb->clk);
 
        fb->board->remove(fb);
index 1d37f42..7213b52 100644 (file)
@@ -11,6 +11,8 @@
 #ifndef __LINUX_CLK_H
 #define __LINUX_CLK_H
 
+#include <linux/kernel.h>
+
 struct device;
 
 /*
@@ -40,12 +42,32 @@ struct clk;
  */
 struct clk *clk_get(struct device *dev, const char *id);
 
+/**
+ * clk_prepare - prepare a clock source
+ * @clk: clock source
+ *
+ * This prepares the clock source for use.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+int clk_prepare(struct clk *clk);
+#else
+static inline int clk_prepare(struct clk *clk)
+{
+       might_sleep();
+       return 0;
+}
+#endif
+
 /**
  * clk_enable - inform the system when the clock source should be running.
  * @clk: clock source
  *
  * If the clock can not be enabled/disabled, this should return success.
  *
+ * May be called from atomic contexts.
+ *
  * Returns success (0) or negative errno.
  */
 int clk_enable(struct clk *clk);
@@ -57,6 +79,8 @@ int clk_enable(struct clk *clk);
  * Inform the system that a clock source is no longer required by
  * a driver and may be shut down.
  *
+ * May be called from atomic contexts.
+ *
  * Implementation detail: if the clock source is shared between
  * multiple drivers, clk_enable() calls must be balanced by the
  * same number of clk_disable() calls for the clock source to be
@@ -64,6 +88,25 @@ int clk_enable(struct clk *clk);
  */
 void clk_disable(struct clk *clk);
 
+
+/**
+ * clk_unprepare - undo preparation of a clock source
+ * @clk: clock source
+ *
+ * This undoes a previously prepared clock.  The caller must balance
+ * the number of prepare and unprepare calls.
+ *
+ * Must not be called from within atomic context.
+ */
+#ifdef CONFIG_HAVE_CLK_PREPARE
+void clk_unprepare(struct clk *clk);
+#else
+static inline void clk_unprepare(struct clk *clk)
+{
+       might_sleep();
+}
+#endif
+
 /**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *               This is only valid once the clock source has been enabled.
index 457bcb0..d9a4fd0 100644 (file)
@@ -24,6 +24,13 @@ struct clk_lookup {
        struct clk              *clk;
 };
 
+#define CLKDEV_INIT(d, n, c)   \
+       {                       \
+               .dev_id = d,    \
+               .con_id = n,    \
+               .clk = c,       \
+       }
+
 struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
        const char *dev_fmt, ...);