LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] kexec ppc64: fix misaligned cmdline
From: David Gibson @ 2007-06-05  0:16 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev, horms, kexec, miltonm
In-Reply-To: <2554.1181001397@neuling.org>

On Tue, Jun 05, 2007 at 09:56:37AM +1000, Miichael Neuling wrote:
> > > If the cmdline changes between boots, we can get misalignment of the
> > > bootargs entry, which in turn corrupts our device tree blob and hence
> > > kills our kexec boot.  
> > > 
> > > Specifically, if the cmdline length was >= 8 before and the new cmdline
> > > length is < 8, we can get corruption.
> > 
> > Hrm.  Have you considered using dtc for this conversion, rather than
> > this somewhat dubious looking fs2dt?
> 
> Numerous times.  
> 
> fs2dt needs to be converted to use the device tree library, but that
> will take a lot more work than a 5 minute patch.


Well, sure.. but do you need fs2dt at all.  dtc has an "fs" input
mode..

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] kexec ppc64: fix misaligned cmdline
From: Michael Neuling @ 2007-06-04 23:56 UTC (permalink / raw)
  To: David Gibson; +Cc: linuxppc-dev, horms, kexec, miltonm
In-Reply-To: <20070604234917.GB10877@localhost.localdomain>

> > If the cmdline changes between boots, we can get misalignment of the
> > bootargs entry, which in turn corrupts our device tree blob and hence
> > kills our kexec boot.  
> > 
> > Specifically, if the cmdline length was >= 8 before and the new cmdline
> > length is < 8, we can get corruption.
> 
> Hrm.  Have you considered using dtc for this conversion, rather than
> this somewhat dubious looking fs2dt?

Numerous times.  

fs2dt needs to be converted to use the device tree library, but that
will take a lot more work than a 5 minute patch.

Mikey

^ permalink raw reply

* Re: [PATCH] powerpc: fix typo in booting-without-of-txt section numbering
From: David Gibson @ 2007-06-04 23:55 UTC (permalink / raw)
  To: Stuart Yoder; +Cc: linuxppc-dev, paulus
In-Reply-To: <200706042116.l54LGFuZ022877@ld0164-tx32.am.freescale.net>

On Mon, Jun 04, 2007 at 04:16:15PM -0500, Stuart Yoder wrote:
> >From 799bc4dbad6b4e8c2d88c7c2c4746072b9175222 Mon Sep 17 00:00:00 2001
> From: Stuart Yoder <stuart.yoder@freescale.com>
> Date: Mon, 4 Jun 2007 16:08:35 -0500
> Subject: [PATCH] test
> 
> Fix typo in section numbering.
> 
> 
> Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>

Acked-by: David Gibson <david@gibson.dropbear.id.au>

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: [PATCH] kexec ppc64: fix misaligned cmdline
From: David Gibson @ 2007-06-04 23:49 UTC (permalink / raw)
  To: Michael Neuling; +Cc: linuxppc-dev, horms, kexec, miltonm
In-Reply-To: <25445.1180941825@neuling.org>

On Mon, Jun 04, 2007 at 05:23:45PM +1000, Miichael Neuling wrote:
> If the cmdline changes between boots, we can get misalignment of the
> bootargs entry, which in turn corrupts our device tree blob and hence
> kills our kexec boot.  
> 
> Specifically, if the cmdline length was >= 8 before and the new cmdline
> length is < 8, we can get corruption.

Hrm.  Have you considered using dtc for this conversion, rather than
this somewhat dubious looking fs2dt?

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

^ permalink raw reply

* Re: Using Cypress EZ-Host on ML403/5
From: Peter Korsgaard @ 2007-06-04 23:12 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-embedded
In-Reply-To: <fa686aa40706041559i43c03574kfc6ca7574e16ab3b@mail.gmail.com>

>>>>> "Grant" == Grant Likely <grant.likely@secretlab.ca> writes:

Hi,

 >> Yeah, I've also had quite varied success with USB sticks - Some work
 >> just fine, others not at all. I'm still trying to figure out what goes
 >> wrong..

 Grant> I think I've solved this problem.  The driver wasn't checking the
 Grant> active flag on TDs in check_td_list().  If the c67x00 ran out of time
 Grant> in a frame, not all the TDs would get processed.  Without this check
 Grant> the HCD would interpret unprocessed TDs as successfully completed.

Ahh - Good catch!

 Grant> I've also got a fair number of comments/changes on the driver in patch
 Grant> form.  I'll send it to the list shortly.

Great, I'm looking forward to seeing it!

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* Re: Using Cypress EZ-Host on ML403/5
From: Grant Likely @ 2007-06-04 22:59 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: linuxppc-embedded
In-Reply-To: <87wszqucpr.fsf@p4.be.48ers.dk>

On 5/2/07, Peter Korsgaard <jacmet@sunsite.dk> wrote:
> >>>>> "Grant" == Grant Likely <grant.likely@secretlab.ca> writes:
>
>  Grant> Some block devices seem to be giving me grief.  I have no problem with
>  Grant> my SanDisk ImageMate CF reader.  However, I've got a SanDisk Curzer
>  Grant> Micro that gets reset during transfers.  Is this something you've seen
>  Grant> before?  Log output is below.
>
> Yeah, I've also had quite varied success with USB sticks - Some work
> just fine, others not at all. I'm still trying to figure out what goes
> wrong..

I think I've solved this problem.  The driver wasn't checking the
active flag on TDs in check_td_list().  If the c67x00 ran out of time
in a frame, not all the TDs would get processed.  Without this check
the HCD would interpret unprocessed TDs as successfully completed.

I've also got a fair number of comments/changes on the driver in patch
form.  I'll send it to the list shortly.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: [PATCH 2/8] Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Randy Vinson @ 2007-06-04 22:31 UTC (permalink / raw)
  To: Andy Fleming; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <02DC2E36-86B1-4458-BB0C-13CF79AC1D11@freescale.com>

Andy Fleming wrote:
> On Jun 3, 2007, at 03:33, Gabriel Paubert wrote:
> 
[snippage]
>>
>> This said, I'm looking at device trees right now, and I can understand
>> that interrupt-parent of the 8259 is &mpic in mpc8641_hpcn.dts, but
>> I don't understand at all why it is &pci1 on the mpc85??cds.dts.
>>
>> But the definition of the ISA bridge in these files is very strange to
>> start with: I've never seen an ISA bridge with only an interrupt  
>> controller
>> on it, no interrupts are connected to it and its reg property is
>> almost certainly wrong. Maybe it is an example of things that should
>> not be done.
> 
> 
> I take full responsibility for that.  The CDS is a strange beast, so  
> I did some strange things in the DTS.
> 
> The i8259 is on a subsidiary bus, and so it's one bus #1.
Actually, that's not strictly true. If a card containing a P2P bridge is
installed into PCI slot 4, the i8259 will end up on a bus that is not
numbered bus 1. I've often wondered how something like that is handled
in the DTS.

Randy V.

^ permalink raw reply

* Re: [RFC/PATCH 4/4] Add support for MSI on Axon-based Cell systems
From: Benjamin Herrenschmidt @ 2007-06-04 22:45 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <90f8b99fa6a8e4b8898d64630d96036f68668b03.1180961962.git.michael@ellerman.id.au>

On Mon, 2007-06-04 at 23:00 +1000, Michael Ellerman wrote:
> This patch adds support for the setup and decoding of MSIs
> on Axon-based Cell systems.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

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

> ---
> 
> This still needs a bit of cleanup, but sending now for an early review.
> 
>  arch/powerpc/platforms/cell/Makefile   |    2 +
>  arch/powerpc/platforms/cell/axon_msi.c |  412 ++++++++++++++++++++++++++++++++
>  2 files changed, 414 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
> index 869af89..6615d40 100644
> --- a/arch/powerpc/platforms/cell/Makefile
> +++ b/arch/powerpc/platforms/cell/Makefile
> @@ -23,3 +23,5 @@ obj-$(CONFIG_SPU_BASE)			+= spu_callbacks.o spu_base.o \
>  					   $(spu-priv1-y) \
>  					   $(spu-manage-y) \
>  					   spufs/
> +
> +obj-$(CONFIG_PCI_MSI)			+= axon_msi.o
> diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
> new file mode 100644
> index 0000000..2709853
> --- /dev/null
> +++ b/arch/powerpc/platforms/cell/axon_msi.c
> @@ -0,0 +1,412 @@
> +/*
> + * Copyright 2007, Michael Ellerman, IBM Corporation.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/kernel.h>
> +#include <linux/pci.h>
> +#include <linux/msi.h>
> +#include <linux/reboot.h>
> +
> +#include <asm/dcr.h>
> +#include <asm/machdep.h>
> +#include <asm/prom.h>
> +
> +
> +/*
> + * MSIC Control Register
> + */
> +#define MSIC_CTRL_REG_ADDR	0x6F
> +
> +/* Flags */
> +#define MSIC_ENABLE		0x0001	/* Bit 31 */
> +#define MSIC_FIFO_FULL_ENABLE	0x0002	/* Bit 30 */
> +#define MSIC_IRQ_ENABLE		0x0008	/* Bit 28 */
> +#define MSIC_FULL_STOP_ENABLE	0x0010	/* Bit 27 */
> +
> +/* Size configuration constants */
> +#define MSIC_SIZE_MASK		0x0180	/* Bits 22:23 */
> +#define MSIC_SIZE_SHIFT		(7)
> +#define	MSIC_SIZE_32K		0x0
> +#define	MSIC_SIZE_64K		0x1
> +#define	MSIC_SIZE_128K		0x2
> +#define	MSIC_SIZE_256K		0x3
> +
> +/* The size we're actually using */
> +#define MSIC_FIFO_SIZE		MSIC_SIZE_32K
> +
> +/* Different representations of the fifo size */
> +#define MSIC_FIFO_SHIFT		(MSIC_FIFO_SIZE + 0xF)
> +#define MSIC_FIFO_BYTES		(1 << MSIC_FIFO_SHIFT)
> +#define MSIC_FIFO_MASK		(MSIC_FIFO_BYTES - 1)
> +#define MSIC_FIFO_ORDER		max(MSIC_FIFO_SHIFT - PAGE_SHIFT, 0)
> +
> +/*
> + * MSIC Base Address registers (FIFO location)
> + */
> +#define MSIC_BASE_ADDR_HI_REG	0x72
> +#define MSIC_BASE_ADDR_LO_REG	0x73
> +
> +#define MSIC_READ_OFFSET_REG	0x74
> +#define MSIC_WRITE_OFFSET_REG	0x75
> +
> +#define MSIC_DCR_BASE		MSIC_CTRL_REG_ADDR
> +#define MSIC_DCR_SIZE		(MSIC_WRITE_OFFSET_REG - MSIC_CTRL_REG_ADDR)
> +
> +
> +struct axon_msic {
> +	struct device_node *dn;
> +	struct irq_host *irq_host;
> +	void *fifo;
> +	dcr_host_t dcr_host;
> +	struct list_head list;
> +	u32 read_offset;
> +};
> +
> +
> +static LIST_HEAD(axon_msic_list);
> +
> +static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
> +{
> +	struct axon_msic *msic = get_irq_data(irq);
> +	u32 write_offset, msi;
> +	unsigned int cirq;
> +
> +	write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
> +	pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
> +
> +	/* write_offset doesn't wrap properly, so we have to mask it */
> +	write_offset &= MSIC_FIFO_MASK;
> +
> +	while (msic->read_offset != write_offset) {
> +		msi  = le32_to_cpup((__le32*)(msic->fifo + msic->read_offset));
> +		msi &= 0xFFFF;
> +
> +		pr_debug("axon_msi: woff %x roff %x @ %p msi %x msi@0 %x\n",
> +			write_offset, msic->read_offset,
> +			msic->fifo + msic->read_offset, msi, *(u32*)msic->fifo);
> +
> +		msic->read_offset += 0x10;
> +		msic->read_offset &= MSIC_FIFO_MASK;
> +
> +		cirq = irq_linear_revmap(msic->irq_host, msi);
> +		if (cirq != NO_IRQ)
> +			generic_handle_irq(cirq);
> +		else
> +			pr_debug("axon_msi: mapped to NO_IRQ!\n");
> +	}
> +
> +	dcr_write(msic->dcr_host, MSIC_READ_OFFSET_REG, msic->read_offset);
> +
> +	desc->chip->eoi(irq);
> +}
> +
> +static struct axon_msic *find_msi_translator(struct pci_dev *dev)
> +{
> +	struct irq_host *irq_host;
> +	struct device_node *np, *tmp;
> +	const phandle *ph;
> +
> +	np = pci_device_to_OF_node(dev);
> +	if (!np) {
> +		dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n");
> +		return NULL;
> +	}
> +
> +	for (; np; tmp = of_get_parent(np), of_node_put(np), np = tmp) {
> +		ph = of_get_property(np, "msi-translator", NULL);
> +		if (ph)
> +			break;
> +	}
> +
> +	if (!ph) {
> +		dev_dbg(&dev->dev, "axon_msi: no msi-translator found\n");
> +		goto out_error;
> +	}
> +
> +	tmp = np;
> +	np = of_find_node_by_phandle(*ph);
> +	if (!np) {
> +		dev_dbg(&dev->dev, "axon_msi: invalid msi-translator found\n");
> +		goto out_error;
> +	}
> +
> +	irq_host = irq_find_host(np);
> +	if (!irq_host) {
> +		dev_dbg(&dev->dev, "axon_msi: no irq_host found\n");
> +		goto out_error;
> +	}
> +
> +	return irq_host->host_data;
> +
> +out_error:
> +	of_node_put(np);
> +	of_node_put(tmp);
> +
> +	return NULL;
> +}
> +
> +static int axon_msi_check_device(struct pci_dev *dev, int nvec, int type)
> +{
> +	if (!find_msi_translator(dev))
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
> +{
> +	struct device_node *np, *tmp;
> +	int pos, len;
> +	u16 flags;
> +	const u32 *prop;
> +
> +	np = pci_device_to_OF_node(dev);
> +	if (!np) {
> +		dev_dbg(&dev->dev, "axon_msi: no pci_dn found\n");
> +		return -ENODEV;
> +	}
> +
> +	pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
> +	if (!pos || pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &flags)) {
> +		dev_err(&dev->dev, "axon_msi: error reading config space!\n");
> +		return -EIO;
> +	}
> +
> +	for (; np; tmp = of_get_parent(np), of_node_put(np), np = tmp) {
> +		if (flags & PCI_MSI_FLAGS_64BIT) {
> +			prop = of_get_property(np, "msi-address-64", &len);
> +			if (prop)
> +				break;
> +		}
> +
> +		prop = of_get_property(np, "msi-address-32", &len);
> +		if (prop)
> +			break;
> +	}
> +	of_node_put(np);
> +
> +	if (!prop) {
> +		dev_dbg(&dev->dev, "axon_msi: no msi-address-(32|64) found\n");
> +		return -ENOENT;
> +	}
> +
> +	switch (len) {
> +	case 8:
> +		msg->address_hi = prop[0];
> +		msg->address_lo = prop[1];
> +		break;
> +	case 4:
> +		msg->address_hi = 0;
> +		msg->address_lo = prop[0];
> +		break;
> +	default:
> +		dev_dbg(&dev->dev, "axon_msi: malformed msi-address-(32|64)\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> +{
> +	unsigned int virq, rc;
> +	struct msi_desc *entry;
> +	struct msi_msg msg;
> +	struct axon_msic *msic;
> +
> +	msic = find_msi_translator(dev);
> +	if (!msic)
> +		return -ENODEV;
> +
> +	rc = setup_msi_msg_address(dev, &msg);
> +	if (rc)
> +		return rc;
> +
> +	/* We rely on being able to stash a virq in a u16 */
> +	BUILD_BUG_ON(NR_IRQS > 65536);
> +
> +	list_for_each_entry(entry, &dev->msi_list, list) {
> +		virq = irq_create_direct_mapping(msic->irq_host);
> +		if (virq == NO_IRQ) {
> +			pr_debug("axon_msi: virq allocation failed!\n");
> +			return -1;
> +		}
> +		pr_debug("axon_msi: allocated virq 0x%x for %s\n",
> +			 virq, pci_name(dev));
> +
> +		set_irq_msi(virq, entry);
> +		msg.data = virq;
> +		write_msi_msg(virq, &msg);
> +	}
> +
> +	return 0;
> +}
> +
> +static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)
> +{
> +	struct msi_desc *entry;
> +
> +	pr_debug("axon_msi: tearing down irqs for %s\n", pci_name(dev));
> +
> +	list_for_each_entry(entry, &dev->msi_list, list) {
> +		if (entry->irq == NO_IRQ)
> +			continue;
> +
> +		set_irq_msi(entry->irq, NULL);
> +		irq_dispose_mapping(entry->irq);
> +	}
> +}
> +
> +static struct irq_chip msic_irq_chip = {
> +	.mask		= mask_msi_irq,
> +	.unmask		= unmask_msi_irq,
> +	.shutdown	= unmask_msi_irq,
> +	.typename	= "AXON-MSI",
> +};
> +
> +static int msic_host_map(struct irq_host *h, unsigned int virq,
> +			 irq_hw_number_t hw)
> +{
> +	set_irq_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq);
> +	return 0;
> +}
> +
> +static int msic_host_match(struct irq_host *host, struct device_node *node)
> +{
> +	struct axon_msic *msic = host->host_data;
> +	return msic->dn == node;
> +}
> +
> +static struct irq_host_ops msic_host_ops = {
> +	.match	= msic_host_match,
> +	.map	= msic_host_map,
> +};
> +
> +static int axon_msi_notify_reboot(struct notifier_block *nb,
> +				  unsigned long code, void *data)
> +{
> +	struct axon_msic *msic;
> +	u32 tmp;
> +
> +	list_for_each_entry(msic, &axon_msic_list, list) {
> +		tmp  = dcr_read(msic->dcr_host, MSIC_CTRL_REG_ADDR);
> +		tmp &= ~MSIC_ENABLE;
> +		dcr_write(msic->dcr_host, MSIC_CTRL_REG_ADDR, tmp);
> +		pr_debug("axon_msi: disabling %s\n", msic->dn->full_name);
> +	}
> +
> +	return 0;
> +}
> +
> +static struct notifier_block axon_msi_reboot_notifier = {
> +	.notifier_call = axon_msi_notify_reboot
> +};
> +
> +static int axon_msi_setup_one(struct device_node *node)
> +{
> +	struct page *page;
> +	struct axon_msic *msic;
> +	unsigned int virq;
> +
> +	pr_debug("axon_msi: setting up dn %s\n", node->full_name);
> +
> +	msic = kzalloc(sizeof(struct axon_msic), GFP_KERNEL);
> +	if (!msic) {
> +		printk(KERN_ERR "axon_msi: couldn't allocate msic\n");
> +		goto out_put;
> +	}
> +
> +	msic->dn = node;
> +
> +	msic->dcr_host = dcr_map(node, MSIC_DCR_BASE, MSIC_DCR_SIZE);
> +	if (!DCR_MAP_OK(msic->dcr_host)) {
> +		printk(KERN_ERR "axon_msi: dcr_map failed\n");
> +		goto out_free_msic;
> +	}
> +
> +	page = alloc_pages_node(of_node_to_nid(node),
> +				GFP_KERNEL, MSIC_FIFO_ORDER);
> +	if (!page) {
> +		printk(KERN_ERR "axon_msi: couldn't allocate fifo\n");
> +		goto out_free_msic;
> +	}
> +
> +	msic->fifo = page_address(page);
> +
> +	msic->irq_host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, NR_IRQS,
> +					&msic_host_ops, 0);
> +	if (!msic->irq_host) {
> +		printk(KERN_ERR "axon_msi: couldn't allocate host\n");
> +		goto out_free_fifo;
> +	}
> +
> +	msic->irq_host->host_data = msic;
> +
> +	virq = irq_of_parse_and_map(node, 0);
> +	if (virq == NO_IRQ) {
> +		printk(KERN_ERR "axon_msi: irq parse/map failed!\n");
> +		goto out_free_host;
> +	}
> +
> +	set_irq_data(virq, msic);
> +	set_irq_chained_handler(virq, axon_msi_cascade);
> +	pr_debug("axon_msi: irq 0x%x setup for axon_msi!\n", virq);
> +
> +	/* Enable the MSIC hardware */
> +	dcr_write(msic->dcr_host, MSIC_BASE_ADDR_HI_REG,
> +				  (u64)msic->fifo >> 32);
> +	dcr_write(msic->dcr_host, MSIC_BASE_ADDR_LO_REG,
> +				  (u64)msic->fifo & 0xFFFFFFFF);
> +	dcr_write(msic->dcr_host, MSIC_CTRL_REG_ADDR,
> +				  MSIC_IRQ_ENABLE | MSIC_ENABLE |
> +				  (MSIC_FIFO_SIZE << MSIC_SIZE_SHIFT));
> +
> +	list_add(&msic->list, &axon_msic_list);
> +
> +	return 0;
> +
> +out_free_host:
> +	kfree(msic->irq_host);
> +out_free_fifo:
> +	__free_pages(virt_to_page(msic->fifo), MSIC_FIFO_ORDER);
> +out_free_msic:
> +	kfree(msic);
> +out_put:
> +	of_node_put(node);
> +
> +	return -1;
> +}
> +
> +static int axon_msi_init(void)
> +{
> +	struct device_node *node;
> +	int found = 0;
> +
> +	pr_debug("axon_msi: initialising ...\n");
> +
> +	for_each_compatible_node(node, NULL, "ibm,axon-msic") {
> +		if (axon_msi_setup_one(of_node_get(node)) == 0)
> +			found++;
> +	}
> +	of_node_put(node);
> +
> +	if (found) {
> +		ppc_md.setup_msi_irqs = axon_msi_setup_msi_irqs;
> +		ppc_md.teardown_msi_irqs = axon_msi_teardown_msi_irqs;
> +		ppc_md.msi_check_device = axon_msi_check_device;
> +
> +		register_reboot_notifier(&axon_msi_reboot_notifier);
> +
> +		pr_debug("axon_msi: registered callbacks!\n");
> +	}
> +
> +	return 0;
> +}
> +arch_initcall(axon_msi_init);

^ permalink raw reply

* Re: [PATCH 3/4] Add for_each_compatible_node()
From: Benjamin Herrenschmidt @ 2007-06-04 22:44 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <ddbfea5b1932c224845e3441b115cf7c3e495deb.1180961962.git.michael@ellerman.id.au>

On Mon, 2007-06-04 at 23:00 +1000, Michael Ellerman wrote:
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

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

> ---
>  include/asm-powerpc/prom.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
> 
> diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
> index 6845af9..1122a92 100644
> --- a/include/asm-powerpc/prom.h
> +++ b/include/asm-powerpc/prom.h
> @@ -124,6 +124,9 @@ extern struct device_node *of_find_node_by_type(struct device_node *from,
>  	     dn = of_find_node_by_type(dn, type))
>  extern struct device_node *of_find_compatible_node(struct device_node *from,
>  	const char *type, const char *compat);
> +#define for_each_compatible_node(dn, type, compatible) \
> +	for (dn = of_find_compatible_node(NULL, type, compatible); dn; \
> +	     dn = of_find_compatible_node(dn, type, compatible))
>  extern struct device_node *of_find_node_by_path(const char *path);
>  extern struct device_node *of_find_node_by_phandle(phandle handle);
>  extern struct device_node *of_find_all_nodes(struct device_node *prev);

^ permalink raw reply

* Re: [PATCH 2/4] Add irq_create_direct_mapping()
From: Benjamin Herrenschmidt @ 2007-06-04 22:44 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <1e7f2ee0ff2e863d04e1f98f381f217359110163.1180961962.git.michael@ellerman.id.au>

On Mon, 2007-06-04 at 23:00 +1000, Michael Ellerman wrote:
> This patch adds irq_create_direct_mapping(). This routine is
> an alternative to irq_create_mapping(), for irq controllers that
> can use linux virq numbers directly as hardware numbers.
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

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

> ---
>  arch/powerpc/kernel/irq.c |   24 ++++++++++++++++++++++++
>  include/asm-powerpc/irq.h |    9 +++++++++
>  2 files changed, 33 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 9bafc88..fdb3b00 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -611,6 +611,30 @@ static int irq_setup_virq(struct irq_host *host, unsigned int virq,
>  	return 0;
>  }
>  
> +unsigned int irq_create_direct_mapping(struct irq_host *host)
> +{
> +	unsigned int virq;
> +
> +	if (host == NULL)
> +		host = irq_default_host;
> +
> +	BUG_ON(host == NULL);
> +	WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
> +
> +	virq = irq_alloc_virt(host, 1, 0);
> +	if (virq == NO_IRQ) {
> +		pr_debug("irq: create_direct virq allocation failed\n");
> +		return NO_IRQ;
> +	}
> +
> +	pr_debug("irq: create_direct obtained virq %d\n", virq);
> +
> +	if (irq_setup_virq(host, virq, virq))
> +		return NO_IRQ;
> +
> +	return virq;
> +}
> +
>  unsigned int irq_create_mapping(struct irq_host *host,
>  				irq_hw_number_t hwirq)
>  {
> diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
> index 4734cc1..8384e3f 100644
> --- a/include/asm-powerpc/irq.h
> +++ b/include/asm-powerpc/irq.h
> @@ -226,6 +226,15 @@ extern void irq_dispose_mapping(unsigned int virq);
>  extern unsigned int irq_find_mapping(struct irq_host *host,
>  				     irq_hw_number_t hwirq);
>  
> +/**
> + * irq_create_direct_mapping - Allocate a virq for direct mapping
> + * @host: host to allocate the virq for or NULL for default host
> + *
> + * This routine is used for irq controllers which can choose the hardware
> + * interrupt numbers they generate. In such a case it's simplest to use
> + * the linux virq as the hardware interrupt number.
> + */
> +extern unsigned int irq_create_direct_mapping(struct irq_host *host);
>  
>  /**
>   * irq_radix_revmap - Find a linux virq from a hw irq number.

^ permalink raw reply

* Re: [PATCH 1/4] Split virq setup logic out into irq_setup_virq()
From: Benjamin Herrenschmidt @ 2007-06-04 22:43 UTC (permalink / raw)
  To: Michael Ellerman; +Cc: linuxppc-dev
In-Reply-To: <f0cd638495b96585dec513f41335154e60675813.1180961962.git.michael@ellerman.id.au>

On Mon, 2007-06-04 at 22:59 +1000, Michael Ellerman wrote:
> A future patch will need the logic at the end of irq_create_mapping()
> which setups a virq and installs it in the irq_map. So split it out
> into a new function irq_setup_virq().
> 
> Signed-off-by: Michael Ellerman <michael@ellerman.id.au>

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

> ---
>  arch/powerpc/kernel/irq.c |   32 +++++++++++++++++++++-----------
>  1 files changed, 21 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
> index 42c8ed6..9bafc88 100644
> --- a/arch/powerpc/kernel/irq.c
> +++ b/arch/powerpc/kernel/irq.c
> @@ -591,6 +591,25 @@ static void irq_radix_rdunlock(unsigned long flags)
>  	local_irq_restore(flags);
>  }
>  
> +static int irq_setup_virq(struct irq_host *host, unsigned int virq,
> +			    irq_hw_number_t hwirq)
> +{
> +	/* Clear IRQ_NOREQUEST flag */
> +	get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
> +
> +	/* map it */
> +	smp_wmb();
> +	irq_map[virq].hwirq = hwirq;
> +	smp_mb();
> +
> +	if (host->ops->map(host, virq, hwirq)) {
> +		pr_debug("irq: -> mapping failed, freeing\n");
> +		irq_free_virt(virq, 1);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
>  
>  unsigned int irq_create_mapping(struct irq_host *host,
>  				irq_hw_number_t hwirq)
> @@ -639,18 +658,9 @@ unsigned int irq_create_mapping(struct irq_host *host,
>  	}
>  	pr_debug("irq: -> obtained virq %d\n", virq);
>  
> -	/* Clear IRQ_NOREQUEST flag */
> -	get_irq_desc(virq)->status &= ~IRQ_NOREQUEST;
> -
> -	/* map it */
> -	smp_wmb();
> -	irq_map[virq].hwirq = hwirq;
> -	smp_mb();
> -	if (host->ops->map(host, virq, hwirq)) {
> -		pr_debug("irq: -> mapping failed, freeing\n");
> -		irq_free_virt(virq, 1);
> +	if (irq_setup_virq(host, virq, hwirq))
>  		return NO_IRQ;
> -	}
> +
>  	return virq;
>  }
>  EXPORT_SYMBOL_GPL(irq_create_mapping);

^ permalink raw reply

* [PATCH v2 9/9] Created quirk_mpc8641_transparent() to initialize bridge resources.
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

The 8641 RC poses as a transparent bridge, but does not implement the
IO_BASE or IO_LIMIT registers in the config space.  This means that
the code which initializes the bridge resources ends up setting the
IO resources erroneously.

This change sets RC of mpc8641 to be a transparent bridge
for legacy I/O access and initializes the RC bridge resources
from the device tree.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---

Incorporates review suggestions from Milton.

 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |   76 ++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index a82da4b..83a2c28 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -318,6 +318,7 @@ static void __devinit quirk_uli5288(struct pci_dev *dev)
 static void __devinit quirk_uli5229(struct pci_dev *dev)
 {
 	unsigned short temp;
+
 	pci_write_config_word(dev, 0x04, 0x0405);
 	dev->class &= ~0x5;
 	pci_read_config_word(dev, 0x4a, &temp);
@@ -325,6 +326,75 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
 	pci_write_config_word(dev, 0x4a, temp);
 }
 
+static void __devinit quirk_mpc8641_transparent(struct pci_dev *dev)
+{
+	const u32 *ranges;
+	struct resource *res;
+	int len;
+	int i;
+	unsigned int flags;
+	u64 size;
+	struct device_node *node;
+	struct pci_controller *hose;
+
+	/*
+	 * Make the bridge be transparent.
+	 */
+	dev->transparent = 1;
+
+	/*
+	 * parse ranges property
+	 * Ensure IO resource is placed in the PCI_BRIDGE_RESOURCES entry.
+	 * PCI #address-cells == 3 and #size-cells == 2 always
+	 */
+	hose = pci_bus_to_hose(dev->bus->number);
+	if (!hose) {
+		printk(KERN_ERR "Can't find hose for bus %d\n",
+		       dev->bus->number);
+		return;
+	}
+	node = hose->arch_data;
+
+	ranges = of_get_property(node, "ranges", &len);
+	if (ranges == NULL) {
+		printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
+		       node->full_name);
+		return;
+	}
+
+	/*
+	 * Each PCI range is 3 words of PCI address, 1 word
+	 * of CPU address, 2 words of size:
+	 * one range is  < [pci_addr]  [CPU]  [size] >
+	 */
+	i = PCI_BRIDGE_RESOURCES + 1;
+	for (; len >= 24; len -= 24, ranges += 6) {
+		flags = of_bus_pci_get_flags(&ranges[0]);
+		size = of_read_number(&ranges[4], 2);
+		if (flags == 0 || size == 0)
+			continue;
+		if (flags & IORESOURCE_IO) {
+			res = &dev->resource[PCI_BRIDGE_RESOURCES];
+			if (res->flags) {
+				printk(KERN_ERR "PCI: ignoring extra I/O range"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+		} else {
+			if (i >= PCI_NUM_RESOURCES) {
+				printk(KERN_ERR "PCI: too many memory ranges"
+				       " for bridge %s\n", node->full_name);
+				continue;
+			}
+			res = &dev->resource[i];
+			++i;
+		}
+		res->start = of_read_number(&ranges[1], 2);
+		res->end = res->start + size - 1;
+		res->flags = flags;
+	}
+}
+
 static void __devinit early_uli5249(struct pci_dev *dev)
 {
 	unsigned char temp;
@@ -339,6 +409,12 @@ static void __devinit early_uli5249(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_FREESCALE,
+			PCI_DEVICE_ID_8641_PCI_HOST_BRIDGE,
+			quirk_mpc8641_transparent);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_FREESCALE,
+			PCI_DEVICE_ID_8641D_PCI_HOST_BRIDGE,
+			quirk_mpc8641_transparent);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249);
 #endif /* CONFIG_PCI */
 
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 8/9] Export of_bus_pci_get_flags().
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

It will be needed by the following patch.

Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/kernel/prom_parse.c |    2 +-
 include/asm-powerpc/prom.h       |    1 +
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 3786dcc..754926f 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -153,7 +153,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
 	return of_bus_default_translate(addr + 1, offset, na - 1);
 }
 
-static unsigned int of_bus_pci_get_flags(const u32 *addr)
+unsigned int of_bus_pci_get_flags(const u32 *addr)
 {
 	unsigned int flags = 0;
 	u32 w = addr[0];
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 6845af9..0168373 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -185,6 +185,7 @@ extern int pci_device_from_OF_node(struct device_node *node,
 extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
 extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
 extern void pci_create_OF_bus_map(void);
+extern unsigned int of_bus_pci_get_flags(const u32 *addr);
 #endif
 
 extern struct resource *request_OF_resource(struct device_node* node,
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 7/9] Add Freescale PCI VENDOR ID.
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org; +Cc: pci-ids

Also add 8641/8641D Host Bridge device IDs as well.
All of which already exist or have been submitted to
The Linux PCI ID Repository at:
    http://pci-ids.ucw.cz/

CC-to: pci-ids@ucw.cz
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 include/linux/pci_ids.h |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 62b3e00..0e0dc98 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2093,6 +2093,10 @@
 #define PCI_VENDOR_ID_TDI               0x192E
 #define PCI_DEVICE_ID_TDI_EHCI          0x0101
 
+#define PCI_VENDOR_ID_FREESCALE		0x1957
+#define PCI_DEVICE_ID_8641_PCI_HOST_BRIDGE	0x7010
+#define PCI_DEVICE_ID_8641D_PCI_HOST_BRIDGE	0x7011
+
 #define PCI_VENDOR_ID_PASEMI		0x1959
 
 #define PCI_VENDOR_ID_ATTANSIC		0x1969
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 6/9] Let subordinate transparent bridges be transparent.
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

In pcibios_fixup_bus(), bridges that are subordinate
to transparent bridges were still relocating their
IORESOURCE_IO and IO_RESOURCE_MEM start and end values.

Fix this by preventing the transparent bridge from
relocating the start and end values, thus allowing the
subordinate non-transparent bridge full molestation rights.

Signed-off-by: York Sun <yorksun@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---

This is the variant that was suggested by Ben H.

 arch/powerpc/kernel/pci_32.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index e66064b..7738a28 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1370,7 +1370,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 		for (i = 0; i < 4; ++i) {
 			if ((res = bus->resource[i]) == NULL)
 				continue;
-			if (!res->flags)
+			if (!res->flags || bus->self->transparent)
 				continue;
 			if (io_offset && (res->flags & IORESOURCE_IO)) {
 				res->start += io_offset;
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 5/9] Set IDE in ULI1575 to not native mode.
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: Zhang Wei <wei.zhang@freescale.com>

Set IDE in ULI1575 to not 100% native mode, which forces
the IDE driver to probe the irq itself.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 9259788..a82da4b 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -319,6 +319,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
 {
 	unsigned short temp;
 	pci_write_config_word(dev, 0x04, 0x0405);
+	dev->class &= ~0x5;
 	pci_read_config_word(dev, 0x4a, &temp);
 	temp |= 0x1000;
 	pci_write_config_word(dev, 0x4a, temp);
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 4/9] Float the PCi bus number assignments on MPC8641HPCN board.
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: Zhang Wei <wei.zhang@freescale.com>

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/platforms/86xx/mpc86xx_hpcn.c |    1 +
 arch/powerpc/platforms/86xx/pci.c          |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 1051702..9259788 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -363,6 +363,7 @@ mpc86xx_hpcn_setup_arch(void)
 	}
 
 #ifdef CONFIG_PCI
+	pci_assign_all_buses = 1;
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		add_bridge(np);
 
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 07ff52c..c80d8f1 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -136,6 +136,18 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
 
 int mpc86xx_exclude_device(u_char bus, u_char devfn)
 {
+	struct pci_controller *hose;
+
+	hose = pci_bus_to_hose(bus);
+	if (unlikely(!hose))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	/* Correcting the hose->bus_offset value. */
+	out_be32(hose->cfg_addr, 0x80000000 | ((hose->first_busno
+					- hose->bus_offset) << 16));
+	if (unlikely(in_le32(hose->cfg_data) == 0xffffffff))
+		hose->bus_offset = hose->bus_offset ? 0 : hose->first_busno;
+
 	return PCIBIOS_SUCCESSFUL;
 }
 
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 3/9] 8641HPCN: Add PCI-Express link training status check
From: Jon Loeliger @ 2007-06-04 22:30 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: Zhang Wei <wei.zhang@freescale.com>

Avoid system halt while the link training is fault.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/platforms/86xx/pci.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 7efae7c..07ff52c 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -122,7 +122,6 @@ static void __init
 mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
 {
 	u16 cmd;
-	unsigned int temps;
 
 	DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n",
 			pcie_offset, pcie_size);
@@ -140,6 +139,9 @@ int mpc86xx_exclude_device(u_char bus, u_char devfn)
 	return PCIBIOS_SUCCESSFUL;
 }
 
+#define PCIE_LTSSM	0x04000004	/* PCIe Link Training and Status */
+#define PCIE_LTSSM_L0	0x16		/* L0 state */
+
 int __init add_bridge(struct device_node *dev)
 {
 	int len;
@@ -148,12 +150,20 @@ int __init add_bridge(struct device_node *dev)
 	const int *bus_range;
 	int has_address = 0;
 	int primary = 0;
+	void *pcicfg_addr;
 
 	DBG("Adding PCIE host bridge %s\n", dev->full_name);
 
 	/* Fetch host bridge registers address */
 	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
 
+	/* Probe the hose link training status */
+	pcicfg_addr = ioremap(rsrc.start, 0x1000);
+	out_be32(pcicfg_addr, 0x80000000 | PCIE_LTSSM);
+	if (in_le16(pcicfg_addr + 4) < PCIE_LTSSM_L0)
+		return -ENXIO;
+	iounmap(pcicfg_addr);
+
 	/* Get bus range if any */
 	bus_range = of_get_property(dev, "bus-range", &len);
 	if (bus_range == NULL || len < 2 * sizeof(int))
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 2/9] Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Jon Loeliger @ 2007-06-04 22:29 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: Wade Farnsworth <wfarnsworth@mvista.com>

This adds device nodes for the PCI bridges as well as the ISA devices on
the newer revision MPC8641HPCN.  It also adds the PCI ranges to the soc
node so that address translation for the ISA devices works properly.

Signed-off-by: Wade Farnsworth <wfarnsworth@mvista.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/boot/dts/mpc8641_hpcn.dts |   97 +++++++++++++++++++++++++++----
 1 files changed, 84 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 260b264..e96c4a0 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -56,8 +56,12 @@
 		#size-cells = <1>;
 		#interrupt-cells = <2>;
 		device_type = "soc";
-		ranges = <0 f8000000 00100000>;
-		reg = <f8000000 00100000>;	// CCSRBAR 1M
+		ranges = <00001000 f8001000 000ff000
+			  80000000 80000000 20000000
+			  e2000000 e2000000 00100000
+			  a0000000 a0000000 20000000
+			  e3000000 e3000000 00100000>;
+		reg = <f8000000 00001000>;	// CCSRBAR
 		bus-frequency = <0>;
 
 		i2c@3000 {
@@ -285,17 +289,84 @@
 				f800 0 0 3 &i8259 0 0
 				f800 0 0 4 &i8259 0 0
 				>;
-			i8259: i8259@4d0 {
-				clock-frequency = <0>;
-				interrupt-controller;
-				device_type = "interrupt-controller";
-				#address-cells = <0>;
-				#interrupt-cells = <2>;
-				built-in;
-				compatible = "chrp,iic";
-                	        big-endian;
-				interrupts = <49 2>;
-				interrupt-parent = <&mpic>;
+			uli1575@0 {
+				reg = <0 0 0 0 0>;
+				#size-cells = <2>;
+				#address-cells = <3>;
+				ranges = <02000000 0 80000000
+					  02000000 0 80000000
+					  0 20000000
+					  01000000 0 00000000
+					  01000000 0 00000000
+					  0 00100000>;
+
+				pci_bridge@0 {
+					reg = <0 0 0 0 0>;
+					#size-cells = <2>;
+					#address-cells = <3>;
+					ranges = <02000000 0 80000000
+						  02000000 0 80000000
+						  0 20000000
+						  01000000 0 00000000
+						  01000000 0 00000000
+						  0 00100000>;
+
+					isa@1e {
+						device_type = "isa";
+						#interrupt-cells = <2>;
+						#size-cells = <1>;
+						#address-cells = <2>;
+						reg = <f000 0 0 0 0>;
+						ranges = <1 0 01000000 0 0
+							  00001000>;
+						interrupt-parent = <&i8259>;
+
+						i8259: interrupt-controller@20 {
+							reg = <1 20 2
+							       1 a0 2
+							       1 4d0 2>;
+							clock-frequency = <0>;
+							interrupt-controller;
+							device_type = "interrupt-controller";
+							#address-cells = <0>;
+							#interrupt-cells = <2>;
+							built-in;
+							compatible = "chrp,iic";
+							interrupts = <49 2>;
+							interrupt-parent =
+								<&mpic>;
+						};
+
+						i8042@60 {
+							#size-cells = <0>;
+							#address-cells = <1>;
+							reg = <1 60 1 1 64 1>;
+							interrupts = <1 3 c 3>;
+							interrupt-parent =
+								<&i8259>;
+
+							keyboard@0 {
+								reg = <0>;
+								compatible = "pnpPNP,303";
+							};
+
+							mouse@1 {
+								reg = <1>;
+								compatible = "pnpPNP,f03";
+							};
+						};
+
+						rtc@70 {
+							compatible =
+								"pnpPNP,b00";
+							reg = <1 70 2>;
+						};
+
+						gpio@400 {
+							reg = <1 400 80>;
+						};
+					};
+				};
 			};
 
 		};
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 1/9] Remove the errata fix codes for MPC8641 silicon ver 1.0 which is end of life.
From: Jon Loeliger @ 2007-06-04 22:29 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

From: Zhang Wei <wei.zhang@freescale.com>

Remove the errata fix codes for MPC8641 silicon ver 1.0 which
is end of life.

The MPC8641 silicon ver 1.0 is not fully support PCI/PCI Express
specifications. The revision 2.0 fixes all of these errata
and the rev 1.0 silicon is end of life. So errata codes are removed.

Now, The chip is full compatible with PCI/PCI Express
specifications. The generic PCI code is used.

Signed-off-by: Zhang Wei <wei.zhang@freescale.com>
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
Signed-off-by: Jon Loeliger <jdl@freescale.com>
---
 arch/powerpc/Kconfig                  |    3 +--
 arch/powerpc/platforms/86xx/mpc86xx.h |    6 ------
 arch/powerpc/platforms/86xx/pci.c     |   10 +---------
 3 files changed, 2 insertions(+), 17 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 56d3c0d..e683668 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -183,7 +183,6 @@ config PPC_86xx
 	bool "Freescale 86xx"
 	select 6xx
 	select FSL_SOC
-	select FSL_PCIE
 	select PPC_FPU
 	select ALTIVEC
 	help
@@ -675,7 +674,7 @@ config FSL_SOC
 
 config FSL_PCIE
 	bool
-	depends on PPC_86xx
+	depends on PPC_85xx
 
 # Yes MCA RS/6000s exist but Linux-PPC does not currently support any
 config MCA
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h
index 2834462..740b300 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx.h
+++ b/arch/powerpc/platforms/86xx/mpc86xx.h
@@ -19,12 +19,6 @@ extern int add_bridge(struct device_node *dev);
 
 extern int mpc86xx_exclude_device(u_char bus, u_char devfn);
 
-extern void setup_indirect_pcie(struct pci_controller *hose,
-				       u32 cfg_addr, u32 cfg_data);
-extern void setup_indirect_pcie_nomap(struct pci_controller *hose,
-					     void __iomem *cfg_addr,
-					     void __iomem *cfg_data);
-
 extern void __init mpc86xx_smp_init(void);
 
 #endif	/* __MPC86XX_H__ */
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 8235c56..7efae7c 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -133,18 +133,10 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
 	early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);
 
 	early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);
-
-	/* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */
-	early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps);
-	temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
-	early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
 }
 
 int mpc86xx_exclude_device(u_char bus, u_char devfn)
 {
-	if (bus == 0 && PCI_SLOT(devfn) == 0)
-		return PCIBIOS_DEVICE_NOT_FOUND;
-
 	return PCIBIOS_SUCCESSFUL;
 }
 
@@ -178,7 +170,7 @@ int __init add_bridge(struct device_node *dev)
 	hose->first_busno = bus_range ? bus_range[0] : 0x0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xfe;
 
-	setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4);
+	setup_indirect_pci(hose, rsrc.start, rsrc.start + 0x4);
 
 	/* Setup the PCIE host controller. */
 	mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1);
-- 
1.5.0.3

^ permalink raw reply related

* [PATCH v2 0/9] Add Generic PCI-E support to 8641HPCN
From: Jon Loeliger @ 2007-06-04 22:29 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org

Paul,

This 8-part patch set combines the two previous patch
sets, 5 from Zheng Wei, and 3 from me, along with one
from Wade Farnsworth into one nice-n-happy set, all
designed to re-enable PCI-Express on the MPC8641HPCN board.

This is version 2 of the patch set and incorporates
improvements suggested by list reviewers.

Yes, there is one hacky bus number adjusting being done
in  _exclude_device(), but I think I read that it will
take some fairly serious effort to rewrite the PPC-32
version of PCI bus numbering to make it "right".

In the meantime, these patches work, and will enable us
to add on the 8548 and 8544 PCI-Express code as well.

These are rebased to your current top-of-master branch.

Thanks,
jdl

^ permalink raw reply

* Re: [patch 1/3] powerpc: fix pci_setup_phb_io_dynamic for pci_iomap
From: Arnd Bergmann @ 2007-06-04 22:27 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus, cbe-oss-dev
In-Reply-To: <1180995548.31677.68.camel@localhost.localdomain>

On Tuesday 05 June 2007, Benjamin Herrenschmidt wrote:
> 
> On Mon, 2007-06-04 at 20:14 +0200, Arnd Bergmann wrote:
> > From: Arnd Bergmann <arnd.bergmann@de.ibm.com>
> > We had a problem on a system with only dynamically allocated
> > PCI buses (using of_pci_phb_driver) in combination with libata.
> > This setup ended up having no "primary" phb, which means
> > that pci_io_base never got initialized and all IO port
> > numbers are 64 bit numbers, which is larger than the
> > PIO_MASK limit.
> 
> That's for 2.6.22 ? I wonder if a better fix is to initialize
> pci_io_base statically and clear it in iSeries code... didn't I post a
> patch for that a while ago ?

We talked about this, but I can't find a patch from you that did this.
Either way should be fine, mine may be slightly less invasive, while
statically initializing pci_io_base is what you also do in your
rewrite of that code for 2.6.23.

	Arnd <><

^ permalink raw reply

* Re: [PATCH 3/5] Float the pci bus number on MPC8641HPCN board.
From: Benjamin Herrenschmidt @ 2007-06-04 22:24 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev list, Paul Mackerras, Wei Zhang
In-Reply-To: <1180983654.9632.28.camel@ld0161-tx32>

On Mon, 2007-06-04 at 14:00 -0500, Jon Loeliger wrote:
> On Fri, 2007-06-01 at 18:28, Benjamin Herrenschmidt wrote:
> > On Fri, 2007-06-01 at 14:58 -0500, Kumar Gala wrote:
> > > 
> > > So looking at the code it looks like pci_assign_all_buses should  
> > > handle numbering the busses properly when we scan the busses, so  
> > > what's the issue that causes that not to be correct? 
> > 
> > Yeah, that's what powermac uses... Any reason it wouldn't work ?
> > 
> > Ben.
> 
> Empirical testing says it doesn't work.

You may also need to tweak pcibios_assign_bus_offset to bump it to a
higher value. There are issues when renumbering bus numbers when during
the probe, a bus is renumbered to the same number as a not-yet probed
bridge on the same segment.

That is fixed on powermac by adding an artificial "offset" of 16 between
bus numbers of different domains via this offset variable.

Ben.

^ permalink raw reply

* Re: [patch 1/3] powerpc: fix pci_setup_phb_io_dynamic for pci_iomap
From: Benjamin Herrenschmidt @ 2007-06-04 22:19 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, paulus, cbe-oss-dev, Arnd Bergmann
In-Reply-To: <20070604181739.375615838@arndb.de>

On Mon, 2007-06-04 at 20:14 +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd.bergmann@de.ibm.com>
> We had a problem on a system with only dynamically allocated
> PCI buses (using of_pci_phb_driver) in combination with libata.
> This setup ended up having no "primary" phb, which means
> that pci_io_base never got initialized and all IO port
> numbers are 64 bit numbers, which is larger than the
> PIO_MASK limit.

That's for 2.6.22 ? I wonder if a better fix is to initialize
pci_io_base statically and clear it in iSeries code... didn't I post a
patch for that a while ago ?

Ben.

^ permalink raw reply

* Re: 83xx GPIO/EXT int in arch/powerpc/
From: Andy Fleming @ 2007-06-04 21:57 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev
In-Reply-To: <20070604211740.GN17456@chiana.homelinux.org>


On Jun 4, 2007, at 16:17, Marc Leeman wrote:

>
> So I don't have to define the GPIO pins in pio-map in "vi) Pin
> configuration nodes" and already set in the U-Boot bootloader?  
> Using the
> GPIOs for interrupts or IO would just work "out of the box" after the
> U-boot initialisation (used for TI's HPI in with the UPMB).

I meant external interrupts, not GPIOs.  I just had a brain fart.

>
> Hang, and I finally thought the documentation made sense to me :-)
>
> I already tried hardcoding the EXT7 pin as assigned in the ppc arch
> (int 23); this would mean that, in the powerpc arch, the  
> assignments of
> interrupts is different wrt to ppc?


In the intervening versions between the introduction of arch/powerpc,  
and now, the interrupt mapping has also changed.  The interrupts are  
now all virtualized, and therefore all the interrupts start at 1 for  
each interrupt controller.  The numbers therefore change depending on  
how things are initialized.  You can't use hard-coded numbers  
anymore.  You need to map them into virtual numbers.  The easiest way  
is to set up an of node for the device, and invoke the necessary  
translation functions from your board code (Take a look at the CDS  
code for an example with a fairly complicated tree.  Or any other fsl  
board code for an almost-reasonable topology.  :) )

Andy

^ permalink raw reply


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