mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
Merge tag 'v6.6.116' of git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable into odroid-6.6.y
This is the 6.6.116 stable release Change-Id: Ifd9496a0a36c0b0436ced35277a2fc4ace7641ab
This commit is contained in:
@@ -75,3 +75,13 @@ Description:
|
||||
The default value is 1 (GNU Remote Debug command).
|
||||
Other permissible value is 0 which is for vendor defined debug
|
||||
target.
|
||||
|
||||
What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_poll_interval_ms
|
||||
Date: February 2024
|
||||
Contact: Mathias Nyman <mathias.nyman@linux.intel.com>
|
||||
Description:
|
||||
This attribute adjust the polling interval used to check for
|
||||
DbC events. Unit is milliseconds. Accepted values range from 0
|
||||
up to 5000. The default value is 64 ms.
|
||||
This polling interval is used while DbC is enabled but has no
|
||||
active data transfers.
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
VERSION = 6
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 115
|
||||
SUBLEVEL = 116
|
||||
EXTRAVERSION =
|
||||
NAME = Pinguïn Aangedreven
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* This code generates raw asm output which is post-processed to extract
|
||||
* and format the required data.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/stddef.h>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
* This code generates raw asm output which is post-processed to extract
|
||||
* and format the required data.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* 2001-2002 Keith Owens
|
||||
* Copyright (C) 2012 ARM Ltd.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/arm_sdei.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*
|
||||
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
*
|
||||
* Copyright (C) 2020-2022 Loongson Technology Corporation Limited
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
|
||||
#define COMPILE_OFFSETS
|
||||
#define ASM_OFFSETS_C
|
||||
|
||||
#include <linux/stddef.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/stddef.h>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
* Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
|
||||
* Copyright (C) 2000 MIPS Technologies, Inc.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org>
|
||||
* Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/signal.h>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2012 Regents of the University of California
|
||||
* Copyright (C) 2017 SiFive
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/kbuild.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* This code generates raw asm output which is post-processed to extract
|
||||
* and format the required data.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#define ASM_OFFSETS_C
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
* compile this file to assembler, and then extract the
|
||||
* #defines from the assembly-language output.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*
|
||||
* On sparc, thread_info data is static and TI_XXX offsets are computed by hand.
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mm_types.h>
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <sysdep/kernel-offsets.h>
|
||||
|
||||
@@ -1185,8 +1185,10 @@ do_cmd_auto:
|
||||
retbleed_mitigation = RETBLEED_MITIGATION_EIBRS;
|
||||
break;
|
||||
default:
|
||||
if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF)
|
||||
if (retbleed_mitigation != RETBLEED_MITIGATION_STUFF) {
|
||||
pr_err(RETBLEED_INTEL_MSG);
|
||||
retbleed_mitigation = RETBLEED_MITIGATION_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1592,7 +1594,7 @@ set_mode:
|
||||
static const char * const spectre_v2_strings[] = {
|
||||
[SPECTRE_V2_NONE] = "Vulnerable",
|
||||
[SPECTRE_V2_RETPOLINE] = "Mitigation: Retpolines",
|
||||
[SPECTRE_V2_LFENCE] = "Mitigation: LFENCE",
|
||||
[SPECTRE_V2_LFENCE] = "Vulnerable: LFENCE",
|
||||
[SPECTRE_V2_EIBRS] = "Mitigation: Enhanced / Automatic IBRS",
|
||||
[SPECTRE_V2_EIBRS_LFENCE] = "Mitigation: Enhanced / Automatic IBRS + LFENCE",
|
||||
[SPECTRE_V2_EIBRS_RETPOLINE] = "Mitigation: Enhanced / Automatic IBRS + Retpolines",
|
||||
@@ -3220,9 +3222,6 @@ static const char *spectre_bhi_state(void)
|
||||
|
||||
static ssize_t spectre_v2_show_state(char *buf)
|
||||
{
|
||||
if (spectre_v2_enabled == SPECTRE_V2_LFENCE)
|
||||
return sysfs_emit(buf, "Vulnerable: LFENCE\n");
|
||||
|
||||
if (spectre_v2_enabled == SPECTRE_V2_EIBRS && unprivileged_ebpf_enabled())
|
||||
return sysfs_emit(buf, "Vulnerable: eIBRS with unprivileged eBPF\n");
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*
|
||||
* Chris Zankel <chris@zankel.net>
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/coprocessor.h>
|
||||
|
||||
@@ -306,6 +306,14 @@ DEVICE_CHANNEL(ch10_dimm_label, S_IRUGO | S_IWUSR,
|
||||
channel_dimm_label_show, channel_dimm_label_store, 10);
|
||||
DEVICE_CHANNEL(ch11_dimm_label, S_IRUGO | S_IWUSR,
|
||||
channel_dimm_label_show, channel_dimm_label_store, 11);
|
||||
DEVICE_CHANNEL(ch12_dimm_label, S_IRUGO | S_IWUSR,
|
||||
channel_dimm_label_show, channel_dimm_label_store, 12);
|
||||
DEVICE_CHANNEL(ch13_dimm_label, S_IRUGO | S_IWUSR,
|
||||
channel_dimm_label_show, channel_dimm_label_store, 13);
|
||||
DEVICE_CHANNEL(ch14_dimm_label, S_IRUGO | S_IWUSR,
|
||||
channel_dimm_label_show, channel_dimm_label_store, 14);
|
||||
DEVICE_CHANNEL(ch15_dimm_label, S_IRUGO | S_IWUSR,
|
||||
channel_dimm_label_show, channel_dimm_label_store, 15);
|
||||
|
||||
/* Total possible dynamic DIMM Label attribute file table */
|
||||
static struct attribute *dynamic_csrow_dimm_attr[] = {
|
||||
@@ -321,6 +329,10 @@ static struct attribute *dynamic_csrow_dimm_attr[] = {
|
||||
&dev_attr_legacy_ch9_dimm_label.attr.attr,
|
||||
&dev_attr_legacy_ch10_dimm_label.attr.attr,
|
||||
&dev_attr_legacy_ch11_dimm_label.attr.attr,
|
||||
&dev_attr_legacy_ch12_dimm_label.attr.attr,
|
||||
&dev_attr_legacy_ch13_dimm_label.attr.attr,
|
||||
&dev_attr_legacy_ch14_dimm_label.attr.attr,
|
||||
&dev_attr_legacy_ch15_dimm_label.attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -349,6 +361,14 @@ DEVICE_CHANNEL(ch10_ce_count, S_IRUGO,
|
||||
channel_ce_count_show, NULL, 10);
|
||||
DEVICE_CHANNEL(ch11_ce_count, S_IRUGO,
|
||||
channel_ce_count_show, NULL, 11);
|
||||
DEVICE_CHANNEL(ch12_ce_count, S_IRUGO,
|
||||
channel_ce_count_show, NULL, 12);
|
||||
DEVICE_CHANNEL(ch13_ce_count, S_IRUGO,
|
||||
channel_ce_count_show, NULL, 13);
|
||||
DEVICE_CHANNEL(ch14_ce_count, S_IRUGO,
|
||||
channel_ce_count_show, NULL, 14);
|
||||
DEVICE_CHANNEL(ch15_ce_count, S_IRUGO,
|
||||
channel_ce_count_show, NULL, 15);
|
||||
|
||||
/* Total possible dynamic ce_count attribute file table */
|
||||
static struct attribute *dynamic_csrow_ce_count_attr[] = {
|
||||
@@ -364,6 +384,10 @@ static struct attribute *dynamic_csrow_ce_count_attr[] = {
|
||||
&dev_attr_legacy_ch9_ce_count.attr.attr,
|
||||
&dev_attr_legacy_ch10_ce_count.attr.attr,
|
||||
&dev_attr_legacy_ch11_ce_count.attr.attr,
|
||||
&dev_attr_legacy_ch12_ce_count.attr.attr,
|
||||
&dev_attr_legacy_ch13_ce_count.attr.attr,
|
||||
&dev_attr_legacy_ch14_ce_count.attr.attr,
|
||||
&dev_attr_legacy_ch15_ce_count.attr.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* GPIO library for the ACCES IDIO-16 family
|
||||
* Copyright (C) 2022 William Breathitt Gray
|
||||
*/
|
||||
#include <linux/bitmap.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
@@ -106,6 +107,7 @@ int devm_idio_16_regmap_register(struct device *const dev,
|
||||
struct idio_16_data *data;
|
||||
struct regmap_irq_chip *chip;
|
||||
struct regmap_irq_chip_data *chip_data;
|
||||
DECLARE_BITMAP(fixed_direction_output, IDIO_16_NGPIO);
|
||||
|
||||
if (!config->parent)
|
||||
return -EINVAL;
|
||||
@@ -163,6 +165,9 @@ int devm_idio_16_regmap_register(struct device *const dev,
|
||||
gpio_config.irq_domain = regmap_irq_get_domain(chip_data);
|
||||
gpio_config.reg_mask_xlate = idio_16_reg_mask_xlate;
|
||||
|
||||
bitmap_from_u64(fixed_direction_output, GENMASK_U64(15, 0));
|
||||
gpio_config.fixed_direction_output = fixed_direction_output;
|
||||
|
||||
return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_idio_16_regmap_register);
|
||||
|
||||
@@ -29,6 +29,12 @@ struct gpio_regmap {
|
||||
unsigned int reg_clr_base;
|
||||
unsigned int reg_dir_in_base;
|
||||
unsigned int reg_dir_out_base;
|
||||
unsigned long *fixed_direction_output;
|
||||
|
||||
#ifdef CONFIG_REGMAP_IRQ
|
||||
int regmap_irq_line;
|
||||
struct regmap_irq_chip_data *irq_chip_data;
|
||||
#endif
|
||||
|
||||
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
|
||||
unsigned int offset, unsigned int *reg,
|
||||
@@ -117,6 +123,13 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip,
|
||||
unsigned int base, val, reg, mask;
|
||||
int invert, ret;
|
||||
|
||||
if (gpio->fixed_direction_output) {
|
||||
if (test_bit(offset, gpio->fixed_direction_output))
|
||||
return GPIO_LINE_DIRECTION_OUT;
|
||||
else
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
}
|
||||
|
||||
if (gpio->reg_dat_base && !gpio->reg_set_base)
|
||||
return GPIO_LINE_DIRECTION_IN;
|
||||
if (gpio->reg_set_base && !gpio->reg_dat_base)
|
||||
@@ -203,6 +216,7 @@ EXPORT_SYMBOL_GPL(gpio_regmap_get_drvdata);
|
||||
*/
|
||||
struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config)
|
||||
{
|
||||
struct irq_domain *irq_domain;
|
||||
struct gpio_regmap *gpio;
|
||||
struct gpio_chip *chip;
|
||||
int ret;
|
||||
@@ -274,12 +288,37 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
|
||||
chip->direction_output = gpio_regmap_direction_output;
|
||||
}
|
||||
|
||||
if (config->fixed_direction_output) {
|
||||
gpio->fixed_direction_output = bitmap_alloc(chip->ngpio,
|
||||
GFP_KERNEL);
|
||||
if (!gpio->fixed_direction_output) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_gpio;
|
||||
}
|
||||
bitmap_copy(gpio->fixed_direction_output,
|
||||
config->fixed_direction_output, chip->ngpio);
|
||||
}
|
||||
|
||||
ret = gpiochip_add_data(chip, gpio);
|
||||
if (ret < 0)
|
||||
goto err_free_gpio;
|
||||
goto err_free_bitmap;
|
||||
|
||||
if (config->irq_domain) {
|
||||
ret = gpiochip_irqchip_add_domain(chip, config->irq_domain);
|
||||
#ifdef CONFIG_REGMAP_IRQ
|
||||
if (config->regmap_irq_chip) {
|
||||
gpio->regmap_irq_line = config->regmap_irq_line;
|
||||
ret = regmap_add_irq_chip_fwnode(dev_fwnode(config->parent), config->regmap,
|
||||
config->regmap_irq_line, config->regmap_irq_flags,
|
||||
0, config->regmap_irq_chip, &gpio->irq_chip_data);
|
||||
if (ret)
|
||||
goto err_free_bitmap;
|
||||
|
||||
irq_domain = regmap_irq_get_domain(gpio->irq_chip_data);
|
||||
} else
|
||||
#endif
|
||||
irq_domain = config->irq_domain;
|
||||
|
||||
if (irq_domain) {
|
||||
ret = gpiochip_irqchip_add_domain(chip, irq_domain);
|
||||
if (ret)
|
||||
goto err_remove_gpiochip;
|
||||
}
|
||||
@@ -288,6 +327,8 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config
|
||||
|
||||
err_remove_gpiochip:
|
||||
gpiochip_remove(chip);
|
||||
err_free_bitmap:
|
||||
bitmap_free(gpio->fixed_direction_output);
|
||||
err_free_gpio:
|
||||
kfree(gpio);
|
||||
return ERR_PTR(ret);
|
||||
@@ -300,7 +341,13 @@ EXPORT_SYMBOL_GPL(gpio_regmap_register);
|
||||
*/
|
||||
void gpio_regmap_unregister(struct gpio_regmap *gpio)
|
||||
{
|
||||
#ifdef CONFIG_REGMAP_IRQ
|
||||
if (gpio->irq_chip_data)
|
||||
regmap_del_irq_chip(gpio->regmap_irq_line, gpio->irq_chip_data);
|
||||
#endif
|
||||
|
||||
gpiochip_remove(&gpio->gpio_chip);
|
||||
bitmap_free(gpio->fixed_direction_output);
|
||||
kfree(gpio);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpio_regmap_unregister);
|
||||
|
||||
@@ -329,8 +329,9 @@ struct sc16is7xx_one {
|
||||
struct kthread_work reg_work;
|
||||
struct kthread_delayed_work ms_work;
|
||||
struct sc16is7xx_one_config config;
|
||||
bool irda_mode;
|
||||
unsigned int old_mctrl;
|
||||
u8 old_lcr; /* Value before EFR access. */
|
||||
bool irda_mode;
|
||||
};
|
||||
|
||||
struct sc16is7xx_port {
|
||||
@@ -355,10 +356,6 @@ static struct uart_driver sc16is7xx_uart = {
|
||||
.nr = SC16IS7XX_MAX_DEVS,
|
||||
};
|
||||
|
||||
static void sc16is7xx_ier_set(struct uart_port *port, u8 bit);
|
||||
static void sc16is7xx_stop_tx(struct uart_port *port);
|
||||
|
||||
#define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e)))
|
||||
#define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e)))
|
||||
|
||||
static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)
|
||||
@@ -416,6 +413,85 @@ static void sc16is7xx_power(struct uart_port *port, int on)
|
||||
on ? 0 : SC16IS7XX_IER_SLEEP_BIT);
|
||||
}
|
||||
|
||||
/*
|
||||
* In an amazing feat of design, the Enhanced Features Register (EFR)
|
||||
* shares the address of the Interrupt Identification Register (IIR).
|
||||
* Access to EFR is switched on by writing a magic value (0xbf) to the
|
||||
* Line Control Register (LCR). Any interrupt firing during this time will
|
||||
* see the EFR where it expects the IIR to be, leading to
|
||||
* "Unexpected interrupt" messages.
|
||||
*
|
||||
* Prevent this possibility by claiming a mutex while accessing the EFR,
|
||||
* and claiming the same mutex from within the interrupt handler. This is
|
||||
* similar to disabling the interrupt, but that doesn't work because the
|
||||
* bulk of the interrupt processing is run as a workqueue job in thread
|
||||
* context.
|
||||
*/
|
||||
static void sc16is7xx_efr_lock(struct uart_port *port)
|
||||
{
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
|
||||
mutex_lock(&one->efr_lock);
|
||||
|
||||
/* Backup content of LCR. */
|
||||
one->old_lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
|
||||
|
||||
/* Enable access to Enhanced register set */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B);
|
||||
|
||||
/* Disable cache updates when writing to EFR registers */
|
||||
regcache_cache_bypass(one->regmap, true);
|
||||
}
|
||||
|
||||
static void sc16is7xx_efr_unlock(struct uart_port *port)
|
||||
{
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
|
||||
/* Re-enable cache updates when writing to normal registers */
|
||||
regcache_cache_bypass(one->regmap, false);
|
||||
|
||||
/* Restore original content of LCR */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, one->old_lcr);
|
||||
|
||||
mutex_unlock(&one->efr_lock);
|
||||
}
|
||||
|
||||
static void sc16is7xx_ier_clear(struct uart_port *port, u8 bit)
|
||||
{
|
||||
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
|
||||
lockdep_assert_held_once(&port->lock);
|
||||
|
||||
one->config.flags |= SC16IS7XX_RECONF_IER;
|
||||
one->config.ier_mask |= bit;
|
||||
one->config.ier_val &= ~bit;
|
||||
kthread_queue_work(&s->kworker, &one->reg_work);
|
||||
}
|
||||
|
||||
static void sc16is7xx_ier_set(struct uart_port *port, u8 bit)
|
||||
{
|
||||
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
|
||||
lockdep_assert_held_once(&port->lock);
|
||||
|
||||
one->config.flags |= SC16IS7XX_RECONF_IER;
|
||||
one->config.ier_mask |= bit;
|
||||
one->config.ier_val |= bit;
|
||||
kthread_queue_work(&s->kworker, &one->reg_work);
|
||||
}
|
||||
|
||||
static void sc16is7xx_stop_tx(struct uart_port *port)
|
||||
{
|
||||
sc16is7xx_ier_clear(port, SC16IS7XX_IER_THRI_BIT);
|
||||
}
|
||||
|
||||
static void sc16is7xx_stop_rx(struct uart_port *port)
|
||||
{
|
||||
sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT);
|
||||
}
|
||||
|
||||
static const struct sc16is7xx_devtype sc16is74x_devtype = {
|
||||
.name = "SC16IS74X",
|
||||
.nr_gpio = 0,
|
||||
@@ -506,40 +582,6 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
|
||||
div /= prescaler;
|
||||
}
|
||||
|
||||
/* In an amazing feat of design, the Enhanced Features Register shares
|
||||
* the address of the Interrupt Identification Register, and is
|
||||
* switched in by writing a magic value (0xbf) to the Line Control
|
||||
* Register. Any interrupt firing during this time will see the EFR
|
||||
* where it expects the IIR to be, leading to "Unexpected interrupt"
|
||||
* messages.
|
||||
*
|
||||
* Prevent this possibility by claiming a mutex while accessing the
|
||||
* EFR, and claiming the same mutex from within the interrupt handler.
|
||||
* This is similar to disabling the interrupt, but that doesn't work
|
||||
* because the bulk of the interrupt processing is run as a workqueue
|
||||
* job in thread context.
|
||||
*/
|
||||
mutex_lock(&one->efr_lock);
|
||||
|
||||
lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
|
||||
|
||||
/* Open the LCR divisors for configuration */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
|
||||
SC16IS7XX_LCR_CONF_MODE_B);
|
||||
|
||||
/* Enable enhanced features */
|
||||
regcache_cache_bypass(one->regmap, true);
|
||||
sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
|
||||
SC16IS7XX_EFR_ENABLE_BIT,
|
||||
SC16IS7XX_EFR_ENABLE_BIT);
|
||||
|
||||
regcache_cache_bypass(one->regmap, false);
|
||||
|
||||
/* Put LCR back to the normal mode */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
|
||||
|
||||
mutex_unlock(&one->efr_lock);
|
||||
|
||||
/* If bit MCR_CLKSEL is set, the divide by 4 prescaler is activated. */
|
||||
sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
|
||||
SC16IS7XX_MCR_CLKSEL_BIT,
|
||||
@@ -547,7 +589,8 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
|
||||
|
||||
mutex_lock(&one->efr_lock);
|
||||
|
||||
/* Open the LCR divisors for configuration */
|
||||
/* Backup LCR and access special register set (DLL/DLH) */
|
||||
lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
|
||||
SC16IS7XX_LCR_CONF_MODE_A);
|
||||
|
||||
@@ -557,7 +600,7 @@ static int sc16is7xx_set_baud(struct uart_port *port, int baud)
|
||||
sc16is7xx_port_write(port, SC16IS7XX_DLL_REG, div % 256);
|
||||
regcache_cache_bypass(one->regmap, false);
|
||||
|
||||
/* Put LCR back to the normal mode */
|
||||
/* Restore LCR and access to general register set */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
|
||||
|
||||
mutex_unlock(&one->efr_lock);
|
||||
@@ -889,42 +932,6 @@ static void sc16is7xx_reg_proc(struct kthread_work *ws)
|
||||
sc16is7xx_reconf_rs485(&one->port);
|
||||
}
|
||||
|
||||
static void sc16is7xx_ier_clear(struct uart_port *port, u8 bit)
|
||||
{
|
||||
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
|
||||
lockdep_assert_held_once(&port->lock);
|
||||
|
||||
one->config.flags |= SC16IS7XX_RECONF_IER;
|
||||
one->config.ier_mask |= bit;
|
||||
one->config.ier_val &= ~bit;
|
||||
kthread_queue_work(&s->kworker, &one->reg_work);
|
||||
}
|
||||
|
||||
static void sc16is7xx_ier_set(struct uart_port *port, u8 bit)
|
||||
{
|
||||
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
|
||||
|
||||
lockdep_assert_held_once(&port->lock);
|
||||
|
||||
one->config.flags |= SC16IS7XX_RECONF_IER;
|
||||
one->config.ier_mask |= bit;
|
||||
one->config.ier_val |= bit;
|
||||
kthread_queue_work(&s->kworker, &one->reg_work);
|
||||
}
|
||||
|
||||
static void sc16is7xx_stop_tx(struct uart_port *port)
|
||||
{
|
||||
sc16is7xx_ier_clear(port, SC16IS7XX_IER_THRI_BIT);
|
||||
}
|
||||
|
||||
static void sc16is7xx_stop_rx(struct uart_port *port)
|
||||
{
|
||||
sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT);
|
||||
}
|
||||
|
||||
static void sc16is7xx_ms_proc(struct kthread_work *ws)
|
||||
{
|
||||
struct sc16is7xx_one *one = to_sc16is7xx_one(ws, ms_work.work);
|
||||
@@ -1074,17 +1081,7 @@ static void sc16is7xx_set_termios(struct uart_port *port,
|
||||
if (!(termios->c_cflag & CREAD))
|
||||
port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK;
|
||||
|
||||
/* As above, claim the mutex while accessing the EFR. */
|
||||
mutex_lock(&one->efr_lock);
|
||||
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
|
||||
SC16IS7XX_LCR_CONF_MODE_B);
|
||||
|
||||
/* Configure flow control */
|
||||
regcache_cache_bypass(one->regmap, true);
|
||||
sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]);
|
||||
sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]);
|
||||
|
||||
port->status &= ~(UPSTAT_AUTOCTS | UPSTAT_AUTORTS);
|
||||
if (termios->c_cflag & CRTSCTS) {
|
||||
flow |= SC16IS7XX_EFR_AUTOCTS_BIT |
|
||||
@@ -1096,16 +1093,16 @@ static void sc16is7xx_set_termios(struct uart_port *port,
|
||||
if (termios->c_iflag & IXOFF)
|
||||
flow |= SC16IS7XX_EFR_SWFLOW1_BIT;
|
||||
|
||||
sc16is7xx_port_update(port,
|
||||
SC16IS7XX_EFR_REG,
|
||||
SC16IS7XX_EFR_FLOWCTRL_BITS,
|
||||
flow);
|
||||
regcache_cache_bypass(one->regmap, false);
|
||||
|
||||
/* Update LCR register */
|
||||
sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
|
||||
|
||||
mutex_unlock(&one->efr_lock);
|
||||
/* Update EFR registers */
|
||||
sc16is7xx_efr_lock(port);
|
||||
sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]);
|
||||
sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]);
|
||||
sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
|
||||
SC16IS7XX_EFR_FLOWCTRL_BITS, flow);
|
||||
sc16is7xx_efr_unlock(port);
|
||||
|
||||
/* Get baud rate generator configuration */
|
||||
baud = uart_get_baud_rate(port, termios, old,
|
||||
|
||||
@@ -665,7 +665,8 @@ static int xhci_dbc_start(struct xhci_dbc *dbc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return mod_delayed_work(system_wq, &dbc->event_work, 1);
|
||||
return mod_delayed_work(system_wq, &dbc->event_work,
|
||||
msecs_to_jiffies(dbc->poll_interval));
|
||||
}
|
||||
|
||||
static void xhci_dbc_stop(struct xhci_dbc *dbc)
|
||||
@@ -854,6 +855,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
|
||||
{
|
||||
dma_addr_t deq;
|
||||
union xhci_trb *evt;
|
||||
enum evtreturn ret = EVT_DONE;
|
||||
u32 ctrl, portsc;
|
||||
bool update_erdp = false;
|
||||
|
||||
@@ -878,7 +880,8 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
|
||||
dev_info(dbc->dev, "DbC configured\n");
|
||||
portsc = readl(&dbc->regs->portsc);
|
||||
writel(portsc, &dbc->regs->portsc);
|
||||
return EVT_GSER;
|
||||
ret = EVT_GSER;
|
||||
break;
|
||||
}
|
||||
|
||||
return EVT_DONE;
|
||||
@@ -938,6 +941,8 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
|
||||
break;
|
||||
case TRB_TYPE(TRB_TRANSFER):
|
||||
dbc_handle_xfer_event(dbc, evt);
|
||||
if (ret != EVT_GSER)
|
||||
ret = EVT_XFER_DONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -956,7 +961,7 @@ static enum evtreturn xhci_dbc_do_handle_events(struct xhci_dbc *dbc)
|
||||
lo_hi_writeq(deq, &dbc->regs->erdp);
|
||||
}
|
||||
|
||||
return EVT_DONE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void xhci_dbc_handle_events(struct work_struct *work)
|
||||
@@ -964,8 +969,11 @@ static void xhci_dbc_handle_events(struct work_struct *work)
|
||||
enum evtreturn evtr;
|
||||
struct xhci_dbc *dbc;
|
||||
unsigned long flags;
|
||||
unsigned int poll_interval;
|
||||
unsigned long busypoll_timelimit;
|
||||
|
||||
dbc = container_of(to_delayed_work(work), struct xhci_dbc, event_work);
|
||||
poll_interval = dbc->poll_interval;
|
||||
|
||||
spin_lock_irqsave(&dbc->lock, flags);
|
||||
evtr = xhci_dbc_do_handle_events(dbc);
|
||||
@@ -981,13 +989,28 @@ static void xhci_dbc_handle_events(struct work_struct *work)
|
||||
dbc->driver->disconnect(dbc);
|
||||
break;
|
||||
case EVT_DONE:
|
||||
/*
|
||||
* Set fast poll rate if there are pending out transfers, or
|
||||
* a transfer was recently processed
|
||||
*/
|
||||
busypoll_timelimit = dbc->xfer_timestamp +
|
||||
msecs_to_jiffies(DBC_XFER_INACTIVITY_TIMEOUT);
|
||||
|
||||
if (!list_empty(&dbc->eps[BULK_OUT].list_pending) ||
|
||||
time_is_after_jiffies(busypoll_timelimit))
|
||||
poll_interval = 0;
|
||||
break;
|
||||
case EVT_XFER_DONE:
|
||||
dbc->xfer_timestamp = jiffies;
|
||||
poll_interval = 0;
|
||||
break;
|
||||
default:
|
||||
dev_info(dbc->dev, "stop handling dbc events\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mod_delayed_work(system_wq, &dbc->event_work, 1);
|
||||
mod_delayed_work(system_wq, &dbc->event_work,
|
||||
msecs_to_jiffies(poll_interval));
|
||||
}
|
||||
|
||||
static ssize_t dbc_show(struct device *dev,
|
||||
@@ -1206,11 +1229,48 @@ static ssize_t dbc_bInterfaceProtocol_store(struct device *dev,
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t dbc_poll_interval_ms_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct xhci_dbc *dbc;
|
||||
struct xhci_hcd *xhci;
|
||||
|
||||
xhci = hcd_to_xhci(dev_get_drvdata(dev));
|
||||
dbc = xhci->dbc;
|
||||
|
||||
return sysfs_emit(buf, "%u\n", dbc->poll_interval);
|
||||
}
|
||||
|
||||
static ssize_t dbc_poll_interval_ms_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct xhci_dbc *dbc;
|
||||
struct xhci_hcd *xhci;
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
ret = kstrtou32(buf, 0, &value);
|
||||
if (ret || value > DBC_POLL_INTERVAL_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
xhci = hcd_to_xhci(dev_get_drvdata(dev));
|
||||
dbc = xhci->dbc;
|
||||
|
||||
dbc->poll_interval = value;
|
||||
|
||||
mod_delayed_work(system_wq, &dbc->event_work, 0);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(dbc);
|
||||
static DEVICE_ATTR_RW(dbc_idVendor);
|
||||
static DEVICE_ATTR_RW(dbc_idProduct);
|
||||
static DEVICE_ATTR_RW(dbc_bcdDevice);
|
||||
static DEVICE_ATTR_RW(dbc_bInterfaceProtocol);
|
||||
static DEVICE_ATTR_RW(dbc_poll_interval_ms);
|
||||
|
||||
static struct attribute *dbc_dev_attributes[] = {
|
||||
&dev_attr_dbc.attr,
|
||||
@@ -1218,6 +1278,7 @@ static struct attribute *dbc_dev_attributes[] = {
|
||||
&dev_attr_dbc_idProduct.attr,
|
||||
&dev_attr_dbc_bcdDevice.attr,
|
||||
&dev_attr_dbc_bInterfaceProtocol.attr,
|
||||
&dev_attr_dbc_poll_interval_ms.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -1242,6 +1303,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver *
|
||||
dbc->idVendor = DBC_VENDOR_ID;
|
||||
dbc->bcdDevice = DBC_DEVICE_REV;
|
||||
dbc->bInterfaceProtocol = DBC_PROTOCOL;
|
||||
dbc->poll_interval = DBC_POLL_INTERVAL_DEFAULT;
|
||||
|
||||
if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE)
|
||||
goto err;
|
||||
|
||||
@@ -93,7 +93,9 @@ struct dbc_ep {
|
||||
|
||||
#define DBC_QUEUE_SIZE 16
|
||||
#define DBC_WRITE_BUF_SIZE 8192
|
||||
|
||||
#define DBC_POLL_INTERVAL_DEFAULT 64 /* milliseconds */
|
||||
#define DBC_POLL_INTERVAL_MAX 5000 /* milliseconds */
|
||||
#define DBC_XFER_INACTIVITY_TIMEOUT 10 /* milliseconds */
|
||||
/*
|
||||
* Private structure for DbC hardware state:
|
||||
*/
|
||||
@@ -139,6 +141,8 @@ struct xhci_dbc {
|
||||
|
||||
enum dbc_state state;
|
||||
struct delayed_work event_work;
|
||||
unsigned int poll_interval; /* ms */
|
||||
unsigned long xfer_timestamp;
|
||||
unsigned resume_required:1;
|
||||
struct dbc_ep eps[2];
|
||||
|
||||
@@ -184,6 +188,7 @@ struct dbc_request {
|
||||
enum evtreturn {
|
||||
EVT_ERR = -1,
|
||||
EVT_DONE,
|
||||
EVT_XFER_DONE,
|
||||
EVT_GSER,
|
||||
EVT_DISC,
|
||||
};
|
||||
|
||||
@@ -2080,10 +2080,10 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
|
||||
|
||||
/* returns with log_tree_root freed on success */
|
||||
ret = btrfs_recover_log_trees(log_tree_root);
|
||||
btrfs_put_root(log_tree_root);
|
||||
if (ret) {
|
||||
btrfs_handle_fs_error(fs_info, ret,
|
||||
"Failed to recover log tree");
|
||||
btrfs_put_root(log_tree_root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -4175,7 +4175,8 @@ static int prepare_allocation_clustered(struct btrfs_fs_info *fs_info,
|
||||
}
|
||||
|
||||
static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
|
||||
struct find_free_extent_ctl *ffe_ctl)
|
||||
struct find_free_extent_ctl *ffe_ctl,
|
||||
struct btrfs_space_info *space_info)
|
||||
{
|
||||
if (ffe_ctl->for_treelog) {
|
||||
spin_lock(&fs_info->treelog_bg_lock);
|
||||
@@ -4199,6 +4200,7 @@ static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info,
|
||||
u64 avail = block_group->zone_capacity - block_group->alloc_offset;
|
||||
|
||||
if (block_group_bits(block_group, ffe_ctl->flags) &&
|
||||
block_group->space_info == space_info &&
|
||||
avail >= ffe_ctl->num_bytes) {
|
||||
ffe_ctl->hint_byte = block_group->start;
|
||||
break;
|
||||
@@ -4220,7 +4222,7 @@ static int prepare_allocation(struct btrfs_fs_info *fs_info,
|
||||
return prepare_allocation_clustered(fs_info, ffe_ctl,
|
||||
space_info, ins);
|
||||
case BTRFS_EXTENT_ALLOC_ZONED:
|
||||
return prepare_allocation_zoned(fs_info, ffe_ctl);
|
||||
return prepare_allocation_zoned(fs_info, ffe_ctl, space_info);
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
@@ -3051,9 +3051,10 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (btrfs_is_zoned(fs_info))
|
||||
btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
|
||||
ordered_extent->disk_num_bytes);
|
||||
ret = btrfs_zone_finish_endio(fs_info, ordered_extent->disk_bytenr,
|
||||
ordered_extent->disk_num_bytes);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered_extent->flags)) {
|
||||
truncated = true;
|
||||
|
||||
@@ -1271,8 +1271,7 @@ static void scrub_throttle_dev_io(struct scrub_ctx *sctx, struct btrfs_device *d
|
||||
* Slice is divided into intervals when the IO is submitted, adjust by
|
||||
* bwlimit and maximum of 64 intervals.
|
||||
*/
|
||||
div = max_t(u32, 1, (u32)(bwlimit / (16 * 1024 * 1024)));
|
||||
div = min_t(u32, 64, div);
|
||||
div = clamp(bwlimit / (16 * 1024 * 1024), 1, 64);
|
||||
|
||||
/* Start new epoch, set deadline */
|
||||
now = ktime_get();
|
||||
|
||||
@@ -1796,7 +1796,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
/* see comments in should_cow_block() */
|
||||
set_bit(BTRFS_ROOT_FORCE_COW, &root->state);
|
||||
smp_wmb();
|
||||
smp_mb__after_atomic();
|
||||
|
||||
btrfs_set_root_node(new_root_item, tmp);
|
||||
/* record when the snapshot was created in key.offset */
|
||||
|
||||
@@ -2493,15 +2493,13 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
if (level != 0)
|
||||
return 0;
|
||||
|
||||
ret = btrfs_read_extent_buffer(eb, &check);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
level = btrfs_header_level(eb);
|
||||
|
||||
if (level != 0)
|
||||
return 0;
|
||||
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
@@ -7422,7 +7420,6 @@ next:
|
||||
|
||||
log_root_tree->log_root = NULL;
|
||||
clear_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags);
|
||||
btrfs_put_root(log_root_tree);
|
||||
|
||||
return 0;
|
||||
error:
|
||||
|
||||
@@ -2263,16 +2263,17 @@ bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 length)
|
||||
int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 length)
|
||||
{
|
||||
struct btrfs_block_group *block_group;
|
||||
u64 min_alloc_bytes;
|
||||
|
||||
if (!btrfs_is_zoned(fs_info))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
block_group = btrfs_lookup_block_group(fs_info, logical);
|
||||
ASSERT(block_group);
|
||||
if (WARN_ON_ONCE(!block_group))
|
||||
return -ENOENT;
|
||||
|
||||
/* No MIXED_BG on zoned btrfs. */
|
||||
if (block_group->flags & BTRFS_BLOCK_GROUP_DATA)
|
||||
@@ -2289,6 +2290,7 @@ void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical, u64 len
|
||||
|
||||
out:
|
||||
btrfs_put_block_group(block_group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void btrfs_zone_finish_endio_workfn(struct work_struct *work)
|
||||
|
||||
@@ -71,7 +71,7 @@ int btrfs_sync_zone_write_pointer(struct btrfs_device *tgt_dev, u64 logical,
|
||||
bool btrfs_zone_activate(struct btrfs_block_group *block_group);
|
||||
int btrfs_zone_finish(struct btrfs_block_group *block_group);
|
||||
bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices, u64 flags);
|
||||
void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical,
|
||||
int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info, u64 logical,
|
||||
u64 length);
|
||||
void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg,
|
||||
struct extent_buffer *eb);
|
||||
@@ -227,8 +227,11 @@ static inline bool btrfs_can_activate_zone(struct btrfs_fs_devices *fs_devices,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info,
|
||||
u64 logical, u64 length) { }
|
||||
static inline int btrfs_zone_finish_endio(struct btrfs_fs_info *fs_info,
|
||||
u64 logical, u64 length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void btrfs_schedule_zone_finish_bg(struct btrfs_block_group *bg,
|
||||
struct extent_buffer *eb) { }
|
||||
|
||||
@@ -526,7 +526,7 @@ static inline void audit_log_kern_module(const char *name)
|
||||
|
||||
static inline void audit_fanotify(u32 response, struct fanotify_response_info_audit_rule *friar)
|
||||
{
|
||||
if (!audit_dummy_context())
|
||||
if (audit_enabled)
|
||||
__audit_fanotify(response, friar);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
# define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
|
||||
#endif
|
||||
|
||||
#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
|
||||
#define BITS_TO_LONGS(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
|
||||
#define BITS_TO_U64(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(u64))
|
||||
#define BITS_TO_U32(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
|
||||
#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
|
||||
#define BITS_PER_BYTE 8
|
||||
#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
|
||||
|
||||
/*
|
||||
* Create a contiguous bitmask starting at bit position @l and ending at
|
||||
@@ -18,17 +19,50 @@
|
||||
* GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
|
||||
*/
|
||||
#if !defined(__ASSEMBLY__)
|
||||
|
||||
/*
|
||||
* Missing asm support
|
||||
*
|
||||
* GENMASK_U*() depend on BITS_PER_TYPE() which relies on sizeof(),
|
||||
* something not available in asm. Nevertheless, fixed width integers is a C
|
||||
* concept. Assembly code can rely on the long and long long versions instead.
|
||||
*/
|
||||
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/overflow.h>
|
||||
#define GENMASK_INPUT_CHECK(h, l) \
|
||||
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \
|
||||
__is_constexpr((l) > (h)), (l) > (h), 0)))
|
||||
#else
|
||||
|
||||
/*
|
||||
* Generate a mask for the specified type @t. Additional checks are made to
|
||||
* guarantee the value returned fits in that type, relying on
|
||||
* -Wshift-count-overflow compiler check to detect incompatible arguments.
|
||||
* For example, all these create build errors or warnings:
|
||||
*
|
||||
* - GENMASK(15, 20): wrong argument order
|
||||
* - GENMASK(72, 15): doesn't fit unsigned long
|
||||
* - GENMASK_U32(33, 15): doesn't fit in a u32
|
||||
*/
|
||||
#define GENMASK_TYPE(t, h, l) \
|
||||
((t)(GENMASK_INPUT_CHECK(h, l) + \
|
||||
(type_max(t) << (l) & \
|
||||
type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h)))))
|
||||
|
||||
#define GENMASK_U8(h, l) GENMASK_TYPE(u8, h, l)
|
||||
#define GENMASK_U16(h, l) GENMASK_TYPE(u16, h, l)
|
||||
#define GENMASK_U32(h, l) GENMASK_TYPE(u32, h, l)
|
||||
#define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l)
|
||||
|
||||
#else /* defined(__ASSEMBLY__) */
|
||||
|
||||
/*
|
||||
* BUILD_BUG_ON_ZERO is not available in h files included from asm files,
|
||||
* disable the input check if that is the case.
|
||||
*/
|
||||
#define GENMASK_INPUT_CHECK(h, l) 0
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__ASSEMBLY__) */
|
||||
|
||||
#define __GENMASK(h, l) \
|
||||
(((~UL(0)) - (UL(1) << (l)) + 1) & \
|
||||
|
||||
@@ -37,9 +37,18 @@ struct regmap;
|
||||
* offset to a register/bitmask pair. If not
|
||||
* given the default gpio_regmap_simple_xlate()
|
||||
* is used.
|
||||
* @fixed_direction_output:
|
||||
* (Optional) Bitmap representing the fixed direction of
|
||||
* the GPIO lines. Useful when there are GPIO lines with a
|
||||
* fixed direction mixed together in the same register.
|
||||
* @drvdata: (Optional) Pointer to driver specific data which is
|
||||
* not used by gpio-remap but is provided "as is" to the
|
||||
* driver callback(s).
|
||||
* @regmap_irq_chip: (Optional) Pointer on an regmap_irq_chip structure. If
|
||||
* set, a regmap-irq device will be created and the IRQ
|
||||
* domain will be set accordingly.
|
||||
* @regmap_irq_line (Optional) The IRQ the device uses to signal interrupts.
|
||||
* @regmap_irq_flags (Optional) The IRQF_ flags to use for the interrupt.
|
||||
*
|
||||
* The ->reg_mask_xlate translates a given base address and GPIO offset to
|
||||
* register and mask pair. The base address is one of the given register
|
||||
@@ -77,6 +86,13 @@ struct gpio_regmap_config {
|
||||
int reg_stride;
|
||||
int ngpio_per_reg;
|
||||
struct irq_domain *irq_domain;
|
||||
unsigned long *fixed_direction_output;
|
||||
|
||||
#ifdef CONFIG_REGMAP_IRQ
|
||||
struct regmap_irq_chip *regmap_irq_chip;
|
||||
int regmap_irq_line;
|
||||
unsigned long regmap_irq_flags;
|
||||
#endif
|
||||
|
||||
int (*reg_mask_xlate)(struct gpio_regmap *gpio, unsigned int base,
|
||||
unsigned int offset, unsigned int *reg,
|
||||
|
||||
@@ -112,7 +112,6 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
|
||||
struct netlink_ext_ack *extack);
|
||||
void qdisc_put_rtab(struct qdisc_rate_table *tab);
|
||||
void qdisc_put_stab(struct qdisc_size_table *tab);
|
||||
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc);
|
||||
bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
|
||||
struct net_device *dev, struct netdev_queue *txq,
|
||||
spinlock_t *root_lock, bool validate);
|
||||
@@ -306,4 +305,28 @@ static inline bool tc_qdisc_stats_dump(struct Qdisc *sch,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
|
||||
{
|
||||
if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
|
||||
pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
|
||||
txt, qdisc->ops->id, qdisc->handle >> 16);
|
||||
qdisc->flags |= TCQ_F_WARN_NONWC;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned int qdisc_peek_len(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
skb = sch->ops->peek(sch);
|
||||
if (unlikely(skb == NULL)) {
|
||||
qdisc_warn_nonwc("qdisc_peek_len", sch);
|
||||
return 0;
|
||||
}
|
||||
len = qdisc_pkt_len(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -184,6 +184,10 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
|
||||
struct perf_callchain_entry_ctx ctx;
|
||||
int rctx;
|
||||
|
||||
/* crosstask is not supported for user stacks */
|
||||
if (crosstask && user && !kernel)
|
||||
return NULL;
|
||||
|
||||
entry = get_callchain_entry(&rctx);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
@@ -200,18 +204,15 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
|
||||
perf_callchain_kernel(&ctx, regs);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
if (user && !crosstask) {
|
||||
if (!user_mode(regs)) {
|
||||
if (current->mm)
|
||||
regs = task_pt_regs(current);
|
||||
else
|
||||
if (current->flags & (PF_KTHREAD | PF_USER_WORKER))
|
||||
regs = NULL;
|
||||
else
|
||||
regs = task_pt_regs(current);
|
||||
}
|
||||
|
||||
if (regs) {
|
||||
if (crosstask)
|
||||
goto exit_put;
|
||||
|
||||
if (add_mark)
|
||||
perf_callchain_store_context(&ctx, PERF_CONTEXT_USER);
|
||||
|
||||
@@ -219,7 +220,6 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user,
|
||||
}
|
||||
}
|
||||
|
||||
exit_put:
|
||||
put_callchain_entry(rctx);
|
||||
|
||||
return entry;
|
||||
|
||||
@@ -6985,7 +6985,7 @@ static void perf_sample_regs_user(struct perf_regs *regs_user,
|
||||
if (user_mode(regs)) {
|
||||
regs_user->abi = perf_reg_abi(current);
|
||||
regs_user->regs = regs;
|
||||
} else if (!(current->flags & PF_KTHREAD)) {
|
||||
} else if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
|
||||
perf_get_regs_user(regs_user, regs);
|
||||
} else {
|
||||
regs_user->abi = PERF_SAMPLE_REGS_ABI_NONE;
|
||||
@@ -7612,7 +7612,7 @@ static u64 perf_virt_to_phys(u64 virt)
|
||||
* Try IRQ-safe get_user_page_fast_only first.
|
||||
* If failed, leave phys_addr as 0.
|
||||
*/
|
||||
if (current->mm != NULL) {
|
||||
if (!(current->flags & (PF_KTHREAD | PF_USER_WORKER))) {
|
||||
struct page *p;
|
||||
|
||||
pagefault_disable();
|
||||
@@ -7724,7 +7724,8 @@ struct perf_callchain_entry *
|
||||
perf_callchain(struct perf_event *event, struct pt_regs *regs)
|
||||
{
|
||||
bool kernel = !event->attr.exclude_callchain_kernel;
|
||||
bool user = !event->attr.exclude_callchain_user;
|
||||
bool user = !event->attr.exclude_callchain_user &&
|
||||
!(current->flags & (PF_KTHREAD | PF_USER_WORKER));
|
||||
/* Disallow cross-task user callchains. */
|
||||
bool crosstask = event->ctx->task && event->ctx->task != current;
|
||||
const u32 max_stack = event->attr.sample_max_stack;
|
||||
|
||||
@@ -619,6 +619,10 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
|
||||
}
|
||||
|
||||
subflow:
|
||||
/* No need to try establishing subflows to remote id0 if not allowed */
|
||||
if (mptcp_pm_add_addr_c_flag_case(msk))
|
||||
goto exit;
|
||||
|
||||
/* check if should create a new subflow */
|
||||
while (msk->pm.local_addr_used < local_addr_max &&
|
||||
msk->pm.subflows < subflows_max) {
|
||||
@@ -650,6 +654,8 @@ subflow:
|
||||
__mptcp_subflow_connect(sk, &local.addr, &addrs[i]);
|
||||
spin_lock_bh(&msk->pm.lock);
|
||||
}
|
||||
|
||||
exit:
|
||||
mptcp_pm_nl_check_work_pending(msk);
|
||||
}
|
||||
|
||||
|
||||
@@ -599,16 +599,6 @@ out:
|
||||
qdisc_skb_cb(skb)->pkt_len = pkt_len;
|
||||
}
|
||||
|
||||
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
|
||||
{
|
||||
if (!(qdisc->flags & TCQ_F_WARN_NONWC)) {
|
||||
pr_warn("%s: %s qdisc %X: is non-work-conserving?\n",
|
||||
txt, qdisc->ops->id, qdisc->handle >> 16);
|
||||
qdisc->flags |= TCQ_F_WARN_NONWC;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(qdisc_warn_nonwc);
|
||||
|
||||
static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
|
||||
{
|
||||
struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
|
||||
|
||||
@@ -835,22 +835,6 @@ update_vf(struct hfsc_class *cl, unsigned int len, u64 cur_time)
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
qdisc_peek_len(struct Qdisc *sch)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int len;
|
||||
|
||||
skb = sch->ops->peek(sch);
|
||||
if (unlikely(skb == NULL)) {
|
||||
qdisc_warn_nonwc("qdisc_peek_len", sch);
|
||||
return 0;
|
||||
}
|
||||
len = qdisc_pkt_len(skb);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void
|
||||
hfsc_adjust_levels(struct hfsc_class *cl)
|
||||
{
|
||||
|
||||
@@ -1002,7 +1002,7 @@ static struct sk_buff *agg_dequeue(struct qfq_aggregate *agg,
|
||||
|
||||
if (cl->qdisc->q.qlen == 0) /* no more packets, remove from list */
|
||||
list_del_init(&cl->alist);
|
||||
else if (cl->deficit < qdisc_pkt_len(cl->qdisc->ops->peek(cl->qdisc))) {
|
||||
else if (cl->deficit < qdisc_peek_len(cl->qdisc)) {
|
||||
cl->deficit += agg->lmax;
|
||||
list_move_tail(&cl->alist, &agg->active);
|
||||
}
|
||||
|
||||
@@ -3837,7 +3837,8 @@ endpoint_tests()
|
||||
|
||||
# remove and re-add
|
||||
if reset_with_events "delete re-add signal" &&
|
||||
mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
|
||||
continue_if mptcp_lib_kallsyms_has "subflow_rebuild_header$"; then
|
||||
ip netns exec $ns1 sysctl -q net.mptcp.add_addr_timeout=0
|
||||
pm_nl_set_limits $ns1 0 3
|
||||
pm_nl_set_limits $ns2 3 3
|
||||
pm_nl_add_endpoint $ns1 10.0.2.1 id 1 flags signal
|
||||
|
||||
Reference in New Issue
Block a user