diff --git a/drivers/virt/gunyah/Kconfig b/drivers/virt/gunyah/Kconfig index bd8e31184962..2eac0b68fcec 100644 --- a/drivers/virt/gunyah/Kconfig +++ b/drivers/virt/gunyah/Kconfig @@ -5,6 +5,7 @@ config GUNYAH depends on ARM64 depends on MAILBOX select GUNYAH_PLATFORM_HOOKS + select AUXILIARY_BUS help The Gunyah drivers are the helper interfaces that run in a guest VM such as basic inter-VM IPC and signaling mechanisms, and higher level diff --git a/drivers/virt/gunyah/rsc_mgr.c b/drivers/virt/gunyah/rsc_mgr.c index 383be5ac0f44..cddf249faf79 100644 --- a/drivers/virt/gunyah/rsc_mgr.c +++ b/drivers/virt/gunyah/rsc_mgr.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,7 @@ struct gh_rm { struct mutex send_lock; struct blocking_notifier_head nh; + struct auxiliary_device adev; struct miscdevice miscdev; struct irq_domain *irq_domain; }; @@ -704,6 +706,7 @@ free: kfree(connection); return ret; } +EXPORT_SYMBOL_GPL(gh_rm_call); int gh_rm_notifier_register(struct gh_rm *rm, struct notifier_block *nb) @@ -745,6 +748,32 @@ static const struct file_operations gh_dev_fops = { .llseek = noop_llseek, }; +static void gh_adev_release(struct device *dev) +{ + /* no-op */ +} + +static int gh_adev_init(struct gh_rm *rm, const char *name) +{ + struct auxiliary_device *adev = &rm->adev; + int ret = 0; + + adev->name = name; + adev->dev.parent = rm->dev; + adev->dev.release = gh_adev_release; + ret = auxiliary_device_init(adev); + if (ret) + return ret; + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return ret; +} + static int gh_msgq_platform_probe_direction(struct platform_device *pdev, bool tx, struct gh_resource *ghrsc) { @@ -841,7 +870,16 @@ static int gh_rm_drv_probe(struct platform_device *pdev) if (ret) goto err_irq_domain; + ret = gh_adev_init(rm, "gh_rm_core"); + if (ret) { + dev_err(&pdev->dev, "Failed to add gh_rm_core device\n"); + goto err_misc_device; + } + return 0; + +err_misc_device: + misc_deregister(&rm->miscdev); err_irq_domain: irq_domain_remove(rm->irq_domain); err_msgq: @@ -856,6 +894,8 @@ static int gh_rm_drv_remove(struct platform_device *pdev) { struct gh_rm *rm = platform_get_drvdata(pdev); + auxiliary_device_delete(&rm->adev); + auxiliary_device_uninit(&rm->adev); misc_deregister(&rm->miscdev); irq_domain_remove(rm->irq_domain); mbox_free_channel(gh_msgq_chan(&rm->msgq)); diff --git a/include/linux/gunyah_rsc_mgr.h b/include/linux/gunyah_rsc_mgr.h index 58693c27cf1a..b2a5505007f5 100644 --- a/include/linux/gunyah_rsc_mgr.h +++ b/include/linux/gunyah_rsc_mgr.h @@ -14,6 +14,8 @@ #define GH_MEM_HANDLE_INVAL U32_MAX struct gh_rm; +int gh_rm_call(struct gh_rm *rm, u32 message_id, void *req_buff, size_t req_buff_size, + void **resp_buf, size_t *resp_buff_size); int gh_rm_notifier_register(struct gh_rm *rm, struct notifier_block *nb); int gh_rm_notifier_unregister(struct gh_rm *rm, struct notifier_block *nb); struct device *gh_rm_get(struct gh_rm *rm);