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

Commit af6e1d99 authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: adxl34 - make enable/disable separate from suspend/resume



Suspending and resuming the device should be separate from enabling
and disabling it through sysfs attribute and thus should not alter
ac->disabled flag.

[michael.hennerich@analog.com: various fixups]
Tested-by: default avatarMichael Hennerich <michael.hennerich@analog.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 963ce8ae
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -58,14 +58,14 @@ static int adxl34x_i2c_read_block(struct device *dev,
	return 0;
}

static const struct adxl34x_bus_ops adx134x_smbus_bops = {
static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
	.bustype	= BUS_I2C,
	.write		= adxl34x_smbus_write,
	.read		= adxl34x_smbus_read,
	.read_block	= adxl34x_smbus_read_block,
};

static const struct adxl34x_bus_ops adx134x_i2c_bops = {
static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
	.bustype	= BUS_I2C,
	.write		= adxl34x_smbus_write,
	.read		= adxl34x_smbus_read,
@@ -88,7 +88,7 @@ static int __devinit adxl34x_i2c_probe(struct i2c_client *client,
	ac = adxl34x_probe(&client->dev, client->irq, false,
			   i2c_check_functionality(client->adapter,
						   I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
				&adx134x_smbus_bops : &adx134x_i2c_bops);
				&adxl34x_smbus_bops : &adxl34x_i2c_bops);
	if (IS_ERR(ac))
		return PTR_ERR(ac);

@@ -105,26 +105,26 @@ static int __devexit adxl34x_i2c_remove(struct i2c_client *client)
}

#ifdef CONFIG_PM
static int adxl34x_suspend(struct i2c_client *client, pm_message_t message)
static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message)
{
	struct adxl34x *ac = i2c_get_clientdata(client);

	adxl34x_disable(ac);
	adxl34x_suspend(ac);

	return 0;
}

static int adxl34x_resume(struct i2c_client *client)
static int adxl34x_i2c_resume(struct i2c_client *client)
{
	struct adxl34x *ac = i2c_get_clientdata(client);

	adxl34x_enable(ac);
	adxl34x_resume(ac);

	return 0;
}
#else
# define adxl34x_suspend NULL
# define adxl34x_resume  NULL
# define adxl34x_i2c_suspend NULL
# define adxl34x_i2c_resume  NULL
#endif

static const struct i2c_device_id adxl34x_id[] = {
@@ -141,8 +141,8 @@ static struct i2c_driver adxl34x_driver = {
	},
	.probe    = adxl34x_i2c_probe,
	.remove   = __devexit_p(adxl34x_i2c_remove),
	.suspend  = adxl34x_suspend,
	.resume   = adxl34x_resume,
	.suspend  = adxl34x_i2c_suspend,
	.resume   = adxl34x_i2c_resume,
	.id_table = adxl34x_id,
};

+8 −8
Original line number Diff line number Diff line
@@ -94,26 +94,26 @@ static int __devexit adxl34x_spi_remove(struct spi_device *spi)
}

#ifdef CONFIG_PM
static int adxl34x_suspend(struct spi_device *spi, pm_message_t message)
static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message)
{
	struct adxl34x *ac = dev_get_drvdata(&spi->dev);

	adxl34x_disable(ac);
	adxl34x_suspend(ac);

	return 0;
}

static int adxl34x_resume(struct spi_device *spi)
static int adxl34x_spi_resume(struct spi_device *spi)
{
	struct adxl34x *ac = dev_get_drvdata(&spi->dev);

	adxl34x_enable(ac);
	adxl34x_resume(ac);

	return 0;
}
#else
# define adxl34x_suspend NULL
# define adxl34x_resume  NULL
# define adxl34x_spi_suspend NULL
# define adxl34x_spi_resume  NULL
#endif

static struct spi_driver adxl34x_driver = {
@@ -124,8 +124,8 @@ static struct spi_driver adxl34x_driver = {
	},
	.probe   = adxl34x_spi_probe,
	.remove  = __devexit_p(adxl34x_spi_remove),
	.suspend = adxl34x_suspend,
	.resume  = adxl34x_resume,
	.suspend = adxl34x_spi_suspend,
	.resume  = adxl34x_spi_resume,
};

static int __init adxl34x_spi_init(void)
+49 −27
Original line number Diff line number Diff line
@@ -200,6 +200,7 @@ struct adxl34x {
	unsigned orient3d_saved;
	bool disabled;	/* P: mutex */
	bool opened;	/* P: mutex */
	bool suspended;	/* P: mutex */
	bool fifo_delay;
	int irq;
	unsigned model;
@@ -399,41 +400,44 @@ static irqreturn_t adxl34x_irq(int irq, void *handle)

static void __adxl34x_disable(struct adxl34x *ac)
{
	if (!ac->disabled && ac->opened) {
	/*
	 * A '0' places the ADXL34x into standby mode
	 * with minimum power consumption.
	 */
	AC_WRITE(ac, POWER_CTL, 0);

		ac->disabled = true;
	}
}

static void __adxl34x_enable(struct adxl34x *ac)
{
	if (ac->disabled && ac->opened) {
	AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
		ac->disabled = false;
	}
}

void adxl34x_disable(struct adxl34x *ac)
void adxl34x_suspend(struct adxl34x *ac)
{
	mutex_lock(&ac->mutex);

	if (!ac->suspended && !ac->disabled && ac->opened)
		__adxl34x_disable(ac);

	ac->suspended = true;

	mutex_unlock(&ac->mutex);
}
EXPORT_SYMBOL_GPL(adxl34x_disable);
EXPORT_SYMBOL_GPL(adxl34x_suspend);

void adxl34x_enable(struct adxl34x *ac)
void adxl34x_resume(struct adxl34x *ac)
{
	mutex_lock(&ac->mutex);

	if (ac->suspended && !ac->disabled && ac->opened)
		__adxl34x_enable(ac);

	ac->suspended= false;

	mutex_unlock(&ac->mutex);
}

EXPORT_SYMBOL_GPL(adxl34x_enable);
EXPORT_SYMBOL_GPL(adxl34x_resume);

static ssize_t adxl34x_disable_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
@@ -455,10 +459,21 @@ static ssize_t adxl34x_disable_store(struct device *dev,
	if (error)
		return error;

	if (val)
		adxl34x_disable(ac);
	else
		adxl34x_enable(ac);
	mutex_lock(&ac->mutex);

	if (!ac->suspended && ac->opened) {
		if (val) {
			if (!ac->disabled)
				__adxl34x_disable(ac);
		} else {
			if (ac->disabled)
				__adxl34x_enable(ac);
		}
	}

	ac->disabled = !!val;

	mutex_unlock(&ac->mutex);

	return count;
}
@@ -575,7 +590,7 @@ static ssize_t adxl34x_autosleep_store(struct device *dev,
	else
		ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK);

	if (!ac->disabled && ac->opened)
	if (!ac->disabled && !ac->suspended && ac->opened)
		AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);

	mutex_unlock(&ac->mutex);
@@ -649,8 +664,12 @@ static int adxl34x_input_open(struct input_dev *input)
	struct adxl34x *ac = input_get_drvdata(input);

	mutex_lock(&ac->mutex);
	ac->opened = true;

	if (!ac->suspended && !ac->disabled)
		__adxl34x_enable(ac);

	ac->opened = true;

	mutex_unlock(&ac->mutex);

	return 0;
@@ -661,8 +680,12 @@ static void adxl34x_input_close(struct input_dev *input)
	struct adxl34x *ac = input_get_drvdata(input);

	mutex_lock(&ac->mutex);

	if (!ac->suspended && !ac->disabled)
		__adxl34x_disable(ac);

	ac->opened = false;

	mutex_unlock(&ac->mutex);
}

@@ -878,7 +901,6 @@ EXPORT_SYMBOL_GPL(adxl34x_probe);

int adxl34x_remove(struct adxl34x *ac)
{
	adxl34x_disable(ac);
	sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
	free_irq(ac->irq, ac);
	input_unregister_device(ac->input);
+2 −2
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@ struct adxl34x_bus_ops {
	int (*write)(struct device *, unsigned char, unsigned char);
};

void adxl34x_disable(struct adxl34x *ac);
void adxl34x_enable(struct adxl34x *ac);
void adxl34x_suspend(struct adxl34x *ac);
void adxl34x_resume(struct adxl34x *ac);
struct adxl34x *adxl34x_probe(struct device *dev, int irq,
			      bool fifo_delay_default,
			      const struct adxl34x_bus_ops *bops);