diff options
author | Sebastian Reichel <sre@kernel.org> | 2016-01-31 03:52:38 +0300 |
---|---|---|
committer | Sebastian Reichel <sre@kernel.org> | 2016-05-02 22:56:25 +0300 |
commit | 4bcf7414528a6b7ca52d28953a732a4cf36063e8 (patch) | |
tree | a70c2897861ee30a420153a94651a723a70aec1f /drivers/hsi/controllers/omap_ssi_port.c | |
parent | 0fae198988b873d30fe9ecb6a6271afb36df97e9 (diff) | |
download | linux-4bcf7414528a6b7ca52d28953a732a4cf36063e8.tar.xz |
HSI: omap-ssi: add clk change support
This adds support for frequency changes of the SSI
functional clock, which may occur due to DVFS.
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-By: Sebastian Reichel <sre@kernel.org>
Diffstat (limited to 'drivers/hsi/controllers/omap_ssi_port.c')
-rw-r--r-- | drivers/hsi/controllers/omap_ssi_port.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/hsi/controllers/omap_ssi_port.c b/drivers/hsi/controllers/omap_ssi_port.c index 1569bbb53ee8..98b22e88085c 100644 --- a/drivers/hsi/controllers/omap_ssi_port.c +++ b/drivers/hsi/controllers/omap_ssi_port.c @@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/dma-mapping.h> #include <linux/pm_runtime.h> +#include <linux/delay.h> #include <linux/gpio/consumer.h> #include <linux/debugfs.h> @@ -514,6 +515,11 @@ static int ssi_flush(struct hsi_client *cl) pm_runtime_get_sync(omap_port->pdev); spin_lock_bh(&omap_port->lock); + + /* stop all ssi communication */ + pinctrl_pm_select_idle_state(omap_port->pdev); + udelay(1); /* wait for racing frames */ + /* Stop all DMA transfers */ for (i = 0; i < SSI_MAX_GDD_LCH; i++) { msg = omap_ssi->gdd_trn[i].msg; @@ -550,6 +556,10 @@ static int ssi_flush(struct hsi_client *cl) ssi_flush_queue(&omap_port->rxqueue[i], NULL); } ssi_flush_queue(&omap_port->brkqueue, NULL); + + /* Resume SSI communication */ + pinctrl_pm_select_default_state(omap_port->pdev); + spin_unlock_bh(&omap_port->lock); pm_runtime_put_sync(omap_port->pdev); @@ -1302,6 +1312,16 @@ static int ssi_restore_divisor(struct omap_ssi_port *omap_port) return 0; } +void omap_ssi_port_update_fclk(struct hsi_controller *ssi, + struct omap_ssi_port *omap_port) +{ + /* update divisor */ + u32 div = ssi_calculate_div(ssi); + omap_port->sst.divisor = div; + ssi_restore_divisor(omap_port); +} +EXPORT_SYMBOL_GPL(omap_ssi_port_update_fclk); + static int omap_ssi_port_runtime_suspend(struct device *dev) { struct hsi_port *port = dev_get_drvdata(dev); |