Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3df63a6 authored by Bingzhe Cai's avatar Bingzhe Cai Committed by Gerrit - the friendly Code Review server
Browse files

input: sensors: create dedicate workqueue for sensors



Default system workqueue may be bounded on specific cpu, that cpu
will always be wakeup to handle the workqueue, this will consume
extra power in some case. This change fix issue by create dedicate
sensor workqueue which not bounded to any cpu.

Change-Id: I38f64def943625cc525b56e863a4ef5384bc10ac
Signed-off-by: default avatarBingzhe Cai <bingzhec@codeaurora.org>
parent b7e153cb
Loading
Loading
Loading
Loading
+30 −10
Original line number Original line Diff line number Diff line
/* drivers/input/misc/akm8963.c - akm8963 compass driver
/* drivers/input/misc/akm8963.c - akm8963 compass driver
 *
 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
 *
 *
 * Copyright (C) 2007-2008 HTC Corporation.
 * Copyright (C) 2007-2008 HTC Corporation.
 * Author: Hou-Kun Chen <houkun.chen@gmail.com>
 * Author: Hou-Kun Chen <houkun.chen@gmail.com>
@@ -66,6 +68,7 @@ struct akm_compass_data {
	struct pinctrl_state	*pin_default;
	struct pinctrl_state	*pin_default;
	struct pinctrl_state	*pin_sleep;
	struct pinctrl_state	*pin_sleep;
	struct sensors_classdev	cdev;
	struct sensors_classdev	cdev;
	struct workqueue_struct	*data_wq;
	struct delayed_work	dwork;
	struct delayed_work	dwork;
	struct mutex		op_mutex;
	struct mutex		op_mutex;


@@ -872,9 +875,10 @@ static int akm_enable_set(struct sensors_classdev *sensors_cdev,
		if (enable) {
		if (enable) {
			AKECS_SetMode(akm,
			AKECS_SetMode(akm,
				AKM_MODE_SNG_MEASURE | AKM8963_BIT_OP_16);
				AKM_MODE_SNG_MEASURE | AKM8963_BIT_OP_16);
			schedule_delayed_work(&akm->dwork,
			queue_delayed_work(akm->data_wq,
					msecs_to_jiffies(
					&akm->dwork,
						akm->delay[MAG_DATA_FLAG]));
					msecs_to_jiffies
					(akm->delay[MAG_DATA_FLAG]));
		} else {
		} else {
			cancel_delayed_work_sync(&akm->dwork);
			cancel_delayed_work_sync(&akm->dwork);
			AKECS_SetMode(akm, AKM_MODE_POWERDOWN);
			AKECS_SetMode(akm, AKM_MODE_POWERDOWN);
@@ -1486,7 +1490,8 @@ static int akm_compass_resume(struct device *dev)
		if (AKM_IS_MAG_DATA_ENABLED() &&
		if (AKM_IS_MAG_DATA_ENABLED() &&
			akm->use_poll &&
			akm->use_poll &&
			akm->pdata->auto_report)
			akm->pdata->auto_report)
			schedule_delayed_work(&akm->dwork,
			queue_delayed_work(akm->data_wq,
				&akm->dwork,
				(unsigned long)nsecs_to_jiffies64(
				(unsigned long)nsecs_to_jiffies64(
				akm->delay[MAG_DATA_FLAG]));
				akm->delay[MAG_DATA_FLAG]));
	}
	}
@@ -1826,7 +1831,8 @@ exit:
		dev_warn(&akm->i2c->dev, "Failed to set mode\n");
		dev_warn(&akm->i2c->dev, "Failed to set mode\n");


	if (akm->use_poll)
	if (akm->use_poll)
		schedule_delayed_work(&akm->dwork,
		queue_delayed_work(akm->data_wq,
				&akm->dwork,
				msecs_to_jiffies(akm->delay[MAG_DATA_FLAG]));
				msecs_to_jiffies(akm->delay[MAG_DATA_FLAG]));
}
}


@@ -1949,10 +1955,11 @@ int akm8963_compass_probe(
		err = pinctrl_select_state(s_akm->pinctrl, s_akm->pin_default);
		err = pinctrl_select_state(s_akm->pinctrl, s_akm->pin_default);
		if (err) {
		if (err) {
			dev_err(&i2c->dev, "Can't select pinctrl state\n");
			dev_err(&i2c->dev, "Can't select pinctrl state\n");
			goto err_compass_pwr_off;
			goto err_unregister_device;
		}
		}
	}
	}


	s_akm->data_wq = NULL;
	if ((s_akm->pdata->use_int) &&
	if ((s_akm->pdata->use_int) &&
		gpio_is_valid(s_akm->pdata->gpio_int)) {
		gpio_is_valid(s_akm->pdata->gpio_int)) {
		s_akm->use_poll = false;
		s_akm->use_poll = false;
@@ -1998,6 +2005,12 @@ int akm8963_compass_probe(
		}
		}
	} else if (s_akm->pdata->auto_report) {
	} else if (s_akm->pdata->auto_report) {
		s_akm->use_poll = true;
		s_akm->use_poll = true;
		s_akm->data_wq =
			create_freezable_workqueue("akm8963_data_work");
		if (!s_akm->data_wq) {
			dev_err(&i2c->dev, "Cannot create workqueue!\n");
			goto err_unregister_device;
		}
		INIT_DELAYED_WORK(&s_akm->dwork, akm_dev_poll);
		INIT_DELAYED_WORK(&s_akm->dwork, akm_dev_poll);
	}
	}


@@ -2006,7 +2019,7 @@ int akm8963_compass_probe(
	if (0 > err) {
	if (0 > err) {
		dev_err(&i2c->dev,
		dev_err(&i2c->dev,
				"%s: create sysfs failed.", __func__);
				"%s: create sysfs failed.", __func__);
		goto err_free_irq;
		goto err_destroy_workqueue;
	}
	}


	s_akm->cdev = sensors_cdev;
	s_akm->cdev = sensors_cdev;
@@ -2031,15 +2044,17 @@ int akm8963_compass_probe(


remove_sysfs:
remove_sysfs:
	remove_sysfs_interfaces(s_akm);
	remove_sysfs_interfaces(s_akm);
err_free_irq:
err_destroy_workqueue:
	if (s_akm->data_wq)
		destroy_workqueue(s_akm->data_wq);
	if (s_akm->i2c->irq)
	if (s_akm->i2c->irq)
		free_irq(s_akm->i2c->irq, s_akm);
		free_irq(s_akm->i2c->irq, s_akm);
err_unregister_device:
	input_unregister_device(s_akm->input);
err_gpio_free:
err_gpio_free:
	if ((s_akm->pdata->use_int) &&
	if ((s_akm->pdata->use_int) &&
		(gpio_is_valid(s_akm->pdata->gpio_int)))
		(gpio_is_valid(s_akm->pdata->gpio_int)))
		gpio_free(s_akm->pdata->gpio_int);
		gpio_free(s_akm->pdata->gpio_int);
err_unregister_device:
	input_unregister_device(s_akm->input);
err_compass_pwr_off:
err_compass_pwr_off:
	akm_compass_power_set(s_akm, false);
	akm_compass_power_set(s_akm, false);
err_compass_pwr_init:
err_compass_pwr_init:
@@ -2059,8 +2074,13 @@ static int akm8963_compass_remove(struct i2c_client *i2c)
	if (akm_compass_power_init(akm, false))
	if (akm_compass_power_init(akm, false))
		dev_err(&i2c->dev, "power deinit failed.\n");
		dev_err(&i2c->dev, "power deinit failed.\n");
	remove_sysfs_interfaces(akm);
	remove_sysfs_interfaces(akm);
	if (akm->data_wq)
		destroy_workqueue(s_akm->data_wq);
	if (akm->i2c->irq)
	if (akm->i2c->irq)
		free_irq(akm->i2c->irq, akm);
		free_irq(akm->i2c->irq, akm);
	if ((s_akm->pdata->use_int) &&
		(gpio_is_valid(s_akm->pdata->gpio_int)))
		gpio_free(s_akm->pdata->gpio_int);
	input_unregister_device(akm->input);
	input_unregister_device(akm->input);
	devm_kfree(&i2c->dev, akm);
	devm_kfree(&i2c->dev, akm);
	dev_info(&i2c->dev, "successfully removed.");
	dev_info(&i2c->dev, "successfully removed.");
+17 −5
Original line number Original line Diff line number Diff line
@@ -1472,6 +1472,7 @@ struct bma2x2_data {
	struct mutex value_mutex;
	struct mutex value_mutex;
	struct mutex enable_mutex;
	struct mutex enable_mutex;
	struct mutex mode_mutex;
	struct mutex mode_mutex;
	struct workqueue_struct *data_wq;
	struct delayed_work work;
	struct delayed_work work;
	struct work_struct irq_work;
	struct work_struct irq_work;
	struct regulator *vdd;
	struct regulator *vdd;
@@ -4909,7 +4910,7 @@ static void bma2x2_work_func(struct work_struct *work)
	mutex_lock(&bma2x2->value_mutex);
	mutex_lock(&bma2x2->value_mutex);
	bma2x2->value = acc;
	bma2x2->value = acc;
	mutex_unlock(&bma2x2->value_mutex);
	mutex_unlock(&bma2x2->value_mutex);
	schedule_delayed_work(&bma2x2->work, delay);
	queue_delayed_work(bma2x2->data_wq, &bma2x2->work, delay);
}
}
#endif
#endif


@@ -5165,7 +5166,8 @@ static void bma2x2_set_enable(struct device *dev, int enable)
			bma2x2_set_mode(bma2x2->bma2x2_client,
			bma2x2_set_mode(bma2x2->bma2x2_client,
					BMA2X2_MODE_NORMAL);
					BMA2X2_MODE_NORMAL);
#ifndef CONFIG_BMA_ENABLE_NEWDATA_INT
#ifndef CONFIG_BMA_ENABLE_NEWDATA_INT
			schedule_delayed_work(&bma2x2->work,
			queue_delayed_work(bma2x2->data_wq,
				&bma2x2->work,
				msecs_to_jiffies(atomic_read(&bma2x2->delay)));
				msecs_to_jiffies(atomic_read(&bma2x2->delay)));
#endif
#endif
			atomic_set(&bma2x2->enable, 1);
			atomic_set(&bma2x2->enable, 1);
@@ -7249,6 +7251,12 @@ static int bma2x2_probe(struct i2c_client *client,
#ifndef CONFIG_BMA_ENABLE_NEWDATA_INT
#ifndef CONFIG_BMA_ENABLE_NEWDATA_INT
	INIT_DELAYED_WORK(&data->work, bma2x2_work_func);
	INIT_DELAYED_WORK(&data->work, bma2x2_work_func);
#endif
#endif
	data->data_wq = create_freezable_workqueue("bma2x2_data_work");
	if (!data->data_wq) {
		dev_err(&client->dev, "Cannot get create workqueue!\n");
		goto free_irq_exit;
	}

	atomic_set(&data->delay, POLL_DEFAULT_INTERVAL_MS);
	atomic_set(&data->delay, POLL_DEFAULT_INTERVAL_MS);
	atomic_set(&data->enable, 0);
	atomic_set(&data->enable, 0);


@@ -7257,7 +7265,7 @@ static int bma2x2_probe(struct i2c_client *client,
		dev_err(&client->dev,
		dev_err(&client->dev,
			"Cannot allocate input device\n");
			"Cannot allocate input device\n");
		err = -ENOMEM;
		err = -ENOMEM;
		goto free_irq_exit;
		goto destroy_workqueue_exit;
	}
	}


	dev_interrupt = devm_input_allocate_device(&client->dev);
	dev_interrupt = devm_input_allocate_device(&client->dev);
@@ -7265,7 +7273,7 @@ static int bma2x2_probe(struct i2c_client *client,
		dev_err(&client->dev,
		dev_err(&client->dev,
			"Cannot allocate input interrupt device\n");
			"Cannot allocate input interrupt device\n");
		err = -ENOMEM;
		err = -ENOMEM;
		goto free_irq_exit;
		goto destroy_workqueue_exit;
	}
	}


	/* only value events reported */
	/* only value events reported */
@@ -7486,6 +7494,8 @@ destroy_g_sensor_class_exit:
	class_destroy(data->g_sensor_class);
	class_destroy(data->g_sensor_class);
#endif
#endif


destroy_workqueue_exit:
	destroy_workqueue(data->data_wq);
free_irq_exit:
free_irq_exit:
disable_power_exit:
disable_power_exit:
	bma2x2_power_ctl(data, false);
	bma2x2_power_ctl(data, false);
@@ -7528,7 +7538,8 @@ static void bma2x2_late_resume(struct early_suspend *h)
	if (atomic_read(&data->enable) == 1) {
	if (atomic_read(&data->enable) == 1) {
		bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_NORMAL);
		bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_NORMAL);
#ifndef CONFIG_BMA_ENABLE_NEWDATA_INT
#ifndef CONFIG_BMA_ENABLE_NEWDATA_INT
		schedule_delayed_work(&data->work,
		queue_delayed_work(data->data_wq,
				&data->work,
				msecs_to_jiffies(atomic_read(&data->delay)));
				msecs_to_jiffies(atomic_read(&data->delay)));
#endif
#endif
	}
	}
@@ -7558,6 +7569,7 @@ static int bma2x2_remove(struct i2c_client *client)
		sysfs_remove_group(&data->input->dev.kobj,
		sysfs_remove_group(&data->input->dev.kobj,
				&bma2x2_attribute_group);
				&bma2x2_attribute_group);


	destroy_workqueue(data->data_wq);
	bma2x2_set_enable(&client->dev, 0);
	bma2x2_set_enable(&client->dev, 0);
	bma2x2_power_deinit(data);
	bma2x2_power_deinit(data);
	i2c_set_clientdata(client, NULL);
	i2c_set_clientdata(client, NULL);
+21 −7
Original line number Original line Diff line number Diff line
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
 *
 *
 * Copyright (c) 2014, The Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
 *
 *
 * File Name          : lis3dh_acc.c
 * File Name          : lis3dh_acc.c
 * Authors            : MSH - Motion Mems BU - Application Team
 * Authors            : MSH - Motion Mems BU - Application Team
@@ -263,6 +263,7 @@ struct lis3dh_acc_data {
	struct pinctrl_state *pin_sleep;
	struct pinctrl_state *pin_sleep;


	struct mutex lock;
	struct mutex lock;
	struct workqueue_struct *data_wq;
	struct delayed_work input_work;
	struct delayed_work input_work;


	struct input_dev *input_dev;
	struct input_dev *input_dev;
@@ -1135,7 +1136,7 @@ static int lis3dh_acc_enable(struct lis3dh_acc_data *acc)
			return err;
			return err;
		}
		}
		if (!acc->pdata->enable_int && !acc->use_batch) {
		if (!acc->pdata->enable_int && !acc->use_batch) {
			schedule_delayed_work(&acc->input_work,
			queue_delayed_work(acc->data_wq, &acc->input_work,
				msecs_to_jiffies(acc->delay_ms));
				msecs_to_jiffies(acc->delay_ms));
			return 0;
			return 0;
		}
		}
@@ -1768,8 +1769,8 @@ static void lis3dh_acc_input_work_func(struct work_struct *work)
	else
	else
		lis3dh_acc_report_values(acc, xyz);
		lis3dh_acc_report_values(acc, xyz);


	schedule_delayed_work(&acc->input_work, msecs_to_jiffies(
	queue_delayed_work(acc->data_wq, &acc->input_work,
			acc->delay_ms));
		msecs_to_jiffies(acc->delay_ms));
	mutex_unlock(&acc->lock);
	mutex_unlock(&acc->lock);
}
}


@@ -1825,8 +1826,6 @@ static int lis3dh_acc_input_init(struct lis3dh_acc_data *acc)
{
{
	int err;
	int err;


	if (!acc->pdata->enable_int)
		INIT_DELAYED_WORK(&acc->input_work, lis3dh_acc_input_work_func);
	acc->input_dev = devm_input_allocate_device(&acc->client->dev);
	acc->input_dev = devm_input_allocate_device(&acc->client->dev);
	if (!acc->input_dev) {
	if (!acc->input_dev) {
		err = -ENOMEM;
		err = -ENOMEM;
@@ -2150,12 +2149,22 @@ static int lis3dh_acc_probe(struct i2c_client *client,
		goto err_power_off;
		goto err_power_off;
	}
	}


	acc->data_wq = NULL;
	if (!acc->pdata->enable_int) {
		acc->data_wq = create_freezable_workqueue("lis3dh_data_work");
		if (!acc->data_wq) {
			dev_err(&client->dev, "create workquque failed\n");
			goto err_power_off;
		}
		INIT_DELAYED_WORK(&acc->input_work,
			lis3dh_acc_input_work_func);
	}


	err = create_sysfs_interfaces(&client->dev);
	err = create_sysfs_interfaces(&client->dev);
	if (err < 0) {
	if (err < 0) {
		dev_err(&client->dev,
		dev_err(&client->dev,
		   "device LIS3DH_ACC_DEV_NAME sysfs register failed\n");
		   "device LIS3DH_ACC_DEV_NAME sysfs register failed\n");
		goto err_power_off;
		goto err_destroy_workqueue;
	}
	}


	acc->cdev = lis3dh_acc_cdev;
	acc->cdev = lis3dh_acc_cdev;
@@ -2226,6 +2235,9 @@ err_unreg_sensor_class:
	sensors_classdev_unregister(&acc->cdev);
	sensors_classdev_unregister(&acc->cdev);
err_remove_sysfs_int:
err_remove_sysfs_int:
	remove_sysfs_interfaces(&client->dev);
	remove_sysfs_interfaces(&client->dev);
err_destroy_workqueue:
	if (acc->data_wq)
		destroy_workqueue(acc->data_wq);
err_power_off:
err_power_off:
	lis3dh_acc_device_power_off(acc);
	lis3dh_acc_device_power_off(acc);
err_regulator_init:
err_regulator_init:
@@ -2257,6 +2269,8 @@ static int lis3dh_acc_remove(struct i2c_client *client)
	sensors_classdev_unregister(&acc->cdev);
	sensors_classdev_unregister(&acc->cdev);
	lis3dh_acc_config_regulator(acc, false);
	lis3dh_acc_config_regulator(acc, false);
	remove_sysfs_interfaces(&client->dev);
	remove_sysfs_interfaces(&client->dev);
	if (acc->data_wq)
		destroy_workqueue(acc->data_wq);


	if (acc->pdata->exit)
	if (acc->pdata->exit)
		acc->pdata->exit();
		acc->pdata->exit();
+20 −5
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
 *  mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
 *  mma8x5x.c - Linux kernel modules for 3-Axis Orientation/Motion
 *  Detection Sensor MMA8451/MMA8452/MMA8453
 *  Detection Sensor MMA8451/MMA8452/MMA8453
 *
 *
 *  Copyright (c) 2013-2014, The Linux Foundation. All Rights Reserved.
 *  Copyright (c) 2013-2015, The Linux Foundation. All Rights Reserved.
 *  Linux Foundation chooses to take subject only to the GPLv2 license
 *  Linux Foundation chooses to take subject only to the GPLv2 license
 *  terms, and distributes only under these terms.
 *  terms, and distributes only under these terms.
 *  Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
 *  Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
@@ -189,6 +189,7 @@ struct mma8x5x_data_axis {
};
};
struct mma8x5x_data {
struct mma8x5x_data {
	struct i2c_client *client;
	struct i2c_client *client;
	struct workqueue_struct *data_wq;
	struct delayed_work dwork;
	struct delayed_work dwork;
	struct input_dev *idev;
	struct input_dev *idev;
	struct mutex data_lock;
	struct mutex data_lock;
@@ -512,7 +513,8 @@ static void mma8x5x_dev_poll(struct work_struct *work)


	if ((pdata->active & MMA_STATE_MASK) == MMA_ACTIVED) {
	if ((pdata->active & MMA_STATE_MASK) == MMA_ACTIVED) {
		mma8x5x_report_data(pdata);
		mma8x5x_report_data(pdata);
		schedule_delayed_work(&pdata->dwork,
		queue_delayed_work(pdata->data_wq,
				&pdata->dwork,
				msecs_to_jiffies(pdata->poll_delay));
				msecs_to_jiffies(pdata->poll_delay));
	}
	}
}
}
@@ -580,7 +582,8 @@ static int mma8x5x_enable_set(struct sensors_classdev *sensors_cdev,
				goto err_failed;
				goto err_failed;
			}
			}
			if (!pdata->use_int)
			if (!pdata->use_int)
				schedule_delayed_work(&pdata->dwork,
				queue_delayed_work(pdata->data_wq,
					&pdata->dwork,
					msecs_to_jiffies(pdata->poll_delay));
					msecs_to_jiffies(pdata->poll_delay));


			pdata->active = MMA_ACTIVED;
			pdata->active = MMA_ACTIVED;
@@ -883,6 +886,7 @@ static int mma8x5x_probe(struct i2c_client *client,
	i2c_set_clientdata(client, pdata);
	i2c_set_clientdata(client, pdata);
	/* Initialize the MMA8X5X chip */
	/* Initialize the MMA8X5X chip */
	mma8x5x_device_init(client);
	mma8x5x_device_init(client);
	pdata->data_wq = NULL;
	if (pdata->use_int) {
	if (pdata->use_int) {
		if (pdata->int_pin >= 0)
		if (pdata->int_pin >= 0)
			client->irq = gpio_to_irq(pdata->int_pin);
			client->irq = gpio_to_irq(pdata->int_pin);
@@ -916,6 +920,11 @@ static int mma8x5x_probe(struct i2c_client *client,
		mma8x5x_device_int_init(client);
		mma8x5x_device_int_init(client);
	} else {
	} else {
		INIT_DELAYED_WORK(&pdata->dwork, mma8x5x_dev_poll);
		INIT_DELAYED_WORK(&pdata->dwork, mma8x5x_dev_poll);
		pdata->data_wq = create_freezable_workqueue("mma_data_work");
		if (!pdata->data_wq) {
			dev_err(&client->dev, "Create workqueue failed!\n");
			goto err_alloc_work_queue;
		}
	}
	}
	idev = devm_input_allocate_device(&client->dev);
	idev = devm_input_allocate_device(&client->dev);
	if (!idev) {
	if (!idev) {
@@ -963,9 +972,12 @@ static int mma8x5x_probe(struct i2c_client *client,
err_create_class_sysfs:
err_create_class_sysfs:
	sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group);
	sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group);
err_alloc_poll_device:
err_alloc_poll_device:
	if (pdata->data_wq)
		destroy_workqueue(pdata->data_wq);
err_register_irq:
err_register_irq:
	if (pdata->use_int)
	if (pdata->use_int)
		device_init_wakeup(&client->dev, false);
		device_init_wakeup(&client->dev, false);
err_alloc_work_queue:
err_set_gpio_direction:
err_set_gpio_direction:
	if (gpio_is_valid(pdata->int_pin) && pdata->use_int)
	if (gpio_is_valid(pdata->int_pin) && pdata->use_int)
		gpio_free(pdata->int_pin);
		gpio_free(pdata->int_pin);
@@ -986,6 +998,8 @@ static int mma8x5x_remove(struct i2c_client *client)
	if (pdata) {
	if (pdata) {
		idev = pdata->idev;
		idev = pdata->idev;
		sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group);
		sysfs_remove_group(&idev->dev.kobj, &mma8x5x_attr_group);
		if (pdata->data_wq)
			destroy_workqueue(pdata->data_wq);
		if (pdata->use_int) {
		if (pdata->use_int) {
			device_init_wakeup(&client->dev, false);
			device_init_wakeup(&client->dev, false);
			if (gpio_is_valid(pdata->int_pin))
			if (gpio_is_valid(pdata->int_pin))
@@ -1039,7 +1053,8 @@ static int mma8x5x_resume(struct device *dev)
	if (pdata->active == MMA_ACTIVED) {
	if (pdata->active == MMA_ACTIVED) {
		val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
		val = i2c_smbus_read_byte_data(client, MMA8X5X_CTRL_REG1);
		i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val|0x01);
		i2c_smbus_write_byte_data(client, MMA8X5X_CTRL_REG1, val|0x01);
		schedule_delayed_work(&pdata->dwork,
		queue_delayed_work(pdata->data_wq,
				&pdata->dwork,
				msecs_to_jiffies(pdata->poll_delay));
				msecs_to_jiffies(pdata->poll_delay));
	}
	}


+21 −5
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2014, Linux Foundation. All rights reserved.
 * Copyright (c) 2014-2015, Linux Foundation. All rights reserved.
 * Linux Foundation chooses to take subject only to the GPLv2 license
 * Linux Foundation chooses to take subject only to the GPLv2 license
 * terms, and distributes only under these terms.
 * terms, and distributes only under these terms.
 * Copyright (C) 2010 MEMSIC, Inc.
 * Copyright (C) 2010 MEMSIC, Inc.
@@ -102,6 +102,7 @@ struct mmc3416x_vec {
struct mmc3416x_data {
struct mmc3416x_data {
	struct mutex		ecompass_lock;
	struct mutex		ecompass_lock;
	struct mutex		ops_lock;
	struct mutex		ops_lock;
	struct workqueue_struct *data_wq;
	struct delayed_work	dwork;
	struct delayed_work	dwork;
	struct sensors_classdev	cdev;
	struct sensors_classdev	cdev;
	struct mmc3416x_vec	last;
	struct mmc3416x_vec	last;
@@ -276,7 +277,8 @@ static void mmc3416x_poll(struct work_struct *work)
	input_sync(memsic->idev);
	input_sync(memsic->idev);


exit:
exit:
	schedule_delayed_work(&memsic->dwork,
	queue_delayed_work(memsic->data_wq,
			&memsic->dwork,
			msecs_to_jiffies(memsic->poll_interval));
			msecs_to_jiffies(memsic->poll_interval));
}
}


@@ -554,7 +556,8 @@ static int mmc3416x_set_enable(struct sensors_classdev *sensors_cdev,


		memsic->timeout = jiffies;
		memsic->timeout = jiffies;
		if (memsic->auto_report)
		if (memsic->auto_report)
			schedule_delayed_work(&memsic->dwork,
			queue_delayed_work(memsic->data_wq,
				&memsic->dwork,
				msecs_to_jiffies(memsic->poll_interval));
				msecs_to_jiffies(memsic->poll_interval));
	} else if ((!enable) && memsic->enable) {
	} else if ((!enable) && memsic->enable) {
		if (memsic->auto_report)
		if (memsic->auto_report)
@@ -663,9 +666,16 @@ static int mmc3416x_probe(struct i2c_client *client, const struct i2c_device_id
		goto out_init_input;
		goto out_init_input;
	}
	}


	memsic->data_wq = NULL;
	if (memsic->auto_report) {
	if (memsic->auto_report) {
		dev_info(&client->dev, "auto report is enabled\n");
		dev_dbg(&client->dev, "auto report is enabled\n");
		INIT_DELAYED_WORK(&memsic->dwork, mmc3416x_poll);
		INIT_DELAYED_WORK(&memsic->dwork, mmc3416x_poll);
		memsic->data_wq =
			create_freezable_workqueue("mmc3416_data_work");
		if (!memsic->data_wq) {
			dev_err(&client->dev, "Cannot create workqueue.\n");
			goto out_create_workqueue;
		}
	}
	}


	memsic->cdev = sensors_cdev;
	memsic->cdev = sensors_cdev;
@@ -692,6 +702,9 @@ static int mmc3416x_probe(struct i2c_client *client, const struct i2c_device_id
out_power_set:
out_power_set:
	sensors_classdev_unregister(&memsic->cdev);
	sensors_classdev_unregister(&memsic->cdev);
out_register_classdev:
out_register_classdev:
	if (memsic->data_wq)
		destroy_workqueue(memsic->data_wq);
out_create_workqueue:
	input_unregister_device(memsic->idev);
	input_unregister_device(memsic->idev);
out_init_input:
out_init_input:
out_check_device:
out_check_device:
@@ -705,6 +718,8 @@ static int mmc3416x_remove(struct i2c_client *client)
	struct mmc3416x_data *memsic = dev_get_drvdata(&client->dev);
	struct mmc3416x_data *memsic = dev_get_drvdata(&client->dev);


	sensors_classdev_unregister(&memsic->cdev);
	sensors_classdev_unregister(&memsic->cdev);
	if (memsic->data_wq)
		destroy_workqueue(memsic->data_wq);
	mmc3416x_power_deinit(memsic);
	mmc3416x_power_deinit(memsic);


	if (memsic->idev)
	if (memsic->idev)
@@ -751,7 +766,8 @@ static int mmc3416x_resume(struct device *dev)
		}
		}


		if (memsic->auto_report)
		if (memsic->auto_report)
			schedule_delayed_work(&memsic->dwork,
			queue_delayed_work(memsic->data_wq,
				&memsic->dwork,
				msecs_to_jiffies(memsic->poll_interval));
				msecs_to_jiffies(memsic->poll_interval));
	}
	}


Loading