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
6e0545c4
Commit
6e0545c4
authored
Oct 05, 2020
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regmap/for-5.10' into regmap-next
parents
549738f1
3a6f0fb7
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
954 additions
and
8 deletions
+954
-8
drivers/base/regmap/Kconfig
drivers/base/regmap/Kconfig
+5
-1
drivers/base/regmap/Makefile
drivers/base/regmap/Makefile
+1
-0
drivers/base/regmap/internal.h
drivers/base/regmap/internal.h
+3
-0
drivers/base/regmap/regmap-debugfs.c
drivers/base/regmap/regmap-debugfs.c
+1
-1
drivers/base/regmap/regmap-irq.c
drivers/base/regmap/regmap-irq.c
+32
-1
drivers/base/regmap/regmap-sdw.c
drivers/base/regmap/regmap-sdw.c
+0
-1
drivers/base/regmap/regmap-spi-avmm.c
drivers/base/regmap/regmap-spi-avmm.c
+719
-0
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+141
-4
include/linux/regmap.h
include/linux/regmap.h
+52
-0
No files found.
drivers/base/regmap/Kconfig
View file @
6e0545c4
...
...
@@ -4,7 +4,7 @@
# subsystems should select the appropriate symbols.
config REGMAP
default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C)
default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SCCB || REGMAP_I3C
|| REGMAP_SPI_AVMM
)
select IRQ_DOMAIN if REGMAP_IRQ
bool
...
...
@@ -53,3 +53,7 @@ config REGMAP_SCCB
config REGMAP_I3C
tristate
depends on I3C
config REGMAP_SPI_AVMM
tristate
depends on SPI
drivers/base/regmap/Makefile
View file @
6e0545c4
...
...
@@ -17,3 +17,4 @@ obj-$(CONFIG_REGMAP_W1) += regmap-w1.o
obj-$(CONFIG_REGMAP_SOUNDWIRE)
+=
regmap-sdw.o
obj-$(CONFIG_REGMAP_SCCB)
+=
regmap-sccb.o
obj-$(CONFIG_REGMAP_I3C)
+=
regmap-i3c.o
obj-$(CONFIG_REGMAP_SPI_AVMM)
+=
regmap-spi-avmm.o
drivers/base/regmap/internal.h
View file @
6e0545c4
...
...
@@ -161,6 +161,9 @@ struct regmap {
void
*
selector_work_buf
;
/* Scratch buffer used for selector */
struct
hwspinlock
*
hwlock
;
/* if set, the regmap core can sleep */
bool
can_sleep
;
};
struct
regcache_ops
{
...
...
drivers/base/regmap/regmap-debugfs.c
View file @
6e0545c4
...
...
@@ -183,7 +183,7 @@ static inline void regmap_calc_tot_len(struct regmap *map,
{
/* Calculate the length of a fixed format */
if
(
!
map
->
debugfs_tot_len
)
{
map
->
debugfs_reg_len
=
regmap_calc_reg_len
(
map
->
max_register
)
,
map
->
debugfs_reg_len
=
regmap_calc_reg_len
(
map
->
max_register
)
;
map
->
debugfs_val_len
=
2
*
map
->
format
.
val_bytes
;
map
->
debugfs_tot_len
=
map
->
debugfs_reg_len
+
map
->
debugfs_val_len
+
3
;
/* : \n */
...
...
drivers/base/regmap/regmap-irq.c
View file @
6e0545c4
...
...
@@ -168,6 +168,14 @@ static void regmap_irq_sync_unlock(struct irq_data *data)
ret
=
regmap_write
(
map
,
reg
,
~
d
->
mask_buf
[
i
]);
else
ret
=
regmap_write
(
map
,
reg
,
d
->
mask_buf
[
i
]);
if
(
d
->
chip
->
clear_ack
)
{
if
(
d
->
chip
->
ack_invert
&&
!
ret
)
ret
=
regmap_write
(
map
,
reg
,
d
->
mask_buf
[
i
]);
else
if
(
!
ret
)
ret
=
regmap_write
(
map
,
reg
,
~
d
->
mask_buf
[
i
]);
}
if
(
ret
!=
0
)
dev_err
(
d
->
map
->
dev
,
"Failed to ack 0x%x: %d
\n
"
,
reg
,
ret
);
...
...
@@ -493,7 +501,20 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
if
(
data
->
status_buf
[
i
]
&&
(
chip
->
ack_base
||
chip
->
use_ack
))
{
reg
=
chip
->
ack_base
+
(
i
*
map
->
reg_stride
*
data
->
irq_reg_stride
);
ret
=
regmap_write
(
map
,
reg
,
data
->
status_buf
[
i
]);
if
(
chip
->
ack_invert
)
ret
=
regmap_write
(
map
,
reg
,
~
data
->
status_buf
[
i
]);
else
ret
=
regmap_write
(
map
,
reg
,
data
->
status_buf
[
i
]);
if
(
chip
->
clear_ack
)
{
if
(
chip
->
ack_invert
&&
!
ret
)
ret
=
regmap_write
(
map
,
reg
,
data
->
status_buf
[
i
]);
else
if
(
!
ret
)
ret
=
regmap_write
(
map
,
reg
,
~
data
->
status_buf
[
i
]);
}
if
(
ret
!=
0
)
dev_err
(
map
->
dev
,
"Failed to ack 0x%x: %d
\n
"
,
reg
,
ret
);
...
...
@@ -722,6 +743,16 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
else
ret
=
regmap_write
(
map
,
reg
,
d
->
status_buf
[
i
]
&
d
->
mask_buf
[
i
]);
if
(
chip
->
clear_ack
)
{
if
(
chip
->
ack_invert
&&
!
ret
)
ret
=
regmap_write
(
map
,
reg
,
(
d
->
status_buf
[
i
]
&
d
->
mask_buf
[
i
]));
else
if
(
!
ret
)
ret
=
regmap_write
(
map
,
reg
,
~
(
d
->
status_buf
[
i
]
&
d
->
mask_buf
[
i
]));
}
if
(
ret
!=
0
)
{
dev_err
(
map
->
dev
,
"Failed to ack 0x%x: %d
\n
"
,
reg
,
ret
);
...
...
drivers/base/regmap/regmap-sdw.c
View file @
6e0545c4
...
...
@@ -2,7 +2,6 @@
// Copyright(c) 2015-17 Intel Corporation.
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/soundwire/sdw.h>
#include "internal.h"
...
...
drivers/base/regmap/regmap-spi-avmm.c
0 → 100644
View file @
6e0545c4
This diff is collapsed.
Click to expand it.
drivers/base/regmap/regmap.c
View file @
6e0545c4
...
...
@@ -209,6 +209,18 @@ static bool regmap_volatile_range(struct regmap *map, unsigned int reg,
return
true
;
}
static
void
regmap_format_12_20_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
{
u8
*
out
=
map
->
work_buf
;
out
[
0
]
=
reg
>>
4
;
out
[
1
]
=
(
reg
<<
4
)
|
(
val
>>
16
);
out
[
2
]
=
val
>>
8
;
out
[
3
]
=
val
;
}
static
void
regmap_format_2_6_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
{
...
...
@@ -711,13 +723,17 @@ struct regmap *__regmap_init(struct device *dev,
if
(
ret
)
goto
err_map
;
ret
=
-
EINVAL
;
/* Later error paths rely on this */
if
(
config
->
disable_locking
)
{
map
->
lock
=
map
->
unlock
=
regmap_lock_unlock_none
;
map
->
can_sleep
=
config
->
can_sleep
;
regmap_debugfs_disable
(
map
);
}
else
if
(
config
->
lock
&&
config
->
unlock
)
{
map
->
lock
=
config
->
lock
;
map
->
unlock
=
config
->
unlock
;
map
->
lock_arg
=
config
->
lock_arg
;
map
->
can_sleep
=
config
->
can_sleep
;
}
else
if
(
config
->
use_hwlock
)
{
map
->
hwlock
=
hwspin_lock_request_specific
(
config
->
hwlock_id
);
if
(
!
map
->
hwlock
)
{
...
...
@@ -753,6 +769,7 @@ struct regmap *__regmap_init(struct device *dev,
mutex_init
(
&
map
->
mutex
);
map
->
lock
=
regmap_lock_mutex
;
map
->
unlock
=
regmap_unlock_mutex
;
map
->
can_sleep
=
true
;
lockdep_set_class_and_name
(
&
map
->
mutex
,
lock_key
,
lock_name
);
}
...
...
@@ -883,6 +900,16 @@ struct regmap *__regmap_init(struct device *dev,
}
break
;
case
12
:
switch
(
config
->
val_bits
)
{
case
20
:
map
->
format
.
format_write
=
regmap_format_12_20_write
;
break
;
default:
goto
err_hwlock
;
}
break
;
case
8
:
map
->
format
.
format_reg
=
regmap_format_8
;
break
;
...
...
@@ -1243,6 +1270,106 @@ struct regmap_field *devm_regmap_field_alloc(struct device *dev,
}
EXPORT_SYMBOL_GPL
(
devm_regmap_field_alloc
);
/**
* regmap_field_bulk_alloc() - Allocate and initialise a bulk register field.
*
* @regmap: regmap bank in which this register field is located.
* @rm_field: regmap register fields within the bank.
* @reg_field: Register fields within the bank.
* @num_fields: Number of register fields.
*
* The return value will be an -ENOMEM on error or zero for success.
* Newly allocated regmap_fields should be freed by calling
* regmap_field_bulk_free()
*/
int
regmap_field_bulk_alloc
(
struct
regmap
*
regmap
,
struct
regmap_field
**
rm_field
,
struct
reg_field
*
reg_field
,
int
num_fields
)
{
struct
regmap_field
*
rf
;
int
i
;
rf
=
kcalloc
(
num_fields
,
sizeof
(
*
rf
),
GFP_KERNEL
);
if
(
!
rf
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
num_fields
;
i
++
)
{
regmap_field_init
(
&
rf
[
i
],
regmap
,
reg_field
[
i
]);
rm_field
[
i
]
=
&
rf
[
i
];
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
regmap_field_bulk_alloc
);
/**
* devm_regmap_field_bulk_alloc() - Allocate and initialise a bulk register
* fields.
*
* @dev: Device that will be interacted with
* @regmap: regmap bank in which this register field is located.
* @rm_field: regmap register fields within the bank.
* @reg_field: Register fields within the bank.
* @num_fields: Number of register fields.
*
* The return value will be an -ENOMEM on error or zero for success.
* Newly allocated regmap_fields will be automatically freed by the
* device management code.
*/
int
devm_regmap_field_bulk_alloc
(
struct
device
*
dev
,
struct
regmap
*
regmap
,
struct
regmap_field
**
rm_field
,
struct
reg_field
*
reg_field
,
int
num_fields
)
{
struct
regmap_field
*
rf
;
int
i
;
rf
=
devm_kcalloc
(
dev
,
num_fields
,
sizeof
(
*
rf
),
GFP_KERNEL
);
if
(
!
rf
)
return
-
ENOMEM
;
for
(
i
=
0
;
i
<
num_fields
;
i
++
)
{
regmap_field_init
(
&
rf
[
i
],
regmap
,
reg_field
[
i
]);
rm_field
[
i
]
=
&
rf
[
i
];
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
devm_regmap_field_bulk_alloc
);
/**
* regmap_field_bulk_free() - Free register field allocated using
* regmap_field_bulk_alloc.
*
* @field: regmap fields which should be freed.
*/
void
regmap_field_bulk_free
(
struct
regmap_field
*
field
)
{
kfree
(
field
);
}
EXPORT_SYMBOL_GPL
(
regmap_field_bulk_free
);
/**
* devm_regmap_field_bulk_free() - Free a bulk register field allocated using
* devm_regmap_field_bulk_alloc.
*
* @dev: Device that will be interacted with
* @field: regmap field which should be freed.
*
* Free register field allocated using devm_regmap_field_bulk_alloc(). Usually
* drivers need not call this function, as the memory allocated via devm
* will be freed as per device-driver life-cycle.
*/
void
devm_regmap_field_bulk_free
(
struct
device
*
dev
,
struct
regmap_field
*
field
)
{
devm_kfree
(
dev
,
field
);
}
EXPORT_SYMBOL_GPL
(
devm_regmap_field_bulk_free
);
/**
* devm_regmap_field_free() - Free a register field allocated using
* devm_regmap_field_alloc.
...
...
@@ -1365,6 +1492,8 @@ void regmap_exit(struct regmap *map)
}
if
(
map
->
hwlock
)
hwspin_lock_free
(
map
->
hwlock
);
if
(
map
->
lock
==
regmap_lock_mutex
)
mutex_destroy
(
&
map
->
mutex
);
kfree_const
(
map
->
name
);
kfree
(
map
->
patch
);
kfree
(
map
);
...
...
@@ -2253,8 +2382,12 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map,
if
(
ret
!=
0
)
return
ret
;
if
(
regs
[
i
].
delay_us
)
udelay
(
regs
[
i
].
delay_us
);
if
(
regs
[
i
].
delay_us
)
{
if
(
map
->
can_sleep
)
fsleep
(
regs
[
i
].
delay_us
);
else
udelay
(
regs
[
i
].
delay_us
);
}
base
+=
n
;
n
=
0
;
...
...
@@ -2290,8 +2423,12 @@ static int _regmap_multi_reg_write(struct regmap *map,
if
(
ret
!=
0
)
return
ret
;
if
(
regs
[
i
].
delay_us
)
udelay
(
regs
[
i
].
delay_us
);
if
(
regs
[
i
].
delay_us
)
{
if
(
map
->
can_sleep
)
fsleep
(
regs
[
i
].
delay_us
);
else
udelay
(
regs
[
i
].
delay_us
);
}
}
return
0
;
}
...
...
include/linux/regmap.h
View file @
6e0545c4
...
...
@@ -342,6 +342,7 @@ typedef void (*regmap_unlock)(void *);
* @hwlock_id: Specify the hardware spinlock id.
* @hwlock_mode: The hardware spinlock mode, should be HWLOCK_IRQSTATE,
* HWLOCK_IRQ or 0.
* @can_sleep: Optional, specifies whether regmap operations can sleep.
*/
struct
regmap_config
{
const
char
*
name
;
...
...
@@ -398,6 +399,8 @@ struct regmap_config {
bool
use_hwlock
;
unsigned
int
hwlock_id
;
unsigned
int
hwlock_mode
;
bool
can_sleep
;
};
/**
...
...
@@ -567,6 +570,10 @@ struct regmap *__regmap_init_sdw(struct sdw_slave *sdw,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__regmap_init_spi_avmm
(
struct
spi_device
*
spi
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__devm_regmap_init
(
struct
device
*
dev
,
const
struct
regmap_bus
*
bus
,
...
...
@@ -620,6 +627,10 @@ struct regmap *__devm_regmap_init_i3c(struct i3c_device *i3c,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__devm_regmap_init_spi_avmm
(
struct
spi_device
*
spi
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
/*
* Wrapper for regmap_init macros to include a unique lockdep key and name
* for each call. No-op if CONFIG_LOCKDEP is not set.
...
...
@@ -806,6 +817,19 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
__regmap_lockdep_wrapper(__regmap_init_sdw, #config, \
sdw, config)
/**
* regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave
* to AVMM Bus Bridge
*
* @spi: Device that will be interacted with
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer
* to a struct regmap.
*/
#define regmap_init_spi_avmm(spi, config) \
__regmap_lockdep_wrapper(__regmap_init_spi_avmm, #config, \
spi, config)
/**
* devm_regmap_init() - Initialise managed register map
...
...
@@ -993,6 +1017,21 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
__regmap_lockdep_wrapper(__devm_regmap_init_i3c, #config, \
i3c, config)
/**
* devm_regmap_init_spi_avmm() - Initialize register map for Intel SPI Slave
* to AVMM Bus Bridge
*
* @spi: Device that will be interacted with
* @config: Configuration for register map
*
* The return value will be an ERR_PTR() on error or a valid pointer
* to a struct regmap. The map will be automatically freed by the
* device management code.
*/
#define devm_regmap_init_spi_avmm(spi, config) \
__regmap_lockdep_wrapper(__devm_regmap_init_spi_avmm, #config, \
spi, config)
int
regmap_mmio_attach_clk
(
struct
regmap
*
map
,
struct
clk
*
clk
);
void
regmap_mmio_detach_clk
(
struct
regmap
*
map
);
void
regmap_exit
(
struct
regmap
*
map
);
...
...
@@ -1150,6 +1189,17 @@ struct regmap_field *devm_regmap_field_alloc(struct device *dev,
struct
regmap
*
regmap
,
struct
reg_field
reg_field
);
void
devm_regmap_field_free
(
struct
device
*
dev
,
struct
regmap_field
*
field
);
int
regmap_field_bulk_alloc
(
struct
regmap
*
regmap
,
struct
regmap_field
**
rm_field
,
struct
reg_field
*
reg_field
,
int
num_fields
);
void
regmap_field_bulk_free
(
struct
regmap_field
*
field
);
int
devm_regmap_field_bulk_alloc
(
struct
device
*
dev
,
struct
regmap
*
regmap
,
struct
regmap_field
**
field
,
struct
reg_field
*
reg_field
,
int
num_fields
);
void
devm_regmap_field_bulk_free
(
struct
device
*
dev
,
struct
regmap_field
*
field
);
int
regmap_field_read
(
struct
regmap_field
*
field
,
unsigned
int
*
val
);
int
regmap_field_update_bits_base
(
struct
regmap_field
*
field
,
unsigned
int
mask
,
unsigned
int
val
,
...
...
@@ -1305,6 +1355,7 @@ struct regmap_irq_sub_irq_map {
* @mask_invert: Inverted mask register: cleared bits are masked out.
* @use_ack: Use @ack register even if it is zero.
* @ack_invert: Inverted ack register: cleared bits for ack.
* @clear_ack: Use this to set 1 and 0 or vice-versa to clear interrupts.
* @wake_invert: Inverted wake register: cleared bits are wake enabled.
* @type_invert: Invert the type flags.
* @type_in_mask: Use the mask registers for controlling irq type. For
...
...
@@ -1353,6 +1404,7 @@ struct regmap_irq_chip {
bool
mask_invert
:
1
;
bool
use_ack
:
1
;
bool
ack_invert
:
1
;
bool
clear_ack
:
1
;
bool
wake_invert
:
1
;
bool
runtime_pm
:
1
;
bool
type_invert
:
1
;
...
...
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