]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Input: rmi4 - refactor function allocation and registration
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 5 May 2026 04:59:40 +0000 (21:59 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 12 Jun 2026 05:39:28 +0000 (22:39 -0700)
Currently, rmi_create_function() allocates memory for the rmi_function
structure, but rmi_register_function() initializes the device via
device_initialize(). This split of ownership makes error handling in
rmi_create_function() confusing because the caller must be aware that
if rmi_register_function() fails, it has already called put_device() to
clean up the memory.

To make the memory lifecycle explicit and fix potential leaks cleanly
introduce rmi_alloc_function() to handle memory allocation and device
initialization, and make the caller of rmi_register_function()
responsible for cleanup.

Assisted-by: Gemini:gemini-3.1-pro
Link: https://patch.msgid.link/20260505045952.1570713-10-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/rmi4/rmi_bus.c
drivers/input/rmi4/rmi_bus.h
drivers/input/rmi4/rmi_driver.c

index ade57e2a7201454f814c72f861b60b0c46ac79f1..c58866df555d53eaf81ea544555f3d772df5ef7b 100644 (file)
@@ -237,36 +237,46 @@ static int rmi_function_remove(struct device *dev)
        return 0;
 }
 
-int rmi_register_function(struct rmi_function *fn)
+struct rmi_function *rmi_alloc_function(struct rmi_device *rmi_dev, u8 id)
 {
-       struct rmi_device *rmi_dev = fn->rmi_dev;
-       int error;
+       struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
+       struct rmi_function *fn;
+
+       fn = kzalloc(sizeof(*fn) +
+                       BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long),
+                    GFP_KERNEL);
+       if (!fn)
+               return NULL;
 
        device_initialize(&fn->dev);
 
-       dev_set_name(&fn->dev, "%s.fn%02x",
-                    dev_name(&rmi_dev->dev), fn->fd.function_number);
+       dev_set_name(&fn->dev, "%s.fn%02x", dev_name(&rmi_dev->dev), id);
 
        fn->dev.parent = &rmi_dev->dev;
        fn->dev.type = &rmi_function_type;
        fn->dev.bus = &rmi_bus_type;
+       fn->rmi_dev = rmi_dev;
+
+       return fn;
+}
+
+int rmi_register_function(struct rmi_function *fn)
+{
+       struct rmi_device *rmi_dev = fn->rmi_dev;
+       int error;
 
        error = device_add(&fn->dev);
        if (error) {
                dev_err(&rmi_dev->dev,
-                       "Failed device_register function device %s\n",
+                       "Failed to register function device %s\n",
                        dev_name(&fn->dev));
-               goto err_put_device;
+               return error;
        }
 
        rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev, "Registered F%02X.\n",
                        fn->fd.function_number);
 
        return 0;
-
-err_put_device:
-       put_device(&fn->dev);
-       return error;
 }
 
 void rmi_unregister_function(struct rmi_function *fn)
index d4d0d82c69aa32b0da9e3ee2694fb1157a4fbc67..90122df21f746cc3b8da326035f96da3ae1d68f0 100644 (file)
@@ -49,6 +49,7 @@ struct rmi_function {
 
 bool rmi_is_function_device(struct device *dev);
 
+struct rmi_function *rmi_alloc_function(struct rmi_device *rmi_dev, u8 id);
 int __must_check rmi_register_function(struct rmi_function *);
 void rmi_unregister_function(struct rmi_function *);
 
index 94b49e4dd0fa29fca897b3e36178e1deca7b0292..2ac82cd3ff6d4889d3d9dd3f890c5c01eac34301 100644 (file)
@@ -872,9 +872,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
        rmi_dbg(RMI_DEBUG_CORE, dev, "Initializing F%02X.\n",
                        pdt->function_number);
 
-       fn = kzalloc(sizeof(struct rmi_function) +
-                       BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long),
-                    GFP_KERNEL);
+       fn = rmi_alloc_function(rmi_dev, pdt->function_number);
        if (!fn) {
                dev_err(dev, "Failed to allocate memory for F%02X\n",
                        pdt->function_number);
@@ -884,8 +882,6 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
        INIT_LIST_HEAD(&fn->node);
        rmi_driver_copy_pdt_to_fd(pdt, &fn->fd);
 
-       fn->rmi_dev = rmi_dev;
-
        fn->num_of_irqs = pdt->interrupt_source_count;
        fn->irq_pos = *current_irq_count;
        *current_irq_count += fn->num_of_irqs;
@@ -894,8 +890,10 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
                set_bit(fn->irq_pos + i, fn->irq_mask);
 
        error = rmi_register_function(fn);
-       if (error)
+       if (error) {
+               put_device(&fn->dev);
                return error;
+       }
 
        if (pdt->function_number == 0x01)
                data->f01_container = fn;