163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko/* 2ca632f556697d45d67ed5cada7cedf3ddfe0db4bGrant Likely * au1550 psc spi controller driver 363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * may work also with au1200, au1210, au1250 463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * will not work on au1000, au1100 and au1500 (no full spi controller there) 563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * 663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * Copyright (c) 2006 ATRON electronic GmbH 763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * Author: Jan Nikitenko <jan.nikitenko@gmail.com> 863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * 963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * This program is free software; you can redistribute it and/or modify 1063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * it under the terms of the GNU General Public License as published by 1163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * the Free Software Foundation; either version 2 of the License, or 1263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * (at your option) any later version. 1363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * 1463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * This program is distributed in the hope that it will be useful, 1563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * but WITHOUT ANY WARRANTY; without even the implied warranty of 1663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * GNU General Public License for more details. 1863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * 1963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * You should have received a copy of the GNU General Public License 2063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * along with this program; if not, write to the Free Software 2163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 2363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 2463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/init.h> 2563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/interrupt.h> 265a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 2763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/errno.h> 28d7614de422c0b55db0c1013a6c72330187536004Paul Gortmaker#include <linux/module.h> 2963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/device.h> 3063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/platform_device.h> 313a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss#include <linux/resource.h> 3263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/spi/spi.h> 3363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/spi/spi_bitbang.h> 3463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/dma-mapping.h> 3563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <linux/completion.h> 3663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <asm/mach-au1x00/au1000.h> 3763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <asm/mach-au1x00/au1xxx_psc.h> 3863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <asm/mach-au1x00/au1xxx_dbdma.h> 3963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 4063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#include <asm/mach-au1x00/au1550_spi.h> 4163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 4263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic unsigned usedma = 1; 4363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkomodule_param(usedma, uint, 0644); 4463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 4563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko/* 4663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#define AU1550_SPI_DEBUG_LOOPBACK 4763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko*/ 4863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 4963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 5063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#define AU1550_SPI_DBDMA_DESCRIPTORS 1 5163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#define AU1550_SPI_DMA_RXTMP_MINSIZE 2048U 5263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 5363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostruct au1550_spi { 5463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct spi_bitbang bitbang; 5563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 5663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko volatile psc_spi_t __iomem *regs; 5763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int irq; 5863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 5963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned len; 6063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned tx_count; 6163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned rx_count; 6263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko const u8 *tx; 6363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u8 *rx; 6463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 6563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko void (*rx_word)(struct au1550_spi *hw); 6663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko void (*tx_word)(struct au1550_spi *hw); 6763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); 6863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko irqreturn_t (*irq_callback)(struct au1550_spi *hw); 6963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct completion master_done; 7163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned usedma; 7363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 dma_tx_id; 7463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 dma_rx_id; 7563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 dma_tx_ch; 7663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 dma_rx_ch; 7763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u8 *dma_rx_tmpbuf; 7963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned dma_rx_tmpbuf_size; 8063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 dma_rx_tmpbuf_addr; 8163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct spi_master *master; 8363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct device *dev; 8463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi_info *pdata; 853a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss struct resource *ioarea; 8663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko}; 8763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko/* we use an 8-bit memory device for dma transfers to/from spi fifo */ 9063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic dbdev_tab_t au1550_spi_mem_dbdev = 9163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 9263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_id = DBDMA_MEM_CHAN, 9363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_flags = DEV_FLAGS_ANYUSE|DEV_FLAGS_SYNC, 9463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_tsize = 0, 9563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_devwidth = 8, 9663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_physaddr = 0x00000000, 9763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_intlevel = 0, 9863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .dev_intpolarity = 0 9963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko}; 10063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 1013a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Laussstatic int ddma_memid; /* id to above mem dma device */ 1023a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss 10363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw); 10463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 10563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 10640369e1cdb71287662213ae214842899e77a0544Jan Nikitenko/* 10763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * compute BRG and DIV bits to setup spi clock based on main input clock rate 10863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * that was specified in platform data structure 10963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * according to au1550 datasheet: 11063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * psc_tempclk = psc_mainclk / (2 << DIV) 11163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * spiclk = psc_tempclk / (2 * (BRG + 1)) 11263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * BRG valid range is 4..63 11363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * DIV valid range is 0..3 11463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 11563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic u32 au1550_spi_baudcfg(struct au1550_spi *hw, unsigned speed_hz) 11663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 11763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 mainclk_hz = hw->pdata->mainclk_hz; 11863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 div, brg; 11963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 12063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko for (div = 0; div < 4; div++) { 12163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko brg = mainclk_hz / speed_hz / (4 << div); 12263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* now we have BRG+1 in brg, so count with that */ 12363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (brg < (4 + 1)) { 12463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko brg = (4 + 1); /* speed_hz too big */ 12563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko break; /* set lowest brg (div is == 0) */ 12663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 12763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (brg <= (63 + 1)) 12863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko break; /* we have valid brg and div */ 12963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 13063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (div == 4) { 13163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko div = 3; /* speed_hz too small */ 13263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko brg = (63 + 1); /* set highest brg and div */ 13363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 13463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko brg--; 13563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return PSC_SPICFG_SET_BAUD(brg) | PSC_SPICFG_SET_DIV(div); 13663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 13763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 13863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic inline void au1550_spi_mask_ack_all(struct au1550_spi *hw) 13963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 14063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spimsk = 14163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko PSC_SPIMSK_MM | PSC_SPIMSK_RR | PSC_SPIMSK_RO 14263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIMSK_RU | PSC_SPIMSK_TR | PSC_SPIMSK_TO 14363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIMSK_TU | PSC_SPIMSK_SD | PSC_SPIMSK_MD; 1442f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 14563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 14663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spievent = 14763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko PSC_SPIEVNT_MM | PSC_SPIEVNT_RR | PSC_SPIEVNT_RO 14863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIEVNT_RU | PSC_SPIEVNT_TR | PSC_SPIEVNT_TO 14963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD | PSC_SPIEVNT_MD; 1502f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 15163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 15263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 15363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_reset_fifos(struct au1550_spi *hw) 15463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 15563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 pcr; 15663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 15763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spipcr = PSC_SPIPCR_RC | PSC_SPIPCR_TC; 1582f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 15963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko do { 16063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko pcr = hw->regs->psc_spipcr; 1612f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 16263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } while (pcr != 0); 16363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 16463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 16563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko/* 16663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * dma transfers are used for the most common spi word size of 8-bits 16763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * we cannot easily change already set up dma channels' width, so if we wanted 16863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * dma support for more than 8-bit words (up to 24 bits), we would need to 16963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * setup dma channels from scratch on each spi transfer, based on bits_per_word 17063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * instead we have pre set up 8 bit dma channels supporting spi 4 to 8 bits 17163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * transfers, and 9 to 24 bits spi transfers will be done in pio irq based mode 17263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * callbacks to handle dma or pio are set up in au1550_spi_bits_handlers_set() 17363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 17463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_chipsel(struct spi_device *spi, int value) 17563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 17663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = spi_master_get_devdata(spi->master); 17763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; 17863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 cfg, stat; 17963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 18063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko switch (value) { 18163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko case BITBANG_CS_INACTIVE: 18263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->pdata->deactivate_cs) 18363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->pdata->deactivate_cs(hw->pdata, spi->chip_select, 18463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cspol); 18563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko break; 18663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 18763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko case BITBANG_CS_ACTIVE: 18863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_bits_handlers_set(hw, spi->bits_per_word); 18963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 19063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = hw->regs->psc_spicfg; 1912f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 19263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; 1932f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 19463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 19563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (spi->mode & SPI_CPOL) 19663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_BI; 19763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko else 19863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_BI; 19963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (spi->mode & SPI_CPHA) 20063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_CDE; 20163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko else 20263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_CDE; 20363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 20463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (spi->mode & SPI_LSB_FIRST) 20563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_MLF; 20663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko else 20763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_MLF; 20863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 20963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->usedma && spi->bits_per_word <= 8) 21063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_DD_DISABLE; 21163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko else 21263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_DD_DISABLE; 21363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = PSC_SPICFG_CLR_LEN(cfg); 21463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_SET_LEN(spi->bits_per_word); 21563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 21663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = PSC_SPICFG_CLR_BAUD(cfg); 21763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_SET_DIV(3); 21863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= au1550_spi_baudcfg(hw, spi->max_speed_hz); 21963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 22063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg = cfg | PSC_SPICFG_DE_ENABLE; 2212f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 22263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko do { 22363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 2242f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 22563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } while ((stat & PSC_SPISTAT_DR) == 0); 22663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 22763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->pdata->activate_cs) 22863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->pdata->activate_cs(hw->pdata, spi->chip_select, 22963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cspol); 23063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko break; 23163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 23263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 23363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 23463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic int au1550_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t) 23563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 23663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = spi_master_get_devdata(spi->master); 23763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko unsigned bpw, hz; 23863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 cfg, stat; 23963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 24004ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko bpw = spi->bits_per_word; 24104ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko hz = spi->max_speed_hz; 24204ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko if (t) { 24304ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko if (t->bits_per_word) 24404ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko bpw = t->bits_per_word; 24504ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko if (t->speed_hz) 24604ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko hz = t->speed_hz; 24704ba24b34ac8ea4885295a7f7f78f719bc8c859bJan Nikitenko } 24863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 2490dd26e53b56137431e373c781fe2984393c9d573Axel Lin if (!hz) 25063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return -EINVAL; 25163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 25263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_bits_handlers_set(hw, spi->bits_per_word); 25363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 25463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = hw->regs->psc_spicfg; 2552f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 25663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg = cfg & ~PSC_SPICFG_DE_ENABLE; 2572f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 25863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 25963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->usedma && bpw <= 8) 26063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_DD_DISABLE; 26163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko else 26263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_DD_DISABLE; 26363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = PSC_SPICFG_CLR_LEN(cfg); 26463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_SET_LEN(bpw); 26563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 26663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = PSC_SPICFG_CLR_BAUD(cfg); 26763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg &= ~PSC_SPICFG_SET_DIV(3); 26863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= au1550_spi_baudcfg(hw, hz); 26963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 27063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg = cfg; 2712f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 27263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 27363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (cfg & PSC_SPICFG_DE_ENABLE) { 27463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko do { 27563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 2762f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 27763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } while ((stat & PSC_SPISTAT_DR) == 0); 27863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 27963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 28063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_reset_fifos(hw); 28163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_mask_ack_all(hw); 28263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return 0; 28363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 28463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 28563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko/* 28663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * for dma spi transfers, we have to setup rx channel, otherwise there is 28763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * no reliable way how to recognize that spi transfer is done 28863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * dma complete callbacks are called before real spi transfer is finished 28963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * and if only tx dma channel is set up (and rx fifo overflow event masked) 29063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * spi master done event irq is not generated unless rx fifo is empty (emptied) 29163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * so we need rx tmp buffer to use for rx dma if user does not provide one 29263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 29363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic int au1550_spi_dma_rxtmp_alloc(struct au1550_spi *hw, unsigned size) 29463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 29563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf = kmalloc(size, GFP_KERNEL); 29663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (!hw->dma_rx_tmpbuf) 29763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return -ENOMEM; 29863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf_size = size; 29963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf_addr = dma_map_single(hw->dev, hw->dma_rx_tmpbuf, 30063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko size, DMA_FROM_DEVICE); 3018d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06FUJITA Tomonori if (dma_mapping_error(hw->dev, hw->dma_rx_tmpbuf_addr)) { 30263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko kfree(hw->dma_rx_tmpbuf); 30363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf = 0; 30463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf_size = 0; 30563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return -EFAULT; 30663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 30763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return 0; 30863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 30963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 31063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_dma_rxtmp_free(struct au1550_spi *hw) 31163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 31263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_unmap_single(hw->dev, hw->dma_rx_tmpbuf_addr, 31363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf_size, DMA_FROM_DEVICE); 31463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko kfree(hw->dma_rx_tmpbuf); 31563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf = 0; 31663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_tmpbuf_size = 0; 31763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 31863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 31963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic int au1550_spi_dma_txrxb(struct spi_device *spi, struct spi_transfer *t) 32063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 32163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = spi_master_get_devdata(spi->master); 32263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_addr_t dma_tx_addr; 32363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_addr_t dma_rx_addr; 32463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 res; 32563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 32663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->len = t->len; 32763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_count = 0; 32863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_count = 0; 32963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 33063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx = t->tx_buf; 33163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx = t->rx_buf; 33263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_tx_addr = t->tx_dma; 33363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_rx_addr = t->rx_dma; 33463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 33563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* 3364e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko * check if buffers are already dma mapped, map them otherwise: 3374e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko * - first map the TX buffer, so cache data gets written to memory 3384e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko * - then map the RX buffer, so that cache entries (with 3394e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko * soon-to-be-stale data) get removed 34063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * use rx buffer in place of tx if tx buffer was not provided 34163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * use temp rx buffer (preallocated or realloc to fit) for rx dma 34263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 3434e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko if (t->tx_buf) { 3444e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko if (t->tx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ 3454e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko dma_tx_addr = dma_map_single(hw->dev, 3464e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko (void *)t->tx_buf, 3474e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko t->len, DMA_TO_DEVICE); 3484e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko if (dma_mapping_error(hw->dev, dma_tx_addr)) 3494e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko dev_err(hw->dev, "tx dma map error\n"); 3504e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko } 3514e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko } 3524e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko 35363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (t->rx_buf) { 35463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (t->rx_dma == 0) { /* if DMA_ADDR_INVALID, map it */ 35563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_rx_addr = dma_map_single(hw->dev, 35663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko (void *)t->rx_buf, 35763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko t->len, DMA_FROM_DEVICE); 3588d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06FUJITA Tomonori if (dma_mapping_error(hw->dev, dma_rx_addr)) 35963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(hw->dev, "rx dma map error\n"); 36063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 36163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } else { 36263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (t->len > hw->dma_rx_tmpbuf_size) { 36363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int ret; 36463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 36563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_dma_rxtmp_free(hw); 36663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko ret = au1550_spi_dma_rxtmp_alloc(hw, max(t->len, 36763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko AU1550_SPI_DMA_RXTMP_MINSIZE)); 36863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (ret < 0) 36963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return ret; 37063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 37163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx = hw->dma_rx_tmpbuf; 37263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_rx_addr = hw->dma_rx_tmpbuf_addr; 37363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_sync_single_for_device(hw->dev, dma_rx_addr, 37463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko t->len, DMA_FROM_DEVICE); 37563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 3764e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko 3774e253d23003b54c88d0919d6088be74f00eec3c7Jan Nikitenko if (!t->tx_buf) { 37863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_sync_single_for_device(hw->dev, dma_rx_addr, 37963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko t->len, DMA_BIDIRECTIONAL); 38063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx = hw->rx; 38163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 38263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 38363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* put buffers on the ring */ 384963accbc82a0912b39de39d59e2fd6741db3aa4bManuel Lauss res = au1xxx_dbdma_put_dest(hw->dma_rx_ch, virt_to_phys(hw->rx), 385ea071cc705e8bfba0c8bf84be8d4f9f4e9da6962Manuel Lauss t->len, DDMA_FLAGS_IE); 38663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (!res) 38763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(hw->dev, "rx dma put dest error\n"); 38863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 389963accbc82a0912b39de39d59e2fd6741db3aa4bManuel Lauss res = au1xxx_dbdma_put_source(hw->dma_tx_ch, virt_to_phys(hw->tx), 390ea071cc705e8bfba0c8bf84be8d4f9f4e9da6962Manuel Lauss t->len, DDMA_FLAGS_IE); 39163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (!res) 39263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(hw->dev, "tx dma put source error\n"); 39363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 39463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_start(hw->dma_rx_ch); 39563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_start(hw->dma_tx_ch); 39663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 39763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* by default enable nearly all events interrupt */ 39863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spimsk = PSC_SPIMSK_SD; 3992f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 40063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 40163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* start the transfer */ 40263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spipcr = PSC_SPIPCR_MS; 4032f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 40463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 40563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko wait_for_completion(&hw->master_done); 40663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 40763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_stop(hw->dma_tx_ch); 40863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_stop(hw->dma_rx_ch); 40963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 41063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (!t->rx_buf) { 41163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* using the temporal preallocated and premapped buffer */ 41263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_sync_single_for_cpu(hw->dev, dma_rx_addr, t->len, 41363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko DMA_FROM_DEVICE); 41463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 41563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* unmap buffers if mapped above */ 41663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (t->rx_buf && t->rx_dma == 0 ) 41763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_unmap_single(hw->dev, dma_rx_addr, t->len, 41863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko DMA_FROM_DEVICE); 41963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (t->tx_buf && t->tx_dma == 0 ) 42063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dma_unmap_single(hw->dev, dma_tx_addr, t->len, 42163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko DMA_TO_DEVICE); 42263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 42363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count; 42463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 42563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 42663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic irqreturn_t au1550_spi_dma_irq_callback(struct au1550_spi *hw) 42763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 42863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 stat, evnt; 42963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 43063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 43163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko evnt = hw->regs->psc_spievent; 4322f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 43363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if ((stat & PSC_SPISTAT_DI) == 0) { 43463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(hw->dev, "Unexpected IRQ!\n"); 43563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return IRQ_NONE; 43663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 43763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 43863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO 43963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO 44063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIEVNT_TU | PSC_SPIEVNT_SD)) 44163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko != 0) { 44263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* 44363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * due to an spi error we consider transfer as done, 44463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * so mask all events until before next transfer start 445886db6acf468bb6684e936a5456d470c69a75ef8Masanari Iida * and stop the possibly running dma immediately 44663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 44763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_mask_ack_all(hw); 44863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_stop(hw->dma_rx_ch); 44963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_stop(hw->dma_tx_ch); 45063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 45125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* get number of transferred bytes */ 45263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_count = hw->len - au1xxx_get_dma_residue(hw->dma_rx_ch); 45363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_count = hw->len - au1xxx_get_dma_residue(hw->dma_tx_ch); 45463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 45563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_reset(hw->dma_rx_ch); 45663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_reset(hw->dma_tx_ch); 45763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_reset_fifos(hw); 45863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 459bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko if (evnt == PSC_SPIEVNT_RO) 460bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko dev_err(hw->dev, 461bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko "dma transfer: receive FIFO overflow!\n"); 462bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko else 463bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko dev_err(hw->dev, 464bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko "dma transfer: unexpected SPI error " 465bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko "(event=0x%x stat=0x%x)!\n", evnt, stat); 46663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 46763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko complete(&hw->master_done); 46863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return IRQ_HANDLED; 46963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 47063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 47163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if ((evnt & PSC_SPIEVNT_MD) != 0) { 47263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* transfer completed successfully */ 47363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_mask_ack_all(hw); 47463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_count = hw->len; 47563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_count = hw->len; 47663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko complete(&hw->master_done); 47763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 47863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return IRQ_HANDLED; 47963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 48063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 48163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 48263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko/* routines to handle different word sizes in pio mode */ 48363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#define AU1550_SPI_RX_WORD(size, mask) \ 48463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_rx_word_##size(struct au1550_spi *hw) \ 48563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ \ 48663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 fifoword = hw->regs->psc_spitxrx & (u32)(mask); \ 4872f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ \ 48863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->rx) { \ 48963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko *(u##size *)hw->rx = (u##size)fifoword; \ 49063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx += (size) / 8; \ 49163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } \ 49263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_count += (size) / 8; \ 49363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 49463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 49563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#define AU1550_SPI_TX_WORD(size, mask) \ 49663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_tx_word_##size(struct au1550_spi *hw) \ 49763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ \ 49863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 fifoword = 0; \ 49963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->tx) { \ 50063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko fifoword = *(u##size *)hw->tx & (u32)(mask); \ 50163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx += (size) / 8; \ 50263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } \ 50363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_count += (size) / 8; \ 50463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->tx_count >= hw->len) \ 50563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko fifoword |= PSC_SPITXRX_LC; \ 50663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spitxrx = fifoword; \ 5072f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ \ 50863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 50963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 51063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoAU1550_SPI_RX_WORD(8,0xff) 51163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoAU1550_SPI_RX_WORD(16,0xffff) 51263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoAU1550_SPI_RX_WORD(32,0xffffff) 51363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoAU1550_SPI_TX_WORD(8,0xff) 51463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoAU1550_SPI_TX_WORD(16,0xffff) 51563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoAU1550_SPI_TX_WORD(32,0xffffff) 51663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 51763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic int au1550_spi_pio_txrxb(struct spi_device *spi, struct spi_transfer *t) 51863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 51963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 stat, mask; 52063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = spi_master_get_devdata(spi->master); 52163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 52263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx = t->tx_buf; 52363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx = t->rx_buf; 52463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->len = t->len; 52563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_count = 0; 52663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_count = 0; 52763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 52863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* by default enable nearly all events after filling tx fifo */ 52963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko mask = PSC_SPIMSK_SD; 53063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 53163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* fill the transmit FIFO */ 53263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko while (hw->tx_count < hw->len) { 53363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 53463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_word(hw); 53563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 53663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->tx_count >= hw->len) { 53763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* mask tx fifo request interrupt as we are done */ 53863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko mask |= PSC_SPIMSK_TR; 53963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 54063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 54163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 5422f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 54363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (stat & PSC_SPISTAT_TF) 54463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko break; 54563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 54663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 54763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* enable event interrupts */ 54863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spimsk = mask; 5492f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 55063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 55163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* start the transfer */ 55263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spipcr = PSC_SPIPCR_MS; 5532f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 55463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 55563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko wait_for_completion(&hw->master_done); 55663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 55763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return hw->rx_count < hw->tx_count ? hw->rx_count : hw->tx_count; 55863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 55963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 56063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic irqreturn_t au1550_spi_pio_irq_callback(struct au1550_spi *hw) 56163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 56263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int busy; 56363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 stat, evnt; 56463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 56563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 56663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko evnt = hw->regs->psc_spievent; 5672f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 56863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if ((stat & PSC_SPISTAT_DI) == 0) { 56963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(hw->dev, "Unexpected IRQ!\n"); 57063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return IRQ_NONE; 57163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 57263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 57363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if ((evnt & (PSC_SPIEVNT_MM | PSC_SPIEVNT_RO 57463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko | PSC_SPIEVNT_RU | PSC_SPIEVNT_TO 575bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko | PSC_SPIEVNT_SD)) 57663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko != 0) { 57763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* 57863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * due to an error we consider transfer as done, 57963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * so mask all events until before next transfer start 58063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 58163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_mask_ack_all(hw); 58263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_reset_fifos(hw); 583bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko dev_err(hw->dev, 584bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko "pio transfer: unexpected SPI error " 585bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko "(event=0x%x stat=0x%x)!\n", evnt, stat); 58663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko complete(&hw->master_done); 58763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return IRQ_HANDLED; 58863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 58963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 59063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* 59163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * while there is something to read from rx fifo 59263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * or there is a space to write to tx fifo: 59363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 59463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko do { 59563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko busy = 0; 59663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 5972f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 59863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 599bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko /* 600bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * Take care to not let the Rx FIFO overflow. 601bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * 602bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * We only write a byte if we have read one at least. Initially, 603bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * the write fifo is full, so we should read from the read fifo 604bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * first. 605bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * In case we miss a word from the read fifo, we should get a 606bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * RO event and should back out. 607bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko */ 608bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko if (!(stat & PSC_SPISTAT_RE) && hw->rx_count < hw->len) { 60963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_word(hw); 61063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko busy = 1; 61163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 612bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko if (!(stat & PSC_SPISTAT_TF) && hw->tx_count < hw->len) 613bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko hw->tx_word(hw); 61463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 61563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } while (busy); 61663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 617bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko hw->regs->psc_spievent = PSC_SPIEVNT_RR | PSC_SPIEVNT_TR; 6182f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 61963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 620bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko /* 621bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * Restart the SPI transmission in case of a transmit underflow. 622bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * This seems to work despite the notes in the Au1550 data book 623bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * of Figure 8-4 with flowchart for SPI master operation: 624bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * 625bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * """Note 1: An XFR Error Interrupt occurs, unless masked, 626bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * for any of the following events: Tx FIFO Underflow, 627bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * Rx FIFO Overflow, or Multiple-master Error 628bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * Note 2: In case of a Tx Underflow Error, all zeroes are 629bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * transmitted.""" 630bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * 631bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * By simply restarting the spi transfer on Tx Underflow Error, 632bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * we assume that spi transfer was paused instead of zeroes 633bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko * transmittion mentioned in the Note 2 of Au1550 data book. 634bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko */ 635bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko if (evnt & PSC_SPIEVNT_TU) { 636bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko hw->regs->psc_spievent = PSC_SPIEVNT_TU | PSC_SPIEVNT_MD; 6372f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 638bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko hw->regs->psc_spipcr = PSC_SPIPCR_MS; 6392f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 640bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko } 641bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko 642bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko if (hw->rx_count >= hw->len) { 64363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* transfer completed successfully */ 64463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_mask_ack_all(hw); 64563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko complete(&hw->master_done); 64663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 64763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return IRQ_HANDLED; 64863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 64963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 65063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic int au1550_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) 65163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 65263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = spi_master_get_devdata(spi->master); 65363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return hw->txrx_bufs(spi, t); 65463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 65563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 65640369e1cdb71287662213ae214842899e77a0544Jan Nikitenkostatic irqreturn_t au1550_spi_irq(int irq, void *dev) 65763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 65863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = dev; 65963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return hw->irq_callback(hw); 66063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 66163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 66263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void au1550_spi_bits_handlers_set(struct au1550_spi *hw, int bpw) 66363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 66463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (bpw <= 8) { 66563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->usedma) { 66663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->txrx_bufs = &au1550_spi_dma_txrxb; 66763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->irq_callback = &au1550_spi_dma_irq_callback; 66863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } else { 66963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_word = &au1550_spi_rx_word_8; 67063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_word = &au1550_spi_tx_word_8; 67163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->txrx_bufs = &au1550_spi_pio_txrxb; 67263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->irq_callback = &au1550_spi_pio_irq_callback; 67363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 67463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } else if (bpw <= 16) { 67563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_word = &au1550_spi_rx_word_16; 67663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_word = &au1550_spi_tx_word_16; 67763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->txrx_bufs = &au1550_spi_pio_txrxb; 67863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->irq_callback = &au1550_spi_pio_irq_callback; 67963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } else { 68063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->rx_word = &au1550_spi_rx_word_32; 68163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->tx_word = &au1550_spi_tx_word_32; 68263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->txrx_bufs = &au1550_spi_pio_txrxb; 68363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->irq_callback = &au1550_spi_pio_irq_callback; 68463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 68563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 68663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 6872deff8d602e8c9a2cab4b070be829294e1211f2cGrant Likelystatic void au1550_spi_setup_psc_as_spi(struct au1550_spi *hw) 68863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 68963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko u32 stat, cfg; 69063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 69163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* set up the PSC for SPI mode */ 69263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_ctrl = PSC_CTRL_DISABLE; 6932f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 69463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_sel = PSC_SEL_PS_SPIMODE; 6952f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 69663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 69763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg = 0; 6982f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 69963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 70063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_ctrl = PSC_CTRL_ENABLE; 7012f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 70263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 70363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko do { 70463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 7052f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 70663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } while ((stat & PSC_SPISTAT_SR) == 0); 70763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 70863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 70963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg = hw->usedma ? 0 : PSC_SPICFG_DD_DISABLE; 71063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_SET_LEN(8); 71163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_RT_FIFO8 | PSC_SPICFG_TT_FIFO8; 71263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* use minimal allowed brg and div values as initial setting: */ 71363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_SET_BAUD(4) | PSC_SPICFG_SET_DIV(0); 71463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 71563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#ifdef AU1550_SPI_DEBUG_LOOPBACK 71663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko cfg |= PSC_SPICFG_LB; 71763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko#endif 71863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 71963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg = cfg; 7202f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 72163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 72263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_mask_ack_all(hw); 72363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 72463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->regs->psc_spicfg |= PSC_SPICFG_DE_ENABLE; 7252f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 72663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 72763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko do { 72863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko stat = hw->regs->psc_spistat; 7292f73bfbe0873452f4cd388ec2f67f8226fe93f79Manuel Lauss wmb(); /* drain writebuffer */ 73063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } while ((stat & PSC_SPISTAT_DR) == 0); 731bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko 732bbe48ecc7f6559318cfc6c023da225a0b0e14ab3Jan Nikitenko au1550_spi_reset_fifos(hw); 73363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 73463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 73563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7362deff8d602e8c9a2cab4b070be829294e1211f2cGrant Likelystatic int au1550_spi_probe(struct platform_device *pdev) 73763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 73863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw; 73963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct spi_master *master; 7403a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss struct resource *r; 74163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int err = 0; 74263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 74363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko master = spi_alloc_master(&pdev->dev, sizeof(struct au1550_spi)); 74463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (master == NULL) { 74563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, "No memory for spi_master\n"); 74663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENOMEM; 74763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_nomem; 74863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 74963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 750e7db06b5d5afcef15c4c3e61c3a7441ed7ad1407David Brownell /* the spi->mode bits understood by this driver: */ 751e7db06b5d5afcef15c4c3e61c3a7441ed7ad1407David Brownell master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; 75224778be20f87d5aadb19624fc768b3159fa43efcStephen Warren master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 24); 753e7db06b5d5afcef15c4c3e61c3a7441ed7ad1407David Brownell 75463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw = spi_master_get_devdata(master); 75563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 75694c69f765f1b4a658d96905ec59928e3e3e07e6aAxel Lin hw->master = master; 7578074cf063e410a2c0cf1704c3b31002e21f5df7cJingoo Han hw->pdata = dev_get_platdata(&pdev->dev); 75863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dev = &pdev->dev; 75963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 76063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->pdata == NULL) { 76163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, "No platform data supplied\n"); 76263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENOENT; 76363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_pdata; 76463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 76563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7663a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 7673a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (!r) { 7683a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss dev_err(&pdev->dev, "no IRQ\n"); 7693a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss err = -ENODEV; 7703a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss goto err_no_iores; 7713a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss } 7723a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->irq = r->start; 7733a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss 7743a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->usedma = 0; 7753a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss r = platform_get_resource(pdev, IORESOURCE_DMA, 0); 7763a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (r) { 7773a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->dma_tx_id = r->start; 7783a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss r = platform_get_resource(pdev, IORESOURCE_DMA, 1); 7793a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (r) { 7803a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->dma_rx_id = r->start; 7813a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (usedma && ddma_memid) { 7823a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (pdev->dev.dma_mask == NULL) 7833a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss dev_warn(&pdev->dev, "no dma mask\n"); 7843a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss else 7853a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->usedma = 1; 7863a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss } 7873a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss } 7883a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss } 78963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7903a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 7913a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (!r) { 7923a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss dev_err(&pdev->dev, "no mmio resource\n"); 7933a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss err = -ENODEV; 7943a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss goto err_no_iores; 79563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 79663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 7973a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->ioarea = request_mem_region(r->start, sizeof(psc_spi_t), 7983a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss pdev->name); 7993a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (!hw->ioarea) { 80063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, "Cannot reserve iomem region\n"); 80163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENXIO; 80263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_iores; 80363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 80463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8053a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->regs = (psc_spi_t __iomem *)ioremap(r->start, sizeof(psc_spi_t)); 8063a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (!hw->regs) { 8073a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss dev_err(&pdev->dev, "cannot ioremap\n"); 8083a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss err = -ENXIO; 8093a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss goto err_ioremap; 81063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 81163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8123a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss platform_set_drvdata(pdev, hw); 81363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8143a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss init_completion(&hw->master_done); 8153a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss 8163a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->bitbang.master = hw->master; 8173a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->bitbang.setup_transfer = au1550_spi_setupxfer; 8183a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->bitbang.chipselect = au1550_spi_chipsel; 8193a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->bitbang.txrx_bufs = au1550_spi_txrx_bufs; 8203a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss 8213a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (hw->usedma) { 8223a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss hw->dma_tx_ch = au1xxx_dbdma_chan_alloc(ddma_memid, 82363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_tx_id, NULL, (void *)hw); 82463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->dma_tx_ch == 0) { 82563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, 82663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko "Cannot allocate tx dma channel\n"); 82763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENXIO; 82863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_txdma; 82963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 83063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_set_devwidth(hw->dma_tx_ch, 8); 83163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (au1xxx_dbdma_ring_alloc(hw->dma_tx_ch, 83263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko AU1550_SPI_DBDMA_DESCRIPTORS) == 0) { 83363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, 83463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko "Cannot allocate tx dma descriptors\n"); 83563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENXIO; 83663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_txdma_descr; 83763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 83863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 83963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 84063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->dma_rx_ch = au1xxx_dbdma_chan_alloc(hw->dma_rx_id, 8413a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss ddma_memid, NULL, (void *)hw); 84263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->dma_rx_ch == 0) { 84363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, 84463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko "Cannot allocate rx dma channel\n"); 84563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENXIO; 84663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_rxdma; 84763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 84863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_set_devwidth(hw->dma_rx_ch, 8); 84963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (au1xxx_dbdma_ring_alloc(hw->dma_rx_ch, 85063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko AU1550_SPI_DBDMA_DESCRIPTORS) == 0) { 85163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, 85263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko "Cannot allocate rx dma descriptors\n"); 85363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = -ENXIO; 85463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_rxdma_descr; 85563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 85663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 85763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = au1550_spi_dma_rxtmp_alloc(hw, 85863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko AU1550_SPI_DMA_RXTMP_MINSIZE); 85963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (err < 0) { 86063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, 86163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko "Cannot allocate initial rx dma tmp buffer\n"); 86263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_dma_rxtmp_alloc; 86363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 86463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 86563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 86663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_bits_handlers_set(hw, 8); 86763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 86863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = request_irq(hw->irq, au1550_spi_irq, 0, pdev->name, hw); 86963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (err) { 87063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, "Cannot claim IRQ\n"); 87163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_no_irq; 87263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 87363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 8743a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss master->bus_num = pdev->id; 87563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko master->num_chipselect = hw->pdata->num_chipselect; 87663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 87763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko /* 87863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * precompute valid range for spi freq - from au1550 datasheet: 87963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * psc_tempclk = psc_mainclk / (2 << DIV) 88063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * spiclk = psc_tempclk / (2 * (BRG + 1)) 88163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * BRG valid range is 4..63 88263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * DIV valid range is 0..3 88363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * round the min and max frequencies to values that would still 88463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko * produce valid brg and div 88563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko */ 88663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko { 88763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int min_div = (2 << 0) * (2 * (4 + 1)); 88863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko int max_div = (2 << 3) * (2 * (63 + 1)); 8890dd26e53b56137431e373c781fe2984393c9d573Axel Lin master->max_speed_hz = hw->pdata->mainclk_hz / min_div; 8900dd26e53b56137431e373c781fe2984393c9d573Axel Lin master->min_speed_hz = 8910dd26e53b56137431e373c781fe2984393c9d573Axel Lin hw->pdata->mainclk_hz / (max_div + 1) + 1; 89263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 89363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 89463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_setup_psc_as_spi(hw); 89563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 89663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko err = spi_bitbang_start(&hw->bitbang); 89763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (err) { 89863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_err(&pdev->dev, "Failed to register SPI master\n"); 89963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko goto err_register; 90063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 90163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 90263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_info(&pdev->dev, 90363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko "spi master registered: bus_num=%d num_chipselect=%d\n", 90463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko master->bus_num, master->num_chipselect); 90563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 90663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return 0; 90763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 90863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_register: 90963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko free_irq(hw->irq, hw); 91063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 91163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_irq: 91263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_dma_rxtmp_free(hw); 91363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 91463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_dma_rxtmp_alloc: 91563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_rxdma_descr: 91663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->usedma) 91763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_chan_free(hw->dma_rx_ch); 91863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 91963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_rxdma: 92063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_txdma_descr: 92163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->usedma) 92263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_chan_free(hw->dma_tx_ch); 92363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 92463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_txdma: 9253a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss iounmap((void __iomem *)hw->regs); 9263a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss 9273a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lausserr_ioremap: 92830670539b867d08c1931abd4815699de5887ee58Himangi Saraogi release_mem_region(r->start, sizeof(psc_spi_t)); 92963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 93063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_iores: 93163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_no_pdata: 93263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko spi_master_put(hw->master); 93363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 93463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkoerr_nomem: 93563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return err; 93663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 93763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 9382deff8d602e8c9a2cab4b070be829294e1211f2cGrant Likelystatic int au1550_spi_remove(struct platform_device *pdev) 93963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 94063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko struct au1550_spi *hw = platform_get_drvdata(pdev); 94163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 94263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko dev_info(&pdev->dev, "spi master remove: bus_num=%d\n", 94363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko hw->master->bus_num); 94463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 94563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko spi_bitbang_stop(&hw->bitbang); 94663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko free_irq(hw->irq, hw); 9473a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss iounmap((void __iomem *)hw->regs); 94861a2381c7b28255b1b76405827da47104a3913a0Manuel Lauss release_mem_region(hw->ioarea->start, sizeof(psc_spi_t)); 94963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 95063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko if (hw->usedma) { 95163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1550_spi_dma_rxtmp_free(hw); 95263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_chan_free(hw->dma_rx_ch); 95363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko au1xxx_dbdma_chan_free(hw->dma_tx_ch); 95463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko } 95563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 95663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko spi_master_put(hw->master); 95763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko return 0; 95863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 95963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 9607e38c3c4453bdb5ffdf8bf0ff0d9a760540f0893Kay Sievers/* work with hotplug and coldplug */ 9617e38c3c4453bdb5ffdf8bf0ff0d9a760540f0893Kay SieversMODULE_ALIAS("platform:au1550-spi"); 9627e38c3c4453bdb5ffdf8bf0ff0d9a760540f0893Kay Sievers 96363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic struct platform_driver au1550_spi_drv = { 96475dab1bfbbaa54c4e8cdca0f46b4ed65492559c6Wolfram Sang .probe = au1550_spi_probe, 9652deff8d602e8c9a2cab4b070be829294e1211f2cGrant Likely .remove = au1550_spi_remove, 96663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .driver = { 96763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .name = "au1550-spi", 96863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko .owner = THIS_MODULE, 96963bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko }, 97063bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko}; 97163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 97263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic int __init au1550_spi_init(void) 97363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 9743a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss /* 9753a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss * create memory device with 8 bits dev_devwidth 9763a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss * needed for proper byte ordering to spi fifo 9773a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss */ 978970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss switch (alchemy_get_cputype()) { 979970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss case ALCHEMY_CPU_AU1550: 980970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss case ALCHEMY_CPU_AU1200: 981970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss case ALCHEMY_CPU_AU1300: 982970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss break; 983970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss default: 984970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss return -ENODEV; 985970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss } 986970e268d6ed1f1799829cc0c87ea271a9e127e79Manuel Lauss 9873a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (usedma) { 9883a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss ddma_memid = au1xxx_ddma_add_device(&au1550_spi_mem_dbdev); 9893a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (!ddma_memid) 9903a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss printk(KERN_ERR "au1550-spi: cannot add memory" 9913a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss "dbdma device\n"); 9923a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss } 99375dab1bfbbaa54c4e8cdca0f46b4ed65492559c6Wolfram Sang return platform_driver_register(&au1550_spi_drv); 99463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 99563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkomodule_init(au1550_spi_init); 99663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 99763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkostatic void __exit au1550_spi_exit(void) 99863bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko{ 9993a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss if (usedma && ddma_memid) 10003a93a159c61e38a12f7ecbb3a25cf3f012abcf7aManuel Lauss au1xxx_ddma_del_device(ddma_memid); 100163bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko platform_driver_unregister(&au1550_spi_drv); 100263bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko} 100363bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenkomodule_exit(au1550_spi_exit); 100463bd23591e6c3891d34e4c6dba7c6aa41b05caadJan Nikitenko 100563bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoMODULE_DESCRIPTION("Au1550 PSC SPI Driver"); 100663bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoMODULE_AUTHOR("Jan Nikitenko <jan.nikitenko@gmail.com>"); 100763bd23591e6c3891d34e4c6dba7c6aa41b05caadJan NikitenkoMODULE_LICENSE("GPL"); 1008