summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2016-02-05 08:38:04 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-02-05 15:13:28 +0100
commit9064a935cda5548368fad5e3927c6483c2f7f58e (patch)
tree988e12feb5e656c4245c444bd48bab4c50ecfa89 /arch
parent77bfff1cbef2db1b8024dbb4fd2e5bdaeff5b9f0 (diff)
downloadbarebox-9064a935cda5548368fad5e3927c6483c2f7f58e.tar.gz
barebox-9064a935cda5548368fad5e3927c6483c2f7f58e.tar.xz
ARM: i.MX: iim: Switch to regmap support
To provide consumers easier access to the IIM. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-imx/iim.c121
1 files changed, 62 insertions, 59 deletions
diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
index c5751fe111..c16a6c6879 100644
--- a/arch/arm/mach-imx/iim.c
+++ b/arch/arm/mach-imx/iim.c
@@ -26,6 +26,7 @@
#include <malloc.h>
#include <of.h>
#include <io.h>
+#include <regmap.h>
#include <regulator.h>
#include <linux/err.h>
@@ -40,14 +41,14 @@
struct iim_priv;
struct iim_bank {
- struct cdev cdev;
+ struct regmap *map;
void __iomem *bankbase;
int bank;
struct iim_priv *iim;
+ struct regmap_config map_config;
};
struct iim_priv {
- struct cdev cdev;
struct device_d dev;
void __iomem *base;
void __iomem *bankbase;
@@ -102,34 +103,28 @@ static int imx_iim_fuse_sense(struct iim_bank *bank, unsigned int row)
return readb(reg_base + IIM_SDAT);
}
-static ssize_t imx_iim_cdev_read(struct cdev *cdev, void *buf, size_t count,
- loff_t offset, ulong flags)
+static int imx_iim_reg_read(void *ctx, unsigned int reg, unsigned int *val)
{
- ulong size, i;
- struct iim_bank *bank = container_of(cdev, struct iim_bank, cdev);
+ struct iim_bank *bank = ctx;
- size = min((loff_t)count, 32 - offset);
if (bank->iim->sense_enable) {
- for (i = 0; i < size; i++) {
- int row_val;
-
- row_val = imx_iim_fuse_sense(bank, offset + i);
- if (row_val < 0)
- return row_val;
- ((u8 *)buf)[i] = (u8)row_val;
- }
+ int row_val;
+ row_val = imx_iim_fuse_sense(bank, reg);
+ if (row_val < 0)
+ return row_val;
+ *val = (u8)row_val;
} else {
- for (i = 0; i < size; i++)
- ((u8 *)buf)[i] = ((u8 *)bank->bankbase)[(offset+i)*4];
+ *val = readl(bank->bankbase + reg * 4);
}
- return size;
+ return 0;
}
int imx_iim_read(unsigned int banknum, int offset, void *buf, int count)
{
struct iim_priv *iim = imx_iim;
struct iim_bank *bank;
+ int ret;
if (!imx_iim)
return -ENODEV;
@@ -139,7 +134,11 @@ int imx_iim_read(unsigned int banknum, int offset, void *buf, int count)
bank = iim->bank[banknum];
- return imx_iim_cdev_read(&bank->cdev, buf, count, offset, 0);
+ ret = regmap_bulk_read(bank->map, offset, buf, count);
+ if (ret)
+ return ret;
+
+ return count;
}
static int imx_iim_fuse_blow_one(struct iim_bank *bank, unsigned int row, u8 value)
@@ -198,11 +197,10 @@ out:
return ret;
}
-static int imx_iim_fuse_blow(struct iim_bank *bank, unsigned offset, const void *buf,
- unsigned size)
+static int imx_iim_fuse_blow(struct iim_bank *bank, unsigned offset, unsigned val)
{
struct iim_priv *iim = bank->iim;
- int ret, i;
+ int ret;
if (IS_ERR(iim->fuse_supply)) {
iim->fuse_supply = regulator_get(iim->dev.parent, "vdd-fuse");
@@ -218,11 +216,9 @@ static int imx_iim_fuse_blow(struct iim_bank *bank, unsigned offset, const void
if (iim->supply)
iim->supply(1);
- for (i = 0; i < size; i++) {
- ret = imx_iim_fuse_blow_one(bank, offset + i, ((u8 *)buf)[i]);
- if (ret < 0)
- goto err_out;
- }
+ ret = imx_iim_fuse_blow_one(bank, offset, val);
+ if (ret < 0)
+ goto err_out;
if (iim->supply)
iim->supply(0);
@@ -235,52 +231,60 @@ err_out:
return ret;
}
-static ssize_t imx_iim_cdev_write(struct cdev *cdev, const void *buf, size_t count,
- loff_t offset, ulong flags)
+static ssize_t imx_iim_reg_write(void *ctx, unsigned int reg, unsigned int val)
{
- ulong size, i;
- struct iim_bank *bank = container_of(cdev, struct iim_bank, cdev);
+ struct iim_bank *bank = ctx;
- size = min((loff_t)count, 32 - offset);
-
- if (IS_ENABLED(CONFIG_IMX_IIM_FUSE_BLOW) && bank->iim->write_enable) {
- return imx_iim_fuse_blow(bank, offset, buf, size);
- } else {
- for (i = 0; i < size; i++)
- ((u8 *)bank->bankbase)[(offset+i)*4] = ((u8 *)buf)[i];
- }
+ if (IS_ENABLED(CONFIG_IMX_IIM_FUSE_BLOW) && bank->iim->write_enable)
+ return imx_iim_fuse_blow(bank, reg, val);
+ else
+ writel(val, bank->bankbase + reg * 4);
- return size;
+ return 0;
}
-static struct file_operations imx_iim_ops = {
- .read = imx_iim_cdev_read,
- .write = imx_iim_cdev_write,
- .lseek = dev_lseek_default,
+static struct regmap_bus imx_iim_regmap_bus = {
+ .reg_write = imx_iim_reg_write,
+ .reg_read = imx_iim_reg_read,
};
static int imx_iim_add_bank(struct iim_priv *iim, int num)
{
struct iim_bank *bank;
- struct cdev *cdev;
+ char *name;
+ int ret;
bank = xzalloc(sizeof (*bank));
bank->bankbase = iim->base + 0x800 + 0x400 * num;
bank->bank = num;
bank->iim = iim;
- cdev = &bank->cdev;
- cdev->ops = &imx_iim_ops;
- cdev->size = 32;
- cdev->name = asprintf(DRIVERNAME "_bank%d", num);
- if (cdev->name == NULL)
- return -ENOMEM;
iim->bank[num] = bank;
- return devfs_create(cdev);
+ bank->map_config.reg_bits = 8,
+ bank->map_config.val_bits = 8,
+ bank->map_config.reg_stride = 1,
+ bank->map_config.max_register = 31,
+ bank->map_config.name = xasprintf("bank%d", num);
+
+ bank->map = regmap_init(&iim->dev, &imx_iim_regmap_bus, bank, &bank->map_config);
+ if (IS_ERR(bank->map))
+ return PTR_ERR(bank->map);
+
+ name = xasprintf(DRIVERNAME "_bank%d", num);
+
+ ret = regmap_register_cdev(bank->map, name);
+
+ free(name);
+
+ if (ret)
+ return ret;
+
+ return 0;
}
+
#if IS_ENABLED(CONFIG_OFDEVICE)
#define MAC_BYTES 6
@@ -297,7 +301,7 @@ static int imx_iim_get_mac(struct param_d *param, void *priv)
struct iim_bank *bank = iimmac->bank;
int ret;
- ret = imx_iim_cdev_read(&bank->cdev, iimmac->ethaddr, MAC_BYTES, iimmac->offset, 0);
+ ret = regmap_bulk_read(bank->map, iimmac->offset, iimmac->ethaddr, MAC_BYTES);
if (ret < 0)
return ret;
@@ -310,7 +314,7 @@ static int imx_iim_set_mac(struct param_d *param, void *priv)
struct iim_bank *bank = iimmac->bank;
int ret;
- ret = imx_iim_cdev_write(&bank->cdev, iimmac->ethaddr, MAC_BYTES, iimmac->offset, 0);
+ ret = regmap_bulk_write(bank->map, iimmac->offset, iimmac->ethaddr, MAC_BYTES);
if (ret < 0)
return ret;
@@ -364,12 +368,11 @@ static void imx_iim_init_dt(struct device_d *dev, struct iim_priv *iim)
bank = be32_to_cpup(prop++);
offset = be32_to_cpup(prop++);
- ret = imx_iim_read(bank, offset, mac, 6);
- if (ret == 6) {
- of_eth_register_ethaddr(rnode, mac);
- } else {
+ ret = regmap_bulk_read(iim->bank[bank]->map, offset, mac, MAC_BYTES);
+ if (ret)
dev_err(dev, "cannot read: %s\n", strerror(-ret));
- }
+ else
+ of_eth_register_ethaddr(rnode, mac);
if (IS_ENABLED(CONFIG_NET))
imx_iim_add_mac_param(iim, macnum, bank, offset);