eeh-powernv.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*
  2. * The file intends to implement the platform dependent EEH operations on
  3. * powernv platform. Actually, the powernv was created in order to fully
  4. * hypervisor support.
  5. *
  6. * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. */
  13. #include <linux/atomic.h>
  14. #include <linux/delay.h>
  15. #include <linux/export.h>
  16. #include <linux/init.h>
  17. #include <linux/list.h>
  18. #include <linux/msi.h>
  19. #include <linux/of.h>
  20. #include <linux/pci.h>
  21. #include <linux/proc_fs.h>
  22. #include <linux/rbtree.h>
  23. #include <linux/sched.h>
  24. #include <linux/seq_file.h>
  25. #include <linux/spinlock.h>
  26. #include <asm/eeh.h>
  27. #include <asm/eeh_event.h>
  28. #include <asm/firmware.h>
  29. #include <asm/io.h>
  30. #include <asm/iommu.h>
  31. #include <asm/machdep.h>
  32. #include <asm/msi_bitmap.h>
  33. #include <asm/opal.h>
  34. #include <asm/ppc-pci.h>
  35. #include "powernv.h"
  36. #include "pci.h"
  37. /**
  38. * powernv_eeh_init - EEH platform dependent initialization
  39. *
  40. * EEH platform dependent initialization on powernv
  41. */
  42. static int powernv_eeh_init(void)
  43. {
  44. struct pci_controller *hose;
  45. struct pnv_phb *phb;
  46. /* We require OPALv3 */
  47. if (!firmware_has_feature(FW_FEATURE_OPALv3)) {
  48. pr_warn("%s: OPALv3 is required !\n",
  49. __func__);
  50. return -EINVAL;
  51. }
  52. /* Set probe mode */
  53. eeh_add_flag(EEH_PROBE_MODE_DEV);
  54. /*
  55. * P7IOC blocks PCI config access to frozen PE, but PHB3
  56. * doesn't do that. So we have to selectively enable I/O
  57. * prior to collecting error log.
  58. */
  59. list_for_each_entry(hose, &hose_list, list_node) {
  60. phb = hose->private_data;
  61. if (phb->model == PNV_PHB_MODEL_P7IOC)
  62. eeh_add_flag(EEH_ENABLE_IO_FOR_LOG);
  63. break;
  64. }
  65. return 0;
  66. }
  67. /**
  68. * powernv_eeh_post_init - EEH platform dependent post initialization
  69. *
  70. * EEH platform dependent post initialization on powernv. When
  71. * the function is called, the EEH PEs and devices should have
  72. * been built. If the I/O cache staff has been built, EEH is
  73. * ready to supply service.
  74. */
  75. static int powernv_eeh_post_init(void)
  76. {
  77. struct pci_controller *hose;
  78. struct pnv_phb *phb;
  79. int ret = 0;
  80. list_for_each_entry(hose, &hose_list, list_node) {
  81. phb = hose->private_data;
  82. if (phb->eeh_ops && phb->eeh_ops->post_init) {
  83. ret = phb->eeh_ops->post_init(hose);
  84. if (ret)
  85. break;
  86. }
  87. }
  88. return ret;
  89. }
  90. /**
  91. * powernv_eeh_dev_probe - Do probe on PCI device
  92. * @dev: PCI device
  93. * @flag: unused
  94. *
  95. * When EEH module is installed during system boot, all PCI devices
  96. * are checked one by one to see if it supports EEH. The function
  97. * is introduced for the purpose. By default, EEH has been enabled
  98. * on all PCI devices. That's to say, we only need do necessary
  99. * initialization on the corresponding eeh device and create PE
  100. * accordingly.
  101. *
  102. * It's notable that's unsafe to retrieve the EEH device through
  103. * the corresponding PCI device. During the PCI device hotplug, which
  104. * was possiblly triggered by EEH core, the binding between EEH device
  105. * and the PCI device isn't built yet.
  106. */
  107. static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag)
  108. {
  109. struct pci_controller *hose = pci_bus_to_host(dev->bus);
  110. struct pnv_phb *phb = hose->private_data;
  111. struct device_node *dn = pci_device_to_OF_node(dev);
  112. struct eeh_dev *edev = of_node_to_eeh_dev(dn);
  113. int ret;
  114. /*
  115. * When probing the root bridge, which doesn't have any
  116. * subordinate PCI devices. We don't have OF node for
  117. * the root bridge. So it's not reasonable to continue
  118. * the probing.
  119. */
  120. if (!dn || !edev || edev->pe)
  121. return 0;
  122. /* Skip for PCI-ISA bridge */
  123. if ((dev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
  124. return 0;
  125. /* Initialize eeh device */
  126. edev->class_code = dev->class;
  127. edev->mode &= 0xFFFFFF00;
  128. if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)
  129. edev->mode |= EEH_DEV_BRIDGE;
  130. edev->pcix_cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
  131. if (pci_is_pcie(dev)) {
  132. edev->pcie_cap = pci_pcie_cap(dev);
  133. if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
  134. edev->mode |= EEH_DEV_ROOT_PORT;
  135. else if (pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM)
  136. edev->mode |= EEH_DEV_DS_PORT;
  137. edev->aer_cap = pci_find_ext_capability(dev,
  138. PCI_EXT_CAP_ID_ERR);
  139. }
  140. edev->config_addr = ((dev->bus->number << 8) | dev->devfn);
  141. edev->pe_config_addr = phb->bdfn_to_pe(phb, dev->bus, dev->devfn & 0xff);
  142. /* Create PE */
  143. ret = eeh_add_to_parent_pe(edev);
  144. if (ret) {
  145. pr_warn("%s: Can't add PCI dev %s to parent PE (%d)\n",
  146. __func__, pci_name(dev), ret);
  147. return ret;
  148. }
  149. /*
  150. * Cache the PE primary bus, which can't be fetched when
  151. * full hotplug is in progress. In that case, all child
  152. * PCI devices of the PE are expected to be removed prior
  153. * to PE reset.
  154. */
  155. if (!edev->pe->bus)
  156. edev->pe->bus = dev->bus;
  157. /*
  158. * Enable EEH explicitly so that we will do EEH check
  159. * while accessing I/O stuff
  160. */
  161. eeh_add_flag(EEH_ENABLED);
  162. /* Save memory bars */
  163. eeh_save_bars(edev);
  164. return 0;
  165. }
  166. /**
  167. * powernv_eeh_set_option - Initialize EEH or MMIO/DMA reenable
  168. * @pe: EEH PE
  169. * @option: operation to be issued
  170. *
  171. * The function is used to control the EEH functionality globally.
  172. * Currently, following options are support according to PAPR:
  173. * Enable EEH, Disable EEH, Enable MMIO and Enable DMA
  174. */
  175. static int powernv_eeh_set_option(struct eeh_pe *pe, int option)
  176. {
  177. struct pci_controller *hose = pe->phb;
  178. struct pnv_phb *phb = hose->private_data;
  179. int ret = -EEXIST;
  180. /*
  181. * What we need do is pass it down for hardware
  182. * implementation to handle it.
  183. */
  184. if (phb->eeh_ops && phb->eeh_ops->set_option)
  185. ret = phb->eeh_ops->set_option(pe, option);
  186. return ret;
  187. }
  188. /**
  189. * powernv_eeh_get_pe_addr - Retrieve PE address
  190. * @pe: EEH PE
  191. *
  192. * Retrieve the PE address according to the given tranditional
  193. * PCI BDF (Bus/Device/Function) address.
  194. */
  195. static int powernv_eeh_get_pe_addr(struct eeh_pe *pe)
  196. {
  197. return pe->addr;
  198. }
  199. /**
  200. * powernv_eeh_get_state - Retrieve PE state
  201. * @pe: EEH PE
  202. * @delay: delay while PE state is temporarily unavailable
  203. *
  204. * Retrieve the state of the specified PE. For IODA-compitable
  205. * platform, it should be retrieved from IODA table. Therefore,
  206. * we prefer passing down to hardware implementation to handle
  207. * it.
  208. */
  209. static int powernv_eeh_get_state(struct eeh_pe *pe, int *delay)
  210. {
  211. struct pci_controller *hose = pe->phb;
  212. struct pnv_phb *phb = hose->private_data;
  213. int ret = EEH_STATE_NOT_SUPPORT;
  214. if (phb->eeh_ops && phb->eeh_ops->get_state) {
  215. ret = phb->eeh_ops->get_state(pe);
  216. /*
  217. * If the PE state is temporarily unavailable,
  218. * to inform the EEH core delay for default
  219. * period (1 second)
  220. */
  221. if (delay) {
  222. *delay = 0;
  223. if (ret & EEH_STATE_UNAVAILABLE)
  224. *delay = 1000;
  225. }
  226. }
  227. return ret;
  228. }
  229. /**
  230. * powernv_eeh_reset - Reset the specified PE
  231. * @pe: EEH PE
  232. * @option: reset option
  233. *
  234. * Reset the specified PE
  235. */
  236. static int powernv_eeh_reset(struct eeh_pe *pe, int option)
  237. {
  238. struct pci_controller *hose = pe->phb;
  239. struct pnv_phb *phb = hose->private_data;
  240. int ret = -EEXIST;
  241. if (phb->eeh_ops && phb->eeh_ops->reset)
  242. ret = phb->eeh_ops->reset(pe, option);
  243. return ret;
  244. }
  245. /**
  246. * powernv_eeh_wait_state - Wait for PE state
  247. * @pe: EEH PE
  248. * @max_wait: maximal period in microsecond
  249. *
  250. * Wait for the state of associated PE. It might take some time
  251. * to retrieve the PE's state.
  252. */
  253. static int powernv_eeh_wait_state(struct eeh_pe *pe, int max_wait)
  254. {
  255. int ret;
  256. int mwait;
  257. while (1) {
  258. ret = powernv_eeh_get_state(pe, &mwait);
  259. /*
  260. * If the PE's state is temporarily unavailable,
  261. * we have to wait for the specified time. Otherwise,
  262. * the PE's state will be returned immediately.
  263. */
  264. if (ret != EEH_STATE_UNAVAILABLE)
  265. return ret;
  266. max_wait -= mwait;
  267. if (max_wait <= 0) {
  268. pr_warn("%s: Timeout getting PE#%x's state (%d)\n",
  269. __func__, pe->addr, max_wait);
  270. return EEH_STATE_NOT_SUPPORT;
  271. }
  272. msleep(mwait);
  273. }
  274. return EEH_STATE_NOT_SUPPORT;
  275. }
  276. /**
  277. * powernv_eeh_get_log - Retrieve error log
  278. * @pe: EEH PE
  279. * @severity: temporary or permanent error log
  280. * @drv_log: driver log to be combined with retrieved error log
  281. * @len: length of driver log
  282. *
  283. * Retrieve the temporary or permanent error from the PE.
  284. */
  285. static int powernv_eeh_get_log(struct eeh_pe *pe, int severity,
  286. char *drv_log, unsigned long len)
  287. {
  288. struct pci_controller *hose = pe->phb;
  289. struct pnv_phb *phb = hose->private_data;
  290. int ret = -EEXIST;
  291. if (phb->eeh_ops && phb->eeh_ops->get_log)
  292. ret = phb->eeh_ops->get_log(pe, severity, drv_log, len);
  293. return ret;
  294. }
  295. /**
  296. * powernv_eeh_configure_bridge - Configure PCI bridges in the indicated PE
  297. * @pe: EEH PE
  298. *
  299. * The function will be called to reconfigure the bridges included
  300. * in the specified PE so that the mulfunctional PE would be recovered
  301. * again.
  302. */
  303. static int powernv_eeh_configure_bridge(struct eeh_pe *pe)
  304. {
  305. struct pci_controller *hose = pe->phb;
  306. struct pnv_phb *phb = hose->private_data;
  307. int ret = 0;
  308. if (phb->eeh_ops && phb->eeh_ops->configure_bridge)
  309. ret = phb->eeh_ops->configure_bridge(pe);
  310. return ret;
  311. }
  312. /**
  313. * powernv_pe_err_inject - Inject specified error to the indicated PE
  314. * @pe: the indicated PE
  315. * @type: error type
  316. * @func: specific error type
  317. * @addr: address
  318. * @mask: address mask
  319. *
  320. * The routine is called to inject specified error, which is
  321. * determined by @type and @func, to the indicated PE for
  322. * testing purpose.
  323. */
  324. static int powernv_eeh_err_inject(struct eeh_pe *pe, int type, int func,
  325. unsigned long addr, unsigned long mask)
  326. {
  327. struct pci_controller *hose = pe->phb;
  328. struct pnv_phb *phb = hose->private_data;
  329. int ret = -EEXIST;
  330. if (phb->eeh_ops && phb->eeh_ops->err_inject)
  331. ret = phb->eeh_ops->err_inject(pe, type, func, addr, mask);
  332. return ret;
  333. }
  334. /**
  335. * powernv_eeh_next_error - Retrieve next EEH error to handle
  336. * @pe: Affected PE
  337. *
  338. * Using OPAL API, to retrieve next EEH error for EEH core to handle
  339. */
  340. static int powernv_eeh_next_error(struct eeh_pe **pe)
  341. {
  342. struct pci_controller *hose;
  343. struct pnv_phb *phb = NULL;
  344. list_for_each_entry(hose, &hose_list, list_node) {
  345. phb = hose->private_data;
  346. break;
  347. }
  348. if (phb && phb->eeh_ops->next_error)
  349. return phb->eeh_ops->next_error(pe);
  350. return -EEXIST;
  351. }
  352. static int powernv_eeh_restore_config(struct device_node *dn)
  353. {
  354. struct eeh_dev *edev = of_node_to_eeh_dev(dn);
  355. struct pnv_phb *phb;
  356. s64 ret;
  357. if (!edev)
  358. return -EEXIST;
  359. phb = edev->phb->private_data;
  360. ret = opal_pci_reinit(phb->opal_id,
  361. OPAL_REINIT_PCI_DEV, edev->config_addr);
  362. if (ret) {
  363. pr_warn("%s: Can't reinit PCI dev 0x%x (%lld)\n",
  364. __func__, edev->config_addr, ret);
  365. return -EIO;
  366. }
  367. return 0;
  368. }
  369. static struct eeh_ops powernv_eeh_ops = {
  370. .name = "powernv",
  371. .init = powernv_eeh_init,
  372. .post_init = powernv_eeh_post_init,
  373. .of_probe = NULL,
  374. .dev_probe = powernv_eeh_dev_probe,
  375. .set_option = powernv_eeh_set_option,
  376. .get_pe_addr = powernv_eeh_get_pe_addr,
  377. .get_state = powernv_eeh_get_state,
  378. .reset = powernv_eeh_reset,
  379. .wait_state = powernv_eeh_wait_state,
  380. .get_log = powernv_eeh_get_log,
  381. .configure_bridge = powernv_eeh_configure_bridge,
  382. .err_inject = powernv_eeh_err_inject,
  383. .read_config = pnv_pci_cfg_read,
  384. .write_config = pnv_pci_cfg_write,
  385. .next_error = powernv_eeh_next_error,
  386. .restore_config = powernv_eeh_restore_config
  387. };
  388. /**
  389. * eeh_powernv_init - Register platform dependent EEH operations
  390. *
  391. * EEH initialization on powernv platform. This function should be
  392. * called before any EEH related functions.
  393. */
  394. static int __init eeh_powernv_init(void)
  395. {
  396. int ret = -EINVAL;
  397. eeh_set_pe_aux_size(PNV_PCI_DIAG_BUF_SIZE);
  398. ret = eeh_ops_register(&powernv_eeh_ops);
  399. if (!ret)
  400. pr_info("EEH: PowerNV platform initialized\n");
  401. else
  402. pr_info("EEH: Failed to initialize PowerNV platform (%d)\n", ret);
  403. return ret;
  404. }
  405. machine_early_initcall(powernv, eeh_powernv_init);