static int cm3323_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm3323_p *data = NULL; pr_info("[SENSOR]: %s - Probe Start!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[SENSOR]: %s - i2c_check_functionality error\n", __func__); goto exit; } data = kzalloc(sizeof(struct cm3323_p), GFP_KERNEL); if (data == NULL) { pr_err("[SENSOR]: %s - kzalloc error\n", __func__); ret = -ENOMEM; goto exit_kzalloc; } data->i2c_client = client; i2c_set_clientdata(client, data); /* Check if the device is there or not. */ ret = cm3323_setup_reg(data); if (ret < 0) { pr_err("[SENSOR]: %s - could not setup regs\n", __func__); goto exit_setup_reg; } /* input device init */ ret = cm3323_input_init(data); if (ret < 0) goto exit_input_init; atomic_set(&data->delay, CM3323_DEFAULT_DELAY); data->time_count = 0; INIT_DELAYED_WORK(&data->work, cm3323_work_func_light); /* set sysfs for light sensor */ sensors_register(data->light_dev, data, sensor_attrs, MODULE_NAME); pr_info("[SENSOR]: %s - Probe done!\n", __func__); return 0; exit_input_init: exit_setup_reg: kfree(data); exit_kzalloc: exit: pr_err("[SENSOR]: %s - Probe fail!\n", __func__); return ret; }
static int cm3323_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = -ENODEV; struct cm3323_p *data = NULL; pr_info("[SENSOR]: %s - Probe Start!\n", __func__); if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[SENSOR]: %s - i2c_check_functionality error\n", __func__); goto exit; } data = kzalloc(sizeof(struct cm3323_p), GFP_KERNEL); if (data == NULL) { pr_err("[SENSOR]: %s - kzalloc error\n", __func__); ret = -ENOMEM; goto exit_kzalloc; } data->i2c_client = client; i2c_set_clientdata(client, data); mutex_init(&data->power_lock); mutex_init(&data->read_lock); /* Check if the device is there or not. */ ret = cm3323_setup_reg(data); if (ret < 0) { pr_err("[SENSOR]: %s - could not setup regs\n", __func__); goto exit_setup_reg; } /* input device init */ ret = cm3323_input_init(data); if (ret < 0) goto exit_input_init; /* light_timer settings. we poll for light values using a timer. */ hrtimer_init(&data->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); data->poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC); data->light_timer.function = cm3323_light_timer_func; data->time_count = 0; /* the timer just fires off a work queue request. we need a thread to read the i2c (can be slow and blocking). */ data->light_wq = create_singlethread_workqueue("cm3323_light_wq"); if (!data->light_wq) { ret = -ENOMEM; pr_err("[SENSOR]: %s - could not create light workqueue\n", __func__); goto exit_create_light_workqueue; } /* this is the thread function we run on the work queue */ INIT_WORK(&data->work_light, cm3323_work_func_light); /* set sysfs for light sensor */ sensors_register(data->light_dev, data, sensor_attrs, MODULE_NAME); pr_info("[SENSOR]: %s - Probe done!\n", __func__); return 0; exit_create_light_workqueue: sysfs_remove_group(&data->input->dev.kobj, &light_attribute_group); sensors_remove_symlink(&data->input->dev.kobj, data->input->name); input_unregister_device(data->input); exit_input_init: exit_setup_reg: mutex_destroy(&data->read_lock); mutex_destroy(&data->power_lock); kfree(data); exit_kzalloc: exit: pr_err("[SENSOR]: %s - Probe fail!\n", __func__); return ret; }