mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 09:01:34 +00:00
bus: fsl-mc: pause the MC firmware before IOMMU setup
Add a bus notifier to pause the MC firmware as soon as its device gets discovered. This is needed as the firmware is live thus, as soon as the SMMU gets probed and enabled, it will crash the firmware due to SMMU context faults. The firmware will be resumed at probe time, after the required IOMMU setup was completed. Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> Link: https://lore.kernel.org/r/20210715140718.8513-5-laurentiu.tudor@nxp.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3ab520cfc7
commit
8c97a4fc1b
@ -896,6 +896,8 @@ error_cleanup_dev:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fsl_mc_device_add);
|
||||
|
||||
static struct notifier_block fsl_mc_nb;
|
||||
|
||||
/**
|
||||
* fsl_mc_device_remove - Remove an fsl-mc device from being visible to
|
||||
* Linux
|
||||
@ -1203,6 +1205,8 @@ static int fsl_mc_bus_remove(struct platform_device *pdev)
|
||||
fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
|
||||
mc->root_mc_bus_dev->mc_io = NULL;
|
||||
|
||||
bus_unregister_notifier(&fsl_mc_bus_type, &fsl_mc_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1236,6 +1240,44 @@ static struct platform_driver fsl_mc_bus_driver = {
|
||||
.shutdown = fsl_mc_bus_shutdown,
|
||||
};
|
||||
|
||||
static int fsl_mc_bus_notifier(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
struct device *dev = data;
|
||||
struct resource *res;
|
||||
void __iomem *fsl_mc_regs;
|
||||
|
||||
if (action != BUS_NOTIFY_ADD_DEVICE)
|
||||
return 0;
|
||||
|
||||
if (!of_match_device(fsl_mc_bus_match_table, dev) &&
|
||||
!acpi_match_device(fsl_mc_bus_acpi_match_table, dev))
|
||||
return 0;
|
||||
|
||||
res = platform_get_resource(to_platform_device(dev), IORESOURCE_MEM, 1);
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
fsl_mc_regs = ioremap(res->start, resource_size(res));
|
||||
if (!fsl_mc_regs)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Make sure that the MC firmware is paused before the IOMMU setup for
|
||||
* it is done or otherwise the firmware will crash right after the SMMU
|
||||
* gets probed and enabled.
|
||||
*/
|
||||
writel(readl(fsl_mc_regs + FSL_MC_GCR1) | (GCR1_P1_STOP | GCR1_P2_STOP),
|
||||
fsl_mc_regs + FSL_MC_GCR1);
|
||||
iounmap(fsl_mc_regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct notifier_block fsl_mc_nb = {
|
||||
.notifier_call = fsl_mc_bus_notifier,
|
||||
};
|
||||
|
||||
static int __init fsl_mc_bus_driver_init(void)
|
||||
{
|
||||
int error;
|
||||
@ -1260,7 +1302,7 @@ static int __init fsl_mc_bus_driver_init(void)
|
||||
if (error < 0)
|
||||
goto error_cleanup_dprc_driver;
|
||||
|
||||
return 0;
|
||||
return bus_register_notifier(&platform_bus_type, &fsl_mc_nb);
|
||||
|
||||
error_cleanup_dprc_driver:
|
||||
dprc_driver_exit();
|
||||
|
Loading…
Reference in New Issue
Block a user