142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * MPC52xx SPI bus driver. 342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * Copyright (C) 2008 Secret Lab Technologies Ltd. 542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * This file is released under the GPLv2 742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * This is the driver for the MPC5200's dedicated SPI controller. 942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 1042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * Note: this driver does not support the MPC5200 PSC in SPI mode. For 1142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * that driver see drivers/spi/mpc52xx_psc_spi.c 1242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 1342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 1442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/module.h> 1542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/init.h> 1642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/errno.h> 1742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/of_platform.h> 1842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/interrupt.h> 1942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/delay.h> 2042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/spi/spi.h> 2142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <linux/io.h> 22b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu#include <linux/of_gpio.h> 235a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 2442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <asm/time.h> 2542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#include <asm/mpc52xx.h> 2642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 2742bbb70980f3720b0ae6da6af862af0e95a04351Grant LikelyMODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>"); 2842bbb70980f3720b0ae6da6af862af0e95a04351Grant LikelyMODULE_DESCRIPTION("MPC52xx SPI (non-PSC) Driver"); 2942bbb70980f3720b0ae6da6af862af0e95a04351Grant LikelyMODULE_LICENSE("GPL"); 3042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 3142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* Register offsets */ 3242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1 0x00 3342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_SPIE (1 << 7) 3442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_SPE (1 << 6) 3542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_MSTR (1 << 4) 3642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_CPOL (1 << 3) 3742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_CPHA (1 << 2) 3842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_SSOE (1 << 1) 3942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL1_LSBFE (1 << 0) 4042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 4142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_CTRL2 0x01 4242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_BRR 0x04 4342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 4442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_STATUS 0x05 4542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_STATUS_SPIF (1 << 7) 4642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_STATUS_WCOL (1 << 6) 4742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_STATUS_MODF (1 << 4) 4842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 4942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_DATA 0x09 5042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_PORTDATA 0x0d 5142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define SPI_DATADIR 0x10 5242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 5342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* FSM state return values */ 5442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define FSM_STOP 0 /* Nothing more for the state machine to */ 5542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* do. If something interesting happens */ 56937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang /* then an IRQ will be received */ 5742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define FSM_POLL 1 /* need to poll for completion, an IRQ is */ 5842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* not expected */ 5942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely#define FSM_CONTINUE 2 /* Keep iterating the state machine */ 6042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 6142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* Driver internal data */ 6242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystruct mpc52xx_spi { 6342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_master *master; 6442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely void __iomem *regs; 6542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int irq0; /* MODF irq */ 6642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int irq1; /* SPIF irq */ 67937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang unsigned int ipb_freq; 6842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 69937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang /* Statistics; not used now, but will be reintroduced for debugfs */ 7042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int msg_count; 7142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int wcol_count; 7242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int wcol_ticks; 7342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u32 wcol_tx_timestamp; 7442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int modf_count; 7542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int byte_count; 7642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 7742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct list_head queue; /* queue of pending messages */ 7842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spinlock_t lock; 7942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct work_struct work; 8042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 8142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Details of current transfer (length, and buffer pointers) */ 8242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_message *message; /* current message */ 8342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_transfer *transfer; /* current transfer */ 8442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int (*state)(int irq, struct mpc52xx_spi *ms, u8 status, u8 data); 8542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int len; 8642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int timestamp; 8742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u8 *rx_buf; 8842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely const u8 *tx_buf; 8942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int cs_change; 90b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu int gpio_cs_count; 91b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu unsigned int *gpio_cs; 9242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely}; 9342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 9442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 9542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * CS control function 9642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 9742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic void mpc52xx_spi_chipsel(struct mpc52xx_spi *ms, int value) 9842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 99b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu int cs; 100b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 101b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu if (ms->gpio_cs_count > 0) { 102b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu cs = ms->message->spi->chip_select; 103b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu gpio_set_value(ms->gpio_cs[cs], value ? 0 : 1); 104b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu } else 105b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu out_8(ms->regs + SPI_PORTDATA, value ? 0 : 0x08); 10642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 10742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 10842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 10942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * Start a new transfer. This is called both by the idle state 11042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * for the first transfer in a message, and by the wait state when the 11142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * previous transfer in a message is complete. 11242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 11342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic void mpc52xx_spi_start_transfer(struct mpc52xx_spi *ms) 11442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 11542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->rx_buf = ms->transfer->rx_buf; 11642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->tx_buf = ms->transfer->tx_buf; 11742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->len = ms->transfer->len; 11842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 11942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Activate the chip select */ 12042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->cs_change) 12142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_chipsel(ms, 1); 12242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->cs_change = ms->transfer->cs_change; 12342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 12442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Write out the first byte */ 12542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->wcol_tx_timestamp = get_tbl(); 12642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->tx_buf) 12742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_DATA, *ms->tx_buf++); 12842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely else 12942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_DATA, 0); 13042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 13142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 13242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* Forward declaration of state handlers */ 13342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms, 13442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u8 status, u8 data); 13542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int mpc52xx_spi_fsmstate_wait(int irq, struct mpc52xx_spi *ms, 13642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u8 status, u8 data); 13742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 13842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 13942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * IDLE state 14042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 14142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * No transfers are in progress; if another transfer is pending then retrieve 14242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * it and kick it off. Otherwise, stop processing the state machine 14342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 14442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int 14542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelympc52xx_spi_fsmstate_idle(int irq, struct mpc52xx_spi *ms, u8 status, u8 data) 14642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 14742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_device *spi; 14842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int spr, sppr; 14942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u8 ctrl1; 15042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 15142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (status && (irq != NO_IRQ)) 15242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_err(&ms->master->dev, "spurious irq, status=0x%.2x\n", 15342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely status); 15442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 15542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Check if there is another transfer waiting. */ 15642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (list_empty(&ms->queue)) 15742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_STOP; 15842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 15942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* get the head of the queue */ 16042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->message = list_first_entry(&ms->queue, struct spi_message, queue); 16142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely list_del_init(&ms->message->queue); 16242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 16342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Setup the controller parameters */ 16442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ctrl1 = SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR; 16542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spi = ms->message->spi; 16642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spi->mode & SPI_CPHA) 16742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ctrl1 |= SPI_CTRL1_CPHA; 16842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spi->mode & SPI_CPOL) 16942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ctrl1 |= SPI_CTRL1_CPOL; 17042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spi->mode & SPI_LSB_FIRST) 17142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ctrl1 |= SPI_CTRL1_LSBFE; 17242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_CTRL1, ctrl1); 17342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 17442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Setup the controller speed */ 17542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* minimum divider is '2'. Also, add '1' to force rounding the 17642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * divider up. */ 17742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely sppr = ((ms->ipb_freq / ms->message->spi->max_speed_hz) + 1) >> 1; 17842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spr = 0; 17942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (sppr < 1) 18042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely sppr = 1; 18142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely while (((sppr - 1) & ~0x7) != 0) { 18242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely sppr = (sppr + 1) >> 1; /* add '1' to force rounding up */ 18342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spr++; 18442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 18542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely sppr--; /* sppr quantity in register is offset by 1 */ 18642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spr > 7) { 18742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Don't overrun limits of SPI baudrate register */ 18842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spr = 7; 18942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely sppr = 7; 19042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 19142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_BRR, sppr << 4 | spr); /* Set speed */ 19242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 19342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->cs_change = 1; 19442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->transfer = container_of(ms->message->transfers.next, 19542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_transfer, transfer_list); 19642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 19742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_start_transfer(ms); 19842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->state = mpc52xx_spi_fsmstate_transfer; 19942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 20042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 20142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 20242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 20342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 20442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * TRANSFER state 20542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 20642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * In the middle of a transfer. If the SPI core has completed processing 20742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * a byte, then read out the received data and write out the next byte 20842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * (unless this transfer is finished; in which case go on to the wait 20942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * state) 21042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 21142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int mpc52xx_spi_fsmstate_transfer(int irq, struct mpc52xx_spi *ms, 21242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u8 status, u8 data) 21342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 21442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (!status) 21542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return ms->irq0 ? FSM_STOP : FSM_POLL; 21642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 21742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (status & SPI_STATUS_WCOL) { 21842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* The SPI controller is stoopid. At slower speeds, it may 21942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * raise the SPIF flag before the state machine is actually 22042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * finished, which causes a collision (internal to the state 22142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * machine only). The manual recommends inserting a delay 22242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * between receiving the interrupt and sending the next byte, 22342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * but it can also be worked around simply by retrying the 22442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * transfer which is what we do here. */ 22542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->wcol_count++; 22642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->wcol_ticks += get_tbl() - ms->wcol_tx_timestamp; 22742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->wcol_tx_timestamp = get_tbl(); 22842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely data = 0; 22942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->tx_buf) 230937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang data = *(ms->tx_buf - 1); 23142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_DATA, data); /* try again */ 23242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 23342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } else if (status & SPI_STATUS_MODF) { 23442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->modf_count++; 23542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_err(&ms->master->dev, "mode fault\n"); 23642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_chipsel(ms, 0); 23742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->message->status = -EIO; 23842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->message->complete(ms->message->context); 23942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->state = mpc52xx_spi_fsmstate_idle; 24042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 24142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 24242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 24342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Read data out of the spi device */ 24442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->byte_count++; 24542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->rx_buf) 24642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely *ms->rx_buf++ = data; 24742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 24842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Is the transfer complete? */ 24942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->len--; 25042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->len == 0) { 25142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->timestamp = get_tbl(); 25242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->timestamp += ms->transfer->delay_usecs * tb_ticks_per_usec; 25342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->state = mpc52xx_spi_fsmstate_wait; 25442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 25542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 25642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 25742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Write out the next byte */ 25842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->wcol_tx_timestamp = get_tbl(); 25942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->tx_buf) 26042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_DATA, *ms->tx_buf++); 26142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely else 26242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(ms->regs + SPI_DATA, 0); 26342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 26442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 26542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 26642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 26742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 26842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * WAIT state 26942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * 27042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * A transfer has completed; need to wait for the delay period to complete 27142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * before starting the next transfer 27242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 27342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int 27442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelympc52xx_spi_fsmstate_wait(int irq, struct mpc52xx_spi *ms, u8 status, u8 data) 27542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 27642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (status && irq) 27742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_err(&ms->master->dev, "spurious irq, status=0x%.2x\n", 27842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely status); 27942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 28042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (((int)get_tbl()) - ms->timestamp < 0) 28142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_POLL; 28242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 28342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->message->actual_length += ms->transfer->len; 28442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 28542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Check if there is another transfer in this message. If there 28642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * aren't then deactivate CS, notify sender, and drop back to idle 28742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * to start the next message. */ 28842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->transfer->transfer_list.next == &ms->message->transfers) { 28942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->msg_count++; 29042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_chipsel(ms, 0); 29142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->message->status = 0; 29242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->message->complete(ms->message->context); 29342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->state = mpc52xx_spi_fsmstate_idle; 29442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 29542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 29642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 29742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* There is another transfer; kick it off */ 29842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 29942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->cs_change) 30042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_chipsel(ms, 0); 30142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 30242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->transfer = container_of(ms->transfer->transfer_list.next, 30342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_transfer, transfer_list); 30442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_start_transfer(ms); 30542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->state = mpc52xx_spi_fsmstate_transfer; 30642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return FSM_CONTINUE; 30742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 30842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 30942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/** 31042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * mpc52xx_spi_fsm_process - Finite State Machine iteration function 31142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * @irq: irq number that triggered the FSM or 0 for polling 31242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * @ms: pointer to mpc52xx_spi driver data 31342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 31442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic void mpc52xx_spi_fsm_process(int irq, struct mpc52xx_spi *ms) 31542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 31642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely int rc = FSM_CONTINUE; 31742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely u8 status, data; 31842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 31942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely while (rc == FSM_CONTINUE) { 32042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Interrupt cleared by read of STATUS followed by 32142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * read of DATA registers */ 32242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely status = in_8(ms->regs + SPI_STATUS); 32342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely data = in_8(ms->regs + SPI_DATA); 32442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely rc = ms->state(irq, ms, status, data); 32542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 32642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 32742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (rc == FSM_POLL) 32842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely schedule_work(&ms->work); 32942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 33042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 33142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/** 33242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * mpc52xx_spi_irq - IRQ handler 33342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 33442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic irqreturn_t mpc52xx_spi_irq(int irq, void *_ms) 33542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 33642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct mpc52xx_spi *ms = _ms; 33742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_lock(&ms->lock); 33842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_fsm_process(irq, ms); 33942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_unlock(&ms->lock); 34042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return IRQ_HANDLED; 34142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 34242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 34342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/** 34442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * mpc52xx_spi_wq - Workqueue function for polling the state machine 34542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 34642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic void mpc52xx_spi_wq(struct work_struct *work) 34742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 34842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct mpc52xx_spi *ms = container_of(work, struct mpc52xx_spi, work); 34942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely unsigned long flags; 35042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 35142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_lock_irqsave(&ms->lock, flags); 35242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely mpc52xx_spi_fsm_process(0, ms); 35342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_unlock_irqrestore(&ms->lock, flags); 35442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 35542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 35642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 35742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * spi_master ops 35842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 35942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 36042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int mpc52xx_spi_setup(struct spi_device *spi) 36142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 36242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spi->bits_per_word % 8) 36342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return -EINVAL; 36442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 36542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spi->mode & ~(SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST)) 36642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return -EINVAL; 36742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 36842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (spi->chip_select >= spi->master->num_chipselect) 36942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return -EINVAL; 37042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 37142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return 0; 37242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 37342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 37442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likelystatic int mpc52xx_spi_transfer(struct spi_device *spi, struct spi_message *m) 37542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 37642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct mpc52xx_spi *ms = spi_master_get_devdata(spi->master); 37742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely unsigned long flags; 37842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 37942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely m->actual_length = 0; 38042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely m->status = -EINPROGRESS; 38142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 38242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_lock_irqsave(&ms->lock, flags); 38342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely list_add_tail(&m->queue, &ms->queue); 38442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_unlock_irqrestore(&ms->lock, flags); 38542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely schedule_work(&ms->work); 38642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 38742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return 0; 38842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 38942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 39042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely/* 39142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * OF Platform Bus Binding 39242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely */ 39318d306d1375696b0e6b5b39e4744d7fa2ad5e170Grant Likelystatic int __devinit mpc52xx_spi_probe(struct platform_device *op) 39442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 39542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_master *master; 39642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct mpc52xx_spi *ms; 39742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely void __iomem *regs; 3984a495b1c43ed2e1495dad19987100ccd6c1575d7Luotao Fu u8 ctrl1; 399b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu int rc, i = 0; 400b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu int gpio_cs; 40142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 40242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* MMIO registers */ 40342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_dbg(&op->dev, "probing mpc5200 SPI device\n"); 40461c7a080a5a061c976988fd4b844dfb468dda255Grant Likely regs = of_iomap(op->dev.of_node, 0); 40542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (!regs) 40642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return -ENODEV; 40742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 40842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* initialize the device */ 4094a495b1c43ed2e1495dad19987100ccd6c1575d7Luotao Fu ctrl1 = SPI_CTRL1_SPIE | SPI_CTRL1_SPE | SPI_CTRL1_MSTR; 4104a495b1c43ed2e1495dad19987100ccd6c1575d7Luotao Fu out_8(regs + SPI_CTRL1, ctrl1); 41142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(regs + SPI_CTRL2, 0x0); 41242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(regs + SPI_DATADIR, 0xe); /* Set output pins */ 41342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely out_8(regs + SPI_PORTDATA, 0x8); /* Deassert /SS signal */ 41442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 41542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Clear the status register and re-read it to check for a MODF 41642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * failure. This driver cannot currently handle multiple masters 41742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * on the SPI bus. This fault will also occur if the SPI signals 41842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely * are not connected to any pins (port_config setting) */ 41942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely in_8(regs + SPI_STATUS); 4204a495b1c43ed2e1495dad19987100ccd6c1575d7Luotao Fu out_8(regs + SPI_CTRL1, ctrl1); 4214a495b1c43ed2e1495dad19987100ccd6c1575d7Luotao Fu 42242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely in_8(regs + SPI_DATA); 42342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (in_8(regs + SPI_STATUS) & SPI_STATUS_MODF) { 42442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_err(&op->dev, "mode fault; is port_config correct?\n"); 42542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely rc = -EIO; 42642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely goto err_init; 42742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 42842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 42942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_dbg(&op->dev, "allocating spi_master struct\n"); 43042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely master = spi_alloc_master(&op->dev, sizeof *ms); 43142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (!master) { 43242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely rc = -ENOMEM; 43342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely goto err_alloc; 43442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 435b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 43642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely master->bus_num = -1; 43742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely master->setup = mpc52xx_spi_setup; 43842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely master->transfer = mpc52xx_spi_transfer; 439d65aea99bd9e1d2e9560c5fff6c512d93c4a78d5Luotao Fu master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; 44012b15e83289bc7cf2ec9a342412e0c955beeb395Anatolij Gustschin master->dev.of_node = op->dev.of_node; 441d65aea99bd9e1d2e9560c5fff6c512d93c4a78d5Luotao Fu 44242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_set_drvdata(&op->dev, master); 44342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 44442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms = spi_master_get_devdata(master); 44542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->master = master; 44642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->regs = regs; 44761c7a080a5a061c976988fd4b844dfb468dda255Grant Likely ms->irq0 = irq_of_parse_and_map(op->dev.of_node, 0); 44861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely ms->irq1 = irq_of_parse_and_map(op->dev.of_node, 1); 44942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->state = mpc52xx_spi_fsmstate_idle; 45061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely ms->ipb_freq = mpc5xxx_get_bus_frequency(op->dev.of_node); 45161c7a080a5a061c976988fd4b844dfb468dda255Grant Likely ms->gpio_cs_count = of_gpio_count(op->dev.of_node); 452b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu if (ms->gpio_cs_count > 0) { 453b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu master->num_chipselect = ms->gpio_cs_count; 454b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu ms->gpio_cs = kmalloc(ms->gpio_cs_count * sizeof(unsigned int), 455b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu GFP_KERNEL); 456b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu if (!ms->gpio_cs) { 457b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu rc = -ENOMEM; 458b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu goto err_alloc; 459b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu } 460b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 461b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu for (i = 0; i < ms->gpio_cs_count; i++) { 46261c7a080a5a061c976988fd4b844dfb468dda255Grant Likely gpio_cs = of_get_gpio(op->dev.of_node, i); 463b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu if (gpio_cs < 0) { 464b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu dev_err(&op->dev, 465b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu "could not parse the gpio field " 466b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu "in oftree\n"); 467b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu rc = -ENODEV; 468b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu goto err_gpio; 469b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu } 470b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 471b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu rc = gpio_request(gpio_cs, dev_name(&op->dev)); 472b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu if (rc) { 473b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu dev_err(&op->dev, 474b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu "can't request spi cs gpio #%d " 475b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu "on gpio line %d\n", i, gpio_cs); 476b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu goto err_gpio; 477b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu } 478b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 479b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu gpio_direction_output(gpio_cs, 1); 480b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu ms->gpio_cs[i] = gpio_cs; 481b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu } 482937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang } else { 483b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu master->num_chipselect = 1; 484937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang } 485b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 48642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spin_lock_init(&ms->lock); 48742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely INIT_LIST_HEAD(&ms->queue); 48842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely INIT_WORK(&ms->work, mpc52xx_spi_wq); 48942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 49042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* Decide if interrupts can be used */ 49142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (ms->irq0 && ms->irq1) { 492937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang rc = request_irq(ms->irq0, mpc52xx_spi_irq, 0, 49342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely "mpc5200-spi-modf", ms); 494937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang rc |= request_irq(ms->irq1, mpc52xx_spi_irq, 0, 495937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang "mpc5200-spi-spif", ms); 49642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (rc) { 49742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely free_irq(ms->irq0, ms); 49842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely free_irq(ms->irq1, ms); 49942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->irq0 = ms->irq1 = 0; 50042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 50142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } else { 50242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely /* operate in polled mode */ 50342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely ms->irq0 = ms->irq1 = 0; 50442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely } 50542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 50642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (!ms->irq0) 50742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_info(&op->dev, "using polled mode\n"); 50842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 50942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_dbg(&op->dev, "registering spi_master struct\n"); 51042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely rc = spi_register_master(master); 51142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely if (rc) 51242bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely goto err_register; 51342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 51442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_info(&ms->master->dev, "registered MPC5200 SPI bus\n"); 51542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 51642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return rc; 51742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 51842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely err_register: 51942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely dev_err(&ms->master->dev, "initialization failed\n"); 52042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spi_master_put(master); 521b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu err_gpio: 522b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu while (i-- > 0) 523b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu gpio_free(ms->gpio_cs[i]); 524b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 525937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang kfree(ms->gpio_cs); 52642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely err_alloc: 52742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely err_init: 52842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely iounmap(regs); 52942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return rc; 53042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 53142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 5322dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int __devexit mpc52xx_spi_remove(struct platform_device *op) 53342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely{ 53442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct spi_master *master = dev_get_drvdata(&op->dev); 53542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely struct mpc52xx_spi *ms = spi_master_get_devdata(master); 536b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu int i; 53742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 53842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely free_irq(ms->irq0, ms); 53942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely free_irq(ms->irq1, ms); 54042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 541b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu for (i = 0; i < ms->gpio_cs_count; i++) 542b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu gpio_free(ms->gpio_cs[i]); 543b8d4e2ce60b63294e3408d1c5211b8a8dc4af095Luotao Fu 544937041e21634ffecc92d05cf693423a2c95b7252Wolfram Sang kfree(ms->gpio_cs); 54542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spi_unregister_master(master); 54642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely spi_master_put(master); 54742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely iounmap(ms->regs); 54842bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 54942bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely return 0; 55042bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely} 55142bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 552631e61b7ca12ef14c834f99f8948e410c539f585Márton Némethstatic const struct of_device_id mpc52xx_spi_match[] __devinitconst = { 55342bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely { .compatible = "fsl,mpc5200-spi", }, 55442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely {} 55542bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely}; 55642bbb70980f3720b0ae6da6af862af0e95a04351Grant LikelyMODULE_DEVICE_TABLE(of, mpc52xx_spi_match); 55742bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely 55818d306d1375696b0e6b5b39e4744d7fa2ad5e170Grant Likelystatic struct platform_driver mpc52xx_spi_of_driver = { 5594018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .driver = { 5604018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .name = "mpc52xx-spi", 5614018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .owner = THIS_MODULE, 5624018294b53d1dae026880e45f174c1cc63b5d435Grant Likely .of_match_table = mpc52xx_spi_match, 5634018294b53d1dae026880e45f174c1cc63b5d435Grant Likely }, 56442bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely .probe = mpc52xx_spi_probe, 5654bdac7da5237170b1392f39ebee99d235043fad8Wolfram Sang .remove = __devexit_p(mpc52xx_spi_remove), 56642bbb70980f3720b0ae6da6af862af0e95a04351Grant Likely}; 567940ab88962bc1aff3273a8356d64577a6e386736Grant Likelymodule_platform_driver(mpc52xx_spi_of_driver); 568