Hi Boris, I love your patch! Yet something to improve: [auto build test ERROR on char-misc/char-misc-testing] [also build test ERROR on v5.1-rc3 next-20190401] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Boris-Brezillon/eeprom-at25-Convert-the-driver-to-the-spi-mem-interface/20190401-160450 config: x86_64-randconfig-m3-201913 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): drivers/misc/eeprom/at25.o: In function `at25_rdsr': >> drivers/misc/eeprom/at25.c:130: undefined reference to `spi_mem_exec_op' drivers/misc/eeprom/at25.o: In function `at25_ee_read': >> drivers/misc/eeprom/at25.c:178: undefined reference to `spi_mem_dirmap_read' drivers/misc/eeprom/at25.o: In function `at25_create_dirmaps': >> drivers/misc/eeprom/at25.c:86: undefined reference to `devm_spi_mem_dirmap_create' drivers/misc/eeprom/at25.c:94: undefined reference to `devm_spi_mem_dirmap_create' drivers/misc/eeprom/at25.c:106: undefined reference to `devm_spi_mem_dirmap_create' drivers/misc/eeprom/at25.c:114: undefined reference to `devm_spi_mem_dirmap_create' drivers/misc/eeprom/at25.o: In function `at25_wren': drivers/misc/eeprom/at25.c:144: undefined reference to `spi_mem_exec_op' drivers/misc/eeprom/at25.o: In function `at25_ee_write': >> drivers/misc/eeprom/at25.c:240: undefined reference to `spi_mem_dirmap_write' drivers/misc/eeprom/at25.o: In function `at25_driver_init': >> drivers/misc/eeprom/at25.c:468: undefined reference to `spi_mem_driver_register_with_owner' drivers/misc/eeprom/at25.o: In function `at25_driver_exit': >> drivers/misc/eeprom/at25.c:468: undefined reference to `spi_mem_driver_unregister' vim +130 drivers/misc/eeprom/at25.c 70 71 static int at25_create_dirmaps(struct at25_data *at25) 72 { 73 struct spi_mem_dirmap_info info = { 74 .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(AT25_READ, 1), 75 SPI_MEM_OP_ADDR(at25->addrlen, 0, 1), 76 SPI_MEM_OP_NO_DUMMY, 77 SPI_MEM_OP_DATA_IN(0, NULL, 1)), 78 .offset = 0, 79 .length = at25->chip.byte_len, 80 }; 81 struct device *dev = &at25->spimem->spi->dev; 82 83 if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR) 84 info.length = 256; 85 > 86 at25->dirmap.rdesc[0] = devm_spi_mem_dirmap_create(dev, at25->spimem, 87 &info); 88 if (IS_ERR(at25->dirmap.rdesc[0])) 89 return PTR_ERR(at25->dirmap.rdesc[0]); 90 91 info.op_tmpl.cmd.opcode = AT25_WRITE; 92 info.op_tmpl.data.dir = SPI_MEM_DATA_OUT; 93 94 at25->dirmap.wdesc[0] = devm_spi_mem_dirmap_create(dev, at25->spimem, 95 &info); 96 if (IS_ERR(at25->dirmap.wdesc[0])) 97 return PTR_ERR(at25->dirmap.wdesc[0]); 98 99 if (!(at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)) 100 return 0; 101 102 info.length = at25->chip.byte_len - 256; 103 info.op_tmpl.cmd.opcode = AT25_READ | AT25_INSTR_BIT3; 104 info.op_tmpl.data.dir = SPI_MEM_DATA_IN; 105 > 106 at25->dirmap.rdesc[1] = devm_spi_mem_dirmap_create(dev, at25->spimem, 107 &info); 108 if (IS_ERR(at25->dirmap.rdesc[1])) 109 return PTR_ERR(at25->dirmap.rdesc[1]); 110 111 info.op_tmpl.cmd.opcode = AT25_WRITE | AT25_INSTR_BIT3; 112 info.op_tmpl.data.dir = SPI_MEM_DATA_OUT; 113 114 at25->dirmap.wdesc[1] = devm_spi_mem_dirmap_create(dev, at25->spimem, 115 &info); 116 if (IS_ERR(at25->dirmap.wdesc[1])) 117 return PTR_ERR(at25->dirmap.wdesc[1]); 118 119 return 0; 120 } 121 122 static int at25_rdsr(struct at25_data *at25) 123 { 124 struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(AT25_RDSR, 1), 125 SPI_MEM_OP_NO_ADDR, 126 SPI_MEM_OP_NO_DUMMY, 127 SPI_MEM_OP_DATA_IN(1, at25->scratchbuf, 1)); 128 int ret; 129 > 130 ret = spi_mem_exec_op(at25->spimem, &op); 131 if (ret) 132 return ret; 133 134 return *((u8 *)at25->scratchbuf); 135 } 136 137 static int at25_wren(struct at25_data *at25) 138 { 139 struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(AT25_WREN, 1), 140 SPI_MEM_OP_NO_ADDR, 141 SPI_MEM_OP_NO_DUMMY, 142 SPI_MEM_OP_NO_DATA); 143 144 return spi_mem_exec_op(at25->spimem, &op); 145 } 146 147 static int at25_ee_read(void *priv, unsigned int offset, 148 void *val, size_t count) 149 { 150 struct spi_mem_dirmap_desc *desc; 151 struct at25_data *at25 = priv; 152 unsigned int dirmap_offset; 153 ssize_t status; 154 155 if (unlikely(offset >= at25->chip.byte_len)) 156 return -EINVAL; 157 if ((offset + count) > at25->chip.byte_len) 158 count = at25->chip.byte_len - offset; 159 if (unlikely(!count)) 160 return -EINVAL; 161 162 if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR && offset > 255) { 163 desc = at25->dirmap.rdesc[1]; 164 dirmap_offset = offset - 256; 165 } else { 166 desc = at25->dirmap.rdesc[0]; 167 dirmap_offset = offset; 168 } 169 170 mutex_lock(&at25->lock); 171 172 /* Read it all at once. 173 * 174 * REVISIT that's potentially a problem with large chips, if 175 * other devices on the bus need to be accessed regularly or 176 * this chip is clocked very slowly 177 */ > 178 status = spi_mem_dirmap_read(desc, dirmap_offset, count, val); 179 dev_dbg(&at25->spimem->spi->dev, "read %zu bytes at %d --> %zd\n", 180 count, offset, status); 181 182 mutex_unlock(&at25->lock); 183 return status; 184 } 185 186 static int at25_ee_write(void *priv, unsigned int off, void *val, size_t count) 187 { 188 struct at25_data *at25 = priv; 189 const char *buf = val; 190 int status = 0; 191 unsigned buf_size; 192 u8 *bounce; 193 194 if (unlikely(off >= at25->chip.byte_len)) 195 return -EFBIG; 196 if ((off + count) > at25->chip.byte_len) 197 count = at25->chip.byte_len - off; 198 if (unlikely(!count)) 199 return -EINVAL; 200 201 /* Temp buffer starts with command and address */ 202 buf_size = at25->chip.page_size; 203 if (buf_size > io_limit) 204 buf_size = io_limit; 205 bounce = kmalloc(buf_size, GFP_KERNEL); 206 if (!bounce) 207 return -ENOMEM; 208 209 /* For write, rollover is within the page ... so we write at 210 * most one page, then manually roll over to the next page. 211 */ 212 mutex_lock(&at25->lock); 213 do { 214 struct spi_mem_dirmap_desc *desc; 215 unsigned long timeout, retries; 216 unsigned segment; 217 unsigned int dirmap_offset; 218 int sr; 219 220 status = at25_wren(at25); 221 if (status < 0) { 222 dev_dbg(&at25->spimem->spi->dev, "WREN --> %d\n", 223 status); 224 break; 225 } 226 227 if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR && off > 255) { 228 desc = at25->dirmap.wdesc[1]; 229 dirmap_offset = off - 256; 230 } else { 231 desc = at25->dirmap.wdesc[0]; 232 dirmap_offset = off; 233 } 234 235 /* Write as much of a page as we can */ 236 segment = buf_size - (dirmap_offset % buf_size); 237 if (segment > count) 238 segment = count; 239 memcpy(bounce, buf, segment); > 240 status = spi_mem_dirmap_write(desc, dirmap_offset, segment, 241 bounce); 242 dev_dbg(&at25->spimem->spi->dev, 243 "write %u bytes at %u --> %d\n", 244 segment, off, status); 245 if (status < 0) 246 break; 247 248 /* REVISIT this should detect (or prevent) failed writes 249 * to readonly sections of the EEPROM... 250 */ 251 252 /* Wait for non-busy status */ 253 timeout = jiffies + msecs_to_jiffies(EE_TIMEOUT); 254 retries = 0; 255 do { 256 sr = at25_rdsr(at25); 257 if (sr < 0 || (sr & AT25_SR_nRDY)) { 258 dev_dbg(&at25->spimem->spi->dev, 259 "rdsr --> %d (%02x)\n", sr, sr); 260 /* at HZ=100, this is sloooow */ 261 msleep(1); 262 continue; 263 } 264 if (!(sr & AT25_SR_nRDY)) 265 break; 266 } while (retries++ < 3 || time_before_eq(jiffies, timeout)); 267 268 if ((sr < 0) || (sr & AT25_SR_nRDY)) { 269 dev_err(&at25->spimem->spi->dev, 270 "write %u bytes offset %u, timeout after %u msecs\n", 271 segment, off, 272 jiffies_to_msecs(jiffies - 273 (timeout - EE_TIMEOUT))); 274 status = -ETIMEDOUT; 275 break; 276 } 277 278 off += segment; 279 buf += segment; 280 count -= segment; 281 282 } while (count > 0); 283 284 mutex_unlock(&at25->lock); 285 286 kfree(bounce); 287 return status; 288 } 289 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Attachment:
.config.gz
Description: application/gzip
______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/