aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/platform
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2020-04-16 11:15:40 +0300
committerLee Jones <lee.jones@linaro.org>2020-04-24 11:17:44 +0100
commit7e18c89d6e37bfffa2b161b08f40b53d2ce7ee94 (patch)
tree8148ee6e3983d393e0e646de7a7b74b2863f3440 /drivers/platform
parentplatform/x86: intel_scu_ipcutil: Convert to use new SCU IPC API (diff)
downloadwireguard-linux-7e18c89d6e37bfffa2b161b08f40b53d2ce7ee94.tar.xz
wireguard-linux-7e18c89d6e37bfffa2b161b08f40b53d2ce7ee94.zip
platform/x86: intel_scu_ipc: Add managed function to register SCU IPC
Drivers such as intel_pmc_ipc.c can be unloaded as well so in order to support those in this driver add a new function that can be called to unregister the SCU IPC when it is not needed anymore. We also add a managed version of the intel_scu_ipc_register() that takes care of calling intel_scu_ipc_unregister() automatically when the driver is unbound. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index 608034ea7af5..d9cf7f7602b0 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -637,6 +637,68 @@ err_unlock:
}
EXPORT_SYMBOL_GPL(__intel_scu_ipc_register);
+/**
+ * intel_scu_ipc_unregister() - Unregister SCU IPC
+ * @scu: SCU IPC handle
+ *
+ * This unregisters the SCU IPC device and releases the acquired
+ * resources once the refcount goes to zero.
+ */
+void intel_scu_ipc_unregister(struct intel_scu_ipc_dev *scu)
+{
+ mutex_lock(&ipclock);
+ if (!WARN_ON(!ipcdev)) {
+ ipcdev = NULL;
+ device_unregister(&scu->dev);
+ }
+ mutex_unlock(&ipclock);
+}
+EXPORT_SYMBOL_GPL(intel_scu_ipc_unregister);
+
+static void devm_intel_scu_ipc_unregister(struct device *dev, void *res)
+{
+ struct intel_scu_ipc_devres *dr = res;
+ struct intel_scu_ipc_dev *scu = dr->scu;
+
+ intel_scu_ipc_unregister(scu);
+}
+
+/**
+ * __devm_intel_scu_ipc_register() - Register managed SCU IPC device
+ * @parent: Parent device
+ * @scu_data: Data used to configure SCU IPC
+ * @owner: Module registering the SCU IPC device
+ *
+ * Call this function to register managed SCU IPC mechanism under
+ * @parent. Returns pointer to the new SCU IPC device or ERR_PTR() in
+ * case of failure. The caller may use the returned instance if it needs
+ * to do SCU IPC calls itself.
+ */
+struct intel_scu_ipc_dev *
+__devm_intel_scu_ipc_register(struct device *parent,
+ const struct intel_scu_ipc_data *scu_data,
+ struct module *owner)
+{
+ struct intel_scu_ipc_devres *dr;
+ struct intel_scu_ipc_dev *scu;
+
+ dr = devres_alloc(devm_intel_scu_ipc_unregister, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return NULL;
+
+ scu = __intel_scu_ipc_register(parent, scu_data, owner);
+ if (IS_ERR(scu)) {
+ devres_free(dr);
+ return scu;
+ }
+
+ dr->scu = scu;
+ devres_add(parent, dr);
+
+ return scu;
+}
+EXPORT_SYMBOL_GPL(__devm_intel_scu_ipc_register);
+
static int __init intel_scu_ipc_init(void)
{
return class_register(&intel_scu_ipc_class);