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
d17032f2
Commit
d17032f2
authored
Jun 14, 2021
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'regmap/for-5.14' into regmap-next
parents
614124be
0df02409
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
222 additions
and
8 deletions
+222
-8
drivers/base/regmap/Kconfig
drivers/base/regmap/Kconfig
+5
-1
drivers/base/regmap/Makefile
drivers/base/regmap/Makefile
+1
-0
drivers/base/regmap/regmap-i2c.c
drivers/base/regmap/regmap-i2c.c
+38
-7
drivers/base/regmap/regmap-irq.c
drivers/base/regmap/regmap-irq.c
+7
-0
drivers/base/regmap/regmap-mdio.c
drivers/base/regmap/regmap-mdio.c
+116
-0
drivers/base/regmap/regmap.c
drivers/base/regmap/regmap.c
+15
-0
include/linux/regmap.h
include/linux/regmap.h
+40
-0
No files found.
drivers/base/regmap/Kconfig
View file @
d17032f2
...
...
@@ -4,8 +4,9 @@
# 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_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM)
default y if (REGMAP_I2C || REGMAP_SPI || REGMAP_SPMI || REGMAP_W1 || REGMAP_AC97 || REGMAP_MMIO || REGMAP_IRQ || REGMAP_SOUNDWIRE || REGMAP_SOUNDWIRE_MBQ || REGMAP_SCCB || REGMAP_I3C || REGMAP_SPI_AVMM
|| REGMAP_MDIO
)
select IRQ_DOMAIN if REGMAP_IRQ
select MDIO_BUS if REGMAP_MDIO
bool
config REGCACHE_COMPRESSED
...
...
@@ -36,6 +37,9 @@ config REGMAP_W1
tristate
depends on W1
config REGMAP_MDIO
tristate
config REGMAP_MMIO
tristate
...
...
drivers/base/regmap/Makefile
View file @
d17032f2
...
...
@@ -19,3 +19,4 @@ obj-$(CONFIG_REGMAP_SOUNDWIRE_MBQ) += regmap-sdw-mbq.o
obj-$(CONFIG_REGMAP_SCCB)
+=
regmap-sccb.o
obj-$(CONFIG_REGMAP_I3C)
+=
regmap-i3c.o
obj-$(CONFIG_REGMAP_SPI_AVMM)
+=
regmap-spi-avmm.o
obj-$(CONFIG_REGMAP_MDIO)
+=
regmap-mdio.o
drivers/base/regmap/regmap-i2c.c
View file @
d17032f2
...
...
@@ -306,33 +306,64 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
static
const
struct
regmap_bus
*
regmap_get_i2c_bus
(
struct
i2c_client
*
i2c
,
const
struct
regmap_config
*
config
)
{
const
struct
i2c_adapter_quirks
*
quirks
;
const
struct
regmap_bus
*
bus
=
NULL
;
struct
regmap_bus
*
ret_bus
;
u16
max_read
=
0
,
max_write
=
0
;
if
(
i2c_check_functionality
(
i2c
->
adapter
,
I2C_FUNC_I2C
))
return
&
regmap_i2c
;
bus
=
&
regmap_i2c
;
else
if
(
config
->
val_bits
==
8
&&
config
->
reg_bits
==
8
&&
i2c_check_functionality
(
i2c
->
adapter
,
I2C_FUNC_SMBUS_I2C_BLOCK
))
return
&
regmap_i2c_smbus_i2c_block
;
bus
=
&
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
;
bus
=
&
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
))
switch
(
regmap_get_val_endian
(
&
i2c
->
dev
,
NULL
,
config
))
{
case
REGMAP_ENDIAN_LITTLE
:
return
&
regmap_smbus_word
;
bus
=
&
regmap_smbus_word
;
break
;
case
REGMAP_ENDIAN_BIG
:
return
&
regmap_smbus_word_swapped
;
bus
=
&
regmap_smbus_word_swapped
;
break
;
default:
/* everything else is not supported */
break
;
}
else
if
(
config
->
val_bits
==
8
&&
config
->
reg_bits
==
8
&&
i2c_check_functionality
(
i2c
->
adapter
,
I2C_FUNC_SMBUS_BYTE_DATA
))
return
&
regmap_smbus_byte
;
bus
=
&
regmap_smbus_byte
;
if
(
!
bus
)
return
ERR_PTR
(
-
ENOTSUPP
);
quirks
=
i2c
->
adapter
->
quirks
;
if
(
quirks
)
{
if
(
quirks
->
max_read_len
&&
(
bus
->
max_raw_read
==
0
||
bus
->
max_raw_read
>
quirks
->
max_read_len
))
max_read
=
quirks
->
max_read_len
;
if
(
quirks
->
max_write_len
&&
(
bus
->
max_raw_write
==
0
||
bus
->
max_raw_write
>
quirks
->
max_write_len
))
max_write
=
quirks
->
max_write_len
;
if
(
max_read
||
max_write
)
{
ret_bus
=
kmemdup
(
bus
,
sizeof
(
*
bus
),
GFP_KERNEL
);
if
(
!
ret_bus
)
return
ERR_PTR
(
-
ENOMEM
);
ret_bus
->
free_on_exit
=
true
;
ret_bus
->
max_raw_read
=
max_read
;
ret_bus
->
max_raw_write
=
max_write
;
bus
=
ret_bus
;
}
}
return
ERR_PTR
(
-
ENOTSUPP
)
;
return
bus
;
}
struct
regmap
*
__regmap_init_i2c
(
struct
i2c_client
*
i2c
,
...
...
drivers/base/regmap/regmap-irq.c
View file @
d17032f2
...
...
@@ -531,6 +531,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
}
}
if
(
chip
->
status_invert
)
for
(
i
=
0
;
i
<
data
->
chip
->
num_regs
;
i
++
)
data
->
status_buf
[
i
]
=
~
data
->
status_buf
[
i
];
/*
* Ignore masked IRQs and ack if we need to; we ack early so
* there is no race between handling and acknowleding the
...
...
@@ -800,6 +804,9 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode,
goto
err_alloc
;
}
if
(
chip
->
status_invert
)
d
->
status_buf
[
i
]
=
~
d
->
status_buf
[
i
];
if
(
d
->
status_buf
[
i
]
&&
(
chip
->
ack_base
||
chip
->
use_ack
))
{
reg
=
sub_irq_reg
(
d
,
d
->
chip
->
ack_base
,
i
);
if
(
chip
->
ack_invert
)
...
...
drivers/base/regmap/regmap-mdio.c
0 → 100644
View file @
d17032f2
// SPDX-License-Identifier: GPL-2.0
#include <linux/errno.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/regmap.h>
#define REGVAL_MASK GENMASK(15, 0)
#define REGNUM_C22_MASK GENMASK(4, 0)
/* Clause-45 mask includes the device type (5 bit) and actual register number (16 bit) */
#define REGNUM_C45_MASK GENMASK(20, 0)
static
int
regmap_mdio_read
(
struct
mdio_device
*
mdio_dev
,
u32
reg
,
unsigned
int
*
val
)
{
int
ret
;
ret
=
mdiobus_read
(
mdio_dev
->
bus
,
mdio_dev
->
addr
,
reg
);
if
(
ret
<
0
)
return
ret
;
*
val
=
ret
&
REGVAL_MASK
;
return
0
;
}
static
int
regmap_mdio_write
(
struct
mdio_device
*
mdio_dev
,
u32
reg
,
unsigned
int
val
)
{
return
mdiobus_write
(
mdio_dev
->
bus
,
mdio_dev
->
addr
,
reg
,
val
);
}
static
int
regmap_mdio_c22_read
(
void
*
context
,
unsigned
int
reg
,
unsigned
int
*
val
)
{
struct
mdio_device
*
mdio_dev
=
context
;
if
(
unlikely
(
reg
&
~
REGNUM_C22_MASK
))
return
-
ENXIO
;
return
regmap_mdio_read
(
mdio_dev
,
reg
,
val
);
}
static
int
regmap_mdio_c22_write
(
void
*
context
,
unsigned
int
reg
,
unsigned
int
val
)
{
struct
mdio_device
*
mdio_dev
=
context
;
if
(
unlikely
(
reg
&
~
REGNUM_C22_MASK
))
return
-
ENXIO
;
return
mdiobus_write
(
mdio_dev
->
bus
,
mdio_dev
->
addr
,
reg
,
val
);
}
static
const
struct
regmap_bus
regmap_mdio_c22_bus
=
{
.
reg_write
=
regmap_mdio_c22_write
,
.
reg_read
=
regmap_mdio_c22_read
,
};
static
int
regmap_mdio_c45_read
(
void
*
context
,
unsigned
int
reg
,
unsigned
int
*
val
)
{
struct
mdio_device
*
mdio_dev
=
context
;
if
(
unlikely
(
reg
&
~
REGNUM_C45_MASK
))
return
-
ENXIO
;
return
regmap_mdio_read
(
mdio_dev
,
MII_ADDR_C45
|
reg
,
val
);
}
static
int
regmap_mdio_c45_write
(
void
*
context
,
unsigned
int
reg
,
unsigned
int
val
)
{
struct
mdio_device
*
mdio_dev
=
context
;
if
(
unlikely
(
reg
&
~
REGNUM_C45_MASK
))
return
-
ENXIO
;
return
regmap_mdio_write
(
mdio_dev
,
MII_ADDR_C45
|
reg
,
val
);
}
static
const
struct
regmap_bus
regmap_mdio_c45_bus
=
{
.
reg_write
=
regmap_mdio_c45_write
,
.
reg_read
=
regmap_mdio_c45_read
,
};
struct
regmap
*
__regmap_init_mdio
(
struct
mdio_device
*
mdio_dev
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
)
{
const
struct
regmap_bus
*
bus
;
if
(
config
->
reg_bits
==
5
&&
config
->
val_bits
==
16
)
bus
=
&
regmap_mdio_c22_bus
;
else
if
(
config
->
reg_bits
==
21
&&
config
->
val_bits
==
16
)
bus
=
&
regmap_mdio_c45_bus
;
else
return
ERR_PTR
(
-
EOPNOTSUPP
);
return
__regmap_init
(
&
mdio_dev
->
dev
,
bus
,
mdio_dev
,
config
,
lock_key
,
lock_name
);
}
EXPORT_SYMBOL_GPL
(
__regmap_init_mdio
);
struct
regmap
*
__devm_regmap_init_mdio
(
struct
mdio_device
*
mdio_dev
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
)
{
const
struct
regmap_bus
*
bus
;
if
(
config
->
reg_bits
==
5
&&
config
->
val_bits
==
16
)
bus
=
&
regmap_mdio_c22_bus
;
else
if
(
config
->
reg_bits
==
21
&&
config
->
val_bits
==
16
)
bus
=
&
regmap_mdio_c45_bus
;
else
return
ERR_PTR
(
-
EOPNOTSUPP
);
return
__devm_regmap_init
(
&
mdio_dev
->
dev
,
bus
,
mdio_dev
,
config
,
lock_key
,
lock_name
);
}
EXPORT_SYMBOL_GPL
(
__devm_regmap_init_mdio
);
MODULE_AUTHOR
(
"Sander Vanheule <sander@svanheule.net>"
);
MODULE_DESCRIPTION
(
"Regmap MDIO Module"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/base/regmap/regmap.c
View file @
d17032f2
...
...
@@ -243,6 +243,16 @@ static void regmap_format_7_9_write(struct regmap *map,
*
out
=
cpu_to_be16
((
reg
<<
9
)
|
val
);
}
static
void
regmap_format_7_17_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
{
u8
*
out
=
map
->
work_buf
;
out
[
2
]
=
val
;
out
[
1
]
=
val
>>
8
;
out
[
0
]
=
(
val
>>
16
)
|
(
reg
<<
1
);
}
static
void
regmap_format_10_14_write
(
struct
regmap
*
map
,
unsigned
int
reg
,
unsigned
int
val
)
{
...
...
@@ -885,6 +895,9 @@ struct regmap *__regmap_init(struct device *dev,
case
9
:
map
->
format
.
format_write
=
regmap_format_7_9_write
;
break
;
case
17
:
map
->
format
.
format_write
=
regmap_format_7_17_write
;
break
;
default:
goto
err_hwlock
;
}
...
...
@@ -1496,6 +1509,8 @@ void regmap_exit(struct regmap *map)
mutex_destroy
(
&
map
->
mutex
);
kfree_const
(
map
->
name
);
kfree
(
map
->
patch
);
if
(
map
->
bus
&&
map
->
bus
->
free_on_exit
)
kfree
(
map
->
bus
);
kfree
(
map
);
}
EXPORT_SYMBOL_GPL
(
regmap_exit
);
...
...
include/linux/regmap.h
View file @
d17032f2
...
...
@@ -27,6 +27,7 @@ struct device_node;
struct
i2c_client
;
struct
i3c_device
;
struct
irq_domain
;
struct
mdio_device
;
struct
slim_device
;
struct
spi_device
;
struct
spmi_device
;
...
...
@@ -502,6 +503,7 @@ typedef void (*regmap_hw_free_context)(void *context);
* DEFAULT, BIG is assumed.
* @max_raw_read: Max raw read size that can be used on the bus.
* @max_raw_write: Max raw write size that can be used on the bus.
* @free_on_exit: kfree this on exit of regmap
*/
struct
regmap_bus
{
bool
fast_io
;
...
...
@@ -519,6 +521,7 @@ struct regmap_bus {
enum
regmap_endian
val_format_endian_default
;
size_t
max_raw_read
;
size_t
max_raw_write
;
bool
free_on_exit
;
};
/*
...
...
@@ -538,6 +541,10 @@ struct regmap *__regmap_init_i2c(struct i2c_client *i2c,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__regmap_init_mdio
(
struct
mdio_device
*
mdio_dev
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__regmap_init_sccb
(
struct
i2c_client
*
i2c
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
...
...
@@ -594,6 +601,10 @@ struct regmap *__devm_regmap_init_i2c(struct i2c_client *i2c,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__devm_regmap_init_mdio
(
struct
mdio_device
*
mdio_dev
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
const
char
*
lock_name
);
struct
regmap
*
__devm_regmap_init_sccb
(
struct
i2c_client
*
i2c
,
const
struct
regmap_config
*
config
,
struct
lock_class_key
*
lock_key
,
...
...
@@ -697,6 +708,19 @@ int regmap_attach_dev(struct device *dev, struct regmap *map,
__regmap_lockdep_wrapper(__regmap_init_i2c, #config, \
i2c, config)
/**
* regmap_init_mdio() - Initialise register map
*
* @mdio_dev: 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_mdio(mdio_dev, config) \
__regmap_lockdep_wrapper(__regmap_init_mdio, #config, \
mdio_dev, config)
/**
* regmap_init_sccb() - Initialise register map
*
...
...
@@ -888,6 +912,20 @@ bool regmap_ac97_default_volatile(struct device *dev, unsigned int reg);
__regmap_lockdep_wrapper(__devm_regmap_init_i2c, #config, \
i2c, config)
/**
* devm_regmap_init_mdio() - Initialise managed register map
*
* @mdio_dev: 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 regmap will be automatically freed by the
* device management code.
*/
#define devm_regmap_init_mdio(mdio_dev, config) \
__regmap_lockdep_wrapper(__devm_regmap_init_mdio, #config, \
mdio_dev, config)
/**
* devm_regmap_init_sccb() - Initialise managed register map
*
...
...
@@ -1411,6 +1449,7 @@ struct regmap_irq_sub_irq_map {
* @not_fixed_stride: Used when chip peripherals are not laid out with fixed
* stride. Must be used with sub_reg_offsets containing the
* offsets to each peripheral.
* @status_invert: Inverted status register: cleared bits are active interrupts.
* @runtime_pm: Hold a runtime PM lock on the device when accessing it.
*
* @num_regs: Number of registers in each control bank.
...
...
@@ -1463,6 +1502,7 @@ struct regmap_irq_chip {
bool
type_in_mask
:
1
;
bool
clear_on_unmask
:
1
;
bool
not_fixed_stride
:
1
;
bool
status_invert
:
1
;
int
num_regs
;
...
...
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