LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [patch 07/18] PS3: Make ps3av.h usable from user space
From: Christoph Hellwig @ 2007-06-06  7:46 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Geert Uytterhoeven, linuxppc-dev, Paul Mackerras, Masashi Kimoto
In-Reply-To: <46662337.9060908@am.sony.com>

On Tue, Jun 05, 2007 at 08:00:07PM -0700, Geoff Levand wrote:
> The user applications to manage the PS3 AV modes can use values
> defined in this header.

NACK.  First please don't introduce new unifdef-y headers but always
separated them.  Second I don't see any of the values actually used
in a user<->kerne interface.  If the application only happens to use
the same values it should ship a copy of the header intead.

^ permalink raw reply

* Re: [PATCH 2/8] Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Benjamin Herrenschmidt @ 2007-06-06  7:09 UTC (permalink / raw)
  To: Randy Vinson; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <466492DC.6050708@mvista.com>

On Mon, 2007-06-04 at 15:31 -0700, Randy Vinson wrote:
> Actually, that's not strictly true. If a card containing a P2P bridge
> is
> installed into PCI slot 4, the i8259 will end up on a bus that is not
> numbered bus 1. I've often wondered how something like that is handled
> in the DTS.

The bus number shouldn't matter as long as low IO cycles are properly
forwarded to it.

Ben.

^ permalink raw reply

* Re: [PATCH v2 8/9] Export of_bus_pci_get_flags().
From: Benjamin Herrenschmidt @ 2007-06-06  7:08 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1180996223.9632.76.camel@ld0161-tx32>

On Mon, 2007-06-04 at 17:30 -0500, Jon Loeliger wrote:
> It will be needed by the following patch.
> 
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> Signed-off-by: Jon Loeliger <jdl@freescale.com>

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

> ---
>  arch/powerpc/kernel/prom_parse.c |    2 +-
>  include/asm-powerpc/prom.h       |    1 +
>  2 files changed, 2 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
> index 3786dcc..754926f 100644
> --- a/arch/powerpc/kernel/prom_parse.c
> +++ b/arch/powerpc/kernel/prom_parse.c
> @@ -153,7 +153,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
>  	return of_bus_default_translate(addr + 1, offset, na - 1);
>  }
>  
> -static unsigned int of_bus_pci_get_flags(const u32 *addr)
> +unsigned int of_bus_pci_get_flags(const u32 *addr)
>  {
>  	unsigned int flags = 0;
>  	u32 w = addr[0];
> diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
> index 6845af9..0168373 100644
> --- a/include/asm-powerpc/prom.h
> +++ b/include/asm-powerpc/prom.h
> @@ -185,6 +185,7 @@ extern int pci_device_from_OF_node(struct device_node *node,
>  extern struct device_node* pci_busdev_to_OF_node(struct pci_bus *, int);
>  extern struct device_node* pci_device_to_OF_node(struct pci_dev *);
>  extern void pci_create_OF_bus_map(void);
> +extern unsigned int of_bus_pci_get_flags(const u32 *addr);
>  #endif
>  
>  extern struct resource *request_OF_resource(struct device_node* node,

^ permalink raw reply

* Re: [PATCH v2 6/9] Let subordinate transparent bridges be transparent.
From: Benjamin Herrenschmidt @ 2007-06-06  7:06 UTC (permalink / raw)
  To: Jon Loeliger; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <1180996213.9632.74.camel@ld0161-tx32>

On Mon, 2007-06-04 at 17:30 -0500, Jon Loeliger wrote:
> In pcibios_fixup_bus(), bridges that are subordinate
> to transparent bridges were still relocating their
> IORESOURCE_IO and IO_RESOURCE_MEM start and end values.
> 
> Fix this by preventing the transparent bridge from
> relocating the start and end values, thus allowing the
> subordinate non-transparent bridge full molestation rights.
> 
> Signed-off-by: York Sun <yorksun@freescale.com>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> Signed-off-by: Jon Loeliger <jdl@freescale.com>

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

> ---
> 
> This is the variant that was suggested by Ben H.
> 
>  arch/powerpc/kernel/pci_32.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
> index e66064b..7738a28 100644
> --- a/arch/powerpc/kernel/pci_32.c
> +++ b/arch/powerpc/kernel/pci_32.c
> @@ -1370,7 +1370,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
>  		for (i = 0; i < 4; ++i) {
>  			if ((res = bus->resource[i]) == NULL)
>  				continue;
> -			if (!res->flags)
> +			if (!res->flags || bus->self->transparent)
>  				continue;
>  			if (io_offset && (res->flags & IORESOURCE_IO)) {
>  				res->start += io_offset;

^ permalink raw reply

* Re: [patch 1/3] powerpc: fix pci_setup_phb_io_dynamic for pci_iomap
From: Benjamin Herrenschmidt @ 2007-06-06  7:05 UTC (permalink / raw)
  To: Arnd Bergmann; +Cc: linuxppc-dev, paulus, cbe-oss-dev, Arnd Bergmann
In-Reply-To: <20070604181739.375615838@arndb.de>

On Mon, 2007-06-04 at 20:14 +0200, Arnd Bergmann wrote:
> plain text document attachment (pci-iomap-fix-2.diff)
> From: Arnd Bergmann <arnd.bergmann@de.ibm.com>
> We had a problem on a system with only dynamically allocated
> PCI buses (using of_pci_phb_driver) in combination with libata.
> This setup ended up having no "primary" phb, which means
> that pci_io_base never got initialized and all IO port
> numbers are 64 bit numbers, which is larger than the
> PIO_MASK limit.
> 
> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

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

Paulus, that's a bug fix, should probably go into 2.6.22

> ---
> Index: linux-2.6/arch/powerpc/kernel/of_platform.c
> ===================================================================
> --- linux-2.6.orig/arch/powerpc/kernel/of_platform.c
> +++ linux-2.6/arch/powerpc/kernel/of_platform.c
> @@ -433,7 +433,7 @@ static int __devinit of_pci_phb_probe(st
>  	 * Note also that we don't do ISA, this will also be fixed with a
>  	 * more massive rework.
>  	 */
> -	pci_setup_phb_io(phb, 0);
> +	pci_setup_phb_io(phb, pci_io_base == 0);
>  
>  	/* Init pci_dn data structures */
>  	pci_devs_phb_init_dynamic(phb);
> 
> --

^ permalink raw reply

* Re: 83xx GPIO/EXT int in arch/powerpc/
From: Benjamin Herrenschmidt @ 2007-06-06  7:03 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: linuxppc-dev
In-Reply-To: <cbf493edec7259df199568389814dab6@kernel.crashing.org>

I'm a bit afraid that our various messages on the subject have been a
tad confusing :-) Especially your blurb on virtual number is a bit scary
Andy :-)

So I'm in a good mood, I'll attempt to explain what's going on.

The powerpc kernel nowadays separate linux IRQ numbers (what you see in
pci_device->irq, or what devices do a request_irq() on) from HW numbers.

The former are what we call "virtual" IRQ numbers, and are just indices
in a giant array (has always been), and can now be arbitrarily mapped to
HW numbers. In addition, linux always reserve numbers 0...15. 0 is
always illegal and 1..15 can only be mapped to a 8259 type legacy ISA
controller. This is to avoid problem with stupid drivers from the x86
world.

HW numbers are local to a given interrupt controller and they should be
all you care about in the device-tree.

If a device has interrupt source 2 on the IPIC, it should have an
interrupts property encoding a 2 (along with whatever the IPIC uses to
encode polarity). This will ultimately be turned into some other number
by linux for a virtual irq, but that's not the business of the dts.

Now, there is no automagic way of setting up GPIOs. You have to manually
(from your firmware that is, or maybe from your platform code),
configure the appropriate GPIO to the appropriate HW irq source on the
IPIC that matches what you put in your DTS.

The way those HW numbers are then parsed and turned into virtual IRQ
numbers depends on the type of device. Basically, you can always do it
manually with the irq_* functions, either by providing directly the low
level values (I wouldn't recommand that in general) or by letting the
linux device-tree parser do it for you.

However, if your device is a PCI device, it might be a simple as letting
the linux PCI code do it for you :-) the linux PCI code uses the parser
to attempt to resolve interrupts for every PCI device in the system.

Thus, you have multiple options here:

 - The easy/hack/bad one: You can have a ppc_md.pci_irq_fixup hook in
your platform code that maps it manually to a hard coded number. That's
ugly, but it will work. Though expect complaints if you ever try to
merge your code upstream.

 - You can create a device-node for the PCI device. PCI devices
normally, in linux, don't need to have device-nodes in the DTS, at least
it's not mandatory, but you -can- do it. If your node has the correct
"reg" property, it should be matches by the linux parser, and thus you
have the ability to put an interrupts property in there. It would
normally be a PCI interrupt specification, but you can specify
explicitely an interrupt parent that points to the IPIC and thus have an
interrupt pointing directly there. That's the example that, I think,
Andy gave you

 - You can do it in your interrupt-map. That's probably the cleanest way
to do it. Basically, you don't need a node for your device (or if you
have one, you let it do the standard "interrupts" for PCI which contains
an interrupt in number). However, in the interrupt-map of the bridge,
you'll notice that there's an entry for every possible dev/fn. Each of
them has an explicit parent PIC specification. Just make sure you have
an entry there for your device pin A dev/fn whose specification points
to the IPIC with the appropriate IRQ number and that should work fine.
If your device emits interrupts on multiple pins, you can always have
multiple entries, etc...

Now, that's assuming GPIOs, when used as external interrupts, are
directly routed to the IPIC. I don't know the 83xx so I just assumed
it :-) If that's not the case, you may need some intermediary cascaded
interrupt controller or something around those lines.

Ben.

^ permalink raw reply

* [PATCH] Create a dummy zImage if no valid platform has been selected.
From: Tony Breeds @ 2007-06-06  7:01 UTC (permalink / raw)
  To: LinuxPPC-dev


Signed-off-by: Tony Breeds <tony@bakeyournoodle.com>

---
This is mostly aimed at getting allnoconfig to complete.

 arch/powerpc/boot/Makefile |    8 ++++++++
 1 file changed, 8 insertions(+)

Index: working/arch/powerpc/boot/Makefile
===================================================================
--- working.orig/arch/powerpc/boot/Makefile
+++ working/arch/powerpc/boot/Makefile
@@ -188,6 +188,9 @@ $(obj)/zImage.%: vmlinux $(wrapperbits)
 $(obj)/zImage.ps3: vmlinux
 	$(STRIP) -s -R .comment $< -o $@
 
+$(obj)/zImage.strip: vmlinux
+	$(STRIP) -s -R .comment $< -o $@
+
 $(obj)/zImage.initrd.ps3: vmlinux
 	@echo "  WARNING zImage.initrd.ps3 not supported (yet)"
 
@@ -213,6 +216,11 @@ $(obj)/treeImage.initrd.%: vmlinux $(dts
 $(obj)/treeImage.%: vmlinux $(dts) $(wrapperbits)
 	$(call if_changed,wrap,treeboot-$*,$(dts))
 
+# If we don't have a platform selected then just strip the vmlinux.
+ifeq ("$(image-y)", "")
+image-y := zImage.strip
+endif
+
 $(obj)/zImage:		$(addprefix $(obj)/, $(image-y))
 	@rm -f $@; ln $< $@
 $(obj)/zImage.initrd:	$(addprefix $(obj)/, $(initrd-y))


Yours Tony

  linux.conf.au        http://linux.conf.au/ || http://lca2008.linux.org.au/
  Jan 28 - Feb 02 2008 The Australian Linux Technical Conference!

^ permalink raw reply

* Re: [patch 18/18] PS3: Device registration routines.
From: Geert Uytterhoeven @ 2007-06-06  6:57 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <466623A4.1080102@am.sony.com>

On Tue, 5 Jun 2007, Geoff Levand wrote:
> Add routines to probe devices present on the system
> and to register those devices with the LDM.

This one depends on the storage driver core, which I submitted for review on
May 25, but which have changed in the mean time due to the PS3 system bus
device rework.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- Sony Network and Software Technology Center Europe (NSCE)
Geert.Uytterhoeven@sonycom.com ------- The Corporate Village, Da Vincilaan 7-D1
Voice +32-2-7008453 Fax +32-2-7008622 ---------------- B-1935 Zaventem, Belgium

^ permalink raw reply

* Re: [patch 15/18] PS3: System manager re-work
From: Geert Uytterhoeven @ 2007-06-06  6:51 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <46662385.60904@am.sony.com>

On Tue, 5 Jun 2007, Geoff Levand wrote:
> --- /dev/null
> +++ b/drivers/ps3/sys-manager-core.c
> @@ -0,0 +1,68 @@
> +/*
> + *  PS3 System Manager core.
> + *
> + *  Copyright (C) 2007 Sony Computer Entertainment Inc.
> + *  Copyright 2007 Sony Corp.
> + *
> + *  This program is free software; you can redistribute it and/or modify
> + *  it under the terms of the GNU General Public License as published by
> + *  the Free Software Foundation; version 2 of the License.
> + *
> + *  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
> + */
> +#define DEBUG

Woops

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- Sony Network and Software Technology Center Europe (NSCE)
Geert.Uytterhoeven@sonycom.com ------- The Corporate Village, Da Vincilaan 7-D1
Voice +32-2-7008453 Fax +32-2-7008622 ---------------- B-1935 Zaventem, Belgium

^ permalink raw reply

* Re: [patch 17/18] PS3: Frame buffer system-bus rework
From: Geert Uytterhoeven @ 2007-06-06  6:51 UTC (permalink / raw)
  To: Geoff Levand
  Cc: Linux/PPC Development, Paul Mackerras,
	Linux Frame Buffer Device Development
In-Reply-To: <46662399.7030401@am.sony.com>


This one should go through linux-fbdev-devel (CC) for review, but Paul can
merge it because it depends on the PS3 system bus device rework.

On Tue, 5 Jun 2007, Geoff Levand wrote:
> Convert the ps3fb device from a platform device to a PS3 system bus device.
> Fix the remove and shutdown methods to support kexec and to make ps3fb a
> loadable module.
> 
> Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
> ---
>  arch/powerpc/platforms/ps3/setup.c |    9 -
>  drivers/video/Kconfig              |    4 
>  drivers/video/ps3fb.c              |  300 +++++++++++++++++--------------------
>  include/asm-powerpc/ps3fb.h        |   12 -
>  4 files changed, 145 insertions(+), 180 deletions(-)
> 
> --- a/arch/powerpc/platforms/ps3/setup.c
> +++ b/arch/powerpc/platforms/ps3/setup.c
> @@ -107,7 +107,7 @@ static void ps3_panic(char *str)
>  	while(1);
>  }
>  
> -#ifdef CONFIG_FB_PS3
> +#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
>  static void prealloc(struct ps3_prealloc *p)
>  {
>  	if (!p->size)
> @@ -125,10 +125,11 @@ static void prealloc(struct ps3_prealloc
>  }
>  
>  struct ps3_prealloc ps3fb_videomemory = {
> -    .name = "ps3fb videomemory",
> -    .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
> -    .align = 1024*1024			/* the GPU requires 1 MiB alignment */
> +	.name = "ps3fb videomemory",
> +	.size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
> +	.align = 1024*1024		/* the GPU requires 1 MiB alignment */
>  };
> +EXPORT_SYMBOL_GPL(ps3fb_videomemory);
>  #define prealloc_ps3fb_videomemory()	prealloc(&ps3fb_videomemory)
>  
>  static int __init early_parse_ps3fb(char *p)
> --- a/drivers/video/Kconfig
> +++ b/drivers/video/Kconfig
> @@ -1790,8 +1790,8 @@ config FB_IBM_GXT4500
>  	  adaptor, found on some IBM System P (pSeries) machines.
>  
>  config FB_PS3
> -	bool "PS3 GPU framebuffer driver"
> -	depends on (FB = y) && PS3_PS3AV
> +	tristate "PS3 GPU framebuffer driver"
> +	depends on FB && PS3_PS3AV
>  	select FB_SYS_FILLRECT
>  	select FB_SYS_COPYAREA
>  	select FB_SYS_IMAGEBLIT
> --- a/drivers/video/ps3fb.c
> +++ b/drivers/video/ps3fb.c
> @@ -27,7 +27,6 @@
>  #include <linux/vmalloc.h>
>  #include <linux/delay.h>
>  #include <linux/interrupt.h>
> -#include <linux/platform_device.h>
>  #include <linux/console.h>
>  #include <linux/ioctl.h>
>  #include <linux/notifier.h>
> @@ -46,6 +45,9 @@
>  #include <asm/ps3fb.h>
>  #include <asm/ps3.h>
>  
> +
> +#define DEVICE_NAME		"ps3fb"
> +
>  #ifdef PS3FB_DEBUG
>  #define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
>  #else
> @@ -126,7 +128,6 @@ struct gpu_driver_info {
>  
>  struct ps3fb_priv {
>  	unsigned int irq_no;
> -	void *dev;
>  
>  	u64 context_handle, memory_handle;
>  	void *xdr_ea;
> @@ -171,7 +172,7 @@ static const struct ps3fb_res_table ps3f
>  	{    0,    0,   0,   0 , 0} };
>  
>  /* default resolution */
> -#define GPU_RES_INDEX 0		/* 720 x 480 */
> +#define GPU_RES_INDEX	0		/* 720 x 480 */
>  
>  static const struct fb_videomode ps3fb_modedb[] = {
>      /* 60 Hz broadcast modes (modes "1" to "5") */
> @@ -298,10 +299,9 @@ static const struct fb_videomode ps3fb_m
>  #define FB_OFF(i)	(GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
>  
>  static int ps3fb_mode;
> -module_param(ps3fb_mode, bool, 0);
> -
> -static char *mode_option __initdata;
> +module_param(ps3fb_mode, int, 0);
>  
> +static char *mode_option __devinitdata;
>  
>  static int ps3fb_get_res_table(u32 xres, u32 yres)
>  {
> @@ -681,15 +681,15 @@ int ps3fb_wait_for_vsync(u32 crtc)
>  
>  EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
>  
> -void ps3fb_flip_ctl(int on)
> +void ps3fb_flip_ctl(int on, void *data)
>  {
> +	struct ps3fb_priv *priv = data;
>  	if (on)
> -		atomic_dec_if_positive(&ps3fb.ext_flip);
> +		atomic_dec_if_positive(&priv->ext_flip);
>  	else
> -		atomic_inc(&ps3fb.ext_flip);
> +		atomic_inc(&priv->ext_flip);
>  }
>  
> -EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
>  
>      /*
>       * ioctl
> @@ -851,37 +851,9 @@ static irqreturn_t ps3fb_vsync_interrupt
>  	return IRQ_HANDLED;
>  }
>  
> -#ifndef MODULE
> -static int __init ps3fb_setup(char *options)
> -{
> -	char *this_opt;
> -	int mode = 0;
> -
> -	if (!options || !*options)
> -		return 0;	/* no options */
> -
> -	while ((this_opt = strsep(&options, ",")) != NULL) {
> -		if (!*this_opt)
> -			continue;
> -		if (!strncmp(this_opt, "mode:", 5))
> -			mode = simple_strtoul(this_opt + 5, NULL, 0);
> -		else
> -			mode_option = this_opt;
> -	}
> -	return mode;
> -}
> -#endif	/* MODULE */
> -
> -    /*
> -     *  Initialisation
> -     */
> -
> -static void ps3fb_platform_release(struct device *device)
> -{
> -	/* This is called when the reference count goes to zero. */
> -}
>  
> -static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
> +static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
> +				struct ps3_system_bus_device *dev)
>  {
>  	int error;
>  
> @@ -897,7 +869,6 @@ static int ps3fb_vsync_settings(struct g
>  		return -EINVAL;
>  	}
>  
> -	ps3fb.dev = dev;
>  	error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
>  				   &ps3fb.irq_no);
>  	if (error) {
> @@ -907,7 +878,7 @@ static int ps3fb_vsync_settings(struct g
>  	}
>  
>  	error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
> -			    "ps3fb vsync", ps3fb.dev);
> +			    DEVICE_NAME, dev);
>  	if (error) {
>  		printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
>  		       error);
> @@ -966,16 +937,47 @@ static struct fb_ops ps3fb_ops = {
>  };
>  
>  static struct fb_fix_screeninfo ps3fb_fix __initdata = {
> -	.id =		"PS3 FB",
> +	.id =		DEVICE_NAME,
>  	.type =		FB_TYPE_PACKED_PIXELS,
>  	.visual =	FB_VISUAL_TRUECOLOR,
>  	.accel =	FB_ACCEL_NONE,
>  };
>  
> -static int __init ps3fb_probe(struct platform_device *dev)
> +static int ps3fb_set_sync(void)
> +{
> +	int status;
> +
> +#ifdef HEAD_A
> +	status = lv1_gpu_context_attribute(0x0,
> +					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
> +					   0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
> +	if (status) {
> +		printk(KERN_ERR
> +		       "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
> +		       __func__, status);
> +		return -1;
> +	}
> +#endif
> +#ifdef HEAD_B
> +	status = lv1_gpu_context_attribute(0x0,
> +					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
> +					   1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
> +
> +	if (status) {
> +		printk(KERN_ERR
> +		       "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
> +		       __func__, status);
> +		return -1;
> +	}
> +#endif
> +	return 0;
> +}
> +
> +static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
>  {
>  	struct fb_info *info;
>  	int retval = -ENOMEM;
> +	u32 xres, yres;
>  	u64 ddr_lpar = 0;
>  	u64 lpar_dma_control = 0;
>  	u64 lpar_driver_info = 0;
> @@ -986,6 +988,32 @@ static int __init ps3fb_probe(struct pla
>  	unsigned long offset;
>  	struct task_struct *task;
>  
> +	printk(" -> %s:%u\n", __func__, __LINE__);
> +
> +	status = ps3_open_hv_device(dev);
> +	if (status) {
> +		printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__);
> +		goto err;
> +	}
> +
> +	if (!ps3fb_mode)
> +		ps3fb_mode = ps3av_get_mode();
> +	DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
> +
> +	if (ps3fb_mode > 0 &&
> +	    !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
> +		ps3fb.res_index = ps3fb_get_res_table(xres, yres);
> +		DPRINTK("res_index:%d\n", ps3fb.res_index);
> +	} else
> +		ps3fb.res_index = GPU_RES_INDEX;
> +
> +	atomic_set(&ps3fb.f_count, -1);	/* fbcon opens ps3fb */
> +	atomic_set(&ps3fb.ext_flip, 0);	/* for flip with vsync */
> +	init_waitqueue_head(&ps3fb.wait_vsync);
> +	ps3fb.num_frames = 1;
> +
> +	ps3fb_set_sync();
> +
>  	/* get gpu context handle */
>  	status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
>  					 &ps3fb.memory_handle, &ddr_lpar);
> @@ -1029,7 +1057,7 @@ static int __init ps3fb_probe(struct pla
>  	 * leakage into userspace
>  	 */
>  	memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
> -	info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
> +	info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
>  	if (!info)
>  		goto err_free_irq;
>  
> @@ -1061,20 +1089,22 @@ static int __init ps3fb_probe(struct pla
>  	if (retval < 0)
>  		goto err_fb_dealloc;
>  
> -	platform_set_drvdata(dev, info);
> +	dev->core.driver_data = info;
>  
>  	printk(KERN_INFO
>  	       "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
>  	       info->node, ps3fb_videomemory.size >> 10);
>  
> -	task = kthread_run(ps3fbd, info, "ps3fbd");
> +	task = kthread_run(ps3fbd, info, DEVICE_NAME);
>  	if (IS_ERR(task)) {
>  		retval = PTR_ERR(task);
>  		goto err_unregister_framebuffer;
>  	}
>  
>  	ps3fb.task = task;
> +	ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
>  
> +	printk(" <- %s:%u\n", __func__, __LINE__);
>  	return 0;
>  
>  err_unregister_framebuffer:
> @@ -1084,7 +1114,7 @@ err_fb_dealloc:
>  err_framebuffer_release:
>  	framebuffer_release(info);
>  err_free_irq:
> -	free_irq(ps3fb.irq_no, ps3fb.dev);
> +	free_irq(ps3fb.irq_no, dev);
>  	ps3_irq_plug_destroy(ps3fb.irq_no);
>  err_iounmap_dinfo:
>  	iounmap((u8 __iomem *)ps3fb.dinfo);
> @@ -1096,26 +1126,39 @@ err:
>  	return retval;
>  }
>  
> -static void ps3fb_shutdown(struct platform_device *dev)
> +static int __devexit ps3fb_remove(struct ps3_system_bus_device *dev)
>  {
> -	ps3fb_flip_ctl(0);	/* flip off */
> -	ps3fb.dinfo->irq.mask = 0;
> -	free_irq(ps3fb.irq_no, ps3fb.dev);
> -	ps3_irq_plug_destroy(ps3fb.irq_no);
> -	iounmap((u8 __iomem *)ps3fb.dinfo);
> +	BUG();
> +	return 0;
>  }
>  
> -void ps3fb_cleanup(void)
> +static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
>  {
>  	int status;
> +	struct fb_info *info = dev->core.driver_data;
> +
> +	printk(" -> %s:%d\n", __func__, __LINE__);
> +
> +	// is this stuff ok here??
> +	// just set .shutdown = ps3fb_remove???
> +
> +	ps3fb_flip_ctl(0, &ps3fb);	/* flip off */
> +	ps3fb.dinfo->irq.mask = 0;
> +
> +	if (info) {
> +		unregister_framebuffer(info);
> +		fb_dealloc_cmap(&info->cmap);
> +		framebuffer_release(info);
> +	}
>  
> +	ps3av_register_flip_ctl(NULL, NULL);
>  	if (ps3fb.task) {
>  		struct task_struct *task = ps3fb.task;
>  		ps3fb.task = NULL;
>  		kthread_stop(task);
>  	}
>  	if (ps3fb.irq_no) {
> -		free_irq(ps3fb.irq_no, ps3fb.dev);
> +		free_irq(ps3fb.irq_no, dev);
>  		ps3_irq_plug_destroy(ps3fb.irq_no);
>  	}
>  	iounmap((u8 __iomem *)ps3fb.dinfo);
> @@ -1128,134 +1171,67 @@ void ps3fb_cleanup(void)
>  	if (status)
>  		DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
>  
> -	ps3av_dev_close();
> -}
> -
> -EXPORT_SYMBOL_GPL(ps3fb_cleanup);
> +	ps3_close_hv_device(dev);
> +	printk(" <- %s:%d\n", __func__, __LINE__);
>  
> -static int ps3fb_remove(struct platform_device *dev)
> -{
> -	struct fb_info *info = platform_get_drvdata(dev);
> -
> -	if (info) {
> -		unregister_framebuffer(info);
> -		fb_dealloc_cmap(&info->cmap);
> -		framebuffer_release(info);
> -	}
> -	ps3fb_cleanup();
>  	return 0;
>  }
>  
> -static struct platform_driver ps3fb_driver = {
> -	.probe	= ps3fb_probe,
> -	.remove = ps3fb_remove,
> -	.shutdown = ps3fb_shutdown,
> -	.driver = { .name = "ps3fb" }
> -};
> -
> -static struct platform_device ps3fb_device = {
> -	.name	= "ps3fb",
> -	.id	= 0,
> -	.dev	= { .release = ps3fb_platform_release }
> +static struct ps3_system_bus_driver ps3fb_driver = {
> +	.match_id	= PS3_MATCH_ID_GRAPHICS,
> +	.core.name	= DEVICE_NAME,
> +	.core.owner	= THIS_MODULE,
> +	.probe		= ps3fb_probe,
> +	.remove		= __devexit_p(ps3fb_remove),
> +	.shutdown	= ps3fb_shutdown,
>  };
>  
> -int ps3fb_set_sync(void)
> +static int __init ps3fb_setup(void)
>  {
> -	int status;
> +	char *options, *this_opt;
>  
> -#ifdef HEAD_A
> -	status = lv1_gpu_context_attribute(0x0,
> -					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
> -					   0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
> -	if (status) {
> -		printk(KERN_ERR
> -		       "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
> -		       __func__, status);
> -		return -1;
> -	}
> +#ifdef MODULE
> +	return 0;
>  #endif
> -#ifdef HEAD_B
> -	status = lv1_gpu_context_attribute(0x0,
> -					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
> -					   1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
>  
> -	if (status) {
> -		printk(KERN_ERR
> -		       "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
> -		       __func__, status);
> -		return -1;
> +	if (fb_get_options(DEVICE_NAME, &options))
> +		return -ENXIO;
> +
> +	if (!options || !*options)
> +		return 0;
> +
> +	while ((this_opt = strsep(&options, ",")) != NULL) {
> +		if (!*this_opt)
> +			continue;
> +		if (!strncmp(this_opt, "mode:", 5))
> +			ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
> +		else
> +			mode_option = this_opt;
>  	}
> -#endif
>  	return 0;
>  }
>  
> -EXPORT_SYMBOL_GPL(ps3fb_set_sync);
> -
>  static int __init ps3fb_init(void)
>  {
> -	int error;
> -#ifndef MODULE
> -	int mode;
> -	char *option = NULL;
> -
> -	if (fb_get_options("ps3fb", &option))
> -		goto err;
> -#endif
> -
> -	if (!ps3fb_videomemory.address)
> -		goto err;
> -
> -	error = ps3av_dev_open();
> -	if (error) {
> -		printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__);
> -		goto err;
> -	}
> -
> -	ps3fb_mode = ps3av_get_mode();
> -	DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
> -#ifndef MODULE
> -	mode = ps3fb_setup(option);	/* check boot option */
> -	if (mode)
> -		ps3fb_mode = mode;
> -#endif
> -	if (ps3fb_mode > 0) {
> -		u32 xres, yres;
> -		ps3av_video_mode2res(ps3fb_mode, &xres, &yres);
> -		ps3fb.res_index = ps3fb_get_res_table(xres, yres);
> -		DPRINTK("res_index:%d\n", ps3fb.res_index);
> -	} else
> -		ps3fb.res_index = GPU_RES_INDEX;
> -
> -	atomic_set(&ps3fb.f_count, -1);	/* fbcon opens ps3fb */
> -	atomic_set(&ps3fb.ext_flip, 0);	/* for flip with vsync */
> -	init_waitqueue_head(&ps3fb.wait_vsync);
> -	ps3fb.num_frames = 1;
> -
> -	error = platform_driver_register(&ps3fb_driver);
> -	if (!error) {
> -		error = platform_device_register(&ps3fb_device);
> -		if (error)
> -			platform_driver_unregister(&ps3fb_driver);
> -	}
> -
> -	ps3fb_set_sync();
> -
> -	return error;
> +	if (!ps3fb_videomemory.address ||  ps3fb_setup())
> +		return -ENXIO;
>  
> -err:
> -	return -ENXIO;
> +	return ps3_system_bus_driver_register(&ps3fb_driver);
>  }
>  
> -module_init(ps3fb_init);
> -
> -#ifdef MODULE
>  static void __exit ps3fb_exit(void)
>  {
> -	platform_device_unregister(&ps3fb_device);
> -	platform_driver_unregister(&ps3fb_driver);
> +	printk(" -> %s:%d\n", __func__, __LINE__);
> +	ps3_system_bus_driver_unregister(&ps3fb_driver);
> +	printk(" <- %s:%d\n", __func__, __LINE__);
>  }
>  
> -module_exit(ps3fb_exit);
> +module_init(ps3fb_init);
> +#if 0
> +module_exit(ps3fb_exit);	/* FIXME: need to fix fbcon to support remove */
> +#endif
>  
>  MODULE_LICENSE("GPL");
> -#endif				/* MODULE */
> +MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver");
> +MODULE_AUTHOR("Sony Computer Entertainment Inc.");
> +MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS);
> --- a/include/asm-powerpc/ps3fb.h
> +++ b/include/asm-powerpc/ps3fb.h
> @@ -41,16 +41,4 @@ struct ps3fb_ioctl_res {
>  	__u32 num_frames; /* num of frame buffers */
>  };
>  
> -#ifdef __KERNEL__
> -
> -#ifdef CONFIG_FB_PS3
> -extern void ps3fb_flip_ctl(int on);
> -extern void ps3fb_cleanup(void);
> -#else
> -static inline void ps3fb_flip_ctl(int on) {}
> -static inline void ps3fb_cleanup(void) {}
> -#endif
> -
> -#endif /* __KERNEL__ */
> -
>  #endif /* _ASM_POWERPC_PS3FB_H_ */
> 
> -- 
> 
> 

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- Sony Network and Software Technology Center Europe (NSCE)
Geert.Uytterhoeven@sonycom.com ------- The Corporate Village, Da Vincilaan 7-D1
Voice +32-2-7008453 Fax +32-2-7008622 ---------------- B-1935 Zaventem, Belgium

^ permalink raw reply

* Re: [patch 16/18] PS3: Rework AV settings driver
From: Geert Uytterhoeven @ 2007-06-06  6:49 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <46662391.10700@am.sony.com>

On Tue, 5 Jun 2007, Geoff Levand wrote:
> --- a/drivers/ps3/ps3av.c
> +++ b/drivers/ps3/ps3av.c

...

> +#define DEBUG

Another one

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- Sony Network and Software Technology Center Europe (NSCE)
Geert.Uytterhoeven@sonycom.com ------- The Corporate Village, Da Vincilaan 7-D1
Voice +32-2-7008453 Fax +32-2-7008622 ---------------- B-1935 Zaventem, Belgium

^ permalink raw reply

* Re: [patch 09/18] PS3: System-bus rework
From: Geert Uytterhoeven @ 2007-06-06  6:43 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <4666234B.2020208@am.sony.com>

On Tue, 5 Jun 2007, Geoff Levand wrote:
> --- a/arch/powerpc/platforms/ps3/mm.c
> +++ b/arch/powerpc/platforms/ps3/mm.c
> @@ -17,6 +17,7 @@
>   *  along with this program; if not, write to the Free Software
>   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>   */
> +#define DEBUG
>  
>  #include <linux/kernel.h>
>  #include <linux/module.h>

> --- a/arch/powerpc/platforms/ps3/system-bus.c
> +++ b/arch/powerpc/platforms/ps3/system-bus.c
> @@ -18,6 +18,8 @@
>   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>   */
>  
> +#define DEBUG
> +
>  #include <linux/kernel.h>
>  #include <linux/init.h>
>  #include <linux/module.h>

You forgot to remove these before release.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- Sony Network and Software Technology Center Europe (NSCE)
Geert.Uytterhoeven@sonycom.com ------- The Corporate Village, Da Vincilaan 7-D1
Voice +32-2-7008453 Fax +32-2-7008622 ---------------- B-1935 Zaventem, Belgium

^ permalink raw reply

* Re: [PATCH] powerpc: Add Marvell mv64x60 udbg putc/getc functions
From: Paul Mackerras @ 2007-06-06  6:06 UTC (permalink / raw)
  To: Dale Farnsworth; +Cc: linuxppc-dev
In-Reply-To: <20070523220518.GA2312@xyzzy.farnsworth.org>

Dale Farnsworth writes:

> Paul, this patch is unchanged from the one I posted 10 days ago.
> At that time, I saw no discussion, other than Mark's ACK.  I'd 
> argue that this is a bugfix, and hope that it could go into 2.6.22.

Um, it seems rather large, and in particular adds a fair bit of
completely new code.  Is there a simpler way of getting to an
acceptable point - e.g. just not use the udbg console on these boards?
If we don't have udbg support for them then the udbg console would
seem a bit pointless, no?

Paul.

^ permalink raw reply

* Re: [PATCH] of_serial: ignore unknown serial port
From: Paul Mackerras @ 2007-06-06  5:58 UTC (permalink / raw)
  To: Ishizaki Kou; +Cc: linuxppc-dev, arnd
In-Reply-To: <20070531.183033.-1300520557.kouish@swc.toshiba.co.jp>

Ishizaki Kou writes:

> Current of_serial driver assumes unknown serial port to be 8250. But
> this behavior may cause fatal problems when the serial port is not
> 8250. This patch corrects probe routine to ignore unknown serial port.
> 
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
> Cc: Arnd Bergmann <arnd@arndb.de>

Is this a bugfix that needs to go in 2.6.22?  Likewise, is your next
patch (of_serial: add port type checking) needed in 2.6.22?

Paul.

^ permalink raw reply

* Re: [RFC/PATCH 4/4] Add support for MSI on Axon-based Cell systems
From: Michael Ellerman @ 2007-06-06  5:19 UTC (permalink / raw)
  To: Milton Miller; +Cc: ppcdev
In-Reply-To: <62dbe474663a3a3e91268f0bdc2f6479@bga.com>

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

On Tue, 2007-06-05 at 09:12 -0500, Milton Miller wrote:
> On Mon Jun 4 23:00:05 EST 2007, Michael Ellerman wrote:
> > This patch adds support for the setup and decoding of MSIs
> > on Axon-based Cell systems.
> >
> > This still needs a bit of cleanup, but sending now for an early review.
> 
> Ok here is some from someone without the documentation.

Thanks Milton, that's what I was after :)

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Re: Linux interrupt managing on 8xx
From: Ricardo Scop @ 2007-06-06  4:02 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: DI BACCO ANTONIO - technolabs
In-Reply-To: <F1F6EC0C8B75034F9E3A79FC85122E8E264992@aquib01a>

On Monday 04 June 2007 17:37, DI BACCO ANTONIO - technolabs wrote:
> I have a component named pca9555 (on the i2c bus) that is an I/O expander.
> It can generate an interrupt to the MPC8xx processor (SIU_IRQ1 pin). This
> pin will be active till I read registers of pca9555. Because I cannot
> access the i2c bus in the interrupt handler I queue a work on a work queue.
> Just at the end of the interrupt handler  should I disable the interrupt on
> the mpc8xx? I think that otherwise the interrupt will pop up again till I
> execute the work in the work queue finally reading the pca9555 and shutting
> off the source of the interrupt.

Well, why don't you simply program the interrupt to be edge-triggered in the 
SIEL register? This way it will only occur again after the pin level is 
cleared.

HTH,

Ricardo.

^ permalink raw reply

* Re: [PATCH] Donate dedicated CPU cycles
From: Paul Mackerras @ 2007-06-06  4:25 UTC (permalink / raw)
  To: Jake Moilanen; +Cc: linuxppc-dev
In-Reply-To: <1180638885.5756.11.camel@goblue>

Jake Moilanen writes:

> A Power6 can give up CPU cycles on a dedicated CPU (as opposed to a
> shared CPU) to other shared processors if the administrator asks for it
> (via the HMC).
> 
> This patch enables that to work properly on P6.

Is this something that needs to be controlled from userland, e.g. by a
sysctl or something in /sys?

Paul.

^ permalink raw reply

* Re: [patch 01/18] Cell: Add spu shutdown method
From: Michael Ellerman @ 2007-06-06  4:08 UTC (permalink / raw)
  To: Geoff Levand
  Cc: linuxppc-dev, Paul Mackerras, Arnd Bergmann, André Detsch
In-Reply-To: <46662303.1040606@am.sony.com>

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

On Tue, 2007-06-05 at 19:59 -0700, Geoff Levand wrote:
> Add a shutdown method to spu_sysdev_class to allow proper spu resource
> cleanup on system shutdown.  This is needed to support kexec on the PS3
> platform.
> 
> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
> ---
>  arch/powerpc/platforms/cell/spu_base.c |   12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)

André, does this interact with your kexec work at all?

cheers

> --- a/arch/powerpc/platforms/cell/spu_base.c
> +++ b/arch/powerpc/platforms/cell/spu_base.c
> @@ -462,8 +462,18 @@ void spu_free(struct spu *spu)
>  }
>  EXPORT_SYMBOL_GPL(spu_free);
>  
> +static int spu_shutdown(struct sys_device *sysdev)
> +{
> +	struct spu *spu = container_of(sysdev, struct spu, sysdev);
> +
> +	spu_free_irqs(spu);
> +	spu_destroy_spu(spu);
> +	return 0;
> +}
> +
>  struct sysdev_class spu_sysdev_class = {
> -	set_kset_name("spu")
> +	set_kset_name("spu"),
> +	.shutdown = spu_shutdown,
>  };
>  
>  int spu_add_sysdev_attr(struct sysdev_attribute *attr)
> 
-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* Re: [patch 03/18] PS3: Use __maybe_unused
From: Michael Ellerman @ 2007-06-06  4:05 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <46662315.30004@am.sony.com>

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

On Tue, 2007-06-05 at 19:59 -0700, Geoff Levand wrote:
> Change the PS3 debug routines from using the GCC specific
> '__attribute__ ((unused))' to the preprocessor macro
> __maybe_unused.

I'm confused. If DEBUG is defined then they're used, if it's not then
they're not built.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* [PATCH] spufs: fix error handling in spufs_fill_dir()
From: Jeremy Kerr @ 2007-06-06  4:03 UTC (permalink / raw)
  To: paulus; +Cc: linuxppc-dev, cbe-oss-dev

From: Sebastian Siewior <bigeasy@linux.vnet.ibm.com>

The error path in spufs_fill_dir() is broken. If d_alloc_name() or
spufs_new_file() fails, spufs_prune_dir() is getting called. At this time
dir->inode is not set and a NULL pointer is dereferenced by mutex_lock().
This bugfix replaces spufs_prune_dir() with a shorter version that does
not touch dir->inode but simply removes all children.

Signed-off-by: Sebastian Siewior <bigeasy@linux.vnet.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>

---

Paulus - another bugfix for 2.6.22.

---

 arch/powerpc/platforms/cell/spufs/inode.c |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

Index: linux-2.6-spufs/arch/powerpc/platforms/cell/spufs/inode.c
===================================================================
--- linux-2.6-spufs.orig/arch/powerpc/platforms/cell/spufs/inode.c
+++ linux-2.6-spufs/arch/powerpc/platforms/cell/spufs/inode.c
@@ -177,7 +177,7 @@ static int spufs_rmdir(struct inode *par
 static int spufs_fill_dir(struct dentry *dir, struct tree_descr *files,
 			  int mode, struct spu_context *ctx)
 {
-	struct dentry *dentry;
+	struct dentry *dentry, *tmp;
 	int ret;
 
 	while (files->name && files->name[0]) {
@@ -193,7 +193,20 @@ static int spufs_fill_dir(struct dentry 
 	}
 	return 0;
 out:
-	spufs_prune_dir(dir);
+	/*
+	 * remove all children from dir. dir->inode is not set so don't
+	 * just simply use spufs_prune_dir() and panic afterwards :)
+	 * dput() looks like it will do the right thing:
+	 * - dec parent's ref counter
+	 * - remove child from parent's child list
+	 * - free child's inode if possible
+	 * - free child
+	 */
+	list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) {
+		dput(dentry);
+	}
+
+	shrink_dcache_parent(dir);
 	return ret;
 }
 

^ permalink raw reply

* Re: [patch 08/18] PS3: Kexec support
From: Michael Ellerman @ 2007-06-06  4:01 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <4666233F.1080103@am.sony.com>

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

On Tue, 2007-06-05 at 20:00 -0700, Geoff Levand wrote:
> Fixup the core platform parts needed for kexec to work on the PS3.
>  - Setup ps3_hpte_clear correctly.
>  - Mask interrupts on irq removal.
>  - Release all hypervisor resources.

The irq changes might be kexec related, but it's a mess to review. You
seem to moving a bunch of code around in the patch as well.


> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
> ---
>  arch/powerpc/platforms/ps3/htab.c      |   14 +-
>  arch/powerpc/platforms/ps3/interrupt.c |  199 ++++++++++++++++++++-------------
>  arch/powerpc/platforms/ps3/setup.c     |   29 ++--
>  3 files changed, 147 insertions(+), 95 deletions(-)
> 
> --- a/arch/powerpc/platforms/ps3/htab.c
> +++ b/arch/powerpc/platforms/ps3/htab.c
> @@ -234,10 +234,18 @@ static void ps3_hpte_invalidate(unsigned
>  
>  static void ps3_hpte_clear(void)
>  {
> -	/* Make sure to clean up the frame buffer device first */
> -	ps3fb_cleanup();
> +	int result;
>  
> -	lv1_unmap_htab(htab_addr);
> +	DBG(" -> %s:%d\n", __func__, __LINE__);
> +
> +	result = lv1_unmap_htab(htab_addr);
> +	BUG_ON(result);
> +
> +	ps3_mm_shutdown();
> +
> +	ps3_mm_vas_destroy();
> +
> +	DBG(" <- %s:%d\n", __func__, __LINE__);
>  }

Do you really want to be calling DBG() here? Hmm, it looks like it
doesn't actually do anything?

>  
>  void __init ps3_hpte_init(unsigned long htab_size)
> --- a/arch/powerpc/platforms/ps3/interrupt.c
> +++ b/arch/powerpc/platforms/ps3/interrupt.c
> @@ -91,6 +91,92 @@ struct ps3_private {
>  static DEFINE_PER_CPU(struct ps3_private, ps3_private);
>  
>  /**
> + * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
> + * @virq: The assigned Linux virq.
> + *
> + * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
> + */
> +
> +static void ps3_chip_mask(unsigned int virq)
> +{
> +	struct ps3_private *pd = get_irq_chip_data(virq);
> +	u64 bit = 0x8000000000000000UL >> virq;
> +	u64 *p = &pd->bmp.mask;
> +	u64 old;
> +	unsigned long flags;
> +
> +	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
> +
> +	local_irq_save(flags);
> +	asm volatile(
> +		     "1:	ldarx %0,0,%3\n"
> +		     "andc	%0,%0,%2\n"
> +		     "stdcx.	%0,0,%3\n"
> +		     "bne-	1b"
> +		     : "=&r" (old), "+m" (*p)
> +		     : "r" (bit), "r" (p)
> +		     : "cc" );
> +
> +	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
> +	local_irq_restore(flags);

How is this different from set_bit() ?  (asm-powerpc/bitops.h)

ps. now that I see you're just moving this code around someone's
probably already asked that question.

> +/**
> + * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
> + * @virq: The assigned Linux virq.
> + *
> + * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
> + */
> +
> +static void ps3_chip_unmask(unsigned int virq)
> +{
> +	struct ps3_private *pd = get_irq_chip_data(virq);
> +	u64 bit = 0x8000000000000000UL >> virq;
> +	u64 *p = &pd->bmp.mask;
> +	u64 old;
> +	unsigned long flags;
> +
> +	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
> +
> +	local_irq_save(flags);
> +	asm volatile(
> +		     "1:	ldarx %0,0,%3\n"
> +		     "or	%0,%0,%2\n"
> +		     "stdcx.	%0,0,%3\n"
> +		     "bne-	1b"
> +		     : "=&r" (old), "+m" (*p)
> +		     : "r" (bit), "r" (p)
> +		     : "cc" );
> +
> +	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
> +	local_irq_restore(flags);
> +}
> +
> +/**
> + * ps3_chip_eoi - HV end-of-interrupt.
> + * @virq: The assigned Linux virq.
> + *
> + * Calls lv1_end_of_interrupt_ext().
> + */
> +
> +static void ps3_chip_eoi(unsigned int virq)
> +{
> +	const struct ps3_private *pd = get_irq_chip_data(virq);
> +	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
> +}
> +
> +/**
> + * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
> + */
> +
> +static struct irq_chip ps3_irq_chip = {
> +	.typename = "ps3",
> +	.mask = ps3_chip_mask,
> +	.unmask = ps3_chip_unmask,
> +	.eoi = ps3_chip_eoi,
> +};
> +
> +/**
>   * ps3_virq_setup - virq related setup.
>   * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
>   * serviced on.
> @@ -134,6 +220,8 @@ int ps3_virq_setup(enum ps3_cpu_binding 
>  		goto fail_set;
>  	}
>  
> +	ps3_chip_mask(*virq);
> +
>  	return result;
>  
>  fail_set:
> @@ -225,6 +313,8 @@ int ps3_irq_plug_destroy(unsigned int vi
>  	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
>  		pd->node, pd->cpu, virq);
>  
> +	ps3_chip_mask(virq);
> +
>  	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
>  
>  	if (result)
> @@ -282,7 +372,9 @@ int ps3_event_receive_port_destroy(unsig
>  {
>  	int result;
>  
> -	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
> +	pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
> +
> +	ps3_chip_mask(virq);
>  
>  	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
>  
> @@ -290,17 +382,13 @@ int ps3_event_receive_port_destroy(unsig
>  		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
>  			__func__, __LINE__, ps3_result(result));
>  
> -	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
> -	 * so don't call ps3_irq_plug_destroy() here.
> +	/* Can't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
> +	 * calls from interrupt context (smp_call_function).
>  	 */
>  
> -	result = ps3_virq_destroy(virq);
> -	BUG_ON(result);
> -
>  	pr_debug(" <- %s:%d\n", __func__, __LINE__);
>  	return result;
>  }
> -EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
>  
>  int ps3_send_event_locally(unsigned int virq)
>  {
> @@ -372,6 +460,13 @@ int ps3_sb_event_receive_port_destroy(co
>  	result = ps3_event_receive_port_destroy(virq);
>  	BUG_ON(result);
>  
> +	/* ps3_event_receive_port_destroy() destroys the IRQ plug,
> +	 * so don't call ps3_irq_plug_destroy() here.
> +	 */
> +
> +	result = ps3_virq_destroy(virq);
> +	BUG_ON(result);
> +
>  	pr_debug(" <- %s:%d\n", __func__, __LINE__);
>  	return result;
>  }
> @@ -412,16 +507,23 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
>  int ps3_io_irq_destroy(unsigned int virq)
>  {
>  	int result;
> +	unsigned long outlet = virq_to_hw(virq);
>  
> -	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
> +	ps3_chip_mask(virq);
>  
> -	if (result)
> -		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
> -			__func__, __LINE__, ps3_result(result));
> +	/* lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
> +	 * so call ps3_irq_plug_destroy() first.
> +	 */
>  
>  	result = ps3_irq_plug_destroy(virq);
>  	BUG_ON(result);
>  
> +	result = lv1_destruct_io_irq_outlet(outlet);
> +
> +	if (result)
> +		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
> +			__func__, __LINE__, ps3_result(result));
> +
>  	return result;
>  }
>  EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
> @@ -466,6 +568,7 @@ int ps3_vuart_irq_destroy(unsigned int v
>  {
>  	int result;
>  
> +	ps3_chip_mask(virq);
>  	result = lv1_deconfigure_virtual_uart_irq();
>  
>  	if (result) {
> @@ -514,9 +617,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_bindi
>  
>  int ps3_spe_irq_destroy(unsigned int virq)
>  {
> -	int result = ps3_irq_plug_destroy(virq);
> +	int result;
> +
> +	ps3_chip_mask(virq);
> +
> +	result = ps3_irq_plug_destroy(virq);
>  	BUG_ON(result);
> -	return 0;
> +
> +	return result;
>  }
>  
> 
> @@ -565,67 +673,6 @@ static void __maybe_unused _dump_mask(st
>  static void dump_bmp(struct ps3_private* pd) {};
>  #endif /* defined(DEBUG) */
>  
> -static void ps3_chip_mask(unsigned int virq)
> -{
> -	struct ps3_private *pd = get_irq_chip_data(virq);
> -	u64 bit = 0x8000000000000000UL >> virq;
> -	u64 *p = &pd->bmp.mask;
> -	u64 old;
> -	unsigned long flags;
> -
> -	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
> -
> -	local_irq_save(flags);
> -	asm volatile(
> -		     "1:	ldarx %0,0,%3\n"
> -		     "andc	%0,%0,%2\n"
> -		     "stdcx.	%0,0,%3\n"
> -		     "bne-	1b"
> -		     : "=&r" (old), "+m" (*p)
> -		     : "r" (bit), "r" (p)
> -		     : "cc" );
> -
> -	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
> -	local_irq_restore(flags);
> -}
> -
> -static void ps3_chip_unmask(unsigned int virq)
> -{
> -	struct ps3_private *pd = get_irq_chip_data(virq);
> -	u64 bit = 0x8000000000000000UL >> virq;
> -	u64 *p = &pd->bmp.mask;
> -	u64 old;
> -	unsigned long flags;
> -
> -	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
> -
> -	local_irq_save(flags);
> -	asm volatile(
> -		     "1:	ldarx %0,0,%3\n"
> -		     "or	%0,%0,%2\n"
> -		     "stdcx.	%0,0,%3\n"
> -		     "bne-	1b"
> -		     : "=&r" (old), "+m" (*p)
> -		     : "r" (bit), "r" (p)
> -		     : "cc" );
> -
> -	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
> -	local_irq_restore(flags);
> -}
> -
> -static void ps3_chip_eoi(unsigned int virq)
> -{
> -	const struct ps3_private *pd = get_irq_chip_data(virq);
> -	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
> -}
> -
> -static struct irq_chip irq_chip = {
> -	.typename = "ps3",
> -	.mask = ps3_chip_mask,
> -	.unmask = ps3_chip_unmask,
> -	.eoi = ps3_chip_eoi,
> -};
> -
>  static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
>  {
>  	set_irq_chip_data(virq, NULL);
> @@ -637,7 +684,7 @@ static int ps3_host_map(struct irq_host 
>  	pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
>  		virq);
>  
> -	set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
> +	set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
>  
>  	return 0;
>  }
> @@ -657,7 +704,7 @@ void __init ps3_register_ipi_debug_brk(u
>  		cpu, virq, pd->bmp.ipi_debug_brk_mask);
>  }
>  
> -unsigned int ps3_get_irq(void)
> +static unsigned int ps3_get_irq(void)
>  {
>  	struct ps3_private *pd = &__get_cpu_var(ps3_private);
>  	u64 x = (pd->bmp.status & pd->bmp.mask);
> --- a/arch/powerpc/platforms/ps3/setup.c
> +++ b/arch/powerpc/platforms/ps3/setup.c
> @@ -209,31 +209,28 @@ static int __init ps3_probe(void)
>  #if defined(CONFIG_KEXEC)
>  static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
>  {
> -	DBG(" -> %s:%d\n", __func__, __LINE__);
> +	int result;
> +	u64 ppe_id;
> +	u64 thread_id = secondary ? 1 : 0;
> +
> +	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, secondary);
> +	ps3_smp_cleanup_cpu(thread_id);
> +
> +	lv1_get_logical_ppe_id(&ppe_id);
> +	result = lv1_configure_irq_state_bitmap(ppe_id, secondary ? 0 : 1, 0);
>  
> -	if (secondary) {
> -		int cpu;
> -		for_each_online_cpu(cpu)
> -			if (cpu)
> -				ps3_smp_cleanup_cpu(cpu);
> -	} else
> -		ps3_smp_cleanup_cpu(0);
> +	/* seems to fail on second call */
> +	DBG("%s:%d: lv1_configure_irq_state_bitmap (%d) %s\n", __func__,
> +		__LINE__, secondary, ps3_result(result));
>  
>  	DBG(" <- %s:%d\n", __func__, __LINE__);
>  }
>  
>  static void ps3_machine_kexec(struct kimage *image)
>  {
> -	unsigned long ppe_id;
> -
>  	DBG(" -> %s:%d\n", __func__, __LINE__);
>  
> -	lv1_get_logical_ppe_id(&ppe_id);
> -	lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
> -	ps3_mm_shutdown();
> -	ps3_mm_vas_destroy();
> -
> -	default_machine_kexec(image);
> +	default_machine_kexec(image); // needs ipi, never returns.

Just get rid of ps3_machine_kexec() and hook default_machine_kexec()
directly into your ppc_md.

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

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

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

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

^ permalink raw reply

* [patch 06/18] PS3: Add support for HDMI RGB Full Range mode
From: Geoff Levand @ 2007-06-06  2:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Geert Uytterhoeven, Paul Mackerras, Masashi Kimoto
In-Reply-To: <20070606024407.786638029@am.sony.com>

Add support for HDMI RGB Full Range mode, which is available on system
software 1.80 or newer.

CC: Masashi Kimoto <Masashi_Kimoto@hq.scei.sony.co.jp>
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
 drivers/ps3/ps3av_cmd.c     |   16 ++++++++++++++++
 include/asm-powerpc/ps3av.h |   12 +++++++++---
 2 files changed, 25 insertions(+), 3 deletions(-)

--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -143,6 +143,14 @@ static u32 ps3av_vid_video2av(int vid)
 	return PS3AV_CMD_AV_VID_480P;
 }
 
+static int ps3av_hdmi_range(void)
+{
+	if (ps3_compare_firmware_version(1, 8, 0) < 0)
+		return 0;
+	else
+		return 1; /* supported */
+}
+
 int ps3av_cmd_init(void)
 {
 	int res;
@@ -350,6 +358,10 @@ u32 ps3av_cmd_set_av_video_cs(void *p, u
 	/* should be same as video_mode.video_cs_out */
 	av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8);
 	av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out);
+	if ((id & PS3AV_MODE_WHITE) && ps3av_hdmi_range())
+		av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_ON;
+	else /* default off */
+		av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_OFF;
 	av_video_cs->aspect = aspect;
 	if (id & PS3AV_MODE_DITHER) {
 		av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON
@@ -392,6 +404,10 @@ u32 ps3av_cmd_set_video_mode(void *p, u3
 	video_mode->pitch = video_mode->width * 4;	/* line_length */
 	video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT;
 	video_mode->video_format = ps3av_video_fmt_table[video_fmt].format;
+	if ((id & PS3AV_MODE_COLOR) && ps3av_hdmi_range())
+		video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT;
+	else /* default enable */
+		video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT;
 	video_mode->video_order = ps3av_video_fmt_table[video_fmt].order;
 
 	pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n",
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -159,6 +159,9 @@
 #define PS3AV_CMD_VIDEO_FMT_X8R8G8B8			0x0000
 /* video_out_format */
 #define PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT		0x0000
+/* video_cl_cnv */
+#define PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT		0x0000
+#define PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT		0x0010
 /* video_sync */
 #define PS3AV_CMD_VIDEO_SYNC_VSYNC			0x0001
 #define PS3AV_CMD_VIDEO_SYNC_CSYNC			0x0004
@@ -311,6 +314,8 @@
 #define PS3AV_MODE_MASK				0x000F
 #define PS3AV_MODE_HDCP_OFF			0x1000	/* Retail PS3 product doesn't support this */
 #define PS3AV_MODE_DITHER			0x0800
+#define PS3AV_MODE_COLOR			0x0400
+#define PS3AV_MODE_WHITE			0x0200
 #define PS3AV_MODE_FULL				0x0080
 #define PS3AV_MODE_DVI				0x0040
 #define PS3AV_MODE_RGB				0x0020
@@ -529,9 +534,9 @@ struct ps3av_pkt_video_mode {
 	u32 video_out_format;	/* in: out format */
 	u32 video_format;	/* in: input frame buffer format */
 	u8 reserved3;
-	u8 reserved4;
+	u8 video_cl_cnv;	/* in: color conversion */
 	u16 video_order;	/* in: input RGB order */
-	u32 reserved5;
+	u32 reserved4;
 };
 
 /* video: format */
@@ -539,7 +544,8 @@ struct ps3av_pkt_video_format {
 	struct ps3av_send_hdr send_hdr;
 	u32 video_head;		/* in: head */
 	u32 video_format;	/* in: frame buffer format */
-	u16 reserved;
+	u8 reserved;
+	u8 video_cl_cnv;	/* in: color conversion */
 	u16 video_order;	/* in: input RGB order */
 };
 

-- 

^ permalink raw reply

* [patch 08/18] PS3: Kexec support
From: Geoff Levand @ 2007-06-06  3:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Paul Mackerras
In-Reply-To: <20070606024407.786638029@am.sony.com>

Fixup the core platform parts needed for kexec to work on the PS3.
 - Setup ps3_hpte_clear correctly.
 - Mask interrupts on irq removal.
 - Release all hypervisor resources.

Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
 arch/powerpc/platforms/ps3/htab.c      |   14 +-
 arch/powerpc/platforms/ps3/interrupt.c |  199 ++++++++++++++++++++-------------
 arch/powerpc/platforms/ps3/setup.c     |   29 ++--
 3 files changed, 147 insertions(+), 95 deletions(-)

--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -234,10 +234,18 @@ static void ps3_hpte_invalidate(unsigned
 
 static void ps3_hpte_clear(void)
 {
-	/* Make sure to clean up the frame buffer device first */
-	ps3fb_cleanup();
+	int result;
 
-	lv1_unmap_htab(htab_addr);
+	DBG(" -> %s:%d\n", __func__, __LINE__);
+
+	result = lv1_unmap_htab(htab_addr);
+	BUG_ON(result);
+
+	ps3_mm_shutdown();
+
+	ps3_mm_vas_destroy();
+
+	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
 void __init ps3_hpte_init(unsigned long htab_size)
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -91,6 +91,92 @@ struct ps3_private {
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
 
 /**
+ * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
+ * @virq: The assigned Linux virq.
+ *
+ * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
+ */
+
+static void ps3_chip_mask(unsigned int virq)
+{
+	struct ps3_private *pd = get_irq_chip_data(virq);
+	u64 bit = 0x8000000000000000UL >> virq;
+	u64 *p = &pd->bmp.mask;
+	u64 old;
+	unsigned long flags;
+
+	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+
+	local_irq_save(flags);
+	asm volatile(
+		     "1:	ldarx %0,0,%3\n"
+		     "andc	%0,%0,%2\n"
+		     "stdcx.	%0,0,%3\n"
+		     "bne-	1b"
+		     : "=&r" (old), "+m" (*p)
+		     : "r" (bit), "r" (p)
+		     : "cc" );
+
+	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+	local_irq_restore(flags);
+}
+
+/**
+ * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
+ */
+
+static void ps3_chip_unmask(unsigned int virq)
+{
+	struct ps3_private *pd = get_irq_chip_data(virq);
+	u64 bit = 0x8000000000000000UL >> virq;
+	u64 *p = &pd->bmp.mask;
+	u64 old;
+	unsigned long flags;
+
+	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+
+	local_irq_save(flags);
+	asm volatile(
+		     "1:	ldarx %0,0,%3\n"
+		     "or	%0,%0,%2\n"
+		     "stdcx.	%0,0,%3\n"
+		     "bne-	1b"
+		     : "=&r" (old), "+m" (*p)
+		     : "r" (bit), "r" (p)
+		     : "cc" );
+
+	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+	local_irq_restore(flags);
+}
+
+/**
+ * ps3_chip_eoi - HV end-of-interrupt.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls lv1_end_of_interrupt_ext().
+ */
+
+static void ps3_chip_eoi(unsigned int virq)
+{
+	const struct ps3_private *pd = get_irq_chip_data(virq);
+	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
+}
+
+/**
+ * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
+ */
+
+static struct irq_chip ps3_irq_chip = {
+	.typename = "ps3",
+	.mask = ps3_chip_mask,
+	.unmask = ps3_chip_unmask,
+	.eoi = ps3_chip_eoi,
+};
+
+/**
  * ps3_virq_setup - virq related setup.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
@@ -134,6 +220,8 @@ int ps3_virq_setup(enum ps3_cpu_binding 
 		goto fail_set;
 	}
 
+	ps3_chip_mask(*virq);
+
 	return result;
 
 fail_set:
@@ -225,6 +313,8 @@ int ps3_irq_plug_destroy(unsigned int vi
 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
 		pd->node, pd->cpu, virq);
 
+	ps3_chip_mask(virq);
+
 	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
 
 	if (result)
@@ -282,7 +372,9 @@ int ps3_event_receive_port_destroy(unsig
 {
 	int result;
 
-	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
+	pr_debug(" -> %s:%d virq %u\n", __func__, __LINE__, virq);
+
+	ps3_chip_mask(virq);
 
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
@@ -290,17 +382,13 @@ int ps3_event_receive_port_destroy(unsig
 		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
-	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
-	 * so don't call ps3_irq_plug_destroy() here.
+	/* Can't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
+	 * calls from interrupt context (smp_call_function).
 	 */
 
-	result = ps3_virq_destroy(virq);
-	BUG_ON(result);
-
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
 
 int ps3_send_event_locally(unsigned int virq)
 {
@@ -372,6 +460,13 @@ int ps3_sb_event_receive_port_destroy(co
 	result = ps3_event_receive_port_destroy(virq);
 	BUG_ON(result);
 
+	/* ps3_event_receive_port_destroy() destroys the IRQ plug,
+	 * so don't call ps3_irq_plug_destroy() here.
+	 */
+
+	result = ps3_virq_destroy(virq);
+	BUG_ON(result);
+
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
@@ -412,16 +507,23 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
 int ps3_io_irq_destroy(unsigned int virq)
 {
 	int result;
+	unsigned long outlet = virq_to_hw(virq);
 
-	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+	ps3_chip_mask(virq);
 
-	if (result)
-		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
+	/* lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
+	 * so call ps3_irq_plug_destroy() first.
+	 */
 
 	result = ps3_irq_plug_destroy(virq);
 	BUG_ON(result);
 
+	result = lv1_destruct_io_irq_outlet(outlet);
+
+	if (result)
+		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+
 	return result;
 }
 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -466,6 +568,7 @@ int ps3_vuart_irq_destroy(unsigned int v
 {
 	int result;
 
+	ps3_chip_mask(virq);
 	result = lv1_deconfigure_virtual_uart_irq();
 
 	if (result) {
@@ -514,9 +617,14 @@ int ps3_spe_irq_setup(enum ps3_cpu_bindi
 
 int ps3_spe_irq_destroy(unsigned int virq)
 {
-	int result = ps3_irq_plug_destroy(virq);
+	int result;
+
+	ps3_chip_mask(virq);
+
+	result = ps3_irq_plug_destroy(virq);
 	BUG_ON(result);
-	return 0;
+
+	return result;
 }
 
 
@@ -565,67 +673,6 @@ static void __maybe_unused _dump_mask(st
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static void ps3_chip_mask(unsigned int virq)
-{
-	struct ps3_private *pd = get_irq_chip_data(virq);
-	u64 bit = 0x8000000000000000UL >> virq;
-	u64 *p = &pd->bmp.mask;
-	u64 old;
-	unsigned long flags;
-
-	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
-
-	local_irq_save(flags);
-	asm volatile(
-		     "1:	ldarx %0,0,%3\n"
-		     "andc	%0,%0,%2\n"
-		     "stdcx.	%0,0,%3\n"
-		     "bne-	1b"
-		     : "=&r" (old), "+m" (*p)
-		     : "r" (bit), "r" (p)
-		     : "cc" );
-
-	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-	local_irq_restore(flags);
-}
-
-static void ps3_chip_unmask(unsigned int virq)
-{
-	struct ps3_private *pd = get_irq_chip_data(virq);
-	u64 bit = 0x8000000000000000UL >> virq;
-	u64 *p = &pd->bmp.mask;
-	u64 old;
-	unsigned long flags;
-
-	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
-
-	local_irq_save(flags);
-	asm volatile(
-		     "1:	ldarx %0,0,%3\n"
-		     "or	%0,%0,%2\n"
-		     "stdcx.	%0,0,%3\n"
-		     "bne-	1b"
-		     : "=&r" (old), "+m" (*p)
-		     : "r" (bit), "r" (p)
-		     : "cc" );
-
-	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-	local_irq_restore(flags);
-}
-
-static void ps3_chip_eoi(unsigned int virq)
-{
-	const struct ps3_private *pd = get_irq_chip_data(virq);
-	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
-}
-
-static struct irq_chip irq_chip = {
-	.typename = "ps3",
-	.mask = ps3_chip_mask,
-	.unmask = ps3_chip_unmask,
-	.eoi = ps3_chip_eoi,
-};
-
 static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
 {
 	set_irq_chip_data(virq, NULL);
@@ -637,7 +684,7 @@ static int ps3_host_map(struct irq_host 
 	pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
 		virq);
 
-	set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
+	set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
 
 	return 0;
 }
@@ -657,7 +704,7 @@ void __init ps3_register_ipi_debug_brk(u
 		cpu, virq, pd->bmp.ipi_debug_brk_mask);
 }
 
-unsigned int ps3_get_irq(void)
+static unsigned int ps3_get_irq(void)
 {
 	struct ps3_private *pd = &__get_cpu_var(ps3_private);
 	u64 x = (pd->bmp.status & pd->bmp.mask);
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -209,31 +209,28 @@ static int __init ps3_probe(void)
 #if defined(CONFIG_KEXEC)
 static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
 {
-	DBG(" -> %s:%d\n", __func__, __LINE__);
+	int result;
+	u64 ppe_id;
+	u64 thread_id = secondary ? 1 : 0;
+
+	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, secondary);
+	ps3_smp_cleanup_cpu(thread_id);
+
+	lv1_get_logical_ppe_id(&ppe_id);
+	result = lv1_configure_irq_state_bitmap(ppe_id, secondary ? 0 : 1, 0);
 
-	if (secondary) {
-		int cpu;
-		for_each_online_cpu(cpu)
-			if (cpu)
-				ps3_smp_cleanup_cpu(cpu);
-	} else
-		ps3_smp_cleanup_cpu(0);
+	/* seems to fail on second call */
+	DBG("%s:%d: lv1_configure_irq_state_bitmap (%d) %s\n", __func__,
+		__LINE__, secondary, ps3_result(result));
 
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
 static void ps3_machine_kexec(struct kimage *image)
 {
-	unsigned long ppe_id;
-
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
-	lv1_get_logical_ppe_id(&ppe_id);
-	lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
-	ps3_mm_shutdown();
-	ps3_mm_vas_destroy();
-
-	default_machine_kexec(image);
+	default_machine_kexec(image); // needs ipi, never returns.
 
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }

-- 

^ permalink raw reply

* [patch 07/18] PS3: Make ps3av.h usable from user space
From: Geoff Levand @ 2007-06-06  3:00 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Geert Uytterhoeven, Paul Mackerras, Masashi Kimoto
In-Reply-To: <20070606024407.786638029@am.sony.com>

The user applications to manage the PS3 AV modes can use values
defined in this header.

CC: Masashi Kimoto <Masashi_Kimoto@hq.scei.sony.co.jp>
Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
---
 include/asm-powerpc/Kbuild  |    1 +
 include/asm-powerpc/ps3av.h |    2 ++
 2 files changed, 3 insertions(+)

--- a/include/asm-powerpc/Kbuild
+++ b/include/asm-powerpc/Kbuild
@@ -34,6 +34,7 @@ unifdef-y += elf.h
 unifdef-y += nvram.h
 unifdef-y += param.h
 unifdef-y += posix_types.h
+unifdef-y += ps3av.h
 unifdef-y += ptrace.h
 unifdef-y += seccomp.h
 unifdef-y += signal.h
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -321,6 +321,7 @@
 #define PS3AV_MODE_RGB				0x0020
 
 
+#ifdef __KERNEL__
 /** command packet structure **/
 struct ps3av_send_hdr {
 	u16 version;
@@ -723,4 +724,5 @@ extern int ps3av_audio_mute(int);
 extern int ps3av_dev_open(void);
 extern int ps3av_dev_close(void);
 
+#endif /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_PS3AV_H_ */

-- 

^ permalink raw reply

* Re: [patch 11/18] PS3: System-bus modinfo attribute
From: Stephen Rothwell @ 2007-06-06  3:17 UTC (permalink / raw)
  To: Geoff Levand; +Cc: linuxppc-dev, Paul, David Woodhouse, Mackerras
In-Reply-To: <4666235C.10209@am.sony.com>

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

On Tue, 05 Jun 2007 20:00:44 -0700 Geoff Levand <geoffrey.levand@am.sony.com> wrote:
>
> +static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
> +			     char *buf)
> +{
> +	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
> +        int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id);

Broken whitespace ...

> +
> +        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;

And here.

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

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

^ permalink raw reply


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