CC: [email protected]
CC: [email protected]
BCC: [email protected]
CC: [email protected]
TO: Miquel Raynal <[email protected]>

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
master
head:   56e337f2cf1326323844927a04e9dbce9a244835
commit: d8701fe890ecbab239086e7053d62d0f08587d7c mtd: rawnand: renesas: Add new 
NAND controller driver
date:   3 months ago
:::::: branch date: 2 days ago
:::::: commit date: 3 months ago
config: arm-randconfig-c002-20220316 
(https://download.01.org/0day-ci/archive/20220318/[email protected]/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
a6ec1e3d798f8eab43fb3a91028c6ab04e115fcb)
reproduce (this is a W=1 build):
        wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install arm cross compiling tool for clang build
        # apt-get install binutils-arm-linux-gnueabi
        # 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d8701fe890ecbab239086e7053d62d0f08587d7c
        git remote add linus 
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
        git fetch --no-tags linus master
        git checkout d8701fe890ecbab239086e7053d62d0f08587d7c
        # save the config file to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=arm 
clang-analyzer 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>


clang-analyzer warnings: (new ones prefixed by >>)
                   ^
   drivers/mtd/tests/subpagetest.c:250:2: note: '?' condition is true
           pr_info("verifying all eraseblocks for 0xff\n");
           ^
   include/linux/printk.h:519:2: note: expanded from macro 'pr_info'
           printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
           ^
   include/linux/printk.h:446:26: note: expanded from macro 'printk'
   #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
                            ^
   include/linux/printk.h:417:3: note: expanded from macro 'printk_index_wrap'
                   __printk_index_emit(_fmt, NULL, NULL);                  \
                   ^
   include/linux/printk.h:379:12: note: expanded from macro 
'__printk_index_emit'
                                   .fmt = __builtin_constant_p(_fmt) ? (_fmt) : 
NULL, \
                                          ^
   drivers/mtd/tests/subpagetest.c:250:2: note: '?' condition is true
           pr_info("verifying all eraseblocks for 0xff\n");
           ^
   include/linux/printk.h:519:2: note: expanded from macro 'pr_info'
           printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
           ^
   include/linux/printk.h:446:26: note: expanded from macro 'printk'
   #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
                            ^
   include/linux/printk.h:417:3: note: expanded from macro 'printk_index_wrap'
                   __printk_index_emit(_fmt, NULL, NULL);                  \
                   ^
   include/linux/printk.h:383:14: note: expanded from macro 
'__printk_index_emit'
                                   .level = __builtin_constant_p(_level) ? 
(_level) : NULL, \
                                            ^
   drivers/mtd/tests/subpagetest.c:250:2: note: Loop condition is false.  
Exiting loop
           pr_info("verifying all eraseblocks for 0xff\n");
           ^
   include/linux/printk.h:519:2: note: expanded from macro 'pr_info'
           printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__)
           ^
   include/linux/printk.h:446:26: note: expanded from macro 'printk'
   #define printk(fmt, ...) printk_index_wrap(_printk, fmt, ##__VA_ARGS__)
                            ^
   include/linux/printk.h:417:3: note: expanded from macro 'printk_index_wrap'
                   __printk_index_emit(_fmt, NULL, NULL);                  \
                   ^
   include/linux/printk.h:369:2: note: expanded from macro '__printk_index_emit'
           do {                                                            \
           ^
   drivers/mtd/tests/subpagetest.c:251:14: note: Assuming 'i' is < 'ebcnt'
           for (i = 0; i < ebcnt; ++i) {
                       ^~~~~~~~~
   drivers/mtd/tests/subpagetest.c:251:2: note: Loop condition is true.  
Entering loop body
           for (i = 0; i < ebcnt; ++i) {
           ^
   drivers/mtd/tests/subpagetest.c:252:7: note: Assuming the condition is false
                   if (bbt[i])
                       ^~~~~~
   drivers/mtd/tests/subpagetest.c:252:3: note: Taking false branch
                   if (bbt[i])
                   ^
   drivers/mtd/tests/subpagetest.c:254:9: note: Calling 'verify_eraseblock_ff'
                   err = verify_eraseblock_ff(i);
                         ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/mtd/tests/subpagetest.c:220:14: note: Assuming the condition is true
           for (j = 0; j < mtd->erasesize / subpgsize; ++j) {
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/mtd/tests/subpagetest.c:220:2: note: Loop condition is true.  
Entering loop body
           for (j = 0; j < mtd->erasesize / subpgsize; ++j) {
           ^
   drivers/mtd/tests/subpagetest.c:222:9: note: Value assigned to 'subpgsize'
                   err = mtd_read(mtd, addr, subpgsize, &read, readbuf);
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/mtd/tests/subpagetest.c:223:16: note: Assuming 'err' is 0
                   if (unlikely(err || read != subpgsize)) {
                                ^
   include/linux/compiler.h:78:42: note: expanded from macro 'unlikely'
   # define unlikely(x)    __builtin_expect(!!(x), 0)
                                               ^
   drivers/mtd/tests/subpagetest.c:223:16: note: Left side of '||' is false
                   if (unlikely(err || read != subpgsize)) {
                                ^
   drivers/mtd/tests/subpagetest.c:223:23: note: Assuming 'read' is equal to 
'subpgsize'
                   if (unlikely(err || read != subpgsize)) {
                                       ^
   include/linux/compiler.h:78:42: note: expanded from macro 'unlikely'
   # define unlikely(x)    __builtin_expect(!!(x), 0)
                                               ^
   drivers/mtd/tests/subpagetest.c:223:3: note: Taking false branch
                   if (unlikely(err || read != subpgsize)) {
                   ^
   drivers/mtd/tests/subpagetest.c:234:3: note: Taking false branch
                   if (unlikely(memcmp(readbuf, writebuf, subpgsize))) {
                   ^
   drivers/mtd/tests/subpagetest.c:220:33: note: Division by zero
           for (j = 0; j < mtd->erasesize / subpgsize; ++j) {
                           ~~~~~~~~~~~~~~~^~~~~~~~~~~
   Suppressed 1 warnings (1 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use 
-system-headers to display errors from system headers as well.
   1 warning generated.
   Suppressed 1 warnings (1 in non-user code).
   Use -header-filter=.* to display errors from all non-system headers. Use 
-system-headers to display errors from system headers as well.
   2 warnings generated.
>> drivers/mtd/nand/raw/renesas-nand-controller.c:874:4: warning: Null pointer 
>> passed as 2nd argument to memory copy function 
>> [clang-analyzer-unix.cstring.NullArg]
                           memcpy(&last_bytes, rop.buf + (words * sizeof(u32)), 
remainder);
                           ^                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:698:6: note: Assuming 
'check_only' is false
           if (!check_only)
               ^~~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:698:2: note: Taking true 
branch
           if (!check_only)
           ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:701:18: note: Assuming 
'op_id' is < field 'ninstrs'
           for (op_id = 0; op_id < op->ninstrs; op_id++) {
                           ^~~~~~~~~~~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:701:2: note: Loop condition 
is true.  Entering loop body
           for (op_id = 0; op_id < op->ninstrs; op_id++) {
           ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:706:3: note: Control jumps to 
'case NAND_OP_DATA_OUT_INSTR:'  at line 782
                   switch (instr->type) {
                   ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:784:4: note: Value assigned 
to 'rop.buf'
                           rop.buf = instr->ctx.data.buf.in;
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:788:4: note: Control jumps to 
'case 0:'  at line 789
                           switch (data_phase++) {
                           ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:790:9: note: 'cmd_phase' is 
<= 2
                                   if (cmd_phase <= 2)
                                       ^~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:790:5: note: Taking true 
branch
                                   if (cmd_phase <= 2)
                                   ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:792:9: note: 'addr_phase' is 
<= 1
                                   if (addr_phase <= 1)
                                       ^~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:792:5: note: Taking true 
branch
                                   if (addr_phase <= 1)
                                   ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:794:9: note: 'delay_phase' is 
equal to 0
                                   if (delay_phase == 0)
                                       ^~~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:794:5: note: Taking true 
branch
                                   if (delay_phase == 0)
                                   ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:796:5: note:  Execution 
continues on line 800
                                   break;
                                   ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:800:4: note:  Execution 
continues on line 701
                           break;
                           ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:701:18: note: Assuming 
'op_id' is >= field 'ninstrs'
           for (op_id = 0; op_id < op->ninstrs; op_id++) {
                           ^~~~~~~~~~~~~~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:701:2: note: Loop condition 
is false. Execution continues on line 829
           for (op_id = 0; op_id < op->ninstrs; op_id++) {
           ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:829:6: note: Assuming field 
'buf' is null
           if (rop.buf && !rop.read)
               ^~~~~~~
   drivers/mtd/nand/raw/renesas-nand-controller.c:829:14: note: Left side of 
'&&' is false
           if (rop.buf && !rop.read)
                       ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:832:18: note: Taking false 
branch
                   rop.command |= COMMAND_SEQ_GEN_IN;
                                  ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:27:32: note: expanded from 
macro 'COMMAND_SEQ_GEN_IN'
   #define     COMMAND_SEQ_GEN_IN COMMAND_SEQ_18
                                  ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:25:28: note: expanded from 
macro 'COMMAND_SEQ_18'
   #define     COMMAND_SEQ_18 COMMAND_SEQ(0x32)
                              ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:22:26: note: expanded from 
macro 'COMMAND_SEQ'
   #define   COMMAND_SEQ(x) FIELD_PREP(GENMASK(5, 0), (x))
                            ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to 
see all)
   include/linux/compiler_types.h:335:2: note: expanded from macro 
'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, 
__COUNTER__)
           ^
   include/linux/compiler_types.h:323:2: note: expanded from macro 
'_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ^
   include/linux/compiler_types.h:315:3: note: expanded from macro 
'__compiletime_assert'
                   if (!(condition))                                       \
                   ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:832:18: note: Loop condition 
is false.  Exiting loop
                   rop.command |= COMMAND_SEQ_GEN_IN;
                                  ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:27:32: note: expanded from 
macro 'COMMAND_SEQ_GEN_IN'
   #define     COMMAND_SEQ_GEN_IN COMMAND_SEQ_18
                                  ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:25:28: note: expanded from 
macro 'COMMAND_SEQ_18'
   #define     COMMAND_SEQ_18 COMMAND_SEQ(0x32)
                              ^
   drivers/mtd/nand/raw/renesas-nand-controller.c:22:26: note: expanded from 
macro 'COMMAND_SEQ'
   #define   COMMAND_SEQ(x) FIELD_PREP(GENMASK(5, 0), (x))
                            ^
   note: (skipping 3 expansions in backtrace; use -fmacro-backtrace-limit=0 to 
see all)
   include/linux/compiler_types.h:335:2: note: expanded from macro 
'compiletime_assert'
           _compiletime_assert(condition, msg, __compiletime_assert_, 
__COUNTER__)
           ^
   include/linux/compiler_types.h:323:2: note: expanded from macro 
'_compiletime_assert'
           __compiletime_assert(condition, msg, prefix, suffix)
           ^

vim +874 drivers/mtd/nand/raw/renesas-nand-controller.c

d8701fe890ecba Miquel Raynal 2021-12-17  677  
d8701fe890ecba Miquel Raynal 2021-12-17  678  /*
d8701fe890ecba Miquel Raynal 2021-12-17  679   * This controller is simple 
enough and thus does not need to use the parser
d8701fe890ecba Miquel Raynal 2021-12-17  680   * provided by the core, instead, 
handle every situation here.
d8701fe890ecba Miquel Raynal 2021-12-17  681   */
d8701fe890ecba Miquel Raynal 2021-12-17  682  static int rnandc_exec_op(struct 
nand_chip *chip,
d8701fe890ecba Miquel Raynal 2021-12-17  683                      const struct 
nand_operation *op, bool check_only)
d8701fe890ecba Miquel Raynal 2021-12-17  684  {
d8701fe890ecba Miquel Raynal 2021-12-17  685    struct rnandc *rnandc = 
to_rnandc(chip->controller);
d8701fe890ecba Miquel Raynal 2021-12-17  686    const struct nand_op_instr 
*instr = NULL;
d8701fe890ecba Miquel Raynal 2021-12-17  687    struct rnandc_op rop = {
d8701fe890ecba Miquel Raynal 2021-12-17  688            .command = 
COMMAND_INPUT_SEL_AHBS,
d8701fe890ecba Miquel Raynal 2021-12-17  689            .gen_seq_ctrl = 
GEN_SEQ_IMD_SEQ,
d8701fe890ecba Miquel Raynal 2021-12-17  690    };
d8701fe890ecba Miquel Raynal 2021-12-17  691    unsigned int cmd_phase = 0, 
addr_phase = 0, data_phase = 0,
d8701fe890ecba Miquel Raynal 2021-12-17  692            delay_phase = 0, delays 
= 0;
d8701fe890ecba Miquel Raynal 2021-12-17  693    unsigned int op_id, col_addrs, 
row_addrs, naddrs, remainder, words, i;
d8701fe890ecba Miquel Raynal 2021-12-17  694    const u8 *addrs;
d8701fe890ecba Miquel Raynal 2021-12-17  695    u32 last_bytes;
d8701fe890ecba Miquel Raynal 2021-12-17  696    int ret;
d8701fe890ecba Miquel Raynal 2021-12-17  697  
d8701fe890ecba Miquel Raynal 2021-12-17  698    if (!check_only)
d8701fe890ecba Miquel Raynal 2021-12-17  699            
rnandc_select_target(chip, op->cs);
d8701fe890ecba Miquel Raynal 2021-12-17  700  
d8701fe890ecba Miquel Raynal 2021-12-17  701    for (op_id = 0; op_id < 
op->ninstrs; op_id++) {
d8701fe890ecba Miquel Raynal 2021-12-17  702            instr = 
&op->instrs[op_id];
d8701fe890ecba Miquel Raynal 2021-12-17  703  
d8701fe890ecba Miquel Raynal 2021-12-17  704            nand_op_trace("  ", 
instr);
d8701fe890ecba Miquel Raynal 2021-12-17  705  
d8701fe890ecba Miquel Raynal 2021-12-17  706            switch (instr->type) {
d8701fe890ecba Miquel Raynal 2021-12-17  707            case NAND_OP_CMD_INSTR:
d8701fe890ecba Miquel Raynal 2021-12-17  708                    switch 
(cmd_phase++) {
d8701fe890ecba Miquel Raynal 2021-12-17  709                    case 0:
d8701fe890ecba Miquel Raynal 2021-12-17  710                            
rop.command |= COMMAND_0(instr->ctx.cmd.opcode);
d8701fe890ecba Miquel Raynal 2021-12-17  711                            
rop.gen_seq_ctrl |= GEN_SEQ_CMD0_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  712                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  713                    case 1:
d8701fe890ecba Miquel Raynal 2021-12-17  714                            
rop.gen_seq_ctrl |= GEN_SEQ_COMMAND_3(instr->ctx.cmd.opcode);
d8701fe890ecba Miquel Raynal 2021-12-17  715                            
rop.gen_seq_ctrl |= GEN_SEQ_CMD3_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  716                            if 
(addr_phase == 0)
d8701fe890ecba Miquel Raynal 2021-12-17  717                                    
addr_phase = 1;
d8701fe890ecba Miquel Raynal 2021-12-17  718                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  719                    case 2:
d8701fe890ecba Miquel Raynal 2021-12-17  720                            
rop.command |= COMMAND_2(instr->ctx.cmd.opcode);
d8701fe890ecba Miquel Raynal 2021-12-17  721                            
rop.gen_seq_ctrl |= GEN_SEQ_CMD2_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  722                            if 
(addr_phase <= 1)
d8701fe890ecba Miquel Raynal 2021-12-17  723                                    
addr_phase = 2;
d8701fe890ecba Miquel Raynal 2021-12-17  724                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  725                    case 3:
d8701fe890ecba Miquel Raynal 2021-12-17  726                            
rop.command |= COMMAND_1(instr->ctx.cmd.opcode);
d8701fe890ecba Miquel Raynal 2021-12-17  727                            
rop.gen_seq_ctrl |= GEN_SEQ_CMD1_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  728                            if 
(addr_phase <= 1)
d8701fe890ecba Miquel Raynal 2021-12-17  729                                    
addr_phase = 2;
d8701fe890ecba Miquel Raynal 2021-12-17  730                            if 
(delay_phase == 0)
d8701fe890ecba Miquel Raynal 2021-12-17  731                                    
delay_phase = 1;
d8701fe890ecba Miquel Raynal 2021-12-17  732                            if 
(data_phase == 0)
d8701fe890ecba Miquel Raynal 2021-12-17  733                                    
data_phase = 1;
d8701fe890ecba Miquel Raynal 2021-12-17  734                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  735                    default:
d8701fe890ecba Miquel Raynal 2021-12-17  736                            return 
-EOPNOTSUPP;
d8701fe890ecba Miquel Raynal 2021-12-17  737                    }
d8701fe890ecba Miquel Raynal 2021-12-17  738                    break;
d8701fe890ecba Miquel Raynal 2021-12-17  739  
d8701fe890ecba Miquel Raynal 2021-12-17  740            case NAND_OP_ADDR_INSTR:
d8701fe890ecba Miquel Raynal 2021-12-17  741                    addrs = 
instr->ctx.addr.addrs;
d8701fe890ecba Miquel Raynal 2021-12-17  742                    naddrs = 
instr->ctx.addr.naddrs;
d8701fe890ecba Miquel Raynal 2021-12-17  743                    if (naddrs > 5)
d8701fe890ecba Miquel Raynal 2021-12-17  744                            return 
-EOPNOTSUPP;
d8701fe890ecba Miquel Raynal 2021-12-17  745  
d8701fe890ecba Miquel Raynal 2021-12-17  746                    col_addrs = 
min(2U, naddrs);
d8701fe890ecba Miquel Raynal 2021-12-17  747                    row_addrs = 
naddrs > 2 ? naddrs - col_addrs : 0;
d8701fe890ecba Miquel Raynal 2021-12-17  748  
d8701fe890ecba Miquel Raynal 2021-12-17  749                    switch 
(addr_phase++) {
d8701fe890ecba Miquel Raynal 2021-12-17  750                    case 0:
d8701fe890ecba Miquel Raynal 2021-12-17  751                            for (i 
= 0; i < col_addrs; i++)
d8701fe890ecba Miquel Raynal 2021-12-17  752                                    
rop.addr0_col |= addrs[i] << (i * 8);
d8701fe890ecba Miquel Raynal 2021-12-17  753                            
rop.gen_seq_ctrl |= GEN_SEQ_COL_A0(col_addrs);
d8701fe890ecba Miquel Raynal 2021-12-17  754  
d8701fe890ecba Miquel Raynal 2021-12-17  755                            for (i 
= 0; i < row_addrs; i++)
d8701fe890ecba Miquel Raynal 2021-12-17  756                                    
rop.addr0_row |= addrs[2 + i] << (i * 8);
d8701fe890ecba Miquel Raynal 2021-12-17  757                            
rop.gen_seq_ctrl |= GEN_SEQ_ROW_A0(row_addrs);
d8701fe890ecba Miquel Raynal 2021-12-17  758  
d8701fe890ecba Miquel Raynal 2021-12-17  759                            if 
(cmd_phase == 0)
d8701fe890ecba Miquel Raynal 2021-12-17  760                                    
cmd_phase = 1;
d8701fe890ecba Miquel Raynal 2021-12-17  761                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  762                    case 1:
d8701fe890ecba Miquel Raynal 2021-12-17  763                            for (i 
= 0; i < col_addrs; i++)
d8701fe890ecba Miquel Raynal 2021-12-17  764                                    
rop.addr1_col |= addrs[i] << (i * 8);
d8701fe890ecba Miquel Raynal 2021-12-17  765                            
rop.gen_seq_ctrl |= GEN_SEQ_COL_A1(col_addrs);
d8701fe890ecba Miquel Raynal 2021-12-17  766  
d8701fe890ecba Miquel Raynal 2021-12-17  767                            for (i 
= 0; i < row_addrs; i++)
d8701fe890ecba Miquel Raynal 2021-12-17  768                                    
rop.addr1_row |= addrs[2 + i] << (i * 8);
d8701fe890ecba Miquel Raynal 2021-12-17  769                            
rop.gen_seq_ctrl |= GEN_SEQ_ROW_A1(row_addrs);
d8701fe890ecba Miquel Raynal 2021-12-17  770  
d8701fe890ecba Miquel Raynal 2021-12-17  771                            if 
(cmd_phase <= 1)
d8701fe890ecba Miquel Raynal 2021-12-17  772                                    
cmd_phase = 2;
d8701fe890ecba Miquel Raynal 2021-12-17  773                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  774                    default:
d8701fe890ecba Miquel Raynal 2021-12-17  775                            return 
-EOPNOTSUPP;
d8701fe890ecba Miquel Raynal 2021-12-17  776                    }
d8701fe890ecba Miquel Raynal 2021-12-17  777                    break;
d8701fe890ecba Miquel Raynal 2021-12-17  778  
d8701fe890ecba Miquel Raynal 2021-12-17  779            case 
NAND_OP_DATA_IN_INSTR:
d8701fe890ecba Miquel Raynal 2021-12-17  780                    rop.read = true;
d8701fe890ecba Miquel Raynal 2021-12-17  781                    fallthrough;
d8701fe890ecba Miquel Raynal 2021-12-17  782            case 
NAND_OP_DATA_OUT_INSTR:
d8701fe890ecba Miquel Raynal 2021-12-17  783                    
rop.gen_seq_ctrl |= GEN_SEQ_DATA_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  784                    rop.buf = 
instr->ctx.data.buf.in;
d8701fe890ecba Miquel Raynal 2021-12-17  785                    rop.len = 
instr->ctx.data.len;
d8701fe890ecba Miquel Raynal 2021-12-17  786                    rop.command |= 
COMMAND_FIFO_SEL;
d8701fe890ecba Miquel Raynal 2021-12-17  787  
d8701fe890ecba Miquel Raynal 2021-12-17  788                    switch 
(data_phase++) {
d8701fe890ecba Miquel Raynal 2021-12-17  789                    case 0:
d8701fe890ecba Miquel Raynal 2021-12-17  790                            if 
(cmd_phase <= 2)
d8701fe890ecba Miquel Raynal 2021-12-17  791                                    
cmd_phase = 3;
d8701fe890ecba Miquel Raynal 2021-12-17  792                            if 
(addr_phase <= 1)
d8701fe890ecba Miquel Raynal 2021-12-17  793                                    
addr_phase = 2;
d8701fe890ecba Miquel Raynal 2021-12-17  794                            if 
(delay_phase == 0)
d8701fe890ecba Miquel Raynal 2021-12-17  795                                    
delay_phase = 1;
d8701fe890ecba Miquel Raynal 2021-12-17  796                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  797                    default:
d8701fe890ecba Miquel Raynal 2021-12-17  798                            return 
-EOPNOTSUPP;
d8701fe890ecba Miquel Raynal 2021-12-17  799                    }
d8701fe890ecba Miquel Raynal 2021-12-17  800                    break;
d8701fe890ecba Miquel Raynal 2021-12-17  801  
d8701fe890ecba Miquel Raynal 2021-12-17  802            case 
NAND_OP_WAITRDY_INSTR:
d8701fe890ecba Miquel Raynal 2021-12-17  803                    switch 
(delay_phase++) {
d8701fe890ecba Miquel Raynal 2021-12-17  804                    case 0:
d8701fe890ecba Miquel Raynal 2021-12-17  805                            
rop.gen_seq_ctrl |= GEN_SEQ_DELAY0_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  806  
d8701fe890ecba Miquel Raynal 2021-12-17  807                            if 
(cmd_phase <= 2)
d8701fe890ecba Miquel Raynal 2021-12-17  808                                    
cmd_phase = 3;
d8701fe890ecba Miquel Raynal 2021-12-17  809                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  810                    case 1:
d8701fe890ecba Miquel Raynal 2021-12-17  811                            
rop.gen_seq_ctrl |= GEN_SEQ_DELAY1_EN;
d8701fe890ecba Miquel Raynal 2021-12-17  812  
d8701fe890ecba Miquel Raynal 2021-12-17  813                            if 
(cmd_phase <= 3)
d8701fe890ecba Miquel Raynal 2021-12-17  814                                    
cmd_phase = 4;
d8701fe890ecba Miquel Raynal 2021-12-17  815                            if 
(data_phase == 0)
d8701fe890ecba Miquel Raynal 2021-12-17  816                                    
data_phase = 1;
d8701fe890ecba Miquel Raynal 2021-12-17  817                            break;
d8701fe890ecba Miquel Raynal 2021-12-17  818                    default:
d8701fe890ecba Miquel Raynal 2021-12-17  819                            return 
-EOPNOTSUPP;
d8701fe890ecba Miquel Raynal 2021-12-17  820                    }
d8701fe890ecba Miquel Raynal 2021-12-17  821                    break;
d8701fe890ecba Miquel Raynal 2021-12-17  822            }
d8701fe890ecba Miquel Raynal 2021-12-17  823    }
d8701fe890ecba Miquel Raynal 2021-12-17  824  
d8701fe890ecba Miquel Raynal 2021-12-17  825    /*
d8701fe890ecba Miquel Raynal 2021-12-17  826     * Sequence 19 is generic and 
dedicated to write operations.
d8701fe890ecba Miquel Raynal 2021-12-17  827     * Sequence 18 is also generic 
and works for all other operations.
d8701fe890ecba Miquel Raynal 2021-12-17  828     */
d8701fe890ecba Miquel Raynal 2021-12-17  829    if (rop.buf && !rop.read)
d8701fe890ecba Miquel Raynal 2021-12-17  830            rop.command |= 
COMMAND_SEQ_GEN_OUT;
d8701fe890ecba Miquel Raynal 2021-12-17  831    else
d8701fe890ecba Miquel Raynal 2021-12-17  832            rop.command |= 
COMMAND_SEQ_GEN_IN;
d8701fe890ecba Miquel Raynal 2021-12-17  833  
d8701fe890ecba Miquel Raynal 2021-12-17  834    if (delays > 1) {
d8701fe890ecba Miquel Raynal 2021-12-17  835            dev_err(rnandc->dev, 
"Cannot handle more than one wait delay\n");
d8701fe890ecba Miquel Raynal 2021-12-17  836            return -EOPNOTSUPP;
d8701fe890ecba Miquel Raynal 2021-12-17  837    }
d8701fe890ecba Miquel Raynal 2021-12-17  838  
d8701fe890ecba Miquel Raynal 2021-12-17  839    if (check_only)
d8701fe890ecba Miquel Raynal 2021-12-17  840            return 0;
d8701fe890ecba Miquel Raynal 2021-12-17  841  
d8701fe890ecba Miquel Raynal 2021-12-17  842    rnandc_trigger_op(rnandc, &rop);
d8701fe890ecba Miquel Raynal 2021-12-17  843  
d8701fe890ecba Miquel Raynal 2021-12-17  844    words = rop.len / sizeof(u32);
d8701fe890ecba Miquel Raynal 2021-12-17  845    remainder = rop.len % 
sizeof(u32);
d8701fe890ecba Miquel Raynal 2021-12-17  846    if (rop.buf && rop.read) {
d8701fe890ecba Miquel Raynal 2021-12-17  847            while 
(!FIFO_STATE_C_EMPTY(readl(rnandc->regs + FIFO_STATE_REG)))
d8701fe890ecba Miquel Raynal 2021-12-17  848                    cpu_relax();
d8701fe890ecba Miquel Raynal 2021-12-17  849  
d8701fe890ecba Miquel Raynal 2021-12-17  850            while 
(FIFO_STATE_R_EMPTY(readl(rnandc->regs + FIFO_STATE_REG)))
d8701fe890ecba Miquel Raynal 2021-12-17  851                    cpu_relax();
d8701fe890ecba Miquel Raynal 2021-12-17  852  
d8701fe890ecba Miquel Raynal 2021-12-17  853            
ioread32_rep(rnandc->regs + FIFO_DATA_REG, rop.buf, words);
d8701fe890ecba Miquel Raynal 2021-12-17  854            if (remainder) {
d8701fe890ecba Miquel Raynal 2021-12-17  855                    last_bytes = 
readl_relaxed(rnandc->regs + FIFO_DATA_REG);
d8701fe890ecba Miquel Raynal 2021-12-17  856                    memcpy(rop.buf 
+ (words * sizeof(u32)), &last_bytes,
d8701fe890ecba Miquel Raynal 2021-12-17  857                           
remainder);
d8701fe890ecba Miquel Raynal 2021-12-17  858            }
d8701fe890ecba Miquel Raynal 2021-12-17  859  
d8701fe890ecba Miquel Raynal 2021-12-17  860            if 
(!FIFO_STATE_R_EMPTY(readl(rnandc->regs + FIFO_STATE_REG))) {
d8701fe890ecba Miquel Raynal 2021-12-17  861                    
dev_warn(rnandc->dev,
d8701fe890ecba Miquel Raynal 2021-12-17  862                             
"Clearing residual data in the read FIFO\n");
d8701fe890ecba Miquel Raynal 2021-12-17  863                    
rnandc_clear_fifo(rnandc);
d8701fe890ecba Miquel Raynal 2021-12-17  864            }
d8701fe890ecba Miquel Raynal 2021-12-17  865    } else if (rop.len && 
!rop.read) {
d8701fe890ecba Miquel Raynal 2021-12-17  866            while 
(FIFO_STATE_W_FULL(readl(rnandc->regs + FIFO_STATE_REG)))
d8701fe890ecba Miquel Raynal 2021-12-17  867                    cpu_relax();
d8701fe890ecba Miquel Raynal 2021-12-17  868  
d8701fe890ecba Miquel Raynal 2021-12-17  869            
iowrite32_rep(rnandc->regs + FIFO_DATA_REG, rop.buf,
d8701fe890ecba Miquel Raynal 2021-12-17  870                          
DIV_ROUND_UP(rop.len, 4));
d8701fe890ecba Miquel Raynal 2021-12-17  871  
d8701fe890ecba Miquel Raynal 2021-12-17  872            if (remainder) {
d8701fe890ecba Miquel Raynal 2021-12-17  873                    last_bytes = 0;
d8701fe890ecba Miquel Raynal 2021-12-17 @874                    
memcpy(&last_bytes, rop.buf + (words * sizeof(u32)), remainder);
d8701fe890ecba Miquel Raynal 2021-12-17  875                    
writel_relaxed(last_bytes, rnandc->regs + FIFO_DATA_REG);
d8701fe890ecba Miquel Raynal 2021-12-17  876            }
d8701fe890ecba Miquel Raynal 2021-12-17  877  
d8701fe890ecba Miquel Raynal 2021-12-17  878            while 
(!FIFO_STATE_W_EMPTY(readl(rnandc->regs + FIFO_STATE_REG)))
d8701fe890ecba Miquel Raynal 2021-12-17  879                    cpu_relax();
d8701fe890ecba Miquel Raynal 2021-12-17  880    }
d8701fe890ecba Miquel Raynal 2021-12-17  881  
d8701fe890ecba Miquel Raynal 2021-12-17  882    ret = 
rnandc_wait_end_of_op(rnandc, chip);
d8701fe890ecba Miquel Raynal 2021-12-17  883    if (ret)
d8701fe890ecba Miquel Raynal 2021-12-17  884            return ret;
d8701fe890ecba Miquel Raynal 2021-12-17  885  
d8701fe890ecba Miquel Raynal 2021-12-17  886    return 0;
d8701fe890ecba Miquel Raynal 2021-12-17  887  }
d8701fe890ecba Miquel Raynal 2021-12-17  888  

---
0-DAY CI Kernel Test Service
https://lists.01.org/hyperkitty/list/[email protected]
_______________________________________________
kbuild mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to