aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorVitaly Wool <vwool@ru.mvista.com>2006-01-08 16:34:28 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-13 19:29:56 -0500
commit8275c642ccdce09a2146d0a9eb022e3698ee927e (patch)
treeea330810f665fcbdf36d31b0da1643db528ad83f /drivers/mtd
parent2f9f762879015d738a5ec2ac8a16be94b3a4a06d (diff)
[PATCH] spi: use linked lists rather than an array
This makes the SPI core and its users access transfers in the SPI message structure as linked list not as an array, as discussed on LKML. From: David Brownell <dbrownell@users.sourceforge.net> Updates including doc, bugfixes to the list code, add spi_message_add_tail(). Plus, initialize things _before_ grabbing the locks in some cases (in case it grows more expensive). This also merges some bitbang updates of mine that didn't yet make it into the mm tree. Signed-off-by: Vitaly Wool <vwool@ru.mvista.com> Signed-off-by: Dmitry Pervushin <dpervushin@gmail.com> Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/devices/m25p80.c50
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c28
2 files changed, 42 insertions, 36 deletions
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 71a072103a7f..45108ed85588 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -245,6 +245,21 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
245 if (from + len > flash->mtd.size) 245 if (from + len > flash->mtd.size)
246 return -EINVAL; 246 return -EINVAL;
247 247
248 spi_message_init(&m);
249 memset(t, 0, (sizeof t));
250
251 t[0].tx_buf = flash->command;
252 t[0].len = sizeof(flash->command);
253 spi_message_add_tail(&t[0], &m);
254
255 t[1].rx_buf = buf;
256 t[1].len = len;
257 spi_message_add_tail(&t[1], &m);
258
259 /* Byte count starts at zero. */
260 if (retlen)
261 *retlen = 0;
262
248 down(&flash->lock); 263 down(&flash->lock);
249 264
250 /* Wait till previous write/erase is done. */ 265 /* Wait till previous write/erase is done. */
@@ -254,8 +269,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
254 return 1; 269 return 1;
255 } 270 }
256 271
257 memset(t, 0, (sizeof t));
258
259 /* NOTE: OPCODE_FAST_READ (if available) is faster... */ 272 /* NOTE: OPCODE_FAST_READ (if available) is faster... */
260 273
261 /* Set up the write data buffer. */ 274 /* Set up the write data buffer. */
@@ -264,19 +277,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len,
264 flash->command[2] = from >> 8; 277 flash->command[2] = from >> 8;
265 flash->command[3] = from; 278 flash->command[3] = from;
266 279
267 /* Byte count starts at zero. */
268 if (retlen)
269 *retlen = 0;
270
271 t[0].tx_buf = flash->command;
272 t[0].len = sizeof(flash->command);
273
274 t[1].rx_buf = buf;
275 t[1].len = len;
276
277 m.transfers = t;
278 m.n_transfer = 2;
279
280 spi_sync(flash->spi, &m); 280 spi_sync(flash->spi, &m);
281 281
282 *retlen = m.actual_length - sizeof(flash->command); 282 *retlen = m.actual_length - sizeof(flash->command);
@@ -313,6 +313,16 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
313 if (to + len > flash->mtd.size) 313 if (to + len > flash->mtd.size)
314 return -EINVAL; 314 return -EINVAL;
315 315
316 spi_message_init(&m);
317 memset(t, 0, (sizeof t));
318
319 t[0].tx_buf = flash->command;
320 t[0].len = sizeof(flash->command);
321 spi_message_add_tail(&t[0], &m);
322
323 t[1].tx_buf = buf;
324 spi_message_add_tail(&t[1], &m);
325
316 down(&flash->lock); 326 down(&flash->lock);
317 327
318 /* Wait until finished previous write command. */ 328 /* Wait until finished previous write command. */
@@ -321,26 +331,17 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
321 331
322 write_enable(flash); 332 write_enable(flash);
323 333
324 memset(t, 0, (sizeof t));
325
326 /* Set up the opcode in the write buffer. */ 334 /* Set up the opcode in the write buffer. */
327 flash->command[0] = OPCODE_PP; 335 flash->command[0] = OPCODE_PP;
328 flash->command[1] = to >> 16; 336 flash->command[1] = to >> 16;
329 flash->command[2] = to >> 8; 337 flash->command[2] = to >> 8;
330 flash->command[3] = to; 338 flash->command[3] = to;
331 339
332 t[0].tx_buf = flash->command;
333 t[0].len = sizeof(flash->command);
334
335 m.transfers = t;
336 m.n_transfer = 2;
337
338 /* what page do we start with? */ 340 /* what page do we start with? */
339 page_offset = to % FLASH_PAGESIZE; 341 page_offset = to % FLASH_PAGESIZE;
340 342
341 /* do all the bytes fit onto one page? */ 343 /* do all the bytes fit onto one page? */
342 if (page_offset + len <= FLASH_PAGESIZE) { 344 if (page_offset + len <= FLASH_PAGESIZE) {
343 t[1].tx_buf = buf;
344 t[1].len = len; 345 t[1].len = len;
345 346
346 spi_sync(flash->spi, &m); 347 spi_sync(flash->spi, &m);
@@ -352,7 +353,6 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len,
352 /* the size of data remaining on the first page */ 353 /* the size of data remaining on the first page */
353 page_size = FLASH_PAGESIZE - page_offset; 354 page_size = FLASH_PAGESIZE - page_offset;
354 355
355 t[1].tx_buf = buf;
356 t[1].len = page_size; 356 t[1].len = page_size;
357 spi_sync(flash->spi, &m); 357 spi_sync(flash->spi, &m);
358 358
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index a39b3b6b266c..99d3a0320fc9 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -147,7 +147,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
147{ 147{
148 struct dataflash *priv = (struct dataflash *)mtd->priv; 148 struct dataflash *priv = (struct dataflash *)mtd->priv;
149 struct spi_device *spi = priv->spi; 149 struct spi_device *spi = priv->spi;
150 struct spi_transfer x[1] = { { .tx_dma = 0, }, }; 150 struct spi_transfer x = { .tx_dma = 0, };
151 struct spi_message msg; 151 struct spi_message msg;
152 unsigned blocksize = priv->page_size << 3; 152 unsigned blocksize = priv->page_size << 3;
153 u8 *command; 153 u8 *command;
@@ -162,10 +162,11 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
162 || (instr->addr % priv->page_size) != 0) 162 || (instr->addr % priv->page_size) != 0)
163 return -EINVAL; 163 return -EINVAL;
164 164
165 x[0].tx_buf = command = priv->command; 165 spi_message_init(&msg);
166 x[0].len = 4; 166
167 msg.transfers = x; 167 x.tx_buf = command = priv->command;
168 msg.n_transfer = 1; 168 x.len = 4;
169 spi_message_add_tail(&x, &msg);
169 170
170 down(&priv->lock); 171 down(&priv->lock);
171 while (instr->len > 0) { 172 while (instr->len > 0) {
@@ -256,12 +257,15 @@ static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len,
256 DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n", 257 DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n",
257 command[0], command[1], command[2], command[3]); 258 command[0], command[1], command[2], command[3]);
258 259
260 spi_message_init(&msg);
261
259 x[0].tx_buf = command; 262 x[0].tx_buf = command;
260 x[0].len = 8; 263 x[0].len = 8;
264 spi_message_add_tail(&x[0], &msg);
265
261 x[1].rx_buf = buf; 266 x[1].rx_buf = buf;
262 x[1].len = len; 267 x[1].len = len;
263 msg.transfers = x; 268 spi_message_add_tail(&x[1], &msg);
264 msg.n_transfer = 2;
265 269
266 down(&priv->lock); 270 down(&priv->lock);
267 271
@@ -320,9 +324,11 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
320 if ((to + len) > mtd->size) 324 if ((to + len) > mtd->size)
321 return -EINVAL; 325 return -EINVAL;
322 326
327 spi_message_init(&msg);
328
323 x[0].tx_buf = command = priv->command; 329 x[0].tx_buf = command = priv->command;
324 x[0].len = 4; 330 x[0].len = 4;
325 msg.transfers = x; 331 spi_message_add_tail(&x[0], &msg);
326 332
327 pageaddr = ((unsigned)to / priv->page_size); 333 pageaddr = ((unsigned)to / priv->page_size);
328 offset = ((unsigned)to % priv->page_size); 334 offset = ((unsigned)to % priv->page_size);
@@ -364,7 +370,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
364 DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n", 370 DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n",
365 command[0], command[1], command[2], command[3]); 371 command[0], command[1], command[2], command[3]);
366 372
367 msg.n_transfer = 1;
368 status = spi_sync(spi, &msg); 373 status = spi_sync(spi, &msg);
369 if (status < 0) 374 if (status < 0)
370 DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n", 375 DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n",
@@ -385,14 +390,16 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
385 390
386 x[1].tx_buf = writebuf; 391 x[1].tx_buf = writebuf;
387 x[1].len = writelen; 392 x[1].len = writelen;
388 msg.n_transfer = 2; 393 spi_message_add_tail(x + 1, &msg);
389 status = spi_sync(spi, &msg); 394 status = spi_sync(spi, &msg);
395 spi_transfer_del(x + 1);
390 if (status < 0) 396 if (status < 0)
391 DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n", 397 DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n",
392 spi->dev.bus_id, addr, writelen, status); 398 spi->dev.bus_id, addr, writelen, status);
393 399
394 (void) dataflash_waitready(priv->spi); 400 (void) dataflash_waitready(priv->spi);
395 401
402
396#ifdef CONFIG_DATAFLASH_WRITE_VERIFY 403#ifdef CONFIG_DATAFLASH_WRITE_VERIFY
397 404
398 /* (3) Compare to Buffer1 */ 405 /* (3) Compare to Buffer1 */
@@ -405,7 +412,6 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
405 DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n", 412 DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n",
406 command[0], command[1], command[2], command[3]); 413 command[0], command[1], command[2], command[3]);
407 414
408 msg.n_transfer = 1;
409 status = spi_sync(spi, &msg); 415 status = spi_sync(spi, &msg);
410 if (status < 0) 416 if (status < 0)
411 DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n", 417 DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n",