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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. --- a/drivers/mtd/spi-nor/spi-nor.c
  2. +++ b/drivers/mtd/spi-nor/spi-nor.c
  3. @@ -1381,6 +1381,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. @@ -1630,10 +1690,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. @@ -1663,11 +1725,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. @@ -141,6 +141,7 @@ enum spi_nor_option_flags {
  105. SNOR_F_NO_OP_CHIP_ERASE = BIT(2),
  106. SNOR_F_S3AN_ADDR_DEFAULT = BIT(3),
  107. SNOR_F_READY_XSR_RDY = BIT(4),
  108. + SNOR_F_SST = BIT(5),
  109. };
  110. /**
  111. @@ -180,6 +181,7 @@ struct spi_nor {
  112. struct mutex lock;
  113. struct device *dev;
  114. u32 page_size;
  115. + u16 chunk_size;
  116. u8 addr_width;
  117. u8 erase_opcode;
  118. u8 read_opcode;