Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 3/4] pci: Introduce a domain number for pci_host_bridge.
From: Liviu Dudau @ 2014-02-27 13:06 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel
  Cc: devicetree@vger.kernel.org, LKML, LAKML
In-Reply-To: <1393506402-11474-1-git-send-email-Liviu.Dudau@arm.com>

Make it easier to discover the domain number of a bus by storing
the number in pci_host_bridge for the root bus. Several architectures
have their own way of storing this information, so it makes sense
to try to unify the code. While at this, add a new function that
creates a root bus in a given domain and make pci_create_root_bus()
a wrapper around this function.

Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 78ccba0..1b2f45c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1714,8 +1714,9 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 {
 }
 
-struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+struct pci_bus *pci_create_root_bus_in_domain(struct device *parent,
+		int domain, int bus, struct pci_ops *ops, void *sysdata,
+		struct list_head *resources)
 {
 	int error;
 	struct pci_host_bridge *bridge;
@@ -1732,6 +1733,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 
 	bridge->dev.parent = parent;
 	bridge->dev.release = pci_release_host_bridge_dev;
+	bridge->domain_nr = domain;
 	error = pcibios_root_bridge_prepare(bridge);
 	if (error) {
 		kfree(bridge);
@@ -1745,7 +1747,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	b->sysdata = sysdata;
 	b->ops = ops;
 	b->number = b->busn_res.start = bus;
-	b2 = pci_find_bus(pci_domain_nr(b), bus);
+	b2 = pci_find_bus(bridge->domain_nr, bus);
 	if (b2) {
 		/* If we already got to this bus through a different bridge, ignore it */
 		dev_dbg(&b2->dev, "bus already known\n");
@@ -1753,7 +1755,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 	}
 
 	bridge->bus = b;
-	dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
+	dev_set_name(&bridge->dev, "pci%04x:%02x", bridge->domain_nr, bus);
 	error = device_register(&bridge->dev);
 	if (error) {
 		put_device(&bridge->dev);
@@ -1768,7 +1770,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 
 	b->dev.class = &pcibus_class;
 	b->dev.parent = b->bridge;
-	dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus);
+	dev_set_name(&b->dev, "%04x:%02x", bridge->domain_nr, bus);
 	error = device_register(&b->dev);
 	if (error)
 		goto class_dev_reg_err;
@@ -1821,6 +1823,22 @@ err_out:
 	return NULL;
 }
 
+struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
+		struct pci_ops *ops, void *sysdata, struct list_head *resources)
+{
+	int domain_nr;
+	struct pci_bus *b = pci_alloc_bus();
+	if (!b)
+		return NULL;
+
+	b->sysdata = sysdata;
+	domain_nr = pci_domain_nr(b);
+	kfree(b);
+
+	return pci_create_root_bus_in_domain(parent, domain_nr, bus,
+				ops, sysdata, resources);
+}
+
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
 {
 	struct resource *res = &b->busn_res;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 33aa2ca..1eed009 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -394,6 +394,7 @@ struct pci_host_bridge_window {
 struct pci_host_bridge {
 	struct device dev;
 	struct pci_bus *bus;		/* root bus */
+	int domain_nr;
 	struct list_head windows;	/* pci_host_bridge_windows */
 	void (*release_fn)(struct pci_host_bridge *);
 	void *release_data;
@@ -747,6 +748,9 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata);
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
 				    struct pci_ops *ops, void *sysdata,
 				    struct list_head *resources);
+struct pci_bus *pci_create_root_bus_in_domain(struct device *parent,
+			int domain, int bus, struct pci_ops *ops,
+			void *sysdata, struct list_head *resources);
 int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax);
 int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax);
 void pci_bus_release_busn_res(struct pci_bus *b);
-- 
1.9.0

^ permalink raw reply related

* [PATCH v2 4/4] pci: Add support for creating a generic host_bridge from device tree
From: Liviu Dudau @ 2014-02-27 13:06 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel
  Cc: LKML, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, LAKML
In-Reply-To: <1393506402-11474-1-git-send-email-Liviu.Dudau-5wv7dgnIgG8@public.gmane.org>

Several platforms use a rather generic version of parsing
the device tree to find the host bridge ranges. Move the common code
into the generic PCI code and use it to create a pci_host_bridge
structure that can be used by arch code.

Based on early attempts by Andrew Murray to unify the code.
Used powerpc and microblaze PCI code as starting point.

Signed-off-by: Liviu Dudau <Liviu.Dudau-5wv7dgnIgG8@public.gmane.org>

diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
index 06ace62..feb8436 100644
--- a/drivers/pci/host-bridge.c
+++ b/drivers/pci/host-bridge.c
@@ -6,9 +6,13 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_pci.h>
 
 #include "pci.h"
 
+static int domain_nr;
+
 static struct pci_bus *find_pci_root_bus(struct pci_bus *bus)
 {
 	while (bus->parent)
@@ -91,3 +95,133 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
 	res->end = region->end + offset;
 }
 EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+/**
+ * pci_host_bridge_of_get_ranges - Parse PCI host bridge resources from DT
+ * @dev: device node of the host bridge having the range property
+ * @resources: list where the range of resources will be added after DT parsing
+ * @io_base: pointer to a variable that will contain the physical address for
+ * the start of the I/O range.
+ *
+ * If this function returns an error then the @resources list will be freed.
+ *
+ * This function will parse the "ranges" property of a PCI host bridge device
+ * node and setup the resource mapping based on its content. It is expected
+ * that the property conforms with the Power ePAPR document.
+ *
+ * Each architecture is then offered the chance of applying their own
+ * filtering of pci_host_bridge_windows based on their own restrictions by
+ * calling pcibios_fixup_bridge_ranges(). The filtered list of windows
+ * can then be used when creating a pci_host_bridge structure.
+ */
+static int pci_host_bridge_of_get_ranges(struct device_node *dev,
+		struct list_head *resources, resource_size_t *io_base)
+{
+	struct resource *res;
+	struct of_pci_range range;
+	struct of_pci_range_parser parser;
+	int err;
+
+	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
+
+	/* Check for ranges property */
+	err = of_pci_range_parser_init(&parser, dev);
+	if (err)
+		return err;
+
+	pr_debug("Parsing ranges property...\n");
+	for_each_of_pci_range(&parser, &range) {
+		/* Read next ranges element */
+		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
+				range.pci_space, range.pci_addr);
+		pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
+					range.cpu_addr, range.size);
+
+		/*
+		 * If we failed translation or got a zero-sized region
+		 * then skip this range
+		 */
+		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
+			continue;
+
+		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
+		if (!res) {
+			err = -ENOMEM;
+			goto bridge_ranges_nomem;
+		}
+
+		of_pci_range_to_resource(&range, dev, res);
+
+		if (resource_type(res) == IORESOURCE_IO)
+			*io_base = range.cpu_addr;
+
+		pci_add_resource_offset(resources, res,
+				res->start - range.pci_addr);
+	}
+
+	/* Apply architecture specific fixups for the ranges */
+	pcibios_fixup_bridge_ranges(resources);
+
+	return 0;
+
+bridge_ranges_nomem:
+	pci_free_resource_list(resources);
+	return err;
+}
+
+/**
+ * of_create_pci_host_bridge - Create a PCI host bridge structure using
+ * information passed in the DT.
+ * @parent: device owning this host bridge
+ * @ops: pci_ops associated with the host controller
+ * @host_data: opaque data structure used by the host controller.
+ *
+ * returns a pointer to the newly created pci_host_bridge structure, or
+ * NULL if the call failed.
+ *
+ * This function will try to obtain the host bridge domain number by
+ * using of_alias_get_id() call with "pci-domain" as a stem. If that
+ * fails, a local allocator will be used that will put each host bridge
+ * in a new domain.
+ */
+struct pci_host_bridge *
+of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops, void *host_data)
+{
+	int err, domain, busno;
+	struct resource bus_range;
+	struct pci_bus *root_bus;
+	struct pci_host_bridge *bridge;
+	resource_size_t io_base;
+	LIST_HEAD(res);
+
+	domain = of_alias_get_id(parent->of_node, "pci-domain");
+	if (domain == -ENODEV)
+		domain = domain_nr++;
+
+	err = of_pci_parse_bus_range(parent->of_node, &bus_range);
+	if (err) {
+		dev_info(parent, "No bus range for %s, using default [0-255]\n",
+			parent->of_node->full_name);
+		bus_range.start = 0;
+		bus_range.end = 255;
+		bus_range.flags = IORESOURCE_BUS;
+	}
+	busno = bus_range.start;
+	pci_add_resource(&res, &bus_range);
+
+	/* now parse the rest of host bridge bus ranges */
+	if (pci_host_bridge_of_get_ranges(parent->of_node, &res, &io_base))
+		return NULL;
+
+	/* then create the root bus */
+	root_bus = pci_create_root_bus_in_domain(parent, domain, busno,
+						ops, host_data, &res);
+	if (!root_bus)
+		return NULL;
+
+	bridge = to_pci_host_bridge(root_bus->bridge);
+	bridge->io_base = io_base;
+
+	return bridge;
+}
+EXPORT_SYMBOL_GPL(of_create_pci_host_bridge);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1eed009..0c5e269 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -395,6 +395,7 @@ struct pci_host_bridge {
 	struct device dev;
 	struct pci_bus *bus;		/* root bus */
 	int domain_nr;
+	resource_size_t io_base;	/* physical address for the start of I/O area */
 	struct list_head windows;	/* pci_host_bridge_windows */
 	void (*release_fn)(struct pci_host_bridge *);
 	void *release_data;
@@ -1786,11 +1787,23 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
 	return bus ? bus->dev.of_node : NULL;
 }
 
+struct pci_host_bridge *
+of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops,
+			void *host_data);
+
+void pcibios_fixup_bridge_ranges(struct list_head *resources);
 #else /* CONFIG_OF */
 static inline void pci_set_of_node(struct pci_dev *dev) { }
 static inline void pci_release_of_node(struct pci_dev *dev) { }
 static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
 static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
+
+static inline struct pci_host_bridge *
+pci_host_bridge_of_init(struct device *parent, struct pci_ops *ops,
+			void *host_data)
+{
+	return NULL;
+}
 #endif  /* CONFIG_OF */
 
 #ifdef CONFIG_EEH
-- 
1.9.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 0/3] [RFC] Add support for PCI in AArch64
From: Liviu Dudau @ 2014-02-27 13:09 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel
  Cc: LKML, devicetree@vger.kernel.org, LAKML

Hi,

This patch adds support for PCI to AArch64. It is based on my v2 patch
that adds support for creating generic host bridge structure from
device tree. With that in place, I was able to boot a platform that
has PCIe host bridge support and use a PCIe network card.

Changes from v1:
  - Added Catalin's patch for moving the PCI_IO_BASE location and extend
    its size to 16MB
  - Integrated Arnd's version of pci_ioremap_io that uses a bitmap for
    keeping track of assigned IO space and returns an io_offset. At the
    moment the code is added in arch/arm64 but it can be moved in drivers/pci.
  - Added a fix for the generic ioport_map() function when !CONFIG_GENERIC_IOMAP
    as suggested by Arnd.

The API used is different from the one used by ARM architecture. There is
no pci_common_init_dev() function and no hw_pci structure, as that is no
longer needed. Once the last signature is added to the legal agreement, I
will post the host bridge driver code that I am using. Meanwhile, here
is an example of what the probe function looks like, posted as an example:

static int myhostbridge_probe(struct platform_device *pdev)
{
	int err;
	struct device_node *dev;
	struct pci_host_bridge *bridge;
	struct myhostbridge_port *pp;
	resource_size_t lastbus;

	dev = pdev->dev.of_node;

	if (!of_device_is_available(dev)) {
		pr_warn("%s: disabled\n", dev->full_name);
		return -ENODEV;
	}

	pp = kzalloc(sizeof(struct myhostbridge_port), GFP_KERNEL);
	if (!pp)
		return -ENOMEM;

	bridge = of_create_pci_host_bridge(&pdev->dev, &myhostbridge_ops, pp);
	if (!bridge) {
		err = -EINVAL;
		goto bridge_init_fail;
	}

	err = myhostbridge_setup(bridge->bus);
	if (err)
		goto bridge_init_fail;

	/* We always enable PCI domains and we keep domain 0 backward
	 * compatible in /proc for video cards
	 */
	pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0);
	pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);

	lastbus = pci_scan_child_bus(bridge->bus);
	pci_bus_update_busn_res_end(bridge->bus, lastbus);

	pci_assign_unassigned_bus_resources(bridge->bus);

	pci_bus_add_devices(bridge->bus);

	return 0;

bridge_init_fail:
	kfree(pp);
	return err;
}


Best regards,
Liviu



Catalin Marinas (1):
  arm64: Extend the PCI I/O space to 16MB

Liviu Dudau (2):
  Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
  arm64: Add architecture support for PCI

 Documentation/arm64/memory.txt |  16 ++++--
 arch/arm64/Kconfig             |  19 ++++++-
 arch/arm64/include/asm/Kbuild  |   1 +
 arch/arm64/include/asm/io.h    |   5 +-
 arch/arm64/include/asm/pci.h   |  47 +++++++++++++++
 arch/arm64/kernel/Makefile     |   1 +
 arch/arm64/kernel/pci.c        | 126 +++++++++++++++++++++++++++++++++++++++++
 include/asm-generic/io.h       |   2 +-
 8 files changed, 207 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/pci.c

-- 
1.9.0

^ permalink raw reply

* [PATCH v2 1/3] Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
From: Liviu Dudau @ 2014-02-27 13:09 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel
  Cc: LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393506599-11561-1-git-send-email-Liviu.Dudau@arm.com>

The inline version of ioport_map() that gets used when !CONFIG_GENERIC_IOMAP
is wrong. It returns a mapped (i.e. virtual) address that can start from
zero and completely ignores the PCI_IOBASE and IO_SPACE_LIMIT that most
architectures that use !CONFIG_GENERIC_MAP define.

Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index d5afe96..df72051 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr)
 #ifndef CONFIG_GENERIC_IOMAP
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
-	return (void __iomem *) port;
+	return (void __iomem *)(PCI_IOBASE + (port & IO_SPACE_LIMIT));
 }
 
 static inline void ioport_unmap(void __iomem *p)
-- 
1.9.0

^ permalink raw reply related

* [PATCH v2 2/3] arm64: Extend the PCI I/O space to 16MB
From: Liviu Dudau @ 2014-02-27 13:09 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel
  Cc: LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393506599-11561-1-git-send-email-Liviu.Dudau@arm.com>

From: Catalin Marinas <catalin.marinas@arm.com>

The patch moves the PCI I/O space (currently at 64K) before the
earlyprintk mapping and extends it to 16MB.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

diff --git a/Documentation/arm64/memory.txt b/Documentation/arm64/memory.txt
index 5e054bf..85e24c4 100644
--- a/Documentation/arm64/memory.txt
+++ b/Documentation/arm64/memory.txt
@@ -35,11 +35,13 @@ ffffffbc00000000	ffffffbdffffffff	   8GB		vmemmap
 
 ffffffbe00000000	ffffffbffbbfffff	  ~8GB		[guard, future vmmemap]
 
-ffffffbffbc00000	ffffffbffbdfffff	   2MB		earlyprintk device
+ffffffbffa000000	ffffffbffaffffff	  16MB		PCI I/O space
+
+ffffffbffb000000	ffffffbffbbfffff	  12MB		[guard]
 
-ffffffbffbe00000	ffffffbffbe0ffff	  64KB		PCI I/O space
+ffffffbffbc00000	ffffffbffbdfffff	   2MB		earlyprintk device
 
-ffffffbffbe10000	ffffffbcffffffff	  ~2MB		[guard]
+ffffffbffbe00000	ffffffbffbffffff	   2MB		[guard]
 
 ffffffbffc000000	ffffffbfffffffff	  64MB		modules
 
@@ -60,11 +62,13 @@ fffffdfc00000000	fffffdfdffffffff	   8GB		vmemmap
 
 fffffdfe00000000	fffffdfffbbfffff	  ~8GB		[guard, future vmmemap]
 
-fffffdfffbc00000	fffffdfffbdfffff	   2MB		earlyprintk device
+fffffdfffa000000	fffffdfffaffffff	  16MB		PCI I/O space
+
+fffffdfffb000000	fffffdfffbbfffff	  12MB		[guard]
 
-fffffdfffbe00000	fffffdfffbe0ffff	  64KB		PCI I/O space
+fffffdfffbc00000	fffffdfffbdfffff	   2MB		earlyprintk device
 
-fffffdfffbe10000	fffffdfffbffffff	  ~2MB		[guard]
+fffffdfffbe00000	fffffdfffbffffff	   2MB		[guard]
 
 fffffdfffc000000	fffffdffffffffff	  64MB		modules
 
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 4cc813e..7846a6b 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -121,7 +121,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
  *  I/O port access primitives.
  */
 #define IO_SPACE_LIMIT		0xffff
-#define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_2M))
+#define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_32M))
 
 static inline u8 inb(unsigned long addr)
 {
-- 
1.9.0

^ permalink raw reply related

* [PATCH v2 3/3] arm64: Add architecture support for PCI
From: Liviu Dudau @ 2014-02-27 13:09 UTC (permalink / raw)
  To: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel
  Cc: LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393506599-11561-1-git-send-email-Liviu.Dudau@arm.com>

Use the generic host bridge functions to provide support for
PCI Express on arm64. There is no support for ISA memory.

Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>

 create mode 100644 arch/arm64/include/asm/pci.h
 create mode 100644 arch/arm64/kernel/pci.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 27bbcfc..d1c8568 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -62,7 +62,7 @@ config MMU
 	def_bool y
 
 config NO_IOPORT
-	def_bool y
+	def_bool y if !PCI
 
 config STACKTRACE_SUPPORT
 	def_bool y
@@ -134,6 +134,23 @@ menu "Bus support"
 config ARM_AMBA
 	bool
 
+config PCI
+	bool "PCI support"
+	help
+	  This feature enables support for PCIe bus system. If you say Y
+	  here, the kernel will include drivers and infrastructure code
+	  to support PCIe bus devices.
+
+config PCI_DOMAINS
+	def_bool PCI
+
+config PCI_SYSCALL
+	def_bool PCI
+
+source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+source "drivers/pci/hotplug/Kconfig"
+
 endmenu
 
 menu "Kernel Features"
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 71c53ec..46924bc 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -26,6 +26,7 @@ generic-y += mman.h
 generic-y += msgbuf.h
 generic-y += mutex.h
 generic-y += pci.h
+generic-y += pci-bridge.h
 generic-y += poll.h
 generic-y += posix_types.h
 generic-y += resource.h
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 7846a6b..67463a5 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -120,7 +120,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 /*
  *  I/O port access primitives.
  */
-#define IO_SPACE_LIMIT		0xffff
+#define arch_has_dev_port()	(1)
+#define IO_SPACE_LIMIT		0x1ffffff
 #define PCI_IOBASE		((void __iomem *)(MODULES_VADDR - SZ_32M))
 
 static inline u8 inb(unsigned long addr)
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
new file mode 100644
index 0000000..3edf9e0
--- /dev/null
+++ b/arch/arm64/include/asm/pci.h
@@ -0,0 +1,47 @@
+#ifndef __ASM_PCI_H
+#define __ASM_PCI_H
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm-generic/pci-bridge.h>
+#include <asm-generic/pci-dma-compat.h>
+
+#define PCIBIOS_MIN_IO		0x1000
+#define PCIBIOS_MIN_MEM		0
+
+/*
+ * Set to 1 if the kernel should re-assign all PCI bus numbers
+ */
+#define pcibios_assign_all_busses() \
+	(pci_has_flag(PCI_REASSIGN_ALL_BUS))
+
+/*
+ * PCI address space differs from physical memory address space
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+
+extern int isa_dma_bridge_buggy;
+
+static inline int pci_domain_nr(struct pci_bus *bus)
+{
+	struct pci_host_bridge *bridge = to_pci_host_bridge(bus->bridge);
+
+	if (bridge)
+		return bridge->domain_nr;
+
+	return 0;
+}
+
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+	return pci_domain_nr(bus);
+}
+
+extern unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr);
+
+#endif  /* __KERNEL__ */
+#endif  /* __ASM_PCI_H */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 2d4554b..64fc479 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
 arm64-obj-$(CONFIG_EARLY_PRINTK)	+= early_printk.o
 arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)	+= sleep.o suspend.o
 arm64-obj-$(CONFIG_JUMP_LABEL)		+= jump_label.o
+arm64-obj-$(CONFIG_PCI)			+= pci.o
 
 obj-y					+= $(arm64-obj-y) vdso/
 obj-m					+= $(arm64-obj-m)
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
new file mode 100644
index 0000000..496df41
--- /dev/null
+++ b/arch/arm64/kernel/pci.c
@@ -0,1 +1,126 @@
+/*
+ * Code borrowed from powerpc/kernel/pci-common.c
+ *
+ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
+ * Copyright (C) 2014 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of_pci.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+
+#include <asm/pci-bridge.h>
+
+
+/*
+ * Called after each bus is probed, but before its children are examined
+ */
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+	struct pci_dev *dev;
+	struct resource *res;
+	int i;
+
+	if (!pci_is_root_bus(bus)) {
+		pci_read_bridge_bases(bus);
+
+		pci_bus_for_each_resource(bus, res, i) {
+			if (!res || !res->flags || res->parent)
+				continue;
+
+			/*
+			 * If we are going to reassign everything, we can
+			 * shrink the P2P resource to have zero size to
+			 * save space
+			 */
+			if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
+				res->flags |= IORESOURCE_UNSET;
+				res->start = 0;
+				res->end = -1;
+				continue;
+			}
+		}
+	}
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		/* Ignore fully discovered devices */
+		if (dev->is_added)
+			continue;
+
+		set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
+
+		/* Read default IRQs and fixup if necessary */
+		dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
+	}
+}
+EXPORT_SYMBOL(pcibios_fixup_bus);
+
+/*
+ * We don't have to worry about legacy ISA devices, so nothing to do here
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+				resource_size_t size, resource_size_t align)
+{
+	return ALIGN(res->start, align);
+}
+EXPORT_SYMBOL(pcibios_align_resource);
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	return pci_enable_resources(dev, mask);
+}
+
+void pcibios_fixup_bridge_ranges(struct list_head *resources)
+{
+}
+
+#define IO_SPACE_PAGES	((IO_SPACE_LIMIT + 1) / PAGE_SIZE)
+static DECLARE_BITMAP(pci_iospace, IO_SPACE_PAGES);
+
+unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr)
+{
+	unsigned long start, len, virt_start;
+	int err;
+
+	if (res->end > IO_SPACE_LIMIT)
+		return -EINVAL;
+
+	/*
+	 * try finding free space for the whole size first,
+	 * fall back to 64K if not available
+	 */
+	len = resource_size(res);
+	start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
+				res->start / PAGE_SIZE, len / PAGE_SIZE, 0);
+	if (start == IO_SPACE_PAGES && len > SZ_64K) {
+		len = SZ_64K;
+		start = 0;
+		start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
+					start, len / PAGE_SIZE, 0);
+	}
+
+	/* no 64K area found */
+	if (start == IO_SPACE_PAGES)
+		return -ENOMEM;
+
+	/* ioremap physical aperture to virtual aperture */
+	virt_start = start * PAGE_SIZE + (unsigned long)PCI_IOBASE;
+	err = ioremap_page_range(virt_start, virt_start + len,
+				phys_addr, __pgprot(PROT_DEVICE_nGnRE));
+	if (err)
+		return err;
+
+	bitmap_set(pci_iospace, start, len / PAGE_SIZE);
+
+	/* return io_offset */
+	return start * PAGE_SIZE - res->start;
+}
-- 
1.9.0

^ permalink raw reply related

* Re: [RFC PATCH v4 3/8] staging: imx-drm: Document updated imx-drm device tree bindings
From: Tomi Valkeinen @ 2014-02-27 13:16 UTC (permalink / raw)
  To: Russell King - ARM Linux, Laurent Pinchart
  Cc: devel, devicetree, kernel, David Airlie, Greg Kroah-Hartman,
	dri-devel, Philipp Zabel, Grant Likely, Shawn Guo, Fabio Estevam,
	linux-arm-kernel
In-Reply-To: <20140227115652.GI21483@n2100.arm.linux.org.uk>


[-- Attachment #1.1: Type: text/plain, Size: 649 bytes --]

On 27/02/14 13:56, Russell King - ARM Linux wrote:

>> Is there even need for such a master device? You can find all the
>> connected display devices from any single display device, by just
>> following the endpoint links.
> 
> Please read up on what has been discussed over previous years:
> 
> http://lists.freedesktop.org/archives/dri-devel/2013-July/041159.html

Thanks, that was an interesting thread. Too bad I missed it, it was
during the holiday season. And seems Laurent missed it also, as he
didn't make any replies.

The thread seemed to go over the very same things that had already been
discussed with CDF.

 Tomi



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

[-- Attachment #2: Type: text/plain, Size: 176 bytes --]

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Re: [PATCH v2 1/4] pci: OF: Fix the conversion of IO ranges into IO resources.
From: Arnd Bergmann @ 2014-02-27 13:20 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel, LKML,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, LAKML
In-Reply-To: <1393506402-11474-2-git-send-email-Liviu.Dudau-5wv7dgnIgG8@public.gmane.org>

On Thursday 27 February 2014 13:06:39 Liviu Dudau wrote:
> +       res->flags = range->flags;
> +       if (res->flags & IORESOURCE_IO) {
> +               unsigned long port;
> +               port = pci_address_to_pio(range->pci_addr);
> +               if (port == (unsigned long)-1) {
> +                       res->start = (resource_size_t)OF_BAD_ADDR;
> +                       res->end = (resource_size_t)OF_BAD_ADDR;
> +                       return;
> +               }
> 

I think this conflicts with the way that pci_address_to_pio() is
defined on powerpc, where it expects a CPU address as the input,
not a PCI i/o address.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 2/4] pci: Create pci_host_bridge before its associated bus in pci_create_root_bus.
From: Arnd Bergmann @ 2014-02-27 13:22 UTC (permalink / raw)
  To: linaro-kernel
  Cc: Liviu Dudau, linux-pci, Bjorn Helgaas, Catalin Marinas,
	Will Deacon, devicetree@vger.kernel.org, LKML, LAKML
In-Reply-To: <1393506402-11474-3-git-send-email-Liviu.Dudau@arm.com>

On Thursday 27 February 2014 13:06:40 Liviu Dudau wrote:
> Before commit 7b5436635800 the pci_host_bridge was created before the root bus.
> As that commit has added a needless dependency on the bus for pci_alloc_host_bridge()
> the creation order has been changed for no good reason. Revert the order of
> creation as we are going to depend on the pci_host_bridge structure to retrieve the
> domain number of the root bus.
> 
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> 

Looks good to me.

	Arnd

^ permalink raw reply

* Re: [PATCH v2 1/4] pci: OF: Fix the conversion of IO ranges into IO resources.
From: Andrew Murray @ 2014-02-27 13:22 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: linux-pci, Bjorn Helgaas, Catalin Marinas, Will Deacon,
	linaro-kernel, LKML, devicetree@vger.kernel.org, LAKML
In-Reply-To: <1393506402-11474-2-git-send-email-Liviu.Dudau@arm.com>

On 27 February 2014 13:06, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
>
> The ranges property for a host bridge controller in DT describes
> the mapping between the PCI bus address and the CPU physical address.
> The resources framework however expects that the IO resources start
> at a pseudo "port" address 0 (zero) and have a maximum size of 64kb.

Is this just in the case of ARM? (I've tried to keep up with the
conversation, but apologies if I've misunderstood).

> The conversion from pci ranges to resources failed to take that into
> account.
>
> In the process move the function into drivers/of/address.c as it
> now depends on pci_address_to_pio() code.
>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>
> diff --git a/drivers/of/address.c b/drivers/of/address.c
> index 1a54f1f..7cf2b16 100644
> --- a/drivers/of/address.c
> +++ b/drivers/of/address.c
> @@ -719,3 +719,34 @@ void __iomem *of_iomap(struct device_node *np, int index)
>         return ioremap(res.start, resource_size(&res));
>  }
>  EXPORT_SYMBOL(of_iomap);
> +
> +/**
> + * of_pci_range_to_resource - Create a resource from an of_pci_range
> + * @range:     the PCI range that describes the resource
> + * @np:                device node where the range belongs to
> + * @res:       pointer to a valid resource that will be updated to
> + *              reflect the values contained in the range.
> + * Note that if the range is an IO range, the resource will be converted
> + * using pci_address_to_pio() which can fail if it is called to early or
> + * if the range cannot be matched to any host bridge IO space.
> + */
> +void of_pci_range_to_resource(struct of_pci_range *range,
> +       struct device_node *np, struct resource *res)
> +{
> +       res->flags = range->flags;
> +       if (res->flags & IORESOURCE_IO) {
> +               unsigned long port;
> +               port = pci_address_to_pio(range->pci_addr);

Is this likely to break existing users of of_pci_range_to_resource?

For example arch/mips: IO_SPACE_LIMIT defaults to 0xffff and there is
no overridden implementation for pci_address_to_pio, therefore this
will set res->start to OF_BAD_ADDR whereas previously it would have
been the CPU address for I/O (assuming the cpu_addr was previously >
64K).

I have no idea if I/O previously worked for mips, but this patch seems
to change that behavior. It may be a similar story for microblaze and
powerpc.

Andrew Murray

> +               if (port == (unsigned long)-1) {
> +                       res->start = (resource_size_t)OF_BAD_ADDR;
> +                       res->end = (resource_size_t)OF_BAD_ADDR;
> +                       return;
> +               }
> +               res->start = port;
> +       } else {
> +               res->start = range->cpu_addr;
> +       }
> +       res->end = res->start + range->size - 1;
> +       res->parent = res->child = res->sibling = NULL;
> +       res->name = np->full_name;
> +}
> diff --git a/include/linux/of_address.h b/include/linux/of_address.h
> index 5f6ed6b..a667762 100644
> --- a/include/linux/of_address.h
> +++ b/include/linux/of_address.h
> @@ -23,17 +23,8 @@ struct of_pci_range {
>  #define for_each_of_pci_range(parser, range) \
>         for (; of_pci_range_parser_one(parser, range);)
>
> -static inline void of_pci_range_to_resource(struct of_pci_range *range,
> -                                           struct device_node *np,
> -                                           struct resource *res)
> -{
> -       res->flags = range->flags;
> -       res->start = range->cpu_addr;
> -       res->end = range->cpu_addr + range->size - 1;
> -       res->parent = res->child = res->sibling = NULL;
> -       res->name = np->full_name;
> -}
> -
> +extern void of_pci_range_to_resource(struct of_pci_range *range,
> +               struct device_node *np, struct resource *res);
>  /* Translate a DMA address from device space to CPU space */
>  extern u64 of_translate_dma_address(struct device_node *dev,
>                                     const __be32 *in_addr);
> --
> 1.9.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 3/4] pci: Introduce a domain number for pci_host_bridge.
From: Arnd Bergmann @ 2014-02-27 13:22 UTC (permalink / raw)
  To: linaro-kernel
  Cc: Liviu Dudau, linux-pci, Bjorn Helgaas, Catalin Marinas,
	Will Deacon, devicetree@vger.kernel.org, LKML, LAKML
In-Reply-To: <1393506402-11474-4-git-send-email-Liviu.Dudau@arm.com>

On Thursday 27 February 2014 13:06:41 Liviu Dudau wrote:
> Make it easier to discover the domain number of a bus by storing
> the number in pci_host_bridge for the root bus. Several architectures
> have their own way of storing this information, so it makes sense
> to try to unify the code. While at this, add a new function that
> creates a root bus in a given domain and make pci_create_root_bus()
> a wrapper around this function.
> 
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply

* Re: [RFC PATCH v4 3/8] staging: imx-drm: Document updated imx-drm device tree bindings
From: Rob Clark @ 2014-02-27 13:23 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: devel, devicetree@vger.kernel.org, kernel@pengutronix.de,
	Greg Kroah-Hartman, dri-devel@lists.freedesktop.org,
	Tomi Valkeinen, Philipp Zabel, Grant Likely,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20140227130020.GJ21483@n2100.arm.linux.org.uk>

On Thu, Feb 27, 2014 at 8:00 AM, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Thu, Feb 27, 2014 at 02:06:25PM +0100, Philipp Zabel wrote:
>> For the i.MX6 display subsystem there is no clear single master device,
>> and the physical configuration changes across the SoC family. The
>> i.MX6Q/i.MX6D SoCs have two separate display controller devices IPU1 and
>> IPU2, with two output ports each.
>
> Not also forgetting that there's another scenario too: you may wish
> to drive IPU1 and IPU2 as two completely separate display subsystems
> in some hardware, but as a combined display subsystem in others.
>
> Here's another scenario.  You may have these two IPUs on the SoC, but
> there's only one display output.  You want to leave the second IPU
> disabled, as you wouldn't want it to be probed or even exposed to
> userland.

I agree with Russell here, purely hw description is not always going
to be enough information to know how to assemble a bag of parts into a
system.

Maybe there is some way we should be splitting this "meta" description
into different dt files or something like this (?) to make it easier
for alternative configurations, but if the hw description alone is not
enough information for the drivers to know what to do, some (for lack
of a better word) "use-case" configuration is needed, and that has to
go *somewhere*... better to put it in DT than hard code it in the
driver.

BR,
-R

> On the face of it, the top-level super-device node doesn't look very
> hardware-y, but it actually is - it's about how a board uses the
> hardware provided.  This is entirely in keeping with the spirit of DT,
> which is to describe what hardware is present and how it's connected
> together, whether it be at the chip or board level.
>
> If this wasn't the case, we wouldn't even attempt to describe what devices
> we have on which I2C buses - we'd just list the hardware on the board
> without giving any information about how it's wired together.
>
> This is no different - however, it doesn't have (and shouldn't) be
> subsystem specific... but - and this is the challenge we then face - how
> do you decide that on one board with a single zImage kernel, with both
> DRM and fbdev built-in, whether to use the DRM interfaces or the fbdev
> interfaces?  We could have both matching the same compatible string, but
> we'd also need some way to tell each other that they're not allowed to
> bind.
>
> Before anyone argues against "it isn't hardware-y", stop and think.
> What if I design a board with two Epson LCD controllers on board and
> put a muxing arrangement on their output.  Is that one or two devices?
> What if I want them to operate as one combined system?  What if I have
> two different LCD controllers on a board.  How is this any different
> from the two independent IPU hardware blocks integrated inside an iMX6
> SoC with a muxing arrangement on their output?
>
> It's very easy to look at a SoC and make the wrong decision...
>
> --
> FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
> improving, and getting towards what was expected from it.
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v2 3/3] arm64: Add architecture support for PCI
From: Andrew Murray @ 2014-02-27 13:35 UTC (permalink / raw)
  To: Liviu Dudau
  Cc: devicetree@vger.kernel.org, linaro-kernel, linux-pci, Will Deacon,
	LKML, Catalin Marinas, Bjorn Helgaas, LAKML
In-Reply-To: <1393506599-11561-4-git-send-email-Liviu.Dudau@arm.com>

On 27 February 2014 13:09, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> Use the generic host bridge functions to provide support for
> PCI Express on arm64. There is no support for ISA memory.
>
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
>
>  create mode 100644 arch/arm64/include/asm/pci.h
>  create mode 100644 arch/arm64/kernel/pci.c
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 27bbcfc..d1c8568 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -62,7 +62,7 @@ config MMU
>         def_bool y
>
>  config NO_IOPORT
> -       def_bool y
> +       def_bool y if !PCI
>
>  config STACKTRACE_SUPPORT
>         def_bool y
> @@ -134,6 +134,23 @@ menu "Bus support"
>  config ARM_AMBA
>         bool
>
> +config PCI
> +       bool "PCI support"
> +       help
> +         This feature enables support for PCIe bus system. If you say Y
> +         here, the kernel will include drivers and infrastructure code
> +         to support PCIe bus devices.
> +
> +config PCI_DOMAINS
> +       def_bool PCI
> +
> +config PCI_SYSCALL
> +       def_bool PCI
> +
> +source "drivers/pci/Kconfig"
> +source "drivers/pci/pcie/Kconfig"
> +source "drivers/pci/hotplug/Kconfig"
> +
>  endmenu
>
>  menu "Kernel Features"
> diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
> index 71c53ec..46924bc 100644
> --- a/arch/arm64/include/asm/Kbuild
> +++ b/arch/arm64/include/asm/Kbuild
> @@ -26,6 +26,7 @@ generic-y += mman.h
>  generic-y += msgbuf.h
>  generic-y += mutex.h
>  generic-y += pci.h
> +generic-y += pci-bridge.h
>  generic-y += poll.h
>  generic-y += posix_types.h
>  generic-y += resource.h
> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
> index 7846a6b..67463a5 100644
> --- a/arch/arm64/include/asm/io.h
> +++ b/arch/arm64/include/asm/io.h
> @@ -120,7 +120,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
>  /*
>   *  I/O port access primitives.
>   */
> -#define IO_SPACE_LIMIT         0xffff
> +#define arch_has_dev_port()    (1)
> +#define IO_SPACE_LIMIT         0x1ffffff
>  #define PCI_IOBASE             ((void __iomem *)(MODULES_VADDR - SZ_32M))
>
>  static inline u8 inb(unsigned long addr)
> diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h
> new file mode 100644
> index 0000000..3edf9e0
> --- /dev/null
> +++ b/arch/arm64/include/asm/pci.h
> @@ -0,0 +1,47 @@
> +#ifndef __ASM_PCI_H
> +#define __ASM_PCI_H
> +#ifdef __KERNEL__
> +
> +#include <linux/types.h>
> +#include <linux/slab.h>
> +#include <linux/dma-mapping.h>
> +
> +#include <asm/io.h>
> +#include <asm-generic/pci-bridge.h>
> +#include <asm-generic/pci-dma-compat.h>
> +
> +#define PCIBIOS_MIN_IO         0x1000
> +#define PCIBIOS_MIN_MEM                0
> +
> +/*
> + * Set to 1 if the kernel should re-assign all PCI bus numbers
> + */
> +#define pcibios_assign_all_busses() \
> +       (pci_has_flag(PCI_REASSIGN_ALL_BUS))
> +
> +/*
> + * PCI address space differs from physical memory address space
> + */
> +#define PCI_DMA_BUS_IS_PHYS    (0)
> +
> +extern int isa_dma_bridge_buggy;
> +
> +static inline int pci_domain_nr(struct pci_bus *bus)
> +{
> +       struct pci_host_bridge *bridge = to_pci_host_bridge(bus->bridge);
> +
> +       if (bridge)
> +               return bridge->domain_nr;
> +
> +       return 0;
> +}
> +
> +static inline int pci_proc_domain(struct pci_bus *bus)
> +{
> +       return pci_domain_nr(bus);
> +}
> +
> +extern unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr);
> +
> +#endif  /* __KERNEL__ */
> +#endif  /* __ASM_PCI_H */
> diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
> index 2d4554b..64fc479 100644
> --- a/arch/arm64/kernel/Makefile
> +++ b/arch/arm64/kernel/Makefile
> @@ -20,6 +20,7 @@ arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o
>  arm64-obj-$(CONFIG_EARLY_PRINTK)       += early_printk.o
>  arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND)  += sleep.o suspend.o
>  arm64-obj-$(CONFIG_JUMP_LABEL)         += jump_label.o
> +arm64-obj-$(CONFIG_PCI)                        += pci.o
>
>  obj-y                                  += $(arm64-obj-y) vdso/
>  obj-m                                  += $(arm64-obj-m)
> diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
> new file mode 100644
> index 0000000..496df41
> --- /dev/null
> +++ b/arch/arm64/kernel/pci.c
> @@ -0,1 +1,126 @@
> +/*
> + * Code borrowed from powerpc/kernel/pci-common.c
> + *
> + * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
> + * Copyright (C) 2014 ARM Ltd.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/of_pci.h>
> +#include <linux/of_platform.h>
> +#include <linux/slab.h>
> +
> +#include <asm/pci-bridge.h>
> +
> +
> +/*
> + * Called after each bus is probed, but before its children are examined
> + */
> +void pcibios_fixup_bus(struct pci_bus *bus)
> +{
> +       struct pci_dev *dev;
> +       struct resource *res;
> +       int i;
> +
> +       if (!pci_is_root_bus(bus)) {
> +               pci_read_bridge_bases(bus);
> +
> +               pci_bus_for_each_resource(bus, res, i) {
> +                       if (!res || !res->flags || res->parent)
> +                               continue;
> +
> +                       /*
> +                        * If we are going to reassign everything, we can
> +                        * shrink the P2P resource to have zero size to
> +                        * save space
> +                        */
> +                       if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) {
> +                               res->flags |= IORESOURCE_UNSET;
> +                               res->start = 0;
> +                               res->end = -1;
> +                               continue;
> +                       }
> +               }
> +       }
> +
> +       list_for_each_entry(dev, &bus->devices, bus_list) {
> +               /* Ignore fully discovered devices */
> +               if (dev->is_added)
> +                       continue;
> +
> +               set_dev_node(&dev->dev, pcibus_to_node(dev->bus));
> +
> +               /* Read default IRQs and fixup if necessary */
> +               dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
> +       }
> +}
> +EXPORT_SYMBOL(pcibios_fixup_bus);
> +
> +/*
> + * We don't have to worry about legacy ISA devices, so nothing to do here
> + */
> +resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> +                               resource_size_t size, resource_size_t align)
> +{
> +       return ALIGN(res->start, align);
> +}
> +EXPORT_SYMBOL(pcibios_align_resource);
> +
> +int pcibios_enable_device(struct pci_dev *dev, int mask)
> +{
> +       return pci_enable_resources(dev, mask);
> +}

It looks like you will soon be able to remove this and rely on the
shinny new weak implementation of pcibios_enable_device now
(http://www.spinics.net/lists/linux-pci/msg29387.html)

Andrew Murray

> +
> +void pcibios_fixup_bridge_ranges(struct list_head *resources)
> +{
> +}
> +
> +#define IO_SPACE_PAGES ((IO_SPACE_LIMIT + 1) / PAGE_SIZE)
> +static DECLARE_BITMAP(pci_iospace, IO_SPACE_PAGES);
> +
> +unsigned long pci_ioremap_io(const struct resource *res, phys_addr_t phys_addr)
> +{
> +       unsigned long start, len, virt_start;
> +       int err;
> +
> +       if (res->end > IO_SPACE_LIMIT)
> +               return -EINVAL;
> +
> +       /*
> +        * try finding free space for the whole size first,
> +        * fall back to 64K if not available
> +        */
> +       len = resource_size(res);
> +       start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
> +                               res->start / PAGE_SIZE, len / PAGE_SIZE, 0);
> +       if (start == IO_SPACE_PAGES && len > SZ_64K) {
> +               len = SZ_64K;
> +               start = 0;
> +               start = bitmap_find_next_zero_area(pci_iospace, IO_SPACE_PAGES,
> +                                       start, len / PAGE_SIZE, 0);
> +       }
> +
> +       /* no 64K area found */
> +       if (start == IO_SPACE_PAGES)
> +               return -ENOMEM;
> +
> +       /* ioremap physical aperture to virtual aperture */
> +       virt_start = start * PAGE_SIZE + (unsigned long)PCI_IOBASE;
> +       err = ioremap_page_range(virt_start, virt_start + len,
> +                               phys_addr, __pgprot(PROT_DEVICE_nGnRE));
> +       if (err)
> +               return err;
> +
> +       bitmap_set(pci_iospace, start, len / PAGE_SIZE);
> +
> +       /* return io_offset */
> +       return start * PAGE_SIZE - res->start;
> +}
> --
> 1.9.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2 4/4] pci: Add support for creating a generic host_bridge from device tree
From: Arnd Bergmann @ 2014-02-27 13:38 UTC (permalink / raw)
  To: linaro-kernel, Benjamin Herrenschmidt
  Cc: Liviu Dudau, linux-pci, Bjorn Helgaas, Catalin Marinas,
	Will Deacon, devicetree@vger.kernel.org, LKML, LAKML
In-Reply-To: <1393506402-11474-5-git-send-email-Liviu.Dudau@arm.com>

On Thursday 27 February 2014 13:06:42 Liviu Dudau wrote:
> Several platforms use a rather generic version of parsing
> the device tree to find the host bridge ranges. Move the common code
> into the generic PCI code and use it to create a pci_host_bridge
> structure that can be used by arch code.
> 
> Based on early attempts by Andrew Murray to unify the code.
> Used powerpc and microblaze PCI code as starting point.
> 
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>

Please add Benjamin Herrenschmidt to Cc here, I think it would be helpful
to get his input so we can make this work on powerpc as well.

> diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c
> index 06ace62..feb8436 100644
> --- a/drivers/pci/host-bridge.c
> +++ b/drivers/pci/host-bridge.c
> @@ -6,9 +6,13 @@
>  #include <linux/init.h>
>  #include <linux/pci.h>
>  #include <linux/module.h>
> +#include <linux/of_address.h>
> +#include <linux/of_pci.h>
>  
>  #include "pci.h"
>  
> +static int domain_nr;
> +

For correctness, I think you want an 'atomic_t' here and use
atomic_inc_return() to get a new value.

>  static struct pci_bus *find_pci_root_bus(struct pci_bus *bus)
>  {
>  	while (bus->parent)
> @@ -91,3 +95,133 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res,
>  	res->end = region->end + offset;
>  }
>  EXPORT_SYMBOL(pcibios_bus_to_resource);
> +
> +/**
> + * pci_host_bridge_of_get_ranges - Parse PCI host bridge resources from DT
> + * @dev: device node of the host bridge having the range property
> + * @resources: list where the range of resources will be added after DT parsing
> + * @io_base: pointer to a variable that will contain the physical address for
> + * the start of the I/O range.
> + *
> + * If this function returns an error then the @resources list will be freed.
> + *
> + * This function will parse the "ranges" property of a PCI host bridge device
> + * node and setup the resource mapping based on its content. It is expected
> + * that the property conforms with the Power ePAPR document.
> + *
> + * Each architecture is then offered the chance of applying their own
> + * filtering of pci_host_bridge_windows based on their own restrictions by
> + * calling pcibios_fixup_bridge_ranges(). The filtered list of windows
> + * can then be used when creating a pci_host_bridge structure.
> + */
> +static int pci_host_bridge_of_get_ranges(struct device_node *dev,
> +		struct list_head *resources, resource_size_t *io_base)
> +{
> +	struct resource *res;
> +	struct of_pci_range range;
> +	struct of_pci_range_parser parser;
> +	int err;
> +
> +	pr_info("PCI host bridge %s ranges:\n", dev->full_name);
> +
> +	/* Check for ranges property */
> +	err = of_pci_range_parser_init(&parser, dev);
> +	if (err)
> +		return err;
> +
> +	pr_debug("Parsing ranges property...\n");
> +	for_each_of_pci_range(&parser, &range) {
> +		/* Read next ranges element */
> +		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
> +				range.pci_space, range.pci_addr);
> +		pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
> +					range.cpu_addr, range.size);
> +
> +		/*
> +		 * If we failed translation or got a zero-sized region
> +		 * then skip this range
> +		 */
> +		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
> +			continue;
> +
> +		res = kzalloc(sizeof(struct resource), GFP_KERNEL);
> +		if (!res) {
> +			err = -ENOMEM;
> +			goto bridge_ranges_nomem;
> +		}
> +
> +		of_pci_range_to_resource(&range, dev, res);
> +
> +		if (resource_type(res) == IORESOURCE_IO)
> +			*io_base = range.cpu_addr;
> +
> +		pci_add_resource_offset(resources, res,
> +				res->start - range.pci_addr);
> +	}

This is not the correct resource for I/O space at all. Please talk
to Will, I've been over this with him in detail and he probably
understands it now. I assume you are both working in the same
building.

Since this is common PCI code, you could also decide to open-code
the pci_add_resource_offset() function. If you don't do that, I
think you have a memory leak for the resources that you can avoid
by allocating the resource and pci_host_bridge_window structures
together with a single kzalloc.

> +	/* Apply architecture specific fixups for the ranges */
> +	pcibios_fixup_bridge_ranges(resources);
> +
> +	return 0;
> +
> +bridge_ranges_nomem:
> +	pci_free_resource_list(resources);
> +	return err;
> +}
> +
> +/**
> + * of_create_pci_host_bridge - Create a PCI host bridge structure using
> + * information passed in the DT.
> + * @parent: device owning this host bridge
> + * @ops: pci_ops associated with the host controller
> + * @host_data: opaque data structure used by the host controller.
> + *
> + * returns a pointer to the newly created pci_host_bridge structure, or
> + * NULL if the call failed.
> + *
> + * This function will try to obtain the host bridge domain number by
> + * using of_alias_get_id() call with "pci-domain" as a stem. If that
> + * fails, a local allocator will be used that will put each host bridge
> + * in a new domain.
> + */
> +struct pci_host_bridge *
> +of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops, void *host_data)
> +{
> +	int err, domain, busno;
> +	struct resource bus_range;
> +	struct pci_bus *root_bus;
> +	struct pci_host_bridge *bridge;
> +	resource_size_t io_base;
> +	LIST_HEAD(res);
> +
> +	domain = of_alias_get_id(parent->of_node, "pci-domain");
> +	if (domain == -ENODEV)
> +		domain = domain_nr++;
> +
> +	err = of_pci_parse_bus_range(parent->of_node, &bus_range);
> +	if (err) {
> +		dev_info(parent, "No bus range for %s, using default [0-255]\n",
> +			parent->of_node->full_name);
> +		bus_range.start = 0;
> +		bus_range.end = 255;
> +		bus_range.flags = IORESOURCE_BUS;
> +	}
> +	busno = bus_range.start;
> +	pci_add_resource(&res, &bus_range);
> +
> +	/* now parse the rest of host bridge bus ranges */
> +	if (pci_host_bridge_of_get_ranges(parent->of_node, &res, &io_base))
> +		return NULL;
> +
> +	/* then create the root bus */
> +	root_bus = pci_create_root_bus_in_domain(parent, domain, busno,
> +						ops, host_data, &res);
> +	if (!root_bus)
> +		return NULL;

Do we have any code that checks for conflicting domain/bus numbers here?
I guess pci_create_root_bus_in_domain() will fail if you have that.

Since pci_create_root_bus_in_domain() is a new function that you just
introduced, it would be helpful to change the calling conventions
so it returns an error pointer instead of NULL upon failing.
of_create_pci_host_bridge() can do the same, but pci_create_root_bus()
should keep returning NULL so we don't have to change all the
callers.

> +	bridge = to_pci_host_bridge(root_bus->bridge);
> +	bridge->io_base = io_base;
> +
> +	return bridge;
> +}
> +EXPORT_SYMBOL_GPL(of_create_pci_host_bridge);
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 1eed009..0c5e269 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -395,6 +395,7 @@ struct pci_host_bridge {
>  	struct device dev;
>  	struct pci_bus *bus;		/* root bus */
>  	int domain_nr;
> +	resource_size_t io_base;	/* physical address for the start of I/O area */
>  	struct list_head windows;	/* pci_host_bridge_windows */
>  	void (*release_fn)(struct pci_host_bridge *);
>  	void *release_data;

What is the io_base used for here?

> @@ -1786,11 +1787,23 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
>  	return bus ? bus->dev.of_node : NULL;
>  }
>  
> +struct pci_host_bridge *
> +of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops,
> +			void *host_data);
> +
> +void pcibios_fixup_bridge_ranges(struct list_head *resources);
>  #else /* CONFIG_OF */
>  static inline void pci_set_of_node(struct pci_dev *dev) { }
>  static inline void pci_release_of_node(struct pci_dev *dev) { }
>  static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
>  static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
> +
> +static inline struct pci_host_bridge *
> +pci_host_bridge_of_init(struct device *parent, struct pci_ops *ops,
> +			void *host_data)
> +{
> +	return NULL;
> +}
>  #endif  /* CONFIG_OF */
>  
>  #ifdef CONFIG_EEH
> 

^ permalink raw reply

* Re: [RFC PATCH v4 3/8] staging: imx-drm: Document updated imx-drm device tree bindings
From: Russell King - ARM Linux @ 2014-02-27 13:43 UTC (permalink / raw)
  To: Tomi Valkeinen
  Cc: devel, devicetree, kernel, Greg Kroah-Hartman, dri-devel,
	Laurent Pinchart, Grant Likely, linux-arm-kernel
In-Reply-To: <530F3A93.501@ti.com>

On Thu, Feb 27, 2014 at 03:16:03PM +0200, Tomi Valkeinen wrote:
> On 27/02/14 13:56, Russell King - ARM Linux wrote:
> 
> >> Is there even need for such a master device? You can find all the
> >> connected display devices from any single display device, by just
> >> following the endpoint links.
> > 
> > Please read up on what has been discussed over previous years:
> > 
> > http://lists.freedesktop.org/archives/dri-devel/2013-July/041159.html
> 
> Thanks, that was an interesting thread. Too bad I missed it, it was
> during the holiday season. And seems Laurent missed it also, as he
> didn't make any replies.
> 
> The thread seemed to go over the very same things that had already been
> discussed with CDF.

That may be - but the problem with CDF solving this problem is that it's
wrong.  It's fixing what is in actual fact a *generic* problem in a much
too specific way.  To put it another way, it's forcing everyone to fix
the same problem in their own separate ways because no one is willing to
take a step back and look at the larger picture.

We can see that because ASoC has exactly the same problem - it has to
wait until all devices (DMA, CPU DAIs, codecs etc) are present before it
can initialise, just like DRM.  Can you re-use the CDF solution for ASoC?
No.  Can it be re-used elsewhere in non-display subsystems?  No.

Therefore, CDF is yet another implementation specific solution to a
generic problem which can't be re-used.

Yes, I realise that CDF may do other stuff, but because of the above, it's
a broken solution.

-- 
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

^ permalink raw reply

* Re: [PATCH v2 4/4] pci: Add support for creating a generic host_bridge from device tree
From: Arnd Bergmann @ 2014-02-27 13:48 UTC (permalink / raw)
  To: linaro-kernel
  Cc: devicetree@vger.kernel.org, linux-pci, Benjamin Herrenschmidt,
	Liviu Dudau, LKML, Will Deacon, Catalin Marinas, Bjorn Helgaas,
	LAKML
In-Reply-To: <18746655.qWHLpMg2Yy@wuerfel>

On Thursday 27 February 2014 14:38:32 Arnd Bergmann wrote:
> > +     pr_debug("Parsing ranges property...\n");
> > +     for_each_of_pci_range(&parser, &range) {
> > +             /* Read next ranges element */
> > +             pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
> > +                             range.pci_space, range.pci_addr);
> > +             pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
> > +                                     range.cpu_addr, range.size);
> > +
> > +             /*
> > +              * If we failed translation or got a zero-sized region
> > +              * then skip this range
> > +              */
> > +             if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
> > +                     continue;
> > +
> > +             res = kzalloc(sizeof(struct resource), GFP_KERNEL);
> > +             if (!res) {
> > +                     err = -ENOMEM;
> > +                     goto bridge_ranges_nomem;
> > +             }
> > +
> > +             of_pci_range_to_resource(&range, dev, res);
> > +
> > +             if (resource_type(res) == IORESOURCE_IO)
> > +                     *io_base = range.cpu_addr;
> > +
> > +             pci_add_resource_offset(resources, res,
> > +                             res->start - range.pci_addr);
> > +     }
> 
> This is not the correct resource for I/O space at all. Please talk
> to Will, I've been over this with him in detail and he probably
> understands it now. I assume you are both working in the same
> building.
> 

Sorry, I initially missed part of your changes in patch 1.
I think it's actually correct now.

	Arnd

^ permalink raw reply

* Re: [RFC PATCH v4 3/8] staging: imx-drm: Document updated imx-drm device tree bindings
From: Tomi Valkeinen @ 2014-02-27 13:55 UTC (permalink / raw)
  To: Russell King - ARM Linux, Philipp Zabel
  Cc: devel, devicetree, David Airlie, Greg Kroah-Hartman, dri-devel,
	Laurent Pinchart, kernel, Grant Likely, Shawn Guo,
	linux-arm-kernel
In-Reply-To: <20140227130020.GJ21483@n2100.arm.linux.org.uk>


[-- Attachment #1.1: Type: text/plain, Size: 6092 bytes --]

On 27/02/14 15:00, Russell King - ARM Linux wrote:
> On Thu, Feb 27, 2014 at 02:06:25PM +0100, Philipp Zabel wrote:
>> For the i.MX6 display subsystem there is no clear single master device,
>> and the physical configuration changes across the SoC family. The
>> i.MX6Q/i.MX6D SoCs have two separate display controller devices IPU1 and
>> IPU2, with two output ports each.
> 
> Not also forgetting that there's another scenario too: you may wish
> to drive IPU1 and IPU2 as two completely separate display subsystems
> in some hardware, but as a combined display subsystem in others.
> 
> Here's another scenario.  You may have these two IPUs on the SoC, but
> there's only one display output.  You want to leave the second IPU
> disabled, as you wouldn't want it to be probed or even exposed to
> userland.

I first want to say I don't see anything wrong with such a super node.
As you say, it does describe hardware. But I also want to say that I
still don't see a need for it. Or, maybe more exactly, I don't see a
need for it in general. Maybe there are certain cases where two devices
has to be controlled by a master device. Maybe this one is one of those.

In the imx case, why wouldn't this work, without any master node, with
the IPU nodes separate in the DT data:

- One IPU enabled, one disabled: nothing special here, just set the
other IPU to status="disabled" in the DT data. The driver for the
enabled IPU would register the required DRM entities.

- Two IPUs as separate units: almost the same as above, but both would
independently register the DRM entities.

- Two IPUs in combined mode:

Pick one IPU as the master, and one as slave. Link the IPU nodes in DT
data with phandles, say: master=<&ipu1> on the slave IPU and
slave=<&ipu0> on the master.

The master one will register the DRM entities, and the slave one will
just do what the master says.

As for the probe time "are we ready yet?" problem, the IPU driver can
just delay registering the DRM entities until all the nodes in its graph
have been probed. The component helpers can probably be used here.

> On the face of it, the top-level super-device node doesn't look very
> hardware-y, but it actually is - it's about how a board uses the
> hardware provided.  This is entirely in keeping with the spirit of DT,
> which is to describe what hardware is present and how it's connected
> together, whether it be at the chip or board level.

No disagreement there. I'm mostly put off by the naming. The binding doc
says it's a "DRM master device", compatible with "fsl,imx-drm". Now,
naming may not be the most important thing in the world, but I'd rather
use generic terms, not linux driver stack names.

> If this wasn't the case, we wouldn't even attempt to describe what devices
> we have on which I2C buses - we'd just list the hardware on the board
> without giving any information about how it's wired together.
> 
> This is no different - however, it doesn't have (and shouldn't) be
> subsystem specific... but - and this is the challenge we then face - how
> do you decide that on one board with a single zImage kernel, with both
> DRM and fbdev built-in, whether to use the DRM interfaces or the fbdev
> interfaces?  We could have both matching the same compatible string, but
> we'd also need some way to tell each other that they're not allowed to
> bind.

Yes, that's an annoying problem, we have that on OMAP. It's a clear sign
that our video support is rather messed up.

My opinion is that the fbdev and drm drivers for a single hardware
should be exclusive at compile time. We don't allow multiple drivers for
single device for other subsystems either, do we? Eventually we should
have only one driver for one hardware device.

If that's not possible, then the drivers in question could have an
option to enable or disable themselves, passed via the kernel command
line, so that the user can select which subsystem to use.

> Before anyone argues against "it isn't hardware-y", stop and think.
> What if I design a board with two Epson LCD controllers on board and
> put a muxing arrangement on their output.  Is that one or two devices?
> What if I want them to operate as one combined system?  What if I have
> two different LCD controllers on a board.  How is this any different
> from the two independent IPU hardware blocks integrated inside an iMX6
> SoC with a muxing arrangement on their output?

Well, generally speaking, I think one option is to treat the two
controllers separately and let the userspace handle it. That may or may
not be viable, depending on the hardware, but to me it resembles very
much a PC with two video cards.

If you want the two controllers to operate together more closely, you
always need special code for that particular case.

This is what CDF has been trying to accomplish: individual drivers for
each display entity, connected together via ports and endpoints. Driver
for Epson LCD controller would expose an API, that can be used handle
the LCD controller, it wouldn't make any other demands on how it's used,
is it part of DRM or fbdev, what's before or after it, etc.

Now, and I think this was your point, some kind of master device/driver
is needed to register the required DRM or fbdev entities. Usually that
can be the driver for the SoCs display controller, i.e. the first
display entity in the display pipeline. Sometimes, if it's required to
have multiple devices act together, it may be a driver specifically
designed for that purpose.

So no, I don't have a problem with master device nodes in DT. I have a
problem having pure SW stack nomenclature in the DT data (or even worse,
SW stack entities in the DT data), and I have a problem requiring
everyone to have a master device node if it's only needed for special cases.

And yes, this series is about IMX bindings, not generic ones. And I'm
also fine with requiring everyone to have a master device node, if it
can be shown that it's the only sensible approach.

 Tomi



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

[-- Attachment #2: Type: text/plain, Size: 169 bytes --]

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply

* Re: [PATCH v2 1/4] pci: OF: Fix the conversion of IO ranges into IO resources.
From: Arnd Bergmann @ 2014-02-27 13:58 UTC (permalink / raw)
  To: Andrew Murray
  Cc: Liviu Dudau, linux-pci, Bjorn Helgaas, Catalin Marinas,
	Will Deacon, linaro-kernel, LKML, devicetree@vger.kernel.org,
	LAKML
In-Reply-To: <CAPcvp5EqcKEWoH_--azp+sMykmEWtY5whHG=c9t3sZVXZyAPUg@mail.gmail.com>

On Thursday 27 February 2014 13:22:19 Andrew Murray wrote:
> On 27 February 2014 13:06, Liviu Dudau <Liviu.Dudau@arm.com> wrote:
> >
> > The ranges property for a host bridge controller in DT describes
> > the mapping between the PCI bus address and the CPU physical address.
> > The resources framework however expects that the IO resources start
> > at a pseudo "port" address 0 (zero) and have a maximum size of 64kb.
> 
> Is this just in the case of ARM? (I've tried to keep up with the
> conversation, but apologies if I've misunderstood).

We are a bit inconsistent on Linux. The limitation cited above is
indeed something we came up with on ARM to simplify the possible
cases we have to worry about.

In theory, each PCI host can have its own 4GB I/O space, but in practice
limiting to 64KB is the most reasonable way to use it, and that
still provides plenty of room for I/O registers since most devices
don't use any, and at most a few bytes of address space.

The limit we enforce on Linux is IO_SPACE_LIMIT, which is sometimes set
to 0xffffffff, but I think most if not all of those cases are done so
in error.

> > + * of_pci_range_to_resource - Create a resource from an of_pci_range
> > + * @range:     the PCI range that describes the resource
> > + * @np:                device node where the range belongs to
> > + * @res:       pointer to a valid resource that will be updated to
> > + *              reflect the values contained in the range.
> > + * Note that if the range is an IO range, the resource will be converted
> > + * using pci_address_to_pio() which can fail if it is called to early or
> > + * if the range cannot be matched to any host bridge IO space.
> > + */
> > +void of_pci_range_to_resource(struct of_pci_range *range,
> > +       struct device_node *np, struct resource *res)
> > +{
> > +       res->flags = range->flags;
> > +       if (res->flags & IORESOURCE_IO) {
> > +               unsigned long port;
> > +               port = pci_address_to_pio(range->pci_addr);
> 
> Is this likely to break existing users of of_pci_range_to_resource?
> 
> For example arch/mips: IO_SPACE_LIMIT defaults to 0xffff and there is
> no overridden implementation for pci_address_to_pio, therefore this
> will set res->start to OF_BAD_ADDR whereas previously it would have
> been the CPU address for I/O (assuming the cpu_addr was previously >
> 64K).

The function is used on MIPS, Microblaze and ARM at the moment.
MIPS currently gets it wrong, by calling pci_add_resource_offset
on the CPU address for IORESOURCE_IO, which is the wrong space.
Limiting to IO_SPACE_LIMIT will fix it for the first host bridge
on MIPS, and the second one will still not work, until
IO_SPACE_LIMIT is fixed.

On ARM, I believe we have a couple of drivers that make the
same mistake, and others that at the moment override the
address with range->pci_addr, so they won't change.

Microblaze does 'range.cpu_addr = range.pci_addr;' for the I/O
space window to fix it up. We should probably take a closer look there.

	Arnd

^ permalink raw reply

* Re: [PATCH v2 1/3] Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases.
From: Arnd Bergmann @ 2014-02-27 14:09 UTC (permalink / raw)
  To: linaro-kernel
  Cc: Liviu Dudau, linux-pci, Bjorn Helgaas, Catalin Marinas,
	Will Deacon, devicetree@vger.kernel.org, LKML, LAKML
In-Reply-To: <1393506599-11561-2-git-send-email-Liviu.Dudau@arm.com>

On Thursday 27 February 2014 13:09:57 Liviu Dudau wrote:
> The inline version of ioport_map() that gets used when !CONFIG_GENERIC_IOMAP
> is wrong. It returns a mapped (i.e. virtual) address that can start from
> zero and completely ignores the PCI_IOBASE and IO_SPACE_LIMIT that most
> architectures that use !CONFIG_GENERIC_MAP define.
> 
> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
> 
> 

Acked-by: Arnd Bergmann <arnd@arndb.de>

^ permalink raw reply

* Re: [RFC PATCH v4 3/8] staging: imx-drm: Document updated imx-drm device tree bindings
From: Tomi Valkeinen @ 2014-02-27 14:10 UTC (permalink / raw)
  To: Russell King - ARM Linux
  Cc: devel, devicetree, kernel, David Airlie, Greg Kroah-Hartman,
	dri-devel, Laurent Pinchart, Philipp Zabel, Grant Likely,
	Shawn Guo, linux-arm-kernel
In-Reply-To: <20140227134348.GK21483@n2100.arm.linux.org.uk>


[-- Attachment #1.1: Type: text/plain, Size: 2120 bytes --]

On 27/02/14 15:43, Russell King - ARM Linux wrote:

> That may be - but the problem with CDF solving this problem is that it's
> wrong.  It's fixing what is in actual fact a *generic* problem in a much
> too specific way.  To put it another way, it's forcing everyone to fix
> the same problem in their own separate ways because no one is willing to
> take a step back and look at the larger picture.
> 
> We can see that because ASoC has exactly the same problem - it has to
> wait until all devices (DMA, CPU DAIs, codecs etc) are present before it
> can initialise, just like DRM.  Can you re-use the CDF solution for ASoC?
> No.  Can it be re-used elsewhere in non-display subsystems?  No.
> 
> Therefore, CDF is yet another implementation specific solution to a
> generic problem which can't be re-used.
> 
> Yes, I realise that CDF may do other stuff, but because of the above, it's
> a broken solution.

What? Because CDF didn't fix a particular subproblem for everyone, it's
broken solution? Or did I miss your point?

The main point of CDF is not solving the initialization issue. If that
was the point, it would've been Common Initialization Framework.

The main point of CDF is to allow us to have encoder and panel drivers
that can be used by all platforms, in complex display pipeline setups.
It just also has to have some solution for the initialization problem to
get things working.

In fact, Laurent's CDF version has a solution for init problem which, I
my memory serves me right, is very much similar to yours. It just wasn't
generic. I don't remember if Laurent had a specific master node defined,
but the LCD controller was very much like it. It would be trivial to
change it to use the component helpers.

My solution is different, because I don't like the idea of requiring all
the display components to be up and running to use any of the displays.
In fact, it's not a solution at all for me, as it would prevent displays
working on boards that do not have all the display components installed,
or if the user didn't compile all the drivers.

 Tomi



[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]

[-- Attachment #2: Type: text/plain, Size: 169 bytes --]

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply

* Re: [PATCH RFC 2/5] ASoC: tlv320aic31xx: Add codec driver to Makefile and Kconfig
From: Peter Ujfalusi @ 2014-02-27 14:11 UTC (permalink / raw)
  To: Jyri Sarha, linux-omap, alsa-devel, devicetree, bcousson, broonie
  Cc: detheridge
In-Reply-To: <e5ddd051ac319649d50da0da804750c1c6619edb.1393405575.git.jsarha@ti.com>

On 02/26/2014 11:14 AM, Jyri Sarha wrote:
> Signed-off-by: Jyri Sarha <jsarha@ti.com>
> ---
>  sound/soc/codecs/Kconfig  |    4 ++++
>  sound/soc/codecs/Makefile |    2 ++
>  2 files changed, 6 insertions(+)
> 
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 983d087a..ead9dc5 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -74,6 +74,7 @@ config SND_SOC_ALL_CODECS
>  	select SND_SOC_TLV320AIC23 if I2C
>  	select SND_SOC_TLV320AIC26 if SPI_MASTER
>  	select SND_SOC_TLV320AIC32X4 if I2C
> +	select SND_SOC_TLV320AIC31XX if I2C

You should keep this file ordered.

>  	select SND_SOC_TLV320AIC3X if I2C
>  	select SND_SOC_TPA6130A2 if I2C
>  	select SND_SOC_TLV320DAC33 if I2C
> @@ -364,6 +365,9 @@ config SND_SOC_TLV320AIC26
>  config SND_SOC_TLV320AIC32X4
>  	tristate
>  
> +config SND_SOC_TLV320AIC31XX
> +        tristate
> +
>  config SND_SOC_TLV320AIC3X
>  	tristate
>  
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index bc12676..23f8042 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -64,6 +64,7 @@ snd-soc-stac9766-objs := stac9766.o
>  snd-soc-tas5086-objs := tas5086.o
>  snd-soc-tlv320aic23-objs := tlv320aic23.o
>  snd-soc-tlv320aic26-objs := tlv320aic26.o
> +snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o

Same here.

>  snd-soc-tlv320aic3x-objs := tlv320aic3x.o
>  snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
>  snd-soc-tlv320dac33-objs := tlv320dac33.o
> @@ -194,6 +195,7 @@ obj-$(CONFIG_SND_SOC_STAC9766)	+= snd-soc-stac9766.o
>  obj-$(CONFIG_SND_SOC_TAS5086)	+= snd-soc-tas5086.o
>  obj-$(CONFIG_SND_SOC_TLV320AIC23)	+= snd-soc-tlv320aic23.o
>  obj-$(CONFIG_SND_SOC_TLV320AIC26)	+= snd-soc-tlv320aic26.o
> +obj-$(CONFIG_SND_SOC_TLV320AIC31XX)     += snd-soc-tlv320aic31xx.o

and here

>  obj-$(CONFIG_SND_SOC_TLV320AIC3X)	+= snd-soc-tlv320aic3x.o
>  obj-$(CONFIG_SND_SOC_TLV320AIC32X4)     += snd-soc-tlv320aic32x4.o
>  obj-$(CONFIG_SND_SOC_TLV320DAC33)	+= snd-soc-tlv320dac33.o
> 

-- 
Péter
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v9 0/9] USB Host support for OMAP5 uEVM
From: Roger Quadros @ 2014-02-27 14:18 UTC (permalink / raw)
  To: lee.jones, tony, bcousson
  Cc: devicetree, linux-usb, linux-kernel, balbi, linux-omap,
	linux-arm-kernel, Roger Quadros

Hi,

This patchset brings up USB Host ports and Ethernet port on
the OMAP5 uEVM board.

It also does some cleanup with respect to DT clock binding
for the mfd/omap-usb-host driver.

Please queue these for -next.

Lee,

I've folded some platform data dependent patches with mfd patches
so that they don't break functionality when applied individually.
You can safely pull in all MFD patches (1 to 6).

Tony & Benoit,

Can you please accept patches 7, 8 and 9?

Thanks.

Tested on:
 - OMAP5 uEVM
 - Pandaboard ES Rev. B1
 - Beagleboard-XM Rev C2 (DT + Legacy)
 - Beagleboard Rev C4 (DT + Legacy)

Changelog:

v9:
- Folded dependent platform data patches into MFD patches.

v8:
- Addressed review comments and split patch
  "mfd: omap-usb-host: Get clocks based on hardware revision"
- Removed unnecessary usb host dummy clocks on OMAP3
- Removed unnecessary clock alias "ehci_logic_fck" for OMAP3
- Rebased on 3.14-rc3

v7:
- Rebased on 3.14-rc2
- Removed incompatible ids from DT files and examples

v6:
- Initialized clocks to -ENODEV and split patch 3.

v5:
- Expose all clocks in the DT binding document for mfd:omap-usb-host
and mfd:omap-usb-tll

v4:
- Updated DT binding document for clock binding

v3:
- Rebased on top of 3.13-rc7

cheers,
-roger

---
Roger Quadros (9):
  mfd: omap-usb-host: Get clocks based on hardware revision
  mfd: omap-usb-host: Always fail on clk_get() error
  mfd: omap-usb-host: Use proper clock name instead of alias
  mfd: omap-usb-host: Use clock names as per function for reference
    clocks
  mfd: omap-usb-host: Update DT clock binding information
  mfd: omap-usb-tll: Update DT clock binding information
  ARM: OMAP2+: Remove legacy_init_ehci_clk()
  ARM: dts: OMAP2+: Get rid of incompatible ids for USB host nodes
  usb: omap: dts: Update DT binding example usage

 .../devicetree/bindings/mfd/omap-usb-host.txt      |  23 ++++
 .../devicetree/bindings/mfd/omap-usb-tll.txt       |  10 ++
 .../devicetree/bindings/usb/ehci-omap.txt          |   2 +-
 .../devicetree/bindings/usb/ohci-omap3.txt         |   2 +-
 arch/arm/boot/dts/omap3.dtsi                       |   4 +-
 arch/arm/boot/dts/omap4-panda-common.dtsi          |   8 +-
 arch/arm/boot/dts/omap4.dtsi                       |  10 +-
 arch/arm/boot/dts/omap5-uevm.dts                   |   8 +-
 arch/arm/boot/dts/omap5.dtsi                       |  10 +-
 arch/arm/mach-omap2/cclock3xxx_data.c              |   4 -
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c         |   6 --
 arch/arm/mach-omap2/pdata-quirks.c                 |  16 ---
 drivers/clk/ti/clk-3xxx.c                          |   4 -
 drivers/mfd/omap-usb-host.c                        | 116 ++++++++++++++-------
 14 files changed, 135 insertions(+), 88 deletions(-)

-- 
1.8.3.2

^ permalink raw reply

* [PATCH v9 1/9] mfd: omap-usb-host: Get clocks based on hardware revision
From: Roger Quadros @ 2014-02-27 14:18 UTC (permalink / raw)
  To: lee.jones, tony, bcousson
  Cc: devicetree, Samuel Ortiz, linux-usb, linux-kernel, balbi,
	Tero Kristo, linux-omap, linux-arm-kernel, Roger Quadros
In-Reply-To: <1393510711-4697-1-git-send-email-rogerq@ti.com>

Not all revisions have all the clocks so get the necessary clocks
based on hardware revision.

This should avoid un-necessary clk_get failure messages that were
observed earlier.

Also remove the dummy USB host clocks from the OMAP3 clock data.
These are no longer expected by the driver.

CC: Lee Jones <lee.jones@linaro.org>
CC: Samuel Ortiz <sameo@linux.intel.com>
CC: Tero Kristo <t-kristo@ti.com>
Acked-by: Mike Turquette <mturquette@linaro.org> [OMAP3 CLK data]
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/mach-omap2/cclock3xxx_data.c |  4 ----
 drivers/clk/ti/clk-3xxx.c             |  4 ----
 drivers/mfd/omap-usb-host.c           | 43 ++++++++++++++++++++++++++---------
 3 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c
index 3b05aea..4299a55 100644
--- a/arch/arm/mach-omap2/cclock3xxx_data.c
+++ b/arch/arm/mach-omap2/cclock3xxx_data.c
@@ -3495,10 +3495,6 @@ static struct omap_clk omap3xxx_clks[] = {
 	CLK(NULL,	"dss_tv_fck",	&dss_tv_fck),
 	CLK(NULL,	"dss_96m_fck",	&dss_96m_fck),
 	CLK(NULL,	"dss2_alwon_fck",	&dss2_alwon_fck),
-	CLK(NULL,	"utmi_p1_gfclk",	&dummy_ck),
-	CLK(NULL,	"utmi_p2_gfclk",	&dummy_ck),
-	CLK(NULL,	"xclk60mhsp1_ck",	&dummy_ck),
-	CLK(NULL,	"xclk60mhsp2_ck",	&dummy_ck),
 	CLK(NULL,	"init_60m_fclk",	&dummy_ck),
 	CLK(NULL,	"gpt1_fck",	&gpt1_fck),
 	CLK(NULL,	"aes2_ick",	&aes2_ick),
diff --git a/drivers/clk/ti/clk-3xxx.c b/drivers/clk/ti/clk-3xxx.c
index d323023..0d1750a 100644
--- a/drivers/clk/ti/clk-3xxx.c
+++ b/drivers/clk/ti/clk-3xxx.c
@@ -130,10 +130,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
 	DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
 	DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
 	DT_CLK(NULL, "dss2_alwon_fck", "dss2_alwon_fck"),
-	DT_CLK(NULL, "utmi_p1_gfclk", "dummy_ck"),
-	DT_CLK(NULL, "utmi_p2_gfclk", "dummy_ck"),
-	DT_CLK(NULL, "xclk60mhsp1_ck", "dummy_ck"),
-	DT_CLK(NULL, "xclk60mhsp2_ck", "dummy_ck"),
 	DT_CLK(NULL, "init_60m_fclk", "dummy_ck"),
 	DT_CLK(NULL, "gpt1_fck", "gpt1_fck"),
 	DT_CLK(NULL, "aes2_ick", "aes2_ick"),
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 0c3c9a0..c63bfdf 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -665,22 +665,43 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		goto err_mem;
 	}
 
-	need_logic_fck = false;
+	/* Set all clocks as invalid to begin with */
+	omap->ehci_logic_fck = ERR_PTR(-ENODEV);
+	omap->init_60m_fclk = ERR_PTR(-ENODEV);
+	omap->utmi_p1_gfclk = ERR_PTR(-ENODEV);
+	omap->utmi_p2_gfclk = ERR_PTR(-ENODEV);
+	omap->xclk60mhsp1_ck = ERR_PTR(-ENODEV);
+	omap->xclk60mhsp2_ck = ERR_PTR(-ENODEV);
+
 	for (i = 0; i < omap->nports; i++) {
-		if (is_ehci_phy_mode(i) || is_ehci_tll_mode(i) ||
-			is_ehci_hsic_mode(i))
-				need_logic_fck |= true;
+		omap->utmi_clk[i] = ERR_PTR(-ENODEV);
+		omap->hsic480m_clk[i] = ERR_PTR(-ENODEV);
+		omap->hsic60m_clk[i] = ERR_PTR(-ENODEV);
 	}
 
-	omap->ehci_logic_fck = ERR_PTR(-EINVAL);
-	if (need_logic_fck) {
-		omap->ehci_logic_fck = devm_clk_get(dev, "ehci_logic_fck");
-		if (IS_ERR(omap->ehci_logic_fck)) {
-			ret = PTR_ERR(omap->ehci_logic_fck);
-			dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
+	/* for OMAP3 i.e. USBHS REV1 */
+	if (omap->usbhs_rev == OMAP_USBHS_REV1) {
+		need_logic_fck = false;
+		for (i = 0; i < omap->nports; i++) {
+			if (is_ehci_phy_mode(pdata->port_mode[i]) ||
+			    is_ehci_tll_mode(pdata->port_mode[i]) ||
+			    is_ehci_hsic_mode(pdata->port_mode[i]))
+
+				need_logic_fck |= true;
+		}
+
+		if (need_logic_fck) {
+			omap->ehci_logic_fck = devm_clk_get(dev,
+							    "ehci_logic_fck");
+			if (IS_ERR(omap->ehci_logic_fck)) {
+				ret = PTR_ERR(omap->ehci_logic_fck);
+				dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
+			}
 		}
+		goto initialize;
 	}
 
+	/* for OMAP4+ i.e. USBHS REV2+ */
 	omap->utmi_p1_gfclk = devm_clk_get(dev, "utmi_p1_gfclk");
 	if (IS_ERR(omap->utmi_p1_gfclk)) {
 		ret = PTR_ERR(omap->utmi_p1_gfclk);
@@ -748,7 +769,6 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
-		/* for OMAP3, clk_set_parent fails */
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->xclk60mhsp1_ck);
 		if (ret != 0)
@@ -776,6 +796,7 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 					ret);
 	}
 
+initialize:
 	omap_usbhs_init(dev);
 
 	if (dev->of_node) {
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v9 2/9] mfd: omap-usb-host: Always fail on clk_get() error
From: Roger Quadros @ 2014-02-27 14:18 UTC (permalink / raw)
  To: lee.jones, tony, bcousson
  Cc: devicetree, Samuel Ortiz, linux-usb, linux-kernel, balbi,
	linux-omap, linux-arm-kernel, Roger Quadros
In-Reply-To: <1393510711-4697-1-git-send-email-rogerq@ti.com>

Be more strict and always fail on clk_get() error.

CC: Lee Jones <lee.jones@linaro.org>
CC: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 drivers/mfd/omap-usb-host.c | 62 +++++++++++++++++++++++++++++----------------
 1 file changed, 40 insertions(+), 22 deletions(-)

diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index c63bfdf..c31baa7 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -695,7 +695,8 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 							    "ehci_logic_fck");
 			if (IS_ERR(omap->ehci_logic_fck)) {
 				ret = PTR_ERR(omap->ehci_logic_fck);
-				dev_dbg(dev, "ehci_logic_fck failed:%d\n", ret);
+				dev_err(dev, "ehci_logic_fck failed:%d\n", ret);
+				goto err_mem;
 			}
 		}
 		goto initialize;
@@ -749,51 +750,68 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 		 * them
 		 */
 		omap->utmi_clk[i] = devm_clk_get(dev, clkname);
-		if (IS_ERR(omap->utmi_clk[i]))
-			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-				clkname, PTR_ERR(omap->utmi_clk[i]));
+		if (IS_ERR(omap->utmi_clk[i])) {
+			ret = PTR_ERR(omap->utmi_clk[i]);
+			dev_err(dev, "Failed to get clock : %s : %d\n",
+				clkname, ret);
+			goto err_mem;
+		}
 
 		snprintf(clkname, sizeof(clkname),
 				"usb_host_hs_hsic480m_p%d_clk", i + 1);
 		omap->hsic480m_clk[i] = devm_clk_get(dev, clkname);
-		if (IS_ERR(omap->hsic480m_clk[i]))
-			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-				clkname, PTR_ERR(omap->hsic480m_clk[i]));
+		if (IS_ERR(omap->hsic480m_clk[i])) {
+			ret = PTR_ERR(omap->hsic480m_clk[i]);
+			dev_err(dev, "Failed to get clock : %s : %d\n",
+				clkname, ret);
+			goto err_mem;
+		}
 
 		snprintf(clkname, sizeof(clkname),
 				"usb_host_hs_hsic60m_p%d_clk", i + 1);
 		omap->hsic60m_clk[i] = devm_clk_get(dev, clkname);
-		if (IS_ERR(omap->hsic60m_clk[i]))
-			dev_dbg(dev, "Failed to get clock : %s : %ld\n",
-				clkname, PTR_ERR(omap->hsic60m_clk[i]));
+		if (IS_ERR(omap->hsic60m_clk[i])) {
+			ret = PTR_ERR(omap->hsic60m_clk[i]);
+			dev_err(dev, "Failed to get clock : %s : %d\n",
+				clkname, ret);
+			goto err_mem;
+		}
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->xclk60mhsp1_ck);
-		if (ret != 0)
-			dev_dbg(dev, "xclk60mhsp1_ck set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "xclk60mhsp1_ck set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	} else if (is_ehci_tll_mode(pdata->port_mode[0])) {
 		ret = clk_set_parent(omap->utmi_p1_gfclk,
 					omap->init_60m_fclk);
-		if (ret != 0)
-			dev_dbg(dev, "P0 init_60m_fclk set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "P0 init_60m_fclk set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[1])) {
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 					omap->xclk60mhsp2_ck);
-		if (ret != 0)
-			dev_dbg(dev, "xclk60mhsp2_ck set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "xclk60mhsp2_ck set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	} else if (is_ehci_tll_mode(pdata->port_mode[1])) {
 		ret = clk_set_parent(omap->utmi_p2_gfclk,
 						omap->init_60m_fclk);
-		if (ret != 0)
-			dev_dbg(dev, "P1 init_60m_fclk set parent failed: %d\n",
-					ret);
+		if (ret != 0) {
+			dev_err(dev, "P1 init_60m_fclk set parent failed: %d\n",
+				ret);
+			goto err_mem;
+		}
 	}
 
 initialize:
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v9 3/9] mfd: omap-usb-host: Use proper clock name instead of alias
From: Roger Quadros @ 2014-02-27 14:18 UTC (permalink / raw)
  To: lee.jones, tony, bcousson
  Cc: devicetree, Paul Walmsley, Samuel Ortiz, linux-usb, linux-kernel,
	balbi, linux-omap, linux-arm-kernel, Roger Quadros
In-Reply-To: <1393510711-4697-1-git-send-email-rogerq@ti.com>

Use the proper clock name 'usbhost_120m_fck' instead of the
alias 'ehci_logic_fck'

Get rid of the 'ehci_logic_fck' alias from the OMAP3 hwmod data
as well.

CC: Paul Walmsley <paul@pwsan.com>
CC: Lee Jones <lee.jones@linaro.org>
CC: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Roger Quadros <rogerq@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 6 ------
 drivers/mfd/omap-usb-host.c                | 5 +++--
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 4c3b1e6..ad87f46 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -1955,10 +1955,6 @@ static struct omap_hwmod_class omap3xxx_usb_host_hs_hwmod_class = {
 	.sysc = &omap3xxx_usb_host_hs_sysc,
 };
 
-static struct omap_hwmod_opt_clk omap3xxx_usb_host_hs_opt_clks[] = {
-	  { .role = "ehci_logic_fck", .clk = "usbhost_120m_fck", },
-};
-
 static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = {
 	{ .name = "ohci-irq", .irq = 76 + OMAP_INTC_START, },
 	{ .name = "ehci-irq", .irq = 77 + OMAP_INTC_START, },
@@ -1981,8 +1977,6 @@ static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = {
 			.idlest_stdby_bit = OMAP3430ES2_ST_USBHOST_STDBY_SHIFT,
 		},
 	},
-	.opt_clks	= omap3xxx_usb_host_hs_opt_clks,
-	.opt_clks_cnt	= ARRAY_SIZE(omap3xxx_usb_host_hs_opt_clks),
 
 	/*
 	 * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index c31baa7..865c276 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -692,10 +692,11 @@ static int usbhs_omap_probe(struct platform_device *pdev)
 
 		if (need_logic_fck) {
 			omap->ehci_logic_fck = devm_clk_get(dev,
-							    "ehci_logic_fck");
+							    "usbhost_120m_fck");
 			if (IS_ERR(omap->ehci_logic_fck)) {
 				ret = PTR_ERR(omap->ehci_logic_fck);
-				dev_err(dev, "ehci_logic_fck failed:%d\n", ret);
+				dev_err(dev, "usbhost_120m_fck failed:%d\n",
+					ret);
 				goto err_mem;
 			}
 		}
-- 
1.8.3.2

^ permalink raw reply related


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