iomem_copy.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright 2024 Kalray, Inc. All Rights Reserved.
  4. */
  5. #include <linux/align.h>
  6. #include <linux/export.h>
  7. #include <linux/io.h>
  8. #include <linux/types.h>
  9. #include <linux/unaligned.h>
  10. #ifndef memset_io
  11. /**
  12. * memset_io() - Set a range of I/O memory to a constant value
  13. * @addr: The beginning of the I/O-memory range to set
  14. * @val: The value to set the memory to
  15. * @count: The number of bytes to set
  16. *
  17. * Set a range of I/O memory to a given value.
  18. */
  19. void memset_io(volatile void __iomem *addr, int val, size_t count)
  20. {
  21. long qc = (u8)val;
  22. qc *= ~0UL / 0xff;
  23. while (count && !IS_ALIGNED((long)addr, sizeof(long))) {
  24. __raw_writeb(val, addr);
  25. addr++;
  26. count--;
  27. }
  28. while (count >= sizeof(long)) {
  29. #ifdef CONFIG_64BIT
  30. __raw_writeq(qc, addr);
  31. #else
  32. __raw_writel(qc, addr);
  33. #endif
  34. addr += sizeof(long);
  35. count -= sizeof(long);
  36. }
  37. while (count) {
  38. __raw_writeb(val, addr);
  39. addr++;
  40. count--;
  41. }
  42. }
  43. EXPORT_SYMBOL(memset_io);
  44. #endif
  45. #ifndef memcpy_fromio
  46. /**
  47. * memcpy_fromio() - Copy a block of data from I/O memory
  48. * @dst: The (RAM) destination for the copy
  49. * @src: The (I/O memory) source for the data
  50. * @count: The number of bytes to copy
  51. *
  52. * Copy a block of data from I/O memory.
  53. */
  54. void memcpy_fromio(void *dst, const volatile void __iomem *src, size_t count)
  55. {
  56. while (count && !IS_ALIGNED((long)src, sizeof(long))) {
  57. *(u8 *)dst = __raw_readb(src);
  58. src++;
  59. dst++;
  60. count--;
  61. }
  62. while (count >= sizeof(long)) {
  63. #ifdef CONFIG_64BIT
  64. long val = __raw_readq(src);
  65. #else
  66. long val = __raw_readl(src);
  67. #endif
  68. put_unaligned(val, (long *)dst);
  69. src += sizeof(long);
  70. dst += sizeof(long);
  71. count -= sizeof(long);
  72. }
  73. while (count) {
  74. *(u8 *)dst = __raw_readb(src);
  75. src++;
  76. dst++;
  77. count--;
  78. }
  79. }
  80. EXPORT_SYMBOL(memcpy_fromio);
  81. #endif
  82. #ifndef memcpy_toio
  83. /**
  84. * memcpy_toio() -Copy a block of data into I/O memory
  85. * @dst: The (I/O memory) destination for the copy
  86. * @src: The (RAM) source for the data
  87. * @count: The number of bytes to copy
  88. *
  89. * Copy a block of data to I/O memory.
  90. */
  91. void memcpy_toio(volatile void __iomem *dst, const void *src, size_t count)
  92. {
  93. while (count && !IS_ALIGNED((long)dst, sizeof(long))) {
  94. __raw_writeb(*(u8 *)src, dst);
  95. src++;
  96. dst++;
  97. count--;
  98. }
  99. while (count >= sizeof(long)) {
  100. long val = get_unaligned((long *)src);
  101. #ifdef CONFIG_64BIT
  102. __raw_writeq(val, dst);
  103. #else
  104. __raw_writel(val, dst);
  105. #endif
  106. src += sizeof(long);
  107. dst += sizeof(long);
  108. count -= sizeof(long);
  109. }
  110. while (count) {
  111. __raw_writeb(*(u8 *)src, dst);
  112. src++;
  113. dst++;
  114. count--;
  115. }
  116. }
  117. EXPORT_SYMBOL(memcpy_toio);
  118. #endif