Unverified Commit 93ce5576 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Mark Brown
Browse files

regmap: mmio: Introduce IO accessors that can talk to IO port



Some users may use regmap MMIO for IO ports, and this can be done
by assigning ioreadXX()/iowriteXX() and their Big Endian counterparts
to the regmap context.

Add IO port support with a corresponding flag added.

While doing that, make sure that user won't select relaxed MMIO access
along with IO port because the latter have no relaxed variants.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: default avatarWilliam Breathitt Gray <william.gray@linaro.org>
Link: https://lore.kernel.org/r/20220808203401.35153-4-andriy.shevchenko@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 159dfabd
Loading
Loading
Loading
Loading
+96 −9
Original line number Diff line number Diff line
@@ -74,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)
@@ -88,6 +94,12 @@ 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)
@@ -95,6 +107,12 @@ static void regmap_mmio_write16be(struct regmap_mmio_context *ctx,
	iowrite16be(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);
}

static void regmap_mmio_write32le(struct regmap_mmio_context *ctx,
				  unsigned int reg,
				  unsigned int val)
@@ -109,6 +127,12 @@ static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx,
	writel_relaxed(val, ctx->regs + reg);
}

static void regmap_mmio_iowrite32le(struct regmap_mmio_context *ctx,
				    unsigned int reg, unsigned int val)
{
	iowrite32(val, ctx->regs + reg);
}

static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
				  unsigned int reg,
				  unsigned int val)
@@ -116,6 +140,12 @@ static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
	iowrite32be(val, ctx->regs + reg);
}

static void regmap_mmio_iowrite32be(struct regmap_mmio_context *ctx,
				    unsigned int reg, unsigned int val)
{
	iowrite32be(val, ctx->regs + reg);
}

static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
{
	struct regmap_mmio_context *ctx = context;
@@ -147,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)
{
@@ -159,12 +195,24 @@ 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 ioread16be(ctx->regs + reg);
}

static unsigned int regmap_mmio_ioread16be(struct regmap_mmio_context *ctx,
					   unsigned int reg)
{
	return ioread16be(ctx->regs + reg);
}

static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx,
				         unsigned int reg)
{
@@ -177,12 +225,24 @@ static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx
	return readl_relaxed(ctx->regs + reg);
}

static unsigned int regmap_mmio_ioread32le(struct regmap_mmio_context *ctx,
					   unsigned int reg)
{
	return ioread32(ctx->regs + reg);
}

static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
				         unsigned int reg)
{
	return ioread32be(ctx->regs + reg);
}

static unsigned int regmap_mmio_ioread32be(struct regmap_mmio_context *ctx,
					   unsigned int reg)
{
	return ioread32be(ctx->regs + reg);
}

static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
{
	struct regmap_mmio_context *ctx = context;
@@ -245,6 +305,9 @@ 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);
@@ -261,7 +324,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
#endif
		switch (config->val_bits) {
		case 8:
			if (config->use_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 {
@@ -270,7 +336,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
			}
			break;
		case 16:
			if (config->use_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 {
@@ -279,7 +348,10 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
			}
			break;
		case 32:
			if (config->use_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 {
@@ -298,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;
+3 −0
Original line number Diff line number Diff line
@@ -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.
@@ -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;