ckernelgcc-warninggcc4.9

GCC compiler error, 'p_data' may be used uninitialized


New to C language, from looking at the code I cannot figure out how to initialize p_data. From what I can figure out p_data is part of a structure.
Can someone explain how to initialize p_data?

#ifdef CUST_LGE_TOUCH_BRING_UP
struct synaptics_rmi4_data *rmi4_data;
struct synaptics_rmi4_device_info *rmi;
const struct synaptics_dsx_board_data *platform_data =
        client->dev.platform_data;
struct synaptics_dsx_board_data *p_data;

printk("[Touch] %s START!!!!!!!!!!!!!!\n",__func__);
#endif

if (!i2c_check_functionality(client->adapter,
        I2C_FUNC_SMBUS_BYTE_DATA)) {
    dev_err(&client->dev,
            "%s: SMBus byte data commands not supported by host\n",
            __func__);
    return -EIO;
}
#ifdef CUST_LGE_TOUCH_BRING_UP
rmi4_data = kzalloc(sizeof(*rmi4_data), GFP_KERNEL);
if (!rmi4_data) {
    dev_err(&client->dev,
            "%s: Failed to alloc mem for rmi4_data\n",
            __func__);
    return -ENOMEM;
}
#endif

synaptics_dsx_i2c_device = kzalloc(
        sizeof(struct platform_device),
        GFP_KERNEL);
if (!synaptics_dsx_i2c_device) {
    dev_err(&client->dev,
            "%s: Failed to allocate memory for synaptics_dsx_i2c_device\n",
            __func__);
    ret = -ENOMEM;
    goto err_alloc_dsx_i2c_device;
}

#ifdef CUST_LGE_TOUCH_BRING_UP
if (client->dev.of_node) {
    p_data = devm_kzalloc(&client->dev,
        sizeof(struct synaptics_dsx_board_data), GFP_KERNEL);
    if (!p_data) {
        dev_err(&client->dev, "%s : Failed to allocate memory\n", __func__);
        ret = -ENOMEM;
        goto error_alloc_dsx_board_data;
    }

    retval = synaptics_rmi4_parse_dt(&client->dev, p_data);
    platform_data = p_data;
    client->dev.platform_data = p_data;
    if (retval) {
        printk("%s : Failed to parse device Tree",__func__);
        ret = retval;
        goto error;
    }

} else {
    platform_data  = client->dev.platform_data;
    if (!platform_data) {
        printk("%s : Failed to copy platform_data\n", __func__);
        retval = -EINVAL;
    }
}

printk("%s: Probing i2c RMI device, addr: 0x%02x\n", __func__, client->addr);

rmi = &(rmi4_data->rmi4_mod_info);

if (!platform_data) {
    dev_err(&client->dev,
            "%s: No platform data found\n",
            __func__);
    ret = -EINVAL;
    goto error;
}

printk("[Touch D] x_flip = %d\n", platform_data->x_flip);
printk("[Touch D] y_flip = %d\n", platform_data->y_flip);
printk("[Touch D] regulator_en = %d\n", platform_data->regulator_en);
printk("[Touch D] reset_gpio = %d\n", platform_data->reset_gpio);
printk("[Touch D] irq_gpio = %d\n", platform_data->irq_gpio);
printk("[Touch D] irq_flags = %lx\n", platform_data->irq_flags);
printk("[Touch D] panel_x = %d\n", platform_data->panel_x);
printk("[Touch D] panel_y = %d\n", platform_data->panel_y);
printk("[Touch D] reset_delay_ms = %d\n", platform_data->reset_delay_ms);

 if (platform_data->regulator_en) { 
    rmi4_data->vreg_l22 = regulator_get(&client->dev, "vdd_ana"); 
    if (IS_ERR(rmi4_data->vreg_l22)) { 
        dev_err(&client->dev, 
                "%s: Failed to get regulator vreg_l22\n", 
                __func__); 
        retval = PTR_ERR(rmi4_data->vreg_l22);
        ret = -retval;
        goto error;
    } 
    regulator_set_voltage(rmi4_data->vreg_l22, 3300000, 3300000); 
    regulator_enable(rmi4_data->vreg_l22); 

    rmi4_data->vreg_lvs3 = regulator_get(&client->dev, "vcc_i2c"); 
    if (IS_ERR(rmi4_data->vreg_lvs3)) { 
        dev_err(&client->dev, 
                "%s: Failed to get regulator vreg_l22\n",
                __func__); 
        retval = PTR_ERR(rmi4_data->vreg_lvs3);
        ret = -retval;
        goto error;
    } 
    regulator_enable(rmi4_data->vreg_lvs3); 
    }else
    rmi4_power_on(client, 1);
    msleep(400);

printk("[Touch D] %s : Done regulator set!!! \n",__func__);
#endif

hw_if.board_data = client->dev.platform_data;
hw_if.bus_access = &bus_access;

synaptics_dsx_i2c_device->name = PLATFORM_DRIVER_NAME;
synaptics_dsx_i2c_device->id = 0;
synaptics_dsx_i2c_device->num_resources = 0;
synaptics_dsx_i2c_device->dev.parent = &client->dev;
synaptics_dsx_i2c_device->dev.platform_data = &hw_if;
synaptics_dsx_i2c_device->dev.release = synaptics_rmi4_i2c_dev_release;

retval = platform_device_register(synaptics_dsx_i2c_device);
if (retval) {
    dev_err(&client->dev,
            "%s: Failed to register platform device\n",
            __func__);
    ret = -ENODEV;
    goto error;
}

#ifdef CUST_LGE_TOUCH_BRING_UP
printk("[Touch D] Complete %s !!! \n",__func__);
#endif
return 0;

#ifdef CUST_LGE_TOUCH_BRING_UP
error:
devm_kfree(&client->dev, p_data);
#endif

That last part is where the compiler warning is, can it because error: is after return 0; ?

 #ifdef CUST_LGE_TOUCH_BRING_UP
error:
devm_kfree(&client->dev, p_data);
#endif

Solution

  • If client->dev.of_node is false here

    if (client->dev.of_node) {
    

    p_data is never initialised, but still the code finally calls

    devm_kfree(&client->dev, p_data);
    

    hence the warning.

    To fix this you might want to change this

    struct synaptics_dsx_board_data *p_data;
    

    to be

    struct synaptics_dsx_board_data *p_data = NULL;
    

    This fix assumes that devm_kfree(&client->dev, p_data); can handle a NULL being past as last argument.