system-bus.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*
  2. * PS3 system bus driver.
  3. *
  4. * Copyright (C) 2006 Sony Computer Entertainment Inc.
  5. * Copyright 2006 Sony Corp.
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; version 2 of the License.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include <linux/kernel.h>
  21. #include <linux/init.h>
  22. #include <linux/module.h>
  23. #include <linux/dma-mapping.h>
  24. #include <linux/err.h>
  25. #include <asm/udbg.h>
  26. #include <asm/lv1call.h>
  27. #include <asm/firmware.h>
  28. #include "platform.h"
  29. #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
  30. static void _dump_mmio_region(const struct ps3_mmio_region* r,
  31. const char* func, int line)
  32. {
  33. pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id,
  34. r->did.dev_id);
  35. pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
  36. pr_debug("%s:%d: len %lxh\n", func, line, r->len);
  37. pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
  38. }
  39. int ps3_mmio_region_create(struct ps3_mmio_region *r)
  40. {
  41. int result;
  42. result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id,
  43. r->bus_addr, r->len, r->page_size, &r->lpar_addr);
  44. if (result) {
  45. pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
  46. __func__, __LINE__, ps3_result(result));
  47. r->lpar_addr = 0;
  48. }
  49. dump_mmio_region(r);
  50. return result;
  51. }
  52. int ps3_free_mmio_region(struct ps3_mmio_region *r)
  53. {
  54. int result;
  55. result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id,
  56. r->lpar_addr);
  57. if (result)
  58. pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
  59. __func__, __LINE__, ps3_result(result));
  60. r->lpar_addr = 0;
  61. return result;
  62. }
  63. static int ps3_system_bus_match(struct device *_dev,
  64. struct device_driver *_drv)
  65. {
  66. int result;
  67. struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv);
  68. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  69. result = dev->match_id == drv->match_id;
  70. pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__,
  71. dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name,
  72. (result ? "match" : "miss"));
  73. return result;
  74. }
  75. static int ps3_system_bus_probe(struct device *_dev)
  76. {
  77. int result;
  78. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  79. struct ps3_system_bus_driver *drv =
  80. to_ps3_system_bus_driver(_dev->driver);
  81. result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
  82. if (result) {
  83. pr_debug("%s:%d: lv1_open_device failed (%d)\n",
  84. __func__, __LINE__, result);
  85. result = -EACCES;
  86. goto clean_none;
  87. }
  88. if (dev->d_region->did.bus_id) {
  89. result = ps3_dma_region_create(dev->d_region);
  90. if (result) {
  91. pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n",
  92. __func__, __LINE__, result);
  93. BUG_ON("check region type");
  94. result = -EINVAL;
  95. goto clean_device;
  96. }
  97. }
  98. BUG_ON(!drv);
  99. if (drv->probe)
  100. result = drv->probe(dev);
  101. else
  102. pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
  103. dev->core.bus_id);
  104. if (result) {
  105. pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
  106. goto clean_dma;
  107. }
  108. return result;
  109. clean_dma:
  110. ps3_dma_region_free(dev->d_region);
  111. clean_device:
  112. lv1_close_device(dev->did.bus_id, dev->did.dev_id);
  113. clean_none:
  114. return result;
  115. }
  116. static int ps3_system_bus_remove(struct device *_dev)
  117. {
  118. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  119. struct ps3_system_bus_driver *drv =
  120. to_ps3_system_bus_driver(_dev->driver);
  121. if (drv->remove)
  122. drv->remove(dev);
  123. else
  124. pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
  125. dev->core.bus_id);
  126. ps3_dma_region_free(dev->d_region);
  127. ps3_free_mmio_region(dev->m_region);
  128. lv1_close_device(dev->did.bus_id, dev->did.dev_id);
  129. return 0;
  130. }
  131. struct bus_type ps3_system_bus_type = {
  132. .name = "ps3_system_bus",
  133. .match = ps3_system_bus_match,
  134. .probe = ps3_system_bus_probe,
  135. .remove = ps3_system_bus_remove,
  136. };
  137. int __init ps3_system_bus_init(void)
  138. {
  139. int result;
  140. if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
  141. return 0;
  142. result = bus_register(&ps3_system_bus_type);
  143. BUG_ON(result);
  144. return result;
  145. }
  146. core_initcall(ps3_system_bus_init);
  147. /* Allocates a contiguous real buffer and creates mappings over it.
  148. * Returns the virtual address of the buffer and sets dma_handle
  149. * to the dma address (mapping) of the first page.
  150. */
  151. static void * ps3_alloc_coherent(struct device *_dev, size_t size,
  152. dma_addr_t *dma_handle, gfp_t flag)
  153. {
  154. int result;
  155. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  156. unsigned long virt_addr;
  157. BUG_ON(!dev->d_region->bus_addr);
  158. flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
  159. flag |= __GFP_ZERO;
  160. virt_addr = __get_free_pages(flag, get_order(size));
  161. if (!virt_addr) {
  162. pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
  163. goto clean_none;
  164. }
  165. result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle);
  166. if (result) {
  167. pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
  168. __func__, __LINE__, result);
  169. BUG_ON("check region type");
  170. goto clean_alloc;
  171. }
  172. return (void*)virt_addr;
  173. clean_alloc:
  174. free_pages(virt_addr, get_order(size));
  175. clean_none:
  176. dma_handle = NULL;
  177. return NULL;
  178. }
  179. static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
  180. dma_addr_t dma_handle)
  181. {
  182. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  183. ps3_dma_unmap(dev->d_region, dma_handle, size);
  184. free_pages((unsigned long)vaddr, get_order(size));
  185. }
  186. /* Creates TCEs for a user provided buffer. The user buffer must be
  187. * contiguous real kernel storage (not vmalloc). The address of the buffer
  188. * passed here is the kernel (virtual) address of the buffer. The buffer
  189. * need not be page aligned, the dma_addr_t returned will point to the same
  190. * byte within the page as vaddr.
  191. */
  192. static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
  193. enum dma_data_direction direction)
  194. {
  195. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  196. int result;
  197. unsigned long bus_addr;
  198. result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
  199. &bus_addr);
  200. if (result) {
  201. pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
  202. __func__, __LINE__, result);
  203. }
  204. return bus_addr;
  205. }
  206. static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
  207. size_t size, enum dma_data_direction direction)
  208. {
  209. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  210. int result;
  211. result = ps3_dma_unmap(dev->d_region, dma_addr, size);
  212. if (result) {
  213. pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
  214. __func__, __LINE__, result);
  215. }
  216. }
  217. static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
  218. enum dma_data_direction direction)
  219. {
  220. #if defined(CONFIG_PS3_DYNAMIC_DMA)
  221. BUG_ON("do");
  222. #endif
  223. return 0;
  224. }
  225. static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
  226. int nents, enum dma_data_direction direction)
  227. {
  228. #if defined(CONFIG_PS3_DYNAMIC_DMA)
  229. BUG_ON("do");
  230. #endif
  231. }
  232. static int ps3_dma_supported(struct device *_dev, u64 mask)
  233. {
  234. return 1;
  235. }
  236. static struct dma_mapping_ops ps3_dma_ops = {
  237. .alloc_coherent = ps3_alloc_coherent,
  238. .free_coherent = ps3_free_coherent,
  239. .map_single = ps3_map_single,
  240. .unmap_single = ps3_unmap_single,
  241. .map_sg = ps3_map_sg,
  242. .unmap_sg = ps3_unmap_sg,
  243. .dma_supported = ps3_dma_supported
  244. };
  245. /**
  246. * ps3_system_bus_release_device - remove a device from the system bus
  247. */
  248. static void ps3_system_bus_release_device(struct device *_dev)
  249. {
  250. struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
  251. kfree(dev);
  252. }
  253. /**
  254. * ps3_system_bus_device_register - add a device to the system bus
  255. *
  256. * ps3_system_bus_device_register() expects the dev object to be allocated
  257. * dynamically by the caller. The system bus takes ownership of the dev
  258. * object and frees the object in ps3_system_bus_release_device().
  259. */
  260. int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
  261. {
  262. int result;
  263. static unsigned int dev_count = 1;
  264. dev->core.parent = NULL;
  265. dev->core.bus = &ps3_system_bus_type;
  266. dev->core.release = ps3_system_bus_release_device;
  267. dev->core.archdata.of_node = NULL;
  268. dev->core.archdata.dma_ops = &ps3_dma_ops;
  269. dev->core.archdata.numa_node = 0;
  270. snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
  271. dev_count++);
  272. pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
  273. result = device_register(&dev->core);
  274. return result;
  275. }
  276. EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
  277. int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
  278. {
  279. int result;
  280. drv->core.bus = &ps3_system_bus_type;
  281. result = driver_register(&drv->core);
  282. return result;
  283. }
  284. EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
  285. void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
  286. {
  287. driver_unregister(&drv->core);
  288. }
  289. EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);