]> Pileus Git - ~andy/linux/blobdiff - drivers/spi/spi-orion.c
Merge branch 'upstream' into bugfix-video
[~andy/linux] / drivers / spi / spi-orion.c
index e496f799b7a9053326a1f68f82a67b49a36eaaea..dfd04e91fa6da35d14c89f3aeb874935d41da339 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/orion_spi.h>
 #include <linux/module.h>
+#include <linux/clk.h>
 #include <asm/unaligned.h>
 
 #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));