Merge remote-tracking branches 'spi/topic/bcm53xx', 'spi/topic/cadence', 'spi/topic/checkpatch' and 'spi/topic/clps711x' into spi-next

This commit is contained in:
Mark Brown 2014-10-03 16:33:37 +01:00
Коммит 1fc8450313
15 изменённых файлов: 418 добавлений и 46 удалений

Просмотреть файл

@ -113,6 +113,14 @@ config SPI_AU1550
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
PSC SPI controller found on Au1550, Au1200 and Au1300 series. PSC SPI controller found on Au1550, Au1200 and Au1300 series.
config SPI_BCM53XX
tristate "Broadcom BCM53xx SPI controller"
depends on ARCH_BCM_5301X
depends on BCMA_POSSIBLE
select BCMA
help
Enable support for the SPI controller on Broadcom BCM53xx ARM SoCs.
config SPI_BCM63XX config SPI_BCM63XX
tristate "Broadcom BCM63xx SPI controller" tristate "Broadcom BCM63xx SPI controller"
depends on BCM63XX depends on BCM63XX

Просмотреть файл

@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
obj-$(CONFIG_SPI_ATH79) += spi-ath79.o obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
obj-$(CONFIG_SPI_AU1550) += spi-au1550.o obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o
obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o
obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o
obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o
obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o

299
drivers/spi/spi-bcm53xx.c Normal file
Просмотреть файл

@ -0,0 +1,299 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/bcma/bcma.h>
#include <linux/spi/spi.h>
#include "spi-bcm53xx.h"
#define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */
/* The longest observed required wait was 19 ms */
#define BCM53XXSPI_SPE_TIMEOUT_MS 80
struct bcm53xxspi {
struct bcma_device *core;
struct spi_master *master;
size_t read_offset;
};
static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset)
{
return bcma_read32(b53spi->core, offset);
}
static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset,
u32 value)
{
bcma_write32(b53spi->core, offset, value);
}
static inline unsigned int bcm53xxspi_calc_timeout(size_t len)
{
/* Do some magic calculation based on length and buad. Add 10% and 1. */
return (len * 9000 / BCM53XXSPI_MAX_SPI_BAUD * 110 / 100) + 1;
}
static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms)
{
unsigned long deadline;
u32 tmp;
/* SPE bit has to be 0 before we read MSPI STATUS */
deadline = jiffies + BCM53XXSPI_SPE_TIMEOUT_MS * HZ / 1000;
do {
tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
if (!(tmp & B53SPI_MSPI_SPCR2_SPE))
break;
udelay(5);
} while (!time_after_eq(jiffies, deadline));
if (tmp & B53SPI_MSPI_SPCR2_SPE)
goto spi_timeout;
/* Check status */
deadline = jiffies + timeout_ms * HZ / 1000;
do {
tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_MSPI_STATUS);
if (tmp & B53SPI_MSPI_MSPI_STATUS_SPIF) {
bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0);
return 0;
}
cpu_relax();
udelay(100);
} while (!time_after_eq(jiffies, deadline));
spi_timeout:
bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0);
pr_err("Timeout waiting for SPI to be ready!\n");
return -EBUSY;
}
static void bcm53xxspi_buf_write(struct bcm53xxspi *b53spi, u8 *w_buf,
size_t len, bool cont)
{
u32 tmp;
int i;
for (i = 0; i < len; i++) {
/* Transmit Register File MSB */
bcm53xxspi_write(b53spi, B53SPI_MSPI_TXRAM + 4 * (i * 2),
(unsigned int)w_buf[i]);
}
for (i = 0; i < len; i++) {
tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL |
B53SPI_CDRAM_PCS_DSCK;
if (!cont && i == len - 1)
tmp &= ~B53SPI_CDRAM_CONT;
tmp &= ~0x1;
/* Command Register File */
bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp);
}
/* Set queue pointers */
bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0);
bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, len - 1);
if (cont)
bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1);
/* Start SPI transfer */
tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
tmp |= B53SPI_MSPI_SPCR2_SPE;
if (cont)
tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD;
bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp);
/* Wait for SPI to finish */
bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len));
if (!cont)
bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0);
b53spi->read_offset = len;
}
static void bcm53xxspi_buf_read(struct bcm53xxspi *b53spi, u8 *r_buf,
size_t len, bool cont)
{
u32 tmp;
int i;
for (i = 0; i < b53spi->read_offset + len; i++) {
tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL |
B53SPI_CDRAM_PCS_DSCK;
if (!cont && i == b53spi->read_offset + len - 1)
tmp &= ~B53SPI_CDRAM_CONT;
tmp &= ~0x1;
/* Command Register File */
bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp);
}
/* Set queue pointers */
bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0);
bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP,
b53spi->read_offset + len - 1);
if (cont)
bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1);
/* Start SPI transfer */
tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2);
tmp |= B53SPI_MSPI_SPCR2_SPE;
if (cont)
tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD;
bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp);
/* Wait for SPI to finish */
bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len));
if (!cont)
bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0);
for (i = 0; i < len; ++i) {
int offset = b53spi->read_offset + i;
/* Data stored in the transmit register file LSB */
r_buf[i] = (u8)bcm53xxspi_read(b53spi, B53SPI_MSPI_RXRAM + 4 * (1 + offset * 2));
}
b53spi->read_offset = 0;
}
static int bcm53xxspi_transfer_one(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *t)
{
struct bcm53xxspi *b53spi = spi_master_get_devdata(master);
u8 *buf;
size_t left;
if (t->tx_buf) {
buf = (u8 *)t->tx_buf;
left = t->len;
while (left) {
size_t to_write = min_t(size_t, 16, left);
bool cont = left - to_write > 0;
bcm53xxspi_buf_write(b53spi, buf, to_write, cont);
left -= to_write;
buf += to_write;
}
}
if (t->rx_buf) {
buf = (u8 *)t->rx_buf;
left = t->len;
while (left) {
size_t to_read = min_t(size_t, 16 - b53spi->read_offset,
left);
bool cont = left - to_read > 0;
bcm53xxspi_buf_read(b53spi, buf, to_read, cont);
left -= to_read;
buf += to_read;
}
}
return 0;
}
/**************************************************
* BCMA
**************************************************/
static struct spi_board_info bcm53xx_info = {
.modalias = "bcm53xxspiflash",
};
static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl);
static int bcm53xxspi_bcma_probe(struct bcma_device *core)
{
struct bcm53xxspi *b53spi;
struct spi_master *master;
int err;
if (core->bus->drv_cc.core->id.rev != 42) {
pr_err("SPI on SoC with unsupported ChipCommon rev\n");
return -ENOTSUPP;
}
master = spi_alloc_master(&core->dev, sizeof(*b53spi));
if (!master)
return -ENOMEM;
b53spi = spi_master_get_devdata(master);
b53spi->master = master;
b53spi->core = core;
master->transfer_one = bcm53xxspi_transfer_one;
bcma_set_drvdata(core, b53spi);
err = devm_spi_register_master(&core->dev, master);
if (err) {
spi_master_put(master);
bcma_set_drvdata(core, NULL);
goto out;
}
/* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */
spi_new_device(master, &bcm53xx_info);
out:
return err;
}
static void bcm53xxspi_bcma_remove(struct bcma_device *core)
{
struct bcm53xxspi *b53spi = bcma_get_drvdata(core);
spi_unregister_master(b53spi->master);
}
static struct bcma_driver bcm53xxspi_bcma_driver = {
.name = KBUILD_MODNAME,
.id_table = bcm53xxspi_bcma_tbl,
.probe = bcm53xxspi_bcma_probe,
.remove = bcm53xxspi_bcma_remove,
};
/**************************************************
* Init & exit
**************************************************/
static int __init bcm53xxspi_module_init(void)
{
int err = 0;
err = bcma_driver_register(&bcm53xxspi_bcma_driver);
if (err)
pr_err("Failed to register bcma driver: %d\n", err);
return err;
}
static void __exit bcm53xxspi_module_exit(void)
{
bcma_driver_unregister(&bcm53xxspi_bcma_driver);
}
module_init(bcm53xxspi_module_init);
module_exit(bcm53xxspi_module_exit);
MODULE_DESCRIPTION("Broadcom BCM53xx SPI Controller driver");
MODULE_AUTHOR("Rafał Miłecki <zajec5@gmail.com>");
MODULE_LICENSE("GPL");

72
drivers/spi/spi-bcm53xx.h Normal file
Просмотреть файл

@ -0,0 +1,72 @@
#ifndef SPI_BCM53XX_H
#define SPI_BCM53XX_H
#define B53SPI_BSPI_REVISION_ID 0x000
#define B53SPI_BSPI_SCRATCH 0x004
#define B53SPI_BSPI_MAST_N_BOOT_CTRL 0x008
#define B53SPI_BSPI_BUSY_STATUS 0x00c
#define B53SPI_BSPI_INTR_STATUS 0x010
#define B53SPI_BSPI_B0_STATUS 0x014
#define B53SPI_BSPI_B0_CTRL 0x018
#define B53SPI_BSPI_B1_STATUS 0x01c
#define B53SPI_BSPI_B1_CTRL 0x020
#define B53SPI_BSPI_STRAP_OVERRIDE_CTRL 0x024
#define B53SPI_BSPI_FLEX_MODE_ENABLE 0x028
#define B53SPI_BSPI_BITS_PER_CYCLE 0x02c
#define B53SPI_BSPI_BITS_PER_PHASE 0x030
#define B53SPI_BSPI_CMD_AND_MODE_BYTE 0x034
#define B53SPI_BSPI_BSPI_FLASH_UPPER_ADDR_BYTE 0x038
#define B53SPI_BSPI_BSPI_XOR_VALUE 0x03c
#define B53SPI_BSPI_BSPI_XOR_ENABLE 0x040
#define B53SPI_BSPI_BSPI_PIO_MODE_ENABLE 0x044
#define B53SPI_BSPI_BSPI_PIO_IODIR 0x048
#define B53SPI_BSPI_BSPI_PIO_DATA 0x04c
/* RAF */
#define B53SPI_RAF_START_ADDR 0x100
#define B53SPI_RAF_NUM_WORDS 0x104
#define B53SPI_RAF_CTRL 0x108
#define B53SPI_RAF_FULLNESS 0x10c
#define B53SPI_RAF_WATERMARK 0x110
#define B53SPI_RAF_STATUS 0x114
#define B53SPI_RAF_READ_DATA 0x118
#define B53SPI_RAF_WORD_CNT 0x11c
#define B53SPI_RAF_CURR_ADDR 0x120
/* MSPI */
#define B53SPI_MSPI_SPCR0_LSB 0x200
#define B53SPI_MSPI_SPCR0_MSB 0x204
#define B53SPI_MSPI_SPCR1_LSB 0x208
#define B53SPI_MSPI_SPCR1_MSB 0x20c
#define B53SPI_MSPI_NEWQP 0x210
#define B53SPI_MSPI_ENDQP 0x214
#define B53SPI_MSPI_SPCR2 0x218
#define B53SPI_MSPI_SPCR2_SPE 0x00000040
#define B53SPI_MSPI_SPCR2_CONT_AFTER_CMD 0x00000080
#define B53SPI_MSPI_MSPI_STATUS 0x220
#define B53SPI_MSPI_MSPI_STATUS_SPIF 0x00000001
#define B53SPI_MSPI_CPTQP 0x224
#define B53SPI_MSPI_TXRAM 0x240 /* 32 registers, up to 0x2b8 */
#define B53SPI_MSPI_RXRAM 0x2c0 /* 32 registers, up to 0x33c */
#define B53SPI_MSPI_CDRAM 0x340 /* 16 registers, up to 0x37c */
#define B53SPI_CDRAM_PCS_PCS0 0x00000001
#define B53SPI_CDRAM_PCS_PCS1 0x00000002
#define B53SPI_CDRAM_PCS_PCS2 0x00000004
#define B53SPI_CDRAM_PCS_PCS3 0x00000008
#define B53SPI_CDRAM_PCS_DISABLE_ALL 0x0000000f
#define B53SPI_CDRAM_PCS_DSCK 0x00000010
#define B53SPI_CDRAM_BITSE 0x00000040
#define B53SPI_CDRAM_CONT 0x00000080
#define B53SPI_MSPI_WRITE_LOCK 0x380
#define B53SPI_MSPI_DISABLE_FLUSH_GEN 0x384
/* Interrupt */
#define B53SPI_INTR_RAF_LR_FULLNESS_REACHED 0x3a0
#define B53SPI_INTR_RAF_LR_TRUNCATED 0x3a4
#define B53SPI_INTR_RAF_LR_IMPATIENT 0x3a8
#define B53SPI_INTR_RAF_LR_SESSION_DONE 0x3ac
#define B53SPI_INTR_RAF_LR_OVERREAD 0x3b0
#define B53SPI_INTR_MSPI_DONE 0x3b4
#define B53SPI_INTR_MSPI_HALT_SET_TRANSACTION_DONE 0x3b8
#endif /* SPI_BCM53XX_H */

Просмотреть файл

@ -677,7 +677,6 @@ static struct platform_driver cdns_spi_driver = {
.remove = cdns_spi_remove, .remove = cdns_spi_remove,
.driver = { .driver = {
.name = CDNS_SPI_NAME, .name = CDNS_SPI_NAME,
.owner = THIS_MODULE,
.of_match_table = cdns_spi_of_match, .of_match_table = cdns_spi_of_match,
.pm = &cdns_spi_dev_pm_ops, .pm = &cdns_spi_dev_pm_ops,
}, },

Просмотреть файл

@ -30,7 +30,6 @@
struct spi_clps711x_data { struct spi_clps711x_data {
void __iomem *syncio; void __iomem *syncio;
struct regmap *syscon; struct regmap *syscon;
struct regmap *syscon1;
struct clk *spi_clk; struct clk *spi_clk;
u8 *tx_buf; u8 *tx_buf;
@ -47,27 +46,6 @@ static int spi_clps711x_setup(struct spi_device *spi)
return 0; return 0;
} }
static void spi_clps711x_setup_xfer(struct spi_device *spi,
struct spi_transfer *xfer)
{
struct spi_master *master = spi->master;
struct spi_clps711x_data *hw = spi_master_get_devdata(master);
/* Setup SPI frequency divider */
if (xfer->speed_hz >= master->max_speed_hz)
regmap_update_bits(hw->syscon1, SYSCON_OFFSET,
SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(3));
else if (xfer->speed_hz >= (master->max_speed_hz / 2))
regmap_update_bits(hw->syscon1, SYSCON_OFFSET,
SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(2));
else if (xfer->speed_hz >= (master->max_speed_hz / 8))
regmap_update_bits(hw->syscon1, SYSCON_OFFSET,
SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(1));
else
regmap_update_bits(hw->syscon1, SYSCON_OFFSET,
SYSCON1_ADCKSEL_MASK, SYSCON1_ADCKSEL(0));
}
static int spi_clps711x_prepare_message(struct spi_master *master, static int spi_clps711x_prepare_message(struct spi_master *master,
struct spi_message *msg) struct spi_message *msg)
{ {
@ -87,7 +65,7 @@ static int spi_clps711x_transfer_one(struct spi_master *master,
struct spi_clps711x_data *hw = spi_master_get_devdata(master); struct spi_clps711x_data *hw = spi_master_get_devdata(master);
u8 data; u8 data;
spi_clps711x_setup_xfer(spi, xfer); clk_set_rate(hw->spi_clk, xfer->speed_hz ? : spi->max_speed_hz);
hw->len = xfer->len; hw->len = xfer->len;
hw->bpw = xfer->bits_per_word; hw->bpw = xfer->bits_per_word;
@ -176,13 +154,11 @@ static int spi_clps711x_probe(struct platform_device *pdev)
} }
} }
hw->spi_clk = devm_clk_get(&pdev->dev, "spi"); hw->spi_clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(hw->spi_clk)) { if (IS_ERR(hw->spi_clk)) {
dev_err(&pdev->dev, "Can't get clocks\n");
ret = PTR_ERR(hw->spi_clk); ret = PTR_ERR(hw->spi_clk);
goto err_out; goto err_out;
} }
master->max_speed_hz = clk_get_rate(hw->spi_clk);
hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3"); hw->syscon = syscon_regmap_lookup_by_pdevname("syscon.3");
if (IS_ERR(hw->syscon)) { if (IS_ERR(hw->syscon)) {
@ -190,12 +166,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
goto err_out; goto err_out;
} }
hw->syscon1 = syscon_regmap_lookup_by_pdevname("syscon.1");
if (IS_ERR(hw->syscon1)) {
ret = PTR_ERR(hw->syscon1);
goto err_out;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hw->syncio = devm_ioremap_resource(&pdev->dev, res); hw->syncio = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(hw->syncio)) { if (IS_ERR(hw->syncio)) {

Просмотреть файл

@ -167,8 +167,10 @@ static void davinci_spi_rx_buf_u16(u32 data, struct davinci_spi *dspi)
static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi) static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi)
{ {
u32 data = 0; u32 data = 0;
if (dspi->tx) { if (dspi->tx) {
const u8 *tx = dspi->tx; const u8 *tx = dspi->tx;
data = *tx++; data = *tx++;
dspi->tx = tx; dspi->tx = tx;
} }
@ -178,8 +180,10 @@ static u32 davinci_spi_tx_buf_u8(struct davinci_spi *dspi)
static u32 davinci_spi_tx_buf_u16(struct davinci_spi *dspi) static u32 davinci_spi_tx_buf_u16(struct davinci_spi *dspi)
{ {
u32 data = 0; u32 data = 0;
if (dspi->tx) { if (dspi->tx) {
const u16 *tx = dspi->tx; const u16 *tx = dspi->tx;
data = *tx++; data = *tx++;
dspi->tx = tx; dspi->tx = tx;
} }
@ -996,8 +1000,8 @@ static int davinci_spi_probe(struct platform_device *pdev)
goto free_clk; goto free_clk;
dev_info(&pdev->dev, "DMA: supported\n"); dev_info(&pdev->dev, "DMA: supported\n");
dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, " dev_info(&pdev->dev, "DMA: RX channel: %pa, TX channel: %pa, event queue: %d\n",
"event queue: %d\n", &dma_rx_chan, &dma_tx_chan, &dma_rx_chan, &dma_tx_chan,
pdata->dma_event_q); pdata->dma_event_q);
} }

Просмотреть файл

@ -135,8 +135,7 @@ static int mrst_spi_debugfs_init(struct dw_spi *dws)
static void mrst_spi_debugfs_remove(struct dw_spi *dws) static void mrst_spi_debugfs_remove(struct dw_spi *dws)
{ {
if (dws->debugfs) debugfs_remove_recursive(dws->debugfs);
debugfs_remove_recursive(dws->debugfs);
} }
#else #else
@ -177,7 +176,7 @@ static inline u32 rx_max(struct dw_spi *dws)
{ {
u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes; u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes;
return min(rx_left, (u32)dw_readw(dws, DW_SPI_RXFLR)); return min_t(u32, rx_left, dw_readw(dws, DW_SPI_RXFLR));
} }
static void dw_writer(struct dw_spi *dws) static void dw_writer(struct dw_spi *dws)
@ -228,8 +227,9 @@ static void *next_transfer(struct dw_spi *dws)
struct spi_transfer, struct spi_transfer,
transfer_list); transfer_list);
return RUNNING_STATE; return RUNNING_STATE;
} else }
return DONE_STATE;
return DONE_STATE;
} }
/* /*
@ -471,10 +471,12 @@ static void pump_transfers(unsigned long data)
*/ */
if (!dws->dma_mapped && !chip->poll_mode) { if (!dws->dma_mapped && !chip->poll_mode) {
int templen = dws->len / dws->n_bytes; int templen = dws->len / dws->n_bytes;
txint_level = dws->fifo_len / 2; txint_level = dws->fifo_len / 2;
txint_level = (templen > txint_level) ? txint_level : templen; txint_level = (templen > txint_level) ? txint_level : templen;
imask |= SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI; imask |= SPI_INT_TXEI | SPI_INT_TXOI |
SPI_INT_RXUI | SPI_INT_RXOI;
dws->transfer_handler = interrupt_transfer; dws->transfer_handler = interrupt_transfer;
} }
@ -515,7 +517,6 @@ static void pump_transfers(unsigned long data)
early_exit: early_exit:
giveback(dws); giveback(dws);
return;
} }
static int dw_spi_transfer_one_message(struct spi_master *master, static int dw_spi_transfer_one_message(struct spi_master *master,
@ -626,6 +627,7 @@ static void spi_hw_init(struct dw_spi *dws)
*/ */
if (!dws->fifo_len) { if (!dws->fifo_len) {
u32 fifo; u32 fifo;
for (fifo = 2; fifo <= 257; fifo++) { for (fifo = 2; fifo <= 257; fifo++) {
dw_writew(dws, DW_SPI_TXFLTR, fifo); dw_writew(dws, DW_SPI_TXFLTR, fifo);
if (fifo != dw_readw(dws, DW_SPI_TXFLTR)) if (fifo != dw_readw(dws, DW_SPI_TXFLTR))

Просмотреть файл

@ -266,6 +266,7 @@ static int ep93xx_spi_setup(struct spi_device *spi)
if (chip->ops && chip->ops->setup) { if (chip->ops && chip->ops->setup) {
int ret = chip->ops->setup(spi); int ret = chip->ops->setup(spi);
if (ret) { if (ret) {
kfree(chip); kfree(chip);
return ret; return ret;

Просмотреть файл

@ -154,12 +154,14 @@ static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set)
static void mxs_ssp_dma_irq_callback(void *param) static void mxs_ssp_dma_irq_callback(void *param)
{ {
struct mxs_spi *spi = param; struct mxs_spi *spi = param;
complete(&spi->c); complete(&spi->c);
} }
static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id) static irqreturn_t mxs_ssp_irq_handler(int irq, void *dev_id)
{ {
struct mxs_ssp *ssp = dev_id; struct mxs_ssp *ssp = dev_id;
dev_err(ssp->dev, "%s[%i] CTRL1=%08x STATUS=%08x\n", dev_err(ssp->dev, "%s[%i] CTRL1=%08x STATUS=%08x\n",
__func__, __LINE__, __func__, __LINE__,
readl(ssp->base + HW_SSP_CTRL1(ssp)), readl(ssp->base + HW_SSP_CTRL1(ssp)),
@ -189,7 +191,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi,
if (!len) if (!len)
return -EINVAL; return -EINVAL;
dma_xfer = kzalloc(sizeof(*dma_xfer) * sgs, GFP_KERNEL); dma_xfer = kcalloc(sgs, sizeof(*dma_xfer), GFP_KERNEL);
if (!dma_xfer) if (!dma_xfer)
return -ENOMEM; return -ENOMEM;

Просмотреть файл

@ -179,8 +179,8 @@ static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi)
for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) { for (i = 0; i < ORION_SPI_WAIT_RDY_MAX_LOOP; i++) {
if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG))) if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG)))
return 1; return 1;
else
udelay(1); udelay(1);
} }
return -1; return -1;
@ -360,6 +360,7 @@ static int orion_spi_probe(struct platform_device *pdev)
master->bus_num = pdev->id; master->bus_num = pdev->id;
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
u32 cell_index; u32 cell_index;
if (!of_property_read_u32(pdev->dev.of_node, "cell-index", if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
&cell_index)) &cell_index))
master->bus_num = cell_index; master->bus_num = cell_index;

Просмотреть файл

@ -302,6 +302,7 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(
max_n_32bit = DIV_ROUND_UP(nbytes, 4); max_n_32bit = DIV_ROUND_UP(nbytes, 4);
for (count = 0; count < max_n_32bit; count++) { for (count = 0; count < max_n_32bit; count++) {
u32 x = 0; u32 x = 0;
for (i = 0; (i < 4) && nbytes; i++, nbytes--) for (i = 0; (i < 4) && nbytes; i++, nbytes--)
x |= (u32)(*tx_buf++) << (i * 8); x |= (u32)(*tx_buf++) << (i * 8);
tegra_spi_writel(tspi, x, SPI_TX_FIFO); tegra_spi_writel(tspi, x, SPI_TX_FIFO);
@ -312,6 +313,7 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(
nbytes = written_words * tspi->bytes_per_word; nbytes = written_words * tspi->bytes_per_word;
for (count = 0; count < max_n_32bit; count++) { for (count = 0; count < max_n_32bit; count++) {
u32 x = 0; u32 x = 0;
for (i = 0; nbytes && (i < tspi->bytes_per_word); for (i = 0; nbytes && (i < tspi->bytes_per_word);
i++, nbytes--) i++, nbytes--)
x |= (u32)(*tx_buf++) << (i * 8); x |= (u32)(*tx_buf++) << (i * 8);
@ -338,6 +340,7 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(
len = tspi->curr_dma_words * tspi->bytes_per_word; len = tspi->curr_dma_words * tspi->bytes_per_word;
for (count = 0; count < rx_full_count; count++) { for (count = 0; count < rx_full_count; count++) {
u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO); u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO);
for (i = 0; len && (i < 4); i++, len--) for (i = 0; len && (i < 4); i++, len--)
*rx_buf++ = (x >> i*8) & 0xFF; *rx_buf++ = (x >> i*8) & 0xFF;
} }
@ -345,8 +348,10 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(
read_words += tspi->curr_dma_words; read_words += tspi->curr_dma_words;
} else { } else {
u32 rx_mask = ((u32)1 << t->bits_per_word) - 1; u32 rx_mask = ((u32)1 << t->bits_per_word) - 1;
for (count = 0; count < rx_full_count; count++) { for (count = 0; count < rx_full_count; count++) {
u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO) & rx_mask; u32 x = tegra_spi_readl(tspi, SPI_RX_FIFO) & rx_mask;
for (i = 0; (i < tspi->bytes_per_word); i++) for (i = 0; (i < tspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF; *rx_buf++ = (x >> (i*8)) & 0xFF;
} }
@ -365,6 +370,7 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf(
if (tspi->is_packed) { if (tspi->is_packed) {
unsigned 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); memcpy(tspi->tx_dma_buf, t->tx_buf + tspi->cur_pos, len);
} else { } else {
unsigned int i; unsigned int i;
@ -374,6 +380,7 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf(
for (count = 0; count < tspi->curr_dma_words; count++) { for (count = 0; count < tspi->curr_dma_words; count++) {
u32 x = 0; u32 x = 0;
for (i = 0; consume && (i < tspi->bytes_per_word); for (i = 0; consume && (i < tspi->bytes_per_word);
i++, consume--) i++, consume--)
x |= (u32)(*tx_buf++) << (i * 8); x |= (u32)(*tx_buf++) << (i * 8);
@ -396,6 +403,7 @@ static void tegra_spi_copy_spi_rxbuf_to_client_rxbuf(
if (tspi->is_packed) { if (tspi->is_packed) {
unsigned len = tspi->curr_dma_words * tspi->bytes_per_word; unsigned len = tspi->curr_dma_words * tspi->bytes_per_word;
memcpy(t->rx_buf + tspi->cur_rx_pos, tspi->rx_dma_buf, len); memcpy(t->rx_buf + tspi->cur_rx_pos, tspi->rx_dma_buf, len);
} else { } else {
unsigned int i; unsigned int i;
@ -405,6 +413,7 @@ static void tegra_spi_copy_spi_rxbuf_to_client_rxbuf(
for (count = 0; count < tspi->curr_dma_words; count++) { for (count = 0; count < tspi->curr_dma_words; count++) {
u32 x = tspi->rx_dma_buf[count] & rx_mask; u32 x = tspi->rx_dma_buf[count] & rx_mask;
for (i = 0; (i < tspi->bytes_per_word); i++) for (i = 0; (i < tspi->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF; *rx_buf++ = (x >> (i*8)) & 0xFF;
} }

Просмотреть файл

@ -99,7 +99,7 @@
#define SPI_TX_TRIG_MASK (0x3 << 16) #define SPI_TX_TRIG_MASK (0x3 << 16)
#define SPI_TX_TRIG_1W (0x0 << 16) #define SPI_TX_TRIG_1W (0x0 << 16)
#define SPI_TX_TRIG_4W (0x1 << 16) #define SPI_TX_TRIG_4W (0x1 << 16)
#define SPI_DMA_BLK_COUNT(count) (((count) - 1) & 0xFFFF); #define SPI_DMA_BLK_COUNT(count) (((count) - 1) & 0xFFFF)
#define SPI_TX_FIFO 0x10 #define SPI_TX_FIFO 0x10
#define SPI_RX_FIFO 0x20 #define SPI_RX_FIFO 0x20
@ -221,6 +221,7 @@ static int tegra_sflash_read_rx_fifo_to_client_rxbuf(
while (!(status & SPI_RXF_EMPTY)) { while (!(status & SPI_RXF_EMPTY)) {
int i; int i;
u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO); u32 x = tegra_sflash_readl(tsd, SPI_RX_FIFO);
for (i = 0; (i < tsd->bytes_per_word); i++) for (i = 0; (i < tsd->bytes_per_word); i++)
*rx_buf++ = (x >> (i*8)) & 0xFF; *rx_buf++ = (x >> (i*8)) & 0xFF;
read_words++; read_words++;

Просмотреть файл

@ -97,6 +97,7 @@ static void txx9spi_cs_func(struct spi_device *spi, struct txx9spi *c,
int on, unsigned int cs_delay) int on, unsigned int cs_delay)
{ {
int val = (spi->mode & SPI_CS_HIGH) ? on : !on; int val = (spi->mode & SPI_CS_HIGH) ? on : !on;
if (on) { if (on) {
/* deselect the chip with cs_change hint in last transfer */ /* deselect the chip with cs_change hint in last transfer */
if (c->last_chipselect >= 0) if (c->last_chipselect >= 0)
@ -188,6 +189,7 @@ static void txx9spi_work_one(struct txx9spi *c, struct spi_message *m)
if (prev_speed_hz != speed_hz if (prev_speed_hz != speed_hz
|| prev_bits_per_word != bits_per_word) { || prev_bits_per_word != bits_per_word) {
int n = DIV_ROUND_UP(c->baseclk, speed_hz) - 1; int n = DIV_ROUND_UP(c->baseclk, speed_hz) - 1;
n = clamp(n, SPI_MIN_DIVIDER, SPI_MAX_DIVIDER); n = clamp(n, SPI_MIN_DIVIDER, SPI_MAX_DIVIDER);
/* enter config mode */ /* enter config mode */
txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR, txx9spi_wr(c, mcr | TXx9_SPMCR_CONFIG | TXx9_SPMCR_BCLR,

Просмотреть файл

@ -46,6 +46,7 @@ static inline unsigned int xtfpga_spi_read32(const struct xtfpga_spi *spi,
static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi) static inline void xtfpga_spi_wait_busy(struct xtfpga_spi *xspi)
{ {
unsigned i; unsigned i;
for (i = 0; xtfpga_spi_read32(xspi, XTFPGA_SPI_BUSY) && for (i = 0; xtfpga_spi_read32(xspi, XTFPGA_SPI_BUSY) &&
i < BUSY_WAIT_US; ++i) i < BUSY_WAIT_US; ++i)
udelay(1); udelay(1);