LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] General CHRP/MPC5K2 platform support patch
From: Nicolas DET @ 2006-10-26 12:09 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: akpm, sl, linuxppc-dev, linuxppc-embedded, sha
In-Reply-To: <1161817576.22582.142.camel@localhost.localdomain>

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

Benjamin Herrenschmidt wrote:

>>> * serial stuff / IBP Freq. As this frequency is MPC52xx specific. I
>>> think it would make sense to add a new func mpc52xx_getipbfreq(void).
>>> The way it would be implemented may depend of the architecture. Our
>>> firmware contains an 'ipb-freq' property in '/builtin/'.
> 
> BTW. I forgot to comment on the above in my previous mail... As I said,
> there should be no such thing. Instead, the IPB freq should be in the
> device-tree.
> 
> 
> 

What do you mean exactly by 'the IPB freq should be in the device-tree'? 
It is as property.

Regards

[-- Attachment #2: 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


^ permalink raw reply

* Re: [PATCH] General CHRP/MPC5K2 platform support patch
From: Nicolas DET @ 2006-10-26 11:17 UTC (permalink / raw)
  To: Grant Likely
  Cc: akpm, sl, linuxppc-dev, Paul Mackerras, linuxppc-embedded, sha
In-Reply-To: <528646bc0610251541s21bb45f1t6fc911778d5084@mail.gmail.com>

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

Paul Mackerras wrote:
 > Nicolas DET writes:
 >
 >>  	if (machine && strncmp(machine, "Pegasos", 7) == 0) {
 >>  		_chrp_type = _CHRP_Pegasos;
 >> +	} else if (machine && strncmp(machine, "EFIKA5K2", 8) == 0) {
 >> +		_chrp_type =_CHRP_E5K2;
 >
 > This whole _chrp_type thing, and having to do different things based
 > on the root-node model property, is really only a workaround for
 > older machines with inadequate device trees.  Decisions about things
 > like which interrupt controller driver(s) to instantiate should be
 > taken based on properties in the appropriate device-tree nodes, for
 > instance the model and compatible properties in the node(s) for the
 > interrupt controller(s).  In fact I'd like to get rid of _chrp_type
 > completely.
 >

I remove this part of the patch which is only cosmetic (good CHRP name).

 >> 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
 >
 > What is this going to do to other 52xx users?
 >

IRQ 0 may cause issue in earlier kernel as far as I understood. New one, 
using the new IRQ stuff, just works (at least works great here).

This is a revert change from:
http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e21b9f2e9a580ce7375ec58953c1bb19aabe0db4
Regards,

[-- Attachment #2: 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


^ permalink raw reply

* Re: [PATCH] General CHRP/MPC5K2 platform support patch
From: Nicolas DET @ 2006-10-26 11:09 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: akpm, sl, linuxppc-dev, Paul Mackerras, linuxppc-embedded, sha
In-Reply-To: <1161817178.22582.138.camel@localhost.localdomain>

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

Benjamin Herrenschmidt wrote:

>  - Format of the interrupt cells (they have come up upon my suggestion
> to a 3-cell based format (could probably be compressed a bit but heh)
> and that should be documented publically)
> 

It's some kind of 'documented' in mpc52xx_pic.c/xlate()

>  - Binding (set of required properties and their definitions) for on
> chip devices, and more specifically, for representing the bestcomm and
> the links between devices and associated bestcomm tasks.

Bestcomm is something a bit 'weird'. I think we are the only to use this 
approach (task code loaded by the OFW and not by the OS). As said 
earlier, I've been in contact with an bestcomm coders and I think we 
would work together on this subject.


[-- Attachment #2: 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


^ permalink raw reply

* Re: [PATCH] General CHRP/MPC5K2 platform support patch
From: Nicolas DET @ 2006-10-26 11:09 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: akpm, Sylvain Munaut, sl, linuxppc-dev, linuxppc-embedded, sha
In-Reply-To: <1161816783.22582.132.camel@localhost.localdomain>

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

Benjamin Herrenschmidt wrote:
> On Wed, 2006-10-25 at 21:05 +0200, Nicolas DET wrote:
> 
> In addition to various whitespace damage in the patch...
> 
>> +	if (_chrp_type ==  _CHRP_E5K2) {
>> +		ppc_md.get_irq = mpc52xx_get_irq;
>> +		mpc52xx_init_irq();
>> +		return;
>> +	}
> 
> As I wrote, the above should be unnecessary.
> 
>>  	chrp_find_openpic();
>>  	chrp_find_8259();
> 
> Just add a
> 
> 	chrp_find_mpc5200pic();
> 
> Which will set itself as the default controller and set ppc_md.get_irq
> if none have done it before.
>  
>> @@ -530,6 +540,9 @@ chrp_init2(void)
>>  	chrp_nvram_init();
>>  #endif
>>  
>> +	if (_chrp_type == _CHRP_E5K2)
>> +		return;
> 

Done.


>> +static void
>> +mpc52xx_ic_disable(unsigned int virq)
>> +{
>> +        u32 val;
>> +	int irq;
>> +
>> +	irq = irq_map[virq].hwirq;
> 
> You should test if the result is valid just in case you were called with
> [...]
> I'm surprised the revmap is working at all... considering the issues you
> have above. You are lucky but things should be fixed anyway.
> 

As said in the mail. I'm waiting for the opinion of the original authors 
and the mainteners. What's why I did not made much change in this file.
In the current patch, I know do:
mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR, NR_IRQS, 
&mpc52xx_irqhost_ops, -1);

Which should be ok.

>> --- a/arch/powerpc/sysdev/Makefile	2006-10-25 19:07:24.000000000 +0200
>> +++ b/arch/powerpc/sysdev/Makefile	2006-10-25 20:33:32.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_CHRP)		+= mpc52xx_pic.o
> 

Done.

Regards

[-- Attachment #2: chrpmpc52xx_2.6.19-rc3.patch --]
[-- Type: text/plain, Size: 15111 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	2006-10-25 19:07:24.000000000 +0200
+++ b/arch/powerpc/sysdev/mpc52xx_pic.c	2006-10-26 10:55:44.000000000 +0200
@@ -0,0 +1,371 @@
+/*
+ * arch/powerpc/sysdev/mpc52xx_pic.c
+ *
+ * Programmable Interrupt Controller functions for the Freescale MPC52xx 
+ * embedded CPU.
+ * Modified for CHRP Efika 5K2
+ * 
+ * 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.
+ */
+
+//#define DEBUG
+
+#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 11:32:54.000000000 +0200
@@ -384,6 +384,12 @@ config PPC_CHRP
 	select PPC_RTAS
 	select PPC_MPC106
 	select PPC_UDBG_16550
+	select PPC_MPC52xx_PIC
+	default y
+
+config PPC_MPC52xx_PIC
+        bool
+	depends on PPC_CHRP
 	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 10:59:39.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;
@@ -494,8 +540,12 @@ void __init chrp_init_IRQ(void)
 #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON)
 	struct device_node *kbd;
 #endif
-	chrp_find_openpic();
-	chrp_find_8259();
+
+	if ( chrp_find_mpc52xx_pic() < 0)
+	{
+		chrp_find_openpic();
+		chrp_find_8259();
+	}
 
 #ifdef CONFIG_SMP
 	/* Pegasos has no MPIC, those ops would make it crash. It might be an
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
 #define MPC52xx_MAIN_IRQ_BASE	(MPC52xx_CRIT_IRQ_BASE + MPC52xx_CRIT_IRQ_NUM)
 #define MPC52xx_SDMA_IRQ_BASE	(MPC52xx_MAIN_IRQ_BASE + MPC52xx_MAIN_IRQ_NUM)
 #define MPC52xx_PERP_IRQ_BASE	(MPC52xx_SDMA_IRQ_BASE + MPC52xx_SDMA_IRQ_NUM)
@@ -415,7 +415,7 @@ struct mpc52xx_cdm {
 #ifndef __ASSEMBLY__
 
 extern void mpc52xx_init_irq(void);
-extern int mpc52xx_get_irq(void);
+extern unsigned int mpc52xx_get_irq(void);
 
 extern unsigned long mpc52xx_find_end_of_memory(void);
 extern void mpc52xx_set_bat(void);

[-- 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


^ permalink raw reply

* Linux-2.6.x for TQM860L
From: tran vanle @ 2006-10-26  9:50 UTC (permalink / raw)
  To: linuxppc-embedded

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

Hi WolfgangDenk
  I have just read pages
  http://www.denx.de/wiki/Know/Linux24vs26 and i see you had build Linux-2.6.11.7 for TQM860L with instruction below 
  Download  Kernel Version 2.6.11.7 from kernel.org plus 8xx v2.6 TLB patch by Marcelo Tosatti (4 Apr 2005)
  Download config-2.6.11.7-TQM860L
  Build instruction

-> export CROSS_COMPILE=ppc_8xx-  -> cp ../config-2.6.11.7-TQM860L .config  -> make ARCH=ppc CROSS_COMPILE=ppc_8xx- oldconfig  -> time make -j8 ARCH=ppc CROSS_COMPILE=ppc_8xx- uImage
   
  I had done exactly these intruction but I received error 
  Why? Had I missed another guide?
  Thanks
   
  LeVan  

 		
---------------------------------
Do you Yahoo!?
  Help K-Zone create the longest line of footprints and break a world record

[-- Attachment #2: Type: text/html, Size: 1484 bytes --]

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 12/16] cell: add temperature to SPU and CPU sysfs entries
From: Benjamin Herrenschmidt @ 2006-10-26  9:19 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Andrew Morton, linuxppc-dev, Heiko Carstens, linux-kernel,
	cbe-oss-dev
In-Reply-To: <200610260935.01801.arnd@arndb.de>

On Thu, 2006-10-26 at 09:35 +0200, Arnd Bergmann wrote:
> On Thursday 26 October 2006 01:19, Benjamin Herrenschmidt wrote:
> > > 
> > > Will crash if cpu_add_sysdev_attr_group failed...
> > 
> > 
> > Which is a total PITA. If this is the case, then we should modify the
> > add calls to at least initialize enough fields before they can fail for
> > the remove calls not to crash. You don't want to keep track precisely of
> > what file was added and what not and test all of that in your exit code
> > path, it's just insane.
> 
> Heiko suggested that earlied in http://lkml.org/lkml/2006/10/9/22,
> but Andrew didn't like it.
> 
> Currently, the worst is that sysfs_remove_file can be used
> on a nonexisting file,  but sysfs_remove_group cannot, which is
> inconsistent. Either sysfs_remove_file should WARN_ON or
> sysfs_remove_group should silently return, and I'd prefer the
> latter, as it makes users simpler.

We need to argue with Andrew then. I'll have a go tomorrow

Ben.

^ permalink raw reply

* Re: [PATCH] powerpc: Make pci_read_irq_line the default:
From: Zang Roy-r61911 @ 2006-10-26  8:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras; +Cc: linuxppc-dev list
In-Reply-To: <1161843365.5299.21.camel@localhost.localdomain>

On Thu, 2006-10-26 at 14:16, Benjamin Herrenschmidt wrote:

> Index: linux-work/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
> ===================================================================
> ---
> linux-work.orig/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c  
> 2006-10-09 12:03:33.000000000 +1000
> +++
> linux-work/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c       
> 2006-10-26 15:52:15.000000000 +1000

Paul,
	Please do not apply this part of patch. I will prove a new one to
update the irq map hopefully tomorrow.

Roy

	

^ permalink raw reply

* Re: System ACE driver - for 2.6 kernel - need help to understand xsa_thread
From: Ameet Patil @ 2006-10-26  8:00 UTC (permalink / raw)
  To: agnel juni; +Cc: linuxppc-embedded
In-Reply-To: <20061026003115.22528.qmail@web8408.mail.in.yahoo.com>

Hi Junita,
    Its a hack really! When I was developing/porting the SysAce driver 
to 2.6 I tried to maintain the code as is from the 2.4 kernel driver. In 
doing so I found that there is a slight difference between the two 
kernels. i.e. I am not sure why, but the sysace device can only handle 
requests for 2 sectors at a time. This was fine in the 2.4 as the kernel 
always requested 2 sectors. However, in 2.6 I found that this is 
different: the requests are 8 secs. or more. I tried to fix this in vain 
by changing several parameters of the driver during initialization. 
Anyway, due to several issues I didn't try hard to fix it at that time.

Hence this hack: No matter how many sec. req. I get from the kernel, I 
use a loop to req. only 2 secs. at a time. The xsa_device.req_done is 
used as a flag and reset in the XSA IRQ IIRC.

If you find a better approach, please do update me. Hope this helps!

cheers,
-Ameet

agnel juni wrote:
> 
> Hello all
> 
> I am trying to understand the parameters that are sent through "cur_req" 
> function used in funtion xsa_thread in System ACE driver.
> 
> In xsa_thread function in the System ACE driver ,
> 
> In 2.4 kernel:
> --------------------
> while ((stat = cur_req(&SysAce, sector,
>                                        CURRENT->current_nr_sectors,
>                                        CURRENT->buffer)) == XST_DEVICE_BUSY)
>                         xsa_short_delay();
> 
>  
> Where as in 2.6 kernel this is changed to
> ---------------------------------------------------------------
> 
> for(i = xsa_cur_req->current_nr_sectors; i > 0; i-=2){
>                         xsa_device.req_done = 1;
>                         while ((stat = cur_req(&SysAce, sector,
>                                         2,
>                                         buffer)) == XST_DEVICE_BUSY)
>                                 xsa_short_delay();
> #endif
> 
> Ameet , could you help me understand the impact of the parameters, 
> especailly the 3rd paramter which is hardcoded in 2.6 kernel.It would be 
> great if you could clarify this in regard to 'mount' command.
> 
> Thanks in advance
> Junita
> 
> 
> 
> ------------------------------------------------------------------------
> Find out what India is talking about on - Yahoo! Answers India 
> <http://us.rd.yahoo.com/mail/in/yanswers/*http://in.answers.yahoo.com/>
> Send FREE SMS to your friend's mobile from Yahoo! Messenger Version 8. 
> Get it NOW 
> <http://us.rd.yahoo.com/mail/in/messengertagline/*http://in.messenger.yahoo.com> 
> 

^ permalink raw reply

* CPM2 SCC/SMC break handling broken
From: Laurent Pinchart @ 2006-10-26  8:02 UTC (permalink / raw)
  To: linuxppc-embedded

Hi everybody,

I need to generate a break on a CPM2 SMC serial port (same issue with SCC 
serial ports).

The tcsendbreak() man page states that the function should generate a break 
between 250ms and 500ms, but testing showed that the break is one character 
long (10 bits in 8N1 mode).

Breaks are handled by the tty layer (drivers/char/tty_io.c), the generic 
serial layer (drivers/serial/serial_core.c) and the CPM driver 
(drivers/char/cpm_uart/cpm_uart_core.c).

As the tty driver (drivers/serial/serial_core.c) defines a break handler 
(break_ctl), the tty layer calls send_break to send the break:

static int send_break(struct tty_struct *tty, unsigned int duration)
{
        tty->driver->break_ctl(tty, -1);
        if (!signal_pending(current)) {
                msleep_interruptible(duration);
        }
        tty->driver->break_ctl(tty, 0);
        if (signal_pending(current))
                return -EINTR;
        return 0;
}

tty->driver->break_ctl just forwards the call to the CPM driver, which does

static void cpm_uart_break_ctl(struct uart_port *port, int break_state)
{
        struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
        int line = pinfo - cpm_uart_ports;

        pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line,
                break_state);

        if (break_state)
                cpm_line_cr_cmd(line, CPM_CR_STOP_TX);
        else
                cpm_line_cr_cmd(line, CPM_CR_RESTART_TX);
}

CPM_CR_STOP_TX is documented to generate a break of BRKCR characters. The 
BRKCR register is initialized to 1, so only 1 break character is sent, which 
won't last between 250ms and 500ms.

cpm_uart_break_ctl() is not told how long the break must last, so it can't 
modify BRKCR before sending CPM_CR_STOP_TX. A solution would be to let the 
driver handle the break itself instead of having tty_io.c calling 
send_break(). To do that, the driver (serial_core.c) must not declare a break 
handler. This would obviously break all other serial drivers. Another 
solution would be to have a new platform handler for CPM serial ports which 
will turn the I/O ports to low-level outputs. This sounds more like a hack to 
me though.

Could anyone think of a proper solution which would not disturb the other 
drivers too much ?

Laurent Pinchart

^ permalink raw reply

* Re: MPC7448_HPC2 question
From: Zang Roy-r61911 @ 2006-10-26  7:59 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list, Alexandre.Bounine@tundra.com
In-Reply-To: <1161783936.22582.89.camel@localhost.localdomain>

On Wed, 2006-10-25 at 21:45, Benjamin Herrenschmidt wrote:
> On Wed, 2006-10-25 at 17:31 +0800, Zang Roy-r61911 wrote:
> > On Wed, 2006-10-25 at 13:20, Benjamin Herrenschmidt wrote:
> > 
> > > 
> > > Cannot be replaced by:
> > > 
> > >         pci_read_irq_line(dev);
> > 
> > When I use pci_read_irq_line(), the pci interrupt number exceeds the
> > limit of mpic-> irq_count. my mpic->irq_count = 0x18, which is
> gotten
> > from on chip register. 
> > 
> > mpic_host_map() can not return successful value.
> 
> That is not normal... Something must be wrong with your code or your
> DT... can you get more details about what precisely is happening in
> both
> cases ?
> 
> Ben.
> 

I think I have gotten the point. For tsi108/9, there are 24 internal
interrupt. PCI/INTA  to PCI/INTD are routed to interrupt 23 with a
special mechanism on the chip. INTA to INTD are assiged to nubmer 36 to
39, which are exceed the nubmer irq number assigned in mpic_alloc().
This cause abnormal return in function pci_read_irq_line().
I have worked out a patch. after a test, I will publish it.
Roy

^ permalink raw reply

* RE: Using WindRiver Probe JTAG
From: Matias Sundman (AS/EAB) @ 2006-10-26  7:24 UTC (permalink / raw)
  To: Michael Zagalsky, linuxppc-embedded
In-Reply-To: <1ea6be8e0610250554l5f9a431cr26f03a99574f68d9@mail.gmail.com>

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

Hello,
My name is Matias and I am working @ Ericsson in Stockholm.
We are using both BDI2000 and the WR ICE / probe.
I must say that if you have anyway invested in Workbench go with the WR
solutions. It is very convenient to debug U-boot , the Linux kernel or
insmod:ing of kernel modules with WB once you have things set-up. In
order to see the symbols you do not need to compile your kernel under
WB.
 
Why do we have both BDI2000 and WR tools? We started with the open
source tools suite a few years back but have now made a transition
towards
the Eclipse based WB environment in order to get a uniform and easy to
use/deploy development environment.
 
Note that I think that the Opensource tools and BDI2000 is a very good
alternative if you are a smaller organization or if you do not want to
or have
the $$$ to invest in WB.
 
Cheers // Matias

________________________________

From: linuxppc-embedded-bounces+matias.sundman=ericsson.com@ozlabs.org
[mailto:linuxppc-embedded-bounces+matias.sundman=ericsson.com@ozlabs.org
] On Behalf Of Michael Zagalsky
Sent: den 25 oktober 2006 14:54
To: linuxppc-embedded@ozlabs.org
Subject: Using WindRiver Probe JTAG


Hi guys.
I'd like to know if anybody had an experience using Wind River Probe
JTAG with PowerPC architecture in general, and with PowerQuicc iii
family in particular.
We're using WR workbench, but I am not sure whether to use their JTAG or
the popular BDI2000.
Does anybody know if WR Probe uses GDB, or something proprietary to WR?
Can it be attached to gdb/ddd/eclipse, or only to WR workbench IDE?
For kernel debugging with symbolic information - can it use any binary
compiled with -g, or it has to be compiled under WR workbench
environment that has some add-ons (I know, it sounds strange - but I
actually heard some vague saying of this kind from WR representative). 
 
I know those are questions that should be addressed to Wind River ,
which I did, but I didn't get clear enough answers - so your (good/bad)
field experience could be very helpful.
 
Thanks a lot, 
Michael

[-- Attachment #2: Type: text/html, Size: 3895 bytes --]

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH 12/16] cell: add temperature to SPU and CPU sysfs entries
From: Arnd Bergmann @ 2006-10-26  7:35 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Andrew Morton, linuxppc-dev, Heiko Carstens, linux-kernel,
	cbe-oss-dev
In-Reply-To: <1161818364.22582.145.camel@localhost.localdomain>

On Thursday 26 October 2006 01:19, Benjamin Herrenschmidt wrote:
> > 
> > Will crash if cpu_add_sysdev_attr_group failed...
> 
> 
> Which is a total PITA. If this is the case, then we should modify the
> add calls to at least initialize enough fields before they can fail for
> the remove calls not to crash. You don't want to keep track precisely of
> what file was added and what not and test all of that in your exit code
> path, it's just insane.

Heiko suggested that earlied in http://lkml.org/lkml/2006/10/9/22,
but Andrew didn't like it.

Currently, the worst is that sysfs_remove_file can be used
on a nonexisting file,  but sysfs_remove_group cannot, which is
inconsistent. Either sysfs_remove_file should WARN_ON or
sysfs_remove_group should silently return, and I'd prefer the
latter, as it makes users simpler.

	Arnd <><

^ permalink raw reply

* Re: Using WindRiver Probe JTAG
From: David H. Lynch Jr. @ 2006-10-26  5:21 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <1ea6be8e0610250749j4ceee6adlf1a5fae26cb494b@mail.gmail.com>

    Is there any publicly available documentation on the PPC JTAG 
interface ?

    Specifically the low level JTAG commands to manipulate the PPC ?

-- 
Dave Lynch 					  	    DLA Systems
Software Development:  				         Embedded Linux
717.627.3770 	       dhlii@dlasys.net 	  http://www.dlasys.net
fax: 1.253.369.9244 			           Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.

"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein

^ permalink raw reply

* [PATCH] powerpc: Remove old pci_map_irq and pci_swizzle_irq from ppc_md
From: Benjamin Herrenschmidt @ 2006-10-26  6:56 UTC (permalink / raw)
  To: linuxppc-dev list

This patch removes ppc_md.pci_map_irq and ppc_md.pci_swizzle for ARCH=powerpc.

These were inherited from ARCH=ppc, but are not needed since parsing of interrupts
should be done via the of_* functions (who can do swizzling). If we ever need to
do non-standard swizzling on bridges without a device-node, then we might add
back a slightly different version of ppc_md.pci_swizzle but for now, that is not
the case.

I removed the couple of calls for these in 83xx. If that breaks something, then
there is a problem with the device-tree on these.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

It's of course totally untested on 83xx hardware, so please let me know
before we merge :)

Index: linux-cell/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-cell.orig/arch/powerpc/kernel/pci_32.c	2006-10-26 16:47:07.000000000 +1000
+++ linux-cell/arch/powerpc/kernel/pci_32.c	2006-10-26 16:50:13.000000000 +1000
@@ -1282,10 +1282,6 @@ pcibios_init(void)
 	if (pci_assign_all_buses && have_of)
 		pcibios_make_OF_bus_map();
 
-	/* Do machine dependent PCI interrupt routing */
-	if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)
-		pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);
-
 	/* Call machine dependent fixup */
 	if (ppc_md.pcibios_fixup)
 		ppc_md.pcibios_fixup();
@@ -1308,25 +1304,6 @@ pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-unsigned char __init
-common_swizzle(struct pci_dev *dev, unsigned char *pinp)
-{
-	struct pci_controller *hose = dev->sysdata;
-
-	if (dev->bus->number != hose->first_busno) {
-		u8 pin = *pinp;
-		do {
-			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
-			/* Move up the chain of bridges. */
-			dev = dev->bus->self;
-		} while (dev->bus->self);
-		*pinp = pin;
-
-		/* The slot is the idsel of the last bridge. */
-	}
-	return PCI_SLOT(dev->devfn);
-}
-
 unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
 			     unsigned long start, unsigned long size)
 {
Index: linux-cell/arch/powerpc/platforms/83xx/mpc832x_mds.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc832x_mds.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/83xx/mpc832x_mds.c	2006-10-26 16:48:24.000000000 +1000
@@ -96,8 +96,6 @@ static void __init mpc832x_sys_setup_arc
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
-
-	ppc_md.pci_swizzle = common_swizzle;
 	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
 #endif
 
Index: linux-cell/arch/powerpc/platforms/83xx/mpc8360e_pb.c
===================================================================
--- linux-cell.orig/arch/powerpc/platforms/83xx/mpc8360e_pb.c	2006-10-23 14:41:37.000000000 +1000
+++ linux-cell/arch/powerpc/platforms/83xx/mpc8360e_pb.c	2006-10-26 16:48:35.000000000 +1000
@@ -102,8 +102,6 @@ static void __init mpc8360_sys_setup_arc
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
-
-	ppc_md.pci_swizzle = common_swizzle;
 	ppc_md.pci_exclude_device = mpc83xx_exclude_device;
 #endif
 
Index: linux-cell/include/asm-powerpc/machdep.h
===================================================================
--- linux-cell.orig/include/asm-powerpc/machdep.h	2006-10-26 16:47:07.000000000 +1000
+++ linux-cell/include/asm-powerpc/machdep.h	2006-10-26 16:47:39.000000000 +1000
@@ -199,10 +199,6 @@ struct machdep_calls {
 	 * Returns 0 to allow assignment/enabling of the device. */
 	int  (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
 
-	/* For interrupt routing */
-	unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
-	int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
-
 	/* Called in indirect_* to avoid touching devices */
 	int (*pci_exclude_device)(unsigned char, unsigned char);
 

^ permalink raw reply

* [2/2] build failure for E500 CPUs w/ CONFIG_OPROFLE=y
From: Vitaly Wool @ 2006-10-26  6:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: oprofile-list, linuxppc-embedded

Below is the patch for the problem described in "[0/2] build failure for 8540 w/ CONFIG_OPROFLE=y" letter representing the second approach. This approach just fixes the mess with ctr_read/ctr_write functions.
Pro: no need to mess with arch's and add more confusion to arch/powerpc/oprofile/common.c.
Con: when compiled for FSL_BOOKE, op_model_7450 is not valid as it takes ctr_read/ctr_write from FSL_BOOKE variant, which is confusing but actually doesn't matter since it will never be used in this case.

So, here's the second patch...

 arch/powerpc/oprofile/op_model_7450.c      |   12 ++++-----
 arch/powerpc/oprofile/op_model_fsl_booke.c |   37 -----------------------------
 include/asm-powerpc/oprofile_impl.h        |   36 ++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+), 43 deletions(-)

Signed-off-by: Vitaly Wool <vwool@ru.mvista.com>

Index: linux-2.6.18/arch/powerpc/oprofile/op_model_7450.c
===================================================================
--- linux-2.6.18.orig/arch/powerpc/oprofile/op_model_7450.c
+++ linux-2.6.18/arch/powerpc/oprofile/op_model_7450.c
@@ -58,7 +58,7 @@ static u32 mmcr0_val, mmcr1_val, mmcr2_v
  * enables the counters to trigger the interrupt, and sets the
  * counters to only count when the mark bit is not set.
  */
-static void pmc_start_ctrs(void)
+static void pmc_7450_start_ctrs(void)
 {
 	u32 mmcr0 = mfspr(SPRN_MMCR0);
 
@@ -69,7 +69,7 @@ static void pmc_start_ctrs(void)
 }
 
 /* Disables the counters on this CPU, and freezes them */
-static void pmc_stop_ctrs(void)
+static void pmc_7450_stop_ctrs(void)
 {
 	u32 mmcr0 = mfspr(SPRN_MMCR0);
 
@@ -84,7 +84,7 @@ static void pmc_stop_ctrs(void)
 static void fsl7450_cpu_setup(void *unused)
 {
 	/* freeze all counters */
-	pmc_stop_ctrs();
+	pmc_7450_stop_ctrs();
 
 	mtspr(SPRN_MMCR0, mmcr0_val);
 	mtspr(SPRN_MMCR1, mmcr1_val);
@@ -145,7 +145,7 @@ static void fsl7450_start(struct op_coun
 	/* Clear the freeze bit, and enable the interrupt.
 	 * The counters won't actually start until the rfi clears
 	 * the PMM bit */
-	pmc_start_ctrs();
+	pmc_7450_start_ctrs();
 
 	oprofile_running = 1;
 }
@@ -154,7 +154,7 @@ static void fsl7450_start(struct op_coun
 static void fsl7450_stop(void)
 {
 	/* freeze counters */
-	pmc_stop_ctrs();
+	pmc_7450_stop_ctrs();
 
 	oprofile_running = 0;
 
@@ -194,7 +194,7 @@ static void fsl7450_handle_interrupt(str
 	/* Clear the freeze bit, and reenable the interrupt.
 	 * The counters won't actually start until the rfi clears
 	 * the PMM bit */
-	pmc_start_ctrs();
+	pmc_7450_start_ctrs();
 }
 
 struct op_powerpc_model op_model_7450= {
Index: linux-2.6.18/arch/powerpc/oprofile/op_model_fsl_booke.c
===================================================================
--- linux-2.6.18.orig/arch/powerpc/oprofile/op_model_fsl_booke.c
+++ linux-2.6.18/arch/powerpc/oprofile/op_model_fsl_booke.c
@@ -32,43 +32,6 @@ static unsigned long reset_value[OP_MAX_
 static int num_counters;
 static int oprofile_running;
 
-static inline unsigned int ctr_read(unsigned int i)
-{
-	switch(i) {
-		case 0:
-			return mfpmr(PMRN_PMC0);
-		case 1:
-			return mfpmr(PMRN_PMC1);
-		case 2:
-			return mfpmr(PMRN_PMC2);
-		case 3:
-			return mfpmr(PMRN_PMC3);
-		default:
-			return 0;
-	}
-}
-
-static inline void ctr_write(unsigned int i, unsigned int val)
-{
-	switch(i) {
-		case 0:
-			mtpmr(PMRN_PMC0, val);
-			break;
-		case 1:
-			mtpmr(PMRN_PMC1, val);
-			break;
-		case 2:
-			mtpmr(PMRN_PMC2, val);
-			break;
-		case 3:
-			mtpmr(PMRN_PMC3, val);
-			break;
-		default:
-			break;
-	}
-}
-
-
 static void fsl_booke_reg_setup(struct op_counter_config *ctr,
 			     struct op_system_config *sys,
 			     int num_ctrs)
Index: linux-2.6.18/include/asm-powerpc/oprofile_impl.h
===================================================================
--- linux-2.6.18.orig/include/asm-powerpc/oprofile_impl.h
+++ linux-2.6.18/include/asm-powerpc/oprofile_impl.h
@@ -121,6 +121,42 @@ static inline void ctr_write(unsigned in
 		break;
 	}
 }
+#else
+static inline unsigned int ctr_read(unsigned int i)
+{
+	switch(i) {
+		case 0:
+			return mfpmr(PMRN_PMC0);
+		case 1:
+			return mfpmr(PMRN_PMC1);
+		case 2:
+			return mfpmr(PMRN_PMC2);
+		case 3:
+			return mfpmr(PMRN_PMC3);
+		default:
+			return 0;
+	}
+}
+
+static inline void ctr_write(unsigned int i, unsigned int val)
+{
+	switch(i) {
+		case 0:
+			mtpmr(PMRN_PMC0, val);
+			break;
+		case 1:
+			mtpmr(PMRN_PMC1, val);
+			break;
+		case 2:
+			mtpmr(PMRN_PMC2, val);
+			break;
+		case 3:
+			mtpmr(PMRN_PMC3, val);
+			break;
+		default:
+			break;
+	}
+}
 #endif /* !CONFIG_FSL_BOOKE */
 
 extern void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth);

^ permalink raw reply

* [1/2] build failure for E500 CPUs w/ CONFIG_OPROFLE=y
From: Vitaly Wool @ 2006-10-26  6:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: oprofile-list, linuxppc-embedded

Below is the patch for the problem described in "[0/2] build failure for 8540 w/ CONFIG_OPROFLE=y" letter representing the first approach. This approach is based on (pretty reasonable) assumption that op_model_7450.c is applicable only to 6XX, so let's compile it only when CONFIG_6XX==y. This results in more #ifdef's in arch/powerpc/oprofile/common.c, which doesn't look good to me. I'd rather "switch (cur_cpu_spec->oprofile_type) ..." to SoC-dependent header files arranging that one as static inline func...

Anyway, here's the patch.

 arch/powerpc/oprofile/Makefile |    2 +-
 arch/powerpc/oprofile/common.c |    7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

Signed-off-by: Vitaly Wool <vwool@ru.mvista.com>

Index: linux-2.6.18/arch/powerpc/oprofile/Makefile
===================================================================
--- linux-2.6.18.orig/arch/powerpc/oprofile/Makefile
+++ linux-2.6.18/arch/powerpc/oprofile/Makefile
@@ -13,4 +13,4 @@ DRIVER_OBJS := $(addprefix ../../../driv
 oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
 oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
 oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
-oprofile-$(CONFIG_PPC32) += op_model_7450.o
+oprofile-$(CONFIG_6XX) += op_model_7450.o
Index: linux-2.6.18/arch/powerpc/oprofile/common.c
===================================================================
--- linux-2.6.18.orig/arch/powerpc/oprofile/common.c
+++ linux-2.6.18/arch/powerpc/oprofile/common.c
@@ -135,19 +135,18 @@ int __init oprofile_arch_init(struct opr
 		return -ENODEV;
 
 	switch (cur_cpu_spec->oprofile_type) {
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC64)
 		case PPC_OPROFILE_RS64:
 			model = &op_model_rs64;
 			break;
 		case PPC_OPROFILE_POWER4:
 			model = &op_model_power4;
 			break;
-#else
+#elif defined (CONFIG_6XX)
 		case PPC_OPROFILE_G4:
 			model = &op_model_7450;
 			break;
-#endif
-#ifdef CONFIG_FSL_BOOKE
+#elif defined (CONFIG_FSL_BOOKE)
 		case PPC_OPROFILE_BOOKE:
 			model = &op_model_fsl_booke;
 			break;

^ permalink raw reply

* [0/2] build failure for E500 CPUs w/ CONFIG_OPROFLE=y
From: Vitaly Wool @ 2006-10-26  6:43 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: oprofile-list, linuxppc-embedded

Hello folks,

we've observed the following build failure compiling the kernel w/ oprofile on 8540 (FSL_BOOKE):

CC      arch/powerpc/oprofile/op_model_7450.o
arch/powerpc/oprofile/op_model_7450.c:62: error: conflicting types for
'pmc_start_ctrs'
include/asm/pmc.h:41: error: previous declaration of 'pmc_start_ctrs' was here
arch/powerpc/oprofile/op_model_7450.c:62: error: conflicting types for
'pmc_start_ctrs'
include/asm/pmc.h:41: error: previous declaration of 'pmc_start_ctrs' was here
arch/powerpc/oprofile/op_model_7450.c:73: warning: static declaration of
'pmc_stop_ctrs' follows non-static declaration
include/asm/pmc.h:42: warning: previous declaration of 'pmc_stop_ctrs' was here
arch/powerpc/oprofile/op_model_7450.c: In function `fsl7450_start':
arch/powerpc/oprofile/op_model_7450.c:140: warning: implicit declaration of
function `ctr_write'
arch/powerpc/oprofile/op_model_7450.c: In function `fsl7450_handle_interrupt':
arch/powerpc/oprofile/op_model_7450.c:182: warning: implicit declaration of
function `ctr_read'
make[1]: *** [arch/powerpc/oprofile/op_model_7450.o] Error 1

The thing is that op_model_7450.c is compiled when CONFIG_PPC32 is true which might be reasonable but results in conflicting functions' types when compiled w/ CONFIG_FSL_BOOKE=y. Effectively, op_model_fsl_booke.c introduces the functions with the same names as op_model_7450.c but with different declarations, and latter ones are static while former ones are not, and this can drive any compiler mad.

This message will have two *alternative* follow-up patches which are probably more likely RFCs rather than complete solutions, but still I'm sure it's reasonable to look at those, b/c those represent two different approaches and we need to decide which way to go first.

Vitaly

^ permalink raw reply

* [PATCH] powerpc: Make pci_read_irq_line the default:
From: Benjamin Herrenschmidt @ 2006-10-26  6:16 UTC (permalink / raw)
  To: linuxppc-dev list

This patch reworks the way IRQs are fixed up on PCI for arch powerpc.

It makes pci_read_irq_line() called by default in the PCI code for
devices that are probed, and add an optional per-device fixup in
ppc_md for platforms that really need to correct what they obtain
from pci_read_irq_line().

It also removes ppc_md.irq_bus_setup which was only used by pSeries
and should not be needed anymore.

I've also removed the pSeries s7a workaround as it can't work with
the current interrupt code anyway. I'm trying to get one of these
machines working so I can test a proper fix for that problem.

I also haven't updated the old-style fixup code from 85xx_cds.c
because it's actually buggy :) It assigns pci_dev->irq hard coded
numbers which is no good with the new IRQ mapping code. It should
at least use irq_create_mapping(NULL, hard_coded_number); and possibly
also set_irq_type() to set them as level low.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

The patch is only very lightly compile tested on a couple of platforms,
I would appreciate if Freescale folks could test on various 8xxx setups
to make sure I didn't break anything. Thanks !

BTW. The diffstat is cool :)

 arch/powerpc/kernel/pci_32.c                      |    9 ++++
 arch/powerpc/kernel/pci_64.c                      |    8 ++-
 arch/powerpc/platforms/82xx/mpc82xx_ads.c         |   13 ------
 arch/powerpc/platforms/83xx/mpc834x_itx.c         |    3 -
 arch/powerpc/platforms/83xx/mpc834x_sys.c         |    3 -
 arch/powerpc/platforms/83xx/mpc83xx.h             |    1
 arch/powerpc/platforms/83xx/pci.c                 |    9 ----
 arch/powerpc/platforms/85xx/mpc85xx_ads.c         |   11 -----
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c        |   10 ----
 arch/powerpc/platforms/cell/setup.c               |    9 ----
 arch/powerpc/platforms/chrp/chrp.h                |    1
 arch/powerpc/platforms/chrp/pci.c                 |    9 ----
 arch/powerpc/platforms/chrp/setup.c               |    1
 arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c |   16 ++-----
 arch/powerpc/platforms/maple/maple.h              |    2
 arch/powerpc/platforms/maple/pci.c                |   45 ++++++++--------------
 arch/powerpc/platforms/maple/setup.c              |    2
 arch/powerpc/platforms/pasemi/pasemi.h            |    1
 arch/powerpc/platforms/pasemi/pci.c               |    8 ---
 arch/powerpc/platforms/pasemi/setup.c             |    1
 arch/powerpc/platforms/powermac/pci.c             |   35 ++++++-----------
 arch/powerpc/platforms/powermac/pmac.h            |    2
 arch/powerpc/platforms/powermac/setup.c           |    2
 arch/powerpc/platforms/pseries/pci.c              |   35 -----------------
 arch/powerpc/platforms/pseries/setup.c            |    1
 include/asm-powerpc/machdep.h                     |    2
 include/asm-powerpc/ppc-pci.h                     |    1
 27 files changed, 57 insertions(+), 183 deletions(-)


Index: linux-work/arch/powerpc/kernel/pci_32.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_32.c	2006-10-23 14:41:37.000000000 +1000
+++ linux-work/arch/powerpc/kernel/pci_32.c	2006-10-26 15:52:15.000000000 +1000
@@ -1338,6 +1338,7 @@ void __init pcibios_fixup_bus(struct pci
 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
 	unsigned long io_offset;
 	struct resource *res;
+	struct pci_device *dev;
 	int i;
 
 	io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
@@ -1390,8 +1391,16 @@ void __init pcibios_fixup_bus(struct pci
 		}
 	}
 
+	/* Platform specific bus fixups */
 	if (ppc_md.pcibios_fixup_bus)
 		ppc_md.pcibios_fixup_bus(bus);
+
+	/* Read default IRQs and fixup if necessary */
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		pci_read_irq_line(dev);
+		if (ppc_md.pci_irq_fixup)
+			ppc_md.pci_irq_fixup(dev);
+	}
 }
 
 char __init *pcibios_setup(char *str)
Index: linux-work/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/pci_64.c	2006-10-23 14:41:37.000000000 +1000
+++ linux-work/arch/powerpc/kernel/pci_64.c	2006-10-26 15:53:02.000000000 +1000
@@ -1223,8 +1223,12 @@ static void __devinit do_bus_setup(struc
 	list_for_each_entry(dev, &bus->devices, bus_list)
 		ppc_md.iommu_dev_setup(dev);
 
-	if (ppc_md.irq_bus_setup)
-		ppc_md.irq_bus_setup(bus);
+	/* Read default IRQs and fixup if necessary */
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		pci_read_irq_line(dev);
+		if (ppc_md.pci_irq_fixup)
+			ppc_md.pci_irq_fixup(dev);
+	}
 }
 
 void __devinit pcibios_fixup_bus(struct pci_bus *bus)
Index: linux-work/arch/powerpc/platforms/pseries/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/pci.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/pseries/pci.c	2006-10-26 15:53:31.000000000 +1000
@@ -29,8 +29,6 @@
 #include <asm/prom.h>
 #include <asm/ppc-pci.h>
 
-static int __devinitdata s7a_workaround = -1;
-
 #if 0
 void pcibios_name_device(struct pci_dev *dev)
 {
@@ -57,39 +55,6 @@ void pcibios_name_device(struct pci_dev 
 DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
 #endif
 
-static void __devinit check_s7a(void)
-{
-	struct device_node *root;
-	const char *model;
-
-	s7a_workaround = 0;
-	root = of_find_node_by_path("/");
-	if (root) {
-		model = get_property(root, "model", NULL);
-		if (model && !strcmp(model, "IBM,7013-S7A"))
-			s7a_workaround = 1;
-		of_node_put(root);
-	}
-}
-
-void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
-{
-	struct pci_dev *dev;
-
-	if (s7a_workaround < 0)
-		check_s7a();
-	list_for_each_entry(dev, &bus->devices, bus_list) {
-		pci_read_irq_line(dev);
-		if (s7a_workaround) {
-			if (dev->irq > 16) {
-				dev->irq -= 3;
-				pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
-					dev->irq);
-			}
-		}
-	}
-}
-
 static void __init pSeries_request_regions(void)
 {
 	if (!isa_io_base)
Index: linux-work/arch/powerpc/platforms/pseries/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pseries/setup.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/pseries/setup.c	2006-10-26 15:53:59.000000000 +1000
@@ -553,7 +553,6 @@ define_machine(pseries) {
 	.log_error		= pSeries_log_error,
 	.pcibios_fixup		= pSeries_final_fixup,
 	.pci_probe_mode		= pSeries_pci_probe_mode,
-	.irq_bus_setup		= pSeries_irq_bus_setup,
 	.restart		= rtas_restart,
 	.power_off		= rtas_power_off,
 	.halt			= rtas_halt,
Index: linux-work/include/asm-powerpc/machdep.h
===================================================================
--- linux-work.orig/include/asm-powerpc/machdep.h	2006-10-09 12:03:34.000000000 +1000
+++ linux-work/include/asm-powerpc/machdep.h	2006-10-26 15:54:34.000000000 +1000
@@ -86,7 +86,6 @@ struct machdep_calls {
 	void		(*tce_flush)(struct iommu_table *tbl);
 	void		(*iommu_dev_setup)(struct pci_dev *dev);
 	void		(*iommu_bus_setup)(struct pci_bus *bus);
-	void		(*irq_bus_setup)(struct pci_bus *bus);
 #endif /* CONFIG_PPC64 */
 
 	int		(*probe)(void);
@@ -106,6 +105,7 @@ struct machdep_calls {
 	/* Called after scanning the bus, before allocating resources */
 	void		(*pcibios_fixup)(void);
 	int		(*pci_probe_mode)(struct pci_bus *);
+	void		(*pci_irq_fixup)(struct pci_dev *dev);
 
 	void		(*restart)(char *cmd);
 	void		(*power_off)(void);
Index: linux-work/include/asm-powerpc/ppc-pci.h
===================================================================
--- linux-work.orig/include/asm-powerpc/ppc-pci.h	2006-10-06 13:48:24.000000000 +1000
+++ linux-work/include/asm-powerpc/ppc-pci.h	2006-10-26 15:54:53.000000000 +1000
@@ -47,7 +47,6 @@ unsigned long get_phb_buid (struct devic
 
 /* From pSeries_pci.h */
 extern void pSeries_final_fixup(void);
-extern void pSeries_irq_bus_setup(struct pci_bus *bus);
 
 extern unsigned long pci_probe_only;
 
Index: linux-work/arch/powerpc/platforms/cell/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/cell/setup.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/cell/setup.c	2006-10-26 15:55:21.000000000 +1000
@@ -80,14 +80,6 @@ static void cell_progress(char *s, unsig
 	printk("*** %04x : %s\n", hex, s ? s : "");
 }
 
-static void __init cell_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	for_each_pci_dev(dev)
-		pci_read_irq_line(dev);
-}
-
 static void __init cell_init_irq(void)
 {
 	iic_init_IRQ();
@@ -180,7 +172,6 @@ define_machine(cell) {
 	.check_legacy_ioport	= cell_check_legacy_ioport,
 	.progress		= cell_progress,
 	.init_IRQ       	= cell_init_irq,
-	.pcibios_fixup		= cell_pcibios_fixup,
 #ifdef CONFIG_KEXEC
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
Index: linux-work/arch/powerpc/platforms/maple/maple.h
===================================================================
--- linux-work.orig/arch/powerpc/platforms/maple/maple.h	2006-01-14 14:43:22.000000000 +1100
+++ linux-work/arch/powerpc/platforms/maple/maple.h	2006-10-26 15:52:15.000000000 +1000
@@ -8,5 +8,5 @@ extern void maple_get_rtc_time(struct rt
 extern unsigned long maple_get_boot_time(void);
 extern void maple_calibrate_decr(void);
 extern void maple_pci_init(void);
-extern void maple_pcibios_fixup(void);
+extern void maple_pci_irq_fixup(struct pci_dev *dev);
 extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
Index: linux-work/arch/powerpc/platforms/maple/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/maple/pci.c	2006-10-13 17:23:48.000000000 +1000
+++ linux-work/arch/powerpc/platforms/maple/pci.c	2006-10-26 15:52:15.000000000 +1000
@@ -502,38 +502,29 @@ static int __init add_bridge(struct devi
 }
 
 
-void __init maple_pcibios_fixup(void)
+void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
 {
-	struct pci_dev *dev = NULL;
+	DBG(" -> maple_pci_irq_fixup\n");
 
-	DBG(" -> maple_pcibios_fixup\n");
-
-	for_each_pci_dev(dev) {
-		/* Fixup IRQ for PCIe host */
-		if (u4_pcie != NULL && dev->bus->number == 0 &&
-		    pci_bus_to_host(dev->bus) == u4_pcie) {
-			printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
-			dev->irq = irq_create_mapping(NULL, 1);
-			if (dev->irq != NO_IRQ)
-				set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
-			continue;
-		}
-
-		/* Hide AMD8111 IDE interrupt when in legacy mode so
-		 * the driver calls pci_get_legacy_ide_irq()
-		 */
-		if (dev->vendor == PCI_VENDOR_ID_AMD &&
-		    dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
-		    (dev->class & 5) != 5) {
-			dev->irq = NO_IRQ;
-			continue;
-		}
+	/* Fixup IRQ for PCIe host */
+	if (u4_pcie != NULL && dev->bus->number == 0 &&
+	    pci_bus_to_host(dev->bus) == u4_pcie) {
+		printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
+		dev->irq = irq_create_mapping(NULL, 1);
+		if (dev->irq != NO_IRQ)
+			set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+	}
 
-		/* For all others, map the interrupt from the device-tree */
-		pci_read_irq_line(dev);
+	/* Hide AMD8111 IDE interrupt when in legacy mode so
+	 * the driver calls pci_get_legacy_ide_irq()
+	 */
+	if (dev->vendor == PCI_VENDOR_ID_AMD &&
+	    dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
+	    (dev->class & 5) != 5) {
+		dev->irq = NO_IRQ;
 	}
 
-	DBG(" <- maple_pcibios_fixup\n");
+	DBG(" <- maple_pci_irq_fixup\n");
 }
 
 static void __init maple_fixup_phb_resources(void)
Index: linux-work/arch/powerpc/platforms/maple/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/maple/setup.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/maple/setup.c	2006-10-26 15:52:15.000000000 +1000
@@ -312,7 +312,7 @@ define_machine(maple_md) {
 	.setup_arch		= maple_setup_arch,
 	.init_early		= maple_init_early,
 	.init_IRQ		= maple_init_IRQ,
-	.pcibios_fixup		= maple_pcibios_fixup,
+	.pci_irq_fixup		= maple_pci_irq_fixup,
 	.pci_get_legacy_ide_irq	= maple_pci_get_legacy_ide_irq,
 	.restart		= maple_restart,
 	.power_off		= maple_power_off,
Index: linux-work/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/pci.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/powermac/pci.c	2006-10-26 15:52:15.000000000 +1000
@@ -985,30 +985,23 @@ static int __init add_bridge(struct devi
 	return 0;
 }
 
-void __init pmac_pcibios_fixup(void)
+void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
 {
-	struct pci_dev* dev = NULL;
-
-	for_each_pci_dev(dev) {
-		/* Read interrupt from the device-tree */
-		pci_read_irq_line(dev);
-
 #ifdef CONFIG_PPC32
-		/* Fixup interrupt for the modem/ethernet combo controller.
-		 * on machines with a second ohare chip.
-		 * The number in the device tree (27) is bogus (correct for
-		 * the ethernet-only board but not the combo ethernet/modem
-		 * board). The real interrupt is 28 on the second controller
-		 * -> 28+32 = 60.
-		 */
-		if (has_second_ohare &&
-		    dev->vendor == PCI_VENDOR_ID_DEC &&
-		    dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
-			dev->irq = irq_create_mapping(NULL, 60);
-			set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
-		}
-#endif /* CONFIG_PPC32 */
+	/* Fixup interrupt for the modem/ethernet combo controller.
+	 * on machines with a second ohare chip.
+	 * The number in the device tree (27) is bogus (correct for
+	 * the ethernet-only board but not the combo ethernet/modem
+	 * board). The real interrupt is 28 on the second controller
+	 * -> 28+32 = 60.
+	 */
+	if (has_second_ohare &&
+	    dev->vendor == PCI_VENDOR_ID_DEC &&
+	    dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
+		dev->irq = irq_create_mapping(NULL, 60);
+		set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
 	}
+#endif /* CONFIG_PPC32 */
 }
 
 #ifdef CONFIG_PPC64
Index: linux-work/arch/powerpc/platforms/powermac/pmac.h
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/pmac.h	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/powermac/pmac.h	2006-10-26 15:52:15.000000000 +1000
@@ -20,7 +20,7 @@ extern void pmac_get_rtc_time(struct rtc
 extern int pmac_set_rtc_time(struct rtc_time *);
 extern void pmac_read_rtc_time(void);
 extern void pmac_calibrate_decr(void);
-extern void pmac_pcibios_fixup(void);
+extern void pmac_pci_irq_fixup(struct pci_dev *);
 extern void pmac_pci_init(void);
 extern unsigned long pmac_ide_get_base(int index);
 extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
Index: linux-work/arch/powerpc/platforms/powermac/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/powermac/setup.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/powermac/setup.c	2006-10-26 15:52:15.000000000 +1000
@@ -727,7 +727,7 @@ define_machine(powermac) {
 	.show_cpuinfo		= pmac_show_cpuinfo,
 	.init_IRQ		= pmac_pic_init,
 	.get_irq		= NULL,	/* changed later */
-	.pcibios_fixup		= pmac_pcibios_fixup,
+	.pci_irq_fixup		= pmac_pci_irq_fixup,
 	.restart		= pmac_restart,
 	.power_off		= pmac_power_off,
 	.halt			= pmac_halt,
Index: linux-work/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c	2006-10-26 15:52:15.000000000 +1000
@@ -89,7 +89,7 @@ u8 find_slot_by_devfn(unsigned int *inte
 /*
  * Scans the interrupt map for pci device
  */
-void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
+void __devinit mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
 {
 	struct pci_controller *hose;
 	struct device_node *node;
@@ -117,19 +117,13 @@ void mpc7448_hpc2_fixup_irq(struct pci_d
 		pin = 1;
 	pin--;
 	dev->irq  = interrupt[slot*4*7 + pin*7 + 5];
+
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+
 	DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq);
 }
 /* temporary pci irq map fixup*/
 
-void __init mpc7448_hpc2_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-	for_each_pci_dev(dev) {
-		mpc7448_hpc2_fixup_irq(dev);
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-	}
-}
-
 static void __init mpc7448_hpc2_setup_arch(void)
 {
 	struct device_node *cpu;
@@ -300,7 +294,7 @@ define_machine(mpc7448_hpc2){
 	.init_IRQ 		= mpc7448_hpc2_init_IRQ,
 	.show_cpuinfo 		= mpc7448_hpc2_show_cpuinfo,
 	.get_irq 		= mpic_get_irq,
-	.pcibios_fixup 		= mpc7448_hpc2_pcibios_fixup,
+	.pci_irq_fixup 		= mpc7448_hpc2_fixup_irq,
 	.restart 		= mpc7448_hpc2_restart,
 	.calibrate_decr 	= generic_calibrate_decr,
 	.machine_check_exception= mpc7448_machine_check_exception,
Index: linux-work/arch/powerpc/platforms/pasemi/pasemi.h
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pasemi/pasemi.h	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/pasemi/pasemi.h	2006-10-26 15:52:15.000000000 +1000
@@ -3,6 +3,5 @@
 
 extern unsigned long pas_get_boot_time(void);
 extern void pas_pci_init(void);
-extern void pas_pcibios_fixup(void);
 
 #endif /* _PASEMI_PASEMI_H */
Index: linux-work/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pasemi/pci.c	2006-10-11 11:48:41.000000000 +1000
+++ linux-work/arch/powerpc/platforms/pasemi/pci.c	2006-10-26 15:52:15.000000000 +1000
@@ -148,14 +148,6 @@ static int __init add_bridge(struct devi
 }
 
 
-void __init pas_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	for_each_pci_dev(dev)
-		pci_read_irq_line(dev);
-}
-
 static void __init pas_fixup_phb_resources(void)
 {
 	struct pci_controller *hose, *tmp;
Index: linux-work/arch/powerpc/platforms/pasemi/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/pasemi/setup.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/pasemi/setup.c	2006-10-26 15:52:15.000000000 +1000
@@ -176,7 +176,6 @@ define_machine(pas) {
 	.init_early		= pas_init_early,
 	.init_IRQ		= pas_init_IRQ,
 	.get_irq		= mpic_get_irq,
-	.pcibios_fixup		= pas_pcibios_fixup,
 	.restart		= pas_restart,
 	.power_off		= pas_power_off,
 	.halt			= pas_halt,
Index: linux-work/arch/powerpc/platforms/82xx/mpc82xx_ads.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/82xx/mpc82xx_ads.c	2006-10-11 11:48:41.000000000 +1000
+++ linux-work/arch/powerpc/platforms/82xx/mpc82xx_ads.c	2006-10-26 15:52:15.000000000 +1000
@@ -515,16 +515,6 @@ static int m82xx_pci_exclude_device(u_ch
 		return PCIBIOS_SUCCESSFUL;
 }
 
-static void
-__init mpc82xx_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	for_each_pci_dev(dev) {
-		pci_read_irq_line(dev);
-	}
-}
-
 void __init add_bridge(struct device_node *np)
 {
 	int len;
@@ -597,9 +587,6 @@ static void __init mpc82xx_ads_setup_arc
 		add_bridge(np);
 
 	of_node_put(np);
-	ppc_md.pci_map_irq = NULL;
-	ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
-	ppc_md.pcibios_fixup_bus = NULL;
 #endif
 
 #ifdef  CONFIG_ROOT_NFS
Index: linux-work/arch/powerpc/platforms/83xx/mpc834x_itx.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/83xx/mpc834x_itx.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/83xx/mpc834x_itx.c	2006-10-26 15:52:15.000000000 +1000
@@ -122,7 +122,4 @@ define_machine(mpc834x_itx) {
 	.time_init		= mpc83xx_time_init,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
-#ifdef CONFIG_PCI
-	.pcibios_fixup		= mpc83xx_pcibios_fixup,
-#endif
 };
Index: linux-work/arch/powerpc/platforms/83xx/mpc834x_sys.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/83xx/mpc834x_sys.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/83xx/mpc834x_sys.c	2006-10-26 15:52:15.000000000 +1000
@@ -137,7 +137,4 @@ define_machine(mpc834x_sys) {
 	.time_init		= mpc83xx_time_init,
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
-#ifdef CONFIG_PCI
-	.pcibios_fixup		= mpc83xx_pcibios_fixup,
-#endif
 };
Index: linux-work/arch/powerpc/platforms/83xx/mpc83xx.h
===================================================================
--- linux-work.orig/arch/powerpc/platforms/83xx/mpc83xx.h	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/83xx/mpc83xx.h	2006-10-26 15:52:15.000000000 +1000
@@ -11,7 +11,6 @@
 
 extern int add_bridge(struct device_node *dev);
 extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
-extern void mpc83xx_pcibios_fixup(void);
 extern void mpc83xx_restart(char *cmd);
 extern long mpc83xx_time_init(void);
 
Index: linux-work/arch/powerpc/platforms/83xx/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/83xx/pci.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/83xx/pci.c	2006-10-26 15:52:15.000000000 +1000
@@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u
 	return PCIBIOS_SUCCESSFUL;
 }
 
-void __init mpc83xx_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	/* map all the PCI irqs */
-	for_each_pci_dev(dev)
-		pci_read_irq_line(dev);
-}
-
 int __init add_bridge(struct device_node *dev)
 {
 	int len;
Index: linux-work/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c	2006-10-26 15:52:15.000000000 +1000
@@ -398,15 +398,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_fil
 }
 
 
-void __init mpc86xx_hpcn_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	for_each_pci_dev(dev)
-		pci_read_irq_line(dev);
-}
-
-
 /*
  * Called very early, device-tree isn't unflattened
  */
@@ -461,7 +452,6 @@ define_machine(mpc86xx_hpcn) {
 	.setup_arch		= mpc86xx_hpcn_setup_arch,
 	.init_IRQ		= mpc86xx_hpcn_init_irq,
 	.show_cpuinfo		= mpc86xx_hpcn_show_cpuinfo,
-	.pcibios_fixup		= mpc86xx_hpcn_pcibios_fixup,
 	.get_irq		= mpic_get_irq,
 	.restart		= mpc86xx_restart,
 	.time_init		= mpc86xx_time_init,
Index: linux-work/arch/powerpc/platforms/chrp/chrp.h
===================================================================
--- linux-work.orig/arch/powerpc/platforms/chrp/chrp.h	2006-09-08 17:17:10.000000000 +1000
+++ linux-work/arch/powerpc/platforms/chrp/chrp.h	2006-10-26 15:52:15.000000000 +1000
@@ -9,4 +9,3 @@ extern long chrp_time_init(void);
 
 extern void chrp_find_bridges(void);
 extern void chrp_event_scan(unsigned long);
-extern void chrp_pcibios_fixup(void);
Index: linux-work/arch/powerpc/platforms/chrp/setup.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/chrp/setup.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/chrp/setup.c	2006-10-26 15:52:15.000000000 +1000
@@ -598,7 +598,6 @@ define_machine(chrp) {
 	.init			= chrp_init2,
 	.show_cpuinfo		= chrp_show_cpuinfo,
 	.init_IRQ		= chrp_init_IRQ,
-	.pcibios_fixup		= chrp_pcibios_fixup,
 	.restart		= rtas_restart,
 	.power_off		= rtas_power_off,
 	.halt			= rtas_halt,
Index: linux-work/arch/powerpc/platforms/85xx/mpc85xx_ads.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/85xx/mpc85xx_ads.c	2006-10-09 12:03:33.000000000 +1000
+++ linux-work/arch/powerpc/platforms/85xx/mpc85xx_ads.c	2006-10-26 15:52:15.000000000 +1000
@@ -53,15 +53,6 @@ mpc85xx_exclude_device(u_char bus, u_cha
 	else
 		return PCIBIOS_SUCCESSFUL;
 }
-
-void __init
-mpc85xx_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	for_each_pci_dev(dev)
-		pci_read_irq_line(dev);
-}
 #endif /* CONFIG_PCI */
 
 #ifdef CONFIG_CPM2
@@ -253,8 +244,6 @@ static void __init mpc85xx_ads_setup_arc
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
-
-	ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 #endif
 
Index: linux-work/arch/powerpc/platforms/chrp/pci.c
===================================================================
--- linux-work.orig/arch/powerpc/platforms/chrp/pci.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/platforms/chrp/pci.c	2006-10-26 15:52:15.000000000 +1000
@@ -156,15 +156,6 @@ hydra_init(void)
 	return 1;
 }
 
-void __init
-chrp_pcibios_fixup(void)
-{
-	struct pci_dev *dev = NULL;
-
-	for_each_pci_dev(dev)
-		pci_read_irq_line(dev);
-}
-
 #define PRG_CL_RESET_VALID 0x00010000
 
 static void __init

^ permalink raw reply

* Re: 2.6.19-rc2-mm2
From: Joseph Fannin @ 2006-10-26  6:11 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, paulus, linux-kernel
In-Reply-To: <20061020015641.b4ed72e5.akpm@osdl.org>

On Fri, Oct 20, 2006 at 01:56:41AM -0700, Andrew Morton wrote:
>
> ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.19-rc2/2.6.19-rc2-mm2/
>

    The "Lazy interrupt disabling for 64-bit machines" patch
(which is in -rc2-mm2 through git-powerpc) seems to make -rc2-mm2
not build for ppc32 when KEXEC is enabled.  Building with kexec
enabled worked in -rc2-mm1.

    Building -mm2 fails when trying to make the vmlinux.  I don't have
the exact messages anymore, sorry, but it was an "undefined reference
to hard_irq_disable' in arch/powerpc/kernel/entry_32.S".  This appears
to be the result of an earlier warning about an "implicit
declaration of hard_irq_disable" in arch/powerpc/kernel/crash.c .

    (There's a comment at the top of that file that made it sound to
me like the file is for PPC64 only, but looking closer makes me think
that's not the case.)

    Backing out that "lazy interrupt" patch got -mm2 building again.
Turning kexec off works too.

    I don't use kexec, I just have it config'd on.  I doubt anyone is
actually using kexec in -mm on ppc32.  I'm just sayin'.

--
Joseph Fannin
jhf@columbus.rr.com

^ permalink raw reply

* [PATCH] powerpc: Fix various offb issues
From: Benjamin Herrenschmidt @ 2006-10-26  5:38 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev list

This patch fixes a few issues in offb:

 - A test was inverted causing the palette hack to never work
(no device node was passed down to the init function)

 - Some cards seem to have their assigned-addresses property in a random
order, thus we need to try using of_get_pci_address() first, which will
fail if it's not a PCI device, and fallback to of_get_address() in that
case. of_get_pci_address() properly parsees assigned-addresses to test
the BAR number and thus will get it right whatever the order is.

 - Some cards (like GXT4500) provide a linebytes of 0xffffffff in the
device-tree which does no good. This patch handles that by using the
screen width when that happens. (Also fixes btext.c while at it).

 - Add detection of the GXT4500 in addition to the GXT2000 for the
palette hacks (we use the same hack, palette is linear in register space
at offset 0x6000).

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Paul: In addition to making the GXT4500 somewhat work (it's 1024x768@60
8bpp so it's not great, but X works) this patch fixes a couple of
problems that might have been plaguing other users as well, so I reckon
it's good to go into 2.6.19. 

Index: linux-work/arch/powerpc/kernel/btext.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/btext.c	2006-10-06 13:47:54.000000000 +1000
+++ linux-work/arch/powerpc/kernel/btext.c	2006-10-26 14:37:16.000000000 +1000
@@ -182,7 +182,7 @@ int btext_initialize(struct device_node 
 	prop = get_property(np, "linux,bootx-linebytes", NULL);
 	if (prop == NULL)
 		prop = get_property(np, "linebytes", NULL);
-	if (prop)
+	if (prop && *prop != 0xffffffffu)
 		pitch = *prop;
 	if (pitch == 1)
 		pitch = 0x1000;
Index: linux-work/drivers/video/offb.c
===================================================================
--- linux-work.orig/drivers/video/offb.c	2006-10-06 13:48:17.000000000 +1000
+++ linux-work/drivers/video/offb.c	2006-10-26 15:32:41.000000000 +1000
@@ -157,7 +157,7 @@ static int offb_setcolreg(u_int regno, u
 		out_le32(par->cmap_adr + 0xb4, (red << 16 | green << 8 | blue));
 		break;
 	case cmap_gxt2000:
-		out_le32((unsigned __iomem *) par->cmap_adr + regno,
+		out_le32(((unsigned __iomem *) par->cmap_adr) + regno,
 			 (red << 16 | green << 8 | blue));
 		break;
 	}
@@ -213,7 +213,7 @@ static int offb_blank(int blank, struct 
 				out_le32(par->cmap_adr + 0xb4, 0);
 				break;
 			case cmap_gxt2000:
-				out_le32((unsigned __iomem *) par->cmap_adr + i,
+				out_le32(((unsigned __iomem *) par->cmap_adr) + i,
 					 0);
 				break;
 			}
@@ -226,13 +226,23 @@ static int offb_blank(int blank, struct 
 static void __iomem *offb_map_reg(struct device_node *np, int index,
 				  unsigned long offset, unsigned long size)
 {
-	struct resource r;
-
-	if (of_address_to_resource(np, index, &r))
-		return 0;
-	if ((r.start + offset + size) > r.end)
-		return 0;
-	return ioremap(r.start + offset, size);
+	const u32 *addrp;
+	u64 asize, taddr;
+	unsigned int flags;
+
+	addrp = of_get_pci_address(np, index, &asize, &flags);
+	if (addrp == NULL)
+		addrp = of_get_address(np, index, &asize, &flags);
+	if (addrp == NULL)
+		return NULL;
+	if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+		return NULL;
+	if ((offset + size) > asize)
+		return NULL;
+	taddr = of_translate_address(np, addrp);
+	if (taddr == OF_BAD_ADDR)
+		return NULL;
+	return ioremap(taddr + offset, size);
 }
 
 static void __init offb_init_fb(const char *name, const char *full_name,
@@ -289,7 +299,6 @@ static void __init offb_init_fb(const ch
 
 	par->cmap_type = cmap_unknown;
 	if (depth == 8) {
-		/* Palette hacks disabled for now */
 		if (dp && !strncmp(name, "ATY,Rage128", 11)) {
 			par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff);
 			if (par->cmap_adr)
@@ -313,7 +322,8 @@ static void __init offb_init_fb(const ch
 			    ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
 			par->cmap_data = par->cmap_adr + 1;
 			par->cmap_type = cmap_m64;
-		} else if (dp && device_is_compatible(dp, "pci1014,b7")) {
+		} else if (dp && (device_is_compatible(dp, "pci1014,b7") ||
+				  device_is_compatible(dp, "pci1014,21c"))) {
 			par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000);
 			if (par->cmap_adr)
 				par->cmap_type = cmap_gxt2000;
@@ -433,7 +443,7 @@ static void __init offb_init_nodriver(st
 	pp = get_property(dp, "linux,bootx-linebytes", &len);
 	if (pp == NULL)
 		pp = get_property(dp, "linebytes", &len);
-	if (pp && len == sizeof(u32))
+	if (pp && len == sizeof(u32) && (*pp != 0xffffffffu))
 		pitch = *pp;
 	else
 		pitch = width * ((depth + 7) / 8);
@@ -496,7 +506,7 @@ static void __init offb_init_nodriver(st
 		offb_init_fb(no_real_node ? "bootx" : dp->name,
 			     no_real_node ? "display" : dp->full_name,
 			     width, height, depth, pitch, address,
-			     no_real_node ? dp : NULL);
+			     no_real_node ? NULL : dp);
 	}
 }
 

^ permalink raw reply

* 83xx usage of pci_fixup_irq
From: Benjamin Herrenschmidt @ 2006-10-26  4:34 UTC (permalink / raw)
  To: linuxppc-dev

I'd like to remove on ppc32 those 2 members of ppc_md:

unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);

They are used by only those 2 platforms:

arch/powerpc/platforms/83xx/mpc832x_mds.c:

and

arch/powerpc/platforms/83xx/mpc8360e_pb.c:

They shouldn't be necessary however with the prom_parse.c code and using
standard of_irq_map_pci() (or pci_read_irq_line() which uses it).

So is there any special reason I can't just remove these ?

(I'm also adding a common 32/64 bits pci_irq_fixup for platforms that
really need a fixup and making pci_read_irq_line() the default).

If we ever need some non-standard swizzle, then I might re-introduce a
swizzle callback in here (but common 32/64 bits this time) that is used
by of_irq_map_pci().

Ben.

^ permalink raw reply

* [POWERPC] MPC52xx is a 6xx variant, remove PPC_52xx config option
From: Grant Likely @ 2006-10-26  3:52 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, linuxppc-embedded

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 arch/powerpc/Kconfig |    5 -----
 1 files changed, 0 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index f9b11c1..6bff8b7 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -126,11 +126,6 @@ config CLASSIC32
 	  systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
 	  Note that the kernel runs in 32-bit mode even on 64-bit chips.
 
-config PPC_52xx
-	bool "Freescale 52xx"
-	select 6xx
-	select PPC_FPU
-	
 config PPC_82xx
 	bool "Freescale 82xx"
 	select 6xx
-- 
1.4.3.rc2.g0503

^ permalink raw reply related

* [PATCH 2/3] Create compat_sys_migrate_pages
From: Stephen Rothwell @ 2006-10-26  3:57 UTC (permalink / raw)
  To: LKML; +Cc: ppc-dev, paulus, ak, linux-mm
In-Reply-To: <20061026133305.b0db54e6.sfr@canb.auug.org.au>

This is needed on bigendian 64bit architectures. The obvious way to do
this (taking the other compat_ routines in this file as examples) is to
use compat_alloc_user_space and copy the bitmasks back there, however you
cannot call compat_alloc_user_space twice for a single system call and
this method saves two copies of the bitmasks.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 mm/mempolicy.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 95 insertions(+), 16 deletions(-)

OOPS, forgot to add a couple of fixes.  Replacement of 2/3 only ...
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 617fb31..aa81d41 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -854,6 +854,58 @@ static int get_nodes(nodemask_t *nodes,
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static int compat_get_nodes(nodemask_t *nodes,
+		const compat_ulong_t __user *nmask, unsigned long maxnode)
+{
+	unsigned long k;
+	unsigned long nlongs;
+	unsigned long nbits = maxnode - 1;
+	compat_ulong_t endmask;
+
+	if (maxnode == 0)
+		return -EINVAL;
+	nodes_clear(*nodes);
+	if (nbits == 0 || !nmask)
+		return 0;
+	if (nbits > PAGE_SIZE * BITS_PER_BYTE)
+		return -EINVAL;
+
+	nlongs = BITS_TO_COMPAT_LONGS(nbits);
+	if ((nbits % BITS_PER_COMPAT_LONG) == 0)
+		endmask = (compat_ulong_t)~0;
+	else
+		endmask = ((compat_ulong_t)1 <<
+				(nbits % BITS_PER_COMPAT_LONG)) - 1;
+
+	/* When the user specified more nodes than supported just check
+	   if the non supported part is all zero. */
+	if (nbits > MAX_NUMNODES) {
+		if (nlongs > PAGE_SIZE / sizeof(compat_ulong_t))
+			return -EINVAL;
+		for (k = BITS_TO_COMPAT_LONGS(MAX_NUMNODES); k < nlongs; k++) {
+			compat_ulong_t t;
+
+			if (get_user(t, nmask + k))
+				return -EFAULT;
+			if (k == (nlongs - 1)) {
+				if (t & endmask)
+					return -EINVAL;
+			} else if (t)
+				return -EINVAL;
+		}
+		nbits = MAX_NUMNODES;
+		endmask = ~0;
+	}
+
+	if (compat_get_bitmap(nodes_addr(*nodes), nmask, nbits))
+		return -EFAULT;
+	if (nbits % BITS_PER_COMPAT_LONG)
+		nodes_addr(*nodes)[BITS_TO_COMPAT_LONGS(nbits) - 1] &= endmask;
+	return 0;
+}
+#endif /* CONFIG_COMPAT */
+
 /* Copy a kernel node mask to user space */
 static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
 			      nodemask_t *nodes)
@@ -900,25 +952,13 @@ asmlinkage long sys_set_mempolicy(int mo
 	return do_set_mempolicy(mode, &nodes);
 }
 
-asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
-		const unsigned long __user *old_nodes,
-		const unsigned long __user *new_nodes)
+static long internal_migrate_pages(pid_t pid, nodemask_t *old, nodemask_t *new)
 {
 	struct mm_struct *mm;
 	struct task_struct *task;
-	nodemask_t old;
-	nodemask_t new;
 	nodemask_t task_nodes;
 	int err;
 
-	err = get_nodes(&old, old_nodes, maxnode);
-	if (err)
-		return err;
-
-	err = get_nodes(&new, new_nodes, maxnode);
-	if (err)
-		return err;
-
 	/* Find the mm_struct */
 	read_lock(&tasklist_lock);
 	task = pid ? find_task_by_pid(pid) : current;
@@ -947,7 +987,7 @@ asmlinkage long sys_migrate_pages(pid_t
 
 	task_nodes = cpuset_mems_allowed(task);
 	/* Is the user allowed to access the target nodes? */
-	if (!nodes_subset(new, task_nodes) && !capable(CAP_SYS_NICE)) {
+	if (!nodes_subset(*new, task_nodes) && !capable(CAP_SYS_NICE)) {
 		err = -EPERM;
 		goto out;
 	}
@@ -956,13 +996,32 @@ asmlinkage long sys_migrate_pages(pid_t
 	if (err)
 		goto out;
 
-	err = do_migrate_pages(mm, &old, &new,
+	err = do_migrate_pages(mm, old, new,
 		capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE);
 out:
 	mmput(mm);
 	return err;
 }
 
+asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
+		const unsigned long __user *old_nodes,
+		const unsigned long __user *new_nodes)
+{
+	nodemask_t old;
+	nodemask_t new;
+	int err;
+
+	err = get_nodes(&old, old_nodes, maxnode);
+	if (err)
+		return err;
+
+	err = get_nodes(&new, new_nodes, maxnode);
+	if (err)
+		return err;
+
+	return internal_migrate_pages(pid, &old, &new);
+}
+
 
 /* Retrieve NUMA policy */
 asmlinkage long sys_get_mempolicy(int __user *policy,
@@ -1067,7 +1126,27 @@ asmlinkage long compat_sys_mbind(compat_
 	return sys_mbind(start, len, mode, nm, nr_bits+1, flags);
 }
 
-#endif
+asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
+			compat_ulong_t maxnode,
+			const compat_ulong_t __user *old_nodes,
+			const compat_ulong_t __user *new_nodes)
+{
+	nodemask_t old;
+	nodemask_t new;
+	int err;
+
+	err = compat_get_nodes(&old, old_nodes, maxnode);
+	if (err)
+		return err;
+
+	err = compat_get_nodes(&new, new_nodes, maxnode);
+	if (err)
+		return err;
+
+	return internal_migrate_pages(pid, &old, &new);
+}
+
+#endif /* CONFIG_COMPAT */
 
 /* Return effective policy for a VMA */
 static struct mempolicy * get_vma_policy(struct task_struct *task,
-- 
1.4.3.2

^ permalink raw reply related

* [PATCH 3/3] [POWERPC] Wire up sys_migrate_pages
From: Stephen Rothwell @ 2006-10-26  3:34 UTC (permalink / raw)
  To: LKML; +Cc: ppc-dev, paulus, ak, linux-mm
In-Reply-To: <20061026133305.b0db54e6.sfr@canb.auug.org.au>


Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 include/asm-powerpc/systbl.h |    1 +
 include/asm-powerpc/unistd.h |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index eac85ce..4708ebe 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -304,3 +304,4 @@ SYSCALL_SPU(fchmodat)
 SYSCALL_SPU(faccessat)
 COMPAT_SYS_SPU(get_robust_list)
 COMPAT_SYS_SPU(set_robust_list)
+COMPAT_SYS(migrate_pages)
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 464a48c..4cdab3f 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -323,10 +323,11 @@ #define __NR_fchmodat		297
 #define __NR_faccessat		298
 #define __NR_get_robust_list	299
 #define __NR_set_robust_list	300
+#define __NR_migrate_pages	301
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		301
+#define __NR_syscalls		302
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
-- 
1.4.3.2

^ permalink raw reply related

* [PATCH 2/3] Create compat_sys_migrate_pages
From: Stephen Rothwell @ 2006-10-26  3:33 UTC (permalink / raw)
  To: LKML; +Cc: ppc-dev, paulus, ak, linux-mm
In-Reply-To: <20061026132659.2ff90dd1.sfr@canb.auug.org.au>

This is needed on bigendian 64bit architectures. The obvious way to do
this (taking the other compat_ routines in this file as examples) is to
use compat_alloc_user_space and copy the bitmasks back there, however you
cannot call compat_alloc_user_space twice for a single system call and
this method saves two copies of the bitmasks.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 mm/mempolicy.c |  107 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 93 insertions(+), 14 deletions(-)

Maybe the other compat routines in here should be converted to use
compat_get_nodes as well.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 617fb31..65c0281 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -854,6 +854,58 @@ static int get_nodes(nodemask_t *nodes,
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static int compat_get_nodes(nodemask_t *nodes,
+		const compat_ulong_t __user *nmask, unsigned long maxnode)
+{
+	unsigned long k;
+	unsigned long nlongs;
+	unsigned long nbits = maxnode - 1;
+	compat_ulong_t endmask;
+
+	if (maxnode == 0)
+		return -EINVAL;
+	nodes_clear(*nodes);
+	if (nbits == 0 || !nmask)
+		return 0;
+	if (nbits > PAGE_SIZE * BITS_PER_BYTE)
+		return -EINVAL;
+
+	nlongs = BITS_TO_COMPAT_LONGS(nbits);
+	if ((nbits % BITS_PER_COMPAT_LONG) == 0)
+		endmask = (compat_ulong_t)~0;
+	else
+		endmask = ((compat_ulong_t)1 <<
+				(nbits % BITS_PER_COMPAT_LONG)) - 1;
+
+	/* When the user specified more nodes than supported just check
+	   if the non supported part is all zero. */
+	if (nbits > MAX_NUMNODES) {
+		if (nlongs > PAGE_SIZE / sizeof(compat_ulong_t))
+			return -EINVAL;
+		for (k = BITS_TO_COMPAT_LONGS(MAX_NUMNODES); k < nlongs; k++) {
+			compat_ulong_t t;
+
+			if (get_user(t, nmask + k))
+				return -EFAULT;
+			if (k == (nlongs - 1)) {
+				if (t & endmask)
+					return -EINVAL;
+			} else if (t)
+				return -EINVAL;
+		}
+		nbits = MAX_NUMNODES;
+		endmask = ~0;
+	}
+
+	if (compat_get_bitmap(nodes_addr(*nodes), nmask, nbits))
+		return -EFAULT;
+	if (nbits % BITS_PER_COMPAT_LONG)
+		nodes_addr(*nodes)[BITS_TO_COMPAT_LONGS(nbits) - 1] &= endmask;
+	return 0;
+}
+#endif /* CONFIG_COMPAT */
+
 /* Copy a kernel node mask to user space */
 static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
 			      nodemask_t *nodes)
@@ -900,25 +952,13 @@ asmlinkage long sys_set_mempolicy(int mo
 	return do_set_mempolicy(mode, &nodes);
 }
 
-asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
-		const unsigned long __user *old_nodes,
-		const unsigned long __user *new_nodes)
+static long internal_migrate_pages(pid_t pid, nodemask_t *old, nodemask_t *new)
 {
 	struct mm_struct *mm;
 	struct task_struct *task;
-	nodemask_t old;
-	nodemask_t new;
 	nodemask_t task_nodes;
 	int err;
 
-	err = get_nodes(&old, old_nodes, maxnode);
-	if (err)
-		return err;
-
-	err = get_nodes(&new, new_nodes, maxnode);
-	if (err)
-		return err;
-
 	/* Find the mm_struct */
 	read_lock(&tasklist_lock);
 	task = pid ? find_task_by_pid(pid) : current;
@@ -963,6 +1003,25 @@ out:
 	return err;
 }
 
+asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
+		const unsigned long __user *old_nodes,
+		const unsigned long __user *new_nodes)
+{
+	nodemask_t old;
+	nodemask_t new;
+	int err;
+
+	err = get_nodes(&old, old_nodes, maxnode);
+	if (err)
+		return err;
+
+	err = get_nodes(&new, new_nodes, maxnode);
+	if (err)
+		return err;
+
+	return internal_migrate_pages(pid, old, new);
+}
+
 
 /* Retrieve NUMA policy */
 asmlinkage long sys_get_mempolicy(int __user *policy,
@@ -1067,7 +1126,27 @@ asmlinkage long compat_sys_mbind(compat_
 	return sys_mbind(start, len, mode, nm, nr_bits+1, flags);
 }
 
-#endif
+asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
+			compat_ulong_t maxnode,
+			const compat_ulong_t __user *old_nodes,
+			const compat_ulong_t __user *new_nodes)
+{
+	nodemask_t old;
+	nodemask_t new;
+	int err;
+
+	err = get_nodes(&old, old_nodes, maxnode);
+	if (err)
+		return err;
+
+	err = get_nodes(&new, new_nodes, maxnode);
+	if (err)
+		return err;
+
+	return internal_migrate_pages(pid, old, new);
+}
+
+#endif /* CONFIG_COMPAT */
 
 /* Return effective policy for a VMA */
 static struct mempolicy * get_vma_policy(struct task_struct *task,
-- 
1.4.3.2

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox