Merge remote-tracking branches 'spi/topic/pxa2xx', 'spi/topic/s3c64xx', 'spi/topic...
authorMark Brown <broonie@kernel.org>
Fri, 26 Jan 2018 17:57:31 +0000 (17:57 +0000)
committerMark Brown <broonie@kernel.org>
Fri, 26 Jan 2018 17:57:31 +0000 (17:57 +0000)
1  2  3  4  5  6 
drivers/spi/spi-sh-msiof.c

      #include <linux/dmaengine.h>
      #include <linux/err.h>
      #include <linux/gpio.h>
+++ ++#include <linux/gpio/consumer.h>
      #include <linux/interrupt.h>
      #include <linux/io.h>
      #include <linux/kernel.h>
@@@@@@@ -55,9 -55,9 -55,9 -56,14 -55,9 -55,9 +56,14 @@@@@@@ struct sh_msiof_spi_priv 
        void *rx_dma_page;
        dma_addr_t tx_dma_addr;
        dma_addr_t rx_dma_addr;
+++ ++  unsigned short unused_ss;
+++ ++  bool native_cs_inited;
+++ ++  bool native_cs_high;
        bool slave_aborted;
      };
      
+++ ++#define MAX_SS    3       /* Maximum number of native chip selects */
+++ ++
      #define TMDR1     0x00    /* Transmit Mode Register 1 */
      #define TMDR2     0x04    /* Transmit Mode Register 2 */
      #define TMDR3     0x08    /* Transmit Mode Register 3 */
      #define MDR1_XXSTP         0x00000001 /* Transmission/Reception Stop on FIFO */
      /* TMDR1 */
      #define TMDR1_PCON         0x40000000 /* Transfer Signal Connection */
+++ ++#define TMDR1_SYNCCH_MASK 0xc000000 /* Synchronization Signal Channel Select */
+++ ++#define TMDR1_SYNCCH_SHIFT         26 /* 0=MSIOF_SYNC, 1=MSIOF_SS1, 2=MSIOF_SS2 */
      
      /* TMDR2 and RMDR2 */
      #define MDR2_BITLEN1(i)   (((i) - 1) << 24) /* Data Size (8-32 bits) */
@@@@@@@ -324,7 -324,7 -324,7 -332,7 -324,7 -324,7 +332,7 @@@@@@@ static u32 sh_msiof_spi_get_dtdl_and_sy
        return val;
      }
      
--- --static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p,
+++ ++static void sh_msiof_spi_set_pin_regs(struct sh_msiof_spi_priv *p, u32 ss,
                                      u32 cpol, u32 cpha,
                                      u32 tx_hi_z, u32 lsb_first, u32 cs_high)
      {
        tmp |= !cs_high << MDR1_SYNCAC_SHIFT;
        tmp |= lsb_first << MDR1_BITLSB_SHIFT;
        tmp |= sh_msiof_spi_get_dtdl_and_syncdl(p);
--- --  if (spi_controller_is_slave(p->master))
+++ ++  if (spi_controller_is_slave(p->master)) {
                sh_msiof_write(p, TMDR1, tmp | TMDR1_PCON);
--- --  else
--- --          sh_msiof_write(p, TMDR1, tmp | MDR1_TRMD | TMDR1_PCON);
+++ ++  } else {
+++ ++          sh_msiof_write(p, TMDR1,
+++ ++                         tmp | MDR1_TRMD | TMDR1_PCON |
+++ ++                         (ss < MAX_SS ? ss : 0) << TMDR1_SYNCCH_SHIFT);
+++ ++  }
        if (p->master->flags & SPI_MASTER_MUST_TX) {
                /* These bits are reserved if RX needs TX */
                tmp &= ~0x0000ffff;
@@@@@@@ -528,8 -528,8 -528,8 -539,7 -528,8 -528,8 +539,7 @@@@@@@ static int sh_msiof_spi_setup(struct sp
      {
        struct device_node      *np = spi->master->dev.of_node;
        struct sh_msiof_spi_priv *p = spi_master_get_devdata(spi->master);
--- --
--- --  pm_runtime_get_sync(&p->pdev->dev);
+++ ++  u32 clr, set, tmp;
      
        if (!np) {
                /*
                spi->cs_gpio = (uintptr_t)spi->controller_data;
        }
      
--- --  /* Configure pins before deasserting CS */
--- --  sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL),
--- --                            !!(spi->mode & SPI_CPHA),
--- --                            !!(spi->mode & SPI_3WIRE),
--- --                            !!(spi->mode & SPI_LSB_FIRST),
--- --                            !!(spi->mode & SPI_CS_HIGH));
+++ ++  if (gpio_is_valid(spi->cs_gpio)) {
+++ ++          gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
+++ ++          return 0;
+++ ++  }
      
--- --  if (spi->cs_gpio >= 0)
--- --          gpio_set_value(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH));
+++ ++  if (spi_controller_is_slave(p->master))
+++ ++          return 0;
      
+++ ++  if (p->native_cs_inited &&
+++ ++      (p->native_cs_high == !!(spi->mode & SPI_CS_HIGH)))
+++ ++          return 0;
      
+++ ++  /* Configure native chip select mode/polarity early */
+++ ++  clr = MDR1_SYNCMD_MASK;
+++ ++  set = MDR1_TRMD | TMDR1_PCON | MDR1_SYNCMD_SPI;
+++ ++  if (spi->mode & SPI_CS_HIGH)
+++ ++          clr |= BIT(MDR1_SYNCAC_SHIFT);
+++ ++  else
+++ ++          set |= BIT(MDR1_SYNCAC_SHIFT);
+++ ++  pm_runtime_get_sync(&p->pdev->dev);
+++ ++  tmp = sh_msiof_read(p, TMDR1) & ~clr;
+++ ++  sh_msiof_write(p, TMDR1, tmp | set);
        pm_runtime_put(&p->pdev->dev);
--- --
+++ ++  p->native_cs_high = spi->mode & SPI_CS_HIGH;
+++ ++  p->native_cs_inited = true;
        return 0;
      }
      
@@@@@@@ -560,13 -560,13 -560,13 -582,20 -560,13 -560,13 +582,20 @@@@@@@ static int sh_msiof_prepare_message(str
      {
        struct sh_msiof_spi_priv *p = spi_master_get_devdata(master);
        const struct spi_device *spi = msg->spi;
+++ ++  u32 ss, cs_high;
      
        /* Configure pins before asserting CS */
--- --  sh_msiof_spi_set_pin_regs(p, !!(spi->mode & SPI_CPOL),
+++ ++  if (gpio_is_valid(spi->cs_gpio)) {
+++ ++          ss = p->unused_ss;
+++ ++          cs_high = p->native_cs_high;
+++ ++  } else {
+++ ++          ss = spi->chip_select;
+++ ++          cs_high = !!(spi->mode & SPI_CS_HIGH);
+++ ++  }
+++ ++  sh_msiof_spi_set_pin_regs(p, ss, !!(spi->mode & SPI_CPOL),
                                  !!(spi->mode & SPI_CPHA),
                                  !!(spi->mode & SPI_3WIRE),
--- --                            !!(spi->mode & SPI_LSB_FIRST),
--- --                            !!(spi->mode & SPI_CS_HIGH));
+++ ++                            !!(spi->mode & SPI_LSB_FIRST), cs_high);
        return 0;
      }
      
@@@@@@@ -784,21 -784,11 -784,11 -813,11 -784,11 -784,11 +813,21 @@@@@@@ static int sh_msiof_dma_once(struct sh_
                goto stop_dma;
        }
      
 -----  /* wait for tx fifo to be emptied / rx fifo to be filled */
 +++++  /* wait for tx/rx DMA completion */
        ret = sh_msiof_wait_for_completion(p);
        if (ret)
                goto stop_reset;
      
 +++++  if (!rx) {
 +++++          reinit_completion(&p->done);
 +++++          sh_msiof_write(p, IER, IER_TEOFE);
 +++++
 +++++          /* wait for tx fifo to be emptied */
 +++++          ret = sh_msiof_wait_for_completion(p);
 +++++          if (ret)
 +++++                  goto stop_reset;
 +++++  }
 +++++
        /* clear status bits */
        sh_msiof_reset_str(p);
      
@@@@@@@ -922,9 -912,9 -912,9 -941,8 -912,9 -912,9 +951,8 @@@@@@@ static int sh_msiof_transfer_one(struc
      
                ret = sh_msiof_dma_once(p, tx_buf, rx_buf, l);
                if (ret == -EAGAIN) {
--- --                  pr_warn_once("%s %s: DMA not available, falling back to PIO\n",
--- --                               dev_driver_string(&p->pdev->dev),
--- --                               dev_name(&p->pdev->dev));
+++ ++                  dev_warn_once(&p->pdev->dev,
+++ ++                          "DMA not available, falling back to PIO\n");
                        break;
                }
                if (ret)
@@@@@@@ -1081,6 -1071,6 -1071,6 -1099,45 -1071,6 -1071,6 +1109,45 @@@@@@@ static struct sh_msiof_spi_info *sh_msi
      }
      #endif
      
+++ ++static int sh_msiof_get_cs_gpios(struct sh_msiof_spi_priv *p)
+++ ++{
+++ ++  struct device *dev = &p->pdev->dev;
+++ ++  unsigned int used_ss_mask = 0;
+++ ++  unsigned int cs_gpios = 0;
+++ ++  unsigned int num_cs, i;
+++ ++  int ret;
+++ ++
+++ ++  ret = gpiod_count(dev, "cs");
+++ ++  if (ret <= 0)
+++ ++          return 0;
+++ ++
+++ ++  num_cs = max_t(unsigned int, ret, p->master->num_chipselect);
+++ ++  for (i = 0; i < num_cs; i++) {
+++ ++          struct gpio_desc *gpiod;
+++ ++
+++ ++          gpiod = devm_gpiod_get_index(dev, "cs", i, GPIOD_ASIS);
+++ ++          if (!IS_ERR(gpiod)) {
+++ ++                  cs_gpios++;
+++ ++                  continue;
+++ ++          }
+++ ++
+++ ++          if (PTR_ERR(gpiod) != -ENOENT)
+++ ++                  return PTR_ERR(gpiod);
+++ ++
+++ ++          if (i >= MAX_SS) {
+++ ++                  dev_err(dev, "Invalid native chip select %d\n", i);
+++ ++                  return -EINVAL;
+++ ++          }
+++ ++          used_ss_mask |= BIT(i);
+++ ++  }
+++ ++  p->unused_ss = ffz(used_ss_mask);
+++ ++  if (cs_gpios && p->unused_ss >= MAX_SS) {
+++ ++          dev_err(dev, "No unused native chip select available\n");
+++ ++          return -EINVAL;
+++ ++  }
+++ ++  return 0;
+++ ++}
+++ ++
      static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev,
        enum dma_transfer_direction dir, unsigned int id, dma_addr_t port_addr)
      {
@@@@@@@ -1294,13 -1284,13 -1284,13 -1351,18 -1284,13 -1284,13 +1361,18 @@@@@@@ static int sh_msiof_spi_probe(struct pl
        if (p->info->rx_fifo_override)
                p->rx_fifo_size = p->info->rx_fifo_override;
      
+++ ++  /* Setup GPIO chip selects */
+++ ++  master->num_chipselect = p->info->num_chipselect;
+++ ++  ret = sh_msiof_get_cs_gpios(p);
+++ ++  if (ret)
+++ ++          goto err1;
+++ ++
        /* init master code */
        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
        master->mode_bits |= SPI_LSB_FIRST | SPI_3WIRE;
        master->flags = chipdata->master_flags;
        master->bus_num = pdev->id;
        master->dev.of_node = pdev->dev.of_node;
--- --  master->num_chipselect = p->info->num_chipselect;
        master->setup = sh_msiof_spi_setup;
        master->prepare_message = sh_msiof_prepare_message;
        master->slave_abort = sh_msiof_slave_abort;