summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/iim.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-07-27 12:15:43 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2011-07-29 12:06:12 +0200
commit6b07e264e643f0f73da2fd6f36be66f4d5579933 (patch)
treecb540099f6f550c9c018d7bd6408a9648eaf1675 /arch/arm/mach-imx/iim.c
parentffcf536cef0fe90bb0b7340b82492ce0a54a0dc6 (diff)
downloadbarebox-6b07e264e643f0f73da2fd6f36be66f4d5579933.tar.gz
barebox-6b07e264e643f0f73da2fd6f36be66f4d5579933.tar.xz
ARM i.MX: IIM rework
The IIM module uses two drivers, one for the general IIM module and one for the individual banks. This patch turns this into a single driver to ease registration of the resources. This changes the user visible behaviour in the way that the explicit_sense_enable and permanent_write_enable device parameters are no longer bank specific but for the whole device. Also, the IIM module supports a maximum of 8 fuse banks, with these patch all of them are registered, even if they are not present in a SoC. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-imx/iim.c')
-rw-r--r--arch/arm/mach-imx/iim.c99
1 files changed, 49 insertions, 50 deletions
diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
index 0774ebba9c..1d23fd3e84 100644
--- a/arch/arm/mach-imx/iim.c
+++ b/arch/arm/mach-imx/iim.c
@@ -31,7 +31,15 @@
static unsigned long mac_addr_base;
-static int do_fuse_sense(unsigned long reg_base, unsigned int bank,
+struct iim_priv {
+ struct cdev cdev;
+ void __iomem *base;
+ void __iomem *bankbase;
+ int bank;
+ int banksize;
+};
+
+static int do_fuse_sense(void __iomem *reg_base, unsigned int bank,
unsigned int row)
{
u8 err, stat;
@@ -77,37 +85,34 @@ static ssize_t imx_iim_read(struct cdev *cdev, void *buf, size_t count,
ulong offset, ulong flags)
{
ulong size, i;
- struct device_d *dev = cdev->dev;
+ struct iim_priv *priv = cdev->priv;
const char *sense_param;
unsigned long explicit_sense = 0;
- if (dev == NULL)
- return -EINVAL;
-
- if ((sense_param = dev_get_param(dev, "explicit_sense_enable")))
+ if ((sense_param = dev_get_param(cdev->dev, "explicit_sense_enable")))
explicit_sense = simple_strtoul(sense_param, NULL, 0);
- size = min((ulong)count, dev->size - offset);
+ size = min((ulong)count, priv->banksize - offset);
if (explicit_sense) {
for (i = 0; i < size; i++) {
int row_val;
- row_val = do_fuse_sense(dev->parent->map_base,
- dev->id, (offset+i)*4);
+ row_val = do_fuse_sense(priv->base,
+ priv->bank, (offset + i) * 4);
if (row_val < 0)
return row_val;
((u8 *)buf)[i] = (u8)row_val;
}
} else {
for (i = 0; i < size; i++)
- ((u8 *)buf)[i] = ((u8 *)dev->map_base)[(offset+i)*4];
+ ((u8 *)buf)[i] = ((u8 *)priv->bankbase)[(offset+i)*4];
}
return size;
}
#ifdef CONFIG_IMX_IIM_FUSE_BLOW
-static int do_fuse_blow(unsigned long reg_base, unsigned int bank,
+static int do_fuse_blow(void __iomem *reg_base, unsigned int bank,
unsigned int row, u8 value)
{
int bit, ret = 0;
@@ -172,24 +177,21 @@ static ssize_t imx_iim_write(struct cdev *cdev, const void *buf, size_t count,
ulong offset, ulong flags)
{
ulong size, i;
- struct device_d *dev = cdev->dev;
+ struct iim_priv *priv = cdev->priv;
const char *write_param;
unsigned int blow_enable = 0;
- if (dev == NULL)
- return -EINVAL;
-
- if ((write_param = dev_get_param(dev, "permanent_write_enable")))
+ if ((write_param = dev_get_param(cdev->dev, "permanent_write_enable")))
blow_enable = simple_strtoul(write_param, NULL, 0);
- size = min((ulong)count, dev->size - offset);
+ size = min((ulong)count, priv->banksize - offset);
#ifdef CONFIG_IMX_IIM_FUSE_BLOW
if (blow_enable) {
for (i = 0; i < size; i++) {
int ret;
- ret = do_fuse_blow(dev->parent->map_base, dev->id,
- (offset+i)*4, ((u8 *)buf)[i]);
+ ret = do_fuse_blow(priv->base, priv->bank,
+ (offset + i) * 4, ((u8 *)buf)[i]);
if (ret < 0)
return ret;
}
@@ -197,7 +199,7 @@ static ssize_t imx_iim_write(struct cdev *cdev, const void *buf, size_t count,
#endif /* CONFIG_IMX_IIM_FUSE_BLOW */
{
for (i = 0; i < size; i++)
- ((u8 *)dev->map_base)[(offset+i)*4] = ((u8 *)buf)[i];
+ ((u8 *)priv->bankbase)[(offset+i)*4] = ((u8 *)buf)[i];
}
return size;
@@ -224,38 +226,41 @@ static int imx_iim_blow_enable_set(struct device_d *dev, struct param_d *param,
return dev_param_set_generic(dev, param, blow_enable ? "1" : "0");
}
-static int imx_iim_probe(struct device_d *dev)
-{
- struct imx_iim_platform_data *pdata = dev->platform_data;
-
- if (pdata)
- mac_addr_base = pdata->mac_addr_base;
-
- return 0;
-}
-
-static int imx_iim_bank_probe(struct device_d *dev)
+static int imx_iim_add_bank(struct device_d *dev, int num)
{
+ struct iim_priv *priv;
struct cdev *cdev;
- struct device_d *parent;
- int err;
- cdev = xzalloc(sizeof (struct cdev));
- dev->priv = cdev;
+ priv = xzalloc(sizeof (*priv));
+ priv->base = (void __iomem *)dev->map_base;
+ priv->bankbase = priv->base + 0x800 + 0x400 * num;
+ priv->bank = num;
+ priv->banksize = 32;
+ cdev = &priv->cdev;
cdev->dev = dev;
cdev->ops = &imx_iim_ops;
- cdev->size = dev->size;
- cdev->name = asprintf(DRIVERNAME "_bank%d", dev->id);
+ cdev->priv = priv;
+ cdev->size = 32;
+ cdev->name = asprintf(DRIVERNAME "_bank%d", num);
if (cdev->name == NULL)
return -ENOMEM;
- parent = get_device_by_name(DRIVERNAME "0");
- if (parent == NULL)
- return -ENODEV;
- err = dev_add_child(parent, dev);
- if (err < 0)
- return err;
+ return devfs_create(cdev);
+}
+
+static int imx_iim_probe(struct device_d *dev)
+{
+ struct imx_iim_platform_data *pdata = dev->platform_data;
+ int err;
+ int i;
+
+ if (pdata)
+ mac_addr_base = pdata->mac_addr_base;
+
+ for (i = 0; i < 8; i++) {
+ imx_iim_add_bank(dev, i);
+ }
#ifdef CONFIG_IMX_IIM_FUSE_BLOW
err = dev_add_param(dev, "permanent_write_enable",
@@ -275,7 +280,7 @@ static int imx_iim_bank_probe(struct device_d *dev)
if (err < 0)
return err;
- return devfs_create(cdev);
+ return 0;
}
static struct driver_d imx_iim_driver = {
@@ -283,15 +288,9 @@ static struct driver_d imx_iim_driver = {
.probe = imx_iim_probe,
};
-static struct driver_d imx_iim_bank_driver = {
- .name = DRIVERNAME "_bank",
- .probe = imx_iim_bank_probe,
-};
-
static int imx_iim_init(void)
{
register_driver(&imx_iim_driver);
- register_driver(&imx_iim_bank_driver);
return 0;
}