diff options
Diffstat (limited to 'drivers/mfd/adp5520.c')
| -rw-r--r-- | drivers/mfd/adp5520.c | 56 |
1 files changed, 22 insertions, 34 deletions
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index 3122139b430..f495b8b57dd 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c @@ -20,7 +20,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/init.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/irq.h> @@ -36,6 +35,7 @@ struct adp5520_chip { struct blocking_notifier_head notifier_list; int irq; unsigned long id; + uint8_t mode; }; static int __adp5520_read(struct i2c_client *client, @@ -109,7 +109,7 @@ int adp5520_set_bits(struct device *dev, int reg, uint8_t bit_mask) ret = __adp5520_read(chip->client, reg, ®_val); - if (!ret && ((reg_val & bit_mask) == 0)) { + if (!ret && ((reg_val & bit_mask) != bit_mask)) { reg_val |= bit_mask; ret = __adp5520_write(chip->client, reg, reg_val); } @@ -203,10 +203,10 @@ static int adp5520_remove_subdevs(struct adp5520_chip *chip) return device_for_each_child(chip->dev, NULL, __remove_subdev); } -static int __devinit adp5520_probe(struct i2c_client *client, +static int adp5520_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct adp5520_platform_data *pdata = client->dev.platform_data; + struct adp5520_platform_data *pdata = dev_get_platdata(&client->dev); struct platform_device *pdev; struct adp5520_chip *chip; int ret; @@ -222,7 +222,7 @@ static int __devinit adp5520_probe(struct i2c_client *client, return -ENODEV; } - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; @@ -243,7 +243,7 @@ static int __devinit adp5520_probe(struct i2c_client *client, if (ret) { dev_err(&client->dev, "failed to request irq %d\n", chip->irq); - goto out_free_chip; + return ret; } } @@ -301,13 +301,10 @@ out_free_irq: if (chip->irq) free_irq(chip->irq, chip); -out_free_chip: - kfree(chip); - return ret; } -static int __devexit adp5520_remove(struct i2c_client *client) +static int adp5520_remove(struct i2c_client *client) { struct adp5520_chip *chip = dev_get_drvdata(&client->dev); @@ -316,32 +313,34 @@ static int __devexit adp5520_remove(struct i2c_client *client) adp5520_remove_subdevs(chip); adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); - kfree(chip); return 0; } -#ifdef CONFIG_PM -static int adp5520_suspend(struct i2c_client *client, - pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int adp5520_suspend(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); + adp5520_read(chip->dev, ADP5520_MODE_STATUS, &chip->mode); + /* All other bits are W1C */ + chip->mode &= ADP5520_BL_EN | ADP5520_DIM_EN | ADP5520_nSTNBY; + adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); return 0; } -static int adp5520_resume(struct i2c_client *client) +static int adp5520_resume(struct device *dev) { + struct i2c_client *client = to_i2c_client(dev); struct adp5520_chip *chip = dev_get_drvdata(&client->dev); - adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); + adp5520_write(chip->dev, ADP5520_MODE_STATUS, chip->mode); return 0; } -#else -#define adp5520_suspend NULL -#define adp5520_resume NULL #endif +static SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume); + static const struct i2c_device_id adp5520_id[] = { { "pmic-adp5520", ID_ADP5520 }, { "pmic-adp5501", ID_ADP5501 }, @@ -353,25 +352,14 @@ static struct i2c_driver adp5520_driver = { .driver = { .name = "adp5520", .owner = THIS_MODULE, + .pm = &adp5520_pm, }, .probe = adp5520_probe, - .remove = __devexit_p(adp5520_remove), - .suspend = adp5520_suspend, - .resume = adp5520_resume, + .remove = adp5520_remove, .id_table = adp5520_id, }; -static int __init adp5520_init(void) -{ - return i2c_add_driver(&adp5520_driver); -} -module_init(adp5520_init); - -static void __exit adp5520_exit(void) -{ - i2c_del_driver(&adp5520_driver); -} -module_exit(adp5520_exit); +module_i2c_driver(adp5520_driver); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver"); |
