io.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/export.h>
  3. #include <linux/types.h>
  4. #include <linux/io.h>
  5. #include <linux/spinlock.h>
  6. static DEFINE_RAW_SPINLOCK(__io_lock);
  7. /*
  8. * Generic atomic MMIO modify.
  9. *
  10. * Allows thread-safe access to registers shared by unrelated subsystems.
  11. * The access is protected by a single MMIO-wide lock.
  12. */
  13. void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set)
  14. {
  15. unsigned long flags;
  16. u32 value;
  17. raw_spin_lock_irqsave(&__io_lock, flags);
  18. value = readl_relaxed(reg) & ~mask;
  19. value |= (set & mask);
  20. writel_relaxed(value, reg);
  21. raw_spin_unlock_irqrestore(&__io_lock, flags);
  22. }
  23. EXPORT_SYMBOL(atomic_io_modify_relaxed);
  24. void atomic_io_modify(void __iomem *reg, u32 mask, u32 set)
  25. {
  26. unsigned long flags;
  27. u32 value;
  28. raw_spin_lock_irqsave(&__io_lock, flags);
  29. value = readl_relaxed(reg) & ~mask;
  30. value |= (set & mask);
  31. writel(value, reg);
  32. raw_spin_unlock_irqrestore(&__io_lock, flags);
  33. }
  34. EXPORT_SYMBOL(atomic_io_modify);
  35. /*
  36. * Copy data from IO memory space to "real" memory space.
  37. * This needs to be optimized.
  38. */
  39. void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
  40. {
  41. unsigned char *t = to;
  42. while (count) {
  43. count--;
  44. *t = readb(from);
  45. t++;
  46. from++;
  47. }
  48. }
  49. EXPORT_SYMBOL(_memcpy_fromio);
  50. /*
  51. * Copy data from "real" memory space to IO memory space.
  52. * This needs to be optimized.
  53. */
  54. void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
  55. {
  56. const unsigned char *f = from;
  57. while (count) {
  58. count--;
  59. writeb(*f, to);
  60. f++;
  61. to++;
  62. }
  63. }
  64. EXPORT_SYMBOL(_memcpy_toio);
  65. /*
  66. * "memset" on IO memory space.
  67. * This needs to be optimized.
  68. */
  69. void _memset_io(volatile void __iomem *dst, int c, size_t count)
  70. {
  71. while (count) {
  72. count--;
  73. writeb(c, dst);
  74. dst++;
  75. }
  76. }
  77. EXPORT_SYMBOL(_memset_io);