LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 3/4] Simplify rtas_change_msi() error semantics
From: Benjamin Herrenschmidt @ 2007-10-02  8:37 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1191310825.6593.21.camel@concordia>


On Tue, 2007-10-02 at 17:40 +1000, Michael Ellerman wrote:
> 
> rtas_disable_msi() asks firmware to configure 0 MSIs on the device,
> that
> hopefully succeeds. AFAIK configuring 0 MSIs is as close as we can get
> to disabling MSI via RTAS.
> 
> Perhaps that should also (re)enable INTX?

Not sure... maybe. RTAS doesn't do it ? Then there,s the question of
what happens on machines that don't support INTx ...

Cheers.
Ben.

^ permalink raw reply

* [PATCH 5/5] Celleb: update for PCI
From: Ishizaki Kou @ 2007-10-02  8:26 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch kit to support PCI bus on Celleb with new "I/O routines
for PowerPC." External PCI on Celleb must do explicit synchronization
with devices (Bus has no automatic synchronization feature).

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/pci.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/pci.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/pci.h
@@ -25,11 +25,18 @@
 
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
+#include <asm/ppc-pci.h>
 
 extern int celleb_setup_phb(struct pci_controller *);
 extern int celleb_pci_probe_mode(struct pci_bus *);
 
-extern struct pci_ops celleb_epci_ops;
 extern int celleb_setup_epci(struct device_node *, struct pci_controller *);
 
+extern void *celleb_dummy_page_va;
+extern int __init celleb_pci_workaround_init(void);
+extern void __init celleb_pci_add_one(struct pci_controller *,
+				      void (*)(struct pci_controller *));
+extern void fake_pci_workaround_init(struct pci_controller *);
+extern void epci_workaround_init(struct pci_controller *);
+
 #endif /* _CELLEB_PCI_H */
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc.h
@@ -53,7 +53,7 @@
 #define SCC_EPCI_STATUS         0x808
 #define SCC_EPCI_ABTSET         0x80c
 #define SCC_EPCI_WATRP          0x810
-#define SCC_EPCI_DUMMYRADR      0x814
+#define SCC_EPCI_DUMYRADR       0x814
 #define SCC_EPCI_SWRESP         0x818
 #define SCC_EPCI_CNTOPT         0x81c
 #define SCC_EPCI_ECMODE         0xf00
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Makefile
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Makefile
@@ -1,6 +1,7 @@
 obj-y				+= interrupt.o iommu.o setup.o \
-				   htab.o beat.o pci.o \
-				   scc_epci.o scc_uhc.o hvCall.o
+				   htab.o beat.o hvCall.o pci.o \
+				   scc_epci.o scc_uhc.o \
+				   io-workarounds.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)	+= udbg_beat.o
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -137,6 +137,8 @@ static int __init celleb_publish_devices
 	/* Publish OF platform devices for southbridge IOs */
 	of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
 
+	celleb_pci_workaround_init();
+
 	return 0;
 }
 device_initcall(celleb_publish_devices);
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/pci.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/pci.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/pci.c
@@ -31,6 +31,7 @@
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/pci_regs.h>
+#include <linux/of_device.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -435,36 +436,58 @@ static void __init celleb_alloc_private_
 			GFP_KERNEL);
 }
 
+static int __init celleb_setup_fake_pci(struct device_node *dev,
+					struct pci_controller *phb)
+{
+	struct device_node *node;
+
+	phb->ops = &celleb_fake_pci_ops;
+	celleb_alloc_private_mem(phb);
+
+	for (node = of_get_next_child(dev, NULL);
+	     node != NULL; node = of_get_next_child(dev, node))
+		celleb_setup_fake_pci_device(node, phb);
+
+	return 0;
+}
+
+void __init fake_pci_workaround_init(struct pci_controller *phb)
+{
+	/**
+	 *  We will add fake pci bus to scc_pci_bus for the purpose to improve
+	 *  I/O Macro performance. But device-tree and device drivers
+	 *  are not ready to use address with a token.
+	 */
+
+	/* celleb_pci_add_one(phb, NULL); */
+}
+
+static struct of_device_id celleb_phb_match[] __initdata = {
+	{
+		.name = "pci-pseudo",
+		.data = celleb_setup_fake_pci,
+	}, {
+		.name = "epci",
+		.data = celleb_setup_epci,
+	}, {
+	},
+};
+
 int __init celleb_setup_phb(struct pci_controller *phb)
 {
-	const char *name;
 	struct device_node *dev = phb->arch_data;
-	struct device_node *node;
-	unsigned int rlen;
+	const struct of_device_id *match;
+	int (*setup_func)(struct device_node *, struct pci_controller *);
 
-	name = of_get_property(dev, "name", &rlen);
-	if (!name)
+	match = of_match_node(celleb_phb_match, dev);
+	if (!match)
 		return 1;
 
-	pr_debug("PCI: celleb_setup_phb() %s\n", name);
 	phb_set_bus_ranges(dev, phb);
 	phb->buid = 1;
 
-	if (strcmp(name, "epci") == 0) {
-		phb->ops = &celleb_epci_ops;
-		return celleb_setup_epci(dev, phb);
-
-	} else if (strcmp(name, "pci-pseudo") == 0) {
-		phb->ops = &celleb_fake_pci_ops;
-		celleb_alloc_private_mem(phb);
-		for (node = of_get_next_child(dev, NULL);
-		     node != NULL; node = of_get_next_child(dev, node))
-			celleb_setup_fake_pci_device(node, phb);
-
-	} else
-		return 1;
-
-	return 0;
+	setup_func = match->data;
+	return (*setup_func)(dev, phb);
 }
 
 int celleb_pci_probe_mode(struct pci_bus *bus)
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc_epci.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc_epci.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc_epci.c
@@ -43,7 +43,11 @@
 
 #define iob()  __asm__ __volatile__("eieio; sync":::"memory")
 
-static inline volatile void __iomem *celleb_epci_get_epci_base(
+struct epci_private {
+	dma_addr_t	dummy_page_da;
+};
+
+static inline PCI_IO_ADDR celleb_epci_get_epci_base(
 					struct pci_controller *hose)
 {
 	/*
@@ -55,7 +59,7 @@ static inline volatile void __iomem *cel
 	return hose->cfg_addr;
 }
 
-static inline volatile void __iomem *celleb_epci_get_epci_cfg(
+static inline PCI_IO_ADDR celleb_epci_get_epci_cfg(
 					struct pci_controller *hose)
 {
 	/*
@@ -67,20 +71,11 @@ static inline volatile void __iomem *cel
 	return hose->cfg_data;
 }
 
-#if 0 /* test code for epci dummy read */
-static void celleb_epci_dummy_read(struct pci_dev *dev)
+static void scc_epci_dummy_read(struct pci_controller *hose)
 {
-	volatile void __iomem *epci_base;
-	struct device_node *node;
-	struct pci_controller *hose;
+	PCI_IO_ADDR epci_base;
 	u32 val;
 
-	node = (struct device_node *)dev->bus->sysdata;
-	hose = pci_find_hose_for_OF_device(node);
-
-	if (!hose)
-		return;
-
 	epci_base = celleb_epci_get_epci_base(hose);
 
 	val = in_be32(epci_base + SCC_EPCI_WATRP);
@@ -88,21 +83,45 @@ static void celleb_epci_dummy_read(struc
 
 	return;
 }
-#endif
+
+void __init epci_workaround_init(struct pci_controller *hose)
+{
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR reg;
+	struct epci_private *private = hose->private_data;
+
+	BUG_ON(!private);
+
+	private->dummy_page_da = dma_map_single(hose->parent,
+		celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
+	if (private->dummy_page_da == DMA_ERROR_CODE) {
+		printk(KERN_ERR "EPCI: dummy read disabled."
+		       "Map dummy page failed.\n");
+		return;
+	}
+
+	celleb_pci_add_one(hose, scc_epci_dummy_read);
+	epci_base = celleb_epci_get_epci_base(hose);
+
+	reg = epci_base + SCC_EPCI_DUMYRADR;
+	out_be32(reg, private->dummy_page_da);
+}
 
 static inline void clear_and_disable_master_abort_interrupt(
 					struct pci_controller *hose)
 {
-	volatile void __iomem *epci_base, *reg;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR reg;
 	epci_base = celleb_epci_get_epci_base(hose);
 	reg = epci_base + PCI_COMMAND;
 	out_be32(reg, in_be32(reg) | (PCI_STATUS_REC_MASTER_ABORT << 16));
 }
 
 static int celleb_epci_check_abort(struct pci_controller *hose,
-				   volatile void __iomem *addr)
+				   PCI_IO_ADDR addr)
 {
-	volatile void __iomem *reg, *epci_base;
+	PCI_IO_ADDR reg;
+	PCI_IO_ADDR epci_base;
 	u32 val;
 
 	iob();
@@ -132,12 +151,12 @@ static int celleb_epci_check_abort(struc
 	return PCIBIOS_SUCCESSFUL;
 }
 
-static volatile void __iomem *celleb_epci_make_config_addr(
+static PCI_IO_ADDR celleb_epci_make_config_addr(
 					struct pci_bus *bus,
 					struct pci_controller *hose,
 					unsigned int devfn, int where)
 {
-	volatile void __iomem *addr;
+	PCI_IO_ADDR addr;
 
 	if (bus != hose->bus)
 		addr = celleb_epci_get_epci_cfg(hose) +
@@ -157,7 +176,8 @@ static volatile void __iomem *celleb_epc
 static int celleb_epci_read_config(struct pci_bus *bus,
 			unsigned int devfn, int where, int size, u32 * val)
 {
-	volatile void __iomem *epci_base, *addr;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR addr;
 	struct device_node *node;
 	struct pci_controller *hose;
 
@@ -220,7 +240,8 @@ static int celleb_epci_read_config(struc
 static int celleb_epci_write_config(struct pci_bus *bus,
 			unsigned int devfn, int where, int size, u32 val)
 {
-	volatile void __iomem *epci_base, *addr;
+	PCI_IO_ADDR epci_base;
+	PCI_IO_ADDR addr;
 	struct device_node *node;
 	struct pci_controller *hose;
 
@@ -286,7 +307,8 @@ struct pci_ops celleb_epci_ops = {
 static int __init celleb_epci_init(struct pci_controller *hose)
 {
 	u32 val;
-	volatile void __iomem *reg, *epci_base;
+	PCI_IO_ADDR reg;
+	PCI_IO_ADDR epci_base;
 	int hwres = 0;
 
 	epci_base = celleb_epci_get_epci_base(hose);
@@ -440,10 +462,24 @@ int __init celleb_setup_epci(struct devi
 		 r.start, (unsigned long)hose->cfg_data,
 		(r.end - r.start + 1));
 
+	hose->private_data = kzalloc(sizeof(struct epci_private), GFP_KERNEL);
+	if (hose->private_data == NULL) {
+		printk(KERN_ERR "EPCI: no memory for private data.\n");
+		goto error;
+	}
+
+	hose->ops = &celleb_epci_ops;
 	celleb_epci_init(hose);
 
 	return 0;
 
 error:
+	kfree(hose->private_data);
+
+	if (hose->cfg_addr)
+		iounmap(hose->cfg_addr);
+
+	if (hose->cfg_data)
+		iounmap(hose->cfg_data);
 	return 1;
 }
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/io-workarounds.c
===================================================================
--- /dev/null
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/io-workarounds.c
@@ -0,0 +1,279 @@
+/*
+ * Support for Celleb io workarounds
+ *
+ * (C) Copyright 2006-2007 TOSHIBA CORPORATION
+ *
+ * This file is based to arch/powerpc/platform/cell/io-workarounds.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/of_device.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+
+#include "pci.h"
+
+#define MAX_CELLEB_PCI_BUS	4
+
+void *celleb_dummy_page_va;
+
+static struct celleb_pci_bus {
+	struct pci_controller *phb;
+	void (*dummy_read)(struct pci_controller *);
+} celleb_pci_busses[MAX_CELLEB_PCI_BUS];
+
+static int celleb_pci_count = 0;
+
+static struct celleb_pci_bus *celleb_pci_find(unsigned long vaddr,
+					      unsigned long paddr)
+{
+	int i, j;
+	struct resource *res;
+
+	for (i = 0; i < celleb_pci_count; i++) {
+		struct celleb_pci_bus *bus = &celleb_pci_busses[i];
+		struct pci_controller *phb = bus->phb;
+		if (paddr)
+			for (j = 0; j < 3; j++) {
+				res = &phb->mem_resources[j];
+				if (paddr >= res->start && paddr <= res->end)
+					return bus;
+			}
+		res = &phb->io_resource;
+		if (vaddr && vaddr >= res->start && vaddr <= res->end)
+			return bus;
+	}
+	return NULL;
+}
+
+static void celleb_io_flush(const PCI_IO_ADDR addr)
+{
+	struct celleb_pci_bus *bus;
+	int token;
+
+	token = PCI_GET_ADDR_TOKEN(addr);
+
+	if (token && token <= celleb_pci_count)
+		bus = &celleb_pci_busses[token - 1];
+	else {
+		unsigned long vaddr, paddr;
+		pte_t *ptep;
+
+		vaddr = (unsigned long)PCI_FIX_ADDR(addr);
+		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
+			return;
+
+		ptep = find_linux_pte(init_mm.pgd, vaddr);
+		if (ptep == NULL)
+			paddr = 0;
+		else
+			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
+		bus = celleb_pci_find(vaddr, paddr);
+
+		if (bus == NULL)
+			return;
+	}
+
+	if (bus->dummy_read)
+		bus->dummy_read(bus->phb);
+}
+
+static u8 celleb_readb(const PCI_IO_ADDR addr)
+{
+	u8 val;
+	val = __do_readb(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u16 celleb_readw(const PCI_IO_ADDR addr)
+{
+	u16 val;
+	val = __do_readw(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u32 celleb_readl(const PCI_IO_ADDR addr)
+{
+	u32 val;
+	val = __do_readl(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u64 celleb_readq(const PCI_IO_ADDR addr)
+{
+	u64 val;
+	val = __do_readq(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u16 celleb_readw_be(const PCI_IO_ADDR addr)
+{
+	u16 val;
+	val = __do_readw_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u32 celleb_readl_be(const PCI_IO_ADDR addr)
+{
+	u32 val;
+	val = __do_readl_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static u64 celleb_readq_be(const PCI_IO_ADDR addr)
+{
+	u64 val;
+	val = __do_readq_be(addr);
+	celleb_io_flush(addr);
+	return val;
+}
+
+static void celleb_readsb(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsb(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_readsw(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsw(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_readsl(const PCI_IO_ADDR addr,
+			  void *buf, unsigned long count)
+{
+	__do_readsl(addr, buf, count);
+	celleb_io_flush(addr);
+}
+
+static void celleb_memcpy_fromio(void *dest,
+				 const PCI_IO_ADDR src,
+				 unsigned long n)
+{
+	__do_memcpy_fromio(dest, src, n);
+	celleb_io_flush(src);
+}
+
+static void __iomem *celleb_ioremap(unsigned long addr,
+				     unsigned long size,
+				     unsigned long flags)
+{
+	struct celleb_pci_bus *bus;
+	void __iomem *res = __ioremap(addr, size, flags);
+	int busno;
+
+	bus = celleb_pci_find(0, addr);
+	if (bus != NULL) {
+		busno = bus - celleb_pci_busses;
+		PCI_SET_ADDR_TOKEN(res, busno + 1);
+	}
+	return res;
+}
+
+static void celleb_iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(PCI_FIX_ADDR(addr));
+}
+
+static struct ppc_pci_io celleb_pci_io __initdata = {
+	.readb = celleb_readb,
+	.readw = celleb_readw,
+	.readl = celleb_readl,
+	.readq = celleb_readq,
+	.readw_be = celleb_readw_be,
+	.readl_be = celleb_readl_be,
+	.readq_be = celleb_readq_be,
+	.readsb = celleb_readsb,
+	.readsw = celleb_readsw,
+	.readsl = celleb_readsl,
+	.memcpy_fromio = celleb_memcpy_fromio,
+};
+
+void __init celleb_pci_add_one(struct pci_controller *phb,
+			       void (*dummy_read)(struct pci_controller *))
+{
+	struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
+	struct device_node *np = phb->arch_data;
+
+	if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
+		printk(KERN_ERR "Too many pci bridges, workarounds"
+		       " disabled for %s\n", np->full_name);
+		return;
+	}
+
+	celleb_pci_count++;
+
+	bus->phb = phb;
+	bus->dummy_read = dummy_read;
+}
+
+static struct of_device_id celleb_pci_workaround_match[] __initdata = {
+	{
+		.name = "pci-pseudo",
+		.data = fake_pci_workaround_init,
+	}, {
+		.name = "epci",
+		.data = epci_workaround_init,
+	}, {
+	},
+};
+
+int __init celleb_pci_workaround_init(void)
+{
+	struct pci_controller *phb;
+	struct device_node *node;
+	const struct  of_device_id *match;
+	void (*init_func)(struct pci_controller *);
+
+	celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!celleb_dummy_page_va) {
+		printk(KERN_ERR "Celleb: dummy read disabled."
+			"Alloc celleb_dummy_page_va failed\n");
+		return 1;
+	}
+
+	list_for_each_entry(phb, &hose_list, list_node) {
+		node = phb->arch_data;
+		match = of_match_node(celleb_pci_workaround_match, node);
+
+		if (match) {
+			init_func = match->data;
+			(*init_func)(phb);
+		}
+	}
+
+	ppc_pci_io = celleb_pci_io;
+	ppc_md.ioremap = celleb_ioremap;
+	ppc_md.iounmap = celleb_iounmap;
+
+	return 0;
+}
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/Kconfig
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/Kconfig
@@ -2,6 +2,7 @@ config PPC_CELLEB
 	bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
 	depends on PPC_MULTIPLATFORM && PPC64
 	select PPC_CELL
+	select PPC_INDIRECT_IO
 	select PPC_OF_PLATFORM_PCI
 	select HAS_TXX9_SERIAL
 	select PPC_UDBG_BEAT

^ permalink raw reply

* [PATCH 4/5] Celleb: Serial I/O update
From: Ishizaki Kou @ 2007-10-02  8:25 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is an update patch for Serial I/O on Celleb.
  - Detection algorithm has been changed

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/scc_sio.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/scc_sio.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/scc_sio.c
@@ -1,7 +1,7 @@
 /*
  * setup serial port in SCC
  *
- * (C) Copyright 2006 TOSHIBA CORPORATION
+ * (C) Copyright 2006-2007 TOSHIBA CORPORATION
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -42,40 +42,40 @@ static struct {
 static int __init txx9_serial_init(void)
 {
 	extern int early_serial_txx9_setup(struct uart_port *port);
-	struct device_node *node;
+	struct device_node *node = NULL;
 	int i;
 	struct uart_port req;
 	struct of_irq irq;
 	struct resource res;
 
-	node = of_find_node_by_path("/ioif1/sio");
-	if (!node)
-		return 0;
-
-	for(i = 0; i < sizeof(txx9_scc_tab)/sizeof(txx9_scc_tab[0]); i++) {
-		if (!(txx9_serial_bitmap & (1<<i)))
-			continue;
-
-		if (of_irq_map_one(node, i, &irq))
-			continue;
-		if (of_address_to_resource(node, txx9_scc_tab[i].index, &res))
-			continue;
-
-		memset(&req, 0, sizeof(req));
-		req.line = i;
-		req.iotype = UPIO_MEM;
-		req.mapbase = res.start + txx9_scc_tab[i].offset;
+	while ((node = of_find_compatible_node(node,
+				"serial", "toshiba,sio-scc")) != NULL) {
+		for (i = 0; i < ARRAY_SIZE(txx9_scc_tab); i++) {
+			if (!(txx9_serial_bitmap & (1<<i)))
+				continue;
+
+			if (of_irq_map_one(node, i, &irq))
+				continue;
+			if (of_address_to_resource(node,
+				txx9_scc_tab[i].index, &res))
+				continue;
+
+			memset(&req, 0, sizeof(req));
+			req.line = i;
+			req.iotype = UPIO_MEM;
+			req.mapbase = res.start + txx9_scc_tab[i].offset;
 #ifdef CONFIG_SERIAL_TXX9_CONSOLE
-		req.membase = ioremap(req.mapbase, 0x24);
+			req.membase = ioremap(req.mapbase, 0x24);
 #endif
-		req.irq = irq_create_of_mapping(irq.controller,
-			irq.specifier, irq.size);
-		req.flags |= UPF_IOREMAP | UPF_BUGGY_UART /*HAVE_CTS_LINE*/;
-		req.uartclk = 83300000;
-		early_serial_txx9_setup(&req);
+			req.irq = irq_create_of_mapping(irq.controller,
+				irq.specifier, irq.size);
+			req.flags |= UPF_IOREMAP | UPF_BUGGY_UART
+				/*HAVE_CTS_LINE*/;
+			req.uartclk = 83300000;
+			early_serial_txx9_setup(&req);
+		}
 	}
 
-	of_node_put(node);
 	return 0;
 }
 

^ permalink raw reply

* [PATCH 3/5] Celleb: New HTAB Guest OS Interface on Beat
From: Ishizaki Kou @ 2007-10-02  8:23 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch kit to work with new Guest OS Interface
to tweak HTAB on Beat. It detects old and new Guest OS Interfaces
automatically.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -119,7 +119,7 @@ static int __init celleb_probe(void)
 		return 0;
 
 	powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE;
-	hpte_init_beat();
+	hpte_init_beat_v3();
 	return 1;
 }
 
Index: linux-powerpc-git/include/asm-powerpc/mmu-hash64.h
===================================================================
--- linux-powerpc-git.orig/include/asm-powerpc/mmu-hash64.h
+++ linux-powerpc-git/include/asm-powerpc/mmu-hash64.h
@@ -256,6 +256,7 @@ extern void hpte_init_native(void);
 extern void hpte_init_lpar(void);
 extern void hpte_init_iSeries(void);
 extern void hpte_init_beat(void);
+extern void hpte_init_beat_v3(void);
 
 extern void stabs_alloc(void);
 extern void slb_initialize(void);
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat_syscall.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat_syscall.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat_syscall.h
@@ -157,4 +157,8 @@
 #define HV_rtc_write __BEAT_ADD_VENDOR_ID(0x191, 1)
 #define HV_eeprom_read __BEAT_ADD_VENDOR_ID(0x192, 1)
 #define HV_eeprom_write __BEAT_ADD_VENDOR_ID(0x193, 1)
+#define HV_insert_htab_entry3 __BEAT_ADD_VENDOR_ID(0x104, 1)
+#define HV_invalidate_htab_entry3 __BEAT_ADD_VENDOR_ID(0x105, 1)
+#define HV_update_htab_permission3 __BEAT_ADD_VENDOR_ID(0x106, 1)
+#define HV_clear_htab3 __BEAT_ADD_VENDOR_ID(0x107, 1)
 #endif
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat_wrapper.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat_wrapper.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat_wrapper.h
@@ -98,6 +98,37 @@ static inline s64 beat_write_htab_entry(
 	return ret;
 }
 
+static inline s64 beat_insert_htab_entry3(u64 htab_id, u64 group,
+	u64 hpte_v, u64 hpte_r, u64 mask_v, u64 value_v, u64 *slot)
+{
+	u64 dummy[1];
+	s64 ret;
+
+	ret = beat_hcall1(HV_insert_htab_entry3, dummy, htab_id, group,
+		hpte_v, hpte_r, mask_v, value_v);
+	*slot = dummy[0];
+	return ret;
+}
+
+static inline s64 beat_invalidate_htab_entry3(u64 htab_id, u64 group,
+	u64 va, u64 pss)
+{
+	return beat_hcall_norets(HV_invalidate_htab_entry3,
+		htab_id, group, va, pss);
+}
+
+static inline s64 beat_update_htab_permission3(u64 htab_id, u64 group,
+	u64 va, u64 pss, u64 ptel_mask, u64 ptel_value)
+{
+	return beat_hcall_norets(HV_update_htab_permission3,
+		htab_id, group, va, pss, ptel_mask, ptel_value);
+}
+
+static inline s64 beat_clear_htab3(u64 htab_id)
+{
+	return beat_hcall_norets(HV_clear_htab3, htab_id);
+}
+
 static inline void beat_shutdown_logical_partition(u64 code)
 {
 	(void)beat_hcall_norets(HV_shutdown_logical_partition, code);
@@ -217,4 +248,41 @@ static inline s64 beat_put_iopte(u64 ioa
 		ioid, flags);
 }
 
+static inline s64 beat_construct_event_receive_port(u64 *port)
+{
+	u64 dummy[1];
+	s64 ret;
+
+	ret = beat_hcall1(HV_construct_event_receive_port, dummy);
+	*port = dummy[0];
+	return ret;
+}
+
+static inline s64 beat_destruct_event_receive_port(u64 port)
+{
+	s64 ret;
+
+	ret = beat_hcall_norets(HV_destruct_event_receive_port, port);
+	return ret;
+}
+
+static inline s64 beat_create_repository_node(u64 path[4], u64 data[2])
+{
+	s64 ret;
+
+	ret = beat_hcall_norets(HV_create_repository_node2,
+		path[0], path[1], path[2], path[3], data[0], data[1]);
+	return ret;
+}
+
+static inline s64 beat_get_repository_node_value(u64 lpid, u64 path[4],
+	u64 data[2])
+{
+	s64 ret;
+
+	ret = beat_hcall2(HV_get_repository_node_value2, data,
+		lpid, path[0], path[1], path[2], path[3]);
+	return ret;
+}
+
 #endif
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/htab.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/htab.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/htab.c
@@ -306,3 +306,133 @@ void __init hpte_init_beat(void)
 	ppc_md.hpte_remove	= beat_lpar_hpte_remove;
 	ppc_md.hpte_clear_all	= beat_lpar_hptab_clear;
 }
+
+static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
+				  unsigned long va, unsigned long pa,
+				  unsigned long rflags, unsigned long vflags,
+				  int psize)
+{
+	unsigned long lpar_rc;
+	unsigned long slot;
+	unsigned long hpte_v, hpte_r;
+
+	/* same as iseries */
+	if (vflags & HPTE_V_SECONDARY)
+		return -1;
+
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
+			"rflags=%lx, vflags=%lx, psize=%d)\n",
+		hpte_group, va, pa, rflags, vflags, psize);
+
+	hpte_v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
+	hpte_r = hpte_encode_r(pa, psize) | rflags;
+
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
+
+	if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))
+		hpte_r &= ~_PAGE_COHERENT;
+
+	/* insert into not-volted entry */
+	lpar_rc = beat_insert_htab_entry3(0, hpte_group, hpte_v, hpte_r,
+		HPTE_V_BOLTED, 0, &slot);
+	/*
+	 * Since we try and ioremap PHBs we don't own, the pte insert
+	 * will fail. However we must catch the failure in hash_page
+	 * or we will loop forever, so return -2 in this case.
+	 */
+	if (unlikely(lpar_rc != 0)) {
+		if (!(vflags & HPTE_V_BOLTED))
+			DBG_LOW(" lpar err %lx\n", lpar_rc);
+		return -2;
+	}
+	if (!(vflags & HPTE_V_BOLTED))
+		DBG_LOW(" -> slot: %lx\n", slot);
+
+	/* We have to pass down the secondary bucket bit here as well */
+	return (slot ^ hpte_group) & 15;
+}
+
+/*
+ * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
+ * the low 3 bits of flags happen to line up.  So no transform is needed.
+ * We can probably optimize here and assume the high bits of newpp are
+ * already zero.  For now I am paranoid.
+ */
+static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
+				    unsigned long newpp,
+				    unsigned long va,
+				    int psize, int local)
+{
+	unsigned long lpar_rc;
+	unsigned long want_v;
+	unsigned long pss;
+
+	want_v = hpte_encode_v(va, psize);
+	pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
+
+	DBG_LOW("    update: "
+		"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
+		want_v & HPTE_V_AVPN, slot, psize, newpp);
+
+	lpar_rc = beat_update_htab_permission3(0, slot, want_v, pss, 7, newpp);
+
+	if (lpar_rc == 0xfffffff7) {
+		DBG_LOW("not found !\n");
+		return -1;
+	}
+
+	DBG_LOW("ok\n");
+
+	BUG_ON(lpar_rc != 0);
+
+	return 0;
+}
+
+static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va,
+					 int psize, int local)
+{
+	unsigned long want_v;
+	unsigned long lpar_rc;
+	unsigned long pss;
+
+	DBG_LOW("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
+		slot, va, psize, local);
+	want_v = hpte_encode_v(va, psize);
+	pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
+
+	lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss);
+
+	/* E_busy can be valid output: page may be already replaced */
+	BUG_ON(lpar_rc != 0 && lpar_rc != 0xfffffff7);
+}
+
+static int64_t _beat_lpar_hptab_clear_v3(void)
+{
+	return beat_clear_htab3(0);
+}
+
+static void beat_lpar_hptab_clear_v3(void)
+{
+	_beat_lpar_hptab_clear_v3();
+}
+
+void __init hpte_init_beat_v3(void)
+{
+	if (_beat_lpar_hptab_clear_v3() == 0) {
+		ppc_md.hpte_invalidate	= beat_lpar_hpte_invalidate_v3;
+		ppc_md.hpte_updatepp	= beat_lpar_hpte_updatepp_v3;
+		ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
+		ppc_md.hpte_insert	= beat_lpar_hpte_insert_v3;
+		ppc_md.hpte_remove	= beat_lpar_hpte_remove;
+		ppc_md.hpte_clear_all	= beat_lpar_hptab_clear_v3;
+	} else {
+		ppc_md.hpte_invalidate	= beat_lpar_hpte_invalidate;
+		ppc_md.hpte_updatepp	= beat_lpar_hpte_updatepp;
+		ppc_md.hpte_updateboltedpp = beat_lpar_hpte_updateboltedpp;
+		ppc_md.hpte_insert	= beat_lpar_hpte_insert;
+		ppc_md.hpte_remove	= beat_lpar_hpte_remove;
+		ppc_md.hpte_clear_all	= beat_lpar_hptab_clear;
+	}
+}

^ permalink raw reply

* [PATCH 2/5] Celleb: Support for Power/Reset buttons
From: Ishizaki Kou @ 2007-10-02  8:21 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This is a patch to support Power/Reset buttons on Beat on Celleb.

On Beat, we have an event from Beat if Power button or Reset button
is pressed. This patch catches the event and convert it to a signal
to INIT process by calling ctrl_alt_del() function.

/sbin/inittab have no entry to turn the machine power off so we have
to detect if power button is pressed or not internally in our driver.
This idea is taken from PS3's event handling subsystem.

Signed-off-by: Kou Ishizaki <Kou.Ishizaki@toshiba.co.jp>
---

This patch is taken after "[PATCH 1/5] Move pause() and kexec_cpu_down()
to beat.c" applied, so some lines are taken in from that patch.
No functional dependency is incorporated.


Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
@@ -22,16 +22,24 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/rtc.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/reboot.h>
 
 #include <asm/hvconsole.h>
 #include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
 
 #include "beat_wrapper.h"
 #include "beat.h"
+#include "interrupt.h"
+
+static int beat_pm_poweroff_flag;
 
 void beat_restart(char *cmd)
 {
-	beat_shutdown_logical_partition(1);
+	beat_shutdown_logical_partition(!beat_pm_poweroff_flag);
 }
 
 void beat_power_off(void)
@@ -170,6 +178,90 @@ void beat_kexec_cpu_down(int crash, int 
 }
 #endif
 
+static irqreturn_t beat_power_event(int virq, void *arg)
+{
+	printk(KERN_DEBUG "Beat: power button pressed\n");
+	beat_pm_poweroff_flag = 1;
+	ctrl_alt_del();
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t beat_reset_event(int virq, void *arg)
+{
+	printk(KERN_DEBUG "Beat: reset button pressed\n");
+	beat_pm_poweroff_flag = 0;
+	ctrl_alt_del();
+	return IRQ_HANDLED;
+}
+
+static struct beat_event_list {
+	const char *typecode;
+	irq_handler_t handler;
+	unsigned int virq;
+} beat_event_list[] = {
+	{ "power", beat_power_event, 0 },
+	{ "reset", beat_reset_event, 0 },
+};
+
+static int __init beat_register_event(void)
+{
+	u64 path[4], data[2];
+	int rc, i;
+	unsigned int virq;
+
+	for (i = 0; i < ARRAY_SIZE(beat_event_list); i++) {
+		struct beat_event_list *ev = &beat_event_list[i];
+
+		if (beat_construct_event_receive_port(data) != 0) {
+			printk(KERN_ERR "Beat: "
+			       "cannot construct event receive port for %s\n",
+			       ev->typecode);
+			return -EINVAL;
+		}
+
+		virq = irq_create_mapping(NULL, data[0]);
+		if (virq == NO_IRQ) {
+			printk(KERN_ERR "Beat: failed to get virtual IRQ"
+			       " for event receive port for %s\n",
+			       ev->typecode);
+			beat_destruct_event_receive_port(data[0]);
+			return -EIO;
+		}
+		ev->virq = virq;
+
+		rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+				      ev->typecode, NULL);
+		if (rc != 0) {
+			printk(KERN_ERR "Beat: failed to request virtual IRQ"
+			       " for event receive port for %s\n",
+			       ev->typecode);
+			beat_destruct_event_receive_port(data[0]);
+			return rc;
+		}
+
+		path[0] = 0x1000000065780000ul;	/* 1,ex */
+		path[1] = 0x627574746f6e0000ul;	/* button */
+		path[2] = 0;
+		strncpy((char *)&path[2], ev->typecode, 8);
+		path[3] = 0;
+		data[1] = 0;
+
+		beat_create_repository_node(path, data);
+	}
+	return 0;
+}
+
+static int __init beat_event_init(void)
+{
+	if (!firmware_has_feature(FW_FEATURE_BEAT))
+		return -EINVAL;
+
+	beat_pm_poweroff_flag = 0;
+	return beat_register_event();
+}
+
+device_initcall(beat_event_init);
+
 EXPORT_SYMBOL(beat_get_term_char);
 EXPORT_SYMBOL(beat_put_term_char);
 EXPORT_SYMBOL(beat_halt_code);

^ permalink raw reply

* Re: [PATCH 7/7] Celleb: update for PCI
From: Arnd Bergmann @ 2007-10-02  8:18 UTC (permalink / raw)
  To: Ishizaki Kou; +Cc: linuxppc-dev, paulus
In-Reply-To: <20071002.170439.-1300534196.kouish@swc.toshiba.co.jp>

On Tuesday 02 October 2007, Ishizaki Kou wrote:
> Though I agree it's better to make code common, I hope to keep them
> separate for now. Because I'm now developing PCI Express support and
> it also uses io-workaround mechanism. I'll try to make them common in
> this work.

Ok, fair enough. Let's use your current version for 2.6.24 and then
work on a new version that handles both PCI and PCIe correctly
on both platforms. I'm certainly interested in getting the PCIe
workarounds running on QS20 as well.

	Arnd <><

^ permalink raw reply

* [PATCH 1/5] Celleb: Move pause, kexec_cpu_down to beat.c
From: Ishizaki Kou @ 2007-10-02  8:18 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

This patch is an update for "Beat on Celleb"
  - Move beat_pause(), beat_kexec_cpu_down() from setup.c to beat.c

Signed-off-by: <Kou.Ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---

Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.h
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.h
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.h
@@ -36,5 +36,7 @@ ssize_t beat_nvram_get_size(void);
 ssize_t beat_nvram_read(char *, size_t, loff_t *);
 ssize_t beat_nvram_write(char *, size_t, loff_t *);
 int beat_set_xdabr(unsigned long);
+void beat_power_save(void);
+void beat_kexec_cpu_down(int, int);
 
 #endif /* _CELLEB_BEAT_H */
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/setup.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/setup.c
@@ -111,11 +111,6 @@ static void __init celleb_setup_arch(voi
 #endif
 }
 
-static void beat_power_save(void)
-{
-	beat_pause(0);
-}
-
 static int __init celleb_probe(void)
 {
 	unsigned long root = of_get_flat_dt_root();
@@ -128,13 +123,6 @@ static int __init celleb_probe(void)
 	return 1;
 }
 
-#ifdef CONFIG_KEXEC
-static void celleb_kexec_cpu_down(int crash, int secondary)
-{
-	beatic_deinit_IRQ();
-}
-#endif
-
 static struct of_device_id celleb_bus_ids[] __initdata = {
 	{ .type = "scc", },
 	{ .type = "ioif", },	/* old style */
@@ -175,7 +163,7 @@ define_machine(celleb) {
 	.pci_probe_mode 	= celleb_pci_probe_mode,
 	.pci_setup_phb		= celleb_setup_phb,
 #ifdef CONFIG_KEXEC
-	.kexec_cpu_down		= celleb_kexec_cpu_down,
+	.kexec_cpu_down		= beat_kexec_cpu_down,
 	.machine_kexec		= default_machine_kexec,
 	.machine_kexec_prepare	= default_machine_kexec_prepare,
 	.machine_crash_shutdown	= default_machine_crash_shutdown,
Index: linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- linux-powerpc-git.orig/arch/powerpc/platforms/celleb/beat.c
+++ linux-powerpc-git/arch/powerpc/platforms/celleb/beat.c
@@ -158,6 +158,18 @@ int64_t beat_put_term_char(u64 vterm, u6
 	return beat_put_characters_to_console(vterm, len, (u8*)db);
 }
 
+void beat_power_save(void)
+{
+	beat_pause(0);
+}
+
+#ifdef CONFIG_KEXEC
+void beat_kexec_cpu_down(int crash, int secondary)
+{
+	beatic_deinit_IRQ();
+}
+#endif
+
 EXPORT_SYMBOL(beat_get_term_char);
 EXPORT_SYMBOL(beat_put_term_char);
 EXPORT_SYMBOL(beat_halt_code);

^ permalink raw reply

* [PATCH 0/5] Updates of "Celleb" patches for 2.6.24
From: Ishizaki Kou @ 2007-10-02  8:16 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev

Follwing patch series is an update to support Cell Reference Set (Celleb).
Two patches of former series are declined, two are updated, and rest 
three still remain.

Declined patches are "fixing SLB initialization" and "VFD support for
Celleb 2." I found former patch not necessary anymore, and latter seems
under discussion to drive such device generally.

[PATCH 1/5] Celleb: Move pause, kexec_cpu_down to beat.c
  This is quite simple patch to move two functions from "setup.c" to
"beat.c". This patch is slightly updated to declare beat_kexec_cpu_down()
function unconditionally.

[PATCH 2/5] Celleb: Support for Power/Reset buttons
  This is patch to add support Power/Reset buttons on Celleb. With
this patch, Power/Reset button causes call of ctrl_alt_del() function,
not to call machine dependent routines.

  I think it is better than this to handle such buttons in consistent way,
such as 'event', but I have to make working such buttons with existing
Fedora's inittab. I feel we have to have acpi or like that, but currently
we don't have such subsystem.

[PATCH 3/5] Celleb: New HTAB Guest OS Interface on Beat
  This is a patch to support new HTAB Guest OS Interface on Beat. Beat v3
and later will provide you such interface. Beat v2 or former provide you
older Guest OS Interface only, so this patch detects whether the new inter-
face is available or not, and reflect it to ppc_md.

  Not changed from former patch.

[PATCH 4/5] Celleb: Serial I/O update
  This patch updates scc_sio.c to support newer serial-port detection
algorithm.

  Not changed from former patch.

[PATCH 5/5] Celleb: update for PCI
  This patch incorporates PCI support for Celleb.
  - io_workarounds.c: Kicks synchronization port whenever reading
  MMIO registers (so-called "dummy read").
  - Replaced "volatile void * __iommu" to "PCI_IO_ADDR" because the
  compiler complains on volatile pointer.
  - Setup via bus name.
  - alloc_maybe_bootmem() has been gone.

  Not changed from former patch.


Best regards,
Kou Ishizaki

^ permalink raw reply

* What's the preferred way to export board information to userspace ?
From: Laurent Pinchart @ 2007-10-02  8:10 UTC (permalink / raw)
  To: linuxppc-dev

Hi everybody,

it seems linuxppc-embedded is going away. I should have posted this here in=
=20
the first place, so sorry for the cross-post.

I need to export some read-only board-specific information (serial number,=
=20
boot mode jumper configuration, ...) that are collected from various locati=
ons=20
(CPLD, flash, U-Boot, ...) to userspace applications.

Could anyone advice me on the preferred way to do that ? I can easily add a=
=20
quick&dirty sysfs/procfs based implementation, but I was wondering if there=
=20
was some kind of clean and generic way.

Best regards,

=2D-=20
Laurent Pinchart
CSE Semaphore Belgium

Chauss=E9e de Bruxelles, 732A
B-1410 Waterloo
Belgium

T +32 (2) 387 42 59
=46 +32 (2) 387 42 75

^ permalink raw reply

* Re: [PATCH 7/7] Celleb: update for PCI
From: Ishizaki Kou @ 2007-10-02  8:04 UTC (permalink / raw)
  To: arnd; +Cc: linuxppc-dev, paulus
In-Reply-To: <200709261409.32231.arnd@arndb.de>

Arnd Bergmann <arnd@arndb.de> wrote:
> On Wednesday 26 September 2007, Ishizaki Kou wrote:
> > This is a patch kit to support PCI bus on Celleb with new "I/O routines
> > for PowerPC." External PCI on Celleb must do explicit synchronization
> > with devices (Bus has no automatic synchronization feature).
> 
> It seems you are duplicating a lot of
> arch/powerpc/platforms/cell/io-workarounds.c, in order to work around
> the same problem:

 (snip)

> Is there a way that we can make that code common? I guess there could be a
> file in arch/powerpc/sysdev that can handle this correctly for all hardware
> that requires this particular workaround (currently celleb and QS20, but
> potentially more).

Though I agree it's better to make code common, I hope to keep them
separate for now. Because I'm now developing PCI Express support and
it also uses io-workaround mechanism. I'll try to make them common in
this work.

Best regards,
Kou Ishizaki

^ permalink raw reply

* Stdout console clogging => 300ms blocked
From: Willaert, Bernard @ 2007-10-02  7:41 UTC (permalink / raw)
  To: linuxppc-dev

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

System details:
Freescale MPC8347@200MHz
Kernel 2.6.18

Problem:
When we log debug output via the serial console on a multithreaded
application, the console throughput may get clogged and then we
experience a >300ms deadlock.

Quick and dirty test program: threadtest.c:
//----------------------------------------------------------------------
-------------------------
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>

#define THREAD_DELAY 1000

void* thread_1(void* unused)
{
	while (1)
	{
		usleep(THREAD_DELAY);
		fprintf(stdout," <----- thread 1\n");
	}
	return NULL;
}

void* thread_2(void* unused)
{
	static long ts_old;
	long ts;
	struct timeval tv;

	while (1)
	{
		usleep(THREAD_DELAY);
		fprintf(stdout," <----- thread 2\n");

		gettimeofday (&tv, NULL);
		ts = (tv.tv_sec * 1000L) + (tv.tv_usec / 1000L);
		if ((ts - ts_old) > 100)
		{
			fprintf(stdout, "!!!!!!!!!!! thread2 interval
timeout = %d ms\n",(int)(ts - ts_old));
		}
		ts_old = ts;
	}
	return NULL;			

}



int main()
{
	pthread_t pthread_id_1, pthread_id_2;
	
	pthread_create(&pthread_id_1,NULL,&thread_1,NULL);
	pthread_create(&pthread_id_2,NULL,&thread_2,NULL);
	while (1)
	{
	}
	return 0;

}

//----------------------------------------------------------------------
-------------------------

Build command on our platform: 
powerpc-linux-uclibc-gcc threadtest.c  -lpthread -o threadtest
Execute: ./threadtest > /dev/console &

Uboot settings for the serial console:
consoledev=ttyS0
baudrate=115200
stdin=serial
stdout=serial
stderr=serial
boot_go=setenv bootargs console=$consoledev,$baudrate $args_rtc
$args_mtd $args_nfs $args_debug;bootm $addr_kernel $addr_root $addr_dtb


Expected output [snippet] on the console:
.... /\ ........
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
.... /\ ........

Real output on the console:

.... /\ ........
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
!!!!!!!!!!! thread2 interval timeout = 335 ms
 <----- thread 1
 <----- thread 2
 <----- thread 1
 <----- thread 2
 <----- thread 1
.... /\ ........ 

This timeout shows up around every second and has always about the same
value of 335 ms.
Can somebody reproduce this behaviour ( the console speed and/or thread
interval may have to be tweaked to clog the serial output) ?
Thank you in advance for your help.
Bernard




-----------------------------------------------------------
Bernard Willaert
Software Development Engineer Modality OEM Solutions
BARCO Medical Imaging Division
President Kennedypark 35 - B-8500 KORTRIJK - BELGIUM
Tel.  +32 56 233 439  Fax +32 56 233 457
www.barco.com/medical
mailto:bernard.willaert@barco.com





DISCLAIMER:
Unless indicated otherwise, the information contained in this message is privileged and confidential, and is intended only for the use of the addressee(s) named above and others who have been specifically authorized to receive it. If you are not the intended recipient, you are hereby notified that any dissemination, distribution or copying of this message and/or attachments is strictly prohibited. The company accepts no liability for any damage caused by any virus transmitted by this email. Furthermore, the company does not warrant a proper and complete transmission of this information, nor does it accept liability for any delays. If you have received this message in error, please contact the sender and delete the message. Thank you.

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

^ permalink raw reply

* Re: [PATCH 3/4] Simplify rtas_change_msi() error semantics
From: Michael Ellerman @ 2007-10-02  7:40 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191306253.6310.106.camel@pasglop>

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

On Tue, 2007-10-02 at 16:24 +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2007-10-02 at 15:58 +1000, Michael Ellerman wrote:
> > > Looks allright, just a question tho... what do we do if it fails ?
> > Do we
> > > try to fallback to a lower number of MSIs ? Or what ? Dead device ?
> > 
> > That's all up to the device driver. In theory the driver could try again
> > with a lower count - but that might require extra logic in the driver to
> > handle shared irq handlers etc. In practice I think the current drivers
> > will just fail.
> 
> Question is badly phrased.. I meant something more like... what do we do
> if RTAS returns a lower count ?
> 
> That is, we end up with that device with that lower count of MSIs
> enabled, we fail at the driver level, do we still somewhat keep track ?
> Drivers might assume that means it can use LSIs no ? which may not be
> the case... Shouldn't we try to switch back to LSI mode (or does the
> RTAS interface doesnt allow it ?)

OK I get you. So:

rtas_setup_msi_irqs() detects that it got fewer MSIs than it asked for
and returns an error.

The generic code (drivers/pci/msi.c) notices the error and calls
msi_free_irqs().

That calls back into rtas_teardown_msi_irqs() which disposes of the virq
mappings and calls rtas_disable_msi().

rtas_disable_msi() asks firmware to configure 0 MSIs on the device, that
hopefully succeeds. AFAIK configuring 0 MSIs is as close as we can get
to disabling MSI via RTAS.

Perhaps that should also (re)enable INTX?

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [PATCH] cpm: rounding of brg clockdivider
From: Esben Haabendal @ 2007-10-02  7:24 UTC (permalink / raw)
  To: Scott Wood, LinuxPPC-dev


Do rounding of brg clockdivider instead of truncate to get more precise baudrates

Something similar might be needed for cpm_fastbrg...

---
commit 52d631eb8f64cef794d6aa66494e253cf268894e
tree 956149a0eb5beb9afb280f4593615929eab7b779
parent 300070dd6b5e71af0c6fbecd32388905dbdd3ea5
author Esben Haabendal <eha@doredevelopment.dk> Wed, 19 Sep 2007 13:18:59 +0200
committer Esben Haabendal <esben@esben.doredevelopment.dk> Wed, 19 Sep 2007 13:18:59 +0200

 arch/powerpc/sysdev/cpm2_common.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c
index 9058da2..a2c8157 100644
--- a/arch/powerpc/sysdev/cpm2_common.c
+++ b/arch/powerpc/sysdev/cpm2_common.c
@@ -102,7 +102,9 @@ cpm_setbrg(uint brg, uint rate)
                brg -= 4;
        }
        bp += brg;
-       out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN);
+       /* Set the BRG clock divider to get the best match to the requested
+        * baudrate (rounding required) */
+       out_be32(bp, ((((((BRG_UART_CLK*2)/rate)+1)/2)-1) << 1) | CPM_BRG_EN);
 
        cpm2_unmap(bp);
 }




!-------------------------------------------------------------flip-

-- 
Esben Haabendal
Embedded Software Consultant
Doré Development ApS

^ permalink raw reply related

* RE: [PATCH 6/9] fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.
From: Esben Haabendal @ 2007-10-02  7:10 UTC (permalink / raw)
  To: 'Scott Wood'; +Cc: netdev, linuxppc-dev
In-Reply-To: <20070920220121.GF28784@loki.buserror.net>

Hi Scott,

A minor error handling bug

> +	const u32 *data = of_get_property(np, "phy-handle", &len);
> +	if (!data || len != 4)
> +		return -EINVAL;
> +
> +	phynode = of_find_node_by_phandle(*data);
> +	if (!phynode)
> +		return -EINVAL;
> +
> +	mdionode = of_get_parent(phynode);
> +	if (!phynode)

if (!mdionode)

> +		goto out_put_phy;

Best regards,
Esben

^ permalink raw reply

* Re: Powerbook shuts down hard when hot, patch found
From: Michel Dänzer @ 2007-10-02  6:43 UTC (permalink / raw)
  To: Michael Buesch; +Cc: linuxppc-dev
In-Reply-To: <200710012258.18716.mb@bu3sch.de>


On Mon, 2007-10-01 at 22:58 +0200, Michael Buesch wrote:
> On Monday 01 October 2007 10:00:02 Michel Dänzer wrote:
> > 
> > On Sun, 2007-09-30 at 12:16 +0200, Michael Buesch wrote:
> > > 
> > > Ah, forgot to say.
> > > It does not crash immediately when the register is written. It takes about two seconds
> > > to crash. And when the machine is colder to begin with, it takes slightly
> > > longer to trigger. That _might_ support your overheating theory.
> > > 
> > > Though, it does not trigger when it's up and running, no matter how hot you drive it.
> > 
> > Maybe the thermal control module prevents it from overheating. Have you
> > tried unloading it or loading it ASAP on bootup to see if that makes any
> > difference either way?
> 
> I'm not sure how that works. Can I unload the framebuffer module?

I'm talking about the thermal control module (therm_adt746x in my case),
not radeonfb.


-- 
Earthling Michel Dänzer           |          http://tungstengraphics.com
Libre software enthusiast         |          Debian, X and DRI developer

^ permalink raw reply

* Re: [PATCH v2 2/6] Sysace: Use the established platform bus api
From: Jens Axboe @ 2007-10-02  6:35 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Christoph Hellwig, paulus, linux-kernel, linuxppc-dev
In-Reply-To: <1191304710.6310.97.camel@pasglop>

On Tue, Oct 02 2007, Benjamin Herrenschmidt wrote:
> 
> On Mon, 2007-10-01 at 13:59 +0200, Jens Axboe wrote:
> > On Sun, Sep 30 2007, Grant Likely wrote:
> > > On 9/30/07, Christoph Hellwig <hch@infradead.org> wrote:
> > > > On Sun, Sep 30, 2007 at 04:57:09PM -0600, Grant Likely wrote:
> > > > > +     if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
> > > > > +             goto err_plat;
> > > >
> > > >         rc = platform_driver_register(&ace_platform_driver);
> > > >         if (rc)
> > > >                  goto err_plat;
> > > >
> > > > please.
> > > 
> > > Okay, will do.
> > > 
> > > >
> > > > > +      err_plat:
> > > > > +     unregister_blkdev(ace_major, "xsysace");
> > > > > +      err_blk:
> > > >
> > > > labels should be indented zero or one space, but not more.
> > > 
> > > scripts/Lindent does this.  Originally, I *didn't* have my labels
> > > indented.  :-)   Does Lindent need to be fixed?
> > 
> > Seems so, if it idents labels.
> > 
> > Just send a fixup patch for that, I'll add your series to the block tree
> > for 2.6.24.
> 
> It's actually better off living in the powerpc tree I think as it's
> really about adding support for a new powerpc platform and somewhat
> needs to sync with other things in there. Unless you really want the
> whole thing in your tree :-)

I already included it yesterday, it'll go up once 2.6.24 opens. Let me
know if you want me to rip it out, though.

-- 
Jens Axboe

^ permalink raw reply

* Re: [PATCH 3/4] Simplify rtas_change_msi() error semantics
From: Benjamin Herrenschmidt @ 2007-10-02  6:24 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1191304690.6593.8.camel@concordia>


On Tue, 2007-10-02 at 15:58 +1000, Michael Ellerman wrote:
> > Looks allright, just a question tho... what do we do if it fails ?
> Do we
> > try to fallback to a lower number of MSIs ? Or what ? Dead device ?
> 
> That's all up to the device driver. In theory the driver could try again
> with a lower count - but that might require extra logic in the driver to
> handle shared irq handlers etc. In practice I think the current drivers
> will just fail.

Question is badly phrased.. I meant something more like... what do we do
if RTAS returns a lower count ?

That is, we end up with that device with that lower count of MSIs
enabled, we fail at the driver level, do we still somewhat keep track ?
Drivers might assume that means it can use LSIs no ? which may not be
the case... Shouldn't we try to switch back to LSI mode (or does the
RTAS interface doesnt allow it ?)

Ben.

^ permalink raw reply

* Re: [PATCH 6/7] Add dcr_map_reg() helper
From: Benjamin Herrenschmidt @ 2007-10-02  6:22 UTC (permalink / raw)
  To: michael; +Cc: linuxppc-dev
In-Reply-To: <1191304300.6593.2.camel@concordia>


On Tue, 2007-10-02 at 15:51 +1000, Michael Ellerman wrote:
> On Tue, 2007-10-02 at 15:19 +1000, Benjamin Herrenschmidt wrote:
> > On Mon, 2007-09-17 at 16:05 +1000, Michael Ellerman wrote:
> > > Add a helper routine to map dcr's based on the "dcr-reg" property of
> > > a device node.
> > > 
> > > Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> > 
> > Wouldn't it be more consistent to call it of_map_dcr ? Or maybe find an
> > even better name, but dcr_map_reg really sucks :-)
> 
> That would give us dcr_map(), dcr_unmap() and of_map_dcr() - which
> doesn't strike me as more consistent.
> 
> I don't particularly like dcr_map_reg(), but I think it's at least
> obvious that it's a variant of dcr_map() and that it has something to do
> with a "reg" .. maybe even a "dcr-reg" :)

dcr_map_node maybe ? dcr_map_device ? dcr_map_property ? hrm...
allright, keep it that way if you want but heh, at least see if you can
come up with something better before it gets merged :-)

Ben

^ permalink raw reply

* Re: [PATCH 3/7] Use dcr_host_t.base in ibm_emac_mal
From: Michael Ellerman @ 2007-10-02  6:06 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191302025.6310.70.camel@pasglop>

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

On Tue, 2007-10-02 at 15:13 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2007-09-17 at 16:05 +1000, Michael Ellerman wrote:
> > This requires us to do a sort-of fake dcr_map(), so that base is set
> > properly. This will be fixed/removed when the device-tree-aware emac driver
> > is merged.
> > 
> > Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> 
> Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> 
> (Have you actually tested btw ? :-)

Hmm, I wrote these in mid June, so to be honest I don't remember. I
don't think I boot tested it on anything, but I think I would have built
it.

I see now that the newemac driver is in Jeff's 24 tree, so it's probably
best to wait for Linus to merge that and then we can fix up it as well
in the one series.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: nap/dfs on 7448
From: Benjamin Herrenschmidt @ 2007-10-02  6:01 UTC (permalink / raw)
  To: Leisner, Martin; +Cc: linuxppc-dev
In-Reply-To: <556445368AFA1C438794ABDA8901891C0738E1E8@USA0300MS03.na.xerox.net>


On Mon, 2007-10-01 at 17:32 -0400, Leisner, Martin wrote:
> I asked this on linuxppc-embedded a week ago (I didn't even know this
> list existed until last week -- another reason to get rid of
> linuxpcc-embedded).
> 
> Has anyone gotten NAP/DFS to reliably work on a 7448?
> 
> I'm seeing strange problems with peripherals...(using a ram disk
> works fine).

Could it be that your host bridge isn't properly waking up the CPU to
DOZE state for snooping DMA ? (It might require some delays on QACK in
some cases, I know Apple had workarounds in those areas, maybe something
along those lines need to be configured in the chipset).

Ben.

^ permalink raw reply

* Re: [PATCH v2 2/6] Sysace: Use the established platform bus api
From: Benjamin Herrenschmidt @ 2007-10-02  5:58 UTC (permalink / raw)
  To: Jens Axboe; +Cc: Christoph Hellwig, paulus, linux-kernel, linuxppc-dev
In-Reply-To: <20071001115954.GD5303@kernel.dk>


On Mon, 2007-10-01 at 13:59 +0200, Jens Axboe wrote:
> On Sun, Sep 30 2007, Grant Likely wrote:
> > On 9/30/07, Christoph Hellwig <hch@infradead.org> wrote:
> > > On Sun, Sep 30, 2007 at 04:57:09PM -0600, Grant Likely wrote:
> > > > +     if ((rc = platform_driver_register(&ace_platform_driver)) != 0)
> > > > +             goto err_plat;
> > >
> > >         rc = platform_driver_register(&ace_platform_driver);
> > >         if (rc)
> > >                  goto err_plat;
> > >
> > > please.
> > 
> > Okay, will do.
> > 
> > >
> > > > +      err_plat:
> > > > +     unregister_blkdev(ace_major, "xsysace");
> > > > +      err_blk:
> > >
> > > labels should be indented zero or one space, but not more.
> > 
> > scripts/Lindent does this.  Originally, I *didn't* have my labels
> > indented.  :-)   Does Lindent need to be fixed?
> 
> Seems so, if it idents labels.
> 
> Just send a fixup patch for that, I'll add your series to the block tree
> for 2.6.24.

It's actually better off living in the powerpc tree I think as it's
really about adding support for a new powerpc platform and somewhat
needs to sync with other things in there. Unless you really want the
whole thing in your tree :-)

Cheers
Ben.

^ permalink raw reply

* Re: [PATCH 3/4] Simplify rtas_change_msi() error semantics
From: Michael Ellerman @ 2007-10-02  5:58 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191302603.6310.88.camel@pasglop>

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

On Tue, 2007-10-02 at 15:23 +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2007-09-20 at 16:36 +1000, Michael Ellerman wrote:
> > Currently rtas_change_msi() returns either the error code from RTAS, or if
> > the RTAS call succeeded the number of irqs that were configured by RTAS.
> > This makes checking the return value more complicated than it needs to be.
> > 
> > Instead, have rtas_change_msi() check that the number of irqs configured by
> > RTAS is equal to what we requested - and return an error otherwise. This makes
> > the return semantics match the usual 0 for success, something else for error.
> > 
> > Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> 
> Looks allright, just a question tho... what do we do if it fails ? Do we
> try to fallback to a lower number of MSIs ? Or what ? Dead device ?

That's all up to the device driver. In theory the driver could try again
with a lower count - but that might require extra logic in the driver to
handle shared irq handlers etc. In practice I think the current drivers
will just fail.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* Re: [PATCH v2 5/6] Sysace: Move IRQ handler registration to occur after FSM is initialized
From: Benjamin Herrenschmidt @ 2007-10-02  5:55 UTC (permalink / raw)
  To: Grant Likely; +Cc: axboe, linuxppc-dev, paulus, linux-kernel
In-Reply-To: <20070930225726.2476.44211.stgit@trillian.cg.shawcable.net>


On Sun, 2007-09-30 at 16:57 -0600, Grant Likely wrote:
>         val |= ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ;
>         ace_out(ace, ACE_CTRL, val);
>  
> +       /* Now we can hook up the irq handler */
> +       if (ace->irq != NO_IRQ) {
> +               rc = request_irq(ace->irq, ace_interrupt, 0,
> "systemace", ace);
> +               if (rc) {
> +                       /* Failure - fall back to polled mode */
> +                       dev_err(ace->dev, "request_irq failed\n");
> +                       ace->irq = NO_IRQ;
> +               }
> +       }
> +

I don't know the HW but from the above, it looks like you enable
interrupt emission on the HW before you register the handler, which is
wrong. You should make sure on the contrary that IRQs on the HW are
disabled until after you have registered a handler.

Only really a problem if you have shared interrupts but still...

Ben.

^ permalink raw reply

* Re: [PATCH 2 6/7] Uartlite: Add of-platform-bus binding
From: Benjamin Herrenschmidt @ 2007-10-02  5:53 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20070930224208.1871.2913.stgit@trillian.cg.shawcable.net>


On Sun, 2007-09-30 at 16:42 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> Add of_platform bus binding so this driver can be used with arch/powerpc

Another option is to have a "constructor" in the platform code that
generates the platform device from the DT. It might even become the
preferred way one of these days, I'm not too sure at this stage. Anyway,
do what you prefer.

> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> 
>  drivers/serial/uartlite.c |  101 +++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 93 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
> index ed13b9f..8752fac 100644
> --- a/drivers/serial/uartlite.c
> +++ b/drivers/serial/uartlite.c
> @@ -1,7 +1,8 @@
>  /*
>   * uartlite.c: Serial driver for Xilinx uartlite serial controller
>   *
> - * Peter Korsgaard <jacmet@sunsite.dk>
> + * Copyright (C) 2006 Peter Korsgaard <jacmet@sunsite.dk>
> + * Copyright (C) 2007 Secret Lab Technologies Ltd.
>   *
>   * This file is licensed under the terms of the GNU General Public License
>   * version 2.  This program is licensed "as is" without any warranty of any
> @@ -17,6 +18,10 @@
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
>  #include <asm/io.h>
> +#if defined(CONFIG_OF)
> +#include <linux/of_device.h>
> +#include <linux/of_platform.h>
> +#endif
>  
>  #define ULITE_NAME		"ttyUL"
>  #define ULITE_MAJOR		204
> @@ -382,8 +387,10 @@ static int __init ulite_console_setup(struct console *co, char *options)
>  	port = &ulite_ports[co->index];
>  
>  	/* not initialized yet? */
> -	if (!port->membase)
> +	if (!port->membase) {
> +		pr_debug("console on ttyUL%i not initialized\n", co->index);
>  		return -ENODEV;
> +	}
>  
>  	if (options)
>  		uart_parse_options(options, &baud, &parity, &bits, &flow);
> @@ -542,6 +549,72 @@ static struct platform_driver ulite_platform_driver = {
>  };
>  
>  /* ---------------------------------------------------------------------
> + * OF bus bindings
> + */
> +#if defined(CONFIG_OF)
> +static int __devinit
> +ulite_of_probe(struct of_device *op, const struct of_device_id *match)
> +{
> +	struct resource res;
> +	const unsigned int *id;
> +	int irq, rc;
> +
> +	dev_dbg(&op->dev, "%s(%p, %p)\n", __FUNCTION__, op, match);
> +
> +	rc = of_address_to_resource(op->node, 0, &res);
> +	if (rc) {
> +		dev_err(&op->dev, "invalide address\n");
> +		return rc;
> +	}
> +
> +	irq = irq_of_parse_and_map(op->node, 0);
> +
> +	id = of_get_property(op->node, "port-number", NULL);
> +
> +	return ulite_assign(&op->dev, id ? *id : -1, res.start, irq);
> +}
> +
> +static int __devexit ulite_of_remove(struct of_device *op)
> +{
> +	return ulite_release(&op->dev);
> +}
> +
> +/* Match table for of_platform binding */
> +static struct of_device_id __devinit ulite_of_match[] = {
> +	{ .type = "serial", .compatible = "xilinx,uartlite", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, ulite_of_match);
> +
> +static struct of_platform_driver ulite_of_driver = {
> +	.owner = THIS_MODULE,
> +	.name = "uartlite",
> +	.match_table = ulite_of_match,
> +	.probe = ulite_of_probe,
> +	.remove = __devexit_p(ulite_of_remove),
> +	.driver = {
> +		.name = "uartlite",
> +	},
> +};
> +
> +/* Registration helpers to keep the number of #ifdefs to a minimum */
> +static inline int __init ulite_of_register(void)
> +{
> +	pr_debug("uartlite: calling of_register_platform_driver()\n");
> +	return of_register_platform_driver(&ulite_of_driver);
> +}
> +
> +static inline void __exit ulite_of_unregister(void)
> +{
> +	of_unregister_platform_driver(&ulite_of_driver);
> +}
> +#else /* CONFIG_OF */
> +/* CONFIG_OF not enabled; do nothing helpers */
> +static inline int __init ulite_of_register(void) { return 0; }
> +static inline void __exit ulite_of_unregister(void) { }
> +#endif /* CONFIG_OF */
> +
> +/* ---------------------------------------------------------------------
>   * Module setup/teardown
>   */
>  
> @@ -549,20 +622,32 @@ int __init ulite_init(void)
>  {
>  	int ret;
>  
> -	ret = uart_register_driver(&ulite_uart_driver);
> -	if (ret)
> -		return ret;
> +	pr_debug("uartlite: calling uart_register_driver()\n");
> +	if ((ret = uart_register_driver(&ulite_uart_driver)) != 0)
> +		goto err_uart;
>  
> -	ret = platform_driver_register(&ulite_platform_driver);
> -	if (ret)
> -		uart_unregister_driver(&ulite_uart_driver);
> +	if ((ret = ulite_of_register()) != 0)
> +		goto err_of;
>  
> +	pr_debug("uartlite: calling platform_driver_register()\n");
> +	if ((ret = platform_driver_register(&ulite_platform_driver)) != 0)
> +		goto err_plat;
> +
> +	return 0;
> +
> +err_plat:
> +	ulite_of_unregister();
> +err_of:
> +	uart_unregister_driver(&ulite_uart_driver);
> +err_uart:
> +	printk(KERN_ERR "registering uartlite driver failed: err=%i", ret);
>  	return ret;
>  }
>  
>  void __exit ulite_exit(void)
>  {
>  	platform_driver_unregister(&ulite_platform_driver);
> +	ulite_of_unregister();
>  	uart_unregister_driver(&ulite_uart_driver);
>  }
>  
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH 6/7] Add dcr_map_reg() helper
From: Michael Ellerman @ 2007-10-02  5:51 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1191302382.6310.80.camel@pasglop>

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

On Tue, 2007-10-02 at 15:19 +1000, Benjamin Herrenschmidt wrote:
> On Mon, 2007-09-17 at 16:05 +1000, Michael Ellerman wrote:
> > Add a helper routine to map dcr's based on the "dcr-reg" property of
> > a device node.
> > 
> > Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
> 
> Wouldn't it be more consistent to call it of_map_dcr ? Or maybe find an
> even better name, but dcr_map_reg really sucks :-)

That would give us dcr_map(), dcr_unmap() and of_map_dcr() - which
doesn't strike me as more consistent.

I don't particularly like dcr_map_reg(), but I think it's at least
obvious that it's a variant of dcr_map() and that it has something to do
with a "reg" .. maybe even a "dcr-reg" :)

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply


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