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
8e24a6e6
Commit
8e24a6e6
authored
Dec 11, 2012
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regmap/topic/table' into regmap-next
parents
db760fbe
76aad392
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
122 additions
and
11 deletions
+122
-11
drivers/base/regmap/internal.h
drivers/base/regmap/internal.h
+4
-0
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+46
-0
include/linux/regmap.h
include/linux/regmap.h
+72
-11
No files found.
drivers/base/regmap/internal.h
View file @
8e24a6e6
...
@@ -69,6 +69,10 @@ struct regmap {
...
@@ -69,6 +69,10 @@ struct regmap {
bool
(
*
readable_reg
)(
struct
device
*
dev
,
unsigned
int
reg
);
bool
(
*
readable_reg
)(
struct
device
*
dev
,
unsigned
int
reg
);
bool
(
*
volatile_reg
)(
struct
device
*
dev
,
unsigned
int
reg
);
bool
(
*
volatile_reg
)(
struct
device
*
dev
,
unsigned
int
reg
);
bool
(
*
precious_reg
)(
struct
device
*
dev
,
unsigned
int
reg
);
bool
(
*
precious_reg
)(
struct
device
*
dev
,
unsigned
int
reg
);
const
struct
regmap_access_table
*
wr_table
;
const
struct
regmap_access_table
*
rd_table
;
const
struct
regmap_access_table
*
volatile_table
;
const
struct
regmap_access_table
*
precious_table
;
u8
read_flag_mask
;
u8
read_flag_mask
;
u8
write_flag_mask
;
u8
write_flag_mask
;
...
...
drivers/base/regmap/regmap.c
View file @
8e24a6e6
...
@@ -34,6 +34,36 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
...
@@ -34,6 +34,36 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
unsigned
int
mask
,
unsigned
int
val
,
unsigned
int
mask
,
unsigned
int
val
,
bool
*
change
);
bool
*
change
);
bool
regmap_reg_in_ranges
(
unsigned
int
reg
,
const
struct
regmap_range
*
ranges
,
unsigned
int
nranges
)
{
const
struct
regmap_range
*
r
;
int
i
;
for
(
i
=
0
,
r
=
ranges
;
i
<
nranges
;
i
++
,
r
++
)
if
(
regmap_reg_in_range
(
reg
,
r
))
return
true
;
return
false
;
}
EXPORT_SYMBOL_GPL
(
regmap_reg_in_ranges
);
static
bool
_regmap_check_range_table
(
struct
regmap
*
map
,
unsigned
int
reg
,
const
struct
regmap_access_table
*
table
)
{
/* Check "no ranges" first */
if
(
regmap_reg_in_ranges
(
reg
,
table
->
no_ranges
,
table
->
n_no_ranges
))
return
false
;
/* In case zero "yes ranges" are supplied, any reg is OK */
if
(
!
table
->
n_yes_ranges
)
return
true
;
return
regmap_reg_in_ranges
(
reg
,
table
->
yes_ranges
,
table
->
n_yes_ranges
);
}
bool
regmap_writeable
(
struct
regmap
*
map
,
unsigned
int
reg
)
bool
regmap_writeable
(
struct
regmap
*
map
,
unsigned
int
reg
)
{
{
if
(
map
->
max_register
&&
reg
>
map
->
max_register
)
if
(
map
->
max_register
&&
reg
>
map
->
max_register
)
...
@@ -42,6 +72,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
...
@@ -42,6 +72,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)
if
(
map
->
writeable_reg
)
if
(
map
->
writeable_reg
)
return
map
->
writeable_reg
(
map
->
dev
,
reg
);
return
map
->
writeable_reg
(
map
->
dev
,
reg
);
if
(
map
->
wr_table
)
return
_regmap_check_range_table
(
map
,
reg
,
map
->
wr_table
);
return
true
;
return
true
;
}
}
...
@@ -56,6 +89,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
...
@@ -56,6 +89,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg)
if
(
map
->
readable_reg
)
if
(
map
->
readable_reg
)
return
map
->
readable_reg
(
map
->
dev
,
reg
);
return
map
->
readable_reg
(
map
->
dev
,
reg
);
if
(
map
->
rd_table
)
return
_regmap_check_range_table
(
map
,
reg
,
map
->
rd_table
);
return
true
;
return
true
;
}
}
...
@@ -67,6 +103,9 @@ bool regmap_volatile(struct regmap *map, unsigned int reg)
...
@@ -67,6 +103,9 @@ bool regmap_volatile(struct regmap *map, unsigned int reg)
if
(
map
->
volatile_reg
)
if
(
map
->
volatile_reg
)
return
map
->
volatile_reg
(
map
->
dev
,
reg
);
return
map
->
volatile_reg
(
map
->
dev
,
reg
);
if
(
map
->
volatile_table
)
return
_regmap_check_range_table
(
map
,
reg
,
map
->
volatile_table
);
return
true
;
return
true
;
}
}
...
@@ -78,6 +117,9 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
...
@@ -78,6 +117,9 @@ bool regmap_precious(struct regmap *map, unsigned int reg)
if
(
map
->
precious_reg
)
if
(
map
->
precious_reg
)
return
map
->
precious_reg
(
map
->
dev
,
reg
);
return
map
->
precious_reg
(
map
->
dev
,
reg
);
if
(
map
->
precious_table
)
return
_regmap_check_range_table
(
map
,
reg
,
map
->
precious_table
);
return
false
;
return
false
;
}
}
...
@@ -370,6 +412,10 @@ struct regmap *regmap_init(struct device *dev,
...
@@ -370,6 +412,10 @@ struct regmap *regmap_init(struct device *dev,
map
->
bus
=
bus
;
map
->
bus
=
bus
;
map
->
bus_context
=
bus_context
;
map
->
bus_context
=
bus_context
;
map
->
max_register
=
config
->
max_register
;
map
->
max_register
=
config
->
max_register
;
map
->
wr_table
=
config
->
wr_table
;
map
->
rd_table
=
config
->
rd_table
;
map
->
volatile_table
=
config
->
volatile_table
;
map
->
precious_table
=
config
->
precious_table
;
map
->
writeable_reg
=
config
->
writeable_reg
;
map
->
writeable_reg
=
config
->
writeable_reg
;
map
->
readable_reg
=
config
->
readable_reg
;
map
->
readable_reg
=
config
->
readable_reg
;
map
->
volatile_reg
=
config
->
volatile_reg
;
map
->
volatile_reg
=
config
->
volatile_reg
;
...
...
include/linux/regmap.h
View file @
8e24a6e6
...
@@ -54,6 +54,36 @@ enum regmap_endian {
...
@@ -54,6 +54,36 @@ enum regmap_endian {
REGMAP_ENDIAN_NATIVE
,
REGMAP_ENDIAN_NATIVE
,
};
};
/**
* A register range, used for access related checks
* (readable/writeable/volatile/precious checks)
*
* @range_min: address of first register
* @range_max: address of last register
*/
struct
regmap_range
{
unsigned
int
range_min
;
unsigned
int
range_max
;
};
/*
* A table of ranges including some yes ranges and some no ranges.
* If a register belongs to a no_range, the corresponding check function
* will return false. If a register belongs to a yes range, the corresponding
* check function will return true. "no_ranges" are searched first.
*
* @yes_ranges : pointer to an array of regmap ranges used as "yes ranges"
* @n_yes_ranges: size of the above array
* @no_ranges: pointer to an array of regmap ranges used as "no ranges"
* @n_no_ranges: size of the above array
*/
struct
regmap_access_table
{
const
struct
regmap_range
*
yes_ranges
;
unsigned
int
n_yes_ranges
;
const
struct
regmap_range
*
no_ranges
;
unsigned
int
n_no_ranges
;
};
typedef
void
(
*
regmap_lock
)(
void
*
);
typedef
void
(
*
regmap_lock
)(
void
*
);
typedef
void
(
*
regmap_unlock
)(
void
*
);
typedef
void
(
*
regmap_unlock
)(
void
*
);
...
@@ -71,22 +101,39 @@ typedef void (*regmap_unlock)(void *);
...
@@ -71,22 +101,39 @@ typedef void (*regmap_unlock)(void *);
* @val_bits: Number of bits in a register value, mandatory.
* @val_bits: Number of bits in a register value, mandatory.
*
*
* @writeable_reg: Optional callback returning true if the register
* @writeable_reg: Optional callback returning true if the register
* can be written to.
* can be written to. If this field is NULL but wr_table
* (see below) is not, the check is performed on such table
* (a register is writeable if it belongs to one of the ranges
* specified by wr_table).
* @readable_reg: Optional callback returning true if the register
* @readable_reg: Optional callback returning true if the register
* can be read from.
* can be read from. If this field is NULL but rd_table
* (see below) is not, the check is performed on such table
* (a register is readable if it belongs to one of the ranges
* specified by rd_table).
* @volatile_reg: Optional callback returning true if the register
* @volatile_reg: Optional callback returning true if the register
* value can't be cached.
* value can't be cached. If this field is NULL but
* volatile_table (see below) is not, the check is performed on
* such table (a register is volatile if it belongs to one of
* the ranges specified by volatile_table).
* @precious_reg: Optional callback returning true if the rgister
* @precious_reg: Optional callback returning true if the rgister
* should not be read outside of a call from the driver
* should not be read outside of a call from the driver
* (eg, a clear on read interrupt status register).
* (eg, a clear on read interrupt status register). If this
* @lock: Optional lock callback (overrides regmap's default lock
* field is NULL but precious_table (see below) is not, the
* function, based on spinlock or mutex).
* check is performed on such table (a register is precious if
* @unlock: As above for unlocking.
* it belongs to one of the ranges specified by precious_table).
* @lock_arg: this field is passed as the only argument of lock/unlock
* @lock: Optional lock callback (overrides regmap's default lock
* functions (ignored in case regular lock/unlock functions
* function, based on spinlock or mutex).
* are not overridden).
* @unlock: As above for unlocking.
* @lock_arg: this field is passed as the only argument of lock/unlock
* functions (ignored in case regular lock/unlock functions
* are not overridden).
*
*
* @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
* valid ranges for write access.
* @rd_table: As above, for read access.
* @volatile_table: As above, for volatile registers.
* @precious_table: As above, for precious registers.
* @reg_defaults: Power on reset values for registers (for use with
* @reg_defaults: Power on reset values for registers (for use with
* register cache support).
* register cache support).
* @num_reg_defaults: Number of elements in reg_defaults.
* @num_reg_defaults: Number of elements in reg_defaults.
...
@@ -131,6 +178,10 @@ struct regmap_config {
...
@@ -131,6 +178,10 @@ struct regmap_config {
void
*
lock_arg
;
void
*
lock_arg
;
unsigned
int
max_register
;
unsigned
int
max_register
;
const
struct
regmap_access_table
*
wr_table
;
const
struct
regmap_access_table
*
rd_table
;
const
struct
regmap_access_table
*
volatile_table
;
const
struct
regmap_access_table
*
precious_table
;
const
struct
reg_default
*
reg_defaults
;
const
struct
reg_default
*
reg_defaults
;
unsigned
int
num_reg_defaults
;
unsigned
int
num_reg_defaults
;
enum
regcache_type
cache_type
;
enum
regcache_type
cache_type
;
...
@@ -281,6 +332,16 @@ void regcache_mark_dirty(struct regmap *map);
...
@@ -281,6 +332,16 @@ void regcache_mark_dirty(struct regmap *map);
int
regmap_register_patch
(
struct
regmap
*
map
,
const
struct
reg_default
*
regs
,
int
regmap_register_patch
(
struct
regmap
*
map
,
const
struct
reg_default
*
regs
,
int
num_regs
);
int
num_regs
);
static
inline
bool
regmap_reg_in_range
(
unsigned
int
reg
,
const
struct
regmap_range
*
range
)
{
return
reg
>=
range
->
range_min
&&
reg
<=
range
->
range_max
;
}
bool
regmap_reg_in_ranges
(
unsigned
int
reg
,
const
struct
regmap_range
*
ranges
,
unsigned
int
nranges
);
/**
/**
* Description of an IRQ for the generic regmap irq_chip.
* Description of an IRQ for the generic regmap irq_chip.
*
*
...
...
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