nvmem: rockchip-efuse: add support for rk3288 secure efuse
[firefly-linux-kernel-4.4.55.git] / drivers / mfd / tps65910.c
index d792772048358dbc9857cd3090d693a951d48713..f7ab115483a9d3357122a70ee562a345885c57ed 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mfd/core.h>
 #include <linux/regmap.h>
 #include <linux/mfd/tps65910.h>
+#include <linux/of.h>
 #include <linux/of_device.h>
 
 static struct resource rtc_resources[] = {
@@ -35,7 +36,7 @@ static struct resource rtc_resources[] = {
        }
 };
 
-static struct mfd_cell tps65910s[] = {
+static const struct mfd_cell tps65910s[] = {
        {
                .name = "tps65910-gpio",
        },
@@ -254,8 +255,10 @@ static int tps65910_irq_init(struct tps65910 *tps65910, int irq,
        ret = regmap_add_irq_chip(tps65910->regmap, tps65910->chip_irq,
                IRQF_ONESHOT, pdata->irq_base,
                tps6591x_irqs_chip, &tps65910->irq_data);
-       if (ret < 0)
+       if (ret < 0) {
                dev_warn(tps65910->dev, "Failed to add irq_chip %d\n", ret);
+               tps65910->chip_irq = 0;
+       }
        return ret;
 }
 
@@ -376,7 +379,7 @@ err_sleep_init:
 }
 
 #ifdef CONFIG_OF
-static struct of_device_id tps65910_of_match[] = {
+static const struct of_device_id tps65910_of_match[] = {
        { .compatible = "ti,tps65910", .data = (void *)TPS65910},
        { .compatible = "ti,tps65911", .data = (void *)TPS65911},
        { },
@@ -384,7 +387,7 @@ static struct of_device_id tps65910_of_match[] = {
 MODULE_DEVICE_TABLE(of, tps65910_of_match);
 
 static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
-                                               int *chip_id)
+                                               unsigned long *chip_id)
 {
        struct device_node *np = client->dev.of_node;
        struct tps65910_board *board_info;
@@ -398,7 +401,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
                return NULL;
        }
 
-       *chip_id  = (int)match->data;
+       *chip_id  = (unsigned long)match->data;
 
        board_info = devm_kzalloc(&client->dev, sizeof(*board_info),
                        GFP_KERNEL);
@@ -410,14 +413,10 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
        ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop);
        if (!ret)
                board_info->vmbch_threshold = prop;
-       else if (*chip_id == TPS65911)
-               dev_warn(&client->dev, "VMBCH-Threshold not specified");
 
        ret = of_property_read_u32(np, "ti,vmbch2-threshold", &prop);
        if (!ret)
                board_info->vmbch2_threshold = prop;
-       else if (*chip_id == TPS65911)
-               dev_warn(&client->dev, "VMBCH2-Threshold not specified");
 
        prop = of_property_read_bool(np, "ti,en-ck32k-xtal");
        board_info->en_ck32k_xtal = prop;
@@ -432,7 +431,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
 #else
 static inline
 struct tps65910_board *tps65910_parse_dt(struct i2c_client *client,
-                                        int *chip_id)
+                                        unsigned long *chip_id)
 {
        return NULL;
 }
@@ -454,14 +453,14 @@ static void tps65910_power_off(void)
 }
 
 static int tps65910_i2c_probe(struct i2c_client *i2c,
-                                       const struct i2c_device_id *id)
+                             const struct i2c_device_id *id)
 {
        struct tps65910 *tps65910;
        struct tps65910_board *pmic_plat_data;
        struct tps65910_board *of_pmic_plat_data = NULL;
        struct tps65910_platform_data *init_data;
+       unsigned long chip_id = id->driver_data;
        int ret = 0;
-       int chip_id = id->driver_data;
 
        pmic_plat_data = dev_get_platdata(&i2c->dev);
 
@@ -487,6 +486,11 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
        tps65910->i2c_client = i2c;
        tps65910->id = chip_id;
 
+       /* Work around silicon erratum SWCZ010: the tps65910 may miss the
+        * first I2C transfer. So issue a dummy transfer before the first
+        * real transfer.
+        */
+       i2c_master_send(i2c, "", 1);
        tps65910->regmap = devm_regmap_init_i2c(i2c, &tps65910_regmap_config);
        if (IS_ERR(tps65910->regmap)) {
                ret = PTR_ERR(tps65910->regmap);
@@ -512,6 +516,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
                              regmap_irq_get_domain(tps65910->irq_data));
        if (ret < 0) {
                dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret);
+               tps65910_irq_exit(tps65910);
                return ret;
        }
 
@@ -539,7 +544,6 @@ MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id);
 static struct i2c_driver tps65910_i2c_driver = {
        .driver = {
                   .name = "tps65910",
-                  .owner = THIS_MODULE,
                   .of_match_table = of_match_ptr(tps65910_of_match),
        },
        .probe = tps65910_i2c_probe,