/*
 * SuperH Mobile MERAM Driver for SuperH Mobile LCDC Driver
 *
 * Copyright (c) 2011	Damian Hobson-Garcia <dhobsong@igel.co.jp>
 *                      Takanari Hayama <taki@igel.co.jp>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/pm_runtime.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <video/sh_mobile_meram.h>

/* meram registers */
#define MEVCR1			0x4
#define MEVCR1_RST		(1 << 31)
#define MEVCR1_WD		(1 << 30)
#define MEVCR1_AMD1		(1 << 29)
#define MEVCR1_AMD0		(1 << 28)
#define MEQSEL1			0x40
#define MEQSEL2			0x44

#define MExxCTL			0x400
#define MExxCTL_BV		(1 << 31)
#define MExxCTL_BSZ_SHIFT	28
#define MExxCTL_MSAR_MASK	(0x7ff << MExxCTL_MSAR_SHIFT)
#define MExxCTL_MSAR_SHIFT	16
#define MExxCTL_NXT_MASK	(0x1f << MExxCTL_NXT_SHIFT)
#define MExxCTL_NXT_SHIFT	11
#define MExxCTL_WD1		(1 << 10)
#define MExxCTL_WD0		(1 << 9)
#define MExxCTL_WS		(1 << 8)
#define MExxCTL_CB		(1 << 7)
#define MExxCTL_WBF		(1 << 6)
#define MExxCTL_WF		(1 << 5)
#define MExxCTL_RF		(1 << 4)
#define MExxCTL_CM		(1 << 3)
#define MExxCTL_MD_READ		(1 << 0)
#define MExxCTL_MD_WRITE	(2 << 0)
#define MExxCTL_MD_ICB_WB	(3 << 0)
#define MExxCTL_MD_ICB		(4 << 0)
#define MExxCTL_MD_FB		(7 << 0)
#define MExxCTL_MD_MASK		(7 << 0)
#define MExxBSIZE		0x404
#define MExxBSIZE_RCNT_SHIFT	28
#define MExxBSIZE_YSZM1_SHIFT	16
#define MExxBSIZE_XSZM1_SHIFT	0
#define MExxMNCF		0x408
#define MExxMNCF_KWBNM_SHIFT	28
#define MExxMNCF_KRBNM_SHIFT	24
#define MExxMNCF_BNM_SHIFT	16
#define MExxMNCF_XBV		(1 << 15)
#define MExxMNCF_CPL_YCBCR444	(1 << 12)
#define MExxMNCF_CPL_YCBCR420	(2 << 12)
#define MExxMNCF_CPL_YCBCR422	(3 << 12)
#define MExxMNCF_CPL_MSK	(3 << 12)
#define MExxMNCF_BL		(1 << 2)
#define MExxMNCF_LNM_SHIFT	0
#define MExxSARA		0x410
#define MExxSARB		0x414
#define MExxSBSIZE		0x418
#define MExxSBSIZE_HDV		(1 << 31)
#define MExxSBSIZE_HSZ16	(0 << 28)
#define MExxSBSIZE_HSZ32	(1 << 28)
#define MExxSBSIZE_HSZ64	(2 << 28)
#define MExxSBSIZE_HSZ128	(3 << 28)
#define MExxSBSIZE_SBSIZZ_SHIFT	0

#define MERAM_MExxCTL_VAL(next, addr)	\
	((((next) << MExxCTL_NXT_SHIFT) & MExxCTL_NXT_MASK) | \
	 (((addr) << MExxCTL_MSAR_SHIFT) & MExxCTL_MSAR_MASK))
#define	MERAM_MExxBSIZE_VAL(rcnt, yszm1, xszm1) \
	(((rcnt) << MExxBSIZE_RCNT_SHIFT) | \
	 ((yszm1) << MExxBSIZE_YSZM1_SHIFT) | \
	 ((xszm1) << MExxBSIZE_XSZM1_SHIFT))

#define SH_MOBILE_MERAM_ICB_NUM		32

static unsigned long common_regs[] = {
	MEVCR1,
	MEQSEL1,
	MEQSEL2,
};
#define CMN_REGS_SIZE ARRAY_SIZE(common_regs)

static unsigned long icb_regs[] = {
	MExxCTL,
	MExxBSIZE,
	MExxMNCF,
	MExxSARA,
	MExxSARB,
	MExxSBSIZE,
};
#define ICB_REGS_SIZE ARRAY_SIZE(icb_regs)

/*
 * sh_mobile_meram_icb - MERAM ICB information
 * @regs: Registers cache
 * @region: Start and end addresses of the MERAM region
 * @cache_unit: Bytes to cache per ICB
 * @pixelformat: Video pixel format of the data stored in the ICB
 * @current_reg: Which of Start Address Register A (0) or B (1) is in use
 */
struct sh_mobile_meram_icb {
	unsigned long regs[ICB_REGS_SIZE];

	unsigned long region;
	unsigned int cache_unit;
	unsigned int pixelformat;
	unsigned int current_reg;
};

/*
 * sh_mobile_meram_priv - MERAM device
 * @base: Registers base address
 * @regs: Registers cache
 * @lock: Protects used_icb and icbs
 * @used_icb: Bitmask of used ICBs
 * @icbs: ICBs
 */
struct sh_mobile_meram_priv {
	void __iomem *base;
	unsigned long regs[CMN_REGS_SIZE];

	struct mutex lock;
	unsigned long used_icb;
	struct sh_mobile_meram_icb icbs[SH_MOBILE_MERAM_ICB_NUM];
};

/* settings */
#define MERAM_SEC_LINE 15
#define MERAM_LINE_WIDTH 2048

/*
 * MERAM/ICB access functions
 */

#define MERAM_ICB_OFFSET(base, idx, off)	((base) + (off) + (idx) * 0x20)

static inline void meram_write_icb(void __iomem *base, unsigned int idx,
				   unsigned int off, unsigned long val)
{
	iowrite32(val, MERAM_ICB_OFFSET(base, idx, off));
}

static inline unsigned long meram_read_icb(void __iomem *base, unsigned int idx,
					   unsigned int off)
{
	return ioread32(MERAM_ICB_OFFSET(base, idx, off));
}

static inline void meram_write_reg(void __iomem *base, unsigned int off,
				   unsigned long val)
{
	iowrite32(val, base + off);
}

static inline unsigned long meram_read_reg(void __iomem *base, unsigned int off)
{
	return ioread32(base + off);
}

/*
 * register ICB
 */

#define MERAM_CACHE_START(p)	 ((p) >> 16)
#define MERAM_CACHE_END(p)	 ((p) & 0xffff)
#define MERAM_CACHE_SET(o, s)	 ((((o) & 0xffff) << 16) | \
				  (((o) + (s) - 1) & 0xffff))

/*
 * check if there's no overlaps in MERAM allocation.
 */

static inline int meram_check_overlap(struct sh_mobile_meram_priv *priv,
				      const struct sh_mobile_meram_icb_cfg *new)
{
	unsigned int used_start, used_end, meram_start, meram_end;
	unsigned int i;

	/* valid ICB? */
	if (new->marker_icb & ~0x1f || new->cache_icb & ~0x1f)
		return 1;

	if (test_bit(new->marker_icb, &priv->used_icb) ||
	    test_bit(new->cache_icb,  &priv->used_icb))
		return  1;

	for (i = 0; i < SH_MOBILE_MERAM_ICB_NUM; i++) {
		if (!test_bit(i, &priv->used_icb))
			continue;

		used_start = MERAM_CACHE_START(priv->icbs[i].region);
		used_end   = MERAM_CACHE_END(priv->icbs[i].region);
		meram_start = new->meram_offset;
		meram_end   = new->meram_offset + new->meram_size;

		if ((meram_start >= used_start && meram_start < used_end) ||
		    (meram_end > used_start && meram_end < used_end))
			return 1;
	}

	return 0;
}

/*
 * mark the specified ICB as used
 */

static inline void meram_mark(struct sh_mobile_meram_priv *priv,
			      const struct sh_mobile_meram_icb_cfg *new,
			      int pixelformat)
{
	__set_bit(new->marker_icb, &priv->used_icb);
	__set_bit(new->cache_icb, &priv->used_icb);

	priv->icbs[new->marker_icb].region = MERAM_CACHE_SET(new->meram_offset,
							     new->meram_size);
	priv->icbs[new->cache_icb].region = MERAM_CACHE_SET(new->meram_offset,
							    new->meram_size);
	priv->icbs[new->marker_icb].current_reg = 1;
	priv->icbs[new->marker_icb].pixelformat = pixelformat;
}

/*
 * unmark the specified ICB as used
 */

static inline void meram_unmark(struct sh_mobile_meram_priv *priv,
				const struct sh_mobile_meram_icb_cfg *icb)
{
	__clear_bit(icb->marker_icb, &priv->used_icb);
	__clear_bit(icb->cache_icb, &priv->used_icb);
}

/*
 * is this a YCbCr(NV12, NV16 or NV24) colorspace
 */
static inline int is_nvcolor(int cspace)
{
	if (cspace == SH_MOBILE_MERAM_PF_NV ||
	    cspace == SH_MOBILE_MERAM_PF_NV24)
		return 1;
	return 0;
}

/*
 * set the next address to fetch
 */
static inline void meram_set_next_addr(struct sh_mobile_meram_priv *priv,
				       const struct sh_mobile_meram_cfg *cfg,
				       unsigned long base_addr_y,
				       unsigned long base_addr_c)
{
	struct sh_mobile_meram_icb *icb = &priv->icbs[cfg->icb[0].marker_icb];
	unsigned long target;

	icb->current_reg ^= 1;
	target = icb->current_reg ? MExxSARB : MExxSARA;

	/* set the next address to fetch */
	meram_write_icb(priv->base, cfg->icb[0].cache_icb, target,
			base_addr_y);
	meram_write_icb(priv->base, cfg->icb[0].marker_icb, target,
			base_addr_y +
			priv->icbs[cfg->icb[0].marker_icb].cache_unit);

	if (is_nvcolor(icb->pixelformat)) {
		meram_write_icb(priv->base, cfg->icb[1].cache_icb,  target,
				base_addr_c);
		meram_write_icb(priv->base, cfg->icb[1].marker_icb, target,
				base_addr_c +
				priv->icbs[cfg->icb[1].marker_icb].cache_unit);
	}
}

/*
 * get the next ICB address
 */
static inline void
meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
			const struct sh_mobile_meram_cfg *cfg,
			unsigned long *icb_addr_y, unsigned long *icb_addr_c)
{
	struct sh_mobile_meram_priv *priv = pdata->priv;
	struct sh_mobile_meram_icb *icb = &priv->icbs[cfg->icb[0].marker_icb];
	unsigned long icb_offset;

	if (pdata->addr_mode == SH_MOBILE_MERAM_MODE0)
		icb_offset = 0x80000000 | (icb->current_reg << 29);
	else
		icb_offset = 0xc0000000 | (icb->current_reg << 23);

	*icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24);
	if (is_nvcolor(icb->pixelformat))
		*icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24);
}

#define MERAM_CALC_BYTECOUNT(x, y) \
	(((x) * (y) + (MERAM_LINE_WIDTH - 1)) & ~(MERAM_LINE_WIDTH - 1))

/*
 * initialize MERAM
 */

static int meram_init(struct sh_mobile_meram_priv *priv,
		      const struct sh_mobile_meram_icb_cfg *icb,
		      unsigned int xres, unsigned int yres,
		      unsigned int *out_pitch)
{
	unsigned long total_byte_count = MERAM_CALC_BYTECOUNT(xres, yres);
	unsigned long bnm;
	unsigned int lcdc_pitch;
	unsigned int xpitch;
	unsigned int line_cnt;
	unsigned int save_lines;

	/* adjust pitch to 1024, 2048, 4096 or 8192 */
	lcdc_pitch = (xres - 1) | 1023;
	lcdc_pitch = lcdc_pitch | (lcdc_pitch >> 1);
	lcdc_pitch = lcdc_pitch | (lcdc_pitch >> 2);
	lcdc_pitch += 1;

	/* derive settings */
	if (lcdc_pitch == 8192 && yres >= 1024) {
		lcdc_pitch = xpitch = MERAM_LINE_WIDTH;
		line_cnt = total_byte_count >> 11;
		*out_pitch = xres;
		save_lines = (icb->meram_size / 16 / MERAM_SEC_LINE);
		save_lines *= MERAM_SEC_LINE;
	} else {
		xpitch = xres;
		line_cnt = yres;
		*out_pitch = lcdc_pitch;
		save_lines = icb->meram_size / (lcdc_pitch >> 10) / 2;
		save_lines &= 0xff;
	}
	bnm = (save_lines - 1) << 16;

	/* TODO: we better to check if we have enough MERAM buffer size */

	/* set up ICB */
	meram_write_icb(priv->base, icb->cache_icb,  MExxBSIZE,
			MERAM_MExxBSIZE_VAL(0x0, line_cnt - 1, xpitch - 1));
	meram_write_icb(priv->base, icb->marker_icb, MExxBSIZE,
			MERAM_MExxBSIZE_VAL(0xf, line_cnt - 1, xpitch - 1));

	meram_write_icb(priv->base, icb->cache_icb,  MExxMNCF, bnm);
	meram_write_icb(priv->base, icb->marker_icb, MExxMNCF, bnm);

	meram_write_icb(priv->base, icb->cache_icb,  MExxSBSIZE, xpitch);
	meram_write_icb(priv->base, icb->marker_icb, MExxSBSIZE, xpitch);

	/* save a cache unit size */
	priv->icbs[icb->cache_icb].cache_unit = xres * save_lines;
	priv->icbs[icb->marker_icb].cache_unit = xres * save_lines;

	/*
	 * Set MERAM for framebuffer
	 *
	 * we also chain the cache_icb and the marker_icb.
	 * we also split the allocated MERAM buffer between two ICBs.
	 */
	meram_write_icb(priv->base, icb->cache_icb, MExxCTL,
			MERAM_MExxCTL_VAL(icb->marker_icb, icb->meram_offset) |
			MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
			MExxCTL_MD_FB);
	meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
			MERAM_MExxCTL_VAL(icb->cache_icb, icb->meram_offset +
					  icb->meram_size / 2) |
			MExxCTL_WD1 | MExxCTL_WD0 | MExxCTL_WS | MExxCTL_CM |
			MExxCTL_MD_FB);

	return 0;
}

static void meram_deinit(struct sh_mobile_meram_priv *priv,
			 const struct sh_mobile_meram_icb_cfg *icb)
{
	/* disable ICB */
	meram_write_icb(priv->base, icb->cache_icb,  MExxCTL,
			MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF);
	meram_write_icb(priv->base, icb->marker_icb, MExxCTL,
			MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF);

	priv->icbs[icb->cache_icb].cache_unit = 0;
	priv->icbs[icb->marker_icb].cache_unit = 0;
}

/*
 * register the ICB
 */

static int sh_mobile_meram_register(struct sh_mobile_meram_info *pdata,
				    const struct sh_mobile_meram_cfg *cfg,
				    unsigned int xres, unsigned int yres,
				    unsigned int pixelformat,
				    unsigned long base_addr_y,
				    unsigned long base_addr_c,
				    unsigned long *icb_addr_y,
				    unsigned long *icb_addr_c,
				    unsigned int *pitch)
{
	struct platform_device *pdev;
	struct sh_mobile_meram_priv *priv;
	unsigned int out_pitch;
	unsigned int n;
	int error = 0;

	if (!pdata || !pdata->priv || !pdata->pdev || !cfg)
		return -EINVAL;

	if (pixelformat != SH_MOBILE_MERAM_PF_NV &&
	    pixelformat != SH_MOBILE_MERAM_PF_NV24 &&
	    pixelformat != SH_MOBILE_MERAM_PF_RGB)
		return -EINVAL;

	priv = pdata->priv;
	pdev = pdata->pdev;

	dev_dbg(&pdev->dev, "registering %dx%d (%s) (y=%08lx, c=%08lx)",
		xres, yres, (!pixelformat) ? "yuv" : "rgb",
		base_addr_y, base_addr_c);

	/* we can't handle wider than 8192px */
	if (xres > 8192) {
		dev_err(&pdev->dev, "width exceeding the limit (> 8192).");
		return -EINVAL;
	}

	/* do we have at least one ICB config? */
	if (cfg->icb[0].marker_icb < 0 || cfg->icb[0].cache_icb < 0) {
		dev_err(&pdev->dev, "at least one ICB is required.");
		return -EINVAL;
	}

	mutex_lock(&priv->lock);

	/* make sure that there's no overlaps */
	if (meram_check_overlap(priv, &cfg->icb[0])) {
		dev_err(&pdev->dev, "conflicting config detected.");
		error = -EINVAL;
		goto err;
	}
	n = 1;

	/* do the same if we have the second ICB set */
	if (cfg->icb[1].marker_icb >= 0 && cfg->icb[1].cache_icb >= 0) {
		if (meram_check_overlap(priv, &cfg->icb[1])) {
			dev_err(&pdev->dev, "conflicting config detected.");
			error = -EINVAL;
			goto err;
		}
		n = 2;
	}

	if (is_nvcolor(pixelformat) && n != 2) {
		dev_err(&pdev->dev, "requires two ICB sets for planar Y/C.");
		error =  -EINVAL;
		goto err;
	}

	/* we now register the ICB */
	meram_mark(priv, &cfg->icb[0], pixelformat);
	if (is_nvcolor(pixelformat))
		meram_mark(priv, &cfg->icb[1], pixelformat);

	/* initialize MERAM */
	meram_init(priv, &cfg->icb[0], xres, yres, &out_pitch);
	*pitch = out_pitch;
	if (pixelformat == SH_MOBILE_MERAM_PF_NV)
		meram_init(priv, &cfg->icb[1], xres, (yres + 1) / 2,
			&out_pitch);
	else if (pixelformat == SH_MOBILE_MERAM_PF_NV24)
		meram_init(priv, &cfg->icb[1], 2 * xres, (yres + 1) / 2,
			&out_pitch);

	meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c);
	meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c);

	dev_dbg(&pdev->dev, "registered - can access via y=%08lx, c=%08lx",
		*icb_addr_y, *icb_addr_c);

err:
	mutex_unlock(&priv->lock);
	return error;
}

static int sh_mobile_meram_unregister(struct sh_mobile_meram_info *pdata,
				      const struct sh_mobile_meram_cfg *cfg)
{
	struct sh_mobile_meram_priv *priv;
	struct sh_mobile_meram_icb *icb;

	if (!pdata || !pdata->priv || !cfg)
		return -EINVAL;

	priv = pdata->priv;
	icb = &priv->icbs[cfg->icb[0].marker_icb];

	mutex_lock(&priv->lock);

	/* deinit & unmark */
	if (is_nvcolor(icb->pixelformat)) {
		meram_deinit(priv, &cfg->icb[1]);
		meram_unmark(priv, &cfg->icb[1]);
	}
	meram_deinit(priv, &cfg->icb[0]);
	meram_unmark(priv, &cfg->icb[0]);

	mutex_unlock(&priv->lock);

	return 0;
}

static int sh_mobile_meram_update(struct sh_mobile_meram_info *pdata,
				  const struct sh_mobile_meram_cfg *cfg,
				  unsigned long base_addr_y,
				  unsigned long base_addr_c,
				  unsigned long *icb_addr_y,
				  unsigned long *icb_addr_c)
{
	struct sh_mobile_meram_priv *priv;

	if (!pdata || !pdata->priv || !cfg)
		return -EINVAL;

	priv = pdata->priv;

	mutex_lock(&priv->lock);

	meram_set_next_addr(priv, cfg, base_addr_y, base_addr_c);
	meram_get_next_icb_addr(pdata, cfg, icb_addr_y, icb_addr_c);

	mutex_unlock(&priv->lock);

	return 0;
}

static int sh_mobile_meram_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
	unsigned int i, j;

	for (i = 0; i < CMN_REGS_SIZE; i++)
		priv->regs[i] = meram_read_reg(priv->base, common_regs[i]);

	for (i = 0; i < 32; i++) {
		if (!test_bit(i, &priv->used_icb))
			continue;
		for (j = 0; j < ICB_REGS_SIZE; j++) {
			priv->icbs[i].regs[j] =
				meram_read_icb(priv->base, i, icb_regs[j]);
			/* Reset ICB on resume */
			if (icb_regs[j] == MExxCTL)
				priv->icbs[i].regs[j] |=
					MExxCTL_WBF | MExxCTL_WF | MExxCTL_RF;
		}
	}
	return 0;
}

static int sh_mobile_meram_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
	unsigned int i, j;

	for (i = 0; i < 32; i++) {
		if (!test_bit(i, &priv->used_icb))
			continue;
		for (j = 0; j < ICB_REGS_SIZE; j++)
			meram_write_icb(priv->base, i, icb_regs[j],
					priv->icbs[i].regs[j]);
	}

	for (i = 0; i < CMN_REGS_SIZE; i++)
		meram_write_reg(priv->base, common_regs[i], priv->regs[i]);
	return 0;
}

static const struct dev_pm_ops sh_mobile_meram_dev_pm_ops = {
	.runtime_suspend = sh_mobile_meram_runtime_suspend,
	.runtime_resume = sh_mobile_meram_runtime_resume,
};

static struct sh_mobile_meram_ops sh_mobile_meram_ops = {
	.module			= THIS_MODULE,
	.meram_register		= sh_mobile_meram_register,
	.meram_unregister	= sh_mobile_meram_unregister,
	.meram_update		= sh_mobile_meram_update,
};

/*
 * initialize MERAM
 */

static int __devinit sh_mobile_meram_probe(struct platform_device *pdev)
{
	struct sh_mobile_meram_priv *priv;
	struct sh_mobile_meram_info *pdata = pdev->dev.platform_data;
	struct resource *regs;
	struct resource *meram;
	int error;

	if (!pdata) {
		dev_err(&pdev->dev, "no platform data defined\n");
		return -EINVAL;
	}

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	meram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (regs == NULL || meram == NULL) {
		dev_err(&pdev->dev, "cannot get platform resources\n");
		return -ENOENT;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "cannot allocate device data\n");
		return -ENOMEM;
	}

	/* initialize private data */
	mutex_init(&priv->lock);
	pdata->ops = &sh_mobile_meram_ops;
	pdata->priv = priv;
	pdata->pdev = pdev;

	if (!request_mem_region(regs->start, resource_size(regs), pdev->name)) {
		dev_err(&pdev->dev, "MERAM registers region already claimed\n");
		error = -EBUSY;
		goto err_req_regs;
	}

	if (!request_mem_region(meram->start, resource_size(meram),
				pdev->name)) {
		dev_err(&pdev->dev, "MERAM memory region already claimed\n");
		error = -EBUSY;
		goto err_req_meram;
	}

	priv->base = ioremap_nocache(regs->start, resource_size(regs));
	if (!priv->base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		error = -EFAULT;
		goto err_ioremap;
	}

	/* initialize ICB addressing mode */
	if (pdata->addr_mode == SH_MOBILE_MERAM_MODE1)
		meram_write_reg(priv->base, MEVCR1, MEVCR1_AMD1);

	platform_set_drvdata(pdev, priv);
	pm_runtime_enable(&pdev->dev);

	dev_info(&pdev->dev, "sh_mobile_meram initialized.");

	return 0;

err_ioremap:
	release_mem_region(meram->start, resource_size(meram));
err_req_meram:
	release_mem_region(regs->start, resource_size(regs));
err_req_regs:
	mutex_destroy(&priv->lock);
	kfree(priv);

	return error;
}


static int sh_mobile_meram_remove(struct platform_device *pdev)
{
	struct sh_mobile_meram_priv *priv = platform_get_drvdata(pdev);
	struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	struct resource *meram = platform_get_resource(pdev, IORESOURCE_MEM, 1);

	pm_runtime_disable(&pdev->dev);

	iounmap(priv->base);
	release_mem_region(meram->start, resource_size(meram));
	release_mem_region(regs->start, resource_size(regs));

	mutex_destroy(&priv->lock);

	kfree(priv);

	return 0;
}

static struct platform_driver sh_mobile_meram_driver = {
	.driver	= {
		.name		= "sh_mobile_meram",
		.owner		= THIS_MODULE,
		.pm		= &sh_mobile_meram_dev_pm_ops,
	},
	.probe		= sh_mobile_meram_probe,
	.remove		= sh_mobile_meram_remove,
};

module_platform_driver(sh_mobile_meram_driver);

MODULE_DESCRIPTION("SuperH Mobile MERAM driver");
MODULE_AUTHOR("Damian Hobson-Garcia / Takanari Hayama");
MODULE_LICENSE("GPL v2");
