* [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
@ 2020-11-28 18:51 Jonathan Cameron
2020-11-28 19:20 ` Linus Walleij
0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Cameron @ 2020-11-28 18:51 UTC (permalink / raw)
To: linux-iio; +Cc: Jonathan Cameron, Andy Shevchenko, Linus Walleij
From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
The whole one time programable memory is treated as a single 64bit
little endian value. Thus we can avoid a lot of messy handling
of fields overlapping byte boundaries by just loading and manipulating
it as an __le64 converted to a u64. That lets us just use FIELD_GET()
and GENMASK() to extract the values desired.
Note only build tested.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
drivers/iio/gyro/mpu3050-core.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
index 00e58060968c..6380fc1bdee3 100644
--- a/drivers/iio/gyro/mpu3050-core.c
+++ b/drivers/iio/gyro/mpu3050-core.c
@@ -13,6 +13,7 @@
* TODO: add support for setting up the low pass 3dB frequency.
*/
+#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
@@ -784,7 +785,8 @@ static int mpu3050_read_mem(struct mpu3050 *mpu3050,
static int mpu3050_hw_init(struct mpu3050 *mpu3050)
{
int ret;
- u8 otp[8];
+ __le64 otp_le;
+ u64 otp;
/* Reset */
ret = regmap_update_bits(mpu3050->map,
@@ -815,29 +817,31 @@ static int mpu3050_hw_init(struct mpu3050 *mpu3050)
MPU3050_MEM_USER_BANK |
MPU3050_MEM_OTP_BANK_0),
0,
- sizeof(otp),
- otp);
+ sizeof(otp_le),
+ (u8 *)&otp_le);
if (ret)
return ret;
/* This is device-unique data so it goes into the entropy pool */
- add_device_randomness(otp, sizeof(otp));
+ add_device_randomness(&otp_le, sizeof(otp_le));
+
+ otp = le64_to_cpu(otp_le);
dev_info(mpu3050->dev,
- "die ID: %04X, wafer ID: %02X, A lot ID: %04X, "
- "W lot ID: %03X, WP ID: %01X, rev ID: %02X\n",
+ "die ID: %04lX, wafer ID: %02lX, A lot ID: %04lX, "
+ "W lot ID: %03lX, WP ID: %01lX, rev ID: %02lX\n",
/* Die ID, bits 0-12 */
- (otp[1] << 8 | otp[0]) & 0x1fff,
+ FIELD_GET(GENMASK(12, 0), otp),
/* Wafer ID, bits 13-17 */
- ((otp[2] << 8 | otp[1]) & 0x03e0) >> 5,
+ FIELD_GET(GENMASK(17, 13), otp),
/* A lot ID, bits 18-33 */
- ((otp[4] << 16 | otp[3] << 8 | otp[2]) & 0x3fffc) >> 2,
+ FIELD_GET(GENMASK(33, 18), otp),
/* W lot ID, bits 34-45 */
- ((otp[5] << 8 | otp[4]) & 0x3ffc) >> 2,
+ FIELD_GET(GENMASK(45, 34), otp),
/* WP ID, bits 47-49 */
- ((otp[6] << 8 | otp[5]) & 0x0380) >> 7,
+ FIELD_GET(GENMASK(49, 47), otp),
/* rev ID, bits 50-55 */
- otp[6] >> 2);
+ FIELD_GET(GENMASK(55, 50), otp));
return 0;
}
--
2.29.2
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
2020-11-28 18:51 [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up Jonathan Cameron
@ 2020-11-28 19:20 ` Linus Walleij
2020-11-28 23:18 ` Andy Shevchenko
0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2020-11-28 19:20 UTC (permalink / raw)
To: Jonathan Cameron; +Cc: linux-iio, Jonathan Cameron, Andy Shevchenko
On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
> From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
> Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
>
> The whole one time programable memory is treated as a single 64bit
> little endian value. Thus we can avoid a lot of messy handling
> of fields overlapping byte boundaries by just loading and manipulating
> it as an __le64 converted to a u64. That lets us just use FIELD_GET()
> and GENMASK() to extract the values desired.
>
> Note only build tested.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>
Are there any specific prerequisites? linux-next?
When I apply this and try to compile for an ARMv7 target I get
a lot of noise and an error:
In file included from <command-line>:0:0:
../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
../include/linux/bits.h:36:11: warning: right shift count is negative
[-Wshift-count-negative]
(~UL(0) >> (BITS_PER_LONG - 1 - (h))))
^
./../include/linux/compiler_types.h:299:9: note: in definition of
macro ‘__compiletime_assert’
if (!(condition)) \
^~~~~~~~~
./../include/linux/compiler_types.h:319:2: note: in expansion of macro
‘_compiletime_assert’
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^~~~~~~~~~~~~~~~~~~
../include/linux/build_bug.h:39:37: note: in expansion of macro
‘compiletime_assert’
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
../include/linux/bitfield.h:46:3: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
^~~~~~~~~~~~~~~~
../include/linux/bitfield.h:108:3: note: in expansion of macro
‘__BF_FIELD_CHECK’
__BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
^~~~~~~~~~~~~~~~
../include/linux/dev_printk.h:118:33: note: in expansion of macro ‘FIELD_GET’
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~~~
../include/linux/bits.h:38:31: note: in expansion of macro ‘__GENMASK’
(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
^~~~~~~~~
../include/linux/dev_printk.h:118:33: note: in expansion of macro ‘GENMASK’
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~~~
../drivers/iio/gyro/mpu3050-core.c:830:2: note: in expansion of macro ‘dev_info’
dev_info(mpu3050->dev,
^~~~~~~~
../include/linux/bits.h:36:11: warning: right shift count is negative
[-Wshift-count-negative]
(~UL(0) >> (BITS_PER_LONG - 1 - (h))))
^
./../include/linux/compiler_types.h:299:9: note: in definition of
macro ‘__compiletime_assert’
if (!(condition)) \
^~~~~~~~~
./../include/linux/compiler_types.h:319:2: note: in expansion of macro
‘_compiletime_assert’
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
^~~~~~~~~~~~~~~~~~~
../include/linux/build_bug.h:39:37: note: in expansion of macro
‘compiletime_assert’
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
^~~~~~~~~~~~~~~~~~
../include/linux/bitfield.h:48:3: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \
^~~~~~~~~~~~~~~~
../include/linux/bitfield.h:108:3: note: in expansion of macro
‘__BF_FIELD_CHECK’
__BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
^~~~~~~~~~~~~~~~
../include/linux/dev_printk.h:118:33: note: in expansion of macro ‘FIELD_GET’
_dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
^~~~~~~~~~~
(...)
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
2020-11-28 19:20 ` Linus Walleij
@ 2020-11-28 23:18 ` Andy Shevchenko
2020-11-29 1:11 ` Linus Walleij
0 siblings, 1 reply; 5+ messages in thread
From: Andy Shevchenko @ 2020-11-28 23:18 UTC (permalink / raw)
To: Linus Walleij
Cc: Jonathan Cameron, linux-iio, Jonathan Cameron, Andy Shevchenko
On Sun, Nov 29, 2020 at 12:22 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
>
> > From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> >
> > Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
> >
> > The whole one time programable memory is treated as a single 64bit
> > little endian value. Thus we can avoid a lot of messy handling
> > of fields overlapping byte boundaries by just loading and manipulating
> > it as an __le64 converted to a u64. That lets us just use FIELD_GET()
> > and GENMASK() to extract the values desired.
> >
> > Note only build tested.
> >
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
>
> Are there any specific prerequisites? linux-next?
>
> When I apply this and try to compile for an ARMv7 target I get
> a lot of noise and an error:
>
> In file included from <command-line>:0:0:
> ../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
> ../include/linux/bits.h:36:11: warning: right shift count is negative
> [-Wshift-count-negative]
> (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
I think GENMASK_ULL() has to be used.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
2020-11-28 23:18 ` Andy Shevchenko
@ 2020-11-29 1:11 ` Linus Walleij
2020-11-29 11:28 ` Jonathan Cameron
0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2020-11-29 1:11 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Jonathan Cameron, linux-iio, Jonathan Cameron, Andy Shevchenko
On Sun, Nov 29, 2020 at 12:18 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
> On Sun, Nov 29, 2020 at 12:22 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > >
> > > Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
> > >
> > > The whole one time programable memory is treated as a single 64bit
> > > little endian value. Thus we can avoid a lot of messy handling
> > > of fields overlapping byte boundaries by just loading and manipulating
> > > it as an __le64 converted to a u64. That lets us just use FIELD_GET()
> > > and GENMASK() to extract the values desired.
> > >
> > > Note only build tested.
> > >
> > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > > Cc: Linus Walleij <linus.walleij@linaro.org>
> >
> > Are there any specific prerequisites? linux-next?
> >
> > When I apply this and try to compile for an ARMv7 target I get
> > a lot of noise and an error:
> >
> > In file included from <command-line>:0:0:
> > ../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
> > ../include/linux/bits.h:36:11: warning: right shift count is negative
> > [-Wshift-count-negative]
> > (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
>
> I think GENMASK_ULL() has to be used.
Oh indeed. It works as long as one just try to test-compile it on a 64bit
machine of course :D
Yours,
Linus Walleij
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
2020-11-29 1:11 ` Linus Walleij
@ 2020-11-29 11:28 ` Jonathan Cameron
0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2020-11-29 11:28 UTC (permalink / raw)
To: Linus Walleij
Cc: Andy Shevchenko, linux-iio, Jonathan Cameron, Andy Shevchenko
On Sun, 29 Nov 2020 02:11:01 +0100
Linus Walleij <linus.walleij@linaro.org> wrote:
> On Sun, Nov 29, 2020 at 12:18 AM Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
> > On Sun, Nov 29, 2020 at 12:22 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> > > On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
> > >
> > > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > >
> > > > Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
> > > >
> > > > The whole one time programable memory is treated as a single 64bit
> > > > little endian value. Thus we can avoid a lot of messy handling
> > > > of fields overlapping byte boundaries by just loading and manipulating
> > > > it as an __le64 converted to a u64. That lets us just use FIELD_GET()
> > > > and GENMASK() to extract the values desired.
> > > >
> > > > Note only build tested.
> > > >
> > > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > > > Cc: Linus Walleij <linus.walleij@linaro.org>
> > >
> > > Are there any specific prerequisites? linux-next?
> > >
> > > When I apply this and try to compile for an ARMv7 target I get
> > > a lot of noise and an error:
> > >
> > > In file included from <command-line>:0:0:
> > > ../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
> > > ../include/linux/bits.h:36:11: warning: right shift count is negative
> > > [-Wshift-count-negative]
> > > (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
> >
> > I think GENMASK_ULL() has to be used.
>
> Oh indeed. It works as long as one just try to test-compile it on a 64bit
> machine of course :D
Doh. That's me being lazy :(
Will flip them all over to GENMASK_ULL and do a 32 bit build test.
I checked that the FIELD_GET would be fine, but forgot to look at
GENMASK.
oops.
Jonathan
>
> Yours,
> Linus Walleij
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2020-11-29 11:28 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-28 18:51 [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up Jonathan Cameron
2020-11-28 19:20 ` Linus Walleij
2020-11-28 23:18 ` Andy Shevchenko
2020-11-29 1:11 ` Linus Walleij
2020-11-29 11:28 ` Jonathan Cameron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).