diff options
Diffstat (limited to 'drivers/spi/spi-coldfire-qspi.c')
-rw-r--r-- | drivers/spi/spi-coldfire-qspi.c | 112 |
1 files changed, 46 insertions, 66 deletions
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index 28ae470397a9..e2fa628e55e7 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
@@ -77,8 +77,6 @@ struct mcfqspi { | |||
77 | struct mcfqspi_cs_control *cs_control; | 77 | struct mcfqspi_cs_control *cs_control; |
78 | 78 | ||
79 | wait_queue_head_t waitq; | 79 | wait_queue_head_t waitq; |
80 | |||
81 | struct device *dev; | ||
82 | }; | 80 | }; |
83 | 81 | ||
84 | static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) | 82 | static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val) |
@@ -135,13 +133,13 @@ static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select, | |||
135 | 133 | ||
136 | static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi) | 134 | static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi) |
137 | { | 135 | { |
138 | return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ? | 136 | return (mcfqspi->cs_control->setup) ? |
139 | mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0; | 137 | mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0; |
140 | } | 138 | } |
141 | 139 | ||
142 | static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi) | 140 | static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi) |
143 | { | 141 | { |
144 | if (mcfqspi->cs_control && mcfqspi->cs_control->teardown) | 142 | if (mcfqspi->cs_control->teardown) |
145 | mcfqspi->cs_control->teardown(mcfqspi->cs_control); | 143 | mcfqspi->cs_control->teardown(mcfqspi->cs_control); |
146 | } | 144 | } |
147 | 145 | ||
@@ -300,68 +298,45 @@ static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count, | |||
300 | } | 298 | } |
301 | } | 299 | } |
302 | 300 | ||
303 | static int mcfqspi_transfer_one_message(struct spi_master *master, | 301 | static void mcfqspi_set_cs(struct spi_device *spi, bool enable) |
304 | struct spi_message *msg) | ||
305 | { | 302 | { |
306 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 303 | struct mcfqspi *mcfqspi = spi_master_get_devdata(spi->master); |
307 | struct spi_device *spi = msg->spi; | 304 | bool cs_high = spi->mode & SPI_CS_HIGH; |
308 | struct spi_transfer *t; | ||
309 | int status = 0; | ||
310 | |||
311 | list_for_each_entry(t, &msg->transfers, transfer_list) { | ||
312 | bool cs_high = spi->mode & SPI_CS_HIGH; | ||
313 | u16 qmr = MCFQSPI_QMR_MSTR; | ||
314 | |||
315 | qmr |= t->bits_per_word << 10; | ||
316 | if (spi->mode & SPI_CPHA) | ||
317 | qmr |= MCFQSPI_QMR_CPHA; | ||
318 | if (spi->mode & SPI_CPOL) | ||
319 | qmr |= MCFQSPI_QMR_CPOL; | ||
320 | if (t->speed_hz) | ||
321 | qmr |= mcfqspi_qmr_baud(t->speed_hz); | ||
322 | else | ||
323 | qmr |= mcfqspi_qmr_baud(spi->max_speed_hz); | ||
324 | mcfqspi_wr_qmr(mcfqspi, qmr); | ||
325 | 305 | ||
306 | if (enable) | ||
326 | mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); | 307 | mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high); |
308 | else | ||
309 | mcfqspi_cs_deselect(mcfqspi, spi->chip_select, cs_high); | ||
310 | } | ||
327 | 311 | ||
328 | mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); | 312 | static int mcfqspi_transfer_one(struct spi_master *master, |
329 | if (t->bits_per_word == 8) | 313 | struct spi_device *spi, |
330 | mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, | 314 | struct spi_transfer *t) |
331 | t->rx_buf); | 315 | { |
332 | else | 316 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
333 | mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, | 317 | u16 qmr = MCFQSPI_QMR_MSTR; |
334 | t->rx_buf); | 318 | |
335 | mcfqspi_wr_qir(mcfqspi, 0); | 319 | qmr |= t->bits_per_word << 10; |
336 | 320 | if (spi->mode & SPI_CPHA) | |
337 | if (t->delay_usecs) | 321 | qmr |= MCFQSPI_QMR_CPHA; |
338 | udelay(t->delay_usecs); | 322 | if (spi->mode & SPI_CPOL) |
339 | if (t->cs_change) { | 323 | qmr |= MCFQSPI_QMR_CPOL; |
340 | if (!list_is_last(&t->transfer_list, &msg->transfers)) | 324 | qmr |= mcfqspi_qmr_baud(t->speed_hz); |
341 | mcfqspi_cs_deselect(mcfqspi, spi->chip_select, | 325 | mcfqspi_wr_qmr(mcfqspi, qmr); |
342 | cs_high); | 326 | |
343 | } else { | 327 | mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE); |
344 | if (list_is_last(&t->transfer_list, &msg->transfers)) | 328 | if (t->bits_per_word == 8) |
345 | mcfqspi_cs_deselect(mcfqspi, spi->chip_select, | 329 | mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, t->rx_buf); |
346 | cs_high); | 330 | else |
347 | } | 331 | mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf, |
348 | msg->actual_length += t->len; | 332 | t->rx_buf); |
349 | } | 333 | mcfqspi_wr_qir(mcfqspi, 0); |
350 | msg->status = status; | ||
351 | spi_finalize_current_message(master); | ||
352 | |||
353 | return status; | ||
354 | 334 | ||
335 | return 0; | ||
355 | } | 336 | } |
356 | 337 | ||
357 | static int mcfqspi_setup(struct spi_device *spi) | 338 | static int mcfqspi_setup(struct spi_device *spi) |
358 | { | 339 | { |
359 | if (spi->chip_select >= spi->master->num_chipselect) { | ||
360 | dev_dbg(&spi->dev, "%d chip select is out of range\n", | ||
361 | spi->chip_select); | ||
362 | return -EINVAL; | ||
363 | } | ||
364 | |||
365 | mcfqspi_cs_deselect(spi_master_get_devdata(spi->master), | 340 | mcfqspi_cs_deselect(spi_master_get_devdata(spi->master), |
366 | spi->chip_select, spi->mode & SPI_CS_HIGH); | 341 | spi->chip_select, spi->mode & SPI_CS_HIGH); |
367 | 342 | ||
@@ -388,6 +363,11 @@ static int mcfqspi_probe(struct platform_device *pdev) | |||
388 | return -ENOENT; | 363 | return -ENOENT; |
389 | } | 364 | } |
390 | 365 | ||
366 | if (!pdata->cs_control) { | ||
367 | dev_dbg(&pdev->dev, "pdata->cs_control is NULL\n"); | ||
368 | return -EINVAL; | ||
369 | } | ||
370 | |||
391 | master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi)); | 371 | master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi)); |
392 | if (master == NULL) { | 372 | if (master == NULL) { |
393 | dev_dbg(&pdev->dev, "spi_alloc_master failed\n"); | 373 | dev_dbg(&pdev->dev, "spi_alloc_master failed\n"); |
@@ -436,12 +416,12 @@ static int mcfqspi_probe(struct platform_device *pdev) | |||
436 | } | 416 | } |
437 | 417 | ||
438 | init_waitqueue_head(&mcfqspi->waitq); | 418 | init_waitqueue_head(&mcfqspi->waitq); |
439 | mcfqspi->dev = &pdev->dev; | ||
440 | 419 | ||
441 | master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; | 420 | master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA; |
442 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); | 421 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16); |
443 | master->setup = mcfqspi_setup; | 422 | master->setup = mcfqspi_setup; |
444 | master->transfer_one_message = mcfqspi_transfer_one_message; | 423 | master->set_cs = mcfqspi_set_cs; |
424 | master->transfer_one = mcfqspi_transfer_one; | ||
445 | master->auto_runtime_pm = true; | 425 | master->auto_runtime_pm = true; |
446 | 426 | ||
447 | platform_set_drvdata(pdev, master); | 427 | platform_set_drvdata(pdev, master); |
@@ -451,7 +431,7 @@ static int mcfqspi_probe(struct platform_device *pdev) | |||
451 | dev_dbg(&pdev->dev, "spi_register_master failed\n"); | 431 | dev_dbg(&pdev->dev, "spi_register_master failed\n"); |
452 | goto fail2; | 432 | goto fail2; |
453 | } | 433 | } |
454 | pm_runtime_enable(mcfqspi->dev); | 434 | pm_runtime_enable(&pdev->dev); |
455 | 435 | ||
456 | dev_info(&pdev->dev, "Coldfire QSPI bus driver\n"); | 436 | dev_info(&pdev->dev, "Coldfire QSPI bus driver\n"); |
457 | 437 | ||
@@ -473,9 +453,8 @@ static int mcfqspi_remove(struct platform_device *pdev) | |||
473 | { | 453 | { |
474 | struct spi_master *master = platform_get_drvdata(pdev); | 454 | struct spi_master *master = platform_get_drvdata(pdev); |
475 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 455 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
476 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
477 | 456 | ||
478 | pm_runtime_disable(mcfqspi->dev); | 457 | pm_runtime_disable(&pdev->dev); |
479 | /* disable the hardware (set the baud rate to 0) */ | 458 | /* disable the hardware (set the baud rate to 0) */ |
480 | mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); | 459 | mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); |
481 | 460 | ||
@@ -490,8 +469,11 @@ static int mcfqspi_suspend(struct device *dev) | |||
490 | { | 469 | { |
491 | struct spi_master *master = dev_get_drvdata(dev); | 470 | struct spi_master *master = dev_get_drvdata(dev); |
492 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 471 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
472 | int ret; | ||
493 | 473 | ||
494 | spi_master_suspend(master); | 474 | ret = spi_master_suspend(master); |
475 | if (ret) | ||
476 | return ret; | ||
495 | 477 | ||
496 | clk_disable(mcfqspi->clk); | 478 | clk_disable(mcfqspi->clk); |
497 | 479 | ||
@@ -503,11 +485,9 @@ static int mcfqspi_resume(struct device *dev) | |||
503 | struct spi_master *master = dev_get_drvdata(dev); | 485 | struct spi_master *master = dev_get_drvdata(dev); |
504 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 486 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
505 | 487 | ||
506 | spi_master_resume(master); | ||
507 | |||
508 | clk_enable(mcfqspi->clk); | 488 | clk_enable(mcfqspi->clk); |
509 | 489 | ||
510 | return 0; | 490 | return spi_master_resume(master); |
511 | } | 491 | } |
512 | #endif | 492 | #endif |
513 | 493 | ||