cregit-Linux how code gets into the kernel

Release 4.11 drivers/base/regmap/regmap-mmio.c

/*
 * Register map access API - MMIO support
 *
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include "internal.h"


struct regmap_mmio_context {
	
void __iomem *regs;
	
unsigned val_bytes;
	
struct clk *clk;

	
void (*reg_write)(struct regmap_mmio_context *ctx,
			  unsigned int reg, unsigned int val);
	
unsigned int (*reg_read)(struct regmap_mmio_context *ctx,
			         unsigned int reg);
};


static int regmap_mmio_regbits_check(size_t reg_bits) { switch (reg_bits) { case 8: case 16: case 32: #ifdef CONFIG_64BIT case 64: #endif return 0; default: return -EINVAL; } }

Contributors

PersonTokensPropCommitsCommitProp
Xiubo Li40100.00%1100.00%
Total40100.00%1100.00%


static int regmap_mmio_get_min_stride(size_t val_bits) { int min_stride; switch (val_bits) { case 8: /* The core treats 0 as 1 */ min_stride = 0; return 0; case 16: min_stride = 2; break; case 32: min_stride = 4; break; #ifdef CONFIG_64BIT case 64: min_stride = 8; break; #endif default: return -EINVAL; } return min_stride; }

Contributors

PersonTokensPropCommitsCommitProp
Xiubo Li66100.00%1100.00%
Total66100.00%1100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown2066.67%133.33%
Xiubo Li930.00%133.33%
Philipp Zabel13.33%133.33%
Total30100.00%3100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown2066.67%150.00%
Xiubo Li1033.33%150.00%
Total30100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown1446.67%125.00%
Stephen Warren826.67%125.00%
Philipp Zabel516.67%125.00%
Xiubo Li310.00%125.00%
Total30100.00%4100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown1963.33%150.00%
Stephen Warren1136.67%150.00%
Total30100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown2066.67%150.00%
Stephen Warren1033.33%150.00%
Total30100.00%2100.00%

#ifdef CONFIG_64BIT
static void regmap_mmio_write64le(struct regmap_mmio_context *ctx, unsigned int reg, unsigned int val) { writeq(val, ctx->regs + reg); }

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown2170.00%150.00%
Stephen Warren930.00%150.00%
Total30100.00%2100.00%

#endif
static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val) { struct regmap_mmio_context *ctx = context; int ret; if (!IS_ERR(ctx->clk)) { ret = clk_enable(ctx->clk); if (ret < 0) return ret; } ctx->reg_write(ctx, reg, val); if (!IS_ERR(ctx->clk)) clk_disable(ctx->clk); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown6067.42%125.00%
Stephen Warren1617.98%250.00%
Philipp Zabel1314.61%125.00%
Total89100.00%4100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown934.62%125.00%
Stephen Warren934.62%125.00%
Xiubo Li830.77%250.00%
Total26100.00%4100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown1869.23%150.00%
Stephen Warren830.77%150.00%
Total26100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown1661.54%120.00%
Stephen Warren623.08%240.00%
Philipp Zabel27.69%120.00%
Xiubo Li27.69%120.00%
Total26100.00%5100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown1973.08%150.00%
Philipp Zabel726.92%150.00%
Total26100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown1869.23%150.00%
Stephen Warren830.77%150.00%
Total26100.00%2100.00%

#ifdef CONFIG_64BIT
static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx, unsigned int reg) { return readq(ctx->regs + reg); }

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown2076.92%150.00%
Stephen Warren623.08%150.00%
Total26100.00%2100.00%

#endif
static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val) { struct regmap_mmio_context *ctx = context; int ret; if (!IS_ERR(ctx->clk)) { ret = clk_enable(ctx->clk); if (ret < 0) return ret; } *val = ctx->reg_read(ctx, reg); if (!IS_ERR(ctx->clk)) clk_disable(ctx->clk); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown5358.24%125.00%
Stephen Warren2527.47%250.00%
Philipp Zabel1314.29%125.00%
Total91100.00%4100.00%


static void regmap_mmio_free_context(void *context) { struct regmap_mmio_context *ctx = context; if (!IS_ERR(ctx->clk)) { clk_unprepare(ctx->clk); clk_put(ctx->clk); } kfree(context); }

Contributors

PersonTokensPropCommitsCommitProp
Philipp Zabel2960.42%133.33%
Stephen Warren1939.58%266.67%
Total48100.00%3100.00%

static const struct regmap_bus regmap_mmio = { .fast_io = true, .reg_write = regmap_mmio_write, .reg_read = regmap_mmio_read, .free_context = regmap_mmio_free_context, .val_format_endian_default = REGMAP_ENDIAN_LITTLE, };
static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, const char *clk_id, void __iomem *regs, const struct regmap_config *config) { struct regmap_mmio_context *ctx; int min_stride; int ret; ret = regmap_mmio_regbits_check(config->reg_bits); if (ret) return ERR_PTR(ret); if (config->pad_bits) return ERR_PTR(-EINVAL); min_stride = regmap_mmio_get_min_stride(config->val_bits); if (min_stride < 0) return ERR_PTR(min_stride); if (config->reg_stride < min_stride) 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->clk = ERR_PTR(-ENODEV); switch (regmap_get_val_endian(dev, &regmap_mmio, config)) { case REGMAP_ENDIAN_DEFAULT: case REGMAP_ENDIAN_LITTLE: #ifdef __LITTLE_ENDIAN case REGMAP_ENDIAN_NATIVE: #endif switch (config->val_bits) { case 8: ctx->reg_read = regmap_mmio_read8; ctx->reg_write = regmap_mmio_write8; break; case 16: ctx->reg_read = regmap_mmio_read16le; ctx->reg_write = regmap_mmio_write16le; break; case 32: ctx->reg_read = regmap_mmio_read32le; ctx->reg_write = regmap_mmio_write32le; break; #ifdef CONFIG_64BIT case 64: ctx->reg_read = regmap_mmio_read64le; ctx->reg_write = regmap_mmio_write64le; break; #endif default: ret = -EINVAL; goto err_free; } break; case REGMAP_ENDIAN_BIG: #ifdef __BIG_ENDIAN case REGMAP_ENDIAN_NATIVE: #endif switch (config->val_bits) { case 8: ctx->reg_read = regmap_mmio_read8; ctx->reg_write = regmap_mmio_write8; break; case 16: ctx->reg_read = regmap_mmio_read16be; ctx->reg_write = regmap_mmio_write16be; break; case 32: ctx->reg_read = regmap_mmio_read32be; ctx->reg_write = regmap_mmio_write32be; break; default: ret = -EINVAL; goto err_free; } break; default: ret = -EINVAL; goto err_free; } if (clk_id == NULL) return ctx; ctx->clk = clk_get(dev, clk_id); if (IS_ERR(ctx->clk)) { ret = PTR_ERR(ctx->clk); goto err_free; } ret = clk_prepare(ctx->clk); if (ret < 0) { clk_put(ctx->clk); goto err_free; } return ctx; err_free: kfree(ctx); return ERR_PTR(ret); }

Contributors

PersonTokensPropCommitsCommitProp
Mark Brown19343.27%218.18%
Stephen Warren12026.91%327.27%
Philipp Zabel9621.52%19.09%
Xiubo Li347.62%327.27%
Dimitris Papastamos20.45%19.09%
Axel Lin10.22%19.09%
Total446100.00%11100.00%


struct regmap *__regmap_init_mmio_clk(struct device *dev, const char *clk_id, void __iomem *regs, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { struct regmap_mmio_context *ctx; ctx = regmap_mmio_gen_context(dev, clk_id, regs, config); if (IS_ERR(ctx)) return ERR_CAST(ctx); return __regmap_init(dev, &regmap_mmio, ctx, config, lock_key, lock_name); }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Warren6170.93%133.33%
Nicolas Boichat1618.60%133.33%
Philipp Zabel910.47%133.33%
Total86100.00%3100.00%

EXPORT_SYMBOL_GPL(__regmap_init_mmio_clk);
struct regmap *__devm_regmap_init_mmio_clk(struct device *dev, const char *clk_id, void __iomem *regs, const struct regmap_config *config, struct lock_class_key *lock_key, const char *lock_name) { struct regmap_mmio_context *ctx; ctx = regmap_mmio_gen_context(dev, clk_id, regs, config); if (IS_ERR(ctx)) return ERR_CAST(ctx); return __devm_regmap_init(dev, &regmap_mmio, ctx, config, lock_key, lock_name); }

Contributors

PersonTokensPropCommitsCommitProp
Stephen Warren6170.93%133.33%
Nicolas Boichat1618.60%133.33%
Philipp Zabel910.47%133.33%
Total86100.00%3100.00%

EXPORT_SYMBOL_GPL(__devm_regmap_init_mmio_clk); MODULE_LICENSE("GPL v2");

Overall Contributors

PersonTokensPropCommitsCommitProp
Mark Brown57140.13%318.75%
Stephen Warren44731.41%318.75%
Philipp Zabel19213.49%212.50%
Xiubo Li17612.37%531.25%
Nicolas Boichat342.39%16.25%
Dimitris Papastamos20.14%16.25%
Axel Lin10.07%16.25%
Total1423100.00%16100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.