Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/imx', 'spi/topic...
[linux-2.6-microblaze.git] / drivers / base / regmap / regmap.c
index 1cf427b..f2281af 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/export.h>
 #include <linux/mutex.h>
 #include <linux/err.h>
+#include <linux/of.h>
 #include <linux/rbtree.h>
 #include <linux/sched.h>
 
@@ -448,6 +449,66 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
 }
 EXPORT_SYMBOL_GPL(regmap_attach_dev);
 
+static enum regmap_endian regmap_get_reg_endian(const struct regmap_bus *bus,
+                                       const struct regmap_config *config)
+{
+       enum regmap_endian endian;
+
+       /* Retrieve the endianness specification from the regmap config */
+       endian = config->reg_format_endian;
+
+       /* If the regmap config specified a non-default value, use that */
+       if (endian != REGMAP_ENDIAN_DEFAULT)
+               return endian;
+
+       /* Retrieve the endianness specification from the bus config */
+       if (bus && bus->reg_format_endian_default)
+               endian = bus->reg_format_endian_default;
+
+       /* If the bus specified a non-default value, use that */
+       if (endian != REGMAP_ENDIAN_DEFAULT)
+               return endian;
+
+       /* Use this if no other value was found */
+       return REGMAP_ENDIAN_BIG;
+}
+
+static enum regmap_endian regmap_get_val_endian(struct device *dev,
+                                       const struct regmap_bus *bus,
+                                       const struct regmap_config *config)
+{
+       struct device_node *np = dev->of_node;
+       enum regmap_endian endian;
+
+       /* Retrieve the endianness specification from the regmap config */
+       endian = config->val_format_endian;
+
+       /* If the regmap config specified a non-default value, use that */
+       if (endian != REGMAP_ENDIAN_DEFAULT)
+               return endian;
+
+       /* Parse the device's DT node for an endianness specification */
+       if (of_property_read_bool(np, "big-endian"))
+               endian = REGMAP_ENDIAN_BIG;
+       else if (of_property_read_bool(np, "little-endian"))
+               endian = REGMAP_ENDIAN_LITTLE;
+
+       /* If the endianness was specified in DT, use that */
+       if (endian != REGMAP_ENDIAN_DEFAULT)
+               return endian;
+
+       /* Retrieve the endianness specification from the bus config */
+       if (bus && bus->val_format_endian_default)
+               endian = bus->val_format_endian_default;
+
+       /* If the bus specified a non-default value, use that */
+       if (endian != REGMAP_ENDIAN_DEFAULT)
+               return endian;
+
+       /* Use this if no other value was found */
+       return REGMAP_ENDIAN_BIG;
+}
+
 /**
  * regmap_init(): Initialise register map
  *
@@ -551,17 +612,8 @@ struct regmap *regmap_init(struct device *dev,
                map->reg_read  = _regmap_bus_read;
        }
 
-       reg_endian = config->reg_format_endian;
-       if (reg_endian == REGMAP_ENDIAN_DEFAULT)
-               reg_endian = bus->reg_format_endian_default;
-       if (reg_endian == REGMAP_ENDIAN_DEFAULT)
-               reg_endian = REGMAP_ENDIAN_BIG;
-
-       val_endian = config->val_format_endian;
-       if (val_endian == REGMAP_ENDIAN_DEFAULT)
-               val_endian = bus->val_format_endian_default;
-       if (val_endian == REGMAP_ENDIAN_DEFAULT)
-               val_endian = REGMAP_ENDIAN_BIG;
+       reg_endian = regmap_get_reg_endian(bus, config);
+       val_endian = regmap_get_val_endian(dev, bus, config);
 
        switch (config->reg_bits + map->reg_shift) {
        case 2: