Commit 95607c30 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/fix/au1550', 'spi/fix/cadence',...

Merge remote-tracking branches 'spi/fix/au1550', 'spi/fix/cadence', 'spi/fix/omap2-mcspi' and 'spi/fix/orion' into spi-linus
...@@ -925,8 +925,7 @@ static int au1550_spi_probe(struct platform_device *pdev) ...@@ -925,8 +925,7 @@ static int au1550_spi_probe(struct platform_device *pdev)
iounmap((void __iomem *)hw->regs); iounmap((void __iomem *)hw->regs);
err_ioremap: err_ioremap:
release_resource(hw->ioarea); release_mem_region(r->start, sizeof(psc_spi_t));
kfree(hw->ioarea);
err_no_iores: err_no_iores:
err_no_pdata: err_no_pdata:
...@@ -946,8 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev) ...@@ -946,8 +945,7 @@ static int au1550_spi_remove(struct platform_device *pdev)
spi_bitbang_stop(&hw->bitbang); spi_bitbang_stop(&hw->bitbang);
free_irq(hw->irq, hw); free_irq(hw->irq, hw);
iounmap((void __iomem *)hw->regs); iounmap((void __iomem *)hw->regs);
release_resource(hw->ioarea); release_mem_region(r->start, sizeof(psc_spi_t));
kfree(hw->ioarea);
if (hw->usedma) { if (hw->usedma) {
au1550_spi_dma_rxtmp_free(hw); au1550_spi_dma_rxtmp_free(hw);
......
...@@ -205,18 +205,30 @@ static void cdns_spi_chipselect(struct spi_device *spi, bool is_high) ...@@ -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) static void cdns_spi_config_clock_mode(struct spi_device *spi)
{ {
struct cdns_spi *xspi = spi_master_get_devdata(spi->master); 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 */ /* 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) 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) 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) ...@@ -370,6 +382,12 @@ static irqreturn_t cdns_spi_irq(int irq, void *dev_id)
return status; 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 * cdns_transfer_one - Initiates the SPI transfer
...@@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master) ...@@ -416,8 +434,6 @@ static int cdns_prepare_transfer_hardware(struct spi_master *master)
{ {
struct cdns_spi *xspi = spi_master_get_devdata(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_write(xspi, CDNS_SPI_ER_OFFSET,
CDNS_SPI_ER_ENABLE_MASK); CDNS_SPI_ER_ENABLE_MASK);
...@@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev) ...@@ -532,6 +548,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
xspi->is_decoded_cs = 0; xspi->is_decoded_cs = 0;
master->prepare_transfer_hardware = cdns_prepare_transfer_hardware; master->prepare_transfer_hardware = cdns_prepare_transfer_hardware;
master->prepare_message = cdns_prepare_message;
master->transfer_one = cdns_transfer_one; master->transfer_one = cdns_transfer_one;
master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware; master->unprepare_transfer_hardware = cdns_unprepare_transfer_hardware;
master->set_cs = cdns_spi_chipselect; master->set_cs = cdns_spi_chipselect;
......
...@@ -149,6 +149,7 @@ struct omap2_mcspi_cs { ...@@ -149,6 +149,7 @@ struct omap2_mcspi_cs {
void __iomem *base; void __iomem *base;
unsigned long phys; unsigned long phys;
int word_len; int word_len;
u16 mode;
struct list_head node; struct list_head node;
/* Context save and restore shadow register */ /* Context save and restore shadow register */
u32 chconf0, chctrl0; u32 chconf0, chctrl0;
...@@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, ...@@ -926,6 +927,8 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
mcspi_write_chconf0(spi, l); mcspi_write_chconf0(spi, l);
cs->mode = spi->mode;
dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n", dev_dbg(&spi->dev, "setup: speed %d, sample %s edge, clk %s\n",
speed_hz, speed_hz,
(spi->mode & SPI_CPHA) ? "trailing" : "leading", (spi->mode & SPI_CPHA) ? "trailing" : "leading",
...@@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) ...@@ -998,6 +1001,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
return -ENOMEM; return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14; cs->base = mcspi->base + spi->chip_select * 0x14;
cs->phys = mcspi->phys + spi->chip_select * 0x14; cs->phys = mcspi->phys + spi->chip_select * 0x14;
cs->mode = 0;
cs->chconf0 = 0; cs->chconf0 = 0;
cs->chctrl0 = 0; cs->chctrl0 = 0;
spi->controller_state = cs; spi->controller_state = cs;
...@@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m) ...@@ -1079,6 +1083,16 @@ static void omap2_mcspi_work(struct omap2_mcspi *mcspi, struct spi_message *m)
cs = spi->controller_state; cs = spi->controller_state;
cd = spi->controller_data; 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); omap2_mcspi_set_enable(spi, 0);
list_for_each_entry(t, &m->transfers, transfer_list) { list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) { if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
......
...@@ -346,8 +346,6 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -346,8 +346,6 @@ static int orion_spi_probe(struct platform_device *pdev)
struct resource *r; struct resource *r;
unsigned long tclk_hz; unsigned long tclk_hz;
int status = 0; int status = 0;
const u32 *iprop;
int size;
master = spi_alloc_master(&pdev->dev, sizeof(*spi)); master = spi_alloc_master(&pdev->dev, sizeof(*spi));
if (master == NULL) { if (master == NULL) {
...@@ -358,10 +356,10 @@ static int orion_spi_probe(struct platform_device *pdev) ...@@ -358,10 +356,10 @@ static int orion_spi_probe(struct platform_device *pdev)
if (pdev->id != -1) if (pdev->id != -1)
master->bus_num = pdev->id; master->bus_num = pdev->id;
if (pdev->dev.of_node) { if (pdev->dev.of_node) {
iprop = of_get_property(pdev->dev.of_node, "cell-index", u32 cell_index;
&size); if (!of_property_read_u32(pdev->dev.of_node, "cell-index",
if (iprop && size == sizeof(*iprop)) &cell_index))
master->bus_num = *iprop; master->bus_num = cell_index;
} }
/* we support only mode 0, and no options */ /* we support only mode 0, and no options */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment