Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
a2b37efc
Commit
a2b37efc
authored
Feb 14, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regmap/topic/no-bus' into regmap-next
parents
a31f6849
d2a5884a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
65 additions
and
13 deletions
+65
-13
drivers/base/regmap/internal.h
drivers/base/regmap/internal.h
+2
-0
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+46
-12
include/linux/regmap.h
include/linux/regmap.h
+17
-1
No files found.
drivers/base/regmap/internal.h
View file @
a2b37efc
...
@@ -91,6 +91,8 @@ struct regmap {
...
@@ -91,6 +91,8 @@ struct regmap {
int
(
*
reg_read
)(
void
*
context
,
unsigned
int
reg
,
unsigned
int
*
val
);
int
(
*
reg_read
)(
void
*
context
,
unsigned
int
reg
,
unsigned
int
*
val
);
int
(
*
reg_write
)(
void
*
context
,
unsigned
int
reg
,
unsigned
int
val
);
int
(
*
reg_write
)(
void
*
context
,
unsigned
int
reg
,
unsigned
int
val
);
bool
defer_caching
;
u8
read_flag_mask
;
u8
read_flag_mask
;
u8
write_flag_mask
;
u8
write_flag_mask
;
...
...
drivers/base/regmap/regmap.c
View file @
a2b37efc
...
@@ -389,7 +389,7 @@ struct regmap *regmap_init(struct device *dev,
...
@@ -389,7 +389,7 @@ struct regmap *regmap_init(struct device *dev,
enum
regmap_endian
reg_endian
,
val_endian
;
enum
regmap_endian
reg_endian
,
val_endian
;
int
i
,
j
;
int
i
,
j
;
if
(
!
bus
||
!
config
)
if
(
!
config
)
goto
err
;
goto
err
;
map
=
kzalloc
(
sizeof
(
*
map
),
GFP_KERNEL
);
map
=
kzalloc
(
sizeof
(
*
map
),
GFP_KERNEL
);
...
@@ -403,7 +403,8 @@ struct regmap *regmap_init(struct device *dev,
...
@@ -403,7 +403,8 @@ struct regmap *regmap_init(struct device *dev,
map
->
unlock
=
config
->
unlock
;
map
->
unlock
=
config
->
unlock
;
map
->
lock_arg
=
config
->
lock_arg
;
map
->
lock_arg
=
config
->
lock_arg
;
}
else
{
}
else
{
if
(
bus
->
fast_io
)
{
if
((
bus
&&
bus
->
fast_io
)
||
config
->
fast_io
)
{
spin_lock_init
(
&
map
->
spinlock
);
spin_lock_init
(
&
map
->
spinlock
);
map
->
lock
=
regmap_lock_spinlock
;
map
->
lock
=
regmap_lock_spinlock
;
map
->
unlock
=
regmap_unlock_spinlock
;
map
->
unlock
=
regmap_unlock_spinlock
;
...
@@ -447,11 +448,19 @@ struct regmap *regmap_init(struct device *dev,
...
@@ -447,11 +448,19 @@ struct regmap *regmap_init(struct device *dev,
if
(
config
->
read_flag_mask
||
config
->
write_flag_mask
)
{
if
(
config
->
read_flag_mask
||
config
->
write_flag_mask
)
{
map
->
read_flag_mask
=
config
->
read_flag_mask
;
map
->
read_flag_mask
=
config
->
read_flag_mask
;
map
->
write_flag_mask
=
config
->
write_flag_mask
;
map
->
write_flag_mask
=
config
->
write_flag_mask
;
}
else
{
}
else
if
(
bus
)
{
map
->
read_flag_mask
=
bus
->
read_flag_mask
;
map
->
read_flag_mask
=
bus
->
read_flag_mask
;
}
}
map
->
reg_read
=
_regmap_bus_read
;
if
(
!
bus
)
{
map
->
reg_read
=
config
->
reg_read
;
map
->
reg_write
=
config
->
reg_write
;
map
->
defer_caching
=
false
;
goto
skip_format_initialization
;
}
else
{
map
->
reg_read
=
_regmap_bus_read
;
}
reg_endian
=
config
->
reg_format_endian
;
reg_endian
=
config
->
reg_format_endian
;
if
(
reg_endian
==
REGMAP_ENDIAN_DEFAULT
)
if
(
reg_endian
==
REGMAP_ENDIAN_DEFAULT
)
...
@@ -604,10 +613,15 @@ struct regmap *regmap_init(struct device *dev,
...
@@ -604,10 +613,15 @@ struct regmap *regmap_init(struct device *dev,
goto
err_map
;
goto
err_map
;
}
}
if
(
map
->
format
.
format_write
)
if
(
map
->
format
.
format_write
)
{
map
->
defer_caching
=
false
;
map
->
reg_write
=
_regmap_bus_formatted_write
;
map
->
reg_write
=
_regmap_bus_formatted_write
;
else
if
(
map
->
format
.
format_val
)
}
else
if
(
map
->
format
.
format_val
)
{
map
->
defer_caching
=
true
;
map
->
reg_write
=
_regmap_bus_raw_write
;
map
->
reg_write
=
_regmap_bus_raw_write
;
}
skip_format_initialization:
map
->
range_tree
=
RB_ROOT
;
map
->
range_tree
=
RB_ROOT
;
for
(
i
=
0
;
i
<
config
->
num_ranges
;
i
++
)
{
for
(
i
=
0
;
i
<
config
->
num_ranges
;
i
++
)
{
...
@@ -810,7 +824,7 @@ void regmap_exit(struct regmap *map)
...
@@ -810,7 +824,7 @@ void regmap_exit(struct regmap *map)
regcache_exit
(
map
);
regcache_exit
(
map
);
regmap_debugfs_exit
(
map
);
regmap_debugfs_exit
(
map
);
regmap_range_exit
(
map
);
regmap_range_exit
(
map
);
if
(
map
->
bus
->
free_context
)
if
(
map
->
bus
&&
map
->
bus
->
free_context
)
map
->
bus
->
free_context
(
map
->
bus_context
);
map
->
bus
->
free_context
(
map
->
bus_context
);
kfree
(
map
->
work_buf
);
kfree
(
map
->
work_buf
);
kfree
(
map
);
kfree
(
map
);
...
@@ -916,6 +930,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
...
@@ -916,6 +930,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg,
size_t
len
;
size_t
len
;
int
i
;
int
i
;
BUG_ON
(
!
map
->
bus
);
/* Check for unwritable registers before we start */
/* Check for unwritable registers before we start */
if
(
map
->
writeable_reg
)
if
(
map
->
writeable_reg
)
for
(
i
=
0
;
i
<
val_len
/
map
->
format
.
val_bytes
;
i
++
)
for
(
i
=
0
;
i
<
val_len
/
map
->
format
.
val_bytes
;
i
++
)
...
@@ -1068,7 +1084,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
...
@@ -1068,7 +1084,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
struct
regmap_range_node
*
range
;
struct
regmap_range_node
*
range
;
struct
regmap
*
map
=
context
;
struct
regmap
*
map
=
context
;
BUG_ON
(
!
map
->
format
.
format_write
);
BUG_ON
(
!
map
->
bus
||
!
map
->
format
.
format_write
);
range
=
_regmap_range_lookup
(
map
,
reg
);
range
=
_regmap_range_lookup
(
map
,
reg
);
if
(
range
)
{
if
(
range
)
{
...
@@ -1094,7 +1110,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
...
@@ -1094,7 +1110,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
{
{
struct
regmap
*
map
=
context
;
struct
regmap
*
map
=
context
;
BUG_ON
(
!
map
->
format
.
format_val
);
BUG_ON
(
!
map
->
bus
||
!
map
->
format
.
format_val
);
map
->
format
.
format_val
(
map
->
work_buf
+
map
->
format
.
reg_bytes
map
->
format
.
format_val
(
map
->
work_buf
+
map
->
format
.
reg_bytes
+
map
->
format
.
pad_bytes
,
val
,
0
);
+
map
->
format
.
pad_bytes
,
val
,
0
);
...
@@ -1105,12 +1121,18 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
...
@@ -1105,12 +1121,18 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
map
->
format
.
val_bytes
,
false
);
map
->
format
.
val_bytes
,
false
);
}
}
static
inline
void
*
_regmap_map_get_context
(
struct
regmap
*
map
)
{
return
(
map
->
bus
)
?
map
:
map
->
bus_context
;
}
int
_regmap_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
int
_regmap_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
unsigned
int
val
)
{
{
int
ret
;
int
ret
;
void
*
context
=
_regmap_map_get_context
(
map
);
if
(
!
map
->
cache_bypass
&&
map
->
format
.
format_write
)
{
if
(
!
map
->
cache_bypass
&&
!
map
->
defer_caching
)
{
ret
=
regcache_write
(
map
,
reg
,
val
);
ret
=
regcache_write
(
map
,
reg
,
val
);
if
(
ret
!=
0
)
if
(
ret
!=
0
)
return
ret
;
return
ret
;
...
@@ -1127,7 +1149,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
...
@@ -1127,7 +1149,7 @@ int _regmap_write(struct regmap *map, unsigned int reg,
trace_regmap_reg_write
(
map
->
dev
,
reg
,
val
);
trace_regmap_reg_write
(
map
->
dev
,
reg
,
val
);
return
map
->
reg_write
(
map
,
reg
,
val
);
return
map
->
reg_write
(
context
,
reg
,
val
);
}
}
/**
/**
...
@@ -1178,6 +1200,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
...
@@ -1178,6 +1200,8 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
{
{
int
ret
;
int
ret
;
if
(
!
map
->
bus
)
return
-
EINVAL
;
if
(
val_len
%
map
->
format
.
val_bytes
)
if
(
val_len
%
map
->
format
.
val_bytes
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
reg
%
map
->
reg_stride
)
if
(
reg
%
map
->
reg_stride
)
...
@@ -1214,6 +1238,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
...
@@ -1214,6 +1238,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val,
size_t
val_bytes
=
map
->
format
.
val_bytes
;
size_t
val_bytes
=
map
->
format
.
val_bytes
;
void
*
wval
;
void
*
wval
;
if
(
!
map
->
bus
)
return
-
EINVAL
;
if
(
!
map
->
format
.
parse_val
)
if
(
!
map
->
format
.
parse_val
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
reg
%
map
->
reg_stride
)
if
(
reg
%
map
->
reg_stride
)
...
@@ -1310,6 +1336,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
...
@@ -1310,6 +1336,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
u8
*
u8
=
map
->
work_buf
;
u8
*
u8
=
map
->
work_buf
;
int
ret
;
int
ret
;
BUG_ON
(
!
map
->
bus
);
range
=
_regmap_range_lookup
(
map
,
reg
);
range
=
_regmap_range_lookup
(
map
,
reg
);
if
(
range
)
{
if
(
range
)
{
ret
=
_regmap_select_page
(
map
,
&
reg
,
range
,
ret
=
_regmap_select_page
(
map
,
&
reg
,
range
,
...
@@ -1361,6 +1389,8 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
...
@@ -1361,6 +1389,8 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
unsigned
int
*
val
)
unsigned
int
*
val
)
{
{
int
ret
;
int
ret
;
void
*
context
=
_regmap_map_get_context
(
map
);
BUG_ON
(
!
map
->
reg_read
);
BUG_ON
(
!
map
->
reg_read
);
if
(
!
map
->
cache_bypass
)
{
if
(
!
map
->
cache_bypass
)
{
...
@@ -1372,7 +1402,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
...
@@ -1372,7 +1402,7 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
if
(
map
->
cache_only
)
if
(
map
->
cache_only
)
return
-
EBUSY
;
return
-
EBUSY
;
ret
=
map
->
reg_read
(
map
,
reg
,
val
);
ret
=
map
->
reg_read
(
context
,
reg
,
val
);
if
(
ret
==
0
)
{
if
(
ret
==
0
)
{
#ifdef LOG_DEVICE
#ifdef LOG_DEVICE
if
(
strcmp
(
dev_name
(
map
->
dev
),
LOG_DEVICE
)
==
0
)
if
(
strcmp
(
dev_name
(
map
->
dev
),
LOG_DEVICE
)
==
0
)
...
@@ -1434,6 +1464,8 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
...
@@ -1434,6 +1464,8 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
unsigned
int
v
;
unsigned
int
v
;
int
ret
,
i
;
int
ret
,
i
;
if
(
!
map
->
bus
)
return
-
EINVAL
;
if
(
val_len
%
map
->
format
.
val_bytes
)
if
(
val_len
%
map
->
format
.
val_bytes
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
reg
%
map
->
reg_stride
)
if
(
reg
%
map
->
reg_stride
)
...
@@ -1485,6 +1517,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
...
@@ -1485,6 +1517,8 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
size_t
val_bytes
=
map
->
format
.
val_bytes
;
size_t
val_bytes
=
map
->
format
.
val_bytes
;
bool
vol
=
regmap_volatile_range
(
map
,
reg
,
val_count
);
bool
vol
=
regmap_volatile_range
(
map
,
reg
,
val_count
);
if
(
!
map
->
bus
)
return
-
EINVAL
;
if
(
!
map
->
format
.
parse_val
)
if
(
!
map
->
format
.
parse_val
)
return
-
EINVAL
;
return
-
EINVAL
;
if
(
reg
%
map
->
reg_stride
)
if
(
reg
%
map
->
reg_stride
)
...
...
include/linux/regmap.h
View file @
a2b37efc
...
@@ -128,7 +128,18 @@ typedef void (*regmap_unlock)(void *);
...
@@ -128,7 +128,18 @@ typedef void (*regmap_unlock)(void *);
* @lock_arg: this field is passed as the only argument of lock/unlock
* @lock_arg: this field is passed as the only argument of lock/unlock
* functions (ignored in case regular lock/unlock functions
* functions (ignored in case regular lock/unlock functions
* are not overridden).
* are not overridden).
*
* @reg_read: Optional callback that if filled will be used to perform
* all the reads from the registers. Should only be provided for
* devices whos read operation cannot be represented as a simple read
* operation on a bus such as SPI, I2C, etc. Most of the devices do
* not need this.
* @reg_write: Same as above for writing.
* @fast_io: Register IO is fast. Use a spinlock instead of a mutex
* to perform locking. This field is ignored if custom lock/unlock
* functions are used (see fields lock/unlock of struct regmap_config).
* 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.
* @max_register: Optional, specifies the maximum valid register index.
* @max_register: Optional, specifies the maximum valid register index.
* @wr_table: Optional, points to a struct regmap_access_table specifying
* @wr_table: Optional, points to a struct regmap_access_table specifying
* valid ranges for write access.
* valid ranges for write access.
...
@@ -178,6 +189,11 @@ struct regmap_config {
...
@@ -178,6 +189,11 @@ struct regmap_config {
regmap_unlock
unlock
;
regmap_unlock
unlock
;
void
*
lock_arg
;
void
*
lock_arg
;
int
(
*
reg_read
)(
void
*
context
,
unsigned
int
reg
,
unsigned
int
*
val
);
int
(
*
reg_write
)(
void
*
context
,
unsigned
int
reg
,
unsigned
int
val
);
bool
fast_io
;
unsigned
int
max_register
;
unsigned
int
max_register
;
const
struct
regmap_access_table
*
wr_table
;
const
struct
regmap_access_table
*
wr_table
;
const
struct
regmap_access_table
*
rd_table
;
const
struct
regmap_access_table
*
rd_table
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment