linux-4.4.1/_regmap_raw_write()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#yf831632]
#backlinks
*説明 [#t7f628f2]
-パス: [[linux-4.4.1/drivers/base/regmap/regmap.c]]
-FIXME: これは何?
--説明
**引数 [#ud2689cd]
-struct regmap *map
--
--[[linux-4.4.1/regmap]]
-unsigned int reg
--
-const void *val
--
-size_t val_len
--
**返り値 [#ncf98cf3]
-int
--
**参考 [#qb798f22]
*実装 [#eec8c2db]
int _regmap_raw_write(struct regmap *map, unsigned int r...
const void *val, size_t val_len)
{
struct regmap_range_node *range;
unsigned long flags;
u8 *u8 = map->work_buf;
void *work_val = map->work_buf + map->format.reg_bytes +
map->format.pad_bytes;
void *buf;
int ret = -ENOTSUPP;
size_t len;
int i;
-
--[[linux-4.4.1/regmap_range_node]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
WARN_ON(!map->bus);
-
--[[linux-4.4.1/WARN_ON()]]
/* Check for unwritable registers before we start */
if (map->writeable_reg)
for (i = 0; i < val_len / map->format.val_bytes; i++)
if (!map->writeable_reg(map->dev,
reg + (i * map->reg_stride)))
return -EINVAL;
if (!map->cache_bypass && map->format.parse_val) {
unsigned int ival;
int val_bytes = map->format.val_bytes;
for (i = 0; i < val_len / val_bytes; i++) {
ival = map->format.parse_val(val + (i * val_bytes));
ret = regcache_write(map, reg + (i * map->reg_stride),
ival);
if (ret) {
dev_err(map->dev,
"Error in caching of register: %x ret: %d\n",
reg + i, ret);
return ret;
}
-
--[[linux-4.4.1/regcache_write()]]
--[[linux-4.4.1/dev_err()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
}
if (map->cache_only) {
map->cache_dirty = true;
return 0;
}
}
range = _regmap_range_lookup(map, reg);
-
--[[linux-4.4.1/_regmap_range_lookup()]]
if (range) {
int val_num = val_len / map->format.val_bytes;
int win_offset = (reg - range->range_min) % range->win...
int win_residue = range->window_len - win_offset;
/* If the write goes beyond the end of the window spli...
while (val_num > win_residue) {
dev_dbg(map->dev, "Writing window %d/%zu\n",
win_residue, val_len / map->format.val_bytes);
ret = _regmap_raw_write(map, reg, val, win_residue *
map->format.val_bytes);
if (ret != 0)
return ret;
-
--[[linux-4.4.1/dev_dbg()]]
--[[linux-4.4.1/_regmap_raw_write()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
reg += win_residue;
val_num -= win_residue;
val += win_residue * map->format.val_bytes;
val_len -= win_residue * map->format.val_bytes;
win_offset = (reg - range->range_min) %
range->window_len;
win_residue = range->window_len - win_offset;
}
ret = _regmap_select_page(map, ®, range, val_num);
if (ret != 0)
return ret;
-
--[[linux-4.4.1/_regmap_select_page()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
}
map->format.format_reg(map->work_buf, reg, map->reg_shi...
u8[0] |= map->write_flag_mask;
/*
* Essentially all I/O mechanisms will be faster with a...
* buffer to write. Since register syncs often generat...
* writes of single registers optimise that case.
*/
if (val != work_val && val_len == map->format.val_bytes...
memcpy(work_val, val, map->format.val_bytes);
val = work_val;
}
-
--[[linux-4.4.1/memcpy()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
if (map->async && map->bus->async_write) {
struct regmap_async *async;
trace_regmap_async_write_start(map, reg, val_len);
spin_lock_irqsave(&map->async_lock, flags);
async = list_first_entry_or_null(&map->async_free,
struct regmap_async,
list);
if (async)
list_del(&async->list);
spin_unlock_irqrestore(&map->async_lock, flags);
-
--[[linux-4.4.1/regmap_async]]
--[[linux-4.4.1/trace_regmap_async_write_start()]]
--[[linux-4.4.1/spin_lock_irqsave()]]
--[[linux-4.4.1/list_first_entry_or_null()]]
--[[linux-4.4.1/list_del()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]
if (!async) {
async = map->bus->async_alloc();
if (!async)
return -ENOMEM;
async->work_buf = kzalloc(map->format.buf_size,
GFP_KERNEL | GFP_DMA);
if (!async->work_buf) {
kfree(async);
return -ENOMEM;
}
}
-
--map->bus は regmap_bus *型
--[[linux-4.4.1/regmap_bus]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
--[[linux-4.4.1/kzalloc()]]
--[[linux-4.4.1/kfree()]]
async->map = map;
/* If the caller supplied the value we can use it safe...
memcpy(async->work_buf, map->work_buf, map->format.pad...
map->format.reg_bytes + map->format.val_bytes);
-
--[[linux-4.4.1/memcpy()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
spin_lock_irqsave(&map->async_lock, flags);
list_add_tail(&async->list, &map->async_list);
spin_unlock_irqrestore(&map->async_lock, flags);
-
--[[linux-4.4.1/spin_lock_irqsave()]]
--[[linux-4.4.1/list_add_tail()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]
if (val != work_val)
ret = map->bus->async_write(map->bus_context,
async->work_buf,
map->format.reg_bytes +
map->format.pad_bytes,
val, val_len, async);
else
ret = map->bus->async_write(map->bus_context,
async->work_buf,
map->format.reg_bytes +
map->format.pad_bytes +
val_len, NULL, 0, async);
-
--map->bus は regmap_bus *型
--[[linux-4.4.1/regmap_bus]]
if (ret != 0) {
dev_err(map->dev, "Failed to schedule write: %d\n",
ret);
spin_lock_irqsave(&map->async_lock, flags);
list_move(&async->list, &map->async_free);
spin_unlock_irqrestore(&map->async_lock, flags);
}
-
--[[linux-4.4.1/spin_lock_irqsave()]]
--[[linux-4.4.1/list_move()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]
return ret;
}
trace_regmap_hw_write_start(map, reg, val_len / map->fo...
-
--[[linux-4.4.1/trace_regmap_hw_write_start()]]
/* If we're doing a single register write we can probab...
* send the work_buf directly, otherwise try to do a ga...
* write.
*/
if (val == work_val)
ret = map->bus->write(map->bus_context, map->work_buf,
map->format.reg_bytes +
map->format.pad_bytes +
val_len);
else if (map->bus->gather_write)
ret = map->bus->gather_write(map->bus_context, map->wo...
map->format.reg_bytes +
map->format.pad_bytes,
val, val_len);
-
--map->bus は regmap_bus *型
--[[linux-4.4.1/regmap_bus]]
/* If that didn't work fall back on linearising by hand...
if (ret == -ENOTSUPP) {
len = map->format.reg_bytes + map->format.pad_bytes + ...
buf = kzalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
memcpy(buf, map->work_buf, map->format.reg_bytes);
memcpy(buf + map->format.reg_bytes + map->format.pad_b...
val, val_len);
ret = map->bus->write(map->bus_context, buf, len);
kfree(buf);
-
--[[linux-4.4.1/kzalloc()]]
--[[linux-4.4.1/memcpy()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
--[[linux-4.4.1/kfree()]]
}
trace_regmap_hw_write_done(map, reg, val_len / map->for...
-
--[[linux-4.4.1/trace_regmap_hw_write_done()]]
return ret;
}
*コメント [#q899ac6c]
終了行:
*参照元 [#yf831632]
#backlinks
*説明 [#t7f628f2]
-パス: [[linux-4.4.1/drivers/base/regmap/regmap.c]]
-FIXME: これは何?
--説明
**引数 [#ud2689cd]
-struct regmap *map
--
--[[linux-4.4.1/regmap]]
-unsigned int reg
--
-const void *val
--
-size_t val_len
--
**返り値 [#ncf98cf3]
-int
--
**参考 [#qb798f22]
*実装 [#eec8c2db]
int _regmap_raw_write(struct regmap *map, unsigned int r...
const void *val, size_t val_len)
{
struct regmap_range_node *range;
unsigned long flags;
u8 *u8 = map->work_buf;
void *work_val = map->work_buf + map->format.reg_bytes +
map->format.pad_bytes;
void *buf;
int ret = -ENOTSUPP;
size_t len;
int i;
-
--[[linux-4.4.1/regmap_range_node]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
WARN_ON(!map->bus);
-
--[[linux-4.4.1/WARN_ON()]]
/* Check for unwritable registers before we start */
if (map->writeable_reg)
for (i = 0; i < val_len / map->format.val_bytes; i++)
if (!map->writeable_reg(map->dev,
reg + (i * map->reg_stride)))
return -EINVAL;
if (!map->cache_bypass && map->format.parse_val) {
unsigned int ival;
int val_bytes = map->format.val_bytes;
for (i = 0; i < val_len / val_bytes; i++) {
ival = map->format.parse_val(val + (i * val_bytes));
ret = regcache_write(map, reg + (i * map->reg_stride),
ival);
if (ret) {
dev_err(map->dev,
"Error in caching of register: %x ret: %d\n",
reg + i, ret);
return ret;
}
-
--[[linux-4.4.1/regcache_write()]]
--[[linux-4.4.1/dev_err()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
}
if (map->cache_only) {
map->cache_dirty = true;
return 0;
}
}
range = _regmap_range_lookup(map, reg);
-
--[[linux-4.4.1/_regmap_range_lookup()]]
if (range) {
int val_num = val_len / map->format.val_bytes;
int win_offset = (reg - range->range_min) % range->win...
int win_residue = range->window_len - win_offset;
/* If the write goes beyond the end of the window spli...
while (val_num > win_residue) {
dev_dbg(map->dev, "Writing window %d/%zu\n",
win_residue, val_len / map->format.val_bytes);
ret = _regmap_raw_write(map, reg, val, win_residue *
map->format.val_bytes);
if (ret != 0)
return ret;
-
--[[linux-4.4.1/dev_dbg()]]
--[[linux-4.4.1/_regmap_raw_write()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
reg += win_residue;
val_num -= win_residue;
val += win_residue * map->format.val_bytes;
val_len -= win_residue * map->format.val_bytes;
win_offset = (reg - range->range_min) %
range->window_len;
win_residue = range->window_len - win_offset;
}
ret = _regmap_select_page(map, ®, range, val_num);
if (ret != 0)
return ret;
-
--[[linux-4.4.1/_regmap_select_page()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
}
map->format.format_reg(map->work_buf, reg, map->reg_shi...
u8[0] |= map->write_flag_mask;
/*
* Essentially all I/O mechanisms will be faster with a...
* buffer to write. Since register syncs often generat...
* writes of single registers optimise that case.
*/
if (val != work_val && val_len == map->format.val_bytes...
memcpy(work_val, val, map->format.val_bytes);
val = work_val;
}
-
--[[linux-4.4.1/memcpy()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
if (map->async && map->bus->async_write) {
struct regmap_async *async;
trace_regmap_async_write_start(map, reg, val_len);
spin_lock_irqsave(&map->async_lock, flags);
async = list_first_entry_or_null(&map->async_free,
struct regmap_async,
list);
if (async)
list_del(&async->list);
spin_unlock_irqrestore(&map->async_lock, flags);
-
--[[linux-4.4.1/regmap_async]]
--[[linux-4.4.1/trace_regmap_async_write_start()]]
--[[linux-4.4.1/spin_lock_irqsave()]]
--[[linux-4.4.1/list_first_entry_or_null()]]
--[[linux-4.4.1/list_del()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]
if (!async) {
async = map->bus->async_alloc();
if (!async)
return -ENOMEM;
async->work_buf = kzalloc(map->format.buf_size,
GFP_KERNEL | GFP_DMA);
if (!async->work_buf) {
kfree(async);
return -ENOMEM;
}
}
-
--map->bus は regmap_bus *型
--[[linux-4.4.1/regmap_bus]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
--[[linux-4.4.1/kzalloc()]]
--[[linux-4.4.1/kfree()]]
async->map = map;
/* If the caller supplied the value we can use it safe...
memcpy(async->work_buf, map->work_buf, map->format.pad...
map->format.reg_bytes + map->format.val_bytes);
-
--[[linux-4.4.1/memcpy()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
spin_lock_irqsave(&map->async_lock, flags);
list_add_tail(&async->list, &map->async_list);
spin_unlock_irqrestore(&map->async_lock, flags);
-
--[[linux-4.4.1/spin_lock_irqsave()]]
--[[linux-4.4.1/list_add_tail()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]
if (val != work_val)
ret = map->bus->async_write(map->bus_context,
async->work_buf,
map->format.reg_bytes +
map->format.pad_bytes,
val, val_len, async);
else
ret = map->bus->async_write(map->bus_context,
async->work_buf,
map->format.reg_bytes +
map->format.pad_bytes +
val_len, NULL, 0, async);
-
--map->bus は regmap_bus *型
--[[linux-4.4.1/regmap_bus]]
if (ret != 0) {
dev_err(map->dev, "Failed to schedule write: %d\n",
ret);
spin_lock_irqsave(&map->async_lock, flags);
list_move(&async->list, &map->async_free);
spin_unlock_irqrestore(&map->async_lock, flags);
}
-
--[[linux-4.4.1/spin_lock_irqsave()]]
--[[linux-4.4.1/list_move()]]
--[[linux-4.4.1/spin_unlock_irqrestore()]]
return ret;
}
trace_regmap_hw_write_start(map, reg, val_len / map->fo...
-
--[[linux-4.4.1/trace_regmap_hw_write_start()]]
/* If we're doing a single register write we can probab...
* send the work_buf directly, otherwise try to do a ga...
* write.
*/
if (val == work_val)
ret = map->bus->write(map->bus_context, map->work_buf,
map->format.reg_bytes +
map->format.pad_bytes +
val_len);
else if (map->bus->gather_write)
ret = map->bus->gather_write(map->bus_context, map->wo...
map->format.reg_bytes +
map->format.pad_bytes,
val, val_len);
-
--map->bus は regmap_bus *型
--[[linux-4.4.1/regmap_bus]]
/* If that didn't work fall back on linearising by hand...
if (ret == -ENOTSUPP) {
len = map->format.reg_bytes + map->format.pad_bytes + ...
buf = kzalloc(len, GFP_KERNEL);
if (!buf)
return -ENOMEM;
memcpy(buf, map->work_buf, map->format.reg_bytes);
memcpy(buf + map->format.reg_bytes + map->format.pad_b...
val, val_len);
ret = map->bus->write(map->bus_context, buf, len);
kfree(buf);
-
--[[linux-4.4.1/kzalloc()]]
--[[linux-4.4.1/memcpy()]]
--map->format は regmap_format 型
--[[linux-4.4.1/regmap_format]]
--[[linux-4.4.1/kfree()]]
}
trace_regmap_hw_write_done(map, reg, val_len / map->for...
-
--[[linux-4.4.1/trace_regmap_hw_write_done()]]
return ret;
}
*コメント [#q899ac6c]
ページ名: