1754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen/* 2754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Driver for Atmel AT32 and AT91 SPI Controllers 3754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 4754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Copyright (C) 2006 Atmel Corporation 5754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 6754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * This program is free software; you can redistribute it and/or modify 7754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * it under the terms of the GNU General Public License version 2 as 8754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * published by the Free Software Foundation. 9754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 10754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 11754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/kernel.h> 12754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/init.h> 13754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/clk.h> 14754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/module.h> 15754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/platform_device.h> 16754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/delay.h> 17754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/dma-mapping.h> 18754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/err.h> 19754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/interrupt.h> 20754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <linux/spi/spi.h> 215a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 22754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 23754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#include <asm/io.h> 24a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/board.h> 2560e8972dc7e1df843d7132fb572e74f10502a4b7Russell King#include <asm/gpio.h> 26a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/cpu.h> 27bb2d1c36c7f3a78d482622289c8de0c1a5fe790fDavid Brownell 28ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* SPI register offsets */ 29ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CR 0x0000 30ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MR 0x0004 31ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RDR 0x0008 32ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TDR 0x000c 33ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SR 0x0010 34ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_IER 0x0014 35ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_IDR 0x0018 36ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_IMR 0x001c 37ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CSR0 0x0030 38ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CSR1 0x0034 39ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CSR2 0x0038 40ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CSR3 0x003c 41ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RPR 0x0100 42ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RCR 0x0104 43ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TPR 0x0108 44ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TCR 0x010c 45ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RNPR 0x0110 46ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RNCR 0x0114 47ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TNPR 0x0118 48ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TNCR 0x011c 49ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PTCR 0x0120 50ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PTSR 0x0124 51ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 52ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in CR */ 53ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SPIEN_OFFSET 0 54ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SPIEN_SIZE 1 55ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SPIDIS_OFFSET 1 56ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SPIDIS_SIZE 1 57ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SWRST_OFFSET 7 58ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SWRST_SIZE 1 59ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_LASTXFER_OFFSET 24 60ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_LASTXFER_SIZE 1 61ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 62ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in MR */ 63ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MSTR_OFFSET 0 64ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MSTR_SIZE 1 65ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PS_OFFSET 1 66ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PS_SIZE 1 67ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PCSDEC_OFFSET 2 68ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PCSDEC_SIZE 1 69ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_FDIV_OFFSET 3 70ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_FDIV_SIZE 1 71ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MODFDIS_OFFSET 4 72ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MODFDIS_SIZE 1 73ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_LLB_OFFSET 7 74ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_LLB_SIZE 1 75ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PCS_OFFSET 16 76ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_PCS_SIZE 4 77ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_DLYBCS_OFFSET 24 78ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_DLYBCS_SIZE 8 79ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 80ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in RDR */ 81ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RD_OFFSET 0 82ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RD_SIZE 16 83ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 84ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in TDR */ 85ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TD_OFFSET 0 86ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TD_SIZE 16 87ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 88ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in SR */ 89ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RDRF_OFFSET 0 90ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RDRF_SIZE 1 91ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TDRE_OFFSET 1 92ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TDRE_SIZE 1 93ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MODF_OFFSET 2 94ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_MODF_SIZE 1 95ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_OVRES_OFFSET 3 96ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_OVRES_SIZE 1 97ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_ENDRX_OFFSET 4 98ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_ENDRX_SIZE 1 99ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_ENDTX_OFFSET 5 100ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_ENDTX_SIZE 1 101ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXBUFF_OFFSET 6 102ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXBUFF_SIZE 1 103ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXBUFE_OFFSET 7 104ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXBUFE_SIZE 1 105ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_NSSR_OFFSET 8 106ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_NSSR_SIZE 1 107ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXEMPTY_OFFSET 9 108ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXEMPTY_SIZE 1 109ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SPIENS_OFFSET 16 110ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SPIENS_SIZE 1 111ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 112ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in CSR0 */ 113ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CPOL_OFFSET 0 114ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CPOL_SIZE 1 115ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_NCPHA_OFFSET 1 116ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_NCPHA_SIZE 1 117ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CSAAT_OFFSET 3 118ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_CSAAT_SIZE 1 119ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_OFFSET 4 120ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_SIZE 4 121ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SCBR_OFFSET 8 122ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_SCBR_SIZE 8 123ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_DLYBS_OFFSET 16 124ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_DLYBS_SIZE 8 125ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_DLYBCT_OFFSET 24 126ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_DLYBCT_SIZE 8 127ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 128ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in RCR */ 129ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXCTR_OFFSET 0 130ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXCTR_SIZE 16 131ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 132ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in TCR */ 133ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXCTR_OFFSET 0 134ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXCTR_SIZE 16 135ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 136ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in RNCR */ 137ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXNCR_OFFSET 0 138ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXNCR_SIZE 16 139ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 140ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in TNCR */ 141ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXNCR_OFFSET 0 142ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXNCR_SIZE 16 143ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 144ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bitfields in PTCR */ 145ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXTEN_OFFSET 0 146ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXTEN_SIZE 1 147ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXTDIS_OFFSET 1 148ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_RXTDIS_SIZE 1 149ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXTEN_OFFSET 8 150ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXTEN_SIZE 1 151ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXTDIS_OFFSET 9 152ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_TXTDIS_SIZE 1 153ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 154ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Constants for BITS */ 155ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_8_BPT 0 156ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_9_BPT 1 157ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_10_BPT 2 158ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_11_BPT 3 159ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_12_BPT 4 160ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_13_BPT 5 161ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_14_BPT 6 162ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_15_BPT 7 163ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BITS_16_BPT 8 164ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 165ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Bit manipulation macros */ 166ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BIT(name) \ 167ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely (1 << SPI_##name##_OFFSET) 168ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BF(name,value) \ 169ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely (((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET) 170ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BFEXT(name,value) \ 171ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely (((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1)) 172ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define SPI_BFINS(name,value,old) \ 173ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely ( ((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \ 174ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely | SPI_BF(name,value)) 175ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 176ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely/* Register access macros */ 177ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define spi_readl(port,reg) \ 178ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely __raw_readl((port)->regs + SPI_##reg) 179ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely#define spi_writel(port,reg,value) \ 180ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely __raw_writel((value), (port)->regs + SPI_##reg) 181ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely 182754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 183754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen/* 184754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * The core SPI transfer engine just talks to a register bank to set up 185754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * DMA transfers; transfer queue progress is driven by IRQs. The clock 186754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * framework provides the base clock, subdivided for each spi_device. 187754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 188754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstruct atmel_spi { 189754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spinlock_t lock; 190754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 191754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen void __iomem *regs; 192754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen int irq; 193754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct clk *clk; 194754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct platform_device *pdev; 195defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell struct spi_device *stay; 196754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 197754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen u8 stopping; 198754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct list_head queue; 199754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_transfer *current_transfer; 200154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg unsigned long current_remaining_bytes; 201154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct spi_transfer *next_transfer; 202154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg unsigned long next_remaining_bytes; 203754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 204754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen void *buffer; 205754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dma_addr_t buffer_dma; 206754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen}; 207754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 2085ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen/* Controller-specific per-slave state */ 2095ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoenstruct atmel_spi_device { 2105ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen unsigned int npcs_pin; 2115ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen u32 csr; 2125ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen}; 2135ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen 214754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#define BUFFER_SIZE PAGE_SIZE 215754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#define INVALID_DMA_ADDRESS 0xffffffff 216754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 217754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen/* 2185bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * Version 2 of the SPI controller has 2195bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * - CR.LASTXFER 2205bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) 2215bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) 2225bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * - SPI_CSRx.CSAAT 2235bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * - SPI_CSRx.SBCR allows faster clocking 2245bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * 2255bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * We can determine the controller version by reading the VERSION 2265bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * register, but I haven't checked that it exists on all chips, and 2275bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen * this is cheaper anyway. 2285bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen */ 2295bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoenstatic bool atmel_spi_is_v2(void) 2305bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen{ 2315bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen return !cpu_is_at91rm9200(); 2325bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen} 2335bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen 2345bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen/* 235754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby 236754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * they assume that spi slave device state will not change on deselect, so 237defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * that automagic deselection is OK. ("NPCSx rises if no data is to be 238defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * transmitted") Not so! Workaround uses nCSx pins as GPIOs; or newer 239defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * controllers have CSAAT and friends. 240754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 241defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * Since the CSAAT functionality is a bit weird on newer controllers as 242defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * well, we use GPIO to control nCSx pins on all controllers, updating 243defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * MR.PCS to avoid confusing the controller. Using GPIOs also lets us 244defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * support active-high chipselects despite the controller's belief that 245defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * only active-low devices/systems exists. 246defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * 247defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * However, at91rm9200 has a second erratum whereby nCS0 doesn't work 248defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * right when driven with GPIO. ("Mode Fault does not allow more than one 249defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * Master on Chip Select 0.") No workaround exists for that ... so for 250defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH, 251defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * and (c) will trigger that first erratum in some cases. 2525ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * 2535ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * TODO: Test if the atmel_spi_is_v2() branch below works on 2545ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * AT91RM9200 if we use some other register than CSR0. However, don't 2555ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * do this unconditionally since AP7000 has an errata where the BITS 2565ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * field in CSR0 overrides all other CSRs. 257754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 258754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 259defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownellstatic void cs_activate(struct atmel_spi *as, struct spi_device *spi) 260754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 2615ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen struct atmel_spi_device *asd = spi->controller_state; 262754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen unsigned active = spi->mode & SPI_CS_HIGH; 263defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell u32 mr; 264defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 2655ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (atmel_spi_is_v2()) { 2665ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen /* 2675ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * Always use CSR0. This ensures that the clock 2685ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * switches to the correct idle polarity before we 2695ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen * toggle the CS. 2705ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen */ 2715ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi_writel(as, CSR0, asd->csr); 2725ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi_writel(as, MR, SPI_BF(PCS, 0x0e) | SPI_BIT(MODFDIS) 2735ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen | SPI_BIT(MSTR)); 2745ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen mr = spi_readl(as, MR); 2755ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen gpio_set_value(asd->npcs_pin, active); 2765ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen } else { 2775ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; 2785ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen int i; 2795ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen u32 csr; 2805ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen 2815ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen /* Make sure clock polarity is correct */ 2825ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen for (i = 0; i < spi->master->num_chipselect; i++) { 2835ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen csr = spi_readl(as, CSR0 + 4 * i); 2845ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if ((csr ^ cpol) & SPI_BIT(CPOL)) 2855ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi_writel(as, CSR0 + 4 * i, 2865ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen csr ^ SPI_BIT(CPOL)); 2875ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen } 2885ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen 2895ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen mr = spi_readl(as, MR); 2905ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); 2915ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (spi->chip_select != 0) 2925ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen gpio_set_value(asd->npcs_pin, active); 2935ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi_writel(as, MR, mr); 2945ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen } 295defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 296defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell dev_dbg(&spi->dev, "activate %u%s, mr %08x\n", 2975ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen asd->npcs_pin, active ? " (high)" : "", 298defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell mr); 299754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 300754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 301defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownellstatic void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) 302754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 3035ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen struct atmel_spi_device *asd = spi->controller_state; 304754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen unsigned active = spi->mode & SPI_CS_HIGH; 305defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell u32 mr; 306defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 307defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell /* only deactivate *this* device; sometimes transfers to 308defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell * another device may be active when this routine is called. 309defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell */ 310defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell mr = spi_readl(as, MR); 311defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell if (~SPI_BFEXT(PCS, mr) & (1 << spi->chip_select)) { 312defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell mr = SPI_BFINS(PCS, 0xf, mr); 313defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell spi_writel(as, MR, mr); 314defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell } 315754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 316defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n", 3175ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen asd->npcs_pin, active ? " (low)" : "", 318defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell mr); 319defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 3205bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen if (atmel_spi_is_v2() || spi->chip_select != 0) 3215ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen gpio_set_value(asd->npcs_pin, !active); 322754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 323754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 324154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdegstatic inline int atmel_spi_xfer_is_last(struct spi_message *msg, 325154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct spi_transfer *xfer) 326154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg{ 327154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg return msg->transfers.prev == &xfer->transfer_list; 328154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg} 329154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 330154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdegstatic inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) 331154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg{ 332154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg return xfer->delay_usecs == 0 && !xfer->cs_change; 333154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg} 334154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 335154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdegstatic void atmel_spi_next_xfer_data(struct spi_master *master, 336154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct spi_transfer *xfer, 337154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg dma_addr_t *tx_dma, 338154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg dma_addr_t *rx_dma, 339154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg u32 *plen) 340154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg{ 341154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct atmel_spi *as = spi_master_get_devdata(master); 342154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg u32 len = *plen; 343154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 344154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg /* use scratch buffer only when rx or tx data is unspecified */ 345154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (xfer->rx_buf) 3466aed4ee9b4610cd1e0315c90855b32e59ee81a15Ben Nizette *rx_dma = xfer->rx_dma + xfer->len - *plen; 347154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg else { 348154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg *rx_dma = as->buffer_dma; 349154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (len > BUFFER_SIZE) 350154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len = BUFFER_SIZE; 351154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg } 352154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (xfer->tx_buf) 3536aed4ee9b4610cd1e0315c90855b32e59ee81a15Ben Nizette *tx_dma = xfer->tx_dma + xfer->len - *plen; 354154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg else { 355154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg *tx_dma = as->buffer_dma; 356154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (len > BUFFER_SIZE) 357154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len = BUFFER_SIZE; 358154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg memset(as->buffer, 0, len); 359154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg dma_sync_single_for_device(&as->pdev->dev, 360154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg as->buffer_dma, len, DMA_TO_DEVICE); 361154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg } 362154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 363154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg *plen = len; 364154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg} 365154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 366754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen/* 367754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Submit next transfer for DMA. 368754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * lock is held, spi irq is blocked 369754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 370754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic void atmel_spi_next_xfer(struct spi_master *master, 371754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_message *msg) 372754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 373754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as = spi_master_get_devdata(master); 374754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_transfer *xfer; 375dc329442b9fd365bec95718013586c07ff600c34Gerard Kam u32 len, remaining; 376dc329442b9fd365bec95718013586c07ff600c34Gerard Kam u32 ieval; 377754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dma_addr_t tx_dma, rx_dma; 378754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 379154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (!as->current_transfer) 380154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg xfer = list_entry(msg->transfers.next, 381154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct spi_transfer, transfer_list); 382154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg else if (!as->next_transfer) 383154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg xfer = list_entry(as->current_transfer->transfer_list.next, 384154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct spi_transfer, transfer_list); 385154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg else 386154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg xfer = NULL; 387154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 388154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (xfer) { 389dc329442b9fd365bec95718013586c07ff600c34Gerard Kam spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); 390dc329442b9fd365bec95718013586c07ff600c34Gerard Kam 391154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len = xfer->len; 392154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); 393154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg remaining = xfer->len - len; 394154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 395154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, RPR, rx_dma); 396154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, TPR, tx_dma); 397154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 398154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (msg->spi->bits_per_word > 8) 399154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len >>= 1; 400154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, RCR, len); 401154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, TCR, len); 4028bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen 4038bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen dev_dbg(&msg->spi->dev, 4048bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen " start xfer %p: len %u tx %p/%08x rx %p/%08x\n", 4058bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, 4068bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen xfer->rx_buf, xfer->rx_dma); 407154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg } else { 408154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg xfer = as->next_transfer; 409154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg remaining = as->next_remaining_bytes; 410754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 411754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 412154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg as->current_transfer = xfer; 413154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg as->current_remaining_bytes = remaining; 414754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 415154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (remaining > 0) 416154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len = remaining; 4178bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen else if (!atmel_spi_xfer_is_last(msg, xfer) 4188bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen && atmel_spi_xfer_can_be_chained(xfer)) { 419154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg xfer = list_entry(xfer->transfer_list.next, 420154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg struct spi_transfer, transfer_list); 421154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len = xfer->len; 422154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg } else 423154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg xfer = NULL; 424754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 425154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg as->next_transfer = xfer; 426754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 427154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (xfer) { 428dc329442b9fd365bec95718013586c07ff600c34Gerard Kam u32 total; 429dc329442b9fd365bec95718013586c07ff600c34Gerard Kam 430154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg total = len; 431154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); 432154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg as->next_remaining_bytes = total - len; 433754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 434154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, RNPR, rx_dma); 435154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, TNPR, tx_dma); 436754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 437154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (msg->spi->bits_per_word > 8) 438154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg len >>= 1; 439154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, RNCR, len); 440154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, TNCR, len); 4418bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen 4428bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen dev_dbg(&msg->spi->dev, 4438bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen " next xfer %p: len %u tx %p/%08x rx %p/%08x\n", 4448bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, 4458bacb219018a52e6f02a3cff6a7badf102ddfc44Haavard Skinnemoen xfer->rx_buf, xfer->rx_dma); 446dc329442b9fd365bec95718013586c07ff600c34Gerard Kam ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); 447154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg } else { 448154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, RNCR, 0); 449154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg spi_writel(as, TNCR, 0); 450dc329442b9fd365bec95718013586c07ff600c34Gerard Kam ieval = SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) | SPI_BIT(OVRES); 451154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg } 452154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg 453154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg /* REVISIT: We're waiting for ENDRX before we start the next 454754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * transfer because we need to handle some difficult timing 455754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * issues otherwise. If we wait for ENDTX in one transfer and 456754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * then starts waiting for ENDRX in the next, it's difficult 457754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * to tell the difference between the ENDRX interrupt we're 458754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * actually waiting for and the ENDRX interrupt of the 459754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * previous transfer. 460754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 461754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * It should be doable, though. Just not now... 462754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 463dc329442b9fd365bec95718013586c07ff600c34Gerard Kam spi_writel(as, IER, ieval); 464754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); 465754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 466754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 467754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic void atmel_spi_next_message(struct spi_master *master) 468754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 469754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as = spi_master_get_devdata(master); 470754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_message *msg; 471defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell struct spi_device *spi; 472754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 473754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen BUG_ON(as->current_transfer); 474754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 475754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg = list_entry(as->queue.next, struct spi_message, queue); 476defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell spi = msg->spi; 477754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 47849dce689ad4ef0fd1f970ef762168e4bd46f69a3Tony Jones dev_dbg(master->dev.parent, "start message %p for %s\n", 4796c7377ab6814c247d7600955a4ead2e3db490697Kay Sievers msg, dev_name(&spi->dev)); 480defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 481defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell /* select chip if it's not still active */ 482defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell if (as->stay) { 483defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell if (as->stay != spi) { 484defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_deactivate(as, as->stay); 485defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_activate(as, spi); 486defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell } 487defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell as->stay = NULL; 488defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell } else 489defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_activate(as, spi); 490754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 491754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_next_xfer(master, msg); 492754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 493754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 4948da0859a246838c81fe57d952b91d419e9c44179David Brownell/* 4958da0859a246838c81fe57d952b91d419e9c44179David Brownell * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma: 4968da0859a246838c81fe57d952b91d419e9c44179David Brownell * - The buffer is either valid for CPU access, else NULL 497b595076a180a56d1bb170e6eceda6eb9d76f4cd3Uwe Kleine-König * - If the buffer is valid, so is its DMA address 4988da0859a246838c81fe57d952b91d419e9c44179David Brownell * 499b595076a180a56d1bb170e6eceda6eb9d76f4cd3Uwe Kleine-König * This driver manages the dma address unless message->is_dma_mapped. 5008da0859a246838c81fe57d952b91d419e9c44179David Brownell */ 5018da0859a246838c81fe57d952b91d419e9c44179David Brownellstatic int 502754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenatmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) 503754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 5048da0859a246838c81fe57d952b91d419e9c44179David Brownell struct device *dev = &as->pdev->dev; 5058da0859a246838c81fe57d952b91d419e9c44179David Brownell 506754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS; 5078da0859a246838c81fe57d952b91d419e9c44179David Brownell if (xfer->tx_buf) { 508214b574ab81236e7740243985d63a1d6a61231a2Jean-Christophe PLAGNIOL-VILLARD /* tx_buf is a const void* where we need a void * for the dma 509214b574ab81236e7740243985d63a1d6a61231a2Jean-Christophe PLAGNIOL-VILLARD * mapping */ 510214b574ab81236e7740243985d63a1d6a61231a2Jean-Christophe PLAGNIOL-VILLARD void *nonconst_tx = (void *)xfer->tx_buf; 511214b574ab81236e7740243985d63a1d6a61231a2Jean-Christophe PLAGNIOL-VILLARD 5128da0859a246838c81fe57d952b91d419e9c44179David Brownell xfer->tx_dma = dma_map_single(dev, 513214b574ab81236e7740243985d63a1d6a61231a2Jean-Christophe PLAGNIOL-VILLARD nonconst_tx, xfer->len, 514754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen DMA_TO_DEVICE); 5158d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06FUJITA Tomonori if (dma_mapping_error(dev, xfer->tx_dma)) 5168da0859a246838c81fe57d952b91d419e9c44179David Brownell return -ENOMEM; 5178da0859a246838c81fe57d952b91d419e9c44179David Brownell } 5188da0859a246838c81fe57d952b91d419e9c44179David Brownell if (xfer->rx_buf) { 5198da0859a246838c81fe57d952b91d419e9c44179David Brownell xfer->rx_dma = dma_map_single(dev, 520754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer->rx_buf, xfer->len, 521754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen DMA_FROM_DEVICE); 5228d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06FUJITA Tomonori if (dma_mapping_error(dev, xfer->rx_dma)) { 5238da0859a246838c81fe57d952b91d419e9c44179David Brownell if (xfer->tx_buf) 5248da0859a246838c81fe57d952b91d419e9c44179David Brownell dma_unmap_single(dev, 5258da0859a246838c81fe57d952b91d419e9c44179David Brownell xfer->tx_dma, xfer->len, 5268da0859a246838c81fe57d952b91d419e9c44179David Brownell DMA_TO_DEVICE); 5278da0859a246838c81fe57d952b91d419e9c44179David Brownell return -ENOMEM; 5288da0859a246838c81fe57d952b91d419e9c44179David Brownell } 5298da0859a246838c81fe57d952b91d419e9c44179David Brownell } 5308da0859a246838c81fe57d952b91d419e9c44179David Brownell return 0; 531754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 532754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 533754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic void atmel_spi_dma_unmap_xfer(struct spi_master *master, 534754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_transfer *xfer) 535754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 536754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (xfer->tx_dma != INVALID_DMA_ADDRESS) 53749dce689ad4ef0fd1f970ef762168e4bd46f69a3Tony Jones dma_unmap_single(master->dev.parent, xfer->tx_dma, 538754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer->len, DMA_TO_DEVICE); 539754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (xfer->rx_dma != INVALID_DMA_ADDRESS) 54049dce689ad4ef0fd1f970ef762168e4bd46f69a3Tony Jones dma_unmap_single(master->dev.parent, xfer->rx_dma, 541754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer->len, DMA_FROM_DEVICE); 542754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 543754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 544754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic void 545754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenatmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as, 546defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell struct spi_message *msg, int status, int stay) 547754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 548defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell if (!stay || status < 0) 549defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_deactivate(as, msg->spi); 550defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell else 551defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell as->stay = msg->spi; 552defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 553754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen list_del(&msg->queue); 554754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->status = status; 555754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 55649dce689ad4ef0fd1f970ef762168e4bd46f69a3Tony Jones dev_dbg(master->dev.parent, 557754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen "xfer complete: %u bytes transferred\n", 558754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->actual_length); 559754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 560754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_unlock(&as->lock); 561754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->complete(msg->context); 562754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_lock(&as->lock); 563754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 564754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->current_transfer = NULL; 565154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg as->next_transfer = NULL; 566754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 567754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* continue if needed */ 568754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (list_empty(&as->queue) || as->stopping) 569754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); 570754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen else 571754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_next_message(master); 572754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 573754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 574754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic irqreturn_t 575754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenatmel_spi_interrupt(int irq, void *dev_id) 576754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 577754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_master *master = dev_id; 578754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as = spi_master_get_devdata(master); 579754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_message *msg; 580754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_transfer *xfer; 581754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen u32 status, pending, imr; 582754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen int ret = IRQ_NONE; 583754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 584754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_lock(&as->lock); 585754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 586754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer = as->current_transfer; 587754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg = list_entry(as->queue.next, struct spi_message, queue); 588754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 589754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen imr = spi_readl(as, IMR); 590754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen status = spi_readl(as, SR); 591754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen pending = status & imr; 592754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 593754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (pending & SPI_BIT(OVRES)) { 594754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen int timeout; 595754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 596754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen ret = IRQ_HANDLED; 597754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 598dc329442b9fd365bec95718013586c07ff600c34Gerard Kam spi_writel(as, IDR, (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) 599754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen | SPI_BIT(OVRES))); 600754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 601754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* 602754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * When we get an overrun, we disregard the current 603754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * transfer. Data will not be copied back from any 604754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * bounce buffer and msg->actual_len will not be 605754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * updated with the last xfer. 606754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 607754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * We will also not process any remaning transfers in 608754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * the message. 609754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 610754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * First, stop the transfer and unmap the DMA buffers. 611754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 612754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); 613754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!msg->is_dma_mapped) 614754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_dma_unmap_xfer(master, xfer); 615754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 616754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* REVISIT: udelay in irq is unfriendly */ 617754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (xfer->delay_usecs) 618754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen udelay(xfer->delay_usecs); 619754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 620dc329442b9fd365bec95718013586c07ff600c34Gerard Kam dev_warn(master->dev.parent, "overrun (%u/%u remaining)\n", 621754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_readl(as, TCR), spi_readl(as, RCR)); 622754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 623754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* 624754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Clean up DMA registers and make sure the data 625754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * registers are empty. 626754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 627754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, RNCR, 0); 628754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, TNCR, 0); 629754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, RCR, 0); 630754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, TCR, 0); 631754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen for (timeout = 1000; timeout; timeout--) 632754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (spi_readl(as, SR) & SPI_BIT(TXEMPTY)) 633754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen break; 634754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!timeout) 63549dce689ad4ef0fd1f970ef762168e4bd46f69a3Tony Jones dev_warn(master->dev.parent, 636754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen "timeout waiting for TXEMPTY"); 637754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen while (spi_readl(as, SR) & SPI_BIT(RDRF)) 638754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_readl(as, RDR); 639754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 640754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* Clear any overrun happening while cleaning up */ 641754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_readl(as, SR); 642754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 643defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell atmel_spi_msg_done(master, as, msg, -EIO, 0); 644dc329442b9fd365bec95718013586c07ff600c34Gerard Kam } else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) { 645754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen ret = IRQ_HANDLED; 646754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 647754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, IDR, pending); 648754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 649154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (as->current_remaining_bytes == 0) { 650754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->actual_length += xfer->len; 651754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 652754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!msg->is_dma_mapped) 653754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_dma_unmap_xfer(master, xfer); 654754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 655754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* REVISIT: udelay in irq is unfriendly */ 656754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (xfer->delay_usecs) 657754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen udelay(xfer->delay_usecs); 658754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 659154443c72f47169ebcb3a7befbff0e934c49bff3Silvester Erdeg if (atmel_spi_xfer_is_last(msg, xfer)) { 660754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* report completed message */ 661defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell atmel_spi_msg_done(master, as, msg, 0, 662defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell xfer->cs_change); 663754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } else { 664754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (xfer->cs_change) { 665defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_deactivate(as, msg->spi); 666754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen udelay(1); 667defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_activate(as, msg->spi); 668754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 669754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 670754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* 671754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Not done yet. Submit the next transfer. 672754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * 673754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * FIXME handle protocol options for xfer 674754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 675754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_next_xfer(master, msg); 676754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 677754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } else { 678754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* 679754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * Keep going, we still have data to send in 680754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * the current transfer. 681754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 682754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_next_xfer(master, msg); 683754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 684754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 685754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 686754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_unlock(&as->lock); 687754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 688754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return ret; 689754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 690754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 691754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic int atmel_spi_setup(struct spi_device *spi) 692754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 693754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as; 6945ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen struct atmel_spi_device *asd; 695754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen u32 scbr, csr; 696754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen unsigned int bits = spi->bits_per_word; 697592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen unsigned long bus_hz; 698754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen unsigned int npcs_pin; 699754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen int ret; 700754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 701754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as = spi_master_get_devdata(spi->master); 702754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 703754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (as->stopping) 704754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -ESHUTDOWN; 705754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 706754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (spi->chip_select > spi->master->num_chipselect) { 707754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(&spi->dev, 708754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen "setup: invalid chipselect %u (%u defined)\n", 709754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi->chip_select, spi->master->num_chipselect); 710754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -EINVAL; 711754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 712754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 713754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (bits < 8 || bits > 16) { 714754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(&spi->dev, 715754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen "setup: invalid bits_per_word %u (8 to 16)\n", 716754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen bits); 717754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -EINVAL; 718754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 719754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 720defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell /* see notes above re chipselect */ 7215bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen if (!atmel_spi_is_v2() 722defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell && spi->chip_select == 0 723defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell && (spi->mode & SPI_CS_HIGH)) { 724defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell dev_dbg(&spi->dev, "setup: can't be active-high\n"); 725defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell return -EINVAL; 726defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell } 727defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 7285bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen /* v1 chips start out at half the peripheral bus speed. */ 729754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen bus_hz = clk_get_rate(as->clk); 7305bfa26ca1332780dfeeabafd7f169fc6fb48ba30Haavard Skinnemoen if (!atmel_spi_is_v2()) 731592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen bus_hz /= 2; 732592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen 733754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (spi->max_speed_hz) { 734592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen /* 735592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen * Calculate the lowest divider that satisfies the 736592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen * constraint, assuming div32/fdiv/mbz == 0. 737592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen */ 738592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz); 739592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen 740592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen /* 741592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen * If the resulting divider doesn't fit into the 742592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen * register bitfield, we can't satisfy the constraint. 743592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen */ 744754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (scbr >= (1 << SPI_SCBR_SIZE)) { 7458da0859a246838c81fe57d952b91d419e9c44179David Brownell dev_dbg(&spi->dev, 7468da0859a246838c81fe57d952b91d419e9c44179David Brownell "setup: %d Hz too slow, scbr %u; min %ld Hz\n", 7478da0859a246838c81fe57d952b91d419e9c44179David Brownell spi->max_speed_hz, scbr, bus_hz/255); 748754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -EINVAL; 749754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 750754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } else 751592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen /* speed zero means "as slow as possible" */ 752754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen scbr = 0xff; 753754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 754754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8); 755754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (spi->mode & SPI_CPOL) 756754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen csr |= SPI_BIT(CPOL); 757754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!(spi->mode & SPI_CPHA)) 758754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen csr |= SPI_BIT(NCPHA); 759754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 7601eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen /* DLYBS is mostly irrelevant since we manage chipselect using GPIOs. 7611eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen * 7621eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen * DLYBCT would add delays between words, slowing down transfers. 7631eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen * It could potentially be useful to cope with DMA bottlenecks, but 7641eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen * in those cases it's probably best to just use a lower bitrate. 7651eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen */ 7661eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen csr |= SPI_BF(DLYBS, 0); 7671eed29df472a33bba013d5a2ea2f9e32f4414397Haavard Skinnemoen csr |= SPI_BF(DLYBCT, 0); 768754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 769754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* chipselect must have been muxed as GPIO (e.g. in board setup) */ 770754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen npcs_pin = (unsigned int)spi->controller_data; 7715ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen asd = spi->controller_state; 7725ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (!asd) { 7735ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL); 7745ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (!asd) 7755ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen return -ENOMEM; 7765ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen 7776c7377ab6814c247d7600955a4ead2e3db490697Kay Sievers ret = gpio_request(npcs_pin, dev_name(&spi->dev)); 7785ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (ret) { 7795ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen kfree(asd); 780754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return ret; 7815ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen } 7825ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen 7835ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen asd->npcs_pin = npcs_pin; 7845ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi->controller_state = asd; 78528735a7253a6c24364765e80a5428b4a151fccc2David Brownell gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); 786defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell } else { 787defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell unsigned long flags; 788defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 789defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell spin_lock_irqsave(&as->lock, flags); 790defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell if (as->stay == spi) 791defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell as->stay = NULL; 792defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_deactivate(as, spi); 793defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell spin_unlock_irqrestore(&as->lock, flags); 794754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 795754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 7965ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen asd->csr = csr; 7975ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen 798754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(&spi->dev, 799754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", 800592e7bf80566bf5ac3ed073d4e198dd5b0824c04Haavard Skinnemoen bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); 801754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 8025ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (!atmel_spi_is_v2()) 8035ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi_writel(as, CSR0 + 4 * spi->chip_select, csr); 804754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 805754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return 0; 806754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 807754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 808754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) 809754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 810754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as; 811754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_transfer *xfer; 812754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen unsigned long flags; 81349dce689ad4ef0fd1f970ef762168e4bd46f69a3Tony Jones struct device *controller = spi->master->dev.parent; 814b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger u8 bits; 815b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger struct atmel_spi_device *asd; 816754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 817754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as = spi_master_get_devdata(spi->master); 818754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 819754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(controller, "new message %p submitted for %s\n", 8206c7377ab6814c247d7600955a4ead2e3db490697Kay Sievers msg, dev_name(&spi->dev)); 821754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 8225b96f1729064453e09805a387378e0644da1c937Stanislaw Gruszka if (unlikely(list_empty(&msg->transfers))) 823754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -EINVAL; 824754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 825754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (as->stopping) 826754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -ESHUTDOWN; 827754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 828754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen list_for_each_entry(xfer, &msg->transfers, transfer_list) { 82906719814780da741e7acf587367a86c3965c03a2Atsushi Nemoto if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) { 830754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(&spi->dev, "missing rx or tx buf\n"); 831754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -EINVAL; 832754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 833754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 834b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger if (xfer->bits_per_word) { 835b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger asd = spi->controller_state; 836b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger bits = (asd->csr >> 4) & 0xf; 837b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger if (bits != xfer->bits_per_word - 8) { 838b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger dev_dbg(&spi->dev, "you can't yet change " 839ee2007d299ad4020115b193858817e6c57e95db5Matthias Brugger "bits_per_word in transfers\n"); 840b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger return -ENOPROTOOPT; 841b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger } 842b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger } 843b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger 844754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* FIXME implement these protocol options!! */ 845b9d228f9e896df1af787b2f3467889ab0832370aMatthias Brugger if (xfer->speed_hz) { 846754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(&spi->dev, "no protocol options yet\n"); 847754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -ENOPROTOOPT; 848754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 849754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 8508da0859a246838c81fe57d952b91d419e9c44179David Brownell /* 8518da0859a246838c81fe57d952b91d419e9c44179David Brownell * DMA map early, for performance (empties dcache ASAP) and 8528da0859a246838c81fe57d952b91d419e9c44179David Brownell * better fault reporting. This is a DMA-only driver. 8538da0859a246838c81fe57d952b91d419e9c44179David Brownell * 8548da0859a246838c81fe57d952b91d419e9c44179David Brownell * NOTE that if dma_unmap_single() ever starts to do work on 8558da0859a246838c81fe57d952b91d419e9c44179David Brownell * platforms supported by this driver, we would need to clean 8568da0859a246838c81fe57d952b91d419e9c44179David Brownell * up mappings for previously-mapped transfers. 8578da0859a246838c81fe57d952b91d419e9c44179David Brownell */ 8588da0859a246838c81fe57d952b91d419e9c44179David Brownell if (!msg->is_dma_mapped) { 8598da0859a246838c81fe57d952b91d419e9c44179David Brownell if (atmel_spi_dma_map_xfer(as, xfer) < 0) 8608da0859a246838c81fe57d952b91d419e9c44179David Brownell return -ENOMEM; 8618da0859a246838c81fe57d952b91d419e9c44179David Brownell } 862754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 863754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 864defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell#ifdef VERBOSE 865754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen list_for_each_entry(xfer, &msg->transfers, transfer_list) { 866754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_dbg(controller, 867754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen " xfer %p: len %u tx %p/%08x rx %p/%08x\n", 868754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer, xfer->len, 869754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer->tx_buf, xfer->tx_dma, 870754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen xfer->rx_buf, xfer->rx_dma); 871754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 872defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell#endif 873754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 874754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->status = -EINPROGRESS; 875754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->actual_length = 0; 876754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 877754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_lock_irqsave(&as->lock, flags); 878754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen list_add_tail(&msg->queue, &as->queue); 879754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!as->current_transfer) 880754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen atmel_spi_next_message(spi->master); 881754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_unlock_irqrestore(&as->lock, flags); 882754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 883754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return 0; 884754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 885754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 886bb2d1c36c7f3a78d482622289c8de0c1a5fe790fDavid Brownellstatic void atmel_spi_cleanup(struct spi_device *spi) 887754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 888defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell struct atmel_spi *as = spi_master_get_devdata(spi->master); 8895ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen struct atmel_spi_device *asd = spi->controller_state; 890defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell unsigned gpio = (unsigned) spi->controller_data; 891defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell unsigned long flags; 892defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 8935ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen if (!asd) 894defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell return; 895defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 896defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell spin_lock_irqsave(&as->lock, flags); 897defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell if (as->stay == spi) { 898defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell as->stay = NULL; 899defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell cs_deactivate(as, spi); 900defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell } 901defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell spin_unlock_irqrestore(&as->lock, flags); 902defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell 9035ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen spi->controller_state = NULL; 904defbd3b4bbd9d85a68529f829f4ee39899c318dcDavid Brownell gpio_free(gpio); 9055ee36c989831ab720eee282521462cce0a3c4900Haavard Skinnemoen kfree(asd); 906754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 907754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 908754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen/*-------------------------------------------------------------------------*/ 909754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 9101cb201af626eedf0ff78cc1712c731b463994c60Jean-Christophe PLAGNIOL-VILLARDstatic int __devinit atmel_spi_probe(struct platform_device *pdev) 911754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 912754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct resource *regs; 913754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen int irq; 914754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct clk *clk; 915754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen int ret; 916754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_master *master; 917754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as; 918754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 919754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 920754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!regs) 921754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return -ENXIO; 922754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 923754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen irq = platform_get_irq(pdev, 0); 924754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (irq < 0) 925754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return irq; 926754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 927754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk = clk_get(&pdev->dev, "spi_clk"); 928754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (IS_ERR(clk)) 929754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return PTR_ERR(clk); 930754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 931754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* setup spi core then atmel-specific driver state */ 932754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen ret = -ENOMEM; 933754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen master = spi_alloc_master(&pdev->dev, sizeof *as); 934754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!master) 935754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen goto out_free; 936754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 937e7db06b5d5afcef15c4c3e61c3a7441ed7ad1407David Brownell /* the spi->mode bits understood by this driver: */ 938e7db06b5d5afcef15c4c3e61c3a7441ed7ad1407David Brownell master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; 939e7db06b5d5afcef15c4c3e61c3a7441ed7ad1407David Brownell 940754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen master->bus_num = pdev->id; 941754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen master->num_chipselect = 4; 942754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen master->setup = atmel_spi_setup; 943754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen master->transfer = atmel_spi_transfer; 944754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen master->cleanup = atmel_spi_cleanup; 945754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen platform_set_drvdata(pdev, master); 946754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 947754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as = spi_master_get_devdata(master); 948754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 9498da0859a246838c81fe57d952b91d419e9c44179David Brownell /* 9508da0859a246838c81fe57d952b91d419e9c44179David Brownell * Scratch buffer is used for throwaway rx and tx data. 9518da0859a246838c81fe57d952b91d419e9c44179David Brownell * It's coherent to minimize dcache pollution. 9528da0859a246838c81fe57d952b91d419e9c44179David Brownell */ 953754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE, 954754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen &as->buffer_dma, GFP_KERNEL); 955754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!as->buffer) 956754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen goto out_free; 957754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 958754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_lock_init(&as->lock); 959754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen INIT_LIST_HEAD(&as->queue); 960754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->pdev = pdev; 961905aa0ae91798feb4e12d6237496d269dc2f4962hartleys as->regs = ioremap(regs->start, resource_size(regs)); 962754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (!as->regs) 963754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen goto out_free_buffer; 964754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->irq = irq; 965754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->clk = clk; 966754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 967754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen ret = request_irq(irq, atmel_spi_interrupt, 0, 9686c7377ab6814c247d7600955a4ead2e3db490697Kay Sievers dev_name(&pdev->dev), master); 969754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (ret) 970754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen goto out_unmap_regs; 971754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 972754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* Initialize the hardware */ 973754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_enable(clk); 974754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, CR, SPI_BIT(SWRST)); 97550d7d5bf3168db5d04566dd7ffb9a820e9fdf484Jean-Christophe Lallemand spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ 976754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); 977754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); 978754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, CR, SPI_BIT(SPIEN)); 979754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 980754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* go! */ 981754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n", 982754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen (unsigned long)regs->start, irq); 983754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 984754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen ret = spi_register_master(master); 985754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen if (ret) 986754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen goto out_reset_hw; 987754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 988754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return 0; 989754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 990754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenout_reset_hw: 991754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, CR, SPI_BIT(SWRST)); 99250d7d5bf3168db5d04566dd7ffb9a820e9fdf484Jean-Christophe Lallemand spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ 993754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_disable(clk); 994754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen free_irq(irq, master); 995754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenout_unmap_regs: 996754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen iounmap(as->regs); 997754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenout_free_buffer: 998754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, 999754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->buffer_dma); 1000754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenout_free: 1001754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_put(clk); 1002754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_master_put(master); 1003754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return ret; 1004754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 1005754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 10061cb201af626eedf0ff78cc1712c731b463994c60Jean-Christophe PLAGNIOL-VILLARDstatic int __devexit atmel_spi_remove(struct platform_device *pdev) 1007754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 1008754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_master *master = platform_get_drvdata(pdev); 1009754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as = spi_master_get_devdata(master); 1010754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_message *msg; 1011754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1012754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* reset the hardware and block queue progress */ 1013754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_lock_irq(&as->lock); 1014754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->stopping = 1; 1015754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_writel(as, CR, SPI_BIT(SWRST)); 101650d7d5bf3168db5d04566dd7ffb9a820e9fdf484Jean-Christophe Lallemand spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ 1017754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_readl(as, SR); 1018754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spin_unlock_irq(&as->lock); 1019754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1020754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* Terminate remaining queued transfers */ 1021754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen list_for_each_entry(msg, &as->queue, queue) { 1022754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen /* REVISIT unmapping the dma is a NOP on ARM and AVR32 1023754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen * but we shouldn't depend on that... 1024754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen */ 1025754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->status = -ESHUTDOWN; 1026754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen msg->complete(msg->context); 1027754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen } 1028754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1029754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer, 1030754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen as->buffer_dma); 1031754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1032754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_disable(as->clk); 1033754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_put(as->clk); 1034754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen free_irq(as->irq, master); 1035754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen iounmap(as->regs); 1036754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1037754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen spi_unregister_master(master); 1038754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1039754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return 0; 1040754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 1041754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1042754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#ifdef CONFIG_PM 1043754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1044754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg) 1045754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 1046754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_master *master = platform_get_drvdata(pdev); 1047754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as = spi_master_get_devdata(master); 1048754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1049754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_disable(as->clk); 1050754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return 0; 1051754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 1052754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1053754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic int atmel_spi_resume(struct platform_device *pdev) 1054754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen{ 1055754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct spi_master *master = platform_get_drvdata(pdev); 1056754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen struct atmel_spi *as = spi_master_get_devdata(master); 1057754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1058754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen clk_enable(as->clk); 1059754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen return 0; 1060754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen} 1061754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1062754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#else 1063754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#define atmel_spi_suspend NULL 1064754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#define atmel_spi_resume NULL 1065754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen#endif 1066754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1067754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1068754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoenstatic struct platform_driver atmel_spi_driver = { 1069754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen .driver = { 1070754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen .name = "atmel_spi", 1071754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen .owner = THIS_MODULE, 1072754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen }, 1073754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen .suspend = atmel_spi_suspend, 1074754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen .resume = atmel_spi_resume, 10751cb201af626eedf0ff78cc1712c731b463994c60Jean-Christophe PLAGNIOL-VILLARD .probe = atmel_spi_probe, 1076754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen .remove = __exit_p(atmel_spi_remove), 1077754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen}; 1078940ab88962bc1aff3273a8356d64577a6e386736Grant Likelymodule_platform_driver(atmel_spi_driver); 1079754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard Skinnemoen 1080754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard SkinnemoenMODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver"); 1081e05503ef1186ad33dfe56794407891eb1dd93ef6Jean DelvareMODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); 1082754ce4f29937ba11f16afa41a648a30b0fc1f075Haavard SkinnemoenMODULE_LICENSE("GPL"); 10837e38c3c4453bdb5ffdf8bf0ff0d9a760540f0893Kay SieversMODULE_ALIAS("platform:atmel_spi"); 1084