iwl-io.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved.
  4. *
  5. * Portions of this file are derived from the ipw3945 project.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of version 2 of the GNU General Public License as
  9. * published by the Free Software Foundation.
  10. *
  11. * This program is distributed in the hope that it will be useful, but WITHOUT
  12. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  14. * more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along with
  17. * this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19. *
  20. * The full GNU General Public License is included in this distribution in the
  21. * file called LICENSE.
  22. *
  23. * Contact Information:
  24. * Intel Linux Wireless <ilw@linux.intel.com>
  25. * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  26. *
  27. *****************************************************************************/
  28. #include <linux/delay.h>
  29. #include <linux/device.h>
  30. #include <linux/export.h>
  31. #include "iwl-io.h"
  32. #include "iwl-csr.h"
  33. #include "iwl-debug.h"
  34. #define IWL_POLL_INTERVAL 10 /* microseconds */
  35. void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
  36. {
  37. iwl_write32(trans, reg, iwl_read32(trans, reg) | mask);
  38. }
  39. void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
  40. {
  41. iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask);
  42. }
  43. void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask)
  44. {
  45. unsigned long flags;
  46. spin_lock_irqsave(&trans->reg_lock, flags);
  47. __iwl_set_bit(trans, reg, mask);
  48. spin_unlock_irqrestore(&trans->reg_lock, flags);
  49. }
  50. EXPORT_SYMBOL_GPL(iwl_set_bit);
  51. void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask)
  52. {
  53. unsigned long flags;
  54. spin_lock_irqsave(&trans->reg_lock, flags);
  55. __iwl_clear_bit(trans, reg, mask);
  56. spin_unlock_irqrestore(&trans->reg_lock, flags);
  57. }
  58. EXPORT_SYMBOL_GPL(iwl_clear_bit);
  59. void iwl_set_bits_mask(struct iwl_trans *trans, u32 reg, u32 mask, u32 value)
  60. {
  61. unsigned long flags;
  62. u32 v;
  63. #ifdef CONFIG_IWLWIFI_DEBUG
  64. WARN_ON_ONCE(value & ~mask);
  65. #endif
  66. spin_lock_irqsave(&trans->reg_lock, flags);
  67. v = iwl_read32(trans, reg);
  68. v &= ~mask;
  69. v |= value;
  70. iwl_write32(trans, reg, v);
  71. spin_unlock_irqrestore(&trans->reg_lock, flags);
  72. }
  73. EXPORT_SYMBOL_GPL(iwl_set_bits_mask);
  74. int iwl_poll_bit(struct iwl_trans *trans, u32 addr,
  75. u32 bits, u32 mask, int timeout)
  76. {
  77. int t = 0;
  78. do {
  79. if ((iwl_read32(trans, addr) & mask) == (bits & mask))
  80. return t;
  81. udelay(IWL_POLL_INTERVAL);
  82. t += IWL_POLL_INTERVAL;
  83. } while (t < timeout);
  84. return -ETIMEDOUT;
  85. }
  86. EXPORT_SYMBOL_GPL(iwl_poll_bit);
  87. u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg)
  88. {
  89. u32 value = 0x5a5a5a5a;
  90. unsigned long flags;
  91. spin_lock_irqsave(&trans->reg_lock, flags);
  92. if (iwl_trans_grab_nic_access(trans, false)) {
  93. value = iwl_read32(trans, reg);
  94. iwl_trans_release_nic_access(trans);
  95. }
  96. spin_unlock_irqrestore(&trans->reg_lock, flags);
  97. return value;
  98. }
  99. EXPORT_SYMBOL_GPL(iwl_read_direct32);
  100. void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value)
  101. {
  102. unsigned long flags;
  103. spin_lock_irqsave(&trans->reg_lock, flags);
  104. if (iwl_trans_grab_nic_access(trans, false)) {
  105. iwl_write32(trans, reg, value);
  106. iwl_trans_release_nic_access(trans);
  107. }
  108. spin_unlock_irqrestore(&trans->reg_lock, flags);
  109. }
  110. EXPORT_SYMBOL_GPL(iwl_write_direct32);
  111. int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask,
  112. int timeout)
  113. {
  114. int t = 0;
  115. do {
  116. if ((iwl_read_direct32(trans, addr) & mask) == mask)
  117. return t;
  118. udelay(IWL_POLL_INTERVAL);
  119. t += IWL_POLL_INTERVAL;
  120. } while (t < timeout);
  121. return -ETIMEDOUT;
  122. }
  123. EXPORT_SYMBOL_GPL(iwl_poll_direct_bit);
  124. static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 ofs)
  125. {
  126. u32 val = iwl_trans_read_prph(trans, ofs);
  127. trace_iwlwifi_dev_ioread_prph32(trans->dev, ofs, val);
  128. return val;
  129. }
  130. static inline void __iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
  131. {
  132. trace_iwlwifi_dev_iowrite_prph32(trans->dev, ofs, val);
  133. iwl_trans_write_prph(trans, ofs, val);
  134. }
  135. u32 iwl_read_prph(struct iwl_trans *trans, u32 ofs)
  136. {
  137. unsigned long flags;
  138. u32 val = 0x5a5a5a5a;
  139. spin_lock_irqsave(&trans->reg_lock, flags);
  140. if (iwl_trans_grab_nic_access(trans, false)) {
  141. val = __iwl_read_prph(trans, ofs);
  142. iwl_trans_release_nic_access(trans);
  143. }
  144. spin_unlock_irqrestore(&trans->reg_lock, flags);
  145. return val;
  146. }
  147. EXPORT_SYMBOL_GPL(iwl_read_prph);
  148. void iwl_write_prph(struct iwl_trans *trans, u32 ofs, u32 val)
  149. {
  150. unsigned long flags;
  151. spin_lock_irqsave(&trans->reg_lock, flags);
  152. if (iwl_trans_grab_nic_access(trans, false)) {
  153. __iwl_write_prph(trans, ofs, val);
  154. iwl_trans_release_nic_access(trans);
  155. }
  156. spin_unlock_irqrestore(&trans->reg_lock, flags);
  157. }
  158. EXPORT_SYMBOL_GPL(iwl_write_prph);
  159. void iwl_set_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
  160. {
  161. unsigned long flags;
  162. spin_lock_irqsave(&trans->reg_lock, flags);
  163. if (iwl_trans_grab_nic_access(trans, false)) {
  164. __iwl_write_prph(trans, ofs,
  165. __iwl_read_prph(trans, ofs) | mask);
  166. iwl_trans_release_nic_access(trans);
  167. }
  168. spin_unlock_irqrestore(&trans->reg_lock, flags);
  169. }
  170. EXPORT_SYMBOL_GPL(iwl_set_bits_prph);
  171. void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 ofs,
  172. u32 bits, u32 mask)
  173. {
  174. unsigned long flags;
  175. spin_lock_irqsave(&trans->reg_lock, flags);
  176. if (iwl_trans_grab_nic_access(trans, false)) {
  177. __iwl_write_prph(trans, ofs,
  178. (__iwl_read_prph(trans, ofs) & mask) | bits);
  179. iwl_trans_release_nic_access(trans);
  180. }
  181. spin_unlock_irqrestore(&trans->reg_lock, flags);
  182. }
  183. EXPORT_SYMBOL_GPL(iwl_set_bits_mask_prph);
  184. void iwl_clear_bits_prph(struct iwl_trans *trans, u32 ofs, u32 mask)
  185. {
  186. unsigned long flags;
  187. u32 val;
  188. spin_lock_irqsave(&trans->reg_lock, flags);
  189. if (iwl_trans_grab_nic_access(trans, false)) {
  190. val = __iwl_read_prph(trans, ofs);
  191. __iwl_write_prph(trans, ofs, (val & ~mask));
  192. iwl_trans_release_nic_access(trans);
  193. }
  194. spin_unlock_irqrestore(&trans->reg_lock, flags);
  195. }
  196. EXPORT_SYMBOL_GPL(iwl_clear_bits_prph);