diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2015-08-04 17:52:00 +0200 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2015-08-04 17:52:00 +0200 |
commit | 073b50be0713f8cba043935e1daae714e66026db (patch) | |
tree | ed0a71b56576df2637ffa9a4d3dae8d836b63428 /drivers/spi | |
parent | 3a5c56b021108a9c2aeead3109946cd4f2fc7078 (diff) | |
parent | 89e419960fb6a260f6a112821507d516117d5aa1 (diff) |
Merge tag 'v4.1.4' into toradex_vf_4.1-next
This is the 4.1.4 stable release
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-orion.c | 25 | ||||
-rw-r--r-- | drivers/spi/spi.c | 11 |
2 files changed, 29 insertions, 7 deletions
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 861664776672..ff97cabdaa81 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c @@ -61,6 +61,12 @@ enum orion_spi_type { struct orion_spi_dev { enum orion_spi_type typ; + /* + * min_divisor and max_hz should be exclusive, the only we can + * have both is for managing the armada-370-spi case with old + * device tree + */ + unsigned long max_hz; unsigned int min_divisor; unsigned int max_divisor; u32 prescale_mask; @@ -387,8 +393,9 @@ static const struct orion_spi_dev orion_spi_dev_data = { static const struct orion_spi_dev armada_spi_dev_data = { .typ = ARMADA_SPI, - .min_divisor = 1, + .min_divisor = 4, .max_divisor = 1920, + .max_hz = 50000000, .prescale_mask = ARMADA_SPI_CLK_PRESCALE_MASK, }; @@ -454,7 +461,21 @@ static int orion_spi_probe(struct platform_device *pdev) goto out; tclk_hz = clk_get_rate(spi->clk); - master->max_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->min_divisor); + + /* + * With old device tree, armada-370-spi could be used with + * Armada XP, however for this SoC the maximum frequency is + * 50MHz instead of tclk/4. On Armada 370, tclk cannot be + * higher than 200MHz. So, in order to be able to handle both + * SoCs, we can take the minimum of 50MHz and tclk/4. + */ + if (of_device_is_compatible(pdev->dev.of_node, + "marvell,armada-370-spi")) + master->max_speed_hz = min(devdata->max_hz, + DIV_ROUND_UP(tclk_hz, devdata->min_divisor)); + else + master->max_speed_hz = + DIV_ROUND_UP(tclk_hz, devdata->min_divisor); master->min_speed_hz = DIV_ROUND_UP(tclk_hz, devdata->max_divisor); r = platform_get_resource(pdev, IORESOURCE_MEM, 0); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 50910d85df5a..d35c1a13217c 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -988,9 +988,6 @@ void spi_finalize_current_message(struct spi_master *master) spin_lock_irqsave(&master->queue_lock, flags); mesg = master->cur_msg; - master->cur_msg = NULL; - - queue_kthread_work(&master->kworker, &master->pump_messages); spin_unlock_irqrestore(&master->queue_lock, flags); spi_unmap_msg(master, mesg); @@ -1003,9 +1000,13 @@ void spi_finalize_current_message(struct spi_master *master) } } - trace_spi_message_done(mesg); - + spin_lock_irqsave(&master->queue_lock, flags); + master->cur_msg = NULL; master->cur_msg_prepared = false; + queue_kthread_work(&master->kworker, &master->pump_messages); + spin_unlock_irqrestore(&master->queue_lock, flags); + + trace_spi_message_done(mesg); mesg->state = NULL; if (mesg->complete) |