1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * 4 * Copyright (C) 2013 John Crispin <john@phrozen.org> 5 */ 6 7 #include <linux/interrupt.h> 8 #include <linux/of.h> 9 #include <linux/of_platform.h> 10 #include <linux/of_irq.h> 11 #include <linux/platform_device.h> 12 13 #include <asm/mach-ralink/ralink_regs.h> 14 15 #define REG_ILL_ACC_ADDR 0x10 16 #define REG_ILL_ACC_TYPE 0x14 17 18 #define ILL_INT_STATUS BIT(31) 19 #define ILL_ACC_WRITE BIT(30) 20 #define ILL_ACC_LEN_M 0xff 21 #define ILL_ACC_OFF_M 0xf 22 #define ILL_ACC_OFF_S 16 23 #define ILL_ACC_ID_M 0x7 24 #define ILL_ACC_ID_S 8 25 26 #define DRV_NAME "ill_acc" 27 28 static const char * const ill_acc_ids[] = { 29 "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb", 30 }; 31 32 static irqreturn_t ill_acc_irq_handler(int irq, void *_priv) 33 { 34 struct device *dev = (struct device *) _priv; 35 u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR); 36 u32 type = rt_memc_r32(REG_ILL_ACC_TYPE); 37 38 dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n", 39 (type & ILL_ACC_WRITE) ? ("write") : ("read"), 40 ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M], 41 addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M, 42 type & ILL_ACC_LEN_M); 43 44 rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); 45 46 return IRQ_HANDLED; 47 } 48 49 static int __init ill_acc_of_setup(void) 50 { 51 struct platform_device *pdev; 52 struct device_node *np; 53 int irq; 54 55 /* somehow this driver breaks on RT5350 */ 56 if (of_machine_is_compatible("ralink,rt5350-soc")) 57 return -EINVAL; 58 59 np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc"); 60 if (!np) 61 return -EINVAL; 62 63 pdev = of_find_device_by_node(np); 64 if (!pdev) { 65 pr_err("%pOFn: failed to lookup pdev\n", np); 66 of_node_put(np); 67 return -EINVAL; 68 } 69 70 irq = irq_of_parse_and_map(np, 0); 71 of_node_put(np); 72 if (!irq) { 73 dev_err(&pdev->dev, "failed to get irq\n"); 74 put_device(&pdev->dev); 75 return -EINVAL; 76 } 77 78 if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) { 79 dev_err(&pdev->dev, "failed to request irq\n"); 80 put_device(&pdev->dev); 81 return -EINVAL; 82 } 83 84 rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE); 85 86 dev_info(&pdev->dev, "irq registered\n"); 87 88 return 0; 89 } 90 91 arch_initcall(ill_acc_of_setup); 92