Commit e2be7031 authored by Marcin Wojtas's avatar Marcin Wojtas Committed by Mark Brown

spi: orion: enable clocks before spi_setup

The spi-orion driver disables its clocks whenever it is not used.
In usual case during boot (i.e. using SPI flash) it is not a problem,
as the child device driver is present and probed along with
spi_register_master() execution.

However in case the child device driver is not ready
(e.g. when its type is module_spi_driver) the spi_setup() callback
can be called after the spi-orion probe. It may happen,
that as a result there will be an attempt to access controller's
registers with the clocks disabled.

Prevent such situations and make sure the clocks are on,
each time the spi_setup() is called.
Signed-off-by: default avatarMarcin Wojtas <mw@semihalf.com>
Signed-off-by: default avatarKonstantin Porotchkin <kostap@marvell.com>
Link: https://lore.kernel.org/r/20201223103827.29721-2-kostap@marvell.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent a34d4197
......@@ -96,10 +96,16 @@ struct orion_spi {
struct clk *clk;
struct clk *axi_clk;
const struct orion_spi_dev *devdata;
struct device *dev;
struct orion_child_options child[ORION_NUM_CHIPSELECTS];
};
#ifdef CONFIG_PM
static int orion_spi_runtime_suspend(struct device *dev);
static int orion_spi_runtime_resume(struct device *dev);
#endif
static inline void __iomem *spi_reg(struct orion_spi *orion_spi, u32 reg)
{
return orion_spi->base + reg;
......@@ -507,7 +513,21 @@ static int orion_spi_transfer_one(struct spi_master *master,
static int orion_spi_setup(struct spi_device *spi)
{
return orion_spi_setup_transfer(spi, NULL);
int ret;
#ifdef CONFIG_PM
struct orion_spi *orion_spi = spi_master_get_devdata(spi->master);
struct device *dev = orion_spi->dev;
orion_spi_runtime_resume(dev);
#endif
ret = orion_spi_setup_transfer(spi, NULL);
#ifdef CONFIG_PM
orion_spi_runtime_suspend(dev);
#endif
return ret;
}
static int orion_spi_reset(struct orion_spi *orion_spi)
......@@ -630,6 +650,7 @@ static int orion_spi_probe(struct platform_device *pdev)
spi = spi_master_get_devdata(master);
spi->master = master;
spi->dev = &pdev->dev;
of_id = of_match_device(orion_spi_of_match_table, &pdev->dev);
devdata = (of_id) ? of_id->data : &orion_spi_dev_data;
......
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