diff options
-rw-r--r-- | drivers/spi/Kconfig | 7 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi.c | 56 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi.h | 32 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi_of.c | 124 |
5 files changed, 45 insertions, 175 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 58ad21c700d3..665d03d4e022 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -353,7 +353,6 @@ config SPI_XILINX | |||
353 | tristate "Xilinx SPI controller common module" | 353 | tristate "Xilinx SPI controller common module" |
354 | depends on HAS_IOMEM && EXPERIMENTAL | 354 | depends on HAS_IOMEM && EXPERIMENTAL |
355 | select SPI_BITBANG | 355 | select SPI_BITBANG |
356 | select SPI_XILINX_OF if (XILINX_VIRTEX || MICROBLAZE) | ||
357 | help | 356 | help |
358 | This exposes the SPI controller IP from the Xilinx EDK. | 357 | This exposes the SPI controller IP from the Xilinx EDK. |
359 | 358 | ||
@@ -362,12 +361,6 @@ config SPI_XILINX | |||
362 | 361 | ||
363 | Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)" | 362 | Or for the DS570, see "XPS Serial Peripheral Interface (SPI) (v2.00b)" |
364 | 363 | ||
365 | config SPI_XILINX_OF | ||
366 | tristate "Xilinx SPI controller OF device" | ||
367 | depends on SPI_XILINX && (XILINX_VIRTEX || MICROBLAZE) | ||
368 | help | ||
369 | This is the OF driver for the SPI controller IP from the Xilinx EDK. | ||
370 | |||
371 | config SPI_NUC900 | 364 | config SPI_NUC900 |
372 | tristate "Nuvoton NUC900 series SPI" | 365 | tristate "Nuvoton NUC900 series SPI" |
373 | depends on ARCH_W90X900 && EXPERIMENTAL | 366 | depends on ARCH_W90X900 && EXPERIMENTAL |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 0d03159b5668..02dad4ae412d 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -43,7 +43,6 @@ obj-$(CONFIG_SPI_TEGRA) += spi_tegra.o | |||
43 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o | 43 | obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi_topcliff_pch.o |
44 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o | 44 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o |
45 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o | 45 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o |
46 | obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o | ||
47 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o | 46 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o |
48 | obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o | 47 | obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o |
49 | obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o | 48 | obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o |
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index bb3b520df9dd..7adaef62a991 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c | |||
@@ -16,13 +16,12 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/of.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> |
22 | #include <linux/io.h> | ||
23 | |||
24 | #include "xilinx_spi.h" | ||
25 | #include <linux/spi/xilinx_spi.h> | 23 | #include <linux/spi/xilinx_spi.h> |
24 | #include <linux/io.h> | ||
26 | 25 | ||
27 | #define XILINX_SPI_NAME "xilinx_spi" | 26 | #define XILINX_SPI_NAME "xilinx_spi" |
28 | 27 | ||
@@ -352,6 +351,15 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) | |||
352 | return IRQ_HANDLED; | 351 | return IRQ_HANDLED; |
353 | } | 352 | } |
354 | 353 | ||
354 | #ifdef CONFIG_OF | ||
355 | static const struct of_device_id xilinx_spi_of_match[] = { | ||
356 | { .compatible = "xlnx,xps-spi-2.00.a", }, | ||
357 | { .compatible = "xlnx,xps-spi-2.00.b", }, | ||
358 | {} | ||
359 | }; | ||
360 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | ||
361 | #endif | ||
362 | |||
355 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | 363 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, |
356 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) | 364 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word) |
357 | { | 365 | { |
@@ -462,13 +470,35 @@ static int __devinit xilinx_spi_probe(struct platform_device *dev) | |||
462 | { | 470 | { |
463 | struct xspi_platform_data *pdata; | 471 | struct xspi_platform_data *pdata; |
464 | struct resource *r; | 472 | struct resource *r; |
465 | int irq; | 473 | int irq, num_cs = 0, little_endian = 0, bits_per_word = 8; |
466 | struct spi_master *master; | 474 | struct spi_master *master; |
467 | u8 i; | 475 | u8 i; |
468 | 476 | ||
469 | pdata = dev->dev.platform_data; | 477 | pdata = dev->dev.platform_data; |
470 | if (!pdata) | 478 | if (pdata) { |
471 | return -ENODEV; | 479 | num_cs = pdata->num_chipselect; |
480 | little_endian = pdata->little_endian; | ||
481 | bits_per_word = pdata->bits_per_word; | ||
482 | } | ||
483 | |||
484 | #ifdef CONFIG_OF | ||
485 | if (dev->dev.of_node) { | ||
486 | const __be32 *prop; | ||
487 | int len; | ||
488 | |||
489 | /* number of slave select bits is required */ | ||
490 | prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", | ||
491 | &len); | ||
492 | if (prop && len >= sizeof(*prop)) | ||
493 | num_cs = __be32_to_cpup(prop); | ||
494 | } | ||
495 | #endif | ||
496 | |||
497 | if (!num_cs) { | ||
498 | dev_err(&dev->dev, "Missing slave select configuration data\n"); | ||
499 | return -EINVAL; | ||
500 | } | ||
501 | |||
472 | 502 | ||
473 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | 503 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); |
474 | if (!r) | 504 | if (!r) |
@@ -478,14 +508,15 @@ static int __devinit xilinx_spi_probe(struct platform_device *dev) | |||
478 | if (irq < 0) | 508 | if (irq < 0) |
479 | return -ENXIO; | 509 | return -ENXIO; |
480 | 510 | ||
481 | master = xilinx_spi_init(&dev->dev, r, irq, dev->id, | 511 | master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, |
482 | pdata->num_chipselect, pdata->little_endian, | 512 | little_endian, bits_per_word); |
483 | pdata->bits_per_word); | ||
484 | if (!master) | 513 | if (!master) |
485 | return -ENODEV; | 514 | return -ENODEV; |
486 | 515 | ||
487 | for (i = 0; i < pdata->num_devices; i++) | 516 | if (pdata) { |
488 | spi_new_device(master, pdata->devices + i); | 517 | for (i = 0; i < pdata->num_devices; i++) |
518 | spi_new_device(master, pdata->devices + i); | ||
519 | } | ||
489 | 520 | ||
490 | platform_set_drvdata(dev, master); | 521 | platform_set_drvdata(dev, master); |
491 | return 0; | 522 | return 0; |
@@ -508,6 +539,9 @@ static struct platform_driver xilinx_spi_driver = { | |||
508 | .driver = { | 539 | .driver = { |
509 | .name = XILINX_SPI_NAME, | 540 | .name = XILINX_SPI_NAME, |
510 | .owner = THIS_MODULE, | 541 | .owner = THIS_MODULE, |
542 | #ifdef CONFIG_OF | ||
543 | .of_match_table = xilinx_spi_of_match, | ||
544 | #endif | ||
511 | }, | 545 | }, |
512 | }; | 546 | }; |
513 | 547 | ||
diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h deleted file mode 100644 index d710a33f569f..000000000000 --- a/drivers/spi/xilinx_spi.h +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | /* | ||
2 | * Xilinx SPI device driver API and platform data header file | ||
3 | * | ||
4 | * Copyright (c) 2009 Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | #ifndef _XILINX_SPI_H_ | ||
21 | #define _XILINX_SPI_H_ | ||
22 | |||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/spi/spi_bitbang.h> | ||
25 | |||
26 | #define XILINX_SPI_NAME "xilinx_spi" | ||
27 | |||
28 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, | ||
29 | u32 irq, s16 bus_num, int num_cs, int little_endian, int bits_per_word); | ||
30 | |||
31 | void xilinx_spi_deinit(struct spi_master *master); | ||
32 | #endif | ||
diff --git a/drivers/spi/xilinx_spi_of.c b/drivers/spi/xilinx_spi_of.c deleted file mode 100644 index c2d8ade87a38..000000000000 --- a/drivers/spi/xilinx_spi_of.c +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | /* | ||
2 | * Xilinx SPI OF device driver | ||
3 | * | ||
4 | * Copyright (c) 2009 Intel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
18 | */ | ||
19 | |||
20 | /* Supports: | ||
21 | * Xilinx SPI devices as OF devices | ||
22 | * | ||
23 | * Inspired by xilinx_spi.c, 2002-2007 (c) MontaVista Software, Inc. | ||
24 | */ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/io.h> | ||
30 | #include <linux/slab.h> | ||
31 | |||
32 | #include <linux/of_address.h> | ||
33 | #include <linux/of_platform.h> | ||
34 | #include <linux/of_device.h> | ||
35 | #include <linux/of_spi.h> | ||
36 | |||
37 | #include <linux/spi/xilinx_spi.h> | ||
38 | #include "xilinx_spi.h" | ||
39 | |||
40 | |||
41 | static int __devinit xilinx_spi_of_probe(struct platform_device *ofdev, | ||
42 | const struct of_device_id *match) | ||
43 | { | ||
44 | struct spi_master *master; | ||
45 | struct resource r_mem; | ||
46 | struct resource r_irq; | ||
47 | int rc = 0; | ||
48 | const u32 *prop; | ||
49 | int len, num_cs; | ||
50 | |||
51 | rc = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); | ||
52 | if (rc) { | ||
53 | dev_warn(&ofdev->dev, "invalid address\n"); | ||
54 | return rc; | ||
55 | } | ||
56 | |||
57 | rc = of_irq_to_resource(ofdev->dev.of_node, 0, &r_irq); | ||
58 | if (rc == NO_IRQ) { | ||
59 | dev_warn(&ofdev->dev, "no IRQ found\n"); | ||
60 | return -ENODEV; | ||
61 | } | ||
62 | |||
63 | /* number of slave select bits is required */ | ||
64 | prop = of_get_property(ofdev->dev.of_node, "xlnx,num-ss-bits", &len); | ||
65 | if (!prop || len < sizeof(*prop)) { | ||
66 | dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | num_cs = __be32_to_cpup(prop); | ||
70 | master = xilinx_spi_init(&ofdev->dev, &r_mem, r_irq.start, -1, | ||
71 | num_cs, 0, 8); | ||
72 | if (!master) | ||
73 | return -ENODEV; | ||
74 | |||
75 | dev_set_drvdata(&ofdev->dev, master); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int __devexit xilinx_spi_remove(struct platform_device *ofdev) | ||
81 | { | ||
82 | xilinx_spi_deinit(dev_get_drvdata(&ofdev->dev)); | ||
83 | dev_set_drvdata(&ofdev->dev, 0); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int __exit xilinx_spi_of_remove(struct platform_device *op) | ||
88 | { | ||
89 | return xilinx_spi_remove(op); | ||
90 | } | ||
91 | |||
92 | static const struct of_device_id xilinx_spi_of_match[] = { | ||
93 | { .compatible = "xlnx,xps-spi-2.00.a", }, | ||
94 | { .compatible = "xlnx,xps-spi-2.00.b", }, | ||
95 | {} | ||
96 | }; | ||
97 | |||
98 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | ||
99 | |||
100 | static struct of_platform_driver xilinx_spi_of_driver = { | ||
101 | .probe = xilinx_spi_of_probe, | ||
102 | .remove = __exit_p(xilinx_spi_of_remove), | ||
103 | .driver = { | ||
104 | .name = "xilinx-xps-spi", | ||
105 | .owner = THIS_MODULE, | ||
106 | .of_match_table = xilinx_spi_of_match, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | static int __init xilinx_spi_of_init(void) | ||
111 | { | ||
112 | return of_register_platform_driver(&xilinx_spi_of_driver); | ||
113 | } | ||
114 | module_init(xilinx_spi_of_init); | ||
115 | |||
116 | static void __exit xilinx_spi_of_exit(void) | ||
117 | { | ||
118 | of_unregister_platform_driver(&xilinx_spi_of_driver); | ||
119 | } | ||
120 | module_exit(xilinx_spi_of_exit); | ||
121 | |||
122 | MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); | ||
123 | MODULE_DESCRIPTION("Xilinx SPI platform driver"); | ||
124 | MODULE_LICENSE("GPL v2"); | ||