public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] ppc64: updates for BPA platform
@ 2005-08-18 17:33 Arnd Bergmann
  2005-08-18 17:35 ` [PATCH 1/4] ppc64: fix IPI on bpa_iic Arnd Bergmann
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Arnd Bergmann @ 2005-08-18 17:33 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc64-dev, linux-kernel

These are a few updates for the BPA platform of ppc64. Only the first
two patches are meant for inclusion, the others are provided here
for people who are running on Cell already and cannot wait for clean
versions of the patches ;-)

I also have lots of updates pending for spufs, but will send them
separately.

	Arnd <><


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

* [PATCH 1/4] ppc64: fix IPI on bpa_iic
  2005-08-18 17:33 [PATCH 0/4] ppc64: updates for BPA platform Arnd Bergmann
@ 2005-08-18 17:35 ` Arnd Bergmann
  2005-08-18 17:39 ` [PATCH 2/4] net: update the spider_net driver Arnd Bergmann
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Arnd Bergmann @ 2005-08-18 17:35 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc64-dev, linux-kernel

This fixes a severe bug in the bpa_iic driver that caused
all sorts of problems.

We had been using incorrect priority values for inter processor
interrupts, which resulted in always doing CALL_FUNCTION
instead of RESCHEDULE or DEBUGGER_BREAK.

The symptoms cured by this patch include bad performance on
SMP systems spurious kernel panics in the IPI code.

Signed-off-by: Arnd Bergmann <arndb@de.ibm.com>

--- linux-2.6.13-rc6.orig/arch/ppc64/kernel/bpa_iic.c
+++ linux-2.6.13-rc6/arch/ppc64/kernel/bpa_iic.c
@@ -205,6 +205,18 @@ static struct iic_regs __iomem *find_iic
 }
 
 #ifdef CONFIG_SMP
+
+/* Use the highest interrupt priorities for IPI */
+static inline int iic_ipi_to_irq(int ipi)
+{
+	return IIC_IPI_OFFSET + IIC_NUM_IPIS - 1 - ipi;
+}
+
+static inline int iic_irq_to_ipi(int irq)
+{
+	return IIC_NUM_IPIS - 1 - (irq - IIC_IPI_OFFSET);
+}
+
 void iic_setup_cpu(void)
 {
 	out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
@@ -212,18 +224,20 @@ void iic_setup_cpu(void)
 
 void iic_cause_IPI(int cpu, int mesg)
 {
-	out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
+	out_be64(&per_cpu(iic, cpu).regs->generate, (IIC_NUM_IPIS - 1 - mesg) << 4);
 }
 
 static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
 {
-
-	smp_message_recv(irq - IIC_IPI_OFFSET, regs);
+	smp_message_recv(iic_irq_to_ipi(irq), regs);
 	return IRQ_HANDLED;
 }
 
-static void iic_request_ipi(int irq, const char *name)
+static void iic_request_ipi(int ipi, const char *name)
 {
+	int irq;
+
+	irq = iic_ipi_to_irq(ipi);
 	/* IPIs are marked SA_INTERRUPT as they must run with irqs
 	 * disabled */
 	get_irq_desc(irq)->handler = &iic_pic;
@@ -233,10 +247,10 @@ static void iic_request_ipi(int irq, con
 
 void iic_request_IPIs(void)
 {
-	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
-	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
+	iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
+	iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
 #ifdef CONFIG_DEBUGGER
-	iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
+	iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
 #endif /* CONFIG_DEBUGGER */
 }
 #endif /* CONFIG_SMP */


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

* [PATCH 2/4] net: update the spider_net driver
  2005-08-18 17:33 [PATCH 0/4] ppc64: updates for BPA platform Arnd Bergmann
  2005-08-18 17:35 ` [PATCH 1/4] ppc64: fix IPI on bpa_iic Arnd Bergmann
@ 2005-08-18 17:39 ` Arnd Bergmann
  2005-08-18 17:40 ` [PATCH 3/4] ppc64: add RTAS console driver Arnd Bergmann
  2005-08-18 17:42 ` [PATCH 4/4] ppc64: small hacks for running on BPA hardware Arnd Bergmann
  3 siblings, 0 replies; 6+ messages in thread
From: Arnd Bergmann @ 2005-08-18 17:39 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linuxppc64-dev, linux-kernel, paulus, netdev, akpm

This update fixes a few bugs in the spider_net driver, relative to
the version in 2.6.13-rc6-mm1. Please merge the updated driver in the
2.6.14 cycle.

- Prevent PCI posting problems by using synchronous register access
  in critical places
- Check return value from firmware device tree functions
- fix device cleanup

From: Jens Osterkamp <osterkam@de.ibm.com>
Signed-off-by: Arnd Bergmann <arndb@de.ibm.com>

diff -u devel-akpm/drivers/net/spider_net.c linux-2.6.13-rc3/drivers/net/spider_net.c
--- devel-akpm/drivers/net/spider_net.c	2005-08-06 15:34:31.000000000 -0700
+++ linux-2.6.13-rc3/drivers/net/spider_net.c
@@ -109,6 +109,23 @@
 }
 
 /**
+ * spider_net_write_reg_sync - writes to an SMMIO register of a card
+ * @card: device structure
+ * @reg: register to write to
+ * @value: value to write into the specified SMMIO register
+ *
+ * Unlike spider_net_write_reg, this will also make sure the
+ * data arrives on the card by reading the reg again.
+ */
+static void
+spider_net_write_reg_sync(struct spider_net_card *card, u32 reg, u32 value)
+{
+	value = cpu_to_le32(value);
+	writel(value, card->regs + reg);
+	(void)readl(card->regs + reg);
+}
+
+/**
  * spider_net_rx_irq_off - switch off rx irq on this spider card
  * @card: device structure
  *
@@ -123,7 +140,7 @@
 	spin_lock_irqsave(&card->intmask_lock, flags);
 	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
 	regvalue &= ~SPIDER_NET_RXINT;
-	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue);
+	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
 	spin_unlock_irqrestore(&card->intmask_lock, flags);
 }
 
@@ -196,7 +213,7 @@
 	spin_lock_irqsave(&card->intmask_lock, flags);
 	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
 	regvalue |= SPIDER_NET_RXINT;
-	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue);
+	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
 	spin_unlock_irqrestore(&card->intmask_lock, flags);
 }
 
@@ -215,7 +232,7 @@
 	spin_lock_irqsave(&card->intmask_lock, flags);
 	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
 	regvalue &= ~SPIDER_NET_TXINT;
-	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue);
+	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
 	spin_unlock_irqrestore(&card->intmask_lock, flags);
 }
 
@@ -234,7 +251,7 @@
 	spin_lock_irqsave(&card->intmask_lock, flags);
 	regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
 	regvalue |= SPIDER_NET_TXINT;
-	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue);
+	spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue);
 	spin_unlock_irqrestore(&card->intmask_lock, flags);
 }
 
@@ -813,6 +830,9 @@
 	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
 	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
 
+	/* free_irq(netdev->irq, netdev);*/
+	free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
+
 	spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
 			     SPIDER_NET_DMA_TX_FEND_VALUE);
 
@@ -822,10 +842,6 @@
 	/* release chains */
 	spider_net_release_tx_chain(card, 1);
 
-	/* switch off card */
-	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
-			     SPIDER_NET_CKRCTRL_STOP_VALUE);
-
 	spider_net_free_chain(card, &card->tx_chain);
 	spider_net_free_chain(card, &card->rx_chain);
 
@@ -1744,6 +1760,10 @@
 		goto register_int_failed;
 
 	spider_net_enable_card(card);
+	
+	netif_start_queue(netdev);
+	netif_carrier_on(netdev);
+	netif_poll_enable(netdev);
 
 	return 0;
 
@@ -2045,7 +2065,12 @@
 	netdev->irq = card->pdev->irq;
 
 	dn = pci_device_to_OF_node(card->pdev);
+	if (!dn)
+		return -EIO;
+
 	mac = (u8 *)get_property(dn, "local-mac-address", NULL);
+	if (!mac)
+		return -EIO;
 	memcpy(addr.sa_data, mac, ETH_ALEN);
 
 	result = spider_net_set_mac(netdev, &addr);
@@ -2241,12 +2266,17 @@
 
 	wait_event(card->waitq,
 		   atomic_read(&card->tx_timeout_task_counter) == 0);
-
+	
 	unregister_netdev(netdev);
+
+	/* switch off card */
+	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
+			     SPIDER_NET_CKRCTRL_STOP_VALUE);
+	spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
+			     SPIDER_NET_CKRCTRL_RUN_VALUE);
+	
 	spider_net_undo_pci_setup(card);
 	free_netdev(netdev);
-
-	free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
 }
 
 static struct pci_driver spider_net_driver = {


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

* [PATCH 3/4] ppc64: add RTAS console driver
  2005-08-18 17:33 [PATCH 0/4] ppc64: updates for BPA platform Arnd Bergmann
  2005-08-18 17:35 ` [PATCH 1/4] ppc64: fix IPI on bpa_iic Arnd Bergmann
  2005-08-18 17:39 ` [PATCH 2/4] net: update the spider_net driver Arnd Bergmann
@ 2005-08-18 17:40 ` Arnd Bergmann
  2005-08-18 18:07   ` Nish Aravamudan
  2005-08-18 17:42 ` [PATCH 4/4] ppc64: small hacks for running on BPA hardware Arnd Bergmann
  3 siblings, 1 reply; 6+ messages in thread
From: Arnd Bergmann @ 2005-08-18 17:40 UTC (permalink / raw)
  To: linuxppc64-dev; +Cc: linux-kernel

The RTAS console driver can be used by all machines that abstract
the system console through the {get,put}-term-char interface.
It replaces the hvconsole on BPA, because we don't run under
a hypervisor.

This driver needs to be redone as a special case of hvconsole,
so there is no point in applying the patch to generic kernels.
You will however need it if you intend to run on present Cell
hardware.

From: Utz Bacher <utz.bacher@de.ibm.com>
Signed-off-by: Arnd Bergmann <arndb@de.ibm.com>

--- linux-cg.orig/drivers/char/Kconfig	2005-08-18 17:09:44.971886072 -0400
+++ linux-cg/drivers/char/Kconfig	2005-08-18 17:30:54.496933408 -0400
@@ -560,6 +560,12 @@ config HVC_CONSOLE
 	  console. This driver allows each pSeries partition to have a console
 	  which is accessed via the HMC.
 
+config RTASCONS
+        bool "RTAS firmware console support"
+        depends on PPC_RTAS
+        help
+          RTAS console support.
+
 config HVCS
 	tristate "IBM Hypervisor Virtual Console Server support"
 	depends on PPC_PSERIES
--- linux-cg.orig/drivers/char/Makefile	2005-08-18 17:09:44.974885616 -0400
+++ linux-cg/drivers/char/Makefile	2005-08-18 17:30:54.497933256 -0400
@@ -40,6 +40,7 @@ obj-$(CONFIG_N_HDLC)		+= n_hdlc.o
 obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
 obj-$(CONFIG_SX)		+= sx.o generic_serial.o
 obj-$(CONFIG_RIO)		+= rio/ generic_serial.o
+obj-$(CONFIG_RTASCONS)		+= rtascons.o
 obj-$(CONFIG_HVC_CONSOLE)	+= hvc_console.o hvc_vio.o hvsi.o
 obj-$(CONFIG_RAW_DRIVER)	+= raw.o
 obj-$(CONFIG_SGI_SNSC)		+= snsc.o snsc_event.o
--- linux-cg.orig/drivers/char/rtascons.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-cg/drivers/char/rtascons.c	2005-08-18 17:31:21.912892064 -0400
@@ -0,0 +1,339 @@
+/*
+ * console driver using RTAS calls
+ *
+ * (C) Copyright IBM Corp. 2004
+ * RTAS console driver
+ *
+ * Author: Utz Bacher <utz.bacher@de.ibm.com>
+ *
+ *    inspired by drivers/char/hvc_console.c
+ *    written by Anton Blanchard and Paul Mackerras
+ *
+ * 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, 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.
+ */
+
+/* The whole driver assumes we only have one RTAS console. This makes
+ * things pretty easy. */
+
+#include <linux/console.h>
+#include <linux/cpumask.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/sysrq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <asm/atomic.h>
+#include <asm/rtas.h>
+#include <asm/uaccess.h>
+
+
+#define RTASCONS_MAJOR		229
+#define RTASCONS_MINOR		0
+
+#define RTASCONS_SYSRQ_KEY	'\x0f'
+
+#define RTASCONS_PUT_ATTEMPTS	16
+#define RTASCONS_PUT_DELAY	100
+#define RTASCONS_BUFFER_SIZE	4096
+
+#define RTASCONS_MAX_POLL	50
+#define RTASCONS_WRITE_ROOM	200
+
+#define RTASCONS_TIMEOUT	((HZ + 99) / 100)
+
+
+static struct tty_driver *rtascons_ttydriver;
+
+static atomic_t rtascons_usecount = ATOMIC_INIT(0);
+static struct tty_struct *rtascons_tty;
+
+static int rtascons_put_char_token;
+static int rtascons_get_char_token;
+
+static spinlock_t rtascons_buffer_lock = SPIN_LOCK_UNLOCKED;
+static char rtascons_buffer[RTASCONS_BUFFER_SIZE];
+static int rtascons_buffer_head = 0;
+static int rtascons_buffer_used = 0;
+
+static int
+rtascons_get_char(void)
+{
+	int result;
+
+	if (rtas_call(rtascons_get_char_token, 0, 2, &result))
+		result = -1;
+
+	return result;
+}
+
+/* assumes that rtascons_buffer_lock is held */
+static void
+rtascons_flush_chars(void)
+{
+	int result;
+	int attempts = RTASCONS_PUT_ATTEMPTS;
+
+	/* if there is more than one character to be displayed, wait a bit */
+	for (; rtascons_buffer_used && attempts; udelay(RTASCONS_PUT_DELAY)) {
+		attempts--;
+		result = rtas_call(rtascons_put_char_token, 1, 1, NULL,
+				   rtascons_buffer[rtascons_buffer_head]);
+
+		if (!result) {
+			rtascons_buffer_head = (rtascons_buffer_head + 1) %
+				RTASCONS_BUFFER_SIZE;
+			rtascons_buffer_used--;
+		}
+	}
+}
+
+static void
+rtascons_put_char(char c)
+{
+	spin_lock(&rtascons_buffer_lock);
+
+	if (rtascons_buffer_used >= (RTASCONS_BUFFER_SIZE / 2))
+		udelay(RTASCONS_PUT_DELAY); /* slow down if buffer tends
+					       to get full */
+
+	if (rtascons_buffer_used >= RTASCONS_BUFFER_SIZE)
+		goto out; /* we're loosing characters. */
+
+	/* enqueue character */
+	rtascons_buffer[(rtascons_buffer_head + rtascons_buffer_used) %
+		RTASCONS_BUFFER_SIZE] = c;
+	rtascons_buffer_used++;
+out:
+	rtascons_flush_chars();
+
+	spin_unlock(&rtascons_buffer_lock);
+}
+
+static void
+rtascons_print_str(const char *buf, int count)
+{
+	int i = 0;
+	while (i < count) {
+		rtascons_put_char(buf[i]);
+		if (buf[i] == '\n')
+			rtascons_put_char('\r');
+		i++;
+	}
+}
+
+static int
+rtascons_open(struct tty_struct *tty, struct file *filp)
+{
+	/* only one console */
+	if (tty->index) {
+		/* close will be called and that decrement */
+		atomic_inc(&rtascons_usecount);
+		return -ENODEV;
+	}
+
+	if (atomic_inc_return(&rtascons_usecount) == 1) {
+		rtascons_tty = tty;
+	}
+
+	tty->driver_data = &rtascons_ttydriver;
+
+	return 0;
+}
+
+static void
+rtascons_close(struct tty_struct *tty, struct file * filp)
+{
+	atomic_dec(&rtascons_usecount);
+}
+
+static void
+rtascons_hangup(struct tty_struct *tty)
+{
+}
+
+static int
+rtascons_write(struct tty_struct *tty, const unsigned char *buf, int count)
+{
+	if (!atomic_read(&rtascons_usecount))
+		return 0;
+
+	rtascons_print_str(buf, count);
+
+	return count;
+}
+
+static int
+rtascons_write_room(struct tty_struct *tty)
+{
+	return RTASCONS_WRITE_ROOM;
+}
+
+static int
+rtascons_chars_in_buffer(struct tty_struct *tty)
+{
+	return 0;
+}
+
+static void
+rtascons_poll(void)
+{
+	int i;
+	int do_poll = RTASCONS_MAX_POLL;
+#ifdef CONFIG_MAGIC_SYSRQ
+	static int sysrq_pressed = 0;
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+	if (!atomic_read(&rtascons_usecount))
+		return;
+
+	while (do_poll--) {
+		i = rtascons_get_char();
+		if (i < 0)
+			break;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+		if (i == RTASCONS_SYSRQ_KEY) {
+			sysrq_pressed = 1;
+			continue;
+		} else if (sysrq_pressed) {
+			handle_sysrq(i, NULL, rtascons_tty);
+			sysrq_pressed = 0;
+			continue;
+		}
+#endif /* CONFIG_MAGIC_SYSRQ */
+
+		tty_insert_flip_char(rtascons_tty, (unsigned char) i, 0);
+	}
+
+	tty_flip_buffer_push(rtascons_tty);
+}
+
+#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
+extern cpumask_t cpus_in_xmon;
+#else
+static const cpumask_t cpus_in_xmon = CPU_MASK_NONE;
+#endif
+
+static int
+krtasconsd(void *unused)
+{
+	daemonize("krtasconsd");
+
+	for (;;) {
+		if (cpus_empty(cpus_in_xmon)) {
+			rtascons_poll();
+			/* no need for atomic access */
+			if (rtascons_buffer_used) {
+				spin_lock(&rtascons_buffer_lock);
+				rtascons_flush_chars();
+				spin_unlock(&rtascons_buffer_lock);
+			}
+		}
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(RTASCONS_TIMEOUT);
+	}
+}
+
+static struct tty_operations rtascons_ops = {
+	.open = rtascons_open,
+	.close = rtascons_close,
+	.write = rtascons_write,
+	.hangup = rtascons_hangup,
+	.write_room = rtascons_write_room,
+	.chars_in_buffer = rtascons_chars_in_buffer,
+};
+
+static int __init
+rtascons_init(void)
+{
+	rtascons_ttydriver = alloc_tty_driver(1);
+	if (!rtascons_ttydriver)
+		return -ENOMEM;
+
+	rtascons_ttydriver->owner = THIS_MODULE;
+	rtascons_ttydriver->devfs_name = "rtascons/";
+	rtascons_ttydriver->driver_name = "rtascons";
+	rtascons_ttydriver->name = "rtascons";
+	rtascons_ttydriver->major = RTASCONS_MAJOR;
+	rtascons_ttydriver->minor_start = RTASCONS_MINOR;
+	rtascons_ttydriver->type = TTY_DRIVER_TYPE_SYSTEM;
+	rtascons_ttydriver->subtype = SYSTEM_TYPE_CONSOLE;
+	rtascons_ttydriver->init_termios = tty_std_termios;
+	rtascons_ttydriver->flags = TTY_DRIVER_REAL_RAW;
+	tty_set_operations(rtascons_ttydriver, &rtascons_ops);
+
+	if (tty_register_driver(rtascons_ttydriver))
+		panic("Couldn't register RTAS console driver\n");
+
+	kernel_thread(krtasconsd, NULL, CLONE_KERNEL);
+
+	return 0;
+}
+
+static void __exit
+rtascons_exit(void)
+{
+}
+
+static void
+rtascons_print(struct console *con, const char *buf, unsigned count)
+{
+	rtascons_print_str(buf, count);
+}
+
+static struct tty_driver *rtascons_device(struct console *con, int *index)
+{
+	*index = con->index;
+	return rtascons_ttydriver;
+}
+
+static int __init
+rtascons_setup(struct console *con, char *options)
+{
+	return (con->index);
+}
+
+struct console rtascons_driver = {
+	.name		= "rtas",
+	.write		= rtascons_print,
+	.device		= rtascons_device,
+	.setup		= rtascons_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= -1,
+};
+
+static int __init
+rtascons_register(void)
+{
+	rtascons_put_char_token = rtas_token("put-term-char");
+	if (rtascons_put_char_token == -1)
+		return -EIO;
+	rtascons_get_char_token = rtas_token("get-term-char");
+	if (rtascons_get_char_token == -1)
+		return -EIO;
+
+	register_console(&rtascons_driver);
+	return 0;
+}
+
+console_initcall(rtascons_register);
+
+module_init(rtascons_init);
+module_exit(rtascons_exit);


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

* [PATCH 4/4] ppc64: small hacks for running on BPA hardware
  2005-08-18 17:33 [PATCH 0/4] ppc64: updates for BPA platform Arnd Bergmann
                   ` (2 preceding siblings ...)
  2005-08-18 17:40 ` [PATCH 3/4] ppc64: add RTAS console driver Arnd Bergmann
@ 2005-08-18 17:42 ` Arnd Bergmann
  3 siblings, 0 replies; 6+ messages in thread
From: Arnd Bergmann @ 2005-08-18 17:42 UTC (permalink / raw)
  To: linuxppc64-dev; +Cc: linux-kernel

This patch is not meant for inclusion in a generic kernel,
but is currently needed to support the available HW.
Most of the things done in here are workarounds for
deficiencies in the present hardware or firmware that
will be solved there in later releases.

Signed-off-by: Arnd Bergmann <arndb@de.ibm.com>

--- linux-cg.orig/arch/ppc64/Kconfig	2005-08-18 17:23:29.789907568 -0400
+++ linux-cg/arch/ppc64/Kconfig	2005-08-18 17:23:52.529911976 -0400
@@ -221,6 +221,12 @@ config SMP
 
 	  If you don't know what to do here, say Y.
 
+config BE_DD2
+	bool "BE DD2.x Errata Workaround Support"
+	depends on PPC_BPA
+	---help---
+	This support enables BE DD2.x errata workarounds.
+
 config NR_CPUS
 	int "Maximum number of CPUs (2-128)"
 	range 2 128
--- linux-cg.orig/arch/ppc64/kernel/Makefile	2005-08-18 17:22:05.500940704 -0400
+++ linux-cg/arch/ppc64/kernel/Makefile	2005-08-18 17:23:52.668890848 -0400
@@ -33,7 +33,7 @@ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci
 			     pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
 			     pSeries_setup.o pSeries_iommu.o
 
-obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
+obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o bpa_pci.o \
 			 bpa_iic.o spider-pic.o
 
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o
--- linux-cg.orig/arch/ppc64/kernel/bpa_iommu.c	2005-08-18 17:23:29.778909240 -0400
+++ linux-cg/arch/ppc64/kernel/bpa_iommu.c	2005-08-18 17:23:52.472920640 -0400
@@ -245,8 +245,6 @@ set_iocmd_config(void __iomem *base)
 }
 
 /* FIXME: get these from the device tree */
-#define ioc_base	0x20000511000ull
-#define ioc_mmio_base	0x20000510000ull
 #define ioid		0x48a
 #define iopt_phys_offset (- 0x20000000) /* We have a 512MB offset from the SB */
 #define io_page_size	0x1000000
@@ -278,12 +276,22 @@ static void bpa_map_iommu(void)
 	void __iomem *base;
 	ioste ioste;
 	unsigned long index;
-
+	struct device_node *node;
+	unsigned long *handle, ioc_mmio_base, ioc_base;
+	int nodelen;
+
+	for(node = of_find_node_by_type(NULL, "cpu");
+	    node;
+	    node = of_find_node_by_type(node, "cpu")) {
+		handle = (unsigned long *) get_property(node, "ioc-translation", &nodelen); 
+		ioc_base = *handle + 0x1000;
+				
 	base = __ioremap(ioc_base, 0x1000, _PAGE_NO_CACHE);
 	pr_debug("%lx mapped to %p\n", ioc_base, base);
 	set_iocmd_config(base);
 	iounmap(base);
 
+		ioc_mmio_base = *handle;
 	base = __ioremap(ioc_mmio_base, 0x1000, _PAGE_NO_CACHE);
 	pr_debug("%lx mapped to %p\n", ioc_mmio_base, base);
 
@@ -302,6 +310,7 @@ static void bpa_map_iommu(void)
 			map_iopt_entry(address));
 	}
 	iounmap(base);
+	}
 }
 
 
--- linux-cg.orig/arch/ppc64/kernel/bpa_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-cg/arch/ppc64/kernel/bpa_pci.c	2005-08-18 17:28:39.211996792 -0400
@@ -0,0 +1,83 @@
+/*
+ * BPA specific PCI code
+ *
+ * Copyright (C) 2005 IBM Corporation,
+ 			Arnd Bergmann <arndb@de.ibm.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/prom.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+
+#include "pci.h"
+#include "bpa_iic.h"
+
+void __init bpa_final_fixup(void)
+{
+	struct pci_dev *dev = NULL;
+
+	phbs_remap_io();
+
+	for_each_pci_dev(dev) {
+	// FIXME: fix IRQ numbers for devices on second south bridge
+	}
+}
+
+static void fixup_spider_ipci_irq(struct pci_dev* dev)
+{
+	int irq_node_offset;
+	pr_debug("fixup for %04x:%04x at %02x.%1x: ", dev->vendor, dev->device,
+			 PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+	switch (dev->devfn) {
+		case PCI_DEVFN(3,0):
+			/* ethernet */
+			dev->irq = 8;
+			break;
+		case PCI_DEVFN(5,0):
+			/* OHCI 0 */
+			dev->irq = 10;
+			break;
+		case PCI_DEVFN(6,0):
+			/* OHCI 1 */
+			dev->irq = 11;
+			break;
+		case PCI_DEVFN(5,1):
+			/* EHCI 0 */
+			dev->irq = 10;
+			break;
+		case PCI_DEVFN(6,1):
+			/* EHCI 1 */
+			dev->irq = 11;
+			break;
+	}
+
+	irq_node_offset = IIC_NODE_STRIDE * (pci_domain_nr(dev->bus)-1);
+	dev->irq += irq_node_offset;
+
+	pr_debug("irq %0x\n", dev->irq);
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2,
+		PCI_DEVICE_ID_TOSHIBA_SPIDER_NET, fixup_spider_ipci_irq);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2,
+		PCI_DEVICE_ID_TOSHIBA_SPIDER_OHCI, fixup_spider_ipci_irq);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2,
+		PCI_DEVICE_ID_TOSHIBA_SPIDER_EHCI, fixup_spider_ipci_irq);
--- linux-cg.orig/arch/ppc64/kernel/bpa_setup.c	2005-08-18 17:22:05.507939640 -0400
+++ linux-cg/arch/ppc64/kernel/bpa_setup.c	2005-08-18 17:23:52.669890696 -0400
@@ -54,6 +54,8 @@
 #define DBG(fmt...)
 #endif
 
+extern void bpa_final_fixup(void);
+
 void bpa_get_cpuinfo(struct seq_file *m)
 {
 	struct device_node *root;
@@ -129,6 +131,7 @@ struct machdep_calls __initdata bpa_md =
 	.setup_arch		= bpa_setup_arch,
 	.init_early		= bpa_init_early,
 	.get_cpuinfo		= bpa_get_cpuinfo,
+	.pcibios_fixup		= bpa_final_fixup,
 	.restart		= rtas_restart,
 	.power_off		= rtas_power_off,
 	.halt			= rtas_halt,
--- linux-cg.orig/arch/ppc64/kernel/head.S	2005-08-18 17:23:29.782908632 -0400
+++ linux-cg/arch/ppc64/kernel/head.S	2005-08-18 17:23:52.626897232 -0400
@@ -312,6 +312,38 @@ label##_pSeries:					\
 	RUNLATCH_ON(r13);				\
 	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
 
+#define WORKAROUND_EXCEPTION_PSERIES(n, label)			\
+	. = n;						\
+	.globl label##_pSeries;				\
+label##_pSeries:					\
+	mtspr	SPRG1,r21;		/* save r21 */	\
+        mfspr   r21, SPRN_CTRLF;			\
+        oris    r21, r21, 0x00C0;			\
+        mtspr   SPRN_CTRLT, r21;			\
+	mfspr	r21,SPRG1;		/* restore r21 */	\
+	mtspr	SPRG1,r13;		/* save r13 */	\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
+#define RES_EXCEPTION_PSERIES(n, label)			\
+	. = n;						\
+	.globl label##_pSeries;				\
+label##_pSeries:					\
+        mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg */ \
+        mtspr   SPRG1,r21;              /* use SPRG1 as scratch reg */ \
+        mfspr   r20,SPRG3;              /* get paca virtual address */ \
+        cmpdi   r20,0x0;                /* if SPRG3 zero,thread  */    \
+	bne     20f;			/* shouldn't run */ \
+18:					/* Stop current Thread */ \
+	andi.	 r21,0,0;					 \
+	mtspr    SPRN_CTRLT,r21;					 \
+19:								\
+	b	 19b;		 	/* Thread should be stopped */	 \
+20:							\
+	HMT_MEDIUM;					\
+	mtspr	SPRG1,r13;		/* save r13 */	\
+	RUNLATCH_ON(r13);				\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+
 #define STD_EXCEPTION_ISERIES(n, label, area)		\
 	.globl label##_iSeries;				\
 label##_iSeries:					\
@@ -391,7 +423,11 @@ label##_common:						\
 	.globl __start_interrupts
 __start_interrupts:
 
+#ifdef CONFIG_BE_DD2
+	RES_EXCEPTION_PSERIES(0x100, system_reset)
+#else
 	STD_EXCEPTION_PSERIES(0x100, system_reset)
+#endif
 
 	. = 0x200
 _machine_check_pSeries:
@@ -459,11 +495,15 @@ instruction_access_slb_pSeries:
 	mfspr	r3,SRR0			/* SRR0 is faulting address */
 	b	.do_slb_miss		/* Rel. branch works in real mode */
 
-	STD_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+#ifdef CONFIG_BE_DD2
+	WORKAROUND_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+#endif
 	STD_EXCEPTION_PSERIES(0x600, alignment)
 	STD_EXCEPTION_PSERIES(0x700, program_check)
 	STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-	STD_EXCEPTION_PSERIES(0x900, decrementer)
+#ifdef CONFIG_BE_DD2
+	WORKAROUND_EXCEPTION_PSERIES(0x900, decrementer)
+#endif
 	STD_EXCEPTION_PSERIES(0xa00, trap_0a)
 	STD_EXCEPTION_PSERIES(0xb00, trap_0b)
 
--- linux-cg.orig/arch/ppc64/kernel/prom_init.c	2005-08-18 17:23:29.787907872 -0400
+++ linux-cg/arch/ppc64/kernel/prom_init.c	2005-08-18 17:23:52.776874432 -0400
@@ -1365,6 +1365,8 @@ static int __init prom_find_machine_type
 				return PLATFORM_POWERMAC;
 			if (strstr(p, RELOC("Momentum,Maple")))
 				return PLATFORM_MAPLE;
+			if (strstr(p, RELOC("IBM,CPB")))
+				return PLATFORM_BPA;
 			i += sl + 1;
 		}
 	}
--- linux-cg.orig/arch/ppc64/kernel/spider-pic.c	2005-08-18 17:23:29.780908936 -0400
+++ linux-cg/arch/ppc64/kernel/spider-pic.c	2005-08-18 17:23:52.473920488 -0400
@@ -84,10 +84,11 @@ static void __iomem *spider_get_irq_conf
 
 static void spider_enable_irq(unsigned int irq)
 {
+	int nodeid = (irq / IIC_NODE_STRIDE) * 0x10;
 	void __iomem *cfg = spider_get_irq_config(irq);
 	irq = spider_get_nr(irq);
 
-	out_be32(cfg, in_be32(cfg) | 0x3107000eu);
+	out_be32(cfg, in_be32(cfg) | 0x3107000eu | nodeid);
 	out_be32(cfg + 4, in_be32(cfg + 4) | 0x00020000u | irq);
 }
 
@@ -150,13 +151,17 @@ int spider_get_irq(unsigned long int_pen
 void spider_init_IRQ(void)
 {
 	int node;
+#if 0
 	struct device_node *dn;
 	unsigned int *property;
+#endif
 	long spiderpic;
+	long pics[] = { 0x24000008000, 0x34000008000 };
 	int n;
 
 /* FIXME: detect multiple PICs as soon as the device tree has them */
-	for (node = 0; node < 1; node++) {
+	for (node = 0; node <= 1; node++) {
+#if 0
 		dn = of_find_node_by_path("/");
 		n = prom_n_addr_cells(dn);
 		property = (unsigned int *) get_property(dn,
@@ -166,6 +171,8 @@ void spider_init_IRQ(void)
 			continue;
 		for (spiderpic = 0; n > 0; --n)
 			spiderpic = (spiderpic << 32) + *property++;
+#endif
+		spiderpic = pics[node];
 		printk(KERN_DEBUG "SPIDER addr: %lx\n", spiderpic);
 		spider_pics[node] = __ioremap(spiderpic, 0x800, _PAGE_NO_CACHE);
 		for (n = 0; n < IIC_NUM_EXT; n++) {
--- linux-cg.orig/include/asm-ppc64/processor.h	2005-08-18 17:23:29.773910000 -0400
+++ linux-cg/include/asm-ppc64/processor.h	2005-08-18 17:23:52.423928088 -0400
@@ -438,7 +438,7 @@ struct thread_struct {
 	.fs = KERNEL_DS, \
 	.fpr = {0}, \
 	.fpscr = 0, \
-	.fpexc_mode = MSR_FE0|MSR_FE1, \
+	.fpexc_mode = 0, \
 }
 
 /*
--- linux-cg.orig/include/linux/pci_ids.h	2005-08-18 17:23:29.775909696 -0400
+++ linux-cg/include/linux/pci_ids.h	2005-08-18 17:23:52.827004832 -0400
@@ -1611,6 +1611,8 @@
 #define PCI_DEVICE_ID_TOSHIBA_TX4927	0x0180
 #define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC	0x0108
 #define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3
+#define PCI_DEVICE_ID_TOSHIBA_SPIDER_OHCI 0x01b6
+#define PCI_DEVICE_ID_TOSHIBA_SPIDER_EHCI 0x01b5
 
 #define PCI_VENDOR_ID_RICOH		0x1180
 #define PCI_DEVICE_ID_RICOH_RL5C465	0x0465


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

* Re: [PATCH 3/4] ppc64: add RTAS console driver
  2005-08-18 17:40 ` [PATCH 3/4] ppc64: add RTAS console driver Arnd Bergmann
@ 2005-08-18 18:07   ` Nish Aravamudan
  0 siblings, 0 replies; 6+ messages in thread
From: Nish Aravamudan @ 2005-08-18 18:07 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc64-dev, linux-kernel

On 8/18/05, Arnd Bergmann <arnd@arndb.de> wrote:
> The RTAS console driver can be used by all machines that abstract
> the system console through the {get,put}-term-char interface.
> It replaces the hvconsole on BPA, because we don't run under
> a hypervisor.
> 
> This driver needs to be redone as a special case of hvconsole,
> so there is no point in applying the patch to generic kernels.
> You will however need it if you intend to run on present Cell
> hardware.
> 
> From: Utz Bacher <utz.bacher@de.ibm.com>
> Signed-off-by: Arnd Bergmann <arndb@de.ibm.com>

<snip>
 
> --- linux-cg.orig/drivers/char/rtascons.c       1969-12-31 19:00:00.000000000 -0500
> +++ linux-cg/drivers/char/rtascons.c    2005-08-18 17:31:21.912892064 

<snip>

> +#define RTASCONS_TIMEOUT       ((HZ + 99) / 100)

msecs_to_jiffies(10)? Or perhaps leave it in milliseconds with a
comment as such (see below)?

<snip>

> +static int
> +krtasconsd(void *unused)
> +{
> +       daemonize("krtasconsd");
> +
> +       for (;;) {
> +               if (cpus_empty(cpus_in_xmon)) {
> +                       rtascons_poll();
> +                       /* no need for atomic access */
> +                       if (rtascons_buffer_used) {
> +                               spin_lock(&rtascons_buffer_lock);
> +                               rtascons_flush_chars();
> +                               spin_unlock(&rtascons_buffer_lock);
> +                       }
> +               }
> +
> +               set_current_state(TASK_INTERRUPTIBLE);
> +               schedule_timeout(RTASCONS_TIMEOUT);

Couldn't this be msleep_interruptible(RTASCONS_TIMEOUT) [if you make
RTASCONS_TIMEOUT in milliseconds]?

Thanks,
Nish

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

end of thread, other threads:[~2005-08-18 18:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-18 17:33 [PATCH 0/4] ppc64: updates for BPA platform Arnd Bergmann
2005-08-18 17:35 ` [PATCH 1/4] ppc64: fix IPI on bpa_iic Arnd Bergmann
2005-08-18 17:39 ` [PATCH 2/4] net: update the spider_net driver Arnd Bergmann
2005-08-18 17:40 ` [PATCH 3/4] ppc64: add RTAS console driver Arnd Bergmann
2005-08-18 18:07   ` Nish Aravamudan
2005-08-18 17:42 ` [PATCH 4/4] ppc64: small hacks for running on BPA hardware Arnd Bergmann

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