12ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown/* 22ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * Register cache access API - flat caching support 32ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * 42ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * Copyright 2012 Wolfson Microelectronics plc 52ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * 62ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 72ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * 82ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * This program is free software; you can redistribute it and/or modify 92ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * it under the terms of the GNU General Public License version 2 as 102ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown * published by the Free Software Foundation. 112ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown */ 122ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 132ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown#include <linux/slab.h> 142ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown#include <linux/device.h> 152ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown#include <linux/seq_file.h> 162ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 172ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown#include "internal.h" 182ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 192ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brownstatic int regcache_flat_init(struct regmap *map) 202ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown{ 212ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown int i; 222ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown unsigned int *cache; 232ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 242ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown map->cache = kzalloc(sizeof(unsigned int) * (map->max_register + 1), 252ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown GFP_KERNEL); 262ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown if (!map->cache) 272ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown return -ENOMEM; 282ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 292ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown cache = map->cache; 302ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 312ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown for (i = 0; i < map->num_reg_defaults; i++) 322ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown cache[map->reg_defaults[i].reg] = map->reg_defaults[i].def; 332ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 342ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown return 0; 352ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown} 362ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 372ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brownstatic int regcache_flat_exit(struct regmap *map) 382ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown{ 392ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown kfree(map->cache); 402ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown map->cache = NULL; 412ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 422ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown return 0; 432ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown} 442ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 452ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brownstatic int regcache_flat_read(struct regmap *map, 462ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown unsigned int reg, unsigned int *value) 472ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown{ 482ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown unsigned int *cache = map->cache; 492ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 502ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown *value = cache[reg]; 512ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 522ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown return 0; 532ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown} 542ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 552ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brownstatic int regcache_flat_write(struct regmap *map, unsigned int reg, 562ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown unsigned int value) 572ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown{ 582ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown unsigned int *cache = map->cache; 592ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 602ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown cache[reg] = value; 612ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 622ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown return 0; 632ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown} 642ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown 652ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brownstruct regcache_ops regcache_flat_ops = { 662ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown .type = REGCACHE_FLAT, 672ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown .name = "flat", 682ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown .init = regcache_flat_init, 692ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown .exit = regcache_flat_exit, 702ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown .read = regcache_flat_read, 712ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown .write = regcache_flat_write, 722ac902ce17f9dfa0d4d1f0818be147b5d2515fb7Mark Brown}; 73