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
9b98f92c
Commit
9b98f92c
authored
May 29, 2020
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regmap/for-5.8' into regmap-next
parents
4bcc6a0b
93b92992
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
222 additions
and
55 deletions
+222
-55
drivers/base/regmap/regmap-i2c.c
drivers/base/regmap/regmap-i2c.c
+61
-0
drivers/base/regmap/regmap-irq.c
drivers/base/regmap/regmap-irq.c
+68
-16
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+23
-0
include/linux/regmap.h
include/linux/regmap.h
+70
-39
No files found.
drivers/base/regmap/regmap-i2c.c
View file @
9b98f92c
...
...
@@ -246,6 +246,63 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
.
max_raw_write
=
I2C_SMBUS_BLOCK_MAX
,
};
static
int
regmap_i2c_smbus_i2c_write_reg16
(
void
*
context
,
const
void
*
data
,
size_t
count
)
{
struct
device
*
dev
=
context
;
struct
i2c_client
*
i2c
=
to_i2c_client
(
dev
);
if
(
count
<
2
)
return
-
EINVAL
;
count
--
;
return
i2c_smbus_write_i2c_block_data
(
i2c
,
((
u8
*
)
data
)[
0
],
count
,
(
u8
*
)
data
+
1
);
}
static
int
regmap_i2c_smbus_i2c_read_reg16
(
void
*
context
,
const
void
*
reg
,
size_t
reg_size
,
void
*
val
,
size_t
val_size
)
{
struct
device
*
dev
=
context
;
struct
i2c_client
*
i2c
=
to_i2c_client
(
dev
);
int
ret
,
count
,
len
=
val_size
;
if
(
reg_size
!=
2
)
return
-
EINVAL
;
ret
=
i2c_smbus_write_byte_data
(
i2c
,
((
u16
*
)
reg
)[
0
]
&
0xff
,
((
u16
*
)
reg
)[
0
]
>>
8
);
if
(
ret
<
0
)
return
ret
;
count
=
0
;
do
{
/* Current Address Read */
ret
=
i2c_smbus_read_byte
(
i2c
);
if
(
ret
<
0
)
break
;
*
((
u8
*
)
val
++
)
=
ret
;
count
++
;
len
--
;
}
while
(
len
>
0
);
if
(
count
==
val_size
)
return
0
;
else
if
(
ret
<
0
)
return
ret
;
else
return
-
EIO
;
}
static
const
struct
regmap_bus
regmap_i2c_smbus_i2c_block_reg16
=
{
.
write
=
regmap_i2c_smbus_i2c_write_reg16
,
.
read
=
regmap_i2c_smbus_i2c_read_reg16
,
.
max_raw_read
=
I2C_SMBUS_BLOCK_MAX
,
.
max_raw_write
=
I2C_SMBUS_BLOCK_MAX
,
};
static
const
struct
regmap_bus
*
regmap_get_i2c_bus
(
struct
i2c_client
*
i2c
,
const
struct
regmap_config
*
config
)
{
...
...
@@ -255,6 +312,10 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
i2c_check_functionality
(
i2c
->
adapter
,
I2C_FUNC_SMBUS_I2C_BLOCK
))
return
&
regmap_i2c_smbus_i2c_block
;
else
if
(
config
->
val_bits
==
8
&&
config
->
reg_bits
==
16
&&
i2c_check_functionality
(
i2c
->
adapter
,
I2C_FUNC_SMBUS_I2C_BLOCK
))
return
&
regmap_i2c_smbus_i2c_block_reg16
;
else
if
(
config
->
val_bits
==
16
&&
config
->
reg_bits
==
8
&&
i2c_check_functionality
(
i2c
->
adapter
,
I2C_FUNC_SMBUS_WORD_DATA
))
...
...
drivers/base/regmap/regmap-irq.c
View file @
9b98f92c
...
...
@@ -541,8 +541,9 @@ static const struct irq_domain_ops regmap_domain_ops = {
};
/**
* regmap_add_irq_chip() - Use standard regmap IRQ controller handling
* regmap_add_irq_chip
_np
() - Use standard regmap IRQ controller handling
*
* @np: The device_node where the IRQ domain should be added to.
* @map: The regmap for the device.
* @irq: The IRQ the device uses to signal interrupts.
* @irq_flags: The IRQF_ flags to use for the primary interrupt.
...
...
@@ -556,9 +557,10 @@ static const struct irq_domain_ops regmap_domain_ops = {
* register cache. The chip driver is responsible for restoring the
* register values used by the IRQ controller over suspend and resume.
*/
int
regmap_add_irq_chip
(
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
)
int
regmap_add_irq_chip_np
(
struct
device_node
*
np
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
)
{
struct
regmap_irq_chip_data
*
d
;
int
i
;
...
...
@@ -769,12 +771,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
}
if
(
irq_base
)
d
->
domain
=
irq_domain_add_legacy
(
map
->
dev
->
of_node
,
chip
->
num_irqs
,
irq_base
,
0
,
&
regmap_domain_ops
,
d
);
d
->
domain
=
irq_domain_add_legacy
(
np
,
chip
->
num_irqs
,
irq_base
,
0
,
&
regmap_domain_ops
,
d
);
else
d
->
domain
=
irq_domain_add_linear
(
map
->
dev
->
of_node
,
chip
->
num_irqs
,
d
->
domain
=
irq_domain_add_linear
(
np
,
chip
->
num_irqs
,
&
regmap_domain_ops
,
d
);
if
(
!
d
->
domain
)
{
dev_err
(
map
->
dev
,
"Failed to create IRQ domain
\n
"
);
...
...
@@ -808,6 +808,30 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
kfree
(
d
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
regmap_add_irq_chip_np
);
/**
* regmap_add_irq_chip() - Use standard regmap IRQ controller handling
*
* @map: The regmap for the device.
* @irq: The IRQ the device uses to signal interrupts.
* @irq_flags: The IRQF_ flags to use for the primary interrupt.
* @irq_base: Allocate at specific IRQ number if irq_base > 0.
* @chip: Configuration for the interrupt controller.
* @data: Runtime data structure for the controller, allocated on success.
*
* Returns 0 on success or an errno on failure.
*
* This is the same as regmap_add_irq_chip_np, except that the device
* node of the regmap is used.
*/
int
regmap_add_irq_chip
(
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
)
{
return
regmap_add_irq_chip_np
(
map
->
dev
->
of_node
,
map
,
irq
,
irq_flags
,
irq_base
,
chip
,
data
);
}
EXPORT_SYMBOL_GPL
(
regmap_add_irq_chip
);
/**
...
...
@@ -875,9 +899,10 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
}
/**
* devm_regmap_add_irq_chip
() - Resource manager regmap_add_irq_chi
p()
* devm_regmap_add_irq_chip
_np() - Resource manager regmap_add_irq_chip_n
p()
*
* @dev: The device pointer on which irq_chip belongs to.
* @np: The device_node where the IRQ domain should be added to.
* @map: The regmap for the device.
* @irq: The IRQ the device uses to signal interrupts
* @irq_flags: The IRQF_ flags to use for the primary interrupt.
...
...
@@ -890,10 +915,11 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
* The ®map_irq_chip_data will be automatically released when the device is
* unbound.
*/
int
devm_regmap_add_irq_chip
(
struct
device
*
dev
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
)
int
devm_regmap_add_irq_chip_np
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
)
{
struct
regmap_irq_chip_data
**
ptr
,
*
d
;
int
ret
;
...
...
@@ -903,8 +929,8 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
if
(
!
ptr
)
return
-
ENOMEM
;
ret
=
regmap_add_irq_chip
(
map
,
irq
,
irq_flags
,
irq_base
,
chip
,
&
d
);
ret
=
regmap_add_irq_chip
_np
(
np
,
map
,
irq
,
irq_flags
,
irq_base
,
chip
,
&
d
);
if
(
ret
<
0
)
{
devres_free
(
ptr
);
return
ret
;
...
...
@@ -915,6 +941,32 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
*
data
=
d
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
devm_regmap_add_irq_chip_np
);
/**
* devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
*
* @dev: The device pointer on which irq_chip belongs to.
* @map: The regmap for the device.
* @irq: The IRQ the device uses to signal interrupts
* @irq_flags: The IRQF_ flags to use for the primary interrupt.
* @irq_base: Allocate at specific IRQ number if irq_base > 0.
* @chip: Configuration for the interrupt controller.
* @data: Runtime data structure for the controller, allocated on success
*
* Returns 0 on success or an errno on failure.
*
* The ®map_irq_chip_data will be automatically released when the device is
* unbound.
*/
int
devm_regmap_add_irq_chip
(
struct
device
*
dev
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
)
{
return
devm_regmap_add_irq_chip_np
(
dev
,
map
->
dev
->
of_node
,
map
,
irq
,
irq_flags
,
irq_base
,
chip
,
data
);
}
EXPORT_SYMBOL_GPL
(
devm_regmap_add_irq_chip
);
/**
...
...
drivers/base/regmap/regmap.c
View file @
9b98f92c
...
...
@@ -827,6 +827,7 @@ struct regmap *__regmap_init(struct device *dev,
}
else
if
(
!
bus
->
read
||
!
bus
->
write
)
{
map
->
reg_read
=
_regmap_bus_reg_read
;
map
->
reg_write
=
_regmap_bus_reg_write
;
map
->
reg_update_bits
=
bus
->
reg_update_bits
;
map
->
defer_caching
=
false
;
goto
skip_format_initialization
;
...
...
@@ -2936,6 +2937,28 @@ int regmap_update_bits_base(struct regmap *map, unsigned int reg,
}
EXPORT_SYMBOL_GPL
(
regmap_update_bits_base
);
/**
* regmap_test_bits() - Check if all specified bits are set in a register.
*
* @map: Register map to operate on
* @reg: Register to read from
* @bits: Bits to test
*
* Returns -1 if the underlying regmap_read() fails, 0 if at least one of the
* tested bits is not set and 1 if all tested bits are set.
*/
int
regmap_test_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
)
{
unsigned
int
val
,
ret
;
ret
=
regmap_read
(
map
,
reg
,
&
val
);
if
(
ret
)
return
ret
;
return
(
val
&
bits
)
==
bits
;
}
EXPORT_SYMBOL_GPL
(
regmap_test_bits
);
void
regmap_async_complete_cb
(
struct
regmap_async
*
async
,
int
ret
)
{
struct
regmap
*
map
=
async
->
map
;
...
...
include/linux/regmap.h
View file @
9b98f92c
...
...
@@ -17,10 +17,12 @@
#include <linux/err.h>
#include <linux/bug.h>
#include <linux/lockdep.h>
#include <linux/iopoll.h>
struct
module
;
struct
clk
;
struct
device
;
struct
device_node
;
struct
i2c_client
;
struct
i3c_device
;
struct
irq_domain
;
...
...
@@ -71,6 +73,13 @@ struct reg_sequence {
unsigned
int
delay_us
;
};
#define REG_SEQ(_reg, _def, _delay_us) { \
.reg = _reg, \
.def = _def, \
.delay_us = _delay_us, \
}
#define REG_SEQ0(_reg, _def) REG_SEQ(_reg, _def, 0)
#define regmap_update_bits(map, reg, mask, val) \
regmap_update_bits_base(map, reg, mask, val, NULL, false, false)
#define regmap_update_bits_async(map, reg, mask, val)\
...
...
@@ -122,26 +131,10 @@ struct reg_sequence {
*/
#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \
({ \
u64 __timeout_us = (timeout_us); \
unsigned long __sleep_us = (sleep_us); \
ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
int __ret; \
might_sleep_if(__sleep_us); \
for (;;) { \
__ret = regmap_read((map), (addr), &(val)); \
if (__ret) \
break; \
if (cond) \
break; \
if ((__timeout_us) && \
ktime_compare(ktime_get(), __timeout) > 0) { \
__ret = regmap_read((map), (addr), &(val)); \
break; \
} \
if (__sleep_us) \
usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
} \
__ret ?: ((cond) ? 0 : -ETIMEDOUT); \
int __ret, __tmp; \
__tmp = read_poll_timeout(regmap_read, __ret, __ret || (cond), \
sleep_us, timeout_us, false, (map), (addr), &(val)); \
__ret ?: __tmp; \
})
/**
...
...
@@ -209,25 +202,10 @@ struct reg_sequence {
*/
#define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \
({ \
u64 __timeout_us = (timeout_us); \
unsigned long __sleep_us = (sleep_us); \
ktime_t timeout = ktime_add_us(ktime_get(), __timeout_us); \
int pollret; \
might_sleep_if(__sleep_us); \
for (;;) { \
pollret = regmap_field_read((field), &(val)); \
if (pollret) \
break; \
if (cond) \
break; \
if (__timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \
pollret = regmap_field_read((field), &(val)); \
break; \
} \
if (__sleep_us) \
usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
} \
pollret ?: ((cond) ? 0 : -ETIMEDOUT); \
int __ret, __tmp; \
__tmp = read_poll_timeout(regmap_field_read, __ret, __ret || (cond), \
sleep_us, timeout_us, false, (field), &(val)); \
__ret ?: __tmp; \
})
#ifdef CONFIG_REGMAP
...
...
@@ -1111,6 +1089,21 @@ bool regmap_reg_in_ranges(unsigned int reg,
const
struct
regmap_range
*
ranges
,
unsigned
int
nranges
);
static
inline
int
regmap_set_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
)
{
return
regmap_update_bits_base
(
map
,
reg
,
bits
,
bits
,
NULL
,
false
,
false
);
}
static
inline
int
regmap_clear_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
)
{
return
regmap_update_bits_base
(
map
,
reg
,
bits
,
0
,
NULL
,
false
,
false
);
}
int
regmap_test_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
);
/**
* struct reg_field - Description of an register field
*
...
...
@@ -1134,6 +1127,14 @@ struct reg_field {
.msb = _msb, \
}
#define REG_FIELD_ID(_reg, _lsb, _msb, _size, _offset) { \
.reg = _reg, \
.lsb = _lsb, \
.msb = _msb, \
.id_size = _size, \
.id_offset = _offset, \
}
struct
regmap_field
*
regmap_field_alloc
(
struct
regmap
*
regmap
,
struct
reg_field
reg_field
);
void
regmap_field_free
(
struct
regmap_field
*
field
);
...
...
@@ -1310,12 +1311,21 @@ struct regmap_irq_chip_data;
int
regmap_add_irq_chip
(
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
);
int
regmap_add_irq_chip_np
(
struct
device_node
*
np
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
);
void
regmap_del_irq_chip
(
int
irq
,
struct
regmap_irq_chip_data
*
data
);
int
devm_regmap_add_irq_chip
(
struct
device
*
dev
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
);
int
devm_regmap_add_irq_chip_np
(
struct
device
*
dev
,
struct
device_node
*
np
,
struct
regmap
*
map
,
int
irq
,
int
irq_flags
,
int
irq_base
,
const
struct
regmap_irq_chip
*
chip
,
struct
regmap_irq_chip_data
**
data
);
void
devm_regmap_del_irq_chip
(
struct
device
*
dev
,
int
irq
,
struct
regmap_irq_chip_data
*
data
);
...
...
@@ -1410,6 +1420,27 @@ static inline int regmap_update_bits_base(struct regmap *map, unsigned int reg,
return
-
EINVAL
;
}
static
inline
int
regmap_set_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
int
regmap_clear_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
int
regmap_test_bits
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
bits
)
{
WARN_ONCE
(
1
,
"regmap API is disabled"
);
return
-
EINVAL
;
}
static
inline
int
regmap_field_update_bits_base
(
struct
regmap_field
*
field
,
unsigned
int
mask
,
unsigned
int
val
,
bool
*
change
,
bool
async
,
bool
force
)
...
...
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