logic_pio.c 8.5 KB

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