ill_acc.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * This program is free software; you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License version 2 as published
  4. * by the Free Software Foundation.
  5. *
  6. * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
  7. */
  8. #include <linux/interrupt.h>
  9. #include <linux/of_platform.h>
  10. #include <linux/of_irq.h>
  11. #include <asm/mach-ralink/ralink_regs.h>
  12. #define REG_ILL_ACC_ADDR 0x10
  13. #define REG_ILL_ACC_TYPE 0x14
  14. #define ILL_INT_STATUS BIT(31)
  15. #define ILL_ACC_WRITE BIT(30)
  16. #define ILL_ACC_LEN_M 0xff
  17. #define ILL_ACC_OFF_M 0xf
  18. #define ILL_ACC_OFF_S 16
  19. #define ILL_ACC_ID_M 0x7
  20. #define ILL_ACC_ID_S 8
  21. #define DRV_NAME "ill_acc"
  22. static const char * const ill_acc_ids[] = {
  23. "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb",
  24. };
  25. static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
  26. {
  27. struct device *dev = (struct device *) _priv;
  28. u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
  29. u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
  30. dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
  31. (type & ILL_ACC_WRITE) ? ("write") : ("read"),
  32. ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
  33. addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
  34. type & ILL_ACC_LEN_M);
  35. rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
  36. return IRQ_HANDLED;
  37. }
  38. static int __init ill_acc_of_setup(void)
  39. {
  40. struct platform_device *pdev;
  41. struct device_node *np;
  42. int irq;
  43. /* somehow this driver breaks on RT5350 */
  44. if (of_machine_is_compatible("ralink,rt5350-soc"))
  45. return -EINVAL;
  46. np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
  47. if (!np)
  48. return -EINVAL;
  49. pdev = of_find_device_by_node(np);
  50. if (!pdev) {
  51. pr_err("%s: failed to lookup pdev\n", np->name);
  52. return -EINVAL;
  53. }
  54. irq = irq_of_parse_and_map(np, 0);
  55. if (!irq) {
  56. dev_err(&pdev->dev, "failed to get irq\n");
  57. return -EINVAL;
  58. }
  59. if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
  60. dev_err(&pdev->dev, "failed to request irq\n");
  61. return -EINVAL;
  62. }
  63. rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
  64. dev_info(&pdev->dev, "irq registered\n");
  65. return 0;
  66. }
  67. arch_initcall(ill_acc_of_setup);