summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorMarcus Cooper <marcus.xm.cooper@stericsson.com>2011-05-16 10:08:49 +0200
committerUlf Hansson <ulf.hansson@stericsson.com>2011-09-19 16:00:08 +0200
commita7f4b5490f9b4868cc503b0b93f2769f05f0d143 (patch)
tree608b8406fe58bbc232b22168040c27b2c469e660 /drivers/misc
parent9b98d7e361682361f02ce6edb896534613acabaf (diff)
bh1780gli: Add early suspend/late resume
ST-Ericsson Linux next: Not tested, ask SSM for ER. ST-Ericsson ID: ER337907 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I66430fe4369c1320c78b1a8dca5e4abbb3b9abcf Signed-off-by: Marcus Cooper <marcus.xm.cooper@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23099 Reviewed-by: QATEST Reviewed-by: Martin PERSSON <martin.persson@stericsson.com> Reviewed-by: Chethan Krishna N <chethan.krishna@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/28973 Tested-by: Naga RADHESH Y <naga.radheshy@stericsson.com> Reviewed-by: Bibek BASU <bibek.basu@stericsson.com> Tested-by: Bibek BASU <bibek.basu@stericsson.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/bh1780gli.c124
1 files changed, 94 insertions, 30 deletions
diff --git a/drivers/misc/bh1780gli.c b/drivers/misc/bh1780gli.c
index 0a731371fb5..c49d45fa236 100644
--- a/drivers/misc/bh1780gli.c
+++ b/drivers/misc/bh1780gli.c
@@ -25,6 +25,10 @@
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
#define BH1780_REG_CONTROL 0x80
#define BH1780_REG_PARTID 0x8A
#define BH1780_REG_MANFID 0x8B
@@ -42,11 +46,19 @@
struct bh1780_data {
struct i2c_client *client;
struct regulator *regulator;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
int power_state;
/* lock for sysfs operations */
struct mutex lock;
};
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bh1780_early_suspend(struct early_suspend *ddata);
+static void bh1780_late_resume(struct early_suspend *ddata);
+#endif
+
static int bh1780_write(struct bh1780_data *ddata, u8 reg, u8 val, char *msg)
{
int ret = i2c_smbus_write_byte_data(ddata->client, reg, val);
@@ -191,6 +203,12 @@ static int __devinit bh1780_probe(struct i2c_client *client,
dev_err(&client->dev, "failed to read part ID\n");
goto put_regulator;
}
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ ddata->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ ddata->early_suspend.suspend = bh1780_early_suspend;
+ ddata->early_suspend.resume = bh1780_late_resume;
+ register_early_suspend(&ddata->early_suspend);
+#endif
regulator_disable(ddata->regulator);
ddata->power_state = BH1780_POFF;
@@ -225,57 +243,101 @@ static int __devexit bh1780_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
-static int bh1780_suspend(struct device *dev)
+static int bh1780_do_suspend(struct bh1780_data *ddata)
{
- struct bh1780_data *ddata;
- int state, ret;
- struct i2c_client *client = to_i2c_client(dev);
+ int ret = 0;
- ddata = i2c_get_clientdata(client);
- state = bh1780_read(ddata, BH1780_REG_CONTROL, "CONTROL");
- if (state < 0)
- return state;
+ mutex_lock(&ddata->lock);
- ddata->power_state = state & BH1780_POWMASK;
+ if (ddata->power_state == BH1780_POFF)
+ goto unlock;
- ret = bh1780_write(ddata, BH1780_REG_CONTROL, BH1780_POFF,
- "CONTROL");
+ ret = bh1780_write(ddata, BH1780_REG_CONTROL, BH1780_POFF, "CONTROL");
if (ret < 0)
- return ret;
-
- regulator_disable(ddata->regulator);
+ goto unlock;
- return 0;
+ if (ddata->regulator)
+ regulator_disable(ddata->regulator);
+unlock:
+ mutex_unlock(&ddata->lock);
+ return ret;
}
-static int bh1780_resume(struct device *dev)
+static int bh1780_do_resume(struct bh1780_data *ddata)
{
- struct bh1780_data *ddata;
- int state, ret;
- struct i2c_client *client = to_i2c_client(dev);
+ int ret = 0;
- ddata = i2c_get_clientdata(client);
- state = ddata->power_state;
- ret = bh1780_write(ddata, BH1780_REG_CONTROL, state,
- "CONTROL");
+ mutex_lock(&ddata->lock);
- regulator_enable(ddata->regulator);
+ if (ddata->power_state == BH1780_POFF)
+ goto unlock;
+
+ if (ddata->regulator)
+ regulator_enable(ddata->regulator);
+
+ ret = bh1780_write(ddata, BH1780_REG_CONTROL,
+ ddata->power_state, "CONTROL");
- ret = bh1780_write(ddata, BH1780_REG_CONTROL, ddata->power_state,
- "CONTROL");
+unlock:
+ mutex_unlock(&ddata->lock);
+ return ret;
+}
+#if (!defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_PM))
+static int bh1780_suspend(struct device *dev)
+{
+ struct bh1780_data *ddata = dev_get_drvdata(dev);
+ int ret = 0;
+
+ ret = bh1780_do_suspend(ddata);
if (ret < 0)
- return ret;
+ dev_err(&ddata->client->dev,
+ "Error while suspending the device\n");
- return 0;
+ return ret;
+}
+
+static int bh1780_resume(struct device *dev)
+{
+ struct bh1780_data *ddata = dev_get_drvdata(dev);
+ int ret = 0;
+
+ ret = bh1780_do_resume(ddata);
+ if (ret < 0)
+ dev_err(&ddata->client->dev,
+ "Error while resuming the device\n");
+
+ return ret;
}
static SIMPLE_DEV_PM_OPS(bh1780_pm, bh1780_suspend, bh1780_resume);
#define BH1780_PMOPS (&bh1780_pm)
#else
#define BH1780_PMOPS NULL
-#endif /* CONFIG_PM */
+static void bh1780_early_suspend(struct early_suspend *data)
+{
+ struct bh1780_data *ddata =
+ container_of(data, struct bh1780_data, early_suspend);
+ int ret;
+
+ ret = bh1780_do_suspend(ddata);
+ if (ret < 0)
+ dev_err(&ddata->client->dev,
+ "Error while suspending the device\n");
+}
+
+static void bh1780_late_resume(struct early_suspend *data)
+{
+ struct bh1780_data *ddata =
+ container_of(data, struct bh1780_data, early_suspend);
+ int ret;
+
+ ret = bh1780_do_resume(ddata);
+ if (ret < 0)
+ dev_err(&ddata->client->dev,
+ "Error while resuming the device\n");
+}
+#endif /*!CONFIG_HAS_EARLYSUSPEND && CONFIG_PM */
static const struct i2c_device_id bh1780_id[] = {
{ "bh1780", 0 },
@@ -288,7 +350,9 @@ static struct i2c_driver bh1780_driver = {
.id_table = bh1780_id,
.driver = {
.name = "bh1780",
+#if (!defined(CONFIG_HAS_EARLYSUSPEND) && defined(CONFIG_PM))
.pm = BH1780_PMOPS,
+#endif
},
};