bt1-apb.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
  4. *
  5. * Authors:
  6. * Serge Semin <Sergey.Semin@baikalelectronics.ru>
  7. *
  8. * Baikal-T1 APB-bus driver
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/types.h>
  13. #include <linux/device.h>
  14. #include <linux/atomic.h>
  15. #include <linux/platform_device.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/io.h>
  18. #include <linux/nmi.h>
  19. #include <linux/of.h>
  20. #include <linux/regmap.h>
  21. #include <linux/clk.h>
  22. #include <linux/reset.h>
  23. #include <linux/time64.h>
  24. #include <linux/sysfs.h>
  25. #define APB_EHB_ISR 0x00
  26. #define APB_EHB_ISR_PENDING BIT(0)
  27. #define APB_EHB_ISR_MASK BIT(1)
  28. #define APB_EHB_ADDR 0x04
  29. #define APB_EHB_TIMEOUT 0x08
  30. #define APB_EHB_TIMEOUT_MIN 0x000003FFU
  31. #define APB_EHB_TIMEOUT_MAX 0xFFFFFFFFU
  32. /*
  33. * struct bt1_apb - Baikal-T1 APB EHB private data
  34. * @dev: Pointer to the device structure.
  35. * @regs: APB EHB registers map.
  36. * @res: No-device error injection memory region.
  37. * @irq: Errors IRQ number.
  38. * @rate: APB-bus reference clock rate.
  39. * @pclk: APB-reference clock.
  40. * @prst: APB domain reset line.
  41. * @count: Number of errors detected.
  42. */
  43. struct bt1_apb {
  44. struct device *dev;
  45. struct regmap *regs;
  46. void __iomem *res;
  47. int irq;
  48. unsigned long rate;
  49. struct clk *pclk;
  50. struct reset_control *prst;
  51. atomic_t count;
  52. };
  53. static const struct regmap_config bt1_apb_regmap_cfg = {
  54. .reg_bits = 32,
  55. .val_bits = 32,
  56. .reg_stride = 4,
  57. .max_register = APB_EHB_TIMEOUT,
  58. .fast_io = true
  59. };
  60. static inline unsigned long bt1_apb_n_to_timeout_us(struct bt1_apb *apb, u32 n)
  61. {
  62. u64 timeout = (u64)n * USEC_PER_SEC;
  63. do_div(timeout, apb->rate);
  64. return timeout;
  65. }
  66. static inline unsigned long bt1_apb_timeout_to_n_us(struct bt1_apb *apb,
  67. unsigned long timeout)
  68. {
  69. u64 n = (u64)timeout * apb->rate;
  70. do_div(n, USEC_PER_SEC);
  71. return n;
  72. }
  73. static irqreturn_t bt1_apb_isr(int irq, void *data)
  74. {
  75. struct bt1_apb *apb = data;
  76. u32 addr = 0;
  77. regmap_read(apb->regs, APB_EHB_ADDR, &addr);
  78. dev_crit_ratelimited(apb->dev,
  79. "APB-bus fault %d: Slave access timeout at 0x%08x\n",
  80. atomic_inc_return(&apb->count),
  81. addr);
  82. /*
  83. * Print backtrace on each CPU. This might be pointless if the fault
  84. * has happened on the same CPU as the IRQ handler is executed or
  85. * the other core proceeded further execution despite the error.
  86. * But if it's not, by looking at the trace we would get straight to
  87. * the cause of the problem.
  88. */
  89. trigger_all_cpu_backtrace();
  90. regmap_update_bits(apb->regs, APB_EHB_ISR, APB_EHB_ISR_PENDING, 0);
  91. return IRQ_HANDLED;
  92. }
  93. static void bt1_apb_clear_data(void *data)
  94. {
  95. struct bt1_apb *apb = data;
  96. struct platform_device *pdev = to_platform_device(apb->dev);
  97. platform_set_drvdata(pdev, NULL);
  98. }
  99. static struct bt1_apb *bt1_apb_create_data(struct platform_device *pdev)
  100. {
  101. struct device *dev = &pdev->dev;
  102. struct bt1_apb *apb;
  103. int ret;
  104. apb = devm_kzalloc(dev, sizeof(*apb), GFP_KERNEL);
  105. if (!apb)
  106. return ERR_PTR(-ENOMEM);
  107. ret = devm_add_action(dev, bt1_apb_clear_data, apb);
  108. if (ret) {
  109. dev_err(dev, "Can't add APB EHB data clear action\n");
  110. return ERR_PTR(ret);
  111. }
  112. apb->dev = dev;
  113. atomic_set(&apb->count, 0);
  114. platform_set_drvdata(pdev, apb);
  115. return apb;
  116. }
  117. static int bt1_apb_request_regs(struct bt1_apb *apb)
  118. {
  119. struct platform_device *pdev = to_platform_device(apb->dev);
  120. void __iomem *regs;
  121. regs = devm_platform_ioremap_resource_byname(pdev, "ehb");
  122. if (IS_ERR(regs)) {
  123. dev_err(apb->dev, "Couldn't map APB EHB registers\n");
  124. return PTR_ERR(regs);
  125. }
  126. apb->regs = devm_regmap_init_mmio(apb->dev, regs, &bt1_apb_regmap_cfg);
  127. if (IS_ERR(apb->regs)) {
  128. dev_err(apb->dev, "Couldn't create APB EHB regmap\n");
  129. return PTR_ERR(apb->regs);
  130. }
  131. apb->res = devm_platform_ioremap_resource_byname(pdev, "nodev");
  132. if (IS_ERR(apb->res))
  133. dev_err(apb->dev, "Couldn't map reserved region\n");
  134. return PTR_ERR_OR_ZERO(apb->res);
  135. }
  136. static int bt1_apb_request_rst(struct bt1_apb *apb)
  137. {
  138. int ret;
  139. apb->prst = devm_reset_control_get_optional_exclusive(apb->dev, "prst");
  140. if (IS_ERR(apb->prst))
  141. return dev_err_probe(apb->dev, PTR_ERR(apb->prst),
  142. "Couldn't get reset control line\n");
  143. ret = reset_control_deassert(apb->prst);
  144. if (ret)
  145. dev_err(apb->dev, "Failed to deassert the reset line\n");
  146. return ret;
  147. }
  148. static int bt1_apb_request_clk(struct bt1_apb *apb)
  149. {
  150. apb->pclk = devm_clk_get_enabled(apb->dev, "pclk");
  151. if (IS_ERR(apb->pclk))
  152. return dev_err_probe(apb->dev, PTR_ERR(apb->pclk),
  153. "Couldn't get APB clock descriptor\n");
  154. apb->rate = clk_get_rate(apb->pclk);
  155. if (!apb->rate) {
  156. dev_err(apb->dev, "Invalid clock rate\n");
  157. return -EINVAL;
  158. }
  159. return 0;
  160. }
  161. static void bt1_apb_clear_irq(void *data)
  162. {
  163. struct bt1_apb *apb = data;
  164. regmap_update_bits(apb->regs, APB_EHB_ISR, APB_EHB_ISR_MASK, 0);
  165. }
  166. static int bt1_apb_request_irq(struct bt1_apb *apb)
  167. {
  168. struct platform_device *pdev = to_platform_device(apb->dev);
  169. int ret;
  170. apb->irq = platform_get_irq(pdev, 0);
  171. if (apb->irq < 0)
  172. return apb->irq;
  173. ret = devm_request_irq(apb->dev, apb->irq, bt1_apb_isr, IRQF_SHARED,
  174. "bt1-apb", apb);
  175. if (ret) {
  176. dev_err(apb->dev, "Couldn't request APB EHB IRQ\n");
  177. return ret;
  178. }
  179. ret = devm_add_action(apb->dev, bt1_apb_clear_irq, apb);
  180. if (ret) {
  181. dev_err(apb->dev, "Can't add APB EHB IRQs clear action\n");
  182. return ret;
  183. }
  184. /* Unmask IRQ and clear it' pending flag. */
  185. regmap_update_bits(apb->regs, APB_EHB_ISR,
  186. APB_EHB_ISR_PENDING | APB_EHB_ISR_MASK,
  187. APB_EHB_ISR_MASK);
  188. return 0;
  189. }
  190. static ssize_t count_show(struct device *dev, struct device_attribute *attr,
  191. char *buf)
  192. {
  193. struct bt1_apb *apb = dev_get_drvdata(dev);
  194. return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&apb->count));
  195. }
  196. static DEVICE_ATTR_RO(count);
  197. static ssize_t timeout_show(struct device *dev, struct device_attribute *attr,
  198. char *buf)
  199. {
  200. struct bt1_apb *apb = dev_get_drvdata(dev);
  201. unsigned long timeout;
  202. int ret;
  203. u32 n;
  204. ret = regmap_read(apb->regs, APB_EHB_TIMEOUT, &n);
  205. if (ret)
  206. return ret;
  207. timeout = bt1_apb_n_to_timeout_us(apb, n);
  208. return scnprintf(buf, PAGE_SIZE, "%lu\n", timeout);
  209. }
  210. static ssize_t timeout_store(struct device *dev,
  211. struct device_attribute *attr,
  212. const char *buf, size_t count)
  213. {
  214. struct bt1_apb *apb = dev_get_drvdata(dev);
  215. unsigned long timeout;
  216. int ret;
  217. u32 n;
  218. if (kstrtoul(buf, 0, &timeout) < 0)
  219. return -EINVAL;
  220. n = bt1_apb_timeout_to_n_us(apb, timeout);
  221. n = clamp(n, APB_EHB_TIMEOUT_MIN, APB_EHB_TIMEOUT_MAX);
  222. ret = regmap_write(apb->regs, APB_EHB_TIMEOUT, n);
  223. return ret ?: count;
  224. }
  225. static DEVICE_ATTR_RW(timeout);
  226. static ssize_t inject_error_show(struct device *dev,
  227. struct device_attribute *attr, char *buf)
  228. {
  229. return scnprintf(buf, PAGE_SIZE, "Error injection: nodev irq\n");
  230. }
  231. static ssize_t inject_error_store(struct device *dev,
  232. struct device_attribute *attr,
  233. const char *data, size_t count)
  234. {
  235. struct bt1_apb *apb = dev_get_drvdata(dev);
  236. /*
  237. * Either dummy read from the unmapped address in the APB IO area
  238. * or manually set the IRQ status.
  239. */
  240. if (sysfs_streq(data, "nodev"))
  241. readl(apb->res);
  242. else if (sysfs_streq(data, "irq"))
  243. regmap_update_bits(apb->regs, APB_EHB_ISR, APB_EHB_ISR_PENDING,
  244. APB_EHB_ISR_PENDING);
  245. else
  246. return -EINVAL;
  247. return count;
  248. }
  249. static DEVICE_ATTR_RW(inject_error);
  250. static struct attribute *bt1_apb_sysfs_attrs[] = {
  251. &dev_attr_count.attr,
  252. &dev_attr_timeout.attr,
  253. &dev_attr_inject_error.attr,
  254. NULL
  255. };
  256. ATTRIBUTE_GROUPS(bt1_apb_sysfs);
  257. static void bt1_apb_remove_sysfs(void *data)
  258. {
  259. struct bt1_apb *apb = data;
  260. device_remove_groups(apb->dev, bt1_apb_sysfs_groups);
  261. }
  262. static int bt1_apb_init_sysfs(struct bt1_apb *apb)
  263. {
  264. int ret;
  265. ret = device_add_groups(apb->dev, bt1_apb_sysfs_groups);
  266. if (ret) {
  267. dev_err(apb->dev, "Failed to create EHB APB sysfs nodes\n");
  268. return ret;
  269. }
  270. ret = devm_add_action_or_reset(apb->dev, bt1_apb_remove_sysfs, apb);
  271. if (ret)
  272. dev_err(apb->dev, "Can't add APB EHB sysfs remove action\n");
  273. return ret;
  274. }
  275. static int bt1_apb_probe(struct platform_device *pdev)
  276. {
  277. struct bt1_apb *apb;
  278. int ret;
  279. apb = bt1_apb_create_data(pdev);
  280. if (IS_ERR(apb))
  281. return PTR_ERR(apb);
  282. ret = bt1_apb_request_regs(apb);
  283. if (ret)
  284. return ret;
  285. ret = bt1_apb_request_rst(apb);
  286. if (ret)
  287. return ret;
  288. ret = bt1_apb_request_clk(apb);
  289. if (ret)
  290. return ret;
  291. ret = bt1_apb_request_irq(apb);
  292. if (ret)
  293. return ret;
  294. ret = bt1_apb_init_sysfs(apb);
  295. if (ret)
  296. return ret;
  297. return 0;
  298. }
  299. static const struct of_device_id bt1_apb_of_match[] = {
  300. { .compatible = "baikal,bt1-apb" },
  301. { }
  302. };
  303. MODULE_DEVICE_TABLE(of, bt1_apb_of_match);
  304. static struct platform_driver bt1_apb_driver = {
  305. .probe = bt1_apb_probe,
  306. .driver = {
  307. .name = "bt1-apb",
  308. .of_match_table = bt1_apb_of_match
  309. }
  310. };
  311. module_platform_driver(bt1_apb_driver);
  312. MODULE_AUTHOR("Serge Semin <Sergey.Semin@baikalelectronics.ru>");
  313. MODULE_DESCRIPTION("Baikal-T1 APB-bus driver");