logic_pio.c 8.5 KB

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