logic_pio.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved.
  4. * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
  5. * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
  6. */
  7. #define pr_fmt(fmt) "LOGIC PIO: " fmt
  8. #include <linux/of.h>
  9. #include <linux/io.h>
  10. #include <linux/logic_pio.h>
  11. #include <linux/mm.h>
  12. #include <linux/rculist.h>
  13. #include <linux/sizes.h>
  14. #include <linux/slab.h>
  15. /* The unique hardware address list */
  16. static LIST_HEAD(io_range_list);
  17. static DEFINE_MUTEX(io_range_mutex);
  18. /* Consider a kernel general helper for this */
  19. #define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len))
  20. /**
  21. * logic_pio_register_range - register logical PIO range for a host
  22. * @new_range: pointer to the IO range to be registered.
  23. *
  24. * Returns 0 on success, the error code in case of failure.
  25. *
  26. * Register a new IO range node in the IO range list.
  27. */
  28. int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
  29. {
  30. struct logic_pio_hwaddr *range;
  31. resource_size_t start;
  32. resource_size_t end;
  33. resource_size_t mmio_end = 0;
  34. resource_size_t iio_sz = MMIO_UPPER_LIMIT;
  35. int ret = 0;
  36. if (!new_range || !new_range->fwnode || !new_range->size)
  37. return -EINVAL;
  38. start = new_range->hw_start;
  39. end = new_range->hw_start + new_range->size;
  40. mutex_lock(&io_range_mutex);
  41. list_for_each_entry(range, &io_range_list, list) {
  42. if (range->fwnode == new_range->fwnode) {
  43. /* range already there */
  44. goto end_register;
  45. }
  46. if (range->flags == LOGIC_PIO_CPU_MMIO &&
  47. new_range->flags == LOGIC_PIO_CPU_MMIO) {
  48. /* for MMIO ranges we need to check for overlap */
  49. if (start >= range->hw_start + range->size ||
  50. end < range->hw_start) {
  51. mmio_end = range->io_start + range->size;
  52. } else {
  53. ret = -EFAULT;
  54. goto end_register;
  55. }
  56. } else if (range->flags == LOGIC_PIO_INDIRECT &&
  57. new_range->flags == LOGIC_PIO_INDIRECT) {
  58. iio_sz += range->size;
  59. }
  60. }
  61. /* range not registered yet, check for available space */
  62. if (new_range->flags == LOGIC_PIO_CPU_MMIO) {
  63. if (mmio_end + new_range->size - 1 > MMIO_UPPER_LIMIT) {
  64. /* if it's too big check if 64K space can be reserved */
  65. if (mmio_end + SZ_64K - 1 > MMIO_UPPER_LIMIT) {
  66. ret = -E2BIG;
  67. goto end_register;
  68. }
  69. new_range->size = SZ_64K;
  70. pr_warn("Requested IO range too big, new size set to 64K\n");
  71. }
  72. new_range->io_start = mmio_end;
  73. } else if (new_range->flags == LOGIC_PIO_INDIRECT) {
  74. if (iio_sz + new_range->size - 1 > IO_SPACE_LIMIT) {
  75. ret = -E2BIG;
  76. goto end_register;
  77. }
  78. new_range->io_start = iio_sz;
  79. } else {
  80. /* invalid flag */
  81. ret = -EINVAL;
  82. goto end_register;
  83. }
  84. list_add_tail_rcu(&new_range->list, &io_range_list);
  85. end_register:
  86. mutex_unlock(&io_range_mutex);
  87. return ret;
  88. }
  89. /**
  90. * logic_pio_unregister_range - unregister a logical PIO range for a host
  91. * @range: pointer to the IO range which has been already registered.
  92. *
  93. * Unregister a previously-registered IO range node.
  94. */
  95. void logic_pio_unregister_range(struct logic_pio_hwaddr *range)
  96. {
  97. mutex_lock(&io_range_mutex);
  98. list_del_rcu(&range->list);
  99. mutex_unlock(&io_range_mutex);
  100. synchronize_rcu();
  101. }
  102. /**
  103. * find_io_range_by_fwnode - find logical PIO range for given FW node
  104. * @fwnode: FW node handle associated with logical PIO range
  105. *
  106. * Returns pointer to node on success, NULL otherwise.
  107. *
  108. * Traverse the io_range_list to find the registered node for @fwnode.
  109. */
  110. struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode)
  111. {
  112. struct logic_pio_hwaddr *range, *found_range = NULL;
  113. rcu_read_lock();
  114. list_for_each_entry_rcu(range, &io_range_list, list) {
  115. if (range->fwnode == fwnode) {
  116. found_range = range;
  117. break;
  118. }
  119. }
  120. rcu_read_unlock();
  121. return found_range;
  122. }
  123. /* Return a registered range given an input PIO token */
  124. static struct logic_pio_hwaddr *find_io_range(unsigned long pio)
  125. {
  126. struct logic_pio_hwaddr *range, *found_range = NULL;
  127. rcu_read_lock();
  128. list_for_each_entry_rcu(range, &io_range_list, list) {
  129. if (in_range(pio, range->io_start, range->size)) {
  130. found_range = range;
  131. break;
  132. }
  133. }
  134. rcu_read_unlock();
  135. if (!found_range)
  136. pr_err("PIO entry token 0x%lx invalid\n", pio);
  137. return found_range;
  138. }
  139. /**
  140. * logic_pio_to_hwaddr - translate logical PIO to HW address
  141. * @pio: logical PIO value
  142. *
  143. * Returns HW address if valid, ~0 otherwise.
  144. *
  145. * Translate the input logical PIO to the corresponding hardware address.
  146. * The input PIO should be unique in the whole logical PIO space.
  147. */
  148. resource_size_t logic_pio_to_hwaddr(unsigned long pio)
  149. {
  150. struct logic_pio_hwaddr *range;
  151. range = find_io_range(pio);
  152. if (range)
  153. return range->hw_start + pio - range->io_start;
  154. return (resource_size_t)~0;
  155. }
  156. /**
  157. * logic_pio_trans_hwaddr - translate HW address to logical PIO
  158. * @fwnode: FW node reference for the host
  159. * @addr: Host-relative HW address
  160. * @size: size to translate
  161. *
  162. * Returns Logical PIO value if successful, ~0UL otherwise
  163. */
  164. unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode,
  165. resource_size_t addr, resource_size_t size)
  166. {
  167. struct logic_pio_hwaddr *range;
  168. range = find_io_range_by_fwnode(fwnode);
  169. if (!range || range->flags == LOGIC_PIO_CPU_MMIO) {
  170. pr_err("IO range not found or invalid\n");
  171. return ~0UL;
  172. }
  173. if (range->size < size) {
  174. pr_err("resource size %pa cannot fit in IO range size %pa\n",
  175. &size, &range->size);
  176. return ~0UL;
  177. }
  178. return addr - range->hw_start + range->io_start;
  179. }
  180. unsigned long logic_pio_trans_cpuaddr(resource_size_t addr)
  181. {
  182. struct logic_pio_hwaddr *range;
  183. rcu_read_lock();
  184. list_for_each_entry_rcu(range, &io_range_list, list) {
  185. if (range->flags != LOGIC_PIO_CPU_MMIO)
  186. continue;
  187. if (in_range(addr, range->hw_start, range->size)) {
  188. unsigned long cpuaddr;
  189. cpuaddr = addr - range->hw_start + range->io_start;
  190. rcu_read_unlock();
  191. return cpuaddr;
  192. }
  193. }
  194. rcu_read_unlock();
  195. pr_err("addr %pa not registered in io_range_list\n", &addr);
  196. return ~0UL;
  197. }
  198. #if defined(CONFIG_INDIRECT_PIO) && defined(PCI_IOBASE)
  199. #define BUILD_LOGIC_IO(bw, type) \
  200. type logic_in##bw(unsigned long addr) \
  201. { \
  202. type ret = (type)~0; \
  203. \
  204. if (addr < MMIO_UPPER_LIMIT) { \
  205. ret = read##bw(PCI_IOBASE + addr); \
  206. } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
  207. struct logic_pio_hwaddr *entry = find_io_range(addr); \
  208. \
  209. if (entry && entry->ops) \
  210. ret = entry->ops->in(entry->hostdata, \
  211. addr, sizeof(type)); \
  212. else \
  213. WARN_ON_ONCE(1); \
  214. } \
  215. return ret; \
  216. } \
  217. \
  218. void logic_out##bw(type value, unsigned long addr) \
  219. { \
  220. if (addr < MMIO_UPPER_LIMIT) { \
  221. write##bw(value, PCI_IOBASE + addr); \
  222. } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
  223. struct logic_pio_hwaddr *entry = find_io_range(addr); \
  224. \
  225. if (entry && entry->ops) \
  226. entry->ops->out(entry->hostdata, \
  227. addr, value, sizeof(type)); \
  228. else \
  229. WARN_ON_ONCE(1); \
  230. } \
  231. } \
  232. \
  233. void logic_ins##bw(unsigned long addr, void *buffer, \
  234. unsigned int count) \
  235. { \
  236. if (addr < MMIO_UPPER_LIMIT) { \
  237. reads##bw(PCI_IOBASE + addr, buffer, count); \
  238. } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
  239. struct logic_pio_hwaddr *entry = find_io_range(addr); \
  240. \
  241. if (entry && entry->ops) \
  242. entry->ops->ins(entry->hostdata, \
  243. addr, buffer, sizeof(type), count); \
  244. else \
  245. WARN_ON_ONCE(1); \
  246. } \
  247. \
  248. } \
  249. \
  250. void logic_outs##bw(unsigned long addr, const void *buffer, \
  251. unsigned int count) \
  252. { \
  253. if (addr < MMIO_UPPER_LIMIT) { \
  254. writes##bw(PCI_IOBASE + addr, buffer, count); \
  255. } else if (addr >= MMIO_UPPER_LIMIT && addr < IO_SPACE_LIMIT) { \
  256. struct logic_pio_hwaddr *entry = find_io_range(addr); \
  257. \
  258. if (entry && entry->ops) \
  259. entry->ops->outs(entry->hostdata, \
  260. addr, buffer, sizeof(type), count); \
  261. else \
  262. WARN_ON_ONCE(1); \
  263. } \
  264. }
  265. BUILD_LOGIC_IO(b, u8)
  266. EXPORT_SYMBOL(logic_inb);
  267. EXPORT_SYMBOL(logic_insb);
  268. EXPORT_SYMBOL(logic_outb);
  269. EXPORT_SYMBOL(logic_outsb);
  270. BUILD_LOGIC_IO(w, u16)
  271. EXPORT_SYMBOL(logic_inw);
  272. EXPORT_SYMBOL(logic_insw);
  273. EXPORT_SYMBOL(logic_outw);
  274. EXPORT_SYMBOL(logic_outsw);
  275. BUILD_LOGIC_IO(l, u32)
  276. EXPORT_SYMBOL(logic_inl);
  277. EXPORT_SYMBOL(logic_insl);
  278. EXPORT_SYMBOL(logic_outl);
  279. EXPORT_SYMBOL(logic_outsl);
  280. #endif /* CONFIG_INDIRECT_PIO && PCI_IOBASE */