diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2018-06-21 18:00:05 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2018-07-27 09:58:12 +1000 |
commit | 9840fcd8cc43bfba486a53b4461044f1a1189cdc (patch) | |
tree | a2ba69532326e0b578283f277c741b4c7de7a21f /drivers/fsi/fsi-core.c | |
parent | d1dcd678257603e71cf3f3d84c70e2b6f0f14bb8 (diff) |
fsi: Prevent multiple concurrent rescans
The bus scanning process isn't terribly good at parallel attempts
at rescanning the same bus. Let's have a per-master mutex protecting
the scanning process.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'drivers/fsi/fsi-core.c')
-rw-r--r-- | drivers/fsi/fsi-core.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index dea5bd48acc5..2c31563fdcae 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -1203,8 +1203,14 @@ static void fsi_master_unscan(struct fsi_master *master) int fsi_master_rescan(struct fsi_master *master) { + int rc; + + mutex_lock(&master->scan_lock); fsi_master_unscan(master); - return fsi_master_scan(master); + rc = fsi_master_scan(master); + mutex_unlock(&master->scan_lock); + + return rc; } EXPORT_SYMBOL_GPL(fsi_master_rescan); @@ -1240,6 +1246,7 @@ int fsi_master_register(struct fsi_master *master) int rc; struct device_node *np; + mutex_init(&master->scan_lock); master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL); dev_set_name(&master->dev, "fsi%d", master->idx); @@ -1264,8 +1271,11 @@ int fsi_master_register(struct fsi_master *master) } np = dev_of_node(&master->dev); - if (!of_property_read_bool(np, "no-scan-on-init")) + if (!of_property_read_bool(np, "no-scan-on-init")) { + mutex_lock(&master->scan_lock); fsi_master_scan(master); + mutex_unlock(&master->scan_lock); + } return 0; } @@ -1278,7 +1288,9 @@ void fsi_master_unregister(struct fsi_master *master) master->idx = -1; } + mutex_lock(&master->scan_lock); fsi_master_unscan(master); + mutex_unlock(&master->scan_lock); device_unregister(&master->dev); } EXPORT_SYMBOL_GPL(fsi_master_unregister); |