diff options
Diffstat (limited to 'drivers/regulator/pfuze100-regulator.c')
| -rw-r--r-- | drivers/regulator/pfuze100-regulator.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index d60d7d1b7fa2..7d56c22b5e40 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -10,6 +10,7 @@ #include <linux/of_device.h> #include <linux/regulator/of_regulator.h> #include <linux/platform_device.h> +#include <linux/reboot.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> #include <linux/regulator/pfuze100.h> @@ -75,7 +76,7 @@ struct pfuze_chip { struct device *dev; struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; struct regulator_dev *regulators[PFUZE100_MAX_REGULATOR]; - struct pfuze_regulator *pfuze_regulators; + const struct pfuze_regulator *pfuze_regulators; }; static const int pfuze100_swbst[] = { @@ -366,7 +367,7 @@ static const struct regulator_ops pfuze3000_sw_regulator_ops = { } /* PFUZE100 */ -static struct pfuze_regulator pfuze100_regulators[] = { +static const struct pfuze_regulator pfuze100_regulators[] = { PFUZE100_SW_REG(PFUZE100, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), PFUZE100_SW_REG(PFUZE100, SW1C, PFUZE100_SW1CVOL, 300000, 1875000, 25000), PFUZE100_SW_REG(PFUZE100, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), @@ -385,7 +386,7 @@ static struct pfuze_regulator pfuze100_regulators[] = { PFUZE100_COIN_REG(PFUZE100, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin), }; -static struct pfuze_regulator pfuze200_regulators[] = { +static const struct pfuze_regulator pfuze200_regulators[] = { PFUZE100_SW_REG(PFUZE200, SW1AB, PFUZE100_SW1ABVOL, 300000, 1875000, 25000), PFUZE100_SW_REG(PFUZE200, SW2, PFUZE100_SW2VOL, 400000, 1975000, 25000), PFUZE100_SW_REG(PFUZE200, SW3A, PFUZE100_SW3AVOL, 400000, 1975000, 25000), @@ -402,7 +403,7 @@ static struct pfuze_regulator pfuze200_regulators[] = { PFUZE100_COIN_REG(PFUZE200, COIN, PFUZE100_COINVOL, 0x7, pfuze100_coin), }; -static struct pfuze_regulator pfuze3000_regulators[] = { +static const struct pfuze_regulator pfuze3000_regulators[] = { PFUZE3000_SW_REG(PFUZE3000, SW1A, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), PFUZE100_SW_REG(PFUZE3000, SW1B, PFUZE100_SW1CVOL, 700000, 1475000, 25000), PFUZE3000_SW_REG(PFUZE3000, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), @@ -418,7 +419,7 @@ static struct pfuze_regulator pfuze3000_regulators[] = { PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), }; -static struct pfuze_regulator pfuze3001_regulators[] = { +static const struct pfuze_regulator pfuze3001_regulators[] = { PFUZE3000_SW_REG(PFUZE3001, SW1, PFUZE100_SW1ABVOL, 0x1f, pfuze3000_sw1a), PFUZE3000_SW_REG(PFUZE3001, SW2, PFUZE100_SW2VOL, 0x7, pfuze3000_sw2lo), PFUZE3000_SW3_REG(PFUZE3001, SW3, PFUZE100_SW3AVOL, 900000, 1650000, 50000), @@ -521,6 +522,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) parent = of_get_child_by_name(np, "regulators"); if (!parent) { dev_err(dev, "regulators node not found\n"); + of_node_put(np); return -EINVAL; } @@ -550,6 +552,7 @@ static int pfuze_parse_regulators_dt(struct pfuze_chip *chip) } of_node_put(parent); + of_node_put(np); if (ret < 0) { dev_err(dev, "Error parsing regulator init data: %d\n", ret); @@ -569,10 +572,10 @@ static inline struct device_node *match_of_node(int index) return pfuze_matches[index].of_node; } -static struct pfuze_chip *syspm_pfuze_chip; - -static void pfuze_power_off_prepare(void) +static int pfuze_power_off_prepare(struct sys_off_data *data) { + struct pfuze_chip *syspm_pfuze_chip = data->cb_data; + dev_info(syspm_pfuze_chip->dev, "Configure standby mode for power off"); /* Switch from default mode: APS/APS to APS/Off */ @@ -607,28 +610,30 @@ static void pfuze_power_off_prepare(void) regmap_update_bits(syspm_pfuze_chip->regmap, PFUZE100_VGEN6VOL, PFUZE100_VGENxLPWR | PFUZE100_VGENxSTBY, PFUZE100_VGENxSTBY); + + return NOTIFY_DONE; } static int pfuze_power_off_prepare_init(struct pfuze_chip *pfuze_chip) { + int err; + if (pfuze_chip->chip_id != PFUZE100) { dev_warn(pfuze_chip->dev, "Requested pm_power_off_prepare handler for not supported chip\n"); return -ENODEV; } - if (pm_power_off_prepare) { - dev_warn(pfuze_chip->dev, "pm_power_off_prepare is already registered.\n"); - return -EBUSY; + err = devm_register_sys_off_handler(pfuze_chip->dev, + SYS_OFF_MODE_POWER_OFF_PREPARE, + SYS_OFF_PRIO_DEFAULT, + pfuze_power_off_prepare, + pfuze_chip); + if (err) { + dev_err(pfuze_chip->dev, "failed to register sys-off handler: %d\n", + err); + return err; } - if (syspm_pfuze_chip) { - dev_warn(pfuze_chip->dev, "syspm_pfuze_chip is already set.\n"); - return -EBUSY; - } - - syspm_pfuze_chip = pfuze_chip; - pm_power_off_prepare = pfuze_power_off_prepare; - return 0; } @@ -675,12 +680,12 @@ static const struct regmap_config pfuze_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = PFUZE_NUMREGS - 1, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; -static int pfuze100_regulator_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int pfuze100_regulator_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct pfuze_chip *pfuze_chip; struct regulator_config config = { }; int i, ret; @@ -694,8 +699,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, return -ENOMEM; if (client->dev.of_node) { - match = of_match_device(of_match_ptr(pfuze_dt_ids), - &client->dev); + match = of_match_device(pfuze_dt_ids, &client->dev); if (!match) { dev_err(&client->dev, "Error: No device match found\n"); return -ENODEV; @@ -761,7 +765,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, ((pfuze_chip->chip_id == PFUZE3000) ? "3000" : "3001")))); memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, - sizeof(pfuze_chip->regulator_descs)); + regulator_num * sizeof(struct pfuze_regulator)); ret = pfuze_parse_regulators_dt(pfuze_chip); if (ret) @@ -837,23 +841,13 @@ static int pfuze100_regulator_probe(struct i2c_client *client, return 0; } -static int pfuze100_regulator_remove(struct i2c_client *client) -{ - if (syspm_pfuze_chip) { - syspm_pfuze_chip = NULL; - pm_power_off_prepare = NULL; - } - - return 0; -} - static struct i2c_driver pfuze_driver = { .driver = { .name = "pfuze100-regulator", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, .of_match_table = pfuze_dt_ids, }, .probe = pfuze100_regulator_probe, - .remove = pfuze100_regulator_remove, }; module_i2c_driver(pfuze_driver); |
