diff options
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-orion.txt | 19 | ||||
-rw-r--r-- | drivers/spi/Kconfig | 9 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/spi-bcm63xx.c | 2 | ||||
-rw-r--r-- | drivers/spi/spi-gpio.c | 3 | ||||
-rw-r--r-- | drivers/spi/spi-imx.c | 14 | ||||
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 8 | ||||
-rw-r--r-- | drivers/spi/spi-orion.c | 22 | ||||
-rw-r--r-- | drivers/spi/spi-pl022.c | 23 | ||||
-rw-r--r-- | drivers/spi/spi-tegra.c | 89 | ||||
-rw-r--r-- | drivers/spi/spi-xcomm.c | 276 | ||||
-rw-r--r-- | drivers/spi/spi.c | 2 | ||||
-rw-r--r-- | include/linux/amba/pl022.h | 9 |
13 files changed, 430 insertions, 47 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-orion.txt b/Documentation/devicetree/bindings/spi/spi-orion.txt new file mode 100644 index 000000000000..a3ff50fc76fb --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-orion.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | Marvell Orion SPI device | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : should be "marvell,orion-spi". | ||
5 | - reg : offset and length of the register set for the device | ||
6 | - cell-index : Which of multiple SPI controllers is this. | ||
7 | Optional properties: | ||
8 | - interrupts : Is currently not used. | ||
9 | |||
10 | Example: | ||
11 | spi@10600 { | ||
12 | compatible = "marvell,orion-spi"; | ||
13 | #address-cells = <1>; | ||
14 | #size-cells = <0>; | ||
15 | cell-index = <0>; | ||
16 | reg = <0x10600 0x28>; | ||
17 | interrupts = <23>; | ||
18 | status = "disabled"; | ||
19 | }; | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index cb90bc62d0a9..4cde4fb0cd6c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -357,7 +357,7 @@ config SPI_STMP3XXX | |||
357 | 357 | ||
358 | config SPI_TEGRA | 358 | config SPI_TEGRA |
359 | tristate "Nvidia Tegra SPI controller" | 359 | tristate "Nvidia Tegra SPI controller" |
360 | depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA | 360 | depends on ARCH_TEGRA && (TEGRA_SYSTEM_DMA || TEGRA20_APB_DMA) |
361 | help | 361 | help |
362 | SPI driver for NVidia Tegra SoCs | 362 | SPI driver for NVidia Tegra SoCs |
363 | 363 | ||
@@ -384,6 +384,13 @@ config SPI_TXX9 | |||
384 | help | 384 | help |
385 | SPI driver for Toshiba TXx9 MIPS SoCs | 385 | SPI driver for Toshiba TXx9 MIPS SoCs |
386 | 386 | ||
387 | config SPI_XCOMM | ||
388 | tristate "Analog Devices AD-FMCOMMS1-EBZ SPI-I2C-bridge driver" | ||
389 | depends on I2C | ||
390 | help | ||
391 | Support for the SPI-I2C bridge found on the Analog Devices | ||
392 | AD-FMCOMMS1-EBZ board. | ||
393 | |||
387 | config SPI_XILINX | 394 | config SPI_XILINX |
388 | tristate "Xilinx SPI controller common module" | 395 | tristate "Xilinx SPI controller common module" |
389 | depends on HAS_IOMEM && EXPERIMENTAL | 396 | depends on HAS_IOMEM && EXPERIMENTAL |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 9d75d2198ff5..273f50d1127a 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -61,5 +61,6 @@ obj-$(CONFIG_SPI_TI_SSP) += spi-ti-ssp.o | |||
61 | obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o | 61 | obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o |
62 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o | 62 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o |
63 | obj-$(CONFIG_SPI_TXX9) += spi-txx9.o | 63 | obj-$(CONFIG_SPI_TXX9) += spi-txx9.o |
64 | obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o | ||
64 | obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o | 65 | obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o |
65 | 66 | ||
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 7491971139a6..6e25ef1bce91 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
@@ -129,7 +129,7 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, | |||
129 | 129 | ||
130 | /* Find the closest clock configuration */ | 130 | /* Find the closest clock configuration */ |
131 | for (i = 0; i < SPI_CLK_MASK; i++) { | 131 | for (i = 0; i < SPI_CLK_MASK; i++) { |
132 | if (hz <= bcm63xx_spi_freq_table[i][0]) { | 132 | if (hz >= bcm63xx_spi_freq_table[i][0]) { |
133 | clk_cfg = bcm63xx_spi_freq_table[i][1]; | 133 | clk_cfg = bcm63xx_spi_freq_table[i][1]; |
134 | break; | 134 | break; |
135 | } | 135 | } |
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index 0094c645ff0d..0b56cfc71fab 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
@@ -235,7 +235,8 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
235 | status = gpio_request(cs, dev_name(&spi->dev)); | 235 | status = gpio_request(cs, dev_name(&spi->dev)); |
236 | if (status) | 236 | if (status) |
237 | return status; | 237 | return status; |
238 | status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH); | 238 | status = gpio_direction_output(cs, |
239 | !(spi->mode & SPI_CS_HIGH)); | ||
239 | } | 240 | } |
240 | } | 241 | } |
241 | if (!status) | 242 | if (!status) |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 47877d687614..e834ff8c0188 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -626,7 +626,7 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) | |||
626 | int active = is_active != BITBANG_CS_INACTIVE; | 626 | int active = is_active != BITBANG_CS_INACTIVE; |
627 | int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); | 627 | int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); |
628 | 628 | ||
629 | if (gpio < 0) | 629 | if (!gpio_is_valid(gpio)) |
630 | return; | 630 | return; |
631 | 631 | ||
632 | gpio_set_value(gpio, dev_is_lowactive ^ active); | 632 | gpio_set_value(gpio, dev_is_lowactive ^ active); |
@@ -688,8 +688,6 @@ static int spi_imx_setupxfer(struct spi_device *spi, | |||
688 | config.speed_hz = spi->max_speed_hz; | 688 | config.speed_hz = spi->max_speed_hz; |
689 | if (!config.bpw) | 689 | if (!config.bpw) |
690 | config.bpw = spi->bits_per_word; | 690 | config.bpw = spi->bits_per_word; |
691 | if (!config.speed_hz) | ||
692 | config.speed_hz = spi->max_speed_hz; | ||
693 | 691 | ||
694 | /* Initialize the functions for transfer */ | 692 | /* Initialize the functions for transfer */ |
695 | if (config.bpw <= 8) { | 693 | if (config.bpw <= 8) { |
@@ -738,7 +736,7 @@ static int spi_imx_setup(struct spi_device *spi) | |||
738 | dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, | 736 | dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, |
739 | spi->mode, spi->bits_per_word, spi->max_speed_hz); | 737 | spi->mode, spi->bits_per_word, spi->max_speed_hz); |
740 | 738 | ||
741 | if (gpio >= 0) | 739 | if (gpio_is_valid(gpio)) |
742 | gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); | 740 | gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); |
743 | 741 | ||
744 | spi_imx_chipselect(spi, BITBANG_CS_INACTIVE); | 742 | spi_imx_chipselect(spi, BITBANG_CS_INACTIVE); |
@@ -791,11 +789,11 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
791 | 789 | ||
792 | for (i = 0; i < master->num_chipselect; i++) { | 790 | for (i = 0; i < master->num_chipselect; i++) { |
793 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); | 791 | int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); |
794 | if (cs_gpio < 0 && mxc_platform_info) | 792 | if (!gpio_is_valid(cs_gpio) && mxc_platform_info) |
795 | cs_gpio = mxc_platform_info->chipselect[i]; | 793 | cs_gpio = mxc_platform_info->chipselect[i]; |
796 | 794 | ||
797 | spi_imx->chipselect[i] = cs_gpio; | 795 | spi_imx->chipselect[i] = cs_gpio; |
798 | if (cs_gpio < 0) | 796 | if (!gpio_is_valid(cs_gpio)) |
799 | continue; | 797 | continue; |
800 | 798 | ||
801 | ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); | 799 | ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME); |
@@ -897,7 +895,7 @@ out_release_mem: | |||
897 | release_mem_region(res->start, resource_size(res)); | 895 | release_mem_region(res->start, resource_size(res)); |
898 | out_gpio_free: | 896 | out_gpio_free: |
899 | while (--i >= 0) { | 897 | while (--i >= 0) { |
900 | if (spi_imx->chipselect[i] >= 0) | 898 | if (gpio_is_valid(spi_imx->chipselect[i])) |
901 | gpio_free(spi_imx->chipselect[i]); | 899 | gpio_free(spi_imx->chipselect[i]); |
902 | } | 900 | } |
903 | spi_master_put(master); | 901 | spi_master_put(master); |
@@ -922,7 +920,7 @@ static int __devexit spi_imx_remove(struct platform_device *pdev) | |||
922 | iounmap(spi_imx->base); | 920 | iounmap(spi_imx->base); |
923 | 921 | ||
924 | for (i = 0; i < master->num_chipselect; i++) | 922 | for (i = 0; i < master->num_chipselect; i++) |
925 | if (spi_imx->chipselect[i] >= 0) | 923 | if (gpio_is_valid(spi_imx->chipselect[i])) |
926 | gpio_free(spi_imx->chipselect[i]); | 924 | gpio_free(spi_imx->chipselect[i]); |
927 | 925 | ||
928 | spi_master_put(master); | 926 | spi_master_put(master); |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 0c73dd4f43a0..7d46b15e1520 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -388,7 +388,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
388 | 388 | ||
389 | if (tx != NULL) { | 389 | if (tx != NULL) { |
390 | wait_for_completion(&mcspi_dma->dma_tx_completion); | 390 | wait_for_completion(&mcspi_dma->dma_tx_completion); |
391 | dma_unmap_single(&spi->dev, xfer->tx_dma, count, DMA_TO_DEVICE); | 391 | dma_unmap_single(mcspi->dev, xfer->tx_dma, count, |
392 | DMA_TO_DEVICE); | ||
392 | 393 | ||
393 | /* for TX_ONLY mode, be sure all words have shifted out */ | 394 | /* for TX_ONLY mode, be sure all words have shifted out */ |
394 | if (rx == NULL) { | 395 | if (rx == NULL) { |
@@ -403,7 +404,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
403 | 404 | ||
404 | if (rx != NULL) { | 405 | if (rx != NULL) { |
405 | wait_for_completion(&mcspi_dma->dma_rx_completion); | 406 | wait_for_completion(&mcspi_dma->dma_rx_completion); |
406 | dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE); | 407 | dma_unmap_single(mcspi->dev, xfer->rx_dma, count, |
408 | DMA_FROM_DEVICE); | ||
407 | omap2_mcspi_set_enable(spi, 0); | 409 | omap2_mcspi_set_enable(spi, 0); |
408 | 410 | ||
409 | if (l & OMAP2_MCSPI_CHCONF_TURBO) { | 411 | if (l & OMAP2_MCSPI_CHCONF_TURBO) { |
@@ -1032,7 +1034,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
1032 | return 0; | 1034 | return 0; |
1033 | } | 1035 | } |
1034 | 1036 | ||
1035 | static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1037 | static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
1036 | { | 1038 | { |
1037 | struct spi_master *master = mcspi->master; | 1039 | struct spi_master *master = mcspi->master; |
1038 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | 1040 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index dfd04e91fa6d..9b0caddce503 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/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/of.h> | ||
20 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
21 | #include <asm/unaligned.h> | 22 | #include <asm/unaligned.h> |
22 | 23 | ||
@@ -45,7 +46,6 @@ struct orion_spi { | |||
45 | void __iomem *base; | 46 | void __iomem *base; |
46 | unsigned int max_speed; | 47 | unsigned int max_speed; |
47 | unsigned int min_speed; | 48 | unsigned int min_speed; |
48 | struct orion_spi_info *spi_info; | ||
49 | struct clk *clk; | 49 | struct clk *clk; |
50 | }; | 50 | }; |
51 | 51 | ||
@@ -450,11 +450,10 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
450 | struct spi_master *master; | 450 | struct spi_master *master; |
451 | struct orion_spi *spi; | 451 | struct orion_spi *spi; |
452 | struct resource *r; | 452 | struct resource *r; |
453 | struct orion_spi_info *spi_info; | ||
454 | unsigned long tclk_hz; | 453 | unsigned long tclk_hz; |
455 | int status = 0; | 454 | int status = 0; |
456 | 455 | const u32 *iprop; | |
457 | spi_info = pdev->dev.platform_data; | 456 | int size; |
458 | 457 | ||
459 | master = spi_alloc_master(&pdev->dev, sizeof *spi); | 458 | master = spi_alloc_master(&pdev->dev, sizeof *spi); |
460 | if (master == NULL) { | 459 | if (master == NULL) { |
@@ -464,6 +463,12 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
464 | 463 | ||
465 | if (pdev->id != -1) | 464 | if (pdev->id != -1) |
466 | master->bus_num = pdev->id; | 465 | master->bus_num = pdev->id; |
466 | if (pdev->dev.of_node) { | ||
467 | iprop = of_get_property(pdev->dev.of_node, "cell-index", | ||
468 | &size); | ||
469 | if (iprop && size == sizeof(*iprop)) | ||
470 | master->bus_num = *iprop; | ||
471 | } | ||
467 | 472 | ||
468 | /* we support only mode 0, and no options */ | 473 | /* we support only mode 0, and no options */ |
469 | master->mode_bits = 0; | 474 | master->mode_bits = 0; |
@@ -476,7 +481,6 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
476 | 481 | ||
477 | spi = spi_master_get_devdata(master); | 482 | spi = spi_master_get_devdata(master); |
478 | spi->master = master; | 483 | spi->master = master; |
479 | spi->spi_info = spi_info; | ||
480 | 484 | ||
481 | spi->clk = clk_get(&pdev->dev, NULL); | 485 | spi->clk = clk_get(&pdev->dev, NULL); |
482 | if (IS_ERR(spi->clk)) { | 486 | if (IS_ERR(spi->clk)) { |
@@ -511,6 +515,7 @@ static int __init orion_spi_probe(struct platform_device *pdev) | |||
511 | if (orion_spi_reset(spi) < 0) | 515 | if (orion_spi_reset(spi) < 0) |
512 | goto out_rel_mem; | 516 | goto out_rel_mem; |
513 | 517 | ||
518 | master->dev.of_node = pdev->dev.of_node; | ||
514 | status = spi_register_master(master); | 519 | status = spi_register_master(master); |
515 | if (status < 0) | 520 | if (status < 0) |
516 | goto out_rel_mem; | 521 | goto out_rel_mem; |
@@ -552,10 +557,17 @@ static int __exit orion_spi_remove(struct platform_device *pdev) | |||
552 | 557 | ||
553 | MODULE_ALIAS("platform:" DRIVER_NAME); | 558 | MODULE_ALIAS("platform:" DRIVER_NAME); |
554 | 559 | ||
560 | static const struct of_device_id orion_spi_of_match_table[] __devinitdata = { | ||
561 | { .compatible = "marvell,orion-spi", }, | ||
562 | {} | ||
563 | }; | ||
564 | MODULE_DEVICE_TABLE(of, orion_spi_of_match_table); | ||
565 | |||
555 | static struct platform_driver orion_spi_driver = { | 566 | static struct platform_driver orion_spi_driver = { |
556 | .driver = { | 567 | .driver = { |
557 | .name = DRIVER_NAME, | 568 | .name = DRIVER_NAME, |
558 | .owner = THIS_MODULE, | 569 | .owner = THIS_MODULE, |
570 | .of_match_table = of_match_ptr(orion_spi_of_match_table), | ||
559 | }, | 571 | }, |
560 | .remove = __exit_p(orion_spi_remove), | 572 | .remove = __exit_p(orion_spi_remove), |
561 | }; | 573 | }; |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 400ae2121a2a..aab518ec2bbc 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -489,6 +489,11 @@ static void giveback(struct pl022 *pl022) | |||
489 | pl022->cur_transfer = NULL; | 489 | pl022->cur_transfer = NULL; |
490 | pl022->cur_chip = NULL; | 490 | pl022->cur_chip = NULL; |
491 | spi_finalize_current_message(pl022->master); | 491 | spi_finalize_current_message(pl022->master); |
492 | |||
493 | /* disable the SPI/SSP operation */ | ||
494 | writew((readw(SSP_CR1(pl022->virtbase)) & | ||
495 | (~SSP_CR1_MASK_SSE)), SSP_CR1(pl022->virtbase)); | ||
496 | |||
492 | } | 497 | } |
493 | 498 | ||
494 | /** | 499 | /** |
@@ -2048,6 +2053,9 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2048 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
2049 | adev->res.start, pl022->virtbase); | 2054 | adev->res.start, pl022->virtbase); |
2050 | 2055 | ||
2056 | pm_runtime_enable(dev); | ||
2057 | pm_runtime_resume(dev); | ||
2058 | |||
2051 | pl022->clk = clk_get(&adev->dev, NULL); | 2059 | pl022->clk = clk_get(&adev->dev, NULL); |
2052 | if (IS_ERR(pl022->clk)) { | 2060 | if (IS_ERR(pl022->clk)) { |
2053 | status = PTR_ERR(pl022->clk); | 2061 | status = PTR_ERR(pl022->clk); |
@@ -2158,6 +2166,7 @@ pl022_remove(struct amba_device *adev) | |||
2158 | clk_disable(pl022->clk); | 2166 | clk_disable(pl022->clk); |
2159 | clk_unprepare(pl022->clk); | 2167 | clk_unprepare(pl022->clk); |
2160 | clk_put(pl022->clk); | 2168 | clk_put(pl022->clk); |
2169 | pm_runtime_disable(&adev->dev); | ||
2161 | iounmap(pl022->virtbase); | 2170 | iounmap(pl022->virtbase); |
2162 | amba_release_regions(adev); | 2171 | amba_release_regions(adev); |
2163 | tasklet_disable(&pl022->pump_transfers); | 2172 | tasklet_disable(&pl022->pump_transfers); |
@@ -2251,15 +2260,6 @@ static struct vendor_data vendor_st_pl023 = { | |||
2251 | .loopback = false, | 2260 | .loopback = false, |
2252 | }; | 2261 | }; |
2253 | 2262 | ||
2254 | static struct vendor_data vendor_db5500_pl023 = { | ||
2255 | .fifodepth = 32, | ||
2256 | .max_bpw = 32, | ||
2257 | .unidir = false, | ||
2258 | .extended_cr = true, | ||
2259 | .pl023 = true, | ||
2260 | .loopback = true, | ||
2261 | }; | ||
2262 | |||
2263 | static struct amba_id pl022_ids[] = { | 2263 | static struct amba_id pl022_ids[] = { |
2264 | { | 2264 | { |
2265 | /* | 2265 | /* |
@@ -2291,11 +2291,6 @@ static struct amba_id pl022_ids[] = { | |||
2291 | .mask = 0xffffffff, | 2291 | .mask = 0xffffffff, |
2292 | .data = &vendor_st_pl023, | 2292 | .data = &vendor_st_pl023, |
2293 | }, | 2293 | }, |
2294 | { | ||
2295 | .id = 0x10080023, | ||
2296 | .mask = 0xffffffff, | ||
2297 | .data = &vendor_db5500_pl023, | ||
2298 | }, | ||
2299 | { 0, 0 }, | 2294 | { 0, 0 }, |
2300 | }; | 2295 | }; |
2301 | 2296 | ||
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index 7f99ff3553a6..ef52c1c6f5c5 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
31 | 31 | ||
32 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
33 | #include <linux/dmaengine.h> | ||
33 | 34 | ||
34 | #include <mach/dma.h> | 35 | #include <mach/dma.h> |
35 | 36 | ||
@@ -162,12 +163,23 @@ struct spi_tegra_data { | |||
162 | * require transfers to be 4 byte aligned we need a bounce buffer | 163 | * require transfers to be 4 byte aligned we need a bounce buffer |
163 | * for the generic case. | 164 | * for the generic case. |
164 | */ | 165 | */ |
166 | int dma_req_len; | ||
167 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
165 | struct tegra_dma_req rx_dma_req; | 168 | struct tegra_dma_req rx_dma_req; |
166 | struct tegra_dma_channel *rx_dma; | 169 | struct tegra_dma_channel *rx_dma; |
170 | #else | ||
171 | struct dma_chan *rx_dma; | ||
172 | struct dma_slave_config sconfig; | ||
173 | struct dma_async_tx_descriptor *rx_dma_desc; | ||
174 | dma_cookie_t rx_cookie; | ||
175 | #endif | ||
167 | u32 *rx_bb; | 176 | u32 *rx_bb; |
168 | dma_addr_t rx_bb_phys; | 177 | dma_addr_t rx_bb_phys; |
169 | }; | 178 | }; |
170 | 179 | ||
180 | #if !defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
181 | static void tegra_spi_rx_dma_complete(void *args); | ||
182 | #endif | ||
171 | 183 | ||
172 | static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, | 184 | static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, |
173 | unsigned long reg) | 185 | unsigned long reg) |
@@ -190,10 +202,24 @@ static void spi_tegra_go(struct spi_tegra_data *tspi) | |||
190 | 202 | ||
191 | val = spi_tegra_readl(tspi, SLINK_DMA_CTL); | 203 | val = spi_tegra_readl(tspi, SLINK_DMA_CTL); |
192 | val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; | 204 | val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; |
193 | val |= SLINK_DMA_BLOCK_SIZE(tspi->rx_dma_req.size / 4 - 1); | 205 | val |= SLINK_DMA_BLOCK_SIZE(tspi->dma_req_len / 4 - 1); |
194 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | 206 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); |
195 | 207 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | |
208 | tspi->rx_dma_req.size = tspi->dma_req_len; | ||
196 | tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req); | 209 | tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req); |
210 | #else | ||
211 | tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma, | ||
212 | tspi->rx_bb_phys, tspi->dma_req_len, | ||
213 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); | ||
214 | if (!tspi->rx_dma_desc) { | ||
215 | dev_err(&tspi->pdev->dev, "dmaengine slave prep failed\n"); | ||
216 | return; | ||
217 | } | ||
218 | tspi->rx_dma_desc->callback = tegra_spi_rx_dma_complete; | ||
219 | tspi->rx_dma_desc->callback_param = tspi; | ||
220 | tspi->rx_cookie = dmaengine_submit(tspi->rx_dma_desc); | ||
221 | dma_async_issue_pending(tspi->rx_dma); | ||
222 | #endif | ||
197 | 223 | ||
198 | val |= SLINK_DMA_EN; | 224 | val |= SLINK_DMA_EN; |
199 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | 225 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); |
@@ -221,7 +247,7 @@ static unsigned spi_tegra_fill_tx_fifo(struct spi_tegra_data *tspi, | |||
221 | spi_tegra_writel(tspi, val, SLINK_TX_FIFO); | 247 | spi_tegra_writel(tspi, val, SLINK_TX_FIFO); |
222 | } | 248 | } |
223 | 249 | ||
224 | tspi->rx_dma_req.size = len / tspi->cur_bytes_per_word * 4; | 250 | tspi->dma_req_len = len / tspi->cur_bytes_per_word * 4; |
225 | 251 | ||
226 | return len; | 252 | return len; |
227 | } | 253 | } |
@@ -318,9 +344,8 @@ static void spi_tegra_start_message(struct spi_device *spi, | |||
318 | spi_tegra_start_transfer(spi, t); | 344 | spi_tegra_start_transfer(spi, t); |
319 | } | 345 | } |
320 | 346 | ||
321 | static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) | 347 | static void handle_spi_rx_dma_complete(struct spi_tegra_data *tspi) |
322 | { | 348 | { |
323 | struct spi_tegra_data *tspi = req->dev; | ||
324 | unsigned long flags; | 349 | unsigned long flags; |
325 | struct spi_message *m; | 350 | struct spi_message *m; |
326 | struct spi_device *spi; | 351 | struct spi_device *spi; |
@@ -380,6 +405,19 @@ static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) | |||
380 | 405 | ||
381 | spin_unlock_irqrestore(&tspi->lock, flags); | 406 | spin_unlock_irqrestore(&tspi->lock, flags); |
382 | } | 407 | } |
408 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
409 | static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) | ||
410 | { | ||
411 | struct spi_tegra_data *tspi = req->dev; | ||
412 | handle_spi_rx_dma_complete(tspi); | ||
413 | } | ||
414 | #else | ||
415 | static void tegra_spi_rx_dma_complete(void *args) | ||
416 | { | ||
417 | struct spi_tegra_data *tspi = args; | ||
418 | handle_spi_rx_dma_complete(tspi); | ||
419 | } | ||
420 | #endif | ||
383 | 421 | ||
384 | static int spi_tegra_setup(struct spi_device *spi) | 422 | static int spi_tegra_setup(struct spi_device *spi) |
385 | { | 423 | { |
@@ -471,6 +509,9 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
471 | struct spi_tegra_data *tspi; | 509 | struct spi_tegra_data *tspi; |
472 | struct resource *r; | 510 | struct resource *r; |
473 | int ret; | 511 | int ret; |
512 | #if !defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
513 | dma_cap_mask_t mask; | ||
514 | #endif | ||
474 | 515 | ||
475 | master = spi_alloc_master(&pdev->dev, sizeof *tspi); | 516 | master = spi_alloc_master(&pdev->dev, sizeof *tspi); |
476 | if (master == NULL) { | 517 | if (master == NULL) { |
@@ -522,12 +563,24 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
522 | 563 | ||
523 | INIT_LIST_HEAD(&tspi->queue); | 564 | INIT_LIST_HEAD(&tspi->queue); |
524 | 565 | ||
566 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
525 | tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT); | 567 | tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT); |
526 | if (!tspi->rx_dma) { | 568 | if (!tspi->rx_dma) { |
527 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); | 569 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); |
528 | ret = -ENODEV; | 570 | ret = -ENODEV; |
529 | goto err3; | 571 | goto err3; |
530 | } | 572 | } |
573 | #else | ||
574 | dma_cap_zero(mask); | ||
575 | dma_cap_set(DMA_SLAVE, mask); | ||
576 | tspi->rx_dma = dma_request_channel(mask, NULL, NULL); | ||
577 | if (!tspi->rx_dma) { | ||
578 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); | ||
579 | ret = -ENODEV; | ||
580 | goto err3; | ||
581 | } | ||
582 | |||
583 | #endif | ||
531 | 584 | ||
532 | tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | 585 | tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, |
533 | &tspi->rx_bb_phys, GFP_KERNEL); | 586 | &tspi->rx_bb_phys, GFP_KERNEL); |
@@ -537,6 +590,7 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
537 | goto err4; | 590 | goto err4; |
538 | } | 591 | } |
539 | 592 | ||
593 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
540 | tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete; | 594 | tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete; |
541 | tspi->rx_dma_req.to_memory = 1; | 595 | tspi->rx_dma_req.to_memory = 1; |
542 | tspi->rx_dma_req.dest_addr = tspi->rx_bb_phys; | 596 | tspi->rx_dma_req.dest_addr = tspi->rx_bb_phys; |
@@ -546,6 +600,23 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
546 | tspi->rx_dma_req.source_wrap = 4; | 600 | tspi->rx_dma_req.source_wrap = 4; |
547 | tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; | 601 | tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; |
548 | tspi->rx_dma_req.dev = tspi; | 602 | tspi->rx_dma_req.dev = tspi; |
603 | #else | ||
604 | /* Dmaengine Dma slave config */ | ||
605 | tspi->sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; | ||
606 | tspi->sconfig.dst_addr = tspi->phys + SLINK_RX_FIFO; | ||
607 | tspi->sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
608 | tspi->sconfig.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | ||
609 | tspi->sconfig.slave_id = spi_tegra_req_sels[pdev->id]; | ||
610 | tspi->sconfig.src_maxburst = 1; | ||
611 | tspi->sconfig.dst_maxburst = 1; | ||
612 | ret = dmaengine_device_control(tspi->rx_dma, | ||
613 | DMA_SLAVE_CONFIG, (unsigned long) &tspi->sconfig); | ||
614 | if (ret < 0) { | ||
615 | dev_err(&pdev->dev, "can not do slave configure for dma %d\n", | ||
616 | ret); | ||
617 | goto err4; | ||
618 | } | ||
619 | #endif | ||
549 | 620 | ||
550 | master->dev.of_node = pdev->dev.of_node; | 621 | master->dev.of_node = pdev->dev.of_node; |
551 | ret = spi_register_master(master); | 622 | ret = spi_register_master(master); |
@@ -559,7 +630,11 @@ err5: | |||
559 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | 630 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, |
560 | tspi->rx_bb, tspi->rx_bb_phys); | 631 | tspi->rx_bb, tspi->rx_bb_phys); |
561 | err4: | 632 | err4: |
633 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
562 | tegra_dma_free_channel(tspi->rx_dma); | 634 | tegra_dma_free_channel(tspi->rx_dma); |
635 | #else | ||
636 | dma_release_channel(tspi->rx_dma); | ||
637 | #endif | ||
563 | err3: | 638 | err3: |
564 | clk_put(tspi->clk); | 639 | clk_put(tspi->clk); |
565 | err2: | 640 | err2: |
@@ -581,7 +656,11 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) | |||
581 | tspi = spi_master_get_devdata(master); | 656 | tspi = spi_master_get_devdata(master); |
582 | 657 | ||
583 | spi_unregister_master(master); | 658 | spi_unregister_master(master); |
659 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
584 | tegra_dma_free_channel(tspi->rx_dma); | 660 | tegra_dma_free_channel(tspi->rx_dma); |
661 | #else | ||
662 | dma_release_channel(tspi->rx_dma); | ||
663 | #endif | ||
585 | 664 | ||
586 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | 665 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, |
587 | tspi->rx_bb, tspi->rx_bb_phys); | 666 | tspi->rx_bb, tspi->rx_bb_phys); |
diff --git a/drivers/spi/spi-xcomm.c b/drivers/spi/spi-xcomm.c new file mode 100644 index 000000000000..266a847e2992 --- /dev/null +++ b/drivers/spi/spi-xcomm.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * Analog Devices AD-FMCOMMS1-EBZ board I2C-SPI bridge driver | ||
3 | * | ||
4 | * Copyright 2012 Analog Devices Inc. | ||
5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
6 | * | ||
7 | * Licensed under the GPL-2 or later. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/spi/spi.h> | ||
16 | #include <asm/unaligned.h> | ||
17 | |||
18 | #define SPI_XCOMM_SETTINGS_LEN_OFFSET 10 | ||
19 | #define SPI_XCOMM_SETTINGS_3WIRE BIT(6) | ||
20 | #define SPI_XCOMM_SETTINGS_CS_HIGH BIT(5) | ||
21 | #define SPI_XCOMM_SETTINGS_SAMPLE_END BIT(4) | ||
22 | #define SPI_XCOMM_SETTINGS_CPHA BIT(3) | ||
23 | #define SPI_XCOMM_SETTINGS_CPOL BIT(2) | ||
24 | #define SPI_XCOMM_SETTINGS_CLOCK_DIV_MASK 0x3 | ||
25 | #define SPI_XCOMM_SETTINGS_CLOCK_DIV_64 0x2 | ||
26 | #define SPI_XCOMM_SETTINGS_CLOCK_DIV_16 0x1 | ||
27 | #define SPI_XCOMM_SETTINGS_CLOCK_DIV_4 0x0 | ||
28 | |||
29 | #define SPI_XCOMM_CMD_UPDATE_CONFIG 0x03 | ||
30 | #define SPI_XCOMM_CMD_WRITE 0x04 | ||
31 | |||
32 | #define SPI_XCOMM_CLOCK 48000000 | ||
33 | |||
34 | struct spi_xcomm { | ||
35 | struct i2c_client *i2c; | ||
36 | |||
37 | uint16_t settings; | ||
38 | uint16_t chipselect; | ||
39 | |||
40 | unsigned int current_speed; | ||
41 | |||
42 | uint8_t buf[63]; | ||
43 | }; | ||
44 | |||
45 | static int spi_xcomm_sync_config(struct spi_xcomm *spi_xcomm, unsigned int len) | ||
46 | { | ||
47 | uint16_t settings; | ||
48 | uint8_t *buf = spi_xcomm->buf; | ||
49 | |||
50 | settings = spi_xcomm->settings; | ||
51 | settings |= len << SPI_XCOMM_SETTINGS_LEN_OFFSET; | ||
52 | |||
53 | buf[0] = SPI_XCOMM_CMD_UPDATE_CONFIG; | ||
54 | put_unaligned_be16(settings, &buf[1]); | ||
55 | put_unaligned_be16(spi_xcomm->chipselect, &buf[3]); | ||
56 | |||
57 | return i2c_master_send(spi_xcomm->i2c, buf, 5); | ||
58 | } | ||
59 | |||
60 | static void spi_xcomm_chipselect(struct spi_xcomm *spi_xcomm, | ||
61 | struct spi_device *spi, int is_active) | ||
62 | { | ||
63 | unsigned long cs = spi->chip_select; | ||
64 | uint16_t chipselect = spi_xcomm->chipselect; | ||
65 | |||
66 | if (is_active) | ||
67 | chipselect |= BIT(cs); | ||
68 | else | ||
69 | chipselect &= ~BIT(cs); | ||
70 | |||
71 | spi_xcomm->chipselect = chipselect; | ||
72 | } | ||
73 | |||
74 | static int spi_xcomm_setup_transfer(struct spi_xcomm *spi_xcomm, | ||
75 | struct spi_device *spi, struct spi_transfer *t, unsigned int *settings) | ||
76 | { | ||
77 | unsigned int speed; | ||
78 | |||
79 | if ((t->bits_per_word && t->bits_per_word != 8) || t->len > 62) | ||
80 | return -EINVAL; | ||
81 | |||
82 | speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz; | ||
83 | |||
84 | if (speed != spi_xcomm->current_speed) { | ||
85 | unsigned int divider = DIV_ROUND_UP(SPI_XCOMM_CLOCK, speed); | ||
86 | if (divider >= 64) | ||
87 | *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_64; | ||
88 | else if (divider >= 16) | ||
89 | *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_16; | ||
90 | else | ||
91 | *settings |= SPI_XCOMM_SETTINGS_CLOCK_DIV_4; | ||
92 | |||
93 | spi_xcomm->current_speed = speed; | ||
94 | } | ||
95 | |||
96 | if (spi->mode & SPI_CPOL) | ||
97 | *settings |= SPI_XCOMM_SETTINGS_CPOL; | ||
98 | else | ||
99 | *settings &= ~SPI_XCOMM_SETTINGS_CPOL; | ||
100 | |||
101 | if (spi->mode & SPI_CPHA) | ||
102 | *settings &= ~SPI_XCOMM_SETTINGS_CPHA; | ||
103 | else | ||
104 | *settings |= SPI_XCOMM_SETTINGS_CPHA; | ||
105 | |||
106 | if (spi->mode & SPI_3WIRE) | ||
107 | *settings |= SPI_XCOMM_SETTINGS_3WIRE; | ||
108 | else | ||
109 | *settings &= ~SPI_XCOMM_SETTINGS_3WIRE; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int spi_xcomm_txrx_bufs(struct spi_xcomm *spi_xcomm, | ||
115 | struct spi_device *spi, struct spi_transfer *t) | ||
116 | { | ||
117 | int ret; | ||
118 | |||
119 | if (t->tx_buf) { | ||
120 | spi_xcomm->buf[0] = SPI_XCOMM_CMD_WRITE; | ||
121 | memcpy(spi_xcomm->buf + 1, t->tx_buf, t->len); | ||
122 | |||
123 | ret = i2c_master_send(spi_xcomm->i2c, spi_xcomm->buf, t->len + 1); | ||
124 | if (ret < 0) | ||
125 | return ret; | ||
126 | else if (ret != t->len + 1) | ||
127 | return -EIO; | ||
128 | } else if (t->rx_buf) { | ||
129 | ret = i2c_master_recv(spi_xcomm->i2c, t->rx_buf, t->len); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | else if (ret != t->len) | ||
133 | return -EIO; | ||
134 | } | ||
135 | |||
136 | return t->len; | ||
137 | } | ||
138 | |||
139 | static int spi_xcomm_transfer_one(struct spi_master *master, | ||
140 | struct spi_message *msg) | ||
141 | { | ||
142 | struct spi_xcomm *spi_xcomm = spi_master_get_devdata(master); | ||
143 | unsigned int settings = spi_xcomm->settings; | ||
144 | struct spi_device *spi = msg->spi; | ||
145 | unsigned cs_change = 0; | ||
146 | struct spi_transfer *t; | ||
147 | bool is_first = true; | ||
148 | int status = 0; | ||
149 | bool is_last; | ||
150 | |||
151 | is_first = true; | ||
152 | |||
153 | spi_xcomm_chipselect(spi_xcomm, spi, true); | ||
154 | |||
155 | list_for_each_entry(t, &msg->transfers, transfer_list) { | ||
156 | |||
157 | if (!t->tx_buf && !t->rx_buf && t->len) { | ||
158 | status = -EINVAL; | ||
159 | break; | ||
160 | } | ||
161 | |||
162 | status = spi_xcomm_setup_transfer(spi_xcomm, spi, t, &settings); | ||
163 | if (status < 0) | ||
164 | break; | ||
165 | |||
166 | is_last = list_is_last(&t->transfer_list, &msg->transfers); | ||
167 | cs_change = t->cs_change; | ||
168 | |||
169 | if (cs_change ^ is_last) | ||
170 | settings |= BIT(5); | ||
171 | else | ||
172 | settings &= ~BIT(5); | ||
173 | |||
174 | if (t->rx_buf) { | ||
175 | spi_xcomm->settings = settings; | ||
176 | status = spi_xcomm_sync_config(spi_xcomm, t->len); | ||
177 | if (status < 0) | ||
178 | break; | ||
179 | } else if (settings != spi_xcomm->settings || is_first) { | ||
180 | spi_xcomm->settings = settings; | ||
181 | status = spi_xcomm_sync_config(spi_xcomm, 0); | ||
182 | if (status < 0) | ||
183 | break; | ||
184 | } | ||
185 | |||
186 | if (t->len) { | ||
187 | status = spi_xcomm_txrx_bufs(spi_xcomm, spi, t); | ||
188 | |||
189 | if (status < 0) | ||
190 | break; | ||
191 | |||
192 | if (status > 0) | ||
193 | msg->actual_length += status; | ||
194 | } | ||
195 | status = 0; | ||
196 | |||
197 | if (t->delay_usecs) | ||
198 | udelay(t->delay_usecs); | ||
199 | |||
200 | is_first = false; | ||
201 | } | ||
202 | |||
203 | if (status != 0 || !cs_change) | ||
204 | spi_xcomm_chipselect(spi_xcomm, spi, false); | ||
205 | |||
206 | msg->status = status; | ||
207 | spi_finalize_current_message(master); | ||
208 | |||
209 | return status; | ||
210 | } | ||
211 | |||
212 | static int spi_xcomm_setup(struct spi_device *spi) | ||
213 | { | ||
214 | if (spi->bits_per_word != 8) | ||
215 | return -EINVAL; | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int __devinit spi_xcomm_probe(struct i2c_client *i2c, | ||
221 | const struct i2c_device_id *id) | ||
222 | { | ||
223 | struct spi_xcomm *spi_xcomm; | ||
224 | struct spi_master *master; | ||
225 | int ret; | ||
226 | |||
227 | master = spi_alloc_master(&i2c->dev, sizeof(*spi_xcomm)); | ||
228 | if (!master) | ||
229 | return -ENOMEM; | ||
230 | |||
231 | spi_xcomm = spi_master_get_devdata(master); | ||
232 | spi_xcomm->i2c = i2c; | ||
233 | |||
234 | master->num_chipselect = 16; | ||
235 | master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_3WIRE; | ||
236 | master->flags = SPI_MASTER_HALF_DUPLEX; | ||
237 | master->setup = spi_xcomm_setup; | ||
238 | master->transfer_one_message = spi_xcomm_transfer_one; | ||
239 | master->dev.of_node = i2c->dev.of_node; | ||
240 | i2c_set_clientdata(i2c, master); | ||
241 | |||
242 | ret = spi_register_master(master); | ||
243 | if (ret < 0) | ||
244 | spi_master_put(master); | ||
245 | |||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | static int __devexit spi_xcomm_remove(struct i2c_client *i2c) | ||
250 | { | ||
251 | struct spi_master *master = i2c_get_clientdata(i2c); | ||
252 | |||
253 | spi_unregister_master(master); | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static const struct i2c_device_id spi_xcomm_ids[] = { | ||
259 | { "spi-xcomm" }, | ||
260 | { }, | ||
261 | }; | ||
262 | |||
263 | static struct i2c_driver spi_xcomm_driver = { | ||
264 | .driver = { | ||
265 | .name = "spi-xcomm", | ||
266 | .owner = THIS_MODULE, | ||
267 | }, | ||
268 | .id_table = spi_xcomm_ids, | ||
269 | .probe = spi_xcomm_probe, | ||
270 | .remove = __devexit_p(spi_xcomm_remove), | ||
271 | }; | ||
272 | module_i2c_driver(spi_xcomm_driver); | ||
273 | |||
274 | MODULE_LICENSE("GPL"); | ||
275 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
276 | MODULE_DESCRIPTION("Analog Devices AD-FMCOMMS1-EBZ board I2C-SPI bridge driver"); | ||
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 1041cb83d67a..84c2861d6f4d 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -53,7 +53,7 @@ modalias_show(struct device *dev, struct device_attribute *a, char *buf) | |||
53 | { | 53 | { |
54 | const struct spi_device *spi = to_spi_device(dev); | 54 | const struct spi_device *spi = to_spi_device(dev); |
55 | 55 | ||
56 | return sprintf(buf, "%s\n", spi->modalias); | 56 | return sprintf(buf, "%s%s\n", SPI_MODULE_PREFIX, spi->modalias); |
57 | } | 57 | } |
58 | 58 | ||
59 | static struct device_attribute spi_dev_attrs[] = { | 59 | static struct device_attribute spi_dev_attrs[] = { |
diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index 76dd1b199a1b..fe1d7b283cb6 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h | |||
@@ -231,6 +231,7 @@ enum ssp_chip_select { | |||
231 | struct dma_chan; | 231 | struct dma_chan; |
232 | /** | 232 | /** |
233 | * struct pl022_ssp_master - device.platform_data for SPI controller devices. | 233 | * struct pl022_ssp_master - device.platform_data for SPI controller devices. |
234 | * @bus_id: identifier for this bus | ||
234 | * @num_chipselect: chipselects are used to distinguish individual | 235 | * @num_chipselect: chipselects are used to distinguish individual |
235 | * SPI slaves, and are numbered from zero to num_chipselects - 1. | 236 | * SPI slaves, and are numbered from zero to num_chipselects - 1. |
236 | * each slave has a chipselect signal, but it's common that not | 237 | * each slave has a chipselect signal, but it's common that not |
@@ -259,19 +260,13 @@ struct pl022_ssp_controller { | |||
259 | * struct ssp_config_chip - spi_board_info.controller_data for SPI | 260 | * struct ssp_config_chip - spi_board_info.controller_data for SPI |
260 | * slave devices, copied to spi_device.controller_data. | 261 | * slave devices, copied to spi_device.controller_data. |
261 | * | 262 | * |
262 | * @lbm: used for test purpose to internally connect RX and TX | ||
263 | * @iface: Interface type(Motorola, TI, Microwire, Universal) | 263 | * @iface: Interface type(Motorola, TI, Microwire, Universal) |
264 | * @hierarchy: sets whether interface is master or slave | 264 | * @hierarchy: sets whether interface is master or slave |
265 | * @slave_tx_disable: SSPTXD is disconnected (in slave mode only) | 265 | * @slave_tx_disable: SSPTXD is disconnected (in slave mode only) |
266 | * @clk_freq: Tune freq parameters of SSP(when in master mode) | 266 | * @clk_freq: Tune freq parameters of SSP(when in master mode) |
267 | * @endian_rx: Endianess of Data in Rx FIFO | ||
268 | * @endian_tx: Endianess of Data in Tx FIFO | ||
269 | * @data_size: Width of data element(4 to 32 bits) | ||
270 | * @com_mode: communication mode: polling, Interrupt or DMA | 267 | * @com_mode: communication mode: polling, Interrupt or DMA |
271 | * @rx_lev_trig: Rx FIFO watermark level (for IT & DMA mode) | 268 | * @rx_lev_trig: Rx FIFO watermark level (for IT & DMA mode) |
272 | * @tx_lev_trig: Tx FIFO watermark level (for IT & DMA mode) | 269 | * @tx_lev_trig: Tx FIFO watermark level (for IT & DMA mode) |
273 | * @clk_phase: Motorola SPI interface Clock phase | ||
274 | * @clk_pol: Motorola SPI interface Clock polarity | ||
275 | * @ctrl_len: Microwire interface: Control length | 270 | * @ctrl_len: Microwire interface: Control length |
276 | * @wait_state: Microwire interface: Wait state | 271 | * @wait_state: Microwire interface: Wait state |
277 | * @duplex: Microwire interface: Full/Half duplex | 272 | * @duplex: Microwire interface: Full/Half duplex |
@@ -279,8 +274,6 @@ struct pl022_ssp_controller { | |||
279 | * before sampling the incoming line | 274 | * before sampling the incoming line |
280 | * @cs_control: function pointer to board-specific function to | 275 | * @cs_control: function pointer to board-specific function to |
281 | * assert/deassert I/O port to control HW generation of devices chip-select. | 276 | * assert/deassert I/O port to control HW generation of devices chip-select. |
282 | * @dma_xfer_type: Type of DMA xfer (Mem-to-periph or Periph-to-Periph) | ||
283 | * @dma_config: DMA configuration for SSP controller and peripheral | ||
284 | */ | 277 | */ |
285 | struct pl022_config_chip { | 278 | struct pl022_config_chip { |
286 | enum ssp_interface iface; | 279 | enum ssp_interface iface; |