cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ipu_idmac.c (46211B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2008
      4 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
      5 *
      6 * Copyright (C) 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
      7 */
      8
      9#include <linux/dma-mapping.h>
     10#include <linux/init.h>
     11#include <linux/platform_device.h>
     12#include <linux/err.h>
     13#include <linux/spinlock.h>
     14#include <linux/delay.h>
     15#include <linux/list.h>
     16#include <linux/clk.h>
     17#include <linux/vmalloc.h>
     18#include <linux/string.h>
     19#include <linux/interrupt.h>
     20#include <linux/io.h>
     21#include <linux/module.h>
     22#include <linux/dma/ipu-dma.h>
     23
     24#include "../dmaengine.h"
     25#include "ipu_intern.h"
     26
     27#define FS_VF_IN_VALID	0x00000002
     28#define FS_ENC_IN_VALID	0x00000001
     29
     30static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
     31			       bool wait_for_stop);
     32
     33/*
     34 * There can be only one, we could allocate it dynamically, but then we'd have
     35 * to add an extra parameter to some functions, and use something as ugly as
     36 *	struct ipu *ipu = to_ipu(to_idmac(ichan->dma_chan.device));
     37 * in the ISR
     38 */
     39static struct ipu ipu_data;
     40
     41#define to_ipu(id) container_of(id, struct ipu, idmac)
     42
     43static u32 __idmac_read_icreg(struct ipu *ipu, unsigned long reg)
     44{
     45	return __raw_readl(ipu->reg_ic + reg);
     46}
     47
     48#define idmac_read_icreg(ipu, reg) __idmac_read_icreg(ipu, reg - IC_CONF)
     49
     50static void __idmac_write_icreg(struct ipu *ipu, u32 value, unsigned long reg)
     51{
     52	__raw_writel(value, ipu->reg_ic + reg);
     53}
     54
     55#define idmac_write_icreg(ipu, v, reg) __idmac_write_icreg(ipu, v, reg - IC_CONF)
     56
     57static u32 idmac_read_ipureg(struct ipu *ipu, unsigned long reg)
     58{
     59	return __raw_readl(ipu->reg_ipu + reg);
     60}
     61
     62static void idmac_write_ipureg(struct ipu *ipu, u32 value, unsigned long reg)
     63{
     64	__raw_writel(value, ipu->reg_ipu + reg);
     65}
     66
     67/*****************************************************************************
     68 * IPU / IC common functions
     69 */
     70static void dump_idmac_reg(struct ipu *ipu)
     71{
     72	dev_dbg(ipu->dev, "IDMAC_CONF 0x%x, IC_CONF 0x%x, IDMAC_CHA_EN 0x%x, "
     73		"IDMAC_CHA_PRI 0x%x, IDMAC_CHA_BUSY 0x%x\n",
     74		idmac_read_icreg(ipu, IDMAC_CONF),
     75		idmac_read_icreg(ipu, IC_CONF),
     76		idmac_read_icreg(ipu, IDMAC_CHA_EN),
     77		idmac_read_icreg(ipu, IDMAC_CHA_PRI),
     78		idmac_read_icreg(ipu, IDMAC_CHA_BUSY));
     79	dev_dbg(ipu->dev, "BUF0_RDY 0x%x, BUF1_RDY 0x%x, CUR_BUF 0x%x, "
     80		"DB_MODE 0x%x, TASKS_STAT 0x%x\n",
     81		idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
     82		idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
     83		idmac_read_ipureg(ipu, IPU_CHA_CUR_BUF),
     84		idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL),
     85		idmac_read_ipureg(ipu, IPU_TASKS_STAT));
     86}
     87
     88static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
     89{
     90	switch (fmt) {
     91	case IPU_PIX_FMT_GENERIC:	/* generic data */
     92	case IPU_PIX_FMT_RGB332:
     93	case IPU_PIX_FMT_YUV420P:
     94	case IPU_PIX_FMT_YUV422P:
     95	default:
     96		return 1;
     97	case IPU_PIX_FMT_RGB565:
     98	case IPU_PIX_FMT_YUYV:
     99	case IPU_PIX_FMT_UYVY:
    100		return 2;
    101	case IPU_PIX_FMT_BGR24:
    102	case IPU_PIX_FMT_RGB24:
    103		return 3;
    104	case IPU_PIX_FMT_GENERIC_32:	/* generic data */
    105	case IPU_PIX_FMT_BGR32:
    106	case IPU_PIX_FMT_RGB32:
    107	case IPU_PIX_FMT_ABGR32:
    108		return 4;
    109	}
    110}
    111
    112/* Enable direct write to memory by the Camera Sensor Interface */
    113static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
    114{
    115	uint32_t ic_conf, mask;
    116
    117	switch (channel) {
    118	case IDMAC_IC_0:
    119		mask = IC_CONF_PRPENC_EN;
    120		break;
    121	case IDMAC_IC_7:
    122		mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
    123		break;
    124	default:
    125		return;
    126	}
    127	ic_conf = idmac_read_icreg(ipu, IC_CONF) | mask;
    128	idmac_write_icreg(ipu, ic_conf, IC_CONF);
    129}
    130
    131/* Called under spin_lock_irqsave(&ipu_data.lock) */
    132static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
    133{
    134	uint32_t ic_conf, mask;
    135
    136	switch (channel) {
    137	case IDMAC_IC_0:
    138		mask = IC_CONF_PRPENC_EN;
    139		break;
    140	case IDMAC_IC_7:
    141		mask = IC_CONF_RWS_EN | IC_CONF_PRPENC_EN;
    142		break;
    143	default:
    144		return;
    145	}
    146	ic_conf = idmac_read_icreg(ipu, IC_CONF) & ~mask;
    147	idmac_write_icreg(ipu, ic_conf, IC_CONF);
    148}
    149
    150static uint32_t ipu_channel_status(struct ipu *ipu, enum ipu_channel channel)
    151{
    152	uint32_t stat = TASK_STAT_IDLE;
    153	uint32_t task_stat_reg = idmac_read_ipureg(ipu, IPU_TASKS_STAT);
    154
    155	switch (channel) {
    156	case IDMAC_IC_7:
    157		stat = (task_stat_reg & TSTAT_CSI2MEM_MASK) >>
    158			TSTAT_CSI2MEM_OFFSET;
    159		break;
    160	case IDMAC_IC_0:
    161	case IDMAC_SDC_0:
    162	case IDMAC_SDC_1:
    163	default:
    164		break;
    165	}
    166	return stat;
    167}
    168
    169struct chan_param_mem_planar {
    170	/* Word 0 */
    171	u32	xv:10;
    172	u32	yv:10;
    173	u32	xb:12;
    174
    175	u32	yb:12;
    176	u32	res1:2;
    177	u32	nsb:1;
    178	u32	lnpb:6;
    179	u32	ubo_l:11;
    180
    181	u32	ubo_h:15;
    182	u32	vbo_l:17;
    183
    184	u32	vbo_h:9;
    185	u32	res2:3;
    186	u32	fw:12;
    187	u32	fh_l:8;
    188
    189	u32	fh_h:4;
    190	u32	res3:28;
    191
    192	/* Word 1 */
    193	u32	eba0;
    194
    195	u32	eba1;
    196
    197	u32	bpp:3;
    198	u32	sl:14;
    199	u32	pfs:3;
    200	u32	bam:3;
    201	u32	res4:2;
    202	u32	npb:6;
    203	u32	res5:1;
    204
    205	u32	sat:2;
    206	u32	res6:30;
    207} __attribute__ ((packed));
    208
    209struct chan_param_mem_interleaved {
    210	/* Word 0 */
    211	u32	xv:10;
    212	u32	yv:10;
    213	u32	xb:12;
    214
    215	u32	yb:12;
    216	u32	sce:1;
    217	u32	res1:1;
    218	u32	nsb:1;
    219	u32	lnpb:6;
    220	u32	sx:10;
    221	u32	sy_l:1;
    222
    223	u32	sy_h:9;
    224	u32	ns:10;
    225	u32	sm:10;
    226	u32	sdx_l:3;
    227
    228	u32	sdx_h:2;
    229	u32	sdy:5;
    230	u32	sdrx:1;
    231	u32	sdry:1;
    232	u32	sdr1:1;
    233	u32	res2:2;
    234	u32	fw:12;
    235	u32	fh_l:8;
    236
    237	u32	fh_h:4;
    238	u32	res3:28;
    239
    240	/* Word 1 */
    241	u32	eba0;
    242
    243	u32	eba1;
    244
    245	u32	bpp:3;
    246	u32	sl:14;
    247	u32	pfs:3;
    248	u32	bam:3;
    249	u32	res4:2;
    250	u32	npb:6;
    251	u32	res5:1;
    252
    253	u32	sat:2;
    254	u32	scc:1;
    255	u32	ofs0:5;
    256	u32	ofs1:5;
    257	u32	ofs2:5;
    258	u32	ofs3:5;
    259	u32	wid0:3;
    260	u32	wid1:3;
    261	u32	wid2:3;
    262
    263	u32	wid3:3;
    264	u32	dec_sel:1;
    265	u32	res6:28;
    266} __attribute__ ((packed));
    267
    268union chan_param_mem {
    269	struct chan_param_mem_planar		pp;
    270	struct chan_param_mem_interleaved	ip;
    271};
    272
    273static void ipu_ch_param_set_plane_offset(union chan_param_mem *params,
    274					  u32 u_offset, u32 v_offset)
    275{
    276	params->pp.ubo_l = u_offset & 0x7ff;
    277	params->pp.ubo_h = u_offset >> 11;
    278	params->pp.vbo_l = v_offset & 0x1ffff;
    279	params->pp.vbo_h = v_offset >> 17;
    280}
    281
    282static void ipu_ch_param_set_size(union chan_param_mem *params,
    283				  uint32_t pixel_fmt, uint16_t width,
    284				  uint16_t height, uint16_t stride)
    285{
    286	u32 u_offset;
    287	u32 v_offset;
    288
    289	params->pp.fw		= width - 1;
    290	params->pp.fh_l		= height - 1;
    291	params->pp.fh_h		= (height - 1) >> 8;
    292	params->pp.sl		= stride - 1;
    293
    294	switch (pixel_fmt) {
    295	case IPU_PIX_FMT_GENERIC:
    296		/*Represents 8-bit Generic data */
    297		params->pp.bpp	= 3;
    298		params->pp.pfs	= 7;
    299		params->pp.npb	= 31;
    300		params->pp.sat	= 2;		/* SAT = use 32-bit access */
    301		break;
    302	case IPU_PIX_FMT_GENERIC_32:
    303		/*Represents 32-bit Generic data */
    304		params->pp.bpp	= 0;
    305		params->pp.pfs	= 7;
    306		params->pp.npb	= 7;
    307		params->pp.sat	= 2;		/* SAT = use 32-bit access */
    308		break;
    309	case IPU_PIX_FMT_RGB565:
    310		params->ip.bpp	= 2;
    311		params->ip.pfs	= 4;
    312		params->ip.npb	= 15;
    313		params->ip.sat	= 2;		/* SAT = 32-bit access */
    314		params->ip.ofs0	= 0;		/* Red bit offset */
    315		params->ip.ofs1	= 5;		/* Green bit offset */
    316		params->ip.ofs2	= 11;		/* Blue bit offset */
    317		params->ip.ofs3	= 16;		/* Alpha bit offset */
    318		params->ip.wid0	= 4;		/* Red bit width - 1 */
    319		params->ip.wid1	= 5;		/* Green bit width - 1 */
    320		params->ip.wid2	= 4;		/* Blue bit width - 1 */
    321		break;
    322	case IPU_PIX_FMT_BGR24:
    323		params->ip.bpp	= 1;		/* 24 BPP & RGB PFS */
    324		params->ip.pfs	= 4;
    325		params->ip.npb	= 7;
    326		params->ip.sat	= 2;		/* SAT = 32-bit access */
    327		params->ip.ofs0	= 0;		/* Red bit offset */
    328		params->ip.ofs1	= 8;		/* Green bit offset */
    329		params->ip.ofs2	= 16;		/* Blue bit offset */
    330		params->ip.ofs3	= 24;		/* Alpha bit offset */
    331		params->ip.wid0	= 7;		/* Red bit width - 1 */
    332		params->ip.wid1	= 7;		/* Green bit width - 1 */
    333		params->ip.wid2	= 7;		/* Blue bit width - 1 */
    334		break;
    335	case IPU_PIX_FMT_RGB24:
    336		params->ip.bpp	= 1;		/* 24 BPP & RGB PFS */
    337		params->ip.pfs	= 4;
    338		params->ip.npb	= 7;
    339		params->ip.sat	= 2;		/* SAT = 32-bit access */
    340		params->ip.ofs0	= 16;		/* Red bit offset */
    341		params->ip.ofs1	= 8;		/* Green bit offset */
    342		params->ip.ofs2	= 0;		/* Blue bit offset */
    343		params->ip.ofs3	= 24;		/* Alpha bit offset */
    344		params->ip.wid0	= 7;		/* Red bit width - 1 */
    345		params->ip.wid1	= 7;		/* Green bit width - 1 */
    346		params->ip.wid2	= 7;		/* Blue bit width - 1 */
    347		break;
    348	case IPU_PIX_FMT_BGRA32:
    349	case IPU_PIX_FMT_BGR32:
    350	case IPU_PIX_FMT_ABGR32:
    351		params->ip.bpp	= 0;
    352		params->ip.pfs	= 4;
    353		params->ip.npb	= 7;
    354		params->ip.sat	= 2;		/* SAT = 32-bit access */
    355		params->ip.ofs0	= 8;		/* Red bit offset */
    356		params->ip.ofs1	= 16;		/* Green bit offset */
    357		params->ip.ofs2	= 24;		/* Blue bit offset */
    358		params->ip.ofs3	= 0;		/* Alpha bit offset */
    359		params->ip.wid0	= 7;		/* Red bit width - 1 */
    360		params->ip.wid1	= 7;		/* Green bit width - 1 */
    361		params->ip.wid2	= 7;		/* Blue bit width - 1 */
    362		params->ip.wid3	= 7;		/* Alpha bit width - 1 */
    363		break;
    364	case IPU_PIX_FMT_RGBA32:
    365	case IPU_PIX_FMT_RGB32:
    366		params->ip.bpp	= 0;
    367		params->ip.pfs	= 4;
    368		params->ip.npb	= 7;
    369		params->ip.sat	= 2;		/* SAT = 32-bit access */
    370		params->ip.ofs0	= 24;		/* Red bit offset */
    371		params->ip.ofs1	= 16;		/* Green bit offset */
    372		params->ip.ofs2	= 8;		/* Blue bit offset */
    373		params->ip.ofs3	= 0;		/* Alpha bit offset */
    374		params->ip.wid0	= 7;		/* Red bit width - 1 */
    375		params->ip.wid1	= 7;		/* Green bit width - 1 */
    376		params->ip.wid2	= 7;		/* Blue bit width - 1 */
    377		params->ip.wid3	= 7;		/* Alpha bit width - 1 */
    378		break;
    379	case IPU_PIX_FMT_UYVY:
    380		params->ip.bpp	= 2;
    381		params->ip.pfs	= 6;
    382		params->ip.npb	= 7;
    383		params->ip.sat	= 2;		/* SAT = 32-bit access */
    384		break;
    385	case IPU_PIX_FMT_YUV420P2:
    386	case IPU_PIX_FMT_YUV420P:
    387		params->ip.bpp	= 3;
    388		params->ip.pfs	= 3;
    389		params->ip.npb	= 7;
    390		params->ip.sat	= 2;		/* SAT = 32-bit access */
    391		u_offset = stride * height;
    392		v_offset = u_offset + u_offset / 4;
    393		ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
    394		break;
    395	case IPU_PIX_FMT_YVU422P:
    396		params->ip.bpp	= 3;
    397		params->ip.pfs	= 2;
    398		params->ip.npb	= 7;
    399		params->ip.sat	= 2;		/* SAT = 32-bit access */
    400		v_offset = stride * height;
    401		u_offset = v_offset + v_offset / 2;
    402		ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
    403		break;
    404	case IPU_PIX_FMT_YUV422P:
    405		params->ip.bpp	= 3;
    406		params->ip.pfs	= 2;
    407		params->ip.npb	= 7;
    408		params->ip.sat	= 2;		/* SAT = 32-bit access */
    409		u_offset = stride * height;
    410		v_offset = u_offset + u_offset / 2;
    411		ipu_ch_param_set_plane_offset(params, u_offset, v_offset);
    412		break;
    413	default:
    414		dev_err(ipu_data.dev,
    415			"mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
    416		break;
    417	}
    418
    419	params->pp.nsb = 1;
    420}
    421
    422static void ipu_ch_param_set_buffer(union chan_param_mem *params,
    423				    dma_addr_t buf0, dma_addr_t buf1)
    424{
    425	params->pp.eba0 = buf0;
    426	params->pp.eba1 = buf1;
    427}
    428
    429static void ipu_ch_param_set_rotation(union chan_param_mem *params,
    430				      enum ipu_rotate_mode rotate)
    431{
    432	params->pp.bam = rotate;
    433}
    434
    435static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
    436				uint32_t num_words)
    437{
    438	for (; num_words > 0; num_words--) {
    439		dev_dbg(ipu_data.dev,
    440			"write param mem - addr = 0x%08X, data = 0x%08X\n",
    441			addr, *data);
    442		idmac_write_ipureg(&ipu_data, addr, IPU_IMA_ADDR);
    443		idmac_write_ipureg(&ipu_data, *data++, IPU_IMA_DATA);
    444		addr++;
    445		if ((addr & 0x7) == 5) {
    446			addr &= ~0x7;	/* set to word 0 */
    447			addr += 8;	/* increment to next row */
    448		}
    449	}
    450}
    451
    452static int calc_resize_coeffs(uint32_t in_size, uint32_t out_size,
    453			      uint32_t *resize_coeff,
    454			      uint32_t *downsize_coeff)
    455{
    456	uint32_t temp_size;
    457	uint32_t temp_downsize;
    458
    459	*resize_coeff	= 1 << 13;
    460	*downsize_coeff	= 1 << 13;
    461
    462	/* Cannot downsize more than 8:1 */
    463	if (out_size << 3 < in_size)
    464		return -EINVAL;
    465
    466	/* compute downsizing coefficient */
    467	temp_downsize = 0;
    468	temp_size = in_size;
    469	while (temp_size >= out_size * 2 && temp_downsize < 2) {
    470		temp_size >>= 1;
    471		temp_downsize++;
    472	}
    473	*downsize_coeff = temp_downsize;
    474
    475	/*
    476	 * compute resizing coefficient using the following formula:
    477	 * resize_coeff = M*(SI -1)/(SO - 1)
    478	 * where M = 2^13, SI - input size, SO - output size
    479	 */
    480	*resize_coeff = (8192L * (temp_size - 1)) / (out_size - 1);
    481	if (*resize_coeff >= 16384L) {
    482		dev_err(ipu_data.dev, "Warning! Overflow on resize coeff.\n");
    483		*resize_coeff = 0x3FFF;
    484	}
    485
    486	dev_dbg(ipu_data.dev, "resizing from %u -> %u pixels, "
    487		"downsize=%u, resize=%u.%lu (reg=%u)\n", in_size, out_size,
    488		*downsize_coeff, *resize_coeff >= 8192L ? 1 : 0,
    489		((*resize_coeff & 0x1FFF) * 10000L) / 8192L, *resize_coeff);
    490
    491	return 0;
    492}
    493
    494static enum ipu_color_space format_to_colorspace(enum pixel_fmt fmt)
    495{
    496	switch (fmt) {
    497	case IPU_PIX_FMT_RGB565:
    498	case IPU_PIX_FMT_BGR24:
    499	case IPU_PIX_FMT_RGB24:
    500	case IPU_PIX_FMT_BGR32:
    501	case IPU_PIX_FMT_RGB32:
    502		return IPU_COLORSPACE_RGB;
    503	default:
    504		return IPU_COLORSPACE_YCBCR;
    505	}
    506}
    507
    508static int ipu_ic_init_prpenc(struct ipu *ipu,
    509			      union ipu_channel_param *params, bool src_is_csi)
    510{
    511	uint32_t reg, ic_conf;
    512	uint32_t downsize_coeff, resize_coeff;
    513	enum ipu_color_space in_fmt, out_fmt;
    514
    515	/* Setup vertical resizing */
    516	calc_resize_coeffs(params->video.in_height,
    517			    params->video.out_height,
    518			    &resize_coeff, &downsize_coeff);
    519	reg = (downsize_coeff << 30) | (resize_coeff << 16);
    520
    521	/* Setup horizontal resizing */
    522	calc_resize_coeffs(params->video.in_width,
    523			    params->video.out_width,
    524			    &resize_coeff, &downsize_coeff);
    525	reg |= (downsize_coeff << 14) | resize_coeff;
    526
    527	/* Setup color space conversion */
    528	in_fmt = format_to_colorspace(params->video.in_pixel_fmt);
    529	out_fmt = format_to_colorspace(params->video.out_pixel_fmt);
    530
    531	/*
    532	 * Colourspace conversion unsupported yet - see _init_csc() in
    533	 * Freescale sources
    534	 */
    535	if (in_fmt != out_fmt) {
    536		dev_err(ipu->dev, "Colourspace conversion unsupported!\n");
    537		return -EOPNOTSUPP;
    538	}
    539
    540	idmac_write_icreg(ipu, reg, IC_PRP_ENC_RSC);
    541
    542	ic_conf = idmac_read_icreg(ipu, IC_CONF);
    543
    544	if (src_is_csi)
    545		ic_conf &= ~IC_CONF_RWS_EN;
    546	else
    547		ic_conf |= IC_CONF_RWS_EN;
    548
    549	idmac_write_icreg(ipu, ic_conf, IC_CONF);
    550
    551	return 0;
    552}
    553
    554static uint32_t dma_param_addr(uint32_t dma_ch)
    555{
    556	/* Channel Parameter Memory */
    557	return 0x10000 | (dma_ch << 4);
    558}
    559
    560static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
    561				     bool prio)
    562{
    563	u32 reg = idmac_read_icreg(ipu, IDMAC_CHA_PRI);
    564
    565	if (prio)
    566		reg |= 1UL << channel;
    567	else
    568		reg &= ~(1UL << channel);
    569
    570	idmac_write_icreg(ipu, reg, IDMAC_CHA_PRI);
    571
    572	dump_idmac_reg(ipu);
    573}
    574
    575static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
    576{
    577	uint32_t mask;
    578
    579	switch (channel) {
    580	case IDMAC_IC_0:
    581	case IDMAC_IC_7:
    582		mask = IPU_CONF_CSI_EN | IPU_CONF_IC_EN;
    583		break;
    584	case IDMAC_SDC_0:
    585	case IDMAC_SDC_1:
    586		mask = IPU_CONF_SDC_EN | IPU_CONF_DI_EN;
    587		break;
    588	default:
    589		mask = 0;
    590		break;
    591	}
    592
    593	return mask;
    594}
    595
    596/**
    597 * ipu_enable_channel() - enable an IPU channel.
    598 * @idmac:	IPU DMAC context.
    599 * @ichan:	IDMAC channel.
    600 * @return:	0 on success or negative error code on failure.
    601 */
    602static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
    603{
    604	struct ipu *ipu = to_ipu(idmac);
    605	enum ipu_channel channel = ichan->dma_chan.chan_id;
    606	uint32_t reg;
    607	unsigned long flags;
    608
    609	spin_lock_irqsave(&ipu->lock, flags);
    610
    611	/* Reset to buffer 0 */
    612	idmac_write_ipureg(ipu, 1UL << channel, IPU_CHA_CUR_BUF);
    613	ichan->active_buffer = 0;
    614	ichan->status = IPU_CHANNEL_ENABLED;
    615
    616	switch (channel) {
    617	case IDMAC_SDC_0:
    618	case IDMAC_SDC_1:
    619	case IDMAC_IC_7:
    620		ipu_channel_set_priority(ipu, channel, true);
    621		break;
    622	default:
    623		break;
    624	}
    625
    626	reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
    627
    628	idmac_write_icreg(ipu, reg | (1UL << channel), IDMAC_CHA_EN);
    629
    630	ipu_ic_enable_task(ipu, channel);
    631
    632	spin_unlock_irqrestore(&ipu->lock, flags);
    633	return 0;
    634}
    635
    636/**
    637 * ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
    638 * @ichan:	IDMAC channel.
    639 * @pixel_fmt:	pixel format of buffer. Pixel format is a FOURCC ASCII code.
    640 * @width:	width of buffer in pixels.
    641 * @height:	height of buffer in pixels.
    642 * @stride:	stride length of buffer in pixels.
    643 * @rot_mode:	rotation mode of buffer. A rotation setting other than
    644 *		IPU_ROTATE_VERT_FLIP should only be used for input buffers of
    645 *		rotation channels.
    646 * @phyaddr_0:	buffer 0 physical address.
    647 * @phyaddr_1:	buffer 1 physical address. Setting this to a value other than
    648 *		NULL enables double buffering mode.
    649 * @return:	0 on success or negative error code on failure.
    650 */
    651static int ipu_init_channel_buffer(struct idmac_channel *ichan,
    652				   enum pixel_fmt pixel_fmt,
    653				   uint16_t width, uint16_t height,
    654				   uint32_t stride,
    655				   enum ipu_rotate_mode rot_mode,
    656				   dma_addr_t phyaddr_0, dma_addr_t phyaddr_1)
    657{
    658	enum ipu_channel channel = ichan->dma_chan.chan_id;
    659	struct idmac *idmac = to_idmac(ichan->dma_chan.device);
    660	struct ipu *ipu = to_ipu(idmac);
    661	union chan_param_mem params = {};
    662	unsigned long flags;
    663	uint32_t reg;
    664	uint32_t stride_bytes;
    665
    666	stride_bytes = stride * bytes_per_pixel(pixel_fmt);
    667
    668	if (stride_bytes % 4) {
    669		dev_err(ipu->dev,
    670			"Stride length must be 32-bit aligned, stride = %d, bytes = %d\n",
    671			stride, stride_bytes);
    672		return -EINVAL;
    673	}
    674
    675	/* IC channel's stride must be a multiple of 8 pixels */
    676	if ((channel <= IDMAC_IC_13) && (stride % 8)) {
    677		dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
    678		return -EINVAL;
    679	}
    680
    681	/* Build parameter memory data for DMA channel */
    682	ipu_ch_param_set_size(&params, pixel_fmt, width, height, stride_bytes);
    683	ipu_ch_param_set_buffer(&params, phyaddr_0, phyaddr_1);
    684	ipu_ch_param_set_rotation(&params, rot_mode);
    685
    686	spin_lock_irqsave(&ipu->lock, flags);
    687
    688	ipu_write_param_mem(dma_param_addr(channel), (uint32_t *)&params, 10);
    689
    690	reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
    691
    692	if (phyaddr_1)
    693		reg |= 1UL << channel;
    694	else
    695		reg &= ~(1UL << channel);
    696
    697	idmac_write_ipureg(ipu, reg, IPU_CHA_DB_MODE_SEL);
    698
    699	ichan->status = IPU_CHANNEL_READY;
    700
    701	spin_unlock_irqrestore(&ipu->lock, flags);
    702
    703	return 0;
    704}
    705
    706/**
    707 * ipu_select_buffer() - mark a channel's buffer as ready.
    708 * @channel:	channel ID.
    709 * @buffer_n:	buffer number to mark ready.
    710 */
    711static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
    712{
    713	/* No locking - this is a write-one-to-set register, cleared by IPU */
    714	if (buffer_n == 0)
    715		/* Mark buffer 0 as ready. */
    716		idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF0_RDY);
    717	else
    718		/* Mark buffer 1 as ready. */
    719		idmac_write_ipureg(&ipu_data, 1UL << channel, IPU_CHA_BUF1_RDY);
    720}
    721
    722/**
    723 * ipu_update_channel_buffer() - update physical address of a channel buffer.
    724 * @ichan:	IDMAC channel.
    725 * @buffer_n:	buffer number to update.
    726 *		0 or 1 are the only valid values.
    727 * @phyaddr:	buffer physical address.
    728 */
    729/* Called under spin_lock(_irqsave)(&ichan->lock) */
    730static void ipu_update_channel_buffer(struct idmac_channel *ichan,
    731				      int buffer_n, dma_addr_t phyaddr)
    732{
    733	enum ipu_channel channel = ichan->dma_chan.chan_id;
    734	uint32_t reg;
    735	unsigned long flags;
    736
    737	spin_lock_irqsave(&ipu_data.lock, flags);
    738
    739	if (buffer_n == 0) {
    740		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
    741		if (reg & (1UL << channel)) {
    742			ipu_ic_disable_task(&ipu_data, channel);
    743			ichan->status = IPU_CHANNEL_READY;
    744		}
    745
    746		/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
    747		idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
    748				   0x0008UL, IPU_IMA_ADDR);
    749		idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
    750	} else {
    751		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
    752		if (reg & (1UL << channel)) {
    753			ipu_ic_disable_task(&ipu_data, channel);
    754			ichan->status = IPU_CHANNEL_READY;
    755		}
    756
    757		/* Check if double-buffering is already enabled */
    758		reg = idmac_read_ipureg(&ipu_data, IPU_CHA_DB_MODE_SEL);
    759
    760		if (!(reg & (1UL << channel)))
    761			idmac_write_ipureg(&ipu_data, reg | (1UL << channel),
    762					   IPU_CHA_DB_MODE_SEL);
    763
    764		/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 1) */
    765		idmac_write_ipureg(&ipu_data, dma_param_addr(channel) +
    766				   0x0009UL, IPU_IMA_ADDR);
    767		idmac_write_ipureg(&ipu_data, phyaddr, IPU_IMA_DATA);
    768	}
    769
    770	spin_unlock_irqrestore(&ipu_data.lock, flags);
    771}
    772
    773/* Called under spin_lock_irqsave(&ichan->lock) */
    774static int ipu_submit_buffer(struct idmac_channel *ichan,
    775	struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
    776{
    777	unsigned int chan_id = ichan->dma_chan.chan_id;
    778	struct device *dev = &ichan->dma_chan.dev->device;
    779
    780	if (async_tx_test_ack(&desc->txd))
    781		return -EINTR;
    782
    783	/*
    784	 * On first invocation this shouldn't be necessary, the call to
    785	 * ipu_init_channel_buffer() above will set addresses for us, so we
    786	 * could make it conditional on status >= IPU_CHANNEL_ENABLED, but
    787	 * doing it again shouldn't hurt either.
    788	 */
    789	ipu_update_channel_buffer(ichan, buf_idx, sg_dma_address(sg));
    790
    791	ipu_select_buffer(chan_id, buf_idx);
    792	dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
    793		sg, chan_id, buf_idx);
    794
    795	return 0;
    796}
    797
    798/* Called under spin_lock_irqsave(&ichan->lock) */
    799static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
    800				      struct idmac_tx_desc *desc)
    801{
    802	struct scatterlist *sg;
    803	int i, ret = 0;
    804
    805	for (i = 0, sg = desc->sg; i < 2 && sg; i++) {
    806		if (!ichan->sg[i]) {
    807			ichan->sg[i] = sg;
    808
    809			ret = ipu_submit_buffer(ichan, desc, sg, i);
    810			if (ret < 0)
    811				return ret;
    812
    813			sg = sg_next(sg);
    814		}
    815	}
    816
    817	return ret;
    818}
    819
    820static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
    821{
    822	struct idmac_tx_desc *desc = to_tx_desc(tx);
    823	struct idmac_channel *ichan = to_idmac_chan(tx->chan);
    824	struct idmac *idmac = to_idmac(tx->chan->device);
    825	struct ipu *ipu = to_ipu(idmac);
    826	struct device *dev = &ichan->dma_chan.dev->device;
    827	dma_cookie_t cookie;
    828	unsigned long flags;
    829	int ret;
    830
    831	/* Sanity check */
    832	if (!list_empty(&desc->list)) {
    833		/* The descriptor doesn't belong to client */
    834		dev_err(dev, "Descriptor %p not prepared!\n", tx);
    835		return -EBUSY;
    836	}
    837
    838	mutex_lock(&ichan->chan_mutex);
    839
    840	async_tx_clear_ack(tx);
    841
    842	if (ichan->status < IPU_CHANNEL_READY) {
    843		struct idmac_video_param *video = &ichan->params.video;
    844		/*
    845		 * Initial buffer assignment - the first two sg-entries from
    846		 * the descriptor will end up in the IDMAC buffers
    847		 */
    848		dma_addr_t dma_1 = sg_is_last(desc->sg) ? 0 :
    849			sg_dma_address(&desc->sg[1]);
    850
    851		WARN_ON(ichan->sg[0] || ichan->sg[1]);
    852
    853		cookie = ipu_init_channel_buffer(ichan,
    854						 video->out_pixel_fmt,
    855						 video->out_width,
    856						 video->out_height,
    857						 video->out_stride,
    858						 IPU_ROTATE_NONE,
    859						 sg_dma_address(&desc->sg[0]),
    860						 dma_1);
    861		if (cookie < 0)
    862			goto out;
    863	}
    864
    865	dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
    866
    867	cookie = dma_cookie_assign(tx);
    868
    869	/* ipu->lock can be taken under ichan->lock, but not v.v. */
    870	spin_lock_irqsave(&ichan->lock, flags);
    871
    872	list_add_tail(&desc->list, &ichan->queue);
    873	/* submit_buffers() atomically verifies and fills empty sg slots */
    874	ret = ipu_submit_channel_buffers(ichan, desc);
    875
    876	spin_unlock_irqrestore(&ichan->lock, flags);
    877
    878	if (ret < 0) {
    879		cookie = ret;
    880		goto dequeue;
    881	}
    882
    883	if (ichan->status < IPU_CHANNEL_ENABLED) {
    884		ret = ipu_enable_channel(idmac, ichan);
    885		if (ret < 0) {
    886			cookie = ret;
    887			goto dequeue;
    888		}
    889	}
    890
    891	dump_idmac_reg(ipu);
    892
    893dequeue:
    894	if (cookie < 0) {
    895		spin_lock_irqsave(&ichan->lock, flags);
    896		list_del_init(&desc->list);
    897		spin_unlock_irqrestore(&ichan->lock, flags);
    898		tx->cookie = cookie;
    899		ichan->dma_chan.cookie = cookie;
    900	}
    901
    902out:
    903	mutex_unlock(&ichan->chan_mutex);
    904
    905	return cookie;
    906}
    907
    908/* Called with ichan->chan_mutex held */
    909static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
    910{
    911	struct idmac_tx_desc *desc =
    912		vmalloc(array_size(n, sizeof(struct idmac_tx_desc)));
    913	struct idmac *idmac = to_idmac(ichan->dma_chan.device);
    914
    915	if (!desc)
    916		return -ENOMEM;
    917
    918	/* No interrupts, just disable the tasklet for a moment */
    919	tasklet_disable(&to_ipu(idmac)->tasklet);
    920
    921	ichan->n_tx_desc = n;
    922	ichan->desc = desc;
    923	INIT_LIST_HEAD(&ichan->queue);
    924	INIT_LIST_HEAD(&ichan->free_list);
    925
    926	while (n--) {
    927		struct dma_async_tx_descriptor *txd = &desc->txd;
    928
    929		memset(txd, 0, sizeof(*txd));
    930		dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
    931		txd->tx_submit		= idmac_tx_submit;
    932
    933		list_add(&desc->list, &ichan->free_list);
    934
    935		desc++;
    936	}
    937
    938	tasklet_enable(&to_ipu(idmac)->tasklet);
    939
    940	return 0;
    941}
    942
    943/**
    944 * ipu_init_channel() - initialize an IPU channel.
    945 * @idmac:	IPU DMAC context.
    946 * @ichan:	pointer to the channel object.
    947 * @return      0 on success or negative error code on failure.
    948 */
    949static int ipu_init_channel(struct idmac *idmac, struct idmac_channel *ichan)
    950{
    951	union ipu_channel_param *params = &ichan->params;
    952	uint32_t ipu_conf;
    953	enum ipu_channel channel = ichan->dma_chan.chan_id;
    954	unsigned long flags;
    955	uint32_t reg;
    956	struct ipu *ipu = to_ipu(idmac);
    957	int ret = 0, n_desc = 0;
    958
    959	dev_dbg(ipu->dev, "init channel = %d\n", channel);
    960
    961	if (channel != IDMAC_SDC_0 && channel != IDMAC_SDC_1 &&
    962	    channel != IDMAC_IC_7)
    963		return -EINVAL;
    964
    965	spin_lock_irqsave(&ipu->lock, flags);
    966
    967	switch (channel) {
    968	case IDMAC_IC_7:
    969		n_desc = 16;
    970		reg = idmac_read_icreg(ipu, IC_CONF);
    971		idmac_write_icreg(ipu, reg & ~IC_CONF_CSI_MEM_WR_EN, IC_CONF);
    972		break;
    973	case IDMAC_IC_0:
    974		n_desc = 16;
    975		reg = idmac_read_ipureg(ipu, IPU_FS_PROC_FLOW);
    976		idmac_write_ipureg(ipu, reg & ~FS_ENC_IN_VALID, IPU_FS_PROC_FLOW);
    977		ret = ipu_ic_init_prpenc(ipu, params, true);
    978		break;
    979	case IDMAC_SDC_0:
    980	case IDMAC_SDC_1:
    981		n_desc = 4;
    982		break;
    983	default:
    984		break;
    985	}
    986
    987	ipu->channel_init_mask |= 1L << channel;
    988
    989	/* Enable IPU sub module */
    990	ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) |
    991		ipu_channel_conf_mask(channel);
    992	idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
    993
    994	spin_unlock_irqrestore(&ipu->lock, flags);
    995
    996	if (n_desc && !ichan->desc)
    997		ret = idmac_desc_alloc(ichan, n_desc);
    998
    999	dump_idmac_reg(ipu);
   1000
   1001	return ret;
   1002}
   1003
   1004/**
   1005 * ipu_uninit_channel() - uninitialize an IPU channel.
   1006 * @idmac:	IPU DMAC context.
   1007 * @ichan:	pointer to the channel object.
   1008 */
   1009static void ipu_uninit_channel(struct idmac *idmac, struct idmac_channel *ichan)
   1010{
   1011	enum ipu_channel channel = ichan->dma_chan.chan_id;
   1012	unsigned long flags;
   1013	uint32_t reg;
   1014	unsigned long chan_mask = 1UL << channel;
   1015	uint32_t ipu_conf;
   1016	struct ipu *ipu = to_ipu(idmac);
   1017
   1018	spin_lock_irqsave(&ipu->lock, flags);
   1019
   1020	if (!(ipu->channel_init_mask & chan_mask)) {
   1021		dev_err(ipu->dev, "Channel already uninitialized %d\n",
   1022			channel);
   1023		spin_unlock_irqrestore(&ipu->lock, flags);
   1024		return;
   1025	}
   1026
   1027	/* Reset the double buffer */
   1028	reg = idmac_read_ipureg(ipu, IPU_CHA_DB_MODE_SEL);
   1029	idmac_write_ipureg(ipu, reg & ~chan_mask, IPU_CHA_DB_MODE_SEL);
   1030
   1031	ichan->sec_chan_en = false;
   1032
   1033	switch (channel) {
   1034	case IDMAC_IC_7:
   1035		reg = idmac_read_icreg(ipu, IC_CONF);
   1036		idmac_write_icreg(ipu, reg & ~(IC_CONF_RWS_EN | IC_CONF_PRPENC_EN),
   1037			     IC_CONF);
   1038		break;
   1039	case IDMAC_IC_0:
   1040		reg = idmac_read_icreg(ipu, IC_CONF);
   1041		idmac_write_icreg(ipu, reg & ~(IC_CONF_PRPENC_EN | IC_CONF_PRPENC_CSC1),
   1042				  IC_CONF);
   1043		break;
   1044	case IDMAC_SDC_0:
   1045	case IDMAC_SDC_1:
   1046	default:
   1047		break;
   1048	}
   1049
   1050	ipu->channel_init_mask &= ~(1L << channel);
   1051
   1052	ipu_conf = idmac_read_ipureg(ipu, IPU_CONF) &
   1053		~ipu_channel_conf_mask(channel);
   1054	idmac_write_ipureg(ipu, ipu_conf, IPU_CONF);
   1055
   1056	spin_unlock_irqrestore(&ipu->lock, flags);
   1057
   1058	ichan->n_tx_desc = 0;
   1059	vfree(ichan->desc);
   1060	ichan->desc = NULL;
   1061}
   1062
   1063/**
   1064 * ipu_disable_channel() - disable an IPU channel.
   1065 * @idmac:		IPU DMAC context.
   1066 * @ichan:		channel object pointer.
   1067 * @wait_for_stop:	flag to set whether to wait for channel end of frame or
   1068 *			return immediately.
   1069 * @return:		0 on success or negative error code on failure.
   1070 */
   1071static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
   1072			       bool wait_for_stop)
   1073{
   1074	enum ipu_channel channel = ichan->dma_chan.chan_id;
   1075	struct ipu *ipu = to_ipu(idmac);
   1076	uint32_t reg;
   1077	unsigned long flags;
   1078	unsigned long chan_mask = 1UL << channel;
   1079	unsigned int timeout;
   1080
   1081	if (wait_for_stop && channel != IDMAC_SDC_1 && channel != IDMAC_SDC_0) {
   1082		timeout = 40;
   1083		/* This waiting always fails. Related to spurious irq problem */
   1084		while ((idmac_read_icreg(ipu, IDMAC_CHA_BUSY) & chan_mask) ||
   1085		       (ipu_channel_status(ipu, channel) == TASK_STAT_ACTIVE)) {
   1086			timeout--;
   1087			msleep(10);
   1088
   1089			if (!timeout) {
   1090				dev_dbg(ipu->dev,
   1091					"Warning: timeout waiting for channel %u to "
   1092					"stop: buf0_rdy = 0x%08X, buf1_rdy = 0x%08X, "
   1093					"busy = 0x%08X, tstat = 0x%08X\n", channel,
   1094					idmac_read_ipureg(ipu, IPU_CHA_BUF0_RDY),
   1095					idmac_read_ipureg(ipu, IPU_CHA_BUF1_RDY),
   1096					idmac_read_icreg(ipu, IDMAC_CHA_BUSY),
   1097					idmac_read_ipureg(ipu, IPU_TASKS_STAT));
   1098				break;
   1099			}
   1100		}
   1101		dev_dbg(ipu->dev, "timeout = %d * 10ms\n", 40 - timeout);
   1102	}
   1103	/* SDC BG and FG must be disabled before DMA is disabled */
   1104	if (wait_for_stop && (channel == IDMAC_SDC_0 ||
   1105			      channel == IDMAC_SDC_1)) {
   1106		for (timeout = 5;
   1107		     timeout && !ipu_irq_status(ichan->eof_irq); timeout--)
   1108			msleep(5);
   1109	}
   1110
   1111	spin_lock_irqsave(&ipu->lock, flags);
   1112
   1113	/* Disable IC task */
   1114	ipu_ic_disable_task(ipu, channel);
   1115
   1116	/* Disable DMA channel(s) */
   1117	reg = idmac_read_icreg(ipu, IDMAC_CHA_EN);
   1118	idmac_write_icreg(ipu, reg & ~chan_mask, IDMAC_CHA_EN);
   1119
   1120	spin_unlock_irqrestore(&ipu->lock, flags);
   1121
   1122	return 0;
   1123}
   1124
   1125static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
   1126	struct idmac_tx_desc **desc, struct scatterlist *sg)
   1127{
   1128	struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
   1129
   1130	if (sgnew)
   1131		/* next sg-element in this list */
   1132		return sgnew;
   1133
   1134	if ((*desc)->list.next == &ichan->queue)
   1135		/* No more descriptors on the queue */
   1136		return NULL;
   1137
   1138	/* Fetch next descriptor */
   1139	*desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
   1140	return (*desc)->sg;
   1141}
   1142
   1143/*
   1144 * We have several possibilities here:
   1145 * current BUF		next BUF
   1146 *
   1147 * not last sg		next not last sg
   1148 * not last sg		next last sg
   1149 * last sg		first sg from next descriptor
   1150 * last sg		NULL
   1151 *
   1152 * Besides, the descriptor queue might be empty or not. We process all these
   1153 * cases carefully.
   1154 */
   1155static irqreturn_t idmac_interrupt(int irq, void *dev_id)
   1156{
   1157	struct idmac_channel *ichan = dev_id;
   1158	struct device *dev = &ichan->dma_chan.dev->device;
   1159	unsigned int chan_id = ichan->dma_chan.chan_id;
   1160	struct scatterlist **sg, *sgnext, *sgnew = NULL;
   1161	/* Next transfer descriptor */
   1162	struct idmac_tx_desc *desc, *descnew;
   1163	bool done = false;
   1164	u32 ready0, ready1, curbuf, err;
   1165	struct dmaengine_desc_callback cb;
   1166
   1167	/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
   1168
   1169	dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
   1170
   1171	spin_lock(&ipu_data.lock);
   1172
   1173	ready0	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
   1174	ready1	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
   1175	curbuf	= idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
   1176	err	= idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
   1177
   1178	if (err & (1 << chan_id)) {
   1179		idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
   1180		spin_unlock(&ipu_data.lock);
   1181		/*
   1182		 * Doing this
   1183		 * ichan->sg[0] = ichan->sg[1] = NULL;
   1184		 * you can force channel re-enable on the next tx_submit(), but
   1185		 * this is dirty - think about descriptors with multiple
   1186		 * sg elements.
   1187		 */
   1188		dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
   1189			 chan_id, ready0, ready1, curbuf);
   1190		return IRQ_HANDLED;
   1191	}
   1192	spin_unlock(&ipu_data.lock);
   1193
   1194	/* Other interrupts do not interfere with this channel */
   1195	spin_lock(&ichan->lock);
   1196	if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
   1197		     (!ichan->active_buffer && (ready0 >> chan_id) & 1)
   1198		     )) {
   1199		spin_unlock(&ichan->lock);
   1200		dev_dbg(dev,
   1201			"IRQ with active buffer still ready on channel %x, "
   1202			"active %d, ready %x, %x!\n", chan_id,
   1203			ichan->active_buffer, ready0, ready1);
   1204		return IRQ_NONE;
   1205	}
   1206
   1207	if (unlikely(list_empty(&ichan->queue))) {
   1208		ichan->sg[ichan->active_buffer] = NULL;
   1209		spin_unlock(&ichan->lock);
   1210		dev_err(dev,
   1211			"IRQ without queued buffers on channel %x, active %d, "
   1212			"ready %x, %x!\n", chan_id,
   1213			ichan->active_buffer, ready0, ready1);
   1214		return IRQ_NONE;
   1215	}
   1216
   1217	/*
   1218	 * active_buffer is a software flag, it shows which buffer we are
   1219	 * currently expecting back from the hardware, IDMAC should be
   1220	 * processing the other buffer already
   1221	 */
   1222	sg = &ichan->sg[ichan->active_buffer];
   1223	sgnext = ichan->sg[!ichan->active_buffer];
   1224
   1225	if (!*sg) {
   1226		spin_unlock(&ichan->lock);
   1227		return IRQ_HANDLED;
   1228	}
   1229
   1230	desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
   1231	descnew = desc;
   1232
   1233	dev_dbg(dev, "IDMAC irq %d, dma %#llx, next dma %#llx, current %d, curbuf %#x\n",
   1234		irq, (u64)sg_dma_address(*sg),
   1235		sgnext ? (u64)sg_dma_address(sgnext) : 0,
   1236		ichan->active_buffer, curbuf);
   1237
   1238	/* Find the descriptor of sgnext */
   1239	sgnew = idmac_sg_next(ichan, &descnew, *sg);
   1240	if (sgnext != sgnew)
   1241		dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
   1242
   1243	/*
   1244	 * if sgnext == NULL sg must be the last element in a scatterlist and
   1245	 * queue must be empty
   1246	 */
   1247	if (unlikely(!sgnext)) {
   1248		if (!WARN_ON(sg_next(*sg)))
   1249			dev_dbg(dev, "Underrun on channel %x\n", chan_id);
   1250		ichan->sg[!ichan->active_buffer] = sgnew;
   1251
   1252		if (unlikely(sgnew)) {
   1253			ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
   1254		} else {
   1255			spin_lock(&ipu_data.lock);
   1256			ipu_ic_disable_task(&ipu_data, chan_id);
   1257			spin_unlock(&ipu_data.lock);
   1258			ichan->status = IPU_CHANNEL_READY;
   1259			/* Continue to check for complete descriptor */
   1260		}
   1261	}
   1262
   1263	/* Calculate and submit the next sg element */
   1264	sgnew = idmac_sg_next(ichan, &descnew, sgnew);
   1265
   1266	if (unlikely(!sg_next(*sg)) || !sgnext) {
   1267		/*
   1268		 * Last element in scatterlist done, remove from the queue,
   1269		 * _init for debugging
   1270		 */
   1271		list_del_init(&desc->list);
   1272		done = true;
   1273	}
   1274
   1275	*sg = sgnew;
   1276
   1277	if (likely(sgnew) &&
   1278	    ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
   1279		dmaengine_desc_get_callback(&descnew->txd, &cb);
   1280
   1281		list_del_init(&descnew->list);
   1282		spin_unlock(&ichan->lock);
   1283
   1284		dmaengine_desc_callback_invoke(&cb, NULL);
   1285		spin_lock(&ichan->lock);
   1286	}
   1287
   1288	/* Flip the active buffer - even if update above failed */
   1289	ichan->active_buffer = !ichan->active_buffer;
   1290	if (done)
   1291		dma_cookie_complete(&desc->txd);
   1292
   1293	dmaengine_desc_get_callback(&desc->txd, &cb);
   1294
   1295	spin_unlock(&ichan->lock);
   1296
   1297	if (done && (desc->txd.flags & DMA_PREP_INTERRUPT))
   1298		dmaengine_desc_callback_invoke(&cb, NULL);
   1299
   1300	return IRQ_HANDLED;
   1301}
   1302
   1303static void ipu_gc_tasklet(struct tasklet_struct *t)
   1304{
   1305	struct ipu *ipu = from_tasklet(ipu, t, tasklet);
   1306	int i;
   1307
   1308	for (i = 0; i < IPU_CHANNELS_NUM; i++) {
   1309		struct idmac_channel *ichan = ipu->channel + i;
   1310		struct idmac_tx_desc *desc;
   1311		unsigned long flags;
   1312		struct scatterlist *sg;
   1313		int j, k;
   1314
   1315		for (j = 0; j < ichan->n_tx_desc; j++) {
   1316			desc = ichan->desc + j;
   1317			spin_lock_irqsave(&ichan->lock, flags);
   1318			if (async_tx_test_ack(&desc->txd)) {
   1319				list_move(&desc->list, &ichan->free_list);
   1320				for_each_sg(desc->sg, sg, desc->sg_len, k) {
   1321					if (ichan->sg[0] == sg)
   1322						ichan->sg[0] = NULL;
   1323					else if (ichan->sg[1] == sg)
   1324						ichan->sg[1] = NULL;
   1325				}
   1326				async_tx_clear_ack(&desc->txd);
   1327			}
   1328			spin_unlock_irqrestore(&ichan->lock, flags);
   1329		}
   1330	}
   1331}
   1332
   1333/* Allocate and initialise a transfer descriptor. */
   1334static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
   1335		struct scatterlist *sgl, unsigned int sg_len,
   1336		enum dma_transfer_direction direction, unsigned long tx_flags,
   1337		void *context)
   1338{
   1339	struct idmac_channel *ichan = to_idmac_chan(chan);
   1340	struct idmac_tx_desc *desc = NULL;
   1341	struct dma_async_tx_descriptor *txd = NULL;
   1342	unsigned long flags;
   1343
   1344	/* We only can handle these three channels so far */
   1345	if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
   1346	    chan->chan_id != IDMAC_IC_7)
   1347		return NULL;
   1348
   1349	if (!is_slave_direction(direction)) {
   1350		dev_err(chan->device->dev, "Invalid DMA direction %d!\n", direction);
   1351		return NULL;
   1352	}
   1353
   1354	mutex_lock(&ichan->chan_mutex);
   1355
   1356	spin_lock_irqsave(&ichan->lock, flags);
   1357	if (!list_empty(&ichan->free_list)) {
   1358		desc = list_entry(ichan->free_list.next,
   1359				  struct idmac_tx_desc, list);
   1360
   1361		list_del_init(&desc->list);
   1362
   1363		desc->sg_len	= sg_len;
   1364		desc->sg	= sgl;
   1365		txd		= &desc->txd;
   1366		txd->flags	= tx_flags;
   1367	}
   1368	spin_unlock_irqrestore(&ichan->lock, flags);
   1369
   1370	mutex_unlock(&ichan->chan_mutex);
   1371
   1372	tasklet_schedule(&to_ipu(to_idmac(chan->device))->tasklet);
   1373
   1374	return txd;
   1375}
   1376
   1377/* Re-select the current buffer and re-activate the channel */
   1378static void idmac_issue_pending(struct dma_chan *chan)
   1379{
   1380	struct idmac_channel *ichan = to_idmac_chan(chan);
   1381	struct idmac *idmac = to_idmac(chan->device);
   1382	struct ipu *ipu = to_ipu(idmac);
   1383	unsigned long flags;
   1384
   1385	/* This is not always needed, but doesn't hurt either */
   1386	spin_lock_irqsave(&ipu->lock, flags);
   1387	ipu_select_buffer(chan->chan_id, ichan->active_buffer);
   1388	spin_unlock_irqrestore(&ipu->lock, flags);
   1389
   1390	/*
   1391	 * Might need to perform some parts of initialisation from
   1392	 * ipu_enable_channel(), but not all, we do not want to reset to buffer
   1393	 * 0, don't need to set priority again either, but re-enabling the task
   1394	 * and the channel might be a good idea.
   1395	 */
   1396}
   1397
   1398static int idmac_pause(struct dma_chan *chan)
   1399{
   1400	struct idmac_channel *ichan = to_idmac_chan(chan);
   1401	struct idmac *idmac = to_idmac(chan->device);
   1402	struct ipu *ipu = to_ipu(idmac);
   1403	struct list_head *list, *tmp;
   1404	unsigned long flags;
   1405
   1406	mutex_lock(&ichan->chan_mutex);
   1407
   1408	spin_lock_irqsave(&ipu->lock, flags);
   1409	ipu_ic_disable_task(ipu, chan->chan_id);
   1410
   1411	/* Return all descriptors into "prepared" state */
   1412	list_for_each_safe(list, tmp, &ichan->queue)
   1413		list_del_init(list);
   1414
   1415	ichan->sg[0] = NULL;
   1416	ichan->sg[1] = NULL;
   1417
   1418	spin_unlock_irqrestore(&ipu->lock, flags);
   1419
   1420	ichan->status = IPU_CHANNEL_INITIALIZED;
   1421
   1422	mutex_unlock(&ichan->chan_mutex);
   1423
   1424	return 0;
   1425}
   1426
   1427static int __idmac_terminate_all(struct dma_chan *chan)
   1428{
   1429	struct idmac_channel *ichan = to_idmac_chan(chan);
   1430	struct idmac *idmac = to_idmac(chan->device);
   1431	struct ipu *ipu = to_ipu(idmac);
   1432	unsigned long flags;
   1433	int i;
   1434
   1435	ipu_disable_channel(idmac, ichan,
   1436			    ichan->status >= IPU_CHANNEL_ENABLED);
   1437
   1438	tasklet_disable(&ipu->tasklet);
   1439
   1440	/* ichan->queue is modified in ISR, have to spinlock */
   1441	spin_lock_irqsave(&ichan->lock, flags);
   1442	list_splice_init(&ichan->queue, &ichan->free_list);
   1443
   1444	if (ichan->desc)
   1445		for (i = 0; i < ichan->n_tx_desc; i++) {
   1446			struct idmac_tx_desc *desc = ichan->desc + i;
   1447			if (list_empty(&desc->list))
   1448				/* Descriptor was prepared, but not submitted */
   1449				list_add(&desc->list, &ichan->free_list);
   1450
   1451			async_tx_clear_ack(&desc->txd);
   1452		}
   1453
   1454	ichan->sg[0] = NULL;
   1455	ichan->sg[1] = NULL;
   1456	spin_unlock_irqrestore(&ichan->lock, flags);
   1457
   1458	tasklet_enable(&ipu->tasklet);
   1459
   1460	ichan->status = IPU_CHANNEL_INITIALIZED;
   1461
   1462	return 0;
   1463}
   1464
   1465static int idmac_terminate_all(struct dma_chan *chan)
   1466{
   1467	struct idmac_channel *ichan = to_idmac_chan(chan);
   1468	int ret;
   1469
   1470	mutex_lock(&ichan->chan_mutex);
   1471
   1472	ret = __idmac_terminate_all(chan);
   1473
   1474	mutex_unlock(&ichan->chan_mutex);
   1475
   1476	return ret;
   1477}
   1478
   1479#ifdef DEBUG
   1480static irqreturn_t ic_sof_irq(int irq, void *dev_id)
   1481{
   1482	struct idmac_channel *ichan = dev_id;
   1483	printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
   1484	       irq, ichan->dma_chan.chan_id);
   1485	disable_irq_nosync(irq);
   1486	return IRQ_HANDLED;
   1487}
   1488
   1489static irqreturn_t ic_eof_irq(int irq, void *dev_id)
   1490{
   1491	struct idmac_channel *ichan = dev_id;
   1492	printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
   1493	       irq, ichan->dma_chan.chan_id);
   1494	disable_irq_nosync(irq);
   1495	return IRQ_HANDLED;
   1496}
   1497
   1498static int ic_sof = -EINVAL, ic_eof = -EINVAL;
   1499#endif
   1500
   1501static int idmac_alloc_chan_resources(struct dma_chan *chan)
   1502{
   1503	struct idmac_channel *ichan = to_idmac_chan(chan);
   1504	struct idmac *idmac = to_idmac(chan->device);
   1505	int ret;
   1506
   1507	/* dmaengine.c now guarantees to only offer free channels */
   1508	BUG_ON(chan->client_count > 1);
   1509	WARN_ON(ichan->status != IPU_CHANNEL_FREE);
   1510
   1511	dma_cookie_init(chan);
   1512
   1513	ret = ipu_irq_map(chan->chan_id);
   1514	if (ret < 0)
   1515		goto eimap;
   1516
   1517	ichan->eof_irq = ret;
   1518
   1519	/*
   1520	 * Important to first disable the channel, because maybe someone
   1521	 * used it before us, e.g., the bootloader
   1522	 */
   1523	ipu_disable_channel(idmac, ichan, true);
   1524
   1525	ret = ipu_init_channel(idmac, ichan);
   1526	if (ret < 0)
   1527		goto eichan;
   1528
   1529	ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
   1530			  ichan->eof_name, ichan);
   1531	if (ret < 0)
   1532		goto erirq;
   1533
   1534#ifdef DEBUG
   1535	if (chan->chan_id == IDMAC_IC_7) {
   1536		ic_sof = ipu_irq_map(69);
   1537		if (ic_sof > 0) {
   1538			ret = request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
   1539			if (ret)
   1540				dev_err(&chan->dev->device, "request irq failed for IC SOF");
   1541		}
   1542		ic_eof = ipu_irq_map(70);
   1543		if (ic_eof > 0) {
   1544			ret = request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
   1545			if (ret)
   1546				dev_err(&chan->dev->device, "request irq failed for IC EOF");
   1547		}
   1548	}
   1549#endif
   1550
   1551	ichan->status = IPU_CHANNEL_INITIALIZED;
   1552
   1553	dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
   1554		chan->chan_id, ichan->eof_irq);
   1555
   1556	return ret;
   1557
   1558erirq:
   1559	ipu_uninit_channel(idmac, ichan);
   1560eichan:
   1561	ipu_irq_unmap(chan->chan_id);
   1562eimap:
   1563	return ret;
   1564}
   1565
   1566static void idmac_free_chan_resources(struct dma_chan *chan)
   1567{
   1568	struct idmac_channel *ichan = to_idmac_chan(chan);
   1569	struct idmac *idmac = to_idmac(chan->device);
   1570
   1571	mutex_lock(&ichan->chan_mutex);
   1572
   1573	__idmac_terminate_all(chan);
   1574
   1575	if (ichan->status > IPU_CHANNEL_FREE) {
   1576#ifdef DEBUG
   1577		if (chan->chan_id == IDMAC_IC_7) {
   1578			if (ic_sof > 0) {
   1579				free_irq(ic_sof, ichan);
   1580				ipu_irq_unmap(69);
   1581				ic_sof = -EINVAL;
   1582			}
   1583			if (ic_eof > 0) {
   1584				free_irq(ic_eof, ichan);
   1585				ipu_irq_unmap(70);
   1586				ic_eof = -EINVAL;
   1587			}
   1588		}
   1589#endif
   1590		free_irq(ichan->eof_irq, ichan);
   1591		ipu_irq_unmap(chan->chan_id);
   1592	}
   1593
   1594	ichan->status = IPU_CHANNEL_FREE;
   1595
   1596	ipu_uninit_channel(idmac, ichan);
   1597
   1598	mutex_unlock(&ichan->chan_mutex);
   1599
   1600	tasklet_schedule(&to_ipu(idmac)->tasklet);
   1601}
   1602
   1603static enum dma_status idmac_tx_status(struct dma_chan *chan,
   1604		       dma_cookie_t cookie, struct dma_tx_state *txstate)
   1605{
   1606	return dma_cookie_status(chan, cookie, txstate);
   1607}
   1608
   1609static int __init ipu_idmac_init(struct ipu *ipu)
   1610{
   1611	struct idmac *idmac = &ipu->idmac;
   1612	struct dma_device *dma = &idmac->dma;
   1613	int i;
   1614
   1615	dma_cap_set(DMA_SLAVE, dma->cap_mask);
   1616	dma_cap_set(DMA_PRIVATE, dma->cap_mask);
   1617
   1618	/* Compulsory common fields */
   1619	dma->dev				= ipu->dev;
   1620	dma->device_alloc_chan_resources	= idmac_alloc_chan_resources;
   1621	dma->device_free_chan_resources		= idmac_free_chan_resources;
   1622	dma->device_tx_status			= idmac_tx_status;
   1623	dma->device_issue_pending		= idmac_issue_pending;
   1624
   1625	/* Compulsory for DMA_SLAVE fields */
   1626	dma->device_prep_slave_sg		= idmac_prep_slave_sg;
   1627	dma->device_pause			= idmac_pause;
   1628	dma->device_terminate_all		= idmac_terminate_all;
   1629
   1630	INIT_LIST_HEAD(&dma->channels);
   1631	for (i = 0; i < IPU_CHANNELS_NUM; i++) {
   1632		struct idmac_channel *ichan = ipu->channel + i;
   1633		struct dma_chan *dma_chan = &ichan->dma_chan;
   1634
   1635		spin_lock_init(&ichan->lock);
   1636		mutex_init(&ichan->chan_mutex);
   1637
   1638		ichan->status		= IPU_CHANNEL_FREE;
   1639		ichan->sec_chan_en	= false;
   1640		snprintf(ichan->eof_name, sizeof(ichan->eof_name), "IDMAC EOF %d", i);
   1641
   1642		dma_chan->device	= &idmac->dma;
   1643		dma_cookie_init(dma_chan);
   1644		dma_chan->chan_id	= i;
   1645		list_add_tail(&dma_chan->device_node, &dma->channels);
   1646	}
   1647
   1648	idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
   1649
   1650	return dma_async_device_register(&idmac->dma);
   1651}
   1652
   1653static void ipu_idmac_exit(struct ipu *ipu)
   1654{
   1655	int i;
   1656	struct idmac *idmac = &ipu->idmac;
   1657
   1658	for (i = 0; i < IPU_CHANNELS_NUM; i++) {
   1659		struct idmac_channel *ichan = ipu->channel + i;
   1660
   1661		idmac_terminate_all(&ichan->dma_chan);
   1662	}
   1663
   1664	dma_async_device_unregister(&idmac->dma);
   1665}
   1666
   1667/*****************************************************************************
   1668 * IPU common probe / remove
   1669 */
   1670
   1671static int __init ipu_probe(struct platform_device *pdev)
   1672{
   1673	struct resource *mem_ipu, *mem_ic;
   1674	int ret;
   1675
   1676	spin_lock_init(&ipu_data.lock);
   1677
   1678	mem_ipu	= platform_get_resource(pdev, IORESOURCE_MEM, 0);
   1679	mem_ic	= platform_get_resource(pdev, IORESOURCE_MEM, 1);
   1680	if (!mem_ipu || !mem_ic)
   1681		return -EINVAL;
   1682
   1683	ipu_data.dev = &pdev->dev;
   1684
   1685	platform_set_drvdata(pdev, &ipu_data);
   1686
   1687	ret = platform_get_irq(pdev, 0);
   1688	if (ret < 0)
   1689		goto err_noirq;
   1690
   1691	ipu_data.irq_fn = ret;
   1692	ret = platform_get_irq(pdev, 1);
   1693	if (ret < 0)
   1694		goto err_noirq;
   1695
   1696	ipu_data.irq_err = ret;
   1697
   1698	dev_dbg(&pdev->dev, "fn irq %u, err irq %u\n",
   1699		ipu_data.irq_fn, ipu_data.irq_err);
   1700
   1701	/* Remap IPU common registers */
   1702	ipu_data.reg_ipu = ioremap(mem_ipu->start, resource_size(mem_ipu));
   1703	if (!ipu_data.reg_ipu) {
   1704		ret = -ENOMEM;
   1705		goto err_ioremap_ipu;
   1706	}
   1707
   1708	/* Remap Image Converter and Image DMA Controller registers */
   1709	ipu_data.reg_ic = ioremap(mem_ic->start, resource_size(mem_ic));
   1710	if (!ipu_data.reg_ic) {
   1711		ret = -ENOMEM;
   1712		goto err_ioremap_ic;
   1713	}
   1714
   1715	/* Get IPU clock */
   1716	ipu_data.ipu_clk = clk_get(&pdev->dev, NULL);
   1717	if (IS_ERR(ipu_data.ipu_clk)) {
   1718		ret = PTR_ERR(ipu_data.ipu_clk);
   1719		goto err_clk_get;
   1720	}
   1721
   1722	/* Make sure IPU HSP clock is running */
   1723	clk_prepare_enable(ipu_data.ipu_clk);
   1724
   1725	/* Disable all interrupts */
   1726	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
   1727	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_2);
   1728	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_3);
   1729	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_4);
   1730	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_5);
   1731
   1732	dev_dbg(&pdev->dev, "%s @ 0x%08lx, fn irq %u, err irq %u\n", pdev->name,
   1733		(unsigned long)mem_ipu->start, ipu_data.irq_fn, ipu_data.irq_err);
   1734
   1735	ret = ipu_irq_attach_irq(&ipu_data, pdev);
   1736	if (ret < 0)
   1737		goto err_attach_irq;
   1738
   1739	/* Initialize DMA engine */
   1740	ret = ipu_idmac_init(&ipu_data);
   1741	if (ret < 0)
   1742		goto err_idmac_init;
   1743
   1744	tasklet_setup(&ipu_data.tasklet, ipu_gc_tasklet);
   1745
   1746	ipu_data.dev = &pdev->dev;
   1747
   1748	dev_dbg(ipu_data.dev, "IPU initialized\n");
   1749
   1750	return 0;
   1751
   1752err_idmac_init:
   1753err_attach_irq:
   1754	ipu_irq_detach_irq(&ipu_data, pdev);
   1755	clk_disable_unprepare(ipu_data.ipu_clk);
   1756	clk_put(ipu_data.ipu_clk);
   1757err_clk_get:
   1758	iounmap(ipu_data.reg_ic);
   1759err_ioremap_ic:
   1760	iounmap(ipu_data.reg_ipu);
   1761err_ioremap_ipu:
   1762err_noirq:
   1763	dev_err(&pdev->dev, "Failed to probe IPU: %d\n", ret);
   1764	return ret;
   1765}
   1766
   1767static int ipu_remove(struct platform_device *pdev)
   1768{
   1769	struct ipu *ipu = platform_get_drvdata(pdev);
   1770
   1771	ipu_idmac_exit(ipu);
   1772	ipu_irq_detach_irq(ipu, pdev);
   1773	clk_disable_unprepare(ipu->ipu_clk);
   1774	clk_put(ipu->ipu_clk);
   1775	iounmap(ipu->reg_ic);
   1776	iounmap(ipu->reg_ipu);
   1777	tasklet_kill(&ipu->tasklet);
   1778
   1779	return 0;
   1780}
   1781
   1782/*
   1783 * We need two MEM resources - with IPU-common and Image Converter registers,
   1784 * including PF_CONF and IDMAC_* registers, and two IRQs - function and error
   1785 */
   1786static struct platform_driver ipu_platform_driver = {
   1787	.driver = {
   1788		.name	= "ipu-core",
   1789	},
   1790	.remove		= ipu_remove,
   1791};
   1792
   1793static int __init ipu_init(void)
   1794{
   1795	return platform_driver_probe(&ipu_platform_driver, ipu_probe);
   1796}
   1797subsys_initcall(ipu_init);
   1798
   1799MODULE_DESCRIPTION("IPU core driver");
   1800MODULE_LICENSE("GPL v2");
   1801MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
   1802MODULE_ALIAS("platform:ipu-core");