Skip to content

Commit

Permalink
Input: adxl34 - make enable/disable separate from suspend/resume
Browse files Browse the repository at this point in the history
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: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
  • Loading branch information
Dmitry Torokhov committed Jul 3, 2010
1 parent 963ce8a commit af6e1d9
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 48 deletions.
22 changes: 11 additions & 11 deletions drivers/input/misc/adxl34x-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);

Expand All @@ -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[] = {
Expand All @@ -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,
};

Expand Down
16 changes: 8 additions & 8 deletions drivers/input/misc/adxl34x-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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)
Expand Down
76 changes: 49 additions & 27 deletions drivers/input/misc/adxl34x.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
/*
* A '0' places the ADXL34x into standby mode
* with minimum power consumption.
*/
AC_WRITE(ac, POWER_CTL, 0);
}

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;
}
AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
}

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

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);
__adxl34x_enable(ac);

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)
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -649,8 +664,12 @@ static int adxl34x_input_open(struct input_dev *input)
struct adxl34x *ac = input_get_drvdata(input);

mutex_lock(&ac->mutex);

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

ac->opened = true;
__adxl34x_enable(ac);

mutex_unlock(&ac->mutex);

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

mutex_lock(&ac->mutex);
__adxl34x_disable(ac);

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

ac->opened = false;

mutex_unlock(&ac->mutex);
}

Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions drivers/input/misc/adxl34x.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit af6e1d9

Please sign in to comment.