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
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