root/drivers/spi/spi-dw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dw_spi_show_regs
  2. dw_spi_debugfs_init
  3. dw_spi_debugfs_remove
  4. dw_spi_debugfs_init
  5. dw_spi_debugfs_remove
  6. dw_spi_set_cs
  7. tx_max
  8. rx_max
  9. dw_writer
  10. dw_reader
  11. int_error_stop
  12. interrupt_transfer
  13. dw_spi_irq
  14. poll_transfer
  15. dw_spi_transfer_one
  16. dw_spi_handle_err
  17. dw_spi_setup
  18. dw_spi_cleanup
  19. spi_hw_init
  20. dw_spi_add_host
  21. dw_spi_remove_host
  22. dw_spi_suspend_host
  23. dw_spi_resume_host

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Designware SPI core controller driver (refer pxa2xx_spi.c)
   4  *
   5  * Copyright (c) 2009, Intel Corporation.
   6  */
   7 
   8 #include <linux/dma-mapping.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/module.h>
  11 #include <linux/highmem.h>
  12 #include <linux/delay.h>
  13 #include <linux/slab.h>
  14 #include <linux/spi/spi.h>
  15 
  16 #include "spi-dw.h"
  17 
  18 #ifdef CONFIG_DEBUG_FS
  19 #include <linux/debugfs.h>
  20 #endif
  21 
  22 /* Slave spi_dev related */
  23 struct chip_data {
  24         u8 tmode;               /* TR/TO/RO/EEPROM */
  25         u8 type;                /* SPI/SSP/MicroWire */
  26 
  27         u8 poll_mode;           /* 1 means use poll mode */
  28 
  29         u16 clk_div;            /* baud rate divider */
  30         u32 speed_hz;           /* baud rate */
  31         void (*cs_control)(u32 command);
  32 };
  33 
  34 #ifdef CONFIG_DEBUG_FS
  35 #define SPI_REGS_BUFSIZE        1024
  36 static ssize_t dw_spi_show_regs(struct file *file, char __user *user_buf,
  37                 size_t count, loff_t *ppos)
  38 {
  39         struct dw_spi *dws = file->private_data;
  40         char *buf;
  41         u32 len = 0;
  42         ssize_t ret;
  43 
  44         buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL);
  45         if (!buf)
  46                 return 0;
  47 
  48         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  49                         "%s registers:\n", dev_name(&dws->master->dev));
  50         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  51                         "=================================\n");
  52         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  53                         "CTRL0: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL0));
  54         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  55                         "CTRL1: \t\t0x%08x\n", dw_readl(dws, DW_SPI_CTRL1));
  56         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  57                         "SSIENR: \t0x%08x\n", dw_readl(dws, DW_SPI_SSIENR));
  58         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  59                         "SER: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SER));
  60         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  61                         "BAUDR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_BAUDR));
  62         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  63                         "TXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_TXFLTR));
  64         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  65                         "RXFTLR: \t0x%08x\n", dw_readl(dws, DW_SPI_RXFLTR));
  66         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  67                         "TXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_TXFLR));
  68         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  69                         "RXFLR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_RXFLR));
  70         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  71                         "SR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_SR));
  72         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  73                         "IMR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_IMR));
  74         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  75                         "ISR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_ISR));
  76         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  77                         "DMACR: \t\t0x%08x\n", dw_readl(dws, DW_SPI_DMACR));
  78         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  79                         "DMATDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMATDLR));
  80         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  81                         "DMARDLR: \t0x%08x\n", dw_readl(dws, DW_SPI_DMARDLR));
  82         len += scnprintf(buf + len, SPI_REGS_BUFSIZE - len,
  83                         "=================================\n");
  84 
  85         ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
  86         kfree(buf);
  87         return ret;
  88 }
  89 
  90 static const struct file_operations dw_spi_regs_ops = {
  91         .owner          = THIS_MODULE,
  92         .open           = simple_open,
  93         .read           = dw_spi_show_regs,
  94         .llseek         = default_llseek,
  95 };
  96 
  97 static int dw_spi_debugfs_init(struct dw_spi *dws)
  98 {
  99         char name[32];
 100 
 101         snprintf(name, 32, "dw_spi%d", dws->master->bus_num);
 102         dws->debugfs = debugfs_create_dir(name, NULL);
 103         if (!dws->debugfs)
 104                 return -ENOMEM;
 105 
 106         debugfs_create_file("registers", S_IFREG | S_IRUGO,
 107                 dws->debugfs, (void *)dws, &dw_spi_regs_ops);
 108         return 0;
 109 }
 110 
 111 static void dw_spi_debugfs_remove(struct dw_spi *dws)
 112 {
 113         debugfs_remove_recursive(dws->debugfs);
 114 }
 115 
 116 #else
 117 static inline int dw_spi_debugfs_init(struct dw_spi *dws)
 118 {
 119         return 0;
 120 }
 121 
 122 static inline void dw_spi_debugfs_remove(struct dw_spi *dws)
 123 {
 124 }
 125 #endif /* CONFIG_DEBUG_FS */
 126 
 127 void dw_spi_set_cs(struct spi_device *spi, bool enable)
 128 {
 129         struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
 130         struct chip_data *chip = spi_get_ctldata(spi);
 131         bool cs_high = !!(spi->mode & SPI_CS_HIGH);
 132 
 133         /* Chip select logic is inverted from spi_set_cs() */
 134         if (chip && chip->cs_control)
 135                 chip->cs_control(!enable);
 136 
 137         /*
 138          * DW SPI controller demands any native CS being set in order to
 139          * proceed with data transfer. So in order to activate the SPI
 140          * communications we must set a corresponding bit in the Slave
 141          * Enable register no matter whether the SPI core is configured to
 142          * support active-high or active-low CS level.
 143          */
 144         if (cs_high == enable)
 145                 dw_writel(dws, DW_SPI_SER, BIT(spi->chip_select));
 146         else if (dws->cs_override)
 147                 dw_writel(dws, DW_SPI_SER, 0);
 148 }
 149 EXPORT_SYMBOL_GPL(dw_spi_set_cs);
 150 
 151 /* Return the max entries we can fill into tx fifo */
 152 static inline u32 tx_max(struct dw_spi *dws)
 153 {
 154         u32 tx_left, tx_room, rxtx_gap;
 155 
 156         tx_left = (dws->tx_end - dws->tx) / dws->n_bytes;
 157         tx_room = dws->fifo_len - dw_readl(dws, DW_SPI_TXFLR);
 158 
 159         /*
 160          * Another concern is about the tx/rx mismatch, we
 161          * though to use (dws->fifo_len - rxflr - txflr) as
 162          * one maximum value for tx, but it doesn't cover the
 163          * data which is out of tx/rx fifo and inside the
 164          * shift registers. So a control from sw point of
 165          * view is taken.
 166          */
 167         rxtx_gap =  ((dws->rx_end - dws->rx) - (dws->tx_end - dws->tx))
 168                         / dws->n_bytes;
 169 
 170         return min3(tx_left, tx_room, (u32) (dws->fifo_len - rxtx_gap));
 171 }
 172 
 173 /* Return the max entries we should read out of rx fifo */
 174 static inline u32 rx_max(struct dw_spi *dws)
 175 {
 176         u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes;
 177 
 178         return min_t(u32, rx_left, dw_readl(dws, DW_SPI_RXFLR));
 179 }
 180 
 181 static void dw_writer(struct dw_spi *dws)
 182 {
 183         u32 max;
 184         u16 txw = 0;
 185 
 186         spin_lock(&dws->buf_lock);
 187         max = tx_max(dws);
 188         while (max--) {
 189                 /* Set the tx word if the transfer's original "tx" is not null */
 190                 if (dws->tx_end - dws->len) {
 191                         if (dws->n_bytes == 1)
 192                                 txw = *(u8 *)(dws->tx);
 193                         else
 194                                 txw = *(u16 *)(dws->tx);
 195                 }
 196                 dw_write_io_reg(dws, DW_SPI_DR, txw);
 197                 dws->tx += dws->n_bytes;
 198         }
 199         spin_unlock(&dws->buf_lock);
 200 }
 201 
 202 static void dw_reader(struct dw_spi *dws)
 203 {
 204         u32 max;
 205         u16 rxw;
 206 
 207         spin_lock(&dws->buf_lock);
 208         max = rx_max(dws);
 209         while (max--) {
 210                 rxw = dw_read_io_reg(dws, DW_SPI_DR);
 211                 /* Care rx only if the transfer's original "rx" is not null */
 212                 if (dws->rx_end - dws->len) {
 213                         if (dws->n_bytes == 1)
 214                                 *(u8 *)(dws->rx) = rxw;
 215                         else
 216                                 *(u16 *)(dws->rx) = rxw;
 217                 }
 218                 dws->rx += dws->n_bytes;
 219         }
 220         spin_unlock(&dws->buf_lock);
 221 }
 222 
 223 static void int_error_stop(struct dw_spi *dws, const char *msg)
 224 {
 225         spi_reset_chip(dws);
 226 
 227         dev_err(&dws->master->dev, "%s\n", msg);
 228         dws->master->cur_msg->status = -EIO;
 229         spi_finalize_current_transfer(dws->master);
 230 }
 231 
 232 static irqreturn_t interrupt_transfer(struct dw_spi *dws)
 233 {
 234         u16 irq_status = dw_readl(dws, DW_SPI_ISR);
 235 
 236         /* Error handling */
 237         if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) {
 238                 dw_readl(dws, DW_SPI_ICR);
 239                 int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun");
 240                 return IRQ_HANDLED;
 241         }
 242 
 243         dw_reader(dws);
 244         if (dws->rx_end == dws->rx) {
 245                 spi_mask_intr(dws, SPI_INT_TXEI);
 246                 spi_finalize_current_transfer(dws->master);
 247                 return IRQ_HANDLED;
 248         }
 249         if (irq_status & SPI_INT_TXEI) {
 250                 spi_mask_intr(dws, SPI_INT_TXEI);
 251                 dw_writer(dws);
 252                 /* Enable TX irq always, it will be disabled when RX finished */
 253                 spi_umask_intr(dws, SPI_INT_TXEI);
 254         }
 255 
 256         return IRQ_HANDLED;
 257 }
 258 
 259 static irqreturn_t dw_spi_irq(int irq, void *dev_id)
 260 {
 261         struct spi_controller *master = dev_id;
 262         struct dw_spi *dws = spi_controller_get_devdata(master);
 263         u16 irq_status = dw_readl(dws, DW_SPI_ISR) & 0x3f;
 264 
 265         if (!irq_status)
 266                 return IRQ_NONE;
 267 
 268         if (!master->cur_msg) {
 269                 spi_mask_intr(dws, SPI_INT_TXEI);
 270                 return IRQ_HANDLED;
 271         }
 272 
 273         return dws->transfer_handler(dws);
 274 }
 275 
 276 /* Must be called inside pump_transfers() */
 277 static int poll_transfer(struct dw_spi *dws)
 278 {
 279         do {
 280                 dw_writer(dws);
 281                 dw_reader(dws);
 282                 cpu_relax();
 283         } while (dws->rx_end > dws->rx);
 284 
 285         return 0;
 286 }
 287 
 288 static int dw_spi_transfer_one(struct spi_controller *master,
 289                 struct spi_device *spi, struct spi_transfer *transfer)
 290 {
 291         struct dw_spi *dws = spi_controller_get_devdata(master);
 292         struct chip_data *chip = spi_get_ctldata(spi);
 293         unsigned long flags;
 294         u8 imask = 0;
 295         u16 txlevel = 0;
 296         u32 cr0;
 297         int ret;
 298 
 299         dws->dma_mapped = 0;
 300         spin_lock_irqsave(&dws->buf_lock, flags);
 301         dws->tx = (void *)transfer->tx_buf;
 302         dws->tx_end = dws->tx + transfer->len;
 303         dws->rx = transfer->rx_buf;
 304         dws->rx_end = dws->rx + transfer->len;
 305         dws->len = transfer->len;
 306         spin_unlock_irqrestore(&dws->buf_lock, flags);
 307 
 308         /* Ensure dw->rx and dw->rx_end are visible */
 309         smp_mb();
 310 
 311         spi_enable_chip(dws, 0);
 312 
 313         /* Handle per transfer options for bpw and speed */
 314         if (transfer->speed_hz != dws->current_freq) {
 315                 if (transfer->speed_hz != chip->speed_hz) {
 316                         /* clk_div doesn't support odd number */
 317                         chip->clk_div = (DIV_ROUND_UP(dws->max_freq, transfer->speed_hz) + 1) & 0xfffe;
 318                         chip->speed_hz = transfer->speed_hz;
 319                 }
 320                 dws->current_freq = transfer->speed_hz;
 321                 spi_set_clk(dws, chip->clk_div);
 322         }
 323 
 324         dws->n_bytes = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);
 325         dws->dma_width = DIV_ROUND_UP(transfer->bits_per_word, BITS_PER_BYTE);
 326 
 327         /* Default SPI mode is SCPOL = 0, SCPH = 0 */
 328         cr0 = (transfer->bits_per_word - 1)
 329                 | (chip->type << SPI_FRF_OFFSET)
 330                 | ((((spi->mode & SPI_CPOL) ? 1 : 0) << SPI_SCOL_OFFSET) |
 331                         (((spi->mode & SPI_CPHA) ? 1 : 0) << SPI_SCPH_OFFSET) |
 332                         (((spi->mode & SPI_LOOP) ? 1 : 0) << SPI_SRL_OFFSET))
 333                 | (chip->tmode << SPI_TMOD_OFFSET);
 334 
 335         /*
 336          * Adjust transfer mode if necessary. Requires platform dependent
 337          * chipselect mechanism.
 338          */
 339         if (chip->cs_control) {
 340                 if (dws->rx && dws->tx)
 341                         chip->tmode = SPI_TMOD_TR;
 342                 else if (dws->rx)
 343                         chip->tmode = SPI_TMOD_RO;
 344                 else
 345                         chip->tmode = SPI_TMOD_TO;
 346 
 347                 cr0 &= ~SPI_TMOD_MASK;
 348                 cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
 349         }
 350 
 351         dw_writel(dws, DW_SPI_CTRL0, cr0);
 352 
 353         /* Check if current transfer is a DMA transaction */
 354         if (master->can_dma && master->can_dma(master, spi, transfer))
 355                 dws->dma_mapped = master->cur_msg_mapped;
 356 
 357         /* For poll mode just disable all interrupts */
 358         spi_mask_intr(dws, 0xff);
 359 
 360         /*
 361          * Interrupt mode
 362          * we only need set the TXEI IRQ, as TX/RX always happen syncronizely
 363          */
 364         if (dws->dma_mapped) {
 365                 ret = dws->dma_ops->dma_setup(dws, transfer);
 366                 if (ret < 0) {
 367                         spi_enable_chip(dws, 1);
 368                         return ret;
 369                 }
 370         } else if (!chip->poll_mode) {
 371                 txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes);
 372                 dw_writel(dws, DW_SPI_TXFLTR, txlevel);
 373 
 374                 /* Set the interrupt mask */
 375                 imask |= SPI_INT_TXEI | SPI_INT_TXOI |
 376                          SPI_INT_RXUI | SPI_INT_RXOI;
 377                 spi_umask_intr(dws, imask);
 378 
 379                 dws->transfer_handler = interrupt_transfer;
 380         }
 381 
 382         spi_enable_chip(dws, 1);
 383 
 384         if (dws->dma_mapped) {
 385                 ret = dws->dma_ops->dma_transfer(dws, transfer);
 386                 if (ret < 0)
 387                         return ret;
 388         }
 389 
 390         if (chip->poll_mode)
 391                 return poll_transfer(dws);
 392 
 393         return 1;
 394 }
 395 
 396 static void dw_spi_handle_err(struct spi_controller *master,
 397                 struct spi_message *msg)
 398 {
 399         struct dw_spi *dws = spi_controller_get_devdata(master);
 400 
 401         if (dws->dma_mapped)
 402                 dws->dma_ops->dma_stop(dws);
 403 
 404         spi_reset_chip(dws);
 405 }
 406 
 407 /* This may be called twice for each spi dev */
 408 static int dw_spi_setup(struct spi_device *spi)
 409 {
 410         struct dw_spi_chip *chip_info = NULL;
 411         struct chip_data *chip;
 412 
 413         /* Only alloc on first setup */
 414         chip = spi_get_ctldata(spi);
 415         if (!chip) {
 416                 chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL);
 417                 if (!chip)
 418                         return -ENOMEM;
 419                 spi_set_ctldata(spi, chip);
 420         }
 421 
 422         /*
 423          * Protocol drivers may change the chip settings, so...
 424          * if chip_info exists, use it
 425          */
 426         chip_info = spi->controller_data;
 427 
 428         /* chip_info doesn't always exist */
 429         if (chip_info) {
 430                 if (chip_info->cs_control)
 431                         chip->cs_control = chip_info->cs_control;
 432 
 433                 chip->poll_mode = chip_info->poll_mode;
 434                 chip->type = chip_info->type;
 435         }
 436 
 437         chip->tmode = SPI_TMOD_TR;
 438 
 439         return 0;
 440 }
 441 
 442 static void dw_spi_cleanup(struct spi_device *spi)
 443 {
 444         struct chip_data *chip = spi_get_ctldata(spi);
 445 
 446         kfree(chip);
 447         spi_set_ctldata(spi, NULL);
 448 }
 449 
 450 /* Restart the controller, disable all interrupts, clean rx fifo */
 451 static void spi_hw_init(struct device *dev, struct dw_spi *dws)
 452 {
 453         spi_reset_chip(dws);
 454 
 455         /*
 456          * Try to detect the FIFO depth if not set by interface driver,
 457          * the depth could be from 2 to 256 from HW spec
 458          */
 459         if (!dws->fifo_len) {
 460                 u32 fifo;
 461 
 462                 for (fifo = 1; fifo < 256; fifo++) {
 463                         dw_writel(dws, DW_SPI_TXFLTR, fifo);
 464                         if (fifo != dw_readl(dws, DW_SPI_TXFLTR))
 465                                 break;
 466                 }
 467                 dw_writel(dws, DW_SPI_TXFLTR, 0);
 468 
 469                 dws->fifo_len = (fifo == 1) ? 0 : fifo;
 470                 dev_dbg(dev, "Detected FIFO size: %u bytes\n", dws->fifo_len);
 471         }
 472 
 473         /* enable HW fixup for explicit CS deselect for Amazon's alpine chip */
 474         if (dws->cs_override)
 475                 dw_writel(dws, DW_SPI_CS_OVERRIDE, 0xF);
 476 }
 477 
 478 int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
 479 {
 480         struct spi_controller *master;
 481         int ret;
 482 
 483         BUG_ON(dws == NULL);
 484 
 485         master = spi_alloc_master(dev, 0);
 486         if (!master)
 487                 return -ENOMEM;
 488 
 489         dws->master = master;
 490         dws->type = SSI_MOTO_SPI;
 491         dws->dma_inited = 0;
 492         dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR);
 493         spin_lock_init(&dws->buf_lock);
 494 
 495         spi_controller_set_devdata(master, dws);
 496 
 497         ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev),
 498                           master);
 499         if (ret < 0) {
 500                 dev_err(dev, "can not get IRQ\n");
 501                 goto err_free_master;
 502         }
 503 
 504         master->use_gpio_descriptors = true;
 505         master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
 506         master->bits_per_word_mask =  SPI_BPW_RANGE_MASK(4, 16);
 507         master->bus_num = dws->bus_num;
 508         master->num_chipselect = dws->num_cs;
 509         master->setup = dw_spi_setup;
 510         master->cleanup = dw_spi_cleanup;
 511         master->set_cs = dw_spi_set_cs;
 512         master->transfer_one = dw_spi_transfer_one;
 513         master->handle_err = dw_spi_handle_err;
 514         master->max_speed_hz = dws->max_freq;
 515         master->dev.of_node = dev->of_node;
 516         master->dev.fwnode = dev->fwnode;
 517         master->flags = SPI_MASTER_GPIO_SS;
 518 
 519         if (dws->set_cs)
 520                 master->set_cs = dws->set_cs;
 521 
 522         /* Basic HW init */
 523         spi_hw_init(dev, dws);
 524 
 525         if (dws->dma_ops && dws->dma_ops->dma_init) {
 526                 ret = dws->dma_ops->dma_init(dws);
 527                 if (ret) {
 528                         dev_warn(dev, "DMA init failed\n");
 529                         dws->dma_inited = 0;
 530                 } else {
 531                         master->can_dma = dws->dma_ops->can_dma;
 532                 }
 533         }
 534 
 535         ret = spi_register_controller(master);
 536         if (ret) {
 537                 dev_err(&master->dev, "problem registering spi master\n");
 538                 goto err_dma_exit;
 539         }
 540 
 541         dw_spi_debugfs_init(dws);
 542         return 0;
 543 
 544 err_dma_exit:
 545         if (dws->dma_ops && dws->dma_ops->dma_exit)
 546                 dws->dma_ops->dma_exit(dws);
 547         spi_enable_chip(dws, 0);
 548         free_irq(dws->irq, master);
 549 err_free_master:
 550         spi_controller_put(master);
 551         return ret;
 552 }
 553 EXPORT_SYMBOL_GPL(dw_spi_add_host);
 554 
 555 void dw_spi_remove_host(struct dw_spi *dws)
 556 {
 557         dw_spi_debugfs_remove(dws);
 558 
 559         spi_unregister_controller(dws->master);
 560 
 561         if (dws->dma_ops && dws->dma_ops->dma_exit)
 562                 dws->dma_ops->dma_exit(dws);
 563 
 564         spi_shutdown_chip(dws);
 565 
 566         free_irq(dws->irq, dws->master);
 567 }
 568 EXPORT_SYMBOL_GPL(dw_spi_remove_host);
 569 
 570 int dw_spi_suspend_host(struct dw_spi *dws)
 571 {
 572         int ret;
 573 
 574         ret = spi_controller_suspend(dws->master);
 575         if (ret)
 576                 return ret;
 577 
 578         spi_shutdown_chip(dws);
 579         return 0;
 580 }
 581 EXPORT_SYMBOL_GPL(dw_spi_suspend_host);
 582 
 583 int dw_spi_resume_host(struct dw_spi *dws)
 584 {
 585         spi_hw_init(&dws->master->dev, dws);
 586         return spi_controller_resume(dws->master);
 587 }
 588 EXPORT_SYMBOL_GPL(dw_spi_resume_host);
 589 
 590 MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>");
 591 MODULE_DESCRIPTION("Driver for DesignWare SPI controller core");
 592 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */