All of lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] for target toolchain to be compiled
From: Jonathan dumaresq @ 2009-11-09 20:52 UTC (permalink / raw)
  To: buildroot

Hi,

I just installed a fresh kubuntu 9.10 and try to build my .config file that
I was able to do in 9.04. 

From What I see, the target toolchain is not compiled and failed to 
>compile
uclibc. 

Here a sample of the output.

/buildroot/PROJECTS/buildroot/atngw100/toolchain/bin/sed -i -e
's,^.*UCLIBC_HAS_WCHAR.*,UCLIBC_HAS_WCHAR=y,g'
/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc-0.9.30-avr32-2.1.5/.
oldconfig
/buildroot/PROJECTS/buildroot/atngw100/toolchain/bin/sed -i -e
's,^.*UCLIBC_HAS_PROGRAM_INVOCATION_NAME.*,UCLIBC_HAS_PROGRAM_INVOCATION_NAM
E=n,g'
/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc-0.9.30-avr32-2.1.5/.
oldconfig
cp -f
/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc-0.9.30-avr32-2.1.5/.
oldconfig
/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc-0.9.30-avr32-2.1.5/.
config
mkdir -p
/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc_dev/usr/include
mkdir -p /buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc_dev/usr/lib
mkdir -p /buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc_dev/lib
/usr/bin/make -j1 -C
/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc-0.9.30-avr32-2.1.5 \
                ARCH="avr32" \
 
PREFIX=/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc_dev/ \
                DEVEL_PREFIX=/usr/ \
 
RUNTIME_PREFIX=/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc_dev/
\
                HOSTCC="/usr/bin/gcc" \
                oldconfig
make[1]: Entering directory
`/buildroot/PROJECTS/buildroot/atngw100/toolchain/uClibc-0.9.30-avr32-2.1.5'
  MKDIR include/config
/bin/sh:
/buildroot/PROJECTS/buildroot/atngw100/build/staging_dir/usr/bin/avr32-linux
-uclibc-gcc: not found
make[2]:
/buildroot/PROJECTS/buildroot/atngw100/build/staging_dir/usr/bin/avr32-linux
-uclibc-gcc: Command not found
make[2]:
/buildroot/PROJECTS/buildroot/atngw100/build/staging_dir/usr/bin/avr32-linux
-uclibc-gcc: Command not found
/bin/sh:
/buildroot/PROJECTS/buildroot/atngw100/build/staging_dir/usr/bin/avr32-linux
-uclibc-gcc: not found
make[2]:
/buildroot/PROJECTS/buildroot/atngw100/build/staging_dir/usr/bin/avr32-linux
-uclibc-gcc: Command not found
make[2]:
/buildroot/PROJECTS/buildroot/atngw100/build/staging_dir/usr/bin/avr32-linux
-uclibc-gcc: Command not found

What File I should play with to get the toolchain compiled in ?

Jonathan

^ permalink raw reply

* Re: [PATCH-v4 0/4] OMAP: Adding flash support to SDP, ZOOM2 and LDP boards
From: Tony Lindgren @ 2009-11-09 20:52 UTC (permalink / raw)
  To: Vimal Singh; +Cc: linux-omap, vimal singh
In-Reply-To: <ce9ab5790911040328p215dede2v37db38a966a5bbd5@mail.gmail.com>

* Vimal Singh <vimal.newwork@gmail.com> [091104 03:28]:
> Hi Tony,
> 
> I did not see any comment on these patches. Could you please upstream these?
> Or, do you have some other plan?

Had few comments in your v9 patch, please fix those and then add
this to into omap for-next queue for the upcoming merge window.

Regards,

Tony

> 
> -
> vimal
> 
> On Mon, Oct 26, 2009 at 5:37 PM, Vimal Singh <vimal.newwork@gmail.com> wrote:
> > I posted a patch series for this sometime back and did not get any respose.. :(
> > http://marc.info/?l=linux-omap&m=125258227301958&w=2
> >
> > This time again I am posting these patches, with one more patch added
> > in series, after re-basing the patches on top of LO master head.
> >
> > This patch series adds flash support for NAND (in sdp, zoom2 and ldp),
> > OneNAND and NOR (in sdp)
> >
> > Tested on Zoom2 by Vikram, On SDP by Vimal
> >
> > [PATCH-v4 1/4] OMAP2/3: Add support for flash on SDP boards
> > [PATCH-v4 2/4] OMAP3: Add support for NAND on ZOOM2/LDP boards
> > [PATCH-v4 3/4] OMAP: Zoom2: Enable NAND and JFFS2 support in defconfig
> > [PATCH 4/4] OMAP: 3430SDP: Enable NAND in defconfig
> >
> >  arch/arm/configs/omap_3430sdp_defconfig      |  574 +++++++++++--------------
> >  arch/arm/configs/omap_zoom2_defconfig        |  334 ++++++++++----
> >  arch/arm/mach-omap2/Makefile                 |    2
> >  arch/arm/mach-omap2/board-2430sdp.c          |    2
> >  arch/arm/mach-omap2/board-3430sdp.c          |    2
> >  arch/arm/mach-omap2/board-ldp.c              |    2
> >  arch/arm/mach-omap2/board-sdp-flash.c        |  327 ++++++++++++++
> >  arch/arm/mach-omap2/board-zoom-flash.c       |  196 ++++++++
> >  arch/arm/mach-omap2/board-zoom2.c            |    2
> >  arch/arm/plat-omap/include/plat/board-sdp.h  |   15
> >  arch/arm/plat-omap/include/plat/board-zoom.h |   36 +
> >  arch/arm/plat-omap/include/plat/gpmc.h       |    2
> >  arch/arm/plat-omap/include/plat/nand.h       |    2
> >  14 files changed, 1095 insertions(+), 403 deletions(-)
> >
> > --
> > Regards,
> > Vimal Singh
> >
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] sh_mobile_ceu_camera: document the scaling and cropping algorithm
From: Guennadi Liakhovetski @ 2009-11-09 20:17 UTC (permalink / raw)
  To: Linux Media Mailing List

The sh_mobile_ceu_camera driver implements an advanced algorithm, combining
scaling and cropping on the client and on the host. Due to its complexity the
algorithm deserves separate documentation.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
 Documentation/video4linux/sh_mobile_ceu_camera.txt |  157 ++++++++++++++++++++
 1 files changed, 157 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/video4linux/sh_mobile_ceu_camera.txt

diff --git a/Documentation/video4linux/sh_mobile_ceu_camera.txt b/Documentation/video4linux/sh_mobile_ceu_camera.txt
new file mode 100644
index 0000000..2ae1634
--- /dev/null
+++ b/Documentation/video4linux/sh_mobile_ceu_camera.txt
@@ -0,0 +1,157 @@
+	Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
+	=======================================================================
+
+Terminology
+-----------
+
+sensor scales: horizontal and vertical scales, configured by the sensor driver
+host scales: -"- host driver
+combined scales: sensor_scale * host_scale
+
+
+Generic scaling / cropping scheme
+---------------------------------
+
+-1--
+|
+-2-- -\
+|      --\
+|         --\
++-5-- -\     -- -3--
+|       ---\
+|           --- -4-- -\
+|                      -\
+|                        - -6--
+|
+|                        - -6'-
+|                      -/
+|           --- -4'- -/
+|       ---/
++-5'- -/
+|            -- -3'-
+|         --/
+|      --/
+-2'- -/
+|
+|
+-1'-
+
+Produced by user requests:
+
+S_CROP(left / top = (5) - (1), width / height = (5') - (5))
+S_FMT(width / height = (6') - (6))
+
+Here:
+
+(1) to (1') - whole max width or height
+(1) to (2)  - sensor cropped left or top
+(2) to (2') - sensor cropped width or height
+(3) to (3') - sensor scale
+(3) to (4)  - CEU cropped left or top
+(4) to (4') - CEU cropped width or height
+(5) to (5') - reverse sensor scale applied to CEU cropped width or height
+(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
+(6) to (6') - CEU scale - user window
+
+
+S_FMT
+-----
+
+Do not touch input rectangle - it is already optimal.
+
+1. Calculate current sensor scales:
+
+	scale_s = ((3') - (3)) / ((2') - (2))
+
+2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
+current sensor scales onto input window - this is user S_CROP:
+
+	width_u = (5') - (5) = ((4') - (4)) * scale_s
+
+3. Calculate new combined scales from "effective" input window to requested user
+window:
+
+	scale_comb = width_u / ((6') - (6))
+
+4. Calculate sensor output window by applying combined scales to real input
+window:
+
+	width_s_out = ((2') - (2)) / scale_comb
+
+5. Apply iterative sensor S_FMT for sensor output window.
+
+	subdev->video_ops->s_fmt(.width = width_s_out)
+
+6. Retrieve sensor output window (g_fmt)
+
+7. Calculate new sensor scales:
+
+	scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
+
+8. Calculate new CEU crop - apply sensor scales to previously calculated
+"effective" crop:
+
+	width_ceu = (4')_new - (4)_new = width_u / scale_s_new
+	left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
+
+9. Use CEU cropping to crop to the new window:
+
+	ceu_crop(.width = width_ceu, .left = left_ceu)
+
+10. Use CEU scaling to scale to the requested user window:
+
+	scale_ceu = width_ceu / width
+
+
+S_CROP
+------
+
+If old scale applied to new crop is invalid produce nearest new scale possible
+
+1. Calculate current combined scales.
+
+	scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
+
+2. Apply iterative sensor S_CROP for new input window.
+
+3. If old combined scales applied to new crop produce an impossible user window,
+adjust scales to produce nearest possible window.
+
+	width_u_out = ((5') - (5)) / scale_comb
+
+	if (width_u_out > max)
+		scale_comb = ((5') - (5)) / max;
+	else if (width_u_out < min)
+		scale_comb = ((5') - (5)) / min;
+
+4. Issue G_CROP to retrieve actual input window.
+
+5. Using actual input window and calculated combined scales calculate sensor
+target output window.
+
+	width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
+
+6. Apply iterative S_FMT for new sensor target output window.
+
+7. Issue G_FMT to retrieve the actual sensor output window.
+
+8. Calculate sensor scales.
+
+	scale_s = ((3') - (3)) / ((2') - (2))
+
+9. Calculate sensor output subwindow to be cropped on CEU by applying sensor
+scales to the requested window.
+
+	width_ceu = ((5') - (5)) / scale_s
+
+10. Use CEU cropping for above calculated window.
+
+11. Calculate CEU scales from sensor scales from results of (10) and user window
+from (3)
+
+	scale_ceu = calc_scale(((5') - (5)), &width_u_out)
+
+12. Apply CEU scales.
+
+--
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
-- 
1.6.2.4


^ permalink raw reply related

* Re: [PATCH-v4 1/4] OMAP2/3: Add support for flash on SDP boards
From: Tony Lindgren @ 2009-11-09 20:51 UTC (permalink / raw)
  To: Vimal Singh; +Cc: linux-omap, vimal singh
In-Reply-To: <ce9ab5790910260510g6f2a731fqb87388bd5dee6a84@mail.gmail.com>

Hi,

Few comments below.

* Vimal Singh <vimal.newwork@gmail.com> [091026 05:10]:
> From 92c416f513df62cc0ad75b61639df27f2857b641 Mon Sep 17 00:00:00 2001
> From: Vimal Singh <vimalsingh@ti.com>
> Date: Mon, 26 Oct 2009 14:24:18 +0530
> Subject: [PATCH] OMAP2/3: Add support for flash on SDP boards
> 
> Add support for flash on SDP boards. NAND, NOR and OneNAND
> are supported.
> 
> Only tested on 3430SDP (ES2 and ES3.1), somebody please test on
> 2430SDP and check the chips select for 2430SDP.
> 
> Also note that:
> For OneNAND: in the earlier 2430SDP code the kernel partition
> was set to only 1MB instead of 2MB on 3430SDP. If people want
> the old partition sizes back on 2430SDP, please provide a patch.
> 
> For NAND: 'U-Boot', 'Boot Env' and 'Kernel' partitions sizes increased
> by few blocks to provide few spare blocks for NAND bab block management
> in u-boot. If people want old partition sizes, please provide a patch.
> 
> Signed-off-by: Vimal Singh <vimalsingh@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> ---
>  arch/arm/mach-omap2/Makefile                |    2 +
>  arch/arm/mach-omap2/board-2430sdp.c         |    2 +
>  arch/arm/mach-omap2/board-3430sdp.c         |    2 +
>  arch/arm/mach-omap2/board-sdp-flash.c       |  327 +++++++++++++++++++++++++++
>  arch/arm/plat-omap/include/plat/board-sdp.h |   15 ++
>  arch/arm/plat-omap/include/plat/gpmc.h      |    2 +
>  6 files changed, 350 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/board-sdp-flash.c
>  create mode 100644 arch/arm/plat-omap/include/plat/board-sdp.h
> 
> diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
> index 03cb4fc..627f500 100644
> --- a/arch/arm/mach-omap2/Makefile
> +++ b/arch/arm/mach-omap2/Makefile
> @@ -53,6 +53,7 @@ obj-$(CONFIG_OMAP_IOMMU)		+= $(iommu-y)
>  obj-$(CONFIG_MACH_OMAP_GENERIC)		+= board-generic.o
>  obj-$(CONFIG_MACH_OMAP_H4)		+= board-h4.o
>  obj-$(CONFIG_MACH_OMAP_2430SDP)		+= board-2430sdp.o \
> +					   board-sdp-flash.o \
>  					   mmc-twl4030.o
>  obj-$(CONFIG_MACH_OMAP_APOLLON)		+= board-apollon.o
>  obj-$(CONFIG_MACH_OMAP3_BEAGLE)		+= board-omap3beagle.o \
> @@ -66,6 +67,7 @@ obj-$(CONFIG_MACH_OMAP3EVM)		+= board-omap3evm.o \
>  obj-$(CONFIG_MACH_OMAP3_PANDORA)	+= board-omap3pandora.o \
>  					   mmc-twl4030.o
>  obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o \
> +					   board-sdp-flash.o \
>  					   mmc-twl4030.o
>  obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
>  obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
> diff --git a/arch/arm/mach-omap2/board-2430sdp.c
> b/arch/arm/mach-omap2/board-2430sdp.c
> index db9374b..5676ab9 100644
> --- a/arch/arm/mach-omap2/board-2430sdp.c
> +++ b/arch/arm/mach-omap2/board-2430sdp.c
> @@ -38,6 +38,7 @@
>  #include <plat/usb.h>
>  #include <plat/gpmc-smc91x.h>
> 
> +#include <plat/board-sdp.h>
>  #include "mmc-twl4030.h"
> 
>  #define SDP2430_CS0_BASE	0x04000000
> @@ -205,6 +206,7 @@ static void __init omap_2430sdp_init(void)
>  	twl4030_mmc_init(mmc);
>  	usb_musb_init();
>  	board_smc91x_init();
> +	sdp_flash_init();
> 
>  	/* Turn off secondary LCD backlight */
>  	ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight");
> diff --git a/arch/arm/mach-omap2/board-3430sdp.c
> b/arch/arm/mach-omap2/board-3430sdp.c
> index a3c1271..4497ded 100644
> --- a/arch/arm/mach-omap2/board-3430sdp.c
> +++ b/arch/arm/mach-omap2/board-3430sdp.c
> @@ -41,6 +41,7 @@
>  #include <plat/control.h>
>  #include <plat/gpmc-smc91x.h>
> 
> +#include <plat/board-sdp.h>
>  #include "sdram-qimonda-hyb18m512160af-6.h"
>  #include "mmc-twl4030.h"
> 
> @@ -511,6 +512,7 @@ static void __init omap_3430sdp_init(void)
>  	omap_serial_init();
>  	usb_musb_init();
>  	board_smc91x_init();
> + 	sdp_flash_init();
>  	enable_board_wakeup_source();
>  	usb_ehci_init(&ehci_pdata);
>  }
> diff --git a/arch/arm/mach-omap2/board-sdp-flash.c
> b/arch/arm/mach-omap2/board-sdp-flash.c
> new file mode 100644
> index 0000000..a19327d
> --- /dev/null
> +++ b/arch/arm/mach-omap2/board-sdp-flash.c
> @@ -0,0 +1,327 @@
> +/*
> + * arch/arm/mach-omap2/board-sdp-flash.c
> + *
> + * Copyright (C) 2009 Nokia Corporation
> + * Copyright (C) 2007 Texas Instruments
> + *
> + * Modified from mach-omap2/board-3430sdp-flash.c
> + * Author: Vimal Singh <vimalsingh@ti.com>
> + *
> + * 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.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/platform_device.h>
> +#include <linux/mtd/mtd.h>
> +#include <linux/mtd/partitions.h>
> +#include <linux/io.h>
> +
> +#include <asm/mach/flash.h>
> +#include <plat/onenand.h>
> +#include <plat/gpmc.h>
> +#include <plat/nand.h>
> +
> +#define REG_FPGA_REV			0x10
> +#define REG_FPGA_DIP_SWITCH_INPUT2	0x60
> +#define MAX_SUPPORTED_GPMC_CONFIG	3
> +
> +/* various memory sizes */
> +#define FLASH_SIZE_SDPV1	SZ_64M
> +#define FLASH_SIZE_SDPV2	SZ_128M
> +
> +#define FLASH_BASE_SDPV1	0x04000000 /* NOR flash (64 Meg aligned) */
> +#define FLASH_BASE_SDPV2	0x10000000 /* NOR flash (256 Meg aligned) */
> +
> +#define DEBUG_BASE		0x08000000 /* debug board */
> +
> +#define PDC_NOR		1
> +#define PDC_NAND	2
> +#define PDC_ONENAND	3
> +#define DBG_MPDB	4
> +
> +/* REVISIT: Does for some x, chip_sel_sdp[x] maches for 2430 SDP ? */
> +
> +/* SDP3430 V2 Board CS organization
> + * Different from SDP3430 V1. Now 4 switches used to specify CS
> + */
> +static const unsigned char chip_sel_sdp[][GPMC_CS_NUM] = {
> +/* GPMC CS Indices (ON=0, OFF=1)*/
> +/* S8-1 2 3 4 IDX   CS0,       CS1,      CS2 ..                    CS7  */
> +/*ON ON ON ON*/{PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0},
> +/*ON ON ON OFF*/{PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0},
> +/*ON ON OFF ON */{PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0},
> +};

The comments above look confusing, how about this instead:

/*
 * SDP3430 V2 Board CS organization
 * Different from SDP3430 V1. Now 4 switches used to specify CS
 *
 * See also the Switch S8 settings in the comments.
 *
 * REVISIT: Add support for 2430 SDP
 */
static const unsigned char chip_sel_sdp[][GPMC_CS_NUM] = {	
	{ PDC_NOR, PDC_NAND, PDC_ONENAND, DBG_MPDB, 0, 0, 0, 0 }, /* S8:1111 */
	{ PDC_ONENAND, PDC_NAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0 }, /* S8:1110 */
	{ PDC_NAND, PDC_ONENAND, PDC_NOR, DBG_MPDB, 0, 0, 0, 0 }, /* S8:1101 */
};


> +static struct mtd_partition sdp_nor_partitions[] = {
> +	/* bootloader (U-Boot, etc) in first sector */
> +	{
> +		.name		= "Bootloader-NOR",
> +		.offset		= 0,
> +		.size		= SZ_256K,
> +		.mask_flags	= MTD_WRITEABLE, /* force read-only */
> +	},
> +	/* bootloader params in the next sector */
> +	{
> +		.name		= "Params-NOR",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= SZ_256K,
> +		.mask_flags	= 0,
> +	},
> +	/* kernel */
> +	{
> +		.name		= "Kernel-NOR",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= SZ_2M,
> +		.mask_flags	= 0
> +	},
> +	/* file system */
> +	{
> +		.name		= "Filesystem-NOR",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= MTDPART_SIZ_FULL,
> +		.mask_flags	= 0
> +	}
> +};
> +
> +static struct flash_platform_data sdp_nor_data = {
> +	.map_name	= "cfi_probe",
> +	.width		= 2,
> +	.parts		= sdp_nor_partitions,
> +	.nr_parts	= ARRAY_SIZE(sdp_nor_partitions),
> +};
> +
> +static struct resource sdp_nor_resource = {
> +	.start		= 0,
> +	.end		= 0,
> +	.flags		= IORESOURCE_MEM,
> +};
> +
> +static struct platform_device sdp_nor_device = {
> +	.name		= "omapflash",
> +	.id		= 0,
> +	.dev		= {
> +			.platform_data = &sdp_nor_data,
> +	},
> +	.num_resources	= 1,
> +	.resource	= &sdp_nor_resource,
> +};
> +
> +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
> +		defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
> +
> +static struct mtd_partition board_onenand_partitions[] = {
> +	{
> +		.name		= "X-Loader-OneNAND",
> +		.offset		= 0,
> +		.size		= 4 * (64 * 2048),
> +		.mask_flags	= MTD_WRITEABLE  /* force read-only */
> +	},
> +	{
> +		.name		= "U-Boot-OneNAND",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= 2 * (64 * 2048),
> +		.mask_flags	= MTD_WRITEABLE  /* force read-only */
> +	},
> +	{
> +		.name		= "U-Boot Environment-OneNAND",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= 1 * (64 * 2048),
> +	},
> +	{
> +		.name		= "Kernel-OneNAND",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= 16 * (64 * 2048),
> +	},
> +	{
> +		.name		= "File System-OneNAND",
> +		.offset		= MTDPART_OFS_APPEND,
> +		.size		= MTDPART_SIZ_FULL,
> +	},
> +};
> +
> +static struct omap_onenand_platform_data board_onenand_data = {
> +	.parts		= board_onenand_partitions,
> +	.nr_parts	= ARRAY_SIZE(board_onenand_partitions),
> +	.dma_channel	= -1,   /* disable DMA in OMAP OneNAND driver */
> +};
> +
> +
> +static void __init board_onenand_init(void)
> +{
> +	gpmc_onenand_init(&board_onenand_data);
> +}
> +
> +#else
> +
> +static inline void board_onenand_init(void)
> +{
> +}
> +#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */
> +
> +static struct mtd_partition sdp_nand_partitions[] = {
> +	/* All the partition sizes are listed in terms of NAND block size */
> +	{
> +		.name		= "X-Loader-NAND",
> +		.offset		= 0,
> +		.size		= 4 * (64 * 2048),
> +		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
> +	},
> +	{
> +		.name		= "U-Boot-NAND",
> +		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x80000 */
> +		.size		= 10 * (64 * 2048),
> +		.mask_flags	= MTD_WRITEABLE,	/* force read-only */
> +	},
> +	{
> +		.name		= "Boot Env-NAND",
> +
> +		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x1c0000 */
> +		.size		= 6 * (64 * 2048),
> +	},
> +	{
> +		.name		= "Kernel-NAND",
> +		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x280000 */
> +		.size		= 40 * (64 * 2048),
> +	},
> +	{
> +		.name		= "File System - NAND",
> +		.size		= MTDPART_SIZ_FULL,
> +		.offset		= MTDPART_OFS_APPEND,	/* Offset = 0x780000 */
> +	},
> +};
> +
> +static struct omap_nand_platform_data sdp_nand_data = {
> +	.parts		= sdp_nand_partitions,
> +	.nr_parts	= ARRAY_SIZE(sdp_nand_partitions),
> +	.nand_setup	= NULL,
> +	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
> +	.dev_ready	= NULL,
> +};
> +
> +static struct resource sdp_nand_resource = {
> +	.flags		= IORESOURCE_MEM,
> +};
> +
> +static struct platform_device sdp_nand_device = {
> +	.name			= "omap2-nand",
> +	.id			= 0,
> +	.dev			= {
> +		.platform_data	= &sdp_nand_data,
> +	},
> +	.num_resources	= 1,
> +	.resource		= &sdp_nand_resource,
> +};
> +
> +/**
> + * get_gpmc0_type - Reads the FPGA DIP_SWITCH_INPUT_REGISTER2 to get
> + * the various cs values.
> + */
> +static u8 get_gpmc0_type(void)
> +{
> +	u8 cs;
> +	void __iomem *fpga_map_addr;
> +	fpga_map_addr = ioremap(DEBUG_BASE, 4096);
> +	/* if ioremap does not return a valid pointer, exit */

This seems like an unnecessary comment.


> +	if (!fpga_map_addr)
> +		return -ENOMEM;
> +
> +	if (!(__raw_readw(fpga_map_addr + REG_FPGA_REV))) {
> +		/* we dont have an DEBUG FPGA??? */
> +		/* Depend on #defines!! default to strata boot return param */
> +		return 0x0;
> +	}

Maybe return -ENODEV here too instead?


> +	/* S8-DIP-OFF = 1, S8-DIP-ON = 0 */
> +	cs = (u8) (__raw_readw(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2)
> +			& 0xF);

Do you need the cast here?

Also, generally the hex numbers are written lower case in Linux.


> +	/* ES2.0 SDP's onwards 4 dip switches are provided for CS */
> +	if (omap_rev() >= OMAP3430_REV_ES1_0)
> +		/* change (S8-1:4=DS-2:0) to (S8-4:1=DS-2:0) */
> +		cs = ((cs & 8) >> 3) | ((cs & 4) >> 1) |
> +			((cs & 2) << 1) | ((cs & 1) << 3);
> +	else
> +		/* change (S8-1:3=DS-2:0) to (S8-3:1=DS-2:0) */
> +		cs = ((cs & 4) >> 2) | (cs & 2) | ((cs & 1) << 2);
> +	iounmap(fpga_map_addr);
> +	return cs;
> +}
> +
> +/**
> + * sdp3430_flash_init - Identify devices connected to GPMC and register.
> + *
> + * @return - void.
> + */
> +void __init sdp_flash_init(void)
> +{
> +	u8		cs = 0;
> +	u8		nandcs = GPMC_CS_NUM + 1;
> +	u8		onenandcs = GPMC_CS_NUM + 1;
> +	u8		idx;
> +	unsigned char	*config_sel = NULL;
> +
> +	/* REVISIT: Is this return correct idx for 2430 SDP?
> +	 * for which cs configuration matches for 2430 SDP?
> +	 */
> +	idx = get_gpmc0_type();
> +	if (idx >= MAX_SUPPORTED_GPMC_CONFIG) {
> +		printk(KERN_ERR "Invalid Chip select Selection..\
> +				sdp3430_flash_init returned with error\n");
> +		return;
> +	}

In general, you can have multiple format strings to printk:

		printk(KERN_ERR "Some text here "
				"with more text here\n");

But in this case, how about just use:

		printk(KERN_ERR "sdp_flash: Invalid chip select: %d\n", cs);

> +	config_sel = (unsigned char *)(chip_sel_sdp[idx]);

The casting here should not be needed?


> +
> +	/* Configure start address and size of NOR device */
> +	if (omap_rev() >= OMAP3430_REV_ES1_0) {
> +		sdp_nor_resource.start	= FLASH_BASE_SDPV2;
> +		sdp_nor_resource.end	= FLASH_BASE_SDPV2
> +						+ FLASH_SIZE_SDPV2 - 1;
> +	} else {
> +		sdp_nor_resource.start	= FLASH_BASE_SDPV1;
> +		sdp_nor_resource.end	= FLASH_BASE_SDPV1
> +						+ FLASH_SIZE_SDPV1 - 1;
> +	}
> +
> +	if (platform_device_register(&sdp_nor_device) < 0)
> +		printk(KERN_ERR "Unable to register NOR device\n");
> +
> +	while (cs < GPMC_CS_NUM) {
> +		switch (config_sel[cs]) {
> +		case PDC_NAND:
> +			if (nandcs > GPMC_CS_NUM)
> +				nandcs = cs;
> +			break;
> +		case PDC_ONENAND:
> +			if (onenandcs > GPMC_CS_NUM)
> +				onenandcs = cs;
> +			break;
> +		};
> +		cs++;
> +	}
> +
> +	if (onenandcs > GPMC_CS_NUM) {
> +		printk(KERN_INFO "OneNAND: Unable to find configuration "
> +				" in GPMC\n ");
> +	} else {
> +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
> +		defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
> +
> +		board_onenand_data.cs = onenandcs;
> +#endif /* CONFIG_MTD_ONENAND_OMAP2 || CONFIG_MTD_ONENAND_OMAP2_MODULE */
> +		board_onenand_init();
> +	}

To me it the ifdef above is not needed if you pass the cs to the function:
		board_onenand_init(cs);

> +
> +	if (nandcs > GPMC_CS_NUM) {
> +		printk(KERN_INFO "NAND: Unable to find configuration "
> +				" in GPMC\n ");
> +	} else {
> +		sdp_nand_data.cs = nandcs;
> +		sdp_nand_data.gpmc_cs_baseaddr = (void *)(OMAP34XX_GPMC_VIRT +
> +					GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
> +		sdp_nand_data.gpmc_baseaddr = (void *) (OMAP34XX_GPMC_VIRT);
> +
> +		if (platform_device_register(&sdp_nand_device) < 0)
> +			printk(KERN_ERR "Unable to register NAND device\n");
> +
> +	}

This should be done in gpmc.c instead. If we don't have a function in gpmc.c
for doing this, let's rather add a function there.


> +}
> diff --git a/arch/arm/plat-omap/include/plat/board-sdp.h
> b/arch/arm/plat-omap/include/plat/board-sdp.h
> new file mode 100644
> index 0000000..632f21a
> --- /dev/null
> +++ b/arch/arm/plat-omap/include/plat/board-sdp.h
> @@ -0,0 +1,15 @@
> +/*
> + *  arch/arm/plat-omap/include/plat/board-sdp.h
> + *
> + *  Information structures for SDP-specific board config data
> + *
> + *  Copyright (C) 2009 Nokia Corporation
> + *  Copyright (C) 2009 Texas Instruments
> + *
> + * 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.
> + */
> +
> +extern void sdp_flash_init(void);
> +
> diff --git a/arch/arm/plat-omap/include/plat/gpmc.h
> b/arch/arm/plat-omap/include/plat/gpmc.h
> index 9c99cda..c752ab7 100644
> --- a/arch/arm/plat-omap/include/plat/gpmc.h
> +++ b/arch/arm/plat-omap/include/plat/gpmc.h
> @@ -27,6 +27,8 @@
> 
>  #define GPMC_CONFIG		0x50
>  #define GPMC_STATUS		0x54
> +#define GPMC_CS0_BASE		0x60
> +#define GPMC_CS_SIZE		0x30
> 
>  #define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
>  #define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
> -- 
> 1.5.5

^ permalink raw reply

* OE weekly changelog 2009-11-02 to 2009-11-09
From: Cliff Brake @ 2009-11-09 20:46 UTC (permalink / raw)
  To: openembedded-devel

OE weekly changelog 2009-11-02 to 2009-11-09

Alexandre Tisserant (1):
  gecko-mediaplayer: make ai-flash.js work with midori as well

Andrea Adami (6):
  kexecboot-cfg: Deploy default icon. Bump PR.
  kexecboot-cfg: Center OpenEmbedded 32x32 icon.
  kexecboot: remove older releases incompatible with new boot.cfg.
  checksums.ini: purge deprecated kexecboot entries.
  kexecboot-cfg: sync boot.cfg with upstream. Bump PR.
  kexecboot_git: bump to 40e5be92f045f2a7cfc918f4b1acc42f6cc013e9 and

Artur Wronowski (2):
  libpar2: new recipe; multi-part archives library
  nzbget: new recipe; a command-line based binary newsgrabber for nzb files

Brijesh Singh (6):
  gstreamer-ti svn: bump up svn rev and add boot script
  bc-cat-omap 0.1.0: add recipe to build bc-cat module.
  libgles-omap3.inc: use libpvrPVR2D_FRONTWSEGL.so
  task-gstreamer-ti: do not install gst-ti on am3517 platform
  ti-demo-x11-image: add task and image for build x11 based demo image for TI
  ti-dmai_svn: bumup svn rev

Chris Larson (3):
  prelink: pull in /etc/cron.daily/prelink in the postinst.
  autofs: switch to a .inc.
  opkg: Don't prompt for user input from stdin if it's not a tty.

David Lanzendörfer (1):
  linux-replicant: new recipe; kernel tree for HTC devices

David-John Willis (7):
  omap3-pandora.conf: Merge in latest machine file.
  omap3-pandora.conf: Line endings.
  u-boot-omap3pandora: Bump SRCREV to fix issue with loading without an EXT bo
  xserver-xorg-conf: Update xorg.conf for the omap3-pandora. i.e. cut out a lo
  avahi: Bump packages to 0.6.25 (security fix) and add checksums.
  xfce4-panel: Add new upstream 4.6.2 release and checksums.
  tracker: Add 0.6.95 release and series of patches to support cross compile.

Frans Meulenbroeks (32):
  myththemes: created recipe
  cdparanoia: created svn recipe
  taglib: also install .tcc files in staging
  mythplugins: added mythmusic; fixed configure patch, remove unneeded MythBac
  mythplugins: fixed remaining staging issues
  mysql: fixed mysql_config in staging
  mythplugins: added zoneminder, cleaned up images in do_stage
  qt4-x11-free.inc: bumped PR to force recompilation so it uses the fixed mysq
  mysql: changed postinstall: pid file goes to /var/run/mysql i.s.o /var/run a
  mythplugins: add zoneminder package
  mythtv: added dependency to glibc-gconv-utf-16
  mysql: moved pid dir from /var/run/mysql to /var/lib/mysql as /var/run is cr
  mysql5: created recipe
  mythtv: added mc.sql; introduced database package for that one (similar to d
  xmltv: moved from 0.5.54 to 0.5.56
  checksusm: added checksum for xmltv 0.5.56
  libxml-twig-perl: forgot to bump PR, here it is
  mysql5: added missing file misc.m4.patch
  mysql5: added DEPENDS to -native, reworked packaging
  grun: added recipe (created by tovarish, bugzilla 5067)
  texi2html: added recipe contributed by Lynn Lin (bugzilla #4759)
  help2man: added recipe created by Lynn Lin (bugzilla #4774)
  mysql5: fixed packaging

Henning Heinold (2):
  cmake.bbclass: use staging from autotools too
  boost: add new version 1.4.0

Holger Hans Peter Freyther (1):
  base.bbclass: Better error message in case the Config Parser fails

Jeremy Lainé (4):
  linux-2.6.31: update boc01 RTC driver for upstream submission
  ntp-4.2.4p7: invoke ntpdate using if-up.d, not an init script
  ntp-4.2.4p7: make it possible to call hwclock from ntpdate if-up.d script
  bitbake.conf: add support for "cpio.lzma" images

Jeremy Puhlman (2):
  neon: Add m4 dir to autoreconf.
  autofs: pass RANLIB into the build.

Khem Raj (4):
  proxy-libintl_20080418.bb: Fix QA error missing GNU_HASH
  uclibc-nptl: Update to latest tip of branch
  eglibc_svn.bb: Update to latest svn tip.
  x86.conf: Fix typo in comments

Koen Kooi (59):
  checksums: merge in checksums from openpandora repo
  abiword: fix shlib packaging
  firefox: add 3.5.4
  abiword 2.8.1: package abicollab certs as well
  firefox 3.5.4: fixup .pc files
  angstrom feed sorter: fix typo
  angstrom feed builder: clean iso-codes as well
  gecko-mediaplayer: update for ff 3.5.4
  dsplink: remove reference to asm/page.h
  angstrom uboot scripts: change to mem=99M for omap3 since gst-ti is less hun
  xserver-xorg-conf: simply touchbook config
  gst-plugins: blacklist -static for meta packages as well
  libxml-parser-perl: add 2.36
  angstrom feed builder: also clean perl and perl-native during architecture c
  libgles-omap3: adjust for future releases
  gthumb: fix packaging
  gecko-media-player: add missing patch
  opkg: bump SRCREV to r240
  expedite, evas: don't turn of the GL engine forcefully
  efl: bump SRCREV to 43437
  e* bbclass: fix up PACKAGES (again!)
  exalt: update to current form
  linux-omap 2.6.29: backport some relocations from .31, this is needed if you
  omap3 machines: don't drag in omap3-sgx-modules by default
  opencv: bump SRCREV to just after 2.0.0 release
  u-boot: fix beagle fw_env.conf
  gnome-themes: delete obsolete versions
  mythtv 0.22rcX: only add glibc-gconv stuff for glibc build
  boost 1.36: various ARM fixups:
  asio: bump PR to get boost fixes
  angstrom: raise default pref in mplayer recipe as well
  checksums: sort and add missing checksum
  squashfs-tools: fix up native version
  linux-omap-pm 2.6.29: cleanup some touchbook stuff
  gdm: tweak initscript and add grep to depends since busybox grep doesn't do
  gdm: add tcp-wrappers to DEPENDS, fix typo in initscript
  sqlite3: add 3.6.20
  omap3-touchbook: ship both omapfb and fbdev drivers
  xserver-xorg-conf: switch to fbdev driver for touchbook till the vrfb bug ge
  gecko-mediaplayer: fix packaging
  linux-omap-pm 2.6.29: add hack to get asoc to register on the touchbook
  arora: add 0.10.1. Arora is a qtwebkit based browser.
  arora: factor common stuff into .inc and add qt4/embedded version
  libxml-twig-perl: as noted previously, upstream are idiots and keep replacin
  firefix: add 3.5.5
  gecko-mediaplayer: adjust for firefo 3.5.5
  angstrom package uploader: update blacklist
  gecko-mediaplayer: remove fragile hardcoded symlink
  nautilus: add 2.28.1
  sqlite3: add dep on tcl-native
  gnome-icon-theme: clean out old versions, having some off them (but not all)
  gnome-icon-theme: bump PR
  gnome bbclass: delete more scrollkeeper junk
  gnome-system-tools, gnome-terminal: bump PR to get rid of scrollkeeper junk
  gnome-icon-theme: while I'm at it, run it through oe-stylize
  asciidoc: add 8.5.1
  u-boot: fix touchbook fw_env.config

Marcin Juszkiewicz (9):
  matchbox-config-gtk: sync with Poky
  linux-bug: bump SRCREV, enable more modules
  openvpn: added 2.1rc20 and enabled reading passwords from file
  usbutils: added 0.86
  checksums.ini: added usbutils and openvpn
  transmission: added 1.76
  transmission: improve packaging
  transmission: fix breakage of "r3" version - GUI in PN-gui, daemon in PN
  java.bbclass: fixed oe_jarinstall for broken symlinks

Martin Jansa (1):
  eglibc: updated armv4t-interworking.patch

Matthew Dombroski (1):
  qmake2.bbclass: Add lupdate and lrelease.

Michael 'Mickey' Lauer (1):
  conf/machine/htcdream.conf: mention commercial device names in description

Michael Smith (1):
  fastjar 0.98: add non-native recipe

Otavio Salvador (1):
  chicken.inc: fix install and compilation issues

Paul Eggleton (1):
  qte: fix build failure with modern kernels due to removal of asm/page.h

Petr Štetiar (5):
  geodegx: Linux 2.6.31.4
  geodegx: Fix glibc configure error
  libgsf: fix compile error, add missing dependency on gtk+
  obex-data-server: fix compile error, add missing dependency on gtk+
  wv: fix compile problem

Ricardo Salveti (1):
  eject-2.1.5: adding HOMEPAGE and fixing SRC_URI

Robert Nelson (1):
  linux-omap 2.6.29: fix FIFO issues with large transfers on the MUSB controll

Robert P. J. Day (3):
  usermanual: Aesthetic fix in chapter 1.
  User manual typoes and aesthetics, chapter 2 only.
  User Manual: Warn readers about mmap and SELinux issue.

Sebastian Spaeth (6):
  connman: include connman_0.46 (mv'd from connman_0.19)
  connman: add checksums for 0.46
  vala: add version 0.7.8 and checksums
  vala-native: add 0.7.8
  vala vala-native: Make use of GNOME_MIRROR in SRC_URI

Stanislav Brabec (11):
  linux-rp-2.6.26 for spitz and akita: Added netfilter support. Disabled two d
  gpsd: Removed custom do_stage.
  mplayer-svn: Worked around internal compiler error on iwmmxt.
  angstrom-2008.1.conf: Must use mplayer-svn, anything older is incompatible w
  prismstumbler-0.7.3+0.7.4pre1: Use much simper and more robust libgps check.
  balsa-2.4.1: Depends on gnome-icon-theme.
  lame: Fix possible linking QA error.
  lame: Update to version 3.98.2.
  gdb-7.0: Always use --enable-static to work-around possible linking problems
  ncurses: Always use --enable-static to work-around possible linking problems
  gnome-icon-theme-2.28.0: Set it as arch-independent package.

Steffen Sledz (1):
  busybox-1.11.3: undefined reference __cpu_to_be16 fixed for busybox-static

Thomas Kunze (1):
  tune-strongarm.inc: add EXTRA_FEED_ARCHS

Bugs fixed:

bug_id resolution        short_desc
481 FIXED        GPE-mini-browser scrolls page when spacebar pressed
in text entry field
1010 FIXED       gpesyncd is missing po/POTFILES.in
1105 INVALID     RFE: Timer app
1650 FIXED       task-base does not install ohci-hcd module for usbhost mchines
3589 WONTFIX     OE don' t create root image with ext3 FS on AMD64
5123 FIXED       meta-toolchain-gpe-1.0-autobuild
5023 FIXED       Missing depencies of package python-email
4759 FIXED       new recipe texi2html_1.78.bb
4774 FIXED       new recipe help2man_1.36.4.bb
5026 WONTFIX     dpkg_1.14.23.bb un-fetchable
5061 FIXED       gpe-scap-1.3 mips-strdup patch
5067 FIXED       New recipe for gRun
5327 INVALID     gcc-cross-intermediate-4.4.1-r6.1: oe_runmake failed.

Bugs opened:

bug_id resolution        short_desc



^ permalink raw reply

* Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd
From: Rafael J. Wysocki @ 2009-11-09 20:48 UTC (permalink / raw)
  To: Alan Stern
  Cc: Greg KH, Mike Galbraith, LKML, Jesse Barnes, pm list,
	Thomas Gleixner, Linus Torvalds, Ingo Molnar
In-Reply-To: <Pine.LNX.4.44L0.0911091527390.2858-100000@iolanthe.rowland.org>

On Monday 09 November 2009, Alan Stern wrote:
> On Mon, 9 Nov 2009, Rafael J. Wysocki wrote:
> 
> > Still, RIP always points to list_del_init(cwq->worklist.next); in
> > run_workqueue().
> 
> Use a big hammer: Create a new global variable, set it to 1 while
> resuming and back to 0 after the tasks have been thawed.  While the
> variable is nonzero, print in the log the list pointers in
> cwq->worklist just before executing the list_del_init().  Maybe also 
> print some other interesting information about cwq.

I've just sent a message containing full call trace.

It shows the problem is a general protection fault that happens _after_ we've
thawed tasks.

Thanks,
Rafael

^ permalink raw reply

* + kernel-sysc-implement-prctlpr_get_endian-for-all-architectures.patch added to -mm tree
From: akpm @ 2009-11-09 20:47 UTC (permalink / raw)
  To: mm-commits; +Cc: deller, anton, paulus


The patch titled
     kernel/sys.c: implement prctl(PR_GET_ENDIAN) for all architectures
has been added to the -mm tree.  Its filename is
     kernel-sysc-implement-prctlpr_get_endian-for-all-architectures.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find
out what to do about this

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: kernel/sys.c: implement prctl(PR_GET_ENDIAN) for all architectures
From: Helge Deller <deller@gmx.de>

The PR_GET_ENDIAN and PR_SET_ENDIAN prctl() calls have been implemented to
allow to switch processes at runtime from big-endian to little-endian mode
(and vice versa) on PowerPC processors.  Since the other architectures
don't support this feature, they currently will just fail and return
-EINVAL.

This patch adds just minimal overhead and implements the PR_GET_ENDIAN
call for all other architectures by returning the native endianess of the
architecture.  Furthermore, calling prctl(PR_SET_ENDIAN) with the native
endianess of the architecture will succeed, while trying to set another
(not-supported) endianess, will fail.

The patch can be tested with the following program:

#include <stdio.h>
#include <linux/prctl.h>

int main(int argc, char **argv)
{
	int endian, ret;

	ret = prctl(PR_GET_ENDIAN, &endian);
	if (ret)
		perror("prctl(PR_GET_ENDIAN) not implemented");
	printf("current process/machine is running in %s endian mode (%d)\n",
		endian == PR_ENDIAN_LITTLE ? "little":"big", endian);

	/* setting native endianess should succeed */
	ret = prctl(PR_SET_ENDIAN, endian);
	printf("prctl(PR_SET_ENDIAN,%d) should succeed: %s\n",
		endian, ret == 0 ? "OK":"FAIL");

	/* setting foreign endianess should fail */
	endian = (endian == PR_ENDIAN_LITTLE) ?
		PR_ENDIAN_BIG : PR_ENDIAN_LITTLE;
	ret = prctl(PR_SET_ENDIAN, endian);
	printf("prctl(PR_SET_ENDIAN,%d) should fail: %s\n",
		endian, ret == 0 ? "OK":"FAIL");
}

Signed-off-by: Helge Deller <deller@gmx.de>
Cc: Anton Blanchard <anton@samba.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---


diff -puN kernel/sys.c~kernel-sysc-implement-prctlpr_get_endian-for-all-architectures kernel/sys.c
--- a/kernel/sys.c~kernel-sysc-implement-prctlpr_get_endian-for-all-architectures
+++ a/kernel/sys.c
@@ -46,6 +46,15 @@
 #include <asm/io.h>
 #include <asm/unistd.h>
 
+#if defined(__BIG_ENDIAN)
+# define PRCTL_ENDIAN_DEFAULT	(PR_ENDIAN_BIG)
+#elif defined(__LITTLE_ENDIAN)
+# define PRCTL_ENDIAN_DEFAULT	(PR_ENDIAN_LITTLE)
+#else
+# error "No endianess?"
+#endif
+
+
 #ifndef SET_UNALIGN_CTL
 # define SET_UNALIGN_CTL(a,b)	(-EINVAL)
 #endif
@@ -65,10 +74,12 @@
 # define GET_FPEXC_CTL(a,b)	(-EINVAL)
 #endif
 #ifndef GET_ENDIAN
-# define GET_ENDIAN(a,b)	(-EINVAL)
+# define GET_ENDIAN(task,addr)	\
+	put_user(PRCTL_ENDIAN_DEFAULT, (int __user *) (addr))
 #endif
 #ifndef SET_ENDIAN
-# define SET_ENDIAN(a,b)	(-EINVAL)
+# define SET_ENDIAN(task,value)	\
+	( (value) == PRCTL_ENDIAN_DEFAULT ? 0 : -EINVAL )
 #endif
 #ifndef GET_TSC_CTL
 # define GET_TSC_CTL(a)		(-EINVAL)
_

Patches currently in -mm which might be from deller@gmx.de are

linux-next.patch
kernel-sysc-implement-prctlpr_get_endian-for-all-architectures.patch


^ permalink raw reply

* Re: [linux-pm] Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd
From: Rafael J. Wysocki @ 2009-11-09 20:48 UTC (permalink / raw)
  To: Alan Stern
  Cc: Thomas Gleixner, Mike Galbraith, Greg KH, LKML, Jesse Barnes,
	Ingo Molnar, Linus Torvalds, pm list
In-Reply-To: <Pine.LNX.4.44L0.0911091527390.2858-100000@iolanthe.rowland.org>

On Monday 09 November 2009, Alan Stern wrote:
> On Mon, 9 Nov 2009, Rafael J. Wysocki wrote:
> 
> > Still, RIP always points to list_del_init(cwq->worklist.next); in
> > run_workqueue().
> 
> Use a big hammer: Create a new global variable, set it to 1 while
> resuming and back to 0 after the tasks have been thawed.  While the
> variable is nonzero, print in the log the list pointers in
> cwq->worklist just before executing the list_del_init().  Maybe also 
> print some other interesting information about cwq.

I've just sent a message containing full call trace.

It shows the problem is a general protection fault that happens _after_ we've
thawed tasks.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH] Implement prctl(PR_GET_ENDIAN) for all architectures
From: Andrew Morton @ 2009-11-09 20:46 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-kernel, Anton Blanchard, Paul Mackerras
In-Reply-To: <20091022193533.GA5827@p100.box>

On Thu, 22 Oct 2009 21:35:33 +0200
Helge Deller <deller@gmx.de> wrote:

> The PR_GET_ENDIAN and PR_SET_ENDIAN prctl() calls have been implemented
> to allow to switch processes at runtime from big-endian to little-endian
> mode (and vice versa) on PowerPC processors. Since the other architectures
> don't support this feature, they currently will just fail and return -EINVAL.
> 
> This patch adds just minimal overhead and implements the PR_GET_ENDIAN
> call for all other architectures by returning the native endianess of
> the architecture. Furthermore, calling prctl(PR_SET_ENDIAN) with the
> native endianess of the architecture will succeed, while trying to
> set another (not-supported) endianess, will fail.
> 
> The patch can be tested with the following program:
> 
> #include <stdio.h>
> #include <linux/prctl.h>
> 
> int main(int argc, char **argv)
> {
> 	int endian, ret;
> 
> 	ret = prctl(PR_GET_ENDIAN, &endian);
> 	if (ret)
> 		perror("prctl(PR_GET_ENDIAN) not implemented");
> 	printf("current process/machine is running in %s endian mode (%d)\n",
> 		endian == PR_ENDIAN_LITTLE ? "little":"big", endian);
> 
> 	/* setting native endianess should succeed */
> 	ret = prctl(PR_SET_ENDIAN, endian);
> 	printf("prctl(PR_SET_ENDIAN,%d) should succeed: %s\n",
> 		endian, ret == 0 ? "OK":"FAIL");
> 
> 	/* setting foreign endianess should fail */
> 	endian = (endian == PR_ENDIAN_LITTLE) ?
> 		PR_ENDIAN_BIG : PR_ENDIAN_LITTLE;
> 	ret = prctl(PR_SET_ENDIAN, endian);
> 	printf("prctl(PR_SET_ENDIAN,%d) should fail: %s\n",
> 		endian, ret == 0 ? "OK":"FAIL");
> }
> 

The changelog forgot to provide any reason for making this change to
the kernel.


^ permalink raw reply

* Re: [PATCH] e820: fix clip_to_limit()
From: Keir Fraser @ 2009-11-09 20:46 UTC (permalink / raw)
  To: Xiao Guangrong; +Cc: Xiao Guangrong, xen-devel
In-Reply-To: <4AF875E9.4040807@gmail.com>

I think the 'break' is in the wrong place. Actually also I think the case of
successful change_range_type() is also wrong, as i=0 will be skipped on the
next iteration of the loop.

Overall I decided that modifying the e820 map inside the iterator loop was
just bad and confusing, so I've rewritten it in response to your bug
discovery. Please take a look at xen-unstable:20419 and let me know if you
see any issues.

 Thanks,
 Keir

On 09/11/2009 20:04, "Xiao Guangrong" <ericxiao.gr@gmail.com> wrote:

> In clip_to_limit(), after memmove(&e820.map[i], &e820.map[i+1], ...), the
> original
> e820.map[i+1] become current e820.map[i] but the next loop count is i+1, so
> the original
> e820.map[i+1] will be skipped
> 
> Actually, e820 is sorted form low to high by sanitize_e820_map(), so we can
> simply break
> the loop if we meet the item which overrun "limit"
> 
> Signed-off-by: Xiao Guangrong <ericxiao.gr@gmail.com>
> 
> diff -r 93bc06dd1161 -r 5e06f2790d93 xen/arch/x86/e820.c
> --- a/xen/arch/x86/e820.c Tue Nov 10 02:41:59 2009 +0800
> +++ b/xen/arch/x86/e820.c Tue Nov 10 03:51:08 2009 +0800
> @@ -389,6 +389,7 @@
>                       (e820.nr_map - i - 1) * sizeof(struct e820entry));
>               e820.nr_map--;
>           }
> + break;
>       }
> 
>       if ( old_limit )

^ permalink raw reply

* GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume (was: Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd)
From: Rafael J. Wysocki @ 2009-11-09 20:45 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Mike Galbraith, Greg KH, LKML, Jesse Barnes, Ingo Molnar,
	Linus Torvalds, pm list
In-Reply-To: <200911092100.58187.rjw@sisk.pl>

On Monday 09 November 2009, Rafael J. Wysocki wrote:
> On Monday 09 November 2009, Thomas Gleixner wrote:
> > On Mon, 9 Nov 2009, Rafael J. Wysocki wrote:
> > 
> > > On Monday 09 November 2009, Mike Galbraith wrote:
> > > > On Mon, 2009-11-09 at 16:47 +0100, Rafael J. Wysocki wrote:
> > > > > On Monday 09 November 2009, Mike Galbraith wrote:
> > > > 
> > > > > > > Very likely.  What did you do to fix it?
> > > > > > 
> > > > > > You don't really wanna know.  In 31 with newidle enabled, the below
> > > > > > fixed it.  It won't fix 32, though it might cure the resume problem.
> > > > > 
> > > > > OK, I'll give it a try.
> > > 
> > > It doesn't help.
> > > 
> > > Also, I can reproduce the issue with current -git and kernel preepmtion
> > > disabled.
> > > 
> > > > I just tried to trigger badness via high speed online/offline combined
> > > > with taskset with CONFIG_PREEMPT enabled, and couldn't make it explode.
> > > 
> > > I'm not able to do it this way too, so resume seems to be necessary to trigger
> > > it.  I'm going try with the suspend debug in the "core" mode.
> > > 
> > > > (damn, wish i could s2ram this box)
> > > 
> > > That need not suffice.  I have two other boxes that suspend and resume
> > > correctly with 2.6.32-rc, AFAICS.
> > > 
> > > However, there seems to be a systematic error somewhere, since the failure
> > > always happens at the same place, ie. list_del_init(cwq->worklist.next); in
> > > run_workqueue(), in preemptible as well as in non-preemptible kernels.
> > > 
> > > Which is kind of strange, given the !list_empty(&cwq->worklist) test right
> > > before it.
> > 
> > Does that happen before or after the secondary CPU has been brought up ?
> 
> Way after.  It seems to happen more-or-less during or right after the thawing
> of tasks.
> 
> Moreover, the call trace I get is (manual transcription):

OK, below is the full call trace I found in the kernel log.

[   51.520183] PM: Finishing wakeup.
[   51.520186] Restarting tasks ... 
[   51.520387] usb 5-2: USB disconnect, address 2
[   51.544197] done.
[   52.013018] general protection fault: 0000 [#1] PREEMPT SMP 
[   52.013431] last sysfs file: /sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2/1-2:1.3/ttyUSB3/port_number
[   52.013700] CPU 0 
[   52.013900] Modules linked in: ip6t_LOG af_packet xt_tcpudp xt_pkttype ipt_LOG xt_limit bnep sco rfcomm l2cap crc16 snd_pcm_oss snd_mixer_oss snd_seq binfmt_misc snd_seq_device ip6t_REJECT nf_conntrack_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT xt_state iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_ipv4 cpufreq_conservative nf_conntrack nf_defrag_ipv4 cpufreq_ondemand ip_tables cpufreq_userspace cpufreq_powersave acpi_cpufreq ip6table_filter ip6_tables x_tables freq_table ipv6 microcode fuse loop sr_mod cdrom dm_mod arc4 ecb btusb snd_hda_codec_realtek bluetooth iwlagn snd_hda_intel snd_hda_codec iwlcore pcmcia snd_hwdep snd_pcm sdhci_pci mac80211 snd_timer joydev sdhci toshiba_acpi yenta_socket usbhid cfg80211 snd option rtc_cmos mmc_core firewire_ohci vi
 deo rsrc_nonstatic psmouse firewire_core backlight soundcore iTCO_wdt rtc_core hid battery ac intel_agp button usb_storage snd_page_alloc usbserial rfkill pcmcia_core iTCO_vendor_support e1!
 000e rtc_lib led_class serio_raw crc_itu_t output uinput sg ehci_hcd uhci_hcd sd_mod crc_t10dif usbcore ext3 jbd fan ahci libata thermal processor
[   52.016961] Pid: 9, comm: events/0 Not tainted 2.6.32-rc6-tst #160 PORTEGE R500
[   52.016961] RIP: 0010:[<ffffffff81054bff>]  [<ffffffff81054bff>] worker_thread+0x15b/0x22a
[   52.016961] RSP: 0018:ffff88007f0d9e40  EFLAGS: 00010046
[   52.016961] RAX: ffff88007e056b68 RBX: ffff88007f09bd48 RCX: 6b6b6b6b6b6b6b6b
[   52.016961] RDX: 6b6b6b6b6b6b6b6b RSI: 0000000000000000 RDI: ffff880001613d00
[   52.016961] RBP: ffff88007f0d9ee0 R08: ffff88007f0b9178 R09: ffff88007f0d9e10
[   52.016961] R10: ffff880001613d00 R11: 0000000000000001 R12: ffff88007e056b60
[   52.016961] R13: ffff880001613d00 R14: ffff88007f0b9140 R15: ffff88007f0b9140
[   52.016961] FS:  0000000000000000(0000) GS:ffff880001600000(0000) knlGS:0000000000000000
[   52.016961] CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
[   52.016961] CR2: 00007f786667d060 CR3: 0000000001001000 CR4: 00000000000006f0
[   52.016961] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   52.016961] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   52.016961] Process events/0 (pid: 9, threadinfo ffff88007f0d8000, task ffff88007f0b9140)
[   52.016961] Stack:
[   52.016961]  000000000000c918 ffff88007f0b9578 ffff88007f0d9fd8 ffff88007f0b9140
[   52.016961] <0> ffff880001613d08 ffff88007f0b9140 ffff880001613d18 6b6b6b6b6b6b6b6b
[   52.016961] <0> 0000000000000000 ffff88007f0b9140 ffffffff81058281 ffff88007f0d9e98
[   52.016961] Call Trace:
[   52.016961]  [<ffffffff81058281>] ? autoremove_wake_function+0x0/0x38
[   52.016961]  [<ffffffff81054aa4>] ? worker_thread+0x0/0x22a
[   52.016961]  [<ffffffff8105805a>] kthread+0x69/0x71
[   52.016961]  [<ffffffff8100c16a>] child_rip+0xa/0x20
[   52.016961]  [<ffffffff81057ff1>] ? kthread+0x0/0x71
[   52.016961]  [<ffffffff8100c160>] ? child_rip+0x0/0x20
[   52.016961] Code: 74 12 4c 89 e6 4c 89 f7 ff 13 48 83 c3 08 48 83 3b 00 eb ec e8 3d ef ff ff 49 8b 45 08 4d 89 65 30 4c 89 ef 48 8b 08 48 8b 50 08 <48> 89 51 08 48 89 0a 48 89 40 08 48 89 00 e8 f6 11 24 00 49 8b 
[   52.016961] RIP  [<ffffffff81054bff>] worker_thread+0x15b/0x22a
[   52.016961]  RSP <ffff88007f0d9e40>
[   52.016961] ---[ end trace 1d831fad17e9eb5d ]---
[   52.016961] note: events/0[9] exited with preempt_count 1

So, this actually is a general protection fault that killed events and it
happened exactly in list_del_init(cwq->worklist.next); in run_workqueue().

Thanks,
Rafael

^ permalink raw reply

* NULL mp->m_log in 2.6.31 xfs_log_move_tail
From: Ed Cashin @ 2009-11-09 20:39 UTC (permalink / raw)
  To: linux-xfs

A colleague has seen oopses in 2.6.31 when an XFS is mounted on an AoE
target that becomes unresponsive and is marked as "down" by the aoe
driver.  The aoe driver starts failing all new I/O requests after
failing all current requests when the device is down.

I looked at the trace (included below) and put in the following check:

--- linux-2.6.31/fs/xfs/xfs_log.c.20091009	2009-10-09 16:49:23.062989234 -0400
+++ linux-2.6.31/fs/xfs/xfs_log.c	2009-10-09 16:49:39.766738875 -0400
@@ -822,6 +822,7 @@ xfs_log_move_tail(xfs_mount_t	*mp,
 	xlog_t		*log = mp->m_log;
 	int		need_bytes, free_bytes, cycle, bytes;
 
+	BUG_ON(!log);
 	if (XLOG_FORCED_SHUTDOWN(log))
 		return;
 
... and subsequent tests showed the BUG_ON being triggered.  I meant
to gather more information but have gotten sidetracked, so I'm posting
this information now in the hopes that it is helpful.

I/O error in filesystem ("etherd/e8.1") meta-data dev etherd/e8.1 block 
0x1bf0862       ("xlog_iodone") error 5 buf count 1024
xfs_force_shutdown(etherd/e8.1,0x2) called from line 1044 of file 
fs/xfs/xfs_log.c.  Return address = 0xffffffffa03e79bf
Filesystem "etherd/e8.1": Log I/O Error Detected.  Shutting down 
filesystem: etherd/e8.1
Please umount the filesystem, and rectify the problem(s)
XFS: Unable to update superblock counters. Freespace may not be correct 
on next mount.
------------[ cut here ]------------
kernel BUG at fs/xfs/xfs_log.c:825!
invalid opcode: 0000 [#1] SMP
last sysfs file: /sys/devices/virtual/block/etherd!e8.33/state
CPU 1
Modules linked in: aoe xfs exportfs bridge stp llc bnep sco l2cap 
bluetooth rfkill sunrpc ip6t_REJECT nf_conntrack_ipv6 ip6table_filter 
ip6_tables ipv6 p4_clockmod freq_table speedstep_lib dm_multipath uinput 
ixgbe e1000e i5k_amb e1000 hwmon i5000_edac ppdev iTCO_wdt 
iTCO_vendor_support edac_core parport_pc dca mdio i2c_i801 parport 
floppy pcspkr shpchp ata_generic pata_acpi radeon ttm drm i2c_algo_bit 
i2c_core [last unloaded: aoe]
Pid: 21300, comm: umount Not tainted 2.6.31 #1 X7DB8
RIP: 0010:[<ffffffffa03e823b>]  [<ffffffffa03e823b>] 
xfs_log_move_tail+0x34/0x174 [xfs]
RSP: 0018:ffff88006e985b08  EFLAGS: 00010246
RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffff88006e985ba8
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff88007542c540
RBP: ffff88006e985b48 R08: ffff88007b101900 R09: ffffffff817a21d8
R10: ffff880019379c00 R11: 00000000860c2753 R12: ffff88007542c180
R13: 0000000000000000 R14: ffff88007b101900 R15: 0000000000000000
FS:  00007f089e005740(0000) GS:ffff880001a6f000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007f089d6d69ce CR3: 00000000765ae000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process umount (pid: 21300, threadinfo ffff88006e984000, task 
ffff88006d8f0000)
Stack:
  0000000000000000 00000000860c2753 ffff88006e985b48 ffff88007b101900
<0> ffff88007542c180 ffff88007b101900 ffff88007b101900 0000000000000000
<0> ffff88006e985b88 ffffffffa03f4e9d ffff88006e985b88 00000000860c2753
Call Trace:
  [<ffffffffa03f4e9d>] xfs_trans_ail_delete+0x82/0xf4 [xfs]
  [<ffffffffa03cc7fd>] xfs_buf_iodone+0x40/0x63 [xfs]
  [<ffffffffa03cc759>] xfs_buf_do_callbacks+0x3c/0x5f [xfs]
  [<ffffffffa03cca19>] xfs_buf_iodone_callbacks+0x136/0x175 [xfs]
  [<ffffffffa04002a5>] xfs_buf_iodone_work+0x63/0x86 [xfs]
  [<ffffffffa040035b>] xfs_buf_ioend+0x93/0xb7 [xfs]
  [<ffffffffa03fb230>] xfs_bioerror+0x56/0x76 [xfs]
  [<ffffffffa0404668>] xfs_bdstrat_cb+0x48/0x67 [xfs]
  [<ffffffffa03fff3e>] xfs_buf_iostrategy+0x2a/0x47 [xfs]
  [<ffffffffa03ffffc>] xfs_flush_buftarg+0xa1/0x125 [xfs]
  [<ffffffffa04000b2>] xfs_free_buftarg+0x32/0x8f [xfs]
  [<ffffffffa0406e61>] xfs_close_devices+0x77/0x94 [xfs]
  [<ffffffffa0406f2f>] xfs_fs_put_super+0xb1/0xe8 [xfs]
  [<ffffffff8112ccf6>] generic_shutdown_super+0x69/0xf2
  [<ffffffff8112cdb9>] kill_block_super+0x3a/0x6a
  [<ffffffff8112d6af>] deactivate_super+0x68/0x95
  [<ffffffff81144420>] mntput_no_expire+0xc6/0x114
  [<ffffffff81144aa6>] sys_umount+0x2f2/0x337
  [<ffffffff81012f82>] system_call_fastpath+0x16/0x1b
Code: 55 41 54 53 48 83 ec 18 0f 1f 44 00 00 65 48 8b 04 25 28 00 00 00 
48 89 45 c8 31 c0 48 8b 9f 40 01 00 00 49 89 f5 48 85 db 75 04 <0f> 0b 
eb fe f6 43 20 08 0f 85 0f 01 00 00 48 85 f6 75 19 48 8d
RIP  [<ffffffffa03e823b>] xfs_log_move_tail+0x34/0x174 [xfs]
  RSP <ffff88006e985b08>
---[ end trace 838ac7bc7c8a18c8 ]---
------------[ cut here ]------------
WARNING: at kernel/exit.c:895 do_exit+0x54/0x6da()
Hardware name: X7DB8
Modules linked in: aoe xfs exportfs bridge stp llc bnep sco l2cap 
bluetooth rfkill sunrpc ip6t_REJECT nf_conntrack_ipv6 ip6table_filter 
ip6_tables ipv6 p4_clockmod freq_table speedstep_lib dm_multipath uinput 
ixgbe e1000e i5k_amb e1000 hwmon i5000_edac ppdev iTCO_wdt 
iTCO_vendor_support edac_core parport_pc dca mdio i2c_i801 parport 
floppy pcspkr shpchp ata_generic pata_acpi radeon ttm drm i2c_algo_bit 
i2c_core [last unloaded: aoe]
Pid: 21300, comm: umount Tainted: G      D    2.6.31 #1
Call Trace:
  [<ffffffff810610ff>] warn_slowpath_common+0x8d/0xbb
  [<ffffffff81061154>] warn_slowpath_null+0x27/0x3d
  [<ffffffff8106516f>] do_exit+0x54/0x6da
  [<ffffffff814d564f>] oops_end+0xc8/0xe7
  [<ffffffff810171ad>] die+0x6d/0x8c
  [<ffffffff814d4fdd>] do_trap+0x124/0x147
  [<ffffffff814d705d>] ? atomic_notifier_call_chain+0x26/0x3c
  [<ffffffff81014eb0>] do_invalid_op+0xa9/0xc9
  [<ffffffffa03e823b>] ? xfs_log_move_tail+0x34/0x174 [xfs]
  [<ffffffff814d3c6b>] ? trace_hardirqs_off_thunk+0x3a/0x6c
  [<ffffffff81013e2b>] invalid_op+0x1b/0x20
  [<ffffffffa03e823b>] ? xfs_log_move_tail+0x34/0x174 [xfs]
  [<ffffffffa03f4e9d>] xfs_trans_ail_delete+0x82/0xf4 [xfs]
  [<ffffffffa03cc7fd>] xfs_buf_iodone+0x40/0x63 [xfs]
  [<ffffffffa03cc759>] xfs_buf_do_callbacks+0x3c/0x5f [xfs]
  [<ffffffffa03cca19>] xfs_buf_iodone_callbacks+0x136/0x175 [xfs]
  [<ffffffffa04002a5>] xfs_buf_iodone_work+0x63/0x86 [xfs]
  [<ffffffffa040035b>] xfs_buf_ioend+0x93/0xb7 [xfs]
  [<ffffffffa03fb230>] xfs_bioerror+0x56/0x76 [xfs]
  [<ffffffffa0404668>] xfs_bdstrat_cb+0x48/0x67 [xfs]
  [<ffffffffa03fff3e>] xfs_buf_iostrategy+0x2a/0x47 [xfs]
  [<ffffffffa03ffffc>] xfs_flush_buftarg+0xa1/0x125 [xfs]
  [<ffffffffa04000b2>] xfs_free_buftarg+0x32/0x8f [xfs]
  [<ffffffffa0406e61>] xfs_close_devices+0x77/0x94 [xfs]
  [<ffffffffa0406f2f>] xfs_fs_put_super+0xb1/0xe8 [xfs]
  [<ffffffff8112ccf6>] generic_shutdown_super+0x69/0xf2
  [<ffffffff8112cdb9>] kill_block_super+0x3a/0x6a
  [<ffffffff8112d6af>] deactivate_super+0x68/0x95
  [<ffffffff81144420>] mntput_no_expire+0xc6/0x114
  [<ffffffff81144aa6>] sys_umount+0x2f2/0x337
  [<ffffffff81012f82>] system_call_fastpath+0x16/0x1b
---[ end trace 838ac7bc7c8a18c9 ]---
[root@stuart srrd]#

-- 
  Ed Cashin <ecashin@coraid.com>
  Find experimental aoe Linux driver patches at
  http://coraid.typepad.com/aoe_linux_proving_grounds/

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply

* [PATCH] provide crucial explanations for the dreaded "No init found." boot failure.
From: Andreas Mohr @ 2009-11-09 20:45 UTC (permalink / raw)
  To: Américo Wang
  Cc: Andreas Mohr, Linus Torvalds, Michael A. Griffith, linux-kernel
In-Reply-To: <20091108151153.GC6240@hack>

On Sun, Nov 08, 2009 at 11:11:53PM +0800, Américo Wang wrote:
> On Sun, Nov 08, 2009 at 03:45:50PM +0100, Andreas Mohr wrote:
> >Hi,
> >
> >On Sun, Nov 08, 2009 at 10:25:06PM +0800, Américo Wang wrote:
> >> On Sun, Nov 08, 2009 at 01:00:08PM +0100, Andreas Mohr wrote:
> >So, where to put it?
> >Documentation/initrd.txt is related, however I'd create something
> >like Documentation/initialization/...
> >Or perhaps Documentation/bootup/init.txt ?
> 
> Personally, I prefer Documentation/init.txt, but adding it to
> initrd.txt also makes sense for me. :)

Yup, chose Documentation/init.txt.

Patch against 2.6.32-rc6 attached, UNTESTED (checkpatch.pl is fine).

Please get something like this committed, half a million $$ in prior damage
ought to be enough for everybody.

Thanks,

Signed-off-by: Andreas Mohr <andi@lisas.de>


--- linux-2.6.32-rc6/init/main.c.orig	2009-11-08 11:09:51.000000000 +0100
+++ linux-2.6.32-rc6/init/main.c	2009-11-09 21:34:24.000000000 +0100
@@ -846,7 +846,8 @@
 	run_init_process("/bin/init");
 	run_init_process("/bin/sh");
 
-	panic("No init found.  Try passing init= option to kernel.");
+	panic("No init found.  Try passing init= option to kernel. "
+	      "See Linux Documentation/init.txt for guidance.");
 }
 
 static int __init kernel_init(void * unused)
--- /dev/null	2009-10-09 14:49:35.924999847 +0200
+++ linux-2.6.32-rc6/Documentation/init.txt	2009-11-09 21:27:39.000000000 +0100
@@ -0,0 +1,42 @@
+Explaining the dreaded "No init found." boot hang message
+=========================================================
+
+OK, so you've got this pretty unintuitive message (currently located
+in init/main.c) and are wondering what the H*** went wrong.
+Some high-level reasons for failure (listed roughly in order of execution)
+to load the init binary are:
+A) Unable to mount root FS
+B) init binary doesn't exist on rootfs
+C) other requirements not met
+D) binary exists but dependencies not available
+E) binary cannot be loaded
+
+Detailed explanations:
+A) Please make sure you have the correct root FS type
+(and root= in bootloader or CONFIG_CMDLINE points to the correct partition),
+required drivers such as storage hardware (such as SCSI or USB!)
+and filesystem (ext3, jffs2 etc.) are builtin (alternatively as modules by
+using initrd)
+C) Possibly a conflict in console= setup --> initial console unavailable.
+E.g. some serial consoles are unreliable due to serial IRQ issues (e.g. missing
+interrupt-based configuration).
+Try using a different console= device or e.g. netconsole=.
+D) e.g. crucial library dependencies of the init binary such as
+/lib/ld-linux.so.2 missing or broken. Use readelf -d <INIT>|grep NEEDED
+to find out which libraries are required.
+E) make sure the binary's architecture matches your hardware.
+E.g. i386 vs. x86_64 mismatch, or trying to load x86 on ARM hardware.
+Or did you try loading a non-binary file here!?! (shell script?)
+To find out more, add code patch to display kernel_execve()s return values.
+
+Please extend this explanation whenever you find new failure causes
+(after all loading the init binary is a CRITICAL and hard transition step
+which needs to be made as painless as possible), then submit patch to LKML.
+Further TODOs:
+- Implement the various run_init_process() invocations via a struct array
+  which can then store the kernel_execve() result value and on failure
+  log it all by iterating over _all_ results (very important usability fix).
+- try to make the implementation itself more helpful in general,
+  e.g. by providing additional error messages at affected places.
+
+Andreas Mohr <andi at lisas period de>

^ permalink raw reply

* GPF in run_workqueue()/list_del_init(cwq->worklist.next) on resume (was: Re: Help needed: Resume problems in 2.6.32-rc, perhaps related to preempt_count leakage in keventd)
From: Rafael J. Wysocki @ 2009-11-09 20:45 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: Mike Galbraith, Ingo Molnar, LKML, pm list, Greg KH,
	Linus Torvalds, Jesse Barnes
In-Reply-To: <200911092100.58187.rjw@sisk.pl>

On Monday 09 November 2009, Rafael J. Wysocki wrote:
> On Monday 09 November 2009, Thomas Gleixner wrote:
> > On Mon, 9 Nov 2009, Rafael J. Wysocki wrote:
> > 
> > > On Monday 09 November 2009, Mike Galbraith wrote:
> > > > On Mon, 2009-11-09 at 16:47 +0100, Rafael J. Wysocki wrote:
> > > > > On Monday 09 November 2009, Mike Galbraith wrote:
> > > > 
> > > > > > > Very likely.  What did you do to fix it?
> > > > > > 
> > > > > > You don't really wanna know.  In 31 with newidle enabled, the below
> > > > > > fixed it.  It won't fix 32, though it might cure the resume problem.
> > > > > 
> > > > > OK, I'll give it a try.
> > > 
> > > It doesn't help.
> > > 
> > > Also, I can reproduce the issue with current -git and kernel preepmtion
> > > disabled.
> > > 
> > > > I just tried to trigger badness via high speed online/offline combined
> > > > with taskset with CONFIG_PREEMPT enabled, and couldn't make it explode.
> > > 
> > > I'm not able to do it this way too, so resume seems to be necessary to trigger
> > > it.  I'm going try with the suspend debug in the "core" mode.
> > > 
> > > > (damn, wish i could s2ram this box)
> > > 
> > > That need not suffice.  I have two other boxes that suspend and resume
> > > correctly with 2.6.32-rc, AFAICS.
> > > 
> > > However, there seems to be a systematic error somewhere, since the failure
> > > always happens at the same place, ie. list_del_init(cwq->worklist.next); in
> > > run_workqueue(), in preemptible as well as in non-preemptible kernels.
> > > 
> > > Which is kind of strange, given the !list_empty(&cwq->worklist) test right
> > > before it.
> > 
> > Does that happen before or after the secondary CPU has been brought up ?
> 
> Way after.  It seems to happen more-or-less during or right after the thawing
> of tasks.
> 
> Moreover, the call trace I get is (manual transcription):

OK, below is the full call trace I found in the kernel log.

[   51.520183] PM: Finishing wakeup.
[   51.520186] Restarting tasks ... 
[   51.520387] usb 5-2: USB disconnect, address 2
[   51.544197] done.
[   52.013018] general protection fault: 0000 [#1] PREEMPT SMP 
[   52.013431] last sysfs file: /sys/devices/pci0000:00/0000:00:1d.0/usb1/1-2/1-2:1.3/ttyUSB3/port_number
[   52.013700] CPU 0 
[   52.013900] Modules linked in: ip6t_LOG af_packet xt_tcpudp xt_pkttype ipt_LOG xt_limit bnep sco rfcomm l2cap crc16 snd_pcm_oss snd_mixer_oss snd_seq binfmt_misc snd_seq_device ip6t_REJECT nf_conntrack_ipv6 ip6table_raw xt_NOTRACK ipt_REJECT xt_state iptable_raw iptable_filter ip6table_mangle nf_conntrack_netbios_ns nf_conntrack_ipv4 cpufreq_conservative nf_conntrack nf_defrag_ipv4 cpufreq_ondemand ip_tables cpufreq_userspace cpufreq_powersave acpi_cpufreq ip6table_filter ip6_tables x_tables freq_table ipv6 microcode fuse loop sr_mod cdrom dm_mod arc4 ecb btusb snd_hda_codec_realtek bluetooth iwlagn snd_hda_intel snd_hda_codec iwlcore pcmcia snd_hwdep snd_pcm sdhci_pci mac80211 snd_timer joydev sdhci toshiba_acpi yenta_socket usbhid cfg80211 snd option rtc_cmos mmc_core firewire_ohci video rsrc_nonstatic psmouse firewire_core backlight soundcore iTCO_wdt rtc_core hid battery ac intel_agp button usb_storage snd_page_alloc usbserial rfkill pcmcia_core iTCO_vendor_support e1000e rtc_lib led_class serio_raw crc_itu_t output uinput sg ehci_hcd uhci_hcd sd_mod crc_t10dif usbcore ext3 jbd fan ahci libata thermal processor
[   52.016961] Pid: 9, comm: events/0 Not tainted 2.6.32-rc6-tst #160 PORTEGE R500
[   52.016961] RIP: 0010:[<ffffffff81054bff>]  [<ffffffff81054bff>] worker_thread+0x15b/0x22a
[   52.016961] RSP: 0018:ffff88007f0d9e40  EFLAGS: 00010046
[   52.016961] RAX: ffff88007e056b68 RBX: ffff88007f09bd48 RCX: 6b6b6b6b6b6b6b6b
[   52.016961] RDX: 6b6b6b6b6b6b6b6b RSI: 0000000000000000 RDI: ffff880001613d00
[   52.016961] RBP: ffff88007f0d9ee0 R08: ffff88007f0b9178 R09: ffff88007f0d9e10
[   52.016961] R10: ffff880001613d00 R11: 0000000000000001 R12: ffff88007e056b60
[   52.016961] R13: ffff880001613d00 R14: ffff88007f0b9140 R15: ffff88007f0b9140
[   52.016961] FS:  0000000000000000(0000) GS:ffff880001600000(0000) knlGS:0000000000000000
[   52.016961] CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
[   52.016961] CR2: 00007f786667d060 CR3: 0000000001001000 CR4: 00000000000006f0
[   52.016961] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[   52.016961] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[   52.016961] Process events/0 (pid: 9, threadinfo ffff88007f0d8000, task ffff88007f0b9140)
[   52.016961] Stack:
[   52.016961]  000000000000c918 ffff88007f0b9578 ffff88007f0d9fd8 ffff88007f0b9140
[   52.016961] <0> ffff880001613d08 ffff88007f0b9140 ffff880001613d18 6b6b6b6b6b6b6b6b
[   52.016961] <0> 0000000000000000 ffff88007f0b9140 ffffffff81058281 ffff88007f0d9e98
[   52.016961] Call Trace:
[   52.016961]  [<ffffffff81058281>] ? autoremove_wake_function+0x0/0x38
[   52.016961]  [<ffffffff81054aa4>] ? worker_thread+0x0/0x22a
[   52.016961]  [<ffffffff8105805a>] kthread+0x69/0x71
[   52.016961]  [<ffffffff8100c16a>] child_rip+0xa/0x20
[   52.016961]  [<ffffffff81057ff1>] ? kthread+0x0/0x71
[   52.016961]  [<ffffffff8100c160>] ? child_rip+0x0/0x20
[   52.016961] Code: 74 12 4c 89 e6 4c 89 f7 ff 13 48 83 c3 08 48 83 3b 00 eb ec e8 3d ef ff ff 49 8b 45 08 4d 89 65 30 4c 89 ef 48 8b 08 48 8b 50 08 <48> 89 51 08 48 89 0a 48 89 40 08 48 89 00 e8 f6 11 24 00 49 8b 
[   52.016961] RIP  [<ffffffff81054bff>] worker_thread+0x15b/0x22a
[   52.016961]  RSP <ffff88007f0d9e40>
[   52.016961] ---[ end trace 1d831fad17e9eb5d ]---
[   52.016961] note: events/0[9] exited with preempt_count 1

So, this actually is a general protection fault that killed events and it
happened exactly in list_del_init(cwq->worklist.next); in run_workqueue().

Thanks,
Rafael

^ permalink raw reply

* Re: SRPT and SCST
From: Chris Worley @ 2009-11-09 20:43 UTC (permalink / raw)
  To: Vladislav Bolkhovitin
  Cc: Bart Van Assche, Arend Dittmer, Philip Pokorny,
	scst-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-rdma-u79uwXL29TY76Z2rM5mHXA, Vu Pham
In-Reply-To: <4AF87B05.1050902-d+Crzxg7Rs0@public.gmane.org>

On Mon, Nov 9, 2009 at 1:26 PM, Vladislav Bolkhovitin <vst-d+Crzxg7Rs0@public.gmane.org> wrote:
> Bart Van Assche, on 11/08/2009 12:49 PM wrote:
>>
>> On Fri, Nov 6, 2009 at 6:28 PM, Arend Dittmer
>> <adittmer-pabcTyWEv4ZW60MLeMDbCVaTQe2KTcn/@public.gmane.org> wrote:
>>>
>>> Please find attached the gzip'ed /var/log/messages.
>>
>> This log clearly show the login and logout actions from the different
>> initiators. I couldn't find anything unusual in the posted log file
>> however. Around which time did the initiator start complaining about
>> aborted SCSI commands ? Does this issue also happen when using the SRP
>> initiator included in a vanilla (non-OFED) Linux kernel ?
>
> It looks painfully similar to what Chris Worley experienced some time ago
> and somehow fixed/workarounded.
>
> Chris, can you comment on this?

The "thread=1" fixed the problem mostly, but I am working with another
group that says they still get an abort, but haven't gotten around to
providing me with the info I need to look at it.

Chris
>
>> Bart.
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
>> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH] sh_mobile_ceu_camera: document the scaling and cropping algorithm
From: Guennadi Liakhovetski @ 2009-11-09 20:43 UTC (permalink / raw)
  To: Linux Media Mailing List

The sh_mobile_ceu_camera driver implements an advanced algorithm, combining
scaling and cropping on the client and on the host. Due to its complexity the
algorithm deserves separate documentation.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---

I'm having internet problems here, and it seems the first attempt to send 
this mail failed magically... resending, sorry, if it ends up double on 
the list.

 Documentation/video4linux/sh_mobile_ceu_camera.txt |  157 ++++++++++++++++++++
 1 files changed, 157 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/video4linux/sh_mobile_ceu_camera.txt

diff --git a/Documentation/video4linux/sh_mobile_ceu_camera.txt b/Documentation/video4linux/sh_mobile_ceu_camera.txt
new file mode 100644
index 0000000..2ae1634
--- /dev/null
+++ b/Documentation/video4linux/sh_mobile_ceu_camera.txt
@@ -0,0 +1,157 @@
+	Cropping and Scaling algorithm, used in the sh_mobile_ceu_camera driver
+	=======================================================================
+
+Terminology
+-----------
+
+sensor scales: horizontal and vertical scales, configured by the sensor driver
+host scales: -"- host driver
+combined scales: sensor_scale * host_scale
+
+
+Generic scaling / cropping scheme
+---------------------------------
+
+-1--
+|
+-2-- -\
+|      --\
+|         --\
++-5-- -\     -- -3--
+|       ---\
+|           --- -4-- -\
+|                      -\
+|                        - -6--
+|
+|                        - -6'-
+|                      -/
+|           --- -4'- -/
+|       ---/
++-5'- -/
+|            -- -3'-
+|         --/
+|      --/
+-2'- -/
+|
+|
+-1'-
+
+Produced by user requests:
+
+S_CROP(left / top = (5) - (1), width / height = (5') - (5))
+S_FMT(width / height = (6') - (6))
+
+Here:
+
+(1) to (1') - whole max width or height
+(1) to (2)  - sensor cropped left or top
+(2) to (2') - sensor cropped width or height
+(3) to (3') - sensor scale
+(3) to (4)  - CEU cropped left or top
+(4) to (4') - CEU cropped width or height
+(5) to (5') - reverse sensor scale applied to CEU cropped width or height
+(2) to (5)  - reverse sensor scale applied to CEU cropped left or top
+(6) to (6') - CEU scale - user window
+
+
+S_FMT
+-----
+
+Do not touch input rectangle - it is already optimal.
+
+1. Calculate current sensor scales:
+
+	scale_s = ((3') - (3)) / ((2') - (2))
+
+2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
+current sensor scales onto input window - this is user S_CROP:
+
+	width_u = (5') - (5) = ((4') - (4)) * scale_s
+
+3. Calculate new combined scales from "effective" input window to requested user
+window:
+
+	scale_comb = width_u / ((6') - (6))
+
+4. Calculate sensor output window by applying combined scales to real input
+window:
+
+	width_s_out = ((2') - (2)) / scale_comb
+
+5. Apply iterative sensor S_FMT for sensor output window.
+
+	subdev->video_ops->s_fmt(.width = width_s_out)
+
+6. Retrieve sensor output window (g_fmt)
+
+7. Calculate new sensor scales:
+
+	scale_s_new = ((3')_new - (3)_new) / ((2') - (2))
+
+8. Calculate new CEU crop - apply sensor scales to previously calculated
+"effective" crop:
+
+	width_ceu = (4')_new - (4)_new = width_u / scale_s_new
+	left_ceu = (4)_new - (3)_new = ((5) - (2)) / scale_s_new
+
+9. Use CEU cropping to crop to the new window:
+
+	ceu_crop(.width = width_ceu, .left = left_ceu)
+
+10. Use CEU scaling to scale to the requested user window:
+
+	scale_ceu = width_ceu / width
+
+
+S_CROP
+------
+
+If old scale applied to new crop is invalid produce nearest new scale possible
+
+1. Calculate current combined scales.
+
+	scale_comb = (((4') - (4)) / ((6') - (6))) * (((2') - (2)) / ((3') - (3)))
+
+2. Apply iterative sensor S_CROP for new input window.
+
+3. If old combined scales applied to new crop produce an impossible user window,
+adjust scales to produce nearest possible window.
+
+	width_u_out = ((5') - (5)) / scale_comb
+
+	if (width_u_out > max)
+		scale_comb = ((5') - (5)) / max;
+	else if (width_u_out < min)
+		scale_comb = ((5') - (5)) / min;
+
+4. Issue G_CROP to retrieve actual input window.
+
+5. Using actual input window and calculated combined scales calculate sensor
+target output window.
+
+	width_s_out = ((3') - (3)) = ((2') - (2)) / scale_comb
+
+6. Apply iterative S_FMT for new sensor target output window.
+
+7. Issue G_FMT to retrieve the actual sensor output window.
+
+8. Calculate sensor scales.
+
+	scale_s = ((3') - (3)) / ((2') - (2))
+
+9. Calculate sensor output subwindow to be cropped on CEU by applying sensor
+scales to the requested window.
+
+	width_ceu = ((5') - (5)) / scale_s
+
+10. Use CEU cropping for above calculated window.
+
+11. Calculate CEU scales from sensor scales from results of (10) and user window
+from (3)
+
+	scale_ceu = calc_scale(((5') - (5)), &width_u_out)
+
+12. Apply CEU scales.
+
+--
+Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
-- 
1.6.2.4


^ permalink raw reply related

* [PATCH] Use ST vendor enum instead of numeral
From: Linus Walleij @ 2009-11-09 20:43 UTC (permalink / raw)
  To: linux-arm-kernel

This fixes a leftover instance of using the 0x80 numeral instead
of the new AMBA_VENDOR_ST enum in the MMCI/PL180 driver.

Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
---
 drivers/mmc/host/mmci.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 705a589..90d168a 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -56,7 +56,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
 				clk = 255;
 			host->cclk = host->mclk / (2 * (clk + 1));
 		}
-		if (host->hw_designer == 0x80)
+		if (host->hw_designer == AMBA_VENDOR_ST)
 			clk |= MCI_FCEN; /* Bug fix in ST IP block */
 		clk |= MCI_CLK_ENABLE;
 		/* This hasn't proven to be worthwhile */
-- 
1.6.3.3

^ permalink raw reply related

* Re: [PATCH/RFC] tmio_mmc: keep card-detect interrupts enabled
From: Guennadi Liakhovetski @ 2009-11-09 20:39 UTC (permalink / raw)
  To: Ian Molton; +Cc: Linux Media Mailing List
In-Reply-To: <c09aa50a0911091218i681449e0r5cb96b9db3e0def6@mail.gmail.com>

(re-adding accidentally dropped ML)

On Mon, 9 Nov 2009, Ian Molton wrote:

> Well, I presume we want to know when the card gets removed :)

Sure, that's why we shouldn't mask those interrupts:-) If they do get 
masked and missed, I do not know, if the interrupt remains pending in this 
case, because they never get detected then:)

> 
> 2009/11/9 Guennadi Liakhovetski <g.liakhovetski@gmx.de>:
> > Hi Ian
> >
> > Why did you drop all CCs?
> >
> > On Mon, 9 Nov 2009, Ian Molton wrote:
> >
> >> I havent looked at the consequences for the driver if a insert IRQ
> >> occurs during IO, however it seems logical that we should not
> >> permanently mask the IRQ.
> >>
> >> I presume that the IRQ remains pending?
> >
> > Don't know, never checked. Is this important to know?
> >
> > Thanks
> > Guennadi
> >
> >>
> >> 2009/11/6 Guennadi Liakhovetski <g.liakhovetski@gmx.de>:
> >> > On SuperH platforms the SDHI controller does not produce any command IRQs
> >> > after a completed IO. This leads to card-detect interrupts staying
> >> > disabled. Do not disable card-detect interrupts on DATA IRQs.
> >> >
> >> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> >> > ---
> >> >
> >> > Marked as RFC because I'm not really sure this is a correct approach to
> >> > fix this problem, and whether this will have negative effect on other
> >> > tmio_mmc MFD users.
> >> >
> >> > diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
> >> > index c676767..0b31d44 100644
> >> > --- a/drivers/mmc/host/tmio_mmc.h
> >> > +++ b/drivers/mmc/host/tmio_mmc.h
> >> > @@ -55,10 +55,8 @@
> >> >  /* Define some IRQ masks */
> >> >  /* This is the mask used at reset by the chip */
> >> >  #define TMIO_MASK_ALL           0x837f031d
> >> > -#define TMIO_MASK_READOP  (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND | \
> >> > -               TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
> >> > -#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND | \
> >> > -               TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
> >> > +#define TMIO_MASK_READOP  (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
> >> > +#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
> >> >  #define TMIO_MASK_CMD     (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
> >> >                TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
> >> >  #define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* Re: [Qemu-devel] [sneak preview] major scsi overhaul
From: Blue Swirl @ 2009-11-09 20:38 UTC (permalink / raw)
  To: Avi Kivity; +Cc: Gerd Hoffmann, qemu-devel@nongnu.org
In-Reply-To: <4AF80CFF.1090607@redhat.com>

On Mon, Nov 9, 2009 at 2:37 PM, Avi Kivity <avi@redhat.com> wrote:
> On 11/09/2009 11:08 AM, Gerd Hoffmann wrote:
>>
>>> You are also moving the compilation to Makefile.hw, which is not
>>> exactly an improvement. Is this needed because of the QEMUIOVector
>>> stuff?
>>
>> Almost correct ;)
>>
>> It is because of QEMUSGList which drags in a target_phys_addr_t
>> dependency.
>
> As Michael notes, devices have physical address sizes independent of the
> target platform; a PCI device that supports 64-bit addresses can be plugged
> into a motherboard that supports 32-bit address bus processors.

True. But I think the solution is not to make all buses maximum width,
but support multiple buses with width translation in between.

> We can fix this in several ways:
> - creating QEMUSG64List and QEMUSG32List (and typedefing PCISGList to the
> former)
> - making QEMUSGList always use 64-bit addresses since it will almost always
> be used with devices (which are often 64-bit capable)
> - making target_phys_addr_t always 64-bit (which loses some performance with
> 32-on-32 emulation)
> - others?

We could improve the compilation system so that on 64 bit hosts the
benefit of single size target_phys_addr_t results in compiling the
files only once.

^ permalink raw reply

* Terratec Cinergy 600 TV MK3: Problem with Radio/RDS
From: Roland Egli @ 2009-11-09 20:36 UTC (permalink / raw)
  To: video4linux-list

Hi all

I have the TV card "Terratec Cinergy 600 TV MK3" with SAA7134HL. The 
tuner is a Philips FM1216ME/H-3 and there is an additional RDS decoder 
SAA6588T.

For loading the module I use
$ modprobe saa7134 card=48 tuner=38

TV works fine, but I have a problem with the radio. The sound is very 
noisy, not stereo and there is as well no RDS reception (saa6588 module 
is loaded as well).

The following infos go to the log:
Nov  9 21:33:52 oslo kernel: [ 1667.403249] saa7130/34: v4l2 driver 
version 0.2.15 loaded
Nov  9 21:33:52 oslo kernel: [ 1667.403319] saa7134[0]: found at 
0000:02:0b.0, rev: 1, irq: 23, latency: 64, mmio: 0xfeaff400
Nov  9 21:33:52 oslo kernel: [ 1667.403330] saa7134[0]: subsystem: 
153b:1158, board: Terratec Cinergy 600 TV MK3 [card=48,insmod option]
Nov  9 21:33:52 oslo kernel: [ 1667.403365] saa7134[0]: board init: gpio 
is 50000
Nov  9 21:33:52 oslo kernel: [ 1667.403483] input: saa7134 IR (Terratec 
Cinergy 60 as /devices/pci0000:00/0000:00:1e.0/0000:02:0b.0/input/input7
Nov  9 21:33:52 oslo kernel: [ 1667.403567] IRQ 23/saa7134[0]: 
IRQF_DISABLED is not guaranteed on shared IRQs
Nov  9 21:33:52 oslo kernel: [ 1667.559198] saa7134[0]: i2c eeprom 00: 
3b 15 58 11 ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559225] saa7134[0]: i2c eeprom 10: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559251] saa7134[0]: i2c eeprom 20: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559276] saa7134[0]: i2c eeprom 30: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559300] saa7134[0]: i2c eeprom 40: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559326] saa7134[0]: i2c eeprom 50: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559351] saa7134[0]: i2c eeprom 60: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559376] saa7134[0]: i2c eeprom 70: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559400] saa7134[0]: i2c eeprom 80: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559425] saa7134[0]: i2c eeprom 90: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559450] saa7134[0]: i2c eeprom a0: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559475] saa7134[0]: i2c eeprom b0: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559500] saa7134[0]: i2c eeprom c0: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559524] saa7134[0]: i2c eeprom d0: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559549] saa7134[0]: i2c eeprom e0: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559574] saa7134[0]: i2c eeprom f0: 
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Nov  9 21:33:52 oslo kernel: [ 1667.559602] i2c-adapter i2c-0: Invalid 
7-bit address 0x7a
Nov  9 21:33:52 oslo kernel: [ 1667.592173] tuner 0-0043: chip found @ 
0x86 (saa7134[0])
Nov  9 21:33:52 oslo kernel: [ 1667.592284] tda9887 0-0043: creating new 
instance
Nov  9 21:33:52 oslo kernel: [ 1667.592287] tda9887 0-0043: 
tda988[5/6/7] found
Nov  9 21:33:52 oslo kernel: [ 1667.632092] All bytes are equal. It is 
not a TEA5767
Nov  9 21:33:52 oslo kernel: [ 1667.632309] tuner 0-0060: chip found @ 
0xc0 (saa7134[0])
Nov  9 21:33:52 oslo kernel: [ 1667.646672] tuner-simple 0-0060: 
creating new instance
Nov  9 21:33:52 oslo kernel: [ 1667.646680] tuner-simple 0-0060: type 
set to 38 (Philips PAL/SECAM multi (FM1216ME MK3))
Nov  9 21:33:52 oslo kernel: [ 1667.736118] saa6588 0-0010: saa6588 
found @ 0x20 (saa7134[0])
Nov  9 21:33:52 oslo kernel: [ 1667.744073] saa7134[0]: found RDS decoder
Nov  9 21:33:52 oslo kernel: [ 1667.752207] saa7134[0]: registered 
device video1 [v4l2]
Nov  9 21:33:52 oslo kernel: [ 1667.752276] saa7134[0]: registered 
device vbi0
Nov  9 21:33:52 oslo kernel: [ 1667.752337] saa7134[0]: registered 
device radio0
Nov  9 21:33:52 oslo kernel: [ 1667.768981] saa7134 ALSA driver for DMA 
sound loaded
Nov  9 21:33:52 oslo kernel: [ 1667.769069] IRQ 23/saa7134[0]: 
IRQF_DISABLED is not guaranteed on shared IRQs
Nov  9 21:33:52 oslo kernel: [ 1667.769109] saa7134[0]/alsa: saa7134[0] 
at 0xfeaff400 irq 23 registered as card -2

Does anyone have an idea about the reason for this problem or even 
better a solution?
Does anyone use the same card without problem?

Many thanks in advance.
Roland


--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list

^ permalink raw reply

* Re: [v11][PATCH 8/9] Define clone_with_pids() syscall
From: Serge E. Hallyn @ 2009-11-09 20:37 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: linux-kernel, Containers, Martin Schwidefsky, Heiko Carstens,
	linux-s390
In-Reply-To: <20091105054124.GH16142@us.ibm.com>

Here is a stab at the s390 syscall.

From f710be4f1296d50551210bcc9ff6ba25d288bc46 Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <serue@us.ibm.com>
Date: Fri, 6 Nov 2009 19:03:43 -0500
Subject: [PATCH 1/1] implement s390 clone_with_pids syscall

This does the s390 hook for v11 of clone-with-pids.

I've got a program using the syscall successfully passing
args to the child function and continuing to run - but I
haven't yet gotten that hooked into user-cr/restart.c
successfully.

The core of my user-space code to use it is:

int do_child(void *arg)
{
	int iarg = (int ) arg;

	printf("here i am, i was passed %d, my tid is %d\n", iarg, gettid());
	return 0;
}

 #define do_cwp(flags, pids, args, sz) \
( { \
	register unsigned long int __r2 asm ("2") = (unsigned long int)(flags); \
	register unsigned long int __r3 asm ("3") = (unsigned long int)(args); \
	register unsigned long int __r4 asm ("4") = (unsigned long int)(sz); \
	register unsigned long int __r5 asm ("5") = (unsigned long int)(pids); \
	register unsigned long int __result asm ("2"); \
	__asm__ __volatile__( \
		" lghi %%r1,%5\n" /* put __NR_cwp in r1 for svc 0 */ \
		" svc 0\n" /* do __NR_cwp syscall */ \
		" ltgr %%r2,%%r2\n" /* returned 0? */ \
		" jnz 1f\n" /* if not goto label 1 */ \
		" lg %%r3,0(%%r15)\n"   /* get fnarg off stack into arg 1 */ \
		" lg %%r2,8(%%r15)\n"   /* get fn off stack into r3 for basr*/ \
		" lgr %%r1,%%r15\n" /* tmp store old stack pointer */ \
		" aghi %%r15,-160\n" /* move the stack */ \
		" stg %%r1,0(%%r15)\n" /* and save old stack pointer */ \
		" basr %%r14,%%r3\n" /* call fn(arg) */ \
		" svc 1\n"  /* call exit */ \
		" 1:\n" \
		: "=d" (__result) \
		: "0" (__r2), "d" (__r3), "d" (__r4), "d" (__r5), \
		  "i" (__NR_clone_with_pids) \
		: "1", "cc", "memory"); \
	__result; \
} )

int clone_with_pids(int (*fn)(void *), int flags, int nrpids, int *pids,
		    void *fnarg)
{
	long retval;
	struct clone_args clone_args, *ca = &clone_args;
	int stacksize;
	void *sb;
	u64 *s;
	int i;

	memset(ca, 0, sizeof(struct clone_args));
	stacksize = 4*getpagesize();
	sb  = (void *) malloc(stacksize);
	if (!sb) {
		perror("malloc");
		_exit(1);
	}

	ca->child_stack_base = (u64) sb;
	ca->child_stack_size = stacksize-8;
	s = (u64 *)(sb + ca->child_stack_size);
	*--s = (u64)fnarg;
	*--s = (u64)fn;
	ca->child_stack_size -= 16;
	ca->nr_pids = nrpids;
	retval = do_cwp(flags, pids, ca, sizeof(struct clone_args));

	return retval;
}

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
 arch/s390/include/asm/unistd.h  |    3 +-
 arch/s390/kernel/compat_linux.c |   50 ++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/process.c      |   51 +++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/syscalls.S     |    1 +
 4 files changed, 104 insertions(+), 1 deletions(-)

diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index cb5232d..ae9474e 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -269,7 +269,8 @@
 #define	__NR_pwritev		329
 #define __NR_rt_tgsigqueueinfo	330
 #define __NR_perf_event_open	331
-#define NR_syscalls 332
+#define __NR_clone_with_pids	332
+#define NR_syscalls 333
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 0debcec..1750fae 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -762,6 +762,56 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
 	return sys_write(fd, buf, count);
 }
 
+asmlinkage long sys32_clone_with_pids(void)
+{
+	int rc;
+	struct pt_regs *regs = task_pt_regs(current);
+	int args_size;
+	struct clone_args kca;
+	unsigned long flags;
+	int __user *parent_tid_ptr;
+	int __user *child_tid_ptr;
+	unsigned long __user child_stack;
+	unsigned long stack_size;
+	unsigned int flags_low;
+	struct clone_args __user *uca;
+	pid_t __user *pids;
+
+	flags_low = regs->gprs[2] & 0xffffffffUL;
+	uca = compat_ptr(regs->gprs[3]);
+	args_size = regs->gprs[4] & 0xffffffffUL;
+	pids = compat_ptr(regs->gprs[5]);
+
+	rc = fetch_clone_args_from_user(uca, args_size, &kca);
+	if (rc)
+		return rc;
+
+	/*
+	 * TODO: Convert 'clone-flags' to 64-bits on all architectures.
+	 * TODO: When ->clone_flags_high is non-zero, copy it in to the
+	 * 	 higher word(s) of 'flags':
+	 *
+	 * 		flags = (kca.clone_flags_high << 32) | flags_low;
+	 */
+	flags = flags_low;
+	parent_tid_ptr = (int *)kca.parent_tid_ptr;
+	child_tid_ptr =  (int *)kca.child_tid_ptr;
+
+	stack_size = (unsigned long)kca.child_stack_size;
+	child_stack = (unsigned long)kca.child_stack_base + stack_size;
+
+	if (!child_stack)
+		child_stack = regs->gprs[15];
+
+	/*
+	 * TODO: On 32-bit systems, clone_flags is passed in as 32-bit value
+	 * 	 to several functions. Need to convert clone_flags to 64-bit.
+	 */
+	return do_fork_with_pids(flags, child_stack, regs, stack_size,
+				parent_tid_ptr, child_tid_ptr, kca.nr_pids,
+				pids);
+}
+
 /*
  * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
  * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5417eb5..e27a1b4 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -241,6 +241,57 @@ SYSCALL_DEFINE4(clone, unsigned long, newsp, unsigned long, clone_flags,
 		       parent_tidptr, child_tidptr);
 }
 
+SYSCALL_DEFINE0(clone_with_pids)
+{
+	int rc;
+	struct pt_regs *regs = task_pt_regs(current);
+	int args_size;
+	struct clone_args kca;
+	unsigned long flags;
+	int __user *parent_tid_ptr;
+	int __user *child_tid_ptr;
+	unsigned long __user child_stack;
+	unsigned long stack_size;
+	unsigned int flags_low;
+	struct clone_args __user *uca;
+	pid_t __user *pids;
+
+	flags_low = regs->gprs[2];
+	uca = (struct clone_args __user *)regs->gprs[3];
+	args_size = regs->gprs[4];
+	pids = (pid_t __user *)regs->gprs[5];
+
+	rc = fetch_clone_args_from_user(uca, args_size, &kca);
+	if (rc)
+		return rc;
+
+	/*
+	 * TODO: Convert 'clone-flags' to 64-bits on all architectures.
+	 * TODO: When ->clone_flags_high is non-zero, copy it in to the
+	 * 	 higher word(s) of 'flags':
+	 *
+	 * 		flags = (kca.clone_flags_high << 32) | flags_low;
+	 */
+	flags = flags_low;
+	parent_tid_ptr = (int *)kca.parent_tid_ptr;
+	child_tid_ptr =  (int *)kca.child_tid_ptr;
+
+	stack_size = (unsigned long)kca.child_stack_size;
+	child_stack = (unsigned long)kca.child_stack_base;
+	if (child_stack)
+		child_stack += stack_size;
+	else
+		child_stack = regs->gprs[15];
+
+	/*
+	 * TODO: On 32-bit systems, clone_flags is passed in as 32-bit value
+	 * 	 to several functions. Need to convert clone_flags to 64-bit.
+	 */
+	return do_fork_with_pids(flags, child_stack, regs, stack_size,
+				parent_tid_ptr, child_tid_ptr, kca.nr_pids,
+				pids);
+}
+
 /*
  * This is trivial, and on the face of it looks like it
  * could equally well be done in user mode.
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 30eca07..c6dc240 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -340,3 +340,4 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
 SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */
 SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
+SYSCALL(sys_clone_with_pids,sys_clone_with_pids,sys_clone_with_pids_wrapper)
-- 
1.6.1

^ permalink raw reply related

* Re: [v11][PATCH 8/9] Define clone_with_pids() syscall
From: Serge E. Hallyn @ 2009-11-09 20:37 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: Martin Schwidefsky, linux-s390-u79uwXL29TY76Z2rM5mHXA, Containers,
	Heiko Carstens, linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20091105054124.GH16142-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>

Here is a stab at the s390 syscall.

From f710be4f1296d50551210bcc9ff6ba25d288bc46 Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
Date: Fri, 6 Nov 2009 19:03:43 -0500
Subject: [PATCH 1/1] implement s390 clone_with_pids syscall

This does the s390 hook for v11 of clone-with-pids.

I've got a program using the syscall successfully passing
args to the child function and continuing to run - but I
haven't yet gotten that hooked into user-cr/restart.c
successfully.

The core of my user-space code to use it is:

int do_child(void *arg)
{
	int iarg = (int ) arg;

	printf("here i am, i was passed %d, my tid is %d\n", iarg, gettid());
	return 0;
}

 #define do_cwp(flags, pids, args, sz) \
( { \
	register unsigned long int __r2 asm ("2") = (unsigned long int)(flags); \
	register unsigned long int __r3 asm ("3") = (unsigned long int)(args); \
	register unsigned long int __r4 asm ("4") = (unsigned long int)(sz); \
	register unsigned long int __r5 asm ("5") = (unsigned long int)(pids); \
	register unsigned long int __result asm ("2"); \
	__asm__ __volatile__( \
		" lghi %%r1,%5\n" /* put __NR_cwp in r1 for svc 0 */ \
		" svc 0\n" /* do __NR_cwp syscall */ \
		" ltgr %%r2,%%r2\n" /* returned 0? */ \
		" jnz 1f\n" /* if not goto label 1 */ \
		" lg %%r3,0(%%r15)\n"   /* get fnarg off stack into arg 1 */ \
		" lg %%r2,8(%%r15)\n"   /* get fn off stack into r3 for basr*/ \
		" lgr %%r1,%%r15\n" /* tmp store old stack pointer */ \
		" aghi %%r15,-160\n" /* move the stack */ \
		" stg %%r1,0(%%r15)\n" /* and save old stack pointer */ \
		" basr %%r14,%%r3\n" /* call fn(arg) */ \
		" svc 1\n"  /* call exit */ \
		" 1:\n" \
		: "=d" (__result) \
		: "0" (__r2), "d" (__r3), "d" (__r4), "d" (__r5), \
		  "i" (__NR_clone_with_pids) \
		: "1", "cc", "memory"); \
	__result; \
} )

int clone_with_pids(int (*fn)(void *), int flags, int nrpids, int *pids,
		    void *fnarg)
{
	long retval;
	struct clone_args clone_args, *ca = &clone_args;
	int stacksize;
	void *sb;
	u64 *s;
	int i;

	memset(ca, 0, sizeof(struct clone_args));
	stacksize = 4*getpagesize();
	sb  = (void *) malloc(stacksize);
	if (!sb) {
		perror("malloc");
		_exit(1);
	}

	ca->child_stack_base = (u64) sb;
	ca->child_stack_size = stacksize-8;
	s = (u64 *)(sb + ca->child_stack_size);
	*--s = (u64)fnarg;
	*--s = (u64)fn;
	ca->child_stack_size -= 16;
	ca->nr_pids = nrpids;
	retval = do_cwp(flags, pids, ca, sizeof(struct clone_args));

	return retval;
}

Signed-off-by: Serge E. Hallyn <serue-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
---
 arch/s390/include/asm/unistd.h  |    3 +-
 arch/s390/kernel/compat_linux.c |   50 ++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/process.c      |   51 +++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/syscalls.S     |    1 +
 4 files changed, 104 insertions(+), 1 deletions(-)

diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index cb5232d..ae9474e 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -269,7 +269,8 @@
 #define	__NR_pwritev		329
 #define __NR_rt_tgsigqueueinfo	330
 #define __NR_perf_event_open	331
-#define NR_syscalls 332
+#define __NR_clone_with_pids	332
+#define NR_syscalls 333
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 0debcec..1750fae 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -762,6 +762,56 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
 	return sys_write(fd, buf, count);
 }
 
+asmlinkage long sys32_clone_with_pids(void)
+{
+	int rc;
+	struct pt_regs *regs = task_pt_regs(current);
+	int args_size;
+	struct clone_args kca;
+	unsigned long flags;
+	int __user *parent_tid_ptr;
+	int __user *child_tid_ptr;
+	unsigned long __user child_stack;
+	unsigned long stack_size;
+	unsigned int flags_low;
+	struct clone_args __user *uca;
+	pid_t __user *pids;
+
+	flags_low = regs->gprs[2] & 0xffffffffUL;
+	uca = compat_ptr(regs->gprs[3]);
+	args_size = regs->gprs[4] & 0xffffffffUL;
+	pids = compat_ptr(regs->gprs[5]);
+
+	rc = fetch_clone_args_from_user(uca, args_size, &kca);
+	if (rc)
+		return rc;
+
+	/*
+	 * TODO: Convert 'clone-flags' to 64-bits on all architectures.
+	 * TODO: When ->clone_flags_high is non-zero, copy it in to the
+	 * 	 higher word(s) of 'flags':
+	 *
+	 * 		flags = (kca.clone_flags_high << 32) | flags_low;
+	 */
+	flags = flags_low;
+	parent_tid_ptr = (int *)kca.parent_tid_ptr;
+	child_tid_ptr =  (int *)kca.child_tid_ptr;
+
+	stack_size = (unsigned long)kca.child_stack_size;
+	child_stack = (unsigned long)kca.child_stack_base + stack_size;
+
+	if (!child_stack)
+		child_stack = regs->gprs[15];
+
+	/*
+	 * TODO: On 32-bit systems, clone_flags is passed in as 32-bit value
+	 * 	 to several functions. Need to convert clone_flags to 64-bit.
+	 */
+	return do_fork_with_pids(flags, child_stack, regs, stack_size,
+				parent_tid_ptr, child_tid_ptr, kca.nr_pids,
+				pids);
+}
+
 /*
  * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
  * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5417eb5..e27a1b4 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -241,6 +241,57 @@ SYSCALL_DEFINE4(clone, unsigned long, newsp, unsigned long, clone_flags,
 		       parent_tidptr, child_tidptr);
 }
 
+SYSCALL_DEFINE0(clone_with_pids)
+{
+	int rc;
+	struct pt_regs *regs = task_pt_regs(current);
+	int args_size;
+	struct clone_args kca;
+	unsigned long flags;
+	int __user *parent_tid_ptr;
+	int __user *child_tid_ptr;
+	unsigned long __user child_stack;
+	unsigned long stack_size;
+	unsigned int flags_low;
+	struct clone_args __user *uca;
+	pid_t __user *pids;
+
+	flags_low = regs->gprs[2];
+	uca = (struct clone_args __user *)regs->gprs[3];
+	args_size = regs->gprs[4];
+	pids = (pid_t __user *)regs->gprs[5];
+
+	rc = fetch_clone_args_from_user(uca, args_size, &kca);
+	if (rc)
+		return rc;
+
+	/*
+	 * TODO: Convert 'clone-flags' to 64-bits on all architectures.
+	 * TODO: When ->clone_flags_high is non-zero, copy it in to the
+	 * 	 higher word(s) of 'flags':
+	 *
+	 * 		flags = (kca.clone_flags_high << 32) | flags_low;
+	 */
+	flags = flags_low;
+	parent_tid_ptr = (int *)kca.parent_tid_ptr;
+	child_tid_ptr =  (int *)kca.child_tid_ptr;
+
+	stack_size = (unsigned long)kca.child_stack_size;
+	child_stack = (unsigned long)kca.child_stack_base;
+	if (child_stack)
+		child_stack += stack_size;
+	else
+		child_stack = regs->gprs[15];
+
+	/*
+	 * TODO: On 32-bit systems, clone_flags is passed in as 32-bit value
+	 * 	 to several functions. Need to convert clone_flags to 64-bit.
+	 */
+	return do_fork_with_pids(flags, child_stack, regs, stack_size,
+				parent_tid_ptr, child_tid_ptr, kca.nr_pids,
+				pids);
+}
+
 /*
  * This is trivial, and on the face of it looks like it
  * could equally well be done in user mode.
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 30eca07..c6dc240 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -340,3 +340,4 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
 SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */
 SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
+SYSCALL(sys_clone_with_pids,sys_clone_with_pids,sys_clone_with_pids_wrapper)
-- 
1.6.1

^ permalink raw reply related

* Re: [v11][PATCH 8/9] Define clone_with_pids() syscall
From: Serge E. Hallyn @ 2009-11-09 20:37 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: linux-kernel, Containers, Martin Schwidefsky, Heiko Carstens,
	linux-s390
In-Reply-To: <20091105054124.GH16142@us.ibm.com>

Here is a stab at the s390 syscall.

>From f710be4f1296d50551210bcc9ff6ba25d288bc46 Mon Sep 17 00:00:00 2001
From: Serge E. Hallyn <serue@us.ibm.com>
Date: Fri, 6 Nov 2009 19:03:43 -0500
Subject: [PATCH 1/1] implement s390 clone_with_pids syscall

This does the s390 hook for v11 of clone-with-pids.

I've got a program using the syscall successfully passing
args to the child function and continuing to run - but I
haven't yet gotten that hooked into user-cr/restart.c
successfully.

The core of my user-space code to use it is:

int do_child(void *arg)
{
	int iarg = (int ) arg;

	printf("here i am, i was passed %d, my tid is %d\n", iarg, gettid());
	return 0;
}

 #define do_cwp(flags, pids, args, sz) \
( { \
	register unsigned long int __r2 asm ("2") = (unsigned long int)(flags); \
	register unsigned long int __r3 asm ("3") = (unsigned long int)(args); \
	register unsigned long int __r4 asm ("4") = (unsigned long int)(sz); \
	register unsigned long int __r5 asm ("5") = (unsigned long int)(pids); \
	register unsigned long int __result asm ("2"); \
	__asm__ __volatile__( \
		" lghi %%r1,%5\n" /* put __NR_cwp in r1 for svc 0 */ \
		" svc 0\n" /* do __NR_cwp syscall */ \
		" ltgr %%r2,%%r2\n" /* returned 0? */ \
		" jnz 1f\n" /* if not goto label 1 */ \
		" lg %%r3,0(%%r15)\n"   /* get fnarg off stack into arg 1 */ \
		" lg %%r2,8(%%r15)\n"   /* get fn off stack into r3 for basr*/ \
		" lgr %%r1,%%r15\n" /* tmp store old stack pointer */ \
		" aghi %%r15,-160\n" /* move the stack */ \
		" stg %%r1,0(%%r15)\n" /* and save old stack pointer */ \
		" basr %%r14,%%r3\n" /* call fn(arg) */ \
		" svc 1\n"  /* call exit */ \
		" 1:\n" \
		: "=d" (__result) \
		: "0" (__r2), "d" (__r3), "d" (__r4), "d" (__r5), \
		  "i" (__NR_clone_with_pids) \
		: "1", "cc", "memory"); \
	__result; \
} )

int clone_with_pids(int (*fn)(void *), int flags, int nrpids, int *pids,
		    void *fnarg)
{
	long retval;
	struct clone_args clone_args, *ca = &clone_args;
	int stacksize;
	void *sb;
	u64 *s;
	int i;

	memset(ca, 0, sizeof(struct clone_args));
	stacksize = 4*getpagesize();
	sb  = (void *) malloc(stacksize);
	if (!sb) {
		perror("malloc");
		_exit(1);
	}

	ca->child_stack_base = (u64) sb;
	ca->child_stack_size = stacksize-8;
	s = (u64 *)(sb + ca->child_stack_size);
	*--s = (u64)fnarg;
	*--s = (u64)fn;
	ca->child_stack_size -= 16;
	ca->nr_pids = nrpids;
	retval = do_cwp(flags, pids, ca, sizeof(struct clone_args));

	return retval;
}

Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
 arch/s390/include/asm/unistd.h  |    3 +-
 arch/s390/kernel/compat_linux.c |   50 ++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/process.c      |   51 +++++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/syscalls.S     |    1 +
 4 files changed, 104 insertions(+), 1 deletions(-)

diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index cb5232d..ae9474e 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -269,7 +269,8 @@
 #define	__NR_pwritev		329
 #define __NR_rt_tgsigqueueinfo	330
 #define __NR_perf_event_open	331
-#define NR_syscalls 332
+#define __NR_clone_with_pids	332
+#define NR_syscalls 333
 
 /* 
  * There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 0debcec..1750fae 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -762,6 +762,56 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
 	return sys_write(fd, buf, count);
 }
 
+asmlinkage long sys32_clone_with_pids(void)
+{
+	int rc;
+	struct pt_regs *regs = task_pt_regs(current);
+	int args_size;
+	struct clone_args kca;
+	unsigned long flags;
+	int __user *parent_tid_ptr;
+	int __user *child_tid_ptr;
+	unsigned long __user child_stack;
+	unsigned long stack_size;
+	unsigned int flags_low;
+	struct clone_args __user *uca;
+	pid_t __user *pids;
+
+	flags_low = regs->gprs[2] & 0xffffffffUL;
+	uca = compat_ptr(regs->gprs[3]);
+	args_size = regs->gprs[4] & 0xffffffffUL;
+	pids = compat_ptr(regs->gprs[5]);
+
+	rc = fetch_clone_args_from_user(uca, args_size, &kca);
+	if (rc)
+		return rc;
+
+	/*
+	 * TODO: Convert 'clone-flags' to 64-bits on all architectures.
+	 * TODO: When ->clone_flags_high is non-zero, copy it in to the
+	 * 	 higher word(s) of 'flags':
+	 *
+	 * 		flags = (kca.clone_flags_high << 32) | flags_low;
+	 */
+	flags = flags_low;
+	parent_tid_ptr = (int *)kca.parent_tid_ptr;
+	child_tid_ptr =  (int *)kca.child_tid_ptr;
+
+	stack_size = (unsigned long)kca.child_stack_size;
+	child_stack = (unsigned long)kca.child_stack_base + stack_size;
+
+	if (!child_stack)
+		child_stack = regs->gprs[15];
+
+	/*
+	 * TODO: On 32-bit systems, clone_flags is passed in as 32-bit value
+	 * 	 to several functions. Need to convert clone_flags to 64-bit.
+	 */
+	return do_fork_with_pids(flags, child_stack, regs, stack_size,
+				parent_tid_ptr, child_tid_ptr, kca.nr_pids,
+				pids);
+}
+
 /*
  * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
  * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5417eb5..e27a1b4 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -241,6 +241,57 @@ SYSCALL_DEFINE4(clone, unsigned long, newsp, unsigned long, clone_flags,
 		       parent_tidptr, child_tidptr);
 }
 
+SYSCALL_DEFINE0(clone_with_pids)
+{
+	int rc;
+	struct pt_regs *regs = task_pt_regs(current);
+	int args_size;
+	struct clone_args kca;
+	unsigned long flags;
+	int __user *parent_tid_ptr;
+	int __user *child_tid_ptr;
+	unsigned long __user child_stack;
+	unsigned long stack_size;
+	unsigned int flags_low;
+	struct clone_args __user *uca;
+	pid_t __user *pids;
+
+	flags_low = regs->gprs[2];
+	uca = (struct clone_args __user *)regs->gprs[3];
+	args_size = regs->gprs[4];
+	pids = (pid_t __user *)regs->gprs[5];
+
+	rc = fetch_clone_args_from_user(uca, args_size, &kca);
+	if (rc)
+		return rc;
+
+	/*
+	 * TODO: Convert 'clone-flags' to 64-bits on all architectures.
+	 * TODO: When ->clone_flags_high is non-zero, copy it in to the
+	 * 	 higher word(s) of 'flags':
+	 *
+	 * 		flags = (kca.clone_flags_high << 32) | flags_low;
+	 */
+	flags = flags_low;
+	parent_tid_ptr = (int *)kca.parent_tid_ptr;
+	child_tid_ptr =  (int *)kca.child_tid_ptr;
+
+	stack_size = (unsigned long)kca.child_stack_size;
+	child_stack = (unsigned long)kca.child_stack_base;
+	if (child_stack)
+		child_stack += stack_size;
+	else
+		child_stack = regs->gprs[15];
+
+	/*
+	 * TODO: On 32-bit systems, clone_flags is passed in as 32-bit value
+	 * 	 to several functions. Need to convert clone_flags to 64-bit.
+	 */
+	return do_fork_with_pids(flags, child_stack, regs, stack_size,
+				parent_tid_ptr, child_tid_ptr, kca.nr_pids,
+				pids);
+}
+
 /*
  * This is trivial, and on the face of it looks like it
  * could equally well be done in user mode.
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 30eca07..c6dc240 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -340,3 +340,4 @@ SYSCALL(sys_preadv,sys_preadv,compat_sys_preadv_wrapper)
 SYSCALL(sys_pwritev,sys_pwritev,compat_sys_pwritev_wrapper)
 SYSCALL(sys_rt_tgsigqueueinfo,sys_rt_tgsigqueueinfo,compat_sys_rt_tgsigqueueinfo_wrapper) /* 330 */
 SYSCALL(sys_perf_event_open,sys_perf_event_open,sys_perf_event_open_wrapper)
+SYSCALL(sys_clone_with_pids,sys_clone_with_pids,sys_clone_with_pids_wrapper)
-- 
1.6.1


^ permalink raw reply related

* [PATCH] Add COH 901 318 DMA block driver v4
From: Linus Walleij @ 2009-11-09 20:36 UTC (permalink / raw)
  To: Maciej Sosnowski, Dan Williams, linux-kernel
  Cc: linux-arm-kernel, Linus Walleij

This patch adds support for the ST-Ericsson COH 901 318 DMA block,
found in the U300 series platforms. It registers a DMA slave for
device I/O and also a memcpy slave for memcpy.

Signed-off-by: Linus Walleij <linus.walleij@stericsson.com>
---
ChangeLog v3->v4
- Removed the useless forward declaration of structs by arranging
  #includes correctly. (Alan Cox)
- NULL check ordering, exit on failure etc (Alan Cox)
- Fixed a possible overflow in if statement. (Alan Cox)
- Tag IO areas as __iomem (Alan Cox)
- Check for base adresss NULL before operating on pointer on
  several spots. (Alan Cox)
- Removed dma_map() and dma_unmap() - clients shall do this.
  (Maciej)
- Add spin_unlock() in error path for coh901318_lli_fill_sg.
  (Maciej)
- Hope it is fine now!
---
 arch/arm/mach-u300/include/mach/coh901318.h |  281 ++++++
 drivers/dma/Kconfig                         |    7 +
 drivers/dma/Makefile                        |    1 +
 drivers/dma/coh901318.c                     | 1312 +++++++++++++++++++++++++++
 drivers/dma/coh901318_lli.c                 |  318 +++++++
 drivers/dma/coh901318_lli.h                 |  124 +++
 6 files changed, 2043 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-u300/include/mach/coh901318.h
 create mode 100644 drivers/dma/coh901318.c
 create mode 100644 drivers/dma/coh901318_lli.c
 create mode 100644 drivers/dma/coh901318_lli.h

diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h
new file mode 100644
index 0000000..f4cfee9
--- /dev/null
+++ b/arch/arm/mach-u300/include/mach/coh901318.h
@@ -0,0 +1,281 @@
+/*
+ *
+ * include/linux/coh901318.h
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * DMA driver for COH 901 318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef COH901318_H
+#define COH901318_H
+
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+
+#define MAX_DMA_PACKET_SIZE_SHIFT 11
+#define MAX_DMA_PACKET_SIZE (1 << MAX_DMA_PACKET_SIZE_SHIFT)
+
+/**
+ * struct coh901318_lli - linked list item for DMAC
+ * @control: control settings for DMAC
+ * @src_addr: transfer source address
+ * @dst_addr: transfer destination address
+ * @link_addr:  physical address to next lli
+ * @virt_link_addr: virtual addres of next lli (only used by pool_free)
+ * @phy_this: physical address of current lli (only used by pool_free)
+ */
+struct coh901318_lli {
+	u32 control;
+	dma_addr_t src_addr;
+	dma_addr_t dst_addr;
+	dma_addr_t link_addr;
+
+	void *virt_link_addr;
+	dma_addr_t phy_this;
+};
+/**
+ * struct coh901318_params - parameters for DMAC configuration
+ * @config: DMA config register
+ * @ctrl_lli_last: DMA control register for the last lli in the list
+ * @ctrl_lli: DMA control register for an lli
+ * @ctrl_lli_chained: DMA control register for a chained lli
+ */
+struct coh901318_params {
+	u32 config;
+	u32 ctrl_lli_last;
+	u32 ctrl_lli;
+	u32 ctrl_lli_chained;
+};
+/**
+ * struct coh_dma_channel - dma channel base
+ * @name: ascii name of dma channel
+ * @number: channel id number
+ * @desc_nbr_max: number of preallocated descriptortors
+ * @priority_high: prio of channel, 0 low otherwise high.
+ * @param: configuration parameters
+ * @dev_addr: physical address of periphal connected to channel
+ */
+struct coh_dma_channel {
+	const char name[32];
+	const int number;
+	const int desc_nbr_max;
+	const int priority_high;
+	const struct coh901318_params param;
+	const dma_addr_t dev_addr;
+};
+
+/**
+ * dma_access_memory_state_t - register dma for memory access
+ *
+ * @dev: The dma device
+ * @active:  1 means dma intends to access memory
+ *           0 means dma wont access memory
+ */
+typedef void (*dma_access_memory_state_t)(struct device *dev,
+					  bool active);
+
+/**
+ * struct powersave - DMA power save structure
+ * @lock: lock protecting data in this struct
+ * @started_channels: bit mask indicating active dma channels
+ */
+struct powersave {
+	spinlock_t lock;
+	u64 started_channels;
+};
+/**
+ * struct coh901318_platform - platform arch structure
+ * @chans_slave: specifying dma slave channels
+ * @chans_memcpy: specifying dma memcpy channels
+ * @access_memory_state: requesting DMA memeory access (on / off)
+ * @chan_conf: dma channel configurations
+ * @max_channels: max number of dma chanenls
+ */
+struct coh901318_platform {
+	const int *chans_slave;
+	const int *chans_memcpy;
+	const dma_access_memory_state_t access_memory_state;
+	const struct coh_dma_channel *chan_conf;
+	const int max_channels;
+};
+
+/**
+ * coh901318_get_bytes_left() - Get number of bytes left on a current transfer
+ * @chan: dma channel handle
+ * return number of bytes left, or negative on error
+ */
+u32 coh901318_get_bytes_left(struct dma_chan *chan);
+
+/**
+ * coh901318_stop() - Stops dma transfer
+ * @chan: dma channel handle
+ * return 0 on success otherwise negative value
+ */
+void coh901318_stop(struct dma_chan *chan);
+
+/**
+ * coh901318_continue() - Resumes a stopped dma transfer
+ * @chan: dma channel handle
+ * return 0 on success otherwise negative value
+ */
+void coh901318_continue(struct dma_chan *chan);
+
+/**
+ * coh901318_filter_id() - DMA channel filter function
+ * @chan: dma channel handle
+ * @chan_id: id of dma channel to be filter out
+ *
+ * In dma_request_channel() it specifies what channel id to be requested
+ */
+bool coh901318_filter_id(struct dma_chan *chan, void *chan_id);
+
+/*
+ * DMA Controller - this access the static mappings of the coh901318 dma.
+ *
+ */
+
+#define COH901318_MOD32_MASK					(0x1F)
+#define COH901318_WORD_MASK					(0xFFFFFFFF)
+/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */
+#define COH901318_INT_STATUS1					(0x0000)
+#define COH901318_INT_STATUS2					(0x0004)
+/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_TC_INT_STATUS1				(0x0008)
+#define COH901318_TC_INT_STATUS2				(0x000C)
+/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */
+#define COH901318_TC_INT_CLEAR1					(0x0010)
+#define COH901318_TC_INT_CLEAR2					(0x0014)
+/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_RAW_TC_INT_STATUS1				(0x0018)
+#define COH901318_RAW_TC_INT_STATUS2				(0x001C)
+/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */
+#define COH901318_BE_INT_STATUS1				(0x0020)
+#define COH901318_BE_INT_STATUS2				(0x0024)
+/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */
+#define COH901318_BE_INT_CLEAR1					(0x0028)
+#define COH901318_BE_INT_CLEAR2					(0x002C)
+/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
+#define COH901318_RAW_BE_INT_STATUS1				(0x0030)
+#define COH901318_RAW_BE_INT_STATUS2				(0x0034)
+
+/*
+ * CX_CFG - Channel Configuration Registers 32bit (R/W)
+ */
+#define COH901318_CX_CFG					(0x0100)
+#define COH901318_CX_CFG_SPACING				(0x04)
+/* Channel enable activates tha dma job */
+#define COH901318_CX_CFG_CH_ENABLE				(0x00000001)
+#define COH901318_CX_CFG_CH_DISABLE				(0x00000000)
+/* Request Mode */
+#define COH901318_CX_CFG_RM_MASK				(0x00000006)
+#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY			(0x0 << 1)
+#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY			(0x1 << 1)
+#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY			(0x1 << 1)
+#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY		(0x3 << 1)
+#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY		(0x3 << 1)
+/* Linked channel request field. RM must == 11 */
+#define COH901318_CX_CFG_LCRF_SHIFT				3
+#define COH901318_CX_CFG_LCRF_MASK				(0x000001F8)
+#define COH901318_CX_CFG_LCR_DISABLE				(0x00000000)
+/* Terminal Counter Interrupt Request Mask */
+#define COH901318_CX_CFG_TC_IRQ_ENABLE				(0x00000200)
+#define COH901318_CX_CFG_TC_IRQ_DISABLE				(0x00000000)
+/* Bus Error interrupt Mask */
+#define COH901318_CX_CFG_BE_IRQ_ENABLE				(0x00000400)
+#define COH901318_CX_CFG_BE_IRQ_DISABLE				(0x00000000)
+
+/*
+ * CX_STAT - Channel Status Registers 32bit (R/-)
+ */
+#define COH901318_CX_STAT					(0x0200)
+#define COH901318_CX_STAT_SPACING				(0x04)
+#define COH901318_CX_STAT_RBE_IRQ_IND				(0x00000008)
+#define COH901318_CX_STAT_RTC_IRQ_IND				(0x00000004)
+#define COH901318_CX_STAT_ACTIVE				(0x00000002)
+#define COH901318_CX_STAT_ENABLED				(0x00000001)
+
+/*
+ * CX_CTRL - Channel Control Registers 32bit (R/W)
+ */
+#define COH901318_CX_CTRL					(0x0400)
+#define COH901318_CX_CTRL_SPACING				(0x10)
+/* Transfer Count Enable */
+#define COH901318_CX_CTRL_TC_ENABLE				(0x00001000)
+#define COH901318_CX_CTRL_TC_DISABLE				(0x00000000)
+/* Transfer Count Value 0 - 4095 */
+#define COH901318_CX_CTRL_TC_VALUE_MASK				(0x00000FFF)
+/* Burst count */
+#define COH901318_CX_CTRL_BURST_COUNT_MASK			(0x0000E000)
+#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES			(0x7 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES			(0x6 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES			(0x5 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES			(0x4 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES			(0x3 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES			(0x2 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES			(0x1 << 13)
+#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE			(0x0 << 13)
+/* Source bus size  */
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK			(0x00030000)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS			(0x2 << 16)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS			(0x1 << 16)
+#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS			(0x0 << 16)
+/* Source address increment */
+#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE			(0x00040000)
+#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE			(0x00000000)
+/* Destination Bus Size */
+#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK			(0x00180000)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS			(0x2 << 19)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS			(0x1 << 19)
+#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS			(0x0 << 19)
+/* Destination address increment */
+#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE			(0x00200000)
+#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE			(0x00000000)
+/* Master Mode (Master2 is only connected to MSL) */
+#define COH901318_CX_CTRL_MASTER_MODE_MASK			(0x00C00000)
+#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W			(0x3 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W			(0x2 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M2RW			(0x1 << 22)
+#define COH901318_CX_CTRL_MASTER_MODE_M1RW			(0x0 << 22)
+/* Terminal Count flag to PER enable */
+#define COH901318_CX_CTRL_TCP_ENABLE				(0x01000000)
+#define COH901318_CX_CTRL_TCP_DISABLE				(0x00000000)
+/* Terminal Count flags to CPU enable */
+#define COH901318_CX_CTRL_TC_IRQ_ENABLE				(0x02000000)
+#define COH901318_CX_CTRL_TC_IRQ_DISABLE			(0x00000000)
+/* Hand shake to peripheral */
+#define COH901318_CX_CTRL_HSP_ENABLE				(0x04000000)
+#define COH901318_CX_CTRL_HSP_DISABLE				(0x00000000)
+#define COH901318_CX_CTRL_HSS_ENABLE				(0x08000000)
+#define COH901318_CX_CTRL_HSS_DISABLE				(0x00000000)
+/* DMA mode */
+#define COH901318_CX_CTRL_DDMA_MASK				(0x30000000)
+#define COH901318_CX_CTRL_DDMA_LEGACY				(0x0 << 28)
+#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1			(0x1 << 28)
+#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2			(0x2 << 28)
+/* Primary Request Data Destination */
+#define COH901318_CX_CTRL_PRDD_MASK				(0x40000000)
+#define COH901318_CX_CTRL_PRDD_DEST				(0x1 << 30)
+#define COH901318_CX_CTRL_PRDD_SOURCE				(0x0 << 30)
+
+/*
+ * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W)
+ */
+#define COH901318_CX_SRC_ADDR					(0x0404)
+#define COH901318_CX_SRC_ADDR_SPACING				(0x10)
+
+/*
+ * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W
+ */
+#define COH901318_CX_DST_ADDR					(0x0408)
+#define COH901318_CX_DST_ADDR_SPACING				(0x10)
+
+/*
+ * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W)
+ */
+#define COH901318_CX_LNK_ADDR					(0x040C)
+#define COH901318_CX_LNK_ADDR_SPACING				(0x10)
+#define COH901318_CX_LNK_LINK_IMMEDIATE				(0x00000001)
+#endif /* COH901318_H */
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 6681519..9576028 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -109,6 +109,13 @@ config SH_DMAE
 	help
 	  Enable support for the Renesas SuperH DMA controllers.
 
+config COH901318
+	bool "ST-Ericsson COH901318 DMA support"
+	select DMA_ENGINE
+	depends on ARCH_U300
+	help
+	  Enable support for ST-Ericsson COH 901 318 DMA.
+
 config DMA_ENGINE
 	bool
 
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index eca71ba..4db768e 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
 obj-$(CONFIG_MX3_IPU) += ipu/
 obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
 obj-$(CONFIG_SH_DMAE) += shdma.o
+obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c
new file mode 100644
index 0000000..c043a6b
--- /dev/null
+++ b/drivers/dma/coh901318.c
@@ -0,0 +1,1312 @@
+/*
+ * driver/dma/coh901318.c
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * DMA driver for COH 901 318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/slab.h> /* kmalloc() */
+#include <linux/dmaengine.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/irqreturn.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <mach/coh901318.h>
+
+#include "coh901318_lli.h"
+
+#define COHC_2_DEV(cohc) (&cohc->chan.dev->device)
+
+#ifdef VERBOSE_DEBUG
+#define COH_DBG(x) ({ if (1) x; 0; })
+#else
+#define COH_DBG(x) ({ if (0) x; 0; })
+#endif
+
+struct coh901318_desc {
+	struct dma_async_tx_descriptor desc;
+	struct list_head node;
+	struct scatterlist *sg;
+	unsigned int sg_len;
+	struct coh901318_lli *data;
+	enum dma_data_direction dir;
+	int pending_irqs;
+	unsigned long flags;
+};
+
+struct coh901318_base {
+	struct device *dev;
+	void __iomem *virtbase;
+	struct coh901318_pool pool;
+	struct powersave pm;
+	struct dma_device dma_slave;
+	struct dma_device dma_memcpy;
+	struct coh901318_chan *chans;
+	struct coh901318_platform *platform;
+};
+
+struct coh901318_chan {
+	spinlock_t lock;
+	int allocated;
+	int id;
+	int stopped;
+
+	struct work_struct free_work;
+	struct dma_chan chan;
+
+	struct tasklet_struct tasklet;
+
+	struct list_head active;
+	struct list_head queue;
+	struct list_head free;
+
+	unsigned long nbr_active_done;
+	unsigned long busy;
+	int pending_irqs;
+
+	struct coh901318_base *base;
+};
+
+static void coh901318_list_print(struct coh901318_chan *cohc,
+				 struct coh901318_lli *lli)
+{
+	struct coh901318_lli *l;
+	dma_addr_t addr =  virt_to_phys(lli);
+	int i = 0;
+
+	while (addr) {
+		l = phys_to_virt(addr);
+		dev_vdbg(COHC_2_DEV(cohc), "i %d, lli %p, ctrl 0x%x, src 0x%x"
+			 ", dst 0x%x, link 0x%x link_virt 0x%p\n",
+			 i, l, l->control, l->src_addr, l->dst_addr,
+			 l->link_addr, phys_to_virt(l->link_addr));
+		i++;
+		addr = l->link_addr;
+	}
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#define COH901318_DEBUGFS_ASSIGN(x, y) (x = y)
+
+static struct coh901318_base *debugfs_dma_base;
+static struct dentry *dma_dentry;
+
+static int coh901318_debugfs_open(struct inode *inode, struct file *file)
+{
+
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static int coh901318_debugfs_read(struct file *file, char __user *buf,
+				  size_t count, loff_t *f_pos)
+{
+	u64 started_channels = debugfs_dma_base->pm.started_channels;
+	int pool_count = debugfs_dma_base->pool.debugfs_pool_counter;
+	int i;
+	int ret = 0;
+	char *dev_buf;
+	char *tmp;
+	int dev_size;
+
+	dev_buf = kmalloc(4*1024, GFP_KERNEL);
+	if (dev_buf == NULL)
+		goto err_kmalloc;
+	tmp = dev_buf;
+
+	tmp += sprintf(tmp, "DMA -- enable dma channels\n");
+
+	for (i = 0; i < debugfs_dma_base->platform->max_channels; i++)
+		if (started_channels & (1 << i))
+			tmp += sprintf(tmp, "channel %d\n", i);
+
+	tmp += sprintf(tmp, "Pool alloc nbr %d\n", pool_count);
+	dev_size = tmp  - dev_buf;
+
+	/* No more to read if offset != 0 */
+	if (*f_pos > dev_size)
+		goto out;
+
+	if (count > dev_size - *f_pos)
+		count = dev_size - *f_pos;
+
+	if (copy_to_user(buf, dev_buf + *f_pos, count))
+		ret = -EINVAL;
+	ret = count;
+	*f_pos += count;
+
+ out:
+	kfree(dev_buf);
+	return ret;
+
+ err_kmalloc:
+	return 0;
+}
+
+static const struct file_operations coh901318_debugfs_status_operations = {
+	.owner		= THIS_MODULE,
+	.open		= coh901318_debugfs_open,
+	.read		= coh901318_debugfs_read,
+};
+
+
+static int __init init_coh901318_debugfs(void)
+{
+
+	dma_dentry = debugfs_create_dir("dma", NULL);
+
+	(void) debugfs_create_file("status",
+				   S_IFREG | S_IRUGO,
+				   dma_dentry, NULL,
+				   &coh901318_debugfs_status_operations);
+	return 0;
+}
+
+static void __exit exit_coh901318_debugfs(void)
+{
+	debugfs_remove_recursive(dma_dentry);
+}
+
+module_init(init_coh901318_debugfs);
+module_exit(exit_coh901318_debugfs);
+#else
+
+#define COH901318_DEBUGFS_ASSIGN(x, y)
+
+#endif /* CONFIG_DEBUG_FS */
+
+static inline struct coh901318_chan *to_coh901318_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct coh901318_chan, chan);
+}
+
+static inline dma_addr_t
+cohc_dev_addr(struct coh901318_chan *cohc)
+{
+	return cohc->base->platform->chan_conf[cohc->id].dev_addr;
+}
+
+static inline const struct coh901318_params *
+cohc_chan_param(struct coh901318_chan *cohc)
+{
+	return &cohc->base->platform->chan_conf[cohc->id].param;
+}
+
+static inline const struct coh_dma_channel *
+cohc_chan_conf(struct coh901318_chan *cohc)
+{
+	return &cohc->base->platform->chan_conf[cohc->id];
+}
+
+static void enable_powersave(struct coh901318_chan *cohc)
+{
+	unsigned long flags;
+	struct powersave *pm = &cohc->base->pm;
+
+	spin_lock_irqsave(&pm->lock, flags);
+
+	pm->started_channels &= ~(1ULL << cohc->id);
+
+	if (!pm->started_channels) {
+		/* DMA no longer intends to access memory */
+		cohc->base->platform->access_memory_state(cohc->base->dev,
+							  false);
+	}
+
+	spin_unlock_irqrestore(&pm->lock, flags);
+}
+static void disable_powersave(struct coh901318_chan *cohc)
+{
+	unsigned long flags;
+	struct powersave *pm = &cohc->base->pm;
+
+	spin_lock_irqsave(&pm->lock, flags);
+
+	if (!pm->started_channels) {
+		/* DMA intends to access memory */
+		cohc->base->platform->access_memory_state(cohc->base->dev,
+							  true);
+	}
+
+	pm->started_channels |= (1ULL << cohc->id);
+
+	spin_unlock_irqrestore(&pm->lock, flags);
+}
+
+static inline int coh901318_set_ctrl(struct coh901318_chan *cohc, u32 control)
+{
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	writel(control,
+	       virtbase + COH901318_CX_CTRL +
+	       COH901318_CX_CTRL_SPACING * channel);
+	return 0;
+}
+
+static inline int coh901318_set_conf(struct coh901318_chan *cohc, u32 conf)
+{
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	writel(conf,
+	       virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING*channel);
+	return 0;
+}
+
+
+static int coh901318_start(struct coh901318_chan *cohc)
+{
+	u32 val;
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	disable_powersave(cohc);
+
+	val = readl(virtbase + COH901318_CX_CFG +
+		    COH901318_CX_CFG_SPACING * channel);
+
+	/* Enable channel */
+	val |= COH901318_CX_CFG_CH_ENABLE;
+	writel(val, virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING * channel);
+
+	return 0;
+}
+
+static int coh901318_prep_linked_list(struct coh901318_chan *cohc,
+				      struct coh901318_lli *data)
+{
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	BUG_ON(readl(virtbase + COH901318_CX_STAT +
+		     COH901318_CX_STAT_SPACING*channel) &
+	       COH901318_CX_STAT_ACTIVE);
+
+	writel(data->src_addr,
+	       virtbase + COH901318_CX_SRC_ADDR +
+	       COH901318_CX_SRC_ADDR_SPACING * channel);
+
+	writel(data->dst_addr, virtbase +
+	       COH901318_CX_DST_ADDR +
+	       COH901318_CX_DST_ADDR_SPACING * channel);
+
+	writel(data->link_addr, virtbase + COH901318_CX_LNK_ADDR +
+	       COH901318_CX_LNK_ADDR_SPACING * channel);
+
+	writel(data->control, virtbase + COH901318_CX_CTRL +
+	       COH901318_CX_CTRL_SPACING * channel);
+
+	return 0;
+}
+static dma_cookie_t
+coh901318_assign_cookie(struct coh901318_chan *cohc,
+			struct coh901318_desc *cohd)
+{
+	dma_cookie_t cookie = cohc->chan.cookie;
+
+	if (++cookie < 0)
+		cookie = 1;
+
+	cohc->chan.cookie = cookie;
+	cohd->desc.cookie = cookie;
+
+	return cookie;
+}
+
+static struct coh901318_desc *
+coh901318_desc_get(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *desc;
+
+	if (list_empty(&cohc->free)) {
+		/* alloc new desc because we're out of used ones
+		 * TODO: alloc a pile of descs instead of just one,
+		 * avoid many small allocations.
+		 */
+		desc = kmalloc(sizeof(struct coh901318_desc), GFP_NOWAIT);
+		if (desc == NULL)
+			goto out;
+		INIT_LIST_HEAD(&desc->node);
+	} else {
+		/* Reuse an old desc. */
+		desc = list_first_entry(&cohc->free,
+					struct coh901318_desc,
+					node);
+		list_del(&desc->node);
+	}
+
+ out:
+	return desc;
+}
+
+static void
+coh901318_desc_free(struct coh901318_chan *cohc, struct coh901318_desc *cohd)
+{
+	list_add_tail(&cohd->node, &cohc->free);
+}
+
+/* call with irq lock held */
+static void
+coh901318_desc_submit(struct coh901318_chan *cohc, struct coh901318_desc *desc)
+{
+	list_add_tail(&desc->node, &cohc->active);
+
+	BUG_ON(cohc->pending_irqs != 0);
+
+	cohc->pending_irqs = desc->pending_irqs;
+}
+
+static struct coh901318_desc *
+coh901318_first_active_get(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *d;
+
+	if (list_empty(&cohc->active))
+		return NULL;
+
+	d = list_first_entry(&cohc->active,
+			     struct coh901318_desc,
+			     node);
+	return d;
+}
+
+static void
+coh901318_desc_remove(struct coh901318_desc *cohd)
+{
+	list_del(&cohd->node);
+}
+
+static void
+coh901318_desc_queue(struct coh901318_chan *cohc, struct coh901318_desc *desc)
+{
+	list_add_tail(&desc->node, &cohc->queue);
+}
+
+static struct coh901318_desc *
+coh901318_first_queued(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *d;
+
+	if (list_empty(&cohc->queue))
+		return NULL;
+
+	d = list_first_entry(&cohc->queue,
+			     struct coh901318_desc,
+			     node);
+	return d;
+}
+
+/*
+ * DMA start/stop controls
+ */
+u32 coh901318_get_bytes_left(struct dma_chan *chan)
+{
+	unsigned long flags;
+	u32 ret;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Read transfer count value */
+	ret = readl(cohc->base->virtbase +
+		    COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING *
+		    cohc->id) & COH901318_CX_CTRL_TC_VALUE_MASK;
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	return ret;
+}
+EXPORT_SYMBOL(coh901318_get_bytes_left);
+
+
+/* Stops a transfer without losing data. Enables power save.
+   Use this function in conjunction with coh901318_continue(..)
+*/
+void coh901318_stop(struct dma_chan *chan)
+{
+	u32 val;
+	unsigned long flags;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Disable channel in HW */
+	val = readl(virtbase + COH901318_CX_CFG +
+		    COH901318_CX_CFG_SPACING * channel);
+
+	/* Stopping infinit transfer */
+	if ((val & COH901318_CX_CTRL_TC_ENABLE) == 0 &&
+	    (val & COH901318_CX_CFG_CH_ENABLE))
+		cohc->stopped = 1;
+
+
+	val &= ~COH901318_CX_CFG_CH_ENABLE;
+	/* Enable twice, HW bug work around */
+	writel(val, virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING * channel);
+	writel(val, virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING * channel);
+
+	/* Spin-wait for it to actually go inactive */
+	while (readl(virtbase + COH901318_CX_STAT+COH901318_CX_STAT_SPACING *
+		     channel) & COH901318_CX_STAT_ACTIVE)
+		cpu_relax();
+
+	/* Check if we stopped an active job */
+	if ((readl(virtbase + COH901318_CX_CTRL+COH901318_CX_CTRL_SPACING *
+		   channel) & COH901318_CX_CTRL_TC_VALUE_MASK) > 0)
+		cohc->stopped = 1;
+
+	enable_powersave(cohc);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+EXPORT_SYMBOL(coh901318_stop);
+
+/* Continues a transfer that has been stopped via 300_dma_stop(..).
+   Power save is handled.
+*/
+void coh901318_continue(struct dma_chan *chan)
+{
+	u32 val;
+	unsigned long flags;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	int channel = cohc->id;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	disable_powersave(cohc);
+
+	if (cohc->stopped) {
+		/* Enable channel in HW */
+		val = readl(cohc->base->virtbase + COH901318_CX_CFG +
+			    COH901318_CX_CFG_SPACING * channel);
+
+		val |= COH901318_CX_CFG_CH_ENABLE;
+
+		writel(val, cohc->base->virtbase + COH901318_CX_CFG +
+		       COH901318_CX_CFG_SPACING*channel);
+
+		cohc->stopped = 0;
+	}
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+EXPORT_SYMBOL(coh901318_continue);
+
+bool coh901318_filter_id(struct dma_chan *chan, void *chan_id)
+{
+	unsigned int ch_nr = (unsigned int) chan_id;
+
+	if (ch_nr == to_coh901318_chan(chan)->id)
+		return true;
+
+	return false;
+}
+EXPORT_SYMBOL(coh901318_filter_id);
+
+/*
+ * DMA channel allocation
+ */
+static int coh901318_config(struct coh901318_chan *cohc,
+			    struct coh901318_params *param)
+{
+	unsigned long flags;
+	const struct coh901318_params *p;
+	int channel = cohc->id;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	if (param)
+		p = param;
+	else
+		p = &cohc->base->platform->chan_conf[channel].param;
+
+	/* Clear any pending BE or TC interrupt */
+	if (channel < 32) {
+		writel(1 << channel, virtbase + COH901318_BE_INT_CLEAR1);
+		writel(1 << channel, virtbase + COH901318_TC_INT_CLEAR1);
+	} else {
+		writel(1 << (channel - 32), virtbase +
+		       COH901318_BE_INT_CLEAR2);
+		writel(1 << (channel - 32), virtbase +
+		       COH901318_TC_INT_CLEAR2);
+	}
+
+	coh901318_set_conf(cohc, p->config);
+	coh901318_set_ctrl(cohc, p->ctrl_lli_last);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	return 0;
+}
+
+/* must lock when calling this function
+ * start queued jobs, if any
+ * TODO: start all queued jobs in one go
+ *
+ * Returns descriptor if queued job is started otherwise NULL.
+ * If the queue is empty NULL is returned.
+ */
+static struct coh901318_desc *coh901318_queue_start(struct coh901318_chan *cohc)
+{
+	struct coh901318_desc *cohd_que;
+
+	/* start queued jobs, if any
+	 * TODO: transmit all queued jobs in one go
+	 */
+	cohd_que = coh901318_first_queued(cohc);
+
+	if (cohd_que != NULL) {
+		/* Remove from queue */
+		coh901318_desc_remove(cohd_que);
+		/* initiate DMA job */
+		cohc->busy = 1;
+
+		coh901318_desc_submit(cohc, cohd_que);
+
+		coh901318_prep_linked_list(cohc, cohd_que->data);
+
+		/* start dma job */
+		coh901318_start(cohc);
+
+	}
+
+	return cohd_que;
+}
+
+static void dma_tasklet(unsigned long data)
+{
+	struct coh901318_chan *cohc = (struct coh901318_chan *) data;
+	struct coh901318_desc *cohd_fin;
+	unsigned long flags;
+	dma_async_tx_callback callback;
+	void *callback_param;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* get first active entry from list */
+	cohd_fin = coh901318_first_active_get(cohc);
+
+	BUG_ON(cohd_fin->pending_irqs == 0);
+
+	if (cohd_fin == NULL)
+		goto err;
+
+	cohd_fin->pending_irqs--;
+
+	BUG_ON(cohc->nbr_active_done && cohd_fin == NULL);
+
+	if (cohc->nbr_active_done == 0)
+		return;
+
+	if (!cohd_fin->pending_irqs) {
+		/* release the lli allocation*/
+		coh901318_lli_free(&cohc->base->pool, &cohd_fin->data);
+	}
+
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] chan_id %d pending_irqs %d"
+		 " nbr_active_done %ld\n", __func__,
+		 cohc->id, cohc->pending_irqs, cohc->nbr_active_done);
+
+	/* callback to client */
+	callback = cohd_fin->desc.callback;
+	callback_param = cohd_fin->desc.callback_param;
+
+	if (!cohd_fin->pending_irqs) {
+		coh901318_desc_remove(cohd_fin);
+
+		/* return desc to free-list */
+		coh901318_desc_free(cohc, cohd_fin);
+	}
+
+	if (cohc->nbr_active_done)
+		cohc->nbr_active_done--;
+
+	if (cohc->nbr_active_done) {
+		if (cohc_chan_conf(cohc)->priority_high)
+			tasklet_hi_schedule(&cohc->tasklet);
+		else
+			tasklet_schedule(&cohc->tasklet);
+	}
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	if (callback)
+		callback(callback_param);
+
+	return;
+
+ err:
+	spin_unlock_irqrestore(&cohc->lock, flags);
+	dev_err(COHC_2_DEV(cohc), "[%s] No active dma desc\n", __func__);
+}
+
+
+/* called from interrupt context */
+static void dma_tc_handle(struct coh901318_chan *cohc)
+{
+	BUG_ON(!cohc->allocated && (list_empty(&cohc->active) ||
+				    list_empty(&cohc->queue)));
+
+	if (!cohc->allocated)
+		return;
+
+	BUG_ON(cohc->pending_irqs == 0);
+
+	cohc->pending_irqs--;
+	cohc->nbr_active_done++;
+
+	if (cohc->pending_irqs == 0 && coh901318_queue_start(cohc) == NULL)
+		cohc->busy = 0;
+
+	BUG_ON(list_empty(&cohc->active));
+
+	if (cohc_chan_conf(cohc)->priority_high)
+		tasklet_hi_schedule(&cohc->tasklet);
+	else
+		tasklet_schedule(&cohc->tasklet);
+}
+
+
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+	u32 status1;
+	u32 status2;
+	int i;
+	int ch;
+	struct coh901318_base *base  = dev_id;
+	struct coh901318_chan *cohc;
+	void __iomem *virtbase = base->virtbase;
+
+	status1 = readl(virtbase + COH901318_INT_STATUS1);
+	status2 = readl(virtbase + COH901318_INT_STATUS2);
+
+	if (unlikely(status1 == 0 && status2 == 0)) {
+		dev_warn(base->dev, "spurious DMA IRQ from no channel!\n");
+		return IRQ_HANDLED;
+	}
+
+	/* TODO: consider handle IRQ in tasklet here to
+	 *       minimize interrupt latency */
+
+	/* Check the first 32 DMA channels for IRQ */
+	while (status1) {
+		/* Find first bit set, return as a number. */
+		i = ffs(status1) - 1;
+		ch = i;
+
+		cohc = &base->chans[ch];
+		spin_lock(&cohc->lock);
+
+		/* Mask off this bit */
+		status1 &= ~(1 << i);
+		/* Check the individual channel bits */
+		if (test_bit(i, virtbase + COH901318_BE_INT_STATUS1)) {
+			dev_crit(COHC_2_DEV(cohc),
+				 "DMA bus error on channel %d!\n", ch);
+			BUG_ON(1);
+			/* Clear BE interrupt */
+			__set_bit(i, virtbase + COH901318_BE_INT_CLEAR1);
+		} else {
+			/* Caused by TC, really? */
+			if (unlikely(!test_bit(i, virtbase +
+					       COH901318_TC_INT_STATUS1))) {
+				dev_warn(COHC_2_DEV(cohc),
+					 "ignoring interrupt not caused by terminal count on channel %d\n", ch);
+				/* Clear TC interrupt */
+				BUG_ON(1);
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR1);
+			} else {
+				/* Enable powersave if transfer has finished */
+				if (!(readl(virtbase + COH901318_CX_STAT +
+					    COH901318_CX_STAT_SPACING*ch) &
+				      COH901318_CX_STAT_ENABLED)) {
+					enable_powersave(cohc);
+				}
+
+				/* Must clear TC interrupt before calling
+				 * dma_tc_handle
+				 * in case tc_handle initate a new dma job
+				 */
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR1);
+
+				dma_tc_handle(cohc);
+			}
+		}
+		spin_unlock(&cohc->lock);
+	}
+
+	/* Check the remaining 32 DMA channels for IRQ */
+	while (status2) {
+		/* Find first bit set, return as a number. */
+		i = ffs(status2) - 1;
+		ch = i + 32;
+		cohc = &base->chans[ch];
+		spin_lock(&cohc->lock);
+
+		/* Mask off this bit */
+		status2 &= ~(1 << i);
+		/* Check the individual channel bits */
+		if (test_bit(i, virtbase + COH901318_BE_INT_STATUS2)) {
+			dev_crit(COHC_2_DEV(cohc),
+				 "DMA bus error on channel %d!\n", ch);
+			/* Clear BE interrupt */
+			BUG_ON(1);
+			__set_bit(i, virtbase + COH901318_BE_INT_CLEAR2);
+		} else {
+			/* Caused by TC, really? */
+			if (unlikely(!test_bit(i, virtbase +
+					       COH901318_TC_INT_STATUS2))) {
+				dev_warn(COHC_2_DEV(cohc),
+					 "ignoring interrupt not caused by terminal count on channel %d\n", ch);
+				/* Clear TC interrupt */
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR2);
+				BUG_ON(1);
+			} else {
+				/* Enable powersave if transfer has finished */
+				if (!(readl(virtbase + COH901318_CX_STAT +
+					    COH901318_CX_STAT_SPACING*ch) &
+				      COH901318_CX_STAT_ENABLED)) {
+					enable_powersave(cohc);
+				}
+				/* Must clear TC interrupt before calling
+				 * dma_tc_handle
+				 * in case tc_handle initate a new dma job
+				 */
+				__set_bit(i, virtbase + COH901318_TC_INT_CLEAR2);
+
+				dma_tc_handle(cohc);
+			}
+		}
+		spin_unlock(&cohc->lock);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int coh901318_alloc_chan_resources(struct dma_chan *chan)
+{
+	struct coh901318_chan	*cohc = to_coh901318_chan(chan);
+
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] DMA channel %d\n",
+		 __func__, cohc->id);
+
+	if (chan->client_count > 1)
+		return -EBUSY;
+
+	coh901318_config(cohc, NULL);
+
+	cohc->allocated = 1;
+
+	return 1;
+}
+
+static void
+coh901318_free_chan_resources(struct dma_chan *chan)
+{
+	struct coh901318_chan	*cohc = to_coh901318_chan(chan);
+	int channel = cohc->id;
+	unsigned long flags;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Disable HW */
+	writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CFG +
+	       COH901318_CX_CFG_SPACING*channel);
+	writel(0x00000000U, cohc->base->virtbase + COH901318_CX_CTRL +
+	       COH901318_CX_CTRL_SPACING*channel);
+
+	cohc->allocated = 0;
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	chan->device->device_terminate_all(chan);
+}
+
+
+static dma_cookie_t
+coh901318_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+	struct coh901318_desc *cohd = container_of(tx, struct coh901318_desc,
+						   desc);
+	struct coh901318_chan *cohc = to_coh901318_chan(tx->chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	tx->cookie = coh901318_assign_cookie(cohc, cohd);
+
+	coh901318_desc_queue(cohc, cohd);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+
+	return tx->cookie;
+}
+
+static struct dma_async_tx_descriptor *
+coh901318_prep_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
+		      size_t size, unsigned long flags)
+{
+	struct coh901318_lli *data;
+	struct coh901318_desc *cohd;
+	unsigned long flg;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	int lli_len;
+
+	spin_lock_irqsave(&cohc->lock, flg);
+
+	dev_vdbg(COHC_2_DEV(cohc),
+		 "[%s] channel %d src 0x%x dest 0x%x size %d\n",
+		 __func__, cohc->id, src, dest, size);
+
+	lli_len = size >> MAX_DMA_PACKET_SIZE_SHIFT;
+	if ((lli_len << MAX_DMA_PACKET_SIZE_SHIFT) < size)
+		lli_len++;
+
+	data = coh901318_lli_alloc(&cohc->base->pool, lli_len);
+
+	if (data == NULL)
+		goto err;
+
+	cohd = coh901318_desc_get(cohc);
+	cohd->sg = NULL;
+	cohd->sg_len = 0;
+	cohd->data = data;
+
+	cohd->pending_irqs =
+		coh901318_lli_fill_memcpy(
+					  &cohc->base->pool, data, src, size, dest,
+					  cohc_chan_param(cohc)->ctrl_lli_chained,
+					  cohc_chan_param(cohc)->ctrl_lli_last);
+	cohd->flags = flags;
+
+	COH_DBG(coh901318_list_print(cohc, data));
+
+	dma_async_tx_descriptor_init(&cohd->desc, chan);
+
+	cohd->desc.tx_submit = coh901318_tx_submit;
+
+	spin_unlock_irqrestore(&cohc->lock, flg);
+
+	return &cohd->desc;
+ err:
+	spin_unlock_irqrestore(&cohc->lock, flg);
+	return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+coh901318_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+			unsigned int sg_len, enum dma_data_direction direction,
+			unsigned long flags)
+{
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	struct coh901318_lli *data;
+	struct coh901318_desc *cohd;
+	struct scatterlist *sg;
+	int len = 0;
+	int size;
+	int i;
+	u32 ctrl_chained = cohc_chan_param(cohc)->ctrl_lli_chained;
+	u32 ctrl = cohc_chan_param(cohc)->ctrl_lli;
+	u32 ctrl_last = cohc_chan_param(cohc)->ctrl_lli_last;
+	unsigned long flg;
+
+	if (!sgl)
+		goto out;
+	if (sgl->length == 0)
+		goto out;
+
+	spin_lock_irqsave(&cohc->lock, flg);
+
+	dev_vdbg(COHC_2_DEV(cohc), "[%s] sg_len %d dir %d\n",
+		 __func__, sg_len, direction);
+
+	cohd = coh901318_desc_get(cohc);
+	cohd->sg = NULL;
+	cohd->sg_len = 0;
+	cohd->dir = direction;
+
+	if (direction == DMA_TO_DEVICE) {
+		u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE |
+			COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE;
+
+		ctrl_chained |= tx_flags;
+		ctrl_last |= tx_flags;
+		ctrl |= tx_flags;
+	} else if (direction == DMA_FROM_DEVICE) {
+		u32 rx_flags = COH901318_CX_CTRL_PRDD_DEST |
+			COH901318_CX_CTRL_DST_ADDR_INC_ENABLE;
+
+		ctrl_chained |= rx_flags;
+		ctrl_last |= rx_flags;
+		ctrl |= rx_flags;
+	} else
+		goto err_direction;
+
+	dma_async_tx_descriptor_init(&cohd->desc, chan);
+
+	cohd->desc.tx_submit = coh901318_tx_submit;
+
+
+	/* The dma only supports transmitting packages up to
+	 * MAX_DMA_PACKET_SIZE. Calculate to total number of
+	 * dma elemts required to send the entire sg list
+	 */
+	for_each_sg(sgl, sg, sg_len, i) {
+		unsigned int factor;
+		size = sg_dma_len(sg);
+
+		if (size <= MAX_DMA_PACKET_SIZE) {
+			len++;
+			continue;
+		}
+
+		factor = size >> MAX_DMA_PACKET_SIZE_SHIFT;
+		if ((factor << MAX_DMA_PACKET_SIZE_SHIFT) < size)
+			factor++;
+
+		len += factor;
+	}
+
+	data = coh901318_lli_alloc(&cohc->base->pool, len);
+
+	if (data == NULL)
+		goto err_dma_alloc;
+
+	/* initiate allocated data list */
+	cohd->pending_irqs =
+		coh901318_lli_fill_sg(&cohc->base->pool, data, sgl, sg_len,
+				      cohc_dev_addr(cohc),
+				      ctrl_chained,
+				      ctrl,
+				      ctrl_last,
+				      direction, COH901318_CX_CTRL_TC_IRQ_ENABLE);
+	cohd->data = data;
+
+	cohd->flags = flags;
+
+	COH_DBG(coh901318_list_print(cohc, data));
+
+	spin_unlock_irqrestore(&cohc->lock, flg);
+
+	return &cohd->desc;
+ err_dma_alloc:
+ err_direction:
+	coh901318_desc_remove(cohd);
+	coh901318_desc_free(cohc, cohd);
+	spin_unlock_irqrestore(&cohc->lock, flg);
+ out:
+	return NULL;
+}
+
+static struct dma_async_tx_descriptor *
+coh901318_prep_interrupt(struct dma_chan *chan,
+			 unsigned long flags)
+{
+	/* TODO implement */
+
+	return NULL;
+}
+
+static enum dma_status
+coh901318_is_tx_complete(struct dma_chan *chan,
+			 dma_cookie_t cookie, dma_cookie_t *last,
+			 dma_cookie_t *used)
+{
+	/* TODO implement */
+
+	return DMA_SUCCESS;
+}
+
+static void
+coh901318_issue_pending(struct dma_chan *chan)
+{
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	unsigned long flags;
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Busy means that pending jobs are already being processed */
+	if (!cohc->busy)
+		coh901318_queue_start(cohc);
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+
+static void
+coh901318_terminate_all(struct dma_chan *chan)
+{
+	unsigned long flags;
+	struct coh901318_chan *cohc = to_coh901318_chan(chan);
+	struct coh901318_desc *cohd;
+	void __iomem *virtbase = cohc->base->virtbase;
+
+	coh901318_stop(chan);
+
+	spin_lock_irqsave(&cohc->lock, flags);
+
+	/* Clear any pending BE or TC interrupt */
+	if (cohc->id < 32) {
+		writel(1 << cohc->id, virtbase + COH901318_BE_INT_CLEAR1);
+		writel(1 << cohc->id, virtbase + COH901318_TC_INT_CLEAR1);
+	} else {
+		writel(1 << (cohc->id - 32), virtbase +
+		       COH901318_BE_INT_CLEAR2);
+		writel(1 << (cohc->id - 32), virtbase +
+		       COH901318_TC_INT_CLEAR2);
+	}
+
+	enable_powersave(cohc);
+
+	while ((cohd = coh901318_first_active_get(cohc))) {
+		/* release the lli allocation*/
+		coh901318_lli_free(&cohc->base->pool, &cohd->data);
+
+		coh901318_desc_remove(cohd);
+
+		/* return desc to free-list */
+		coh901318_desc_free(cohc, cohd);
+	}
+
+	while ((cohd = coh901318_first_queued(cohc))) {
+		/* release the lli allocation*/
+		coh901318_lli_free(&cohc->base->pool, &cohd->data);
+
+		coh901318_desc_remove(cohd);
+
+		/* return desc to free-list */
+		coh901318_desc_free(cohc, cohd);
+	}
+
+
+	cohc->nbr_active_done = 0;
+	cohc->busy = 0;
+	cohc->pending_irqs = 0;
+
+	spin_unlock_irqrestore(&cohc->lock, flags);
+}
+void coh901318_base_init(struct dma_device *dma, const int *pick_chans,
+			 struct coh901318_base *base)
+{
+	int chans_i;
+	int i = 0;
+	struct coh901318_chan *cohc;
+
+	INIT_LIST_HEAD(&dma->channels);
+
+	for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) {
+		for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) {
+			cohc = &base->chans[i];
+
+			cohc->base = base;
+			cohc->chan.device = dma;
+			cohc->id = i;
+			cohc->chan.cookie = i;
+
+			/* TODO: do we really need this lock if only one
+			 * client is connected to each channel?
+			 */
+
+			spin_lock_init(&cohc->lock);
+
+			cohc->pending_irqs = 0;
+			cohc->nbr_active_done = 0;
+			cohc->busy = 0;
+			INIT_LIST_HEAD(&cohc->free);
+			INIT_LIST_HEAD(&cohc->active);
+			INIT_LIST_HEAD(&cohc->queue);
+
+			tasklet_init(&cohc->tasklet, dma_tasklet,
+				     (unsigned long) cohc);
+
+			list_add_tail(&cohc->chan.device_node,
+				      &dma->channels);
+		}
+	}
+}
+
+static int __init coh901318_probe(struct platform_device *pdev)
+{
+	int err = 0;
+	struct coh901318_platform *pdata;
+	struct coh901318_base *base;
+	int irq;
+	struct resource *io;
+
+	io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!io)
+		goto err_get_resource;
+
+	/* Map DMA controller registers to virtual memory */
+	if (request_mem_region(io->start,
+			       resource_size(io),
+			       pdev->dev.driver->name) == NULL) {
+		err = -EBUSY;
+		goto err_request_mem;
+	}
+
+	pdata = pdev->dev.platform_data;
+	if (!pdata)
+		goto err_no_platformdata;
+
+	base = kmalloc(ALIGN(sizeof(struct coh901318_base), 4) +
+		       pdata->max_channels *
+		       sizeof(struct coh901318_chan),
+		       GFP_KERNEL);
+	if (!base)
+		goto err_alloc_coh_dma_channels;
+
+	base->chans = ((void *)base) + ALIGN(sizeof(struct coh901318_base), 4);
+
+	base->virtbase = ioremap(io->start, resource_size(io));
+	if (!base->virtbase) {
+		err = -ENOMEM;
+		goto err_no_ioremap;
+	}
+
+	base->dev = &pdev->dev;
+	base->platform = pdata;
+	spin_lock_init(&base->pm.lock);
+	base->pm.started_channels = 0;
+
+	COH901318_DEBUGFS_ASSIGN(debugfs_dma_base, base);
+
+	platform_set_drvdata(pdev, base);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto err_no_irq;
+
+	err = request_irq(irq, dma_irq_handler, IRQF_DISABLED,
+			  "coh901318", base);
+	if (err) {
+		dev_crit(&pdev->dev,
+			 "Cannot allocate IRQ for DMA controller!\n");
+		goto err_request_irq;
+	}
+
+	err = coh901318_pool_create(&base->pool, &pdev->dev,
+				    sizeof(struct coh901318_lli),
+				    32);
+	if (err)
+		goto err_pool_create;
+
+	/* init channels for device transfers */
+	coh901318_base_init(&base->dma_slave,  base->platform->chans_slave,
+			    base);
+
+	dma_cap_zero(base->dma_slave.cap_mask);
+	dma_cap_set(DMA_SLAVE, base->dma_slave.cap_mask);
+
+	base->dma_slave.device_alloc_chan_resources = coh901318_alloc_chan_resources;
+	base->dma_slave.device_free_chan_resources = coh901318_free_chan_resources;
+	base->dma_slave.device_prep_dma_interrupt = coh901318_prep_interrupt;
+	base->dma_slave.device_prep_slave_sg = coh901318_prep_slave_sg;
+	base->dma_slave.device_is_tx_complete = coh901318_is_tx_complete;
+	base->dma_slave.device_issue_pending = coh901318_issue_pending;
+	base->dma_slave.device_terminate_all = coh901318_terminate_all;
+	base->dma_slave.dev = &pdev->dev;
+
+	err = dma_async_device_register(&base->dma_slave);
+
+	if (err)
+		goto err_register_slave;
+
+	/* init channels for memcpy */
+	coh901318_base_init(&base->dma_memcpy, base->platform->chans_memcpy,
+			    base);
+
+	dma_cap_zero(base->dma_memcpy.cap_mask);
+	dma_cap_set(DMA_MEMCPY, base->dma_memcpy.cap_mask);
+
+	base->dma_memcpy.device_alloc_chan_resources = coh901318_alloc_chan_resources;
+	base->dma_memcpy.device_free_chan_resources = coh901318_free_chan_resources;
+	base->dma_memcpy.device_prep_dma_interrupt = coh901318_prep_interrupt;
+	base->dma_memcpy.device_prep_dma_memcpy = coh901318_prep_memcpy;
+	base->dma_memcpy.device_is_tx_complete = coh901318_is_tx_complete;
+	base->dma_memcpy.device_issue_pending = coh901318_issue_pending;
+	base->dma_memcpy.device_terminate_all = coh901318_terminate_all;
+	base->dma_memcpy.dev = &pdev->dev;
+	err = dma_async_device_register(&base->dma_memcpy);
+
+	if (err)
+		goto err_register_memcpy;
+
+	dev_dbg(&pdev->dev, "Initialized COH901318 DMA on virtual base 0x%08x\n",
+		(u32) base->virtbase);
+
+	return err;
+
+ err_register_memcpy:
+	dma_async_device_unregister(&base->dma_slave);
+ err_register_slave:
+	coh901318_pool_destroy(&base->pool);
+ err_pool_create:
+	free_irq(platform_get_irq(pdev, 0), base);
+ err_request_irq:
+ err_no_irq:
+	iounmap(base->virtbase);
+ err_no_ioremap:
+	kfree(base);
+ err_alloc_coh_dma_channels:
+ err_no_platformdata:
+	release_mem_region(pdev->resource->start,
+			   resource_size(pdev->resource));
+ err_request_mem:
+ err_get_resource:
+	return err;
+}
+
+static int __exit coh901318_remove(struct platform_device *pdev)
+{
+	struct coh901318_base *base = platform_get_drvdata(pdev);
+
+	dma_async_device_unregister(&base->dma_memcpy);
+	dma_async_device_unregister(&base->dma_slave);
+	coh901318_pool_destroy(&base->pool);
+	free_irq(platform_get_irq(pdev, 0), base);
+	kfree(base);
+	iounmap(base->virtbase);
+	release_mem_region(pdev->resource->start,
+			   resource_size(pdev->resource));
+	return 0;
+}
+
+
+static struct platform_driver coh901318_driver = {
+	.remove = __exit_p(coh901318_remove),
+	.driver = {
+		.name	= "coh901318",
+	},
+};
+
+int __init coh901318_init(void)
+{
+	return platform_driver_probe(&coh901318_driver, coh901318_probe);
+}
+subsys_initcall(coh901318_init);
+
+void __exit coh901318_exit(void)
+{
+	platform_driver_unregister(&coh901318_driver);
+}
+module_exit(coh901318_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Per Friden");
diff --git a/drivers/dma/coh901318_lli.c b/drivers/dma/coh901318_lli.c
new file mode 100644
index 0000000..c5f7e15
--- /dev/null
+++ b/drivers/dma/coh901318_lli.c
@@ -0,0 +1,318 @@
+/*
+ * driver/dma/coh901318_lli.c
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Support functions for handling lli for dma
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/dmapool.h>
+#include <linux/memory.h>
+#include <mach/coh901318.h>
+
+#include "coh901318_lli.h"
+
+#if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
+#define DEBUGFS_POOL_COUNTER_RESET(pool) (pool->debugfs_pool_counter = 0)
+#define DEBUGFS_POOL_COUNTER_ADD(pool, add) (pool->debugfs_pool_counter += add)
+#else
+#define DEBUGFS_POOL_COUNTER_RESET(pool)
+#define DEBUGFS_POOL_COUNTER_ADD(pool, add)
+#endif
+
+static struct coh901318_lli *
+coh901318_lli_next(struct coh901318_lli *data)
+{
+	if (data == NULL || data->link_addr == 0)
+		return NULL;
+
+	return (struct coh901318_lli *) data->virt_link_addr;
+}
+
+int coh901318_pool_create(struct coh901318_pool *pool,
+			  struct device *dev,
+			  size_t size, size_t align)
+{
+	spin_lock_init(&pool->lock);
+	pool->dev = dev;
+	pool->dmapool = dma_pool_create("lli_pool", dev, size, align, 0);
+
+	DEBUGFS_POOL_COUNTER_RESET(pool);
+	return 0;
+}
+
+int coh901318_pool_destroy(struct coh901318_pool *pool)
+{
+
+	dma_pool_destroy(pool->dmapool);
+	return 0;
+}
+
+struct coh901318_lli *
+coh901318_lli_alloc(struct coh901318_pool *pool, unsigned int len)
+{
+	int i;
+	struct coh901318_lli *head;
+	struct coh901318_lli *lli;
+	struct coh901318_lli *lli_prev;
+	dma_addr_t phy;
+
+	if (len == 0)
+		goto err;
+
+	spin_lock(&pool->lock);
+
+	head = dma_pool_alloc(pool->dmapool, GFP_ATOMIC, &phy);
+
+	if (head == NULL)
+		goto err;
+
+	DEBUGFS_POOL_COUNTER_ADD(pool, 1);
+
+	lli = head;
+	lli->phy_this = phy;
+
+	for (i = 1; i < len; i++) {
+		lli_prev = lli;
+
+		lli = dma_pool_alloc(pool->dmapool, GFP_ATOMIC, &phy);
+
+		if (lli == NULL)
+			goto err_clean_up;
+
+		DEBUGFS_POOL_COUNTER_ADD(pool, 1);
+		lli->phy_this = phy;
+
+		lli_prev->link_addr = phy;
+		lli_prev->virt_link_addr = lli;
+	}
+
+	lli->link_addr = 0x00000000U;
+
+	spin_unlock(&pool->lock);
+
+	return head;
+
+ err:
+	spin_unlock(&pool->lock);
+	return NULL;
+
+ err_clean_up:
+	lli_prev->link_addr = 0x00000000U;
+	spin_unlock(&pool->lock);
+	coh901318_lli_free(pool, &head);
+	return NULL;
+}
+
+void coh901318_lli_free(struct coh901318_pool *pool,
+			struct coh901318_lli **lli)
+{
+	struct coh901318_lli *l;
+	struct coh901318_lli *next;
+
+	if (lli == NULL)
+		return;
+
+	l = *lli;
+
+	if (l == NULL)
+		return;
+
+	spin_lock(&pool->lock);
+
+	while (l->link_addr) {
+		next = l->virt_link_addr;
+		dma_pool_free(pool->dmapool, l, l->phy_this);
+		DEBUGFS_POOL_COUNTER_ADD(pool, -1);
+		l = next;
+	}
+	dma_pool_free(pool->dmapool, l, l->phy_this);
+	DEBUGFS_POOL_COUNTER_ADD(pool, -1);
+
+	spin_unlock(&pool->lock);
+	*lli = NULL;
+}
+
+int
+coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t source, unsigned int size,
+			  dma_addr_t destination, u32 ctrl_chained,
+			  u32 ctrl_eom)
+{
+	int s = size;
+	dma_addr_t src = source;
+	dma_addr_t dst = destination;
+
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+
+	while (lli->link_addr) {
+		lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE;
+		lli->src_addr = src;
+		lli->dst_addr = dst;
+
+		s -= MAX_DMA_PACKET_SIZE;
+		lli = coh901318_lli_next(lli);
+
+		src += MAX_DMA_PACKET_SIZE;
+		dst += MAX_DMA_PACKET_SIZE;
+	}
+
+	lli->control = ctrl_eom | s;
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+
+	/* One irq per single transfer */
+	return 1;
+}
+
+int
+coh901318_lli_fill_single(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t buf, unsigned int size,
+			  dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_eom,
+			  enum dma_data_direction dir)
+{
+	int s = size;
+	dma_addr_t src;
+	dma_addr_t dst;
+
+
+	if (dir == DMA_TO_DEVICE) {
+		src = buf;
+		dst = dev_addr;
+
+	} else if (dir == DMA_FROM_DEVICE) {
+
+		src = dev_addr;
+		dst = buf;
+	} else {
+		return -EINVAL;
+	}
+
+	while (lli->link_addr) {
+		size_t block_size = MAX_DMA_PACKET_SIZE;
+		lli->control = ctrl_chained | MAX_DMA_PACKET_SIZE;
+
+		/* If we are on the next-to-final block and there will
+		 * be less than half a DMA packet left for the last
+		 * block, then we want to make this block a little
+		 * smaller to balance the sizes. This is meant to
+		 * avoid too small transfers if the buffer size is
+		 * (MAX_DMA_PACKET_SIZE*N + 1) */
+		if (s < (MAX_DMA_PACKET_SIZE + MAX_DMA_PACKET_SIZE/2))
+			block_size = MAX_DMA_PACKET_SIZE/2;
+
+		s -= block_size;
+		lli->src_addr = src;
+		lli->dst_addr = dst;
+
+		lli = coh901318_lli_next(lli);
+
+		if (dir == DMA_TO_DEVICE)
+			src += block_size;
+		else if (dir == DMA_FROM_DEVICE)
+			dst += block_size;
+	}
+
+	lli->control = ctrl_eom | s;
+	lli->src_addr = src;
+	lli->dst_addr = dst;
+
+	/* One irq per single transfer */
+	return 1;
+}
+
+int
+coh901318_lli_fill_sg(struct coh901318_pool *pool,
+		      struct coh901318_lli *lli,
+		      struct scatterlist *sgl, unsigned int nents,
+		      dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl,
+		      u32 ctrl_last,
+		      enum dma_data_direction dir, u32 ctrl_irq_mask)
+{
+	int i;
+	struct scatterlist *sg;
+	u32 ctrl_sg;
+	dma_addr_t src = 0;
+	dma_addr_t dst = 0;
+	int nbr_of_irq = 0;
+	u32 bytes_to_transfer;
+	u32 elem_size;
+
+	if (lli == NULL)
+		goto err;
+
+	spin_lock(&pool->lock);
+
+	if (dir == DMA_TO_DEVICE)
+		dst = dev_addr;
+	else if (dir == DMA_FROM_DEVICE)
+		src = dev_addr;
+	else
+		goto err;
+
+	for_each_sg(sgl, sg, nents, i) {
+		if (sg_is_chain(sg)) {
+			/* sg continues to the next sg-element don't
+			 * send ctrl_finish until the last
+			 * sg-element in the chain
+			 */
+			ctrl_sg = ctrl_chained;
+		} else if (i == nents - 1)
+			ctrl_sg = ctrl_last;
+		else
+			ctrl_sg = ctrl ? ctrl : ctrl_last;
+
+
+		if ((ctrl_sg & ctrl_irq_mask))
+			nbr_of_irq++;
+
+		if (dir == DMA_TO_DEVICE)
+			/* increment source address */
+			src = sg_dma_address(sg);
+		else
+			/* increment destination address */
+			dst =  sg_dma_address(sg);
+
+		bytes_to_transfer = sg_dma_len(sg);
+
+		while (bytes_to_transfer) {
+			u32 val;
+
+			if (bytes_to_transfer > MAX_DMA_PACKET_SIZE) {
+				elem_size = MAX_DMA_PACKET_SIZE;
+				val = ctrl_chained;
+			} else {
+				elem_size = bytes_to_transfer;
+				val = ctrl_sg;
+			}
+
+			lli->control = val | elem_size;
+			lli->src_addr = src;
+			lli->dst_addr = dst;
+
+			if (dir == DMA_FROM_DEVICE)
+				dst += elem_size;
+			else
+				src += elem_size;
+
+			BUG_ON(lli->link_addr & 3);
+
+			bytes_to_transfer -= elem_size;
+			lli = coh901318_lli_next(lli);
+		}
+
+	}
+	spin_unlock(&pool->lock);
+
+	/* There can be many IRQs per sg transfer */
+	return nbr_of_irq;
+ err:
+	spin_unlock(&pool->lock);
+	return -EINVAL;
+}
diff --git a/drivers/dma/coh901318_lli.h b/drivers/dma/coh901318_lli.h
new file mode 100644
index 0000000..7bf713b
--- /dev/null
+++ b/drivers/dma/coh901318_lli.h
@@ -0,0 +1,124 @@
+/*
+ * driver/dma/coh901318_lli.h
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson
+ * License terms: GNU General Public License (GPL) version 2
+ * Support functions for handling lli for coh901318
+ * Author: Per Friden <per.friden@stericsson.com>
+ */
+
+#ifndef COH901318_LLI_H
+#define COH901318_LLI_H
+
+#include <mach/coh901318.h>
+
+struct device;
+
+struct coh901318_pool {
+	spinlock_t lock;
+	struct dma_pool *dmapool;
+	struct device *dev;
+
+#ifdef CONFIG_DEBUG_FS
+	int debugfs_pool_counter;
+#endif
+};
+
+struct device;
+/**
+ * coh901318_pool_create() - Creates an dma pool for lli:s
+ * @pool: pool handle
+ * @dev: dma device
+ * @lli_nbr: number of lli:s in the pool
+ * @algin: adress alignemtn of lli:s
+ * returns 0 on success otherwise none zero
+ */
+int coh901318_pool_create(struct coh901318_pool *pool,
+			  struct device *dev,
+			  size_t lli_nbr, size_t align);
+
+/**
+ * coh901318_pool_destroy() - Destroys the dma pool
+ * @pool: pool handle
+ * returns 0 on success otherwise none zero
+ */
+int coh901318_pool_destroy(struct coh901318_pool *pool);
+
+/**
+ * coh901318_lli_alloc() - Allocates a linked list
+ *
+ * @pool: pool handle
+ * @len: length to list
+ * return: none NULL if success otherwise NULL
+ */
+struct coh901318_lli *
+coh901318_lli_alloc(struct coh901318_pool *pool,
+		    unsigned int len);
+
+/**
+ * coh901318_lli_free() - Returns the linked list items to the pool
+ * @pool: pool handle
+ * @lli: reference to lli pointer to be freed
+ */
+void coh901318_lli_free(struct coh901318_pool *pool,
+			struct coh901318_lli **lli);
+
+/**
+ * coh901318_lli_fill_memcpy() - Prepares the lli:s for dma memcpy
+ * @pool: pool handle
+ * @lli: allocated lli
+ * @src: src address
+ * @size: transfer size
+ * @dst: destination address
+ * @ctrl_chained: ctrl for chained lli
+ * @ctrl_last: ctrl for the last lli
+ * returns number of CPU interrupts for the lli, negative on error.
+ */
+int
+coh901318_lli_fill_memcpy(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t src, unsigned int size,
+			  dma_addr_t dst, u32 ctrl_chained, u32 ctrl_last);
+
+/**
+ * coh901318_lli_fill_single() - Prepares the lli:s for dma single transfer
+ * @pool: pool handle
+ * @lli: allocated lli
+ * @buf: transfer buffer
+ * @size: transfer size
+ * @dev_addr: address of periphal
+ * @ctrl_chained: ctrl for chained lli
+ * @ctrl_last: ctrl for the last lli
+ * @dir: direction of transfer (to or from device)
+ * returns number of CPU interrupts for the lli, negative on error.
+ */
+int
+coh901318_lli_fill_single(struct coh901318_pool *pool,
+			  struct coh901318_lli *lli,
+			  dma_addr_t buf, unsigned int size,
+			  dma_addr_t dev_addr, u32 ctrl_chained, u32 ctrl_last,
+			  enum dma_data_direction dir);
+
+/**
+ * coh901318_lli_fill_single() - Prepares the lli:s for dma scatter list transfer
+ * @pool: pool handle
+ * @lli: allocated lli
+ * @sg: scatter gather list
+ * @nents: number of entries in sg
+ * @dev_addr: address of periphal
+ * @ctrl_chained: ctrl for chained lli
+ * @ctrl: ctrl of middle lli
+ * @ctrl_last: ctrl for the last lli
+ * @dir: direction of transfer (to or from device)
+ * @ctrl_irq_mask: ctrl mask for CPU interrupt
+ * returns number of CPU interrupts for the lli, negative on error.
+ */
+int
+coh901318_lli_fill_sg(struct coh901318_pool *pool,
+		      struct coh901318_lli *lli,
+		      struct scatterlist *sg, unsigned int nents,
+		      dma_addr_t dev_addr, u32 ctrl_chained,
+		      u32 ctrl, u32 ctrl_last,
+		      enum dma_data_direction dir, u32 ctrl_irq_mask);
+
+#endif /* COH901318_LLI_H */
-- 
1.6.3.3


^ permalink raw reply related

* [Xenomai-core] [pull request] heap reference and trivial build fixes
From: Jan Kiszka @ 2009-11-09 20:36 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: xenomai-core

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

The following changes since commit 6d7d6bc436ef3d1fb51fa8de06d4ecf004e3b6a5:
  Gilles Chanteperdrix (1):
        nucleus: defer selector block deletion to an APC.

are available in the git repository at:

  git://git.xenomai.org/xenomai-jki.git for-upstream

Jan Kiszka (2):
      nucleus: Track heap mapping on to mm-clone
      nucleus: Fix trivial build warning

 ksrc/nucleus/heap.c   |   12 +++++++++++-
 ksrc/nucleus/module.c |    2 +-
 2 files changed, 12 insertions(+), 2 deletions(-)

---

[PATCH] nucleus: Track heap mapping on to mm-clone

When the mm is cloned (due to fork), the heap mapping counter need to be
updated as well. Register an open callback with the vm-ops for this
purpose.

Signed-off-by: Jan Kiszka <jan.kiszka@domain.hid>
---
 ksrc/nucleus/heap.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/ksrc/nucleus/heap.c b/ksrc/nucleus/heap.c
index b5fb1cd..27a4ad7 100644
--- a/ksrc/nucleus/heap.c
+++ b/ksrc/nucleus/heap.c
@@ -1017,6 +1017,15 @@ static void __unreserve_and_free_heap(void *ptr, size_t size, int kmflags)
 	}
 }
 
+static void xnheap_vmopen(struct vm_area_struct *vma)
+{
+	xnheap_t *heap = vma->vm_private_data;
+
+	spin_lock(&kheapq_lock);
+	heap->archdep.numaps++;
+	spin_unlock(&kheapq_lock);
+}
+
 static void xnheap_vmclose(struct vm_area_struct *vma)
 {
 	xnheap_t *heap = vma->vm_private_data;
@@ -1037,7 +1046,8 @@ static void xnheap_vmclose(struct vm_area_struct *vma)
 }
 
 static struct vm_operations_struct xnheap_vmops = {
-      .close = &xnheap_vmclose
+	.open = &xnheap_vmopen,
+	.close = &xnheap_vmclose
 };
 
 static int xnheap_open(struct inode *inode, struct file *file)
-- 
1.6.0.2


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 257 bytes --]

^ permalink raw reply related


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.