Loading drivers/base/regmap/regmap-mmio.c +88 −52 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ struct regmap_mmio_context { void __iomem *regs; unsigned int val_bytes; bool relaxed_mmio; bool attached_clk; struct clk *clk; Loading @@ -33,9 +32,6 @@ static int regmap_mmio_regbits_check(size_t reg_bits) case 8: case 16: case 32: #ifdef CONFIG_64BIT case 64: #endif return 0; default: return -EINVAL; Loading @@ -57,11 +53,6 @@ static int regmap_mmio_get_min_stride(size_t val_bits) case 32: min_stride = 4; break; #ifdef CONFIG_64BIT case 64: min_stride = 8; break; #endif default: return -EINVAL; } Loading @@ -83,6 +74,12 @@ static void regmap_mmio_write8_relaxed(struct regmap_mmio_context *ctx, writeb_relaxed(val, ctx->regs + reg); } static void regmap_mmio_iowrite8(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite8(val, ctx->regs + reg); } static void regmap_mmio_write16le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) Loading @@ -97,9 +94,21 @@ static void regmap_mmio_write16le_relaxed(struct regmap_mmio_context *ctx, writew_relaxed(val, ctx->regs + reg); } static void regmap_mmio_iowrite16le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite16(val, ctx->regs + reg); } static void regmap_mmio_write16be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writew(swab16(val), ctx->regs + reg); } static void regmap_mmio_iowrite16be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite16be(val, ctx->regs + reg); } Loading @@ -118,28 +127,24 @@ static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx, writel_relaxed(val, ctx->regs + reg); } static void regmap_mmio_write32be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) static void regmap_mmio_iowrite32le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite32be(val, ctx->regs + reg); iowrite32(val, ctx->regs + reg); } #ifdef CONFIG_64BIT static void regmap_mmio_write64le(struct regmap_mmio_context *ctx, static void regmap_mmio_write32be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writeq(val, ctx->regs + reg); writel(swab32(val), ctx->regs + reg); } static void regmap_mmio_write64le_relaxed(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) static void regmap_mmio_iowrite32be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writeq_relaxed(val, ctx->regs + reg); iowrite32be(val, ctx->regs + reg); } #endif static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val) { Loading Loading @@ -172,6 +177,12 @@ static unsigned int regmap_mmio_read8_relaxed(struct regmap_mmio_context *ctx, return readb_relaxed(ctx->regs + reg); } static unsigned int regmap_mmio_ioread8(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread8(ctx->regs + reg); } static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx, unsigned int reg) { Loading @@ -184,8 +195,20 @@ static unsigned int regmap_mmio_read16le_relaxed(struct regmap_mmio_context *ctx return readw_relaxed(ctx->regs + reg); } static unsigned int regmap_mmio_ioread16le(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread16(ctx->regs + reg); } static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx, unsigned int reg) { return swab16(readw(ctx->regs + reg)); } static unsigned int regmap_mmio_ioread16be(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread16be(ctx->regs + reg); } Loading @@ -202,25 +225,23 @@ static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx return readl_relaxed(ctx->regs + reg); } static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_ioread32le(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread32be(ctx->regs + reg); return ioread32(ctx->regs + reg); } #ifdef CONFIG_64BIT static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx, unsigned int reg) { return readq(ctx->regs + reg); return swab32(readl(ctx->regs + reg)); } static unsigned int regmap_mmio_read64le_relaxed(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_ioread32be(struct regmap_mmio_context *ctx, unsigned int reg) { return readq_relaxed(ctx->regs + reg); return ioread32be(ctx->regs + reg); } #endif static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val) { Loading Loading @@ -284,13 +305,15 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, if (config->reg_stride < min_stride) return ERR_PTR(-EINVAL); if (config->use_relaxed_mmio && config->io_port) return ERR_PTR(-EINVAL); ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return ERR_PTR(-ENOMEM); ctx->regs = regs; ctx->val_bytes = config->val_bits / 8; ctx->relaxed_mmio = config->use_relaxed_mmio; ctx->clk = ERR_PTR(-ENODEV); switch (regmap_get_val_endian(dev, ®map_mmio, config)) { Loading @@ -301,7 +324,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, #endif switch (config->val_bits) { case 8: if (ctx->relaxed_mmio) { if (config->io_port) { ctx->reg_read = regmap_mmio_ioread8; ctx->reg_write = regmap_mmio_iowrite8; } else if (config->use_relaxed_mmio) { ctx->reg_read = regmap_mmio_read8_relaxed; ctx->reg_write = regmap_mmio_write8_relaxed; } else { Loading @@ -310,7 +336,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, } break; case 16: if (ctx->relaxed_mmio) { if (config->io_port) { ctx->reg_read = regmap_mmio_ioread16le; ctx->reg_write = regmap_mmio_iowrite16le; } else if (config->use_relaxed_mmio) { ctx->reg_read = regmap_mmio_read16le_relaxed; ctx->reg_write = regmap_mmio_write16le_relaxed; } else { Loading @@ -319,7 +348,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, } break; case 32: if (ctx->relaxed_mmio) { if (config->io_port) { ctx->reg_read = regmap_mmio_ioread32le; ctx->reg_write = regmap_mmio_iowrite32le; } else if (config->use_relaxed_mmio) { ctx->reg_read = regmap_mmio_read32le_relaxed; ctx->reg_write = regmap_mmio_write32le_relaxed; } else { Loading @@ -327,17 +359,6 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, ctx->reg_write = regmap_mmio_write32le; } break; #ifdef CONFIG_64BIT case 64: if (ctx->relaxed_mmio) { ctx->reg_read = regmap_mmio_read64le_relaxed; ctx->reg_write = regmap_mmio_write64le_relaxed; } else { ctx->reg_read = regmap_mmio_read64le; ctx->reg_write = regmap_mmio_write64le; } break; #endif default: ret = -EINVAL; goto err_free; Loading @@ -349,16 +370,31 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, #endif switch (config->val_bits) { case 8: if (config->io_port) { ctx->reg_read = regmap_mmio_ioread8; ctx->reg_write = regmap_mmio_iowrite8; } else { ctx->reg_read = regmap_mmio_read8; ctx->reg_write = regmap_mmio_write8; } break; case 16: if (config->io_port) { ctx->reg_read = regmap_mmio_ioread16be; ctx->reg_write = regmap_mmio_iowrite16be; } else { ctx->reg_read = regmap_mmio_read16be; ctx->reg_write = regmap_mmio_write16be; } break; case 32: if (config->io_port) { ctx->reg_read = regmap_mmio_ioread32be; ctx->reg_write = regmap_mmio_iowrite32be; } else { ctx->reg_read = regmap_mmio_read32be; ctx->reg_write = regmap_mmio_write32be; } break; default: ret = -EINVAL; Loading include/linux/regmap.h +3 −0 Original line number Diff line number Diff line Loading @@ -311,6 +311,8 @@ typedef void (*regmap_unlock)(void *); * This field is a duplicate of a similar file in * 'struct regmap_bus' and serves exact same purpose. * Use it only for "no-bus" cases. * @io_port: Support IO port accessors. Makes sense only when MMIO vs. IO port * access can be distinguished. * @max_register: Optional, specifies the maximum valid register address. * @wr_table: Optional, points to a struct regmap_access_table specifying * valid ranges for write access. Loading Loading @@ -399,6 +401,7 @@ struct regmap_config { size_t max_raw_write; bool fast_io; bool io_port; unsigned int max_register; const struct regmap_access_table *wr_table; Loading Loading
drivers/base/regmap/regmap-mmio.c +88 −52 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ struct regmap_mmio_context { void __iomem *regs; unsigned int val_bytes; bool relaxed_mmio; bool attached_clk; struct clk *clk; Loading @@ -33,9 +32,6 @@ static int regmap_mmio_regbits_check(size_t reg_bits) case 8: case 16: case 32: #ifdef CONFIG_64BIT case 64: #endif return 0; default: return -EINVAL; Loading @@ -57,11 +53,6 @@ static int regmap_mmio_get_min_stride(size_t val_bits) case 32: min_stride = 4; break; #ifdef CONFIG_64BIT case 64: min_stride = 8; break; #endif default: return -EINVAL; } Loading @@ -83,6 +74,12 @@ static void regmap_mmio_write8_relaxed(struct regmap_mmio_context *ctx, writeb_relaxed(val, ctx->regs + reg); } static void regmap_mmio_iowrite8(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite8(val, ctx->regs + reg); } static void regmap_mmio_write16le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) Loading @@ -97,9 +94,21 @@ static void regmap_mmio_write16le_relaxed(struct regmap_mmio_context *ctx, writew_relaxed(val, ctx->regs + reg); } static void regmap_mmio_iowrite16le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite16(val, ctx->regs + reg); } static void regmap_mmio_write16be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writew(swab16(val), ctx->regs + reg); } static void regmap_mmio_iowrite16be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite16be(val, ctx->regs + reg); } Loading @@ -118,28 +127,24 @@ static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx, writel_relaxed(val, ctx->regs + reg); } static void regmap_mmio_write32be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) static void regmap_mmio_iowrite32le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { iowrite32be(val, ctx->regs + reg); iowrite32(val, ctx->regs + reg); } #ifdef CONFIG_64BIT static void regmap_mmio_write64le(struct regmap_mmio_context *ctx, static void regmap_mmio_write32be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writeq(val, ctx->regs + reg); writel(swab32(val), ctx->regs + reg); } static void regmap_mmio_write64le_relaxed(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) static void regmap_mmio_iowrite32be(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writeq_relaxed(val, ctx->regs + reg); iowrite32be(val, ctx->regs + reg); } #endif static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val) { Loading Loading @@ -172,6 +177,12 @@ static unsigned int regmap_mmio_read8_relaxed(struct regmap_mmio_context *ctx, return readb_relaxed(ctx->regs + reg); } static unsigned int regmap_mmio_ioread8(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread8(ctx->regs + reg); } static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx, unsigned int reg) { Loading @@ -184,8 +195,20 @@ static unsigned int regmap_mmio_read16le_relaxed(struct regmap_mmio_context *ctx return readw_relaxed(ctx->regs + reg); } static unsigned int regmap_mmio_ioread16le(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread16(ctx->regs + reg); } static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx, unsigned int reg) { return swab16(readw(ctx->regs + reg)); } static unsigned int regmap_mmio_ioread16be(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread16be(ctx->regs + reg); } Loading @@ -202,25 +225,23 @@ static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx return readl_relaxed(ctx->regs + reg); } static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_ioread32le(struct regmap_mmio_context *ctx, unsigned int reg) { return ioread32be(ctx->regs + reg); return ioread32(ctx->regs + reg); } #ifdef CONFIG_64BIT static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx, unsigned int reg) { return readq(ctx->regs + reg); return swab32(readl(ctx->regs + reg)); } static unsigned int regmap_mmio_read64le_relaxed(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_ioread32be(struct regmap_mmio_context *ctx, unsigned int reg) { return readq_relaxed(ctx->regs + reg); return ioread32be(ctx->regs + reg); } #endif static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val) { Loading Loading @@ -284,13 +305,15 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, if (config->reg_stride < min_stride) return ERR_PTR(-EINVAL); if (config->use_relaxed_mmio && config->io_port) return ERR_PTR(-EINVAL); ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) return ERR_PTR(-ENOMEM); ctx->regs = regs; ctx->val_bytes = config->val_bits / 8; ctx->relaxed_mmio = config->use_relaxed_mmio; ctx->clk = ERR_PTR(-ENODEV); switch (regmap_get_val_endian(dev, ®map_mmio, config)) { Loading @@ -301,7 +324,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, #endif switch (config->val_bits) { case 8: if (ctx->relaxed_mmio) { if (config->io_port) { ctx->reg_read = regmap_mmio_ioread8; ctx->reg_write = regmap_mmio_iowrite8; } else if (config->use_relaxed_mmio) { ctx->reg_read = regmap_mmio_read8_relaxed; ctx->reg_write = regmap_mmio_write8_relaxed; } else { Loading @@ -310,7 +336,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, } break; case 16: if (ctx->relaxed_mmio) { if (config->io_port) { ctx->reg_read = regmap_mmio_ioread16le; ctx->reg_write = regmap_mmio_iowrite16le; } else if (config->use_relaxed_mmio) { ctx->reg_read = regmap_mmio_read16le_relaxed; ctx->reg_write = regmap_mmio_write16le_relaxed; } else { Loading @@ -319,7 +348,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, } break; case 32: if (ctx->relaxed_mmio) { if (config->io_port) { ctx->reg_read = regmap_mmio_ioread32le; ctx->reg_write = regmap_mmio_iowrite32le; } else if (config->use_relaxed_mmio) { ctx->reg_read = regmap_mmio_read32le_relaxed; ctx->reg_write = regmap_mmio_write32le_relaxed; } else { Loading @@ -327,17 +359,6 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, ctx->reg_write = regmap_mmio_write32le; } break; #ifdef CONFIG_64BIT case 64: if (ctx->relaxed_mmio) { ctx->reg_read = regmap_mmio_read64le_relaxed; ctx->reg_write = regmap_mmio_write64le_relaxed; } else { ctx->reg_read = regmap_mmio_read64le; ctx->reg_write = regmap_mmio_write64le; } break; #endif default: ret = -EINVAL; goto err_free; Loading @@ -349,16 +370,31 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, #endif switch (config->val_bits) { case 8: if (config->io_port) { ctx->reg_read = regmap_mmio_ioread8; ctx->reg_write = regmap_mmio_iowrite8; } else { ctx->reg_read = regmap_mmio_read8; ctx->reg_write = regmap_mmio_write8; } break; case 16: if (config->io_port) { ctx->reg_read = regmap_mmio_ioread16be; ctx->reg_write = regmap_mmio_iowrite16be; } else { ctx->reg_read = regmap_mmio_read16be; ctx->reg_write = regmap_mmio_write16be; } break; case 32: if (config->io_port) { ctx->reg_read = regmap_mmio_ioread32be; ctx->reg_write = regmap_mmio_iowrite32be; } else { ctx->reg_read = regmap_mmio_read32be; ctx->reg_write = regmap_mmio_write32be; } break; default: ret = -EINVAL; Loading
include/linux/regmap.h +3 −0 Original line number Diff line number Diff line Loading @@ -311,6 +311,8 @@ typedef void (*regmap_unlock)(void *); * This field is a duplicate of a similar file in * 'struct regmap_bus' and serves exact same purpose. * Use it only for "no-bus" cases. * @io_port: Support IO port accessors. Makes sense only when MMIO vs. IO port * access can be distinguished. * @max_register: Optional, specifies the maximum valid register address. * @wr_table: Optional, points to a struct regmap_access_table specifying * valid ranges for write access. Loading Loading @@ -399,6 +401,7 @@ struct regmap_config { size_t max_raw_write; bool fast_io; bool io_port; unsigned int max_register; const struct regmap_access_table *wr_table; Loading