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:
Коммит
95607c3033
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче