rio-access.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /*
  2. * RapidIO configuration space access support
  3. *
  4. * Copyright 2005 MontaVista Software, Inc.
  5. * Matt Porter <mporter@kernel.crashing.org>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. */
  12. #include <linux/rio.h>
  13. #include <linux/module.h>
  14. /*
  15. * These interrupt-safe spinlocks protect all accesses to RIO
  16. * configuration space and doorbell access.
  17. */
  18. static DEFINE_SPINLOCK(rio_config_lock);
  19. static DEFINE_SPINLOCK(rio_doorbell_lock);
  20. /*
  21. * Wrappers for all RIO configuration access functions. They just check
  22. * alignment, do locking and call the low-level functions pointed to
  23. * by rio_mport->ops.
  24. */
  25. #define RIO_8_BAD 0
  26. #define RIO_16_BAD (offset & 1)
  27. #define RIO_32_BAD (offset & 3)
  28. /**
  29. * RIO_LOP_READ - Generate rio_local_read_config_* functions
  30. * @size: Size of configuration space read (8, 16, 32 bits)
  31. * @type: C type of value argument
  32. * @len: Length of configuration space read (1, 2, 4 bytes)
  33. *
  34. * Generates rio_local_read_config_* functions used to access
  35. * configuration space registers on the local device.
  36. */
  37. #define RIO_LOP_READ(size,type,len) \
  38. int __rio_local_read_config_##size \
  39. (struct rio_mport *mport, u32 offset, type *value) \
  40. { \
  41. int res; \
  42. unsigned long flags; \
  43. u32 data = 0; \
  44. if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
  45. spin_lock_irqsave(&rio_config_lock, flags); \
  46. res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
  47. *value = (type)data; \
  48. spin_unlock_irqrestore(&rio_config_lock, flags); \
  49. return res; \
  50. }
  51. /**
  52. * RIO_LOP_WRITE - Generate rio_local_write_config_* functions
  53. * @size: Size of configuration space write (8, 16, 32 bits)
  54. * @type: C type of value argument
  55. * @len: Length of configuration space write (1, 2, 4 bytes)
  56. *
  57. * Generates rio_local_write_config_* functions used to access
  58. * configuration space registers on the local device.
  59. */
  60. #define RIO_LOP_WRITE(size,type,len) \
  61. int __rio_local_write_config_##size \
  62. (struct rio_mport *mport, u32 offset, type value) \
  63. { \
  64. int res; \
  65. unsigned long flags; \
  66. if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
  67. spin_lock_irqsave(&rio_config_lock, flags); \
  68. res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
  69. spin_unlock_irqrestore(&rio_config_lock, flags); \
  70. return res; \
  71. }
  72. RIO_LOP_READ(8, u8, 1)
  73. RIO_LOP_READ(16, u16, 2)
  74. RIO_LOP_READ(32, u32, 4)
  75. RIO_LOP_WRITE(8, u8, 1)
  76. RIO_LOP_WRITE(16, u16, 2)
  77. RIO_LOP_WRITE(32, u32, 4)
  78. EXPORT_SYMBOL_GPL(__rio_local_read_config_8);
  79. EXPORT_SYMBOL_GPL(__rio_local_read_config_16);
  80. EXPORT_SYMBOL_GPL(__rio_local_read_config_32);
  81. EXPORT_SYMBOL_GPL(__rio_local_write_config_8);
  82. EXPORT_SYMBOL_GPL(__rio_local_write_config_16);
  83. EXPORT_SYMBOL_GPL(__rio_local_write_config_32);
  84. /**
  85. * RIO_OP_READ - Generate rio_mport_read_config_* functions
  86. * @size: Size of configuration space read (8, 16, 32 bits)
  87. * @type: C type of value argument
  88. * @len: Length of configuration space read (1, 2, 4 bytes)
  89. *
  90. * Generates rio_mport_read_config_* functions used to access
  91. * configuration space registers on the local device.
  92. */
  93. #define RIO_OP_READ(size,type,len) \
  94. int rio_mport_read_config_##size \
  95. (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
  96. { \
  97. int res; \
  98. unsigned long flags; \
  99. u32 data = 0; \
  100. if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
  101. spin_lock_irqsave(&rio_config_lock, flags); \
  102. res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
  103. *value = (type)data; \
  104. spin_unlock_irqrestore(&rio_config_lock, flags); \
  105. return res; \
  106. }
  107. /**
  108. * RIO_OP_WRITE - Generate rio_mport_write_config_* functions
  109. * @size: Size of configuration space write (8, 16, 32 bits)
  110. * @type: C type of value argument
  111. * @len: Length of configuration space write (1, 2, 4 bytes)
  112. *
  113. * Generates rio_mport_write_config_* functions used to access
  114. * configuration space registers on the local device.
  115. */
  116. #define RIO_OP_WRITE(size,type,len) \
  117. int rio_mport_write_config_##size \
  118. (struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
  119. { \
  120. int res; \
  121. unsigned long flags; \
  122. if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
  123. spin_lock_irqsave(&rio_config_lock, flags); \
  124. res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
  125. spin_unlock_irqrestore(&rio_config_lock, flags); \
  126. return res; \
  127. }
  128. RIO_OP_READ(8, u8, 1)
  129. RIO_OP_READ(16, u16, 2)
  130. RIO_OP_READ(32, u32, 4)
  131. RIO_OP_WRITE(8, u8, 1)
  132. RIO_OP_WRITE(16, u16, 2)
  133. RIO_OP_WRITE(32, u32, 4)
  134. EXPORT_SYMBOL_GPL(rio_mport_read_config_8);
  135. EXPORT_SYMBOL_GPL(rio_mport_read_config_16);
  136. EXPORT_SYMBOL_GPL(rio_mport_read_config_32);
  137. EXPORT_SYMBOL_GPL(rio_mport_write_config_8);
  138. EXPORT_SYMBOL_GPL(rio_mport_write_config_16);
  139. EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
  140. /**
  141. * rio_mport_send_doorbell - Send a doorbell message
  142. *
  143. * @mport: RIO master port
  144. * @destid: RIO device destination ID
  145. * @data: Doorbell message data
  146. *
  147. * Send a doorbell message to a RIO device. The doorbell message
  148. * has a 16-bit info field provided by the data argument.
  149. */
  150. int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
  151. {
  152. int res;
  153. unsigned long flags;
  154. spin_lock_irqsave(&rio_doorbell_lock, flags);
  155. res = mport->ops->dsend(mport, mport->id, destid, data);
  156. spin_unlock_irqrestore(&rio_doorbell_lock, flags);
  157. return res;
  158. }
  159. EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);