Skip to content

Commit

Permalink
Merge remote-tracking branches 'spi/topic/orion', 'spi/topic/pxa2xx',…
Browse files Browse the repository at this point in the history
… 'spi/topic/qup', 'spi/topic/rockchip' and 'spi/topic/samsung' into spi-next
  • Loading branch information
Mark Brown committed Feb 8, 2015
6 parents 8328509 + 2324440 + 9064bf3 + 0667dd5 + 97cf566 + 75d30c5 commit 4f9f454
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 212 deletions.
1 change: 0 additions & 1 deletion drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,6 @@ config SPI_S3C24XX_FIQ
config SPI_S3C64XX
tristate "Samsung S3C64XX series type SPI"
depends on (PLAT_SAMSUNG || ARCH_EXYNOS)
select S3C64XX_PL080 if ARCH_S3C64XX
help
SPI driver for Samsung S3C64XX and newer SoCs.

Expand Down
88 changes: 37 additions & 51 deletions drivers/spi/spi-orion.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@
/* Runtime PM autosuspend timeout: PM is fairly light on this driver */
#define SPI_AUTOSUSPEND_TIMEOUT 200

#define ORION_NUM_CHIPSELECTS 1 /* only one slave is supported*/
/* Some SoCs using this driver support up to 8 chip selects.
* It is up to the implementer to only use the chip selects
* that are available.
*/
#define ORION_NUM_CHIPSELECTS 8

#define ORION_SPI_WAIT_RDY_MAX_LOOP 2000 /* in usec */

#define ORION_SPI_IF_CTRL_REG 0x00
Expand All @@ -44,6 +49,10 @@
#define ARMADA_SPI_CLK_PRESCALE_MASK 0xDF
#define ORION_SPI_MODE_MASK (ORION_SPI_MODE_CPOL | \
ORION_SPI_MODE_CPHA)
#define ORION_SPI_CS_MASK 0x1C
#define ORION_SPI_CS_SHIFT 2
#define ORION_SPI_CS(cs) ((cs << ORION_SPI_CS_SHIFT) & \
ORION_SPI_CS_MASK)

enum orion_spi_type {
ORION_SPI,
Expand Down Expand Up @@ -215,9 +224,18 @@ orion_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
return 0;
}

static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable)
static void orion_spi_set_cs(struct spi_device *spi, bool enable)
{
if (enable)
struct orion_spi *orion_spi;

orion_spi = spi_master_get_devdata(spi->master);

orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, ORION_SPI_CS_MASK);
orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG,
ORION_SPI_CS(spi->chip_select));

/* Chip select logic is inverted from spi_set_cs */
if (!enable)
orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
else
orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
Expand Down Expand Up @@ -332,64 +350,31 @@ orion_spi_write_read(struct spi_device *spi, struct spi_transfer *xfer)
return xfer->len - count;
}

static int orion_spi_transfer_one_message(struct spi_master *master,
struct spi_message *m)
static int orion_spi_transfer_one(struct spi_master *master,
struct spi_device *spi,
struct spi_transfer *t)
{
struct orion_spi *orion_spi = spi_master_get_devdata(master);
struct spi_device *spi = m->spi;
struct spi_transfer *t = NULL;
int par_override = 0;
int status = 0;
int cs_active = 0;

/* Load defaults */
status = orion_spi_setup_transfer(spi, NULL);

status = orion_spi_setup_transfer(spi, t);
if (status < 0)
goto msg_done;

list_for_each_entry(t, &m->transfers, transfer_list) {
if (par_override || t->speed_hz || t->bits_per_word) {
par_override = 1;
status = orion_spi_setup_transfer(spi, t);
if (status < 0)
break;
if (!t->speed_hz && !t->bits_per_word)
par_override = 0;
}

if (!cs_active) {
orion_spi_set_cs(orion_spi, 1);
cs_active = 1;
}
return status;

if (t->len)
m->actual_length += orion_spi_write_read(spi, t);
if (t->len)
orion_spi_write_read(spi, t);

if (t->delay_usecs)
udelay(t->delay_usecs);

if (t->cs_change) {
orion_spi_set_cs(orion_spi, 0);
cs_active = 0;
}
}

msg_done:
if (cs_active)
orion_spi_set_cs(orion_spi, 0);

m->status = status;
spi_finalize_current_message(master);
return status;
}

return 0;
static int orion_spi_setup(struct spi_device *spi)
{
return orion_spi_setup_transfer(spi, NULL);
}

static int orion_spi_reset(struct orion_spi *orion_spi)
{
/* Verify that the CS is deasserted */
orion_spi_set_cs(orion_spi, 0);

orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1);
return 0;
}

Expand Down Expand Up @@ -442,9 +427,10 @@ static int orion_spi_probe(struct platform_device *pdev)

/* we support only mode 0, and no options */
master->mode_bits = SPI_CPHA | SPI_CPOL;

master->transfer_one_message = orion_spi_transfer_one_message;
master->set_cs = orion_spi_set_cs;
master->transfer_one = orion_spi_transfer_one;
master->num_chipselect = ORION_NUM_CHIPSELECTS;
master->setup = orion_spi_setup;
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
master->auto_runtime_pm = true;

Expand Down
17 changes: 10 additions & 7 deletions drivers/spi/spi-pxa2xx-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,23 +111,24 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
* by using ->dma_running.
*/
if (atomic_dec_and_test(&drv_data->dma_running)) {
void __iomem *reg = drv_data->ioaddr;

/*
* If the other CPU is still handling the ROR interrupt we
* might not know about the error yet. So we re-check the
* ROR bit here before we clear the status register.
*/
if (!error) {
u32 status = read_SSSR(reg) & drv_data->mask_sr;
u32 status = pxa2xx_spi_read(drv_data, SSSR)
& drv_data->mask_sr;
error = status & SSSR_ROR;
}

/* Clear status & disable interrupts */
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1)
& ~drv_data->dma_cr1);
write_SSSR_CS(drv_data, drv_data->clear_sr);
if (!pxa25x_ssp_comp(drv_data))
write_SSTO(0, reg);
pxa2xx_spi_write(drv_data, SSTO, 0);

if (!error) {
pxa2xx_spi_unmap_dma_buffers(drv_data);
Expand All @@ -139,7 +140,9 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
msg->state = pxa2xx_spi_next_transfer(drv_data);
} else {
/* In case we got an error we disable the SSP now */
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
pxa2xx_spi_write(drv_data, SSCR0,
pxa2xx_spi_read(drv_data, SSCR0)
& ~SSCR0_SSE);

msg->state = ERROR_STATE;
}
Expand Down Expand Up @@ -247,7 +250,7 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
{
u32 status;

status = read_SSSR(drv_data->ioaddr) & drv_data->mask_sr;
status = pxa2xx_spi_read(drv_data, SSSR) & drv_data->mask_sr;
if (status & SSSR_ROR) {
dev_err(&drv_data->pdev->dev, "FIFO overrun\n");

Expand Down
30 changes: 16 additions & 14 deletions drivers/spi/spi-pxa2xx-pxadma.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/pxa2xx_spi.h>

#include <mach/dma.h>
#include "spi-pxa2xx.h"

#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
Expand Down Expand Up @@ -114,11 +115,11 @@ static void pxa2xx_spi_unmap_dma_buffers(struct driver_data *drv_data)
drv_data->dma_mapped = 0;
}

static int wait_ssp_rx_stall(void const __iomem *ioaddr)
static int wait_ssp_rx_stall(struct driver_data *drv_data)
{
unsigned long limit = loops_per_jiffy << 1;

while ((read_SSSR(ioaddr) & SSSR_BSY) && --limit)
while ((pxa2xx_spi_read(drv_data, SSSR) & SSSR_BSY) && --limit)
cpu_relax();

return limit;
Expand All @@ -137,17 +138,18 @@ static int wait_dma_channel_stop(int channel)
static void pxa2xx_spi_dma_error_stop(struct driver_data *drv_data,
const char *msg)
{
void __iomem *reg = drv_data->ioaddr;

/* Stop and reset */
DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
write_SSSR_CS(drv_data, drv_data->clear_sr);
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1)
& ~drv_data->dma_cr1);
if (!pxa25x_ssp_comp(drv_data))
write_SSTO(0, reg);
pxa2xx_spi_write(drv_data, SSTO, 0);
pxa2xx_spi_flush(drv_data);
write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg);
pxa2xx_spi_write(drv_data, SSCR0,
pxa2xx_spi_read(drv_data, SSCR0) & ~SSCR0_SSE);

pxa2xx_spi_unmap_dma_buffers(drv_data);

Expand All @@ -159,11 +161,12 @@ static void pxa2xx_spi_dma_error_stop(struct driver_data *drv_data,

static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data)
{
void __iomem *reg = drv_data->ioaddr;
struct spi_message *msg = drv_data->cur_msg;

/* Clear and disable interrupts on SSP and DMA channels*/
write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg);
pxa2xx_spi_write(drv_data, SSCR1,
pxa2xx_spi_read(drv_data, SSCR1)
& ~drv_data->dma_cr1);
write_SSSR_CS(drv_data, drv_data->clear_sr);
DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL;
DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL;
Expand Down Expand Up @@ -224,7 +227,7 @@ void pxa2xx_spi_dma_handler(int channel, void *data)
&& (drv_data->ssp_type == PXA25x_SSP)) {

/* Wait for rx to stall */
if (wait_ssp_rx_stall(drv_data->ioaddr) == 0)
if (wait_ssp_rx_stall(drv_data) == 0)
dev_err(&drv_data->pdev->dev,
"dma_handler: ssp rx stall failed\n");

Expand All @@ -236,9 +239,8 @@ void pxa2xx_spi_dma_handler(int channel, void *data)
irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
{
u32 irq_status;
void __iomem *reg = drv_data->ioaddr;

irq_status = read_SSSR(reg) & drv_data->mask_sr;
irq_status = pxa2xx_spi_read(drv_data, SSSR) & drv_data->mask_sr;
if (irq_status & SSSR_ROR) {
pxa2xx_spi_dma_error_stop(drv_data,
"dma_transfer: fifo overrun");
Expand All @@ -248,7 +250,7 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
/* Check for false positive timeout */
if ((irq_status & SSSR_TINT)
&& (DCSR(drv_data->tx_channel) & DCSR_RUN)) {
write_SSSR(SSSR_TINT, reg);
pxa2xx_spi_write(drv_data, SSSR, SSSR_TINT);
return IRQ_HANDLED;
}

Expand All @@ -257,7 +259,7 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
/* Clear and disable timeout interrupt, do the rest in
* dma_transfer_complete */
if (!pxa25x_ssp_comp(drv_data))
write_SSTO(0, reg);
pxa2xx_spi_write(drv_data, SSTO, 0);

/* finish this transfer, start the next */
pxa2xx_spi_dma_transfer_complete(drv_data);
Expand Down
Loading

0 comments on commit 4f9f454

Please sign in to comment.