xref: /linux/arch/mips/ralink/ill_acc.c (revision e1a7566d)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
25433acd8SJohn Crispin /*
35433acd8SJohn Crispin  *
497b92108SJohn Crispin  * Copyright (C) 2013 John Crispin <john@phrozen.org>
55433acd8SJohn Crispin  */
65433acd8SJohn Crispin 
75433acd8SJohn Crispin #include <linux/interrupt.h>
8*e1a7566dSRob Herring #include <linux/of.h>
95433acd8SJohn Crispin #include <linux/of_platform.h>
105433acd8SJohn Crispin #include <linux/of_irq.h>
11*e1a7566dSRob Herring #include <linux/platform_device.h>
125433acd8SJohn Crispin 
135433acd8SJohn Crispin #include <asm/mach-ralink/ralink_regs.h>
145433acd8SJohn Crispin 
155433acd8SJohn Crispin #define REG_ILL_ACC_ADDR	0x10
165433acd8SJohn Crispin #define REG_ILL_ACC_TYPE	0x14
175433acd8SJohn Crispin 
185433acd8SJohn Crispin #define ILL_INT_STATUS		BIT(31)
195433acd8SJohn Crispin #define ILL_ACC_WRITE		BIT(30)
205433acd8SJohn Crispin #define ILL_ACC_LEN_M		0xff
215433acd8SJohn Crispin #define ILL_ACC_OFF_M		0xf
225433acd8SJohn Crispin #define ILL_ACC_OFF_S		16
235433acd8SJohn Crispin #define ILL_ACC_ID_M		0x7
245433acd8SJohn Crispin #define ILL_ACC_ID_S		8
255433acd8SJohn Crispin 
265433acd8SJohn Crispin #define	DRV_NAME		"ill_acc"
275433acd8SJohn Crispin 
285433acd8SJohn Crispin static const char * const ill_acc_ids[] = {
295433acd8SJohn Crispin 	"cpu", "dma", "ppe", "pdma rx", "pdma tx", "pci/e", "wmac", "usb",
305433acd8SJohn Crispin };
315433acd8SJohn Crispin 
ill_acc_irq_handler(int irq,void * _priv)325433acd8SJohn Crispin static irqreturn_t ill_acc_irq_handler(int irq, void *_priv)
335433acd8SJohn Crispin {
345433acd8SJohn Crispin 	struct device *dev = (struct device *) _priv;
355433acd8SJohn Crispin 	u32 addr = rt_memc_r32(REG_ILL_ACC_ADDR);
365433acd8SJohn Crispin 	u32 type = rt_memc_r32(REG_ILL_ACC_TYPE);
375433acd8SJohn Crispin 
385433acd8SJohn Crispin 	dev_err(dev, "illegal %s access from %s - addr:0x%08x offset:%d len:%d\n",
395433acd8SJohn Crispin 		(type & ILL_ACC_WRITE) ? ("write") : ("read"),
405433acd8SJohn Crispin 		ill_acc_ids[(type >> ILL_ACC_ID_S) & ILL_ACC_ID_M],
415433acd8SJohn Crispin 		addr, (type >> ILL_ACC_OFF_S) & ILL_ACC_OFF_M,
425433acd8SJohn Crispin 		type & ILL_ACC_LEN_M);
435433acd8SJohn Crispin 
449dd6f1c1SJonas Gorski 	rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
455433acd8SJohn Crispin 
465433acd8SJohn Crispin 	return IRQ_HANDLED;
475433acd8SJohn Crispin }
485433acd8SJohn Crispin 
ill_acc_of_setup(void)495433acd8SJohn Crispin static int __init ill_acc_of_setup(void)
505433acd8SJohn Crispin {
515433acd8SJohn Crispin 	struct platform_device *pdev;
525433acd8SJohn Crispin 	struct device_node *np;
535433acd8SJohn Crispin 	int irq;
545433acd8SJohn Crispin 
555433acd8SJohn Crispin 	/* somehow this driver breaks on RT5350 */
565433acd8SJohn Crispin 	if (of_machine_is_compatible("ralink,rt5350-soc"))
575433acd8SJohn Crispin 		return -EINVAL;
585433acd8SJohn Crispin 
595433acd8SJohn Crispin 	np = of_find_compatible_node(NULL, NULL, "ralink,rt3050-memc");
605433acd8SJohn Crispin 	if (!np)
615433acd8SJohn Crispin 		return -EINVAL;
625433acd8SJohn Crispin 
635433acd8SJohn Crispin 	pdev = of_find_device_by_node(np);
645433acd8SJohn Crispin 	if (!pdev) {
659475e90fSRob Herring 		pr_err("%pOFn: failed to lookup pdev\n", np);
664a0a1436SHangyu Hua 		of_node_put(np);
675433acd8SJohn Crispin 		return -EINVAL;
685433acd8SJohn Crispin 	}
695433acd8SJohn Crispin 
705433acd8SJohn Crispin 	irq = irq_of_parse_and_map(np, 0);
71405db98bSWang Qing 	of_node_put(np);
725433acd8SJohn Crispin 	if (!irq) {
735433acd8SJohn Crispin 		dev_err(&pdev->dev, "failed to get irq\n");
74defed0bbSyu kuai 		put_device(&pdev->dev);
755433acd8SJohn Crispin 		return -EINVAL;
765433acd8SJohn Crispin 	}
775433acd8SJohn Crispin 
785433acd8SJohn Crispin 	if (request_irq(irq, ill_acc_irq_handler, 0, "ill_acc", &pdev->dev)) {
795433acd8SJohn Crispin 		dev_err(&pdev->dev, "failed to request irq\n");
80defed0bbSyu kuai 		put_device(&pdev->dev);
815433acd8SJohn Crispin 		return -EINVAL;
825433acd8SJohn Crispin 	}
835433acd8SJohn Crispin 
845433acd8SJohn Crispin 	rt_memc_w32(ILL_INT_STATUS, REG_ILL_ACC_TYPE);
855433acd8SJohn Crispin 
865433acd8SJohn Crispin 	dev_info(&pdev->dev, "irq registered\n");
875433acd8SJohn Crispin 
885433acd8SJohn Crispin 	return 0;
895433acd8SJohn Crispin }
905433acd8SJohn Crispin 
915433acd8SJohn Crispin arch_initcall(ill_acc_of_setup);
92