]> Pileus Git - ~andy/linux/blobdiff - drivers/pcmcia/pxa2xx_base.c
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux...
[~andy/linux] / drivers / pcmcia / pxa2xx_base.c
index 55a7d0b045b1d66a28d21527c3123caca11f3119..3755e7c8c715f5f9bebf60c5d9a7ff4a5e250f65 100644 (file)
@@ -179,8 +179,8 @@ static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int cl
 
 static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
 {
-       unsigned int clk = get_memclk_frequency_10khz();
-       return pxa2xx_pcmcia_set_mcxx(skt, clk);
+       unsigned long clk = clk_get_rate(skt->clk);
+       return pxa2xx_pcmcia_set_mcxx(skt, clk / 10000);
 }
 
 #ifdef CONFIG_CPU_FREQ
@@ -282,24 +282,41 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
        struct pcmcia_low_level *ops;
        struct skt_dev_info *sinfo;
        struct soc_pcmcia_socket *skt;
+       struct clk *clk;
 
        ops = (struct pcmcia_low_level *)dev->dev.platform_data;
-       if (!ops)
+       if (!ops) {
+               ret = -ENODEV;
+               goto err0;
+       }
+
+       if (cpu_is_pxa320() && ops->nr > 1) {
+               dev_err(&dev->dev, "pxa320 supports only one pcmcia slot");
+               ret = -EINVAL;
+               goto err0;
+       }
+
+       clk = clk_get(&dev->dev, NULL);
+       if (!clk)
                return -ENODEV;
 
        pxa2xx_drv_pcmcia_ops(ops);
 
        sinfo = kzalloc(SKT_DEV_INFO_SIZE(ops->nr), GFP_KERNEL);
-       if (!sinfo)
+       if (!sinfo) {
+               clk_put(clk);
                return -ENOMEM;
+       }
 
        sinfo->nskt = ops->nr;
+       sinfo->clk = clk;
 
        /* Initialize processor specific parameters */
        for (i = 0; i < ops->nr; i++) {
                skt = &sinfo->skt[i];
 
                skt->nr = ops->first + i;
+               skt->clk = clk;
                skt->ops = ops;
                skt->socket.owner = ops->owner;
                skt->socket.dev.parent = &dev->dev;
@@ -307,18 +324,26 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
 
                ret = pxa2xx_drv_pcmcia_add_one(skt);
                if (ret)
-                       break;
+                       goto err1;
        }
 
        if (ret) {
                while (--i >= 0)
                        soc_pcmcia_remove_one(&sinfo->skt[i]);
                kfree(sinfo);
+               clk_put(clk);
        } else {
                pxa2xx_configure_sockets(&dev->dev);
                dev_set_drvdata(&dev->dev, sinfo);
        }
 
+       return 0;
+
+err1:
+       while (--i >= 0)
+               soc_pcmcia_remove_one(&sinfo->skt[i]);
+       kfree(sinfo);
+err0:
        return ret;
 }
 
@@ -332,6 +357,7 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev)
        for (i = 0; i < sinfo->nskt; i++)
                soc_pcmcia_remove_one(&sinfo->skt[i]);
 
+       clk_put(sinfo->clk);
        kfree(sinfo);
        return 0;
 }