drivers/base/firmware_loader/sysfs_upload.c

Source file repositories/reference/linux-study-clean/drivers/base/firmware_loader/sysfs_upload.c

File Facts

System
Linux kernel
Corpus path
drivers/base/firmware_loader/sysfs_upload.c
Extension
.c
Size
10333 bytes
Lines
409
Domain
Driver Families
Bucket
drivers/base
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

ret = device_add(fw_dev);
	if (ret) {
		dev_err(fw_dev, "%s: device_register failed\n", __func__);
		put_device(fw_dev);
		goto exit_module_put;
	}

	return fw_upload;

free_fw_upload_priv:
	kfree(fw_upload_priv);

free_fw_upload:
	kfree(fw_upload);

exit_module_put:
	module_put(module);

	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(firmware_upload_register);

/**
 * firmware_upload_unregister() - Unregister firmware upload interface
 * @fw_upload: pointer to struct fw_upload
 **/
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) {
		mutex_unlock(&fw_upload_priv->lock);
		goto unregister;
	}

	fw_upload_priv->ops->cancel(fw_upload);
	mutex_unlock(&fw_upload_priv->lock);

	/* Ensure lower-level device-driver is finished */
	flush_work(&fw_upload_priv->work);

unregister:
	device_unregister(&fw_sysfs->dev);
	module_put(module);
}
EXPORT_SYMBOL_GPL(firmware_upload_unregister);

Annotation

Implementation Notes