LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Memory corruption
From: Geert Uytterhoeven @ 2008-04-24 15:31 UTC (permalink / raw)
  To: Linux/PPC Development

[-- Attachment #1: Type: TEXT/PLAIN, Size: 5023 bytes --]

	Hi,

I saw some random lockups on my PS3, so I decided to give the current kernel a
try on the PS3 development tool.  It crashes when setting up the network:

| <5>Sending DHCP requests ., OK
| IP-Config: Got DHCP answer from 192.168.106.200, my address is 192.168.106.196
| IP-Config: Complete:
|      device=eth0, addr=192.168.106.196, mask=255.255.255.0, gw=192.168.106.254,
|      host=192.168.106.196, domain=sonytel.be, nis-domain=(none),
|      bootserver=192.168.106.200, rootserver=192.168.106.200, rootpath=/disk-02/ps3linux/debian-powerpc
| <5>Looking up port of RPC 100003/2 on 192.168.106.200
| <0>Unrecoverable FP Unavailable Exception 800 at c000000000305220
| Oops: Unrecoverable FP Unavailable Exception, sig: 6 [#1]
| SMP NR_CPUS=2 PS3
| Modules linked in:
| NIP: c000000000305220 LR: c000000000304d34 CTR: c0000000003051c0
| REGS: c00000000604aa70 TRAP: 0800   Not tainted  (2.6.25-03562-g3dc5063-dirty)
| MSR: 8000000000008032 <EE,IR,DR>  CR: 24004082  XER: 00000000
| TASK = c000000006046040[1] 'swapper' THREAD: c000000006048000 CPU: 0
| <6>GPR00: 0000000000000800 c00000000604acf0 c000000000603a88 c000000006262680 
| <6>GPR04: 0662160400000002 0000000000004000 c0000000064a4110 c00000000062eda8 
| <6>GPR08: c0000000061a6000 0000000000000001 0000000000000100 c0000000062bf880 
| <6>GPR12: 0000001100000000 c000000000548300 0000000000000000 0000000000000000 
| <6>GPR16: 0000000000000000 000000000000005c 0000000000000000 000000000000005c 
| <6>GPR20: c0000000063a9db8 00000000c0a86ac8 0000000000000000 c0000000063a9d08 
| <6>GPR24: 0000000000000040 0000000000004000 c0000000063a9b80 c000000006391e00 
| <6>GPR28: c0000000064a4020 c000000006262680 c0000000005ae478 c00000000604acf0 
| NIP [c000000000305220] .ip_output+0x60/0x8c
| LR [c000000000304d34] .ip_local_out+0x50/0x78
| Call Trace:
| [c00000000604acf0] [c00000000604ada0] 0xc00000000604ada0 (unreliable)
| [c00000000604ad70] [c000000000304d34] .ip_local_out+0x50/0x78
| [c00000000604ae00] [c0000000003050c0] .ip_push_pending_frames+0x364/0x410
| [c00000000604aeb0] [c000000000326a60] .udp_push_pending_frames+0x350/0x408
| [c00000000604af70] [c000000000328048] .udp_sendmsg+0x4c4/0x630
| [c00000000604b0d0] [c0000000003306e4] .inet_sendmsg+0x84/0xb0
| [c00000000604b170] [c0000000002cd430] .sock_sendmsg+0xc4/0x108
| [c00000000604b370] [c0000000002ceed8] .kernel_sendmsg+0x40/0x64
| [c00000000604b400] [c00000000038cc1c] .xs_send_kvec+0xc8/0x100
| [c00000000604b510] [c00000000038cd10] .xs_sendpages+0xbc/0x2f4
| [c00000000604b5e0] [c00000000038ed38] .xs_udp_send_request+0x60/0x148
| [c00000000604b680] [c00000000038b1b8] .xprt_transmit+0x144/0x27c
| [c00000000604b730] [c00000000038776c] .call_transmit+0x248/0x2b0
| [c00000000604b7d0] [c000000000390a68] .__rpc_execute+0xd8/0x314
| [c00000000604b870] [c000000000390d18] .rpc_execute+0x40/0x5c
| [c00000000604b900] [c000000000387fe8] .rpc_run_task+0x84/0xb0
| [c00000000604b9a0] [c00000000038814c] .rpc_call_sync+0x74/0xc0
| [c00000000604ba70] [c00000000039a568] .rpcb_getport_sync+0x110/0x178
| [c00000000604bb80] [c000000000511118] .root_nfs_getport+0x8c/0xbc
| [c00000000604bc30] [c0000000005112f0] .nfs_root_data+0x1a8/0x328
| [c00000000604bd70] [c0000000004f66a8] .mount_root+0x40/0x150
| [c00000000604be10] [c0000000004f695c] .prepare_namespace+0x1a4/0x1f4
| [c00000000604bea0] [c0000000004f5a48] .kernel_init+0x388/0x3c8
| [c00000000604bf90] [c0000000000229c8] .kernel_thread+0x4c/0x68
| Instruction dump:
| e9230028 e8fe8018 7c000026 54001ffe e9090018 78001f24 7d27002a 38000800 
| 7d2948f8 7d6b482a e92b0058 39290001 <c0000000> 00546e70 f9030020 4bfff775 
                                       ^^^^^^^^  ^^^^^^^^
			     should be f92b0058  b003007e

| <4>---[ end trace c7cf3d9b6c787395 ]---
| <0>Kernel panic - not syncing: Attempted to kill init!
| smp_call_function on cpu 0: other cpus not responding (0)
| 
|    System does not reboot automatically.
|    Please press POWER button.
| 
| <7>eth0: no IPv6 routers present

Findings:
  - Disabling CONFIG_INET fixed the problem.
  - I didn't manage to lock up my PS3 afterwards neither.
    But... while typing this, I saw an oops accessing address
    0xf000f000f0007000 somewhere in the networking code, so it looks like some
    corruption is going on after all.
  - Upon closer look, 8 bytes in the instruction dump above are not correct
    and have been overwritten with 0xc000000000546e70, which is the address of
    init_task.

With kind regards,

Geert Uytterhoeven
Software Architect

Sony Network and Software Technology Center Europe
The Corporate Village · Da Vincilaan 7-D1 · B-1935 Zaventem · Belgium

Phone:    +32 (0)2 700 8453
Fax:      +32 (0)2 700 8622
E-mail:   Geert.Uytterhoeven@sonycom.com
Internet: http://www.sony-europe.com/

Sony Network and Software Technology Center Europe
A division of Sony Service Centre (Europe) N.V.
Registered office: Technologielaan 7 · B-1840 Londerzeel · Belgium
VAT BE 0413.825.160 · RPR Brussels
Fortis Bank Zaventem · BIC GEBABEBB08A · IBAN BE39001382358619

^ permalink raw reply

* [PATCH] add gpiolib support for mpc5200
From: Sascha Hauer @ 2008-04-24 15:36 UTC (permalink / raw)
  To: linuxppc-dev

Hi all,

Feel free to comment on this.

Sascha


This patch adds gpiolib support for mpc5200 SOCs. I'm not sure
whether it's a good idea to make this optional via kconfig.
The gpt devices only support a single gpio. In the current of_gpio
implementation each chip consumes 32 GPIOs which leads to huge
gaps.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

---
 arch/powerpc/platforms/52xx/Kconfig        |    6 
 arch/powerpc/platforms/52xx/Makefile       |    2 
 arch/powerpc/platforms/52xx/mpc52xx_gpio.c |  408 +++++++++++++++++++++++++++++
 3 files changed, 416 insertions(+)

Index: arch/powerpc/platforms/52xx/mpc52xx_gpio.c
===================================================================
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
@@ -0,0 +1,408 @@
+/*
+ * MPC52xx gpio driver
+ *
+ * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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/of.h>
+#include <linux/kernel.h>
+#include <linux/of_gpio.h>
+#include <linux/io.h>
+#include <asm/of_platform.h>
+#include <asm/prom.h>
+#include <asm/gpio.h>
+#include <asm/mpc52xx.h>
+#include <sysdev/fsl_soc.h>
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+/*
+ * GPIO LIB API implementation for wakeup GPIOs.
+ *
+ * There's a maximum of 8 wakeup GPIOs. Which of these are available
+ * for use depends on your board setup.
+ *
+ * 0 -> GPIO_WKUP_7
+ * 1 -> GPIO_WKUP_6
+ * 2 -> PSC6_1
+ * 3 -> PSC6_0
+ * 4 -> ETH_17
+ * 5 -> PSC3_9
+ * 6 -> PSC2_4
+ * 7 -> PSC1_4
+ *
+ */
+static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
+	unsigned int ret;
+
+	ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
+
+	pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);
+
+	return ret;
+}
+
+static void mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
+	unsigned int tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	tmp = in_8(&regs->wkup_dvo);
+	if (val)
+		tmp |= 1 << (7 - gpio);
+	else
+		tmp &= ~(1 << (7 - gpio));
+	out_8(&regs->wkup_dvo, tmp);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+}
+
+static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio_wkup *regs = mm_gc->regs;
+	unsigned int tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	tmp = in_8(&regs->wkup_ddr);
+	tmp &= ~(1 << (7 - gpio));
+	out_8(&regs->wkup_ddr, tmp);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return 0;
+}
+
+static int mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio_wkup *regs = mm_gc->regs;
+	unsigned int tmp;
+	unsigned long flags;
+
+	/* First set initial value */
+	mpc52xx_wkup_gpio_set(gc, gpio, val);
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	/* Then set direction */
+	tmp = in_8(&regs->wkup_ddr);
+	tmp |= 1 << (7 - gpio);
+	out_8(&regs->wkup_ddr, tmp);
+
+	/* Finally enable the pin */
+	tmp = in_8(&regs->wkup_gpioe);
+	tmp |= 1 << (7 - gpio);
+	out_8(&regs->wkup_gpioe, tmp);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+
+	return 0;
+}
+
+static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
+                                    const struct of_device_id *match)
+{
+	struct of_mm_gpio_chip *mmchip;
+	struct of_gpio_chip *chip;
+
+	mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
+	if (!mmchip)
+		return -ENOMEM;
+
+	chip = &mmchip->of_gc;
+
+	chip->gpio_cells          = 2;
+	chip->gc.ngpio            = 8;
+	chip->gc.direction_input  = mpc52xx_wkup_gpio_dir_in;
+	chip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
+	chip->gc.get              = mpc52xx_wkup_gpio_get;
+	chip->gc.set              = mpc52xx_wkup_gpio_set;
+
+	return of_mm_gpiochip_add(ofdev->node, mmchip);
+}
+
+static int mpc52xx_gpiochip_remove(struct of_device *ofdev)
+{
+	return -EBUSY;
+}
+
+static struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
+	{
+		.compatible = "fsl,mpc5200-gpio-wkup",
+	},
+	{}
+};
+
+static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = {
+	.name = "gpio_wkup",
+	.match_table = mpc52xx_wkup_gpiochip_match,
+	.probe = mpc52xx_wkup_gpiochip_probe,
+	.remove = mpc52xx_gpiochip_remove,
+};
+
+/*
+ * GPIO LIB API implementation for simple GPIOs
+ *
+ * There's a maximum of 32 simple GPIOs. Which of these are available
+ * for use depends on your board setup.
+ * The numbering reflects the bit numbering in the port registers:
+ *
+ *  0..1  > reserved
+ *  2..3  > IRDA
+ *  4..7  > ETHR
+ *  8..11 > reserved
+ * 12..15 > USB
+ * 16..17 > reserved
+ * 18..23 > PSC3
+ * 24..27 > PSC2
+ * 28..31 > PSC1
+ */
+static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
+	unsigned int ret;
+
+	ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
+
+	return ret;
+}
+
+static void mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
+	unsigned int tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	tmp = in_be32(&regs->simple_dvo);
+	if (val)
+		tmp |= 1 << (31 - gpio);
+	else
+		tmp &= ~(1 << (31 - gpio));
+	out_be32(&regs->simple_dvo, tmp);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+}
+
+static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio *regs = mm_gc->regs;
+	unsigned int tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	tmp = in_be32(&regs->simple_ddr);
+	tmp &= ~(1 << (31 - gpio));
+	out_be32(&regs->simple_ddr, tmp);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	return 0;
+}
+
+static int mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpio *regs = mm_gc->regs;
+	unsigned int tmp;
+	unsigned long flags;
+
+	/* First set initial value */
+	mpc52xx_simple_gpio_set(gc, gpio, val);
+
+	spin_lock_irqsave(&gpio_lock, flags);
+
+	/* Then set direction */
+	tmp = in_be32(&regs->simple_ddr);
+	tmp |= 1 << (31 - gpio);
+	out_be32(&regs->simple_ddr, tmp);
+
+	/* Finally enable the pin */
+	tmp = in_be32(&regs->simple_gpioe);
+	tmp |= 1 << (31 - gpio);
+	out_be32(&regs->simple_gpioe, tmp);
+
+	spin_unlock_irqrestore(&gpio_lock, flags);
+
+	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+
+	return 0;
+}
+
+static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
+                                    const struct of_device_id *match)
+{
+	struct of_mm_gpio_chip *mmchip;
+	struct of_gpio_chip *chip;
+
+	mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
+	if (!mmchip)
+		return -ENOMEM;
+
+	chip = &mmchip->of_gc;
+
+	chip->gpio_cells          = 2;
+	chip->gc.ngpio            = 32;
+	chip->gc.direction_input  = mpc52xx_simple_gpio_dir_in;
+	chip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
+	chip->gc.get              = mpc52xx_simple_gpio_get;
+	chip->gc.set              = mpc52xx_simple_gpio_set;
+
+	return of_mm_gpiochip_add(ofdev->node, mmchip);
+}
+
+static struct of_device_id mpc52xx_simple_gpiochip_match[] = {
+	{
+		.compatible = "fsl,mpc5200-gpio",
+	},
+	{}
+};
+
+static struct of_platform_driver mpc52xx_simple_gpiochip_driver = {
+	.name = "gpio",
+	.match_table = mpc52xx_simple_gpiochip_match,
+	.probe = mpc52xx_simple_gpiochip_probe,
+	.remove = mpc52xx_gpiochip_remove,
+};
+
+/*
+ * GPIO LIB API implementation for gpt GPIOs.
+ *
+ * Each gpt only has a single GPIO.
+ */
+static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
+	unsigned int ret;
+
+	return (in_be32(&regs->status) & (1 << (31 - 23))) ? 1 : 0;
+
+	return ret;
+}
+
+static void mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
+
+	if (val)
+		out_be32(&regs->mode, 0x34);
+	else
+		out_be32(&regs->mode, 0x24);
+
+	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+}
+
+static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
+	struct mpc52xx_gpt *regs = mm_gc->regs;
+
+	out_be32(&regs->mode, 0x04);
+
+	return 0;
+}
+
+static int mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	mpc52xx_gpt_gpio_set(gc, gpio, val);
+	pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
+
+	return 0;
+}
+
+static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev,
+                                    const struct of_device_id *match)
+{
+	struct of_mm_gpio_chip *mmchip;
+	struct of_gpio_chip *chip;
+
+	mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
+	if (!mmchip)
+		return -ENOMEM;
+
+	chip = &mmchip->of_gc;
+
+	chip->gpio_cells          = 2;
+	chip->gc.ngpio            = 1;
+	chip->gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
+	chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
+	chip->gc.get              = mpc52xx_gpt_gpio_get;
+	chip->gc.set              = mpc52xx_gpt_gpio_set;
+
+	return of_mm_gpiochip_add(ofdev->node, mmchip);
+}
+
+static struct of_device_id mpc52xx_gpt_gpiochip_match[] = {
+	{
+		.compatible = "fsl,mpc5200-gpt-gpio",
+	},
+	{}
+};
+
+static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = {
+	.name = "gpio_gpt",
+	.match_table = mpc52xx_gpt_gpiochip_match,
+	.probe = mpc52xx_gpt_gpiochip_probe,
+	.remove = mpc52xx_gpiochip_remove,
+};
+
+static int __init mpc52xx_gpio_init(void)
+{
+	if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
+		printk(KERN_ERR "Unable to register wakeup GPIO driver\n");
+
+	if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
+		printk(KERN_ERR "Unable to register simple GPIO driver\n");
+
+	if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver))
+		printk(KERN_ERR "Unable to register gpt GPIO driver\n");
+
+	return 0;
+}
+
+
+/* Make sure we get initialised before anyone else tries to use us */
+subsys_initcall(mpc52xx_gpio_init);
+
+/* No exit call at the moment as we cannot unregister of gpio chips */
+
+MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
+MODULE_LICENSE("GPL v2");
+
Index: arch/powerpc/platforms/52xx/Kconfig
===================================================================
--- a/arch/powerpc/platforms/52xx/Kconfig.orig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -44,3 +44,9 @@ config PPC_MPC5200_BUGFIX
 
 	  It is safe to say 'Y' here
 
+config PPC_MPC5200_GPIO
+	bool "MPC5200 GPIO support"
+	depends on PPC_MPC52xx
+	select HAVE_GPIO_LIB
+	help
+	  Enable gpiolib support for mpc5200 based boards
Index: arch/powerpc/platforms/52xx/Makefile
===================================================================
--- a/arch/powerpc/platforms/52xx/Makefile.orig
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -14,3 +14,5 @@ obj-$(CONFIG_PM)		+= mpc52xx_sleep.o mpc
 ifeq ($(CONFIG_PPC_LITE5200),y)
 	obj-$(CONFIG_PM)	+= lite5200_sleep.o lite5200_pm.o
 endif
+
+obj-$(CONFIG_PPC_MPC5200_GPIO)	+= mpc52xx_gpio.o
\ No newline at end of file

-- 
Pengutronix e.K. - Linux Solutions for Science and Industry
-----------------------------------------------------------
Kontakt-Informationen finden Sie im Header dieser Mail oder
auf der Webseite -> http://www.pengutronix.de/impressum/ <-

^ permalink raw reply

* Re: missing current-speed property prevents autoconsole on pegasos
From: Matt Sealey @ 2008-04-24 15:42 UTC (permalink / raw)
  To: Olaf Hering; +Cc: linuxppc-dev
In-Reply-To: <20080423152206.GA10935@aepfle.de>

Why not just have users who wish to use console serial port autodetection
add 3 lines to their nvramrc?

-- 
Matt Sealey <matt@genesi-usa.com>
Genesi, Manager, Developer Relations

Olaf Hering wrote:
> Pegasos2 has no current-speed property in
> /pci@80000000/isa@C/serial@i2F8. As a result, console=ttyS0,115200 is
> still required unless the patch below is used.
> 
> What is the correct way to restore console detection on pegasos2?
> 
> Index: linux-2.6.25-pegasos/arch/powerpc/platforms/chrp/setup.c
> ===================================================================
> --- linux-2.6.25-pegasos.orig/arch/powerpc/platforms/chrp/setup.c
> +++ linux-2.6.25-pegasos/arch/powerpc/platforms/chrp/setup.c
> @@ -302,7 +305,7 @@ static void chrp_init_early(void)
>         if (!property)
>                 goto out_put;
>         if (!strcmp(property, "failsafe") || !strcmp(property, "serial"))
> -               add_preferred_console("ttyS", 0, NULL);
> +               add_preferred_console("ttyS", 0, "115200");
>  out_put:
>         of_node_put(node);
>  }
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH 00/10] powerpc: Add kexec/kdump support for ppc32
From: Dale Farnsworth @ 2008-04-24 15:42 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <C695814A-E9D5-4C62-81DF-E49127ECD2E0@kernel.crashing.org>

On Thu, Apr 24, 2008 at 07:50:52AM -0500, Kumar Gala wrote:
> On Nov 22, 2007, at 9:42 AM, Dale Farnsworth wrote:
>> This patch series adds kexec and kdump support for ppc32 in arch/ 
>> powerpc.
>> It has been successfully tested on the mpc8548_cds and prpmc2800  
>> platforms.
>> Mark Greer and I are preparing patches to the kexec-tools package as
>> well.
>
> Dale, can you look at updating your patchset now that we've made some  
> progress on other patches.

Yes.  It'll take a couple of weeks for me to fit it in though.

-Dale

^ permalink raw reply

* Re: mpc5200b custom board upstreamable?
From: Sascha Hauer @ 2008-04-24 15:53 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <fa686aa40804240813p66889769y3bee6eb0111741f7@mail.gmail.com>

On Thu, Apr 24, 2008 at 09:13:45AM -0600, Grant Likely wrote:
> On Thu, Apr 24, 2008 at 9:12 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> >
> >  Hi all,
> >
> >  I had the intention to push the code for a custom mpc5200b board (freely
> >  available, no internal project) upstream. After cleaning up the code I
> >  realized that actually no board specific code is left and our board is
> >  well handled by the mpc5200_simple_platform machine.
> >
> >  The only issue is that the machine only matches things like
> >  "schindler,cm5200", there's no generic entry. Would it be possible to
> >  add a "generic-mpc52xx" entry to this list?
> 
> I'm being cautious about this for the time being.  I'd like to have a
> generic match mechanism, but I don't want to do something that isn't
> easy to recover from if it turns out to be brain dead.  For now, just
> add your board name to the explicit match list.

The board is called "generic". No, just kidding ;)

> 
> >
> >  Another question: are defconfig and dts files for custom boards acceptable
> >  for upstream?
> 
> Yes, in the arch/powerpc/configs/52xx/ directory.

ok

Sascha

-- 
Pengutronix e.K. - Linux Solutions for Science and Industry
-----------------------------------------------------------
Kontakt-Informationen finden Sie im Header dieser Mail oder
auf der Webseite -> http://www.pengutronix.de/impressum/ <-

^ permalink raw reply

* Re: SecretLab 2.6.24 with USB
From: Aaron Sells @ 2008-04-24 16:04 UTC (permalink / raw)
  To: Peter Korsgaard, sam.d.karp; +Cc: linuxppc-embedded
In-Reply-To: <87iqy8haf8.fsf@macbook.be.48ers.dk>

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

Peter Korsgaard wrote:
> I don't see anything with platform devices for the c67x00 driver.

I added the relevant struct information.  The patch is attached.

> Either you do this by hand or you
> create XPAR_* macros which take the needed info out of xparameter.h
> (sorry, I don't have an xparameters.h with those defines at hand).

I generate the xparameters_ml403.h file using Xilinx's EDK base system 
builder wizard.  However, the wizard does not automatically enable the 
Cypress device to be interrupt driven.  I have manually done this as 
described in the attached patch.

The resulting xparameters_ml403.h has the following defines:

sellsa@SS-SBIR-Ubuntu:~/spacesuit/linux-2.6-xlnx$ cat 
arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h | grep USB
/* Definitions for peripheral CYPRESS_USB */
#define XPAR_CYPRESS_USB_PRH0_BASEADDR 0x80800000
#define XPAR_CYPRESS_USB_PRH0_HIGHADDR 0x8080FFFF
#define XPAR_SYSTEM_USB_INT_PIN_MASK 0X000001
#define XPAR_XPS_INTC_0_SYSTEM_USB_INT_PIN_INTR 0

When I boot the Xilinx ML403 board up, I get the following:

[    9.256329] ------------[ cut here ]------------
[    9.260000] Badness at drivers/usb/c67x00/c67x00-ll-hpi.c:244
[    9.260000] NIP: c01b5d6c LR: c01b5d60 CTR: c00170f4
[    9.260000] REGS: c3c19d70 TRAP: 0700   Not tainted 
(2.6.24-rc8-xlnx-dirty)
[    9.260000] MSR: 00029030 <EE,ME,IR,DR>  CR: 24000082  XER: 20000073
[    9.260000] TASK = c3c178a0[1] 'swapper' THREAD: c3c18000
[    9.260000] GPR00: 00000001 c3c19e20 c3c178a0 00000000 c032f518 
c0372730 27b38fa6 00000001
[    9.260000] GPR08: 00000000 00200200 c3d2b164 c3d2b164 24000082 
ffffcd64 c02d4c5c c02d4c6c
[    9.260000] GPR16: c02d4c90 c02d4c98 c02d4ca8 c02d4cd4 c02d4ce8 
00000000 c02d7114 c0370e78
[    9.260000] GPR24: c0360000 c02d4c54 c0330724 00000000 c3d2b148 
00000000 c3d2b140 c0330708
[    9.260000] NIP [c01b5d6c] c67x00_ll_reset+0x48/0x88
[    9.260000] LR [c01b5d60] c67x00_ll_reset+0x3c/0x88
[    9.260000] Call Trace:
[    9.260000] [c3c19e20] [c01b5d60] c67x00_ll_reset+0x3c/0x88 (unreliable)
[    9.260000] [c3c19e40] [c02885e0] c67x00_drv_probe+0x16c/0x2d8
[    9.260000] [c3c19e70] [c01694b0] platform_drv_probe+0x20/0x30
[    9.260000] [c3c19e80] [c01674f8] driver_probe_device+0xec/0x194
[    9.260000] [c3c19ea0] [c0167750] __driver_attach+0x88/0xf4
[    9.260000] [c3c19ec0] [c0166648] bus_for_each_dev+0x58/0x98
[    9.260000] [c3c19ef0] [c01672f4] driver_attach+0x24/0x34
[    9.260000] [c3c19f00] [c016706c] bus_add_driver+0xb4/0x218
[    9.260000] [c3c19f20] [c0167a64] driver_register+0x78/0x10c
[    9.260000] [c3c19f40] [c016982c] platform_driver_register+0x9c/0xac
[    9.260000] [c3c19f50] [c035fa44] c67x00_init+0x18/0x28
[    9.260000] [c3c19f60] [c034e200] kernel_init+0xfc/0x294
[    9.260000] [c3c19ff0] [c00047d8] kernel_thread+0x44/0x60
[    9.260000] Instruction dump:
[    9.260000] 90010024 480d56c5 38800000 7fa3eb78 6084fa50 4bfff2f5 
387d0020 388004e2
[    9.260000] 480d48d9 707dffff 7c000026 54001ffe <0f000000> 3c00ffff 
7fbd00d0 60000005
[   11.316192] c67x00 c67x00.0: Device reset failed
[   11.364172] c67x00: probe of c67x00.0 failed with error 65531

Sam, since you have this working, any help would be greatly appreciated. 
  What else do I need to do in order to get USB host working on this board?

[-- Attachment #2: virtex_devices.c.patch --]
[-- Type: text/plain, Size: 1551 bytes --]

--- arch/ppc/syslib/virtex_devices.c.old	2008-04-24 11:37:03.000000000 -0400
+++ arch/ppc/syslib/virtex_devices.c	2008-04-24 11:10:09.000000000 -0400
@@ -18,6 +18,7 @@
 #include <syslib/virtex_devices.h>
 #include <platforms/4xx/xparameters/xparameters.h>
 #include <linux/xilinx_devices.h>
+#include <linux/usb/c67x00.h>
 #include <asm/io.h>
 
 /*
@@ -320,6 +321,31 @@
 	}, \
 }
 
+/*
+ * Cypress USB C67x00 shortcut macro for single instance
+ */
+#define XPAR_C67x00_USB(num) { \
+	.name = "c67x00", \
+	.id = num, \
+	.num_resources = 2, \
+	.resource = (struct resource[]) { \
+		{ \
+			.start	= XPAR_CYPRESS_USB_PRH0_BASEADDR, \
+			.end	= XPAR_CYPRESS_USB_PRH0_BASEADDR + 0xf, \
+			.flags	= IORESOURCE_MEM, \
+		}, \
+		{ \
+			.start  = XPAR_XPS_INTC_0_SYSTEM_USB_INT_PIN_INTR, \
+			.end    = XPAR_XPS_INTC_0_SYSTEM_USB_INT_PIN_INTR, \
+			.flags  = IORESOURCE_IRQ, \
+		}, \
+	}, \
+	.dev.platform_data	= &(struct c67x00_platform_data) { \
+		.sie_config	= C67X00_SIE1_HOST | C67X00_SIE2_PERIPHERAL, \
+		.hpi_regstep	= 0x02, /* A0 not connected on 16bit bus */ \
+	}, \
+}
+
 /* UART 8250 driver platform data table */
 struct plat_serial8250_port virtex_serial_platform_data[] = {
 #if defined(XPAR_UARTNS550_0_BASEADDR)
@@ -511,6 +537,13 @@
 #if defined(XPAR_OPB_AC97_CONTROLLER_REF_1_BASEADDR)
 	XPAR_AC97_CONTROLLER_REFERENCE(1),
 #endif
+
+#if defined(XPAR_CYPRESS_USB_PRH0_BASEADDR)
+	XPAR_C67x00_USB(0),
+#endif
+#if defined(XPAR_CYPRESS_USB_PRH1_BASEADDR)
+	XPAR_C67x00_USB(1),
+#endif
 };
 
 /* Early serial support functions */

[-- Attachment #3: XilinxEDKUSBInterrupts.patch --]
[-- Type: text/plain, Size: 1652 bytes --]

diff -Naur ml403project.old/data/system.ucf ml403project/data/system.ucf
--- ml403project.old/data/system.ucf	2008-04-24 11:29:30.000000000 -0400
+++ ml403project/data/system.ucf	2008-04-24 11:28:04.000000000 -0400
@@ -599,6 +599,10 @@
 Net fpga_0_FLASH_Mem_CE_pin<0> SLEW = FAST;
 Net fpga_0_FLASH_Mem_CE_pin<0> DRIVE = 8;
 
+###NET USB interrupt
+Net USB_INT_pin LOC=V5;
+Net USB_INT_pin IOSTANDARD = LVCMOS33;
+
 #### New GMAC Coregen Derived Constraints
 		
 NET "*tx_gmii_mii_clk*"    			TNM_NET = "clk_phy_tx_clk0";
diff -Naur ml403project.old/system.mhs ml403project/system.mhs
--- ml403project.old/system.mhs	2008-04-24 11:29:08.000000000 -0400
+++ ml403project/system.mhs	2008-04-24 11:28:29.000000000 -0400
@@ -18,6 +18,7 @@
  PARAMETER VERSION = 2.1.0
 
 
+ PORT USB_INT_pin = USB_INT, DIR = I
  PORT fpga_0_RS232_Uart_RX_pin = fpga_0_RS232_Uart_RX, DIR = I
  PORT fpga_0_RS232_Uart_TX_pin = fpga_0_RS232_Uart_TX, DIR = O
  PORT fpga_0_LEDs_4Bit_GPIO_IO_pin = fpga_0_LEDs_4Bit_GPIO_IO, DIR = IO, VEC = [0:3]
@@ -421,6 +422,6 @@
  PARAMETER C_HIGHADDR = 0x8180ffff
  BUS_INTERFACE SPLB = plb
  PORT Irq = EICC405EXTINPUTIRQ
- PORT Intr = RS232_Uart_Interrupt & LEDs_4Bit_IP2INTC_Irpt & LEDs_Positions_IP2INTC_Irpt & Push_Buttons_Position_IP2INTC_Irpt & IIC_EEPROM_IIC2INTC_Irpt & TriMode_MAC_GMII_TemacIntc0_Irpt & xps_timer_1_Interrupt & TriMode_MAC_GMII_fifo_IP2INTC_Irpt
+ PORT Intr = RS232_Uart_Interrupt & LEDs_4Bit_IP2INTC_Irpt & LEDs_Positions_IP2INTC_Irpt & Push_Buttons_Position_IP2INTC_Irpt & IIC_EEPROM_IIC2INTC_Irpt & TriMode_MAC_GMII_TemacIntc0_Irpt & xps_timer_1_Interrupt & TriMode_MAC_GMII_fifo_IP2INTC_Irpt & USB_INT
 END
 

^ permalink raw reply

* Re: mpc5200b custom board upstreamable?
From: Grant Likely @ 2008-04-24 16:07 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <20080424155303.GK6692@pengutronix.de>

On Thu, Apr 24, 2008 at 9:53 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Thu, Apr 24, 2008 at 09:13:45AM -0600, Grant Likely wrote:
>  > On Thu, Apr 24, 2008 at 9:12 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
>  > >
>  > >  Hi all,
>  > >
>  > >  I had the intention to push the code for a custom mpc5200b board (freely
>  > >  available, no internal project) upstream. After cleaning up the code I
>  > >  realized that actually no board specific code is left and our board is
>  > >  well handled by the mpc5200_simple_platform machine.
>  > >
>  > >  The only issue is that the machine only matches things like
>  > >  "schindler,cm5200", there's no generic entry. Would it be possible to
>  > >  add a "generic-mpc52xx" entry to this list?
>  >
>  > I'm being cautious about this for the time being.  I'd like to have a
>  > generic match mechanism, but I don't want to do something that isn't
>  > easy to recover from if it turns out to be brain dead.  For now, just
>  > add your board name to the explicit match list.
>
>  The board is called "generic". No, just kidding ;)

/me slaps Sascha

Seriously though; I do intend to fix this, but I don't think adding a
generic entry to the compatible list is the right way to do it.  For
example, what would "mpc5200-generic" really mean anyway?  Convention
for usage of 'compatible' would indicate that it means the *entire
board* is compatible (obviously not true).  The use-case you're
talking about is simply "the board uses a 5200 and firmware is sane".
On the other hand, I may just be overthinking things and compatible is
the most appropriate place to specify that the board is a mpc5200
based board.  (please feel free to argue with my; my opinion can
probably be swayed... attaching promises of beer to your argument is
probably an effective strategy)

This is an issue that probably affects the other embedded platforms
too, so it would be nice to agree on a common method of handling it.

Regardless, whatever method is chosen, it is also important that it is
always possible for board specific fixups to override the generic
behavior.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* EABI
From: Brian Silverman @ 2008-04-24 16:13 UTC (permalink / raw)
  To: linuxppc-embedded

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

Is it possible to compile a Linux application using an EABI compiler 
(specfically, Xilinx's EDK powerpc-eabi-gcc.exe)?
 
The issue at hand is that we'd like for our customers to be able to use 
the Xilinx EDK toolchain (which we know they will have) to compile Linx 
apps without having to install another toolchain (crosstool, ELDK, etc).
 
So, what I'm hoping is that the EDK toolchain can be configured to be 
Linux compatible binaries, or that there is some kind of wrapper that 
will handle the incompatible interfaces.  Searching around, I've seen 
some mention of Linux EABI compatibility (for Debian ARM releases), but 
I haven't found any clear concensus...

P.S. My apologies if this message appears on the mailing list twice...

-- 
Brian Silverman
Concept X, LLC


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

^ permalink raw reply

* Re: [RFC][WIP][PATCH] Add IRQSTACKS to ppc32
From: Kumar Gala @ 2008-04-24 16:25 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1209048813.9060.192.camel@pasglop>


On Apr 24, 2008, at 9:53 AM, Benjamin Herrenschmidt wrote:
>
> On Thu, 2008-04-24 at 07:59 -0500, Kumar Gala wrote:
>> I'm going to change it to be just lmb_alloc() so it will be difficult
>> to share with ppc64 (other than w/an ifdef).
>
> Unless we change lmb_alloc to just be an lmb_alloc_base with 0 and  
> have
> the later do the right thing ?

don't follow.  Look at the "real" patch and comment on that.

> You don't put highmem in the LMBs ? If you do, we do need to have the
> max lowmem there no ?

we restrict lmb alloc via LMB_REAL_LIMIT in include/asm-powerpc/lmb.h

- k

^ permalink raw reply

* Re: mpc5200b custom board upstreamable?
From: Sascha Hauer @ 2008-04-24 16:28 UTC (permalink / raw)
  To: Grant Likely; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <fa686aa40804240907w7e36b579y4d2c63f00dd30848@mail.gmail.com>

On Thu, Apr 24, 2008 at 10:07:20AM -0600, Grant Likely wrote:
> On Thu, Apr 24, 2008 at 9:53 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > On Thu, Apr 24, 2008 at 09:13:45AM -0600, Grant Likely wrote:
> >  > On Thu, Apr 24, 2008 at 9:12 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> >  > >
> >  > >  Hi all,
> >  > >
> >  > >  I had the intention to push the code for a custom mpc5200b board (freely
> >  > >  available, no internal project) upstream. After cleaning up the code I
> >  > >  realized that actually no board specific code is left and our board is
> >  > >  well handled by the mpc5200_simple_platform machine.
> >  > >
> >  > >  The only issue is that the machine only matches things like
> >  > >  "schindler,cm5200", there's no generic entry. Would it be possible to
> >  > >  add a "generic-mpc52xx" entry to this list?
> >  >
> >  > I'm being cautious about this for the time being.  I'd like to have a
> >  > generic match mechanism, but I don't want to do something that isn't
> >  > easy to recover from if it turns out to be brain dead.  For now, just
> >  > add your board name to the explicit match list.
> >
> >  The board is called "generic". No, just kidding ;)
> 
> /me slaps Sascha
> 
> Seriously though; I do intend to fix this, but I don't think adding a
> generic entry to the compatible list is the right way to do it.  For
> example, what would "mpc5200-generic" really mean anyway?  Convention
> for usage of 'compatible' would indicate that it means the *entire
> board* is compatible (obviously not true).  The use-case you're
> talking about is simply "the board uses a 5200 and firmware is sane".
> On the other hand, I may just be overthinking things and compatible is
> the most appropriate place to specify that the board is a mpc5200
> based board.  (please feel free to argue with my; my opinion can
> probably be swayed... attaching promises of beer to your argument is
> probably an effective strategy)

At the moment my compatible entry looks like this:

compatible = "phytec,pcm030","generic-mpc52xx";

What I think would be nice is that "phytec,pcm030" support is used
when available and "generic-mpc52xx" as a fallback. We do not have any
platform specific hacks at the moment, but we may have later. Having
"phytec,pcm030" in the simple machine would prevent us from doing so.

> 
> This is an issue that probably affects the other embedded platforms
> too, so it would be nice to agree on a common method of handling it.
> 
> Regardless, whatever method is chosen, it is also important that it is
> always possible for board specific fixups to override the generic
> behavior.

agreed

Sascha


-- 
Pengutronix e.K. - Linux Solutions for Science and Industry
-----------------------------------------------------------
Kontakt-Informationen finden Sie im Header dieser Mail oder
auf der Webseite -> http://www.pengutronix.de/impressum/ <-

^ permalink raw reply

* Re: [PATCH 00/10] powerpc: Add kexec/kdump support for ppc32
From: Kumar Gala @ 2008-04-24 16:28 UTC (permalink / raw)
  To: Dale Farnsworth; +Cc: linuxppc-dev
In-Reply-To: <20080424154258.GA25852@farnsworth.org>


On Apr 24, 2008, at 10:42 AM, Dale Farnsworth wrote:
> On Thu, Apr 24, 2008 at 07:50:52AM -0500, Kumar Gala wrote:
>> On Nov 22, 2007, at 9:42 AM, Dale Farnsworth wrote:
>>> This patch series adds kexec and kdump support for ppc32 in arch/
>>> powerpc.
>>> It has been successfully tested on the mpc8548_cds and prpmc2800
>>> platforms.
>>> Mark Greer and I are preparing patches to the kexec-tools package as
>>> well.
>>
>> Dale, can you look at updating your patchset now that we've made some
>> progress on other patches.
>
> Yes.  It'll take a couple of weeks for me to fit it in though.

no problem.  I figure we are aiming for 2.6.27 for this functionality.

- k

^ permalink raw reply

* [PATCH] [POWERPC] spufs: add .gitignore for spu_save_dump.h & spu_restore_dump.h
From: Kumar Gala @ 2008-04-24 16:37 UTC (permalink / raw)
  To: jk, Paul Mackerras; +Cc: linuxppc-dev

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/platforms/cell/spufs/.gitignore |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 arch/powerpc/platforms/cell/spufs/.gitignore

diff --git a/arch/powerpc/platforms/cell/spufs/.gitignore b/arch/powerpc/platforms/cell/spufs/.gitignore
new file mode 100644
index 0000000..a09ee8d
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/.gitignore
@@ -0,0 +1,2 @@
+spu_save_dump.h
+spu_restore_dump.h
-- 
1.5.4.1

^ permalink raw reply related

* [PATCH] [POWERPC] Update .gitignore file
From: Kumar Gala @ 2008-04-24 16:39 UTC (permalink / raw)
  To: linuxppc-dev

Update .gitignore for zImage.iseries

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 arch/powerpc/boot/.gitignore |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
index 5ef2bdf..2347294 100644
--- a/arch/powerpc/boot/.gitignore
+++ b/arch/powerpc/boot/.gitignore
@@ -27,6 +27,7 @@ zImage.chrp
 zImage.coff
 zImage.coff.lds
 zImage.ep*
+zImage.iseries
 zImage.*lds
 zImage.miboot
 zImage.pmac
-- 
1.5.4.1

^ permalink raw reply related

* Re: EABI
From: Kumar Gala @ 2008-04-24 16:45 UTC (permalink / raw)
  To: Brian Silverman; +Cc: linuxppc-embedded
In-Reply-To: <4810B196.7000300@conceptxdesign.com>


On Apr 24, 2008, at 11:13 AM, Brian Silverman wrote:
> Is it possible to compile a Linux application using an EABI compiler  
> (specfically, Xilinx's EDK powerpc-eabi-gcc.exe)?
>
> The issue at hand is that we'd like for our customers to be able to  
> use the Xilinx EDK toolchain (which we know they will have) to  
> compile Linx apps without having to install another toolchain  
> (crosstool, ELDK, etc).
>
> So, what I'm hoping is that the EDK toolchain can be configured to  
> be Linux compatible binaries, or that there is some kind of wrapper  
> that will handle the incompatible interfaces.  Searching around,  
> I've seen some mention of Linux EABI compatibility (for Debian ARM  
> releases), but I haven't found any clear concensus...
>
> P.S. My apologies if this message appears on the mailing list twice...

The EABI and Linux ABI are not compatible and if you want to link with  
any libraries you will need a different compiler for linux.

- k

^ permalink raw reply

* Re: EABI
From: Grant Likely @ 2008-04-24 16:50 UTC (permalink / raw)
  To: Brian Silverman; +Cc: linuxppc-embedded
In-Reply-To: <4810B196.7000300@conceptxdesign.com>

On Thu, Apr 24, 2008 at 10:13 AM, Brian Silverman
<bsilverman@conceptxdesign.com> wrote:
>
>
> Is it possible to compile a Linux application using an EABI compiler
> (specfically, Xilinx's EDK powerpc-eabi-gcc.exe)?
>
> The issue at hand is that we'd like for our customers to be able to use the
> Xilinx EDK toolchain (which we know they will have) to compile Linx apps
> without having to install another toolchain (crosstool, ELDK, etc).
>
> So, what I'm hoping is that the EDK toolchain can be configured to be Linux
> compatible binaries, or that there is some kind of wrapper that will handle
> the incompatible interfaces.  Searching around, I've seen some mention of
> Linux EABI compatibility (for Debian ARM releases), but I haven't found any
> clear concensus...
>
>  P.S. My apologies if this message appears on the mailing list twice...

Unfortunately, no.

I recommend making use of the ELDK toolchain from Denx.

Cheers,
g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* [PATCH] [POWERPC] bootwrapper: fix build error on virtex405-head.S
From: Grant Likely @ 2008-04-24 17:33 UTC (permalink / raw)
  To: linuxppc-dev, jwboyer, paulus

From: Grant Likely <grant.likely@secretlab.ca>

virtex405-head.S is an assembler file, not a C file; therefore BOOTAFLAGS
is the correct place to set the needed -mcpu=405 flag.

Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
Paul, Josh;

This is a bug fix required in .26 ASAP.

Cheers,
g.

 arch/powerpc/boot/Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 5ba50c6..7822d25 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -40,7 +40,7 @@ $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
-$(obj)/virtex405-head.o: BOOTCFLAGS += -mcpu=405
+$(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
 
 
 zlib       := inffast.c inflate.c inftrees.c

^ permalink raw reply related

* [RFCv2 POWERPC] booting-without-of: bindings for FHCI USB, GPIO LEDs, MCU, and NAND on UPM
From: Anton Vorontsov @ 2008-04-24 17:52 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood
In-Reply-To: <20080422194135.GA27822@polina.dev.rtsoft.ru>

On Tue, Apr 22, 2008 at 11:41:35PM +0400, Anton Vorontsov wrote:
> Hi all,
> 
> Here is purposed bindings draft for the new drivers that I would like to
> send for this or next merge window, depending on results of this RFC. ;-)
> (The new bindings needs to be in-tree or at least Acked before I could
> send the drivers.)
> 
> Comments and suggestions are highly appreciated.

Much thanks for the comments on previous version. Here is the new one,
please speak up if there is anything I could improve.

Thanks in advance.

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index c350623..b560dc5 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -59,6 +59,10 @@ Table of Contents
       p) Freescale Synchronous Serial Interface
       q) USB EHCI controllers
       r) Freescale General-purpose Timers Module
+      s) Freescale QUICC Engine USB Controller
+      t) LEDs on GPIOs
+      u) Freescale MCU with MPC8349E-mITX compatible firmware
+      v) NAND on UPM-driven Freescale Localbus
 
   VII - Marvell Discovery mv64[345]6x System Controller chips
     1) The /system-controller node
@@ -2866,6 +2870,128 @@ platforms are moved over to use the flattened-device-tree model.
     	clock-frequency = <0>;
     };
 
+    s) Freescale QUICC Engine USB Controller
+
+    Required properties:
+      - compatible : should be "fsl,<chip>-qe-usb", "fsl,mpc8323-qe-usb";
+      - reg : the first two cells should contain gtm registers location and
+        length, the next two two cells should contain PRAM location and
+        length.
+      - interrupts : should contain USB interrupt.
+      - interrupt-parent : interrupt source phandle.
+      - fsl,fullspeed-clock : specifies the full speed USB clock source in
+        "clk<num>" or "brg<num>" format.
+      - fsl,lowspeed-clock : specifies the low speed USB clock source in
+        "clk<num>" or "brg<num>" format.
+      - fsl,usb-mode : should be "host".
+      - linux,hub-power-budget : optional, USB power budget for the root hub
+        in mA.
+      - gpios : should specify GPIOs in this order: USBOE, USBTP, USBTN, USBRP,
+        USBRN, SPEED (optional), and POWER (optional).
+
+    Example:
+
+	usb@6c0 {
+		compatible = "fsl,mpc8360-qe-usb", "fsl,mpc8323-qe-usb";
+		reg = <0x6c0 0x40 0x8b00 0x100>;
+		interrupts = <11>;
+		interrupt-parent = <&qeic>;
+		fsl,fullspeed-clock = "clk21";
+		fsl,usb-mode = "host";
+		gpios = <&qe_pio_b  2 0 /* USBOE */
+			 &qe_pio_b  3 0 /* USBTP */
+			 &qe_pio_b  8 0 /* USBTN */
+			 &qe_pio_b  9 0 /* USBRP */
+			 &qe_pio_b 11 0 /* USBRN */
+			 &qe_pio_e 20 0 /* SPEED */
+			 &qe_pio_e 21 0 /* POWER */>;
+	};
+
+    t) LEDs on GPIOs
+
+    Required properties:
+      - compatible : should be "linux,gpio-led".
+      - linux,name : LED name.
+      - linux,active-low : property should be present if LED wired as
+        active-low.
+      - linux,default-trigger : Linux default trigger for this LED.
+      - linux,brightness : default brightness.
+      - gpios : should specify LED GPIO.
+
+    Example:
+
+	led@0 {
+		compatible = "linux,gpio-led";
+		linux,name = "pwr";
+		linux,brightness = <1>;
+		linux,active-low;
+		gpios = <&mcu_pio 0>;
+	};
+
+	led@1 {
+	        compatible = "linux,gpio-led";
+	        linux,name = "hdd";
+	        linux,default-trigger = "ide-disk";
+		linux,active-low;
+		gpios = <&mcu_pio 1>;
+	};
+
+    u) Freescale MCU with MPC8349E-mITX compatible firmware
+
+    Required properties:
+      - compatible : "fsl,<mcu-chip>-<board>", "fsl,mcu-mpc8349emitx";
+      - reg : should specify I2C address (0x0a).
+      - #address-cells : should be 0.
+      - #size-cells : should be 0.
+      - #gpio-cells : should be 2.
+      - gpio-controller : should be present;
+
+    Example:
+
+	mcu_pio: mcu@0a {
+		#address-cells = <0>;
+		#size-cells = <0>;
+		#gpio-cells = <2>;
+		compatible = "fsl,mc9s08qg8-mpc8349emitx",
+			     "fsl,mcu-mpc8349emitx";
+		reg = <0x0a>;
+		gpio-controller;
+	};
+
+    v) Freescale Localbus UPM programmed to work with NAND flash
+
+      Required properties:
+      - #address-cells : should be 0;
+      - #size-cells : should be 0;
+      - compatible : "fsl,upm-nand".
+      - reg : should specify localbus chip select and size used for the chip.
+      - fsl,upm-addr-offset : UPM pattern offset for the address latch.
+      - fsl,upm-cmd-offset : UPM pattern offset for the command latch.
+      - gpios : may specify optional GPIO connected to the Ready-Not-Busy pin.
+
+      Example:
+
+	upm@1,0 {
+		#address-cells = <0>;
+		#size-cells = <0>;
+		compatible = "fsl,upm-nand";
+		reg = <1 0 1>;
+		fsl,upm-addr-offset = <16>;
+		fsl,upm-cmd-offset = <8>;
+		gpios = <&qe_pio_e 18 0>;
+
+		flash {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "stmicro,NAND512W3A2BN6E";
+
+			partition@0 {
+				...
+			};
+		};
+	};
+
 VII - Marvell Discovery mv64[345]6x System Controller chips
 ===========================================================
 

^ permalink raw reply related

* Re: SecretLab 2.6.24 with USB
From: Peter Korsgaard @ 2008-04-24 18:25 UTC (permalink / raw)
  To: Aaron Sells; +Cc: sam.d.karp, linuxppc-embedded
In-Reply-To: <4810AF87.80602@zin-tech.com>

>>>>> "Aaron" == Aaron Sells <aaron.sells@zin-tech.com> writes:

Hi,

 Aaron> I generate the xparameters_ml403.h file using Xilinx's EDK base system
 Aaron> builder wizard.  However, the wizard does not automatically enable the
 Aaron> Cypress device to be interrupt driven.  I have manually done this as
 Aaron> described in the attached patch.

 Aaron> The resulting xparameters_ml403.h has the following defines:

 Aaron> sellsa@SS-SBIR-Ubuntu:~/spacesuit/linux-2.6-xlnx$ cat
 Aaron> arch/ppc/platforms/4xx/xparameters/xparameters_ml403.h | grep USB
 Aaron> /* Definitions for peripheral CYPRESS_USB */
 Aaron> #define XPAR_CYPRESS_USB_PRH0_BASEADDR 0x80800000
 Aaron> #define XPAR_CYPRESS_USB_PRH0_HIGHADDR 0x8080FFFF
 Aaron> #define XPAR_SYSTEM_USB_INT_PIN_MASK 0X000001
 Aaron> #define XPAR_XPS_INTC_0_SYSTEM_USB_INT_PIN_INTR 0

Ok.

 Aaron> When I boot the Xilinx ML403 board up, I get the following:

 Aaron> [    9.256329] ------------[ cut here ]------------
 Aaron> [    9.260000] Badness at drivers/usb/c67x00/c67x00-ll-hpi.c:244
 Aaron> [    9.260000] NIP: c01b5d6c LR: c01b5d60 CTR: c00170f4
 Aaron> [    9.260000] REGS: c3c19d70 TRAP: 0700   Not tainted
 Aaron> (2.6.24-rc8-xlnx-dirty)
 Aaron> [    9.260000] MSR: 00029030 <EE,ME,IR,DR>  CR: 24000082  XER: 20000073
 Aaron> [    9.260000] TASK = c3c178a0[1] 'swapper' THREAD: c3c18000
 Aaron> [    9.260000] GPR00: 00000001 c3c19e20 c3c178a0 00000000 c032f518
 Aaron> c0372730 27b38fa6 00000001
 Aaron> [    9.260000] GPR08: 00000000 00200200 c3d2b164 c3d2b164 24000082
 Aaron> ffffcd64 c02d4c5c c02d4c6c
 Aaron> [    9.260000] GPR16: c02d4c90 c02d4c98 c02d4ca8 c02d4cd4 c02d4ce8
 Aaron> 00000000 c02d7114 c0370e78
 Aaron> [    9.260000] GPR24: c0360000 c02d4c54 c0330724 00000000 c3d2b148
 Aaron> 00000000 c3d2b140 c0330708
 Aaron> [    9.260000] NIP [c01b5d6c] c67x00_ll_reset+0x48/0x88
 Aaron> [    9.260000] LR [c01b5d60] c67x00_ll_reset+0x3c/0x88
 Aaron> [    9.260000] Call Trace:
 Aaron> [    9.260000] [c3c19e20] [c01b5d60] c67x00_ll_reset+0x3c/0x88 (unreliable)

This is an interrupt timeout. It seems like the interrupt isn't
correctly connected.

 Aaron> Sam, since you have this working, any help would be greatly
 Aaron> appreciated. What else do I need to do in order to get USB host
 Aaron> working on this board?

That should be about it.
 
 Aaron> +/*
 Aaron> + * Cypress USB C67x00 shortcut macro for single instance
 Aaron> + */
 Aaron> +#define XPAR_C67x00_USB(num) { \
 Aaron> +	.name = "c67x00", \
 Aaron> +	.id = num, \
 Aaron> +	.num_resources = 2, \
 Aaron> +	.resource = (struct resource[]) { \
 Aaron> +		{ \
 Aaron> +			.start	= XPAR_CYPRESS_USB_PRH0_BASEADDR, \
 Aaron> +			.end	= XPAR_CYPRESS_USB_PRH0_BASEADDR + 0xf, \
 Aaron> +			.flags	= IORESOURCE_MEM, \
 Aaron> +		}, \
 Aaron> +		{ \
 Aaron> +			.start  = XPAR_XPS_INTC_0_SYSTEM_USB_INT_PIN_INTR, \
 Aaron> +			.end    = XPAR_XPS_INTC_0_SYSTEM_USB_INT_PIN_INTR, \
 Aaron> +			.flags  = IORESOURCE_IRQ, \
 Aaron> +		}, \
 Aaron> +	}, \

I guess you need to add a few "num" to those defines to make it work
with multiple devices.

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* Re: [PATCH] [POWERPC] bootwrapper: fix build error on virtex405-head.S
From: Josh Boyer @ 2008-04-24 18:38 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev, paulus
In-Reply-To: <20080424173246.17691.73308.stgit@trillian.secretlab.ca>

On Thu, 2008-04-24 at 11:33 -0600, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> virtex405-head.S is an assembler file, not a C file; therefore BOOTAFLAGS
> is the correct place to set the needed -mcpu=405 flag.
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

Applied, pushed to 4xx/next and 4xx/for-2.6.26, and included in my pull
request.

josh

^ permalink raw reply

* Re: [PATCH] add gpiolib support for mpc5200
From: Grant Likely @ 2008-04-24 18:45 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linuxppc-dev
In-Reply-To: <20080424153659.GJ6692@pengutronix.de>

On Thu, Apr 24, 2008 at 9:36 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> Hi all,
>
>  Feel free to comment on this.
>
>  Sascha
>
>
>  This patch adds gpiolib support for mpc5200 SOCs. I'm not sure
>  whether it's a good idea to make this optional via kconfig.
>  The gpt devices only support a single gpio. In the current of_gpio
>  implementation each chip consumes 32 GPIOs which leads to huge
>  gaps.
>
>  Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Looks pretty good.  You've saved me the need to go write a driver
myself.  Comments below, but I'll pull it into my tree and give it a
spin.

I don't see any mechanism for setting the open drain state of the pin.
 That will either need to be done by platform code or encoded into the
device tree.  Does the OF gpio infrastructure provide any callback to
the driver when something requests the pin?  That would seem to be the
ideal place to set the open drain state.

You'll also need to document the format of the gpio pin specifier for
these devices (ie. first cell is GPIO number, second cell is ????).

As for the wide spans caused by gpt gpios, it is probably okay for
now, but we can rework it to do something clever (like have a single
registration for all gpt gpios) at a later date.

Cheers,
g.

>
>  ---
>   arch/powerpc/platforms/52xx/Kconfig        |    6
>   arch/powerpc/platforms/52xx/Makefile       |    2
>   arch/powerpc/platforms/52xx/mpc52xx_gpio.c |  408 +++++++++++++++++++++++++++++
>   3 files changed, 416 insertions(+)
>
>  Index: arch/powerpc/platforms/52xx/mpc52xx_gpio.c
>  ===================================================================
>  --- /dev/null
>  +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
>  @@ -0,0 +1,408 @@
>  +/*
>  + * MPC52xx gpio driver
>  + *
>  + * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
>  + *
>  + * This program is free software; you can redistribute it and/or modify
>  + * it under the terms of the GNU General Public License version 2
>  + * as published by the Free Software Foundation.
>  + *
>  + * 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/of.h>
>  +#include <linux/kernel.h>
>  +#include <linux/of_gpio.h>
>  +#include <linux/io.h>
>  +#include <asm/of_platform.h>
>  +#include <asm/prom.h>
>  +#include <asm/gpio.h>
>  +#include <asm/mpc52xx.h>
>  +#include <sysdev/fsl_soc.h>
>  +
>  +static DEFINE_SPINLOCK(gpio_lock);
>  +
>  +/*
>  + * GPIO LIB API implementation for wakeup GPIOs.
>  + *
>  + * There's a maximum of 8 wakeup GPIOs. Which of these are available
>  + * for use depends on your board setup.
>  + *
>  + * 0 -> GPIO_WKUP_7
>  + * 1 -> GPIO_WKUP_6
>  + * 2 -> PSC6_1
>  + * 3 -> PSC6_0
>  + * 4 -> ETH_17
>  + * 5 -> PSC3_9
>  + * 6 -> PSC2_4
>  + * 7 -> PSC1_4
>  + *
>  + */
>  +static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
>  +       unsigned int ret;
>  +
>  +       ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
>  +
>  +       pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);

dev_dbg maybe?

>  +
>  +       return ret;
>  +}
>  +
>  +static void mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_8(&regs->wkup_dvo);
>  +       if (val)
>  +               tmp |= 1 << (7 - gpio);
>  +       else
>  +               tmp &= ~(1 << (7 - gpio));
>  +       out_8(&regs->wkup_dvo, tmp);

Rather than read/modify/write of the device register; the function
would probably be faster (one fewer barrier) if you used a shadow
register of the pin state and the critical region would be
shorter/simpler.  Also, while this device doesn't have the side
effects associated with shared input/output register, it might still
be good form to use a shadow register just for the sake of clarity.

>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +}
>  +
>  +static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_8(&regs->wkup_ddr);
>  +       tmp &= ~(1 << (7 - gpio));
>  +       out_8(&regs->wkup_ddr, tmp);
>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       return 0;
>  +}
>  +
>  +static int mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       /* First set initial value */
>  +       mpc52xx_wkup_gpio_set(gc, gpio, val);
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       /* Then set direction */
>  +       tmp = in_8(&regs->wkup_ddr);
>  +       tmp |= 1 << (7 - gpio);
>  +       out_8(&regs->wkup_ddr, tmp);
>  +
>  +       /* Finally enable the pin */
>  +       tmp = in_8(&regs->wkup_gpioe);
>  +       tmp |= 1 << (7 - gpio);
>  +       out_8(&regs->wkup_gpioe, tmp);

Do you want/need the cost of enabling the pin every time dir_out is
called?  Can it be done when the pin is requested instead?  Or by the
board firmware/platform code?  Some drivers (for example the i2c
bitbang driver for the clock signal; see i2c-gpio.c) change the state
by changing the direction of the pin.

>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +
>  +       return 0;
>  +}
>  +
>  +static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
>  +                                    const struct of_device_id *match)
>  +{
>  +       struct of_mm_gpio_chip *mmchip;
>  +       struct of_gpio_chip *chip;
>  +
>  +       mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
>  +       if (!mmchip)
>  +               return -ENOMEM;
>  +
>  +       chip = &mmchip->of_gc;
>  +
>  +       chip->gpio_cells          = 2;
>  +       chip->gc.ngpio            = 8;
>  +       chip->gc.direction_input  = mpc52xx_wkup_gpio_dir_in;
>  +       chip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
>  +       chip->gc.get              = mpc52xx_wkup_gpio_get;
>  +       chip->gc.set              = mpc52xx_wkup_gpio_set;
>  +
>  +       return of_mm_gpiochip_add(ofdev->node, mmchip);
>  +}
>  +
>  +static int mpc52xx_gpiochip_remove(struct of_device *ofdev)
>  +{
>  +       return -EBUSY;
>  +}
>  +
>  +static struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
>  +       {
>  +               .compatible = "fsl,mpc5200-gpio-wkup",
>  +       },
>  +       {}
>  +};
>  +
>  +static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = {
>  +       .name = "gpio_wkup",
>  +       .match_table = mpc52xx_wkup_gpiochip_match,
>  +       .probe = mpc52xx_wkup_gpiochip_probe,
>  +       .remove = mpc52xx_gpiochip_remove,
>  +};
>  +
>  +/*
>  + * GPIO LIB API implementation for simple GPIOs
>  + *
>  + * There's a maximum of 32 simple GPIOs. Which of these are available
>  + * for use depends on your board setup.
>  + * The numbering reflects the bit numbering in the port registers:
>  + *
>  + *  0..1  > reserved
>  + *  2..3  > IRDA
>  + *  4..7  > ETHR
>  + *  8..11 > reserved
>  + * 12..15 > USB
>  + * 16..17 > reserved
>  + * 18..23 > PSC3
>  + * 24..27 > PSC2
>  + * 28..31 > PSC1
>  + */
>  +static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
>  +       unsigned int ret;
>  +
>  +       ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
>  +
>  +       return ret;
>  +}
>  +
>  +static void mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_be32(&regs->simple_dvo);
>  +       if (val)
>  +               tmp |= 1 << (31 - gpio);
>  +       else
>  +               tmp &= ~(1 << (31 - gpio));
>  +       out_be32(&regs->simple_dvo, tmp);
>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +}
>  +
>  +static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_be32(&regs->simple_ddr);
>  +       tmp &= ~(1 << (31 - gpio));
>  +       out_be32(&regs->simple_ddr, tmp);
>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       return 0;
>  +}
>  +
>  +static int mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       /* First set initial value */
>  +       mpc52xx_simple_gpio_set(gc, gpio, val);
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       /* Then set direction */
>  +       tmp = in_be32(&regs->simple_ddr);
>  +       tmp |= 1 << (31 - gpio);
>  +       out_be32(&regs->simple_ddr, tmp);
>  +
>  +       /* Finally enable the pin */
>  +       tmp = in_be32(&regs->simple_gpioe);
>  +       tmp |= 1 << (31 - gpio);
>  +       out_be32(&regs->simple_gpioe, tmp);

ditto here

>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +
>  +       return 0;
>  +}
>  +
>  +static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
>  +                                    const struct of_device_id *match)
>  +{
>  +       struct of_mm_gpio_chip *mmchip;
>  +       struct of_gpio_chip *chip;
>  +
>  +       mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
>  +       if (!mmchip)
>  +               return -ENOMEM;
>  +
>  +       chip = &mmchip->of_gc;
>  +
>  +       chip->gpio_cells          = 2;
>  +       chip->gc.ngpio            = 32;
>  +       chip->gc.direction_input  = mpc52xx_simple_gpio_dir_in;
>  +       chip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
>  +       chip->gc.get              = mpc52xx_simple_gpio_get;
>  +       chip->gc.set              = mpc52xx_simple_gpio_set;
>  +
>  +       return of_mm_gpiochip_add(ofdev->node, mmchip);
>  +}
>  +
>  +static struct of_device_id mpc52xx_simple_gpiochip_match[] = {
>  +       {
>  +               .compatible = "fsl,mpc5200-gpio",
>  +       },
>  +       {}
>  +};
>  +
>  +static struct of_platform_driver mpc52xx_simple_gpiochip_driver = {
>  +       .name = "gpio",
>  +       .match_table = mpc52xx_simple_gpiochip_match,
>  +       .probe = mpc52xx_simple_gpiochip_probe,
>  +       .remove = mpc52xx_gpiochip_remove,
>  +};
>  +
>  +/*
>  + * GPIO LIB API implementation for gpt GPIOs.
>  + *
>  + * Each gpt only has a single GPIO.
>  + */
>  +static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
>  +       unsigned int ret;
>  +
>  +       return (in_be32(&regs->status) & (1 << (31 - 23))) ? 1 : 0;
>  +
>  +       return ret;
>  +}
>  +
>  +static void mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
>  +
>  +       if (val)
>  +               out_be32(&regs->mode, 0x34);
>  +       else
>  +               out_be32(&regs->mode, 0x24);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +}
>  +
>  +static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpt *regs = mm_gc->regs;
>  +
>  +       out_be32(&regs->mode, 0x04);
>  +
>  +       return 0;
>  +}
>  +
>  +static int mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       mpc52xx_gpt_gpio_set(gc, gpio, val);
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +
>  +       return 0;
>  +}
>  +
>  +static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev,
>  +                                    const struct of_device_id *match)
>  +{
>  +       struct of_mm_gpio_chip *mmchip;
>  +       struct of_gpio_chip *chip;
>  +
>  +       mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
>  +       if (!mmchip)
>  +               return -ENOMEM;
>  +
>  +       chip = &mmchip->of_gc;
>  +
>  +       chip->gpio_cells          = 2;
>  +       chip->gc.ngpio            = 1;
>  +       chip->gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
>  +       chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
>  +       chip->gc.get              = mpc52xx_gpt_gpio_get;
>  +       chip->gc.set              = mpc52xx_gpt_gpio_set;
>  +
>  +       return of_mm_gpiochip_add(ofdev->node, mmchip);
>  +}
>  +
>  +static struct of_device_id mpc52xx_gpt_gpiochip_match[] = {
>  +       {
>  +               .compatible = "fsl,mpc5200-gpt-gpio",
>  +       },
>  +       {}
>  +};
>  +
>  +static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = {
>  +       .name = "gpio_gpt",
>  +       .match_table = mpc52xx_gpt_gpiochip_match,
>  +       .probe = mpc52xx_gpt_gpiochip_probe,
>  +       .remove = mpc52xx_gpiochip_remove,
>  +};
>  +
>  +static int __init mpc52xx_gpio_init(void)
>  +{
>  +       if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
>  +               printk(KERN_ERR "Unable to register wakeup GPIO driver\n");
>  +
>  +       if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
>  +               printk(KERN_ERR "Unable to register simple GPIO driver\n");
>  +
>  +       if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver))
>  +               printk(KERN_ERR "Unable to register gpt GPIO driver\n");
>  +
>  +       return 0;
>  +}
>  +
>  +
>  +/* Make sure we get initialised before anyone else tries to use us */
>  +subsys_initcall(mpc52xx_gpio_init);
>  +
>  +/* No exit call at the moment as we cannot unregister of gpio chips */
>  +
>  +MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
>  +MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
>  +MODULE_LICENSE("GPL v2");
>  +
>  Index: arch/powerpc/platforms/52xx/Kconfig
>  ===================================================================
>  --- a/arch/powerpc/platforms/52xx/Kconfig.orig
>  +++ b/arch/powerpc/platforms/52xx/Kconfig
>  @@ -44,3 +44,9 @@ config PPC_MPC5200_BUGFIX
>
>           It is safe to say 'Y' here
>
>  +config PPC_MPC5200_GPIO
>  +       bool "MPC5200 GPIO support"
>  +       depends on PPC_MPC52xx
>  +       select HAVE_GPIO_LIB
>  +       help
>  +         Enable gpiolib support for mpc5200 based boards
>  Index: arch/powerpc/platforms/52xx/Makefile
>  ===================================================================
>  --- a/arch/powerpc/platforms/52xx/Makefile.orig
>  +++ b/arch/powerpc/platforms/52xx/Makefile
>  @@ -14,3 +14,5 @@ obj-$(CONFIG_PM)              += mpc52xx_sleep.o mpc
>   ifeq ($(CONFIG_PPC_LITE5200),y)
>         obj-$(CONFIG_PM)        += lite5200_sleep.o lite5200_pm.o
>   endif
>  +
>  +obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o
>  \ No newline at end of file
>
>  --
>  Pengutronix e.K. - Linux Solutions for Science and Industry
>  -----------------------------------------------------------
>  Kontakt-Informationen finden Sie im Header dieser Mail oder
>  auf der Webseite -> http://www.pengutronix.de/impressum/ <-
>  _______________________________________________
>  Linuxppc-dev mailing list
>  Linuxppc-dev@ozlabs.org
>  https://ozlabs.org/mailman/listinfo/linuxppc-dev
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: [PATCH] add gpiolib support for mpc5200
From: Grant Likely @ 2008-04-24 19:11 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: linuxppc-dev
In-Reply-To: <20080424153659.GJ6692@pengutronix.de>

On Thu, Apr 24, 2008 at 9:36 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> Hi all,
>
>  Feel free to comment on this.
>
>  Sascha
>
>
>  This patch adds gpiolib support for mpc5200 SOCs. I'm not sure
>  whether it's a good idea to make this optional via kconfig.
>  The gpt devices only support a single gpio. In the current of_gpio
>  implementation each chip consumes 32 GPIOs which leads to huge
>  gaps.
>
>  Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Looks pretty good.  You've saved me the need to go write a driver
myself.  Comments below, but I'll pull it into my tree and give it a
spin.

I don't see any mechanism for setting the open drain state of the pin.
 That will either need to be done by platform code or encoded into the
device tree.  Does the OF gpio infrastructure provide any callback to
the driver when something requests the pin?  That would seem to be the
ideal place to set the open drain state.

You'll also need to document the format of the gpio pin specifier for
these devices (ie. first cell is GPIO number, second cell is ????).

As for the wide spans caused by gpt gpios, it is probably okay for
now, but we can rework it to do something clever (like have a single
registration for all gpt gpios) at a later date.

Cheers,
g.

>
>  ---
>   arch/powerpc/platforms/52xx/Kconfig        |    6
>   arch/powerpc/platforms/52xx/Makefile       |    2
>   arch/powerpc/platforms/52xx/mpc52xx_gpio.c |  408 +++++++++++++++++++++++++++++
>   3 files changed, 416 insertions(+)
>
>  Index: arch/powerpc/platforms/52xx/mpc52xx_gpio.c
>  ===================================================================
>  --- /dev/null
>  +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpio.c
>  @@ -0,0 +1,408 @@
>  +/*
>  + * MPC52xx gpio driver
>  + *
>  + * Copyright (c) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
>  + *
>  + * This program is free software; you can redistribute it and/or modify
>  + * it under the terms of the GNU General Public License version 2
>  + * as published by the Free Software Foundation.
>  + *
>  + * 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/of.h>
>  +#include <linux/kernel.h>
>  +#include <linux/of_gpio.h>
>  +#include <linux/io.h>
>  +#include <asm/of_platform.h>
>  +#include <asm/prom.h>
>  +#include <asm/gpio.h>
>  +#include <asm/mpc52xx.h>
>  +#include <sysdev/fsl_soc.h>
>  +
>  +static DEFINE_SPINLOCK(gpio_lock);
>  +
>  +/*
>  + * GPIO LIB API implementation for wakeup GPIOs.
>  + *
>  + * There's a maximum of 8 wakeup GPIOs. Which of these are available
>  + * for use depends on your board setup.
>  + *
>  + * 0 -> GPIO_WKUP_7
>  + * 1 -> GPIO_WKUP_6
>  + * 2 -> PSC6_1
>  + * 3 -> PSC6_0
>  + * 4 -> ETH_17
>  + * 5 -> PSC3_9
>  + * 6 -> PSC2_4
>  + * 7 -> PSC1_4
>  + *
>  + */
>  +static int mpc52xx_wkup_gpio_get(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
>  +       unsigned int ret;
>  +
>  +       ret = (in_8(&regs->wkup_ival) >> (7 - gpio)) & 1;
>  +
>  +       pr_debug("%s: gpio: %d ret: %d\n", __func__, gpio, ret);

dev_dbg maybe?

>  +
>  +       return ret;
>  +}
>  +
>  +static void mpc52xx_wkup_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_8(&regs->wkup_dvo);
>  +       if (val)
>  +               tmp |= 1 << (7 - gpio);
>  +       else
>  +               tmp &= ~(1 << (7 - gpio));
>  +       out_8(&regs->wkup_dvo, tmp);

Rather than read/modify/write of the device register; the function
would probably be faster (one fewer barrier) if you used a shadow
register of the pin state and the critical region would be
shorter/simpler.  Also, while this device doesn't have the side
effects associated with shared input/output register, it might still
be good form to use a shadow register just for the sake of clarity.

>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +}
>  +
>  +static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_8(&regs->wkup_ddr);
>  +       tmp &= ~(1 << (7 - gpio));
>  +       out_8(&regs->wkup_ddr, tmp);
>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       return 0;
>  +}
>  +
>  +static int mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio_wkup *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       /* First set initial value */
>  +       mpc52xx_wkup_gpio_set(gc, gpio, val);
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       /* Then set direction */
>  +       tmp = in_8(&regs->wkup_ddr);
>  +       tmp |= 1 << (7 - gpio);
>  +       out_8(&regs->wkup_ddr, tmp);
>  +
>  +       /* Finally enable the pin */
>  +       tmp = in_8(&regs->wkup_gpioe);
>  +       tmp |= 1 << (7 - gpio);
>  +       out_8(&regs->wkup_gpioe, tmp);

Do you want/need the cost of enabling the pin every time dir_out is
called?  Can it be done when the pin is requested instead?  Or by the
board firmware/platform code?  Some drivers (for example the i2c
bitbang driver for the clock signal; see i2c-gpio.c) change the state
by changing the direction of the pin.

>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +
>  +       return 0;
>  +}
>  +
>  +static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev,
>  +                                    const struct of_device_id *match)
>  +{
>  +       struct of_mm_gpio_chip *mmchip;
>  +       struct of_gpio_chip *chip;
>  +
>  +       mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
>  +       if (!mmchip)
>  +               return -ENOMEM;
>  +
>  +       chip = &mmchip->of_gc;
>  +
>  +       chip->gpio_cells          = 2;
>  +       chip->gc.ngpio            = 8;
>  +       chip->gc.direction_input  = mpc52xx_wkup_gpio_dir_in;
>  +       chip->gc.direction_output = mpc52xx_wkup_gpio_dir_out;
>  +       chip->gc.get              = mpc52xx_wkup_gpio_get;
>  +       chip->gc.set              = mpc52xx_wkup_gpio_set;
>  +
>  +       return of_mm_gpiochip_add(ofdev->node, mmchip);
>  +}
>  +
>  +static int mpc52xx_gpiochip_remove(struct of_device *ofdev)
>  +{
>  +       return -EBUSY;
>  +}
>  +
>  +static struct of_device_id mpc52xx_wkup_gpiochip_match[] = {
>  +       {
>  +               .compatible = "fsl,mpc5200-gpio-wkup",
>  +       },
>  +       {}
>  +};
>  +
>  +static struct of_platform_driver mpc52xx_wkup_gpiochip_driver = {
>  +       .name = "gpio_wkup",
>  +       .match_table = mpc52xx_wkup_gpiochip_match,
>  +       .probe = mpc52xx_wkup_gpiochip_probe,
>  +       .remove = mpc52xx_gpiochip_remove,
>  +};
>  +
>  +/*
>  + * GPIO LIB API implementation for simple GPIOs
>  + *
>  + * There's a maximum of 32 simple GPIOs. Which of these are available
>  + * for use depends on your board setup.
>  + * The numbering reflects the bit numbering in the port registers:
>  + *
>  + *  0..1  > reserved
>  + *  2..3  > IRDA
>  + *  4..7  > ETHR
>  + *  8..11 > reserved
>  + * 12..15 > USB
>  + * 16..17 > reserved
>  + * 18..23 > PSC3
>  + * 24..27 > PSC2
>  + * 28..31 > PSC1
>  + */
>  +static int mpc52xx_simple_gpio_get(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
>  +       unsigned int ret;
>  +
>  +       ret = (in_be32(&regs->simple_ival) >> (31 - gpio)) & 1;
>  +
>  +       return ret;
>  +}
>  +
>  +static void mpc52xx_simple_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio __iomem *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_be32(&regs->simple_dvo);
>  +       if (val)
>  +               tmp |= 1 << (31 - gpio);
>  +       else
>  +               tmp &= ~(1 << (31 - gpio));
>  +       out_be32(&regs->simple_dvo, tmp);
>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +}
>  +
>  +static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       tmp = in_be32(&regs->simple_ddr);
>  +       tmp &= ~(1 << (31 - gpio));
>  +       out_be32(&regs->simple_ddr, tmp);
>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       return 0;
>  +}
>  +
>  +static int mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpio *regs = mm_gc->regs;
>  +       unsigned int tmp;
>  +       unsigned long flags;
>  +
>  +       /* First set initial value */
>  +       mpc52xx_simple_gpio_set(gc, gpio, val);
>  +
>  +       spin_lock_irqsave(&gpio_lock, flags);
>  +
>  +       /* Then set direction */
>  +       tmp = in_be32(&regs->simple_ddr);
>  +       tmp |= 1 << (31 - gpio);
>  +       out_be32(&regs->simple_ddr, tmp);
>  +
>  +       /* Finally enable the pin */
>  +       tmp = in_be32(&regs->simple_gpioe);
>  +       tmp |= 1 << (31 - gpio);
>  +       out_be32(&regs->simple_gpioe, tmp);

ditto here

>  +
>  +       spin_unlock_irqrestore(&gpio_lock, flags);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +
>  +       return 0;
>  +}
>  +
>  +static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev,
>  +                                    const struct of_device_id *match)
>  +{
>  +       struct of_mm_gpio_chip *mmchip;
>  +       struct of_gpio_chip *chip;
>  +
>  +       mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
>  +       if (!mmchip)
>  +               return -ENOMEM;
>  +
>  +       chip = &mmchip->of_gc;
>  +
>  +       chip->gpio_cells          = 2;
>  +       chip->gc.ngpio            = 32;
>  +       chip->gc.direction_input  = mpc52xx_simple_gpio_dir_in;
>  +       chip->gc.direction_output = mpc52xx_simple_gpio_dir_out;
>  +       chip->gc.get              = mpc52xx_simple_gpio_get;
>  +       chip->gc.set              = mpc52xx_simple_gpio_set;
>  +
>  +       return of_mm_gpiochip_add(ofdev->node, mmchip);
>  +}
>  +
>  +static struct of_device_id mpc52xx_simple_gpiochip_match[] = {
>  +       {
>  +               .compatible = "fsl,mpc5200-gpio",
>  +       },
>  +       {}
>  +};
>  +
>  +static struct of_platform_driver mpc52xx_simple_gpiochip_driver = {
>  +       .name = "gpio",
>  +       .match_table = mpc52xx_simple_gpiochip_match,
>  +       .probe = mpc52xx_simple_gpiochip_probe,
>  +       .remove = mpc52xx_gpiochip_remove,
>  +};
>  +
>  +/*
>  + * GPIO LIB API implementation for gpt GPIOs.
>  + *
>  + * Each gpt only has a single GPIO.
>  + */
>  +static int mpc52xx_gpt_gpio_get(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
>  +       unsigned int ret;
>  +
>  +       return (in_be32(&regs->status) & (1 << (31 - 23))) ? 1 : 0;
>  +
>  +       return ret;
>  +}
>  +
>  +static void mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpt __iomem *regs = mm_gc->regs;
>  +
>  +       if (val)
>  +               out_be32(&regs->mode, 0x34);
>  +       else
>  +               out_be32(&regs->mode, 0x24);
>  +
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +}
>  +
>  +static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
>  +{
>  +       struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc);
>  +       struct mpc52xx_gpt *regs = mm_gc->regs;
>  +
>  +       out_be32(&regs->mode, 0x04);
>  +
>  +       return 0;
>  +}
>  +
>  +static int mpc52xx_gpt_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
>  +{
>  +       mpc52xx_gpt_gpio_set(gc, gpio, val);
>  +       pr_debug("%s: gpio: %d val: %d\n", __func__, gpio, val);
>  +
>  +       return 0;
>  +}
>  +
>  +static int __devinit mpc52xx_gpt_gpiochip_probe(struct of_device *ofdev,
>  +                                    const struct of_device_id *match)
>  +{
>  +       struct of_mm_gpio_chip *mmchip;
>  +       struct of_gpio_chip *chip;
>  +
>  +       mmchip = kzalloc(sizeof(*mmchip), GFP_KERNEL);
>  +       if (!mmchip)
>  +               return -ENOMEM;
>  +
>  +       chip = &mmchip->of_gc;
>  +
>  +       chip->gpio_cells          = 2;
>  +       chip->gc.ngpio            = 1;
>  +       chip->gc.direction_input  = mpc52xx_gpt_gpio_dir_in;
>  +       chip->gc.direction_output = mpc52xx_gpt_gpio_dir_out;
>  +       chip->gc.get              = mpc52xx_gpt_gpio_get;
>  +       chip->gc.set              = mpc52xx_gpt_gpio_set;
>  +
>  +       return of_mm_gpiochip_add(ofdev->node, mmchip);
>  +}
>  +
>  +static struct of_device_id mpc52xx_gpt_gpiochip_match[] = {
>  +       {
>  +               .compatible = "fsl,mpc5200-gpt-gpio",
>  +       },
>  +       {}
>  +};
>  +
>  +static struct of_platform_driver mpc52xx_gpt_gpiochip_driver = {
>  +       .name = "gpio_gpt",
>  +       .match_table = mpc52xx_gpt_gpiochip_match,
>  +       .probe = mpc52xx_gpt_gpiochip_probe,
>  +       .remove = mpc52xx_gpiochip_remove,
>  +};
>  +
>  +static int __init mpc52xx_gpio_init(void)
>  +{
>  +       if (of_register_platform_driver(&mpc52xx_wkup_gpiochip_driver))
>  +               printk(KERN_ERR "Unable to register wakeup GPIO driver\n");
>  +
>  +       if (of_register_platform_driver(&mpc52xx_simple_gpiochip_driver))
>  +               printk(KERN_ERR "Unable to register simple GPIO driver\n");
>  +
>  +       if (of_register_platform_driver(&mpc52xx_gpt_gpiochip_driver))
>  +               printk(KERN_ERR "Unable to register gpt GPIO driver\n");
>  +
>  +       return 0;
>  +}
>  +
>  +
>  +/* Make sure we get initialised before anyone else tries to use us */
>  +subsys_initcall(mpc52xx_gpio_init);
>  +
>  +/* No exit call at the moment as we cannot unregister of gpio chips */
>  +
>  +MODULE_DESCRIPTION("Freescale MPC52xx gpio driver");
>  +MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de");
>  +MODULE_LICENSE("GPL v2");
>  +
>  Index: arch/powerpc/platforms/52xx/Kconfig
>  ===================================================================
>  --- a/arch/powerpc/platforms/52xx/Kconfig.orig
>  +++ b/arch/powerpc/platforms/52xx/Kconfig
>  @@ -44,3 +44,9 @@ config PPC_MPC5200_BUGFIX
>
>           It is safe to say 'Y' here
>
>  +config PPC_MPC5200_GPIO
>  +       bool "MPC5200 GPIO support"
>  +       depends on PPC_MPC52xx
>  +       select HAVE_GPIO_LIB
>  +       help
>  +         Enable gpiolib support for mpc5200 based boards
>  Index: arch/powerpc/platforms/52xx/Makefile
>  ===================================================================
>  --- a/arch/powerpc/platforms/52xx/Makefile.orig
>  +++ b/arch/powerpc/platforms/52xx/Makefile
>  @@ -14,3 +14,5 @@ obj-$(CONFIG_PM)              += mpc52xx_sleep.o mpc
>   ifeq ($(CONFIG_PPC_LITE5200),y)
>         obj-$(CONFIG_PM)        += lite5200_sleep.o lite5200_pm.o
>   endif
>  +
>  +obj-$(CONFIG_PPC_MPC5200_GPIO) += mpc52xx_gpio.o
>  \ No newline at end of file
>
>  --
>  Pengutronix e.K. - Linux Solutions for Science and Industry
>  -----------------------------------------------------------
>  Kontakt-Informationen finden Sie im Header dieser Mail oder
>  auf der Webseite -> http://www.pengutronix.de/impressum/ <-
>  _______________________________________________
>  Linuxppc-dev mailing list
>  Linuxppc-dev@ozlabs.org
>  https://ozlabs.org/mailman/listinfo/linuxppc-dev
>



-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: [Cbe-oss-dev] [PATCH] Reworked Cell OProfile: SPU mutex lock fix
From: Maynard Johnson @ 2008-04-24 19:46 UTC (permalink / raw)
  To: Carl Love
  Cc: linuxppc-dev, oprofile-list, cbe-oss-dev, Arnd Bergmann,
	linux-kernel
In-Reply-To: <1208965811.6444.91.camel@carll-linux-desktop>

Carl Love wrote:
> This is a reworked patch to fix the SPU data storage.  Currently, the 
> SPU escape sequences and program counter data is being added directly 
> into the kernel buffer without holding the buffer_mutex lock.  This 
> patch changes how the data is stored.  A new function,
> oprofile_add_value, is added into the oprofile driver to allow adding
> generic data to the per cpu buffers.  This enables a series of calls
> to the oprofile_add_value to enter the needed SPU escape sequences 
> and SPU program data into the kernel buffer via the per cpu buffers
> without any additional processing. The oprofile_add_value function is
> generic so it could be used by other architecures as well provided
> the needed postprocessing was added to opreport.
>
> Finally, this patch backs out the changes previously added to the 
> oprofile generic code for handling the architecture specific 
> ops.sync_start and ops.sync_stop that allowed the architecture
> to skip the per CPU buffer creation.
>   
Looks good except for the few minor things noted below . . .

-Maynard
> Signed-off-by: Carl Love <carll@us.ibm.com>
>
> Index: Cell_kernel_4_15_2008/arch/powerpc/oprofile/cell/pr_util.h
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/arch/powerpc/oprofile/cell/pr_util.h
> +++ Cell_kernel_4_15_2008/arch/powerpc/oprofile/cell/pr_util.h
> @@ -20,11 +20,6 @@
>  #include <asm/cell-regs.h>
>  #include <asm/spu.h>
>
> -/* Defines used for sync_start */
> -#define SKIP_GENERIC_SYNC 0
> -#define SYNC_START_ERROR -1
> -#define DO_GENERIC_SYNC 1
> -
>  struct spu_overlay_info {	/* map of sections within an SPU overlay */
>  	unsigned int vma;	/* SPU virtual memory address from elf */
>  	unsigned int size;	/* size of section from elf */
> @@ -85,7 +80,7 @@ void stop_spu_profiling(void);
>  int spu_sync_start(void);
>
>  /* remove the hooks */
> -int spu_sync_stop(void);
> +void spu_sync_stop(void);
>
>  /* Record SPU program counter samples to the oprofile event buffer. */
>  void spu_sync_buffer(int spu_num, unsigned int *samples,
> Index: Cell_kernel_4_15_2008/arch/powerpc/oprofile/cell/spu_task_sync.c
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/arch/powerpc/oprofile/cell/spu_task_sync.c
> +++ Cell_kernel_4_15_2008/arch/powerpc/oprofile/cell/spu_task_sync.c
> @@ -31,11 +31,13 @@
>
>  #define RELEASE_ALL 9999
>
> -static DEFINE_SPINLOCK(buffer_lock);
> +static DEFINE_SPINLOCK(add_value_lock);
>  static DEFINE_SPINLOCK(cache_lock);
>  static int num_spu_nodes;
> +int per_cpu_buffers_exist=0;
>   
The per_cpu_buffers_exist variable is not used for anything useful -- a 
vestige of something done earlier, I think.
>  int spu_prof_num_nodes;
>  int last_guard_val[MAX_NUMNODES * 8];
> +static int spu_ctx_sw_seen[MAX_NUMNODES * 8];
>   
[snip]
>  int spu_sync_start(void)
>  {
>  	int k;
> -	int ret = SKIP_GENERIC_SYNC;
> +	int ret = 0;
>  	int register_ret;
> -	unsigned long flags = 0;
> +	int cpu;
>
>  	spu_prof_num_nodes = number_of_online_nodes();
>  	num_spu_nodes = spu_prof_num_nodes * 8;
>
> -	spin_lock_irqsave(&buffer_lock, flags);
> -	add_event_entry(ESCAPE_CODE);
> -	add_event_entry(SPU_PROFILING_CODE);
> -	add_event_entry(num_spu_nodes);
> -	spin_unlock_irqrestore(&buffer_lock, flags);
> +	/* At this point, the CPU buffers have been generated so
>   
Suggest you change "generated" to "allocated" for clarity.
> +	 * writes to the per CPU buffers can occur.  Need to
> +	 * set the flag that the buffers exist before registering for
> +	 * the SPU context switches or the routine to process the
> +	 * context switches will not write context switch information.
> +	 */
> +	per_cpu_buffers_exist = 1;
>   
delete
> +
> +	/* The SPU_PROFILING_CODE escape sequence must proceed
> +	 * the SPU context switch info.
> +	 */
> +	for_each_online_cpu(cpu) {
> +		oprofile_add_value(ESCAPE_CODE, cpu);
> +		oprofile_add_value(SPU_PROFILING_CODE, cpu);
> +		oprofile_add_value((unsigned long int)
> +					    num_spu_nodes, cpu);
> +	}
>
>  	/* Register for SPU events  */
>  	register_ret = spu_switch_event_register(&spu_active);
>  	if (register_ret) {
> -		ret = SYNC_START_ERROR;
> +		/* Stop the profile_spus() function from trying
> +		 * to store samples into the per CPU buffer.  The
> +		 * buffer will not be there.
> +		 */
> +		per_cpu_buffers_exist = 0;
>   
delete
> +		ret = -1;
>  		goto out;
>  	}
>
> -	for (k = 0; k < (MAX_NUMNODES * 8); k++)
> +	for (k = 0; k < (MAX_NUMNODES * 8); k++) {
>  		last_guard_val[k] = 0;
> +		spu_ctx_sw_seen[k] = 0;
> +	}
>  	pr_debug("spu_sync_start -- running.\n");
>  out:
>  	return ret;
> +
>  }
>
>  /* Record SPU program counter samples to the oprofile event buffer. */
> @@ -432,7 +460,7 @@ void spu_sync_buffer(int spu_num, unsign
>
>  	map = c_info->map;
>  	the_spu = c_info->the_spu;
> -	spin_lock(&buffer_lock);
> +	spin_lock(&add_value_lock);
>  	for (i = 0; i < num_samples; i++) {
>  		unsigned int sample = *(samples+i);
>  		int grd_val = 0;
> @@ -452,15 +480,22 @@ void spu_sync_buffer(int spu_num, unsign
>  			break;
>  		}
>
> -		add_event_entry(file_offset | spu_num_shifted);
>   
In our initial Cell SPU oprofile support submission to the kernel, we 
had added a prototype for add_event_entry to include/linux/oprofile.h .  
Now that this patch has replaced all uses of add_event_entry with the 
new oprofile_add_value function, we should remove the add_event_entry 
prototype from the header file -- especially since we were 
misusing/abusing it anyway (not grabbing the buffer_mutex before calling).
> +		/* We must ensure that the SPU context switch has been written
> +		 * out before samples for the SPU.  Otherwise, the SPU context
> +		 * information is not available and the postprocessing of the
> +		 * SPU PC will fail with no available anonymous map information.
> +		 */
> +		if (spu_ctx_sw_seen[spu_num])
> +			oprofile_add_value((file_offset | spu_num_shifted),
> +						    (spu_num >> 2));
>   
Carl, you and I had discussed earlier in a phone call how the above use 
of oprofile_add_value results in the CPU buffer space being used up 
twice as fast as normal (because of the implementation of 
oprofile_add_value writing a special ESCAPE code followed by the actual 
data).  Do we need to do something (either in userspace or kernel 
driver) to increase CPU buffer size?  Maybe on Cell BE, the default CPU 
buffer size should be doubled, but I don't think that could easily be 
done in the kernel driver.  Probably easier to add in the userspace tools.
>  	}
> -	spin_unlock(&buffer_lock);
> +	spin_unlock(&add_value_lock);
>  out:
>  	spin_unlock_irqrestore(&cache_lock, flags);
>  }
>
>
> -int spu_sync_stop(void)
> +void spu_sync_stop(void)
>  {
>  	unsigned long flags = 0;
>  	int ret = spu_switch_event_unregister(&spu_active);
>   
The variable 'ret' isn't needed anymore.  Maybe add a comment that we're 
intentionally ignoring return values from spu_switch_event_unregister 
and release_cached_info since we want/need generic sync_stop to run even 
if spu_sync_stop has a problem.
> @@ -475,8 +510,9 @@ int spu_sync_stop(void)
>  	ret = release_cached_info(RELEASE_ALL);
>  	spin_unlock_irqrestore(&cache_lock, flags);
>  out:
> +	per_cpu_buffers_exist = 0;
>   
delete
>  	pr_debug("spu_sync_stop -- done.\n");
> -	return ret;
> +	return;
>  }
>
>
> Index: Cell_kernel_4_15_2008/arch/powerpc/oprofile/op_model_cell.c
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/arch/powerpc/oprofile/op_model_cell.c
> +++ Cell_kernel_4_15_2008/arch/powerpc/oprofile/op_model_cell.c
> @@ -1191,15 +1191,15 @@ static int cell_sync_start(void)
>  	if (spu_cycle_reset)
>  		return spu_sync_start();
>  	else
> -		return DO_GENERIC_SYNC;
> +		return 0;
>  }
>
> -static int cell_sync_stop(void)
> +static void cell_sync_stop(void)
>  {
>  	if (spu_cycle_reset)
> -		return spu_sync_stop();
> -	else
> -		return 1;
> +		spu_sync_stop();
> +
> +	return;
>  }
>
>  struct op_powerpc_model op_model_cell = {
> Index: Cell_kernel_4_15_2008/drivers/oprofile/buffer_sync.c
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/drivers/oprofile/buffer_sync.c
> +++ Cell_kernel_4_15_2008/drivers/oprofile/buffer_sync.c
> @@ -521,6 +521,20 @@ void sync_buffer(int cpu)
>  			} else if (s->event == CPU_TRACE_BEGIN) {
>  				state = sb_bt_start;
>  				add_trace_begin();
> +			} else if (s->event == VALUE_HEADER_ID) {
> +				/* The next event contains a value
> +				 * to enter directly into the event buffer.
> +				 */
> +				increment_tail(cpu_buf);
> +				i++;  /* one less entry in buffer to process */
> +
> +				s = &cpu_buf->buffer[cpu_buf->tail_pos];
> +
> +				if (is_code(s->eip))
>   
This check seems sort of superfluous to me, but if you really want to 
keep it, make it an 'if (unlikely()) ' type of check.
> +					add_event_entry(s->event);
> +				else
> +					printk("KERN_ERR Oprofile per CPU" \
> +					       "buffer sequence error.\n");
>  			} else {
>  				struct mm_struct * oldmm = mm;
>
> Index: Cell_kernel_4_15_2008/drivers/oprofile/cpu_buffer.c
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/drivers/oprofile/cpu_buffer.c
> +++ Cell_kernel_4_15_2008/drivers/oprofile/cpu_buffer.c
> @@ -224,6 +224,35 @@ static void oprofile_end_trace(struct op
>  	cpu_buf->tracing = 0;
>  }
>
> +/*
> + * Add a value to the per CPU buffer.  The value is passed from the per CPU
> + * buffer to the kernel buffer with no additional processing.  The assumption
> + * is any processing of the value will be done in the postprocessor.  This
> + * function should only be used for special architecture specific data.
> + * Currently only used by the CELL processor.
> + *
> + * The first enty in the per cpu buffer consists of the escape code and
>   
"entry"
> + * the VALUE_HEADER_ID value.  The next entry consists of an escape code
> + * with the value to store.  The syn_buffer routine takes the value from
> + * the second entry and put it into the kernel buffer.
> + */
> +void oprofile_add_value(unsigned long value, int cpu) {
> +	struct oprofile_cpu_buffer * cpu_buf = &cpu_buffer[cpu];
> +
> +	/* Enter a sequence of two evnets.  The first event says the
>   
"events"
> +	 * next event contains a value that is to be put directly into the
> +	 * event buffer.
> +	 */
> +
> +	if (nr_available_slots(cpu_buf) < 3) {
> +		cpu_buf->sample_lost_overflow++;
> +		return;
> +	}
> +
> +	add_sample(cpu_buf, ESCAPE_CODE, VALUE_HEADER_ID);
> +	add_sample(cpu_buf, ESCAPE_CODE, value);
> +}
> +
>  void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
>  				unsigned long event, int is_kernel)
>  {
> Index: Cell_kernel_4_15_2008/drivers/oprofile/cpu_buffer.h
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/drivers/oprofile/cpu_buffer.h
> +++ Cell_kernel_4_15_2008/drivers/oprofile/cpu_buffer.h
> @@ -54,5 +54,6 @@ void cpu_buffer_reset(struct oprofile_cp
>  /* transient events for the CPU buffer -> event buffer */
>  #define CPU_IS_KERNEL 1
>  #define CPU_TRACE_BEGIN 2
> +#define VALUE_HEADER_ID 3
>
>  #endif /* OPROFILE_CPU_BUFFER_H */
> Index: Cell_kernel_4_15_2008/drivers/oprofile/oprof.c
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/drivers/oprofile/oprof.c
> +++ Cell_kernel_4_15_2008/drivers/oprofile/oprof.c
> @@ -53,24 +53,13 @@ int oprofile_setup(void)
>  	 * us missing task deaths and eventually oopsing
>  	 * when trying to process the event buffer.
>  	 */
> -	if (oprofile_ops.sync_start) {
> -		int sync_ret = oprofile_ops.sync_start();
> -		switch (sync_ret) {
> -		case 0:
> -			goto post_sync;
> -		case 1:
> -			goto do_generic;
> -		case -1:
> -			goto out3;
> -		default:
> -			goto out3;
> -		}
> -	}
> -do_generic:
> +	if (oprofile_ops.sync_start
> +	    && ((err = oprofile_ops.sync_start())))
> +		goto out2;
> +
>  	if ((err = sync_start()))
>  		goto out3;
>
> -post_sync:
>  	is_setup = 1;
>  	mutex_unlock(&start_mutex);
>  	return 0;
> @@ -133,20 +122,9 @@ out:
>  void oprofile_shutdown(void)
>  {
>  	mutex_lock(&start_mutex);
> -	if (oprofile_ops.sync_stop) {
> -		int sync_ret = oprofile_ops.sync_stop();
> -		switch (sync_ret) {
> -		case 0:
> -			goto post_sync;
> -		case 1:
> -			goto do_generic;
> -		default:
> -			goto post_sync;
> -		}
> -	}
> -do_generic:
> +	if (oprofile_ops.sync_stop)
> +		oprofile_ops.sync_stop();
>  	sync_stop();
> -post_sync:
>  	if (oprofile_ops.shutdown)
>  		oprofile_ops.shutdown();
>  	is_setup = 0;
> Index: Cell_kernel_4_15_2008/include/linux/oprofile.h
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/include/linux/oprofile.h
> +++ Cell_kernel_4_15_2008/include/linux/oprofile.h
>   
As mentioned above, the add_event_entry prototype should be removed from 
this header file.
> @@ -56,12 +56,10 @@ struct oprofile_operations {
>  	/* Stop delivering interrupts. */
>  	void (*stop)(void);
>  	/* Arch-specific buffer sync functions.
> -	 * Return value = 0:  Success
> -	 * Return value = -1: Failure
> -	 * Return value = 1:  Run generic sync function
> +	 * Sync start: Return 0 for Success,  -1 for Failure
>  	 */
>  	int (*sync_start)(void);
> -	int (*sync_stop)(void);
> +	void (*sync_stop)(void);
>
>  	/* Initiate a stack backtrace. Optional. */
>  	void (*backtrace)(struct pt_regs * const regs, unsigned int depth);
> @@ -106,6 +104,17 @@ void oprofile_add_sample(struct pt_regs 
>  void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
>  				unsigned long event, int is_kernel);
>
> +/*
> + * Add a value to the per CPU buffer.  The value is passed from the per CPU
> + * buffer to the kernel buffer with no additional processing.  The assumption
> + * is any processing of the value will be done in the postprocessor.  This
> + * function should only be used for special architecture specific data.
> + * Currently only used by the CELL processor.
> + *
> + * This function does not perform a backtrace.
> + */
> +void oprofile_add_value(unsigned long value, int cpu);
> +
>  /* Use this instead when the PC value is not from the regs. Doesn't
>   * backtrace. */
>  void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event);
> Index: Cell_kernel_4_15_2008/include/asm-powerpc/oprofile_impl.h
> ===================================================================
> --- Cell_kernel_4_15_2008.orig/include/asm-powerpc/oprofile_impl.h
> +++ Cell_kernel_4_15_2008/include/asm-powerpc/oprofile_impl.h
> @@ -48,7 +48,7 @@ struct op_powerpc_model {
>  	void (*stop) (void);
>  	void (*global_stop) (void);
>  	int (*sync_start)(void);
> -	int (*sync_stop)(void);
> +	void (*sync_stop)(void);
>  	void (*handle_interrupt) (struct pt_regs *,
>  				  struct op_counter_config *);
>  	int num_counters;
>
>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
> Don't miss this year's exciting event. There's still time to save $100. 
> Use priority code J8TL2D2. 
> http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
> _______________________________________________
> oprofile-list mailing list
> oprofile-list@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/oprofile-list
>   

^ permalink raw reply

* sysfs cpu entry
From: Kevin Diggs @ 2008-04-24 22:05 UTC (permalink / raw)
  To: linuxppc-dev

Hi,

	Can someone suggest where to add the code for a cpu 
(/sys/devices/system/cpu/cpu0) entry in sysfs?

	The 2.6.24 release has a sysfs.c file but it only seems to be used for 
64-bit? Anyone know why? What kind of planetary disasters will I create 
if I allow it to be used in 32-bit as well?

kevin

P.S.:  On an unrelated note, anyone know where to start looking for 
problems in pmac_zilog. My 8600 modem which worked fine in 2.4 is now 
essentially useless. Some problem with handshaking, I think.

^ permalink raw reply

* Re: [PATCH] [POWERPC] spufs: add .gitignore for spu_save_dump.h & spu_restore_dump.h
From: Jeremy Kerr @ 2008-04-24 22:26 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <Pine.LNX.4.64.0804241136310.22265@blarg.am.freescale.net>

Kumar,

> --- /dev/null
> +++ b/arch/powerpc/platforms/cell/spufs/.gitignore
> @@ -0,0 +1,2 @@
> +spu_save_dump.h
> +spu_restore_dump.h

nak - these still need to be tracked (and distributed with the tree), as 
we want to be able to build the kernel without spu-gcc.


Jeremy

^ permalink raw reply

* [git pull] Please pull powerpc.git master branch
From: Paul Mackerras @ 2008-04-25  0:19 UTC (permalink / raw)
  To: torvalds; +Cc: linuxppc-dev, akpm, linux-kernel

Linus,

Please do:

git pull \
git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc.git master

to get another powerpc update.  There are fixes for various problems
that have arisen plus a few patchsets that were not quite ready to go
when I sent the last pull request but now are.

Note that there are some generic changes to include/linux/sched.h and
init/main.c.  They are from a set of 3 patches from Ben H that Andrew
Morton acked and asked us to push through the powerpc tree.

Thanks,
Paul.

 Documentation/powerpc/booting-without-of.txt   |   11 
 MAINTAINERS                                    |   25 +
 arch/powerpc/Kconfig                           |   83 ++
 arch/powerpc/boot/.gitignore                   |    1 
 arch/powerpc/boot/Makefile                     |    2 
 arch/powerpc/boot/dts/canyonlands.dts          |   37 +
 arch/powerpc/boot/dts/glacier.dts              |   37 +
 arch/powerpc/boot/ns16550.c                    |    5 
 arch/powerpc/kernel/Makefile                   |    9 
 arch/powerpc/kernel/asm-offsets.c              |   11 
 arch/powerpc/kernel/cpu_setup_44x.S            |    1 
 arch/powerpc/kernel/cpu_setup_6xx.S            |    8 
 arch/powerpc/kernel/cputable.c                 |    4 
 arch/powerpc/kernel/head_fsl_booke.S           |   11 
 arch/powerpc/kernel/misc_32.S                  |    6 
 arch/powerpc/kernel/misc_64.S                  |   20 -
 arch/powerpc/kernel/of_platform.c              |    2 
 arch/powerpc/kernel/paca.c                     |   87 +-
 arch/powerpc/kernel/ppc32.h                    |    2 
 arch/powerpc/kernel/process.c                  |   31 +
 arch/powerpc/kernel/prom.c                     |    4 
 arch/powerpc/kernel/prom_init_check.sh         |   58 +
 arch/powerpc/kernel/ptrace32.c                 |   27 -
 arch/powerpc/kernel/setup_64.c                 |    5 
 arch/powerpc/kernel/stacktrace.c               |    1 
 arch/powerpc/kernel/udbg.c                     |    4 
 arch/powerpc/mm/fsl_booke_mmu.c                |    2 
 arch/powerpc/mm/hash_low_32.S                  |    4 
 arch/powerpc/mm/init_32.c                      |   13 
 arch/powerpc/mm/init_64.c                      |    3 
 arch/powerpc/mm/mem.c                          |   37 +
 arch/powerpc/mm/numa.c                         |    1 
 arch/powerpc/mm/pgtable_32.c                   |   23 +
 arch/powerpc/platforms/Kconfig                 |    1 
 arch/powerpc/platforms/Kconfig.cputype         |    4 
 arch/powerpc/platforms/Makefile                |    1 
 arch/powerpc/platforms/cell/Kconfig            |   13 
 arch/powerpc/platforms/cell/Makefile           |   20 -
 arch/powerpc/platforms/cell/axon_msi.c         |    6 
 arch/powerpc/platforms/cell/beat.c             |    2 
 arch/powerpc/platforms/cell/beat.h             |    0 
 arch/powerpc/platforms/cell/beat_htab.c        |    0 
 arch/powerpc/platforms/cell/beat_hvCall.S      |    0 
 arch/powerpc/platforms/cell/beat_interrupt.c   |    2 
 arch/powerpc/platforms/cell/beat_interrupt.h   |    0 
 arch/powerpc/platforms/cell/beat_iommu.c       |    0 
 arch/powerpc/platforms/cell/beat_smp.c         |    2 
 arch/powerpc/platforms/cell/beat_spu_priv1.c   |    0 
 arch/powerpc/platforms/cell/beat_syscall.h     |    0 
 arch/powerpc/platforms/cell/beat_udbg.c        |    0 
 arch/powerpc/platforms/cell/beat_wrapper.h     |    0 
 arch/powerpc/platforms/cell/celleb_pci.c       |   50 +
 arch/powerpc/platforms/cell/celleb_pci.h       |   19 
 arch/powerpc/platforms/cell/celleb_scc.h       |   87 ++
 arch/powerpc/platforms/cell/celleb_scc_epci.c  |   77 --
 arch/powerpc/platforms/cell/celleb_scc_pciex.c |  547 ++++++++++++++
 arch/powerpc/platforms/cell/celleb_scc_sio.c   |    0 
 arch/powerpc/platforms/cell/celleb_scc_uhc.c   |    2 
 arch/powerpc/platforms/cell/celleb_setup.c     |   12 
 arch/powerpc/platforms/cell/io-workarounds.c   |  358 +++------
 arch/powerpc/platforms/cell/io-workarounds.h   |   49 +
 arch/powerpc/platforms/cell/setup.c            |   43 +
 arch/powerpc/platforms/cell/spider-pci.c       |  184 +++++
 arch/powerpc/platforms/celleb/Kconfig          |   12 
 arch/powerpc/platforms/celleb/Makefile         |    9 
 arch/powerpc/platforms/celleb/io-workarounds.c |  280 -------
 arch/powerpc/platforms/iseries/exception.S     |   27 +
 arch/powerpc/platforms/ps3/os-area.c           |    1 
 arch/powerpc/platforms/pseries/Kconfig         |    5 
 arch/powerpc/platforms/pseries/Makefile        |    4 
 arch/powerpc/platforms/pseries/eeh.c           |    1 
 arch/powerpc/platforms/pseries/eeh_cache.c     |    1 
 arch/powerpc/platforms/pseries/firmware.c      |   10 
 arch/powerpc/platforms/pseries/iommu.c         |   39 -
 arch/powerpc/platforms/pseries/lpar.c          |   36 -
 arch/powerpc/platforms/pseries/ras.c           |    4 
 arch/powerpc/platforms/pseries/rtasd.c         |   14 
 arch/powerpc/platforms/pseries/scanlog.c       |   23 -
 arch/powerpc/platforms/pseries/setup.c         |   17 
 arch/powerpc/platforms/pseries/smp.c           |   11 
 arch/powerpc/platforms/pseries/xics.c          |    1 
 arch/powerpc/sysdev/mv64x60_dev.c              |   52 +
 arch/powerpc/sysdev/mv64x60_udbg.c             |    2 
 arch/ppc/8260_io/fcc_enet.c                    |   19 
 arch/ppc/8xx_io/enet.c                         |   23 -
 arch/ppc/Kconfig                               |   82 --
 arch/ppc/configs/ads8272_defconfig             |  930 ------------------------
 arch/ppc/configs/mpc86x_ads_defconfig          |  633 ----------------
 arch/ppc/configs/mpc885ads_defconfig           |  622 ----------------
 arch/ppc/kernel/ppc_ksyms.c                    |    1 
 arch/ppc/lib/string.S                          |   14 
 arch/ppc/platforms/Makefile                    |    4 
 arch/ppc/platforms/fads.h                      |   25 -
 arch/ppc/platforms/mpc8272ads_setup.c          |  367 ---------
 arch/ppc/platforms/mpc885ads.h                 |   93 --
 arch/ppc/platforms/mpc885ads_setup.c           |  476 ------------
 arch/ppc/platforms/pq2ads.c                    |   53 -
 arch/ppc/platforms/pq2ads.h                    |   94 --
 arch/ppc/platforms/pq2ads_pd.h                 |   32 -
 arch/ppc/syslib/m8260_setup.c                  |    6 
 arch/ppc/syslib/m82xx_pci.c                    |   38 -
 arch/ppc/syslib/m8xx_setup.c                   |   10 
 drivers/char/xilinx_hwicap/xilinx_hwicap.c     |    2 
 drivers/macintosh/windfarm_pm112.c             |    3 
 drivers/macintosh/windfarm_pm81.c              |    4 
 drivers/macintosh/windfarm_pm91.c              |    3 
 drivers/net/Kconfig                            |    1 
 drivers/of/of_i2c.c                            |    3 
 drivers/serial/of_serial.c                     |   14 
 include/asm-powerpc/fixmap.h                   |  106 +++
 include/asm-powerpc/highmem.h                  |   41 +
 include/asm-powerpc/io-defs.h                  |  101 +--
 include/asm-powerpc/io.h                       |    8 
 include/asm-powerpc/kdump.h                    |    5 
 include/asm-powerpc/paca.h                     |    1 
 include/asm-powerpc/page.h                     |   45 +
 include/asm-powerpc/page_32.h                  |    6 
 include/asm-powerpc/thread_info.h              |    8 
 include/asm-ppc/mmu.h                          |    2 
 include/asm-ppc/mpc8260.h                      |    4 
 include/asm-ppc/mpc8xx.h                       |    4 
 include/linux/sched.h                          |    2 
 init/main.c                                    |    7 
 123 files changed, 1923 insertions(+), 4572 deletions(-)
 create mode 100644 arch/powerpc/kernel/prom_init_check.sh
 rename arch/powerpc/platforms/{celleb/beat.c => cell/beat.c} (99%)
 rename arch/powerpc/platforms/{celleb/beat.h => cell/beat.h} (100%)
 rename arch/powerpc/platforms/{celleb/htab.c => cell/beat_htab.c} (100%)
 rename arch/powerpc/platforms/{celleb/hvCall.S => cell/beat_hvCall.S} (100%)
 rename arch/powerpc/platforms/{celleb/interrupt.c => cell/beat_interrupt.c} (99%)
 rename arch/powerpc/platforms/{celleb/interrupt.h => cell/beat_interrupt.h} (100%)
 rename arch/powerpc/platforms/{celleb/iommu.c => cell/beat_iommu.c} (100%)
 rename arch/powerpc/platforms/{celleb/smp.c => cell/beat_smp.c} (99%)
 rename arch/powerpc/platforms/{celleb/spu_priv1.c => cell/beat_spu_priv1.c} (100%)
 rename arch/powerpc/platforms/{celleb/beat_syscall.h => cell/beat_syscall.h} (100%)
 rename arch/powerpc/platforms/{celleb/udbg_beat.c => cell/beat_udbg.c} (100%)
 rename arch/powerpc/platforms/{celleb/beat_wrapper.h => cell/beat_wrapper.h} (100%)
 rename arch/powerpc/platforms/{celleb/pci.c => cell/celleb_pci.c} (93%)
 rename arch/powerpc/platforms/{celleb/pci.h => cell/celleb_pci.h} (73%)
 rename arch/powerpc/platforms/{celleb/scc.h => cell/celleb_scc.h} (68%)
 rename arch/powerpc/platforms/{celleb/scc_epci.c => cell/celleb_scc_epci.c} (86%)
 create mode 100644 arch/powerpc/platforms/cell/celleb_scc_pciex.c
 rename arch/powerpc/platforms/{celleb/scc_sio.c => cell/celleb_scc_sio.c} (100%)
 rename arch/powerpc/platforms/{celleb/scc_uhc.c => cell/celleb_scc_uhc.c} (99%)
 rename arch/powerpc/platforms/{celleb/setup.c => cell/celleb_setup.c} (97%)
 create mode 100644 arch/powerpc/platforms/cell/io-workarounds.h
 create mode 100644 arch/powerpc/platforms/cell/spider-pci.c
 delete mode 100644 arch/powerpc/platforms/celleb/Kconfig
 delete mode 100644 arch/powerpc/platforms/celleb/Makefile
 delete mode 100644 arch/powerpc/platforms/celleb/io-workarounds.c
 delete mode 100644 arch/ppc/configs/ads8272_defconfig
 delete mode 100644 arch/ppc/configs/mpc86x_ads_defconfig
 delete mode 100644 arch/ppc/configs/mpc885ads_defconfig
 delete mode 100644 arch/ppc/platforms/mpc8272ads_setup.c
 delete mode 100644 arch/ppc/platforms/mpc885ads.h
 delete mode 100644 arch/ppc/platforms/mpc885ads_setup.c
 delete mode 100644 arch/ppc/platforms/pq2ads.c
 delete mode 100644 arch/ppc/platforms/pq2ads.h
 delete mode 100644 arch/ppc/platforms/pq2ads_pd.h
 create mode 100644 include/asm-powerpc/fixmap.h

Adrian Bunk (2):
      [POWERPC] drivers/of/of_i2c.c: Add MODULE_LICENSE
      [POWERPC] char/xilinx_hwicap/ section fix

Benjamin Herrenschmidt (3):
      [POWERPC] Add thread_info_cache_init() weak hook
      [POWERPC] Fix kernel stack allocation alignment
      [POWERPC] Use __weak macro for smp_setup_processor_id

Christoph Hellwig (1):
      [POWERPC] Fix new warnings arising from stacktrace patch

Geoff Levand (1):
      [POWERPC] PS3: Fix gelic net module dependency

Grant Likely (1):
      [POWERPC] bootwrapper: fix build error on virtex405-head.S

Ishizaki Kou (9):
      [POWERPC] cell: Generalize io-workarounds code
      [POWERPC] celleb: Consolidate io-workarounds code
      [POWERPC] celleb: Move the files for celleb base support
      [POWERPC] celleb: Move the SCC related code for celleb
      [POWERPC] celleb: Move files for Beat hvcall interfaces
      [POWERPC] celleb: Move files for Beat mmu and iommu
      [POWERPC] celleb: Move a file for SPU on Beat
      [POWERPC] celleb: Move miscellaneous files for Beat
      [POWERPC] celleb: Add support for PCI Express

John Linn (2):
      [POWERPC] Xilinx: boot support for Xilinx uart 16550.
      [POWERPC] Xilinx: of_serial support for Xilinx uart 16550.

Josh Boyer (2):
      [POWERPC] 4xx: Fix duplicate phys_addr_t definition
      [POWERPC] Add strncmp to arch/ppc

Kay Sievers (1):
      [POWERPC] macintosh/windfarm: Fix platform driver hotplug/coldplug

Kumar Gala (9):
      [PPC] Remove mpc8272 ads board from arch/ppc
      [PPC] Remove mpc885ads and mpc86x ads boards from arch/ppc
      [POWERPC] ppc32: Fix errata for 603 CPUs
      [POWERPC] 85xx: Add support for relocatable kernel (and booting at non-zero)
      [POWERPC] Port fixmap from x86 and use for kmap_atomic
      [POWERPC] Clean up access to thread_info in assembly
      [POWERPC] Cleanup asm-offsets.c
      [POWERPC] Clean up misc_64.S
      [POWERPC] Add zImage.iseries to arch/powerpc/boot/.gitignore

Michael Ellerman (9):
      [POWERPC] Add include of linux/of.h to numa.c
      [POWERPC] Add include of linux/of.h to os-area.c
      [POWERPC] Discourage people from fiddling with kernel data from prom_init
      [POWERPC] Use of_get_next_parent() in platforms/cell/axon_msi.c
      [POWERPC] Set udbg_console index to 0
      [POWERPC] Mark udbg console as CON_ANYTIME, ie. callable early in boot
      [POWERPC] Register udbg console early on pseries LPAR
      [POWERPC] Convert from DBG() to pr_debug() in platforms/pseries/
      [POWERPC] Add CONFIG_PPC_PSERIES_DEBUG to enable debugging for platforms/pseries

Paul Mackerras (1):
      Revert "[POWERPC] Add compat handler for PTRACE_GETSIGINFO"

Remi Machet (3):
      [POWERPC] Use default values if necessary in mv64x60 I2C initialization
      [POWERPC] Initialize all mv64x60 devices even if one fails
      [POWERPC] Fix mv64x60 early console code to use cell-index property

Stefan Roese (2):
      [POWERPC] 4xx: Add NOR FLASH entries to Canyonlands and Glacier dts
      [POWERPC] 4xx: Fix 460GT support to not enable FPU

Timur Tabi (1):
      [POWERPC] Add Timur Tabi to the MAINTAINERS file

Tony Breeds (2):
      [POWERPC] Make iSeries spin on __secondary_hold_spinloop, like pSeries
      [POWERPC] Raise the upper limit of NR_CPUS and move the pacas into the BSS

^ 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