diff options
| -rw-r--r-- | Documentation/networking/ip-sysctl.txt | 4 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-modem.dtsi | 12 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/vplatform-lfv-smmu.dtsi | 2 | ||||
| -rw-r--r-- | arch/arm64/include/asm/esr.h | 40 | ||||
| -rw-r--r-- | arch/arm64/kernel/entry.S | 12 | ||||
| -rw-r--r-- | arch/arm64/kernel/traps.c | 33 | ||||
| -rw-r--r-- | drivers/clocksource/Kconfig | 8 | ||||
| -rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 8 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink.c | 36 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_private.h | 10 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_smem_native_xprt.c | 32 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_ssr.c | 13 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_xprt_if.h | 3 | ||||
| -rw-r--r-- | include/linux/inetdevice.h | 2 | ||||
| -rw-r--r-- | include/uapi/linux/ip.h | 1 | ||||
| -rw-r--r-- | include/uapi/linux/sysctl.h | 1 | ||||
| -rw-r--r-- | kernel/sysctl_binary.c | 1 | ||||
| -rw-r--r-- | net/ipv4/devinet.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/nf_defrag_ipv4.c | 10 | ||||
| -rw-r--r-- | sound/soc/msm/apq8096-auto.c | 148 |
20 files changed, 344 insertions, 34 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index f6851d94c1af..40dc329f142b 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1239,6 +1239,10 @@ igmp_link_local_mcast_reports - BOOLEAN 224.0.0.X range. Default TRUE +nf_ipv4_defrag_skip - BOOLEAN + Skip defragmentation per interface if set. + Default : 0 (always defrag) + Alexey Kuznetsov. kuznet@ms2.inr.ac.ru diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-modem.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-modem.dtsi index 67c53e450134..1be84c16b80a 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-modem.dtsi +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-modem.dtsi @@ -105,13 +105,13 @@ "halt_nc", "rmb_base", "restart_reg"; clocks = <&clock_gcc clk_cxo_clk_src>, - <&clock_gcc clk_gcc_mss_cfg_ahb_clk>, + <&clock_virt clk_gcc_mss_cfg_ahb_clk>, <&clock_gcc clk_pnoc_clk>, - <&clock_gcc clk_gcc_mss_q6_bimc_axi_clk>, - <&clock_gcc clk_gcc_boot_rom_ahb_clk>, - <&clock_gcc clk_gpll0_out_msscc>, - <&clock_gcc clk_gcc_mss_snoc_axi_clk>, - <&clock_gcc clk_gcc_mss_mnoc_bimc_axi_clk>, + <&clock_virt clk_gcc_mss_q6_bimc_axi_clk>, + <&clock_virt clk_gcc_boot_rom_ahb_clk>, + <&clock_virt clk_gpll0_out_msscc>, + <&clock_virt clk_gcc_mss_snoc_axi_clk>, + <&clock_virt clk_gcc_mss_mnoc_bimc_axi_clk>, <&clock_gcc clk_qdss_clk>; clock-names = "xo", "iface_clk", "pnoc_clk", "bus_clk", "mem_clk", "gpll0_mss_clk", "snoc_axi_clk", diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-smmu.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-smmu.dtsi index 2076ba08280e..04dae361cade 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-smmu.dtsi +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-smmu.dtsi @@ -33,7 +33,7 @@ <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>; vdd-supply = <&gdsc_hlos1_vote_lpass_adsp>; - clocks = <&clock_gcc clk_hlos1_vote_lpass_adsp_smmu_clk>; + clocks = <&clock_virt clk_hlos1_vote_lpass_adsp_smmu_clk>; clock-names = "lpass_q6_smmu_clocks"; #clock-cells = <1>; }; diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index f772e15c4766..2d4e9c26f8f6 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -109,6 +109,46 @@ ((ESR_ELx_EC_BRK64 << ESR_ELx_EC_SHIFT) | ESR_ELx_IL | \ ((imm) & 0xffff)) +/* ISS field definitions for System instruction traps */ +#define ESR_ELx_SYS64_ISS_RES0_SHIFT 22 +#define ESR_ELx_SYS64_ISS_RES0_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_RES0_SHIFT) +#define ESR_ELx_SYS64_ISS_DIR_MASK 0x1 +#define ESR_ELx_SYS64_ISS_DIR_READ 0x1 +#define ESR_ELx_SYS64_ISS_DIR_WRITE 0x0 + +#define ESR_ELx_SYS64_ISS_RT_SHIFT 5 +#define ESR_ELx_SYS64_ISS_RT_MASK (UL(0x1f) << ESR_ELx_SYS64_ISS_RT_SHIFT) +#define ESR_ELx_SYS64_ISS_CRM_SHIFT 1 +#define ESR_ELx_SYS64_ISS_CRM_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRM_SHIFT) +#define ESR_ELx_SYS64_ISS_CRN_SHIFT 10 +#define ESR_ELx_SYS64_ISS_CRN_MASK (UL(0xf) << ESR_ELx_SYS64_ISS_CRN_SHIFT) +#define ESR_ELx_SYS64_ISS_OP1_SHIFT 14 +#define ESR_ELx_SYS64_ISS_OP1_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP1_SHIFT) +#define ESR_ELx_SYS64_ISS_OP2_SHIFT 17 +#define ESR_ELx_SYS64_ISS_OP2_MASK (UL(0x7) << ESR_ELx_SYS64_ISS_OP2_SHIFT) +#define ESR_ELx_SYS64_ISS_OP0_SHIFT 20 +#define ESR_ELx_SYS64_ISS_OP0_MASK (UL(0x3) << ESR_ELx_SYS64_ISS_OP0_SHIFT) +#define ESR_ELx_SYS64_ISS_SYS_MASK (ESR_ELx_SYS64_ISS_OP0_MASK | \ + ESR_ELx_SYS64_ISS_OP1_MASK | \ + ESR_ELx_SYS64_ISS_OP2_MASK | \ + ESR_ELx_SYS64_ISS_CRN_MASK | \ + ESR_ELx_SYS64_ISS_CRM_MASK) +#define ESR_ELx_SYS64_ISS_SYS_VAL(op0, op1, op2, crn, crm) \ + (((op0) << ESR_ELx_SYS64_ISS_OP0_SHIFT) | \ + ((op1) << ESR_ELx_SYS64_ISS_OP1_SHIFT) | \ + ((op2) << ESR_ELx_SYS64_ISS_OP2_SHIFT) | \ + ((crn) << ESR_ELx_SYS64_ISS_CRN_SHIFT) | \ + ((crm) << ESR_ELx_SYS64_ISS_CRM_SHIFT)) + +#define ESR_ELx_SYS64_ISS_SYS_OP_MASK (ESR_ELx_SYS64_ISS_SYS_MASK | \ + ESR_ELx_SYS64_ISS_DIR_MASK) + +#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) + +#define ESR_ELx_SYS64_ISS_SYS_CNTFRQ (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 0, 14, 0) | \ + ESR_ELx_SYS64_ISS_DIR_READ) + #ifndef __ASSEMBLY__ #include <asm/types.h> diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 381f9febcdb6..c4a6865a2d4e 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -575,7 +575,7 @@ el0_sync: cmp x24, #ESR_ELx_EC_FP_EXC64 // FP/ASIMD exception b.eq el0_fpsimd_exc cmp x24, #ESR_ELx_EC_SYS64 // configurable trap - b.eq el0_undef + b.eq el0_sys cmp x24, #ESR_ELx_EC_SP_ALIGN // stack alignment exception b.eq el0_sp_pc cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception @@ -714,6 +714,16 @@ el0_undef: mov x0, sp bl do_undefinstr b ret_to_user +el0_sys: + /* + * System instructions, for trapped cache maintenance instructions + */ + enable_dbg_and_irq + ct_user_exit + mov x0, x25 + mov x1, sp + bl do_sysinstr + b ret_to_user el0_dbg: /* * Debug exception handling diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index f7834a3e4d64..f80faf3547c6 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -33,6 +33,7 @@ #include <linux/syscalls.h> #include <asm/atomic.h> +#include <asm/barrier.h> #include <asm/bug.h> #include <asm/debug-monitors.h> #include <asm/esr.h> @@ -449,6 +450,38 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) arm64_notify_die("Oops - undefined instruction", regs, &info, 0); } +static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs) +{ + int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; + + isb(); + if (rt != 31) + regs->regs[rt] = arch_counter_get_cntvct(); + regs->pc += 4; +} + +static void cntfrq_read_handler(unsigned int esr, struct pt_regs *regs) +{ + int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT; + + if (rt != 31) + regs->regs[rt] = read_sysreg(cntfrq_el0); + regs->pc += 4; +} + +asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs) +{ + if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTVCT) { + cntvct_read_handler(esr, regs); + return; + } else if ((esr & ESR_ELx_SYS64_ISS_SYS_OP_MASK) == ESR_ELx_SYS64_ISS_SYS_CNTFRQ) { + cntfrq_read_handler(esr, regs); + return; + } + + do_undefinstr(regs); +} + long compat_arm_syscall(struct pt_regs *regs); asmlinkage long do_ni_syscall(struct pt_regs *regs) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 8bf3355e95db..64b8158675b5 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -167,6 +167,14 @@ config MSM_TIMER_LEAP counter rollover. On every counter read if least significant 32 bits are set, reread counter. +config ARM_ARCH_TIMER_VCT_ACCESS + bool "Support for ARM architected timer virtual counter access in userspace" + default !ARM64 + depends on ARM_ARCH_TIMER + help + This option enables support for reading the ARM architected timer's + virtual counter in userspace. + config ARM_GLOBAL_TIMER bool select CLKSRC_OF if OF diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 5dc26d29e4a4..893c91a45e47 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -332,8 +332,12 @@ static void arch_counter_set_user_access(void) | ARCH_TIMER_VIRT_EVT_EN); /* Enable user access to the virtual and physical counters */ - cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN | ARCH_TIMER_USR_PCT_ACCESS_EN - | ARCH_TIMER_USR_VT_ACCESS_EN; + cntkctl |= ARCH_TIMER_USR_PCT_ACCESS_EN | ARCH_TIMER_USR_VT_ACCESS_EN; + + if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)) + cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; + else + cntkctl &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; arch_timer_set_cntkctl(cntkctl); } diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index f21e9c4c4f4e..813c97bb4a50 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -455,6 +455,42 @@ static void glink_put_ch_ctx(struct channel_ctx *ctx) rwref_put(&ctx->ch_state_lhb2); } + +/** + * glink_subsys_up() - Inform transport about remote subsystem up. + * @subsystem: The name of the subsystem + * + * Call into the transport using the subsys_up(if_ptr) function to allow it to + * initialize any necessary structures. + * + * Return: Standard error codes. + */ +int glink_subsys_up(const char *subsystem) +{ + int ret = 0; + bool transport_found = false; + struct glink_core_xprt_ctx *xprt_ctx = NULL; + + mutex_lock(&transport_list_lock_lha0); + list_for_each_entry(xprt_ctx, &transport_list, list_node) { + if (!strcmp(subsystem, xprt_ctx->edge) && + !xprt_is_fully_opened(xprt_ctx)) { + GLINK_INFO_XPRT(xprt_ctx, "%s: %s Subsystem up\n", + __func__, subsystem); + if (xprt_ctx->ops->subsys_up) + xprt_ctx->ops->subsys_up(xprt_ctx->ops); + transport_found = true; + } + } + mutex_unlock(&transport_list_lock_lha0); + + if (!transport_found) + ret = -ENODEV; + + return ret; +} +EXPORT_SYMBOL(glink_subsys_up); + /** * glink_ssr() - Clean up locally for SSR by simulating remote close * @subsystem: The name of the subsystem being restarted diff --git a/drivers/soc/qcom/glink_private.h b/drivers/soc/qcom/glink_private.h index e91ad30f73ab..c94ca7d57b2f 100644 --- a/drivers/soc/qcom/glink_private.h +++ b/drivers/soc/qcom/glink_private.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -817,6 +817,14 @@ uint32_t glink_ssr_get_seq_num(void); */ int glink_ssr(const char *subsystem); +/* + * glink_subsys_up() - SSR sub system up function. + * @subsystem: Constant string for name of remote subsystem. + * + * Return: Standard error code. + */ +int glink_subsys_up(const char *subsystem); + /** * notify for subsystem() - Notify other subsystems that a subsystem is being * restarted diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index a678e03235c0..4407dfbc45df 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -876,15 +876,6 @@ static void __rx_worker(struct edge_info *einfo, bool atomic_ctx) rcu_id = srcu_read_lock(&einfo->use_ref); - if (unlikely(!einfo->rx_fifo) && atomic_ctx) { - if (!get_rx_fifo(einfo)) { - srcu_read_unlock(&einfo->use_ref, rcu_id); - return; - } - einfo->in_ssr = false; - einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); - } - if (einfo->in_ssr) { srcu_read_unlock(&einfo->use_ref, rcu_id); return; @@ -1487,6 +1478,24 @@ static void tx_cmd_ch_remote_close_ack(struct glink_transport_if *if_ptr, } /** + * subsys_up() - process a subsystem up notification + * @if_ptr: The transport which is up + * + */ +static void subsys_up(struct glink_transport_if *if_ptr) +{ + struct edge_info *einfo; + + einfo = container_of(if_ptr, struct edge_info, xprt_if); + if (!einfo->rx_fifo) { + if (!get_rx_fifo(einfo)) + return; + einfo->in_ssr = false; + einfo->xprt_if.glink_core_if_ptr->link_up(&einfo->xprt_if); + } +} + +/** * ssr() - process a subsystem restart notification of a transport * @if_ptr: The transport to restart * @@ -2166,6 +2175,7 @@ static void init_xprt_if(struct edge_info *einfo) einfo->xprt_if.tx_cmd_ch_remote_open_ack = tx_cmd_ch_remote_open_ack; einfo->xprt_if.tx_cmd_ch_remote_close_ack = tx_cmd_ch_remote_close_ack; einfo->xprt_if.ssr = ssr; + einfo->xprt_if.subsys_up = subsys_up; einfo->xprt_if.allocate_rx_intent = allocate_rx_intent; einfo->xprt_if.deallocate_rx_intent = deallocate_rx_intent; einfo->xprt_if.tx_cmd_local_rx_intent = tx_cmd_local_rx_intent; @@ -2437,6 +2447,7 @@ static int glink_smem_native_probe(struct platform_device *pdev) rc); goto request_irq_fail; } + einfo->in_ssr = true; rc = enable_irq_wake(irq_line); if (rc < 0) pr_err("%s: enable_irq_wake() failed on %d\n", __func__, @@ -2941,6 +2952,7 @@ static int glink_mailbox_probe(struct platform_device *pdev) cfg_p_addr = smem_virt_to_phys(mbox_cfg); writel_relaxed(lower_32_bits(cfg_p_addr), mbox_loc); writel_relaxed(upper_32_bits(cfg_p_addr), mbox_loc + 4); + einfo->in_ssr = true; send_irq(einfo); iounmap(mbox_size); iounmap(mbox_loc); diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/soc/qcom/glink_ssr.c index fb003bd5d35b..fe7fb1e5b925 100644 --- a/drivers/soc/qcom/glink_ssr.c +++ b/drivers/soc/qcom/glink_ssr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -490,6 +490,17 @@ static int glink_ssr_restart_notifier_cb(struct notifier_block *this, "Subsystem notification failed", ret); return ret; } + } else if (code == SUBSYS_AFTER_POWERUP) { + GLINK_SSR_LOG("<SSR> %s: %s: subsystem restart for %s\n", + __func__, "SUBSYS_AFTER_POWERUP", + notifier->subsystem); + ss_info = get_info_for_subsystem(notifier->subsystem); + if (ss_info == NULL) { + GLINK_SSR_ERR("<SSR> %s: ss_info is NULL\n", __func__); + return -EINVAL; + } + + glink_subsys_up(ss_info->edge); } return NOTIFY_DONE; } diff --git a/drivers/soc/qcom/glink_xprt_if.h b/drivers/soc/qcom/glink_xprt_if.h index 47c15807e379..1902152d91cb 100644 --- a/drivers/soc/qcom/glink_xprt_if.h +++ b/drivers/soc/qcom/glink_xprt_if.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -105,6 +105,7 @@ struct glink_transport_if { void (*tx_cmd_ch_remote_close_ack)(struct glink_transport_if *if_ptr, uint32_t rcid); int (*ssr)(struct glink_transport_if *if_ptr); + void (*subsys_up)(struct glink_transport_if *if_ptr); /* channel data */ int (*allocate_rx_intent)(struct glink_transport_if *if_ptr, diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index ee971f335a8b..7118876e9896 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -128,6 +128,8 @@ static inline void ipv4_devconf_setall(struct in_device *in_dev) #define IN_DEV_ARP_ANNOUNCE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_ANNOUNCE) #define IN_DEV_ARP_IGNORE(in_dev) IN_DEV_MAXCONF((in_dev), ARP_IGNORE) #define IN_DEV_ARP_NOTIFY(in_dev) IN_DEV_MAXCONF((in_dev), ARP_NOTIFY) +#define IN_DEV_NF_IPV4_DEFRAG_SKIP(in_dev) \ + IN_DEV_ORCONF((in_dev), NF_IPV4_DEFRAG_SKIP) struct in_ifaddr { struct hlist_node hash; diff --git a/include/uapi/linux/ip.h b/include/uapi/linux/ip.h index 08f894d2ddbd..7b5e2aac86ac 100644 --- a/include/uapi/linux/ip.h +++ b/include/uapi/linux/ip.h @@ -165,6 +165,7 @@ enum IPV4_DEVCONF_IGMPV2_UNSOLICITED_REPORT_INTERVAL, IPV4_DEVCONF_IGMPV3_UNSOLICITED_REPORT_INTERVAL, IPV4_DEVCONF_IGNORE_ROUTES_WITH_LINKDOWN, + IPV4_DEVCONF_NF_IPV4_DEFRAG_SKIP, __IPV4_DEVCONF_MAX }; diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h index 01eb22ca6b3d..47e0de1df362 100644 --- a/include/uapi/linux/sysctl.h +++ b/include/uapi/linux/sysctl.h @@ -483,6 +483,7 @@ enum NET_IPV4_CONF_PROMOTE_SECONDARIES=20, NET_IPV4_CONF_ARP_ACCEPT=21, NET_IPV4_CONF_ARP_NOTIFY=22, + NET_IPV4_CONF_NF_IPV4_DEFRAG_SKIP = 23, }; /* /proc/sys/net/ipv4/netfilter */ diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 4a816bab38a2..d7612fcba10a 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -255,6 +255,7 @@ static const struct bin_table bin_net_ipv4_conf_vars_table[] = { { CTL_INT, NET_IPV4_CONF_NOPOLICY, "disable_policy" }, { CTL_INT, NET_IPV4_CONF_FORCE_IGMP_VERSION, "force_igmp_version" }, { CTL_INT, NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" }, + { CTL_INT, NET_IPV4_CONF_NF_IPV4_DEFRAG_SKIP, "nf_ipv4_defrag_skip" }, {} }; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 0212591b0077..1110e70e0ec6 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -2196,6 +2196,8 @@ static struct devinet_sysctl_table { "promote_secondaries"), DEVINET_SYSCTL_FLUSHING_ENTRY(ROUTE_LOCALNET, "route_localnet"), + DEVINET_SYSCTL_RW_ENTRY(NF_IPV4_DEFRAG_SKIP, + "nf_ipv4_defrag_skip"), }, }; diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index a04dee536b8e..39455484bd13 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c @@ -11,6 +11,7 @@ #include <linux/netfilter.h> #include <linux/module.h> #include <linux/skbuff.h> +#include <linux/inetdevice.h> #include <net/route.h> #include <net/ip.h> @@ -80,8 +81,13 @@ static unsigned int ipv4_conntrack_defrag(void *priv, #endif /* Gather fragments. */ if (ip_is_fragment(ip_hdr(skb))) { - enum ip_defrag_users user = - nf_ct_defrag_user(state->hook, skb); + enum ip_defrag_users user; + + if (skb->dev && + IN_DEV_NF_IPV4_DEFRAG_SKIP(__in_dev_get_rcu(skb->dev))) + return NF_ACCEPT; + + user = nf_ct_defrag_user(state->hook, skb); if (nf_ct_ipv4_gather_frags(state->net, skb, user)) return NF_STOLEN; diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c index 1fbdc7049d13..4bd4469d4904 100644 --- a/sound/soc/msm/apq8096-auto.c +++ b/sound/soc/msm/apq8096-auto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -150,6 +150,9 @@ static int msm_pri_tdm_rate = SAMPLING_RATE_48KHZ; static int msm_pri_tdm_slot_width = 32; static int msm_pri_tdm_slot_num = 8; +static int msm_sec_tdm_slot_width = 32; +static int msm_sec_tdm_slot_num = 8; + /* EC Reference default values are set in mixer_paths.xml */ static int msm_ec_ref_ch = 4; static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; @@ -494,13 +497,12 @@ static const char *const ec_ref_rate_text[] = {"0", "8000", "16000", static const char *const mi2s_rate_text[] = {"32000", "44100", "48000"}; -static const char *const pri_tdm_rate_text[] = {"8000", "16000", "48000"}; +static const char *const tdm_rate_text[] = {"8000", "16000", "48000"}; -static const char *const pri_tdm_slot_num_text[] = {"One", "Two", "Four", +static const char *const tdm_slot_num_text[] = {"One", "Two", "Four", "Eight", "Sixteen", "Thirtytwo"}; - -static const char *const pri_tdm_slot_width_text[] = {"16", "24", "32"}; +static const char *const tdm_slot_width_text[] = {"16", "24", "32"}; static struct afe_clk_set sec_mi2s_tx_clk = { AFE_API_VERSION_I2S_CONFIG, @@ -1142,6 +1144,98 @@ static int msm_pri_tdm_slot_num_put(struct snd_kcontrol *kcontrol, return 0; } +static int msm_sec_tdm_slot_width_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = msm_sec_tdm_slot_width; + pr_debug("%s: msm_sec_tdm_slot_width = %d\n", + __func__, msm_sec_tdm_slot_width); + return 0; +} + +static int msm_sec_tdm_slot_width_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_sec_tdm_slot_width = 16; + break; + case 1: + msm_sec_tdm_slot_width = 24; + break; + case 2: + msm_sec_tdm_slot_width = 32; + break; + default: + msm_sec_tdm_slot_width = 32; + break; + } + pr_debug("%s: msm_sec_tdm_slot_width= %d\n", + __func__, msm_sec_tdm_slot_width); + return 0; +} + +static int msm_sec_tdm_slot_num_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (msm_sec_tdm_slot_num) { + case 1: + ucontrol->value.integer.value[0] = 0; + break; + case 2: + ucontrol->value.integer.value[0] = 1; + break; + case 4: + ucontrol->value.integer.value[0] = 2; + break; + case 8: + ucontrol->value.integer.value[0] = 3; + break; + case 16: + ucontrol->value.integer.value[0] = 4; + break; + case 32: + default: + ucontrol->value.integer.value[0] = 5; + break; + } + + pr_debug("%s: msm_sec_tdm_slot_num = %d\n", + __func__, msm_sec_tdm_slot_num); + return 0; +} + +static int msm_sec_tdm_slot_num_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + switch (ucontrol->value.integer.value[0]) { + case 0: + msm_sec_tdm_slot_num = 1; + break; + case 1: + msm_sec_tdm_slot_num = 2; + break; + case 2: + msm_sec_tdm_slot_num = 4; + break; + case 3: + msm_sec_tdm_slot_num = 8; + break; + case 4: + msm_sec_tdm_slot_num = 16; + break; + case 5: + msm_sec_tdm_slot_num = 32; + break; + default: + msm_sec_tdm_slot_num = 8; + break; + } + pr_debug("%s: msm_sec_tdm_slot_num = %d\n", + __func__, msm_sec_tdm_slot_num); + return 0; +} + static int msm_tdm_slot_mapping_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -3336,7 +3430,7 @@ static unsigned int tdm_param_set_slot_mask(int slots) unsigned int slot_mask = 0; unsigned int i = 0; - if ((slots != 16) && (slots != 8)) { + if ((slots <= 0) || (slots > 32)) { pr_err("%s: invalid slot number %d\n", __func__, slots); return -EINVAL; } @@ -3470,51 +3564,83 @@ static int apq8096_tdm_snd_hw_params(struct snd_pcm_substream *substream, slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_7]; break; case AFE_PORT_ID_SECONDARY_TDM_RX: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_0]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_1: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_1]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_2: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_2]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_3: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_3]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_4: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_4]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_5: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_5]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_6: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_6]; break; case AFE_PORT_ID_SECONDARY_TDM_RX_7: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_RX_7]; break; case AFE_PORT_ID_SECONDARY_TDM_TX: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_0]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_1: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_1]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_2: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_2]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_3: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_3]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_4: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_4]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_5: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_5]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_6: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_6]; break; case AFE_PORT_ID_SECONDARY_TDM_TX_7: + slots = msm_sec_tdm_slot_num; + slot_width = msm_sec_tdm_slot_width; slot_offset = tdm_slot_offset[SECONDARY_TDM_TX_7]; break; case AFE_PORT_ID_TERTIARY_TDM_RX: @@ -3707,9 +3833,9 @@ static const struct soc_enum msm_snd_enum[] = { SOC_ENUM_SINGLE_EXT(3, ec_ref_bit_format_text), SOC_ENUM_SINGLE_EXT(9, ec_ref_rate_text), SOC_ENUM_SINGLE_EXT(3, mi2s_rate_text), - SOC_ENUM_SINGLE_EXT(3, pri_tdm_rate_text), - SOC_ENUM_SINGLE_EXT(6, pri_tdm_slot_num_text), - SOC_ENUM_SINGLE_EXT(3, pri_tdm_slot_width_text), + SOC_ENUM_SINGLE_EXT(3, tdm_rate_text), + SOC_ENUM_SINGLE_EXT(6, tdm_slot_num_text), + SOC_ENUM_SINGLE_EXT(3, tdm_slot_width_text), }; static const struct snd_kcontrol_new msm_snd_controls[] = { @@ -3908,6 +4034,10 @@ static const struct snd_kcontrol_new msm_snd_controls[] = { msm_pri_tdm_slot_num_get, msm_pri_tdm_slot_num_put), SOC_ENUM_EXT("PRI_TDM Slot Width", msm_snd_enum[14], msm_pri_tdm_slot_width_get, msm_pri_tdm_slot_width_put), + SOC_ENUM_EXT("SEC_TDM Slot Number", msm_snd_enum[13], + msm_sec_tdm_slot_num_get, msm_sec_tdm_slot_num_put), + SOC_ENUM_EXT("SEC_TDM Slot Width", msm_snd_enum[14], + msm_sec_tdm_slot_width_get, msm_sec_tdm_slot_width_put), SOC_SINGLE_MULTI_EXT("PRI_TDM_RX_0 Slot Mapping", SND_SOC_NOPM, PRIMARY_TDM_RX_0, 0xFFFF, 0, 8, msm_tdm_slot_mapping_get, |
