public inbox for linuxppc-dev@ozlabs.org 
 help / color / mirror / Atom feed
From: Nicolas DET <nd@bplan-gmbh•de>
To: Grant Likely <grant.likely@secretlab•ca>
Cc: akpm@osdl•org, sl@bplan-gmbh•de, linuxppc-dev@ozlabs•org,
	linuxppc-embedded@ozlabs•org, sha@pengutronix•de
Subject: Re: [PATCH] General CHRP/MPC5K2 platform support patch
Date: Thu, 26 Oct 2006 21:21:30 +0200	[thread overview]
Message-ID: <45410ABA.9000902@bplan-gmbh.de> (raw)
In-Reply-To: <528646bc0610261214i34351884reb3171413e4c105@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 611 bytes --]

Grant Likely wrote:

>>
>> diff -uprN a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
>> --- a/include/asm-ppc/mpc52xx.h 2006-10-25 19:07:48.000000000 +0200
>> +++ b/include/asm-ppc/mpc52xx.h 2006-10-25 19:11:55.000000000 +0200
>> @@ -119,7 +119,7 @@ enum ppc_sys_devices {
>>  #define MPC52xx_SDMA_IRQ_NUM   17
>>  #define MPC52xx_PERP_IRQ_NUM   23
>>
>> -#define MPC52xx_CRIT_IRQ_BASE  1
>> +#define MPC52xx_CRIT_IRQ_BASE  0
> 
> Is this *strictly* necessary for adding mpc52xx-pic support to
> arch/powerpc?  If not, then move it to a separate patch.


Removed as it does not hurt ARCH=powerpc.

Bye

[-- Attachment #2: chrpmpc52xx_2.6.19-rc3.patch --]
[-- Type: text/plain, Size: 14370 bytes --]

--- a/arch/powerpc/sysdev/Makefile	2006-10-25 19:07:24.000000000 +0200
+++ b/arch/powerpc/sysdev/Makefile	2006-10-26 11:38:02.000000000 +0200
@@ -13,6 +13,7 @@ obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_PPC_TODC)		+= todc.o
 obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
+obj-$(CONFIG_PPC_MPC52xx_PIC)	+= mpc52xx_pic.o
 
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_I8259)		+= i8259.o
--- a/arch/powerpc/sysdev/mpc52xx_pic.c	1970-01-01 01:00:00.000000000 +0100
+++ b/arch/powerpc/sysdev/mpc52xx_pic.c	2006-10-26 18:55:04.000000000 +0200
@@ -0,0 +1,368 @@
+/*
+ * arch/powerpc/sysdev/mpc52xx_pic.c
+ *
+ * Programmable Interrupt Controller functions for the Freescale MPC52xx 
+ * embedded CPU.
+ * 
+ * Maintainer : Sylvain Munaut <tnt@246tNt•com>
+ *
+ * Based on (well, mostly copied from) the code from the 2.4 kernel by
+ * Dale Farnsworth <dfarnsworth@mvista•com> and Kent Borg.
+ * 
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt•com>
+ * Copyright (C) 2003 Montavista Software, Inc
+ * 
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/stddef.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/stddef.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/prom.h>
+
+#include <asm/mpc52xx.h>
+
+static struct mpc52xx_intr __iomem *intr;
+static struct mpc52xx_sdma __iomem *sdma;
+
+static struct irq_host *mpc52xx_irqhost = NULL;
+
+static void
+mpc52xx_ic_disable(unsigned int virq)
+{
+        u32 val;
+	int irq;
+
+	irq = irq_map[virq].hwirq;
+
+	pr_debug("%s: irq=%d\n", __func__, irq);
+
+        if (irq == MPC52xx_IRQ0) {
+                val = in_be32(&intr->ctrl);
+                val &= ~(1 << 11);
+                out_be32(&intr->ctrl, val);
+        } else if (irq < MPC52xx_IRQ1) {
+                BUG();
+        } else if (irq <= MPC52xx_IRQ3) {
+                val = in_be32(&intr->ctrl);
+                val &= ~(1 << (10 - (irq - MPC52xx_IRQ1)));
+                out_be32(&intr->ctrl, val);
+        } else if (irq < MPC52xx_SDMA_IRQ_BASE) {
+                val = in_be32(&intr->main_mask);
+                val |= 1 << (16 - (irq - MPC52xx_MAIN_IRQ_BASE));
+                out_be32(&intr->main_mask, val);
+        } else if (irq < MPC52xx_PERP_IRQ_BASE) {
+                val = in_be32(&sdma->IntMask);
+                val |= 1 << (irq - MPC52xx_SDMA_IRQ_BASE);
+                out_be32(&sdma->IntMask, val);
+        } else {
+                val = in_be32(&intr->per_mask);
+                val |= 1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE));
+                out_be32(&intr->per_mask, val);
+        }
+}
+
+static void
+mpc52xx_ic_enable(unsigned int virq)
+{
+        u32 val;
+	int irq;
+
+	irq = irq_map[virq].hwirq;
+
+	pr_debug("%s: irq=%d\n", __func__, irq);
+
+        if (irq == MPC52xx_IRQ0) {
+                val = in_be32(&intr->ctrl);
+                val |= 1 << 11;
+                out_be32(&intr->ctrl, val);
+        } else if (irq < MPC52xx_IRQ1) {
+                BUG();
+        } else if (irq <= MPC52xx_IRQ3) {
+                val = in_be32(&intr->ctrl);
+                val |= 1 << (10 - (irq - MPC52xx_IRQ1));
+                out_be32(&intr->ctrl, val);
+        } else if (irq < MPC52xx_SDMA_IRQ_BASE) {
+                val = in_be32(&intr->main_mask);
+                val &= ~(1 << (16 - (irq - MPC52xx_MAIN_IRQ_BASE)));
+                out_be32(&intr->main_mask, val);
+        } else if (irq < MPC52xx_PERP_IRQ_BASE) {
+                val = in_be32(&sdma->IntMask);
+                val &= ~(1 << (irq - MPC52xx_SDMA_IRQ_BASE));
+                out_be32(&sdma->IntMask, val);
+        } else {
+                val = in_be32(&intr->per_mask);
+                val &= ~(1 << (31 - (irq - MPC52xx_PERP_IRQ_BASE)));
+                out_be32(&intr->per_mask, val);
+        }
+}
+
+static void
+mpc52xx_ic_ack(unsigned int virq)
+{
+        u32 val;
+	int irq;
+
+	irq = irq_map[virq].hwirq;
+
+	pr_debug("%s: irq=%d\n", __func__, irq);
+
+        /*
+         * Only some irqs are reset here, others in interrupting hardware.
+         */
+
+        switch (irq) {
+        case MPC52xx_IRQ0:
+                val = in_be32(&intr->ctrl);
+                val |= 0x08000000;
+                out_be32(&intr->ctrl, val);
+                break;
+        case MPC52xx_CCS_IRQ:
+                val = in_be32(&intr->enc_status);
+                val |= 0x00000400;
+                out_be32(&intr->enc_status, val);
+                break;
+        case MPC52xx_IRQ1:
+                val = in_be32(&intr->ctrl);
+                val |= 0x04000000;
+                out_be32(&intr->ctrl, val);
+                break;
+        case MPC52xx_IRQ2:
+                val = in_be32(&intr->ctrl);
+                val |= 0x02000000;
+                out_be32(&intr->ctrl, val);
+                break;
+        case MPC52xx_IRQ3:
+                val = in_be32(&intr->ctrl);
+                val |= 0x01000000;
+                out_be32(&intr->ctrl, val);
+                break;
+        default:
+                if (irq >= MPC52xx_SDMA_IRQ_BASE
+                                && irq < (MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)) {
+                        out_be32(&sdma->IntPend,
+                                 1 << (irq - MPC52xx_SDMA_IRQ_BASE));
+                }
+
+                break;
+        }
+
+}
+
+static void
+mpc52xx_ic_disable_and_ack(unsigned int irq)
+{
+        mpc52xx_ic_disable(irq);
+        mpc52xx_ic_ack(irq);
+}
+
+static void
+mpc52xx_ic_end(unsigned int irq)
+{
+        if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+                mpc52xx_ic_enable(irq);
+}
+
+static struct irq_chip mpc52xx_irqchip = {
+	.name	= " MPC52xx  ",
+	.enable		= mpc52xx_ic_enable,
+	.disable	= mpc52xx_ic_disable,
+	.ack		= mpc52xx_ic_disable_and_ack,
+	.end		= mpc52xx_ic_end,
+};
+
+
+extern struct device_node *find_mpc52xx_pic(void);
+static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
+{
+	pr_debug("%s: %p vs %p\n", __func__, find_mpc52xx_pic(),  node);
+	return find_mpc52xx_pic() == node;
+}
+
+static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
+                            u32 *intspec, unsigned int intsize,
+                            irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+{
+        static unsigned char map_senses[4] = {
+                IRQ_TYPE_LEVEL_HIGH,
+                IRQ_TYPE_EDGE_FALLING,
+                IRQ_TYPE_EDGE_RISING,
+		IRQ_TYPE_LEVEL_LOW,
+        };
+
+        int intrvect_l1;
+        int intrvect_l2;
+	int intrvect_type;
+        int intrvect_linux;
+
+        pr_debug("%s:\n", __func__);
+
+	if (intsize!=3)
+		return -1;
+
+        intrvect_l1 = (int) intspec[0];
+        intrvect_l2 = (int) intspec[1];
+	intrvect_type = (int) intspec[2];
+
+        pr_debug("l1=%d, l2=%d, type=%d\n", intrvect_l1, intrvect_l2, intrvect_type );
+
+        switch(intrvect_l1) {
+        case 0: /* Critical */
+                intrvect_linux = MPC52xx_CRIT_IRQ_BASE;
+                break;
+
+        case 1: /* Main */
+                intrvect_linux = MPC52xx_MAIN_IRQ_BASE;
+                break;
+
+        case 2: /* Periph */
+                intrvect_linux = MPC52xx_PERP_IRQ_BASE;
+                break;
+
+        case 3: /* Bestcomm */
+                intrvect_linux = MPC52xx_SDMA_IRQ_BASE;
+                break;
+
+        default:
+                if ( printk_ratelimit() )
+			printk(KERN_ERR "Wrong L1 interrupt vector (%d)\n", intrvect_l1);
+
+                return -1;
+        }
+
+        intrvect_linux += intrvect_l2;
+
+        pr_debug("return %d\n", intrvect_linux);
+
+	*out_hwirq = intrvect_linux;
+	*out_flags = map_senses[intrvect_type];
+
+        return 0;
+
+}
+
+int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw)
+{
+	pr_debug("%s: v=%d, hw=%d\n", __func__, virq, (int) hw);
+
+	return 0;
+}
+
+void mpc52xx_irqhost_unmap(struct irq_host *h, unsigned int virq)
+{
+	pr_debug("%s: v=%d\n", __func__, virq);
+}
+
+static struct irq_host_ops mpc52xx_irqhost_ops = {
+        .match = mpc52xx_irqhost_match,
+        .xlate = mpc52xx_irqhost_xlate,
+	.map   = mpc52xx_irqhost_map,
+	.unmap = mpc52xx_irqhost_unmap,
+};
+
+void __init
+mpc52xx_init_irq(void)
+{
+	int i;
+        u32 intr_ctrl;
+	
+
+        /* Remap the necessary zones */
+        intr = ioremap(MPC52xx_PA(MPC52xx_INTR_OFFSET), MPC52xx_INTR_SIZE);
+        sdma = ioremap(MPC52xx_PA(MPC52xx_SDMA_OFFSET), MPC52xx_SDMA_SIZE);
+
+        if ((intr==NULL) || (sdma==NULL))
+                panic("Can't ioremap PIC/SDMA register or init_irq !");
+
+        /* Disable all interrupt sources. */
+        out_be32(&sdma->IntPend, 0xffffffff);	/* 1 means clear pending */
+        out_be32(&sdma->IntMask, 0xffffffff);	/* 1 means disabled */
+        out_be32(&intr->per_mask, 0x7ffffc00);	/* 1 means disabled */
+        out_be32(&intr->main_mask, 0x00010fff);	/* 1 means disabled */
+        intr_ctrl = in_be32(&intr->ctrl);
+        intr_ctrl &=    0x00ff0000;	/* Keeps IRQ[0-3] config */
+        intr_ctrl |=	0x0f000000 |	/* clear IRQ 0-3 */
+                     0x00001000 |	/* MEE master external enable */
+                     0x00000000 |	/* 0 means disable IRQ 0-3 */
+                     0x00000001;	/* CEb route critical normally */
+        out_be32(&intr->ctrl, intr_ctrl);
+
+        /* Zero a bunch of the priority settings.  */
+        out_be32(&intr->per_pri1, 0);
+        out_be32(&intr->per_pri2, 0);
+        out_be32(&intr->per_pri3, 0);
+        out_be32(&intr->main_pri1, 0);
+        out_be32(&intr->main_pri2, 0);
+        /* Initialize irq_desc[i].handler's with mpc52xx_ic. */
+        for (i = 0; i < NR_IRQS; i++) {
+                irq_desc[i].chip = &mpc52xx_irqchip;
+                irq_desc[i].status = IRQ_LEVEL;
+		
+        }
+
+#define IRQn_MODE(intr_ctrl,irq) (((intr_ctrl) >> (22-(i<<1))) & 0x03)
+        for (i=0 ; i<4 ; i++) {
+                int mode;
+                mode = IRQn_MODE(intr_ctrl,i);
+                if ((mode == 0x1) || (mode == 0x2))
+                        irq_desc[i?MPC52xx_IRQ1+i-1:MPC52xx_IRQ0].status = 0;
+        }
+
+	/*
+	 * As last step, add an irq host to translate the real
+	 * hw irq information provided by the ofw to linux virq
+	*/
+
+	mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_IRQS, &mpc52xx_irqhost_ops, -1);
+	pr_debug("%s: mpc52xx_irqhost =%p\n", __func__, mpc52xx_irqhost );
+}
+
+unsigned int
+mpc52xx_get_irq(void)
+{
+        u32 status;
+	int virq;
+        int irq = NO_IRQ_IGNORE;
+
+        status = in_be32(&intr->enc_status);
+        if (status & 0x00000400)
+        {		/* critical */
+                irq = (status >> 8) & 0x3;
+                if (irq == 2)			/* high priority peripheral */
+                        goto peripheral;
+                irq += MPC52xx_CRIT_IRQ_BASE;
+        } else if (status & 0x00200000)
+        {		/* main */
+                irq = (status >> 16) & 0x1f;
+                if (irq == 4)			/* low priority peripheral */
+                        goto peripheral;
+                irq += MPC52xx_MAIN_IRQ_BASE;
+        } else if (status & 0x20000000)
+        {		/* peripheral */
+peripheral:
+                irq = (status >> 24) & 0x1f;
+                if (irq == 0) {			/* bestcomm */
+                        status = in_be32(&sdma->IntPend);
+                        irq = ffs(status) + MPC52xx_SDMA_IRQ_BASE-1;
+                } else
+                        irq += MPC52xx_PERP_IRQ_BASE;
+
+        }
+
+	virq = irq_linear_revmap(mpc52xx_irqhost, irq);
+	pr_debug("%s: irq=%d -> %d\n", __func__, irq, virq);
+
+        return virq;
+}
+
--- a/arch/powerpc/Kconfig	2006-10-25 19:07:23.000000000 +0200
+++ b/arch/powerpc/Kconfig	2006-10-26 18:55:58.000000000 +0200
@@ -384,6 +384,11 @@ config PPC_CHRP
 	select PPC_RTAS
 	select PPC_MPC106
 	select PPC_UDBG_16550
+	select PPC_MPC52xx_PIC
+	default y
+
+config PPC_MPC52xx_PIC
+        bool
 	default y
 
 config PPC_PMAC
--- a/arch/powerpc/platforms/chrp/setup.c	2006-10-25 19:07:23.000000000 +0200
+++ b/arch/powerpc/platforms/chrp/setup.c	2006-10-26 18:56:34.000000000 +0200
@@ -51,6 +51,7 @@
 #include <asm/mpic.h>
 #include <asm/rtas.h>
 #include <asm/xmon.h>
+#include <asm/mpc52xx.h>
 
 #include "chrp.h"
 
@@ -435,6 +436,51 @@ static struct irqaction xmon_irqaction =
 };
 #endif
 
+
+struct device_node *find_mpc52xx_pic(void)
+{
+	struct device_node *dev;
+	const char *piccompatible_list[] =
+	{
+		"mpc5200-interrupt-controller",
+		"mpc52xx-interrupt-controller",
+		"mpc52xx-pic",
+		"mpc5200-pic",
+		"5200-interrupt-controller",
+		"52xx-interrupt-controller",
+		"52xx-pic",
+		"5200-pic",
+		NULL
+	};
+
+	/* Look for an MPC52xx interrupt controller */
+	for_each_node_by_type(dev, "interrupt-controller")
+	{
+		const char **piccompatible_entry = piccompatible_list;
+
+		for(piccompatible_entry = piccompatible_list; *piccompatible_entry; piccompatible_entry++ )
+		{
+			if (device_is_compatible(dev, *piccompatible_entry ))
+				return dev;
+		}
+	}
+
+	return NULL;
+}
+
+static int  __init chrp_find_mpc52xx_pic(void)
+{
+	if (find_mpc52xx_pic())
+	{
+		printk(KERN_INFO "Found MPC52xx Interrupt Controller\n");
+		ppc_md.get_irq = mpc52xx_get_irq;
+		mpc52xx_init_irq();
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
 static void __init chrp_find_8259(void)
 {
 	struct device_node *np, *pic = NULL;
@@ -473,8 +519,11 @@ static void __init chrp_find_8259(void)
 		break;
 	}
 	if (np == NULL)
-		printk(KERN_WARNING "Cannot find PCI interrupt acknowledge"
-		       " address, polling\n");
+	{
+		printk(KERN_WARNING "Cannot find PCI/i8259 interrupt acknowledge"
+		       " Fix your tree!\n");
+		return;
+	}
 
 	i8259_init(pic, chrp_int_ack);
 	if (ppc_md.get_irq == NULL)
@@ -494,6 +543,8 @@ void __init chrp_init_IRQ(void)
 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
 	struct device_node *kbd;
 #endif
+
+	chrp_find_mpc52xx_pic();
 	chrp_find_openpic();
 	chrp_find_8259();
 

[-- Attachment #3: nd.vcf --]
[-- Type: text/x-vcard, Size: 249 bytes --]

begin:vcard
fn:Nicolas DET ( bplan GmbH )
n:DET;Nicolas
org:bplan GmbH
adr:;;;;;;Germany
email;internet:nd@bplan-gmbh•de
title:Software Entwicklung
tel;work:+49 6171 9187 - 31
x-mozilla-html:FALSE
url:http://www.bplan-gmbh.de
version:2.1
end:vcard


  reply	other threads:[~2006-10-26 19:21 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-25 19:05 [PATCH] General CHRP/MPC5K2 platform support patch Nicolas DET
2006-10-25 21:59 ` Paul Mackerras
2006-10-25 22:41   ` Grant Likely
2006-10-25 22:59     ` Benjamin Herrenschmidt
2006-10-26 11:09       ` Nicolas DET
2006-10-26 11:17     ` Nicolas DET
2006-10-25 22:53 ` Benjamin Herrenschmidt
2006-10-26 11:09   ` Nicolas DET
2006-10-26 12:49     ` Benjamin Herrenschmidt
2006-10-26 12:59       ` Nicolas DET
2006-10-26 16:02         ` Grant Likely
2006-10-26 16:09           ` Grant Likely
2006-10-26 17:06             ` Nicolas DET
2006-10-26 17:54               ` Sylvain Munaut
2006-10-27  3:08                 ` Benjamin Herrenschmidt
2006-10-26 19:14               ` Grant Likely
2006-10-26 19:21                 ` Nicolas DET [this message]
2006-10-26 19:32                   ` Nicolas DET
2006-10-27  2:49               ` Benjamin Herrenschmidt
2006-10-26 16:45           ` Sven Luther
2006-10-26 19:50           ` Nicolas DET
2006-10-26 20:00             ` Grant Likely
2006-10-26 20:51               ` Sylvain Munaut
2006-10-27  3:28               ` Benjamin Herrenschmidt
2006-10-27 14:52                 ` Nicolas DET
2006-10-27 15:04                   ` Nicolas DET
2006-10-27 17:08                     ` Jon Loeliger
2006-10-28  0:27                       ` Stephen Rothwell
2006-10-27 22:34                     ` Benjamin Herrenschmidt
2006-10-27 22:05                   ` Sylvain Munaut
2006-10-25 23:01 ` Grant Likely
2006-10-25 23:06   ` Benjamin Herrenschmidt
2006-10-25 23:13     ` Sven Luther
2006-10-26 12:09     ` Nicolas DET
2006-10-26 12:51       ` Benjamin Herrenschmidt
2006-10-26 17:17 ` John Rigby
2006-10-26 17:23   ` Nicolas DET
2006-10-26 17:33   ` Sylvain Munaut
2006-10-27  3:03     ` Benjamin Herrenschmidt
2006-10-27  2:57   ` Benjamin Herrenschmidt

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=45410ABA.9000902@bplan-gmbh.de \
    --to=nd@bplan-gmbh$(echo .)de \
    --cc=akpm@osdl$(echo .)org \
    --cc=grant.likely@secretlab$(echo .)ca \
    --cc=linuxppc-dev@ozlabs$(echo .)org \
    --cc=linuxppc-embedded@ozlabs$(echo .)org \
    --cc=sha@pengutronix$(echo .)de \
    --cc=sl@bplan-gmbh$(echo .)de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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