summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt4
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-modem.dtsi12
-rw-r--r--arch/arm/boot/dts/qcom/vplatform-lfv-smmu.dtsi2
-rw-r--r--arch/arm64/include/asm/esr.h40
-rw-r--r--arch/arm64/kernel/entry.S12
-rw-r--r--arch/arm64/kernel/traps.c33
-rw-r--r--drivers/clocksource/Kconfig8
-rw-r--r--drivers/clocksource/arm_arch_timer.c8
-rw-r--r--drivers/soc/qcom/glink.c36
-rw-r--r--drivers/soc/qcom/glink_private.h10
-rw-r--r--drivers/soc/qcom/glink_smem_native_xprt.c32
-rw-r--r--drivers/soc/qcom/glink_ssr.c13
-rw-r--r--drivers/soc/qcom/glink_xprt_if.h3
-rw-r--r--include/linux/inetdevice.h2
-rw-r--r--include/uapi/linux/ip.h1
-rw-r--r--include/uapi/linux/sysctl.h1
-rw-r--r--kernel/sysctl_binary.c1
-rw-r--r--net/ipv4/devinet.c2
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c10
-rw-r--r--sound/soc/msm/apq8096-auto.c148
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,