drivers/accel/qaic/qaic_drv.c

Source file repositories/reference/linux-study-clean/drivers/accel/qaic/qaic_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/accel/qaic/qaic_drv.c
Extension
.c
Size
22512 bytes
Lines
859
Domain
Driver Families
Bucket
drivers/accel
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static struct pci_driver qaic_pci_driver = {
	.name = QAIC_NAME,
	.id_table = qaic_ids,
	.probe = qaic_pci_probe,
	.remove = qaic_pci_remove,
	.shutdown = qaic_pci_shutdown,
	.err_handler = &qaic_pci_err_handler,
	.driver = {
		.pm = pm_sleep_ptr(&qaic_pm_ops),
	},
};

static int __init qaic_init(void)
{
	int ret;

	ret = pci_register_driver(&qaic_pci_driver);
	if (ret) {
		pr_debug("qaic: pci_register_driver failed %d\n", ret);
		return ret;
	}

	ret = mhi_driver_register(&qaic_mhi_driver);
	if (ret) {
		pr_debug("qaic: mhi_driver_register failed %d\n", ret);
		goto free_pci;
	}

	ret = sahara_register();
	if (ret) {
		pr_debug("qaic: sahara_register failed %d\n", ret);
		goto free_mhi;
	}

	ret = qaic_timesync_init();
	if (ret)
		pr_debug("qaic: qaic_timesync_init failed %d\n", ret);

	ret = qaic_bootlog_register();
	if (ret)
		pr_debug("qaic: qaic_bootlog_register failed %d\n", ret);

	ret = qaic_ras_register();
	if (ret)
		pr_debug("qaic: qaic_ras_register failed %d\n", ret);
	ret = qaic_ssr_register();
	if (ret) {
		pr_debug("qaic: qaic_ssr_register failed %d\n", ret);
		goto free_bootlog;
	}

	return 0;

free_bootlog:
	qaic_bootlog_unregister();
free_mhi:
	mhi_driver_unregister(&qaic_mhi_driver);
free_pci:
	pci_unregister_driver(&qaic_pci_driver);
	return ret;
}

static void __exit qaic_exit(void)
{
	/*
	 * We assume that qaic_pci_remove() is called due to a hotplug event
	 * which would mean that the link is down, and thus
	 * qaic_mhi_free_controller() should not try to access the device during
	 * cleanup.
	 * We call pci_unregister_driver() below, which also triggers
	 * qaic_pci_remove(), but since this is module exit, we expect the link
	 * to the device to be up, in which case qaic_mhi_free_controller()
	 * should try to access the device during cleanup to put the device in
	 * a sane state.
	 * For that reason, we set link_up here to let qaic_mhi_free_controller
	 * know the expected link state. Since the module is going to be
	 * removed at the end of this, we don't need to worry about
	 * reinitializing the link_up state after the cleanup is done.
	 */
	link_up = true;
	qaic_ssr_unregister();
	qaic_ras_unregister();
	qaic_bootlog_unregister();
	qaic_timesync_deinit();
	sahara_unregister();
	mhi_driver_unregister(&qaic_mhi_driver);
	pci_unregister_driver(&qaic_pci_driver);
}

module_init(qaic_init);

Annotation

Implementation Notes