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