diff --git a/Documentation/Changes b/Documentation/Changes
index 1de131bb49fb..9ad68f1819d3 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -25,7 +25,7 @@ o Gnu C 3.2 # gcc --version
o Gnu make 3.80 # make --version
o binutils 2.12 # ld -v
o util-linux 2.10o # fdformat --version
-o module-init-tools 0.9.10 # depmod -V
+o kmod 13 # depmod -V
o e2fsprogs 1.41.4 # e2fsck -V
o jfsutils 1.1.3 # fsck.jfs -V
o reiserfsprogs 3.6.3 # reiserfsck -V
@@ -119,12 +119,6 @@ is not build with CONFIG_KALLSYMS and you have no way to rebuild and
reproduce the Oops with that option, then you can still decode that Oops
with ksymoops.
-Module-Init-Tools
------------------
-
-A new module loader is now in the kernel that requires module-init-tools
-to use. It is backward compatible with the 2.4.x series kernels.
-
Mkinitrd
--------
@@ -302,14 +296,15 @@ Util-linux
----------
o
+Kmod
+----
+o
+o
+
Ksymoops
--------
o
-Module-Init-Tools
------------------
-o
-
Mkinitrd
--------
o
diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax.txt b/Documentation/devicetree/bindings/input/touchscreen/himax.txt
deleted file mode 100644
index b54c85971927..000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/himax.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Himax touch controller
-
-Required properties:
-
- - compatible : Should be "himax,hxcommon"
- - reg : i2c slave address of the device.
- - interrupt-parent : parent of interrupt.
- - himax,irq-gpio : irq gpio.
- - himax,reset-gpio : reset gpio.
- - vdd-supply : Power supply needed to power up the device.
- - avdd-supply : Power source required to power up i2c bus.
- - himax,panel-coords : panel coordinates for the chip in pixels.
- It is a four tuple consisting of min x,
- min y, max x and max y values.
- - himax,display-coords : display coordinates in pixels. It is a four
- tuple consisting of min x, min y, max x and
- max y values
-
-Optional properties:
- - himax,3v3-gpio : gpio acting as 3.3 v supply.
- - report_type : Multi-touch protocol type. Default 0.
- 0 for protocol A, 1 for protocol B.
diff --git a/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt b/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt
new file mode 100644
index 000000000000..9889f55dd4bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/himax_i2c_ts.txt
@@ -0,0 +1,57 @@
+Himax touch controller
+
+Required properties:
+
+ - compatible : should be "himax,hxcommon"
+ - reg : i2c slave address of the device
+ - interrupt-parent : parent of interrupt
+ - interrupts : touch sample interrupt to indicate presense or release
+ of fingers on the panel.
+ - himax,irq-gpio : irq gpio
+ - himax,reset-gpio : reset gpio
+
+Optional property:
+ - vdd-supply : Analog power supply needed to power device
+ - vcc_i2c-supply : Power source required to pull up i2c bus
+ - himax,i2c-pull-up : specify to indicate pull up is needed
+ - himax,disable-gpios : specify to disable gpios in suspend (power saving)
+ - himax,button-map : virtual key code mappings to be used
+ - himax,x-flip : modify orientation of the x axis
+ - himax,y-flip : modify orientation of the y axis
+ - himax,panel-coords : touch panel min x, min y, max x and
+ max y resolution
+ - himax,display-coords : display min x, min y, max x and
+ max y resolution
+ - himax,reset-delay : reset delay for controller (ms), default 100
+ - himax,fw-image-name : name of firmware .img file in /etc/firmware
+ - himax,power-down : fully power down regulators in suspend
+ - himax,do-lockdown : perform one time lockdown procedure
+
+Example:
+ i2c@f9927000 { /* BLSP1 QUP5 */
+ cell-index = <5>;
+ compatible = "himax,hxcommon";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg-names = "qup_phys_addr";
+ reg = <0xf9927000 0x1000>;
+ interrupt-names = "qup_err_intr";
+ interrupts = <0 99 0>;
+ gpios = <&msmgpio 19 0>, /* SCL */
+ <&msmgpio 18 0>; /* SDA */
+ qcom,i2c-bus-freq = <100000>;
+ qcom,i2c-src-freq = <19200000>;
+
+ himax_ts@20 {
+ compatible = "himax,hxcommon"
+ reg = <0x20>;
+ interrupt-parent = <&tlmm>;
+ interrupts = <255 0x2008>;
+ vdd-supply = <&pm8994_l15>;
+ avdd-supply = <&pm8994_l22>;
+ himax,panel-coords = <0 720 0 1440>;
+ himax,display-coords = <0 720 0 1440>;
+ himax,irq-gpio = <&tlmm 255 0x2008>;
+ himax,rst-gpio = <&tlmm 8 0x00>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/hmxchipset.txt b/Documentation/devicetree/bindings/input/touchscreen/hmxchipset.txt
deleted file mode 100644
index b1fc17fff80f..000000000000
--- a/Documentation/devicetree/bindings/input/touchscreen/hmxchipset.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Himax Touch Controller
-
-Required properties:
-
- - compatible : Should be "himax,hxcommon"
- - reg : I2C slave address of the device.
- - interrupt-parent : Parent of interrupt.
- - interrupts : Configuration of touch panel controller interrupt
- GPIO.
- - interrupt-gpios : Interrupt gpio which is to provide interrupts to
- host, same as "interrupts" node.
- - reset-gpios : Reset gpio to control the reset of chip.
- - himax,display-coords : Display coordinates in pixels. It is a four
- tuple consisting of min x, min y, max x and
- max y values.
-
-Optional properties:
-
- - avdd-supply : Power supply needed to power up the device, this is
- for fixed voltage external regulator.
- - vdd-supply : Power supply needed to power up the device, when use
- external regulator, do not add this property.
- - himax,panel-coords : Panel coordinates for the chip in pixels.
- It is a four tuple consisting of min x,
- min y, max x and max y values.
-
-Example:
-&i2c_3 {
- status = "okay";
- himax_ts@48 {
- compatible = "himax,hxcommon";
- reg = <0x48>;
- interrupt-parent = <&tlmm>;
- interrupts = <65 0x2>;
- vdd-supply = <&pm8953_l10>;
- avdd-supply = <&pm8953_l5>;
- pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_release";
- pinctrl-0 = <&ts_int_active &ts_reset_active>;
- pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
- pinctrl-2 = <&ts_release>;
- himax,panel-coords = <0 800 0 1280>;
- himax,display-coords = <0 800 0 1280>;
- himax,irq-gpio = <&tlmm 65 0x2008>;
- //himax,rst-gpio = <&tlmm 64 0x0>;
- report_type = <1>;
- };
-};
diff --git a/Documentation/devicetree/bindings/platform/msm/ssm.txt b/Documentation/devicetree/bindings/platform/msm/ssm.txt
deleted file mode 100644
index 7df3efd66577..000000000000
--- a/Documentation/devicetree/bindings/platform/msm/ssm.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-* Qualcomm Technologies, Inc. Secure Service Module driver
-
-This module enables framework to which a client can register itself
-specifying different attributes and defining various permission levels
-associated with different combination of attribute values and mode of the system.
-
-Required properties:
-- compatible: Must be "qcom,ssm"
-
-Example:
- qcom,ssm {
- compatible = "qcom,ssm";
- };
\ No newline at end of file
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
index 80c8fd14ef94..bc9727207289 100755
--- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
+++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt
@@ -1371,6 +1371,16 @@ Required properties:
When clock rate is set to zero,
then external clock is assumed.
+ - qcom,msm-cpudai-tdm-afe-ebit-unsupported: Notify if ebit setting is needed
+ When this is set , alongwith
+ clock rate as zero then afe
+ is not configured for clock.
+
+ - qcom,msm-cpudai-tdm-sec-port-start: For chipsets with the limitation where we need
+ to start both RX and TX AFE ports, this flag is
+ used to start TX/RX port for RX/TX streams.
+
+
[Second Level Nodes]
Required properties:
@@ -1963,6 +1973,9 @@ Optional properties:
- qcom,wsa-devs: This property contains list of wsa codec names. The names
should comply with the wsa nodes configurations.
- qcom,wsa-aux-dev-prefix: This property contains list of wsa codec prefixes.
+- qcom,tdm-i2s-switch-enable: For chipsets where tdm mics are controlled by
+ switch, drive corresponding gpio to output high
+ to enable switch.
Example:
sound {
diff --git a/Documentation/devicetree/bindings/sound/taiko_codec.txt b/Documentation/devicetree/bindings/sound/taiko_codec.txt
index 90bef273363d..5f8d2938b187 100644
--- a/Documentation/devicetree/bindings/sound/taiko_codec.txt
+++ b/Documentation/devicetree/bindings/sound/taiko_codec.txt
@@ -536,6 +536,10 @@ Tasha audio CODEC in I2C mode
- qcom,cdc-dmic-sample-rate - Specifies dmic sample rate.
- qcom,cdc-variant - Specifies codec variant.
+ - qcom,wcd9xxx-mic-tristate: For chipsets where I2S TX line is shared between
+ the Codec and TDM mics, tristate the WCD mics to
+ avoid PCM interference as the end product uses
+ only TDM mics.
Example:
i2c_3: i2c@78B7000 { /* BLSP1 QUP3 */
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index e9b27436f543..d5455ba063ec 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -78,6 +78,7 @@ haoyu Haoyu Microelectronic Co. Ltd.
hisilicon Hisilicon Limited.
honeywell Honeywell
hp Hewlett Packard
+himax Himax Coroporation
i2se I2SE GmbH
ibm International Business Machines (IBM)
idt Integrated Device Technologies, Inc.
diff --git a/Makefile b/Makefile
index 1f203e0f8433..6b804d1a4e0b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 18
-SUBLEVEL = 116
+SUBLEVEL = 122
EXTRAVERSION =
NAME = Diseased Newt
@@ -615,6 +615,7 @@ KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)
KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)
KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)
KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)
+KBUILD_CFLAGS += $(call cc-disable-warning, attribute-alias)
KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
KBUILD_AFLAGS += $(call cc-option,-fno-PIE)
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index cb34a25a0168..755554ebd9dc 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -525,24 +525,19 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
SYSCALL_DEFINE1(osf_utsname, char __user *, name)
{
int error;
+ char tmp[5 * 32];
down_read(&uts_sem);
- error = -EFAULT;
- if (copy_to_user(name + 0, utsname()->sysname, 32))
- goto out;
- if (copy_to_user(name + 32, utsname()->nodename, 32))
- goto out;
- if (copy_to_user(name + 64, utsname()->release, 32))
- goto out;
- if (copy_to_user(name + 96, utsname()->version, 32))
- goto out;
- if (copy_to_user(name + 128, utsname()->machine, 32))
- goto out;
+ memcpy(tmp + 0 * 32, utsname()->sysname, 32);
+ memcpy(tmp + 1 * 32, utsname()->nodename, 32);
+ memcpy(tmp + 2 * 32, utsname()->release, 32);
+ memcpy(tmp + 3 * 32, utsname()->version, 32);
+ memcpy(tmp + 4 * 32, utsname()->machine, 32);
+ up_read(&uts_sem);
- error = 0;
- out:
- up_read(&uts_sem);
- return error;
+ if (copy_to_user(name, tmp, sizeof(tmp)))
+ return -EFAULT;
+ return 0;
}
SYSCALL_DEFINE0(getpagesize)
@@ -560,24 +555,22 @@ SYSCALL_DEFINE0(getdtablesize)
*/
SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)
{
- unsigned len;
- int i;
+ int len, err = 0;
+ char *kname;
+ char tmp[32];
- if (!access_ok(VERIFY_WRITE, name, namelen))
- return -EFAULT;
-
- len = namelen;
- if (len > 32)
- len = 32;
+ if (namelen < 0 || namelen > 32)
+ namelen = 32;
down_read(&uts_sem);
- for (i = 0; i < len; ++i) {
- __put_user(utsname()->domainname[i], name + i);
- if (utsname()->domainname[i] == '\0')
- break;
- }
+ kname = utsname()->domainname;
+ len = strnlen(kname, namelen);
+ len = min(len + 1, namelen);
+ memcpy(tmp, kname, len);
up_read(&uts_sem);
+ if (copy_to_user(name, tmp, len))
+ return -EFAULT;
return 0;
}
@@ -740,13 +733,14 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
};
unsigned long offset;
const char *res;
- long len, err = -EINVAL;
+ long len;
+ char tmp[__NEW_UTS_LEN + 1];
offset = command-1;
if (offset >= ARRAY_SIZE(sysinfo_table)) {
/* Digital UNIX has a few unpublished interfaces here */
printk("sysinfo(%d)", command);
- goto out;
+ return -EINVAL;
}
down_read(&uts_sem);
@@ -754,13 +748,11 @@ SYSCALL_DEFINE3(osf_sysinfo, int, command, char __user *, buf, long, count)
len = strlen(res)+1;
if ((unsigned long)len > (unsigned long)count)
len = count;
- if (copy_to_user(buf, res, len))
- err = -EFAULT;
- else
- err = 0;
+ memcpy(tmp, res, len);
up_read(&uts_sem);
- out:
- return err;
+ if (copy_to_user(buf, tmp, len))
+ return -EFAULT;
+ return 0;
}
SYSCALL_DEFINE5(osf_getsysinfo, unsigned long, op, void __user *, buffer,
diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h
index 43de30256981..ee08badc5b91 100644
--- a/arch/arc/include/asm/delay.h
+++ b/arch/arc/include/asm/delay.h
@@ -17,8 +17,11 @@
#ifndef __ASM_ARC_UDELAY_H
#define __ASM_ARC_UDELAY_H
+#include
#include /* HZ */
+extern unsigned long loops_per_jiffy;
+
static inline void __delay(unsigned long loops)
{
__asm__ __volatile__(
diff --git a/arch/arc/include/asm/page.h b/arch/arc/include/asm/page.h
index 9c8aa41e45c2..25f6583a7a2c 100644
--- a/arch/arc/include/asm/page.h
+++ b/arch/arc/include/asm/page.h
@@ -97,7 +97,7 @@ typedef unsigned long pgtable_t;
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
/* Default Permissions for stack/heaps pages (Non Executable) */
-#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE)
+#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
#define WANT_PAGE_VIRTUAL 1
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index 7670f33b9ce2..0f12756d6389 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -372,7 +372,7 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,
/* Decode a PTE containing swap "identifier "into constituents */
#define __swp_type(pte_lookalike) (((pte_lookalike).val) & 0x1f)
-#define __swp_offset(pte_lookalike) ((pte_lookalike).val << 13)
+#define __swp_offset(pte_lookalike) ((pte_lookalike).val >> 13)
/* NOPs, to keep generic kernel happy */
#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
diff --git a/arch/arc/mm/cache_arc700.c b/arch/arc/mm/cache_arc700.c
index 2147ca2bc131..51cba86e8cc9 100644
--- a/arch/arc/mm/cache_arc700.c
+++ b/arch/arc/mm/cache_arc700.c
@@ -642,7 +642,7 @@ void flush_cache_mm(struct mm_struct *mm)
void flush_cache_page(struct vm_area_struct *vma, unsigned long u_vaddr,
unsigned long pfn)
{
- unsigned int paddr = pfn << PAGE_SHIFT;
+ phys_addr_t paddr = pfn << PAGE_SHIFT;
u_vaddr &= PAGE_MASK;
@@ -662,8 +662,9 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page,
unsigned long u_vaddr)
{
/* TBD: do we really need to clear the kernel mapping */
- __flush_dcache_page(page_address(page), u_vaddr);
- __flush_dcache_page(page_address(page), page_address(page));
+ __flush_dcache_page((phys_addr_t)page_address(page), u_vaddr);
+ __flush_dcache_page((phys_addr_t)page_address(page),
+ (phys_addr_t)page_address(page));
}
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
index 5a452fdd7c5d..1f4b2033ba2b 100644
--- a/arch/arm/boot/dts/am3517.dtsi
+++ b/arch/arm/boot/dts/am3517.dtsi
@@ -62,6 +62,11 @@
};
};
+/* Table Table 5-79 of the TRM shows 480ab000 is reserved */
+&usb_otg_hs {
+ status = "disabled";
+};
+
&iva {
status = "disabled";
};
diff --git a/arch/arm/boot/dts/am437x-sk-evm.dts b/arch/arm/boot/dts/am437x-sk-evm.dts
index 53bbfc90b26a..247ea36407cb 100644
--- a/arch/arm/boot/dts/am437x-sk-evm.dts
+++ b/arch/arm/boot/dts/am437x-sk-evm.dts
@@ -415,6 +415,8 @@
touchscreen-size-x = <480>;
touchscreen-size-y = <272>;
+
+ wakeup-source;
};
tlv320aic3106: tlv320aic3106@1b {
diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
index 0bd98cd00816..4ef5c3410fcc 100644
--- a/arch/arm/boot/dts/da850.dtsi
+++ b/arch/arm/boot/dts/da850.dtsi
@@ -267,11 +267,7 @@
compatible = "ti,dm6441-gpio";
gpio-controller;
reg = <0x226000 0x1000>;
- interrupts = <42 IRQ_TYPE_EDGE_BOTH
- 43 IRQ_TYPE_EDGE_BOTH 44 IRQ_TYPE_EDGE_BOTH
- 45 IRQ_TYPE_EDGE_BOTH 46 IRQ_TYPE_EDGE_BOTH
- 47 IRQ_TYPE_EDGE_BOTH 48 IRQ_TYPE_EDGE_BOTH
- 49 IRQ_TYPE_EDGE_BOTH 50 IRQ_TYPE_EDGE_BOTH>;
+ interrupts = <42 43 44 45 46 47 48 49 50>;
ti,ngpio = <144>;
ti,davinci-gpio-unbanked = <0>;
status = "disabled";
diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi
index 22c9fc0fbc9e..862e00cfeea7 100644
--- a/arch/arm/boot/dts/imx6sx.dtsi
+++ b/arch/arm/boot/dts/imx6sx.dtsi
@@ -1206,7 +1206,7 @@
/* non-prefetchable memory */
0x82000000 0 0x08000000 0x08000000 0 0x00f00000>;
num-lanes = <1>;
- interrupts = ;
+ interrupts = ;
clocks = <&clks IMX6SX_CLK_PCIE_REF_125M>,
<&clks IMX6SX_CLK_PCIE_AXI>,
<&clks IMX6SX_CLK_LVDS1_OUT>,
diff --git a/arch/arm/boot/dts/qcom/apq8009-audio-external_codec.dtsi b/arch/arm/boot/dts/qcom/apq8009-audio-external_codec.dtsi
index 57c3db93bb01..c70e5ec90cec 100644
--- a/arch/arm/boot/dts/qcom/apq8009-audio-external_codec.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8009-audio-external_codec.dtsi
@@ -25,7 +25,9 @@
qcom,model = "apq8009-tashalite-snd-card";
qcom,msm-mbhc-hphl-swh = <0>;
qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,afe-rxtx-lb;
qcom,msm-mclk-freq = <9600000>;
+ qcom,tdm-audio-intf;
qcom,msm-hs-micbias-type = "internal";
qcom,audio-routing =
"AIF4 VI", "MCLK",
@@ -87,7 +89,9 @@
<&incall_record_rx>, <&incall_record_tx>,
<&incall_music_rx>, <&incall_music_2_rx>,
<&bt_sco_rx>,
- <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>;
+ <&bt_sco_tx>, <&int_fm_rx>, <&int_fm_tx>,
+ <&afe_loopback_tx>, <&dai_pri_tdm_rx_0>,
+ <&dai_pri_tdm_tx_0>;
asoc-cpu-names = "msm-dai-q6-auxpcm.1", "msm-dai-q6-hdmi.8",
"msm-dai-q6-mi2s.0",
"msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
@@ -101,7 +105,9 @@
"msm-dai-q6-dev.32772", "msm-dai-q6-dev.32773",
"msm-dai-q6-dev.32770",
"msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289",
- "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293";
+ "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293",
+ "msm-dai-q6-dev.24577", "msm-dai-q6-tdm.36864",
+ "msm-dai-q6-tdm.36865";
asoc-codec = <&stub_codec>;
asoc-codec-names = "msm-stub-codec.1";
qcom,wsa-max-devs = <2>;
@@ -221,4 +227,44 @@
};
};
};
+
+ pri_tdm_rx: qcom,msm-dai-tdm-pri-rx {
+ compatible = "qcom,msm-dai-tdm";
+ qcom,msm-cpudai-tdm-group-id = <37120>;
+ qcom,msm-cpudai-tdm-group-num-ports = <1>;
+ qcom,msm-cpudai-tdm-group-port-id = <36864>;
+ qcom,msm-cpudai-tdm-clk-rate = <12288000>;
+ qcom,msm-cpudai-tdm-sec-port-enable;
+ qcom,msm-cpudai-tdm-clk-attribute = /bits/ 16 <1>;
+ dai_pri_tdm_rx_0: qcom,msm-dai-q6-tdm-pri-rx-0 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36864>;
+ qcom,msm-cpudai-tdm-sync-mode = <0>;
+ qcom,msm-cpudai-tdm-sync-src = <1>;
+ qcom,msm-cpudai-tdm-data-out = <0>;
+ qcom,msm-cpudai-tdm-invert-sync = <0>;
+ qcom,msm-cpudai-tdm-data-delay = <1>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+ };
+
+ pri_tdm_tx: qcom,msm-dai-tdm-pri-tx {
+ compatible = "qcom,msm-dai-tdm";
+ qcom,msm-cpudai-tdm-group-id = <37121>;
+ qcom,msm-cpudai-tdm-group-num-ports = <1>;
+ qcom,msm-cpudai-tdm-group-port-id = <36865>;
+ qcom,msm-cpudai-tdm-clk-rate = <12288000>;
+ qcom,msm-cpudai-tdm-sec-port-enable;
+ qcom,msm-cpudai-tdm-clk-attribute = /bits/ 16 <1>;
+ dai_pri_tdm_tx_0: qcom,msm-dai-q6-tdm-pri-tx-0 {
+ compatible = "qcom,msm-dai-q6-tdm";
+ qcom,msm-cpudai-tdm-dev-id = <36865>;
+ qcom,msm-cpudai-tdm-sync-mode = <0>;
+ qcom,msm-cpudai-tdm-sync-src = <1>;
+ qcom,msm-cpudai-tdm-data-out = <0>;
+ qcom,msm-cpudai-tdm-invert-sync = <0>;
+ qcom,msm-cpudai-tdm-data-delay = <1>;
+ qcom,msm-cpudai-tdm-data-align = <0>;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi b/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi
index 810b6ae7d0f6..f651fa2c0c6c 100644
--- a/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8009-dragon.dtsi
@@ -17,9 +17,14 @@
#include "msm8909-pm8916-mtp.dtsi"
#include "apq8009-audio-external_codec.dtsi"
+&audio_codec_mtp {
+ status = "disabled";
+};
+
&soc {
- ext-codec {
- qcom,msm-mbhc-hphl-swh = <0>;
+ sound-9335 {
+ qcom,model = "apq8009-tashalite-snd-card-tdm";
+ qcom,tdm-i2s-switch-enable = <&msm_gpio 88 0>;
qcom,audio-routing =
"AIF4 VI", "MCLK",
"RX_BIAS", "MCLK",
@@ -38,16 +43,32 @@
"SpkrRight IN", "SPK2 OUT";
};
- sound-9335 {
- status = "disabled";
- };
-
i2c@78b8000 {
wcd9xxx_codec@d {
- status = "disabled";
+ qcom,wcd9xxx-mic-tristate;
+ qcom,cdc-reset-gpio = <&msm_gpio 23 0>;
+
+ cdc-vdd-buck-supply = <&wcd_vdd_buck_1p8>;
+ qcom,cdc-vdd-buck-voltage = <0 0>;
+ qcom,cdc-vdd-buck-current = <250000>;
+
+ cdc-buck-sido-supply = <&wcd_vdd_buck_1p8>;
+ qcom,cdc-buck-sido-voltage = <0 0>;
+ qcom,cdc-buck-sido-current = <250000>;
};
};
+ wcd_vdd_buck_1p8: wcd_vdd_buck_1p8 {
+ compatible = "regulator-fixed";
+ regulator-name = "wcd_vdd_buck_1p8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ status = "ok";
+ enable-active-high;
+ gpio = <&pm8916_gpios 4 0>;
+ vin-supply = <&pm8916_s4>;
+ };
+
vph_pwr_vreg: vph_pwr_vreg {
compatible = "regulator-fixed";
status = "ok";
@@ -128,6 +149,17 @@
};
};
+&pm8916_gpios {
+ gpio@c300 {
+ qcom,mode = <1>; /* DIGITAL OUT */
+ qcom,pull = <1>; /* No Pull */
+ qcom,vin-sel = <2>; /* 1.8 */
+ qcom,src-sel = <0>; /* CONSTANT */
+ qcom,master-en = <1>; /* ENABLE GPIO */
+ status = "okay";
+ };
+};
+
&pm8916_bms {
status = "ok";
qcom,disable-bms;
diff --git a/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi b/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi
index 8649b2000e70..0cf97ceb1ca7 100644
--- a/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi
+++ b/arch/arm/boot/dts/qcom/apq8053-lite-dragon.dtsi
@@ -408,7 +408,8 @@
2 &tlmm 133 0>;
interrupt-names = "hc_irq", "pwr_irq", "status_irq";
- qcom,clk-rates = <400000 20000000 25000000 50000000>;
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 177770000>;
qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
status = "ok";
diff --git a/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts b/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts
index c21b6d6cbc9e..a30813f4be6c 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v2-auto-dragonboard.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts
index 74bb21eedf10..0f021e0ef437 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-adp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts
index 82030c493f8d..4e683f632894 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-cdp.dts
@@ -38,7 +38,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts b/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts
index cd02dacbdcee..2be4f89c0cc7 100644
--- a/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom/apq8096-v3-auto-dragonboard.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts
index e2d4f2b9babe..fa0da0c23743 100644
--- a/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096pro-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts
index fdea81eb9322..3ee3238bae7b 100644
--- a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-adp.dts
@@ -31,7 +31,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts
index d5eb6031e378..15bd28865e64 100644
--- a/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/apq8096pro-v1.1-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi b/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi
index 9ad11c4cf64d..c5b7575ef438 100644
--- a/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi
+++ b/arch/arm/boot/dts/qcom/dsi-panel-hx83100a-800p-video.dtsi
@@ -39,11 +39,6 @@
qcom,mdss-dsi-on-command = [
39 01 00 00 78 00 02 11 00
39 01 00 00 14 00 02 29 00
- 39 01 00 00 00 00 04 B9 83 10 0A
- 39 01 00 00 00 00 08 C9 1F 00 08 1E 81 1E 00
- 39 01 00 00 00 00 02 53 24
- 39 01 00 00 05 00 02 55 02
- 39 01 00 00 00 00 0A CA 40 3C 38 34 33 32 30 2C 28
];
qcom,mdss-dsi-off-command = [05 01 00 00 96 00 02 28 00
05 01 00 00 00 00 02 10 00];
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi b/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
index 3ab680127d64..c32278a35ad1 100644
--- a/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9650-ccard.dtsi
@@ -613,7 +613,7 @@
reg = <0>;
spi-max-frequency = <9600000>;
interrupt-parent = <&tlmm_pinmux>;
- interrupts = <87 0>;
+ interrupts = <87 2>;
qcom,reset-gpio = <&tlmm_pinmux 89 0x1>;
qcom,clk-freq-mhz = <20000000>;
qcom,max-can-channels = <1>;
diff --git a/arch/arm/boot/dts/qcom/mdm9650-ttp.dts b/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
index 8a951ffb004f..1638d1866ded 100644
--- a/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
+++ b/arch/arm/boot/dts/qcom/mdm9650-ttp.dts
@@ -78,7 +78,7 @@
spi-max-frequency = <4800000>;
reg = <0>;
interrupt-parent = <&tlmm_pinmux>;
- interrupts = <84 0>;
+ interrupts = <84 1>;
reset-gpio = <&tlmm_pinmux 68 0x1>;
pinctrl-names = "active", "sleep";
pinctrl-0 = <&can_rst_on>;
diff --git a/arch/arm/boot/dts/qcom/mdm9650.dtsi b/arch/arm/boot/dts/qcom/mdm9650.dtsi
index 2d46a23ce20e..94e02dc3239f 100644
--- a/arch/arm/boot/dts/qcom/mdm9650.dtsi
+++ b/arch/arm/boot/dts/qcom/mdm9650.dtsi
@@ -22,7 +22,7 @@
<286 0x10000>, <283 0x10000>, <359 0x10000>;
interrupt-parent = <&intc>;
- reserved-memory {
+ reserved_mem: reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
@@ -1058,8 +1058,8 @@
qcom,limit-temp = <60>;
qcom,temp-hysteresis = <10>;
qcom,freq-step = <2>;
- qcom,vdd-restriction-temp = <5>;
- qcom,vdd-restriction-temp-hysteresis = <10>;
+ qcom,vdd-restriction-temp = <10>;
+ qcom,vdd-restriction-temp-hysteresis = <15>;
vdd-dig-supply = <&pmd9650_s5_floor_level>;
qcom,disable-cx-phase-ctrl;
qcom,disable-gfx-phase-ctrl;
@@ -1069,9 +1069,9 @@
qcom,vdd-dig-rstr{
qcom,vdd-rstr-reg = "vdd-dig";
- qcom,levels = ;
+ qcom,levels = ;
qcom,min-level = ;
};
};
diff --git a/arch/arm/boot/dts/qcom/msm8909.dtsi b/arch/arm/boot/dts/qcom/msm8909.dtsi
index 34a8cccbd5a4..d1d618d77786 100644
--- a/arch/arm/boot/dts/qcom/msm8909.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8909.dtsi
@@ -1727,6 +1727,11 @@
qcom,msm-dai-q6-dev-id = <240>;
};
+ afe_loopback_tx: qcom,msm-dai-q6-afe-loopback-tx {
+ compatible = "qcom,msm-dai-q6-dev";
+ qcom,msm-dai-q6-dev-id = <24577>;
+ };
+
incall_record_rx: qcom,msm-dai-q6-incall-record-rx {
compatible = "qcom,msm-dai-q6-dev";
qcom,msm-dai-q6-dev-id = <32771>;
@@ -1861,6 +1866,10 @@
qcom,use-sw-aes-cbc-ecb-ctr-algo;
qcom,use-sw-aes-xts-algo;
qcom,use-sw-ahash-algo;
+ qcom,use-sw-aes-ccm-algo;
+ qcom,use-sw-hmac-algo;
+ qcom,use-sw-aead-algo;
+
status = "disabled";
qcom,ce-opp-freq = <100000000>;
};
diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts
index d4cf58f9b8ea..4ff449a45d1a 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-v3-auto-adp.dts
@@ -31,7 +31,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts
index 33daf9d6f0e7..250ce9289c70 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-v3-auto-cdp.dts
@@ -43,7 +43,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts b/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts
index d84b0d781b29..cf1128b5d283 100644
--- a/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996-v3-pm8004-agave-adp.dts
@@ -28,7 +28,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
index 15b00af5f0f4..91f9ab654e51 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-adp.dts
@@ -31,7 +31,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <122 0>;
+ interrupts = <122 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts
index 4a78a2fef835..a4c0a0515995 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts b/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts
index d75f56d12291..13a0e914cdfa 100644
--- a/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts
+++ b/arch/arm/boot/dts/qcom/msm8996pro-v1.1-auto-cdp.dts
@@ -30,7 +30,7 @@
compatible = "qcom,renesas,rh850";
reg = <0>;
interrupt-parent = <&tlmm>;
- interrupts = <127 0>;
+ interrupts = <127 2>;
spi-max-frequency = <5000000>;
qcom,clk-freq-mhz = <16000000>;
qcom,max-can-channels = <4>;
diff --git a/arch/arm/boot/dts/qcom/sdx20.dtsi b/arch/arm/boot/dts/qcom/sdx20.dtsi
index 811eef6f2755..6059ed7278f6 100644
--- a/arch/arm/boot/dts/qcom/sdx20.dtsi
+++ b/arch/arm/boot/dts/qcom/sdx20.dtsi
@@ -39,6 +39,17 @@
reg = <0x88000000 0x7300000>;
};
+&reserved_mem {
+ linux,cma {
+ compatible = "shared-dma-pool";
+ alloc-ranges = <0 0x00000000 0 0x90000000>;
+ reusable;
+ alignment = <0 0x400000>;
+ size = <0 0xc00000>;
+ linux,cma-default;
+ };
+};
+
&soc {
/* SD card 2.95 V supply */
sdc_vreg: sdc_vreg {
@@ -138,6 +149,16 @@
/delete-node/ qcom,spm@b009000;
/delete-node/ qcom,mpm@601b8;
/delete-node/ qcom,lpm-levels;
+
+ qcom,msm-thermal {
+ qcom,vdd-restriction-temp = <5>;
+ qcom,vdd-restriction-temp-hysteresis = <10>;
+ qcom,vdd-dig-rstr{
+ qcom,levels = ;
+ };
+ };
};
&clock_gcc {
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dtsi b/arch/arm/boot/dts/tegra30-cardhu.dtsi
index a1b682ea01bd..224a7605877e 100644
--- a/arch/arm/boot/dts/tegra30-cardhu.dtsi
+++ b/arch/arm/boot/dts/tegra30-cardhu.dtsi
@@ -200,6 +200,7 @@
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
+ reset-gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_LOW>;
};
};
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index e6b0007355f8..0dfa0029470f 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -146,9 +146,11 @@ CONFIG_USB_STORAGE=y
CONFIG_USB_CHIPIDEA=y
CONFIG_USB_CHIPIDEA_UDC=y
CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_CHIPIDEA_ULPI=y
CONFIG_NOP_USB_XCEIV=y
CONFIG_USB_GADGET=y
CONFIG_USB_ETH=m
+CONFIG_USB_ULPI_BUS=y
CONFIG_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_PLTFM=y
diff --git a/arch/arm/configs/mdm-perf_defconfig b/arch/arm/configs/mdm-perf_defconfig
index 9b207032aeee..09a3f1e14f6d 100644
--- a/arch/arm/configs/mdm-perf_defconfig
+++ b/arch/arm/configs/mdm-perf_defconfig
@@ -27,7 +27,6 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MSM=y
-CONFIG_ARCH_MDM9640=y
CONFIG_ARCH_MDM9650=y
CONFIG_PCI_MSM=y
CONFIG_PREEMPT=y
@@ -205,7 +204,7 @@ CONFIG_TUN=y
# CONFIG_NET_VENDOR_CIRRUS is not set
# CONFIG_NET_VENDOR_FARADAY is not set
# CONFIG_NET_VENDOR_INTEL is not set
-CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
CONFIG_ECM_IPA=y
CONFIG_RNDIS_IPA=y
@@ -238,7 +237,6 @@ CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=m
-CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_HSL=y
@@ -282,12 +280,7 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MDM9650=y
-CONFIG_UHID=y
-CONFIG_HID_APPLE=y
-CONFIG_HID_ELECOM=y
-CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
-CONFIG_HID_MULTITOUCH=y
+# CONFIG_HID_GENERIC is not set
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_XHCI_HCD=y
@@ -295,19 +288,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
CONFIG_USB_EHCI_MSM_HSIC=y
CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_DWC3=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_NOP_USB_XCEIV=y
@@ -399,8 +379,6 @@ CONFIG_DEVFREQ_SPDM=y
CONFIG_IIO=y
CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=y
-CONFIG_IIO_ST_ACCEL_3AXIS=y
-CONFIG_IIO_ST_GYRO_3AXIS=y
CONFIG_SENSORS_BMI160_IIO=y
CONFIG_SENSORS_BMI160_IIO_RING=y
CONFIG_ENABLE_ACC_GYRO_BUFFERING=y
diff --git a/arch/arm/configs/mdm_defconfig b/arch/arm/configs/mdm_defconfig
index bffd18813078..031eceff80ed 100644
--- a/arch/arm/configs/mdm_defconfig
+++ b/arch/arm/configs/mdm_defconfig
@@ -205,7 +205,7 @@ CONFIG_TUN=y
# CONFIG_NET_VENDOR_CIRRUS is not set
# CONFIG_NET_VENDOR_FARADAY is not set
# CONFIG_NET_VENDOR_INTEL is not set
-CONFIG_KS8851=y
+# CONFIG_NET_VENDOR_MICREL is not set
# CONFIG_NET_VENDOR_MICROCHIP is not set
CONFIG_ECM_IPA=y
CONFIG_RNDIS_IPA=y
@@ -238,7 +238,6 @@ CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=m
-CONFIG_SERIO_LIBPS2=y
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM_HS=y
CONFIG_SERIAL_MSM_HSL=y
@@ -259,7 +258,6 @@ CONFIG_SPI_SPIDEV=m
CONFIG_PPS_CLIENT_GPIO=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_PINCTRL_MDM9607=y
-CONFIG_PINCTRL_MDM9640=y
CONFIG_PINCTRL_MDM9650=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
@@ -289,12 +287,7 @@ CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
CONFIG_SND_SOC_MDM9650=y
-CONFIG_UHID=y
-CONFIG_HID_APPLE=y
-CONFIG_HID_ELECOM=y
-CONFIG_HID_MAGICMOUSE=y
-CONFIG_HID_MICROSOFT=y
-CONFIG_HID_MULTITOUCH=y
+# CONFIG_HID_GENERIC is not set
CONFIG_USB=y
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_XHCI_HCD=y
@@ -302,19 +295,6 @@ CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MSM=y
CONFIG_USB_EHCI_MSM_HSIC=y
CONFIG_USB_ACM=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-CONFIG_USB_STORAGE_ISD200=y
-CONFIG_USB_STORAGE_USBAT=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_STORAGE_ALAUDA=y
-CONFIG_USB_STORAGE_ONETOUCH=y
-CONFIG_USB_STORAGE_KARMA=y
-CONFIG_USB_STORAGE_CYPRESS_ATACB=y
CONFIG_USB_DWC3=y
CONFIG_USB_EHSET_TEST_FIXTURE=y
CONFIG_NOP_USB_XCEIV=y
@@ -411,8 +391,6 @@ CONFIG_DEVFREQ_SPDM=y
CONFIG_IIO=y
CONFIG_IIO_BUFFER=y
CONFIG_IIO_BUFFER_CB=y
-CONFIG_IIO_ST_ACCEL_3AXIS=y
-CONFIG_IIO_ST_GYRO_3AXIS=y
CONFIG_SENSORS_BMI160_IIO=y
CONFIG_SENSORS_BMI160_IIO_RING=y
CONFIG_ENABLE_ACC_GYRO_BUFFERING=y
diff --git a/arch/arm/configs/msm8909-perf_defconfig b/arch/arm/configs/msm8909-perf_defconfig
index 5e79c10ae920..2557519188a3 100644
--- a/arch/arm/configs/msm8909-perf_defconfig
+++ b/arch/arm/configs/msm8909-perf_defconfig
@@ -256,6 +256,7 @@ CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
CONFIG_NETDEVICES=y
@@ -531,10 +532,10 @@ CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_CTR=y
-CONFIG_CRYPTO_XTS=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm/configs/msm8909_defconfig b/arch/arm/configs/msm8909_defconfig
index 230bab172feb..de501ebb77c0 100644
--- a/arch/arm/configs/msm8909_defconfig
+++ b/arch/arm/configs/msm8909_defconfig
@@ -261,6 +261,7 @@ CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_FEC=y
CONFIG_NETDEVICES=y
@@ -584,7 +585,6 @@ CONFIG_HARDENED_USERCOPY=y
CONFIG_SECURITY_SELINUX=y
CONFIG_CRYPTO_NULL=y
CONFIG_CRYPTO_CTR=y
-CONFIG_CRYPTO_XTS=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
diff --git a/arch/arm/configs/msmcortex_defconfig b/arch/arm/configs/msmcortex_defconfig
index 2400e9efbf3f..c193a0eb7de5 100644
--- a/arch/arm/configs/msmcortex_defconfig
+++ b/arch/arm/configs/msmcortex_defconfig
@@ -670,7 +670,6 @@ CONFIG_CRYPTO_CTR=y
CONFIG_CRYPTO_XCBC=y
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_TWOFISH=y
-CONFIG_FIPS_ENABLE=y
CONFIG_CRYPTO_DEV_QCRYPTO=y
CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
CONFIG_CRYPTO_DEV_QCEDEV=y
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index c5a51e79e74f..1a5fe8f4797c 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -251,7 +251,7 @@ extern int __put_user_8(void *, unsigned long long);
({ \
unsigned long __limit = current_thread_info()->addr_limit - 1; \
const typeof(*(p)) __user *__tmp_p = (p); \
- register const typeof(*(p)) __r2 asm("r2") = (x); \
+ register typeof(*(p)) __r2 asm("r2") = (x); \
register const typeof(*(p)) __user *__p asm("r0") = __tmp_p; \
register unsigned long __l asm("r1") = __limit; \
register int __e asm("r0"); \
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 70ccd1ea5ba1..70b4254674a2 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -841,19 +841,35 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
pmd = stage2_get_pmd(kvm, cache, addr);
VM_BUG_ON(!pmd);
- /*
- * Mapping in huge pages should only happen through a fault. If a
- * page is merged into a transparent huge page, the individual
- * subpages of that huge page should be unmapped through MMU
- * notifiers before we get here.
- *
- * Merging of CompoundPages is not supported; they should become
- * splitting first, unmapped, merged, and mapped back in on-demand.
- */
- VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
-
old_pmd = *pmd;
if (pmd_present(old_pmd)) {
+ /*
+ * Multiple vcpus faulting on the same PMD entry, can
+ * lead to them sequentially updating the PMD with the
+ * same value. Following the break-before-make
+ * (pmd_clear() followed by tlb_flush()) process can
+ * hinder forward progress due to refaults generated
+ * on missing translations.
+ *
+ * Skip updating the page table if the entry is
+ * unchanged.
+ */
+ if (pmd_val(old_pmd) == pmd_val(*new_pmd))
+ return 0;
+
+ /*
+ * Mapping in huge pages should only happen through a
+ * fault. If a page is merged into a transparent huge
+ * page, the individual subpages of that huge page
+ * should be unmapped through MMU notifiers before we
+ * get here.
+ *
+ * Merging of CompoundPages is not supported; they
+ * should become splitting first, unmapped, merged,
+ * and mapped back in on-demand.
+ */
+ VM_BUG_ON(pmd_pfn(old_pmd) != pmd_pfn(*new_pmd));
+
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
} else {
@@ -898,6 +914,10 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
/* Create 2nd stage page table mapping - Level 3 */
old_pte = *pte;
if (pte_present(old_pte)) {
+ /* Skip page table update if there is no change */
+ if (pte_val(old_pte) == pte_val(*new_pte))
+ return 0;
+
kvm_set_pte(pte, __pte(0));
kvm_tlb_flush_vmid_ipa(kvm, addr);
} else {
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 0eecd83c624e..d7f382856c42 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -160,7 +160,7 @@ static int pxa_irq_suspend(void)
{
int i;
- for (i = 0; i < pxa_internal_irq_nr / 32; i++) {
+ for (i = 0; i < DIV_ROUND_UP(pxa_internal_irq_nr, 32); i++) {
void __iomem *base = irq_base(i);
saved_icmr[i] = __raw_readl(base + ICMR);
@@ -179,7 +179,7 @@ static void pxa_irq_resume(void)
{
int i;
- for (i = 0; i < pxa_internal_irq_nr / 32; i++) {
+ for (i = 0; i < DIV_ROUND_UP(pxa_internal_irq_nr, 32); i++) {
void __iomem *base = irq_base(i);
__raw_writel(saved_icmr[i], base + ICMR);
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 36f03792bc01..54605542196e 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -85,6 +85,7 @@ config ARM64
select SPARSE_IRQ
select SYSCTL_EXCEPTION_TRACE
select HAVE_CONTEXT_TRACKING
+ select THREAD_INFO_IN_TASK
select MSM_JTAGV8 if CORESIGHT_ETMV4
help
ARM 64-bit (AArch64) Linux support.
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index 3106c09e7ebd..e3cec69b09f4 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -250,6 +250,7 @@ CONFIG_TUSB320_TYPE_C=y
CONFIG_FUSB301_TYPE_C=y
CONFIG_PTN5150_TYPE_C=y
CONFIG_TI_DRV2667=y
+CONFIG_FORCE_FAST_CHARGE=y
CONFIG_EEPROM_AT24=y
CONFIG_DTS_EAGLE=y
CONFIG_SCSI=y
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 000000000000..2e61d21294ba
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,27 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include
+
+#include
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+struct task_struct;
+
+static __always_inline struct task_struct *get_current(void)
+{
+ return (struct task_struct *)read_sysreg(sp_el0);
+}
+#define current get_current()
+#else
+#include
+#define get_current() (current_thread_info()->task)
+#define current get_current()
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index c78ede618c48..c6dec25b1724 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -56,6 +56,9 @@ asmlinkage void secondary_start_kernel(void);
*/
struct secondary_data {
void *stack;
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ struct task_struct *task;
+#endif
};
extern struct secondary_data secondary_data;
extern void secondary_entry(void);
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 7193434e165d..756cbf10d5ab 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -46,15 +46,26 @@ typedef unsigned long mm_segment_t;
struct thread_info {
unsigned long flags; /* low level flags */
mm_segment_t addr_limit; /* address limit */
+#ifndef CONFIG_THREAD_INFO_IN_TASK
struct task_struct *task; /* main task structure */
+#endif
struct exec_domain *exec_domain; /* execution domain */
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
u64 ttbr0; /* saved TTBR0_EL1 */
#endif
int preempt_count; /* 0 => preemptable, <0 => bug */
+#ifndef CONFIG_THREAD_INFO_IN_TASK
int cpu; /* cpu */
+#endif
};
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+}
+#else
#define INIT_THREAD_INFO(tsk) \
{ \
.task = &tsk, \
@@ -65,7 +76,6 @@ struct thread_info {
}
#define init_thread_info (init_thread_union.thread_info)
-#define init_stack (init_thread_union.stack)
/*
* how to get the current stack pointer from C
@@ -88,6 +98,9 @@ static inline struct thread_info *current_thread_info(void)
return (struct thread_info *)sp_el0;
}
+#endif
+
+#define init_stack (init_thread_union.stack)
#define thread_saved_pc(tsk) \
((unsigned long)(tsk->thread.cpu_context.pc))
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index a865573461e1..1e5c7d0430ea 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -34,12 +34,17 @@ int main(void)
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
BLANK();
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ DEFINE(TSK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
+ DEFINE(TSK_TI_PREEMPT, offsetof(struct task_struct, thread_info.preempt_count));
+ DEFINE(TSK_TI_ADDR_LIMIT, offsetof(struct task_struct, thread_info.addr_limit));
+ DEFINE(TSK_STACK, offsetof(struct task_struct, stack));
+#else
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
- DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
- DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+#endif
#ifdef CONFIG_ARM64_SW_TTBR0_PAN
DEFINE(TSK_TI_TTBR0, offsetof(struct thread_info, ttbr0));
#endif
@@ -113,6 +118,11 @@ int main(void)
DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ DEFINE(CPU_BOOT_STACK, offsetof(struct secondary_data, stack));
+ DEFINE(CPU_BOOT_TASK, offsetof(struct secondary_data, task));
+ BLANK();
+#endif
#ifdef CONFIG_KVM_ARM_HOST
DEFINE(VCPU_CONTEXT, offsetof(struct kvm_vcpu, arch.ctxt));
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 709f8cf0af8e..07403f503818 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -116,18 +116,31 @@ alternative_else_nop_endif
.if \el == 0
mrs x21, sp_el0
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr_this_cpu tsk, __entry_task, x20 // Ensure MDSCR_EL1.SS is clear,
+ ldr x19, [tsk, #TSK_TI_FLAGS] // since we can unmask debug
+#else
mov tsk, sp
and tsk, tsk, #~(THREAD_SIZE - 1) // Ensure MDSCR_EL1.SS is clear,
ldr x19, [tsk, #TI_FLAGS] // since we can unmask debug
+#endif
disable_step_tsk x19, x20 // exceptions when scheduling.
.else
add x21, sp, #S_FRAME_SIZE
get_thread_info tsk
/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x20, [tsk, #TSK_TI_ADDR_LIMIT]
+#else
ldr x20, [tsk, #TI_ADDR_LIMIT]
+#endif
str x20, [sp, #S_ORIG_ADDR_LIMIT]
mov x20, #TASK_SIZE_64
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
+#else
str x20, [tsk, #TI_ADDR_LIMIT]
+#endif
ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
.endif /* \el == 0 */
mrs x22, elr_el1
@@ -189,7 +202,11 @@ alternative_else_nop_endif
.if \el != 0
/* Restore the task's original addr_limit. */
ldr x20, [sp, #S_ORIG_ADDR_LIMIT]
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ str x20, [tsk, #TSK_TI_ADDR_LIMIT]
+#else
str x20, [tsk, #TI_ADDR_LIMIT]
+#endif
/* No need to restore UAO, it will be restored from SPSR_EL1 */
.endif
@@ -487,9 +504,17 @@ el1_irq:
#ifdef CONFIG_PREEMPT
get_thread_info tsk
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr w24, [tsk, #TSK_TI_PREEMPT] // get preempt count
+#else
ldr w24, [tsk, #TI_PREEMPT] // get preempt count
+#endif
cbnz w24, 1f // preempt count != 0
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get flags
+#else
ldr x0, [tsk, #TI_FLAGS] // get flags
+#endif
tbz x0, #TIF_NEED_RESCHED, 1f // needs rescheduling?
bl el1_preempt
1:
@@ -504,7 +529,11 @@ ENDPROC(el1_irq)
el1_preempt:
mov x24, lr
1: bl preempt_schedule_irq // irq en/disable is done inside
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x0, [tsk, #TSK_TI_FLAGS] // get new tasks TI_FLAGS
+#else
ldr x0, [tsk, #TI_FLAGS] // get new tasks TI_FLAGS
+#endif
tbnz x0, #TIF_NEED_RESCHED, 1b // needs rescheduling?
ret x24
#endif
@@ -771,8 +800,12 @@ ENTRY(cpu_switch_to)
mov v15.16b, v15.16b
#endif
mov sp, x9
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ msr sp_el0, x1
+#else
and x9, x9, #~(THREAD_SIZE - 1)
msr sp_el0, x9
+#endif
ret
ENDPROC(cpu_switch_to)
@@ -783,7 +816,11 @@ ENDPROC(cpu_switch_to)
ret_fast_syscall:
disable_irq // disable interrupts
str x0, [sp, #S_X0] // returned x0
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x1, [tsk, #TSK_TI_FLAGS] // re-check for syscall tracing
+#else
ldr x1, [tsk, #TI_FLAGS] // re-check for syscall tracing
+#endif
and x2, x1, #_TIF_SYSCALL_WORK
cbnz x2, ret_fast_syscall_trace
and x2, x1, #_TIF_WORK_MASK
@@ -815,7 +852,11 @@ work_resched:
*/
ret_to_user:
disable_irq // disable interrupts
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x1, [tsk, #TSK_TI_FLAGS]
+#else
ldr x1, [tsk, #TI_FLAGS]
+#endif
and x2, x1, #_TIF_WORK_MASK
cbnz x2, work_pending
enable_step_tsk x1, x2
@@ -848,7 +889,11 @@ el0_svc_naked: // compat entry point
enable_dbg_and_irq
ct_user_exit 1
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ ldr x16, [tsk, #TSK_TI_FLAGS] // check for syscall hooks
+#else
ldr x16, [tsk, #TI_FLAGS] // check for syscall hooks
+#endif
tst x16, #_TIF_SYSCALL_WORK
b.ne __sys_trace
cmp scno, sc_nr // check upper syscall limit
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 517c821955b6..e34584fd690d 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -456,10 +456,18 @@ __mmap_switched:
bl __pi_memset
dsb ishst // Make zero page visible to PTW
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ adrp x4, init_thread_union
+ add sp, x4, #THREAD_SIZE
+ adr_l x5, init_task
+ msr sp_el0, x5 // Save thread_info
+#else
adr_l sp, initial_sp, x4
mov x4, sp
and x4, x4, #~(THREAD_SIZE - 1)
msr sp_el0, x4 // Save thread_info
+#endif
+
str_l x21, __fdt_pointer, x5 // Save FDT pointer
str_l x24, memstart_addr, x6 // Save PHYS_OFFSET
mov x29, #0
@@ -642,10 +650,18 @@ ENTRY(secondary_startup)
ENDPROC(secondary_startup)
ENTRY(__secondary_switched)
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ adr_l x0, secondary_data
+ ldr x1, [x0, #CPU_BOOT_STACK] // get secondary_data.stack
+ mov sp, x1
+ ldr x2, [x0, #CPU_BOOT_TASK]
+ msr sp_el0, x2
+#else
ldr x0, [x21] // get secondary_data.stack
mov sp, x0
and x0, x0, #~(THREAD_SIZE - 1)
msr sp_el0, x0 // save thread_info
+#endif
mov x29, #0
b secondary_start_kernel
ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index e21fd6559b68..4db258a02254 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -44,6 +44,9 @@
#include
#include
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+#include
+#endif
#include
#include
#include
@@ -391,6 +394,22 @@ static void uao_thread_switch(struct task_struct *next)
}
}
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+/*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ *
+ * This is *only* for exception entry from EL0, and is not valid until we
+ * __switch_to() a user task.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task);
+
+static void entry_task_switch(struct task_struct *next)
+{
+ __this_cpu_write(__entry_task, next);
+}
+#endif
+
/*
* Thread switching.
*/
@@ -403,6 +422,9 @@ struct task_struct *__switch_to(struct task_struct *prev,
tls_thread_switch(next);
hw_breakpoint_thread_switch(next);
contextidr_thread_switch(next);
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ entry_task_switch(next);
+#endif
uao_thread_switch(next);
/*
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index 5f80881df662..61cca6eb99ec 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -97,6 +97,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
* We need to tell the secondary core where to find its stack and the
* page tables.
*/
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ secondary_data.task = idle;
+#endif
secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -120,6 +123,9 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
}
+#ifdef CONFIG_THREAD_INFO_IN_TASK
+ secondary_data.task = NULL;
+#endif
secondary_data.stack = NULL;
return ret;
@@ -134,7 +140,7 @@ static void smp_store_cpu_info(unsigned int cpuid)
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
-asmlinkage void secondary_start_kernel(void)
+asmlinkage notrace void secondary_start_kernel(void)
{
struct mm_struct *mm = &init_mm;
unsigned int cpu = smp_processor_id();
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d2de3ccb72d0..f23887c11664 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -114,11 +114,13 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
}
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
-#define PFN_MASK ((1UL << (64 - PAGE_SHIFT)) - 1)
-
int pfn_valid(unsigned long pfn)
{
- return (pfn & PFN_MASK) == pfn && memblock_is_memory(pfn << PAGE_SHIFT);
+ phys_addr_t addr = pfn << PAGE_SHIFT;
+
+ if ((addr >> PAGE_SHIFT) != pfn)
+ return 0;
+ return memblock_is_memory(addr);
}
EXPORT_SYMBOL(pfn_valid);
#endif
diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
index f9924fbcfe42..456e3f75ef3b 100644
--- a/arch/m68k/include/asm/mcf_pgalloc.h
+++ b/arch/m68k/include/asm/mcf_pgalloc.h
@@ -43,6 +43,7 @@ extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
unsigned long address)
{
+ pgtable_page_dtor(page);
__free_page(page);
}
@@ -73,8 +74,9 @@ static inline struct page *pte_alloc_one(struct mm_struct *mm,
return page;
}
-extern inline void pte_free(struct mm_struct *mm, struct page *page)
+static inline void pte_free(struct mm_struct *mm, struct page *page)
{
+ pgtable_page_dtor(page);
__free_page(page);
}
diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile
index 8e211cc28dac..e0f2afb98098 100644
--- a/arch/microblaze/boot/Makefile
+++ b/arch/microblaze/boot/Makefile
@@ -21,18 +21,20 @@ $(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
quiet_cmd_cp = CP $< $@$2
cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
-quiet_cmd_strip = STRIP $@
+quiet_cmd_strip = STRIP $< $@$2
cmd_strip = $(STRIP) -K microblaze_start -K _end -K __log_buf \
- -K _fdt_start vmlinux -o $@
+ -K _fdt_start $< -o $@$2
UIMAGE_LOADADDR = $(CONFIG_KERNEL_BASE_ADDR)
+UIMAGE_IN = $@
+UIMAGE_OUT = $@.ub
$(obj)/simpleImage.%: vmlinux FORCE
$(call if_changed,cp,.unstrip)
$(call if_changed,objcopy)
$(call if_changed,uimage)
- $(call if_changed,strip)
- @echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
+ $(call if_changed,strip,.strip)
+ @echo 'Kernel: $(UIMAGE_OUT) is ready' ' (#'`cat .version`')'
clean-files += simpleImage.*.unstrip linux.bin.ub
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 706bab38479d..c00585d915bc 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -269,12 +269,6 @@ static int __init bcm47xx_cpu_fixes(void)
*/
if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
cpu_wait = NULL;
-
- /*
- * BCM47XX Erratum "R10: PCIe Transactions Periodically Fail"
- * Enable ExternalSync for sync instruction to take effect
- */
- set_c0_config7(MIPS_CONF7_ES);
break;
#endif
}
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 9655d0a47e8c..f38ca68285ea 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -667,8 +667,6 @@
#define MIPS_CONF7_WII (_ULCAST_(1) << 31)
#define MIPS_CONF7_RPS (_ULCAST_(1) << 2)
-/* ExternalSync */
-#define MIPS_CONF7_ES (_ULCAST_(1) << 8)
#define MIPS_CONF7_IAR (_ULCAST_(1) << 10)
#define MIPS_CONF7_AR (_ULCAST_(1) << 16)
@@ -1865,7 +1863,6 @@ __BUILD_SET_C0(status)
__BUILD_SET_C0(cause)
__BUILD_SET_C0(config)
__BUILD_SET_C0(config5)
-__BUILD_SET_C0(config7)
__BUILD_SET_C0(intcontrol)
__BUILD_SET_C0(intctl)
__BUILD_SET_C0(srsmap)
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 578ece1e4a99..351a5a9e4f52 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -143,7 +143,7 @@ struct mips_fpu_struct {
#define NUM_DSP_REGS 6
-typedef __u32 dspreg_t;
+typedef unsigned long dspreg_t;
struct mips_dsp_state {
dspreg_t dspr[NUM_DSP_REGS];
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index c1bd750494c1..0b16f07ada9f 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -751,7 +751,7 @@ long arch_ptrace(struct task_struct *child, long request,
goto out;
}
dregs = __get_dsp_regs(child);
- tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ tmp = dregs[addr - DSP_BASE];
break;
}
case DSP_CONTROL:
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index d95117e71f69..286ec2d24d47 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -140,7 +140,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
goto out;
}
dregs = __get_dsp_regs(child);
- tmp = (unsigned long) (dregs[addr - DSP_BASE]);
+ tmp = dregs[addr - DSP_BASE];
break;
}
case DSP_CONTROL:
diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
index 493e72f64b35..5768ec3c1781 100644
--- a/arch/powerpc/include/asm/fadump.h
+++ b/arch/powerpc/include/asm/fadump.h
@@ -194,9 +194,6 @@ struct fadump_crash_info_header {
struct cpumask cpu_online_mask;
};
-/* Crash memory ranges */
-#define INIT_CRASHMEM_RANGES (INIT_MEMBLOCK_REGIONS + 2)
-
struct fad_crash_memory_ranges {
unsigned long long base;
unsigned long long size;
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 791d4c3329c3..c3c835290131 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -35,6 +35,7 @@
#include
#include
#include
+#include
#include
#include
@@ -48,8 +49,10 @@ static struct fadump_mem_struct fdm;
static const struct fadump_mem_struct *fdm_active;
static DEFINE_MUTEX(fadump_mutex);
-struct fad_crash_memory_ranges crash_memory_ranges[INIT_CRASHMEM_RANGES];
+struct fad_crash_memory_ranges *crash_memory_ranges;
+int crash_memory_ranges_size;
int crash_mem_ranges;
+int max_crash_mem_ranges;
/* Scan the Firmware Assisted dump configuration details. */
int __init early_init_dt_scan_fw_dump(unsigned long node,
@@ -726,38 +729,88 @@ static int __init process_fadump(const struct fadump_mem_struct *fdm_active)
return 0;
}
-static inline void fadump_add_crash_memory(unsigned long long base,
- unsigned long long end)
+static void free_crash_memory_ranges(void)
+{
+ kfree(crash_memory_ranges);
+ crash_memory_ranges = NULL;
+ crash_memory_ranges_size = 0;
+ max_crash_mem_ranges = 0;
+}
+
+/*
+ * Allocate or reallocate crash memory ranges array in incremental units
+ * of PAGE_SIZE.
+ */
+static int allocate_crash_memory_ranges(void)
+{
+ struct fad_crash_memory_ranges *new_array;
+ u64 new_size;
+
+ new_size = crash_memory_ranges_size + PAGE_SIZE;
+ pr_debug("Allocating %llu bytes of memory for crash memory ranges\n",
+ new_size);
+
+ new_array = krealloc(crash_memory_ranges, new_size, GFP_KERNEL);
+ if (new_array == NULL) {
+ pr_err("Insufficient memory for setting up crash memory ranges\n");
+ free_crash_memory_ranges();
+ return -ENOMEM;
+ }
+
+ crash_memory_ranges = new_array;
+ crash_memory_ranges_size = new_size;
+ max_crash_mem_ranges = (new_size /
+ sizeof(struct fad_crash_memory_ranges));
+ return 0;
+}
+
+static inline int fadump_add_crash_memory(unsigned long long base,
+ unsigned long long end)
{
if (base == end)
- return;
+ return 0;
+
+ if (crash_mem_ranges == max_crash_mem_ranges) {
+ int ret;
+
+ ret = allocate_crash_memory_ranges();
+ if (ret)
+ return ret;
+ }
pr_debug("crash_memory_range[%d] [%#016llx-%#016llx], %#llx bytes\n",
crash_mem_ranges, base, end - 1, (end - base));
crash_memory_ranges[crash_mem_ranges].base = base;
crash_memory_ranges[crash_mem_ranges].size = end - base;
crash_mem_ranges++;
+ return 0;
}
-static void fadump_exclude_reserved_area(unsigned long long start,
+static int fadump_exclude_reserved_area(unsigned long long start,
unsigned long long end)
{
unsigned long long ra_start, ra_end;
+ int ret = 0;
ra_start = fw_dump.reserve_dump_area_start;
ra_end = ra_start + fw_dump.reserve_dump_area_size;
if ((ra_start < end) && (ra_end > start)) {
if ((start < ra_start) && (end > ra_end)) {
- fadump_add_crash_memory(start, ra_start);
- fadump_add_crash_memory(ra_end, end);
+ ret = fadump_add_crash_memory(start, ra_start);
+ if (ret)
+ return ret;
+
+ ret = fadump_add_crash_memory(ra_end, end);
} else if (start < ra_start) {
- fadump_add_crash_memory(start, ra_start);
+ ret = fadump_add_crash_memory(start, ra_start);
} else if (ra_end < end) {
- fadump_add_crash_memory(ra_end, end);
+ ret = fadump_add_crash_memory(ra_end, end);
}
} else
- fadump_add_crash_memory(start, end);
+ ret = fadump_add_crash_memory(start, end);
+
+ return ret;
}
static int fadump_init_elfcore_header(char *bufp)
@@ -793,10 +846,11 @@ static int fadump_init_elfcore_header(char *bufp)
* Traverse through memblock structure and setup crash memory ranges. These
* ranges will be used create PT_LOAD program headers in elfcore header.
*/
-static void fadump_setup_crash_memory_ranges(void)
+static int fadump_setup_crash_memory_ranges(void)
{
struct memblock_region *reg;
unsigned long long start, end;
+ int ret;
pr_debug("Setup crash memory ranges.\n");
crash_mem_ranges = 0;
@@ -807,7 +861,9 @@ static void fadump_setup_crash_memory_ranges(void)
* specified during fadump registration. We need to create a separate
* program header for this chunk with the correct offset.
*/
- fadump_add_crash_memory(RMA_START, fw_dump.boot_memory_size);
+ ret = fadump_add_crash_memory(RMA_START, fw_dump.boot_memory_size);
+ if (ret)
+ return ret;
for_each_memblock(memory, reg) {
start = (unsigned long long)reg->base;
@@ -816,8 +872,12 @@ static void fadump_setup_crash_memory_ranges(void)
start = fw_dump.boot_memory_size;
/* add this range excluding the reserved dump area. */
- fadump_exclude_reserved_area(start, end);
+ ret = fadump_exclude_reserved_area(start, end);
+ if (ret)
+ return ret;
}
+
+ return 0;
}
/*
@@ -941,6 +1001,7 @@ static void register_fadump(void)
{
unsigned long addr;
void *vaddr;
+ int ret;
/*
* If no memory is reserved then we can not register for firmware-
@@ -949,7 +1010,9 @@ static void register_fadump(void)
if (!fw_dump.reserve_dump_area_size)
return;
- fadump_setup_crash_memory_ranges();
+ ret = fadump_setup_crash_memory_ranges();
+ if (ret)
+ return ret;
addr = be64_to_cpu(fdm.rmr_region.destination_address) + be64_to_cpu(fdm.rmr_region.source_len);
/* Initialize fadump crash info header. */
@@ -1028,6 +1091,7 @@ void fadump_cleanup(void)
} else if (fw_dump.dump_registered) {
/* Un-register Firmware-assisted dump if it was registered. */
fadump_unregister_dump(&fdm);
+ free_crash_memory_ranges();
}
}
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index fafff8dbd5d9..3c957548f336 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -722,7 +722,7 @@ start_here:
tovirt(r6,r6)
lis r5, abatron_pteptrs@h
ori r5, r5, abatron_pteptrs@l
- stw r5, 0xf0(r0) /* Must match your Abatron config file */
+ stw r5, 0xf0(0) /* Must match your Abatron config file */
tophys(r5,r5)
stw r6, 0(r5)
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 432459c817fa..28724443d1a6 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -11,6 +11,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c
index f803f4b8ab6f..8608e358217f 100644
--- a/arch/powerpc/platforms/chrp/time.c
+++ b/arch/powerpc/platforms/chrp/time.c
@@ -27,6 +27,8 @@
#include
#include
+#include
+
extern spinlock_t rtc_lock;
#define NVRAM_AS0 0x74
@@ -62,7 +64,7 @@ long __init chrp_time_init(void)
return 0;
}
-int chrp_cmos_clock_read(int addr)
+static int chrp_cmos_clock_read(int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
@@ -70,7 +72,7 @@ int chrp_cmos_clock_read(int addr)
return (inb(nvram_data));
}
-void chrp_cmos_clock_write(unsigned long val, int addr)
+static void chrp_cmos_clock_write(unsigned long val, int addr)
{
if (nvram_as1 != 0)
outb(addr>>8, nvram_as1);
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index c269caee58f9..f44b382449ca 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -35,6 +35,8 @@
*/
#define HW_BROADWAY_ICR 0x00
#define HW_BROADWAY_IMR 0x04
+#define HW_STARLET_ICR 0x08
+#define HW_STARLET_IMR 0x0c
/*
@@ -74,6 +76,9 @@ static void hlwd_pic_unmask(struct irq_data *d)
void __iomem *io_base = irq_data_get_irq_chip_data(d);
setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
+
+ /* Make sure the ARM (aka. Starlet) doesn't handle this interrupt. */
+ clrbits32(io_base + HW_STARLET_IMR, 1 << irq);
}
diff --git a/arch/powerpc/platforms/powermac/bootx_init.c b/arch/powerpc/platforms/powermac/bootx_init.c
index 3e91ef538114..9adc9eaaf365 100644
--- a/arch/powerpc/platforms/powermac/bootx_init.c
+++ b/arch/powerpc/platforms/powermac/bootx_init.c
@@ -467,7 +467,7 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
boot_infos_t *bi = (boot_infos_t *) r4;
unsigned long hdr;
unsigned long space;
- unsigned long ptr, x;
+ unsigned long ptr;
char *model;
unsigned long offset = reloc_offset();
@@ -561,6 +561,8 @@ void __init bootx_init(unsigned long r3, unsigned long r4)
* MMU switched OFF, so this should not be useful anymore.
*/
if (bi->version < 4) {
+ unsigned long x __maybe_unused;
+
bootx_printf("Touching pages...\n");
/*
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index b127a29ac526..49148e2e13a8 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -359,6 +359,7 @@ static int pmac_late_init(void)
}
machine_late_initcall(powermac, pmac_late_init);
+void note_bootable_part(dev_t dev, int part, int goodness);
/*
* This is __init_refok because we check for "initializing" before
* touching any of the __init sensitive things and "initializing"
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index d263f7bc80fc..c85c76dc4400 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -298,7 +298,7 @@ static struct rtas_error_log *fwnmi_get_errinfo(struct pt_regs *regs)
}
savep = __va(regs->gpr[3]);
- regs->gpr[3] = savep[0]; /* restore original r3 */
+ regs->gpr[3] = be64_to_cpu(savep[0]); /* restore original r3 */
/* If it isn't an extended log we can use the per cpu 64bit buffer */
h = (struct rtas_error_log *)&savep[1];
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h
index cb700d54bd83..0a1ca50298e8 100644
--- a/arch/s390/include/asm/cpu_mf.h
+++ b/arch/s390/include/asm/cpu_mf.h
@@ -118,7 +118,7 @@ struct hws_basic_entry {
struct hws_diag_entry {
unsigned int def:16; /* 0-15 Data Entry Format */
- unsigned int R:14; /* 16-19 and 20-30 reserved */
+ unsigned int R:15; /* 16-19 and 20-30 reserved */
unsigned int I:1; /* 31 entry valid or invalid */
u8 data[]; /* Machine-dependent sample data */
} __packed;
@@ -134,7 +134,9 @@ struct hws_trailer_entry {
unsigned int f:1; /* 0 - Block Full Indicator */
unsigned int a:1; /* 1 - Alert request control */
unsigned int t:1; /* 2 - Timestamp format */
- unsigned long long:61; /* 3 - 63: Reserved */
+ unsigned int :29; /* 3 - 31: Reserved */
+ unsigned int bsdes:16; /* 32-47: size of basic SDE */
+ unsigned int dsdes:16; /* 48-63: size of diagnostic SDE */
};
unsigned long long flags; /* 0 - 63: All indicators */
};
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h
index 06f3034605a1..33894abf03df 100644
--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -271,7 +271,6 @@ struct qdio_outbuf_state {
void *user;
};
-#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00
#define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01
#define CHSC_AC1_INITIATE_INPUTQ 0x80
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index fbe8f2cf9245..eecd61bdc0d9 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -494,6 +494,8 @@ static inline int do_exception(struct pt_regs *regs, int access)
/* No reason to continue if interrupted by SIGKILL. */
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
fault = VM_FAULT_SIGNAL;
+ if (flags & FAULT_FLAG_RETRY_NOWAIT)
+ goto out_up;
goto out;
}
if (unlikely(fault & VM_FAULT_ERROR))
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index b6b76785f879..f5101a890b57 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -397,6 +397,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
hwirq = 0;
list_for_each_entry(msi, &pdev->msi_list, list) {
rc = -EIO;
+ if (hwirq >= msi_vecs)
+ break;
irq = irq_alloc_desc(0); /* Alloc irq on node 0 */
if (irq < 0)
goto out_msi;
diff --git a/arch/sparc/kernel/sys_sparc_32.c b/arch/sparc/kernel/sys_sparc_32.c
index 646988d4c1a3..740f43b9b541 100644
--- a/arch/sparc/kernel/sys_sparc_32.c
+++ b/arch/sparc/kernel/sys_sparc_32.c
@@ -201,23 +201,27 @@ SYSCALL_DEFINE5(rt_sigaction, int, sig,
asmlinkage long sys_getdomainname(char __user *name, int len)
{
- int nlen, err;
-
+ int nlen, err;
+ char tmp[__NEW_UTS_LEN + 1];
+
if (len < 0)
return -EINVAL;
- down_read(&uts_sem);
-
+ down_read(&uts_sem);
+
nlen = strlen(utsname()->domainname) + 1;
err = -EINVAL;
if (nlen > len)
- goto out;
+ goto out_unlock;
+ memcpy(tmp, utsname()->domainname, nlen);
- err = -EFAULT;
- if (!copy_to_user(name, utsname()->domainname, nlen))
- err = 0;
+ up_read(&uts_sem);
-out:
+ if (copy_to_user(name, tmp, nlen))
+ return -EFAULT;
+ return 0;
+
+out_unlock:
up_read(&uts_sem);
return err;
}
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 98a5cf313d39..7301fa2091bc 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -524,23 +524,27 @@ extern void check_pending(int signum);
SYSCALL_DEFINE2(getdomainname, char __user *, name, int, len)
{
- int nlen, err;
+ int nlen, err;
+ char tmp[__NEW_UTS_LEN + 1];
if (len < 0)
return -EINVAL;
- down_read(&uts_sem);
-
+ down_read(&uts_sem);
+
nlen = strlen(utsname()->domainname) + 1;
err = -EINVAL;
if (nlen > len)
- goto out;
+ goto out_unlock;
+ memcpy(tmp, utsname()->domainname, nlen);
+
+ up_read(&uts_sem);
- err = -EFAULT;
- if (!copy_to_user(name, utsname()->domainname, nlen))
- err = 0;
+ if (copy_to_user(name, tmp, nlen))
+ return -EFAULT;
+ return 0;
-out:
+out_unlock:
up_read(&uts_sem);
return err;
}
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index d5d3af159bec..291cb502d141 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -2240,9 +2240,6 @@ static ssize_t store_int_with_restart(struct device *s,
if (check_interval == old_check_interval)
return ret;
- if (check_interval < 1)
- check_interval = 1;
-
mutex_lock(&mce_sysfs_mutex);
mce_restart();
mutex_unlock(&mce_sysfs_mutex);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index e98f68cfea02..cae9a3b6446b 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -175,7 +175,7 @@ void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *e
u64 prev_count, new_count, delta;
int shift;
- if (event->hw.idx >= UNCORE_PMC_IDX_FIXED)
+ if (event->hw.idx == UNCORE_PMC_IDX_FIXED)
shift = 64 - uncore_fixed_ctr_bits(box);
else
shift = 64 - uncore_perf_ctr_bits(box);
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
index 2749965afed0..83cadc2605a7 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
@@ -240,7 +240,7 @@ static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct p
{
struct hw_perf_event *hwc = &event->hw;
- if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
+ if (hwc->idx == UNCORE_PMC_IDX_FIXED)
wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 51947348fcb9..323d122267b2 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -365,7 +365,6 @@ int __copy_instruction(u8 *dest, u8 *src)
newdisp = (u8 *) src + (s64) insn.displacement.value - (u8 *) dest;
if ((s64) (s32) newdisp != newdisp) {
pr_err("Kprobes error: new displacement does not fit into s32 (%llx)\n", newdisp);
- pr_err("\tSrc: %p, Dest: %p, old disp: %x\n", src, dest, insn.displacement.value);
return 0;
}
disp = (u8 *) dest + insn_offset_displacement(&insn);
@@ -568,8 +567,7 @@ static int reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
* Raise a BUG or we'll continue in an endless reentering loop
* and eventually a stack overflow.
*/
- printk(KERN_WARNING "Unrecoverable kprobe detected at %p.\n",
- p->addr);
+ pr_err("Unrecoverable kprobe detected.\n");
dump_kprobe(p);
BUG();
default:
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index f547f866e86c..ba48e77c8e9e 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -438,6 +438,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
return prev_p;
}
+EXPORT_SYMBOL_GPL(start_thread);
void set_personality_64bit(void)
{
diff --git a/block/blk-core.c b/block/blk-core.c
index 7d4cd21b123b..fb4160993001 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2966,7 +2966,7 @@ int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
blk_rq_init(NULL, rq);
__rq_for_each_bio(bio_src, rq_src) {
- bio = bio_clone_fast(bio_src, gfp_mask, bs);
+ bio = bio_clone_bioset(bio_src, gfp_mask, bs);
if (!bio)
goto free_and_out;
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 520729d898fe..5061d7ad33e4 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -72,11 +72,9 @@ static inline u8 *ablkcipher_get_spot(u8 *start, unsigned int len)
return max(start, end_page);
}
-static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk,
- unsigned int bsize)
+static inline void ablkcipher_done_slow(struct ablkcipher_walk *walk,
+ unsigned int n)
{
- unsigned int n = bsize;
-
for (;;) {
unsigned int len_this_page = scatterwalk_pagelen(&walk->out);
@@ -88,17 +86,13 @@ static inline unsigned int ablkcipher_done_slow(struct ablkcipher_walk *walk,
n -= len_this_page;
scatterwalk_start(&walk->out, scatterwalk_sg_next(walk->out.sg));
}
-
- return bsize;
}
-static inline unsigned int ablkcipher_done_fast(struct ablkcipher_walk *walk,
- unsigned int n)
+static inline void ablkcipher_done_fast(struct ablkcipher_walk *walk,
+ unsigned int n)
{
scatterwalk_advance(&walk->in, n);
scatterwalk_advance(&walk->out, n);
-
- return n;
}
static int ablkcipher_walk_next(struct ablkcipher_request *req,
@@ -108,39 +102,40 @@ int ablkcipher_walk_done(struct ablkcipher_request *req,
struct ablkcipher_walk *walk, int err)
{
struct crypto_tfm *tfm = req->base.tfm;
- unsigned int nbytes = 0;
+ unsigned int n; /* bytes processed */
+ bool more;
- if (likely(err >= 0)) {
- unsigned int n = walk->nbytes - err;
+ if (unlikely(err < 0))
+ goto finish;
- if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW)))
- n = ablkcipher_done_fast(walk, n);
- else if (WARN_ON(err)) {
- err = -EINVAL;
- goto err;
- } else
- n = ablkcipher_done_slow(walk, n);
+ n = walk->nbytes - err;
+ walk->total -= n;
+ more = (walk->total != 0);
- nbytes = walk->total - n;
- err = 0;
+ if (likely(!(walk->flags & ABLKCIPHER_WALK_SLOW))) {
+ ablkcipher_done_fast(walk, n);
+ } else {
+ if (WARN_ON(err)) {
+ /* unexpected case; didn't process all bytes */
+ err = -EINVAL;
+ goto finish;
+ }
+ ablkcipher_done_slow(walk, n);
}
- scatterwalk_done(&walk->in, 0, nbytes);
- scatterwalk_done(&walk->out, 1, nbytes);
-
-err:
- walk->total = nbytes;
- walk->nbytes = nbytes;
+ scatterwalk_done(&walk->in, 0, more);
+ scatterwalk_done(&walk->out, 1, more);
- if (nbytes) {
+ if (more) {
crypto_yield(req->base.flags);
return ablkcipher_walk_next(req, walk);
}
-
+ err = 0;
+finish:
+ walk->nbytes = 0;
if (walk->iv != req->info)
memcpy(req->info, walk->iv, tfm->crt_ablkcipher.ivsize);
kfree(walk->iv_buffer);
-
return err;
}
EXPORT_SYMBOL_GPL(ablkcipher_walk_done);
diff --git a/crypto/authenc.c b/crypto/authenc.c
index 78fb16cab13f..eb029ea72f98 100644
--- a/crypto/authenc.c
+++ b/crypto/authenc.c
@@ -112,6 +112,7 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key,
CRYPTO_TFM_RES_MASK);
out:
+ memzero_explicit(&keys, sizeof(keys));
return err;
badkey:
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index 024bff2344fc..c248a966aa5b 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -86,6 +86,7 @@ static int crypto_authenc_esn_setkey(struct crypto_aead *authenc_esn, const u8 *
CRYPTO_TFM_RES_MASK);
out:
+ memzero_explicit(&keys, sizeof(keys));
return err;
badkey:
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c
index f25799f351f7..5ebfdd0d4543 100644
--- a/crypto/blkcipher.c
+++ b/crypto/blkcipher.c
@@ -70,19 +70,18 @@ static inline u8 *blkcipher_get_spot(u8 *start, unsigned int len)
return max(start, end_page);
}
-static inline unsigned int blkcipher_done_slow(struct blkcipher_walk *walk,
- unsigned int bsize)
+static inline void blkcipher_done_slow(struct blkcipher_walk *walk,
+ unsigned int bsize)
{
u8 *addr;
addr = (u8 *)ALIGN((unsigned long)walk->buffer, walk->alignmask + 1);
addr = blkcipher_get_spot(addr, bsize);
scatterwalk_copychunks(addr, &walk->out, bsize, 1);
- return bsize;
}
-static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk,
- unsigned int n)
+static inline void blkcipher_done_fast(struct blkcipher_walk *walk,
+ unsigned int n)
{
if (walk->flags & BLKCIPHER_WALK_COPY) {
blkcipher_map_dst(walk);
@@ -96,49 +95,48 @@ static inline unsigned int blkcipher_done_fast(struct blkcipher_walk *walk,
scatterwalk_advance(&walk->in, n);
scatterwalk_advance(&walk->out, n);
-
- return n;
}
int blkcipher_walk_done(struct blkcipher_desc *desc,
struct blkcipher_walk *walk, int err)
{
- unsigned int nbytes = 0;
+ unsigned int n; /* bytes processed */
+ bool more;
- if (likely(err >= 0)) {
- unsigned int n = walk->nbytes - err;
+ if (unlikely(err < 0))
+ goto finish;
- if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW)))
- n = blkcipher_done_fast(walk, n);
- else if (WARN_ON(err)) {
- err = -EINVAL;
- goto err;
- } else
- n = blkcipher_done_slow(walk, n);
+ n = walk->nbytes - err;
+ walk->total -= n;
+ more = (walk->total != 0);
- nbytes = walk->total - n;
- err = 0;
+ if (likely(!(walk->flags & BLKCIPHER_WALK_SLOW))) {
+ blkcipher_done_fast(walk, n);
+ } else {
+ if (WARN_ON(err)) {
+ /* unexpected case; didn't process all bytes */
+ err = -EINVAL;
+ goto finish;
+ }
+ blkcipher_done_slow(walk, n);
}
- scatterwalk_done(&walk->in, 0, nbytes);
- scatterwalk_done(&walk->out, 1, nbytes);
-
-err:
- walk->total = nbytes;
- walk->nbytes = nbytes;
+ scatterwalk_done(&walk->in, 0, more);
+ scatterwalk_done(&walk->out, 1, more);
- if (nbytes) {
+ if (more) {
crypto_yield(desc->flags);
return blkcipher_walk_next(desc, walk);
}
-
+ err = 0;
+finish:
+ walk->nbytes = 0;
if (walk->iv != desc->info)
memcpy(desc->info, walk->iv, walk->ivsize);
if (walk->buffer != walk->page)
kfree(walk->buffer);
if (walk->page)
free_page((unsigned long)walk->page);
-
return err;
}
EXPORT_SYMBOL_GPL(blkcipher_walk_done);
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index c305d4112735..bd5f14ea528e 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -306,6 +306,14 @@ static void pcrypt_aead_exit_tfm(struct crypto_tfm *tfm)
crypto_free_aead(ctx->child);
}
+static void pcrypt_free(struct crypto_instance *inst)
+{
+ struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);
+
+ crypto_drop_spawn(&ctx->spawn);
+ kfree(inst);
+}
+
static struct crypto_instance *pcrypt_alloc_instance(struct crypto_alg *alg)
{
struct crypto_instance *inst;
@@ -375,6 +383,7 @@ static struct crypto_instance *pcrypt_alloc_aead(struct rtattr **tb,
inst->alg.cra_aead.encrypt = pcrypt_aead_encrypt;
inst->alg.cra_aead.decrypt = pcrypt_aead_decrypt;
inst->alg.cra_aead.givencrypt = pcrypt_aead_givencrypt;
+ inst->tmpl->free = pcrypt_free;
out_put_alg:
crypto_mod_put(alg);
@@ -397,14 +406,6 @@ static struct crypto_instance *pcrypt_alloc(struct rtattr **tb)
return ERR_PTR(-EINVAL);
}
-static void pcrypt_free(struct crypto_instance *inst)
-{
- struct pcrypt_instance_ctx *ctx = crypto_instance_ctx(inst);
-
- crypto_drop_spawn(&ctx->spawn);
- kfree(inst);
-}
-
static int pcrypt_cpumask_change_notify(struct notifier_block *self,
unsigned long val, void *data)
{
@@ -517,7 +518,6 @@ static void pcrypt_fini_padata(struct padata_pcrypt *pcrypt)
static struct crypto_template pcrypt_tmpl = {
.name = "pcrypt",
.alloc = pcrypt_alloc,
- .free = pcrypt_free,
.module = THIS_MODULE,
};
diff --git a/crypto/vmac.c b/crypto/vmac.c
index df76a816cfb2..bb2fc787d615 100644
--- a/crypto/vmac.c
+++ b/crypto/vmac.c
@@ -1,6 +1,10 @@
/*
- * Modified to interface to the Linux kernel
+ * VMAC: Message Authentication Code using Universal Hashing
+ *
+ * Reference: https://tools.ietf.org/html/draft-krovetz-vmac-01
+ *
* Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2018, Google Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -16,14 +20,15 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
-/* --------------------------------------------------------------------------
- * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai.
- * This implementation is herby placed in the public domain.
- * The authors offers no warranty. Use at your own risk.
- * Please send bug reports to the authors.
- * Last modified: 17 APR 08, 1700 PDT
- * ----------------------------------------------------------------------- */
+/*
+ * Derived from:
+ * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai.
+ * This implementation is herby placed in the public domain.
+ * The authors offers no warranty. Use at your own risk.
+ * Last modified: 17 APR 08, 1700 PDT
+ */
+#include
#include
#include
#include
@@ -31,9 +36,35 @@
#include
#include
#include
-#include
#include
+/*
+ * User definable settings.
+ */
+#define VMAC_TAG_LEN 64
+#define VMAC_KEY_SIZE 128/* Must be 128, 192 or 256 */
+#define VMAC_KEY_LEN (VMAC_KEY_SIZE/8)
+#define VMAC_NHBYTES 128/* Must 2^i for any 3 < i < 13 Standard = 128*/
+
+/* per-transform (per-key) context */
+struct vmac_tfm_ctx {
+ struct crypto_cipher *cipher;
+ u64 nhkey[(VMAC_NHBYTES/8)+2*(VMAC_TAG_LEN/64-1)];
+ u64 polykey[2*VMAC_TAG_LEN/64];
+ u64 l3key[2*VMAC_TAG_LEN/64];
+};
+
+/* per-request context */
+struct vmac_desc_ctx {
+ union {
+ u8 partial[VMAC_NHBYTES]; /* partial block */
+ __le64 partial_words[VMAC_NHBYTES / 8];
+ };
+ unsigned int partial_size; /* size of the partial block */
+ bool first_block_processed;
+ u64 polytmp[2*VMAC_TAG_LEN/64]; /* running total of L2-hash */
+};
+
/*
* Constants and masks
*/
@@ -318,13 +349,6 @@ static void poly_step_func(u64 *ahi, u64 *alo,
} while (0)
#endif
-static void vhash_abort(struct vmac_ctx *ctx)
-{
- ctx->polytmp[0] = ctx->polykey[0] ;
- ctx->polytmp[1] = ctx->polykey[1] ;
- ctx->first_block_processed = 0;
-}
-
static u64 l3hash(u64 p1, u64 p2, u64 k1, u64 k2, u64 len)
{
u64 rh, rl, t, z = 0;
@@ -364,280 +388,209 @@ static u64 l3hash(u64 p1, u64 p2, u64 k1, u64 k2, u64 len)
return rl;
}
-static void vhash_update(const unsigned char *m,
- unsigned int mbytes, /* Pos multiple of VMAC_NHBYTES */
- struct vmac_ctx *ctx)
+/* L1 and L2-hash one or more VMAC_NHBYTES-byte blocks */
+static void vhash_blocks(const struct vmac_tfm_ctx *tctx,
+ struct vmac_desc_ctx *dctx,
+ const __le64 *mptr, unsigned int blocks)
{
- u64 rh, rl, *mptr;
- const u64 *kptr = (u64 *)ctx->nhkey;
- int i;
- u64 ch, cl;
- u64 pkh = ctx->polykey[0];
- u64 pkl = ctx->polykey[1];
-
- if (!mbytes)
- return;
-
- BUG_ON(mbytes % VMAC_NHBYTES);
-
- mptr = (u64 *)m;
- i = mbytes / VMAC_NHBYTES; /* Must be non-zero */
-
- ch = ctx->polytmp[0];
- cl = ctx->polytmp[1];
-
- if (!ctx->first_block_processed) {
- ctx->first_block_processed = 1;
+ const u64 *kptr = tctx->nhkey;
+ const u64 pkh = tctx->polykey[0];
+ const u64 pkl = tctx->polykey[1];
+ u64 ch = dctx->polytmp[0];
+ u64 cl = dctx->polytmp[1];
+ u64 rh, rl;
+
+ if (!dctx->first_block_processed) {
+ dctx->first_block_processed = true;
nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl);
rh &= m62;
ADD128(ch, cl, rh, rl);
mptr += (VMAC_NHBYTES/sizeof(u64));
- i--;
+ blocks--;
}
- while (i--) {
+ while (blocks--) {
nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl);
rh &= m62;
poly_step(ch, cl, pkh, pkl, rh, rl);
mptr += (VMAC_NHBYTES/sizeof(u64));
}
- ctx->polytmp[0] = ch;
- ctx->polytmp[1] = cl;
+ dctx->polytmp[0] = ch;
+ dctx->polytmp[1] = cl;
}
-static u64 vhash(unsigned char m[], unsigned int mbytes,
- u64 *tagl, struct vmac_ctx *ctx)
+static int vmac_setkey(struct crypto_shash *tfm,
+ const u8 *key, unsigned int keylen)
{
- u64 rh, rl, *mptr;
- const u64 *kptr = (u64 *)ctx->nhkey;
- int i, remaining;
- u64 ch, cl;
- u64 pkh = ctx->polykey[0];
- u64 pkl = ctx->polykey[1];
-
- mptr = (u64 *)m;
- i = mbytes / VMAC_NHBYTES;
- remaining = mbytes % VMAC_NHBYTES;
-
- if (ctx->first_block_processed) {
- ch = ctx->polytmp[0];
- cl = ctx->polytmp[1];
- } else if (i) {
- nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, ch, cl);
- ch &= m62;
- ADD128(ch, cl, pkh, pkl);
- mptr += (VMAC_NHBYTES/sizeof(u64));
- i--;
- } else if (remaining) {
- nh_16(mptr, kptr, 2*((remaining+15)/16), ch, cl);
- ch &= m62;
- ADD128(ch, cl, pkh, pkl);
- mptr += (VMAC_NHBYTES/sizeof(u64));
- goto do_l3;
- } else {/* Empty String */
- ch = pkh; cl = pkl;
- goto do_l3;
- }
-
- while (i--) {
- nh_vmac_nhbytes(mptr, kptr, VMAC_NHBYTES/8, rh, rl);
- rh &= m62;
- poly_step(ch, cl, pkh, pkl, rh, rl);
- mptr += (VMAC_NHBYTES/sizeof(u64));
- }
- if (remaining) {
- nh_16(mptr, kptr, 2*((remaining+15)/16), rh, rl);
- rh &= m62;
- poly_step(ch, cl, pkh, pkl, rh, rl);
- }
-
-do_l3:
- vhash_abort(ctx);
- remaining *= 8;
- return l3hash(ch, cl, ctx->l3key[0], ctx->l3key[1], remaining);
-}
+ struct vmac_tfm_ctx *tctx = crypto_shash_ctx(tfm);
+ __be64 out[2];
+ u8 in[16] = { 0 };
+ unsigned int i;
+ int err;
-static u64 vmac(unsigned char m[], unsigned int mbytes,
- const unsigned char n[16], u64 *tagl,
- struct vmac_ctx_t *ctx)
-{
- u64 *in_n, *out_p;
- u64 p, h;
- int i;
-
- in_n = ctx->__vmac_ctx.cached_nonce;
- out_p = ctx->__vmac_ctx.cached_aes;
-
- i = n[15] & 1;
- if ((*(u64 *)(n+8) != in_n[1]) || (*(u64 *)(n) != in_n[0])) {
- in_n[0] = *(u64 *)(n);
- in_n[1] = *(u64 *)(n+8);
- ((unsigned char *)in_n)[15] &= 0xFE;
- crypto_cipher_encrypt_one(ctx->child,
- (unsigned char *)out_p, (unsigned char *)in_n);
-
- ((unsigned char *)in_n)[15] |= (unsigned char)(1-i);
+ if (keylen != VMAC_KEY_LEN) {
+ crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+ return -EINVAL;
}
- p = be64_to_cpup(out_p + i);
- h = vhash(m, mbytes, (u64 *)0, &ctx->__vmac_ctx);
- return le64_to_cpu(p + h);
-}
-static int vmac_set_key(unsigned char user_key[], struct vmac_ctx_t *ctx)
-{
- u64 in[2] = {0}, out[2];
- unsigned i;
- int err = 0;
-
- err = crypto_cipher_setkey(ctx->child, user_key, VMAC_KEY_LEN);
+ err = crypto_cipher_setkey(tctx->cipher, key, keylen);
if (err)
return err;
/* Fill nh key */
- ((unsigned char *)in)[0] = 0x80;
- for (i = 0; i < sizeof(ctx->__vmac_ctx.nhkey)/8; i += 2) {
- crypto_cipher_encrypt_one(ctx->child,
- (unsigned char *)out, (unsigned char *)in);
- ctx->__vmac_ctx.nhkey[i] = be64_to_cpup(out);
- ctx->__vmac_ctx.nhkey[i+1] = be64_to_cpup(out+1);
- ((unsigned char *)in)[15] += 1;
+ in[0] = 0x80;
+ for (i = 0; i < ARRAY_SIZE(tctx->nhkey); i += 2) {
+ crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in);
+ tctx->nhkey[i] = be64_to_cpu(out[0]);
+ tctx->nhkey[i+1] = be64_to_cpu(out[1]);
+ in[15]++;
}
/* Fill poly key */
- ((unsigned char *)in)[0] = 0xC0;
- in[1] = 0;
- for (i = 0; i < sizeof(ctx->__vmac_ctx.polykey)/8; i += 2) {
- crypto_cipher_encrypt_one(ctx->child,
- (unsigned char *)out, (unsigned char *)in);
- ctx->__vmac_ctx.polytmp[i] =
- ctx->__vmac_ctx.polykey[i] =
- be64_to_cpup(out) & mpoly;
- ctx->__vmac_ctx.polytmp[i+1] =
- ctx->__vmac_ctx.polykey[i+1] =
- be64_to_cpup(out+1) & mpoly;
- ((unsigned char *)in)[15] += 1;
+ in[0] = 0xC0;
+ in[15] = 0;
+ for (i = 0; i < ARRAY_SIZE(tctx->polykey); i += 2) {
+ crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in);
+ tctx->polykey[i] = be64_to_cpu(out[0]) & mpoly;
+ tctx->polykey[i+1] = be64_to_cpu(out[1]) & mpoly;
+ in[15]++;
}
/* Fill ip key */
- ((unsigned char *)in)[0] = 0xE0;
- in[1] = 0;
- for (i = 0; i < sizeof(ctx->__vmac_ctx.l3key)/8; i += 2) {
+ in[0] = 0xE0;
+ in[15] = 0;
+ for (i = 0; i < ARRAY_SIZE(tctx->l3key); i += 2) {
do {
- crypto_cipher_encrypt_one(ctx->child,
- (unsigned char *)out, (unsigned char *)in);
- ctx->__vmac_ctx.l3key[i] = be64_to_cpup(out);
- ctx->__vmac_ctx.l3key[i+1] = be64_to_cpup(out+1);
- ((unsigned char *)in)[15] += 1;
- } while (ctx->__vmac_ctx.l3key[i] >= p64
- || ctx->__vmac_ctx.l3key[i+1] >= p64);
+ crypto_cipher_encrypt_one(tctx->cipher, (u8 *)out, in);
+ tctx->l3key[i] = be64_to_cpu(out[0]);
+ tctx->l3key[i+1] = be64_to_cpu(out[1]);
+ in[15]++;
+ } while (tctx->l3key[i] >= p64 || tctx->l3key[i+1] >= p64);
}
- /* Invalidate nonce/aes cache and reset other elements */
- ctx->__vmac_ctx.cached_nonce[0] = (u64)-1; /* Ensure illegal nonce */
- ctx->__vmac_ctx.cached_nonce[1] = (u64)0; /* Ensure illegal nonce */
- ctx->__vmac_ctx.first_block_processed = 0;
-
- return err;
+ return 0;
}
-static int vmac_setkey(struct crypto_shash *parent,
- const u8 *key, unsigned int keylen)
+static int vmac_init(struct shash_desc *desc)
{
- struct vmac_ctx_t *ctx = crypto_shash_ctx(parent);
+ const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+ struct vmac_desc_ctx *dctx = shash_desc_ctx(desc);
- if (keylen != VMAC_KEY_LEN) {
- crypto_shash_set_flags(parent, CRYPTO_TFM_RES_BAD_KEY_LEN);
- return -EINVAL;
- }
-
- return vmac_set_key((u8 *)key, ctx);
-}
-
-static int vmac_init(struct shash_desc *pdesc)
-{
+ dctx->partial_size = 0;
+ dctx->first_block_processed = false;
+ memcpy(dctx->polytmp, tctx->polykey, sizeof(dctx->polytmp));
return 0;
}
-static int vmac_update(struct shash_desc *pdesc, const u8 *p,
- unsigned int len)
+static int vmac_update(struct shash_desc *desc, const u8 *p, unsigned int len)
{
- struct crypto_shash *parent = pdesc->tfm;
- struct vmac_ctx_t *ctx = crypto_shash_ctx(parent);
- int expand;
- int min;
-
- expand = VMAC_NHBYTES - ctx->partial_size > 0 ?
- VMAC_NHBYTES - ctx->partial_size : 0;
-
- min = len < expand ? len : expand;
-
- memcpy(ctx->partial + ctx->partial_size, p, min);
- ctx->partial_size += min;
-
- if (len < expand)
- return 0;
-
- vhash_update(ctx->partial, VMAC_NHBYTES, &ctx->__vmac_ctx);
- ctx->partial_size = 0;
-
- len -= expand;
- p += expand;
+ const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+ struct vmac_desc_ctx *dctx = shash_desc_ctx(desc);
+ unsigned int n;
+
+ if (dctx->partial_size) {
+ n = min(len, VMAC_NHBYTES - dctx->partial_size);
+ memcpy(&dctx->partial[dctx->partial_size], p, n);
+ dctx->partial_size += n;
+ p += n;
+ len -= n;
+ if (dctx->partial_size == VMAC_NHBYTES) {
+ vhash_blocks(tctx, dctx, dctx->partial_words, 1);
+ dctx->partial_size = 0;
+ }
+ }
- if (len % VMAC_NHBYTES) {
- memcpy(ctx->partial, p + len - (len % VMAC_NHBYTES),
- len % VMAC_NHBYTES);
- ctx->partial_size = len % VMAC_NHBYTES;
+ if (len >= VMAC_NHBYTES) {
+ n = round_down(len, VMAC_NHBYTES);
+ /* TODO: 'p' may be misaligned here */
+ vhash_blocks(tctx, dctx, (const __le64 *)p, n / VMAC_NHBYTES);
+ p += n;
+ len -= n;
}
- vhash_update(p, len - len % VMAC_NHBYTES, &ctx->__vmac_ctx);
+ if (len) {
+ memcpy(dctx->partial, p, len);
+ dctx->partial_size = len;
+ }
return 0;
}
-static int vmac_final(struct shash_desc *pdesc, u8 *out)
+static u64 vhash_final(const struct vmac_tfm_ctx *tctx,
+ struct vmac_desc_ctx *dctx)
{
- struct crypto_shash *parent = pdesc->tfm;
- struct vmac_ctx_t *ctx = crypto_shash_ctx(parent);
- vmac_t mac;
- u8 nonce[16] = {};
-
- /* vmac() ends up accessing outside the array bounds that
- * we specify. In appears to access up to the next 2-word
- * boundary. We'll just be uber cautious and zero the
- * unwritten bytes in the buffer.
- */
- if (ctx->partial_size) {
- memset(ctx->partial + ctx->partial_size, 0,
- VMAC_NHBYTES - ctx->partial_size);
+ unsigned int partial = dctx->partial_size;
+ u64 ch = dctx->polytmp[0];
+ u64 cl = dctx->polytmp[1];
+
+ /* L1 and L2-hash the final block if needed */
+ if (partial) {
+ /* Zero-pad to next 128-bit boundary */
+ unsigned int n = round_up(partial, 16);
+ u64 rh, rl;
+
+ memset(&dctx->partial[partial], 0, n - partial);
+ nh_16(dctx->partial_words, tctx->nhkey, n / 8, rh, rl);
+ rh &= m62;
+ if (dctx->first_block_processed)
+ poly_step(ch, cl, tctx->polykey[0], tctx->polykey[1],
+ rh, rl);
+ else
+ ADD128(ch, cl, rh, rl);
}
- mac = vmac(ctx->partial, ctx->partial_size, nonce, NULL, ctx);
- memcpy(out, &mac, sizeof(vmac_t));
- memzero_explicit(&mac, sizeof(vmac_t));
- memset(&ctx->__vmac_ctx, 0, sizeof(struct vmac_ctx));
- ctx->partial_size = 0;
+
+ /* L3-hash the 128-bit output of L2-hash */
+ return l3hash(ch, cl, tctx->l3key[0], tctx->l3key[1], partial * 8);
+}
+
+static int vmac_final(struct shash_desc *desc, u8 *out)
+{
+ const struct vmac_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
+ struct vmac_desc_ctx *dctx = shash_desc_ctx(desc);
+ static const u8 nonce[16] = {}; /* TODO: this is insecure */
+ union {
+ u8 bytes[16];
+ __be64 pads[2];
+ } block;
+ int index;
+ u64 hash, pad;
+
+ /* Finish calculating the VHASH of the message */
+ hash = vhash_final(tctx, dctx);
+
+ /* Generate pseudorandom pad by encrypting the nonce */
+ memcpy(&block, nonce, 16);
+ index = block.bytes[15] & 1;
+ block.bytes[15] &= ~1;
+ crypto_cipher_encrypt_one(tctx->cipher, block.bytes, block.bytes);
+ pad = be64_to_cpu(block.pads[index]);
+
+ /* The VMAC is the sum of VHASH and the pseudorandom pad */
+ put_unaligned_le64(hash + pad, out);
return 0;
}
static int vmac_init_tfm(struct crypto_tfm *tfm)
{
- struct crypto_cipher *cipher;
- struct crypto_instance *inst = (void *)tfm->__crt_alg;
+ struct crypto_instance *inst = crypto_tfm_alg_instance(tfm);
struct crypto_spawn *spawn = crypto_instance_ctx(inst);
- struct vmac_ctx_t *ctx = crypto_tfm_ctx(tfm);
+ struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+ struct crypto_cipher *cipher;
cipher = crypto_spawn_cipher(spawn);
if (IS_ERR(cipher))
return PTR_ERR(cipher);
- ctx->child = cipher;
+ tctx->cipher = cipher;
return 0;
}
static void vmac_exit_tfm(struct crypto_tfm *tfm)
{
- struct vmac_ctx_t *ctx = crypto_tfm_ctx(tfm);
- crypto_free_cipher(ctx->child);
+ struct vmac_tfm_ctx *tctx = crypto_tfm_ctx(tfm);
+
+ crypto_free_cipher(tctx->cipher);
}
static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb)
@@ -655,6 +608,10 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb)
if (IS_ERR(alg))
return PTR_ERR(alg);
+ err = -EINVAL;
+ if (alg->cra_blocksize != 16)
+ goto out_put_alg;
+
inst = shash_alloc_instance("vmac", alg);
err = PTR_ERR(inst);
if (IS_ERR(inst))
@@ -670,11 +627,12 @@ static int vmac_create(struct crypto_template *tmpl, struct rtattr **tb)
inst->alg.base.cra_blocksize = alg->cra_blocksize;
inst->alg.base.cra_alignmask = alg->cra_alignmask;
- inst->alg.digestsize = sizeof(vmac_t);
- inst->alg.base.cra_ctxsize = sizeof(struct vmac_ctx_t);
+ inst->alg.base.cra_ctxsize = sizeof(struct vmac_tfm_ctx);
inst->alg.base.cra_init = vmac_init_tfm;
inst->alg.base.cra_exit = vmac_exit_tfm;
+ inst->alg.descsize = sizeof(struct vmac_desc_ctx);
+ inst->alg.digestsize = VMAC_TAG_LEN / 8;
inst->alg.init = vmac_init;
inst->alg.update = vmac_update;
inst->alg.final = vmac_final;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index cd4de7e038ea..3e72f9b42097 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -476,9 +476,11 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
}
control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL
- | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
| OSC_PCI_EXPRESS_PME_CONTROL;
+ if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE))
+ control |= OSC_PCI_EXPRESS_NATIVE_HP_CONTROL;
+
if (pci_aer_available()) {
if (aer_acpi_firmware_first())
dev_info(&device->dev,
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 9bdc1867137b..bdf540f8ca8a 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2173,12 +2173,16 @@ static void ata_eh_link_autopsy(struct ata_link *link)
if (qc->err_mask & ~AC_ERR_OTHER)
qc->err_mask &= ~AC_ERR_OTHER;
- /* SENSE_VALID trumps dev/unknown error and revalidation */
+ /*
+ * SENSE_VALID trumps dev/unknown error and revalidation. Upper
+ * layers will determine whether the command is worth retrying
+ * based on the sense data and device class/type. Otherwise,
+ * determine directly if the command is worth retrying using its
+ * error mask and flags.
+ */
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
-
- /* determine whether the command is worth retrying */
- if (ata_eh_worth_retry(qc))
+ else if (ata_eh_worth_retry(qc))
qc->flags |= ATA_QCFLAG_RETRY;
/* accumulate error info */
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 998991a365b8..81fb29741dc1 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2525,7 +2525,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
if (!CDROM_CAN(CDC_SELECT_DISC) ||
(arg == CDSL_CURRENT || arg == CDSL_NONE))
return cdi->ops->drive_status(cdi, CDSL_CURRENT);
- if (((int)arg >= cdi->capacity))
+ if (arg >= cdi->capacity)
return -EINVAL;
return cdrom_slot_status(cdi, arg);
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 37d1c3836d0a..69de8258d10f 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1843,8 +1843,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
spin_unlock(&fl->apps->hlock);
if (!fl->sctx) {
- kfree(fl);
- return 0;
+ goto bail;
}
(void)fastrpc_release_current_dsp_process(fl);
@@ -1856,6 +1855,9 @@ static int fastrpc_file_free(struct fastrpc_file *fl)
if (fl->ssrcount == fl->apps->channel[cid].ssrcount)
kref_put_mutex(&fl->apps->channel[cid].kref,
fastrpc_channel_close, &fl->apps->smd_mutex);
+
+bail:
+ mutex_destroy(&fl->map_mutex);
kfree(fl);
return 0;
}
@@ -2009,7 +2011,6 @@ static int fastrpc_device_release(struct inode *inode, struct file *file)
}
me->pending_free++;
mutex_unlock(&me->flfree_mutex);
- mutex_destroy(&fl->map_mutex);
file->private_data = NULL;
}
bail:
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
index e195d9d0931c..6e24f475d65d 100644
--- a/drivers/char/diag/diag_dci.c
+++ b/drivers/char/diag/diag_dci.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#ifdef CONFIG_DIAG_OVER_USB
#include
#endif
@@ -229,7 +230,7 @@ static int diag_dci_init_buffer(struct diag_dci_buffer_t *buffer, int type)
switch (type) {
case DCI_BUF_PRIMARY:
buffer->capacity = IN_BUF_SIZE;
- buffer->data = kzalloc(buffer->capacity, GFP_KERNEL);
+ buffer->data = vzalloc(buffer->capacity);
if (!buffer->data)
return -ENOMEM;
break;
@@ -239,7 +240,7 @@ static int diag_dci_init_buffer(struct diag_dci_buffer_t *buffer, int type)
break;
case DCI_BUF_CMD:
buffer->capacity = DIAG_MAX_REQ_SIZE + DCI_BUF_SIZE;
- buffer->data = kzalloc(buffer->capacity, GFP_KERNEL);
+ buffer->data = vzalloc(buffer->capacity);
if (!buffer->data)
return -ENOMEM;
break;
@@ -2615,7 +2616,7 @@ static int diag_dci_init_remote(void)
create_dci_event_mask_tbl(temp->event_mask_composite);
}
- partial_pkt.data = kzalloc(MAX_DCI_PACKET_SZ, GFP_KERNEL);
+ partial_pkt.data = vzalloc(MAX_DCI_PACKET_SZ);
if (!partial_pkt.data) {
pr_err("diag: Unable to create partial pkt data\n");
return -ENOMEM;
@@ -2671,7 +2672,7 @@ int diag_dci_init(void)
goto err;
if (driver->apps_dci_buf == NULL) {
- driver->apps_dci_buf = kzalloc(DCI_BUF_SIZE, GFP_KERNEL);
+ driver->apps_dci_buf = vzalloc(DCI_BUF_SIZE);
if (driver->apps_dci_buf == NULL)
goto err;
}
@@ -2688,12 +2689,12 @@ int diag_dci_init(void)
return DIAG_DCI_NO_ERROR;
err:
pr_err("diag: Could not initialize diag DCI buffers");
- kfree(driver->apps_dci_buf);
+ vfree(driver->apps_dci_buf);
driver->apps_dci_buf = NULL;
if (driver->diag_dci_wq)
destroy_workqueue(driver->diag_dci_wq);
- kfree(partial_pkt.data);
+ vfree(partial_pkt.data);
partial_pkt.data = NULL;
mutex_destroy(&driver->dci_mutex);
mutex_destroy(&dci_log_mask_mutex);
@@ -2713,9 +2714,9 @@ void diag_dci_channel_init(void)
void diag_dci_exit(void)
{
- kfree(partial_pkt.data);
+ vfree(partial_pkt.data);
partial_pkt.data = NULL;
- kfree(driver->apps_dci_buf);
+ vfree(driver->apps_dci_buf);
driver->apps_dci_buf = NULL;
mutex_destroy(&driver->dci_mutex);
mutex_destroy(&dci_log_mask_mutex);
@@ -2855,7 +2856,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
new_entry->in_service = 0;
INIT_LIST_HEAD(&new_entry->list_write_buf);
mutex_init(&new_entry->write_buf_mutex);
- new_entry->dci_log_mask = kzalloc(DCI_LOG_MASK_SIZE, GFP_KERNEL);
+ new_entry->dci_log_mask = vzalloc(DCI_LOG_MASK_SIZE);
if (!new_entry->dci_log_mask) {
pr_err("diag: Unable to create log mask for client, %d",
driver->dci_client_id);
@@ -2863,7 +2864,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
}
create_dci_log_mask_tbl(new_entry->dci_log_mask, DCI_LOG_MASK_CLEAN);
- new_entry->dci_event_mask = kzalloc(DCI_EVENT_MASK_SIZE, GFP_KERNEL);
+ new_entry->dci_event_mask = vzalloc(DCI_EVENT_MASK_SIZE);
if (!new_entry->dci_event_mask) {
pr_err("diag: Unable to create event mask for client, %d",
driver->dci_client_id);
@@ -2873,7 +2874,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
new_entry->buffers = kzalloc(new_entry->num_buffers *
sizeof(struct diag_dci_buf_peripheral_t),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!new_entry->buffers) {
pr_err("diag: Unable to allocate buffers for peripherals in %s\n",
__func__);
@@ -2897,7 +2898,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
if (!proc_buf->buf_primary)
goto fail_alloc;
proc_buf->buf_cmd = kzalloc(sizeof(struct diag_dci_buffer_t),
- GFP_KERNEL);
+ GFP_KERNEL);
if (!proc_buf->buf_cmd)
goto fail_alloc;
err = diag_dci_init_buffer(proc_buf->buf_primary,
@@ -2930,7 +2931,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
if (proc_buf) {
mutex_destroy(&proc_buf->health_mutex);
if (proc_buf->buf_primary) {
- kfree(proc_buf->buf_primary->data);
+ vfree(proc_buf->buf_primary->data);
proc_buf->buf_primary->data = NULL;
mutex_destroy(
&proc_buf->buf_primary->data_mutex);
@@ -2938,7 +2939,7 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
kfree(proc_buf->buf_primary);
proc_buf->buf_primary = NULL;
if (proc_buf->buf_cmd) {
- kfree(proc_buf->buf_cmd->data);
+ vfree(proc_buf->buf_cmd->data);
proc_buf->buf_cmd->data = NULL;
mutex_destroy(
&proc_buf->buf_cmd->data_mutex);
@@ -2947,9 +2948,9 @@ int diag_dci_register_client(struct diag_dci_reg_tbl_t *reg_entry)
proc_buf->buf_cmd = NULL;
}
}
- kfree(new_entry->dci_event_mask);
+ vfree(new_entry->dci_event_mask);
new_entry->dci_event_mask = NULL;
- kfree(new_entry->dci_log_mask);
+ vfree(new_entry->dci_log_mask);
new_entry->dci_log_mask = NULL;
kfree(new_entry->buffers);
new_entry->buffers = NULL;
@@ -2984,7 +2985,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
* Clear the client's log and event masks, update the cumulative
* masks and send the masks to peripherals
*/
- kfree(entry->dci_log_mask);
+ vfree(entry->dci_log_mask);
entry->dci_log_mask = NULL;
diag_dci_invalidate_cumulative_log_mask(token);
if (token == DCI_LOCAL_PROC)
@@ -2993,7 +2994,7 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
if (ret != DIAG_DCI_NO_ERROR) {
return ret;
}
- kfree(entry->dci_event_mask);
+ vfree(entry->dci_event_mask);
entry->dci_event_mask = NULL;
diag_dci_invalidate_cumulative_event_mask(token);
if (token == DCI_LOCAL_PROC)
@@ -3057,12 +3058,12 @@ int diag_dci_deinit_client(struct diag_dci_client_tbl *entry)
}
mutex_lock(&proc_buf->buf_primary->data_mutex);
- kfree(proc_buf->buf_primary->data);
+ vfree(proc_buf->buf_primary->data);
proc_buf->buf_primary->data = NULL;
mutex_unlock(&proc_buf->buf_primary->data_mutex);
mutex_lock(&proc_buf->buf_cmd->data_mutex);
- kfree(proc_buf->buf_cmd->data);
+ vfree(proc_buf->buf_cmd->data);
proc_buf->buf_cmd->data = NULL;
mutex_unlock(&proc_buf->buf_cmd->data_mutex);
diff --git a/drivers/char/diag/diag_masks.c b/drivers/char/diag/diag_masks.c
index dd20aec9983e..4b24df4b6e4c 100644
--- a/drivers/char/diag/diag_masks.c
+++ b/drivers/char/diag/diag_masks.c
@@ -168,10 +168,11 @@ static void diag_send_log_mask_update(uint8_t peripheral, int equip_id)
}
mask_info->update_buf = temp;
mask_info->update_buf_len = header_len + mask_size;
+ buf = temp;
}
memcpy(buf, &ctrl_pkt, header_len);
- if (mask_size > 0)
+ if (mask_size > 0 && mask_size <= LOG_MASK_SIZE)
memcpy(buf + header_len, mask->ptr, mask_size);
mutex_unlock(&mask->lock);
@@ -255,9 +256,16 @@ static void diag_send_event_mask_update(uint8_t peripheral)
} else {
mask_info->update_buf = temp;
mask_info->update_buf_len = temp_len;
+ buf = temp;
}
}
- memcpy(buf + sizeof(header), mask_info->ptr, num_bytes);
+ if (num_bytes > 0 && num_bytes < mask_info->mask_len)
+ memcpy(buf + sizeof(header), mask_info->ptr, num_bytes);
+ else {
+ pr_err("diag: num_bytes(%d) is not satisfying length condition\n",
+ num_bytes);
+ goto err;
+ }
write_len += num_bytes;
break;
default:
@@ -360,6 +368,7 @@ static void diag_send_msg_mask_update(uint8_t peripheral, int first, int last)
} else {
mask_info->update_buf = temp;
mask_info->update_buf_len = temp_len;
+ buf = temp;
pr_debug("diag: In %s, successfully reallocated msg_mask update buffer to len: %d\n",
__func__, mask_info->update_buf_len);
}
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 4ba5c7e4e254..28970b8e4564 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1417,14 +1417,22 @@ static int
write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
{
size_t bytes;
- __u32 buf[16];
+ __u32 t, buf[16];
const char __user *p = buffer;
while (count > 0) {
+ int b, i = 0;
+
bytes = min(count, sizeof(buf));
if (copy_from_user(&buf, p, bytes))
return -EFAULT;
+ for (b = bytes ; b > 0 ; b -= sizeof(__u32), i++) {
+ if (!arch_get_random_int(&t))
+ break;
+ buf[i] ^= t;
+ }
+
count -= bytes;
p += bytes;
diff --git a/drivers/clk/msm/clock-a7.c b/drivers/clk/msm/clock-a7.c
index 96f52df8f830..1dd67b6daed6 100644
--- a/drivers/clk/msm/clock-a7.c
+++ b/drivers/clk/msm/clock-a7.c
@@ -221,6 +221,7 @@ static int of_get_fmax_vdd_class(struct platform_device *pdev, struct clk *c,
devm_kfree(&pdev->dev, array);
vdd->num_levels = prop_len;
vdd->cur_level = prop_len;
+ vdd->use_max_uV = true;
c->num_fmax = prop_len;
return 0;
}
diff --git a/drivers/clk/msm/clock-gcc-9650.c b/drivers/clk/msm/clock-gcc-9650.c
index e2912ff869b4..e454707952b0 100644
--- a/drivers/clk/msm/clock-gcc-9650.c
+++ b/drivers/clk/msm/clock-gcc-9650.c
@@ -1734,6 +1734,11 @@ static int msm_gcc_9650_probe(struct platform_device *pdev)
if (ret)
return ret;
+ if (of_device_is_compatible(pdev->dev.of_node, "qcom,gcc-9650")) {
+ vdd_dig.use_max_uV = true;
+ vdd_dig_ao.use_max_uV = true;
+ }
+
for_sdx20 = of_device_is_compatible(pdev->dev.of_node,
"qcom,gcc-sdx20");
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c
index c178ed8c3908..2250db026198 100644
--- a/drivers/crypto/padlock-aes.c
+++ b/drivers/crypto/padlock-aes.c
@@ -266,6 +266,8 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
return;
}
+ count -= initial;
+
if (initial)
asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
: "+S"(input), "+D"(output)
@@ -273,7 +275,7 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key,
asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */
: "+S"(input), "+D"(output)
- : "d"(control_word), "b"(key), "c"(count - initial));
+ : "d"(control_word), "b"(key), "c"(count));
}
static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
@@ -284,6 +286,8 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
if (count < cbc_fetch_blocks)
return cbc_crypt(input, output, key, iv, control_word, count);
+ count -= initial;
+
if (initial)
asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */
: "+S" (input), "+D" (output), "+a" (iv)
@@ -291,7 +295,7 @@ static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key,
asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" /* rep xcryptcbc */
: "+S" (input), "+D" (output), "+a" (iv)
- : "d" (control_word), "b" (key), "c" (count-initial));
+ : "d" (control_word), "b" (key), "c" (count));
return iv;
}
diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c
index a1f911aaf220..a95f46c2a984 100644
--- a/drivers/dma/k3dma.c
+++ b/drivers/dma/k3dma.c
@@ -652,7 +652,7 @@ static struct dma_chan *k3_of_dma_simple_xlate(struct of_phandle_args *dma_spec,
struct k3_dma_dev *d = ofdma->of_dma_data;
unsigned int request = dma_spec->args[0];
- if (request > d->dma_requests)
+ if (request >= d->dma_requests)
return NULL;
return dma_get_slave_channel(&(d->chans[request].vc.chan));
diff --git a/drivers/gpu/drm/armada/armada_hw.h b/drivers/gpu/drm/armada/armada_hw.h
index 27319a8335e2..345dc4d0851e 100644
--- a/drivers/gpu/drm/armada/armada_hw.h
+++ b/drivers/gpu/drm/armada/armada_hw.h
@@ -160,6 +160,7 @@ enum {
CFG_ALPHAM_GRA = 0x1 << 16,
CFG_ALPHAM_CFG = 0x2 << 16,
CFG_ALPHA_MASK = 0xff << 8,
+#define CFG_ALPHA(x) ((x) << 8)
CFG_PIXCMD_MASK = 0xff,
};
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c
index 5c22b380f8f3..f8a69ec63550 100644
--- a/drivers/gpu/drm/armada/armada_overlay.c
+++ b/drivers/gpu/drm/armada/armada_overlay.c
@@ -27,6 +27,7 @@ struct armada_ovl_plane_properties {
uint16_t contrast;
uint16_t saturation;
uint32_t colorkey_mode;
+ uint32_t colorkey_enable;
};
struct armada_ovl_plane {
@@ -62,11 +63,13 @@ armada_ovl_update_attr(struct armada_ovl_plane_properties *prop,
writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE);
spin_lock_irq(&dcrtc->irq_lock);
- armada_updatel(prop->colorkey_mode | CFG_ALPHAM_GRA,
- CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
- dcrtc->base + LCD_SPU_DMA_CTRL1);
-
- armada_updatel(ADV_GRACOLORKEY, 0, dcrtc->base + LCD_SPU_ADV_REG);
+ armada_updatel(prop->colorkey_mode,
+ CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK,
+ dcrtc->base + LCD_SPU_DMA_CTRL1);
+ if (dcrtc->variant->has_spu_adv_reg)
+ armada_updatel(prop->colorkey_enable,
+ ADV_GRACOLORKEY | ADV_VIDCOLORKEY,
+ dcrtc->base + LCD_SPU_ADV_REG);
spin_unlock_irq(&dcrtc->irq_lock);
}
@@ -339,8 +342,17 @@ static int armada_ovl_plane_set_property(struct drm_plane *plane,
dplane->prop.colorkey_vb |= K2B(val);
update_attr = true;
} else if (property == priv->colorkey_mode_prop) {
- dplane->prop.colorkey_mode &= ~CFG_CKMODE_MASK;
- dplane->prop.colorkey_mode |= CFG_CKMODE(val);
+ if (val == CKMODE_DISABLE) {
+ dplane->prop.colorkey_mode =
+ CFG_CKMODE(CKMODE_DISABLE) |
+ CFG_ALPHAM_CFG | CFG_ALPHA(255);
+ dplane->prop.colorkey_enable = 0;
+ } else {
+ dplane->prop.colorkey_mode =
+ CFG_CKMODE(val) |
+ CFG_ALPHAM_GRA | CFG_ALPHA(0);
+ dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
+ }
update_attr = true;
} else if (property == priv->brightness_prop) {
dplane->prop.brightness = val - 256;
@@ -469,7 +481,9 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
dplane->prop.colorkey_yr = 0xfefefe00;
dplane->prop.colorkey_ug = 0x01010100;
dplane->prop.colorkey_vb = 0x01010100;
- dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB);
+ dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) |
+ CFG_ALPHAM_GRA | CFG_ALPHA(0);
+ dplane->prop.colorkey_enable = ADV_GRACOLORKEY;
dplane->prop.brightness = 0;
dplane->prop.contrast = 0x4000;
dplane->prop.saturation = 0x4000;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gsc.c b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
index 11b87d2a7913..ba69d1c72221 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gsc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gsc.c
@@ -526,21 +526,25 @@ static int gsc_src_set_fmt(struct device *dev, u32 fmt)
GSC_IN_CHROMA_ORDER_CRCB);
break;
case DRM_FORMAT_NV21:
+ cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_2P);
+ break;
case DRM_FORMAT_NV61:
- cfg |= (GSC_IN_CHROMA_ORDER_CRCB |
- GSC_IN_YUV420_2P);
+ cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV422_2P);
break;
case DRM_FORMAT_YUV422:
cfg |= GSC_IN_YUV422_3P;
break;
case DRM_FORMAT_YUV420:
+ cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P);
+ break;
case DRM_FORMAT_YVU420:
- cfg |= GSC_IN_YUV420_3P;
+ cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_3P);
break;
case DRM_FORMAT_NV12:
+ cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_2P);
+ break;
case DRM_FORMAT_NV16:
- cfg |= (GSC_IN_CHROMA_ORDER_CBCR |
- GSC_IN_YUV420_2P);
+ cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV422_2P);
break;
default:
dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt);
@@ -800,18 +804,25 @@ static int gsc_dst_set_fmt(struct device *dev, u32 fmt)
GSC_OUT_CHROMA_ORDER_CRCB);
break;
case DRM_FORMAT_NV21:
- case DRM_FORMAT_NV61:
cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_2P);
break;
+ case DRM_FORMAT_NV61:
+ cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV422_2P);
+ break;
case DRM_FORMAT_YUV422:
+ cfg |= GSC_OUT_YUV422_3P;
+ break;
case DRM_FORMAT_YUV420:
+ cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P);
+ break;
case DRM_FORMAT_YVU420:
- cfg |= GSC_OUT_YUV420_3P;
+ cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_3P);
break;
case DRM_FORMAT_NV12:
+ cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_2P);
+ break;
case DRM_FORMAT_NV16:
- cfg |= (GSC_OUT_CHROMA_ORDER_CBCR |
- GSC_OUT_YUV420_2P);
+ cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV422_2P);
break;
default:
dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt);
diff --git a/drivers/gpu/drm/exynos/regs-gsc.h b/drivers/gpu/drm/exynos/regs-gsc.h
index 9ad592707aaf..ade10966d6af 100644
--- a/drivers/gpu/drm/exynos/regs-gsc.h
+++ b/drivers/gpu/drm/exynos/regs-gsc.h
@@ -138,6 +138,7 @@
#define GSC_OUT_YUV420_3P (3 << 4)
#define GSC_OUT_YUV422_1P (4 << 4)
#define GSC_OUT_YUV422_2P (5 << 4)
+#define GSC_OUT_YUV422_3P (6 << 4)
#define GSC_OUT_YUV444 (7 << 4)
#define GSC_OUT_TILE_TYPE_MASK (1 << 2)
#define GSC_OUT_TILE_C_16x8 (0 << 2)
diff --git a/drivers/gpu/drm/gma500/psb_intel_drv.h b/drivers/gpu/drm/gma500/psb_intel_drv.h
index 860dd2177ca1..283570080d47 100644
--- a/drivers/gpu/drm/gma500/psb_intel_drv.h
+++ b/drivers/gpu/drm/gma500/psb_intel_drv.h
@@ -252,7 +252,7 @@ extern int intelfb_remove(struct drm_device *dev,
extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
-extern int psb_intel_lvds_mode_valid(struct drm_connector *connector,
+extern enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode);
extern int psb_intel_lvds_set_property(struct drm_connector *connector,
struct drm_property *property,
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index 61e3a097a478..ccd1b8bf0fd5 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -343,7 +343,7 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
}
}
-int psb_intel_lvds_mode_valid(struct drm_connector *connector,
+enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_psb_private *dev_priv = connector->dev->dev_private;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index b8520aadbc0c..c993ae279ca9 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -484,7 +484,7 @@ static int dsi_ctrl_init_regmap(struct platform_device *pdev,
}
ctrl->hw.base = ptr;
- pr_debug("[%s] map dsi_ctrl registers to %p\n", ctrl->name,
+ pr_debug("[%s] map dsi_ctrl registers to %pK\n", ctrl->name,
ctrl->hw.base);
ptr = msm_ioremap(pdev, "mmss_misc", ctrl->name);
@@ -494,7 +494,7 @@ static int dsi_ctrl_init_regmap(struct platform_device *pdev,
}
ctrl->hw.mmss_misc_base = ptr;
- pr_debug("[%s] map mmss_misc registers to %p\n", ctrl->name,
+ pr_debug("[%s] map mmss_misc registers to %pK\n", ctrl->name,
ctrl->hw.mmss_misc_base);
return rc;
}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
index 7a8dd567bb1f..1af0a55f840f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_panel.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -1469,7 +1469,7 @@ static int dsi_panel_parse_dba_config(struct dsi_panel *panel,
"qcom,bridge-name", &len);
if (!panel->dba_config.bridge_name || len <= 0) {
SDE_ERROR(
- "%s:%d Unable to read bridge_name, data=%p,len=%d\n",
+ "%s:%d Unable to read bridge_name, data=%pK,len=%d\n",
__func__, __LINE__, panel->dba_config.bridge_name, len);
rc = -EINVAL;
goto error;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
index 1ccbbe7df573..f7a77336e691 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -93,7 +93,8 @@ static int dsi_phy_regmap_init(struct platform_device *pdev,
phy->hw.base = ptr;
- pr_debug("[%s] map dsi_phy registers to %p\n", phy->name, phy->hw.base);
+ pr_debug("[%s] map dsi_phy registers to %pK\n",
+ phy->name, phy->hw.base);
return rc;
}
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c
index 0940e84b2821..253e022ffb09 100644
--- a/drivers/gpu/drm/msm/edp/edp.c
+++ b/drivers/gpu/drm/msm/edp/edp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2015, 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
@@ -54,7 +54,7 @@ static struct msm_edp *edp_init(struct platform_device *pdev)
ret = -ENOMEM;
goto fail;
}
- DBG("eDP probed=%p", edp);
+ DBG("eDP probed=%pK", edp);
edp->pdev = pdev;
platform_set_drvdata(pdev, edp);
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 62e3047e3f31..63a1de59c3a5 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -2,7 +2,7 @@
* Copyright (C) 2013 Red Hat
* Author: Rob Clark
*
- * Copyright (c) 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-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 as published by
@@ -99,7 +99,8 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
}
if (reglog)
- printk(KERN_DEBUG "IO:region %s %p %08lx\n", dbgname, ptr, size);
+ pr_debug("IO:region %s %pK %08lx\n",
+ dbgname, ptr, size);
return ptr;
}
@@ -107,7 +108,7 @@ void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
void msm_writel(u32 data, void __iomem *addr)
{
if (reglog)
- printk(KERN_DEBUG "IO:W %p %08x\n", addr, data);
+ pr_debug("IO:W %pK %08x\n", addr, data);
writel(data, addr);
}
@@ -115,7 +116,7 @@ u32 msm_readl(const void __iomem *addr)
{
u32 val = readl(addr);
if (reglog)
- printk(KERN_ERR "IO:R %p %08x\n", addr, val);
+ pr_debug("IO:R %pK %08x\n", addr, val);
return val;
}
@@ -598,7 +599,7 @@ static int msm_enable_vblank(struct drm_device *dev, unsigned int pipe)
struct msm_kms *kms = priv->kms;
if (!kms)
return -ENXIO;
- DBG("dev=%p, crtc=%u", dev, pipe);
+ DBG("dev=%pK crtc=%u", dev, pipe);
return vblank_ctrl_queue_work(priv, pipe, true);
}
@@ -608,7 +609,7 @@ static void msm_disable_vblank(struct drm_device *dev, unsigned int pipe)
struct msm_kms *kms = priv->kms;
if (!kms)
return;
- DBG("dev=%p, crtc=%u", dev, pipe);
+ DBG("dev=%pK, crtc=%u", dev, pipe);
vblank_ctrl_queue_work(priv, pipe, false);
}
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
index dca4de382581..7b1a6246b268 100644
--- a/drivers/gpu/drm/msm/msm_fb.c
+++ b/drivers/gpu/drm/msm/msm_fb.c
@@ -43,7 +43,7 @@ static void msm_framebuffer_destroy(struct drm_framebuffer *fb)
struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
int i, n = drm_format_num_planes(fb->pixel_format);
- DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
+ DBG("destroy: FB ID: %d (%pK)", fb->base.id, fb);
drm_framebuffer_cleanup(fb);
@@ -178,7 +178,7 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
unsigned int hsub, vsub;
bool is_modified = false;
- DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
+ DBG("create framebuffer: dev=%pK, mode_cmd=%pK (%dx%d@%4.4s)",
dev, mode_cmd, mode_cmd->width, mode_cmd->height,
(char *)&mode_cmd->pixel_format);
@@ -261,7 +261,7 @@ struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
goto fail;
}
- DBG("create: FB ID: %d (%p)", fb->base.id, fb);
+ DBG("create: FB ID: %d (%pK)", fb->base.id, fb);
return fb;
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index e49df634e3f2..14cdd10f29f9 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -146,7 +146,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
goto fail_unlock;
}
- DBG("fbi=%p, dev=%p", fbi, dev);
+ DBG("fbi=%pK, dev=%pK", fbi, dev);
fbdev->fb = fb;
helper->fb = fb;
@@ -167,7 +167,7 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
fbi->fix.smem_start = paddr;
fbi->fix.smem_len = fbdev->bo->size;
- DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
+ DBG("par=%pK, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 05ae5b7e4dc1..69bd4c53df65 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -290,7 +290,7 @@ int msm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
pfn = page_to_pfn(pages[pgoff]);
- VERB("Inserting %p pfn %lx, pa %lx", vmf->virtual_address,
+ VERB("Inserting %pK pfn %lx, pa %lx", vmf->virtual_address,
pfn, pfn << PAGE_SHIFT);
ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
@@ -399,7 +399,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
msm_obj->domain[id].sgt,
IOMMU_READ | IOMMU_NOEXEC);
if (ret) {
- DRM_ERROR("Unable to map phy buf=%p\n",
+ DRM_ERROR("Unable to map phy buf=%pK\n",
(void *)pa);
return ret;
}
@@ -414,7 +414,7 @@ int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
msm_obj->domain[id].iova =
sg_dma_address(msm_obj->domain[id].sgt->sgl);
}
- DRM_DEBUG("iova=%p\n",
+ DRM_DEBUG("iova=%pK\n",
(void *)msm_obj->domain[id].iova);
} else {
WARN_ONCE(1, "physical address being used\n");
@@ -599,7 +599,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
uint64_t off = drm_vma_node_start(&obj->vma_node);
WARN_ON(!mutex_is_locked(&dev->struct_mutex));
- seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %p %zu\n",
+ seq_printf(m, "%08x: %c(r=%u,w=%u) %2d (%2d) %08llx %pK %zu\n",
msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
msm_obj->read_timestamp, msm_obj->write_timestamp,
obj->name, obj->refcount.refcount.counter,
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index fd06bf826b2c..b3e5827719ba 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -1253,7 +1253,7 @@ struct drm_crtc *sde_crtc_init(struct drm_device *dev,
sde_crtc_install_properties(crtc);
- SDE_DEBUG("%s: successfully initialized crtc=%p\n",
+ SDE_DEBUG("%s: successfully initialized crtc=%pK\n",
sde_crtc->name, crtc);
return crtc;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
index 629ca373665c..1a5e0faf9e47 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_catalog.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2016, 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
@@ -133,7 +133,7 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 major,
struct sde_mdss_cfg *cfg = NULL;
if (!dev || !dev->dev) {
- SDE_ERROR("dev=%p or dev->dev is NULL\n", dev);
+ SDE_ERROR("dev=%pK or dev->dev is NULL\n", dev);
return NULL;
}
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index cffdaad1de32..c013fc135a97 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, 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
@@ -1506,7 +1506,7 @@ u32 sde_plane_num_of_phy_pipe(struct drm_plane *plane)
struct sde_plane *sde_plane = to_sde_plane(plane);
if (!plane || !sde_plane) {
- SDE_ERROR("plane=%p or sde_plane=%p is NULL\n",
+ SDE_ERROR("plane=%pK or sde_plane=%pK is NULL\n",
plane, sde_plane);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 30f00748ed37..7fa9151be619 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -851,7 +851,7 @@ static int radeon_lvds_get_modes(struct drm_connector *connector)
return ret;
}
-static int radeon_lvds_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_encoder *encoder = radeon_best_single_encoder(connector);
@@ -994,7 +994,7 @@ static int radeon_vga_get_modes(struct drm_connector *connector)
return ret;
}
-static int radeon_vga_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_vga_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
@@ -1133,7 +1133,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector)
return 1;
}
-static int radeon_tv_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_tv_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
if ((mode->hdisplay > 1024) || (mode->vdisplay > 768))
@@ -1464,7 +1464,7 @@ static void radeon_dvi_force(struct drm_connector *connector)
radeon_connector->use_digital = true;
}
-static int radeon_dvi_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_dvi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
@@ -1761,7 +1761,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
return ret;
}
-static int radeon_dp_mode_valid(struct drm_connector *connector,
+static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
struct drm_device *dev = connector->dev;
diff --git a/drivers/gpu/drm/udl/udl_fb.c b/drivers/gpu/drm/udl/udl_fb.c
index 29bd801f5dad..0c648efd9a58 100644
--- a/drivers/gpu/drm/udl/udl_fb.c
+++ b/drivers/gpu/drm/udl/udl_fb.c
@@ -341,7 +341,7 @@ static int udl_fb_open(struct fb_info *info, int user)
struct fb_deferred_io *fbdefio;
- fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
+ fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL);
if (fbdefio) {
fbdefio->delay = DL_DEFIO_WRITE_DELAY;
diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c
index 33dbfb2c4748..30bfeb1b2512 100644
--- a/drivers/gpu/drm/udl/udl_main.c
+++ b/drivers/gpu/drm/udl/udl_main.c
@@ -141,18 +141,13 @@ static void udl_free_urb_list(struct drm_device *dev)
struct list_head *node;
struct urb_node *unode;
struct urb *urb;
- int ret;
unsigned long flags;
DRM_DEBUG("Waiting for completes and freeing all render urbs\n");
/* keep waiting and freeing, until we've got 'em all */
while (count--) {
-
- /* Getting interrupted means a leak, but ok at shutdown*/
- ret = down_interruptible(&udl->urbs.limit_sem);
- if (ret)
- break;
+ down(&udl->urbs.limit_sem);
spin_lock_irqsave(&udl->urbs.lock, flags);
@@ -176,17 +171,22 @@ static void udl_free_urb_list(struct drm_device *dev)
static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
{
struct udl_device *udl = dev->dev_private;
- int i = 0;
struct urb *urb;
struct urb_node *unode;
char *buf;
+ size_t wanted_size = count * size;
spin_lock_init(&udl->urbs.lock);
+retry:
udl->urbs.size = size;
INIT_LIST_HEAD(&udl->urbs.list);
- while (i < count) {
+ sema_init(&udl->urbs.limit_sem, 0);
+ udl->urbs.count = 0;
+ udl->urbs.available = 0;
+
+ while (udl->urbs.count * size < wanted_size) {
unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL);
if (!unode)
break;
@@ -202,11 +202,16 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
}
unode->urb = urb;
- buf = usb_alloc_coherent(udl->udev, MAX_TRANSFER, GFP_KERNEL,
+ buf = usb_alloc_coherent(udl->udev, size, GFP_KERNEL,
&urb->transfer_dma);
if (!buf) {
kfree(unode);
usb_free_urb(urb);
+ if (size > PAGE_SIZE) {
+ size /= 2;
+ udl_free_urb_list(dev);
+ goto retry;
+ }
break;
}
@@ -217,16 +222,14 @@ static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size)
list_add_tail(&unode->entry, &udl->urbs.list);
- i++;
+ up(&udl->urbs.limit_sem);
+ udl->urbs.count++;
+ udl->urbs.available++;
}
- sema_init(&udl->urbs.limit_sem, i);
- udl->urbs.count = i;
- udl->urbs.available = i;
-
- DRM_DEBUG("allocated %d %d byte urbs\n", i, (int) size);
+ DRM_DEBUG("allocated %d %d byte urbs\n", udl->urbs.count, (int) size);
- return i;
+ return udl->urbs.count;
}
struct urb *udl_get_urb(struct drm_device *dev)
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index 2d86ac02b2cd..8463f83e037f 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -981,6 +981,14 @@ static int i2c_hid_probe(struct i2c_client *client,
pm_runtime_set_active(&client->dev);
pm_runtime_enable(&client->dev);
+ /* Make sure there is something at this address */
+ ret = i2c_smbus_read_byte(client);
+ if (ret < 0) {
+ dev_dbg(&client->dev, "nothing at this address: %d\n", ret);
+ ret = -ENXIO;
+ goto err_pm;
+ }
+
ret = i2c_hid_fetch_hid_descriptor(ihid);
if (ret < 0)
goto err_pm;
diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
index f771c6afbab5..beab499d182c 100644
--- a/drivers/i2c/busses/i2c-ismt.c
+++ b/drivers/i2c/busses/i2c-ismt.c
@@ -587,7 +587,7 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
/* unmap the data buffer */
if (dma_size != 0)
- dma_unmap_single(&adap->dev, dma_addr, dma_size, dma_direction);
+ dma_unmap_single(dev, dma_addr, dma_size, dma_direction);
if (unlikely(!ret)) {
dev_err(dev, "completion wait timed out\n");
diff --git a/drivers/iio/frequency/ad9523.c b/drivers/iio/frequency/ad9523.c
index 7c5245d9f99c..4cffd8fc5cae 100644
--- a/drivers/iio/frequency/ad9523.c
+++ b/drivers/iio/frequency/ad9523.c
@@ -507,7 +507,7 @@ static ssize_t ad9523_store(struct device *dev,
return ret;
if (!state)
- return 0;
+ return len;
mutex_lock(&indio_dev->mlock);
switch ((u32)this_attr->address) {
@@ -641,7 +641,7 @@ static int ad9523_read_raw(struct iio_dev *indio_dev,
code = (AD9523_CLK_DIST_DIV_PHASE_REV(ret) * 3141592) /
AD9523_CLK_DIST_DIV_REV(ret);
*val = code / 1000000;
- *val2 = (code % 1000000) * 10;
+ *val2 = code % 1000000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 74c30f4c557e..0c79b0626a6e 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1466,7 +1466,8 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
mad_reg_req->oui, 3)) {
method = &(*vendor_table)->vendor_class[
vclass]->method_table[i];
- BUG_ON(!*method);
+ if (!*method)
+ goto error3;
goto check_in_use;
}
}
@@ -1476,10 +1477,12 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req,
vclass]->oui[i])) {
method = &(*vendor_table)->vendor_class[
vclass]->method_table[i];
- BUG_ON(*method);
/* Allocate method table for this OUI */
- if ((ret = allocate_method_table(method)))
- goto error3;
+ if (!*method) {
+ ret = allocate_method_table(method);
+ if (ret)
+ goto error3;
+ }
memcpy((*vendor_table)->vendor_class[vclass]->oui[i],
mad_reg_req->oui, 3);
goto check_in_use;
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 81dd84d0b68b..eaadd636c21b 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -180,7 +180,7 @@ static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
return NULL;
mutex_lock(&mut);
- mc->id = idr_alloc(&multicast_idr, mc, 0, 0, GFP_KERNEL);
+ mc->id = idr_alloc(&multicast_idr, NULL, 0, 0, GFP_KERNEL);
mutex_unlock(&mut);
if (mc->id < 0)
goto error;
@@ -1262,6 +1262,10 @@ static ssize_t ucma_process_join(struct ucma_file *file,
goto err3;
}
+ mutex_lock(&mut);
+ idr_replace(&multicast_idr, mc, mc->id);
+ mutex_unlock(&mut);
+
mutex_unlock(&file->mut);
ucma_put_ctx(ctx);
return 0;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 3341d74c8c9b..3771e65bacab 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -1161,7 +1161,7 @@ config TOUCHSCREEN_HIMAX_CHIPSET
HIMAX controllers are multi touch controllers which can
report 10 touches at a time.
- If unsure, say N.
+ If unsure, say N.
source "drivers/input/touchscreen/hxchipset/Kconfig"
diff --git a/drivers/input/touchscreen/hxchipset/HX83100_Amber_0901_030B.i b/drivers/input/touchscreen/hxchipset/HX83100_Amber_0901_030B.i
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_124.i b/drivers/input/touchscreen/hxchipset/HX_CRC_124.i
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_128.i b/drivers/input/touchscreen/hxchipset/HX_CRC_128.i
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_60.i b/drivers/input/touchscreen/hxchipset/HX_CRC_60.i
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/drivers/input/touchscreen/hxchipset/HX_CRC_64.i b/drivers/input/touchscreen/hxchipset/HX_CRC_64.i
deleted file mode 100644
index e69de29bb2d1..000000000000
diff --git a/drivers/input/touchscreen/hxchipset/Kconfig b/drivers/input/touchscreen/hxchipset/Kconfig
index ebf3aa478af5..3dc5a026c851 100644
--- a/drivers/input/touchscreen/hxchipset/Kconfig
+++ b/drivers/input/touchscreen/hxchipset/Kconfig
@@ -3,19 +3,44 @@
#
config TOUCHSCREEN_HIMAX_I2C
- tristate "HIMAX chipset i2c touchscreen"
- depends on TOUCHSCREEN_HIMAX_CHIPSET
- help
+ tristate "HIMAX chipset i2c touchscreen"
+ depends on TOUCHSCREEN_HIMAX_CHIPSET
+ help
+ Say Y here to enable support for HIMAX CHIPSET over I2C based touchscreens.
+ If unsure, say N.
+
+ To compile this driver as a module,
This enables support for HIMAX CHIPSET over I2C based touchscreens.
config TOUCHSCREEN_HIMAX_DEBUG
- tristate "HIMAX debug function"
- depends on TOUCHSCREEN_HIMAX_I2C
- help
+ tristate "HIMAX debug function"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ Say Y here to enable support for HIMAX debug function.
+
+ If unsure, say N.
+
+ To compile this driver as a module,
This enables support for HIMAX debug function.
+config TOUCHSCREEN_HIMAX_ITO_TEST
+ tristate "HIMAX driver test over Dragon Board"
+ depends on TOUCHSCREEN_HIMAX_I2C
+ help
+ Say Y here to enable support for HIMAX driver test over Dragon Board.
+
+ If unsure, say N.
+
+ To compile this driver as a module,
+ this enables support for HIMAX driver test over Dragon Board.
+
config HMX_DB
tristate "HIMAX driver test over Dragon Board"
depends on TOUCHSCREEN_HIMAX_I2C
help
- This enables support for HIMAX driver test over Dragon Board.
+ Say Y here to enable support for HIMAX driver test over Dragon Board.
+
+ If unsure, say N.
+
+ To compile this driver as a module,
+ this enables support for HIMAX driver test over Dragon Board.
diff --git a/drivers/input/touchscreen/hxchipset/Makefile b/drivers/input/touchscreen/hxchipset/Makefile
index 509d4913bc39..522907a48956 100644
--- a/drivers/input/touchscreen/hxchipset/Makefile
+++ b/drivers/input/touchscreen/hxchipset/Makefile
@@ -1,3 +1,4 @@
# Makefile for the Himax touchscreen drivers.
obj-$(CONFIG_TOUCHSCREEN_HIMAX_I2C) += himax_platform.o himax_ic.o himax_common.o himax_debug.o
+obj-$(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) += himax_ito_test.o
\ No newline at end of file
diff --git a/drivers/input/touchscreen/hxchipset/himax_common.c b/drivers/input/touchscreen/hxchipset/himax_common.c
index 417b0c08e361..d4bc5beb0203 100644
--- a/drivers/input/touchscreen/hxchipset/himax_common.c
+++ b/drivers/input/touchscreen/hxchipset/himax_common.c
@@ -1,4 +1,4 @@
-/* Himax Android Driver Sample Code for Himax chipset
+ /* Himax Android Driver Sample Code for Himax chipset
*
* Copyright (C) 2015 Himax Corporation.
*
@@ -21,107 +21,32 @@
#define FRAME_COUNT 5
#if defined(HX_AUTO_UPDATE_FW)
- static unsigned char i_CTPM_FW[]=
- {
- #include "HX83100_Amber_0901_030B.i"
- };
+ char *i_CTPM_firmware_name = "HX83100_Amber_0B01_030E.bin";
+ const struct firmware *i_CTPM_FW = NULL;
#endif
-#ifdef HX_ESD_WORKAROUND
- extern void HX_report_ESD_event(void);
- unsigned char ESD_00_counter = 0;
- unsigned char ESD_00_Flag = 0;
-#endif
-
-//static int tpd_keys_local[HX_KEY_MAX_COUNT] = HX_KEY_ARRAY; // for Virtual key array
+/*static int tpd_keys_local[HX_KEY_MAX_COUNT] = HX_KEY_ARRAY;
+// for Virtual key array */
struct himax_ts_data *private_ts;
-struct himax_ic_data* ic_data;
-
-static int HX_TOUCH_INFO_POINT_CNT;
-
-#ifdef HX_AUTO_UPDATE_FW
-extern unsigned long FW_VER_MAJ_FLASH_ADDR;
-extern unsigned long FW_VER_MIN_FLASH_ADDR;
-extern unsigned long CFG_VER_MAJ_FLASH_ADDR;
-extern unsigned long CFG_VER_MIN_FLASH_ADDR;
-#endif
-extern unsigned long FW_VER_MAJ_FLASH_LENG;
-extern unsigned long FW_VER_MIN_FLASH_LENG;
-extern unsigned long CFG_VER_MAJ_FLASH_LENG;
-extern unsigned long CFG_VER_MIN_FLASH_LENG;
-extern unsigned char IC_TYPE;
-extern unsigned char IC_CHECKSUM;
-
-#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
-extern int himax_touch_proc_init(void);
-extern void himax_touch_proc_deinit(void);
-//PROC-START
-#ifdef HX_TP_PROC_FLASH_DUMP
-extern void himax_ts_flash_func(void);
-extern void setFlashBuffer(void);
-extern bool getFlashDumpGoing(void);
-extern uint8_t getSysOperation(void);
-extern void setSysOperation(uint8_t operation);
-#endif
-
-#ifdef HX_TP_PROC_HITOUCH
-extern bool hitouch_is_connect;
-#endif
-
-#ifdef HX_TP_PROC_DIAG
- extern int touch_monitor_stop_flag;
- extern int touch_monitor_stop_limit;
- extern void himax_ts_diag_func(void);
- extern int16_t *getMutualBuffer(void);
- extern int16_t *getMutualNewBuffer(void);
- extern int16_t *getMutualOldBuffer(void);
- extern int16_t *getSelfBuffer(void);
- extern uint8_t getXChannel(void);
- extern uint8_t getYChannel(void);
- extern uint8_t getDiagCommand(void);
- extern void setXChannel(uint8_t x);
- extern void setYChannel(uint8_t y);
- extern void setMutualBuffer(void);
- extern void setMutualNewBuffer(void);
- extern void setMutualOldBuffer(void);
- extern uint8_t coordinate_dump_enable;
- extern struct file *coordinate_fn;
- extern uint8_t diag_coor[128];
-#ifdef HX_TP_PROC_2T2R
- extern int16_t *getMutualBuffer_2(void);
- extern uint8_t getXChannel_2(void);
- extern uint8_t getYChannel_2(void);
- extern void setXChannel_2(uint8_t x);
- extern void setYChannel_2(uint8_t y);
- extern void setMutualBuffer_2(void);
-#endif
-#endif
-//PROC-END
-#endif
-
-extern int himax_parse_dt(struct himax_ts_data *ts,
- struct himax_i2c_platform_data *pdata);
-extern int himax_ts_pinctrl_init(struct himax_ts_data *ts);
-
-static uint8_t vk_press;
-static uint8_t AA_press;
-static uint8_t EN_NoiseFilter;
-static uint8_t Last_EN_NoiseFilter;
-static int hx_point_num; // for himax_ts_work_func use
-static int p_point_num = 0xFFFF;
-static int tpd_key;
-static int tpd_key_old;
-static int probe_fail_flag;
-static bool config_load;
+struct himax_ic_data *ic_data;
+
+static int HX_TOUCH_INFO_POINT_CNT;
+
+static uint8_t vk_press = 0x00;
+static uint8_t AA_press = 0x00;
+static uint8_t EN_NoiseFilter = 0x00;
+static int hx_point_num; /*for himax_ts_work_func use*/
+static int p_point_num = 0xFFFF;
+static int tpd_key = 0x00;
+static int tpd_key_old = 0x00;
+static int probe_fail_flag;
+static bool config_load;
static struct himax_config *config_selected;
-//static int iref_number = 11;
-//static bool iref_found = false;
+/*static int iref_number = 11;*/
+/*static bool iref_found = false;*/
-#ifdef HX_USB_DETECT2
-extern bool USB_Flag;
-#endif
#if defined(CONFIG_FB)
int fb_notifier_callback(struct notifier_block *self,
@@ -134,6 +59,7 @@ static void himax_ts_late_resume(struct early_suspend *h);
int himax_input_register(struct himax_ts_data *ts)
{
int ret;
+
ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) {
ret = -ENOMEM;
@@ -175,25 +101,36 @@ int himax_input_register(struct himax_ts_data *ts)
set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
if (ts->protocol_type == PROTOCOL_TYPE_A) {
- //ts->input_dev->mtsize = ts->nFinger_support;
+ /*ts->input_dev->mtsize = ts->nFinger_support;*/
input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID,
0, 3, 0, 0);
} else {/* PROTOCOL_TYPE_B */
set_bit(MT_TOOL_FINGER, ts->input_dev->keybit);
- input_mt_init_slots(ts->input_dev, ts->nFinger_support,0);
+ input_mt_init_slots(ts->input_dev, ts->nFinger_support, 0);
}
I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n",
- ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
-
- input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0);
- input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,ts->pdata->abs_width_min, ts->pdata->abs_width_max, ts->pdata->abs_pressure_fuzz, 0);
-
-// input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0, ((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0);
-// input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0, (BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max,
+ ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,
+ ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,
+ ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,
+ ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max,
+ ts->pdata->abs_pressure_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,
+ ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max,
+ ts->pdata->abs_pressure_fuzz, 0);
+ input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,
+ ts->pdata->abs_width_min, ts->pdata->abs_width_max,
+ ts->pdata->abs_pressure_fuzz, 0);
+
+/*input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0,
+((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0);*/
+/*input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0,
+(BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0);*/
return input_register_device(ts->input_dev);
}
@@ -201,87 +138,103 @@ int himax_input_register(struct himax_ts_data *ts)
static void calcDataSize(uint8_t finger_num)
{
struct himax_ts_data *ts_data = private_ts;
+
ts_data->coord_data_size = 4 * finger_num;
- ts_data->area_data_size = ((finger_num / 4) + (finger_num % 4 ? 1 : 0)) * 4;
- ts_data->raw_data_frame_size = 128 - ts_data->coord_data_size - ts_data->area_data_size - 4 - 4 - 1;
- ts_data->raw_data_nframes = ((uint32_t)ts_data->x_channel * ts_data->y_channel +
- ts_data->x_channel + ts_data->y_channel) / ts_data->raw_data_frame_size +
- (((uint32_t)ts_data->x_channel * ts_data->y_channel +
- ts_data->x_channel + ts_data->y_channel) % ts_data->raw_data_frame_size)? 1 : 0;
- I("%s: coord_data_size: %d, area_data_size:%d, raw_data_frame_size:%d, raw_data_nframes:%d", __func__, ts_data->coord_data_size, ts_data->area_data_size, ts_data->raw_data_frame_size, ts_data->raw_data_nframes);
+ ts_data->area_data_size = ((finger_num / 4) +
+ (finger_num % 4 ? 1 : 0)) * 4;
+ ts_data->raw_data_frame_size = 128 -
+ ts_data->coord_data_size -
+ ts_data->area_data_size - 4 - 4 - 1;
+
+ ts_data->raw_data_nframes =
+ ((uint32_t)ts_data->x_channel *
+ ts_data->y_channel + ts_data->x_channel + ts_data->y_channel) /
+ ts_data->raw_data_frame_size + (((uint32_t)ts_data->x_channel *
+ ts_data->y_channel + ts_data->x_channel + ts_data->y_channel) %
+ ts_data->raw_data_frame_size) ? 1 : 0;
+
+ I("%s: coord_data_size: %d, area_data_size:%d",
+ __func__, ts_data->coord_data_size, ts_data->area_data_size);
+ I("raw_data_frame_size:%d, raw_data_nframes:%d",
+ ts_data->raw_data_frame_size, ts_data->raw_data_nframes);
}
static void calculate_point_number(void)
{
- HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4 ;
+ HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4;
- if ( (ic_data->HX_MAX_PT % 4) == 0)
- HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4 ;
+ if ((ic_data->HX_MAX_PT % 4) == 0)
+ HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4;
else
- HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) +1) * 4 ;
+ HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) + 1) * 4;
}
-#if 0
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
static int himax_read_Sensor_ID(struct i2c_client *client)
-{
- uint8_t val_high[1], val_low[1], ID0=0, ID1=0;
+{
+ uint8_t val_high[1], val_low[1], ID0 = 0, ID1 = 0;
char data[3];
const int normalRetry = 10;
int sensor_id;
-
- data[0] = 0x56; data[1] = 0x02; data[2] = 0x02;/*ID pin PULL High*/
- i2c_himax_master_write(client, &data[0],3,normalRetry);
- usleep_range(1000, 2000);
- //read id pin high
+ data[0] = 0x56; data[1] = 0x02;
+ data[2] = 0x02;/*ID pin PULL High*/
+ i2c_himax_master_write(client, &data[0], 3, normalRetry);
+ usleep(1000);
+
+ /*read id pin high*/
i2c_himax_read(client, 0x57, val_high, 1, normalRetry);
- data[0] = 0x56; data[1] = 0x01; data[2] = 0x01;/*ID pin PULL Low*/
- i2c_himax_master_write(client, &data[0],3,normalRetry);
- usleep_range(1000, 2000);
+ data[0] = 0x56; data[1] = 0x01;
+ data[2] = 0x01;/*ID pin PULL Low*/
+ i2c_himax_master_write(client, &data[0], 3, normalRetry);
+ usleep(1000);
- //read id pin low
+ /*read id pin low*/
i2c_himax_read(client, 0x57, val_low, 1, normalRetry);
- if((val_high[0] & 0x01) ==0)
- ID0=0x02;/*GND*/
- else if((val_low[0] & 0x01) ==0)
- ID0=0x01;/*Floating*/
+ if ((val_high[0] & 0x01) == 0)
+ ID0 = 0x02;/*GND*/
+ else if ((val_low[0] & 0x01) == 0)
+ ID0 = 0x01;/*Floating*/
else
- ID0=0x04;/*VCC*/
-
- if((val_high[0] & 0x02) ==0)
- ID1=0x02;/*GND*/
- else if((val_low[0] & 0x02) ==0)
- ID1=0x01;/*Floating*/
- else
- ID1=0x04;/*VCC*/
- if((ID0==0x04)&&(ID1!=0x04))
- {
- data[0] = 0x56; data[1] = 0x02; data[2] = 0x01;/*ID pin PULL High,Low*/
- i2c_himax_master_write(client, &data[0],3,normalRetry);
- usleep_range(1000, 2000);
-
- }
- else if((ID0!=0x04)&&(ID1==0x04))
- {
- data[0] = 0x56; data[1] = 0x01; data[2] = 0x02;/*ID pin PULL Low,High*/
- i2c_himax_master_write(client, &data[0],3,normalRetry);
- usleep_range(1000, 2000);
+ ID0 = 0x04;/*VCC*/
- }
- else if((ID0==0x04)&&(ID1==0x04))
- {
- data[0] = 0x56; data[1] = 0x02; data[2] = 0x02;/*ID pin PULL High,High*/
- i2c_himax_master_write(client, &data[0],3,normalRetry);
- usleep_range(1000, 2000);
+ if ((val_high[0] & 0x02) == 0)
+ ID1 = 0x02;/*GND*/
+ else if ((val_low[0] & 0x02) == 0)
+ ID1 = 0x01;/*Floating*/
+ else
+ ID1 = 0x04;/*VCC*/
+ if ((ID0 == 0x04) && (ID1 != 0x04)) {
+ data[0] = 0x56; data[1] = 0x02;
+ data[2] = 0x01;/*ID pin PULL High,Low*/
+ i2c_himax_master_write(client,
+ &data[0], 3, normalRetry);
+ usleep(1000);
+
+ } else if ((ID0 != 0x04) && (ID1 == 0x04)) {
+ data[0] = 0x56; data[1] = 0x01;
+ data[2] = 0x02;/*ID pin PULL Low,High*/
+ i2c_himax_master_write(client,
+ &data[0], 3, normalRetry);
+ usleep(1000);
+
+ } else if ((ID0 == 0x04) && (ID1 == 0x04)) {
+ data[0] = 0x56; data[1] = 0x02;
+ data[2] = 0x02;/*ID pin PULL High,High*/
+ i2c_himax_master_write(client,
+ &data[0], 3, normalRetry);
+ usleep(1000);
- }
- sensor_id=(ID1<<4)|ID0;
+ }
+ sensor_id = (ID1<<4)|ID0;
data[0] = 0xE4; data[1] = sensor_id;
- i2c_himax_master_write(client, &data[0],2,normalRetry);/*Write to MCU*/
- usleep_range(1000, 2000);
+ i2c_himax_master_write(client,
+ &data[0], 2, normalRetry);/*Write to MCU*/
+ usleep(1000);
return sensor_id;
@@ -290,125 +243,173 @@ static int himax_read_Sensor_ID(struct i2c_client *client)
static void himax_power_on_initCMD(struct i2c_client *client)
{
I("%s:\n", __func__);
-
himax_touch_information(client);
-
- //himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM
+ /*himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM */
}
#ifdef HX_AUTO_UPDATE_FW
static int i_update_FW(void)
{
int upgrade_times = 0;
- unsigned char* ImageBuffer = i_CTPM_FW;
- int fullFileLength = sizeof(i_CTPM_FW);
+ int fullFileLength = 0;
int i_FW_VER = 0, i_CFG_VER = 0;
- uint8_t ret = -1, result = 0;
-// uint8_t tmp_addr[4];
-// uint8_t tmp_data[4];
+ int ret = -1, result = 0;
+ /*uint8_t tmp_addr[4];*/
+ /*uint8_t tmp_data[4];*/
int CRC_from_FW = 0;
int CRC_Check_result = 0;
- i_FW_VER = i_CTPM_FW[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[FW_VER_MIN_FLASH_ADDR];
- i_CFG_VER = i_CTPM_FW[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[CFG_VER_MIN_FLASH_ADDR];
+ ret = himax_load_CRC_bin_file(private_ts->client);
+ if (ret < 0) {
+ E("%s: himax_load_CRC_bin_file fail Error Code=%d.\n",
+ __func__, ret);
+ ret = -1;
+ return ret;
+ }
+ I("file name = %s\n", i_CTPM_firmware_name);
+ ret = request_firmware(&i_CTPM_FW,
+ i_CTPM_firmware_name, private_ts->dev);
+ if (ret < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, ret);
+ ret = -2;
+ return ret;
+ }
+
+ if (i_CTPM_FW == NULL) {
+ I("%s: i_CTPM_FW = NULL\n", __func__);
+ ret = -3;
+ return ret;
+ }
+ fullFileLength = i_CTPM_FW->size;
- I("%s: i_fullFileLength = %d\n", __func__,fullFileLength);
+ i_FW_VER = i_CTPM_FW->data[FW_VER_MAJ_FLASH_ADDR]<<8
+ | i_CTPM_FW->data[FW_VER_MIN_FLASH_ADDR];
+ i_CFG_VER = i_CTPM_FW->data[CFG_VER_MAJ_FLASH_ADDR]<<8
+ | i_CTPM_FW->data[CFG_VER_MIN_FLASH_ADDR];
+
+ I("%s: i_fullFileLength = %d\n", __func__, fullFileLength);
himax_sense_off(private_ts->client);
msleep(500);
- CRC_from_FW = himax_check_CRC(private_ts->client,fw_image_64k);
- CRC_Check_result = Calculate_CRC_with_AP(ImageBuffer, CRC_from_FW,fw_image_64k);
- I("%s: Check sum result = %d\n", __func__,CRC_Check_result);
- //I("%s: ic_data->vendor_fw_ver = %X, i_FW_VER = %X,\n", __func__,ic_data->vendor_fw_ver, i_FW_VER);
- //I("%s: ic_data->vendor_config_ver = %X, i_CFG_VER = %X,\n", __func__,ic_data->vendor_config_ver, i_CFG_VER);
-
- if ((CRC_Check_result == 0)|| ( ic_data->vendor_fw_ver < i_FW_VER ) || ( ic_data->vendor_config_ver < i_CFG_VER ))
- {
- himax_int_enable(private_ts->client->irq,0);
+ CRC_from_FW = himax_check_CRC(private_ts->client, fw_image_64k);
+ CRC_Check_result =
+ Calculate_CRC_with_AP((unsigned char *)i_CTPM_FW->data,
+ CRC_from_FW, fw_image_64k);
+ I("%s: Check sum result = %d\n", __func__, CRC_Check_result);
+ /*I("%s: ic_data->vendor_fw_ver = %X, i_FW_VER = %X,\n",
+ __func__, ic_data->vendor_fw_ver, i_FW_VER);*/
+ /*I("%s: ic_data->vendor_config_ver = %X, i_CFG_VER = %X,\n",
+ __func__, ic_data->vendor_config_ver, i_CFG_VER);*/
+
+ if ((CRC_Check_result == 0) ||
+ (ic_data->vendor_fw_ver < i_FW_VER) ||
+ (ic_data->vendor_config_ver < i_CFG_VER)) {
+ himax_int_enable(private_ts->client->irq, 0);
update_retry:
- if(fullFileLength == FW_SIZE_60k){
- ret = fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,ImageBuffer,fullFileLength,false);
- }else if (fullFileLength == FW_SIZE_64k){
- ret = fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,ImageBuffer,fullFileLength,false);
- }else if (fullFileLength == FW_SIZE_124k){
- ret = fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,ImageBuffer,fullFileLength,false);
- }else if (fullFileLength == FW_SIZE_128k){
- ret = fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,ImageBuffer,fullFileLength,false);
- }
- if(ret == 0){
- upgrade_times++;
- E("%s: TP upgrade error, upgrade_times = %d\n", __func__, upgrade_times);
- if(upgrade_times < 3)
- goto update_retry;
- else
- {
- himax_sense_on(private_ts->client, 0x01);
- msleep(120);
-#ifdef HX_ESD_WORKAROUND
- HX_ESD_RESET_ACTIVATE = 1;
-#endif
- result = -1;//upgrade fail
- }
- }
- else if(ret == 1){
-/*
- // 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001) (Lock register R/W from driver)
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
- himax_register_write(private_ts->client, tmp_addr, 1, tmp_data);
-
- // 2. Write driver initial code condition
- // write value from AHB I2C : 0x8001_C603 = 0x000000FF
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x01; tmp_addr[1] = 0xC6; tmp_addr[0] = 0x03;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xFF;
- himax_register_write(private_ts->client, tmp_addr, 1, tmp_data);
-
- // 1. Set DDREG_Req = 0 (0x9000_0020 = 0x0000_0001) (Lock register R/W from driver)
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_register_write(private_ts->client, tmp_addr, 1, tmp_data);
-*/
+ if (fullFileLength == FW_SIZE_60k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_60k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ } else if (fullFileLength == FW_SIZE_64k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_64k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ } else if (fullFileLength == FW_SIZE_124k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_124k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ } else if (fullFileLength == FW_SIZE_128k) {
+ ret = fts_ctpm_fw_upgrade_with_sys_fs_128k
+ (private_ts->client,
+ (unsigned char *)i_CTPM_FW->data,
+ fullFileLength, false);
+ }
+ if (ret == 0) {
+ upgrade_times++;
+ E("%s: TP upgrade error, upgrade_times = %d\n",
+ __func__, upgrade_times);
+ if (upgrade_times < 3)
+ goto update_retry;
+ else {
himax_sense_on(private_ts->client, 0x01);
msleep(120);
#ifdef HX_ESD_WORKAROUND
HX_ESD_RESET_ACTIVATE = 1;
#endif
-
- ic_data->vendor_fw_ver = i_FW_VER;
- ic_data->vendor_config_ver = i_CFG_VER;
- result = 1;//upgrade success
- I("%s: TP upgrade OK\n", __func__);
+ result = -1;/*upgrade fail*/
}
-
- himax_int_enable(private_ts->client->irq,1);
- return result;
- }
- else
- {
+ } else if (ret == 1) {
+ /*
+ // 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001)
+ (Lock register R/W from driver)
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ himax_register_write(private_ts->client,
+ tmp_addr, 1, tmp_data);
+
+ // 2. Write driver initial code condition
+ //write value from AHB I2C:0x8001_C603 = 0x000000FF
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+ tmp_addr[1] = 0xC6; tmp_addr[0] = 0x03;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xFF;
+ himax_register_write(private_ts->client,
+ tmp_addr, 1, tmp_data);
+
+ // 1. Set DDREG_Req = 0(0x9000_0020 = 0x0000_0001)
+ (Lock register R/W from driver)
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_register_write(private_ts->client,
+ tmp_addr, 1, tmp_data);
+ */
himax_sense_on(private_ts->client, 0x01);
- return 0;//NO upgrade
+ msleep(120);
+#ifdef HX_ESD_WORKAROUND
+ HX_ESD_RESET_ACTIVATE = 1;
+#endif
+
+ ic_data->vendor_fw_ver = i_FW_VER;
+ ic_data->vendor_config_ver = i_CFG_VER;
+ result = 1;/*upgrade success*/
+ I("%s: TP upgrade OK\n", __func__);
}
+
+ himax_int_enable(private_ts->client->irq, 1);
+ return result;
+
+ } else {
+ himax_sense_on(private_ts->client, 0x01);
+ return 0;/*NO upgrade*/
+ }
}
-#endif
+#endif
#ifdef HX_RST_PIN_FUNC
-void himax_HW_reset(uint8_t loadconfig,uint8_t int_off)
+void himax_HW_reset(uint8_t loadconfig, uint8_t int_off)
{
struct himax_ts_data *ts = private_ts;
int ret = 0;
return;
if (ts->rst_gpio) {
- if(int_off)
- {
- if (ts->use_irq)
- himax_int_enable(private_ts->client->irq,0);
- else {
- hrtimer_cancel(&ts->timer);
- ret = cancel_work_sync(&ts->work);
- }
+ if (int_off) {
+ if (ts->use_irq)
+ himax_int_enable(private_ts->client->irq, 0);
+ else {
+ hrtimer_cancel(&ts->timer);
+ ret = cancel_work_sync(&ts->work);
}
+ }
I("%s: Now reset the Touch chip.\n", __func__);
@@ -417,51 +418,51 @@ void himax_HW_reset(uint8_t loadconfig,uint8_t int_off)
himax_rst_gpio_set(ts->rst_gpio, 1);
msleep(20);
- if(loadconfig)
- himax_loadSensorConfig(private_ts->client,private_ts->pdata);
+ if (loadconfig)
+ himax_loadSensorConfig(private_ts->client,
+ private_ts->pdata);
- if(int_off)
- {
- if (ts->use_irq)
- himax_int_enable(private_ts->client->irq,1);
- else
- hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
- }
+ if (int_off) {
+ if (ts->use_irq)
+ himax_int_enable(private_ts->client->irq, 1);
+ else
+ hrtimer_start(&ts->timer,
+ ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
}
}
#endif
-int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata)
+int himax_loadSensorConfig(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
{
+ int err = -1;
if (!client) {
E("%s: Necessary parameters client are null!\n", __func__);
- return -EINVAL;
+ return err;
}
-
- if(config_load == false)
- {
- config_selected = kzalloc(sizeof(*config_selected), GFP_KERNEL);
- if (config_selected == NULL) {
- E("%s: alloc config_selected fail!\n", __func__);
- return -ENOMEM;
- }
+ if (config_load == false) {
+ config_selected = kzalloc(sizeof(*config_selected), GFP_KERNEL);
+ if (config_selected == NULL) {
+ E("%s: alloc config_selected fail!\n", __func__);
+ return err;
}
+ }
+ himax_power_on_initCMD(client);
- himax_power_on_initCMD(client);
-
- himax_int_enable(client->irq,0);
- himax_read_FW_ver(client);
+ himax_int_enable(client->irq, 0);
+ himax_read_FW_ver(client);
#ifdef HX_RST_PIN_FUNC
- himax_HW_reset(true,false);
+ himax_HW_reset(true, false);
#endif
- himax_int_enable(client->irq,1);
- I("FW_VER : %X \n",ic_data->vendor_fw_ver);
+ himax_int_enable(client->irq, 1);
+ I("FW_VER : %X\n", ic_data->vendor_fw_ver);
- ic_data->vendor_sensor_id=0x2602;
- I("sensor_id=%x.\n",ic_data->vendor_sensor_id);
+ ic_data->vendor_sensor_id = 0x2602;
+ I("sensor_id=%x.\n", ic_data->vendor_sensor_id);
- himax_sense_on(private_ts->client, 0x01);//1=Flash, 0=SRAM
+ himax_sense_on(private_ts->client, 0x01);/*1=Flash, 0=SRAM*/
msleep(120);
#ifdef HX_ESD_WORKAROUND
HX_ESD_RESET_ACTIVATE = 1;
@@ -474,47 +475,49 @@ int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_
#ifdef HX_ESD_WORKAROUND
void ESD_HW_REST(void)
{
- I("START_Himax TP: ESD - Reset\n");
-
+ I("START_Himax TP: ESD - Reset\n");
+
HX_report_ESD_event();
ESD_00_counter = 0;
ESD_00_Flag = 0;
- /*************************************/
- if (private_ts->protocol_type == PROTOCOL_TYPE_A)
+ /*************************************/
+ if (private_ts->protocol_type == PROTOCOL_TYPE_A)
input_mt_sync(private_ts->input_dev);
- input_report_key(private_ts->input_dev, BTN_TOUCH, 0);
- input_sync(private_ts->input_dev);
- /*************************************/
+ input_report_key(private_ts->input_dev, BTN_TOUCH, 0);
+ input_sync(private_ts->input_dev);
+ /*************************************/
I("END_Himax TP: ESD - Reset\n");
}
#endif
#ifdef HX_HIGH_SENSE
-void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable)
+void himax_set_HSEN_func(struct i2c_client *client, uint8_t HSEN_enable)
{
uint8_t tmp_data[4];
- if(HSEN_enable)
- {
+ if (HSEN_enable) {
I(" %s in", __func__);
- HSEN_bit_retry:
- himax_set_HSEN_enable(client,HSEN_enable);
+HSEN_bit_retry:
+ himax_set_HSEN_enable(client, HSEN_enable);
msleep(20);
- himax_get_HSEN_enable(client,tmp_data);
- I("%s: Read HSEN bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
- ,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
- if(tmp_data[0]!= 0x01)
- {
- I("%s: retry HSEN bit write data[0]=%x \n",__func__,tmp_data[0]);
- goto HSEN_bit_retry;
- }
+ himax_get_HSEN_enable(client, tmp_data);
+ I("%s: Read HSEN bit data[0]=%x data[1]=%x",
+ __func__, tmp_data[0], tmp_data[1]);
+ I("data[2]=%x data[3]=%x\n",
+ tmp_data[2], tmp_data[3]);
+
+ if (tmp_data[0] != 0x01) {
+ I("%s: retry HSEN bit write data[0]=%x\n",
+ __func__, tmp_data[0]);
+ goto HSEN_bit_retry;
+ }
}
}
static void himax_HSEN_func(struct work_struct *work)
{
- struct himax_ts_data *ts = container_of(work, struct himax_ts_data,
- hsen_work.work);
+ struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, hsen_work.work);
himax_set_HSEN_func(ts->client, ts->HSEN_enable);
}
@@ -525,9 +528,10 @@ static void himax_HSEN_func(struct work_struct *work)
#ifdef HX_GESTURE_TRACK
static void gest_pt_log_coordinate(int rx, int tx)
{
- //driver report x y with range 0 - 255 , we scale it up to x/y pixel
- gest_pt_x[gest_pt_cnt] = rx*(ic_data->HX_X_RES)/255;
- gest_pt_y[gest_pt_cnt] = tx*(ic_data->HX_Y_RES)/255;
+ /*driver report x y with range 0 - 255*/
+ /* And we scale it up to x/y coordinates*/
+ gest_pt_x[gest_pt_cnt] = rx * (ic_data->HX_X_RES) / 255;
+ gest_pt_y[gest_pt_cnt] = tx * (ic_data->HX_Y_RES) / 255;
}
#endif
static int himax_parse_wake_event(struct himax_ts_data *ts)
@@ -535,145 +539,143 @@ static int himax_parse_wake_event(struct himax_ts_data *ts)
uint8_t buf[64];
unsigned char check_sum_cal = 0;
#ifdef HX_GESTURE_TRACK
- int tmp_max_x=0x00,tmp_min_x=0xFFFF,tmp_max_y=0x00,tmp_min_y=0xFFFF;
+ int tmp_max_x = 0x00, tmp_min_x = 0xFFFF,
+ tmp_max_y = 0x00, tmp_min_y = 0xFFFF;
int gest_len;
#endif
- int i=0, check_FC = 0, gesture_flag = 0;
+ int i = 0, check_FC = 0, gesture_flag = 0;
himax_burst_enable(ts->client, 0);
- himax_read_event_stack(ts->client,buf,56);
+ himax_read_event_stack(ts->client, buf, 56);
- for(i=0;igest_pt_x[i])
- tmp_min_x=gest_pt_x[i];
- if(tmp_max_ygest_pt_y[i])
- tmp_min_y=gest_pt_y[i];
- }
- I("gest_point x_min= %d, x_max= %d, y_min= %d, y_max= %d\n",tmp_min_x,tmp_max_x,tmp_min_y,tmp_max_y);
- gest_start_x=gest_pt_x[0];
- gn_gesture_coor[0] = gest_start_x;
- gest_start_y=gest_pt_y[0];
- gn_gesture_coor[1] = gest_start_y;
- gest_end_x=gest_pt_x[gest_pt_cnt-1];
- gn_gesture_coor[2] = gest_end_x;
- gest_end_y=gest_pt_y[gest_pt_cnt-1];
- gn_gesture_coor[3] = gest_end_y;
- gest_width = tmp_max_x - tmp_min_x;
- gn_gesture_coor[4] = gest_width;
- gest_height = tmp_max_y - tmp_min_y;
- gn_gesture_coor[5] = gest_height;
- gest_mid_x = (tmp_max_x + tmp_min_x)/2;
- gn_gesture_coor[6] = gest_mid_x;
- gest_mid_y = (tmp_max_y + tmp_min_y)/2;
- gn_gesture_coor[7] = gest_mid_y;
- gn_gesture_coor[8] = gest_mid_x;//gest_up_x
- gn_gesture_coor[9] = gest_mid_y-gest_height/2;//gest_up_y
- gn_gesture_coor[10] = gest_mid_x;//gest_down_x
- gn_gesture_coor[11] = gest_mid_y+gest_height/2; //gest_down_y
- gn_gesture_coor[12] = gest_mid_x-gest_width/2; //gest_left_x
- gn_gesture_coor[13] = gest_mid_y; //gest_left_y
- gn_gesture_coor[14] = gest_mid_x+gest_width/2; //gest_right_x
- gn_gesture_coor[15] = gest_mid_y; //gest_right_y
-
+ if (gest_pt_cnt) {
+ for (i = 0 ; i < gest_pt_cnt ; i++) {
+ if (tmp_max_x < gest_pt_x[i])
+ tmp_max_x = gest_pt_x[i];
+ if (tmp_min_x > gest_pt_x[i])
+ tmp_min_x = gest_pt_x[i];
+ if (tmp_max_y < gest_pt_y[i])
+ tmp_max_y = gest_pt_y[i];
+ if (tmp_min_y > gest_pt_y[i])
+ tmp_min_y = gest_pt_y[i];
}
+ I("gest_point x_min= %d, x_max= %d\n",
+ tmp_min_x, tmp_max_x);
+ I("y_min= %d, y_max= %d\n",
+ tmp_min_y, tmp_max_y);
+ gest_start_x = gest_pt_x[0];
+ gn_gesture_coor[0] = gest_start_x;
+ gest_start_y = gest_pt_y[0];
+ gn_gesture_coor[1] = gest_start_y;
+ gest_end_x = gest_pt_x[gest_pt_cnt - 1];
+ gn_gesture_coor[2] = gest_end_x;
+ gest_end_y = gest_pt_y[gest_pt_cnt - 1];
+ gn_gesture_coor[3] = gest_end_y;
+ gest_width = tmp_max_x - tmp_min_x;
+ gn_gesture_coor[4] = gest_width;
+ gest_height = tmp_max_y - tmp_min_y;
+ gn_gesture_coor[5] = gest_height;
+ gest_mid_x = (tmp_max_x + tmp_min_x) / 2;
+ gn_gesture_coor[6] = gest_mid_x;
+ gest_mid_y = (tmp_max_y + tmp_min_y) / 2;
+ gn_gesture_coor[7] = gest_mid_y;
+ /*gest_up_x*/
+ gn_gesture_coor[8] = gest_mid_x;
+ /*gest_up_y*/
+ gn_gesture_coor[9] = gest_mid_y - gest_height / 2;
+ /*gest_down_x*/
+ gn_gesture_coor[10] = gest_mid_x;
+ /*gest_down_y*/
+ gn_gesture_coor[11] = gest_mid_y + gest_height / 2;
+ /*gest_left_x*/
+ gn_gesture_coor[12] = gest_mid_x - gest_width / 2;
+ /*gest_left_y*/
+ gn_gesture_coor[13] = gest_mid_y;
+ /*gest_right_x*/
+ gn_gesture_coor[14] = gest_mid_x + gest_width / 2;
+ /*gest_right_y*/
+ gn_gesture_coor[15] = gest_mid_y;
+
+ }
}
#endif
- if(gesture_flag != 0x80)
- {
- if(!ts->gesture_cust_en[gesture_flag])
- {
- I("%s NOT report customer key \n ",__func__);
- return 0;//NOT report customer key
- }
- }
- else
- {
- if(!ts->gesture_cust_en[0])
- {
- I("%s NOT report report double click \n",__func__);
- return 0;//NOT report power key
- }
+ if (gesture_flag != 0x80) {
+ if (!ts->gesture_cust_en[gesture_flag]) {
+ I("%s NOT report customer key\n ", __func__);
+ return 0;/*NOT report customer key*/
+ }
+ } else {
+ if (!ts->gesture_cust_en[0]) {
+ I("%s NOT report report double click\n", __func__);
+ return 0;/*NOT report power key*/
+ }
}
- if(gesture_flag == 0x80)
+ if (gesture_flag == 0x80)
return EV_GESTURE_PWR;
else
return gesture_flag;
@@ -685,225 +687,242 @@ void himax_wake_check_func(void)
ret_event = himax_parse_wake_event(private_ts);
switch (ret_event) {
- case EV_GESTURE_PWR:
- KEY_EVENT = KEY_POWER;
+ case EV_GESTURE_PWR:
+ KEY_EVENT = KEY_POWER;
break;
- case EV_GESTURE_01:
- KEY_EVENT = KEY_CUST_01;
+ case EV_GESTURE_01:
+ KEY_EVENT = KEY_CUST_01;
break;
- case EV_GESTURE_02:
- KEY_EVENT = KEY_CUST_02;
+ case EV_GESTURE_02:
+ KEY_EVENT = KEY_CUST_02;
break;
- case EV_GESTURE_03:
- KEY_EVENT = KEY_CUST_03;
+ case EV_GESTURE_03:
+ KEY_EVENT = KEY_CUST_03;
break;
- case EV_GESTURE_04:
- KEY_EVENT = KEY_CUST_04;
+ case EV_GESTURE_04:
+ KEY_EVENT = KEY_CUST_04;
break;
- case EV_GESTURE_05:
- KEY_EVENT = KEY_CUST_05;
+ case EV_GESTURE_05:
+ KEY_EVENT = KEY_CUST_05;
break;
- case EV_GESTURE_06:
- KEY_EVENT = KEY_CUST_06;
+ case EV_GESTURE_06:
+ KEY_EVENT = KEY_CUST_06;
break;
- case EV_GESTURE_07:
- KEY_EVENT = KEY_CUST_07;
+ case EV_GESTURE_07:
+ KEY_EVENT = KEY_CUST_07;
break;
- case EV_GESTURE_08:
- KEY_EVENT = KEY_CUST_08;
+ case EV_GESTURE_08:
+ KEY_EVENT = KEY_CUST_08;
break;
- case EV_GESTURE_09:
- KEY_EVENT = KEY_CUST_09;
+ case EV_GESTURE_09:
+ KEY_EVENT = KEY_CUST_09;
break;
- case EV_GESTURE_10:
- KEY_EVENT = KEY_CUST_10;
+ case EV_GESTURE_10:
+ KEY_EVENT = KEY_CUST_10;
break;
- case EV_GESTURE_11:
- KEY_EVENT = KEY_CUST_11;
+ case EV_GESTURE_11:
+ KEY_EVENT = KEY_CUST_11;
break;
- case EV_GESTURE_12:
- KEY_EVENT = KEY_CUST_12;
+ case EV_GESTURE_12:
+ KEY_EVENT = KEY_CUST_12;
break;
- case EV_GESTURE_13:
- KEY_EVENT = KEY_CUST_13;
+ case EV_GESTURE_13:
+ KEY_EVENT = KEY_CUST_13;
break;
- case EV_GESTURE_14:
- KEY_EVENT = KEY_CUST_14;
+ case EV_GESTURE_14:
+ KEY_EVENT = KEY_CUST_14;
break;
- case EV_GESTURE_15:
- KEY_EVENT = KEY_CUST_15;
+ case EV_GESTURE_15:
+ KEY_EVENT = KEY_CUST_15;
break;
}
- if(ret_event)
- {
- I(" %s SMART WAKEUP KEY event %x press\n",__func__,KEY_EVENT);
- input_report_key(private_ts->input_dev, KEY_EVENT, 1);
- input_sync(private_ts->input_dev);
- //msleep(100);
- I(" %s SMART WAKEUP KEY event %x release\n",__func__,KEY_EVENT);
- input_report_key(private_ts->input_dev, KEY_EVENT, 0);
- input_sync(private_ts->input_dev);
- FAKE_POWER_KEY_SEND=true;
+ if (ret_event) {
+ I(" %s SMART WAKEUP KEY event %x press\n",
+ __func__, KEY_EVENT);
+ input_report_key(private_ts->input_dev, KEY_EVENT, 1);
+ input_sync(private_ts->input_dev);
+ /*msleep(100);*/
+ I(" %s SMART WAKEUP KEY event %x release\n",
+ __func__, KEY_EVENT);
+ input_report_key(private_ts->input_dev, KEY_EVENT, 0);
+ input_sync(private_ts->input_dev);
+ FAKE_POWER_KEY_SEND = true;
#ifdef HX_GESTURE_TRACK
- I("gest_start_x= %d, gest_start_y= %d, gest_end_x= %d, gest_end_y= %d\n",gest_start_x,gest_start_y,
- gest_end_x,gest_end_y);
- I("gest_width= %d, gest_height= %d, gest_mid_x= %d, gest_mid_y= %d\n",gest_width,gest_height,
- gest_mid_x,gest_mid_y);
- I("gest_up_x= %d, gest_up_y= %d, gest_down_x= %d, gest_down_y= %d\n",gn_gesture_coor[8],gn_gesture_coor[9],
- gn_gesture_coor[10],gn_gesture_coor[11]);
- I("gest_left_x= %d, gest_left_y= %d, gest_right_x= %d, gest_right_y= %d\n",gn_gesture_coor[12],gn_gesture_coor[13],
- gn_gesture_coor[14],gn_gesture_coor[15]);
+ I("gest_start_x= %d, gest_start_y= %d\n",
+ gest_start_x, gest_start_y);
+ I("gest_end_x= %d, gest_end_y= %d\n",
+ gest_end_x, gest_end_y);
+ I("gest_width= %d, gest_height= %d\n",
+ gest_width, gest_height);
+ I("gest_mid_x= %d, gest_mid_y= %d\n",
+ gest_mid_x, gest_mid_y);
+ I("gest_up_x= %d, gest_up_y= %d\n",
+ gn_gesture_coor[8], gn_gesture_coor[9]);
+ I("gest_down_x= %d, gest_down_y= %d\n",
+ gn_gesture_coor[10], gn_gesture_coor[11]);
+ I("gest_left_x= %d, gest_left_y= %d\n",
+ gn_gesture_coor[12], gn_gesture_coor[13]);
+ I("gest_right_x= %d, gest_right_y= %d\n",
+ gn_gesture_coor[14], gn_gesture_coor[15]);
#endif
- }
+ }
}
#endif
-static void himax_ts_button_func(int tp_key_index,struct himax_ts_data *ts)
+static void himax_ts_button_func(int tp_key_index, struct himax_ts_data *ts)
{
uint16_t x_position = 0, y_position = 0;
-if ( tp_key_index != 0x00)
- {
- I("virtual key index =%x\n",tp_key_index);
- if ( tp_key_index == 0x01) {
+
+ if (tp_key_index != 0x00) {
+ I("virtual key index =%x\n", tp_key_index);
+ if (tp_key_index == 0x01) {
vk_press = 1;
I("back key pressed\n");
- if (ts->pdata->virtual_key)
- {
- if (ts->button[0].index) {
- x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2;
- y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2;
- }
- if (ts->protocol_type == PROTOCOL_TYPE_A) {
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
- x_position);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
- y_position);
- input_mt_sync(ts->input_dev);
- } else if (ts->protocol_type == PROTOCOL_TYPE_B) {
- input_mt_slot(ts->input_dev, 0);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
- 1);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
- x_position);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
- y_position);
- }
+ if (ts->pdata->virtual_key) {
+ if (ts->button[0].index) {
+ x_position = (ts->button[0].x_range_min
+ + ts->button[0].x_range_max) / 2;
+ y_position = (ts->button[0].y_range_min
+ + ts->button[0].y_range_max) / 2;
}
- else
- input_report_key(ts->input_dev, KEY_BACK, 1);
- }
- else if ( tp_key_index == 0x02) {
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type
+ == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 1);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ }
+ } else
+ input_report_key(ts->input_dev, KEY_BACK, 1);
+ } else if (tp_key_index == 0x02) {
vk_press = 1;
I("home key pressed\n");
- if (ts->pdata->virtual_key)
- {
- if (ts->button[1].index) {
- x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2;
- y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2;
- }
- if (ts->protocol_type == PROTOCOL_TYPE_A) {
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
- x_position);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
- y_position);
- input_mt_sync(ts->input_dev);
- } else if (ts->protocol_type == PROTOCOL_TYPE_B) {
- input_mt_slot(ts->input_dev, 0);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
- 1);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
- x_position);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
- y_position);
- }
+ if (ts->pdata->virtual_key) {
+ if (ts->button[1].index) {
+ x_position = (ts->button[1].x_range_min
+ + ts->button[1].x_range_max) / 2;
+ y_position = (ts->button[1].y_range_min
+ + ts->button[1].y_range_max) / 2;
}
- else
- input_report_key(ts->input_dev, KEY_HOME, 1);
- }
- else if ( tp_key_index == 0x04) {
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type
+ == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 1);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ }
+ } else
+ input_report_key(ts->input_dev, KEY_HOME, 1);
+ } else if (tp_key_index == 0x04) {
vk_press = 1;
I("APP_switch key pressed\n");
- if (ts->pdata->virtual_key)
- {
- if (ts->button[2].index) {
- x_position = (ts->button[2].x_range_min + ts->button[2].x_range_max) / 2;
- y_position = (ts->button[2].y_range_min + ts->button[2].y_range_max) / 2;
- }
- if (ts->protocol_type == PROTOCOL_TYPE_A) {
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
- x_position);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
- y_position);
- input_mt_sync(ts->input_dev);
- } else if (ts->protocol_type == PROTOCOL_TYPE_B) {
- input_mt_slot(ts->input_dev, 0);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER,
- 1);
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE,
- 100);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X,
- x_position);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y,
- y_position);
- }
+ if (ts->pdata->virtual_key) {
+ if (ts->button[2].index) {
+ x_position = (ts->button[2].x_range_min
+ + ts->button[2].x_range_max) / 2;
+ y_position = (ts->button[2].y_range_min
+ + ts->button[2].y_range_max) / 2;
}
- else
- input_report_key(ts->input_dev, KEY_F10, 1);
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, 0);
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ input_mt_sync(ts->input_dev);
+ } else if (ts->protocol_type ==
+ PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, 0);
+
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 1);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, 100);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x_position);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y_position);
+ }
+ } else
+ input_report_key(ts->input_dev, KEY_F10, 1);
}
input_sync(ts->input_dev);
- }
-else/*tp_key_index =0x00*/
- {
+ } else {/*tp_key_index =0x00*/
I("virtual key released\n");
vk_press = 0;
if (ts->protocol_type == PROTOCOL_TYPE_A) {
input_mt_sync(ts->input_dev);
- }
- else if (ts->protocol_type == PROTOCOL_TYPE_B) {
+ } else if (ts->protocol_type == PROTOCOL_TYPE_B) {
input_mt_slot(ts->input_dev, 0);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
+ input_mt_report_slot_state(ts->input_dev,
+ MT_TOOL_FINGER, 0);
}
input_report_key(ts->input_dev, KEY_BACK, 0);
input_report_key(ts->input_dev, KEY_HOME, 0);
input_report_key(ts->input_dev, KEY_F10, 0);
- input_sync(ts->input_dev);
+ input_sync(ts->input_dev);
}
}
@@ -915,8 +934,8 @@ void himax_ts_work(struct himax_ts_data *ts)
uint8_t finger_on = 0;
int32_t loop_i;
uint16_t check_sum_cal = 0;
- int raw_cnt_max ;
- int raw_cnt_rmd ;
+ int raw_cnt_max;
+ int raw_cnt_rmd;
int hx_touch_info_size;
uint8_t coordInfoSize = ts->coord_data_size + ts->area_data_size + 4;
@@ -924,121 +943,111 @@ void himax_ts_work(struct himax_ts_data *ts)
int16_t *mutual_data;
int16_t *self_data;
uint8_t diag_cmd;
- int i;
- int mul_num;
- int self_num;
+ int i;
+ int mul_num;
+ int self_num;
int RawDataLen = 0;
- //coordinate dump start
- char coordinate_char[15+(ic_data->HX_MAX_PT+5)*2*5+2];
- //coordinate dump end
+ /*coordinate dump start*/
+ char coordinate_char[15 + (ic_data->HX_MAX_PT + 5) * 2 * 5 + 2];
+ struct timeval t;
+ struct tm broken;
+ /*coordinate dump end*/
#endif
memset(buf, 0x00, sizeof(buf));
memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
- raw_cnt_max = ic_data->HX_MAX_PT/4;
- raw_cnt_rmd = ic_data->HX_MAX_PT%4;
-
+ raw_cnt_max = ic_data->HX_MAX_PT / 4;
+ raw_cnt_rmd = ic_data->HX_MAX_PT % 4;
#if defined(HX_USB_DETECT2)
himax_cable_detect_func();
#endif
- if (raw_cnt_rmd != 0x00) //more than 4 fingers
- {
- RawDataLen = cal_data_len(raw_cnt_rmd, ic_data->HX_MAX_PT, raw_cnt_max);
- hx_touch_info_size = (ic_data->HX_MAX_PT+raw_cnt_max+2)*4;
- }
- else //less than 4 fingers
- {
- RawDataLen = cal_data_len(raw_cnt_rmd, ic_data->HX_MAX_PT, raw_cnt_max);
- hx_touch_info_size = (ic_data->HX_MAX_PT+raw_cnt_max+1)*4;
+ if (raw_cnt_rmd != 0x00) { /*more than 4 fingers*/
+ RawDataLen = cal_data_len(raw_cnt_rmd,
+ ic_data->HX_MAX_PT, raw_cnt_max);
+ hx_touch_info_size = (ic_data->HX_MAX_PT + raw_cnt_max + 2) * 4;
+ } else { /*less than 4 fingers*/
+ RawDataLen = cal_data_len(raw_cnt_rmd,
+ ic_data->HX_MAX_PT, raw_cnt_max);
+ hx_touch_info_size = (ic_data->HX_MAX_PT + raw_cnt_max + 1) * 4;
}
#ifdef HX_TP_PROC_DIAG
diag_cmd = getDiagCommand();
- if( diag_cmd ){
+ if (diag_cmd) {
ret = read_event_stack(ts->client, buf, 128);
- }
- else{
- if(touch_monitor_stop_flag != 0){
+ } else {
+ if (touch_monitor_stop_flag != 0) {
ret = read_event_stack(ts->client, buf, 128);
- touch_monitor_stop_flag-- ;
- }
- else{
- ret = read_event_stack(ts->client, buf, hx_touch_info_size);
+ touch_monitor_stop_flag--;
+ } else {
+ ret = read_event_stack(ts->client,
+ buf, hx_touch_info_size);
}
}
if (!ret)
#else
- if(!read_event_stack(ts->client, buf, hx_touch_info_size))
-#endif
- {
- E("%s: can't read data from chip!\n", __func__);
- goto err_workqueue_out;
- }
+ if (!read_event_stack(ts->client, buf, hx_touch_info_size))
+#endif
+ {
+ E("%s: can't read data from chip!\n", __func__);
+ goto err_workqueue_out;
+ }
post_read_event_stack(ts->client);
#ifdef HX_ESD_WORKAROUND
- for(i = 0; i < hx_touch_info_size; i++)
- {
- if(buf[i] == 0xED)/*case 1 ESD recovery flow*/
- {
+ for (i = 0; i < hx_touch_info_size; i++) {
+ if (buf[i] == 0xED) { /*case 1 ESD recovery flow*/
check_sum_cal = 1;
- }else if(buf[i] == 0x00)
- {
+ } else if (buf[i] == 0x00) {
ESD_00_Flag = 1;
- }
- else
- {
+ } else {
check_sum_cal = 0;
ESD_00_counter = 0;
- ESD_00_Flag = 0;
+ ESD_00_Flag = 0;
i = hx_touch_info_size;
break;
- }
- }
- if (ESD_00_Flag == 1){
- ESD_00_counter ++;
+ }
}
- if (ESD_00_counter > 1){
+ if (ESD_00_Flag == 1)
+ ESD_00_counter++;
+ if (ESD_00_counter > 1)
check_sum_cal = 2;
+ if (check_sum_cal == 2 && HX_ESD_RESET_ACTIVATE == 0) {
+ I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n");
+ ESD_HW_REST();
+ return;
}
-
- if (check_sum_cal == 2 && HX_ESD_RESET_ACTIVATE == 0)
- {
- I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n");
- ESD_HW_REST();
- return;
- }
-
- if (check_sum_cal == 1 && HX_ESD_RESET_ACTIVATE == 0)
- {
+ if (check_sum_cal == 1 && HX_ESD_RESET_ACTIVATE == 0) {
I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n");
ESD_HW_REST();
return;
- }
- else if (HX_ESD_RESET_ACTIVATE)
- {
+ } else if (HX_ESD_RESET_ACTIVATE) {
#ifdef HX_SMART_WAKEUP
- queue_delayed_work(ts->himax_smwp_wq, &ts->smwp_work, msecs_to_jiffies(50));
+ queue_delayed_work(ts->himax_smwp_wq,
+ &ts->smwp_work, msecs_to_jiffies(50));
#endif
#ifdef HX_HIGH_SENSE
- queue_delayed_work(ts->himax_hsen_wq, &ts->hsen_work, msecs_to_jiffies(50));
+ queue_delayed_work(ts->himax_hsen_wq,
+ &ts->hsen_work, msecs_to_jiffies(50));
#endif
- HX_ESD_RESET_ACTIVATE = 0;/*drop 1st interrupts after chip reset*/
- I("[HIMAX TP MSG]:%s: Back from reset, ready to serve.\n", __func__);
+/*drop 1st interrupts after chip reset*/
+ HX_ESD_RESET_ACTIVATE = 0;
+ I("[HIMAX TP MSG]:%s: Back from reset,ready to serve.\n",
+ __func__);
}
#endif
- for (loop_i = 0, check_sum_cal = 0; loop_i < hx_touch_info_size; loop_i++)
+ for (loop_i = 0, check_sum_cal = 0;
+ loop_i < hx_touch_info_size; loop_i++)
check_sum_cal += buf[loop_i];
-
- if ((check_sum_cal % 0x100 != 0) )
- {
- I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n", check_sum_cal);
+
+ if ((check_sum_cal % 0x100 != 0)) {
+ I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n",
+ check_sum_cal);
return;
}
-
if (ts->debug_log_level & BIT(0)) {
I("%s: raw data:\n", __func__);
for (loop_i = 0; loop_i < hx_touch_info_size; loop_i++) {
@@ -1048,260 +1057,289 @@ void himax_ts_work(struct himax_ts_data *ts)
}
}
- //touch monitor raw data fetch
+ /*touch monitor raw data fetch*/
#ifdef HX_TP_PROC_DIAG
diag_cmd = getDiagCommand();
- if (diag_cmd >= 1 && diag_cmd <= 6)
- {
- //Check 124th byte CRC
- if(!diag_check_sum(hx_touch_info_size, buf))
- {
+ if (diag_cmd >= 1 && diag_cmd <= 6) {
+ /*Check 124th byte CRC*/
+ if (!diag_check_sum(hx_touch_info_size, buf))
goto bypass_checksum_failed_packet;
- }
+
#ifdef HX_TP_PROC_2T2R
- if(Is_2T2R && diag_cmd == 4)
- {
+ if (Is_2T2R && diag_cmd == 4) {
mutual_data = getMutualBuffer_2();
- self_data = getSelfBuffer();
+ self_data = getSelfBuffer();
- // initiallize the block number of mutual and self
+ /* initiallize the block number of mutual and self*/
mul_num = getXChannel_2() * getYChannel_2();
#ifdef HX_EN_SEL_BUTTON
- self_num = getXChannel_2() + getYChannel_2() + ic_data->HX_BT_NUM;
+ self_num = getXChannel_2() +
+ getYChannel_2() + ic_data->HX_BT_NUM;
#else
self_num = getXChannel_2() + getYChannel_2();
#endif
- }
- else
-#endif
+ } else
+#endif
{
mutual_data = getMutualBuffer();
- self_data = getSelfBuffer();
+ self_data = getSelfBuffer();
- // initiallize the block number of mutual and self
+ /* initiallize the block number of mutual and self*/
mul_num = getXChannel() * getYChannel();
#ifdef HX_EN_SEL_BUTTON
- self_num = getXChannel() + getYChannel() + ic_data->HX_BT_NUM;
+ self_num = getXChannel() +
+ getYChannel() + ic_data->HX_BT_NUM;
#else
self_num = getXChannel() + getYChannel();
#endif
}
- diag_parse_raw_data(hx_touch_info_size, RawDataLen, mul_num, self_num, buf, diag_cmd, mutual_data, self_data);
+ diag_parse_raw_data(hx_touch_info_size,
+ RawDataLen, mul_num, self_num, buf,
+ diag_cmd, mutual_data, self_data);
- }
- else if (diag_cmd == 7)
- {
+ } else if (diag_cmd == 7) {
memcpy(&(diag_coor[0]), &buf[0], 128);
}
- //coordinate dump start
- if (coordinate_dump_enable == 1)
- {
- for(i=0; i<(15 + (ic_data->HX_MAX_PT+5)*2*5); i++)
- {
+ /*coordinate dump start*/
+ if (coordinate_dump_enable == 1) {
+ for (i = 0; i < (15 + (ic_data->
+ HX_MAX_PT + 5) * 2 * 5);
+ i++) {
coordinate_char[i] = 0x20;
}
- coordinate_char[15 + (ic_data->HX_MAX_PT+5)*2*5] = 0xD;
- coordinate_char[15 + (ic_data->HX_MAX_PT+5)*2*5 + 1] = 0xA;
+ coordinate_char[15 +
+ (ic_data->HX_MAX_PT + 5) * 2 * 5] = 0xD;
+ coordinate_char[15 +
+ (ic_data->HX_MAX_PT + 5) * 2 * 5 + 1] = 0xA;
}
- //coordinate dump end
+ /*coordinate dump end*/
bypass_checksum_failed_packet:
#endif
- EN_NoiseFilter = (buf[HX_TOUCH_INFO_POINT_CNT+2]>>3);
- //I("EN_NoiseFilter=%d\n",EN_NoiseFilter);
- EN_NoiseFilter = EN_NoiseFilter & 0x01;
- //I("EN_NoiseFilter2=%d\n",EN_NoiseFilter);
+ EN_NoiseFilter = (buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 3);
+ /*I("EN_NoiseFilter=%d\n",EN_NoiseFilter);*/
+ EN_NoiseFilter = EN_NoiseFilter & 0x01;
+ /*I("EN_NoiseFilter2=%d\n",EN_NoiseFilter);*/
#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON)
- tpd_key = (buf[HX_TOUCH_INFO_POINT_CNT+2]>>4);
- if (tpd_key == 0x0F)/*All (VK+AA)leave*/
- {
- tpd_key = 0x00;
- }
- //I("[DEBUG] tpd_key: %x\r\n", tpd_key);
-#else
+ tpd_key = (buf[HX_TOUCH_INFO_POINT_CNT + 2] >> 4);
+ if (tpd_key == 0x0F) {/*All (VK+AA)leave*/
tpd_key = 0x00;
+ }
+ /*I("[DEBUG] tpd_key: %x\r\n", tpd_key);*/
+#else
+ tpd_key = 0x00;
#endif
- p_point_num = hx_point_num;
-
- if (buf[HX_TOUCH_INFO_POINT_CNT] == 0xff)
- hx_point_num = 0;
- else
- hx_point_num= buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f;
-
- // Touch Point information
- if (hx_point_num != 0 ) {
- if(vk_press == 0x00)
- {
- uint16_t old_finger = ts->pre_finger_mask;
- ts->pre_finger_mask = 0;
- finger_num = buf[coordInfoSize - 4] & 0x0F;
- finger_on = 1;
- AA_press = 1;
- for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) {
- int base = loop_i * 4;
- int x = buf[base] << 8 | buf[base + 1];
- int y = (buf[base + 2] << 8 | buf[base + 3]);
- int w = buf[(ts->nFinger_support * 4) + loop_i];
- if(x >= 0 && x <= ts->pdata->abs_x_max && y >= 0 && y <= ts->pdata->abs_y_max){
- finger_num--;
-
- if ((ts->debug_log_level & BIT(3)) > 0)
- {
- if (old_finger >> loop_i == 0)
- {
- if (ts->useScreenRes)
- {
- I("status: Screen:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n",
- loop_i+1, x * ts->widthFactor >> SHIFTBITS,
- y * ts->heightFactor >> SHIFTBITS, w, EN_NoiseFilter);
- }
- else
- {
- I("status: Raw:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n",
- loop_i+1, x, y, w, EN_NoiseFilter);
- }
- }
- }
-
- if (ts->protocol_type == PROTOCOL_TYPE_B)
- {
- input_mt_slot(ts->input_dev, loop_i);
- }
-
- input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
- input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w);
- input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
- input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y);
-
- if (ts->protocol_type == PROTOCOL_TYPE_A)
- {
- input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, loop_i);
- input_mt_sync(ts->input_dev);
- }
- else
- {
- ts->last_slot = loop_i;
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1);
- }
-
- if (!ts->first_pressed)
- {
- ts->first_pressed = 1;
- I("S1@%d, %d\n", x, y);
- }
-
- ts->pre_finger_data[loop_i][0] = x;
- ts->pre_finger_data[loop_i][1] = y;
-
-
- if (ts->debug_log_level & BIT(1))
- I("Finger %d=> X:%d, Y:%d W:%d, Z:%d, F:%d, N:%d\n",
- loop_i + 1, x, y, w, w, loop_i + 1, EN_NoiseFilter);
-
- ts->pre_finger_mask = ts->pre_finger_mask + (1 << loop_i);
-
- } else {
- if (ts->protocol_type == PROTOCOL_TYPE_B)
- {
- input_mt_slot(ts->input_dev, loop_i);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
- }
-
- if (loop_i == 0 && ts->first_pressed == 1)
- {
- ts->first_pressed = 2;
- I("E1@%d, %d\n",
- ts->pre_finger_data[0][0] , ts->pre_finger_data[0][1]);
- }
- if ((ts->debug_log_level & BIT(3)) > 0)
- {
- if (old_finger >> loop_i == 1)
- {
- if (ts->useScreenRes)
- {
- I("status: Screen:F:%02d Up, X:%d, Y:%d, N:%d\n",
- loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
- ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter);
- }
- else
- {
- I("status: Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",
- loop_i+1, ts->pre_finger_data[loop_i][0],
- ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter);
- }
- }
- }
- }
- }
+ p_point_num = hx_point_num;
+
+ if (buf[HX_TOUCH_INFO_POINT_CNT] == 0xff)
+ hx_point_num = 0;
+ else
+ hx_point_num = buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f;
+
+ /* Touch Point information*/
+ if ((hx_point_num != 0) && (vk_press == 0x00)) {
+ uint16_t old_finger = ts->pre_finger_mask;
- }else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) {
- //temp_x[0] = 0xFFFF;
- //temp_y[0] = 0xFFFF;
- //temp_x[1] = 0xFFFF;
- //temp_y[1] = 0xFFFF;
- himax_ts_button_func(tpd_key,ts);
- finger_on = 0;
+ ts->pre_finger_mask = 0;
+ finger_num = buf[coordInfoSize - 4] & 0x0F;
+ finger_on = 1;
+ AA_press = 1;
+ for (i = 0; i < ts->nFinger_support; i++) {
+ int base = i * 4;
+ int x = buf[base] << 8 | buf[base + 1];
+ int y = (buf[base + 2] << 8 | buf[base + 3]);
+ int w = buf[(ts->nFinger_support * 4) + i];
+
+ if (x >= 0 && x <= ts->pdata->abs_x_max
+ && y >= 0 && y <= ts->pdata->abs_y_max) {
+ finger_num--;
+ if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 0))
+ && (ts->useScreenRes)) {
+ I("status:Screen:F:%02d", i + 1);
+ I("Down,X:%d,Y:%d,W:%d,N:%d\n",
+ x * ts->widthFactor >> SHIFTBITS,
+ y * ts->heightFactor >> SHIFTBITS,
+ w, EN_NoiseFilter);
+ } else if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 0))
+ && !(ts->useScreenRes)) {
+ I("status:Raw:F:%02d", i + 1);
+ I("Down,X:%d,Y:%d,W:%d,N:%d\n",
+ x, y, w, EN_NoiseFilter);
}
- input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
- input_sync(ts->input_dev);
- } else if (hx_point_num == 0){
- if(AA_press)
- {
- // leave event
- finger_on = 0;
- AA_press = 0;
- if (ts->protocol_type == PROTOCOL_TYPE_A)
- input_mt_sync(ts->input_dev);
- for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) {
- if (((ts->pre_finger_mask >> loop_i) & 1) == 1) {
- if (ts->protocol_type == PROTOCOL_TYPE_B) {
- input_mt_slot(ts->input_dev, loop_i);
- input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
- }
- }
- }
- if (ts->pre_finger_mask > 0) {
- for (loop_i = 0; loop_i < ts->nFinger_support && (ts->debug_log_level & BIT(3)) > 0; loop_i++) {
- if (((ts->pre_finger_mask >> loop_i) & 1) == 1) {
- if (ts->useScreenRes) {
- I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS,
- ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter);
- } else {
- I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter);
- }
- }
- }
- ts->pre_finger_mask = 0;
+ if (ts->protocol_type == PROTOCOL_TYPE_B)
+ input_mt_slot(ts->input_dev, i);
+
+ input_report_abs(ts->input_dev,
+ ABS_MT_TOUCH_MAJOR, w);
+ input_report_abs(ts->input_dev,
+ ABS_MT_WIDTH_MAJOR, w);
+ input_report_abs(ts->input_dev,
+ ABS_MT_PRESSURE, w);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_X, x);
+ input_report_abs(ts->input_dev,
+ ABS_MT_POSITION_Y, y);
+
+ if (ts->protocol_type == PROTOCOL_TYPE_A) {
+ input_report_abs(ts->input_dev,
+ ABS_MT_TRACKING_ID, i);
+ input_mt_sync(ts->input_dev);
+ } else {
+ ts->last_slot = i;
+ input_mt_report_slot_state
+ (ts->input_dev,
+ MT_TOOL_FINGER, 1);
}
- if (ts->first_pressed == 1) {
- ts->first_pressed = 2;
- I("E1@%d, %d\n",ts->pre_finger_data[0][0] , ts->pre_finger_data[0][1]);
+ if (!ts->first_pressed) {
+ ts->first_pressed = 1;
+ I("S1@%d, %d\n", x, y);
}
- if (ts->debug_log_level & BIT(1))
- I("All Finger leave\n");
+ ts->pre_finger_data[i][0] = x;
+ ts->pre_finger_data[i][1] = y;
+
+ if (ts->debug_log_level & BIT(1)) {
+ I("Finger %d=> X:%d,Y:%d,W:%d,",
+ i + 1, x, y, w);
+ I("Z:%d,F:%d,N:%d\n",
+ w, i + 1, EN_NoiseFilter);
+ }
+ ts->pre_finger_mask =
+ ts->pre_finger_mask + (1 << i);
+ } else {
+ if (ts->protocol_type == PROTOCOL_TYPE_B) {
+ input_mt_slot(ts->input_dev, i);
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 0);
+ }
+ if (i == 0 && ts->first_pressed == 1) {
+ ts->first_pressed = 2;
+ I("E1@%d, %d\n",
+ ts->pre_finger_data[0][0],
+ ts->pre_finger_data[0][1]);
+ }
+ if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 1))
+ && (ts->useScreenRes)) {
+ I("status:Screen:F:%02d,Up,X:%d,Y:%d\n",
+ i + 1, ts->pre_finger_data[i][0]
+ * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[i][1]
+ * ts->heightFactor >> SHIFTBITS);
+ } else if ((((ts->debug_log_level & BIT(3)) > 0)
+ && (old_finger >> i == 1))
+ && !(ts->useScreenRes)) {
+ I("status:Raw:F:%02d,Up,X:%d,Y:%d\n",
+ i + 1, ts->pre_finger_data[i][0],
+ ts->pre_finger_data[i][1]);
+ }
}
- else if (tpd_key != 0x00) {
- himax_ts_button_func(tpd_key,ts);
- finger_on = 1;
+ }
+ input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+ input_sync(ts->input_dev);
+ } else if ((hx_point_num != 0)
+ && ((tpd_key_old != 0x00) && (tpd_key == 0x00))) {
+ /*temp_x[0] = 0xFFFF;*/
+ /*temp_y[0] = 0xFFFF;*/
+ /*temp_x[1] = 0xFFFF;*/
+ /*temp_y[1] = 0xFFFF;*/
+ himax_ts_button_func(tpd_key, ts);
+ finger_on = 0;
+ input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+ input_sync(ts->input_dev);
+ } else if (hx_point_num == 0) {
+ if (AA_press) {
+ /*leave event*/
+ finger_on = 0;
+ AA_press = 0;
+ if (ts->protocol_type == PROTOCOL_TYPE_A)
+ input_mt_sync(ts->input_dev);
+
+ for (i = 0 ; i < ts->nFinger_support ; i++) {
+ if ((((ts->pre_finger_mask >> i) & 1) == 1)
+ && (ts->protocol_type == PROTOCOL_TYPE_B)) {
+ input_mt_slot(ts->input_dev, i);
+ input_mt_report_slot_state
+ (ts->input_dev, MT_TOOL_FINGER, 0);
+ }
}
- else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) {
- himax_ts_button_func(tpd_key,ts);
- finger_on = 0;
+ if (ts->pre_finger_mask > 0) {
+ for (i = 0; i < ts->nFinger_support
+ && (ts->debug_log_level & BIT(3)) > 0; i++) {
+ if ((((ts->pre_finger_mask
+ >> i) & 1) == 1)
+ && (ts->useScreenRes)) {
+ I("status:%X,", 0);
+ I("Screen:F:%02d,", i + 1);
+ I("Up,X:%d,Y:%d\n",
+ ts->pre_finger_data[i][0]
+ * ts->widthFactor >> SHIFTBITS,
+ ts->pre_finger_data[i][1]
+ * ts->heightFactor >> SHIFTBITS
+ );
+ } else if ((((ts->pre_finger_mask
+ >> i) & 1) == 1)
+ && !(ts->useScreenRes)) {
+ I("status:%X,", 0);
+ I("Screen:F:%02d,", i + 1);
+ I("Up,X:%d,Y:%d\n",
+ ts->pre_finger_data[i][0],
+ ts->pre_finger_data[i][1]);
+ }
+ }
+ ts->pre_finger_mask = 0;
+ }
+
+ if (ts->first_pressed == 1) {
+ ts->first_pressed = 2;
+ I("E1@%d, %d\n", ts->pre_finger_data[0][0],
+ ts->pre_finger_data[0][1]);
}
- input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
- input_sync(ts->input_dev);
+
+ if (ts->debug_log_level & BIT(1))
+ I("All Finger leave\n");
+
+#ifdef HX_TP_PROC_DIAG
+ /*coordinate dump start*/
+ if (coordinate_dump_enable == 1) {
+ do_gettimeofday(&t);
+ time_to_tm(t.tv_sec, 0, &broken);
+ snprintf(&coordinate_char[0], 15,
+ "%2d:%2d:%2d:%lu,", broken.tm_hour,
+ broken.tm_min, broken.tm_sec,
+ t.tv_usec / 1000);
+
+ snprintf(&coordinate_char[15], 10,
+ "Touch up!");
+
+ coordinate_fn->f_op->write
+ (coordinate_fn, &coordinate_char[0],
+ 15 + (ic_data->HX_MAX_PT + 5)
+ * 2 * sizeof(char) * 5 + 2,
+ &coordinate_fn->f_pos);
+ }
+ /*coordinate dump end*/
+#endif
+ } else if (tpd_key != 0x00) {
+ himax_ts_button_func(tpd_key, ts);
+ finger_on = 1;
+ } else if ((tpd_key_old != 0x00) && (tpd_key == 0x00)) {
+ himax_ts_button_func(tpd_key, ts);
+ finger_on = 0;
}
- tpd_key_old = tpd_key;
- Last_EN_NoiseFilter = EN_NoiseFilter;
+ input_report_key(ts->input_dev, BTN_TOUCH, finger_on);
+ input_sync(ts->input_dev);
+ }
+ tpd_key_old = tpd_key;
workqueue_out:
return;
@@ -1310,7 +1348,7 @@ void himax_ts_work(struct himax_ts_data *ts)
I("%s: Now reset the Touch chip.\n", __func__);
#ifdef HX_RST_PIN_FUNC
- himax_HW_reset(true,false);
+ himax_HW_reset(true, false);
#endif
goto workqueue_out;
@@ -1329,6 +1367,7 @@ enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer)
static void himax_cable_tp_status_handler_func(int connect_status)
{
struct himax_ts_data *ts;
+
I("Touch: cable change to %d\n", connect_status);
ts = private_ts;
if (ts->cable_config) {
@@ -1342,18 +1381,23 @@ static void himax_cable_tp_status_handler_func(int connect_status)
ts->usb_connected = 0x00;
}
- i2c_himax_master_write(ts->client, ts->cable_config,
- sizeof(ts->cable_config), HIMAX_I2C_RETRY_TIMES);
+ i2c_himax_master_write(ts->client,
+ ts->cable_config,
+ sizeof(ts->cable_config),
+ HIMAX_I2C_RETRY_TIMES);
- I("%s: Cable status change: 0x%2.2X\n", __func__, ts->cable_config[1]);
+ I("%s: Cable status change: 0x%2.2X\n",
+ __func__, ts->cable_config[1]);
} else
- I("%s: Cable status is the same as previous one, ignore.\n", __func__);
+ I("%s: Cable status is same, ignore.\n",
+ __func__);
} else {
if (connect_status)
ts->usb_connected = 0x01;
else
ts->usb_connected = 0x00;
- I("%s: Cable status remembered: 0x%2.2X\n", __func__, ts->usb_connected);
+ I("%s: Cable status remembered: 0x%2.2X\n",
+ __func__, ts->usb_connected);
}
}
}
@@ -1373,16 +1417,20 @@ void himax_cable_detect_func(void)
struct himax_ts_data *ts;
u32 connect_status = 0;
- connect_status = USB_Flag;//upmu_is_chr_det();
+ connect_status = USB_Flag;/*upmu_is_chr_det();*/
ts = private_ts;
- //I("Touch: cable status=%d, cable_config=%p, usb_connected=%d \n", connect_status,ts->cable_config, ts->usb_connected);
+ /*I("Touch: cable status=%d, cable_config=%p,
+ usb_connected=%d\n", connect_status,
+ ts->cable_config, ts->usb_connected);*/
+
if (ts->cable_config) {
if ((!!connect_status) != ts->usb_connected) {
- //notify USB plug/unplug
- // 0x9008_8060 ==> 0x0000_0000/0001
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x60;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00;
-
+ /*notify USB plug/unplug*/
+ /*0x9008_8060 ==> 0x0000_0000/0001*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x60;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
if (!!connect_status) {
tmp_data[0] = 0x01;
ts->usb_connected = 0x01;
@@ -1393,10 +1441,13 @@ void himax_cable_detect_func(void)
himax_flash_write_burst(ts->client, tmp_addr, tmp_data);
- I("%s: Cable status change: 0x%2.2X\n", __func__, ts->usb_connected);
- }
- //else
- //I("%s: Cable status is the same as previous one, ignore.\n", __func__);
+ I("%s: Cable status change: 0x%2.2X\n",
+ __func__, ts->usb_connected);
+ }
+ /*else*/
+ /*I("%s: Cable status is the same as previous one,
+ ignore.\n", __func__);*/
+
}
}
#endif
@@ -1417,52 +1468,52 @@ int himax_fb_register(struct himax_ts_data *ts)
#endif
#ifdef HX_SMART_WAKEUP
-void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable)
+void himax_set_SMWP_func(struct i2c_client *client, uint8_t SMWP_enable)
{
uint8_t tmp_data[4];
- if(SMWP_enable)
- {
- SMWP_bit_retry:
+ if (SMWP_enable) {
+SMWP_bit_retry:
himax_set_SMWP_enable(client, SMWP_enable);
msleep(20);
- himax_get_SMWP_enable(client,tmp_data);
- I("%s: Read SMWP bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
- ,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
- if(tmp_data[0]!= 0x01)
- {
- I("%s: retry SMWP bit write data[0]=%x \n",__func__,tmp_data[0]);
- goto SMWP_bit_retry;
- }
+ himax_get_SMWP_enable(client, tmp_data);
+I("%s: Read SMWP bit data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
+__func__, tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);
+
+ if (tmp_data[0] != 0x01) {
+ I("%s: retry SMWP bit write data[0]=%x\n",
+ __func__, tmp_data[0]);
+ goto SMWP_bit_retry;
+ }
}
}
static void himax_SMWP_work(struct work_struct *work)
{
- struct himax_ts_data *ts = container_of(work, struct himax_ts_data,
- smwp_work.work);
+ struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, smwp_work.work);
I(" %s in", __func__);
- himax_set_SMWP_func(ts->client,ts->SMWP_enable);
+ himax_set_SMWP_func(ts->client, ts->SMWP_enable);
}
#endif
-#ifdef HX_TP_PROC_FLASH_DUMP
+#ifdef HX_TP_PROC_FLASH_DUMP
static void himax_ts_flash_work_func(struct work_struct *work)
{
himax_ts_flash_func();
}
#endif
-#ifdef HX_TP_PROC_DIAG
+#ifdef HX_TP_PROC_DIAG
static void himax_ts_diag_work_func(struct work_struct *work)
{
himax_ts_diag_func();
}
#endif
-void himax_ts_init(struct himax_ts_data *ts)
+bool himax_ts_init(struct himax_ts_data *ts)
{
int ret = 0, err = 0;
struct himax_i2c_platform_data *pdata;
@@ -1476,15 +1527,14 @@ void himax_ts_init(struct himax_ts_data *ts)
/* Set pinctrl in active state */
if (ts->ts_pinctrl) {
ret = pinctrl_select_state(ts->ts_pinctrl,
- ts->pinctrl_state_active);
- if (ret < 0) {
- E("Failed to set pin in active state %d",ret);
- }
+ ts->pinctrl_state_active);
+ if (ret < 0)
+ E("Failed to set pin in active state %d", ret);
}
himax_burst_enable(client, 0);
- //Get Himax IC Type / FW information / Calculate the point number
+ /*Get Himax IC Type / FW information / Calculate the point number */
if (himax_check_chip_version(ts->client) == false) {
E("Himax chip doesn NOT EXIST");
goto err_ic_package_failed;
@@ -1496,10 +1546,9 @@ void himax_ts_init(struct himax_ts_data *ts)
if (pdata->virtual_key)
ts->button = pdata->virtual_key;
-#ifdef HX_TP_PROC_FLASH_DUMP
+#ifdef HX_TP_PROC_FLASH_DUMP
ts->flash_wq = create_singlethread_workqueue("himax_flash_wq");
- if (!ts->flash_wq)
- {
+ if (!ts->flash_wq) {
E("%s: create flash workqueue failed\n", __func__);
err = -ENOMEM;
goto err_create_wq_failed;
@@ -1511,10 +1560,9 @@ void himax_ts_init(struct himax_ts_data *ts)
setFlashBuffer();
#endif
-#ifdef HX_TP_PROC_DIAG
+#ifdef HX_TP_PROC_DIAG
ts->himax_diag_wq = create_singlethread_workqueue("himax_diag");
- if (!ts->himax_diag_wq)
- {
+ if (!ts->himax_diag_wq) {
E("%s: create diag workqueue failed\n", __func__);
err = -ENOMEM;
goto err_create_wq_failed;
@@ -1526,40 +1574,42 @@ himax_read_FW_ver(client);
#ifdef HX_AUTO_UPDATE_FW
I(" %s in", __func__);
- if(i_update_FW() == false)
- I("NOT Have new FW=NOT UPDATE=\n");
+ if (i_update_FW() <= 0)
+ I("FW NOT UPDATE=\n");
else
I("Have new FW=UPDATE=\n");
#endif
- //Himax Power On and Load Config
+ /*Himax Power On and Load Config*/
if (himax_loadSensorConfig(client, pdata) < 0) {
- E("%s: Load Sesnsor configuration failed, unload driver.\n", __func__);
+ E("%s: Load Sesnsor config failed,unload driver.\n",
+ __func__);
goto err_detect_failed;
}
calculate_point_number();
#ifdef HX_TP_PROC_DIAG
- setXChannel(ic_data->HX_RX_NUM); // X channel
- setYChannel(ic_data->HX_TX_NUM); // Y channel
+ setXChannel(ic_data->HX_RX_NUM); /*X channel*/
+ setYChannel(ic_data->HX_TX_NUM); /*Y channel*/
setMutualBuffer();
setMutualNewBuffer();
setMutualOldBuffer();
if (getMutualBuffer() == NULL) {
E("%s: mutual buffer allocate fail failed\n", __func__);
- return;
+ return false;
}
#ifdef HX_TP_PROC_2T2R
- if(Is_2T2R){
- setXChannel_2(ic_data->HX_RX_NUM_2); // X channel
- setYChannel_2(ic_data->HX_TX_NUM_2); // Y channel
+ if (Is_2T2R) {
+ setXChannel_2(ic_data->HX_RX_NUM_2); /*X channel*/
+ setYChannel_2(ic_data->HX_TX_NUM_2); /*Y channel*/
setMutualBuffer_2();
if (getMutualBuffer_2() == NULL) {
- E("%s: mutual buffer 2 allocate fail failed\n", __func__);
- return;
+ E("%s: mutual buffer 2 allocate fail failed\n",
+ __func__);
+ return false;
}
}
#endif
@@ -1572,7 +1622,7 @@ himax_read_FW_ver(client);
ts->x_channel = ic_data->HX_RX_NUM;
ts->y_channel = ic_data->HX_TX_NUM;
ts->nFinger_support = ic_data->HX_MAX_PT;
- //calculate the i2c data size
+ /*calculate the i2c data size*/
calcDataSize(ts->nFinger_support);
I("%s: calcDataSize complete\n", __func__);
#ifdef CONFIG_OF
@@ -1584,14 +1634,13 @@ himax_read_FW_ver(client);
pdata->cable_config[1] = 0x00;
#endif
ts->suspended = false;
-#if defined(HX_USB_DETECT)||defined(HX_USB_DETECT2)
+#if defined(HX_USB_DETECT) || defined(HX_USB_DETECT2)
ts->usb_connected = 0x00;
ts->cable_config = pdata->cable_config;
#endif
ts->protocol_type = pdata->protocol_type;
I("%s: Use Protocol Type %c\n", __func__,
ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B');
-
ret = himax_input_register(ts);
if (ret) {
E("%s: Unable to register %s input device\n",
@@ -1599,8 +1648,9 @@ himax_read_FW_ver(client);
goto err_input_register_device_failed;
}
#ifdef HX_SMART_WAKEUP
- ts->SMWP_enable=0;
- wake_lock_init(&ts->ts_SMWP_wake_lock, WAKE_LOCK_SUSPEND, HIMAX_common_NAME);
+ ts->SMWP_enable = 0;
+ wakeup_source_init(&ts->ts_SMWP_wake_lock,
+ WAKE_LOCK_SUSPEND, HIMAX_common_NAME);
ts->himax_smwp_wq = create_singlethread_workqueue("HMX_SMWP_WORK");
if (!ts->himax_smwp_wq) {
@@ -1611,7 +1661,7 @@ himax_read_FW_ver(client);
INIT_DELAYED_WORK(&ts->smwp_work, himax_SMWP_work);
#endif
#ifdef HX_HIGH_SENSE
- ts->HSEN_enable=0;
+ ts->HSEN_enable = 0;
ts->himax_hsen_wq = create_singlethread_workqueue("HMX_HSEN_WORK");
if (!ts->himax_hsen_wq) {
E(" allocate himax_hsen_wq failed\n");
@@ -1633,7 +1683,7 @@ himax_read_FW_ver(client);
err = himax_ts_register_interrupt(ts->client);
if (err)
goto err_register_interrupt_failed;
- return;
+ return true;
err_register_interrupt_failed:
#ifdef HX_HIGH_SENSE
@@ -1641,26 +1691,26 @@ himax_read_FW_ver(client);
#endif
#ifdef HX_SMART_WAKEUP
err_smwp_wq_failed:
- wake_lock_destroy(&ts->ts_SMWP_wake_lock);
+ wakeup_source_trash(&ts->ts_SMWP_wake_lock);
#endif
err_input_register_device_failed:
input_free_device(ts->input_dev);
err_detect_failed:
-#ifdef HX_TP_PROC_FLASH_DUMP
+#ifdef HX_TP_PROC_FLASH_DUMP
err_create_wq_failed:
#endif
err_ic_package_failed:
-
-return;
+return false;
}
-int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id)
+int himax_chip_common_probe(struct i2c_client *client,
+const struct i2c_device_id *id)
{
int err = 0;
struct himax_ts_data *ts;
struct himax_i2c_platform_data *pdata;
- //Check I2C functionality
+ /*Check I2C functionality*/
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
E("%s: i2c check functionality error\n", __func__);
err = -ENODEV;
@@ -1677,6 +1727,7 @@ int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_i
i2c_set_clientdata(client, ts);
ts->client = client;
ts->dev = &client->dev;
+ mutex_init(&ts->rw_lock);
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (pdata == NULL) { /*Allocate Platform data space*/
@@ -1691,7 +1742,8 @@ int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_i
}
#ifdef CONFIG_OF
- if (client->dev.of_node) { /*DeviceTree Init Platform_data*/
+ /*DeviceTree Init Platform_data*/
+ if (client->dev.of_node) {
err = himax_parse_dt(ts, pdata);
if (err < 0) {
I(" pdata is NULL for DT\n");
@@ -1704,12 +1756,11 @@ int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_i
ts->rst_gpio = pdata->gpio_reset;
#endif
-himax_gpio_power_config(ts->client, pdata);
+ himax_gpio_power_config(ts->client, pdata);
err = himax_ts_pinctrl_init(ts);
- if (err || ts->ts_pinctrl == NULL) {
+ if (err || ts->ts_pinctrl == NULL)
E(" Pinctrl init failed\n");
- }
#ifndef CONFIG_OF
if (pdata->power) {
@@ -1736,7 +1787,7 @@ himax_gpio_power_config(ts->client, pdata);
}
#endif
- return 0;
+ return 0;
#ifdef CONFIG_FB
err_fb_notif_wq_create:
@@ -1783,8 +1834,10 @@ int himax_chip_common_remove(struct i2c_client *client)
himax_touch_proc_deinit();
#endif
#ifdef CONFIG_FB
- if (fb_unregister_client(&ts->fb_notif))
- dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n");
+ if (fb_unregister_client(&ts->fb_notif)) {
+ dev_err(&client->dev,
+ "Error occurred while unregistering fb_notifier.\n");
+ }
#endif
if (!ts->use_irq)
@@ -1810,7 +1863,7 @@ int himax_chip_common_remove(struct i2c_client *client)
}
}
#ifdef HX_SMART_WAKEUP
- wake_lock_destroy(&ts->ts_SMWP_wake_lock);
+ wakeup_source_trash(&ts->ts_SMWP_wake_lock);
#endif
kfree(ts);
@@ -1822,38 +1875,36 @@ int himax_chip_common_suspend(struct himax_ts_data *ts)
{
int ret;
- if(ts->suspended)
- {
- I("%s: Already suspended. Skipped. \n", __func__);
+ if (ts->suspended) {
+ I("%s: Already suspended. Skipped.\n", __func__);
return 0;
- }
- else
- {
+
+ } else {
ts->suspended = true;
- I("%s: enter \n", __func__);
+ I("%s: enter\n", __func__);
}
#ifdef HX_TP_PROC_FLASH_DUMP
- if (getFlashDumpGoing())
- {
- I("[himax] %s: Flash dump is going, reject suspend\n",__func__);
+ if (getFlashDumpGoing()) {
+ I("[himax] %s: Flash dump is going,reject suspend\n",
+ __func__);
return 0;
}
#endif
#ifdef HX_TP_PROC_HITOUCH
- if(hitouch_is_connect)
- {
- I("[himax] %s: Hitouch connect, reject suspend\n",__func__);
+ if (hitouch_is_connect) {
+ I("[himax] %s: Hitouch connect,reject suspend\n",
+ __func__);
return 0;
}
#endif
#ifdef HX_SMART_WAKEUP
- if(ts->SMWP_enable)
- {
+ if (ts->SMWP_enable) {
atomic_set(&ts->suspend_mode, 1);
ts->pre_finger_mask = 0;
- FAKE_POWER_KEY_SEND=false;
- I("[himax] %s: SMART_WAKEUP enable, reject suspend\n",__func__);
+ FAKE_POWER_KEY_SEND = false;
+ I("[himax] %s: SMART_WAKEUP enable,reject suspend\n",
+ __func__);
return 0;
}
#endif
@@ -1864,19 +1915,18 @@ int himax_chip_common_suspend(struct himax_ts_data *ts)
if (!ts->use_irq) {
ret = cancel_work_sync(&ts->work);
if (ret)
- himax_int_enable(ts->client->irq,1);
+ himax_int_enable(ts->client->irq, 1);
}
- //ts->first_pressed = 0;
+ /*ts->first_pressed = 0;*/
atomic_set(&ts->suspend_mode, 1);
ts->pre_finger_mask = 0;
if (ts->ts_pinctrl) {
ret = pinctrl_select_state(ts->ts_pinctrl,
ts->pinctrl_state_suspend);
- if (ret < 0) {
+ if (ret < 0)
E("Failed to get idle pinctrl state %d\n", ret);
- }
}
if (ts->pdata->powerOff3V3 && ts->pdata->power)
@@ -1889,20 +1939,16 @@ int himax_chip_common_resume(struct himax_ts_data *ts)
{
int retval;
- I("%s: enter \n", __func__);
+ I("%s: enter\n", __func__);
if (ts->pdata->powerOff3V3 && ts->pdata->power)
ts->pdata->power(1);
-
-
- /*************************************/
+
if (ts->protocol_type == PROTOCOL_TYPE_A)
- input_mt_sync(ts->input_dev);
+ input_mt_sync(ts->input_dev);
input_report_key(ts->input_dev, BTN_TOUCH, 0);
input_sync(ts->input_dev);
- /*************************************/
-
-
+
if (ts->ts_pinctrl) {
retval = pinctrl_select_state(ts->ts_pinctrl,
ts->pinctrl_state_active);
@@ -1914,7 +1960,7 @@ int himax_chip_common_resume(struct himax_ts_data *ts)
atomic_set(&ts->suspend_mode, 0);
- himax_int_enable(ts->client->irq,1);
+ himax_int_enable(ts->client->irq, 1);
ts->suspended = false;
#if defined(HX_USB_DETECT2)
@@ -1922,10 +1968,12 @@ int himax_chip_common_resume(struct himax_ts_data *ts)
himax_cable_detect_func();
#endif
#ifdef HX_SMART_WAKEUP
- queue_delayed_work(ts->himax_smwp_wq, &ts->smwp_work, msecs_to_jiffies(1000));
+ queue_delayed_work(ts->himax_smwp_wq,
+ &ts->smwp_work, msecs_to_jiffies(1000));
#endif
#ifdef HX_HIGH_SENSE
- queue_delayed_work(ts->himax_hsen_wq, &ts->hsen_work, msecs_to_jiffies(1000));
+ queue_delayed_work(ts->himax_hsen_wq,
+ &ts->hsen_work, msecs_to_jiffies(1000));
#endif
return 0;
err_pinctrl_select_resume:
diff --git a/drivers/input/touchscreen/hxchipset/himax_common.h b/drivers/input/touchscreen/hxchipset/himax_common.h
index 27ce9aafd959..41c97f7b5204 100644
--- a/drivers/input/touchscreen/hxchipset/himax_common.h
+++ b/drivers/input/touchscreen/hxchipset/himax_common.h
@@ -16,9 +16,13 @@
#ifndef HIMAX_COMMON_H
#define HIMAX_COMMON_H
+#include "himax_platform.h"
+
#include
-#include
-#include
+/*#include */
+/*#include */
+#include
+#include
#include
#include
@@ -34,9 +38,9 @@
#include
#include
#include
+#include
#include
#include
-#include "himax_platform.h"
#if defined(CONFIG_FB)
#include
@@ -48,7 +52,7 @@
#ifdef CONFIG_OF
#include
#endif
-#define HIMAX_DRIVER_VER "0.2.4.0"
+#define HIMAX_DRIVER_VER "0.3.1.0"
#define FLASH_DUMP_FILE "/data/user/Flash_Dump.bin"
#define DIAG_COORDINATE_FILE "/sdcard/Coordinate_Dump.csv"
@@ -62,39 +66,39 @@
#define HX_TP_PROC_SELF_TEST
#define HX_TP_PROC_RESET
#define HX_TP_PROC_SENSE_ON_OFF
-//#define HX_TP_PROC_2T2R
+/*#define HX_TP_PROC_2T2R*/
int himax_touch_proc_init(void);
void himax_touch_proc_deinit(void);
#endif
-//===========Himax Option function=============
-//#define HX_RST_PIN_FUNC
-//#define HX_AUTO_UPDATE_FW
-//#define HX_HIGH_SENSE
-//#define HX_SMART_WAKEUP
-//#define HX_USB_DETECT
-//#define HX_ESD_WORKAROUND
-//#define HX_USB_DETECT2
-
-//#define HX_EN_SEL_BUTTON // Support Self Virtual key ,default is close
-#define HX_EN_MUT_BUTTON // Support Mutual Virtual Key ,default is close
-
-#define HX_KEY_MAX_COUNT 4
-#define DEFAULT_RETRY_CNT 3
-
-#define HX_VKEY_0 KEY_BACK
-#define HX_VKEY_1 KEY_HOME
-#define HX_VKEY_2 KEY_RESERVED
-#define HX_VKEY_3 KEY_RESERVED
-#define HX_KEY_ARRAY {HX_VKEY_0, HX_VKEY_1, HX_VKEY_2, HX_VKEY_3}
+/*===========Himax Option function=============*/
+/*#define HX_RST_PIN_FUNC*/
+#define HX_AUTO_UPDATE_FW
+/*#define HX_HIGH_SENSE*/
+/*#define HX_SMART_WAKEUP*/
+/*#define HX_USB_DETECT*/
+/*#define HX_ESD_WORKAROUND*/
+/*#define HX_USB_DETECT2*/
+/*#define HX_EN_SEL_BUTTON*//* Support Self Virtual key ,default is close*/
+#define HX_EN_MUT_BUTTON/* Support Mutual Virtual Key ,default is close*/
+/*#define HX_EN_CHECK_PATCH*/
+
+#define HX_KEY_MAX_COUNT 4
+#define DEFAULT_RETRY_CNT 3
+
+#define HX_VKEY_0 KEY_BACK
+#define HX_VKEY_1 KEY_HOME
+#define HX_VKEY_2 KEY_RESERVED
+#define HX_VKEY_3 KEY_RESERVED
+#define HX_KEY_ARRAY {HX_VKEY_0, HX_VKEY_1, HX_VKEY_2, HX_VKEY_3}
#define SHIFTBITS 5
-//#define FLASH_SIZE 131072
-#define FW_SIZE_60k 61440
-#define FW_SIZE_64k 65536
-#define FW_SIZE_124k 126976
-#define FW_SIZE_128k 131072
+/*#define FLASH_SIZE 131072*/
+#define FW_SIZE_60k 61440
+#define FW_SIZE_64k 65536
+#define FW_SIZE_124k 126976
+#define FW_SIZE_128k 131072
struct himax_ic_data {
int vendor_fw_ver;
@@ -183,12 +187,12 @@ struct himax_ts_data {
bool suspended;
bool probe_done;
struct mutex fb_mutex;
+ struct mutex rw_lock;
atomic_t suspend_mode;
uint8_t x_channel;
uint8_t y_channel;
uint8_t useScreenRes;
uint8_t diag_command;
-
uint8_t protocol_type;
uint8_t first_pressed;
uint8_t coord_data_size;
@@ -198,11 +202,9 @@ struct himax_ts_data {
uint8_t nFinger_support;
uint8_t irq_enabled;
uint8_t diag_self[50];
-
uint16_t finger_pressed;
uint16_t last_slot;
uint16_t pre_finger_mask;
-
uint32_t debug_log_level;
uint32_t widthFactor;
uint32_t heightFactor;
@@ -214,20 +216,20 @@ struct himax_ts_data {
uint32_t pl_x_max;
uint32_t pl_y_min;
uint32_t pl_y_max;
-
+
int use_irq;
int (*power)(int on);
int pre_finger_data[10][2];
-
+
struct device *dev;
struct workqueue_struct *himax_wq;
struct work_struct work;
struct input_dev *input_dev;
struct hrtimer timer;
struct i2c_client *client;
- struct himax_i2c_platform_data *pdata;
+ struct himax_i2c_platform_data *pdata;
struct himax_virtual_key *button;
-
+
#if defined(CONFIG_FB)
struct notifier_block fb_notif;
#elif defined(CONFIG_HAS_EARLYSUSPEND)
@@ -235,8 +237,8 @@ struct himax_ts_data {
#endif
#ifdef HX_TP_PROC_FLASH_DUMP
- struct workqueue_struct *flash_wq;
- struct work_struct flash_work;
+ struct workqueue_struct *flash_wq;
+ struct work_struct flash_work;
#endif
#ifdef HX_RST_PIN_FUNC
@@ -250,7 +252,7 @@ struct himax_ts_data {
#ifdef HX_SMART_WAKEUP
uint8_t SMWP_enable;
uint8_t gesture_cust_en[16];
- struct wake_lock ts_SMWP_wake_lock;
+ struct wakeup_source ts_SMWP_wake_lock;
struct workqueue_struct *himax_smwp_wq;
struct delayed_work smwp_work;
#endif
@@ -261,7 +263,7 @@ struct himax_ts_data {
struct delayed_work hsen_work;
#endif
-#if defined(HX_USB_DETECT)||defined(HX_USB_DETECT2)
+#if defined(HX_USB_DETECT) || defined(HX_USB_DETECT2)
uint8_t usb_connected;
uint8_t *cable_config;
#endif
@@ -273,30 +275,30 @@ struct himax_ts_data {
struct pinctrl_state *pinctrl_state_release;
};
-#define HX_CMD_NOP 0x00
-#define HX_CMD_SETMICROOFF 0x35
-#define HX_CMD_SETROMRDY 0x36
-#define HX_CMD_TSSLPIN 0x80
-#define HX_CMD_TSSLPOUT 0x81
-#define HX_CMD_TSSOFF 0x82
-#define HX_CMD_TSSON 0x83
-#define HX_CMD_ROE 0x85
-#define HX_CMD_RAE 0x86
-#define HX_CMD_RLE 0x87
-#define HX_CMD_CLRES 0x88
-#define HX_CMD_TSSWRESET 0x9E
-#define HX_CMD_SETDEEPSTB 0xD7
-#define HX_CMD_SET_CACHE_FUN 0xDD
-#define HX_CMD_SETIDLE 0xF2
-#define HX_CMD_SETIDLEDELAY 0xF3
-#define HX_CMD_SELFTEST_BUFFER 0x8D
+#define HX_CMD_NOP 0x00
+#define HX_CMD_SETMICROOFF 0x35
+#define HX_CMD_SETROMRDY 0x36
+#define HX_CMD_TSSLPIN 0x80
+#define HX_CMD_TSSLPOUT 0x81
+#define HX_CMD_TSSOFF 0x82
+#define HX_CMD_TSSON 0x83
+#define HX_CMD_ROE 0x85
+#define HX_CMD_RAE 0x86
+#define HX_CMD_RLE 0x87
+#define HX_CMD_CLRES 0x88
+#define HX_CMD_TSSWRESET 0x9E
+#define HX_CMD_SETDEEPSTB 0xD7
+#define HX_CMD_SET_CACHE_FUN 0xDD
+#define HX_CMD_SETIDLE 0xF2
+#define HX_CMD_SETIDLEDELAY 0xF3
+#define HX_CMD_SELFTEST_BUFFER 0x8D
#define HX_CMD_MANUALMODE 0x42
-#define HX_CMD_FLASH_ENABLE 0x43
+#define HX_CMD_FLASH_ENABLE 0x43
#define HX_CMD_FLASH_SET_ADDRESS 0x44
#define HX_CMD_FLASH_WRITE_REGISTER 0x45
#define HX_CMD_FLASH_SET_COMMAND 0x47
#define HX_CMD_FLASH_WRITE_BUFFER 0x48
-#define HX_CMD_FLASH_PAGE_ERASE 0x4D
+#define HX_CMD_FLASH_PAGE_ERASE 0x4D
#define HX_CMD_FLASH_SECTOR_ERASE 0x4E
#define HX_CMD_CB 0xCB
#define HX_CMD_EA 0xEA
@@ -311,7 +313,7 @@ enum input_protocol_type {
};
#ifdef HX_HIGH_SENSE
-void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable);
+void himax_set_HSEN_func(struct i2c_client *client, uint8_t HSEN_enable);
#endif
#ifdef HX_SMART_WAKEUP
@@ -319,18 +321,18 @@ void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable);
#define GEST_PTLG_HDR_LEN (4)
#define GEST_PTLG_HDR_ID1 (0xCC)
#define GEST_PTLG_HDR_ID2 (0x44)
-#define GEST_PT_MAX_NUM (128)
+#define GEST_PT_MAX_NUM (128)
#ifdef HX_GESTURE_TRACK
static int gest_pt_cnt;
static int gest_pt_x[GEST_PT_MAX_NUM];
static int gest_pt_y[GEST_PT_MAX_NUM];
-static int gest_start_x,gest_start_y,gest_end_x,gest_end_y;
-static int gest_width,gest_height,gest_mid_x,gest_mid_y;
+static int gest_start_x, gest_start_y, gest_end_x, gest_end_y;
+static int gest_width, gest_height, gest_mid_x, gest_mid_y;
static int gn_gesture_coor[16];
#endif
-void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable);
+void himax_set_SMWP_func(struct i2c_client *client, uint8_t SMWP_enable);
extern bool FAKE_POWER_KEY_SEND;
enum gesture_event_type {
@@ -380,16 +382,91 @@ irqreturn_t himax_ts_thread(int irq, void *ptr);
int himax_input_register(struct himax_ts_data *ts);
#endif
-extern int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id);
-extern int himax_chip_common_remove(struct i2c_client *client);
-extern int himax_chip_common_suspend(struct himax_ts_data *ts);
-extern int himax_chip_common_resume(struct himax_ts_data *ts);
-int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata);
+int himax_chip_common_probe(struct i2c_client *client,
+const struct i2c_device_id *id);
+int himax_chip_common_remove(struct i2c_client *client);
+int himax_chip_common_suspend(struct himax_ts_data *ts);
+int himax_chip_common_resume(struct himax_ts_data *ts);
+int himax_loadSensorConfig(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata);
#ifdef HX_USB_DETECT2
-//extern kal_bool upmu_is_chr_det(void);
+/*extern kal_bool upmu_is_chr_det(void);*/
void himax_cable_detect_func(void);
#endif
+#ifdef HX_AUTO_UPDATE_FW
+extern unsigned long FW_VER_MAJ_FLASH_ADDR;
+extern unsigned long FW_VER_MIN_FLASH_ADDR;
+extern unsigned long CFG_VER_MAJ_FLASH_ADDR;
+extern unsigned long CFG_VER_MIN_FLASH_ADDR;
+#endif
+extern unsigned long FW_VER_MAJ_FLASH_LENG;
+extern unsigned long FW_VER_MIN_FLASH_LENG;
+extern unsigned long CFG_VER_MAJ_FLASH_LENG;
+extern unsigned long CFG_VER_MIN_FLASH_LENG;
+extern unsigned char IC_TYPE;
+extern unsigned char IC_CHECKSUM;
+
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+extern int himax_touch_proc_init(void);
+extern void himax_touch_proc_deinit(void);
+/*PROC-START*/
+#ifdef HX_TP_PROC_FLASH_DUMP
+extern void himax_ts_flash_func(void);
+extern void setFlashBuffer(void);
+extern bool getFlashDumpGoing(void);
+extern uint8_t getSysOperation(void);
+extern void setSysOperation(uint8_t operation);
+#endif
+
+#ifdef HX_TP_PROC_HITOUCH
+extern bool hitouch_is_connect;
+#endif
+
+#ifdef HX_TP_PROC_DIAG
+ extern int touch_monitor_stop_flag;
+
+ extern int touch_monitor_stop_limit;
+
+ extern void himax_ts_diag_func(void);
+
+ extern int16_t *getMutualBuffer(void);
+ extern int16_t *getMutualNewBuffer(void);
+ extern int16_t *getMutualOldBuffer(void);
+ extern int16_t *getSelfBuffer(void);
+ extern uint8_t getXChannel(void);
+ extern uint8_t getYChannel(void);
+ extern uint8_t getDiagCommand(void);
+ extern void setXChannel(uint8_t x);
+ extern void setYChannel(uint8_t y);
+ extern void setMutualBuffer(void);
+ extern void setMutualNewBuffer(void);
+ extern void setMutualOldBuffer(void);
+ extern uint8_t coordinate_dump_enable;
+ extern struct file *coordinate_fn;
+ extern uint8_t diag_coor[128];
+#ifdef HX_TP_PROC_2T2R
+ extern int16_t *getMutualBuffer_2(void);
+ extern uint8_t getXChannel_2(void);
+ extern uint8_t getYChannel_2(void);
+ extern void setXChannel_2(uint8_t x);
+ extern void setYChannel_2(uint8_t y);
+ extern void setMutualBuffer_2(void);
+#endif
+#endif
+/*PROC-END*/
+#endif
+
+#ifdef HX_USB_DETECT2
+ extern bool USB_Flag;
+#endif
+#ifdef HX_ESD_WORKAROUND
+ extern void HX_report_ESD_event(void);
+ unsigned char ESD_00_counter = 0;
+ unsigned char ESD_00_Flag = 0;
+#endif
+bool himax_ts_init(struct himax_ts_data *ts);
+
#endif
diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.c b/drivers/input/touchscreen/hxchipset/himax_debug.c
index f8bee11b4351..55cc7ca92e4c 100644
--- a/drivers/input/touchscreen/hxchipset/himax_debug.c
+++ b/drivers/input/touchscreen/hxchipset/himax_debug.c
@@ -16,32 +16,16 @@
#include "himax_debug.h"
#include "himax_ic.h"
-//struct himax_debug_data* debug_data;
-
-extern struct himax_ic_data* ic_data;
-extern struct himax_ts_data *private_ts;
-extern unsigned char IC_TYPE;
-extern unsigned char IC_CHECKSUM;
-extern int himax_input_register(struct himax_ts_data *ts);
-#ifdef QCT
-extern irqreturn_t himax_ts_thread(int irq, void *ptr);
-#endif
-#ifdef MTK
-#ifdef CONFIG_OF_TOUCH
-extern irqreturn_t tpd_eint_interrupt_handler(int irq, void *desc);
-#else
-extern void tpd_eint_interrupt_handler(void);
-#endif
-#endif
+/*struct himax_debug_data* debug_data;*/
#ifdef HX_TP_PROC_DIAG
#ifdef HX_TP_PROC_2T2R
-int HX_RX_NUM_2 = 0;
-int HX_TX_NUM_2 = 0;
+int HX_RX_NUM_2;
+int HX_TX_NUM_2;
#endif
-int touch_monitor_stop_flag = 0;
+int touch_monitor_stop_flag;
int touch_monitor_stop_limit = 5;
-uint8_t g_diag_arr_num = 0;
+uint8_t g_diag_arr_num;
#endif
#ifdef HX_ESD_WORKAROUND
@@ -52,11 +36,11 @@ u8 HX_ESD_RESET_ACTIVATE;
bool FAKE_POWER_KEY_SEND;
#endif
-//=============================================================================================================
-//
-// Segment : Himax PROC Debug Function
-//
-//=============================================================================================================
+/*========================================================
+
+Segment : Himax PROC Debug Function
+
+==========================================================*/
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
static ssize_t himax_vendor_read(struct file *file, char *buf,
@@ -65,33 +49,26 @@ static ssize_t himax_vendor_read(struct file *file, char *buf,
ssize_t ret = 0;
char *temp_buf;
- if(!HX_PROC_SEND_FLAG)
- {
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
+ ret += snprintf(temp_buf, len,
+ "%s_FW:%#x_CFG:%#x_SensorId:%#x\n",
+ HIMAX_common_NAME, ic_data->vendor_fw_ver,
+ ic_data->vendor_config_ver, ic_data->vendor_sensor_id);
- ret += snprintf(temp_buf, len, "%s_FW:%#x_CFG:%#x_SensorId:%#x\n", HIMAX_common_NAME,
- ic_data->vendor_fw_ver, ic_data->vendor_config_ver, ic_data->vendor_sensor_id);
- HX_PROC_SEND_FLAG=1;
+ HX_PROC_SEND_FLAG = 1;
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
-static const struct file_operations himax_proc_vendor_ops =
-{
+const struct file_operations himax_proc_vendor_ops = {
.owner = THIS_MODULE,
.read = himax_vendor_read,
};
@@ -107,29 +84,21 @@ static ssize_t himax_attn_read(struct file *file, char *buf,
if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- ret += snprintf(temp_buf, len, "attn = %x\n", himax_int_gpio_read(ts_data->pdata->gpio_irq));
+ ret += snprintf(temp_buf, len, "attn = %x\n",
+ himax_int_gpio_read(ts_data->pdata->gpio_irq));
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
-
-static const struct file_operations himax_proc_attn_ops =
-{
+const struct file_operations himax_proc_attn_ops = {
.owner = THIS_MODULE,
.read = himax_attn_read,
};
@@ -143,23 +112,16 @@ static ssize_t himax_int_en_read(struct file *file, char *buf,
if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- ret += snprintf(temp_buf, len, "%d ", ts->irq_enabled);
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ ret += snprintf(temp_buf, len-1, "%d ", ts->irq_enabled);
+ ret += snprintf(temp_buf, 1, "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
@@ -167,18 +129,15 @@ static ssize_t himax_int_en_write(struct file *file, const char *buff,
size_t len, loff_t *pos)
{
struct himax_ts_data *ts = private_ts;
- char buf_tmp[12]= {0};
- int value, ret=0;
+ char buf_tmp[12] = {0};
+ int value, ret = 0;
- if (len >= 12)
- {
+ if (len >= 12) {
I("%s: no command exceeds 12 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf_tmp, buff, len))
- {
return -EFAULT;
- }
if (buf_tmp[0] == '0')
value = false;
@@ -188,36 +147,43 @@ static ssize_t himax_int_en_write(struct file *file, const char *buff,
return -EINVAL;
if (value) {
- if(ic_data->HX_INT_IS_EDGE)
- {
+ if (ic_data->HX_INT_IS_EDGE) {
#ifdef MTK
#ifdef CONFIG_OF_TOUCH
- himax_int_enable(ts->client->irq,1);
+ himax_int_enable(ts->client->irq, 1);
#else
- //mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE);
- //mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
- mt_eint_registration(ts->client->irq, EINTF_TRIGGER_FALLING, tpd_eint_interrupt_handler, 1);
+ /*mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_TYPE);
+ mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);*/
+ mt_eint_registration(ts->client->irq,
+ EINTF_TRIGGER_FALLING, tpd_eint_interrupt_handler, 1);
#endif
#endif
#ifdef QCT
- ret = request_threaded_irq(ts->client->irq, NULL, himax_ts_thread,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, ts->client->name, ts);
+ ret = request_threaded_irq(ts->client->irq,
+ NULL, himax_ts_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ ts->client->name, ts);
#endif
- }
- else
- {
+ } else {
#ifdef MTK
#ifdef CONFIG_OF_TOUCH
- himax_int_enable(ts->client->irq,1);
+ himax_int_enable(ts->client->irq, 1);
#else
- //mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_TYPE);
- //mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
- mt_eint_registration(ts->client->irq, EINTF_TRIGGER_LOW, tpd_eint_interrupt_handler, 1);
+ /*mt_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_TYPE);
+ mt_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM,
+ CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);*/
+ mt_eint_registration(ts->client->irq,
+ EINTF_TRIGGER_LOW, tpd_eint_interrupt_handler, 1);
#endif
#endif
#ifdef QCT
- ret = request_threaded_irq(ts->client->irq, NULL, himax_ts_thread,
- IRQF_TRIGGER_LOW | IRQF_ONESHOT, ts->client->name, ts);
+ ret = request_threaded_irq(ts->client->irq,
+ NULL, himax_ts_thread,
+ IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+ ts->client->name, ts);
#endif
}
if (ret == 0) {
@@ -225,7 +191,7 @@ static ssize_t himax_int_en_write(struct file *file, const char *buff,
irq_enable_count = 1;
}
} else {
- himax_int_enable(ts->client->irq,0);
+ himax_int_enable(ts->client->irq, 0);
free_irq(ts->client->irq, ts);
ts->irq_enabled = 0;
}
@@ -233,8 +199,7 @@ static ssize_t himax_int_en_write(struct file *file, const char *buff,
return len;
}
-static const struct file_operations himax_proc_int_en_ops =
-{
+const struct file_operations himax_proc_int_en_ops = {
.owner = THIS_MODULE,
.read = himax_int_en_read,
.write = himax_int_en_write,
@@ -249,26 +214,19 @@ static ssize_t himax_layout_read(struct file *file, char *buf,
if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_min);
- ret += snprintf(temp_buf+ret, len-ret, "%d ", ts->pdata->abs_x_max);
- ret += snprintf(temp_buf+ret, len-ret, "%d ", ts->pdata->abs_y_min);
- ret += snprintf(temp_buf+ret, len-ret, "%d ", ts->pdata->abs_y_max);
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_min);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_x_max);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_y_min);
+ ret += snprintf(temp_buf, len, "%d ", ts->pdata->abs_y_max);
+ ret += snprintf(temp_buf, len, "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
@@ -283,17 +241,14 @@ static ssize_t himax_layout_write(struct file *file, const char *buff,
int layout[4] = {0};
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
- for (i = 0; i < 20; i++) {
+ for (i = 0 ; i < 20 ; i++) {
if (buf[i] == ',' || buf[i] == '\n') {
memset(buf_tmp, 0x0, sizeof(buf_tmp));
if (i - j <= 5)
@@ -310,20 +265,24 @@ static ssize_t himax_layout_write(struct file *file, const char *buff,
}
}
if (k == 4) {
- ts->pdata->abs_x_min=layout[0];
- ts->pdata->abs_x_max=layout[1];
- ts->pdata->abs_y_min=layout[2];
- ts->pdata->abs_y_max=layout[3];
- I("%d, %d, %d, %d\n",ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+ ts->pdata->abs_x_min = layout[0];
+ ts->pdata->abs_x_max = layout[1];
+ ts->pdata->abs_y_min = layout[2];
+ ts->pdata->abs_y_max = layout[3];
+ I("%d, %d, %d, %d\n", ts->pdata->abs_x_min,
+ ts->pdata->abs_x_max, ts->pdata->abs_y_min,
+ ts->pdata->abs_y_max);
input_unregister_device(ts->input_dev);
himax_input_register(ts);
- } else
- I("ERR@%d, %d, %d, %d\n",ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max);
+ } else {
+ I("ERR@%d, %d, %d, %d\n", ts->pdata->abs_x_min,
+ ts->pdata->abs_x_max, ts->pdata->abs_y_min,
+ ts->pdata->abs_y_max);
+ }
return len;
}
-static const struct file_operations himax_proc_layout_ops =
-{
+const struct file_operations himax_proc_layout_ops = {
.owner = THIS_MODULE,
.read = himax_layout_read,
.write = himax_layout_write,
@@ -335,26 +294,21 @@ static ssize_t himax_debug_level_read(struct file *file, char *buf,
struct himax_ts_data *ts_data;
size_t ret = 0;
char *temp_buf;
+
ts_data = private_ts;
if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- ret += snprintf(temp_buf, len, "%d\n", ts_data->debug_log_level);
+ ret += snprintf(temp_buf, len, "%d\n",
+ ts_data->debug_log_level);
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
@@ -365,29 +319,26 @@ static ssize_t himax_debug_level_write(struct file *file, const char *buff,
struct himax_ts_data *ts;
char buf_tmp[11];
int i;
+
ts = private_ts;
- if (len >= 12)
- {
+ if (len >= 12) {
I("%s: no command exceeds 12 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf_tmp, buff, len))
- {
return -EFAULT;
- }
ts->debug_log_level = 0;
- for(i=0; i='0' && buf_tmp[i]<='9' )
- ts->debug_log_level |= (buf_tmp[i]-'0');
- else if( buf_tmp[i]>='A' && buf_tmp[i]<='F' )
- ts->debug_log_level |= (buf_tmp[i]-'A'+10);
- else if( buf_tmp[i]>='a' && buf_tmp[i]<='f' )
- ts->debug_log_level |= (buf_tmp[i]-'a'+10);
-
- if(i!=len-2)
+ for (i = 0 ; i < len - 1 ; i++) {
+ if (buf_tmp[i] >= '0' && buf_tmp[i] <= '9')
+ ts->debug_log_level |= (buf_tmp[i] - '0');
+ else if (buf_tmp[i] >= 'A' && buf_tmp[i] <= 'F')
+ ts->debug_log_level |= (buf_tmp[i]-'A' + 10);
+ else if (buf_tmp[i] >= 'a' && buf_tmp[i] <= 'f')
+ ts->debug_log_level |= (buf_tmp[i] - 'a' + 10);
+
+ if (i != len - 2)
ts->debug_log_level <<= 4;
}
@@ -395,8 +346,12 @@ static ssize_t himax_debug_level_write(struct file *file, const char *buff,
if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 &&
(ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 &&
(ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) {
- ts->widthFactor = (ts->pdata->screenWidth << SHIFTBITS)/(ts->pdata->abs_x_max - ts->pdata->abs_x_min);
- ts->heightFactor = (ts->pdata->screenHeight << SHIFTBITS)/(ts->pdata->abs_y_max - ts->pdata->abs_y_min);
+ ts->widthFactor =
+ (ts->pdata->screenWidth << SHIFTBITS)
+ / (ts->pdata->abs_x_max - ts->pdata->abs_x_min);
+ ts->heightFactor =
+ (ts->pdata->screenHeight << SHIFTBITS)
+ / (ts->pdata->abs_y_max - ts->pdata->abs_y_min);
if (ts->widthFactor > 0 && ts->heightFactor > 0)
ts->useScreenRes = 1;
else {
@@ -415,8 +370,7 @@ static ssize_t himax_debug_level_write(struct file *file, const char *buff,
return len;
}
-static const struct file_operations himax_proc_debug_level_ops =
-{
+const struct file_operations himax_proc_debug_level_ops = {
.owner = THIS_MODULE,
.read = himax_debug_level_read,
.write = himax_debug_level_write,
@@ -433,35 +387,33 @@ static ssize_t himax_proc_register_read(struct file *file, char *buf,
memset(data, 0x00, sizeof(data));
- I("himax_register_show: %x,%x,%x,%x\n", register_command[0],register_command[1],register_command[2],register_command[3]);
- if(!HX_PROC_SEND_FLAG)
- {
+ I("himax_register_show: %x,%x,%x,%x\n", register_command[0],
+ register_command[1], register_command[2], register_command[3]);
+
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- himax_register_read(private_ts->client, register_command, 1, data);
+ himax_register_read(private_ts->client,
+ register_command, 1, data);
- ret += snprintf(temp_buf, len, "command: %x,%x,%x,%x\n", register_command[0],register_command[1],register_command[2],register_command[3]);
+ ret += snprintf(temp_buf, len, "command: %x,%x,%x,%x\n",
+ register_command[0], register_command[1],
+ register_command[2], register_command[3]);
- for (loop_i = 0; loop_i < 128; loop_i++) {
- ret += snprintf(temp_buf+ret, len-ret, "0x%2.2X ", data[loop_i]);
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+ ret += snprintf(temp_buf + ret,
+ sizeof(data[loop_i]), "0x%2.2X ", data[loop_i]);
if ((loop_i % 16) == 15)
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ ret += snprintf(temp_buf + ret, 1, "\n");
}
- ret += snprintf(temp_buf+ret, len-ret, "\n");
- HX_PROC_SEND_FLAG=1;
+ ret += snprintf(temp_buf + ret, len, "\n");
+ HX_PROC_SEND_FLAG = 1;
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
@@ -475,40 +427,48 @@ static ssize_t himax_proc_register_write(struct file *file, const char *buff,
uint8_t write_da[128];
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
memset(buf_tmp, 0x0, sizeof(buf_tmp));
memset(write_da, 0x0, sizeof(write_da));
- I("himax %s \n",buf);
+ I("himax %s\n", buf);
if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':') {
if (buf[2] == 'x') {
memcpy(buf_tmp, buf + 3, 8);
- if (!kstrtoul(buf_tmp, 16, &result))
- {
- register_command[0] = (uint8_t)result;
- register_command[1] = (uint8_t)(result >> 8);
- register_command[2] = (uint8_t)(result >> 16);
- register_command[3] = (uint8_t)(result >> 24);
- }
+ if (!kstrtoul(buf_tmp, 16, &result)) {
+ register_command[0] =
+ (uint8_t)result;
+ register_command[1] =
+ (uint8_t)(result >> 8);
+ register_command[2] =
+ (uint8_t)(result >> 16);
+ register_command[3] =
+ (uint8_t)(result >> 24);
+ }
base = 11;
- I("CMD: %x,%x,%x,%x\n", register_command[0],register_command[1],register_command[2],register_command[3]);
+ I("CMD: %x,%x,%x,%x\n", register_command[0],
+ register_command[1], register_command[2],
+ register_command[3]);
- for (loop_i = 0; loop_i < 128 && (base+10)<80; loop_i++) {
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
if (buf[base] == '\n') {
if (buf[0] == 'w') {
- himax_register_write(private_ts->client, register_command, 1, write_da);
- I("CMD: %x, %x, %x, %x, len=%d\n", write_da[0], write_da[1],write_da[2],write_da[3],length);
+ himax_register_write
+ (private_ts->client,
+ register_command
+ , 1, write_da);
+ I("CMD:%x, %x, %x, %x,len=%d\n",
+ write_da[0], write_da[1],
+ write_da[2], write_da[3],
+ length);
}
I("\n");
return len;
@@ -518,12 +478,16 @@ static ssize_t himax_proc_register_write(struct file *file, const char *buff,
buf_tmp[11] = '\0';
memcpy(buf_tmp, buf + base + 2, 8);
if (!kstrtoul(buf_tmp, 16, &result)) {
- write_da[loop_i] = (uint8_t)result;
- write_da[loop_i+1] = (uint8_t)(result >> 8);
- write_da[loop_i+2] = (uint8_t)(result >> 16);
- write_da[loop_i+3] = (uint8_t)(result >> 24);
+ write_da[loop_i] =
+ (uint8_t)result;
+ write_da[loop_i+1] =
+ (uint8_t)(result >> 8);
+ write_da[loop_i+2] =
+ (uint8_t)(result >> 16);
+ write_da[loop_i+3] =
+ (uint8_t)(result >> 24);
}
- length+=4;
+ length += 4;
}
base += 10;
}
@@ -532,8 +496,7 @@ static ssize_t himax_proc_register_write(struct file *file, const char *buff,
return len;
}
-static const struct file_operations himax_proc_register_ops =
-{
+const struct file_operations himax_proc_register_ops = {
.owner = THIS_MODULE,
.read = himax_proc_register_read,
.write = himax_proc_register_write,
@@ -579,15 +542,18 @@ void setYChannel(uint8_t y)
}
void setMutualBuffer(void)
{
- diag_mutual = kzalloc(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+ diag_mutual = kzalloc
+ (x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
}
void setMutualNewBuffer(void)
{
- diag_mutual_new = kzalloc(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+ diag_mutual_new = kzalloc
+ (x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
}
void setMutualOldBuffer(void)
{
- diag_mutual_old = kzalloc(x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
+ diag_mutual_old = kzalloc
+ (x_channel * y_channel * sizeof(int16_t), GFP_KERNEL);
}
#ifdef HX_TP_PROC_2T2R
@@ -613,94 +579,82 @@ void setYChannel_2(uint8_t y)
}
void setMutualBuffer_2(void)
{
- diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int16_t), GFP_KERNEL);
+ diag_mutual_2 = kzalloc
+ (x_channel_2 * y_channel_2 * sizeof(int16_t), GFP_KERNEL);
}
#endif
static ssize_t himax_diag_arrange_write(struct file *file, const char *buff,
size_t len, loff_t *pos)
{
- //struct himax_ts_data *ts = private_ts;
+ /*struct himax_ts_data *ts = private_ts;*/
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
g_diag_arr_num = buf[0] - '0';
- I("%s: g_diag_arr_num = %d \n", __func__,g_diag_arr_num);
+ I("%s: g_diag_arr_num = %d\n", __func__, g_diag_arr_num);
return len;
}
-static const struct file_operations himax_proc_diag_arrange_ops =
-{
+const struct file_operations himax_proc_diag_arrange_ops = {
.owner = THIS_MODULE,
.write = himax_diag_arrange_write,
};
-static void himax_diag_arrange_print(struct seq_file *s, int i, int j, int transpose)
+static void himax_diag_arrange_print
+(struct seq_file *s, int i, int j, int transpose)
{
- if(transpose)
- seq_printf(s, "%6d", diag_mutual[ j + i*x_channel]);
+ if (transpose)
+ seq_printf(s, "%6d", diag_mutual[j + i * x_channel]);
else
- seq_printf(s, "%6d", diag_mutual[ i + j*x_channel]);
+ seq_printf(s, "%6d", diag_mutual[i + j * x_channel]);
}
-static void himax_diag_arrange_inloop(struct seq_file *s, int in_init,bool transpose, int j)
+static void himax_diag_arrange_inloop
+(struct seq_file *s, int in_init, bool transpose, int j)
{
int i;
int in_max = 0;
- if(transpose)
+ if (transpose)
in_max = y_channel;
else
in_max = x_channel;
- if (in_init > 0)
- {
- for(i = in_init-1;i >= 0;i--)
- {
+ if (in_init > 0) {
+ for (i = in_init - 1 ; i >= 0 ; i--)
himax_diag_arrange_print(s, i, j, transpose);
- }
- }
- else
- {
- for (i = 0; i < in_max; i++)
- {
+ } else {
+ for (i = 0 ; i < in_max ; i++)
himax_diag_arrange_print(s, i, j, transpose);
- }
}
}
-static void himax_diag_arrange_outloop(struct seq_file *s, int transpose, int out_init, int in_init)
+static void himax_diag_arrange_outloop
+(struct seq_file *s, int transpose, int out_init, int in_init)
{
int j;
int out_max = 0;
- if(transpose)
+ if (transpose)
out_max = x_channel;
else
out_max = y_channel;
- if(out_init > 0)
- {
- for(j = out_init-1;j >= 0;j--)
- {
+ if (out_init > 0) {
+ for (j = out_init - 1 ; j >= 0 ; j--) {
himax_diag_arrange_inloop(s, in_init, transpose, j);
seq_printf(s, " %5d\n", diag_self[j]);
}
- }
- else
- {
- for(j = 0;j < out_max;j++)
- {
+ } else {
+ for (j = 0 ; j < out_max ; j++) {
himax_diag_arrange_inloop(s, in_init, transpose, j);
seq_printf(s, " %5d\n", diag_self[j]);
}
@@ -709,33 +663,35 @@ static void himax_diag_arrange_outloop(struct seq_file *s, int transpose, int ou
static void himax_diag_arrange(struct seq_file *s)
{
- int bit2,bit1,bit0;
+ int bit2, bit1, bit0;
int i;
bit2 = g_diag_arr_num >> 2;
bit1 = g_diag_arr_num >> 1 & 0x1;
bit0 = g_diag_arr_num & 0x1;
- if (g_diag_arr_num < 4)
- {
- himax_diag_arrange_outloop(s, bit2, bit1 * y_channel, bit0 * x_channel);
- for (i = y_channel; i < x_channel + y_channel; i++) {
+ if (g_diag_arr_num < 4) {
+ himax_diag_arrange_outloop(s,
+ bit2, bit1 * y_channel, bit0 * x_channel);
+
+ for (i = y_channel ; i < x_channel + y_channel ; i++)
seq_printf(s, "%6d", diag_self[i]);
- }
- }
- else
- {
- himax_diag_arrange_outloop(s, bit2, bit1 * x_channel, bit0 * y_channel);
- for (i = x_channel; i < x_channel + y_channel; i++) {
+
+ } else {
+ himax_diag_arrange_outloop(s,
+ bit2, bit1 * x_channel, bit0 * y_channel);
+
+ for (i = x_channel ; i < x_channel + y_channel ; i++)
seq_printf(s, "%6d", diag_self[i]);
- }
+
}
}
static void *himax_diag_seq_start(struct seq_file *s, loff_t *pos)
{
- if (*pos>=1) return NULL;
- return (void *)((unsigned long) *pos+1);
+ if (*pos >= 1)
+ return NULL;
+ return (void *)((unsigned long) *pos + 1);
}
static void *himax_diag_seq_next(struct seq_file *s, void *v, loff_t *pos)
@@ -748,87 +704,96 @@ static void himax_diag_seq_stop(struct seq_file *s, void *v)
static int himax_diag_seq_read(struct seq_file *s, void *v)
{
size_t count = 0;
- int32_t loop_i;//,loop_j
+ int32_t loop_i;/*loop_j*/
uint16_t mutual_num, self_num, width;
#ifdef HX_TP_PROC_2T2R
- if(Is_2T2R && diag_command == 4)
- {
+ if (Is_2T2R && diag_command == 4) {
mutual_num = x_channel_2 * y_channel_2;
- self_num = x_channel_2 + y_channel_2; //don't add KEY_COUNT
+ /*don't add KEY_COUNT*/
+ self_num = x_channel_2 + y_channel_2;
width = x_channel_2;
- seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel_2, y_channel_2);
- }
- else
+ seq_printf(s, "ChannelStart: %4d, %4d\n\n",
+ x_channel_2, y_channel_2);
+ } else
#endif
{
mutual_num = x_channel * y_channel;
- self_num = x_channel + y_channel; //don't add KEY_COUNT
+ /*don't add KEY_COUNT*/
+ self_num = x_channel + y_channel;
width = x_channel;
- seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel, y_channel);
+ seq_printf(s, "ChannelStart: %4d, %4d\n\n",
+ x_channel, y_channel);
}
- // start to show out the raw data in adb shell
+ /* start to show out the raw data in adb shell*/
if (diag_command >= 1 && diag_command <= 6) {
if (diag_command <= 3) {
himax_diag_arrange(s);
- seq_printf(s, "\n\n");
+ seq_puts(s, "\n\n");
#ifdef HX_EN_SEL_BUTTON
- seq_printf(s, "\n");
- for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++)
- seq_printf(s, "%6d", diag_self[HX_RX_NUM + HX_TX_NUM + loop_i]);
+ seq_putc(s, '\n');
+ for (loop_i = 0 ; loop_i < HX_BT_NUM ; loop_i++)
+ seq_printf(s, "%6d",
+ diag_self[HX_RX_NUM + HX_TX_NUM + loop_i]);
#endif
#ifdef HX_TP_PROC_2T2R
- }else if(Is_2T2R && diag_command == 4 ) {
- for (loop_i = 0; loop_i < mutual_num; loop_i++) {
+ } else if (Is_2T2R && diag_command == 4) {
+ for (loop_i = 0 ; loop_i < mutual_num ; loop_i++) {
seq_printf(s, "%4d", diag_mutual_2[loop_i]);
if ((loop_i % width) == (width - 1))
- seq_printf(s, " %6d\n", diag_self[width + loop_i/width]);
+ seq_printf(s, " %6d\n",
+ diag_self[width + loop_i / width]);
}
- seq_printf(s, "\n");
- for (loop_i = 0; loop_i < width; loop_i++) {
+ seq_putc(s, '\n');
+ for (loop_i = 0 ; loop_i < width ; loop_i++) {
seq_printf(s, "%6d", diag_self[loop_i]);
if (((loop_i) % width) == (width - 1))
- seq_printf(s, "\n");
+ seq_putc(s, '\n');
}
#ifdef HX_EN_SEL_BUTTON
- seq_printf(s, "\n");
- for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++)
- seq_printf(s, "%4d", diag_self[HX_RX_NUM_2 + HX_TX_NUM_2 + loop_i]);
+ seq_putc(s, '\n');
+ for (loop_i = 0 ; loop_i < HX_BT_NUM ; loop_i++) {
+ seq_printf(s, "%4d",
+ diag_self[HX_RX_NUM_2 + HX_TX_NUM_2 + loop_i]);
+ }
#endif
#endif
} else if (diag_command > 4) {
- for (loop_i = 0; loop_i < self_num; loop_i++) {
+ for (loop_i = 0 ; loop_i < self_num ; loop_i++) {
seq_printf(s, "%4d", diag_self[loop_i]);
- if (((loop_i - mutual_num) % width) == (width - 1))
- seq_printf(s, "\n");
+ if (((loop_i - mutual_num) % width)
+ == (width - 1)) {
+ seq_putc(s, '\n');
+ }
}
} else {
- for (loop_i = 0; loop_i < mutual_num; loop_i++) {
+ for (loop_i = 0 ; loop_i < mutual_num ; loop_i++) {
seq_printf(s, "%4d", diag_mutual[loop_i]);
if ((loop_i % width) == (width - 1))
- seq_printf(s, "\n");
+ seq_putc(s, '\n');
}
}
- seq_printf(s, "ChannelEnd");
- seq_printf(s, "\n");
+ seq_puts(s, "ChannelEnd");
+ seq_putc(s, '\n');
} else if (diag_command == 7) {
- for (loop_i = 0; loop_i < 128 ;loop_i++) {
+ for (loop_i = 0; loop_i < 128 ; loop_i++) {
if ((loop_i % 16) == 0)
- seq_printf(s, "LineStart:");
+ seq_puts(s, "LineStart:");
seq_printf(s, "%4d", diag_coor[loop_i]);
if ((loop_i % 16) == 15)
- seq_printf(s, "\n");
+ seq_putc(s, '\n');
}
- } else if (diag_command == 9 || diag_command == 91 || diag_command == 92){
+ } else if (diag_command == 9 ||
+ diag_command == 91 || diag_command == 92) {
+
himax_diag_arrange(s);
- seq_printf(s, "\n");
+ seq_putc(s, '\n');
}
return count;
}
-static const struct seq_operations himax_diag_seq_ops =
-{
+const struct seq_operations himax_diag_seq_ops = {
.start = himax_diag_seq_start,
.next = himax_diag_seq_next,
.stop = himax_diag_seq_stop,
@@ -838,25 +803,24 @@ static int himax_diag_proc_open(struct inode *inode, struct file *file)
{
return seq_open(file, &himax_diag_seq_ops);
};
-bool DSRAM_Flag;
+bool DSRAM_Flag = false;
-//DSRAM thread
+/*DSRAM thread*/
void himax_ts_diag_func(void)
{
- int i=0, j=0;
+ int i = 0, j = 0;
unsigned int index = 0;
int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
uint8_t info_data[total_size];
- int16_t *mutual_data = NULL;
- int16_t *mutual_data_new = NULL;
- int16_t *mutual_data_old = NULL;
+ int16_t *mutual_data;
+ int16_t *mutual_data_new;
+ int16_t *mutual_data_old;
int16_t new_data;
himax_burst_enable(private_ts->client, 1);
- if(diag_command == 9 || diag_command == 91)
- {
+ if (diag_command == 9 || diag_command == 91) {
mutual_data = getMutualBuffer();
- }else if(diag_command == 92){
+ } else if (diag_command == 92) {
mutual_data = getMutualBuffer();
mutual_data_new = getMutualNewBuffer();
mutual_data_old = getMutualOldBuffer();
@@ -864,49 +828,63 @@ void himax_ts_diag_func(void)
himax_get_DSRAM_data(private_ts->client, info_data);
index = 0;
- for (i = 0; i < ic_data->HX_TX_NUM; i++)
- {
- for (j = 0; j < ic_data->HX_RX_NUM; j++)
- {
- new_data = (short)(info_data[index + 1] << 8 | info_data[index]);
- if(diag_command == 9){
- mutual_data[i*ic_data->HX_RX_NUM+j] = new_data;
- }else if(diag_command == 91){ //Keep max data for 100 frame
- if(mutual_data[i * ic_data->HX_RX_NUM + j] < new_data)
- mutual_data[i * ic_data->HX_RX_NUM + j] = new_data;
- }else if(diag_command == 92){ //Cal data for [N]-[N-1] frame
- mutual_data_new[i * ic_data->HX_RX_NUM + j] = new_data;
- mutual_data[i * ic_data->HX_RX_NUM + j] = mutual_data_new[i * ic_data->HX_RX_NUM + j] - mutual_data_old[i * ic_data->HX_RX_NUM + j];
+ for (i = 0 ; i < ic_data->HX_TX_NUM ; i++) {
+ for (j = 0 ; j < ic_data->HX_RX_NUM ; j++) {
+ new_data = (short)(info_data[index + 1]
+ << 8 | info_data[index]);
+ if (diag_command == 9) {
+ mutual_data[i * ic_data->HX_RX_NUM + j]
+ = new_data;
+ /*Keep max data for 100 frame*/
+ } else if (diag_command == 91) {
+ if (mutual_data[i * ic_data->HX_RX_NUM + j]
+ < new_data) {
+ mutual_data[i * ic_data->HX_RX_NUM + j]
+ = new_data;
+ }
+ /*Cal data for [N]-[N-1] frame*/
+ } else if (diag_command == 92) {
+ mutual_data_new[i * ic_data->HX_RX_NUM + j]
+ = new_data;
+
+ mutual_data[i * ic_data->HX_RX_NUM + j] =
+ mutual_data_new[i * ic_data->HX_RX_NUM + j] -
+ mutual_data_old[i * ic_data->HX_RX_NUM + j];
}
index += 2;
}
}
- if(diag_command == 92){
- memcpy(mutual_data_old,mutual_data_new,x_channel * y_channel * sizeof(int16_t)); //copy N data to N-1 array
+ /*copy N data to N-1 array*/
+ if (diag_command == 92) {
+ memcpy(mutual_data_old, mutual_data_new,
+ x_channel * y_channel * sizeof(int16_t));
}
+
diag_max_cnt++;
- if(diag_command == 9 || diag_command == 92){
- queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
- }else if(diag_command == 91){
- if(diag_max_cnt > 100) //count for 100 frame
- {
- //Clear DSRAM flag
+ if (diag_command == 9 || diag_command == 92) {
+ queue_delayed_work(private_ts->himax_diag_wq,
+ &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+ } else if (diag_command == 91) {
+ if (diag_max_cnt > 100) {/*count for 100 frame*/
+ /*Clear DSRAM flag*/
DSRAM_Flag = false;
- //Enable ISR
- himax_int_enable(private_ts->client->irq,1);
+ /*Enable ISR*/
+ himax_int_enable(private_ts->client->irq, 1);
- //=====================================
- // test result command : 0x8002_0324 ==> 0x00
- //=====================================
+ /*=====================================
+ test result command : 0x8002_0324 ==> 0x00
+ =====================================*/
himax_diag_register_set(private_ts->client, 0x00);
- }else{
- queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ);
+ } else {
+ queue_delayed_work(private_ts->himax_diag_wq,
+ &private_ts->himax_diag_delay_wrok, 1 / 10 * HZ);
}
}
}
-static ssize_t himax_diag_write(struct file *filp, const char __user *buff, size_t len, loff_t *data)
+static ssize_t himax_diag_write
+(struct file *filp, const char __user *buff, size_t len, loff_t *data)
{
char messages[80] = {0};
@@ -915,67 +893,66 @@ static ssize_t himax_diag_write(struct file *filp, const char __user *buff, size
memset(receive, 0x00, sizeof(receive));
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(messages, buff, len))
- {
return -EFAULT;
- }
- if (messages[1] == 0x0A){
- diag_command =messages[0] - '0';
- }else{
- diag_command =(messages[0] - '0')*10 + (messages[1] - '0');
- }
- I("[Himax]diag_command=0x%x\n",diag_command);
- if (diag_command < 0x04){
- if(DSRAM_Flag)
- {
- //1. Clear DSRAM flag
+ if (messages[1] == 0x0A)
+ diag_command = messages[0] - '0';
+ else
+ diag_command = (messages[0] - '0') * 10 + (messages[1] - '0');
+
+
+ I("[Himax]diag_command=0x%x\n", diag_command);
+ if (diag_command < 0x04) {
+ if (DSRAM_Flag) {
+ /*1. Clear DSRAM flag*/
DSRAM_Flag = false;
- //2. Stop DSRAM thread
- cancel_delayed_work_sync(&private_ts->himax_diag_delay_wrok);
+ /*2. Stop DSRAM thread*/
+ cancel_delayed_work_sync
+ (&private_ts->himax_diag_delay_wrok);
- //3. Enable ISR
- himax_int_enable(private_ts->client->irq,1);
+ /*3. Enable ISR*/
+ himax_int_enable(private_ts->client->irq, 1);
}
command[0] = diag_command;
himax_diag_register_set(private_ts->client, command[0]);
- }
- //coordinate dump start
- else if (diag_command == 0x08) {
- E("%s: coordinate_dump_file_create error\n", __func__);
- }
- else if (diag_command == 0x09 || diag_command == 91 || diag_command == 92){
+ /*coordinate dump start*/
+ } else if (diag_command == 0x09 ||
+ diag_command == 91 || diag_command == 92) {
+
diag_max_cnt = 0;
- memset(diag_mutual, 0x00, x_channel * y_channel * sizeof(int16_t)); //Set data 0 everytime
+ /*Set data 0 everytime*/
+ memset(diag_mutual, 0x00,
+ x_channel * y_channel * sizeof(int16_t));
- //1. Disable ISR
- himax_int_enable(private_ts->client->irq,0);
+ /*1. Disable ISR*/
+ himax_int_enable(private_ts->client->irq, 0);
- //2. Start DSRAM thread
- //himax_diag_register_set(private_ts->client, 0x0A);
+ /*2. Start DSRAM thread*/
+ /*himax_diag_register_set(private_ts->client, 0x0A);*/
- queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100);
+ queue_delayed_work(private_ts->himax_diag_wq,
+ &private_ts->himax_diag_delay_wrok, 2 * HZ / 100);
I("%s: Start get raw data in DSRAM\n", __func__);
- //3. Set DSRAM flag
+ /*3. Set DSRAM flag*/
DSRAM_Flag = true;
- }else{
+ } else {
command[0] = 0x00;
himax_diag_register_set(private_ts->client, command[0]);
- E("[Himax]Diag command error!diag_command=0x%x\n",diag_command);
+ E("[Himax]Diag command error!diag_command=0x%x\n",
+ diag_command);
}
return len;
}
-static const struct file_operations himax_proc_diag_ops =
-{
+const struct file_operations himax_proc_diag_ops = {
.owner = THIS_MODULE,
.open = himax_diag_proc_open,
.read = seq_read,
@@ -989,23 +966,20 @@ static ssize_t himax_reset_write(struct file *file, const char *buff,
{
char buf_tmp[12];
- if (len >= 12)
- {
+ if (len >= 12) {
I("%s: no command exceeds 12 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf_tmp, buff, len))
- {
return -EFAULT;
- }
- //if (buf_tmp[0] == '1')
- // ESD_HW_REST();
+
+ /*if (buf_tmp[0] == '1')
+ ESD_HW_REST();*/
return len;
}
-static const struct file_operations himax_proc_reset_ops =
-{
+const struct file_operations himax_proc_reset_ops = {
.owner = THIS_MODULE,
.write = himax_reset_write,
};
@@ -1018,291 +992,263 @@ static ssize_t himax_debug_read(struct file *file, char *buf,
size_t count = 0;
char *temp_buf;
- if(!HX_PROC_SEND_FLAG)
- {
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf){
- HX_PROC_SEND_FLAG=0;
- return count;
- }
-
- if (debug_level_cmd == 't')
- {
- if (fw_update_complete)
- count += snprintf(temp_buf+count, len-count, "FW Update Complete ");
- else
- {
- count += snprintf(temp_buf+count, len-count, "FW Update Fail ");
- }
- }
- else if (debug_level_cmd == 'h')
- {
- if (handshaking_result == 0)
- {
- count += snprintf(temp_buf+count, len-count, "Handshaking Result = %d (MCU Running)\n", handshaking_result);
- }
- else if (handshaking_result == 1)
- {
- count += snprintf(temp_buf+count, len-count, "Handshaking Result = %d (MCU Stop)\n", handshaking_result);
- }
- else if (handshaking_result == 2)
- {
- count += snprintf(temp_buf+count, len-count, "Handshaking Result = %d (I2C Error)\n", handshaking_result);
- }
- else
- {
- count += snprintf(temp_buf+count, len-count, "Handshaking Result = error\n");
- }
- }
- else if (debug_level_cmd == 'v')
- {
- count += snprintf(temp_buf+count, len-count, "FW_VER = ");
- count += snprintf(temp_buf+count, len-count, "0x%2.2X\n", ic_data->vendor_fw_ver);
- count += snprintf(temp_buf+count, len-count, "CONFIG_VER = ");
- count += snprintf(temp_buf+count, len-count, "0x%2.2X\n", ic_data->vendor_config_ver);
- count += snprintf(temp_buf+count, len-count, "\n");
- }
- else if (debug_level_cmd == 'd')
- {
- count += snprintf(temp_buf+count, len-count, "Himax Touch IC Information :\n");
- if (IC_TYPE == HX_85XX_D_SERIES_PWON)
- {
- count += snprintf(temp_buf+count, len-count, "IC Type : D\n");
- }
- else if (IC_TYPE == HX_85XX_E_SERIES_PWON)
- {
- count += snprintf(temp_buf+count, len-count, "IC Type : E\n");
- }
- else if (IC_TYPE == HX_85XX_ES_SERIES_PWON)
- {
- count += snprintf(temp_buf+count, len-count, "IC Type : ES\n");
- }
- else if (IC_TYPE == HX_85XX_F_SERIES_PWON)
- {
- count += snprintf(temp_buf+count, len-count, "IC Type : F\n");
- }
- else
- {
- count += snprintf(temp_buf+count, len-count, "IC Type error.\n");
+ if (debug_level_cmd == 't') {
+ if (fw_update_complete) {
+ count += snprintf(temp_buf, len,
+ "FW Update Complete ");
+ } else {
+ count += snprintf(temp_buf, len,
+ "FW Update Fail ");
}
- if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_SW)
- {
- count += snprintf(temp_buf+count, len-count, "IC Checksum : SW\n");
+ } else if (debug_level_cmd == 'h') {
+ if (handshaking_result == 0) {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = %d (MCU Running)\n",
+ handshaking_result);
+ } else if (handshaking_result == 1) {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = %d (MCU Stop)\n",
+ handshaking_result);
+ } else if (handshaking_result == 2) {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = %d (I2C Error)\n",
+ handshaking_result);
+ } else {
+ count += snprintf(temp_buf, len,
+ "Handshaking Result = error\n");
}
- else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_HW)
- {
- count += snprintf(temp_buf+count, len-count, "IC Checksum : HW\n");
+ } else if (debug_level_cmd == 'v') {
+ count += snprintf(temp_buf + count, len,
+ "FW_VER = ");
+ count += snprintf(temp_buf + count, len,
+ "0x%2.2X\n", ic_data->vendor_fw_ver);
+ count += snprintf(temp_buf + count, len,
+ "CONFIG_VER = ");
+ count += snprintf(temp_buf + count, len,
+ "0x%2.2X\n", ic_data->vendor_config_ver);
+ count += snprintf(temp_buf + count, len,
+ "\n");
+ } else if (debug_level_cmd == 'd') {
+ count += snprintf(temp_buf + count, len,
+ "Himax Touch IC Information :\n");
+ if (IC_TYPE == HX_85XX_D_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : D\n");
+ } else if (IC_TYPE == HX_85XX_E_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : E\n");
+ } else if (IC_TYPE == HX_85XX_ES_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : ES\n");
+ } else if (IC_TYPE == HX_85XX_F_SERIES_PWON) {
+ count += snprintf(temp_buf + count, len,
+ "IC Type : F\n");
+ } else {
+ count += snprintf(temp_buf + count, len,
+ "IC Type error.\n");
}
- else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_CRC)
- {
- count += snprintf(temp_buf+count, len-count, "IC Checksum : CRC\n");
+ if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_SW) {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum : SW\n");
+ } else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_HW) {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum : HW\n");
+ } else if (IC_CHECKSUM == HX_TP_BIN_CHECKSUM_CRC) {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum : CRC\n");
+ } else {
+ count += snprintf(temp_buf + count, len,
+ "IC Checksum error.\n");
}
- else
- {
- count += snprintf(temp_buf+count, len-count, "IC Checksum error.\n");
+ if (ic_data->HX_INT_IS_EDGE) {
+ count += snprintf(temp_buf + count, len,
+ "Interrupt : EDGE TIRGGER\n");
+ } else {
+ count += snprintf(temp_buf + count, len,
+ "Interrupt : LEVEL TRIGGER\n");
}
-
- if (ic_data->HX_INT_IS_EDGE)
- {
- count += snprintf(temp_buf+count, len-count, "Interrupt : EDGE TIRGGER\n");
- }
- else
- {
- count += snprintf(temp_buf+count, len-count, "Interrupt : LEVEL TRIGGER\n");
- }
-
- count += snprintf(temp_buf+count, len-count, "RX Num : %d\n", ic_data->HX_RX_NUM);
- count += snprintf(temp_buf+count, len-count, "TX Num : %d\n", ic_data->HX_TX_NUM);
- count += snprintf(temp_buf+count, len-count, "BT Num : %d\n", ic_data->HX_BT_NUM);
- count += snprintf(temp_buf+count, len-count, "X Resolution : %d\n", ic_data->HX_X_RES);
- count += snprintf(temp_buf+count, len-count, "Y Resolution : %d\n", ic_data->HX_Y_RES);
- count += snprintf(temp_buf+count, len-count, "Max Point : %d\n", ic_data->HX_MAX_PT);
- count += snprintf(temp_buf+count, len-count, "XY reverse : %d\n", ic_data->HX_XY_REVERSE);
+ count += snprintf(temp_buf + count, len,
+ "RX Num : %d\n", ic_data->HX_RX_NUM);
+ count += snprintf(temp_buf + count, len,
+ "TX Num : %d\n", ic_data->HX_TX_NUM);
+ count += snprintf(temp_buf + count, len,
+ "BT Num : %d\n", ic_data->HX_BT_NUM);
+ count += snprintf(temp_buf + count, len,
+ "X Resolution : %d\n", ic_data->HX_X_RES);
+ count += snprintf(temp_buf + count, len,
+ "Y Resolution : %d\n", ic_data->HX_Y_RES);
+ count += snprintf(temp_buf + count, len,
+ "Max Point : %d\n", ic_data->HX_MAX_PT);
+ count += snprintf(temp_buf + count, len,
+ "XY reverse : %d\n", ic_data->HX_XY_REVERSE);
#ifdef HX_TP_PROC_2T2R
- if(Is_2T2R)
- {
- count += snprintf(temp_buf+count, len-count, "2T2R panel\n");
- count += snprintf(temp_buf+count, len-count, "RX Num_2 : %d\n", HX_RX_NUM_2);
- count += snprintf(temp_buf+count, len-count, "TX Num_2 : %d\n", HX_TX_NUM_2);
+ if (Is_2T2R) {
+ count += snprintf(temp_buf + count, len,
+ "2T2R panel\n");
+ count += snprintf(temp_buf + count, len,
+ "RX Num_2 : %d\n", HX_RX_NUM_2);
+ count += snprintf(temp_buf + count, len,
+ "TX Num_2 : %d\n", HX_TX_NUM_2);
}
#endif
- }
- else if (debug_level_cmd == 'i')
- {
- count += snprintf(temp_buf+count, len-count, "Himax Touch Driver Version:\n");
- count += snprintf(temp_buf+count, len-count, "%s\n", HIMAX_DRIVER_VER);
+ } else if (debug_level_cmd == 'i') {
+ count += snprintf(temp_buf + count, len,
+ "Himax Touch Driver Version:\n");
+ count += snprintf(temp_buf + count, len,
+ "%s\n", HIMAX_DRIVER_VER);
}
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
- HX_PROC_SEND_FLAG=1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return count;
}
static ssize_t himax_debug_write(struct file *file, const char *buff,
size_t len, loff_t *pos)
{
- const struct firmware *fw = NULL;
- unsigned char *fw_data = NULL;
+ int result = 0;
char fileName[128];
char buf[80] = {0};
- int result;
+ const struct firmware *fw = NULL;
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
- if ( buf[0] == 'h') //handshaking
- {
+ if (buf[0] == 'h') {/*handshaking*/
debug_level_cmd = buf[0];
- himax_int_enable(private_ts->client->irq,0);
+ himax_int_enable(private_ts->client->irq, 0);
- handshaking_result = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail
+ /*0:Running, 1:Stop, 2:I2C Fail*/
+ handshaking_result = himax_hand_shaking(private_ts->client);
- himax_int_enable(private_ts->client->irq,1);
+ himax_int_enable(private_ts->client->irq, 1);
return len;
- }
-
- else if ( buf[0] == 'v') //firmware version
- {
+ } else if (buf[0] == 'v') { /*firmware version*/
debug_level_cmd = buf[0];
- himax_int_enable(private_ts->client->irq,0);
+ himax_int_enable(private_ts->client->irq, 0);
#ifdef HX_RST_PIN_FUNC
- himax_HW_reset(false,false);
+ himax_HW_reset(false, false);
#endif
himax_read_FW_ver(private_ts->client);
- //himax_check_chip_version();
+ /*himax_check_chip_version();*/
#ifdef HX_RST_PIN_FUNC
- himax_HW_reset(true,false);
+ himax_HW_reset(true, false);
#endif
- himax_int_enable(private_ts->client->irq,1);
+ himax_int_enable(private_ts->client->irq, 1);
return len;
- }
+ } else if (buf[0] == 'd') { /*ic information*/
- else if ( buf[0] == 'd') //ic information
- {
debug_level_cmd = buf[0];
return len;
- }
+ } else if (buf[0] == 'i') {/*driver version*/
- else if ( buf[0] == 'i') //driver version
- {
debug_level_cmd = buf[0];
return len;
- }
-
- else if (buf[0] == 't')
- {
+ } else if (buf[0] == 't') {
- himax_int_enable(private_ts->client->irq,0);
+ himax_int_enable(private_ts->client->irq, 0);
+ debug_level_cmd = buf[0];
+ fw_update_complete = false;
- debug_level_cmd = buf[0];
- fw_update_complete = false;
+ result = himax_load_CRC_bin_file(private_ts->client);
+ if (result < 0) {
+ E("%s: himax_load_CRC_bin_file fail Error Code=%d.\n",
+ __func__, result);
+ return result;
+ }
memset(fileName, 0, 128);
- // parse the file name
+/* parse the file name*/
snprintf(fileName, len-4, "%s", &buf[4]);
I("%s: upgrade from file(%s) start!\n", __func__, fileName);
- // open file
result = request_firmware(&fw, fileName, private_ts->dev);
- if (result) {
- E("%s: open firmware file failed\n", __func__);
- goto firmware_upgrade_done;
- //return len;
- }
-
- I("%s: FW len %d\n", __func__, fw->size);
- fw_data = (unsigned char *)fw->data;
-
- I("%s: FW image,len %d: %02X, %02X, %02X, %02X\n", __func__, result, upgrade_fw[0], upgrade_fw[1], upgrade_fw[2], upgrade_fw[3]);
-
- if (fw_data != NULL)
- {
- // start to upgrade
- himax_int_enable(private_ts->client->irq,0);
-
- if ((buf[1] == '6') && (buf[2] == '0'))
- {
- if (fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,upgrade_fw, result, false) == 0)
- {
- E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ if (result < 0) {
+ I("fail to request_firmware fwpath: %s (ret:%d)\n",
+ fileName, result);
+ return result;
+ }
+ I("%s: FW image: %02X, %02X, %02X, %02X ret=%d\n", __func__,
+ fw->data[0], fw->data[1], fw->data[2], fw->data[3], result);
+ if (result >= 0) {
+ /*start to upgrade*/
+ himax_int_enable(private_ts->client->irq, 0);
+
+ if ((buf[1] == '6') && (buf[2] == '0')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_60k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = false;
- }
- else
- {
- I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = true;
}
- }
- else if ((buf[1] == '6') && (buf[2] == '4'))
- {
- if (fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,upgrade_fw, result, false) == 0)
- {
- E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ } else if ((buf[1] == '6') && (buf[2] == '4')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_64k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = false;
- }
- else
- {
- I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = true;
}
- }
- else if ((buf[1] == '2') && (buf[2] == '4'))
- {
- if (fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,upgrade_fw, result, false) == 0)
- {
- E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ } else if ((buf[1] == '2') && (buf[2] == '4')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_124k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = false;
- }
- else
- {
- I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = true;
}
- }
- else if ((buf[1] == '2') && (buf[2] == '8'))
- {
- if (fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,upgrade_fw, result, false) == 0)
- {
- E("%s: TP upgrade error, line: %d\n", __func__, __LINE__);
+ } else if ((buf[1] == '2') && (buf[2] == '8')) {
+ if (fts_ctpm_fw_upgrade_with_sys_fs_128k
+ (private_ts->client, (unsigned char *)fw->data,
+ fw->size, false) == 0) {
+ E("%s: TP upgrade error, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = false;
- }
- else
- {
- I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__);
+ } else {
+ I("%s: TP upgrade OK, line: %d\n",
+ __func__, __LINE__);
fw_update_complete = true;
}
- }
- else
- {
- E("%s: Flash command fail: %d\n", __func__, __LINE__);
+ } else {
+ E("%s: Flash command fail: %d\n",
+ __func__, __LINE__);
fw_update_complete = false;
}
release_firmware(fw);
goto firmware_upgrade_done;
- //return count;
+ /*return count;*/
}
}
- firmware_upgrade_done:
+firmware_upgrade_done:
#ifdef HX_RST_PIN_FUNC
- himax_HW_reset(true,false);
+ himax_HW_reset(true, false);
#endif
himax_sense_on(private_ts->client, 0x01);
@@ -1310,16 +1256,15 @@ static ssize_t himax_debug_write(struct file *file, const char *buff,
#ifdef HX_ESD_WORKAROUND
HX_ESD_RESET_ACTIVATE = 1;
#endif
- himax_int_enable(private_ts->client->irq,1);
+ himax_int_enable(private_ts->client->irq, 1);
- //todo himax_chip->tp_firmware_upgrade_proceed = 0;
- //todo himax_chip->suspend_state = 0;
- //todo enable_irq(himax_chip->irq);
+ /*todo himax_chip->tp_firmware_upgrade_proceed = 0;
+ todo himax_chip->suspend_state = 0;
+ todo enable_irq(himax_chip->irq);*/
return len;
}
-static const struct file_operations himax_proc_debug_ops =
-{
+const struct file_operations himax_proc_debug_ops = {
.owner = THIS_MODULE,
.read = himax_debug_read,
.write = himax_debug_write,
@@ -1376,9 +1321,9 @@ bool getFlashDumpGoing(void)
void setFlashBuffer(void)
{
- flash_buffer = kzalloc(Flash_Size * sizeof(uint8_t), GFP_KERNEL);
- if (flash_buffer)
- memset(flash_buffer,0x00,Flash_Size);
+ flash_buffer = kzalloc
+ (Flash_Size * sizeof(uint8_t), GFP_KERNEL);
+ memset(flash_buffer, 0x00, Flash_Size);
}
void setSysOperation(uint8_t operation)
@@ -1389,7 +1334,8 @@ void setSysOperation(uint8_t operation)
static void setFlashDumpProgress(uint8_t progress)
{
flash_progress = progress;
- //I("setFlashDumpProgress : progress = %d ,flash_progress = %d \n",progress,flash_progress);
+ /*I("setFlashDumpProgress : progress = %d ,
+ flash_progress = %d\n",progress,flash_progress);*/
}
static void setFlashDumpComplete(uint8_t status)
@@ -1432,130 +1378,113 @@ static ssize_t himax_proc_flash_read(struct file *file, char *buf,
{
int ret = 0;
int loop_i;
- uint8_t local_flash_read_step=0;
+ uint8_t local_flash_read_step = 0;
uint8_t local_flash_complete = 0;
uint8_t local_flash_progress = 0;
uint8_t local_flash_command = 0;
uint8_t local_flash_fail = 0;
char *temp_buf;
+
local_flash_complete = getFlashDumpComplete();
local_flash_progress = getFlashDumpProgress();
local_flash_command = getFlashCommand();
local_flash_fail = getFlashDumpFail();
- I("flash_progress = %d \n",local_flash_progress);
- if(!HX_PROC_SEND_FLAG)
- {
+ I("flash_progress = %d\n", local_flash_progress);
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
-
- if (local_flash_fail)
- {
- ret += snprintf(temp_buf+ret, len-ret, "FlashStart:Fail \n");
- ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ if (local_flash_fail) {
+ ret += snprintf(temp_buf + ret, len,
+ "FlashStart:Fail\n");
+ ret += snprintf(temp_buf + ret, len,
+ "FlashEnd");
+ ret += snprintf(temp_buf + ret, len,
+ "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
return ret;
}
- if (!local_flash_complete)
- {
- ret += snprintf(temp_buf+ret, len-ret, "FlashStart:Ongoing:0x%2.2x \n",flash_progress);
- ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ if (!local_flash_complete) {
+ ret += snprintf(temp_buf+ret, len,
+ "FlashStart:Ongoing:0x%2.2x\n", flash_progress);
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
return ret;
}
- if (local_flash_command == 1 && local_flash_complete)
- {
- ret += snprintf(temp_buf+ret, len-ret, "FlashStart:Complete \n");
- ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ if (local_flash_command == 1 && local_flash_complete) {
+ ret += snprintf(temp_buf+ret, len,
+ "FlashStart:Complete\n");
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
return ret;
}
- if (local_flash_command == 3 && local_flash_complete)
- {
- ret += snprintf(temp_buf+ret, len-ret, "FlashStart: \n");
- for(loop_i = 0; loop_i < 128; loop_i++)
- {
- ret += snprintf(temp_buf+ret, len-ret, "x%2.2x", flash_buffer[loop_i]);
+ if (local_flash_command == 3 && local_flash_complete) {
+ ret += snprintf(temp_buf+ret, len, "FlashStart:\n");
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
+ ret += snprintf(temp_buf + ret, len,
+ "x%2.2x", flash_buffer[loop_i]);
if ((loop_i % 16) == 15)
- {
- ret += snprintf(temp_buf+ret, len-ret, "\n");
- }
+ ret += snprintf(temp_buf + ret, len,
+ "\n");
}
- ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
return ret;
}
- //flash command == 0 , report the data
+ /*flash command == 0 , report the data*/
local_flash_read_step = getFlashReadStep();
- ret += snprintf(temp_buf+ret, len-ret, "FlashStart:%2.2x \n",local_flash_read_step);
+ ret += snprintf(temp_buf + ret, len,
+ "FlashStart:%2.2x\n", local_flash_read_step);
- for (loop_i = 0; loop_i < 1024; loop_i++)
- {
- ret += snprintf(temp_buf+ret, len-ret, "x%2.2X", flash_buffer[local_flash_read_step*1024 + loop_i]);
+ for (loop_i = 0 ; loop_i < 1024 ; loop_i++) {
+ ret += snprintf(temp_buf + ret, len, "x%2.2X",
+ flash_buffer[local_flash_read_step * 1024 + loop_i]);
if ((loop_i % 16) == 15)
- {
- ret += snprintf(temp_buf+ret, len-ret, "\n");
- }
+ ret += snprintf(temp_buf + ret, len, "\n");
}
- ret += snprintf(temp_buf+ret, len-ret, "FlashEnd");
- ret += snprintf(temp_buf+ret, len-ret, "\n");
+ ret += snprintf(temp_buf + ret, len, "FlashEnd");
+ ret += snprintf(temp_buf + ret, len, "\n");
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
-static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
- size_t len, loff_t *pos)
+static ssize_t himax_proc_flash_write(struct file *file,
+const char *buff, size_t len, loff_t *pos)
{
char buf_tmp[6];
unsigned long result = 0;
@@ -1563,85 +1492,74 @@ static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
int base = 0;
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
memset(buf_tmp, 0x0, sizeof(buf_tmp));
I("%s: buf[0] = %s\n", __func__, buf);
- if (getSysOperation() == 1)
- {
+ if (getSysOperation() == 1) {
E("%s: PROC is busy , return!\n", __func__);
return len;
}
- if (buf[0] == '0')
- {
+ if (buf[0] == '0') {
setFlashCommand(0);
- if (buf[1] == ':' && buf[2] == 'x')
- {
+ if (buf[1] == ':' && buf[2] == 'x') {
memcpy(buf_tmp, buf + 3, 2);
I("%s: read_Step = %s\n", __func__, buf_tmp);
- if (!kstrtoul(buf_tmp, 16, &result))
- {
- I("%s: read_Step = %lu \n", __func__, result);
+ if (!kstrtoul(buf_tmp, 16, &result)) {
+ I("%s: read_Step = %lu\n", __func__, result);
setFlashReadStep(result);
}
}
- }
- else if (buf[0] == '1')// 1_60,1_64,1_24,1_28 for flash size 60k,64k,124k,128k
- {
+ /* 1_60,1_64,1_24,1_28 for flash size 60k,64k,124k,128k*/
+ } else if (buf[0] == '1') {
+
setSysOperation(1);
setFlashCommand(1);
setFlashDumpProgress(0);
setFlashDumpComplete(0);
setFlashDumpFail(0);
- if ((buf[1] == '_' ) && (buf[2] == '6' )){
- if (buf[3] == '0'){
+ if ((buf[1] == '_') && (buf[2] == '6')) {
+ if (buf[3] == '0')
Flash_Size = FW_SIZE_60k;
- }else if (buf[3] == '4'){
+ else if (buf[3] == '4')
Flash_Size = FW_SIZE_64k;
- }
- }else if ((buf[1] == '_' ) && (buf[2] == '2' )){
- if (buf[3] == '4'){
+
+ } else if ((buf[1] == '_') && (buf[2] == '2')) {
+ if (buf[3] == '4')
Flash_Size = FW_SIZE_124k;
- }else if (buf[3] == '8'){
+ else if (buf[3] == '8')
Flash_Size = FW_SIZE_128k;
- }
}
queue_work(private_ts->flash_wq, &private_ts->flash_work);
- }
- else if (buf[0] == '2') // 2_60,2_64,2_24,2_28 for flash size 60k,64k,124k,128k
- {
+ /* 2_60,2_64,2_24,2_28 for flash size 60k,64k,124k,128k*/
+ } else if (buf[0] == '2') {
setSysOperation(1);
setFlashCommand(2);
setFlashDumpProgress(0);
setFlashDumpComplete(0);
setFlashDumpFail(0);
- if ((buf[1] == '_' ) && (buf[2] == '6' )){
- if (buf[3] == '0'){
+ if ((buf[1] == '_') && (buf[2] == '6')) {
+ if (buf[3] == '0')
Flash_Size = FW_SIZE_60k;
- }else if (buf[3] == '4'){
+ else if (buf[3] == '4')
Flash_Size = FW_SIZE_64k;
- }
- }else if ((buf[1] == '_' ) && (buf[2] == '2' )){
- if (buf[3] == '4'){
+
+ } else if ((buf[1] == '_') && (buf[2] == '2')) {
+ if (buf[3] == '4')
Flash_Size = FW_SIZE_124k;
- }else if (buf[3] == '8'){
+ else if (buf[3] == '8')
Flash_Size = FW_SIZE_128k;
- }
+
}
queue_work(private_ts->flash_wq, &private_ts->flash_work);
- }
- else if (buf[0] == '3')
- {
+ } else if (buf[0] == '3') {
setSysOperation(1);
setFlashCommand(3);
setFlashDumpProgress(0);
@@ -1650,20 +1568,14 @@ static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
memcpy(buf_tmp, buf + 3, 2);
if (!kstrtoul(buf_tmp, 16, &result))
- {
setFlashDumpSector(result);
- }
memcpy(buf_tmp, buf + 7, 2);
if (!kstrtoul(buf_tmp, 16, &result))
- {
setFlashDumpPage(result);
- }
queue_work(private_ts->flash_wq, &private_ts->flash_work);
- }
- else if (buf[0] == '4')
- {
+ } else if (buf[0] == '4') {
I("%s: command 4 enter.\n", __func__);
setSysOperation(1);
setFlashCommand(4);
@@ -1673,40 +1585,29 @@ static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
memcpy(buf_tmp, buf + 3, 2);
if (!kstrtoul(buf_tmp, 16, &result))
- {
setFlashDumpSector(result);
- }
else
- {
E("%s: command 4 , sector error.\n", __func__);
return len;
- }
+
memcpy(buf_tmp, buf + 7, 2);
if (!kstrtoul(buf_tmp, 16, &result))
- {
setFlashDumpPage(result);
- }
else
- {
E("%s: command 4 , page error.\n", __func__);
return len;
- }
base = 11;
I("=========Himax flash page buffer start=========\n");
- for(loop_i=0;loop_i<128 && base<80;loop_i++)
- {
+ for (loop_i = 0 ; loop_i < 128 ; loop_i++) {
memcpy(buf_tmp, buf + base, 2);
- if (!kstrtoul(buf_tmp, 16, &result))
- {
+ if (!kstrtoul(buf_tmp, 16, &result)) {
flash_buffer[loop_i] = result;
- I("%d ",flash_buffer[loop_i]);
+ I("%d ", flash_buffer[loop_i]);
if (loop_i % 16 == 15)
- {
I("\n");
- }
}
base += 3;
}
@@ -1717,8 +1618,7 @@ static ssize_t himax_proc_flash_write(struct file *file, const char *buff,
return len;
}
-static const struct file_operations himax_proc_flash_ops =
-{
+const struct file_operations himax_proc_flash_ops = {
.owner = THIS_MODULE,
.read = himax_proc_flash_read,
.write = himax_proc_flash_write,
@@ -1728,31 +1628,44 @@ void himax_ts_flash_func(void)
{
uint8_t local_flash_command = 0;
- himax_int_enable(private_ts->client->irq,0);
+ himax_int_enable(private_ts->client->irq, 0);
setFlashDumpGoing(true);
- //sector = getFlashDumpSector();
- //page = getFlashDumpPage();
+ /*sector = getFlashDumpSector();*/
+ /*page = getFlashDumpPage();*/
local_flash_command = getFlashCommand();
msleep(100);
- I("%s: local_flash_command = %d enter.\n", __func__,local_flash_command);
+ I("%s: local_flash_command = %d enter.\n",
+ __func__, local_flash_command);
- if ((local_flash_command == 1 || local_flash_command == 2)|| (local_flash_command==0x0F))
- {
- himax_flash_dump_func(private_ts->client, local_flash_command,Flash_Size, flash_buffer);
+ if ((local_flash_command == 1 || local_flash_command == 2)
+ || (local_flash_command == 0x0F)) {
+ himax_flash_dump_func(private_ts->client,
+ local_flash_command, Flash_Size, flash_buffer);
}
+
I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n");
- if (local_flash_command == 2)
- {
- E("Flash dump failed\n");
+ if (local_flash_command == 2) {
+ struct file *fn;
+ struct filename *vts_name;
+
+ vts_name = getname_kernel(FLASH_DUMP_FILE);
+ fn = file_open_name(vts_name, O_CREAT | O_WRONLY, 0);
+ if (!IS_ERR(fn)) {
+ I("%s create file and ready to write\n", __func__);
+ fn->f_op->write(fn, flash_buffer,
+ Flash_Size * sizeof(uint8_t), &fn->f_pos);
+
+ filp_close(fn, NULL);
+ }
}
- himax_int_enable(private_ts->client->irq,1);
+ himax_int_enable(private_ts->client->irq, 1);
setFlashDumpGoing(false);
setFlashDumpComplete(1);
@@ -1761,7 +1674,7 @@ void himax_ts_flash_func(void)
/* Flash_Dump_i2c_transfer_error:
- himax_int_enable(private_ts->client->irq,1);
+ himax_int_enable(private_ts->client->irq, 1);
setFlashDumpGoing(false);
setFlashDumpComplete(0);
setFlashDumpFail(1);
@@ -1776,53 +1689,47 @@ void himax_ts_flash_func(void)
static ssize_t himax_self_test_read(struct file *file, char *buf,
size_t len, loff_t *pos)
{
- int val=0x00;
+ int val = 0x00;
int ret = 0;
char *temp_buf;
- I("%s: enter, %d \n", __func__, __LINE__);
- if(!HX_PROC_SEND_FLAG)
- {
+ I("%s:enter, %d\n", __func__, __LINE__);
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- himax_int_enable(private_ts->client->irq,0);//disable irq
+ himax_int_enable(private_ts->client->irq, 0);/*disable irq*/
val = himax_chip_self_test(private_ts->client);
#ifdef HX_ESD_WORKAROUND
HX_ESD_RESET_ACTIVATE = 1;
#endif
- himax_int_enable(private_ts->client->irq,1);//enable irq
+ himax_int_enable(private_ts->client->irq, 1);/*enable irq*/
if (val == 0x01) {
- ret += snprintf(temp_buf+ret, len-ret, "Self_Test Pass\n");
+ ret += snprintf(temp_buf + ret, len,
+ "Self_Test Pass\n");
} else {
- ret += snprintf(temp_buf+ret, len-ret, "Self_Test Fail\n");
+ ret += snprintf(temp_buf + ret, len,
+ "Self_Test Fail\n");
}
-
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return ret;
}
/*
-static ssize_t himax_chip_self_test_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t himax_chip_self_test_store(struct device *dev,
+struct device_attribute *attr, const char *buf, size_t count)
{
char buf_tmp[2];
unsigned long result = 0;
memset(buf_tmp, 0x0, sizeof(buf_tmp));
memcpy(buf_tmp, buf, 2);
- if(!kstrtoul(buf_tmp, 16, &result))
+ if (!kstrtoul(buf_tmp, 16, &result))
{
sel_type = (uint8_t)result;
}
@@ -1831,8 +1738,7 @@ static ssize_t himax_chip_self_test_store(struct device *dev,struct device_attri
}
*/
-static const struct file_operations himax_proc_self_test_ops =
-{
+const struct file_operations himax_proc_self_test_ops = {
.owner = THIS_MODULE,
.read = himax_self_test_read,
};
@@ -1844,42 +1750,33 @@ static ssize_t himax_sense_on_off_write(struct file *file, const char *buff,
{
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
- if(buf[0] == '0')
- {
+ if (buf[0] == '0') {
himax_sense_off(private_ts->client);
- I("Sense off \n");
- }
- else if(buf[0] == '1')
- {
- if(buf[1] == '1'){
+ I("Sense off\n");
+ } else if (buf[0] == '1') {
+ if (buf[1] == '1') {
himax_sense_on(private_ts->client, 0x01);
- I("Sense on re-map off, run flash \n");
- }else if(buf[1] == '0'){
+ I("Sense on re-map off, run flash\n");
+ } else if (buf[1] == '0') {
himax_sense_on(private_ts->client, 0x00);
- I("Sense on re-map on, run sram \n");
- }else{
- I("Do nothing \n");
+ I("Sense on re-map on, run sram\n");
+ } else {
+ I("Do nothing\n");
}
- }
- else
- {
- I("Do nothing \n");
+ } else {
+ I("Do nothing\n");
}
return len;
}
-static const struct file_operations himax_proc_sense_on_off_ops =
-{
+const struct file_operations himax_proc_sense_on_off_ops = {
.owner = THIS_MODULE,
.write = himax_sense_on_off_write,
};
@@ -1893,25 +1790,18 @@ static ssize_t himax_HSEN_read(struct file *file, char *buf,
size_t count = 0;
char *temp_buf;
- if(!HX_PROC_SEND_FLAG)
- {
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return count;
- }
count = snprintf(temp_buf, len, "%d\n", ts->HSEN_enable);
- HX_PROC_SEND_FLAG=1;
+ HX_PROC_SEND_FLAG = 1;
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
+
kfree(temp_buf);
- }
- else
- HX_PROC_SEND_FLAG=0;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return count;
}
@@ -1922,22 +1812,17 @@ static ssize_t himax_HSEN_write(struct file *file, const char *buff,
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
- if (buf[0] == '0'){
+ if (buf[0] == '0')
ts->HSEN_enable = 0;
- }
- else if (buf[0] == '1'){
+ else if (buf[0] == '1')
ts->HSEN_enable = 1;
- }
else
return -EINVAL;
@@ -1948,8 +1833,7 @@ static ssize_t himax_HSEN_write(struct file *file, const char *buff,
return len;
}
-static const struct file_operations himax_proc_HSEN_ops =
-{
+const struct file_operations himax_proc_HSEN_ops = {
.owner = THIS_MODULE,
.read = himax_HSEN_read,
.write = himax_HSEN_write,
@@ -1964,25 +1848,17 @@ static ssize_t himax_SMWP_read(struct file *file, char *buf,
struct himax_ts_data *ts = private_ts;
char *temp_buf;
- if(!HX_PROC_SEND_FLAG)
- {
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return count;
- }
- count = snprintf(temp_buf, len, "%d\n", ts->SMWP_enable);
+ count = snprintf(temp_buf, "%d\n", len, ts->SMWP_enable);
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
- HX_PROC_SEND_FLAG=1;
- }
- else
- HX_PROC_SEND_FLAG=0;
+ HX_PROC_SEND_FLAG = 1;
+ } else
+ HX_PROC_SEND_FLAG = 0;
return count;
}
@@ -1993,25 +1869,17 @@ static ssize_t himax_SMWP_write(struct file *file, const char *buff,
struct himax_ts_data *ts = private_ts;
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
-
if (buf[0] == '0')
- {
ts->SMWP_enable = 0;
- }
else if (buf[0] == '1')
- {
ts->SMWP_enable = 1;
- }
else
return -EINVAL;
@@ -2022,41 +1890,33 @@ static ssize_t himax_SMWP_write(struct file *file, const char *buff,
return len;
}
-static const struct file_operations himax_proc_SMWP_ops =
-{
+const struct file_operations himax_proc_SMWP_ops = {
.owner = THIS_MODULE,
.read = himax_SMWP_read,
.write = himax_SMWP_write,
};
-static ssize_t himax_GESTURE_read(struct file *file, char *buf,
- size_t len, loff_t *pos)
+static ssize_t himax_GESTURE_read(struct file *file,
+char *buf, size_t len, loff_t *pos)
{
struct himax_ts_data *ts = private_ts;
- int i =0;
+ int i = 0;
int ret = 0;
char *temp_buf;
- if(!HX_PROC_SEND_FLAG)
- {
+ if (!HX_PROC_SEND_FLAG) {
temp_buf = kzalloc(len, GFP_KERNEL);
- if (!temp_buf) {
- HX_PROC_SEND_FLAG=0;
- return ret;
- }
- for(i=0;i<16;i++)
- ret += snprintf(temp_buf+ret, len-ret, "ges_en[%d]=%d\n", i, ts->gesture_cust_en[i]);
+ for (i = 0 ; i < 16 ; i++)
+ ret += snprintf(temp_buf + ret, len,
+ "ges_en[%d]=%d\n", i, ts->gesture_cust_en[i]);
+
HX_PROC_SEND_FLAG = 1;
if (copy_to_user(buf, temp_buf, len))
- {
I("%s,here:%d\n", __func__, __LINE__);
- }
kfree(temp_buf);
HX_PROC_SEND_FLAG = 1;
- }
- else
- {
+ } else {
HX_PROC_SEND_FLAG = 0;
ret = 0;
}
@@ -2067,35 +1927,30 @@ static ssize_t himax_GESTURE_write(struct file *file, const char *buff,
size_t len, loff_t *pos)
{
struct himax_ts_data *ts = private_ts;
- int i =0;
+ int i = 0;
char buf[80] = {0};
- if (len >= 80)
- {
+ if (len >= 80) {
I("%s: no command exceeds 80 chars.\n", __func__);
return -EFAULT;
}
if (copy_from_user(buf, buff, len))
- {
return -EFAULT;
- }
- I("himax_GESTURE_store= %s \n",buf);
- for (i=0;i<16;i++)
- {
+ I("himax_GESTURE_store= %s\n", buf);
+ for (i = 0 ; i < 16 ; i++) {
if (buf[i] == '0')
- ts->gesture_cust_en[i]= 0;
+ ts->gesture_cust_en[i] = 0;
else if (buf[i] == '1')
- ts->gesture_cust_en[i]= 1;
+ ts->gesture_cust_en[i] = 1;
else
- ts->gesture_cust_en[i]= 0;
- I("gesture en[%d]=%d \n", i, ts->gesture_cust_en[i]);
+ ts->gesture_cust_en[i] = 0;
+ I("gesture en[%d]=%d\n", i, ts->gesture_cust_en[i]);
}
return len;
}
-static const struct file_operations himax_proc_Gesture_ops =
-{
+const struct file_operations himax_proc_Gesture_ops = {
.owner = THIS_MODULE,
.read = himax_GESTURE_read,
.write = himax_GESTURE_write,
@@ -2104,202 +1959,223 @@ static const struct file_operations himax_proc_Gesture_ops =
int himax_touch_proc_init(void)
{
- himax_touch_proc_dir = proc_mkdir( HIMAX_PROC_TOUCH_FOLDER, NULL);
- if (himax_touch_proc_dir == NULL)
- {
+ himax_touch_proc_dir = proc_mkdir(HIMAX_PROC_TOUCH_FOLDER, NULL);
+ if (himax_touch_proc_dir == NULL) {
E(" %s: himax_touch_proc_dir file create failed!\n", __func__);
return -ENOMEM;
}
- himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_level_ops);
- if (himax_proc_debug_level_file == NULL)
- {
+ himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_level_ops);
+
+ if (himax_proc_debug_level_file == NULL) {
E(" %s: proc debug_level file create failed!\n", __func__);
goto fail_1;
}
- himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE, (S_IRUGO),himax_touch_proc_dir, &himax_proc_vendor_ops);
- if(himax_proc_vendor_file == NULL)
- {
+ himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE,
+ (S_IRUGO), himax_touch_proc_dir, &himax_proc_vendor_ops);
+
+ if (himax_proc_vendor_file == NULL) {
E(" %s: proc vendor file create failed!\n", __func__);
goto fail_2;
}
- himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE, (S_IRUGO),himax_touch_proc_dir, &himax_proc_attn_ops);
- if(himax_proc_attn_file == NULL)
- {
+ himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE,
+ (S_IRUGO), himax_touch_proc_dir, &himax_proc_attn_ops);
+
+ if (himax_proc_attn_file == NULL) {
E(" %s: proc attn file create failed!\n", __func__);
goto fail_3;
}
- himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_int_en_ops);
- if(himax_proc_int_en_file == NULL)
- {
+ himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_int_en_ops);
+
+ if (himax_proc_int_en_file == NULL) {
E(" %s: proc int en file create failed!\n", __func__);
goto fail_4;
}
- himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_layout_ops);
- if(himax_proc_layout_file == NULL)
- {
+ himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_layout_ops);
+
+ if (himax_proc_layout_file == NULL) {
E(" %s: proc layout file create failed!\n", __func__);
goto fail_5;
}
#ifdef HX_TP_PROC_RESET
- himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE, (S_IWUSR), himax_touch_proc_dir, &himax_proc_reset_ops);
- if(himax_proc_reset_file == NULL)
- {
+ himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE,
+ (S_IWUSR), himax_touch_proc_dir, &himax_proc_reset_ops);
+
+ if (himax_proc_reset_file == NULL) {
E(" %s: proc reset file create failed!\n", __func__);
goto fail_6;
}
#endif
#ifdef HX_TP_PROC_DIAG
- himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_ops);
- if(himax_proc_diag_file == NULL)
- {
+ himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_ops);
+
+ if (himax_proc_diag_file == NULL) {
E(" %s: proc diag file create failed!\n", __func__);
goto fail_7;
}
- himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_diag_arrange_ops);
- if(himax_proc_diag_arrange_file == NULL)
- {
+ himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE,
+ (S_IWUSR | S_IRUGO),
+ himax_touch_proc_dir, &himax_proc_diag_arrange_ops);
+
+ if (himax_proc_diag_arrange_file == NULL) {
E(" %s: proc diag file create failed!\n", __func__);
goto fail_7_1;
}
#endif
#ifdef HX_TP_PROC_REGISTER
- himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_register_ops);
- if(himax_proc_register_file == NULL)
- {
+ himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_register_ops);
+
+ if (himax_proc_register_file == NULL) {
E(" %s: proc register file create failed!\n", __func__);
goto fail_8;
}
#endif
#ifdef HX_TP_PROC_DEBUG
- himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_ops);
- if(himax_proc_debug_file == NULL)
- {
+ himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_debug_ops);
+
+ if (himax_proc_debug_file == NULL) {
E(" %s: proc debug file create failed!\n", __func__);
goto fail_9;
}
#endif
#ifdef HX_TP_PROC_FLASH_DUMP
- himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE, (S_IWUSR|S_IRUGO), himax_touch_proc_dir, &himax_proc_flash_ops);
- if(himax_proc_flash_dump_file == NULL)
- {
+ himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE,
+ (S_IWUSR | S_IRUGO), himax_touch_proc_dir, &himax_proc_flash_ops);
+
+ if (himax_proc_flash_dump_file == NULL) {
E(" %s: proc flash dump file create failed!\n", __func__);
goto fail_10;
}
#endif
#ifdef HX_TP_PROC_SELF_TEST
- himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE, (S_IRUGO), himax_touch_proc_dir, &himax_proc_self_test_ops);
- if(himax_proc_self_test_file == NULL)
- {
+ himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE,
+ (S_IRUGO), himax_touch_proc_dir, &himax_proc_self_test_ops);
+
+ if (himax_proc_self_test_file == NULL) {
E(" %s: proc self_test file create failed!\n", __func__);
goto fail_11;
}
#endif
#ifdef HX_HIGH_SENSE
- himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_HSEN_ops);
- if(himax_proc_HSEN_file == NULL)
- {
+ himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_HSEN_ops);
+
+ if (himax_proc_HSEN_file == NULL) {
E(" %s: proc HSEN file create failed!\n", __func__);
goto fail_12;
}
#endif
#ifdef HX_SMART_WAKEUP
- himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_SMWP_ops);
- if(himax_proc_SMWP_file == NULL)
- {
+ himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_SMWP_ops);
+
+ if (himax_proc_SMWP_file == NULL) {
E(" %s: proc SMWP file create failed!\n", __func__);
goto fail_13;
}
- himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_Gesture_ops);
- if(himax_proc_GESTURE_file == NULL)
- {
+
+ himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_Gesture_ops);
+
+ if (himax_proc_GESTURE_file == NULL) {
E(" %s: proc GESTURE file create failed!\n", __func__);
goto fail_14;
}
#endif
#ifdef HX_TP_PROC_SENSE_ON_OFF
- himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), himax_touch_proc_dir, &himax_proc_sense_on_off_ops);
- if(himax_proc_SENSE_ON_OFF_file == NULL)
- {
+ himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE,
+ (S_IWUSR | S_IRUGO | S_IWUGO),
+ himax_touch_proc_dir, &himax_proc_sense_on_off_ops);
+
+ if (himax_proc_SENSE_ON_OFF_file == NULL) {
E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__);
goto fail_15;
}
#endif
- return 0 ;
+ return 0;
#ifdef HX_TP_PROC_SENSE_ON_OFF
- fail_15:
+fail_15:
#endif
#ifdef HX_SMART_WAKEUP
- remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir );
- fail_14:
- remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir );
- fail_13:
+ remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir);
+fail_14:
+ remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir);
+fail_13:
#endif
#ifdef HX_HIGH_SENSE
- remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir );
- fail_12:
+ remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir);
+fail_12:
#endif
#ifdef HX_TP_PROC_SELF_TEST
- remove_proc_entry( HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir );
- fail_11:
+ remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
+fail_11:
#endif
#ifdef HX_TP_PROC_FLASH_DUMP
- remove_proc_entry( HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir );
- fail_10:
+ remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
+fail_10:
#endif
#ifdef HX_TP_PROC_DEBUG
- remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir );
- fail_9:
+ remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
+fail_9:
#endif
#ifdef HX_TP_PROC_REGISTER
- remove_proc_entry( HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir );
- fail_8:
+ remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
+fail_8:
#endif
#ifdef HX_TP_PROC_DIAG
- remove_proc_entry( HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir );
- fail_7:
- remove_proc_entry( HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir );
- fail_7_1:
+ remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
+fail_7:
+ remove_proc_entry(HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir);
+fail_7_1:
#endif
#ifdef HX_TP_PROC_RESET
- remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir );
- fail_6:
+ remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir);
+fail_6:
#endif
- remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir );
- fail_5: remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir );
- fail_4: remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir );
- fail_3: remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir );
- fail_2: remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir );
- fail_1: remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL );
+ remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir);
+fail_5: remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir);
+fail_4: remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir);
+fail_3: remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir);
+fail_2: remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir);
+fail_1: remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL);
return -ENOMEM;
}
void himax_touch_proc_deinit(void)
{
#ifdef HX_TP_PROC_SENSE_ON_OFF
- remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir );
+ remove_proc_entry(HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir);
#endif
#ifdef HX_SMART_WAKEUP
- remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir );
- remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir );
+ remove_proc_entry(HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir);
#endif
#ifdef HX_DOT_VIEW
- remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir );
+ remove_proc_entry(HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir);
#endif
#ifdef HX_TP_PROC_SELF_TEST
remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir);
@@ -2308,7 +2184,7 @@ void himax_touch_proc_deinit(void)
remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir);
#endif
#ifdef HX_TP_PROC_DEBUG
- remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir );
+ remove_proc_entry(HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir);
#endif
#ifdef HX_TP_PROC_REGISTER
remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir);
@@ -2317,13 +2193,13 @@ void himax_touch_proc_deinit(void)
remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir);
#endif
#ifdef HX_TP_PROC_RESET
- remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir );
+ remove_proc_entry(HIMAX_PROC_RESET_FILE, himax_touch_proc_dir);
#endif
- remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir );
- remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir );
- remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir );
- remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir );
- remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir );
- remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL );
+ remove_proc_entry(HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir);
+ remove_proc_entry(HIMAX_PROC_TOUCH_FOLDER, NULL);
}
#endif
diff --git a/drivers/input/touchscreen/hxchipset/himax_debug.h b/drivers/input/touchscreen/hxchipset/himax_debug.h
index 91a7ae2eb7ab..7a24a170eaca 100644
--- a/drivers/input/touchscreen/hxchipset/himax_debug.h
+++ b/drivers/input/touchscreen/hxchipset/himax_debug.h
@@ -17,7 +17,7 @@
#include "himax_common.h"
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
- #define HIMAX_PROC_TOUCH_FOLDER "android_touch"
+ #define HIMAX_PROC_TOUCH_FOLDER "android_touch"
#define HIMAX_PROC_DEBUG_LEVEL_FILE "debug_level"
#define HIMAX_PROC_VENDOR_FILE "vendor"
#define HIMAX_PROC_ATTN_FILE "attn"
@@ -33,60 +33,76 @@
uint8_t HX_PROC_SEND_FLAG;
-extern int himax_touch_proc_init(void);
-extern void himax_touch_proc_deinit(void);
-bool getFlashDumpGoing(void);
+ extern int himax_touch_proc_init(void);
+ extern void himax_touch_proc_deinit(void);
+ bool getFlashDumpGoing(void);
+
+ extern struct himax_ic_data *ic_data;
+ extern struct himax_ts_data *private_ts;
+ extern unsigned char IC_TYPE;
+ extern unsigned char IC_CHECKSUM;
+
+#ifdef QCT
+ extern irqreturn_t himax_ts_thread(int irq, void *ptr);
+#endif
+#ifdef MTK
+#ifdef CONFIG_OF_TOUCH
+ extern irqreturn_t tpd_eint_interrupt_handler(int irq, void *desc);
+#else
+ extern void tpd_eint_interrupt_handler(void);
+#endif
+#endif
#ifdef HX_TP_PROC_REGISTER
#define HIMAX_PROC_REGISTER_FILE "register"
- struct proc_dir_entry *himax_proc_register_file;
+ struct proc_dir_entry *himax_proc_register_file = NULL;
uint8_t register_command[4];
#endif
#ifdef HX_TP_PROC_DIAG
#define HIMAX_PROC_DIAG_FILE "diag"
- struct proc_dir_entry *himax_proc_diag_file;
+ struct proc_dir_entry *himax_proc_diag_file = NULL;
#define HIMAX_PROC_DIAG_ARR_FILE "diag_arr"
- struct proc_dir_entry *himax_proc_diag_arrange_file;
+ struct proc_dir_entry *himax_proc_diag_arrange_file = NULL;
#ifdef HX_TP_PROC_2T2R
static bool Is_2T2R;
static uint8_t x_channel_2;
static uint8_t y_channel_2;
static uint8_t *diag_mutual_2;
-
+
int16_t *getMutualBuffer_2(void);
- uint8_t getXChannel_2(void);
- uint8_t getYChannel_2(void);
-
- void setMutualBuffer_2(void);
- void setXChannel_2(uint8_t x);
- void setYChannel_2(uint8_t y);
+ uint8_t getXChannel_2(void);
+ uint8_t getYChannel_2(void);
+
+ void setMutualBuffer_2(void);
+ void setXChannel_2(uint8_t x);
+ void setYChannel_2(uint8_t y);
#endif
- uint8_t x_channel;
- uint8_t y_channel;
- int16_t *diag_mutual;
- int16_t *diag_mutual_new;
- int16_t *diag_mutual_old;
- uint8_t diag_max_cnt;
-
- int diag_command;
- uint8_t diag_coor[128];// = {0xFF};
+ uint8_t x_channel = 0;
+ uint8_t y_channel = 0;
+ int16_t *diag_mutual = NULL;
+ int16_t *diag_mutual_new = NULL;
+ int16_t *diag_mutual_old = NULL;
+ uint8_t diag_max_cnt = 0;
+
+ int diag_command = 0;
+ uint8_t diag_coor[128];/* = {0xFF};*/
int16_t diag_self[100] = {0};
int16_t *getMutualBuffer(void);
int16_t *getMutualNewBuffer(void);
int16_t *getMutualOldBuffer(void);
int16_t *getSelfBuffer(void);
- uint8_t getDiagCommand(void);
- uint8_t getXChannel(void);
- uint8_t getYChannel(void);
-
- void setMutualBuffer(void);
- void setMutualNewBuffer(void);
- void setMutualOldBuffer(void);
- void setXChannel(uint8_t x);
- void setYChannel(uint8_t y);
+ uint8_t getDiagCommand(void);
+ uint8_t getXChannel(void);
+ uint8_t getYChannel(void);
+
+ void setMutualBuffer(void);
+ void setMutualNewBuffer(void);
+ void setMutualOldBuffer(void);
+ void setXChannel(uint8_t x);
+ void setYChannel(uint8_t y);
uint8_t coordinate_dump_enable = 0;
struct file *coordinate_fn;
#endif
@@ -106,24 +122,24 @@ bool getFlashDumpGoing(void);
struct proc_dir_entry *himax_proc_flash_dump_file = NULL;
static int Flash_Size = 131072;
- static uint8_t *flash_buffer = NULL;
- static uint8_t flash_command = 0;
- static uint8_t flash_read_step = 0;
- static uint8_t flash_progress = 0;
- static uint8_t flash_dump_complete = 0;
- static uint8_t flash_dump_fail = 0;
- static uint8_t sys_operation = 0;
- static uint8_t flash_dump_sector = 0;
- static uint8_t flash_dump_page = 0;
- static bool flash_dump_going = false;
+ static uint8_t *flash_buffer;
+ static uint8_t flash_command;
+ static uint8_t flash_read_step;
+ static uint8_t flash_progress;
+ static uint8_t flash_dump_complete;
+ static uint8_t flash_dump_fail;
+ static uint8_t sys_operation;
+ static uint8_t flash_dump_sector;
+ static uint8_t flash_dump_page;
+ static bool flash_dump_going;
static uint8_t getFlashCommand(void);
static uint8_t getFlashDumpComplete(void);
static uint8_t getFlashDumpFail(void);
static uint8_t getFlashDumpProgress(void);
static uint8_t getFlashReadStep(void);
- //static uint8_t getFlashDumpSector(void);
- //static uint8_t getFlashDumpPage(void);
+ /*static uint8_t getFlashDumpSector(void);*/
+ /*static uint8_t getFlashDumpPage(void);*/
void setFlashBuffer(void);
uint8_t getSysOperation(void);
@@ -150,8 +166,8 @@ bool getFlashDumpGoing(void);
#ifdef HX_TP_PROC_RESET
#define HIMAX_PROC_RESET_FILE "reset"
-extern void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
-struct proc_dir_entry *himax_proc_reset_file = NULL;
+extern void himax_HW_reset(uint8_t loadconfig, uint8_t int_off);
+struct proc_dir_entry *himax_proc_reset_file;
#endif
#ifdef HX_HIGH_SENSE
@@ -165,16 +181,16 @@ struct proc_dir_entry *himax_proc_reset_file = NULL;
#endif
#ifdef HX_RST_PIN_FUNC
- void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
+ void himax_HW_reset(uint8_t loadconfig, uint8_t int_off);
#endif
#ifdef HX_SMART_WAKEUP
#define HIMAX_PROC_SMWP_FILE "SMWP"
-struct proc_dir_entry *himax_proc_SMWP_file = NULL;
+struct proc_dir_entry *himax_proc_SMWP_file;
#define HIMAX_PROC_GESTURE_FILE "GESTURE"
-struct proc_dir_entry *himax_proc_GESTURE_file = NULL;
-uint8_t HX_SMWP_EN = 0;
-//extern bool FAKE_POWER_KEY_SEND;
+struct proc_dir_entry *himax_proc_GESTURE_file;
+uint8_t HX_SMWP_EN;
+/*extern bool FAKE_POWER_KEY_SEND;*/
#endif
#endif
diff --git a/drivers/input/touchscreen/hxchipset/himax_ic.c b/drivers/input/touchscreen/hxchipset/himax_ic.c
index 6ad8dc03149b..e2934c2d2396 100644
--- a/drivers/input/touchscreen/hxchipset/himax_ic.c
+++ b/drivers/input/touchscreen/hxchipset/himax_ic.c
@@ -15,45 +15,31 @@
#include "himax_ic.h"
-static unsigned char i_TP_CRC_FW_128K[]=
-{
- #include "HX_CRC_128.i"
-};
-static unsigned char i_TP_CRC_FW_64K[]=
-{
- #include "HX_CRC_64.i"
-};
-static unsigned char i_TP_CRC_FW_124K[]=
-{
- #include "HX_CRC_124.i"
-};
-static unsigned char i_TP_CRC_FW_60K[]=
-{
- #include "HX_CRC_60.i"
-};
-
-
-unsigned long FW_VER_MAJ_FLASH_ADDR;
-unsigned long FW_VER_MAJ_FLASH_LENG;
-unsigned long FW_VER_MIN_FLASH_ADDR;
-unsigned long FW_VER_MIN_FLASH_LENG;
-unsigned long CFG_VER_MAJ_FLASH_ADDR;
-unsigned long CFG_VER_MAJ_FLASH_LENG;
-unsigned long CFG_VER_MIN_FLASH_ADDR;
-unsigned long CFG_VER_MIN_FLASH_LENG;
-
-unsigned char IC_TYPE = 0;
-unsigned char IC_CHECKSUM = 0;
-
-extern struct himax_ic_data* ic_data;
-
-int himax_hand_shaking(struct i2c_client *client) //0:Running, 1:Stop, 2:I2C Fail
+const struct firmware *i_TP_CRC_FW_128K;
+const struct firmware *i_TP_CRC_FW_64K;
+const struct firmware *i_TP_CRC_FW_124K;
+const struct firmware *i_TP_CRC_FW_60K;
+
+unsigned long FW_VER_MAJ_FLASH_ADDR;
+unsigned long FW_VER_MAJ_FLASH_LENG;
+unsigned long FW_VER_MIN_FLASH_ADDR;
+unsigned long FW_VER_MIN_FLASH_LENG;
+unsigned long CFG_VER_MAJ_FLASH_ADDR;
+unsigned long CFG_VER_MAJ_FLASH_LENG;
+unsigned long CFG_VER_MIN_FLASH_ADDR;
+unsigned long CFG_VER_MIN_FLASH_LENG;
+
+unsigned char IC_TYPE;
+unsigned char IC_CHECKSUM;
+
+ /*0:Running, 1:Stop, 2:I2C Fail*/
+int himax_hand_shaking(struct i2c_client *client)
{
int ret, result;
uint8_t hw_reset_check[1];
uint8_t hw_reset_check_2[1];
uint8_t buf0[2];
- uint8_t IC_STATUS_CHECK = 0xAA;
+ uint8_t IC_STATUS_CHECK = 0xAA;
memset(hw_reset_check, 0x00, sizeof(hw_reset_check));
memset(hw_reset_check_2, 0x00, sizeof(hw_reset_check_2));
@@ -67,45 +53,50 @@ int himax_hand_shaking(struct i2c_client *client) //0:Running, 1:Stop, 2:I2C
IC_STATUS_CHECK = 0xAA;
}
- ret = i2c_himax_master_write(client, buf0, 2, HIMAX_I2C_RETRY_TIMES);
+ ret = i2c_himax_master_write(client,
+ buf0, 2, HIMAX_I2C_RETRY_TIMES);
if (ret < 0) {
- E("[Himax]:write 0xF2 failed line: %d \n",__LINE__);
+ E("[Himax]:write 0xF2 failed line: %d\n", __LINE__);
goto work_func_send_i2c_msg_fail;
}
- msleep(50);
-
+ msleep(50);
+
buf0[0] = 0xF2;
buf0[1] = 0x00;
- ret = i2c_himax_master_write(client, buf0, 2, HIMAX_I2C_RETRY_TIMES);
+ ret = i2c_himax_master_write(client,
+ buf0, 2, HIMAX_I2C_RETRY_TIMES);
if (ret < 0) {
- E("[Himax]:write 0x92 failed line: %d \n",__LINE__);
+ E("[Himax]:write 0x92 failed line: %d\n", __LINE__);
goto work_func_send_i2c_msg_fail;
}
- usleep_range(2000, 4000);
-
- ret = i2c_himax_read(client, 0xD1, hw_reset_check, 1, HIMAX_I2C_RETRY_TIMES);
+ usleep_range(1999, 2000);
+
+ ret = i2c_himax_read(client, 0xD1,
+ hw_reset_check, 1, HIMAX_I2C_RETRY_TIMES);
if (ret < 0) {
- E("[Himax]:i2c_himax_read 0xD1 failed line: %d \n",__LINE__);
+ E("[Himax]:i2c_himax_read 0xD1 failed line: %d\n", __LINE__);
goto work_func_send_i2c_msg_fail;
}
-
- if ((IC_STATUS_CHECK != hw_reset_check[0])) {
- usleep_range(2000, 4000);
- ret = i2c_himax_read(client, 0xD1, hw_reset_check_2, 1, HIMAX_I2C_RETRY_TIMES);
+
+ if (IC_STATUS_CHECK != hw_reset_check[0]) {
+ usleep_range(1999, 2000);
+ ret = i2c_himax_read(client, 0xD1,
+ hw_reset_check_2, 1, HIMAX_I2C_RETRY_TIMES);
if (ret < 0) {
- E("[Himax]:i2c_himax_read 0xD1 failed line: %d \n",__LINE__);
+ E("[Himax]:i2c_himax_read 0xD1 failed line: %d\n",
+ __LINE__);
goto work_func_send_i2c_msg_fail;
}
-
- if (hw_reset_check[0] == hw_reset_check_2[0]) {
- result = 1;
- } else {
- result = 0;
- }
+
+ if (hw_reset_check[0] == hw_reset_check_2[0])
+ result = 1;
+ else
+ result = 0;
+
} else {
- result = 0;
+ result = 0;
}
-
+
return result;
work_func_send_i2c_msg_fail:
@@ -117,66 +108,71 @@ void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command)
uint8_t tmp_addr[4];
uint8_t tmp_data[4];
- if(diag_command != 0)
+ if (diag_command != 0)
diag_command = diag_command + 5;
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x02; tmp_addr[1] = 0x01; tmp_addr[0] = 0x80;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = diag_command;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x01; tmp_addr[0] = 0x80;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = diag_command;
himax_flash_write_burst(client, tmp_addr, tmp_data);
}
-void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer)
+void himax_flash_dump_func(struct i2c_client *client,
+uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer)
{
- //struct himax_ts_data *ts = container_of(work, struct himax_ts_data, flash_work);
-
-// uint8_t sector = 0;
-// uint8_t page = 0;
+ /*struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, flash_work);*/
+ /*uint8_t sector = 0;*/
+ /*uint8_t page = 0;*/
uint8_t tmp_addr[4];
uint8_t tmp_data[4];
uint8_t out_buffer[20];
- uint8_t in_buffer[260] = {0};
+ uint8_t in_buffer[260];
int page_prog_start = 0;
int i = 0;
himax_sense_off(client);
himax_burst_enable(client, 0);
/*=============Dump Flash Start=============*/
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================*/
+ /* SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780*/
+ /*=====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- for (page_prog_start = 0; page_prog_start < Flash_Size; page_prog_start = page_prog_start + 256)
- {
- //=================================
- // SPI Transfer Control
- // Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
- // Set read start address : 0x8000_0028 ==> 0x0000_0000
- // Set command : 0x8000_0024 ==> 0x0000_003B
- //=================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x69; tmp_data[2] = 0x40; tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
+ for (page_prog_start = 0 ; page_prog_start < Flash_Size;
+ page_prog_start = page_prog_start + 256) {
+ /*=====================================
+ SPI Transfer Control
+ Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
+ Set read start address : 0x8000_0028 ==> 0x0000_0000
+ Set command : 0x8000_0024 ==> 0x0000_003B
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x69; tmp_data[2] = 0x40;
+ tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
- if (page_prog_start < 0x100)
- {
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ if (page_prog_start < 0x100) {
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = 0x00;
tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
- {
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = (uint8_t)(page_prog_start >> 8);
tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
- {
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
tmp_data[3] = 0x00;
tmp_data[2] = (uint8_t)(page_prog_start >> 16);
tmp_data[1] = (uint8_t)(page_prog_start >> 8);
@@ -184,43 +180,46 @@ void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_comman
}
himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //==================================
- // AHB_I2C Burst Read
- // Set SPI data register : 0x8000_002C ==> 0x00
- //==================================
+ /*=====================================
+ AHB_I2C Burst Read
+ Set SPI data register : 0x8000_002C ==> 0x00
+ =====================================*/
out_buffer[0] = 0x2C;
out_buffer[1] = 0x00;
out_buffer[2] = 0x00;
out_buffer[3] = 0x80;
- i2c_himax_write(client, 0x00 ,out_buffer, 4, 3);
+ i2c_himax_write(client, 0x00, out_buffer, 4, 3);
- //==================================
- // Read access : 0x0C ==> 0x00
- //==================================
+ /*=====================================
+ Read access : 0x0C ==> 0x00
+ =====================================*/
out_buffer[0] = 0x00;
- i2c_himax_write(client, 0x0C ,out_buffer, 1, 3);
+ i2c_himax_write(client, 0x0C, out_buffer, 1, 3);
- //==================================
- // Read 128 bytes two times
- //==================================
- i2c_himax_read(client, 0x08 ,in_buffer, 128, 3);
- for (i = 0; i < 128; i++)
- flash_buffer[i + page_prog_start] = in_buffer[i];
+ /*=====================================
+ Read 128 bytes two times
+ =====================================*/
+ i2c_himax_read(client, 0x08, in_buffer, 128, 3);
+ for (i = 0 ; i < 128 ; i++)
+ flash_buffer[i + page_prog_start]
+ = in_buffer[i];
- i2c_himax_read(client, 0x08 ,in_buffer, 128, 3);
- for (i = 0; i < 128; i++)
- flash_buffer[(i + 128) + page_prog_start] = in_buffer[i];
+ i2c_himax_read(client, 0x08 , in_buffer, 128, 3);
+ for (i = 0 ; i < 128 ; i++)
+ flash_buffer[(i + 128) + page_prog_start]
+ = in_buffer[i];
I("%s:Verify Progress: %x\n", __func__, page_prog_start);
}
/*=============Dump Flash End=============*/
- //msleep(100);
- /*
+ /*//msleep(100);
for( i=0 ; i<8 ;i++)
{
for(j=0 ; j<64 ; j++)
@@ -239,7 +238,7 @@ int himax_chip_self_test(struct i2c_client *client)
{
uint8_t tmp_addr[4];
uint8_t tmp_data[128];
- int pf_value=0x00;
+ int pf_value = 0x00;
uint8_t test_result_id = 0;
int j;
@@ -249,19 +248,24 @@ int himax_chip_self_test(struct i2c_client *client)
himax_interface_on(client);
himax_sense_off(client);
- //Set criteria
+ /*Set criteria*/
himax_burst_enable(client, 1);
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x94;
- tmp_data[3] = 0x14; tmp_data[2] = 0xC8; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- tmp_data[7] = 0x13; tmp_data[6] = 0x60; tmp_data[5] = 0x0A; tmp_data[4] = 0x99;
-
- himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 8);
-
- //start selftest
- // 0x9008_805C ==> 0x0000_0001
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x5C;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x94;
+ tmp_data[3] = 0x14; tmp_data[2] = 0xC8;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_data[7] = 0x13; tmp_data[6] = 0x60;
+ tmp_data[5] = 0x0A; tmp_data[4] = 0x99;
+
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 8);
+
+ /*start selftest*/
+ /* 0x9008_805C ==> 0x0000_0001*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x5C;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
himax_flash_write_burst(client, tmp_addr, tmp_data);
himax_sense_on(client, 1);
@@ -271,19 +275,21 @@ int himax_chip_self_test(struct i2c_client *client)
himax_sense_off(client);
msleep(20);
- //=====================================
- // Read test result ID : 0x9008_8078 ==> 0xA/0xB/0xC/0xF
- //=====================================
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x78;
+ /*=====================================
+ Read test result ID : 0x9008_8078 ==> 0xA/0xB/0xC/0xF
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x78;
himax_register_read(client, tmp_addr, 1, tmp_data);
test_result_id = tmp_data[0];
- I("%s: check test result, test_result_id=%x, test_result=%x\n", __func__
- ,test_result_id,tmp_data[0]);
+ I("%s: check test result, test_result_id=%x, test_result=%x\n",
+ __func__ , test_result_id, tmp_data[0]);
- if (test_result_id==0xF) {
+ if (test_result_id == 0xF) {
I("[Himax]: self-test pass\n");
pf_value = 0x1;
} else {
@@ -292,22 +298,28 @@ int himax_chip_self_test(struct i2c_client *client)
}
himax_burst_enable(client, 1);
- for (j = 0;j < 10; j++){
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x06; tmp_addr[1] = 0x00; tmp_addr[0] = 0x0C;
+ for (j = 0 ; j < 10 ; j++) {
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x06;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x0C;
himax_register_read(client, tmp_addr, 1, tmp_data);
I("[Himax]: 9006000C = %d\n", tmp_data[0]);
- if (tmp_data[0] != 0){
- tmp_data[3] = 0x90; tmp_data[2] = 0x06; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- if ( i2c_himax_write(client, 0x00 ,tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- }
- tmp_data[0] = 0x00;
- if ( i2c_himax_write(client, 0x0C ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- }
- i2c_himax_read(client, 0x08, tmp_data, 124,HIMAX_I2C_RETRY_TIMES);
- }else{
+ if (tmp_data[0] != 0) {
+ tmp_data[3] = 0x90; tmp_data[2] = 0x06;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ if (i2c_himax_write(client, 0x00,
+ tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ }
+ tmp_data[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ }
+ i2c_himax_read(client, 0x08,
+ tmp_data, 124, HIMAX_I2C_RETRY_TIMES);
+ } else {
break;
}
}
@@ -324,15 +336,18 @@ void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable)
uint8_t tmp_data[4];
himax_burst_enable(client, 0);
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = HSEN_enable;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = HSEN_enable;
himax_flash_write_burst(client, tmp_addr, tmp_data);
}
-void himax_get_HSEN_enable(struct i2c_client *client,uint8_t *tmp_data)
+void himax_get_HSEN_enable(struct i2c_client *client, uint8_t *tmp_data)
{
uint8_t tmp_addr[4];
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x50;
himax_register_read(client, tmp_addr, 1, tmp_data);
}
@@ -341,206 +356,232 @@ void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable)
uint8_t tmp_addr[4];
uint8_t tmp_data[4];
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = SMWP_enable;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = SMWP_enable;
himax_flash_write_burst(client, tmp_addr, tmp_data);
}
-void himax_get_SMWP_enable(struct i2c_client *client,uint8_t *tmp_data)
+void himax_get_SMWP_enable(struct i2c_client *client,
+uint8_t *tmp_data)
{
uint8_t tmp_addr[4];
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x54;
himax_register_read(client, tmp_addr, 1, tmp_data);
}
int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte)
{
uint8_t tmp_data[4];
+ int err = -1;
tmp_data[0] = 0x31;
- if ( i2c_himax_write(client, 0x13 ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+
+ if (i2c_himax_write(client, 0x13,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
- return -EBUSY;
+ return err;
}
-
+
tmp_data[0] = (0x10 | auto_add_4_byte);
- if ( i2c_himax_write(client, 0x0D ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x0D,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
- return -EBUSY;
+ return err;
}
return 0;
}
-void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data)
+void himax_register_read(struct i2c_client *client,
+uint8_t *read_addr, int read_length, uint8_t *read_data)
{
uint8_t tmp_data[4];
int i = 0;
int address = 0;
- if(read_length>256)
- {
+ if (read_length > 256) {
E("%s: read len over 256!\n", __func__);
return;
}
if (read_length > 1)
himax_burst_enable(client, 1);
else
- himax_burst_enable(client, 0);
- address = (read_addr[3] << 24) + (read_addr[2] << 16) + (read_addr[1] << 8) + read_addr[0];
+ himax_burst_enable(client, 0);
+
+ address = (read_addr[3] << 24) +
+ (read_addr[2] << 16) +
+ (read_addr[1] << 8) +
+ read_addr[0];
+
i = address;
- tmp_data[0] = (uint8_t)i;
- tmp_data[1] = (uint8_t)(i >> 8);
- tmp_data[2] = (uint8_t)(i >> 16);
- tmp_data[3] = (uint8_t)(i >> 24);
- if ( i2c_himax_write(client, 0x00 ,tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- return;
- }
- tmp_data[0] = 0x00;
- if ( i2c_himax_write(client, 0x0C ,tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- return;
- }
-
- if ( i2c_himax_read(client, 0x08 ,read_data, read_length * 4, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- return;
- }
+ tmp_data[0] = (uint8_t)i;
+ tmp_data[1] = (uint8_t)(i >> 8);
+ tmp_data[2] = (uint8_t)(i >> 16);
+ tmp_data[3] = (uint8_t)(i >> 24);
+ if (i2c_himax_write(client, 0x00,
+ tmp_data, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ tmp_data[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ tmp_data, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
+ if (i2c_himax_read(client, 0x08,
+ read_data, read_length * 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
if (read_length > 1)
himax_burst_enable(client, 0);
}
-void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data)
+void himax_flash_read(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *read_data)
{
- uint8_t tmpbyte[2];
-
- if ( i2c_himax_write(client, 0x00 ,®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ uint8_t tmpbyte[2];
+
+ if (i2c_himax_write(client, 0x00,
+ ®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(client, 0x01 ,®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x01,
+ ®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(client, 0x02 ,®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x02,
+ ®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(client, 0x03 ,®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x03,
+ ®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- tmpbyte[0] = 0x00;
- if ( i2c_himax_write(client, 0x0C ,&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ tmpbyte[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_read(client, 0x08 ,&read_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x08,
+ &read_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_read(client, 0x09 ,&read_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x09,
+ &read_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_read(client, 0x0A ,&read_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x0A,
+ &read_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_read(client, 0x0B ,&read_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x0B,
+ &read_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_read(client, 0x18 ,&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x18,
+ &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
- }// No bus request
+ } /* No bus request*/
- if ( i2c_himax_read(client, 0x0F ,&tmpbyte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x0F,
+ &tmpbyte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
- }// idle state
+ } /* idle state*/
}
-void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data)
+void himax_flash_write_burst(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *write_data)
{
- uint8_t data_byte[8];
+ uint8_t data_byte[8];
int i = 0, j = 0;
- for (i = 0; i < 4; i++)
- {
- data_byte[i] = reg_byte[i];
- }
- for (j = 4; j < 8; j++)
- {
- data_byte[j] = write_data[j-4];
- }
-
- if ( i2c_himax_write(client, 0x00 ,data_byte, 8, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- return;
- }
+ for (i = 0 ; i < 4; i++)
+ data_byte[i] = reg_byte[i];
+
+ for (j = 4 ; j < 8; j++)
+ data_byte[j] = write_data[j-4];
+
+ if (i2c_himax_write(client, 0x00,
+ data_byte, 8, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }
}
-int himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length)
+int himax_flash_write_burst_length(struct i2c_client *client,
+uint8_t *reg_byte, uint8_t *write_data, int length)
{
- uint8_t data_byte[256];
- int i = 0, j = 0;
+ uint8_t data_byte[256];
+ int i = 0, j = 0, err = -1;
- for (i = 0; i < 4; i++)
- {
- data_byte[i] = reg_byte[i];
- }
- for (j = 4; j < length + 4; j++)
- {
- data_byte[j] = write_data[j - 4];
- }
-
- if ( i2c_himax_write(client, 0x00 ,data_byte, length + 4, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- return -EBUSY;
- }
+ for (i = 0 ; i < 4 ; i++)
+ data_byte[i] = reg_byte[i];
- return 0;
+ for (j = 4 ; j < length + 4 ; j++)
+ data_byte[j] = write_data[j - 4];
+
+ if (i2c_himax_write(client, 0x00,
+ data_byte, length + 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return err;
+ }
+ return 0;
}
-int himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data)
+int himax_register_write(struct i2c_client *client,
+uint8_t *write_addr, int write_length, uint8_t *write_data)
{
- int i =0, address = 0;
- int ret = 0;
+ int i = 0, address = 0;
+ int ret = 0, err = -1;
- address = (write_addr[3] << 24) + (write_addr[2] << 16) + (write_addr[1] << 8) + write_addr[0];
+ address = (write_addr[3] << 24) +
+ (write_addr[2] << 16) +
+ (write_addr[1] << 8) +
+ write_addr[0];
- for (i = address; i < address + write_length * 4; i = i + 4)
- {
- if (write_length > 1)
- {
+ for (i = address ; i < address + write_length * 4;
+ i = i + 4) {
+ if (write_length > 1) {
ret = himax_burst_enable(client, 1);
- if(ret)
- return ret;
- }
- else
- {
+ if (ret)
+ return err;
+ } else {
ret = himax_burst_enable(client, 0);
- if(ret)
- return ret;
+ if (ret)
+ return err;
}
- ret = himax_flash_write_burst_lenth(client, write_addr, write_data, write_length * 4);
- if(ret < 0)
- return ret;
+ ret = himax_flash_write_burst_length(client,
+ write_addr, write_data, write_length * 4);
+ if (ret < 0)
+ return err;
}
return 0;
@@ -550,50 +591,62 @@ void himax_sense_off(struct i2c_client *client)
{
uint8_t wdt_off = 0x00;
uint8_t tmp_addr[4];
- uint8_t tmp_data[5];
+ uint8_t tmp_data[5];
himax_burst_enable(client, 0);
- while(wdt_off == 0x00)
- {
- // 0x9000_800C ==> 0x0000_AC53
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xAC; tmp_data[0] = 0x53;
+ while (wdt_off == 0x00) {
+ /* 0x9000_800C ==> 0x0000_AC53*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0xAC; tmp_data[0] = 0x53;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Read Watch Dog disable password : 0x9000_800C ==> 0x0000_AC53
- //=====================================
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
+ /*=====================================*/
+ /* Read Watch Dog disable password :
+ 0x9000_800C ==> 0x0000_AC53 */
+ /*=====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x0C;
himax_register_read(client, tmp_addr, 1, tmp_data);
-
- //Check WDT
- if (tmp_data[0] == 0x53 && tmp_data[1] == 0xAC && tmp_data[2] == 0x00 && tmp_data[3] == 0x00)
+
+ /*Check WDT*/
+ if (tmp_data[0] == 0x53 && tmp_data[1] == 0xAC
+ && tmp_data[2] == 0x00 && tmp_data[3] == 0x00)
wdt_off = 0x01;
else
wdt_off = 0x00;
}
- // VCOM //0x9008_806C ==> 0x0000_0001
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x08; tmp_addr[1] = 0x80; tmp_addr[0] = 0x6C;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ /* VCOM //0x9008_806C ==> 0x0000_0001*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80; tmp_addr[0] = 0x6C;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
himax_flash_write_burst(client, tmp_addr, tmp_data);
msleep(20);
- // 0x9000_0010 ==> 0x0000_00DA
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xDA;
+ /* 0x9000_0010 ==> 0x0000_00DA*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xDA;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Read CPU clock off password : 0x9000_0010 ==> 0x0000_00DA
- //=====================================
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ /*=====================================
+ Read CPU clock off password : 0x9000_0010 ==> 0x0000_00DA
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
himax_register_read(client, tmp_addr, 1, tmp_data);
- I("%s: CPU clock off password data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
- ,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+ I("%s: CPU clock off password data[0]=%x",
+ __func__, tmp_data[0]);
+ I(" data[1]=%x data[2]=%x data[3]=%x\n",
+ tmp_data[1], tmp_data[2], tmp_data[3]);
}
@@ -602,11 +655,12 @@ void himax_interface_on(struct i2c_client *client)
uint8_t tmp_addr[4];
uint8_t tmp_data[5];
- //===========================================
- // Any Cmd for ineterface on : 0x9000_0000 ==> 0x0000_0000
- //===========================================
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
- himax_flash_read(client, tmp_addr, tmp_data); //avoid RD/WR fail
+ /*=====================================
+ Any Cmd for ineterface on : 0x9000_0000 ==> 0x0000_0000
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ himax_flash_read(client, tmp_addr, tmp_data); /*avoid RD/WR fail*/
}
bool wait_wip(struct i2c_client *client, int Timing)
@@ -614,55 +668,64 @@ bool wait_wip(struct i2c_client *client, int Timing)
uint8_t tmp_addr[4];
uint8_t tmp_data[4];
uint8_t in_buffer[10];
- //uint8_t out_buffer[20];
+ /*uint8_t out_buffer[20];*/
int retry_cnt = 0;
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_flash_write_burst(client, tmp_addr, tmp_data);
in_buffer[0] = 0x01;
- do
- {
- //=====================================
- // SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x42; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x03;
+ do {
+ /*=====================================
+ SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x42; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x03;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // SPI Command : 0x8000_0024 ==> 0x0000_0005
- // read 0x8000_002C for 0x01, means wait success
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x05;
+ /*=====================================
+ SPI Command : 0x8000_0024 ==> 0x0000_0005
+ read 0x8000_002C for 0x01, means wait success
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x05;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- in_buffer[0] = in_buffer[1] = in_buffer[2] = in_buffer[3] = 0xFF;
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+ in_buffer[0] = in_buffer[1] =
+ in_buffer[2] = in_buffer[3] = 0xFF;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
himax_register_read(client, tmp_addr, 1, in_buffer);
-
+
if ((in_buffer[0] & 0x01) == 0x00)
return true;
retry_cnt++;
-
- if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00 || in_buffer[2] != 0x00 || in_buffer[3] != 0x00)
- I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, buffer[1]=%d, buffer[2]=%d, buffer[3]=%d \n", __func__,
- retry_cnt,in_buffer[0],in_buffer[1],in_buffer[2],in_buffer[3]);
- if (retry_cnt > 100)
- {
+ if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00
+ || in_buffer[2] != 0x00 || in_buffer[3] != 0x00){
+ I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, ",
+ __func__, retry_cnt, in_buffer[0]);
+ I("buffer[1]=%d, buffer[2]=%d, buffer[3]=%d\n",
+ in_buffer[1], in_buffer[2], in_buffer[3]);
+ }
+ if (retry_cnt > 100) {
E("%s: Wait wip error!\n", __func__);
- return false;
- }
+ return false;
+ }
msleep(Timing);
- }while ((in_buffer[0] & 0x01) == 0x01);
+ } while ((in_buffer[0] & 0x01) == 0x01);
return true;
}
@@ -673,74 +736,93 @@ void himax_sense_on(struct i2c_client *client, uint8_t FlashMode)
himax_interface_on(client);
himax_burst_enable(client, 0);
- //CPU reset
- // 0x9000_0014 ==> 0x0000_00CA
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xCA;
+ /*CPU reset*/
+ /* 0x9000_0014 ==> 0x0000_00CA*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xCA;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Read pull low CPU reset signal : 0x9000_0014 ==> 0x0000_00CA
- //=====================================
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ /*=====================================
+ Read pull low CPU reset signal : 0x9000_0014 ==> 0x0000_00CA
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
himax_register_read(client, tmp_addr, 1, tmp_data);
- I("%s: check pull low CPU reset signal data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
- ,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
+ I("%s: check pull low CPU reset signal data[0]=%x data[1]=%x ",
+ __func__, tmp_data[0], tmp_data[1]);
+ I("data[2]=%x data[3]=%x\n",
+ tmp_data[2], tmp_data[3]);
- // 0x9000_0014 ==> 0x0000_0000
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ /* 0x9000_0014 ==> 0x0000_0000*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Read revert pull low CPU reset signal : 0x9000_0014 ==> 0x0000_0000
- //=====================================
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
+ /*=====================================
+ Read revert pull low CPU reset signal : 0x9000_0014 ==> 0x0000_0000
+ =====================================*/
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x14;
himax_register_read(client, tmp_addr, 1, tmp_data);
- I("%s: revert pull low CPU reset signal data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n", __func__
- ,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]);
-
- //=====================================
- // Reset TCON
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x02; tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_flash_write_burst(client, tmp_addr, tmp_data);
- usleep_range(10000, 20000);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x02; tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
- himax_flash_write_burst(client, tmp_addr, tmp_data);
-
- if (FlashMode == 0x00) //SRAM
- {
- //=====================================
- // Re-map
- //=====================================
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xF1;
- himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
+ I("%s: revert pull low CPU reset signal data[0]=%x data[1]=%x ",
+ __func__, tmp_data[0], tmp_data[1]);
+ I("data[2]=%x data[3]=%x\n",
+ tmp_data[2], tmp_data[3]);
+
+ /*=====================================
+ Reset TCON
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+ usleep_range(9999, 10000);
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x02;
+ tmp_addr[1] = 0x01; tmp_addr[0] = 0xE0;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ if (FlashMode == 0x00) { /*SRAM*/
+ /*=====================================
+ Re-map
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xF1;
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
I("%s:83100_Chip_Re-map ON\n", __func__);
- }
- else
- {
- //=====================================
- // Re-map off
- //=====================================
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
+ } else {
+ /*=====================================
+ Re-map off
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
I("%s:83100_Chip_Re-map OFF\n", __func__);
}
- //=====================================
- // CPU clock on
- //=====================================
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
+ /*=====================================
+ CPU clock on
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 4);
}
@@ -751,36 +833,45 @@ void himax_chip_erase(struct i2c_client *client)
himax_burst_enable(client, 0);
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Chip Erase
- // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
- // 2. 0x8000_0024 ==> 0x0000_0006
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ /*=====================================
+ Chip Erase
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Chip Erase
- // Erase Command : 0x8000_0024 ==> 0x0000_00C7
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0xC7;
+ /*=====================================
+ Chip Erase
+ Erase Command : 0x8000_0024 ==> 0x0000_00C7
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0xC7;
himax_flash_write_burst(client, tmp_addr, tmp_data);
-
+
msleep(2000);
-
+
if (!wait_wip(client, 100))
E("%s:83100_Chip_Erase Fail\n", __func__);
@@ -793,53 +884,64 @@ bool himax_block_erase(struct i2c_client *client)
himax_burst_enable(client, 0);
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Chip Erase
- // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
- // 2. 0x8000_0024 ==> 0x0000_0006
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ /*=====================================
+ Chip Erase
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=====================================
- // Block Erase
- // Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr
- // 0x8000_0020 ==> 0x6700_0000 //control
- // 0x8000_0024 ==> 0x0000_0052 //BE
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ /*=====================================
+ Block Erase
+ Erase Command :
+ 0x8000_0028 ==> 0x0000_0000 //SPI addr
+ 0x8000_0020 ==> 0x6700_0000 //control
+ 0x8000_0024 ==> 0x0000_0052 //BE
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_flash_write_burst(client, tmp_addr, tmp_data);
-
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x67; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x67; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_flash_write_burst(client, tmp_addr, tmp_data);
-
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x52;
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x52;
himax_flash_write_burst(client, tmp_addr, tmp_data);
msleep(1000);
- if (!wait_wip(client, 100))
- {
+ if (!wait_wip(client, 100)) {
E("%s:83100_Erase Fail\n", __func__);
return false;
- }
- else
- {
+ } else {
return true;
}
@@ -853,97 +955,110 @@ bool himax_sector_erase(struct i2c_client *client, int start_addr)
himax_burst_enable(client, 0);
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- for (page_prog_start = start_addr; page_prog_start < start_addr + 0x0F000; page_prog_start = page_prog_start + 0x1000)
- {
- //=====================================
- // Chip Erase
- // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
- // 2. 0x8000_0024 ==> 0x0000_0006
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_flash_write_burst(client, tmp_addr, tmp_data);
-
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
- himax_flash_write_burst(client, tmp_addr, tmp_data);
-
- //=====================================
- // Sector Erase
- // Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr
- // 0x8000_0020 ==> 0x6700_0000 //control
- // 0x8000_0024 ==> 0x0000_0020 //SE
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
- if (page_prog_start < 0x100)
- {
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
- {
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = (uint8_t)(page_prog_start >> 8); tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
- {
- tmp_data[3] = 0x00; tmp_data[2] = (uint8_t)(page_prog_start >> 16); tmp_data[1] = (uint8_t)(page_prog_start >> 8); tmp_data[0] = (uint8_t)page_prog_start;
- }
- himax_flash_write_burst(client, tmp_addr, tmp_data);
+ for (page_prog_start = start_addr;
+ page_prog_start < start_addr + 0x0F000;
+ page_prog_start = page_prog_start + 0x1000) {
+ /*=====================================
+ Chip Erase
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x67; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_flash_write_burst(client, tmp_addr, tmp_data);
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x20;
- himax_flash_write_burst(client, tmp_addr, tmp_data);
+ /*=====================================
+ Sector Erase
+ Erase Command :
+ 0x8000_0028 ==> 0x0000_0000 //SPI addr
+ 0x8000_0020 ==> 0x6700_0000 //control
+ 0x8000_0024 ==> 0x0000_0020 //SE
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ if (page_prog_start < 0x100) {
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ tmp_data[0] = (uint8_t)page_prog_start;
+ }
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
+
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x67; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
- msleep(200);
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x20;
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
- if (!wait_wip(client, 100))
- {
- E("%s:83100_Erase Fail\n", __func__);
- return false;
- }
- }
- return true;
+ msleep(200);
+
+ if (!wait_wip(client, 100)) {
+ E("%s:83100_Erase Fail\n", __func__);
+ return false;
+ }
+ }
+ return true;
}
void himax_sram_write(struct i2c_client *client, uint8_t *FW_content)
{
int i = 0;
uint8_t tmp_addr[4];
- uint8_t tmp_data[128];
- int FW_length = 0x4000; // 0x4000 = 16K bin file
-
- //himax_sense_off(client);
+ uint8_t tmp_data[64];
+ int FW_length = 0x4000; /* 0x4000 = 16K bin file */
+
+ /*himax_sense_off(client);*/
- for (i = 0; i < FW_length; i = i + 128)
- {
+ for (i = 0; i < FW_length; i = i + 64) {
himax_burst_enable(client, 1);
- if (i < 0x100)
- {
- tmp_addr[3] = 0x08;
- tmp_addr[2] = 0x00;
- tmp_addr[1] = 0x00;
+ if (i < 0x100) {
+ tmp_addr[3] = 0x08;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00;
tmp_addr[0] = i;
- }
- else if (i >= 0x100 && i < 0x10000)
- {
- tmp_addr[3] = 0x08;
- tmp_addr[2] = 0x00;
- tmp_addr[1] = (i >> 8);
+ } else if (i >= 0x100 && i < 0x10000) {
+ tmp_addr[3] = 0x08;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = (i >> 8);
tmp_addr[0] = i;
}
- memcpy(&tmp_data[0], &FW_content[i], 128);
- himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 128);
+ memcpy(&tmp_data[0], &FW_content[i], 64);
+ himax_flash_write_burst_length(client, tmp_addr, tmp_data, 64);
}
@@ -951,182 +1066,197 @@ void himax_sram_write(struct i2c_client *client, uint8_t *FW_content)
E("%s:83100_Sram_Write Fail\n", __func__);
}
-bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size)
+bool himax_sram_verify(struct i2c_client *client,
+uint8_t *FW_File, int FW_Size)
{
int i = 0;
uint8_t out_buffer[20];
uint8_t in_buffer[128];
uint8_t *get_fw_content;
- get_fw_content = kzalloc(0x4000*sizeof(uint8_t), GFP_KERNEL);
- if (!get_fw_content)
- return false;
+ get_fw_content = kzalloc(0x4000 * sizeof(uint8_t), GFP_KERNEL);
- for (i = 0; i < 0x4000; i = i + 128)
- {
+ for (i = 0 ; i < 0x4000 ; i = i + 128) {
himax_burst_enable(client, 1);
- //==================================
- // AHB_I2C Burst Read
- //==================================
- if (i < 0x100)
- {
- out_buffer[3] = 0x08;
- out_buffer[2] = 0x00;
- out_buffer[1] = 0x00;
+ /*=====================================
+ AHB_I2C Burst Read
+ =====================================*/
+ if (i < 0x100) {
+ out_buffer[3] = 0x08;
+ out_buffer[2] = 0x00;
+ out_buffer[1] = 0x00;
out_buffer[0] = i;
- }
- else if (i >= 0x100 && i < 0x10000)
- {
- out_buffer[3] = 0x08;
- out_buffer[2] = 0x00;
- out_buffer[1] = (i >> 8);
+ } else if (i >= 0x100 && i < 0x10000) {
+ out_buffer[3] = 0x08;
+ out_buffer[2] = 0x00;
+ out_buffer[1] = (i >> 8);
out_buffer[0] = i;
}
- if ( i2c_himax_write(client, 0x00 ,out_buffer, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x00, out_buffer,
+ 4, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return false;
}
- out_buffer[0] = 0x00;
- if ( i2c_himax_write(client, 0x0C ,out_buffer, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ out_buffer[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C, out_buffer,
+ 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return false;
}
- if ( i2c_himax_read(client, 0x08 ,in_buffer, 128, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_read(client, 0x08, in_buffer,
+ 128, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return false;
}
memcpy(&get_fw_content[i], &in_buffer[0], 128);
}
- for (i = 0; i < FW_Size; i++)
- {
- if (FW_File[i] != get_fw_content[i])
- {
- E("%s: fail! SRAM[%x]=%x NOT CRC_ifile=%x\n", __func__,i,get_fw_content[i],FW_File[i]);
- return false;
- }
+ for (i = 0 ; i < FW_Size ; i++) {
+ if (FW_File[i] != get_fw_content[i]) {
+ E("%s: fail! SRAM[%x]=%x NOT CRC_ifile=%x\n",
+ __func__, i, get_fw_content[i], FW_File[i]);
+ return false;
}
+ }
kfree(get_fw_content);
return true;
}
-void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size)
+void himax_flash_programming(struct i2c_client *client,
+uint8_t *FW_content, int FW_Size)
{
int page_prog_start = 0;
int program_length = 48;
int i = 0, j = 0, k = 0;
uint8_t tmp_addr[4];
uint8_t tmp_data[4];
- uint8_t buring_data[256]; // Read for flash data, 128K
- // 4 bytes for 0x80002C padding
+ /* // Read for flash data, 128K //4 bytes for 0x80002C padding */
+ uint8_t buring_data[256];
- //himax_interface_on(client);
+ /*himax_interface_on(client);*/
himax_burst_enable(client, 0);
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256)
- {
- //msleep(5);
- //=====================================
- // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000
- // 2. 0x8000_0024 ==> 0x0000_0006
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x47; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ for (page_prog_start = 0 ; page_prog_start < FW_Size;
+ page_prog_start = page_prog_start + 256) {
+ /*msleep(5);*/
+ /*=====================================
+ Write Enable :
+ 1. 0x8000_0020 ==> 0x4700_0000
+ 2. 0x8000_0024 ==> 0x0000_0006
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x47; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x06;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x06;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=================================
- // SPI Transfer Control
- // Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000
- // Set read start address : 0x8000_0028 ==> 0x0000_0000
- //=================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x61; tmp_data[2] = 0x0F; tmp_data[1] = 0xF0; tmp_data[0] = 0x00;
- // data bytes should be 0x6100_0000 + ((word_number)*4-1)*4096 = 0x6100_0000 + 0xFF000 = 0x610F_F000
- // Programmable size = 1 page = 256 bytes, word_number = 256 byte / 4 = 64
+ /*=====================================
+ SPI Transfer Control
+ Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000
+ Set read start address : 0x8000_0028 ==> 0x0000_0000
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x61; tmp_data[2] = 0x0F;
+ tmp_data[1] = 0xF0; tmp_data[0] = 0x00;
+ /*data bytes should be 0x6100_0000 +
+ ((word_number)*4-1)*4096 = 0x6100_0000 +
+ 0xFF000 = 0x610F_F000
+ Programmable size = 1 page = 256 bytes,
+ word_number = 256 byte / 4 = 64*/
himax_flash_write_burst(client, tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
- //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; // Flash start address 1st : 0x0000_0000
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ /* tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ // Flash start address 1st : 0x0000_0000 */
- if (page_prog_start < 0x100)
- {
- tmp_data[3] = 0x00;
- tmp_data[2] = 0x00;
- tmp_data[1] = 0x00;
+ if (page_prog_start < 0x100) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00;
tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
- {
- tmp_data[3] = 0x00;
- tmp_data[2] = 0x00;
- tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = 0x00;
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
- {
- tmp_data[3] = 0x00;
- tmp_data[2] = (uint8_t)(page_prog_start >> 16);
- tmp_data[1] = (uint8_t)(page_prog_start >> 8);
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
+ tmp_data[3] = 0x00;
+ tmp_data[2] = (uint8_t)(page_prog_start >> 16);
+ tmp_data[1] = (uint8_t)(page_prog_start >> 8);
tmp_data[0] = (uint8_t)page_prog_start;
}
-
- himax_flash_write_burst(client, tmp_addr, tmp_data);
+ himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=================================
- // Send 16 bytes data : 0x8000_002C ==> 16 bytes data
- //=================================
+ /*=====================================
+ Send 16 bytes data : 0x8000_002C ==> 16 bytes data
+ =====================================*/
buring_data[0] = 0x2C;
buring_data[1] = 0x00;
buring_data[2] = 0x00;
buring_data[3] = 0x80;
-
- for (i = /*0*/page_prog_start, j = 0; i < 16 + page_prog_start/**/; i++, j++) /// <------ bin file
- {
+
+ for (i = /*0*/page_prog_start, j = 0;
+ i < 16 + page_prog_start/**/;
+ i++, j++) { /* <------ bin file*/
+
buring_data[j + 4] = FW_content[i];
}
-
- if ( i2c_himax_write(client, 0x00 ,buring_data, 20, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x00, buring_data,
+ 20, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- //=================================
- // Write command : 0x8000_0024 ==> 0x0000_0002
- //=================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x02;
+ /*=====================================
+ Write command : 0x8000_0024 ==> 0x0000_0002
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x02;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- //=================================
- // Send 240 bytes data : 0x8000_002C ==> 240 bytes data
- //=================================
+ /*=====================================
+ Send 240 bytes data : 0x8000_002C ==> 240 bytes data
+ =====================================*/
- for (j = 0; j < 5; j++)
- {
- for (i = (page_prog_start + 16 + (j * 48)), k = 0; i < (page_prog_start + 16 + (j * 48)) + program_length; i++, k++) /// <------ bin file
- {
- buring_data[k+4] = FW_content[i];//(byte)i;
+ for (j = 0; j < 5; j++) {
+ for (i = (page_prog_start + 16 + (j * 48)), k = 0;
+ i < (page_prog_start + 16 + (j * 48)) + program_length;
+ i++, k++) { /*<------ bin file*/
+ buring_data[k+4] = FW_content[i];/*(byte)i;*/
}
- if ( i2c_himax_write(client, 0x00 ,buring_data, program_length+4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x00, buring_data,
+ program_length + 4,
+ HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
@@ -1145,52 +1275,61 @@ bool himax_check_chip_version(struct i2c_client *client)
uint8_t ret_data = 0x00;
int i = 0;
int ret = 0;
+
himax_sense_off(client);
- for (i = 0; i < 5; i++)
- {
- // 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001) (Lock register R/W from driver)
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x01;
+
+ for (i = 0 ; i < 5 ; i++) {
+ /* 1. Set DDREG_Req = 1 (0x9000_0020 = 0x0000_0001)
+ (Lock register R/W from driver) */
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x01;
ret = himax_register_write(client, tmp_addr, 1, tmp_data);
- if(ret)
+ if (ret)
return false;
- // 2. Set bank as 0 (0x8001_BD01 = 0x0000_0000)
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x01; tmp_addr[1] = 0xBD; tmp_addr[0] = 0x01;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ /* 2. Set bank as 0 (0x8001_BD01 = 0x0000_0000)*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+ tmp_addr[1] = 0xBD; tmp_addr[0] = 0x01;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
ret = himax_register_write(client, tmp_addr, 1, tmp_data);
- if(ret)
+ if (ret)
return false;
- // 3. Read driver ID register RF4H 1 byte (0x8001_F401)
- // Driver register RF4H 1 byte value = 0x84H, read back value will become 0x84848484
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x01; tmp_addr[1] = 0xF4; tmp_addr[0] = 0x01;
+ /* 3. Read driver ID register RF4H 1 byte (0x8001_F401)
+ // Driver register RF4H 1 byte value = 0x84H,
+ read back value will become 0x84848484 */
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x01;
+ tmp_addr[1] = 0xF4; tmp_addr[0] = 0x01;
himax_register_read(client, tmp_addr, 1, tmp_data);
ret_data = tmp_data[0];
I("%s:Read driver IC ID = %X\n", __func__, ret_data);
- if (ret_data == 0x84)
- {
+ if (ret_data == 0x84) {
IC_TYPE = HX_83100_SERIES_PWON;
- //himax_sense_on(client, 0x01);
+ /*himax_sense_on(client, 0x01);*/
ret_data = true;
break;
- }
- else
- {
+
+ } else {
ret_data = false;
E("%s:Read driver ID register Fail:\n", __func__);
}
}
- // 4. After read finish, set DDREG_Req = 0 (0x9000_0020 = 0x0000_0000) (Unlock register R/W from driver)
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ /* 4. After read finish, set DDREG_Req = 0
+ (0x9000_0020 = 0x0000_0000) (Unlock register R/W from driver)*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
himax_register_write(client, tmp_addr, 1, tmp_data);
- //himax_sense_on(client, 0x01);
+ /*himax_sense_on(client, 0x01);*/
return ret_data;
}
-#if 1
+/*#if 1*/
int himax_check_CRC(struct i2c_client *client, int mode)
{
bool burnFW_success = false;
@@ -1200,52 +1339,70 @@ int himax_check_CRC(struct i2c_client *client, int mode)
int CRC_value = 0;
memset(tmp_data, 0x00, sizeof(tmp_data));
+ if (i_TP_CRC_FW_60K == NULL) {
+ I("%s: i_TP_CRC_FW_60K = NULL\n", __func__);
+ return 0;
+ } else if (i_TP_CRC_FW_64K == NULL) {
+ I("%s: i_TP_CRC_FW_64K = NULL\n", __func__);
+ return 0;
+ } else if (i_TP_CRC_FW_124K == NULL) {
+ I("%s: i_TP_CRC_FW_124K = NULL\n", __func__);
+ return 0;
+ } else if (i_TP_CRC_FW_128K == NULL) {
+ I("%s: i_TP_CRC_FW_128K = NULL\n", __func__);
+ return 0;
+ }
- if (1)
- {
- if(mode == fw_image_60k)
- {
- himax_sram_write(client, (i_TP_CRC_FW_60K));
- burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_60K, 0x4000);
- }
- else if(mode == fw_image_64k)
- {
- himax_sram_write(client, (i_TP_CRC_FW_64K));
- burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_64K, 0x4000);
- }
- else if(mode == fw_image_124k)
- {
- himax_sram_write(client, (i_TP_CRC_FW_124K));
- burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_124K, 0x4000);
+ if (1) {
+ if (mode == fw_image_60k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_60K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_60K->data, 0x4000);
+ } else if (mode == fw_image_64k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_64K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_64K->data, 0x4000);
+ } else if (mode == fw_image_124k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_124K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_124K->data, 0x4000);
+ } else if (mode == fw_image_128k) {
+ himax_sram_write(client,
+ (unsigned char *)i_TP_CRC_FW_128K->data);
+ burnFW_success = himax_sram_verify(client,
+ (unsigned char *)i_TP_CRC_FW_128K->data, 0x4000);
}
- else if(mode == fw_image_128k)
- {
- himax_sram_write(client, (i_TP_CRC_FW_128K));
- burnFW_success = himax_sram_verify(client, i_TP_CRC_FW_128K, 0x4000);
- }
- if (burnFW_success)
- {
- I("%s: Start to do CRC FW mode=%d \n", __func__,mode);
- himax_sense_on(client, 0x00); // run CRC firmware
+ if (burnFW_success) {
+ I("%s: Start to do CRC FW mode=%d\n", __func__, mode);
+ himax_sense_on(client, 0x00); /* run CRC firmware*/
- while(true)
- {
+ while (true) {
msleep(100);
-
- tmp_addr[3] = 0x90;
- tmp_addr[2] = 0x08;
- tmp_addr[1] = 0x80;
+ tmp_addr[3] = 0x90;
+ tmp_addr[2] = 0x08;
+ tmp_addr[1] = 0x80;
tmp_addr[0] = 0x94;
- himax_register_read(client, tmp_addr, 1, tmp_data);
-
- I("%s: CRC from firmware is %x, %x, %x, %x \n", __func__,tmp_data[3],
- tmp_data[2],tmp_data[1],tmp_data[0]);
-
- if (tmp_data[3] == 0xFF && tmp_data[2] == 0xFF && tmp_data[1] == 0xFF && tmp_data[0] == 0xFF)
- {
- }
- else
+ himax_register_read(client,
+ tmp_addr, 1, tmp_data);
+
+ I("%s: CRC from firmware is %x, %x, %x, %x\n",
+ __func__, tmp_data[3], tmp_data[2],
+ tmp_data[1], tmp_data[0]);
+/*
+ if (tmp_data[3] == 0xFF && tmp_data[2] == 0xFF
+ && tmp_data[1] == 0xFF && tmp_data[0] == 0xFF) {
+ } else
break;
+ */
+ if (!(tmp_data[3] == 0xFF
+ && tmp_data[2] == 0xFF
+ && tmp_data[1] == 0xFF
+ && tmp_data[0] == 0xFF)) {
+ break;
+ }
}
CRC_value = tmp_data[3];
@@ -1259,30 +1416,32 @@ int himax_check_CRC(struct i2c_client *client, int mode)
tmp_value = tmp_data[0] << 24;
CRC_value += tmp_value;
- I("%s: CRC Value is %x \n", __func__, CRC_value);
+ I("%s: CRC Value is %x\n", __func__, CRC_value);
- //Close Remapping
- //=====================================
- // Re-map close
- //=====================================
- tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00;
- himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 4);
- return CRC_value;
- }
- else
- {
+ /*Close Remapping*/
+ /*=====================================
+ Re-map close
+ =====================================*/
+ tmp_addr[3] = 0x90; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x00;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x00;
+ himax_flash_write_burst_length(client,
+ tmp_addr, tmp_data, 4);
+ return CRC_value;
+
+ } else {
E("%s: SRAM write fail\n", __func__);
return 0;
- }
- }
- else
- I("%s: NO CRC Check File \n", __func__);
+ }
+ } else
+ I("%s: NO CRC Check File\n", __func__);
return 0;
}
-bool Calculate_CRC_with_AP(unsigned char *FW_content , int CRC_from_FW, int mode)
+bool Calculate_CRC_with_AP(unsigned char *FW_content,
+int CRC_from_FW, int mode)
{
uint8_t tmp_data[4];
int i, j;
@@ -1291,42 +1450,35 @@ bool Calculate_CRC_with_AP(unsigned char *FW_content , int CRC_from_FW, int mode
int CRC = 0xFFFFFFFF;
int PolyNomial = 0x82F63B78;
int length = 0;
-
+
if (mode == fw_image_128k)
length = 0x8000;
else if (mode == fw_image_124k)
length = 0x7C00;
else if (mode == fw_image_64k)
length = 0x4000;
- else //if (mode == fw_image_60k)
+ else /*if (mode == fw_image_60k)*/
length = 0x3C00;
- for (i = 0; i < length; i++)
- {
- fw_data = FW_content[i * 4 ];
-
- for (j = 1; j < 4; j++)
- {
+ for (i = 0 ; i < length ; i++) {
+ fw_data = FW_content[i * 4];
+
+ for (j = 1 ; j < 4 ; j++) {
fw_data_2 = FW_content[i * 4 + j];
fw_data += (fw_data_2) << (8 * j);
}
CRC = fw_data ^ CRC;
- for (j = 0; j < 32; j++)
- {
+ for (j = 0 ; j < 32 ; j++) {
if ((CRC % 2) != 0)
- {
- CRC = ((CRC >> 1) & 0x7FFFFFFF) ^ PolyNomial;
- }
+ CRC = ((CRC >> 1) & 0x7FFFFFFF) ^ PolyNomial;
else
- {
- CRC = (((CRC >> 1) ^ 0x7FFFFFFF)& 0x7FFFFFFF);
- }
+ CRC = (((CRC >> 1) ^ 0x7FFFFFFF) & 0x7FFFFFFF);
}
}
- I("%s: CRC calculate from bin file is %x \n", __func__, CRC);
+ I("%s: CRC calculate from bin file is %x\n", __func__, CRC);
tmp_data[0] = (uint8_t)(CRC >> 24);
tmp_data[1] = (uint8_t)(CRC >> 16);
@@ -1334,58 +1486,129 @@ bool Calculate_CRC_with_AP(unsigned char *FW_content , int CRC_from_FW, int mode
tmp_data[3] = (uint8_t) CRC;
CRC = tmp_data[0];
- CRC += tmp_data[1] << 8;
+ CRC += tmp_data[1] << 8;
CRC += tmp_data[2] << 16;
CRC += tmp_data[3] << 24;
- I("%s: CRC calculate from bin file REVERSE %x \n", __func__, CRC);
- I("%s: CRC calculate from FWis %x \n", __func__, CRC_from_FW);
+ I("%s: CRC calculate from bin file REVERSE %x\n", __func__, CRC);
+ I("%s: CRC calculate from FWis %x\n", __func__, CRC_from_FW);
if (CRC_from_FW == CRC)
return true;
else
return false;
}
-#endif
+/*#endif*/
-int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int himax_load_CRC_bin_file(struct i2c_client *client)
+{
+ int err = 0;
+ char *CRC_60_firmware_name = "HX_CRC_60.bin";
+ char *CRC_64_firmware_name = "HX_CRC_64.bin";
+ char *CRC_124_firmware_name = "HX_CRC_124.bin";
+ char *CRC_128_firmware_name = "HX_CRC_128.bin";
+
+ I("%s,Entering\n", __func__);
+ if (i_TP_CRC_FW_60K == NULL) {
+ I("load file name = %s\n", CRC_60_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_60K,
+ CRC_60_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -1;
+ goto request_60k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_60K\n", __func__);
+
+ if (i_TP_CRC_FW_64K == NULL) {
+ I("load file name = %s\n", CRC_64_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_64K,
+ CRC_64_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -2;
+ goto request_64k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_64K\n", __func__);
+
+ if (i_TP_CRC_FW_124K == NULL) {
+ I("load file name = %s\n", CRC_124_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_124K,
+ CRC_124_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -3;
+ goto request_124k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_124K\n", __func__);
+
+ if (i_TP_CRC_FW_128K == NULL) {
+ I("load file name = %s\n", CRC_128_firmware_name);
+ err = request_firmware(&i_TP_CRC_FW_128K,
+ CRC_128_firmware_name, private_ts->dev);
+ if (err < 0) {
+ E("%s,fail in line%d error code=%d\n",
+ __func__, __LINE__, err);
+ err = -4;
+ goto request_128k_fw_fail;
+ }
+ } else
+ I("%s already load i_TP_CRC_FW_128K\n", __func__);
+
+ return err;
+
+request_128k_fw_fail:
+ release_firmware(i_TP_CRC_FW_124K);
+request_124k_fw_fail:
+ release_firmware(i_TP_CRC_FW_64K);
+request_64k_fw_fail:
+ release_firmware(i_TP_CRC_FW_60K);
+request_60k_fw_fail:
+ return err;
+}
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
{
int CRC_from_FW = 0;
int burnFW_success = 0;
- if (len != 0x10000) //64k
- {
- E("%s: The file size is not 64K bytes\n", __func__);
- return false;
- }
+ if (len != 0x10000) {/*64k*/
+ E("%s: The file size is not 64K bytes\n", __func__);
+ return false;
+ }
himax_sense_off(client);
msleep(500);
himax_interface_on(client);
- if (!himax_sector_erase(client, 0x00000))
- {
- E("%s:Sector erase fail!Please restart the IC.\n", __func__);
- return false;
- }
+ if (!himax_sector_erase(client, 0x00000)) {
+ E("%s:Sector erase fail!Please restart the IC.\n", __func__);
+ return false;
+ }
himax_flash_programming(client, fw, 0x0F000);
- //burnFW_success = himax_83100_Verify(fw, len);
- //if(burnFW_success==false)
- // return burnFW_success;
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
- CRC_from_FW = himax_check_CRC(client,fw_image_60k);
- burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_60k);
- //himax_sense_on(client, 0x01);
+ CRC_from_FW = himax_check_CRC(client, fw_image_60k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_60k);
+ /*himax_sense_on(client, 0x01);*/
return burnFW_success;
}
-int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
{
int CRC_from_FW = 0;
int burnFW_success = 0;
- if (len != 0x10000) //64k
- {
- E("%s: The file size is not 64K bytes\n", __func__);
- return false;
+ if (len != 0x10000) { /*64k*/
+ E("%s: The file size is not 64K bytes\n", __func__);
+ return false;
}
himax_sense_off(client);
msleep(500);
@@ -1393,62 +1616,58 @@ int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char
himax_chip_erase(client);
himax_flash_programming(client, fw, len);
- //burnFW_success = himax_83100_Verify(fw, len);
- //if(burnFW_success==false)
- // return burnFW_success;
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
- CRC_from_FW = himax_check_CRC(client,fw_image_64k);
- burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_64k);
- //himax_sense_on(client, 0x01);
+ CRC_from_FW = himax_check_CRC(client, fw_image_64k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_64k);
+ /*himax_sense_on(client, 0x01);*/
return burnFW_success;
}
-int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
{
int CRC_from_FW = 0;
int burnFW_success = 0;
- if (len != 0x20000) //128k
- {
- E("%s: The file size is not 128K bytes\n", __func__);
- return false;
+ if (len != 0x20000) { /*128k*/
+ E("%s: The file size is not 128K bytes\n", __func__);
+ return false;
}
himax_sense_off(client);
msleep(500);
himax_interface_on(client);
- if (!himax_block_erase(client))
- {
- E("%s:Block erase fail!Please restart the IC.\n", __func__);
- return false;
- }
-
- if (!himax_sector_erase(client, 0x10000))
- {
- E("%s:Sector erase fail!Please restart the IC.\n", __func__);
- return false;
- }
+ if (!himax_block_erase(client)) {
+ E("%s:Block erase fail!Please restart the IC.\n", __func__);
+ return false;
+ }
+ if (!himax_sector_erase(client, 0x10000)) {
+ E("%s:Sector erase fail!Please restart the IC.\n", __func__);
+ return false;
+ }
himax_flash_programming(client, fw, 0x1F000);
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
- //burnFW_success = himax_83100_Verify(fw, len);
- //if(burnFW_success==false)
- // return burnFW_success;
-
- CRC_from_FW = himax_check_CRC(client,fw_image_124k);
- burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_124k);
- //himax_sense_on(client, 0x01);
+ CRC_from_FW = himax_check_CRC(client, fw_image_124k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_124k);
+ /*himax_sense_on(client, 0x01);*/
return burnFW_success;
}
-int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref)
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client,
+unsigned char *fw, int len, bool change_iref)
{
int CRC_from_FW = 0;
int burnFW_success = 0;
- if (len != 0x20000) //128k
- {
- E("%s: The file size is not 128K bytes\n", __func__);
- return false;
+ if (len != 0x20000) { /*128k*/
+ E("%s: The file size is not 128K bytes\n", __func__);
+ return false;
}
himax_sense_off(client);
msleep(500);
@@ -1457,13 +1676,13 @@ int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned cha
himax_flash_programming(client, fw, len);
- //burnFW_success = himax_83100_Verify(fw, len);
- //if(burnFW_success==false)
- // return burnFW_success;
+ /*burnFW_success = himax_83100_Verify(fw, len);
+ if(burnFW_success==false)
+ return burnFW_success;*/
- CRC_from_FW = himax_check_CRC(client,fw_image_128k);
- burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW,fw_image_128k);
- //himax_sense_on(client, 0x01);
+ CRC_from_FW = himax_check_CRC(client, fw_image_128k);
+ burnFW_success = Calculate_CRC_with_AP(fw, CRC_from_FW, fw_image_128k);
+ /*himax_sense_on(client, 0x01); */
return burnFW_success;
}
@@ -1472,10 +1691,9 @@ void himax_touch_information(struct i2c_client *client)
uint8_t cmd[4];
char data[12] = {0};
- I("%s:IC_TYPE =%d\n", __func__,IC_TYPE);
+ I("%s:IC_TYPE =%d\n", __func__, IC_TYPE);
- if(IC_TYPE == HX_83100_SERIES_PWON)
- {
+ if (IC_TYPE == HX_83100_SERIES_PWON) {
cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xF8;
himax_register_read(client, cmd, 1, data);
@@ -1486,11 +1704,11 @@ void himax_touch_information(struct i2c_client *client)
cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xFC;
himax_register_read(client, cmd, 1, data);
- if((data[1] & 0x04) == 0x04) {
+ if ((data[1] & 0x04) == 0x04)
ic_data->HX_XY_REVERSE = true;
- } else {
+ else
ic_data->HX_XY_REVERSE = false;
- }
+
ic_data->HX_Y_RES = data[3]*256;
cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x01; cmd[0] = 0x00;
himax_register_read(client, cmd, 1, data);
@@ -1498,32 +1716,35 @@ void himax_touch_information(struct i2c_client *client)
ic_data->HX_X_RES = data[1]*256 + data[2];
cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0x8C;
himax_register_read(client, cmd, 1, data);
- if((data[0] & 0x01) == 1) {
+ if ((data[0] & 0x01) == 1)
ic_data->HX_INT_IS_EDGE = true;
- } else {
+ else
ic_data->HX_INT_IS_EDGE = false;
- }
- if (ic_data->HX_RX_NUM > 40)
+
+ if (ic_data->HX_RX_NUM > 40)
ic_data->HX_RX_NUM = 29;
- if (ic_data->HX_TX_NUM > 20)
+ if (ic_data->HX_TX_NUM > 20)
ic_data->HX_TX_NUM = 16;
- if (ic_data->HX_MAX_PT > 10)
+ if (ic_data->HX_MAX_PT > 10)
ic_data->HX_MAX_PT = 10;
- if (ic_data->HX_Y_RES > 2000)
+ if (ic_data->HX_Y_RES > 2000)
ic_data->HX_Y_RES = 1280;
- if (ic_data->HX_X_RES > 2000)
+ if (ic_data->HX_X_RES > 2000)
ic_data->HX_X_RES = 720;
#ifdef HX_EN_MUT_BUTTON
cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xE8;
himax_register_read(client, cmd, 1, data);
ic_data->HX_BT_NUM = data[3];
#endif
- I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d \n", __func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT);
- I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d \n", __func__,ic_data->HX_XY_REVERSE,ic_data->HX_Y_RES,ic_data->HX_X_RES);
- I("%s:HX_INT_IS_EDGE =%d \n", __func__,ic_data->HX_INT_IS_EDGE);
- }
- else
- {
+ I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d\n",
+ __func__, ic_data->HX_RX_NUM,
+ ic_data->HX_TX_NUM, ic_data->HX_MAX_PT);
+ I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d\n",
+ __func__, ic_data->HX_XY_REVERSE,
+ ic_data->HX_Y_RES, ic_data->HX_X_RES);
+ I("%s:HX_INT_IS_EDGE =%d\n",
+ __func__, ic_data->HX_INT_IS_EDGE);
+ } else {
ic_data->HX_RX_NUM = 0;
ic_data->HX_TX_NUM = 0;
ic_data->HX_BT_NUM = 0;
@@ -1538,35 +1759,34 @@ void himax_touch_information(struct i2c_client *client)
void himax_read_FW_ver(struct i2c_client *client)
{
uint8_t cmd[4];
- uint8_t data[64] = {0};
+ uint8_t data[64];
- //=====================================
- // Read FW version : 0x0000_E303
- //=====================================
+ /*=====================================
+ Read FW version : 0x0000_E303
+ =====================================*/
cmd[3] = 0x00; cmd[2] = 0x00; cmd[1] = 0xE3; cmd[0] = 0x00;
himax_register_read(client, cmd, 1, data);
- ic_data->vendor_config_ver = data[3]<<8;
+ ic_data->vendor_config_ver = data[3] << 8;
cmd[3] = 0x00; cmd[2] = 0x00; cmd[1] = 0xE3; cmd[0] = 0x04;
himax_register_read(client, cmd, 1, data);
ic_data->vendor_config_ver = data[0] | ic_data->vendor_config_ver;
- I("CFG_VER : %X \n",ic_data->vendor_config_ver);
+ I("CFG_VER : %X\n", ic_data->vendor_config_ver);
cmd[3] = 0x08; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0x28;
himax_register_read(client, cmd, 1, data);
ic_data->vendor_fw_ver = data[0]<<8 | data[1];
- I("FW_VER : %X \n",ic_data->vendor_fw_ver);
-
+ I("FW_VER : %X\n", ic_data->vendor_fw_ver);
- return;
}
bool himax_ic_package_check(struct i2c_client *client)
{
-#if 0
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
uint8_t cmd[3];
uint8_t data[3];
@@ -1574,260 +1794,284 @@ bool himax_ic_package_check(struct i2c_client *client)
memset(data, 0x00, sizeof(data));
if (i2c_himax_read(client, 0xD1, cmd, 3, HIMAX_I2C_RETRY_TIMES) < 0)
- return false ;
+ return false;
if (i2c_himax_read(client, 0x31, data, 3, HIMAX_I2C_RETRY_TIMES) < 0)
return false;
- if((data[0] == 0x85 && data[1] == 0x29))
- {
- IC_TYPE = HX_85XX_F_SERIES_PWON;
- IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 64901; //0xFD85
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 64902; //0xFD86
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 64928; //0xFDA0
- CFG_VER_MAJ_FLASH_LENG = 12;
- CFG_VER_MIN_FLASH_ADDR = 64940; //0xFDAC
- CFG_VER_MIN_FLASH_LENG = 12;
- I("Himax IC package 852x F\n");
- }
- if((data[0] == 0x85 && data[1] == 0x30) || (cmd[0] == 0x05 && cmd[1] == 0x85 && cmd[2] == 0x29))
- {
- IC_TYPE = HX_85XX_E_SERIES_PWON;
- IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 133; //0x0085
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 134; //0x0086
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 160; //0x00A0
- CFG_VER_MAJ_FLASH_LENG = 12;
- CFG_VER_MIN_FLASH_ADDR = 172; //0x00AC
- CFG_VER_MIN_FLASH_LENG = 12;
- I("Himax IC package 852x E\n");
- }
- else if((data[0] == 0x85 && data[1] == 0x31))
- {
- IC_TYPE = HX_85XX_ES_SERIES_PWON;
- IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 133; //0x0085
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 134; //0x0086
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 160; //0x00A0
- CFG_VER_MAJ_FLASH_LENG = 12;
- CFG_VER_MIN_FLASH_ADDR = 172; //0x00AC
- CFG_VER_MIN_FLASH_LENG = 12;
- I("Himax IC package 852x ES\n");
- }
- else if ((data[0] == 0x85 && data[1] == 0x28) || (cmd[0] == 0x04 && cmd[1] == 0x85 &&
- (cmd[2] == 0x26 || cmd[2] == 0x27 || cmd[2] == 0x28))) {
- IC_TYPE = HX_85XX_D_SERIES_PWON;
- IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 133; // 0x0085
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 134; // 0x0086
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 160; // 0x00A0
+ if ((data[0] == 0x85 && data[1] == 0x29)) {
+ IC_TYPE = HX_85XX_F_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 64901; /*0xFD85*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 64902; /*0xFD86*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 64928; /*0xFDA0*/
CFG_VER_MAJ_FLASH_LENG = 12;
- CFG_VER_MIN_FLASH_ADDR = 172; // 0x00AC
+ CFG_VER_MIN_FLASH_ADDR = 64940; /*0xFDAC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x F\n");
+ }
+ if ((data[0] == 0x85 && data[1] == 0x30)
+ || (cmd[0] == 0x05 && cmd[1] == 0x85 && cmd[2] == 0x29)) {
+ IC_TYPE = HX_85XX_E_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 160; /*0x00A0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 172; /*0x00AC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x E\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x31)) {
+ IC_TYPE = HX_85XX_ES_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 160; /*0x00A0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 172; /*0x00AC*/
+ CFG_VER_MIN_FLASH_LENG = 12;
+ I("Himax IC package 852x ES\n");
+ } else if ((data[0] == 0x85 && data[1] == 0x28)
+ || (cmd[0] == 0x04 && cmd[1] == 0x85
+ && (cmd[2] == 0x26 || cmd[2] == 0x27
+ || cmd[2] == 0x28))) {
+ IC_TYPE = HX_85XX_D_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 160; /*0x00A0*/
+ CFG_VER_MAJ_FLASH_LENG = 12;
+ CFG_VER_MIN_FLASH_ADDR = 172; /* 0x00AC*/
CFG_VER_MIN_FLASH_LENG = 12;
I("Himax IC package 852x D\n");
- } else if ((data[0] == 0x85 && data[1] == 0x23) || (cmd[0] == 0x03 && cmd[1] == 0x85 &&
- (cmd[2] == 0x26 || cmd[2] == 0x27 || cmd[2] == 0x28 || cmd[2] == 0x29))) {
- IC_TYPE = HX_85XX_C_SERIES_PWON;
- IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 133; // 0x0085
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 134; // 0x0086
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 135; // 0x0087
+ } else if ((data[0] == 0x85 && data[1] == 0x23) ||
+ (cmd[0] == 0x03 && cmd[1] == 0x85 &&
+ (cmd[2] == 0x26 || cmd[2] == 0x27 ||
+ cmd[2] == 0x28 || cmd[2] == 0x29))) {
+ IC_TYPE = HX_85XX_C_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 134; /*0x0086*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 135; /*0x0087*/
CFG_VER_MAJ_FLASH_LENG = 12;
- CFG_VER_MIN_FLASH_ADDR = 147; // 0x0093
+ CFG_VER_MIN_FLASH_ADDR = 147; /*0x0093*/
CFG_VER_MIN_FLASH_LENG = 12;
I("Himax IC package 852x C\n");
} else if ((data[0] == 0x85 && data[1] == 0x26) ||
- (cmd[0] == 0x02 && cmd[1] == 0x85 &&
- (cmd[2] == 0x19 || cmd[2] == 0x25 || cmd[2] == 0x26))) {
+ (cmd[0] == 0x02 && cmd[1] == 0x85 &&
+ (cmd[2] == 0x19 || cmd[2] == 0x25 || cmd[2] == 0x26))) {
IC_TYPE = HX_85XX_B_SERIES_PWON;
IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 133; // 0x0085
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 728; // 0x02D8
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 692; // 0x02B4
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 133; /*0x0085*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 728; /*0x02D8*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 692; /*0x02B4*/
CFG_VER_MAJ_FLASH_LENG = 3;
- CFG_VER_MIN_FLASH_ADDR = 704; // 0x02C0
+ CFG_VER_MIN_FLASH_ADDR = 704; /*0x02C0*/
CFG_VER_MIN_FLASH_LENG = 3;
I("Himax IC package 852x B\n");
} else if ((data[0] == 0x85 && data[1] == 0x20) || (cmd[0] == 0x01 &&
- cmd[1] == 0x85 && cmd[2] == 0x19)) {
+ cmd[1] == 0x85 && cmd[2] == 0x19)) {
IC_TYPE = HX_85XX_A_SERIES_PWON;
IC_CHECKSUM = HX_TP_BIN_CHECKSUM_SW;
I("Himax IC package 852x A\n");
} else {
E("Himax IC package incorrect!!\n");
- }*/
+ }
#else
- IC_TYPE = HX_83100_SERIES_PWON;
- IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
- //Himax: Set FW and CFG Flash Address
- FW_VER_MAJ_FLASH_ADDR = 57384; //0xE028
- FW_VER_MAJ_FLASH_LENG = 1;
- FW_VER_MIN_FLASH_ADDR = 57385; //0xE029
- FW_VER_MIN_FLASH_LENG = 1;
- CFG_VER_MAJ_FLASH_ADDR = 58115; //0xE303
- CFG_VER_MAJ_FLASH_LENG = 1;
- CFG_VER_MIN_FLASH_ADDR = 58116; //0xE304
- CFG_VER_MIN_FLASH_LENG = 1;
+ IC_TYPE = HX_83100_SERIES_PWON;
+ IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC;
+ /*Himax: Set FW and CFG Flash Address*/
+ FW_VER_MAJ_FLASH_ADDR = 57384; /*0xE028*/
+ FW_VER_MAJ_FLASH_LENG = 1;
+ FW_VER_MIN_FLASH_ADDR = 57385; /*0xE029*/
+ FW_VER_MIN_FLASH_LENG = 1;
+ CFG_VER_MAJ_FLASH_ADDR = 58115; /*0xE303*/
+ CFG_VER_MAJ_FLASH_LENG = 1;
+ CFG_VER_MIN_FLASH_ADDR = 58116; /*0xE304*/
+ CFG_VER_MIN_FLASH_LENG = 1;
I("Himax IC package 83100_in\n");
#endif
return true;
}
-void himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length)
+void himax_read_event_stack(struct i2c_client *client,
+uint8_t *buf, uint8_t length)
{
uint8_t cmd[4];
- cmd[3] = 0x90; cmd[2] = 0x06; cmd[1] = 0x00; cmd[0] = 0x00;
- if ( i2c_himax_write(client, 0x00 ,cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
+ cmd[3] = 0x90; cmd[2] = 0x06;
+ cmd[1] = 0x00; cmd[0] = 0x00;
+ if (i2c_himax_write(client, 0x00,
+ cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
}
- cmd[0] = 0x00;
- if ( i2c_himax_write(client, 0x0C ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
+ cmd[0] = 0x00;
+ if (i2c_himax_write(client, 0x0C,
+ cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
}
- i2c_himax_read(client, 0x08, buf, length, HIMAX_I2C_RETRY_TIMES);
+ i2c_himax_read(client, 0x08,
+ buf, length, HIMAX_I2C_RETRY_TIMES);
}
-#if 0
-static void himax_83100_Flash_Write(uint8_t * reg_byte, uint8_t * write_data)
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static void himax_83100_Flash_Write(uint8_t *reg_byte, uint8_t *write_data)
{
uint8_t tmpbyte[2];
- if ( i2c_himax_write(private_ts->client, 0x00 ,®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x00,
+ ®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x01 ,®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x01,
+ ®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x02 ,®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x02,
+ ®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x03 ,®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client,
+ 0x03, ®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x04 ,&write_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client,
+ 0x04, &write_data[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x05 ,&write_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client,
+ 0x05, &write_data[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x06 ,&write_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client,
+ 0x06, &write_data[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x07 ,&write_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client,
+ 0x07, &write_data[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if (isBusrtOn == false)
- {
- tmpbyte[0] = 0x01;
- if ( i2c_himax_write(private_ts->client, 0x0C ,&tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
- E("%s: i2c access fail!\n", __func__);
- return;
+ if (isBusrtOn == false) {
+ tmpbyte[0] = 0x01;
+ if (i2c_himax_write(private_ts->client,
+ 0x0C, &tmpbyte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
}
- }
+ }
}
#endif
-#if 0
-static void himax_83100_Flash_Burst_Write(uint8_t * reg_byte, uint8_t * write_data)
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
+static void himax_83100_Flash_Burst_Write
+(uint8_t *reg_byte, uint8_t *write_data)
{
- //uint8_t tmpbyte[2];
+ /*uint8_t tmpbyte[2];*/
int i = 0;
- if ( i2c_himax_write(private_ts->client, 0x00 ,®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x00,
+ ®_byte[0], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x01 ,®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x01,
+ ®_byte[1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x02 ,®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x02,
+ ®_byte[2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x03 ,®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x03,
+ ®_byte[3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- // Write 256 bytes with continue burst mode
- for (i = 0; i < 256; i = i + 4)
- {
- if ( i2c_himax_write(private_ts->client, 0x04 ,&write_data[i], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ /*Write 256 bytes with continue burst mode*/
+ for (i = 0 ; i < 256 ; i = i + 4) {
+ if (i2c_himax_write(private_ts->client,
+ 0x04, &write_data[i], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x05 ,&write_data[i+1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x05,
+ &write_data[i+1], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x06 ,&write_data[i+2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x06,
+ &write_data[i+2], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- if ( i2c_himax_write(private_ts->client, 0x07 ,&write_data[i+3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(private_ts->client, 0x07,
+ &write_data[i+3], 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
return;
}
- }
+ }
- //if (isBusrtOn == false)
- //{
- // tmpbyte[0] = 0x01;
- // if ( i2c_himax_write(private_ts->client, 0x0C ,&tmpbyte[0], 1, 3) < 0) {
- // E("%s: i2c access fail!\n", __func__);
- // return;
- // }
- //}
+ /*if (isBusrtOn == false)
+ {
+ tmpbyte[0] = 0x01;
+ if (i2c_himax_write(private_ts->client,
+ 0x0C, &tmpbyte[0], 1, 3) < 0) {
+ E("%s: i2c access fail!\n", __func__);
+ return;
+ }*/
}
#endif
-#if 0
+/*#if 0*/
+#ifdef HX_EN_CHECK_PATCH
static bool himax_83100_Verify(uint8_t *FW_File, int FW_Size)
{
uint8_t tmp_addr[4];
@@ -1835,49 +2079,51 @@ static bool himax_83100_Verify(uint8_t *FW_File, int FW_Size)
uint8_t out_buffer[20];
uint8_t in_buffer[260];
- int fail_addr=0, fail_cnt=0;
+ int fail_addr = 0, fail_cnt = 0;
int page_prog_start = 0;
int i = 0;
himax_interface_on(private_ts->client);
himax_burst_enable(private_ts->client, 0);
- //=====================================
- // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
- //=====================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
- tmp_data[3] = 0x00; tmp_data[2] = 0x02; tmp_data[1] = 0x07; tmp_data[0] = 0x80;
+ /*=====================================
+ SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x10;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x02;
+ tmp_data[1] = 0x07; tmp_data[0] = 0x80;
himax_83100_Flash_Write(tmp_addr, tmp_data);
- for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256)
- {
- //=================================
- // SPI Transfer Control
- // Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
- // Set read start address : 0x8000_0028 ==> 0x0000_0000
- // Set command : 0x8000_0024 ==> 0x0000_003B
- //=================================
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
- tmp_data[3] = 0x69; tmp_data[2] = 0x40; tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
+ for (page_prog_start = 0; page_prog_start < FW_Size;
+ page_prog_start = page_prog_start + 256) {
+ /*=====================================
+ SPI Transfer Control
+ Set 256 bytes page read : 0x8000_0020 ==> 0x6940_02FF
+ Set read start address : 0x8000_0028 ==> 0x0000_0000
+ Set command : 0x8000_0024 ==> 0x0000_003B
+ =====================================*/
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x20;
+ tmp_data[3] = 0x69; tmp_data[2] = 0x40;
+ tmp_data[1] = 0x02; tmp_data[0] = 0xFF;
himax_83100_Flash_Write(tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
- if (page_prog_start < 0x100)
- {
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x28;
+ if (page_prog_start < 0x100) {
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = 0x00;
tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x100 && page_prog_start < 0x10000)
- {
+ } else if (page_prog_start >= 0x100
+ && page_prog_start < 0x10000) {
tmp_data[3] = 0x00;
tmp_data[2] = 0x00;
tmp_data[1] = (uint8_t)(page_prog_start >> 8);
tmp_data[0] = (uint8_t)page_prog_start;
- }
- else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000)
- {
+ } else if (page_prog_start >= 0x10000
+ && page_prog_start < 0x1000000) {
tmp_data[3] = 0x00;
tmp_data[2] = (uint8_t)(page_prog_start >> 16);
tmp_data[1] = (uint8_t)(page_prog_start >> 8);
@@ -1885,65 +2131,73 @@ static bool himax_83100_Verify(uint8_t *FW_File, int FW_Size)
}
himax_83100_Flash_Write(tmp_addr, tmp_data);
- tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x24;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x00; tmp_data[0] = 0x3B;
himax_83100_Flash_Write(tmp_addr, tmp_data);
- //==================================
- // AHB_I2C Burst Read
- // Set SPI data register : 0x8000_002C ==> 0x00
- //==================================
+ /*==================================
+ AHB_I2C Burst Read
+ Set SPI data register : 0x8000_002C ==> 0x00
+ ==================================*/
out_buffer[0] = 0x2C;
out_buffer[1] = 0x00;
out_buffer[2] = 0x00;
out_buffer[3] = 0x80;
- i2c_himax_write(private_ts->client, 0x00 ,out_buffer, 4, HIMAX_I2C_RETRY_TIMES);
+ i2c_himax_write(private_ts->client, 0x00,
+ out_buffer, 4, HIMAX_I2C_RETRY_TIMES);
- //==================================
- // Read access : 0x0C ==> 0x00
- //==================================
+ /*==================================
+ Read access : 0x0C ==> 0x00
+ ==================================*/
out_buffer[0] = 0x00;
- i2c_himax_write(private_ts->client, 0x0C ,out_buffer, 1, HIMAX_I2C_RETRY_TIMES);
-
- //==================================
- // Read 128 bytes two times
- //==================================
- i2c_himax_read(private_ts->client, 0x08 ,in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
+ i2c_himax_write(private_ts->client, 0x0C,
+ out_buffer, 1, HIMAX_I2C_RETRY_TIMES);
+
+ /*==================================
+ Read 128 bytes two times
+ ==================================*/
+ i2c_himax_read(private_ts->client, 0x08,
+ in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
for (i = 0; i < 128; i++)
flash_buffer[i + page_prog_start] = in_buffer[i];
- i2c_himax_read(private_ts->client, 0x08 ,in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
+ i2c_himax_read(private_ts->client, 0x08,
+ in_buffer, 128, HIMAX_I2C_RETRY_TIMES);
for (i = 0; i < 128; i++)
- flash_buffer[(i + 128) + page_prog_start] = in_buffer[i];
-
- //tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
- //himax_register_read(tmp_addr, 32, out in_buffer);
- //for (int i = 0; i < 128; i++)
- // flash_buffer[i + page_prog_start] = in_buffer[i];
- //tmp_addr[3] = 0x80; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
- //himax_register_read(tmp_addr, 32, out in_buffer);
- //for (int i = 0; i < 128; i++)
- // flash_buffer[i + page_prog_start] = in_buffer[i];
-
+ flash_buffer[(i + 128)
+ + page_prog_start] = in_buffer[i];
+
+ /*tmp_addr[3] = 0x80;
+ tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+ himax_register_read(tmp_addr, 32, out in_buffer);
+ for (int i = 0; i < 128; i++)
+ flash_buffer[i + page_prog_start] = in_buffer[i];
+ tmp_addr[3] = 0x80; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x00; tmp_addr[0] = 0x2C;
+ himax_register_read(tmp_addr, 32, out in_buffer);
+ for (int i = 0; i < 128; i++)
+ flash_buffer[i + page_prog_start] = in_buffer[i];
+ */
I("%s:Verify Progress: %x\n", __func__, page_prog_start);
}
fail_cnt = 0;
- for (i = 0; i < FW_Size; i++)
- {
- if (FW_File[i] != flash_buffer[i])
- {
+ for (i = 0; i < FW_Size; i++) {
+ if (FW_File[i] != flash_buffer[i]) {
if (fail_cnt == 0)
fail_addr = i;
fail_cnt++;
- //E("%s Fail Block:%x\n", __func__, i);
- //return false;
+ /*E("%s Fail Block:%x\n", __func__, i);
+ return false;*/
}
}
- if (fail_cnt > 0)
- {
- E("%s:Start Fail Block:%x and fail block count=%x\n" , __func__,fail_addr,fail_cnt);
+ if (fail_cnt > 0) {
+ E("%s:Start Fail Block:%x and fail block count=%x\n",
+ __func__, fail_addr, fail_cnt);
return false;
}
@@ -1959,56 +2213,60 @@ void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data)
int cnt = 0;
unsigned char tmp_addr[4];
unsigned char tmp_data[4];
- uint8_t max_i2c_size = 32;
+ uint8_t max_i2c_size = 32;
int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2;
int total_size_4bytes = total_size / 4;
int total_read_times = 0;
unsigned long address = 0x08000468;
- tmp_addr[3] = 0x08; tmp_addr[2] = 0x00; tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
- tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x5A; tmp_data[0] = 0xA5;
+
+ tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
+ tmp_data[3] = 0x00; tmp_data[2] = 0x00;
+ tmp_data[1] = 0x5A; tmp_data[0] = 0xA5;
himax_flash_write_burst(client, tmp_addr, tmp_data);
- do
- {
+ do {
cnt++;
himax_register_read(client, tmp_addr, 1, tmp_data);
- usleep_range(10000, 20000);
+ usleep_range(9999, 10000);
} while ((tmp_data[1] != 0xA5 || tmp_data[0] != 0x5A) && cnt < 100);
- tmp_addr[3] = 0x08; tmp_addr[2] = 0x00; tmp_addr[1] = 0x04; tmp_addr[0] = 0x68;
- if (total_size_4bytes % max_i2c_size == 0)
- {
+ tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x04; tmp_addr[0] = 0x68;
+ if (total_size_4bytes % max_i2c_size == 0)
total_read_times = total_size_4bytes / max_i2c_size;
- }
else
- {
total_read_times = total_size_4bytes / max_i2c_size + 1;
- }
- for (i = 0; i < (total_read_times); i++)
- {
- if ( total_size_4bytes >= max_i2c_size)
- {
- himax_register_read(client, tmp_addr, max_i2c_size, &info_data[i*max_i2c_size*4]);
+
+ for (i = 0 ; i < (total_read_times) ; i++) {
+ if (total_size_4bytes >= max_i2c_size) {
+ himax_register_read(client, tmp_addr,
+ max_i2c_size,
+ &info_data[i*max_i2c_size*4]);
total_size_4bytes = total_size_4bytes - max_i2c_size;
+ } else {
+ himax_register_read(client, tmp_addr,
+ total_size_4bytes % max_i2c_size,
+ &info_data[i*max_i2c_size*4]);
}
- else
- {
- himax_register_read(client, tmp_addr, total_size_4bytes % max_i2c_size, &info_data[i*max_i2c_size*4]);
- }
- address += max_i2c_size*4;
- tmp_addr[1] = (uint8_t)((address>>8)&0x00FF);
- tmp_addr[0] = (uint8_t)((address)&0x00FF);
- }
- tmp_addr[3] = 0x08; tmp_addr[2] = 0x00; tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
- tmp_data[3] = 0x11; tmp_data[2] = 0x22; tmp_data[1] = 0x33; tmp_data[0] = 0x44;
+ address += max_i2c_size * 4;
+ tmp_addr[1] = (uint8_t)((address>>8) & 0x00FF);
+ tmp_addr[0] = (uint8_t)((address) & 0x00FF);
+ }
+ tmp_addr[3] = 0x08; tmp_addr[2] = 0x00;
+ tmp_addr[1] = 0x04; tmp_addr[0] = 0x64;
+ tmp_data[3] = 0x11; tmp_data[2] = 0x22;
+ tmp_data[1] = 0x33; tmp_data[0] = 0x44;
himax_flash_write_burst(client, tmp_addr, tmp_data);
}
-//ts_work
-int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max){
+/*ts_work*/
+int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max)
+{
int RawDataLen;
- if (raw_cnt_rmd != 0x00) {
- RawDataLen = 124 - ((HX_MAX_PT+raw_cnt_max+3)*4) - 1;
- }else{
- RawDataLen = 124 - ((HX_MAX_PT+raw_cnt_max+2)*4) - 1;
- }
+
+ if (raw_cnt_rmd != 0x00)
+ RawDataLen = 124 - ((HX_MAX_PT + raw_cnt_max + 3) * 4) - 1;
+ else
+ RawDataLen = 124 - ((HX_MAX_PT + raw_cnt_max + 2) * 4) - 1;
+
return RawDataLen;
}
@@ -2016,40 +2274,40 @@ bool read_event_stack(struct i2c_client *client, uint8_t *buf, int length)
{
uint8_t cmd[4];
- if(length > 56)
+ if (length > 56)
length = 124;
- //=====================
- //AHB I2C Burst Read
- //=====================
+ /*=====================
+ AHB I2C Burst Read
+ =====================*/
cmd[0] = 0x31;
- if ( i2c_himax_write(client, 0x13 ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x13, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
goto err_workqueue_out;
}
cmd[0] = 0x10;
- if ( i2c_himax_write(client, 0x0D ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x0D, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
goto err_workqueue_out;
}
- //=====================
- //Read event stack
- //=====================
+ /*=====================
+ Read event stack
+ =====================*/
cmd[3] = 0x90; cmd[2] = 0x06; cmd[1] = 0x00; cmd[0] = 0x00;
- if ( i2c_himax_write(client, 0x00 ,cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x00, cmd, 4, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
goto err_workqueue_out;
}
cmd[0] = 0x00;
- if ( i2c_himax_write(client, 0x0C ,cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
+ if (i2c_himax_write(client, 0x0C, cmd, 1, HIMAX_I2C_RETRY_TIMES) < 0) {
E("%s: i2c access fail!\n", __func__);
goto err_workqueue_out;
}
- i2c_himax_read(client, 0x08, buf, length,HIMAX_I2C_RETRY_TIMES);
+ i2c_himax_read(client, 0x08, buf, length, HIMAX_I2C_RETRY_TIMES);
return 1;
-
- err_workqueue_out:
+
+err_workqueue_out:
return 0;
}
@@ -2057,62 +2315,67 @@ bool post_read_event_stack(struct i2c_client *client)
{
return 1;
}
-bool diag_check_sum( uint8_t hx_touch_info_size, uint8_t *buf) //return checksum value
+bool diag_check_sum(uint8_t hx_touch_info_size,
+uint8_t *buf) /*return checksum value*/
{
uint16_t check_sum_cal = 0;
int i;
- //Check 124th byte CRC
- for (i = hx_touch_info_size, check_sum_cal = 0; i < 124; i=i+2)
- {
- check_sum_cal += (buf[i+1]*256 + buf[i]);
- }
- if (check_sum_cal % 0x10000 != 0)
- {
- I("%s: diag check sum fail! check_sum_cal=%X, hx_touch_info_size=%d, \n",__func__,check_sum_cal, hx_touch_info_size);
+ /*Check 124th byte CRC*/
+ for (i = hx_touch_info_size, check_sum_cal = 0 ; i < 124 ; i = i + 2)
+ check_sum_cal += (buf[i + 1] * 256 + buf[i]);
+
+ if (check_sum_cal % 0x10000 != 0) {
+ I("%s:diag chksum fail!check_sum_cal=%X,hx_touchinfo_sz=%d,\n",
+ __func__, check_sum_cal, hx_touch_info_size);
return 0;
}
return 1;
}
-
-void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen, int mul_num, int self_num, uint8_t *buf, uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data)
+void diag_parse_raw_data(int hx_touch_info_size,
+int RawDataLen, int mul_num, int self_num, uint8_t *buf,
+uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data)
{
int RawDataLen_word;
int index = 0;
- int temp1, temp2,i;
-
- if (buf[hx_touch_info_size] == 0x3A && buf[hx_touch_info_size+1] == 0xA3 && buf[hx_touch_info_size+2] > 0 && buf[hx_touch_info_size+3] == diag_cmd+5 )
- {
- RawDataLen_word = RawDataLen/2;
- index = (buf[hx_touch_info_size+2] - 1) * RawDataLen_word;
- //I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);
- for (i = 0; i < RawDataLen_word; i++)
- {
+ int temp1, temp2, i;
+
+ if (buf[hx_touch_info_size] == 0x3A &&
+ buf[hx_touch_info_size + 1] == 0xA3 &&
+ buf[hx_touch_info_size + 2] > 0 &&
+ buf[hx_touch_info_size + 3] == diag_cmd + 5) {
+ RawDataLen_word = RawDataLen / 2;
+ index = (buf[hx_touch_info_size + 2] - 1) * RawDataLen_word;
+ /*I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",
+ index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);*/
+ for (i = 0; i < RawDataLen_word; i++) {
temp1 = index + i;
- if (temp1 < mul_num)
- { //mutual
- mutual_data[index + i] = buf[i*2 + hx_touch_info_size+4+1]*256 + buf[i*2 + hx_touch_info_size+4]; //4: RawData Header, 1:HSB
- }
- else
- {//self
+ if (temp1 < mul_num) { /*mutual*/
+ /*4: RawData Header, 1:HSB */
+ mutual_data[index + i]
+ = buf[i*2 + hx_touch_info_size + 4 + 1]
+ * 256
+ + buf[i * 2 + hx_touch_info_size + 4];
+ } else { /*self*/
temp1 = i + index;
temp2 = self_num + mul_num;
-
+
if (temp1 >= temp2)
- {
break;
- }
- self_data[i+index-mul_num] = buf[i*2 + hx_touch_info_size+4]; //4: RawData Header
- self_data[i+index-mul_num+1] = buf[i*2 + hx_touch_info_size+4+1];
+ /*4: RawData Header*/
+ self_data[i + index - mul_num]
+ = buf[i * 2 + hx_touch_info_size + 4];
+ self_data[i + index - mul_num + 1]
+ = buf[i * 2 + hx_touch_info_size + 4 + 1];
}
}
- }
- else
- {
+ } else {
I("[HIMAX TP MSG]%s: header format is wrong!\n", __func__);
- I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num);
+ I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n",
+ index, buf[56], buf[57], buf[58], buf[59],
+ mul_num, self_num);
}
}
diff --git a/drivers/input/touchscreen/hxchipset/himax_ic.h b/drivers/input/touchscreen/hxchipset/himax_ic.h
index 18cd12b8b36f..ce7d0d49c362 100644
--- a/drivers/input/touchscreen/hxchipset/himax_ic.h
+++ b/drivers/input/touchscreen/hxchipset/himax_ic.h
@@ -18,7 +18,6 @@
#include
-
#define HX_85XX_A_SERIES_PWON 1
#define HX_85XX_B_SERIES_PWON 2
#define HX_85XX_C_SERIES_PWON 3
@@ -40,43 +39,110 @@ enum fw_image_type {
};
int himax_hand_shaking(struct i2c_client *client);
-void himax_set_SMWP_enable(struct i2c_client *client,uint8_t SMWP_enable);
-void himax_get_SMWP_enable(struct i2c_client *client,uint8_t *tmp_data);
-void himax_set_HSEN_enable(struct i2c_client *client,uint8_t HSEN_enable);
-void himax_get_HSEN_enable(struct i2c_client *client,uint8_t *tmp_data);
+void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable);
+void himax_get_SMWP_enable(struct i2c_client *client, uint8_t *tmp_data);
+void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable);
+void himax_get_HSEN_enable(struct i2c_client *client, uint8_t *tmp_data);
void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command);
-void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer);
+
+void himax_flash_dump_func(struct i2c_client *client,
+uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer);
+
int himax_chip_self_test(struct i2c_client *client);
-int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte); ////himax_83100_BURST_INC0_EN
-void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data); ////RegisterRead83100
-void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data); ////himax_83100_Flash_Read
-void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data); ////himax_83100_Flash_Write_Burst
-int himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length); ////himax_83100_Flash_Write_Burst_lenth
-int himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data); ////RegisterWrite83100
-void himax_sense_off(struct i2c_client *client); ////himax_83100_SenseOff
-void himax_interface_on(struct i2c_client *client); ////himax_83100_Interface_on
+
+/*himax_83100_BURST_INC0_EN*/
+int himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte);
+
+/*RegisterRead83100*/
+void himax_register_read(struct i2c_client *client,
+ uint8_t *read_addr, int read_length, uint8_t *read_data);
+
+/*himax_83100_Flash_Read*/
+void himax_flash_read(struct i2c_client *client,
+ uint8_t *reg_byte, uint8_t *read_data);
+
+/*himax_83100_Flash_Write_Burst*/
+void himax_flash_write_burst(struct i2c_client *client,
+ uint8_t *reg_byte, uint8_t *write_data);
+
+/*himax_83100_Flash_Write_Burst_length*/
+int himax_flash_write_burst_length(struct i2c_client *client,
+ uint8_t *reg_byte, uint8_t *write_data, int length);
+
+/*RegisterWrite83100*/
+int himax_register_write(struct i2c_client *client,
+ uint8_t *write_addr, int write_length, uint8_t *write_data);
+
+/*himax_83100_SenseOff*/
+void himax_sense_off(struct i2c_client *client);
+/*himax_83100_Interface_on*/
+void himax_interface_on(struct i2c_client *client);
bool wait_wip(struct i2c_client *client, int Timing);
-void himax_sense_on(struct i2c_client *client, uint8_t FlashMode); ////himax_83100_SenseOn
-void himax_chip_erase(struct i2c_client *client); ////himax_83100_Chip_Erase
-bool himax_block_erase(struct i2c_client *client); ////himax_83100_Block_Erase
-bool himax_sector_erase(struct i2c_client *client, int start_addr); ////himax_83100_Sector_Erase
-void himax_sram_write(struct i2c_client *client, uint8_t *FW_content); ////himax_83100_Sram_Write
-bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size); ////himax_83100_Sram_Verify
-void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size); ////himax_83100_Flash_Programming
-bool himax_check_chip_version(struct i2c_client *client); ////himax_83100_CheckChipVersion
-int himax_check_CRC(struct i2c_client *client, int mode); ////himax_83100_Check_CRC
-bool Calculate_CRC_with_AP(unsigned char *FW_content , int CRC_from_FW, int mode);
-int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
-int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
-int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
-int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref);
+
+/*himax_83100_SenseOn*/
+void himax_sense_on(struct i2c_client *client,
+ uint8_t FlashMode);
+
+/*himax_83100_Chip_Erase*/
+void himax_chip_erase(struct i2c_client *client);
+/*himax_83100_Block_Erase*/
+bool himax_block_erase(struct i2c_client *client);
+
+/*himax_83100_Sector_Erase*/
+bool himax_sector_erase(struct i2c_client *client, int start_addr);
+
+/*himax_83100_Sram_Write*/
+void himax_sram_write(struct i2c_client *client, uint8_t *FW_content);
+
+/*himax_83100_Sram_Verify*/
+bool himax_sram_verify(struct i2c_client *client,
+ uint8_t *FW_File, int FW_Size);
+
+/*himax_83100_Flash_Programming*/
+void himax_flash_programming(struct i2c_client *client,
+ uint8_t *FW_content, int FW_Size);
+
+/*himax_83100_CheckChipVersion*/
+bool himax_check_chip_version(struct i2c_client *client);
+
+/*himax_83100_Check_CRC*/
+int himax_check_CRC(struct i2c_client *client, int mode);
+
+bool Calculate_CRC_with_AP(unsigned char *FW_content,
+ int CRC_from_FW, int mode);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
+int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client,
+ unsigned char *fw, int len, bool change_iref);
+
void himax_touch_information(struct i2c_client *client);
void himax_read_FW_ver(struct i2c_client *client);
bool himax_ic_package_check(struct i2c_client *client);
-void himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length);
+
+void himax_read_event_stack(struct i2c_client *client,
+ uint8_t *buf, uint8_t length);
+
int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max);
bool read_event_stack(struct i2c_client *client, uint8_t *buf_ts, int length);
bool post_read_event_stack(struct i2c_client *client);
-bool diag_check_sum( uint8_t hx_touch_info_size, uint8_t *buf_ts); //return checksum value
-void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen, int mul_num, int self_num, uint8_t *buf_ts, uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data);
-void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data);
\ No newline at end of file
+
+/*return checksum value*/
+bool diag_check_sum(uint8_t hx_touch_info_size, uint8_t *buf_ts);
+
+void diag_parse_raw_data(int hx_touch_info_size, int RawDataLen,
+ int mul_num, int self_num, uint8_t *buf_ts,
+ uint8_t diag_cmd, int16_t *mutual_data, int16_t *self_data);
+
+void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data);
+extern struct himax_ts_data *private_ts;
+extern struct himax_ic_data *ic_data;
+
+int himax_load_CRC_bin_file(struct i2c_client *client);
diff --git a/drivers/input/touchscreen/hxchipset/himax_platform.c b/drivers/input/touchscreen/hxchipset/himax_platform.c
index 7e8a1d6572c5..309bb5e01073 100644
--- a/drivers/input/touchscreen/hxchipset/himax_platform.c
+++ b/drivers/input/touchscreen/hxchipset/himax_platform.c
@@ -16,6 +16,13 @@
#include "himax_platform.h"
#include "himax_common.h"
+#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
+#define D(x...) pr_info("[HXTP][DEBUG] " x)
+#define I(x...) pr_info("[HXTP][INFO] " x)
+#define W(x...) pr_info("[HXTP][WARNING] " x)
+#define E(x...) pr_info("[HXTP][ERROR] " x)
+#endif
+
int irq_enable_count = 0;
#ifdef HX_SMART_WAKEUP
#define TS_WAKE_LOCK_TIMEOUT (2 * HZ)
@@ -25,16 +32,7 @@ int irq_enable_count = 0;
#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
#define PINCTRL_STATE_RELEASE "pmx_ts_release"
-extern struct himax_ic_data* ic_data;
-extern void himax_ts_work(struct himax_ts_data *ts);
-extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
-extern int himax_ts_init(struct himax_ts_data *ts);
-
-extern int tp_rst_gpio;
-
-#ifdef HX_TP_PROC_DIAG
-extern uint8_t getDiagCommand(void);
-#endif
+/*extern int himax_ts_init(struct himax_ts_data *ts);*/
void himax_vk_parser(struct device_node *dt,
struct himax_i2c_platform_data *pdata)
@@ -49,30 +47,34 @@ void himax_vk_parser(struct device_node *dt,
if (node == NULL) {
I(" DT-No vk info in DT");
return;
+
} else {
while ((pp = of_get_next_child(node, pp)))
cnt++;
if (!cnt)
return;
- vk = kzalloc(cnt * (sizeof *vk), GFP_KERNEL);
- if (!vk)
- return;
+ vk = kcalloc(cnt, sizeof(*vk), GFP_KERNEL);
pp = NULL;
while ((pp = of_get_next_child(node, pp))) {
if (of_property_read_u32(pp, "idx", &data) == 0)
vk[i].index = data;
- if (of_property_read_u32_array(pp, "range", coords, 4) == 0) {
- vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1];
- vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3];
+ if (of_property_read_u32_array(pp, "range",
+ coords, 4) == 0) {
+ vk[i].x_range_min = coords[0],
+ vk[i].x_range_max = coords[1];
+ vk[i].y_range_min = coords[2],
+ vk[i].y_range_max = coords[3];
} else
I(" range faile");
i++;
}
pdata->virtual_key = vk;
for (i = 0; i < cnt; i++)
- I(" vk[%d] idx:%d x_min:%d, y_max:%d", i,pdata->virtual_key[i].index,
- pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max);
+ I(" vk[%d] idx:%d x_min:%d, y_max:%d",
+ i, pdata->virtual_key[i].index,
+ pdata->virtual_key[i].x_range_min,
+ pdata->virtual_key[i].y_range_max);
}
}
@@ -89,25 +91,31 @@ int himax_parse_dt(struct himax_ts_data *ts,
if (prop) {
coords_size = prop->length / sizeof(u32);
if (coords_size != 4)
- D(" %s:Invalid panel coords size %d", __func__, coords_size);
+ D(" %s:Invalid panel coords size %d",
+ __func__, coords_size);
}
- if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0) {
+ if (of_property_read_u32_array(dt, "himax,panel-coords",
+ coords, coords_size) == 0) {
pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1];
pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3];
- I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min,
- pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max);
+ I(" DT-%s:panel-coords = %d, %d, %d, %d\n",
+ __func__, pdata->abs_x_min, pdata->abs_x_max,
+ pdata->abs_y_min, pdata->abs_y_max);
}
prop = of_find_property(dt, "himax,display-coords", NULL);
if (prop) {
coords_size = prop->length / sizeof(u32);
if (coords_size != 4)
- D(" %s:Invalid display coords size %d", __func__, coords_size);
+ D(" %s:Invalid display coords size %d",
+ __func__, coords_size);
}
- rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size);
+ rc = of_property_read_u32_array(dt, "himax,display-coords",
+ coords, coords_size);
if (rc && (rc != -EINVAL)) {
- D(" %s:Fail to read display-coords %d\n", __func__, rc);
+ D(" %s:Fail to read display-coords %d\n",
+ __func__, rc);
return rc;
}
pdata->screenWidth = coords[1];
@@ -116,19 +124,19 @@ int himax_parse_dt(struct himax_ts_data *ts,
pdata->screenHeight);
pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0);
- if (!gpio_is_valid(pdata->gpio_irq)) {
+ if (!gpio_is_valid(pdata->gpio_irq))
I(" DT:gpio_irq value is not valid\n");
- }
pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0);
- if (!gpio_is_valid(pdata->gpio_reset)) {
+ if (!gpio_is_valid(pdata->gpio_reset))
I(" DT:gpio_rst value is not valid\n");
- }
+
pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0);
- if (!gpio_is_valid(pdata->gpio_3v3_en)) {
+ if (!gpio_is_valid(pdata->gpio_3v3_en))
I(" DT:gpio_3v3_en value is not valid\n");
- }
- I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
+
+ I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d",
+ pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
if (of_property_read_u32(dt, "report_type", &data) == 0) {
pdata->protocol_type = data;
@@ -140,7 +148,8 @@ int himax_parse_dt(struct himax_ts_data *ts,
return 0;
}
-int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+int i2c_himax_read(struct i2c_client *client,
+uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
{
int retry;
struct i2c_msg msg[] = {
@@ -157,7 +166,7 @@ int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, ui
.buf = data,
}
};
-
+ mutex_lock(&private_ts->rw_lock);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 2) == 2)
break;
@@ -166,13 +175,16 @@ int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, ui
if (retry == toRetry) {
E("%s: i2c_read_block retry over %d\n",
__func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
+ mutex_unlock(&private_ts->rw_lock);
return 0;
}
-int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
+int i2c_himax_write(struct i2c_client *client,
+uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry)
{
int retry/*, loop_i*/;
uint8_t buf[length + 1];
@@ -188,7 +200,7 @@ int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, u
buf[0] = command;
memcpy(buf+1, data, length);
-
+ mutex_lock(&private_ts->rw_lock);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 1) == 1)
break;
@@ -198,13 +210,16 @@ int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, u
if (retry == toRetry) {
E("%s: i2c_write_block retry over %d\n",
__func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
+ mutex_unlock(&private_ts->rw_lock);
return 0;
}
-int i2c_himax_read_command(struct i2c_client *client, uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry)
+int i2c_himax_read_command(struct i2c_client *client,
+uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry)
{
int retry;
struct i2c_msg msg[] = {
@@ -215,7 +230,7 @@ int i2c_himax_read_command(struct i2c_client *client, uint8_t length, uint8_t *d
.buf = data,
}
};
-
+ mutex_lock(&private_ts->rw_lock);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 1) == 1)
break;
@@ -224,17 +239,21 @@ int i2c_himax_read_command(struct i2c_client *client, uint8_t length, uint8_t *d
if (retry == toRetry) {
E("%s: i2c_read_block retry over %d\n",
__func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
+ mutex_unlock(&private_ts->rw_lock);
return 0;
}
-int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry)
+int i2c_himax_write_command(struct i2c_client *client,
+uint8_t command, uint8_t toRetry)
{
return i2c_himax_write(client, command, NULL, 0, toRetry);
}
-int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry)
+int i2c_himax_master_write(struct i2c_client *client,
+uint8_t *data, uint8_t length, uint8_t toRetry)
{
int retry/*, loop_i*/;
uint8_t buf[length];
@@ -249,7 +268,7 @@ int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t len
};
memcpy(buf, data, length);
-
+ mutex_lock(&private_ts->rw_lock);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 1) == 1)
break;
@@ -259,8 +278,10 @@ int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t len
if (retry == toRetry) {
E("%s: i2c_write_block retry over %d\n",
__func__, toRetry);
+ mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
+ mutex_unlock(&private_ts->rw_lock);
return 0;
}
@@ -287,62 +308,51 @@ uint8_t himax_int_gpio_read(int pinnum)
}
#if defined(CONFIG_HMX_DB)
-static int himax_regulator_configure(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+static int himax_regulator_configure(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
{
- int retval;
- pdata->vcc_dig = regulator_get(&client->dev,
- "vdd");
- if (IS_ERR(pdata->vcc_dig))
- {
- E("%s: Failed to get regulator vdd\n",
- __func__);
- retval = PTR_ERR(pdata->vcc_dig);
- return retval;
- }
- pdata->vcc_ana = regulator_get(&client->dev,
- "avdd");
- if (IS_ERR(pdata->vcc_ana))
- {
- E("%s: Failed to get regulator avdd\n",
- __func__);
- retval = PTR_ERR(pdata->vcc_ana);
- regulator_put(pdata->vcc_ana);
- return retval;
- }
-
- return 0;
+ int retval;
+
+ pdata->vcc_dig = regulator_get(&client->dev, "vdd");
+ if (IS_ERR(pdata->vcc_dig)) {
+ E("%s: Failed to get regulator vdd\n", __func__);
+ retval = PTR_ERR(pdata->vcc_dig);
+ return retval;
+ }
+ pdata->vcc_ana = regulator_get(&client->dev, "avdd");
+ if (IS_ERR(pdata->vcc_ana)) {
+ E("%s: Failed to get regulator avdd\n", __func__);
+ retval = PTR_ERR(pdata->vcc_ana);
+ regulator_put(pdata->vcc_ana);
+ return retval;
+ }
+
+ return 0;
};
-static int himax_power_on(struct himax_i2c_platform_data *pdata, bool on)
+static int himax_power_on(struct himax_i2c_platform_data *pdata,
+bool on)
{
- int retval;
-
- if (on)
- {
- retval = regulator_enable(pdata->vcc_dig);
- if (retval)
- {
- E("%s: Failed to enable regulator vdd\n",
- __func__);
- return retval;
- }
- msleep(100);
- retval = regulator_enable(pdata->vcc_ana);
- if (retval)
- {
- E("%s: Failed to enable regulator avdd\n",
- __func__);
- regulator_disable(pdata->vcc_dig);
- return retval;
- }
- }
- else
- {
- regulator_disable(pdata->vcc_dig);
- regulator_disable(pdata->vcc_ana);
- }
-
- return 0;
+ int retval;
+
+ if (on) {
+ retval = regulator_enable(pdata->vcc_dig);
+ if (retval) {
+ E("%s: Failed to enable regulator vdd\n", __func__);
+ return retval;
+ }
+ msleep(100);
+ retval = regulator_enable(pdata->vcc_ana);
+ if (retval) {
+ E("%s: Failed to enable regulator avdd\n", __func__);
+ regulator_disable(pdata->vcc_dig);
+ return retval;
+ }
+ } else {
+ regulator_disable(pdata->vcc_dig);
+ regulator_disable(pdata->vcc_ana);
+ }
+ return 0;
}
int himax_ts_pinctrl_init(struct himax_ts_data *ts)
@@ -353,41 +363,35 @@ int himax_ts_pinctrl_init(struct himax_ts_data *ts)
ts->ts_pinctrl = devm_pinctrl_get(&(ts->client->dev));
if (IS_ERR_OR_NULL(ts->ts_pinctrl)) {
retval = PTR_ERR(ts->ts_pinctrl);
- dev_dbg(&ts->client->dev,
- "Target does not use pinctrl %d\n", retval);
+ dev_dbg(&ts->client->dev, "Target does not use pinctrl %d\n",
+ retval);
goto err_pinctrl_get;
}
- ts->pinctrl_state_active
- = pinctrl_lookup_state(ts->ts_pinctrl,
- PINCTRL_STATE_ACTIVE);
+ ts->pinctrl_state_active = pinctrl_lookup_state(ts->ts_pinctrl,
+ PINCTRL_STATE_ACTIVE);
if (IS_ERR_OR_NULL(ts->pinctrl_state_active)) {
retval = PTR_ERR(ts->pinctrl_state_active);
- dev_err(&ts->client->dev,
- "Can not lookup %s pinstate %d\n",
- PINCTRL_STATE_ACTIVE, retval);
+ dev_err(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+ PINCTRL_STATE_ACTIVE, retval);
goto err_pinctrl_lookup;
}
- ts->pinctrl_state_suspend
- = pinctrl_lookup_state(ts->ts_pinctrl,
- PINCTRL_STATE_SUSPEND);
+ ts->pinctrl_state_suspend = pinctrl_lookup_state(ts->ts_pinctrl,
+ PINCTRL_STATE_SUSPEND);
if (IS_ERR_OR_NULL(ts->pinctrl_state_suspend)) {
retval = PTR_ERR(ts->pinctrl_state_suspend);
- dev_err(&ts->client->dev,
- "Can not lookup %s pinstate %d\n",
- PINCTRL_STATE_SUSPEND, retval);
+ dev_err(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+ PINCTRL_STATE_SUSPEND, retval);
goto err_pinctrl_lookup;
}
- ts->pinctrl_state_release
- = pinctrl_lookup_state(ts->ts_pinctrl,
- PINCTRL_STATE_RELEASE);
+ ts->pinctrl_state_release = pinctrl_lookup_state(ts->ts_pinctrl,
+ PINCTRL_STATE_RELEASE);
if (IS_ERR_OR_NULL(ts->pinctrl_state_release)) {
retval = PTR_ERR(ts->pinctrl_state_release);
- dev_dbg(&ts->client->dev,
- "Can not lookup %s pinstate %d\n",
- PINCTRL_STATE_RELEASE, retval);
+ dev_dbg(&ts->client->dev, "Can not lookup %s pinstate %d\n",
+ PINCTRL_STATE_RELEASE, retval);
}
return 0;
@@ -399,185 +403,161 @@ int himax_ts_pinctrl_init(struct himax_ts_data *ts)
return retval;
}
-int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+int himax_gpio_power_config(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
{
- int error;
+ int error;
- error = himax_regulator_configure(client, pdata);
- if (error)
- {
- E("Failed to intialize hardware\n");
- goto err_regulator_not_on;
- }
+ error = himax_regulator_configure(client, pdata);
+ if (error) {
+ E("Failed to initialize hardware\n");
+ goto err_regulator_not_on;
+ }
#ifdef HX_RST_PIN_FUNC
- if (gpio_is_valid(pdata->gpio_reset))
- {
- /* configure touchscreen reset out gpio */
- error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
- if (error)
- {
- E("unable to request gpio [%d]\n",
- pdata->gpio_reset);
- goto err_regulator_on;
- }
-
- error = gpio_direction_output(pdata->gpio_reset, 0);
- if (error)
- {
- E("unable to set direction for gpio [%d]\n",
- pdata->gpio_reset);
- goto err_gpio_reset_req;
- }
- }
+ if (gpio_is_valid(pdata->gpio_reset)) {
+ /* configure touchscreen reset out gpio */
+ error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
+ if (error) {
+ E("unable to request gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_regulator_on;
+ }
+ error = gpio_direction_output(pdata->gpio_reset, 0);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_gpio_reset_req;
+ }
+ }
#endif
- error = himax_power_on(pdata, true);
- if (error)
- {
- E("Failed to power on hardware\n");
- goto err_gpio_reset_req;
- }
+ error = himax_power_on(pdata, true);
+ if (error) {
+ E("Failed to power on hardware\n");
+ goto err_gpio_reset_req;
+ }
#ifdef HX_IRQ_PIN_FUNC
- if (gpio_is_valid(pdata->gpio_irq))
- {
- /* configure touchscreen irq gpio */
- error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
- if (error)
- {
- E("unable to request gpio [%d]\n",
- pdata->gpio_irq);
- goto err_power_on;
- }
- error = gpio_direction_input(pdata->gpio_irq);
- if (error)
- {
- E("unable to set direction for gpio [%d]\n",
- pdata->gpio_irq);
- goto err_gpio_irq_req;
- }
- client->irq = gpio_to_irq(pdata->gpio_irq);
- }
- else
- {
- E("irq gpio not provided\n");
- goto err_power_on;
- }
+ /* configure touchscreen irq gpio */
+ if (gpio_is_valid(pdata->gpio_irq)) {
+ error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
+ if (error) {
+ E("unable to request gpio [%d]\n", pdata->gpio_irq);
+ goto err_power_on;
+ }
+ error = gpio_direction_input(pdata->gpio_irq);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_irq);
+ goto err_gpio_irq_req;
+ }
+ client->irq = gpio_to_irq(pdata->gpio_irq);
+ } else {
+ E("irq gpio not provided\n");
+ goto err_power_on;
+ }
#endif
-
- msleep(20);
+ msleep(20);
#ifdef HX_RST_PIN_FUNC
- if (gpio_is_valid(pdata->gpio_reset))
- {
- error = gpio_direction_output(pdata->gpio_reset, 1);
- if (error)
- {
- E("unable to set direction for gpio [%d]\n",
- pdata->gpio_reset);
- goto err_gpio_irq_req;
- }
- }
+ if (gpio_is_valid(pdata->gpio_reset)) {
+ error = gpio_direction_output(pdata->gpio_reset, 1);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ goto err_gpio_irq_req;
+ }
+ }
#endif
- return 0;
+ return 0;
#ifdef HX_RST_PIN_FUNC
- err_gpio_irq_req:
+err_gpio_irq_req:
#endif
#ifdef HX_IRQ_PIN_FUNC
- if (gpio_is_valid(pdata->gpio_irq))
- gpio_free(pdata->gpio_irq);
- err_power_on:
+ if (gpio_is_valid(pdata->gpio_irq))
+ gpio_free(pdata->gpio_irq);
+err_power_on:
#endif
- himax_power_on(pdata, false);
- err_gpio_reset_req:
+ himax_power_on(pdata, false);
+err_gpio_reset_req:
#ifdef HX_RST_PIN_FUNC
- if (gpio_is_valid(pdata->gpio_reset))
- gpio_free(pdata->gpio_reset);
- err_regulator_on:
+ if (gpio_is_valid(pdata->gpio_reset))
+ gpio_free(pdata->gpio_reset);
+err_regulator_on:
#endif
- err_regulator_not_on:
+err_regulator_not_on:
- return error;
+ return error;
}
#else
-int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata)
+int himax_gpio_power_config(struct i2c_client *client,
+struct himax_i2c_platform_data *pdata)
{
- int error=0;
-
+ int error = 0;
+
#ifdef HX_RST_PIN_FUNC
- if (pdata->gpio_reset >= 0)
- {
- error = gpio_request(pdata->gpio_reset, "himax-reset");
- if (error < 0)
- {
- E("%s: request reset pin failed\n", __func__);
- return error;
- }
- error = gpio_direction_output(pdata->gpio_reset, 0);
- if (error)
- {
- E("unable to set direction for gpio [%d]\n",
- pdata->gpio_reset);
- return error;
- }
+ if (pdata->gpio_reset >= 0) {
+ error = gpio_request(pdata->gpio_reset, "himax-reset");
+ if (error < 0) {
+ E("%s: request reset pin failed\n", __func__);
+ return error;
}
+ error = gpio_direction_output(pdata->gpio_reset, 0);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ return error;
+ }
+ }
#endif
- if (pdata->gpio_3v3_en >= 0)
- {
- error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
- if (error < 0)
- {
- E("%s: request 3v3_en pin failed\n", __func__);
- return error;
- }
- gpio_direction_output(pdata->gpio_3v3_en, 1);
- I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en));
+ if (pdata->gpio_3v3_en >= 0) {
+ error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
+ if (error < 0) {
+ E("%s: request 3v3_en pin failed\n", __func__);
+ return error;
}
+ gpio_direction_output(pdata->gpio_3v3_en, 1);
+ I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en));
+ }
#ifdef HX_IRQ_PIN_FUNC
- if (gpio_is_valid(pdata->gpio_irq))
- {
- /* configure touchscreen irq gpio */
- error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
- if (error)
- {
- E("unable to request gpio [%d]\n",pdata->gpio_irq);
- return error;
- }
- error = gpio_direction_input(pdata->gpio_irq);
- if (error)
- {
- E("unable to set direction for gpio [%d]\n",pdata->gpio_irq);
- return error;
- }
- client->irq = gpio_to_irq(pdata->gpio_irq);
+ if (gpio_is_valid(pdata->gpio_irq)) {
+ /* configure touchscreen irq gpio */
+ error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
+ if (error) {
+ E("unable to request gpio [%d]\n", pdata->gpio_irq);
+ return error;
}
- else
- {
- E("irq gpio not provided\n");
+ error = gpio_direction_input(pdata->gpio_irq);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_irq);
return error;
}
+ client->irq = gpio_to_irq(pdata->gpio_irq);
+ } else {
+ E("irq gpio not provided\n");
+ return error;
+ }
#endif
- msleep(20);
-
+ msleep(20);
+
#ifdef HX_RST_PIN_FUNC
- if (pdata->gpio_reset >= 0)
- {
- error = gpio_direction_output(pdata->gpio_reset, 1);
- if (error)
- {
- E("unable to set direction for gpio [%d]\n",
- pdata->gpio_reset);
- return error;
- }
+ if (pdata->gpio_reset >= 0) {
+ error = gpio_direction_output(pdata->gpio_reset, 1);
+ if (error) {
+ E("unable to set direction for gpio [%d]\n",
+ pdata->gpio_reset);
+ return error;
}
- msleep(20);
-#endif
-
- return error;
}
+ msleep(20);
+#endif
+
+ return error;
+}
#endif
static void himax_ts_isr_func(struct himax_ts_data *ts)
@@ -595,34 +575,40 @@ irqreturn_t himax_ts_thread(int irq, void *ptr)
if (ts->debug_log_level & BIT(2)) {
getnstimeofday(&timeStart);
- usleep_range(5000, 7000);
- //I(" Irq start time = %ld.%06ld s\n",
- // timeStart.tv_sec, timeStart.tv_nsec/1000);
+ usleep_range(4999, 5000);
+ /*I(" Irq start time = %ld.%06ld s\n",
+ timeStart.tv_sec, timeStart.tv_nsec/1000);*/
}
#ifdef HX_SMART_WAKEUP
- if (atomic_read(&ts->suspend_mode)&&(!FAKE_POWER_KEY_SEND)&&(ts->SMWP_enable)&&(!diag_cmd)) {
- wake_lock_timeout(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
+ if (atomic_read(&ts->suspend_mode)
+ && (!FAKE_POWER_KEY_SEND)
+ && (ts->SMWP_enable)
+ && (!diag_cmd)) {
+ __pm_wakeup_event(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT);
msleep(200);
himax_wake_check_func();
return IRQ_HANDLED;
}
#endif
himax_ts_isr_func((struct himax_ts_data *)ptr);
- if(ts->debug_log_level & BIT(2)) {
- getnstimeofday(&timeEnd);
- timeDelta.tv_nsec = (timeEnd.tv_sec*1000000000+timeEnd.tv_nsec)
- -(timeStart.tv_sec*1000000000+timeStart.tv_nsec);
- //I("Irq finish time = %ld.%06ld s\n",
- // timeEnd.tv_sec, timeEnd.tv_nsec/1000);
- //I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000);
+ if (ts->debug_log_level & BIT(2)) {
+ getnstimeofday(&timeEnd);
+ timeDelta.tv_nsec
+ = (timeEnd.tv_sec * 1000000000 + timeEnd.tv_nsec)
+ - (timeStart.tv_sec * 1000000000 + timeStart.tv_nsec);
+ /*I("Irq finish time = %ld.%06ld s\n",
+ timeEnd.tv_sec, timeEnd.tv_nsec/1000);
+ I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000);*/
}
return IRQ_HANDLED;
}
static void himax_ts_work_func(struct work_struct *work)
{
- struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work);
+ struct himax_ts_data *ts =
+ container_of(work, struct himax_ts_data, work);
+
himax_ts_work(ts);
}
@@ -634,24 +620,26 @@ int himax_ts_register_interrupt(struct i2c_client *client)
int ret = 0;
ts->irq_enabled = 0;
- //Work functon
+ /*Work functon*/
if (client->irq) {/*INT mode*/
ts->use_irq = 1;
- if(ic_data->HX_INT_IS_EDGE)
- {
- I("%s edge triiger falling\n ",__func__);
- ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts);
- }
- else
- {
- I("%s level trigger low\n ",__func__);
- ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts);
+ if (ic_data->HX_INT_IS_EDGE) {
+ I("%s edge triiger falling\n ", __func__);
+ ret = request_threaded_irq(client->irq,
+ NULL, himax_ts_thread, IRQF_TRIGGER_FALLING
+ | IRQF_ONESHOT, client->name, ts);
+ } else {
+ I("%s level trigger low\n ", __func__);
+ ret = request_threaded_irq(client->irq,
+ NULL, himax_ts_thread, IRQF_TRIGGER_LOW
+ | IRQF_ONESHOT, client->name, ts);
}
if (ret == 0) {
ts->irq_enabled = 1;
irq_enable_count = 1;
tp_irq = client->irq;
- I("%s: irq enabled at qpio: %d\n", __func__, client->irq);
+ I("%s: irq enabled at qpio: %d\n",
+ __func__, client->irq);
#ifdef HX_SMART_WAKEUP
irq_set_irq_wake(client->irq, 1);
#endif
@@ -662,8 +650,8 @@ int himax_ts_register_interrupt(struct i2c_client *client)
} else {
I("%s: client->irq is empty, use polling mode.\n", __func__);
}
-
- if (!ts->use_irq) {/*if use polling mode need to disable HX_ESD_WORKAROUND function*/
+ /*if use polling mode need to disable HX_ESD_WORKAROUND function*/
+ if (!ts->use_irq) {
ts->himax_wq = create_singlethread_workqueue("himax_touch");
INIT_WORK(&ts->work, himax_ts_work_func);
@@ -680,7 +668,7 @@ static int himax_common_suspend(struct device *dev)
{
struct himax_ts_data *ts = dev_get_drvdata(dev);
- I("%s: enter \n", __func__);
+ I("%s: enter\n", __func__);
himax_chip_common_suspend(ts);
return 0;
@@ -690,7 +678,7 @@ static int himax_common_resume(struct device *dev)
{
struct himax_ts_data *ts = dev_get_drvdata(dev);
- I("%s: enter \n", __func__);
+ I("%s: enter\n", __func__);
himax_chip_common_resume(ts);
return 0;
@@ -702,23 +690,28 @@ int fb_notifier_callback(struct notifier_block *self,
{
struct fb_event *evdata = data;
int *blank;
- struct himax_ts_data *ts=
- container_of(self, struct himax_ts_data, fb_notif);
+ struct himax_ts_data *ts
+ = container_of(self, struct himax_ts_data, fb_notif);
+ int ERR = 1;
I(" %s\n", __func__);
- if (evdata && evdata->data && event == FB_EVENT_BLANK && ts &&
- ts->client) {
+ if (evdata && evdata->data && event
+ == FB_EVENT_BLANK && ts && ts->client) {
blank = evdata->data;
mutex_lock(&ts->fb_mutex);
switch (*blank) {
case FB_BLANK_UNBLANK:
if (!ts->probe_done) {
- himax_ts_init(ts);
- ts->probe_done = true;
- } else {
+ if (himax_ts_init(ts) == true) {
+ I("himax_ts_init return OK\n");
+ ts->probe_done = true;
+ } else {
+ I("himax_ts_init return Fail\n");
+ return -ERR;
+ }
+ } else
himax_common_resume(&ts->client->dev);
- }
break;
case FB_BLANK_POWERDOWN:
@@ -748,7 +741,7 @@ static const struct dev_pm_ops himax_common_pm_ops = {
};
#ifdef CONFIG_OF
-static const struct of_device_id himax_match_table[] = {
+static struct of_device_id himax_match_table[] = {
{.compatible = "himax,hxcommon" },
{},
};
@@ -770,16 +763,10 @@ static struct i2c_driver himax_common_driver = {
},
};
-static void __init himax_common_init_async(void *unused, async_cookie_t cookie)
-{
- I("%s:Enter \n", __func__);
- i2c_add_driver(&himax_common_driver);
-}
-
static int __init himax_common_init(void)
{
I("Himax common touch panel driver init\n");
- async_schedule(himax_common_init_async, NULL);
+ i2c_add_driver(&himax_common_driver);
return 0;
}
@@ -792,5 +779,5 @@ module_init(himax_common_init);
module_exit(himax_common_exit);
MODULE_DESCRIPTION("Himax_common driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/touchscreen/hxchipset/himax_platform.h b/drivers/input/touchscreen/hxchipset/himax_platform.h
index 1223685683aa..6871e53cd1f2 100644
--- a/drivers/input/touchscreen/hxchipset/himax_platform.h
+++ b/drivers/input/touchscreen/hxchipset/himax_platform.h
@@ -22,6 +22,7 @@
#include
#include
#include
+
#if defined(CONFIG_HMX_DB)
#include
#endif
@@ -31,15 +32,11 @@
#define HIMAX_I2C_RETRY_TIMES 10
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
-#define D(x...) pr_debug("[HXTP] " x)
-#define I(x...) pr_info("[HXTP] " x)
-#define W(x...) pr_warning("[HXTP][WARNING] " x)
-#define E(x...) pr_err("[HXTP][ERROR] " x)
-#define DIF(x...) \
-do {\
- if (debug_flag) \
- pr_debug("[HXTP][DEBUG] " x) \
-} while(0)
+#define D(x...) pr_info("[HXTP][DEBUG] " x)
+#define I(x...) pr_info("[HXTP][INFO] " x)
+#define W(x...) pr_info("[HXTP][WARNING] " x)
+#define E(x...) pr_info("[HXTP][ERROR] " x)
+#define DIF(x...) do { if (debug_flag) pr_info("[HXTP][DEBUG] " x) } while (0)
#else
#define D(x...)
#define I(x...)
@@ -53,24 +50,24 @@ do {\
#define HX_VTG_MIN_UV 2700000
#define HX_VTG_MAX_UV 3300000
#define HX_ACTIVE_LOAD_UA 15000
-#define HX_LPM_LOAD_UA 10
+#define HX_LPM_LOAD_UA 10
/* Digital voltage @1.8 V */
#define HX_VTG_DIG_MIN_UV 1800000
#define HX_VTG_DIG_MAX_UV 1800000
#define HX_ACTIVE_LOAD_DIG_UA 10000
-#define HX_LPM_LOAD_DIG_UA 10
+#define HX_LPM_LOAD_DIG_UA 10
#define HX_I2C_VTG_MIN_UV 1800000
#define HX_I2C_VTG_MAX_UV 1800000
-#define HX_I2C_LOAD_UA 10000
-#define HX_I2C_LPM_LOAD_UA 10
+#define HX_I2C_LOAD_UA 10000
+#define HX_I2C_LPM_LOAD_UA 10
#endif
-#define HIMAX_common_NAME "himax_tp"
+#define HIMAX_common_NAME "himax_tp"
#define HIMAX_I2C_ADDR 0x48
#define INPUT_DEV_NAME "himax-touchscreen"
-struct himax_i2c_platform_data {
+struct himax_i2c_platform_data {
int abs_x_min;
int abs_x_max;
int abs_x_fuzz;
@@ -108,28 +105,53 @@ struct himax_i2c_platform_data {
int irq_gpio;
u32 irq_gpio_flags;
- struct regulator *vcc_ana; //For Dragon Board
- struct regulator *vcc_dig; //For Dragon Board
- struct regulator *vcc_i2c; //For Dragon Board
-#endif
+ struct regulator *vcc_ana; /*For Dragon Board*/
+ struct regulator *vcc_dig; /*For Dragon Board*/
+ struct regulator *vcc_i2c; /*For Dragon Board*/
+#endif
};
extern int irq_enable_count;
-extern int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
-extern int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
-extern int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry);
-extern int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry);
-extern int i2c_himax_read_command(struct i2c_client *client, uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry);
-extern void himax_int_enable(int irqnum, int enable);
-extern int himax_ts_register_interrupt(struct i2c_client *client);
-extern void himax_rst_gpio_set(int pinnum, uint8_t value);
-extern uint8_t himax_int_gpio_read(int pinnum);
-
-extern int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata);
+int i2c_himax_read(struct i2c_client *client,
+ uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_write(struct i2c_client *client,
+ uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_write_command(struct i2c_client *client,
+ uint8_t command, uint8_t toRetry);
+
+int i2c_himax_master_write(struct i2c_client *client,
+ uint8_t *data, uint8_t length, uint8_t toRetry);
+
+int i2c_himax_read_command(struct i2c_client *client,
+ uint8_t length, uint8_t *data, uint8_t *readlength, uint8_t toRetry);
+
+void himax_int_enable(int irqnum, int enable);
+int himax_ts_register_interrupt(struct i2c_client *client);
+void himax_rst_gpio_set(int pinnum, uint8_t value);
+uint8_t himax_int_gpio_read(int pinnum);
+
+int himax_gpio_power_config(struct i2c_client *client,
+ struct himax_i2c_platform_data *pdata);
#if defined(CONFIG_FB)
-extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
+extern int fb_notifier_callback(struct notifier_block *self,
+ unsigned long event, void *data);
#endif
+extern struct himax_ts_data *private_ts;
+extern struct himax_ic_data *ic_data;
+extern void himax_ts_work(struct himax_ts_data *ts);
+extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
+extern int tp_rst_gpio;
+
+#ifdef HX_TP_PROC_DIAG
+extern uint8_t getDiagCommand(void);
+#endif
+
+int himax_parse_dt(struct himax_ts_data *ts,
+ struct himax_i2c_platform_data *pdata);
+int himax_ts_pinctrl_init(struct himax_ts_data *ts);
#endif
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index e4c43a17b333..8088c34336aa 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1655,13 +1655,7 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
} else
return -EINVAL;
case IIOCDBGVAR:
- if (arg) {
- if (copy_to_user(argp, &dev, sizeof(ulong)))
- return -EFAULT;
- return 0;
- } else
- return -EINVAL;
- break;
+ return -EINVAL;
default:
if ((cmd & IIOCDRVCTL) == IIOCDRVCTL)
cmd = ((cmd >> _IOC_NRSHIFT) & _IOC_NRMASK) & ISDN_DRVIOCTL_MASK;
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c
index 6e3fae202b11..fe19e5841bfc 100644
--- a/drivers/md/bcache/writeback.c
+++ b/drivers/md/bcache/writeback.c
@@ -462,8 +462,10 @@ static int bch_writeback_thread(void *arg)
* data on cache. BCACHE_DEV_DETACHING flag is set in
* bch_cached_dev_detach().
*/
- if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
+ if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) {
+ up_write(&dc->writeback_lock);
break;
+ }
}
up_write(&dc->writeback_lock);
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index 1e64e9c50d85..aeb9ee6082d9 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -324,7 +324,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
disk_super->version = cpu_to_le32(MAX_CACHE_VERSION);
memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
- disk_super->policy_hint_size = 0;
+ disk_super->policy_hint_size = cpu_to_le32(0);
__copy_sm_root(cmd, disk_super);
@@ -635,6 +635,7 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]);
disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]);
disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]);
+ disk_super->policy_hint_size = cpu_to_le32(cmd->policy_hint_size);
disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
diff --git a/drivers/md/dm-req-crypt.c b/drivers/md/dm-req-crypt.c
index 05b3c3138d75..196952d49b40 100644
--- a/drivers/md/dm-req-crypt.c
+++ b/drivers/md/dm-req-crypt.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2016, 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
* only version 2 as published by the Free Software Foundation.
@@ -42,7 +42,7 @@
#define MAX_ENCRYPTION_BUFFERS 1
#define MIN_IOS 256
#define MIN_POOL_PAGES 32
-#define KEY_SIZE_XTS 32
+#define KEY_SIZE_XTS 64
#define AES_XTS_IV_LEN 16
#define MAX_MSM_ICE_KEY_LUT_SIZE 32
#define SECTOR_SIZE 512
@@ -457,22 +457,22 @@ static void req_cryptd_crypt_write_convert(struct req_dm_crypt_io *io)
struct bio *bio_src = NULL;
unsigned int total_sg_len_req_in = 0, total_sg_len_req_out = 0,
total_bytes_in_req = 0, error = DM_MAPIO_REMAPPED, rc = 0;
- struct req_iterator iter;
- struct req_iterator iter1;
struct ablkcipher_request *req = NULL;
struct req_crypt_result result;
- struct bio_vec bvec;
struct scatterlist *req_sg_in = NULL;
struct scatterlist *req_sg_out = NULL;
int copy_bio_sector_to_req = 0;
gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
struct page *page = NULL;
u8 IV[AES_XTS_IV_LEN];
- int remaining_size = 0, err = 0;
+ int size = 0, err = 0;
struct crypto_engine_entry engine;
unsigned int engine_list_total = 0;
struct crypto_engine_entry *curr_engine_list = NULL;
unsigned int *engine_cursor = NULL;
+ unsigned int i;
+ struct bio_vec *_bvec;
+ struct bio *_bio;
if (io) {
@@ -582,27 +582,31 @@ static void req_cryptd_crypt_write_convert(struct req_dm_crypt_io *io)
goto ablkcipher_req_alloc_failure;
}
- rq_for_each_segment(bvec, clone, iter) {
- if (bvec.bv_len > remaining_size) {
- page = NULL;
- while (page == NULL) {
- page = mempool_alloc(req_page_pool, gfp_mask);
- if (!page) {
- DMERR("%s Crypt page alloc failed",
+ __rq_for_each_bio(_bio, clone) {
+ bio_for_each_segment_all(_bvec, _bio, i) {
+ if (_bvec->bv_len > size) {
+ page = NULL;
+ while (page == NULL) {
+ page = mempool_alloc(req_page_pool,
+ gfp_mask);
+ if (!page) {
+ DMERR("%s Page alloc failed",
__func__);
- congestion_wait(BLK_RW_ASYNC, HZ/100);
+ congestion_wait(BLK_RW_ASYNC,
+ HZ/100);
+ }
}
- }
- bvec.bv_page = page;
- bvec.bv_offset = 0;
- remaining_size = PAGE_SIZE - bvec.bv_len;
- if (remaining_size < 0)
- BUG();
- } else {
- bvec.bv_page = page;
- bvec.bv_offset = PAGE_SIZE - remaining_size;
- remaining_size = remaining_size - bvec.bv_len;
+ _bvec->bv_page = page;
+ _bvec->bv_offset = 0;
+ size = PAGE_SIZE - _bvec->bv_len;
+ if (size < 0)
+ BUG();
+ } else {
+ _bvec->bv_page = page;
+ _bvec->bv_offset = PAGE_SIZE - size;
+ size = size - _bvec->bv_len;
+ }
}
}
@@ -664,12 +668,16 @@ static void req_cryptd_crypt_write_convert(struct req_dm_crypt_io *io)
ablkcipher_request_free(req);
if (error == DM_REQ_CRYPT_ERROR_AFTER_PAGE_MALLOC) {
- rq_for_each_segment(bvec, clone, iter1) {
- if (bvec.bv_offset == 0) {
- mempool_free(bvec.bv_page, req_page_pool);
- bvec.bv_page = NULL;
- } else
- bvec.bv_page = NULL;
+ __rq_for_each_bio(_bio, clone) {
+ bio_for_each_segment_all(_bvec, _bio, i) {
+ if (_bvec->bv_offset == 0) {
+ mempool_free(_bvec->bv_page,
+ req_page_pool);
+ _bvec->bv_page = NULL;
+ } else {
+ _bvec->bv_page = NULL;
+ }
+ }
}
}
@@ -866,8 +874,9 @@ static int req_crypt_endio(struct dm_target *ti, struct request *clone,
int error, union map_info *map_context)
{
int err = 0;
- struct req_iterator iter1;
- struct bio_vec bvec;
+ struct bio_vec *_bvec;
+ struct bio *_bio;
+ unsigned int i;
struct req_dm_crypt_io *req_io = map_context->ptr;
/* If it is for ICE, free up req_io and return */
@@ -878,12 +887,17 @@ static int req_crypt_endio(struct dm_target *ti, struct request *clone,
}
if (rq_data_dir(clone) == WRITE) {
- rq_for_each_segment(bvec, clone, iter1) {
- if (req_io->should_encrypt && bvec.bv_offset == 0) {
- mempool_free(bvec.bv_page, req_page_pool);
- bvec.bv_page = NULL;
- } else
- bvec.bv_page = NULL;
+ __rq_for_each_bio(_bio, clone) {
+ bio_for_each_segment_all(_bvec, _bio, i) {
+ if (req_io->should_encrypt &&
+ _bvec->bv_offset == 0) {
+ mempool_free(_bvec->bv_page,
+ req_page_pool);
+ _bvec->bv_page = NULL;
+ } else {
+ _bvec->bv_page = NULL;
+ }
+ }
}
mempool_free(req_io, req_io_pool);
goto submit_request;
@@ -1297,11 +1311,11 @@ static int req_crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
/*
- * If underlying device supports flush/discard, mapped target
+ * If underlying device supports flush, mapped target
* should also allow it
*/
ti->num_flush_bios = 1;
- ti->num_discard_bios = 1;
+ /* TODO: Discard support */
err = 0;
DMINFO("%s: Mapping block_device %s to dm-req-crypt ok!\n",
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 245731994cee..5558c8e77ecb 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1427,13 +1427,13 @@ static void clone_bio(struct dm_target_io *tio, struct bio *bio,
}
static struct dm_target_io *alloc_tio(struct clone_info *ci,
- struct dm_target *ti,
+ struct dm_target *ti, int nr_iovecs,
unsigned target_bio_nr)
{
struct dm_target_io *tio;
struct bio *clone;
- clone = bio_alloc_bioset(GFP_NOIO, 0, ci->md->bs);
+ clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, ci->md->bs);
tio = container_of(clone, struct dm_target_io, clone);
tio->io = ci->io;
@@ -1447,12 +1447,18 @@ static void __clone_and_map_simple_bio(struct clone_info *ci,
struct dm_target *ti,
unsigned target_bio_nr, unsigned *len)
{
- struct dm_target_io *tio = alloc_tio(ci, ti, target_bio_nr);
+ struct dm_target_io *tio = alloc_tio(ci, ti, ci->bio->bi_max_vecs,
+ target_bio_nr);
struct bio *clone = &tio->clone;
tio->len_ptr = len;
- __bio_clone_fast(clone, ci->bio);
+ /*
+ * Discard requests require the bio's inline iovecs be initialized.
+ * ci->bio->bi_max_vecs is BIO_INLINE_VECS anyway, for both flush
+ * and discard, so no need for concern about wasted bvec allocations.
+ */
+ __bio_clone_fast(clone, ci->bio);
if (len)
bio_setup_sector(clone, ci->sector, *len);
@@ -1495,7 +1501,7 @@ static void __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti
num_target_bios = ti->num_write_bios(ti, bio);
for (target_bio_nr = 0; target_bio_nr < num_target_bios; target_bio_nr++) {
- tio = alloc_tio(ci, ti, target_bio_nr);
+ tio = alloc_tio(ci, ti, 0, target_bio_nr);
tio->len_ptr = len;
clone_bio(tio, bio, sector, *len);
__map_bio(tio);
@@ -3095,7 +3101,7 @@ struct dm_md_mempools *dm_alloc_md_mempools(unsigned type, unsigned integrity, u
if (!pools->io_pool)
goto out;
- pools->bs = bioset_create_nobvec(pool_size, front_pad);
+ pools->bs = bioset_create(pool_size, front_pad);
if (!pools->bs)
goto out;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index f88f912f0296..ba201db6afce 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5676,6 +5676,9 @@ static int hot_remove_disk(struct mddev *mddev, dev_t dev)
char b[BDEVNAME_SIZE];
struct md_rdev *rdev;
+ if (!mddev->pers)
+ return -ENODEV;
+
rdev = find_rdev(mddev, dev);
if (!rdev)
return -ENXIO;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index b19149e45154..bd26567248b3 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -3770,6 +3770,13 @@ static int run(struct mddev *mddev)
disk->rdev->saved_raid_disk < 0)
conf->fullsync = 1;
}
+
+ if (disk->replacement &&
+ !test_bit(In_sync, &disk->replacement->flags) &&
+ disk->replacement->saved_raid_disk < 0) {
+ conf->fullsync = 1;
+ }
+
disk->recovery_disabled = mddev->recovery_disabled - 1;
}
diff --git a/drivers/media/common/siano/smsendian.c b/drivers/media/common/siano/smsendian.c
index bfe831c10b1c..b95a631f23f9 100644
--- a/drivers/media/common/siano/smsendian.c
+++ b/drivers/media/common/siano/smsendian.c
@@ -35,7 +35,7 @@ void smsendian_handle_tx_message(void *buffer)
switch (msg->x_msg_header.msg_type) {
case MSG_SMS_DATA_DOWNLOAD_REQ:
{
- msg->msg_data[0] = le32_to_cpu(msg->msg_data[0]);
+ msg->msg_data[0] = le32_to_cpu((__force __le32)(msg->msg_data[0]));
break;
}
@@ -44,7 +44,7 @@ void smsendian_handle_tx_message(void *buffer)
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msg_words; i++)
- msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
+ msg->msg_data[i] = le32_to_cpu((__force __le32)msg->msg_data[i]);
break;
}
@@ -64,7 +64,7 @@ void smsendian_handle_rx_message(void *buffer)
{
struct sms_version_res *ver =
(struct sms_version_res *) msg;
- ver->chip_model = le16_to_cpu(ver->chip_model);
+ ver->chip_model = le16_to_cpu((__force __le16)ver->chip_model);
break;
}
@@ -81,7 +81,7 @@ void smsendian_handle_rx_message(void *buffer)
sizeof(struct sms_msg_hdr))/4;
for (i = 0; i < msg_words; i++)
- msg->msg_data[i] = le32_to_cpu(msg->msg_data[i]);
+ msg->msg_data[i] = le32_to_cpu((__force __le32)msg->msg_data[i]);
break;
}
@@ -95,9 +95,9 @@ void smsendian_handle_message_header(void *msg)
#ifdef __BIG_ENDIAN
struct sms_msg_hdr *phdr = (struct sms_msg_hdr *)msg;
- phdr->msg_type = le16_to_cpu(phdr->msg_type);
- phdr->msg_length = le16_to_cpu(phdr->msg_length);
- phdr->msg_flags = le16_to_cpu(phdr->msg_flags);
+ phdr->msg_type = le16_to_cpu((__force __le16)phdr->msg_type);
+ phdr->msg_length = le16_to_cpu((__force __le16)phdr->msg_length);
+ phdr->msg_flags = le16_to_cpu((__force __le16)phdr->msg_flags);
#endif /* __BIG_ENDIAN */
}
EXPORT_SYMBOL_GPL(smsendian_handle_message_header);
diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c
index b49254e4ea0a..6a2f204b902f 100644
--- a/drivers/media/i2c/smiapp/smiapp-core.c
+++ b/drivers/media/i2c/smiapp/smiapp-core.c
@@ -939,7 +939,7 @@ static int smiapp_read_nvm(struct smiapp_sensor *sensor,
if (rval)
goto out;
- for (i = 0; i < 1000; i++) {
+ for (i = 1000; i > 0; i--) {
rval = smiapp_read(
sensor,
SMIAPP_REG_U8_DATA_TRANSFER_IF_1_STATUS, &s);
@@ -950,11 +950,10 @@ static int smiapp_read_nvm(struct smiapp_sensor *sensor,
if (s & SMIAPP_DATA_TRANSFER_IF_1_STATUS_RD_READY)
break;
- if (--i == 0) {
- rval = -ETIMEDOUT;
- goto out;
- }
-
+ }
+ if (!i) {
+ rval = -ETIMEDOUT;
+ goto out;
}
for (i = 0; i < SMIAPP_NVM_PAGE_SIZE; i++) {
diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c
index 86763203d61d..021c46da794d 100644
--- a/drivers/media/pci/saa7164/saa7164-fw.c
+++ b/drivers/media/pci/saa7164/saa7164-fw.c
@@ -430,7 +430,8 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev)
__func__, fw->size);
if (fw->size != fwlength) {
- printk(KERN_ERR "xc5000: firmware incorrect size\n");
+ printk(KERN_ERR "saa7164: firmware incorrect size %zu != %u\n",
+ fw->size, fwlength);
ret = -ENOMEM;
goto out;
}
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
index 437af72a6a55..76acbab8aefa 100644
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_dev.c
@@ -32,6 +32,8 @@
#define MSM_JPEG_NAME "jpeg"
#define DEV_NAME_LEN 10
+static char devname[DEV_NAME_LEN];
+
static int msm_jpeg_open(struct inode *inode, struct file *filp)
{
int rc = 0;
@@ -185,7 +187,6 @@ static int msm_jpeg_init_dev(struct platform_device *pdev)
struct msm_jpeg_device *msm_jpeg_device_p;
const struct of_device_id *device_id;
const struct msm_jpeg_priv_data *priv_data;
- char devname[DEV_NAME_LEN];
msm_jpeg_device_p = kzalloc(sizeof(struct msm_jpeg_device), GFP_ATOMIC);
if (!msm_jpeg_device_p) {
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index 86b7b1b6f6c0..579f032949a1 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -22,6 +22,7 @@
#define MSM_VDEC_DVC_NAME "msm_vdec_8974"
#define MIN_NUM_OUTPUT_BUFFERS 4
#define MIN_NUM_OUTPUT_BUFFERS_VP9 6
+#define MIN_NUM_OUTPUT_BUFFERS_HEVC 5
#define MIN_NUM_CAPTURE_BUFFERS 6
#define MIN_NUM_THUMBNAIL_MODE_CAPTURE_BUFFERS 1
#define MAX_NUM_OUTPUT_BUFFERS VB2_MAX_FRAME
@@ -1494,6 +1495,10 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
V4L2_PIX_FMT_VP9 &&
*num_buffers < MIN_NUM_OUTPUT_BUFFERS_VP9)
*num_buffers = MIN_NUM_OUTPUT_BUFFERS_VP9;
+ else if (inst->fmts[OUTPUT_PORT].fourcc ==
+ V4L2_PIX_FMT_HEVC &&
+ *num_buffers < MIN_NUM_OUTPUT_BUFFERS_HEVC)
+ *num_buffers = MIN_NUM_OUTPUT_BUFFERS_HEVC;
for (i = 0; i < *num_planes; i++) {
sizes[i] = get_frame_size(inst,
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index e5e7449a1ebf..d31ed91f66cf 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -2449,7 +2449,6 @@ static int msm_comm_session_abort(struct msm_vidc_inst *inst)
}
hdev = inst->core->device;
abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE);
- init_completion(&inst->completions[abort_completion]);
rc = call_hfi_op(hdev, session_abort, (void *)inst->session);
if (rc) {
@@ -2608,8 +2607,6 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst)
__func__);
}
- init_completion(&core->completions
- [SYS_MSG_INDEX(HAL_SYS_INIT_DONE)]);
rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data);
if (rc) {
dprintk(VIDC_ERR, "Failed to init core, id = %d\n",
@@ -2713,8 +2710,6 @@ static int msm_comm_session_init(int flipped_state,
dprintk(VIDC_ERR, "Invalid session\n");
return -EINVAL;
}
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_INIT_DONE)]);
rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data,
inst, get_hal_domain(inst->session_type),
@@ -2852,8 +2847,6 @@ static int msm_vidc_start(int flipped_state, struct msm_vidc_inst *inst)
inst, inst->state);
goto exit;
}
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_START_DONE)]);
rc = call_hfi_op(hdev, session_start, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -2883,8 +2876,6 @@ static int msm_vidc_stop(int flipped_state, struct msm_vidc_inst *inst)
goto exit;
}
dprintk(VIDC_DBG, "Send Stop to hal\n");
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_STOP_DONE)]);
rc = call_hfi_op(hdev, session_stop, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR, "Failed to send stop\n");
@@ -2914,8 +2905,6 @@ static int msm_vidc_release_res(int flipped_state, struct msm_vidc_inst *inst)
}
dprintk(VIDC_DBG,
"Send release res to hal\n");
- init_completion(&inst->completions[
- SESSION_MSG_INDEX(HAL_SESSION_RELEASE_RESOURCE_DONE)]);
rc = call_hfi_op(hdev, session_release_res, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -2946,8 +2935,6 @@ static int msm_comm_session_close(int flipped_state,
}
dprintk(VIDC_DBG,
"Send session close to hal\n");
- init_completion(
- &inst->completions[SESSION_MSG_INDEX(HAL_SESSION_END_DONE)]);
rc = call_hfi_op(hdev, session_end, (void *) inst->session);
if (rc) {
dprintk(VIDC_ERR,
@@ -3987,8 +3974,6 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
}
mutex_unlock(&inst->sync_lock);
- init_completion(&inst->completions[
- SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO)]);
switch (ptype) {
case HAL_PARAM_PROFILE_LEVEL_CURRENT:
case HAL_CONFIG_VDEC_ENTROPY:
@@ -4212,8 +4197,6 @@ int msm_comm_release_scratch_buffers(struct msm_vidc_inst *inst,
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID) {
buffer_info.response_required = true;
- init_completion(&inst->completions[SESSION_MSG_INDEX
- (HAL_SESSION_RELEASE_BUFFER_DONE)]);
rc = call_hfi_op(hdev, session_release_buffers,
(void *)inst->session, &buffer_info);
if (rc) {
@@ -4284,9 +4267,6 @@ int msm_comm_release_persist_buffers(struct msm_vidc_inst *inst)
if (inst->state != MSM_VIDC_CORE_INVALID &&
core->state != VIDC_CORE_INVALID) {
buffer_info.response_required = true;
- init_completion(
- &inst->completions[SESSION_MSG_INDEX
- (HAL_SESSION_RELEASE_BUFFER_DONE)]);
rc = call_hfi_op(hdev, session_release_buffers,
(void *)inst->session, &buffer_info);
if (rc) {
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index 2346364fe959..fb4ede7a287b 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -937,8 +937,6 @@ static int __core_set_resource(struct venus_hfi_device *device,
return rc;
}
-static DECLARE_COMPLETION(release_resources_done);
-
static int __alloc_imem(struct venus_hfi_device *device, unsigned long size)
{
struct imem *imem = NULL;
@@ -2158,8 +2156,6 @@ static int venus_hfi_core_init(void *device)
dev = device;
mutex_lock(&dev->lock);
- init_completion(&release_resources_done);
-
rc = __load_fw(dev);
if (rc) {
dprintk(VIDC_ERR, "Failed to load Venus FW\n");
@@ -3461,7 +3457,6 @@ static int __response_handler(struct venus_hfi_device *device)
break;
case HAL_SYS_RELEASE_RESOURCE_DONE:
dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
- complete(&release_resources_done);
break;
case HAL_SYS_INIT_DONE:
dprintk(VIDC_DBG, "Received SYS_INIT_DONE\n");
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index 233eccc5c33e..3e91109b205d 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -2117,6 +2117,7 @@ static int isp_initialize_modules(struct isp_device *isp)
static void isp_detach_iommu(struct isp_device *isp)
{
+ arm_iommu_detach_device(isp->dev);
arm_iommu_release_mapping(isp->mapping);
isp->mapping = NULL;
iommu_group_remove_device(isp->dev);
@@ -2150,8 +2151,7 @@ static int isp_attach_iommu(struct isp_device *isp)
mapping = arm_iommu_create_mapping(&platform_bus_type, SZ_1G, SZ_2G);
if (IS_ERR(mapping)) {
dev_err(isp->dev, "failed to create ARM IOMMU mapping\n");
- ret = PTR_ERR(mapping);
- goto error;
+ return PTR_ERR(mapping);
}
isp->mapping = mapping;
@@ -2166,7 +2166,8 @@ static int isp_attach_iommu(struct isp_device *isp)
return 0;
error:
- isp_detach_iommu(isp);
+ arm_iommu_release_mapping(isp->mapping);
+ isp->mapping = NULL;
return ret;
}
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c
index 2a497c80c77f..80261e556367 100644
--- a/drivers/media/radio/si470x/radio-si470x-i2c.c
+++ b/drivers/media/radio/si470x/radio-si470x-i2c.c
@@ -96,7 +96,7 @@ MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
*/
int si470x_get_register(struct si470x_device *radio, int regnr)
{
- u16 buf[READ_REG_NUM];
+ __be16 buf[READ_REG_NUM];
struct i2c_msg msgs[1] = {
{
.addr = radio->client->addr,
@@ -121,7 +121,7 @@ int si470x_get_register(struct si470x_device *radio, int regnr)
int si470x_set_register(struct si470x_device *radio, int regnr)
{
int i;
- u16 buf[WRITE_REG_NUM];
+ __be16 buf[WRITE_REG_NUM];
struct i2c_msg msgs[1] = {
{
.addr = radio->client->addr,
@@ -151,7 +151,7 @@ int si470x_set_register(struct si470x_device *radio, int regnr)
static int si470x_get_all_registers(struct si470x_device *radio)
{
int i;
- u16 buf[READ_REG_NUM];
+ __be16 buf[READ_REG_NUM];
struct i2c_msg msgs[1] = {
{
.addr = radio->client->addr,
diff --git a/drivers/mfd/wcd9xxx-core.c b/drivers/mfd/wcd9xxx-core.c
index de1b1ba28f83..c8c5efd3c4b9 100644
--- a/drivers/mfd/wcd9xxx-core.c
+++ b/drivers/mfd/wcd9xxx-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -2881,6 +2881,8 @@ static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev)
else
pdata->cdc_variant = WCD9XXX;
}
+ pdata->wcd9xxx_mic_tristate = of_property_read_bool(dev->of_node,
+ "qcom,wcd9xxx-mic-tristate");
return pdata;
err:
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 80ed8a3b81b0..8e7d82ce1eb9 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -643,6 +643,13 @@ config MEMORY_STATE_TIME
help
Memory time statistics exported to /sys/kernel/memory_state_time
+
+config FORCE_FAST_CHARGE
+ bool "Force faster charge rate for USB"
+ default n
+ help
+ This allows users to override default charge rate for USB
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2ebaa0c98532..2b7ca8226ae7 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -84,3 +84,4 @@ obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.o
obj-$(CONFIG_APDS9930) += apds993x.o
obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o
obj-$(CONFIG_MEMORY_STATE_TIME) += memory_state_time.o
+obj-$(CONFIG_FORCE_FAST_CHARGE) += fastchg.o
diff --git a/drivers/misc/fastchg.c b/drivers/misc/fastchg.c
new file mode 100644
index 000000000000..a00d425bb57d
--- /dev/null
+++ b/drivers/misc/fastchg.c
@@ -0,0 +1,102 @@
+/*
+ * Author: Chad Froebel
+ *
+ * Port to Thulium: engstk
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+/*
+ * Possible values for "force_fast_charge" are :
+ *
+ * 0 - Disabled (default)
+ * 1 - Force faster charge
+*/
+
+#include
+#include
+#include
+#include
+
+int force_fast_charge = 0;
+
+static int __init get_fastcharge_opt(char *ffc)
+{
+ if (strcmp(ffc, "0") == 0) {
+ force_fast_charge = 0;
+ } else if (strcmp(ffc, "1") == 0) {
+ force_fast_charge = 1;
+ } else {
+ force_fast_charge = 0;
+ }
+ return 1;
+}
+
+__setup("ffc=", get_fastcharge_opt);
+
+static ssize_t force_fast_charge_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+ size_t count = 0;
+ count += sprintf(buf, "%d\n", force_fast_charge);
+ return count;
+}
+
+static ssize_t force_fast_charge_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
+{
+ sscanf(buf, "%d ", &force_fast_charge);
+ if (force_fast_charge < 0 || force_fast_charge > 1)
+ force_fast_charge = 0;
+
+ return count;
+}
+
+static struct kobj_attribute force_fast_charge_attribute =
+__ATTR(force_fast_charge, 0664, force_fast_charge_show, force_fast_charge_store);
+
+static struct attribute *force_fast_charge_attrs[] = {
+&force_fast_charge_attribute.attr,
+NULL,
+};
+
+static struct attribute_group force_fast_charge_attr_group = {
+.attrs = force_fast_charge_attrs,
+};
+
+/* Initialize fast charge sysfs folder */
+static struct kobject *force_fast_charge_kobj;
+
+int force_fast_charge_init(void)
+{
+ int force_fast_charge_retval;
+
+ force_fast_charge_kobj = kobject_create_and_add("fast_charge", kernel_kobj);
+ if (!force_fast_charge_kobj) {
+ return -ENOMEM;
+ }
+
+ force_fast_charge_retval = sysfs_create_group(force_fast_charge_kobj, &force_fast_charge_attr_group);
+
+ if (force_fast_charge_retval)
+ kobject_put(force_fast_charge_kobj);
+
+ if (force_fast_charge_retval)
+ kobject_put(force_fast_charge_kobj);
+
+ return (force_fast_charge_retval);
+}
+
+void force_fast_charge_exit(void)
+{
+ kobject_put(force_fast_charge_kobj);
+}
+
+module_init(force_fast_charge_init);
+module_exit(force_fast_charge_exit);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index f2955be61899..1fca674d3ed9 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -8648,6 +8648,7 @@ static int qseecom_probe(struct platform_device *pdev)
static int qseecom_remove(struct platform_device *pdev)
{
struct qseecom_registered_kclient_list *kclient = NULL;
+ struct qseecom_registered_kclient_list *kclient_tmp = NULL;
unsigned long flags = 0;
int ret = 0;
int i;
@@ -8657,10 +8658,8 @@ static int qseecom_remove(struct platform_device *pdev)
atomic_set(&qseecom.qseecom_state, QSEECOM_STATE_NOT_READY);
spin_lock_irqsave(&qseecom.registered_kclient_list_lock, flags);
- list_for_each_entry(kclient, &qseecom.registered_kclient_list_head,
- list) {
- if (!kclient)
- goto exit_irqrestore;
+ list_for_each_entry_safe(kclient, kclient_tmp,
+ &qseecom.registered_kclient_list_head, list) {
/* Break the loop if client handle is NULL */
if (!kclient->handle)
@@ -8684,7 +8683,7 @@ static int qseecom_remove(struct platform_device *pdev)
kzfree(kclient->handle);
exit_free_kclient:
kzfree(kclient);
-exit_irqrestore:
+
spin_unlock_irqrestore(&qseecom.registered_kclient_list_lock, flags);
if (qseecom.qseos_version > QSEEE_VERSION_00)
diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c
index 44725296f72a..655a387eb9ad 100644
--- a/drivers/net/can/mscan/mpc5xxx_can.c
+++ b/drivers/net/can/mscan/mpc5xxx_can.c
@@ -86,6 +86,11 @@ static u32 mpc52xx_can_get_clock(struct platform_device *ofdev,
return 0;
}
cdm = of_iomap(np_cdm, 0);
+ if (!cdm) {
+ of_node_put(np_cdm);
+ dev_err(&ofdev->dev, "can't map clock node!\n");
+ return 0;
+ }
if (in_8(&cdm->ipb_clk_sel) & 0x1)
freq *= 2;
diff --git a/drivers/net/can/spi/k61.c b/drivers/net/can/spi/k61.c
index 4668d40a1612..6bb9204dfc2f 100644
--- a/drivers/net/can/spi/k61.c
+++ b/drivers/net/can/spi/k61.c
@@ -60,6 +60,7 @@ struct k61_can {
int cmd_result;
int bits_per_word;
int reset_delay_msec;
+ s64 time_diff;
};
struct k61_netdev_privdata {
@@ -97,6 +98,9 @@ struct spi_miso { /* TLV for MISO line */
#define CMD_CAN_DATA_BUFF_REMOVE 0x88
#define CMD_CAN_RELEASE_BUFFER 0x89
#define CMD_CAN_DATA_BUFF_REMOVE_ALL 0x8A
+#define CMD_UPDATE_TIME_INFO 0x9D
+#define CMD_SUSPEND_EVENT 0x9E
+#define CMD_RESUME_EVENT 0x9F
#define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0)
#define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1)
@@ -112,7 +116,7 @@ struct can_fw_resp {
} __packed;
struct can_write_req {
- u32 ts;
+ u64 ts;
u32 mid;
u8 dlc;
u8 data[];
@@ -123,7 +127,7 @@ struct can_write_resp {
} __packed;
struct can_receive_frame {
- u32 ts;
+ u64 ts;
u32 mid;
u8 dlc;
u8 data[];
@@ -136,6 +140,10 @@ struct can_add_filter_req {
u8 type;
} __packed;
+struct can_time_info {
+ u64 time;
+} __packed;
+
static struct can_bittiming_const k61_bittiming_const = {
.name = "k61",
.tseg1_min = 4,
@@ -199,8 +207,7 @@ static void k61_receive_frame(struct k61_can *priv_data,
struct can_frame *cf;
struct sk_buff *skb;
struct skb_shared_hwtstamps *skt;
- struct timeval tv;
- static int msec;
+ ktime_t nsec;
struct net_device *netdev;
int i;
@@ -217,7 +224,7 @@ static void k61_receive_frame(struct k61_can *priv_data,
return;
}
- LOGDI("rcv frame %d %x %d %x %x %x %x %x %x %x %x\n",
+ LOGDI("rcv frame %llu %x %d %x %x %x %x %x %x %x %x\n",
frame->ts, frame->mid, frame->dlc, frame->data[0],
frame->data[1], frame->data[2], frame->data[3], frame->data[4],
frame->data[5], frame->data[6], frame->data[7]);
@@ -227,13 +234,11 @@ static void k61_receive_frame(struct k61_can *priv_data,
for (i = 0; i < cf->can_dlc; i++)
cf->data[i] = frame->data[i];
- msec = le32_to_cpu(frame->ts);
- tv.tv_sec = msec / 1000;
- tv.tv_usec = (msec - tv.tv_sec * 1000) * 1000;
+ nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff);
skt = skb_hwtstamps(skb);
- skt->hwtstamp = timeval_to_ktime(tv);
+ skt->hwtstamp = nsec;
LOGDI(" hwtstamp %lld\n", ktime_to_ms(skt->hwtstamp));
- skb->tstamp = timeval_to_ktime(tv);
+ skb->tstamp = nsec;
netif_rx(skb);
netdev->stats.rx_packets++;
netdev->stats.rx_bytes += cf->can_dlc;
@@ -243,6 +248,9 @@ static void k61_process_response(struct k61_can *priv_data,
struct spi_miso *resp)
{
int ret = 0;
+ u64 mstime;
+ ktime_t ktime_now;
+
LOGDI("<%x %2d [%d]\n", resp->cmd, resp->len, resp->seq);
if (resp->cmd == CMD_CAN_RECEIVE_FRAME) {
struct can_receive_frame *frame =
@@ -253,6 +261,12 @@ static void k61_process_response(struct k61_can *priv_data,
dev_info(&priv_data->spidev->dev, "fw %d.%d.%d",
fw_resp->maj, fw_resp->min, fw_resp->ver);
+ } else if (resp->cmd == CMD_UPDATE_TIME_INFO) {
+ struct can_time_info *time_data =
+ (struct can_time_info *)resp->data;
+ ktime_now = ktime_get_boottime();
+ mstime = ktime_to_ms(ktime_now);
+ priv_data->time_diff = mstime - (le64_to_cpu(time_data->time));
}
if (resp->cmd == priv_data->wait_cmd) {
@@ -377,6 +391,30 @@ static int k61_query_firmware_version(struct k61_can *priv_data)
return ret;
}
+static int k61_notify_power_events(struct k61_can *priv_data, u8 event_type)
+{
+ char *tx_buf, *rx_buf;
+ int ret;
+ struct spi_mosi *req;
+
+ mutex_lock(&priv_data->spi_lock);
+ tx_buf = priv_data->tx_buf;
+ rx_buf = priv_data->rx_buf;
+ memset(tx_buf, 0, XFER_BUFFER_SIZE);
+ memset(rx_buf, 0, XFER_BUFFER_SIZE);
+ priv_data->xfer_length = XFER_BUFFER_SIZE;
+
+ req = (struct spi_mosi *)tx_buf;
+ req->cmd = event_type;
+ req->len = 0;
+ req->seq = atomic_inc_return(&priv_data->msg_seq);
+
+ ret = k61_do_spi_transaction(priv_data);
+ mutex_unlock(&priv_data->spi_lock);
+
+ return ret;
+}
+
static int k61_can_write(struct k61_can *priv_data, struct can_frame *cf)
{
char *tx_buf, *rx_buf;
@@ -813,6 +851,7 @@ static int k61_probe(struct spi_device *spi)
int err, retry = 0, query_err = -1;
struct k61_can *priv_data;
struct device *dev;
+ u32 irq_type;
dev = &spi->dev;
dev_dbg(dev, "k61_probe");
@@ -869,8 +908,11 @@ static int k61_probe(struct spi_device *spi)
goto unregister_candev;
}
+ irq_type = irq_get_trigger_type(spi->irq);
+ if (irq_type == IRQ_TYPE_NONE)
+ irq_type = IRQ_TYPE_EDGE_FALLING;
err = request_threaded_irq(spi->irq, NULL, k61_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ irq_type | IRQF_ONESHOT,
"k61", priv_data);
if (err) {
dev_err(dev, "Failed to request irq: %d", err);
@@ -924,7 +966,10 @@ static const struct of_device_id k61_match_table[] = {
static int k61_suspend(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
+ struct k61_can *priv_data = spi_get_drvdata(spi);
+ u8 power_event = CMD_SUSPEND_EVENT;
+ k61_notify_power_events(priv_data, power_event);
enable_irq_wake(spi->irq);
return 0;
}
@@ -933,9 +978,10 @@ static int k61_resume(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
struct k61_can *priv_data = spi_get_drvdata(spi);
+ u8 power_event = CMD_RESUME_EVENT;
disable_irq_wake(spi->irq);
- k61_rx_message(priv_data);
+ k61_notify_power_events(priv_data, power_event);
return 0;
}
diff --git a/drivers/net/can/spi/qti-can.c b/drivers/net/can/spi/qti-can.c
index 253e341dbb58..27bd2fe2edff 100644
--- a/drivers/net/can/spi/qti-can.c
+++ b/drivers/net/can/spi/qti-can.c
@@ -70,6 +70,7 @@ struct qti_can {
bool can_fw_cmd_timeout_req;
u32 rem_all_buffering_timeout_ms;
u32 can_fw_cmd_timeout_ms;
+ s64 time_diff;
};
struct qti_can_netdev_privdata {
@@ -118,6 +119,10 @@ struct spi_miso { /* TLV for MISO line */
#define CMD_BEGIN_BOOT_ROM_UPGRADE 0x99
#define CMD_BOOT_ROM_UPGRADE_DATA 0x9A
#define CMD_END_BOOT_ROM_UPGRADE 0x9B
+#define CMD_END_FW_UPDATE_FILE 0x9C
+#define CMD_UPDATE_TIME_INFO 0x9D
+#define CMD_SUSPEND_EVENT 0x9E
+#define CMD_RESUME_EVENT 0x9F
#define IOCTL_RELEASE_CAN_BUFFER (SIOCDEVPRIVATE + 0)
#define IOCTL_ENABLE_BUFFERING (SIOCDEVPRIVATE + 1)
@@ -132,6 +137,7 @@ struct spi_miso { /* TLV for MISO line */
#define IOCTL_BEGIN_BOOT_ROM_UPGRADE (SIOCDEVPRIVATE + 11)
#define IOCTL_BOOT_ROM_UPGRADE_DATA (SIOCDEVPRIVATE + 12)
#define IOCTL_END_BOOT_ROM_UPGRADE (SIOCDEVPRIVATE + 13)
+#define IOCTL_END_FW_UPDATE_FILE (SIOCDEVPRIVATE + 14)
#define IFR_DATA_OFFSET 0x100
struct can_fw_resp {
@@ -163,7 +169,7 @@ struct can_add_filter_resp {
struct can_receive_frame {
u8 can_if;
- u32 ts;
+ u64 ts;
u32 mid;
u8 dlc;
u8 data[8];
@@ -178,6 +184,10 @@ struct can_config_bit_timing {
u32 brp;
} __packed;
+struct can_time_info {
+ u64 time;
+} __packed;
+
static struct can_bittiming_const rh850_bittiming_const = {
.name = "qti_can",
.tseg1_min = 1,
@@ -291,7 +301,7 @@ static void qti_can_receive_frame(struct qti_can *priv_data,
return;
}
- LOGDI("rcv frame %d %d %x %d %x %x %x %x %x %x %x %x\n",
+ LOGDI("rcv frame %d %llu %x %d %x %x %x %x %x %x %x %x\n",
frame->can_if, frame->ts, frame->mid, frame->dlc,
frame->data[0], frame->data[1], frame->data[2], frame->data[3],
frame->data[4], frame->data[5], frame->data[6], frame->data[7]);
@@ -301,7 +311,8 @@ static void qti_can_receive_frame(struct qti_can *priv_data,
for (i = 0; i < cf->can_dlc; i++)
cf->data[i] = frame->data[i];
- nsec = ms_to_ktime(le32_to_cpu(frame->ts));
+ nsec = ms_to_ktime(le64_to_cpu(frame->ts) + priv_data->time_diff);
+
skt = skb_hwtstamps(skb);
skt->hwtstamp = nsec;
LOGDI(" hwtstamp %lld\n", ktime_to_ms(skt->hwtstamp));
@@ -354,6 +365,8 @@ static int qti_can_process_response(struct qti_can *priv_data,
struct spi_miso *resp, int length)
{
int ret = 0;
+ u64 mstime;
+ ktime_t ktime_now;
LOGDI("<%x %2d [%d]\n", resp->cmd, resp->len, resp->seq);
if (resp->cmd == CMD_CAN_RECEIVE_FRAME) {
@@ -402,6 +415,12 @@ static int qti_can_process_response(struct qti_can *priv_data,
ret |= (fw_resp->br_min & 0xFF) << 16;
ret |= (fw_resp->maj & 0xF) << 8;
ret |= (fw_resp->min & 0xFF);
+ } else if (resp->cmd == CMD_UPDATE_TIME_INFO) {
+ struct can_time_info *time_data =
+ (struct can_time_info *)resp->data;
+ ktime_now = ktime_get_boottime();
+ mstime = ktime_to_ms(ktime_now);
+ priv_data->time_diff = mstime - (le64_to_cpu(time_data->time));
}
if (resp->cmd == priv_data->wait_cmd) {
@@ -563,6 +582,30 @@ static int qti_can_query_firmware_version(struct qti_can *priv_data)
return ret;
}
+static int qti_can_notify_power_events(struct qti_can *priv_data, u8 event_type)
+{
+ char *tx_buf, *rx_buf;
+ int ret;
+ struct spi_mosi *req;
+
+ mutex_lock(&priv_data->spi_lock);
+ tx_buf = priv_data->tx_buf;
+ rx_buf = priv_data->rx_buf;
+ memset(tx_buf, 0, XFER_BUFFER_SIZE);
+ memset(rx_buf, 0, XFER_BUFFER_SIZE);
+ priv_data->xfer_length = XFER_BUFFER_SIZE;
+
+ req = (struct spi_mosi *)tx_buf;
+ req->cmd = event_type;
+ req->len = 0;
+ req->seq = atomic_inc_return(&priv_data->msg_seq);
+
+ ret = qti_can_do_spi_transaction(priv_data);
+ mutex_unlock(&priv_data->spi_lock);
+
+ return ret;
+}
+
static int qti_can_set_bitrate(struct net_device *netdev)
{
char *tx_buf, *rx_buf;
@@ -983,6 +1026,8 @@ static int qti_can_convert_ioctl_cmd_to_spi_cmd(int ioctl_cmd)
return CMD_BOOT_ROM_UPGRADE_DATA;
case IOCTL_END_BOOT_ROM_UPGRADE:
return CMD_END_BOOT_ROM_UPGRADE;
+ case IOCTL_END_FW_UPDATE_FILE:
+ return CMD_END_FW_UPDATE_FILE;
}
return -EINVAL;
}
@@ -1119,6 +1164,7 @@ static int qti_can_netdev_do_ioctl(struct net_device *netdev,
case IOCTL_BEGIN_BOOT_ROM_UPGRADE:
case IOCTL_BOOT_ROM_UPGRADE_DATA:
case IOCTL_END_BOOT_ROM_UPGRADE:
+ case IOCTL_END_FW_UPDATE_FILE:
ret = qti_can_do_blocking_ioctl(netdev, ifr, cmd);
break;
}
@@ -1243,6 +1289,7 @@ static int qti_can_probe(struct spi_device *spi)
int err, retry = 0, query_err = -1, i;
struct qti_can *priv_data = NULL;
struct device *dev;
+ u32 irq_type;
dev = &spi->dev;
dev_info(dev, "qti_can_probe");
@@ -1319,7 +1366,7 @@ static int qti_can_probe(struct spi_device *spi)
}
priv_data->support_can_fd = of_property_read_bool(spi->dev.of_node,
- "support-can-fd");
+ "qcom,support-can-fd");
if (of_device_is_compatible(spi->dev.of_node, "qcom,nxp,mpc5746c"))
qti_can_bittiming_const = flexcan_bittiming_const;
@@ -1349,8 +1396,11 @@ static int qti_can_probe(struct spi_device *spi)
}
}
+ irq_type = irq_get_trigger_type(spi->irq);
+ if (irq_type == IRQ_TYPE_NONE)
+ irq_type = IRQ_TYPE_EDGE_FALLING;
err = request_threaded_irq(spi->irq, NULL, qti_can_irq,
- IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ irq_type | IRQF_ONESHOT,
"qti-can", priv_data);
if (err) {
LOGDE("Failed to request irq: %d", err);
@@ -1416,6 +1466,10 @@ static int qti_can_remove(struct spi_device *spi)
static int qti_can_suspend(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
+ struct qti_can *priv_data = spi_get_drvdata(spi);
+ u8 power_event = CMD_SUSPEND_EVENT;
+
+ qti_can_notify_power_events(priv_data, power_event);
enable_irq_wake(spi->irq);
return 0;
@@ -1425,9 +1479,10 @@ static int qti_can_resume(struct device *dev)
{
struct spi_device *spi = to_spi_device(dev);
struct qti_can *priv_data = spi_get_drvdata(spi);
+ u8 power_event = CMD_RESUME_EVENT;
disable_irq_wake(spi->irq);
- qti_can_rx_message(priv_data);
+ qti_can_notify_power_events(priv_data, power_event);
return 0;
}
diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c
index b1ca40552a84..2af6e3c8b718 100644
--- a/drivers/net/can/usb/ems_usb.c
+++ b/drivers/net/can/usb/ems_usb.c
@@ -1083,6 +1083,7 @@ static void ems_usb_disconnect(struct usb_interface *intf)
usb_free_urb(dev->intr_urb);
kfree(dev->intr_in_buffer);
+ kfree(dev->tx_msg_buffer);
}
}
diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c
index 8a998e3884ce..8ca23539c23a 100644
--- a/drivers/net/can/xilinx_can.c
+++ b/drivers/net/can/xilinx_can.c
@@ -25,8 +25,10 @@
#include
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -100,7 +102,7 @@ enum xcan_reg {
#define XCAN_INTR_ALL (XCAN_IXR_TXOK_MASK | XCAN_IXR_BSOFF_MASK |\
XCAN_IXR_WKUP_MASK | XCAN_IXR_SLP_MASK | \
XCAN_IXR_RXNEMP_MASK | XCAN_IXR_ERROR_MASK | \
- XCAN_IXR_ARBLST_MASK | XCAN_IXR_RXOK_MASK)
+ XCAN_IXR_RXOFLW_MASK | XCAN_IXR_ARBLST_MASK)
/* CAN register bit shift - XCAN___SHIFT */
#define XCAN_BTR_SJW_SHIFT 7 /* Synchronous jump width */
@@ -117,6 +119,7 @@ enum xcan_reg {
/**
* struct xcan_priv - This definition define CAN driver instance
* @can: CAN private data structure.
+ * @tx_lock: Lock for synchronizing TX interrupt handling
* @tx_head: Tx CAN packets ready to send on the queue
* @tx_tail: Tx CAN packets successfully sended on the queue
* @tx_max: Maximum number packets the driver can send
@@ -131,6 +134,7 @@ enum xcan_reg {
*/
struct xcan_priv {
struct can_priv can;
+ spinlock_t tx_lock;
unsigned int tx_head;
unsigned int tx_tail;
unsigned int tx_max;
@@ -158,6 +162,11 @@ static const struct can_bittiming_const xcan_bittiming_const = {
.brp_inc = 1,
};
+#define XCAN_CAP_WATERMARK 0x0001
+struct xcan_devtype_data {
+ unsigned int caps;
+};
+
/**
* xcan_write_reg_le - Write a value to the device register little endian
* @priv: Driver private data structure
@@ -237,6 +246,10 @@ static int set_reset_mode(struct net_device *ndev)
usleep_range(500, 10000);
}
+ /* reset clears FIFOs */
+ priv->tx_head = 0;
+ priv->tx_tail = 0;
+
return 0;
}
@@ -391,6 +404,7 @@ static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
struct net_device_stats *stats = &ndev->stats;
struct can_frame *cf = (struct can_frame *)skb->data;
u32 id, dlc, data[2] = {0, 0};
+ unsigned long flags;
if (can_dropped_invalid_skb(ndev, skb))
return NETDEV_TX_OK;
@@ -438,6 +452,9 @@ static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
data[1] = be32_to_cpup((__be32 *)(cf->data + 4));
can_put_echo_skb(skb, ndev, priv->tx_head % priv->tx_max);
+
+ spin_lock_irqsave(&priv->tx_lock, flags);
+
priv->tx_head++;
/* Write the Frame to Xilinx CAN TX FIFO */
@@ -453,10 +470,16 @@ static int xcan_start_xmit(struct sk_buff *skb, struct net_device *ndev)
stats->tx_bytes += cf->can_dlc;
}
+ /* Clear TX-FIFO-empty interrupt for xcan_tx_interrupt() */
+ if (priv->tx_max > 1)
+ priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_TXFEMP_MASK);
+
/* Check if the TX buffer is full */
if ((priv->tx_head - priv->tx_tail) == priv->tx_max)
netif_stop_queue(ndev);
+ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
return NETDEV_TX_OK;
}
@@ -598,7 +621,6 @@ static void xcan_err_interrupt(struct net_device *ndev, u32 isr)
if (isr & XCAN_IXR_RXOFLW_MASK) {
stats->rx_over_errors++;
stats->rx_errors++;
- priv->write_reg(priv, XCAN_SRR_OFFSET, XCAN_SRR_RESET_MASK);
if (skb) {
cf->can_id |= CAN_ERR_CRTL;
cf->data[1] |= CAN_ERR_CRTL_RX_OVERFLOW;
@@ -710,15 +732,7 @@ static int xcan_rx_poll(struct napi_struct *napi, int quota)
isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
while ((isr & XCAN_IXR_RXNEMP_MASK) && (work_done < quota)) {
- if (isr & XCAN_IXR_RXOK_MASK) {
- priv->write_reg(priv, XCAN_ICR_OFFSET,
- XCAN_IXR_RXOK_MASK);
- work_done += xcan_rx(ndev);
- } else {
- priv->write_reg(priv, XCAN_ICR_OFFSET,
- XCAN_IXR_RXNEMP_MASK);
- break;
- }
+ work_done += xcan_rx(ndev);
priv->write_reg(priv, XCAN_ICR_OFFSET, XCAN_IXR_RXNEMP_MASK);
isr = priv->read_reg(priv, XCAN_ISR_OFFSET);
}
@@ -729,7 +743,7 @@ static int xcan_rx_poll(struct napi_struct *napi, int quota)
if (work_done < quota) {
napi_complete(napi);
ier = priv->read_reg(priv, XCAN_IER_OFFSET);
- ier |= (XCAN_IXR_RXOK_MASK | XCAN_IXR_RXNEMP_MASK);
+ ier |= XCAN_IXR_RXNEMP_MASK;
priv->write_reg(priv, XCAN_IER_OFFSET, ier);
}
return work_done;
@@ -801,9 +815,9 @@ static irqreturn_t xcan_interrupt(int irq, void *dev_id)
}
/* Check for the type of receive interrupt and Processing it */
- if (isr & (XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK)) {
+ if (isr & XCAN_IXR_RXNEMP_MASK) {
ier = priv->read_reg(priv, XCAN_IER_OFFSET);
- ier &= ~(XCAN_IXR_RXNEMP_MASK | XCAN_IXR_RXOK_MASK);
+ ier &= ~XCAN_IXR_RXNEMP_MASK;
priv->write_reg(priv, XCAN_IER_OFFSET, ier);
napi_schedule(&priv->napi);
}
@@ -1032,6 +1046,18 @@ static int __maybe_unused xcan_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(xcan_dev_pm_ops, xcan_suspend, xcan_resume);
+static const struct xcan_devtype_data xcan_zynq_data = {
+ .caps = XCAN_CAP_WATERMARK,
+};
+
+/* Match table for OF platform binding */
+static const struct of_device_id xcan_of_match[] = {
+ { .compatible = "xlnx,zynq-can-1.0", .data = &xcan_zynq_data },
+ { .compatible = "xlnx,axi-can-1.00.a", },
+ { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(of, xcan_of_match);
+
/**
* xcan_probe - Platform registration call
* @pdev: Handle to the platform device structure
@@ -1046,8 +1072,10 @@ static int xcan_probe(struct platform_device *pdev)
struct resource *res; /* IO mem resources */
struct net_device *ndev;
struct xcan_priv *priv;
+ const struct of_device_id *of_id;
+ int caps = 0;
void __iomem *addr;
- int ret, rx_max, tx_max;
+ int ret, rx_max, tx_max, tx_fifo_depth;
/* Get the virtual base address for the device */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1057,7 +1085,8 @@ static int xcan_probe(struct platform_device *pdev)
goto err;
}
- ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", &tx_max);
+ ret = of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth",
+ &tx_fifo_depth);
if (ret < 0)
goto err;
@@ -1065,6 +1094,30 @@ static int xcan_probe(struct platform_device *pdev)
if (ret < 0)
goto err;
+ of_id = of_match_device(xcan_of_match, &pdev->dev);
+ if (of_id) {
+ const struct xcan_devtype_data *devtype_data = of_id->data;
+
+ if (devtype_data)
+ caps = devtype_data->caps;
+ }
+
+ /* There is no way to directly figure out how many frames have been
+ * sent when the TXOK interrupt is processed. If watermark programming
+ * is supported, we can have 2 frames in the FIFO and use TXFEMP
+ * to determine if 1 or 2 frames have been sent.
+ * Theoretically we should be able to use TXFWMEMP to determine up
+ * to 3 frames, but it seems that after putting a second frame in the
+ * FIFO, with watermark at 2 frames, it can happen that TXFWMEMP (less
+ * than 2 frames in FIFO) is set anyway with no TXOK (a frame was
+ * sent), which is not a sensible state - possibly TXFWMEMP is not
+ * completely synchronized with the rest of the bits?
+ */
+ if (caps & XCAN_CAP_WATERMARK)
+ tx_max = min(tx_fifo_depth, 2);
+ else
+ tx_max = 1;
+
/* Create a CAN device instance */
ndev = alloc_candev(sizeof(struct xcan_priv), tx_max);
if (!ndev)
@@ -1079,6 +1132,7 @@ static int xcan_probe(struct platform_device *pdev)
CAN_CTRLMODE_BERR_REPORTING;
priv->reg_base = addr;
priv->tx_max = tx_max;
+ spin_lock_init(&priv->tx_lock);
/* Get IRQ for the device */
ndev->irq = platform_get_irq(pdev, 0);
@@ -1146,9 +1200,9 @@ static int xcan_probe(struct platform_device *pdev)
devm_can_led_init(ndev);
clk_disable_unprepare(priv->bus_clk);
clk_disable_unprepare(priv->can_clk);
- netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth:%d\n",
+ netdev_dbg(ndev, "reg_base=0x%p irq=%d clock=%d, tx fifo depth: actual %d, using %d\n",
priv->reg_base, ndev->irq, priv->can.clock.freq,
- priv->tx_max);
+ tx_fifo_depth, priv->tx_max);
return 0;
@@ -1184,14 +1238,6 @@ static int xcan_remove(struct platform_device *pdev)
return 0;
}
-/* Match table for OF platform binding */
-static struct of_device_id xcan_of_match[] = {
- { .compatible = "xlnx,zynq-can-1.0", },
- { .compatible = "xlnx,axi-can-1.00.a", },
- { /* end of list */ },
-};
-MODULE_DEVICE_TABLE(of, xcan_of_match);
-
static struct platform_driver xcan_driver = {
.probe = xcan_probe,
.remove = xcan_remove,
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 067f2cb9b215..ae05c8734d49 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -1674,6 +1674,7 @@ static struct sk_buff *atl1c_alloc_skb(struct atl1c_adapter *adapter)
skb = build_skb(page_address(page) + adapter->rx_page_offset,
adapter->rx_frag_size);
if (likely(skb)) {
+ skb_reserve(skb, NET_SKB_PAD);
adapter->rx_page_offset += adapter->rx_frag_size;
if (adapter->rx_page_offset >= PAGE_SIZE)
adapter->rx_page = NULL;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 29e8e6eceb64..3a794871423b 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1613,6 +1613,7 @@ struct bnx2x {
struct link_vars link_vars;
u32 link_cnt;
struct bnx2x_link_report_data last_reported_link;
+ bool force_link_down;
struct mdio_if_info mdio;
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index f41f53fe1340..82e6c7f12ec2 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1257,6 +1257,11 @@ void __bnx2x_link_report(struct bnx2x *bp)
{
struct bnx2x_link_report_data cur_data;
+ if (bp->force_link_down) {
+ bp->link_vars.link_up = 0;
+ return;
+ }
+
/* reread mf_cfg */
if (IS_PF(bp) && !CHIP_IS_E1(bp))
bnx2x_read_mf_cfg(bp);
@@ -2799,6 +2804,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
bp->pending_max = 0;
}
+ bp->force_link_down = false;
if (bp->port.pmf) {
rc = bnx2x_initial_phy_init(bp, load_mode);
if (rc)
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
index 1edc931b1458..2a518c998ecc 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
@@ -3296,14 +3296,18 @@ static int bnx2x_set_rss_flags(struct bnx2x *bp, struct ethtool_rxnfc *info)
DP(BNX2X_MSG_ETHTOOL,
"rss re-configured, UDP 4-tupple %s\n",
udp_rss_requested ? "enabled" : "disabled");
- return bnx2x_rss(bp, &bp->rss_conf_obj, false, true);
+ if (bp->state == BNX2X_STATE_OPEN)
+ return bnx2x_rss(bp, &bp->rss_conf_obj, false,
+ true);
} else if ((info->flow_type == UDP_V6_FLOW) &&
(bp->rss_conf_obj.udp_rss_v6 != udp_rss_requested)) {
bp->rss_conf_obj.udp_rss_v6 = udp_rss_requested;
DP(BNX2X_MSG_ETHTOOL,
"rss re-configured, UDP 4-tupple %s\n",
udp_rss_requested ? "enabled" : "disabled");
- return bnx2x_rss(bp, &bp->rss_conf_obj, false, true);
+ if (bp->state == BNX2X_STATE_OPEN)
+ return bnx2x_rss(bp, &bp->rss_conf_obj, false,
+ true);
}
return 0;
@@ -3401,7 +3405,10 @@ static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
bp->rss_conf_obj.ind_table[i] = indir[i] + bp->fp->cl_id;
}
- return bnx2x_config_rss_eth(bp, false);
+ if (bp->state == BNX2X_STATE_OPEN)
+ return bnx2x_config_rss_eth(bp, false);
+
+ return 0;
}
/**
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index f8e8206d7620..8063e928827c 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -10036,6 +10036,12 @@ static void bnx2x_sp_rtnl_task(struct work_struct *work)
bp->sp_rtnl_state = 0;
smp_mb();
+ /* Immediately indicate link as down */
+ bp->link_vars.link_up = 0;
+ bp->force_link_down = true;
+ netif_carrier_off(bp->dev);
+ BNX2X_ERR("Indicating link is down due to Tx-timeout\n");
+
bnx2x_nic_unload(bp, UNLOAD_NORMAL, true);
bnx2x_nic_load(bp, LOAD_NORMAL);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index a9db2337d9e2..faee5ed88e5c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -529,7 +529,7 @@ static void dcb_tx_queue_prio_enable(struct net_device *dev, int enable)
"Can't %s DCB Priority on port %d, TX Queue %d: err=%d\n",
enable ? "set" : "unset", pi->port_id, i, -err);
else
- txq->dcb_prio = value;
+ txq->dcb_prio = enable ? value : 0;
}
}
#endif /* CONFIG_CHELSIO_T4_DCB */
diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.c b/drivers/net/ethernet/cisco/enic/enic_clsf.c
index 0be6850be8a2..d911a3e94528 100644
--- a/drivers/net/ethernet/cisco/enic/enic_clsf.c
+++ b/drivers/net/ethernet/cisco/enic/enic_clsf.c
@@ -78,7 +78,6 @@ void enic_rfs_flw_tbl_init(struct enic *enic)
enic->rfs_h.max = enic->config.num_arfs;
enic->rfs_h.free = enic->rfs_h.max;
enic->rfs_h.toclean = 0;
- enic_rfs_timer_start(enic);
}
void enic_rfs_flw_tbl_free(struct enic *enic)
@@ -87,7 +86,6 @@ void enic_rfs_flw_tbl_free(struct enic *enic)
enic_rfs_timer_stop(enic);
spin_lock_bh(&enic->rfs_h.lock);
- enic->rfs_h.free = 0;
for (i = 0; i < (1 << ENIC_RFS_FLW_BITSHIFT); i++) {
struct hlist_head *hhead;
struct hlist_node *tmp;
@@ -98,6 +96,7 @@ void enic_rfs_flw_tbl_free(struct enic *enic)
enic_delfltr(enic, n->fltr_id);
hlist_del(&n->node);
kfree(n);
+ enic->rfs_h.free++;
}
}
spin_unlock_bh(&enic->rfs_h.lock);
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 14b19aa2125f..c6775de7b4f2 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -1643,7 +1643,7 @@ static int enic_open(struct net_device *netdev)
vnic_intr_unmask(&enic->intr[i]);
enic_notify_timer_start(enic);
- enic_rfs_flw_tbl_init(enic);
+ enic_rfs_timer_start(enic);
return 0;
@@ -1717,10 +1717,32 @@ static int enic_stop(struct net_device *netdev)
return 0;
}
+static int _enic_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ bool running = netif_running(netdev);
+ int err = 0;
+
+ ASSERT_RTNL();
+ if (running) {
+ err = enic_stop(netdev);
+ if (err)
+ return err;
+ }
+
+ netdev->mtu = new_mtu;
+
+ if (running) {
+ err = enic_open(netdev);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int enic_change_mtu(struct net_device *netdev, int new_mtu)
{
struct enic *enic = netdev_priv(netdev);
- int running = netif_running(netdev);
if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU)
return -EINVAL;
@@ -1728,20 +1750,12 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu)
if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
return -EOPNOTSUPP;
- if (running)
- enic_stop(netdev);
-
- netdev->mtu = new_mtu;
-
if (netdev->mtu > enic->port_mtu)
netdev_warn(netdev,
- "interface MTU (%d) set higher than port MTU (%d)\n",
- netdev->mtu, enic->port_mtu);
+ "interface MTU (%d) set higher than port MTU (%d)\n",
+ netdev->mtu, enic->port_mtu);
- if (running)
- enic_open(netdev);
-
- return 0;
+ return _enic_change_mtu(netdev, new_mtu);
}
static void enic_change_mtu_work(struct work_struct *work)
@@ -1749,47 +1763,9 @@ static void enic_change_mtu_work(struct work_struct *work)
struct enic *enic = container_of(work, struct enic, change_mtu_work);
struct net_device *netdev = enic->netdev;
int new_mtu = vnic_dev_mtu(enic->vdev);
- int err;
- unsigned int i;
-
- new_mtu = max_t(int, ENIC_MIN_MTU, min_t(int, ENIC_MAX_MTU, new_mtu));
rtnl_lock();
-
- /* Stop RQ */
- del_timer_sync(&enic->notify_timer);
-
- for (i = 0; i < enic->rq_count; i++)
- napi_disable(&enic->napi[i]);
-
- vnic_intr_mask(&enic->intr[0]);
- enic_synchronize_irqs(enic);
- err = vnic_rq_disable(&enic->rq[0]);
- if (err) {
- rtnl_unlock();
- netdev_err(netdev, "Unable to disable RQ.\n");
- return;
- }
- vnic_rq_clean(&enic->rq[0], enic_free_rq_buf);
- vnic_cq_clean(&enic->cq[0]);
- vnic_intr_clean(&enic->intr[0]);
-
- /* Fill RQ with new_mtu-sized buffers */
- netdev->mtu = new_mtu;
- vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf);
- /* Need at least one buffer on ring to get going */
- if (vnic_rq_desc_used(&enic->rq[0]) == 0) {
- rtnl_unlock();
- netdev_err(netdev, "Unable to alloc receive buffers.\n");
- return;
- }
-
- /* Start RQ */
- vnic_rq_enable(&enic->rq[0]);
- napi_enable(&enic->napi[0]);
- vnic_intr_unmask(&enic->intr[0]);
- enic_notify_timer_start(enic);
-
+ (void)_enic_change_mtu(netdev, new_mtu);
rtnl_unlock();
netdev_info(netdev, "interface MTU set as %d\n", netdev->mtu);
@@ -2508,6 +2484,7 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
enic->notify_timer.function = enic_notify_timer;
enic->notify_timer.data = (unsigned long)enic;
+ enic_rfs_flw_tbl_init(enic);
enic_set_rx_coal_setting(enic);
INIT_WORK(&enic->reset, enic_reset);
INIT_WORK(&enic->change_mtu_work, enic_change_mtu_work);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index b5f484bf3fda..4be0a22757d2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -1781,7 +1781,12 @@ s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
if (enable_addr != 0)
rar_high |= IXGBE_RAH_AV;
+ /* Record lower 32 bits of MAC address and then make
+ * sure that write is flushed to hardware before writing
+ * the upper 16 bits and setting the valid bit.
+ */
IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
+ IXGBE_WRITE_FLUSH(hw);
IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
return 0;
@@ -1813,8 +1818,13 @@ s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
- IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
+ /* Clear the address valid bit and upper 16 bits of the address
+ * before clearing the lower bits. This way we aren't updating
+ * a live filter.
+ */
IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+ IXGBE_WRITE_FLUSH(hw);
+ IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
/* clear VMDq pool/queue selection for this RAR */
hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index fbb0c02276f9..816b614025b4 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -2709,7 +2709,7 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
u32 srqn = qp_get_srqn(qpc) & 0xffffff;
int use_srq = (qp_get_srqn(qpc) >> 24) & 1;
struct res_srq *srq;
- int local_qpn = be32_to_cpu(qpc->local_qpn) & 0xffffff;
+ int local_qpn = vhcr->in_modifier & 0xffffff;
err = qp_res_start_move_to(dev, slave, qpn, RES_QP_HW, &qp, 0);
if (err)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index 59a721fba018..8c787fab7993 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -1136,6 +1136,8 @@ static ssize_t qlcnic_83xx_sysfs_flash_write_handler(struct file *filp,
return QL_STATUS_INVALID_PARAM;
ret = kstrtoul(buf, 16, &data);
+ if (ret)
+ return ret;
switch (data) {
case QLC_83XX_FLASH_SECTOR_ERASE_CMD:
diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c b/drivers/net/ethernet/qualcomm/qca_spi.c
index 487d6ab771e9..2ec7fa82b4cf 100644
--- a/drivers/net/ethernet/qualcomm/qca_spi.c
+++ b/drivers/net/ethernet/qualcomm/qca_spi.c
@@ -636,7 +636,7 @@ qcaspi_netdev_open(struct net_device *dev)
return ret;
}
- netif_start_queue(qca->net_dev);
+ /* SPI thread takes care of TX queue */
return 0;
}
@@ -740,6 +740,9 @@ qcaspi_netdev_tx_timeout(struct net_device *dev)
qca->net_dev->stats.tx_errors++;
/* Trigger tx queue flush and QCA7000 reset */
qca->sync = QCASPI_SYNC_UNKNOWN;
+
+ if (qca->spi_thread)
+ wake_up_process(qca->spi_thread);
}
static int
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 103ae8ef8643..fc7b5ac6d6fe 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -53,7 +53,7 @@
#include "stmmac.h"
#include
-#define STMMAC_ALIGN(x) L1_CACHE_ALIGN(x)
+#define STMMAC_ALIGN(x) __ALIGN_KERNEL(x, SMP_CACHE_BYTES)
/* Module parameters */
#define TX_TIMEO 5000
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index ea712512c7d1..03fcce11ea4e 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1514,6 +1514,10 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
static int match_first_device(struct device *dev, void *data)
{
+ if (dev->parent && dev->parent->of_node)
+ return of_device_is_compatible(dev->parent->of_node,
+ "ti,davinci_mdio");
+
return !strncmp(dev_name(dev), "davinci_mdio", 12);
}
diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
index 3b67d60d4378..bc42a1d7a43f 100644
--- a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
+++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c
@@ -219,6 +219,7 @@ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np)
ret = of_mdiobus_register(bus, np1);
if (ret) {
mdiobus_free(bus);
+ lp->mii_bus = NULL;
return ret;
}
return 0;
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index c2894e43840e..35db4fc691e7 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -90,10 +90,6 @@
static const char banner[] __initconst = KERN_INFO \
"AX.25: bpqether driver version 004\n";
-static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
-
-static char bpq_eth_addr[6];
-
static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
static int bpq_device_event(struct notifier_block *, unsigned long, void *);
@@ -512,8 +508,8 @@ static int bpq_new_device(struct net_device *edev)
bpq->ethdev = edev;
bpq->axdev = ndev;
- memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
- memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
+ eth_broadcast_addr(bpq->dest_addr);
+ eth_broadcast_addr(bpq->acpt_addr);
err = register_netdevice(ndev);
if (err)
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index 30b44326364e..ab9cfa8e6ac6 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -661,7 +661,7 @@ static void rtl8150_set_multicast(struct net_device *netdev)
(netdev->flags & IFF_ALLMULTI)) {
rx_creg &= 0xfffe;
rx_creg |= 0x0002;
- dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
+ dev_dbg(&netdev->dev, "%s: allmulti set\n", netdev->name);
} else {
/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
rx_creg &= 0x00fc;
diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c
index b1fccaaf96b8..c3b6815f07c3 100644
--- a/drivers/net/usb/smsc75xx.c
+++ b/drivers/net/usb/smsc75xx.c
@@ -81,6 +81,9 @@ static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+static int smsc75xx_link_ok_nopm(struct usbnet *dev);
+static int smsc75xx_phy_gig_workaround(struct usbnet *dev);
+
static int __must_check __smsc75xx_read_reg(struct usbnet *dev, u32 index,
u32 *data, int in_pm)
{
@@ -840,6 +843,9 @@ static int smsc75xx_phy_initialize(struct usbnet *dev)
return -EIO;
}
+ /* phy workaround for gig link */
+ smsc75xx_phy_gig_workaround(dev);
+
smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE,
ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP |
ADVERTISE_PAUSE_ASYM);
@@ -978,6 +984,62 @@ static int smsc75xx_wait_ready(struct usbnet *dev, int in_pm)
return -EIO;
}
+static int smsc75xx_phy_gig_workaround(struct usbnet *dev)
+{
+ struct mii_if_info *mii = &dev->mii;
+ int ret = 0, timeout = 0;
+ u32 buf, link_up = 0;
+
+ /* Set the phy in Gig loopback */
+ smsc75xx_mdio_write(dev->net, mii->phy_id, MII_BMCR, 0x4040);
+
+ /* Wait for the link up */
+ do {
+ link_up = smsc75xx_link_ok_nopm(dev);
+ usleep_range(10000, 20000);
+ timeout++;
+ } while ((!link_up) && (timeout < 1000));
+
+ if (timeout >= 1000) {
+ netdev_warn(dev->net, "Timeout waiting for PHY link up\n");
+ return -EIO;
+ }
+
+ /* phy reset */
+ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n", ret);
+ return ret;
+ }
+
+ buf |= PMT_CTL_PHY_RST;
+
+ ret = smsc75xx_write_reg(dev, PMT_CTL, buf);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to write PMT_CTL: %d\n", ret);
+ return ret;
+ }
+
+ timeout = 0;
+ do {
+ usleep_range(10000, 20000);
+ ret = smsc75xx_read_reg(dev, PMT_CTL, &buf);
+ if (ret < 0) {
+ netdev_warn(dev->net, "Failed to read PMT_CTL: %d\n",
+ ret);
+ return ret;
+ }
+ timeout++;
+ } while ((buf & PMT_CTL_PHY_RST) && (timeout < 100));
+
+ if (timeout >= 100) {
+ netdev_warn(dev->net, "timeout waiting for PHY Reset\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
static int smsc75xx_reset(struct usbnet *dev)
{
struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index bea0f313a7a8..2b2d01a3e511 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1384,7 +1384,7 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
case 0x001:
printk(KERN_WARNING "%s: Master Abort (naughty)\n", dev->name);
break;
- case 0x010:
+ case 0x002:
printk(KERN_WARNING "%s: Target Abort (not so naughty)\n", dev->name);
break;
default:
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 37f53bd8fcb1..184b6810cde9 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -68,12 +68,14 @@ enum CountryCode {
CTRY_AUSTRALIA = 36,
CTRY_AUSTRIA = 40,
CTRY_AZERBAIJAN = 31,
+ CTRY_BAHAMAS = 44,
CTRY_BAHRAIN = 48,
CTRY_BANGLADESH = 50,
CTRY_BARBADOS = 52,
CTRY_BELARUS = 112,
CTRY_BELGIUM = 56,
CTRY_BELIZE = 84,
+ CTRY_BERMUDA = 60,
CTRY_BOLIVIA = 68,
CTRY_BOSNIA_HERZ = 70,
CTRY_BRAZIL = 76,
@@ -159,6 +161,7 @@ enum CountryCode {
CTRY_ROMANIA = 642,
CTRY_RUSSIA = 643,
CTRY_SAUDI_ARABIA = 682,
+ CTRY_SERBIA = 688,
CTRY_SERBIA_MONTENEGRO = 891,
CTRY_SINGAPORE = 702,
CTRY_SLOVAKIA = 703,
@@ -170,11 +173,13 @@ enum CountryCode {
CTRY_SWITZERLAND = 756,
CTRY_SYRIA = 760,
CTRY_TAIWAN = 158,
+ CTRY_TANZANIA = 834,
CTRY_THAILAND = 764,
CTRY_TRINIDAD_Y_TOBAGO = 780,
CTRY_TUNISIA = 788,
CTRY_TURKEY = 792,
CTRY_UAE = 784,
+ CTRY_UGANDA = 800,
CTRY_UKRAINE = 804,
CTRY_UNITED_KINGDOM = 826,
CTRY_UNITED_STATES = 840,
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index bdd2b4d61f2f..15bbd1e0d912 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -35,6 +35,7 @@ enum EnumRd {
FRANCE_RES = 0x31,
FCC3_FCCA = 0x3A,
FCC3_WORLD = 0x3B,
+ FCC3_ETSIC = 0x3F,
ETSI1_WORLD = 0x37,
ETSI3_ETSIA = 0x32,
@@ -44,6 +45,7 @@ enum EnumRd {
ETSI4_ETSIC = 0x38,
ETSI5_WORLD = 0x39,
ETSI6_WORLD = 0x34,
+ ETSI8_WORLD = 0x3D,
ETSI_RESERVED = 0x33,
MKK1_MKKA = 0x40,
@@ -59,6 +61,7 @@ enum EnumRd {
MKK1_MKKA1 = 0x4A,
MKK1_MKKA2 = 0x4B,
MKK1_MKKC = 0x4C,
+ APL2_FCCA = 0x4D,
APL3_FCCA = 0x50,
APL1_WORLD = 0x52,
@@ -67,6 +70,7 @@ enum EnumRd {
APL1_ETSIC = 0x55,
APL2_ETSIC = 0x56,
APL5_WORLD = 0x58,
+ APL13_WORLD = 0x5A,
APL6_WORLD = 0x5B,
APL7_FCCA = 0x5C,
APL8_WORLD = 0x5D,
@@ -168,6 +172,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
{FCC3_FCCA, CTL_FCC, CTL_FCC},
{FCC3_WORLD, CTL_FCC, CTL_ETSI},
+ {FCC3_ETSIC, CTL_FCC, CTL_ETSI},
{FCC4_FCCA, CTL_FCC, CTL_FCC},
{FCC5_FCCA, CTL_FCC, CTL_FCC},
{FCC6_FCCA, CTL_FCC, CTL_FCC},
@@ -179,6 +184,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
{ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
+ {ETSI8_WORLD, CTL_ETSI, CTL_ETSI},
/* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
{ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
@@ -188,9 +194,11 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = {
{FCC1_FCCA, CTL_FCC, CTL_FCC},
{APL1_WORLD, CTL_FCC, CTL_ETSI},
{APL2_WORLD, CTL_FCC, CTL_ETSI},
+ {APL2_FCCA, CTL_FCC, CTL_FCC},
{APL3_WORLD, CTL_FCC, CTL_ETSI},
{APL4_WORLD, CTL_FCC, CTL_ETSI},
{APL5_WORLD, CTL_FCC, CTL_ETSI},
+ {APL13_WORLD, CTL_ETSI, CTL_ETSI},
{APL6_WORLD, CTL_ETSI, CTL_ETSI},
{APL8_WORLD, CTL_ETSI, CTL_ETSI},
{APL9_WORLD, CTL_ETSI, CTL_ETSI},
@@ -298,6 +306,7 @@ static struct country_code_to_enum_rd allCountries[] = {
{CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
{CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
+ {CTRY_BAHAMAS, FCC3_WORLD, "BS"},
{CTRY_BAHRAIN, APL6_WORLD, "BH"},
{CTRY_BANGLADESH, NULL1_WORLD, "BD"},
{CTRY_BARBADOS, FCC2_WORLD, "BB"},
@@ -305,6 +314,7 @@ static struct country_code_to_enum_rd allCountries[] = {
{CTRY_BELGIUM, ETSI1_WORLD, "BE"},
{CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
{CTRY_BELIZE, APL1_ETSIC, "BZ"},
+ {CTRY_BERMUDA, FCC3_FCCA, "BM"},
{CTRY_BOLIVIA, APL1_ETSIC, "BO"},
{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
{CTRY_BRAZIL, FCC3_WORLD, "BR"},
@@ -444,6 +454,7 @@ static struct country_code_to_enum_rd allCountries[] = {
{CTRY_ROMANIA, NULL1_WORLD, "RO"},
{CTRY_RUSSIA, NULL1_WORLD, "RU"},
{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+ {CTRY_SERBIA, ETSI1_WORLD, "RS"},
{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
{CTRY_SINGAPORE, APL6_WORLD, "SG"},
{CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
@@ -455,10 +466,12 @@ static struct country_code_to_enum_rd allCountries[] = {
{CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
{CTRY_SYRIA, NULL1_WORLD, "SY"},
{CTRY_TAIWAN, APL3_FCCA, "TW"},
+ {CTRY_TANZANIA, APL1_WORLD, "TZ"},
{CTRY_THAILAND, FCC3_WORLD, "TH"},
{CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT"},
{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
{CTRY_TURKEY, ETSI3_WORLD, "TR"},
+ {CTRY_UGANDA, FCC3_WORLD, "UG"},
{CTRY_UKRAINE, NULL1_WORLD, "UA"},
{CTRY_UAE, NULL1_WORLD, "AE"},
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index d20d4e6f391a..f6d35d9a06eb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -4201,6 +4201,13 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
brcmf_dbg(TRACE, "Enter\n");
if (bus) {
+ /* Stop watchdog task */
+ if (bus->watchdog_tsk) {
+ send_sig(SIGTERM, bus->watchdog_tsk, 1);
+ kthread_stop(bus->watchdog_tsk);
+ bus->watchdog_tsk = NULL;
+ }
+
/* De-register interrupt handler */
brcmf_sdiod_intr_unregister(bus->sdiodev);
diff --git a/drivers/net/wireless/cnss/cnss_pci.c b/drivers/net/wireless/cnss/cnss_pci.c
index c99addac8e57..f92a8c08e9dd 100644
--- a/drivers/net/wireless/cnss/cnss_pci.c
+++ b/drivers/net/wireless/cnss/cnss_pci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -2761,10 +2761,14 @@ static int cnss_powerup(const struct subsys_desc *subsys)
cnss_configure_wlan_en_gpio(WLAN_EN_LOW);
cnss_wlan_vreg_set(vreg_info, VREG_OFF);
if (penv->pdev) {
- pr_err("%d: Unregistering pci device\n", __LINE__);
- pci_unregister_driver(&cnss_wlan_pci_driver);
- penv->pdev = NULL;
- penv->pci_register_again = true;
+ if (wdrv && wdrv->update_status)
+ wdrv->update_status(penv->pdev, CNSS_SSR_FAIL);
+ if (!penv->recovery_in_progress) {
+ pr_err("%d: Unregistering pci device\n", __LINE__);
+ pci_unregister_driver(&cnss_wlan_pci_driver);
+ penv->pdev = NULL;
+ penv->pci_register_again = true;
+ }
}
err_wlan_vreg_on:
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 4371e12b36f3..3f239f1ad203 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -556,6 +556,9 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf)
MWIFIEX_FUNC_SHUTDOWN);
}
+ if (adapter->workqueue)
+ flush_workqueue(adapter->workqueue);
+
mwifiex_usb_free(card);
dev_dbg(adapter->dev, "%s: removing card\n", __func__);
diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c
index 8428858204a6..fc895b466ebb 100644
--- a/drivers/net/wireless/rsi/rsi_91x_sdio.c
+++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c
@@ -155,7 +155,6 @@ static void rsi_reset_card(struct sdio_func *pfunction)
int err;
struct mmc_card *card = pfunction->card;
struct mmc_host *host = card->host;
- s32 bit = (fls(host->ocr_avail) - 1);
u8 cmd52_resp;
u32 clock, resp, i;
u16 rca;
@@ -175,7 +174,6 @@ static void rsi_reset_card(struct sdio_func *pfunction)
msleep(20);
/* Initialize the SDIO card */
- host->ios.vdd = bit;
host->ios.chip_select = MMC_CS_DONTCARE;
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.power_mode = MMC_POWER_UP;
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index c172da56b550..e4a8280cea83 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -388,6 +388,11 @@ static int wl1271_suspend(struct device *dev)
mmc_pm_flag_t sdio_flags;
int ret = 0;
+ if (!wl) {
+ dev_err(dev, "no wilink module was probed\n");
+ goto out;
+ }
+
dev_dbg(dev, "wl1271 suspend. wow_enabled: %d\n",
wl->wow_enabled);
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 9967733a397e..b780c059cc03 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -85,6 +85,7 @@ struct netfront_cb {
/* IRQ name is queue name with "-tx" or "-rx" appended */
#define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)
+static DECLARE_WAIT_QUEUE_HEAD(module_load_q);
static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
struct netfront_stats {
@@ -902,7 +903,6 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
struct sk_buff *skb,
struct sk_buff_head *list)
{
- struct skb_shared_info *shinfo = skb_shinfo(skb);
RING_IDX cons = queue->rx.rsp_cons;
struct sk_buff *nskb;
@@ -911,15 +911,16 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue,
RING_GET_RESPONSE(&queue->rx, ++cons);
skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0];
- if (shinfo->nr_frags == MAX_SKB_FRAGS) {
+ if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) {
unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
BUG_ON(pull_to <= skb_headlen(skb));
__pskb_pull_tail(skb, pull_to - skb_headlen(skb));
}
- BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS);
+ BUG_ON(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS);
- skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag),
+ skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
+ skb_frag_page(nfrag),
rx->offset, rx->status, PAGE_SIZE);
skb_shinfo(nskb)->nr_frags = 0;
@@ -1359,6 +1360,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
netif_carrier_off(netdev);
xenbus_switch_state(dev, XenbusStateInitialising);
+ wait_event(module_load_q,
+ xenbus_read_driver_state(dev->otherend) !=
+ XenbusStateClosed &&
+ xenbus_read_driver_state(dev->otherend) !=
+ XenbusStateUnknown);
return netdev;
exit:
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 56d8486dc167..cdc109ec5b82 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -457,8 +457,17 @@ int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus,
list_add(&slot->slot_list, &pci_hotplug_slot_list);
result = fs_add_slot(pci_slot);
+ if (result)
+ goto err_list_del;
+
kobject_uevent(&pci_slot->kobj, KOBJ_ADD);
dbg("Added slot %s to the list\n", name);
+ goto out;
+
+err_list_del:
+ list_del(&slot->slot_list);
+ pci_slot->hotplug = NULL;
+ pci_destroy_slot(pci_slot);
out:
mutex_unlock(&pci_hp_mutex);
return result;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 318707870cb2..6b66f9950b57 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -199,13 +199,16 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (!val) {
- if (pci_is_enabled(pdev))
- pci_disable_device(pdev);
- else
- result = -EIO;
- } else
+ device_lock(dev);
+ if (dev->driver)
+ result = -EBUSY;
+ else if (val)
result = pci_enable_device(pdev);
+ else if (pci_is_enabled(pdev))
+ pci_disable_device(pdev);
+ else
+ result = -EIO;
+ device_unlock(dev);
return result < 0 ? result : count;
}
diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c
index 5ac59fbb2440..d6115d3835ee 100644
--- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c
+++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c
@@ -435,7 +435,7 @@ static void imx1_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
const char *name;
int i, ret;
- if (group > info->ngroups)
+ if (group >= info->ngroups)
return;
seq_puts(s, "\n");
diff --git a/drivers/platform/msm/Kconfig b/drivers/platform/msm/Kconfig
index 0774fe4d29aa..198408ad3ea9 100644
--- a/drivers/platform/msm/Kconfig
+++ b/drivers/platform/msm/Kconfig
@@ -194,16 +194,6 @@ config IPA_UT
The user interface to run and control the tests is debugfs file
system.
-config SSM
- tristate "QTI Secure Service Module"
- depends on QSEECOM
- depends on MSM_SMD
- help
- Provides an interface for OEM driver to communicate with Trustzone
- and modem for key exchange and mode change.
- This driver uses Secure Channel Manager interface for trustzone
- communication and communicates with modem over SMD channel.
-
config MSM_MHI
tristate "Modem Host Interface Driver"
help
diff --git a/drivers/platform/msm/Makefile b/drivers/platform/msm/Makefile
index 1ecb76f6a76b..5507a12a7ed3 100644
--- a/drivers/platform/msm/Makefile
+++ b/drivers/platform/msm/Makefile
@@ -25,4 +25,3 @@ obj-$(CONFIG_QPNP_VIBRATOR) += qpnp-vibrator.o
obj-$(CONFIG_MSM_AVTIMER) += avtimer.o
obj-$(CONFIG_MSM_11AD) += msm_11ad/
obj-$(CONFIG_MSM_MHI_DEV) += mhi_dev/
-obj-$(CONFIG_SSM) += ssm.o
\ No newline at end of file
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index 60a610199836..43d99b9c30d9 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -1099,13 +1099,14 @@ int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, unsigned long dev_hdl,
uint32_t val;
struct gsi_evt_ctx *ctx;
int res;
- int ee = gsi_ctx->per.ee;
+ int ee;
unsigned long flags;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (!props || !evt_ring_hdl || dev_hdl != (uintptr_t)gsi_ctx) {
GSIERR("bad params props=%p dev_hdl=0x%lx evt_ring_hdl=%p\n",
@@ -1637,7 +1638,7 @@ int gsi_alloc_channel(struct gsi_chan_props *props, unsigned long dev_hdl,
struct gsi_chan_ctx *ctx;
uint32_t val;
int res;
- int ee = gsi_ctx->per.ee;
+ int ee;
enum gsi_ch_cmd_opcode op = GSI_CH_ALLOCATE;
uint8_t erindex;
void **user_data;
@@ -1646,6 +1647,7 @@ int gsi_alloc_channel(struct gsi_chan_props *props, unsigned long dev_hdl,
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (!props || !chan_hdl || dev_hdl != (uintptr_t)gsi_ctx) {
GSIERR("bad params props=%p dev_hdl=0x%lx chan_hdl=%p\n",
@@ -2287,12 +2289,13 @@ int gsi_query_channel_info(unsigned long chan_hdl,
unsigned long flags;
uint64_t rp;
uint64_t wp;
- int ee = gsi_ctx->per.ee;
+ int ee;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (chan_hdl >= gsi_ctx->max_ch || !info) {
GSIERR("bad params chan_hdl=%lu info=%p\n", chan_hdl, info);
@@ -2357,12 +2360,13 @@ int gsi_is_channel_empty(unsigned long chan_hdl, bool *is_empty)
unsigned long flags;
uint64_t rp;
uint64_t wp;
- int ee = gsi_ctx->per.ee;
+ int ee;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (chan_hdl >= gsi_ctx->max_ch || !is_empty) {
GSIERR("bad params chan_hdl=%lu is_empty=%p\n",
@@ -2546,13 +2550,14 @@ int gsi_poll_channel(unsigned long chan_hdl,
{
struct gsi_chan_ctx *ctx;
uint64_t rp;
- int ee = gsi_ctx->per.ee;
+ int ee;
unsigned long flags;
if (!gsi_ctx) {
pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__);
return -GSI_STATUS_NODEV;
}
+ ee = gsi_ctx->per.ee;
if (chan_hdl >= gsi_ctx->max_ch || !notify) {
GSIERR("bad params chan_hdl=%lu notify=%p\n", chan_hdl, notify);
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
index 158be880b953..2143adbdac12 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_mhi_client.c
@@ -2119,6 +2119,15 @@ int ipa_mhi_suspend(bool force)
IPA_MHI_ERR("ipa_mhi_set_state failed %d\n", res);
return res;
}
+
+ res = ipa_mhi_suspend_dl(force);
+ if (res) {
+ IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res);
+ goto fail_suspend_dl_channel;
+ }
+
+ usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX);
+
res = ipa_mhi_suspend_ul(force, &empty, &force_clear);
if (res) {
IPA_MHI_ERR("ipa_mhi_suspend_ul failed %d\n", res);
@@ -2147,12 +2156,6 @@ int ipa_mhi_suspend(bool force)
usleep_range(IPA_MHI_SUSPEND_SLEEP_MIN, IPA_MHI_SUSPEND_SLEEP_MAX);
- res = ipa_mhi_suspend_dl(force);
- if (res) {
- IPA_MHI_ERR("ipa_mhi_suspend_dl failed %d\n", res);
- goto fail_suspend_dl_channel;
- }
-
if (!empty)
ipa_set_tag_process_before_gating(false);
@@ -2166,14 +2169,12 @@ int ipa_mhi_suspend(bool force)
IPA_MHI_FUNC_EXIT();
return 0;
-fail_suspend_dl_channel:
fail_release_cons:
ipa_mhi_request_prod();
fail_release_prod:
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
fail_suspend_ul_channel:
ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->ul_channels);
- ipa_mhi_set_state(IPA_MHI_STATE_STARTED);
if (force_clear) {
if (
ipa_mhi_disable_force_clear(ipa_mhi_client_ctx->qmi_req_id)) {
@@ -2183,6 +2184,9 @@ int ipa_mhi_suspend(bool force)
IPA_MHI_DBG("force clear datapath disabled\n");
ipa_mhi_client_ctx->qmi_req_id++;
}
+fail_suspend_dl_channel:
+ ipa_mhi_resume_channels(true, ipa_mhi_client_ctx->dl_channels);
+ ipa_mhi_set_state(IPA_MHI_STATE_STARTED);
return res;
}
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index 02db3e5bf87e..8ac4137a8446 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -2584,6 +2584,9 @@ void ipa3_q6_pre_shutdown_cleanup(void)
ipa3_q6_pipe_delay(true);
ipa3_q6_avoid_holb();
+ if (ipa3_ctx->ipa_config_is_mhi)
+ ipa3_set_reset_client_cons_pipe_sus_holb(true,
+ IPA_CLIENT_MHI_CONS);
if (ipa3_q6_clean_q6_tables()) {
IPAERR("Failed to clean Q6 tables\n");
BUG();
@@ -2596,8 +2599,11 @@ void ipa3_q6_pre_shutdown_cleanup(void)
* on pipe reset procedure
*/
ipa3_q6_pipe_delay(false);
-
- ipa3_set_usb_prod_pipe_delay();
+ ipa3_set_reset_client_prod_pipe_delay(true,
+ IPA_CLIENT_USB_PROD);
+ if (ipa3_ctx->ipa_config_is_mhi)
+ ipa3_set_reset_client_prod_pipe_delay(true,
+ IPA_CLIENT_MHI_PROD);
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
IPADBG_LOW("Exit with success\n");
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index 2478baff7ccd..9a6cda454435 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -1848,27 +1848,32 @@ static int ipa3_stop_ul_chan_with_data_drain(u32 qmi_req_id,
}
/*
- * Set USB PROD pipe delay for MBIM/RMNET config
+ * Set reset eo_deay for CLEINT PROD pipe
* Clocks, should be voted before calling this API
* locks should be taken before calling this API
*/
-void ipa3_set_usb_prod_pipe_delay(void)
+int ipa3_set_reset_client_prod_pipe_delay(bool set_reset,
+ enum ipa_client_type client)
{
- int result;
+ int result = 0;
int pipe_idx;
struct ipa3_ep_context *ep;
struct ipa_ep_cfg_ctrl ep_ctrl;
memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl));
- ep_ctrl.ipa_ep_delay = true;
+ ep_ctrl.ipa_ep_delay = set_reset;
+ if (IPA_CLIENT_IS_CONS(client)) {
+ IPAERR("client (%d) not PROD\n", client);
+ return -EINVAL;
+ }
- pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);
+ pipe_idx = ipa3_get_ep_mapping(client);
if (pipe_idx == IPA_EP_NOT_ALLOCATED) {
- IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD);
- return;
+ IPAERR("client (%d) not valid\n", client);
+ return -EINVAL;
}
ep = &ipa3_ctx->ep[pipe_idx];
@@ -1885,6 +1890,59 @@ void ipa3_set_usb_prod_pipe_delay(void)
IPADBG("client (ep: %d) success\n", pipe_idx);
}
client_lock_unlock_cb(pipe_idx, false);
+ return result;
+}
+
+int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset,
+ enum ipa_client_type client)
+{
+ int pipe_idx;
+ struct ipa3_ep_context *ep;
+ struct ipa_ep_cfg_ctrl ep_suspend;
+ struct ipa_ep_cfg_holb ep_holb;
+
+ memset(&ep_suspend, 0, sizeof(ep_suspend));
+ memset(&ep_holb, 0, sizeof(ep_holb));
+
+ ep_suspend.ipa_ep_suspend = set_reset;
+ ep_holb.tmr_val = 0;
+ ep_holb.en = set_reset;
+
+ if (IPA_CLIENT_IS_PROD(client)) {
+ IPAERR("client (%d) not CONS\n", client);
+ return -EINVAL;
+ }
+
+ pipe_idx = ipa3_get_ep_mapping(client);
+
+ if (pipe_idx == IPA_EP_NOT_ALLOCATED) {
+ IPAERR("client (%d) not valid\n", client);
+ return -EINVAL;
+ }
+
+ ep = &ipa3_ctx->ep[pipe_idx];
+ /* Setting sus/holb on MHI_CONS with skip_ep_cfg */
+ client_lock_unlock_cb(pipe_idx, true);
+ if (ep->valid && ep->skip_ep_cfg) {
+ if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0)
+ ipahal_write_reg_n_fields(
+ IPA_ENDP_INIT_CTRL_n,
+ pipe_idx, &ep_suspend);
+ /*
+ * ipa3_cfg_ep_holb is not used here because we are
+ * setting HOLB on Q6 pipes, and from APPS perspective
+ * they are not valid, therefore, the above function
+ * will fail.
+ */
+ ipahal_write_reg_n_fields(
+ IPA_ENDP_INIT_HOL_BLOCK_TIMER_n,
+ pipe_idx, &ep_holb);
+ ipahal_write_reg_n_fields(
+ IPA_ENDP_INIT_HOL_BLOCK_EN_n,
+ pipe_idx, &ep_holb);
+ }
+ client_lock_unlock_cb(pipe_idx, false);
+ return 0;
}
void ipa3_xdci_ep_delay_rm(u32 clnt_hdl)
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index b53a58cf9f70..61e8d8a3dea1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1530,7 +1530,10 @@ int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id);
void ipa3_xdci_ep_delay_rm(u32 clnt_hdl);
void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx);
void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx);
-void ipa3_set_usb_prod_pipe_delay(void);
+int ipa3_set_reset_client_prod_pipe_delay(bool set_reset,
+ enum ipa_client_type client);
+int ipa3_set_reset_client_cons_pipe_sus_holb(bool set_reset,
+ enum ipa_client_type client);
int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
bool should_force_clear, u32 qmi_req_id, bool is_dpl);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
index c56a60f7a7fc..45340fcdd4d1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c
@@ -198,6 +198,7 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client,
union __packed gsi_channel_scratch ch_scratch;
struct ipa3_ep_context *ep;
const struct ipa_gsi_ep_config *ep_cfg;
+ struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
IPA_MHI_FUNC_ENTRY();
@@ -323,6 +324,20 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client,
*params->mhi = ch_scratch.mhi;
+ if (IPA_CLIENT_IS_PROD(ep->client) && ep->skip_ep_cfg) {
+ memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
+ ep_cfg_ctrl.ipa_ep_delay = true;
+ ep->ep_delay_set = true;
+ res = ipa3_cfg_ep_ctrl(ipa_ep_idx, &ep_cfg_ctrl);
+ if (res)
+ IPA_MHI_ERR("client (ep: %d) failed result=%d\n",
+ ipa_ep_idx, res);
+ else
+ IPA_MHI_DBG("client (ep: %d) success\n", ipa_ep_idx);
+ } else {
+ ep->ep_delay_set = false;
+ }
+
IPA_MHI_DBG("Starting channel\n");
res = gsi_start_channel(ep->gsi_chan_hdl);
if (res) {
@@ -496,6 +511,7 @@ int ipa3_disconnect_mhi_pipe(u32 clnt_hdl)
{
struct ipa3_ep_context *ep;
int res;
+ struct ipa_ep_cfg_ctrl ep_cfg_ctrl;
IPA_MHI_FUNC_ENTRY();
@@ -510,6 +526,23 @@ int ipa3_disconnect_mhi_pipe(u32 clnt_hdl)
}
ep = &ipa3_ctx->ep[clnt_hdl];
+ IPA_MHI_ERR("Debug --> Remove ep_delay start");
+ if (ep->ep_delay_set == true) {
+ memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
+ ep_cfg_ctrl.ipa_ep_delay = false;
+ res = ipa3_cfg_ep_ctrl(clnt_hdl,
+ &ep_cfg_ctrl);
+ if (res) {
+ IPAERR
+ ("client(ep:%d) failed to remove delay res=%d\n",
+ clnt_hdl, res);
+ } else {
+ IPADBG("client (ep: %d) delay removed\n",
+ clnt_hdl);
+ ep->ep_delay_set = false;
+ }
+ }
+ IPA_MHI_ERR("Debug --> Remov ep_delay end");
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
res = gsi_dealloc_channel(ep->gsi_chan_hdl);
diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c
index 62a9cb0be81a..cc8e00fa9959 100644
--- a/drivers/platform/msm/mhi_dev/mhi.c
+++ b/drivers/platform/msm/mhi_dev/mhi.c
@@ -1406,16 +1406,20 @@ static void mhi_dev_transfer_completion_cb(void *mreq)
union mhi_dev_ring_element_type *el;
int rc = 0;
struct mhi_req *req = (struct mhi_req *)mreq;
- struct mhi_req *local_req = NULL;
union mhi_dev_ring_element_type *compl_ev = NULL;
struct mhi_dev *mhi = NULL;
unsigned long flags;
+ size_t transfer_len;
+ u32 snd_cmpl;
+ uint32_t rd_offset;
client = req->client;
ch = client->channel;
mhi = ch->ring->mhi_dev;
el = req->el;
- local_req = req;
+ transfer_len = req->len;
+ snd_cmpl = req->snd_cmpl;
+ rd_offset = req->rd_offset;
ch->curr_ereq->context = ch;
dma_unmap_single(&mhi_ctx->pdev->dev, req->dma,
@@ -1429,14 +1433,13 @@ static void mhi_dev_transfer_completion_cb(void *mreq)
compl_ev->evt_tr_comp.chid = ch->ch_id;
compl_ev->evt_tr_comp.type =
MHI_DEV_RING_EL_TRANSFER_COMPLETION_EVENT;
- compl_ev->evt_tr_comp.len = el->tre.len;
+ compl_ev->evt_tr_comp.len = transfer_len;
compl_ev->evt_tr_comp.code = MHI_CMD_COMPL_CODE_EOT;
compl_ev->evt_tr_comp.ptr = ch->ring->ring_ctx->generic.rbase +
- local_req->rd_offset * TR_RING_ELEMENT_SZ;
+ rd_offset * TR_RING_ELEMENT_SZ;
ch->curr_ereq->num_events++;
- if (ch->curr_ereq->num_events >= MAX_TR_EVENTS ||
- local_req->snd_cmpl){
+ if (ch->curr_ereq->num_events >= MAX_TR_EVENTS || snd_cmpl) {
mhi_log(MHI_MSG_VERBOSE,
"num of tr events %d for ch %d\n",
ch->curr_ereq->num_events, ch->ch_id);
@@ -1480,6 +1483,7 @@ static void mhi_dev_scheduler(struct work_struct *work)
enum mhi_dev_state state;
enum mhi_dev_event event = 0;
bool mhi_reset = false;
+ uint32_t bhi_imgtxdb = 0;
mutex_lock(&mhi_ctx->mhi_lock);
/* Check for interrupts */
@@ -1517,6 +1521,10 @@ static void mhi_dev_scheduler(struct work_struct *work)
pr_err("error sending SM event\n");
goto fail;
}
+
+ rc = mhi_dev_mmio_read(mhi, BHI_IMGTXDB, &bhi_imgtxdb);
+ mhi_log(MHI_MSG_VERBOSE,
+ "BHI_IMGTXDB = 0x%x\n", bhi_imgtxdb);
}
if (int_value & MHI_MMIO_CTRL_CRDB_STATUS_MSK) {
@@ -1876,6 +1884,7 @@ int mhi_dev_open_channel(uint32_t chan_id,
(struct mhi_dev_client_cb_reason *cb))
{
int rc = 0;
+ int i = 0;
struct mhi_dev_channel *ch;
struct platform_device *pdev;
@@ -1899,6 +1908,38 @@ int mhi_dev_open_channel(uint32_t chan_id,
goto exit;
}
+ /* Pre allocate event requests */
+ ch->ereqs = kcalloc(MHI_MAX_EVT_REQ, sizeof(*ch->ereqs), GFP_KERNEL);
+ if (!ch->ereqs) {
+ rc = -ENOMEM;
+ goto free_client;
+ }
+ /* pre allocate buffers to queue transfer completion events */
+ ch->tr_events = kcalloc(MHI_MAX_EVT_REQ,
+ MAX_TR_EVENTS * sizeof(*ch->tr_events),
+ GFP_KERNEL);
+ if (!ch->tr_events) {
+ rc = -ENOMEM;
+ goto free_ereqs;
+ }
+
+ /*
+ * Organize the above allocated event request block and
+ * completion event block into linked lists. Each event
+ * request includes a pointer to a block of MAX_TR_EVENTS
+ * completion events.
+ */
+ INIT_LIST_HEAD(&mhi_ctx->ch[chan_id].event_req_buffers);
+ for (i = 0; i < MHI_MAX_EVT_REQ; ++i) {
+ ch->ereqs[i].tr_events = ch->tr_events + i * MAX_TR_EVENTS;
+ list_add_tail(&ch->ereqs[i].list,
+ &mhi_ctx->ch[chan_id].event_req_buffers);
+ }
+ mhi_ctx->ch[chan_id].curr_ereq =
+ container_of(mhi_ctx->ch[chan_id].event_req_buffers.next,
+ struct event_req, list);
+ list_del_init(&mhi_ctx->ch[chan_id].curr_ereq->list);
+
ch->active_client = (*handle_client);
(*handle_client)->channel = ch;
(*handle_client)->event_trigger = mhi_dev_client_cb_reason;
@@ -1911,6 +1952,13 @@ int mhi_dev_open_channel(uint32_t chan_id,
else if (ch->state == MHI_DEV_CH_STOPPED)
ch->state = MHI_DEV_CH_PENDING_START;
+ goto exit;
+
+free_ereqs:
+ kfree(ch->ereqs);
+ ch->ereqs = NULL;
+free_client:
+ kfree(*handle_client);
exit:
mutex_unlock(&ch->ch_lock);
return rc;
@@ -1944,14 +1992,12 @@ int mhi_dev_close_channel(struct mhi_dev_client *handle)
mhi_log(MHI_MSG_ERROR,
"Trying to close an active channel (%d)\n",
ch->ch_id);
- mutex_unlock(&ch->ch_lock);
rc = -EAGAIN;
goto exit;
} else if (ch->tre_loc) {
mhi_log(MHI_MSG_ERROR,
"Trying to close channel (%d) when a TRE is active",
ch->ch_id);
- mutex_unlock(&ch->ch_lock);
rc = -EAGAIN;
goto exit;
}
@@ -1959,6 +2005,10 @@ int mhi_dev_close_channel(struct mhi_dev_client *handle)
ch->state = MHI_DEV_CH_CLOSED;
ch->active_client = NULL;
+ kfree(ch->ereqs);
+ kfree(ch->tr_events);
+ ch->ereqs = NULL;
+ ch->tr_events = NULL;
kfree(handle);
exit:
mutex_unlock(&ch->ch_lock);
@@ -2666,40 +2716,8 @@ static int mhi_init(struct mhi_dev *mhi)
if (!mhi->ch)
return -ENOMEM;
-
- for (i = 0; i < mhi->cfg.channels; i++) {
+ for (i = 0; i < mhi->cfg.channels; i++)
mutex_init(&mhi->ch[i].ch_lock);
- if (i == MHI_CLIENT_IP_SW_4_OUT || i == MHI_CLIENT_IP_SW_4_IN) {
- int nreq = 0;
-
- INIT_LIST_HEAD(&mhi->ch[i].event_req_buffers);
- while (nreq < MHI_MAX_EVT_REQ) {
- struct event_req *ereq;
- /* Pre allocate event requests */
- ereq = kzalloc(sizeof(struct event_req),
- GFP_KERNEL);
- if (!ereq)
- return -ENOMEM;
-
- /* pre allocate buffers to queue
- * transfer completion events
- */
- ereq->tr_events = kzalloc(RING_ELEMENT_TYPE_SZ*
- MAX_TR_EVENTS, GFP_KERNEL);
- if (!ereq->tr_events) {
- kfree(ereq);
- return -ENOMEM;
- }
- list_add_tail(&ereq->list,
- &mhi->ch[i].event_req_buffers);
- nreq++;
- }
- mhi->ch[i].curr_ereq =
- container_of(mhi->ch[i].event_req_buffers.next,
- struct event_req, list);
- list_del_init(&mhi->ch[i].curr_ereq->list);
- }
- }
spin_lock_init(&mhi->lock);
mhi->mmio_backup = devm_kzalloc(&pdev->dev,
diff --git a/drivers/platform/msm/mhi_dev/mhi.h b/drivers/platform/msm/mhi_dev/mhi.h
index d764e1c0eb67..147a435897a9 100644
--- a/drivers/platform/msm/mhi_dev/mhi.h
+++ b/drivers/platform/msm/mhi_dev/mhi.h
@@ -440,7 +440,13 @@ struct mhi_dev_channel {
struct mutex ch_lock;
/* client which the current inbound/outbound message is for */
struct mhi_dev_client *active_client;
-
+ /*
+ * Pointer to event request structs used to temporarily store
+ * completion events and meta data before sending them to host
+ */
+ struct event_req *ereqs;
+ /* Pointer to completion event buffers */
+ union mhi_dev_ring_element_type *tr_events;
struct list_head event_req_buffers;
struct event_req *curr_ereq;
diff --git a/drivers/platform/msm/mhi_dev/mhi_hwio.h b/drivers/platform/msm/mhi_dev/mhi_hwio.h
index 40e1a91a980a..db46f2795c93 100644
--- a/drivers/platform/msm/mhi_dev/mhi_hwio.h
+++ b/drivers/platform/msm/mhi_dev/mhi_hwio.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2017-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
@@ -192,4 +192,6 @@
#define BHI_EXECENV_MASK 0xFFFFFFFF
#define BHI_EXECENV_SHIFT 0
+#define BHI_IMGTXDB (0x218)
+
#endif
diff --git a/drivers/platform/msm/mhi_dev/mhi_ring.c b/drivers/platform/msm/mhi_dev/mhi_ring.c
index 785d6d00568d..91496a46f5c8 100644
--- a/drivers/platform/msm/mhi_dev/mhi_ring.c
+++ b/drivers/platform/msm/mhi_dev/mhi_ring.c
@@ -264,11 +264,12 @@ EXPORT_SYMBOL(mhi_dev_process_ring);
int mhi_dev_add_element(struct mhi_dev_ring *ring,
union mhi_dev_ring_element_type *element,
- struct event_req *ereq, int evt_offset)
+ struct event_req *ereq, int size)
{
uint32_t old_offset = 0;
struct mhi_addr host_addr;
- uint32_t num_elem = 0;
+ uint32_t num_elem = 1;
+ uint32_t num_free_elem;
if (!ring || !element) {
pr_err("%s: Invalid context\n", __func__);
@@ -277,16 +278,24 @@ int mhi_dev_add_element(struct mhi_dev_ring *ring,
mhi_dev_update_wr_offset(ring);
- if ((ring->rd_offset + 1) % ring->ring_size == ring->wr_offset) {
- mhi_log(MHI_MSG_VERBOSE, "ring full to insert element\n");
+ if (ereq)
+ num_elem = size / (sizeof(union mhi_dev_ring_element_type));
+
+ if (ring->rd_offset < ring->wr_offset)
+ num_free_elem = ring->wr_offset - ring->rd_offset - 1;
+ else
+ num_free_elem = ring->ring_size - ring->rd_offset +
+ ring->wr_offset - 1;
+
+ if (num_free_elem < num_elem) {
+ mhi_log(MHI_MSG_ERROR, "No space to add %d elem in ring (%d)\n",
+ num_elem, ring->id);
return -EINVAL;
}
old_offset = ring->rd_offset;
- if (evt_offset) {
- num_elem = evt_offset /
- (sizeof(union mhi_dev_ring_element_type));
+ if (ereq) {
ring->rd_offset += num_elem;
if (ring->rd_offset >= ring->ring_size)
ring->rd_offset -= ring->ring_size;
@@ -308,23 +317,47 @@ int mhi_dev_add_element(struct mhi_dev_ring *ring,
host_addr.device_va = ring->ring_shadow.device_va +
sizeof(union mhi_dev_ring_element_type) * old_offset;
- host_addr.virt_addr = element;
-
- if (evt_offset)
- host_addr.size = evt_offset;
- else
+ if (!ereq) {
+ /* We're adding only a single ring element */
+ host_addr.virt_addr = element;
host_addr.size = sizeof(union mhi_dev_ring_element_type);
- mhi_log(MHI_MSG_VERBOSE, "adding element to ring (%d)\n", ring->id);
- mhi_log(MHI_MSG_VERBOSE, "rd_ofset %d\n", ring->rd_offset);
- mhi_log(MHI_MSG_VERBOSE, "type %d\n", element->generic.type);
+ mhi_log(MHI_MSG_VERBOSE, "adding element to ring (%d)\n",
+ ring->id);
+ mhi_log(MHI_MSG_VERBOSE, "rd_ofset %d\n", ring->rd_offset);
+ mhi_log(MHI_MSG_VERBOSE, "type %d\n", element->generic.type);
- if (ereq)
mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
- ereq, MHI_DEV_DMA_ASYNC);
- else
+ NULL, MHI_DEV_DMA_SYNC);
+ return 0;
+ }
+
+ /* Adding multiple ring elements */
+ if (ring->rd_offset == 0 || (ring->rd_offset > old_offset)) {
+ /* No wrap-around case */
+ host_addr.virt_addr = element;
+ host_addr.size = size;
+ mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
+ ereq, MHI_DEV_DMA_ASYNC);
+ } else {
+ /* Wrap-around case - first chunk uses dma sync */
+ host_addr.virt_addr = element;
+ host_addr.size = (ring->ring_size - old_offset) *
+ sizeof(union mhi_dev_ring_element_type);
+ mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
+ NULL, MHI_DEV_DMA_SYNC);
+
+ /* Copy remaining elements */
+ if (ring->mhi_dev->use_ipa)
+ host_addr.host_pa = ring->ring_shadow.host_pa;
+ else
+ host_addr.device_va = ring->ring_shadow.device_va;
+ host_addr.virt_addr = element + (ring->ring_size - old_offset);
+ host_addr.size = ring->rd_offset *
+ sizeof(union mhi_dev_ring_element_type);
mhi_dev_write_to_host(ring->mhi_dev, &host_addr,
- NULL, MHI_DEV_DMA_SYNC);
+ ereq, MHI_DEV_DMA_ASYNC);
+ }
return 0;
}
EXPORT_SYMBOL(mhi_dev_add_element);
diff --git a/drivers/platform/msm/mhi_dev/mhi_uci.c b/drivers/platform/msm/mhi_dev/mhi_uci.c
index 4d9aa2e5e83f..41360fbbafd6 100644
--- a/drivers/platform/msm/mhi_dev/mhi_uci.c
+++ b/drivers/platform/msm/mhi_dev/mhi_uci.c
@@ -35,9 +35,13 @@
#define MHI_SOFTWARE_CLIENT_LIMIT (MHI_MAX_SOFTWARE_CHANNELS/2)
#define MHI_UCI_IPC_LOG_PAGES (100)
-#define MAX_NR_TRBS_PER_CHAN 1
+/* Max number of MHI write request structures (used in async writes) */
+#define MAX_UCI_WR_REQ 10
+#define MAX_NR_TRBS_PER_CHAN 9
#define MHI_QTI_IFACE_ID 4
-#define DEVICE_NAME "mhi"
+#define DEVICE_NAME "mhi"
+
+#define MHI_UCI_ASYNC_READ_TIMEOUT msecs_to_jiffies(100)
enum uci_dbg_level {
UCI_DBG_VERBOSE = 0x0,
@@ -70,7 +74,131 @@ struct chan_attr {
u32 nr_trbs;
/* direction of the channel, see enum mhi_chan_dir */
enum mhi_chan_dir dir;
- u32 uci_ownership;
+ /* need to register mhi channel state change callback */
+ bool register_cb;
+};
+
+/* UCI channel attributes table */
+static const struct chan_attr uci_chan_attr_table[] = {
+ {
+ MHI_CLIENT_LOOPBACK_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_LOOPBACK_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_SAHARA_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_SAHARA_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_EFS_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_EFS_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_MBIM_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_MBIM_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_QMI_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_QMI_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_0_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_0_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_1_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_IP_CTRL_1_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ {
+ MHI_CLIENT_DUN_OUT,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_OUT,
+ false
+ },
+ {
+ MHI_CLIENT_DUN_IN,
+ TRB_MAX_DATA_SIZE,
+ MAX_NR_TRBS_PER_CHAN,
+ MHI_DIR_IN,
+ false
+ },
+ { /* Must be the last */
+ MHI_CLIENT_INVALID,
+ 0,
+ 0,
+ MHI_DIR_INVALID,
+ false
+ },
};
struct uci_ctrl {
@@ -87,6 +215,8 @@ struct uci_client {
u32 in_chan;
struct mhi_dev_client *out_handle;
struct mhi_dev_client *in_handle;
+ const struct chan_attr *in_chan_attr;
+ const struct chan_attr *out_chan_attr;
wait_queue_head_t read_wq;
wait_queue_head_t write_wq;
atomic_t read_data_ready;
@@ -101,10 +231,16 @@ struct uci_client {
struct mhi_uci_ctxt_t *uci_ctxt;
struct mutex in_chan_lock;
struct mutex out_chan_lock;
+ spinlock_t wr_req_lock;
+ unsigned int f_flags;
+ struct mhi_req *wreqs;
+ struct list_head wr_req_list;
+ struct completion read_done;
+ int (*send)(struct uci_client*, void*, u32);
+ int (*read)(struct uci_client*, struct mhi_req*, int*);
};
struct mhi_uci_ctxt_t {
- struct chan_attr chan_attrib[MHI_MAX_SOFTWARE_CHANNELS];
struct uci_client client_handles[MHI_SOFTWARE_CLIENT_LIMIT];
struct uci_ctrl ctrl_handle;
void (*event_notifier)(struct mhi_dev_client_cb_reason *cb);
@@ -119,6 +255,7 @@ struct mhi_uci_ctxt_t {
};
#define CHAN_TO_CLIENT(_CHAN_NR) (_CHAN_NR / 2)
+#define CLIENT_TO_CHAN(_CLIENT_NR) (_CLIENT_NR * 2)
#define uci_log(_msg_lvl, _msg, ...) do { \
if (_msg_lvl >= mhi_uci_msg_lvl) { \
@@ -155,8 +292,8 @@ static int mhi_init_read_chan(struct uci_client *client_handle,
enum mhi_client_channel chan)
{
int rc = 0;
- u32 i , j;
- struct chan_attr *chan_attributes;
+ u32 i, j;
+ const struct chan_attr *in_chan_attr;
size_t buf_size;
void *data_loc;
@@ -169,10 +306,18 @@ static int mhi_init_read_chan(struct uci_client *client_handle,
return -EINVAL;
}
- chan_attributes = &uci_ctxt.chan_attrib[chan];
- buf_size = chan_attributes->max_packet_size;
+ in_chan_attr = client_handle->in_chan_attr;
+ if (!in_chan_attr) {
+ uci_log(UCI_DBG_ERROR, "Null channel attributes for chan %d\n",
+ client_handle->in_chan);
+ return -EINVAL;
+ }
- for (i = 0; i < (chan_attributes->nr_trbs); i++) {
+ /* Init the completion event for read */
+ init_completion(&client_handle->read_done);
+
+ buf_size = in_chan_attr->max_packet_size;
+ for (i = 0; i < (in_chan_attr->nr_trbs); i++) {
data_loc = kmalloc(buf_size, GFP_KERNEL);
if (!data_loc) {
rc = -ENOMEM;
@@ -191,48 +336,129 @@ static int mhi_init_read_chan(struct uci_client *client_handle,
return rc;
}
-static int mhi_uci_send_packet(struct mhi_dev_client **client_handle, void *buf,
- u32 size, u32 is_uspace_buf)
+static void mhi_uci_write_completion_cb(void *req)
{
- void *data_loc = NULL;
- uintptr_t memcpy_result = 0;
- u32 data_inserted_so_far = 0;
+ struct mhi_req *ureq = req;
struct uci_client *uci_handle;
- struct mhi_req ureq;
+ unsigned long flags;
+ uci_handle = (struct uci_client *)ureq->context;
+ kfree(ureq->buf);
+ ureq->buf = NULL;
- uci_handle = container_of(client_handle, struct uci_client,
- out_handle);
+ spin_lock_irqsave(&uci_handle->wr_req_lock, flags);
+ list_add_tail(&ureq->list, &uci_handle->wr_req_list);
+ spin_unlock_irqrestore(&uci_handle->wr_req_lock, flags);
+}
- if (!client_handle || !buf ||
- !size || !uci_handle)
- return -EINVAL;
+static void mhi_uci_read_completion_cb(void *req)
+{
+ struct mhi_req *ureq = req;
+ struct uci_client *uci_handle;
- if (is_uspace_buf) {
- data_loc = kmalloc(size, GFP_KERNEL);
- if (!data_loc) {
- uci_log(UCI_DBG_ERROR,
- "Failed to allocate memory 0x%x\n",
- size);
- return -ENOMEM;
- }
- memcpy_result = copy_from_user(data_loc, buf, size);
- if (memcpy_result)
- goto error_memcpy;
- } else {
- data_loc = buf;
- }
- ureq.client = *client_handle;
+ uci_handle = (struct uci_client *)ureq->context;
+ complete(&uci_handle->read_done);
+}
+
+static int mhi_uci_send_sync(struct uci_client *uci_handle,
+ void *data_loc, u32 size)
+{
+ struct mhi_req ureq;
+ int ret_val;
+
+ ureq.client = uci_handle->out_handle;
ureq.buf = data_loc;
ureq.len = size;
ureq.chan = uci_handle->out_chan;
ureq.mode = IPA_DMA_SYNC;
- data_inserted_so_far = mhi_dev_write_channel(&ureq);
+ ret_val = mhi_dev_write_channel(&ureq);
+
+ kfree(data_loc);
+ return ret_val;
+}
+
+static int mhi_uci_send_async(struct uci_client *uci_handle,
+ void *data_loc, u32 size)
+{
+ int bytes_to_write;
+ struct mhi_req *ureq;
+
+ uci_log(UCI_DBG_VERBOSE,
+ "Got async write for ch %d of size %d\n",
+ uci_handle->out_chan, size);
+
+ spin_lock_irq(&uci_handle->wr_req_lock);
+ if (list_empty(&uci_handle->wr_req_list)) {
+ uci_log(UCI_DBG_ERROR, "Write request pool empty\n");
+ spin_unlock_irq(&uci_handle->wr_req_lock);
+ return -ENOMEM;
+ }
+ ureq = container_of(uci_handle->wr_req_list.next,
+ struct mhi_req, list);
+ list_del_init(&ureq->list);
+ spin_unlock_irq(&uci_handle->wr_req_lock);
+
+ ureq->client = uci_handle->out_handle;
+ ureq->context = uci_handle;
+ ureq->buf = data_loc;
+ ureq->len = size;
+ ureq->chan = uci_handle->out_chan;
+ ureq->mode = IPA_DMA_ASYNC;
+ ureq->client_cb = mhi_uci_write_completion_cb;
+ ureq->snd_cmpl = 1;
+
+ bytes_to_write = mhi_dev_write_channel(ureq);
+ if (bytes_to_write != size)
+ goto error_async_transfer;
+
+ return bytes_to_write;
+
+error_async_transfer:
+ kfree(data_loc);
+ ureq->buf = NULL;
+ spin_lock_irq(&uci_handle->wr_req_lock);
+ list_add_tail(&ureq->list, &uci_handle->wr_req_list);
+ spin_unlock_irq(&uci_handle->wr_req_lock);
+
+ return bytes_to_write;
+}
+
+static int mhi_uci_send_packet(struct mhi_dev_client **client_handle,
+ const char __user *buf, u32 size)
+{
+ void *data_loc;
+ unsigned long memcpy_result;
+ struct uci_client *uci_handle;
+
+ if (!client_handle || !buf || !size)
+ return -EINVAL;
+
+ if (size > TRB_MAX_DATA_SIZE) {
+ uci_log(UCI_DBG_ERROR,
+ "Too big write size: %d, max supported size is %d\n",
+ size, TRB_MAX_DATA_SIZE);
+ return -EFBIG;
+ }
+
+ uci_handle = container_of(client_handle, struct uci_client,
+ out_handle);
+ data_loc = kmalloc(size, GFP_KERNEL);
+ if (!data_loc) {
+ uci_log(UCI_DBG_ERROR,
+ "Failed to allocate kernel buf for user requested size 0x%x\n",
+ size);
+ return -ENOMEM;
+ }
+ memcpy_result = copy_from_user(data_loc, buf, size);
+ if (memcpy_result)
+ goto error_memcpy;
+
+ return uci_handle->send(uci_handle, data_loc, size);
error_memcpy:
kfree(data_loc);
- return data_inserted_so_far;
+ return -EFAULT;
}
static unsigned int mhi_uci_ctrl_poll(struct file *file, poll_table *wait)
@@ -290,6 +516,119 @@ static unsigned int mhi_uci_client_poll(struct file *file, poll_table *wait)
return mask;
}
+static int mhi_uci_alloc_write_reqs(struct uci_client *client)
+{
+ int i;
+
+ client->wreqs = kcalloc(MAX_UCI_WR_REQ,
+ sizeof(struct mhi_req),
+ GFP_KERNEL);
+ if (!client->wreqs) {
+ uci_log(UCI_DBG_ERROR, "Write reqs alloc failed\n");
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&client->wr_req_list);
+ for (i = 0; i < MAX_UCI_WR_REQ; ++i)
+ list_add_tail(&client->wreqs[i].list, &client->wr_req_list);
+
+ uci_log(UCI_DBG_INFO,
+ "UCI write reqs allocation successful\n");
+ return 0;
+}
+
+static int mhi_uci_read_async(struct uci_client *uci_handle,
+ struct mhi_req *ureq, int *bytes_avail)
+{
+ int ret_val = 0;
+ unsigned long compl_ret;
+
+ uci_log(UCI_DBG_ERROR,
+ "Async read for ch %d\n", uci_handle->in_chan);
+
+ ureq->mode = IPA_DMA_ASYNC;
+ ureq->client_cb = mhi_uci_read_completion_cb;
+ ureq->snd_cmpl = 1;
+ ureq->context = uci_handle;
+
+ reinit_completion(&uci_handle->read_done);
+
+ *bytes_avail = mhi_dev_read_channel(ureq);
+ uci_log(UCI_DBG_VERBOSE, "buf_size = 0x%x bytes_read = 0x%x\n",
+ ureq->len, *bytes_avail);
+ if (*bytes_avail < 0) {
+ uci_log(UCI_DBG_ERROR, "Failed to read channel ret %d\n",
+ *bytes_avail);
+ return -EIO;
+ }
+
+ if (*bytes_avail > 0) {
+ uci_log(UCI_DBG_VERBOSE,
+ "Waiting for async read completion!\n");
+ compl_ret =
+ wait_for_completion_interruptible_timeout(
+ &uci_handle->read_done,
+ MHI_UCI_ASYNC_READ_TIMEOUT);
+
+ if (compl_ret == -ERESTARTSYS) {
+ uci_log(UCI_DBG_ERROR, "Exit signal caught\n");
+ return compl_ret;
+ } else if (compl_ret == 0) {
+ uci_log(UCI_DBG_ERROR, "Read timed out for ch %d\n",
+ uci_handle->in_chan);
+ return -EIO;
+ }
+ uci_log(UCI_DBG_VERBOSE,
+ "wk up Read completed on ch %d\n", ureq->chan);
+
+ uci_handle->pkt_loc = (void *)ureq->buf;
+ uci_handle->pkt_size = ureq->actual_len;
+
+ uci_log(UCI_DBG_VERBOSE,
+ "Got pkt of sz 0x%x at adr %pK, ch %d\n",
+ uci_handle->pkt_size,
+ ureq->buf, ureq->chan);
+ } else {
+ uci_handle->pkt_loc = NULL;
+ uci_handle->pkt_size = 0;
+ }
+
+ return ret_val;
+}
+
+static int mhi_uci_read_sync(struct uci_client *uci_handle,
+ struct mhi_req *ureq, int *bytes_avail)
+{
+ int ret_val = 0;
+
+ ureq->mode = IPA_DMA_SYNC;
+ *bytes_avail = mhi_dev_read_channel(ureq);
+
+ uci_log(UCI_DBG_VERBOSE, "buf_size = 0x%x bytes_read = 0x%x\n",
+ ureq->len, *bytes_avail);
+
+ if (*bytes_avail < 0) {
+ uci_log(UCI_DBG_ERROR, "Failed to read channel ret %d\n",
+ *bytes_avail);
+ return -EIO;
+ }
+
+ if (*bytes_avail > 0) {
+ uci_handle->pkt_loc = (void *)ureq->buf;
+ uci_handle->pkt_size = ureq->actual_len;
+
+ uci_log(UCI_DBG_VERBOSE,
+ "Got pkt of sz 0x%x at adr %pK, ch %d\n",
+ uci_handle->pkt_size,
+ ureq->buf, ureq->chan);
+ } else {
+ uci_handle->pkt_loc = NULL;
+ uci_handle->pkt_size = 0;
+ }
+
+ return ret_val;
+}
+
static int open_client_mhi_channels(struct uci_client *uci_client)
{
int rc = 0;
@@ -300,16 +639,27 @@ static int open_client_mhi_channels(struct uci_client *uci_client)
uci_client->in_chan);
mutex_lock(&uci_client->out_chan_lock);
mutex_lock(&uci_client->in_chan_lock);
+
+ /* Allocate write requests for async operations */
+ if (!(uci_client->f_flags & O_SYNC)) {
+ rc = mhi_uci_alloc_write_reqs(uci_client);
+ if (rc)
+ goto handle_not_rdy_err;
+ uci_client->send = mhi_uci_send_async;
+ uci_client->read = mhi_uci_read_async;
+ } else {
+ uci_client->send = mhi_uci_send_sync;
+ uci_client->read = mhi_uci_read_sync;
+ }
+
uci_log(UCI_DBG_DBG,
"Initializing inbound chan %d.\n",
uci_client->in_chan);
-
rc = mhi_init_read_chan(uci_client, uci_client->in_chan);
- if (rc < 0) {
+ if (rc < 0)
uci_log(UCI_DBG_ERROR,
"Failed to init inbound 0x%x, ret 0x%x\n",
uci_client->in_chan, rc);
- }
rc = mhi_dev_open_channel(uci_client->out_chan,
&uci_client->out_handle,
@@ -320,7 +670,6 @@ static int open_client_mhi_channels(struct uci_client *uci_client)
rc = mhi_dev_open_channel(uci_client->in_chan,
&uci_client->in_handle,
uci_ctxt.event_notifier);
-
if (rc < 0) {
uci_log(UCI_DBG_ERROR,
"Failed to open chan %d, ret 0x%x\n",
@@ -375,6 +724,7 @@ static int mhi_uci_client_open(struct inode *mhi_inode,
return -ENOMEM;
}
uci_handle->uci_ctxt = &uci_ctxt;
+ uci_handle->f_flags = file_handle->f_flags;
if (!atomic_read(&uci_handle->mhi_chans_open)) {
uci_log(UCI_DBG_INFO,
"Opening channels client %d\n",
@@ -397,20 +747,11 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
struct file *file_handle)
{
struct uci_client *uci_handle = file_handle->private_data;
- struct mhi_uci_ctxt_t *uci_ctxt;
- u32 nr_in_bufs = 0;
int rc = 0;
- int in_chan = 0;
- u32 buf_size = 0;
if (!uci_handle)
return -EINVAL;
- uci_ctxt = uci_handle->uci_ctxt;
- in_chan = iminor(mhi_inode) + 1;
- nr_in_bufs = uci_ctxt->chan_attrib[in_chan].nr_trbs;
- buf_size = uci_ctxt->chan_attrib[in_chan].max_packet_size;
-
if (atomic_sub_return(1, &uci_handle->ref_count) == 0) {
uci_log(UCI_DBG_DBG,
"Last client left, closing channel 0x%x\n",
@@ -418,6 +759,8 @@ static int mhi_uci_client_release(struct inode *mhi_inode,
if (atomic_read(&uci_handle->mhi_chans_open)) {
atomic_set(&uci_handle->mhi_chans_open, 0);
+ if (!(uci_handle->f_flags & O_SYNC))
+ kfree(uci_handle->wreqs);
mutex_lock(&uci_handle->out_chan_lock);
rc = mhi_dev_close_channel(uci_handle->out_handle);
wake_up(&uci_handle->write_wq);
@@ -553,7 +896,6 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *ubuf,
struct mutex *mutex;
ssize_t bytes_copied = 0;
u32 addr_offset = 0;
- void *local_buf = NULL;
struct mhi_req ureq;
if (!file || !ubuf || !uspace_buf_size ||
@@ -569,44 +911,19 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *ubuf,
ureq.client = client_handle;
ureq.buf = uci_handle->in_buf_list[0].addr;
ureq.len = uci_handle->in_buf_list[0].buf_size;
- ureq.mode = IPA_DMA_SYNC;
+
uci_log(UCI_DBG_VERBOSE, "Client attempted read on chan %d\n",
ureq.chan);
do {
if (!uci_handle->pkt_loc &&
- !atomic_read(&uci_ctxt.mhi_disabled)) {
-
- bytes_avail = mhi_dev_read_channel(&ureq);
-
- uci_log(UCI_DBG_VERBOSE,
- "reading from mhi_core local_buf = %p",
- local_buf);
- uci_log(UCI_DBG_VERBOSE,
- "buf_size = 0x%x bytes_read = 0x%x\n",
- ureq.len, bytes_avail);
-
- if (bytes_avail < 0) {
- uci_log(UCI_DBG_ERROR,
- "Failed to read channel ret %d\n",
- bytes_avail);
- ret_val = -EIO;
+ !atomic_read(&uci_ctxt.mhi_disabled)) {
+ ret_val = uci_handle->read(uci_handle, &ureq,
+ &bytes_avail);
+ if (ret_val)
goto error;
- }
-
- if (bytes_avail > 0) {
- uci_handle->pkt_loc = (void *) ureq.buf;
- uci_handle->pkt_size = ureq.actual_len;
-
+ if (bytes_avail > 0)
*bytes_pending = (loff_t)uci_handle->pkt_size;
- uci_log(UCI_DBG_VERBOSE,
- "Got pkt of sz 0x%x at adr %p, ch %d\n",
- uci_handle->pkt_size,
- ureq.buf, ureq.chan);
- } else {
- uci_handle->pkt_loc = 0;
- uci_handle->pkt_size = 0;
- }
}
if (bytes_avail == 0) {
@@ -615,7 +932,10 @@ static ssize_t mhi_uci_client_read(struct file *file, char __user *ubuf,
"No data read_data_ready %d, chan %d\n",
atomic_read(&uci_handle->read_data_ready),
ureq.chan);
-
+ if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY)) {
+ ret_val = -EAGAIN;
+ goto error;
+ }
ret_val = wait_event_interruptible(uci_handle->read_wq,
(!mhi_dev_channel_isempty(client_handle)));
@@ -719,10 +1039,10 @@ static ssize_t mhi_uci_client_write(struct file *file,
mutex_lock(&uci_handle->out_chan_lock);
while (!ret_val) {
ret_val = mhi_uci_send_packet(&uci_handle->out_handle,
- (void *)buf, count, 1);
+ buf, count);
if (ret_val < 0) {
uci_log(UCI_DBG_ERROR,
- "Error while writing data to MHI, chan %d, buf %p, size %d\n",
+ "Error while writing data to MHI, chan %d, buf %pK, size %d\n",
chan, (void *)buf, count);
ret_val = -EIO;
break;
@@ -732,6 +1052,8 @@ static ssize_t mhi_uci_client_write(struct file *file,
"No descriptors available, did we poll, chan %d?\n",
chan);
mutex_unlock(&uci_handle->out_chan_lock);
+ if (uci_handle->f_flags & (O_NONBLOCK | O_NDELAY))
+ return -EAGAIN;
ret_val = wait_event_interruptible(uci_handle->write_wq,
!mhi_dev_channel_isempty(
uci_handle->out_handle));
@@ -750,54 +1072,27 @@ static ssize_t mhi_uci_client_write(struct file *file,
static int uci_init_client_attributes(struct mhi_uci_ctxt_t *uci_ctxt)
{
- u32 i = 0;
- u32 data_size = TRB_MAX_DATA_SIZE;
- u32 index = 0;
+ u32 i;
+ u32 index;
struct uci_client *client;
- struct chan_attr *chan_attrib = NULL;
-
- for (i = 0; i < ARRAY_SIZE(uci_ctxt->chan_attrib); i++) {
- chan_attrib = &uci_ctxt->chan_attrib[i];
- switch (i) {
- case MHI_CLIENT_LOOPBACK_OUT:
- case MHI_CLIENT_LOOPBACK_IN:
- case MHI_CLIENT_SAHARA_OUT:
- case MHI_CLIENT_SAHARA_IN:
- case MHI_CLIENT_EFS_OUT:
- case MHI_CLIENT_EFS_IN:
- case MHI_CLIENT_MBIM_OUT:
- case MHI_CLIENT_MBIM_IN:
- case MHI_CLIENT_QMI_OUT:
- case MHI_CLIENT_QMI_IN:
- case MHI_CLIENT_IP_CTRL_0_OUT:
- case MHI_CLIENT_IP_CTRL_0_IN:
- case MHI_CLIENT_IP_CTRL_1_OUT:
- case MHI_CLIENT_IP_CTRL_1_IN:
- case MHI_CLIENT_DUN_OUT:
- case MHI_CLIENT_DUN_IN:
- chan_attrib->uci_ownership = 1;
- break;
- default:
- chan_attrib->uci_ownership = 0;
+ const struct chan_attr *chan_attrib;
+
+ for (i = 0; i < ARRAY_SIZE(uci_chan_attr_table); i += 2) {
+ chan_attrib = &uci_chan_attr_table[i];
+ if (chan_attrib->chan_id == MHI_CLIENT_INVALID)
break;
- }
- if (chan_attrib->uci_ownership) {
- chan_attrib->chan_id = i;
- chan_attrib->max_packet_size = data_size;
- index = CHAN_TO_CLIENT(i);
- client = &uci_ctxt->client_handles[index];
- chan_attrib->nr_trbs = 9;
- client->in_buf_list =
- kmalloc(sizeof(struct mhi_dev_iov) *
- chan_attrib->nr_trbs,
+ index = CHAN_TO_CLIENT(chan_attrib->chan_id);
+ client = &uci_ctxt->client_handles[index];
+ client->out_chan_attr = chan_attrib;
+ client->in_chan_attr = ++chan_attrib;
+ client->in_chan = index * 2;
+ client->out_chan = index * 2 + 1;
+ client->in_buf_list =
+ kcalloc(chan_attrib->nr_trbs,
+ sizeof(struct mhi_dev_iov),
GFP_KERNEL);
- if (NULL == client->in_buf_list)
- return -ENOMEM;
- }
- if (i % 2 == 0)
- chan_attrib->dir = MHI_DIR_OUT;
- else
- chan_attrib->dir = MHI_DIR_IN;
+ if (!client->in_buf_list)
+ return -ENOMEM;
}
return 0;
}
@@ -846,12 +1141,11 @@ static int mhi_register_client(struct uci_client *mhi_client, int index)
{
init_waitqueue_head(&mhi_client->read_wq);
init_waitqueue_head(&mhi_client->write_wq);
- mhi_client->out_chan = index * 2 + 1;
- mhi_client->in_chan = index * 2;
mhi_client->client_index = index;
mutex_init(&mhi_client->in_chan_lock);
mutex_init(&mhi_client->out_chan_lock);
+ spin_lock_init(&mhi_client->wr_req_lock);
uci_log(UCI_DBG_DBG, "Registering chan %d.\n", mhi_client->out_chan);
return 0;
@@ -949,16 +1243,14 @@ int mhi_uci_init(void)
uci_log(UCI_DBG_INFO, "Registering for MHI events.\n");
for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; i++) {
- if (uci_ctxt.chan_attrib[i * 2].uci_ownership) {
- mhi_client = &uci_ctxt.client_handles[i];
-
- r = mhi_register_client(mhi_client, i);
-
- if (r) {
- uci_log(UCI_DBG_CRITICAL,
- "Failed to reg client %d ret %d\n",
- r, i);
- }
+ mhi_client = &uci_ctxt.client_handles[i];
+ if (!mhi_client->in_chan_attr)
+ continue;
+ r = mhi_register_client(mhi_client, i);
+ if (r) {
+ uci_log(UCI_DBG_CRITICAL,
+ "Failed to reg client %d ret %d\n",
+ r, i);
}
}
@@ -992,29 +1284,30 @@ int mhi_uci_init(void)
uci_log(UCI_DBG_INFO, "Setting up device nodes.\n");
for (i = 0; i < MHI_SOFTWARE_CLIENT_LIMIT; i++) {
- if (uci_ctxt.chan_attrib[i*2].uci_ownership) {
- cdev_init(&uci_ctxt.cdev[i], &mhi_uci_client_fops);
- uci_ctxt.cdev[i].owner = THIS_MODULE;
- r = cdev_add(&uci_ctxt.cdev[i],
- uci_ctxt.start_ctrl_nr + i , 1);
- if (IS_ERR_VALUE(r)) {
- uci_log(UCI_DBG_ERROR,
- "Failed to add cdev %d, ret 0x%x\n",
- i, r);
- goto failed_char_add;
- }
+ mhi_client = &uci_ctxt.client_handles[i];
+ if (!mhi_client->in_chan_attr)
+ continue;
+ cdev_init(&uci_ctxt.cdev[i], &mhi_uci_client_fops);
+ uci_ctxt.cdev[i].owner = THIS_MODULE;
+ r = cdev_add(&uci_ctxt.cdev[i],
+ uci_ctxt.start_ctrl_nr + i, 1);
+ if (IS_ERR_VALUE(r)) {
+ uci_log(UCI_DBG_ERROR,
+ "Failed to add cdev %d, ret 0x%x\n",
+ i, r);
+ goto failed_char_add;
+ }
- uci_ctxt.client_handles[i].dev =
- device_create(uci_ctxt.mhi_uci_class, NULL,
- uci_ctxt.start_ctrl_nr + i,
- NULL, DEVICE_NAME "_pipe_%d",
- i * 2);
- if (IS_ERR(uci_ctxt.client_handles[i].dev)) {
- uci_log(UCI_DBG_ERROR,
- "Failed to add cdev %d\n", i);
- cdev_del(&uci_ctxt.cdev[i]);
- goto failed_device_create;
- }
+ uci_ctxt.client_handles[i].dev =
+ device_create(uci_ctxt.mhi_uci_class, NULL,
+ uci_ctxt.start_ctrl_nr + i,
+ NULL, DEVICE_NAME "_pipe_%d",
+ i * 2);
+ if (IS_ERR(uci_ctxt.client_handles[i].dev)) {
+ uci_log(UCI_DBG_ERROR,
+ "Failed to add cdev %d\n", i);
+ cdev_del(&uci_ctxt.cdev[i]);
+ goto failed_device_create;
}
}
diff --git a/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c b/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c
index 146d7c6d70a8..816b3be86a9f 100644
--- a/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c
+++ b/drivers/platform/msm/msm_bus/msm_bus_fabric_adhoc.c
@@ -1012,10 +1012,8 @@ static struct device *msm_bus_device_init(
bus_node = kzalloc(sizeof(struct msm_bus_node_device_type), GFP_KERNEL);
if (!bus_node) {
- MSM_BUS_ERR("%s:Bus node alloc failed\n", __func__);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
+ ret = -ENOMEM;
+ goto err_device_init;
}
bus_dev = &bus_node->dev;
device_initialize(bus_dev);
@@ -1023,47 +1021,37 @@ static struct device *msm_bus_device_init(
node_info = devm_kzalloc(bus_dev,
sizeof(struct msm_bus_node_info_type), GFP_KERNEL);
if (!node_info) {
- MSM_BUS_ERR("%s:Bus node info alloc failed\n", __func__);
- devm_kfree(bus_dev, bus_node);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
+ ret = -ENOMEM;
+ goto err_put_device;
}
bus_node->node_info = node_info;
bus_node->ap_owned = pdata->ap_owned;
bus_dev->of_node = pdata->of_node;
- if (msm_bus_copy_node_info(pdata, bus_dev) < 0) {
- devm_kfree(bus_dev, bus_node);
- devm_kfree(bus_dev, node_info);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
- }
+ ret = msm_bus_copy_node_info(pdata, bus_dev);
+ if (ret)
+ goto err_put_device;
bus_dev->bus = &msm_bus_type;
dev_set_name(bus_dev, bus_node->node_info->name);
ret = device_add(bus_dev);
- if (ret < 0) {
+ if (ret) {
MSM_BUS_ERR("%s: Error registering device %d",
__func__, pdata->node_info->id);
- devm_kfree(bus_dev, bus_node);
- devm_kfree(bus_dev, node_info->dev_connections);
- devm_kfree(bus_dev, node_info->connections);
- devm_kfree(bus_dev, node_info->black_connections);
- devm_kfree(bus_dev, node_info->black_listed_connections);
- devm_kfree(bus_dev, node_info);
- kfree(bus_dev);
- bus_dev = NULL;
- goto exit_device_init;
+ goto err_put_device;
}
device_create_file(bus_dev, &dev_attr_bw);
INIT_LIST_HEAD(&bus_node->devlist);
-
-exit_device_init:
return bus_dev;
+
+err_put_device:
+ put_device(bus_dev);
+ bus_dev = NULL;
+ kfree(bus_node);
+err_device_init:
+ return ERR_PTR(ret);
}
static int msm_bus_setup_dev_conn(struct device *bus_dev, void *data)
@@ -1258,10 +1246,10 @@ static int msm_bus_device_probe(struct platform_device *pdev)
node_dev = msm_bus_device_init(&pdata->info[i]);
- if (!node_dev) {
+ if (IS_ERR(node_dev)) {
MSM_BUS_ERR("%s: Error during dev init for %d",
__func__, pdata->info[i].node_info->id);
- ret = -ENXIO;
+ ret = PTR_ERR(node_dev);
goto exit_device_probe;
}
diff --git a/drivers/platform/msm/sps/sps.c b/drivers/platform/msm/sps/sps.c
index 03cc14aa7e29..2237db198c53 100644
--- a/drivers/platform/msm/sps/sps.c
+++ b/drivers/platform/msm/sps/sps.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -1006,8 +1006,6 @@ static void sps_device_de_init(void)
"sps:%s:BAMs are still registered", __func__);
sps_map_de_init();
-
- kfree(sps);
}
sps_mem_de_init();
@@ -2989,6 +2987,7 @@ static struct platform_driver msm_sps_driver = {
.name = SPS_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = msm_sps_match,
+ .suppress_bind_attrs = true,
},
.remove = msm_sps_remove,
};
diff --git a/drivers/platform/msm/ssm.c b/drivers/platform/msm/ssm.c
deleted file mode 100644
index 6a2909b8c5f4..000000000000
--- a/drivers/platform/msm/ssm.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/* Copyright (c) 2013-2014, 2016 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-/*
- * QTI Secure Service Module(SSM) driver
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "../../misc/qseecom_kernel.h"
-#include "ssm.h"
-
-/* Macros */
-#define SSM_DEV_NAME "ssm"
-#define MPSS_SUBSYS 0
-#define SSM_INFO_CMD_ID 1
-#define MAX_APP_NAME_SIZE 32
-#define SSM_MSG_LEN 200
-#define SSM_MSG_FIELD_LEN 11
-#define ATOM_MSG_LEN (SSM_MSG_FIELD_LEN + SSM_MSG_LEN + 40)
-
-#define TZAPP_NAME "SsmApp"
-#define CHANNEL_NAME "SSM_RTR_MODEM_APPS"
-
-/* SSM driver structure.*/
-struct ssm_driver {
- int32_t app_status;
- int32_t update_status;
- unsigned char *channel_name;
- unsigned char *smd_buffer;
- struct device *dev;
- smd_channel_t *ch;
- struct work_struct ipc_work;
- struct mutex mutex;
- struct qseecom_handle *qseecom_handle;
- struct tzapp_get_mode_info_rsp *resp;
- bool key_status;
- bool ready;
-};
-
-static struct ssm_driver *ssm_drv;
-
-static unsigned int getint(char *buff, unsigned long *res)
-{
- char value[SSM_MSG_FIELD_LEN];
-
- memcpy(value, buff, SSM_MSG_FIELD_LEN);
- value[SSM_MSG_FIELD_LEN - 1] = '\0';
-
- return kstrtoul(skip_spaces(value), 10, res);
-}
-
-/*
- * Setup CMD/RSP pointers.
- */
-static void setup_cmd_rsp_buffers(struct qseecom_handle *handle, void **cmd,
- int *cmd_len, void **resp, int *resp_len)
-{
- *cmd = handle->sbuf;
- if (*cmd_len & QSEECOM_ALIGN_MASK)
- *cmd_len = QSEECOM_ALIGN(*cmd_len);
-
- *resp = handle->sbuf + *cmd_len;
- if (*resp_len & QSEECOM_ALIGN_MASK)
- *resp_len = QSEECOM_ALIGN(*resp_len);
-}
-
-/*
- * Send packet to modem over SMD channel.
- */
-static int update_modem(enum ssm_ipc_req ipc_req, struct ssm_driver *ssm,
- int length, char *data)
-{
- unsigned int packet_len = length + SSM_MSG_FIELD_LEN;
- int rc = 0, count;
-
- snprintf(ssm->smd_buffer, SSM_MSG_FIELD_LEN + 1, "%10u|", ipc_req);
- memcpy(ssm->smd_buffer + SSM_MSG_FIELD_LEN, data, length);
-
- if (smd_write_avail(ssm->ch) < packet_len) {
- dev_err(ssm->dev, "Not enough space dropping request\n");
- rc = -ENOSPC;
- goto out;
- }
-
- count = smd_write(ssm->ch, ssm->smd_buffer, packet_len);
- if (count < packet_len) {
- dev_err(ssm->dev, "smd_write failed for %d\n", ipc_req);
- rc = -EIO;
- }
-
-out:
- return rc;
-}
-
-/*
- * Header Format
- * Each member of header is of 10 byte (ASCII).
- * Each entry is separated by '|' delimiter.
- * |<-10 bytes->|<-10 bytes->|
- * |-------------------------|
- * | IPC code | error code |
- * |-------------------------|
- *
- */
-static int decode_packet(char *buffer, struct ssm_common_msg *pkt)
-{
- int rc;
-
- rc = getint(buffer, (unsigned long *)&pkt->ipc_req);
- if (rc < 0)
- return -EINVAL;
-
- buffer += SSM_MSG_FIELD_LEN;
- rc = getint(buffer, (unsigned long *)&pkt->err_code);
- if (rc < 0)
- return -EINVAL;
-
- dev_dbg(ssm_drv->dev, "req %d error code %d\n",
- pkt->ipc_req, pkt->err_code);
- return 0;
-}
-
-static void process_message(struct ssm_common_msg pkt, struct ssm_driver *ssm)
-{
-
- switch (pkt.ipc_req) {
-
- case SSM_MTOA_MODE_UPDATE_STATUS:
- if (pkt.err_code) {
- dev_err(ssm->dev, "Modem mode update failed\n");
- ssm->update_status = FAILED;
- } else
- ssm->update_status = SUCCESS;
-
- dev_dbg(ssm->dev, "Modem mode update status %d\n",
- pkt.err_code);
- break;
-
- default:
- dev_dbg(ssm->dev, "Invalid message\n");
- break;
- };
-}
-
-/*
- * Work function to handle and process packets coming from modem.
- */
-static void ssm_app_modem_work_fn(struct work_struct *work)
-{
- int sz, rc;
- struct ssm_common_msg pkt;
- struct ssm_driver *ssm;
-
- ssm = container_of(work, struct ssm_driver, ipc_work);
-
- mutex_lock(&ssm->mutex);
- sz = smd_cur_packet_size(ssm->ch);
- if ((sz < SSM_MSG_FIELD_LEN) || (sz > ATOM_MSG_LEN)) {
- dev_dbg(ssm_drv->dev, "Garbled message size\n");
- goto unlock;
- }
-
- if (smd_read_avail(ssm->ch) < sz) {
- dev_err(ssm_drv->dev, "SMD error data in channel\n");
- goto unlock;
- }
-
- if (smd_read(ssm->ch, ssm->smd_buffer, sz) != sz) {
- dev_err(ssm_drv->dev, "Incomplete data\n");
- goto unlock;
- }
-
- rc = decode_packet(ssm->smd_buffer, &pkt);
- if (rc < 0) {
- dev_err(ssm_drv->dev, "Corrupted header\n");
- goto unlock;
- }
-
- process_message(pkt, ssm);
-
-unlock:
- mutex_unlock(&ssm->mutex);
-}
-
-/*
- * MODEM-APPS smd channel callback function.
- */
-static void modem_request(void *ctxt, unsigned event)
-{
- struct ssm_driver *ssm;
-
- ssm = (struct ssm_driver *)ctxt;
-
- switch (event) {
- case SMD_EVENT_OPEN:
- case SMD_EVENT_CLOSE:
- dev_dbg(ssm->dev, "SMD port status changed\n");
- break;
- case SMD_EVENT_DATA:
- if (smd_read_avail(ssm->ch) > 0)
- schedule_work(&ssm->ipc_work);
- break;
- };
-}
-
-/*
- * Load SSM application in TZ and start application:
- */
-static int ssm_load_app(struct ssm_driver *ssm)
-{
- int rc;
-
- /* Load the APP */
- rc = qseecom_start_app(&ssm->qseecom_handle, TZAPP_NAME, SZ_4K);
- if (rc < 0) {
- dev_err(ssm->dev, "Unable to load SSM app\n");
- ssm->app_status = FAILED;
- return -EIO;
- }
-
- ssm->app_status = SUCCESS;
- return 0;
-}
-
-static struct ssm_platform_data *populate_ssm_pdata(struct device *dev)
-{
- struct ssm_platform_data *pdata;
-
- pdata = devm_kzalloc(dev, sizeof(struct ssm_platform_data),
- GFP_KERNEL);
- if (!pdata)
- return NULL;
-
- pdata->need_key_exchg =
- of_property_read_bool(dev->of_node, "qcom,need-keyexhg");
-
- pdata->channel_name = CHANNEL_NAME;
-
- return pdata;
-}
-
-static int ssm_probe(struct platform_device *pdev)
-{
- int rc;
- struct ssm_platform_data *pdata;
- struct ssm_driver *drv;
-
- if (pdev->dev.of_node)
- pdata = populate_ssm_pdata(&pdev->dev);
- else
- pdata = pdev->dev.platform_data;
-
- if (!pdata) {
- dev_err(&pdev->dev, "Empty platform data\n");
- return -ENOMEM;
- }
-
- drv = devm_kzalloc(&pdev->dev, sizeof(struct ssm_driver),
- GFP_KERNEL);
- if (!drv)
- return -ENOMEM;
-
- /* Allocate response buffer */
- drv->resp = devm_kzalloc(&pdev->dev,
- sizeof(struct tzapp_get_mode_info_rsp),
- GFP_KERNEL);
- if (!drv->resp) {
- devm_kfree(&pdev->dev, drv);
- rc = -ENOMEM;
- goto exit;
- }
-
- /* Initialize the driver structure */
- drv->app_status = RETRY;
- drv->ready = false;
- drv->update_status = FAILED;
- mutex_init(&drv->mutex);
- drv->key_status = !pdata->need_key_exchg;
- drv->channel_name = (char *)pdata->channel_name;
- INIT_WORK(&drv->ipc_work, ssm_app_modem_work_fn);
-
- /* Allocate memory for smd buffer */
- drv->smd_buffer = devm_kzalloc(&pdev->dev,
- (sizeof(char) * ATOM_MSG_LEN), GFP_KERNEL);
- if (!drv->smd_buffer) {
- devm_kfree(&pdev->dev, drv->resp);
- devm_kfree(&pdev->dev, drv);
- rc = -ENOMEM;
- goto exit;
- }
-
- drv->dev = &pdev->dev;
- ssm_drv = drv;
- platform_set_drvdata(pdev, ssm_drv);
-
- dev_dbg(&pdev->dev, "probe success\n");
- return 0;
-
-exit:
- mutex_destroy(&drv->mutex);
- platform_set_drvdata(pdev, NULL);
- return rc;
-
-}
-
-static int ssm_remove(struct platform_device *pdev)
-{
-
- if (!ssm_drv)
- return 0;
- /*
- * Step to exit
- * 1. set ready to 0 (oem access closed).
- * 2. Close SMD modem connection closed.
- * 3. cleanup ion.
- */
- ssm_drv->ready = false;
- smd_close(ssm_drv->ch);
- flush_work(&ssm_drv->ipc_work);
-
- /* Shutdown tzapp */
- dev_dbg(&pdev->dev, "Shutting down TZapp\n");
- qseecom_shutdown_app(&ssm_drv->qseecom_handle);
-
- /* freeing the memory allocations
- for the driver and the buffer */
- devm_kfree(&pdev->dev, ssm_drv->smd_buffer);
- devm_kfree(&pdev->dev, ssm_drv->resp);
- devm_kfree(&pdev->dev, ssm_drv);
-
- return 0;
-}
-
-static struct of_device_id ssm_match_table[] = {
- {
- .compatible = "qcom,ssm",
- },
- {}
-};
-
-static struct platform_driver ssm_pdriver = {
- .probe = ssm_probe,
- .remove = ssm_remove,
- .driver = {
- .name = SSM_DEV_NAME,
- .owner = THIS_MODULE,
- .of_match_table = ssm_match_table,
- },
-};
-module_platform_driver(ssm_pdriver);
-
-/*
- * Interface for external OEM driver.
- * This interface supports following functionalities:
- * 1. Set mode (encrypted mode and it's length is passed as parameter).
- * 2. Set mode from TZ (read encrypted mode from TZ)
- * 3. Get status of mode update.
- *
- */
-int ssm_oem_driver_intf(int cmd, char *mode, int len)
-{
- int rc, req_len, resp_len;
- struct tzapp_get_mode_info_req *get_mode_req;
- struct tzapp_get_mode_info_rsp *get_mode_resp;
-
- /* If ssm_drv is NULL, probe failed */
- if (!ssm_drv)
- return -ENODEV;
-
- mutex_lock(&ssm_drv->mutex);
-
- if (ssm_drv->app_status == RETRY) {
- /* Load TZAPP */
- rc = ssm_load_app(ssm_drv);
- if (rc) {
- rc = -ENODEV;
- goto unlock;
- }
- } else if (ssm_drv->app_status == FAILED) {
- rc = -ENODEV;
- goto unlock;
- }
-
- /* Open modem SMD interface */
- if (!ssm_drv->ready) {
- rc = smd_named_open_on_edge(ssm_drv->channel_name,
- SMD_APPS_MODEM,
- &ssm_drv->ch,
- ssm_drv,
- modem_request);
- if (rc) {
- rc = -EAGAIN;
- goto unlock;
- } else
- ssm_drv->ready = true;
- }
-
- /* Try again modem key-exchange not yet done.*/
- if (!ssm_drv->key_status) {
- rc = -EAGAIN;
- goto unlock;
- }
-
- /* Set return status to success */
- rc = 0;
-
- switch (cmd) {
- case SSM_READY:
- break;
-
- case SSM_MODE_INFO_READY:
- ssm_drv->update_status = RETRY;
- /* Fill command structure */
- req_len = sizeof(struct tzapp_get_mode_info_req);
- resp_len = sizeof(struct tzapp_get_mode_info_rsp);
- setup_cmd_rsp_buffers(ssm_drv->qseecom_handle,
- (void **)&get_mode_req, &req_len,
- (void **)&get_mode_resp, &resp_len);
- get_mode_req->tzapp_ssm_cmd = GET_ENC_MODE;
-
- rc = qseecom_set_bandwidth(ssm_drv->qseecom_handle, 1);
- if (rc) {
- ssm_drv->update_status = FAILED;
- dev_err(ssm_drv->dev, "set bandwidth failed\n");
- rc = -EIO;
- break;
- }
- rc = qseecom_send_command(ssm_drv->qseecom_handle,
- (void *)get_mode_req, req_len,
- (void *)get_mode_resp, resp_len);
- if (rc || get_mode_resp->status) {
- ssm_drv->update_status = FAILED;
- break;
- }
- rc = qseecom_set_bandwidth(ssm_drv->qseecom_handle, 0);
- if (rc) {
- ssm_drv->update_status = FAILED;
- dev_err(ssm_drv->dev, "clear bandwidth failed\n");
- rc = -EIO;
- break;
- }
-
- if (get_mode_resp->enc_mode_len > ENC_MODE_MAX_SIZE) {
- ssm_drv->update_status = FAILED;
- rc = -EINVAL;
- break;
- }
- /* Send mode_info to modem */
- rc = update_modem(SSM_ATOM_MODE_UPDATE, ssm_drv,
- get_mode_resp->enc_mode_len,
- get_mode_resp->enc_mode_info);
- if (rc)
- ssm_drv->update_status = FAILED;
- break;
-
- case SSM_SET_MODE:
- ssm_drv->update_status = RETRY;
-
- if (len > ENC_MODE_MAX_SIZE) {
- ssm_drv->update_status = FAILED;
- rc = -EINVAL;
- break;
- }
- memcpy(ssm_drv->resp->enc_mode_info, mode, len);
- ssm_drv->resp->enc_mode_len = len;
-
- /* Send mode_info to modem */
- rc = update_modem(SSM_ATOM_MODE_UPDATE, ssm_drv,
- ssm_drv->resp->enc_mode_len,
- ssm_drv->resp->enc_mode_info);
- if (rc)
- ssm_drv->update_status = FAILED;
- break;
-
- case SSM_GET_MODE_STATUS:
- rc = ssm_drv->update_status;
- break;
-
- default:
- rc = -EINVAL;
- dev_err(ssm_drv->dev, "Invalid command\n");
- break;
- };
-
-unlock:
- mutex_unlock(&ssm_drv->mutex);
- return rc;
-}
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("QTI Secure Service Module");
-
diff --git a/drivers/platform/msm/ssm.h b/drivers/platform/msm/ssm.h
deleted file mode 100644
index ee4f1bc1d83f..000000000000
--- a/drivers/platform/msm/ssm.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* Copyright (c) 2013-2014, 2016 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __SSM_H_
-#define __SSM_H_
-
-#define MAX_APP_NAME_SIZE 32
-#define ENC_MODE_MAX_SIZE 200
-
-/* tzapp response.*/
-enum tz_response {
- RESULT_SUCCESS = 0,
- RESULT_FAILURE = 0xFFFFFFFF,
-};
-
-/* tzapp command list.*/
-enum tz_commands {
- ENC_MODE,
- GET_ENC_MODE,
- KEY_EXCHANGE = 11,
-};
-
-/* MODEM/SSM command list.*/
-enum ssm_ipc_req {
- SSM_IPC_MIN = 0x0000AAAB,
- SSM_ATOM_MODE_UPDATE,
- SSM_MTOA_MODE_UPDATE_STATUS = SSM_IPC_MIN + 4,
- SSM_INVALID_REQ,
-};
-
-/* OEM request commands list.*/
-enum oem_req {
- SSM_READY,
- SSM_MODE_INFO_READY,
- SSM_SET_MODE,
- SSM_GET_MODE_STATUS,
- SSM_INVALID,
-};
-
-/* Modem mode update status.*/
-enum modem_mode_status {
- SUCCESS,
- RETRY,
- FAILED = -1,
-};
-
-/* tzapp encode mode request.*/
-__packed struct tzapp_mode_enc_req {
- uint32_t tzapp_ssm_cmd;
- uint8_t mode_info[4];
-};
-
-/* tzapp encode mode response.*/
-__packed struct tzapp_mode_enc_rsp {
- uint32_t tzapp_ssm_cmd;
- uint8_t enc_mode_info[ENC_MODE_MAX_SIZE];
- uint32_t enc_mode_len;
- uint32_t status;
-};
-
-/* tzapp get mode request.*/
-__packed struct tzapp_get_mode_info_req {
- uint32_t tzapp_ssm_cmd;
-};
-
-/* tzapp get mode response.*/
-__packed struct tzapp_get_mode_info_rsp {
- uint32_t tzapp_ssm_cmd;
- uint8_t enc_mode_info[ENC_MODE_MAX_SIZE];
- uint32_t enc_mode_len;
- uint32_t status;
-};
-
-/* Modem/SSM packet format.*/
-struct ssm_common_msg {
- enum ssm_ipc_req ipc_req;
- int err_code;
-
-};
-
-#endif
diff --git a/drivers/power/qpnp-smbcharger.c b/drivers/power/qpnp-smbcharger.c
index 546581c80688..03cb261ec855 100644
--- a/drivers/power/qpnp-smbcharger.c
+++ b/drivers/power/qpnp-smbcharger.c
@@ -43,6 +43,11 @@
#include
#include
#include
+
+#ifdef CONFIG_FORCE_FAST_CHARGE
+#include
+#endif
+
#if defined(CONFIG_FB)
#include
#include
@@ -2099,7 +2104,11 @@ static int smbchg_set_usb_current_max(struct smbchg_chip *chip,
}
chip->usb_max_current_ma = 500;
}
+#ifdef CONFIG_FORCE_FAST_CHARGE
+ if ((force_fast_charge > 0 && current_ma == CURRENT_500_MA) || current_ma == CURRENT_900_MA) {
+#else
if (current_ma == CURRENT_900_MA) {
+#endif
rc = smbchg_sec_masked_write(chip,
chip->usb_chgpth_base + CHGPTH_CFG,
CFG_USB_2_3_SEL_BIT, CFG_USB_3);
diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
index f8a76090cbca..52d023514560 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -88,6 +88,7 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
case PTP_PF_PHYSYNC:
if (chan != 0)
return -EINVAL;
+ break;
default:
return -EINVAL;
}
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index cb75133085a8..acc9987475f5 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -384,6 +384,8 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
aqcsfrc_mask = AQCSFRC_CSFA_MASK;
}
+ /* Update shadow register first before modifying active register */
+ ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
/*
* Changes to immediate action on Action Qualifier. This puts
* Action Qualifier control on PWM output from next TBCLK
diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c
index c879dff597ee..eceb75105c08 100644
--- a/drivers/regulator/pfuze100-regulator.c
+++ b/drivers/regulator/pfuze100-regulator.c
@@ -142,6 +142,7 @@ static struct regulator_ops pfuze100_sw_regulator_ops = {
static struct regulator_ops pfuze100_swb_regulator_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
+ .is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index 11572354ce66..95d15411a455 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -381,6 +381,11 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
int err;
+ if (!rtc->ops)
+ return -ENODEV;
+ else if (!rtc->ops->set_alarm)
+ return -EINVAL;
+
err = rtc_valid_tm(&alarm->time);
if (err != 0)
return err;
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index fb7298920c8c..90f93c2be8cd 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -640,21 +640,20 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
unsigned long phys_aob = 0;
if (!q->use_cq)
- goto out;
+ return 0;
if (!q->aobs[bufnr]) {
struct qaob *aob = qdio_allocate_aob();
q->aobs[bufnr] = aob;
}
if (q->aobs[bufnr]) {
- q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE;
q->sbal_state[bufnr].aob = q->aobs[bufnr];
q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
phys_aob = virt_to_phys(q->aobs[bufnr]);
WARN_ON_ONCE(phys_aob & 0xFF);
}
-out:
+ q->sbal_state[bufnr].flags = 0;
return phys_aob;
}
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 6adf9abdf955..632295144766 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -901,6 +901,11 @@ static int twa_chrdev_open(struct inode *inode, struct file *file)
unsigned int minor_number;
int retval = TW_IOCTL_ERROR_OS_ENODEV;
+ if (!capable(CAP_SYS_ADMIN)) {
+ retval = -EACCES;
+ goto out;
+ }
+
minor_number = iminor(inode);
if (minor_number >= twa_device_extension_count)
goto out;
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index b327742b95ef..c1e1051f94cc 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1047,6 +1047,9 @@ static int tw_chrdev_open(struct inode *inode, struct file *file)
dprintk(KERN_WARNING "3w-xxxx: tw_ioctl_open()\n");
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
minor_number = iminor(inode);
if (minor_number >= tw_device_extension_count)
return -ENODEV;
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 34a1b1f333b4..d5184aa1ace4 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -752,9 +752,9 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
case ELS_LOGO:
if (fip->mode == FIP_MODE_VN2VN) {
if (fip->state != FIP_ST_VNMP_UP)
- return -EINVAL;
+ goto drop;
if (ntoh24(fh->fh_d_id) == FC_FID_FLOGI)
- return -EINVAL;
+ goto drop;
} else {
if (fip->state != FIP_ST_ENABLED)
return 0;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 9ca83ebef776..857bf9417817 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -283,11 +283,11 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
*/
if (opcode != ISCSI_OP_SCSI_DATA_OUT) {
iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x/%x itt "
+ "task [op %x itt "
"0x%x/0x%x] "
"rejected.\n",
- task->hdr->opcode, opcode,
- task->itt, task->hdr_itt);
+ opcode, task->itt,
+ task->hdr_itt);
return -EACCES;
}
/*
@@ -296,10 +296,10 @@ static int iscsi_check_tmf_restrictions(struct iscsi_task *task, int opcode)
*/
if (conn->session->fast_abort) {
iscsi_conn_printk(KERN_INFO, conn,
- "task [op %x/%x itt "
+ "task [op %x itt "
"0x%x/0x%x] fast abort.\n",
- task->hdr->opcode, opcode,
- task->itt, task->hdr_itt);
+ opcode, task->itt,
+ task->hdr_itt);
return -EACCES;
}
break;
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 2485255f3414..a8e6e32639ae 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -4200,6 +4200,9 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
int irq, i, j;
int error = -ENODEV;
+ if (hba_count >= MAX_CONTROLLERS)
+ goto out;
+
if (pci_enable_device(pdev))
goto out;
pci_set_master(pdev);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 99bdccf92136..6191c300faff 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -325,11 +325,10 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint32_t lun,
wait_for_completion(&tm_iocb->u.tmf.comp);
- rval = tm_iocb->u.tmf.comp_status == CS_COMPLETE ?
- QLA_SUCCESS : QLA_FUNCTION_FAILED;
+ rval = tm_iocb->u.tmf.data;
- if ((rval != QLA_SUCCESS) || tm_iocb->u.tmf.data) {
- ql_dbg(ql_dbg_taskm, vha, 0x8030,
+ if (rval != QLA_SUCCESS) {
+ ql_log(ql_log_warn, vha, 0x8030,
"TM IOCB failed (%x).\n", rval);
}
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 26223ff51e66..7bc28c8d2832 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -5000,8 +5000,9 @@ qla2x00_do_dpc(void *data)
}
}
- if (test_and_clear_bit(ISP_ABORT_NEEDED,
- &base_vha->dpc_flags)) {
+ if (test_and_clear_bit
+ (ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
+ !test_bit(UNLOADING, &base_vha->dpc_flags)) {
ql_dbg(ql_dbg_dpc, base_vha, 0x4007,
"ISP abort scheduled.\n");
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 46b9f39afe63..b0aa970fb999 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -676,8 +676,24 @@ static ssize_t
sdev_store_delete(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- if (device_remove_file_self(dev, attr))
- scsi_remove_device(to_scsi_device(dev));
+ struct kernfs_node *kn;
+
+ kn = sysfs_break_active_protection(&dev->kobj, &attr->attr);
+ WARN_ON_ONCE(!kn);
+ /*
+ * Concurrent writes into the "delete" sysfs attribute may trigger
+ * concurrent calls to device_remove_file() and scsi_remove_device().
+ * device_remove_file() handles concurrent removal calls by
+ * serializing these and by ignoring the second and later removal
+ * attempts. Concurrent calls of scsi_remove_device() are
+ * serialized. The second and later calls of scsi_remove_device() are
+ * ignored because the first call of that function changes the device
+ * state into SDEV_DEL.
+ */
+ device_remove_file(dev, attr);
+ scsi_remove_device(to_scsi_device(dev));
+ if (kn)
+ sysfs_unbreak_active_protection(kn);
return count;
};
static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 8ae1d31a7337..160b9296ad18 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -2243,6 +2243,7 @@ sg_add_sfp(Sg_device * sdp)
write_lock_irqsave(&sdp->sfd_lock, iflags);
if (atomic_read(&sdp->detaching)) {
write_unlock_irqrestore(&sdp->sfd_lock, iflags);
+ kfree(sfp);
return ERR_PTR(-ENODEV);
}
list_add_tail(&sfp->sfd_siblings, &sdp->sfds);
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 1a7154249e23..d5dd70049f81 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -567,9 +567,14 @@ static void pvscsi_complete_request(struct pvscsi_adapter *adapter,
(btstat == BTSTAT_SUCCESS ||
btstat == BTSTAT_LINKED_COMMAND_COMPLETED ||
btstat == BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG)) {
- cmd->result = (DID_OK << 16) | sdstat;
- if (sdstat == SAM_STAT_CHECK_CONDITION && cmd->sense_buffer)
- cmd->result |= (DRIVER_SENSE << 24);
+ if (sdstat == SAM_STAT_COMMAND_TERMINATED) {
+ cmd->result = (DID_RESET << 16);
+ } else {
+ cmd->result = (DID_OK << 16) | sdstat;
+ if (sdstat == SAM_STAT_CHECK_CONDITION &&
+ cmd->sense_buffer)
+ cmd->result |= (DRIVER_SENSE << 24);
+ }
} else
switch (btstat) {
case BTSTAT_SUCCESS:
diff --git a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c
index 91395fdff16a..81b38023f70f 100644
--- a/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c
+++ b/drivers/soc/qcom/qdsp6v2/msm_audio_ion.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2017, 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
@@ -44,6 +44,7 @@
#define MSM_AUDIO_SMMU_SID_OFFSET 32
#define TZBSP_MEM_PROTECT_AUDIO_CMD_ID 0x00000005
+#define TZBSP_MEM_PROTECT_AUDIO_CMD_ID_2 0x00000006
struct addr_range {
dma_addr_t start;
@@ -811,11 +812,12 @@ u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa)
return upper_32_bits(pa);
}
-static void msm_audio_protect_memory_region(struct device *dev)
+static int msm_audio_protect_memory_region(struct device *dev)
{
int ret = 0;
unsigned long size = 0;
phys_addr_t phys_addr = 0;
+ struct scm_desc desc2 = {0};
struct tz_mem_protect_cmd_buf desc = {0};
struct tz_resp resp = {0};
@@ -825,13 +827,24 @@ static void msm_audio_protect_memory_region(struct device *dev)
pr_debug("%s: cma_audio_mem_addr %pK with size %lu\n",
__func__, &phys_addr, size);
- desc.phys_addr = phys_addr;
- desc.size = size;
- ret = scm_call(SCM_SVC_MP, TZBSP_MEM_PROTECT_AUDIO_CMD_ID,
- (void *)&desc , sizeof(desc), (void *)&resp, sizeof(resp));
+ desc2.args[0] = desc.phys_addr = phys_addr;
+ desc2.args[1] = desc.size = size;
+ desc2.arginfo = SCM_ARGS(2);
+ if (!is_scm_armv8()) {
+ ret = scm_call(SCM_SVC_MP, TZBSP_MEM_PROTECT_AUDIO_CMD_ID,
+ (void *)&desc , sizeof(desc),
+ (void *)&resp, sizeof(resp));
+ } else {
+ ret = scm_call2(SCM_SIP_FNID(SCM_SVC_MP,
+ TZBSP_MEM_PROTECT_AUDIO_CMD_ID_2), &desc2);
+ resp.ret = desc2.ret[0];
+ }
if (ret < 0)
pr_err("%s: SCM call failed, scm_call_ret %d tz_resp %d\n",
__func__, ret, resp.ret);
+ if (!is_scm_armv8())
+ return ret;
+ return desc2.ret[0];
}
static int msm_audio_ion_probe(struct platform_device *pdev)
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 63700ab7bd9f..1107a5d5a256 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -230,7 +230,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
}
/* program delay transfers if tx_delay is non zero */
- if (spicfg->wdelay)
+ if (spicfg && spicfg->wdelay)
spidat1 |= SPIDAT1_WDEL;
/*
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index a7998777b8cc..80fef8a76026 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -404,7 +404,8 @@ static void ion_handle_get(struct ion_handle *handle)
}
/* Must hold the client lock */
-static struct ion_handle* ion_handle_get_check_overflow(struct ion_handle *handle)
+static struct ion_handle *ion_handle_get_check_overflow(
+ struct ion_handle *handle)
{
if (atomic_read(&handle->ref.refcount) + 1 == 0)
return ERR_PTR(-EOVERFLOW);
diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c
index 10e8a73cee3c..4d158a7134c1 100644
--- a/drivers/staging/android/ion/ion_system_heap.c
+++ b/drivers/staging/android/ion/ion_system_heap.c
@@ -2,7 +2,7 @@
* drivers/staging/android/ion/ion_system_heap.c
*
* Copyright (C) 2011 Google, Inc.
- * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -619,8 +619,10 @@ static void ion_system_heap_destroy_pools(struct ion_page_pool **pools)
{
int i;
for (i = 0; i < num_orders; i++)
- if (pools[i])
+ if (pools[i]) {
ion_page_pool_destroy(pools[i]);
+ pools[i] = NULL;
+ }
}
/**
diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c
index 4662e00b456a..62fdd670509c 100644
--- a/drivers/staging/imx-drm/imx-ldb.c
+++ b/drivers/staging/imx-drm/imx-ldb.c
@@ -460,6 +460,9 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
return PTR_ERR(imx_ldb->regmap);
}
+ /* disable LDB by resetting the control register to POR default */
+ regmap_write(imx_ldb->regmap, IOMUXC_GPR2, 0);
+
imx_ldb->dev = dev;
if (of_id)
@@ -497,14 +500,14 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
if (ret || i < 0 || i > 1)
return -EINVAL;
+ if (!of_device_is_available(child))
+ continue;
+
if (dual && i > 0) {
dev_warn(dev, "dual-channel mode, ignoring second output\n");
continue;
}
- if (!of_device_is_available(child))
- continue;
-
channel = &imx_ldb->channel[i];
channel->ldb = imx_ldb;
channel->chno = i;
diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c
index 5d6250337fec..4f84de43de7c 100644
--- a/drivers/staging/media/omap4iss/iss_video.c
+++ b/drivers/staging/media/omap4iss/iss_video.c
@@ -11,7 +11,6 @@
* (at your option) any later version.
*/
-#include
#include
#include
#include
@@ -22,6 +21,8 @@
#include
#include
+#include
+
#include "iss_video.h"
#include "iss.h"
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
index a2cc5f834c63..ed18a98a15d8 100644
--- a/drivers/tty/hvc/hvc_opal.c
+++ b/drivers/tty/hvc/hvc_opal.c
@@ -337,7 +337,6 @@ static void udbg_init_opal_common(void)
udbg_putc = udbg_opal_putc;
udbg_getc = udbg_opal_getc;
udbg_getc_poll = udbg_opal_getc_poll;
- tb_ticks_per_usec = 0x200; /* Make udelay not suck */
}
void __init hvc_opal_init_early(void)
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 5222805bfb15..07428642821d 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -114,16 +114,19 @@ static int pty_space(struct tty_struct *to)
static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
{
struct tty_struct *to = tty->link;
+ unsigned long flags;
if (tty->stopped)
return 0;
if (c > 0) {
+ spin_lock_irqsave(&to->port->lock, flags);
/* Stuff the data into the input queue of the other end */
c = tty_insert_flip_string(to->port, buf, c);
/* And shovel */
if (c)
tty_flip_buffer_push(to->port);
+ spin_unlock_irqrestore(&to->port->lock, flags);
}
return c;
}
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 5c247d7943aa..077e0667bbf8 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -202,7 +202,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
unsigned int rate;
int ret;
- if (IS_ERR(d->clk) || !old)
+ if (IS_ERR(d->clk))
goto out;
/* Not requesting clock rates below 1.8432Mhz */
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index e01d39509172..fabf77fca4ad 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1785,6 +1785,9 @@ static const struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x09d8, 0x0320), /* Elatec GmbH TWN3 */
.driver_info = NO_UNION_NORMAL, /* has misplaced union descriptor */
},
+ { USB_DEVICE(0x0ca6, 0xa050), /* Castles VEGA3000 */
+ .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
+ },
{ USB_DEVICE(0x2912, 0x0001), /* ATOL FPrint */
.driver_info = CLEAR_HALT_CONDITIONS,
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 20000128b06c..1791e6d68f12 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -643,18 +643,21 @@ void usb_destroy_configuration(struct usb_device *dev)
return;
if (dev->rawdescriptors) {
- for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+ for (i = 0; i < dev->descriptor.bNumConfigurations &&
+ i < USB_MAXCONFIG; i++)
kfree(dev->rawdescriptors[i]);
kfree(dev->rawdescriptors);
dev->rawdescriptors = NULL;
}
- for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+ for (c = 0; c < dev->descriptor.bNumConfigurations &&
+ c < USB_MAXCONFIG; c++) {
struct usb_host_config *cf = &dev->config[c];
kfree(cf->string);
- for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+ for (i = 0; i < cf->desc.bNumInterfaces &&
+ i < USB_MAXINTERFACES; i++) {
if (cf->intf_cache[i])
kref_put(&cf->intf_cache[i]->ref,
usb_release_interface_cache);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b5e5e5911a6f..e5d045756a8b 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1201,10 +1201,14 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
if (!udev || udev->state == USB_STATE_NOTATTACHED) {
/* Tell hub_wq to disconnect the device or
- * check for a new connection
+ * check for a new connection or over current condition.
+ * Based on USB2.0 Spec Section 11.12.5,
+ * C_PORT_OVER_CURRENT could be set while
+ * PORT_OVER_CURRENT is not. So check for any of them.
*/
if (udev || (portstatus & USB_PORT_STAT_CONNECTION) ||
- (portstatus & USB_PORT_STAT_OVERCURRENT))
+ (portstatus & USB_PORT_STAT_OVERCURRENT) ||
+ (portchange & USB_PORT_STAT_C_OVERCURRENT))
set_bit(port1, hub->change_bits);
} else if (portstatus & USB_PORT_STAT_ENABLE) {
@@ -3337,6 +3341,10 @@ static int wait_for_ss_port_enable(struct usb_device *udev,
while (delay_ms < 2000) {
if (status || *portstatus & USB_PORT_STAT_CONNECTION)
break;
+ if (!port_is_power_on(hub, *portstatus)) {
+ status = -ENODEV;
+ break;
+ }
msleep(20);
delay_ms += 20;
status = hub_port_status(hub, *port1, portstatus, portchange);
diff --git a/drivers/usb/dwc2/hcd_intr.c b/drivers/usb/dwc2/hcd_intr.c
index 551ba878b003..e1675ea36a63 100644
--- a/drivers/usb/dwc2/hcd_intr.c
+++ b/drivers/usb/dwc2/hcd_intr.c
@@ -913,9 +913,8 @@ static int dwc2_xfercomp_isoc_split_in(struct dwc2_hsotg *hsotg,
frame_desc = &qtd->urb->iso_descs[qtd->isoc_frame_index];
len = dwc2_get_actual_xfer_length(hsotg, chan, chnum, qtd,
DWC2_HC_XFER_COMPLETE, NULL);
- if (!len) {
+ if (!len && !qtd->isoc_split_offset) {
qtd->complete_split = 0;
- qtd->isoc_split_offset = 0;
return 0;
}
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index e216c58779cf..af4e2f204a30 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1761,6 +1761,8 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
value = 0;
break;
}
+
+ spin_lock(&cdev->lock);
value = f->set_alt(f, w_index, w_value);
if (value == USB_GADGET_DELAYED_STATUS) {
DBG(cdev,
@@ -1770,6 +1772,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
DBG(cdev, "delayed_status count %d\n",
cdev->delayed_status);
}
+ spin_unlock(&cdev->lock);
break;
case USB_REQ_GET_INTERFACE:
if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
index 424e2902423b..9d87c172bc3c 100644
--- a/drivers/usb/gadget/function/f_fs.c
+++ b/drivers/usb/gadget/function/f_fs.c
@@ -3175,7 +3175,7 @@ static int ffs_func_setup(struct usb_function *f,
__ffs_event_add(ffs, FUNCTIONFS_SETUP);
spin_unlock_irqrestore(&ffs->ev.waitq.lock, flags);
- return USB_GADGET_DELAYED_STATUS;
+ return creq->wLength == 0 ? USB_GADGET_DELAYED_STATUS : 0;
}
static void ffs_func_suspend(struct usb_function *f)
diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c
index f8186613b53e..4848607b0798 100644
--- a/drivers/usb/gadget/udc/r8a66597-udc.c
+++ b/drivers/usb/gadget/udc/r8a66597-udc.c
@@ -835,11 +835,11 @@ static void init_controller(struct r8a66597 *r8a66597)
r8a66597_bset(r8a66597, XCKE, SYSCFG0);
- msleep(3);
+ mdelay(3);
r8a66597_bset(r8a66597, PLLC, SYSCFG0);
- msleep(1);
+ mdelay(1);
r8a66597_bset(r8a66597, SCKE, SYSCFG0);
@@ -1193,7 +1193,7 @@ __acquires(r8a66597->lock)
r8a66597->ep0_req->length = 2;
/* AV: what happens if we get called again before that gets through? */
spin_unlock(&r8a66597->lock);
- r8a66597_queue(r8a66597->gadget.ep0, r8a66597->ep0_req, GFP_KERNEL);
+ r8a66597_queue(r8a66597->gadget.ep0, r8a66597->ep0_req, GFP_ATOMIC);
spin_lock(&r8a66597->lock);
}
diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c
index f1ea5990a50a..c9c5b539eb5e 100644
--- a/drivers/usb/phy/phy-fsl-usb.c
+++ b/drivers/usb/phy/phy-fsl-usb.c
@@ -913,6 +913,7 @@ int usb_otg_start(struct platform_device *pdev)
if (pdata->init && pdata->init(pdev) != 0)
return -EINVAL;
+#ifdef CONFIG_PPC32
if (pdata->big_endian_mmio) {
_fsl_readl = _fsl_readl_be;
_fsl_writel = _fsl_writel_be;
@@ -920,6 +921,7 @@ int usb_otg_start(struct platform_device *pdev)
_fsl_readl = _fsl_readl_le;
_fsl_writel = _fsl_writel_le;
}
+#endif
/* request irq */
p_otg->irq = platform_get_irq(pdev, 0);
@@ -1010,7 +1012,7 @@ int usb_otg_start(struct platform_device *pdev)
/*
* state file in sysfs
*/
-static int show_fsl_usb2_otg_state(struct device *dev,
+static ssize_t show_fsl_usb2_otg_state(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct otg_fsm *fsm = &fsl_otg_dev->fsm;
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 46179a0828eb..493c3679620a 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -789,9 +789,9 @@ static void sierra_close(struct usb_serial_port *port)
kfree(urb->transfer_buffer);
usb_free_urb(urb);
usb_autopm_put_interface_async(serial->interface);
- spin_lock(&portdata->lock);
+ spin_lock_irq(&portdata->lock);
portdata->outstanding_urbs--;
- spin_unlock(&portdata->lock);
+ spin_unlock_irq(&portdata->lock);
}
sierra_stop_rx_urbs(port);
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 9474917de74d..34148637548c 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -1731,12 +1731,12 @@ static int do_register_framebuffer(struct fb_info *fb_info)
return 0;
}
-static int do_unregister_framebuffer(struct fb_info *fb_info)
+static int unbind_console(struct fb_info *fb_info)
{
struct fb_event event;
- int i, ret = 0;
+ int ret;
+ int i = fb_info->node;
- i = fb_info->node;
if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
return -EINVAL;
@@ -1751,17 +1751,29 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
unlock_fb_info(fb_info);
console_unlock();
+ return ret;
+}
+
+static int __unlink_framebuffer(struct fb_info *fb_info);
+
+static int do_unregister_framebuffer(struct fb_info *fb_info)
+{
+ struct fb_event event;
+ int ret;
+
+ ret = unbind_console(fb_info);
+
if (ret)
return -EINVAL;
pm_vt_switch_unregister(fb_info->dev);
- unlink_framebuffer(fb_info);
+ __unlink_framebuffer(fb_info);
if (fb_info->pixmap.addr &&
(fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
kfree(fb_info->pixmap.addr);
fb_destroy_modelist(&fb_info->modelist);
- registered_fb[i] = NULL;
+ registered_fb[fb_info->node] = NULL;
num_registered_fb--;
fb_cleanup_device(fb_info);
event.info = fb_info;
@@ -1774,7 +1786,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
return 0;
}
-int unlink_framebuffer(struct fb_info *fb_info)
+static int __unlink_framebuffer(struct fb_info *fb_info)
{
int i;
@@ -1786,6 +1798,20 @@ int unlink_framebuffer(struct fb_info *fb_info)
device_destroy(fb_class, MKDEV(FB_MAJOR, i));
fb_info->dev = NULL;
}
+
+ return 0;
+}
+
+int unlink_framebuffer(struct fb_info *fb_info)
+{
+ int ret;
+
+ ret = __unlink_framebuffer(fb_info);
+ if (ret)
+ return ret;
+
+ unbind_console(fb_info);
+
return 0;
}
EXPORT_SYMBOL(unlink_framebuffer);
diff --git a/drivers/video/msm/mdss/mdss_compat_utils.c b/drivers/video/msm/mdss/mdss_compat_utils.c
index 558c2d7c1dde..7a93d292a6da 100644
--- a/drivers/video/msm/mdss/mdss_compat_utils.c
+++ b/drivers/video/msm/mdss/mdss_compat_utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 1994 Martin Schaller
*
* 2001 - Documented with DocBook
@@ -2878,26 +2878,28 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
*pp = compat_alloc_user_space(alloc_size);
if (NULL == *pp)
return -ENOMEM;
- memset(*pp, 0, alloc_size);
-
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.r_data =
- (struct mdp_ar_gc_lut_data *)
- ((unsigned long) *pp +
- sizeof(struct msmfb_mdp_pp));
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.g_data =
- (struct mdp_ar_gc_lut_data *)
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((struct mdp_ar_gc_lut_data *)
+ ((unsigned long) *pp +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.lut_cfg_data.data.pgc_lut_data.r_data) ||
+ put_user((struct mdp_ar_gc_lut_data *)
((unsigned long) *pp +
sizeof(struct msmfb_mdp_pp) +
- pgc_size);
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.b_data =
- (struct mdp_ar_gc_lut_data *)
+ pgc_size),
+ &(*pp)->data.lut_cfg_data.data.pgc_lut_data.g_data) ||
+ put_user((struct mdp_ar_gc_lut_data *)
((unsigned long) *pp +
sizeof(struct msmfb_mdp_pp) +
- (2 * pgc_size));
- (*pp)->data.lut_cfg_data.data.pgc_lut_data.cfg_payload
- = (void *)((unsigned long) *pp +
+ (2 * pgc_size)),
+ &(*pp)->data.lut_cfg_data.data.pgc_lut_data.b_data) ||
+ put_user((void *)((unsigned long) *pp +
sizeof(struct msmfb_mdp_pp) +
- (3 * pgc_size));
+ (3 * pgc_size)),
+ &(*pp)->data.lut_cfg_data.data.
+ pgc_lut_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_lut_igc:
alloc_size += __pp_compat_size_igc();
@@ -2907,10 +2909,13 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.lut_cfg_data.data.igc_lut_data.cfg_payload
- = (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.lut_cfg_data.data.
+ igc_lut_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_lut_hist:
alloc_size += __pp_compat_size_hist_lut();
@@ -2920,10 +2925,13 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.lut_cfg_data.data.hist_lut_data.cfg_payload
- = (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.lut_cfg_data.data.
+ hist_lut_data.cfg_payload))
+ return -EFAULT;
break;
default:
*pp = compat_alloc_user_space(alloc_size);
@@ -2932,7 +2940,8 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
alloc_size, lut_type);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
break;
}
break;
@@ -2944,10 +2953,12 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.pcc_cfg_data.cfg_payload =
- (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.pcc_cfg_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_op_gamut_cfg:
alloc_size += __pp_compat_size_gamut();
@@ -2957,10 +2968,12 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.gamut_cfg_data.cfg_payload =
- (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.gamut_cfg_data.cfg_payload))
+ return -EFAULT;
break;
case mdp_op_pa_v2_cfg:
alloc_size += __pp_compat_size_pa();
@@ -2970,16 +2983,19 @@ static int __pp_compat_alloc(struct msmfb_mdp_pp32 __user *pp32,
alloc_size);
return -ENOMEM;
}
- memset(*pp, 0, alloc_size);
- (*pp)->data.pa_v2_cfg_data.cfg_payload =
- (void *)((unsigned long)(*pp) +
- sizeof(struct msmfb_mdp_pp));
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
+ if (put_user((void *)((unsigned long)(*pp) +
+ sizeof(struct msmfb_mdp_pp)),
+ &(*pp)->data.pa_v2_cfg_data.cfg_payload))
+ return -EFAULT;
break;
default:
*pp = compat_alloc_user_space(alloc_size);
if (NULL == *pp)
return -ENOMEM;
- memset(*pp, 0, alloc_size);
+ if (clear_user(*pp, alloc_size))
+ return -EFAULT;
break;
}
return 0;
@@ -3397,7 +3413,9 @@ static int mdss_histo_compat_ioctl(struct fb_info *info, unsigned int cmd,
sizeof(struct mdp_histogram_start_req));
return -EINVAL;
}
- memset(hist_req, 0, sizeof(struct mdp_histogram_start_req));
+ if (clear_user(hist_req,
+ sizeof(struct mdp_histogram_start_req)))
+ return -EFAULT;
ret = __from_user_hist_start_req(hist_req32, hist_req);
if (ret)
goto histo_compat_err;
@@ -3417,7 +3435,8 @@ static int mdss_histo_compat_ioctl(struct fb_info *info, unsigned int cmd,
sizeof(struct mdp_histogram_data));
return -EINVAL;
}
- memset(hist, 0, sizeof(struct mdp_histogram_data));
+ if (clear_user(hist, sizeof(struct mdp_histogram_data)))
+ return -EFAULT;
ret = __from_user_hist_data(hist32, hist);
if (ret)
goto histo_compat_err;
@@ -3920,7 +3939,7 @@ static int __to_user_mdp_overlay(struct mdp_overlay32 __user *ov32,
}
-static int __from_user_mdp_overlay(struct mdp_overlay *ov,
+static int __from_user_mdp_overlay(struct mdp_overlay __user *ov,
struct mdp_overlay32 __user *ov32)
{
__u32 data;
@@ -3979,12 +3998,12 @@ static int __from_user_mdp_overlay(struct mdp_overlay *ov,
return 0;
}
-static int __from_user_mdp_overlaylist(struct mdp_overlay_list *ovlist,
- struct mdp_overlay_list32 *ovlist32,
+static int __from_user_mdp_overlaylist(struct mdp_overlay_list __user *ovlist,
+ struct mdp_overlay_list32 __user *ovlist32,
struct mdp_overlay **to_list_head)
{
__u32 i, ret;
- unsigned long data, from_list_head;
+ unsigned long data, from_list_head, num_overlays;
struct mdp_overlay32 *iter;
if (!to_list_head || !ovlist32 || !ovlist) {
@@ -4005,11 +4024,13 @@ static int __from_user_mdp_overlaylist(struct mdp_overlay_list *ovlist,
sizeof(ovlist32->processed_overlays)))
return -EFAULT;
- if (get_user(data, &ovlist32->overlay_list)) {
+ if (get_user(data, &ovlist32->overlay_list) ||
+ get_user(num_overlays, &ovlist32->num_overlays)) {
ret = -EFAULT;
goto validate_exit;
}
- for (i = 0; i < ovlist32->num_overlays; i++) {
+
+ for (i = 0; i < num_overlays; i++) {
if (get_user(from_list_head, (__u32 *)data + i)) {
ret = -EFAULT;
goto validate_exit;
@@ -4022,7 +4043,8 @@ static int __from_user_mdp_overlaylist(struct mdp_overlay_list *ovlist,
goto validate_exit;
}
}
- ovlist->overlay_list = to_list_head;
+ if (put_user(to_list_head, &ovlist->overlay_list))
+ return -EFAULT;
return 0;
@@ -4031,8 +4053,8 @@ static int __from_user_mdp_overlaylist(struct mdp_overlay_list *ovlist,
return -EFAULT;
}
-static int __to_user_mdp_overlaylist(struct mdp_overlay_list32 *ovlist32,
- struct mdp_overlay_list *ovlist,
+static int __to_user_mdp_overlaylist(struct mdp_overlay_list32 __user *ovlist32,
+ struct mdp_overlay_list __user *ovlist,
struct mdp_overlay **l_ptr)
{
__u32 i, ret;
@@ -4105,31 +4127,33 @@ static u32 __pp_sspp_size(void)
return size;
}
-static int __pp_sspp_set_offsets(struct mdp_overlay *ov)
+static int __pp_sspp_set_offsets(struct mdp_overlay __user *ov)
{
if (!ov) {
pr_err("invalid overlay pointer\n");
return -EFAULT;
}
- ov->overlay_pp_cfg.igc_cfg.cfg_payload = (void *)((unsigned long)ov +
- sizeof(struct mdp_overlay));
- ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload =
- ov->overlay_pp_cfg.igc_cfg.cfg_payload +
- sizeof(struct mdp_igc_lut_data_v1_7);
- ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload =
- ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload +
- sizeof(struct mdp_pa_data_v1_7);
- ov->overlay_pp_cfg.hist_lut_cfg.cfg_payload =
- ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload +
- sizeof(struct mdp_pcc_data_v1_7);
+ if (put_user((void *)((unsigned long)ov + sizeof(struct mdp_overlay)),
+ &(ov->overlay_pp_cfg.igc_cfg.cfg_payload)) ||
+ put_user(ov->overlay_pp_cfg.igc_cfg.cfg_payload +
+ sizeof(struct mdp_igc_lut_data_v1_7),
+ &(ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload)) ||
+ put_user(ov->overlay_pp_cfg.pa_v2_cfg_data.cfg_payload +
+ sizeof(struct mdp_pa_data_v1_7),
+ &(ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload)) ||
+ put_user(ov->overlay_pp_cfg.pcc_cfg_data.cfg_payload +
+ sizeof(struct mdp_pcc_data_v1_7),
+ &(ov->overlay_pp_cfg.hist_lut_cfg.cfg_payload)))
+ return -EFAULT;
return 0;
}
int mdss_compat_overlay_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg, struct file *file)
{
- struct mdp_overlay *ov, **layers_head;
- struct mdp_overlay32 *ov32;
+ struct mdp_overlay **layers_head;
+ struct mdp_overlay __user *ov;
+ struct mdp_overlay32 __user *ov32;
struct mdp_overlay_list __user *ovlist;
struct mdp_overlay_list32 __user *ovlist32;
size_t layers_refs_sz, layers_sz, prepare_sz;
diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c
index 799a4e6ce371..9f28380b151b 100644
--- a/drivers/video/msm/mdss/mdss_dsi_host.c
+++ b/drivers/video/msm/mdss/mdss_dsi_host.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -2104,7 +2104,7 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
/* clear CMD DMA and BTA_DONE isr only */
reg_val |= (DSI_INTR_CMD_DMA_DONE | DSI_INTR_BTA_DONE);
MIPI_OUTP(ctrl->ctrl_base + 0x0110, reg_val);
- mdss_dsi_disable_irq_nosync(ctrl, DSI_CMD_TERM);
+ mdss_dsi_disable_irq(ctrl, DSI_CMD_TERM);
complete(&ctrl->dma_comp);
pr_warn("%s: dma tx done but irq not triggered\n",
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 771d9e76fcc1..5bad60a6dadd 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -416,7 +416,9 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
tell_host(vb, vb->inflate_vq);
/* balloon's page migration 2nd step -- deflate "page" */
+ spin_lock_irqsave(&vb_dev_info->pages_lock, flags);
balloon_page_delete(page);
+ spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
set_page_pfns(vb->pfns, page);
tell_host(vb, vb->deflate_vq);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 3f5fc150c2b7..b2937b645b62 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -4281,7 +4281,7 @@ static int flush_space(struct btrfs_root *root,
break;
}
- return ret;
+ return 0;
}
static inline u64
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index e12f189d539b..80ed75bde04a 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -193,7 +193,6 @@ static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
pr_err("\n");
pr_err("Error: Unexpected object collision\n");
cachefiles_printk_object(object, xobject);
- BUG();
}
atomic_inc(&xobject->usage);
write_unlock(&cache->active_lock);
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 616db0e77b44..a899e69cd5fd 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -27,6 +27,7 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
struct cachefiles_one_read *monitor =
container_of(wait, struct cachefiles_one_read, monitor);
struct cachefiles_object *object;
+ struct fscache_retrieval *op = monitor->op;
struct wait_bit_key *key = _key;
struct page *page = wait->private;
@@ -51,16 +52,22 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
list_del(&wait->task_list);
/* move onto the action list and queue for FS-Cache thread pool */
- ASSERT(monitor->op);
+ ASSERT(op);
- object = container_of(monitor->op->op.object,
- struct cachefiles_object, fscache);
+ /* We need to temporarily bump the usage count as we don't own a ref
+ * here otherwise cachefiles_read_copier() may free the op between the
+ * monitor being enqueued on the op->to_do list and the op getting
+ * enqueued on the work queue.
+ */
+ fscache_get_retrieval(op);
+ object = container_of(op->op.object, struct cachefiles_object, fscache);
spin_lock(&object->work_lock);
- list_add_tail(&monitor->op_link, &monitor->op->to_do);
+ list_add_tail(&monitor->op_link, &op->to_do);
spin_unlock(&object->work_lock);
- fscache_enqueue_retrieval(monitor->op);
+ fscache_enqueue_retrieval(op);
+ fscache_put_retrieval(op);
return 0;
}
diff --git a/fs/dcache.c b/fs/dcache.c
index c99ef9daa6b3..233acac6750a 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1850,10 +1850,12 @@ struct dentry *d_make_root(struct inode *root_inode)
static const struct qstr name = QSTR_INIT("/", 1);
res = __d_alloc(root_inode->i_sb, &name);
- if (res)
+ if (res) {
+ res->d_flags |= DCACHE_RCUACCESS;
d_instantiate(res, root_inode);
- else
+ } else {
iput(root_inode);
+ }
}
return res;
}
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 5834799733ff..1d29039dc85c 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1391,6 +1391,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
goto cleanup_and_exit;
dxtrace(printk(KERN_DEBUG "ext4_find_entry: dx failed, "
"falling back\n"));
+ ret = NULL;
}
nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb);
if (!nblocks) {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 75b5a159d607..3df305d6783c 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -610,13 +610,21 @@ static void fat_set_state(struct super_block *sb,
brelse(bh);
}
+static void fat_reset_iocharset(struct fat_mount_options *opts)
+{
+ if (opts->iocharset != fat_default_iocharset) {
+ /* Note: opts->iocharset can be NULL here */
+ kfree(opts->iocharset);
+ opts->iocharset = fat_default_iocharset;
+ }
+}
+
static void delayed_free(struct rcu_head *p)
{
struct msdos_sb_info *sbi = container_of(p, struct msdos_sb_info, rcu);
unload_nls(sbi->nls_disk);
unload_nls(sbi->nls_io);
- if (sbi->options.iocharset != fat_default_iocharset)
- kfree(sbi->options.iocharset);
+ fat_reset_iocharset(&sbi->options);
kfree(sbi);
}
@@ -1031,7 +1039,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
opts->fs_fmask = opts->fs_dmask = current_umask();
opts->allow_utime = -1;
opts->codepage = fat_default_codepage;
- opts->iocharset = fat_default_iocharset;
+ fat_reset_iocharset(opts);
if (is_vfat) {
opts->shortname = VFAT_SFN_DISPLAY_WINNT|VFAT_SFN_CREATE_WIN95;
opts->rodir = 0;
@@ -1181,8 +1189,7 @@ static int parse_options(struct super_block *sb, char *options, int is_vfat,
/* vfat specific */
case Opt_charset:
- if (opts->iocharset != fat_default_iocharset)
- kfree(opts->iocharset);
+ fat_reset_iocharset(opts);
iocharset = match_strdup(&args[0]);
if (!iocharset)
return -ENOMEM;
@@ -1774,8 +1781,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
iput(fat_inode);
unload_nls(sbi->nls_io);
unload_nls(sbi->nls_disk);
- if (sbi->options.iocharset != fat_default_iocharset)
- kfree(sbi->options.iocharset);
+ fat_reset_iocharset(&sbi->options);
sb->s_fs_info = NULL;
kfree(sbi);
return error;
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index e7b87a0e5185..deac2e89d176 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -37,7 +37,8 @@ void fscache_enqueue_operation(struct fscache_operation *op)
ASSERT(op->processor != NULL);
ASSERT(fscache_object_is_available(op->object));
ASSERTCMP(atomic_read(&op->usage), >, 0);
- ASSERTCMP(op->state, ==, FSCACHE_OP_ST_IN_PROGRESS);
+ ASSERTIFCMP(op->state != FSCACHE_OP_ST_IN_PROGRESS,
+ op->state, ==, FSCACHE_OP_ST_CANCELLED);
fscache_stat(&fscache_n_op_enqueue);
switch (op->flags & FSCACHE_OP_TYPE) {
@@ -401,7 +402,8 @@ void fscache_put_operation(struct fscache_operation *op)
struct fscache_cache *cache;
_enter("{OBJ%x OP%x,%d}",
- op->object->debug_id, op->debug_id, atomic_read(&op->usage));
+ op->object ? op->object->debug_id : 0,
+ op->debug_id, atomic_read(&op->usage));
ASSERTCMP(atomic_read(&op->usage), >, 0);
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index a5a95a058ea2..d49d63c3be9b 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1925,11 +1925,14 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
if (!fc)
return -EPERM;
+ pipe_lock(pipe);
+
bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
- if (!bufs)
+ if (!bufs) {
+ pipe_unlock(pipe);
return -ENOMEM;
+ }
- pipe_lock(pipe);
nbuf = 0;
rem = 0;
for (idx = 0; idx < pipe->nrbufs && rem < len; idx++)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index cccc217dbab4..a8e3026e6f7b 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -926,6 +926,7 @@ static int fuse_readpages_fill(void *_data, struct page *page)
}
if (WARN_ON(req->num_pages >= req->max_pages)) {
+ unlock_page(page);
fuse_put_request(fc, req);
return -EIO;
}
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 46325d5c34fc..405e8c42cb1a 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -493,15 +493,17 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
if (size > PSIZE) {
/*
* To keep the rest of the code simple. Allocate a
- * contiguous buffer to work with
+ * contiguous buffer to work with. Make the buffer large
+ * enough to make use of the whole extent.
*/
- ea_buf->xattr = kmalloc(size, GFP_KERNEL);
+ ea_buf->max_size = (size + sb->s_blocksize - 1) &
+ ~(sb->s_blocksize - 1);
+
+ ea_buf->xattr = kmalloc(ea_buf->max_size, GFP_KERNEL);
if (ea_buf->xattr == NULL)
return -ENOMEM;
ea_buf->flag = EA_MALLOC;
- ea_buf->max_size = (size + sb->s_blocksize - 1) &
- ~(sb->s_blocksize - 1);
if (ea_size == 0)
return 0;
diff --git a/fs/namespace.c b/fs/namespace.c
index 214780c5e541..de824e10ec46 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -592,12 +592,21 @@ bool legitimize_mnt(struct vfsmount *bastard, unsigned seq)
return true;
mnt = real_mount(bastard);
mnt_add_count(mnt, 1);
+ smp_mb(); // see mntput_no_expire()
if (likely(!read_seqretry(&mount_lock, seq)))
return true;
if (bastard->mnt_flags & MNT_SYNC_UMOUNT) {
mnt_add_count(mnt, -1);
return false;
}
+ lock_mount_hash();
+ if (unlikely(bastard->mnt_flags & MNT_DOOMED)) {
+ mnt_add_count(mnt, -1);
+ unlock_mount_hash();
+ return true;
+ }
+ unlock_mount_hash();
+
rcu_read_unlock();
mntput(bastard);
rcu_read_lock();
@@ -1067,12 +1076,27 @@ static DECLARE_DELAYED_WORK(delayed_mntput_work, delayed_mntput);
static void mntput_no_expire(struct mount *mnt)
{
rcu_read_lock();
- mnt_add_count(mnt, -1);
- if (likely(mnt->mnt_ns)) { /* shouldn't be the last one */
+ if (likely(READ_ONCE(mnt->mnt_ns))) {
+ /*
+ * Since we don't do lock_mount_hash() here,
+ * ->mnt_ns can change under us. However, if it's
+ * non-NULL, then there's a reference that won't
+ * be dropped until after an RCU delay done after
+ * turning ->mnt_ns NULL. So if we observe it
+ * non-NULL under rcu_read_lock(), the reference
+ * we are dropping is not the final one.
+ */
+ mnt_add_count(mnt, -1);
rcu_read_unlock();
return;
}
lock_mount_hash();
+ /*
+ * make sure that if __legitimize_mnt() has not seen us grab
+ * mount_lock, we'll see their refcount increment here.
+ */
+ smp_mb();
+ mnt_add_count(mnt, -1);
if (mnt_get_count(mnt)) {
rcu_read_unlock();
unlock_mount_hash();
diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c
index 5aed4f98df41..00727659e439 100644
--- a/fs/nfs/blocklayout/dev.c
+++ b/fs/nfs/blocklayout/dev.c
@@ -157,7 +157,7 @@ static bool bl_map_stripe(struct pnfs_block_dev *dev, u64 offset,
chunk = div_u64(offset, dev->chunk_size);
div_u64_rem(chunk, dev->nr_children, &chunk_idx);
- if (chunk_idx > dev->nr_children) {
+ if (chunk_idx >= dev->nr_children) {
dprintk("%s: invalid chunk idx %d (%lld/%lld)\n",
__func__, chunk_idx, offset, dev->chunk_size);
/* error, should not happen */
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 7c36898af402..59b29acb6419 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -842,8 +842,10 @@ static int listxattr_filler(void *buf, const char *name, int namelen,
size = handler->list(b->dentry, b->buf + b->pos,
b->size, name, namelen,
handler->flags);
- if (size > b->size)
+ if (b->pos + size > b->size) {
+ b->pos = -ERANGE;
return -ERANGE;
+ }
} else {
size = handler->list(b->dentry, NULL, 0, name,
namelen, handler->flags);
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index 6785d086ab38..7d78c3d28bbd 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -340,6 +340,9 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,
TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
+ if (unlikely(length < 0))
+ return -EIO;
+
while (length) {
entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
if (entry->error) {
diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c
index d778763de26e..a61632c9ad68 100644
--- a/fs/squashfs/file.c
+++ b/fs/squashfs/file.c
@@ -198,7 +198,11 @@ static long long read_indexes(struct super_block *sb, int n,
}
for (i = 0; i < blocks; i++) {
- int size = le32_to_cpu(blist[i]);
+ int size = squashfs_block_size(blist[i]);
+ if (size < 0) {
+ err = size;
+ goto failure;
+ }
block += SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
}
n -= blocks;
@@ -371,7 +375,7 @@ static int read_blocklist(struct inode *inode, int index, u64 *block)
sizeof(size));
if (res < 0)
return res;
- return le32_to_cpu(size);
+ return squashfs_block_size(size);
}
/* Copy data into page cache */
diff --git a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
index 0ed6edbc5c71..0681feab4a84 100644
--- a/fs/squashfs/fragment.c
+++ b/fs/squashfs/fragment.c
@@ -49,11 +49,16 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
u64 *fragment_block)
{
struct squashfs_sb_info *msblk = sb->s_fs_info;
- int block = SQUASHFS_FRAGMENT_INDEX(fragment);
- int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
- u64 start_block = le64_to_cpu(msblk->fragment_index[block]);
+ int block, offset, size;
struct squashfs_fragment_entry fragment_entry;
- int size;
+ u64 start_block;
+
+ if (fragment >= msblk->fragments)
+ return -EIO;
+ block = SQUASHFS_FRAGMENT_INDEX(fragment);
+ offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
+
+ start_block = le64_to_cpu(msblk->fragment_index[block]);
size = squashfs_read_metadata(sb, &fragment_entry, &start_block,
&offset, sizeof(fragment_entry));
@@ -61,9 +66,7 @@ int squashfs_frag_lookup(struct super_block *sb, unsigned int fragment,
return size;
*fragment_block = le64_to_cpu(fragment_entry.start_block);
- size = le32_to_cpu(fragment_entry.size);
-
- return size;
+ return squashfs_block_size(fragment_entry.size);
}
diff --git a/fs/squashfs/squashfs_fs.h b/fs/squashfs/squashfs_fs.h
index 506f4ba5b983..e66486366f02 100644
--- a/fs/squashfs/squashfs_fs.h
+++ b/fs/squashfs/squashfs_fs.h
@@ -129,6 +129,12 @@
#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
+static inline int squashfs_block_size(__le32 raw)
+{
+ u32 size = le32_to_cpu(raw);
+ return (size >> 25) ? -EIO : size;
+}
+
/*
* Inode number ops. Inodes consist of a compressed block number, and an
* uncompressed offset within that block
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index 8a6995de0277..3b767ce1e46d 100644
--- a/fs/squashfs/squashfs_fs_sb.h
+++ b/fs/squashfs/squashfs_fs_sb.h
@@ -75,6 +75,7 @@ struct squashfs_sb_info {
unsigned short block_log;
long long bytes_used;
unsigned int inodes;
+ unsigned int fragments;
int xattr_ids;
};
#endif
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index 61cd0b39ed0e..4ffbddb688aa 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -176,6 +176,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
msblk->inode_table = le64_to_cpu(sblk->inode_table_start);
msblk->directory_table = le64_to_cpu(sblk->directory_table_start);
msblk->inodes = le32_to_cpu(sblk->inodes);
+ msblk->fragments = le32_to_cpu(sblk->fragments);
flags = le16_to_cpu(sblk->flags);
TRACE("Found valid superblock on %s\n", bdevname(sb->s_bdev, b));
@@ -186,7 +187,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
TRACE("Filesystem size %lld bytes\n", msblk->bytes_used);
TRACE("Block size %d\n", msblk->block_size);
TRACE("Number of inodes %d\n", msblk->inodes);
- TRACE("Number of fragments %d\n", le32_to_cpu(sblk->fragments));
+ TRACE("Number of fragments %d\n", msblk->fragments);
TRACE("Number of ids %d\n", le16_to_cpu(sblk->no_ids));
TRACE("sblk->inode_table_start %llx\n", msblk->inode_table);
TRACE("sblk->directory_table_start %llx\n", msblk->directory_table);
@@ -273,7 +274,7 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
sb->s_export_op = &squashfs_export_ops;
handle_fragments:
- fragments = le32_to_cpu(sblk->fragments);
+ fragments = msblk->fragments;
if (fragments == 0)
goto check_directory_table;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index e9ef59b3abb1..154a4a953887 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -356,6 +356,50 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
}
EXPORT_SYMBOL_GPL(sysfs_chmod_file);
+/**
+ * sysfs_break_active_protection - break "active" protection
+ * @kobj: The kernel object @attr is associated with.
+ * @attr: The attribute to break the "active" protection for.
+ *
+ * With sysfs, just like kernfs, deletion of an attribute is postponed until
+ * all active .show() and .store() callbacks have finished unless this function
+ * is called. Hence this function is useful in methods that implement self
+ * deletion.
+ */
+struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr)
+{
+ struct kernfs_node *kn;
+
+ kobject_get(kobj);
+ kn = kernfs_find_and_get(kobj->sd, attr->name);
+ if (kn)
+ kernfs_break_active_protection(kn);
+ return kn;
+}
+EXPORT_SYMBOL_GPL(sysfs_break_active_protection);
+
+/**
+ * sysfs_unbreak_active_protection - restore "active" protection
+ * @kn: Pointer returned by sysfs_break_active_protection().
+ *
+ * Undo the effects of sysfs_break_active_protection(). Since this function
+ * calls kernfs_put() on the kernfs node that corresponds to the 'attr'
+ * argument passed to sysfs_break_active_protection() that attribute may have
+ * been removed between the sysfs_break_active_protection() and
+ * sysfs_unbreak_active_protection() calls, it is not safe to access @kn after
+ * this function has returned.
+ */
+void sysfs_unbreak_active_protection(struct kernfs_node *kn)
+{
+ struct kobject *kobj = kn->parent->priv;
+
+ kernfs_unbreak_active_protection(kn);
+ kernfs_put(kn);
+ kobject_put(kobj);
+}
+EXPORT_SYMBOL_GPL(sysfs_unbreak_active_protection);
+
/**
* sysfs_remove_file_ns - remove an object attribute with a custom ns tag
* @kobj: object we're acting for
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c
index ff53c030c5f7..08b7d288d192 100644
--- a/fs/ubifs/journal.c
+++ b/fs/ubifs/journal.c
@@ -661,6 +661,11 @@ int ubifs_jnl_update(struct ubifs_info *c, const struct inode *dir,
spin_lock(&ui->ui_lock);
ui->synced_i_size = ui->ui_size;
spin_unlock(&ui->ui_lock);
+ if (xent) {
+ spin_lock(&host_ui->ui_lock);
+ host_ui->synced_i_size = host_ui->ui_size;
+ spin_unlock(&host_ui->ui_lock);
+ }
mark_inode_clean(c, ui);
mark_inode_clean(c, host_ui);
return 0;
@@ -1107,7 +1112,7 @@ static int recomp_data_node(const struct ubifs_info *c,
int err, len, compr_type, out_len;
out_len = le32_to_cpu(dn->size);
- buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS);
+ buf = kmalloc(out_len * WORST_COMPR_FACTOR, GFP_NOFS);
if (!buf)
return -ENOMEM;
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index a0011aa3a779..f43f162e36f4 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -1091,10 +1091,6 @@ static int scan_check_cb(struct ubifs_info *c,
}
}
- buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
- if (!buf)
- return -ENOMEM;
-
/*
* After an unclean unmount, empty and freeable LEBs
* may contain garbage - do not scan them.
@@ -1113,6 +1109,10 @@ static int scan_check_cb(struct ubifs_info *c,
return LPT_SCAN_CONTINUE;
}
+ buf = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
sleb = ubifs_scan(c, lnum, 0, buf, 0);
if (IS_ERR(sleb)) {
ret = PTR_ERR(sleb);
diff --git a/fs/xattr.c b/fs/xattr.c
index d536edbd377e..cfc6324cfd6e 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -455,7 +455,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
if (error > 0) {
if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) ||
(strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0))
- posix_acl_fix_xattr_to_user(kvalue, size);
+ posix_acl_fix_xattr_to_user(kvalue, error);
if (size && copy_to_user(value, kvalue, error))
error = -EFAULT;
} else if (error == -ERANGE && size >= XATTR_SIZE_MAX) {
diff --git a/include/crypto/vmac.h b/include/crypto/vmac.h
deleted file mode 100644
index 6b700c7b2fe1..000000000000
--- a/include/crypto/vmac.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Modified to interface to the Linux kernel
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-
-#ifndef __CRYPTO_VMAC_H
-#define __CRYPTO_VMAC_H
-
-/* --------------------------------------------------------------------------
- * VMAC and VHASH Implementation by Ted Krovetz (tdk@acm.org) and Wei Dai.
- * This implementation is herby placed in the public domain.
- * The authors offers no warranty. Use at your own risk.
- * Please send bug reports to the authors.
- * Last modified: 17 APR 08, 1700 PDT
- * ----------------------------------------------------------------------- */
-
-/*
- * User definable settings.
- */
-#define VMAC_TAG_LEN 64
-#define VMAC_KEY_SIZE 128/* Must be 128, 192 or 256 */
-#define VMAC_KEY_LEN (VMAC_KEY_SIZE/8)
-#define VMAC_NHBYTES 128/* Must 2^i for any 3 < i < 13 Standard = 128*/
-
-/*
- * This implementation uses u32 and u64 as names for unsigned 32-
- * and 64-bit integer types. These are defined in C99 stdint.h. The
- * following may need adaptation if you are not running a C99 or
- * Microsoft C environment.
- */
-struct vmac_ctx {
- u64 nhkey[(VMAC_NHBYTES/8)+2*(VMAC_TAG_LEN/64-1)];
- u64 polykey[2*VMAC_TAG_LEN/64];
- u64 l3key[2*VMAC_TAG_LEN/64];
- u64 polytmp[2*VMAC_TAG_LEN/64];
- u64 cached_nonce[2];
- u64 cached_aes[2];
- int first_block_processed;
-};
-
-typedef u64 vmac_t;
-
-struct vmac_ctx_t {
- struct crypto_cipher *child;
- struct vmac_ctx __vmac_ctx;
- u8 partial[VMAC_NHBYTES]; /* partial block */
- int partial_size; /* size of the partial block */
-};
-
-#endif /* __CRYPTO_VMAC_H */
diff --git a/include/linux/diagchar.h b/include/linux/diagchar.h
index c3364dce7eea..332cb1b38413 100644
--- a/include/linux/diagchar.h
+++ b/include/linux/diagchar.h
@@ -144,10 +144,10 @@ the appropriate macros. */
/* This needs to be modified manually now, when we add
a new RANGE of SSIDs to the msg_mask_tbl */
#define MSG_MASK_TBL_CNT 26
-#define APPS_EVENT_LAST_ID 0x0B2A
+#define APPS_EVENT_LAST_ID 0x0C5A
#define MSG_SSID_0 0
-#define MSG_SSID_0_LAST 120
+#define MSG_SSID_0_LAST 125
#define MSG_SSID_1 500
#define MSG_SSID_1_LAST 506
#define MSG_SSID_2 1000
@@ -159,11 +159,11 @@ the appropriate macros. */
#define MSG_SSID_5 4000
#define MSG_SSID_5_LAST 4010
#define MSG_SSID_6 4500
-#define MSG_SSID_6_LAST 4573
+#define MSG_SSID_6_LAST 4584
#define MSG_SSID_7 4600
-#define MSG_SSID_7_LAST 4615
+#define MSG_SSID_7_LAST 4616
#define MSG_SSID_8 5000
-#define MSG_SSID_8_LAST 5033
+#define MSG_SSID_8_LAST 5034
#define MSG_SSID_9 5500
#define MSG_SSID_9_LAST 5516
#define MSG_SSID_10 6000
@@ -183,7 +183,7 @@ the appropriate macros. */
#define MSG_SSID_17 9000
#define MSG_SSID_17_LAST 9008
#define MSG_SSID_18 9500
-#define MSG_SSID_18_LAST 9510
+#define MSG_SSID_18_LAST 9521
#define MSG_SSID_19 10200
#define MSG_SSID_19_LAST 10210
#define MSG_SSID_20 10251
@@ -263,7 +263,7 @@ static const uint32_t msg_bld_masks_0[] = {
MSG_MASK_6|MSG_MASK_7|MSG_MASK_8|MSG_MASK_9|MSG_MASK_10,
MSG_LVL_MED,
MSG_LVL_LOW,
- MSG_LVL_LOW,
+ MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_LOW,
MSG_LVL_LOW,
@@ -316,7 +316,7 @@ static const uint32_t msg_bld_masks_0[] = {
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_MED,
MSG_LVL_HIGH,
- MSG_LVL_LOW,
+ MSG_LVL_MED,
MSG_LVL_HIGH,
MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR,
@@ -340,7 +340,8 @@ static const uint32_t msg_bld_masks_0[] = {
MSG_LVL_MED,
MSG_LVL_HIGH,
MSG_LVL_LOW,
- MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL
+ MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL,
+ MSG_LVL_HIGH
};
static const uint32_t msg_bld_masks_1[] = {
@@ -484,6 +485,7 @@ static const uint32_t msg_bld_masks_6[] = {
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
+ MSG_LVL_LOW,
MSG_LVL_LOW
};
@@ -503,7 +505,9 @@ static const uint32_t msg_bld_masks_7[] = {
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
- MSG_LVL_LOW|MSG_LVL_MED|MSG_LVL_HIGH|MSG_LVL_ERROR|MSG_LVL_FATAL
+ MSG_LVL_LOW | MSG_LVL_MED | MSG_LVL_HIGH | MSG_LVL_ERROR |
+ MSG_LVL_FATAL,
+ MSG_LVL_LOW
};
static const uint32_t msg_bld_masks_8[] = {
@@ -523,9 +527,6 @@ static const uint32_t msg_bld_masks_8[] = {
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
@@ -540,6 +541,10 @@ static const uint32_t msg_bld_masks_8[] = {
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_HIGH,
MSG_LVL_HIGH
};
@@ -642,14 +647,14 @@ static const uint32_t msg_bld_masks_10[] = {
MSG_LVL_MED,
MSG_LVL_MED,
MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
- MSG_LVL_LOW,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
+ MSG_LVL_MED,
MSG_LVL_MED
};
@@ -795,7 +800,9 @@ static const uint32_t msg_bld_masks_19[] = {
};
static const uint32_t msg_bld_masks_20[] = {
- MSG_LVL_LOW,
+ MSG_LVL_LOW | MSG_MASK_5 | MSG_MASK_6 | MSG_MASK_7 |
+ MSG_MASK_8 | MSG_MASK_9 | MSG_MASK_10 | MSG_MASK_11 |
+ MSG_MASK_12,
MSG_LVL_LOW,
MSG_LVL_LOW,
MSG_LVL_LOW,
@@ -873,7 +880,7 @@ static const uint32_t msg_bld_masks_25[] = {
/* LOG CODES */
static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 0 */
- 0x1A02, /* EQUIP ID 1 */
+ 0x1C6A, /* EQUIP ID 1 */
0x0, /* EQUIP ID 2 */
0x0, /* EQUIP ID 3 */
0x4910, /* EQUIP ID 4 */
@@ -883,7 +890,7 @@ static const uint32_t log_code_last_tbl[] = {
0x0, /* EQUIP ID 8 */
0x0, /* EQUIP ID 9 */
0xA38A, /* EQUIP ID 10 */
- 0xB201, /* EQUIP ID 11 */
+ 0xB9FF, /* EQUIP ID 11 */
0x0, /* EQUIP ID 12 */
0xD1FF, /* EQUIP ID 13 */
0x0, /* EQUIP ID 14 */
diff --git a/include/linux/fastchg.h b/include/linux/fastchg.h
new file mode 100644
index 000000000000..9dc0adb63d75
--- /dev/null
+++ b/include/linux/fastchg.h
@@ -0,0 +1,22 @@
+/*
+ * Author: Chad Froebel
+ *
+ * Port to Thulium: engstk
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_FASTCHG_H
+#define _LINUX_FASTCHG_H
+
+extern int force_fast_charge;
+
+#endif
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 7693858c5583..16842b4e2056 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -15,8 +15,6 @@
#include
#include
-#include
-
#ifdef CONFIG_SMP
# define INIT_PUSHABLE_TASKS(tsk) \
.pushable_tasks = PLIST_NODE_INIT(tsk.pushable_tasks, MAX_PRIO),
@@ -175,19 +173,12 @@ extern struct task_group root_task_group;
# define INIT_KASAN(tsk)
#endif
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-# define INIT_TASK_TI(tsk) .thread_info = INIT_THREAD_INFO(tsk),
-#else
-# define INIT_TASK_TI(tsk)
-#endif
-
/*
* INIT_TASK is used to set up the first task table, touch at
* your own risk!. Base=0, limit=0x1fffff (=2MB)
*/
#define INIT_TASK(tsk) \
{ \
- INIT_TASK_TI(tsk) \
.state = 0, \
.stack = &init_thread_info, \
.usage = ATOMIC_INIT(2), \
diff --git a/include/linux/mfd/wcd9xxx/pdata.h b/include/linux/mfd/wcd9xxx/pdata.h
index f3cbfbe80c7c..d876386d8ace 100644
--- a/include/linux/mfd/wcd9xxx/pdata.h
+++ b/include/linux/mfd/wcd9xxx/pdata.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-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
@@ -192,6 +192,7 @@ struct wcd9xxx_pdata {
u32 mic_unmute_delay;
enum codec_variant cdc_variant;
u16 use_pinctrl;
+ bool wcd9xxx_mic_tristate;
};
#endif
diff --git a/include/linux/msm_mhi_dev.h b/include/linux/msm_mhi_dev.h
index 7eb1d06f956d..e7656972c13c 100644
--- a/include/linux/msm_mhi_dev.h
+++ b/include/linux/msm_mhi_dev.h
@@ -135,6 +135,7 @@ enum mhi_client_channel {
MHI_CLIENT_RESERVED_2_LOWER = 102,
MHI_CLIENT_RESERVED_2_UPPER = 127,
MHI_MAX_CHANNELS = 102,
+ MHI_CLIENT_INVALID = 0xFFFFFFFF
};
struct mhi_dev_client_cb_data {
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index e2c13cd863bd..4daa5069cbdb 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -162,6 +162,7 @@ void ring_buffer_record_enable(struct ring_buffer *buffer);
void ring_buffer_record_off(struct ring_buffer *buffer);
void ring_buffer_record_on(struct ring_buffer *buffer);
int ring_buffer_record_is_on(struct ring_buffer *buffer);
+int ring_buffer_record_is_set_on(struct ring_buffer *buffer);
void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 004733cd7d46..0e00bf883bea 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1457,13 +1457,6 @@ enum perf_event_task_context {
};
struct task_struct {
-#ifdef CONFIG_THREAD_INFO_IN_TASK
- /*
- * For reasons of header soup (see current_thread_info()), this
- * must be the first element of task_struct.
- */
- struct thread_info thread_info;
-#endif
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack;
atomic_t usage;
@@ -1477,9 +1470,6 @@ struct task_struct {
#ifdef CONFIG_SMP
struct llist_node wake_entry;
int on_cpu;
-#ifdef CONFIG_THREAD_INFO_IN_TASK
- unsigned int cpu; /* current CPU */
-#endif
unsigned int wakee_flips;
unsigned long wakee_flip_decay_ts;
struct task_struct *last_wakee;
@@ -2535,9 +2525,7 @@ void yield(void);
extern struct exec_domain default_exec_domain;
union thread_union {
-#ifndef CONFIG_THREAD_INFO_IN_TASK
struct thread_info thread_info;
-#endif
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
@@ -2923,26 +2911,10 @@ static inline void threadgroup_lock(struct task_struct *tsk) {}
static inline void threadgroup_unlock(struct task_struct *tsk) {}
#endif
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-
-static inline struct thread_info *task_thread_info(struct task_struct *task)
-{
- return &task->thread_info;
-}
-static inline void *task_stack_page(const struct task_struct *task)
-{
- return task->stack;
-}
-#define setup_thread_stack(new,old) do { } while(0)
-static inline unsigned long *end_of_stack(const struct task_struct *task)
-{
- return task->stack;
-}
-
-#elif !defined(__HAVE_THREAD_FUNCTIONS)
+#ifndef __HAVE_THREAD_FUNCTIONS
#define task_thread_info(task) ((struct thread_info *)(task)->stack)
-#define task_stack_page(task) ((void *)(task)->stack)
+#define task_stack_page(task) ((task)->stack)
static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
{
@@ -3245,11 +3217,7 @@ static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
static inline unsigned int task_cpu(const struct task_struct *p)
{
-#ifdef CONFIG_THREAD_INFO_IN_TASK
- return p->cpu;
-#else
return task_thread_info(p)->cpu;
-#endif
}
static inline int task_node(const struct task_struct *p)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 3dbe99528735..393e3e459bf1 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -475,6 +475,7 @@ static inline u32 skb_mstamp_us_delta(const struct skb_mstamp *t1,
* @hash: the packet hash
* @queue_mapping: Queue mapping for multiqueue devices
* @xmit_more: More SKBs are pending for this queue
+ * @pfmemalloc: skbuff was allocated from PFMEMALLOC reserves
* @ndisc_nodetype: router type (from link layer)
* @ooo_okay: allow the mapping of a socket to a queue to be changed
* @l4_hash: indicate hash is a canonical 4-tuple hash over transport
@@ -551,8 +552,8 @@ struct sk_buff {
fclone:2,
peeked:1,
head_frag:1,
- xmit_more:1;
- /* one bit hole */
+ xmit_more:1,
+ pfmemalloc:1;
kmemcheck_bitfield_end(flags1);
/* fields enclosed in headers_start/headers_end are copied
@@ -572,19 +573,18 @@ struct sk_buff {
__u8 __pkt_type_offset[0];
__u8 pkt_type:3;
- __u8 pfmemalloc:1;
__u8 ignore_df:1;
__u8 nfctinfo:3;
-
__u8 nf_trace:1;
+
__u8 ip_summed:2;
__u8 ooo_okay:1;
__u8 l4_hash:1;
__u8 sw_hash:1;
__u8 wifi_acked_valid:1;
__u8 wifi_acked:1;
-
__u8 no_fcs:1;
+
/* Indicates the inner headers are valid in the skbuff. */
__u8 encapsulation:1;
__u8 encap_hdr_csum:1;
@@ -592,11 +592,11 @@ struct sk_buff {
__u8 csum_complete_sw:1;
__u8 csum_level:2;
__u8 csum_bad:1;
-
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2;
#endif
__u8 ipvs_property:1;
+
__u8 inner_protocol_type:1;
__u8 fast_forwarded:1;
/* 4 or 6 bit hole */
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 70ceb2a14a57..8e0c151cc07c 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -200,6 +200,9 @@ int __must_check sysfs_create_files(struct kobject *kobj,
const struct attribute **attr);
int __must_check sysfs_chmod_file(struct kobject *kobj,
const struct attribute *attr, umode_t mode);
+struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr);
+void sysfs_unbreak_active_protection(struct kernfs_node *kn);
void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
const void *ns);
bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr);
@@ -299,6 +302,17 @@ static inline int sysfs_chmod_file(struct kobject *kobj,
return 0;
}
+static inline struct kernfs_node *
+sysfs_break_active_protection(struct kobject *kobj,
+ const struct attribute *attr)
+{
+ return NULL;
+}
+
+static inline void sysfs_unbreak_active_protection(struct kernfs_node *kn)
+{
+}
+
static inline void sysfs_remove_file_ns(struct kobject *kobj,
const struct attribute *attr,
const void *ns)
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index 8784cebd0f51..4cf89517783a 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -13,21 +13,6 @@
struct timespec;
struct compat_timespec;
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-struct thread_info {
- u32 flags; /* low level flags */
-};
-
-#define INIT_THREAD_INFO(tsk) \
-{ \
- .flags = 0, \
-}
-#endif
-
-#ifdef CONFIG_THREAD_INFO_IN_TASK
-#define current_thread_info() ((struct thread_info *)current)
-#endif
-
/*
* System call restart block.
*/
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 428277869400..8f9f676f1e16 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -59,7 +59,8 @@ struct vsock_sock {
struct list_head pending_links;
struct list_head accept_queue;
bool rejected;
- struct delayed_work dwork;
+ struct delayed_work connect_work;
+ struct delayed_work pending_work;
u32 peer_shutdown;
bool sent_request;
bool ignore_connecting_rst;
@@ -70,7 +71,6 @@ struct vsock_sock {
s64 vsock_stream_has_data(struct vsock_sock *vsk);
s64 vsock_stream_has_space(struct vsock_sock *vsk);
-void vsock_pending_work(struct work_struct *work);
struct sock *__vsock_create(struct net *net,
struct socket *sock,
struct sock *parent,
diff --git a/include/net/cnss.h b/include/net/cnss.h
index f005b2833706..2375605bb425 100644
--- a/include/net/cnss.h
+++ b/include/net/cnss.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -102,11 +102,14 @@ struct cnss_platform_cap {
u32 cap_flag;
};
-/* WLAN driver status */
+/* WLAN driver status, keep it aligned with cnss2 */
enum cnss_driver_status {
CNSS_UNINITIALIZED,
CNSS_INITIALIZED,
- CNSS_LOAD_UNLOAD
+ CNSS_LOAD_UNLOAD,
+ CNSS_RECOVERY,
+ CNSS_FW_DOWN,
+ CNSS_SSR_FAIL,
};
enum cnss_runtime_request {
diff --git a/include/net/llc.h b/include/net/llc.h
index e8e61d4fb458..82d989995d18 100644
--- a/include/net/llc.h
+++ b/include/net/llc.h
@@ -116,6 +116,11 @@ static inline void llc_sap_hold(struct llc_sap *sap)
atomic_inc(&sap->refcnt);
}
+static inline bool llc_sap_hold_safe(struct llc_sap *sap)
+{
+ return atomic_inc_not_zero(&sap->refcnt);
+}
+
void llc_sap_close(struct llc_sap *sap);
static inline void llc_sap_put(struct llc_sap *sap)
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index ff4081af4d9c..7c9518bf0453 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -112,6 +112,7 @@ struct net {
#endif
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct netns_nf_frag nf_frag;
+ struct ctl_table_header *nf_frag_frags_hdr;
#endif
struct sock *nfnl;
struct sock *nfnl_stash;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 69ae41f2098c..c57d055f76bc 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -81,7 +81,6 @@ struct netns_ipv6 {
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct netns_nf_frag {
- struct netns_sysctl_ipv6 sysctl;
struct netns_frags frags;
};
#endif
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 4969c879a5d6..ee336e033246 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -387,6 +387,7 @@ extern int tcp_use_userconfig_sysctl_handler(struct ctl_table *, int,
extern int tcp_proc_delayed_ack_control(struct ctl_table *, int,
void __user *, size_t *, loff_t *);
+void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks);
static inline void tcp_dec_quickack_mode(struct sock *sk,
const unsigned int pkts)
{
@@ -545,6 +546,7 @@ int tcp_send_synack(struct sock *);
bool tcp_syn_flood_action(struct sock *sk, const struct sk_buff *skb,
const char *proto);
void tcp_push_one(struct sock *, unsigned int mss_now);
+void __tcp_send_ack(struct sock *sk, u32 rcv_nxt);
void tcp_send_ack(struct sock *sk);
void tcp_send_delayed_ack(struct sock *sk);
void tcp_send_loss_probe(struct sock *sk);
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 6f88d5348f2f..d7f7212a74ca 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -3391,6 +3391,8 @@ struct asm_softvolume_params {
#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 0x00010DDC
+#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 0x0001320C
+
#define ASM_MEDIA_FMT_EVRCB_FS 0x00010BEF
#define ASM_MEDIA_FMT_EVRCWB_FS 0x00010BF0
@@ -3493,6 +3495,56 @@ struct asm_multi_channel_pcm_fmt_blk_v3 {
*/
} __packed;
+struct asm_multi_channel_pcm_fmt_blk_v4 {
+ uint16_t num_channels;
+/*
+ * Number of channels
+ * Supported values: 1 to 8
+ */
+
+ uint16_t bits_per_sample;
+/*
+ * Number of bits per sample per channel
+ * Supported values: 16, 24, 32
+ */
+
+ uint32_t sample_rate;
+/*
+ * Number of samples per second
+ * Supported values: 2000 to 48000, 96000,192000 Hz
+ */
+
+ uint16_t is_signed;
+/* Flag that indicates that PCM samples are signed (1) */
+
+ uint16_t sample_word_size;
+/*
+ * Size in bits of the word that holds a sample of a channel.
+ * Supported values: 12,24,32
+ */
+
+ uint8_t channel_mapping[8];
+/*
+ * Each element, i, in the array describes channel i inside the buffer where
+ * 0 <= i < num_channels. Unused channels are set to 0.
+ */
+ uint16_t endianness;
+/*
+ * Flag to indicate the endianness of the pcm sample
+ * Supported values: 0 - Little endian (all other formats)
+ * 1 - Big endian (AIFF)
+ */
+ uint16_t mode;
+/*
+ * Mode to provide additional info about the pcm input data.
+ * Supported values: 0 - Default QFs (Q15 for 16b, Q23 for packed 24b,
+ * Q31 for unpacked 24b or 32b)
+ * 15 - for 16 bit
+ * 23 - for 24b packed or 8.24 format
+ * 31 - for 24b unpacked or 32bit
+ */
+} __packed;
+
/*
* Payload of the multichannel PCM configuration parameters in
* the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3 media format.
@@ -3503,6 +3555,16 @@ struct asm_multi_channel_pcm_fmt_blk_param_v3 {
struct asm_multi_channel_pcm_fmt_blk_v3 param;
} __packed;
+/*
+ * Payload of the multichannel PCM configuration parameters in
+ * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 media format.
+ */
+struct asm_multi_channel_pcm_fmt_blk_param_v4 {
+ struct apr_hdr hdr;
+ struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
+ struct asm_multi_channel_pcm_fmt_blk_v4 param;
+} __packed;
+
struct asm_stream_cmd_set_encdec_param {
u32 param_id;
/* ID of the parameter. */
@@ -3538,6 +3600,79 @@ struct asm_dec_ddp_endp_param_v2 {
int endp_param_value;
} __packed;
+/*
+ * Payload of the multichannel PCM encoder configuration parameters in
+ * the ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4 media format.
+ */
+
+struct asm_multi_channel_pcm_enc_cfg_v4 {
+ struct apr_hdr hdr;
+ struct asm_stream_cmd_set_encdec_param encdec;
+ struct asm_enc_cfg_blk_param_v2 encblk;
+ uint16_t num_channels;
+ /*
+ * Number of PCM channels.
+ * @values
+ * - 0 -- Native mode
+ * - 1 -- 8 channels
+ * Native mode indicates that encoding must be performed with the number
+ * of channels at the input.
+ */
+ uint16_t bits_per_sample;
+ /*
+ * Number of bits per sample per channel.
+ * @values 16, 24
+ */
+ uint32_t sample_rate;
+ /*
+ * Number of samples per second.
+ * @values 0, 8000 to 48000 Hz
+ * A value of 0 indicates the native sampling rate. Encoding is
+ * performed at the input sampling rate.
+ */
+ uint16_t is_signed;
+ /*
+ * Flag that indicates the PCM samples are signed (1). Currently, only
+ * signed PCM samples are supported.
+ */
+ uint16_t sample_word_size;
+ /*
+ * The size in bits of the word that holds a sample of a channel.
+ * @values 16, 24, 32
+ * 16-bit samples are always placed in 16-bit words:
+ * sample_word_size = 1.
+ * 24-bit samples can be placed in 32-bit words or in consecutive
+ * 24-bit words.
+ * - If sample_word_size = 32, 24-bit samples are placed in the
+ * most significant 24 bits of a 32-bit word.
+ * - If sample_word_size = 24, 24-bit samples are placed in
+ * 24-bit words. @tablebulletend
+ */
+ uint8_t channel_mapping[8];
+ /*
+ * Channel mapping array expected at the encoder output.
+ * Channel[i] mapping describes channel i inside the buffer, where
+ * 0 @le i < num_channels. All valid used channels must be present at
+ * the beginning of the array.
+ * If Native mode is set for the channels, this field is ignored.
+ * @values See Section @xref{dox:PcmChannelDefs}
+ */
+ uint16_t endianness;
+ /*
+ * Flag to indicate the endianness of the pcm sample
+ * Supported values: 0 - Little endian (all other formats)
+ * 1 - Big endian (AIFF)
+ */
+ uint16_t mode;
+ /*
+ * Mode to provide additional info about the pcm input data.
+ * Supported values: 0 - Default QFs (Q15 for 16b, Q23 for packed 24b,
+ * Q31 for unpacked 24b or 32b)
+ * 15 - for 16 bit
+ * 23 - for 24b packed or 8.24 format
+ * 31 - for 24b unpacked or 32bit
+ */
+} __packed;
/*
* Payload of the multichannel PCM encoder configuration parameters in
diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h
index c3638978567e..19daccf4b3df 100644
--- a/include/sound/q6adm-v2.h
+++ b/include/sound/q6adm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -28,6 +28,8 @@
#define AUD_VOL_BLOCK_SIZE 4096
#define AUDIO_RX_CALIBRATION_SIZE (AUD_PROC_BLOCK_SIZE + \
AUD_VOL_BLOCK_SIZE)
+#define SESSION_TYPE_RX 0
+#define SESSION_TYPE_TX 1
enum {
ADM_CUSTOM_TOP_CAL = 0,
ADM_AUDPROC_CAL,
@@ -181,5 +183,6 @@ int adm_get_source_tracking(int port_id, int copp_idx,
int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id,
int session_type,
struct msm_pcm_channel_mixer *ch_mixer,
- int channel_index);
+ int channel_index, bool use_default_chmap,
+ char *ch_map);
#endif /* __Q6_ADM_V2_H__ */
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 7771f2468eee..d58cf56c3eb9 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -103,6 +103,24 @@
#define ASM_SHIFT_GAPLESS_MODE_FLAG 31
#define ASM_SHIFT_LAST_BUFFER_FLAG 30
+#define ASM_LITTLE_ENDIAN 0
+#define ASM_BIG_ENDIAN 1
+
+/* PCM_MEDIA_FORMAT_Version */
+enum {
+ PCM_MEDIA_FORMAT_V2 = 0,
+ PCM_MEDIA_FORMAT_V3,
+ PCM_MEDIA_FORMAT_V4,
+};
+
+/* PCM format modes in DSP */
+enum {
+ DEFAULT_QF = 0,
+ Q15 = 15,
+ Q23 = 23,
+ Q31 = 31,
+};
+
/* payload structure bytes */
#define READDONE_IDX_STATUS 0
#define READDONE_IDX_BUFADD_LSW 1
@@ -270,6 +288,9 @@ int q6asm_open_shared_io(struct audio_client *ac,
int q6asm_open_write_v3(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample);
+int q6asm_open_write_v4(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample);
+
int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample, int32_t stream_id,
bool is_gapless_mode);
@@ -278,6 +299,10 @@ int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample, int32_t stream_id,
bool is_gapless_mode);
+int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample, int32_t stream_id,
+ bool is_gapless_mode);
+
int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
uint32_t passthrough_flag);
@@ -386,6 +411,13 @@ int q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
bool use_back_flavor, u8 *channel_map,
uint16_t sample_word_size);
+int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ uint16_t bits_per_sample, bool use_default_chmap,
+ bool use_back_flavor, u8 *channel_map,
+ uint16_t sample_word_size, uint16_t endianness,
+ uint16_t mode);
+
int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
uint32_t rate, uint32_t channels,
uint16_t bits_per_sample);
@@ -395,6 +427,13 @@ int q6asm_enc_cfg_blk_pcm_format_support_v3(struct audio_client *ac,
uint16_t bits_per_sample,
uint16_t sample_word_size);
+int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ uint16_t bits_per_sample,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode);
+
int q6asm_set_encdec_chan_map(struct audio_client *ac,
uint32_t num_channels);
@@ -444,6 +483,17 @@ int q6asm_media_format_block_pcm_format_support_v3(struct audio_client *ac,
char *channel_map,
uint16_t sample_word_size);
+int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac,
+ uint32_t rate,
+ uint32_t channels,
+ uint16_t bits_per_sample,
+ int stream_id,
+ bool use_default_chmap,
+ char *channel_map,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode);
+
int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
uint32_t rate, uint32_t channels,
bool use_default_chmap, char *channel_map);
@@ -461,6 +511,15 @@ int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
uint16_t bits_per_sample,
uint16_t sample_word_size);
+int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ bool use_default_chmap,
+ char *channel_map,
+ uint16_t bits_per_sample,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode);
+
int q6asm_media_format_block_aac(struct audio_client *ac,
struct asm_aac_cfg *cfg);
diff --git a/include/sound/q6core.h b/include/sound/q6core.h
index f21e790ce600..975eda177664 100644
--- a/include/sound/q6core.h
+++ b/include/sound/q6core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -157,4 +157,23 @@ struct avcs_cmd_deregister_topologies {
int32_t core_set_license(uint32_t key, uint32_t module_id);
int32_t core_get_license_status(uint32_t module_id);
+#define AVCS_GET_VERSIONS 0x00012905
+struct avcs_cmd_get_version_result {
+ struct apr_hdr hdr;
+ uint32_t id;
+};
+#define AVCS_GET_VERSIONS_RSP 0x00012906
+
+#define AVCS_CMDRSP_Q6_ID_2_6 0x00040000
+#define AVCS_CMDRSP_Q6_ID_2_7 0x00040001
+#define AVCS_CMDRSP_Q6_ID_2_8 0x00040002
+
+enum q6_subsys_image {
+ Q6_SUBSYS_AVS2_6 = 1,
+ Q6_SUBSYS_AVS2_7,
+ Q6_SUBSYS_AVS2_8,
+ Q6_SUBSYS_INVALID,
+};
+enum q6_subsys_image q6core_get_avs_version(void);
+int core_get_adsp_ver(void);
#endif /* __Q6CORE_H__ */
diff --git a/include/video/udlfb.h b/include/video/udlfb.h
index f9466fa54ba4..2ad9a6d37ff4 100644
--- a/include/video/udlfb.h
+++ b/include/video/udlfb.h
@@ -87,7 +87,7 @@ struct dlfb_data {
#define MIN_RAW_PIX_BYTES 2
#define MIN_RAW_CMD_BYTES (RAW_HEADER_BYTES + MIN_RAW_PIX_BYTES)
-#define DL_DEFIO_WRITE_DELAY 5 /* fb_deferred_io.delay in jiffies */
+#define DL_DEFIO_WRITE_DELAY msecs_to_jiffies(HZ <= 300 ? 4 : 10) /* optimal value for 720p video */
#define DL_DEFIO_WRITE_DISABLE (HZ*60) /* "disable" with long delay */
/* remove these once align.h patch is taken into kernel */
diff --git a/init/Kconfig b/init/Kconfig
index 7e042a043a62..ed4a0cf9845b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -26,13 +26,6 @@ config IRQ_WORK
config BUILDTIME_EXTABLE_SORT
bool
-config THREAD_INFO_IN_TASK
- bool
- help
- Select this to move thread_info off the stack into task_struct. To
- make this work, an arch will need to remove all thread_info fields
- except flags and fix any runtime bugs.
-
menu "General setup"
config BROKEN
diff --git a/init/init_task.c b/init/init_task.c
index 11f83be1fa79..ba0a7f362d9e 100644
--- a/init/init_task.c
+++ b/init/init_task.c
@@ -22,8 +22,5 @@ EXPORT_SYMBOL(init_task);
* Initial thread structure. Alignment of this is handled by a special
* linker map entry.
*/
-union thread_union init_thread_union __init_task_data = {
-#ifndef CONFIG_THREAD_INFO_IN_TASK
- INIT_THREAD_INFO(init_task)
-#endif
-};
+union thread_union init_thread_union __init_task_data =
+ { INIT_THREAD_INFO(init_task) };
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 25a82734790b..9a5761fe8720 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1774,7 +1774,7 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env)
/* hold the map. If the program is rejected by verifier,
* the map will be released by release_maps() or it
* will be used by the valid program until it's unloaded
- * and all maps are released in free_bpf_prog_info()
+ * and all maps are released in free_used_maps()
*/
atomic_inc(&map->refcnt);
@@ -1940,7 +1940,7 @@ int bpf_check(struct bpf_prog *prog, union bpf_attr *attr)
free_env:
if (!prog->aux->used_maps)
/* if we didn't copy map pointers into bpf_prog_info, release
- * them now. Otherwise free_bpf_prog_info() will release them.
+ * them now. Otherwise free_used_maps() will release them.
*/
release_maps(env);
kfree(env);
diff --git a/kernel/futex.c b/kernel/futex.c
index e75c3c414af5..55e87606f80b 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1918,8 +1918,12 @@ static int unqueue_me(struct futex_q *q)
/* In the common case we don't take the spinlock, which is nice. */
retry:
- lock_ptr = q->lock_ptr;
- barrier();
+ /*
+ * q->lock_ptr can change between this read and the following spin_lock.
+ * Use READ_ONCE to forbid the compiler from reloading q->lock_ptr and
+ * optimizing lock_ptr out of the logic below.
+ */
+ lock_ptr = READ_ONCE(q->lock_ptr);
if (lock_ptr != NULL) {
spin_lock(lock_ptr);
/*
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 55240ca8b12c..6780e32471f3 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2425,7 +2425,7 @@ static int __init debugfs_kprobe_init(void)
if (!dir)
return -ENOMEM;
- file = debugfs_create_file("list", 0444, dir, NULL,
+ file = debugfs_create_file("list", 0400, dir, NULL,
&debugfs_kprobes_operations);
if (!file)
goto error;
@@ -2435,7 +2435,7 @@ static int __init debugfs_kprobe_init(void)
if (!file)
goto error;
- file = debugfs_create_file("blacklist", 0444, dir, NULL,
+ file = debugfs_create_file("blacklist", 0400, dir, NULL,
&debugfs_kprobe_blacklist_ops);
if (!file)
goto error;
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 79bfca4170d9..6b03c6cab7da 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -309,10 +309,16 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
task = create->result;
if (!IS_ERR(task)) {
static const struct sched_param param = { .sched_priority = 0 };
+ char name[TASK_COMM_LEN];
va_list args;
va_start(args, namefmt);
- vsnprintf(task->comm, sizeof(task->comm), namefmt, args);
+ /*
+ * task is already visible to other tasks, so updating
+ * COMM must be protected.
+ */
+ vsnprintf(name, sizeof(name), namefmt, args);
+ set_task_comm(task, name);
va_end(args);
/*
* root may have changed our (kthreadd's) priority or CPU mask.
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 3467618cc0ea..f99008534275 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -1253,11 +1253,11 @@ unsigned long lockdep_count_forward_deps(struct lock_class *class)
this.parent = NULL;
this.class = class;
- local_irq_save(flags);
+ raw_local_irq_save(flags);
arch_spin_lock(&lockdep_lock);
ret = __lockdep_count_forward_deps(&this);
arch_spin_unlock(&lockdep_lock);
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
return ret;
}
@@ -1280,11 +1280,11 @@ unsigned long lockdep_count_backward_deps(struct lock_class *class)
this.parent = NULL;
this.class = class;
- local_irq_save(flags);
+ raw_local_irq_save(flags);
arch_spin_lock(&lockdep_lock);
ret = __lockdep_count_backward_deps(&this);
arch_spin_unlock(&lockdep_lock);
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
return ret;
}
@@ -4083,7 +4083,7 @@ void debug_check_no_locks_freed(const void *mem_from, unsigned long mem_len)
if (unlikely(!debug_locks))
return;
- local_irq_save(flags);
+ raw_local_irq_save(flags);
for (i = 0; i < curr->lockdep_depth; i++) {
hlock = curr->held_locks + i;
@@ -4094,7 +4094,7 @@ void debug_check_no_locks_freed(const void *mem_from, unsigned long mem_len)
print_freed_lock_bug(curr, mem_from, mem_from + mem_len, hlock);
break;
}
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
}
EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 9b08657c6915..7cdb1f5a388e 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1019,11 +1019,7 @@ static inline void __set_task_cpu(struct task_struct *p, unsigned int cpu)
* per-task data have been completed by this moment.
*/
smp_wmb();
-#ifdef CONFIG_THREAD_INFO_IN_TASK
- p->cpu = cpu;
-#else
task_thread_info(p)->cpu = cpu;
-#endif
p->wake_cpu = cpu;
#endif
}
diff --git a/kernel/sys.c b/kernel/sys.c
index 38a20992febf..56978d0bfb86 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1128,18 +1128,19 @@ static int override_release(char __user *release, size_t len)
SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
{
- int errno = 0;
+ struct new_utsname tmp;
down_read(&uts_sem);
- if (copy_to_user(name, utsname(), sizeof *name))
- errno = -EFAULT;
+ memcpy(&tmp, utsname(), sizeof(tmp));
up_read(&uts_sem);
+ if (copy_to_user(name, &tmp, sizeof(tmp)))
+ return -EFAULT;
- if (!errno && override_release(name->release, sizeof(name->release)))
- errno = -EFAULT;
- if (!errno && override_architecture(name))
- errno = -EFAULT;
- return errno;
+ if (override_release(name->release, sizeof(name->release)))
+ return -EFAULT;
+ if (override_architecture(name))
+ return -EFAULT;
+ return 0;
}
#ifdef __ARCH_WANT_SYS_OLD_UNAME
@@ -1148,55 +1149,46 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
*/
SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
{
- int error = 0;
+ struct old_utsname tmp;
if (!name)
return -EFAULT;
down_read(&uts_sem);
- if (copy_to_user(name, utsname(), sizeof(*name)))
- error = -EFAULT;
+ memcpy(&tmp, utsname(), sizeof(tmp));
up_read(&uts_sem);
+ if (copy_to_user(name, &tmp, sizeof(tmp)))
+ return -EFAULT;
- if (!error && override_release(name->release, sizeof(name->release)))
- error = -EFAULT;
- if (!error && override_architecture(name))
- error = -EFAULT;
- return error;
+ if (override_release(name->release, sizeof(name->release)))
+ return -EFAULT;
+ if (override_architecture(name))
+ return -EFAULT;
+ return 0;
}
SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
{
- int error;
+ struct oldold_utsname tmp = {};
if (!name)
return -EFAULT;
- if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname)))
- return -EFAULT;
down_read(&uts_sem);
- error = __copy_to_user(&name->sysname, &utsname()->sysname,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->nodename, &utsname()->nodename,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->release, &utsname()->release,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->release + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->version, &utsname()->version,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->version + __OLD_UTS_LEN);
- error |= __copy_to_user(&name->machine, &utsname()->machine,
- __OLD_UTS_LEN);
- error |= __put_user(0, name->machine + __OLD_UTS_LEN);
+ memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
+ memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
+ memcpy(&tmp.release, &utsname()->release, __OLD_UTS_LEN);
+ memcpy(&tmp.version, &utsname()->version, __OLD_UTS_LEN);
+ memcpy(&tmp.machine, &utsname()->machine, __OLD_UTS_LEN);
up_read(&uts_sem);
+ if (copy_to_user(name, &tmp, sizeof(tmp)))
+ return -EFAULT;
- if (!error && override_architecture(name))
- error = -EFAULT;
- if (!error && override_release(name->release, sizeof(name->release)))
- error = -EFAULT;
- return error ? -EFAULT : 0;
+ if (override_architecture(name))
+ return -EFAULT;
+ if (override_release(name->release, sizeof(name->release)))
+ return -EFAULT;
+ return 0;
}
#endif
@@ -1210,17 +1202,18 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
- down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
- struct new_utsname *u = utsname();
+ struct new_utsname *u;
+ down_write(&uts_sem);
+ u = utsname();
memcpy(u->nodename, tmp, len);
memset(u->nodename + len, 0, sizeof(u->nodename) - len);
errno = 0;
uts_proc_notify(UTS_PROC_HOSTNAME);
+ up_write(&uts_sem);
}
- up_write(&uts_sem);
return errno;
}
@@ -1228,8 +1221,9 @@ SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
{
- int i, errno;
+ int i;
struct new_utsname *u;
+ char tmp[__NEW_UTS_LEN + 1];
if (len < 0)
return -EINVAL;
@@ -1238,11 +1232,11 @@ SYSCALL_DEFINE2(gethostname, char __user *, name, int, len)
i = 1 + strlen(u->nodename);
if (i > len)
i = len;
- errno = 0;
- if (copy_to_user(name, u->nodename, i))
- errno = -EFAULT;
+ memcpy(tmp, u->nodename, i);
up_read(&uts_sem);
- return errno;
+ if (copy_to_user(name, tmp, i))
+ return -EFAULT;
+ return 0;
}
#endif
@@ -1261,17 +1255,18 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
- down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
- struct new_utsname *u = utsname();
+ struct new_utsname *u;
+ down_write(&uts_sem);
+ u = utsname();
memcpy(u->domainname, tmp, len);
memset(u->domainname + len, 0, sizeof(u->domainname) - len);
errno = 0;
uts_proc_notify(UTS_PROC_DOMAINNAME);
+ up_write(&uts_sem);
}
- up_write(&uts_sem);
return errno;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index cd23638d823f..fd5e53ccdfb0 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -397,7 +397,8 @@ static struct ctl_table kern_table[] = {
.data = &sysctl_sched_time_avg,
.maxlen = sizeof(unsigned int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &one,
},
{
.procname = "sched_shares_window_ns",
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 5d7e2ca08342..a1f2a0450e99 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1786,6 +1786,10 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
mutex_lock(&bdev->bd_mutex);
if (attr == &dev_attr_enable) {
+ if (!!value == !!q->blk_trace) {
+ ret = 0;
+ goto out_unlock_bdev;
+ }
if (value)
ret = blk_trace_setup_queue(q, bdev);
else
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 68fcf6829bc5..5821def0b7a0 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -3152,6 +3152,22 @@ int ring_buffer_record_is_on(struct ring_buffer *buffer)
return !atomic_read(&buffer->record_disabled);
}
+/**
+ * ring_buffer_record_is_set_on - return true if the ring buffer is set writable
+ * @buffer: The ring buffer to see if write is set enabled
+ *
+ * Returns true if the ring buffer is set writable by ring_buffer_record_on().
+ * Note that this does NOT mean it is in a writable state.
+ *
+ * It may return true when the ring buffer has been disabled by
+ * ring_buffer_record_disable(), as that is a temporary disabling of
+ * the ring buffer.
+ */
+int ring_buffer_record_is_set_on(struct ring_buffer *buffer)
+{
+ return !(atomic_read(&buffer->record_disabled) & RB_BUFFER_OFF);
+}
+
/**
* ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer
* @buffer: The ring buffer to stop writes to.
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 92e73e37f4bf..1db5a2ec2264 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1030,6 +1030,12 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
arch_spin_lock(&tr->max_lock);
+ /* Inherit the recordable setting from trace_buffer */
+ if (ring_buffer_record_is_set_on(tr->trace_buffer.buffer))
+ ring_buffer_record_on(tr->max_buffer.buffer);
+ else
+ ring_buffer_record_off(tr->max_buffer.buffer);
+
buf = tr->trace_buffer.buffer;
tr->trace_buffer.buffer = tr->max_buffer.buffer;
tr->max_buffer.buffer = buf;
@@ -2183,6 +2189,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
}
EXPORT_SYMBOL_GPL(trace_vbprintk);
+__printf(3, 0)
static int
__trace_array_vprintk(struct ring_buffer *buffer,
unsigned long ip, const char *fmt, va_list args)
@@ -2237,12 +2244,14 @@ __trace_array_vprintk(struct ring_buffer *buffer,
return len;
}
+__printf(3, 0)
int trace_array_vprintk(struct trace_array *tr,
unsigned long ip, const char *fmt, va_list args)
{
return __trace_array_vprintk(tr->trace_buffer.buffer, ip, fmt, args);
}
+__printf(3, 0)
int trace_array_printk(struct trace_array *tr,
unsigned long ip, const char *fmt, ...)
{
@@ -2258,6 +2267,7 @@ int trace_array_printk(struct trace_array *tr,
return ret;
}
+__printf(3, 4)
int trace_array_printk_buf(struct ring_buffer *buffer,
unsigned long ip, const char *fmt, ...)
{
@@ -2273,6 +2283,7 @@ int trace_array_printk_buf(struct ring_buffer *buffer,
return ret;
}
+__printf(2, 0)
int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
{
return trace_array_vprintk(&global_trace, ip, fmt, args);
@@ -6326,7 +6337,9 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
if (buffer) {
mutex_lock(&trace_types_lock);
- if (val) {
+ if (!!val == tracer_tracing_is_on(tr)) {
+ val = 0; /* do nothing */
+ } else if (val) {
tracer_tracing_on(tr);
if (tr->current_trace->start)
tr->current_trace->start(tr);
diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c
index b743e758241e..a958d3397a52 100644
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -663,6 +663,8 @@ event_trigger_callback(struct event_command *cmd_ops,
goto out_free;
out_reg:
+ /* Up the trigger_data count to make sure reg doesn't free it on failure */
+ event_trigger_init(trigger_ops, trigger_data);
ret = cmd_ops->reg(glob, trigger_ops, trigger_data, file);
/*
* The above returns on success the # of functions enabled,
@@ -670,11 +672,13 @@ event_trigger_callback(struct event_command *cmd_ops,
* Consider no functions a failure too.
*/
if (!ret) {
+ cmd_ops->unreg(glob, trigger_ops, trigger_data, file);
ret = -ENOENT;
- goto out_free;
- } else if (ret < 0)
- goto out_free;
- ret = 0;
+ } else if (ret > 0)
+ ret = 0;
+
+ /* Down the counter of trigger_data or free it if not used anymore */
+ event_trigger_free(trigger_ops, trigger_data);
out:
return ret;
@@ -1227,6 +1231,9 @@ event_enable_trigger_func(struct event_command *cmd_ops,
goto out;
}
+ /* Up the trigger_data count to make sure nothing frees it on failure */
+ event_trigger_init(trigger_ops, trigger_data);
+
if (trigger) {
number = strsep(&trigger, ":");
@@ -1277,6 +1284,7 @@ event_enable_trigger_func(struct event_command *cmd_ops,
goto out_disable;
/* Just return zero, not the number of enabled functions */
ret = 0;
+ event_trigger_free(trigger_ops, trigger_data);
out:
return ret;
@@ -1287,7 +1295,7 @@ event_enable_trigger_func(struct event_command *cmd_ops,
out_free:
if (cmd_ops->set_filter)
cmd_ops->set_filter(NULL, trigger_data, NULL);
- kfree(trigger_data);
+ event_trigger_free(trigger_ops, trigger_data);
kfree(enable_data);
goto out;
}
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 940a91ac7d86..efbb9aa0c8ba 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -361,11 +361,10 @@ static struct trace_kprobe *find_trace_kprobe(const char *event,
static int
enable_trace_kprobe(struct trace_kprobe *tk, struct ftrace_event_file *file)
{
+ struct event_file_link *link = NULL;
int ret = 0;
if (file) {
- struct event_file_link *link;
-
link = kmalloc(sizeof(*link), GFP_KERNEL);
if (!link) {
ret = -ENOMEM;
@@ -385,6 +384,18 @@ enable_trace_kprobe(struct trace_kprobe *tk, struct ftrace_event_file *file)
else
ret = enable_kprobe(&tk->rp.kp);
}
+
+ if (ret) {
+ if (file) {
+ /* Notice the if is true on not WARN() */
+ if (!WARN_ON_ONCE(!link))
+ list_del_rcu(&link->list);
+ kfree(link);
+ tk->tp.flags &= ~TP_FLAG_TRACE;
+ } else {
+ tk->tp.flags &= ~TP_FLAG_PROFILE;
+ }
+ }
out:
return ret;
}
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index c2af9b9e32d4..47221e802a4a 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -957,7 +957,7 @@ probe_event_disable(struct trace_uprobe *tu, struct ftrace_event_file *file)
list_del_rcu(&link->list);
/* synchronize with u{,ret}probe_trace_func */
- synchronize_sched();
+ synchronize_rcu();
kfree(link);
if (!list_empty(&tu->tp.files))
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index cc9689628427..69210b6d5013 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -601,9 +601,26 @@ static ssize_t map_write(struct file *file, const char __user *buf,
struct uid_gid_map new_map;
unsigned idx;
struct uid_gid_extent *extent = NULL;
- unsigned long page = 0;
+ unsigned long page;
char *kbuf, *pos, *next_line;
- ssize_t ret = -EINVAL;
+ ssize_t ret;
+
+ /* Only allow < page size writes at the beginning of the file */
+ if ((*ppos != 0) || (count >= PAGE_SIZE))
+ return -EINVAL;
+
+ /* Get a buffer */
+ page = __get_free_page(GFP_TEMPORARY);
+ kbuf = (char *) page;
+ if (!page)
+ return -ENOMEM;
+
+ /* Slurp in the user data */
+ if (copy_from_user(kbuf, buf, count)) {
+ free_page(page);
+ return -EFAULT;
+ }
+ kbuf[count] = '\0';
/*
* The userns_state_mutex serializes all writes to any given map.
@@ -637,24 +654,6 @@ static ssize_t map_write(struct file *file, const char __user *buf,
if (cap_valid(cap_setid) && !file_ns_capable(file, ns, CAP_SYS_ADMIN))
goto out;
- /* Get a buffer */
- ret = -ENOMEM;
- page = __get_free_page(GFP_TEMPORARY);
- kbuf = (char *) page;
- if (!page)
- goto out;
-
- /* Only allow <= page size writes at the beginning of the file */
- ret = -EINVAL;
- if ((*ppos != 0) || (count >= PAGE_SIZE))
- goto out;
-
- /* Slurp in the user data */
- ret = -EFAULT;
- if (copy_from_user(kbuf, buf, count))
- goto out;
- kbuf[count] = '\0';
-
/* Parse the user data */
ret = -EINVAL;
pos = kbuf;
diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c
index c8eac43267e9..d2b3b2973456 100644
--- a/kernel/utsname_sysctl.c
+++ b/kernel/utsname_sysctl.c
@@ -17,7 +17,7 @@
#ifdef CONFIG_PROC_SYSCTL
-static void *get_uts(struct ctl_table *table, int write)
+static void *get_uts(struct ctl_table *table)
{
char *which = table->data;
struct uts_namespace *uts_ns;
@@ -25,21 +25,9 @@ static void *get_uts(struct ctl_table *table, int write)
uts_ns = current->nsproxy->uts_ns;
which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
- if (!write)
- down_read(&uts_sem);
- else
- down_write(&uts_sem);
return which;
}
-static void put_uts(struct ctl_table *table, int write, void *which)
-{
- if (!write)
- up_read(&uts_sem);
- else
- up_write(&uts_sem);
-}
-
/*
* Special case of dostring for the UTS structure. This has locks
* to observe. Should this be in kernel/sys.c ????
@@ -49,13 +37,34 @@ static int proc_do_uts_string(struct ctl_table *table, int write,
{
struct ctl_table uts_table;
int r;
+ char tmp_data[__NEW_UTS_LEN + 1];
+
memcpy(&uts_table, table, sizeof(uts_table));
- uts_table.data = get_uts(table, write);
+ uts_table.data = tmp_data;
+
+ /*
+ * Buffer the value in tmp_data so that proc_dostring() can be called
+ * without holding any locks.
+ * We also need to read the original value in the write==1 case to
+ * support partial writes.
+ */
+ down_read(&uts_sem);
+ memcpy(tmp_data, get_uts(table), sizeof(tmp_data));
+ up_read(&uts_sem);
r = proc_dostring(&uts_table, write, buffer, lenp, ppos);
- put_uts(table, write, uts_table.data);
- if (write)
+ if (write) {
+ /*
+ * Write back the new value.
+ * Note that, since we dropped uts_sem, the result can
+ * theoretically be incorrect if there are two parallel writes
+ * at non-zero offsets to the same sysctl.
+ */
+ down_write(&uts_sem);
+ memcpy(get_uts(table), tmp_data, sizeof(tmp_data));
+ up_write(&uts_sem);
proc_sys_poll_notify(table->poll);
+ }
return r;
}
diff --git a/mm/memory.c b/mm/memory.c
index 8e65576031c2..376854e7367b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -359,15 +359,6 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
{
struct mmu_table_batch **batch = &tlb->batch;
- /*
- * When there's less then two users of this mm there cannot be a
- * concurrent page-table walk.
- */
- if (atomic_read(&tlb->mm->mm_users) < 2) {
- __tlb_remove_table(table);
- return;
- }
-
if (*batch == NULL) {
*batch = (struct mmu_table_batch *)__get_free_page(GFP_NOWAIT | __GFP_NOWARN);
if (*batch == NULL) {
@@ -3523,6 +3514,9 @@ int generic_access_phys(struct vm_area_struct *vma, unsigned long addr,
return -EINVAL;
maddr = ioremap_prot(phys_addr, PAGE_ALIGN(len + offset), prot);
+ if (!maddr)
+ return -ENOMEM;
+
if (write)
memcpy_toio(maddr + offset, buf, len);
else
diff --git a/mm/slub.c b/mm/slub.c
index 6a2f3f115203..35a432cc3e24 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -699,7 +699,7 @@ void object_err(struct kmem_cache *s, struct page *page,
slab_panic(reason);
}
-static void slab_err(struct kmem_cache *s, struct page *page,
+static __printf(3, 4) void slab_err(struct kmem_cache *s, struct page *page,
const char *fmt, ...)
{
va_list args;
@@ -925,12 +925,12 @@ static int check_slab(struct kmem_cache *s, struct page *page)
maxobj = order_objects(compound_order(page), s->size, s->reserved);
if (page->objects > maxobj) {
slab_err(s, page, "objects %u > max %u",
- s->name, page->objects, maxobj);
+ page->objects, maxobj);
return 0;
}
if (page->inuse > page->objects) {
slab_err(s, page, "inuse %u > max %u",
- s->name, page->inuse, page->objects);
+ page->inuse, page->objects);
return 0;
}
/* Slab_pad_check fixes things up after itself */
@@ -947,7 +947,7 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
int nr = 0;
void *fp;
void *object = NULL;
- unsigned long max_objects;
+ int max_objects;
fp = page->freelist;
while (fp && nr <= page->objects) {
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 80ece7cedc9f..3066e7236772 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -1527,7 +1527,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
addr))
return;
- area = remove_vm_area(addr);
+ area = find_vmap_area((unsigned long)addr)->vm;
if (unlikely(!area)) {
WARN(1, KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n",
addr);
@@ -1537,6 +1537,7 @@ static void __vunmap(const void *addr, int deallocate_pages)
debug_check_no_locks_freed(addr, get_vm_area_size(area));
debug_check_no_obj_freed(addr, get_vm_area_size(area));
+ remove_vm_area(addr);
if (deallocate_pages) {
int i;
diff --git a/mm/zswap.c b/mm/zswap.c
index e2f8c7e3c643..7af943e25ddd 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -662,6 +662,15 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
ret = -ENOMEM;
goto reject;
}
+
+ /* A second zswap_is_full() check after
+ * zswap_shrink() to make sure it's now
+ * under the max_pool_percent
+ */
+ if (zswap_is_full()) {
+ ret = -ENOMEM;
+ goto reject;
+ }
}
/* allocate entry */
diff --git a/net/9p/client.c b/net/9p/client.c
index f24b774d2215..7122b32b310f 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -938,7 +938,7 @@ static int p9_client_version(struct p9_client *c)
{
int err = 0;
struct p9_req_t *req;
- char *version;
+ char *version = NULL;
int msize;
p9_debug(P9_DEBUG_9P, ">>> TVERSION msize %d protocol %d\n",
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 80d08f6664cb..9d935dc71b83 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -185,6 +185,8 @@ static void p9_mux_poll_stop(struct p9_conn *m)
spin_lock_irqsave(&p9_poll_lock, flags);
list_del_init(&m->poll_pending_link);
spin_unlock_irqrestore(&p9_poll_lock, flags);
+
+ flush_work(&p9_poll_work);
}
/**
@@ -932,7 +934,7 @@ p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
if (err < 0)
return err;
- if (valid_ipaddr4(addr) < 0)
+ if (addr == NULL || valid_ipaddr4(addr) < 0)
return -EINVAL;
csocket = NULL;
@@ -980,6 +982,9 @@ p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
csocket = NULL;
+ if (addr == NULL)
+ return -EINVAL;
+
if (strlen(addr) >= UNIX_PATH_MAX) {
pr_err("%s (%d): address too long: %s\n",
__func__, task_pid_nr(current), addr);
diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c
index 14ad43b5cf89..d00cb890398b 100644
--- a/net/9p/trans_rdma.c
+++ b/net/9p/trans_rdma.c
@@ -623,6 +623,9 @@ rdma_create_trans(struct p9_client *client, const char *addr, char *args)
struct ib_qp_init_attr qp_attr;
struct ib_device_attr devattr;
+ if (addr == NULL)
+ return -EINVAL;
+
/* Parse the transport specific mount options */
err = parse_opts(args, &opts);
if (err < 0)
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 071ac5c495fc..130180f67ae3 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -192,7 +192,7 @@ static int pack_sg_list(struct scatterlist *sg, int start,
s = rest_of_page(data);
if (s > count)
s = count;
- BUG_ON(index > limit);
+ BUG_ON(index >= limit);
/* Make sure we don't terminate early. */
sg_unmark_end(&sg[index]);
sg_set_buf(&sg[index++], data, s);
@@ -238,6 +238,7 @@ pack_sg_list_p(struct scatterlist *sg, int start, int limit,
s = rest_of_page(data);
if (s > count)
s = count;
+ BUG_ON(index >= limit);
/* Make sure we don't terminate early. */
sg_unmark_end(&sg[index]);
sg_set_page(&sg[index++], pdata[i++], s, data_off);
@@ -616,6 +617,9 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
int ret = -ENOENT;
int found = 0;
+ if (devname == NULL)
+ return -EINVAL;
+
mutex_lock(&virtio_9p_lock);
list_for_each_entry(chan, &virtio_chan_list, chan_list) {
if (!strncmp(devname, chan->tag, chan->tag_len) &&
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 99624495f6c2..3af082bf7c64 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -416,8 +416,8 @@ static void hidp_del_timer(struct hidp_session *session)
del_timer(&session->timer);
}
-static void hidp_process_report(struct hidp_session *session,
- int type, const u8 *data, int len, int intr)
+static void hidp_process_report(struct hidp_session *session, int type,
+ const u8 *data, unsigned int len, int intr)
{
if (len > HID_MAX_BUFFER_SIZE)
len = HID_MAX_BUFFER_SIZE;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 8c54cb211a4d..0882ce101ac8 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -390,7 +390,8 @@ static void sco_sock_cleanup_listen(struct sock *parent)
*/
static void sco_sock_kill(struct sock *sk)
{
- if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket)
+ if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket ||
+ sock_flag(sk, SOCK_DEAD))
return;
BT_DBG("sk %pK state %d", sk, sk->sk_state);
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c
index edbca468fa73..d8e56a5c1a94 100644
--- a/net/caif/caif_dev.c
+++ b/net/caif/caif_dev.c
@@ -131,8 +131,10 @@ static void caif_flow_cb(struct sk_buff *skb)
caifd = caif_get(skb->dev);
WARN_ON(caifd == NULL);
- if (caifd == NULL)
+ if (!caifd) {
+ rcu_read_unlock();
return;
+ }
caifd_hold(caifd);
rcu_read_unlock();
diff --git a/net/core/dev.c b/net/core/dev.c
index af29dd323dbe..dfbf18114d18 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -7046,7 +7046,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
/* We get here if we can't use the current device name */
if (!pat)
goto out;
- if (dev_get_valid_name(net, dev, pat) < 0)
+ err = dev_get_valid_name(net, dev, pat);
+ if (err < 0)
goto out;
}
@@ -7058,7 +7059,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
dev_close(dev);
/* And unlink it from device chain */
- err = -ENODEV;
unlist_netdevice(dev);
synchronize_net();
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 9fd2c9eb54e8..51301ad3c2d9 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1842,9 +1842,12 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm)
return err;
}
- dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
-
- __dev_notify_flags(dev, old_flags, ~0U);
+ if (dev->rtnl_link_state == RTNL_LINK_INITIALIZED) {
+ __dev_notify_flags(dev, old_flags, 0U);
+ } else {
+ dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
+ __dev_notify_flags(dev, old_flags, ~0U);
+ }
return 0;
}
EXPORT_SYMBOL(rtnl_configure_link);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7f13431d0633..2f7adf089922 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -803,6 +803,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
n->cloned = 1;
n->nohdr = 0;
n->peeked = 0;
+ C(pfmemalloc);
n->destructor = NULL;
C(tail);
C(end);
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 86a2ed0fb219..161dfcf86126 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -228,14 +228,16 @@ static void ccid2_cwnd_restart(struct sock *sk, const u32 now)
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
u32 cwnd = hc->tx_cwnd, restart_cwnd,
iwnd = rfc3390_bytes_to_packets(dccp_sk(sk)->dccps_mss_cache);
+ s32 delta = now - hc->tx_lsndtime;
hc->tx_ssthresh = max(hc->tx_ssthresh, (cwnd >> 1) + (cwnd >> 2));
/* don't reduce cwnd below the initial window (IW) */
restart_cwnd = min(cwnd, iwnd);
- cwnd >>= (now - hc->tx_lsndtime) / hc->tx_rto;
- hc->tx_cwnd = max(cwnd, restart_cwnd);
+ while ((delta -= hc->tx_rto) >= 0 && cwnd > restart_cwnd)
+ cwnd >>= 1;
+ hc->tx_cwnd = max(cwnd, restart_cwnd);
hc->tx_cwnd_stamp = now;
hc->tx_cwnd_used = 0;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index ab03e00ffe8f..95f63b79f03e 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -503,6 +503,9 @@ int dsa_slave_suspend(struct net_device *slave_dev)
{
struct dsa_slave_priv *p = netdev_priv(slave_dev);
+ if (!netif_running(slave_dev))
+ return 0;
+
netif_device_detach(slave_dev);
if (p->phy) {
@@ -520,6 +523,9 @@ int dsa_slave_resume(struct net_device *slave_dev)
{
struct dsa_slave_priv *p = netdev_priv(slave_dev);
+ if (!netif_running(slave_dev))
+ return 0;
+
netif_device_attach(slave_dev);
if (p->phy) {
diff --git a/net/ipc_router/ipc_router_socket.c b/net/ipc_router/ipc_router_socket.c
index 8604152dc577..1641509c9352 100644
--- a/net/ipc_router/ipc_router_socket.c
+++ b/net/ipc_router/ipc_router_socket.c
@@ -155,6 +155,7 @@ static int msm_ipc_router_extract_msg(struct msghdr *m,
return -EINVAL;
}
ctl_msg = (union rr_control_msg *)(temp->data);
+ memset(addr, 0x0, sizeof(*addr));
addr->family = AF_MSM_IPC;
addr->address.addrtype = MSM_IPC_ADDR_ID;
addr->address.addr.port_addr.node_id = ctl_msg->cli.node_id;
@@ -163,6 +164,7 @@ static int msm_ipc_router_extract_msg(struct msghdr *m,
return offset;
}
if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_DATA)) {
+ memset(addr, 0x0, sizeof(*addr));
addr->family = AF_MSM_IPC;
addr->address.addrtype = MSM_IPC_ADDR_ID;
addr->address.addr.port_addr.node_id = hdr->src_node_id;
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index e08003d026eb..a5e2646c859d 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -1591,9 +1591,17 @@ unsigned char *cipso_v4_optptr(const struct sk_buff *skb)
int taglen;
for (optlen = iph->ihl*4 - sizeof(struct iphdr); optlen > 0; ) {
- if (optptr[0] == IPOPT_CIPSO)
+ switch (optptr[0]) {
+ case IPOPT_CIPSO:
return optptr;
- taglen = optptr[1];
+ case IPOPT_END:
+ return NULL;
+ case IPOPT_NOOP:
+ taglen = 1;
+ break;
+ default:
+ taglen = optptr[1];
+ }
optlen -= taglen;
optptr += taglen;
}
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 82dc74052ee3..3ca7b4b66b8b 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -209,19 +209,19 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
return ip_hdr(skb)->daddr;
in_dev = __in_dev_get_rcu(dev);
- BUG_ON(!in_dev);
net = dev_net(dev);
scope = RT_SCOPE_UNIVERSE;
if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
+ bool vmark = in_dev && IN_DEV_SRC_VMARK(in_dev);
fl4.flowi4_oif = 0;
fl4.flowi4_iif = LOOPBACK_IFINDEX;
fl4.daddr = ip_hdr(skb)->saddr;
fl4.saddr = 0;
fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
fl4.flowi4_scope = scope;
- fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
+ fl4.flowi4_mark = vmark ? skb->mark : 0;
if (!fib_lookup(net, &fl4, &res))
return FIB_RES_PREFSRC(net, res);
} else {
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 19419b60cb37..0d950edb33c2 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -379,11 +379,6 @@ static struct inet_frag_queue *inet_frag_alloc(struct netns_frags *nf,
{
struct inet_frag_queue *q;
- if (frag_mem_limit(nf) > nf->high_thresh) {
- inet_frag_schedule_worker(f);
- return NULL;
- }
-
q = kmem_cache_zalloc(f->frags_cachep, GFP_ATOMIC);
if (q == NULL)
return NULL;
@@ -420,6 +415,11 @@ struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
struct inet_frag_queue *q;
int depth = 0;
+ if (!nf->high_thresh || frag_mem_limit(nf) > nf->high_thresh) {
+ inet_frag_schedule_worker(f);
+ return NULL;
+ }
+
if (frag_mem_limit(nf) > nf->low_thresh)
inet_frag_schedule_worker(f);
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 7f7bf44b1b91..638adc599e06 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -459,6 +459,8 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->dev = from->dev;
to->mark = from->mark;
+ skb_copy_hash(to, from);
+
/* Copy the flags to each fragment. */
IPCB(to)->flags = IPCB(from)->flags;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 648fa1490ea7..3da772ae8808 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -772,6 +772,11 @@ static void __init ic_bootp_init_ext(u8 *e)
*/
static inline void __init ic_bootp_init(void)
{
+ /* Re-initialise all name servers to NONE, in case any were set via the
+ * "ip=" or "nfsaddrs=" kernel command line parameters: any IP addresses
+ * specified there will already have been decoded but are no longer
+ * needed
+ */
ic_nameservers_predef();
dev_add_pack(&bootp_packet_type);
@@ -1404,6 +1409,13 @@ static int __init ip_auto_config(void)
int err;
unsigned int i;
+ /* Initialise all name servers to NONE (but only if the "ip=" or
+ * "nfsaddrs=" kernel command line parameters weren't decoded, otherwise
+ * we'll overwrite the IP addresses specified there)
+ */
+ if (ic_set_manually == 0)
+ ic_nameservers_predef();
+
#ifdef CONFIG_PROC_FS
proc_create("pnp", S_IRUGO, init_net.proc_net, &pnp_seq_fops);
#endif /* CONFIG_PROC_FS */
@@ -1605,6 +1617,7 @@ static int __init ip_auto_config_setup(char *addrs)
return 1;
}
+ /* Initialise all name servers to NONE */
ic_nameservers_predef();
/* Parse string for static IP assignment. */
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 3f2e38a971dc..2bd31846858c 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -2081,6 +2081,7 @@ static struct xt_match ipt_builtin_mt[] __read_mostly = {
.checkentry = icmp_checkentry,
.proto = IPPROTO_ICMP,
.family = NFPROTO_IPV4,
+ .me = THIS_MODULE,
},
};
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 562f50e272b6..f8841a5f8e0c 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -138,8 +138,9 @@ static int ipv4_ping_group_range(struct ctl_table *table, int write,
if (write && ret == 0) {
low = make_kgid(user_ns, urange[0]);
high = make_kgid(user_ns, urange[1]);
- if (!gid_valid(low) || !gid_valid(high) ||
- (urange[1] < urange[0]) || gid_lt(high, low)) {
+ if (!gid_valid(low) || !gid_valid(high))
+ return -EINVAL;
+ if (urange[1] < urange[0] || gid_lt(high, low)) {
low = make_kgid(&init_user_ns, 1);
high = make_kgid(&init_user_ns, 0);
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 179506f53e1e..391ef03ce2f6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1684,7 +1684,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
* shouldn't happen.
*/
if (WARN(before(*seq, TCP_SKB_CB(skb)->seq),
- "recvmsg bug: copied %X seq %X rcvnxt %X fl %X\n",
+ "TCP recvmsg seq # bug: copied %X, seq %X, rcvnxt %X, fl %X\n",
*seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt,
flags))
break;
@@ -1697,7 +1697,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN)
goto found_fin_ok;
WARN(!(flags & MSG_PEEK),
- "recvmsg bug 2: copied %X seq %X rcvnxt %X fl %X\n",
+ "TCP recvmsg seq # bug 2: copied %X, seq %X, rcvnxt %X, fl %X\n",
*seq, TCP_SKB_CB(skb)->seq, tp->rcv_nxt, flags);
}
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c
index b504371af742..583b9935ebb5 100644
--- a/net/ipv4/tcp_dctcp.c
+++ b/net/ipv4/tcp_dctcp.c
@@ -128,23 +128,14 @@ static void dctcp_ce_state_0_to_1(struct sock *sk)
struct dctcp *ca = inet_csk_ca(sk);
struct tcp_sock *tp = tcp_sk(sk);
- /* State has changed from CE=0 to CE=1 and delayed
- * ACK has not sent yet.
- */
- if (!ca->ce_state && ca->delayed_ack_reserved) {
- u32 tmp_rcv_nxt;
-
- /* Save current rcv_nxt. */
- tmp_rcv_nxt = tp->rcv_nxt;
-
- /* Generate previous ack with CE=0. */
- tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
- tp->rcv_nxt = ca->prior_rcv_nxt;
-
- tcp_send_ack(sk);
-
- /* Recover current rcv_nxt. */
- tp->rcv_nxt = tmp_rcv_nxt;
+ if (!ca->ce_state) {
+ /* State has changed from CE=0 to CE=1, force an immediate
+ * ACK to reflect the new CE state. If an ACK was delayed,
+ * send that first to reflect the prior CE state.
+ */
+ if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER)
+ __tcp_send_ack(sk, ca->prior_rcv_nxt);
+ tcp_enter_quickack_mode(sk, 1);
}
ca->prior_rcv_nxt = tp->rcv_nxt;
@@ -158,23 +149,14 @@ static void dctcp_ce_state_1_to_0(struct sock *sk)
struct dctcp *ca = inet_csk_ca(sk);
struct tcp_sock *tp = tcp_sk(sk);
- /* State has changed from CE=1 to CE=0 and delayed
- * ACK has not sent yet.
- */
- if (ca->ce_state && ca->delayed_ack_reserved) {
- u32 tmp_rcv_nxt;
-
- /* Save current rcv_nxt. */
- tmp_rcv_nxt = tp->rcv_nxt;
-
- /* Generate previous ack with CE=1. */
- tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
- tp->rcv_nxt = ca->prior_rcv_nxt;
-
- tcp_send_ack(sk);
-
- /* Recover current rcv_nxt. */
- tp->rcv_nxt = tmp_rcv_nxt;
+ if (ca->ce_state) {
+ /* State has changed from CE=1 to CE=0, force an immediate
+ * ACK to reflect the new CE state. If an ACK was delayed,
+ * send that first to reflect the prior CE state.
+ */
+ if (inet_csk(sk)->icsk_ack.pending & ICSK_ACK_TIMER)
+ __tcp_send_ack(sk, ca->prior_rcv_nxt);
+ tcp_enter_quickack_mode(sk, 1);
}
ca->prior_rcv_nxt = tp->rcv_nxt;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index c69d8d2b8a94..25e1dab3e2b0 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -172,24 +172,27 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)
}
}
-static void tcp_incr_quickack(struct sock *sk)
+static void tcp_incr_quickack(struct sock *sk, unsigned int max_quickacks)
{
struct inet_connection_sock *icsk = inet_csk(sk);
unsigned int quickacks = tcp_sk(sk)->rcv_wnd / (2 * icsk->icsk_ack.rcv_mss);
if (quickacks == 0)
quickacks = 2;
+ quickacks = min(quickacks, max_quickacks);
if (quickacks > icsk->icsk_ack.quick)
- icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS);
+ icsk->icsk_ack.quick = quickacks;
}
-static void tcp_enter_quickack_mode(struct sock *sk)
+void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks)
{
struct inet_connection_sock *icsk = inet_csk(sk);
- tcp_incr_quickack(sk);
+
+ tcp_incr_quickack(sk, max_quickacks);
icsk->icsk_ack.pingpong = 0;
icsk->icsk_ack.ato = TCP_ATO_MIN;
}
+EXPORT_SYMBOL(tcp_enter_quickack_mode);
/* Send ACKs quickly, if "quick" count is not exhausted
* and the session is not interactive.
@@ -219,8 +222,10 @@ static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp)
tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
}
-static void __tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
+static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
{
+ struct tcp_sock *tp = tcp_sk(sk);
+
switch (TCP_SKB_CB(skb)->ip_dsfield & INET_ECN_MASK) {
case INET_ECN_NOT_ECT:
/* Funny extension: if ECT is not set on a segment,
@@ -228,31 +233,31 @@ static void __tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
* it is probably a retransmit.
*/
if (tp->ecn_flags & TCP_ECN_SEEN)
- tcp_enter_quickack_mode((struct sock *)tp);
+ tcp_enter_quickack_mode(sk, 2);
break;
case INET_ECN_CE:
- if (tcp_ca_needs_ecn((struct sock *)tp))
- tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_IS_CE);
+ if (tcp_ca_needs_ecn(sk))
+ tcp_ca_event(sk, CA_EVENT_ECN_IS_CE);
if (!(tp->ecn_flags & TCP_ECN_DEMAND_CWR)) {
/* Better not delay acks, sender can have a very low cwnd */
- tcp_enter_quickack_mode((struct sock *)tp);
+ tcp_enter_quickack_mode(sk, 2);
tp->ecn_flags |= TCP_ECN_DEMAND_CWR;
}
tp->ecn_flags |= TCP_ECN_SEEN;
break;
default:
- if (tcp_ca_needs_ecn((struct sock *)tp))
- tcp_ca_event((struct sock *)tp, CA_EVENT_ECN_NO_CE);
+ if (tcp_ca_needs_ecn(sk))
+ tcp_ca_event(sk, CA_EVENT_ECN_NO_CE);
tp->ecn_flags |= TCP_ECN_SEEN;
break;
}
}
-static void tcp_ecn_check_ce(struct tcp_sock *tp, const struct sk_buff *skb)
+static void tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
{
- if (tp->ecn_flags & TCP_ECN_OK)
- __tcp_ecn_check_ce(tp, skb);
+ if (tcp_sk(sk)->ecn_flags & TCP_ECN_OK)
+ __tcp_ecn_check_ce(sk, skb);
}
static void tcp_ecn_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th)
@@ -644,7 +649,7 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
/* The _first_ data packet received, initialize
* delayed ACK engine.
*/
- tcp_incr_quickack(sk);
+ tcp_incr_quickack(sk, TCP_MAX_QUICKACKS);
icsk->icsk_ack.ato = TCP_ATO_MIN;
} else {
int m = now - icsk->icsk_ack.lrcvtime;
@@ -660,13 +665,13 @@ static void tcp_event_data_recv(struct sock *sk, struct sk_buff *skb)
/* Too long gap. Apparently sender failed to
* restart window, so that we send ACKs quickly.
*/
- tcp_incr_quickack(sk);
+ tcp_incr_quickack(sk, TCP_MAX_QUICKACKS);
sk_mem_reclaim(sk);
}
}
icsk->icsk_ack.lrcvtime = now;
- tcp_ecn_check_ce(tp, skb);
+ tcp_ecn_check_ce(sk, skb);
if (skb->len >= 128)
tcp_grow_window(sk, skb);
@@ -4007,7 +4012,7 @@ static void tcp_send_dupack(struct sock *sk, const struct sk_buff *skb)
if (TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb)->seq &&
before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);
- tcp_enter_quickack_mode(sk);
+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
if (tcp_is_sack(tp) && sysctl_tcp_dsack) {
u32 end_seq = TCP_SKB_CB(skb)->end_seq;
@@ -4235,7 +4240,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb)
struct sk_buff *skb1;
u32 seq, end_seq;
- tcp_ecn_check_ce(tp, skb);
+ tcp_ecn_check_ce(sk, skb);
if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPOFODROP);
@@ -4507,7 +4512,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
tcp_dsack_set(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq);
out_of_window:
- tcp_enter_quickack_mode(sk);
+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
inet_csk_schedule_ack(sk);
drop:
__kfree_skb(skb);
@@ -4518,8 +4523,6 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
if (!before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt + tcp_receive_window(tp)))
goto out_of_window;
- tcp_enter_quickack_mode(sk);
-
if (before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
/* Partial packet, seq < rcv_next < end_seq */
SOCK_DEBUG(sk, "partial packet: rcv_next %X seq %X - %X\n",
@@ -4658,6 +4661,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
static void tcp_collapse_ofo_queue(struct sock *sk)
{
struct tcp_sock *tp = tcp_sk(sk);
+ u32 range_truesize, sum_tiny = 0;
struct sk_buff *skb = skb_peek(&tp->out_of_order_queue);
struct sk_buff *head;
u32 start, end;
@@ -4667,6 +4671,7 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
start = TCP_SKB_CB(skb)->seq;
end = TCP_SKB_CB(skb)->end_seq;
+ range_truesize = skb->truesize;
head = skb;
for (;;) {
@@ -4681,14 +4686,24 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
if (!skb ||
after(TCP_SKB_CB(skb)->seq, end) ||
before(TCP_SKB_CB(skb)->end_seq, start)) {
- tcp_collapse(sk, &tp->out_of_order_queue,
- head, skb, start, end);
+ /* Do not attempt collapsing tiny skbs */
+ if (range_truesize != head->truesize ||
+ end - start >= SKB_WITH_OVERHEAD(SK_MEM_QUANTUM)) {
+ tcp_collapse(sk, &tp->out_of_order_queue,
+ head, skb, start, end);
+ } else {
+ sum_tiny += range_truesize;
+ if (sum_tiny > sk->sk_rcvbuf >> 3)
+ return;
+ }
+
head = skb;
if (!skb)
break;
/* Start new segment */
start = TCP_SKB_CB(skb)->seq;
end = TCP_SKB_CB(skb)->end_seq;
+ range_truesize = skb->truesize;
} else {
if (before(TCP_SKB_CB(skb)->seq, start))
start = TCP_SKB_CB(skb)->seq;
@@ -4744,6 +4759,9 @@ static int tcp_prune_queue(struct sock *sk)
else if (sk_under_memory_pressure(sk))
tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
+ if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
+ return 0;
+
tcp_collapse_ofo_queue(sk);
if (!skb_queue_empty(&sk->sk_receive_queue))
tcp_collapse(sk, &sk->sk_receive_queue,
@@ -5515,7 +5533,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
* to stand against the temptation 8) --ANK
*/
inet_csk_schedule_ack(sk);
- tcp_enter_quickack_mode(sk);
+ tcp_enter_quickack_mode(sk, TCP_MAX_QUICKACKS);
inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
TCP_DELACK_MAX, TCP_RTO_MAX);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3d4e828a20e2..98b471eaf4a0 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -183,8 +183,13 @@ static void tcp_event_data_sent(struct tcp_sock *tp,
}
/* Account for an ACK we sent. */
-static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts)
+static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts,
+ u32 rcv_nxt)
{
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (unlikely(rcv_nxt != tp->rcv_nxt))
+ return; /* Special ACK sent by DCTCP to reflect ECN */
tcp_dec_quickack_mode(sk, pkts);
inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK);
}
@@ -884,8 +889,8 @@ void tcp_wfree(struct sk_buff *skb)
* We are working here with either a clone of the original
* SKB, or a fresh unique copy made by the retransmit engine.
*/
-static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
- gfp_t gfp_mask)
+static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb,
+ int clone_it, gfp_t gfp_mask, u32 rcv_nxt)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
struct inet_sock *inet;
@@ -948,7 +953,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
th->source = inet->inet_sport;
th->dest = inet->inet_dport;
th->seq = htonl(tcb->seq);
- th->ack_seq = htonl(tp->rcv_nxt);
+ th->ack_seq = htonl(rcv_nxt);
*(((__be16 *)th) + 6) = htons(((tcp_header_size >> 2) << 12) |
tcb->tcp_flags);
@@ -990,7 +995,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
icsk->icsk_af_ops->send_check(sk, skb);
if (likely(tcb->tcp_flags & TCPHDR_ACK))
- tcp_event_ack_sent(sk, tcp_skb_pcount(skb));
+ tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt);
if (skb->len != tcp_header_size)
tcp_event_data_sent(tp, sk);
@@ -1019,6 +1024,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
return net_xmit_eval(err);
}
+static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
+ gfp_t gfp_mask)
+{
+ return __tcp_transmit_skb(sk, skb, clone_it, gfp_mask,
+ tcp_sk(sk)->rcv_nxt);
+}
+
/* This routine just queues the buffer for sending.
*
* NOTE: probe0 timer is not checked, do not forget tcp_push_pending_frames,
@@ -3220,7 +3232,7 @@ void tcp_send_delayed_ack(struct sock *sk)
}
/* This routine sends an ack and also updates the window. */
-void tcp_send_ack(struct sock *sk)
+void __tcp_send_ack(struct sock *sk, u32 rcv_nxt)
{
struct sk_buff *buff;
@@ -3249,9 +3261,14 @@ void tcp_send_ack(struct sock *sk)
/* Send it off, this clears delayed acks for us. */
skb_mstamp_get(&buff->skb_mstamp);
- tcp_transmit_skb(sk, buff, 0, sk_gfp_atomic(sk, GFP_ATOMIC));
+ __tcp_transmit_skb(sk, buff, 0, sk_gfp_atomic(sk, GFP_ATOMIC), rcv_nxt);
+}
+EXPORT_SYMBOL_GPL(__tcp_send_ack);
+
+void tcp_send_ack(struct sock *sk)
+{
+ __tcp_send_ack(sk, tcp_sk(sk)->rcv_nxt);
}
-EXPORT_SYMBOL_GPL(tcp_send_ack);
/* This routine sends a packet with an out of date sequence
* number. It assumes the other end will try to ack it.
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 08c58e46bb51..1101e67a0ee1 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -533,6 +533,8 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
to->dev = from->dev;
to->mark = from->mark;
+ skb_copy_hash(to, from);
+
#ifdef CONFIG_NET_SCHED
to->tc_index = from->tc_index;
#endif
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 9cc16fa524a6..5a8c7b764253 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2062,7 +2062,8 @@ void ipv6_mc_dad_complete(struct inet6_dev *idev)
mld_send_initial_cr(idev);
idev->mc_dad_count--;
if (idev->mc_dad_count)
- mld_dad_start_timer(idev, idev->mc_maxdelay);
+ mld_dad_start_timer(idev,
+ unsolicited_report_interval(idev));
}
}
@@ -2074,7 +2075,8 @@ static void mld_dad_timer_expire(unsigned long data)
if (idev->mc_dad_count) {
idev->mc_dad_count--;
if (idev->mc_dad_count)
- mld_dad_start_timer(idev, idev->mc_maxdelay);
+ mld_dad_start_timer(idev,
+ unsolicited_report_interval(idev));
}
in6_dev_put(idev);
}
@@ -2432,7 +2434,8 @@ static void mld_ifc_timer_expire(unsigned long data)
if (idev->mc_ifc_count) {
idev->mc_ifc_count--;
if (idev->mc_ifc_count)
- mld_ifc_start_timer(idev, idev->mc_maxdelay);
+ mld_ifc_start_timer(idev,
+ unsolicited_report_interval(idev));
}
in6_dev_put(idev);
}
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 22d5002f6030..71e0084ca383 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -2083,6 +2083,7 @@ static struct xt_match ip6t_builtin_mt[] __read_mostly = {
.checkentry = icmp6_checkentry,
.proto = IPPROTO_ICMPV6,
.family = NFPROTO_IPV6,
+ .me = THIS_MODULE,
},
};
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index d235ed7f47ab..4644d4e2a8bc 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -118,7 +118,7 @@ static int nf_ct_frag6_sysctl_register(struct net *net)
if (hdr == NULL)
goto err_reg;
- net->nf_frag.sysctl.frags_hdr = hdr;
+ net->nf_frag_frags_hdr = hdr;
return 0;
err_reg:
@@ -132,8 +132,8 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net)
{
struct ctl_table *table;
- table = net->nf_frag.sysctl.frags_hdr->ctl_table_arg;
- unregister_net_sysctl_table(net->nf_frag.sysctl.frags_hdr);
+ table = net->nf_frag_frags_hdr->ctl_table_arg;
+ unregister_net_sysctl_table(net->nf_frag_frags_hdr);
if (!net_eq(net, &init_net))
kfree(table);
}
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index e3344bb096bd..9877e2ed1755 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1141,7 +1141,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
/* Get routing info from the tunnel socket */
skb_dst_drop(skb);
- skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
+ skb_dst_set(skb, sk_dst_check(sk, 0));
inet = inet_sk(sk);
fl = &inet->cork.fl;
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
index 842851cef698..e896a2c53b12 100644
--- a/net/llc/llc_core.c
+++ b/net/llc/llc_core.c
@@ -73,8 +73,8 @@ struct llc_sap *llc_sap_find(unsigned char sap_value)
rcu_read_lock_bh();
sap = __llc_sap_find(sap_value);
- if (sap)
- llc_sap_hold(sap);
+ if (!sap || !llc_sap_hold_safe(sap))
+ sap = NULL;
rcu_read_unlock_bh();
return sap;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9f5a931eedb9..285c82cdac86 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1876,7 +1876,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
if (!sta->uploaded)
continue;
- if (sta->sdata->vif.type != NL80211_IFTYPE_AP)
+ if (sta->sdata->vif.type != NL80211_IFTYPE_AP &&
+ sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
continue;
for (state = IEEE80211_STA_NOTEXIST;
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index cb372f96f10d..a46e6915a9ce 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -244,14 +244,14 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
* We currently ignore Sync packets
*
* sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
- sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
+ sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
},
[DCCP_PKT_SYNCACK] = {
/*
* We currently ignore SyncAck packets
*
* sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
- sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
+ sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
},
},
[CT_DCCP_ROLE_SERVER] = {
@@ -372,14 +372,14 @@ dccp_state_table[CT_DCCP_ROLE_MAX + 1][DCCP_PKT_SYNCACK + 1][CT_DCCP_MAX + 1] =
* We currently ignore Sync packets
*
* sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
- sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
+ sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
},
[DCCP_PKT_SYNCACK] = {
/*
* We currently ignore SyncAck packets
*
* sNO, sRQ, sRS, sPO, sOP, sCR, sCG, sTW */
- sIG, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
+ sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG,
},
},
};
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 154cc0556dc1..bb7cf74d881c 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3873,6 +3873,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
}
if (req->tp_block_nr) {
+ unsigned int min_frame_size;
+
/* Sanity tests and some calculations */
err = -EBUSY;
if (unlikely(rb->pg_vec))
@@ -3895,12 +3897,12 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
goto out;
if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
goto out;
+ min_frame_size = po->tp_hdrlen + po->tp_reserve;
if (po->tp_version >= TPACKET_V3 &&
- req->tp_block_size <=
- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr))
+ req->tp_block_size <
+ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + min_frame_size)
goto out;
- if (unlikely(req->tp_frame_size < po->tp_hdrlen +
- po->tp_reserve))
+ if (unlikely(req->tp_frame_size < min_frame_size))
goto out;
if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
goto out;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index 30f10fb07f4a..30ec75976d29 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -368,22 +368,20 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
tcf_bind_filter(tp, &cr.res, base);
}
- if (old_r)
- tcf_exts_change(tp, &r->exts, &e);
- else
- tcf_exts_change(tp, &cr.exts, &e);
-
if (old_r && old_r != r)
tcindex_filter_result_init(old_r);
oldp = p;
r->res = cr.res;
+ tcf_exts_change(tp, &r->exts, &e);
+
rcu_assign_pointer(tp->root, cp);
if (r == &new_filter_result) {
struct tcindex_filter *nfp;
struct tcindex_filter __rcu **fp;
+ f->result.res = r->res;
tcf_exts_change(tp, &f->result.exts, &r->exts);
fp = cp->h + (handle % cp->hash);
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index e8d3313ea2c9..b1c9741d5da8 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -431,14 +431,14 @@ static int vsock_send_shutdown(struct sock *sk, int mode)
return transport->shutdown(vsock_sk(sk), mode);
}
-void vsock_pending_work(struct work_struct *work)
+static void vsock_pending_work(struct work_struct *work)
{
struct sock *sk;
struct sock *listener;
struct vsock_sock *vsk;
bool cleanup;
- vsk = container_of(work, struct vsock_sock, dwork.work);
+ vsk = container_of(work, struct vsock_sock, pending_work.work);
sk = sk_vsock(vsk);
listener = vsk->listener;
cleanup = true;
@@ -478,7 +478,6 @@ void vsock_pending_work(struct work_struct *work)
sock_put(sk);
sock_put(listener);
}
-EXPORT_SYMBOL_GPL(vsock_pending_work);
/**** SOCKET OPERATIONS ****/
@@ -577,6 +576,8 @@ static int __vsock_bind(struct sock *sk, struct sockaddr_vm *addr)
return retval;
}
+static void vsock_connect_timeout(struct work_struct *work);
+
struct sock *__vsock_create(struct net *net,
struct socket *sock,
struct sock *parent,
@@ -618,6 +619,8 @@ struct sock *__vsock_create(struct net *net,
vsk->sent_request = false;
vsk->ignore_connecting_rst = false;
vsk->peer_shutdown = 0;
+ INIT_DELAYED_WORK(&vsk->connect_work, vsock_connect_timeout);
+ INIT_DELAYED_WORK(&vsk->pending_work, vsock_pending_work);
psk = parent ? vsock_sk(parent) : NULL;
if (parent) {
@@ -1095,7 +1098,7 @@ static void vsock_connect_timeout(struct work_struct *work)
struct sock *sk;
struct vsock_sock *vsk;
- vsk = container_of(work, struct vsock_sock, dwork.work);
+ vsk = container_of(work, struct vsock_sock, connect_work.work);
sk = sk_vsock(vsk);
lock_sock(sk);
@@ -1196,9 +1199,7 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
* timeout fires.
*/
sock_hold(sk);
- INIT_DELAYED_WORK(&vsk->dwork,
- vsock_connect_timeout);
- schedule_delayed_work(&vsk->dwork, timeout);
+ schedule_delayed_work(&vsk->connect_work, timeout);
/* Skip ahead to preserve error code set above. */
goto out_wait;
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index 9bb63ffec4f2..88ed7cf8eda6 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -1127,8 +1127,7 @@ static int vmci_transport_recv_listen(struct sock *sk,
vpending->listener = sk;
sock_hold(sk);
sock_hold(pending);
- INIT_DELAYED_WORK(&vpending->dwork, vsock_pending_work);
- schedule_delayed_work(&vpending->dwork, HZ);
+ schedule_delayed_work(&vpending->pending_work, HZ);
out:
return err;
diff --git a/net/wireless/db.txt b/net/wireless/db.txt
index 7bdcb4be5b7b..3048c5e0aaec 100644
--- a/net/wireless/db.txt
+++ b/net/wireless/db.txt
@@ -37,9 +37,10 @@ country AI: DFS-ETSI
country AL: DFS-ETSI
(2402 - 2482 @ 40), (20)
- (5150 - 5250 @ 80), (23), AUTO-BW
- (5250 - 5350 @ 80), (23), DFS, AUTO-BW
- (5470 - 5710 @ 160), (30), DFS
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country AM: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -50,7 +51,8 @@ country AN: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country AR:
(2402 - 2482 @ 40), (36)
@@ -71,16 +73,8 @@ country AT: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -107,7 +101,8 @@ country BA: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -125,16 +120,8 @@ country BE: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -149,16 +136,8 @@ country BG: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -241,16 +220,8 @@ country CH: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country CI: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -300,16 +271,8 @@ country CY: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -321,16 +284,8 @@ country CZ: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -351,16 +306,8 @@ country DE: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -368,16 +315,8 @@ country DK: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -410,16 +349,8 @@ country EE: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -432,16 +363,8 @@ country ES: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -455,16 +378,8 @@ country FI: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -479,16 +394,8 @@ country FR: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -496,16 +403,8 @@ country GB: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -527,7 +426,8 @@ country GF: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country GH: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -558,16 +458,8 @@ country GR: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -605,16 +497,8 @@ country HR: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -629,16 +513,8 @@ country HU: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -651,17 +527,8 @@ country IE: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 60 gHz band channels 1-4, ref: Etsi En 302 567
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -685,16 +552,8 @@ country IS: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -702,16 +561,8 @@ country IT: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -729,9 +580,9 @@ country JO:
country JP: DFS-JP
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (20), AUTO-BW, NO-OUTDOOR
- (5250 - 5330 @ 80), (20), DFS, AUTO-BW, NO-OUTDOOR
- (5490 - 5710 @ 160), (20), DFS
+ (5170 - 5250 @ 80), (23), AUTO-BW, NO-OUTDOOR
+ (5250 - 5330 @ 80), (26), DFS, AUTO-BW, NO-OUTDOOR
+ (5490 - 5710 @ 160), (26), DFS
# 60 GHz band channels 2-4 at 10mW,
# ref: http://www.arib.or.jp/english/html/overview/doc/1-STD-T74v1_1.pdf
(59000 - 66000 @ 2160), (10 mW)
@@ -758,8 +609,8 @@ country KN: DFS-FCC
country KR: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (20), AUTO-BW
- (5250 - 5330 @ 80), (20), DFS, AUTO-BW
- (5490 - 5730 @ 160), (30), DFS
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (30), DFS
(5735 - 5835 @ 80), (30)
# 60 GHz band channels 1-4,
# ref: http://www.law.go.kr/%ED%96%89%EC%A0%95%EA%B7%9C%EC%B9%99/%EB%AC%B4%EC%84%A0%EC%84%A4%EB%B9%84%EA%B7%9C%EC%B9%99
@@ -804,16 +655,8 @@ country LI: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country LK: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -832,16 +675,8 @@ country LT: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -849,16 +684,8 @@ country LU: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -866,16 +693,8 @@ country LV: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -888,19 +707,22 @@ country MC: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country MD: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country ME: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country MF: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -919,7 +741,8 @@ country MK: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -948,7 +771,8 @@ country MQ: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country MR: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -960,25 +784,17 @@ country MT: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
-country MU: DFS-FCC
+country MU: DFS-ETSI
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (24), AUTO-BW
- (5250 - 5330 @ 80), (24), DFS, AUTO-BW
- (5490 - 5730 @ 160), (24), DFS
- (5735 - 5835 @ 80), (30)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country MV: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1029,16 +845,8 @@ country NL: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1046,16 +854,8 @@ country NO: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1079,9 +879,10 @@ country OM: DFS-ETSI
country PA:
(2402 - 2472 @ 40), (36)
- (5170 - 5250 @ 80), (23), AUT0-BW
- (5250 - 5330 @ 80), (30), AUTO-BW
- (5735 - 5835 @ 80), (36)
+ (5170 - 5250 @ 80), (30), AUT0-BW
+ (5250 - 5330 @ 80), (24), AUTO-BW
+ (5490 - 5730 @ 160), (24),
+ (5735 - 5835 @ 80), (30)
country PE: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -1094,7 +895,8 @@ country PF: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country PG: DFS-FCC
(2402 - 2482 @ 40), (20)
@@ -1118,16 +920,8 @@ country PL: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1135,7 +929,8 @@ country PM: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country PR: DFS-FCC
(2402 - 2472 @ 40), (30)
@@ -1148,16 +943,8 @@ country PT: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1175,9 +962,12 @@ country PY: DFS-FCC
(5490 - 5730 @ 160), (24), DFS
(5735 - 5835 @ 80), (30)
-country QA:
+country QA: DFS-ETSI
(2402 - 2482 @ 40), (20)
- (5735 - 5835 @ 80), (30)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5730 @ 160), (20), DFS
+ (5735 - 5875 @ 80), (20)
country RE: DFS-ETSI
(2402 - 2482 @ 40), (20)
@@ -1189,16 +979,8 @@ country RO: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1208,7 +990,8 @@ country RS: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1237,16 +1020,8 @@ country SE: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1261,16 +1036,8 @@ country SI: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1278,16 +1045,8 @@ country SK: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
- # 5.9ghz band
- # reference: http://www.etsi.org/deliver/etsi_en/302500_302599/302571/01.02.00_20/en_302571v010200a.pdf
- (5850 - 5870 @ 10), (30)
- (5860 - 5880 @ 10), (30)
- (5870 - 5890 @ 10), (30)
- (5880 - 5900 @ 10), (30)
- (5890 - 5910 @ 10), (30)
- (5900 - 5920 @ 10), (30)
- (5910 - 5930 @ 10), (30)
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1344,7 +1103,8 @@ country TR: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1375,10 +1135,10 @@ country TZ:
# disputable definitions there.
country UA: DFS-ETSI
(2402 - 2482 @ 40), (20)
- (5170 - 5250 @ 80), (20), AUTO-BW
- (5250 - 5330 @ 80), (20), DFS, AUTO-BW
- (5490 - 5670 @ 160), (20), DFS
- (5735 - 5835 @ 80), (20)
+ (5170 - 5250 @ 80), (23), AUTO-BW
+ (5250 - 5330 @ 80), (23), DFS, AUTO-BW
+ (5490 - 5710 @ 160), (24), DFS
+ (5735 - 5835 @ 80), (24)
# 60 gHz band channels 1-4, ref: Etsi En 302 567
(57240 - 65880 @ 2160), (40), NO-OUTDOOR
@@ -1427,7 +1187,8 @@ country VC: DFS-ETSI
(2402 - 2482 @ 40), (20)
(5170 - 5250 @ 80), (23), AUTO-BW
(5250 - 5330 @ 80), (23), DFS, AUTO-BW
- (5490 - 5710 @ 160), (30), DFS
+ (5490 - 5730 @ 160), (30), DFS
+ (5735 - 5875 @ 80), (14)
country VE: DFS-FCC
(2402 - 2482 @ 40), (30)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d442f8736d6c..b900f06436bc 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3899,6 +3899,7 @@ static int parse_station_flags(struct genl_info *info,
params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
BIT(NL80211_STA_FLAG_MFP) |
BIT(NL80211_STA_FLAG_AUTHORIZED);
+ break;
default:
return -EINVAL;
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index e708d6d24898..a408410f428d 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2297,6 +2297,9 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE)
return make_blackhole(net, dst_orig->ops->family, dst_orig);
+ if (IS_ERR(dst))
+ dst_release(dst_orig);
+
return dst;
}
EXPORT_SYMBOL(xfrm_lookup_route);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index a4f14350563e..bb5ae90b5011 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -956,10 +956,12 @@ static inline int xfrm_nlmsg_multicast(struct net *net, struct sk_buff *skb,
{
struct sock *nlsk = rcu_dereference(net->xfrm.nlsk);
- if (nlsk)
- return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC);
- else
- return -1;
+ if (!nlsk) {
+ kfree_skb(skb);
+ return -EPIPE;
+ }
+
+ return nlmsg_multicast(nlsk, skb, pid, group, GFP_ATOMIC);
}
static inline size_t xfrm_spdinfo_msgsize(void)
@@ -1598,9 +1600,11 @@ static inline size_t userpolicy_type_attrsize(void)
#ifdef CONFIG_XFRM_SUB_POLICY
static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
{
- struct xfrm_userpolicy_type upt = {
- .type = type,
- };
+ struct xfrm_userpolicy_type upt;
+
+ /* Sadly there are two holes in struct xfrm_userpolicy_type */
+ memset(&upt, 0, sizeof(upt));
+ upt.type = type;
return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
}
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index 122599b1c13b..ea1e96921e3b 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -10,10 +10,16 @@ DEPMOD=$1
KERNELRELEASE=$2
SYMBOL_PREFIX=$3
-if ! test -r System.map -a -x "$DEPMOD"; then
+if ! test -r System.map ; then
exit 0
fi
+if [ -z $(command -v $DEPMOD) ]; then
+ echo "'make modules_install' requires $DEPMOD. Please install it." >&2
+ echo "This is probably in the kmod package." >&2
+ exit 1
+fi
+
# older versions of depmod don't support -P
# support was added in module-init-tools 3.13
if test -n "$SYMBOL_PREFIX"; then
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index a72b516b319e..59350f6b7e8d 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2037,6 +2037,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
struct smack_known *skp = smk_of_task_struct(p);
isp->smk_inode = skp;
+ isp->smk_flags |= SMK_INODE_INSTANT;
}
/*
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 082509eb805d..c5fc489de26f 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -239,16 +239,12 @@ int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
int err;
while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
- size_t aligned_size;
if (err != -ENOMEM)
return err;
if (size <= PAGE_SIZE)
return -ENOMEM;
- aligned_size = PAGE_SIZE << get_order(size);
- if (size != aligned_size)
- size = aligned_size;
- else
- size >>= 1;
+ size >>= 1;
+ size = PAGE_SIZE << get_order(size);
}
if (! dmab->area)
return -ENOMEM;
diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c
index ef494ffc1369..975a7c939d2f 100644
--- a/sound/core/seq/seq_virmidi.c
+++ b/sound/core/seq/seq_virmidi.c
@@ -163,6 +163,7 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
int count, res;
unsigned char buf[32], *pbuf;
unsigned long flags;
+ bool check_resched = !in_atomic();
if (up) {
vmidi->trigger = 1;
@@ -200,6 +201,15 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream,
vmidi->event.type = SNDRV_SEQ_EVENT_NONE;
}
}
+ if (!check_resched)
+ continue;
+ /* do temporary unlock & cond_resched() for avoiding
+ * CPU soft lockup, which may happen via a write from
+ * a huge rawmidi buffer
+ */
+ spin_unlock_irqrestore(&substream->runtime->lock, flags);
+ cond_resched();
+ spin_lock_irqsave(&substream->runtime->lock, flags);
}
out:
spin_unlock_irqrestore(&substream->runtime->lock, flags);
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 0579daa62215..425d1b664029 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -66,9 +66,9 @@ struct cs5535audio_dma_ops {
};
struct cs5535audio_dma_desc {
- u32 addr;
- u16 size;
- u16 ctlreserved;
+ __le32 addr;
+ __le16 size;
+ __le16 ctlreserved;
};
struct cs5535audio_dma {
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index 9c2dc911d8d7..709f1c584d3e 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -158,8 +158,8 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au,
lastdesc->addr = cpu_to_le32((u32) dma->desc_buf.addr);
lastdesc->size = 0;
lastdesc->ctlreserved = cpu_to_le16(PRD_JMP);
- jmpprd_addr = cpu_to_le32(lastdesc->addr +
- (sizeof(struct cs5535audio_dma_desc)*periods));
+ jmpprd_addr = (u32)dma->desc_buf.addr +
+ sizeof(struct cs5535audio_dma_desc) * periods;
dma->substream = substream;
dma->period_bytes = period_bytes;
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 36f0b8646417..0e6dd2464e81 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -1875,7 +1875,9 @@ int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device,
if (!kctl)
return -ENOMEM;
kctl->id.device = device;
- snd_ctl_add(emu->card, kctl);
+ err = snd_ctl_add(emu->card, kctl);
+ if (err < 0)
+ return err;
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 64*1024, 64*1024);
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 4f1f69be1865..8c778fa33031 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -237,13 +237,13 @@ search_empty(struct snd_emu10k1 *emu, int size)
static int is_valid_page(struct snd_emu10k1 *emu, dma_addr_t addr)
{
if (addr & ~emu->dma_mask) {
- dev_err(emu->card->dev,
+ dev_err_ratelimited(emu->card->dev,
"max memory size is 0x%lx (addr = 0x%lx)!!\n",
emu->dma_mask, (unsigned long)addr);
return 0;
}
if (addr & (EMUPAGESIZE-1)) {
- dev_err(emu->card->dev, "page is not aligned\n");
+ dev_err_ratelimited(emu->card->dev, "page is not aligned\n");
return 0;
}
return 1;
@@ -334,7 +334,7 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst
else
addr = snd_pcm_sgbuf_get_addr(substream, ofs);
if (! is_valid_page(emu, addr)) {
- dev_err(emu->card->dev,
+ dev_err_ratelimited(emu->card->dev,
"emu: failure page = %d\n", idx);
mutex_unlock(&hdr->block_mutex);
return NULL;
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index c5038303a126..0fd39b2f75cc 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1070,11 +1070,19 @@ static int snd_fm801_mixer(struct fm801 *chip)
if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97_sec)) < 0)
return err;
}
- for (i = 0; i < FM801_CONTROLS; i++)
- snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls[i], chip));
+ for (i = 0; i < FM801_CONTROLS; i++) {
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_fm801_controls[i], chip));
+ if (err < 0)
+ return err;
+ }
if (chip->multichannel) {
- for (i = 0; i < FM801_CONTROLS_MULTI; i++)
- snd_ctl_add(chip->card, snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
+ for (i = 0; i < FM801_CONTROLS_MULTI; i++) {
+ err = snd_ctl_add(chip->card,
+ snd_ctl_new1(&snd_fm801_controls_multi[i], chip));
+ if (err < 0)
+ return err;
+ }
}
return 0;
}
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4f7ffa8c4a0d..c1ecee56c7f9 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -38,6 +38,10 @@
/* Enable this to see controls for tuning purpose. */
/*#define ENABLE_TUNING_CONTROLS*/
+#ifdef ENABLE_TUNING_CONTROLS
+#include
+#endif
+
#define FLOAT_ZERO 0x00000000
#define FLOAT_ONE 0x3f800000
#define FLOAT_TWO 0x40000000
@@ -3037,8 +3041,8 @@ static int equalizer_ctl_put(struct snd_kcontrol *kcontrol,
return 1;
}
-static const DECLARE_TLV_DB_SCALE(voice_focus_db_scale, 2000, 100, 0);
-static const DECLARE_TLV_DB_SCALE(eq_db_scale, -2400, 100, 0);
+static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(voice_focus_db_scale, 2000, 100, 0);
+static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(eq_db_scale, -2400, 100, 0);
static int add_tuning_control(struct hda_codec *codec,
hda_nid_t pnid, hda_nid_t nid,
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 5c541ed723dd..5c7fbf403451 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -270,7 +270,7 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
length >>= 2; /* in 32bit words */
/* Transfer using pseudo-dma. */
for (; length > 0; length--) {
- outl(cpu_to_le32(*addr), port);
+ outl(*addr, port);
addr++;
}
addr = (u32 *)runtime->dma_area;
@@ -280,7 +280,7 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
count >>= 2; /* in 32bit words */
/* Transfer using pseudo-dma. */
for (; count > 0; count--) {
- outl(cpu_to_le32(*addr), port);
+ outl(*addr, port);
addr++;
}
@@ -308,7 +308,7 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
length >>= 2; /* in 32bit words */
/* Transfer using pseudo-dma. */
for (; length > 0; length--)
- *addr++ = le32_to_cpu(inl(port));
+ *addr++ = inl(port);
addr = (u32 *)runtime->dma_area;
pipe->hw_ptr = 0;
}
@@ -316,7 +316,7 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
count >>= 2; /* in 32bit words */
/* Transfer using pseudo-dma. */
for (; count > 0; count--)
- *addr++ = le32_to_cpu(inl(port));
+ *addr++ = inl(port);
vx2_release_pseudo_dma(chip);
}
diff --git a/sound/pcmcia/vx/vxp_ops.c b/sound/pcmcia/vx/vxp_ops.c
index 56aa1ba73ccc..49a883341eff 100644
--- a/sound/pcmcia/vx/vxp_ops.c
+++ b/sound/pcmcia/vx/vxp_ops.c
@@ -375,7 +375,7 @@ static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
length >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
for (; length > 0; length--) {
- outw(cpu_to_le16(*addr), port);
+ outw(*addr, port);
addr++;
}
addr = (unsigned short *)runtime->dma_area;
@@ -385,7 +385,7 @@ static void vxp_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
count >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
for (; count > 0; count--) {
- outw(cpu_to_le16(*addr), port);
+ outw(*addr, port);
addr++;
}
vx_release_pseudo_dma(chip);
@@ -417,7 +417,7 @@ static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
length >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
for (; length > 0; length--)
- *addr++ = le16_to_cpu(inw(port));
+ *addr++ = inw(port);
addr = (unsigned short *)runtime->dma_area;
pipe->hw_ptr = 0;
}
@@ -425,12 +425,12 @@ static void vxp_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
count >>= 1; /* in 16bit words */
/* Transfer using pseudo-dma. */
for (; count > 1; count--)
- *addr++ = le16_to_cpu(inw(port));
+ *addr++ = inw(port);
/* Disable DMA */
pchip->regDIALOG &= ~VXP_DLG_DMAREAD_SEL_MASK;
vx_outb(chip, DIALOG, pchip->regDIALOG);
/* Read the last word (16 bits) */
- *addr = le16_to_cpu(inw(port));
+ *addr = inw(port);
/* Disable 16-bit accesses */
pchip->regDIALOG &= ~VXP_DLG_DMA16_SEL_MASK;
vx_outb(chip, DIALOG, pchip->regDIALOG);
diff --git a/sound/soc/codecs/audio-ext-clk.c b/sound/soc/codecs/audio-ext-clk.c
index fda1158682d9..4004fa74c9ba 100644
--- a/sound/soc/codecs/audio-ext-clk.c
+++ b/sound/soc/codecs/audio-ext-clk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -229,31 +229,62 @@ static int audio_ext_set_lpass_mclk_v1(struct clk *clk,
return ret;
}
-static int audio_ext_set_lpass_mclk_v2(enum clk_enablement enable)
+static int audio_ext_set_lpass_mclk_v2(struct clk *clk,
+ enum clk_enablement enable)
{
struct afe_clk_set m_clk = lpass_default2;
struct afe_clk_set ibit_clk = lpass_default2;
- int ret = 0;
+ struct audio_ext_lpass_mclk *audio_lpass_mclk;
+ int ret = 0, val = 0;
pr_debug("%s: Setting clock using v2, enable(%d)\n", __func__, enable);
- /* Set both mclk and ibit clocks when using LPASS_CLK_VER_2 */
- m_clk.enable = enable;
- ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, &m_clk);
- if (ret < 0) {
- pr_err("%s: afe_set_lpass_clock_v2 failed for mclk_3 with ret %d\n",
- __func__, ret);
+ audio_lpass_mclk = container_of(clk, struct audio_ext_lpass_mclk, c);
+ if (audio_lpass_mclk == NULL) {
+ pr_err("%s: audio_lpass_mclk is NULL\n", __func__);
+ ret = -EINVAL;
goto done;
}
- ibit_clk.clk_id = Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT;
- ibit_clk.clk_freq_in_hz = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ;
- ibit_clk.enable = enable;
- ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX, &ibit_clk);
- if (ret < 0) {
- pr_err("%s: afe_set_lpass_clock_v2 failed for ibit with ret %d\n",
- __func__, ret);
- goto err_ibit_clk_set;
+ if (!audio_lpass_mclk->lpass_clock) {
+ /* Set both mclk and ibit clocks when using LPASS_CLK_VER_2 */
+ m_clk.enable = enable;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX,
+ &m_clk);
+ if (ret < 0) {
+ pr_err("%s: afe_set_lpass_clock_v2 failed for mclk_3\n"
+ "with ret %d\n", __func__, ret);
+ goto done;
+ }
+
+ ibit_clk.clk_id = Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT;
+ ibit_clk.clk_freq_in_hz = Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ;
+ ibit_clk.enable = enable;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX,
+ &ibit_clk);
+ if (ret < 0) {
+ pr_err("%s: afe_set_lpass_clock_v2 failed for ibit\n"
+ "with ret %d\n", __func__, ret);
+ goto err_ibit_clk_set;
+ }
+ } else {
+ if (audio_lpass_mclk->lpass_csr_gpio_mux_spkrctl_vaddr &&
+ enable) {
+ val = ioread32(audio_lpass_mclk->
+ lpass_csr_gpio_mux_spkrctl_vaddr);
+ val = val | 0x00000002;
+ iowrite32(val, audio_lpass_mclk->
+ lpass_csr_gpio_mux_spkrctl_vaddr);
+ }
+
+ digital_cdc_core_clk.enable = enable;
+ ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX,
+ &digital_cdc_core_clk);
+ if (ret < 0) {
+ pr_err("%s: afe_set_digital_codec_core_clock failed\n"
+ " with ret %d\n", __func__, ret);
+ goto done;
+ }
}
ret = 0;
@@ -299,7 +330,7 @@ static int audio_ext_lpass_mclk_prepare(struct clk *clk)
lpass_clk_ver = afe_get_lpass_clk_ver();
if (lpass_clk_ver >= LPASS_CLK_VER_2)
- ret = audio_ext_set_lpass_mclk_v2(CLK_ENABLE);
+ ret = audio_ext_set_lpass_mclk_v2(clk, CLK_ENABLE);
else
ret = audio_ext_set_lpass_mclk_v1(clk, CLK_ENABLE);
@@ -336,7 +367,7 @@ static void audio_ext_lpass_mclk_unprepare(struct clk *clk)
lpass_clk_ver = afe_get_lpass_clk_ver();
if (lpass_clk_ver >= LPASS_CLK_VER_2)
- ret = audio_ext_set_lpass_mclk_v2(CLK_DISABLE);
+ ret = audio_ext_set_lpass_mclk_v2(clk, CLK_DISABLE);
else
ret = audio_ext_set_lpass_mclk_v1(clk, CLK_DISABLE);
diff --git a/sound/soc/codecs/msm8x16-wcd.c b/sound/soc/codecs/msm8x16-wcd.c
index 964372f0f328..0044f63fbcd1 100644
--- a/sound/soc/codecs/msm8x16-wcd.c
+++ b/sound/soc/codecs/msm8x16-wcd.c
@@ -49,7 +49,8 @@
SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000)
#define MSM8X16_WCD_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S24_LE |\
- SNDRV_PCM_FMTBIT_S24_3LE)
+ SNDRV_PCM_FMTBIT_S24_3LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
#define NUM_INTERPOLATORS 3
#define BITS_PER_REG 8
@@ -4755,13 +4756,24 @@ static int msm8x16_wcd_hw_params(struct snd_pcm_substream *substream,
}
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
- snd_soc_update_bits(dai->codec,
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ snd_soc_update_bits(dai->codec,
MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL, 0x20, 0x20);
+ } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ snd_soc_update_bits(dai->codec,
+ MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL, 0x20, 0x20);
+ }
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
- snd_soc_update_bits(dai->codec,
+ case SNDRV_PCM_FORMAT_S32_LE:
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ snd_soc_update_bits(dai->codec,
MSM8X16_WCD_A_CDC_CLK_RX_I2S_CTL, 0x20, 0x00);
+ } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ snd_soc_update_bits(dai->codec,
+ MSM8X16_WCD_A_CDC_CLK_TX_I2S_CTL, 0x20, 0x00);
+ }
break;
default:
dev_err(dai->codec->dev, "%s: wrong format selected\n",
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c
index bf6fc60d816e..aed0448707ed 100644
--- a/sound/soc/codecs/wcd9335.c
+++ b/sound/soc/codecs/wcd9335.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-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
@@ -886,6 +886,15 @@ static ssize_t wcd9xxx_print_name(struct switch_dev *sdev, char *buf)
return -EINVAL;
}
+static const struct tasha_reg_mask_val tasha_high_impedance[] = {
+ {WCD9335_TLMM_I2S_TX_SD0_PINCFG, 0x1F, 0x0C},
+ {WCD9335_TLMM_I2S_TX_SD1_PINCFG, 0x1F, 0x0C},
+ {WCD9335_TLMM_I2S_TX_SCK_PINCFG, 0x1F, 0x0C},
+ {WCD9335_TLMM_I2S_TX_WS_PINCFG, 0x1F, 0x0C},
+ {WCD9335_TEST_DEBUG_PIN_CTL_OE_1, 0xE0, 0xE0},
+ {WCD9335_TEST_DEBUG_PIN_CTL_OE_2, 0x01, 0x01},
+};
+
/**
* tasha_set_spkr_gain_offset - offset the speaker path
* gain with the given offset value.
@@ -989,6 +998,20 @@ static void tasha_cdc_sido_ccl_enable(struct tasha_priv *tasha, bool ccl_flag)
}
}
+static void tasha_set_high_impedance_mode(struct snd_soc_codec *codec)
+{
+ const struct tasha_reg_mask_val *regs;
+ int i, size;
+
+ dev_dbg(codec->dev, "%s: setting TX I2S in Hi-Z mode\n", __func__);
+ regs = tasha_high_impedance;
+ size = ARRAY_SIZE(tasha_high_impedance);
+
+ for (i = 0; i < size; i++)
+ snd_soc_update_bits(codec, regs[i].reg,
+ regs[i].mask, regs[i].val);
+}
+
static bool tasha_cdc_is_svs_enabled(struct tasha_priv *tasha)
{
if (TASHA_IS_2_0(tasha->wcd9xxx->version) &&
@@ -13991,6 +14014,8 @@ static int tasha_codec_probe(struct snd_soc_codec *codec)
mutex_unlock(&codec->mutex);
snd_soc_dapm_sync(dapm);
+ if (pdata->wcd9xxx_mic_tristate)
+ tasha_set_high_impedance_mode(codec);
priv_headset_type = tasha;
@@ -14008,6 +14033,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec)
pr_err("%s: failed to register switch audiowizard_force_preset\n", __func__);
}
/* ASUS_BSP Paul --- */
+
return ret;
err_pdata:
diff --git a/sound/soc/msm/apq8009-i2s-ext-codec.c b/sound/soc/msm/apq8009-i2s-ext-codec.c
index 22abdac808d8..14734a366096 100644
--- a/sound/soc/msm/apq8009-i2s-ext-codec.c
+++ b/sound/soc/msm/apq8009-i2s-ext-codec.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
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -69,11 +70,48 @@
#define WSA8810_NAME_1 "wsa881x.20170211"
#define WSA8810_NAME_2 "wsa881x.20170212"
+#define TDM_SLOT_OFFSET_MAX 8
+
enum btsco_rates {
RATE_8KHZ_ID,
RATE_16KHZ_ID,
};
+enum {
+ PRIMARY_TDM_RX_0,
+ PRIMARY_TDM_TX_0,
+ SECONDARY_TDM_RX_0,
+ SECONDARY_TDM_TX_0,
+ TDM_MAX,
+};
+
+
+/* TDM default channels */
+static int msm_pri_tdm_rx_0_ch = 8;
+static int msm_pri_tdm_tx_0_ch = 8;
+
+/* TDM default bit format */
+static int msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+
+/* TDM default sampling rate */
+static int msm_pri_tdm_rx_0_sample_rate = SAMPLING_RATE_48KHZ;
+static int msm_pri_tdm_tx_0_sample_rate = SAMPLING_RATE_48KHZ;
+
+static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
+static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
+ "S32_LE"};
+static char const *tdm_sample_rate_text[] = {"KHZ_16", "KHZ_48"};
+
+/* TDM default offset */
+static unsigned int tdm_slot_offset[TDM_MAX][TDM_SLOT_OFFSET_MAX] = {
+ /* PRI_TDM_RX */
+ {0, 4, 8, 12, 16, 20, 24, 28},
+ /* PRI_TDM_TX */
+ {0, 4, 8, 12, 16, 20, 24, 28},
+};
+
struct apq8009_asoc_mach_data {
int mclk_freq;
struct afe_digital_clk_cfg digital_cdc_clk;
@@ -106,6 +144,7 @@ static int apq8009_auxpcm_rate = 8000;
static atomic_t pri_mi2s_clk_ref;
static atomic_t quat_mi2s_clk_ref;
static atomic_t auxpcm_mi2s_clk_ref;
+static int tdm_i2s_switch_enable = -EINVAL;
static int apq8009_enable_extcodec_ext_clk(struct snd_soc_codec *codec,
int enable, bool dapm);
@@ -286,12 +325,210 @@ static struct snd_soc_dapm_route wcd9335_audio_paths[] = {
{"MIC BIAS4", NULL, "MCLK"},
};
-static char const *rx_bit_format_text[] = {"S16_LE", "S24_3LE", "S24_LE"};
+static char const *rx_bit_format_text[] = {"S16_LE", "S24_3LE", "S24_LE",
+ "S32_LE"};
static const char *const mi2s_tx_ch_text[] = {"One", "Two", "Three", "Four"};
static char const *pri_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
"KHZ_192", "KHZ_8",
"KHZ_16", "KHZ_32"};
+
+static int msm_pri_tdm_rx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("msm_pri_tdm_rx_0_ch = %d",
+ msm_pri_tdm_rx_0_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_rx_0_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_rx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("msm_pri_tdm_rx_0_ch = %d",
+ msm_pri_tdm_rx_0_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("msm_pri_tdm_tx_0_ch = %d",
+ msm_pri_tdm_tx_0_ch);
+ ucontrol->value.integer.value[0] = msm_pri_tdm_tx_0_ch - 1;
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_pri_tdm_tx_0_ch = ucontrol->value.integer.value[0] + 1;
+ pr_debug("msm_pri_tdm_tx_0_ch = %d",
+ msm_pri_tdm_tx_0_ch);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_rx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("msm_pri_tdm_rx_0_bit_format = %ld",
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_rx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("msm_pri_tdm_rx_0_bit_format = %d",
+ msm_pri_tdm_rx_0_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_tx_0_bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("msm_pri_tdm_tx_0_bit_format = %ld",
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ msm_pri_tdm_tx_0_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("msm_pri_tdm_tx_0_bit_format = %d",
+ msm_pri_tdm_tx_0_bit_format);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_rx_0_sample_rate) {
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ }
+ pr_debug("msm_pri_tdm_rx_0_sample_rate = %ld",
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_rx_0_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_pri_tdm_rx_0_sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ default:
+ msm_pri_tdm_rx_0_sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ pr_debug("msm_pri_tdm_rx_0_sample_rate = %d",
+ msm_pri_tdm_rx_0_sample_rate);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (msm_pri_tdm_tx_0_sample_rate) {
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ }
+ pr_debug("msm_pri_tdm_tx_0_sample_rate = %ld",
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_pri_tdm_tx_0_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 0:
+ msm_pri_tdm_tx_0_sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ default:
+ msm_pri_tdm_tx_0_sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ pr_debug("msm_pri_tdm_tx_0_sample_rate = %d",
+ msm_pri_tdm_tx_0_sample_rate);
+ return 0;
+}
+
static int msm_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -397,6 +634,10 @@ static int mi2s_tx_bit_format_get(struct snd_kcontrol *kcontrol,
{
switch (mi2s_tx_bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+
case SNDRV_PCM_FORMAT_S24_LE:
ucontrol->value.integer.value[0] = 2;
break;
@@ -422,6 +663,10 @@ static int mi2s_tx_bit_format_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ tx_bits_per_sample = 32;
+ break;
case 2:
mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
tx_bits_per_sample = 32;
@@ -502,6 +747,203 @@ static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0;
}
+
+static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ channels->min = channels->max = msm_pri_tdm_rx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_rx_0_bit_format);
+ rate->min = rate->max = msm_pri_tdm_rx_0_sample_rate;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ channels->min = channels->max = msm_pri_tdm_tx_0_ch;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ msm_pri_tdm_tx_0_bit_format);
+ rate->min = rate->max = msm_pri_tdm_tx_0_sample_rate;
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported", __func__,
+ cpu_dai->id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d", __func__,
+ cpu_dai->id, channels->max, rate->max);
+
+ return 0;
+}
+
+static unsigned int tdm_param_set_slot_mask(u16 port_id,
+ int slot_width, int channels)
+{
+ unsigned int slot_mask = 0;
+ int upper, lower, i, j;
+ unsigned int *slot_offset;
+
+ switch (port_id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ lower = PRIMARY_TDM_RX_0;
+ upper = PRIMARY_TDM_RX_0;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ lower = PRIMARY_TDM_TX_0;
+ upper = PRIMARY_TDM_TX_0;
+ break;
+ default:
+ return slot_mask;
+ }
+
+ for (i = lower; i <= upper; i++) {
+ slot_offset = tdm_slot_offset[i];
+ for (j = 0; j < channels; j++) {
+ if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ /*
+ * set the mask of active slot according to
+ * the offset table for the group of devices
+ */
+ slot_mask |=
+ (1 << ((slot_offset[j] * 8) / slot_width));
+ else
+ break;
+ }
+ }
+
+ return slot_mask;
+}
+
+static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, slot_width, slots;
+ unsigned int slot_mask;
+ unsigned int *slot_offset;
+ int offset_channels = 0;
+ int i;
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ channels = params_channels(params);
+ switch (channels) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 6:
+ case 8:
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S16_LE:
+ /*
+ * up to 8 channel HW configuration should
+ * use 32 bit slot width for max support of
+ * stream bit width. (slot_width > bit_width)
+ */
+ slot_width = 32;
+ break;
+ default:
+ pr_err("%s: invalid param format 0x%x\n",
+ __func__, params_format(params));
+ return -EINVAL;
+ }
+ slots = 8;
+ slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
+ slot_width, channels);
+ if (!slot_mask) {
+ pr_err("%s: invalid slot_mask 0x%x\n",
+ __func__, slot_mask);
+ return -EINVAL;
+ }
+ break;
+ default:
+ pr_err("%s: invalid param channels %d\n",
+ __func__, channels);
+ return -EINVAL;
+ }
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_RX_0];
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ slot_offset = tdm_slot_offset[PRIMARY_TDM_TX_0];
+ break;
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < channels; i++) {
+ if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
+ offset_channels++;
+ else
+ break;
+ }
+
+ if (offset_channels == 0) {
+ pr_err("%s: slot offset not supported, offset_channels %d\n",
+ __func__, offset_channels);
+ return -EINVAL;
+ }
+
+ if (channels > offset_channels) {
+ pr_err("%s: channels %d exceed offset_channels %d\n",
+ __func__, channels, offset_channels);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ 0, NULL, channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ channels, slot_offset, 0, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+
+end:
+ return ret;
+}
+
static int msm_pri_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -776,9 +1218,16 @@ static int msm_btsco_rate_put(struct snd_kcontrol *kcontrol,
}
static const struct soc_enum msm_snd_enum[] = {
- SOC_ENUM_SINGLE_EXT(3, rx_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_bit_format_text),
+ rx_bit_format_text),
SOC_ENUM_SINGLE_EXT(4, mi2s_tx_ch_text),
SOC_ENUM_SINGLE_EXT(6, pri_rx_sample_rate_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_ch_text),
+ tdm_ch_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_bit_format_text),
+ tdm_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_sample_rate_text),
+ tdm_sample_rate_text),
};
static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ",
@@ -800,6 +1249,22 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
msm_btsco_rate_get, msm_btsco_rate_put),
SOC_ENUM_EXT("MI2S_RX SampleRate", msm_snd_enum[2],
pri_rx_sample_rate_get, pri_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", msm_snd_enum[3],
+ msm_pri_tdm_rx_0_ch_get, msm_pri_tdm_rx_0_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", msm_snd_enum[3],
+ msm_pri_tdm_tx_0_ch_get, msm_pri_tdm_tx_0_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Bit Format", msm_snd_enum[4],
+ msm_pri_tdm_rx_0_bit_format_get,
+ msm_pri_tdm_rx_0_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Bit Format", msm_snd_enum[4],
+ msm_pri_tdm_tx_0_bit_format_get,
+ msm_pri_tdm_tx_0_bit_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", msm_snd_enum[5],
+ msm_pri_tdm_rx_0_sample_rate_get,
+ msm_pri_tdm_rx_0_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", msm_snd_enum[5],
+ msm_pri_tdm_tx_0_sample_rate_get,
+ msm_pri_tdm_tx_0_sample_rate_put),
};
static int apq8009_mclk_event(struct snd_soc_dapm_widget *w,
@@ -974,6 +1439,107 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
__func__, "pri_i2s");
}
+
+static int msm_tdm_startup(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct apq8009_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0, val = 0;
+
+ pr_debug("substream = %s stream = %d",
+ substream->name, substream->stream);
+ pr_debug("dai id = 0x%x", cpu_dai->id);
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_4:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_5:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_6:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_7:
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_4:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_5:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_6:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_7:
+ /* Configure mux for Primary TDM */
+ if (pdata->vaddr_gpio_mux_pcm_ctl) {
+ val = ioread32(pdata->vaddr_gpio_mux_pcm_ctl);
+ val = val | 0x00000001;
+ iowrite32(val, pdata->vaddr_gpio_mux_pcm_ctl);
+ } else {
+ return -EINVAL;
+ }
+ if (pdata->vaddr_gpio_mux_mic_ctl) {
+ val = ioread32(pdata->vaddr_gpio_mux_mic_ctl);
+ /*0x1808000 Use this value for slave mode*/
+ val = val | 0x02020002; /*this is for master mode*/
+ iowrite32(val, pdata->vaddr_gpio_mux_mic_ctl);
+ } else {
+ return -EINVAL;
+ }
+
+ ret = msm_gpioset_activate(CLIENT_WCD_EXT, "quat_i2s");
+ if (ret < 0)
+ pr_err("%s: failed to activate primary TDM gpio set\n",
+ __func__);
+ /* Enable I2S switch to turn on TDM mics for SOM*/
+ if (tdm_i2s_switch_enable >= 0)
+ gpio_direction_output(tdm_i2s_switch_enable, 1);
+ break;
+ default:
+ pr_err("dai id 0x%x not supported", cpu_dai->id);
+ break;
+ return -EINVAL;
+ }
+ return ret;
+}
+
+static void msm_tdm_shutdown(struct snd_pcm_substream *substream)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_4:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_5:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_6:
+ case AFE_PORT_ID_PRIMARY_TDM_RX_7:
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_4:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_5:
+ case AFE_PORT_ID_PRIMARY_TDM_TX_6:
+ ret = msm_gpioset_suspend(CLIENT_WCD_EXT, "quat_i2s");
+ if (ret < 0) {
+ pr_err("%s: gpio set cannot be de-activated %s\n",
+ __func__, "pri_tdm");
+ return;
+ }
+
+ if (tdm_i2s_switch_enable >= 0)
+ gpio_direction_output(tdm_i2s_switch_enable, 0);
+ break;
+ default:
+ break;
+ }
+}
+
static int msm_audrx_init_wcd(struct snd_soc_pcm_runtime *rtd)
{
@@ -1070,6 +1636,28 @@ static struct snd_soc_ops msm_pri_auxpcm_be_ops = {
.startup = msm_prim_auxpcm_startup,
};
+static struct snd_soc_dai_link msm_afe_rxtx_lb_be_dai_link[] = {
+ {
+ .name = LPASS_BE_AFE_LOOPBACK_TX,
+ .stream_name = "AFE Loopback Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.24577",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_ops msm_tdm_be_ops = {
+ .startup = msm_tdm_startup,
+ .hw_params = msm_tdm_snd_hw_params,
+ .shutdown = msm_tdm_shutdown,
+};
+
static struct snd_soc_dai_link apq8009_9326_dai[] = {
/* Backend DAI Links */
{
@@ -1523,6 +2111,7 @@ static struct snd_soc_dai_link apq8009_dai[] = {
.platform_name = "msm-compress-dsp",
.dynamic = 1,
.dpcm_playback = 1,
+ .dpcm_capture = 1,
.trigger = {SND_SOC_DPCM_TRIGGER_POST,
SND_SOC_DPCM_TRIGGER_POST},
.codec_dai_name = "snd-soc-dummy-dai",
@@ -1738,9 +2327,143 @@ static struct snd_soc_dai_link apq8009_dai[] = {
},
};
+static struct snd_soc_dai_link msm_tdm_fe_dai[] = {
+ /* FE TDM DAI links */
+ {
+ .name = "Primary TDM RX 0 Hostless",
+ .stream_name = "Primary TDM RX 0 Hostless",
+ .cpu_dai_name = "PRI_TDM_RX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Primary TDM TX 0 Hostless",
+ .stream_name = "Primary TDM TX 0 Hostless",
+ .cpu_dai_name = "PRI_TDM_TX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Secondary TDM RX 0 Hostless",
+ .stream_name = "Secondary TDM RX 0 Hostless",
+ .cpu_dai_name = "SEC_TDM_RX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "Secondary TDM TX 0 Hostless",
+ .stream_name = "Secondary TDM TX 0 Hostless",
+ .cpu_dai_name = "SEC_TDM_TX_0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+};
+
+static struct snd_soc_dai_link msm_compr_fe_dai[] = {
+ /* FE TDM DAI links */
+ {/* hw:x,43 */
+ .name = "APQ8009 Compress3",
+ .stream_name = "Compress3",
+ .cpu_dai_name = "MultiMedia10",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA10,
+ },
+ {/* hw:x,44 */
+ .name = "APQ8009 Compress4",
+ .stream_name = "Compress4",
+ .cpu_dai_name = "MultiMedia11",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .be_id = MSM_FRONTEND_DAI_MULTIMEDIA11,
+ },
+};
+
+static struct snd_soc_dai_link msm_tdm_be_dai[] = {
+ /* TDM be dai links */
+ {
+ .name = LPASS_BE_PRI_TDM_RX_0,
+ .stream_name = "Primary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36864",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_0,
+ .stream_name = "Primary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36865",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .be_id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &msm_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
static struct snd_soc_dai_link apq8009_9326_dai_links[
ARRAY_SIZE(apq8009_dai) +
- ARRAY_SIZE(apq8009_9326_dai)];
+ ARRAY_SIZE(msm_tdm_fe_dai) +
+ ARRAY_SIZE(msm_compr_fe_dai) +
+ ARRAY_SIZE(apq8009_9326_dai) +
+ ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) +
+ ARRAY_SIZE(msm_tdm_be_dai)];
static struct snd_soc_card snd_soc_card_9326_apq8009;
@@ -1760,7 +2483,7 @@ static int populate_ext_snd_card_dt_data(struct platform_device *pdev)
struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
{
struct snd_soc_card *card = &snd_soc_card_9326_apq8009;
- int num_links, ret;
+ int ret, len1, len2, len3, len4;
card->dev = dev;
ret = snd_soc_of_parse_card_name(card, "qcom,model");
@@ -1771,16 +2494,39 @@ struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
}
pr_debug("%s: CARD is %s\n", __func__, card->name);
- num_links = ARRAY_SIZE(apq8009_9326_dai_links);
+ len1 = ARRAY_SIZE(apq8009_dai);
+ len2 = len1 + ARRAY_SIZE(msm_tdm_fe_dai);
+ len3 = len2 + ARRAY_SIZE(msm_compr_fe_dai);
+ len4 = len3 + ARRAY_SIZE(apq8009_9326_dai);
memcpy(apq8009_9326_dai_links, apq8009_dai,
sizeof(apq8009_dai));
- memcpy(apq8009_9326_dai_links + ARRAY_SIZE(apq8009_dai),
- apq8009_9326_dai, sizeof(apq8009_9326_dai));
+ memcpy(apq8009_9326_dai_links + len1, msm_tdm_fe_dai,
+ sizeof(msm_tdm_fe_dai));
+ memcpy(apq8009_9326_dai_links + len2, msm_compr_fe_dai,
+ sizeof(msm_compr_fe_dai));
+ memcpy(apq8009_9326_dai_links + len3, apq8009_9326_dai,
+ sizeof(apq8009_9326_dai));
+
+ if (of_property_read_bool(dev->of_node, "qcom,afe-rxtx-lb")) {
+ dev_dbg(dev, "%s(): AFE RX to TX loopback supported\n",
+ __func__);
+ memcpy(apq8009_9326_dai_links + len4,
+ msm_afe_rxtx_lb_be_dai_link,
+ sizeof(msm_afe_rxtx_lb_be_dai_link));
+ len4 += ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
+ }
+ if (of_property_read_bool(dev->of_node, "qcom,tdm-audio-intf")) {
+ dev_dbg(dev, "%s(): TDM support present\n",
+ __func__);
+ memcpy(apq8009_9326_dai_links + len4, msm_tdm_be_dai,
+ sizeof(msm_tdm_be_dai));
+ len4 += ARRAY_SIZE(msm_tdm_be_dai);
+ }
card->dai_link = apq8009_9326_dai_links;
- card->num_links = num_links;
+ card->num_links = len4;
card->dev = dev;
return card;
@@ -2140,6 +2886,22 @@ static int apq8009_asoc_machine_probe(struct platform_device *pdev)
ret);
goto err;
}
+
+ tdm_i2s_switch_enable = of_get_named_gpio(pdev->dev.of_node,
+ "qcom,tdm-i2s-switch-enable", 0);
+ if (tdm_i2s_switch_enable >= 0) {
+ dev_dbg(&pdev->dev, "%s: tdm switch gpio %d", __func__,
+ tdm_i2s_switch_enable);
+ ret = gpio_request(tdm_i2s_switch_enable, "TDM_RESET");
+ if (ret) {
+ pr_err("%s: Failed to request gpio\n", __func__);
+ goto err;
+ }
+ } else
+ dev_err(&pdev->dev, "Looking up %s property in node %s failed\n",
+ "qcom,tdm-i2s-switch-enable",
+ pdev->dev.of_node->full_name);
+
return 0;
err:
if (pdata->vaddr_gpio_mux_spkr_ctl)
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 7857813ca3b0..b8f666d0ce15 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -108,7 +108,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -140,7 +141,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -223,7 +225,9 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.rates = (SNDRV_PCM_RATE_8000_192000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE),
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -255,7 +259,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 0,
.channels_max = 8,
.rate_min = 8000,
@@ -288,7 +293,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -320,7 +326,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -372,7 +379,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -2118,7 +2126,10 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.aif_name = "MM_UL9",
.rates = (SNDRV_PCM_RATE_8000_48000|
SNDRV_PCM_RATE_KNOT),
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -2513,7 +2524,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -2532,7 +2544,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
@@ -2551,7 +2564,8 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
diff --git a/sound/soc/msm/msm8952-slimbus.c b/sound/soc/msm/msm8952-slimbus.c
index 7fccff15cac3..775328a8635a 100644
--- a/sound/soc/msm/msm8952-slimbus.c
+++ b/sound/soc/msm/msm8952-slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-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
@@ -1042,6 +1042,9 @@ static int slim0_tx_bit_format_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
switch (slim0_tx_bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
case SNDRV_PCM_FORMAT_S24_3LE:
ucontrol->value.integer.value[0] = 2;
break;
@@ -1065,6 +1068,9 @@ static int slim0_tx_bit_format_put(struct snd_kcontrol *kcontrol,
int rc = 0;
switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ slim0_tx_bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
case 2:
slim0_tx_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
break;
@@ -1799,7 +1805,8 @@ static const char *const slim4_tx_ch_text[] = {"One", "Two", "Three", "Four",
"Five", "Six", "Seven",
"Eight"};
static const char *const vi_feed_ch_text[] = {"One", "Two"};
-static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"};
+static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
+ "S32_LE"};
static char const *slim0_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
"KHZ_192", "KHZ_44P1", "KHZ_16"};
static char const *slim4_rx_sample_rate_text[] = {"KHZ_48", "KHZ_96",
diff --git a/sound/soc/msm/msm8952.c b/sound/soc/msm/msm8952.c
index 880677fc39a9..24fc90036b51 100644
--- a/sound/soc/msm/msm8952.c
+++ b/sound/soc/msm/msm8952.c
@@ -68,6 +68,9 @@ static int msm_vi_feed_tx_ch = 2;
static int mi2s_rx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
static int mi2s_rx_bits_per_sample = 16;
static int mi2s_rx_sample_rate = SAMPLING_RATE_48KHZ;
+static int mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+static int mi2s_tx_bits_per_sample = 16;
+static int mi2s_tx_sample_rate = SAMPLING_RATE_48KHZ;
static atomic_t quat_mi2s_clk_ref;
static atomic_t quin_mi2s_clk_ref;
@@ -161,7 +164,8 @@ static struct afe_clk_set wsa_ana_clk = {
0,
};
-static char const *rx_bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE"};
+static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
+ "S32_LE"};
static const char *const mi2s_ch_text[] = {"One", "Two"};
static const char *const loopback_mclk_text[] = {"DISABLE", "ENABLE"};
static const char *const btsco_rate_text[] = {"BTSCO_RATE_8KHZ",
@@ -389,7 +393,7 @@ static int msm_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
pr_debug("%s(), channel:%d\n", __func__, msm_ter_mi2s_tx_ch);
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_FORMAT_S16_LE);
+ mi2s_tx_bit_format);
rate->min = rate->max = 48000;
channels->min = channels->max = msm_ter_mi2s_tx_ch;
@@ -480,7 +484,7 @@ static int msm_mi2s_snd_hw_params(struct snd_pcm_substream *substream,
mi2s_rx_bit_format);
else
param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
- SNDRV_PCM_FORMAT_S16_LE);
+ mi2s_tx_bit_format);
return 0;
}
@@ -549,7 +553,7 @@ static bool is_mi2s_rx_port(int port_id)
return ret;
}
-static uint32_t get_mi2s_rx_clk_val(int port_id)
+static uint32_t get_mi2s_clk_val(int port_id)
{
uint32_t clk_val = 0;
@@ -559,8 +563,10 @@ static uint32_t get_mi2s_rx_clk_val(int port_id)
*/
if (is_mi2s_rx_port(port_id))
clk_val = (mi2s_rx_sample_rate * mi2s_rx_bits_per_sample * 2);
+ else
+ clk_val = (mi2s_tx_sample_rate * mi2s_tx_bits_per_sample * 2);
- pr_debug("%s: MI2S Rx bit clock value: 0x%0x\n", __func__, clk_val);
+ pr_debug("%s: MI2S bit clock value: 0x%0x\n", __func__, clk_val);
return clk_val;
}
@@ -581,7 +587,7 @@ static int msm_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable)
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
if (pdata->afe_clk_ver == AFE_CLK_VERSION_V1) {
mi2s_rx_clk_v1.clk_val1 =
- get_mi2s_rx_clk_val(port_id);
+ get_mi2s_clk_val(port_id);
ret = afe_set_lpass_clock(port_id,
&mi2s_rx_clk_v1);
} else {
@@ -589,14 +595,14 @@ static int msm_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable)
mi2s_rx_clk.clk_id =
msm8952_get_clk_id(port_id);
mi2s_rx_clk.clk_freq_in_hz =
- get_mi2s_rx_clk_val(port_id);
+ get_mi2s_clk_val(port_id);
ret = afe_set_lpass_clock_v2(port_id,
&mi2s_rx_clk);
}
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
if (pdata->afe_clk_ver == AFE_CLK_VERSION_V1) {
mi2s_tx_clk_v1.clk_val1 =
- Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ;
+ get_mi2s_clk_val(port_id);
ret = afe_set_lpass_clock(port_id,
&mi2s_tx_clk_v1);
} else {
@@ -604,7 +610,7 @@ static int msm_mi2s_sclk_ctl(struct snd_pcm_substream *substream, bool enable)
mi2s_tx_clk.clk_id =
msm8952_get_clk_id(port_id);
mi2s_tx_clk.clk_freq_in_hz =
- Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ;
+ get_mi2s_clk_val(port_id);
ret = afe_set_lpass_clock_v2(port_id,
&mi2s_tx_clk);
}
@@ -790,6 +796,61 @@ static int mi2s_rx_bit_format_put(struct snd_kcontrol *kcontrol,
return 0;
}
+static int mi2s_tx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ mi2s_tx_bits_per_sample = 32;
+ break;
+ case 2:
+ mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ mi2s_tx_bits_per_sample = 32;
+ break;
+ case 1:
+ mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ mi2s_tx_bits_per_sample = 32;
+ break;
+ case 0:
+ default:
+ mi2s_tx_bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ mi2s_tx_bits_per_sample = 16;
+ break;
+ }
+ return 0;
+}
+
+static int mi2s_tx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ switch (mi2s_tx_bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: mi2s_tx_bit_format = %d, ucontrol value = %ld\n",
+ __func__, mi2s_tx_bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
static int loopback_mclk_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -988,8 +1049,8 @@ static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
}
static const struct soc_enum msm_snd_enum[] = {
- SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_bit_format_text),
- rx_bit_format_text),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(bit_format_text),
+ bit_format_text),
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mi2s_ch_text),
mi2s_ch_text),
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(loopback_mclk_text),
@@ -1007,6 +1068,8 @@ static const struct soc_enum msm_snd_enum[] = {
static const struct snd_kcontrol_new msm_snd_controls[] = {
SOC_ENUM_EXT("MI2S_RX Format", msm_snd_enum[0],
mi2s_rx_bit_format_get, mi2s_rx_bit_format_put),
+ SOC_ENUM_EXT("MI2S_TX Format", msm_snd_enum[0],
+ mi2s_tx_bit_format_get, mi2s_tx_bit_format_put),
SOC_ENUM_EXT("MI2S_TX Channels", msm_snd_enum[1],
msm_ter_mi2s_tx_ch_get, msm_ter_mi2s_tx_ch_put),
SOC_ENUM_EXT("MI2S_RX Channels", msm_snd_enum[1],
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 260927e8d434..388fed14ed81 100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -27,6 +27,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -118,7 +119,6 @@ struct msm_compr_pdata {
uint32_t volume[MSM_FRONTEND_DAI_MAX][2]; /* For both L & R */
struct msm_compr_audio_effects *audio_effects[MSM_FRONTEND_DAI_MAX];
bool use_dsp_gapless_mode;
- bool use_legacy_api; /* indicates use older asm apis*/
struct msm_compr_dec_params *dec_params[MSM_FRONTEND_DAI_MAX];
struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
bool is_in_use[MSM_FRONTEND_DAI_MAX];
@@ -842,6 +842,10 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
}
switch (prtd->codec_param.codec.format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bit_width = 32;
+ sample_word_size = 32;
+ break;
case SNDRV_PCM_FORMAT_S24_LE:
bit_width = 24;
sample_word_size = 32;
@@ -856,7 +860,10 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
sample_word_size = 16;
break;
}
- ret = q6asm_media_format_block_pcm_format_support_v3(
+
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ ret = q6asm_media_format_block_pcm_format_support_v3(
prtd->audio_client,
prtd->sample_rate,
prtd->num_channels,
@@ -864,6 +871,24 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
use_default_chmap,
chmap,
sample_word_size);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ ret = q6asm_media_format_block_pcm_format_support_v4(
+ prtd->audio_client,
+ prtd->sample_rate,
+ prtd->num_channels,
+ bit_width, stream_id,
+ use_default_chmap,
+ chmap,
+ sample_word_size,
+ ASM_LITTLE_ENDIAN,
+ DEFAULT_QF);
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (ret < 0)
pr_err("%s: CMD Format block failed\n", __func__);
@@ -1158,10 +1183,25 @@ static int msm_compr_configure_dsp_for_playback
} else {
pr_debug("%s: stream_id %d bits_per_sample %d\n",
__func__, ac->stream_id, bits_per_sample);
- ret = q6asm_stream_open_write_v3(ac,
+
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ ret = q6asm_stream_open_write_v3(ac,
+ prtd->codec, bits_per_sample,
+ ac->stream_id,
+ prtd->gapless_state.use_dsp_gapless_mode);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ ret = q6asm_stream_open_write_v4(ac,
prtd->codec, bits_per_sample,
ac->stream_id,
prtd->gapless_state.use_dsp_gapless_mode);
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (ret < 0) {
pr_err("%s:ASM open write err[%d] for compr type[%d]\n",
__func__, ret, prtd->compr_passthr);
@@ -2282,13 +2322,22 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
/*
* Cache this time as last known time
*/
- if (pdata->use_legacy_api)
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_6):
q6asm_get_session_time_legacy(
prtd->audio_client,
&prtd->marker_timestamp);
- else
+ break;
+ case (Q6_SUBSYS_AVS2_7):
+ case (Q6_SUBSYS_AVS2_8):
q6asm_get_session_time(prtd->audio_client,
&prtd->marker_timestamp);
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
spin_lock_irqsave(&prtd->lock, flags);
/*
@@ -2386,10 +2435,25 @@ static int msm_compr_trigger(struct snd_compr_stream *cstream, int cmd)
pr_debug("%s: open_write stream_id %d bits_per_sample %d",
__func__, stream_id, bits_per_sample);
- rc = q6asm_stream_open_write_v3(prtd->audio_client,
+
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ rc = q6asm_stream_open_write_v3(ac,
+ prtd->codec, bits_per_sample,
+ ac->stream_id,
+ prtd->gapless_state.use_dsp_gapless_mode);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ rc = q6asm_stream_open_write_v4(ac,
prtd->codec, bits_per_sample,
- stream_id,
+ ac->stream_id,
prtd->gapless_state.use_dsp_gapless_mode);
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (rc < 0) {
pr_err("%s: Session out open failed for gapless\n",
__func__);
@@ -2468,13 +2532,22 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream,
stream.
*/
if (!first_buffer || gapless_transition) {
-
- if (pdata->use_legacy_api)
- rc = q6asm_get_session_time_legacy(
- prtd->audio_client, &prtd->marker_timestamp);
- else
- rc = q6asm_get_session_time(
- prtd->audio_client, &prtd->marker_timestamp);
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_6):
+ q6asm_get_session_time_legacy(
+ prtd->audio_client,
+ &prtd->marker_timestamp);
+ break;
+ case (Q6_SUBSYS_AVS2_7):
+ case (Q6_SUBSYS_AVS2_8):
+ q6asm_get_session_time(prtd->audio_client,
+ &prtd->marker_timestamp);
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (rc < 0) {
pr_err("%s: Get Session Time return =%lld\n",
__func__, timestamp);
@@ -3480,8 +3553,6 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
{
struct msm_compr_pdata *pdata;
int i;
- int rc;
- const char *qdsp_version;
pr_debug("%s\n", __func__);
pdata = (struct msm_compr_pdata *)
@@ -3504,17 +3575,6 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
snd_soc_add_platform_controls(platform, msm_compr_gapless_controls,
ARRAY_SIZE(msm_compr_gapless_controls));
- rc = of_property_read_string(platform->dev->of_node,
- "qcom,adsp-version", &qdsp_version);
- if (!rc) {
- if (!strcmp(qdsp_version, "MDSP 1.2"))
- pdata->use_legacy_api = true;
- else
- pdata->use_legacy_api = false;
- } else
- pdata->use_legacy_api = false;
-
- pr_debug("%s: use legacy api %d\n", __func__, pdata->use_legacy_api);
/*
* use_dsp_gapless_mode part of platform data(pdata) is updated from HAL
* through a mixer control before compress driver is opened. The mixer
@@ -3525,6 +3585,16 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
return 0;
}
+static int msm_compr_chmix_cfg_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 128;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 0xFFFFFFFF;
+ return 0;
+}
+
static int msm_compr_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
@@ -3843,6 +3913,113 @@ static int msm_compr_add_app_type_cfg_control(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+
+static int msm_compr_chmix_cfg_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
+ snd_soc_component_get_drvdata(comp);
+ struct snd_compr_stream *cstream = NULL;
+ struct snd_soc_pcm_runtime *rtd = NULL;
+ u64 fe_id = kcontrol->private_value;
+ int ip_channel_cnt, op_channel_cnt;
+ int i, index = 0;
+ int ch_coeff[PCM_FORMAT_MAX_NUM_CHANNEL * PCM_FORMAT_MAX_NUM_CHANNEL];
+ bool use_default_chmap = true;
+ char *chmap = NULL;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ return -EINVAL;
+ }
+ cstream = pdata->cstream[fe_id];
+ if (!cstream) {
+ pr_err("%s: stream inactive\n", __func__);
+ return -EINVAL;
+ }
+ rtd = cstream->private_data;
+ if (!rtd) {
+ pr_err("%s: stream inactive\n", __func__);
+ return -EINVAL;
+ }
+
+ use_default_chmap = !(pdata->ch_map[rtd->dai_link->be_id]->set_ch_map);
+ chmap = pdata->ch_map[rtd->dai_link->be_id]->channel_map;
+
+ ip_channel_cnt = ucontrol->value.integer.value[index++];
+ op_channel_cnt = ucontrol->value.integer.value[index++];
+ /*
+ * wght coeff of first out channel corresponding to each in channel
+ * are sent followed by second out channel for each in channel etc.
+ */
+ memset(ch_coeff, 0, sizeof(ch_coeff));
+ for (i = 0; i < op_channel_cnt * ip_channel_cnt; i++) {
+ ch_coeff[i] =
+ ucontrol->value.integer.value[index++];
+ }
+
+ msm_pcm_routing_send_chmix_cfg(fe_id, ip_channel_cnt, op_channel_cnt,
+ ch_coeff, SESSION_TYPE_RX, use_default_chmap, chmap);
+
+ return 0;
+}
+
+static int msm_compr_chmix_cfg_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_compr_add_chmix_cfg_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = "Audio Stream";
+ const char *deviceNo = "NN";
+ const char *suffix = "Channel Mix Cfg";
+ int ctl_len;
+ char *mixer_str = NULL;
+ struct snd_kcontrol_new chmix_cfg_controls[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_compr_chmix_cfg_ctl_info,
+ .get = msm_compr_chmix_cfg_ctl_get,
+ .put = msm_compr_chmix_cfg_ctl_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s NULL rtd\n", __func__);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: added new compr FE with name %s, id %d, cpu dai %s, device no %d\n",
+ __func__, rtd->dai_link->name, rtd->dai_link->be_id,
+ rtd->dai_link->cpu_dai_name, rtd->pcm->device);
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
+ strlen(suffix) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str)
+ return -ENOMEM;
+
+ snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
+ rtd->pcm->device, suffix);
+
+ chmix_cfg_controls[0].name = mixer_str;
+ chmix_cfg_controls[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s", __func__, mixer_str);
+ snd_soc_add_platform_controls(rtd->platform,
+ chmix_cfg_controls,
+ ARRAY_SIZE(chmix_cfg_controls));
+ kfree(mixer_str);
+ return 0;
+}
+
static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd)
{
const char *mixer_ctl_name = "Playback Channel Map";
@@ -3873,7 +4050,6 @@ static int msm_compr_add_channel_map_control(struct snd_soc_pcm_runtime *rtd)
ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) + 1;
mixer_str = kzalloc(ctl_len, GFP_KERNEL);
-
if (!mixer_str) {
pr_err("%s: failed to allocate mixer ctrl str of len %d\n",
__func__, ctl_len);
@@ -3932,6 +4108,9 @@ static int msm_compr_new(struct snd_soc_pcm_runtime *rtd)
if (rc)
pr_err("%s: Could not add Compr Channel Map Control\n",
__func__);
+ rc = msm_compr_add_chmix_cfg_controls(rtd);
+ if (rc)
+ pr_err("%s: add chmix cfg controls failed:%d\n", __func__, rc);
return 0;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index e5c226f9126b..1c40ba0fa3c1 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -190,17 +190,25 @@ struct msm_dai_q6_auxpcm_dai_data {
struct msm_dai_q6_dai_data bdai_data; /* incoporate base DAI data */
};
+static union afe_port_group_config group_cfg_tx;
+static union afe_port_group_config group_cfg_rx;
+
struct msm_dai_q6_tdm_dai_data {
DECLARE_BITMAP(status_mask, STATUS_MAX);
u32 rate;
u32 channels;
u32 bitwidth;
u32 num_group_ports;
+ bool afe_ebit_unsupported;
+ bool sec_port_enable;
struct afe_clk_set clk_set; /* hold LPASS clock config. */
union afe_port_group_config group_cfg; /* hold tdm group config */
struct afe_tdm_port_config port_cfg; /* hold tdm config */
};
+static bool afe_ebit_unsupported;
+static bool tdm_sec_port_enable;
+
/* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command
* 0: linear PCM
* 1: non-linear PCM
@@ -2049,7 +2057,7 @@ static struct snd_soc_dai_driver msm_dai_q6_afe_lb_tx_dai[] = {
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 48000,
},
.id = AFE_LOOPBACK_TX,
.probe = msm_dai_q6_dai_probe,
@@ -3127,6 +3135,10 @@ static int msm_dai_q6_mi2s_hw_params(struct snd_pcm_substream *substream,
dai_data->port_config.i2s.bit_width = 24;
dai_data->bitwidth = 24;
break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ dai_data->port_config.i2s.bit_width = 32;
+ dai_data->bitwidth = 32;
+ break;
default:
pr_err("%s: format %d\n",
__func__, params_format(params));
@@ -3285,10 +3297,14 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.stream_name = "Primary MI2S Capture",
.aif_name = "PRI_MI2S_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_mi2s_ops,
.id = MSM_PRIM_MI2S,
@@ -3310,10 +3326,14 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.stream_name = "Secondary MI2S Capture",
.aif_name = "SEC_MI2S_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_mi2s_ops,
.id = MSM_SEC_MI2S,
@@ -3334,10 +3354,14 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.stream_name = "Tertiary MI2S Capture",
.aif_name = "TERT_MI2S_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_mi2s_ops,
.id = MSM_TERT_MI2S,
@@ -3359,10 +3383,14 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.stream_name = "Quaternary MI2S Capture",
.aif_name = "QUAT_MI2S_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_mi2s_ops,
.id = MSM_QUAT_MI2S,
@@ -3396,10 +3424,14 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.stream_name = "Quinary MI2S Capture",
.aif_name = "QUIN_MI2S_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_mi2s_ops,
.id = MSM_QUIN_MI2S,
@@ -3411,10 +3443,14 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = {
.stream_name = "Senary_mi2s Capture",
.aif_name = "SENARY_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_192000,
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_dai_q6_mi2s_ops,
.id = MSM_SENARY_MI2S,
@@ -4151,6 +4187,16 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "%s: Clk Attribute from DT file %d\n",
__func__, tdm_clk_set.clk_attri);
+ afe_ebit_unsupported = of_property_read_bool(pdev->dev.of_node,
+ "qcom,msm-cpudai-tdm-afe-ebit-unsupported");
+
+ dev_dbg(&pdev->dev, "afe_ebit_unsupported %d\n", afe_ebit_unsupported);
+
+ tdm_sec_port_enable = of_property_read_bool(pdev->dev.of_node,
+ "qcom,msm-cpudai-tdm-sec-port-enable");
+
+ dev_dbg(&pdev->dev, "tdm_sec_port_enable %d\n", tdm_sec_port_enable);
+
/* other initializations within device group */
atomic_set(&tdm_group_ref[group_idx], 0);
@@ -4926,6 +4972,9 @@ static int msm_dai_q6_tdm_set_clk(
{
int rc = 0;
+ pr_debug("dai_data->group_cfg.tdm_cfg.group_id = %d : %d\n",
+ dai_data->group_cfg.tdm_cfg.group_id,
+ dai_data->clk_set.clk_freq_in_hz);
switch (dai_data->group_cfg.tdm_cfg.group_id) {
case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX:
case AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX:
@@ -5097,11 +5146,15 @@ static int msm_dai_q6_dai_tdm_remove(struct snd_soc_dai *dai)
dev_err(dai->dev, "fail to disable AFE group 0x%x\n",
group_id);
}
- rc = msm_dai_q6_tdm_set_clk(tdm_dai_data,
- dai->id, false);
- if (IS_ERR_VALUE(rc)) {
- dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
+ if (!(tdm_dai_data->afe_ebit_unsupported &&
+ !tdm_dai_data->clk_set.clk_freq_in_hz)) {
+ rc = msm_dai_q6_tdm_set_clk(tdm_dai_data,
+ dai->id, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s: fail to disable AFE clk 0x%x\n",
__func__, dai->id);
+ }
}
}
}
@@ -5138,6 +5191,10 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
case 16:
cap_mask = 0xFFFF;
break;
+ case 4:
+ cap_mask = 0xF;
+ break;
+
default:
dev_err(dai->dev, "%s: invalid slots %d\n",
__func__, slots);
@@ -5180,6 +5237,11 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
tdm_group->nslots_per_frame = slots;
tdm_group->slot_width = slot_width;
tdm_group->slot_mask = rx_mask & cap_mask;
+ dev_dbg(dai->dev, "%s:Rx:tdm_group->nslots_per_frame %d\n"
+ "tdm_group->slot_width %d\n"
+ "tdm_group->slot_mask %d\n", __func__,
+ tdm_group->nslots_per_frame,
+ tdm_group->slot_width, tdm_group->slot_mask);
break;
case AFE_PORT_ID_PRIMARY_TDM_TX:
case AFE_PORT_ID_PRIMARY_TDM_TX_1:
@@ -5216,6 +5278,10 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
tdm_group->nslots_per_frame = slots;
tdm_group->slot_width = slot_width;
tdm_group->slot_mask = tx_mask & cap_mask;
+ dev_dbg(dai->dev, "%s:Tx:tdm_group->nslots_per_frame %d\n"
+ "tdm_group->slot_width %d,tdm_group->slot_mask %d\n"
+ "tx%d\n", __func__, tdm_group->nslots_per_frame,
+ tdm_group->slot_width, tdm_group->slot_mask, tx_mask);
break;
default:
dev_err(dai->dev, "%s: invalid dai id 0x%x\n",
@@ -5516,7 +5582,34 @@ static int msm_dai_q6_tdm_hw_params(struct snd_pcm_substream *substream,
custom_tdm_header->header[6],
custom_tdm_header->header[7]);
}
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ group_cfg_tx.tdm_cfg.num_channels =
+ dai_data->group_cfg.tdm_cfg.num_channels;
+ group_cfg_tx.tdm_cfg.sample_rate =
+ dai_data->group_cfg.tdm_cfg.sample_rate;
+ group_cfg_tx.tdm_cfg.bit_width =
+ dai_data->group_cfg.tdm_cfg.bit_width;
+ group_cfg_tx.tdm_cfg.nslots_per_frame =
+ dai_data->group_cfg.tdm_cfg.nslots_per_frame;
+ group_cfg_tx.tdm_cfg.slot_width =
+ dai_data->group_cfg.tdm_cfg.slot_width;
+ group_cfg_tx.tdm_cfg.slot_mask =
+ dai_data->group_cfg.tdm_cfg.slot_mask;
+ } else {
+ group_cfg_rx.tdm_cfg.num_channels =
+ dai_data->group_cfg.tdm_cfg.num_channels;
+ group_cfg_rx.tdm_cfg.sample_rate =
+ dai_data->group_cfg.tdm_cfg.sample_rate;
+ group_cfg_rx.tdm_cfg.bit_width =
+ dai_data->group_cfg.tdm_cfg.bit_width;
+ group_cfg_rx.tdm_cfg.nslots_per_frame =
+ dai_data->group_cfg.tdm_cfg.nslots_per_frame;
+ group_cfg_rx.tdm_cfg.slot_width =
+ dai_data->group_cfg.tdm_cfg.slot_width;
+ group_cfg_rx.tdm_cfg.slot_mask =
+ dai_data->group_cfg.tdm_cfg.slot_mask;
+ }
return 0;
}
@@ -5527,8 +5620,13 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
struct msm_dai_q6_tdm_dai_data *dai_data =
dev_get_drvdata(dai->dev);
u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
+ u16 sec_group_id = 0;
int group_idx = 0;
+ int sec_group_idx = 0;
+ u16 prim_port_id = 0;
+ u16 sec_port_id = 0;
atomic_t *group_ref = NULL;
+ atomic_t *sec_group_ref = NULL;
group_idx = msm_dai_q6_get_group_idx(dai->id);
if (group_idx < 0) {
@@ -5548,41 +5646,165 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
/* TX and RX share the same clk.
AFE clk is enabled per group to simplify the logic.
DSP will monitor the clk count. */
- rc = msm_dai_q6_tdm_set_clk(dai_data,
- dai->id, true);
- if (IS_ERR_VALUE(rc)) {
- dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n",
- __func__, dai->id);
- goto rtn;
+ if (!(dai_data->afe_ebit_unsupported &&
+ !dai_data->clk_set.clk_freq_in_hz)) {
+ rc = msm_dai_q6_tdm_set_clk(dai_data,
+ dai->id, true);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s:AFE CLK enable fail 0x%x\n",
+ __func__, dai->id);
+ goto rtn;
+ }
}
if (dai_data->num_group_ports > 1) {
+ dev_dbg(dai->dev, "%s:enable afe group\n",
+ __func__);
rc = afe_port_group_enable(group_id,
&dai_data->group_cfg, true);
if (IS_ERR_VALUE(rc)) {
- dev_err(dai->dev, "%s: fail to enable AFE group 0x%x\n",
+ dev_err(dai->dev,
+ "%s:failed to enable grp %x\n",
__func__, group_id);
goto rtn;
}
}
}
-
- rc = afe_tdm_port_start(dai->id, &dai_data->port_cfg,
+ /*
+ * 8909 HW has a dependency where for Rx/Tx to work in TDM mode
+ * We need to start a Tx or Rx port in the same group.
+ * Hence for BG use TDM_TX when a RX session is requested and
+ * use TDM_RX port when a TX session is requested as these ports
+ * are unused as of now.
+ */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ prim_port_id = dai->id;
+ if (dai_data->sec_port_enable) {
+ sec_port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
+ sec_group_ref = &tdm_group_ref[sec_group_idx];
+ }
+ if ((dai_data->num_group_ports > 1) &&
+ (dai_data->sec_port_enable)) {
+ sec_group_id =
+ AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX;
+ sec_group_idx =
+ msm_dai_q6_get_group_idx(sec_group_id);
+ if (sec_group_idx < 0) {
+ dev_err(dai->dev, "%s port id 0x%x\n"
+ "not supported\n", __func__,
+ sec_group_id);
+ goto rtn;
+ }
+ if (atomic_read(sec_group_ref) == 0) {
+ rc = afe_port_group_enable(
+ sec_group_id,
+ &group_cfg_tx,
+ true);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s:failed to\n"
+ "enable grp\n"
+ "%x\n", __func__,
+ group_id);
+ goto rtn;
+ }
+ }
+ }
+ } else {
+ prim_port_id = dai->id;
+ if (dai_data->sec_port_enable) {
+ sec_port_id = AFE_PORT_ID_PRIMARY_TDM_RX;
+ sec_group_ref = &tdm_group_ref[sec_group_idx];
+ }
+ if ((dai_data->num_group_ports > 1) &&
+ (dai_data->sec_port_enable)) {
+ sec_group_id =
+ AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX;
+ sec_group_idx =
+ msm_dai_q6_get_group_idx(sec_group_id);
+ if (sec_group_idx < 0) {
+ dev_err(dai->dev, "%s port id 0x%x\n"
+ " not supported\n", __func__,
+ sec_group_id);
+ goto rtn;
+ }
+ if (atomic_read(sec_group_ref) == 0) {
+ rc = afe_port_group_enable(
+ sec_group_id,
+ &group_cfg_rx,
+ true);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s:failed to\n"
+ "enable grp\n"
+ "%x\n", __func__,
+ group_id);
+ goto rtn;
+ }
+ }
+ }
+ }
+ dev_dbg(dai->dev, "\n%s:open prim port id %d TDM rate: %d\n"
+ "dai_data->port_cfg.tdm.slot_mask %x\n"
+ "dai_data->port_cfg.tdm.nslots_per_frame:%x\n",
+ __func__, prim_port_id,
+ dai_data->port_cfg.tdm.num_channels,
+ dai_data->port_cfg.tdm.slot_mask,
+ dai_data->port_cfg.tdm.nslots_per_frame);
+
+ rc = afe_tdm_port_start(prim_port_id, &dai_data->port_cfg,
dai_data->rate, dai_data->num_group_ports);
+
if (IS_ERR_VALUE(rc)) {
if (atomic_read(group_ref) == 0) {
afe_port_group_enable(group_id,
NULL, false);
- msm_dai_q6_tdm_set_clk(dai_data,
- dai->id, false);
+ if (!(dai_data->afe_ebit_unsupported &&
+ !dai_data->clk_set.clk_freq_in_hz))
+ msm_dai_q6_tdm_set_clk(dai_data,
+ dai->id, false);
}
- dev_err(dai->dev, "%s: fail to open AFE port 0x%x\n",
- __func__, dai->id);
+ dev_err(dai->dev, "%s: open AFE port 0x%x\n",
+ __func__, prim_port_id);
} else {
set_bit(STATUS_PORT_STARTED,
dai_data->status_mask);
atomic_inc(group_ref);
}
+ dai_data->port_cfg.tdm.num_channels = 1;
+ dai_data->port_cfg.tdm.slot_mask = 1;
+
+ dev_dbg(dai->dev, "\n%s:open sec port id %d TDM rate: %d\n"
+ "dai_data->port_cfg.tdm.slot_mask %x\n"
+ "dai_data->port_cfg.tdm.nslotsper_frame:%x\n", __func__,
+ sec_port_id, dai_data->port_cfg.tdm.num_channels,
+ dai_data->port_cfg.tdm.slot_mask,
+ dai_data->port_cfg.tdm.nslots_per_frame);
+
+ if (sec_port_id != 0) {
+ rc = afe_tdm_port_start(sec_port_id,
+ &dai_data->port_cfg,
+ dai_data->rate,
+ dai_data->num_group_ports);
+ if (IS_ERR_VALUE(rc)) {
+ if (atomic_read(group_ref) == 0) {
+ afe_port_group_enable(group_id,
+ NULL, false);
+ if (!(dai_data->afe_ebit_unsupported &&
+ !dai_data->clk_set.clk_freq_in_hz))
+ msm_dai_q6_tdm_set_clk(dai_data,
+ dai->id, false);
+ }
+ dev_err(dai->dev, "%s: fail AFE port 0x%x\n",
+ __func__, sec_port_id);
+ } else {
+ set_bit(STATUS_PORT_STARTED,
+ dai_data->status_mask);
+ atomic_inc(sec_group_ref);
+ }
+ }
+
/* TODO: need to monitor PCM/MI2S/TDM HW status */
/* NOTE: AFE should error out if HW resource contention */
@@ -5600,8 +5822,13 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
struct msm_dai_q6_tdm_dai_data *dai_data =
dev_get_drvdata(dai->dev);
u16 group_id = dai_data->group_cfg.tdm_cfg.group_id;
+ u16 sec_group_id = 0;
int group_idx = 0;
+ int sec_group_idx = 0;
+ u16 prim_port_id = 0;
+ u16 sec_port_id = 0;
atomic_t *group_ref = NULL;
+ atomic_t *sec_group_ref = NULL;
group_idx = msm_dai_q6_get_group_idx(dai->id);
if (group_idx < 0) {
@@ -5615,11 +5842,60 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
group_ref = &tdm_group_ref[group_idx];
if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
- rc = afe_close(dai->id);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ prim_port_id = dai->id;
+ if (dai_data->sec_port_enable) {
+ sec_port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
+ sec_group_ref = &tdm_group_ref[sec_group_idx];
+ }
+ if ((dai_data->num_group_ports > 1) &&
+ (dai_data->sec_port_enable)) {
+ sec_group_id =
+ AFE_GROUP_DEVICE_ID_PRIMARY_TDM_TX;
+ sec_group_idx =
+ msm_dai_q6_get_group_idx(sec_group_id);
+ if (sec_group_idx < 0) {
+ dev_err(dai->dev, "%s port id 0x%x\n"
+ "not supported\n",
+ __func__, sec_group_id);
+ return;
+ }
+ }
+ } else {
+ prim_port_id = dai->id;
+ if (dai_data->sec_port_enable) {
+ sec_port_id = AFE_PORT_ID_PRIMARY_TDM_RX;
+ sec_group_ref = &tdm_group_ref[sec_group_idx];
+ }
+ if ((dai_data->num_group_ports > 1) &&
+ (dai_data->sec_port_enable)) {
+ sec_group_id =
+ AFE_GROUP_DEVICE_ID_PRIMARY_TDM_RX;
+ sec_group_idx =
+ msm_dai_q6_get_group_idx(sec_group_id);
+ if (sec_group_idx < 0) {
+ dev_err(dai->dev, "%s port id 0x%x\n"
+ "not supported\n",
+ __func__, sec_group_id);
+ return;
+ }
+ }
+ }
+ rc = afe_close(prim_port_id);
if (IS_ERR_VALUE(rc)) {
dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n",
- __func__, dai->id);
+ __func__, prim_port_id);
+ }
+
+ if (sec_port_id != 0) {
+ rc = afe_close(sec_port_id);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s: fail AFE port 0x%x\n",
+ __func__, sec_port_id);
+ }
+ atomic_dec(sec_group_ref);
}
+
atomic_dec(group_ref);
clear_bit(STATUS_PORT_STARTED,
dai_data->status_mask);
@@ -5628,17 +5904,32 @@ static void msm_dai_q6_tdm_shutdown(struct snd_pcm_substream *substream,
rc = afe_port_group_enable(group_id,
NULL, false);
if (IS_ERR_VALUE(rc)) {
- dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n",
+ dev_err(dai->dev,
+ "%s: failed to disable grp 0x%x\n",
__func__, group_id);
}
- rc = msm_dai_q6_tdm_set_clk(dai_data,
- dai->id, false);
- if (IS_ERR_VALUE(rc)) {
- dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n",
+ if (!(dai_data->afe_ebit_unsupported &&
+ !dai_data->clk_set.clk_freq_in_hz)) {
+ rc = msm_dai_q6_tdm_set_clk(dai_data,
+ dai->id, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s: fail to disable AFE clk 0x%x\n",
__func__, dai->id);
+ }
+ }
+ }
+ if ((dai_data->num_group_ports > 1) &&
+ (dai_data->sec_port_enable)) {
+ if (atomic_read(sec_group_ref) == 0) {
+ rc = afe_port_group_enable(sec_group_id,
+ NULL, false);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev, "%s:failed to\n"
+ "enable grp %x\n", __func__, group_id);
+ }
}
}
-
/* TODO: need to monitor PCM/MI2S/TDM HW status */
/* NOTE: AFE should error out if HW resource contention */
@@ -7005,6 +7296,46 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
dai_data->group_cfg.tdm_cfg = tdm_group_cfg;
/* copy static num group ports per parent node */
dai_data->num_group_ports = num_tdm_group_ports[group_idx];
+ dev_dbg(&pdev->dev, "TX group configuration tdm_dev_id 0x%x\n",
+ tdm_dev_id);
+
+ dai_data->afe_ebit_unsupported = afe_ebit_unsupported;
+ dai_data->sec_port_enable = tdm_sec_port_enable;
+
+ if (tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX ||
+ tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_1 ||
+ tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_2 ||
+ tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_TX_3) {
+ memcpy(&group_cfg_tx.group_cfg,
+ &dai_data->group_cfg.group_cfg ,
+ sizeof(dai_data->group_cfg.group_cfg));
+ memcpy(&group_cfg_tx.group_enable,
+ &dai_data->group_cfg.group_enable,
+ sizeof(dai_data->group_cfg.group_enable));
+ memcpy(&group_cfg_tx.tdm_cfg,
+ &dai_data->group_cfg.tdm_cfg,
+ sizeof(dai_data->group_cfg.tdm_cfg));
+ dev_dbg(&pdev->dev,
+ "Copy TX group configuration Successfully tdm_id %d\n",
+ tdm_dev_id);
+ }
+ if (tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX ||
+ tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_1 ||
+ tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_2 ||
+ tdm_dev_id == AFE_PORT_ID_PRIMARY_TDM_RX_3) {
+ memcpy(&group_cfg_rx.group_cfg,
+ &dai_data->group_cfg.group_cfg ,
+ sizeof(dai_data->group_cfg.group_cfg));
+ memcpy(&group_cfg_rx.group_enable,
+ &dai_data->group_cfg.group_enable,
+ sizeof(dai_data->group_cfg.group_enable));
+ memcpy(&group_cfg_rx.tdm_cfg,
+ &dai_data->group_cfg.tdm_cfg,
+ sizeof(dai_data->group_cfg.tdm_cfg));
+ dev_dbg(&pdev->dev,
+ "Copy RX group configuration Successfully tdm_id %d\n",
+ tdm_dev_id);
+ }
dev_set_drvdata(&pdev->dev, dai_data);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index eefae71a27bf..e505f416ab2c 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
#include "msm-pcm-q6-v2.h"
#include "msm-pcm-routing-v2.h"
@@ -68,10 +69,11 @@ static struct snd_pcm_hardware msm_pcm_hardware_capture = {
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
- .rates = SNDRV_PCM_RATE_8000_48000,
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .rates = SNDRV_PCM_RATE_8000_384000,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 384000,
.channels_min = 1,
.channels_max = 4,
.buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
@@ -91,10 +93,11 @@ static struct snd_pcm_hardware msm_pcm_hardware_playback = {
SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
- SNDRV_PCM_FMTBIT_S24_3LE),
- .rates = SNDRV_PCM_RATE_8000_192000,
+ SNDRV_PCM_FMTBIT_S24_3LE |
+ SNDRV_PCM_FMTBIT_S32_LE),
+ .rates = SNDRV_PCM_RATE_8000_384000,
.rate_min = 8000,
- .rate_max = 192000,
+ .rate_max = 384000,
.channels_min = 1,
.channels_max = 8,
.buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS *
@@ -109,7 +112,7 @@ static struct snd_pcm_hardware msm_pcm_hardware_playback = {
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
- 88200, 96000, 176400, 192000
+ 88200, 96000, 176400, 192000, 384000
};
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
@@ -290,7 +293,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
struct msm_audio *prtd = runtime->private_data;
struct msm_plat_data *pdata;
struct snd_pcm_hw_params *params;
- int ret;
+ int ret = 0;
uint16_t bits_per_sample;
uint16_t sample_word_size;
@@ -321,6 +324,10 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
pr_debug("%s: perf: %x\n", __func__, prtd->audio_client->perf_mode);
switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bits_per_sample = 32;
+ sample_word_size = 32;
+ break;
case SNDRV_PCM_FORMAT_S24_LE:
bits_per_sample = 24;
sample_word_size = 32;
@@ -336,9 +343,20 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
break;
}
- ret = q6asm_open_write_v3(prtd->audio_client,
- FORMAT_LINEAR_PCM, bits_per_sample);
-
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ ret = q6asm_open_write_v3(prtd->audio_client,
+ FORMAT_LINEAR_PCM, bits_per_sample);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ ret = q6asm_open_write_v4(prtd->audio_client,
+ FORMAT_LINEAR_PCM, bits_per_sample);
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (ret < 0) {
pr_err("%s: q6asm_open_write_v2 failed\n", __func__);
q6asm_audio_client_free(prtd->audio_client);
@@ -361,11 +379,28 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
return ret;
}
- ret = q6asm_media_format_block_multi_ch_pcm_v3(
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ ret = q6asm_media_format_block_multi_ch_pcm_v3(
prtd->audio_client, runtime->rate,
runtime->channels, !prtd->set_channel_map,
prtd->channel_map, bits_per_sample,
sample_word_size);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ ret = q6asm_media_format_block_multi_ch_pcm_v4(
+ prtd->audio_client, runtime->rate,
+ runtime->channels, !prtd->set_channel_map,
+ prtd->channel_map, bits_per_sample,
+ sample_word_size, ASM_LITTLE_ENDIAN,
+ DEFAULT_QF);
+
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (ret < 0)
pr_info("%s: CMD Format block failed\n", __func__);
@@ -410,6 +445,8 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
if ((params_format(params) == SNDRV_PCM_FORMAT_S24_LE) ||
(params_format(params) == SNDRV_PCM_FORMAT_S24_3LE))
bits_per_sample = 24;
+ else if (params_format(params) == SNDRV_PCM_FORMAT_S32_LE)
+ bits_per_sample = 32;
/* ULL mode is not supported in capture path */
if (pdata->perf_mode_set == LEGACY_PCM_MODE)
@@ -421,8 +458,23 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
__func__, params_channels(params),
prtd->audio_client->perf_mode);
- ret = q6asm_open_read_v3(prtd->audio_client, FORMAT_LINEAR_PCM,
- bits_per_sample);
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ ret = q6asm_open_read_v3(prtd->audio_client,
+ FORMAT_LINEAR_PCM,
+ bits_per_sample);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ ret = q6asm_open_read_v4(prtd->audio_client,
+ FORMAT_LINEAR_PCM,
+ bits_per_sample);
+
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (ret < 0) {
pr_err("%s: q6asm_open_read failed\n", __func__);
q6asm_audio_client_free(prtd->audio_client);
@@ -467,6 +519,10 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
return 0;
switch (runtime->format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bits_per_sample = 32;
+ sample_word_size = 32;
+ break;
case SNDRV_PCM_FORMAT_S24_LE:
bits_per_sample = 24;
sample_word_size = 32;
@@ -485,11 +541,32 @@ static int msm_pcm_capture_prepare(struct snd_pcm_substream *substream)
pr_debug("%s: Samp_rate = %d Channel = %d bit width = %d, word size = %d\n",
__func__, prtd->samp_rate, prtd->channel_mode,
bits_per_sample, sample_word_size);
- ret = q6asm_enc_cfg_blk_pcm_format_support_v3(prtd->audio_client,
- prtd->samp_rate,
- prtd->channel_mode,
- bits_per_sample,
- sample_word_size);
+
+ switch (q6core_get_avs_version()) {
+ case (Q6_SUBSYS_AVS2_7):
+ ret = q6asm_enc_cfg_blk_pcm_format_support_v3(
+ prtd->audio_client,
+ prtd->samp_rate,
+ prtd->channel_mode,
+ bits_per_sample,
+ sample_word_size);
+ break;
+ case (Q6_SUBSYS_AVS2_8):
+ ret = q6asm_enc_cfg_blk_pcm_format_support_v4(
+ prtd->audio_client,
+ prtd->samp_rate,
+ prtd->channel_mode,
+ bits_per_sample,
+ sample_word_size,
+ ASM_LITTLE_ENDIAN,
+ DEFAULT_QF);
+
+ break;
+ case (Q6_SUBSYS_INVALID):
+ default:
+ pr_err("%s: INVALID AVS IMAGE\n", __func__);
+ break;
+ }
if (ret < 0)
pr_debug("%s: cmd cfg pcm was block failed", __func__);
@@ -1548,6 +1625,150 @@ static int msm_pcm_add_app_type_controls(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int msm_pcm_chmix_cfg_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 128;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 0xFFFFFFFF;
+ return 0;
+}
+
+static int msm_pcm_chmix_cfg_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *usr_info = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_platform *platform;
+ struct msm_plat_data *pdata;
+ struct snd_pcm_substream *substream;
+ struct msm_audio *prtd;
+ u64 fe_id = kcontrol->private_value;
+ int ip_channel_cnt, op_channel_cnt;
+ int i, index = 0, ret = 0;
+ int ch_coeff[PCM_FORMAT_MAX_NUM_CHANNEL * PCM_FORMAT_MAX_NUM_CHANNEL];
+ bool use_default_chmap = true;
+ char *ch_map = NULL;
+
+ pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s: Received out of bounds fe_id %llu\n",
+ __func__, fe_id);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ if (!usr_info) {
+ pr_err("%s: usr_info is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ platform = snd_soc_component_to_platform(usr_info);
+ if (!platform) {
+ pr_err("%s: platform is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ pdata = dev_get_drvdata(platform->dev);
+ if (!pdata) {
+ pr_err("%s: pdata is null\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+
+ if (!substream) {
+ pr_err("%s substream not found\n", __func__);
+ return -ENODEV;
+ }
+ if (!substream->runtime) {
+ pr_err("%s substream runtime not found\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ prtd = substream->runtime->private_data;
+ if (!prtd) {
+ pr_err("%s: stream inactive\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ use_default_chmap = !prtd->set_channel_map;
+ ch_map = prtd->channel_map;
+ ip_channel_cnt = ucontrol->value.integer.value[index++];
+ op_channel_cnt = ucontrol->value.integer.value[index++];
+ /*
+ * wght coeff of first out channel corresponding to each in channel
+ * are sent followed by second out channel for each in channel etc.
+ */
+ memset(ch_coeff, 0, sizeof(ch_coeff));
+ for (i = 0; i < op_channel_cnt * ip_channel_cnt; i++) {
+ ch_coeff[i] =
+ ucontrol->value.integer.value[index++];
+ }
+
+ msm_pcm_routing_send_chmix_cfg(fe_id, ip_channel_cnt, op_channel_cnt,
+ ch_coeff, SESSION_TYPE_RX, use_default_chmap, ch_map);
+done:
+ return ret;
+}
+
+static int msm_pcm_chmix_cfg_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int msm_pcm_add_chmix_cfg_controls(struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = "Audio Stream";
+ const char *deviceNo = "NN";
+ const char *suffix = "Channel Mix Cfg";
+ char *mixer_str = NULL;
+ int ctl_len = 0;
+ struct msm_plat_data *pdata;
+ struct snd_kcontrol_new chmix_cfg_controls[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_pcm_chmix_cfg_ctl_info,
+ .get = msm_pcm_chmix_cfg_ctl_get,
+ .put = msm_pcm_chmix_cfg_ctl_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s: NULL rtd\n", __func__);
+ return -EINVAL;
+ }
+
+ ctl_len = strlen(mixer_ctl_name) + 1 +
+ strlen(deviceNo) + 1 + strlen(suffix) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+ if (!mixer_str)
+ return -ENOMEM;
+
+ snprintf(mixer_str, ctl_len, "%s %d %s",
+ mixer_ctl_name, rtd->pcm->device, suffix);
+ chmix_cfg_controls[0].name = mixer_str;
+ chmix_cfg_controls[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ pdata = dev_get_drvdata(rtd->platform->dev);
+ if (pdata) {
+ if (!pdata->pcm)
+ pdata->pcm = rtd->pcm;
+ snd_soc_add_platform_controls(rtd->platform,
+ chmix_cfg_controls,
+ ARRAY_SIZE(chmix_cfg_controls));
+ } else {
+ pr_err("%s: NULL pdata\n", __func__);
+ return -EINVAL;
+ }
+ kfree(mixer_str);
+ return 0;
+}
+
static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
@@ -1565,6 +1786,10 @@ static int msm_pcm_add_controls(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add pcm topology control %d\n",
__func__, ret);
}
+
+ ret = msm_pcm_add_chmix_cfg_controls(rtd);
+ if (ret)
+ pr_err("%s: add chmix cfg controls failed:%d\n", __func__, ret);
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index 187133b1db75..b3a7e856a9c0 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -59,11 +59,11 @@ struct msm_audio_in_frame_info {
#define PLAYBACK_MIN_NUM_PERIODS 2
#define PLAYBACK_MAX_NUM_PERIODS 8
-#define PLAYBACK_MAX_PERIOD_SIZE 61440
+#define PLAYBACK_MAX_PERIOD_SIZE 122880
#define PLAYBACK_MIN_PERIOD_SIZE 128
#define CAPTURE_MIN_NUM_PERIODS 2
#define CAPTURE_MAX_NUM_PERIODS 8
-#define CAPTURE_MAX_PERIOD_SIZE 61440
+#define CAPTURE_MAX_PERIOD_SIZE 122880
#define CAPTURE_MIN_PERIOD_SIZE 320
struct msm_audio {
@@ -124,6 +124,7 @@ struct output_meta_data_st {
struct msm_plat_data {
int perf_mode;
int perf_mode_set;
+ struct snd_pcm *pcm;
};
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index f20c6f7a2a54..f5daf4cf1513 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -104,13 +104,16 @@ enum {
#define SLIMBUS_5_TX_TEXT "SLIMBUS_5_TX"
#define TERT_MI2S_TX_TEXT "TERT_MI2S_TX"
#define QUAT_MI2S_TX_TEXT "QUAT_MI2S_TX"
+#define PRI_TDM_TX_3_TEXT "PRI_TDM_TX_3"
+#define PRI_TDM_TX_2_TEXT "PRI_TDM_TX_2"
#define ADM_LSM_TX_TEXT "ADM_LSM_TX"
#define LSM_FUNCTION_TEXT "LSM Function"
static const char * const lsm_port_text[] = {
"None",
SLIMBUS_0_TX_TEXT, SLIMBUS_1_TX_TEXT, SLIMBUS_2_TX_TEXT,
SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT,
- TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT
+ TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT,
+ PRI_TDM_TX_2_TEXT, PRI_TDM_TX_3_TEXT,
};
struct msm_pcm_route_bdai_pp_params {
@@ -133,6 +136,9 @@ static int msm_routing_get_bit_width(unsigned int format)
int bit_width;
switch (format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bit_width = 32;
+ break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
bit_width = 24;
@@ -682,6 +688,78 @@ static bool is_mm_lsm_fe_id(int fe_id)
return rc;
}
+/*
+ * msm_pcm_routing_send_chmix_cfg
+ *
+ * Receives fe_id, ip_channel_cnt, op_channel_cnt, channel weight, session_type
+ * use_default_chmap and channel map to map in channel mixer and send to
+ * adm programmable matrix.
+ *
+ * fe_id - Passed value, frontend id which is wanted
+ * ip_channel_cnt - Passed value, number of input channels
+ * op_channel_cnt - Passed value, number of output channels
+ * ch_wght_coeff - Passed reference, weights for each output channel
+ * session_type - Passed value, session_type for RX or TX
+ * use_default_chmap - true if default channel map to be used
+ * ch_map - input/output channel map for playback/capture session respectively
+ */
+
+int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt,
+ int op_channel_cnt, int *ch_wght_coeff,
+ int session_type, bool use_default_chmap,
+ char *channel_map)
+{
+ int rc = 0, idx = 0, i, j;
+ int be_index = 0, port_id, index = 0;
+ unsigned int session_id = 0;
+
+ pr_debug("%s: fe_id[%d] ip_ch[%d] op_ch[%d] sess_type [%d]\n",
+ __func__, fe_id, ip_channel_cnt, op_channel_cnt, session_type);
+
+ if (!use_default_chmap && (channel_map == NULL)) {
+ pr_err("%s: No valid chan map and can't use default\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if ((ch_wght_coeff == NULL) || (op_channel_cnt > ADM_MAX_CHANNELS) ||
+ (ip_channel_cnt > ADM_MAX_CHANNELS)) {
+ pr_err("%s: Invalid channels or null coefficients\n", __func__);
+ return -EINVAL;
+ }
+
+ for (be_index = 0; be_index < MSM_BACKEND_DAI_MAX; be_index++) {
+ port_id = msm_bedais[be_index].port_id;
+ if (!msm_bedais[be_index].active ||
+ !test_bit(fe_id, &msm_bedais[be_index].fe_sessions))
+ continue;
+
+ session_id = fe_dai_map[fe_id][session_type].strm_id;
+ channel_mixer[fe_id].input_channels[0] = ip_channel_cnt;
+ channel_mixer[fe_id].output_channel = op_channel_cnt;
+ channel_mixer[fe_id].rule = 0;
+
+ for (j = 0; j < op_channel_cnt; j++) {
+ for (i = 0; i < ip_channel_cnt; i++)
+ channel_mixer[fe_id].channel_weight[j][i] =
+ ch_wght_coeff[index++];
+ }
+ for (idx = 0; idx < MAX_COPPS_PER_PORT; idx++) {
+ unsigned long copp =
+ session_copp_map[fe_id][session_type][be_index];
+ if (!test_bit(idx, &copp))
+ continue;
+ rc = adm_programable_channel_mixer(port_id,
+ idx, session_id, session_type,
+ channel_mixer + fe_id, 0,
+ use_default_chmap, channel_map);
+ if (rc < 0)
+ pr_err("%s: err setting channel mix config\n",
+ __func__);
+ }
+ }
+ return 0;
+}
void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
int acdb_dev_id, int sample_rate, int session_type)
@@ -1139,6 +1217,8 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode,
int sess_type = 0;
int i = 0, j = 0, be_id;
int ret = 0;
+ bool use_default_chmap = true;
+ char *ch_map = NULL;
if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
pr_err("%s: invalid FE %d\n", __func__, fe_id);
@@ -1181,7 +1261,8 @@ static int msm_pcm_routing_channel_mixer(int fe_id, bool perf_mode,
ret = adm_programable_channel_mixer(
msm_bedais[be_id].port_id,
copp_idx, dspst_id, sess_type,
- channel_mixer + fe_id, i);
+ channel_mixer + fe_id, i,
+ use_default_chmap, ch_map);
}
}
@@ -2057,6 +2138,12 @@ static int msm_routing_lsm_port_put(struct snd_kcontrol *kcontrol,
case 9:
lsm_port = ADM_LSM_PORT_ID;
break;
+ case 10:
+ lsm_port = AFE_PORT_ID_PRIMARY_TDM_TX_2;
+ break;
+ case 11:
+ lsm_port = AFE_PORT_ID_PRIMARY_TDM_TX_3;
+ break;
default:
pr_err("Default lsm port");
break;
@@ -3233,6 +3320,7 @@ static const struct snd_kcontrol_new ext_ec_ref_mux_ul2 =
SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL2 MUX Mux",
msm_route_ec_ref_rx_enum[0],
msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put);
+
static const struct snd_kcontrol_new ext_ec_ref_mux_ul3 =
SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL3 MUX Mux",
msm_route_ec_ref_rx_enum[0],
@@ -4033,15 +4121,6 @@ static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
-static const struct snd_kcontrol_new mi2s_hl_mixer_controls[] = {
- SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
- MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
- msm_routing_put_port_mixer),
- SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
- MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
- msm_routing_put_port_mixer),
-};
-
static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_PRI_MI2S_RX ,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -7376,6 +7455,9 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX_Voip", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3_Voip", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = {
@@ -7510,6 +7592,9 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = {
SOC_SINGLE_EXT("TERT_MI2S_TX_QCHAT", MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
msm_routing_put_voice_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3_QCHAT", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
};
static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = {
@@ -8854,6 +8939,9 @@ static const struct snd_kcontrol_new sec_mi2s_rx_port_mixer_controls[] = {
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ MSM_BACKEND_DAI_INT_FM_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
SOC_SINGLE_EXT("TERT_MI2S_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
MSM_BACKEND_DAI_TERTIARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
@@ -8896,6 +8984,12 @@ static const struct snd_kcontrol_new lsm1_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm2_mixer_controls[] = {
@@ -8920,6 +9014,12 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm3_mixer_controls[] = {
@@ -8944,6 +9044,12 @@ static const struct snd_kcontrol_new lsm3_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm4_mixer_controls[] = {
@@ -8968,6 +9074,12 @@ static const struct snd_kcontrol_new lsm4_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm5_mixer_controls[] = {
@@ -8992,6 +9104,12 @@ static const struct snd_kcontrol_new lsm5_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm6_mixer_controls[] = {
@@ -9016,6 +9134,12 @@ static const struct snd_kcontrol_new lsm6_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm7_mixer_controls[] = {
@@ -9040,6 +9164,12 @@ static const struct snd_kcontrol_new lsm7_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm8_mixer_controls[] = {
@@ -9064,6 +9194,12 @@ static const struct snd_kcontrol_new lsm8_mixer_controls[] = {
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_2", MSM_BACKEND_DAI_PRI_TDM_TX_2,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
+ SOC_SINGLE_EXT("PRI_TDM_TX_3", MSM_BACKEND_DAI_PRI_TDM_TX_3,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new slim_fm_switch_mixer_controls =
@@ -9158,6 +9294,10 @@ static const struct snd_kcontrol_new lsm_controls[] = {
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
SOC_ENUM_EXT(QUAT_MI2S_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
+ SOC_ENUM_EXT(PRI_TDM_TX_2_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
+ msm_routing_lsm_func_get, msm_routing_lsm_func_put),
+ SOC_ENUM_EXT(PRI_TDM_TX_3_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
+ msm_routing_lsm_func_get, msm_routing_lsm_func_put),
/* kcontrol of lsm_port */
SOC_ENUM_EXT("LSM1 Port", lsm_port_enum,
msm_routing_lsm_port_get,
@@ -9649,6 +9789,9 @@ static int msm_audio_sound_focus_derive_port_id(struct snd_kcontrol *kcontrol,
} else if (!strcmp(kcontrol->id.name + strlen(prefix),
"QUATERNARY_MI2S")) {
*port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+ } else if (!strcmp(kcontrol->id.name + strlen(prefix),
+ "PRIMARY_TDM")) {
+ *port_id = AFE_PORT_ID_PRIMARY_TDM_TX;
} else {
pr_err("%s: mixer ctl name=%s, could not derive valid port id\n",
__func__, kcontrol->id.name);
@@ -9868,6 +10011,21 @@ static const struct snd_kcontrol_new msm_source_tracking_controls[] = {
.info = msm_source_tracking_info,
.get = msm_audio_source_tracking_get,
},
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Sound Focus Audio Tx PRIMARY_TDM",
+ .info = msm_sound_focus_info,
+ .get = msm_audio_sound_focus_get,
+ .put = msm_audio_sound_focus_put,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "Source Tracking Audio Tx PRIMARY_TDM",
+ .info = msm_source_tracking_info,
+ .get = msm_audio_source_tracking_get,
+ },
};
static int spkr_prot_put_vi_lch_port(struct snd_kcontrol *kcontrol,
@@ -10390,6 +10548,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_AIF_IN("SLIMBUS_2_TX", "Slimbus2 Capture", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("QUIN_MI2S_TX", "Quinary MI2S Capture",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SENARY_MI2S_TX", "Senary MI2S Capture",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("INT_BT_SCO_RX", "Internal BT-SCO Playback",
0, 0, 0 , 0),
SND_SOC_DAPM_AIF_IN("INT_BT_SCO_TX", "Internal BT-SCO Capture",
@@ -10631,9 +10791,6 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
SND_SOC_DAPM_MIXER("SEC_MI2S_RX_SD1 Audio Mixer", SND_SOC_NOPM, 0, 0,
secondary_mi2s_rx2_mixer_controls,
ARRAY_SIZE(secondary_mi2s_rx2_mixer_controls)),
- SND_SOC_DAPM_MIXER("SEC_MI2S_RX Port Mixer", SND_SOC_NOPM, 0, 0,
- mi2s_hl_mixer_controls,
- ARRAY_SIZE(mi2s_hl_mixer_controls)),
SND_SOC_DAPM_MIXER("PRI_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
primary_mi2s_rx_mixer_controls,
ARRAY_SIZE(primary_mi2s_rx_mixer_controls)),
@@ -11256,9 +11413,6 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_MI2S_RX_SD1 Audio Mixer", "MultiMedia6", "MM_DL6"},
{"SEC_MI2S_RX_SD1", NULL, "SEC_MI2S_RX_SD1 Audio Mixer"},
- {"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
- {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
-
{"PRI_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -11267,6 +11421,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"PRI_MI2S_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"PRI_MI2S_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
@@ -12087,6 +12242,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"INTERNAL_BT_SCO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"},
{"INTERNAL_BT_SCO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
+ {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"INT_BT_SCO_RX", NULL, "INTERNAL_BT_SCO_RX_Voice Mixer"},
{"AFE_PCM_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"},
@@ -12408,6 +12565,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM1 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM1 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"LSM1 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM1 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM1 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM1_UL_HL", NULL, "LSM1 Mixer"},
{"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -12417,6 +12576,9 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM2 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM2 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"LSM2 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM2 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
+
{"LSM2_UL_HL", NULL, "LSM2 Mixer"},
@@ -12427,6 +12589,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM3 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"LSM3 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM3 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM3 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM3_UL_HL", NULL, "LSM3 Mixer"},
@@ -12437,6 +12601,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM4 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM4 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"LSM4 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM4 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM4 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM4_UL_HL", NULL, "LSM4 Mixer"},
{"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -12446,6 +12612,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM5 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"LSM5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM5 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM5 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM5_UL_HL", NULL, "LSM5 Mixer"},
{"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -12454,6 +12622,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM6 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
{"LSM6 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM6 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM6 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM6 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM6_UL_HL", NULL, "LSM6 Mixer"},
@@ -12463,6 +12633,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM7 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
{"LSM7 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM7 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM7 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM7 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM7_UL_HL", NULL, "LSM7 Mixer"},
@@ -12472,6 +12644,8 @@ static const struct snd_soc_dapm_route intercon[] = {
{"LSM8 Mixer", "SLIMBUS_4_TX", "SLIMBUS_4_TX"},
{"LSM8 Mixer", "SLIMBUS_5_TX", "SLIMBUS_5_TX"},
{"LSM8 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"LSM8 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"},
+ {"LSM8 Mixer", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
{"LSM8_UL_HL", NULL, "LSM8 Mixer"},
@@ -12485,6 +12659,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"},
{"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"},
{"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"},
+ {"QCHAT_Tx Mixer", "PRI_TDM_TX_3_QCHAT", "PRI_TDM_TX_3"},
{"QCHAT_UL", NULL, "QCHAT_Tx Mixer"},
{"INT_FM_RX", NULL, "INTFM_DL_HL"},
@@ -12923,8 +13098,6 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_1_RX Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"SLIMBUS_1_RX Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
{"SLIMBUS_1_RX", NULL, "SLIMBUS_1_RX Mixer"},
- {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
- {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"},
{"AFE_PCM_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"},
{"AFE_PCM_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"},
@@ -12985,6 +13158,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SEC_MI2S_RX Port Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"SEC_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
+ {"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"},
{"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index a47377ab38d3..65cdf43c0f71 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -414,4 +414,8 @@ void msm_pcm_routing_reg_stream_app_type_cfg(int fedai_id, int app_type,
int acdb_dev_id, int sample_rate, int session_type);
int msm_pcm_routing_get_stream_app_type_cfg(int fedai_id, int session_type,
int *app_type, int *acdb_dev_id, int *sample_rate);
+int msm_pcm_routing_send_chmix_cfg(int fe_id, int ip_channel_cnt,
+ int op_channel_cnt, int *ch_wght_coeff,
+ int session_type, bool use_default_chmap,
+ char *channel_map);
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c
index bb995d12f277..4bbd4057299c 100644
--- a/sound/soc/msm/qdsp6v2/q6adm.c
+++ b/sound/soc/msm/qdsp6v2/q6adm.c
@@ -780,18 +780,21 @@ static int adm_populate_channel_weight(u16 *ptr,
* session_type - Passed value, session_type for RX or TX
* ch_mixer - Passed value, ch_mixer for which channel mixer config is needed
* channel_index - Passed value, channel_index for which channel is needed
+ * use_default_chmap - true if default channel map to be used
+ * ch_map - input/output channel map for playback/capture session respectively
*/
int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id,
int session_type,
struct msm_pcm_channel_mixer *ch_mixer,
- int channel_index)
+ int channel_index, bool use_default_chmap,
+ char *ch_map)
{
struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL;
struct adm_param_data_v5 data_v5;
int ret = 0, port_idx, sz = 0, param_size = 0;
u16 *adm_pspd_params;
u16 *ptr;
- int index = 0;
+ int index = 0, i;
pr_debug("%s: port_id = %d\n", __func__, port_id);
port_id = afe_convert_virtual_to_portid(port_id);
@@ -858,84 +861,93 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id,
adm_pspd_params[3] = ch_mixer->input_channels[channel_index];
index = 4;
- if (ch_mixer->output_channel == 1) {
- adm_pspd_params[index] = PCM_CHANNEL_FC;
- } else if (ch_mixer->output_channel == 2) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- } else if (ch_mixer->output_channel == 3) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
- } else if (ch_mixer->output_channel == 4) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 3] = PCM_CHANNEL_RS;
- } else if (ch_mixer->output_channel == 5) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
- adm_pspd_params[index + 3] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 4] = PCM_CHANNEL_RS;
- } else if (ch_mixer->output_channel == 6) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
- adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
- adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
- } else if (ch_mixer->output_channel == 8) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
- adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
- adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
- adm_pspd_params[index + 6] = PCM_CHANNEL_LB;
- adm_pspd_params[index + 7] = PCM_CHANNEL_RB;
- }
-
- index = index + ch_mixer->output_channel;
- if (ch_mixer->input_channels[channel_index] == 1) {
- adm_pspd_params[index] = PCM_CHANNEL_FC;
- } else if (ch_mixer->input_channels[channel_index] == 2) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- } else if (ch_mixer->input_channels[channel_index] == 3) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
- } else if (ch_mixer->input_channels[channel_index] == 4) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 3] = PCM_CHANNEL_RS;
- } else if (ch_mixer->input_channels[channel_index] == 5) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
- adm_pspd_params[index + 3] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 4] = PCM_CHANNEL_RS;
- } else if (ch_mixer->input_channels[channel_index] == 6) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
- adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
- adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
- } else if (ch_mixer->input_channels[channel_index] == 8) {
- adm_pspd_params[index] = PCM_CHANNEL_FL;
- adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
- adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
- adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
- adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
- adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
- adm_pspd_params[index + 6] = PCM_CHANNEL_LB;
- adm_pspd_params[index + 7] = PCM_CHANNEL_RB;
- }
-
- index = index + ch_mixer->input_channels[channel_index];
+ if ((session_type == SESSION_TYPE_TX) && !use_default_chmap && ch_map) {
+ for (i = 0; i < ch_mixer->output_channel; i++)
+ adm_pspd_params[index++] = ch_map[i];
+ } else {
+ if (ch_mixer->output_channel == 1) {
+ adm_pspd_params[index] = PCM_CHANNEL_FC;
+ } else if (ch_mixer->output_channel == 2) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ } else if (ch_mixer->output_channel == 3) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
+ } else if (ch_mixer->output_channel == 4) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_RS;
+ } else if (ch_mixer->output_channel == 5) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 4] = PCM_CHANNEL_RS;
+ } else if (ch_mixer->output_channel == 6) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
+ adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
+ } else if (ch_mixer->output_channel == 8) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
+ adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
+ adm_pspd_params[index + 6] = PCM_CHANNEL_LB;
+ adm_pspd_params[index + 7] = PCM_CHANNEL_RB;
+ }
+ index = index + ch_mixer->output_channel;
+ }
+
+ if ((session_type == SESSION_TYPE_RX) && !use_default_chmap && ch_map) {
+ for (i = 0; i < ch_mixer->input_channels[channel_index]; i++)
+ adm_pspd_params[index++] = ch_map[i];
+ } else {
+ if (ch_mixer->input_channels[channel_index] == 1) {
+ adm_pspd_params[index] = PCM_CHANNEL_FC;
+ } else if (ch_mixer->input_channels[channel_index] == 2) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ } else if (ch_mixer->input_channels[channel_index] == 3) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
+ } else if (ch_mixer->input_channels[channel_index] == 4) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_RS;
+ } else if (ch_mixer->input_channels[channel_index] == 5) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_FC;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 4] = PCM_CHANNEL_RS;
+ } else if (ch_mixer->input_channels[channel_index] == 6) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
+ adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
+ } else if (ch_mixer->input_channels[channel_index] == 8) {
+ adm_pspd_params[index] = PCM_CHANNEL_FL;
+ adm_pspd_params[index + 1] = PCM_CHANNEL_FR;
+ adm_pspd_params[index + 2] = PCM_CHANNEL_LFE;
+ adm_pspd_params[index + 3] = PCM_CHANNEL_FC;
+ adm_pspd_params[index + 4] = PCM_CHANNEL_LS;
+ adm_pspd_params[index + 5] = PCM_CHANNEL_RS;
+ adm_pspd_params[index + 6] = PCM_CHANNEL_LB;
+ adm_pspd_params[index + 7] = PCM_CHANNEL_RB;
+ }
+ index = index + ch_mixer->input_channels[channel_index];
+ }
ret = adm_populate_channel_weight(&adm_pspd_params[index],
ch_mixer, channel_index);
if (ret) {
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index b668c21afae5..efca7bc3ea42 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -135,6 +135,24 @@ static int out_cold_index;
static char *out_buffer;
static char *in_buffer;
+static inline uint32_t q6asm_get_pcm_format_id(uint32_t media_format_block_ver)
+{
+ uint32_t pcm_format_id;
+
+ switch (media_format_block_ver) {
+ case PCM_MEDIA_FORMAT_V4:
+ pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V4;
+ break;
+ case PCM_MEDIA_FORMAT_V3:
+ pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3;
+ break;
+ case PCM_MEDIA_FORMAT_V2:
+ default:
+ pcm_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
+ break;
+ }
+ return pcm_format_id;
+}
static int audio_output_latency_dbgfs_open(struct inode *inode,
struct file *file)
@@ -2343,7 +2361,8 @@ static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr,
static int __q6asm_open_read(struct audio_client *ac,
uint32_t format, uint16_t bits_per_sample,
- bool use_v3_format, bool ts_mode)
+ uint32_t pcm_format_block_ver,
+ bool ts_mode)
{
int rc = 0x00;
struct asm_stream_cmd_open_read_v3 open;
@@ -2383,12 +2402,9 @@ static int __q6asm_open_read(struct audio_client *ac,
switch (format) {
case FORMAT_LINEAR_PCM:
open.mode_flags |= 0x00;
+ open.enc_cfg_id = q6asm_get_pcm_format_id(pcm_format_block_ver);
if (ts_mode)
open.mode_flags |= ABSOLUTE_TIMESTAMP_ENABLE;
- if (use_v3_format)
- open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3;
- else
- open.enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
break;
case FORMAT_MPEG4_AAC:
open.mode_flags |= BUFFER_META_ENABLE;
@@ -2459,14 +2475,16 @@ int q6asm_open_read(struct audio_client *ac,
uint32_t format)
{
return __q6asm_open_read(ac, format, 16,
- false /*use_v3_format*/, false/*ts_mode*/);
+ PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
+ false/*ts_mode*/);
}
int q6asm_open_read_v2(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample)
{
return __q6asm_open_read(ac, format, bits_per_sample,
- false /*use_v3_format*/, false/*ts_mode*/);
+ PCM_MEDIA_FORMAT_V2 /*media fmt block ver*/,
+ false/*ts_mode*/);
}
/*
@@ -2480,7 +2498,8 @@ int q6asm_open_read_v3(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample)
{
return __q6asm_open_read(ac, format, bits_per_sample,
- true /*use_v3_format*/, false/*ts_mode*/);
+ PCM_MEDIA_FORMAT_V3/*media fmt block ver*/,
+ false/*ts_mode*/);
}
EXPORT_SYMBOL(q6asm_open_read_v3);
@@ -2495,7 +2514,8 @@ int q6asm_open_read_v4(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample)
{
return __q6asm_open_read(ac, format, bits_per_sample,
- true /*use_v3_format*/, true/*ts_mode*/);
+ PCM_MEDIA_FORMAT_V4 /*media fmt block ver*/,
+ true/*ts_mode*/);
}
EXPORT_SYMBOL(q6asm_open_read_v4);
@@ -2586,7 +2606,8 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample, uint32_t stream_id,
- bool is_gapless_mode, bool use_v3_format)
+ bool is_gapless_mode,
+ uint32_t pcm_format_block_ver)
{
int rc = 0x00;
struct asm_stream_cmd_open_write_v3 open;
@@ -2654,11 +2675,7 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
}
switch (format) {
case FORMAT_LINEAR_PCM:
- if (use_v3_format)
- open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3;
- else
- open.dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
-
+ open.dec_fmt_id = q6asm_get_pcm_format_id(pcm_format_block_ver);
break;
case FORMAT_MPEG4_AAC:
open.dec_fmt_id = ASM_MEDIA_FMT_AAC_V2;
@@ -2737,7 +2754,7 @@ int q6asm_open_write(struct audio_client *ac, uint32_t format)
{
return __q6asm_open_write(ac, format, 16, ac->stream_id,
false /*gapless*/,
- false /*use_v3_format*/);
+ PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/);
}
int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
@@ -2745,7 +2762,7 @@ int q6asm_open_write_v2(struct audio_client *ac, uint32_t format,
{
return __q6asm_open_write(ac, format, bits_per_sample,
ac->stream_id, false /*gapless*/,
- false /*use_v3_format*/);
+ PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/);
}
/*
@@ -2760,17 +2777,33 @@ int q6asm_open_write_v3(struct audio_client *ac, uint32_t format,
{
return __q6asm_open_write(ac, format, bits_per_sample,
ac->stream_id, false /*gapless*/,
- true /*use_v3_format*/);
+ PCM_MEDIA_FORMAT_V3 /*pcm_format_block_ver*/);
}
EXPORT_SYMBOL(q6asm_open_write_v3);
+/*
+ * q6asm_open_write_v4 - Opens audio playback session
+ *
+ * @ac: Client session handle
+ * @format: decoder format
+ * @bits_per_sample: bit width of playback session
+ */
+int q6asm_open_write_v4(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample)
+{
+ return __q6asm_open_write(ac, format, bits_per_sample,
+ ac->stream_id, false /*gapless*/,
+ PCM_MEDIA_FORMAT_V4 /*pcm_format_block_ver*/);
+}
+EXPORT_SYMBOL(q6asm_open_write_v4);
+
int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
uint16_t bits_per_sample, int32_t stream_id,
bool is_gapless_mode)
{
return __q6asm_open_write(ac, format, bits_per_sample,
stream_id, is_gapless_mode,
- false /*use_v3_format*/);
+ PCM_MEDIA_FORMAT_V2 /*pcm_format_block_ver*/);
}
/*
@@ -2788,10 +2821,29 @@ int q6asm_stream_open_write_v3(struct audio_client *ac, uint32_t format,
{
return __q6asm_open_write(ac, format, bits_per_sample,
stream_id, is_gapless_mode,
- true /*use_v3_format*/);
+ PCM_MEDIA_FORMAT_V3 /*pcm_format_block_ver*/);
}
EXPORT_SYMBOL(q6asm_stream_open_write_v3);
+/*
+ * q6asm_stream_open_write_v4 - Creates audio stream for playback
+ *
+ * @ac: Client session handle
+ * @format: asm playback format
+ * @bits_per_sample: bit width of requested stream
+ * @stream_id: stream id of stream to be associated with this session
+ * @is_gapless_mode: true if gapless mode needs to be enabled
+ */
+int q6asm_stream_open_write_v4(struct audio_client *ac, uint32_t format,
+ uint16_t bits_per_sample, int32_t stream_id,
+ bool is_gapless_mode)
+{
+ return __q6asm_open_write(ac, format, bits_per_sample,
+ stream_id, is_gapless_mode,
+ PCM_MEDIA_FORMAT_V4 /*pcm_format_block_ver*/);
+}
+EXPORT_SYMBOL(q6asm_stream_open_write_v4);
+
static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format,
uint32_t wr_format, bool is_meta_data_mode,
uint32_t bits_per_sample,
@@ -3718,6 +3770,108 @@ int q6asm_set_encdec_chan_map(struct audio_client *ac,
return rc;
}
+/*
+ * q6asm_enc_cfg_blk_pcm_v4 - sends encoder configuration parameters
+ *
+ * @ac: Client session handle
+ * @rate: sample rate
+ * @channels: number of channels
+ * @bits_per_sample: bit width of encoder session
+ * @use_default_chmap: true if default channel map to be used
+ * @use_back_flavor: to configure back left and right channel
+ * @channel_map: input channel map
+ * @sample_word_size: Size in bits of the word that holds a sample of a channel
+ * @endianness: endianness of the pcm data
+ * @mode: Mode to provide additional info about the pcm input data
+ */
+int q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ uint16_t bits_per_sample, bool use_default_chmap,
+ bool use_back_flavor, u8 *channel_map,
+ uint16_t sample_word_size, uint16_t endianness,
+ uint16_t mode)
+{
+ struct asm_multi_channel_pcm_enc_cfg_v4 enc_cfg;
+ struct asm_enc_cfg_blk_param_v2 enc_fg_blk;
+ u8 *channel_mapping;
+ u32 frames_per_buf = 0;
+ int rc;
+
+ if (!use_default_chmap && (channel_map == NULL)) {
+ pr_err("%s: No valid chan map and can't use default\n",
+ __func__);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+
+ pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
+ ac->session, rate, channels,
+ bits_per_sample, sample_word_size);
+
+ memset(&enc_cfg, 0, sizeof(enc_cfg));
+ q6asm_add_hdr(ac, &enc_cfg.hdr, sizeof(enc_cfg), TRUE);
+ atomic_set(&ac->cmd_state, -1);
+ enc_cfg.hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
+ enc_cfg.encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
+ enc_cfg.encdec.param_size = sizeof(enc_cfg) - sizeof(enc_cfg.hdr) -
+ sizeof(enc_cfg.encdec);
+ enc_cfg.encblk.frames_per_buf = frames_per_buf;
+ enc_cfg.encblk.enc_cfg_blk_size = enc_cfg.encdec.param_size -
+ sizeof(enc_fg_blk);
+ enc_cfg.num_channels = channels;
+ enc_cfg.bits_per_sample = bits_per_sample;
+ enc_cfg.sample_rate = rate;
+ enc_cfg.is_signed = 1;
+ enc_cfg.sample_word_size = sample_word_size;
+ enc_cfg.endianness = endianness;
+ enc_cfg.mode = mode;
+ channel_mapping = enc_cfg.channel_mapping;
+
+ memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+ if (use_default_chmap) {
+ pr_debug("%s: setting default channel map for %d channels",
+ __func__, channels);
+ if (q6asm_map_channels(channel_mapping, channels,
+ use_back_flavor)) {
+ pr_err("%s: map channels failed %d\n",
+ __func__, channels);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ } else {
+ pr_debug("%s: Using pre-defined channel map", __func__);
+ memcpy(channel_mapping, channel_map,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
+ }
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
+ if (rc < 0) {
+ pr_err("%s: Command open failed %d\n", __func__, rc);
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout opcode[0x%x]\n",
+ __func__, enc_cfg.hdr.opcode);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto fail_cmd;
+ }
+ return 0;
+fail_cmd:
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_v4);
+
/*
* q6asm_enc_cfg_blk_pcm_v3 - sends encoder configuration parameters
*
@@ -3894,6 +4048,18 @@ int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
return rc;
}
+static int __q6asm_enc_cfg_blk_pcm_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ uint16_t bits_per_sample,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode)
+{
+ return q6asm_enc_cfg_blk_pcm_v4(ac, rate, channels,
+ bits_per_sample, true, false, NULL,
+ sample_word_size, endianness, mode);
+}
+
static int __q6asm_enc_cfg_blk_pcm_v3(struct audio_client *ac,
uint32_t rate, uint32_t channels,
uint16_t bits_per_sample,
@@ -3943,6 +4109,31 @@ int q6asm_enc_cfg_blk_pcm_format_support_v3(struct audio_client *ac,
}
EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v3);
+/*
+ * q6asm_enc_cfg_blk_pcm_format_support_v4 - sends encoder configuration
+ * parameters
+ *
+ * @ac: Client session handle
+ * @rate: sample rate
+ * @channels: number of channels
+ * @bits_per_sample: bit width of encoder session
+ * @sample_word_size: Size in bits of the word that holds a sample of a channel
+ * @endianness: endianness of the pcm data
+ * @mode: Mode to provide additional info about the pcm input data
+ */
+int q6asm_enc_cfg_blk_pcm_format_support_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ uint16_t bits_per_sample,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode)
+{
+ return __q6asm_enc_cfg_blk_pcm_v4(ac, rate, channels,
+ bits_per_sample, sample_word_size,
+ endianness, mode);
+}
+EXPORT_SYMBOL(q6asm_enc_cfg_blk_pcm_format_support_v4);
+
int q6asm_enc_cfg_blk_pcm_native(struct audio_client *ac,
uint32_t rate, uint32_t channels)
{
@@ -4585,6 +4776,91 @@ static int __q6asm_media_format_block_pcm_v3(struct audio_client *ac,
return rc;
}
+static int __q6asm_media_format_block_pcm_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ uint16_t bits_per_sample,
+ int stream_id,
+ bool use_default_chmap,
+ char *channel_map,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode)
+{
+ struct asm_multi_channel_pcm_fmt_blk_param_v4 fmt;
+ u8 *channel_mapping;
+ int rc;
+
+ pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
+ ac->session, rate, channels,
+ bits_per_sample, sample_word_size);
+
+ memset(&fmt, 0, sizeof(fmt));
+ q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id);
+ atomic_set(&ac->cmd_state, -1);
+ /*
+ * Updated the token field with stream/session for compressed playback
+ * Platform driver must know the the stream with which the command is
+ * associated
+ */
+ if (ac->io_mode & COMPRESSED_STREAM_IO)
+ fmt.hdr.token = ((ac->session << 8) & 0xFFFF00) |
+ (stream_id & 0xFF);
+
+ pr_debug("%s: token = 0x%x, stream_id %d, session 0x%x\n",
+ __func__, fmt.hdr.token, stream_id, ac->session);
+
+ fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+ fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
+ sizeof(fmt.fmt_blk);
+ fmt.param.num_channels = channels;
+ fmt.param.bits_per_sample = bits_per_sample;
+ fmt.param.sample_rate = rate;
+ fmt.param.is_signed = 1;
+ fmt.param.sample_word_size = sample_word_size;
+ fmt.param.endianness = endianness;
+ fmt.param.mode = mode;
+ channel_mapping = fmt.param.channel_mapping;
+
+ memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+ if (use_default_chmap) {
+ if (q6asm_map_channels(channel_mapping, channels, false)) {
+ pr_err("%s: map channels failed %d\n",
+ __func__, channels);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ } else {
+ memcpy(channel_mapping, channel_map,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
+ }
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+ if (rc < 0) {
+ pr_err("%s: Comamnd open failed %d\n", __func__, rc);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout. waited for format update\n", __func__);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto fail_cmd;
+ }
+ return 0;
+fail_cmd:
+ return rc;
+}
+
int q6asm_media_format_block_pcm(struct audio_client *ac,
uint32_t rate, uint32_t channels)
{
@@ -4652,6 +4928,47 @@ int q6asm_media_format_block_pcm_format_support_v3(struct audio_client *ac,
}
EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v3);
+/*
+ * q6asm_media_format_block_pcm_format_support_v4- sends pcm decoder
+ * configuration parameters
+ *
+ * @ac: Client session handle
+ * @rate: sample rate
+ * @channels: number of channels
+ * @bits_per_sample: bit width of encoder session
+ * @stream_id: stream id of stream to be associated with this session
+ * @use_default_chmap: true if default channel map to be used
+ * @channel_map: input channel map
+ * @sample_word_size: Size in bits of the word that holds a sample of a channel
+ * @endianness: endianness of the pcm data
+ * @mode: Mode to provide additional info about the pcm input data
+ */
+int q6asm_media_format_block_pcm_format_support_v4(struct audio_client *ac,
+ uint32_t rate,
+ uint32_t channels,
+ uint16_t bits_per_sample,
+ int stream_id,
+ bool use_default_chmap,
+ char *channel_map,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode)
+{
+ if (!use_default_chmap && (channel_map == NULL)) {
+ pr_err("%s: No valid chan map and can't use default\n",
+ __func__);
+ return -EINVAL;
+ }
+ return __q6asm_media_format_block_pcm_v4(ac, rate,
+ channels, bits_per_sample, stream_id,
+ use_default_chmap, channel_map,
+ sample_word_size, endianness,
+ mode);
+
+}
+EXPORT_SYMBOL(q6asm_media_format_block_pcm_format_support_v4);
+
+
static int __q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
uint32_t rate, uint32_t channels,
bool use_default_chmap, char *channel_map,
@@ -4785,6 +5102,78 @@ static int __q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
return rc;
}
+static int __q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
+ uint32_t rate,
+ uint32_t channels,
+ bool use_default_chmap,
+ char *channel_map,
+ uint16_t bits_per_sample,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode)
+{
+ struct asm_multi_channel_pcm_fmt_blk_param_v4 fmt;
+ u8 *channel_mapping;
+ int rc;
+
+ pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]wordsize[%d]\n", __func__,
+ ac->session, rate, channels,
+ bits_per_sample, sample_word_size);
+
+ memset(&fmt, 0, sizeof(fmt));
+ q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
+ atomic_set(&ac->cmd_state, -1);
+
+ fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+ fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
+ sizeof(fmt.fmt_blk);
+ fmt.param.num_channels = channels;
+ fmt.param.bits_per_sample = bits_per_sample;
+ fmt.param.sample_rate = rate;
+ fmt.param.is_signed = 1;
+ fmt.param.sample_word_size = sample_word_size;
+ fmt.param.endianness = endianness;
+ fmt.param.mode = mode;
+ channel_mapping = fmt.param.channel_mapping;
+
+ memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+ if (use_default_chmap) {
+ if (q6asm_map_channels(channel_mapping, channels, false)) {
+ pr_err("%s: map channels failed %d\n",
+ __func__, channels);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ } else {
+ memcpy(channel_mapping, channel_map,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
+ }
+
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+ if (rc < 0) {
+ pr_err("%s: Comamnd open failed %d\n", __func__, rc);
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout. waited for format update\n", __func__);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto fail_cmd;
+ }
+ return 0;
+fail_cmd:
+ return rc;
+}
int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
uint32_t rate, uint32_t channels,
@@ -4832,6 +5221,39 @@ int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
}
EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v3);
+/*
+ * q6asm_media_format_block_multi_ch_pcm_v4 - sends pcm decoder configuration
+ * parameters
+ *
+ * @ac: Client session handle
+ * @rate: sample rate
+ * @channels: number of channels
+ * @bits_per_sample: bit width of encoder session
+ * @use_default_chmap: true if default channel map to be used
+ * @channel_map: input channel map
+ * @sample_word_size: Size in bits of the word that holds a sample of a channel
+ * @endianness: endianness of the pcm data
+ * @mode: Mode to provide additional info about the pcm input data
+ */
+int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ bool use_default_chmap,
+ char *channel_map,
+ uint16_t bits_per_sample,
+ uint16_t sample_word_size,
+ uint16_t endianness,
+ uint16_t mode)
+{
+ return __q6asm_media_format_block_multi_ch_pcm_v4(ac, rate, channels,
+ use_default_chmap,
+ channel_map,
+ bits_per_sample,
+ sample_word_size,
+ endianness,
+ mode);
+}
+EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v4);
+
static int __q6asm_media_format_block_multi_aac(struct audio_client *ac,
struct asm_aac_cfg *cfg, int stream_id)
{
diff --git a/sound/soc/msm/qdsp6v2/q6core.c b/sound/soc/msm/qdsp6v2/q6core.c
index 3fbf251c310c..71a65c63ca5f 100644
--- a/sound/soc/msm/qdsp6v2/q6core.c
+++ b/sound/soc/msm/qdsp6v2/q6core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -57,7 +57,8 @@ struct q6core_str {
u32 bus_bw_resp_received;
enum cmd_flags {
FLAG_NONE,
- FLAG_CMDRSP_LICENSE_RESULT
+ FLAG_CMDRSP_LICENSE_RESULT,
+ FLAG_AVCS_GET_VERSIONS_RESULT,
} cmd_resp_received_flag;
u32 avcs_fwk_ver_resp_received;
struct mutex cmd_lock;
@@ -71,6 +72,7 @@ struct q6core_str {
uint32_t mem_map_cal_handle;
int32_t adsp_status;
struct q6core_avcs_ver_info q6core_avcs_ver_info;
+ u32 q6_core_avs_version;
};
static struct q6core_str q6core_lcl;
@@ -180,7 +182,33 @@ static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
q6core_lcl.bus_bw_resp_received = 1;
wake_up(&q6core_lcl.bus_bw_req_wait);
break;
- case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT:
+ case AVCS_GET_VERSIONS_RSP:
+ payload1 = data->payload;
+ pr_debug("%s: Received ADSP version response[3]0x%x\n",
+ __func__, payload1[3]);
+ q6core_lcl.cmd_resp_received_flag =
+ FLAG_AVCS_GET_VERSIONS_RESULT;
+ if (AVCS_CMDRSP_Q6_ID_2_6 == payload1[3]) {
+ q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_6;
+ pr_debug("%s: Received ADSP version as 2.6\n",
+ __func__);
+ } else if (AVCS_CMDRSP_Q6_ID_2_7 == payload1[3]) {
+ q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_7;
+ pr_debug("%s: Received ADSP version as 2.7\n",
+ __func__);
+ } else if (AVCS_CMDRSP_Q6_ID_2_8 == payload1[3]) {
+ q6core_lcl.q6_core_avs_version = Q6_SUBSYS_AVS2_8;
+ pr_info("%s: Received ADSP version as 2.8\n",
+ __func__);
+ } else {
+ pr_err("%s: ADSP version is neither 2.6 nor 2.7\n",
+ __func__);
+ q6core_lcl.q6_core_avs_version = Q6_SUBSYS_INVALID;
+ }
+ wake_up(&q6core_lcl.cmd_req_wait);
+ break;
+
+ case AVCS_CMDRSP_GET_LICENSE_VALIDATION_RESULT:
payload1 = data->payload;
pr_debug("%s: cmd = LICENSE_VALIDATION_RESULT, result = 0x%x\n",
__func__, payload1[0]);
@@ -421,6 +449,65 @@ int32_t core_set_license(uint32_t key, uint32_t module_id)
return rc;
}
+int core_get_adsp_ver(void)
+{
+ struct avcs_cmd_get_version_result get_aver_cmd;
+ int ret = 0;
+
+ mutex_lock(&(q6core_lcl.cmd_lock));
+ ocm_core_open();
+ if (q6core_lcl.core_handle_q == NULL) {
+ pr_err("%s: apr registration for CORE failed\n", __func__);
+ ret = -ENODEV;
+ goto fail_cmd;
+ }
+
+ get_aver_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ get_aver_cmd.hdr.pkt_size = sizeof(get_aver_cmd);
+ get_aver_cmd.hdr.src_port = 0;
+ get_aver_cmd.hdr.dest_port = 0;
+ get_aver_cmd.hdr.token = 0;
+ get_aver_cmd.hdr.opcode = AVCS_GET_VERSIONS;
+
+ ret = apr_send_pkt(q6core_lcl.core_handle_q,
+ (uint32_t *) &get_aver_cmd);
+ if (ret < 0) {
+ pr_err("%s: Core get DSP version request failed, err %d\n",
+ __func__, ret);
+ ret = -EREMOTE;
+ goto fail_cmd;
+ }
+
+ q6core_lcl.cmd_resp_received_flag &= ~(FLAG_AVCS_GET_VERSIONS_RESULT);
+ mutex_unlock(&(q6core_lcl.cmd_lock));
+ ret = wait_event_timeout(q6core_lcl.cmd_req_wait,
+ (q6core_lcl.cmd_resp_received_flag ==
+ FLAG_AVCS_GET_VERSIONS_RESULT),
+ msecs_to_jiffies(TIMEOUT_MS));
+ mutex_lock(&(q6core_lcl.cmd_lock));
+ if (!ret) {
+ pr_err("%s: wait_event timeout for AVCS_GET_VERSIONS_RESULT\n",
+ __func__);
+ ret = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+ q6core_lcl.cmd_resp_received_flag &= ~(FLAG_AVCS_GET_VERSIONS_RESULT);
+
+fail_cmd:
+ if (ret < 0)
+ q6core_lcl.q6_core_avs_version = Q6_SUBSYS_INVALID;
+ mutex_unlock(&(q6core_lcl.cmd_lock));
+ return ret;
+}
+
+enum q6_subsys_image q6core_get_avs_version(void)
+{
+ if (q6core_lcl.q6_core_avs_version == 0)
+ core_get_adsp_ver();
+ return q6core_lcl.q6_core_avs_version;
+}
+
int32_t core_get_license_status(uint32_t module_id)
{
struct avcs_cmd_get_license_validation_result get_lvr_cmd;
diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c
index 9b5e72f94d1b..11c46335993e 100644
--- a/sound/soc/msm/qdsp6v2/rtac.c
+++ b/sound/soc/msm/qdsp6v2/rtac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -127,6 +127,11 @@ struct mutex rtac_voice_mutex;
struct mutex rtac_voice_apr_mutex;
struct mutex rtac_afe_apr_mutex;
+static struct mutex rtac_asm_cal_mutex;
+static struct mutex rtac_adm_cal_mutex;
+static struct mutex rtac_afe_cal_mutex;
+static struct mutex rtac_voice_cal_mutex;
+
int rtac_clear_mapping(uint32_t cal_type)
{
int result = 0;
@@ -1693,42 +1698,62 @@ static long rtac_ioctl_shared(struct file *f,
}
case AUDIO_GET_RTAC_ADM_CAL:
+ mutex_lock(&rtac_adm_cal_mutex);
result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
+ mutex_unlock(&rtac_adm_cal_mutex);
break;
case AUDIO_SET_RTAC_ADM_CAL:
+ mutex_lock(&rtac_adm_cal_mutex);
result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
+ mutex_unlock(&rtac_adm_cal_mutex);
break;
case AUDIO_GET_RTAC_ASM_CAL:
+ mutex_lock(&rtac_asm_cal_mutex);
result = send_rtac_asm_apr((void *)arg,
ASM_STREAM_CMD_GET_PP_PARAMS_V2);
+ mutex_unlock(&rtac_asm_cal_mutex);
break;
case AUDIO_SET_RTAC_ASM_CAL:
+ mutex_lock(&rtac_asm_cal_mutex);
result = send_rtac_asm_apr((void *)arg,
ASM_STREAM_CMD_SET_PP_PARAMS_V2);
+ mutex_unlock(&rtac_asm_cal_mutex);
break;
case AUDIO_GET_RTAC_CVS_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVS, (void *)arg,
VOICE_CMD_GET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_SET_RTAC_CVS_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVS, (void *)arg,
VOICE_CMD_SET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_GET_RTAC_CVP_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVP, (void *)arg,
VOICE_CMD_GET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_SET_RTAC_CVP_CAL:
+ mutex_lock(&rtac_voice_cal_mutex);
result = send_voice_apr(RTAC_CVP, (void *)arg,
VOICE_CMD_SET_PARAM);
+ mutex_unlock(&rtac_voice_cal_mutex);
break;
case AUDIO_GET_RTAC_AFE_CAL:
+ mutex_lock(&rtac_afe_cal_mutex);
result = send_rtac_afe_apr((void *)arg,
AFE_PORT_CMD_GET_PARAM_V2);
+ mutex_unlock(&rtac_afe_cal_mutex);
break;
case AUDIO_SET_RTAC_AFE_CAL:
+ mutex_lock(&rtac_afe_cal_mutex);
result = send_rtac_afe_apr((void *)arg,
AFE_PORT_CMD_SET_PARAM_V2);
+ mutex_unlock(&rtac_afe_cal_mutex);
break;
default:
pr_err("%s: Invalid IOCTL, command = %d!\n",
@@ -1860,6 +1885,7 @@ static int __init rtac_init(void)
init_waitqueue_head(&rtac_adm_apr_data.cmd_wait);
mutex_init(&rtac_adm_mutex);
mutex_init(&rtac_adm_apr_mutex);
+ mutex_init(&rtac_adm_cal_mutex);
rtac_adm_buffer = kzalloc(
rtac_cal[ADM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
@@ -1876,6 +1902,7 @@ static int __init rtac_init(void)
init_waitqueue_head(&rtac_asm_apr_data[i].cmd_wait);
}
mutex_init(&rtac_asm_apr_mutex);
+ mutex_init(&rtac_asm_cal_mutex);
rtac_asm_buffer = kzalloc(
rtac_cal[ASM_RTAC_CAL].map_data.map_size, GFP_KERNEL);
@@ -1891,6 +1918,7 @@ static int __init rtac_init(void)
atomic_set(&rtac_afe_apr_data.cmd_state, 0);
init_waitqueue_head(&rtac_afe_apr_data.cmd_wait);
mutex_init(&rtac_afe_apr_mutex);
+ mutex_init(&rtac_afe_cal_mutex);
rtac_afe_buffer = kzalloc(
rtac_cal[AFE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
@@ -1911,6 +1939,7 @@ static int __init rtac_init(void)
}
mutex_init(&rtac_voice_mutex);
mutex_init(&rtac_voice_apr_mutex);
+ mutex_init(&rtac_voice_cal_mutex);
rtac_voice_buffer = kzalloc(
rtac_cal[VOICE_RTAC_CAL].map_data.map_size, GFP_KERNEL);
diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c
index 186dc7f33a55..cdb7416a91ff 100644
--- a/sound/soc/sirf/sirf-usp.c
+++ b/sound/soc/sirf/sirf-usp.c
@@ -367,10 +367,9 @@ static int sirf_usp_pcm_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, usp);
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- base = devm_ioremap(&pdev->dev, mem_res->start,
- resource_size(mem_res));
- if (base == NULL)
- return -ENOMEM;
+ base = devm_ioremap_resource(&pdev->dev, mem_res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
usp->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&sirf_usp_regmap_config);
if (IS_ERR(usp->regmap))
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index e871ffb069ce..c09ee574e8a1 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1715,8 +1715,10 @@ int dpcm_be_dai_shutdown(struct snd_soc_pcm_runtime *fe, int stream)
continue;
if ((be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
- (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN))
- continue;
+ (be->dpcm[stream].state != SND_SOC_DPCM_STATE_OPEN)) {
+ soc_pcm_hw_free(be_substream);
+ be->dpcm[stream].state = SND_SOC_DPCM_STATE_HW_FREE;
+ }
dev_dbg(be->dev, "ASoC: close BE %s\n",
dpcm->fe->dai_link->name);
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index e8822542b257..52af32177bf4 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -1263,7 +1263,7 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
if (bytes % (runtime->sample_bits >> 3) != 0) {
int oldbytes = bytes;
bytes = frames * stride;
- dev_warn(&subs->dev->dev,
+ dev_warn_ratelimited(&subs->dev->dev,
"Corrected urb data len. %d->%d\n",
oldbytes, bytes);
}
diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
index d73ef8bb08c7..8e24f39f9158 100644
--- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c
+++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c
@@ -230,7 +230,7 @@ int arch_skip_callchain_idx(struct machine *machine, struct thread *thread,
u64 ip;
u64 skip_slot = -1;
- if (chain->nr < 3)
+ if (!chain || chain->nr < 3)
return skip_slot;
ip = chain->ips[2];
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 5b1b807265a1..f771e09eef33 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -605,9 +605,7 @@ void format_all_counters(struct thread_data *t, struct core_data *c, struct pkg_
if (!printed || !summary_only)
print_header();
- if (topo.num_cpus > 1)
- format_counters(&average.threads, &average.cores,
- &average.packages);
+ format_counters(&average.threads, &average.cores, &average.packages);
printed = 1;
@@ -2011,7 +2009,9 @@ void check_cpuid()
family = (fms >> 8) & 0xf;
model = (fms >> 4) & 0xf;
stepping = fms & 0xf;
- if (family == 6 || family == 0xf)
+ if (family == 0xf)
+ family += (fms >> 20) & 0xff;
+ if (family >= 6)
model += ((fms >> 16) & 0xf) << 4;
if (verbose)
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/snapshot.tc b/tools/testing/selftests/ftrace/test.d/00basic/snapshot.tc
new file mode 100644
index 000000000000..3b1f45e13a2e
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/00basic/snapshot.tc
@@ -0,0 +1,28 @@
+#!/bin/sh
+# description: Snapshot and tracing setting
+# flags: instance
+
+[ ! -f snapshot ] && exit_unsupported
+
+echo "Set tracing off"
+echo 0 > tracing_on
+
+echo "Allocate and take a snapshot"
+echo 1 > snapshot
+
+# Since trace buffer is empty, snapshot is also empty, but allocated
+grep -q "Snapshot is allocated" snapshot
+
+echo "Ensure keep tracing off"
+test `cat tracing_on` -eq 0
+
+echo "Set tracing on"
+echo 1 > tracing_on
+
+echo "Take a snapshot again"
+echo 1 > snapshot
+
+echo "Ensure keep tracing on"
+test `cat tracing_on` -eq 1
+
+exit 0
diff --git a/tools/testing/selftests/sync/config b/tools/testing/selftests/sync/config
new file mode 100644
index 000000000000..1ab7e8130db2
--- /dev/null
+++ b/tools/testing/selftests/sync/config
@@ -0,0 +1,4 @@
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_SYNC=y
+CONFIG_SW_SYNC=y
diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c
index 88d5e71be044..47dfa0b0fcd7 100644
--- a/tools/usb/ffs-test.c
+++ b/tools/usb/ffs-test.c
@@ -44,12 +44,25 @@
/******************** Little Endian Handling ********************************/
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
+/*
+ * cpu_to_le16/32 are used when initializing structures, a context where a
+ * function call is not allowed. To solve this, we code cpu_to_le16/32 in a way
+ * that allows them to be used when initializing structures.
+ */
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le16(x) (x)
+#define cpu_to_le32(x) (x)
+#else
+#define cpu_to_le16(x) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))
+#define cpu_to_le32(x) \
+ ((((x) & 0xff000000u) >> 24) | (((x) & 0x00ff0000u) >> 8) | \
+ (((x) & 0x0000ff00u) << 8) | (((x) & 0x000000ffu) << 24))
+#endif
+
#define le32_to_cpu(x) le32toh(x)
#define le16_to_cpu(x) le16toh(x)
-
/******************** Messages and Errors ***********************************/
static const char argv0[] = "ffs-test";
diff --git a/tools/usb/usbip/src/usbip_detach.c b/tools/usb/usbip/src/usbip_detach.c
index 05c6d15856eb..b4356ed875e5 100644
--- a/tools/usb/usbip/src/usbip_detach.c
+++ b/tools/usb/usbip/src/usbip_detach.c
@@ -43,7 +43,7 @@ void usbip_detach_usage(void)
static int detach_port(char *port)
{
- int ret;
+ int ret = 0;
uint8_t portnum;
char path[PATH_MAX+1];
@@ -71,9 +71,12 @@ static int detach_port(char *port)
}
ret = usbip_vhci_detach_device(portnum);
- if (ret < 0)
- return -1;
+ if (ret < 0) {
+ ret = -1;
+ goto call_driver_close;
+ }
+call_driver_close:
usbip_vhci_driver_close();
return ret;