Driver core fixes for 6.0-rc4
Here are some small driver core fixes for some oft-reported problems in 6.0-rc1. They include: - a bunch of reverts to handle driver_deferred_probe_check_state() problems that were part of the 6.0-rc1 merge. - firmware_loader bugfixes now that the code is being properly tested and used by others - arch_topology fix - deferred driver probe bugfix to solve a long-suffering amba bus problem that many people have reported. All of these have been in linux-next for a while with no reported problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCYxIhbg8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ykhDACgr/u/okZMF3Kds56Rg/2onnEzTScAmgPVBzQY NxzzAxoNfcCnHuYIh3z3 =s9FB -----END PGP SIGNATURE----- Merge tag 'driver-core-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core fixes from Greg KH: "Here are some small driver core fixes for some oft-reported problems in 6.0-rc1. They include: - a bunch of reverts to handle driver_deferred_probe_check_state() problems that were part of the 6.0-rc1 merge. - firmware_loader bugfixes now that the code is being properly tested and used by others - arch_topology fix - deferred driver probe bugfix to solve a long-suffering amba bus problem that many people have reported. All of these have been in linux-next for a while with no reported problems" * tag 'driver-core-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: firmware_loader: Fix memory leak in firmware upload firmware_loader: Fix use-after-free during unregister arch_topology: Silence early cacheinfo errors when non-existent driver core: Don't probe devices after bus_type.match() probe deferral Revert "iommu/of: Delete usage of driver_deferred_probe_check_state()" Revert "PM: domains: Delete usage of driver_deferred_probe_check_state()" Revert "net: mdio: Delete usage of driver_deferred_probe_check_state()" Revert "driver core: Delete driver_deferred_probe_check_state()"
This commit is contained in:
commit
0b3acd1cc0
|
@ -735,7 +735,7 @@ void update_siblings_masks(unsigned int cpuid)
|
|||
int cpu, ret;
|
||||
|
||||
ret = detect_cache_attributes(cpuid);
|
||||
if (ret)
|
||||
if (ret && ret != -ENOENT)
|
||||
pr_info("Early cacheinfo failed, ret = %d\n", ret);
|
||||
|
||||
/* update core and thread sibling masks */
|
||||
|
|
|
@ -274,12 +274,42 @@ static int __init deferred_probe_timeout_setup(char *str)
|
|||
}
|
||||
__setup("deferred_probe_timeout=", deferred_probe_timeout_setup);
|
||||
|
||||
/**
|
||||
* driver_deferred_probe_check_state() - Check deferred probe state
|
||||
* @dev: device to check
|
||||
*
|
||||
* Return:
|
||||
* * -ENODEV if initcalls have completed and modules are disabled.
|
||||
* * -ETIMEDOUT if the deferred probe timeout was set and has expired
|
||||
* and modules are enabled.
|
||||
* * -EPROBE_DEFER in other cases.
|
||||
*
|
||||
* Drivers or subsystems can opt-in to calling this function instead of directly
|
||||
* returning -EPROBE_DEFER.
|
||||
*/
|
||||
int driver_deferred_probe_check_state(struct device *dev)
|
||||
{
|
||||
if (!IS_ENABLED(CONFIG_MODULES) && initcalls_done) {
|
||||
dev_warn(dev, "ignoring dependency for device, assuming no driver\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!driver_deferred_probe_timeout && initcalls_done) {
|
||||
dev_warn(dev, "deferred probe timeout, ignoring dependency\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(driver_deferred_probe_check_state);
|
||||
|
||||
static void deferred_probe_timeout_work_func(struct work_struct *work)
|
||||
{
|
||||
struct device_private *p;
|
||||
|
||||
fw_devlink_drivers_done();
|
||||
|
||||
driver_deferred_probe_timeout = 0;
|
||||
driver_deferred_probe_trigger();
|
||||
flush_work(&deferred_probe_work);
|
||||
|
||||
|
@ -881,6 +911,11 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
|
|||
dev_dbg(dev, "Device match requests probe deferral\n");
|
||||
dev->can_match = true;
|
||||
driver_deferred_probe_add(dev);
|
||||
/*
|
||||
* Device can't match with a driver right now, so don't attempt
|
||||
* to match or bind with other drivers on the bus.
|
||||
*/
|
||||
return ret;
|
||||
} else if (ret < 0) {
|
||||
dev_dbg(dev, "Bus failed to match device: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -1120,6 +1155,11 @@ static int __driver_attach(struct device *dev, void *data)
|
|||
dev_dbg(dev, "Device match requests probe deferral\n");
|
||||
dev->can_match = true;
|
||||
driver_deferred_probe_add(dev);
|
||||
/*
|
||||
* Driver could not match with device, but may match with
|
||||
* another device on the bus.
|
||||
*/
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
dev_dbg(dev, "Bus failed to match device: %d\n", ret);
|
||||
return ret;
|
||||
|
|
|
@ -93,10 +93,9 @@ static void fw_dev_release(struct device *dev)
|
|||
{
|
||||
struct fw_sysfs *fw_sysfs = to_fw_sysfs(dev);
|
||||
|
||||
if (fw_sysfs->fw_upload_priv) {
|
||||
free_fw_priv(fw_sysfs->fw_priv);
|
||||
kfree(fw_sysfs->fw_upload_priv);
|
||||
}
|
||||
if (fw_sysfs->fw_upload_priv)
|
||||
fw_upload_free(fw_sysfs);
|
||||
|
||||
kfree(fw_sysfs);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,12 +106,17 @@ extern struct device_attribute dev_attr_cancel;
|
|||
extern struct device_attribute dev_attr_remaining_size;
|
||||
|
||||
int fw_upload_start(struct fw_sysfs *fw_sysfs);
|
||||
void fw_upload_free(struct fw_sysfs *fw_sysfs);
|
||||
umode_t fw_upload_is_visible(struct kobject *kobj, struct attribute *attr, int n);
|
||||
#else
|
||||
static inline int fw_upload_start(struct fw_sysfs *fw_sysfs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fw_upload_free(struct fw_sysfs *fw_sysfs)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __FIRMWARE_SYSFS_H */
|
||||
|
|
|
@ -264,6 +264,15 @@ int fw_upload_start(struct fw_sysfs *fw_sysfs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void fw_upload_free(struct fw_sysfs *fw_sysfs)
|
||||
{
|
||||
struct fw_upload_priv *fw_upload_priv = fw_sysfs->fw_upload_priv;
|
||||
|
||||
free_fw_priv(fw_sysfs->fw_priv);
|
||||
kfree(fw_upload_priv->fw_upload);
|
||||
kfree(fw_upload_priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* firmware_upload_register() - register for the firmware upload sysfs API
|
||||
* @module: kernel module of this device
|
||||
|
@ -377,6 +386,7 @@ void firmware_upload_unregister(struct fw_upload *fw_upload)
|
|||
{
|
||||
struct fw_sysfs *fw_sysfs = fw_upload->priv;
|
||||
struct fw_upload_priv *fw_upload_priv = fw_sysfs->fw_upload_priv;
|
||||
struct module *module = fw_upload_priv->module;
|
||||
|
||||
mutex_lock(&fw_upload_priv->lock);
|
||||
if (fw_upload_priv->progress == FW_UPLOAD_PROG_IDLE) {
|
||||
|
@ -392,6 +402,6 @@ void firmware_upload_unregister(struct fw_upload *fw_upload)
|
|||
|
||||
unregister:
|
||||
device_unregister(&fw_sysfs->dev);
|
||||
module_put(fw_upload_priv->module);
|
||||
module_put(module);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(firmware_upload_unregister);
|
||||
|
|
|
@ -2733,7 +2733,7 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev,
|
|||
mutex_unlock(&gpd_list_lock);
|
||||
dev_dbg(dev, "%s() failed to find PM domain: %ld\n",
|
||||
__func__, PTR_ERR(pd));
|
||||
return -ENODEV;
|
||||
return driver_deferred_probe_check_state(base_dev);
|
||||
}
|
||||
|
||||
dev_dbg(dev, "adding to PM domain %s\n", pd->name);
|
||||
|
|
|
@ -40,7 +40,7 @@ static int of_iommu_xlate(struct device *dev,
|
|||
* a proper probe-ordering dependency mechanism in future.
|
||||
*/
|
||||
if (!ops)
|
||||
return -ENODEV;
|
||||
return driver_deferred_probe_check_state(dev);
|
||||
|
||||
if (!try_module_get(ops->owner))
|
||||
return -ENODEV;
|
||||
|
|
|
@ -47,7 +47,9 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
|
|||
* just fall back to poll mode
|
||||
*/
|
||||
if (rc == -EPROBE_DEFER)
|
||||
rc = -ENODEV;
|
||||
rc = driver_deferred_probe_check_state(&phy->mdio.dev);
|
||||
if (rc == -EPROBE_DEFER)
|
||||
return rc;
|
||||
|
||||
if (rc > 0) {
|
||||
phy->irq = rc;
|
||||
|
|
|
@ -242,6 +242,7 @@ driver_find_device_by_acpi_dev(struct device_driver *drv, const void *adev)
|
|||
|
||||
extern int driver_deferred_probe_timeout;
|
||||
void driver_deferred_probe_add(struct device *dev);
|
||||
int driver_deferred_probe_check_state(struct device *dev);
|
||||
void driver_init(void);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue