linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: stefan.xk.nilsson@stericsson.com (Stefan Nilsson9)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/4] U5500 generic modem IRQ handler
Date: Thu, 23 Sep 2010 19:49:55 +0200	[thread overview]
Message-ID: <1285264197-9316-3-git-send-email-stefan.xk.nilsson@stericsson.com> (raw)
In-Reply-To: <1285264197-9316-1-git-send-email-stefan.xk.nilsson@stericsson.com>

From: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com>

Acked-by: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Stefan Nilsson XK <stefan.xk.nilsson@stericsson.com>
---
 arch/arm/mach-ux500/modem_irq.c |  139 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-ux500/modem_irq.c

diff --git a/arch/arm/mach-ux500/modem_irq.c b/arch/arm/mach-ux500/modem_irq.c
new file mode 100644
index 0000000..c0e49be
--- /dev/null
+++ b/arch/arm/mach-ux500/modem_irq.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ * Author: Stefan Nilsson <stefan.xk.nilsson@stericsson.com> for ST-Ericsson.
+ * Author: Martin Persson <martin.persson@stericsson.com> for ST-Ericsson.
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+
+#define MODEM_INTCON_BASE_ADDR 0xBFFD3000
+#define MODEM_INTCON_SIZE 0xFFF
+
+#define DEST_IRQ41_OFFSET 0x2A4
+#define DEST_IRQ43_OFFSET 0x2AC
+#define DEST_IRQ45_OFFSET 0x2B4
+
+#define PRIO_IRQ41_OFFSET 0x6A4
+#define PRIO_IRQ43_OFFSET 0x6AC
+#define PRIO_IRQ45_OFFSET 0x6B4
+
+#define ALLOW_IRQ_OFFSET 0x104
+
+#define MODEM_INTCON_CPU_NBR 0x1
+#define MODEM_INTCON_PRIO_HIGH 0x0
+
+#define MODEM_INTCON_ALLOW_IRQ41 0x0200
+#define MODEM_INTCON_ALLOW_IRQ43 0x0800
+#define MODEM_INTCON_ALLOW_IRQ45 0x2000
+
+#define MODEM_IRQ_REG_OFFSET 0x4
+
+struct modem_irq {
+	void __iomem *modem_intcon_base;
+};
+
+
+static void setup_modem_intcon(void __iomem *modem_intcon_base)
+{
+	/* IC_DESTINATION_BASE_ARRAY - Which CPU to receive the IRQ */
+	writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ41_OFFSET);
+	writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ43_OFFSET);
+	writel(MODEM_INTCON_CPU_NBR, modem_intcon_base + DEST_IRQ45_OFFSET);
+
+	/* IC_PRIORITY_BASE_ARRAY - IRQ priority in modem IRQ controller */
+	writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ41_OFFSET);
+	writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ43_OFFSET);
+	writel(MODEM_INTCON_PRIO_HIGH, modem_intcon_base + PRIO_IRQ45_OFFSET);
+
+	/* IC_ALLOW_ARRAY - IRQ enable */
+	writel(MODEM_INTCON_ALLOW_IRQ41 |
+		   MODEM_INTCON_ALLOW_IRQ43 |
+		   MODEM_INTCON_ALLOW_IRQ45,
+		   modem_intcon_base + ALLOW_IRQ_OFFSET);
+}
+
+static irqreturn_t modem_cpu_irq_handler(int irq, void *data)
+{
+	int real_irq;
+	int virt_irq;
+	struct modem_irq *mi = (struct modem_irq *)data;
+
+	/* Read modem side IRQ number from modem IRQ controller */
+	real_irq = readl(mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET) & 0xFF;
+	virt_irq = IRQ_MODEM_EVENTS_BASE + real_irq;
+
+	pr_debug("modem_irq: Worker read addr 0x%X and got value 0x%X "
+		 "which will be 0x%X (%d) which translates to "
+		 "virtual IRQ 0x%X (%d)!\n",
+		   (u32)mi->modem_intcon_base + MODEM_IRQ_REG_OFFSET,
+		   real_irq,
+		   real_irq & 0xFF,
+		   real_irq & 0xFF,
+		   virt_irq,
+		   virt_irq);
+
+	if (virt_irq != 0)
+		generic_handle_irq(virt_irq);
+
+	pr_debug("modem_irq: Done handling virtual IRQ %d!\n", virt_irq);
+
+	return IRQ_HANDLED;
+}
+
+static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip)
+{
+	set_irq_chip(irq, modem_irq_chip);
+	set_irq_handler(irq, handle_simple_irq);
+	set_irq_flags(irq, IRQF_VALID);
+
+	pr_debug("modem_irq: Created virtual IRQ %d\n", irq);
+}
+
+static int modem_irq_init(void)
+{
+	int err;
+	static struct irq_chip  modem_irq_chip;
+	struct modem_irq *mi;
+
+	pr_info("modem_irq: Set up IRQ handler for incoming modem IRQ %d\n",
+		   IRQ_DB5500_MODEM);
+
+	mi = kmalloc(sizeof(struct modem_irq), GFP_KERNEL);
+	if (!mi) {
+		pr_err("modem_irq: Could not allocate device\n");
+		return -ENOMEM;
+	}
+
+	mi->modem_intcon_base =
+		ioremap(MODEM_INTCON_BASE_ADDR, MODEM_INTCON_SIZE);
+	pr_debug("modem_irq: ioremapped modem_intcon_base from "
+		 "phy 0x%x to virt 0x%x\n", MODEM_INTCON_BASE_ADDR,
+		 (u32)mi->modem_intcon_base);
+
+	setup_modem_intcon(mi->modem_intcon_base);
+
+	modem_irq_chip = dummy_irq_chip;
+	modem_irq_chip.name = "modem_irq";
+
+	/* Create the virtual IRQ:s needed */
+	create_virtual_irq(MBOX_PAIR0_VIRT_IRQ, &modem_irq_chip);
+	create_virtual_irq(MBOX_PAIR1_VIRT_IRQ, &modem_irq_chip);
+	create_virtual_irq(MBOX_PAIR2_VIRT_IRQ, &modem_irq_chip);
+
+	err = request_threaded_irq(IRQ_DB5500_MODEM, NULL,
+				   modem_cpu_irq_handler, IRQF_ONESHOT,
+				   "modem_irq", mi);
+	if (err)
+		pr_err("modem_irq: Could not register IRQ %d\n",
+		       IRQ_DB5500_MODEM);
+
+	return 0;
+}
+
+arch_initcall(modem_irq_init);
-- 
1.7.2.2

  parent reply	other threads:[~2010-09-23 17:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-09-23 17:49 [PATCH 0/4] U5500 mailbox driver and modem irq handler Stefan Nilsson9
2010-09-23 17:49 ` [PATCH 1/4] Resources for U5500 mbox " Stefan Nilsson9
2010-09-24  7:02   ` Stefan Nilsson XK
2010-09-23 17:49 ` Stefan Nilsson9 [this message]
2010-09-23 17:49 ` [PATCH 3/4] U5500 mailbox driver Stefan Nilsson9
2010-09-23 17:49 ` [PATCH 4/4] Build configuration for U5500 mbox and modem irq handler Stefan Nilsson9

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1285264197-9316-3-git-send-email-stefan.xk.nilsson@stericsson.com \
    --to=stefan.xk.nilsson@stericsson.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).