Blame view

drivers/spi/spi-au1550.c 25.7 KB
63bd23591   Jan Nikitenko   au1550 SPI contro...
1
  /*
ca632f556   Grant Likely   spi: reorganize d...
2
   * au1550 psc spi controller driver
63bd23591   Jan Nikitenko   au1550 SPI contro...
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
   * may work also with au1200, au1210, au1250
   * will not work on au1000, au1100 and au1500 (no full spi controller there)
   *
   * Copyright (c) 2006 ATRON electronic GmbH
   * Author: Jan Nikitenko <jan.nikitenko@gmail.com>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
63bd23591   Jan Nikitenko   au1550 SPI contro...
18
19
20
21
   */
  
  #include <linux/init.h>
  #include <linux/interrupt.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
22
  #include <linux/slab.h>
63bd23591   Jan Nikitenko   au1550 SPI contro...
23
  #include <linux/errno.h>
d7614de42   Paul Gortmaker   spi: Add module.h...
24
  #include <linux/module.h>
63bd23591   Jan Nikitenko   au1550 SPI contro...
25
26
  #include <linux/device.h>
  #include <linux/platform_device.h>
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
27
  #include <linux/resource.h>
63bd23591   Jan Nikitenko   au1550 SPI contro...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
  #include <linux/spi/spi.h>
  #include <linux/spi/spi_bitbang.h>
  #include <linux/dma-mapping.h>
  #include <linux/completion.h>
  #include <asm/mach-au1x00/au1000.h>
  #include <asm/mach-au1x00/au1xxx_psc.h>
  #include <asm/mach-au1x00/au1xxx_dbdma.h>
  
  #include <asm/mach-au1x00/au1550_spi.h>
  
  static unsigned usedma = 1;
  module_param(usedma, uint, 0644);
  
  /*
  #define AU1550_SPI_DEBUG_LOOPBACK
  */
  
  
  #define AU1550_SPI_DBDMA_DESCRIPTORS 1
  #define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U
  
  struct au1550_spi {
  	struct spi_bitbang bitbang;
  
  	volatile psc_spi_t __iomem *regs;
  	int irq;
63bd23591   Jan Nikitenko   au1550 SPI contro...
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  
  	unsigned len;
  	unsigned tx_count;
  	unsigned rx_count;
  	const u8 *tx;
  	u8 *rx;
  
  	void (*rx_word)(struct au1550_spi *hw);
  	void (*tx_word)(struct au1550_spi *hw);
  	int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t);
  	irqreturn_t (*irq_callback)(struct au1550_spi *hw);
  
  	struct completion master_done;
  
  	unsigned usedma;
  	u32 dma_tx_id;
  	u32 dma_rx_id;
  	u32 dma_tx_ch;
  	u32 dma_rx_ch;
  
  	u8 *dma_rx_tmpbuf;
  	unsigned dma_rx_tmpbuf_size;
  	u32 dma_rx_tmpbuf_addr;
  
  	struct spi_master *master;
  	struct device *dev;
  	struct au1550_spi_info *pdata;
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
81
  	struct resource *ioarea;
63bd23591   Jan Nikitenko   au1550 SPI contro...
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  };
  
  
  /* we use an 8-bit memory device for dma transfers to/from spi fifo */
  static dbdev_tab_t au1550_spi_mem_dbdev =
  {
  	.dev_id			= DBDMA_MEM_CHAN,
  	.dev_flags		= DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC,
  	.dev_tsize		= 0,
  	.dev_devwidth		= 8,
  	.dev_physaddr		= 0x00000000,
  	.dev_intlevel		= 0,
  	.dev_intpolarity	= 0
  };
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
96
  static int ddma_memid;	/* id to above mem dma device */
63bd23591   Jan Nikitenko   au1550 SPI contro...
97
  static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw);
40369e1cd   Jan Nikitenko   au1550_spi: fix p...
98
  /*
63bd23591   Jan Nikitenko   au1550 SPI contro...
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
   *  compute BRG and DIV bits to setup spi clock based on main input clock rate
   *  that was specified in platform data structure
   *  according to au1550 datasheet:
   *    psc_tempclk = psc_mainclk / (2 << DIV)
   *    spiclk = psc_tempclk / (2 * (BRG + 1))
   *    BRG valid range is 4..63
   *    DIV valid range is 0..3
   */
  static u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz)
  {
  	u32 mainclk_hz = hw->pdata->mainclk_hz;
  	u32 div, brg;
  
  	for (div = 0; div < 4; div++) {
  		brg = mainclk_hz / speed_hz / (4 << div);
  		/* now we have BRG+1 in brg, so count with that */
  		if (brg < (4 + 1)) {
  			brg = (4 + 1);	/* speed_hz too big */
  			break;		/* set lowest brg (div is == 0) */
  		}
  		if (brg <= (63 + 1))
  			break;		/* we have valid brg and div */
  	}
  	if (div == 4) {
  		div = 3;		/* speed_hz too small */
  		brg = (63 + 1);		/* set highest brg and div */
  	}
  	brg--;
  	return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div);
  }
  
  static inline void au1550_spi_mask_ack_all(struct au1550_spi *hw)
  {
  	hw->regs->psc_spimsk =
  		  PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO
  		| PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO
  		| PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
136
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
137
138
139
140
141
  
  	hw->regs->psc_spievent =
  		  PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO
  		| PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO
  		| PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
142
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
143
144
145
146
147
148
149
  }
  
  static void au1550_spi_reset_fifos(struct au1550_spi *hw)
  {
  	u32 pcr;
  
  	hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
150
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
151
152
  	do {
  		pcr = hw->regs->psc_spipcr;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
153
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  	} while (pcr != 0);
  }
  
  /*
   * dma transfers are used for the most common spi word size of 8-bits
   * we cannot easily change already set up dma channels' width, so if we wanted
   * dma support for more than 8-bit words (up to 24 bits), we would need to
   * setup dma channels from scratch on each spi transfer, based on bits_per_word
   * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits
   * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode
   * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set()
   */
  static void au1550_spi_chipsel(struct spi_device *spi, int value)
  {
  	struct au1550_spi *hw = spi_master_get_devdata(spi->master);
  	unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0;
  	u32 cfg, stat;
  
  	switch (value) {
  	case BITBANG_CS_INACTIVE:
  		if (hw->pdata->deactivate_cs)
  			hw->pdata->deactivate_cs(hw->pdata, spi->chip_select,
  					cspol);
  		break;
  
  	case BITBANG_CS_ACTIVE:
  		au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
  
  		cfg = hw->regs->psc_spicfg;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
183
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
184
  		hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
185
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  
  		if (spi->mode & SPI_CPOL)
  			cfg |= PSC_SPICFG_BI;
  		else
  			cfg &= ~PSC_SPICFG_BI;
  		if (spi->mode & SPI_CPHA)
  			cfg &= ~PSC_SPICFG_CDE;
  		else
  			cfg |= PSC_SPICFG_CDE;
  
  		if (spi->mode & SPI_LSB_FIRST)
  			cfg |= PSC_SPICFG_MLF;
  		else
  			cfg &= ~PSC_SPICFG_MLF;
  
  		if (hw->usedma && spi->bits_per_word <= 8)
  			cfg &= ~PSC_SPICFG_DD_DISABLE;
  		else
  			cfg |= PSC_SPICFG_DD_DISABLE;
  		cfg = PSC_SPICFG_CLR_LEN(cfg);
  		cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word);
  
  		cfg = PSC_SPICFG_CLR_BAUD(cfg);
  		cfg &= ~PSC_SPICFG_SET_DIV(3);
  		cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz);
  
  		hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
213
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
214
215
  		do {
  			stat = hw->regs->psc_spistat;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
216
  			wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
  		} while ((stat & PSC_SPISTAT_DR) == 0);
  
  		if (hw->pdata->activate_cs)
  			hw->pdata->activate_cs(hw->pdata, spi->chip_select,
  					cspol);
  		break;
  	}
  }
  
  static int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
  {
  	struct au1550_spi *hw = spi_master_get_devdata(spi->master);
  	unsigned bpw, hz;
  	u32 cfg, stat;
04ba24b34   Jan Nikitenko   spi/au1550_spi: f...
231
  	if (t) {
0beb0a6da   Jarkko Nikula   spi: au1550: Simp...
232
233
234
235
236
  		bpw = t->bits_per_word;
  		hz = t->speed_hz;
  	} else {
  		bpw = spi->bits_per_word;
  		hz = spi->max_speed_hz;
04ba24b34   Jan Nikitenko   spi/au1550_spi: f...
237
  	}
63bd23591   Jan Nikitenko   au1550 SPI contro...
238

0dd26e53b   Axel Lin   spi: au1550: Conv...
239
  	if (!hz)
63bd23591   Jan Nikitenko   au1550 SPI contro...
240
  		return -EINVAL;
63bd23591   Jan Nikitenko   au1550 SPI contro...
241
242
243
244
  
  	au1550_spi_bits_handlers_set(hw, spi->bits_per_word);
  
  	cfg = hw->regs->psc_spicfg;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
245
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
246
  	hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
247
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
248
249
250
251
252
253
254
255
256
257
258
259
260
  
  	if (hw->usedma && bpw <= 8)
  		cfg &= ~PSC_SPICFG_DD_DISABLE;
  	else
  		cfg |= PSC_SPICFG_DD_DISABLE;
  	cfg = PSC_SPICFG_CLR_LEN(cfg);
  	cfg |= PSC_SPICFG_SET_LEN(bpw);
  
  	cfg = PSC_SPICFG_CLR_BAUD(cfg);
  	cfg &= ~PSC_SPICFG_SET_DIV(3);
  	cfg |= au1550_spi_baudcfg(hw, hz);
  
  	hw->regs->psc_spicfg = cfg;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
261
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
262
263
264
265
  
  	if (cfg & PSC_SPICFG_DE_ENABLE) {
  		do {
  			stat = hw->regs->psc_spistat;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
266
  			wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
267
268
269
270
271
272
273
  		} while ((stat & PSC_SPISTAT_DR) == 0);
  	}
  
  	au1550_spi_reset_fifos(hw);
  	au1550_spi_mask_ack_all(hw);
  	return 0;
  }
63bd23591   Jan Nikitenko   au1550 SPI contro...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
  /*
   * for dma spi transfers, we have to setup rx channel, otherwise there is
   * no reliable way how to recognize that spi transfer is done
   * dma complete callbacks are called before real spi transfer is finished
   * and if only tx dma channel is set up (and rx fifo overflow event masked)
   * spi master done event irq is not generated unless rx fifo is empty (emptied)
   * so we need rx tmp buffer to use for rx dma if user does not provide one
   */
  static int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size)
  {
  	hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL);
  	if (!hw->dma_rx_tmpbuf)
  		return -ENOMEM;
  	hw->dma_rx_tmpbuf_size = size;
  	hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf,
  			size, DMA_FROM_DEVICE);
8d8bb39b9   FUJITA Tomonori   dma-mapping: add ...
290
  	if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) {
63bd23591   Jan Nikitenko   au1550 SPI contro...
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  		kfree(hw->dma_rx_tmpbuf);
  		hw->dma_rx_tmpbuf = 0;
  		hw->dma_rx_tmpbuf_size = 0;
  		return -EFAULT;
  	}
  	return 0;
  }
  
  static void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw)
  {
  	dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr,
  			hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE);
  	kfree(hw->dma_rx_tmpbuf);
  	hw->dma_rx_tmpbuf = 0;
  	hw->dma_rx_tmpbuf_size = 0;
  }
  
  static int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t)
  {
  	struct au1550_spi *hw = spi_master_get_devdata(spi->master);
  	dma_addr_t dma_tx_addr;
  	dma_addr_t dma_rx_addr;
  	u32 res;
  
  	hw->len = t->len;
  	hw->tx_count = 0;
  	hw->rx_count = 0;
  
  	hw->tx = t->tx_buf;
  	hw->rx = t->rx_buf;
  	dma_tx_addr = t->tx_dma;
  	dma_rx_addr = t->rx_dma;
  
  	/*
4e253d230   Jan Nikitenko   spi: au1550_spi f...
325
326
327
328
  	 * check if buffers are already dma mapped, map them otherwise:
  	 * - first map the TX buffer, so cache data gets written to memory
  	 * - then map the RX buffer, so that cache entries (with
  	 *   soon-to-be-stale data) get removed
63bd23591   Jan Nikitenko   au1550 SPI contro...
329
330
331
  	 * use rx buffer in place of tx if tx buffer was not provided
  	 * use temp rx buffer (preallocated or realloc to fit) for rx dma
  	 */
4e253d230   Jan Nikitenko   spi: au1550_spi f...
332
333
334
335
336
337
338
339
340
341
  	if (t->tx_buf) {
  		if (t->tx_dma == 0) {	/* if DMA_ADDR_INVALID, map it */
  			dma_tx_addr = dma_map_single(hw->dev,
  					(void *)t->tx_buf,
  					t->len, DMA_TO_DEVICE);
  			if (dma_mapping_error(hw->dev, dma_tx_addr))
  				dev_err(hw->dev, "tx dma map error
  ");
  		}
  	}
63bd23591   Jan Nikitenko   au1550 SPI contro...
342
343
344
345
346
  	if (t->rx_buf) {
  		if (t->rx_dma == 0) {	/* if DMA_ADDR_INVALID, map it */
  			dma_rx_addr = dma_map_single(hw->dev,
  					(void *)t->rx_buf,
  					t->len, DMA_FROM_DEVICE);
8d8bb39b9   FUJITA Tomonori   dma-mapping: add ...
347
  			if (dma_mapping_error(hw->dev, dma_rx_addr))
63bd23591   Jan Nikitenko   au1550 SPI contro...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  				dev_err(hw->dev, "rx dma map error
  ");
  		}
  	} else {
  		if (t->len > hw->dma_rx_tmpbuf_size) {
  			int ret;
  
  			au1550_spi_dma_rxtmp_free(hw);
  			ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len,
  					AU1550_SPI_DMA_RXTMP_MINSIZE));
  			if (ret < 0)
  				return ret;
  		}
  		hw->rx = hw->dma_rx_tmpbuf;
  		dma_rx_addr = hw->dma_rx_tmpbuf_addr;
  		dma_sync_single_for_device(hw->dev, dma_rx_addr,
  			t->len, DMA_FROM_DEVICE);
  	}
4e253d230   Jan Nikitenko   spi: au1550_spi f...
366
367
  
  	if (!t->tx_buf) {
63bd23591   Jan Nikitenko   au1550 SPI contro...
368
369
370
371
372
373
  		dma_sync_single_for_device(hw->dev, dma_rx_addr,
  				t->len, DMA_BIDIRECTIONAL);
  		hw->tx = hw->rx;
  	}
  
  	/* put buffers on the ring */
963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
374
  	res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, virt_to_phys(hw->rx),
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
375
  				    t->len, DDMA_FLAGS_IE);
63bd23591   Jan Nikitenko   au1550 SPI contro...
376
377
378
  	if (!res)
  		dev_err(hw->dev, "rx dma put dest error
  ");
963accbc8   Manuel Lauss   MIPS: Alchemy: ch...
379
  	res = au1xxx_dbdma_put_source(hw->dma_tx_ch, virt_to_phys(hw->tx),
ea071cc70   Manuel Lauss   MIPS: Alchemy: re...
380
  				      t->len, DDMA_FLAGS_IE);
63bd23591   Jan Nikitenko   au1550 SPI contro...
381
382
383
384
385
386
387
388
389
  	if (!res)
  		dev_err(hw->dev, "tx dma put source error
  ");
  
  	au1xxx_dbdma_start(hw->dma_rx_ch);
  	au1xxx_dbdma_start(hw->dma_tx_ch);
  
  	/* by default enable nearly all events interrupt */
  	hw->regs->psc_spimsk = PSC_SPIMSK_SD;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
390
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
391
392
393
  
  	/* start the transfer */
  	hw->regs->psc_spipcr = PSC_SPIPCR_MS;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
394
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
  
  	wait_for_completion(&hw->master_done);
  
  	au1xxx_dbdma_stop(hw->dma_tx_ch);
  	au1xxx_dbdma_stop(hw->dma_rx_ch);
  
  	if (!t->rx_buf) {
  		/* using the temporal preallocated and premapped buffer */
  		dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len,
  			DMA_FROM_DEVICE);
  	}
  	/* unmap buffers if mapped above */
  	if (t->rx_buf && t->rx_dma == 0 )
  		dma_unmap_single(hw->dev, dma_rx_addr, t->len,
  			DMA_FROM_DEVICE);
  	if (t->tx_buf && t->tx_dma == 0 )
  		dma_unmap_single(hw->dev, dma_tx_addr, t->len,
  			DMA_TO_DEVICE);
  
  	return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
  }
  
  static irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw)
  {
  	u32 stat, evnt;
  
  	stat = hw->regs->psc_spistat;
  	evnt = hw->regs->psc_spievent;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
423
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
424
425
426
427
428
429
430
431
432
433
434
435
436
  	if ((stat & PSC_SPISTAT_DI) == 0) {
  		dev_err(hw->dev, "Unexpected IRQ!
  ");
  		return IRQ_NONE;
  	}
  
  	if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
  				| PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
  				| PSC_SPIEVNT_TU | PSC_SPIEVNT_SD))
  			!= 0) {
  		/*
  		 * due to an spi error we consider transfer as done,
  		 * so mask all events until before next transfer start
886db6acf   Masanari Iida   spi: fix comment/...
437
  		 * and stop the possibly running dma immediately
63bd23591   Jan Nikitenko   au1550 SPI contro...
438
439
440
441
  		 */
  		au1550_spi_mask_ack_all(hw);
  		au1xxx_dbdma_stop(hw->dma_rx_ch);
  		au1xxx_dbdma_stop(hw->dma_tx_ch);
25985edce   Lucas De Marchi   Fix common misspe...
442
  		/* get number of transferred bytes */
63bd23591   Jan Nikitenko   au1550 SPI contro...
443
444
445
446
447
448
  		hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch);
  		hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch);
  
  		au1xxx_dbdma_reset(hw->dma_rx_ch);
  		au1xxx_dbdma_reset(hw->dma_tx_ch);
  		au1550_spi_reset_fifos(hw);
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
449
450
451
452
453
454
455
456
457
  		if (evnt == PSC_SPIEVNT_RO)
  			dev_err(hw->dev,
  				"dma transfer: receive FIFO overflow!
  ");
  		else
  			dev_err(hw->dev,
  				"dma transfer: unexpected SPI error "
  				"(event=0x%x stat=0x%x)!
  ", evnt, stat);
63bd23591   Jan Nikitenko   au1550 SPI contro...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
  
  		complete(&hw->master_done);
  		return IRQ_HANDLED;
  	}
  
  	if ((evnt & PSC_SPIEVNT_MD) != 0) {
  		/* transfer completed successfully */
  		au1550_spi_mask_ack_all(hw);
  		hw->rx_count = hw->len;
  		hw->tx_count = hw->len;
  		complete(&hw->master_done);
  	}
  	return IRQ_HANDLED;
  }
  
  
  /* routines to handle different word sizes in pio mode */
  #define AU1550_SPI_RX_WORD(size, mask)					\
  static void au1550_spi_rx_word_##size(struct au1550_spi *hw)		\
  {									\
  	u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask);		\
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
479
  	wmb(); /* drain writebuffer */					\
63bd23591   Jan Nikitenko   au1550 SPI contro...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
  	if (hw->rx) {							\
  		*(u##size *)hw->rx = (u##size)fifoword;			\
  		hw->rx += (size) / 8;					\
  	}								\
  	hw->rx_count += (size) / 8;					\
  }
  
  #define AU1550_SPI_TX_WORD(size, mask)					\
  static void au1550_spi_tx_word_##size(struct au1550_spi *hw)		\
  {									\
  	u32 fifoword = 0;						\
  	if (hw->tx) {							\
  		fifoword = *(u##size *)hw->tx & (u32)(mask);		\
  		hw->tx += (size) / 8;					\
  	}								\
  	hw->tx_count += (size) / 8;					\
  	if (hw->tx_count >= hw->len)					\
  		fifoword |= PSC_SPITXRX_LC;				\
  	hw->regs->psc_spitxrx = fifoword;				\
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
499
  	wmb(); /* drain writebuffer */					\
63bd23591   Jan Nikitenko   au1550 SPI contro...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  }
  
  AU1550_SPI_RX_WORD(8,0xff)
  AU1550_SPI_RX_WORD(16,0xffff)
  AU1550_SPI_RX_WORD(32,0xffffff)
  AU1550_SPI_TX_WORD(8,0xff)
  AU1550_SPI_TX_WORD(16,0xffff)
  AU1550_SPI_TX_WORD(32,0xffffff)
  
  static int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t)
  {
  	u32 stat, mask;
  	struct au1550_spi *hw = spi_master_get_devdata(spi->master);
  
  	hw->tx = t->tx_buf;
  	hw->rx = t->rx_buf;
  	hw->len = t->len;
  	hw->tx_count = 0;
  	hw->rx_count = 0;
  
  	/* by default enable nearly all events after filling tx fifo */
  	mask = PSC_SPIMSK_SD;
  
  	/* fill the transmit FIFO */
  	while (hw->tx_count < hw->len) {
  
  		hw->tx_word(hw);
  
  		if (hw->tx_count >= hw->len) {
  			/* mask tx fifo request interrupt as we are done */
  			mask |= PSC_SPIMSK_TR;
  		}
  
  		stat = hw->regs->psc_spistat;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
534
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
535
536
537
538
539
540
  		if (stat & PSC_SPISTAT_TF)
  			break;
  	}
  
  	/* enable event interrupts */
  	hw->regs->psc_spimsk = mask;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
541
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
542
543
544
  
  	/* start the transfer */
  	hw->regs->psc_spipcr = PSC_SPIPCR_MS;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
545
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
546
547
548
549
550
551
552
553
554
555
556
557
558
  
  	wait_for_completion(&hw->master_done);
  
  	return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count;
  }
  
  static irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw)
  {
  	int busy;
  	u32 stat, evnt;
  
  	stat = hw->regs->psc_spistat;
  	evnt = hw->regs->psc_spievent;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
559
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
560
561
562
563
564
565
566
567
  	if ((stat & PSC_SPISTAT_DI) == 0) {
  		dev_err(hw->dev, "Unexpected IRQ!
  ");
  		return IRQ_NONE;
  	}
  
  	if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO
  				| PSC_SPIEVNT_RU | PSC_SPIEVNT_TO
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
568
  				| PSC_SPIEVNT_SD))
63bd23591   Jan Nikitenko   au1550 SPI contro...
569
  			!= 0) {
63bd23591   Jan Nikitenko   au1550 SPI contro...
570
571
572
573
574
575
  		/*
  		 * due to an error we consider transfer as done,
  		 * so mask all events until before next transfer start
  		 */
  		au1550_spi_mask_ack_all(hw);
  		au1550_spi_reset_fifos(hw);
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
576
577
578
579
  		dev_err(hw->dev,
  			"pio transfer: unexpected SPI error "
  			"(event=0x%x stat=0x%x)!
  ", evnt, stat);
63bd23591   Jan Nikitenko   au1550 SPI contro...
580
581
582
583
584
585
586
587
588
589
590
  		complete(&hw->master_done);
  		return IRQ_HANDLED;
  	}
  
  	/*
  	 * while there is something to read from rx fifo
  	 * or there is a space to write to tx fifo:
  	 */
  	do {
  		busy = 0;
  		stat = hw->regs->psc_spistat;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
591
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
592

bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
593
594
595
596
597
598
599
600
601
602
  		/*
  		 * Take care to not let the Rx FIFO overflow.
  		 *
  		 * We only write a byte if we have read one at least. Initially,
  		 * the write fifo is full, so we should read from the read fifo
  		 * first.
  		 * In case we miss a word from the read fifo, we should get a
  		 * RO event and should back out.
  		 */
  		if (!(stat & PSC_SPISTAT_RE) && hw->rx_count < hw->len) {
63bd23591   Jan Nikitenko   au1550 SPI contro...
603
  			hw->rx_word(hw);
63bd23591   Jan Nikitenko   au1550 SPI contro...
604
  			busy = 1;
63bd23591   Jan Nikitenko   au1550 SPI contro...
605

bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
606
607
  			if (!(stat & PSC_SPISTAT_TF) && hw->tx_count < hw->len)
  				hw->tx_word(hw);
63bd23591   Jan Nikitenko   au1550 SPI contro...
608
609
  		}
  	} while (busy);
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
610
  	hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
611
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
612

bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
  	/*
  	 * Restart the SPI transmission in case of a transmit underflow.
  	 * This seems to work despite the notes in the Au1550 data book
  	 * of Figure 8-4 with flowchart for SPI master operation:
  	 *
  	 * """Note 1: An XFR Error Interrupt occurs, unless masked,
  	 * for any of the following events: Tx FIFO Underflow,
  	 * Rx FIFO Overflow, or Multiple-master Error
  	 *    Note 2: In case of a Tx Underflow Error, all zeroes are
  	 * transmitted."""
  	 *
  	 * By simply restarting the spi transfer on Tx Underflow Error,
  	 * we assume that spi transfer was paused instead of zeroes
  	 * transmittion mentioned in the Note 2 of Au1550 data book.
  	 */
  	if (evnt & PSC_SPIEVNT_TU) {
  		hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
630
  		wmb(); /* drain writebuffer */
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
631
  		hw->regs->psc_spipcr = PSC_SPIPCR_MS;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
632
  		wmb(); /* drain writebuffer */
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
633
634
635
  	}
  
  	if (hw->rx_count >= hw->len) {
63bd23591   Jan Nikitenko   au1550 SPI contro...
636
637
638
639
640
641
642
643
644
645
646
647
  		/* transfer completed successfully */
  		au1550_spi_mask_ack_all(hw);
  		complete(&hw->master_done);
  	}
  	return IRQ_HANDLED;
  }
  
  static int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
  {
  	struct au1550_spi *hw = spi_master_get_devdata(spi->master);
  	return hw->txrx_bufs(spi, t);
  }
40369e1cd   Jan Nikitenko   au1550_spi: fix p...
648
  static irqreturn_t au1550_spi_irq(int irq, void *dev)
63bd23591   Jan Nikitenko   au1550 SPI contro...
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
  {
  	struct au1550_spi *hw = dev;
  	return hw->irq_callback(hw);
  }
  
  static void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw)
  {
  	if (bpw <= 8) {
  		if (hw->usedma) {
  			hw->txrx_bufs = &au1550_spi_dma_txrxb;
  			hw->irq_callback = &au1550_spi_dma_irq_callback;
  		} else {
  			hw->rx_word = &au1550_spi_rx_word_8;
  			hw->tx_word = &au1550_spi_tx_word_8;
  			hw->txrx_bufs = &au1550_spi_pio_txrxb;
  			hw->irq_callback = &au1550_spi_pio_irq_callback;
  		}
  	} else if (bpw <= 16) {
  		hw->rx_word = &au1550_spi_rx_word_16;
  		hw->tx_word = &au1550_spi_tx_word_16;
  		hw->txrx_bufs = &au1550_spi_pio_txrxb;
  		hw->irq_callback = &au1550_spi_pio_irq_callback;
  	} else {
  		hw->rx_word = &au1550_spi_rx_word_32;
  		hw->tx_word = &au1550_spi_tx_word_32;
  		hw->txrx_bufs = &au1550_spi_pio_txrxb;
  		hw->irq_callback = &au1550_spi_pio_irq_callback;
  	}
  }
2deff8d60   Grant Likely   spi: Remove erron...
678
  static void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw)
63bd23591   Jan Nikitenko   au1550 SPI contro...
679
680
681
682
683
  {
  	u32 stat, cfg;
  
  	/* set up the PSC for SPI mode */
  	hw->regs->psc_ctrl = PSC_CTRL_DISABLE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
684
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
685
  	hw->regs->psc_sel = PSC_SEL_PS_SPIMODE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
686
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
687
688
  
  	hw->regs->psc_spicfg = 0;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
689
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
690
691
  
  	hw->regs->psc_ctrl = PSC_CTRL_ENABLE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
692
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
693
694
695
  
  	do {
  		stat = hw->regs->psc_spistat;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
696
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
  	} while ((stat & PSC_SPISTAT_SR) == 0);
  
  
  	cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE;
  	cfg |= PSC_SPICFG_SET_LEN(8);
  	cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8;
  	/* use minimal allowed brg and div values as initial setting: */
  	cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0);
  
  #ifdef AU1550_SPI_DEBUG_LOOPBACK
  	cfg |= PSC_SPICFG_LB;
  #endif
  
  	hw->regs->psc_spicfg = cfg;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
711
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
712
713
714
715
  
  	au1550_spi_mask_ack_all(hw);
  
  	hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
716
  	wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
717
718
719
  
  	do {
  		stat = hw->regs->psc_spistat;
2f73bfbe0   Manuel Lauss   MIPS: Alchemy: re...
720
  		wmb(); /* drain writebuffer */
63bd23591   Jan Nikitenko   au1550 SPI contro...
721
  	} while ((stat & PSC_SPISTAT_DR) == 0);
bbe48ecc7   Jan Nikitenko   spi: au1550_spi: ...
722
723
  
  	au1550_spi_reset_fifos(hw);
63bd23591   Jan Nikitenko   au1550 SPI contro...
724
  }
2deff8d60   Grant Likely   spi: Remove erron...
725
  static int au1550_spi_probe(struct platform_device *pdev)
63bd23591   Jan Nikitenko   au1550 SPI contro...
726
727
728
  {
  	struct au1550_spi *hw;
  	struct spi_master *master;
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
729
  	struct resource *r;
63bd23591   Jan Nikitenko   au1550 SPI contro...
730
731
732
733
734
735
736
737
738
  	int err = 0;
  
  	master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi));
  	if (master == NULL) {
  		dev_err(&pdev->dev, "No memory for spi_master
  ");
  		err = -ENOMEM;
  		goto err_nomem;
  	}
e7db06b5d   David Brownell   spi: move more sp...
739
740
  	/* the spi->mode bits understood by this driver: */
  	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
24778be20   Stephen Warren   spi: convert driv...
741
  	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 24);
e7db06b5d   David Brownell   spi: move more sp...
742

63bd23591   Jan Nikitenko   au1550 SPI contro...
743
  	hw = spi_master_get_devdata(master);
94c69f765   Axel Lin   spi: bitbang: Let...
744
  	hw->master = master;
8074cf063   Jingoo Han   spi: use dev_get_...
745
  	hw->pdata = dev_get_platdata(&pdev->dev);
63bd23591   Jan Nikitenko   au1550 SPI contro...
746
747
748
749
750
751
752
753
  	hw->dev = &pdev->dev;
  
  	if (hw->pdata == NULL) {
  		dev_err(&pdev->dev, "No platform data supplied
  ");
  		err = -ENOENT;
  		goto err_no_pdata;
  	}
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
  	r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  	if (!r) {
  		dev_err(&pdev->dev, "no IRQ
  ");
  		err = -ENODEV;
  		goto err_no_iores;
  	}
  	hw->irq = r->start;
  
  	hw->usedma = 0;
  	r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
  	if (r) {
  		hw->dma_tx_id = r->start;
  		r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
  		if (r) {
  			hw->dma_rx_id = r->start;
  			if (usedma && ddma_memid) {
  				if (pdev->dev.dma_mask == NULL)
  					dev_warn(&pdev->dev, "no dma mask
  ");
  				else
  					hw->usedma = 1;
  			}
  		}
  	}
63bd23591   Jan Nikitenko   au1550 SPI contro...
779

3a93a159c   Manuel Lauss   spi: au1550_spi: ...
780
781
782
783
784
785
  	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  	if (!r) {
  		dev_err(&pdev->dev, "no mmio resource
  ");
  		err = -ENODEV;
  		goto err_no_iores;
63bd23591   Jan Nikitenko   au1550 SPI contro...
786
  	}
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
787
788
789
  	hw->ioarea = request_mem_region(r->start, sizeof(psc_spi_t),
  					pdev->name);
  	if (!hw->ioarea) {
63bd23591   Jan Nikitenko   au1550 SPI contro...
790
791
792
793
794
  		dev_err(&pdev->dev, "Cannot reserve iomem region
  ");
  		err = -ENXIO;
  		goto err_no_iores;
  	}
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
795
796
797
798
799
800
  	hw->regs = (psc_spi_t __iomem *)ioremap(r->start, sizeof(psc_spi_t));
  	if (!hw->regs) {
  		dev_err(&pdev->dev, "cannot ioremap
  ");
  		err = -ENXIO;
  		goto err_ioremap;
63bd23591   Jan Nikitenko   au1550 SPI contro...
801
  	}
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
802
  	platform_set_drvdata(pdev, hw);
63bd23591   Jan Nikitenko   au1550 SPI contro...
803

3a93a159c   Manuel Lauss   spi: au1550_spi: ...
804
805
806
807
808
  	init_completion(&hw->master_done);
  
  	hw->bitbang.master = hw->master;
  	hw->bitbang.setup_transfer = au1550_spi_setupxfer;
  	hw->bitbang.chipselect = au1550_spi_chipsel;
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
809
810
811
812
  	hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs;
  
  	if (hw->usedma) {
  		hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(ddma_memid,
63bd23591   Jan Nikitenko   au1550 SPI contro...
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
  			hw->dma_tx_id, NULL, (void *)hw);
  		if (hw->dma_tx_ch == 0) {
  			dev_err(&pdev->dev,
  				"Cannot allocate tx dma channel
  ");
  			err = -ENXIO;
  			goto err_no_txdma;
  		}
  		au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8);
  		if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch,
  			AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
  			dev_err(&pdev->dev,
  				"Cannot allocate tx dma descriptors
  ");
  			err = -ENXIO;
  			goto err_no_txdma_descr;
  		}
  
  
  		hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id,
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
833
  			ddma_memid, NULL, (void *)hw);
63bd23591   Jan Nikitenko   au1550 SPI contro...
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
  		if (hw->dma_rx_ch == 0) {
  			dev_err(&pdev->dev,
  				"Cannot allocate rx dma channel
  ");
  			err = -ENXIO;
  			goto err_no_rxdma;
  		}
  		au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8);
  		if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch,
  			AU1550_SPI_DBDMA_DESCRIPTORS) == 0) {
  			dev_err(&pdev->dev,
  				"Cannot allocate rx dma descriptors
  ");
  			err = -ENXIO;
  			goto err_no_rxdma_descr;
  		}
  
  		err = au1550_spi_dma_rxtmp_alloc(hw,
  			AU1550_SPI_DMA_RXTMP_MINSIZE);
  		if (err < 0) {
  			dev_err(&pdev->dev,
  				"Cannot allocate initial rx dma tmp buffer
  ");
  			goto err_dma_rxtmp_alloc;
  		}
  	}
  
  	au1550_spi_bits_handlers_set(hw, 8);
  
  	err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw);
  	if (err) {
  		dev_err(&pdev->dev, "Cannot claim IRQ
  ");
  		goto err_no_irq;
  	}
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
869
  	master->bus_num = pdev->id;
63bd23591   Jan Nikitenko   au1550 SPI contro...
870
871
872
873
874
875
876
877
878
879
880
881
882
883
  	master->num_chipselect = hw->pdata->num_chipselect;
  
  	/*
  	 *  precompute valid range for spi freq - from au1550 datasheet:
  	 *    psc_tempclk = psc_mainclk / (2 << DIV)
  	 *    spiclk = psc_tempclk / (2 * (BRG + 1))
  	 *    BRG valid range is 4..63
  	 *    DIV valid range is 0..3
  	 *  round the min and max frequencies to values that would still
  	 *  produce valid brg and div
  	 */
  	{
  		int min_div = (2 << 0) * (2 * (4 + 1));
  		int max_div = (2 << 3) * (2 * (63 + 1));
0dd26e53b   Axel Lin   spi: au1550: Conv...
884
885
886
  		master->max_speed_hz = hw->pdata->mainclk_hz / min_div;
  		master->min_speed_hz =
  				hw->pdata->mainclk_hz / (max_div + 1) + 1;
63bd23591   Jan Nikitenko   au1550 SPI contro...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
  	}
  
  	au1550_spi_setup_psc_as_spi(hw);
  
  	err = spi_bitbang_start(&hw->bitbang);
  	if (err) {
  		dev_err(&pdev->dev, "Failed to register SPI master
  ");
  		goto err_register;
  	}
  
  	dev_info(&pdev->dev,
  		"spi master registered: bus_num=%d num_chipselect=%d
  ",
  		master->bus_num, master->num_chipselect);
  
  	return 0;
  
  err_register:
  	free_irq(hw->irq, hw);
  
  err_no_irq:
  	au1550_spi_dma_rxtmp_free(hw);
  
  err_dma_rxtmp_alloc:
  err_no_rxdma_descr:
  	if (hw->usedma)
  		au1xxx_dbdma_chan_free(hw->dma_rx_ch);
  
  err_no_rxdma:
  err_no_txdma_descr:
  	if (hw->usedma)
  		au1xxx_dbdma_chan_free(hw->dma_tx_ch);
  
  err_no_txdma:
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
922
923
924
  	iounmap((void __iomem *)hw->regs);
  
  err_ioremap:
30670539b   Himangi Saraogi   spi: au1550: Fix ...
925
  	release_mem_region(r->start, sizeof(psc_spi_t));
63bd23591   Jan Nikitenko   au1550 SPI contro...
926
927
928
929
930
931
932
933
  
  err_no_iores:
  err_no_pdata:
  	spi_master_put(hw->master);
  
  err_nomem:
  	return err;
  }
2deff8d60   Grant Likely   spi: Remove erron...
934
  static int au1550_spi_remove(struct platform_device *pdev)
63bd23591   Jan Nikitenko   au1550 SPI contro...
935
936
937
938
939
940
941
942
943
  {
  	struct au1550_spi *hw = platform_get_drvdata(pdev);
  
  	dev_info(&pdev->dev, "spi master remove: bus_num=%d
  ",
  		hw->master->bus_num);
  
  	spi_bitbang_stop(&hw->bitbang);
  	free_irq(hw->irq, hw);
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
944
  	iounmap((void __iomem *)hw->regs);
61a2381c7   Manuel Lauss   spi: spi-au1550: ...
945
  	release_mem_region(hw->ioarea->start, sizeof(psc_spi_t));
63bd23591   Jan Nikitenko   au1550 SPI contro...
946
947
948
949
950
951
  
  	if (hw->usedma) {
  		au1550_spi_dma_rxtmp_free(hw);
  		au1xxx_dbdma_chan_free(hw->dma_rx_ch);
  		au1xxx_dbdma_chan_free(hw->dma_tx_ch);
  	}
63bd23591   Jan Nikitenko   au1550 SPI contro...
952
953
954
  	spi_master_put(hw->master);
  	return 0;
  }
7e38c3c44   Kay Sievers   spi: fix platform...
955
956
  /* work with hotplug and coldplug */
  MODULE_ALIAS("platform:au1550-spi");
63bd23591   Jan Nikitenko   au1550 SPI contro...
957
  static struct platform_driver au1550_spi_drv = {
75dab1bfb   Wolfram Sang   spi: spi-au1550: ...
958
  	.probe = au1550_spi_probe,
2deff8d60   Grant Likely   spi: Remove erron...
959
  	.remove = au1550_spi_remove,
63bd23591   Jan Nikitenko   au1550 SPI contro...
960
961
  	.driver = {
  		.name = "au1550-spi",
63bd23591   Jan Nikitenko   au1550 SPI contro...
962
963
964
965
966
  	},
  };
  
  static int __init au1550_spi_init(void)
  {
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
967
968
969
970
  	/*
  	 * create memory device with 8 bits dev_devwidth
  	 * needed for proper byte ordering to spi fifo
  	 */
970e268d6   Manuel Lauss   MIPS: Alchemy: Un...
971
972
973
974
975
976
977
978
  	switch (alchemy_get_cputype()) {
  	case ALCHEMY_CPU_AU1550:
  	case ALCHEMY_CPU_AU1200:
  	case ALCHEMY_CPU_AU1300:
  		break;
  	default:
  		return -ENODEV;
  	}
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
979
980
981
982
983
984
985
  	if (usedma) {
  		ddma_memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev);
  		if (!ddma_memid)
  			printk(KERN_ERR "au1550-spi: cannot add memory"
  					"dbdma device
  ");
  	}
75dab1bfb   Wolfram Sang   spi: spi-au1550: ...
986
  	return platform_driver_register(&au1550_spi_drv);
63bd23591   Jan Nikitenko   au1550 SPI contro...
987
988
989
990
991
  }
  module_init(au1550_spi_init);
  
  static void __exit au1550_spi_exit(void)
  {
3a93a159c   Manuel Lauss   spi: au1550_spi: ...
992
993
  	if (usedma && ddma_memid)
  		au1xxx_ddma_del_device(ddma_memid);
63bd23591   Jan Nikitenko   au1550 SPI contro...
994
995
996
997
998
999
1000
  	platform_driver_unregister(&au1550_spi_drv);
  }
  module_exit(au1550_spi_exit);
  
  MODULE_DESCRIPTION("Au1550 PSC SPI Driver");
  MODULE_AUTHOR("Jan Nikitenko <jan.nikitenko@gmail.com>");
  MODULE_LICENSE("GPL");