Merge 5.4.272 into android11-5.4-lts
Changes in 5.4.272 lan78xx: Fix white space and style issues lan78xx: Add missing return code checks lan78xx: Fix partial packet errors on suspend/resume lan78xx: Fix race conditions in suspend/resume handling net: lan78xx: fix runtime PM count underflow on link stop ixgbe: {dis, en}able irqs in ixgbe_txrx_ring_{dis, en}able geneve: make sure to pull inner header in geneve_rx() net: ice: Fix potential NULL pointer dereference in ice_bridge_setlink() net/ipv6: avoid possible UAF in ip6_route_mpath_notify() net/rds: fix WARNING in rds_conn_connect_if_down netfilter: nft_ct: fix l3num expectations with inet pseudo family netfilter: nf_conntrack_h323: Add protection for bmp length out of range netrom: Fix a data-race around sysctl_netrom_default_path_quality netrom: Fix a data-race around sysctl_netrom_obsolescence_count_initialiser netrom: Fix data-races around sysctl_netrom_network_ttl_initialiser netrom: Fix a data-race around sysctl_netrom_transport_timeout netrom: Fix a data-race around sysctl_netrom_transport_maximum_tries netrom: Fix a data-race around sysctl_netrom_transport_acknowledge_delay netrom: Fix a data-race around sysctl_netrom_transport_busy_delay netrom: Fix a data-race around sysctl_netrom_transport_requested_window_size netrom: Fix a data-race around sysctl_netrom_transport_no_activity_timeout netrom: Fix a data-race around sysctl_netrom_routing_control netrom: Fix a data-race around sysctl_netrom_link_fails_count netrom: Fix data-races around sysctl_net_busy_read selftests: mm: fix map_hugetlb failure on 64K page size systems um: allow not setting extra rpaths in the linux binary serial: max310x: Use devm_clk_get_optional() to get the input clock serial: max310x: Try to get crystal clock rate from property serial: max310x: fail probe if clock crystal is unstable serial: max310x: Make use of device properties serial: max310x: use regmap methods for SPI batch operations serial: max310x: use a separate regmap for each port serial: max310x: prevent infinite while() loop in port startup Input: i8042 - fix strange behavior of touchpad on Clevo NS70PU hv_netvsc: Make netvsc/VF binding check both MAC and serial number hv_netvsc: use netif_is_bond_master() instead of open code hv_netvsc: Register VF in netvsc_probe if NET_DEVICE_REGISTER missed y2038: rusage: use __kernel_old_timeval getrusage: add the "signal_struct *sig" local variable getrusage: move thread_group_cputime_adjusted() outside of lock_task_sighand() getrusage: use __for_each_thread() getrusage: use sig->stats_lock rather than lock_task_sighand() serial: max310x: Unprepare and disable clock in error path regmap: allow to define reg_update_bits for no bus configuration regmap: Add bulk read/write callbacks into regmap_config serial: max310x: make accessing revision id interface-agnostic serial: max310x: implement I2C support serial: max310x: fix IO data corruption in batched operations arm64: dts: qcom: add PDC interrupt controller for SDM845 arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts Linux 5.4.272 Change-Id: Ia3f453dd3f080776d3fdd46b1ea58c6554a70fd6 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
ee2f1c68f1
Makefile
arch
drivers
base/regmap
input/serio
net
tty/serial
include
kernel
net
ipv6
netfilter
netrom
rds
tools/testing/selftests/vm
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 5
|
||||
PATCHLEVEL = 4
|
||||
SUBLEVEL = 271
|
||||
SUBLEVEL = 272
|
||||
EXTRAVERSION =
|
||||
NAME = Kleptomaniac Octopus
|
||||
|
||||
|
@ -963,7 +963,7 @@ put_tv32(struct timeval32 __user *o, struct timespec64 *i)
|
||||
}
|
||||
|
||||
static inline long
|
||||
put_tv_to_tv32(struct timeval32 __user *o, struct timeval *i)
|
||||
put_tv_to_tv32(struct timeval32 __user *o, struct __kernel_old_timeval *i)
|
||||
{
|
||||
return copy_to_user(o, &(struct timeval32){
|
||||
.tv_sec = i->tv_sec,
|
||||
|
@ -85,6 +85,19 @@ config LD_SCRIPT_DYN
|
||||
depends on !LD_SCRIPT_STATIC
|
||||
select MODULE_REL_CRCS if MODVERSIONS
|
||||
|
||||
config LD_SCRIPT_DYN_RPATH
|
||||
bool "set rpath in the binary" if EXPERT
|
||||
default y
|
||||
depends on LD_SCRIPT_DYN
|
||||
help
|
||||
Add /lib (and /lib64 for 64-bit) to the linux binary's rpath
|
||||
explicitly.
|
||||
|
||||
You may need to turn this off if compiling for nix systems
|
||||
that have their libraries in random /nix directories and
|
||||
might otherwise unexpected use libraries from /lib or /lib64
|
||||
instead of the desired ones.
|
||||
|
||||
config HOSTFS
|
||||
tristate "Host filesystem"
|
||||
help
|
||||
|
@ -118,7 +118,8 @@ archprepare:
|
||||
$(Q)$(MAKE) $(build)=$(HOST_DIR)/um include/generated/user_constants.h
|
||||
|
||||
LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static
|
||||
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib $(call cc-option, -no-pie)
|
||||
LINK-$(CONFIG_LD_SCRIPT_DYN) += $(call cc-option, -no-pie)
|
||||
LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib
|
||||
|
||||
CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,) \
|
||||
$(call cc-option, -fno-stack-protector,) \
|
||||
|
@ -44,7 +44,7 @@ ELF_FORMAT := elf64-x86-64
|
||||
|
||||
# Not on all 64-bit distros /lib is a symlink to /lib64. PLD is an example.
|
||||
|
||||
LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64
|
||||
LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib64
|
||||
LINK-y += -m64
|
||||
|
||||
endif
|
||||
|
@ -104,6 +104,10 @@ struct regmap {
|
||||
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
|
||||
int (*reg_update_bits)(void *context, unsigned int reg,
|
||||
unsigned int mask, unsigned int val);
|
||||
/* Bulk read/write */
|
||||
int (*read)(void *context, const void *reg_buf, size_t reg_size,
|
||||
void *val_buf, size_t val_size);
|
||||
int (*write)(void *context, const void *data, size_t count);
|
||||
|
||||
bool defer_caching;
|
||||
|
||||
|
@ -771,12 +771,15 @@ struct regmap *__regmap_init(struct device *dev,
|
||||
map->reg_stride_order = ilog2(map->reg_stride);
|
||||
else
|
||||
map->reg_stride_order = -1;
|
||||
map->use_single_read = config->use_single_read || !bus || !bus->read;
|
||||
map->use_single_write = config->use_single_write || !bus || !bus->write;
|
||||
map->can_multi_write = config->can_multi_write && bus && bus->write;
|
||||
map->use_single_read = config->use_single_read || !(config->read || (bus && bus->read));
|
||||
map->use_single_write = config->use_single_write || !(config->write || (bus && bus->write));
|
||||
map->can_multi_write = config->can_multi_write && (config->write || (bus && bus->write));
|
||||
if (bus) {
|
||||
map->max_raw_read = bus->max_raw_read;
|
||||
map->max_raw_write = bus->max_raw_write;
|
||||
} else if (config->max_raw_read && config->max_raw_write) {
|
||||
map->max_raw_read = config->max_raw_read;
|
||||
map->max_raw_write = config->max_raw_write;
|
||||
}
|
||||
map->dev = dev;
|
||||
map->bus = bus;
|
||||
@ -810,9 +813,19 @@ struct regmap *__regmap_init(struct device *dev,
|
||||
map->read_flag_mask = bus->read_flag_mask;
|
||||
}
|
||||
|
||||
if (!bus) {
|
||||
if (config && config->read && config->write) {
|
||||
map->reg_read = _regmap_bus_read;
|
||||
|
||||
/* Bulk read/write */
|
||||
map->read = config->read;
|
||||
map->write = config->write;
|
||||
|
||||
reg_endian = REGMAP_ENDIAN_NATIVE;
|
||||
val_endian = REGMAP_ENDIAN_NATIVE;
|
||||
} else if (!bus) {
|
||||
map->reg_read = config->reg_read;
|
||||
map->reg_write = config->reg_write;
|
||||
map->reg_update_bits = config->reg_update_bits;
|
||||
|
||||
map->defer_caching = false;
|
||||
goto skip_format_initialization;
|
||||
@ -825,10 +838,13 @@ struct regmap *__regmap_init(struct device *dev,
|
||||
} else {
|
||||
map->reg_read = _regmap_bus_read;
|
||||
map->reg_update_bits = bus->reg_update_bits;
|
||||
}
|
||||
/* Bulk read/write */
|
||||
map->read = bus->read;
|
||||
map->write = bus->write;
|
||||
|
||||
reg_endian = regmap_get_reg_endian(bus, config);
|
||||
val_endian = regmap_get_val_endian(dev, bus, config);
|
||||
reg_endian = regmap_get_reg_endian(bus, config);
|
||||
val_endian = regmap_get_val_endian(dev, bus, config);
|
||||
}
|
||||
|
||||
switch (config->reg_bits + map->reg_shift) {
|
||||
case 2:
|
||||
@ -1479,8 +1495,6 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
WARN_ON(!map->bus);
|
||||
|
||||
/* Check for unwritable or noinc registers in range
|
||||
* before we start
|
||||
*/
|
||||
@ -1562,7 +1576,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
||||
val = work_val;
|
||||
}
|
||||
|
||||
if (map->async && map->bus->async_write) {
|
||||
if (map->async && map->bus && map->bus->async_write) {
|
||||
struct regmap_async *async;
|
||||
|
||||
trace_regmap_async_write_start(map, reg, val_len);
|
||||
@ -1630,10 +1644,10 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
||||
* write.
|
||||
*/
|
||||
if (val == work_val)
|
||||
ret = map->bus->write(map->bus_context, map->work_buf,
|
||||
map->format.reg_bytes +
|
||||
map->format.pad_bytes +
|
||||
val_len);
|
||||
ret = map->write(map->bus_context, map->work_buf,
|
||||
map->format.reg_bytes +
|
||||
map->format.pad_bytes +
|
||||
val_len);
|
||||
else if (map->bus->gather_write)
|
||||
ret = map->bus->gather_write(map->bus_context, map->work_buf,
|
||||
map->format.reg_bytes +
|
||||
@ -1652,7 +1666,7 @@ static int _regmap_raw_write_impl(struct regmap *map, unsigned int reg,
|
||||
memcpy(buf, map->work_buf, map->format.reg_bytes);
|
||||
memcpy(buf + map->format.reg_bytes + map->format.pad_bytes,
|
||||
val, val_len);
|
||||
ret = map->bus->write(map->bus_context, buf, len);
|
||||
ret = map->write(map->bus_context, buf, len);
|
||||
|
||||
kfree(buf);
|
||||
} else if (ret != 0 && !map->cache_bypass && map->format.parse_val) {
|
||||
@ -1709,7 +1723,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
|
||||
struct regmap_range_node *range;
|
||||
struct regmap *map = context;
|
||||
|
||||
WARN_ON(!map->bus || !map->format.format_write);
|
||||
WARN_ON(!map->format.format_write);
|
||||
|
||||
range = _regmap_range_lookup(map, reg);
|
||||
if (range) {
|
||||
@ -1722,8 +1736,7 @@ static int _regmap_bus_formatted_write(void *context, unsigned int reg,
|
||||
|
||||
trace_regmap_hw_write_start(map, reg, 1);
|
||||
|
||||
ret = map->bus->write(map->bus_context, map->work_buf,
|
||||
map->format.buf_size);
|
||||
ret = map->write(map->bus_context, map->work_buf, map->format.buf_size);
|
||||
|
||||
trace_regmap_hw_write_done(map, reg, 1);
|
||||
|
||||
@ -1743,7 +1756,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
|
||||
{
|
||||
struct regmap *map = context;
|
||||
|
||||
WARN_ON(!map->bus || !map->format.format_val);
|
||||
WARN_ON(!map->format.format_val);
|
||||
|
||||
map->format.format_val(map->work_buf + map->format.reg_bytes
|
||||
+ map->format.pad_bytes, val, 0);
|
||||
@ -1757,7 +1770,7 @@ static int _regmap_bus_raw_write(void *context, unsigned int reg,
|
||||
|
||||
static inline void *_regmap_map_get_context(struct regmap *map)
|
||||
{
|
||||
return (map->bus) ? map : map->bus_context;
|
||||
return (map->bus || (!map->bus && map->read)) ? map : map->bus_context;
|
||||
}
|
||||
|
||||
int _regmap_write(struct regmap *map, unsigned int reg,
|
||||
@ -2166,7 +2179,7 @@ static int _regmap_raw_multi_reg_write(struct regmap *map,
|
||||
u8 = buf;
|
||||
*u8 |= map->write_flag_mask;
|
||||
|
||||
ret = map->bus->write(map->bus_context, buf, len);
|
||||
ret = map->write(map->bus_context, buf, len);
|
||||
|
||||
kfree(buf);
|
||||
|
||||
@ -2464,9 +2477,7 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
||||
struct regmap_range_node *range;
|
||||
int ret;
|
||||
|
||||
WARN_ON(!map->bus);
|
||||
|
||||
if (!map->bus || !map->bus->read)
|
||||
if (!map->read)
|
||||
return -EINVAL;
|
||||
|
||||
range = _regmap_range_lookup(map, reg);
|
||||
@ -2482,9 +2493,9 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
||||
map->read_flag_mask);
|
||||
trace_regmap_hw_read_start(map, reg, val_len / map->format.val_bytes);
|
||||
|
||||
ret = map->bus->read(map->bus_context, map->work_buf,
|
||||
map->format.reg_bytes + map->format.pad_bytes,
|
||||
val, val_len);
|
||||
ret = map->read(map->bus_context, map->work_buf,
|
||||
map->format.reg_bytes + map->format.pad_bytes,
|
||||
val, val_len);
|
||||
|
||||
trace_regmap_hw_read_done(map, reg, val_len / map->format.val_bytes);
|
||||
|
||||
@ -2595,8 +2606,6 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
||||
unsigned int v;
|
||||
int ret, i;
|
||||
|
||||
if (!map->bus)
|
||||
return -EINVAL;
|
||||
if (val_len % map->format.val_bytes)
|
||||
return -EINVAL;
|
||||
if (!IS_ALIGNED(reg, map->reg_stride))
|
||||
@ -2611,7 +2620,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
|
||||
size_t chunk_count, chunk_bytes;
|
||||
size_t chunk_regs = val_count;
|
||||
|
||||
if (!map->bus->read) {
|
||||
if (!map->read) {
|
||||
ret = -ENOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
@ -2671,7 +2680,7 @@ EXPORT_SYMBOL_GPL(regmap_raw_read);
|
||||
* @val: Pointer to data buffer
|
||||
* @val_len: Length of output buffer in bytes.
|
||||
*
|
||||
* The regmap API usually assumes that bulk bus read operations will read a
|
||||
* The regmap API usually assumes that bulk read operations will read a
|
||||
* range of registers. Some devices have certain registers for which a read
|
||||
* operation read will read from an internal FIFO.
|
||||
*
|
||||
@ -2689,10 +2698,6 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg,
|
||||
size_t read_len;
|
||||
int ret;
|
||||
|
||||
if (!map->bus)
|
||||
return -EINVAL;
|
||||
if (!map->bus->read)
|
||||
return -ENOTSUPP;
|
||||
if (val_len % map->format.val_bytes)
|
||||
return -EINVAL;
|
||||
if (!IS_ALIGNED(reg, map->reg_stride))
|
||||
@ -2806,7 +2811,7 @@ int regmap_bulk_read(struct regmap *map, unsigned int reg, void *val,
|
||||
if (val_count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (map->bus && map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {
|
||||
if (map->format.parse_inplace && (vol || map->cache_type == REGCACHE_NONE)) {
|
||||
ret = regmap_raw_read(map, reg, val, val_bytes * val_count);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
@ -1179,6 +1179,12 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
|
||||
SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP |
|
||||
SERIO_QUIRK_NOPNP)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NS5x_7xPU"),
|
||||
},
|
||||
.driver_data = (void *)(SERIO_QUIRK_NOAUX)
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "NJ50_70CU"),
|
||||
|
@ -4594,6 +4594,8 @@ ice_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
|
||||
pf_sw = pf->first_sw;
|
||||
/* find the attribute in the netlink message */
|
||||
br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
|
||||
if (!br_spec)
|
||||
return -EINVAL;
|
||||
|
||||
nla_for_each_nested(attr, br_spec, rem) {
|
||||
__u16 mode;
|
||||
|
@ -2938,8 +2938,8 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
|
||||
static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
|
||||
u64 qmask)
|
||||
{
|
||||
u32 mask;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u32 mask;
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case ixgbe_mac_82598EB:
|
||||
@ -10528,6 +10528,44 @@ static void ixgbe_reset_rxr_stats(struct ixgbe_ring *rx_ring)
|
||||
memset(&rx_ring->rx_stats, 0, sizeof(rx_ring->rx_stats));
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_irq_disable_single - Disable single IRQ vector
|
||||
* @adapter: adapter structure
|
||||
* @ring: ring index
|
||||
**/
|
||||
static void ixgbe_irq_disable_single(struct ixgbe_adapter *adapter, u32 ring)
|
||||
{
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
u64 qmask = BIT_ULL(ring);
|
||||
u32 mask;
|
||||
|
||||
switch (adapter->hw.mac.type) {
|
||||
case ixgbe_mac_82598EB:
|
||||
mask = qmask & IXGBE_EIMC_RTX_QUEUE;
|
||||
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask);
|
||||
break;
|
||||
case ixgbe_mac_82599EB:
|
||||
case ixgbe_mac_X540:
|
||||
case ixgbe_mac_X550:
|
||||
case ixgbe_mac_X550EM_x:
|
||||
case ixgbe_mac_x550em_a:
|
||||
mask = (qmask & 0xFFFFFFFF);
|
||||
if (mask)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(0), mask);
|
||||
mask = (qmask >> 32);
|
||||
if (mask)
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EIMS_EX(1), mask);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
IXGBE_WRITE_FLUSH(&adapter->hw);
|
||||
if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
|
||||
synchronize_irq(adapter->msix_entries[ring].vector);
|
||||
else
|
||||
synchronize_irq(adapter->pdev->irq);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_txrx_ring_disable - Disable Rx/Tx/XDP Tx rings
|
||||
* @adapter: adapter structure
|
||||
@ -10544,6 +10582,11 @@ void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring)
|
||||
tx_ring = adapter->tx_ring[ring];
|
||||
xdp_ring = adapter->xdp_ring[ring];
|
||||
|
||||
ixgbe_irq_disable_single(adapter, ring);
|
||||
|
||||
/* Rx/Tx/XDP Tx share the same napi context. */
|
||||
napi_disable(&rx_ring->q_vector->napi);
|
||||
|
||||
ixgbe_disable_txr(adapter, tx_ring);
|
||||
if (xdp_ring)
|
||||
ixgbe_disable_txr(adapter, xdp_ring);
|
||||
@ -10552,9 +10595,6 @@ void ixgbe_txrx_ring_disable(struct ixgbe_adapter *adapter, int ring)
|
||||
if (xdp_ring)
|
||||
synchronize_rcu();
|
||||
|
||||
/* Rx/Tx/XDP Tx share the same napi context. */
|
||||
napi_disable(&rx_ring->q_vector->napi);
|
||||
|
||||
ixgbe_clean_tx_ring(tx_ring);
|
||||
if (xdp_ring)
|
||||
ixgbe_clean_tx_ring(xdp_ring);
|
||||
@ -10582,9 +10622,6 @@ void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring)
|
||||
tx_ring = adapter->tx_ring[ring];
|
||||
xdp_ring = adapter->xdp_ring[ring];
|
||||
|
||||
/* Rx/Tx/XDP Tx share the same napi context. */
|
||||
napi_enable(&rx_ring->q_vector->napi);
|
||||
|
||||
ixgbe_configure_tx_ring(adapter, tx_ring);
|
||||
if (xdp_ring)
|
||||
ixgbe_configure_tx_ring(adapter, xdp_ring);
|
||||
@ -10593,6 +10630,11 @@ void ixgbe_txrx_ring_enable(struct ixgbe_adapter *adapter, int ring)
|
||||
clear_bit(__IXGBE_TX_DISABLED, &tx_ring->state);
|
||||
if (xdp_ring)
|
||||
clear_bit(__IXGBE_TX_DISABLED, &xdp_ring->state);
|
||||
|
||||
/* Rx/Tx/XDP Tx share the same napi context. */
|
||||
napi_enable(&rx_ring->q_vector->napi);
|
||||
ixgbe_irq_enable_queues(adapter, BIT_ULL(ring));
|
||||
IXGBE_WRITE_FLUSH(&adapter->hw);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,7 +215,7 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
|
||||
struct metadata_dst *tun_dst = NULL;
|
||||
struct pcpu_sw_netstats *stats;
|
||||
unsigned int len;
|
||||
int err = 0;
|
||||
int nh, err = 0;
|
||||
void *oiph;
|
||||
|
||||
if (ip_tunnel_collect_metadata() || gs->collect_md) {
|
||||
@ -259,9 +259,23 @@ static void geneve_rx(struct geneve_dev *geneve, struct geneve_sock *gs,
|
||||
goto drop;
|
||||
}
|
||||
|
||||
oiph = skb_network_header(skb);
|
||||
/* Save offset of outer header relative to skb->head,
|
||||
* because we are going to reset the network header to the inner header
|
||||
* and might change skb->head.
|
||||
*/
|
||||
nh = skb_network_header(skb) - skb->head;
|
||||
|
||||
skb_reset_network_header(skb);
|
||||
|
||||
if (!pskb_inet_may_pull(skb)) {
|
||||
DEV_STATS_INC(geneve->dev, rx_length_errors);
|
||||
DEV_STATS_INC(geneve->dev, rx_errors);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Get the outer header. */
|
||||
oiph = skb->head + nh;
|
||||
|
||||
if (geneve_get_sk_family(gs) == AF_INET)
|
||||
err = IP_ECN_decapsulate(oiph, skb);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
|
@ -43,6 +43,10 @@
|
||||
#define LINKCHANGE_INT (2 * HZ)
|
||||
#define VF_TAKEOVER_INT (HZ / 10)
|
||||
|
||||
/* Macros to define the context of vf registration */
|
||||
#define VF_REG_IN_PROBE 1
|
||||
#define VF_REG_IN_NOTIFIER 2
|
||||
|
||||
static unsigned int ring_size __ro_after_init = 128;
|
||||
module_param(ring_size, uint, 0444);
|
||||
MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
|
||||
@ -2037,7 +2041,7 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb)
|
||||
}
|
||||
|
||||
static int netvsc_vf_join(struct net_device *vf_netdev,
|
||||
struct net_device *ndev)
|
||||
struct net_device *ndev, int context)
|
||||
{
|
||||
struct net_device_context *ndev_ctx = netdev_priv(ndev);
|
||||
int ret;
|
||||
@ -2060,7 +2064,11 @@ static int netvsc_vf_join(struct net_device *vf_netdev,
|
||||
goto upper_link_failed;
|
||||
}
|
||||
|
||||
schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT);
|
||||
/* If this registration is called from probe context vf_takeover
|
||||
* is taken care of later in probe itself.
|
||||
*/
|
||||
if (context == VF_REG_IN_NOTIFIER)
|
||||
schedule_delayed_work(&ndev_ctx->vf_takeover, VF_TAKEOVER_INT);
|
||||
|
||||
call_netdevice_notifiers(NETDEV_JOIN, vf_netdev);
|
||||
|
||||
@ -2153,8 +2161,17 @@ static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev)
|
||||
if (!ndev_ctx->vf_alloc)
|
||||
continue;
|
||||
|
||||
if (ndev_ctx->vf_serial == serial)
|
||||
return hv_get_drvdata(ndev_ctx->device_ctx);
|
||||
if (ndev_ctx->vf_serial != serial)
|
||||
continue;
|
||||
|
||||
ndev = hv_get_drvdata(ndev_ctx->device_ctx);
|
||||
if (ndev->addr_len != vf_netdev->addr_len ||
|
||||
memcmp(ndev->perm_addr, vf_netdev->perm_addr,
|
||||
ndev->addr_len) != 0)
|
||||
continue;
|
||||
|
||||
return ndev;
|
||||
|
||||
}
|
||||
|
||||
/* Fallback path to check synthetic vf with help of mac addr.
|
||||
@ -2189,7 +2206,7 @@ static int netvsc_prepare_bonding(struct net_device *vf_netdev)
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int netvsc_register_vf(struct net_device *vf_netdev)
|
||||
static int netvsc_register_vf(struct net_device *vf_netdev, int context)
|
||||
{
|
||||
struct net_device_context *net_device_ctx;
|
||||
struct netvsc_device *netvsc_dev;
|
||||
@ -2228,7 +2245,7 @@ static int netvsc_register_vf(struct net_device *vf_netdev)
|
||||
|
||||
netdev_info(ndev, "VF registering: %s\n", vf_netdev->name);
|
||||
|
||||
if (netvsc_vf_join(vf_netdev, ndev) != 0)
|
||||
if (netvsc_vf_join(vf_netdev, ndev, context) != 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
dev_hold(vf_netdev);
|
||||
@ -2292,10 +2309,31 @@ static int netvsc_unregister_vf(struct net_device *vf_netdev)
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int check_dev_is_matching_vf(struct net_device *event_ndev)
|
||||
{
|
||||
/* Skip NetVSC interfaces */
|
||||
if (event_ndev->netdev_ops == &device_ops)
|
||||
return -ENODEV;
|
||||
|
||||
/* Avoid non-Ethernet type devices */
|
||||
if (event_ndev->type != ARPHRD_ETHER)
|
||||
return -ENODEV;
|
||||
|
||||
/* Avoid Vlan dev with same MAC registering as VF */
|
||||
if (is_vlan_dev(event_ndev))
|
||||
return -ENODEV;
|
||||
|
||||
/* Avoid Bonding master dev with same MAC registering as VF */
|
||||
if (netif_is_bond_master(event_ndev))
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netvsc_probe(struct hv_device *dev,
|
||||
const struct hv_vmbus_device_id *dev_id)
|
||||
{
|
||||
struct net_device *net = NULL;
|
||||
struct net_device *net = NULL, *vf_netdev;
|
||||
struct net_device_context *net_device_ctx;
|
||||
struct netvsc_device_info *device_info = NULL;
|
||||
struct netvsc_device *nvdev;
|
||||
@ -2396,6 +2434,30 @@ static int netvsc_probe(struct hv_device *dev,
|
||||
}
|
||||
|
||||
list_add(&net_device_ctx->list, &netvsc_dev_list);
|
||||
|
||||
/* When the hv_netvsc driver is unloaded and reloaded, the
|
||||
* NET_DEVICE_REGISTER for the vf device is replayed before probe
|
||||
* is complete. This is because register_netdevice_notifier() gets
|
||||
* registered before vmbus_driver_register() so that callback func
|
||||
* is set before probe and we don't miss events like NETDEV_POST_INIT
|
||||
* So, in this section we try to register the matching vf device that
|
||||
* is present as a netdevice, knowing that its register call is not
|
||||
* processed in the netvsc_netdev_notifier(as probing is progress and
|
||||
* get_netvsc_byslot fails).
|
||||
*/
|
||||
for_each_netdev(dev_net(net), vf_netdev) {
|
||||
ret = check_dev_is_matching_vf(vf_netdev);
|
||||
if (ret != 0)
|
||||
continue;
|
||||
|
||||
if (net != get_netvsc_byslot(vf_netdev))
|
||||
continue;
|
||||
|
||||
netvsc_prepare_bonding(vf_netdev);
|
||||
netvsc_register_vf(vf_netdev, VF_REG_IN_PROBE);
|
||||
__netvsc_vf_setup(net, vf_netdev);
|
||||
break;
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
kfree(device_info);
|
||||
@ -2488,29 +2550,17 @@ static int netvsc_netdev_event(struct notifier_block *this,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *event_dev = netdev_notifier_info_to_dev(ptr);
|
||||
int ret = 0;
|
||||
|
||||
/* Skip our own events */
|
||||
if (event_dev->netdev_ops == &device_ops)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Avoid non-Ethernet type devices */
|
||||
if (event_dev->type != ARPHRD_ETHER)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Avoid Vlan dev with same MAC registering as VF */
|
||||
if (is_vlan_dev(event_dev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* Avoid Bonding master dev with same MAC registering as VF */
|
||||
if ((event_dev->priv_flags & IFF_BONDING) &&
|
||||
(event_dev->flags & IFF_MASTER))
|
||||
ret = check_dev_is_matching_vf(event_dev);
|
||||
if (ret != 0)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_POST_INIT:
|
||||
return netvsc_prepare_bonding(event_dev);
|
||||
case NETDEV_REGISTER:
|
||||
return netvsc_register_vf(event_dev);
|
||||
return netvsc_register_vf(event_dev, VF_REG_IN_NOTIFIER);
|
||||
case NETDEV_UNREGISTER:
|
||||
return netvsc_unregister_vf(event_dev);
|
||||
case NETDEV_UP:
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -344,6 +344,7 @@ config SERIAL_MAX310X
|
||||
depends on SPI_MASTER
|
||||
select SERIAL_CORE
|
||||
select REGMAP_SPI if SPI_MASTER
|
||||
select REGMAP_I2C if I2C
|
||||
help
|
||||
This selects support for an advanced UART from Maxim (Dallas).
|
||||
Supported ICs are MAX3107, MAX3108, MAX3109, MAX14830.
|
||||
|
@ -14,9 +14,10 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/property.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial.h>
|
||||
@ -72,7 +73,8 @@
|
||||
#define MAX310X_GLOBALCMD_REG MAX310X_REG_1F /* Global Command (WO) */
|
||||
|
||||
/* Extended registers */
|
||||
#define MAX310X_REVID_EXTREG MAX310X_REG_05 /* Revision ID */
|
||||
#define MAX310X_SPI_REVID_EXTREG MAX310X_REG_05 /* Revision ID */
|
||||
#define MAX310X_I2C_REVID_EXTREG (0x25) /* Revision ID */
|
||||
|
||||
/* IRQ register bits */
|
||||
#define MAX310X_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */
|
||||
@ -235,6 +237,10 @@
|
||||
#define MAX310x_REV_MASK (0xf8)
|
||||
#define MAX310X_WRITE_BIT 0x80
|
||||
|
||||
/* Port startup definitions */
|
||||
#define MAX310X_PORT_STARTUP_WAIT_RETRIES 20 /* Number of retries */
|
||||
#define MAX310X_PORT_STARTUP_WAIT_DELAY_MS 10 /* Delay between retries */
|
||||
|
||||
/* Crystal-related definitions */
|
||||
#define MAX310X_XTAL_WAIT_RETRIES 20 /* Number of retries */
|
||||
#define MAX310X_XTAL_WAIT_DELAY_MS 10 /* Delay between retries */
|
||||
@ -249,7 +255,17 @@
|
||||
#define MAX14830_BRGCFG_CLKDIS_BIT (1 << 6) /* Clock Disable */
|
||||
#define MAX14830_REV_ID (0xb0)
|
||||
|
||||
struct max310x_if_cfg {
|
||||
int (*extended_reg_enable)(struct device *dev, bool enable);
|
||||
|
||||
unsigned int rev_id_reg;
|
||||
};
|
||||
|
||||
struct max310x_devtype {
|
||||
struct {
|
||||
unsigned short min;
|
||||
unsigned short max;
|
||||
} slave_addr;
|
||||
char name[9];
|
||||
int nr;
|
||||
u8 mode1;
|
||||
@ -262,16 +278,16 @@ struct max310x_one {
|
||||
struct work_struct tx_work;
|
||||
struct work_struct md_work;
|
||||
struct work_struct rs_work;
|
||||
struct regmap *regmap;
|
||||
|
||||
u8 wr_header;
|
||||
u8 rd_header;
|
||||
u8 rx_buf[MAX310X_FIFO_SIZE];
|
||||
};
|
||||
#define to_max310x_port(_port) \
|
||||
container_of(_port, struct max310x_one, port)
|
||||
|
||||
struct max310x_port {
|
||||
struct max310x_devtype *devtype;
|
||||
const struct max310x_devtype *devtype;
|
||||
const struct max310x_if_cfg *if_cfg;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
#ifdef CONFIG_GPIOLIB
|
||||
@ -293,26 +309,26 @@ static DECLARE_BITMAP(max310x_lines, MAX310X_UART_NRMAX);
|
||||
|
||||
static u8 max310x_port_read(struct uart_port *port, u8 reg)
|
||||
{
|
||||
struct max310x_port *s = dev_get_drvdata(port->dev);
|
||||
struct max310x_one *one = to_max310x_port(port);
|
||||
unsigned int val = 0;
|
||||
|
||||
regmap_read(s->regmap, port->iobase + reg, &val);
|
||||
regmap_read(one->regmap, reg, &val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static void max310x_port_write(struct uart_port *port, u8 reg, u8 val)
|
||||
{
|
||||
struct max310x_port *s = dev_get_drvdata(port->dev);
|
||||
struct max310x_one *one = to_max310x_port(port);
|
||||
|
||||
regmap_write(s->regmap, port->iobase + reg, val);
|
||||
regmap_write(one->regmap, reg, val);
|
||||
}
|
||||
|
||||
static void max310x_port_update(struct uart_port *port, u8 reg, u8 mask, u8 val)
|
||||
{
|
||||
struct max310x_port *s = dev_get_drvdata(port->dev);
|
||||
struct max310x_one *one = to_max310x_port(port);
|
||||
|
||||
regmap_update_bits(s->regmap, port->iobase + reg, mask, val);
|
||||
regmap_update_bits(one->regmap, reg, mask, val);
|
||||
}
|
||||
|
||||
static int max3107_detect(struct device *dev)
|
||||
@ -361,13 +377,12 @@ static int max3109_detect(struct device *dev)
|
||||
unsigned int val = 0;
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(s->regmap, MAX310X_GLOBALCMD_REG,
|
||||
MAX310X_EXTREG_ENBL);
|
||||
ret = s->if_cfg->extended_reg_enable(dev, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_read(s->regmap, MAX310X_REVID_EXTREG, &val);
|
||||
regmap_write(s->regmap, MAX310X_GLOBALCMD_REG, MAX310X_EXTREG_DSBL);
|
||||
regmap_read(s->regmap, s->if_cfg->rev_id_reg, &val);
|
||||
s->if_cfg->extended_reg_enable(dev, false);
|
||||
if (((val & MAX310x_REV_MASK) != MAX3109_REV_ID)) {
|
||||
dev_err(dev,
|
||||
"%s ID 0x%02x does not match\n", s->devtype->name, val);
|
||||
@ -392,13 +407,12 @@ static int max14830_detect(struct device *dev)
|
||||
unsigned int val = 0;
|
||||
int ret;
|
||||
|
||||
ret = regmap_write(s->regmap, MAX310X_GLOBALCMD_REG,
|
||||
MAX310X_EXTREG_ENBL);
|
||||
ret = s->if_cfg->extended_reg_enable(dev, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_read(s->regmap, MAX310X_REVID_EXTREG, &val);
|
||||
regmap_write(s->regmap, MAX310X_GLOBALCMD_REG, MAX310X_EXTREG_DSBL);
|
||||
regmap_read(s->regmap, s->if_cfg->rev_id_reg, &val);
|
||||
s->if_cfg->extended_reg_enable(dev, false);
|
||||
if (((val & MAX310x_REV_MASK) != MAX14830_REV_ID)) {
|
||||
dev_err(dev,
|
||||
"%s ID 0x%02x does not match\n", s->devtype->name, val);
|
||||
@ -423,6 +437,10 @@ static const struct max310x_devtype max3107_devtype = {
|
||||
.mode1 = MAX310X_MODE1_AUTOSLEEP_BIT | MAX310X_MODE1_IRQSEL_BIT,
|
||||
.detect = max3107_detect,
|
||||
.power = max310x_power,
|
||||
.slave_addr = {
|
||||
.min = 0x2c,
|
||||
.max = 0x2f,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct max310x_devtype max3108_devtype = {
|
||||
@ -431,6 +449,10 @@ static const struct max310x_devtype max3108_devtype = {
|
||||
.mode1 = MAX310X_MODE1_AUTOSLEEP_BIT,
|
||||
.detect = max3108_detect,
|
||||
.power = max310x_power,
|
||||
.slave_addr = {
|
||||
.min = 0x60,
|
||||
.max = 0x6f,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct max310x_devtype max3109_devtype = {
|
||||
@ -439,6 +461,10 @@ static const struct max310x_devtype max3109_devtype = {
|
||||
.mode1 = MAX310X_MODE1_AUTOSLEEP_BIT,
|
||||
.detect = max3109_detect,
|
||||
.power = max310x_power,
|
||||
.slave_addr = {
|
||||
.min = 0x60,
|
||||
.max = 0x6f,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct max310x_devtype max14830_devtype = {
|
||||
@ -447,11 +473,15 @@ static const struct max310x_devtype max14830_devtype = {
|
||||
.mode1 = MAX310X_MODE1_IRQSEL_BIT,
|
||||
.detect = max14830_detect,
|
||||
.power = max14830_power,
|
||||
.slave_addr = {
|
||||
.min = 0x60,
|
||||
.max = 0x6f,
|
||||
},
|
||||
};
|
||||
|
||||
static bool max310x_reg_writeable(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg & 0x1f) {
|
||||
switch (reg) {
|
||||
case MAX310X_IRQSTS_REG:
|
||||
case MAX310X_LSR_IRQSTS_REG:
|
||||
case MAX310X_SPCHR_IRQSTS_REG:
|
||||
@ -468,7 +498,7 @@ static bool max310x_reg_writeable(struct device *dev, unsigned int reg)
|
||||
|
||||
static bool max310x_reg_volatile(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg & 0x1f) {
|
||||
switch (reg) {
|
||||
case MAX310X_RHR_REG:
|
||||
case MAX310X_IRQSTS_REG:
|
||||
case MAX310X_LSR_IRQSTS_REG:
|
||||
@ -490,7 +520,7 @@ static bool max310x_reg_volatile(struct device *dev, unsigned int reg)
|
||||
|
||||
static bool max310x_reg_precious(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg & 0x1f) {
|
||||
switch (reg) {
|
||||
case MAX310X_RHR_REG:
|
||||
case MAX310X_IRQSTS_REG:
|
||||
case MAX310X_SPCHR_IRQSTS_REG:
|
||||
@ -503,6 +533,11 @@ static bool max310x_reg_precious(struct device *dev, unsigned int reg)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool max310x_reg_noinc(struct device *dev, unsigned int reg)
|
||||
{
|
||||
return reg == MAX310X_RHR_REG;
|
||||
}
|
||||
|
||||
static int max310x_set_baud(struct uart_port *port, int baud)
|
||||
{
|
||||
unsigned int mode = 0, div = 0, frac = 0, c = 0, F = 0;
|
||||
@ -556,7 +591,7 @@ static int max310x_update_best_err(unsigned long f, long *besterr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
|
||||
static s32 max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
|
||||
unsigned long freq, bool xtal)
|
||||
{
|
||||
unsigned int div, clksrc, pllcfg = 0;
|
||||
@ -626,40 +661,25 @@ static int max310x_set_ref_clk(struct device *dev, struct max310x_port *s,
|
||||
} while (!stable && (++try < MAX310X_XTAL_WAIT_RETRIES));
|
||||
|
||||
if (!stable)
|
||||
dev_warn(dev, "clock is not stable yet\n");
|
||||
return dev_err_probe(dev, -EAGAIN,
|
||||
"clock is not stable\n");
|
||||
}
|
||||
|
||||
return (int)bestfreq;
|
||||
return bestfreq;
|
||||
}
|
||||
|
||||
static void max310x_batch_write(struct uart_port *port, u8 *txbuf, unsigned int len)
|
||||
{
|
||||
struct max310x_one *one = to_max310x_port(port);
|
||||
struct spi_transfer xfer[] = {
|
||||
{
|
||||
.tx_buf = &one->wr_header,
|
||||
.len = sizeof(one->wr_header),
|
||||
}, {
|
||||
.tx_buf = txbuf,
|
||||
.len = len,
|
||||
}
|
||||
};
|
||||
spi_sync_transfer(to_spi_device(port->dev), xfer, ARRAY_SIZE(xfer));
|
||||
|
||||
regmap_noinc_write(one->regmap, MAX310X_THR_REG, txbuf, len);
|
||||
}
|
||||
|
||||
static void max310x_batch_read(struct uart_port *port, u8 *rxbuf, unsigned int len)
|
||||
{
|
||||
struct max310x_one *one = to_max310x_port(port);
|
||||
struct spi_transfer xfer[] = {
|
||||
{
|
||||
.tx_buf = &one->rd_header,
|
||||
.len = sizeof(one->rd_header),
|
||||
}, {
|
||||
.rx_buf = rxbuf,
|
||||
.len = len,
|
||||
}
|
||||
};
|
||||
spi_sync_transfer(to_spi_device(port->dev), xfer, ARRAY_SIZE(xfer));
|
||||
|
||||
regmap_noinc_read(one->regmap, MAX310X_RHR_REG, rxbuf, len);
|
||||
}
|
||||
|
||||
static void max310x_handle_rx(struct uart_port *port, unsigned int rxlen)
|
||||
@ -1261,16 +1281,18 @@ static int max310x_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
struct regmap *regmap, int irq)
|
||||
static int max310x_probe(struct device *dev, const struct max310x_devtype *devtype,
|
||||
const struct max310x_if_cfg *if_cfg,
|
||||
struct regmap *regmaps[], int irq)
|
||||
{
|
||||
int i, ret, fmin, fmax, freq, uartclk;
|
||||
struct clk *clk_osc, *clk_xtal;
|
||||
int i, ret, fmin, fmax, freq;
|
||||
struct max310x_port *s;
|
||||
bool xtal = false;
|
||||
s32 uartclk = 0;
|
||||
bool xtal;
|
||||
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
for (i = 0; i < devtype->nr; i++)
|
||||
if (IS_ERR(regmaps[i]))
|
||||
return PTR_ERR(regmaps[i]);
|
||||
|
||||
/* Alloc port structure */
|
||||
s = devm_kzalloc(dev, struct_size(s, p, devtype->nr), GFP_KERNEL);
|
||||
@ -1279,23 +1301,20 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_osc = devm_clk_get(dev, "osc");
|
||||
clk_xtal = devm_clk_get(dev, "xtal");
|
||||
if (!IS_ERR(clk_osc)) {
|
||||
s->clk = clk_osc;
|
||||
fmin = 500000;
|
||||
fmax = 35000000;
|
||||
} else if (!IS_ERR(clk_xtal)) {
|
||||
s->clk = clk_xtal;
|
||||
fmin = 1000000;
|
||||
fmax = 4000000;
|
||||
xtal = true;
|
||||
} else if (PTR_ERR(clk_osc) == -EPROBE_DEFER ||
|
||||
PTR_ERR(clk_xtal) == -EPROBE_DEFER) {
|
||||
return -EPROBE_DEFER;
|
||||
/* Always ask for fixed clock rate from a property. */
|
||||
device_property_read_u32(dev, "clock-frequency", &uartclk);
|
||||
|
||||
s->clk = devm_clk_get_optional(dev, "osc");
|
||||
if (IS_ERR(s->clk))
|
||||
return PTR_ERR(s->clk);
|
||||
if (s->clk) {
|
||||
xtal = false;
|
||||
} else {
|
||||
dev_err(dev, "Cannot get clock\n");
|
||||
return -EINVAL;
|
||||
s->clk = devm_clk_get_optional(dev, "xtal");
|
||||
if (IS_ERR(s->clk))
|
||||
return PTR_ERR(s->clk);
|
||||
|
||||
xtal = true;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(s->clk);
|
||||
@ -1303,14 +1322,31 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
return ret;
|
||||
|
||||
freq = clk_get_rate(s->clk);
|
||||
if (freq == 0)
|
||||
freq = uartclk;
|
||||
if (freq == 0) {
|
||||
dev_err(dev, "Cannot get clock rate\n");
|
||||
ret = -EINVAL;
|
||||
goto out_clk;
|
||||
}
|
||||
|
||||
if (xtal) {
|
||||
fmin = 1000000;
|
||||
fmax = 4000000;
|
||||
} else {
|
||||
fmin = 500000;
|
||||
fmax = 35000000;
|
||||
}
|
||||
|
||||
/* Check frequency limits */
|
||||
if (freq < fmin || freq > fmax) {
|
||||
ret = -ERANGE;
|
||||
goto out_clk;
|
||||
}
|
||||
|
||||
s->regmap = regmap;
|
||||
s->regmap = regmaps[0];
|
||||
s->devtype = devtype;
|
||||
s->if_cfg = if_cfg;
|
||||
dev_set_drvdata(dev, s);
|
||||
|
||||
/* Check device to ensure we are talking to what we expect */
|
||||
@ -1319,25 +1355,38 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
goto out_clk;
|
||||
|
||||
for (i = 0; i < devtype->nr; i++) {
|
||||
unsigned int offs = i << 5;
|
||||
bool started = false;
|
||||
unsigned int try = 0, val = 0;
|
||||
|
||||
/* Reset port */
|
||||
regmap_write(s->regmap, MAX310X_MODE2_REG + offs,
|
||||
regmap_write(regmaps[i], MAX310X_MODE2_REG,
|
||||
MAX310X_MODE2_RST_BIT);
|
||||
/* Clear port reset */
|
||||
regmap_write(s->regmap, MAX310X_MODE2_REG + offs, 0);
|
||||
regmap_write(regmaps[i], MAX310X_MODE2_REG, 0);
|
||||
|
||||
/* Wait for port startup */
|
||||
do {
|
||||
regmap_read(s->regmap,
|
||||
MAX310X_BRGDIVLSB_REG + offs, &ret);
|
||||
} while (ret != 0x01);
|
||||
msleep(MAX310X_PORT_STARTUP_WAIT_DELAY_MS);
|
||||
regmap_read(regmaps[i], MAX310X_BRGDIVLSB_REG, &val);
|
||||
|
||||
regmap_write(s->regmap, MAX310X_MODE1_REG + offs,
|
||||
devtype->mode1);
|
||||
if (val == 0x01)
|
||||
started = true;
|
||||
} while (!started && (++try < MAX310X_PORT_STARTUP_WAIT_RETRIES));
|
||||
|
||||
if (!started) {
|
||||
ret = dev_err_probe(dev, -EAGAIN, "port reset failed\n");
|
||||
goto out_uart;
|
||||
}
|
||||
|
||||
regmap_write(regmaps[i], MAX310X_MODE1_REG, devtype->mode1);
|
||||
}
|
||||
|
||||
uartclk = max310x_set_ref_clk(dev, s, freq, xtal);
|
||||
if (uartclk < 0) {
|
||||
ret = uartclk;
|
||||
goto out_uart;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "Reference clock set to %i Hz\n", uartclk);
|
||||
|
||||
for (i = 0; i < devtype->nr; i++) {
|
||||
@ -1357,11 +1406,13 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
s->p[i].port.fifosize = MAX310X_FIFO_SIZE;
|
||||
s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
|
||||
s->p[i].port.iotype = UPIO_PORT;
|
||||
s->p[i].port.iobase = i * 0x20;
|
||||
s->p[i].port.iobase = i;
|
||||
s->p[i].port.membase = (void __iomem *)~0;
|
||||
s->p[i].port.uartclk = uartclk;
|
||||
s->p[i].port.rs485_config = max310x_rs485_config;
|
||||
s->p[i].port.ops = &max310x_ops;
|
||||
s->p[i].regmap = regmaps[i];
|
||||
|
||||
/* Disable all interrupts */
|
||||
max310x_port_write(&s->p[i].port, MAX310X_IRQEN_REG, 0);
|
||||
/* Clear IRQ status register */
|
||||
@ -1372,10 +1423,6 @@ static int max310x_probe(struct device *dev, struct max310x_devtype *devtype,
|
||||
INIT_WORK(&s->p[i].md_work, max310x_md_proc);
|
||||
/* Initialize queue for changing RS485 mode */
|
||||
INIT_WORK(&s->p[i].rs_work, max310x_rs_proc);
|
||||
/* Initialize SPI-transfer buffers */
|
||||
s->p[i].wr_header = (s->p[i].port.iobase + MAX310X_THR_REG) |
|
||||
MAX310X_WRITE_BIT;
|
||||
s->p[i].rd_header = (s->p[i].port.iobase + MAX310X_RHR_REG);
|
||||
|
||||
/* Register port */
|
||||
ret = uart_add_one_port(&max310x_uart, &s->p[i].port);
|
||||
@ -1462,16 +1509,35 @@ static struct regmap_config regcfg = {
|
||||
.val_bits = 8,
|
||||
.write_flag_mask = MAX310X_WRITE_BIT,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.max_register = MAX310X_REG_1F,
|
||||
.writeable_reg = max310x_reg_writeable,
|
||||
.volatile_reg = max310x_reg_volatile,
|
||||
.precious_reg = max310x_reg_precious,
|
||||
.writeable_noinc_reg = max310x_reg_noinc,
|
||||
.readable_noinc_reg = max310x_reg_noinc,
|
||||
.max_raw_read = MAX310X_FIFO_SIZE,
|
||||
.max_raw_write = MAX310X_FIFO_SIZE,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SPI_MASTER
|
||||
static int max310x_spi_extended_reg_enable(struct device *dev, bool enable)
|
||||
{
|
||||
struct max310x_port *s = dev_get_drvdata(dev);
|
||||
|
||||
return regmap_write(s->regmap, MAX310X_GLOBALCMD_REG,
|
||||
enable ? MAX310X_EXTREG_ENBL : MAX310X_EXTREG_DSBL);
|
||||
}
|
||||
|
||||
static const struct max310x_if_cfg __maybe_unused max310x_spi_if_cfg = {
|
||||
.extended_reg_enable = max310x_spi_extended_reg_enable,
|
||||
.rev_id_reg = MAX310X_SPI_REVID_EXTREG,
|
||||
};
|
||||
|
||||
static int max310x_spi_probe(struct spi_device *spi)
|
||||
{
|
||||
struct max310x_devtype *devtype;
|
||||
struct regmap *regmap;
|
||||
const struct max310x_devtype *devtype;
|
||||
struct regmap *regmaps[4];
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
/* Setup SPI bus */
|
||||
@ -1482,23 +1548,18 @@ static int max310x_spi_probe(struct spi_device *spi)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (spi->dev.of_node) {
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(max310x_dt_ids, &spi->dev);
|
||||
if (!of_id)
|
||||
return -ENODEV;
|
||||
devtype = device_get_match_data(&spi->dev);
|
||||
if (!devtype)
|
||||
devtype = (struct max310x_devtype *)spi_get_device_id(spi)->driver_data;
|
||||
|
||||
devtype = (struct max310x_devtype *)of_id->data;
|
||||
} else {
|
||||
const struct spi_device_id *id_entry = spi_get_device_id(spi);
|
||||
|
||||
devtype = (struct max310x_devtype *)id_entry->driver_data;
|
||||
for (i = 0; i < devtype->nr; i++) {
|
||||
u8 port_mask = i * 0x20;
|
||||
regcfg.read_flag_mask = port_mask;
|
||||
regcfg.write_flag_mask = port_mask | MAX310X_WRITE_BIT;
|
||||
regmaps[i] = devm_regmap_init_spi(spi, ®cfg);
|
||||
}
|
||||
|
||||
regcfg.max_register = devtype->nr * 0x20 - 1;
|
||||
regmap = devm_regmap_init_spi(spi, ®cfg);
|
||||
|
||||
return max310x_probe(&spi->dev, devtype, regmap, spi->irq);
|
||||
return max310x_probe(&spi->dev, devtype, &max310x_spi_if_cfg, regmaps, spi->irq);
|
||||
}
|
||||
|
||||
static int max310x_spi_remove(struct spi_device *spi)
|
||||
@ -1518,7 +1579,7 @@ MODULE_DEVICE_TABLE(spi, max310x_id_table);
|
||||
static struct spi_driver max310x_spi_driver = {
|
||||
.driver = {
|
||||
.name = MAX310X_NAME,
|
||||
.of_match_table = of_match_ptr(max310x_dt_ids),
|
||||
.of_match_table = max310x_dt_ids,
|
||||
.pm = &max310x_pm_ops,
|
||||
},
|
||||
.probe = max310x_spi_probe,
|
||||
@ -1527,6 +1588,101 @@ static struct spi_driver max310x_spi_driver = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
static int max310x_i2c_extended_reg_enable(struct device *dev, bool enable)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct regmap_config regcfg_i2c = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.writeable_reg = max310x_reg_writeable,
|
||||
.volatile_reg = max310x_reg_volatile,
|
||||
.precious_reg = max310x_reg_precious,
|
||||
.max_register = MAX310X_I2C_REVID_EXTREG,
|
||||
.writeable_noinc_reg = max310x_reg_noinc,
|
||||
.readable_noinc_reg = max310x_reg_noinc,
|
||||
.max_raw_read = MAX310X_FIFO_SIZE,
|
||||
.max_raw_write = MAX310X_FIFO_SIZE,
|
||||
};
|
||||
|
||||
static const struct max310x_if_cfg max310x_i2c_if_cfg = {
|
||||
.extended_reg_enable = max310x_i2c_extended_reg_enable,
|
||||
.rev_id_reg = MAX310X_I2C_REVID_EXTREG,
|
||||
};
|
||||
|
||||
static unsigned short max310x_i2c_slave_addr(unsigned short addr,
|
||||
unsigned int nr)
|
||||
{
|
||||
/*
|
||||
* For MAX14830 and MAX3109, the slave address depends on what the
|
||||
* A0 and A1 pins are tied to.
|
||||
* See Table I2C Address Map of the datasheet.
|
||||
* Based on that table, the following formulas were determined.
|
||||
* UART1 - UART0 = 0x10
|
||||
* UART2 - UART1 = 0x20 + 0x10
|
||||
* UART3 - UART2 = 0x10
|
||||
*/
|
||||
|
||||
addr -= nr * 0x10;
|
||||
|
||||
if (nr >= 2)
|
||||
addr -= 0x20;
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static int max310x_i2c_probe(struct i2c_client *client)
|
||||
{
|
||||
const struct max310x_devtype *devtype =
|
||||
device_get_match_data(&client->dev);
|
||||
struct i2c_client *port_client;
|
||||
struct regmap *regmaps[4];
|
||||
unsigned int i;
|
||||
u8 port_addr;
|
||||
|
||||
if (client->addr < devtype->slave_addr.min ||
|
||||
client->addr > devtype->slave_addr.max)
|
||||
return dev_err_probe(&client->dev, -EINVAL,
|
||||
"Slave addr 0x%x outside of range [0x%x, 0x%x]\n",
|
||||
client->addr, devtype->slave_addr.min,
|
||||
devtype->slave_addr.max);
|
||||
|
||||
regmaps[0] = devm_regmap_init_i2c(client, ®cfg_i2c);
|
||||
|
||||
for (i = 1; i < devtype->nr; i++) {
|
||||
port_addr = max310x_i2c_slave_addr(client->addr, i);
|
||||
port_client = devm_i2c_new_dummy_device(&client->dev,
|
||||
client->adapter,
|
||||
port_addr);
|
||||
|
||||
regmaps[i] = devm_regmap_init_i2c(port_client, ®cfg_i2c);
|
||||
}
|
||||
|
||||
return max310x_probe(&client->dev, devtype, &max310x_i2c_if_cfg,
|
||||
regmaps, client->irq);
|
||||
}
|
||||
|
||||
static int max310x_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
max310x_remove(&client->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct i2c_driver max310x_i2c_driver = {
|
||||
.driver = {
|
||||
.name = MAX310X_NAME,
|
||||
.of_match_table = max310x_dt_ids,
|
||||
.pm = &max310x_pm_ops,
|
||||
},
|
||||
.probe_new = max310x_i2c_probe,
|
||||
.remove = max310x_i2c_remove,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int __init max310x_uart_init(void)
|
||||
{
|
||||
int ret;
|
||||
@ -1540,15 +1696,35 @@ static int __init max310x_uart_init(void)
|
||||
#ifdef CONFIG_SPI_MASTER
|
||||
ret = spi_register_driver(&max310x_spi_driver);
|
||||
if (ret)
|
||||
uart_unregister_driver(&max310x_uart);
|
||||
goto err_spi_register;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
ret = i2c_add_driver(&max310x_i2c_driver);
|
||||
if (ret)
|
||||
goto err_i2c_register;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_I2C
|
||||
err_i2c_register:
|
||||
spi_unregister_driver(&max310x_spi_driver);
|
||||
#endif
|
||||
|
||||
err_spi_register:
|
||||
uart_unregister_driver(&max310x_uart);
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(max310x_uart_init);
|
||||
|
||||
static void __exit max310x_uart_exit(void)
|
||||
{
|
||||
#ifdef CONFIG_I2C
|
||||
i2c_del_driver(&max310x_i2c_driver);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPI_MASTER
|
||||
spi_unregister_driver(&max310x_spi_driver);
|
||||
#endif
|
||||
|
@ -295,6 +295,17 @@ typedef void (*regmap_unlock)(void *);
|
||||
* read operation on a bus such as SPI, I2C, etc. Most of the
|
||||
* devices do not need this.
|
||||
* @reg_write: Same as above for writing.
|
||||
* @reg_update_bits: Optional callback that if filled will be used to perform
|
||||
* all the update_bits(rmw) operation. Should only be provided
|
||||
* if the function require special handling with lock and reg
|
||||
* handling and the operation cannot be represented as a simple
|
||||
* update_bits operation on a bus such as SPI, I2C, etc.
|
||||
* @read: Optional callback that if filled will be used to perform all the
|
||||
* bulk reads from the registers. Data is returned in the buffer used
|
||||
* to transmit data.
|
||||
* @write: Same as above for writing.
|
||||
* @max_raw_read: Max raw read size that can be used on the device.
|
||||
* @max_raw_write: Max raw write size that can be used on the device.
|
||||
* @fast_io: Register IO is fast. Use a spinlock instead of a mutex
|
||||
* to perform locking. This field is ignored if custom lock/unlock
|
||||
* functions are used (see fields lock/unlock of struct regmap_config).
|
||||
@ -371,6 +382,14 @@ struct regmap_config {
|
||||
|
||||
int (*reg_read)(void *context, unsigned int reg, unsigned int *val);
|
||||
int (*reg_write)(void *context, unsigned int reg, unsigned int val);
|
||||
int (*reg_update_bits)(void *context, unsigned int reg,
|
||||
unsigned int mask, unsigned int val);
|
||||
/* Bulk read/write */
|
||||
int (*read)(void *context, const void *reg_buf, size_t reg_size,
|
||||
void *val_buf, size_t val_size);
|
||||
int (*write)(void *context, const void *data, size_t count);
|
||||
size_t max_raw_read;
|
||||
size_t max_raw_write;
|
||||
|
||||
bool fast_io;
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
#define RUSAGE_THREAD 1 /* only the calling thread */
|
||||
|
||||
struct rusage {
|
||||
struct timeval ru_utime; /* user time used */
|
||||
struct timeval ru_stime; /* system time used */
|
||||
struct __kernel_old_timeval ru_utime; /* user time used */
|
||||
struct __kernel_old_timeval ru_stime; /* system time used */
|
||||
__kernel_long_t ru_maxrss; /* maximum resident set size */
|
||||
__kernel_long_t ru_ixrss; /* integral shared memory size */
|
||||
__kernel_long_t ru_idrss; /* integral unshared data size */
|
||||
|
95
kernel/sys.c
95
kernel/sys.c
@ -1715,74 +1715,87 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
|
||||
struct task_struct *t;
|
||||
unsigned long flags;
|
||||
u64 tgutime, tgstime, utime, stime;
|
||||
unsigned long maxrss = 0;
|
||||
unsigned long maxrss;
|
||||
struct mm_struct *mm;
|
||||
struct signal_struct *sig = p->signal;
|
||||
unsigned int seq = 0;
|
||||
|
||||
memset((char *)r, 0, sizeof (*r));
|
||||
retry:
|
||||
memset(r, 0, sizeof(*r));
|
||||
utime = stime = 0;
|
||||
maxrss = 0;
|
||||
|
||||
if (who == RUSAGE_THREAD) {
|
||||
task_cputime_adjusted(current, &utime, &stime);
|
||||
accumulate_thread_rusage(p, r);
|
||||
maxrss = p->signal->maxrss;
|
||||
goto out;
|
||||
maxrss = sig->maxrss;
|
||||
goto out_thread;
|
||||
}
|
||||
|
||||
if (!lock_task_sighand(p, &flags))
|
||||
return;
|
||||
flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);
|
||||
|
||||
switch (who) {
|
||||
case RUSAGE_BOTH:
|
||||
case RUSAGE_CHILDREN:
|
||||
utime = p->signal->cutime;
|
||||
stime = p->signal->cstime;
|
||||
r->ru_nvcsw = p->signal->cnvcsw;
|
||||
r->ru_nivcsw = p->signal->cnivcsw;
|
||||
r->ru_minflt = p->signal->cmin_flt;
|
||||
r->ru_majflt = p->signal->cmaj_flt;
|
||||
r->ru_inblock = p->signal->cinblock;
|
||||
r->ru_oublock = p->signal->coublock;
|
||||
maxrss = p->signal->cmaxrss;
|
||||
utime = sig->cutime;
|
||||
stime = sig->cstime;
|
||||
r->ru_nvcsw = sig->cnvcsw;
|
||||
r->ru_nivcsw = sig->cnivcsw;
|
||||
r->ru_minflt = sig->cmin_flt;
|
||||
r->ru_majflt = sig->cmaj_flt;
|
||||
r->ru_inblock = sig->cinblock;
|
||||
r->ru_oublock = sig->coublock;
|
||||
maxrss = sig->cmaxrss;
|
||||
|
||||
if (who == RUSAGE_CHILDREN)
|
||||
break;
|
||||
/* fall through */
|
||||
|
||||
case RUSAGE_SELF:
|
||||
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
|
||||
utime += tgutime;
|
||||
stime += tgstime;
|
||||
r->ru_nvcsw += p->signal->nvcsw;
|
||||
r->ru_nivcsw += p->signal->nivcsw;
|
||||
r->ru_minflt += p->signal->min_flt;
|
||||
r->ru_majflt += p->signal->maj_flt;
|
||||
r->ru_inblock += p->signal->inblock;
|
||||
r->ru_oublock += p->signal->oublock;
|
||||
if (maxrss < p->signal->maxrss)
|
||||
maxrss = p->signal->maxrss;
|
||||
t = p;
|
||||
do {
|
||||
r->ru_nvcsw += sig->nvcsw;
|
||||
r->ru_nivcsw += sig->nivcsw;
|
||||
r->ru_minflt += sig->min_flt;
|
||||
r->ru_majflt += sig->maj_flt;
|
||||
r->ru_inblock += sig->inblock;
|
||||
r->ru_oublock += sig->oublock;
|
||||
if (maxrss < sig->maxrss)
|
||||
maxrss = sig->maxrss;
|
||||
|
||||
rcu_read_lock();
|
||||
__for_each_thread(sig, t)
|
||||
accumulate_thread_rusage(t, r);
|
||||
} while_each_thread(p, t);
|
||||
rcu_read_unlock();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
unlock_task_sighand(p, &flags);
|
||||
|
||||
out:
|
||||
r->ru_utime = ns_to_timeval(utime);
|
||||
r->ru_stime = ns_to_timeval(stime);
|
||||
|
||||
if (who != RUSAGE_CHILDREN) {
|
||||
struct mm_struct *mm = get_task_mm(p);
|
||||
|
||||
if (mm) {
|
||||
setmax_mm_hiwater_rss(&maxrss, mm);
|
||||
mmput(mm);
|
||||
}
|
||||
if (need_seqretry(&sig->stats_lock, seq)) {
|
||||
seq = 1;
|
||||
goto retry;
|
||||
}
|
||||
done_seqretry_irqrestore(&sig->stats_lock, seq, flags);
|
||||
|
||||
if (who == RUSAGE_CHILDREN)
|
||||
goto out_children;
|
||||
|
||||
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
|
||||
utime += tgutime;
|
||||
stime += tgstime;
|
||||
|
||||
out_thread:
|
||||
mm = get_task_mm(p);
|
||||
if (mm) {
|
||||
setmax_mm_hiwater_rss(&maxrss, mm);
|
||||
mmput(mm);
|
||||
}
|
||||
|
||||
out_children:
|
||||
r->ru_maxrss = maxrss * (PAGE_SIZE / 1024); /* convert pages to KBs */
|
||||
r->ru_utime = ns_to_kernel_old_timeval(utime);
|
||||
r->ru_stime = ns_to_kernel_old_timeval(stime);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)
|
||||
|
@ -5178,19 +5178,7 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
|
||||
err_nh = NULL;
|
||||
list_for_each_entry(nh, &rt6_nh_list, next) {
|
||||
err = __ip6_ins_rt(nh->fib6_info, info, extack);
|
||||
fib6_info_release(nh->fib6_info);
|
||||
|
||||
if (!err) {
|
||||
/* save reference to last route successfully inserted */
|
||||
rt_last = nh->fib6_info;
|
||||
|
||||
/* save reference to first route for notification */
|
||||
if (!rt_notif)
|
||||
rt_notif = nh->fib6_info;
|
||||
}
|
||||
|
||||
/* nh->fib6_info is used or freed at this point, reset to NULL*/
|
||||
nh->fib6_info = NULL;
|
||||
if (err) {
|
||||
if (replace && nhn)
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
@ -5198,6 +5186,12 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
|
||||
err_nh = nh;
|
||||
goto add_errout;
|
||||
}
|
||||
/* save reference to last route successfully inserted */
|
||||
rt_last = nh->fib6_info;
|
||||
|
||||
/* save reference to first route for notification */
|
||||
if (!rt_notif)
|
||||
rt_notif = nh->fib6_info;
|
||||
|
||||
/* Because each route is added like a single route we remove
|
||||
* these flags after the first nexthop: if there is a collision,
|
||||
@ -5244,8 +5238,7 @@ add_errout:
|
||||
|
||||
cleanup:
|
||||
list_for_each_entry_safe(nh, nh_safe, &rt6_nh_list, next) {
|
||||
if (nh->fib6_info)
|
||||
fib6_info_release(nh->fib6_info);
|
||||
fib6_info_release(nh->fib6_info);
|
||||
list_del(&nh->next);
|
||||
kfree(nh);
|
||||
}
|
||||
|
@ -533,6 +533,8 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
|
||||
/* Get fields bitmap */
|
||||
if (nf_h323_error_boundary(bs, 0, f->sz))
|
||||
return H323_ERROR_BOUND;
|
||||
if (f->sz > 32)
|
||||
return H323_ERROR_RANGE;
|
||||
bmp = get_bitmap(bs, f->sz);
|
||||
if (base)
|
||||
*(unsigned int *)base = bmp;
|
||||
@ -589,6 +591,8 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f,
|
||||
bmp2_len = get_bits(bs, 7) + 1;
|
||||
if (nf_h323_error_boundary(bs, 0, bmp2_len))
|
||||
return H323_ERROR_BOUND;
|
||||
if (bmp2_len > 32)
|
||||
return H323_ERROR_RANGE;
|
||||
bmp2 = get_bitmap(bs, bmp2_len);
|
||||
bmp |= bmp2 >> f->sz;
|
||||
if (base)
|
||||
|
@ -1180,14 +1180,13 @@ static int nft_ct_expect_obj_init(const struct nft_ctx *ctx,
|
||||
switch (priv->l3num) {
|
||||
case NFPROTO_IPV4:
|
||||
case NFPROTO_IPV6:
|
||||
if (priv->l3num != ctx->family)
|
||||
return -EINVAL;
|
||||
if (priv->l3num == ctx->family || ctx->family == NFPROTO_INET)
|
||||
break;
|
||||
|
||||
fallthrough;
|
||||
case NFPROTO_INET:
|
||||
break;
|
||||
return -EINVAL;
|
||||
case NFPROTO_INET: /* tuple.src.l3num supports NFPROTO_IPV4/6 only */
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]);
|
||||
|
@ -431,16 +431,16 @@ static int nr_create(struct net *net, struct socket *sock, int protocol,
|
||||
nr_init_timers(sk);
|
||||
|
||||
nr->t1 =
|
||||
msecs_to_jiffies(sysctl_netrom_transport_timeout);
|
||||
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_timeout));
|
||||
nr->t2 =
|
||||
msecs_to_jiffies(sysctl_netrom_transport_acknowledge_delay);
|
||||
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_acknowledge_delay));
|
||||
nr->n2 =
|
||||
msecs_to_jiffies(sysctl_netrom_transport_maximum_tries);
|
||||
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_maximum_tries));
|
||||
nr->t4 =
|
||||
msecs_to_jiffies(sysctl_netrom_transport_busy_delay);
|
||||
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_busy_delay));
|
||||
nr->idle =
|
||||
msecs_to_jiffies(sysctl_netrom_transport_no_activity_timeout);
|
||||
nr->window = sysctl_netrom_transport_requested_window_size;
|
||||
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_no_activity_timeout));
|
||||
nr->window = READ_ONCE(sysctl_netrom_transport_requested_window_size);
|
||||
|
||||
nr->bpqext = 1;
|
||||
nr->state = NR_STATE_0;
|
||||
@ -932,7 +932,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
|
||||
* G8PZT's Xrouter which is sending packets with command type 7
|
||||
* as an extension of the protocol.
|
||||
*/
|
||||
if (sysctl_netrom_reset_circuit &&
|
||||
if (READ_ONCE(sysctl_netrom_reset_circuit) &&
|
||||
(frametype != NR_RESET || flags != 0))
|
||||
nr_transmit_reset(skb, 1);
|
||||
|
||||
|
@ -81,7 +81,7 @@ static int nr_header(struct sk_buff *skb, struct net_device *dev,
|
||||
buff[6] |= AX25_SSSID_SPARE;
|
||||
buff += AX25_ADDR_LEN;
|
||||
|
||||
*buff++ = sysctl_netrom_network_ttl_initialiser;
|
||||
*buff++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
|
||||
|
||||
*buff++ = NR_PROTO_IP;
|
||||
*buff++ = NR_PROTO_IP;
|
||||
|
@ -97,7 +97,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
|
||||
break;
|
||||
|
||||
case NR_RESET:
|
||||
if (sysctl_netrom_reset_circuit)
|
||||
if (READ_ONCE(sysctl_netrom_reset_circuit))
|
||||
nr_disconnect(sk, ECONNRESET);
|
||||
break;
|
||||
|
||||
@ -128,7 +128,7 @@ static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
|
||||
break;
|
||||
|
||||
case NR_RESET:
|
||||
if (sysctl_netrom_reset_circuit)
|
||||
if (READ_ONCE(sysctl_netrom_reset_circuit))
|
||||
nr_disconnect(sk, ECONNRESET);
|
||||
break;
|
||||
|
||||
@ -263,7 +263,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
|
||||
break;
|
||||
|
||||
case NR_RESET:
|
||||
if (sysctl_netrom_reset_circuit)
|
||||
if (READ_ONCE(sysctl_netrom_reset_circuit))
|
||||
nr_disconnect(sk, ECONNRESET);
|
||||
break;
|
||||
|
||||
|
@ -204,7 +204,7 @@ void nr_transmit_buffer(struct sock *sk, struct sk_buff *skb)
|
||||
dptr[6] |= AX25_SSSID_SPARE;
|
||||
dptr += AX25_ADDR_LEN;
|
||||
|
||||
*dptr++ = sysctl_netrom_network_ttl_initialiser;
|
||||
*dptr++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
|
||||
|
||||
if (!nr_route_frame(skb, NULL)) {
|
||||
kfree_skb(skb);
|
||||
|
@ -153,7 +153,7 @@ static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
|
||||
nr_neigh->digipeat = NULL;
|
||||
nr_neigh->ax25 = NULL;
|
||||
nr_neigh->dev = dev;
|
||||
nr_neigh->quality = sysctl_netrom_default_path_quality;
|
||||
nr_neigh->quality = READ_ONCE(sysctl_netrom_default_path_quality);
|
||||
nr_neigh->locked = 0;
|
||||
nr_neigh->count = 0;
|
||||
nr_neigh->number = nr_neigh_no++;
|
||||
@ -725,7 +725,7 @@ void nr_link_failed(ax25_cb *ax25, int reason)
|
||||
nr_neigh->ax25 = NULL;
|
||||
ax25_cb_put(ax25);
|
||||
|
||||
if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
|
||||
if (++nr_neigh->failed < READ_ONCE(sysctl_netrom_link_fails_count)) {
|
||||
nr_neigh_put(nr_neigh);
|
||||
return;
|
||||
}
|
||||
@ -763,7 +763,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
|
||||
if (ax25 != NULL) {
|
||||
ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
|
||||
ax25->ax25_dev->dev, 0,
|
||||
sysctl_netrom_obsolescence_count_initialiser);
|
||||
READ_ONCE(sysctl_netrom_obsolescence_count_initialiser));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -777,7 +777,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!sysctl_netrom_routing_control && ax25 != NULL)
|
||||
if (!READ_ONCE(sysctl_netrom_routing_control) && ax25 != NULL)
|
||||
return 0;
|
||||
|
||||
/* Its Time-To-Live has expired */
|
||||
|
@ -182,7 +182,8 @@ void nr_write_internal(struct sock *sk, int frametype)
|
||||
*dptr++ = nr->my_id;
|
||||
*dptr++ = frametype;
|
||||
*dptr++ = nr->window;
|
||||
if (nr->bpqext) *dptr++ = sysctl_netrom_network_ttl_initialiser;
|
||||
if (nr->bpqext)
|
||||
*dptr++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
|
||||
break;
|
||||
|
||||
case NR_DISCREQ:
|
||||
@ -236,7 +237,7 @@ void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
|
||||
dptr[6] |= AX25_SSSID_SPARE;
|
||||
dptr += AX25_ADDR_LEN;
|
||||
|
||||
*dptr++ = sysctl_netrom_network_ttl_initialiser;
|
||||
*dptr++ = READ_ONCE(sysctl_netrom_network_ttl_initialiser);
|
||||
|
||||
if (mine) {
|
||||
*dptr++ = 0;
|
||||
|
@ -279,6 +279,9 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
|
||||
put_page(sg_page(&sg[i]));
|
||||
kfree(sg);
|
||||
ret = PTR_ERR(trans_private);
|
||||
/* Trigger connection so that its ready for the next retry */
|
||||
if (ret == -ENODEV)
|
||||
rds_conn_connect_if_down(cp->cp_conn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1314,12 +1314,8 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
|
||||
|
||||
/* Parse any control messages the user may have included. */
|
||||
ret = rds_cmsg_send(rs, rm, msg, &allocated_mr, &vct);
|
||||
if (ret) {
|
||||
/* Trigger connection so that its ready for the next retry */
|
||||
if (ret == -EAGAIN)
|
||||
rds_conn_connect_if_down(conn);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (rm->rdma.op_active && !conn->c_trans->xmit_rdma) {
|
||||
printk_ratelimited(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n",
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include "vm_util.h"
|
||||
|
||||
#define LENGTH (256UL*1024*1024)
|
||||
#define PROTECTION (PROT_READ | PROT_WRITE)
|
||||
@ -70,10 +71,16 @@ int main(int argc, char **argv)
|
||||
{
|
||||
void *addr;
|
||||
int ret;
|
||||
size_t hugepage_size;
|
||||
size_t length = LENGTH;
|
||||
int flags = FLAGS;
|
||||
int shift = 0;
|
||||
|
||||
hugepage_size = default_huge_page_size();
|
||||
/* munmap with fail if the length is not page aligned */
|
||||
if (hugepage_size > length)
|
||||
length = hugepage_size;
|
||||
|
||||
if (argc > 1)
|
||||
length = atol(argv[1]) << 20;
|
||||
if (argc > 2) {
|
||||
|
Loading…
Reference in New Issue
Block a user