Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  * Copyright (C) 2013 John Crispin <john@phrozen.org>
0005  */
0006 
0007 #include <linux/interrupt.h>
0008 #include <linux/of_platform.h>
0009 #include <linux/of_irq.h>
0010 
0011 #include <asm/mach-ralink/ralink_regs.h>
0012 
0013 #define REG_ILL_ACC_ADDR    0x10
0014 #define REG_ILL_ACC_TYPE    0x14
0015 
0016 #define ILL_INT_STATUS      BIT(31)
0017 #define ILL_ACC_WRITE       BIT(30)
0018 #define ILL_ACC_LEN_M       0xff
0019 #define ILL_ACC_OFF_M       0xf
0020 #define ILL_ACC_OFF_S       16
0021 #define ILL_ACC_ID_M        0x7
0022 #define ILL_ACC_ID_S        8
0023 
0024 #define DRV_NAME        "ill_acc"
0025 
0026 static const char * const ill_acc_ids[] = {
0027     "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb",
0028 };
0029 
0030 static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
0031 {
0032     struct device *dev = (struct device *) _priv;
0033     u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
0034     u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
0035 
0036     dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
0037         (type & ILL_ACC_WRITE) ? ("write") : ("read"),
0038         ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
0039         addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
0040         type & ILL_ACC_LEN_M);
0041 
0042     rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
0043 
0044     return IRQ_HANDLED;
0045 }
0046 
0047 static int __init ill_acc_of_setup(void)
0048 {
0049     struct platform_device *pdev;
0050     struct device_node *np;
0051     int irq;
0052 
0053     /* somehow this driver breaks on RT5350 */
0054     if (of_machine_is_compatible("ralink,rt5350-soc"))
0055         return -EINVAL;
0056 
0057     np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
0058     if (!np)
0059         return -EINVAL;
0060 
0061     pdev = of_find_device_by_node(np);
0062     if (!pdev) {
0063         pr_err("%pOFn: failed to lookup pdev\n", np);
0064         of_node_put(np);
0065         return -EINVAL;
0066     }
0067 
0068     irq = irq_of_parse_and_map(np, 0);
0069     of_node_put(np);
0070     if (!irq) {
0071         dev_err(&pdev->dev, "failed to get irq\n");
0072         put_device(&pdev->dev);
0073         return -EINVAL;
0074     }
0075 
0076     if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
0077         dev_err(&pdev->dev, "failed to request irq\n");
0078         put_device(&pdev->dev);
0079         return -EINVAL;
0080     }
0081 
0082     rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
0083 
0084     dev_info(&pdev->dev, "irq registered\n");
0085 
0086     return 0;
0087 }
0088 
0089 arch_initcall(ill_acc_of_setup);