18 Aug, 2019

1 commit

  • Like in H3, A64 SID controller doesn't return correct data
    when using direct access. It appears that on A64, SID needs
    8 bytes of word_size.

    Workaround is to enable read by registers.

    Signed-off-by: Stefan Mavrodiev
    Acked-by: Chen-Yu Tsai
    Tested-by: Vasily Khoruzhick
    Signed-off-by: Srinivas Kandagatla
    Link: https://lore.kernel.org/r/20190818093345.29647-4-srinivas.kandagatla@linaro.org
    Signed-off-by: Greg Kroah-Hartman

    Stefan Mavrodiev
     

26 Apr, 2019

7 commits

  • Add support for H6's SID controller. It supports 4K-bit
    EFUSE, bigger than before.

    Signed-off-by: Yangtao Li
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Yangtao Li
     
  • Updates license to use SPDX-License-Identifier.

    Acked-by: Maxime Ripard
    Signed-off-by: Yangtao Li
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Yangtao Li
     
  • The device tree binding already lists compatible strings for these two
    SoCs. They don't have the defect as seen on the H3, and the size and
    register layout is the same as the A64. Furthermore, the driver does
    not include nvmem cell definitions.

    Add support for these two compatible strings, re-using the config for
    the A64.

    Signed-off-by: Chen-Yu Tsai
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Chen-Yu Tsai
     
  • Originally the SID e-fuses were thought to be in big-endian format.
    Later sources show that they are in fact native or little-endian.
    The most compelling evidence is the thermal sensor calibration data,
    which is a set of one to three 16-bit values. In native-endian they
    are in 16-bit cells with increasing offsets, whereas with big-endian
    they are in the wrong order, and a gap with no data will show if there
    are one or three cells.

    Switch to a native endian representation for the nvmem device. For the
    H3, the register read-out method was already returning data in native
    endian. This only affects the other SoCs.

    Signed-off-by: Chen-Yu Tsai
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Chen-Yu Tsai
     
  • The sunxi_sid driver currently uses a statically allocated nvmem_config
    structure that is updated at probe time. This is sub-optimal as it
    limits the driver to one instance, and also takes up space even if the
    device is not present.

    Modify the driver to allocate the nvmem_config structure at probe time,
    plugging in the desired parameters along the way.

    Signed-off-by: Chen-Yu Tsai
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Chen-Yu Tsai
     
  • SID cells are 32-bit aligned, and a multiple of 32 bits in length. The
    only outlier is the thermal sensor calibration data, which is 16 bits
    per sensor. However a whole 64 bits is allocated for this purpose, so
    we could consider it conforming to the rule above.

    Also, the register read-out method assumes native endian, unlike the
    direct MMIO method, which assumes big endian. Thus no endian conversion
    is involved.

    Under these assumptions, the register read-out method can be slightly
    optimized. Instead of reading one word then discarding 3 bytes, read
    the whole word directly into the buffer. However, for reads under 4
    bytes or trailing bytes, we still use a scratch buffer to extract the
    requested bytes.

    We could go one step further if .word_size was 4, but changing that
    would affect the sysfs interface's behavior.

    Signed-off-by: Chen-Yu Tsai
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Chen-Yu Tsai
     
  • Since the reg_read callbacks already support arbitrary, but 4-byte
    aligned. offsets and lengths into the SID, there is no need for another
    for loop just to use it to read 1 byte at a time.

    Read out the whole SID block in one go.

    Signed-off-by: Chen-Yu Tsai
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Chen-Yu Tsai
     

28 Sep, 2018

3 commits


13 Jun, 2018

1 commit

  • The kzalloc() function has a 2-factor argument form, kcalloc(). This
    patch replaces cases of:

    kzalloc(a * b, gfp)

    with:
    kcalloc(a * b, gfp)

    as well as handling cases of:

    kzalloc(a * b * c, gfp)

    with:

    kzalloc(array3_size(a, b, c), gfp)

    as it's slightly less ugly than:

    kzalloc_array(array_size(a, b), c, gfp)

    This does, however, attempt to ignore constant size factors like:

    kzalloc(4 * 1024, gfp)

    though any constants defined via macros get caught up in the conversion.

    Any factors with a sizeof() of "unsigned char", "char", and "u8" were
    dropped, since they're redundant.

    The Coccinelle script used for this was:

    // Fix redundant parens around sizeof().
    @@
    type TYPE;
    expression THING, E;
    @@

    (
    kzalloc(
    - (sizeof(TYPE)) * E
    + sizeof(TYPE) * E
    , ...)
    |
    kzalloc(
    - (sizeof(THING)) * E
    + sizeof(THING) * E
    , ...)
    )

    // Drop single-byte sizes and redundant parens.
    @@
    expression COUNT;
    typedef u8;
    typedef __u8;
    @@

    (
    kzalloc(
    - sizeof(u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * (COUNT)
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(__u8) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(char) * COUNT
    + COUNT
    , ...)
    |
    kzalloc(
    - sizeof(unsigned char) * COUNT
    + COUNT
    , ...)
    )

    // 2-factor product with sizeof(type/expression) and identifier or constant.
    @@
    type TYPE;
    expression THING;
    identifier COUNT_ID;
    constant COUNT_CONST;
    @@

    (
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_ID)
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_ID
    + COUNT_ID, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (COUNT_CONST)
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * COUNT_CONST
    + COUNT_CONST, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_ID)
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_ID
    + COUNT_ID, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (COUNT_CONST)
    + COUNT_CONST, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * COUNT_CONST
    + COUNT_CONST, sizeof(THING)
    , ...)
    )

    // 2-factor product, only identifiers.
    @@
    identifier SIZE, COUNT;
    @@

    - kzalloc
    + kcalloc
    (
    - SIZE * COUNT
    + COUNT, SIZE
    , ...)

    // 3-factor product with 1 sizeof(type) or sizeof(expression), with
    // redundant parens removed.
    @@
    expression THING;
    identifier STRIDE, COUNT;
    type TYPE;
    @@

    (
    kzalloc(
    - sizeof(TYPE) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(TYPE))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * (COUNT) * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * (STRIDE)
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    |
    kzalloc(
    - sizeof(THING) * COUNT * STRIDE
    + array3_size(COUNT, STRIDE, sizeof(THING))
    , ...)
    )

    // 3-factor product with 2 sizeof(variable), with redundant parens removed.
    @@
    expression THING1, THING2;
    identifier COUNT;
    type TYPE1, TYPE2;
    @@

    (
    kzalloc(
    - sizeof(TYPE1) * sizeof(TYPE2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(THING1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(THING1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * COUNT
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    |
    kzalloc(
    - sizeof(TYPE1) * sizeof(THING2) * (COUNT)
    + array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
    , ...)
    )

    // 3-factor product, only identifiers, with redundant parens removed.
    @@
    identifier STRIDE, SIZE, COUNT;
    @@

    (
    kzalloc(
    - (COUNT) * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * STRIDE * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - (COUNT) * (STRIDE) * (SIZE)
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    |
    kzalloc(
    - COUNT * STRIDE * SIZE
    + array3_size(COUNT, STRIDE, SIZE)
    , ...)
    )

    // Any remaining multi-factor products, first at least 3-factor products,
    // when they're not all constants...
    @@
    expression E1, E2, E3;
    constant C1, C2, C3;
    @@

    (
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(
    - (E1) * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * E3
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - (E1) * (E2) * (E3)
    + array3_size(E1, E2, E3)
    , ...)
    |
    kzalloc(
    - E1 * E2 * E3
    + array3_size(E1, E2, E3)
    , ...)
    )

    // And then all remaining 2 factors products when they're not all constants,
    // keeping sizeof() as the second factor argument.
    @@
    expression THING, E1, E2;
    type TYPE;
    constant C1, C2, C3;
    @@

    (
    kzalloc(sizeof(THING) * C2, ...)
    |
    kzalloc(sizeof(TYPE) * C2, ...)
    |
    kzalloc(C1 * C2 * C3, ...)
    |
    kzalloc(C1 * C2, ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * (E2)
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(TYPE) * E2
    + E2, sizeof(TYPE)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * (E2)
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - sizeof(THING) * E2
    + E2, sizeof(THING)
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * E2
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - (E1) * (E2)
    + E1, E2
    , ...)
    |
    - kzalloc
    + kcalloc
    (
    - E1 * E2
    + E1, E2
    , ...)
    )

    Signed-off-by: Kees Cook

    Kees Cook
     

15 Mar, 2018

1 commit

  • It seems that doing some operation will make the value pre-read on H3
    SID controller wrong again, so all operation should be performed by
    register.

    Change the SID reading to use register only.

    Signed-off-by: Icenowy Zheng
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Icenowy Zheng
     

08 Nov, 2017

2 commits

  • Allwinner A64/H5 SoCs come with a SID controller like the one in H3, but
    without the silicon bug that makes the initial value at 0x200 wrong, so
    the value at 0x200 can be directly read.

    Add support for this kind of SID controller.

    Signed-off-by: Icenowy Zheng
    Acked-by: Rob Herring
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Icenowy Zheng
     
  • All nvmem drivers are supposed to set the owner field of struct
    nvmem_config, but this matches nvmem->dev->driver->owner.

    As far as I see in drivers/nvmem/ directory, all the drivers are
    the case. So, make nvmem_register() set the nvmem's owner to the
    associated driver's owner unless nvmem_config sets otherwise.

    Remove .owner settings in the drivers that are now redundant.

    Signed-off-by: Masahiro Yamada
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Masahiro Yamada
     

08 Apr, 2017

2 commits

  • The H3 SoC have a bigger SID controller, which has its direct read
    address at 0x200 position in the SID block, not 0x0.

    Also, H3 SID controller has some silicon bug that makes the direct read
    value wrong at cold boot, add code to workaround the bug. (This bug has
    already been fixed on A64 and later SoCs)

    Signed-off-by: Icenowy Zheng
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Icenowy Zheng
     
  • Sometimes the SID device have more memory address space than the real
    NVMEM size (for the registers used to read/write the SID).

    Fetch the NVMEM size from device compatible, rather than the memory
    address space's length, in order to prepare for adding some
    registers-based read support.

    Signed-off-by: Icenowy Zheng
    Acked-by: Maxime Ripard
    Signed-off-by: Srinivas Kandagatla
    Signed-off-by: Greg Kroah-Hartman

    Icenowy Zheng
     

02 May, 2016

1 commit


08 Feb, 2016

1 commit


04 Oct, 2015

1 commit

  • The sunxi_sid driver doesn't check for kmalloc return status before
    derefencing the returned pointer, which could lead to a NULL pointer
    dereference if kmalloc failed. Check for its return code to make sure it
    deosn't happen.

    Reported-by: Dan Carpenter
    Signed-off-by: Maxime Ripard
    Signed-off-by: Greg Kroah-Hartman

    Maxime Ripard
     

06 Aug, 2015

1 commit

  • Now that we have the nvmem framework, we can consolidate the common
    driver code. Move the driver to the framework, and hopefully, it will
    fix the sysfs file creation race.

    Signed-off-by: Maxime Ripard
    [srinivas.kandagatla: Moved to regmap based EEPROM framework]
    Signed-off-by: Srinivas Kandagatla
    Tested-by: Philipp Zabel
    Tested-by: Rajendra Nayak
    Signed-off-by: Greg Kroah-Hartman

    Maxime Ripard