input: sensor-dev: fix smatch warning
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / sensor-dev.c
index d7536fc421f75aa2766bfaa3ea4988939a573b18..0527631730972a9485403269bb1ff1b4b7d6170f 100755 (executable)
@@ -36,7 +36,9 @@
 #include <linux/l3g4200d.h>\r
 #include <linux/sensor-dev.h>\r
 #include <linux/module.h>\r
-\r
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+#endif
 \r
 \r
 /*\r
@@ -392,7 +394,39 @@ static void sensor_resume(struct early_suspend *h)
                sensor->ops->resume(sensor->client);\r
 }\r
 #endif\r
-\r
+
+#ifdef CONFIG_PM
+static int sensor_of_suspend(struct device *dev)
+{
+       struct sensor_private_data *sensor = dev_get_drvdata(dev);
+
+       if (sensor->ops->suspend)
+               sensor->ops->suspend(sensor->client);
+
+       return 0;
+}
+
+static int sensor_of_resume(struct device *dev)
+{
+       struct sensor_private_data *sensor = dev_get_drvdata(dev);
+
+       if (sensor->ops->resume)
+               sensor->ops->resume(sensor->client);
+       if (sensor->pdata->power_off_in_suspend)
+               sensor_initial(sensor->client);
+
+       return 0;
+}
+
+static const struct dev_pm_ops sensor_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(sensor_of_suspend, sensor_of_resume)
+};
+
+#define SENSOR_PM_OPS (&sensor_pm_ops)
+#else
+#define SENSOR_PM_OPS NULL
+#endif
+
 static int angle_dev_open(struct inode *inode, struct file *file)\r
 {\r
        //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_ACCEL];     \r
@@ -460,7 +494,6 @@ static long angle_dev_ioctl(struct file *file,
                                }       \r
                                else\r
                                {\r
-                                       PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                        schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                }\r
                                sensor->status_cur = SENSOR_ON;\r
@@ -608,7 +641,6 @@ static long gsensor_dev_ioctl(struct file *file,
                                }       \r
                                else\r
                                {\r
-                                       PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                        schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                }\r
                                sensor->status_cur = SENSOR_ON;\r
@@ -794,7 +826,59 @@ static int compass_dev_release(struct inode *inode, struct file *file)
        return result;\r
 }\r
 \r
-\r
+#ifdef CONFIG_COMPAT
+/* ioctl - I/O control */
+static long compass_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       void __user *arg64 = compat_ptr(arg);
+       int result = 0;
+
+       if (!file->f_op || !file->f_op->unlocked_ioctl) {
+               pr_err("file->f_op or file->f_op->unlocked_ioctl is null\n");
+               return -ENOTTY;
+       }
+
+       switch (cmd) {
+       case COMPAT_ECS_IOCTL_APP_SET_MFLAG:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_MFLAG, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_GET_MFLAG:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_MFLAG, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_SET_AFLAG:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_AFLAG, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_GET_AFLAG:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_AFLAG, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_SET_MVFLAG:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_MVFLAG, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_GET_MVFLAG:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_MVFLAG, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_SET_DELAY:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_SET_DELAY, (unsigned long)arg64);
+               break;
+       case COMPAT_ECS_IOCTL_APP_GET_DELAY:
+               if (file->f_op->unlocked_ioctl)
+                       result = file->f_op->unlocked_ioctl(file, ECS_IOCTL_APP_GET_DELAY, (unsigned long)arg64);
+               break;
+       default:
+               break;
+       }
+
+       return result;
+}
+#endif
+
 \r
 /* ioctl - I/O control */\r
 static long compass_dev_ioctl(struct file *file,\r
@@ -940,7 +1024,6 @@ static long gyro_dev_ioctl(struct file *file,
                                }       \r
                                else\r
                                {\r
-                                       PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                        schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                }\r
                                sensor->status_cur = SENSOR_ON;\r
@@ -969,6 +1052,7 @@ static long gyro_dev_ioctl(struct file *file,
                result = sensor->status_cur;\r
                if (copy_to_user(argp, &result, sizeof(result)))\r
                {\r
+                       mutex_unlock(&sensor->operation_mutex);\r
                        printk("%s:failed to copy sense data to user space.\n",__FUNCTION__);\r
                        return -EFAULT;\r
                }\r
@@ -977,9 +1061,9 @@ static long gyro_dev_ioctl(struct file *file,
                DBG("%s:L3G4200D_IOCTL_SET_ENABLE OK\n", __func__);\r
                break;\r
        case L3G4200D_IOCTL_SET_DELAY:                                  \r
-               mutex_lock(&sensor->operation_mutex);\r
                if (copy_from_user(&rate, argp, sizeof(rate)))\r
                return -EFAULT;\r
+               mutex_lock(&sensor->operation_mutex);\r
                if(sensor->status_cur == SENSOR_OFF)\r
                {\r
                        if ( (result = sensor->ops->active(client, 1, rate) ) < 0 ) {\r
@@ -995,7 +1079,6 @@ static long gyro_dev_ioctl(struct file *file,
                        }       \r
                        else\r
                        {\r
-                               PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                        }\r
                        sensor->status_cur = SENSOR_ON;\r
@@ -1039,6 +1122,33 @@ static int light_dev_release(struct inode *inode, struct file *file)
        return result;\r
 }\r
 \r
+#ifdef CONFIG_COMPAT
+static long light_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       long ret = 0;
+       void __user *arg64 = compat_ptr(arg);
+
+       if (!file->f_op || !file->f_op->unlocked_ioctl) {
+               pr_err("[DEBUG] file->f_op or file->f_op->unlocked_ioctl is null\n");
+               return -ENOTTY;
+       }
+
+       switch (cmd) {
+       case COMPAT_LIGHTSENSOR_IOCTL_GET_ENABLED:
+               if (file->f_op->unlocked_ioctl)
+                       ret = file->f_op->unlocked_ioctl(file, LIGHTSENSOR_IOCTL_GET_ENABLED, (unsigned long)arg64);
+               break;
+       case COMPAT_LIGHTSENSOR_IOCTL_ENABLE:
+               if (file->f_op->unlocked_ioctl)
+                       ret = file->f_op->unlocked_ioctl(file, LIGHTSENSOR_IOCTL_ENABLE, (unsigned long)arg64);
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+#endif
 \r
 /* ioctl - I/O control */\r
 static long light_dev_ioctl(struct file *file,\r
@@ -1076,7 +1186,6 @@ static long light_dev_ioctl(struct file *file,
                                        }       \r
                                        else\r
                                        {\r
-                                               PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                                schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                        }\r
                                        \r
@@ -1140,6 +1249,33 @@ static int proximity_dev_release(struct inode *inode, struct file *file)
        return result;\r
 }\r
 \r
+#ifdef CONFIG_COMPAT
+static long proximity_dev_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       long ret = 0;
+       void __user *arg64 = compat_ptr(arg);
+
+       if (!file->f_op || !file->f_op->unlocked_ioctl) {
+               pr_err("file->f_op or file->f_op->unlocked_ioctl is null\n");
+               return -ENOTTY;
+       }
+
+       switch (cmd) {
+       case COMPAT_PSENSOR_IOCTL_GET_ENABLED:
+               if (file->f_op->unlocked_ioctl)
+                       ret = file->f_op->unlocked_ioctl(file, PSENSOR_IOCTL_GET_ENABLED, (unsigned long)arg64);
+               break;
+       case COMPAT_PSENSOR_IOCTL_ENABLE:
+               if (file->f_op->unlocked_ioctl)
+                       ret = file->f_op->unlocked_ioctl(file, PSENSOR_IOCTL_ENABLE, (unsigned long)arg64);
+               break;
+       default:
+               break;
+       }
+
+       return ret;
+}
+#endif
 \r
 /* ioctl - I/O control */\r
 static long proximity_dev_ioctl(struct file *file,\r
@@ -1177,7 +1313,6 @@ static long proximity_dev_ioctl(struct file *file,
                                        }       \r
                                        else\r
                                        {\r
-                                               PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                                schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                        }\r
                                        \r
@@ -1277,7 +1412,6 @@ static long temperature_dev_ioctl(struct file *file,
                                        }       \r
                                        else\r
                                        {\r
-                                               PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                                schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                        }\r
                                        \r
@@ -1380,7 +1514,6 @@ static long pressure_dev_ioctl(struct file *file,
                                        }       \r
                                        else\r
                                        {\r
-                                               PREPARE_DELAYED_WORK(&sensor->delaywork, sensor_delaywork_func);\r
                                                schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
                                        }\r
                                        \r
@@ -1479,6 +1612,9 @@ static int sensor_misc_device_register(struct sensor_private_data *sensor, int t
                        {\r
                                sensor->fops.owner = THIS_MODULE;\r
                                sensor->fops.unlocked_ioctl = compass_dev_ioctl;\r
+#ifdef CONFIG_COMPAT
+                               sensor->fops.compat_ioctl = compass_dev_compat_ioctl;
+#endif
                                sensor->fops.open = compass_dev_open;\r
                                sensor->fops.release = compass_dev_release;\r
 \r
@@ -1519,6 +1655,9 @@ static int sensor_misc_device_register(struct sensor_private_data *sensor, int t
                        {\r
                                sensor->fops.owner = THIS_MODULE;\r
                                sensor->fops.unlocked_ioctl = light_dev_ioctl;\r
+#ifdef CONFIG_COMPAT
+                               sensor->fops.compat_ioctl = light_dev_compat_ioctl;
+#endif
                                sensor->fops.open = light_dev_open;\r
                                sensor->fops.release = light_dev_release;\r
 \r
@@ -1538,6 +1677,9 @@ static int sensor_misc_device_register(struct sensor_private_data *sensor, int t
                        {\r
                                sensor->fops.owner = THIS_MODULE;\r
                                sensor->fops.unlocked_ioctl = proximity_dev_ioctl;\r
+#ifdef CONFIG_COMPAT
+                               sensor->fops.compat_ioctl = proximity_dev_compat_ioctl;
+#endif
                                sensor->fops.open = proximity_dev_open;\r
                                sensor->fops.release = proximity_dev_release;\r
 \r
@@ -1697,7 +1839,9 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
 \r
        of_property_read_u8(np,"address",&(pdata->address));\r
        of_get_property(np, "project_name", pdata->project_name);\r
-\r
+
+       of_property_read_u32(np, "power-off-in-suspend",
+                            &pdata->power_off_in_suspend);
 \r
        switch(pdata->layout)\r
        {\r
@@ -1898,11 +2042,11 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
        if(result < 0)\r
                goto out_free_memory;\r
        \r
-       sensor->input_dev = input_allocate_device();\r
+       sensor->input_dev = devm_input_allocate_device(&client->dev);\r
        if (!sensor->input_dev) {\r
                result = -ENOMEM;\r
                dev_err(&client->dev,\r
-                       "Failed to allocate input device %s\n", sensor->input_dev->name);\r
+                       "Failed to allocate input device\n");\r
                goto out_free_memory;\r
        }       \r
 \r
@@ -2046,11 +2190,8 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
        return result;\r
        \r
 out_misc_device_register_device_failed:\r
-       input_unregister_device(sensor->input_dev);     \r
 out_input_register_device_failed:\r
-       input_free_device(sensor->input_dev);   \r
 out_free_memory:\r
-       //kfree(sensor);\r
 out_no_free:\r
        dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, result);\r
        return result;\r
@@ -2076,9 +2217,6 @@ static int sensor_remove(struct i2c_client *client)
        \r
        cancel_delayed_work_sync(&sensor->delaywork);\r
        misc_deregister(&sensor->miscdev);\r
-       input_unregister_device(sensor->input_dev);     \r
-       input_free_device(sensor->input_dev);   \r
-       kfree(sensor);\r
 #ifdef CONFIG_HAS_EARLYSUSPEND\r
        if((sensor->ops->suspend) && (sensor->ops->resume))\r
                unregister_early_suspend(&sensor->early_suspend);\r
@@ -2103,6 +2241,7 @@ static const struct i2c_device_id sensor_id[] = {
        {"gs_mc3230",ACCEL_ID_MC3230},\r
        {"mpu6880_acc",ACCEL_ID_MPU6880},\r
        {"mpu6500_acc",ACCEL_ID_MPU6500},\r
+       {"lsm330_acc", ACCEL_ID_LSM330},
        /*compass*/\r
        {"compass", COMPASS_ID_ALL},\r
        {"ak8975", COMPASS_ID_AK8975},  \r
@@ -2116,6 +2255,7 @@ static const struct i2c_device_id sensor_id[] = {
        {"ewtsa_gyro", GYRO_ID_EWTSA},\r
        {"k3g", GYRO_ID_K3G},\r
        {"mpu6880_gyro",GYRO_ID_MPU6880},\r
+       {"lsm330_gyro", GYRO_ID_LSM330},
        /*light sensor*/\r
        {"lightsensor", LIGHT_ID_ALL},  \r
        {"light_cm3217", LIGHT_ID_CM3217},\r
@@ -2152,7 +2292,7 @@ static struct of_device_id sensor_dt_ids[] = {
        { .compatible = "gs_mma7660" },\r
        { .compatible = "gs_mxc6225" },\r
        { .compatible = "gs_mc3230" },\r
-       \r
+       { .compatible = "lsm330_acc" },
        /*compass*/\r
        { .compatible = "ak8975" },\r
        { .compatible = "ak8963" },\r
@@ -2164,7 +2304,7 @@ static struct of_device_id sensor_dt_ids[] = {
        { .compatible = "l3g20d_gyro" },\r
        { .compatible = "ewtsa_gyro" },\r
        { .compatible = "k3g" },\r
-       \r
+       { .compatible = "lsm330_gyro" },
        \r
        /*light sensor*/\r
        { .compatible = "light_cm3217" },\r
@@ -2193,10 +2333,11 @@ static struct i2c_driver sensor_driver = {
        .remove = sensor_remove,\r
        .shutdown = sensor_shut_down,\r
        .id_table = sensor_id,\r
-       .driver = {\r
-                  .owner = THIS_MODULE,\r
-                  .name = "sensors",\r
-                  .of_match_table = of_match_ptr(sensor_dt_ids),\r
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "sensors",
+               .of_match_table = of_match_ptr(sensor_dt_ids),
+               .pm = SENSOR_PM_OPS,
        },\r
 };\r
 \r