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
Kirill Smelkov
linux
Commits
a31f6849
Commit
a31f6849
authored
Feb 14, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regmap/topic/mmio' into regmap-next
parents
5dea2150
878ec67b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
107 additions
and
19 deletions
+107
-19
drivers/base/regmap/regmap-mmio.c
drivers/base/regmap/regmap-mmio.c
+66
-13
include/linux/regmap.h
include/linux/regmap.h
+41
-6
No files found.
drivers/base/regmap/regmap-mmio.c
View file @
a31f6849
...
...
@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
...
...
@@ -26,6 +27,7 @@
struct
regmap_mmio_context
{
void
__iomem
*
regs
;
unsigned
val_bytes
;
struct
clk
*
clk
;
};
static
int
regmap_mmio_gather_write
(
void
*
context
,
...
...
@@ -34,9 +36,16 @@ static int regmap_mmio_gather_write(void *context,
{
struct
regmap_mmio_context
*
ctx
=
context
;
u32
offset
;
int
ret
;
BUG_ON
(
reg_size
!=
4
);
if
(
ctx
->
clk
)
{
ret
=
clk_enable
(
ctx
->
clk
);
if
(
ret
<
0
)
return
ret
;
}
offset
=
*
(
u32
*
)
reg
;
while
(
val_size
)
{
...
...
@@ -64,6 +73,9 @@ static int regmap_mmio_gather_write(void *context,
offset
+=
ctx
->
val_bytes
;
}
if
(
ctx
->
clk
)
clk_disable
(
ctx
->
clk
);
return
0
;
}
...
...
@@ -80,9 +92,16 @@ static int regmap_mmio_read(void *context,
{
struct
regmap_mmio_context
*
ctx
=
context
;
u32
offset
;
int
ret
;
BUG_ON
(
reg_size
!=
4
);
if
(
ctx
->
clk
)
{
ret
=
clk_enable
(
ctx
->
clk
);
if
(
ret
<
0
)
return
ret
;
}
offset
=
*
(
u32
*
)
reg
;
while
(
val_size
)
{
...
...
@@ -110,11 +129,20 @@ static int regmap_mmio_read(void *context,
offset
+=
ctx
->
val_bytes
;
}
if
(
ctx
->
clk
)
clk_disable
(
ctx
->
clk
);
return
0
;
}
static
void
regmap_mmio_free_context
(
void
*
context
)
{
struct
regmap_mmio_context
*
ctx
=
context
;
if
(
ctx
->
clk
)
{
clk_unprepare
(
ctx
->
clk
);
clk_put
(
ctx
->
clk
);
}
kfree
(
context
);
}
...
...
@@ -128,11 +156,14 @@ static struct regmap_bus regmap_mmio = {
.
val_format_endian_default
=
REGMAP_ENDIAN_NATIVE
,
};
static
struct
regmap_mmio_context
*
regmap_mmio_gen_context
(
void
__iomem
*
regs
,
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
;
if
(
config
->
reg_bits
!=
32
)
return
ERR_PTR
(
-
EINVAL
);
...
...
@@ -179,37 +210,59 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(void __iomem *regs,
ctx
->
regs
=
regs
;
ctx
->
val_bytes
=
config
->
val_bits
/
8
;
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
);
}
/**
* regmap_init_mmio
(): Initialise register map
* regmap_init_mmio
_clk(): Initialise register map with register clock
*
* @dev: Device that will be interacted with
* @clk_id: register clock consumer ID
* @regs: Pointer to memory-mapped IO region
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer to
* a struct regmap.
*/
struct
regmap
*
regmap_init_mmio
(
struct
device
*
dev
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
)
struct
regmap
*
regmap_init_mmio
_clk
(
struct
device
*
dev
,
const
char
*
clk_id
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
)
{
struct
regmap_mmio_context
*
ctx
;
ctx
=
regmap_mmio_gen_context
(
regs
,
config
);
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
);
}
EXPORT_SYMBOL_GPL
(
regmap_init_mmio
);
EXPORT_SYMBOL_GPL
(
regmap_init_mmio
_clk
);
/**
* devm_regmap_init_mmio
(): Initialise managed register map
* devm_regmap_init_mmio
_clk(): Initialise managed register map with clock
*
* @dev: Device that will be interacted with
* @clk_id: register clock consumer ID
* @regs: Pointer to memory-mapped IO region
* @config: Configuration for register map
*
...
...
@@ -217,18 +270,18 @@ EXPORT_SYMBOL_GPL(regmap_init_mmio);
* to a struct regmap. The regmap will be automatically freed by the
* device management code.
*/
struct
regmap
*
devm_regmap_init_mmio
(
struct
device
*
dev
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
)
struct
regmap
*
devm_regmap_init_mmio
_clk
(
struct
device
*
dev
,
const
char
*
clk_id
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
)
{
struct
regmap_mmio_context
*
ctx
;
ctx
=
regmap_mmio_gen_context
(
regs
,
config
);
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
);
}
EXPORT_SYMBOL_GPL
(
devm_regmap_init_mmio
);
EXPORT_SYMBOL_GPL
(
devm_regmap_init_mmio
_clk
);
MODULE_LICENSE
(
"GPL v2"
);
include/linux/regmap.h
View file @
a31f6849
...
...
@@ -299,9 +299,9 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c,
const
struct
regmap_config
*
config
);
struct
regmap
*
regmap_init_spi
(
struct
spi_device
*
dev
,
const
struct
regmap_config
*
config
);
struct
regmap
*
regmap_init_mmio
(
struct
device
*
dev
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
);
struct
regmap
*
regmap_init_mmio
_clk
(
struct
device
*
dev
,
const
char
*
clk_id
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
);
struct
regmap
*
devm_regmap_init
(
struct
device
*
dev
,
const
struct
regmap_bus
*
bus
,
...
...
@@ -311,9 +311,44 @@ struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
const
struct
regmap_config
*
config
);
struct
regmap
*
devm_regmap_init_spi
(
struct
spi_device
*
dev
,
const
struct
regmap_config
*
config
);
struct
regmap
*
devm_regmap_init_mmio
(
struct
device
*
dev
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
);
struct
regmap
*
devm_regmap_init_mmio_clk
(
struct
device
*
dev
,
const
char
*
clk_id
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
);
/**
* regmap_init_mmio(): Initialise register map
*
* @dev: Device that will be interacted with
* @regs: Pointer to memory-mapped IO region
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer to
* a struct regmap.
*/
static
inline
struct
regmap
*
regmap_init_mmio
(
struct
device
*
dev
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
)
{
return
regmap_init_mmio_clk
(
dev
,
NULL
,
regs
,
config
);
}
/**
* devm_regmap_init_mmio(): Initialise managed register map
*
* @dev: Device that will be interacted with
* @regs: Pointer to memory-mapped IO region
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer
* to a struct regmap. The regmap will be automatically freed by the
* device management code.
*/
static
inline
struct
regmap
*
devm_regmap_init_mmio
(
struct
device
*
dev
,
void
__iomem
*
regs
,
const
struct
regmap_config
*
config
)
{
return
devm_regmap_init_mmio_clk
(
dev
,
NULL
,
regs
,
config
);
}
void
regmap_exit
(
struct
regmap
*
map
);
int
regmap_reinit_cache
(
struct
regmap
*
map
,
...
...
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