Merge "ARM: dts: msm: Add an energy model for the SDM845 CPUs" into msm-4.9
diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
index b661fe7..3d9d6f3 100644
--- a/arch/arm64/Kconfig.debug
+++ b/arch/arm64/Kconfig.debug
@@ -62,6 +62,9 @@
If in doubt, say N.
+config ARM64_STRICT_BREAK_BEFORE_MAKE
+ bool "Enforce strict break-before-make on page table updates "
+
source "drivers/hwtracing/coresight/Kconfig"
endmenu
diff --git a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
index e21ed36..4a8d06d 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-qrd.dtsi
@@ -11,6 +11,7 @@
*/
#include "smb1355.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/{
qrd_batterydata: qcom,battery-data {
@@ -18,6 +19,34 @@
#include "fg-gen3-batterydata-itech-3000mah.dtsi"
#include "fg-gen3-batterydata-ascent-3450mah.dtsi"
};
+
+ aliases {
+ serial0 = &qupv3_se9_2uart;
+ spi0 = &qupv3_se8_spi;
+ i2c0 = &qupv3_se10_i2c;
+ i2c1 = &qupv3_se3_i2c;
+ hsuart0 = &qupv3_se6_4uart;
+ };
+};
+
+&qupv3_se9_2uart {
+ status = "ok";
+};
+
+&qupv3_se8_spi {
+ status = "ok";
+};
+
+&qupv3_se3_i2c {
+ status = "ok";
+};
+
+&qupv3_se10_i2c {
+ status = "ok";
+};
+
+&qupv3_se6_4uart {
+ status = "ok";
};
&pmi8998_fg {
@@ -39,3 +68,53 @@
qcom,wsa-aux-dev-prefix = "SpkrRight", "SpkrRight";
};
};
+
+&ufsphy_mem {
+ compatible = "qcom,ufs-phy-qmp-v3";
+
+ vdda-phy-supply = <&pm8998_l1>; /* 0.88v */
+ vdda-pll-supply = <&pm8998_l26>; /* 1.2v */
+ vdda-phy-max-microamp = <62900>;
+ vdda-pll-max-microamp = <18300>;
+
+ status = "ok";
+};
+
+&ufshc_mem {
+ vdd-hba-supply = <&ufs_phy_gdsc>;
+ vdd-hba-fixed-regulator;
+ vcc-supply = <&pm8998_l20>;
+ vccq2-supply = <&pm8998_s4>;
+ vcc-max-microamp = <600000>;
+ vccq2-max-microamp = <600000>;
+
+ qcom,vddp-ref-clk-supply = <&pm8998_l2>;
+ qcom,vddp-ref-clk-max-microamp = <100>;
+
+ status = "ok";
+};
+
+&ufsphy_card {
+ compatible = "qcom,ufs-phy-qmp-v3";
+
+ vdda-phy-supply = <&pm8998_l1>; /* 0.88v */
+ vdda-pll-supply = <&pm8998_l26>; /* 1.2v */
+ vdda-phy-max-microamp = <62900>;
+ vdda-pll-max-microamp = <18300>;
+
+ status = "ok";
+};
+
+&ufshc_card {
+ vdd-hba-supply = <&ufs_card_gdsc>;
+ vdd-hba-fixed-regulator;
+ vcc-supply = <&pm8998_l21>;
+ vccq2-supply = <&pm8998_s4>;
+ vcc-max-microamp = <300000>;
+ vccq2-max-microamp = <300000>;
+
+ qcom,vddp-ref-clk-supply = <&pm8998_l2>;
+ qcom,vddp-ref-clk-max-microamp = <100>;
+
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi
index d7cfe4b..987d38b 100644
--- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -1795,6 +1795,11 @@
compatible = "qcom,msm-imem-kaslr_offset";
reg = <0x6d0 12>;
};
+
+ diag_dload@c8 {
+ compatible = "qcom,msm-imem-diag-dload";
+ reg = <0xc8 200>;
+ };
};
qcom,venus@aae0000 {
diff --git a/arch/arm64/configs/sdm845-perf_defconfig b/arch/arm64/configs/sdm845-perf_defconfig
index f39657b..37bdb3d 100644
--- a/arch/arm64/configs/sdm845-perf_defconfig
+++ b/arch/arm64/configs/sdm845-perf_defconfig
@@ -167,6 +167,7 @@
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
@@ -182,6 +183,7 @@
CONFIG_IP_NF_ARP_MANGLE=y
CONFIG_NF_CONNTRACK_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
diff --git a/arch/arm64/configs/sdm845_defconfig b/arch/arm64/configs/sdm845_defconfig
index 7919080..9601fba 100644
--- a/arch/arm64/configs/sdm845_defconfig
+++ b/arch/arm64/configs/sdm845_defconfig
@@ -174,6 +174,7 @@
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_AH=y
CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_RPFILTER=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
@@ -189,6 +190,7 @@
CONFIG_IP_NF_ARP_MANGLE=y
CONFIG_NF_CONNTRACK_IPV6=y
CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
CONFIG_IP6_NF_FILTER=y
CONFIG_IP6_NF_TARGET_REJECT=y
CONFIG_IP6_NF_MANGLE=y
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index ffbb9a5..875545d 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -19,6 +19,7 @@
#include <asm/bug.h>
#include <asm/proc-fns.h>
+#include <asm/bug.h>
#include <asm/memory.h>
#include <asm/pgtable-hwdef.h>
#include <asm/pgtable-prot.h>
@@ -172,6 +173,34 @@ static inline pmd_t pmd_mkcont(pmd_t pmd)
static inline void set_pte(pte_t *ptep, pte_t pte)
{
+#ifdef CONFIG_ARM64_STRICT_BREAK_BEFORE_MAKE
+ pteval_t old = pte_val(*ptep);
+ pteval_t new = pte_val(pte);
+
+ /* Only problematic if valid -> valid */
+ if (!(old & new & PTE_VALID))
+ goto pte_ok;
+
+ /* Changing attributes should go via an invalid entry */
+ if (WARN_ON((old & PTE_ATTRINDX_MASK) != (new & PTE_ATTRINDX_MASK)))
+ goto pte_bad;
+
+ /* Change of OA is only an issue if one mapping is writable */
+ if (!(old & new & PTE_RDONLY) &&
+ WARN_ON(pte_pfn(*ptep) != pte_pfn(pte)))
+ goto pte_bad;
+
+ goto pte_ok;
+
+pte_bad:
+ *ptep = __pte(0);
+ dsb(ishst);
+ asm("tlbi vmalle1is");
+ dsb(ish);
+ isb();
+pte_ok:
+#endif
+
*ptep = pte;
/*
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 0c4a5ee..da845fd 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -189,7 +189,7 @@ static void show_data(unsigned long addr, int nbytes, const char *name)
* don't attempt to dump non-kernel addresses or
* values that are probably just small negative numbers
*/
- if (addr < PAGE_OFFSET || addr > -256UL)
+ if (addr < KIMAGE_VADDR || addr > -256UL)
return;
printk("\n%s: %#lx:\n", name, addr);
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 40e775a..837bbab 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -1953,20 +1953,32 @@ EXPORT_SYMBOL(arm_iommu_release_mapping);
*
* Attaches specified io address space mapping to the provided device,
* this replaces the dma operations (dma_map_ops pointer) with the
- * IOMMU aware version. More than one client might be attached to
- * the same io address space mapping.
+ * IOMMU aware version. Only one device in an iommu_group may use this
+ * function.
*/
int arm_iommu_attach_device(struct device *dev,
struct dma_iommu_mapping *mapping)
{
int err;
int s1_bypass = 0, is_fast = 0;
+ struct iommu_group *group;
+
+ group = dev->iommu_group;
+ if (!group) {
+ dev_err(dev, "No iommu associated with device\n");
+ return -ENODEV;
+ }
+
+ if (iommu_get_domain_for_dev(dev)) {
+ dev_err(dev, "Device already attached to other iommu_domain\n");
+ return -EINVAL;
+ }
iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
if (is_fast)
return fast_smmu_attach_device(dev, mapping);
- err = iommu_attach_device(mapping->domain, dev);
+ err = iommu_attach_group(mapping->domain, group);
if (err)
return err;
@@ -1994,6 +2006,7 @@ void arm_iommu_detach_device(struct device *dev)
{
struct dma_iommu_mapping *mapping;
int is_fast, s1_bypass = 0;
+ struct iommu_group *group;
mapping = to_dma_iommu_mapping(dev);
if (!mapping) {
@@ -2013,7 +2026,13 @@ void arm_iommu_detach_device(struct device *dev)
if (msm_dma_unmap_all_for_dev(dev))
dev_warn(dev, "IOMMU detach with outstanding mappings\n");
- iommu_detach_device(mapping->domain, dev);
+ group = dev->iommu_group;
+ if (!group) {
+ dev_err(dev, "No iommu associated with device\n");
+ return;
+ }
+
+ iommu_detach_group(mapping->domain, group);
kref_put(&mapping->kref, release_iommu_mapping);
dev->archdata.mapping = NULL;
if (!s1_bypass)
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index b18a172..ee847d9f 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -306,7 +306,6 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = {
.subsys = "slpi",
.link.link_info.edge = "dsps",
.link.link_info.transport = "smem",
- .vmid = VMID_SSC_Q6,
},
{
.name = "cdsprpc-smd",
diff --git a/drivers/clk/qcom/clk-cpu-osm.c b/drivers/clk/qcom/clk-cpu-osm.c
index 035d337..884656f 100644
--- a/drivers/clk/qcom/clk-cpu-osm.c
+++ b/drivers/clk/qcom/clk-cpu-osm.c
@@ -2251,7 +2251,7 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
u32 pte_efuse, val;
int num_clks = ARRAY_SIZE(osm_qcom_clk_hws);
struct clk *ext_xo_clk, *clk;
- struct clk_osm *c;
+ struct clk_osm *c, *parent;
struct device *dev = &pdev->dev;
struct clk_onecell_data *clk_data;
char l3speedbinstr[] = "qcom,l3-speedbin0-v0";
@@ -2527,25 +2527,7 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
get_online_cpus();
- /* Enable OSM */
- for_each_online_cpu(cpu) {
- c = logical_cpu_to_clk(cpu);
- if (!c) {
- pr_err("no clock device for CPU=%d\n", cpu);
- return -EINVAL;
- }
-
- rc = clk_set_rate(c->hw.clk, init_rate);
- if (rc) {
- dev_err(&pdev->dev, "Unable to set init rate on CPU %d, rc=%d\n",
- cpu, rc);
- goto provider_err;
- }
- WARN(clk_prepare_enable(c->hw.clk),
- "Failed to enable clock for cpu %d\n", cpu);
- udelay(300);
- }
-
+ /* Set the L3 clock to run off GPLL0 and enable OSM for the domain */
rc = clk_set_rate(l3_clk.hw.clk, init_rate);
if (rc) {
dev_err(&pdev->dev, "Unable to set init rate on L3 cluster, rc=%d\n",
@@ -2556,6 +2538,43 @@ static int clk_cpu_osm_driver_probe(struct platform_device *pdev)
"Failed to enable clock for L3\n");
udelay(300);
+ /* Set CPU clocks to run off GPLL0 and enable OSM for both domains */
+ for_each_online_cpu(cpu) {
+ c = logical_cpu_to_clk(cpu);
+ if (!c) {
+ pr_err("no clock device for CPU=%d\n", cpu);
+ return -EINVAL;
+ }
+
+ parent = to_clk_osm(clk_hw_get_parent(&c->hw));
+ if (!parent->per_core_dcvs) {
+ if (cpu >= 0 && cpu <= 3)
+ c = logical_cpu_to_clk(0);
+ else if (cpu >= 4 && cpu <= 7)
+ c = logical_cpu_to_clk(4);
+ if (!c)
+ return -EINVAL;
+ }
+
+ rc = clk_set_rate(c->hw.clk, init_rate);
+ if (rc) {
+ dev_err(&pdev->dev, "Unable to set init rate on %s, rc=%d\n",
+ clk_hw_get_name(&parent->hw), rc);
+ goto provider_err;
+ }
+ WARN(clk_prepare_enable(c->hw.clk),
+ "Failed to enable OSM for %s\n",
+ clk_hw_get_name(&parent->hw));
+ udelay(300);
+ }
+
+ /*
+ * Add always-on votes for the CPU cluster clocks since we do not want
+ * to re-enable OSM at any point.
+ */
+ clk_prepare_enable(pwrcl_clk.hw.clk);
+ clk_prepare_enable(perfcl_clk.hw.clk);
+
populate_opp_table(pdev);
of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
diff --git a/drivers/clk/qcom/clk-debug.c b/drivers/clk/qcom/clk-debug.c
index 53288f7..fcc2493 100644
--- a/drivers/clk/qcom/clk-debug.c
+++ b/drivers/clk/qcom/clk-debug.c
@@ -133,12 +133,16 @@ static u8 clk_debug_mux_get_parent(struct clk_hw *hw)
{
struct clk_debug_mux *meas = to_clk_measure(hw);
int i, num_parents = clk_hw_get_num_parents(hw);
+ struct clk_hw *hw_clk = clk_hw_get_parent(hw);
+
+ if (!hw_clk)
+ return 0;
for (i = 0; i < num_parents; i++) {
if (!strcmp(meas->parent[i].parents,
- hw->init->parent_names[i])) {
- pr_debug("%s: Clock name %s index %d\n", __func__,
- hw->init->name, i);
+ clk_hw_get_name(hw_clk))) {
+ pr_debug("%s: clock parent - %s, index %d\n", __func__,
+ meas->parent[i].parents, i);
return i;
}
}
@@ -158,8 +162,8 @@ static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
/* Update the recursive debug mux */
regmap_read(meas->regmap[dbg_cc],
meas->parent[index].mux_offset, ®val);
- regval &= ~meas->parent[index].mux_sel_mask <<
- meas->parent[index].mux_sel_shift;
+ regval &= ~(meas->parent[index].mux_sel_mask <<
+ meas->parent[index].mux_sel_shift);
regval |= (meas->parent[index].dbg_cc_mux_sel &
meas->parent[index].mux_sel_mask) <<
meas->parent[index].mux_sel_shift;
@@ -168,31 +172,34 @@ static int clk_debug_mux_set_parent(struct clk_hw *hw, u8 index)
regmap_read(meas->regmap[dbg_cc],
meas->parent[index].post_div_offset, ®val);
- regval &= ~meas->parent[index].post_div_mask <<
- meas->parent[index].post_div_shift;
+ regval &= ~(meas->parent[index].post_div_mask <<
+ meas->parent[index].post_div_shift);
regval |= ((meas->parent[index].post_div_val - 1) &
meas->parent[index].post_div_mask) <<
meas->parent[index].post_div_shift;
regmap_write(meas->regmap[dbg_cc],
meas->parent[index].post_div_offset, regval);
- regmap_read(meas->regmap[dbg_cc],
+ /* Not all recursive muxes have a DEBUG clock. */
+ if (meas->parent[index].cbcr_offset != U32_MAX) {
+ regmap_read(meas->regmap[dbg_cc],
meas->parent[index].cbcr_offset, ®val);
- regval |= BIT(0);
- regmap_write(meas->regmap[dbg_cc],
+ regval |= BIT(0);
+ regmap_write(meas->regmap[dbg_cc],
meas->parent[index].cbcr_offset, regval);
+ }
}
/* Update the debug sel for GCC */
regmap_read(meas->regmap[GCC], meas->debug_offset, ®val);
- regval &= ~meas->src_sel_mask << meas->src_sel_shift;
+ regval &= ~(meas->src_sel_mask << meas->src_sel_shift);
regval |= (meas->parent[index].prim_mux_sel & meas->src_sel_mask) <<
meas->src_sel_shift;
regmap_write(meas->regmap[GCC], meas->debug_offset, regval);
/* Set the GCC mux's post divider bits */
regmap_read(meas->regmap[GCC], meas->post_div_offset, ®val);
- regval &= ~meas->post_div_mask << meas->post_div_shift;
+ regval &= ~(meas->post_div_mask << meas->post_div_shift);
regval |= ((meas->parent[index].prim_mux_div_val - 1) &
meas->post_div_mask) << meas->post_div_shift;
regmap_write(meas->regmap[GCC], meas->post_div_offset, regval);
@@ -234,6 +241,10 @@ static int clk_debug_measure_get(void *data, u64 *val)
if (meas->parent[index].dbg_cc != GCC)
*val *= meas->parent[index].post_div_val;
*val *= meas->parent[index].prim_mux_div_val;
+
+ /* Accommodate for any pre-set dividers */
+ if (meas->parent[index].misc_div_val)
+ *val *= meas->parent[index].misc_div_val;
}
meas_rate = clk_get_rate(hw->clk);
@@ -244,7 +255,6 @@ static int clk_debug_measure_get(void *data, u64 *val)
sw_rate = clk_get_rate(par->clk);
if (sw_rate && meas_rate >= (sw_rate * 2))
*val *= DIV_ROUND_CLOSEST(meas_rate, sw_rate);
-
mutex_unlock(&clk_debug_lock);
return ret;
diff --git a/drivers/clk/qcom/clk-debug.h b/drivers/clk/qcom/clk-debug.h
index 280704e..aa8d97b 100644
--- a/drivers/clk/qcom/clk-debug.h
+++ b/drivers/clk/qcom/clk-debug.h
@@ -66,6 +66,7 @@ enum debug_cc {
* @mux_offset: the debug mux offset.
* @post_div_offset: register with post-divider settings for the debug mux.
* @cbcr_offset: branch register to turn on debug mux.
+ * @misc_div_val: includes any pre-set dividers in the measurement logic.
*/
struct clk_src {
const char *parents;
@@ -81,6 +82,7 @@ struct clk_src {
u32 mux_offset;
u32 post_div_offset;
u32 cbcr_offset;
+ u32 misc_div_val;
};
#define MUX_SRC_LIST(...) \
diff --git a/drivers/clk/qcom/gcc-sdm845.c b/drivers/clk/qcom/gcc-sdm845.c
index 19041e7..29421a1 100644
--- a/drivers/clk/qcom/gcc-sdm845.c
+++ b/drivers/clk/qcom/gcc-sdm845.c
@@ -158,6 +158,12 @@ static const char * const gcc_parent_names_7[] = {
"core_bi_pll_test_se",
};
+static const char * const gcc_parent_names_8[] = {
+ "bi_tcxo_ao",
+ "gpll0",
+ "core_bi_pll_test_se",
+};
+
static struct clk_dummy measure_only_snoc_clk = {
.rrate = 1000,
.hw.init = &(struct clk_init_data){
@@ -298,11 +304,11 @@ static struct clk_rcg2 gcc_cpuss_rbcpr_clk_src = {
.freq_tbl = ftbl_gcc_cpuss_rbcpr_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "gcc_cpuss_rbcpr_clk_src",
- .parent_names = gcc_parent_names_3,
+ .parent_names = gcc_parent_names_8,
.num_parents = 3,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_rcg2_ops,
- VDD_CX_FMAX_MAP1(
+ VDD_CX_FMAX_MAP1_AO(
MIN, 19200000),
},
};
diff --git a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
index 2cb9d05..93ad1b0 100644
--- a/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
+++ b/drivers/clk/qcom/mdss/mdss-dsi-pll-10nm.c
@@ -603,6 +603,9 @@ static void vco_10nm_unprepare(struct clk_hw *hw)
pr_err("dsi pll resources not available\n");
return;
}
+ pll->cached_cfg0 = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG0);
+ pll->cached_cfg1 = MDSS_PLL_REG_R(pll->phy_base, PHY_CMN_CLK_CFG1);
+ pr_debug("cfg0=%d,cfg1=%d\n", pll->cached_cfg0, pll->cached_cfg1);
pll->vco_cached_rate = clk_hw_get_rate(hw);
dsi_pll_disable(vco);
@@ -637,6 +640,12 @@ static int vco_10nm_prepare(struct clk_hw *hw)
mdss_pll_resource_enable(pll, false);
return rc;
}
+ pr_debug("cfg0=%d, cfg1=%d\n", pll->cached_cfg0,
+ pll->cached_cfg1);
+ MDSS_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG0,
+ pll->cached_cfg0);
+ MDSS_PLL_REG_W(pll->phy_base, PHY_CMN_CLK_CFG1,
+ pll->cached_cfg1);
}
rc = dsi_pll_enable(vco);
@@ -1111,7 +1120,7 @@ static struct dsi_pll_vco_clk dsi0pll_vco_clk = {
.max_rate = 3500000000UL,
.hw.init = &(struct clk_init_data){
.name = "dsi0pll_vco_clk",
- .parent_names = (const char *[]){"xo_board"},
+ .parent_names = (const char *[]){"bi_tcxo"},
.num_parents = 1,
.ops = &clk_ops_vco_10nm,
.flags = CLK_GET_RATE_NOCACHE,
@@ -1124,7 +1133,7 @@ static struct dsi_pll_vco_clk dsi1pll_vco_clk = {
.max_rate = 3500000000UL,
.hw.init = &(struct clk_init_data){
.name = "dsi1pll_vco_clk",
- .parent_names = (const char *[]){"xo_board"},
+ .parent_names = (const char *[]){"bi_tcxo"},
.num_parents = 1,
.ops = &clk_ops_vco_10nm,
.flags = CLK_GET_RATE_NOCACHE,
diff --git a/drivers/clk/qcom/mdss/mdss-pll.h b/drivers/clk/qcom/mdss/mdss-pll.h
index eccfcea..ee91e11 100644
--- a/drivers/clk/qcom/mdss/mdss-pll.h
+++ b/drivers/clk/qcom/mdss/mdss-pll.h
@@ -94,6 +94,8 @@ struct mdss_pll_resources {
* suspend/resume scenario. Cached the vco rate for such plls.
*/
unsigned long vco_cached_rate;
+ u32 cached_cfg0;
+ u32 cached_cfg1;
/* dsi/edp/hmdi pll interface type */
u32 pll_interface_type;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
index 122a63d..48c2370 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -248,7 +248,7 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
reg_ctrl = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL);
reg_ctrl2 = DSI_R32(ctrl, DSI_COMMAND_COMPRESSION_MODE_CTRL2);
width_final = mode->dsc->pclk_per_line;
- stride_final = width_final * (h_stride / mode->h_active);
+ stride_final = mode->dsc->bytes_per_pkt;
reg = 0x39 << 8;
/*
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index cb4afe4..34aaea2 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -540,15 +540,42 @@ static int dsi_panel_led_bl_register(struct dsi_panel *panel,
}
#endif
+static int dsi_panel_update_backlight(struct dsi_panel *panel,
+ u32 bl_lvl)
+{
+ int rc = 0;
+ struct mipi_dsi_device *dsi;
+
+ if (!panel || (bl_lvl > 0xffff)) {
+ pr_err("invalid params\n");
+ return -EINVAL;
+ }
+
+ dsi = &panel->mipi_device;
+
+ mutex_lock(&panel->panel_lock);
+
+ rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl);
+ if (rc < 0)
+ pr_err("failed to update dcs backlight:%d\n", bl_lvl);
+
+ mutex_unlock(&panel->panel_lock);
+ return rc;
+}
+
int dsi_panel_set_backlight(struct dsi_panel *panel, u32 bl_lvl)
{
int rc = 0;
struct dsi_backlight_config *bl = &panel->bl_config;
+ pr_debug("backlight type:%d lvl:%d\n", bl->type, bl_lvl);
switch (bl->type) {
case DSI_BACKLIGHT_WLED:
led_trigger_event(bl->wled, bl_lvl);
break;
+ case DSI_BACKLIGHT_DCS:
+ dsi_panel_update_backlight(panel, bl_lvl);
+ break;
default:
pr_err("Backlight type(%d) not supported\n", bl->type);
rc = -ENOTSUPP;
@@ -566,6 +593,8 @@ static int dsi_panel_bl_register(struct dsi_panel *panel)
case DSI_BACKLIGHT_WLED:
rc = dsi_panel_led_bl_register(panel, bl);
break;
+ case DSI_BACKLIGHT_DCS:
+ break;
default:
pr_err("Backlight type(%d) not supported\n", bl->type);
rc = -ENOTSUPP;
@@ -585,6 +614,8 @@ static int dsi_panel_bl_unregister(struct dsi_panel *panel)
case DSI_BACKLIGHT_WLED:
led_trigger_unregister_simple(bl->wled);
break;
+ case DSI_BACKLIGHT_DCS:
+ break;
default:
pr_err("Backlight type(%d) not supported\n", bl->type);
rc = -ENOTSUPP;
diff --git a/drivers/gpu/drm/msm/sde/sde_fence.c b/drivers/gpu/drm/msm/sde/sde_fence.c
index 826fe14..c83472a 100644
--- a/drivers/gpu/drm/msm/sde/sde_fence.c
+++ b/drivers/gpu/drm/msm/sde/sde_fence.c
@@ -207,8 +207,9 @@ static int _sde_fence_create_fd(void *fence_ctx, uint32_t val)
if (!sde_fence)
return -ENOMEM;
- snprintf(sde_fence->name, SDE_FENCE_NAME_SIZE, "fence%u", val);
-
+ sde_fence->ctx = fence_ctx;
+ snprintf(sde_fence->name, SDE_FENCE_NAME_SIZE, "sde_fence:%s:%u",
+ sde_fence->ctx->name, val);
fence_init(&sde_fence->base, &sde_fence_ops, &ctx->lock,
ctx->context, val);
@@ -231,13 +232,13 @@ static int _sde_fence_create_fd(void *fence_ctx, uint32_t val)
}
fd_install(fd, sync_file->file);
+ sde_fence->fd = fd;
+ kref_get(&ctx->kref);
spin_lock(&ctx->list_lock);
- sde_fence->ctx = fence_ctx;
- sde_fence->fd = fd;
list_add_tail(&sde_fence->fence_list, &ctx->fence_list_head);
- kref_get(&ctx->kref);
spin_unlock(&ctx->list_lock);
+
exit:
return fd;
}
@@ -357,6 +358,8 @@ void sde_fence_signal(struct sde_fence_context *ctx, bool is_error)
}
spin_unlock_irqrestore(&ctx->lock, flags);
+ SDE_EVT32(ctx->drm_id, ctx->done_count);
+
spin_lock(&ctx->list_lock);
if (list_empty(&ctx->fence_list_head)) {
SDE_DEBUG("nothing to trigger!-no get_prop call\n");
@@ -370,7 +373,7 @@ void sde_fence_signal(struct sde_fence_context *ctx, bool is_error)
list_for_each_entry_safe(fc, next, &local_list_head, fence_list) {
spin_lock_irqsave(&ctx->lock, flags);
- is_signaled = fence_signal_locked(&fc->base);
+ is_signaled = fence_is_signaled_locked(&fc->base);
spin_unlock_irqrestore(&ctx->lock, flags);
if (is_signaled) {
@@ -381,6 +384,4 @@ void sde_fence_signal(struct sde_fence_context *ctx, bool is_error)
spin_unlock(&ctx->list_lock);
}
}
-
- SDE_EVT32(ctx->drm_id, ctx->done_count);
}
diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c
index 1f770c3..3413ee7 100644
--- a/drivers/gpu/drm/msm/sde_rsc.c
+++ b/drivers/gpu/drm/msm/sde_rsc.c
@@ -780,14 +780,15 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file,
const char __user *p, size_t count, loff_t *ppos)
{
struct sde_rsc_priv *rsc = file->private_data;
- char *input, *mode;
- u32 mode0_state = 0, mode1_state = 0, mode2_state = 0;
+ char *input;
+ u32 mode_state = 0;
int rc;
- if (!rsc || !rsc->hw_ops.mode_ctrl)
+ if (!rsc || !rsc->hw_ops.mode_ctrl || !count ||
+ count > MAX_COUNT_SIZE_SUPPORTED)
return 0;
- input = kmalloc(count, GFP_KERNEL);
+ input = kmalloc(count + 1, GFP_KERNEL);
if (!input)
return -ENOMEM;
@@ -795,43 +796,35 @@ static ssize_t _sde_debugfs_mode_ctrl_write(struct file *file,
kfree(input);
return -EFAULT;
}
- input[count - 1] = '\0';
+ input[count] = '\0';
+
+ rc = kstrtoint(input, 0, &mode_state);
+ if (rc) {
+ pr_err("mode_state: int conversion failed rc:%d\n", rc);
+ goto end;
+ }
+
+ pr_debug("mode_state: %d\n", mode_state);
+ mode_state &= 0x7;
+ if (mode_state != ALL_MODES_DISABLED &&
+ mode_state != ALL_MODES_ENABLED &&
+ mode_state != ONLY_MODE_0_ENABLED &&
+ mode_state != ONLY_MODE_0_1_ENABLED) {
+ pr_err("invalid mode:%d combination\n", mode_state);
+ goto end;
+ }
mutex_lock(&rsc->client_lock);
rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
if (rc)
goto clk_enable_fail;
- mode = strnstr(input, "mode0=", strlen("mode0="));
- if (mode) {
- mode0_state = mode[0] - '0';
- mode0_state &= BIT(0);
- rsc->hw_ops.mode_ctrl(rsc, MODE0_UPDATE, NULL, 0, mode0_state);
- goto end;
- }
-
- mode = strnstr(input, "mode1=", strlen("mode1="));
- if (mode) {
- mode1_state = mode[0] - '0';
- mode1_state &= BIT(0);
- rsc->hw_ops.mode_ctrl(rsc, MODE1_UPDATE, NULL, 0, mode1_state);
- goto end;
- }
-
- mode = strnstr(input, "mode2=", strlen("mode2="));
- if (mode) {
- mode2_state = mode[0] - '0';
- mode2_state &= BIT(0);
- rsc->hw_ops.mode_ctrl(rsc, MODE2_UPDATE, NULL, 0, mode2_state);
- }
-
-end:
+ rsc->hw_ops.mode_ctrl(rsc, MODE_UPDATE, NULL, 0, mode_state);
sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
+
clk_enable_fail:
mutex_unlock(&rsc->client_lock);
-
- pr_info("req: mode0:%d mode1:%d mode2:%d\n", mode0_state, mode1_state,
- mode2_state);
+end:
kfree(input);
return count;
}
@@ -879,14 +872,15 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file,
const char __user *p, size_t count, loff_t *ppos)
{
struct sde_rsc_priv *rsc = file->private_data;
- char *input, *vsync_mode;
+ char *input;
u32 vsync_state = 0;
int rc;
- if (!rsc || !rsc->hw_ops.hw_vsync)
+ if (!rsc || !rsc->hw_ops.hw_vsync || !count ||
+ count > MAX_COUNT_SIZE_SUPPORTED)
return 0;
- input = kmalloc(count, GFP_KERNEL);
+ input = kmalloc(count + 1, GFP_KERNEL);
if (!input)
return -ENOMEM;
@@ -894,18 +888,21 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file,
kfree(input);
return -EFAULT;
}
- input[count - 1] = '\0';
+ input[count] = '\0';
- vsync_mode = strnstr(input, "vsync_mode=", strlen("vsync_mode="));
- if (vsync_mode) {
- vsync_state = vsync_mode[0] - '0';
- vsync_state &= 0x7;
+ rc = kstrtoint(input, 0, &vsync_state);
+ if (rc) {
+ pr_err("vsync_state: int conversion failed rc:%d\n", rc);
+ goto end;
}
+ pr_debug("vsync_state: %d\n", vsync_state);
+ vsync_state &= 0x7;
+
mutex_lock(&rsc->client_lock);
rc = sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, true);
if (rc)
- goto end;
+ goto clk_en_fail;
if (vsync_state)
rsc->hw_ops.hw_vsync(rsc, VSYNC_ENABLE, NULL,
@@ -915,8 +912,9 @@ static ssize_t _sde_debugfs_vsync_mode_write(struct file *file,
sde_rsc_clk_enable(&rsc->phandle, rsc->pclient, false);
-end:
+clk_en_fail:
mutex_unlock(&rsc->client_lock);
+end:
kfree(input);
return count;
}
diff --git a/drivers/gpu/drm/msm/sde_rsc_hw.c b/drivers/gpu/drm/msm/sde_rsc_hw.c
index c87dac4..3332a05 100644
--- a/drivers/gpu/drm/msm/sde_rsc_hw.c
+++ b/drivers/gpu/drm/msm/sde_rsc_hw.c
@@ -572,7 +572,7 @@ int rsc_hw_init(struct sde_rsc_priv *rsc)
}
int rsc_hw_mode_ctrl(struct sde_rsc_priv *rsc, enum rsc_mode_req request,
- char *buffer, int buffer_size, bool mode)
+ char *buffer, int buffer_size, u32 mode)
{
u32 blen = 0;
u32 slot_time;
@@ -588,28 +588,19 @@ int rsc_hw_mode_ctrl(struct sde_rsc_priv *rsc, enum rsc_mode_req request,
rsc->debug_mode));
break;
- case MODE0_UPDATE:
- slot_time = mode ? rsc->timer_config.rsc_time_slot_0_ns :
+ case MODE_UPDATE:
+ slot_time = mode & BIT(0) ? 0x0 :
+ rsc->timer_config.rsc_time_slot_2_ns;
+ dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_0_DRV0,
+ slot_time, rsc->debug_mode);
+
+ slot_time = mode & BIT(1) ?
+ rsc->timer_config.rsc_time_slot_0_ns :
rsc->timer_config.rsc_time_slot_2_ns;
dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_1_DRV0,
slot_time, rsc->debug_mode);
- slot_time = mode ? rsc->timer_config.rsc_time_slot_1_ns :
- rsc->timer_config.rsc_time_slot_2_ns;
- dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_2_DRV0,
- slot_time, rsc->debug_mode);
- rsc->power_collapse_block = mode;
- break;
- case MODE1_UPDATE:
- slot_time = mode ? rsc->timer_config.rsc_time_slot_1_ns :
- rsc->timer_config.rsc_time_slot_2_ns;
- dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_TIME_SLOT_TABLE_2_DRV0,
- slot_time, rsc->debug_mode);
- rsc->power_collapse_block = mode;
- break;
-
- case MODE2_UPDATE:
- rsc->power_collapse_block = mode;
+ rsc->power_collapse_block = !(mode & BIT(2));
break;
default:
@@ -673,7 +664,7 @@ int rsc_hw_vsync(struct sde_rsc_priv *rsc, enum rsc_vsync_req request,
return blen;
blen = snprintf(buffer, buffer_size - blen, "vsync0:0x%x\n",
- dss_reg_r(&rsc->drv_io,
+ dss_reg_r(&rsc->wrapper_io,
SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP0,
rsc->debug_mode));
if (blen >= buffer_size)
@@ -681,15 +672,15 @@ int rsc_hw_vsync(struct sde_rsc_priv *rsc, enum rsc_vsync_req request,
blen += snprintf(buffer + blen, buffer_size - blen,
"vsync1:0x%x\n",
- dss_reg_r(&rsc->drv_io,
+ dss_reg_r(&rsc->wrapper_io,
SDE_RSCC_WRAPPER_VSYNC_TIMESTAMP1,
rsc->debug_mode));
break;
case VSYNC_ENABLE:
- reg = BIT(8) | BIT(9) | ((mode & 0x7) < 10);
+ reg = BIT(8) | ((mode & 0x7) < 10);
dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_DEBUG_BUS,
- mode, rsc->debug_mode);
+ reg, rsc->debug_mode);
break;
case VSYNC_DISABLE:
diff --git a/drivers/gpu/drm/msm/sde_rsc_priv.h b/drivers/gpu/drm/msm/sde_rsc_priv.h
index b83a866..b90b0ac 100644
--- a/drivers/gpu/drm/msm/sde_rsc_priv.h
+++ b/drivers/gpu/drm/msm/sde_rsc_priv.h
@@ -25,20 +25,27 @@
#define MAX_RSC_COUNT 5
+#define ALL_MODES_DISABLED 0x0
+#define ONLY_MODE_0_ENABLED 0x1
+#define ONLY_MODE_0_1_ENABLED 0x3
+#define ALL_MODES_ENABLED 0x7
+
+#define MAX_COUNT_SIZE_SUPPORTED 128
+
struct sde_rsc_priv;
/**
* rsc_mode_req: sde rsc mode request information
* MODE_READ: read vsync status
- * MODE0_UPDATE: mode0 status , this should be 0x0
- * MODE1_UPDATE: mode1 status , this should be 0x1
- * MODE2_UPDATE: mode2 status , this should be 0x2
+ * MODE_UPDATE: mode timeslot update
+ * 0x0: all modes are disabled.
+ * 0x1: Mode-0 is enabled and other two modes are disabled.
+ * 0x3: Mode-0 & Mode-1 are enabled and mode-2 is disabled.
+ * 0x7: all modes are enabled.
*/
enum rsc_mode_req {
MODE_READ,
- MODE0_UPDATE = 0x1,
- MODE1_UPDATE = 0x2,
- MODE2_UPDATE = 0x3,
+ MODE_UPDATE = 0x1,
};
/**
@@ -78,7 +85,7 @@ struct sde_rsc_hw_ops {
int (*state_update)(struct sde_rsc_priv *rsc, enum sde_rsc_state state);
int (*debug_show)(struct seq_file *s, struct sde_rsc_priv *rsc);
int (*mode_ctrl)(struct sde_rsc_priv *rsc, enum rsc_mode_req request,
- char *buffer, int buffer_size, bool mode);
+ char *buffer, int buffer_size, u32 mode);
};
/**
diff --git a/drivers/gpu/msm/kgsl_sync.c b/drivers/gpu/msm/kgsl_sync.c
index 973a2ff..96873c4 100644
--- a/drivers/gpu/msm/kgsl_sync.c
+++ b/drivers/gpu/msm/kgsl_sync.c
@@ -803,11 +803,23 @@ static const char *kgsl_syncsource_driver_name(struct fence *fence)
return "kgsl-syncsource-timeline";
}
+static void kgsl_syncsource_fence_value_str(struct fence *fence,
+ char *str, int size)
+{
+ /*
+ * Each fence is independent of the others on the same timeline.
+ * We use a different context for each of them.
+ */
+ snprintf(str, size, "%llu", fence->context);
+}
+
static const struct fence_ops kgsl_syncsource_fence_ops = {
.get_driver_name = kgsl_syncsource_driver_name,
.get_timeline_name = kgsl_syncsource_get_timeline_name,
.enable_signaling = kgsl_syncsource_enable_signaling,
.wait = fence_default_wait,
.release = kgsl_syncsource_fence_release,
+
+ .fence_value_str = kgsl_syncsource_fence_value_str,
};
diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c
index aded314..8ba6da4 100644
--- a/drivers/iommu/dma-mapping-fast.c
+++ b/drivers/iommu/dma-mapping-fast.c
@@ -730,6 +730,7 @@ int fast_smmu_attach_device(struct device *dev,
{
int atomic_domain = 1;
struct iommu_domain *domain = mapping->domain;
+ struct iommu_group *group;
struct iommu_pgtbl_info info;
u64 size = (u64)mapping->bits << PAGE_SHIFT;
@@ -746,7 +747,18 @@ int fast_smmu_attach_device(struct device *dev,
mapping->fast->domain = domain;
mapping->fast->dev = dev;
- if (iommu_attach_device(domain, dev))
+ group = dev->iommu_group;
+ if (!group) {
+ dev_err(dev, "No iommu associated with device\n");
+ return -ENODEV;
+ }
+
+ if (iommu_get_domain_for_dev(dev)) {
+ dev_err(dev, "Device already attached to other iommu_domain\n");
+ return -EINVAL;
+ }
+
+ if (iommu_attach_group(mapping->domain, group))
return -EINVAL;
if (iommu_domain_get_attr(domain, DOMAIN_ATTR_PGTBL_INFO,
@@ -781,7 +793,7 @@ EXPORT_SYMBOL(fast_smmu_attach_device);
void fast_smmu_detach_device(struct device *dev,
struct dma_iommu_mapping *mapping)
{
- iommu_detach_device(mapping->domain, dev);
+ iommu_detach_group(mapping->domain, dev->iommu_group);
dev->archdata.mapping = NULL;
set_dma_ops(dev, NULL);
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 181e889..bea5f03 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -548,7 +548,7 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
}
}
- if (iommu_attach_device(domain, dev)) {
+ if (iommu_attach_group(domain, dev->iommu_group)) {
seq_puts(s,
"Couldn't attach new domain to device. Is it already attached?\n");
goto out_domain_free;
@@ -669,7 +669,7 @@ static void iommu_debug_device_profiling(struct seq_file *s, struct device *dev,
}
out_detach:
- iommu_detach_device(domain, dev);
+ iommu_detach_group(domain, dev->iommu_group);
out_domain_free:
iommu_domain_free(domain);
}
@@ -1451,6 +1451,8 @@ static const struct file_operations iommu_debug_functional_arm_dma_api_fops = {
static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
int val, bool is_secure)
{
+ struct iommu_group *group = ddev->dev->iommu_group;
+
ddev->domain = iommu_domain_alloc(&platform_bus_type);
if (!ddev->domain) {
pr_err("Couldn't allocate domain\n");
@@ -1464,8 +1466,8 @@ static int iommu_debug_attach_do_attach(struct iommu_debug_device *ddev,
goto out_domain_free;
}
- if (iommu_attach_device(ddev->domain, ddev->dev)) {
- pr_err("Couldn't attach new domain to device. Is it already attached?\n");
+ if (iommu_attach_group(ddev->domain, group)) {
+ dev_err(ddev->dev, "Couldn't attach new domain to device\n");
goto out_domain_free;
}
@@ -1483,6 +1485,8 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
bool is_secure)
{
struct iommu_debug_device *ddev = file->private_data;
+ struct device *dev = ddev->dev;
+ struct iommu_domain *domain;
ssize_t retval;
int val;
@@ -1494,12 +1498,15 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
if (val) {
if (ddev->domain) {
- pr_err("Already attached.\n");
+ pr_err("Iommu-Debug is already attached?\n");
retval = -EINVAL;
goto out;
}
- if (WARN(ddev->dev->archdata.iommu,
- "Attachment tracking out of sync with device\n")) {
+
+ domain = iommu_get_domain_for_dev(dev);
+ if (domain) {
+ pr_err("Another driver is using this device's iommu\n"
+ "Iommu-Debug cannot be used concurrently\n");
retval = -EINVAL;
goto out;
}
@@ -1510,11 +1517,11 @@ static ssize_t __iommu_debug_attach_write(struct file *file,
pr_err("Attached\n");
} else {
if (!ddev->domain) {
- pr_err("No domain. Did you already attach?\n");
+ pr_err("Iommu-Debug is not attached?\n");
retval = -EINVAL;
goto out;
}
- iommu_detach_device(ddev->domain, ddev->dev);
+ iommu_detach_group(ddev->domain, dev->iommu_group);
iommu_domain_free(ddev->domain);
ddev->domain = NULL;
pr_err("Detached\n");
@@ -1566,7 +1573,6 @@ static ssize_t iommu_debug_attach_write_secure(struct file *file,
{
return __iommu_debug_attach_write(file, ubuf, count, offset,
true);
-
}
static const struct file_operations iommu_debug_secure_attach_fops = {
@@ -1868,6 +1874,10 @@ static int snarf_iommu_devices(struct device *dev, void *ignored)
if (!of_find_property(dev->of_node, "iommus", NULL))
return 0;
+ /* Hold a reference count */
+ if (!iommu_group_get(dev))
+ return 0;
+
ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
if (!ddev)
return -ENODEV;
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index c9281fb..daccf64 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -458,9 +458,6 @@ static int gic_populate_rdist(void)
u64 offset = ptr - gic_data.redist_regions[i].redist_base;
gic_data_rdist_rd_base() = ptr;
gic_data_rdist()->phys_base = gic_data.redist_regions[i].phys_base + offset;
- pr_info("CPU%d: found redistributor %lx region %d:%pa\n",
- smp_processor_id(), mpidr, i,
- &gic_data_rdist()->phys_base);
return 0;
}
diff --git a/drivers/mailbox/qti-tcs.c b/drivers/mailbox/qti-tcs.c
index 6d0e913..aeee8d3 100644
--- a/drivers/mailbox/qti-tcs.c
+++ b/drivers/mailbox/qti-tcs.c
@@ -134,6 +134,9 @@ struct tcs_drv {
struct workqueue_struct *wq;
struct tcs_response_pool *resp_pool;
atomic_t tcs_in_use[MAX_POOL_SIZE];
+ /* Debug info */
+ u64 tcs_last_sent_ts[MAX_POOL_SIZE];
+ u64 tcs_last_recv_ts[MAX_POOL_SIZE];
atomic_t tcs_send_count[MAX_POOL_SIZE];
atomic_t tcs_irq_count[MAX_POOL_SIZE];
};
@@ -170,8 +173,9 @@ static struct tcs_response *setup_response(struct tcs_drv *drv,
struct tcs_response_pool *pool = drv->resp_pool;
struct tcs_response *resp = ERR_PTR(-ENOMEM);
int pos;
+ unsigned long flags;
- spin_lock(&pool->lock);
+ spin_lock_irqsave(&pool->lock, flags);
pos = find_first_zero_bit(pool->avail, MAX_POOL_SIZE);
if (pos != MAX_POOL_SIZE) {
bitmap_set(pool->avail, pos, 1);
@@ -182,7 +186,7 @@ static struct tcs_response *setup_response(struct tcs_drv *drv,
resp->err = err;
resp->in_use = false;
}
- spin_unlock(&pool->lock);
+ spin_unlock_irqrestore(&pool->lock, flags);
return resp;
}
@@ -190,34 +194,62 @@ static struct tcs_response *setup_response(struct tcs_drv *drv,
static void free_response(struct tcs_response *resp)
{
struct tcs_response_pool *pool = resp->drv->resp_pool;
+ unsigned long flags;
- spin_lock(&pool->lock);
+ spin_lock_irqsave(&pool->lock, flags);
resp->err = -EINVAL;
bitmap_clear(pool->avail, resp->idx, 1);
- spin_unlock(&pool->lock);
+ spin_unlock_irqrestore(&pool->lock, flags);
}
-static inline struct tcs_response *get_response(struct tcs_drv *drv, u32 m)
+static inline struct tcs_response *get_response(struct tcs_drv *drv, u32 m,
+ bool for_use)
{
struct tcs_response_pool *pool = drv->resp_pool;
struct tcs_response *resp = NULL;
int pos = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&pool->lock, flags);
do {
pos = find_next_bit(pool->avail, MAX_POOL_SIZE, pos);
if (pos == MAX_POOL_SIZE)
break;
+
resp = &pool->resp[pos];
if (resp->m == m && !resp->in_use) {
- resp->in_use = true;
+ resp->in_use = for_use;
break;
}
pos++;
+ udelay(1);
} while (1);
+ spin_unlock_irqrestore(&pool->lock, flags);
return resp;
}
+static void print_response(struct tcs_drv *drv, int m)
+{
+ struct tcs_response *resp;
+ struct tcs_mbox_msg *msg;
+ int i;
+
+ resp = get_response(drv, m, false);
+ if (!resp)
+ return;
+
+ msg = resp->msg;
+ pr_info("Response object idx=%d:\n\tfor-tcs=%d\tin-use=%d\n",
+ resp->idx, resp->m, resp->in_use);
+ pr_info("Msg: state=%d\n", msg->state);
+ for (i = 0; i < msg->num_payload; i++)
+ pr_info("addr=0x%x data=0x%x complete=0x%x\n",
+ msg->payload[i].addr,
+ msg->payload[i].data,
+ msg->payload[i].complete);
+}
+
static inline u32 read_drv_config(void __iomem *base)
{
return le32_to_cpu(readl_relaxed(base + DRV_PRNT_CHLD_CONFIG));
@@ -257,17 +289,19 @@ static inline bool tcs_is_free(struct tcs_drv *drv, int m)
static inline struct tcs_mbox *get_tcs_from_index(struct tcs_drv *drv, int m)
{
- struct tcs_mbox *tcs;
+ struct tcs_mbox *tcs = NULL;
int i;
- for (i = 0; i < TCS_TYPE_NR; i++) {
+ for (i = 0; i < drv->num_tcs; i++) {
tcs = &drv->tcs[i];
- if (tcs->tcs_mask & BIT(m))
+ if (tcs->tcs_mask & (u32)BIT(m))
break;
}
- if (i == TCS_TYPE_NR)
+ if (i == drv->num_tcs) {
+ WARN(1, "Incorrect TCS index %d", m);
tcs = NULL;
+ }
return tcs;
}
@@ -369,16 +403,10 @@ static irqreturn_t tcs_irq_handler(int irq, void *p)
continue;
atomic_inc(&drv->tcs_irq_count[m]);
- resp = get_response(drv, m);
+ resp = get_response(drv, m, true);
if (!resp) {
pr_err("No resp request for TCS-%d\n", m);
- continue;
- }
-
- tcs = get_tcs_from_index(drv, m);
- if (!tcs) {
- pr_err("TCS-%d doesn't exist in DRV\n", m);
- continue;
+ goto no_resp;
}
/* Check if all commands were completed */
@@ -404,7 +432,8 @@ static irqreturn_t tcs_irq_handler(int irq, void *p)
resp->err);
/* Clear the AMC mode for non-ACTIVE TCSes */
- if (tcs->type != ACTIVE_TCS) {
+ tcs = get_tcs_from_index(drv, m);
+ if (tcs && tcs->type != ACTIVE_TCS) {
data = read_tcs_reg(base, TCS_DRV_CONTROL, m, 0);
data &= ~TCS_AMC_MODE_ENABLE;
write_tcs_reg(base, TCS_DRV_CONTROL, m, 0, data);
@@ -419,11 +448,16 @@ static irqreturn_t tcs_irq_handler(int irq, void *p)
write_tcs_reg(base, TCS_DRV_CMD_ENABLE, m, 0, 0);
}
+no_resp:
+ /* Record the recvd time stamp */
+ drv->tcs_last_recv_ts[m] = arch_counter_get_cntvct();
+
/* Clear the TCS IRQ status */
write_tcs_reg(base, TCS_DRV_IRQ_CLEAR, 0, 0, BIT(m));
/* Clean up response object and notify mbox in tasklet */
- send_tcs_response(resp);
+ if (resp)
+ send_tcs_response(resp);
/* Notify the client that this request is completed. */
atomic_set(&drv->tcs_in_use[m], 0);
@@ -628,7 +662,6 @@ static int find_slots(struct tcs_mbox *tcs, struct tcs_mbox_msg *msg)
static int tcs_mbox_write(struct mbox_chan *chan, struct tcs_mbox_msg *msg,
bool trigger)
{
- const struct device *dev = chan->cl->dev;
struct tcs_drv *drv = container_of(chan->mbox, struct tcs_drv, mbox);
int d = drv->drv_id;
struct tcs_mbox *tcs;
@@ -647,7 +680,6 @@ static int tcs_mbox_write(struct mbox_chan *chan, struct tcs_mbox_msg *msg,
spin_lock_irqsave(&tcs->tcs_lock, flags);
slot = find_slots(tcs, msg);
if (slot < 0) {
- dev_err(dev, "No TCS slot found.\n");
spin_unlock_irqrestore(&tcs->tcs_lock, flags);
if (resp)
free_response(resp);
@@ -683,6 +715,7 @@ static int tcs_mbox_write(struct mbox_chan *chan, struct tcs_mbox_msg *msg,
/* Enable interrupt for active votes through wake TCS */
if (tcs->type != ACTIVE_TCS)
enable_tcs_irq(drv, m, true);
+ drv->tcs_last_sent_ts[m] = arch_counter_get_cntvct();
}
/* Write to the TCS or AMC */
@@ -725,6 +758,24 @@ static int tcs_mbox_invalidate(struct mbox_chan *chan)
return 0;
}
+static void dump_tcs_stats(struct tcs_drv *drv)
+{
+ int i;
+ unsigned long long curr = arch_counter_get_cntvct();
+
+ for (i = 0; i < drv->num_tcs; i++) {
+ if (!atomic_read(&drv->tcs_in_use[i]))
+ continue;
+ pr_info("Time: %llu: TCS-%d:\n\tReq Sent:%d Last Sent:%llu\n\tResp Recv:%d Last Recvd:%llu\n",
+ curr, i,
+ atomic_read(&drv->tcs_send_count[i]),
+ drv->tcs_last_sent_ts[i],
+ atomic_read(&drv->tcs_irq_count[i]),
+ drv->tcs_last_recv_ts[i]);
+ print_response(drv, i);
+ }
+}
+
/**
* chan_tcs_write: Validate the incoming message and write to the
* appropriate TCS block.
@@ -738,35 +789,41 @@ static int tcs_mbox_invalidate(struct mbox_chan *chan)
*/
static int chan_tcs_write(struct mbox_chan *chan, void *data)
{
+ struct tcs_drv *drv = container_of(chan->mbox, struct tcs_drv, mbox);
struct tcs_mbox_msg *msg = data;
const struct device *dev = chan->cl->dev;
- int ret = -EINVAL;
+ int ret = 0;
int count = 0;
if (!msg) {
dev_err(dev, "Payload error.\n");
+ ret = -EINVAL;
goto tx_fail;
}
if (!msg->payload || msg->num_payload > MAX_RPMH_PAYLOAD) {
dev_err(dev, "Payload error.\n");
+ ret = -EINVAL;
goto tx_fail;
}
if (msg->invalidate || msg->is_control) {
dev_err(dev, "Incorrect API.\n");
+ ret = -EINVAL;
goto tx_fail;
}
if (msg->state != RPMH_ACTIVE_ONLY_STATE &&
msg->state != RPMH_AWAKE_STATE) {
dev_err(dev, "Incorrect API.\n");
+ ret = -EINVAL;
goto tx_fail;
}
/* Read requests should always be single */
if (msg->is_read && msg->num_payload > 1) {
dev_err(dev, "Incorrect read request.\n");
+ ret = -EINVAL;
goto tx_fail;
}
@@ -780,25 +837,29 @@ static int chan_tcs_write(struct mbox_chan *chan, void *data)
/* Post the message to the TCS and trigger */
do {
ret = tcs_mbox_write(chan, msg, true);
- if (ret == -EBUSY) {
- ret = -EIO;
- udelay(10);
- } else
+ if (ret != -EBUSY)
break;
+ udelay(100);
} while (++count < 10);
tx_fail:
- if (ret) {
- struct tcs_drv *drv = container_of(chan->mbox,
- struct tcs_drv, mbox);
+ /* If there was an error in the request, schedule a response */
+ if (ret < 0 && ret != -EBUSY) {
struct tcs_response *resp = setup_response(
drv, msg, chan, TCS_M_INIT, ret);
dev_err(dev, "Error sending RPMH message %d\n", ret);
send_tcs_response(resp);
+ ret = 0;
}
- return 0;
+ /* If we were just busy waiting for TCS, dump the state and return */
+ if (ret == -EBUSY) {
+ dev_err(dev, "TCS Busy, retrying RPMH message send\n");
+ dump_tcs_stats(drv);
+ }
+
+ return ret;
}
static void __tcs_write_hidden(struct tcs_drv *drv, int d,
diff --git a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
index f3ef0e9..9c030ab 100644
--- a/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
+++ b/drivers/media/platform/msm/camera/cam_req_mgr/cam_mem_mgr.c
@@ -97,7 +97,7 @@ int cam_mem_mgr_init(void)
}
bitmap_size = BITS_TO_LONGS(CAM_MEM_BUFQ_MAX) * sizeof(long);
- tbl.bitmap = kzalloc(sizeof(bitmap_size), GFP_KERNEL);
+ tbl.bitmap = kzalloc(bitmap_size, GFP_KERNEL);
if (!tbl.bitmap) {
rc = -ENOMEM;
goto bitmap_fail;
diff --git a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
index f4215b5..236e7f1 100644
--- a/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera/cam_smmu/cam_smmu_api.c
@@ -1227,7 +1227,6 @@ static enum cam_smmu_buf_state cam_smmu_check_fd_in_list(int idx,
list_for_each_entry(mapping,
&iommu_cb_set.cb_info[idx].smmu_buf_list, list) {
if (mapping->ion_fd == ion_fd) {
- mapping->ref_count++;
*paddr_ptr = mapping->paddr;
*len_ptr = mapping->len;
return CAM_SMMU_BUFF_EXIST;
@@ -1670,7 +1669,7 @@ int cam_smmu_map_iova(int handle, int ion_fd,
if (buf_state == CAM_SMMU_BUFF_EXIST) {
CDBG("ion_fd:%d already in the list, give same addr back",
ion_fd);
- rc = 0;
+ rc = -EALREADY;
goto get_addr_end;
}
rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, dma_dir,
@@ -1777,14 +1776,6 @@ int cam_smmu_unmap_iova(int handle,
goto unmap_end;
}
- mapping_info->ref_count--;
- if (mapping_info->ref_count > 0) {
- CDBG("There are still %u buffer(s) with same fd %d",
- mapping_info->ref_count, mapping_info->ion_fd);
- rc = 0;
- goto unmap_end;
- }
-
/* Unmapping one buffer from device */
CDBG("SMMU: removing buffer idx = %d\n", idx);
rc = cam_smmu_unmap_buf_and_remove_from_list(mapping_info, idx);
@@ -1833,8 +1824,6 @@ int cam_smmu_put_iova(int handle, int ion_fd)
goto put_addr_end;
}
- mapping_info->ref_count--;
-
put_addr_end:
mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
return rc;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index 1a65d07..d80e7f4 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -90,7 +90,7 @@ static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
done = budget - quota;
if (done < budget) {
- napi_complete(napi);
+ napi_complete_done(napi, done);
wil6210_unmask_irq_rx(wil);
wil_dbg_txrx(wil, "NAPI RX complete\n");
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index 796103f..0b8115f 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -239,6 +239,8 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
struct gsi_xfer_elem xfer_elem;
int i;
int aggr_active_bitmap = 0;
+ bool pipe_suspended = false;
+ struct ipa_ep_cfg_ctrl ctrl;
IPADBG("Applying reset channel with open aggregation frame WA\n");
ipahal_write_reg(IPA_AGGR_FORCE_CLOSE, (1 << clnt_hdl));
@@ -265,6 +267,15 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
if (result)
return -EFAULT;
+ ipahal_read_reg_n_fields(IPA_ENDP_INIT_CTRL_n, clnt_hdl, &ctrl);
+ if (ctrl.ipa_ep_suspend) {
+ IPADBG("pipe is suspended, remove suspend\n");
+ pipe_suspended = true;
+ ctrl.ipa_ep_suspend = false;
+ ipahal_write_reg_n_fields(IPA_ENDP_INIT_CTRL_n,
+ clnt_hdl, &ctrl);
+ }
+
/* Start channel and put 1 Byte descriptor on it */
gsi_res = gsi_start_channel(ep->gsi_chan_hdl);
if (gsi_res != GSI_STATUS_SUCCESS) {
@@ -324,6 +335,13 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
*/
msleep(IPA_POLL_AGGR_STATE_SLEEP_MSEC);
+ if (pipe_suspended) {
+ IPADBG("suspend the pipe again\n");
+ ctrl.ipa_ep_suspend = true;
+ ipahal_write_reg_n_fields(IPA_ENDP_INIT_CTRL_n,
+ clnt_hdl, &ctrl);
+ }
+
/* Restore channels properties */
result = ipa3_restore_channel_properties(ep, &orig_chan_props,
&orig_chan_scratch);
@@ -338,6 +356,12 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
ipa3_stop_gsi_channel(clnt_hdl);
dma_free_coherent(ipa3_ctx->pdev, 1, buff, dma_addr);
start_chan_fail:
+ if (pipe_suspended) {
+ IPADBG("suspend the pipe again\n");
+ ctrl.ipa_ep_suspend = true;
+ ipahal_write_reg_n_fields(IPA_ENDP_INIT_CTRL_n,
+ clnt_hdl, &ctrl);
+ }
ipa3_restore_channel_properties(ep, &orig_chan_props,
&orig_chan_scratch);
restore_props_fail:
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 89dd274..faa47d8 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -1055,7 +1055,7 @@ int ipa3_teardown_sys_pipe(u32 clnt_hdl)
ipa_assert();
return result;
}
- result = gsi_reset_channel(ep->gsi_chan_hdl);
+ result = ipa3_reset_gsi_channel(clnt_hdl);
if (result != GSI_STATUS_SUCCESS) {
IPAERR("Failed to reset chan: %d.\n", result);
ipa_assert();
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
index 78fd90b..d369e82 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipahal/ipahal_reg.c
@@ -649,6 +649,21 @@ static void ipareg_construct_endp_init_ctrl_n(enum ipahal_reg_name reg,
IPA_ENDP_INIT_CTRL_n_ENDP_DELAY_BMSK);
}
+static void ipareg_parse_endp_init_ctrl_n(enum ipahal_reg_name reg,
+ void *fields, u32 val)
+{
+ struct ipa_ep_cfg_ctrl *ep_ctrl =
+ (struct ipa_ep_cfg_ctrl *)fields;
+
+ ep_ctrl->ipa_ep_suspend =
+ ((val & IPA_ENDP_INIT_CTRL_n_ENDP_SUSPEND_BMSK) >>
+ IPA_ENDP_INIT_CTRL_n_ENDP_SUSPEND_SHFT);
+
+ ep_ctrl->ipa_ep_delay =
+ ((val & IPA_ENDP_INIT_CTRL_n_ENDP_DELAY_BMSK) >>
+ IPA_ENDP_INIT_CTRL_n_ENDP_DELAY_SHFT);
+}
+
static void ipareg_construct_endp_init_ctrl_scnd_n(enum ipahal_reg_name reg,
const void *fields, u32 *val)
{
@@ -1059,7 +1074,8 @@ static struct ipahal_reg_obj ipahal_reg_objs[IPA_HW_MAX][IPA_REG_MAX] = {
ipareg_construct_endp_init_nat_n, ipareg_parse_dummy,
0x0000080C, 0x70},
[IPA_HW_v3_0][IPA_ENDP_INIT_CTRL_n] = {
- ipareg_construct_endp_init_ctrl_n, ipareg_parse_dummy,
+ ipareg_construct_endp_init_ctrl_n,
+ ipareg_parse_endp_init_ctrl_n,
0x00000800, 0x70},
[IPA_HW_v3_0][IPA_ENDP_INIT_CTRL_SCND_n] = {
ipareg_construct_endp_init_ctrl_scnd_n, ipareg_parse_dummy,
diff --git a/drivers/platform/msm/msm_11ad/msm_11ad.c b/drivers/platform/msm/msm_11ad/msm_11ad.c
index 5595b7b..4e9bd64 100644
--- a/drivers/platform/msm/msm_11ad/msm_11ad.c
+++ b/drivers/platform/msm/msm_11ad/msm_11ad.c
@@ -764,6 +764,25 @@ static int msm_11ad_ssr_powerup(const struct subsys_desc *subsys)
return rc;
}
+static int msm_11ad_ssr_copy_ramdump(struct msm11ad_ctx *ctx)
+{
+ if (ctx->rops.ramdump && ctx->wil_handle) {
+ int rc = ctx->rops.ramdump(ctx->wil_handle, ctx->ramdump_addr,
+ WIGIG_RAMDUMP_SIZE);
+ if (rc) {
+ dev_err(ctx->dev, "ramdump failed : %d\n", rc);
+ return -EINVAL;
+ }
+ }
+
+ ctx->dump_data.version = WIGIG_DUMP_FORMAT_VER;
+ strlcpy(ctx->dump_data.name, WIGIG_SUBSYS_NAME,
+ sizeof(ctx->dump_data.name));
+
+ ctx->dump_data.magic = WIGIG_DUMP_MAGIC_VER_V1;
+ return 0;
+}
+
static int msm_11ad_ssr_ramdump(int enable, const struct subsys_desc *subsys)
{
int rc;
@@ -780,13 +799,10 @@ static int msm_11ad_ssr_ramdump(int enable, const struct subsys_desc *subsys)
if (!enable)
return 0;
- if (ctx->rops.ramdump && ctx->wil_handle) {
- rc = ctx->rops.ramdump(ctx->wil_handle, ctx->ramdump_addr,
- WIGIG_RAMDUMP_SIZE);
- if (rc) {
- dev_err(ctx->dev, "ramdump failed : %d\n", rc);
- return -EINVAL;
- }
+ if (!ctx->recovery_in_progress) {
+ rc = msm_11ad_ssr_copy_ramdump(ctx);
+ if (rc)
+ return rc;
}
memset(&segment, 0, sizeof(segment));
@@ -798,7 +814,6 @@ static int msm_11ad_ssr_ramdump(int enable, const struct subsys_desc *subsys)
static void msm_11ad_ssr_crash_shutdown(const struct subsys_desc *subsys)
{
- int rc;
struct platform_device *pdev;
struct msm11ad_ctx *ctx;
@@ -810,19 +825,8 @@ static void msm_11ad_ssr_crash_shutdown(const struct subsys_desc *subsys)
return;
}
- if (ctx->rops.ramdump && ctx->wil_handle) {
- rc = ctx->rops.ramdump(ctx->wil_handle, ctx->ramdump_addr,
- WIGIG_RAMDUMP_SIZE);
- if (rc)
- dev_err(ctx->dev, "ramdump failed : %d\n", rc);
- /* continue */
- }
-
- ctx->dump_data.version = WIGIG_DUMP_FORMAT_VER;
- strlcpy(ctx->dump_data.name, WIGIG_SUBSYS_NAME,
- sizeof(ctx->dump_data.name));
-
- ctx->dump_data.magic = WIGIG_DUMP_MAGIC_VER_V1;
+ if (!ctx->recovery_in_progress)
+ (void)msm_11ad_ssr_copy_ramdump(ctx);
}
static void msm_11ad_ssr_deinit(struct msm11ad_ctx *ctx)
@@ -901,7 +905,7 @@ static int msm_11ad_ssr_init(struct msm11ad_ctx *ctx)
static void msm_11ad_init_cpu_boost(struct msm11ad_ctx *ctx)
{
unsigned int minfreq = 0, maxfreq = 0, freq;
- int i, boost_cpu;
+ int i, boost_cpu = 0;
for_each_possible_cpu(i) {
freq = cpufreq_quick_get_max(i);
@@ -1321,6 +1325,7 @@ static int msm_11ad_notify_crash(struct msm11ad_ctx *ctx)
if (ctx->subsys) {
dev_info(ctx->dev, "SSR requested\n");
+ (void)msm_11ad_ssr_copy_ramdump(ctx);
ctx->recovery_in_progress = true;
rc = subsystem_restart_dev(ctx->subsys);
if (rc) {
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 806460f..27047b4 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -3366,6 +3366,16 @@ static int fg_hw_init(struct fg_chip *chip)
return rc;
}
+ if (is_debug_batt_id(chip)) {
+ val = ESR_NO_PULL_DOWN;
+ rc = fg_masked_write(chip, BATT_INFO_ESR_PULL_DN_CFG(chip),
+ ESR_PULL_DOWN_MODE_MASK, val);
+ if (rc < 0) {
+ pr_err("Error in writing esr_pull_down, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
return 0;
}
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c
index b9070bd..81d0bb0 100644
--- a/drivers/soc/qcom/rpmh.c
+++ b/drivers/soc/qcom/rpmh.c
@@ -504,8 +504,12 @@ int rpmh_write_passthru(struct rpmh_client *rc, enum rpmh_state state,
/* Create async request batches */
for (i = 0; i < count; i++) {
rpm_msg[i] = __get_rpmh_msg_async(rc, state, cmd, n[i]);
- if (IS_ERR_OR_NULL(rpm_msg[i]))
+ if (IS_ERR_OR_NULL(rpm_msg[i])) {
+ /* Clean up our call by spoofing tx_done */
+ for (j = 0 ; j < i; j++)
+ rpmh_tx_done(&rc->client, &rpm_msg[j]->msg, 0);
return PTR_ERR(rpm_msg[i]);
+ }
cmd += n[i];
}
@@ -518,10 +522,13 @@ int rpmh_write_passthru(struct rpmh_client *rc, enum rpmh_state state,
rpm_msg[i]->wait_count = &wait_count;
/* Bypass caching and write to mailbox directly */
ret = mbox_send_message(rc->chan, &rpm_msg[i]->msg);
- if (ret < 0)
- return ret;
+ if (ret < 0) {
+ pr_err("Error(%d) sending RPM message addr=0x%x\n",
+ ret, rpm_msg[i]->msg.payload[0].addr);
+ break;
+ }
}
- wait_event(waitq, atomic_read(&wait_count) == 0);
+ wait_event(waitq, atomic_read(&wait_count) == (count - i));
} else {
/* Send Sleep requests to the controller, expect no response */
for (i = 0; i < count; i++) {
diff --git a/include/trace/events/power.h b/include/trace/events/power.h
index e792405..d55175e 100644
--- a/include/trace/events/power.h
+++ b/include/trace/events/power.h
@@ -767,6 +767,33 @@ TRACE_EVENT(memlat_dev_update,
__entry->vote)
);
+TRACE_EVENT(sugov_util_update,
+ TP_PROTO(int cpu,
+ unsigned long util, unsigned long max_cap,
+ unsigned long nl, unsigned long pl,
+ unsigned int flags),
+ TP_ARGS(cpu, util, max_cap, nl, pl, flags),
+ TP_STRUCT__entry(
+ __field( int, cpu)
+ __field( unsigned long, util)
+ __field( unsigned long, max_cap)
+ __field( unsigned long, nl)
+ __field( unsigned long, pl)
+ __field( unsigned int, flags)
+ ),
+ TP_fast_assign(
+ __entry->cpu = cpu;
+ __entry->util = util;
+ __entry->max_cap = max_cap;
+ __entry->nl = nl;
+ __entry->pl = pl;
+ __entry->flags = flags;
+ ),
+ TP_printk("cpu=%d util=%lu max_cap=%lu nl=%lu pl=%lu flags=%x",
+ __entry->cpu, __entry->util, __entry->max_cap,
+ __entry->nl, __entry->pl, __entry->flags)
+);
+
#endif /* _TRACE_POWER_H */
/* This part must be outside protection */
diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
index 104432f..dac3724 100644
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -78,6 +78,9 @@ void irq_migrate_all_off_this_cpu(void)
bool affinity_broken;
desc = irq_to_desc(irq);
+ if (!desc)
+ continue;
+
raw_spin_lock(&desc->lock);
affinity_broken = migrate_one_irq(desc);
raw_spin_unlock(&desc->lock);
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 27d96e2..71909a3 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -56,10 +56,13 @@ struct sugov_cpu {
unsigned long iowait_boost_max;
u64 last_update;
+ struct sched_walt_cpu_load walt_load;
+
/* The fields below are only needed when sharing a policy. */
unsigned long util;
unsigned long max;
unsigned int flags;
+ unsigned int cpu;
};
static DEFINE_PER_CPU(struct sugov_cpu, sugov_cpu);
@@ -70,9 +73,6 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
{
s64 delta_ns;
- if (sg_policy->work_in_progress)
- return false;
-
if (unlikely(sg_policy->need_freq_update)) {
sg_policy->need_freq_update = false;
/*
@@ -150,15 +150,18 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
return cpufreq_driver_resolve_freq(policy, freq);
}
-static void sugov_get_util(unsigned long *util, unsigned long *max)
+static void sugov_get_util(unsigned long *util, unsigned long *max, int cpu)
{
- struct rq *rq = this_rq();
+ struct rq *rq = cpu_rq(cpu);
unsigned long cfs_max;
+ struct sugov_cpu *loadcpu = &per_cpu(sugov_cpu, cpu);
- cfs_max = arch_scale_cpu_capacity(NULL, smp_processor_id());
+ cfs_max = arch_scale_cpu_capacity(NULL, cpu);
*util = min(rq->cfs.avg.util_avg, cfs_max);
*max = cfs_max;
+
+ *util = cpu_util_freq(cpu, &loadcpu->walt_load);
}
static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time,
@@ -206,10 +209,12 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
if (!sugov_should_update_freq(sg_policy, time))
return;
+ flags &= ~SCHED_CPUFREQ_RT_DL;
+
if (flags & SCHED_CPUFREQ_RT_DL) {
next_f = policy->cpuinfo.max_freq;
} else {
- sugov_get_util(&util, &max);
+ sugov_get_util(&util, &max, sg_cpu->cpu);
sugov_iowait_boost(sg_cpu, &util, &max);
next_f = get_next_freq(sg_policy, util, max);
}
@@ -236,7 +241,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
unsigned long j_util, j_max;
s64 delta_ns;
- if (j == smp_processor_id())
+ if (j == sg_cpu->cpu)
continue;
j_sg_cpu = &per_cpu(sugov_cpu, j);
@@ -248,7 +253,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
* idle now (and clear iowait_boost for it).
*/
delta_ns = last_freq_update_time - j_sg_cpu->last_update;
- if (delta_ns > TICK_NSEC) {
+ if (delta_ns > sched_ravg_window) {
j_sg_cpu->iowait_boost = 0;
continue;
}
@@ -276,7 +281,9 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time,
unsigned long util, max;
unsigned int next_f;
- sugov_get_util(&util, &max);
+ sugov_get_util(&util, &max, sg_cpu->cpu);
+
+ flags &= ~SCHED_CPUFREQ_RT_DL;
raw_spin_lock(&sg_policy->update_lock);
@@ -287,6 +294,10 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time,
sugov_set_iowait_boost(sg_cpu, time, flags);
sg_cpu->last_update = time;
+ trace_sugov_util_update(sg_cpu->cpu, sg_cpu->util, max,
+ sg_cpu->walt_load.nl,
+ sg_cpu->walt_load.pl, flags);
+
if (sugov_should_update_freq(sg_policy, time)) {
next_f = sugov_next_freq_shared(sg_cpu, util, max, flags);
sugov_update_commit(sg_policy, time, next_f);
@@ -585,6 +596,7 @@ static int sugov_start(struct cpufreq_policy *policy)
memset(sg_cpu, 0, sizeof(*sg_cpu));
sg_cpu->sg_policy = sg_policy;
+ sg_cpu->cpu = cpu;
sg_cpu->flags = SCHED_CPUFREQ_RT;
sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
diff --git a/mm/kasan/kasan.c b/mm/kasan/kasan.c
index 0e9505f..1258b16 100644
--- a/mm/kasan/kasan.c
+++ b/mm/kasan/kasan.c
@@ -559,7 +559,8 @@ bool kasan_slab_free(struct kmem_cache *cache, void *object)
shadow_byte = READ_ONCE(*(s8 *)kasan_mem_to_shadow(object));
if (shadow_byte < 0 || shadow_byte >= KASAN_SHADOW_SCALE_SIZE) {
- kasan_report_double_free(cache, object, shadow_byte);
+ kasan_report_double_free(cache, object,
+ __builtin_return_address(1));
return true;
}
diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 1c260e6..7572917 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -104,7 +104,7 @@ static inline bool kasan_report_enabled(void)
void kasan_report(unsigned long addr, size_t size,
bool is_write, unsigned long ip);
void kasan_report_double_free(struct kmem_cache *cache, void *object,
- s8 shadow);
+ void *ip);
#if defined(CONFIG_SLAB) || defined(CONFIG_SLUB)
void quarantine_put(struct kasan_free_meta *info, struct kmem_cache *cache);
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 073325a..35d2db8 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -48,7 +48,13 @@ static const void *find_first_bad_addr(const void *addr, size_t size)
return first_bad_addr;
}
-static void print_error_description(struct kasan_access_info *info)
+static bool addr_has_shadow(struct kasan_access_info *info)
+{
+ return (info->access_addr >=
+ kasan_shadow_to_mem((void *)KASAN_SHADOW_START));
+}
+
+static const char *get_shadow_bug_type(struct kasan_access_info *info)
{
const char *bug_type = "unknown-crash";
u8 *shadow_addr;
@@ -95,12 +101,39 @@ static void print_error_description(struct kasan_access_info *info)
break;
}
- pr_err("BUG: KASAN: %s in %pS at addr %p\n",
- bug_type, (void *)info->ip,
- info->access_addr);
- pr_err("%s of size %zu by task %s/%d\n",
- info->is_write ? "Write" : "Read",
- info->access_size, current->comm, task_pid_nr(current));
+ return bug_type;
+}
+
+const char *get_wild_bug_type(struct kasan_access_info *info)
+{
+ const char *bug_type = "unknown-crash";
+
+ if ((unsigned long)info->access_addr < PAGE_SIZE)
+ bug_type = "null-ptr-deref";
+ else if ((unsigned long)info->access_addr < TASK_SIZE)
+ bug_type = "user-memory-access";
+ else
+ bug_type = "wild-memory-access";
+
+ return bug_type;
+}
+
+static const char *get_bug_type(struct kasan_access_info *info)
+{
+ if (addr_has_shadow(info))
+ return get_shadow_bug_type(info);
+ return get_wild_bug_type(info);
+}
+
+static void print_error_description(struct kasan_access_info *info)
+{
+ const char *bug_type = get_bug_type(info);
+
+ pr_err("BUG: KASAN: %s in %pS\n",
+ bug_type, (void *)info->ip);
+ pr_err("%s of size %zu at addr %p by task %s/%d\n",
+ info->is_write ? "Write" : "Read", info->access_size,
+ info->access_addr, current->comm, task_pid_nr(current));
}
static inline bool kernel_or_module_addr(const void *addr)
@@ -139,9 +172,9 @@ static void kasan_end_report(unsigned long *flags)
kasan_enable_current();
}
-static void print_track(struct kasan_track *track)
+static void print_track(struct kasan_track *track, const char *prefix)
{
- pr_err("PID = %u\n", track->pid);
+ pr_err("%s by task %u:\n", prefix, track->pid);
if (track->stack) {
struct stack_trace trace;
@@ -152,59 +185,84 @@ static void print_track(struct kasan_track *track)
}
}
-static void kasan_object_err(struct kmem_cache *cache, void *object)
+static struct page *addr_to_page(const void *addr)
+{
+ if ((addr >= (void *)PAGE_OFFSET) &&
+ (addr < high_memory))
+ return virt_to_head_page(addr);
+ return NULL;
+}
+
+static void describe_object_addr(struct kmem_cache *cache, void *object,
+ const void *addr)
+{
+ unsigned long access_addr = (unsigned long)addr;
+ unsigned long object_addr = (unsigned long)object;
+ const char *rel_type;
+ int rel_bytes;
+
+ pr_err("The buggy address belongs to the object at %p\n"
+ " which belongs to the cache %s of size %d\n",
+ object, cache->name, cache->object_size);
+
+ if (!addr)
+ return;
+
+ if (access_addr < object_addr) {
+ rel_type = "to the left";
+ rel_bytes = object_addr - access_addr;
+ } else if (access_addr >= object_addr + cache->object_size) {
+ rel_type = "to the right";
+ rel_bytes = access_addr - (object_addr + cache->object_size);
+ } else {
+ rel_type = "inside";
+ rel_bytes = access_addr - object_addr;
+ }
+
+ pr_err("The buggy address is located %d bytes %s of\n"
+ " %d-byte region [%p, %p)\n",
+ rel_bytes, rel_type, cache->object_size, (void *)object_addr,
+ (void *)(object_addr + cache->object_size));
+}
+
+static void describe_object(struct kmem_cache *cache, void *object,
+ const void *addr)
{
struct kasan_alloc_meta *alloc_info = get_alloc_info(cache, object);
+ if (cache->flags & SLAB_KASAN) {
+ print_track(&alloc_info->alloc_track, "Allocated");
+ pr_err("\n");
+ print_track(&alloc_info->free_track, "Freed");
+ pr_err("\n");
+ }
+
+ describe_object_addr(cache, object, addr);
+}
+
+static void print_address_description(void *addr)
+{
+ struct page *page = addr_to_page(addr);
+
dump_stack();
- pr_err("Object at %p, in cache %s size: %d\n", object, cache->name,
- cache->object_size);
+ pr_err("\n");
- if (!(cache->flags & SLAB_KASAN))
- return;
+ if (page && PageSlab(page)) {
+ struct kmem_cache *cache = page->slab_cache;
+ void *object = nearest_obj(cache, page, addr);
- pr_err("Allocated:\n");
- print_track(&alloc_info->alloc_track);
- pr_err("Freed:\n");
- print_track(&alloc_info->free_track);
-}
+ describe_object(cache, object, addr);
+ }
-void kasan_report_double_free(struct kmem_cache *cache, void *object,
- s8 shadow)
-{
- unsigned long flags;
+ if (kernel_or_module_addr(addr) && !init_task_stack_addr(addr)) {
+ pr_err("The buggy address belongs to the variable:\n");
+ pr_err(" %pS\n", addr);
+ }
- kasan_start_report(&flags);
- pr_err("BUG: Double free or freeing an invalid pointer\n");
- pr_err("Unexpected shadow byte: 0x%hhX\n", shadow);
- kasan_object_err(cache, object);
- kasan_end_report(&flags);
-}
-
-static void print_address_description(struct kasan_access_info *info)
-{
- const void *addr = info->access_addr;
-
- if ((addr >= (void *)PAGE_OFFSET) &&
- (addr < high_memory)) {
- struct page *page = virt_to_head_page(addr);
-
- if (PageSlab(page)) {
- void *object;
- struct kmem_cache *cache = page->slab_cache;
- object = nearest_obj(cache, page,
- (void *)info->access_addr);
- kasan_object_err(cache, object);
- return;
- }
+ if (page) {
+ pr_err("The buggy address belongs to the page:\n");
dump_page(page, "kasan: bad access detected");
}
-
- if (kernel_or_module_addr(addr)) {
- if (!init_task_stack_addr(addr))
- pr_err("Address belongs to variable %pS\n", addr);
- }
- dump_stack();
}
static bool row_is_guilty(const void *row, const void *guilty)
@@ -259,31 +317,34 @@ static void print_shadow_for_address(const void *addr)
}
}
+void kasan_report_double_free(struct kmem_cache *cache, void *object,
+ void *ip)
+{
+ unsigned long flags;
+
+ kasan_start_report(&flags);
+ pr_err("BUG: KASAN: double-free or invalid-free in %pS\n", ip);
+ pr_err("\n");
+ print_address_description(object);
+ pr_err("\n");
+ print_shadow_for_address(object);
+ kasan_end_report(&flags);
+}
+
static void kasan_report_error(struct kasan_access_info *info)
{
unsigned long flags;
- const char *bug_type;
kasan_start_report(&flags);
- if (info->access_addr <
- kasan_shadow_to_mem((void *)KASAN_SHADOW_START)) {
- if ((unsigned long)info->access_addr < PAGE_SIZE)
- bug_type = "null-ptr-deref";
- else if ((unsigned long)info->access_addr < TASK_SIZE)
- bug_type = "user-memory-access";
- else
- bug_type = "wild-memory-access";
- pr_err("BUG: KASAN: %s on address %p\n",
- bug_type, info->access_addr);
- pr_err("%s of size %zu by task %s/%d\n",
- info->is_write ? "Write" : "Read",
- info->access_size, current->comm,
- task_pid_nr(current));
+ print_error_description(info);
+ pr_err("\n");
+
+ if (!addr_has_shadow(info)) {
dump_stack();
} else {
- print_error_description(info);
- print_address_description(info);
+ print_address_description((void *)info->access_addr);
+ pr_err("\n");
print_shadow_for_address(info->first_bad_addr);
}
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index c3f8005..a2dff71 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -83,7 +83,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country AU: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -92,7 +92,6 @@
(5490 - 5590 @ 80), (24), DFS
(5650 - 5730 @ 80), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (43), NO-OUTDOOR
@@ -138,7 +137,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40)
+ (57000 - 66000 @ 2160), (40)
country BF: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -162,7 +161,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country BH:
(2402 - 2482 @ 40), (20)
@@ -192,7 +191,6 @@
(2402 - 2482 @ 40), (20)
(5250 - 5330 @ 80), (30), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -202,7 +200,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (40)
@@ -238,7 +235,6 @@
(5490 - 5590 @ 80), (24), DFS
(5650 - 5730 @ 80), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (40)
@@ -263,9 +259,8 @@
(5890 - 5910 @ 10), (30)
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country CI: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -278,7 +273,6 @@
(2402 - 2482 @ 40), (20)
(5170 - 5330 @ 160), (20)
(5735 - 5835 @ 80), (20)
-
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (50), NO-OUTDOOR
@@ -303,7 +297,6 @@
(5250 - 5330 @ 20), (24), DFS
(5490 - 5730 @ 20), (24), DFS
(5735 - 5835 @ 20), (30)
-
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (30)
@@ -329,7 +322,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
# Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf
# and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf
@@ -348,7 +341,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
# Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from
# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf
@@ -371,7 +364,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country DK: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -388,7 +381,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country DM: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -414,7 +407,6 @@
(5250 - 5330 @ 20), (24), DFS
(5490 - 5730 @ 20), (24), DFS
(5735 - 5835 @ 20), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -433,7 +425,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country EG: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -455,7 +447,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country ET: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -478,7 +470,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country FM: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -502,7 +494,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country GB: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -519,7 +511,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country GD: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -573,7 +565,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country GT: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -587,7 +579,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -601,7 +592,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4, ref: FCC/EU
(57240 - 65880 @ 2160), (40)
@@ -610,7 +600,6 @@
(5170 - 5330 @ 160), (24)
(5490 - 5730 @ 160), (24)
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -629,7 +618,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country HT: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -653,7 +642,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country ID:
# ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf
@@ -675,15 +664,14 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country IL: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
-
# 60 gHz band channels 1-4, base on Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country IN:
(2402 - 2482 @ 40), (20)
@@ -709,7 +697,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country IT: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -726,7 +714,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country JM: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -734,7 +722,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -742,9 +729,8 @@
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23)
(5735 - 5835 @ 80), (23)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ ((57000 - 66000 @ 2160), (40)
country JP: DFS-JP
(2402 - 2482 @ 40), (20)
@@ -834,9 +820,8 @@
(5890 - 5910 @ 10), (30)
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country LK: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -866,7 +851,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country LU: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -883,7 +868,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country LV: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -899,17 +884,15 @@
(5890 - 5910 @ 10), (30)
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country MA: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country MC: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -996,7 +979,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country MU: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -1023,7 +1006,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -1033,7 +1015,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5650 @ 160), (24), DFS
(5735 - 5815 @ 80), (24)
-
# 60 gHz band channels 1-3
(57240 - 63720 @ 2160), (40)
@@ -1055,7 +1036,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -1074,7 +1054,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country NO: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1091,7 +1071,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country NP:
(2402 - 2482 @ 40), (20)
@@ -1104,9 +1084,8 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country OM: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1146,9 +1125,8 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country PK:
(2402 - 2482 @ 40), (30)
@@ -1169,7 +1147,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country PM: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1206,7 +1184,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country PW: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -1221,7 +1199,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -1250,7 +1227,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
# Source:
# http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf
@@ -1260,14 +1237,13 @@
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
(5490 - 5710 @ 160), (30), DFS
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country RU:
(2402 - 2482 @ 40), (20)
(5170 - 5330 @ 160), (23)
(5490 - 5730 @ 160), (30)
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (40)
@@ -1299,7 +1275,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country SG: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -1307,9 +1283,8 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40), NO-OUTDOOR
country SI: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1326,7 +1301,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country SK: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1343,7 +1318,7 @@
(5900 - 5920 @ 10), (30)
(5910 - 5930 @ 10), (30)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
- (57240 - 65880 @ 2160), (40), NO-OUTDOOR
+ (57000 - 66000 @ 2160), (40)
country SN:
(2402 - 2482 @ 40), (20)
@@ -1391,7 +1366,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (40)
@@ -1411,7 +1385,6 @@
(5170 - 5330 @ 160), (27)
(5490 - 5730 @ 160), (36)
(5735 - 5835 @ 80), (36)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -1421,7 +1394,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-3, FCC
(57240 - 63720 @ 2160), (40)
@@ -1480,7 +1452,6 @@
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (40)
@@ -1514,7 +1485,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (40)
@@ -1559,7 +1529,6 @@
(5250 - 5330 @ 80), (24), DFS, AUTO-BW
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-
# 60 gHz band channels 1-4
(57240 - 65880 @ 2160), (40), NO-OUTDOOR