Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'next-spi' of git://git.secretlab.ca/git/linux-2.6

* 'next-spi' of git://git.secretlab.ca/git/linux-2.6:
spi: spi_txx9.c: use resource_size()
spi: spi_sh_sci.c: use resource_size()
spi: spi_mpc8xxx.c: use resource_size()
spi: spi_bfin5xx.c: use resource_size()
spi: atmel_spi.c: use resource_size()
spi: Add s3c64xx SPI Controller driver
atmel_spi: fix dma addr calculation for len > BUFFER_SIZE
spi_s3c24xx: add FIQ pseudo-DMA support
spi: controller driver for Designware SPI core
spidev: add proper section markers
spidev: use DECLARE_BITMAP instead of declaring the array

+2950 -33
+2
arch/arm/mach-s3c2410/include/mach/spi.h
··· 18 18 unsigned int num_cs; /* total chipselects */ 19 19 int bus_num; /* bus number to use. */ 20 20 21 + unsigned int use_fiq:1; /* use fiq */ 22 + 21 23 void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); 22 24 void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); 23 25 };
+28
drivers/spi/Kconfig
··· 216 216 help 217 217 SPI driver for Samsung S3C24XX series ARM SoCs 218 218 219 + config SPI_S3C24XX_FIQ 220 + bool "S3C24XX driver with FIQ pseudo-DMA" 221 + depends on SPI_S3C24XX 222 + select FIQ 223 + help 224 + Enable FIQ support for the S3C24XX SPI driver to provide pseudo 225 + DMA by using the fast-interrupt request framework, This allows 226 + the driver to get DMA-like performance when there are either 227 + no free DMA channels, or when doing transfers that required both 228 + TX and RX data paths. 229 + 219 230 config SPI_S3C24XX_GPIO 220 231 tristate "Samsung S3C24XX series SPI by GPIO" 221 232 depends on ARCH_S3C2410 && EXPERIMENTAL ··· 236 225 GPIO lines to provide the SPI bus. This can be used where 237 226 the inbuilt hardware cannot provide the transfer mode, or 238 227 where the board is using non hardware connected pins. 228 + 229 + config SPI_S3C64XX 230 + tristate "Samsung S3C64XX series type SPI" 231 + depends on ARCH_S3C64XX && EXPERIMENTAL 232 + select S3C64XX_DMA 233 + help 234 + SPI driver for Samsung S3C64XX and newer SoCs. 239 235 240 236 config SPI_SH_MSIOF 241 237 tristate "SuperH MSIOF SPI controller" ··· 306 288 # 307 289 # Add new SPI master controllers in alphabetical order above this line 308 290 # 291 + 292 + config SPI_DESIGNWARE 293 + bool "DesignWare SPI controller core support" 294 + depends on SPI_MASTER 295 + help 296 + general driver for SPI controller core from DesignWare 297 + 298 + config SPI_DW_PCI 299 + tristate "PCI interface driver for DW SPI core" 300 + depends on SPI_DESIGNWARE && PCI 309 301 310 302 # 311 303 # There are lots of SPI device types, with sensors and memory
+9 -1
drivers/spi/Makefile
··· 16 16 obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o 17 17 obj-$(CONFIG_SPI_AU1550) += au1550_spi.o 18 18 obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o 19 + obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o 20 + obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o 19 21 obj-$(CONFIG_SPI_GPIO) += spi_gpio.o 20 22 obj-$(CONFIG_SPI_IMX) += spi_imx.o 21 23 obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o ··· 32 30 obj-$(CONFIG_SPI_MPC8xxx) += spi_mpc8xxx.o 33 31 obj-$(CONFIG_SPI_PPC4xx) += spi_ppc4xx.o 34 32 obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o 35 - obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o 33 + obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx_hw.o 34 + obj-$(CONFIG_SPI_S3C64XX) += spi_s3c64xx.o 36 35 obj-$(CONFIG_SPI_TXX9) += spi_txx9.o 37 36 obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o 38 37 obj-$(CONFIG_SPI_XILINX_OF) += xilinx_spi_of.o ··· 42 39 obj-$(CONFIG_SPI_SH_MSIOF) += spi_sh_msiof.o 43 40 obj-$(CONFIG_SPI_STMP3XXX) += spi_stmp.o 44 41 obj-$(CONFIG_SPI_NUC900) += spi_nuc900.o 42 + 43 + # special build for s3c24xx spi driver with fiq support 44 + spi_s3c24xx_hw-y := spi_s3c24xx.o 45 + spi_s3c24xx_hw-$(CONFIG_SPI_S3C24XX_FIQ) += spi_s3c24xx_fiq.o 46 + 45 47 # ... add above this line ... 46 48 47 49 # SPI protocol drivers (device/link on bus)
+3 -3
drivers/spi/atmel_spi.c
··· 189 189 190 190 /* use scratch buffer only when rx or tx data is unspecified */ 191 191 if (xfer->rx_buf) 192 - *rx_dma = xfer->rx_dma + xfer->len - len; 192 + *rx_dma = xfer->rx_dma + xfer->len - *plen; 193 193 else { 194 194 *rx_dma = as->buffer_dma; 195 195 if (len > BUFFER_SIZE) 196 196 len = BUFFER_SIZE; 197 197 } 198 198 if (xfer->tx_buf) 199 - *tx_dma = xfer->tx_dma + xfer->len - len; 199 + *tx_dma = xfer->tx_dma + xfer->len - *plen; 200 200 else { 201 201 *tx_dma = as->buffer_dma; 202 202 if (len > BUFFER_SIZE) ··· 788 788 spin_lock_init(&as->lock); 789 789 INIT_LIST_HEAD(&as->queue); 790 790 as->pdev = pdev; 791 - as->regs = ioremap(regs->start, (regs->end - regs->start) + 1); 791 + as->regs = ioremap(regs->start, resource_size(regs)); 792 792 if (!as->regs) 793 793 goto out_free_buffer; 794 794 as->irq = irq;
+944
drivers/spi/dw_spi.c
··· 1 + /* 2 + * dw_spi.c - Designware SPI core controller driver (refer pxa2xx_spi.c) 3 + * 4 + * Copyright (c) 2009, Intel Corporation. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License along with 16 + * this program; if not, write to the Free Software Foundation, Inc., 17 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 + */ 19 + 20 + #include <linux/dma-mapping.h> 21 + #include <linux/interrupt.h> 22 + #include <linux/highmem.h> 23 + #include <linux/delay.h> 24 + 25 + #include <linux/spi/dw_spi.h> 26 + #include <linux/spi/spi.h> 27 + 28 + #ifdef CONFIG_DEBUG_FS 29 + #include <linux/debugfs.h> 30 + #endif 31 + 32 + #define START_STATE ((void *)0) 33 + #define RUNNING_STATE ((void *)1) 34 + #define DONE_STATE ((void *)2) 35 + #define ERROR_STATE ((void *)-1) 36 + 37 + #define QUEUE_RUNNING 0 38 + #define QUEUE_STOPPED 1 39 + 40 + #define MRST_SPI_DEASSERT 0 41 + #define MRST_SPI_ASSERT 1 42 + 43 + /* Slave spi_dev related */ 44 + struct chip_data { 45 + u16 cr0; 46 + u8 cs; /* chip select pin */ 47 + u8 n_bytes; /* current is a 1/2/4 byte op */ 48 + u8 tmode; /* TR/TO/RO/EEPROM */ 49 + u8 type; /* SPI/SSP/MicroWire */ 50 + 51 + u8 poll_mode; /* 1 means use poll mode */ 52 + 53 + u32 dma_width; 54 + u32 rx_threshold; 55 + u32 tx_threshold; 56 + u8 enable_dma; 57 + u8 bits_per_word; 58 + u16 clk_div; /* baud rate divider */ 59 + u32 speed_hz; /* baud rate */ 60 + int (*write)(struct dw_spi *dws); 61 + int (*read)(struct dw_spi *dws); 62 + void (*cs_control)(u32 command); 63 + }; 64 + 65 + #ifdef CONFIG_DEBUG_FS 66 + static int spi_show_regs_open(struct inode *inode, struct file *file) 67 + { 68 + file->private_data = inode->i_private; 69 + return 0; 70 + } 71 + 72 + #define SPI_REGS_BUFSIZE 1024 73 + static ssize_t spi_show_regs(struct file *file, char __user *user_buf, 74 + size_t count, loff_t *ppos) 75 + { 76 + struct dw_spi *dws; 77 + char *buf; 78 + u32 len = 0; 79 + ssize_t ret; 80 + 81 + dws = file->private_data; 82 + 83 + buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL); 84 + if (!buf) 85 + return 0; 86 + 87 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 88 + "MRST SPI0 registers:\n"); 89 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 90 + "=================================\n"); 91 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 92 + "CTRL0: \t\t0x%08x\n", dw_readl(dws, ctrl0)); 93 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 94 + "CTRL1: \t\t0x%08x\n", dw_readl(dws, ctrl1)); 95 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 96 + "SSIENR: \t0x%08x\n", dw_readl(dws, ssienr)); 97 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 98 + "SER: \t\t0x%08x\n", dw_readl(dws, ser)); 99 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 100 + "BAUDR: \t\t0x%08x\n", dw_readl(dws, baudr)); 101 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 102 + "TXFTLR: \t0x%08x\n", dw_readl(dws, txfltr)); 103 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 104 + "RXFTLR: \t0x%08x\n", dw_readl(dws, rxfltr)); 105 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 106 + "TXFLR: \t\t0x%08x\n", dw_readl(dws, txflr)); 107 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 108 + "RXFLR: \t\t0x%08x\n", dw_readl(dws, rxflr)); 109 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 110 + "SR: \t\t0x%08x\n", dw_readl(dws, sr)); 111 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 112 + "IMR: \t\t0x%08x\n", dw_readl(dws, imr)); 113 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 114 + "ISR: \t\t0x%08x\n", dw_readl(dws, isr)); 115 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 116 + "DMACR: \t\t0x%08x\n", dw_readl(dws, dmacr)); 117 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 118 + "DMATDLR: \t0x%08x\n", dw_readl(dws, dmatdlr)); 119 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 120 + "DMARDLR: \t0x%08x\n", dw_readl(dws, dmardlr)); 121 + len += snprintf(buf + len, SPI_REGS_BUFSIZE - len, 122 + "=================================\n"); 123 + 124 + ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); 125 + kfree(buf); 126 + return ret; 127 + } 128 + 129 + static const struct file_operations mrst_spi_regs_ops = { 130 + .owner = THIS_MODULE, 131 + .open = spi_show_regs_open, 132 + .read = spi_show_regs, 133 + }; 134 + 135 + static int mrst_spi_debugfs_init(struct dw_spi *dws) 136 + { 137 + dws->debugfs = debugfs_create_dir("mrst_spi", NULL); 138 + if (!dws->debugfs) 139 + return -ENOMEM; 140 + 141 + debugfs_create_file("registers", S_IFREG | S_IRUGO, 142 + dws->debugfs, (void *)dws, &mrst_spi_regs_ops); 143 + return 0; 144 + } 145 + 146 + static void mrst_spi_debugfs_remove(struct dw_spi *dws) 147 + { 148 + if (dws->debugfs) 149 + debugfs_remove_recursive(dws->debugfs); 150 + } 151 + 152 + #else 153 + static inline int mrst_spi_debugfs_init(struct dw_spi *dws) 154 + { 155 + } 156 + 157 + static inline void mrst_spi_debugfs_remove(struct dw_spi *dws) 158 + { 159 + } 160 + #endif /* CONFIG_DEBUG_FS */ 161 + 162 + static void wait_till_not_busy(struct dw_spi *dws) 163 + { 164 + unsigned long end = jiffies + usecs_to_jiffies(1000); 165 + 166 + while (time_before(jiffies, end)) { 167 + if (!(dw_readw(dws, sr) & SR_BUSY)) 168 + return; 169 + } 170 + dev_err(&dws->master->dev, 171 + "DW SPI: Stutus keeps busy for 1000us after a read/write!\n"); 172 + } 173 + 174 + static void flush(struct dw_spi *dws) 175 + { 176 + while (dw_readw(dws, sr) & SR_RF_NOT_EMPT) 177 + dw_readw(dws, dr); 178 + 179 + wait_till_not_busy(dws); 180 + } 181 + 182 + static void null_cs_control(u32 command) 183 + { 184 + } 185 + 186 + static int null_writer(struct dw_spi *dws) 187 + { 188 + u8 n_bytes = dws->n_bytes; 189 + 190 + if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) 191 + || (dws->tx == dws->tx_end)) 192 + return 0; 193 + dw_writew(dws, dr, 0); 194 + dws->tx += n_bytes; 195 + 196 + wait_till_not_busy(dws); 197 + return 1; 198 + } 199 + 200 + static int null_reader(struct dw_spi *dws) 201 + { 202 + u8 n_bytes = dws->n_bytes; 203 + 204 + while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) 205 + && (dws->rx < dws->rx_end)) { 206 + dw_readw(dws, dr); 207 + dws->rx += n_bytes; 208 + } 209 + wait_till_not_busy(dws); 210 + return dws->rx == dws->rx_end; 211 + } 212 + 213 + static int u8_writer(struct dw_spi *dws) 214 + { 215 + if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) 216 + || (dws->tx == dws->tx_end)) 217 + return 0; 218 + 219 + dw_writew(dws, dr, *(u8 *)(dws->tx)); 220 + ++dws->tx; 221 + 222 + wait_till_not_busy(dws); 223 + return 1; 224 + } 225 + 226 + static int u8_reader(struct dw_spi *dws) 227 + { 228 + while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) 229 + && (dws->rx < dws->rx_end)) { 230 + *(u8 *)(dws->rx) = dw_readw(dws, dr); 231 + ++dws->rx; 232 + } 233 + 234 + wait_till_not_busy(dws); 235 + return dws->rx == dws->rx_end; 236 + } 237 + 238 + static int u16_writer(struct dw_spi *dws) 239 + { 240 + if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL) 241 + || (dws->tx == dws->tx_end)) 242 + return 0; 243 + 244 + dw_writew(dws, dr, *(u16 *)(dws->tx)); 245 + dws->tx += 2; 246 + 247 + wait_till_not_busy(dws); 248 + return 1; 249 + } 250 + 251 + static int u16_reader(struct dw_spi *dws) 252 + { 253 + u16 temp; 254 + 255 + while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT) 256 + && (dws->rx < dws->rx_end)) { 257 + temp = dw_readw(dws, dr); 258 + *(u16 *)(dws->rx) = temp; 259 + dws->rx += 2; 260 + } 261 + 262 + wait_till_not_busy(dws); 263 + return dws->rx == dws->rx_end; 264 + } 265 + 266 + static void *next_transfer(struct dw_spi *dws) 267 + { 268 + struct spi_message *msg = dws->cur_msg; 269 + struct spi_transfer *trans = dws->cur_transfer; 270 + 271 + /* Move to next transfer */ 272 + if (trans->transfer_list.next != &msg->transfers) { 273 + dws->cur_transfer = 274 + list_entry(trans->transfer_list.next, 275 + struct spi_transfer, 276 + transfer_list); 277 + return RUNNING_STATE; 278 + } else 279 + return DONE_STATE; 280 + } 281 + 282 + /* 283 + * Note: first step is the protocol driver prepares 284 + * a dma-capable memory, and this func just need translate 285 + * the virt addr to physical 286 + */ 287 + static int map_dma_buffers(struct dw_spi *dws) 288 + { 289 + if (!dws->cur_msg->is_dma_mapped || !dws->dma_inited 290 + || !dws->cur_chip->enable_dma) 291 + return 0; 292 + 293 + if (dws->cur_transfer->tx_dma) 294 + dws->tx_dma = dws->cur_transfer->tx_dma; 295 + 296 + if (dws->cur_transfer->rx_dma) 297 + dws->rx_dma = dws->cur_transfer->rx_dma; 298 + 299 + return 1; 300 + } 301 + 302 + /* Caller already set message->status; dma and pio irqs are blocked */ 303 + static void giveback(struct dw_spi *dws) 304 + { 305 + struct spi_transfer *last_transfer; 306 + unsigned long flags; 307 + struct spi_message *msg; 308 + 309 + spin_lock_irqsave(&dws->lock, flags); 310 + msg = dws->cur_msg; 311 + dws->cur_msg = NULL; 312 + dws->cur_transfer = NULL; 313 + dws->prev_chip = dws->cur_chip; 314 + dws->cur_chip = NULL; 315 + dws->dma_mapped = 0; 316 + queue_work(dws->workqueue, &dws->pump_messages); 317 + spin_unlock_irqrestore(&dws->lock, flags); 318 + 319 + last_transfer = list_entry(msg->transfers.prev, 320 + struct spi_transfer, 321 + transfer_list); 322 + 323 + if (!last_transfer->cs_change) 324 + dws->cs_control(MRST_SPI_DEASSERT); 325 + 326 + msg->state = NULL; 327 + if (msg->complete) 328 + msg->complete(msg->context); 329 + } 330 + 331 + static void int_error_stop(struct dw_spi *dws, const char *msg) 332 + { 333 + /* Stop and reset hw */ 334 + flush(dws); 335 + spi_enable_chip(dws, 0); 336 + 337 + dev_err(&dws->master->dev, "%s\n", msg); 338 + dws->cur_msg->state = ERROR_STATE; 339 + tasklet_schedule(&dws->pump_transfers); 340 + } 341 + 342 + static void transfer_complete(struct dw_spi *dws) 343 + { 344 + /* Update total byte transfered return count actual bytes read */ 345 + dws->cur_msg->actual_length += dws->len; 346 + 347 + /* Move to next transfer */ 348 + dws->cur_msg->state = next_transfer(dws); 349 + 350 + /* Handle end of message */ 351 + if (dws->cur_msg->state == DONE_STATE) { 352 + dws->cur_msg->status = 0; 353 + giveback(dws); 354 + } else 355 + tasklet_schedule(&dws->pump_transfers); 356 + } 357 + 358 + static irqreturn_t interrupt_transfer(struct dw_spi *dws) 359 + { 360 + u16 irq_status, irq_mask = 0x3f; 361 + 362 + irq_status = dw_readw(dws, isr) & irq_mask; 363 + /* Error handling */ 364 + if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) { 365 + dw_readw(dws, txoicr); 366 + dw_readw(dws, rxoicr); 367 + dw_readw(dws, rxuicr); 368 + int_error_stop(dws, "interrupt_transfer: fifo overrun"); 369 + return IRQ_HANDLED; 370 + } 371 + 372 + /* INT comes from tx */ 373 + if (dws->tx && (irq_status & SPI_INT_TXEI)) { 374 + while (dws->tx < dws->tx_end) 375 + dws->write(dws); 376 + 377 + if (dws->tx == dws->tx_end) { 378 + spi_mask_intr(dws, SPI_INT_TXEI); 379 + transfer_complete(dws); 380 + } 381 + } 382 + 383 + /* INT comes from rx */ 384 + if (dws->rx && (irq_status & SPI_INT_RXFI)) { 385 + if (dws->read(dws)) 386 + transfer_complete(dws); 387 + } 388 + return IRQ_HANDLED; 389 + } 390 + 391 + static irqreturn_t dw_spi_irq(int irq, void *dev_id) 392 + { 393 + struct dw_spi *dws = dev_id; 394 + 395 + if (!dws->cur_msg) { 396 + spi_mask_intr(dws, SPI_INT_TXEI); 397 + /* Never fail */ 398 + return IRQ_HANDLED; 399 + } 400 + 401 + return dws->transfer_handler(dws); 402 + } 403 + 404 + /* Must be called inside pump_transfers() */ 405 + static void poll_transfer(struct dw_spi *dws) 406 + { 407 + if (dws->tx) { 408 + while (dws->write(dws)) 409 + dws->read(dws); 410 + } 411 + 412 + dws->read(dws); 413 + transfer_complete(dws); 414 + } 415 + 416 + static void dma_transfer(struct dw_spi *dws, int cs_change) 417 + { 418 + } 419 + 420 + static void pump_transfers(unsigned long data) 421 + { 422 + struct dw_spi *dws = (struct dw_spi *)data; 423 + struct spi_message *message = NULL; 424 + struct spi_transfer *transfer = NULL; 425 + struct spi_transfer *previous = NULL; 426 + struct spi_device *spi = NULL; 427 + struct chip_data *chip = NULL; 428 + u8 bits = 0; 429 + u8 imask = 0; 430 + u8 cs_change = 0; 431 + u16 clk_div = 0; 432 + u32 speed = 0; 433 + u32 cr0 = 0; 434 + 435 + /* Get current state information */ 436 + message = dws->cur_msg; 437 + transfer = dws->cur_transfer; 438 + chip = dws->cur_chip; 439 + spi = message->spi; 440 + 441 + if (message->state == ERROR_STATE) { 442 + message->status = -EIO; 443 + goto early_exit; 444 + } 445 + 446 + /* Handle end of message */ 447 + if (message->state == DONE_STATE) { 448 + message->status = 0; 449 + goto early_exit; 450 + } 451 + 452 + /* Delay if requested at end of transfer*/ 453 + if (message->state == RUNNING_STATE) { 454 + previous = list_entry(transfer->transfer_list.prev, 455 + struct spi_transfer, 456 + transfer_list); 457 + if (previous->delay_usecs) 458 + udelay(previous->delay_usecs); 459 + } 460 + 461 + dws->n_bytes = chip->n_bytes; 462 + dws->dma_width = chip->dma_width; 463 + dws->cs_control = chip->cs_control; 464 + 465 + dws->rx_dma = transfer->rx_dma; 466 + dws->tx_dma = transfer->tx_dma; 467 + dws->tx = (void *)transfer->tx_buf; 468 + dws->tx_end = dws->tx + transfer->len; 469 + dws->rx = transfer->rx_buf; 470 + dws->rx_end = dws->rx + transfer->len; 471 + dws->write = dws->tx ? chip->write : null_writer; 472 + dws->read = dws->rx ? chip->read : null_reader; 473 + dws->cs_change = transfer->cs_change; 474 + dws->len = dws->cur_transfer->len; 475 + if (chip != dws->prev_chip) 476 + cs_change = 1; 477 + 478 + cr0 = chip->cr0; 479 + 480 + /* Handle per transfer options for bpw and speed */ 481 + if (transfer->speed_hz) { 482 + speed = chip->speed_hz; 483 + 484 + if (transfer->speed_hz != speed) { 485 + speed = transfer->speed_hz; 486 + if (speed > dws->max_freq) { 487 + printk(KERN_ERR "MRST SPI0: unsupported" 488 + "freq: %dHz\n", speed); 489 + message->status = -EIO; 490 + goto early_exit; 491 + } 492 + 493 + /* clk_div doesn't support odd number */ 494 + clk_div = dws->max_freq / speed; 495 + clk_div = (clk_div >> 1) << 1; 496 + 497 + chip->speed_hz = speed; 498 + chip->clk_div = clk_div; 499 + } 500 + } 501 + if (transfer->bits_per_word) { 502 + bits = transfer->bits_per_word; 503 + 504 + switch (bits) { 505 + case 8: 506 + dws->n_bytes = 1; 507 + dws->dma_width = 1; 508 + dws->read = (dws->read != null_reader) ? 509 + u8_reader : null_reader; 510 + dws->write = (dws->write != null_writer) ? 511 + u8_writer : null_writer; 512 + break; 513 + case 16: 514 + dws->n_bytes = 2; 515 + dws->dma_width = 2; 516 + dws->read = (dws->read != null_reader) ? 517 + u16_reader : null_reader; 518 + dws->write = (dws->write != null_writer) ? 519 + u16_writer : null_writer; 520 + break; 521 + default: 522 + printk(KERN_ERR "MRST SPI0: unsupported bits:" 523 + "%db\n", bits); 524 + message->status = -EIO; 525 + goto early_exit; 526 + } 527 + 528 + cr0 = (bits - 1) 529 + | (chip->type << SPI_FRF_OFFSET) 530 + | (spi->mode << SPI_MODE_OFFSET) 531 + | (chip->tmode << SPI_TMOD_OFFSET); 532 + } 533 + message->state = RUNNING_STATE; 534 + 535 + /* Check if current transfer is a DMA transaction */ 536 + dws->dma_mapped = map_dma_buffers(dws); 537 + 538 + if (!dws->dma_mapped && !chip->poll_mode) { 539 + if (dws->rx) 540 + imask |= SPI_INT_RXFI; 541 + if (dws->tx) 542 + imask |= SPI_INT_TXEI; 543 + dws->transfer_handler = interrupt_transfer; 544 + } 545 + 546 + /* 547 + * Reprogram registers only if 548 + * 1. chip select changes 549 + * 2. clk_div is changed 550 + * 3. control value changes 551 + */ 552 + if (dw_readw(dws, ctrl0) != cr0 || cs_change || clk_div) { 553 + spi_enable_chip(dws, 0); 554 + 555 + if (dw_readw(dws, ctrl0) != cr0) 556 + dw_writew(dws, ctrl0, cr0); 557 + 558 + /* Set the interrupt mask, for poll mode just diable all int */ 559 + spi_mask_intr(dws, 0xff); 560 + if (!chip->poll_mode) 561 + spi_umask_intr(dws, imask); 562 + 563 + spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); 564 + spi_chip_sel(dws, spi->chip_select); 565 + spi_enable_chip(dws, 1); 566 + 567 + if (cs_change) 568 + dws->prev_chip = chip; 569 + } 570 + 571 + if (dws->dma_mapped) 572 + dma_transfer(dws, cs_change); 573 + 574 + if (chip->poll_mode) 575 + poll_transfer(dws); 576 + 577 + return; 578 + 579 + early_exit: 580 + giveback(dws); 581 + return; 582 + } 583 + 584 + static void pump_messages(struct work_struct *work) 585 + { 586 + struct dw_spi *dws = 587 + container_of(work, struct dw_spi, pump_messages); 588 + unsigned long flags; 589 + 590 + /* Lock queue and check for queue work */ 591 + spin_lock_irqsave(&dws->lock, flags); 592 + if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) { 593 + dws->busy = 0; 594 + spin_unlock_irqrestore(&dws->lock, flags); 595 + return; 596 + } 597 + 598 + /* Make sure we are not already running a message */ 599 + if (dws->cur_msg) { 600 + spin_unlock_irqrestore(&dws->lock, flags); 601 + return; 602 + } 603 + 604 + /* Extract head of queue */ 605 + dws->cur_msg = list_entry(dws->queue.next, struct spi_message, queue); 606 + list_del_init(&dws->cur_msg->queue); 607 + 608 + /* Initial message state*/ 609 + dws->cur_msg->state = START_STATE; 610 + dws->cur_transfer = list_entry(dws->cur_msg->transfers.next, 611 + struct spi_transfer, 612 + transfer_list); 613 + dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi); 614 + 615 + /* Mark as busy and launch transfers */ 616 + tasklet_schedule(&dws->pump_transfers); 617 + 618 + dws->busy = 1; 619 + spin_unlock_irqrestore(&dws->lock, flags); 620 + } 621 + 622 + /* spi_device use this to queue in their spi_msg */ 623 + static int dw_spi_transfer(struct spi_device *spi, struct spi_message *msg) 624 + { 625 + struct dw_spi *dws = spi_master_get_devdata(spi->master); 626 + unsigned long flags; 627 + 628 + spin_lock_irqsave(&dws->lock, flags); 629 + 630 + if (dws->run == QUEUE_STOPPED) { 631 + spin_unlock_irqrestore(&dws->lock, flags); 632 + return -ESHUTDOWN; 633 + } 634 + 635 + msg->actual_length = 0; 636 + msg->status = -EINPROGRESS; 637 + msg->state = START_STATE; 638 + 639 + list_add_tail(&msg->queue, &dws->queue); 640 + 641 + if (dws->run == QUEUE_RUNNING && !dws->busy) { 642 + 643 + if (dws->cur_transfer || dws->cur_msg) 644 + queue_work(dws->workqueue, 645 + &dws->pump_messages); 646 + else { 647 + /* If no other data transaction in air, just go */ 648 + spin_unlock_irqrestore(&dws->lock, flags); 649 + pump_messages(&dws->pump_messages); 650 + return 0; 651 + } 652 + } 653 + 654 + spin_unlock_irqrestore(&dws->lock, flags); 655 + return 0; 656 + } 657 + 658 + /* This may be called twice for each spi dev */ 659 + static int dw_spi_setup(struct spi_device *spi) 660 + { 661 + struct dw_spi_chip *chip_info = NULL; 662 + struct chip_data *chip; 663 + 664 + if (spi->bits_per_word != 8 && spi->bits_per_word != 16) 665 + return -EINVAL; 666 + 667 + /* Only alloc on first setup */ 668 + chip = spi_get_ctldata(spi); 669 + if (!chip) { 670 + chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); 671 + if (!chip) 672 + return -ENOMEM; 673 + 674 + chip->cs_control = null_cs_control; 675 + chip->enable_dma = 0; 676 + } 677 + 678 + /* 679 + * Protocol drivers may change the chip settings, so... 680 + * if chip_info exists, use it 681 + */ 682 + chip_info = spi->controller_data; 683 + 684 + /* chip_info doesn't always exist */ 685 + if (chip_info) { 686 + if (chip_info->cs_control) 687 + chip->cs_control = chip_info->cs_control; 688 + 689 + chip->poll_mode = chip_info->poll_mode; 690 + chip->type = chip_info->type; 691 + 692 + chip->rx_threshold = 0; 693 + chip->tx_threshold = 0; 694 + 695 + chip->enable_dma = chip_info->enable_dma; 696 + } 697 + 698 + if (spi->bits_per_word <= 8) { 699 + chip->n_bytes = 1; 700 + chip->dma_width = 1; 701 + chip->read = u8_reader; 702 + chip->write = u8_writer; 703 + } else if (spi->bits_per_word <= 16) { 704 + chip->n_bytes = 2; 705 + chip->dma_width = 2; 706 + chip->read = u16_reader; 707 + chip->write = u16_writer; 708 + } else { 709 + /* Never take >16b case for MRST SPIC */ 710 + dev_err(&spi->dev, "invalid wordsize\n"); 711 + return -EINVAL; 712 + } 713 + chip->bits_per_word = spi->bits_per_word; 714 + 715 + chip->speed_hz = spi->max_speed_hz; 716 + if (chip->speed_hz) 717 + chip->clk_div = 25000000 / chip->speed_hz; 718 + else 719 + chip->clk_div = 8; /* default value */ 720 + 721 + chip->tmode = 0; /* Tx & Rx */ 722 + /* Default SPI mode is SCPOL = 0, SCPH = 0 */ 723 + chip->cr0 = (chip->bits_per_word - 1) 724 + | (chip->type << SPI_FRF_OFFSET) 725 + | (spi->mode << SPI_MODE_OFFSET) 726 + | (chip->tmode << SPI_TMOD_OFFSET); 727 + 728 + spi_set_ctldata(spi, chip); 729 + return 0; 730 + } 731 + 732 + static void dw_spi_cleanup(struct spi_device *spi) 733 + { 734 + struct chip_data *chip = spi_get_ctldata(spi); 735 + kfree(chip); 736 + } 737 + 738 + static int __init init_queue(struct dw_spi *dws) 739 + { 740 + INIT_LIST_HEAD(&dws->queue); 741 + spin_lock_init(&dws->lock); 742 + 743 + dws->run = QUEUE_STOPPED; 744 + dws->busy = 0; 745 + 746 + tasklet_init(&dws->pump_transfers, 747 + pump_transfers, (unsigned long)dws); 748 + 749 + INIT_WORK(&dws->pump_messages, pump_messages); 750 + dws->workqueue = create_singlethread_workqueue( 751 + dev_name(dws->master->dev.parent)); 752 + if (dws->workqueue == NULL) 753 + return -EBUSY; 754 + 755 + return 0; 756 + } 757 + 758 + static int start_queue(struct dw_spi *dws) 759 + { 760 + unsigned long flags; 761 + 762 + spin_lock_irqsave(&dws->lock, flags); 763 + 764 + if (dws->run == QUEUE_RUNNING || dws->busy) { 765 + spin_unlock_irqrestore(&dws->lock, flags); 766 + return -EBUSY; 767 + } 768 + 769 + dws->run = QUEUE_RUNNING; 770 + dws->cur_msg = NULL; 771 + dws->cur_transfer = NULL; 772 + dws->cur_chip = NULL; 773 + dws->prev_chip = NULL; 774 + spin_unlock_irqrestore(&dws->lock, flags); 775 + 776 + queue_work(dws->workqueue, &dws->pump_messages); 777 + 778 + return 0; 779 + } 780 + 781 + static int stop_queue(struct dw_spi *dws) 782 + { 783 + unsigned long flags; 784 + unsigned limit = 50; 785 + int status = 0; 786 + 787 + spin_lock_irqsave(&dws->lock, flags); 788 + dws->run = QUEUE_STOPPED; 789 + while (!list_empty(&dws->queue) && dws->busy && limit--) { 790 + spin_unlock_irqrestore(&dws->lock, flags); 791 + msleep(10); 792 + spin_lock_irqsave(&dws->lock, flags); 793 + } 794 + 795 + if (!list_empty(&dws->queue) || dws->busy) 796 + status = -EBUSY; 797 + spin_unlock_irqrestore(&dws->lock, flags); 798 + 799 + return status; 800 + } 801 + 802 + static int destroy_queue(struct dw_spi *dws) 803 + { 804 + int status; 805 + 806 + status = stop_queue(dws); 807 + if (status != 0) 808 + return status; 809 + destroy_workqueue(dws->workqueue); 810 + return 0; 811 + } 812 + 813 + /* Restart the controller, disable all interrupts, clean rx fifo */ 814 + static void spi_hw_init(struct dw_spi *dws) 815 + { 816 + spi_enable_chip(dws, 0); 817 + spi_mask_intr(dws, 0xff); 818 + spi_enable_chip(dws, 1); 819 + flush(dws); 820 + } 821 + 822 + int __devinit dw_spi_add_host(struct dw_spi *dws) 823 + { 824 + struct spi_master *master; 825 + int ret; 826 + 827 + BUG_ON(dws == NULL); 828 + 829 + master = spi_alloc_master(dws->parent_dev, 0); 830 + if (!master) { 831 + ret = -ENOMEM; 832 + goto exit; 833 + } 834 + 835 + dws->master = master; 836 + dws->type = SSI_MOTO_SPI; 837 + dws->prev_chip = NULL; 838 + dws->dma_inited = 0; 839 + dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60); 840 + 841 + ret = request_irq(dws->irq, dw_spi_irq, 0, 842 + "dw_spi", dws); 843 + if (ret < 0) { 844 + dev_err(&master->dev, "can not get IRQ\n"); 845 + goto err_free_master; 846 + } 847 + 848 + master->mode_bits = SPI_CPOL | SPI_CPHA; 849 + master->bus_num = dws->bus_num; 850 + master->num_chipselect = dws->num_cs; 851 + master->cleanup = dw_spi_cleanup; 852 + master->setup = dw_spi_setup; 853 + master->transfer = dw_spi_transfer; 854 + 855 + dws->dma_inited = 0; 856 + 857 + /* Basic HW init */ 858 + spi_hw_init(dws); 859 + 860 + /* Initial and start queue */ 861 + ret = init_queue(dws); 862 + if (ret) { 863 + dev_err(&master->dev, "problem initializing queue\n"); 864 + goto err_diable_hw; 865 + } 866 + ret = start_queue(dws); 867 + if (ret) { 868 + dev_err(&master->dev, "problem starting queue\n"); 869 + goto err_diable_hw; 870 + } 871 + 872 + spi_master_set_devdata(master, dws); 873 + ret = spi_register_master(master); 874 + if (ret) { 875 + dev_err(&master->dev, "problem registering spi master\n"); 876 + goto err_queue_alloc; 877 + } 878 + 879 + mrst_spi_debugfs_init(dws); 880 + return 0; 881 + 882 + err_queue_alloc: 883 + destroy_queue(dws); 884 + err_diable_hw: 885 + spi_enable_chip(dws, 0); 886 + free_irq(dws->irq, dws); 887 + err_free_master: 888 + spi_master_put(master); 889 + exit: 890 + return ret; 891 + } 892 + EXPORT_SYMBOL(dw_spi_add_host); 893 + 894 + void __devexit dw_spi_remove_host(struct dw_spi *dws) 895 + { 896 + int status = 0; 897 + 898 + if (!dws) 899 + return; 900 + mrst_spi_debugfs_remove(dws); 901 + 902 + /* Remove the queue */ 903 + status = destroy_queue(dws); 904 + if (status != 0) 905 + dev_err(&dws->master->dev, "dw_spi_remove: workqueue will not " 906 + "complete, message memory not freed\n"); 907 + 908 + spi_enable_chip(dws, 0); 909 + /* Disable clk */ 910 + spi_set_clk(dws, 0); 911 + free_irq(dws->irq, dws); 912 + 913 + /* Disconnect from the SPI framework */ 914 + spi_unregister_master(dws->master); 915 + } 916 + 917 + int dw_spi_suspend_host(struct dw_spi *dws) 918 + { 919 + int ret = 0; 920 + 921 + ret = stop_queue(dws); 922 + if (ret) 923 + return ret; 924 + spi_enable_chip(dws, 0); 925 + spi_set_clk(dws, 0); 926 + return ret; 927 + } 928 + EXPORT_SYMBOL(dw_spi_suspend_host); 929 + 930 + int dw_spi_resume_host(struct dw_spi *dws) 931 + { 932 + int ret; 933 + 934 + spi_hw_init(dws); 935 + ret = start_queue(dws); 936 + if (ret) 937 + dev_err(&dws->master->dev, "fail to start queue (%d)\n", ret); 938 + return ret; 939 + } 940 + EXPORT_SYMBOL(dw_spi_resume_host); 941 + 942 + MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>"); 943 + MODULE_DESCRIPTION("Driver for DesignWare SPI controller core"); 944 + MODULE_LICENSE("GPL v2");
+169
drivers/spi/dw_spi_pci.c
··· 1 + /* 2 + * mrst_spi_pci.c - PCI interface driver for DW SPI Core 3 + * 4 + * Copyright (c) 2009, Intel Corporation. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms and conditions of the GNU General Public License, 8 + * version 2, as published by the Free Software Foundation. 9 + * 10 + * This program is distributed in the hope it will be useful, but WITHOUT 11 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 + * more details. 14 + * 15 + * You should have received a copy of the GNU General Public License along 16 + * with this program; if not, write to the Free Software Foundation, 17 + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 18 + */ 19 + 20 + #include <linux/interrupt.h> 21 + #include <linux/pci.h> 22 + #include <linux/spi/dw_spi.h> 23 + #include <linux/spi/spi.h> 24 + 25 + #define DRIVER_NAME "dw_spi_pci" 26 + 27 + struct dw_spi_pci { 28 + struct pci_dev *pdev; 29 + struct dw_spi dws; 30 + }; 31 + 32 + static int __devinit spi_pci_probe(struct pci_dev *pdev, 33 + const struct pci_device_id *ent) 34 + { 35 + struct dw_spi_pci *dwpci; 36 + struct dw_spi *dws; 37 + int pci_bar = 0; 38 + int ret; 39 + 40 + printk(KERN_INFO "DW: found PCI SPI controller(ID: %04x:%04x)\n", 41 + pdev->vendor, pdev->device); 42 + 43 + ret = pci_enable_device(pdev); 44 + if (ret) 45 + return ret; 46 + 47 + dwpci = kzalloc(sizeof(struct dw_spi_pci), GFP_KERNEL); 48 + if (!dwpci) { 49 + ret = -ENOMEM; 50 + goto err_disable; 51 + } 52 + 53 + dwpci->pdev = pdev; 54 + dws = &dwpci->dws; 55 + 56 + /* Get basic io resource and map it */ 57 + dws->paddr = pci_resource_start(pdev, pci_bar); 58 + dws->iolen = pci_resource_len(pdev, pci_bar); 59 + 60 + ret = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev)); 61 + if (ret) 62 + goto err_kfree; 63 + 64 + dws->regs = ioremap_nocache((unsigned long)dws->paddr, 65 + pci_resource_len(pdev, pci_bar)); 66 + if (!dws->regs) { 67 + ret = -ENOMEM; 68 + goto err_release_reg; 69 + } 70 + 71 + dws->parent_dev = &pdev->dev; 72 + dws->bus_num = 0; 73 + dws->num_cs = 4; 74 + dws->max_freq = 25000000; /* for Moorestwon */ 75 + dws->irq = pdev->irq; 76 + 77 + ret = dw_spi_add_host(dws); 78 + if (ret) 79 + goto err_unmap; 80 + 81 + /* PCI hook and SPI hook use the same drv data */ 82 + pci_set_drvdata(pdev, dwpci); 83 + return 0; 84 + 85 + err_unmap: 86 + iounmap(dws->regs); 87 + err_release_reg: 88 + pci_release_region(pdev, pci_bar); 89 + err_kfree: 90 + kfree(dwpci); 91 + err_disable: 92 + pci_disable_device(pdev); 93 + return ret; 94 + } 95 + 96 + static void __devexit spi_pci_remove(struct pci_dev *pdev) 97 + { 98 + struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); 99 + 100 + pci_set_drvdata(pdev, NULL); 101 + iounmap(dwpci->dws.regs); 102 + pci_release_region(pdev, 0); 103 + kfree(dwpci); 104 + pci_disable_device(pdev); 105 + } 106 + 107 + #ifdef CONFIG_PM 108 + static int spi_suspend(struct pci_dev *pdev, pm_message_t state) 109 + { 110 + struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); 111 + int ret; 112 + 113 + ret = dw_spi_suspend_host(&dwpci->dws); 114 + if (ret) 115 + return ret; 116 + pci_save_state(pdev); 117 + pci_disable_device(pdev); 118 + pci_set_power_state(pdev, pci_choose_state(pdev, state)); 119 + return ret; 120 + } 121 + 122 + static int spi_resume(struct pci_dev *pdev) 123 + { 124 + struct dw_spi_pci *dwpci = pci_get_drvdata(pdev); 125 + int ret; 126 + 127 + pci_set_power_state(pdev, PCI_D0); 128 + pci_restore_state(pdev); 129 + ret = pci_enable_device(pdev); 130 + if (ret) 131 + return ret; 132 + return dw_spi_resume_host(&dwpci->dws); 133 + } 134 + #else 135 + #define spi_suspend NULL 136 + #define spi_resume NULL 137 + #endif 138 + 139 + static const struct pci_device_id pci_ids[] __devinitdata = { 140 + /* Intel Moorestown platform SPI controller 0 */ 141 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) }, 142 + {}, 143 + }; 144 + 145 + static struct pci_driver dw_spi_driver = { 146 + .name = DRIVER_NAME, 147 + .id_table = pci_ids, 148 + .probe = spi_pci_probe, 149 + .remove = __devexit_p(spi_pci_remove), 150 + .suspend = spi_suspend, 151 + .resume = spi_resume, 152 + }; 153 + 154 + static int __init mrst_spi_init(void) 155 + { 156 + return pci_register_driver(&dw_spi_driver); 157 + } 158 + 159 + static void __exit mrst_spi_exit(void) 160 + { 161 + pci_unregister_driver(&dw_spi_driver); 162 + } 163 + 164 + module_init(mrst_spi_init); 165 + module_exit(mrst_spi_exit); 166 + 167 + MODULE_AUTHOR("Feng Tang <feng.tang@intel.com>"); 168 + MODULE_DESCRIPTION("PCI interface driver for DW SPI Core"); 169 + MODULE_LICENSE("GPL v2");
+1 -1
drivers/spi/spi_bfin5xx.c
··· 1294 1294 goto out_error_get_res; 1295 1295 } 1296 1296 1297 - drv_data->regs_base = ioremap(res->start, (res->end - res->start + 1)); 1297 + drv_data->regs_base = ioremap(res->start, resource_size(res)); 1298 1298 if (drv_data->regs_base == NULL) { 1299 1299 dev_err(dev, "Cannot map IO\n"); 1300 1300 status = -ENXIO;
+1 -1
drivers/spi/spi_mpc8xxx.c
··· 1013 1013 1014 1014 init_completion(&mpc8xxx_spi->done); 1015 1015 1016 - mpc8xxx_spi->base = ioremap(mem->start, mem->end - mem->start + 1); 1016 + mpc8xxx_spi->base = ioremap(mem->start, resource_size(mem)); 1017 1017 if (mpc8xxx_spi->base == NULL) { 1018 1018 ret = -ENOMEM; 1019 1019 goto err_ioremap;
+231 -13
drivers/spi/spi_s3c24xx.c
··· 1 1 /* linux/drivers/spi/spi_s3c24xx.c 2 2 * 3 3 * Copyright (c) 2006 Ben Dooks 4 - * Copyright (c) 2006 Simtec Electronics 4 + * Copyright 2006-2009 Simtec Electronics 5 5 * Ben Dooks <ben@simtec.co.uk> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify ··· 28 28 #include <plat/regs-spi.h> 29 29 #include <mach/spi.h> 30 30 31 + #include <plat/fiq.h> 32 + #include <asm/fiq.h> 33 + 34 + #include "spi_s3c24xx_fiq.h" 35 + 31 36 /** 32 37 * s3c24xx_spi_devstate - per device data 33 38 * @hz: Last frequency calculated for @sppre field. ··· 47 42 u8 sppre; 48 43 }; 49 44 45 + enum spi_fiq_mode { 46 + FIQ_MODE_NONE = 0, 47 + FIQ_MODE_TX = 1, 48 + FIQ_MODE_RX = 2, 49 + FIQ_MODE_TXRX = 3, 50 + }; 51 + 50 52 struct s3c24xx_spi { 51 53 /* bitbang has to be first */ 52 54 struct spi_bitbang bitbang; ··· 63 51 int irq; 64 52 int len; 65 53 int count; 54 + 55 + struct fiq_handler fiq_handler; 56 + enum spi_fiq_mode fiq_mode; 57 + unsigned char fiq_inuse; 58 + unsigned char fiq_claimed; 66 59 67 60 void (*set_cs)(struct s3c2410_spi_info *spi, 68 61 int cs, int pol); ··· 83 66 struct device *dev; 84 67 struct s3c2410_spi_info *pdata; 85 68 }; 69 + 86 70 87 71 #define SPCON_DEFAULT (S3C2410_SPCON_MSTR | S3C2410_SPCON_SMOD_INT) 88 72 #define SPPIN_DEFAULT (S3C2410_SPPIN_KEEP) ··· 145 127 } 146 128 147 129 if (spi->mode != cs->mode) { 148 - u8 spcon = SPCON_DEFAULT; 130 + u8 spcon = SPCON_DEFAULT | S3C2410_SPCON_ENSCK; 149 131 150 132 if (spi->mode & SPI_CPHA) 151 133 spcon |= S3C2410_SPCON_CPHA_FMTB; ··· 232 214 return hw->tx ? hw->tx[count] : 0; 233 215 } 234 216 217 + #ifdef CONFIG_SPI_S3C24XX_FIQ 218 + /* Support for FIQ based pseudo-DMA to improve the transfer speed. 219 + * 220 + * This code uses the assembly helper in spi_s3c24xx_spi.S which is 221 + * used by the FIQ core to move data between main memory and the peripheral 222 + * block. Since this is code running on the processor, there is no problem 223 + * with cache coherency of the buffers, so we can use any buffer we like. 224 + */ 225 + 226 + /** 227 + * struct spi_fiq_code - FIQ code and header 228 + * @length: The length of the code fragment, excluding this header. 229 + * @ack_offset: The offset from @data to the word to place the IRQ ACK bit at. 230 + * @data: The code itself to install as a FIQ handler. 231 + */ 232 + struct spi_fiq_code { 233 + u32 length; 234 + u32 ack_offset; 235 + u8 data[0]; 236 + }; 237 + 238 + extern struct spi_fiq_code s3c24xx_spi_fiq_txrx; 239 + extern struct spi_fiq_code s3c24xx_spi_fiq_tx; 240 + extern struct spi_fiq_code s3c24xx_spi_fiq_rx; 241 + 242 + /** 243 + * ack_bit - turn IRQ into IRQ acknowledgement bit 244 + * @irq: The interrupt number 245 + * 246 + * Returns the bit to write to the interrupt acknowledge register. 247 + */ 248 + static inline u32 ack_bit(unsigned int irq) 249 + { 250 + return 1 << (irq - IRQ_EINT0); 251 + } 252 + 253 + /** 254 + * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer 255 + * @hw: The hardware state. 256 + * 257 + * Claim the FIQ handler (only one can be active at any one time) and 258 + * then setup the correct transfer code for this transfer. 259 + * 260 + * This call updates all the necessary state information if sucessful, 261 + * so the caller does not need to do anything more than start the transfer 262 + * as normal, since the IRQ will have been re-routed to the FIQ handler. 263 + */ 264 + void s3c24xx_spi_tryfiq(struct s3c24xx_spi *hw) 265 + { 266 + struct pt_regs regs; 267 + enum spi_fiq_mode mode; 268 + struct spi_fiq_code *code; 269 + int ret; 270 + 271 + if (!hw->fiq_claimed) { 272 + /* try and claim fiq if we haven't got it, and if not 273 + * then return and simply use another transfer method */ 274 + 275 + ret = claim_fiq(&hw->fiq_handler); 276 + if (ret) 277 + return; 278 + } 279 + 280 + if (hw->tx && !hw->rx) 281 + mode = FIQ_MODE_TX; 282 + else if (hw->rx && !hw->tx) 283 + mode = FIQ_MODE_RX; 284 + else 285 + mode = FIQ_MODE_TXRX; 286 + 287 + regs.uregs[fiq_rspi] = (long)hw->regs; 288 + regs.uregs[fiq_rrx] = (long)hw->rx; 289 + regs.uregs[fiq_rtx] = (long)hw->tx + 1; 290 + regs.uregs[fiq_rcount] = hw->len - 1; 291 + regs.uregs[fiq_rirq] = (long)S3C24XX_VA_IRQ; 292 + 293 + set_fiq_regs(&regs); 294 + 295 + if (hw->fiq_mode != mode) { 296 + u32 *ack_ptr; 297 + 298 + hw->fiq_mode = mode; 299 + 300 + switch (mode) { 301 + case FIQ_MODE_TX: 302 + code = &s3c24xx_spi_fiq_tx; 303 + break; 304 + case FIQ_MODE_RX: 305 + code = &s3c24xx_spi_fiq_rx; 306 + break; 307 + case FIQ_MODE_TXRX: 308 + code = &s3c24xx_spi_fiq_txrx; 309 + break; 310 + default: 311 + code = NULL; 312 + } 313 + 314 + BUG_ON(!code); 315 + 316 + ack_ptr = (u32 *)&code->data[code->ack_offset]; 317 + *ack_ptr = ack_bit(hw->irq); 318 + 319 + set_fiq_handler(&code->data, code->length); 320 + } 321 + 322 + s3c24xx_set_fiq(hw->irq, true); 323 + 324 + hw->fiq_mode = mode; 325 + hw->fiq_inuse = 1; 326 + } 327 + 328 + /** 329 + * s3c24xx_spi_fiqop - FIQ core code callback 330 + * @pw: Data registered with the handler 331 + * @release: Whether this is a release or a return. 332 + * 333 + * Called by the FIQ code when another module wants to use the FIQ, so 334 + * return whether we are currently using this or not and then update our 335 + * internal state. 336 + */ 337 + static int s3c24xx_spi_fiqop(void *pw, int release) 338 + { 339 + struct s3c24xx_spi *hw = pw; 340 + int ret = 0; 341 + 342 + if (release) { 343 + if (hw->fiq_inuse) 344 + ret = -EBUSY; 345 + 346 + /* note, we do not need to unroute the FIQ, as the FIQ 347 + * vector code de-routes it to signal the end of transfer */ 348 + 349 + hw->fiq_mode = FIQ_MODE_NONE; 350 + hw->fiq_claimed = 0; 351 + } else { 352 + hw->fiq_claimed = 1; 353 + } 354 + 355 + return ret; 356 + } 357 + 358 + /** 359 + * s3c24xx_spi_initfiq - setup the information for the FIQ core 360 + * @hw: The hardware state. 361 + * 362 + * Setup the fiq_handler block to pass to the FIQ core. 363 + */ 364 + static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *hw) 365 + { 366 + hw->fiq_handler.dev_id = hw; 367 + hw->fiq_handler.name = dev_name(hw->dev); 368 + hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop; 369 + } 370 + 371 + /** 372 + * s3c24xx_spi_usefiq - return if we should be using FIQ. 373 + * @hw: The hardware state. 374 + * 375 + * Return true if the platform data specifies whether this channel is 376 + * allowed to use the FIQ. 377 + */ 378 + static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *hw) 379 + { 380 + return hw->pdata->use_fiq; 381 + } 382 + 383 + /** 384 + * s3c24xx_spi_usingfiq - return if channel is using FIQ 385 + * @spi: The hardware state. 386 + * 387 + * Return whether the channel is currently using the FIQ (separate from 388 + * whether the FIQ is claimed). 389 + */ 390 + static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *spi) 391 + { 392 + return spi->fiq_inuse; 393 + } 394 + #else 395 + 396 + static inline void s3c24xx_spi_initfiq(struct s3c24xx_spi *s) { } 397 + static inline void s3c24xx_spi_tryfiq(struct s3c24xx_spi *s) { } 398 + static inline bool s3c24xx_spi_usefiq(struct s3c24xx_spi *s) { return false; } 399 + static inline bool s3c24xx_spi_usingfiq(struct s3c24xx_spi *s) { return false; } 400 + 401 + #endif /* CONFIG_SPI_S3C24XX_FIQ */ 402 + 235 403 static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t) 236 404 { 237 405 struct s3c24xx_spi *hw = to_hw(spi); 238 - 239 - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", 240 - t->tx_buf, t->rx_buf, t->len); 241 406 242 407 hw->tx = t->tx_buf; 243 408 hw->rx = t->rx_buf; ··· 429 228 430 229 init_completion(&hw->done); 431 230 231 + hw->fiq_inuse = 0; 232 + if (s3c24xx_spi_usefiq(hw) && t->len >= 3) 233 + s3c24xx_spi_tryfiq(hw); 234 + 432 235 /* send the first byte */ 433 236 writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); 434 237 435 238 wait_for_completion(&hw->done); 436 - 437 239 return hw->count; 438 240 } 439 241 ··· 458 254 goto irq_done; 459 255 } 460 256 461 - hw->count++; 257 + if (!s3c24xx_spi_usingfiq(hw)) { 258 + hw->count++; 462 259 463 - if (hw->rx) 464 - hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); 260 + if (hw->rx) 261 + hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); 465 262 466 - count++; 263 + count++; 467 264 468 - if (count < hw->len) 469 - writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); 470 - else 265 + if (count < hw->len) 266 + writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); 267 + else 268 + complete(&hw->done); 269 + } else { 270 + hw->count = hw->len; 271 + hw->fiq_inuse = 0; 272 + 273 + if (hw->rx) 274 + hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT); 275 + 471 276 complete(&hw->done); 277 + } 472 278 473 279 irq_done: 474 280 return IRQ_HANDLED; ··· 535 321 536 322 platform_set_drvdata(pdev, hw); 537 323 init_completion(&hw->done); 324 + 325 + /* initialise fiq handler */ 326 + 327 + s3c24xx_spi_initfiq(hw); 538 328 539 329 /* setup the master state. */ 540 330
+116
drivers/spi/spi_s3c24xx_fiq.S
··· 1 + /* linux/drivers/spi/spi_s3c24xx_fiq.S 2 + * 3 + * Copyright 2009 Simtec Electronics 4 + * Ben Dooks <ben@simtec.co.uk> 5 + * 6 + * S3C24XX SPI - FIQ pseudo-DMA transfer code 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/linkage.h> 14 + #include <asm/assembler.h> 15 + 16 + #include <mach/map.h> 17 + #include <mach/regs-irq.h> 18 + #include <plat/regs-spi.h> 19 + 20 + #include "spi_s3c24xx_fiq.h" 21 + 22 + .text 23 + 24 + @ entry to these routines is as follows, with the register names 25 + @ defined in fiq.h so that they can be shared with the C files which 26 + @ setup the calling registers. 27 + @ 28 + @ fiq_rirq The base of the IRQ registers to find S3C2410_SRCPND 29 + @ fiq_rtmp Temporary register to hold tx/rx data 30 + @ fiq_rspi The base of the SPI register block 31 + @ fiq_rtx The tx buffer pointer 32 + @ fiq_rrx The rx buffer pointer 33 + @ fiq_rcount The number of bytes to move 34 + 35 + @ each entry starts with a word entry of how long it is 36 + @ and an offset to the irq acknowledgment word 37 + 38 + ENTRY(s3c24xx_spi_fiq_rx) 39 + s3c24xx_spi_fix_rx: 40 + .word fiq_rx_end - fiq_rx_start 41 + .word fiq_rx_irq_ack - fiq_rx_start 42 + fiq_rx_start: 43 + ldr fiq_rtmp, fiq_rx_irq_ack 44 + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] 45 + 46 + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] 47 + strb fiq_rtmp, [ fiq_rrx ], #1 48 + 49 + mov fiq_rtmp, #0xff 50 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] 51 + 52 + subs fiq_rcount, fiq_rcount, #1 53 + subnes pc, lr, #4 @@ return, still have work to do 54 + 55 + @@ set IRQ controller so that next op will trigger IRQ 56 + mov fiq_rtmp, #0 57 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] 58 + subs pc, lr, #4 59 + 60 + fiq_rx_irq_ack: 61 + .word 0 62 + fiq_rx_end: 63 + 64 + ENTRY(s3c24xx_spi_fiq_txrx) 65 + s3c24xx_spi_fiq_txrx: 66 + .word fiq_txrx_end - fiq_txrx_start 67 + .word fiq_txrx_irq_ack - fiq_txrx_start 68 + fiq_txrx_start: 69 + 70 + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] 71 + strb fiq_rtmp, [ fiq_rrx ], #1 72 + 73 + ldr fiq_rtmp, fiq_txrx_irq_ack 74 + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] 75 + 76 + ldrb fiq_rtmp, [ fiq_rtx ], #1 77 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] 78 + 79 + subs fiq_rcount, fiq_rcount, #1 80 + subnes pc, lr, #4 @@ return, still have work to do 81 + 82 + mov fiq_rtmp, #0 83 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] 84 + subs pc, lr, #4 85 + 86 + fiq_txrx_irq_ack: 87 + .word 0 88 + 89 + fiq_txrx_end: 90 + 91 + ENTRY(s3c24xx_spi_fiq_tx) 92 + s3c24xx_spi_fix_tx: 93 + .word fiq_tx_end - fiq_tx_start 94 + .word fiq_tx_irq_ack - fiq_tx_start 95 + fiq_tx_start: 96 + ldrb fiq_rtmp, [ fiq_rspi, # S3C2410_SPRDAT ] 97 + 98 + ldr fiq_rtmp, fiq_tx_irq_ack 99 + str fiq_rtmp, [ fiq_rirq, # S3C2410_SRCPND - S3C24XX_VA_IRQ ] 100 + 101 + ldrb fiq_rtmp, [ fiq_rtx ], #1 102 + strb fiq_rtmp, [ fiq_rspi, # S3C2410_SPTDAT ] 103 + 104 + subs fiq_rcount, fiq_rcount, #1 105 + subnes pc, lr, #4 @@ return, still have work to do 106 + 107 + mov fiq_rtmp, #0 108 + str fiq_rtmp, [ fiq_rirq, # S3C2410_INTMOD - S3C24XX_VA_IRQ ] 109 + subs pc, lr, #4 110 + 111 + fiq_tx_irq_ack: 112 + .word 0 113 + 114 + fiq_tx_end: 115 + 116 + .end
+26
drivers/spi/spi_s3c24xx_fiq.h
··· 1 + /* linux/drivers/spi/spi_s3c24xx_fiq.h 2 + * 3 + * Copyright 2009 Simtec Electronics 4 + * Ben Dooks <ben@simtec.co.uk> 5 + * 6 + * S3C24XX SPI - FIQ pseudo-DMA transfer support 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + /* We have R8 through R13 to play with */ 14 + 15 + #ifdef __ASSEMBLY__ 16 + #define __REG_NR(x) r##x 17 + #else 18 + #define __REG_NR(x) (x) 19 + #endif 20 + 21 + #define fiq_rspi __REG_NR(8) 22 + #define fiq_rtmp __REG_NR(9) 23 + #define fiq_rrx __REG_NR(10) 24 + #define fiq_rtx __REG_NR(11) 25 + #define fiq_rcount __REG_NR(12) 26 + #define fiq_rirq __REG_NR(13)
+1196
drivers/spi/spi_s3c64xx.c
··· 1 + /* linux/drivers/spi/spi_s3c64xx.c 2 + * 3 + * Copyright (C) 2009 Samsung Electronics Ltd. 4 + * Jaswinder Singh <jassi.brar@samsung.com> 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + * 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + * 16 + * You should have received a copy of the GNU General Public License 17 + * along with this program; if not, write to the Free Software 18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 + */ 20 + 21 + #include <linux/init.h> 22 + #include <linux/module.h> 23 + #include <linux/workqueue.h> 24 + #include <linux/delay.h> 25 + #include <linux/clk.h> 26 + #include <linux/dma-mapping.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/spi/spi.h> 29 + 30 + #include <mach/dma.h> 31 + #include <plat/spi.h> 32 + 33 + /* Registers and bit-fields */ 34 + 35 + #define S3C64XX_SPI_CH_CFG 0x00 36 + #define S3C64XX_SPI_CLK_CFG 0x04 37 + #define S3C64XX_SPI_MODE_CFG 0x08 38 + #define S3C64XX_SPI_SLAVE_SEL 0x0C 39 + #define S3C64XX_SPI_INT_EN 0x10 40 + #define S3C64XX_SPI_STATUS 0x14 41 + #define S3C64XX_SPI_TX_DATA 0x18 42 + #define S3C64XX_SPI_RX_DATA 0x1C 43 + #define S3C64XX_SPI_PACKET_CNT 0x20 44 + #define S3C64XX_SPI_PENDING_CLR 0x24 45 + #define S3C64XX_SPI_SWAP_CFG 0x28 46 + #define S3C64XX_SPI_FB_CLK 0x2C 47 + 48 + #define S3C64XX_SPI_CH_HS_EN (1<<6) /* High Speed Enable */ 49 + #define S3C64XX_SPI_CH_SW_RST (1<<5) 50 + #define S3C64XX_SPI_CH_SLAVE (1<<4) 51 + #define S3C64XX_SPI_CPOL_L (1<<3) 52 + #define S3C64XX_SPI_CPHA_B (1<<2) 53 + #define S3C64XX_SPI_CH_RXCH_ON (1<<1) 54 + #define S3C64XX_SPI_CH_TXCH_ON (1<<0) 55 + 56 + #define S3C64XX_SPI_CLKSEL_SRCMSK (3<<9) 57 + #define S3C64XX_SPI_CLKSEL_SRCSHFT 9 58 + #define S3C64XX_SPI_ENCLK_ENABLE (1<<8) 59 + #define S3C64XX_SPI_PSR_MASK 0xff 60 + 61 + #define S3C64XX_SPI_MODE_CH_TSZ_BYTE (0<<29) 62 + #define S3C64XX_SPI_MODE_CH_TSZ_HALFWORD (1<<29) 63 + #define S3C64XX_SPI_MODE_CH_TSZ_WORD (2<<29) 64 + #define S3C64XX_SPI_MODE_CH_TSZ_MASK (3<<29) 65 + #define S3C64XX_SPI_MODE_BUS_TSZ_BYTE (0<<17) 66 + #define S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD (1<<17) 67 + #define S3C64XX_SPI_MODE_BUS_TSZ_WORD (2<<17) 68 + #define S3C64XX_SPI_MODE_BUS_TSZ_MASK (3<<17) 69 + #define S3C64XX_SPI_MODE_RXDMA_ON (1<<2) 70 + #define S3C64XX_SPI_MODE_TXDMA_ON (1<<1) 71 + #define S3C64XX_SPI_MODE_4BURST (1<<0) 72 + 73 + #define S3C64XX_SPI_SLAVE_AUTO (1<<1) 74 + #define S3C64XX_SPI_SLAVE_SIG_INACT (1<<0) 75 + 76 + #define S3C64XX_SPI_ACT(c) writel(0, (c)->regs + S3C64XX_SPI_SLAVE_SEL) 77 + 78 + #define S3C64XX_SPI_DEACT(c) writel(S3C64XX_SPI_SLAVE_SIG_INACT, \ 79 + (c)->regs + S3C64XX_SPI_SLAVE_SEL) 80 + 81 + #define S3C64XX_SPI_INT_TRAILING_EN (1<<6) 82 + #define S3C64XX_SPI_INT_RX_OVERRUN_EN (1<<5) 83 + #define S3C64XX_SPI_INT_RX_UNDERRUN_EN (1<<4) 84 + #define S3C64XX_SPI_INT_TX_OVERRUN_EN (1<<3) 85 + #define S3C64XX_SPI_INT_TX_UNDERRUN_EN (1<<2) 86 + #define S3C64XX_SPI_INT_RX_FIFORDY_EN (1<<1) 87 + #define S3C64XX_SPI_INT_TX_FIFORDY_EN (1<<0) 88 + 89 + #define S3C64XX_SPI_ST_RX_OVERRUN_ERR (1<<5) 90 + #define S3C64XX_SPI_ST_RX_UNDERRUN_ERR (1<<4) 91 + #define S3C64XX_SPI_ST_TX_OVERRUN_ERR (1<<3) 92 + #define S3C64XX_SPI_ST_TX_UNDERRUN_ERR (1<<2) 93 + #define S3C64XX_SPI_ST_RX_FIFORDY (1<<1) 94 + #define S3C64XX_SPI_ST_TX_FIFORDY (1<<0) 95 + 96 + #define S3C64XX_SPI_PACKET_CNT_EN (1<<16) 97 + 98 + #define S3C64XX_SPI_PND_TX_UNDERRUN_CLR (1<<4) 99 + #define S3C64XX_SPI_PND_TX_OVERRUN_CLR (1<<3) 100 + #define S3C64XX_SPI_PND_RX_UNDERRUN_CLR (1<<2) 101 + #define S3C64XX_SPI_PND_RX_OVERRUN_CLR (1<<1) 102 + #define S3C64XX_SPI_PND_TRAILING_CLR (1<<0) 103 + 104 + #define S3C64XX_SPI_SWAP_RX_HALF_WORD (1<<7) 105 + #define S3C64XX_SPI_SWAP_RX_BYTE (1<<6) 106 + #define S3C64XX_SPI_SWAP_RX_BIT (1<<5) 107 + #define S3C64XX_SPI_SWAP_RX_EN (1<<4) 108 + #define S3C64XX_SPI_SWAP_TX_HALF_WORD (1<<3) 109 + #define S3C64XX_SPI_SWAP_TX_BYTE (1<<2) 110 + #define S3C64XX_SPI_SWAP_TX_BIT (1<<1) 111 + #define S3C64XX_SPI_SWAP_TX_EN (1<<0) 112 + 113 + #define S3C64XX_SPI_FBCLK_MSK (3<<0) 114 + 115 + #define S3C64XX_SPI_ST_TRLCNTZ(v, i) ((((v) >> (i)->rx_lvl_offset) & \ 116 + (((i)->fifo_lvl_mask + 1))) \ 117 + ? 1 : 0) 118 + 119 + #define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \ 120 + (((i)->fifo_lvl_mask + 1) << 1)) \ 121 + ? 1 : 0) 122 + #define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask) 123 + #define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask) 124 + 125 + #define S3C64XX_SPI_MAX_TRAILCNT 0x3ff 126 + #define S3C64XX_SPI_TRAILCNT_OFF 19 127 + 128 + #define S3C64XX_SPI_TRAILCNT S3C64XX_SPI_MAX_TRAILCNT 129 + 130 + #define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 131 + 132 + #define SUSPND (1<<0) 133 + #define SPIBUSY (1<<1) 134 + #define RXBUSY (1<<2) 135 + #define TXBUSY (1<<3) 136 + 137 + /** 138 + * struct s3c64xx_spi_driver_data - Runtime info holder for SPI driver. 139 + * @clk: Pointer to the spi clock. 140 + * @master: Pointer to the SPI Protocol master. 141 + * @workqueue: Work queue for the SPI xfer requests. 142 + * @cntrlr_info: Platform specific data for the controller this driver manages. 143 + * @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint. 144 + * @work: Work 145 + * @queue: To log SPI xfer requests. 146 + * @lock: Controller specific lock. 147 + * @state: Set of FLAGS to indicate status. 148 + * @rx_dmach: Controller's DMA channel for Rx. 149 + * @tx_dmach: Controller's DMA channel for Tx. 150 + * @sfr_start: BUS address of SPI controller regs. 151 + * @regs: Pointer to ioremap'ed controller registers. 152 + * @xfer_completion: To indicate completion of xfer task. 153 + * @cur_mode: Stores the active configuration of the controller. 154 + * @cur_bpw: Stores the active bits per word settings. 155 + * @cur_speed: Stores the active xfer clock speed. 156 + */ 157 + struct s3c64xx_spi_driver_data { 158 + void __iomem *regs; 159 + struct clk *clk; 160 + struct platform_device *pdev; 161 + struct spi_master *master; 162 + struct workqueue_struct *workqueue; 163 + struct s3c64xx_spi_cntrlr_info *cntrlr_info; 164 + struct spi_device *tgl_spi; 165 + struct work_struct work; 166 + struct list_head queue; 167 + spinlock_t lock; 168 + enum dma_ch rx_dmach; 169 + enum dma_ch tx_dmach; 170 + unsigned long sfr_start; 171 + struct completion xfer_completion; 172 + unsigned state; 173 + unsigned cur_mode, cur_bpw; 174 + unsigned cur_speed; 175 + }; 176 + 177 + static struct s3c2410_dma_client s3c64xx_spi_dma_client = { 178 + .name = "samsung-spi-dma", 179 + }; 180 + 181 + static void flush_fifo(struct s3c64xx_spi_driver_data *sdd) 182 + { 183 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 184 + void __iomem *regs = sdd->regs; 185 + unsigned long loops; 186 + u32 val; 187 + 188 + writel(0, regs + S3C64XX_SPI_PACKET_CNT); 189 + 190 + val = readl(regs + S3C64XX_SPI_CH_CFG); 191 + val |= S3C64XX_SPI_CH_SW_RST; 192 + val &= ~S3C64XX_SPI_CH_HS_EN; 193 + writel(val, regs + S3C64XX_SPI_CH_CFG); 194 + 195 + /* Flush TxFIFO*/ 196 + loops = msecs_to_loops(1); 197 + do { 198 + val = readl(regs + S3C64XX_SPI_STATUS); 199 + } while (TX_FIFO_LVL(val, sci) && loops--); 200 + 201 + /* Flush RxFIFO*/ 202 + loops = msecs_to_loops(1); 203 + do { 204 + val = readl(regs + S3C64XX_SPI_STATUS); 205 + if (RX_FIFO_LVL(val, sci)) 206 + readl(regs + S3C64XX_SPI_RX_DATA); 207 + else 208 + break; 209 + } while (loops--); 210 + 211 + val = readl(regs + S3C64XX_SPI_CH_CFG); 212 + val &= ~S3C64XX_SPI_CH_SW_RST; 213 + writel(val, regs + S3C64XX_SPI_CH_CFG); 214 + 215 + val = readl(regs + S3C64XX_SPI_MODE_CFG); 216 + val &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); 217 + writel(val, regs + S3C64XX_SPI_MODE_CFG); 218 + 219 + val = readl(regs + S3C64XX_SPI_CH_CFG); 220 + val &= ~(S3C64XX_SPI_CH_RXCH_ON | S3C64XX_SPI_CH_TXCH_ON); 221 + writel(val, regs + S3C64XX_SPI_CH_CFG); 222 + } 223 + 224 + static void enable_datapath(struct s3c64xx_spi_driver_data *sdd, 225 + struct spi_device *spi, 226 + struct spi_transfer *xfer, int dma_mode) 227 + { 228 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 229 + void __iomem *regs = sdd->regs; 230 + u32 modecfg, chcfg; 231 + 232 + modecfg = readl(regs + S3C64XX_SPI_MODE_CFG); 233 + modecfg &= ~(S3C64XX_SPI_MODE_TXDMA_ON | S3C64XX_SPI_MODE_RXDMA_ON); 234 + 235 + chcfg = readl(regs + S3C64XX_SPI_CH_CFG); 236 + chcfg &= ~S3C64XX_SPI_CH_TXCH_ON; 237 + 238 + if (dma_mode) { 239 + chcfg &= ~S3C64XX_SPI_CH_RXCH_ON; 240 + } else { 241 + /* Always shift in data in FIFO, even if xfer is Tx only, 242 + * this helps setting PCKT_CNT value for generating clocks 243 + * as exactly needed. 244 + */ 245 + chcfg |= S3C64XX_SPI_CH_RXCH_ON; 246 + writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) 247 + | S3C64XX_SPI_PACKET_CNT_EN, 248 + regs + S3C64XX_SPI_PACKET_CNT); 249 + } 250 + 251 + if (xfer->tx_buf != NULL) { 252 + sdd->state |= TXBUSY; 253 + chcfg |= S3C64XX_SPI_CH_TXCH_ON; 254 + if (dma_mode) { 255 + modecfg |= S3C64XX_SPI_MODE_TXDMA_ON; 256 + s3c2410_dma_config(sdd->tx_dmach, 1); 257 + s3c2410_dma_enqueue(sdd->tx_dmach, (void *)sdd, 258 + xfer->tx_dma, xfer->len); 259 + s3c2410_dma_ctrl(sdd->tx_dmach, S3C2410_DMAOP_START); 260 + } else { 261 + unsigned char *buf = (unsigned char *) xfer->tx_buf; 262 + int i = 0; 263 + while (i < xfer->len) 264 + writeb(buf[i++], regs + S3C64XX_SPI_TX_DATA); 265 + } 266 + } 267 + 268 + if (xfer->rx_buf != NULL) { 269 + sdd->state |= RXBUSY; 270 + 271 + if (sci->high_speed && sdd->cur_speed >= 30000000UL 272 + && !(sdd->cur_mode & SPI_CPHA)) 273 + chcfg |= S3C64XX_SPI_CH_HS_EN; 274 + 275 + if (dma_mode) { 276 + modecfg |= S3C64XX_SPI_MODE_RXDMA_ON; 277 + chcfg |= S3C64XX_SPI_CH_RXCH_ON; 278 + writel(((xfer->len * 8 / sdd->cur_bpw) & 0xffff) 279 + | S3C64XX_SPI_PACKET_CNT_EN, 280 + regs + S3C64XX_SPI_PACKET_CNT); 281 + s3c2410_dma_config(sdd->rx_dmach, 1); 282 + s3c2410_dma_enqueue(sdd->rx_dmach, (void *)sdd, 283 + xfer->rx_dma, xfer->len); 284 + s3c2410_dma_ctrl(sdd->rx_dmach, S3C2410_DMAOP_START); 285 + } 286 + } 287 + 288 + writel(modecfg, regs + S3C64XX_SPI_MODE_CFG); 289 + writel(chcfg, regs + S3C64XX_SPI_CH_CFG); 290 + } 291 + 292 + static inline void enable_cs(struct s3c64xx_spi_driver_data *sdd, 293 + struct spi_device *spi) 294 + { 295 + struct s3c64xx_spi_csinfo *cs; 296 + 297 + if (sdd->tgl_spi != NULL) { /* If last device toggled after mssg */ 298 + if (sdd->tgl_spi != spi) { /* if last mssg on diff device */ 299 + /* Deselect the last toggled device */ 300 + cs = sdd->tgl_spi->controller_data; 301 + cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); 302 + } 303 + sdd->tgl_spi = NULL; 304 + } 305 + 306 + cs = spi->controller_data; 307 + cs->set_level(spi->mode & SPI_CS_HIGH ? 1 : 0); 308 + } 309 + 310 + static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd, 311 + struct spi_transfer *xfer, int dma_mode) 312 + { 313 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 314 + void __iomem *regs = sdd->regs; 315 + unsigned long val; 316 + int ms; 317 + 318 + /* millisecs to xfer 'len' bytes @ 'cur_speed' */ 319 + ms = xfer->len * 8 * 1000 / sdd->cur_speed; 320 + ms += 5; /* some tolerance */ 321 + 322 + if (dma_mode) { 323 + val = msecs_to_jiffies(ms) + 10; 324 + val = wait_for_completion_timeout(&sdd->xfer_completion, val); 325 + } else { 326 + val = msecs_to_loops(ms); 327 + do { 328 + val = readl(regs + S3C64XX_SPI_STATUS); 329 + } while (RX_FIFO_LVL(val, sci) < xfer->len && --val); 330 + } 331 + 332 + if (!val) 333 + return -EIO; 334 + 335 + if (dma_mode) { 336 + u32 status; 337 + 338 + /* 339 + * DmaTx returns after simply writing data in the FIFO, 340 + * w/o waiting for real transmission on the bus to finish. 341 + * DmaRx returns only after Dma read data from FIFO which 342 + * needs bus transmission to finish, so we don't worry if 343 + * Xfer involved Rx(with or without Tx). 344 + */ 345 + if (xfer->rx_buf == NULL) { 346 + val = msecs_to_loops(10); 347 + status = readl(regs + S3C64XX_SPI_STATUS); 348 + while ((TX_FIFO_LVL(status, sci) 349 + || !S3C64XX_SPI_ST_TX_DONE(status, sci)) 350 + && --val) { 351 + cpu_relax(); 352 + status = readl(regs + S3C64XX_SPI_STATUS); 353 + } 354 + 355 + if (!val) 356 + return -EIO; 357 + } 358 + } else { 359 + unsigned char *buf; 360 + int i; 361 + 362 + /* If it was only Tx */ 363 + if (xfer->rx_buf == NULL) { 364 + sdd->state &= ~TXBUSY; 365 + return 0; 366 + } 367 + 368 + i = 0; 369 + buf = xfer->rx_buf; 370 + while (i < xfer->len) 371 + buf[i++] = readb(regs + S3C64XX_SPI_RX_DATA); 372 + 373 + sdd->state &= ~RXBUSY; 374 + } 375 + 376 + return 0; 377 + } 378 + 379 + static inline void disable_cs(struct s3c64xx_spi_driver_data *sdd, 380 + struct spi_device *spi) 381 + { 382 + struct s3c64xx_spi_csinfo *cs = spi->controller_data; 383 + 384 + if (sdd->tgl_spi == spi) 385 + sdd->tgl_spi = NULL; 386 + 387 + cs->set_level(spi->mode & SPI_CS_HIGH ? 0 : 1); 388 + } 389 + 390 + static void s3c64xx_spi_config(struct s3c64xx_spi_driver_data *sdd) 391 + { 392 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 393 + void __iomem *regs = sdd->regs; 394 + u32 val; 395 + 396 + /* Disable Clock */ 397 + val = readl(regs + S3C64XX_SPI_CLK_CFG); 398 + val &= ~S3C64XX_SPI_ENCLK_ENABLE; 399 + writel(val, regs + S3C64XX_SPI_CLK_CFG); 400 + 401 + /* Set Polarity and Phase */ 402 + val = readl(regs + S3C64XX_SPI_CH_CFG); 403 + val &= ~(S3C64XX_SPI_CH_SLAVE | 404 + S3C64XX_SPI_CPOL_L | 405 + S3C64XX_SPI_CPHA_B); 406 + 407 + if (sdd->cur_mode & SPI_CPOL) 408 + val |= S3C64XX_SPI_CPOL_L; 409 + 410 + if (sdd->cur_mode & SPI_CPHA) 411 + val |= S3C64XX_SPI_CPHA_B; 412 + 413 + writel(val, regs + S3C64XX_SPI_CH_CFG); 414 + 415 + /* Set Channel & DMA Mode */ 416 + val = readl(regs + S3C64XX_SPI_MODE_CFG); 417 + val &= ~(S3C64XX_SPI_MODE_BUS_TSZ_MASK 418 + | S3C64XX_SPI_MODE_CH_TSZ_MASK); 419 + 420 + switch (sdd->cur_bpw) { 421 + case 32: 422 + val |= S3C64XX_SPI_MODE_BUS_TSZ_WORD; 423 + break; 424 + case 16: 425 + val |= S3C64XX_SPI_MODE_BUS_TSZ_HALFWORD; 426 + break; 427 + default: 428 + val |= S3C64XX_SPI_MODE_BUS_TSZ_BYTE; 429 + break; 430 + } 431 + val |= S3C64XX_SPI_MODE_CH_TSZ_BYTE; /* Always 8bits wide */ 432 + 433 + writel(val, regs + S3C64XX_SPI_MODE_CFG); 434 + 435 + /* Configure Clock */ 436 + val = readl(regs + S3C64XX_SPI_CLK_CFG); 437 + val &= ~S3C64XX_SPI_PSR_MASK; 438 + val |= ((clk_get_rate(sci->src_clk) / sdd->cur_speed / 2 - 1) 439 + & S3C64XX_SPI_PSR_MASK); 440 + writel(val, regs + S3C64XX_SPI_CLK_CFG); 441 + 442 + /* Enable Clock */ 443 + val = readl(regs + S3C64XX_SPI_CLK_CFG); 444 + val |= S3C64XX_SPI_ENCLK_ENABLE; 445 + writel(val, regs + S3C64XX_SPI_CLK_CFG); 446 + } 447 + 448 + void s3c64xx_spi_dma_rxcb(struct s3c2410_dma_chan *chan, void *buf_id, 449 + int size, enum s3c2410_dma_buffresult res) 450 + { 451 + struct s3c64xx_spi_driver_data *sdd = buf_id; 452 + unsigned long flags; 453 + 454 + spin_lock_irqsave(&sdd->lock, flags); 455 + 456 + if (res == S3C2410_RES_OK) 457 + sdd->state &= ~RXBUSY; 458 + else 459 + dev_err(&sdd->pdev->dev, "DmaAbrtRx-%d\n", size); 460 + 461 + /* If the other done */ 462 + if (!(sdd->state & TXBUSY)) 463 + complete(&sdd->xfer_completion); 464 + 465 + spin_unlock_irqrestore(&sdd->lock, flags); 466 + } 467 + 468 + void s3c64xx_spi_dma_txcb(struct s3c2410_dma_chan *chan, void *buf_id, 469 + int size, enum s3c2410_dma_buffresult res) 470 + { 471 + struct s3c64xx_spi_driver_data *sdd = buf_id; 472 + unsigned long flags; 473 + 474 + spin_lock_irqsave(&sdd->lock, flags); 475 + 476 + if (res == S3C2410_RES_OK) 477 + sdd->state &= ~TXBUSY; 478 + else 479 + dev_err(&sdd->pdev->dev, "DmaAbrtTx-%d \n", size); 480 + 481 + /* If the other done */ 482 + if (!(sdd->state & RXBUSY)) 483 + complete(&sdd->xfer_completion); 484 + 485 + spin_unlock_irqrestore(&sdd->lock, flags); 486 + } 487 + 488 + #define XFER_DMAADDR_INVALID DMA_BIT_MASK(32) 489 + 490 + static int s3c64xx_spi_map_mssg(struct s3c64xx_spi_driver_data *sdd, 491 + struct spi_message *msg) 492 + { 493 + struct device *dev = &sdd->pdev->dev; 494 + struct spi_transfer *xfer; 495 + 496 + if (msg->is_dma_mapped) 497 + return 0; 498 + 499 + /* First mark all xfer unmapped */ 500 + list_for_each_entry(xfer, &msg->transfers, transfer_list) { 501 + xfer->rx_dma = XFER_DMAADDR_INVALID; 502 + xfer->tx_dma = XFER_DMAADDR_INVALID; 503 + } 504 + 505 + /* Map until end or first fail */ 506 + list_for_each_entry(xfer, &msg->transfers, transfer_list) { 507 + 508 + if (xfer->tx_buf != NULL) { 509 + xfer->tx_dma = dma_map_single(dev, xfer->tx_buf, 510 + xfer->len, DMA_TO_DEVICE); 511 + if (dma_mapping_error(dev, xfer->tx_dma)) { 512 + dev_err(dev, "dma_map_single Tx failed\n"); 513 + xfer->tx_dma = XFER_DMAADDR_INVALID; 514 + return -ENOMEM; 515 + } 516 + } 517 + 518 + if (xfer->rx_buf != NULL) { 519 + xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, 520 + xfer->len, DMA_FROM_DEVICE); 521 + if (dma_mapping_error(dev, xfer->rx_dma)) { 522 + dev_err(dev, "dma_map_single Rx failed\n"); 523 + dma_unmap_single(dev, xfer->tx_dma, 524 + xfer->len, DMA_TO_DEVICE); 525 + xfer->tx_dma = XFER_DMAADDR_INVALID; 526 + xfer->rx_dma = XFER_DMAADDR_INVALID; 527 + return -ENOMEM; 528 + } 529 + } 530 + } 531 + 532 + return 0; 533 + } 534 + 535 + static void s3c64xx_spi_unmap_mssg(struct s3c64xx_spi_driver_data *sdd, 536 + struct spi_message *msg) 537 + { 538 + struct device *dev = &sdd->pdev->dev; 539 + struct spi_transfer *xfer; 540 + 541 + if (msg->is_dma_mapped) 542 + return; 543 + 544 + list_for_each_entry(xfer, &msg->transfers, transfer_list) { 545 + 546 + if (xfer->rx_buf != NULL 547 + && xfer->rx_dma != XFER_DMAADDR_INVALID) 548 + dma_unmap_single(dev, xfer->rx_dma, 549 + xfer->len, DMA_FROM_DEVICE); 550 + 551 + if (xfer->tx_buf != NULL 552 + && xfer->tx_dma != XFER_DMAADDR_INVALID) 553 + dma_unmap_single(dev, xfer->tx_dma, 554 + xfer->len, DMA_TO_DEVICE); 555 + } 556 + } 557 + 558 + static void handle_msg(struct s3c64xx_spi_driver_data *sdd, 559 + struct spi_message *msg) 560 + { 561 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 562 + struct spi_device *spi = msg->spi; 563 + struct s3c64xx_spi_csinfo *cs = spi->controller_data; 564 + struct spi_transfer *xfer; 565 + int status = 0, cs_toggle = 0; 566 + u32 speed; 567 + u8 bpw; 568 + 569 + /* If Master's(controller) state differs from that needed by Slave */ 570 + if (sdd->cur_speed != spi->max_speed_hz 571 + || sdd->cur_mode != spi->mode 572 + || sdd->cur_bpw != spi->bits_per_word) { 573 + sdd->cur_bpw = spi->bits_per_word; 574 + sdd->cur_speed = spi->max_speed_hz; 575 + sdd->cur_mode = spi->mode; 576 + s3c64xx_spi_config(sdd); 577 + } 578 + 579 + /* Map all the transfers if needed */ 580 + if (s3c64xx_spi_map_mssg(sdd, msg)) { 581 + dev_err(&spi->dev, 582 + "Xfer: Unable to map message buffers!\n"); 583 + status = -ENOMEM; 584 + goto out; 585 + } 586 + 587 + /* Configure feedback delay */ 588 + writel(cs->fb_delay & 0x3, sdd->regs + S3C64XX_SPI_FB_CLK); 589 + 590 + list_for_each_entry(xfer, &msg->transfers, transfer_list) { 591 + 592 + unsigned long flags; 593 + int use_dma; 594 + 595 + INIT_COMPLETION(sdd->xfer_completion); 596 + 597 + /* Only BPW and Speed may change across transfers */ 598 + bpw = xfer->bits_per_word ? : spi->bits_per_word; 599 + speed = xfer->speed_hz ? : spi->max_speed_hz; 600 + 601 + if (bpw != sdd->cur_bpw || speed != sdd->cur_speed) { 602 + sdd->cur_bpw = bpw; 603 + sdd->cur_speed = speed; 604 + s3c64xx_spi_config(sdd); 605 + } 606 + 607 + /* Polling method for xfers not bigger than FIFO capacity */ 608 + if (xfer->len <= ((sci->fifo_lvl_mask >> 1) + 1)) 609 + use_dma = 0; 610 + else 611 + use_dma = 1; 612 + 613 + spin_lock_irqsave(&sdd->lock, flags); 614 + 615 + /* Pending only which is to be done */ 616 + sdd->state &= ~RXBUSY; 617 + sdd->state &= ~TXBUSY; 618 + 619 + enable_datapath(sdd, spi, xfer, use_dma); 620 + 621 + /* Slave Select */ 622 + enable_cs(sdd, spi); 623 + 624 + /* Start the signals */ 625 + S3C64XX_SPI_ACT(sdd); 626 + 627 + spin_unlock_irqrestore(&sdd->lock, flags); 628 + 629 + status = wait_for_xfer(sdd, xfer, use_dma); 630 + 631 + /* Quiese the signals */ 632 + S3C64XX_SPI_DEACT(sdd); 633 + 634 + if (status) { 635 + dev_err(&spi->dev, "I/O Error: \ 636 + rx-%d tx-%d res:rx-%c tx-%c len-%d\n", 637 + xfer->rx_buf ? 1 : 0, xfer->tx_buf ? 1 : 0, 638 + (sdd->state & RXBUSY) ? 'f' : 'p', 639 + (sdd->state & TXBUSY) ? 'f' : 'p', 640 + xfer->len); 641 + 642 + if (use_dma) { 643 + if (xfer->tx_buf != NULL 644 + && (sdd->state & TXBUSY)) 645 + s3c2410_dma_ctrl(sdd->tx_dmach, 646 + S3C2410_DMAOP_FLUSH); 647 + if (xfer->rx_buf != NULL 648 + && (sdd->state & RXBUSY)) 649 + s3c2410_dma_ctrl(sdd->rx_dmach, 650 + S3C2410_DMAOP_FLUSH); 651 + } 652 + 653 + goto out; 654 + } 655 + 656 + if (xfer->delay_usecs) 657 + udelay(xfer->delay_usecs); 658 + 659 + if (xfer->cs_change) { 660 + /* Hint that the next mssg is gonna be 661 + for the same device */ 662 + if (list_is_last(&xfer->transfer_list, 663 + &msg->transfers)) 664 + cs_toggle = 1; 665 + else 666 + disable_cs(sdd, spi); 667 + } 668 + 669 + msg->actual_length += xfer->len; 670 + 671 + flush_fifo(sdd); 672 + } 673 + 674 + out: 675 + if (!cs_toggle || status) 676 + disable_cs(sdd, spi); 677 + else 678 + sdd->tgl_spi = spi; 679 + 680 + s3c64xx_spi_unmap_mssg(sdd, msg); 681 + 682 + msg->status = status; 683 + 684 + if (msg->complete) 685 + msg->complete(msg->context); 686 + } 687 + 688 + static int acquire_dma(struct s3c64xx_spi_driver_data *sdd) 689 + { 690 + if (s3c2410_dma_request(sdd->rx_dmach, 691 + &s3c64xx_spi_dma_client, NULL) < 0) { 692 + dev_err(&sdd->pdev->dev, "cannot get RxDMA\n"); 693 + return 0; 694 + } 695 + s3c2410_dma_set_buffdone_fn(sdd->rx_dmach, s3c64xx_spi_dma_rxcb); 696 + s3c2410_dma_devconfig(sdd->rx_dmach, S3C2410_DMASRC_HW, 697 + sdd->sfr_start + S3C64XX_SPI_RX_DATA); 698 + 699 + if (s3c2410_dma_request(sdd->tx_dmach, 700 + &s3c64xx_spi_dma_client, NULL) < 0) { 701 + dev_err(&sdd->pdev->dev, "cannot get TxDMA\n"); 702 + s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); 703 + return 0; 704 + } 705 + s3c2410_dma_set_buffdone_fn(sdd->tx_dmach, s3c64xx_spi_dma_txcb); 706 + s3c2410_dma_devconfig(sdd->tx_dmach, S3C2410_DMASRC_MEM, 707 + sdd->sfr_start + S3C64XX_SPI_TX_DATA); 708 + 709 + return 1; 710 + } 711 + 712 + static void s3c64xx_spi_work(struct work_struct *work) 713 + { 714 + struct s3c64xx_spi_driver_data *sdd = container_of(work, 715 + struct s3c64xx_spi_driver_data, work); 716 + unsigned long flags; 717 + 718 + /* Acquire DMA channels */ 719 + while (!acquire_dma(sdd)) 720 + msleep(10); 721 + 722 + spin_lock_irqsave(&sdd->lock, flags); 723 + 724 + while (!list_empty(&sdd->queue) 725 + && !(sdd->state & SUSPND)) { 726 + 727 + struct spi_message *msg; 728 + 729 + msg = container_of(sdd->queue.next, struct spi_message, queue); 730 + 731 + list_del_init(&msg->queue); 732 + 733 + /* Set Xfer busy flag */ 734 + sdd->state |= SPIBUSY; 735 + 736 + spin_unlock_irqrestore(&sdd->lock, flags); 737 + 738 + handle_msg(sdd, msg); 739 + 740 + spin_lock_irqsave(&sdd->lock, flags); 741 + 742 + sdd->state &= ~SPIBUSY; 743 + } 744 + 745 + spin_unlock_irqrestore(&sdd->lock, flags); 746 + 747 + /* Free DMA channels */ 748 + s3c2410_dma_free(sdd->tx_dmach, &s3c64xx_spi_dma_client); 749 + s3c2410_dma_free(sdd->rx_dmach, &s3c64xx_spi_dma_client); 750 + } 751 + 752 + static int s3c64xx_spi_transfer(struct spi_device *spi, 753 + struct spi_message *msg) 754 + { 755 + struct s3c64xx_spi_driver_data *sdd; 756 + unsigned long flags; 757 + 758 + sdd = spi_master_get_devdata(spi->master); 759 + 760 + spin_lock_irqsave(&sdd->lock, flags); 761 + 762 + if (sdd->state & SUSPND) { 763 + spin_unlock_irqrestore(&sdd->lock, flags); 764 + return -ESHUTDOWN; 765 + } 766 + 767 + msg->status = -EINPROGRESS; 768 + msg->actual_length = 0; 769 + 770 + list_add_tail(&msg->queue, &sdd->queue); 771 + 772 + queue_work(sdd->workqueue, &sdd->work); 773 + 774 + spin_unlock_irqrestore(&sdd->lock, flags); 775 + 776 + return 0; 777 + } 778 + 779 + /* 780 + * Here we only check the validity of requested configuration 781 + * and save the configuration in a local data-structure. 782 + * The controller is actually configured only just before we 783 + * get a message to transfer. 784 + */ 785 + static int s3c64xx_spi_setup(struct spi_device *spi) 786 + { 787 + struct s3c64xx_spi_csinfo *cs = spi->controller_data; 788 + struct s3c64xx_spi_driver_data *sdd; 789 + struct s3c64xx_spi_cntrlr_info *sci; 790 + struct spi_message *msg; 791 + u32 psr, speed; 792 + unsigned long flags; 793 + int err = 0; 794 + 795 + if (cs == NULL || cs->set_level == NULL) { 796 + dev_err(&spi->dev, "No CS for SPI(%d)\n", spi->chip_select); 797 + return -ENODEV; 798 + } 799 + 800 + sdd = spi_master_get_devdata(spi->master); 801 + sci = sdd->cntrlr_info; 802 + 803 + spin_lock_irqsave(&sdd->lock, flags); 804 + 805 + list_for_each_entry(msg, &sdd->queue, queue) { 806 + /* Is some mssg is already queued for this device */ 807 + if (msg->spi == spi) { 808 + dev_err(&spi->dev, 809 + "setup: attempt while mssg in queue!\n"); 810 + spin_unlock_irqrestore(&sdd->lock, flags); 811 + return -EBUSY; 812 + } 813 + } 814 + 815 + if (sdd->state & SUSPND) { 816 + spin_unlock_irqrestore(&sdd->lock, flags); 817 + dev_err(&spi->dev, 818 + "setup: SPI-%d not active!\n", spi->master->bus_num); 819 + return -ESHUTDOWN; 820 + } 821 + 822 + spin_unlock_irqrestore(&sdd->lock, flags); 823 + 824 + if (spi->bits_per_word != 8 825 + && spi->bits_per_word != 16 826 + && spi->bits_per_word != 32) { 827 + dev_err(&spi->dev, "setup: %dbits/wrd not supported!\n", 828 + spi->bits_per_word); 829 + err = -EINVAL; 830 + goto setup_exit; 831 + } 832 + 833 + /* Check if we can provide the requested rate */ 834 + speed = clk_get_rate(sci->src_clk) / 2 / (0 + 1); /* Max possible */ 835 + 836 + if (spi->max_speed_hz > speed) 837 + spi->max_speed_hz = speed; 838 + 839 + psr = clk_get_rate(sci->src_clk) / 2 / spi->max_speed_hz - 1; 840 + psr &= S3C64XX_SPI_PSR_MASK; 841 + if (psr == S3C64XX_SPI_PSR_MASK) 842 + psr--; 843 + 844 + speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); 845 + if (spi->max_speed_hz < speed) { 846 + if (psr+1 < S3C64XX_SPI_PSR_MASK) { 847 + psr++; 848 + } else { 849 + err = -EINVAL; 850 + goto setup_exit; 851 + } 852 + } 853 + 854 + speed = clk_get_rate(sci->src_clk) / 2 / (psr + 1); 855 + if (spi->max_speed_hz >= speed) 856 + spi->max_speed_hz = speed; 857 + else 858 + err = -EINVAL; 859 + 860 + setup_exit: 861 + 862 + /* setup() returns with device de-selected */ 863 + disable_cs(sdd, spi); 864 + 865 + return err; 866 + } 867 + 868 + static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) 869 + { 870 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 871 + void __iomem *regs = sdd->regs; 872 + unsigned int val; 873 + 874 + sdd->cur_speed = 0; 875 + 876 + S3C64XX_SPI_DEACT(sdd); 877 + 878 + /* Disable Interrupts - we use Polling if not DMA mode */ 879 + writel(0, regs + S3C64XX_SPI_INT_EN); 880 + 881 + writel(sci->src_clk_nr << S3C64XX_SPI_CLKSEL_SRCSHFT, 882 + regs + S3C64XX_SPI_CLK_CFG); 883 + writel(0, regs + S3C64XX_SPI_MODE_CFG); 884 + writel(0, regs + S3C64XX_SPI_PACKET_CNT); 885 + 886 + /* Clear any irq pending bits */ 887 + writel(readl(regs + S3C64XX_SPI_PENDING_CLR), 888 + regs + S3C64XX_SPI_PENDING_CLR); 889 + 890 + writel(0, regs + S3C64XX_SPI_SWAP_CFG); 891 + 892 + val = readl(regs + S3C64XX_SPI_MODE_CFG); 893 + val &= ~S3C64XX_SPI_MODE_4BURST; 894 + val &= ~(S3C64XX_SPI_MAX_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); 895 + val |= (S3C64XX_SPI_TRAILCNT << S3C64XX_SPI_TRAILCNT_OFF); 896 + writel(val, regs + S3C64XX_SPI_MODE_CFG); 897 + 898 + flush_fifo(sdd); 899 + } 900 + 901 + static int __init s3c64xx_spi_probe(struct platform_device *pdev) 902 + { 903 + struct resource *mem_res, *dmatx_res, *dmarx_res; 904 + struct s3c64xx_spi_driver_data *sdd; 905 + struct s3c64xx_spi_cntrlr_info *sci; 906 + struct spi_master *master; 907 + int ret; 908 + 909 + if (pdev->id < 0) { 910 + dev_err(&pdev->dev, 911 + "Invalid platform device id-%d\n", pdev->id); 912 + return -ENODEV; 913 + } 914 + 915 + if (pdev->dev.platform_data == NULL) { 916 + dev_err(&pdev->dev, "platform_data missing!\n"); 917 + return -ENODEV; 918 + } 919 + 920 + /* Check for availability of necessary resource */ 921 + 922 + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); 923 + if (dmatx_res == NULL) { 924 + dev_err(&pdev->dev, "Unable to get SPI-Tx dma resource\n"); 925 + return -ENXIO; 926 + } 927 + 928 + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); 929 + if (dmarx_res == NULL) { 930 + dev_err(&pdev->dev, "Unable to get SPI-Rx dma resource\n"); 931 + return -ENXIO; 932 + } 933 + 934 + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 935 + if (mem_res == NULL) { 936 + dev_err(&pdev->dev, "Unable to get SPI MEM resource\n"); 937 + return -ENXIO; 938 + } 939 + 940 + master = spi_alloc_master(&pdev->dev, 941 + sizeof(struct s3c64xx_spi_driver_data)); 942 + if (master == NULL) { 943 + dev_err(&pdev->dev, "Unable to allocate SPI Master\n"); 944 + return -ENOMEM; 945 + } 946 + 947 + sci = pdev->dev.platform_data; 948 + 949 + platform_set_drvdata(pdev, master); 950 + 951 + sdd = spi_master_get_devdata(master); 952 + sdd->master = master; 953 + sdd->cntrlr_info = sci; 954 + sdd->pdev = pdev; 955 + sdd->sfr_start = mem_res->start; 956 + sdd->tx_dmach = dmatx_res->start; 957 + sdd->rx_dmach = dmarx_res->start; 958 + 959 + sdd->cur_bpw = 8; 960 + 961 + master->bus_num = pdev->id; 962 + master->setup = s3c64xx_spi_setup; 963 + master->transfer = s3c64xx_spi_transfer; 964 + master->num_chipselect = sci->num_cs; 965 + master->dma_alignment = 8; 966 + /* the spi->mode bits understood by this driver: */ 967 + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 968 + 969 + if (request_mem_region(mem_res->start, 970 + resource_size(mem_res), pdev->name) == NULL) { 971 + dev_err(&pdev->dev, "Req mem region failed\n"); 972 + ret = -ENXIO; 973 + goto err0; 974 + } 975 + 976 + sdd->regs = ioremap(mem_res->start, resource_size(mem_res)); 977 + if (sdd->regs == NULL) { 978 + dev_err(&pdev->dev, "Unable to remap IO\n"); 979 + ret = -ENXIO; 980 + goto err1; 981 + } 982 + 983 + if (sci->cfg_gpio == NULL || sci->cfg_gpio(pdev)) { 984 + dev_err(&pdev->dev, "Unable to config gpio\n"); 985 + ret = -EBUSY; 986 + goto err2; 987 + } 988 + 989 + /* Setup clocks */ 990 + sdd->clk = clk_get(&pdev->dev, "spi"); 991 + if (IS_ERR(sdd->clk)) { 992 + dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n"); 993 + ret = PTR_ERR(sdd->clk); 994 + goto err3; 995 + } 996 + 997 + if (clk_enable(sdd->clk)) { 998 + dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n"); 999 + ret = -EBUSY; 1000 + goto err4; 1001 + } 1002 + 1003 + if (sci->src_clk_nr == S3C64XX_SPI_SRCCLK_PCLK) 1004 + sci->src_clk = sdd->clk; 1005 + else 1006 + sci->src_clk = clk_get(&pdev->dev, sci->src_clk_name); 1007 + if (IS_ERR(sci->src_clk)) { 1008 + dev_err(&pdev->dev, 1009 + "Unable to acquire clock '%s'\n", sci->src_clk_name); 1010 + ret = PTR_ERR(sci->src_clk); 1011 + goto err5; 1012 + } 1013 + 1014 + if (sci->src_clk != sdd->clk && clk_enable(sci->src_clk)) { 1015 + dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", 1016 + sci->src_clk_name); 1017 + ret = -EBUSY; 1018 + goto err6; 1019 + } 1020 + 1021 + sdd->workqueue = create_singlethread_workqueue( 1022 + dev_name(master->dev.parent)); 1023 + if (sdd->workqueue == NULL) { 1024 + dev_err(&pdev->dev, "Unable to create workqueue\n"); 1025 + ret = -ENOMEM; 1026 + goto err7; 1027 + } 1028 + 1029 + /* Setup Deufult Mode */ 1030 + s3c64xx_spi_hwinit(sdd, pdev->id); 1031 + 1032 + spin_lock_init(&sdd->lock); 1033 + init_completion(&sdd->xfer_completion); 1034 + INIT_WORK(&sdd->work, s3c64xx_spi_work); 1035 + INIT_LIST_HEAD(&sdd->queue); 1036 + 1037 + if (spi_register_master(master)) { 1038 + dev_err(&pdev->dev, "cannot register SPI master\n"); 1039 + ret = -EBUSY; 1040 + goto err8; 1041 + } 1042 + 1043 + dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d \ 1044 + with %d Slaves attached\n", 1045 + pdev->id, master->num_chipselect); 1046 + dev_dbg(&pdev->dev, "\tIOmem=[0x%x-0x%x]\ 1047 + \tDMA=[Rx-%d, Tx-%d]\n", 1048 + mem_res->end, mem_res->start, 1049 + sdd->rx_dmach, sdd->tx_dmach); 1050 + 1051 + return 0; 1052 + 1053 + err8: 1054 + destroy_workqueue(sdd->workqueue); 1055 + err7: 1056 + if (sci->src_clk != sdd->clk) 1057 + clk_disable(sci->src_clk); 1058 + err6: 1059 + if (sci->src_clk != sdd->clk) 1060 + clk_put(sci->src_clk); 1061 + err5: 1062 + clk_disable(sdd->clk); 1063 + err4: 1064 + clk_put(sdd->clk); 1065 + err3: 1066 + err2: 1067 + iounmap((void *) sdd->regs); 1068 + err1: 1069 + release_mem_region(mem_res->start, resource_size(mem_res)); 1070 + err0: 1071 + platform_set_drvdata(pdev, NULL); 1072 + spi_master_put(master); 1073 + 1074 + return ret; 1075 + } 1076 + 1077 + static int s3c64xx_spi_remove(struct platform_device *pdev) 1078 + { 1079 + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1080 + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1081 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 1082 + struct resource *mem_res; 1083 + unsigned long flags; 1084 + 1085 + spin_lock_irqsave(&sdd->lock, flags); 1086 + sdd->state |= SUSPND; 1087 + spin_unlock_irqrestore(&sdd->lock, flags); 1088 + 1089 + while (sdd->state & SPIBUSY) 1090 + msleep(10); 1091 + 1092 + spi_unregister_master(master); 1093 + 1094 + destroy_workqueue(sdd->workqueue); 1095 + 1096 + if (sci->src_clk != sdd->clk) 1097 + clk_disable(sci->src_clk); 1098 + 1099 + if (sci->src_clk != sdd->clk) 1100 + clk_put(sci->src_clk); 1101 + 1102 + clk_disable(sdd->clk); 1103 + clk_put(sdd->clk); 1104 + 1105 + iounmap((void *) sdd->regs); 1106 + 1107 + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1108 + release_mem_region(mem_res->start, resource_size(mem_res)); 1109 + 1110 + platform_set_drvdata(pdev, NULL); 1111 + spi_master_put(master); 1112 + 1113 + return 0; 1114 + } 1115 + 1116 + #ifdef CONFIG_PM 1117 + static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) 1118 + { 1119 + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1120 + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1121 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 1122 + struct s3c64xx_spi_csinfo *cs; 1123 + unsigned long flags; 1124 + 1125 + spin_lock_irqsave(&sdd->lock, flags); 1126 + sdd->state |= SUSPND; 1127 + spin_unlock_irqrestore(&sdd->lock, flags); 1128 + 1129 + while (sdd->state & SPIBUSY) 1130 + msleep(10); 1131 + 1132 + /* Disable the clock */ 1133 + if (sci->src_clk != sdd->clk) 1134 + clk_disable(sci->src_clk); 1135 + 1136 + clk_disable(sdd->clk); 1137 + 1138 + sdd->cur_speed = 0; /* Output Clock is stopped */ 1139 + 1140 + return 0; 1141 + } 1142 + 1143 + static int s3c64xx_spi_resume(struct platform_device *pdev) 1144 + { 1145 + struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); 1146 + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); 1147 + struct s3c64xx_spi_cntrlr_info *sci = sdd->cntrlr_info; 1148 + unsigned long flags; 1149 + 1150 + sci->cfg_gpio(pdev); 1151 + 1152 + /* Enable the clock */ 1153 + if (sci->src_clk != sdd->clk) 1154 + clk_enable(sci->src_clk); 1155 + 1156 + clk_enable(sdd->clk); 1157 + 1158 + s3c64xx_spi_hwinit(sdd, pdev->id); 1159 + 1160 + spin_lock_irqsave(&sdd->lock, flags); 1161 + sdd->state &= ~SUSPND; 1162 + spin_unlock_irqrestore(&sdd->lock, flags); 1163 + 1164 + return 0; 1165 + } 1166 + #else 1167 + #define s3c64xx_spi_suspend NULL 1168 + #define s3c64xx_spi_resume NULL 1169 + #endif /* CONFIG_PM */ 1170 + 1171 + static struct platform_driver s3c64xx_spi_driver = { 1172 + .driver = { 1173 + .name = "s3c64xx-spi", 1174 + .owner = THIS_MODULE, 1175 + }, 1176 + .remove = s3c64xx_spi_remove, 1177 + .suspend = s3c64xx_spi_suspend, 1178 + .resume = s3c64xx_spi_resume, 1179 + }; 1180 + MODULE_ALIAS("platform:s3c64xx-spi"); 1181 + 1182 + static int __init s3c64xx_spi_init(void) 1183 + { 1184 + return platform_driver_probe(&s3c64xx_spi_driver, s3c64xx_spi_probe); 1185 + } 1186 + module_init(s3c64xx_spi_init); 1187 + 1188 + static void __exit s3c64xx_spi_exit(void) 1189 + { 1190 + platform_driver_unregister(&s3c64xx_spi_driver); 1191 + } 1192 + module_exit(s3c64xx_spi_exit); 1193 + 1194 + MODULE_AUTHOR("Jaswinder Singh <jassi.brar@samsung.com>"); 1195 + MODULE_DESCRIPTION("S3C64XX SPI Controller Driver"); 1196 + MODULE_LICENSE("GPL");
+1 -1
drivers/spi/spi_sh_sci.c
··· 148 148 ret = -ENOENT; 149 149 goto err1; 150 150 } 151 - sp->membase = ioremap(r->start, r->end - r->start + 1); 151 + sp->membase = ioremap(r->start, resource_size(r)); 152 152 if (!sp->membase) { 153 153 ret = -ENXIO; 154 154 goto err1;
+2 -4
drivers/spi/spi_txx9.c
··· 375 375 res = platform_get_resource(dev, IORESOURCE_MEM, 0); 376 376 if (!res) 377 377 goto exit_busy; 378 - if (!devm_request_mem_region(&dev->dev, 379 - res->start, res->end - res->start + 1, 378 + if (!devm_request_mem_region(&dev->dev, res->start, resource_size(res), 380 379 "spi_txx9")) 381 380 goto exit_busy; 382 - c->membase = devm_ioremap(&dev->dev, 383 - res->start, res->end - res->start + 1); 381 + c->membase = devm_ioremap(&dev->dev, res->start, resource_size(res)); 384 382 if (!c->membase) 385 383 goto exit_busy; 386 384
+9 -9
drivers/spi/spidev.c
··· 53 53 #define SPIDEV_MAJOR 153 /* assigned */ 54 54 #define N_SPI_MINORS 32 /* ... up to 256 */ 55 55 56 - static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; 56 + static DECLARE_BITMAP(minors, N_SPI_MINORS); 57 57 58 58 59 59 /* Bit masks for spi_device.mode management. Note that incorrect ··· 558 558 559 559 /*-------------------------------------------------------------------------*/ 560 560 561 - static int spidev_probe(struct spi_device *spi) 561 + static int __devinit spidev_probe(struct spi_device *spi) 562 562 { 563 563 struct spidev_data *spidev; 564 564 int status; ··· 607 607 return status; 608 608 } 609 609 610 - static int spidev_remove(struct spi_device *spi) 610 + static int __devexit spidev_remove(struct spi_device *spi) 611 611 { 612 612 struct spidev_data *spidev = spi_get_drvdata(spi); 613 613 ··· 629 629 return 0; 630 630 } 631 631 632 - static struct spi_driver spidev_spi = { 632 + static struct spi_driver spidev_spi_driver = { 633 633 .driver = { 634 634 .name = "spidev", 635 635 .owner = THIS_MODULE, ··· 661 661 662 662 spidev_class = class_create(THIS_MODULE, "spidev"); 663 663 if (IS_ERR(spidev_class)) { 664 - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 664 + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); 665 665 return PTR_ERR(spidev_class); 666 666 } 667 667 668 - status = spi_register_driver(&spidev_spi); 668 + status = spi_register_driver(&spidev_spi_driver); 669 669 if (status < 0) { 670 670 class_destroy(spidev_class); 671 - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 671 + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); 672 672 } 673 673 return status; 674 674 } ··· 676 676 677 677 static void __exit spidev_exit(void) 678 678 { 679 - spi_unregister_driver(&spidev_spi); 679 + spi_unregister_driver(&spidev_spi_driver); 680 680 class_destroy(spidev_class); 681 - unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); 681 + unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name); 682 682 } 683 683 module_exit(spidev_exit); 684 684
+212
include/linux/spi/dw_spi.h
··· 1 + #ifndef DW_SPI_HEADER_H 2 + #define DW_SPI_HEADER_H 3 + #include <linux/io.h> 4 + 5 + /* Bit fields in CTRLR0 */ 6 + #define SPI_DFS_OFFSET 0 7 + 8 + #define SPI_FRF_OFFSET 4 9 + #define SPI_FRF_SPI 0x0 10 + #define SPI_FRF_SSP 0x1 11 + #define SPI_FRF_MICROWIRE 0x2 12 + #define SPI_FRF_RESV 0x3 13 + 14 + #define SPI_MODE_OFFSET 6 15 + #define SPI_SCPH_OFFSET 6 16 + #define SPI_SCOL_OFFSET 7 17 + #define SPI_TMOD_OFFSET 8 18 + #define SPI_TMOD_TR 0x0 /* xmit & recv */ 19 + #define SPI_TMOD_TO 0x1 /* xmit only */ 20 + #define SPI_TMOD_RO 0x2 /* recv only */ 21 + #define SPI_TMOD_EPROMREAD 0x3 /* eeprom read mode */ 22 + 23 + #define SPI_SLVOE_OFFSET 10 24 + #define SPI_SRL_OFFSET 11 25 + #define SPI_CFS_OFFSET 12 26 + 27 + /* Bit fields in SR, 7 bits */ 28 + #define SR_MASK 0x7f /* cover 7 bits */ 29 + #define SR_BUSY (1 << 0) 30 + #define SR_TF_NOT_FULL (1 << 1) 31 + #define SR_TF_EMPT (1 << 2) 32 + #define SR_RF_NOT_EMPT (1 << 3) 33 + #define SR_RF_FULL (1 << 4) 34 + #define SR_TX_ERR (1 << 5) 35 + #define SR_DCOL (1 << 6) 36 + 37 + /* Bit fields in ISR, IMR, RISR, 7 bits */ 38 + #define SPI_INT_TXEI (1 << 0) 39 + #define SPI_INT_TXOI (1 << 1) 40 + #define SPI_INT_RXUI (1 << 2) 41 + #define SPI_INT_RXOI (1 << 3) 42 + #define SPI_INT_RXFI (1 << 4) 43 + #define SPI_INT_MSTI (1 << 5) 44 + 45 + /* TX RX interrupt level threshhold, max can be 256 */ 46 + #define SPI_INT_THRESHOLD 32 47 + 48 + enum dw_ssi_type { 49 + SSI_MOTO_SPI = 0, 50 + SSI_TI_SSP, 51 + SSI_NS_MICROWIRE, 52 + }; 53 + 54 + struct dw_spi_reg { 55 + u32 ctrl0; 56 + u32 ctrl1; 57 + u32 ssienr; 58 + u32 mwcr; 59 + u32 ser; 60 + u32 baudr; 61 + u32 txfltr; 62 + u32 rxfltr; 63 + u32 txflr; 64 + u32 rxflr; 65 + u32 sr; 66 + u32 imr; 67 + u32 isr; 68 + u32 risr; 69 + u32 txoicr; 70 + u32 rxoicr; 71 + u32 rxuicr; 72 + u32 msticr; 73 + u32 icr; 74 + u32 dmacr; 75 + u32 dmatdlr; 76 + u32 dmardlr; 77 + u32 idr; 78 + u32 version; 79 + u32 dr; /* Currently oper as 32 bits, 80 + though only low 16 bits matters */ 81 + } __packed; 82 + 83 + struct dw_spi { 84 + struct spi_master *master; 85 + struct spi_device *cur_dev; 86 + struct device *parent_dev; 87 + enum dw_ssi_type type; 88 + 89 + void __iomem *regs; 90 + unsigned long paddr; 91 + u32 iolen; 92 + int irq; 93 + u32 max_freq; /* max bus freq supported */ 94 + 95 + u16 bus_num; 96 + u16 num_cs; /* supported slave numbers */ 97 + 98 + /* Driver message queue */ 99 + struct workqueue_struct *workqueue; 100 + struct work_struct pump_messages; 101 + spinlock_t lock; 102 + struct list_head queue; 103 + int busy; 104 + int run; 105 + 106 + /* Message Transfer pump */ 107 + struct tasklet_struct pump_transfers; 108 + 109 + /* Current message transfer state info */ 110 + struct spi_message *cur_msg; 111 + struct spi_transfer *cur_transfer; 112 + struct chip_data *cur_chip; 113 + struct chip_data *prev_chip; 114 + size_t len; 115 + void *tx; 116 + void *tx_end; 117 + void *rx; 118 + void *rx_end; 119 + int dma_mapped; 120 + dma_addr_t rx_dma; 121 + dma_addr_t tx_dma; 122 + size_t rx_map_len; 123 + size_t tx_map_len; 124 + u8 n_bytes; /* current is a 1/2 bytes op */ 125 + u8 max_bits_per_word; /* maxim is 16b */ 126 + u32 dma_width; 127 + int cs_change; 128 + int (*write)(struct dw_spi *dws); 129 + int (*read)(struct dw_spi *dws); 130 + irqreturn_t (*transfer_handler)(struct dw_spi *dws); 131 + void (*cs_control)(u32 command); 132 + 133 + /* Dma info */ 134 + int dma_inited; 135 + struct dma_chan *txchan; 136 + struct dma_chan *rxchan; 137 + int txdma_done; 138 + int rxdma_done; 139 + u64 tx_param; 140 + u64 rx_param; 141 + struct device *dma_dev; 142 + dma_addr_t dma_addr; 143 + 144 + /* Bus interface info */ 145 + void *priv; 146 + #ifdef CONFIG_DEBUG_FS 147 + struct dentry *debugfs; 148 + #endif 149 + }; 150 + 151 + #define dw_readl(dw, name) \ 152 + __raw_readl(&(((struct dw_spi_reg *)dw->regs)->name)) 153 + #define dw_writel(dw, name, val) \ 154 + __raw_writel((val), &(((struct dw_spi_reg *)dw->regs)->name)) 155 + #define dw_readw(dw, name) \ 156 + __raw_readw(&(((struct dw_spi_reg *)dw->regs)->name)) 157 + #define dw_writew(dw, name, val) \ 158 + __raw_writew((val), &(((struct dw_spi_reg *)dw->regs)->name)) 159 + 160 + static inline void spi_enable_chip(struct dw_spi *dws, int enable) 161 + { 162 + dw_writel(dws, ssienr, (enable ? 1 : 0)); 163 + } 164 + 165 + static inline void spi_set_clk(struct dw_spi *dws, u16 div) 166 + { 167 + dw_writel(dws, baudr, div); 168 + } 169 + 170 + static inline void spi_chip_sel(struct dw_spi *dws, u16 cs) 171 + { 172 + if (cs > dws->num_cs) 173 + return; 174 + dw_writel(dws, ser, 1 << cs); 175 + } 176 + 177 + /* Disable IRQ bits */ 178 + static inline void spi_mask_intr(struct dw_spi *dws, u32 mask) 179 + { 180 + u32 new_mask; 181 + 182 + new_mask = dw_readl(dws, imr) & ~mask; 183 + dw_writel(dws, imr, new_mask); 184 + } 185 + 186 + /* Enable IRQ bits */ 187 + static inline void spi_umask_intr(struct dw_spi *dws, u32 mask) 188 + { 189 + u32 new_mask; 190 + 191 + new_mask = dw_readl(dws, imr) | mask; 192 + dw_writel(dws, imr, new_mask); 193 + } 194 + 195 + /* 196 + * Each SPI slave device to work with dw_api controller should 197 + * has such a structure claiming its working mode (PIO/DMA etc), 198 + * which can be save in the "controller_data" member of the 199 + * struct spi_device 200 + */ 201 + struct dw_spi_chip { 202 + u8 poll_mode; /* 0 for contoller polling mode */ 203 + u8 type; /* SPI/SSP/Micrwire */ 204 + u8 enable_dma; 205 + void (*cs_control)(u32 command); 206 + }; 207 + 208 + extern int dw_spi_add_host(struct dw_spi *dws); 209 + extern void dw_spi_remove_host(struct dw_spi *dws); 210 + extern int dw_spi_suspend_host(struct dw_spi *dws); 211 + extern int dw_spi_resume_host(struct dw_spi *dws); 212 + #endif /* DW_SPI_HEADER_H */