0054-mtd-add-chunked-read-io-to-m25p80.patch 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. --- a/drivers/mtd/spi-nor/spi-nor.c
  2. +++ b/drivers/mtd/spi-nor/spi-nor.c
  3. @@ -1014,6 +1014,66 @@ write_err:
  4. return ret;
  5. }
  6. +static int spi_nor_chunked_write(struct mtd_info *mtd, loff_t _to, size_t _len,
  7. + size_t *_retlen, const u_char *_buf)
  8. +{
  9. + struct spi_nor *nor = mtd_to_spi_nor(mtd);
  10. + int chunk_size;
  11. + int retlen = 0;
  12. + int ret;
  13. +
  14. + chunk_size = nor->chunk_size;
  15. + if (!chunk_size)
  16. + chunk_size = _len;
  17. +
  18. + if (nor->addr_width > 3)
  19. + chunk_size -= nor->addr_width - 3;
  20. +
  21. + while (retlen < _len) {
  22. + size_t len = min_t(int, chunk_size, _len - retlen);
  23. + const u_char *buf = _buf + retlen;
  24. + loff_t to = _to + retlen;
  25. +
  26. + if (nor->flags & SNOR_F_SST)
  27. + ret = sst_write(mtd, to, len, &retlen, buf);
  28. + else
  29. + ret = spi_nor_write(mtd, to, len, &retlen, buf);
  30. + if (ret)
  31. + return ret;
  32. + }
  33. +
  34. + *_retlen += retlen;
  35. + return 0;
  36. +}
  37. +
  38. +static int spi_nor_chunked_read(struct mtd_info *mtd, loff_t _from, size_t _len,
  39. + size_t *_retlen, u_char *_buf)
  40. +{
  41. + struct spi_nor *nor = mtd_to_spi_nor(mtd);
  42. + int chunk_size;
  43. + int ret;
  44. +
  45. + chunk_size = nor->chunk_size;
  46. + if (!chunk_size)
  47. + chunk_size = _len;
  48. +
  49. + *_retlen = 0;
  50. + while (*_retlen < _len) {
  51. + size_t len = min_t(int, chunk_size, _len - *_retlen);
  52. + u_char *buf = _buf + *_retlen;
  53. + loff_t from = _from + *_retlen;
  54. + int retlen = 0;
  55. +
  56. + ret = spi_nor_read(mtd, from, len, &retlen, buf);
  57. + if (ret)
  58. + return ret;
  59. +
  60. + *_retlen += retlen;
  61. + }
  62. +
  63. + return 0;
  64. +}
  65. +
  66. static int macronix_quad_enable(struct spi_nor *nor)
  67. {
  68. int ret, val;
  69. @@ -1201,10 +1261,12 @@ int spi_nor_scan(struct spi_nor *nor, co
  70. }
  71. /* sst nor chips use AAI word program */
  72. - if (info->flags & SST_WRITE)
  73. + if (info->flags & SST_WRITE) {
  74. mtd->_write = sst_write;
  75. - else
  76. + nor->flags |= SNOR_F_SST;
  77. + } else {
  78. mtd->_write = spi_nor_write;
  79. + }
  80. if (info->flags & USE_FSR)
  81. nor->flags |= SNOR_F_USE_FSR;
  82. @@ -1232,11 +1294,20 @@ int spi_nor_scan(struct spi_nor *nor, co
  83. mtd->writebufsize = nor->page_size;
  84. if (np) {
  85. + u32 val;
  86. +
  87. /* If we were instantiated by DT, use it */
  88. if (of_property_read_bool(np, "m25p,fast-read"))
  89. nor->flash_read = SPI_NOR_FAST;
  90. else
  91. nor->flash_read = SPI_NOR_NORMAL;
  92. +
  93. + if (!of_property_read_u32(np, "m25p,chunked-io", &val)) {
  94. + dev_info(dev, "using chunked io (size=%d)\n", val);
  95. + mtd->_read = spi_nor_chunked_read;
  96. + mtd->_write = spi_nor_chunked_write;
  97. + nor->chunk_size = val;
  98. + }
  99. } else {
  100. /* If we weren't instantiated by DT, default to fast-read */
  101. nor->flash_read = SPI_NOR_FAST;
  102. --- a/include/linux/mtd/spi-nor.h
  103. +++ b/include/linux/mtd/spi-nor.h
  104. @@ -116,6 +116,7 @@ enum spi_nor_ops {
  105. enum spi_nor_option_flags {
  106. SNOR_F_USE_FSR = BIT(0),
  107. + SNOR_F_SST = BIT(1),
  108. };
  109. /**
  110. @@ -156,6 +157,7 @@ struct spi_nor {
  111. struct device *dev;
  112. struct device_node *flash_node;
  113. u32 page_size;
  114. + u16 chunk_size;
  115. u8 addr_width;
  116. u8 erase_opcode;
  117. u8 read_opcode;