diff options
Diffstat (limited to 'drivers/spi')
45 files changed, 468 insertions, 631 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 52e2900d9d8e..a1fd73df5416 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -88,7 +88,7 @@ config SPI_BFIN_SPORT | |||
| 88 | 88 | ||
| 89 | config SPI_AU1550 | 89 | config SPI_AU1550 |
| 90 | tristate "Au1550/Au12x0 SPI Controller" | 90 | tristate "Au1550/Au12x0 SPI Controller" |
| 91 | depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL | 91 | depends on MIPS_ALCHEMY && EXPERIMENTAL |
| 92 | select SPI_BITBANG | 92 | select SPI_BITBANG |
| 93 | help | 93 | help |
| 94 | If you say yes to this option, support will be included for the | 94 | If you say yes to this option, support will be included for the |
diff --git a/drivers/spi/spi-altera.c b/drivers/spi/spi-altera.c index 4813a63ce6fb..c00d00e96ee4 100644 --- a/drivers/spi/spi-altera.c +++ b/drivers/spi/spi-altera.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
| 19 | #include <linux/module.h> | ||
| 19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 20 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 21 | #include <linux/spi/spi_bitbang.h> | 22 | #include <linux/spi/spi_bitbang.h> |
| @@ -320,18 +321,7 @@ static struct platform_driver altera_spi_driver = { | |||
| 320 | .of_match_table = altera_spi_match, | 321 | .of_match_table = altera_spi_match, |
| 321 | }, | 322 | }, |
| 322 | }; | 323 | }; |
| 323 | 324 | module_platform_driver(altera_spi_driver); | |
| 324 | static int __init altera_spi_init(void) | ||
| 325 | { | ||
| 326 | return platform_driver_register(&altera_spi_driver); | ||
| 327 | } | ||
| 328 | module_init(altera_spi_init); | ||
| 329 | |||
| 330 | static void __exit altera_spi_exit(void) | ||
| 331 | { | ||
| 332 | platform_driver_unregister(&altera_spi_driver); | ||
| 333 | } | ||
| 334 | module_exit(altera_spi_exit); | ||
| 335 | 325 | ||
| 336 | MODULE_DESCRIPTION("Altera SPI driver"); | 326 | MODULE_DESCRIPTION("Altera SPI driver"); |
| 337 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | 327 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); |
diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c index 03019bf5a5e9..024b48aed5ca 100644 --- a/drivers/spi/spi-ath79.c +++ b/drivers/spi/spi-ath79.c | |||
| @@ -273,18 +273,7 @@ static struct platform_driver ath79_spi_driver = { | |||
| 273 | .owner = THIS_MODULE, | 273 | .owner = THIS_MODULE, |
| 274 | }, | 274 | }, |
| 275 | }; | 275 | }; |
| 276 | 276 | module_platform_driver(ath79_spi_driver); | |
| 277 | static __init int ath79_spi_init(void) | ||
| 278 | { | ||
| 279 | return platform_driver_register(&ath79_spi_driver); | ||
| 280 | } | ||
| 281 | module_init(ath79_spi_init); | ||
| 282 | |||
| 283 | static __exit void ath79_spi_exit(void) | ||
| 284 | { | ||
| 285 | platform_driver_unregister(&ath79_spi_driver); | ||
| 286 | } | ||
| 287 | module_exit(ath79_spi_exit); | ||
| 288 | 277 | ||
| 289 | MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR913X"); | 278 | MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR913X"); |
| 290 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | 279 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); |
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 82dee9a6c0de..16d6a839c7fa 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <asm/io.h> | 23 | #include <asm/io.h> |
| 24 | #include <mach/board.h> | 24 | #include <mach/board.h> |
| 25 | #include <mach/gpio.h> | 25 | #include <asm/gpio.h> |
| 26 | #include <mach/cpu.h> | 26 | #include <mach/cpu.h> |
| 27 | 27 | ||
| 28 | /* SPI register offsets */ | 28 | /* SPI register offsets */ |
| @@ -907,7 +907,7 @@ static void atmel_spi_cleanup(struct spi_device *spi) | |||
| 907 | 907 | ||
| 908 | /*-------------------------------------------------------------------------*/ | 908 | /*-------------------------------------------------------------------------*/ |
| 909 | 909 | ||
| 910 | static int __init atmel_spi_probe(struct platform_device *pdev) | 910 | static int __devinit atmel_spi_probe(struct platform_device *pdev) |
| 911 | { | 911 | { |
| 912 | struct resource *regs; | 912 | struct resource *regs; |
| 913 | int irq; | 913 | int irq; |
| @@ -1003,7 +1003,7 @@ out_free: | |||
| 1003 | return ret; | 1003 | return ret; |
| 1004 | } | 1004 | } |
| 1005 | 1005 | ||
| 1006 | static int __exit atmel_spi_remove(struct platform_device *pdev) | 1006 | static int __devexit atmel_spi_remove(struct platform_device *pdev) |
| 1007 | { | 1007 | { |
| 1008 | struct spi_master *master = platform_get_drvdata(pdev); | 1008 | struct spi_master *master = platform_get_drvdata(pdev); |
| 1009 | struct atmel_spi *as = spi_master_get_devdata(master); | 1009 | struct atmel_spi *as = spi_master_get_devdata(master); |
| @@ -1072,20 +1072,10 @@ static struct platform_driver atmel_spi_driver = { | |||
| 1072 | }, | 1072 | }, |
| 1073 | .suspend = atmel_spi_suspend, | 1073 | .suspend = atmel_spi_suspend, |
| 1074 | .resume = atmel_spi_resume, | 1074 | .resume = atmel_spi_resume, |
| 1075 | .probe = atmel_spi_probe, | ||
| 1075 | .remove = __exit_p(atmel_spi_remove), | 1076 | .remove = __exit_p(atmel_spi_remove), |
| 1076 | }; | 1077 | }; |
| 1077 | 1078 | module_platform_driver(atmel_spi_driver); | |
| 1078 | static int __init atmel_spi_init(void) | ||
| 1079 | { | ||
| 1080 | return platform_driver_probe(&atmel_spi_driver, atmel_spi_probe); | ||
| 1081 | } | ||
| 1082 | module_init(atmel_spi_init); | ||
| 1083 | |||
| 1084 | static void __exit atmel_spi_exit(void) | ||
| 1085 | { | ||
| 1086 | platform_driver_unregister(&atmel_spi_driver); | ||
| 1087 | } | ||
| 1088 | module_exit(atmel_spi_exit); | ||
| 1089 | 1079 | ||
| 1090 | MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver"); | 1080 | MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver"); |
| 1091 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); | 1081 | MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); |
diff --git a/drivers/spi/spi-au1550.c b/drivers/spi/spi-au1550.c index bddee5f516b2..5784c8799616 100644 --- a/drivers/spi/spi-au1550.c +++ b/drivers/spi/spi-au1550.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
| 28 | #include <linux/module.h> | ||
| 28 | #include <linux/device.h> | 29 | #include <linux/device.h> |
| 29 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
| 30 | #include <linux/resource.h> | 31 | #include <linux/resource.h> |
diff --git a/drivers/spi/spi-bfin-sport.c b/drivers/spi/spi-bfin-sport.c index e557ff617b11..248a2cc671a9 100644 --- a/drivers/spi/spi-bfin-sport.c +++ b/drivers/spi/spi-bfin-sport.c | |||
| @@ -938,15 +938,4 @@ static struct platform_driver bfin_sport_spi_driver = { | |||
| 938 | .suspend = bfin_sport_spi_suspend, | 938 | .suspend = bfin_sport_spi_suspend, |
| 939 | .resume = bfin_sport_spi_resume, | 939 | .resume = bfin_sport_spi_resume, |
| 940 | }; | 940 | }; |
| 941 | 941 | module_platform_driver(bfin_sport_spi_driver); | |
| 942 | static int __init bfin_sport_spi_init(void) | ||
| 943 | { | ||
| 944 | return platform_driver_register(&bfin_sport_spi_driver); | ||
| 945 | } | ||
| 946 | module_init(bfin_sport_spi_init); | ||
| 947 | |||
| 948 | static void __exit bfin_sport_spi_exit(void) | ||
| 949 | { | ||
| 950 | platform_driver_unregister(&bfin_sport_spi_driver); | ||
| 951 | } | ||
| 952 | module_exit(bfin_sport_spi_exit); | ||
diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index b8d25f2b7038..3b83ff8b1e2b 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c | |||
| @@ -1098,7 +1098,7 @@ static int bfin_spi_setup(struct spi_device *spi) | |||
| 1098 | 1098 | ||
| 1099 | if (chip->pio_interrupt && !drv_data->irq_requested) { | 1099 | if (chip->pio_interrupt && !drv_data->irq_requested) { |
| 1100 | ret = request_irq(drv_data->spi_irq, bfin_spi_pio_irq_handler, | 1100 | ret = request_irq(drv_data->spi_irq, bfin_spi_pio_irq_handler, |
| 1101 | IRQF_DISABLED, "BFIN_SPI", drv_data); | 1101 | 0, "BFIN_SPI", drv_data); |
| 1102 | if (ret) { | 1102 | if (ret) { |
| 1103 | dev_err(&spi->dev, "Unable to register spi IRQ\n"); | 1103 | dev_err(&spi->dev, "Unable to register spi IRQ\n"); |
| 1104 | goto error; | 1104 | goto error; |
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 02d57fbba295..aef59b1a15f7 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
| 21 | #include <linux/workqueue.h> | 21 | #include <linux/workqueue.h> |
| 22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
| 23 | #include <linux/module.h> | ||
| 23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 24 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
| 25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 9f907ec52def..5ed08e537433 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
| 23 | #include <linux/module.h> | ||
| 23 | #include <linux/device.h> | 24 | #include <linux/device.h> |
| 24 | #include <linux/parport.h> | 25 | #include <linux/parport.h> |
| 25 | 26 | ||
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index ae2cd1c1fda8..6eee64a5d240 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
| @@ -487,7 +487,7 @@ static int __devinit mcfqspi_probe(struct platform_device *pdev) | |||
| 487 | goto fail2; | 487 | goto fail2; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, IRQF_DISABLED, | 490 | status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, 0, |
| 491 | pdev->name, mcfqspi); | 491 | pdev->name, mcfqspi); |
| 492 | if (status) { | 492 | if (status) { |
| 493 | dev_dbg(&pdev->dev, "request_irq failed\n"); | 493 | dev_dbg(&pdev->dev, "request_irq failed\n"); |
| @@ -621,20 +621,10 @@ static struct platform_driver mcfqspi_driver = { | |||
| 621 | .driver.name = DRIVER_NAME, | 621 | .driver.name = DRIVER_NAME, |
| 622 | .driver.owner = THIS_MODULE, | 622 | .driver.owner = THIS_MODULE, |
| 623 | .driver.pm = MCFQSPI_DEV_PM_OPS, | 623 | .driver.pm = MCFQSPI_DEV_PM_OPS, |
| 624 | .probe = mcfqspi_probe, | ||
| 624 | .remove = __devexit_p(mcfqspi_remove), | 625 | .remove = __devexit_p(mcfqspi_remove), |
| 625 | }; | 626 | }; |
| 626 | 627 | module_platform_driver(mcfqspi_driver); | |
| 627 | static int __init mcfqspi_init(void) | ||
| 628 | { | ||
| 629 | return platform_driver_probe(&mcfqspi_driver, mcfqspi_probe); | ||
| 630 | } | ||
| 631 | module_init(mcfqspi_init); | ||
| 632 | |||
| 633 | static void __exit mcfqspi_exit(void) | ||
| 634 | { | ||
| 635 | platform_driver_unregister(&mcfqspi_driver); | ||
| 636 | } | ||
| 637 | module_exit(mcfqspi_exit); | ||
| 638 | 628 | ||
| 639 | MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); | 629 | MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); |
| 640 | MODULE_DESCRIPTION("Coldfire QSPI Controller Driver"); | 630 | MODULE_DESCRIPTION("Coldfire QSPI Controller Driver"); |
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 1f0ed8005c91..31bfba805cf4 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
| @@ -799,7 +799,7 @@ rx_dma_failed: | |||
| 799 | * It will invoke spi_bitbang_start to create work queue so that client driver | 799 | * It will invoke spi_bitbang_start to create work queue so that client driver |
| 800 | * can register transfer method to work queue. | 800 | * can register transfer method to work queue. |
| 801 | */ | 801 | */ |
| 802 | static int davinci_spi_probe(struct platform_device *pdev) | 802 | static int __devinit davinci_spi_probe(struct platform_device *pdev) |
| 803 | { | 803 | { |
| 804 | struct spi_master *master; | 804 | struct spi_master *master; |
| 805 | struct davinci_spi *dspi; | 805 | struct davinci_spi *dspi; |
| @@ -984,7 +984,7 @@ err: | |||
| 984 | * It will also call spi_bitbang_stop to destroy the work queue which was | 984 | * It will also call spi_bitbang_stop to destroy the work queue which was |
| 985 | * created by spi_bitbang_start. | 985 | * created by spi_bitbang_start. |
| 986 | */ | 986 | */ |
| 987 | static int __exit davinci_spi_remove(struct platform_device *pdev) | 987 | static int __devexit davinci_spi_remove(struct platform_device *pdev) |
| 988 | { | 988 | { |
| 989 | struct davinci_spi *dspi; | 989 | struct davinci_spi *dspi; |
| 990 | struct spi_master *master; | 990 | struct spi_master *master; |
| @@ -1011,20 +1011,10 @@ static struct platform_driver davinci_spi_driver = { | |||
| 1011 | .name = "spi_davinci", | 1011 | .name = "spi_davinci", |
| 1012 | .owner = THIS_MODULE, | 1012 | .owner = THIS_MODULE, |
| 1013 | }, | 1013 | }, |
| 1014 | .remove = __exit_p(davinci_spi_remove), | 1014 | .probe = davinci_spi_probe, |
| 1015 | .remove = __devexit_p(davinci_spi_remove), | ||
| 1015 | }; | 1016 | }; |
| 1016 | 1017 | module_platform_driver(davinci_spi_driver); | |
| 1017 | static int __init davinci_spi_init(void) | ||
| 1018 | { | ||
| 1019 | return platform_driver_probe(&davinci_spi_driver, davinci_spi_probe); | ||
| 1020 | } | ||
| 1021 | module_init(davinci_spi_init); | ||
| 1022 | |||
| 1023 | static void __exit davinci_spi_exit(void) | ||
| 1024 | { | ||
| 1025 | platform_driver_unregister(&davinci_spi_driver); | ||
| 1026 | } | ||
| 1027 | module_exit(davinci_spi_exit); | ||
| 1028 | 1018 | ||
| 1029 | MODULE_DESCRIPTION("TI DaVinci SPI Master Controller Driver"); | 1019 | MODULE_DESCRIPTION("TI DaVinci SPI Master Controller Driver"); |
| 1030 | MODULE_LICENSE("GPL"); | 1020 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c index 130e55537db6..e743a45ee92c 100644 --- a/drivers/spi/spi-dw-mid.c +++ b/drivers/spi/spi-dw-mid.c | |||
| @@ -116,13 +116,13 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change) | |||
| 116 | /* 1. setup DMA related registers */ | 116 | /* 1. setup DMA related registers */ |
| 117 | if (cs_change) { | 117 | if (cs_change) { |
| 118 | spi_enable_chip(dws, 0); | 118 | spi_enable_chip(dws, 0); |
| 119 | dw_writew(dws, dmardlr, 0xf); | 119 | dw_writew(dws, DW_SPI_DMARDLR, 0xf); |
| 120 | dw_writew(dws, dmatdlr, 0x10); | 120 | dw_writew(dws, DW_SPI_DMATDLR, 0x10); |
| 121 | if (dws->tx_dma) | 121 | if (dws->tx_dma) |
| 122 | dma_ctrl |= 0x2; | 122 | dma_ctrl |= 0x2; |
| 123 | if (dws->rx_dma) | 123 | if (dws->rx_dma) |
| 124 | dma_ctrl |= 0x1; | 124 | dma_ctrl |= 0x1; |
| 125 | dw_writew(dws, dmacr, dma_ctrl); | 125 | dw_writew(dws, DW_SPI_DMACR, dma_ctrl); |
| 126 | spi_enable_chip(dws, 1); | 126 | spi_enable_chip(dws, 1); |
| 127 | } | 127 | } |
| 128 | 128 | ||
| @@ -200,7 +200,8 @@ static struct dw_spi_dma_ops mid_dma_ops = { | |||
| 200 | 200 | ||
| 201 | int dw_spi_mid_init(struct dw_spi *dws) | 201 | int dw_spi_mid_init(struct dw_spi *dws) |
| 202 | { | 202 | { |
| 203 | u32 *clk_reg, clk_cdiv; | 203 | void __iomem *clk_reg; |
| 204 | u32 clk_cdiv; | ||
| 204 | 205 | ||
| 205 | clk_reg = ioremap_nocache(MRST_CLK_SPI0_REG, 16); | 206 | clk_reg = ioremap_nocache(MRST_CLK_SPI0_REG, 16); |
| 206 | if (!clk_reg) | 207 | if (!clk_reg) |
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 34eb66501dbf..db2f1ba06eab 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/spi/spi.h> | 16 | #include <linux/spi/spi.h> |
| 17 | #include <linux/scatterlist.h> | 17 | #include <linux/scatterlist.h> |
| 18 | #include <linux/module.h> | ||
| 18 | 19 | ||
| 19 | #include "spi-dw.h" | 20 | #include "spi-dw.h" |
| 20 | 21 | ||
| @@ -127,24 +128,14 @@ static int __devexit dw_spi_mmio_remove(struct platform_device *pdev) | |||
| 127 | } | 128 | } |
| 128 | 129 | ||
| 129 | static struct platform_driver dw_spi_mmio_driver = { | 130 | static struct platform_driver dw_spi_mmio_driver = { |
| 131 | .probe = dw_spi_mmio_probe, | ||
| 130 | .remove = __devexit_p(dw_spi_mmio_remove), | 132 | .remove = __devexit_p(dw_spi_mmio_remove), |
| 131 | .driver = { | 133 | .driver = { |
| 132 | .name = DRIVER_NAME, | 134 | .name = DRIVER_NAME, |
| 133 | .owner = THIS_MODULE, | 135 | .owner = THIS_MODULE, |
| 134 | }, | 136 | }, |
| 135 | }; | 137 | }; |
| 136 | 138 | module_platform_driver(dw_spi_mmio_driver); | |
| 137 | static int __init dw_spi_mmio_init(void) | ||
| 138 | { | ||
| 139 | return platform_driver_probe(&dw_spi_mmio_driver, dw_spi_mmio_probe); | ||
| 140 | } | ||
| 141 | module_init(dw_spi_mmio_init); | ||
| 142 | |||
| 143 | static void __exit dw_spi_mmio_exit(void) | ||
| 144 | { | ||
| 145 | platform_driver_unregister(&dw_spi_mmio_driver); | ||
| 146 | } | ||
| 147 | module_exit(dw_spi_mmio_exit); | ||
| 148 | 139 | ||
| 149 | MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>"); | 140 | MODULE_AUTHOR("Jean-Hugues Deschenes <jean-hugues.deschenes@octasic.com>"); |
| 150 | MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core"); | 141 | MODULE_DESCRIPTION("Memory-mapped I/O interface driver for DW SPI Core"); |
diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c index c5f37f03ac8b..f64250ea1611 100644 --- a/drivers/spi/spi-dw-pci.c +++ b/drivers/spi/spi-dw-pci.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/pci.h> | 21 | #include <linux/pci.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
| 24 | #include <linux/module.h> | ||
| 24 | 25 | ||
| 25 | #include "spi-dw.h" | 26 | #include "spi-dw.h" |
| 26 | 27 | ||
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 857cd30b44bb..082458d73ce9 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | #include <linux/dma-mapping.h> | 20 | #include <linux/dma-mapping.h> |
| 21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
| 22 | #include <linux/module.h> | ||
| 22 | #include <linux/highmem.h> | 23 | #include <linux/highmem.h> |
| 23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| @@ -88,35 +89,35 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf, | |||
| 88 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 89 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 89 | "=================================\n"); | 90 | "=================================\n"); |
| 90 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 91 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 91 | "CTRL0: \t\t0x%08x\n", dw_readl(dws, ctrl0)); | 92 | "CTRL0: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL0)); |
| 92 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 93 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 93 | "CTRL1: \t\t0x%08x\n", dw_readl(dws, ctrl1)); | 94 | "CTRL1: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL1)); |
| 94 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 95 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 95 | "SSIENR: \t0x%08x\n", dw_readl(dws, ssienr)); | 96 | "SSIENR: \t0x%08x\n", dw_readl(dws, DW_SPI_SSIENR)); |
| 96 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 97 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 97 | "SER: \t\t0x%08x\n", dw_readl(dws, ser)); | 98 | "SER: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SER)); |
| 98 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 99 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 99 | "BAUDR: \t\t0x%08x\n", dw_readl(dws, baudr)); | 100 | "BAUDR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_BAUDR)); |
| 100 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 101 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 101 | "TXFTLR: \t0x%08x\n", dw_readl(dws, txfltr)); | 102 | "TXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_TXFLTR)); |
| 102 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 103 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 103 | "RXFTLR: \t0x%08x\n", dw_readl(dws, rxfltr)); | 104 | "RXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_RXFLTR)); |
| 104 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 105 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 105 | "TXFLR: \t\t0x%08x\n", dw_readl(dws, txflr)); | 106 | "TXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_TXFLR)); |
| 106 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 107 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 107 | "RXFLR: \t\t0x%08x\n", dw_readl(dws, rxflr)); | 108 | "RXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_RXFLR)); |
| 108 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 109 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 109 | "SR: \t\t0x%08x\n", dw_readl(dws, sr)); | 110 | "SR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SR)); |
| 110 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 111 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 111 | "IMR: \t\t0x%08x\n", dw_readl(dws, imr)); | 112 | "IMR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_IMR)); |
| 112 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 113 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 113 | "ISR: \t\t0x%08x\n", dw_readl(dws, isr)); | 114 | "ISR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_ISR)); |
| 114 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 115 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 115 | "DMACR: \t\t0x%08x\n", dw_readl(dws, dmacr)); | 116 | "DMACR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_DMACR)); |
| 116 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 117 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 117 | "DMATDLR: \t0x%08x\n", dw_readl(dws, dmatdlr)); | 118 | "DMATDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMATDLR)); |
| 118 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 119 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 119 | "DMARDLR: \t0x%08x\n", dw_readl(dws, dmardlr)); | 120 | "DMARDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMARDLR)); |
| 120 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, | 121 | len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, |
| 121 | "=================================\n"); | 122 | "=================================\n"); |
| 122 | 123 | ||
| @@ -166,7 +167,7 @@ static inline u32 tx_max(struct dw_spi *dws) | |||
| 166 | u32 tx_left, tx_room, rxtx_gap; | 167 | u32 tx_left, tx_room, rxtx_gap; |
| 167 | 168 | ||
| 168 | tx_left = (dws->tx_end - dws->tx) / dws->n_bytes; | 169 | tx_left = (dws->tx_end - dws->tx) / dws->n_bytes; |
| 169 | tx_room = dws->fifo_len - dw_readw(dws, txflr); | 170 | tx_room = dws->fifo_len - dw_readw(dws, DW_SPI_TXFLR); |
| 170 | 171 | ||
| 171 | /* | 172 | /* |
| 172 | * Another concern is about the tx/rx mismatch, we | 173 | * Another concern is about the tx/rx mismatch, we |
| @@ -187,7 +188,7 @@ static inline u32 rx_max(struct dw_spi *dws) | |||
| 187 | { | 188 | { |
| 188 | u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; | 189 | u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; |
| 189 | 190 | ||
| 190 | return min(rx_left, (u32)dw_readw(dws, rxflr)); | 191 | return min(rx_left, (u32)dw_readw(dws, DW_SPI_RXFLR)); |
| 191 | } | 192 | } |
| 192 | 193 | ||
| 193 | static void dw_writer(struct dw_spi *dws) | 194 | static void dw_writer(struct dw_spi *dws) |
| @@ -203,7 +204,7 @@ static void dw_writer(struct dw_spi *dws) | |||
| 203 | else | 204 | else |
| 204 | txw = *(u16 *)(dws->tx); | 205 | txw = *(u16 *)(dws->tx); |
| 205 | } | 206 | } |
| 206 | dw_writew(dws, dr, txw); | 207 | dw_writew(dws, DW_SPI_DR, txw); |
| 207 | dws->tx += dws->n_bytes; | 208 | dws->tx += dws->n_bytes; |
| 208 | } | 209 | } |
| 209 | } | 210 | } |
| @@ -214,7 +215,7 @@ static void dw_reader(struct dw_spi *dws) | |||
| 214 | u16 rxw; | 215 | u16 rxw; |
| 215 | 216 | ||
| 216 | while (max--) { | 217 | while (max--) { |
| 217 | rxw = dw_readw(dws, dr); | 218 | rxw = dw_readw(dws, DW_SPI_DR); |
| 218 | /* Care rx only if the transfer's original "rx" is not null */ | 219 | /* Care rx only if the transfer's original "rx" is not null */ |
| 219 | if (dws->rx_end - dws->len) { | 220 | if (dws->rx_end - dws->len) { |
| 220 | if (dws->n_bytes == 1) | 221 | if (dws->n_bytes == 1) |
| @@ -322,13 +323,13 @@ EXPORT_SYMBOL_GPL(dw_spi_xfer_done); | |||
| 322 | 323 | ||
| 323 | static irqreturn_t interrupt_transfer(struct dw_spi *dws) | 324 | static irqreturn_t interrupt_transfer(struct dw_spi *dws) |
| 324 | { | 325 | { |
| 325 | u16 irq_status = dw_readw(dws, isr); | 326 | u16 irq_status = dw_readw(dws, DW_SPI_ISR); |
| 326 | 327 | ||
| 327 | /* Error handling */ | 328 | /* Error handling */ |
| 328 | if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { | 329 | if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { |
| 329 | dw_readw(dws, txoicr); | 330 | dw_readw(dws, DW_SPI_TXOICR); |
| 330 | dw_readw(dws, rxoicr); | 331 | dw_readw(dws, DW_SPI_RXOICR); |
| 331 | dw_readw(dws, rxuicr); | 332 | dw_readw(dws, DW_SPI_RXUICR); |
| 332 | int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun"); | 333 | int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun"); |
| 333 | return IRQ_HANDLED; | 334 | return IRQ_HANDLED; |
| 334 | } | 335 | } |
| @@ -352,7 +353,7 @@ static irqreturn_t interrupt_transfer(struct dw_spi *dws) | |||
| 352 | static irqreturn_t dw_spi_irq(int irq, void *dev_id) | 353 | static irqreturn_t dw_spi_irq(int irq, void *dev_id) |
| 353 | { | 354 | { |
| 354 | struct dw_spi *dws = dev_id; | 355 | struct dw_spi *dws = dev_id; |
| 355 | u16 irq_status = dw_readw(dws, isr) & 0x3f; | 356 | u16 irq_status = dw_readw(dws, DW_SPI_ISR) & 0x3f; |
| 356 | 357 | ||
| 357 | if (!irq_status) | 358 | if (!irq_status) |
| 358 | return IRQ_NONE; | 359 | return IRQ_NONE; |
| @@ -520,11 +521,11 @@ static void pump_transfers(unsigned long data) | |||
| 520 | * 2. clk_div is changed | 521 | * 2. clk_div is changed |
| 521 | * 3. control value changes | 522 | * 3. control value changes |
| 522 | */ | 523 | */ |
| 523 | if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div || imask) { | 524 | if (dw_readw(dws, DW_SPI_CTRL0) != cr0 || cs_change || clk_div || imask) { |
| 524 | spi_enable_chip(dws, 0); | 525 | spi_enable_chip(dws, 0); |
| 525 | 526 | ||
| 526 | if (dw_readw(dws, ctrl0) != cr0) | 527 | if (dw_readw(dws, DW_SPI_CTRL0) != cr0) |
| 527 | dw_writew(dws, ctrl0, cr0); | 528 | dw_writew(dws, DW_SPI_CTRL0, cr0); |
| 528 | 529 | ||
| 529 | spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); | 530 | spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); |
| 530 | spi_chip_sel(dws, spi->chip_select); | 531 | spi_chip_sel(dws, spi->chip_select); |
| @@ -534,7 +535,7 @@ static void pump_transfers(unsigned long data) | |||
| 534 | if (imask) | 535 | if (imask) |
| 535 | spi_umask_intr(dws, imask); | 536 | spi_umask_intr(dws, imask); |
| 536 | if (txint_level) | 537 | if (txint_level) |
| 537 | dw_writew(dws, txfltr, txint_level); | 538 | dw_writew(dws, DW_SPI_TXFLTR, txint_level); |
| 538 | 539 | ||
| 539 | spi_enable_chip(dws, 1); | 540 | spi_enable_chip(dws, 1); |
| 540 | if (cs_change) | 541 | if (cs_change) |
| @@ -790,13 +791,13 @@ static void spi_hw_init(struct dw_spi *dws) | |||
| 790 | if (!dws->fifo_len) { | 791 | if (!dws->fifo_len) { |
| 791 | u32 fifo; | 792 | u32 fifo; |
| 792 | for (fifo = 2; fifo <= 257; fifo++) { | 793 | for (fifo = 2; fifo <= 257; fifo++) { |
| 793 | dw_writew(dws, txfltr, fifo); | 794 | dw_writew(dws, DW_SPI_TXFLTR, fifo); |
| 794 | if (fifo != dw_readw(dws, txfltr)) | 795 | if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) |
| 795 | break; | 796 | break; |
| 796 | } | 797 | } |
| 797 | 798 | ||
| 798 | dws->fifo_len = (fifo == 257) ? 0 : fifo; | 799 | dws->fifo_len = (fifo == 257) ? 0 : fifo; |
| 799 | dw_writew(dws, txfltr, 0); | 800 | dw_writew(dws, DW_SPI_TXFLTR, 0); |
| 800 | } | 801 | } |
| 801 | } | 802 | } |
| 802 | 803 | ||
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 8b7b07bf6c3f..9c57c078031e 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h | |||
| @@ -4,6 +4,33 @@ | |||
| 4 | #include <linux/io.h> | 4 | #include <linux/io.h> |
| 5 | #include <linux/scatterlist.h> | 5 | #include <linux/scatterlist.h> |
| 6 | 6 | ||
| 7 | /* Register offsets */ | ||
| 8 | #define DW_SPI_CTRL0 0x00 | ||
| 9 | #define DW_SPI_CTRL1 0x04 | ||
| 10 | #define DW_SPI_SSIENR 0x08 | ||
| 11 | #define DW_SPI_MWCR 0x0c | ||
| 12 | #define DW_SPI_SER 0x10 | ||
| 13 | #define DW_SPI_BAUDR 0x14 | ||
| 14 | #define DW_SPI_TXFLTR 0x18 | ||
| 15 | #define DW_SPI_RXFLTR 0x1c | ||
| 16 | #define DW_SPI_TXFLR 0x20 | ||
| 17 | #define DW_SPI_RXFLR 0x24 | ||
| 18 | #define DW_SPI_SR 0x28 | ||
| 19 | #define DW_SPI_IMR 0x2c | ||
| 20 | #define DW_SPI_ISR 0x30 | ||
| 21 | #define DW_SPI_RISR 0x34 | ||
| 22 | #define DW_SPI_TXOICR 0x38 | ||
| 23 | #define DW_SPI_RXOICR 0x3c | ||
| 24 | #define DW_SPI_RXUICR 0x40 | ||
| 25 | #define DW_SPI_MSTICR 0x44 | ||
| 26 | #define DW_SPI_ICR 0x48 | ||
| 27 | #define DW_SPI_DMACR 0x4c | ||
| 28 | #define DW_SPI_DMATDLR 0x50 | ||
| 29 | #define DW_SPI_DMARDLR 0x54 | ||
| 30 | #define DW_SPI_IDR 0x58 | ||
| 31 | #define DW_SPI_VERSION 0x5c | ||
| 32 | #define DW_SPI_DR 0x60 | ||
| 33 | |||
| 7 | /* Bit fields in CTRLR0 */ | 34 | /* Bit fields in CTRLR0 */ |
| 8 | #define SPI_DFS_OFFSET 0 | 35 | #define SPI_DFS_OFFSET 0 |
| 9 | 36 | ||
| @@ -55,35 +82,6 @@ enum dw_ssi_type { | |||
| 55 | SSI_NS_MICROWIRE, | 82 | SSI_NS_MICROWIRE, |
| 56 | }; | 83 | }; |
| 57 | 84 | ||
| 58 | struct dw_spi_reg { | ||
| 59 | u32 ctrl0; | ||
| 60 | u32 ctrl1; | ||
| 61 | u32 ssienr; | ||
| 62 | u32 mwcr; | ||
| 63 | u32 ser; | ||
| 64 | u32 baudr; | ||
| 65 | u32 txfltr; | ||
| 66 | u32 rxfltr; | ||
| 67 | u32 txflr; | ||
| 68 | u32 rxflr; | ||
| 69 | u32 sr; | ||
| 70 | u32 imr; | ||
| 71 | u32 isr; | ||
| 72 | u32 risr; | ||
| 73 | u32 txoicr; | ||
| 74 | u32 rxoicr; | ||
| 75 | u32 rxuicr; | ||
| 76 | u32 msticr; | ||
| 77 | u32 icr; | ||
| 78 | u32 dmacr; | ||
| 79 | u32 dmatdlr; | ||
| 80 | u32 dmardlr; | ||
| 81 | u32 idr; | ||
| 82 | u32 version; | ||
| 83 | u32 dr; /* Currently oper as 32 bits, | ||
| 84 | though only low 16 bits matters */ | ||
| 85 | } __packed; | ||
| 86 | |||
| 87 | struct dw_spi; | 85 | struct dw_spi; |
| 88 | struct dw_spi_dma_ops { | 86 | struct dw_spi_dma_ops { |
| 89 | int (*dma_init)(struct dw_spi *dws); | 87 | int (*dma_init)(struct dw_spi *dws); |
| @@ -161,23 +159,34 @@ struct dw_spi { | |||
| 161 | #endif | 159 | #endif |
| 162 | }; | 160 | }; |
| 163 | 161 | ||
| 164 | #define dw_readl(dw, name) \ | 162 | static inline u32 dw_readl(struct dw_spi *dws, u32 offset) |
| 165 | __raw_readl(&(((struct dw_spi_reg *)dw->regs)->name)) | 163 | { |
| 166 | #define dw_writel(dw, name, val) \ | 164 | return __raw_readl(dws->regs + offset); |
| 167 | __raw_writel((val), &(((struct dw_spi_reg *)dw->regs)->name)) | 165 | } |
| 168 | #define dw_readw(dw, name) \ | 166 | |
| 169 | __raw_readw(&(((struct dw_spi_reg *)dw->regs)->name)) | 167 | static inline void dw_writel(struct dw_spi *dws, u32 offset, u32 val) |
| 170 | #define dw_writew(dw, name, val) \ | 168 | { |
| 171 | __raw_writew((val), &(((struct dw_spi_reg *)dw->regs)->name)) | 169 | __raw_writel(val, dws->regs + offset); |
| 170 | } | ||
| 171 | |||
| 172 | static inline u16 dw_readw(struct dw_spi *dws, u32 offset) | ||
| 173 | { | ||
| 174 | return __raw_readw(dws->regs + offset); | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline void dw_writew(struct dw_spi *dws, u32 offset, u16 val) | ||
| 178 | { | ||
| 179 | __raw_writew(val, dws->regs + offset); | ||
| 180 | } | ||
| 172 | 181 | ||
| 173 | static inline void spi_enable_chip(struct dw_spi *dws, int enable) | 182 | static inline void spi_enable_chip(struct dw_spi *dws, int enable) |
| 174 | { | 183 | { |
| 175 | dw_writel(dws, ssienr, (enable ? 1 : 0)); | 184 | dw_writel(dws, DW_SPI_SSIENR, (enable ? 1 : 0)); |
| 176 | } | 185 | } |
| 177 | 186 | ||
| 178 | static inline void spi_set_clk(struct dw_spi *dws, u16 div) | 187 | static inline void spi_set_clk(struct dw_spi *dws, u16 div) |
| 179 | { | 188 | { |
| 180 | dw_writel(dws, baudr, div); | 189 | dw_writel(dws, DW_SPI_BAUDR, div); |
| 181 | } | 190 | } |
| 182 | 191 | ||
| 183 | static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) | 192 | static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) |
| @@ -188,7 +197,7 @@ static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) | |||
| 188 | if (dws->cs_control) | 197 | if (dws->cs_control) |
| 189 | dws->cs_control(1); | 198 | dws->cs_control(1); |
| 190 | 199 | ||
| 191 | dw_writel(dws, ser, 1 << cs); | 200 | dw_writel(dws, DW_SPI_SER, 1 << cs); |
| 192 | } | 201 | } |
| 193 | 202 | ||
| 194 | /* Disable IRQ bits */ | 203 | /* Disable IRQ bits */ |
| @@ -196,8 +205,8 @@ static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) | |||
| 196 | { | 205 | { |
| 197 | u32 new_mask; | 206 | u32 new_mask; |
| 198 | 207 | ||
| 199 | new_mask = dw_readl(dws, imr) & ~mask; | 208 | new_mask = dw_readl(dws, DW_SPI_IMR) & ~mask; |
| 200 | dw_writel(dws, imr, new_mask); | 209 | dw_writel(dws, DW_SPI_IMR, new_mask); |
| 201 | } | 210 | } |
| 202 | 211 | ||
| 203 | /* Enable IRQ bits */ | 212 | /* Enable IRQ bits */ |
| @@ -205,8 +214,8 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) | |||
| 205 | { | 214 | { |
| 206 | u32 new_mask; | 215 | u32 new_mask; |
| 207 | 216 | ||
| 208 | new_mask = dw_readl(dws, imr) | mask; | 217 | new_mask = dw_readl(dws, DW_SPI_IMR) | mask; |
| 209 | dw_writel(dws, imr, new_mask); | 218 | dw_writel(dws, DW_SPI_IMR, new_mask); |
| 210 | } | 219 | } |
| 211 | 220 | ||
| 212 | /* | 221 | /* |
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 1cf645479bfe..0a282e5fcc9c 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/dmaengine.h> | 24 | #include <linux/dmaengine.h> |
| 25 | #include <linux/bitops.h> | 25 | #include <linux/bitops.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/module.h> | ||
| 27 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 28 | #include <linux/workqueue.h> | 29 | #include <linux/workqueue.h> |
| 29 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
| @@ -1025,7 +1026,7 @@ static void ep93xx_spi_release_dma(struct ep93xx_spi *espi) | |||
| 1025 | free_page((unsigned long)espi->zeropage); | 1026 | free_page((unsigned long)espi->zeropage); |
| 1026 | } | 1027 | } |
| 1027 | 1028 | ||
| 1028 | static int __init ep93xx_spi_probe(struct platform_device *pdev) | 1029 | static int __devinit ep93xx_spi_probe(struct platform_device *pdev) |
| 1029 | { | 1030 | { |
| 1030 | struct spi_master *master; | 1031 | struct spi_master *master; |
| 1031 | struct ep93xx_spi_info *info; | 1032 | struct ep93xx_spi_info *info; |
| @@ -1150,7 +1151,7 @@ fail_release_master: | |||
| 1150 | return error; | 1151 | return error; |
| 1151 | } | 1152 | } |
| 1152 | 1153 | ||
| 1153 | static int __exit ep93xx_spi_remove(struct platform_device *pdev) | 1154 | static int __devexit ep93xx_spi_remove(struct platform_device *pdev) |
| 1154 | { | 1155 | { |
| 1155 | struct spi_master *master = platform_get_drvdata(pdev); | 1156 | struct spi_master *master = platform_get_drvdata(pdev); |
| 1156 | struct ep93xx_spi *espi = spi_master_get_devdata(master); | 1157 | struct ep93xx_spi *espi = spi_master_get_devdata(master); |
| @@ -1196,20 +1197,10 @@ static struct platform_driver ep93xx_spi_driver = { | |||
| 1196 | .name = "ep93xx-spi", | 1197 | .name = "ep93xx-spi", |
| 1197 | .owner = THIS_MODULE, | 1198 | .owner = THIS_MODULE, |
| 1198 | }, | 1199 | }, |
| 1199 | .remove = __exit_p(ep93xx_spi_remove), | 1200 | .probe = ep93xx_spi_probe, |
| 1201 | .remove = __devexit_p(ep93xx_spi_remove), | ||
| 1200 | }; | 1202 | }; |
| 1201 | 1203 | module_platform_driver(ep93xx_spi_driver); | |
| 1202 | static int __init ep93xx_spi_init(void) | ||
| 1203 | { | ||
| 1204 | return platform_driver_probe(&ep93xx_spi_driver, ep93xx_spi_probe); | ||
| 1205 | } | ||
| 1206 | module_init(ep93xx_spi_init); | ||
| 1207 | |||
| 1208 | static void __exit ep93xx_spi_exit(void) | ||
| 1209 | { | ||
| 1210 | platform_driver_unregister(&ep93xx_spi_driver); | ||
| 1211 | } | ||
| 1212 | module_exit(ep93xx_spi_exit); | ||
| 1213 | 1204 | ||
| 1214 | MODULE_DESCRIPTION("EP93xx SPI Controller driver"); | 1205 | MODULE_DESCRIPTION("EP93xx SPI Controller driver"); |
| 1215 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); | 1206 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); |
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index 54e499d5f92c..d770f03705c3 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c | |||
| @@ -744,18 +744,7 @@ static struct platform_driver fsl_espi_driver = { | |||
| 744 | .probe = of_fsl_espi_probe, | 744 | .probe = of_fsl_espi_probe, |
| 745 | .remove = __devexit_p(of_fsl_espi_remove), | 745 | .remove = __devexit_p(of_fsl_espi_remove), |
| 746 | }; | 746 | }; |
| 747 | 747 | module_platform_driver(fsl_espi_driver); | |
| 748 | static int __init fsl_espi_init(void) | ||
| 749 | { | ||
| 750 | return platform_driver_register(&fsl_espi_driver); | ||
| 751 | } | ||
| 752 | module_init(fsl_espi_init); | ||
| 753 | |||
| 754 | static void __exit fsl_espi_exit(void) | ||
| 755 | { | ||
| 756 | platform_driver_unregister(&fsl_espi_driver); | ||
| 757 | } | ||
| 758 | module_exit(fsl_espi_exit); | ||
| 759 | 748 | ||
| 760 | MODULE_AUTHOR("Mingkai Hu"); | 749 | MODULE_AUTHOR("Mingkai Hu"); |
| 761 | MODULE_DESCRIPTION("Enhanced Freescale SPI Driver"); | 750 | MODULE_DESCRIPTION("Enhanced Freescale SPI Driver"); |
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index d2407558773f..24cacff57786 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c | |||
| @@ -825,6 +825,9 @@ static void fsl_spi_cpm_free(struct mpc8xxx_spi *mspi) | |||
| 825 | { | 825 | { |
| 826 | struct device *dev = mspi->dev; | 826 | struct device *dev = mspi->dev; |
| 827 | 827 | ||
| 828 | if (!(mspi->flags & SPI_CPM_MODE)) | ||
| 829 | return; | ||
| 830 | |||
| 828 | dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE); | 831 | dma_unmap_single(dev, mspi->dma_dummy_rx, SPI_MRBLR, DMA_FROM_DEVICE); |
| 829 | dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); | 832 | dma_unmap_single(dev, mspi->dma_dummy_tx, PAGE_SIZE, DMA_TO_DEVICE); |
| 830 | cpm_muram_free(cpm_muram_offset(mspi->tx_bd)); | 833 | cpm_muram_free(cpm_muram_offset(mspi->tx_bd)); |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 0e88ab745490..e093d3ec41ba 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 19 | */ | 19 | */ |
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/module.h> | ||
| 21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 23 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
| @@ -311,7 +312,7 @@ done: | |||
| 311 | return value; | 312 | return value; |
| 312 | } | 313 | } |
| 313 | 314 | ||
| 314 | static int __init spi_gpio_probe(struct platform_device *pdev) | 315 | static int __devinit spi_gpio_probe(struct platform_device *pdev) |
| 315 | { | 316 | { |
| 316 | int status; | 317 | int status; |
| 317 | struct spi_master *master; | 318 | struct spi_master *master; |
| @@ -379,7 +380,7 @@ gpio_free: | |||
| 379 | return status; | 380 | return status; |
| 380 | } | 381 | } |
| 381 | 382 | ||
| 382 | static int __exit spi_gpio_remove(struct platform_device *pdev) | 383 | static int __devexit spi_gpio_remove(struct platform_device *pdev) |
| 383 | { | 384 | { |
| 384 | struct spi_gpio *spi_gpio; | 385 | struct spi_gpio *spi_gpio; |
| 385 | struct spi_gpio_platform_data *pdata; | 386 | struct spi_gpio_platform_data *pdata; |
| @@ -408,21 +409,10 @@ MODULE_ALIAS("platform:" DRIVER_NAME); | |||
| 408 | static struct platform_driver spi_gpio_driver = { | 409 | static struct platform_driver spi_gpio_driver = { |
| 409 | .driver.name = DRIVER_NAME, | 410 | .driver.name = DRIVER_NAME, |
| 410 | .driver.owner = THIS_MODULE, | 411 | .driver.owner = THIS_MODULE, |
| 411 | .remove = __exit_p(spi_gpio_remove), | 412 | .probe = spi_gpio_probe, |
| 413 | .remove = __devexit_p(spi_gpio_remove), | ||
| 412 | }; | 414 | }; |
| 413 | 415 | module_platform_driver(spi_gpio_driver); | |
| 414 | static int __init spi_gpio_init(void) | ||
| 415 | { | ||
| 416 | return platform_driver_probe(&spi_gpio_driver, spi_gpio_probe); | ||
| 417 | } | ||
| 418 | module_init(spi_gpio_init); | ||
| 419 | |||
| 420 | static void __exit spi_gpio_exit(void) | ||
| 421 | { | ||
| 422 | platform_driver_unregister(&spi_gpio_driver); | ||
| 423 | } | ||
| 424 | module_exit(spi_gpio_exit); | ||
| 425 | |||
| 426 | 416 | ||
| 427 | MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); | 417 | MODULE_DESCRIPTION("SPI master driver using generic bitbanged GPIO "); |
| 428 | MODULE_AUTHOR("David Brownell"); | 418 | MODULE_AUTHOR("David Brownell"); |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 8ac6542aedcd..c6e697f5e007 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
| @@ -786,9 +786,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
| 786 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | 786 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); |
| 787 | if (cs_gpio < 0) | 787 | if (cs_gpio < 0) |
| 788 | cs_gpio = mxc_platform_info->chipselect[i]; | 788 | cs_gpio = mxc_platform_info->chipselect[i]; |
| 789 | |||
| 790 | spi_imx->chipselect[i] = cs_gpio; | ||
| 789 | if (cs_gpio < 0) | 791 | if (cs_gpio < 0) |
| 790 | continue; | 792 | continue; |
| 791 | spi_imx->chipselect[i] = cs_gpio; | 793 | |
| 792 | ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); | 794 | ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); |
| 793 | if (ret) { | 795 | if (ret) { |
| 794 | while (i > 0) { | 796 | while (i > 0) { |
| @@ -927,19 +929,7 @@ static struct platform_driver spi_imx_driver = { | |||
| 927 | .probe = spi_imx_probe, | 929 | .probe = spi_imx_probe, |
| 928 | .remove = __devexit_p(spi_imx_remove), | 930 | .remove = __devexit_p(spi_imx_remove), |
| 929 | }; | 931 | }; |
| 930 | 932 | module_platform_driver(spi_imx_driver); | |
| 931 | static int __init spi_imx_init(void) | ||
| 932 | { | ||
| 933 | return platform_driver_register(&spi_imx_driver); | ||
| 934 | } | ||
| 935 | |||
| 936 | static void __exit spi_imx_exit(void) | ||
| 937 | { | ||
| 938 | platform_driver_unregister(&spi_imx_driver); | ||
| 939 | } | ||
| 940 | |||
| 941 | module_init(spi_imx_init); | ||
| 942 | module_exit(spi_imx_exit); | ||
| 943 | 933 | ||
| 944 | MODULE_DESCRIPTION("SPI Master Controller driver"); | 934 | MODULE_DESCRIPTION("SPI Master Controller driver"); |
| 945 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | 935 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 6a5b4238fb6b..4c63f772780a 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c | |||
| @@ -559,18 +559,7 @@ static struct platform_driver mpc512x_psc_spi_of_driver = { | |||
| 559 | .of_match_table = mpc512x_psc_spi_of_match, | 559 | .of_match_table = mpc512x_psc_spi_of_match, |
| 560 | }, | 560 | }, |
| 561 | }; | 561 | }; |
| 562 | 562 | module_platform_driver(mpc512x_psc_spi_of_driver); | |
| 563 | static int __init mpc512x_psc_spi_init(void) | ||
| 564 | { | ||
| 565 | return platform_driver_register(&mpc512x_psc_spi_of_driver); | ||
| 566 | } | ||
| 567 | module_init(mpc512x_psc_spi_init); | ||
| 568 | |||
| 569 | static void __exit mpc512x_psc_spi_exit(void) | ||
| 570 | { | ||
| 571 | platform_driver_unregister(&mpc512x_psc_spi_of_driver); | ||
| 572 | } | ||
| 573 | module_exit(mpc512x_psc_spi_exit); | ||
| 574 | 563 | ||
| 575 | MODULE_AUTHOR("John Rigby"); | 564 | MODULE_AUTHOR("John Rigby"); |
| 576 | MODULE_DESCRIPTION("MPC512x PSC SPI Driver"); | 565 | MODULE_DESCRIPTION("MPC512x PSC SPI Driver"); |
diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index e30baf0852ac..66047156d90d 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c | |||
| @@ -511,18 +511,7 @@ static struct platform_driver mpc52xx_psc_spi_of_driver = { | |||
| 511 | .of_match_table = mpc52xx_psc_spi_of_match, | 511 | .of_match_table = mpc52xx_psc_spi_of_match, |
| 512 | }, | 512 | }, |
| 513 | }; | 513 | }; |
| 514 | 514 | module_platform_driver(mpc52xx_psc_spi_of_driver); | |
| 515 | static int __init mpc52xx_psc_spi_init(void) | ||
| 516 | { | ||
| 517 | return platform_driver_register(&mpc52xx_psc_spi_of_driver); | ||
| 518 | } | ||
| 519 | module_init(mpc52xx_psc_spi_init); | ||
| 520 | |||
| 521 | static void __exit mpc52xx_psc_spi_exit(void) | ||
| 522 | { | ||
| 523 | platform_driver_unregister(&mpc52xx_psc_spi_of_driver); | ||
| 524 | } | ||
| 525 | module_exit(mpc52xx_psc_spi_exit); | ||
| 526 | 515 | ||
| 527 | MODULE_AUTHOR("Dragos Carp"); | 516 | MODULE_AUTHOR("Dragos Carp"); |
| 528 | MODULE_DESCRIPTION("MPC52xx PSC SPI Driver"); | 517 | MODULE_DESCRIPTION("MPC52xx PSC SPI Driver"); |
diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 015a974bed72..57633d963456 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c | |||
| @@ -564,16 +564,4 @@ static struct platform_driver mpc52xx_spi_of_driver = { | |||
| 564 | .probe = mpc52xx_spi_probe, | 564 | .probe = mpc52xx_spi_probe, |
| 565 | .remove = __devexit_p(mpc52xx_spi_remove), | 565 | .remove = __devexit_p(mpc52xx_spi_remove), |
| 566 | }; | 566 | }; |
| 567 | 567 | module_platform_driver(mpc52xx_spi_of_driver); | |
| 568 | static int __init mpc52xx_spi_init(void) | ||
| 569 | { | ||
| 570 | return platform_driver_register(&mpc52xx_spi_of_driver); | ||
| 571 | } | ||
| 572 | module_init(mpc52xx_spi_init); | ||
| 573 | |||
| 574 | static void __exit mpc52xx_spi_exit(void) | ||
| 575 | { | ||
| 576 | platform_driver_unregister(&mpc52xx_spi_of_driver); | ||
| 577 | } | ||
| 578 | module_exit(mpc52xx_spi_exit); | ||
| 579 | |||
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index c0a6ce81f9c0..e763254741c2 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c | |||
| @@ -484,19 +484,7 @@ static struct platform_driver nuc900_spi_driver = { | |||
| 484 | .owner = THIS_MODULE, | 484 | .owner = THIS_MODULE, |
| 485 | }, | 485 | }, |
| 486 | }; | 486 | }; |
| 487 | 487 | module_platform_driver(nuc900_spi_driver); | |
| 488 | static int __init nuc900_spi_init(void) | ||
| 489 | { | ||
| 490 | return platform_driver_register(&nuc900_spi_driver); | ||
| 491 | } | ||
| 492 | |||
| 493 | static void __exit nuc900_spi_exit(void) | ||
| 494 | { | ||
| 495 | platform_driver_unregister(&nuc900_spi_driver); | ||
| 496 | } | ||
| 497 | |||
| 498 | module_init(nuc900_spi_init); | ||
| 499 | module_exit(nuc900_spi_exit); | ||
| 500 | 488 | ||
| 501 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | 489 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); |
| 502 | MODULE_DESCRIPTION("nuc900 spi driver!"); | 490 | MODULE_DESCRIPTION("nuc900 spi driver!"); |
diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index f1bde66cea19..698018fd992b 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
| 21 | #include <linux/module.h> | ||
| 21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 22 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
| 23 | #include <linux/spi/spi_bitbang.h> | 24 | #include <linux/spi/spi_bitbang.h> |
| @@ -406,18 +407,7 @@ static struct platform_driver tiny_spi_driver = { | |||
| 406 | .of_match_table = tiny_spi_match, | 407 | .of_match_table = tiny_spi_match, |
| 407 | }, | 408 | }, |
| 408 | }; | 409 | }; |
| 409 | 410 | module_platform_driver(tiny_spi_driver); | |
| 410 | static int __init tiny_spi_init(void) | ||
| 411 | { | ||
| 412 | return platform_driver_register(&tiny_spi_driver); | ||
| 413 | } | ||
| 414 | module_init(tiny_spi_init); | ||
| 415 | |||
| 416 | static void __exit tiny_spi_exit(void) | ||
| 417 | { | ||
| 418 | platform_driver_unregister(&tiny_spi_driver); | ||
| 419 | } | ||
| 420 | module_exit(tiny_spi_exit); | ||
| 421 | 411 | ||
| 422 | MODULE_DESCRIPTION("OpenCores tiny SPI driver"); | 412 | MODULE_DESCRIPTION("OpenCores tiny SPI driver"); |
| 423 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); | 413 | MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>"); |
diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 00a8e9d7dbe4..610f7391456e 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c | |||
| @@ -45,6 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | #include <linux/spi/spi.h> | 46 | #include <linux/spi/spi.h> |
| 47 | #include <linux/spi/spi_bitbang.h> | 47 | #include <linux/spi/spi_bitbang.h> |
| 48 | #include <linux/module.h> | ||
| 48 | 49 | ||
| 49 | #include <asm/system.h> | 50 | #include <asm/system.h> |
| 50 | #include <asm/irq.h> | 51 | #include <asm/irq.h> |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index fde3a2d4f120..322be7aea8b4 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
| @@ -1116,15 +1116,16 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
| 1116 | status = -ENODEV; | 1116 | status = -ENODEV; |
| 1117 | goto err1; | 1117 | goto err1; |
| 1118 | } | 1118 | } |
| 1119 | |||
| 1120 | r->start += pdata->regs_offset; | ||
| 1121 | r->end += pdata->regs_offset; | ||
| 1122 | mcspi->phys = r->start; | ||
| 1119 | if (!request_mem_region(r->start, resource_size(r), | 1123 | if (!request_mem_region(r->start, resource_size(r), |
| 1120 | dev_name(&pdev->dev))) { | 1124 | dev_name(&pdev->dev))) { |
| 1121 | status = -EBUSY; | 1125 | status = -EBUSY; |
| 1122 | goto err1; | 1126 | goto err1; |
| 1123 | } | 1127 | } |
| 1124 | 1128 | ||
| 1125 | r->start += pdata->regs_offset; | ||
| 1126 | r->end += pdata->regs_offset; | ||
| 1127 | mcspi->phys = r->start; | ||
| 1128 | mcspi->base = ioremap(r->start, resource_size(r)); | 1129 | mcspi->base = ioremap(r->start, resource_size(r)); |
| 1129 | if (!mcspi->base) { | 1130 | if (!mcspi->base) { |
| 1130 | dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); | 1131 | dev_dbg(&pdev->dev, "can't ioremap MCSPI\n"); |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 9421a390a5e3..13448c832c44 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c | |||
| @@ -17,6 +17,7 @@ | |||
| 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> | 19 | #include <linux/spi/orion_spi.h> |
| 20 | #include <linux/module.h> | ||
| 20 | #include <asm/unaligned.h> | 21 | #include <asm/unaligned.h> |
| 21 | 22 | ||
| 22 | #define DRIVER_NAME "orion_spi" | 23 | #define DRIVER_NAME "orion_spi" |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 730b4a37b823..5559b2299198 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
| @@ -113,7 +113,6 @@ | |||
| 113 | #define SSP_CR0_MASK_CSS_ST (0x1FUL << 16) | 113 | #define SSP_CR0_MASK_CSS_ST (0x1FUL << 16) |
| 114 | #define SSP_CR0_MASK_FRF_ST (0x3UL << 21) | 114 | #define SSP_CR0_MASK_FRF_ST (0x3UL << 21) |
| 115 | 115 | ||
| 116 | |||
| 117 | /* | 116 | /* |
| 118 | * SSP Control Register 0 - SSP_CR1 | 117 | * SSP Control Register 0 - SSP_CR1 |
| 119 | */ | 118 | */ |
| @@ -283,7 +282,6 @@ | |||
| 283 | 282 | ||
| 284 | #define SPI_POLLING_TIMEOUT 1000 | 283 | #define SPI_POLLING_TIMEOUT 1000 |
| 285 | 284 | ||
| 286 | |||
| 287 | /* | 285 | /* |
| 288 | * The type of reading going on on this chip | 286 | * The type of reading going on on this chip |
| 289 | */ | 287 | */ |
| @@ -515,9 +513,6 @@ static void giveback(struct pl022 *pl022) | |||
| 515 | if (msg->complete) | 513 | if (msg->complete) |
| 516 | msg->complete(msg->context); | 514 | msg->complete(msg->context); |
| 517 | /* This message is completed, so let's turn off the clocks & power */ | 515 | /* This message is completed, so let's turn off the clocks & power */ |
| 518 | clk_disable(pl022->clk); | ||
| 519 | amba_pclk_disable(pl022->adev); | ||
| 520 | amba_vcore_disable(pl022->adev); | ||
| 521 | pm_runtime_put(&pl022->adev->dev); | 516 | pm_runtime_put(&pl022->adev->dev); |
| 522 | } | 517 | } |
| 523 | 518 | ||
| @@ -752,7 +747,6 @@ static void readwriter(struct pl022 *pl022) | |||
| 752 | */ | 747 | */ |
| 753 | } | 748 | } |
| 754 | 749 | ||
| 755 | |||
| 756 | /** | 750 | /** |
| 757 | * next_transfer - Move to the Next transfer in the current spi message | 751 | * next_transfer - Move to the Next transfer in the current spi message |
| 758 | * @pl022: SSP driver private data structure | 752 | * @pl022: SSP driver private data structure |
| @@ -1019,14 +1013,14 @@ static int configure_dma(struct pl022 *pl022) | |||
| 1019 | dmaengine_slave_config(txchan, &tx_conf); | 1013 | dmaengine_slave_config(txchan, &tx_conf); |
| 1020 | 1014 | ||
| 1021 | /* Create sglists for the transfers */ | 1015 | /* Create sglists for the transfers */ |
| 1022 | pages = (pl022->cur_transfer->len >> PAGE_SHIFT) + 1; | 1016 | pages = DIV_ROUND_UP(pl022->cur_transfer->len, PAGE_SIZE); |
| 1023 | dev_dbg(&pl022->adev->dev, "using %d pages for transfer\n", pages); | 1017 | dev_dbg(&pl022->adev->dev, "using %d pages for transfer\n", pages); |
| 1024 | 1018 | ||
| 1025 | ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_KERNEL); | 1019 | ret = sg_alloc_table(&pl022->sgt_rx, pages, GFP_ATOMIC); |
| 1026 | if (ret) | 1020 | if (ret) |
| 1027 | goto err_alloc_rx_sg; | 1021 | goto err_alloc_rx_sg; |
| 1028 | 1022 | ||
| 1029 | ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_KERNEL); | 1023 | ret = sg_alloc_table(&pl022->sgt_tx, pages, GFP_ATOMIC); |
| 1030 | if (ret) | 1024 | if (ret) |
| 1031 | goto err_alloc_tx_sg; | 1025 | goto err_alloc_tx_sg; |
| 1032 | 1026 | ||
| @@ -1534,8 +1528,7 @@ static void pump_messages(struct work_struct *work) | |||
| 1534 | /* Initial message state */ | 1528 | /* Initial message state */ |
| 1535 | pl022->cur_msg->state = STATE_START; | 1529 | pl022->cur_msg->state = STATE_START; |
| 1536 | pl022->cur_transfer = list_entry(pl022->cur_msg->transfers.next, | 1530 | pl022->cur_transfer = list_entry(pl022->cur_msg->transfers.next, |
| 1537 | struct spi_transfer, | 1531 | struct spi_transfer, transfer_list); |
| 1538 | transfer_list); | ||
| 1539 | 1532 | ||
| 1540 | /* Setup the SPI using the per chip configuration */ | 1533 | /* Setup the SPI using the per chip configuration */ |
| 1541 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); | 1534 | pl022->cur_chip = spi_get_ctldata(pl022->cur_msg->spi); |
| @@ -1545,9 +1538,6 @@ static void pump_messages(struct work_struct *work) | |||
| 1545 | * (poll/interrupt/DMA) | 1538 | * (poll/interrupt/DMA) |
| 1546 | */ | 1539 | */ |
| 1547 | pm_runtime_get_sync(&pl022->adev->dev); | 1540 | pm_runtime_get_sync(&pl022->adev->dev); |
| 1548 | amba_vcore_enable(pl022->adev); | ||
| 1549 | amba_pclk_enable(pl022->adev); | ||
| 1550 | clk_enable(pl022->clk); | ||
| 1551 | restore_state(pl022); | 1541 | restore_state(pl022); |
| 1552 | flush(pl022); | 1542 | flush(pl022); |
| 1553 | 1543 | ||
| @@ -1557,7 +1547,6 @@ static void pump_messages(struct work_struct *work) | |||
| 1557 | do_interrupt_dma_transfer(pl022); | 1547 | do_interrupt_dma_transfer(pl022); |
| 1558 | } | 1548 | } |
| 1559 | 1549 | ||
| 1560 | |||
| 1561 | static int __init init_queue(struct pl022 *pl022) | 1550 | static int __init init_queue(struct pl022 *pl022) |
| 1562 | { | 1551 | { |
| 1563 | INIT_LIST_HEAD(&pl022->queue); | 1552 | INIT_LIST_HEAD(&pl022->queue); |
| @@ -1566,8 +1555,8 @@ static int __init init_queue(struct pl022 *pl022) | |||
| 1566 | pl022->running = false; | 1555 | pl022->running = false; |
| 1567 | pl022->busy = false; | 1556 | pl022->busy = false; |
| 1568 | 1557 | ||
| 1569 | tasklet_init(&pl022->pump_transfers, | 1558 | tasklet_init(&pl022->pump_transfers, pump_transfers, |
| 1570 | pump_transfers, (unsigned long)pl022); | 1559 | (unsigned long)pl022); |
| 1571 | 1560 | ||
| 1572 | INIT_WORK(&pl022->pump_messages, pump_messages); | 1561 | INIT_WORK(&pl022->pump_messages, pump_messages); |
| 1573 | pl022->workqueue = create_singlethread_workqueue( | 1562 | pl022->workqueue = create_singlethread_workqueue( |
| @@ -1578,7 +1567,6 @@ static int __init init_queue(struct pl022 *pl022) | |||
| 1578 | return 0; | 1567 | return 0; |
| 1579 | } | 1568 | } |
| 1580 | 1569 | ||
| 1581 | |||
| 1582 | static int start_queue(struct pl022 *pl022) | 1570 | static int start_queue(struct pl022 *pl022) |
| 1583 | { | 1571 | { |
| 1584 | unsigned long flags; | 1572 | unsigned long flags; |
| @@ -1601,7 +1589,6 @@ static int start_queue(struct pl022 *pl022) | |||
| 1601 | return 0; | 1589 | return 0; |
| 1602 | } | 1590 | } |
| 1603 | 1591 | ||
| 1604 | |||
| 1605 | static int stop_queue(struct pl022 *pl022) | 1592 | static int stop_queue(struct pl022 *pl022) |
| 1606 | { | 1593 | { |
| 1607 | unsigned long flags; | 1594 | unsigned long flags; |
| @@ -1797,71 +1784,70 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg) | |||
| 1797 | return 0; | 1784 | return 0; |
| 1798 | } | 1785 | } |
| 1799 | 1786 | ||
| 1800 | static int calculate_effective_freq(struct pl022 *pl022, | 1787 | static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr) |
| 1801 | int freq, | 1788 | { |
| 1802 | struct ssp_clock_params *clk_freq) | 1789 | return rate / (cpsdvsr * (1 + scr)); |
| 1790 | } | ||
| 1791 | |||
| 1792 | static int calculate_effective_freq(struct pl022 *pl022, int freq, struct | ||
| 1793 | ssp_clock_params * clk_freq) | ||
| 1803 | { | 1794 | { |
| 1804 | /* Lets calculate the frequency parameters */ | 1795 | /* Lets calculate the frequency parameters */ |
| 1805 | u16 cpsdvsr = 2; | 1796 | u16 cpsdvsr = CPSDVR_MIN, scr = SCR_MIN; |
| 1806 | u16 scr = 0; | 1797 | u32 rate, max_tclk, min_tclk, best_freq = 0, best_cpsdvsr = 0, |
| 1807 | bool freq_found = false; | 1798 | best_scr = 0, tmp, found = 0; |
| 1808 | u32 rate; | ||
| 1809 | u32 max_tclk; | ||
| 1810 | u32 min_tclk; | ||
| 1811 | 1799 | ||
| 1812 | rate = clk_get_rate(pl022->clk); | 1800 | rate = clk_get_rate(pl022->clk); |
| 1813 | /* cpsdvscr = 2 & scr 0 */ | 1801 | /* cpsdvscr = 2 & scr 0 */ |
| 1814 | max_tclk = (rate / (CPSDVR_MIN * (1 + SCR_MIN))); | 1802 | max_tclk = spi_rate(rate, CPSDVR_MIN, SCR_MIN); |
| 1815 | /* cpsdvsr = 254 & scr = 255 */ | 1803 | /* cpsdvsr = 254 & scr = 255 */ |
| 1816 | min_tclk = (rate / (CPSDVR_MAX * (1 + SCR_MAX))); | 1804 | min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); |
| 1817 | 1805 | ||
| 1818 | if ((freq <= max_tclk) && (freq >= min_tclk)) { | 1806 | if (!((freq <= max_tclk) && (freq >= min_tclk))) { |
| 1819 | while (cpsdvsr <= CPSDVR_MAX && !freq_found) { | ||
| 1820 | while (scr <= SCR_MAX && !freq_found) { | ||
| 1821 | if ((rate / | ||
| 1822 | (cpsdvsr * (1 + scr))) > freq) | ||
| 1823 | scr += 1; | ||
| 1824 | else { | ||
| 1825 | /* | ||
| 1826 | * This bool is made true when | ||
| 1827 | * effective frequency >= | ||
| 1828 | * target frequency is found | ||
| 1829 | */ | ||
| 1830 | freq_found = true; | ||
| 1831 | if ((rate / | ||
| 1832 | (cpsdvsr * (1 + scr))) != freq) { | ||
| 1833 | if (scr == SCR_MIN) { | ||
| 1834 | cpsdvsr -= 2; | ||
| 1835 | scr = SCR_MAX; | ||
| 1836 | } else | ||
| 1837 | scr -= 1; | ||
| 1838 | } | ||
| 1839 | } | ||
| 1840 | } | ||
| 1841 | if (!freq_found) { | ||
| 1842 | cpsdvsr += 2; | ||
| 1843 | scr = SCR_MIN; | ||
| 1844 | } | ||
| 1845 | } | ||
| 1846 | if (cpsdvsr != 0) { | ||
| 1847 | dev_dbg(&pl022->adev->dev, | ||
| 1848 | "SSP Effective Frequency is %u\n", | ||
| 1849 | (rate / (cpsdvsr * (1 + scr)))); | ||
| 1850 | clk_freq->cpsdvsr = (u8) (cpsdvsr & 0xFF); | ||
| 1851 | clk_freq->scr = (u8) (scr & 0xFF); | ||
| 1852 | dev_dbg(&pl022->adev->dev, | ||
| 1853 | "SSP cpsdvsr = %d, scr = %d\n", | ||
| 1854 | clk_freq->cpsdvsr, clk_freq->scr); | ||
| 1855 | } | ||
| 1856 | } else { | ||
| 1857 | dev_err(&pl022->adev->dev, | 1807 | dev_err(&pl022->adev->dev, |
| 1858 | "controller data is incorrect: out of range frequency"); | 1808 | "controller data is incorrect: out of range frequency"); |
| 1859 | return -EINVAL; | 1809 | return -EINVAL; |
| 1860 | } | 1810 | } |
| 1811 | |||
| 1812 | /* | ||
| 1813 | * best_freq will give closest possible available rate (<= requested | ||
| 1814 | * freq) for all values of scr & cpsdvsr. | ||
| 1815 | */ | ||
| 1816 | while ((cpsdvsr <= CPSDVR_MAX) && !found) { | ||
| 1817 | while (scr <= SCR_MAX) { | ||
| 1818 | tmp = spi_rate(rate, cpsdvsr, scr); | ||
| 1819 | |||
| 1820 | if (tmp > freq) | ||
| 1821 | scr++; | ||
| 1822 | /* | ||
| 1823 | * If found exact value, update and break. | ||
| 1824 | * If found more closer value, update and continue. | ||
| 1825 | */ | ||
| 1826 | else if ((tmp == freq) || (tmp > best_freq)) { | ||
| 1827 | best_freq = tmp; | ||
| 1828 | best_cpsdvsr = cpsdvsr; | ||
| 1829 | best_scr = scr; | ||
| 1830 | |||
| 1831 | if (tmp == freq) | ||
| 1832 | break; | ||
| 1833 | } | ||
| 1834 | scr++; | ||
| 1835 | } | ||
| 1836 | cpsdvsr += 2; | ||
| 1837 | scr = SCR_MIN; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF); | ||
| 1841 | clk_freq->scr = (u8) (best_scr & 0xFF); | ||
| 1842 | dev_dbg(&pl022->adev->dev, | ||
| 1843 | "SSP Target Frequency is: %u, Effective Frequency is %u\n", | ||
| 1844 | freq, best_freq); | ||
| 1845 | dev_dbg(&pl022->adev->dev, "SSP cpsdvsr = %d, scr = %d\n", | ||
| 1846 | clk_freq->cpsdvsr, clk_freq->scr); | ||
| 1847 | |||
| 1861 | return 0; | 1848 | return 0; |
| 1862 | } | 1849 | } |
| 1863 | 1850 | ||
| 1864 | |||
| 1865 | /* | 1851 | /* |
| 1866 | * A piece of default chip info unless the platform | 1852 | * A piece of default chip info unless the platform |
| 1867 | * supplies it. | 1853 | * supplies it. |
| @@ -1879,7 +1865,6 @@ static const struct pl022_config_chip pl022_default_chip_info = { | |||
| 1879 | .cs_control = null_cs_control, | 1865 | .cs_control = null_cs_control, |
| 1880 | }; | 1866 | }; |
| 1881 | 1867 | ||
| 1882 | |||
| 1883 | /** | 1868 | /** |
| 1884 | * pl022_setup - setup function registered to SPI master framework | 1869 | * pl022_setup - setup function registered to SPI master framework |
| 1885 | * @spi: spi device which is requesting setup | 1870 | * @spi: spi device which is requesting setup |
| @@ -1956,7 +1941,6 @@ static int pl022_setup(struct spi_device *spi) | |||
| 1956 | goto err_config_params; | 1941 | goto err_config_params; |
| 1957 | } | 1942 | } |
| 1958 | 1943 | ||
| 1959 | |||
| 1960 | status = verify_controller_parameters(pl022, chip_info); | 1944 | status = verify_controller_parameters(pl022, chip_info); |
| 1961 | if (status) { | 1945 | if (status) { |
| 1962 | dev_err(&spi->dev, "controller data is incorrect"); | 1946 | dev_err(&spi->dev, "controller data is incorrect"); |
| @@ -2096,7 +2080,8 @@ static int pl022_setup(struct spi_device *spi) | |||
| 2096 | } | 2080 | } |
| 2097 | SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); | 2081 | SSP_WRITE_BITS(chip->cr1, SSP_DISABLED, SSP_CR1_MASK_SSE, 1); |
| 2098 | SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); | 2082 | SSP_WRITE_BITS(chip->cr1, chip_info->hierarchy, SSP_CR1_MASK_MS, 2); |
| 2099 | SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, 3); | 2083 | SSP_WRITE_BITS(chip->cr1, chip_info->slave_tx_disable, SSP_CR1_MASK_SOD, |
| 2084 | 3); | ||
| 2100 | 2085 | ||
| 2101 | /* Save controller_state */ | 2086 | /* Save controller_state */ |
| 2102 | spi_set_ctldata(spi, chip); | 2087 | spi_set_ctldata(spi, chip); |
| @@ -2122,7 +2107,6 @@ static void pl022_cleanup(struct spi_device *spi) | |||
| 2122 | kfree(chip); | 2107 | kfree(chip); |
| 2123 | } | 2108 | } |
| 2124 | 2109 | ||
| 2125 | |||
| 2126 | static int __devinit | 2110 | static int __devinit |
| 2127 | pl022_probe(struct amba_device *adev, const struct amba_id *id) | 2111 | pl022_probe(struct amba_device *adev, const struct amba_id *id) |
| 2128 | { | 2112 | { |
| @@ -2186,8 +2170,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2186 | } | 2170 | } |
| 2187 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2171 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
| 2188 | adev->res.start, pl022->virtbase); | 2172 | adev->res.start, pl022->virtbase); |
| 2189 | pm_runtime_enable(dev); | ||
| 2190 | pm_runtime_resume(dev); | ||
| 2191 | 2173 | ||
| 2192 | pl022->clk = clk_get(&adev->dev, NULL); | 2174 | pl022->clk = clk_get(&adev->dev, NULL); |
| 2193 | if (IS_ERR(pl022->clk)) { | 2175 | if (IS_ERR(pl022->clk)) { |
| @@ -2196,6 +2178,18 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2196 | goto err_no_clk; | 2178 | goto err_no_clk; |
| 2197 | } | 2179 | } |
| 2198 | 2180 | ||
| 2181 | status = clk_prepare(pl022->clk); | ||
| 2182 | if (status) { | ||
| 2183 | dev_err(&adev->dev, "could not prepare SSP/SPI bus clock\n"); | ||
| 2184 | goto err_clk_prep; | ||
| 2185 | } | ||
| 2186 | |||
| 2187 | status = clk_enable(pl022->clk); | ||
| 2188 | if (status) { | ||
| 2189 | dev_err(&adev->dev, "could not enable SSP/SPI bus clock\n"); | ||
| 2190 | goto err_no_clk_en; | ||
| 2191 | } | ||
| 2192 | |||
| 2199 | /* Disable SSP */ | 2193 | /* Disable SSP */ |
| 2200 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), | 2194 | writew((readw(SSP_CR1(pl022->virtbase)) & (~SSP_CR1_MASK_SSE)), |
| 2201 | SSP_CR1(pl022->virtbase)); | 2195 | SSP_CR1(pl022->virtbase)); |
| @@ -2235,22 +2229,24 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
| 2235 | goto err_spi_register; | 2229 | goto err_spi_register; |
| 2236 | } | 2230 | } |
| 2237 | dev_dbg(dev, "probe succeeded\n"); | 2231 | dev_dbg(dev, "probe succeeded\n"); |
| 2238 | /* | 2232 | |
| 2239 | * Disable the silicon block pclk and any voltage domain and just | 2233 | /* let runtime pm put suspend */ |
| 2240 | * power it up and clock it when it's needed | 2234 | pm_runtime_put(dev); |
| 2241 | */ | ||
| 2242 | amba_pclk_disable(adev); | ||
| 2243 | amba_vcore_disable(adev); | ||
| 2244 | return 0; | 2235 | return 0; |
| 2245 | 2236 | ||
| 2246 | err_spi_register: | 2237 | err_spi_register: |
| 2247 | err_start_queue: | 2238 | err_start_queue: |
| 2248 | err_init_queue: | 2239 | err_init_queue: |
| 2249 | destroy_queue(pl022); | 2240 | destroy_queue(pl022); |
| 2250 | pl022_dma_remove(pl022); | 2241 | if (platform_info->enable_dma) |
| 2242 | pl022_dma_remove(pl022); | ||
| 2243 | |||
| 2251 | free_irq(adev->irq[0], pl022); | 2244 | free_irq(adev->irq[0], pl022); |
| 2252 | pm_runtime_disable(&adev->dev); | ||
| 2253 | err_no_irq: | 2245 | err_no_irq: |
| 2246 | clk_disable(pl022->clk); | ||
| 2247 | err_no_clk_en: | ||
| 2248 | clk_unprepare(pl022->clk); | ||
| 2249 | err_clk_prep: | ||
| 2254 | clk_put(pl022->clk); | 2250 | clk_put(pl022->clk); |
| 2255 | err_no_clk: | 2251 | err_no_clk: |
| 2256 | iounmap(pl022->virtbase); | 2252 | iounmap(pl022->virtbase); |
| @@ -2271,13 +2267,22 @@ pl022_remove(struct amba_device *adev) | |||
| 2271 | if (!pl022) | 2267 | if (!pl022) |
| 2272 | return 0; | 2268 | return 0; |
| 2273 | 2269 | ||
| 2270 | /* | ||
| 2271 | * undo pm_runtime_put() in probe. I assume that we're not | ||
| 2272 | * accessing the primecell here. | ||
| 2273 | */ | ||
| 2274 | pm_runtime_get_noresume(&adev->dev); | ||
| 2275 | |||
| 2274 | /* Remove the queue */ | 2276 | /* Remove the queue */ |
| 2275 | if (destroy_queue(pl022) != 0) | 2277 | if (destroy_queue(pl022) != 0) |
| 2276 | dev_err(&adev->dev, "queue remove failed\n"); | 2278 | dev_err(&adev->dev, "queue remove failed\n"); |
| 2277 | load_ssp_default_config(pl022); | 2279 | load_ssp_default_config(pl022); |
| 2278 | pl022_dma_remove(pl022); | 2280 | if (pl022->master_info->enable_dma) |
| 2281 | pl022_dma_remove(pl022); | ||
| 2282 | |||
| 2279 | free_irq(adev->irq[0], pl022); | 2283 | free_irq(adev->irq[0], pl022); |
| 2280 | clk_disable(pl022->clk); | 2284 | clk_disable(pl022->clk); |
| 2285 | clk_unprepare(pl022->clk); | ||
| 2281 | clk_put(pl022->clk); | 2286 | clk_put(pl022->clk); |
| 2282 | iounmap(pl022->virtbase); | 2287 | iounmap(pl022->virtbase); |
| 2283 | amba_release_regions(adev); | 2288 | amba_release_regions(adev); |
| @@ -2288,46 +2293,70 @@ pl022_remove(struct amba_device *adev) | |||
| 2288 | return 0; | 2293 | return 0; |
| 2289 | } | 2294 | } |
| 2290 | 2295 | ||
| 2291 | #ifdef CONFIG_PM | 2296 | #ifdef CONFIG_SUSPEND |
| 2292 | static int pl022_suspend(struct amba_device *adev, pm_message_t state) | 2297 | static int pl022_suspend(struct device *dev) |
| 2293 | { | 2298 | { |
| 2294 | struct pl022 *pl022 = amba_get_drvdata(adev); | 2299 | struct pl022 *pl022 = dev_get_drvdata(dev); |
| 2295 | int status = 0; | 2300 | int status = 0; |
| 2296 | 2301 | ||
| 2297 | status = stop_queue(pl022); | 2302 | status = stop_queue(pl022); |
| 2298 | if (status) { | 2303 | if (status) { |
| 2299 | dev_warn(&adev->dev, "suspend cannot stop queue\n"); | 2304 | dev_warn(dev, "suspend cannot stop queue\n"); |
| 2300 | return status; | 2305 | return status; |
| 2301 | } | 2306 | } |
| 2302 | 2307 | ||
| 2303 | amba_vcore_enable(adev); | 2308 | amba_vcore_enable(pl022->adev); |
| 2304 | amba_pclk_enable(adev); | 2309 | amba_pclk_enable(pl022->adev); |
| 2305 | load_ssp_default_config(pl022); | 2310 | load_ssp_default_config(pl022); |
| 2306 | amba_pclk_disable(adev); | 2311 | amba_pclk_disable(pl022->adev); |
| 2307 | amba_vcore_disable(adev); | 2312 | amba_vcore_disable(pl022->adev); |
| 2308 | dev_dbg(&adev->dev, "suspended\n"); | 2313 | dev_dbg(dev, "suspended\n"); |
| 2309 | return 0; | 2314 | return 0; |
| 2310 | } | 2315 | } |
| 2311 | 2316 | ||
| 2312 | static int pl022_resume(struct amba_device *adev) | 2317 | static int pl022_resume(struct device *dev) |
| 2313 | { | 2318 | { |
| 2314 | struct pl022 *pl022 = amba_get_drvdata(adev); | 2319 | struct pl022 *pl022 = dev_get_drvdata(dev); |
| 2315 | int status = 0; | 2320 | int status = 0; |
| 2316 | 2321 | ||
| 2317 | /* Start the queue running */ | 2322 | /* Start the queue running */ |
| 2318 | status = start_queue(pl022); | 2323 | status = start_queue(pl022); |
| 2319 | if (status) | 2324 | if (status) |
| 2320 | dev_err(&adev->dev, "problem starting queue (%d)\n", status); | 2325 | dev_err(dev, "problem starting queue (%d)\n", status); |
| 2321 | else | 2326 | else |
| 2322 | dev_dbg(&adev->dev, "resumed\n"); | 2327 | dev_dbg(dev, "resumed\n"); |
| 2323 | 2328 | ||
| 2324 | return status; | 2329 | return status; |
| 2325 | } | 2330 | } |
| 2326 | #else | ||
| 2327 | #define pl022_suspend NULL | ||
| 2328 | #define pl022_resume NULL | ||
| 2329 | #endif /* CONFIG_PM */ | 2331 | #endif /* CONFIG_PM */ |
| 2330 | 2332 | ||
| 2333 | #ifdef CONFIG_PM_RUNTIME | ||
| 2334 | static int pl022_runtime_suspend(struct device *dev) | ||
| 2335 | { | ||
| 2336 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
| 2337 | |||
| 2338 | clk_disable(pl022->clk); | ||
| 2339 | amba_vcore_disable(pl022->adev); | ||
| 2340 | |||
| 2341 | return 0; | ||
| 2342 | } | ||
| 2343 | |||
| 2344 | static int pl022_runtime_resume(struct device *dev) | ||
| 2345 | { | ||
| 2346 | struct pl022 *pl022 = dev_get_drvdata(dev); | ||
| 2347 | |||
| 2348 | amba_vcore_enable(pl022->adev); | ||
| 2349 | clk_enable(pl022->clk); | ||
| 2350 | |||
| 2351 | return 0; | ||
| 2352 | } | ||
| 2353 | #endif | ||
| 2354 | |||
| 2355 | static const struct dev_pm_ops pl022_dev_pm_ops = { | ||
| 2356 | SET_SYSTEM_SLEEP_PM_OPS(pl022_suspend, pl022_resume) | ||
| 2357 | SET_RUNTIME_PM_OPS(pl022_runtime_suspend, pl022_runtime_resume, NULL) | ||
| 2358 | }; | ||
| 2359 | |||
| 2331 | static struct vendor_data vendor_arm = { | 2360 | static struct vendor_data vendor_arm = { |
| 2332 | .fifodepth = 8, | 2361 | .fifodepth = 8, |
| 2333 | .max_bpw = 16, | 2362 | .max_bpw = 16, |
| @@ -2337,7 +2366,6 @@ static struct vendor_data vendor_arm = { | |||
| 2337 | .loopback = true, | 2366 | .loopback = true, |
| 2338 | }; | 2367 | }; |
| 2339 | 2368 | ||
| 2340 | |||
| 2341 | static struct vendor_data vendor_st = { | 2369 | static struct vendor_data vendor_st = { |
| 2342 | .fifodepth = 32, | 2370 | .fifodepth = 32, |
| 2343 | .max_bpw = 32, | 2371 | .max_bpw = 32, |
| @@ -2392,9 +2420,9 @@ static struct amba_id pl022_ids[] = { | |||
| 2392 | * and 32 locations deep TX/RX FIFO but no extended | 2420 | * and 32 locations deep TX/RX FIFO but no extended |
| 2393 | * CR0/CR1 register | 2421 | * CR0/CR1 register |
| 2394 | */ | 2422 | */ |
| 2395 | .id = 0x00080023, | 2423 | .id = 0x00080023, |
| 2396 | .mask = 0xffffffff, | 2424 | .mask = 0xffffffff, |
| 2397 | .data = &vendor_st_pl023, | 2425 | .data = &vendor_st_pl023, |
| 2398 | }, | 2426 | }, |
| 2399 | { | 2427 | { |
| 2400 | .id = 0x10080023, | 2428 | .id = 0x10080023, |
| @@ -2407,27 +2435,23 @@ static struct amba_id pl022_ids[] = { | |||
| 2407 | static struct amba_driver pl022_driver = { | 2435 | static struct amba_driver pl022_driver = { |
| 2408 | .drv = { | 2436 | .drv = { |
| 2409 | .name = "ssp-pl022", | 2437 | .name = "ssp-pl022", |
| 2438 | .pm = &pl022_dev_pm_ops, | ||
| 2410 | }, | 2439 | }, |
| 2411 | .id_table = pl022_ids, | 2440 | .id_table = pl022_ids, |
| 2412 | .probe = pl022_probe, | 2441 | .probe = pl022_probe, |
| 2413 | .remove = __devexit_p(pl022_remove), | 2442 | .remove = __devexit_p(pl022_remove), |
| 2414 | .suspend = pl022_suspend, | ||
| 2415 | .resume = pl022_resume, | ||
| 2416 | }; | 2443 | }; |
| 2417 | 2444 | ||
| 2418 | |||
| 2419 | static int __init pl022_init(void) | 2445 | static int __init pl022_init(void) |
| 2420 | { | 2446 | { |
| 2421 | return amba_driver_register(&pl022_driver); | 2447 | return amba_driver_register(&pl022_driver); |
| 2422 | } | 2448 | } |
| 2423 | |||
| 2424 | subsys_initcall(pl022_init); | 2449 | subsys_initcall(pl022_init); |
| 2425 | 2450 | ||
| 2426 | static void __exit pl022_exit(void) | 2451 | static void __exit pl022_exit(void) |
| 2427 | { | 2452 | { |
| 2428 | amba_driver_unregister(&pl022_driver); | 2453 | amba_driver_unregister(&pl022_driver); |
| 2429 | } | 2454 | } |
| 2430 | |||
| 2431 | module_exit(pl022_exit); | 2455 | module_exit(pl022_exit); |
| 2432 | 2456 | ||
| 2433 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); | 2457 | MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); |
diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index b267fd901e54..98ec53285fc7 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c | |||
| @@ -514,7 +514,7 @@ static int __init spi_ppc4xx_of_probe(struct platform_device *op) | |||
| 514 | /* Request IRQ */ | 514 | /* Request IRQ */ |
| 515 | hw->irqnum = irq_of_parse_and_map(np, 0); | 515 | hw->irqnum = irq_of_parse_and_map(np, 0); |
| 516 | ret = request_irq(hw->irqnum, spi_ppc4xx_int, | 516 | ret = request_irq(hw->irqnum, spi_ppc4xx_int, |
| 517 | IRQF_DISABLED, "spi_ppc4xx_of", (void *)hw); | 517 | 0, "spi_ppc4xx_of", (void *)hw); |
| 518 | if (ret) { | 518 | if (ret) { |
| 519 | dev_err(dev, "unable to allocate interrupt\n"); | 519 | dev_err(dev, "unable to allocate interrupt\n"); |
| 520 | goto free_gpios; | 520 | goto free_gpios; |
| @@ -594,18 +594,7 @@ static struct platform_driver spi_ppc4xx_of_driver = { | |||
| 594 | .of_match_table = spi_ppc4xx_of_match, | 594 | .of_match_table = spi_ppc4xx_of_match, |
| 595 | }, | 595 | }, |
| 596 | }; | 596 | }; |
| 597 | 597 | module_platform_driver(spi_ppc4xx_of_driver); | |
| 598 | static int __init spi_ppc4xx_init(void) | ||
| 599 | { | ||
| 600 | return platform_driver_register(&spi_ppc4xx_of_driver); | ||
| 601 | } | ||
| 602 | module_init(spi_ppc4xx_init); | ||
| 603 | |||
| 604 | static void __exit spi_ppc4xx_exit(void) | ||
| 605 | { | ||
| 606 | platform_driver_unregister(&spi_ppc4xx_of_driver); | ||
| 607 | } | ||
| 608 | module_exit(spi_ppc4xx_exit); | ||
| 609 | 598 | ||
| 610 | MODULE_AUTHOR("Gary Jennejohn & Stefan Roese"); | 599 | MODULE_AUTHOR("Gary Jennejohn & Stefan Roese"); |
| 611 | MODULE_DESCRIPTION("Simple PPC4xx SPI Driver"); | 600 | MODULE_DESCRIPTION("Simple PPC4xx SPI Driver"); |
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 378e504f89eb..8caa07d58e69 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/pci.h> | 5 | #include <linux/pci.h> |
| 6 | #include <linux/platform_device.h> | 6 | #include <linux/platform_device.h> |
| 7 | #include <linux/of_device.h> | 7 | #include <linux/of_device.h> |
| 8 | #include <linux/module.h> | ||
| 8 | #include <linux/spi/pxa2xx_spi.h> | 9 | #include <linux/spi/pxa2xx_spi.h> |
| 9 | 10 | ||
| 10 | struct ce4100_info { | 11 | struct ce4100_info { |
diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index 1996ac57ef91..fc064535f4fc 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
| 26 | #include <linux/spi/spi_bitbang.h> | 26 | #include <linux/spi/spi_bitbang.h> |
| 27 | #include <linux/module.h> | ||
| 27 | 28 | ||
| 28 | #include <plat/regs-spi.h> | 29 | #include <plat/regs-spi.h> |
| 29 | #include <mach/spi.h> | 30 | #include <mach/spi.h> |
| @@ -505,7 +506,7 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw) | |||
| 505 | } | 506 | } |
| 506 | } | 507 | } |
| 507 | 508 | ||
| 508 | static int __init s3c24xx_spi_probe(struct platform_device *pdev) | 509 | static int __devinit s3c24xx_spi_probe(struct platform_device *pdev) |
| 509 | { | 510 | { |
| 510 | struct s3c2410_spi_info *pdata; | 511 | struct s3c2410_spi_info *pdata; |
| 511 | struct s3c24xx_spi *hw; | 512 | struct s3c24xx_spi *hw; |
| @@ -661,7 +662,7 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) | |||
| 661 | return err; | 662 | return err; |
| 662 | } | 663 | } |
| 663 | 664 | ||
| 664 | static int __exit s3c24xx_spi_remove(struct platform_device *dev) | 665 | static int __devexit s3c24xx_spi_remove(struct platform_device *dev) |
| 665 | { | 666 | { |
| 666 | struct s3c24xx_spi *hw = platform_get_drvdata(dev); | 667 | struct s3c24xx_spi *hw = platform_get_drvdata(dev); |
| 667 | 668 | ||
| @@ -719,26 +720,15 @@ static const struct dev_pm_ops s3c24xx_spi_pmops = { | |||
| 719 | 720 | ||
| 720 | MODULE_ALIAS("platform:s3c2410-spi"); | 721 | MODULE_ALIAS("platform:s3c2410-spi"); |
| 721 | static struct platform_driver s3c24xx_spi_driver = { | 722 | static struct platform_driver s3c24xx_spi_driver = { |
| 722 | .remove = __exit_p(s3c24xx_spi_remove), | 723 | .probe = s3c24xx_spi_probe, |
| 724 | .remove = __devexit_p(s3c24xx_spi_remove), | ||
| 723 | .driver = { | 725 | .driver = { |
| 724 | .name = "s3c2410-spi", | 726 | .name = "s3c2410-spi", |
| 725 | .owner = THIS_MODULE, | 727 | .owner = THIS_MODULE, |
| 726 | .pm = S3C24XX_SPI_PMOPS, | 728 | .pm = S3C24XX_SPI_PMOPS, |
| 727 | }, | 729 | }, |
| 728 | }; | 730 | }; |
| 729 | 731 | module_platform_driver(s3c24xx_spi_driver); | |
| 730 | static int __init s3c24xx_spi_init(void) | ||
| 731 | { | ||
| 732 | return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe); | ||
| 733 | } | ||
| 734 | |||
| 735 | static void __exit s3c24xx_spi_exit(void) | ||
| 736 | { | ||
| 737 | platform_driver_unregister(&s3c24xx_spi_driver); | ||
| 738 | } | ||
| 739 | |||
| 740 | module_init(s3c24xx_spi_init); | ||
| 741 | module_exit(s3c24xx_spi_exit); | ||
| 742 | 732 | ||
| 743 | MODULE_DESCRIPTION("S3C24XX SPI Driver"); | 733 | MODULE_DESCRIPTION("S3C24XX SPI Driver"); |
| 744 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | 734 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 595dacc7645f..019a7163572f 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
| @@ -131,6 +131,12 @@ | |||
| 131 | #define RXBUSY (1<<2) | 131 | #define RXBUSY (1<<2) |
| 132 | #define TXBUSY (1<<3) | 132 | #define TXBUSY (1<<3) |
| 133 | 133 | ||
| 134 | struct s3c64xx_spi_dma_data { | ||
| 135 | unsigned ch; | ||
| 136 | enum dma_data_direction direction; | ||
| 137 | enum dma_ch dmach; | ||
| 138 | }; | ||
| 139 | |||
| 134 | /** | 140 | /** |
| 135 | * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. | 141 | * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. |
| 136 | * @clk: Pointer to the spi clock. | 142 | * @clk: Pointer to the spi clock. |
| @@ -164,13 +170,14 @@ struct s3c64xx_spi_driver_data { | |||
| 164 | struct work_struct work; | 170 | struct work_struct work; |
| 165 | struct list_head queue; | 171 | struct list_head queue; |
| 166 | spinlock_t lock; | 172 | spinlock_t lock; |
| 167 | enum dma_ch rx_dmach; | ||
| 168 | enum dma_ch tx_dmach; | ||
| 169 | unsigned long sfr_start; | 173 | unsigned long sfr_start; |
| 170 | struct completion xfer_completion; | 174 | struct completion xfer_completion; |
| 171 | unsigned state; | 175 | unsigned state; |
| 172 | unsigned cur_mode, cur_bpw; | 176 | unsigned cur_mode, cur_bpw; |
| 173 | unsigned cur_speed; | 177 | unsigned cur_speed; |
| 178 | struct s3c64xx_spi_dma_data rx_dma; | ||
| 179 | struct s3c64xx_spi_dma_data tx_dma; | ||
| 180 | struct samsung_dma_ops *ops; | ||
| 174 | }; | 181 | }; |
| 175 | 182 | ||
| 176 | static struct s3c2410_dma_client s3c64xx_spi_dma_client = { | 183 | static struct s3c2410_dma_client s3c64xx_spi_dma_client = { |
| @@ -226,6 +233,78 @@ static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) | |||
| 226 | writel(val, regs + S3C64XX_SPI_CH_CFG); | 233 | writel(val, regs + S3C64XX_SPI_CH_CFG); |
| 227 | } | 234 | } |
| 228 | 235 | ||
| 236 | static void s3c64xx_spi_dmacb(void *data) | ||
| 237 | { | ||
| 238 | struct s3c64xx_spi_driver_data *sdd; | ||
| 239 | struct s3c64xx_spi_dma_data *dma = data; | ||
| 240 | unsigned long flags; | ||
| 241 | |||
| 242 | if (dma->direction == DMA_FROM_DEVICE) | ||
| 243 | sdd = container_of(data, | ||
| 244 | struct s3c64xx_spi_driver_data, rx_dma); | ||
| 245 | else | ||
| 246 | sdd = container_of(data, | ||
| 247 | struct s3c64xx_spi_driver_data, tx_dma); | ||
| 248 | |||
| 249 | spin_lock_irqsave(&sdd->lock, flags); | ||
| 250 | |||
| 251 | if (dma->direction == DMA_FROM_DEVICE) { | ||
| 252 | sdd->state &= ~RXBUSY; | ||
| 253 | if (!(sdd->state & TXBUSY)) | ||
| 254 | complete(&sdd->xfer_completion); | ||
| 255 | } else { | ||
| 256 | sdd->state &= ~TXBUSY; | ||
| 257 | if (!(sdd->state & RXBUSY)) | ||
| 258 | complete(&sdd->xfer_completion); | ||
| 259 | } | ||
| 260 | |||
| 261 | spin_unlock_irqrestore(&sdd->lock, flags); | ||
| 262 | } | ||
| 263 | |||
| 264 | static void prepare_dma(struct s3c64xx_spi_dma_data *dma, | ||
| 265 | unsigned len, dma_addr_t buf) | ||
| 266 | { | ||
| 267 | struct s3c64xx_spi_driver_data *sdd; | ||
| 268 | struct samsung_dma_prep_info info; | ||
| 269 | |||
| 270 | if (dma->direction == DMA_FROM_DEVICE) | ||
| 271 | sdd = container_of((void *)dma, | ||
| 272 | struct s3c64xx_spi_driver_data, rx_dma); | ||
| 273 | else | ||
| 274 | sdd = container_of((void *)dma, | ||
| 275 | struct s3c64xx_spi_driver_data, tx_dma); | ||
| 276 | |||
| 277 | info.cap = DMA_SLAVE; | ||
| 278 | info.len = len; | ||
| 279 | info.fp = s3c64xx_spi_dmacb; | ||
| 280 | info.fp_param = dma; | ||
| 281 | info.direction = dma->direction; | ||
| 282 | info.buf = buf; | ||
| 283 | |||
| 284 | sdd->ops->prepare(dma->ch, &info); | ||
| 285 | sdd->ops->trigger(dma->ch); | ||
| 286 | } | ||
| 287 | |||
| 288 | static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) | ||
| 289 | { | ||
| 290 | struct samsung_dma_info info; | ||
| 291 | |||
| 292 | sdd->ops = samsung_dma_get_ops(); | ||
| 293 | |||
| 294 | info.cap = DMA_SLAVE; | ||
| 295 | info.client = &s3c64xx_spi_dma_client; | ||
| 296 | info.width = sdd->cur_bpw / 8; | ||
| 297 | |||
| 298 | info.direction = sdd->rx_dma.direction; | ||
| 299 | info.fifo = sdd->sfr_start + S3C64XX_SPI_RX_DATA; | ||
| 300 | sdd->rx_dma.ch = sdd->ops->request(sdd->rx_dma.dmach, &info); | ||
| 301 | info.direction = sdd->tx_dma.direction; | ||
| 302 | info.fifo = sdd->sfr_start + S3C64XX_SPI_TX_DATA; | ||
| 303 | sdd->tx_dma.ch = sdd->ops->request(sdd->tx_dma.dmach, &info); | ||
| 304 | |||
| 305 | return 1; | ||
| 306 | } | ||
| 307 | |||
| 229 | static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, | 308 | static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, |
| 230 | struct spi_device *spi, | 309 | struct spi_device *spi, |
| 231 | struct spi_transfer *xfer, int dma_mode) | 310 | struct spi_transfer *xfer, int dma_mode) |
| @@ -258,10 +337,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, | |||
| 258 | chcfg |= S3C64XX_SPI_CH_TXCH_ON; | 337 | chcfg |= S3C64XX_SPI_CH_TXCH_ON; |
| 259 | if (dma_mode) { | 338 | if (dma_mode) { |
| 260 | modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; | 339 | modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; |
| 261 | s3c2410_dma_config(sdd->tx_dmach, sdd->cur_bpw / 8); | 340 | prepare_dma(&sdd->tx_dma, xfer->len, xfer->tx_dma); |
| 262 | s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, | ||
| 263 | xfer->tx_dma, xfer->len); | ||
| 264 | s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); | ||
| 265 | } else { | 341 | } else { |
| 266 | switch (sdd->cur_bpw) { | 342 | switch (sdd->cur_bpw) { |
| 267 | case 32: | 343 | case 32: |
| @@ -293,10 +369,7 @@ static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, | |||
| 293 | writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) | 369 | writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) |
| 294 | | S3C64XX_SPI_PACKET_CNT_EN, | 370 | | S3C64XX_SPI_PACKET_CNT_EN, |
| 295 | regs + S3C64XX_SPI_PACKET_CNT); | 371 | regs + S3C64XX_SPI_PACKET_CNT); |
| 296 | s3c2410_dma_config(sdd->rx_dmach, sdd->cur_bpw / 8); | 372 | prepare_dma(&sdd->rx_dma, xfer->len, xfer->rx_dma); |
| 297 | s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, | ||
| 298 | xfer->rx_dma, xfer->len); | ||
| 299 | s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); | ||
| 300 | } | 373 | } |
| 301 | } | 374 | } |
| 302 | 375 | ||
| @@ -482,46 +555,6 @@ static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) | |||
| 482 | } | 555 | } |
| 483 | } | 556 | } |
| 484 | 557 | ||
| 485 | static void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, | ||
| 486 | int size, enum s3c2410_dma_buffresult res) | ||
| 487 | { | ||
| 488 | struct s3c64xx_spi_driver_data *sdd = buf_id; | ||
| 489 | unsigned long flags; | ||
| 490 | |||
| 491 | spin_lock_irqsave(&sdd->lock, flags); | ||
| 492 | |||
| 493 | if (res == S3C2410_RES_OK) | ||
| 494 | sdd->state &= ~RXBUSY; | ||
| 495 | else | ||
| 496 | dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); | ||
| 497 | |||
| 498 | /* If the other done */ | ||
| 499 | if (!(sdd->state & TXBUSY)) | ||
| 500 | complete(&sdd->xfer_completion); | ||
| 501 | |||
| 502 | spin_unlock_irqrestore(&sdd->lock, flags); | ||
| 503 | } | ||
| 504 | |||
| 505 | static void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, | ||
| 506 | int size, enum s3c2410_dma_buffresult res) | ||
| 507 | { | ||
| 508 | struct s3c64xx_spi_driver_data *sdd = buf_id; | ||
| 509 | unsigned long flags; | ||
| 510 | |||
| 511 | spin_lock_irqsave(&sdd->lock, flags); | ||
| 512 | |||
| 513 | if (res == S3C2410_RES_OK) | ||
| 514 | sdd->state &= ~TXBUSY; | ||
| 515 | else | ||
| 516 | dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); | ||
| 517 | |||
| 518 | /* If the other done */ | ||
| 519 | if (!(sdd->state & RXBUSY)) | ||
| 520 | complete(&sdd->xfer_completion); | ||
| 521 | |||
| 522 | spin_unlock_irqrestore(&sdd->lock, flags); | ||
| 523 | } | ||
| 524 | |||
| 525 | #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) | 558 | #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) |
| 526 | 559 | ||
| 527 | static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, | 560 | static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, |
| @@ -696,12 +729,10 @@ static void handle_msg(struct s3c64xx_spi_driver_data *sdd, | |||
| 696 | if (use_dma) { | 729 | if (use_dma) { |
| 697 | if (xfer->tx_buf != NULL | 730 | if (xfer->tx_buf != NULL |
| 698 | && (sdd->state & TXBUSY)) | 731 | && (sdd->state & TXBUSY)) |
| 699 | s3c2410_dma_ctrl(sdd->tx_dmach, | 732 | sdd->ops->stop(sdd->tx_dma.ch); |
| 700 | S3C2410_DMAOP_FLUSH); | ||
| 701 | if (xfer->rx_buf != NULL | 733 | if (xfer->rx_buf != NULL |
| 702 | && (sdd->state & RXBUSY)) | 734 | && (sdd->state & RXBUSY)) |
| 703 | s3c2410_dma_ctrl(sdd->rx_dmach, | 735 | sdd->ops->stop(sdd->rx_dma.ch); |
| 704 | S3C2410_DMAOP_FLUSH); | ||
| 705 | } | 736 | } |
| 706 | 737 | ||
| 707 | goto out; | 738 | goto out; |
| @@ -739,30 +770,6 @@ out: | |||
| 739 | msg->complete(msg->context); | 770 | msg->complete(msg->context); |
| 740 | } | 771 | } |
| 741 | 772 | ||
| 742 | static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) | ||
| 743 | { | ||
| 744 | if (s3c2410_dma_request(sdd->rx_dmach, | ||
| 745 | &s3c64xx_spi_dma_client, NULL) < 0) { | ||
| 746 | dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); | ||
| 747 | return 0; | ||
| 748 | } | ||
| 749 | s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); | ||
| 750 | s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, | ||
| 751 | sdd->sfr_start + S3C64XX_SPI_RX_DATA); | ||
| 752 | |||
| 753 | if (s3c2410_dma_request(sdd->tx_dmach, | ||
| 754 | &s3c64xx_spi_dma_client, NULL) < 0) { | ||
| 755 | dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); | ||
| 756 | s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); | ||
| 757 | return 0; | ||
| 758 | } | ||
| 759 | s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); | ||
| 760 | s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, | ||
| 761 | sdd->sfr_start + S3C64XX_SPI_TX_DATA); | ||
| 762 | |||
| 763 | return 1; | ||
| 764 | } | ||
| 765 | |||
| 766 | static void s3c64xx_spi_work(struct work_struct *work) | 773 | static void s3c64xx_spi_work(struct work_struct *work) |
| 767 | { | 774 | { |
| 768 | struct s3c64xx_spi_driver_data *sdd = container_of(work, | 775 | struct s3c64xx_spi_driver_data *sdd = container_of(work, |
| @@ -799,8 +806,8 @@ static void s3c64xx_spi_work(struct work_struct *work) | |||
| 799 | spin_unlock_irqrestore(&sdd->lock, flags); | 806 | spin_unlock_irqrestore(&sdd->lock, flags); |
| 800 | 807 | ||
| 801 | /* Free DMA channels */ | 808 | /* Free DMA channels */ |
| 802 | s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client); | 809 | sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client); |
| 803 | s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); | 810 | sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client); |
| 804 | } | 811 | } |
| 805 | 812 | ||
| 806 | static int s3c64xx_spi_transfer(struct spi_device *spi, | 813 | static int s3c64xx_spi_transfer(struct spi_device *spi, |
| @@ -1017,8 +1024,10 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) | |||
| 1017 | sdd->cntrlr_info = sci; | 1024 | sdd->cntrlr_info = sci; |
| 1018 | sdd->pdev = pdev; | 1025 | sdd->pdev = pdev; |
| 1019 | sdd->sfr_start = mem_res->start; | 1026 | sdd->sfr_start = mem_res->start; |
| 1020 | sdd->tx_dmach = dmatx_res->start; | 1027 | sdd->tx_dma.dmach = dmatx_res->start; |
| 1021 | sdd->rx_dmach = dmarx_res->start; | 1028 | sdd->tx_dma.direction = DMA_TO_DEVICE; |
| 1029 | sdd->rx_dma.dmach = dmarx_res->start; | ||
| 1030 | sdd->rx_dma.direction = DMA_FROM_DEVICE; | ||
| 1022 | 1031 | ||
| 1023 | sdd->cur_bpw = 8; | 1032 | sdd->cur_bpw = 8; |
| 1024 | 1033 | ||
| @@ -1106,7 +1115,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) | |||
| 1106 | pdev->id, master->num_chipselect); | 1115 | pdev->id, master->num_chipselect); |
| 1107 | dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", | 1116 | dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\tDMA=[Rx-%d, Tx-%d]\n", |
| 1108 | mem_res->end, mem_res->start, | 1117 | mem_res->end, mem_res->start, |
| 1109 | sdd->rx_dmach, sdd->tx_dmach); | 1118 | sdd->rx_dma.dmach, sdd->tx_dma.dmach); |
| 1110 | 1119 | ||
| 1111 | return 0; | 1120 | return 0; |
| 1112 | 1121 | ||
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index e00d94b22250..1f466bc66d9d 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/module.h> | ||
| 22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 23 | #include <linux/pm_runtime.h> | 24 | #include <linux/pm_runtime.h> |
| 24 | 25 | ||
| @@ -635,7 +636,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) | |||
| 635 | goto err2; | 636 | goto err2; |
| 636 | } | 637 | } |
| 637 | 638 | ||
| 638 | ret = request_irq(i, sh_msiof_spi_irq, IRQF_DISABLED, | 639 | ret = request_irq(i, sh_msiof_spi_irq, 0, |
| 639 | dev_name(&pdev->dev), p); | 640 | dev_name(&pdev->dev), p); |
| 640 | if (ret) { | 641 | if (ret) { |
| 641 | dev_err(&pdev->dev, "unable to request irq\n"); | 642 | dev_err(&pdev->dev, "unable to request irq\n"); |
| @@ -730,18 +731,7 @@ static struct platform_driver sh_msiof_spi_drv = { | |||
| 730 | .pm = &sh_msiof_spi_dev_pm_ops, | 731 | .pm = &sh_msiof_spi_dev_pm_ops, |
| 731 | }, | 732 | }, |
| 732 | }; | 733 | }; |
| 733 | 734 | module_platform_driver(sh_msiof_spi_drv); | |
| 734 | static int __init sh_msiof_spi_init(void) | ||
| 735 | { | ||
| 736 | return platform_driver_register(&sh_msiof_spi_drv); | ||
| 737 | } | ||
| 738 | module_init(sh_msiof_spi_init); | ||
| 739 | |||
| 740 | static void __exit sh_msiof_spi_exit(void) | ||
| 741 | { | ||
| 742 | platform_driver_unregister(&sh_msiof_spi_drv); | ||
| 743 | } | ||
| 744 | module_exit(sh_msiof_spi_exit); | ||
| 745 | 735 | ||
| 746 | MODULE_DESCRIPTION("SuperH MSIOF SPI Master Interface Driver"); | 736 | MODULE_DESCRIPTION("SuperH MSIOF SPI Master Interface Driver"); |
| 747 | MODULE_AUTHOR("Magnus Damm"); | 737 | MODULE_AUTHOR("Magnus Damm"); |
diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c index e7779c09f6ef..097e506042be 100644 --- a/drivers/spi/spi-sh-sci.c +++ b/drivers/spi/spi-sh-sci.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
| 24 | #include <linux/spi/spi_bitbang.h> | 24 | #include <linux/spi/spi_bitbang.h> |
| 25 | #include <linux/module.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/spi.h> | 27 | #include <asm/spi.h> |
| 27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
| @@ -186,18 +187,7 @@ static struct platform_driver sh_sci_spi_drv = { | |||
| 186 | .owner = THIS_MODULE, | 187 | .owner = THIS_MODULE, |
| 187 | }, | 188 | }, |
| 188 | }; | 189 | }; |
| 189 | 190 | module_platform_driver(sh_sci_spi_drv); | |
| 190 | static int __init sh_sci_spi_init(void) | ||
| 191 | { | ||
| 192 | return platform_driver_register(&sh_sci_spi_drv); | ||
| 193 | } | ||
| 194 | module_init(sh_sci_spi_init); | ||
| 195 | |||
| 196 | static void __exit sh_sci_spi_exit(void) | ||
| 197 | { | ||
| 198 | platform_driver_unregister(&sh_sci_spi_drv); | ||
| 199 | } | ||
| 200 | module_exit(sh_sci_spi_exit); | ||
| 201 | 191 | ||
| 202 | MODULE_DESCRIPTION("SH SCI SPI Driver"); | 192 | MODULE_DESCRIPTION("SH SCI SPI Driver"); |
| 203 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); | 193 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); |
diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c index 9eedd71ad898..70c8af9f7ccc 100644 --- a/drivers/spi/spi-sh.c +++ b/drivers/spi/spi-sh.c | |||
| @@ -484,7 +484,7 @@ static int __devinit spi_sh_probe(struct platform_device *pdev) | |||
| 484 | goto error2; | 484 | goto error2; |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | ret = request_irq(irq, spi_sh_irq, IRQF_DISABLED, "spi_sh", ss); | 487 | ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss); |
| 488 | if (ret < 0) { | 488 | if (ret < 0) { |
| 489 | dev_err(&pdev->dev, "request_irq error\n"); | 489 | dev_err(&pdev->dev, "request_irq error\n"); |
| 490 | goto error3; | 490 | goto error3; |
| @@ -524,18 +524,7 @@ static struct platform_driver spi_sh_driver = { | |||
| 524 | .owner = THIS_MODULE, | 524 | .owner = THIS_MODULE, |
| 525 | }, | 525 | }, |
| 526 | }; | 526 | }; |
| 527 | 527 | module_platform_driver(spi_sh_driver); | |
| 528 | static int __init spi_sh_init(void) | ||
| 529 | { | ||
| 530 | return platform_driver_register(&spi_sh_driver); | ||
| 531 | } | ||
| 532 | module_init(spi_sh_init); | ||
| 533 | |||
| 534 | static void __exit spi_sh_exit(void) | ||
| 535 | { | ||
| 536 | platform_driver_unregister(&spi_sh_driver); | ||
| 537 | } | ||
| 538 | module_exit(spi_sh_exit); | ||
| 539 | 528 | ||
| 540 | MODULE_DESCRIPTION("SH SPI bus driver"); | 529 | MODULE_DESCRIPTION("SH SPI bus driver"); |
| 541 | MODULE_LICENSE("GPL"); | 530 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/spi/spi-stmp.c b/drivers/spi/spi-stmp.c index fadff76eb7e0..58e385285323 100644 --- a/drivers/spi/spi-stmp.c +++ b/drivers/spi/spi-stmp.c | |||
| @@ -659,19 +659,8 @@ static struct platform_driver stmp_spi_driver = { | |||
| 659 | .suspend = stmp_spi_suspend, | 659 | .suspend = stmp_spi_suspend, |
| 660 | .resume = stmp_spi_resume, | 660 | .resume = stmp_spi_resume, |
| 661 | }; | 661 | }; |
| 662 | module_platform_driver(stmp_spi_driver); | ||
| 662 | 663 | ||
| 663 | static int __init stmp_spi_init(void) | ||
| 664 | { | ||
| 665 | return platform_driver_register(&stmp_spi_driver); | ||
| 666 | } | ||
| 667 | |||
| 668 | static void __exit stmp_spi_exit(void) | ||
| 669 | { | ||
| 670 | platform_driver_unregister(&stmp_spi_driver); | ||
| 671 | } | ||
| 672 | |||
| 673 | module_init(stmp_spi_init); | ||
| 674 | module_exit(stmp_spi_exit); | ||
| 675 | module_param(pio, int, S_IRUGO); | 664 | module_param(pio, int, S_IRUGO); |
| 676 | module_param(clock, int, S_IRUGO); | 665 | module_param(clock, int, S_IRUGO); |
| 677 | MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com>"); | 666 | MODULE_AUTHOR("dmitry pervushin <dpervushin@embeddedalley.com>"); |
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index a5a6302dc8e0..ae6d78a3e912 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | */ | 18 | */ |
| 19 | 19 | ||
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/module.h> | ||
| 21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
| 22 | #include <linux/err.h> | 23 | #include <linux/err.h> |
| 23 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
| @@ -464,7 +465,7 @@ static int spi_tegra_transfer(struct spi_device *spi, struct spi_message *m) | |||
| 464 | return 0; | 465 | return 0; |
| 465 | } | 466 | } |
| 466 | 467 | ||
| 467 | static int __init spi_tegra_probe(struct platform_device *pdev) | 468 | static int __devinit spi_tegra_probe(struct platform_device *pdev) |
| 468 | { | 469 | { |
| 469 | struct spi_master *master; | 470 | struct spi_master *master; |
| 470 | struct spi_tegra_data *tspi; | 471 | struct spi_tegra_data *tspi; |
| @@ -612,19 +613,9 @@ static struct platform_driver spi_tegra_driver = { | |||
| 612 | .owner = THIS_MODULE, | 613 | .owner = THIS_MODULE, |
| 613 | .of_match_table = spi_tegra_of_match_table, | 614 | .of_match_table = spi_tegra_of_match_table, |
| 614 | }, | 615 | }, |
| 616 | .probe = spi_tegra_probe, | ||
| 615 | .remove = __devexit_p(spi_tegra_remove), | 617 | .remove = __devexit_p(spi_tegra_remove), |
| 616 | }; | 618 | }; |
| 617 | 619 | module_platform_driver(spi_tegra_driver); | |
| 618 | static int __init spi_tegra_init(void) | ||
| 619 | { | ||
| 620 | return platform_driver_probe(&spi_tegra_driver, spi_tegra_probe); | ||
| 621 | } | ||
| 622 | module_init(spi_tegra_init); | ||
| 623 | |||
| 624 | static void __exit spi_tegra_exit(void) | ||
| 625 | { | ||
| 626 | platform_driver_unregister(&spi_tegra_driver); | ||
| 627 | } | ||
| 628 | module_exit(spi_tegra_exit); | ||
| 629 | 620 | ||
| 630 | MODULE_LICENSE("GPL"); | 621 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/spi/spi-ti-ssp.c b/drivers/spi/spi-ti-ssp.c index ee22795c7973..3f6f6e81c655 100644 --- a/drivers/spi/spi-ti-ssp.c +++ b/drivers/spi/spi-ti-ssp.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
| 23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
| 24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| 25 | #include <linux/module.h> | ||
| 25 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 26 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
| 27 | #include <linux/mfd/ti_ssp.h> | 28 | #include <linux/mfd/ti_ssp.h> |
| @@ -383,18 +384,7 @@ static struct platform_driver ti_ssp_spi_driver = { | |||
| 383 | .owner = THIS_MODULE, | 384 | .owner = THIS_MODULE, |
| 384 | }, | 385 | }, |
| 385 | }; | 386 | }; |
| 386 | 387 | module_platform_driver(ti_ssp_spi_driver); | |
| 387 | static int __init ti_ssp_spi_init(void) | ||
| 388 | { | ||
| 389 | return platform_driver_register(&ti_ssp_spi_driver); | ||
| 390 | } | ||
| 391 | module_init(ti_ssp_spi_init); | ||
| 392 | |||
| 393 | static void __exit ti_ssp_spi_exit(void) | ||
| 394 | { | ||
| 395 | platform_driver_unregister(&ti_ssp_spi_driver); | ||
| 396 | } | ||
| 397 | module_exit(ti_ssp_spi_exit); | ||
| 398 | 388 | ||
| 399 | MODULE_DESCRIPTION("SSP SPI Master"); | 389 | MODULE_DESCRIPTION("SSP SPI Master"); |
| 400 | MODULE_AUTHOR("Cyril Chemparathy"); | 390 | MODULE_AUTHOR("Cyril Chemparathy"); |
diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c index 940e73d1cf09..0ce5c12aab55 100644 --- a/drivers/spi/spi-tle62x0.c +++ b/drivers/spi/spi-tle62x0.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/module.h> | ||
| 14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 15 | 16 | ||
| 16 | #include <linux/spi/spi.h> | 17 | #include <linux/spi/spi.h> |
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 1d23f3831866..6a80749391db 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c | |||
| @@ -50,6 +50,8 @@ | |||
| 50 | #define PCH_RX_THOLD 7 | 50 | #define PCH_RX_THOLD 7 |
| 51 | #define PCH_RX_THOLD_MAX 15 | 51 | #define PCH_RX_THOLD_MAX 15 |
| 52 | 52 | ||
| 53 | #define PCH_TX_THOLD 2 | ||
| 54 | |||
| 53 | #define PCH_MAX_BAUDRATE 5000000 | 55 | #define PCH_MAX_BAUDRATE 5000000 |
| 54 | #define PCH_MAX_FIFO_DEPTH 16 | 56 | #define PCH_MAX_FIFO_DEPTH 16 |
| 55 | 57 | ||
| @@ -58,6 +60,7 @@ | |||
| 58 | #define PCH_SLEEP_TIME 10 | 60 | #define PCH_SLEEP_TIME 10 |
| 59 | 61 | ||
| 60 | #define SSN_LOW 0x02U | 62 | #define SSN_LOW 0x02U |
| 63 | #define SSN_HIGH 0x03U | ||
| 61 | #define SSN_NO_CONTROL 0x00U | 64 | #define SSN_NO_CONTROL 0x00U |
| 62 | #define PCH_MAX_CS 0xFF | 65 | #define PCH_MAX_CS 0xFF |
| 63 | #define PCI_DEVICE_ID_GE_SPI 0x8816 | 66 | #define PCI_DEVICE_ID_GE_SPI 0x8816 |
| @@ -316,16 +319,19 @@ static void pch_spi_handler_sub(struct pch_spi_data *data, u32 reg_spsr_val, | |||
| 316 | 319 | ||
| 317 | /* if transfer complete interrupt */ | 320 | /* if transfer complete interrupt */ |
| 318 | if (reg_spsr_val & SPSR_FI_BIT) { | 321 | if (reg_spsr_val & SPSR_FI_BIT) { |
| 319 | if (tx_index < bpw_len) | 322 | if ((tx_index == bpw_len) && (rx_index == tx_index)) { |
| 323 | /* disable interrupts */ | ||
| 324 | pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL); | ||
| 325 | |||
| 326 | /* transfer is completed; | ||
| 327 | inform pch_spi_process_messages */ | ||
| 328 | data->transfer_complete = true; | ||
| 329 | data->transfer_active = false; | ||
| 330 | wake_up(&data->wait); | ||
| 331 | } else { | ||
| 320 | dev_err(&data->master->dev, | 332 | dev_err(&data->master->dev, |
| 321 | "%s : Transfer is not completed", __func__); | 333 | "%s : Transfer is not completed", __func__); |
| 322 | /* disable interrupts */ | 334 | } |
| 323 | pch_spi_setclr_reg(data->master, PCH_SPCR, 0, PCH_ALL); | ||
| 324 | |||
| 325 | /* transfer is completed;inform pch_spi_process_messages */ | ||
| 326 | data->transfer_complete = true; | ||
| 327 | data->transfer_active = false; | ||
| 328 | wake_up(&data->wait); | ||
| 329 | } | 335 | } |
| 330 | } | 336 | } |
| 331 | 337 | ||
| @@ -348,16 +354,26 @@ static irqreturn_t pch_spi_handler(int irq, void *dev_id) | |||
| 348 | "%s returning due to suspend\n", __func__); | 354 | "%s returning due to suspend\n", __func__); |
| 349 | return IRQ_NONE; | 355 | return IRQ_NONE; |
| 350 | } | 356 | } |
| 351 | if (data->use_dma) | ||
| 352 | return IRQ_NONE; | ||
| 353 | 357 | ||
| 354 | io_remap_addr = data->io_remap_addr; | 358 | io_remap_addr = data->io_remap_addr; |
| 355 | spsr = io_remap_addr + PCH_SPSR; | 359 | spsr = io_remap_addr + PCH_SPSR; |
| 356 | 360 | ||
| 357 | reg_spsr_val = ioread32(spsr); | 361 | reg_spsr_val = ioread32(spsr); |
| 358 | 362 | ||
| 359 | if (reg_spsr_val & SPSR_ORF_BIT) | 363 | if (reg_spsr_val & SPSR_ORF_BIT) { |
| 360 | dev_err(&board_dat->pdev->dev, "%s Over run error", __func__); | 364 | dev_err(&board_dat->pdev->dev, "%s Over run error\n", __func__); |
| 365 | if (data->current_msg->complete != 0) { | ||
| 366 | data->transfer_complete = true; | ||
| 367 | data->current_msg->status = -EIO; | ||
| 368 | data->current_msg->complete(data->current_msg->context); | ||
| 369 | data->bcurrent_msg_processing = false; | ||
| 370 | data->current_msg = NULL; | ||
| 371 | data->cur_trans = NULL; | ||
| 372 | } | ||
| 373 | } | ||
| 374 | |||
| 375 | if (data->use_dma) | ||
| 376 | return IRQ_NONE; | ||
| 361 | 377 | ||
| 362 | /* Check if the interrupt is for SPI device */ | 378 | /* Check if the interrupt is for SPI device */ |
| 363 | if (reg_spsr_val & (SPSR_FI_BIT | SPSR_RFI_BIT)) { | 379 | if (reg_spsr_val & (SPSR_FI_BIT | SPSR_RFI_BIT)) { |
| @@ -756,10 +772,6 @@ static void pch_spi_set_ir(struct pch_spi_data *data) | |||
| 756 | 772 | ||
| 757 | wait_event_interruptible(data->wait, data->transfer_complete); | 773 | wait_event_interruptible(data->wait, data->transfer_complete); |
| 758 | 774 | ||
| 759 | pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); | ||
| 760 | dev_dbg(&data->master->dev, | ||
| 761 | "%s:no more control over SSN-writing 0 to SSNXCR.", __func__); | ||
| 762 | |||
| 763 | /* clear all interrupts */ | 775 | /* clear all interrupts */ |
| 764 | pch_spi_writereg(data->master, PCH_SPSR, | 776 | pch_spi_writereg(data->master, PCH_SPSR, |
| 765 | pch_spi_readreg(data->master, PCH_SPSR)); | 777 | pch_spi_readreg(data->master, PCH_SPSR)); |
| @@ -815,10 +827,11 @@ static void pch_spi_copy_rx_data_for_dma(struct pch_spi_data *data, int bpw) | |||
| 815 | } | 827 | } |
| 816 | } | 828 | } |
| 817 | 829 | ||
| 818 | static void pch_spi_start_transfer(struct pch_spi_data *data) | 830 | static int pch_spi_start_transfer(struct pch_spi_data *data) |
| 819 | { | 831 | { |
| 820 | struct pch_spi_dma_ctrl *dma; | 832 | struct pch_spi_dma_ctrl *dma; |
| 821 | unsigned long flags; | 833 | unsigned long flags; |
| 834 | int rtn; | ||
| 822 | 835 | ||
| 823 | dma = &data->dma; | 836 | dma = &data->dma; |
| 824 | 837 | ||
| @@ -833,19 +846,23 @@ static void pch_spi_start_transfer(struct pch_spi_data *data) | |||
| 833 | initiating the transfer. */ | 846 | initiating the transfer. */ |
| 834 | dev_dbg(&data->master->dev, | 847 | dev_dbg(&data->master->dev, |
| 835 | "%s:waiting for transfer to get over\n", __func__); | 848 | "%s:waiting for transfer to get over\n", __func__); |
| 836 | wait_event_interruptible(data->wait, data->transfer_complete); | 849 | rtn = wait_event_interruptible_timeout(data->wait, |
| 850 | data->transfer_complete, | ||
| 851 | msecs_to_jiffies(2 * HZ)); | ||
| 837 | 852 | ||
| 838 | dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent, | 853 | dma_sync_sg_for_cpu(&data->master->dev, dma->sg_rx_p, dma->nent, |
| 839 | DMA_FROM_DEVICE); | 854 | DMA_FROM_DEVICE); |
| 855 | |||
| 856 | dma_sync_sg_for_cpu(&data->master->dev, dma->sg_tx_p, dma->nent, | ||
| 857 | DMA_FROM_DEVICE); | ||
| 858 | memset(data->dma.tx_buf_virt, 0, PAGE_SIZE); | ||
| 859 | |||
| 840 | async_tx_ack(dma->desc_rx); | 860 | async_tx_ack(dma->desc_rx); |
| 841 | async_tx_ack(dma->desc_tx); | 861 | async_tx_ack(dma->desc_tx); |
| 842 | kfree(dma->sg_tx_p); | 862 | kfree(dma->sg_tx_p); |
| 843 | kfree(dma->sg_rx_p); | 863 | kfree(dma->sg_rx_p); |
| 844 | 864 | ||
| 845 | spin_lock_irqsave(&data->lock, flags); | 865 | spin_lock_irqsave(&data->lock, flags); |
| 846 | pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); | ||
| 847 | dev_dbg(&data->master->dev, | ||
| 848 | "%s:no more control over SSN-writing 0 to SSNXCR.", __func__); | ||
| 849 | 866 | ||
| 850 | /* clear fifo threshold, disable interrupts, disable SPI transfer */ | 867 | /* clear fifo threshold, disable interrupts, disable SPI transfer */ |
| 851 | pch_spi_setclr_reg(data->master, PCH_SPCR, 0, | 868 | pch_spi_setclr_reg(data->master, PCH_SPCR, 0, |
| @@ -858,6 +875,8 @@ static void pch_spi_start_transfer(struct pch_spi_data *data) | |||
| 858 | pch_spi_clear_fifo(data->master); | 875 | pch_spi_clear_fifo(data->master); |
| 859 | 876 | ||
| 860 | spin_unlock_irqrestore(&data->lock, flags); | 877 | spin_unlock_irqrestore(&data->lock, flags); |
| 878 | |||
| 879 | return rtn; | ||
| 861 | } | 880 | } |
| 862 | 881 | ||
| 863 | static void pch_dma_rx_complete(void *arg) | 882 | static void pch_dma_rx_complete(void *arg) |
| @@ -1023,8 +1042,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) | |||
| 1023 | /* set receive fifo threshold and transmit fifo threshold */ | 1042 | /* set receive fifo threshold and transmit fifo threshold */ |
| 1024 | pch_spi_setclr_reg(data->master, PCH_SPCR, | 1043 | pch_spi_setclr_reg(data->master, PCH_SPCR, |
| 1025 | ((size - 1) << SPCR_RFIC_FIELD) | | 1044 | ((size - 1) << SPCR_RFIC_FIELD) | |
| 1026 | ((PCH_MAX_FIFO_DEPTH - PCH_DMA_TRANS_SIZE) << | 1045 | (PCH_TX_THOLD << SPCR_TFIC_FIELD), |
| 1027 | SPCR_TFIC_FIELD), | ||
| 1028 | MASK_RFIC_SPCR_BITS | MASK_TFIC_SPCR_BITS); | 1046 | MASK_RFIC_SPCR_BITS | MASK_TFIC_SPCR_BITS); |
| 1029 | 1047 | ||
| 1030 | spin_unlock_irqrestore(&data->lock, flags); | 1048 | spin_unlock_irqrestore(&data->lock, flags); |
| @@ -1035,13 +1053,20 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) | |||
| 1035 | /* offset, length setting */ | 1053 | /* offset, length setting */ |
| 1036 | sg = dma->sg_rx_p; | 1054 | sg = dma->sg_rx_p; |
| 1037 | for (i = 0; i < num; i++, sg++) { | 1055 | for (i = 0; i < num; i++, sg++) { |
| 1038 | if (i == 0) { | 1056 | if (i == (num - 2)) { |
| 1039 | sg->offset = 0; | 1057 | sg->offset = size * i; |
| 1058 | sg->offset = sg->offset * (*bpw / 8); | ||
| 1040 | sg_set_page(sg, virt_to_page(dma->rx_buf_virt), rem, | 1059 | sg_set_page(sg, virt_to_page(dma->rx_buf_virt), rem, |
| 1041 | sg->offset); | 1060 | sg->offset); |
| 1042 | sg_dma_len(sg) = rem; | 1061 | sg_dma_len(sg) = rem; |
| 1062 | } else if (i == (num - 1)) { | ||
| 1063 | sg->offset = size * (i - 1) + rem; | ||
| 1064 | sg->offset = sg->offset * (*bpw / 8); | ||
| 1065 | sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size, | ||
| 1066 | sg->offset); | ||
| 1067 | sg_dma_len(sg) = size; | ||
| 1043 | } else { | 1068 | } else { |
| 1044 | sg->offset = rem + size * (i - 1); | 1069 | sg->offset = size * i; |
| 1045 | sg->offset = sg->offset * (*bpw / 8); | 1070 | sg->offset = sg->offset * (*bpw / 8); |
| 1046 | sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size, | 1071 | sg_set_page(sg, virt_to_page(dma->rx_buf_virt), size, |
| 1047 | sg->offset); | 1072 | sg->offset); |
| @@ -1065,6 +1090,16 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) | |||
| 1065 | dma->desc_rx = desc_rx; | 1090 | dma->desc_rx = desc_rx; |
| 1066 | 1091 | ||
| 1067 | /* TX */ | 1092 | /* TX */ |
| 1093 | if (data->bpw_len > PCH_DMA_TRANS_SIZE) { | ||
| 1094 | num = data->bpw_len / PCH_DMA_TRANS_SIZE; | ||
| 1095 | size = PCH_DMA_TRANS_SIZE; | ||
| 1096 | rem = 16; | ||
| 1097 | } else { | ||
| 1098 | num = 1; | ||
| 1099 | size = data->bpw_len; | ||
| 1100 | rem = data->bpw_len; | ||
| 1101 | } | ||
| 1102 | |||
| 1068 | dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); | 1103 | dma->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); |
| 1069 | sg_init_table(dma->sg_tx_p, num); /* Initialize SG table */ | 1104 | sg_init_table(dma->sg_tx_p, num); /* Initialize SG table */ |
| 1070 | /* offset, length setting */ | 1105 | /* offset, length setting */ |
| @@ -1162,6 +1197,7 @@ static void pch_spi_process_messages(struct work_struct *pwork) | |||
| 1162 | if (data->use_dma) | 1197 | if (data->use_dma) |
| 1163 | pch_spi_request_dma(data, | 1198 | pch_spi_request_dma(data, |
| 1164 | data->current_msg->spi->bits_per_word); | 1199 | data->current_msg->spi->bits_per_word); |
| 1200 | pch_spi_writereg(data->master, PCH_SSNXCR, SSN_NO_CONTROL); | ||
| 1165 | do { | 1201 | do { |
| 1166 | /* If we are already processing a message get the next | 1202 | /* If we are already processing a message get the next |
| 1167 | transfer structure from the message otherwise retrieve | 1203 | transfer structure from the message otherwise retrieve |
| @@ -1184,7 +1220,8 @@ static void pch_spi_process_messages(struct work_struct *pwork) | |||
| 1184 | 1220 | ||
| 1185 | if (data->use_dma) { | 1221 | if (data->use_dma) { |
| 1186 | pch_spi_handle_dma(data, &bpw); | 1222 | pch_spi_handle_dma(data, &bpw); |
| 1187 | pch_spi_start_transfer(data); | 1223 | if (!pch_spi_start_transfer(data)) |
| 1224 | goto out; | ||
| 1188 | pch_spi_copy_rx_data_for_dma(data, bpw); | 1225 | pch_spi_copy_rx_data_for_dma(data, bpw); |
| 1189 | } else { | 1226 | } else { |
| 1190 | pch_spi_set_tx(data, &bpw); | 1227 | pch_spi_set_tx(data, &bpw); |
| @@ -1222,6 +1259,8 @@ static void pch_spi_process_messages(struct work_struct *pwork) | |||
| 1222 | 1259 | ||
| 1223 | } while (data->cur_trans != NULL); | 1260 | } while (data->cur_trans != NULL); |
| 1224 | 1261 | ||
| 1262 | out: | ||
| 1263 | pch_spi_writereg(data->master, PCH_SSNXCR, SSN_HIGH); | ||
| 1225 | if (data->use_dma) | 1264 | if (data->use_dma) |
| 1226 | pch_spi_release_dma(data); | 1265 | pch_spi_release_dma(data); |
| 1227 | } | 1266 | } |
diff --git a/drivers/spi/spi-txx9.c b/drivers/spi/spi-txx9.c index f0a2ab0428a3..d5a3cbb646cb 100644 --- a/drivers/spi/spi-txx9.c +++ b/drivers/spi/spi-txx9.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
| 26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
| 27 | #include <linux/io.h> | 27 | #include <linux/io.h> |
| 28 | #include <linux/module.h> | ||
| 28 | #include <asm/gpio.h> | 29 | #include <asm/gpio.h> |
| 29 | 30 | ||
| 30 | 31 | ||
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 4d2c75df886c..4c5a663b9fa8 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
| @@ -538,18 +538,7 @@ static struct platform_driver xilinx_spi_driver = { | |||
| 538 | .of_match_table = xilinx_spi_of_match, | 538 | .of_match_table = xilinx_spi_of_match, |
| 539 | }, | 539 | }, |
| 540 | }; | 540 | }; |
| 541 | 541 | module_platform_driver(xilinx_spi_driver); | |
| 542 | static int __init xilinx_spi_pltfm_init(void) | ||
| 543 | { | ||
| 544 | return platform_driver_register(&xilinx_spi_driver); | ||
| 545 | } | ||
| 546 | module_init(xilinx_spi_pltfm_init); | ||
| 547 | |||
| 548 | static void __exit xilinx_spi_pltfm_exit(void) | ||
| 549 | { | ||
| 550 | platform_driver_unregister(&xilinx_spi_driver); | ||
| 551 | } | ||
| 552 | module_exit(xilinx_spi_pltfm_exit); | ||
| 553 | 542 | ||
| 554 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); | 543 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); |
| 555 | MODULE_DESCRIPTION("Xilinx SPI driver"); | 544 | MODULE_DESCRIPTION("Xilinx SPI driver"); |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 4d1b9f517ce8..77eae99af11c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/spi/spi.h> | 29 | #include <linux/spi/spi.h> |
| 30 | #include <linux/of_spi.h> | 30 | #include <linux/of_spi.h> |
| 31 | #include <linux/pm_runtime.h> | 31 | #include <linux/pm_runtime.h> |
| 32 | #include <linux/export.h> | ||
| 32 | 33 | ||
| 33 | static void spidev_release(struct device *dev) | 34 | static void spidev_release(struct device *dev) |
| 34 | { | 35 | { |
