xref: /netbsd-src/sys/arch/arm/marvell/mvsoc_intr.c (revision 49de48ba0337540e371bcd9210618dd930f8b42d)
1*49de48baSmartin /*	$NetBSD: mvsoc_intr.c,v 1.9 2014/02/22 16:14:38 martin Exp $	*/
252d286fbSkiyohara /*
352d286fbSkiyohara  * Copyright (c) 2010 KIYOHARA Takashi
452d286fbSkiyohara  * All rights reserved.
552d286fbSkiyohara  *
652d286fbSkiyohara  * Redistribution and use in source and binary forms, with or without
752d286fbSkiyohara  * modification, are permitted provided that the following conditions
852d286fbSkiyohara  * are met:
952d286fbSkiyohara  * 1. Redistributions of source code must retain the above copyright
1052d286fbSkiyohara  *    notice, this list of conditions and the following disclaimer.
1152d286fbSkiyohara  * 2. Redistributions in binary form must reproduce the above copyright
1252d286fbSkiyohara  *    notice, this list of conditions and the following disclaimer in the
1352d286fbSkiyohara  *    documentation and/or other materials provided with the distribution.
1452d286fbSkiyohara  *
1552d286fbSkiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1652d286fbSkiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1752d286fbSkiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1852d286fbSkiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
1952d286fbSkiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
2052d286fbSkiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2152d286fbSkiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2252d286fbSkiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
2352d286fbSkiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2452d286fbSkiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2552d286fbSkiyohara  * POSSIBILITY OF SUCH DAMAGE.
2652d286fbSkiyohara  */
2752d286fbSkiyohara 
2852d286fbSkiyohara #include <sys/cdefs.h>
29*49de48baSmartin __KERNEL_RCSID(0, "$NetBSD: mvsoc_intr.c,v 1.9 2014/02/22 16:14:38 martin Exp $");
301ec637abSkiyohara 
311ec637abSkiyohara #include "opt_mvsoc.h"
3252d286fbSkiyohara 
3352d286fbSkiyohara #define _INTR_PRIVATE
3452d286fbSkiyohara 
3552d286fbSkiyohara #include <sys/param.h>
3652d286fbSkiyohara #include <sys/proc.h>
3752d286fbSkiyohara 
3852d286fbSkiyohara #include <machine/intr.h>
3952d286fbSkiyohara 
40*49de48baSmartin #include <arm/armreg.h>
4152d286fbSkiyohara #include <arm/cpu.h>
4252d286fbSkiyohara #include <arm/pic/picvar.h>
4352d286fbSkiyohara #include <arm/marvell/mvsocreg.h>
4452d286fbSkiyohara #include <arm/marvell/mvsocvar.h>
4552d286fbSkiyohara 
46a9160f60Srkujawa 
47a039bd91Smatt int (*find_pending_irqs)(void);
4852d286fbSkiyohara 
4952d286fbSkiyohara static void mvsoc_bridge_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
5052d286fbSkiyohara static void mvsoc_bridge_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
5152d286fbSkiyohara static int mvsoc_bridge_pic_find_pending_irqs(struct pic_softc *);
5252d286fbSkiyohara static void mvsoc_bridge_pic_establish_irq(struct pic_softc *,
5352d286fbSkiyohara 					   struct intrsource *);
5452d286fbSkiyohara static void mvsoc_bridge_pic_source_name(struct pic_softc *, int, char *,
5552d286fbSkiyohara 					 size_t);
5652d286fbSkiyohara 
5752d286fbSkiyohara static const char * const sources[] = {
5852d286fbSkiyohara     "CPUSelfInt",      "CPUTimer0IntReq", "CPUTimer1IntReq", "CPUWDTimerIntReq",
5952d286fbSkiyohara     "AccessErr",       "Bit64Err",
6052d286fbSkiyohara };
6152d286fbSkiyohara 
6252d286fbSkiyohara static struct pic_ops mvsoc_bridge_picops = {
6352d286fbSkiyohara 	.pic_unblock_irqs = mvsoc_bridge_pic_unblock_irqs,
6452d286fbSkiyohara 	.pic_block_irqs = mvsoc_bridge_pic_block_irqs,
6552d286fbSkiyohara 	.pic_find_pending_irqs = mvsoc_bridge_pic_find_pending_irqs,
6652d286fbSkiyohara 	.pic_establish_irq = mvsoc_bridge_pic_establish_irq,
6752d286fbSkiyohara 	.pic_source_name = mvsoc_bridge_pic_source_name,
6852d286fbSkiyohara };
6952d286fbSkiyohara 
7052d286fbSkiyohara struct pic_softc mvsoc_bridge_pic = {
7152d286fbSkiyohara 	.pic_ops = &mvsoc_bridge_picops,
7252d286fbSkiyohara 	.pic_maxsources = MVSOC_MLMB_MLMBI_NIRQ,
7352d286fbSkiyohara 	.pic_name = "mvsoc_bridge",
7452d286fbSkiyohara };
7552d286fbSkiyohara 
7652d286fbSkiyohara 
7752d286fbSkiyohara void
mvsoc_irq_handler(void * frame)7852d286fbSkiyohara mvsoc_irq_handler(void *frame)
7952d286fbSkiyohara {
8052d286fbSkiyohara 	struct cpu_info * const ci = curcpu();
8152d286fbSkiyohara 	const int oldipl = ci->ci_cpl;
8252d286fbSkiyohara 	const uint32_t oldipl_mask = __BIT(oldipl);
8352d286fbSkiyohara 	int ipl_mask = 0;
8452d286fbSkiyohara 
856a66466fSmatt 	ci->ci_data.cpu_nintr++;
8652d286fbSkiyohara 
8752d286fbSkiyohara 	ipl_mask = find_pending_irqs();
8852d286fbSkiyohara 
8952d286fbSkiyohara 	/*
9052d286fbSkiyohara 	 * Record the pending_ipls and deliver them if we can.
9152d286fbSkiyohara 	 */
9252d286fbSkiyohara 	if ((ipl_mask & ~oldipl_mask) > oldipl_mask)
9352d286fbSkiyohara 		pic_do_pending_ints(I32_bit, oldipl, frame);
9452d286fbSkiyohara }
9552d286fbSkiyohara 
9652d286fbSkiyohara /*
9752d286fbSkiyohara  * Mbus-L to Mbus bridge
9852d286fbSkiyohara  */
9952d286fbSkiyohara 
10052d286fbSkiyohara void *
mvsoc_bridge_intr_establish(int ih,int ipl,int (* ih_func)(void *),void * arg)10152d286fbSkiyohara mvsoc_bridge_intr_establish(int ih, int ipl, int (*ih_func)(void *), void *arg)
10252d286fbSkiyohara {
10352d286fbSkiyohara 
10421c11346Sjakllsch 	return intr_establish(mvsoc_bridge_pic.pic_irqbase + ih, ipl,
10521c11346Sjakllsch 	    IST_LEVEL_HIGH, ih_func, arg);
10652d286fbSkiyohara }
10752d286fbSkiyohara 
10852d286fbSkiyohara /* ARGSUSED */
10952d286fbSkiyohara static void
mvsoc_bridge_pic_unblock_irqs(struct pic_softc * pic,size_t irqbase,uint32_t irq_mask)11052d286fbSkiyohara mvsoc_bridge_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
11152d286fbSkiyohara 			      uint32_t irq_mask)
11252d286fbSkiyohara {
11352d286fbSkiyohara 
11452d286fbSkiyohara 	write_mlmbreg(MVSOC_MLMB_MLMBICR,
11552d286fbSkiyohara 	    read_mlmbreg(MVSOC_MLMB_MLMBICR) & ~irq_mask);
11652d286fbSkiyohara 	write_mlmbreg(MVSOC_MLMB_MLMBIMR,
11752d286fbSkiyohara 	    read_mlmbreg(MVSOC_MLMB_MLMBIMR) | irq_mask);
11852d286fbSkiyohara }
11952d286fbSkiyohara 
12052d286fbSkiyohara /* ARGSUSED */
12152d286fbSkiyohara static void
mvsoc_bridge_pic_block_irqs(struct pic_softc * pic,size_t irqbase,uint32_t irq_mask)12252d286fbSkiyohara mvsoc_bridge_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
12352d286fbSkiyohara 			    uint32_t irq_mask)
12452d286fbSkiyohara {
12552d286fbSkiyohara 
12652d286fbSkiyohara 	write_mlmbreg(MVSOC_MLMB_MLMBIMR,
12752d286fbSkiyohara 	    read_mlmbreg(MVSOC_MLMB_MLMBIMR) & ~irq_mask);
12852d286fbSkiyohara }
12952d286fbSkiyohara 
13052d286fbSkiyohara static int
mvsoc_bridge_pic_find_pending_irqs(struct pic_softc * pic)13152d286fbSkiyohara mvsoc_bridge_pic_find_pending_irqs(struct pic_softc *pic)
13252d286fbSkiyohara {
13352d286fbSkiyohara 	uint32_t pending;
13452d286fbSkiyohara 
13552d286fbSkiyohara 	pending =
13652d286fbSkiyohara 	    read_mlmbreg(MVSOC_MLMB_MLMBICR) & read_mlmbreg(MVSOC_MLMB_MLMBIMR);
13794a0b335Sjakllsch 
13852d286fbSkiyohara 	if (pending == 0)
13952d286fbSkiyohara 		return 0;
14094a0b335Sjakllsch 
14194a0b335Sjakllsch 	return pic_mark_pending_sources(pic, 0, pending);
14252d286fbSkiyohara }
14352d286fbSkiyohara 
14452d286fbSkiyohara /* ARGSUSED */
14552d286fbSkiyohara static void
mvsoc_bridge_pic_establish_irq(struct pic_softc * pic,struct intrsource * is)14652d286fbSkiyohara mvsoc_bridge_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
14752d286fbSkiyohara {
14852d286fbSkiyohara 	/* Nothing */
14952d286fbSkiyohara }
15052d286fbSkiyohara 
15152d286fbSkiyohara static void
mvsoc_bridge_pic_source_name(struct pic_softc * pic,int irq,char * buf,size_t len)15252d286fbSkiyohara mvsoc_bridge_pic_source_name(struct pic_softc *pic, int irq, char *buf,
15352d286fbSkiyohara 			     size_t len)
15452d286fbSkiyohara {
15552d286fbSkiyohara 
15652d286fbSkiyohara 	strlcpy(buf, sources[irq], len);
15752d286fbSkiyohara }
158