diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-07-11 05:31:07 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-07-11 05:31:07 -0400 |
commit | 9e9fd65d1fa51d919d54d731be0e66492b5b6c5a (patch) | |
tree | a1c7bd35ccff62ff2e678514d3599110f18f113a /drivers/spi | |
parent | 05644147064acabb8587c4cbd690047494f7b3a1 (diff) | |
parent | 5b063b87deba33ed1676db9d16c52ede662132d8 (diff) |
Merge branch 'pl022' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson into spi-next
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/spi/spi-imx.c | 38 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c | 30 | ||||
-rw-r--r-- | drivers/spi/spi-pl022.c | 23 |
5 files changed, 62 insertions, 34 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 6eeb8a286a20..0a7256924cf3 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -311,7 +311,7 @@ config SPI_S3C24XX_FIQ | |||
311 | 311 | ||
312 | config SPI_S3C64XX | 312 | config SPI_S3C64XX |
313 | tristate "Samsung S3C64XX series type SPI" | 313 | tristate "Samsung S3C64XX series type SPI" |
314 | depends on (ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS) | 314 | depends on (ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5P64X0 || ARCH_EXYNOS) |
315 | select S3C64XX_DMA if ARCH_S3C64XX | 315 | select S3C64XX_DMA if ARCH_S3C64XX |
316 | help | 316 | help |
317 | SPI driver for Samsung S3C64XX and newer SoCs. | 317 | SPI driver for Samsung S3C64XX and newer SoCs. |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 570f22053be8..47877d687614 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/of.h> | 37 | #include <linux/of.h> |
38 | #include <linux/of_device.h> | 38 | #include <linux/of_device.h> |
39 | #include <linux/of_gpio.h> | 39 | #include <linux/of_gpio.h> |
40 | #include <linux/pinctrl/consumer.h> | ||
40 | 41 | ||
41 | #include <mach/spi.h> | 42 | #include <mach/spi.h> |
42 | 43 | ||
@@ -85,7 +86,8 @@ struct spi_imx_data { | |||
85 | struct completion xfer_done; | 86 | struct completion xfer_done; |
86 | void __iomem *base; | 87 | void __iomem *base; |
87 | int irq; | 88 | int irq; |
88 | struct clk *clk; | 89 | struct clk *clk_per; |
90 | struct clk *clk_ipg; | ||
89 | unsigned long spi_clk; | 91 | unsigned long spi_clk; |
90 | 92 | ||
91 | unsigned int count; | 93 | unsigned int count; |
@@ -758,6 +760,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
758 | struct spi_master *master; | 760 | struct spi_master *master; |
759 | struct spi_imx_data *spi_imx; | 761 | struct spi_imx_data *spi_imx; |
760 | struct resource *res; | 762 | struct resource *res; |
763 | struct pinctrl *pinctrl; | ||
761 | int i, ret, num_cs; | 764 | int i, ret, num_cs; |
762 | 765 | ||
763 | if (!np && !mxc_platform_info) { | 766 | if (!np && !mxc_platform_info) { |
@@ -845,15 +848,28 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
845 | goto out_iounmap; | 848 | goto out_iounmap; |
846 | } | 849 | } |
847 | 850 | ||
848 | spi_imx->clk = clk_get(&pdev->dev, NULL); | 851 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
849 | if (IS_ERR(spi_imx->clk)) { | 852 | if (IS_ERR(pinctrl)) { |
850 | dev_err(&pdev->dev, "unable to get clock\n"); | 853 | ret = PTR_ERR(pinctrl); |
851 | ret = PTR_ERR(spi_imx->clk); | ||
852 | goto out_free_irq; | 854 | goto out_free_irq; |
853 | } | 855 | } |
854 | 856 | ||
855 | clk_enable(spi_imx->clk); | 857 | spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
856 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk); | 858 | if (IS_ERR(spi_imx->clk_ipg)) { |
859 | ret = PTR_ERR(spi_imx->clk_ipg); | ||
860 | goto out_free_irq; | ||
861 | } | ||
862 | |||
863 | spi_imx->clk_per = devm_clk_get(&pdev->dev, "per"); | ||
864 | if (IS_ERR(spi_imx->clk_per)) { | ||
865 | ret = PTR_ERR(spi_imx->clk_per); | ||
866 | goto out_free_irq; | ||
867 | } | ||
868 | |||
869 | clk_prepare_enable(spi_imx->clk_per); | ||
870 | clk_prepare_enable(spi_imx->clk_ipg); | ||
871 | |||
872 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk_per); | ||
857 | 873 | ||
858 | spi_imx->devtype_data->reset(spi_imx); | 874 | spi_imx->devtype_data->reset(spi_imx); |
859 | 875 | ||
@@ -871,8 +887,8 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
871 | return ret; | 887 | return ret; |
872 | 888 | ||
873 | out_clk_put: | 889 | out_clk_put: |
874 | clk_disable(spi_imx->clk); | 890 | clk_disable_unprepare(spi_imx->clk_per); |
875 | clk_put(spi_imx->clk); | 891 | clk_disable_unprepare(spi_imx->clk_ipg); |
876 | out_free_irq: | 892 | out_free_irq: |
877 | free_irq(spi_imx->irq, spi_imx); | 893 | free_irq(spi_imx->irq, spi_imx); |
878 | out_iounmap: | 894 | out_iounmap: |
@@ -900,8 +916,8 @@ static int __devexit spi_imx_remove(struct platform_device *pdev) | |||
900 | spi_bitbang_stop(&spi_imx->bitbang); | 916 | spi_bitbang_stop(&spi_imx->bitbang); |
901 | 917 | ||
902 | writel(0, spi_imx->base + MXC_CSPICTRL); | 918 | writel(0, spi_imx->base + MXC_CSPICTRL); |
903 | clk_disable(spi_imx->clk); | 919 | clk_disable_unprepare(spi_imx->clk_per); |
904 | clk_put(spi_imx->clk); | 920 | clk_disable_unprepare(spi_imx->clk_ipg); |
905 | free_irq(spi_imx->irq, spi_imx); | 921 | free_irq(spi_imx->irq, spi_imx); |
906 | iounmap(spi_imx->base); | 922 | iounmap(spi_imx->base); |
907 | 923 | ||
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 46ef5fe51db5..0c73dd4f43a0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -801,7 +801,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) | |||
801 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 801 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
802 | 802 | ||
803 | if (!cs) { | 803 | if (!cs) { |
804 | cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); | 804 | cs = kzalloc(sizeof *cs, GFP_KERNEL); |
805 | if (!cs) | 805 | if (!cs) |
806 | return -ENOMEM; | 806 | return -ENOMEM; |
807 | cs->base = mcspi->base + spi->chip_select * 0x14; | 807 | cs->base = mcspi->base + spi->chip_select * 0x14; |
@@ -842,6 +842,7 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) | |||
842 | cs = spi->controller_state; | 842 | cs = spi->controller_state; |
843 | list_del(&cs->node); | 843 | list_del(&cs->node); |
844 | 844 | ||
845 | kfree(cs); | ||
845 | } | 846 | } |
846 | 847 | ||
847 | if (spi->chip_select < spi->master->num_chipselect) { | 848 | if (spi->chip_select < spi->master->num_chipselect) { |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index e496f799b7a9..dfd04e91fa6d 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
@@ -16,8 +16,8 @@ | |||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
19 | #include <linux/spi/orion_spi.h> | ||
20 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/clk.h> | ||
21 | #include <asm/unaligned.h> | 21 | #include <asm/unaligned.h> |
22 | 22 | ||
23 | #define DRIVER_NAME "orion_spi" | 23 | #define DRIVER_NAME "orion_spi" |
@@ -46,6 +46,7 @@ struct orion_spi { | |||
46 | unsigned int max_speed; | 46 | unsigned int max_speed; |
47 | unsigned int min_speed; | 47 | unsigned int min_speed; |
48 | struct orion_spi_info *spi_info; | 48 | struct orion_spi_info *spi_info; |
49 | struct clk *clk; | ||
49 | }; | 50 | }; |
50 | 51 | ||
51 | static struct workqueue_struct *orion_spi_wq; | 52 | static struct workqueue_struct *orion_spi_wq; |
@@ -104,7 +105,7 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed) | |||
104 | 105 | ||
105 | orion_spi = spi_master_get_devdata(spi->master); | 106 | orion_spi = spi_master_get_devdata(spi->master); |
106 | 107 | ||
107 | tclk_hz = orion_spi->spi_info->tclk; | 108 | tclk_hz = clk_get_rate(orion_spi->clk); |
108 | 109 | ||
109 | /* | 110 | /* |
110 | * the supported rates are: 4,6,8...30 | 111 | * the supported rates are: 4,6,8...30 |
@@ -450,6 +451,7 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
450 | struct orion_spi *spi; | 451 | struct orion_spi *spi; |
451 | struct resource *r; | 452 | struct resource *r; |
452 | struct orion_spi_info *spi_info; | 453 | struct orion_spi_info *spi_info; |
454 | unsigned long tclk_hz; | ||
453 | int status = 0; | 455 | int status = 0; |
454 | 456 | ||
455 | spi_info = pdev->dev.platform_data; | 457 | spi_info = pdev->dev.platform_data; |
@@ -476,19 +478,28 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
476 | spi->master = master; | 478 | spi->master = master; |
477 | spi->spi_info = spi_info; | 479 | spi->spi_info = spi_info; |
478 | 480 | ||
479 | spi->max_speed = DIV_ROUND_UP(spi_info->tclk, 4); | 481 | spi->clk = clk_get(&pdev->dev, NULL); |
480 | spi->min_speed = DIV_ROUND_UP(spi_info->tclk, 30); | 482 | if (IS_ERR(spi->clk)) { |
483 | status = PTR_ERR(spi->clk); | ||
484 | goto out; | ||
485 | } | ||
486 | |||
487 | clk_prepare(spi->clk); | ||
488 | clk_enable(spi->clk); | ||
489 | tclk_hz = clk_get_rate(spi->clk); | ||
490 | spi->max_speed = DIV_ROUND_UP(tclk_hz, 4); | ||
491 | spi->min_speed = DIV_ROUND_UP(tclk_hz, 30); | ||
481 | 492 | ||
482 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 493 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
483 | if (r == NULL) { | 494 | if (r == NULL) { |
484 | status = -ENODEV; | 495 | status = -ENODEV; |
485 | goto out; | 496 | goto out_rel_clk; |
486 | } | 497 | } |
487 | 498 | ||
488 | if (!request_mem_region(r->start, resource_size(r), | 499 | if (!request_mem_region(r->start, resource_size(r), |
489 | dev_name(&pdev->dev))) { | 500 | dev_name(&pdev->dev))) { |
490 | status = -EBUSY; | 501 | status = -EBUSY; |
491 | goto out; | 502 | goto out_rel_clk; |
492 | } | 503 | } |
493 | spi->base = ioremap(r->start, SZ_1K); | 504 | spi->base = ioremap(r->start, SZ_1K); |
494 | 505 | ||
@@ -508,7 +519,9 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
508 | 519 | ||
509 | out_rel_mem: | 520 | out_rel_mem: |
510 | release_mem_region(r->start, resource_size(r)); | 521 | release_mem_region(r->start, resource_size(r)); |
511 | 522 | out_rel_clk: | |
523 | clk_disable_unprepare(spi->clk); | ||
524 | clk_put(spi->clk); | ||
512 | out: | 525 | out: |
513 | spi_master_put(master); | 526 | spi_master_put(master); |
514 | return status; | 527 | return status; |
@@ -526,6 +539,9 @@ static int __exit orion_spi_remove(struct platform_device *pdev) | |||
526 | 539 | ||
527 | cancel_work_sync(&spi->work); | 540 | cancel_work_sync(&spi->work); |
528 | 541 | ||
542 | clk_disable_unprepare(spi->clk); | ||
543 | clk_put(spi->clk); | ||
544 | |||
529 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 545 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
530 | release_mem_region(r->start, resource_size(r)); | 546 | release_mem_region(r->start, resource_size(r)); |
531 | 547 | ||
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 400ae2121a2a..aab518ec2bbc 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -489,6 +489,11 @@ static void giveback(struct pl022 *pl022) | |||
489 | pl022->cur_transfer = NULL; | 489 | pl022->cur_transfer = NULL; |
490 | pl022->cur_chip = NULL; | 490 | pl022->cur_chip = NULL; |
491 | spi_finalize_current_message(pl022->master); | 491 | spi_finalize_current_message(pl022->master); |
492 | |||
493 | /* disable the SPI/SSP operation */ | ||
494 | writew((readw(SSP_CR1(pl022->virtbase)) & | ||
495 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | ||
496 | |||
492 | } | 497 | } |
493 | 498 | ||
494 | /** | 499 | /** |
@@ -2048,6 +2053,9 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2048 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
2049 | adev->res.start, pl022->virtbase); | 2054 | adev->res.start, pl022->virtbase); |
2050 | 2055 | ||
2056 | pm_runtime_enable(dev); | ||
2057 | pm_runtime_resume(dev); | ||
2058 | |||
2051 | pl022->clk = clk_get(&adev->dev, NULL); | 2059 | pl022->clk = clk_get(&adev->dev, NULL); |
2052 | if (IS_ERR(pl022->clk)) { | 2060 | if (IS_ERR(pl022->clk)) { |
2053 | status = PTR_ERR(pl022->clk); | 2061 | status = PTR_ERR(pl022->clk); |
@@ -2158,6 +2166,7 @@ pl022_remove(struct amba_device *adev) | |||
2158 | clk_disable(pl022->clk); | 2166 | clk_disable(pl022->clk); |
2159 | clk_unprepare(pl022->clk); | 2167 | clk_unprepare(pl022->clk); |
2160 | clk_put(pl022->clk); | 2168 | clk_put(pl022->clk); |
2169 | pm_runtime_disable(&adev->dev); | ||
2161 | iounmap(pl022->virtbase); | 2170 | iounmap(pl022->virtbase); |
2162 | amba_release_regions(adev); | 2171 | amba_release_regions(adev); |
2163 | tasklet_disable(&pl022->pump_transfers); | 2172 | tasklet_disable(&pl022->pump_transfers); |
@@ -2251,15 +2260,6 @@ static struct vendor_data vendor_st_pl023 = { | |||
2251 | .loopback = false, | 2260 | .loopback = false, |
2252 | }; | 2261 | }; |
2253 | 2262 | ||
2254 | static struct vendor_data vendor_db5500_pl023 = { | ||
2255 | .fifodepth = 32, | ||
2256 | .max_bpw = 32, | ||
2257 | .unidir = false, | ||
2258 | .extended_cr = true, | ||
2259 | .pl023 = true, | ||
2260 | .loopback = true, | ||
2261 | }; | ||
2262 | |||
2263 | static struct amba_id pl022_ids[] = { | 2263 | static struct amba_id pl022_ids[] = { |
2264 | { | 2264 | { |
2265 | /* | 2265 | /* |
@@ -2291,11 +2291,6 @@ static struct amba_id pl022_ids[] = { | |||
2291 | .mask = 0xffffffff, | 2291 | .mask = 0xffffffff, |
2292 | .data = &vendor_st_pl023, | 2292 | .data = &vendor_st_pl023, |
2293 | }, | 2293 | }, |
2294 | { | ||
2295 | .id = 0x10080023, | ||
2296 | .mask = 0xffffffff, | ||
2297 | .data = &vendor_db5500_pl023, | ||
2298 | }, | ||
2299 | { 0, 0 }, | 2294 | { 0, 0 }, |
2300 | }; | 2295 | }; |
2301 | 2296 | ||