.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * IMG SPFI controller driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2007,2008,2013 Imagination Technologies Ltd. |
---|
5 | 6 | * Copyright (C) 2014 Google, Inc. |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify it |
---|
8 | | - * under the terms and conditions of the GNU General Public License, |
---|
9 | | - * version 2, as published by the Free Software Foundation. |
---|
10 | 7 | */ |
---|
11 | 8 | |
---|
12 | 9 | #include <linux/clk.h> |
---|
13 | 10 | #include <linux/delay.h> |
---|
14 | 11 | #include <linux/dmaengine.h> |
---|
15 | | -#include <linux/gpio.h> |
---|
16 | 12 | #include <linux/interrupt.h> |
---|
17 | 13 | #include <linux/io.h> |
---|
18 | 14 | #include <linux/irq.h> |
---|
.. | .. |
---|
103 | 99 | struct dma_chan *tx_ch; |
---|
104 | 100 | bool tx_dma_busy; |
---|
105 | 101 | bool rx_dma_busy; |
---|
106 | | -}; |
---|
107 | | - |
---|
108 | | -struct img_spfi_device_data { |
---|
109 | | - bool gpio_requested; |
---|
110 | 102 | }; |
---|
111 | 103 | |
---|
112 | 104 | static inline u32 spfi_readl(struct img_spfi *spfi, u32 reg) |
---|
.. | .. |
---|
445 | 437 | return 0; |
---|
446 | 438 | } |
---|
447 | 439 | |
---|
448 | | -static int img_spfi_setup(struct spi_device *spi) |
---|
449 | | -{ |
---|
450 | | - int ret = -EINVAL; |
---|
451 | | - struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); |
---|
452 | | - |
---|
453 | | - if (!spfi_data) { |
---|
454 | | - spfi_data = kzalloc(sizeof(*spfi_data), GFP_KERNEL); |
---|
455 | | - if (!spfi_data) |
---|
456 | | - return -ENOMEM; |
---|
457 | | - spfi_data->gpio_requested = false; |
---|
458 | | - spi_set_ctldata(spi, spfi_data); |
---|
459 | | - } |
---|
460 | | - if (!spfi_data->gpio_requested) { |
---|
461 | | - ret = gpio_request_one(spi->cs_gpio, |
---|
462 | | - (spi->mode & SPI_CS_HIGH) ? |
---|
463 | | - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, |
---|
464 | | - dev_name(&spi->dev)); |
---|
465 | | - if (ret) |
---|
466 | | - dev_err(&spi->dev, "can't request chipselect gpio %d\n", |
---|
467 | | - spi->cs_gpio); |
---|
468 | | - else |
---|
469 | | - spfi_data->gpio_requested = true; |
---|
470 | | - } else { |
---|
471 | | - if (gpio_is_valid(spi->cs_gpio)) { |
---|
472 | | - int mode = ((spi->mode & SPI_CS_HIGH) ? |
---|
473 | | - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH); |
---|
474 | | - |
---|
475 | | - ret = gpio_direction_output(spi->cs_gpio, mode); |
---|
476 | | - if (ret) |
---|
477 | | - dev_err(&spi->dev, "chipselect gpio %d setup failed (%d)\n", |
---|
478 | | - spi->cs_gpio, ret); |
---|
479 | | - } |
---|
480 | | - } |
---|
481 | | - return ret; |
---|
482 | | -} |
---|
483 | | - |
---|
484 | | -static void img_spfi_cleanup(struct spi_device *spi) |
---|
485 | | -{ |
---|
486 | | - struct img_spfi_device_data *spfi_data = spi_get_ctldata(spi); |
---|
487 | | - |
---|
488 | | - if (spfi_data) { |
---|
489 | | - if (spfi_data->gpio_requested) |
---|
490 | | - gpio_free(spi->cs_gpio); |
---|
491 | | - kfree(spfi_data); |
---|
492 | | - spi_set_ctldata(spi, NULL); |
---|
493 | | - } |
---|
494 | | -} |
---|
495 | | - |
---|
496 | 440 | static void img_spfi_config(struct spi_master *master, struct spi_device *spi, |
---|
497 | 441 | struct spi_transfer *xfer) |
---|
498 | 442 | { |
---|
.. | .. |
---|
662 | 606 | master->max_speed_hz = max_speed_hz; |
---|
663 | 607 | } |
---|
664 | 608 | |
---|
665 | | - master->setup = img_spfi_setup; |
---|
666 | | - master->cleanup = img_spfi_cleanup; |
---|
667 | 609 | master->transfer_one = img_spfi_transfer_one; |
---|
668 | 610 | master->prepare_message = img_spfi_prepare; |
---|
669 | 611 | master->unprepare_message = img_spfi_unprepare; |
---|
670 | 612 | master->handle_err = img_spfi_handle_err; |
---|
| 613 | + master->use_gpio_descriptors = true; |
---|
671 | 614 | |
---|
672 | | - spfi->tx_ch = dma_request_slave_channel(spfi->dev, "tx"); |
---|
673 | | - spfi->rx_ch = dma_request_slave_channel(spfi->dev, "rx"); |
---|
| 615 | + spfi->tx_ch = dma_request_chan(spfi->dev, "tx"); |
---|
| 616 | + if (IS_ERR(spfi->tx_ch)) { |
---|
| 617 | + ret = PTR_ERR(spfi->tx_ch); |
---|
| 618 | + spfi->tx_ch = NULL; |
---|
| 619 | + if (ret == -EPROBE_DEFER) |
---|
| 620 | + goto disable_pm; |
---|
| 621 | + } |
---|
| 622 | + |
---|
| 623 | + spfi->rx_ch = dma_request_chan(spfi->dev, "rx"); |
---|
| 624 | + if (IS_ERR(spfi->rx_ch)) { |
---|
| 625 | + ret = PTR_ERR(spfi->rx_ch); |
---|
| 626 | + spfi->rx_ch = NULL; |
---|
| 627 | + if (ret == -EPROBE_DEFER) |
---|
| 628 | + goto disable_pm; |
---|
| 629 | + } |
---|
| 630 | + |
---|
674 | 631 | if (!spfi->tx_ch || !spfi->rx_ch) { |
---|
675 | 632 | if (spfi->tx_ch) |
---|
676 | 633 | dma_release_channel(spfi->tx_ch); |
---|
.. | .. |
---|
774 | 731 | int ret; |
---|
775 | 732 | |
---|
776 | 733 | ret = pm_runtime_get_sync(dev); |
---|
777 | | - if (ret) { |
---|
| 734 | + if (ret < 0) { |
---|
778 | 735 | pm_runtime_put_noidle(dev); |
---|
779 | 736 | return ret; |
---|
780 | 737 | } |
---|