mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 06:24:53 +08:00
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: Marcin Wojtas <mw@semihalf.com> Signed-off-by: Konstantin Porotchkin <kostap@marvell.com> Link: https://lore.kernel.org/r/20201223103827.29721-2-kostap@marvell.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
a34d4197a1
commit
e2be70318d
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user