All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
  2012-04-30 11:32 [PATCH 01/14] MIPS: make oprofile use cp0_perfcount_irq if it is set John Crispin
@ 2012-04-30 11:32 ` John Crispin
  2012-04-30 16:55   ` David Daney
  0 siblings, 1 reply; 7+ messages in thread
From: John Crispin @ 2012-04-30 11:32 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips@linux-mips.org, John Crispin

Implement pci_load_OF_ranges on MIPS. Due to lack of test hardware only 32bit bus
width is supported. This function is based on the implementation found on powerpc.

Signed-off-by: John Crispin <blogic@openwrt.org>
---
 arch/mips/include/asm/pci.h |   12 +++++++++
 arch/mips/pci/pci.c         |   57 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index fcd4060..fdc47c5 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -17,6 +17,9 @@
  */
 
 #include <linux/ioport.h>
+#ifdef CONFIG_OF
+#include <linux/of.h>
+#endif
 
 /*
  * Each pci channel is a top-level PCI bus seem by CPU.  A machine  with
@@ -26,6 +29,9 @@
 struct pci_controller {
 	struct pci_controller *next;
 	struct pci_bus *bus;
+#ifdef CONFIG_OF
+	struct device_node *of_node;
+#endif
 
 	struct pci_ops *pci_ops;
 	struct resource *mem_resource;
@@ -142,4 +148,10 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 
 extern char * (*pcibios_plat_setup)(char *str);
 
+#ifdef CONFIG_OF
+/* this function parses memory ranges from a device node */
+extern void __devinit pci_load_OF_ranges(struct pci_controller *hose,
+					 struct device_node *node);
+#endif
+
 #endif /* _ASM_PCI_H */
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 0514866..e211819 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/of_address.h>
 
 #include <asm/cpu-info.h>
 
@@ -114,8 +115,64 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
 			pci_bus_assign_resources(bus);
 			pci_enable_bridges(bus);
 		}
+#ifdef CONFIG_OF
+		bus->dev.of_node = hose->of_node;
+#endif
+	}
+}
+
+#ifdef CONFIG_OF
+void __devinit pci_load_OF_ranges(struct pci_controller *hose,
+				struct device_node *node)
+{
+	const __be32 *ranges;
+	int rlen;
+	int pna = of_n_addr_cells(node);
+	int np = pna + 5;
+
+	pr_info("PCI host bridge %s ranges:\n", node->full_name);
+	ranges = of_get_property(node, "ranges", &rlen);
+	if (ranges == NULL)
+		return;
+	hose->of_node = node;
+
+	while ((rlen -= np * 4) >= 0) {
+		u32 pci_space;
+		struct resource *res = 0;
+		unsigned long long addr, size;
+
+		pci_space = ranges[0];
+		addr = of_translate_address(node, ranges + 3);
+		size = of_read_number(ranges + pna + 3, 2);
+		ranges += np;
+		switch ((pci_space >> 24) & 0x3) {
+		case 1:		/* PCI IO space */
+			pr_info("  IO 0x%016llx..0x%016llx\n",
+					addr, addr + size - 1);
+			hose->io_map_base =
+				(unsigned long)ioremap(addr, size);
+			res = hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			break;
+		case 2:		/* PCI Memory space */
+		case 3:		/* PCI 64 bits Memory space */
+			pr_info(" MEM 0x%016llx..0x%016llx\n",
+					addr, addr + size - 1);
+			res = hose->mem_resource;
+			res->flags = IORESOURCE_MEM;
+			break;
+		}
+		if (res != NULL) {
+			res->start = addr;
+			res->name = node->full_name;
+			res->end = res->start + size - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
 	}
 }
+#endif
 
 static DEFINE_MUTEX(pci_scan_mutex);
 
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
  2012-04-30 11:32 ` [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree John Crispin
@ 2012-04-30 16:55   ` David Daney
  2012-04-30 17:02     ` John Crispin
  2012-05-01 11:17     ` John Crispin
  0 siblings, 2 replies; 7+ messages in thread
From: David Daney @ 2012-04-30 16:55 UTC (permalink / raw)
  To: John Crispin; +Cc: Ralf Baechle, linux-mips@linux-mips.org

On 04/30/2012 04:32 AM, John Crispin wrote:
> Implement pci_load_OF_ranges on MIPS. Due to lack of test hardware only 32bit bus
> width is supported. This function is based on the implementation found on powerpc.
>
> Signed-off-by: John Crispin<blogic@openwrt.org>
> ---
>   arch/mips/include/asm/pci.h |   12 +++++++++
>   arch/mips/pci/pci.c         |   57 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 69 insertions(+), 0 deletions(-)
>
> diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
> index fcd4060..fdc47c5 100644
> --- a/arch/mips/include/asm/pci.h
> +++ b/arch/mips/include/asm/pci.h
> @@ -17,6 +17,9 @@
>    */
>
>   #include<linux/ioport.h>
> +#ifdef CONFIG_OF
> +#include<linux/of.h>
> +#endif
>

No need for the #ifdef here.



>   /*
>    * Each pci channel is a top-level PCI bus seem by CPU.  A machine  with
> @@ -26,6 +29,9 @@
>   struct pci_controller {
>   	struct pci_controller *next;
>   	struct pci_bus *bus;
> +#ifdef CONFIG_OF
> +	struct device_node *of_node;
> +#endif
>

Probably no #ifdef here either.

>   	struct pci_ops *pci_ops;
>   	struct resource *mem_resource;
> @@ -142,4 +148,10 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
>
>   extern char * (*pcibios_plat_setup)(char *str);
>
> +#ifdef CONFIG_OF
> +/* this function parses memory ranges from a device node */
> +extern void __devinit pci_load_OF_ranges(struct pci_controller *hose,
> +					 struct device_node *node);
> +#endif

Again, no #ifdef.

> +
>   #endif /* _ASM_PCI_H */
> diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
> index 0514866..e211819 100644
> --- a/arch/mips/pci/pci.c
> +++ b/arch/mips/pci/pci.c
> @@ -16,6 +16,7 @@
>   #include<linux/init.h>
>   #include<linux/types.h>
>   #include<linux/pci.h>
> +#include<linux/of_address.h>
>
>   #include<asm/cpu-info.h>
>
> @@ -114,8 +115,64 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
>   			pci_bus_assign_resources(bus);
>   			pci_enable_bridges(bus);
>   		}
> +#ifdef CONFIG_OF
> +		bus->dev.of_node = hose->of_node;
> +#endif

Same here.

> +	}
> +}
> +
> +#ifdef CONFIG_OF
> +void __devinit pci_load_OF_ranges(struct pci_controller *hose,
> +				struct device_node *node)
> +{

s/load_OF/load_of/


> +	const __be32 *ranges;
> +	int rlen;
> +	int pna = of_n_addr_cells(node);
> +	int np = pna + 5;
> +
> +	pr_info("PCI host bridge %s ranges:\n", node->full_name);
> +	ranges = of_get_property(node, "ranges",&rlen);
> +	if (ranges == NULL)
> +		return;
> +	hose->of_node = node;
> +
> +	while ((rlen -= np * 4)>= 0) {
> +		u32 pci_space;
> +		struct resource *res = 0;
> +		unsigned long long addr, size;
> +
> +		pci_space = ranges[0];
> +		addr = of_translate_address(node, ranges + 3);
> +		size = of_read_number(ranges + pna + 3, 2);

All of this should be able to be replaced with of_get_address();

There is a bunch of of/pci related infrastructure.  Can any of it be 
leveraged?


> +		ranges += np;
> +		switch ((pci_space>>  24)&  0x3) {
> +		case 1:		/* PCI IO space */
> +			pr_info("  IO 0x%016llx..0x%016llx\n",
> +					addr, addr + size - 1);
> +			hose->io_map_base =
> +				(unsigned long)ioremap(addr, size);
> +			res = hose->io_resource;
> +			res->flags = IORESOURCE_IO;
> +			break;
> +		case 2:		/* PCI Memory space */
> +		case 3:		/* PCI 64 bits Memory space */
> +			pr_info(" MEM 0x%016llx..0x%016llx\n",
> +					addr, addr + size - 1);
> +			res = hose->mem_resource;
> +			res->flags = IORESOURCE_MEM;
> +			break;
> +		}
> +		if (res != NULL) {
> +			res->start = addr;
> +			res->name = node->full_name;
> +			res->end = res->start + size - 1;
> +			res->parent = NULL;
> +			res->sibling = NULL;
> +			res->child = NULL;
> +		}
>   	}
>   }
> +#endif
>
>   static DEFINE_MUTEX(pci_scan_mutex);
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
  2012-04-30 16:55   ` David Daney
@ 2012-04-30 17:02     ` John Crispin
  2012-05-01 11:17     ` John Crispin
  1 sibling, 0 replies; 7+ messages in thread
From: John Crispin @ 2012-04-30 17:02 UTC (permalink / raw)
  To: David Daney; +Cc: Ralf Baechle, linux-mips@linux-mips.org

Hi,
>
> No need for the #ifdef here.
>

i will fix this globally in the patch


>> +void __devinit pci_load_OF_ranges(struct pci_controller *hose,
>> +                struct device_node *node)
>> +{
>
> s/load_OF/load_of/

ok, some other arch did _OF_ so i blindly copied it.


>> +    const __be32 *ranges;
>> +    int rlen;
>> +    int pna = of_n_addr_cells(node);
>> +    int np = pna + 5;
>> +
>> +    pr_info("PCI host bridge %s ranges:\n", node->full_name);
>> +    ranges = of_get_property(node, "ranges",&rlen);
>> +    if (ranges == NULL)
>> +        return;
>> +    hose->of_node = node;
>> +
>> +    while ((rlen -= np * 4)>= 0) {
>> +        u32 pci_space;
>> +        struct resource *res = 0;
>> +        unsigned long long addr, size;
>> +
>> +        pci_space = ranges[0];
>> +        addr = of_translate_address(node, ranges + 3);
>> +        size = of_read_number(ranges + pna + 3, 2);
>
> All of this should be able to be replaced with of_get_address();
>
> There is a bunch of of/pci related infrastructure.  Can any of it be
> leveraged?

i look at it when i made the patch 3 months ago. the pci ranges are
mapped very differently to normal reg= <addr len>;  properties. You can
find some info about this at the bottom of this link
http://devicetree.org/Device_Tree_Usage 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
  2012-04-30 16:55   ` David Daney
  2012-04-30 17:02     ` John Crispin
@ 2012-05-01 11:17     ` John Crispin
  1 sibling, 0 replies; 7+ messages in thread
From: John Crispin @ 2012-05-01 11:17 UTC (permalink / raw)
  To: David Daney; +Cc: Ralf Baechle, linux-mips@linux-mips.org

On 30/04/12 18:55, David Daney wrote:
>>       struct pci_ops *pci_ops;
>>       struct resource *mem_resource;
>> @@ -142,4 +148,10 @@ static inline int pci_get_legacy_ide_irq(struct
>> pci_dev *dev, int channel)
>>
>>   extern char * (*pcibios_plat_setup)(char *str);
>>
>> +#ifdef CONFIG_OF
>> +/* this function parses memory ranges from a device node */
>> +extern void __devinit pci_load_OF_ranges(struct pci_controller *hose,
>> +                     struct device_node *node);
>> +#endif
>
> Again, no #ifdef. 


Hi,

are you sure that we don't want to #ifdef this prototype ? The function
is only available when OF is selected.

Thanks,
John

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
@ 2012-05-03 17:42 John Crispin
  2012-05-03 19:30 ` Geert Uytterhoeven
  0 siblings, 1 reply; 7+ messages in thread
From: John Crispin @ 2012-05-03 17:42 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: linux-mips@linux-mips.org, John Crispin

Implement pci_load_of_ranges on MIPS. Due to lack of test hardware only 32bit
bus width is supported. This function is based on the implementation found on
powerpc.

Signed-off-by: John Crispin <blogic@openwrt.org>

---
Changes in V2
* remove some #ifdefs
* rename to pci_load_of_ranges

Changes in V3
* set pointers to NULL and not 0

 arch/mips/include/asm/pci.h |    6 ++++
 arch/mips/pci/pci.c         |   55 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index fcd4060..90bf3b3 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -17,6 +17,7 @@
  */
 
 #include <linux/ioport.h>
+#include <linux/of.h>
 
 /*
  * Each pci channel is a top-level PCI bus seem by CPU.  A machine  with
@@ -26,6 +27,7 @@
 struct pci_controller {
 	struct pci_controller *next;
 	struct pci_bus *bus;
+	struct device_node *of_node;
 
 	struct pci_ops *pci_ops;
 	struct resource *mem_resource;
@@ -142,4 +144,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
 
 extern char * (*pcibios_plat_setup)(char *str);
 
+/* this function parses memory ranges from a device node */
+extern void __devinit pci_load_of_ranges(struct pci_controller *hose,
+					 struct device_node *node);
+
 #endif /* _ASM_PCI_H */
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index 0514866..a10c951 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/of_address.h>
 
 #include <asm/cpu-info.h>
 
@@ -114,9 +115,63 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose)
 			pci_bus_assign_resources(bus);
 			pci_enable_bridges(bus);
 		}
+		bus->dev.of_node = hose->of_node;
 	}
 }
 
+#ifdef CONFIG_OF
+void __devinit pci_load_of_ranges(struct pci_controller *hose,
+				struct device_node *node)
+{
+	const __be32 *ranges;
+	int rlen;
+	int pna = of_n_addr_cells(node);
+	int np = pna + 5;
+
+	pr_info("PCI host bridge %s ranges:\n", node->full_name);
+	ranges = of_get_property(node, "ranges", &rlen);
+	if (ranges == NULL)
+		return;
+	hose->of_node = node;
+
+	while ((rlen -= np * 4) >= 0) {
+		u32 pci_space;
+		struct resource *res = NULL;
+		unsigned long long addr, size;
+
+		pci_space = ranges[0];
+		addr = of_translate_address(node, ranges + 3);
+		size = of_read_number(ranges + pna + 3, 2);
+		ranges += np;
+		switch ((pci_space >> 24) & 0x3) {
+		case 1:		/* PCI IO space */
+			pr_info("  IO 0x%016llx..0x%016llx\n",
+					addr, addr + size - 1);
+			hose->io_map_base =
+				(unsigned long)ioremap(addr, size);
+			res = hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			break;
+		case 2:		/* PCI Memory space */
+		case 3:		/* PCI 64 bits Memory space */
+			pr_info(" MEM 0x%016llx..0x%016llx\n",
+					addr, addr + size - 1);
+			res = hose->mem_resource;
+			res->flags = IORESOURCE_MEM;
+			break;
+		}
+		if (res != NULL) {
+			res->start = addr;
+			res->name = node->full_name;
+			res->end = res->start + size - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+	}
+}
+#endif
+
 static DEFINE_MUTEX(pci_scan_mutex);
 
 void __devinit register_pci_controller(struct pci_controller *hose)
-- 
1.7.9.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
  2012-05-03 17:42 [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree John Crispin
@ 2012-05-03 19:30 ` Geert Uytterhoeven
  2012-05-03 19:39   ` John Crispin
  0 siblings, 1 reply; 7+ messages in thread
From: Geert Uytterhoeven @ 2012-05-03 19:30 UTC (permalink / raw)
  To: John Crispin; +Cc: Ralf Baechle, linux-mips@linux-mips.org

On Thu, May 3, 2012 at 7:42 PM, John Crispin <blogic@openwrt.org> wrote:
> Implement pci_load_of_ranges on MIPS. Due to lack of test hardware only 32bit
> bus width is supported. This function is based on the implementation found on
> powerpc.

There's no pci_load_of_ranges() in arch/powerpc/?

> +void __devinit pci_load_of_ranges(struct pci_controller *hose,
> +                               struct device_node *node)
> +{
> +       const __be32 *ranges;
> +       int rlen;
> +       int pna = of_n_addr_cells(node);
> +       int np = pna + 5;
> +
> +       pr_info("PCI host bridge %s ranges:\n", node->full_name);
> +       ranges = of_get_property(node, "ranges", &rlen);
> +       if (ranges == NULL)
> +               return;
> +       hose->of_node = node;
> +
> +       while ((rlen -= np * 4) >= 0) {
> +               u32 pci_space;
> +               struct resource *res = NULL;
> +               unsigned long long addr, size;

You better use u64, as that's what of_translate_address() and
of_read_number() return.

> +
> +               pci_space = ranges[0];

pci_space = be32_to_cpup(&ranges[0])

> +               addr = of_translate_address(node, ranges + 3);
> +               size = of_read_number(ranges + pna + 3, 2);

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree
  2012-05-03 19:30 ` Geert Uytterhoeven
@ 2012-05-03 19:39   ` John Crispin
  0 siblings, 0 replies; 7+ messages in thread
From: John Crispin @ 2012-05-03 19:39 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Ralf Baechle, linux-mips@linux-mips.org

Hi Geert,


> There's no pci_load_of_ranges() in arch/powerpc/?
>

Sorry, its based on pci_process_bridge_OF_ranges.

I will fold your comments into the patch,

Thanks,
John

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-05-03 19:41 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-03 17:42 [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree John Crispin
2012-05-03 19:30 ` Geert Uytterhoeven
2012-05-03 19:39   ` John Crispin
  -- strict thread matches above, loose matches on Subject: below --
2012-04-30 11:32 [PATCH 01/14] MIPS: make oprofile use cp0_perfcount_irq if it is set John Crispin
2012-04-30 11:32 ` [PATCH 02/14] MIPS: pci: parse memory ranges from devicetree John Crispin
2012-04-30 16:55   ` David Daney
2012-04-30 17:02     ` John Crispin
2012-05-01 11:17     ` John Crispin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.