123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- /*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- *
- * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
- */
- #include <linux/interrupt.h>
- #include <linux/of_platform.h>
- #include <linux/of_irq.h>
- #include <asm/mach-ralink/ralink_regs.h>
- #define REG_ILL_ACC_ADDR 0x10
- #define REG_ILL_ACC_TYPE 0x14
- #define ILL_INT_STATUS BIT(31)
- #define ILL_ACC_WRITE BIT(30)
- #define ILL_ACC_LEN_M 0xff
- #define ILL_ACC_OFF_M 0xf
- #define ILL_ACC_OFF_S 16
- #define ILL_ACC_ID_M 0x7
- #define ILL_ACC_ID_S 8
- #define DRV_NAME "ill_acc"
- static const char * const ill_acc_ids[] = {
- "cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb",
- };
- static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
- {
- struct device *dev = (struct device *) _priv;
- u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
- u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
- dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
- (type & ILL_ACC_WRITE) ? ("write") : ("read"),
- ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
- addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
- type & ILL_ACC_LEN_M);
- rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
- return IRQ_HANDLED;
- }
- static int __init ill_acc_of_setup(void)
- {
- struct platform_device *pdev;
- struct device_node *np;
- int irq;
- /* somehow this driver breaks on RT5350 */
- if (of_machine_is_compatible("ralink,rt5350-soc"))
- return -EINVAL;
- np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
- if (!np)
- return -EINVAL;
- pdev = of_find_device_by_node(np);
- if (!pdev) {
- pr_err("%s: failed to lookup pdev\n", np->name);
- return -EINVAL;
- }
- irq = irq_of_parse_and_map(np, 0);
- if (!irq) {
- dev_err(&pdev->dev, "failed to get irq\n");
- return -EINVAL;
- }
- if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
- dev_err(&pdev->dev, "failed to request irq\n");
- return -EINVAL;
- }
- rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
- dev_info(&pdev->dev, "irq registered\n");
- return 0;
- }
- arch_initcall(ill_acc_of_setup);
|