Merge remote-tracking branches 'spi/fix/au1550', 'spi/fix/cadence', 'spi/fix/omap2-mcspi' and 'spi/fix/orion' into spi-linus

This commit is contained in:
Mark Brown 2014-08-04 17:20:54 +01:00
4 changed files with 45 additions and 18 deletions

View file

@ -925,8 +925,7 @@ err_no_txdma:
iounmap((void __iomem *)hw->regs);
err_ioremap:
release_resource(hw->ioarea);
kfree(hw->ioarea);
release_mem_region(r->start, sizeof(psc_spi_t));
err_no_iores:
err_no_pdata:
@ -946,8 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev)
spi_bitbang_stop(&hw->bitbang);
free_irq(hw->irq, hw);
iounmap((void __iomem *)hw->regs);
release_resource(hw->ioarea);
kfree(hw->ioarea);
release_mem_region(r->start, sizeof(psc_spi_t));
if (hw->usedma) {
au1550_spi_dma_rxtmp_free(hw);

View file

@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high)
static void cdns_spi_config_clock_mode(struct spi_device *spi)
{
struct cdns_spi *xspi = spi_master_get_devdata(spi->master);
u32 ctrl_reg;
u32 ctrl_reg, new_ctrl_reg;
ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
new_ctrl_reg = ctrl_reg = cdns_spi_read(xspi, CDNS_SPI_CR_OFFSET);
/* Set the SPI clock phase and clock polarity */
ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
new_ctrl_reg &= ~(CDNS_SPI_CR_CPHA_MASK | CDNS_SPI_CR_CPOL_MASK);
if (spi->mode & SPI_CPHA)
ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
new_ctrl_reg |= CDNS_SPI_CR_CPHA_MASK;
if (spi->mode & SPI_CPOL)
ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
new_ctrl_reg |= CDNS_SPI_CR_CPOL_MASK;
cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, ctrl_reg);
if (new_ctrl_reg != ctrl_reg) {
/*
* Just writing the CR register does not seem to apply the clock
* setting changes. This is problematic when changing the clock
* polarity as it will cause the SPI slave to see spurious clock
* transitions. To workaround the issue toggle the ER register.
*/
cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
CDNS_SPI_ER_DISABLE_MASK);
cdns_spi_write(xspi, CDNS_SPI_CR_OFFSET, new_ctrl_reg);
cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
CDNS_SPI_ER_ENABLE_MASK);
}
}
/**
@ -370,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
return status;
}
static int cdns_prepare_message(struct spi_master *master,
struct spi_message *msg)
{
cdns_spi_config_clock_mode(msg->spi);
return 0;
}
/**
* cdns_transfer_one - Initiates the SPI transfer
@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
{
struct cdns_spi *xspi = spi_master_get_devdata(master);
cdns_spi_config_clock_mode(master->cur_msg->spi);
cdns_spi_write(xspi, CDNS_SPI_ER_OFFSET,
CDNS_SPI_ER_ENABLE_MASK);
@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
xspi->is_decoded_cs = 0;
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
master->prepare_message = cdns_prepare_message;
master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect;

View file

@ -149,6 +149,7 @@ struct omap2_mcspi_cs {
void __iomem *base;
unsigned long phys;
int word_len;
u16 mode;
struct list_head node;
/* Context save and restore shadow register */
u32 chconf0, chctrl0;
@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
mcspi_write_chconf0(spi, l);
cs->mode = spi->mode;
dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
speed_hz,
(spi->mode & SPI_CPHA) ? "trailing" : "leading",
@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14;
cs->phys = mcspi->phys + spi->chip_select * 0x14;
cs->mode = 0;
cs->chconf0 = 0;
cs->chctrl0 = 0;
spi->controller_state = cs;
@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
cs = spi->controller_state;
cd = spi->controller_data;
/*
* The slave driver could have changed spi->mode in which case
* it will be different from cs->mode (the current hardware setup).
* If so, set par_override (even though its not a parity issue) so
* omap2_mcspi_setup_transfer will be called to configure the hardware
* with the correct mode on the first iteration of the loop below.
*/
if (spi->mode != cs->mode)
par_override = 1;
omap2_mcspi_set_enable(spi, 0);
list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {

View file

@ -346,8 +346,6 @@ static int orion_spi_probe(struct platform_device *pdev)
struct resource *r;
unsigned long tclk_hz;
int status = 0;
const u32 *iprop;
int size;
master = spi_alloc_master(&pdev->dev, sizeof(*spi));
if (master == NULL) {
@ -358,10 +356,10 @@ static int orion_spi_probe(struct platform_device *pdev)
if (pdev->id != -1)
master->bus_num = pdev->id;
if (pdev->dev.of_node) {
iprop = of_get_property(pdev->dev.of_node, "cell-index",
&size);
if (iprop && size == sizeof(*iprop))
master->bus_num = *iprop;
u32 cell_index;
if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
&cell_index))
master->bus_num = cell_index;
}
/* we support only mode 0, and no options */