aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/xilinx_spi.c
diff options
context:
space:
mode:
authorRichard Röjfors <richard.rojfors@mocean-labs.com>2009-11-13 06:28:39 -0500
committerGrant Likely <grant.likely@secretlab.ca>2009-12-08 20:48:14 -0500
commitd5af91a1faca68e9a8cc493b85aa7b194b6128aa (patch)
treee5948bf1cb4e6e2b9d20392d9542da43559c1810 /drivers/spi/xilinx_spi.c
parentb8d4e2ce60b63294e3408d1c5211b8a8dc4af095 (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/spi/xilinx_spi.c')
-rw-r--r--drivers/spi/xilinx_spi.c159
1 files changed, 39 insertions, 120 deletions
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
287static int __init xilinx_spi_of_probe(struct of_device *ofdev, 285struct 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
385free_irq: 347free_irq:
386 free_irq(xspi->irq, xspi); 348 free_irq(xspi->irq, xspi);
387unmap_io: 349unmap_io:
388 iounmap(xspi->regs); 350 iounmap(xspi->regs);
389release_mem: 351map_failed:
390 release_mem_region(r_mem->start, resource_size(r_mem)); 352 release_mem_region(mem->start, resource_size(mem));
391put_master: 353put_master:
392 spi_master_put(master); 354 spi_master_put(master);
393 return rc; 355 return NULL;
394} 356}
357EXPORT_SYMBOL(xilinx_spi_init);
395 358
396static int __devexit xilinx_spi_remove(struct of_device *ofdev) 359void 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 */
417MODULE_ALIAS("platform:" XILINX_SPI_NAME);
418
419static int __exit xilinx_spi_of_remove(struct of_device *op)
420{
421 return xilinx_spi_remove(op);
422}
423 368
424static 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
430MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
431
432static 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
444static int __init xilinx_spi_init(void)
445{
446 return of_register_platform_driver(&xilinx_spi_of_driver);
447} 371}
448module_init(xilinx_spi_init); 372EXPORT_SYMBOL(xilinx_spi_deinit);
449 373
450static void __exit xilinx_spi_exit(void)
451{
452 of_unregister_platform_driver(&xilinx_spi_of_driver);
453}
454module_exit(xilinx_spi_exit);
455MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>"); 374MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
456MODULE_DESCRIPTION("Xilinx SPI driver"); 375MODULE_DESCRIPTION("Xilinx SPI driver");
457MODULE_LICENSE("GPL"); 376MODULE_LICENSE("GPL");