mirror of https://gitee.com/openkylin/linux.git
regmap: Updates for v5.8
This has been a very active release for the regmap API for some reason, a lot of it due to new devices with odd requirements that can sensibly be handled here. - Add support for buses implementing a custom reg_update_bits() method in case the bus has a native operation for this. - Support 16 bit register addresses in SMBus. - Allow customization of the device attached to regmap-irq. - Helpers for bitfield operations and per-port field initializations. -----BEGIN PGP SIGNATURE----- iQFHBAABCgAxFiEEreZoqmdXGLWf4p/qJNaLcl1Uh9AFAl7U4SkTHGJyb29uaWVA a2VybmVsLm9yZwAKCRAk1otyXVSH0EmYB/4jBeaFTowIhas+dXx/+P9Yooe0/3h9 wihte3ZcHIf0ox02nPEd3W/Uf1KpVd5gmHDHJOI0aPCQLk+s4+V9JaaPN4LwIJwL ttl3RP9Bco50BgjMYj3gNuoIya9tjI7bxvblii76IgFb6PjneQURQHc2Rqx72cj5 PVDLKRfkYLJWGdYzRoImKHLAeH6hQTm3juIajq7EaqdA5lXtad4SFp86k0iOhd4l L16Bcgvs0alt3Lq4Sm49gU2mAxfIh88CpoxGIOkTr+W0L9EP5HeB0hCr67BsRXcq DFe0XBgjFJj+hxD4ojBJuvaAm54jcSOiMSKGRhyPsZsSXmzYmylkGYvM =7YCr -----END PGP SIGNATURE----- Merge tag 'regmap-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap Pull regmap updates from Mark Brown: "This has been a very active release for the regmap API for some reason, a lot of it due to new devices with odd requirements that can sensibly be handled here. - Add support for buses implementing a custom reg_update_bits() method in case the bus has a native operation for this. - Support 16 bit register addresses in SMBus. - Allow customization of the device attached to regmap-irq. - Helpers for bitfield operations and per-port field initializations" * tag 'regmap-v5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap: regmap: provide helpers for simple bit operations regmap: add helper for per-port regfield initialization regmap-i2c: add 16-bit width registers support regmap: Simplify implementation of the regmap_field_read_poll_timeout() macro regmap: Simplify implementation of the regmap_read_poll_timeout() macro regmap: add reg_sequence helpers regmap-irq: make it possible to add irq_chip do a specific device node regmap: Add bus reg_update_bits() support regmap: debugfs: check count when read regmap file
This commit is contained in:
commit
213fd09e1a
|
@ -227,6 +227,9 @@ static ssize_t regmap_read_debugfs(struct regmap *map, unsigned int from,
|
||||||
if (*ppos < 0 || !count)
|
if (*ppos < 0 || !count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
|
||||||
|
count = PAGE_SIZE << (MAX_ORDER - 1);
|
||||||
|
|
||||||
buf = kmalloc(count, GFP_KERNEL);
|
buf = kmalloc(count, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -371,6 +374,9 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file,
|
||||||
if (*ppos < 0 || !count)
|
if (*ppos < 0 || !count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (count > (PAGE_SIZE << (MAX_ORDER - 1)))
|
||||||
|
count = PAGE_SIZE << (MAX_ORDER - 1);
|
||||||
|
|
||||||
buf = kmalloc(count, GFP_KERNEL);
|
buf = kmalloc(count, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -246,6 +246,63 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block = {
|
||||||
.max_raw_write = I2C_SMBUS_BLOCK_MAX,
|
.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,
|
static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
|
||||||
const struct regmap_config *config)
|
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_check_functionality(i2c->adapter,
|
||||||
I2C_FUNC_SMBUS_I2C_BLOCK))
|
I2C_FUNC_SMBUS_I2C_BLOCK))
|
||||||
return ®map_i2c_smbus_i2c_block;
|
return ®map_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 ®map_i2c_smbus_i2c_block_reg16;
|
||||||
else if (config->val_bits == 16 && config->reg_bits == 8 &&
|
else if (config->val_bits == 16 && config->reg_bits == 8 &&
|
||||||
i2c_check_functionality(i2c->adapter,
|
i2c_check_functionality(i2c->adapter,
|
||||||
I2C_FUNC_SMBUS_WORD_DATA))
|
I2C_FUNC_SMBUS_WORD_DATA))
|
||||||
|
|
|
@ -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.
|
* @map: The regmap for the device.
|
||||||
* @irq: The IRQ the device uses to signal interrupts.
|
* @irq: The IRQ the device uses to signal interrupts.
|
||||||
* @irq_flags: The IRQF_ flags to use for the primary interrupt.
|
* @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 cache. The chip driver is responsible for restoring the
|
||||||
* register values used by the IRQ controller over suspend and resume.
|
* 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 regmap_add_irq_chip_np(struct device_node *np, struct regmap *map, int irq,
|
||||||
int irq_base, const struct regmap_irq_chip *chip,
|
int irq_flags, int irq_base,
|
||||||
struct regmap_irq_chip_data **data)
|
const struct regmap_irq_chip *chip,
|
||||||
|
struct regmap_irq_chip_data **data)
|
||||||
{
|
{
|
||||||
struct regmap_irq_chip_data *d;
|
struct regmap_irq_chip_data *d;
|
||||||
int i;
|
int i;
|
||||||
|
@ -769,12 +771,10 @@ int regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (irq_base)
|
if (irq_base)
|
||||||
d->domain = irq_domain_add_legacy(map->dev->of_node,
|
d->domain = irq_domain_add_legacy(np, chip->num_irqs, irq_base,
|
||||||
chip->num_irqs, irq_base, 0,
|
0, ®map_domain_ops, d);
|
||||||
®map_domain_ops, d);
|
|
||||||
else
|
else
|
||||||
d->domain = irq_domain_add_linear(map->dev->of_node,
|
d->domain = irq_domain_add_linear(np, chip->num_irqs,
|
||||||
chip->num_irqs,
|
|
||||||
®map_domain_ops, d);
|
®map_domain_ops, d);
|
||||||
if (!d->domain) {
|
if (!d->domain) {
|
||||||
dev_err(map->dev, "Failed to create IRQ domain\n");
|
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);
|
kfree(d);
|
||||||
return ret;
|
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);
|
EXPORT_SYMBOL_GPL(regmap_add_irq_chip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -874,6 +898,51 @@ static int devm_regmap_irq_chip_match(struct device *dev, void *res, void *data)
|
||||||
return *r == data;
|
return *r == data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* devm_regmap_add_irq_chip_np() - Resource manager regmap_add_irq_chip_np()
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
* @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_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;
|
||||||
|
|
||||||
|
ptr = devres_alloc(devm_regmap_irq_chip_release, sizeof(*ptr),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!ptr)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = regmap_add_irq_chip_np(np, map, irq, irq_flags, irq_base,
|
||||||
|
chip, &d);
|
||||||
|
if (ret < 0) {
|
||||||
|
devres_free(ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr = d;
|
||||||
|
devres_add(dev, ptr);
|
||||||
|
*data = d;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip_np);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
|
* devm_regmap_add_irq_chip() - Resource manager regmap_add_irq_chip()
|
||||||
*
|
*
|
||||||
|
@ -895,25 +964,8 @@ int devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
|
||||||
const struct regmap_irq_chip *chip,
|
const struct regmap_irq_chip *chip,
|
||||||
struct regmap_irq_chip_data **data)
|
struct regmap_irq_chip_data **data)
|
||||||
{
|
{
|
||||||
struct regmap_irq_chip_data **ptr, *d;
|
return devm_regmap_add_irq_chip_np(dev, map->dev->of_node, map, irq,
|
||||||
int ret;
|
irq_flags, irq_base, chip, data);
|
||||||
|
|
||||||
ptr = devres_alloc(devm_regmap_irq_chip_release, sizeof(*ptr),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!ptr)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
ret = regmap_add_irq_chip(map, irq, irq_flags, irq_base,
|
|
||||||
chip, &d);
|
|
||||||
if (ret < 0) {
|
|
||||||
devres_free(ptr);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
*ptr = d;
|
|
||||||
devres_add(dev, ptr);
|
|
||||||
*data = d;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip);
|
EXPORT_SYMBOL_GPL(devm_regmap_add_irq_chip);
|
||||||
|
|
||||||
|
|
|
@ -827,6 +827,7 @@ struct regmap *__regmap_init(struct device *dev,
|
||||||
} else if (!bus->read || !bus->write) {
|
} else if (!bus->read || !bus->write) {
|
||||||
map->reg_read = _regmap_bus_reg_read;
|
map->reg_read = _regmap_bus_reg_read;
|
||||||
map->reg_write = _regmap_bus_reg_write;
|
map->reg_write = _regmap_bus_reg_write;
|
||||||
|
map->reg_update_bits = bus->reg_update_bits;
|
||||||
|
|
||||||
map->defer_caching = false;
|
map->defer_caching = false;
|
||||||
goto skip_format_initialization;
|
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);
|
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)
|
void regmap_async_complete_cb(struct regmap_async *async, int ret)
|
||||||
{
|
{
|
||||||
struct regmap *map = async->map;
|
struct regmap *map = async->map;
|
||||||
|
|
|
@ -17,10 +17,12 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/lockdep.h>
|
#include <linux/lockdep.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
|
||||||
struct module;
|
struct module;
|
||||||
struct clk;
|
struct clk;
|
||||||
struct device;
|
struct device;
|
||||||
|
struct device_node;
|
||||||
struct i2c_client;
|
struct i2c_client;
|
||||||
struct i3c_device;
|
struct i3c_device;
|
||||||
struct irq_domain;
|
struct irq_domain;
|
||||||
|
@ -71,6 +73,13 @@ struct reg_sequence {
|
||||||
unsigned int delay_us;
|
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) \
|
#define regmap_update_bits(map, reg, mask, val) \
|
||||||
regmap_update_bits_base(map, reg, mask, val, NULL, false, false)
|
regmap_update_bits_base(map, reg, mask, val, NULL, false, false)
|
||||||
#define regmap_update_bits_async(map, reg, mask, val)\
|
#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) \
|
#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_us) \
|
||||||
({ \
|
({ \
|
||||||
u64 __timeout_us = (timeout_us); \
|
int __ret, __tmp; \
|
||||||
unsigned long __sleep_us = (sleep_us); \
|
__tmp = read_poll_timeout(regmap_read, __ret, __ret || (cond), \
|
||||||
ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
|
sleep_us, timeout_us, false, (map), (addr), &(val)); \
|
||||||
int __ret; \
|
__ret ?: __tmp; \
|
||||||
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); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -209,25 +202,10 @@ struct reg_sequence {
|
||||||
*/
|
*/
|
||||||
#define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \
|
#define regmap_field_read_poll_timeout(field, val, cond, sleep_us, timeout_us) \
|
||||||
({ \
|
({ \
|
||||||
u64 __timeout_us = (timeout_us); \
|
int __ret, __tmp; \
|
||||||
unsigned long __sleep_us = (sleep_us); \
|
__tmp = read_poll_timeout(regmap_field_read, __ret, __ret || (cond), \
|
||||||
ktime_t timeout = ktime_add_us(ktime_get(), __timeout_us); \
|
sleep_us, timeout_us, false, (field), &(val)); \
|
||||||
int pollret; \
|
__ret ?: __tmp; \
|
||||||
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); \
|
|
||||||
})
|
})
|
||||||
|
|
||||||
#ifdef CONFIG_REGMAP
|
#ifdef CONFIG_REGMAP
|
||||||
|
@ -1111,6 +1089,21 @@ bool regmap_reg_in_ranges(unsigned int reg,
|
||||||
const struct regmap_range *ranges,
|
const struct regmap_range *ranges,
|
||||||
unsigned int nranges);
|
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
|
* struct reg_field - Description of an register field
|
||||||
*
|
*
|
||||||
|
@ -1134,6 +1127,14 @@ struct reg_field {
|
||||||
.msb = _msb, \
|
.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 regmap_field *regmap_field_alloc(struct regmap *regmap,
|
||||||
struct reg_field reg_field);
|
struct reg_field reg_field);
|
||||||
void regmap_field_free(struct regmap_field *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 regmap_add_irq_chip(struct regmap *map, int irq, int irq_flags,
|
||||||
int irq_base, const struct regmap_irq_chip *chip,
|
int irq_base, const struct regmap_irq_chip *chip,
|
||||||
struct regmap_irq_chip_data **data);
|
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);
|
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 devm_regmap_add_irq_chip(struct device *dev, struct regmap *map, int irq,
|
||||||
int irq_flags, int irq_base,
|
int irq_flags, int irq_base,
|
||||||
const struct regmap_irq_chip *chip,
|
const struct regmap_irq_chip *chip,
|
||||||
struct regmap_irq_chip_data **data);
|
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,
|
void devm_regmap_del_irq_chip(struct device *dev, int irq,
|
||||||
struct regmap_irq_chip_data *data);
|
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;
|
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,
|
static inline int regmap_field_update_bits_base(struct regmap_field *field,
|
||||||
unsigned int mask, unsigned int val,
|
unsigned int mask, unsigned int val,
|
||||||
bool *change, bool async, bool force)
|
bool *change, bool async, bool force)
|
||||||
|
|
Loading…
Reference in New Issue