-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mfd: Add SuperH Mobile SDHI platform driver
This patch adds an MFD driver for the SuperH Mobile SDHI hardware block. At this point the driver simply wraps the tmio-mmc driver with some clock code. In the future this driver is the place to put SDHI specific hotplug code. Signed-off-by: Magnus Damm <damm@opensource.se> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
- Loading branch information
Magnus Damm
authored and
Paul Mundt
committed
Oct 26, 2009
1 parent
374576a
commit a87d563
Showing
3 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
/* | ||
* SuperH Mobile SDHI | ||
* | ||
* Copyright (C) 2009 Magnus Damm | ||
* | ||
* 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. | ||
* | ||
* Based on "Compaq ASIC3 support": | ||
* | ||
* Copyright 2001 Compaq Computer Corporation. | ||
* Copyright 2004-2005 Phil Blundell | ||
* Copyright 2007-2008 OpenedHand Ltd. | ||
* | ||
* Authors: Phil Blundell <pb@handhelds.org>, | ||
* Samuel Ortiz <sameo@openedhand.com> | ||
* | ||
*/ | ||
|
||
#include <linux/kernel.h> | ||
#include <linux/clk.h> | ||
#include <linux/platform_device.h> | ||
|
||
#include <linux/mfd/core.h> | ||
#include <linux/mfd/tmio.h> | ||
|
||
struct sh_mobile_sdhi { | ||
struct clk *clk; | ||
struct tmio_mmc_data mmc_data; | ||
struct mfd_cell cell_mmc; | ||
}; | ||
|
||
static struct resource sh_mobile_sdhi_resources[] = { | ||
{ | ||
.start = 0x000, | ||
.end = 0x1ff, | ||
.flags = IORESOURCE_MEM, | ||
}, | ||
{ | ||
.start = 0, | ||
.end = 0, | ||
.flags = IORESOURCE_IRQ, | ||
}, | ||
}; | ||
|
||
static struct mfd_cell sh_mobile_sdhi_cell = { | ||
.name = "tmio-mmc", | ||
.num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources), | ||
.resources = sh_mobile_sdhi_resources, | ||
}; | ||
|
||
static int __init sh_mobile_sdhi_probe(struct platform_device *pdev) | ||
{ | ||
struct sh_mobile_sdhi *priv; | ||
struct resource *mem; | ||
char clk_name[8]; | ||
int ret, irq; | ||
|
||
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
if (!mem) | ||
dev_err(&pdev->dev, "missing MEM resource\n"); | ||
|
||
irq = platform_get_irq(pdev, 0); | ||
if (irq < 0) | ||
dev_err(&pdev->dev, "missing IRQ resource\n"); | ||
|
||
if (!mem || (irq < 0)) | ||
return -EINVAL; | ||
|
||
priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL); | ||
if (priv == NULL) { | ||
dev_err(&pdev->dev, "kzalloc failed\n"); | ||
return -ENOMEM; | ||
} | ||
|
||
snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id); | ||
priv->clk = clk_get(&pdev->dev, clk_name); | ||
if (IS_ERR(priv->clk)) { | ||
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); | ||
ret = PTR_ERR(priv->clk); | ||
kfree(priv); | ||
return ret; | ||
} | ||
|
||
clk_enable(priv->clk); | ||
|
||
/* FIXME: silly const unsigned int hclk */ | ||
*(unsigned int *)&priv->mmc_data.hclk = clk_get_rate(priv->clk); | ||
|
||
memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); | ||
priv->cell_mmc.driver_data = &priv->mmc_data; | ||
priv->cell_mmc.platform_data = &priv->cell_mmc; | ||
priv->cell_mmc.data_size = sizeof(priv->cell_mmc); | ||
|
||
platform_set_drvdata(pdev, priv); | ||
|
||
ret = mfd_add_devices(&pdev->dev, pdev->id, | ||
&priv->cell_mmc, 1, mem, irq); | ||
if (ret) { | ||
clk_disable(priv->clk); | ||
clk_put(priv->clk); | ||
kfree(priv); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static int sh_mobile_sdhi_remove(struct platform_device *pdev) | ||
{ | ||
struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev); | ||
|
||
mfd_remove_devices(&pdev->dev); | ||
clk_disable(priv->clk); | ||
clk_put(priv->clk); | ||
kfree(priv); | ||
|
||
return 0; | ||
} | ||
|
||
static struct platform_driver sh_mobile_sdhi_driver = { | ||
.driver = { | ||
.name = "sh_mobile_sdhi", | ||
.owner = THIS_MODULE, | ||
}, | ||
.probe = sh_mobile_sdhi_probe, | ||
.remove = __devexit_p(sh_mobile_sdhi_remove), | ||
}; | ||
|
||
static int __init sh_mobile_sdhi_init(void) | ||
{ | ||
return platform_driver_register(&sh_mobile_sdhi_driver); | ||
} | ||
|
||
static void __exit sh_mobile_sdhi_exit(void) | ||
{ | ||
platform_driver_unregister(&sh_mobile_sdhi_driver); | ||
} | ||
|
||
module_init(sh_mobile_sdhi_init); | ||
module_exit(sh_mobile_sdhi_exit); | ||
|
||
MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); | ||
MODULE_AUTHOR("Magnus Damm"); | ||
MODULE_LICENSE("GPL v2"); |