aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-xilinx.c
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-09-01 08:49:03 -0400
committerMark Brown <broonie@linaro.org>2013-09-01 08:49:03 -0400
commit68aa4cb3374a5f47fe1f7b31e0b5893826c05c69 (patch)
treeaa350fff2ef8ef496d46820487198e9bbfe2bf77 /drivers/spi/spi-xilinx.c
parent11c28cfc1e4f32dc6d02373a1e80d7e83584ed21 (diff)
parentb5f9a9d5113efe11a3b9dad600a6f833274da595 (diff)
Merge remote-tracking branch 'spi/topic/pdata' into spi-next
Diffstat (limited to 'drivers/spi/spi-xilinx.c')
-rw-r--r--drivers/spi/spi-xilinx.c172
1 files changed, 66 insertions, 106 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index fb56fcfdf65e..0bf1b2c457a1 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -80,10 +80,9 @@ struct xilinx_spi {
80 /* bitbang has to be first */ 80 /* bitbang has to be first */
81 struct spi_bitbang bitbang; 81 struct spi_bitbang bitbang;
82 struct completion done; 82 struct completion done;
83 struct resource mem; /* phys mem */
84 void __iomem *regs; /* virt. address of the control registers */ 83 void __iomem *regs; /* virt. address of the control registers */
85 84
86 u32 irq; 85 int irq;
87 86
88 u8 *rx_ptr; /* pointer in the Tx buffer */ 87 u8 *rx_ptr; /* pointer in the Tx buffer */
89 const u8 *tx_ptr; /* pointer in the Rx buffer */ 88 const u8 *tx_ptr; /* pointer in the Rx buffer */
@@ -340,17 +339,34 @@ static const struct of_device_id xilinx_spi_of_match[] = {
340}; 339};
341MODULE_DEVICE_TABLE(of, xilinx_spi_of_match); 340MODULE_DEVICE_TABLE(of, xilinx_spi_of_match);
342 341
343struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem, 342static int xilinx_spi_probe(struct platform_device *pdev)
344 u32 irq, s16 bus_num, int num_cs, int bits_per_word)
345{ 343{
346 struct spi_master *master;
347 struct xilinx_spi *xspi; 344 struct xilinx_spi *xspi;
348 int ret; 345 struct xspi_platform_data *pdata;
346 struct resource *res;
347 int ret, num_cs = 0, bits_per_word = 8;
348 struct spi_master *master;
349 u32 tmp; 349 u32 tmp;
350 u8 i;
351
352 pdata = dev_get_platdata(&pdev->dev);
353 if (pdata) {
354 num_cs = pdata->num_chipselect;
355 bits_per_word = pdata->bits_per_word;
356 } else {
357 of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits",
358 &num_cs);
359 }
350 360
351 master = spi_alloc_master(dev, sizeof(struct xilinx_spi)); 361 if (!num_cs) {
362 dev_err(&pdev->dev,
363 "Missing slave select configuration data\n");
364 return -EINVAL;
365 }
366
367 master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi));
352 if (!master) 368 if (!master)
353 return NULL; 369 return -ENODEV;
354 370
355 /* the spi->mode bits understood by this driver: */ 371 /* the spi->mode bits understood by this driver: */
356 master->mode_bits = SPI_CPOL | SPI_CPHA; 372 master->mode_bits = SPI_CPOL | SPI_CPHA;
@@ -362,22 +378,16 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
362 xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; 378 xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs;
363 init_completion(&xspi->done); 379 init_completion(&xspi->done);
364 380
365 if (!request_mem_region(mem->start, resource_size(mem), 381 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
366 XILINX_SPI_NAME)) 382 xspi->regs = devm_ioremap_resource(&pdev->dev, res);
383 if (IS_ERR(xspi->regs)) {
384 ret = PTR_ERR(xspi->regs);
367 goto put_master; 385 goto put_master;
368
369 xspi->regs = ioremap(mem->start, resource_size(mem));
370 if (xspi->regs == NULL) {
371 dev_warn(dev, "ioremap failure\n");
372 goto map_failed;
373 } 386 }
374 387
375 master->bus_num = bus_num; 388 master->bus_num = pdev->dev.id;
376 master->num_chipselect = num_cs; 389 master->num_chipselect = num_cs;
377 master->dev.of_node = dev->of_node; 390 master->dev.of_node = pdev->dev.of_node;
378
379 xspi->mem = *mem;
380 xspi->irq = irq;
381 391
382 /* 392 /*
383 * Detect endianess on the IP via loop bit in CR. Detection 393 * Detect endianess on the IP via loop bit in CR. Detection
@@ -407,113 +417,63 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
407 } else if (xspi->bits_per_word == 32) { 417 } else if (xspi->bits_per_word == 32) {
408 xspi->tx_fn = xspi_tx32; 418 xspi->tx_fn = xspi_tx32;
409 xspi->rx_fn = xspi_rx32; 419 xspi->rx_fn = xspi_rx32;
410 } else 420 } else {
411 goto unmap_io; 421 ret = -EINVAL;
412 422 goto put_master;
423 }
413 424
414 /* SPI controller initializations */ 425 /* SPI controller initializations */
415 xspi_init_hw(xspi); 426 xspi_init_hw(xspi);
416 427
428 xspi->irq = platform_get_irq(pdev, 0);
429 if (xspi->irq < 0) {
430 ret = xspi->irq;
431 goto put_master;
432 }
433
417 /* Register for SPI Interrupt */ 434 /* Register for SPI Interrupt */
418 ret = request_irq(xspi->irq, xilinx_spi_irq, 0, XILINX_SPI_NAME, xspi); 435 ret = devm_request_irq(&pdev->dev, xspi->irq, xilinx_spi_irq, 0,
436 dev_name(&pdev->dev), xspi);
419 if (ret) 437 if (ret)
420 goto unmap_io; 438 goto put_master;
421 439
422 ret = spi_bitbang_start(&xspi->bitbang); 440 ret = spi_bitbang_start(&xspi->bitbang);
423 if (ret) { 441 if (ret) {
424 dev_err(dev, "spi_bitbang_start FAILED\n"); 442 dev_err(&pdev->dev, "spi_bitbang_start FAILED\n");
425 goto free_irq; 443 goto put_master;
426 }
427
428 dev_info(dev, "at 0x%08llX mapped to 0x%p, irq=%d\n",
429 (unsigned long long)mem->start, xspi->regs, xspi->irq);
430 return master;
431
432free_irq:
433 free_irq(xspi->irq, xspi);
434unmap_io:
435 iounmap(xspi->regs);
436map_failed:
437 release_mem_region(mem->start, resource_size(mem));
438put_master:
439 spi_master_put(master);
440 return NULL;
441}
442EXPORT_SYMBOL(xilinx_spi_init);
443
444void xilinx_spi_deinit(struct spi_master *master)
445{
446 struct xilinx_spi *xspi;
447
448 xspi = spi_master_get_devdata(master);
449
450 spi_bitbang_stop(&xspi->bitbang);
451 free_irq(xspi->irq, xspi);
452 iounmap(xspi->regs);
453
454 release_mem_region(xspi->mem.start, resource_size(&xspi->mem));
455 spi_master_put(xspi->bitbang.master);
456}
457EXPORT_SYMBOL(xilinx_spi_deinit);
458
459static int xilinx_spi_probe(struct platform_device *dev)
460{
461 struct xspi_platform_data *pdata;
462 struct resource *r;
463 int irq, num_cs = 0, bits_per_word = 8;
464 struct spi_master *master;
465 u8 i;
466
467 pdata = dev->dev.platform_data;
468 if (pdata) {
469 num_cs = pdata->num_chipselect;
470 bits_per_word = pdata->bits_per_word;
471 }
472
473#ifdef CONFIG_OF
474 if (dev->dev.of_node) {
475 const __be32 *prop;
476 int len;
477
478 /* number of slave select bits is required */
479 prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits",
480 &len);
481 if (prop && len >= sizeof(*prop))
482 num_cs = __be32_to_cpup(prop);
483 }
484#endif
485
486 if (!num_cs) {
487 dev_err(&dev->dev, "Missing slave select configuration data\n");
488 return -EINVAL;
489 } 444 }
490 445
491 446 dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n",
492 r = platform_get_resource(dev, IORESOURCE_MEM, 0); 447 (unsigned long long)res->start, xspi->regs, xspi->irq);
493 if (!r)
494 return -ENODEV;
495
496 irq = platform_get_irq(dev, 0);
497 if (irq < 0)
498 return -ENXIO;
499
500 master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs,
501 bits_per_word);
502 if (!master)
503 return -ENODEV;
504 448
505 if (pdata) { 449 if (pdata) {
506 for (i = 0; i < pdata->num_devices; i++) 450 for (i = 0; i < pdata->num_devices; i++)
507 spi_new_device(master, pdata->devices + i); 451 spi_new_device(master, pdata->devices + i);
508 } 452 }
509 453
510 platform_set_drvdata(dev, master); 454 platform_set_drvdata(pdev, master);
511 return 0; 455 return 0;
456
457put_master:
458 spi_master_put(master);
459
460 return ret;
512} 461}
513 462
514static int xilinx_spi_remove(struct platform_device *dev) 463static int xilinx_spi_remove(struct platform_device *pdev)
515{ 464{
516 xilinx_spi_deinit(platform_get_drvdata(dev)); 465 struct spi_master *master = platform_get_drvdata(pdev);
466 struct xilinx_spi *xspi = spi_master_get_devdata(master);
467 void __iomem *regs_base = xspi->regs;
468
469 spi_bitbang_stop(&xspi->bitbang);
470
471 /* Disable all the interrupts just in case */
472 xspi->write_fn(0, regs_base + XIPIF_V123B_IIER_OFFSET);
473 /* Disable the global IPIF interrupt */
474 xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET);
475
476 spi_master_put(xspi->bitbang.master);
517 477
518 return 0; 478 return 0;
519} 479}