diff options
author | Richard Röjfors <richard.rojfors@mocean-labs.com> | 2009-11-13 06:28:39 -0500 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2009-12-08 20:48:14 -0500 |
commit | d5af91a1faca68e9a8cc493b85aa7b194b6128aa (patch) | |
tree | e5948bf1cb4e6e2b9d20392d9542da43559c1810 /drivers | |
parent | b8d4e2ce60b63294e3408d1c5211b8a8dc4af095 (diff) |
xilinx_spi: Split into of driver and generic part.
This patch splits the xilinx_spi driver into a generic part and a
OF driver part.
The reason for this is to later add in a platform driver as well.
Tested-by: John Linn <John.Linn@xilinx.com>
Signed-off-by: Richard Röjfors <richard.rojfors@mocean-labs.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/Kconfig | 9 | ||||
-rw-r--r-- | drivers/spi/Makefile | 1 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi.c | 159 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi.h | 32 | ||||
-rw-r--r-- | drivers/spi/xilinx_spi_of.c | 133 |
5 files changed, 213 insertions, 121 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2a4ba1993083..f34a2d16d18f 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -244,14 +244,21 @@ config SPI_TXX9 | |||
244 | 244 | ||
245 | config SPI_XILINX | 245 | config SPI_XILINX |
246 | tristate "Xilinx SPI controller" | 246 | tristate "Xilinx SPI controller" |
247 | depends on (XILINX_VIRTEX || MICROBLAZE) && EXPERIMENTAL | 247 | depends on EXPERIMENTAL |
248 | select SPI_BITBANG | 248 | select SPI_BITBANG |
249 | select SPI_XILINX_OF if (XILINX_VIRTEX || MICROBLAZE) | ||
249 | help | 250 | help |
250 | This exposes the SPI controller IP from the Xilinx EDK. | 251 | This exposes the SPI controller IP from the Xilinx EDK. |
251 | 252 | ||
252 | See the "OPB Serial Peripheral Interface (SPI) (v1.00e)" | 253 | See the "OPB Serial Peripheral Interface (SPI) (v1.00e)" |
253 | Product Specification document (DS464) for hardware details. | 254 | Product Specification document (DS464) for hardware details. |
254 | 255 | ||
256 | config SPI_XILINX_OF | ||
257 | tristate "Xilinx SPI controller OF device" | ||
258 | depends on SPI_XILINX && (XILINX_VIRTEX || MICROBLAZE) | ||
259 | help | ||
260 | This is the OF driver for the SPI controller IP from the Xilinx EDK. | ||
261 | |||
255 | # | 262 | # |
256 | # Add new SPI master controllers in alphabetical order above this line | 263 | # Add new SPI master controllers in alphabetical order above this line |
257 | # | 264 | # |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e3f092a9afa5..01c409548044 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -32,6 +32,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o | |||
32 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o | 32 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o |
33 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o | 33 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o |
34 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o | 34 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o |
35 | obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o | ||
35 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o | 36 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o |
36 | obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o | 37 | obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o |
37 | # ... add above this line ... | 38 | # ... add above this line ... |
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 5a143b9f6361..69fa26d82ce4 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c | |||
@@ -14,16 +14,14 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #include <linux/of_platform.h> | ||
20 | #include <linux/of_device.h> | ||
21 | #include <linux/of_spi.h> | ||
22 | 17 | ||
23 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
24 | #include <linux/spi/spi_bitbang.h> | 19 | #include <linux/spi/spi_bitbang.h> |
25 | #include <linux/io.h> | 20 | #include <linux/io.h> |
26 | 21 | ||
22 | #include "xilinx_spi.h" | ||
23 | #include <linux/spi/xilinx_spi.h> | ||
24 | |||
27 | #define XILINX_SPI_NAME "xilinx_spi" | 25 | #define XILINX_SPI_NAME "xilinx_spi" |
28 | 26 | ||
29 | /* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e) | 27 | /* Register definitions as per "OPB Serial Peripheral Interface (SPI) (v1.00e) |
@@ -78,7 +76,7 @@ struct xilinx_spi { | |||
78 | /* bitbang has to be first */ | 76 | /* bitbang has to be first */ |
79 | struct spi_bitbang bitbang; | 77 | struct spi_bitbang bitbang; |
80 | struct completion done; | 78 | struct completion done; |
81 | 79 | struct resource mem; /* phys mem */ | |
82 | void __iomem *regs; /* virt. address of the control registers */ | 80 | void __iomem *regs; /* virt. address of the control registers */ |
83 | 81 | ||
84 | u32 irq; | 82 | u32 irq; |
@@ -284,40 +282,22 @@ static irqreturn_t xilinx_spi_irq(int irq, void *dev_id) | |||
284 | return IRQ_HANDLED; | 282 | return IRQ_HANDLED; |
285 | } | 283 | } |
286 | 284 | ||
287 | static int __init xilinx_spi_of_probe(struct of_device *ofdev, | 285 | struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, |
288 | const struct of_device_id *match) | 286 | u32 irq, s16 bus_num) |
289 | { | 287 | { |
290 | struct spi_master *master; | 288 | struct spi_master *master; |
291 | struct xilinx_spi *xspi; | 289 | struct xilinx_spi *xspi; |
292 | struct resource r_irq_struct; | 290 | struct xspi_platform_data *pdata = dev->platform_data; |
293 | struct resource r_mem_struct; | 291 | int ret; |
294 | |||
295 | struct resource *r_irq = &r_irq_struct; | ||
296 | struct resource *r_mem = &r_mem_struct; | ||
297 | int rc = 0; | ||
298 | const u32 *prop; | ||
299 | int len; | ||
300 | |||
301 | /* Get resources(memory, IRQ) associated with the device */ | ||
302 | master = spi_alloc_master(&ofdev->dev, sizeof(struct xilinx_spi)); | ||
303 | 292 | ||
304 | if (master == NULL) { | 293 | if (!pdata) { |
305 | return -ENOMEM; | 294 | dev_err(dev, "No platform data attached\n"); |
306 | } | 295 | return NULL; |
307 | |||
308 | dev_set_drvdata(&ofdev->dev, master); | ||
309 | |||
310 | rc = of_address_to_resource(ofdev->node, 0, r_mem); | ||
311 | if (rc) { | ||
312 | dev_warn(&ofdev->dev, "invalid address\n"); | ||
313 | goto put_master; | ||
314 | } | 296 | } |
315 | 297 | ||
316 | rc = of_irq_to_resource(ofdev->node, 0, r_irq); | 298 | master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); |
317 | if (rc == NO_IRQ) { | 299 | if (!master) |
318 | dev_warn(&ofdev->dev, "no IRQ found\n"); | 300 | return NULL; |
319 | goto put_master; | ||
320 | } | ||
321 | 301 | ||
322 | /* the spi->mode bits understood by this driver: */ | 302 | /* the spi->mode bits understood by this driver: */ |
323 | master->mode_bits = SPI_CPOL | SPI_CPHA; | 303 | master->mode_bits = SPI_CPOL | SPI_CPHA; |
@@ -330,128 +310,67 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev, | |||
330 | xspi->bitbang.master->setup = xilinx_spi_setup; | 310 | xspi->bitbang.master->setup = xilinx_spi_setup; |
331 | init_completion(&xspi->done); | 311 | init_completion(&xspi->done); |
332 | 312 | ||
333 | xspi->irq = r_irq->start; | 313 | if (!request_mem_region(mem->start, resource_size(mem), |
334 | 314 | XILINX_SPI_NAME)) | |
335 | if (!request_mem_region(r_mem->start, | ||
336 | r_mem->end - r_mem->start + 1, XILINX_SPI_NAME)) { | ||
337 | rc = -ENXIO; | ||
338 | dev_warn(&ofdev->dev, "memory request failure\n"); | ||
339 | goto put_master; | 315 | goto put_master; |
340 | } | ||
341 | 316 | ||
342 | xspi->regs = ioremap(r_mem->start, r_mem->end - r_mem->start + 1); | 317 | xspi->regs = ioremap(mem->start, resource_size(mem)); |
343 | if (xspi->regs == NULL) { | 318 | if (xspi->regs == NULL) { |
344 | rc = -ENOMEM; | 319 | dev_warn(dev, "ioremap failure\n"); |
345 | dev_warn(&ofdev->dev, "ioremap failure\n"); | 320 | goto map_failed; |
346 | goto release_mem; | ||
347 | } | 321 | } |
348 | xspi->irq = r_irq->start; | ||
349 | 322 | ||
350 | /* dynamic bus assignment */ | 323 | master->bus_num = bus_num; |
351 | master->bus_num = -1; | 324 | master->num_chipselect = pdata->num_chipselect; |
352 | 325 | ||
353 | /* number of slave select bits is required */ | 326 | xspi->mem = *mem; |
354 | prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len); | 327 | xspi->irq = irq; |
355 | if (!prop || len < sizeof(*prop)) { | ||
356 | dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); | ||
357 | goto unmap_io; | ||
358 | } | ||
359 | master->num_chipselect = *prop; | ||
360 | 328 | ||
361 | /* SPI controller initializations */ | 329 | /* SPI controller initializations */ |
362 | xspi_init_hw(xspi->regs); | 330 | xspi_init_hw(xspi->regs); |
363 | 331 | ||
364 | /* Register for SPI Interrupt */ | 332 | /* Register for SPI Interrupt */ |
365 | rc = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); | 333 | ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); |
366 | if (rc != 0) { | 334 | if (ret) |
367 | dev_warn(&ofdev->dev, "irq request failure: %d\n", xspi->irq); | ||
368 | goto unmap_io; | 335 | goto unmap_io; |
369 | } | ||
370 | 336 | ||
371 | rc = spi_bitbang_start(&xspi->bitbang); | 337 | ret = spi_bitbang_start(&xspi->bitbang); |
372 | if (rc != 0) { | 338 | if (ret) { |
373 | dev_err(&ofdev->dev, "spi_bitbang_start FAILED\n"); | 339 | dev_err(dev, "spi_bitbang_start FAILED\n"); |
374 | goto free_irq; | 340 | goto free_irq; |
375 | } | 341 | } |
376 | 342 | ||
377 | dev_info(&ofdev->dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", | 343 | dev_info(dev, "at 0x%08X mapped to 0x%08X, irq=%d\n", |
378 | (unsigned int)r_mem->start, (u32)xspi->regs, xspi->irq); | 344 | (u32)mem->start, (u32)xspi->regs, xspi->irq); |
379 | 345 | return master; | |
380 | /* Add any subnodes on the SPI bus */ | ||
381 | of_register_spi_devices(master, ofdev->node); | ||
382 | |||
383 | return rc; | ||
384 | 346 | ||
385 | free_irq: | 347 | free_irq: |
386 | free_irq(xspi->irq, xspi); | 348 | free_irq(xspi->irq, xspi); |
387 | unmap_io: | 349 | unmap_io: |
388 | iounmap(xspi->regs); | 350 | iounmap(xspi->regs); |
389 | release_mem: | 351 | map_failed: |
390 | release_mem_region(r_mem->start, resource_size(r_mem)); | 352 | release_mem_region(mem->start, resource_size(mem)); |
391 | put_master: | 353 | put_master: |
392 | spi_master_put(master); | 354 | spi_master_put(master); |
393 | return rc; | 355 | return NULL; |
394 | } | 356 | } |
357 | EXPORT_SYMBOL(xilinx_spi_init); | ||
395 | 358 | ||
396 | static int __devexit xilinx_spi_remove(struct of_device *ofdev) | 359 | void xilinx_spi_deinit(struct spi_master *master) |
397 | { | 360 | { |
398 | struct xilinx_spi *xspi; | 361 | struct xilinx_spi *xspi; |
399 | struct spi_master *master; | ||
400 | struct resource r_mem; | ||
401 | 362 | ||
402 | master = platform_get_drvdata(ofdev); | ||
403 | xspi = spi_master_get_devdata(master); | 363 | xspi = spi_master_get_devdata(master); |
404 | 364 | ||
405 | spi_bitbang_stop(&xspi->bitbang); | 365 | spi_bitbang_stop(&xspi->bitbang); |
406 | free_irq(xspi->irq, xspi); | 366 | free_irq(xspi->irq, xspi); |
407 | iounmap(xspi->regs); | 367 | iounmap(xspi->regs); |
408 | if (!of_address_to_resource(ofdev->node, 0, &r_mem)) | ||
409 | release_mem_region(r_mem.start, resource_size(&r_mem)); | ||
410 | dev_set_drvdata(&ofdev->dev, 0); | ||
411 | spi_master_put(xspi->bitbang.master); | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | /* work with hotplug and coldplug */ | ||
417 | MODULE_ALIAS("platform:" XILINX_SPI_NAME); | ||
418 | |||
419 | static int __exit xilinx_spi_of_remove(struct of_device *op) | ||
420 | { | ||
421 | return xilinx_spi_remove(op); | ||
422 | } | ||
423 | 368 | ||
424 | static struct of_device_id xilinx_spi_of_match[] = { | 369 | release_mem_region(xspi->mem.start, resource_size(&xspi->mem)); |
425 | { .compatible = "xlnx,xps-spi-2.00.a", }, | 370 | spi_master_put(xspi->bitbang.master); |
426 | { .compatible = "xlnx,xps-spi-2.00.b", }, | ||
427 | {} | ||
428 | }; | ||
429 | |||
430 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | ||
431 | |||
432 | static struct of_platform_driver xilinx_spi_of_driver = { | ||
433 | .owner = THIS_MODULE, | ||
434 | .name = "xilinx-xps-spi", | ||
435 | .match_table = xilinx_spi_of_match, | ||
436 | .probe = xilinx_spi_of_probe, | ||
437 | .remove = __exit_p(xilinx_spi_of_remove), | ||
438 | .driver = { | ||
439 | .name = "xilinx-xps-spi", | ||
440 | .owner = THIS_MODULE, | ||
441 | }, | ||
442 | }; | ||
443 | |||
444 | static int __init xilinx_spi_init(void) | ||
445 | { | ||
446 | return of_register_platform_driver(&xilinx_spi_of_driver); | ||
447 | } | 371 | } |
448 | module_init(xilinx_spi_init); | 372 | EXPORT_SYMBOL(xilinx_spi_deinit); |
449 | 373 | ||
450 | static void __exit xilinx_spi_exit(void) | ||
451 | { | ||
452 | of_unregister_platform_driver(&xilinx_spi_of_driver); | ||
453 | } | ||
454 | module_exit(xilinx_spi_exit); | ||
455 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); | 374 | MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); |
456 | MODULE_DESCRIPTION("Xilinx SPI driver"); | 375 | MODULE_DESCRIPTION("Xilinx SPI driver"); |
457 | MODULE_LICENSE("GPL"); | 376 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h new file mode 100644 index 000000000000..d211accf68d2 --- /dev/null +++ b/drivers/spi/xilinx_spi.h | |||
@@ -0,0 +1,32 @@ | |||
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); | ||
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 new file mode 100644 index 000000000000..151aa13494bd --- /dev/null +++ b/drivers/spi/xilinx_spi_of.c | |||
@@ -0,0 +1,133 @@ | |||
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 | |||
31 | #include <linux/of_platform.h> | ||
32 | #include <linux/of_device.h> | ||
33 | #include <linux/of_spi.h> | ||
34 | |||
35 | #include <linux/spi/xilinx_spi.h> | ||
36 | #include "xilinx_spi.h" | ||
37 | |||
38 | |||
39 | static int __devinit xilinx_spi_of_probe(struct of_device *ofdev, | ||
40 | const struct of_device_id *match) | ||
41 | { | ||
42 | struct spi_master *master; | ||
43 | struct xspi_platform_data *pdata; | ||
44 | struct resource r_mem; | ||
45 | struct resource r_irq; | ||
46 | int rc = 0; | ||
47 | const u32 *prop; | ||
48 | int len; | ||
49 | |||
50 | rc = of_address_to_resource(ofdev->node, 0, &r_mem); | ||
51 | if (rc) { | ||
52 | dev_warn(&ofdev->dev, "invalid address\n"); | ||
53 | return rc; | ||
54 | } | ||
55 | |||
56 | rc = of_irq_to_resource(ofdev->node, 0, &r_irq); | ||
57 | if (rc == NO_IRQ) { | ||
58 | dev_warn(&ofdev->dev, "no IRQ found\n"); | ||
59 | return -ENODEV; | ||
60 | } | ||
61 | |||
62 | ofdev->dev.platform_data = | ||
63 | kzalloc(sizeof(struct xspi_platform_data), GFP_KERNEL); | ||
64 | pdata = ofdev->dev.platform_data; | ||
65 | if (!pdata) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | /* number of slave select bits is required */ | ||
69 | prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len); | ||
70 | if (!prop || len < sizeof(*prop)) { | ||
71 | dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n"); | ||
72 | return -EINVAL; | ||
73 | } | ||
74 | pdata->num_chipselect = *prop; | ||
75 | master = xilinx_spi_init(&ofdev->dev, &r_mem, r_irq.start, -1); | ||
76 | if (!master) | ||
77 | return -ENODEV; | ||
78 | |||
79 | dev_set_drvdata(&ofdev->dev, master); | ||
80 | |||
81 | /* Add any subnodes on the SPI bus */ | ||
82 | of_register_spi_devices(master, ofdev->node); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int __devexit xilinx_spi_remove(struct of_device *ofdev) | ||
88 | { | ||
89 | xilinx_spi_deinit(dev_get_drvdata(&ofdev->dev)); | ||
90 | dev_set_drvdata(&ofdev->dev, 0); | ||
91 | kfree(ofdev->dev.platform_data); | ||
92 | ofdev->dev.platform_data = NULL; | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int __exit xilinx_spi_of_remove(struct of_device *op) | ||
97 | { | ||
98 | return xilinx_spi_remove(op); | ||
99 | } | ||
100 | |||
101 | static struct of_device_id xilinx_spi_of_match[] = { | ||
102 | { .compatible = "xlnx,xps-spi-2.00.a", }, | ||
103 | { .compatible = "xlnx,xps-spi-2.00.b", }, | ||
104 | {} | ||
105 | }; | ||
106 | |||
107 | MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); | ||
108 | |||
109 | static struct of_platform_driver xilinx_spi_of_driver = { | ||
110 | .match_table = xilinx_spi_of_match, | ||
111 | .probe = xilinx_spi_of_probe, | ||
112 | .remove = __exit_p(xilinx_spi_of_remove), | ||
113 | .driver = { | ||
114 | .name = "xilinx-xps-spi", | ||
115 | .owner = THIS_MODULE, | ||
116 | }, | ||
117 | }; | ||
118 | |||
119 | static int __init xilinx_spi_of_init(void) | ||
120 | { | ||
121 | return of_register_platform_driver(&xilinx_spi_of_driver); | ||
122 | } | ||
123 | module_init(xilinx_spi_of_init); | ||
124 | |||
125 | static void __exit xilinx_spi_of_exit(void) | ||
126 | { | ||
127 | of_unregister_platform_driver(&xilinx_spi_of_driver); | ||
128 | } | ||
129 | module_exit(xilinx_spi_of_exit); | ||
130 | |||
131 | MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>"); | ||
132 | MODULE_DESCRIPTION("Xilinx SPI platform driver"); | ||
133 | MODULE_LICENSE("GPL v2"); | ||