drivers/power/reset/qemu-virt-ctrl.c

Source file repositories/reference/linux-study-clean/drivers/power/reset/qemu-virt-ctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/power/reset/qemu-virt-ctrl.c
Extension
.c
Size
3004 bytes
Lines
123
Domain
Driver Families
Bucket
drivers/power
Inferred role
Driver Families: implementation source
Status
source 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

struct qemu_virt_ctrl {
	void __iomem *base;
	struct notifier_block reboot_nb;
};

static inline void virt_ctrl_write32(u32 val, void __iomem *addr)
{
	if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
		iowrite32be(val, addr);
	else
		iowrite32(val, addr);
}

static int qemu_virt_ctrl_power_off(struct sys_off_data *data)
{
	struct qemu_virt_ctrl *ctrl = data->cb_data;

	virt_ctrl_write32(CMD_HALT, ctrl->base + VIRT_CTRL_REG_CMD);

	return NOTIFY_DONE;
}

static int qemu_virt_ctrl_restart(struct sys_off_data *data)
{
	struct qemu_virt_ctrl *ctrl = data->cb_data;

	virt_ctrl_write32(CMD_RESET, ctrl->base + VIRT_CTRL_REG_CMD);

	return NOTIFY_DONE;
}

static int qemu_virt_ctrl_reboot_notify(struct notifier_block *nb,
					unsigned long action, void *data)
{
	struct qemu_virt_ctrl *ctrl = container_of(nb, struct qemu_virt_ctrl, reboot_nb);

	if (action == SYS_HALT)
		virt_ctrl_write32(CMD_HALT, ctrl->base + VIRT_CTRL_REG_CMD);

	return NOTIFY_DONE;
}

static int qemu_virt_ctrl_probe(struct platform_device *pdev)
{
	struct qemu_virt_ctrl *ctrl;
	int ret;

	ctrl = devm_kzalloc(&pdev->dev, sizeof(*ctrl), GFP_KERNEL);
	if (!ctrl)
		return -ENOMEM;

	ctrl->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(ctrl->base))
		return PTR_ERR(ctrl->base);

	ret = devm_register_sys_off_handler(&pdev->dev,
					    SYS_OFF_MODE_RESTART,
					    SYS_OFF_PRIO_DEFAULT,
					    qemu_virt_ctrl_restart,
					    ctrl);
	if (ret)
		return dev_err_probe(&pdev->dev, ret,
				     "cannot register restart handler\n");

	ret = devm_register_sys_off_handler(&pdev->dev,
					    SYS_OFF_MODE_POWER_OFF,
					    SYS_OFF_PRIO_DEFAULT,
					    qemu_virt_ctrl_power_off,
					    ctrl);
	if (ret)
		return dev_err_probe(&pdev->dev, ret,
				     "cannot register power-off handler\n");

	ctrl->reboot_nb.notifier_call = qemu_virt_ctrl_reboot_notify;
	ret = devm_register_reboot_notifier(&pdev->dev, &ctrl->reboot_nb);
	if (ret)
		return dev_err_probe(&pdev->dev, ret, "cannot register reboot notifier\n");

	return 0;
}

static const struct platform_device_id qemu_virt_ctrl_id[] = {
	{ .name = "qemu-virt-ctrl" },
	{ }
};
MODULE_DEVICE_TABLE(platform, qemu_virt_ctrl_id);

static struct platform_driver qemu_virt_ctrl_driver = {
	.probe = qemu_virt_ctrl_probe,
	.driver = {

Annotation

Implementation Notes