LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: Porting Linux to Xilinx ML410
From: Thomas Glanzmann @ 2007-06-27 21:18 UTC (permalink / raw)
  To: khollan; +Cc: linuxppc-embedded
In-Reply-To: <11328063.post@talk.nabble.com>

Hello,

> Linux/PPC load: console=ttyUL0,9600 root=/dev/xsysace/disc0/part3 rw
> Uncompressing Linux...done.
> Now booting the kernel

> It always stall on the Now booting the kernel.  Im new to linux
> building and any help or suggestions are greatly appreciated.

I have the same problem on a Avnet Memev Virtex-4 FX12 LC Board. I typed
"stop" in the xmd and got an Instruction pointer. I took this
instruction pointer and called:

(thinkpad) [/scratch/tg/linux-2.6-ppc] powerpc-405-linux-gnu-objdump -dS vmlinux | less
/^c00045ac

c00045a0 <__delay>:
c00045a0:       2c 03 00 00     cmpwi   r3,0
c00045a4:       7c 69 03 a6     mtctr   r3
c00045a8:       4d 82 00 20     beqlr
c00045ac:       42 00 00 00     bdnz-   c00045ac <__delay+0xc> <<<< HERE
c00045b0:       4e 80 00 20     blr

which is called from the calibrating delay loop. The calibrating delay
loop is an endless loop if the jiffies do not get incremented. Which is
the case if there are no timer ticks for whatever reason. Reasons could
be:

        - PIT or FIT don't get initialized
        - Interrupts are disabled
        - No interrupt handler registerd or registered for the wrong iq.

However the calibrating delay loop is before the serial console
initialization code. The "Now booting the kernel" line comes from the in
kernel embedded bootloader just before it initalizes the MMU and jumps
to "start_kernel".

If you do any progress on that, please let me know. I am currently
extremly busy, so I don't have time at the moment to debug that any
further.

        Thomas

^ permalink raw reply

* Re: [PATCH 09/15] [POWERPC] 86xx: Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Kumar Gala @ 2007-06-27 21:08 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev list
In-Reply-To: <0639caa4f420578b671c9e2f9713ba39@kernel.crashing.org>


On Jun 27, 2007, at 3:57 PM, Segher Boessenkool wrote:

>>>>> -		ranges = <0 f8000000 00100000>;
>>>>> -		reg = <f8000000 00100000>;	// CCSRBAR 1M
>>>>> +		ranges = <00001000 f8001000 000ff000
>>>> [...]
>>>>> +		reg = <f8000000 00001000>;	// CCSRBAR
>>>>
>>>> This can't be right, and I suspect it will break any kernel  
>>>> access to
>>>> the first 0x1000 bytes of the CCSR_BAR space.  reg should actually
>>>> describe the register space of the SOC.  If ranges needs to specify
>>>> that, too, they should be able to be redundant.  But this looks  
>>>> like
>>>> a big hack, to me.  Am I missing something?
>>>
>>> "reg" and "ranges" can never overlap really.
>>>
>>> Is this the special case where the PHB is visible in
>>> PCI configuration space?
>>>
>>> Or, please explain what CCSR_BAR is...
>>
>> Its a 1M MMIO register space on the SOC (all device registers on  
>> the SOC live there).
>
> Okay, so it has nothing to do with PCI configuration space?

correct

> There is "BAR" in the name, so it is a movable range?  Where
> is the base address set?

in a MMIO register in the space itself.

> What is the relationship between (in the example) the address
> ranges x'f800_0000+1000 and x'f800_1000+ff000?

uugh, not sure what that's all about.

- k

^ permalink raw reply

* Re: [PATCH 3/5 v2] Add the platform device support with RapidIO to MPC8641HPCN platform.
From: Arnd Bergmann @ 2007-06-27 20:56 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus, linux-kernel
In-Reply-To: <1182933348216-git-send-email-wei.zhang@freescale.com>

On Wednesday 27 June 2007, Zhang Wei wrote:
> +static struct of_device_id mpc86xx_of_ids[] =3D {
> +=A0=A0=A0=A0=A0=A0=A0{ .type =3D "soc", },
> +=A0=A0=A0=A0=A0=A0=A0{ .compatible =3D "fsl,rapidio-delta", },
> +=A0=A0=A0=A0=A0=A0=A0{},
> +};
> +
> +static __init int mpc86xx_of_device_init(void)
> +{
> +=A0=A0=A0=A0=A0=A0=A0return of_platform_bus_probe(NULL, mpc86xx_of_ids, =
NULL);
> +}

This will add any devices below the "fsl,rapidio-delta" device
as an of_device. Is that what you actually want? I would guess that
you want to add the bridge itself, not the devices below it.

Is the rapidio device at the root of the device tree, and if so, why
not under the soc bus?

	Arnd <><

^ permalink raw reply

* Re: [PATCH 09/15] [POWERPC] 86xx: Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Segher Boessenkool @ 2007-06-27 20:57 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <41E15EC0-D16E-4A9F-BCA8-1E126F6D95A7@kernel.crashing.org>

>>>> -		ranges = <0 f8000000 00100000>;
>>>> -		reg = <f8000000 00100000>;	// CCSRBAR 1M
>>>> +		ranges = <00001000 f8001000 000ff000
>>> [...]
>>>> +		reg = <f8000000 00001000>;	// CCSRBAR
>>>
>>> This can't be right, and I suspect it will break any kernel access to
>>> the first 0x1000 bytes of the CCSR_BAR space.  reg should actually
>>> describe the register space of the SOC.  If ranges needs to specify
>>> that, too, they should be able to be redundant.  But this looks like
>>> a big hack, to me.  Am I missing something?
>>
>> "reg" and "ranges" can never overlap really.
>>
>> Is this the special case where the PHB is visible in
>> PCI configuration space?
>>
>> Or, please explain what CCSR_BAR is...
>
> Its a 1M MMIO register space on the SOC (all device registers on the 
> SOC live there).

Okay, so it has nothing to do with PCI configuration space?

There is "BAR" in the name, so it is a movable range?  Where
is the base address set?

What is the relationship between (in the example) the address
ranges x'f800_0000+1000 and x'f800_1000+ff000?


Segher

^ permalink raw reply

* Re: [PATCH 09/15] [POWERPC] 86xx: Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Kumar Gala @ 2007-06-27 20:43 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev
In-Reply-To: <8fa84ed4810eb9aca18739bf709e71d9@kernel.crashing.org>


On Jun 27, 2007, at 3:39 PM, Segher Boessenkool wrote:

>>> -		ranges = <0 f8000000 00100000>;
>>> -		reg = <f8000000 00100000>;	// CCSRBAR 1M
>>> +		ranges = <00001000 f8001000 000ff000
>> [...]
>>> +		reg = <f8000000 00001000>;	// CCSRBAR
>>
>> This can't be right, and I suspect it will break any kernel access to
>> the first 0x1000 bytes of the CCSR_BAR space.  reg should actually
>> describe the register space of the SOC.  If ranges needs to specify
>> that, too, they should be able to be redundant.  But this looks like
>> a big hack, to me.  Am I missing something?
>
> "reg" and "ranges" can never overlap really.
>
> Is this the special case where the PHB is visible in
> PCI configuration space?
>
> Or, please explain what CCSR_BAR is...

Its a 1M MMIO register space on the SOC (all device registers on the  
SOC live there).

- k

^ permalink raw reply

* Re: [PATCH 09/15] [POWERPC] 86xx: Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Segher Boessenkool @ 2007-06-27 20:39 UTC (permalink / raw)
  To: Andy Fleming; +Cc: linuxppc-dev
In-Reply-To: <C84F154C-EBC9-471F-A1E1-635A385E684A@freescale.com>

>> -		ranges = <0 f8000000 00100000>;
>> -		reg = <f8000000 00100000>;	// CCSRBAR 1M
>> +		ranges = <00001000 f8001000 000ff000
> [...]
>> +		reg = <f8000000 00001000>;	// CCSRBAR
>
> This can't be right, and I suspect it will break any kernel access to
> the first 0x1000 bytes of the CCSR_BAR space.  reg should actually
> describe the register space of the SOC.  If ranges needs to specify
> that, too, they should be able to be redundant.  But this looks like
> a big hack, to me.  Am I missing something?

"reg" and "ranges" can never overlap really.

Is this the special case where the PHB is visible in
PCI configuration space?

Or, please explain what CCSR_BAR is...


Segher

^ permalink raw reply

* Re: [PATCH 09/15] [POWERPC] 86xx: Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Andy Fleming @ 2007-06-27 19:57 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <11829070192461-git-send-email-galak@kernel.crashing.org>


On Jun 26, 2007, at 20:16, Kumar Gala wrote:

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

>
> -		ranges = <0 f8000000 00100000>;
> -		reg = <f8000000 00100000>;	// CCSRBAR 1M
> +		ranges = <00001000 f8001000 000ff000
[...]
> +		reg = <f8000000 00001000>;	// CCSRBAR


This can't be right, and I suspect it will break any kernel access to  
the first 0x1000 bytes of the CCSR_BAR space.  reg should actually  
describe the register space of the SOC.  If ranges needs to specify  
that, too, they should be able to be redundant.  But this looks like  
a big hack, to me.  Am I missing something?


Andy

^ permalink raw reply

* Re: booting linux-2.6.15 hang on custom mpc8555 board
From: Andy Fleming @ 2007-06-27 19:32 UTC (permalink / raw)
  To: huangyun; +Cc: linuxppc-embedded
In-Reply-To: <OF7929EEAE.73E06DAF-ON48257306.0036AB63-48257306.0039FAD3@coship.com>


On Jun 26, 2007, at 05:33, huangyun@coship.com wrote:

>
> hi,everyone
>    I have porting linux2.6.15 of eldk4.0 to my mpc8555 board, my  
> bootloader
> is u-boot1.1.6, the uboot running is ok,but it hang at booting  
> kernel.no
> any print message.
> I have check the CCSRBAR(0xe0000000) and bd_t struct is the  same  
> as linux
> kernel,  my serial port use uart1. somebody help me! i'm a linux  
> kernel
> newer.

What's your boot command line?

Andy

^ permalink raw reply

* [PATCH 8/8] [POWERPC] Use ppc64 style list management for pci_controller on ppc32
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683733835-git-send-email-galak@kernel.crashing.org>

Use the ppc64 style list management and allocation functions for
pci_controllers.  This makes the pci_controller structs just a bit more
common between ppc32 & ppc64.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/kernel/pci-common.c |   78 ++++++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/pci_32.c     |   61 +++++-------------------------
 arch/powerpc/kernel/pci_64.c     |   66 --------------------------------
 include/asm-powerpc/pci-bridge.h |   11 +++--
 4 files changed, 94 insertions(+), 122 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index b518b88..295cbb1 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -36,6 +36,62 @@
 #define DBG(fmt...)
 #endif
 
+static DEFINE_SPINLOCK(hose_spinlock);
+
+/* XXX kill that some day ... */
+int global_phb_number;		/* Global phb counter */
+
+extern struct list_head hose_list;
+
+/*
+ * pci_controller(phb) initialized common variables.
+ */
+static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
+{
+	memset(hose, 0, sizeof(struct pci_controller));
+
+	spin_lock(&hose_spinlock);
+	hose->global_number = global_phb_number++;
+	list_add_tail(&hose->list_node, &hose_list);
+	spin_unlock(&hose_spinlock);
+}
+
+struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
+{
+	struct pci_controller *phb;
+
+	if (mem_init_done)
+		phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
+	else
+		phb = alloc_bootmem(sizeof (struct pci_controller));
+	if (phb == NULL)
+		return NULL;
+	pci_setup_pci_controller(phb);
+	phb->arch_data = dev;
+	phb->is_dynamic = mem_init_done;
+#ifdef CONFIG_PPC64
+	if (dev) {
+		int nid = of_node_to_nid(dev);
+
+		if (nid < 0 || !node_online(nid))
+			nid = -1;
+
+		PHB_SET_NODE(phb, nid);
+	}
+#endif
+	return phb;
+}
+
+void pcibios_free_controller(struct pci_controller *phb)
+{
+	spin_lock(&hose_spinlock);
+	list_del(&phb->list_node);
+	spin_unlock(&hose_spinlock);
+
+	if (phb->is_dynamic)
+		kfree(phb);
+}
+
 /*
  * Return the domain number for this bus.
  */
@@ -53,6 +109,28 @@ int pci_domain_nr(struct pci_bus *bus)
 EXPORT_SYMBOL(pci_domain_nr);
 
 #ifdef CONFIG_PPC_OF
+
+/* This routine is meant to be used early during boot, when the
+ * PCI bus numbers have not yet been assigned, and you need to
+ * issue PCI config cycles to an OF device.
+ * It could also be used to "fix" RTAS config cycles if you want
+ * to set pci_assign_all_buses to 1 and still use RTAS for PCI
+ * config cycles.
+ */
+struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
+{
+	if (!have_of)
+		return NULL;
+	while(node) {
+		struct pci_controller *hose, *tmp;
+		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
+			if (hose->arch_data == node)
+				return hose;
+		node = node->parent;
+	}
+	return NULL;
+}
+
 static ssize_t pci_show_devspec(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 3dd931e..10d8a35 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -55,8 +55,7 @@ static u8* pci_to_OF_bus_map;
  */
 int pci_assign_all_buses;
 
-struct pci_controller* hose_head;
-struct pci_controller** hose_tail = &hose_head;
+LIST_HEAD(hose_list);
 
 static int pci_bus_count;
 
@@ -607,25 +606,6 @@ pcibios_enable_resources(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-static int next_controller_index;
-
-struct pci_controller * __init
-pcibios_alloc_controller(struct device_node *dev)
-{
-	struct pci_controller *hose;
-
-	hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose));
-	memset(hose, 0, sizeof(struct pci_controller));
-
-	*hose_tail = hose;
-	hose_tail = &hose->next;
-
-	hose->global_number = next_controller_index++;
-	hose->arch_data = dev;
-
-	return hose;
-}
-
 #ifdef CONFIG_PPC_OF
 /*
  * Functions below are used on OpenFirmware machines.
@@ -671,7 +651,7 @@ void
 pcibios_make_OF_bus_map(void)
 {
 	int i;
-	struct pci_controller* hose;
+	struct pci_controller *hose, *tmp;
 	struct property *map_prop;
 	struct device_node *dn;
 
@@ -688,7 +668,7 @@ pcibios_make_OF_bus_map(void)
 		pci_to_OF_bus_map[i] = 0xff;
 
 	/* For each hose, we begin searching bridges */
-	for(hose=hose_head; hose; hose=hose->next) {
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		struct device_node* node;	
 		node = (struct device_node *)hose->arch_data;
 		if (!node)
@@ -819,27 +799,6 @@ pci_device_to_OF_node(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(pci_device_to_OF_node);
 
-/* This routine is meant to be used early during boot, when the
- * PCI bus numbers have not yet been assigned, and you need to
- * issue PCI config cycles to an OF device.
- * It could also be used to "fix" RTAS config cycles if you want
- * to set pci_assign_all_buses to 1 and still use RTAS for PCI
- * config cycles.
- */
-struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
-{
-	if (!have_of)
-		return NULL;
-	while(node) {
-		struct pci_controller* hose;
-		for (hose=hose_head;hose;hose=hose->next)
-			if (hose->arch_data == node)
-				return hose;
-		node=node->parent;
-	}
-	return NULL;
-}
-
 static int
 find_OF_pci_device_filter(struct device_node* node, void* data)
 {
@@ -1248,14 +1207,14 @@ pcibios_fixup_p2p_bridges(void)
 static int __init
 pcibios_init(void)
 {
-	struct pci_controller *hose;
+	struct pci_controller *hose, *tmp;
 	struct pci_bus *bus;
-	int next_busno;
+	int next_busno = 0;
 
 	printk(KERN_INFO "PCI: Probing PCI hardware\n");
 
 	/* Scan all of the recorded PCI controllers.  */
-	for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		if (pci_assign_all_buses)
 			hose->first_busno = next_busno;
 		hose->last_busno = 0xff;
@@ -1410,9 +1369,9 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 static struct pci_controller*
 pci_bus_to_hose(int bus)
 {
-	struct pci_controller* hose = hose_head;
+	struct pci_controller *hose, *tmp;
 
-	for (; hose; hose = hose->next)
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
 		if (bus >= hose->first_busno && bus <= hose->last_busno)
 			return hose;
 	return NULL;
@@ -1462,9 +1421,9 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
 
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
-	struct pci_controller* hose = hose_head;
+	struct pci_controller *hose, *tmp;
 
-	for (; hose; hose = hose->next) {
+	list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
 		unsigned int size = hose->io_resource.end -
 			hose->io_resource.start + 1;
 		if (address >= hose->io_base_phys &&
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 7a9a4fc..e386e3e 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -59,9 +59,6 @@ LIST_HEAD(hose_list);
 
 static struct dma_mapping_ops *pci_dma_ops;
 
-/* XXX kill that some day ... */
-int global_phb_number;		/* Global phb counter */
-
 void set_pci_dma_ops(struct dma_mapping_ops *dma_ops)
 {
 	pci_dma_ops = dma_ops;
@@ -172,55 +169,6 @@ void pcibios_align_resource(void *data, struct resource *res,
 	res->start = start;
 }
 
-static DEFINE_SPINLOCK(hose_spinlock);
-
-/*
- * pci_controller(phb) initialized common variables.
- */
-static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
-{
-	memset(hose, 0, sizeof(struct pci_controller));
-
-	spin_lock(&hose_spinlock);
-	hose->global_number = global_phb_number++;
-	list_add_tail(&hose->list_node, &hose_list);
-	spin_unlock(&hose_spinlock);
-}
-
-struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
-{
-	struct pci_controller *phb;
-
-	if (mem_init_done)
-		phb = kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
-	else
-		phb = alloc_bootmem(sizeof (struct pci_controller));
-	if (phb == NULL)
-		return NULL;
-	pci_setup_pci_controller(phb);
-	phb->arch_data = dev;
-	phb->is_dynamic = mem_init_done;
-	if (dev) {
-		int nid = of_node_to_nid(dev);
-
-		if (nid < 0 || !node_online(nid))
-			nid = -1;
-
-		PHB_SET_NODE(phb, nid);
-	}
-	return phb;
-}
-
-void pcibios_free_controller(struct pci_controller *phb)
-{
-	spin_lock(&hose_spinlock);
-	list_del(&phb->list_node);
-	spin_unlock(&hose_spinlock);
-
-	if (phb->is_dynamic)
-		kfree(phb);
-}
-
 void __devinit pcibios_claim_one_bus(struct pci_bus *b)
 {
 	struct pci_dev *dev;
@@ -957,20 +905,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pcibios_fixup_bus);
 
-struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
-{
-	if (!have_of)
-		return NULL;
-	while(node) {
-		struct pci_controller *hose, *tmp;
-		list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
-			if (hose->arch_data == node)
-				return hose;
-		node = node->parent;
-	}
-	return NULL;
-}
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 	struct pci_controller *hose, *tmp;
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 69ea865..e72c2a6 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -2,9 +2,11 @@
 #define _ASM_POWERPC_PCI_BRIDGE_H
 #ifdef __KERNEL__
 
-#ifndef CONFIG_PPC64
-#include <linux/ioport.h>
 #include <linux/pci.h>
+#include <linux/list.h>
+#include <linux/ioport.h>
+
+#ifndef CONFIG_PPC64
 
 struct device_node;
 struct pci_controller;
@@ -14,8 +16,9 @@ struct pci_controller;
  */
 struct pci_controller {
 	struct pci_bus *bus;
+	char is_dynamic;
 	void *arch_data;
-	struct pci_controller *next;
+	struct list_head list_node;
 	struct device *parent;
 
 	int first_busno;
@@ -84,8 +87,6 @@ extern void setup_grackle(struct pci_controller *hose);
 
 #else
 
-#include <linux/pci.h>
-#include <linux/list.h>
 
 /*
  * This program is free software; you can redistribute it and/or
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 7/8] [POWERPC] Move common PCI code out of pci_32/pci_64
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683713322-git-send-email-galak@kernel.crashing.org>

Moved the low hanging fruit that was either identical or close
to it between ppc32 & ppc64 for PCI into pci-common.c

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/kernel/pci-common.c |  314 ++++++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/pci_32.c     |  294 -----------------------------------
 arch/powerpc/kernel/pci_64.c     |  309 -------------------------------------
 3 files changed, 314 insertions(+), 603 deletions(-)

diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 3ca8cfb..b518b88 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -51,3 +51,317 @@ int pci_domain_nr(struct pci_bus *bus)
 }
 
 EXPORT_SYMBOL(pci_domain_nr);
+
+#ifdef CONFIG_PPC_OF
+static ssize_t pci_show_devspec(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct pci_dev *pdev;
+	struct device_node *np;
+
+	pdev = to_pci_dev (dev);
+	np = pci_device_to_OF_node(pdev);
+	if (np == NULL || np->full_name == NULL)
+		return 0;
+	return sprintf(buf, "%s", np->full_name);
+}
+static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
+#endif /* CONFIG_PPC_OF */
+
+/* Add sysfs properties */
+void pcibios_add_platform_entries(struct pci_dev *pdev)
+{
+#ifdef CONFIG_PPC_OF
+	device_create_file(&pdev->dev, &dev_attr_devspec);
+#endif /* CONFIG_PPC_OF */
+}
+
+char __init *pcibios_setup(char *str)
+{
+	return str;
+}
+
+/*
+ * Reads the interrupt pin to determine if interrupt is use by card.
+ * If the interrupt is used, then gets the interrupt line from the
+ * openfirmware and sets it in the pci_dev and pci_config line.
+ */
+int pci_read_irq_line(struct pci_dev *pci_dev)
+{
+	struct of_irq oirq;
+	unsigned int virq;
+
+	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
+
+#ifdef DEBUG
+	memset(&oirq, 0xff, sizeof(oirq));
+#endif
+	/* Try to get a mapping from the device-tree */
+	if (of_irq_map_pci(pci_dev, &oirq)) {
+		u8 line, pin;
+
+		/* If that fails, lets fallback to what is in the config
+		 * space and map that through the default controller. We
+		 * also set the type to level low since that's what PCI
+		 * interrupts are. If your platform does differently, then
+		 * either provide a proper interrupt tree or don't use this
+		 * function.
+		 */
+		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
+			return -1;
+		if (pin == 0)
+			return -1;
+		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
+		    line == 0xff) {
+			return -1;
+		}
+		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
+
+		virq = irq_create_mapping(NULL, line);
+		if (virq != NO_IRQ)
+			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+	} else {
+		DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
+		    oirq.size, oirq.specifier[0], oirq.specifier[1],
+		    oirq.controller->full_name);
+
+		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+					     oirq.size);
+	}
+	if(virq == NO_IRQ) {
+		DBG(" -> failed to map !\n");
+		return -1;
+	}
+
+	DBG(" -> mapped to linux irq %d\n", virq);
+
+	pci_dev->irq = virq;
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_read_irq_line);
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
+					       resource_size_t *offset,
+					       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (hose == 0)
+		return NULL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
+		*offset += hose->pci_mem_offset;
+#endif
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+		*offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+			*offset += hose->io_base_phys - io_offset;
+		return rp;
+	}
+
+	return NULL;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
+				      pgprot_t protection,
+				      enum pci_mmap_state mmap_state,
+				      int write_combine)
+{
+	unsigned long prot = pgprot_val(protection);
+
+	/* Write combine is always 0 on non-memory space mappings. On
+	 * memory space, if the user didn't pass 1, we check for a
+	 * "prefetchable" resource. This is a bit hackish, but we use
+	 * this to workaround the inability of /sysfs to provide a write
+	 * combine bit
+	 */
+	if (mmap_state != pci_mmap_mem)
+		write_combine = 0;
+	else if (write_combine == 0) {
+		if (rp->flags & IORESOURCE_PREFETCH)
+			write_combine = 1;
+	}
+
+	/* XXX would be nice to have a way to ask for write-through */
+	prot |= _PAGE_NO_CACHE;
+	if (write_combine)
+		prot &= ~_PAGE_GUARDED;
+	else
+		prot |= _PAGE_GUARDED;
+
+	return __pgprot(prot);
+}
+
+/*
+ * This one is used by /dev/mem and fbdev who have no clue about the
+ * PCI device, it tries to find the PCI device first and calls the
+ * above routine
+ */
+pgprot_t pci_phys_mem_access_prot(struct file *file,
+				  unsigned long pfn,
+				  unsigned long size,
+				  pgprot_t protection)
+{
+	struct pci_dev *pdev = NULL;
+	struct resource *found = NULL;
+	unsigned long prot = pgprot_val(protection);
+	unsigned long offset = pfn << PAGE_SHIFT;
+	int i;
+
+	if (page_is_ram(pfn))
+		return __pgprot(prot);
+
+	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+
+	for_each_pci_dev(pdev) {
+		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+			struct resource *rp = &pdev->resource[i];
+			int flags = rp->flags;
+
+			/* Active and same type? */
+			if ((flags & IORESOURCE_MEM) == 0)
+				continue;
+			/* In the range of this resource? */
+			if (offset < (rp->start & PAGE_MASK) ||
+			    offset > rp->end)
+				continue;
+			found = rp;
+			break;
+		}
+		if (found)
+			break;
+	}
+	if (found) {
+		if (found->flags & IORESOURCE_PREFETCH)
+			prot &= ~_PAGE_GUARDED;
+		pci_dev_put(pdev);
+	}
+
+	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+
+	return __pgprot(prot);
+}
+
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
+	struct resource *rp;
+	int ret;
+
+	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
+	if (rp == NULL)
+		return -EINVAL;
+
+	vma->vm_pgoff = offset >> PAGE_SHIFT;
+	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
+						  vma->vm_page_prot,
+						  mmap_state, write_combine);
+
+	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
+}
+
+void pci_resource_to_user(const struct pci_dev *dev, int bar,
+			  const struct resource *rsrc,
+			  resource_size_t *start, resource_size_t *end)
+{
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
+	resource_size_t offset = 0;
+
+	if (hose == NULL)
+		return;
+
+	if (rsrc->flags & IORESOURCE_IO)
+		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+
+	/* We pass a fully fixed up address to userland for MMIO instead of
+	 * a BAR value because X is lame and expects to be able to use that
+	 * to pass to /dev/mem !
+	 *
+	 * That means that we'll have potentially 64 bits values where some
+	 * userland apps only expect 32 (like X itself since it thinks only
+	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
+	 * 32 bits CHRPs :-(
+	 *
+	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
+	 * has been fixed (and the fix spread enough), we can re-enable the
+	 * 2 lines below and pass down a BAR value to userland. In that case
+	 * we'll also have to re-enable the matching code in
+	 * __pci_mmap_make_offset().
+	 *
+	 * BenH.
+	 */
+#if 0
+	else if (rsrc->flags & IORESOURCE_MEM)
+		offset = hose->pci_mem_offset;
+#endif
+
+	*start = rsrc->start - offset;
+	*end = rsrc->end - offset;
+}
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index c81ffa2..3dd931e 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1028,34 +1028,12 @@ pci_create_OF_bus_map(void)
 	}
 }
 
-static ssize_t pci_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct pci_dev *pdev;
-	struct device_node *np;
-
-	pdev = to_pci_dev (dev);
-	np = pci_device_to_OF_node(pdev);
-	if (np == NULL || np->full_name == NULL)
-		return 0;
-	return sprintf(buf, "%s", np->full_name);
-}
-static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-
 #else /* CONFIG_PPC_OF */
 void pcibios_make_OF_bus_map(void)
 {
 }
 #endif /* CONFIG_PPC_OF */
 
-/* Add sysfs properties */
-void pcibios_add_platform_entries(struct pci_dev *pdev)
-{
-#ifdef CONFIG_PPC_OF
-	device_create_file(&pdev->dev, &dev_attr_devspec);
-#endif /* CONFIG_PPC_OF */
-}
-
-
 #ifdef CONFIG_PPC_PMAC
 /*
  * This set of routines checks for PCI<->PCI bridges that have closed
@@ -1390,11 +1368,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 	}
 }
 
-char __init *pcibios_setup(char *str)
-{
-	return str;
-}
-
 /* the next one is stolen from the alpha port... */
 void __init
 pcibios_update_irq(struct pci_dev *dev, int irq)
@@ -1403,64 +1376,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
 	/* XXX FIXME - update OF device tree node interrupt property */
 }
 
-#ifdef CONFIG_PPC_MERGE
-/* XXX This is a copy of the ppc64 version. This is temporary until we start
- * merging the 2 PCI layers
- */
-/*
- * Reads the interrupt pin to determine if interrupt is use by card.
- * If the interrupt is used, then gets the interrupt line from the
- * openfirmware and sets it in the pci_dev and pci_config line.
- */
-int pci_read_irq_line(struct pci_dev *pci_dev)
-{
-	struct of_irq oirq;
-	unsigned int virq;
-
-	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
-
-	/* Try to get a mapping from the device-tree */
-	if (of_irq_map_pci(pci_dev, &oirq)) {
-		u8 line, pin;
-
-		/* If that fails, lets fallback to what is in the config
-		 * space and map that through the default controller. We
-		 * also set the type to level low since that's what PCI
-		 * interrupts are. If your platform does differently, then
-		 * either provide a proper interrupt tree or don't use this
-		 * function.
-		 */
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
-			return -1;
-		if (pin == 0)
-			return -1;
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
-		    line == 0xff) {
-			return -1;
-		}
-		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
-
-		virq = irq_create_mapping(NULL, line);
-		if (virq != NO_IRQ)
-			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
-	} else {
-		DBG(" -> got one, spec %d cells (0x%08x...) on %s\n",
-		    oirq.size, oirq.specifier[0], oirq.controller->full_name);
-
-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
-					     oirq.size);
-	}
-	if(virq == NO_IRQ) {
-		DBG(" -> failed to map !\n");
-		return -1;
-	}
-	pci_dev->irq = virq;
-
-	return 0;
-}
-EXPORT_SYMBOL(pci_read_irq_line);
-#endif /* CONFIG_PPC_MERGE */
-
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	u16 cmd, old_cmd;
@@ -1503,176 +1418,6 @@ pci_bus_to_hose(int bus)
 	return NULL;
 }
 
-static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
-					       resource_size_t *offset,
-					       enum pci_mmap_state mmap_state)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long io_offset = 0;
-	int i, res_bit;
-
-	if (hose == 0)
-		return NULL;		/* should never happen */
-
-	/* If memory, add on the PCI bridge address offset */
-	if (mmap_state == pci_mmap_mem) {
-#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
-		*offset += hose->pci_mem_offset;
-#endif
-		res_bit = IORESOURCE_MEM;
-	} else {
-		io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE;
-		*offset += io_offset;
-		res_bit = IORESOURCE_IO;
-	}
-
-	/*
-	 * Check that the offset requested corresponds to one of the
-	 * resources of the device.
-	 */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		struct resource *rp = &dev->resource[i];
-		int flags = rp->flags;
-
-		/* treat ROM as memory (should be already) */
-		if (i == PCI_ROM_RESOURCE)
-			flags |= IORESOURCE_MEM;
-
-		/* Active and same type? */
-		if ((flags & res_bit) == 0)
-			continue;
-
-		/* In the range of this resource? */
-		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
-			continue;
-
-		/* found it! construct the final physical address */
-		if (mmap_state == pci_mmap_io)
-			*offset += hose->io_base_phys - io_offset;
-		return rp;
-	}
-
-	return NULL;
-}
-
-/*
- * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
- * device mapping.
- */
-static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
-				      pgprot_t protection,
-				      enum pci_mmap_state mmap_state,
-				      int write_combine)
-{
-	unsigned long prot = pgprot_val(protection);
-
-	/* Write combine is always 0 on non-memory space mappings. On
-	 * memory space, if the user didn't pass 1, we check for a
-	 * "prefetchable" resource. This is a bit hackish, but we use
-	 * this to workaround the inability of /sysfs to provide a write
-	 * combine bit
-	 */
-	if (mmap_state != pci_mmap_mem)
-		write_combine = 0;
-	else if (write_combine == 0) {
-		if (rp->flags & IORESOURCE_PREFETCH)
-			write_combine = 1;
-	}
-
-	/* XXX would be nice to have a way to ask for write-through */
-	prot |= _PAGE_NO_CACHE;
-	if (write_combine)
-		prot &= ~_PAGE_GUARDED;
-	else
-		prot |= _PAGE_GUARDED;
-
-	return __pgprot(prot);
-}
-
-/*
- * This one is used by /dev/mem and fbdev who have no clue about the
- * PCI device, it tries to find the PCI device first and calls the
- * above routine
- */
-pgprot_t pci_phys_mem_access_prot(struct file *file,
-				  unsigned long pfn,
-				  unsigned long size,
-				  pgprot_t protection)
-{
-	struct pci_dev *pdev = NULL;
-	struct resource *found = NULL;
-	unsigned long prot = pgprot_val(protection);
-	unsigned long offset = pfn << PAGE_SHIFT;
-	int i;
-
-	if (page_is_ram(pfn))
-		return __pgprot(prot);
-
-	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-
-	for_each_pci_dev(pdev) {
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *rp = &pdev->resource[i];
-			int flags = rp->flags;
-
-			/* Active and same type? */
-			if ((flags & IORESOURCE_MEM) == 0)
-				continue;
-			/* In the range of this resource? */
-			if (offset < (rp->start & PAGE_MASK) ||
-			    offset > rp->end)
-				continue;
-			found = rp;
-			break;
-		}
-		if (found)
-			break;
-	}
-	if (found) {
-		if (found->flags & IORESOURCE_PREFETCH)
-			prot &= ~_PAGE_GUARDED;
-		pci_dev_put(pdev);
-	}
-
-	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
-
-	return __pgprot(prot);
-}
-
-
-/*
- * Perform the actual remap of the pages for a PCI device mapping, as
- * appropriate for this architecture.  The region in the process to map
- * is described by vm_start and vm_end members of VMA, the base physical
- * address is found in vm_pgoff.
- * The pci device structure is provided so that architectures may make mapping
- * decisions on a per-device or per-bus basis.
- *
- * Returns a negative error code on failure, zero on success.
- */
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-			enum pci_mmap_state mmap_state,
-			int write_combine)
-{
-	resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
-	struct resource *rp;
-	int ret;
-
-	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
-	if (rp == NULL)
-		return -EINVAL;
-
-	vma->vm_pgoff = offset >> PAGE_SHIFT;
-	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
-						  vma->vm_page_prot,
-						  mmap_state, write_combine);
-
-	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
-
-	return ret;
-}
-
 /* Provide information on locations of various I/O regions in physical
  * memory.  Do this on a per-card basis so that we choose the right
  * root bridge.
@@ -1715,45 +1460,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
 	return result;
 }
 
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
-			  const struct resource *rsrc,
-			  resource_size_t *start, resource_size_t *end)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	resource_size_t offset = 0;
-
-	if (hose == NULL)
-		return;
-
-	if (rsrc->flags & IORESOURCE_IO)
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-
-	/* We pass a fully fixed up address to userland for MMIO instead of
-	 * a BAR value because X is lame and expects to be able to use that
-	 * to pass to /dev/mem !
-	 *
-	 * That means that we'll have potentially 64 bits values where some
-	 * userland apps only expect 32 (like X itself since it thinks only
-	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
-	 * 32 bits CHRPs :-(
-	 *
-	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
-	 * has been fixed (and the fix spread enough), we can re-enable the
-	 * 2 lines below and pass down a BAR value to userland. In that case
-	 * we'll also have to re-enable the matching code in
-	 * __pci_mmap_make_offset().
-	 *
-	 * BenH.
-	 */
-#if 0
-	else if (rsrc->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-#endif
-
-	*start = rsrc->start - offset;
-	*end = rsrc->end - offset;
-}
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 	struct pci_controller* hose = hose_head;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 23494fe..7a9a4fc 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -601,11 +601,6 @@ static int __init pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-char __init *pcibios_setup(char *str)
-{
-	return str;
-}
-
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	u16 cmd, oldcmd;
@@ -647,211 +642,6 @@ int pci_proc_domain(struct pci_bus *bus)
 	}
 }
 
-/*
- * Platform support for /proc/bus/pci/X/Y mmap()s,
- * modelled on the sparc64 implementation by Dave Miller.
- *  -- paulus.
- */
-
-/*
- * Adjust vm_pgoff of VMA such that it is the physical page offset
- * corresponding to the 32-bit pci bus offset for DEV requested by the user.
- *
- * Basically, the user finds the base address for his device which he wishes
- * to mmap.  They read the 32-bit value from the config space base register,
- * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
- * offset parameter of mmap on /proc/bus/pci/XXX for that device.
- *
- * Returns negative error code on failure, zero on success.
- */
-static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
-					       resource_size_t *offset,
-					       enum pci_mmap_state mmap_state)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	unsigned long io_offset = 0;
-	int i, res_bit;
-
-	if (hose == 0)
-		return NULL;		/* should never happen */
-
-	/* If memory, add on the PCI bridge address offset */
-	if (mmap_state == pci_mmap_mem) {
-#if 0 /* See comment in pci_resource_to_user() for why this is disabled */
-		*offset += hose->pci_mem_offset;
-#endif
-		res_bit = IORESOURCE_MEM;
-	} else {
-		io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-		*offset += io_offset;
-		res_bit = IORESOURCE_IO;
-	}
-
-	/*
-	 * Check that the offset requested corresponds to one of the
-	 * resources of the device.
-	 */
-	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-		struct resource *rp = &dev->resource[i];
-		int flags = rp->flags;
-
-		/* treat ROM as memory (should be already) */
-		if (i == PCI_ROM_RESOURCE)
-			flags |= IORESOURCE_MEM;
-
-		/* Active and same type? */
-		if ((flags & res_bit) == 0)
-			continue;
-
-		/* In the range of this resource? */
-		if (*offset < (rp->start & PAGE_MASK) || *offset > rp->end)
-			continue;
-
-		/* found it! construct the final physical address */
-		if (mmap_state == pci_mmap_io)
-		       	*offset += hose->io_base_phys - io_offset;
-		return rp;
-	}
-
-	return NULL;
-}
-
-/*
- * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
- * device mapping.
- */
-static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp,
-				      pgprot_t protection,
-				      enum pci_mmap_state mmap_state,
-				      int write_combine)
-{
-	unsigned long prot = pgprot_val(protection);
-
-	/* Write combine is always 0 on non-memory space mappings. On
-	 * memory space, if the user didn't pass 1, we check for a
-	 * "prefetchable" resource. This is a bit hackish, but we use
-	 * this to workaround the inability of /sysfs to provide a write
-	 * combine bit
-	 */
-	if (mmap_state != pci_mmap_mem)
-		write_combine = 0;
-	else if (write_combine == 0) {
-		if (rp->flags & IORESOURCE_PREFETCH)
-			write_combine = 1;
-	}
-
-	/* XXX would be nice to have a way to ask for write-through */
-	prot |= _PAGE_NO_CACHE;
-	if (write_combine)
-		prot &= ~_PAGE_GUARDED;
-	else
-		prot |= _PAGE_GUARDED;
-
-	return __pgprot(prot);
-}
-
-/*
- * This one is used by /dev/mem and fbdev who have no clue about the
- * PCI device, it tries to find the PCI device first and calls the
- * above routine
- */
-pgprot_t pci_phys_mem_access_prot(struct file *file,
-				  unsigned long pfn,
-				  unsigned long size,
-				  pgprot_t protection)
-{
-	struct pci_dev *pdev = NULL;
-	struct resource *found = NULL;
-	unsigned long prot = pgprot_val(protection);
-	unsigned long offset = pfn << PAGE_SHIFT;
-	int i;
-
-	if (page_is_ram(pfn))
-		return __pgprot(prot);
-
-	prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
-
-	for_each_pci_dev(pdev) {
-		for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
-			struct resource *rp = &pdev->resource[i];
-			int flags = rp->flags;
-
-			/* Active and same type? */
-			if ((flags & IORESOURCE_MEM) == 0)
-				continue;
-			/* In the range of this resource? */
-			if (offset < (rp->start & PAGE_MASK) ||
-			    offset > rp->end)
-				continue;
-			found = rp;
-			break;
-		}
-		if (found)
-			break;
-	}
-	if (found) {
-		if (found->flags & IORESOURCE_PREFETCH)
-			prot &= ~_PAGE_GUARDED;
-		pci_dev_put(pdev);
-	}
-
-	DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
-
-	return __pgprot(prot);
-}
-
-
-/*
- * Perform the actual remap of the pages for a PCI device mapping, as
- * appropriate for this architecture.  The region in the process to map
- * is described by vm_start and vm_end members of VMA, the base physical
- * address is found in vm_pgoff.
- * The pci device structure is provided so that architectures may make mapping
- * decisions on a per-device or per-bus basis.
- *
- * Returns a negative error code on failure, zero on success.
- */
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
-			enum pci_mmap_state mmap_state, int write_combine)
-{
-	resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT;
-	struct resource *rp;
-	int ret;
-
-	rp = __pci_mmap_make_offset(dev, &offset, mmap_state);
-	if (rp == NULL)
-		return -EINVAL;
-
-	vma->vm_pgoff = offset >> PAGE_SHIFT;
-	vma->vm_page_prot = __pci_mmap_set_pgprot(dev, rp,
-						  vma->vm_page_prot,
-						  mmap_state, write_combine);
-
-	ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
-			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
-
-	return ret;
-}
-
-static ssize_t pci_show_devspec(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct pci_dev *pdev;
-	struct device_node *np;
-
-	pdev = to_pci_dev (dev);
-	np = pci_device_to_OF_node(pdev);
-	if (np == NULL || np->full_name == NULL)
-		return 0;
-	return sprintf(buf, "%s", np->full_name);
-}
-static DEVICE_ATTR(devspec, S_IRUGO, pci_show_devspec, NULL);
-
-void pcibios_add_platform_entries(struct pci_dev *pdev)
-{
-	device_create_file(&pdev->dev, &dev_attr_devspec);
-}
-
 void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
 					    struct device_node *dev, int prim)
 {
@@ -1167,105 +957,6 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pcibios_fixup_bus);
 
-/*
- * Reads the interrupt pin to determine if interrupt is use by card.
- * If the interrupt is used, then gets the interrupt line from the 
- * openfirmware and sets it in the pci_dev and pci_config line.
- */
-int pci_read_irq_line(struct pci_dev *pci_dev)
-{
-	struct of_irq oirq;
-	unsigned int virq;
-
-	DBG("Try to map irq for %s...\n", pci_name(pci_dev));
-
-#ifdef DEBUG
-	memset(&oirq, 0xff, sizeof(oirq));
-#endif
-	/* Try to get a mapping from the device-tree */
-	if (of_irq_map_pci(pci_dev, &oirq)) {
-		u8 line, pin;
-
-		/* If that fails, lets fallback to what is in the config
-		 * space and map that through the default controller. We
-		 * also set the type to level low since that's what PCI
-		 * interrupts are. If your platform does differently, then
-		 * either provide a proper interrupt tree or don't use this
-		 * function.
-		 */
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_PIN, &pin))
-			return -1;
-		if (pin == 0)
-			return -1;
-		if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
-		    line == 0xff) {
-			return -1;
-		}
-		DBG(" -> no map ! Using irq line %d from PCI config\n", line);
-
-		virq = irq_create_mapping(NULL, line);
-		if (virq != NO_IRQ)
-			set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
-	} else {
-		DBG(" -> got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
-		    oirq.size, oirq.specifier[0], oirq.specifier[1],
-		    oirq.controller->full_name);
-
-		virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
-					     oirq.size);
-	}
-	if(virq == NO_IRQ) {
-		DBG(" -> failed to map !\n");
-		return -1;
-	}
-
-	DBG(" -> mapped to linux irq %d\n", virq);
-
-	pci_dev->irq = virq;
-
-	return 0;
-}
-EXPORT_SYMBOL(pci_read_irq_line);
-
-void pci_resource_to_user(const struct pci_dev *dev, int bar,
-			  const struct resource *rsrc,
-			  resource_size_t *start, resource_size_t *end)
-{
-	struct pci_controller *hose = pci_bus_to_host(dev->bus);
-	resource_size_t offset = 0;
-
-	if (hose == NULL)
-		return;
-
-	if (rsrc->flags & IORESOURCE_IO)
-		offset = (unsigned long)hose->io_base_virt - _IO_BASE;
-
-	/* We pass a fully fixed up address to userland for MMIO instead of
-	 * a BAR value because X is lame and expects to be able to use that
-	 * to pass to /dev/mem !
-	 *
-	 * That means that we'll have potentially 64 bits values where some
-	 * userland apps only expect 32 (like X itself since it thinks only
-	 * Sparc has 64 bits MMIO) but if we don't do that, we break it on
-	 * 32 bits CHRPs :-(
-	 *
-	 * Hopefully, the sysfs insterface is immune to that gunk. Once X
-	 * has been fixed (and the fix spread enough), we can re-enable the
-	 * 2 lines below and pass down a BAR value to userland. In that case
-	 * we'll also have to re-enable the matching code in
-	 * __pci_mmap_make_offset().
-	 *
-	 * BenH.
-	 */
-#if 0
-	else if (rsrc->flags & IORESOURCE_MEM)
-		offset = hose->pci_mem_offset;
-#endif
-
-	*start = rsrc->start - offset;
-	*end = rsrc->end - offset;
-}
-
 struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
 {
 	if (!have_of)
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 6/8] [POWERPC] Move pci_bus_to_hose users to pci_bus_to_host
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683691025-git-send-email-galak@kernel.crashing.org>

In the places we can move to using pci_bus_to_host, this allows us
to make pci_bus_to_host static and remove its export.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/kernel/pci_32.c      |    8 ++++----
 arch/powerpc/kernel/ppc_ksyms.c   |    1 -
 arch/powerpc/platforms/86xx/pci.c |    2 +-
 include/asm-powerpc/pci-bridge.h  |    3 ---
 4 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index df3251c..c81ffa2 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -766,7 +766,7 @@ static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
 
 	/* Are we a root bus ? */
 	if (bus->self == NULL || bus->parent == NULL) {
-		struct pci_controller *hose = pci_bus_to_hose(bus->number);
+		struct pci_controller *hose = pci_bus_to_host(bus);
 		if (hose == NULL)
 			return NULL;
 		return of_node_get(hose->arch_data);
@@ -1492,7 +1492,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-struct pci_controller*
+static struct pci_controller*
 pci_bus_to_hose(int bus)
 {
 	struct pci_controller* hose = hose_head;
@@ -1507,7 +1507,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
 					       resource_size_t *offset,
 					       enum pci_mmap_state mmap_state)
 {
-	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
 	unsigned long io_offset = 0;
 	int i, res_bit;
 
@@ -1719,7 +1719,7 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
 			  const struct resource *rsrc,
 			  resource_size_t *start, resource_size_t *end)
 {
-	struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
+	struct pci_controller *hose = pci_bus_to_host(dev->bus);
 	resource_size_t offset = 0;
 
 	if (hose == NULL)
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index c58f2de..e973c32 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -106,7 +106,6 @@ EXPORT_SYMBOL(isa_mem_base);
 EXPORT_SYMBOL(pci_dram_offset);
 EXPORT_SYMBOL(pci_alloc_consistent);
 EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_bus_to_hose);
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL(start_thread);
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 5cb2188..73cd5b0 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -145,7 +145,7 @@ static void __devinit quirk_fsl_pcie_transparent(struct pci_dev *dev)
 	 */
 	dev->transparent = 1;
 
-	hose = pci_bus_to_hose(dev->bus->number);
+	hose = pci_bus_to_host(dev->bus);
 	if (!hose) {
 		printk(KERN_ERR "Can't find hose for bus %d\n",
 		       dev->bus->number);
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index d5a9c9f..69ea865 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -9,9 +9,6 @@
 struct device_node;
 struct pci_controller;
 
-/* Get the PCI host controller for a bus */
-extern struct pci_controller* pci_bus_to_hose(int bus);
-
 /*
  * Structure of a PCI controller (host bridge)
  */
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 5/8] [POWERPC] Merge ppc32 and ppc64 pcibios_alloc_controller() prototypes
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683663762-git-send-email-galak@kernel.crashing.org>

Make the ppc32 pcibios_alloc_controller take a device node to match
the ppc64 prototypes and have it set arch_data.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/kernel/pci_32.c                     |    3 ++-
 arch/powerpc/platforms/52xx/efika.c              |    3 +--
 arch/powerpc/platforms/52xx/mpc52xx_pci.c        |    4 +---
 arch/powerpc/platforms/82xx/mpc82xx_ads.c        |    4 +---
 arch/powerpc/platforms/83xx/pci.c                |    3 +--
 arch/powerpc/platforms/85xx/pci.c                |    3 +--
 arch/powerpc/platforms/86xx/pci.c                |    4 ++--
 arch/powerpc/platforms/chrp/pci.c                |    3 +--
 arch/powerpc/platforms/embedded6xx/linkstation.c |    3 +--
 arch/powerpc/platforms/powermac/pci.c            |    6 ------
 arch/powerpc/sysdev/mv64x60_pci.c                |    4 +---
 arch/powerpc/sysdev/tsi108_pci.c                 |    3 +--
 include/asm-powerpc/pci-bridge.h                 |    8 +++-----
 13 files changed, 16 insertions(+), 35 deletions(-)

diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 56deb31..df3251c 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -610,7 +610,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask)
 static int next_controller_index;
 
 struct pci_controller * __init
-pcibios_alloc_controller(void)
+pcibios_alloc_controller(struct device_node *dev)
 {
 	struct pci_controller *hose;
 
@@ -621,6 +621,7 @@ pcibios_alloc_controller(void)
 	hose_tail = &hose->next;
 
 	hose->global_number = next_controller_index++;
+	hose->arch_data = dev;
 
 	return hose;
 }
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index 010be5c..0256423 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -128,7 +128,7 @@ void __init efika_pcisetup(void)
 	printk(" controlled by %s\n", pcictrl->full_name);
 	printk("\n");
 
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(of_node_get(pcictrl));
 	if (!hose) {
 		printk(KERN_WARNING EFIKA_PLATFORM_NAME
 		       ": Can't allocate PCI controller structure for %s\n",
@@ -136,7 +136,6 @@ void __init efika_pcisetup(void)
 		return;
 	}
 
-	hose->arch_data = of_node_get(pcictrl);
 	hose->first_busno = bus_range[0];
 	hose->last_busno = bus_range[1];
 	hose->ops = &rtas_pci_ops;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 69a0421..4c6c82a 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -385,12 +385,10 @@ mpc52xx_add_bridge(struct device_node *node)
 	 * tree are needed to configure the 52xx PCI controller.  Rather
 	 * than parse the tree here, let pci_process_bridge_OF_ranges()
 	 * do it for us and extract the values after the fact */
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(node);
 	if (!hose)
 		return -ENOMEM;
 
-	hose->arch_data = node;
-
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index d1e0919..da20832 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -543,13 +543,11 @@ static void __init mpc82xx_add_bridge(struct device_node *np)
 
 	pci_assign_all_buses = 1;
 
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(np);
 
 	if (!hose)
 		return;
 
-	hose->arch_data = np;
-
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index f49ed27..c0e2b89 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -62,10 +62,9 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
 	}
 
 	pci_assign_all_buses = 1;
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(dev);
 	if (!hose)
 		return -ENOMEM;
-	hose->arch_data = dev;
 
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index a25b3e7..8118417 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c
@@ -56,10 +56,9 @@ int __init mpc85xx_add_bridge(struct device_node *dev)
 	}
 
 	pci_assign_all_buses = 1;
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(dev);
 	if (!hose)
 		return -ENOMEM;
-	hose->arch_data = dev;
 
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c
index 2d7254c..5cb2188 100644
--- a/arch/powerpc/platforms/86xx/pci.c
+++ b/arch/powerpc/platforms/86xx/pci.c
@@ -196,10 +196,10 @@ int __init mpc86xx_add_bridge(struct device_node *dev)
 		       " bus 0\n", dev->full_name);
 
 	pci_assign_all_buses = 1;
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(dev);
 	if (!hose)
 		return -ENOMEM;
-	hose->arch_data = dev;
+
 	hose->indirect_type = PPC_INDIRECT_TYPE_EXT_REG |
 				PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS;
 
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d840863..3690624 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -254,13 +254,12 @@ chrp_find_bridges(void)
 			printk(" at %llx", (unsigned long long)r.start);
 		printk("\n");
 
-		hose = pcibios_alloc_controller();
+		hose = pcibios_alloc_controller(dev);
 		if (!hose) {
 			printk("Can't allocate PCI controller structure for %s\n",
 				dev->full_name);
 			continue;
 		}
-		hose->arch_data = dev;
 		hose->first_busno = bus_range[0];
 		hose->last_busno = bus_range[1];
 
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
index 885c789..f4d0a7a 100644
--- a/arch/powerpc/platforms/embedded6xx/linkstation.c
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -68,12 +68,11 @@ static int __init linkstation_add_bridge(struct device_node *dev)
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 				" bus 0\n", dev->full_name);
 
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(dev);
 	if (hose == NULL)
 		return -ENOMEM;
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
-	hose->arch_data = dev;
 	setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
 
 	/* Interpret the "ranges" property */
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index fb853c0..92586db 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -916,15 +916,9 @@ static int __init pmac_add_bridge(struct device_node *dev)
 		       " bus 0\n", dev->full_name);
 	}
 
-	/* XXX Different prototypes, to be merged */
-#ifdef CONFIG_PPC64
 	hose = pcibios_alloc_controller(dev);
-#else
-	hose = pcibios_alloc_controller();
-#endif
 	if (!hose)
 		return -ENOMEM;
-	hose->arch_data = dev;
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index 2e77384..45db86c 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -137,12 +137,10 @@ static int __init mv64x60_add_bridge(struct device_node *dev)
 		printk(KERN_WARNING "Can't get bus-range for %s, assume"
 		       " bus 0\n", dev->full_name);
 
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(dev);
 	if (!hose)
 		return -ENOMEM;
 
-	hose->arch_data = dev;
-
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
 
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 298e2dd..90db8a7 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -221,13 +221,12 @@ int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary)
 		       " bus 0\n", dev->full_name);
 	}
 
-	hose = pcibios_alloc_controller();
+	hose = pcibios_alloc_controller(dev);
 
 	if (!hose) {
 		printk("PCI Host bridge init failed\n");
 		return -ENOMEM;
 	}
-	hose->arch_data = dev;
 
 	hose->first_busno = bus_range ? bus_range[0] : 0;
 	hose->last_busno = bus_range ? bus_range[1] : 0xff;
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 80cfb4a..d5a9c9f 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -9,9 +9,6 @@
 struct device_node;
 struct pci_controller;
 
-/* Allocate a new PCI host bridge structure */
-extern struct pci_controller* pcibios_alloc_controller(void);
-
 /* Get the PCI host controller for a bus */
 extern struct pci_controller* pci_bus_to_hose(int bus);
 
@@ -232,8 +229,6 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
 	return PCI_DN(busdn)->phb;
 }
 
-extern struct pci_controller *
-pcibios_alloc_controller(struct device_node *dev);
 extern void pcibios_free_controller(struct pci_controller *phb);
 
 extern void isa_bridge_find_early(struct pci_controller *hose);
@@ -263,6 +258,9 @@ extern void
 pci_process_bridge_OF_ranges(struct pci_controller *hose,
 			   struct device_node *dev, int primary);
 
+/* Allocate a new PCI host bridge structure */
+extern struct pci_controller *
+pcibios_alloc_controller(struct device_node *dev);
 #ifdef CONFIG_PCI
 extern unsigned long pci_address_to_pio(phys_addr_t address);
 #else
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 4/8] [POWERPC] Use global_number in ppc32 pci_controller
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683631074-git-send-email-galak@kernel.crashing.org>

Make the pci_controller struct use global_number for the PHB domain number
instead of index to match what ppc64 does and reuse its pci_domain_nr code.

Introduced a pci-common.c to handle shared code between ppc32 & ppc64.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/kernel/Makefile        |    2 +-
 arch/powerpc/kernel/pci-common.c    |   53 +++++++++++++++++++++++++++++++++++
 arch/powerpc/kernel/pci_32.c        |    6 ++--
 arch/powerpc/kernel/pci_64.c        |   16 ----------
 arch/powerpc/platforms/52xx/efika.c |    4 +-
 arch/powerpc/platforms/chrp/pci.c   |    4 +-
 include/asm-powerpc/pci-bridge.h    |    2 +-
 include/asm-powerpc/pci.h           |    7 +---
 8 files changed, 64 insertions(+), 30 deletions(-)
 create mode 100644 arch/powerpc/kernel/pci-common.c

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index eb6a33e..42c42ec 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -68,7 +68,7 @@ obj-$(CONFIG_MODULES)		+= $(module-y)
 
 pci64-$(CONFIG_PPC64)		+= pci_64.o pci_dn.o isa-bridge.o
 pci32-$(CONFIG_PPC32)		:= pci_32.o
-obj-$(CONFIG_PCI)		+= $(pci64-y) $(pci32-y)
+obj-$(CONFIG_PCI)		+= $(pci64-y) $(pci32-y) pci-common.o
 obj-$(CONFIG_PCI_MSI)		+= msi.o
 kexec-$(CONFIG_PPC64)		:= machine_kexec_64.o
 kexec-$(CONFIG_PPC32)		:= machine_kexec_32.o
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
new file mode 100644
index 0000000..3ca8cfb
--- /dev/null
+++ b/arch/powerpc/kernel/pci-common.c
@@ -0,0 +1,53 @@
+/*
+ * Contains common pci routines for ALL ppc platform
+ *
+ * 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.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/list.h>
+#include <linux/syscalls.h>
+#include <linux/irq.h>
+#include <linux/vmalloc.h>
+
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/byteorder.h>
+#include <asm/machdep.h>
+#include <asm/ppc-pci.h>
+#include <asm/firmware.h>
+
+#ifdef DEBUG
+#include <asm/udbg.h>
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * Return the domain number for this bus.
+ */
+int pci_domain_nr(struct pci_bus *bus)
+{
+	if (firmware_has_feature(FW_FEATURE_ISERIES))
+		return 0;
+	else {
+		struct pci_controller *hose = pci_bus_to_host(bus);
+
+		return hose->global_number;
+	}
+}
+
+EXPORT_SYMBOL(pci_domain_nr);
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 2d4a1c4..56deb31 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -620,7 +620,7 @@ pcibios_alloc_controller(void)
 	*hose_tail = hose;
 	hose_tail = &hose->next;
 
-	hose->index = next_controller_index++;
+	hose->global_number = next_controller_index++;
 
 	return hose;
 }
@@ -1336,7 +1336,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 		if (!res->flags) {
 			if (io_offset)
 				printk(KERN_ERR "I/O resource not set for host"
-				       " bridge %d\n", hose->index);
+				       " bridge %d\n", hose->global_number);
 			res->start = 0;
 			res->end = IO_SPACE_LIMIT;
 			res->flags = IORESOURCE_IO;
@@ -1350,7 +1350,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
 				if (i > 0)
 					continue;
 				printk(KERN_ERR "Memory resource not set for "
-				       "host bridge %d\n", hose->index);
+				       "host bridge %d\n", hose->global_number);
 				res->start = hose->pci_mem_offset;
 				res->end = ~0U;
 				res->flags = IORESOURCE_MEM;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 6ae67eb..23494fe 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -636,22 +636,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
 	return 0;
 }
 
-/*
- * Return the domain number for this bus.
- */
-int pci_domain_nr(struct pci_bus *bus)
-{
-	if (firmware_has_feature(FW_FEATURE_ISERIES))
-		return 0;
-	else {
-		struct pci_controller *hose = pci_bus_to_host(bus);
-
-		return hose->global_number;
-	}
-}
-
-EXPORT_SYMBOL(pci_domain_nr);
-
 /* Decide whether to display the domain number in /proc */
 int pci_proc_domain(struct pci_bus *bus)
 {
diff --git a/arch/powerpc/platforms/52xx/efika.c b/arch/powerpc/platforms/52xx/efika.c
index 4cb4419..010be5c 100644
--- a/arch/powerpc/platforms/52xx/efika.c
+++ b/arch/powerpc/platforms/52xx/efika.c
@@ -54,7 +54,7 @@ static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 	struct pci_controller *hose = bus->sysdata;
 	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
 	    | (((bus->number - hose->first_busno) & 0xff) << 16)
-	    | (hose->index << 24);
+	    | (hose->global_number << 24);
 	int ret = -1;
 	int rval;
 
@@ -69,7 +69,7 @@ static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
 	struct pci_controller *hose = bus->sysdata;
 	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
 	    | (((bus->number - hose->first_busno) & 0xff) << 16)
-	    | (hose->index << 24);
+	    | (hose->global_number << 24);
 	int rval;
 
 	rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index d32fedc..d840863 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -99,7 +99,7 @@ int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 	struct pci_controller *hose = bus->sysdata;
 	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
 		| (((bus->number - hose->first_busno) & 0xff) << 16)
-		| (hose->index << 24);
+		| (hose->global_number << 24);
         int ret = -1;
 	int rval;
 
@@ -114,7 +114,7 @@ int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
 	struct pci_controller *hose = bus->sysdata;
 	unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
 		| (((bus->number - hose->first_busno) & 0xff) << 16)
-		| (hose->index << 24);
+		| (hose->global_number << 24);
 	int rval;
 
 	rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index e2b2b6b..80cfb4a 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -21,7 +21,6 @@ extern struct pci_controller* pci_bus_to_hose(int bus);
 struct pci_controller {
 	struct pci_bus *bus;
 	void *arch_data;
-	int index;			/* PCI domain number */
 	struct pci_controller *next;
 	struct device *parent;
 
@@ -60,6 +59,7 @@ struct pci_controller {
 	 */
 	struct resource	io_resource;
 	struct resource mem_resources[3];
+	int global_number;		/* PCI domain number */
 };
 
 static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h
index 93e3752..0cd3e77 100644
--- a/include/asm-powerpc/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -107,8 +107,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
 #define get_pci_dma_ops()	NULL
 #endif
 
-extern int pci_domain_nr(struct pci_bus *bus);
-
 /* Decide whether to display the domain number in /proc */
 extern int pci_proc_domain(struct pci_bus *bus);
 
@@ -130,9 +128,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
  */
 #define pci_dac_dma_supported(pci_dev, mask)	(0)
 
-/* Return the index of the PCI controller for device PDEV. */
-#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
-
 /* Set the name of the bus as it appears in /proc/bus/pci */
 static inline int pci_proc_domain(struct pci_bus *bus)
 {
@@ -141,6 +136,8 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 
 #endif /* CONFIG_PPC64 */
 
+extern int pci_domain_nr(struct pci_bus *bus);
+
 struct vm_area_struct;
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 3/8] [POWERPC] Removed dead code related to PCI on ppc32
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683612573-git-send-email-galak@kernel.crashing.org>

There are no in kernel users of any off these functions and some of
them were not even EXPORT_SYMBOL:

- pci_bus_io_base()
- pci_bus_io_base_phys()
- pci_bus_mem_base_phys()
- pci_resource_to_bus()
- phys_to_bus()
- pci_phys_to_bus()
- pci_bus_to_phys()
- pci_init_resource()
- resource_fixup()

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/kernel/pci_32.c     |  112 --------------------------------------
 arch/powerpc/kernel/ppc_ksyms.c  |    3 -
 include/asm-powerpc/pci-bridge.h |   12 ----
 3 files changed, 0 insertions(+), 127 deletions(-)

diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 7738a28..2d4a1c4 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -1319,12 +1319,6 @@ pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
-			     unsigned long start, unsigned long size)
-{
-	return start;
-}
-
 void __init pcibios_fixup_bus(struct pci_bus *bus)
 {
 	struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
@@ -1508,53 +1502,6 @@ pci_bus_to_hose(int bus)
 	return NULL;
 }
 
-void __iomem *
-pci_bus_io_base(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return NULL;
-	return hose->io_base_virt;
-}
-
-unsigned long
-pci_bus_io_base_phys(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return 0;
-	return hose->io_base_phys;
-}
-
-unsigned long
-pci_bus_mem_base_phys(unsigned int bus)
-{
-	struct pci_controller *hose;
-
-	hose = pci_bus_to_hose(bus);
-	if (!hose)
-		return 0;
-	return hose->pci_mem_offset;
-}
-
-unsigned long
-pci_resource_to_bus(struct pci_dev *pdev, struct resource *res)
-{
-	/* Hack alert again ! See comments in chrp_pci.c
-	 */
-	struct pci_controller* hose =
-		(struct pci_controller *)pdev->sysdata;
-	if (hose && res->flags & IORESOURCE_MEM)
-		return res->start - hose->pci_mem_offset;
-	/* We may want to do something with IOs here... */
-	return res->start;
-}
-
-
 static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
 					       resource_size_t *offset,
 					       enum pci_mmap_state mmap_state)
@@ -1725,53 +1672,6 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 	return ret;
 }
 
-/* Obsolete functions. Should be removed once the symbios driver
- * is fixed
- */
-unsigned long
-phys_to_bus(unsigned long pa)
-{
-	struct pci_controller *hose;
-	int i;
-
-	for (hose = hose_head; hose; hose = hose->next) {
-		for (i = 0; i < 3; ++i) {
-			if (pa >= hose->mem_resources[i].start
-			    && pa <= hose->mem_resources[i].end) {
-				/*
-				 * XXX the hose->pci_mem_offset really
-				 * only applies to mem_resources[0].
-				 * We need a way to store an offset for
-				 * the others.  -- paulus
-				 */
-				if (i == 0)
-					pa -= hose->pci_mem_offset;
-				return pa;
-			}
-		}
-	}
-	/* hmmm, didn't find it */
-	return 0;
-}
-
-unsigned long
-pci_phys_to_bus(unsigned long pa, int busnr)
-{
-	struct pci_controller* hose = pci_bus_to_hose(busnr);
-	if (!hose)
-		return pa;
-	return pa - hose->pci_mem_offset;
-}
-
-unsigned long
-pci_bus_to_phys(unsigned int ba, int busnr)
-{
-	struct pci_controller* hose = pci_bus_to_hose(busnr);
-	if (!hose)
-		return ba;
-	return ba + hose->pci_mem_offset;
-}
-
 /* Provide information on locations of various I/O regions in physical
  * memory.  Do this on a per-card basis so that we choose the right
  * root bridge.
@@ -1853,18 +1753,6 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
 	*end = rsrc->end - offset;
 }
 
-void __init pci_init_resource(struct resource *res, resource_size_t start,
-			      resource_size_t end, int flags, char *name)
-{
-	res->start = start;
-	res->end = end;
-	res->flags = flags;
-	res->name = name;
-	res->parent = NULL;
-	res->sibling = NULL;
-	res->child = NULL;
-}
-
 unsigned long pci_address_to_pio(phys_addr_t address)
 {
 	struct pci_controller* hose = hose_head;
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index c96fa9b..c58f2de 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -106,9 +106,6 @@ EXPORT_SYMBOL(isa_mem_base);
 EXPORT_SYMBOL(pci_dram_offset);
 EXPORT_SYMBOL(pci_alloc_consistent);
 EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_bus_io_base);
-EXPORT_SYMBOL(pci_bus_io_base_phys);
-EXPORT_SYMBOL(pci_bus_mem_base_phys);
 EXPORT_SYMBOL(pci_bus_to_hose);
 #endif /* CONFIG_PCI */
 
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 229ead9..e2b2b6b 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -9,21 +9,9 @@
 struct device_node;
 struct pci_controller;
 
-/*
- * pci_io_base returns the memory address at which you can access
- * the I/O space for PCI bus number `bus' (or NULL on error).
- */
-extern void __iomem *pci_bus_io_base(unsigned int bus);
-extern unsigned long pci_bus_io_base_phys(unsigned int bus);
-extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
-
 /* Allocate a new PCI host bridge structure */
 extern struct pci_controller* pcibios_alloc_controller(void);
 
-/* Helper function for setting up resources */
-extern void pci_init_resource(struct resource *res, resource_size_t start,
-			      resource_size_t end, int flags, char *name);
-
 /* Get the PCI host controller for a bus */
 extern struct pci_controller* pci_bus_to_hose(int bus);
 
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 2/8] [POWERPC] Remove local_number from pci_controller
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683604166-git-send-email-galak@kernel.crashing.org>

We never actually read local_number so lets just remove it.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/platforms/iseries/pci.c |    2 +-
 include/asm-powerpc/pci-bridge.h     |    1 -
 2 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 23d8762..da87162 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -768,7 +768,7 @@ void __init iSeries_pcibios_init(void)
 		if (phb == NULL)
 			continue;
 
-		phb->pci_mem_offset = phb->local_number = bus;
+		phb->pci_mem_offset = bus;
 		phb->first_busno = bus;
 		phb->last_busno = bus;
 		phb->ops = &iSeries_pci_ops;
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index b032593..229ead9 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -146,7 +146,6 @@ struct pci_controller {
 	struct resource io_resource;
 	struct resource mem_resources[3];
 	int global_number;
-	int local_number;
 	unsigned long buid;
 	unsigned long dma_window_base_cur;
 	unsigned long dma_window_size;
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 1/8] [POWERPC] Merge asm-ppc/pci-bridge.h into asm-power/pci-bridge.h
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <11829683583721-git-send-email-galak@kernel.crashing.org>

Moved bits need for ppc32 from asm-ppc/pci-bridge.h into
asm-powerpc/pci-bridge.h.

Removed ARCH=powerpc specific bits (and comments related to ARCH=ppc)
from asm-ppc/pci-bridge.h as its only used on ARCH=ppc.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 include/asm-powerpc/pci-bridge.h |  138 +++++++++++++++++++++++++++++++++-----
 include/asm-ppc/pci-bridge.h     |   17 -----
 2 files changed, 120 insertions(+), 35 deletions(-)

diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 5261527..b032593 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -3,7 +3,103 @@
 #ifdef __KERNEL__
 
 #ifndef CONFIG_PPC64
-#include <asm-ppc/pci-bridge.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+struct device_node;
+struct pci_controller;
+
+/*
+ * pci_io_base returns the memory address at which you can access
+ * the I/O space for PCI bus number `bus' (or NULL on error).
+ */
+extern void __iomem *pci_bus_io_base(unsigned int bus);
+extern unsigned long pci_bus_io_base_phys(unsigned int bus);
+extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
+
+/* Allocate a new PCI host bridge structure */
+extern struct pci_controller* pcibios_alloc_controller(void);
+
+/* Helper function for setting up resources */
+extern void pci_init_resource(struct resource *res, resource_size_t start,
+			      resource_size_t end, int flags, char *name);
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller* pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+	struct pci_bus *bus;
+	void *arch_data;
+	int index;			/* PCI domain number */
+	struct pci_controller *next;
+	struct device *parent;
+
+	int first_busno;
+	int last_busno;
+	int self_busno;
+
+	void __iomem *io_base_virt;
+	resource_size_t io_base_phys;
+
+	/* Some machines (PReP) have a non 1:1 mapping of
+	 * the PCI memory space in the CPU bus space
+	 */
+	resource_size_t pci_mem_offset;
+
+	struct pci_ops *ops;
+	volatile unsigned int __iomem *cfg_addr;
+	volatile void __iomem *cfg_data;
+
+	/*
+	 * Used for variants of PCI indirect handling and possible quirks:
+	 *  SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
+	 *  EXT_REG - provides access to PCI-e extended registers
+	 *  SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS
+	 *   on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
+	 *   to determine which bus number to match on when generating type0
+	 *   config cycles
+	 */
+#define PPC_INDIRECT_TYPE_SET_CFG_TYPE		(0x00000001)
+#define PPC_INDIRECT_TYPE_EXT_REG		(0x00000002)
+#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS	(0x00000004)
+	u32 indirect_type;
+
+	/* Currently, we limit ourselves to 1 IO range and 3 mem
+	 * ranges since the common pci_bus structure can't handle more
+	 */
+	struct resource	io_resource;
+	struct resource mem_resources[3];
+};
+
+static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
+{
+	return bus->sysdata;
+}
+
+/* These are used for config access before all the PCI probing
+   has been done. */
+int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+			   int where, u8 *val);
+int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn,
+			   int where, u16 *val);
+int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn,
+			    int where, u32 *val);
+int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn,
+			    int where, u8 val);
+int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn,
+			    int where, u16 val);
+int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn,
+			     int where, u32 val);
+
+extern void setup_indirect_pci_nomap(struct pci_controller* hose,
+			       void __iomem *cfg_addr, void __iomem *cfg_data);
+extern void setup_indirect_pci(struct pci_controller* hose,
+			       u32 cfg_addr, u32 cfg_data);
+extern void setup_grackle(struct pci_controller *hose);
+
 #else
 
 #include <linux/pci.h>
@@ -49,8 +145,8 @@ struct pci_controller {
 	 */
 	struct resource io_resource;
 	struct resource mem_resources[3];
-	int global_number;		
-	int local_number;		
+	int global_number;
+	int local_number;
 	unsigned long buid;
 	unsigned long dma_window_base_cur;
 	unsigned long dma_window_size;
@@ -132,9 +228,6 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
 /** Find the bus corresponding to the indicated device node */
 struct pci_bus * pcibios_find_pci_bus(struct device_node *dn);
 
-extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
-					 struct device_node *dev, int primary);
-
 /** Remove all of the PCI devices under this bus */
 void pcibios_remove_pci_devices(struct pci_bus *bus);
 
@@ -152,22 +245,10 @@ static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
 	return PCI_DN(busdn)->phb;
 }
 
-extern struct pci_controller*
-pci_find_hose_for_OF_device(struct device_node* node);
-
 extern struct pci_controller *
 pcibios_alloc_controller(struct device_node *dev);
 extern void pcibios_free_controller(struct pci_controller *phb);
 
-#ifdef CONFIG_PCI
-extern unsigned long pci_address_to_pio(phys_addr_t address);
-#else
-static inline unsigned long pci_address_to_pio(phys_addr_t address)
-{
-	return (unsigned long)-1;
-}
-#endif
-
 extern void isa_bridge_find_early(struct pci_controller *hose);
 
 extern int pcibios_unmap_io_space(struct pci_bus *bus);
@@ -185,5 +266,26 @@ extern int pcibios_map_io_space(struct pci_bus *bus);
 #endif
 
 #endif /* CONFIG_PPC64 */
+
+/* Get the PCI host controller for an OF device */
+extern struct pci_controller*
+pci_find_hose_for_OF_device(struct device_node* node);
+
+/* Fill up host controller resources from the OF node */
+extern void
+pci_process_bridge_OF_ranges(struct pci_controller *hose,
+			   struct device_node *dev, int primary);
+
+#ifdef CONFIG_PCI
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+	return (unsigned long)-1;
+}
+#endif
+
+
+
 #endif /* __KERNEL__ */
 #endif
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index c09fbf0..4d35b84 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -47,8 +47,6 @@ struct pci_controller {
 
 	int first_busno;
 	int last_busno;
-	int self_busno;
-	/* bus_offset is only used by ARCH=ppc */
 	int bus_offset;
 
 	void __iomem *io_base_virt;
@@ -65,24 +63,9 @@ struct pci_controller {
 	/*
 	 * If set, indirect method will set the cfg_type bit as
 	 * needed to generate type 1 configuration transactions.
-	 * use only on ARCH=ppc
 	 */
 	int set_cfg_type;
 
-	/*
-	 * Used for variants of PCI indirect handling and possible quirks:
-	 *  SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
-	 *  EXT_REG - provides access to PCI-e extended registers
-	 *  SURPRESS_PRIMARY_BUS - we surpress the setting of PCI_PRIMARY_BUS
-	 *   on Freescale PCI-e controllers since they used the PCI_PRIMARY_BUS
-	 *   to determine which bus number to match on when generating type0
-	 *   config cycles
-	 */
-#define PPC_INDIRECT_TYPE_SET_CFG_TYPE		(0x00000001)
-#define PPC_INDIRECT_TYPE_EXT_REG		(0x00000002)
-#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS	(0x00000004)
-	u32 indirect_type;
-
 	/* Currently, we limit ourselves to 1 IO range and 3 mem
 	 * ranges since the common pci_bus structure can't handle more
 	 */
-- 
1.5.2.1

^ permalink raw reply related

* [PATCH 0/8] [POWERPC] PCI merge of ppc32 & ppc64
From: Kumar Gala @ 2007-06-27 18:19 UTC (permalink / raw)
  To: linuxppc-dev

This is a set of patches queued for 2.6.23 that merge some of the common
bits of ppc32 & ppc64 PCI code.

Also available at:

master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc.git for_paulus

- k

^ permalink raw reply

* Porting Linux to Xilinx ML410
From: khollan @ 2007-06-27 16:40 UTC (permalink / raw)
  To: linuxppc-embedded


Hi Im trying to get linux 2.6 to run on my ML410 board from xilinx.  I just
created a real simple system with a Uartlite DDR2 and DDR interupt
controller and sysace.  I installed the patches I found for Uartlite and
sysace I found here.  I boot the zImage with XMD with the following
commands:
dow t:/zImage.elf
con
This is what I get out the serial port:
loaded at:     00400000 00537138
board data at: 00000000 00000018
relocated to:  00404064 0040407C
zimage at:     00404E6D 005345F1
avail ram:     00538000 7C7F1B78

Linux/PPC load: console=ttyUL0,9600 root=/dev/xsysace/disc0/part3 rw
Uncompressing Linux...done.
Now booting the kernel

It always stall on the Now booting the kernel.  Im new to linux building and
any help or suggestions are greatly appreciated.
Thanks
Kevin
-- 
View this message in context: http://www.nabble.com/Porting-Linux-to-Xilinx-ML410-tf3989483.html#a11328063
Sent from the linuxppc-embedded mailing list archive at Nabble.com.

^ permalink raw reply

* [PATCH] Schedule removal of arch/ppc
From: Josh Boyer @ 2007-06-27 13:49 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

The arch/ppc tree has been in a semi-nebulous "bug fix only" state for a
few kernel releases now.  The patch below officially declares this as of
the 2.6.22 kernel release and schedules arch/ppc for removal in June of
2008.

Signed-off-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-
index 7d3f205..170a32e 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -348,3 +348,15 @@ Who:  Tejun Heo <htejun@gmail.com>
 
 ---------------------------
 
+What: The arch/ppc and include/asm-ppc directories
+When: Jun 2008
+Why:  The arch/powerpc tree is the merged architecture for ppc32 and ppc64
+      platforms.  Currently there are efforts underway to port the remaining
+      arch/ppc platforms the the merged tree.  New submissions to the arch/ppc
+      tree have been frozen with the 2.6.22 kernel release and that tree will
+      remain in bug-fix only mode until it's scheduled removal.  Platforms
+      that are not ported by June 2008 will be removed due to the lack of an
+      interested maintainer.
+Who:  linuxppc-dev@ozlabs.org
+
+---------------------------

^ permalink raw reply related

* udbg_16550.c and legacy_serial.c
From: Milton Miller @ 2007-06-27 11:29 UTC (permalink / raw)
  To: Milton Miller; +Cc: ppcdev, David Gibson
In-Reply-To: <d8960a6c86859c19b84dc9fd41446fbd@bga.com>

On Jun 27, 2007, at 6:22 AM, Milton Miller wrote:
> (4) Adding a 5th udbg_putc method that calls a byte read to 
> udbg_comport->lsr masked with THRE until 0 and performs a byte write 
> to ->thr shows we have the wrong abstraction.   Please make the 
> inb/outb a method with the comport.  It would seem the actual init_xx 
> could be in the platforms, passing inb, outb, and comport to a helper 
> in udbg_16550.c.   I'm fine with declaring all the early inits in 
> udbg.h
>


I'll repost that with a different subject in case someone else wants to 
work on that.


Also, while researching this, I found that check_legacy_serial_console 
has a check for legacy_serial_console < 0 in it.  Since that is set to 
the legacy_ports array we pass to the serial layer, it would seem all 
the other parsing to find the console is redundant; we can get the np 
that we already found.   However, it also means that the code to notice 
the stdout path is ch-a or ch-b will never be executed because of that 
check.

The comment about stdout being a wierd phandle should read 
"/chosen/stdout is a ihandle.  use linux,stdout-path instead".

no patch at this hour.

milton

^ permalink raw reply

* Re: [PATCH 3/3] First cut at PReP support for arch/powerpc
From: Milton Miller @ 2007-06-27 11:22 UTC (permalink / raw)
  To: David Gibson; +Cc: ppcdev
In-Reply-To: <20070627071008.GA30648@localhost.localdomain>

On Wed Jun 27 17:10:08 EST 2007, David Gibson wrote:
> Here is an implementation to allow PReP systems to boot under the
> arch/powerpc codebase, one of the few remaining platforms supported in
> arch/ppc but not so far in arch/powerpc.
>
> This support is still fairly incomplete - it needs to obtain a lot
> more device information from the residual data and put it into the
> device tree, rather than relying on hardcoded values (both in the code
> and in prep.dts).  Likewise many peripherals will not be supported -
> in particular the RTC is not yet supported, so the time will generally
> be wrong.


Hi David.

A few things I noticed:

(1) Your cleaned up mkprep.c seems to always put on a floppy header, 
where as before that was optional with the -php flag.  Is that header 
right for a hard disk partition?  Or would that just have the 1-sector 
header?  The comments in the old mkprep impiled the raw elf contents 
are used for netboot.  What if the zImage does't fit on the 1.44MB disk 
given in the header?

(2) Uour wrapper rule can leave behind zImage.dts.prep.elf, but there 
is no clean rule for that

(3) Is this the right platform to create the device tree from scratch 
by traversing fw data?  A significiant number of the properties are to 
be filled in or say IBM, which is incorrect.

(4) Adding a 5th udbg_putc method that calls a byte read to 
udbg_comport->lsr masked with THRE until 0 and performs a byte write to 
->thr shows we have the wrong abstraction.   Please make the inb/outb a 
method with the comport.  It would seem the actual init_xx could be in 
the platforms, passing inb, outb, and comport to a helper in 
udbg_16550.c.   I'm fine with declaring all the early inits in udbg.h

(5) the printk PReP architecture is in the middle of prep_find_bridges?

(6) #if 0 prep_request_io will need platform check

(7) do you expect both the kernel and the boot code will continue to 
need residual.h?  If so, can we have the boot dir make a copy like the 
zlib headers?  Or is this only temporary, the kernel only needs a copy 
of the raw blob to export to userspace in the same spot and the 
include/asm-powerpc copy will go away?

milton

^ permalink raw reply

* Re: [PATCH v2] pcmcia: CompactFlash driver for PA Semi Electra boards
From: Milton Miller @ 2007-06-27 11:20 UTC (permalink / raw)
  To: Olof Johansson; +Cc: ppcdev, Christoph Hellwig
In-Reply-To: <20070625171221.GA6684@lixom.net>

> On Mon, Jun 25, 2007 at 08:39:09PM +0100, Christoph Hellwig wrote:
>> On Mon, Jun 25, 2007 at 12:12:21PM -0500, Olof Johansson wrote:
>>> Driver for the CompactFlash slot on the PA Semi Electra eval board. 
>>> It's
>>> a simple device sitting on localbus, with interrupts and 
>>> detect/voltage
>>> control over GPIO.
>>>
>>> The driver is implemented as an of_platform driver, and adds localbus
>>> as a bus being probed by the of_platform framework.
>>
>> Looks good to me. The only odd thing is the inconsistant use of
>> #ifdef CONFIG_PCMCIA in setup.c.
>
> The ifdef is needed since for CONFIG_PCMCIA=n builds, the bus notifier
> isn't available. I wanted to do the bus notifier registration 
> explicitly
> before the of_platform bus probe to avoid later surprises due to 
> reordered
> initcalls in case it was split up in it's own initcall.

If CONFIG_PCMCIA=m then your notifier is not registered.  The modprobe 
of your of_driver loads ds.ko, registers the bus, then registers your 
driver.  When the socket driver tries to dma, the BUG in dma_64 for no 
archdata.dma_ops triggers.

It seems like we need

(1) a notifier that a bus is registered, run before allowing any 
devices, so that platforms can register bus notifiers by bus name 
before the devices and drivers are registered.

(2) a powerpc64 generic pcmcia bus notifier that copys the dma ops from 
the parent socket.

(3) something to set the dma_ops to direct_dma_ops on the of device.

If we don't want (3) to be in the driver (as Christoph previosly 
mentioned), then it needs to be a seperate bus that reuses the of 
matching.  This would be similar to how ibmebus is setup.   If I 
remember the discussion, ibmebus is to provide the alternate dma ops 
and steals match etc code from the of_platform bus type.


Oh, is this why you have depends on PCMCIA=y ?


> I could add the code under ifdef as well, but it didn't seem too
> critical. Once the second major board comes along I'll probably move it
> out to a per-board file, there's no real need for it just yet.

milton

^ permalink raw reply

* Re: [PATCH] pcmcia: CompactFlash driver for PA Semi Electra boards
From: Milton Miller @ 2007-06-27 11:20 UTC (permalink / raw)
  To: Olof Johansson; +Cc: ppcdev
In-Reply-To: <20070625010311.GA31355@lixom.net>

Hi Olof.

On Mon Jun 25 11:03:11 EST 2007, Olof Johansson wrote:
> Driver for the CompactFlash slot on the PA Semi Electra eval board. 
> It's
> a simple device sitting on localbus, with interrupts and detect/voltage
> control over GPIO.
>
> The driver is implemented as an of_platform driver, and adds localbus
> as a bus being probed by the of_platform framework.

...
> +
> +static int __devinit electra_cf_probe(struct of_device *ofdev,
> +                                     const struct of_device_id *match)
> +{
> +       struct device *device = &ofdev->dev;
> +       struct device_node *np = ofdev->node;
> +       struct electra_cf_socket   *cf;
> +       struct resource mem, io;
> +       int status;
> +       const unsigned int *prop;
> +       int err;
> +
> +       err = of_address_to_resource(np, 0, &mem);
> +       if (err)
> +               return -EINVAL;
> +
> +       err = of_address_to_resource(np, 1, &io);
> +       if (err)
> +               return -EINVAL;
> +
> +       cf = kzalloc(sizeof *cf, GFP_KERNEL);
> +       if (!cf)
> +               return -ENOMEM;
> +
> +       init_timer(&cf->timer);
> +       cf->timer.function = electra_cf_timer;
> +       cf->timer.data = (unsigned long) cf;
> +
> +       cf->ofdev = ofdev;
> +       cf->mem_phys = mem.start;
> +       cf->mem_base = ioremap(mem.start, mem.end - mem.start);
> +       cf->io_size = PAGE_ALIGN(io.end - io.start);
> +
> +       cf->io_virt = reserve_phb_iospace(cf->io_size);
> +
> +       cf->gpio_base = ioremap(0xfc103000, 0x1000);
> +       dev_set_drvdata(device, cf);
> +
> +       if (!cf->mem_base || !cf->io_virt || !cf->gpio_base) {
> +               dev_err(device, "can't ioremap ranges\n");
> +               status = -ENOMEM;
> +               goto fail1;
> +       }
> +
> +       __ioremap_explicit(io.start, (unsigned long)cf->io_virt, 
> cf->io_size,
> +                          _PAGE_NO_CACHE | _PAGE_GUARDED);
> +
> +       cf->io_base = (unsigned long)cf->io_virt - VMALLOC_END;
> +
> +       cf->iomem.start = (unsigned long)cf->mem_base;
> +       cf->iomem.end = (unsigned long)cf->mem_base + (mem.end - 
> mem.start);
> +       cf->iomem.flags = IORESOURCE_MEM;
> +
> +       cf->irq = irq_of_parse_and_map(np, 0);
> +
> +       status = request_irq(cf->irq, electra_cf_irq, IRQF_SHARED,
> +                            driver_name, cf);
> +       if (status < 0) {
> +               dev_err(device, "request_irq failed\n");
> +               goto fail1;
> +       }
> +
> +       cf->socket.pci_irq = cf->irq;
> +
> +       prop = get_property(np, "card-detect-gpio", NULL);
> +       cf->gpio_detect = *prop;
> +       prop = get_property(np, "card-vsense-gpio", NULL);
> +       cf->gpio_vsense = *prop;
> +       prop = get_property(np, "card-3v-gpio", NULL);
> +       cf->gpio_3v = *prop;
> +       prop = get_property(np, "card-5v-gpio", NULL);
> +       cf->gpio_5v = *prop;
> +

get_property is now a #define for of_get_property.  I think the use of 
get_property is being deprecated.

If of_get_property fails to find the property, then you will 
dereference a NULL pointer in a probe function and will leave the 
bus_type locked.

> +       cf->socket.io_offset = cf->io_base;
> +
> +       /* reserve chip-select regions */
> +       if (!request_mem_region(mem.start, mem.end + 1 - mem.start,
> +                               driver_name)) {
> +               status = -ENXIO;
> +               dev_err(device, "Can't claim memory region\n");
> +               goto fail1;
> +       }
> +
> +       if (!request_region(cf->io_base, cf->io_size, driver_name)) {
> +               status = -ENXIO;
> +               dev_err(device, "Can't claim I/O region\n");
> +               goto fail2;
> +       }
> +
> +       cf->socket.owner = THIS_MODULE;
> +       cf->socket.dev.parent = &ofdev->dev;
> +       cf->socket.ops = &electra_cf_ops;
> +       cf->socket.resource_ops = &pccard_static_ops;
> +       cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP |
> +                               SS_CAP_MEM_ALIGN;
> +       cf->socket.map_size = 0x800;
> +
> +       status = pcmcia_register_socket(&cf->socket);
> +       if (status < 0) {
> +               dev_err(device, "pcmcia_register_socket failed\n");
> +               goto fail3;
> +       }
> +
> +       dev_info(device, "at mem 0x%lx io 0x%lx irq %d\n",
> +                mem.start, io.start, cf->irq);
> +
> +       cf->active = 1;
> +       electra_cf_timer((unsigned long)cf);
> +       return 0;
> +
> +fail3:
> +       release_mem_region(io.start, io.end + 1 - io.start);
> +fail2:
> +       release_mem_region(mem.start, mem.end + 1 - mem.start);
> +fail1:
> +       /* XXX No way to undo the io reservation at this time */

What io reservation is this comment referring to?


Where is the request_irq undone?

> +       if (cf->mem_base)
> +               iounmap(cf->mem_base);
> +       if (cf->gpio_base)
> +               iounmap(cf->gpio_base);
> +       device_init_wakeup(&ofdev->dev, 0);
> +       kfree(cf);
> +       return status;
> +
> +}
> +
> +static int __devexit electra_cf_remove(struct of_device *ofdev)
> +{
> +       struct device *device = &ofdev->dev;
> +       struct electra_cf_socket *cf;
> +
> +       cf = dev_get_drvdata(device);
> +
> +       cf->active = 0;
> +       pcmcia_unregister_socket(&cf->socket);
> +       free_irq(cf->irq, cf);
> +       del_timer_sync(&cf->timer);
> +
> +       iounmap(cf->mem_base);
> +       iounmap(cf->gpio_base);
> +       release_mem_region(cf->mem_phys, cf->mem_size);
> +       release_region(cf->io_base, cf->io_size);
> +
>

irq_request?

> +       kfree(cf);
> +
> +       return 0;
> +}
> +
> +static int bus_notify(struct notifier_block *nb, unsigned long action,
> +                     void *data)
> +{
> +       struct device *dev = data;
> +
> +       printk("bus notify called\n");
> +
> +       /* We are only intereted in device addition */
> +       if (action != BUS_NOTIFY_ADD_DEVICE)
> +               return 0;
> +
> +       /* We use the direct ops for localbus */
> +       dev->archdata.dma_ops = &dma_direct_ops;
> +

I'm also replying to your reply to hch's reply.  Is that enough of a 
reply? :-)

> +       return 0;
> +}
> +
> +static struct notifier_block bus_notifier = {
> +       .notifier_call = bus_notify,
> +};
> +
> +static struct of_device_id electra_cf_match[] =
> +{
> +       {
> +               .compatible   = "electra-cf",
> +       },
> +       {},
> +};
> +
> +static struct of_platform_driver electra_cf_driver =
> +{
> +       .name      = (char *)driver_name,
> +       .match_table    = electra_cf_match,
> +       .probe    = electra_cf_probe,
> +       .remove   = electra_cf_remove,
> +};
> +
> +static int __init electra_cf_init(void)
> +{
> +       bus_register_notifier(&pcmcia_bus_type, &bus_notifier);
> +       return of_register_platform_driver(&electra_cf_driver);
> +}
> +module_init(electra_cf_init);
> +
> +static void __exit electra_cf_exit(void)
> +{
> +       bus_unregister_notifier(&pcmcia_bus_type, &bus_notifier);
> +       of_unregister_platform_driver(&electra_cf_driver);

Should these be reversed?  (if we keep it here)

> +}
> +module_exit(electra_cf_exit);
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR ("Olof Johansson <olof at lixom.net>");
> +MODULE_DESCRIPTION("PA Semi Electra CF driver");
> +

cheers,
milton

^ permalink raw reply

* Re: powerpc stacktrace and lockdep support
From: Johannes Berg @ 2007-06-26 22:47 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linuxppc-dev
In-Reply-To: <20070108135458.GA23395@lst.de>

On Mon, 2007-01-08 at 14:54 +0100, Christoph Hellwig wrote:
> I recently tried to work on lockdep for powerpc.  I have preliminary
> version of the stacktrace code

That seems to work.

> , but had to give up on trace irqflags
> support because I'm not that knowledgeable on lowlevel ppc details.

I gave it a try. Actually what I had wanted to do was add lockdep
support for things like

function A:
lock()
flush_scheduled_work()
unlock()

function B: (work function that is scheduled)
...
lock()
...
unlock()
...

which can obviously deadlock but isn't caught by any debugging
mechanisms right now.

So anyway, lockdep doesn't work here since I only own powerpc machines,
hence I tried to make it work. Below is the patch, it's quite ugly and
only works on 64-bit right now, it'll probably totally screw up on
32-bit (though hopefully it only makes lockdep complain and stop itself
on 32-bit).

I currently get a lockdep report in XFS with this code. Not sure if
there's a bug in this code or if it actually complains rightfully, the
self-tests all pass...

---
 arch/powerpc/Kconfig            |    8 +++++
 arch/powerpc/kernel/Makefile    |    1 
 arch/powerpc/kernel/entry_64.S  |   23 ++++++++++++++++
 arch/powerpc/kernel/head_64.S   |   55 ++++++++++++++++++++++++++++++++--------
 arch/powerpc/kernel/irq.c       |    2 -
 arch/powerpc/kernel/irqtrace.S  |   42 ++++++++++++++++++++++++++++++
 arch/powerpc/kernel/ppc_ksyms.c |    2 -
 arch/powerpc/kernel/setup_64.c  |    6 ++++
 include/asm-powerpc/hw_irq.h    |   34 +++++++++++++-----------
 include/asm-powerpc/irqflags.h  |   11 ++++----
 include/asm-powerpc/rwsem.h     |   34 ++++++++++++++++++------
 include/asm-powerpc/spinlock.h  |    1 
 12 files changed, 177 insertions(+), 42 deletions(-)

--- linux-2.6-git.orig/arch/powerpc/Kconfig	2007-06-26 18:12:10.424850274 +0200
+++ linux-2.6-git/arch/powerpc/Kconfig	2007-06-26 20:01:50.544814034 +0200
@@ -38,6 +38,14 @@ config STACKTRACE_SUPPORT
 	bool
 	default y
 
+config TRACE_IRQFLAGS_SUPPORT
+	bool
+	default y
+
+config LOCKDEP_SUPPORT
+	bool
+	default y
+
 config RWSEM_GENERIC_SPINLOCK
 	bool
 
--- linux-2.6-git.orig/arch/powerpc/kernel/irq.c	2007-06-26 18:12:10.491850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/irq.c	2007-06-26 18:12:11.376850274 +0200
@@ -114,7 +114,7 @@ static inline void set_soft_enabled(unsi
 	: : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
 }
 
-void local_irq_restore(unsigned long en)
+void raw_local_irq_restore(unsigned long en)
 {
 	/*
 	 * get_paca()->soft_enabled = en;
--- linux-2.6-git.orig/arch/powerpc/kernel/ppc_ksyms.c	2007-06-26 18:12:10.513850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/ppc_ksyms.c	2007-06-26 18:12:11.377850274 +0200
@@ -50,7 +50,7 @@
 #endif
 
 #ifdef CONFIG_PPC64
-EXPORT_SYMBOL(local_irq_restore);
+EXPORT_SYMBOL(raw_local_irq_restore);
 #endif
 
 #ifdef CONFIG_PPC32
--- linux-2.6-git.orig/include/asm-powerpc/hw_irq.h	2007-06-26 18:12:10.618850274 +0200
+++ linux-2.6-git/include/asm-powerpc/hw_irq.h	2007-06-26 18:12:11.443850274 +0200
@@ -27,7 +27,7 @@ static inline unsigned long local_get_fl
 	return flags;
 }
 
-static inline unsigned long local_irq_disable(void)
+static inline unsigned long raw_local_irq_disable(void)
 {
 	unsigned long flags, zero;
 
@@ -39,14 +39,15 @@ static inline unsigned long local_irq_di
 	return flags;
 }
 
-extern void local_irq_restore(unsigned long);
+extern void raw_local_irq_restore(unsigned long);
 extern void iseries_handle_interrupts(void);
 
-#define local_irq_enable()	local_irq_restore(1)
-#define local_save_flags(flags)	((flags) = local_get_flags())
-#define local_irq_save(flags)	((flags) = local_irq_disable())
+#define raw_local_irq_enable()	raw_local_irq_restore(1)
+#define raw_local_save_flags(flags)	((flags) = local_get_flags())
+#define raw_local_irq_save(flags)	((flags) = raw_local_irq_disable())
 
-#define irqs_disabled()		(local_get_flags() == 0)
+#define raw_irqs_disabled()		(local_get_flags() == 0)
+#define raw_irqs_disabled_flags(flags)		((flags) == 0)
 
 #define __hard_irq_enable()	__mtmsrd(mfmsr() | MSR_EE, 1)
 #define __hard_irq_disable()	__mtmsrd(mfmsr() & ~MSR_EE, 1)
@@ -62,13 +63,13 @@ extern void iseries_handle_interrupts(vo
 
 #if defined(CONFIG_BOOKE)
 #define SET_MSR_EE(x)	mtmsr(x)
-#define local_irq_restore(flags)	__asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
+#define raw_local_irq_restore(flags)	__asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
 #else
 #define SET_MSR_EE(x)	mtmsr(x)
-#define local_irq_restore(flags)	mtmsr(flags)
+#define raw_local_irq_restore(flags)	mtmsr(flags)
 #endif
 
-static inline void local_irq_disable(void)
+static inline void raw_local_irq_disable(void)
 {
 #ifdef CONFIG_BOOKE
 	__asm__ __volatile__("wrteei 0": : :"memory");
@@ -80,7 +81,7 @@ static inline void local_irq_disable(voi
 #endif
 }
 
-static inline void local_irq_enable(void)
+static inline void raw_local_irq_enable(void)
 {
 #ifdef CONFIG_BOOKE
 	__asm__ __volatile__("wrteei 1": : :"memory");
@@ -92,7 +93,7 @@ static inline void local_irq_enable(void
 #endif
 }
 
-static inline void local_irq_save_ptr(unsigned long *flags)
+static inline void raw_local_irq_save_ptr(unsigned long *flags)
 {
 	unsigned long msr;
 	msr = mfmsr();
@@ -105,12 +106,13 @@ static inline void local_irq_save_ptr(un
 	__asm__ __volatile__("": : :"memory");
 }
 
-#define local_save_flags(flags)	((flags) = mfmsr())
-#define local_irq_save(flags)	local_irq_save_ptr(&flags)
-#define irqs_disabled()		((mfmsr() & MSR_EE) == 0)
+#define raw_local_save_flags(flags)	((flags) = mfmsr())
+#define raw_local_irq_save(flags)	raw_local_irq_save_ptr(&flags)
+#define raw_irqs_disabled()		((mfmsr() & MSR_EE) == 0)
+#define raw_irqs_disabled_flags(flags)		(((flags) & MSR_EE) == 0)
 
-#define hard_irq_enable()	local_irq_enable()
-#define hard_irq_disable()	local_irq_disable()
+#define hard_irq_enable()	raw_local_irq_enable()
+#define hard_irq_disable()	raw_local_irq_disable()
 
 #endif /* CONFIG_PPC64 */
 
--- linux-2.6-git.orig/include/asm-powerpc/irqflags.h	2007-06-26 18:12:10.669850274 +0200
+++ linux-2.6-git/include/asm-powerpc/irqflags.h	2007-06-27 00:35:50.806820710 +0200
@@ -10,19 +10,20 @@
 #ifndef _ASM_IRQFLAGS_H
 #define _ASM_IRQFLAGS_H
 
+#ifndef __ASSEMBLY__
 /*
  * Get definitions for raw_local_save_flags(x), etc.
  */
 #include <asm-powerpc/hw_irq.h>
+#endif
 
 /*
- * Do the CPU's IRQ-state tracing from assembly code. We call a
- * C function, so save all the C-clobbered registers:
+ * Do the CPU's IRQ-state tracing from assembly code. Also
+ * note the code in arch/powerpc/kernel/irqtrace.S.
  */
 #ifdef CONFIG_TRACE_IRQFLAGS
-
-#error No support on PowerPC yet for CONFIG_TRACE_IRQFLAGS
-
+# define TRACE_IRQS_ON		bl .powerpc_trace_irqs_on
+# define TRACE_IRQS_OFF		bl .powerpc_trace_irqs_off
 #else
 # define TRACE_IRQS_ON
 # define TRACE_IRQS_OFF
--- linux-2.6-git.orig/include/asm-powerpc/rwsem.h	2007-06-26 18:12:10.747850274 +0200
+++ linux-2.6-git/include/asm-powerpc/rwsem.h	2007-06-27 00:13:57.397341965 +0200
@@ -28,11 +28,21 @@ struct rw_semaphore {
 #define RWSEM_ACTIVE_WRITE_BIAS		(RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
 	spinlock_t		wait_lock;
 	struct list_head	wait_list;
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+	struct lockdep_map	dep_map;
+#endif
 };
 
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
+#else
+# define __RWSEM_DEP_MAP_INIT(lockname)
+#endif
+
 #define __RWSEM_INITIALIZER(name) \
 	{ RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, \
-	  LIST_HEAD_INIT((name).wait_list) }
+	  LIST_HEAD_INIT((name).wait_list) \
+	  __RWSEM_DEP_MAP_INIT(name) }
 
 #define DECLARE_RWSEM(name)		\
 	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
@@ -42,12 +52,15 @@ extern struct rw_semaphore *rwsem_down_w
 extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
 extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
 
-static inline void init_rwsem(struct rw_semaphore *sem)
-{
-	sem->count = RWSEM_UNLOCKED_VALUE;
-	spin_lock_init(&sem->wait_lock);
-	INIT_LIST_HEAD(&sem->wait_list);
-}
+extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
+			 struct lock_class_key *key);
+
+#define init_rwsem(sem)					\
+	do {						\
+		static struct lock_class_key __key;	\
+							\
+		__init_rwsem((sem), #sem, &__key);	\
+	} while (0)
 
 /*
  * lock for reading
@@ -74,7 +87,7 @@ static inline int __down_read_trylock(st
 /*
  * lock for writing
  */
-static inline void __down_write(struct rw_semaphore *sem)
+static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 {
 	int tmp;
 
@@ -84,6 +97,11 @@ static inline void __down_write(struct r
 		rwsem_down_write_failed(sem);
 }
 
+static inline void __down_write(struct rw_semaphore *sem)
+{
+	__down_write_nested(sem, 0);
+}
+
 static inline int __down_write_trylock(struct rw_semaphore *sem)
 {
 	int tmp;
--- linux-2.6-git.orig/include/asm-powerpc/spinlock.h	2007-06-26 18:12:10.639850274 +0200
+++ linux-2.6-git/include/asm-powerpc/spinlock.h	2007-06-26 18:12:11.446850274 +0200
@@ -19,6 +19,7 @@
  *
  * (the type definitions are in asm/spinlock_types.h)
  */
+#include <linux/irqflags.h>
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/hvcall.h>
--- linux-2.6-git.orig/arch/powerpc/kernel/head_64.S	2007-06-26 18:12:10.537850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/head_64.S	2007-06-27 00:34:57.402820710 +0200
@@ -34,6 +34,7 @@
 #include <asm/iseries/lpar_map.h>
 #include <asm/thread_info.h>
 #include <asm/firmware.h>
+#include <asm/irqflags.h>
 
 #define DO_SOFT_DISABLE
 
@@ -394,6 +395,12 @@ label##_iSeries:							\
 	EXCEPTION_PROLOG_ISERIES_2;					\
 	b	label##_common;						\
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+#define TRACE_DISABLE_INTS bl .powerpc_trace_irqs_off
+#else
+#define TRACE_DISABLE_INTS
+#endif
+
 #ifdef CONFIG_PPC_ISERIES
 #define DISABLE_INTS				\
 	li	r11,0;				\
@@ -405,14 +412,15 @@ BEGIN_FW_FTR_SECTION;				\
 	mfmsr	r10;				\
 	ori	r10,r10,MSR_EE;			\
 	mtmsrd	r10,1;				\
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES);	\
+	TRACE_DISABLE_INTS
 
 #else
 #define DISABLE_INTS				\
 	li	r11,0;				\
 	stb	r11,PACASOFTIRQEN(r13);		\
-	stb	r11,PACAHARDIRQEN(r13)
-
+	stb	r11,PACAHARDIRQEN(r13);		\
+	TRACE_DISABLE_INTS
 #endif /* CONFIG_PPC_ISERIES */
 
 #define ENABLE_INTS				\
@@ -965,24 +973,38 @@ bad_stack:
  */
 fast_exc_return_irq:			/* restores irq state too */
 	ld	r3,SOFTE(r1)
-	ld	r12,_MSR(r1)
+#ifdef CONFIG_TRACE_IRQFLAGS
+	cmpdi	r3,0
+	beq	1f
+	bl	.trace_hardirqs_on
+	ld	r3,SOFTE(r1)
+1:
 	stb	r3,PACASOFTIRQEN(r13)	/* restore paca->soft_enabled */
+	cmpdi	r3,0
+	bne	2f
+	bl	.trace_hardirqs_off
+	ld	r3,SOFTE(r1)
+2:
+#else
+	stb	r3,PACASOFTIRQEN(r13)	/* restore paca->soft_enabled */
+#endif
+	ld	r12,_MSR(r1)
 	rldicl	r4,r12,49,63		/* get MSR_EE to LSB */
 	stb	r4,PACAHARDIRQEN(r13)	/* restore paca->hard_enabled */
-	b	1f
+	b	3f
 
 	.globl	fast_exception_return
 fast_exception_return:
 	ld	r12,_MSR(r1)
-1:	ld	r11,_NIP(r1)
+3:	ld	r11,_NIP(r1)
 	andi.	r3,r12,MSR_RI		/* check if RI is set */
 	beq-	unrecov_fer
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 	andi.	r3,r12,MSR_PR
-	beq	2f
+	beq	4f
 	ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+4:
 #endif
 
 	ld	r3,_CCR(r1)
@@ -1387,11 +1409,24 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISER
 
 	/*
 	 * hash_page couldn't handle it, set soft interrupt enable back
-	 * to what it was before the trap.  Note that .local_irq_restore
+	 * to what it was before the trap.  Note that .raw_local_irq_restore
 	 * handles any interrupts pending at this point.
 	 */
 	ld	r3,SOFTE(r1)
-	bl	.local_irq_restore
+#ifdef CONFIG_TRACE_IRQFLAGS
+	cmpdi	r3,0
+	beq	14f
+	bl	.trace_hardirqs_on
+	ld	r3,SOFTE(r1)
+14:
+	bl	.raw_local_irq_restore
+	cmpdi	r3,0
+	bne	15f
+	bl	.trace_hardirqs_off
+15:
+#else
+	bl	.raw_local_irq_restore
+#endif
 	b	11f
 
 /* Here we have a page fault that hash_page can't handle. */
--- linux-2.6-git.orig/arch/powerpc/kernel/setup_64.c	2007-06-26 18:12:10.594850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/setup_64.c	2007-06-26 18:12:11.451850274 +0200
@@ -33,6 +33,7 @@
 #include <linux/serial_8250.h>
 #include <linux/bootmem.h>
 #include <linux/pci.h>
+#include <linux/lockdep.h>
 #include <asm/io.h>
 #include <asm/kdump.h>
 #include <asm/prom.h>
@@ -359,6 +360,11 @@ void __init setup_system(void)
 			  &__start___fw_ftr_fixup, &__stop___fw_ftr_fixup);
 
 	/*
+	 * start lockdep
+	 */
+	lockdep_init();
+
+	/*
 	 * Unflatten the device-tree passed by prom_init or kexec
 	 */
 	unflatten_device_tree();
--- linux-2.6-git.orig/arch/powerpc/kernel/entry_64.S	2007-06-26 18:20:59.030850274 +0200
+++ linux-2.6-git/arch/powerpc/kernel/entry_64.S	2007-06-26 21:25:58.630569893 +0200
@@ -29,6 +29,7 @@
 #include <asm/cputable.h>
 #include <asm/firmware.h>
 #include <asm/bug.h>
+#include <asm/irqflags.h>
 
 /*
  * System calls.
@@ -91,6 +92,13 @@ system_call_common:
 	li	r10,1
 	stb	r10,PACASOFTIRQEN(r13)
 	stb	r10,PACAHARDIRQEN(r13)
+#ifdef CONFIG_TRACE_IRQFLAGS
+	bl	.trace_hardirqs_on
+	REST_GPR(0,r1)
+	REST_4GPRS(3,r1)
+	REST_2GPRS(7,r1)
+	addi	r9,r1,STACK_FRAME_OVERHEAD
+#endif
 	std	r10,SOFTE(r1)
 #ifdef CONFIG_PPC_ISERIES
 BEGIN_FW_FTR_SECTION
@@ -491,8 +499,20 @@ BEGIN_FW_FTR_SECTION
 4:
 END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
 #endif
+#ifdef CONFIG_TRACE_IRQFLAGS
+	cmpdi	r5,0
+	beq	5f
+	bl	.trace_hardirqs_on
+	ld	r5,SOFTE(r1)
 	stb	r5,PACASOFTIRQEN(r13)
-
+	b	6f
+5:
+	stb	r5,PACASOFTIRQEN(r13)
+	bl	.trace_hardirqs_off
+6:
+#else
+	stb	r5,PACASOFTIRQEN(r13)
+#endif
 	/* extract EE bit and use it to restore paca->hard_enabled */
 	ld	r3,_MSR(r1)
 	rldicl	r4,r3,49,63		/* r0 = (r3 >> 15) & 1 */
@@ -560,6 +580,7 @@ do_work:
 	bne	restore
 	/* here we are preempting the current task */
 1:
+	TRACE_IRQS_ON
 	li	r0,1
 	stb	r0,PACASOFTIRQEN(r13)
 	stb	r0,PACAHARDIRQEN(r13)
--- linux-2.6-git.orig/arch/powerpc/kernel/Makefile	2007-06-26 19:27:54.032776841 +0200
+++ linux-2.6-git/arch/powerpc/kernel/Makefile	2007-06-27 00:30:19.115820710 +0200
@@ -62,6 +62,7 @@ obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_serial.o udbg_16550.o
 obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
+obj-$(CONFIG_TRACE_IRQFLAGS)	+= irqtrace.o
 
 module-$(CONFIG_PPC64)		+= module_64.o
 obj-$(CONFIG_MODULES)		+= $(module-y)
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-git/arch/powerpc/kernel/irqtrace.S	2007-06-27 00:32:07.125820710 +0200
@@ -0,0 +1,42 @@
+/*
+ * crappy helper for irq-trace
+ */
+
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+
+#define STACKSPACE	GPR0 + 16*8
+
+#ifdef __powerpc64__
+#define ST	std
+#define L	ld
+#else
+#define ST	stw
+#define L	lw
+#endif
+
+#define PRE				\
+	subi	r1,r1,STACKSPACE ;	\
+	SAVE_GPR(0, r1) ;		\
+	SAVE_8GPRS(2, r1) ;		\
+	SAVE_4GPRS(10, r1) ;		\
+	mfcr	r0 ;			\
+	ST	r0, (14*8)(r1) ;	\
+	mflr	r0 ;			\
+	ST	r0, (15*8)(r1)
+
+#define POST				\
+	REST_8GPRS(2, r1) ;		\
+	REST_4GPRS(10, r1) ;		\
+	L	r0, (14*8)(r1) ;	\
+	mtcr	r0 ;			\
+	L	r0, (15*8)(r1) ;	\
+	mtlr	r0 ;			\
+	REST_GPR(0, r1) ;		\
+	addi	r1,r1,STACKSPACE
+
+_GLOBAL(powerpc_trace_irqs_off)
+	PRE
+	bl .trace_hardirqs_off
+	POST
+	blr

^ permalink raw reply

* USB for MPC82xx
From: David @ 2007-06-27  8:49 UTC (permalink / raw)
  To: linuxppc-embedded

Hi,

I know this is a quite old issue but I'm getting quite crazy with it and 
I hope that someone can help me.

The plot is that I'm trying to use USB on an MPC8272. I already know 
that there is a 2.6.x driver that solves this, but the main issue is 
that we are using a 2.4.31 kernel. So we have

I have read a lot about a 2.4 driver that Pantelis Antoniou wrote, but I 
haven't been able to find it.

Does anybody know where I could find a driver?

The other option is to backport the 2.6 driver to 2.4, but I will try 
not to think on that by the moment.

Regards,

David

^ 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