RE: [PATCHv3 2/2] regmap: add DT endianness binding support.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> > + * of_regmap_endian_by_type() - Parse and lookup the endian referenced
> > + * by a device node
> > + * @np: pointer to clock consumer node
> 
> This is not the clock consumer, right?
> 

Yes, you are right.

I will fix it.


> > + * @type: type of consumer's endian input
> > + *
> > + * This function parses the device endian property, and uses them to
> > + * determine the endian of the registers and values.
> > + */
> > +static int of_regmap_endian_by_type(struct device_node *np,
> > +					enum regmap_endian_type type,
> > +					enum regmap_endian *endian)
> > +{
> > +	if (!endian)
> > +		return -EINVAL;
> > +
> > +	switch (type) {
> > +	case REGMAP_ENDIAN_REG:
> > +		if (of_property_read_bool(np, "big-endian-reg"))
> > +			*endian = REGMAP_ENDIAN_BIG;
> > +		else if (of_property_read_bool(np, "little-endian-reg"))
> > +			*endian = REGMAP_ENDIAN_LITTLE;
> > +		else
> > +			*endian = REGMAP_ENDIAN_NATIVE;
> 
> You could also return an error code here as there was no DT property
> found. This doesn't change to much in the code, just an idea.
> 

The properties are all Boolean ones, and returning an error code here
is not proper. Isn't it ?

Returning _NATIVE here means to indicate that the the CPU and DEV are in
the same endianness mode...


Thanks very much,

BRs
Xiubo



> Regards,
> 
> Markus
> 
> > +		break;
> > +	case REGMAP_ENDIAN_VAL:
> > +		if (of_property_read_bool(np, "big-endian-val"))
> > +			*endian = REGMAP_ENDIAN_BIG;
> > +		else if (of_property_read_bool(np, "little-endian-val"))
> > +			*endian = REGMAP_ENDIAN_LITTLE;
> > +		else
> > +			*endian = REGMAP_ENDIAN_NATIVE;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int of_regmap_get_endian(struct device *dev,
> > +				const struct regmap_bus *bus,
> > +				const struct regmap_config *config,
> > +				enum regmap_endian_type type,
> > +				enum regmap_endian *endian)
> > +{
> > +	int ret;
> > +
> > +	if (!endian || !config)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Firstly, try to parse the endian from driver's config,
> > +	 * this is to be compatible with the none DT or the old drivers.
> > +	 * From the driver's config the endian value maybe:
> > +	 *   REGMAP_ENDIAN_BIG,
> > +	 *   REGMAP_ENDIAN_LITTLE,
> > +	 *   REGMAP_ENDIAN_NATIVE,
> > +	 *   REGMAP_ENDIAN_DEFAULT.
> > +	 */
> > +	switch (type) {
> > +	case REGMAP_ENDIAN_REG:
> > +		*endian = config->reg_format_endian;
> > +		break;
> > +	case REGMAP_ENDIAN_VAL:
> > +		*endian = config->val_format_endian;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	/*
> > +	 * If the endian parsing from driver's config is REGMAP_ENDIAN_DEFAULT,
> > +	 * that means maybe we are using the DT node to specify the endianness.
> > +	 */
> > +	if (*endian != REGMAP_ENDIAN_DEFAULT)
> > +		return 0;
> > +
> > +	/*
> > +	 * Secondly, try to parse the endian from DT node if the
> > +	 * driver config does not specify it.
> > +	 * From the DT node the endian value maybe:
> > +	 *   REGMAP_ENDIAN_BIG,
> > +	 *   REGMAP_ENDIAN_LITTLE,
> > +	 *   REGMAP_ENDIAN_NATIVE,
> > +	 */
> > +	if (dev) {
> > +		ret = of_regmap_endian_by_type(dev->of_node, type, endian);
> > +		if (ret < 0)
> > +			return ret;
> > +	}
> > +
> > +	/*
> > +	 * If the endian parsing from DT node is REGMAP_ENDIAN_NATIVE, that
> > +	 * maybe means the DT does not care the endianness or it should use
> > +	 * the regmap bus's default endianness, then we should try to check
> > +	 * whether the regmap bus has specified the default endianess.
> > +	 */
> > +	if (*endian != REGMAP_ENDIAN_NATIVE)
> > +		return 0;
> > +
> > +	/*
> > +	 * Finally, try to parse the endian from regmap bus config
> > +	 * if in device's DT node the endian property is absent.
> > +	 */
> > +	switch (type) {
> > +	case REGMAP_ENDIAN_REG:
> > +		if (bus && bus->reg_format_endian_default)
> > +			*endian = bus->reg_format_endian_default;
> > +		break;
> > +	case REGMAP_ENDIAN_VAL:
> > +		if (bus && bus->val_format_endian_default)
> > +			*endian = bus->val_format_endian_default;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /**
> >   * regmap_init(): Initialise register map
> >   *
> > @@ -518,17 +645,15 @@ 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;
> > +	ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_REG,
> > +				   &reg_endian);
> > +	if (ret)
> > +		return ERR_PTR(ret);
> > +
> > +	ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_VAL,
> > +				   &val_endian);
> > +	if (ret)
> > +		return ERR_PTR(ret);
> >
> >  	switch (config->reg_bits + map->reg_shift) {
> >  	case 2:
> > --
> > 1.8.4
> >
> >
> 
> --
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |
��.n��������+%������w��{.n����z�{��ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f





[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux