LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: powerpc: Move /proc/ppc64 to /proc/powerpc and add symlink
From: Stephen Rothwell @ 2009-09-25  6:28 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list
In-Reply-To: <1253856553.7103.513.camel@pasglop>

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

Hi Ben,

On Fri, 25 Sep 2009 15:29:13 +1000 Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
>  obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
>  obj-$(CONFIG_PPC_OF)		+= of_device.o of_platform.o prom_parse.o
>  obj-$(CONFIG_PPC_CLOCK)		+= clock.o
> -procfs-$(CONFIG_PPC64)		:= proc_ppc64.o
> +procfs-y			:= proc_powerpc.o
>  obj-$(CONFIG_PROC_FS)		+= $(procfs-y)

Surely just:

obj-$(CONFIG_PROC_FS)		+= proc_powerpc.o

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* powerpc/chrp: Use the same RTAS daemon as pSeries
From: Benjamin Herrenschmidt @ 2009-09-25  5:30 UTC (permalink / raw)
  To: linuxppc-dev list

The CHRP code has some fishy timer based code to scan the RTAS event
log, which uses a 1KB stack buffer and doesn't even use the results.

The pSeries code as a nicer daemon that allows userspace to read the
event log and basically uses the same RTAS interface

This patch moves rtasd.c out of platform/pseries and makes it usable
by CHRP, after removing the old crufty event log mechanism in there.

The nvram logging part of the daemon is still only available on 64-bit
since the underlying nvram management routines aren't currently shared.

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

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 3faa391..c002b04 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -46,6 +46,7 @@ procfs-y			:= proc_powerpc.o
 obj-$(CONFIG_PROC_FS)		+= $(procfs-y)
 rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI)	:= rtas_pci.o
 obj-$(CONFIG_PPC_RTAS)		+= rtas.o rtas-rtc.o $(rtaspci-y-y)
+obj-$(CONFIG_PPC_RTAS_DAEMON)	+= rtasd.o
 obj-$(CONFIG_RTAS_FLASH)	+= rtas_flash.o
 obj-$(CONFIG_RTAS_PROC)		+= rtas-proc.o
 obj-$(CONFIG_LPARCFG)		+= lparcfg.o
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
new file mode 100644
index 0000000..2e4832a
--- /dev/null
+++ b/arch/powerpc/kernel/rtasd.c
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * 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.
+ *
+ * Communication to userspace based on kernel/printk.c
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+#include <linux/cpu.h>
+#include <linux/workqueue.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+#include <asm/nvram.h>
+#include <asm/atomic.h>
+#include <asm/machdep.h>
+
+
+static DEFINE_SPINLOCK(rtasd_log_lock);
+
+static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
+
+static char *rtas_log_buf;
+static unsigned long rtas_log_start;
+static unsigned long rtas_log_size;
+
+static int surveillance_timeout = -1;
+
+static unsigned int rtas_error_log_max;
+static unsigned int rtas_error_log_buffer_max;
+
+/* RTAS service tokens */
+static unsigned int event_scan;
+static unsigned int rtas_event_scan_rate;
+
+static int full_rtas_msgs = 0;
+
+/* Stop logging to nvram after first fatal error */
+static int logging_enabled; /* Until we initialize everything,
+                             * make sure we don't try logging
+                             * anything */
+static int error_log_cnt;
+
+/*
+ * Since we use 32 bit RTAS, the physical address of this must be below
+ * 4G or else bad things happen. Allocate this in the kernel data and
+ * make it big enough.
+ */
+static unsigned char logdata[RTAS_ERROR_LOG_MAX];
+
+static char *rtas_type[] = {
+	"Unknown", "Retry", "TCE Error", "Internal Device Failure",
+	"Timeout", "Data Parity", "Address Parity", "Cache Parity",
+	"Address Invalid", "ECC Uncorrected", "ECC Corrupted",
+};
+
+static char *rtas_event_type(int type)
+{
+	if ((type > 0) && (type < 11))
+		return rtas_type[type];
+
+	switch (type) {
+		case RTAS_TYPE_EPOW:
+			return "EPOW";
+		case RTAS_TYPE_PLATFORM:
+			return "Platform Error";
+		case RTAS_TYPE_IO:
+			return "I/O Event";
+		case RTAS_TYPE_INFO:
+			return "Platform Information Event";
+		case RTAS_TYPE_DEALLOC:
+			return "Resource Deallocation Event";
+		case RTAS_TYPE_DUMP:
+			return "Dump Notification Event";
+	}
+
+	return rtas_type[0];
+}
+
+/* To see this info, grep RTAS /var/log/messages and each entry
+ * will be collected together with obvious begin/end.
+ * There will be a unique identifier on the begin and end lines.
+ * This will persist across reboots.
+ *
+ * format of error logs returned from RTAS:
+ * bytes	(size)	: contents
+ * --------------------------------------------------------
+ * 0-7		(8)	: rtas_error_log
+ * 8-47		(40)	: extended info
+ * 48-51	(4)	: vendor id
+ * 52-1023 (vendor specific) : location code and debug data
+ */
+static void printk_log_rtas(char *buf, int len)
+{
+
+	int i,j,n = 0;
+	int perline = 16;
+	char buffer[64];
+	char * str = "RTAS event";
+
+	if (full_rtas_msgs) {
+		printk(RTAS_DEBUG "%d -------- %s begin --------\n",
+		       error_log_cnt, str);
+
+		/*
+		 * Print perline bytes on each line, each line will start
+		 * with RTAS and a changing number, so syslogd will
+		 * print lines that are otherwise the same.  Separate every
+		 * 4 bytes with a space.
+		 */
+		for (i = 0; i < len; i++) {
+			j = i % perline;
+			if (j == 0) {
+				memset(buffer, 0, sizeof(buffer));
+				n = sprintf(buffer, "RTAS %d:", i/perline);
+			}
+
+			if ((i % 4) == 0)
+				n += sprintf(buffer+n, " ");
+
+			n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]);
+
+			if (j == (perline-1))
+				printk(KERN_DEBUG "%s\n", buffer);
+		}
+		if ((i % perline) != 0)
+			printk(KERN_DEBUG "%s\n", buffer);
+
+		printk(RTAS_DEBUG "%d -------- %s end ----------\n",
+		       error_log_cnt, str);
+	} else {
+		struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
+
+		printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
+		       error_log_cnt, rtas_event_type(errlog->type),
+		       errlog->severity);
+	}
+}
+
+static int log_rtas_len(char * buf)
+{
+	int len;
+	struct rtas_error_log *err;
+
+	/* rtas fixed header */
+	len = 8;
+	err = (struct rtas_error_log *)buf;
+	if (err->extended_log_length) {
+
+		/* extended header */
+		len += err->extended_log_length;
+	}
+
+	if (rtas_error_log_max == 0)
+		rtas_error_log_max = rtas_get_error_log_max();
+
+	if (len > rtas_error_log_max)
+		len = rtas_error_log_max;
+
+	return len;
+}
+
+/*
+ * First write to nvram, if fatal error, that is the only
+ * place we log the info.  The error will be picked up
+ * on the next reboot by rtasd.  If not fatal, run the
+ * method for the type of error.  Currently, only RTAS
+ * errors have methods implemented, but in the future
+ * there might be a need to store data in nvram before a
+ * call to panic().
+ *
+ * XXX We write to nvram periodically, to indicate error has
+ * been written and sync'd, but there is a possibility
+ * that if we don't shutdown correctly, a duplicate error
+ * record will be created on next reboot.
+ */
+void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
+{
+	unsigned long offset;
+	unsigned long s;
+	int len = 0;
+
+	pr_debug("rtasd: logging event\n");
+	if (buf == NULL)
+		return;
+
+	spin_lock_irqsave(&rtasd_log_lock, s);
+
+	/* get length and increase count */
+	switch (err_type & ERR_TYPE_MASK) {
+	case ERR_TYPE_RTAS_LOG:
+		len = log_rtas_len(buf);
+		if (!(err_type & ERR_FLAG_BOOT))
+			error_log_cnt++;
+		break;
+	case ERR_TYPE_KERNEL_PANIC:
+	default:
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		return;
+	}
+
+#ifdef CONFIG_PPC64
+	/* Write error to NVRAM */
+	if (logging_enabled && !(err_type & ERR_FLAG_BOOT))
+		nvram_write_error_log(buf, len, err_type, error_log_cnt);
+#endif /* CONFIG_PPC64 */
+
+	/*
+	 * rtas errors can occur during boot, and we do want to capture
+	 * those somewhere, even if nvram isn't ready (why not?), and even
+	 * if rtasd isn't ready. Put them into the boot log, at least.
+	 */
+	if ((err_type & ERR_TYPE_MASK) == ERR_TYPE_RTAS_LOG)
+		printk_log_rtas(buf, len);
+
+	/* Check to see if we need to or have stopped logging */
+	if (fatal || !logging_enabled) {
+		logging_enabled = 0;
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		return;
+	}
+
+	/* call type specific method for error */
+	switch (err_type & ERR_TYPE_MASK) {
+	case ERR_TYPE_RTAS_LOG:
+		offset = rtas_error_log_buffer_max *
+			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
+
+		/* First copy over sequence number */
+		memcpy(&rtas_log_buf[offset], (void *) &error_log_cnt, sizeof(int));
+
+		/* Second copy over error log data */
+		offset += sizeof(int);
+		memcpy(&rtas_log_buf[offset], buf, len);
+
+		if (rtas_log_size < LOG_NUMBER)
+			rtas_log_size += 1;
+		else
+			rtas_log_start += 1;
+
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		wake_up_interruptible(&rtas_log_wait);
+		break;
+	case ERR_TYPE_KERNEL_PANIC:
+	default:
+		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		return;
+	}
+
+}
+
+static int rtas_log_open(struct inode * inode, struct file * file)
+{
+	return 0;
+}
+
+static int rtas_log_release(struct inode * inode, struct file * file)
+{
+	return 0;
+}
+
+/* This will check if all events are logged, if they are then, we
+ * know that we can safely clear the events in NVRAM.
+ * Next we'll sit and wait for something else to log.
+ */
+static ssize_t rtas_log_read(struct file * file, char __user * buf,
+			 size_t count, loff_t *ppos)
+{
+	int error;
+	char *tmp;
+	unsigned long s;
+	unsigned long offset;
+
+	if (!buf || count < rtas_error_log_buffer_max)
+		return -EINVAL;
+
+	count = rtas_error_log_buffer_max;
+
+	if (!access_ok(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+
+	tmp = kmalloc(count, GFP_KERNEL);
+	if (!tmp)
+		return -ENOMEM;
+
+	spin_lock_irqsave(&rtasd_log_lock, s);
+
+	/* if it's 0, then we know we got the last one (the one in NVRAM) */
+	while (rtas_log_size == 0) {
+		if (file->f_flags & O_NONBLOCK) {
+			spin_unlock_irqrestore(&rtasd_log_lock, s);
+			error = -EAGAIN;
+			goto out;
+		}
+
+		if (!logging_enabled) {
+			spin_unlock_irqrestore(&rtasd_log_lock, s);
+			error = -ENODATA;
+			goto out;
+		}
+#ifdef CONFIG_PPC64
+		nvram_clear_error_log();
+#endif /* CONFIG_PPC64 */
+
+		spin_unlock_irqrestore(&rtasd_log_lock, s);
+		error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
+		if (error)
+			goto out;
+		spin_lock_irqsave(&rtasd_log_lock, s);
+	}
+
+	offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
+	memcpy(tmp, &rtas_log_buf[offset], count);
+
+	rtas_log_start += 1;
+	rtas_log_size -= 1;
+	spin_unlock_irqrestore(&rtasd_log_lock, s);
+
+	error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
+out:
+	kfree(tmp);
+	return error;
+}
+
+static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
+{
+	poll_wait(file, &rtas_log_wait, wait);
+	if (rtas_log_size)
+		return POLLIN | POLLRDNORM;
+	return 0;
+}
+
+static const struct file_operations proc_rtas_log_operations = {
+	.read =		rtas_log_read,
+	.poll =		rtas_log_poll,
+	.open =		rtas_log_open,
+	.release =	rtas_log_release,
+};
+
+static int enable_surveillance(int timeout)
+{
+	int error;
+
+	error = rtas_set_indicator(SURVEILLANCE_TOKEN, 0, timeout);
+
+	if (error == 0)
+		return 0;
+
+	if (error == -EINVAL) {
+		printk(KERN_DEBUG "rtasd: surveillance not supported\n");
+		return 0;
+	}
+
+	printk(KERN_ERR "rtasd: could not update surveillance\n");
+	return -1;
+}
+
+static void do_event_scan(void)
+{
+	int error;
+	do {
+		memset(logdata, 0, rtas_error_log_max);
+		error = rtas_call(event_scan, 4, 1, NULL,
+				  RTAS_EVENT_SCAN_ALL_EVENTS, 0,
+				  __pa(logdata), rtas_error_log_max);
+		if (error == -1) {
+			printk(KERN_ERR "event-scan failed\n");
+			break;
+		}
+
+		if (error == 0)
+			pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
+
+	} while(error == 0);
+}
+
+static void rtas_event_scan(struct work_struct *w);
+DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
+
+/*
+ * Delay should be at least one second since some machines have problems if
+ * we call event-scan too quickly.
+ */
+static unsigned long event_scan_delay = 1*HZ;
+static int first_pass = 1;
+
+static void rtas_event_scan(struct work_struct *w)
+{
+	unsigned int cpu;
+
+	do_event_scan();
+
+	get_online_cpus();
+
+	cpu = next_cpu(smp_processor_id(), cpu_online_map);
+	if (cpu == NR_CPUS) {
+		cpu = first_cpu(cpu_online_map);
+
+		if (first_pass) {
+			first_pass = 0;
+			event_scan_delay = 30*HZ/rtas_event_scan_rate;
+
+			if (surveillance_timeout != -1) {
+				pr_debug("rtasd: enabling surveillance\n");
+				enable_surveillance(surveillance_timeout);
+				pr_debug("rtasd: surveillance enabled\n");
+			}
+		}
+	}
+
+	schedule_delayed_work_on(cpu, &event_scan_work,
+		__round_jiffies_relative(event_scan_delay, cpu));
+
+	put_online_cpus();
+}
+
+#ifdef CONFIG_PPC64
+static void retreive_nvram_error_log(void)
+{
+	unsigned int err_type ;
+	int rc ;
+
+	/* See if we have any error stored in NVRAM */
+	memset(logdata, 0, rtas_error_log_max);
+	rc = nvram_read_error_log(logdata, rtas_error_log_max,
+	                          &err_type, &error_log_cnt);
+	/* We can use rtas_log_buf now */
+	logging_enabled = 1;
+	if (!rc) {
+		if (err_type != ERR_FLAG_ALREADY_LOGGED) {
+			pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
+		}
+	}
+}
+#else /* CONFIG_PPC64 */
+static void retreive_nvram_error_log(void)
+{
+}
+#endif /* CONFIG_PPC64 */
+
+static void start_event_scan(void)
+{
+	printk(KERN_DEBUG "RTAS daemon started\n");
+	pr_debug("rtasd: will sleep for %d milliseconds\n",
+		 (30000 / rtas_event_scan_rate));
+
+	/* Retreive errors from nvram if any */
+	retreive_nvram_error_log();
+
+	schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
+				 event_scan_delay);
+}
+
+static int __init rtas_init(void)
+{
+	struct proc_dir_entry *entry;
+
+	if (!machine_is(pseries) && !machine_is(chrp))
+		return 0;
+
+	/* No RTAS */
+	event_scan = rtas_token("event-scan");
+	if (event_scan == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_INFO "rtasd: No event-scan on system\n");
+		return -ENODEV;
+	}
+
+	rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
+	if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
+		printk(KERN_ERR "rtasd: no rtas-event-scan-rate on system\n");
+		return -ENODEV;
+	}
+
+	/* Make room for the sequence number */
+	rtas_error_log_max = rtas_get_error_log_max();
+	rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
+
+	rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
+	if (!rtas_log_buf) {
+		printk(KERN_ERR "rtasd: no memory\n");
+		return -ENOMEM;
+	}
+
+	entry = proc_create("powerpc/rtas/error_log", S_IRUSR, NULL,
+			    &proc_rtas_log_operations);
+	if (!entry)
+		printk(KERN_ERR "Failed to create error_log proc entry\n");
+
+	start_event_scan();
+
+	return 0;
+}
+__initcall(rtas_init);
+
+static int __init surveillance_setup(char *str)
+{
+	int i;
+
+	/* We only do surveillance on pseries */
+	if (!machine_is(pseries))
+		return 0;
+
+	if (get_option(&str,&i)) {
+		if (i >= 0 && i <= 255)
+			surveillance_timeout = i;
+	}
+
+	return 1;
+}
+__setup("surveillance=", surveillance_setup);
+
+static int __init rtasmsgs_setup(char *str)
+{
+	if (strcmp(str, "on") == 0)
+		full_rtas_msgs = 1;
+	else if (strcmp(str, "off") == 0)
+		full_rtas_msgs = 0;
+
+	return 1;
+}
+__setup("rtasmsgs=", rtasmsgs_setup);
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 04a8061..56bf126 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -86,6 +86,11 @@ config RTAS_ERROR_LOGGING
 	depends on PPC_RTAS
 	default n
 
+config PPC_RTAS_DAEMON
+	bool
+	depends on PPC_RTAS
+	default n
+
 config RTAS_PROC
 	bool "Proc interface to RTAS"
 	depends on PPC_RTAS
diff --git a/arch/powerpc/platforms/chrp/Kconfig b/arch/powerpc/platforms/chrp/Kconfig
index 37d438b..bc0b0ef 100644
--- a/arch/powerpc/platforms/chrp/Kconfig
+++ b/arch/powerpc/platforms/chrp/Kconfig
@@ -5,6 +5,8 @@ config PPC_CHRP
 	select PPC_I8259
 	select PPC_INDIRECT_PCI
 	select PPC_RTAS
+	select PPC_RTAS_DAEMON
+	select RTAS_ERROR_LOGGING
 	select PPC_MPC106
 	select PPC_UDBG_16550
 	select PPC_NATIVE
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index cd4ad9a..52f3df3 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -364,19 +364,6 @@ void __init chrp_setup_arch(void)
 	if (ppc_md.progress) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
 }
 
-void
-chrp_event_scan(unsigned long unused)
-{
-	unsigned char log[1024];
-	int ret = 0;
-
-	/* XXX: we should loop until the hardware says no more error logs -- Cort */
-	rtas_call(rtas_token("event-scan"), 4, 1, &ret, 0xffffffff, 0,
-		  __pa(log), 1024);
-	mod_timer(&__get_cpu_var(heartbeat_timer),
-		  jiffies + event_scan_interval);
-}
-
 static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
 {
 	unsigned int cascade_irq = i8259_irq();
@@ -568,9 +555,6 @@ void __init chrp_init_IRQ(void)
 void __init
 chrp_init2(void)
 {
-	struct device_node *device;
-	const unsigned int *p = NULL;
-
 #ifdef CONFIG_NVRAM
 	chrp_nvram_init();
 #endif
@@ -582,40 +566,6 @@ chrp_init2(void)
 	request_region(0x80,0x10,"dma page reg");
 	request_region(0xc0,0x20,"dma2");
 
-	/* Get the event scan rate for the rtas so we know how
-	 * often it expects a heartbeat. -- Cort
-	 */
-	device = of_find_node_by_name(NULL, "rtas");
-	if (device)
-		p = of_get_property(device, "rtas-event-scan-rate", NULL);
-	if (p && *p) {
-		/*
-		 * Arrange to call chrp_event_scan at least *p times
-		 * per minute.  We use 59 rather than 60 here so that
-		 * the rate will be slightly higher than the minimum.
-		 * This all assumes we don't do hotplug CPU on any
-		 * machine that needs the event scans done.
-		 */
-		unsigned long interval, offset;
-		int cpu, ncpus;
-		struct timer_list *timer;
-
-		interval = HZ * 59 / *p;
-		offset = HZ;
-		ncpus = num_online_cpus();
-		event_scan_interval = ncpus * interval;
-		for (cpu = 0; cpu < ncpus; ++cpu) {
-			timer = &per_cpu(heartbeat_timer, cpu);
-			setup_timer(timer, chrp_event_scan, 0);
-			timer->expires = jiffies + offset;
-			add_timer_on(timer, cpu);
-			offset += interval;
-		}
-		printk("RTAS Event Scan Rate: %u (%lu jiffies)\n",
-		       *p, interval);
-	}
-	of_node_put(device);
-
 	if (ppc_md.progress)
 		ppc_md.progress("  Have fun!    ", 0x7777);
 }
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index f0e6f28..26a24bd 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -4,6 +4,7 @@ config PPC_PSERIES
 	select MPIC
 	select PPC_I8259
 	select PPC_RTAS
+	select PPC_RTAS_DAEMON
 	select RTAS_ERROR_LOGGING
 	select PPC_UDBG_16550
 	select PPC_NATIVE
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 790c0b8..4b1c422 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -7,7 +7,7 @@ EXTRA_CFLAGS		+= -DDEBUG
 endif
 
 obj-y			:= lpar.o hvCall.o nvram.o reconfig.o \
-			   setup.o iommu.o ras.o rtasd.o \
+			   setup.o iommu.o ras.o \
 			   firmware.o power.o
 obj-$(CONFIG_SMP)	+= smp.o
 obj-$(CONFIG_XICS)	+= xics.o
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c
deleted file mode 100644
index b3cbac8..0000000
--- a/arch/powerpc/platforms/pseries/rtasd.c
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
- *
- * 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.
- *
- * Communication to userspace based on kernel/printk.c
- */
-
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/spinlock.h>
-#include <linux/cpu.h>
-#include <linux/workqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/rtas.h>
-#include <asm/prom.h>
-#include <asm/nvram.h>
-#include <asm/atomic.h>
-#include <asm/machdep.h>
-
-
-static DEFINE_SPINLOCK(rtasd_log_lock);
-
-static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
-
-static char *rtas_log_buf;
-static unsigned long rtas_log_start;
-static unsigned long rtas_log_size;
-
-static int surveillance_timeout = -1;
-static unsigned int rtas_error_log_max;
-static unsigned int rtas_error_log_buffer_max;
-
-/* RTAS service tokens */
-static unsigned int event_scan;
-static unsigned int rtas_event_scan_rate;
-
-static int full_rtas_msgs = 0;
-
-/* Stop logging to nvram after first fatal error */
-static int logging_enabled; /* Until we initialize everything,
-                             * make sure we don't try logging
-                             * anything */
-static int error_log_cnt;
-
-/*
- * Since we use 32 bit RTAS, the physical address of this must be below
- * 4G or else bad things happen. Allocate this in the kernel data and
- * make it big enough.
- */
-static unsigned char logdata[RTAS_ERROR_LOG_MAX];
-
-static char *rtas_type[] = {
-	"Unknown", "Retry", "TCE Error", "Internal Device Failure",
-	"Timeout", "Data Parity", "Address Parity", "Cache Parity",
-	"Address Invalid", "ECC Uncorrected", "ECC Corrupted",
-};
-
-static char *rtas_event_type(int type)
-{
-	if ((type > 0) && (type < 11))
-		return rtas_type[type];
-
-	switch (type) {
-		case RTAS_TYPE_EPOW:
-			return "EPOW";
-		case RTAS_TYPE_PLATFORM:
-			return "Platform Error";
-		case RTAS_TYPE_IO:
-			return "I/O Event";
-		case RTAS_TYPE_INFO:
-			return "Platform Information Event";
-		case RTAS_TYPE_DEALLOC:
-			return "Resource Deallocation Event";
-		case RTAS_TYPE_DUMP:
-			return "Dump Notification Event";
-	}
-
-	return rtas_type[0];
-}
-
-/* To see this info, grep RTAS /var/log/messages and each entry
- * will be collected together with obvious begin/end.
- * There will be a unique identifier on the begin and end lines.
- * This will persist across reboots.
- *
- * format of error logs returned from RTAS:
- * bytes	(size)	: contents
- * --------------------------------------------------------
- * 0-7		(8)	: rtas_error_log
- * 8-47		(40)	: extended info
- * 48-51	(4)	: vendor id
- * 52-1023 (vendor specific) : location code and debug data
- */
-static void printk_log_rtas(char *buf, int len)
-{
-
-	int i,j,n = 0;
-	int perline = 16;
-	char buffer[64];
-	char * str = "RTAS event";
-
-	if (full_rtas_msgs) {
-		printk(RTAS_DEBUG "%d -------- %s begin --------\n",
-		       error_log_cnt, str);
-
-		/*
-		 * Print perline bytes on each line, each line will start
-		 * with RTAS and a changing number, so syslogd will
-		 * print lines that are otherwise the same.  Separate every
-		 * 4 bytes with a space.
-		 */
-		for (i = 0; i < len; i++) {
-			j = i % perline;
-			if (j == 0) {
-				memset(buffer, 0, sizeof(buffer));
-				n = sprintf(buffer, "RTAS %d:", i/perline);
-			}
-
-			if ((i % 4) == 0)
-				n += sprintf(buffer+n, " ");
-
-			n += sprintf(buffer+n, "%02x", (unsigned char)buf[i]);
-
-			if (j == (perline-1))
-				printk(KERN_DEBUG "%s\n", buffer);
-		}
-		if ((i % perline) != 0)
-			printk(KERN_DEBUG "%s\n", buffer);
-
-		printk(RTAS_DEBUG "%d -------- %s end ----------\n",
-		       error_log_cnt, str);
-	} else {
-		struct rtas_error_log *errlog = (struct rtas_error_log *)buf;
-
-		printk(RTAS_DEBUG "event: %d, Type: %s, Severity: %d\n",
-		       error_log_cnt, rtas_event_type(errlog->type),
-		       errlog->severity);
-	}
-}
-
-static int log_rtas_len(char * buf)
-{
-	int len;
-	struct rtas_error_log *err;
-
-	/* rtas fixed header */
-	len = 8;
-	err = (struct rtas_error_log *)buf;
-	if (err->extended_log_length) {
-
-		/* extended header */
-		len += err->extended_log_length;
-	}
-
-	if (rtas_error_log_max == 0)
-		rtas_error_log_max = rtas_get_error_log_max();
-
-	if (len > rtas_error_log_max)
-		len = rtas_error_log_max;
-
-	return len;
-}
-
-/*
- * First write to nvram, if fatal error, that is the only
- * place we log the info.  The error will be picked up
- * on the next reboot by rtasd.  If not fatal, run the
- * method for the type of error.  Currently, only RTAS
- * errors have methods implemented, but in the future
- * there might be a need to store data in nvram before a
- * call to panic().
- *
- * XXX We write to nvram periodically, to indicate error has
- * been written and sync'd, but there is a possibility
- * that if we don't shutdown correctly, a duplicate error
- * record will be created on next reboot.
- */
-void pSeries_log_error(char *buf, unsigned int err_type, int fatal)
-{
-	unsigned long offset;
-	unsigned long s;
-	int len = 0;
-
-	pr_debug("rtasd: logging event\n");
-	if (buf == NULL)
-		return;
-
-	spin_lock_irqsave(&rtasd_log_lock, s);
-
-	/* get length and increase count */
-	switch (err_type & ERR_TYPE_MASK) {
-	case ERR_TYPE_RTAS_LOG:
-		len = log_rtas_len(buf);
-		if (!(err_type & ERR_FLAG_BOOT))
-			error_log_cnt++;
-		break;
-	case ERR_TYPE_KERNEL_PANIC:
-	default:
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		return;
-	}
-
-	/* Write error to NVRAM */
-	if (logging_enabled && !(err_type & ERR_FLAG_BOOT))
-		nvram_write_error_log(buf, len, err_type, error_log_cnt);
-
-	/*
-	 * rtas errors can occur during boot, and we do want to capture
-	 * those somewhere, even if nvram isn't ready (why not?), and even
-	 * if rtasd isn't ready. Put them into the boot log, at least.
-	 */
-	if ((err_type & ERR_TYPE_MASK) == ERR_TYPE_RTAS_LOG)
-		printk_log_rtas(buf, len);
-
-	/* Check to see if we need to or have stopped logging */
-	if (fatal || !logging_enabled) {
-		logging_enabled = 0;
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		return;
-	}
-
-	/* call type specific method for error */
-	switch (err_type & ERR_TYPE_MASK) {
-	case ERR_TYPE_RTAS_LOG:
-		offset = rtas_error_log_buffer_max *
-			((rtas_log_start+rtas_log_size) & LOG_NUMBER_MASK);
-
-		/* First copy over sequence number */
-		memcpy(&rtas_log_buf[offset], (void *) &error_log_cnt, sizeof(int));
-
-		/* Second copy over error log data */
-		offset += sizeof(int);
-		memcpy(&rtas_log_buf[offset], buf, len);
-
-		if (rtas_log_size < LOG_NUMBER)
-			rtas_log_size += 1;
-		else
-			rtas_log_start += 1;
-
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		wake_up_interruptible(&rtas_log_wait);
-		break;
-	case ERR_TYPE_KERNEL_PANIC:
-	default:
-		WARN_ON_ONCE(!irqs_disabled()); /* @@@ DEBUG @@@ */
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		return;
-	}
-
-}
-
-
-static int rtas_log_open(struct inode * inode, struct file * file)
-{
-	return 0;
-}
-
-static int rtas_log_release(struct inode * inode, struct file * file)
-{
-	return 0;
-}
-
-/* This will check if all events are logged, if they are then, we
- * know that we can safely clear the events in NVRAM.
- * Next we'll sit and wait for something else to log.
- */
-static ssize_t rtas_log_read(struct file * file, char __user * buf,
-			 size_t count, loff_t *ppos)
-{
-	int error;
-	char *tmp;
-	unsigned long s;
-	unsigned long offset;
-
-	if (!buf || count < rtas_error_log_buffer_max)
-		return -EINVAL;
-
-	count = rtas_error_log_buffer_max;
-
-	if (!access_ok(VERIFY_WRITE, buf, count))
-		return -EFAULT;
-
-	tmp = kmalloc(count, GFP_KERNEL);
-	if (!tmp)
-		return -ENOMEM;
-
-	spin_lock_irqsave(&rtasd_log_lock, s);
-	/* if it's 0, then we know we got the last one (the one in NVRAM) */
-	while (rtas_log_size == 0) {
-		if (file->f_flags & O_NONBLOCK) {
-			spin_unlock_irqrestore(&rtasd_log_lock, s);
-			error = -EAGAIN;
-			goto out;
-		}
-
-		if (!logging_enabled) {
-			spin_unlock_irqrestore(&rtasd_log_lock, s);
-			error = -ENODATA;
-			goto out;
-		}
-		nvram_clear_error_log();
-
-		spin_unlock_irqrestore(&rtasd_log_lock, s);
-		error = wait_event_interruptible(rtas_log_wait, rtas_log_size);
-		if (error)
-			goto out;
-		spin_lock_irqsave(&rtasd_log_lock, s);
-	}
-
-	offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK);
-	memcpy(tmp, &rtas_log_buf[offset], count);
-
-	rtas_log_start += 1;
-	rtas_log_size -= 1;
-	spin_unlock_irqrestore(&rtasd_log_lock, s);
-
-	error = copy_to_user(buf, tmp, count) ? -EFAULT : count;
-out:
-	kfree(tmp);
-	return error;
-}
-
-static unsigned int rtas_log_poll(struct file *file, poll_table * wait)
-{
-	poll_wait(file, &rtas_log_wait, wait);
-	if (rtas_log_size)
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-static const struct file_operations proc_rtas_log_operations = {
-	.read =		rtas_log_read,
-	.poll =		rtas_log_poll,
-	.open =		rtas_log_open,
-	.release =	rtas_log_release,
-};
-
-static int enable_surveillance(int timeout)
-{
-	int error;
-
-	error = rtas_set_indicator(SURVEILLANCE_TOKEN, 0, timeout);
-
-	if (error == 0)
-		return 0;
-
-	if (error == -EINVAL) {
-		printk(KERN_DEBUG "rtasd: surveillance not supported\n");
-		return 0;
-	}
-
-	printk(KERN_ERR "rtasd: could not update surveillance\n");
-	return -1;
-}
-
-static void do_event_scan(void)
-{
-	int error;
-	do {
-		memset(logdata, 0, rtas_error_log_max);
-		error = rtas_call(event_scan, 4, 1, NULL,
-				  RTAS_EVENT_SCAN_ALL_EVENTS, 0,
-				  __pa(logdata), rtas_error_log_max);
-		if (error == -1) {
-			printk(KERN_ERR "event-scan failed\n");
-			break;
-		}
-
-		if (error == 0)
-			pSeries_log_error(logdata, ERR_TYPE_RTAS_LOG, 0);
-
-	} while(error == 0);
-}
-
-static void rtas_event_scan(struct work_struct *w);
-DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
-
-/*
- * Delay should be at least one second since some machines have problems if
- * we call event-scan too quickly.
- */
-static unsigned long event_scan_delay = 1*HZ;
-static int first_pass = 1;
-
-static void rtas_event_scan(struct work_struct *w)
-{
-	unsigned int cpu;
-
-	do_event_scan();
-
-	get_online_cpus();
-
-	cpu = next_cpu(smp_processor_id(), cpu_online_map);
-	if (cpu == NR_CPUS) {
-		cpu = first_cpu(cpu_online_map);
-
-		if (first_pass) {
-			first_pass = 0;
-			event_scan_delay = 30*HZ/rtas_event_scan_rate;
-
-			if (surveillance_timeout != -1) {
-				pr_debug("rtasd: enabling surveillance\n");
-				enable_surveillance(surveillance_timeout);
-				pr_debug("rtasd: surveillance enabled\n");
-			}
-		}
-	}
-
-	schedule_delayed_work_on(cpu, &event_scan_work,
-		__round_jiffies_relative(event_scan_delay, cpu));
-
-	put_online_cpus();
-}
-
-static void start_event_scan(void)
-{
-	unsigned int err_type;
-	int rc;
-
-	printk(KERN_DEBUG "RTAS daemon started\n");
-	pr_debug("rtasd: will sleep for %d milliseconds\n",
-		 (30000 / rtas_event_scan_rate));
-
-	/* See if we have any error stored in NVRAM */
-	memset(logdata, 0, rtas_error_log_max);
-	rc = nvram_read_error_log(logdata, rtas_error_log_max,
-	                          &err_type, &error_log_cnt);
-	/* We can use rtas_log_buf now */
-	logging_enabled = 1;
-
-	if (!rc) {
-		if (err_type != ERR_FLAG_ALREADY_LOGGED) {
-			pSeries_log_error(logdata, err_type | ERR_FLAG_BOOT, 0);
-		}
-	}
-
-	schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
-				 event_scan_delay);
-}
-
-static int __init rtas_init(void)
-{
-	struct proc_dir_entry *entry;
-
-	if (!machine_is(pseries))
-		return 0;
-
-	/* No RTAS */
-	event_scan = rtas_token("event-scan");
-	if (event_scan == RTAS_UNKNOWN_SERVICE) {
-		printk(KERN_DEBUG "rtasd: no event-scan on system\n");
-		return -ENODEV;
-	}
-
-	rtas_event_scan_rate = rtas_token("rtas-event-scan-rate");
-	if (rtas_event_scan_rate == RTAS_UNKNOWN_SERVICE) {
-		printk(KERN_ERR "rtasd: no rtas-event-scan-rate on system\n");
-		return -ENODEV;
-	}
-
-	/* Make room for the sequence number */
-	rtas_error_log_max = rtas_get_error_log_max();
-	rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
-
-	rtas_log_buf = vmalloc(rtas_error_log_buffer_max*LOG_NUMBER);
-	if (!rtas_log_buf) {
-		printk(KERN_ERR "rtasd: no memory\n");
-		return -ENOMEM;
-	}
-
-	entry = proc_create("ppc64/rtas/error_log", S_IRUSR, NULL,
-			    &proc_rtas_log_operations);
-	if (!entry)
-		printk(KERN_ERR "Failed to create error_log proc entry\n");
-
-	start_event_scan();
-
-	return 0;
-}
-
-static int __init surveillance_setup(char *str)
-{
-	int i;
-
-	if (get_option(&str,&i)) {
-		if (i >= 0 && i <= 255)
-			surveillance_timeout = i;
-	}
-
-	return 1;
-}
-
-static int __init rtasmsgs_setup(char *str)
-{
-	if (strcmp(str, "on") == 0)
-		full_rtas_msgs = 1;
-	else if (strcmp(str, "off") == 0)
-		full_rtas_msgs = 0;
-
-	return 1;
-}
-__initcall(rtas_init);
-__setup("surveillance=", surveillance_setup);
-__setup("rtasmsgs=", rtasmsgs_setup);

^ permalink raw reply related

* powerpc: Move /proc/ppc64 to /proc/powerpc and add symlink
From: Benjamin Herrenschmidt @ 2009-09-25  5:29 UTC (permalink / raw)
  To: linuxppc-dev list

Some of the stuff in /proc/ppc64 such as the RTAS bits are actually
useful to some 32-bit platforms. Rename the file, and create a
symlink on 64-bit for backward compatibility

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

diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index b23664a..3faa391 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -42,7 +42,7 @@ obj-$(CONFIG_ALTIVEC)		+= vecemu.o
 obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
 obj-$(CONFIG_PPC_OF)		+= of_device.o of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)		+= clock.o
-procfs-$(CONFIG_PPC64)		:= proc_ppc64.o
+procfs-y			:= proc_powerpc.o
 obj-$(CONFIG_PROC_FS)		+= $(procfs-y)
 rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI)	:= rtas_pci.o
 obj-$(CONFIG_PPC_RTAS)		+= rtas.o rtas-rtc.o $(rtaspci-y-y)
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index ed0ac4e..79a00bb 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -781,9 +781,9 @@ static int __init lparcfg_init(void)
 			!firmware_has_feature(FW_FEATURE_ISERIES))
 		mode |= S_IWUSR;
 
-	ent = proc_create("ppc64/lparcfg", mode, NULL, &lparcfg_fops);
+	ent = proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops);
 	if (!ent) {
-		printk(KERN_ERR "Failed to create ppc64/lparcfg\n");
+		printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
 		return -EIO;
 	}
 
diff --git a/arch/powerpc/kernel/proc_powerpc.c b/arch/powerpc/kernel/proc_powerpc.c
new file mode 100644
index 0000000..1ed3b8d
--- /dev/null
+++ b/arch/powerpc/kernel/proc_powerpc.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+
+#include <asm/machdep.h>
+#include <asm/vdso_datapage.h>
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+#include <asm/prom.h>
+
+#ifdef CONFIG_PPC64
+
+static loff_t page_map_seek( struct file *file, loff_t off, int whence)
+{
+	loff_t new;
+	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
+
+	switch(whence) {
+	case 0:
+		new = off;
+		break;
+	case 1:
+		new = file->f_pos + off;
+		break;
+	case 2:
+		new = dp->size + off;
+		break;
+	default:
+		return -EINVAL;
+	}
+	if ( new < 0 || new > dp->size )
+		return -EINVAL;
+	return (file->f_pos = new);
+}
+
+static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
+			      loff_t *ppos)
+{
+	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
+	return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
+}
+
+static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
+{
+	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
+
+	if ((vma->vm_end - vma->vm_start) > dp->size)
+		return -EINVAL;
+
+	remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
+						dp->size, vma->vm_page_prot);
+	return 0;
+}
+
+static const struct file_operations page_map_fops = {
+	.llseek	= page_map_seek,
+	.read	= page_map_read,
+	.mmap	= page_map_mmap
+};
+
+
+static int __init proc_ppc64_init(void)
+{
+	struct proc_dir_entry *pde;
+
+	pde = proc_create_data("powerpc/systemcfg", S_IFREG|S_IRUGO, NULL,
+			       &page_map_fops, vdso_data);
+	if (!pde)
+		return 1;
+	pde->size = PAGE_SIZE;
+
+	return 0;
+}
+__initcall(proc_ppc64_init);
+
+#endif /* CONFIG_PPC64 */
+
+/*
+ * Create the ppc64 and ppc64/rtas directories early. This allows us to
+ * assume that they have been previously created in drivers.
+ */
+static int __init proc_ppc64_create(void)
+{
+	struct proc_dir_entry *root;
+
+	root = proc_mkdir("powerpc", NULL);
+	if (!root)
+		return 1;
+
+#ifdef CONFIG_PPC64
+	if (!proc_symlink("ppc64", NULL, "powerpc"))
+		pr_err("Failed to create link /proc/ppc64 -> /proc/powerpc\n");
+#endif
+
+	if (!of_find_node_by_path("/rtas"))
+		return 0;
+
+	if (!proc_mkdir("rtas", root))
+		return 1;
+
+	if (!proc_symlink("rtas", NULL, "powerpc/rtas"))
+		return 1;
+
+	return 0;
+}
+core_initcall(proc_ppc64_create);
diff --git a/arch/powerpc/kernel/proc_ppc64.c b/arch/powerpc/kernel/proc_ppc64.c
deleted file mode 100644
index c647dde..0000000
--- a/arch/powerpc/kernel/proc_ppc64.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/kernel.h>
-
-#include <asm/machdep.h>
-#include <asm/vdso_datapage.h>
-#include <asm/rtas.h>
-#include <asm/uaccess.h>
-#include <asm/prom.h>
-
-static loff_t  page_map_seek( struct file *file, loff_t off, int whence);
-static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
-			      loff_t *ppos);
-static int     page_map_mmap( struct file *file, struct vm_area_struct *vma );
-
-static const struct file_operations page_map_fops = {
-	.llseek	= page_map_seek,
-	.read	= page_map_read,
-	.mmap	= page_map_mmap
-};
-
-/*
- * Create the ppc64 and ppc64/rtas directories early. This allows us to
- * assume that they have been previously created in drivers.
- */
-static int __init proc_ppc64_create(void)
-{
-	struct proc_dir_entry *root;
-
-	root = proc_mkdir("ppc64", NULL);
-	if (!root)
-		return 1;
-
-	if (!of_find_node_by_path("/rtas"))
-		return 0;
-
-	if (!proc_mkdir("rtas", root))
-		return 1;
-
-	if (!proc_symlink("rtas", NULL, "ppc64/rtas"))
-		return 1;
-
-	return 0;
-}
-core_initcall(proc_ppc64_create);
-
-static int __init proc_ppc64_init(void)
-{
-	struct proc_dir_entry *pde;
-
-	pde = proc_create_data("ppc64/systemcfg", S_IFREG|S_IRUGO, NULL,
-			       &page_map_fops, vdso_data);
-	if (!pde)
-		return 1;
-	pde->size = PAGE_SIZE;
-
-	return 0;
-}
-__initcall(proc_ppc64_init);
-
-static loff_t page_map_seek( struct file *file, loff_t off, int whence)
-{
-	loff_t new;
-	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
-
-	switch(whence) {
-	case 0:
-		new = off;
-		break;
-	case 1:
-		new = file->f_pos + off;
-		break;
-	case 2:
-		new = dp->size + off;
-		break;
-	default:
-		return -EINVAL;
-	}
-	if ( new < 0 || new > dp->size )
-		return -EINVAL;
-	return (file->f_pos = new);
-}
-
-static ssize_t page_map_read( struct file *file, char __user *buf, size_t nbytes,
-			      loff_t *ppos)
-{
-	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
-	return simple_read_from_buffer(buf, nbytes, ppos, dp->data, dp->size);
-}
-
-static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
-{
-	struct proc_dir_entry *dp = PDE(file->f_path.dentry->d_inode);
-
-	if ((vma->vm_end - vma->vm_start) > dp->size)
-		return -EINVAL;
-
-	remap_pfn_range(vma, vma->vm_start, __pa(dp->data) >> PAGE_SHIFT,
-						dp->size, vma->vm_page_prot);
-	return 0;
-}
-
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 13011a9..a85117d 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -6,7 +6,7 @@
  *      as published by the Free Software Foundation; either version
  *      2 of the License, or (at your option) any later version.
  *
- * /proc/ppc64/rtas/firmware_flash interface
+ * /proc/powerpc/rtas/firmware_flash interface
  *
  * This file implements a firmware_flash interface to pump a firmware
  * image into the kernel.  At reboot time rtas_restart() will see the
@@ -740,7 +740,7 @@ static int __init rtas_flash_init(void)
 		return 1;
 	}
 
-	firmware_flash_pde = create_flash_pde("ppc64/rtas/"
+	firmware_flash_pde = create_flash_pde("powerpc/rtas/"
 					      FIRMWARE_FLASH_NAME,
 					      &rtas_flash_operations);
 	if (firmware_flash_pde == NULL) {
@@ -754,7 +754,7 @@ static int __init rtas_flash_init(void)
 	if (rc != 0)
 		goto cleanup;
 
-	firmware_update_pde = create_flash_pde("ppc64/rtas/"
+	firmware_update_pde = create_flash_pde("powerpc/rtas/"
 					       FIRMWARE_UPDATE_NAME,
 					       &rtas_flash_operations);
 	if (firmware_update_pde == NULL) {
@@ -768,7 +768,7 @@ static int __init rtas_flash_init(void)
 	if (rc != 0)
 		goto cleanup;
 
-	validate_pde = create_flash_pde("ppc64/rtas/" VALIDATE_FLASH_NAME,
+	validate_pde = create_flash_pde("powerpc/rtas/" VALIDATE_FLASH_NAME,
 			      		&validate_flash_operations);
 	if (validate_pde == NULL) {
 		rc = -ENOMEM;
@@ -781,7 +781,7 @@ static int __init rtas_flash_init(void)
 	if (rc != 0)
 		goto cleanup;
 
-	manage_pde = create_flash_pde("ppc64/rtas/" MANAGE_FLASH_NAME,
+	manage_pde = create_flash_pde("powerpc/rtas/" MANAGE_FLASH_NAME,
 				      &manage_flash_operations);
 	if (manage_pde == NULL) {
 		rc = -ENOMEM;
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 2e2bbe1..5182d2b 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -184,7 +184,7 @@ static int pSeries_reconfig_remove_node(struct device_node *np)
 }
 
 /*
- * /proc/ppc64/ofdt - yucky binary interface for adding and removing
+ * /proc/powerpc/ofdt - yucky binary interface for adding and removing
  * OF device nodes.  Should be deprecated as soon as we get an
  * in-kernel wrapper for the RTAS ibm,configure-connector call.
  */
@@ -543,7 +543,7 @@ static const struct file_operations ofdt_fops = {
 	.write = ofdt_write
 };
 
-/* create /proc/ppc64/ofdt write-only by root */
+/* create /proc/powerpc/ofdt write-only by root */
 static int proc_ppc64_create_ofdt(void)
 {
 	struct proc_dir_entry *ent;
@@ -551,7 +551,7 @@ static int proc_ppc64_create_ofdt(void)
 	if (!machine_is(pseries))
 		return 0;
 
-	ent = proc_create("ppc64/ofdt", S_IWUSR, NULL, &ofdt_fops);
+	ent = proc_create("powerpc/ofdt", S_IWUSR, NULL, &ofdt_fops);
 	if (ent)
 		ent->size = 0;
 
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c
index 417eca7..1b45c45 100644
--- a/arch/powerpc/platforms/pseries/scanlog.c
+++ b/arch/powerpc/platforms/pseries/scanlog.c
@@ -13,7 +13,7 @@
  * of this data using this driver.  A dump exists if the device-tree
  * /chosen/ibm,scan-log-data property exists.
  *
- * This driver exports /proc/ppc64/scan-log-dump which can be read.
+ * This driver exports /proc/powerpc/scan-log-dump which can be read.
  * The driver supports only sequential reads.
  *
  * The driver looks at a write to the driver for the single word "reset".
@@ -186,7 +186,7 @@ static int __init scanlog_init(void)
 	if (!data)
 		goto err;
 
-	ent = proc_create_data("ppc64/rtas/scan-log-dump", S_IRUSR, NULL,
+	ent = proc_create_data("powerpc/rtas/scan-log-dump", S_IRUSR, NULL,
 			       &scanlog_fops, data);
 	if (!ent)
 		goto err;

^ permalink raw reply related

* Re: [patch] powerpc: build modules outside the kernel tree fails, if it was built using O=
From: Sam Ravnborg @ 2009-09-25  4:39 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: linuxppc-dev, linux-kbuild, Yuri Frolov, rep.dot.nop
In-Reply-To: <1253841141.7103.489.camel@pasglop>

On Fri, Sep 25, 2009 at 11:12:21AM +1000, Benjamin Herrenschmidt wrote:
> On Thu, 2009-09-24 at 15:28 +0400, Yuri Frolov wrote:
> > Hello,
> > 
> > here is a corresponding bug: http://bugzilla.kernel.org/show_bug.cgi?id=11143
> > This patch should correctly export crtsavres.o in order to make O= option working.
> > Please, consider to apply.
> > 
> > 
> > Fix linking modules against crtsavres.o
> 
> Hi !
> 
> This is the same patch you already posted as "
> 
> 
> [PATCH] Fix linking modules against
> crtsavres.o
> "
> 
> Or it's an update ?
> 
> I've asked Sam to review it already since it affects the main kernel
> makefiles, waiting for his answer.
Saw the duplicates. Will get back to it tonight (morning here now).

	Sam

^ permalink raw reply

* [PATCH][v4] powerpc/85xx: Added P1020RDB Platform support.
From: Poonam Aggrwal @ 2009-09-25  4:20 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Poonam Aggrwal

P1020 is another member of Freescale QorIQ series of processors.
It is an e500 based dual core SOC.
Being a scaled down version of P2020 it has following differences from P2020:
- 533MHz - 800MHz core frequency.
- 256Kbyte L2 cache
- Ethernet controllers with classification capabilities(new controller).
>From board perspective P1020RDB is same as P2020RDB.

* This code adds the basic basic platform support for P1020RDB.

Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
---
- based on http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
- branch->next
- The patch does not contain ethernet support because P1020 contains new eTSEC
  controller. The support will be added in the later patches.
- changes above v3-> minor change in a comment for localbus chipselects.
PLEASE ignore the earlier patch mail with no subject.
 arch/powerpc/boot/dts/p1020rdb.dts        |  477 +++++++++++++++++++++++++++++
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c |   24 ++
 2 files changed, 501 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/p1020rdb.dts

diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts
new file mode 100644
index 0000000..de5672c
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1020rdb.dts
@@ -0,0 +1,477 @@
+/*
+ * P1020 RDB Device Tree Source
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/ {
+	model = "fsl,P1020";
+	compatible = "fsl,P1020RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P1020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P1020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		/* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+			  0x1 0x0 0x0 0xffa00000 0x00040000
+			  0x2 0x0 0x0 0xffb00000 0x00020000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x1000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 256KB for Vitesse 7385 Switch firmware */
+				reg = <0x0 0x00040000>;
+				label = "NOR (RO) Vitesse-7385 Firmware";
+				read-only;
+			};
+
+			partition@40000 {
+				/* 256KB for DTB Image */
+				reg = <0x00040000 0x00040000>;
+				label = "NOR (RO) DTB Image";
+				read-only;
+			};
+
+			partition@80000 {
+				/* 3.5 MB for Linux Kernel Image */
+				reg = <0x00080000 0x00380000>;
+				label = "NOR (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@400000 {
+				/* 11MB for JFFS2 based Root file System */
+				reg = <0x00400000 0x00b00000>;
+				label = "NOR (RW) JFFS2 Root File System";
+			};
+
+			partition@f00000 {
+				/* This location must not be altered  */
+				/* 512KB for u-boot Bootloader Image */
+				/* 512KB for u-boot Environment Variables */
+				reg = <0x00f00000 0x00100000>;
+				label = "NOR (RO) U-Boot Image";
+				read-only;
+			};
+		};
+
+		nand@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p1020-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x1 0x0 0x40000>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 1MB for u-boot Bootloader Image */
+				reg = <0x0 0x00100000>;
+				label = "NAND (RO) U-Boot Image";
+				read-only;
+			};
+
+			partition@100000 {
+				/* 1MB for DTB Image */
+				reg = <0x00100000 0x00100000>;
+				label = "NAND (RO) DTB Image";
+				read-only;
+			};
+
+			partition@200000 {
+				/* 4MB for Linux Kernel Image */
+				reg = <0x00200000 0x00400000>;
+				label = "NAND (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@600000 {
+				/* 4MB for Compressed Root file System Image */
+				reg = <0x00600000 0x00400000>;
+				label = "NAND (RO) Compressed RFS Image";
+				read-only;
+			};
+
+			partition@a00000 {
+				/* 7MB for JFFS2 based Root file System */
+				reg = <0x00a00000 0x00700000>;
+				label = "NAND (RW) JFFS2 Root File System";
+			};
+
+			partition@1100000 {
+				/* 15MB for JFFS2 based Root file System */
+				reg = <0x01100000 0x00f00000>;
+				label = "NAND (RW) Writable User area";
+			};
+		};
+
+		L2switch@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "vitesse-7385";
+			reg = <0x2 0x0 0x20000>;
+		};
+
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p1020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p1020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <16 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p1020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				modal = "s25sl128b";
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				partition@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				partition@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				partition@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				partition@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				partition@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p1020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x40000>; // L2,256K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		usb@23000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x23000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <46 0x2>;
+			phy_type = "ulpi";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p1020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p1020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xc0000000
+				  0x2000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index c8468de..495bd8b 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -113,6 +113,7 @@ static int __init mpc85xxrdb_publish_devices(void)
 	return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL);
 }
 machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices);
+machine_device_initcall(p1020_rdb, mpc85xxrdb_publish_devices);
 
 /*
  * Called very early, device-tree isn't unflattened
@@ -126,6 +127,15 @@ static int __init p2020_rdb_probe(void)
 	return 0;
 }
 
+static int __init p1020_rdb_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "fsl,P1020RDB"))
+		return 1;
+	return 0;
+}
+
 define_machine(p2020_rdb) {
 	.name			= "P2020 RDB",
 	.probe			= p2020_rdb_probe,
@@ -139,3 +149,17 @@ define_machine(p2020_rdb) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 };
+
+define_machine(p1020_rdb) {
+	.name			= "P1020 RDB",
+	.probe			= p1020_rdb_probe,
+	.setup_arch		= mpc85xx_rdb_setup_arch,
+	.init_IRQ		= mpc85xx_rdb_pic_init,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
-- 
1.5.6.5

^ permalink raw reply related

* RE: [PATCH][powerpc/85xx] P2020RDB Platform Support Added
From: Aggrwal Poonam-B10812 @ 2009-09-25  4:18 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev list, Felix Radensky, linuxppc-release
In-Reply-To: <87B3AA50-1B12-43D6-9F92-37AA9E5BC142@kernel.crashing.org>

=20

> -----Original Message-----
> From:=20
> linuxppc-dev-bounces+poonam.aggrwal=3Dfreescale.com@lists.ozlabs
> .org=20
> [mailto:linuxppc-dev-bounces+poonam.aggrwal=3Dfreescale.com@list
> s.ozlabs.org] On Behalf Of Kumar Gala
> Sent: Thursday, September 24, 2009 11:42 PM
> To: Aggrwal Poonam-B10812
> Cc: linuxppc-dev list; Felix Radensky;=20
> linuxppc-release@webnode01-prod1.am.freescale.net
> Subject: Re: [PATCH][powerpc/85xx] P2020RDB Platform Support Added
>=20
>=20
> On Aug 5, 2009, at 11:25 PM, Felix Radensky wrote:
>=20
> > Hi, Poonam
> >
> > Poonam Aggrwal wrote:
> >> Adds P2020RDB basic support in linux.
> >> Overview of P2020RDB platform
> >> 	- DDR
> >> 	  DDR2 1G
> >> 	- NOR Flash
> >> 	  16MByte
> >> 	- NAND Flash
> >> 	  32MByte
> >> 	- 3 Ethernet interfaces
> >> 	  1) etSEC1
> >> 		- RGMII
> >> 		- connected to a 5 port Vitesse Switch(VSC7385)
> >> 		- Switch is memory mapped through eLBC interface(CS#2)
> >> 		- IRQ1
> >> 	  2) etSEC2
> >> 		- SGMII
> >> 		- connected to VSC8221
> >> 		- IRQ2
> >> 	  3) etSEC3
> >> 		- RGMII
> >> 		- connected to VSC8641
> >> 		- IRQ3
> >> 	- 2 1X PCIe interfaces
> >> 	- SD/MMC ,USB
> >> 	- SPI EEPROM
> >> 	- Serial I2C EEPROM
> >>
> >> Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
> >> ---
> >> based on=20
> http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
> >> arch/powerpc/boot/dts/p2020rdb.dts        |  586=20
> +++++++++++++++++++=20
> >> ++++++++++
> >> arch/powerpc/configs/mpc85xx_defconfig    |    1 +
> >> arch/powerpc/platforms/85xx/Kconfig       |    9 +
> >> arch/powerpc/platforms/85xx/Makefile      |    3 +-
> >> arch/powerpc/platforms/85xx/mpc85xx_rdb.c |  141 +++++++
> >> 5 files changed, 739 insertions(+), 1 deletions(-) create=20
> mode 100644=20
> >> arch/powerpc/boot/dts/p2020rdb.dts
> >> create mode 100644 arch/powerpc/platforms/85xx/mpc85xx_rdb.c
> >>
> >> diff --git a/arch/powerpc/boot/dts/p2020rdb.dts=20
> b/arch/powerpc/boot/=20
> >> dts/p2020rdb.dts new file mode 100644 index 0000000..d6d8131
> >> --- /dev/null
> >> +++ b/arch/powerpc/boot/dts/p2020rdb.dts
> >> @@ -0,0 +1,586 @@
> >> +/*
> >> + * P2020 RDB Device Tree Source
> >> + *
> >> + * Copyright 2009 Freescale Semiconductor Inc.
> >> + *
> >> + * 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.
> >> + */
> >> +
> >> +/dts-v1/;
> >> +/ {
> >> +	model =3D "fsl,P2020";
> >> +	compatible =3D "fsl,P2020RDB";
> >> +	#address-cells =3D <2>;
> >> +	#size-cells =3D <2>;
> >> +
> >> +	aliases {
> >> +		ethernet0 =3D &enet0;
> >> +		ethernet1 =3D &enet1;
> >> +		ethernet2 =3D &enet2;
> >> +		serial0 =3D &serial0;
> >> +		serial1 =3D &serial1;
> >> +		pci0 =3D &pci0;
> >> +		pci1 =3D &pci1;
> >> +	};
> >> +
> >> +	cpus {
> >> +		#address-cells =3D <1>;
> >> +		#size-cells =3D <0>;
> >> +
> >> +		PowerPC,P2020@0 {
> >> +			device_type =3D "cpu";
> >> +			reg =3D <0x0>;
> >> +			next-level-cache =3D <&L2>;
> >> +		};
> >> +
> >> +		PowerPC,P2020@1 {
> >> +			device_type =3D "cpu";
> >> +			reg =3D <0x1>;
> >> +			next-level-cache =3D <&L2>;
> >> +		};
> >> +	};
> >> +
> >> +	memory {
> >> +		device_type =3D "memory";
> >> +	};
> >> +
> >> +	localbus@ffe05000 {
> >> +		#address-cells =3D <2>;
> >> +		#size-cells =3D <1>;
> >> +		compatible =3D "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
> >> +		reg =3D <0 0xffe05000 0 0x1000>;
> >> +		interrupts =3D <19 2>;
> >> +		interrupt-parent =3D <&mpic>;
> >> +
> >> +		/* NOR and NAND Flashes */
> >> +		ranges =3D <0x0 0x0 0x0 0xef000000 0x01000000
> >> +			  0x1 0x0 0x0 0xffa00000 0x00040000
> >> +			  0x2 0x0 0x0 0xffb00000 0x08000000>;
> >>
> >
> > The comment is a bit misleading, CS2 is L2 switch. Also,=20
> are you sure=20
> > the CS2 range shouldn't look like
> >     0x2 0x0 0x0 0xffb00000 0x00020000
> >
> > That's what L2switch reg property suggests.
>=20
> Did you plan on making this change?
I already fixed it in v3 version of the patch, although please consider
the v4 version just sent recently. V4 also makes the comment proper as
suggested by Felix.

Regards
Poonam
>=20
> >> +		nor@0,0 {
> >> +			#address-cells =3D <1>;
> >> +			#size-cells =3D <1>;
> >> +			compatible =3D "cfi-flash";
> >> +			reg =3D <0x0 0x0 0x1000000>;
> >> +			bank-width =3D <2>;
> >> +			device-width =3D <1>;
> >> +
> >> +			vitesse-7385-fw@0 {
> >> +				/* This location must not be altered  */
> >> +				/* 256KB for Vitesse 7385=20
> Switch firmware */
> >> +				reg =3D <0x0 0x00040000>;
> >> +				label =3D "NOR (RO) Vitesse-7385=20
> Firmware";
> >> +				read-only;
> >> +			};
> >>
> > Partitions should be declared as
> >
> >      partition@0 {
> >                  reg =3D ...
> >                  label =3D ...
> >                  ...
> >       }
> > Felix.
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>=20
>=20

^ permalink raw reply

* (no subject)
From: Poonam Aggrwal @ 2009-09-25  4:16 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Poonam Aggrwal

Subject: [PATCH][v4] powerpc/85xx: Added P1020RDB Platform support.

P1020 is another member of Freescale QorIQ series of processors.
It is an e500 based dual core SOC.
Being a scaled down version of P2020 it has following differences from P2020:
- 533MHz - 800MHz core frequency.
- 256Kbyte L2 cache
- Ethernet controllers with classification capabilities(new controller).
>From board perspective P1020RDB is same as P2020RDB.

* This code adds the basic basic platform support for P1020RDB.

Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
---
- based on http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
- branch->next
- The patch does not contain ethernet support because P1020 contains new eTSEC
  controller. The support will be added in the later patches.
- changes above v3-> minor change in a comment for localbus chipselects.
 arch/powerpc/boot/dts/p1020rdb.dts        |  477 +++++++++++++++++++++++++++++
 arch/powerpc/platforms/85xx/mpc85xx_rdb.c |   24 ++
 2 files changed, 501 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/p1020rdb.dts

diff --git a/arch/powerpc/boot/dts/p1020rdb.dts b/arch/powerpc/boot/dts/p1020rdb.dts
new file mode 100644
index 0000000..de5672c
--- /dev/null
+++ b/arch/powerpc/boot/dts/p1020rdb.dts
@@ -0,0 +1,477 @@
+/*
+ * P1020 RDB Device Tree Source
+ *
+ * Copyright 2009 Freescale Semiconductor Inc.
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/ {
+	model = "fsl,P1020";
+	compatible = "fsl,P1020RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	aliases {
+		serial0 = &serial0;
+		serial1 = &serial1;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P1020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P1020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+
+		/* NOR, NAND Flashes and Vitesse 5 port L2 switch */
+		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
+			  0x1 0x0 0x0 0xffa00000 0x00040000
+			  0x2 0x0 0x0 0xffb00000 0x00020000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x1000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 256KB for Vitesse 7385 Switch firmware */
+				reg = <0x0 0x00040000>;
+				label = "NOR (RO) Vitesse-7385 Firmware";
+				read-only;
+			};
+
+			partition@40000 {
+				/* 256KB for DTB Image */
+				reg = <0x00040000 0x00040000>;
+				label = "NOR (RO) DTB Image";
+				read-only;
+			};
+
+			partition@80000 {
+				/* 3.5 MB for Linux Kernel Image */
+				reg = <0x00080000 0x00380000>;
+				label = "NOR (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@400000 {
+				/* 11MB for JFFS2 based Root file System */
+				reg = <0x00400000 0x00b00000>;
+				label = "NOR (RW) JFFS2 Root File System";
+			};
+
+			partition@f00000 {
+				/* This location must not be altered  */
+				/* 512KB for u-boot Bootloader Image */
+				/* 512KB for u-boot Environment Variables */
+				reg = <0x00f00000 0x00100000>;
+				label = "NOR (RO) U-Boot Image";
+				read-only;
+			};
+		};
+
+		nand@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p1020-fcm-nand",
+				     "fsl,elbc-fcm-nand";
+			reg = <0x1 0x0 0x40000>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 1MB for u-boot Bootloader Image */
+				reg = <0x0 0x00100000>;
+				label = "NAND (RO) U-Boot Image";
+				read-only;
+			};
+
+			partition@100000 {
+				/* 1MB for DTB Image */
+				reg = <0x00100000 0x00100000>;
+				label = "NAND (RO) DTB Image";
+				read-only;
+			};
+
+			partition@200000 {
+				/* 4MB for Linux Kernel Image */
+				reg = <0x00200000 0x00400000>;
+				label = "NAND (RO) Linux Kernel Image";
+				read-only;
+			};
+
+			partition@600000 {
+				/* 4MB for Compressed Root file System Image */
+				reg = <0x00600000 0x00400000>;
+				label = "NAND (RO) Compressed RFS Image";
+				read-only;
+			};
+
+			partition@a00000 {
+				/* 7MB for JFFS2 based Root file System */
+				reg = <0x00a00000 0x00700000>;
+				label = "NAND (RW) JFFS2 Root File System";
+			};
+
+			partition@1100000 {
+				/* 15MB for JFFS2 based Root file System */
+				reg = <0x01100000 0x00f00000>;
+				label = "NAND (RW) Writable User area";
+			};
+		};
+
+		L2switch@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "vitesse-7385";
+			reg = <0x2 0x0 0x20000>;
+		};
+
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p1020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p1020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <16 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p1020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				modal = "s25sl128b";
+				spi-max-frequency = <50000000>;
+				mode = <0>;
+
+				partition@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				partition@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				partition@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				partition@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				partition@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p1020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x40000>; // L2,256K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+			phy_type = "ulpi";
+		};
+
+		usb@23000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x23000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <46 0x2>;
+			phy_type = "ulpi";
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p1020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p1020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc30000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xc0000000
+				  0x2000000 0x0 0xc0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
index c8468de..495bd8b 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_rdb.c
@@ -113,6 +113,7 @@ static int __init mpc85xxrdb_publish_devices(void)
 	return of_platform_bus_probe(NULL, mpc85xxrdb_ids, NULL);
 }
 machine_device_initcall(p2020_rdb, mpc85xxrdb_publish_devices);
+machine_device_initcall(p1020_rdb, mpc85xxrdb_publish_devices);
 
 /*
  * Called very early, device-tree isn't unflattened
@@ -126,6 +127,15 @@ static int __init p2020_rdb_probe(void)
 	return 0;
 }
 
+static int __init p1020_rdb_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (of_flat_dt_is_compatible(root, "fsl,P1020RDB"))
+		return 1;
+	return 0;
+}
+
 define_machine(p2020_rdb) {
 	.name			= "P2020 RDB",
 	.probe			= p2020_rdb_probe,
@@ -139,3 +149,17 @@ define_machine(p2020_rdb) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= udbg_progress,
 };
+
+define_machine(p1020_rdb) {
+	.name			= "P1020 RDB",
+	.probe			= p1020_rdb_probe,
+	.setup_arch		= mpc85xx_rdb_setup_arch,
+	.init_IRQ		= mpc85xx_rdb_pic_init,
+#ifdef CONFIG_PCI
+	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
+#endif
+	.get_irq		= mpic_get_irq,
+	.restart		= fsl_rstcr_restart,
+	.calibrate_decr		= generic_calibrate_decr,
+	.progress		= udbg_progress,
+};
-- 
1.5.6.5

^ permalink raw reply related

* Re: 2.6.31-git5 kernel boot hangs on powerpc
From: Benjamin Herrenschmidt @ 2009-09-25  3:40 UTC (permalink / raw)
  To: Tejun Heo; +Cc: Linux/PPC Development, David Miller
In-Reply-To: <4ABC376D.1020704@kernel.org>

On Fri, 2009-09-25 at 12:22 +0900, Tejun Heo wrote:
> Benjamin Herrenschmidt wrote:
> >> --- Exception: 301 at .memset+0x60/0xfc
> >>     LR = .pcpu_alloc+0x718/0x8fc
> > 
> > So it's memsetting something that causes it to hash_page(), ie, faulting
> > in pages (vmalloc space ?) so far nothing obviously wrong....
> 
> It's probably memset() call near the end of pcpu_populate_chunk()
> where percpu allocator clears the allocated areas before returning to
> user.  I don't think the first chunk is causing the problem as they're
> all in the linear mapped area.  From the second chunk on, they're on
> vmalloc area and very near to the top of it, so that might be exposing
> a hidden problem in paging code?  BTW, for some reason, the problem is
> not reproducible on my powerstation.

That's indeed a possibility, though it would be strange...

Definitely worth looking at your logs, and I'll check with Sachin
about getting on the machine after that if I need to dig more.

Cheers,
Ben.

^ permalink raw reply

* Re: 2.6.31-git5 kernel boot hangs on powerpc
From: Tejun Heo @ 2009-09-25  3:22 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: Linux/PPC Development, David Miller
In-Reply-To: <1253826309.7103.461.camel@pasglop>

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

Benjamin Herrenschmidt wrote:
>> --- Exception: 301 at .memset+0x60/0xfc
>>     LR = .pcpu_alloc+0x718/0x8fc
> 
> So it's memsetting something that causes it to hash_page(), ie, faulting
> in pages (vmalloc space ?) so far nothing obviously wrong....

It's probably memset() call near the end of pcpu_populate_chunk()
where percpu allocator clears the allocated areas before returning to
user.  I don't think the first chunk is causing the problem as they're
all in the linear mapped area.  From the second chunk on, they're on
vmalloc area and very near to the top of it, so that might be exposing
a hidden problem in paging code?  BTW, for some reason, the problem is
not reproducible on my powerstation.

Sachin, can you please apply the attached patch on top of the current
linus tree, reproduce the hang and report full kernel log?  Let's see
which address is causing the problem.

Thanks.

-- 
tejun

[-- Attachment #2: pcpu-debug.patch --]
[-- Type: text/x-patch, Size: 11899 bytes --]

Index: work/mm/percpu.c
===================================================================
--- work.orig/mm/percpu.c
+++ work/mm/percpu.c
@@ -100,9 +100,11 @@ struct pcpu_chunk {
 	int			*map;		/* allocation map */
 	struct vm_struct	**vms;		/* mapped vmalloc regions */
 	bool			immutable;	/* no [de]population allowed */
+	int			id;
 	unsigned long		populated[];	/* populated bitmap */
 };
 
+static int pcpu_chunk_id = 0;
 static int pcpu_unit_pages __read_mostly;
 static int pcpu_unit_size __read_mostly;
 static int pcpu_nr_units __read_mostly;
@@ -314,10 +316,15 @@ static void pcpu_chunk_relocate(struct p
 	int nslot = pcpu_chunk_slot(chunk);
 
 	if (chunk != pcpu_reserved_chunk && oslot != nslot) {
+		printk("PERCPU: chunk %d relocating %d -> %d %p <%p:%p>\n",
+		       chunk->id, oslot, nslot, &chunk->list,
+		       chunk->list.prev, chunk->list.next);
 		if (oslot < nslot)
 			list_move(&chunk->list, &pcpu_slot[nslot]);
 		else
 			list_move_tail(&chunk->list, &pcpu_slot[nslot]);
+		printk("PERCPU: relocated <%p:%p>\n",
+		       chunk->list.prev, chunk->list.next);
 	}
 }
 
@@ -789,6 +796,11 @@ static void pcpu_post_unmap_tlb_flush(st
 static int __pcpu_map_pages(unsigned long addr, struct page **pages,
 			    int nr_pages)
 {
+	int i;
+	printk("PERCPU: map 0x%lx, %d pages", addr, nr_pages);
+	for (i = 0; i < nr_pages; i++)
+		printk(" %lu", page_to_pfn(pages[i]));
+	printk("\n");
 	return map_kernel_range_noflush(addr, nr_pages << PAGE_SHIFT,
 					PAGE_KERNEL, pages);
 }
@@ -957,6 +969,7 @@ static int pcpu_populate_chunk(struct pc
 
 	/* alloc and map */
 	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
+		printk("PERCPU: chunk %d, alloc pages [%d,%d)\n", chunk->id, rs, re);
 		rc = pcpu_alloc_pages(chunk, pages, populated, rs, re);
 		if (rc)
 			goto err_free;
@@ -964,6 +977,7 @@ static int pcpu_populate_chunk(struct pc
 	}
 
 	pcpu_for_each_unpop_region(chunk, rs, re, page_start, page_end) {
+		printk("PERCPU: chunk %d, map pages [%d,%d)\n", chunk->id, rs, re);
 		rc = pcpu_map_pages(chunk, pages, populated, rs, re);
 		if (rc)
 			goto err_unmap;
@@ -973,6 +987,10 @@ static int pcpu_populate_chunk(struct pc
 
 	/* commit new bitmap */
 	bitmap_copy(chunk->populated, populated, pcpu_unit_pages);
+	printk("PERCPU: chunk %d, will clear %db/unit", chunk->id, size);
+	for_each_possible_cpu(cpu)
+		printk(" %p", (void *)pcpu_chunk_addr(chunk, cpu, 0) + off);
+	printk("\n");
 clear:
 	for_each_possible_cpu(cpu)
 		memset((void *)pcpu_chunk_addr(chunk, cpu, 0) + off, 0, size);
@@ -1043,7 +1061,9 @@ static struct pcpu_chunk *alloc_pcpu_chu
  */
 static void *pcpu_alloc(size_t size, size_t align, bool reserved)
 {
+	static int warn_limit = 10;
 	struct pcpu_chunk *chunk;
+	const char *err;
 	int slot, off;
 
 	if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) {
@@ -1059,11 +1079,14 @@ static void *pcpu_alloc(size_t size, siz
 	if (reserved && pcpu_reserved_chunk) {
 		chunk = pcpu_reserved_chunk;
 		if (size > chunk->contig_hint ||
-		    pcpu_extend_area_map(chunk) < 0)
+		    pcpu_extend_area_map(chunk) < 0) {
+			err = "failed to extend area map of reserved chunk";
 			goto fail_unlock;
+		}
 		off = pcpu_alloc_area(chunk, size, align);
 		if (off >= 0)
 			goto area_found;
+		err = "alloc from reserved chunk failed";
 		goto fail_unlock;
 	}
 
@@ -1080,6 +1103,7 @@ restart:
 			case 1:
 				goto restart;	/* pcpu_lock dropped, restart */
 			default:
+				err = "failed to extend area map";
 				goto fail_unlock;
 			}
 
@@ -1093,10 +1117,13 @@ restart:
 	spin_unlock_irq(&pcpu_lock);
 
 	chunk = alloc_pcpu_chunk();
-	if (!chunk)
+	if (!chunk) {
+		err = "failed to allocate new chunk";
 		goto fail_unlock_mutex;
+	}
 
 	spin_lock_irq(&pcpu_lock);
+	chunk->id = pcpu_chunk_id++;
 	pcpu_chunk_relocate(chunk, -1);
 	goto restart;
 
@@ -1107,6 +1134,7 @@ area_found:
 	if (pcpu_populate_chunk(chunk, off, size)) {
 		spin_lock_irq(&pcpu_lock);
 		pcpu_free_area(chunk, off);
+		err = "failed to populate";
 		goto fail_unlock;
 	}
 
@@ -1119,6 +1147,13 @@ fail_unlock:
 	spin_unlock_irq(&pcpu_lock);
 fail_unlock_mutex:
 	mutex_unlock(&pcpu_alloc_mutex);
+	if (warn_limit) {
+		pr_warning("PERCPU: allocation failed, size=%zu align=%zu, "
+			   "%s\n", size, align, err);
+		dump_stack();
+		if (!--warn_limit)
+			pr_info("PERCPU: limit reached, disable warning\n");
+	}
 	return NULL;
 }
 
@@ -1347,6 +1382,10 @@ struct pcpu_alloc_info * __init pcpu_bui
 	struct pcpu_alloc_info *ai;
 	unsigned int *cpu_map;
 
+	/* this function may be called multiple times */
+	memset(group_map, 0, sizeof(group_map));
+	memset(group_cnt, 0, sizeof(group_map));
+
 	/*
 	 * Determine min_unit_size, alloc_size and max_upa such that
 	 * alloc_size is multiple of atom_size and is the smallest
@@ -1574,6 +1613,7 @@ static void pcpu_dump_alloc_info(const c
 int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
 				  void *base_addr)
 {
+	static char cpus_buf[4096] __initdata;
 	static int smap[2], dmap[2];
 	size_t dyn_size = ai->dyn_size;
 	size_t size_sum = ai->static_size + ai->reserved_size + dyn_size;
@@ -1585,17 +1625,26 @@ int __init pcpu_setup_first_chunk(const
 	int *unit_map;
 	int group, unit, i;
 
+	cpumask_scnprintf(cpus_buf, sizeof(cpus_buf), cpu_possible_mask);
+
+#define PCPU_SETUP_BUG_ON(cond)	do {					\
+	if (unlikely(cond)) {						\
+		pr_emerg("PERCPU: failed to initialize, %s", #cond);	\
+		pr_emerg("PERCPU: cpu_possible_mask=%s\n", cpus_buf);	\
+		pcpu_dump_alloc_info(KERN_EMERG, ai);			\
+		BUG();							\
+	}								\
+} while (0)
+
 	/* sanity checks */
 	BUILD_BUG_ON(ARRAY_SIZE(smap) >= PCPU_DFL_MAP_ALLOC ||
 		     ARRAY_SIZE(dmap) >= PCPU_DFL_MAP_ALLOC);
-	BUG_ON(ai->nr_groups <= 0);
-	BUG_ON(!ai->static_size);
-	BUG_ON(!base_addr);
-	BUG_ON(ai->unit_size < size_sum);
-	BUG_ON(ai->unit_size & ~PAGE_MASK);
-	BUG_ON(ai->unit_size < PCPU_MIN_UNIT_SIZE);
-
-	pcpu_dump_alloc_info(KERN_DEBUG, ai);
+	PCPU_SETUP_BUG_ON(ai->nr_groups <= 0);
+	PCPU_SETUP_BUG_ON(!ai->static_size);
+	PCPU_SETUP_BUG_ON(!base_addr);
+	PCPU_SETUP_BUG_ON(ai->unit_size < size_sum);
+	PCPU_SETUP_BUG_ON(ai->unit_size & ~PAGE_MASK);
+	PCPU_SETUP_BUG_ON(ai->unit_size < PCPU_MIN_UNIT_SIZE);
 
 	/* process group information and build config tables accordingly */
 	group_offsets = alloc_bootmem(ai->nr_groups * sizeof(group_offsets[0]));
@@ -1618,8 +1667,9 @@ int __init pcpu_setup_first_chunk(const
 			if (cpu == NR_CPUS)
 				continue;
 
-			BUG_ON(cpu > nr_cpu_ids || !cpu_possible(cpu));
-			BUG_ON(unit_map[cpu] != NR_CPUS);
+			PCPU_SETUP_BUG_ON(cpu > nr_cpu_ids);
+			PCPU_SETUP_BUG_ON(!cpu_possible(cpu));
+			PCPU_SETUP_BUG_ON(unit_map[cpu] != NR_CPUS);
 
 			unit_map[cpu] = unit + i;
 			unit_off[cpu] = gi->base_offset + i * ai->unit_size;
@@ -1632,7 +1682,11 @@ int __init pcpu_setup_first_chunk(const
 	pcpu_nr_units = unit;
 
 	for_each_possible_cpu(cpu)
-		BUG_ON(unit_map[cpu] == NR_CPUS);
+		PCPU_SETUP_BUG_ON(unit_map[cpu] == NR_CPUS);
+
+	/* we're done parsing the input, undefine BUG macro and dump config */
+#undef PCPU_SETUP_BUG_ON
+	pcpu_dump_alloc_info(KERN_INFO, ai);
 
 	pcpu_nr_groups = ai->nr_groups;
 	pcpu_group_offsets = group_offsets;
@@ -1655,6 +1709,8 @@ int __init pcpu_setup_first_chunk(const
 	pcpu_slot = alloc_bootmem(pcpu_nr_slots * sizeof(pcpu_slot[0]));
 	for (i = 0; i < pcpu_nr_slots; i++)
 		INIT_LIST_HEAD(&pcpu_slot[i]);
+	printk("PERCPU: initialized %d slots [%p,%p)\n", pcpu_nr_slots,
+	       &pcpu_slot[0], &pcpu_slot[i]);
 
 	/*
 	 * Initialize static chunk.  If reserved_size is zero, the
@@ -1673,6 +1729,7 @@ int __init pcpu_setup_first_chunk(const
 
 	if (ai->reserved_size) {
 		schunk->free_size = ai->reserved_size;
+		schunk->id = -1;
 		pcpu_reserved_chunk = schunk;
 		pcpu_reserved_chunk_limit = ai->static_size + ai->reserved_size;
 	} else {
@@ -1702,6 +1759,7 @@ int __init pcpu_setup_first_chunk(const
 
 	/* link the first chunk in */
 	pcpu_first_chunk = dchunk ?: schunk;
+	pcpu_first_chunk->id = pcpu_chunk_id++;
 	pcpu_chunk_relocate(pcpu_first_chunk, -1);
 
 	/* we're done */
@@ -1782,7 +1840,7 @@ int __init pcpu_embed_first_chunk(size_t
 	void *base = (void *)ULONG_MAX;
 	void **areas = NULL;
 	struct pcpu_alloc_info *ai;
-	size_t size_sum, areas_size;
+	size_t size_sum, areas_size, max_distance;
 	int group, i, rc;
 
 	ai = pcpu_build_alloc_info(reserved_size, dyn_size, atom_size,
@@ -1832,8 +1890,24 @@ int __init pcpu_embed_first_chunk(size_t
 	}
 
 	/* base address is now known, determine group base offsets */
-	for (group = 0; group < ai->nr_groups; group++)
+	max_distance = 0;
+	for (group = 0; group < ai->nr_groups; group++) {
 		ai->groups[group].base_offset = areas[group] - base;
+		max_distance = max(max_distance, ai->groups[group].base_offset);
+	}
+	max_distance += ai->unit_size;
+
+	/* warn if maximum distance is further than 75% of vmalloc space */
+	if (max_distance > (VMALLOC_END - VMALLOC_START) * 3 / 4) {
+		pr_warning("PERCPU: max_distance=0x%lx too large for vmalloc "
+			   "space 0x%lx\n",
+			   max_distance, VMALLOC_END - VMALLOC_START);
+#ifdef CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK
+		/* and fail if we have fallback */
+		rc = -EINVAL;
+		goto out_free;
+#endif
+	}
 
 	pr_info("PERCPU: Embedded %zu pages/cpu @%p s%zu r%zu d%zu u%zu\n",
 		PFN_DOWN(size_sum), base, ai->static_size, ai->reserved_size,
Index: work/arch/sparc/Kconfig
===================================================================
--- work.orig/arch/sparc/Kconfig
+++ work/arch/sparc/Kconfig
@@ -102,6 +102,9 @@ config HAVE_SETUP_PER_CPU_AREA
 config NEED_PER_CPU_EMBED_FIRST_CHUNK
 	def_bool y if SPARC64
 
+config NEED_PER_CPU_PAGE_FIRST_CHUNK
+	def_bool y if SPARC64
+
 config GENERIC_HARDIRQS_NO__DO_IRQ
 	bool
 	def_bool y if SPARC64
Index: work/arch/sparc/kernel/smp_64.c
===================================================================
--- work.orig/arch/sparc/kernel/smp_64.c
+++ work/arch/sparc/kernel/smp_64.c
@@ -1420,7 +1420,7 @@ static void __init pcpu_free_bootmem(voi
 	free_bootmem(__pa(ptr), size);
 }
 
-static int pcpu_cpu_distance(unsigned int from, unsigned int to)
+static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
 {
 	if (cpu_to_node(from) == cpu_to_node(to))
 		return LOCAL_DISTANCE;
@@ -1428,18 +1428,53 @@ static int pcpu_cpu_distance(unsigned in
 		return REMOTE_DISTANCE;
 }
 
+static void __init pcpu_populate_pte(unsigned long addr)
+{
+	pgd_t *pgd = pgd_offset_k(addr);
+	pud_t *pud;
+	pmd_t *pmd;
+
+	pud = pud_offset(pgd, addr);
+	if (pud_none(*pud)) {
+		pmd_t *new;
+
+		new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+		pud_populate(&init_mm, pud, new);
+	}
+
+	pmd = pmd_offset(pud, addr);
+	if (!pmd_present(*pmd)) {
+		pte_t *new;
+
+		new = __alloc_bootmem(PAGE_SIZE, PAGE_SIZE, PAGE_SIZE);
+		pmd_populate_kernel(&init_mm, pmd, new);
+	}
+}
+
 void __init setup_per_cpu_areas(void)
 {
 	unsigned long delta;
 	unsigned int cpu;
-	int rc;
+	int rc = -EINVAL;
 
-	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
-				    PERCPU_DYNAMIC_RESERVE, 4 << 20,
-				    pcpu_cpu_distance, pcpu_alloc_bootmem,
-				    pcpu_free_bootmem);
-	if (rc)
-		panic("failed to initialize first chunk (%d)", rc);
+	if (pcpu_chosen_fc != PCPU_FC_PAGE) {
+		rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
+					    PERCPU_DYNAMIC_RESERVE, 4 << 20,
+					    pcpu_cpu_distance,
+					    pcpu_alloc_bootmem,
+					    pcpu_free_bootmem);
+		if (rc)
+			pr_warning("PERCPU: %s allocator failed (%d), "
+				   "falling back to page size\n",
+				   pcpu_fc_names[pcpu_chosen_fc], rc);
+	}
+	if (rc < 0)
+		rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE,
+					   pcpu_alloc_bootmem,
+					   pcpu_free_bootmem,
+					   pcpu_populate_pte);
+	if (rc < 0)
+		panic("cannot initialize percpu area (err=%d)", rc);
 
 	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
 	for_each_possible_cpu(cpu)

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-25  3:03 UTC (permalink / raw)
  To: Rex Feany; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1253843480.7103.492.camel@pasglop>


> I think there's more finishyness to 8xx than we thought. IE. That
> tlbil_va might have more reasons to be there than what the comment
> seems to advertize. Can you try to move it even higher up ? IE.
> Unconditionally at the beginning of set_pte_filter ?
> 
> Also, if that doesn't help, can you try putting one in
> set_access_flags_filter() just below ?

Ok, I got a refresher on the whole concept of "unpopulated TLB entries"
on 8xx, and that's damn scary. I think what mislead me initially is that
the comment around the workaround is simply not properly describing the
extent of the problem :-)

So I'm not going to make the 8xx TLB miss code sane, that's beyond what
I'm prepare to do with it, but I suspect that this should fix it (on top
of upstream). Let me know if that's enough or if we also need to put
one of these in ptep_set_access_flags().

Please let me know if that works for you.

Cheers,
Ben.

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 5304093..7a8e676 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -170,6 +170,16 @@ struct page * maybe_pte_to_page(pte_t pte)
 
 static pte_t set_pte_filter(pte_t pte, unsigned long addr)
 {
+#ifdef CONFIG_8xx
+	/* 8xx has a weird concept of "unpopulated" entries. When we take
+	 * a TLB miss for a non-valid PTE, we insert such an entry which
+	 * causes a page fault the next time around. This entry must now
+	 * be kicked out or we'll just fault again
+	 */
+	/* 8xx doesn't care about PID, size or ind args */
+	_tlbil_va(addr, 0, 0, 0);
+#endif /* CONFIG_8xx */
+
 	pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
 	if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
 				       cpu_has_feature(CPU_FTR_NOEXECUTE))) {
@@ -177,17 +187,6 @@ static pte_t set_pte_filter(pte_t pte, unsigned long addr)
 		if (!pg)
 			return pte;
 		if (!test_bit(PG_arch_1, &pg->flags)) {
-#ifdef CONFIG_8xx
-			/* On 8xx, cache control instructions (particularly
-			 * "dcbst" from flush_dcache_icache) fault as write
-			 * operation if there is an unpopulated TLB entry
-			 * for the address in question. To workaround that,
-			 * we invalidate the TLB here, thus avoiding dcbst
-			 * misbehaviour.
-			 */
-			/* 8xx doesn't care about PID, size or ind args */
-			_tlbil_va(addr, 0, 0, 0);
-#endif /* CONFIG_8xx */
 			flush_dcache_icache_page(pg);
 			set_bit(PG_arch_1, &pg->flags);
 		}

^ permalink raw reply related

* Re: [PATCH 3/3] USB: ehci-fsl: Add power management support (resume after deep sleep)
From: Scott Wood @ 2009-09-25  2:30 UTC (permalink / raw)
  To: Anton Vorontsov; +Cc: linux-usb, Jerry Huang, Greg Kroah-Hartman, linuxppc-dev
In-Reply-To: <20090923185244.GC18755@oksana.dev.rtsoft.ru>

On Wed, Sep 23, 2009 at 10:52:44PM +0400, Anton Vorontsov wrote:
+#ifdef CONFIG_SUSPEND
+struct ehci_fsl {
+       struct ehci_hcd ehci;
+
+       /* Saved USB PHY settings, need to restore after deep sleep. */
+       u32 usb_ctrl;
+};

This doesn't seem like the right place to define this... what if we later
need something else that isn't for suspend?  And you could get rid of
EHCI_FSL_PRIV_SIZE.

> +static int ehci_fsl_drv_suspend(struct device *dev)
> +{
> +	struct usb_hcd *hcd = dev_get_drvdata(dev);
> +	struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
> +	void __iomem *non_ehci = hcd->regs;
> +
> +	if (!fsl_deep_sleep())
> +		return 0;

We'll also need to do this if we support suspend to disk...  is there any
good way for the driver to determine that that's what's being done?  Or
more generally, for the platform to communicate to the drivers which ones
are going to lose state without one-off hacks like fsl_deep_sleep().

> +	/* Power up ports (avoids devices disconnect). */
> +	port_nm = HCS_N_PORTS(ehci->hcs_params);
> +	while (port_nm--) {
> +		u32 port_sc;
> +
> +		port_sc = ehci_readl(ehci, &ehci->regs->port_status[port_nm]);
> +		port_sc |= PORT_POWER;
> +		ehci_writel(ehci, port_sc, &ehci->regs->port_status[port_nm]);
> +	}
> +	mdelay(30);

Instead of mdelay, can we somehow hold off any USB operations for a
while?

-Scott

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-25  1:51 UTC (permalink / raw)
  To: Rex Feany; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20090925013528.GA2584@compile2.chatsunix.int.mrv.com>

On Thu, 2009-09-24 at 18:35 -0700, Rex Feany wrote:
> 
> Then I can boot and get to a shell, but userspace is slow. 8 seconds
> to mount
> /proc (vs. less then a second using my old kernel)! Maybe this is an
> unrelated issue?  I'm pretty clueless about the details, I'm sorry.
> PG_arch_1 is used to prevent a cache flush unless it is actually
> needed?
> Then why would changing the location of the tlbil_va() make a
> difference?

I think there's more finishyness to 8xx than we thought. IE. That
tlbil_va might have more reasons to be there than what the comment
seems to advertize. Can you try to move it even higher up ? IE.
Unconditionally at the beginning of set_pte_filter ?

Also, if that doesn't help, can you try putting one in
set_access_flags_filter() just below ?

(Beware that there's two different versions of both functions, only the
first one is compiled/used on 8xx).

It's going to be hard for me to get that "right" since I don't really
know what's going on with the core here, but I suppose if we get it
moving along with extra tlb invalidations, that should be "good enough"
until somebody who really knows what's going on comes up with possibly
a better fix.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Rex Feany @ 2009-09-25  1:35 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1253836376.7103.469.camel@pasglop>

Thus spake Benjamin Herrenschmidt (benh@kernel.crashing.org):

> > Your tree hangs on boot, similar to what I saw without the 8xx
> > work-around patch -- it is hard to tell if it is the same though. :(
> 
> There's no backtrace ? Where does it hang ? Also which workaround
> patch ? The missing tlbil_va() or the _PAGE_SPECIAL problem ?
> 

Ben, I'm sorry, my last email was basically useless. I was refering to the
missing tlbil_va().  The system doesn't crash, but it does seem to hang right
after "Freeing unused kernel memory: 100k init" using your tree.

If I move the tlbil_va() outside of the test for PG_arch_1 :

diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 5304093..d927269 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -176,7 +176,7 @@ static pte_t set_pte_filter(pte_t pte, unsigned long addr)
                struct page *pg = maybe_pte_to_page(pte);
                if (!pg)
                        return pte;
-               if (!test_bit(PG_arch_1, &pg->flags)) {
+
 #ifdef CONFIG_8xx
                        /* On 8xx, cache control instructions (particularly
                         * "dcbst" from flush_dcache_icache) fault as write
@@ -188,6 +188,8 @@ static pte_t set_pte_filter(pte_t pte, unsigned long addr)
                        /* 8xx doesn't care about PID, size or ind args */
                        _tlbil_va(addr, 0, 0, 0);
 #endif /* CONFIG_8xx */
+
+               if (!test_bit(PG_arch_1, &pg->flags)) {
                        flush_dcache_icache_page(pg);
                        set_bit(PG_arch_1, &pg->flags);
                }

Then I can boot and get to a shell, but userspace is slow. 8 seconds to mount
/proc (vs. less then a second using my old kernel)! Maybe this is an
unrelated issue?  I'm pretty clueless about the details, I'm sorry.
PG_arch_1 is used to prevent a cache flush unless it is actually needed?
Then why would changing the location of the tlbil_va() make a difference?

take care!
/rex.

^ permalink raw reply related

* Re: [patch] powerpc: build modules outside the kernel tree fails, if it was built using O=
From: Benjamin Herrenschmidt @ 2009-09-25  1:12 UTC (permalink / raw)
  To: Yuri Frolov; +Cc: rep.dot.nop, linuxppc-dev, Sam Ravnborg, linux-kbuild
In-Reply-To: <4ABB57CB.3000409@ru.mvista.com>

On Thu, 2009-09-24 at 15:28 +0400, Yuri Frolov wrote:
> Hello,
> 
> here is a corresponding bug: http://bugzilla.kernel.org/show_bug.cgi?id=11143
> This patch should correctly export crtsavres.o in order to make O= option working.
> Please, consider to apply.
> 
> 
> Fix linking modules against crtsavres.o

Hi !

This is the same patch you already posted as "


[PATCH] Fix linking modules against
crtsavres.o
"

Or it's an update ?

I've asked Sam to review it already since it affects the main kernel
makefiles, waiting for his answer.

Cheers,
Ben.

> Previously we got
>   CC      drivers/char/hw_random/rng-core.mod.o
>   LD [M]  drivers/char/hw_random/rng-core.ko
> /there/src/buildroot.git.ppc/build_powerpc_nofpu/staging_dir/usr/bin/powerpc-linux-uclibc-ld: arch/powerpc/lib/crtsavres.o: No such file: No such file or directory
> 
> 	* Makefile (LDFLAGS_MODULE_PREREQ): New variable to hold prerequisite
>           files for modules.
> 	* arch/powerpc/Makefile: add crtsavres.o to LDFLAGS_MODULE_PREREQ.
> 	* scripts/Makefile.modpost (cmd_as_o_S): Copy from Makefile.build.
> 	  (cmd_ld_ko_o): Also link LDFLAGS_MODULE_PREREQ.
> 	  Provide rule to build objects from assembler.
> 
> Signed-off-by:  Bernhard Reutner-Fischer  <rep.dot.nop@gmail.com>
> Signed-off by:  Yuri Frolov <yfrolov@ru.mvista.com>
> 
> Makefile                 |    2 ++
> arch/powerpc/Makefile    |    2 +-
> scripts/Makefile.modpost |   12 ++++++++++--
> 3 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff -urpN -X linux-2.6/Documentation/dontdiff linux-2.6/arch/powerpc/Makefile linux-2.6-powerpc-crtsavres/arch/powerpc/Makefile
> --- linux-2.6/arch/powerpc/Makefile	2009-09-17 20:04:31.000000000 +0400
> +++ linux-2.6-powerpc-crtsavres/arch/powerpc/Makefile	2009-09-23 22:08:03.000000000 +0400
> @@ -93,7 +93,7 @@ else
>  	KBUILD_CFLAGS += $(call cc-option,-mtune=power4)
>  endif
>  else
> -LDFLAGS_MODULE	+= arch/powerpc/lib/crtsavres.o
> +LDFLAGS_MODULE_PREREQ += arch/powerpc/lib/crtsavres.o
>  endif
>  
>  ifeq ($(CONFIG_TUNE_CELL),y)
> diff -urpN -X linux-2.6/Documentation/dontdiff linux-2.6/Makefile linux-2.6-powerpc-crtsavres/Makefile
> --- linux-2.6/Makefile	2009-09-17 20:04:30.000000000 +0400
> +++ linux-2.6-powerpc-crtsavres/Makefile	2009-09-23 21:41:16.000000000 +0400
> @@ -326,6 +326,7 @@ MODFLAGS	= -DMODULE
>  CFLAGS_MODULE   = $(MODFLAGS)
>  AFLAGS_MODULE   = $(MODFLAGS)
>  LDFLAGS_MODULE  = -T $(srctree)/scripts/module-common.lds
> +LDFLAGS_MODULE_PREREQ  =
>  CFLAGS_KERNEL	=
>  AFLAGS_KERNEL	=
>  CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
> @@ -355,6 +356,7 @@ export VERSION PATCHLEVEL SUBLEVEL KERNE
>  export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
>  export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
>  export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
> +export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE LDFLAGS_MODULE_PREREQ CHECK CHECKFLAGS
>  
>  export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
>  export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
> diff -urpN -X linux-2.6/Documentation/dontdiff linux-2.6/scripts/Makefile.modpost linux-2.6-powerpc-crtsavres/scripts/Makefile.modpost
> --- linux-2.6/scripts/Makefile.modpost	2009-09-17 20:04:42.000000000 +0400
> +++ linux-2.6-powerpc-crtsavres/scripts/Makefile.modpost	2009-09-23 22:15:00.000000000 +0400
> @@ -122,14 +122,22 @@ quiet_cmd_cc_o_c = CC      $@
>        cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE)	\
>  		   -c -o $@ $<
>  
> -$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
> +quiet_cmd_as_o_S = AS $(quiet_modtag)  $@
> +cmd_as_o_S       = $(CC) $(a_flags) $(AFLAGS_MODULE) -c -o $@ $<
> +
> +$(LDFLAGS_MODULE_PREREQ): %.o: %.S FORCE
> +	$(Q)mkdir -p $(dir $@)
> +	$(call if_changed_dep,as_o_S)
> +
> +$(modules:.ko=.mod.o): %.mod.o: %.mod.c $(LDFLAGS_MODULE_PREREQ) FORCE
>  	$(call if_changed_dep,cc_o_c)
>  
>  targets += $(modules:.ko=.mod.o)
>  
>  # Step 6), final link of the modules
>  quiet_cmd_ld_ko_o = LD [M]  $@
> -      cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@		\
> +      cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE_PREREQ)	\
> +			  $(LDFLAGS_MODULE) -o $@			\
>  			  $(filter-out FORCE,$^)
>  
>  $(modules): %.ko :%.o %.mod.o FORCE
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2009-09-25  0:15 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev list, Andrew Morton, Linux Kernel list

Hi Linus !

Here are a few more powerpc bits for 2.6.32. Mostly bug fixes, and a couple
of performance nits from Anton.

Cheers,
Ben.

The following changes since commit 94a8d5caba74211ec76dac80fc6e2d5c391530df:
  Linus Torvalds (1):
        Merge git://git.kernel.org/.../rusty/linux-2.6-for-linus

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge

Anton Blanchard (4):
      powerpc: Move 64bit heap above 1TB on machines with 1TB segments
      powerpc/perf_counter: Fix vdso detection
      powerpc: Increase NODES_SHIFT on 64bit from 4 to 8
      powerpc: Fix ibm,client-architecture-support printout

Becky Bruce (2):
      powerpc: Rename get_dma_direct_offset get_dma_offset
      powerpc: Change archdata dma_data to a union

Benjamin Herrenschmidt (3):
      powerpc/pmc: Don't access lppaca on Book3E
      powerpc/mm: Fix 40x and 8xx vs. _PAGE_SPECIAL
      Fix build of cpm_uart due to core changes

Hendrik Brueckner (1):
      hvc_console: Provide (un)locked version for hvc_resize()

Huang Weiyi (2):
      powerpc/book3e-64: Remove duplicated #include
      powerpc/mm: Remove duplicated #include

Josh Boyer (1):
      powerpc/4xx: Fix erroneous xmon warning on PowerPC 4xx

Rex Feany (1):
      powerpc/8xx: Fix regression introduced by cache coherency rewrite

Tim Abbott (1):
      powerpc: Cleanup linker script using new linker script macros.

Tony Breeds (1):
      powerpc: Check for unsupported relocs when using CONFIG_RELOCATABLE

roel kluin (1):
      powerpc: kmalloc failure ignored in vio_build_iommu_table()

 arch/powerpc/Kconfig                     |    6 +++
 arch/powerpc/Makefile                    |   11 +++++
 arch/powerpc/include/asm/device.h        |   11 ++++-
 arch/powerpc/include/asm/dma-mapping.h   |   27 ++++++++++-
 arch/powerpc/include/asm/iommu.h         |   10 ++++
 arch/powerpc/include/asm/pmc.h           |    2 +-
 arch/powerpc/include/asm/pte-40x.h       |    1 +
 arch/powerpc/include/asm/pte-8xx.h       |    1 +
 arch/powerpc/include/asm/pte-common.h    |    5 --
 arch/powerpc/kernel/dma-iommu.c          |   16 +++---
 arch/powerpc/kernel/dma.c                |   15 ++-----
 arch/powerpc/kernel/exceptions-64e.S     |    1 -
 arch/powerpc/kernel/pci-common.c         |    2 +-
 arch/powerpc/kernel/process.c            |   17 +++++++-
 arch/powerpc/kernel/prom_init.c          |    3 +-
 arch/powerpc/kernel/vdso.c               |   14 ++++--
 arch/powerpc/kernel/vio.c                |    4 +-
 arch/powerpc/kernel/vmlinux.lds.S        |   69 ++++++-----------------------
 arch/powerpc/mm/pgtable.c                |   19 +++++++-
 arch/powerpc/mm/tlb_low_64e.S            |    1 -
 arch/powerpc/platforms/cell/beat_iommu.c |    2 +-
 arch/powerpc/platforms/cell/iommu.c      |    9 +---
 arch/powerpc/platforms/iseries/iommu.c   |    2 +-
 arch/powerpc/platforms/pasemi/iommu.c    |    2 +-
 arch/powerpc/platforms/pseries/iommu.c   |    8 ++--
 arch/powerpc/relocs_check.pl             |   56 ++++++++++++++++++++++++
 arch/powerpc/sysdev/dart_iommu.c         |    2 +-
 arch/powerpc/xmon/xmon.c                 |   16 ++++++-
 drivers/char/hvc_console.c               |    6 +-
 drivers/char/hvc_console.h               |   12 +++++-
 drivers/char/hvc_iucv.c                  |    4 +-
 drivers/serial/cpm_uart/cpm_uart_core.c  |    2 +-
 32 files changed, 237 insertions(+), 119 deletions(-)
 create mode 100755 arch/powerpc/relocs_check.pl

^ permalink raw reply

* Re: Fw: [PATCH] ppc: add ppc750 CL as supported by oprofile
From: Benjamin Herrenschmidt @ 2009-09-25  0:13 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linuxppc-dev, Dragos Tatulea
In-Reply-To: <20090924170541.5cdffc06.akpm@linux-foundation.org>

On Thu, 2009-09-24 at 17:05 -0700, Andrew Morton wrote:
> 
> Begin forwarded message:

Thanks. I'll pick it up.

Cheers,
Ben.

> Date: Wed, 16 Sep 009 11:58:15 +0300
> From: Dragos Tatulea <dtatulea@ixiacom.com>
> To: paulus@samba.org, linux-kernel@vger.kernel.org
> Cc: Octavian Purdila <opurdila@ixiacom.com>
> Subject: [PATCH] ppc: add ppc750 CL as supported by oprofile
> 
> 
> Hi,
> 
> 	Here's a patch that adds the ppc750 CL cpu as supported by oprofile.
> 
> -- Dragos
> 
> Signed-off-by: Dragos Tatulea <dtatulea@ixiacom.com>
> ---
>  arch/powerpc/kernel/cputable.c |    2 ++
>  1 files changed, 2 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> index 0b9c913..03c862b 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -711,6 +711,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
>  		.cpu_setup		= __setup_cpu_750,
>  		.machine_check		= machine_check_generic,
>  		.platform		= "ppc750",
> +		.oprofile_cpu_type      = "ppc/750",
> +		.oprofile_type		= PPC_OPROFILE_G4,
>  	},
>  	{	/* 745/755 */
>  		.pvr_mask		= 0xfffff000,
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Fw: [PATCH] ppc: add ppc750 CL as supported by oprofile
From: Andrew Morton @ 2009-09-25  0:05 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Dragos Tatulea



Begin forwarded message:

Date: Wed, 16 Sep 2009 11:58:15 +0300
From: Dragos Tatulea <dtatulea@ixiacom.com>
To: paulus@samba.org, linux-kernel@vger.kernel.org
Cc: Octavian Purdila <opurdila@ixiacom.com>
Subject: [PATCH] ppc: add ppc750 CL as supported by oprofile


Hi,

	Here's a patch that adds the ppc750 CL cpu as supported by oprofile.

-- Dragos

Signed-off-by: Dragos Tatulea <dtatulea@ixiacom.com>
---
 arch/powerpc/kernel/cputable.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 0b9c913..03c862b 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -711,6 +711,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.cpu_setup		= __setup_cpu_750,
 		.machine_check		= machine_check_generic,
 		.platform		= "ppc750",
+		.oprofile_cpu_type      = "ppc/750",
+		.oprofile_type		= PPC_OPROFILE_G4,
 	},
 	{	/* 745/755 */
 		.pvr_mask		= 0xfffff000,

^ permalink raw reply related

* Re: [PATCH] perf_event, powerpc: Fix compilation after big perf_counter rename
From: Stephen Rothwell @ 2009-09-24 23:58 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Peter Zijlstra, linux-kernel, linuxppc-dev, Paul Mackerras,
	Linus Torvalds, David S. Miller
In-Reply-To: <1253798755.16237.4.camel@concordia>

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

Hi Ingo,

On Thu, 24 Sep 2009 23:25:55 +1000 Michael Ellerman <michael@ellerman.id.au> wrote:
>
> Give me a day or two, I should be able to add a per-branch setting for
> who to send mails to without too much trouble.

In the mean time I don't now if someone has pointed you at these today:

http://kisskb.ellerman.id.au/kisskb/branch/12/

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Benjamin Herrenschmidt @ 2009-09-24 23:52 UTC (permalink / raw)
  To: Rex Feany; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <20090924233346.GA445@compile2.chatsunix.int.mrv.com>

On Thu, 2009-09-24 at 16:33 -0700, Rex Feany wrote:
> Thus spake Benjamin Herrenschmidt (benh@kernel.crashing.org):
> 
> > You can get my tree at:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
> > 
> > (To get the "merge" branch, just add "merge" after the clone if you
> > are cloning it, or just create a local branch and manually pull
> > into it)
> 
> Your tree hangs on boot, similar to what I saw without the 8xx
> work-around patch -- it is hard to tell if it is the same though. :(

There's no backtrace ? Where does it hang ? Also which workaround
patch ? The missing tlbil_va() or the _PAGE_SPECIAL problem ?

> > Note that i just pushed out so it may take a little while for
> > the kernel.org mirrors to get it, the commit ID is: 
> > 
> > ae48e383e3299c2f87723d21df2db97927774b1e
> 
> Maybe I fail git 101 -- I can't seem to find that commit ID in the repo
> above, but I do see the patches you commited to fix PAGE_SPECIAL and the
> 8xx work-around.

Right. I must have screwed something with the ID.

Ben.

^ permalink raw reply

* Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
From: Rex Feany @ 2009-09-24 23:33 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1253774659.7103.405.camel@pasglop>

Thus spake Benjamin Herrenschmidt (benh@kernel.crashing.org):

> You can get my tree at:
> 
> git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git
> 
> (To get the "merge" branch, just add "merge" after the clone if you
> are cloning it, or just create a local branch and manually pull
> into it)

Your tree hangs on boot, similar to what I saw without the 8xx
work-around patch -- it is hard to tell if it is the same though. :(

> Note that i just pushed out so it may take a little while for
> the kernel.org mirrors to get it, the commit ID is: 
> 
> ae48e383e3299c2f87723d21df2db97927774b1e

Maybe I fail git 101 -- I can't seem to find that commit ID in the repo
above, but I do see the patches you commited to fix PAGE_SPECIAL and the
8xx work-around.

thanks!
/rex.

^ permalink raw reply

* Re: 2.6.31-git5 kernel boot hangs on powerpc
From: Benjamin Herrenschmidt @ 2009-09-24 21:05 UTC (permalink / raw)
  To: Sachin Sant; +Cc: Tejun Heo, Linux/PPC Development, David Miller
In-Reply-To: <4ABB72BD.9050905@in.ibm.com>

On Thu, 2009-09-24 at 18:53 +0530, Sachin Sant wrote:
> Tejun Heo wrote:
> > Sachin Sant wrote:
> >   
> >> Tejun Heo wrote:
> >>     
> >>> Can you please apply the attached patch and see whether anything
> >>> interesting shows up in the kernel log?
> >>>   
> >>>       
> >> Thanks Tejun for the debug patch. Attached here are the relevant logs.
> >> The only messages related to percpu in the logs are
> >>
> >> <6>PERCPU: Embedded 2 pages/cpu @c000000001200000 s100232 r0 d30840 u524288
> >> <7>pcpu-alloc: s100232 r0 d30840 u524288 alloc=1*1048576
> >> <7>pcpu-alloc: [0] 0 1
> >> The captured logs are with latest git.
> >>     
> >
> > Hmm... that means it wasn't caused by rogue percpu pointer access.
> > Pleast wait a bit.  I'll try to reproduce it.
> >   
> I was able to reproduce the hang in a different way. (I still had
> IPV6 disabled in my config). I executed the network namespace container
> tests from LTP and could reproduce a similar hang. The top three
> function calls were the same as with IPV6. Here are the traces
> using xmon debugger.
> 
> 
> Oops: System Reset, sig: 6 [#4]
> SMP NR_CPUS=1024 DEBUG_PAGEALLOC NUMA pSeries
> Modules linked in: quota_v2 quota_tree fuse loop dm_mod sg sd_mod crc_t10dif ibmvscsic scsi_transport_srp scsi_tgt scsi_mod
> NIP: c00000000003c310 LR: c0000000000055d0 CTR: 0000000000000040
> REGS: c0000000fc90f340 TRAP: 0100   Tainted: G      D     (2.6.31-git13-autotest)
> MSR: 8000000000081032 <ME,IR,DR>  CR: 28004420  XER: 200 00001
> TASK = c00000002c408890[8753] 'check_netns_ena' THREAD: c0000000fc90c000 CPU: 2
> GPR00: 00000fffffffffff c0000000fc90f5c0 c000000000b8c2a8 d00007fffff00000
> GPR04: 0000000000000201 0000000000000300 d00007fffff00000 d00007fffff00000
> GPR08: 0000000000000000 000007fffff00000 0000000000000000 0000000000000000
> GPR12: 8000000000009032 c000000000c82a00 0000000000000001 c0000000fc90f924
> GPR16: 0000000000000300 0000000000000001 c0000000fa8e2380 0000000000000000
> GPR20: 0000000000010000 0000000000000001 0000000000000000 0000000000000000
> GPR24: c0000000fa9c09c8 0000000000000001 0000000000000001 c0000000faef6f60
> GPR28: c000000000c6b620 0000000000000000 c000000000af2aa0 c000000000c6d1b0
> NIP [c00000000003c310] .hash_page+0x24/0x4bc
> LR [c0000000000055d0] .do_hash_page+0x50/0x6c
> Call Trace:
> [c0000000fc90f5c0] [c0000000000055d0] .do_hash_page+0x50/0x6c (unreliable)
> --- Exception: 301 at .memset+0x60/0xfc
>     LR = .pcpu_alloc+0x718/0x8fc

So it's memsetting something that causes it to hash_page(), ie, faulting
in pages (vmalloc space ?) so far nothing obviously wrong....

> [c0000000fc90f8b0] [c0000000001700dc] .pcpu_alloc+0x6a8/0x8fc (unreliable)
> [c0000000fc90f9d0] [c000000000614648] .snmp_mib_init+0x54/0x9c
> [c0000000fc90fa60] [c000000000614764] .ipv4_mib_init_net+0xd4/0x1e0
> [c0000000fc90fb10] [c0000000005a839c] .setup_net+0x68/0x124
> [c0000000fc90fbb0] [c0000000005a8ad0] .copy_net_ns+0x88/0x130
> [c0000000fc90fc40] [c0000000000bd5ac] .create_new_namespaces+0x110/0x1d0
> [c0000000fc90fce0] [c0000000000bd874] .unshare_nsproxy_namespaces+0x6c/0xe8
> [c0000000fc90fd80] [c000000000091ee8] .SyS_unshare+0x13c/0x318
> [c0000000fc90fe30] [c0000000000085b4] syscall_exit+0x0/0x40
> Instruction dump:
> 7c0803a6 ebe1fff8 4e800020 78690100 7c0802a6 f8010010 3800ffff fa01ff80
> 7cb02b78 78000500 fa21ff88 fb61ffd8 <7c912378> fa41ff90 7c7b1b78 fa61ff98
> 
> As you can see the call trace is same as far as top three function calls
> are concerned [snmp_mib_init(), pcpu_alloc() and memset()].
> 
> The snmp_mib_init() function is :
> 
> int snmp_mib_init(void *ptr[2], size_t mibsize)
> {
>         BUG_ON(ptr == NULL);
>         ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long long));
>         if (!ptr[0])
>                 goto err0;
>         ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long long));
>         if (!ptr[1])
>                 goto err1;
>         return 0;
> .....
> 
> May be this might help..
> 
> Thanks
> -Sachin
> 
> 

^ permalink raw reply

* Re: [PATCH 4/4] powerpc/fsl: 85xx: add cache-sram support
From: Kumar Gala @ 2009-09-24 18:38 UTC (permalink / raw)
  To: Vivek Mahajan; +Cc: linuxppc-dev
In-Reply-To: <1253783426-11978-4-git-send-email-vivek.mahajan@freescale.com>


On Sep 24, 2009, at 2:10 AM, Vivek Mahajan wrote:

> This adds QorIQ based Cache-SRAM support as under:-
>
> * A small abstraction over powerpc's remote heap allocator
> * Exports mpc85xx_cache_sram_alloc()/free() APIs
> * Supports only one contiguous SRAM window
> * Defines FSL_85XX_CACHE_SRAM and its base address
>
> Signed-off-by: Vivek Mahajan <vivek.mahajan@freescale.com>
> ---
> Resending it to linuxppc-dev@ozlabs.org
>
> arch/powerpc/include/asm/fsl_85xx_cache_sram.h |   48 ++++++
> arch/powerpc/platforms/85xx/Kconfig            |    9 ++
> arch/powerpc/sysdev/Makefile                   |    1 +
> arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h      |   95 ++++++++++++
> arch/powerpc/sysdev/fsl_85xx_cache_sram.c      |  141 +++++++++++++++ 
> +++
> arch/powerpc/sysdev/fsl_85xx_l2ctlr.c          |  184 +++++++++++++++ 
> +++++++++
> 6 files changed, 478 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/include/asm/fsl_85xx_cache_sram.h
> create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
> create mode 100644 arch/powerpc/sysdev/fsl_85xx_cache_sram.c
> create mode 100644 arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
>
> diff --git a/arch/powerpc/include/asm/fsl_85xx_cache_sram.h b/arch/ 
> powerpc/include/asm/fsl_85xx_cache_sram.h
> new file mode 100644
> index 0000000..2af2bdc
> --- /dev/null
> +++ b/arch/powerpc/include/asm/fsl_85xx_cache_sram.h
> @@ -0,0 +1,48 @@
> +/*
> + * Copyright 2009 Freescale Semiconductor, Inc.
> + *
> + * Cache SRAM handling for QorIQ platform
> + *
> + * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
> +
> + * This file is derived from the original work done
> + * by Sylvain Munaut for the Bestcomm SRAM allocator.
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__
> +#define __ASM_POWERPC_FSL_85XX_CACHE_SRAM_H__
> +
> +#include <asm/rheap.h>
> +#include <linux/spinlock.h>
> +
> +/*
> + * Cache-SRAM
> + */
> +
> +struct mpc85xx_cache_sram {
> +	phys_addr_t base_phys;
> +	void *base_virt;
> +	unsigned int size;
> +	rh_info_t *rh;
> +	spinlock_t lock;
> +};
> +
> +extern void mpc85xx_cache_sram_free(void *ptr);
> +extern void *mpc85xx_cache_sram_alloc(unsigned int size,
> +				  phys_addr_t *phys, unsigned int align);
> +
> +#endif /* __AMS_POWERPC_FSL_85XX_CACHE_SRAM_H__ */
> diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/ 
> platforms/85xx/Kconfig
> index d3a975e..b6f23c3 100644
> --- a/arch/powerpc/platforms/85xx/Kconfig
> +++ b/arch/powerpc/platforms/85xx/Kconfig
> @@ -144,6 +144,15 @@ config SBC8560
> 	help
> 	  This option enables support for the Wind River SBC8560 board
>
> +config FSL_85XX_CACHE_SRAM
> +	bool
> +	select PPC_LIB_RHEAP
> +
> +config FSL_85XX_CACHE_SRAM_BASE
> +	hex
> +	depends on FSL_85XX_CACHE_SRAM
> +	default "0xfff00000"
> +
> endif # MPC85xx
>
> config TQM85xx
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/ 
> Makefile
> index 9d4b174..745994c 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -19,6 +19,7 @@ obj-$(CONFIG_FSL_PCI)		+= fsl_pci.o $(fsl-msi-obj-y)
> obj-$(CONFIG_FSL_LBC)		+= fsl_lbc.o
> obj-$(CONFIG_FSL_GTM)		+= fsl_gtm.o
> obj-$(CONFIG_MPC8xxx_GPIO)	+= mpc8xxx_gpio.o
> +obj-$(CONFIG_FSL_85XX_CACHE_SRAM)	+= fsl_85xx_l2ctlr.o  
> fsl_85xx_cache_sram.o
> obj-$(CONFIG_SIMPLE_GPIO)	+= simple_gpio.o
> obj-$(CONFIG_RAPIDIO)		+= fsl_rio.o
> obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
> diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/ 
> powerpc/sysdev/fsl_85xx_cache_ctlr.h
> new file mode 100644
> index 0000000..8c4a4ac
> --- /dev/null
> +++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
> @@ -0,0 +1,95 @@
> +/*
> + * Copyright 2009 Freescale Semiconductor, Inc
> + *
> + * QorIQ based Cache Controller Memory Mapped Registers
> + *
> + * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifndef __FSL_85XX_CACHE_CTLR_H__
> +#define __FSL_85XX_CACHE_CTLR_H__
> +
> +#define L2CR_L2FI		0x40000000	/* L2 flash invalidate */
> +#define L2CR_L2IO		0x00200000	/* L2 instruction only */
> +#define L2CR_SRAM_ZERO		0x00000000	/* L2SRAM zero size */
> +#define L2CR_SRAM_FULL		0x00010000	/* L2SRAM full size */
> +#define L2CR_SRAM_HALF		0x00020000	/* L2SRAM half size */
> +#define L2CR_SRAM_TWO_HALFS	0x00030000	/* L2SRAM two half sizes */
> +#define L2CR_SRAM_QUART		0x00040000	/* L2SRAM one quarter size */
> +#define L2CR_SRAM_TWO_QUARTS	0x00050000	/* L2SRAM two quarter size */
> +#define L2CR_SRAM_EIGHTH	0x00060000	/* L2SRAM one eighth size */
> +#define L2CR_SRAM_TWO_EIGHTH	0x00070000	/* L2SRAM two eighth size */
> +
> +#define L2SRAM_OPTIMAL_SZ_SHIFT	0x00000003	/* Optimum size for  
> L2SRAM */
> +
> +#define L2SRAM_BAR_MSK_LO18	0xFFFFC000	/* Lower 18 bits */
> +#define L2SRAM_BARE_MSK_HI4	0x0000000F	/* Upper 4 bits */
> +
> +enum cache_sram_lock_ways {
> +	LOCK_WAYS_ZERO,
> +	LOCK_WAYS_EIGHTH,
> +	LOCK_WAYS_TWO_EIGHTH,
> +	LOCK_WAYS_HALF = 4,
> +	LOCK_WAYS_FULL = 8,
> +};
> +
> +struct mpc85xx_l2ctlr {
> +	u32	ctl;		/* 0x000 - L2 control */
> +	u8	res1[0xC];
> +	u32	ewar0;		/* 0x010 - External write address 0 */
> +	u32	ewarea0;	/* 0x014 - External write address extended 0 */
> +	u32	ewcr0;		/* 0x018 - External write ctrl */
> +	u8	res2[4];
> +	u32	ewar1;		/* 0x020 - External write address 1 */
> +	u32	ewarea1;	/* 0x024 - External write address extended 1 */
> +	u32	ewcr1;		/* 0x028 - External write ctrl 1 */
> +	u8	res3[4];
> +	u32	ewar2;		/* 0x030 - External write address 2 */
> +	u32	ewarea2;	/* 0x034 - External write address extended 2 */
> +	u32	ewcr2;		/* 0x038 - External write ctrl 2 */
> +	u8	res4[4];
> +	u32	ewar3;		/* 0x040 - External write address 3 */
> +	u32	ewarea3;	/* 0x044 - External write address extended 3 */
> +	u32	ewcr3;		/* 0x048 - External write ctrl 3 */
> +	u8	res5[0xB4];
> +	u32	srbar0;		/* 0x100 - SRAM base address 0 */
> +	u32	srbarea0;	/* 0x104 - SRAM base addr reg ext address 0 */
> +	u32	srbar1;		/* 0x108 - SRAM base address 1 */
> +	u32	srbarea1;	/* 0x10C - SRAM base addr reg ext address 1 */
> +	u8	res6[0xCF0];
> +	u32	errinjhi;	/* 0xE00 - Error injection mask high */
> +	u32	errinjlo;	/* 0xE04 - Error injection mask low */
> +	u32	errinjctl;	/* 0xE08 - Error injection tag/ecc control */
> +	u8	res7[0x14];
> +	u32	captdatahi;	/* 0xE20 - Error data high capture */
> +	u32	captdatalo;	/* 0xE24 - Error data low capture */
> +	u32	captecc;	/* 0xE28 - Error syndrome */
> +	u8	res8[0x14];
> +	u32	errdet;		/* 0xE40 - Error detect */
> +	u32	errdis;		/* 0xE44 - Error disable */
> +	u32	errinten;	/* 0xE48 - Error interrupt enable */
> +	u32	errattr;	/* 0xE4c - Error attribute capture */
> +	u32	erradrrl;	/* 0xE50 - Error address capture low */
> +	u32	erradrrh;	/* 0xE54 - Error address capture high */
> +	u32	errctl;		/* 0xE58 - Error control */
> +	u8	res9[0x1A4];
> +};
> +
> +extern int instantiate_cache_sram(struct of_device *dev, unsigned  
> int size);
> +extern void remove_cache_sram(struct of_device *dev);
> +
> +#endif /* __FSL_85XX_CACHE_CTLR_H__ */
> diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_sram.c b/arch/ 
> powerpc/sysdev/fsl_85xx_cache_sram.c
> new file mode 100644
> index 0000000..6744083
> --- /dev/null
> +++ b/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
> @@ -0,0 +1,141 @@
> +/*
> + * Copyright 2009 Freescale Semiconductor, Inc.
> + *
> + * Simple memory allocator abstraction for QorIQ (P1/P2) based  
> Cache-SRAM
> + *
> + * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
> + *
> + * This file is derived from the original work done
> + * by Sylvain Munaut for the Bestcomm SRAM allocator.
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/of_platform.h>
> +#include <asm/pgtable.h>
> +#include <asm/fsl_85xx_cache_sram.h>
> +
> +struct mpc85xx_cache_sram *cache_sram;
> +
> +void *mpc85xx_cache_sram_alloc(unsigned int size,
> +			   phys_addr_t *phys, unsigned int align)
> +{
> +	unsigned long offset;
> +	unsigned long flags;
> +
> +	if (!size || (size > cache_sram->size) || (align > cache_sram- 
> >size)) {
> +		pr_err("%s(): size(=%x) or align(=%x) zero or too big\n",
> +			__func__, size, align);
> +		return NULL;
> +	}
> +
> +	if ((align &  (align - 1)) || align <= 1) {
> +		pr_err("%s(): align(=%x) must be power of two and >1\n",
> +			__func__, align);
> +		return NULL;
> +	}
> +
> +	spin_lock_irqsave(&cache_sram->lock, flags);
> +	offset = rh_alloc_align(cache_sram->rh, size, align, NULL);
> +	spin_unlock_irqrestore(&cache_sram->lock, flags);
> +
> +	if (IS_ERR_VALUE(offset))
> +		return NULL;
> +
> +	*phys = cache_sram->base_phys + offset;
> +
> +	return (unsigned char *)cache_sram->base_virt + offset;
> +}
> +EXPORT_SYMBOL(mpc85xx_cache_sram_alloc);
> +
> +void mpc85xx_cache_sram_free(void *ptr)
> +{
> +	unsigned long flags;
> +	BUG_ON(!ptr);
> +
> +	spin_lock_irqsave(&cache_sram->lock, flags);
> +	rh_free(cache_sram->rh, ptr - cache_sram->base_virt);
> +	spin_unlock_irqrestore(&cache_sram->lock, flags);
> +}
> +EXPORT_SYMBOL(mpc85xx_cache_sram_free);
> +
> +int __init instantiate_cache_sram(struct of_device *dev, unsigned  
> int size)
> +{
> +	if (cache_sram) {
> +		dev_err(&dev->dev, "Already initialized cache-sram\n");
> +		return -EBUSY;
> +	}
> +
> +	cache_sram = kzalloc(sizeof(struct mpc85xx_cache_sram), GFP_KERNEL);
> +	if (!cache_sram) {
> +		dev_err(&dev->dev, "Out of memory for cache_sram structure\n");
> +		return -ENOMEM;
> +	}
> +
> +	cache_sram->base_phys = CONFIG_FSL_85XX_CACHE_SRAM_BASE;
> +	cache_sram->size = size;
> +
> +	if (!request_mem_region(cache_sram->base_phys, cache_sram->size,
> +						"fsl_85xx_cache_sram")) {
> +		dev_err(&dev->dev, "%s: request memory failed\n",
> +				dev->node->full_name);
> +		kfree(cache_sram);
> +		return -ENXIO;
> +	}
> +
> +	cache_sram->base_virt = ioremap_flags(cache_sram->base_phys,
> +				cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);
> +	if (!cache_sram->base_virt) {
> +		dev_err(&dev->dev, "%s: ioremap_flags failed\n",
> +				dev->node->full_name);
> +		release_mem_region(cache_sram->base_phys, cache_sram->size);
> +		kfree(cache_sram);
> +		return -ENOMEM;
> +	}
> +
> +	cache_sram->rh = rh_create(sizeof(unsigned int));
> +	if (IS_ERR(cache_sram->rh)) {
> +		dev_err(&dev->dev, "%s: Unable to create remote heap\n",
> +				dev->node->full_name);
> +		iounmap(cache_sram->base_virt);
> +		release_mem_region(cache_sram->base_phys, cache_sram->size);
> +		kfree(cache_sram);
> +		return PTR_ERR(cache_sram->rh);
> +	}
> +
> +	rh_attach_region(cache_sram->rh, 0, cache_sram->size);
> +	spin_lock_init(&cache_sram->lock);
> +
> +	dev_info(&dev->dev, "[base:0x%x, size:0x%x] configured and loaded 
> \n",
> +		cache_sram->base_phys, cache_sram->size);
> +	return 0;
> +}
> +
> +void remove_cache_sram(struct of_device *dev)
> +{
> +	BUG_ON(!cache_sram);
> +
> +	rh_detach_region(cache_sram->rh, 0, cache_sram->size);
> +	rh_destroy(cache_sram->rh);
> +
> +	iounmap(cache_sram->base_virt);
> +	release_mem_region(cache_sram->base_phys, cache_sram->size);
> +
> +	kfree(cache_sram);
> +	cache_sram = NULL;
> +
> +	dev_info(&dev->dev, "MPC85xx Cache-SRAM driver unloaded\n");
> +}
> diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/ 
> sysdev/fsl_85xx_l2ctlr.c
> new file mode 100644
> index 0000000..1d36971
> --- /dev/null
> +++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
> @@ -0,0 +1,184 @@
> +/*
> + * Copyright 2009 Freescale Semiconductor, Inc.
> + *
> + * QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation
> + *
> + * Author: Vivek Mahajan <vivek.mahajan@freescale.com>
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/of_platform.h>
> +#include <asm/io.h>
> +
> +#include "fsl_85xx_cache_ctlr.h"
> +
> +static char *param;
> +struct mpc85xx_l2ctlr __iomem *l2ctlr;
> +
> +static long get_cache_sram_size(void)
> +{
> +	unsigned long val;
> +
> +	if (!param || (strict_strtoul(param, 0, &val) < 0))
> +		return -EINVAL;
> +
> +	return val;
> +}
> +
> +static int __init get_cmdline_param(char *str)
> +{
> +	if (!str)
> +		return 0;
> +
> +	param = str;
> +	return 1;
> +}
> +
> +__setup("cache-sram-size=", get_cmdline_param);
> +
> +static int __devinit mpc85xx_l2ctlr_of_probe(struct of_device *dev,
> +					  const struct of_device_id *match)
> +{
> +	long rval;
> +	unsigned int rem;
> +	unsigned char ways;
> +	const unsigned int *prop;
> +	unsigned int l2cache_size;
> +	unsigned int sram_size;
> +
> +	if (!dev->node) {
> +		dev_err(&dev->dev, "Device's OF-node is NULL\n");
> +		return -EINVAL;
> +	}
> +
> +	prop = of_get_property(dev->node, "cache-size", NULL);
> +	if (!prop) {
> +		dev_err(&dev->dev, "Missing L2 cache-size\n");
> +		return -EINVAL;
> +	}
> +	l2cache_size = *prop;
> +
> +	rval = get_cache_sram_size();
> +	if (rval <= 0) {
> +		dev_err(&dev->dev,
> +			"Entire L2 as cache, Aborting Cache-SRAM stuff\n");
> +		return -EINVAL;
> +	}
> +
> +	rem = l2cache_size % (unsigned int)rval;
> +	ways = l2cache_size / (unsigned int)rval;
> +	if (rem || (ways & (ways - 1))) {
> +		dev_err(&dev->dev, "Illegal cache-sram-size in command line\n");
> +		return -EINVAL;
> +	}
> +
> +	sram_size = (unsigned int)rval;
> +
> +	l2ctlr = of_iomap(dev->node, 0);
> +	if (!l2ctlr) {
> +		dev_err(&dev->dev, "Can't map L2 controller\n");
> +		return -EINVAL;
> +	}
> +
> +	/*
> +	 * Write bits[0-17] to srbar0
> +	 */
> +	out_be32(&l2ctlr->srbar0,
> +		CONFIG_FSL_85XX_CACHE_SRAM_BASE & L2SRAM_BAR_MSK_LO18);
> +
> +	/*
> +	 * Write bits[18-21] to srbare0
> +	 */
> +	out_be32(&l2ctlr->srbarea0,
> +		(CONFIG_FSL_85XX_CACHE_SRAM_BASE >> 10) & L2SRAM_BARE_MSK_HI4);
> +
> +	clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI);
> +
> +	switch (ways) {
> +	case LOCK_WAYS_EIGHTH:
> +		setbits32(&l2ctlr->ctl,
> +			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_EIGHTH);
> +		break;
> +
> +	case LOCK_WAYS_TWO_EIGHTH:
> +		setbits32(&l2ctlr->ctl,
> +			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_TWO_EIGHTH);
> +		break;
> +
> +	case LOCK_WAYS_HALF:
> +		setbits32(&l2ctlr->ctl,
> +			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_HALF);
> +		break;
> +
> +	case LOCK_WAYS_FULL:
> +	default:
> +		setbits32(&l2ctlr->ctl,
> +			L2CR_L2E | L2CR_L2FI | L2CR_SRAM_FULL);
> +		break;
> +	}
> +	mbar(1);

why isn't eieio() sufficient here?

> +
> +	rval = instantiate_cache_sram(dev, sram_size);
> +	if (rval < 0) {
> +		dev_err(&dev->dev, "Can't instantiate Cache-SRAM\n");
> +		iounmap(l2ctlr);
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int __devexit mpc85xx_l2ctlr_of_remove(struct of_device *dev)
> +{
> +	BUG_ON(!l2ctlr);
> +
> +	iounmap(l2ctlr);
> +	remove_cache_sram(dev);
> +	dev_info(&dev->dev, "MPC85xx L2 controller unloaded\n");
> +
> +	return 0;
> +}
> +
> +static struct of_device_id mpc85xx_l2ctlr_of_match[] = {
> +	{
> +		.compatible = "fsl,p2020-l2-cache-controller",
> +	},
> +	{},
> +};
> +
> +static struct of_platform_driver mpc85xx_l2ctlr_of_platform_driver  
> = {
> +	.name		= "fsl-l2ctlr",
> +	.match_table	= mpc85xx_l2ctlr_of_match,
> +	.probe		= mpc85xx_l2ctlr_of_probe,
> +	.remove		= __devexit_p(mpc85xx_l2ctlr_of_remove),
> +};
> +
> +static __init int mpc85xx_l2ctlr_of_init(void)
> +{
> +	return of_register_platform_driver 
> (&mpc85xx_l2ctlr_of_platform_driver);
> +}
> +
> +static void __exit mpc85xx_l2ctlr_of_exit(void)
> +{
> +	of_unregister_platform_driver(&mpc85xx_l2ctlr_of_platform_driver);
> +}
> +
> +subsys_initcall(mpc85xx_l2ctlr_of_init);
> +module_exit(mpc85xx_l2ctlr_of_exit);
> +
> +MODULE_DESCRIPTION("Freescale MPC85xx L2 controller init");
> +MODULE_LICENSE("GPL v2");
> -- 
> 1.5.6.5
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH][v2] powerpc/85xx: Create dts for each core in CAMP mode for P2020RDB
From: Kumar Gala @ 2009-09-24 18:20 UTC (permalink / raw)
  To: Poonam Aggrwal; +Cc: linuxppc-dev
In-Reply-To: <1253380436-1590-1-git-send-email-poonam.aggrwal@freescale.com>


On Sep 19, 2009, at 10:13 AM, Poonam Aggrwal wrote:

> This patch creates the dts files for each core and splits the  
> devices between
> the two cores for P2020RDB.
>
> core0 has memory, L2, i2c, spi, dma1, usb, eth0, eth1, crypto,  
> global-util, pci0
> core1 has L2, dma2, eth0, pci1, msi.
>
> MPIC is shared between two cores but each core will protect its
> interrupts from other core by using "protected-sources" of mpic.
>
> Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
> ---
> - based on http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
> - branch->next
> - Removed interrupt properties for serial ports to make them work in  
> polling mode.
> arch/powerpc/boot/dts/p2020rdb_camp_core0.dts |  363 ++++++++++++++++ 
> +++++++++
> arch/powerpc/boot/dts/p2020rdb_camp_core1.dts |  184 +++++++++++++
> arch/powerpc/platforms/85xx/mpc85xx_rdb.c     |   10 +-
> 3 files changed, 556 insertions(+), 1 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
> create mode 100644 arch/powerpc/boot/dts/p2020rdb_camp_core1.dts

applied to merge

- k

^ permalink raw reply

* Re: [PATCH] 82xx: kmalloc failure ignored in ep8248e_mdio_probe()
From: Kumar Gala @ 2009-09-24 18:19 UTC (permalink / raw)
  To: Roel Kluin; +Cc: Andrew Morton, paulus, linuxppc-dev
In-Reply-To: <4AA7C095.7090009@gmail.com>


On Sep 9, 2009, at 7:49 AM, Roel Kluin wrote:

> Prevent NULL dereference if kmalloc() fails. Also clean up if
> of_mdiobus_register() returns an error.
>
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
> ---
> Found with sed: http://kernelnewbies.org/roelkluin
>
> Please review.

applied to merge

- k

^ permalink raw reply

* Re: [PATCH][powerpc/85xx] P2020RDB Platform Support Added
From: Kumar Gala @ 2009-09-24 18:11 UTC (permalink / raw)
  To: Poonam Aggrwal; +Cc: linuxppc-dev list, Felix Radensky, linuxppc-release
In-Reply-To: <4A7A776D.7080400@embedded-sol.com>


On Aug 5, 2009, at 11:25 PM, Felix Radensky wrote:

> Hi, Poonam
>
> Poonam Aggrwal wrote:
>> Adds P2020RDB basic support in linux.
>> Overview of P2020RDB platform
>> 	- DDR
>> 	  DDR2 1G
>> 	- NOR Flash
>> 	  16MByte
>> 	- NAND Flash
>> 	  32MByte
>> 	- 3 Ethernet interfaces
>> 	  1) etSEC1
>> 		- RGMII
>> 		- connected to a 5 port Vitesse Switch(VSC7385)
>> 		- Switch is memory mapped through eLBC interface(CS#2)
>> 		- IRQ1
>> 	  2) etSEC2
>> 		- SGMII
>> 		- connected to VSC8221
>> 		- IRQ2
>> 	  3) etSEC3
>> 		- RGMII
>> 		- connected to VSC8641
>> 		- IRQ3
>> 	- 2 1X PCIe interfaces
>> 	- SD/MMC ,USB
>> 	- SPI EEPROM
>> 	- Serial I2C EEPROM
>>
>> Signed-off-by: Poonam Aggrwal <poonam.aggrwal@freescale.com>
>> ---
>> based on http://www.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
>> arch/powerpc/boot/dts/p2020rdb.dts        |  586 +++++++++++++++++++ 
>> ++++++++++
>> arch/powerpc/configs/mpc85xx_defconfig    |    1 +
>> arch/powerpc/platforms/85xx/Kconfig       |    9 +
>> arch/powerpc/platforms/85xx/Makefile      |    3 +-
>> arch/powerpc/platforms/85xx/mpc85xx_rdb.c |  141 +++++++
>> 5 files changed, 739 insertions(+), 1 deletions(-)
>> create mode 100644 arch/powerpc/boot/dts/p2020rdb.dts
>> create mode 100644 arch/powerpc/platforms/85xx/mpc85xx_rdb.c
>>
>> diff --git a/arch/powerpc/boot/dts/p2020rdb.dts b/arch/powerpc/boot/ 
>> dts/p2020rdb.dts
>> new file mode 100644
>> index 0000000..d6d8131
>> --- /dev/null
>> +++ b/arch/powerpc/boot/dts/p2020rdb.dts
>> @@ -0,0 +1,586 @@
>> +/*
>> + * P2020 RDB Device Tree Source
>> + *
>> + * Copyright 2009 Freescale Semiconductor Inc.
>> + *
>> + * 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.
>> + */
>> +
>> +/dts-v1/;
>> +/ {
>> +	model = "fsl,P2020";
>> +	compatible = "fsl,P2020RDB";
>> +	#address-cells = <2>;
>> +	#size-cells = <2>;
>> +
>> +	aliases {
>> +		ethernet0 = &enet0;
>> +		ethernet1 = &enet1;
>> +		ethernet2 = &enet2;
>> +		serial0 = &serial0;
>> +		serial1 = &serial1;
>> +		pci0 = &pci0;
>> +		pci1 = &pci1;
>> +	};
>> +
>> +	cpus {
>> +		#address-cells = <1>;
>> +		#size-cells = <0>;
>> +
>> +		PowerPC,P2020@0 {
>> +			device_type = "cpu";
>> +			reg = <0x0>;
>> +			next-level-cache = <&L2>;
>> +		};
>> +
>> +		PowerPC,P2020@1 {
>> +			device_type = "cpu";
>> +			reg = <0x1>;
>> +			next-level-cache = <&L2>;
>> +		};
>> +	};
>> +
>> +	memory {
>> +		device_type = "memory";
>> +	};
>> +
>> +	localbus@ffe05000 {
>> +		#address-cells = <2>;
>> +		#size-cells = <1>;
>> +		compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
>> +		reg = <0 0xffe05000 0 0x1000>;
>> +		interrupts = <19 2>;
>> +		interrupt-parent = <&mpic>;
>> +
>> +		/* NOR and NAND Flashes */
>> +		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
>> +			  0x1 0x0 0x0 0xffa00000 0x00040000
>> +			  0x2 0x0 0x0 0xffb00000 0x08000000>;
>>
>
> The comment is a bit misleading, CS2 is L2 switch. Also, are you sure
> the CS2 range shouldn't look like
>     0x2 0x0 0x0 0xffb00000 0x00020000
>
> That's what L2switch reg property suggests.

Did you plan on making this change?

>> +		nor@0,0 {
>> +			#address-cells = <1>;
>> +			#size-cells = <1>;
>> +			compatible = "cfi-flash";
>> +			reg = <0x0 0x0 0x1000000>;
>> +			bank-width = <2>;
>> +			device-width = <1>;
>> +
>> +			vitesse-7385-fw@0 {
>> +				/* This location must not be altered  */
>> +				/* 256KB for Vitesse 7385 Switch firmware */
>> +				reg = <0x0 0x00040000>;
>> +				label = "NOR (RO) Vitesse-7385 Firmware";
>> +				read-only;
>> +			};
>>
> Partitions should be declared as
>
>      partition@0 {
>                  reg = ...
>                  label = ...
>                  ...
>       }
> Felix.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ 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