diff options
Diffstat (limited to 'drivers/spi/spi-sh-msiof.c')
-rw-r--r-- | drivers/spi/spi-sh-msiof.c | 44 |
1 files changed, 28 insertions, 16 deletions
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index c304c7167866..fcd261f98b9f 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -38,6 +38,7 @@ struct sh_msiof_chipdata { u16 tx_fifo_size; u16 rx_fifo_size; u16 master_flags; + u16 min_div; }; struct sh_msiof_spi_priv { @@ -49,6 +50,7 @@ struct sh_msiof_spi_priv { struct completion done; unsigned int tx_fifo_size; unsigned int rx_fifo_size; + unsigned int min_div; void *tx_dma_page; void *rx_dma_page; dma_addr_t tx_dma_addr; @@ -261,6 +263,8 @@ static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, if (!WARN_ON(!spi_hz || !parent_rate)) div = DIV_ROUND_UP(parent_rate, spi_hz); + div = max_t(unsigned long, div, p->min_div); + for (k = 0; k < ARRAY_SIZE(sh_msiof_spi_div_table); k++) { brps = DIV_ROUND_UP(div, sh_msiof_spi_div_table[k].div); /* SCR_BRDV_DIV_1 is valid only if BRPS is x 1/1 or x 1/2 */ @@ -896,7 +900,7 @@ static int sh_msiof_transfer_one(struct spi_master *master, break; copy32 = copy_bswap32; } else if (bits <= 16) { - if (l & 1) + if (l & 3) break; copy32 = copy_wswap32; } else { @@ -998,24 +1002,35 @@ static const struct sh_msiof_chipdata sh_data = { .tx_fifo_size = 64, .rx_fifo_size = 64, .master_flags = 0, + .min_div = 1, +}; + +static const struct sh_msiof_chipdata rcar_gen2_data = { + .tx_fifo_size = 64, + .rx_fifo_size = 64, + .master_flags = SPI_MASTER_MUST_TX, + .min_div = 1, }; -static const struct sh_msiof_chipdata r8a779x_data = { +static const struct sh_msiof_chipdata rcar_gen3_data = { .tx_fifo_size = 64, .rx_fifo_size = 64, .master_flags = SPI_MASTER_MUST_TX, + .min_div = 2, }; static const struct of_device_id sh_msiof_match[] = { { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, - { .compatible = "renesas,msiof-r8a7790", .data = &r8a779x_data }, - { .compatible = "renesas,msiof-r8a7791", .data = &r8a779x_data }, - { .compatible = "renesas,msiof-r8a7792", .data = &r8a779x_data }, - { .compatible = "renesas,msiof-r8a7793", .data = &r8a779x_data }, - { .compatible = "renesas,msiof-r8a7794", .data = &r8a779x_data }, - { .compatible = "renesas,rcar-gen2-msiof", .data = &r8a779x_data }, - { .compatible = "renesas,msiof-r8a7796", .data = &r8a779x_data }, - { .compatible = "renesas,rcar-gen3-msiof", .data = &r8a779x_data }, + { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7745", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7790", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7791", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7792", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data }, + { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data }, + { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data }, { .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */ {}, }; @@ -1175,12 +1190,10 @@ free_tx_chan: static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p) { struct spi_master *master = p->master; - struct device *dev; if (!master->dma_tx) return; - dev = &p->pdev->dev; dma_unmap_single(master->dma_rx->device->dev, p->rx_dma_addr, PAGE_SIZE, DMA_FROM_DEVICE); dma_unmap_single(master->dma_tx->device->dev, p->tx_dma_addr, @@ -1196,15 +1209,13 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) struct resource *r; struct spi_master *master; const struct sh_msiof_chipdata *chipdata; - const struct of_device_id *of_id; struct sh_msiof_spi_info *info; struct sh_msiof_spi_priv *p; int i; int ret; - of_id = of_match_device(sh_msiof_match, &pdev->dev); - if (of_id) { - chipdata = of_id->data; + chipdata = of_device_get_match_data(&pdev->dev); + if (chipdata) { info = sh_msiof_spi_parse_dt(&pdev->dev); } else { chipdata = (const void *)pdev->id_entry->driver_data; @@ -1230,6 +1241,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, p); p->master = master; p->info = info; + p->min_div = chipdata->min_div; init_completion(&p->done); |