diff options
Diffstat (limited to 'drivers/spi/spi-tegra20-slink.c')
| -rw-r--r-- | drivers/spi/spi-tegra20-slink.c | 423 |
1 files changed, 152 insertions, 271 deletions
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index 651167f2e0a..0b9e32e9f49 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -23,7 +23,6 @@ #include <linux/dma-mapping.h> #include <linux/dmapool.h> #include <linux/err.h> -#include <linux/init.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/kernel.h> @@ -33,9 +32,8 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/reset.h> #include <linux/spi/spi.h> -#include <linux/spi/spi-tegra.h> -#include <mach/clk.h> #define SLINK_COMMAND 0x000 #define SLINK_BIT_LENGTH(x) (((x) & 0x1f) << 0) @@ -168,11 +166,10 @@ struct tegra_slink_data { spinlock_t lock; struct clk *clk; + struct reset_control *rst; void __iomem *base; phys_addr_t phys; unsigned irq; - int dma_req_sel; - u32 spi_max_frequency; u32 cur_speed; struct spi_device *cur_spi; @@ -189,7 +186,6 @@ struct tegra_slink_data { unsigned dma_buf_size; unsigned max_buf_size; bool is_curr_dma_xfer; - bool is_hw_based_cs; struct completion rx_dma_complete; struct completion tx_dma_complete; @@ -198,7 +194,7 @@ struct tegra_slink_data { u32 rx_status; u32 status_reg; bool is_packed; - unsigned long packed_size; + u32 packed_size; u32 command_reg; u32 command2_reg; @@ -222,14 +218,14 @@ struct tegra_slink_data { static int tegra_slink_runtime_suspend(struct device *dev); static int tegra_slink_runtime_resume(struct device *dev); -static inline unsigned long tegra_slink_readl(struct tegra_slink_data *tspi, +static inline u32 tegra_slink_readl(struct tegra_slink_data *tspi, unsigned long reg) { return readl(tspi->base + reg); } static inline void tegra_slink_writel(struct tegra_slink_data *tspi, - unsigned long val, unsigned long reg) + u32 val, unsigned long reg) { writel(val, tspi->base + reg); @@ -240,38 +236,30 @@ static inline void tegra_slink_writel(struct tegra_slink_data *tspi, static void tegra_slink_clear_status(struct tegra_slink_data *tspi) { - unsigned long val; - unsigned long val_write = 0; + u32 val_write; - val = tegra_slink_readl(tspi, SLINK_STATUS); + tegra_slink_readl(tspi, SLINK_STATUS); /* Write 1 to clear status register */ val_write = SLINK_RDY | SLINK_FIFO_ERROR; tegra_slink_writel(tspi, val_write, SLINK_STATUS); } -static unsigned long tegra_slink_get_packed_size(struct tegra_slink_data *tspi, +static u32 tegra_slink_get_packed_size(struct tegra_slink_data *tspi, struct spi_transfer *t) { - unsigned long val; - switch (tspi->bytes_per_word) { case 0: - val = SLINK_PACK_SIZE_4; - break; + return SLINK_PACK_SIZE_4; case 1: - val = SLINK_PACK_SIZE_8; - break; + return SLINK_PACK_SIZE_8; case 2: - val = SLINK_PACK_SIZE_16; - break; + return SLINK_PACK_SIZE_16; case 4: - val = SLINK_PACK_SIZE_32; - break; + return SLINK_PACK_SIZE_32; default: - val = 0; + return 0; } - return val; } static unsigned tegra_slink_calculate_curr_xfer_param( @@ -280,13 +268,12 @@ static unsigned tegra_slink_calculate_curr_xfer_param( { unsigned remain_len = t->len - tspi->cur_pos; unsigned max_word; - unsigned bits_per_word ; + unsigned bits_per_word; unsigned max_len; unsigned total_fifo_words; - bits_per_word = t->bits_per_word ? t->bits_per_word : - spi->bits_per_word; - tspi->bytes_per_word = (bits_per_word - 1) / 8 + 1; + bits_per_word = t->bits_per_word; + tspi->bytes_per_word = DIV_ROUND_UP(bits_per_word, 8); if (bits_per_word == 8 || bits_per_word == 16) { tspi->is_packed = 1; @@ -315,10 +302,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf( { unsigned nbytes; unsigned tx_empty_count; - unsigned long fifo_status; + u32 fifo_status; unsigned max_n_32bit; unsigned i, count; - unsigned long x; unsigned int written_words; unsigned fifo_words_left; u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos; @@ -332,9 +318,9 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf( nbytes = written_words * tspi->bytes_per_word; max_n_32bit = DIV_ROUND_UP(nbytes, 4); for (count = 0; count < max_n_32bit; count++) { - x = 0; + u32 x = 0; for (i = 0; (i < 4) && nbytes; i++, nbytes--) - x |= (*tx_buf++) << (i*8); + x |= (u32)(*tx_buf++) << (i * 8); tegra_slink_writel(tspi, x, SLINK_TX_FIFO); } } else { @@ -342,10 +328,10 @@ static unsigned tegra_slink_fill_tx_fifo_from_client_txbuf( written_words = max_n_32bit; nbytes = written_words * tspi->bytes_per_word; for (count = 0; count < max_n_32bit; count++) { - x = 0; + u32 x = 0; for (i = 0; nbytes && (i < tspi->bytes_per_word); i++, nbytes--) - x |= ((*tx_buf++) << i*8); + x |= (u32)(*tx_buf++) << (i * 8); tegra_slink_writel(tspi, x, SLINK_TX_FIFO); } } @@ -357,9 +343,8 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( struct tegra_slink_data *tspi, struct spi_transfer *t) { unsigned rx_full_count; - unsigned long fifo_status; + u32 fifo_status; unsigned i, count; - unsigned long x; unsigned int read_words = 0; unsigned len; u8 *rx_buf = (u8 *)t->rx_buf + tspi->cur_rx_pos; @@ -369,19 +354,15 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( if (tspi->is_packed) { len = tspi->curr_dma_words * tspi->bytes_per_word; for (count = 0; count < rx_full_count; count++) { - x = tegra_slink_readl(tspi, SLINK_RX_FIFO); + u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO); for (i = 0; len && (i < 4); i++, len--) *rx_buf++ = (x >> i*8) & 0xFF; } tspi->cur_rx_pos += tspi->curr_dma_words * tspi->bytes_per_word; read_words += tspi->curr_dma_words; } else { - unsigned int bits_per_word; - - bits_per_word = t->bits_per_word ? t->bits_per_word : - tspi->cur_spi->bits_per_word; for (count = 0; count < rx_full_count; count++) { - x = tegra_slink_readl(tspi, SLINK_RX_FIFO); + u32 x = tegra_slink_readl(tspi, SLINK_RX_FIFO); for (i = 0; (i < tspi->bytes_per_word); i++) *rx_buf++ = (x >> (i*8)) & 0xFF; } @@ -394,27 +375,24 @@ static unsigned int tegra_slink_read_rx_fifo_to_client_rxbuf( static void tegra_slink_copy_client_txbuf_to_spi_txbuf( struct tegra_slink_data *tspi, struct spi_transfer *t) { - unsigned len; - /* Make the dma buffer to read by cpu */ dma_sync_single_for_cpu(tspi->dev, tspi->tx_dma_phys, tspi->dma_buf_size, DMA_TO_DEVICE); if (tspi->is_packed) { - len = tspi->curr_dma_words * tspi->bytes_per_word; + unsigned len = tspi->curr_dma_words * tspi->bytes_per_word; memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len); } else { unsigned int i; unsigned int count; u8 *tx_buf = (u8 *)t->tx_buf + tspi->cur_tx_pos; unsigned consume = tspi->curr_dma_words * tspi->bytes_per_word; - unsigned int x; for (count = 0; count < tspi->curr_dma_words; count++) { - x = 0; + u32 x = 0; for (i = 0; consume && (i < tspi->bytes_per_word); i++, consume--) - x |= ((*tx_buf++) << i * 8); + x |= (u32)(*tx_buf++) << (i * 8); tspi->tx_dma_buf[count] = x; } } @@ -441,15 +419,10 @@ static void tegra_slink_copy_spi_rxbuf_to_client_rxbuf( unsigned int i; unsigned int count; unsigned char *rx_buf = t->rx_buf + tspi->cur_rx_pos; - unsigned int x; - unsigned int rx_mask, bits_per_word; + u32 rx_mask = ((u32)1 << t->bits_per_word) - 1; - bits_per_word = t->bits_per_word ? t->bits_per_word : - tspi->cur_spi->bits_per_word; - rx_mask = (1 << bits_per_word) - 1; for (count = 0; count < tspi->curr_dma_words; count++) { - x = tspi->rx_dma_buf[count]; - x &= rx_mask; + u32 x = tspi->rx_dma_buf[count] & rx_mask; for (i = 0; (i < tspi->bytes_per_word); i++) *rx_buf++ = (x >> (i*8)) & 0xFF; } @@ -470,7 +443,7 @@ static void tegra_slink_dma_complete(void *args) static int tegra_slink_start_tx_dma(struct tegra_slink_data *tspi, int len) { - INIT_COMPLETION(tspi->tx_dma_complete); + reinit_completion(&tspi->tx_dma_complete); tspi->tx_dma_desc = dmaengine_prep_slave_single(tspi->tx_dma_chan, tspi->tx_dma_phys, len, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -489,7 +462,7 @@ static int tegra_slink_start_tx_dma(struct tegra_slink_data *tspi, int len) static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len) { - INIT_COMPLETION(tspi->rx_dma_complete); + reinit_completion(&tspi->rx_dma_complete); tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma_chan, tspi->rx_dma_phys, len, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); @@ -509,17 +482,16 @@ static int tegra_slink_start_rx_dma(struct tegra_slink_data *tspi, int len) static int tegra_slink_start_dma_based_transfer( struct tegra_slink_data *tspi, struct spi_transfer *t) { - unsigned long val; - unsigned long test_val; + u32 val; unsigned int len; int ret = 0; - unsigned long status; + u32 status; /* Make sure that Rx and Tx fifo are empty */ status = tegra_slink_readl(tspi, SLINK_STATUS); if ((status & SLINK_FIFO_EMPTY) != SLINK_FIFO_EMPTY) { - dev_err(tspi->dev, - "Rx/Tx fifo are not empty status 0x%08lx\n", status); + dev_err(tspi->dev, "Rx/Tx fifo are not empty status 0x%08x\n", + (unsigned)status); return -EIO; } @@ -559,9 +531,9 @@ static int tegra_slink_start_dma_based_transfer( } /* Wait for tx fifo to be fill before starting slink */ - test_val = tegra_slink_readl(tspi, SLINK_STATUS); - while (!(test_val & SLINK_TX_FULL)) - test_val = tegra_slink_readl(tspi, SLINK_STATUS); + status = tegra_slink_readl(tspi, SLINK_STATUS); + while (!(status & SLINK_TX_FULL)) + status = tegra_slink_readl(tspi, SLINK_STATUS); } if (tspi->cur_direction & DATA_DIR_RX) { @@ -595,7 +567,7 @@ static int tegra_slink_start_dma_based_transfer( static int tegra_slink_start_cpu_based_transfer( struct tegra_slink_data *tspi, struct spi_transfer *t) { - unsigned long val; + u32 val; unsigned cur_words; val = tspi->packed_size; @@ -637,15 +609,15 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, dma_addr_t dma_phys; int ret; struct dma_slave_config dma_sconfig; - dma_cap_mask_t mask; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_chan = dma_request_channel(mask, NULL, NULL); - if (!dma_chan) { - dev_err(tspi->dev, - "Dma channel is not available, will try later\n"); - return -EPROBE_DEFER; + dma_chan = dma_request_slave_channel_reason(tspi->dev, + dma_to_memory ? "rx" : "tx"); + if (IS_ERR(dma_chan)) { + ret = PTR_ERR(dma_chan); + if (ret != -EPROBE_DEFER) + dev_err(tspi->dev, + "Dma channel is not available: %d\n", ret); + return ret; } dma_buf = dma_alloc_coherent(tspi->dev, tspi->dma_buf_size, @@ -656,7 +628,6 @@ static int tegra_slink_init_dma_param(struct tegra_slink_data *tspi, return -ENOMEM; } - dma_sconfig.slave_id = tspi->dma_req_sel; if (dma_to_memory) { dma_sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; dma_sconfig.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; @@ -715,22 +686,18 @@ static void tegra_slink_deinit_dma_param(struct tegra_slink_data *tspi, } static int tegra_slink_start_transfer_one(struct spi_device *spi, - struct spi_transfer *t, bool is_first_of_msg, - bool is_single_xfer) + struct spi_transfer *t) { struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); u32 speed; u8 bits_per_word; unsigned total_fifo_words; int ret; - struct tegra_spi_device_controller_data *cdata = spi->controller_data; - unsigned long command; - unsigned long command2; + u32 command; + u32 command2; bits_per_word = t->bits_per_word; - speed = t->speed_hz ? t->speed_hz : spi->max_speed_hz; - if (!speed) - speed = tspi->spi_max_frequency; + speed = t->speed_hz; if (speed != tspi->cur_speed) { clk_set_rate(tspi->clk, speed * 4); tspi->cur_speed = speed; @@ -743,60 +710,12 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, tspi->curr_xfer = t; total_fifo_words = tegra_slink_calculate_curr_xfer_param(spi, tspi, t); - if (is_first_of_msg) { - tegra_slink_clear_status(tspi); - - command = tspi->def_command_reg; - command |= SLINK_BIT_LENGTH(bits_per_word - 1); - - command2 = tspi->def_command2_reg; - command2 |= SLINK_SS_EN_CS(spi->chip_select); - - /* possibly use the hw based chip select */ - tspi->is_hw_based_cs = false; - if (cdata && cdata->is_hw_based_cs && is_single_xfer && - ((tspi->curr_dma_words * tspi->bytes_per_word) == - (t->len - tspi->cur_pos))) { - int setup_count; - int sts2; - - setup_count = cdata->cs_setup_clk_count >> 1; - setup_count = max(setup_count, 3); - command2 |= SLINK_SS_SETUP(setup_count); - if (tspi->chip_data->cs_hold_time) { - int hold_count; - - hold_count = cdata->cs_hold_clk_count; - hold_count = max(hold_count, 0xF); - sts2 = tegra_slink_readl(tspi, SLINK_STATUS2); - sts2 &= ~SLINK_SS_HOLD_TIME(0xF); - sts2 |= SLINK_SS_HOLD_TIME(hold_count); - tegra_slink_writel(tspi, sts2, SLINK_STATUS2); - } - tspi->is_hw_based_cs = true; - } - - if (tspi->is_hw_based_cs) - command &= ~SLINK_CS_SW; - else - command |= SLINK_CS_SW | SLINK_CS_VALUE; - - command &= ~SLINK_MODES; - if (spi->mode & SPI_CPHA) - command |= SLINK_CK_SDA; - - if (spi->mode & SPI_CPOL) - command |= SLINK_IDLE_SCLK_DRIVE_HIGH; - else - command |= SLINK_IDLE_SCLK_DRIVE_LOW; - } else { - command = tspi->command_reg; - command &= ~SLINK_BIT_LENGTH(~0); - command |= SLINK_BIT_LENGTH(bits_per_word - 1); + command = tspi->command_reg; + command &= ~SLINK_BIT_LENGTH(~0); + command |= SLINK_BIT_LENGTH(bits_per_word - 1); - command2 = tspi->command2_reg; - command2 &= ~(SLINK_RXEN | SLINK_TXEN); - } + command2 = tspi->command2_reg; + command2 &= ~(SLINK_RXEN | SLINK_TXEN); tegra_slink_writel(tspi, command, SLINK_COMMAND); tspi->command_reg = command; @@ -822,25 +741,24 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi, static int tegra_slink_setup(struct spi_device *spi) { - struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); - unsigned long val; - unsigned long flags; - int ret; - unsigned int cs_pol_bit[MAX_CHIP_SELECT] = { + static const u32 cs_pol_bit[MAX_CHIP_SELECT] = { SLINK_CS_POLARITY, SLINK_CS_POLARITY1, SLINK_CS_POLARITY2, SLINK_CS_POLARITY3, }; + struct tegra_slink_data *tspi = spi_master_get_devdata(spi->master); + u32 val; + unsigned long flags; + int ret; + dev_dbg(&spi->dev, "setup %d bpw, %scpol, %scpha, %dHz\n", spi->bits_per_word, spi->mode & SPI_CPOL ? "" : "~", spi->mode & SPI_CPHA ? "" : "~", spi->max_speed_hz); - BUG_ON(spi->chip_select >= MAX_CHIP_SELECT); - ret = pm_runtime_get_sync(tspi->dev); if (ret < 0) { dev_err(tspi->dev, "pm runtime failed, e = %d\n", ret); @@ -861,72 +779,72 @@ static int tegra_slink_setup(struct spi_device *spi) return 0; } -static int tegra_slink_prepare_transfer(struct spi_master *master) +static int tegra_slink_prepare_message(struct spi_master *master, + struct spi_message *msg) { struct tegra_slink_data *tspi = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; - return pm_runtime_get_sync(tspi->dev); -} + tegra_slink_clear_status(tspi); -static int tegra_slink_unprepare_transfer(struct spi_master *master) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); + tspi->command_reg = tspi->def_command_reg; + tspi->command_reg |= SLINK_CS_SW | SLINK_CS_VALUE; + + tspi->command2_reg = tspi->def_command2_reg; + tspi->command2_reg |= SLINK_SS_EN_CS(spi->chip_select); + + tspi->command_reg &= ~SLINK_MODES; + if (spi->mode & SPI_CPHA) + tspi->command_reg |= SLINK_CK_SDA; + + if (spi->mode & SPI_CPOL) + tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_HIGH; + else + tspi->command_reg |= SLINK_IDLE_SCLK_DRIVE_LOW; - pm_runtime_put(tspi->dev); return 0; } -static int tegra_slink_transfer_one_message(struct spi_master *master, - struct spi_message *msg) +static int tegra_slink_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *xfer) { - bool is_first_msg = true; - int single_xfer; struct tegra_slink_data *tspi = spi_master_get_devdata(master); - struct spi_transfer *xfer; - struct spi_device *spi = msg->spi; int ret; - msg->status = 0; - msg->actual_length = 0; - single_xfer = list_is_singular(&msg->transfers); - list_for_each_entry(xfer, &msg->transfers, transfer_list) { - INIT_COMPLETION(tspi->xfer_completion); - ret = tegra_slink_start_transfer_one(spi, xfer, - is_first_msg, single_xfer); - if (ret < 0) { - dev_err(tspi->dev, - "spi can not start transfer, err %d\n", ret); - goto exit; - } - is_first_msg = false; - ret = wait_for_completion_timeout(&tspi->xfer_completion, - SLINK_DMA_TIMEOUT); - if (WARN_ON(ret == 0)) { - dev_err(tspi->dev, - "spi trasfer timeout, err %d\n", ret); - ret = -EIO; - goto exit; - } + reinit_completion(&tspi->xfer_completion); + ret = tegra_slink_start_transfer_one(spi, xfer); + if (ret < 0) { + dev_err(tspi->dev, + "spi can not start transfer, err %d\n", ret); + return ret; + } - if (tspi->tx_status || tspi->rx_status) { - dev_err(tspi->dev, "Error in Transfer\n"); - ret = -EIO; - goto exit; - } - msg->actual_length += xfer->len; - if (xfer->cs_change && xfer->delay_usecs) { - tegra_slink_writel(tspi, tspi->def_command_reg, - SLINK_COMMAND); - udelay(xfer->delay_usecs); - } + ret = wait_for_completion_timeout(&tspi->xfer_completion, + SLINK_DMA_TIMEOUT); + if (WARN_ON(ret == 0)) { + dev_err(tspi->dev, + "spi trasfer timeout, err %d\n", ret); + return -EIO; } - ret = 0; -exit: + + if (tspi->tx_status) + return tspi->tx_status; + if (tspi->rx_status) + return tspi->rx_status; + + return 0; +} + +static int tegra_slink_unprepare_message(struct spi_master *master, + struct spi_message *msg) +{ + struct tegra_slink_data *tspi = spi_master_get_devdata(master); + tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); - msg->status = ret; - spi_finalize_current_message(master); - return ret; + + return 0; } static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) @@ -942,9 +860,9 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_slink_data *tspi) dev_err(tspi->dev, "CpuXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, tspi->command2_reg, tspi->dma_control_reg); - tegra_periph_reset_assert(tspi->clk); + reset_control_assert(tspi->rst); udelay(2); - tegra_periph_reset_deassert(tspi->clk); + reset_control_deassert(tspi->rst); complete(&tspi->xfer_completion); goto exit; } @@ -1015,9 +933,9 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_slink_data *tspi) dev_err(tspi->dev, "DmaXfer 0x%08x:0x%08x:0x%08x\n", tspi->command_reg, tspi->command2_reg, tspi->dma_control_reg); - tegra_periph_reset_assert(tspi->clk); + reset_control_assert(tspi->rst); udelay(2); - tegra_periph_reset_deassert(tspi->clk); + reset_control_assert(tspi->rst); complete(&tspi->xfer_completion); spin_unlock_irqrestore(&tspi->lock, flags); return IRQ_HANDLED; @@ -1075,40 +993,15 @@ static irqreturn_t tegra_slink_isr(int irq, void *context_data) return IRQ_WAKE_THREAD; } -static struct tegra_spi_platform_data *tegra_slink_parse_dt( - struct platform_device *pdev) -{ - struct tegra_spi_platform_data *pdata; - const unsigned int *prop; - struct device_node *np = pdev->dev.of_node; - u32 of_dma[2]; - - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(&pdev->dev, "Memory alloc for pdata failed\n"); - return NULL; - } - - if (of_property_read_u32_array(np, "nvidia,dma-request-selector", - of_dma, 2) >= 0) - pdata->dma_req_sel = of_dma[1]; - - prop = of_get_property(np, "spi-max-frequency", NULL); - if (prop) - pdata->spi_max_frequency = be32_to_cpup(prop); - - return pdata; -} - -const struct tegra_slink_chip_data tegra30_spi_cdata = { +static const struct tegra_slink_chip_data tegra30_spi_cdata = { .cs_hold_time = true, }; -const struct tegra_slink_chip_data tegra20_spi_cdata = { +static const struct tegra_slink_chip_data tegra20_spi_cdata = { .cs_hold_time = false, }; -static struct of_device_id tegra_slink_of_match[] = { +static const struct of_device_id tegra_slink_of_match[] = { { .compatible = "nvidia,tegra30-slink", .data = &tegra30_spi_cdata, }, { .compatible = "nvidia,tegra20-slink", .data = &tegra20_spi_cdata, }, {} @@ -1120,27 +1013,16 @@ static int tegra_slink_probe(struct platform_device *pdev) struct spi_master *master; struct tegra_slink_data *tspi; struct resource *r; - struct tegra_spi_platform_data *pdata = pdev->dev.platform_data; int ret, spi_irq; const struct tegra_slink_chip_data *cdata = NULL; const struct of_device_id *match; - match = of_match_device(of_match_ptr(tegra_slink_of_match), &pdev->dev); + match = of_match_device(tegra_slink_of_match, &pdev->dev); if (!match) { dev_err(&pdev->dev, "Error: No device match found\n"); return -ENODEV; } cdata = match->data; - if (!pdata && pdev->dev.of_node) - pdata = tegra_slink_parse_dt(pdev); - - if (!pdata) { - dev_err(&pdev->dev, "No platform data, exiting\n"); - return -ENODEV; - } - - if (!pdata->spi_max_frequency) - pdata->spi_max_frequency = 25000000; /* 25MHz */ master = spi_alloc_master(&pdev->dev, sizeof(*tspi)); if (!master) { @@ -1151,20 +1033,23 @@ static int tegra_slink_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->setup = tegra_slink_setup; - master->prepare_transfer_hardware = tegra_slink_prepare_transfer; - master->transfer_one_message = tegra_slink_transfer_one_message; - master->unprepare_transfer_hardware = tegra_slink_unprepare_transfer; + master->prepare_message = tegra_slink_prepare_message; + master->transfer_one = tegra_slink_transfer_one; + master->unprepare_message = tegra_slink_unprepare_message; + master->auto_runtime_pm = true; master->num_chipselect = MAX_CHIP_SELECT; - master->bus_num = -1; - dev_set_drvdata(&pdev->dev, master); + platform_set_drvdata(pdev, master); tspi = spi_master_get_devdata(master); tspi->master = master; - tspi->dma_req_sel = pdata->dma_req_sel; tspi->dev = &pdev->dev; tspi->chip_data = cdata; spin_lock_init(&tspi->lock); + if (of_property_read_u32(tspi->dev->of_node, "spi-max-frequency", + &master->max_speed_hz)) + master->max_speed_hz = 25000000; /* 25MHz */ + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "No IO memory resource\n"); @@ -1172,11 +1057,9 @@ static int tegra_slink_probe(struct platform_device *pdev) goto exit_free_master; } tspi->phys = r->start; - tspi->base = devm_request_and_ioremap(&pdev->dev, r); - if (!tspi->base) { - dev_err(&pdev->dev, - "Cannot request memregion/iomap dma address\n"); - ret = -EADDRNOTAVAIL; + tspi->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(tspi->base)) { + ret = PTR_ERR(tspi->base); goto exit_free_master; } @@ -1191,33 +1074,32 @@ static int tegra_slink_probe(struct platform_device *pdev) goto exit_free_master; } - tspi->clk = devm_clk_get(&pdev->dev, "slink"); + tspi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(tspi->clk)) { dev_err(&pdev->dev, "can not get clock\n"); ret = PTR_ERR(tspi->clk); goto exit_free_irq; } + tspi->rst = devm_reset_control_get(&pdev->dev, "spi"); + if (IS_ERR(tspi->rst)) { + dev_err(&pdev->dev, "can not get reset\n"); + ret = PTR_ERR(tspi->rst); + goto exit_free_irq; + } + tspi->max_buf_size = SLINK_FIFO_DEPTH << 2; tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN; - tspi->spi_max_frequency = pdata->spi_max_frequency; - - if (pdata->dma_req_sel) { - ret = tegra_slink_init_dma_param(tspi, true); - if (ret < 0) { - dev_err(&pdev->dev, "RxDma Init failed, err %d\n", ret); - goto exit_free_irq; - } - ret = tegra_slink_init_dma_param(tspi, false); - if (ret < 0) { - dev_err(&pdev->dev, "TxDma Init failed, err %d\n", ret); - goto exit_rx_dma_free; - } - tspi->max_buf_size = tspi->dma_buf_size; - init_completion(&tspi->tx_dma_complete); - init_completion(&tspi->rx_dma_complete); - } + ret = tegra_slink_init_dma_param(tspi, true); + if (ret < 0) + goto exit_free_irq; + ret = tegra_slink_init_dma_param(tspi, false); + if (ret < 0) + goto exit_rx_dma_free; + tspi->max_buf_size = tspi->dma_buf_size; + init_completion(&tspi->tx_dma_complete); + init_completion(&tspi->rx_dma_complete); init_completion(&tspi->xfer_completion); @@ -1240,7 +1122,7 @@ static int tegra_slink_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); master->dev.of_node = pdev->dev.of_node; - ret = spi_register_master(master); + ret = devm_spi_register_master(&pdev->dev, master); if (ret < 0) { dev_err(&pdev->dev, "can not register to master err %d\n", ret); goto exit_pm_disable; @@ -1263,11 +1145,10 @@ exit_free_master: static int tegra_slink_remove(struct platform_device *pdev) { - struct spi_master *master = dev_get_drvdata(&pdev->dev); + struct spi_master *master = platform_get_drvdata(pdev); struct tegra_slink_data *tspi = spi_master_get_devdata(master); free_irq(tspi->irq, tspi); - spi_unregister_master(master); if (tspi->tx_dma_chan) tegra_slink_deinit_dma_param(tspi, false); @@ -1345,7 +1226,7 @@ static struct platform_driver tegra_slink_driver = { .name = "spi-tegra-slink", .owner = THIS_MODULE, .pm = &slink_pm_ops, - .of_match_table = of_match_ptr(tegra_slink_of_match), + .of_match_table = tegra_slink_of_match, }, .probe = tegra_slink_probe, .remove = tegra_slink_remove, |
