Promotion of kernel.lnx.4.4-161103.

CRs      Change ID                                   Subject
--------------------------------------------------------------------------------------------------------------
1084491   Ia9350b9c7810db7eb900957b4ce5dac046ab5e0d   ARM: dts: msm: Add qcom,dump-size entry for dumping CPU
1084491   I37ca3aae0471fcd60499615df77093d5b5451bf8   Documentation: arm: add cache DT bindings
1078910   I9cb454cebb74df291479cecc3533d2c684363f77   ion: disable system contig heap
1077179   I5bc6a5a46311206818d70567e31fd84adc0128be   leds: qpnp-flash-v2: Fix strobe control settings
1077868   Id568f76e03b93cf411366abf01ea857fb80ff1bf   ARM: dts: msm: correct cpu nodes information for msmtrit
1083761   Ib38ecabb3c4bf40fcf5ad368fbbdbe4c44edbf3b   msm: vidc: Scale bus bw along with venus clocks
1084236   I4c13601b0fded6de9d8f897c6d471c6a40c90e4d   sched/hmp: Automatically add children threads to colocat
1070067   I0d4b9f72a12e91b16f3844ac70db33b7de5e5263   usb_bam: Avoid uninitialized variable errors
1080024   I92bd53432a11241228d2e5ac89a3b20d19b05a31   CHROMIUM: dm: boot time specification of dm=
1049826   I3e11ca7f6df4bb0d928512f81f3e3dc40fed791a   msm: camera: cpp: Validate frame message before manipula
1080024   I952d86fd1475f0825f9be1386e3497b36127abd0   ANDROID: dm: Rebase on top of 4.1
1082476 1750919   I3a79950b76c1c38e487471f21dc60590b032dd3f   msm: vidc: Correct debugfs directory name
1080024   I4ba1043965d25ec444a833283392ac2394c845f3   Revert "init: do_mounts: Add a dummy definition for dm_t
1084009   Ie1a5038458b0b93dfec3e5bfc350686eb1f8eb1b   ASoC: wcd934x: Initialize mbhc pointer before access
1080688   Ia60fc3ecb5c2aba19effe1c8242f2d89fdef3ebd   ARM: dts: msm: specify SPI configuration for msmfalcon.
1083524   Ic26fa36bf84bce020ad07ad87de50e684dd7fa5a   ARM: dts: msm: Add initial support for msmcobalt V2 QRD
1075835 1075868   I06426109ab39d33e2b11514082c0bc989c4c8167   coresight: tmc: avoid null pointer dereference
1072541   If2b3e241076a4e0eeb87eeb4361398313fca6962   dwc3: gadget: Remove disabling events and ep0 from gadge
1081711   Iee908c56ec530569b35dafa060139e0428efc781   soc: qcom: scm: add check to avoid buffer overflow
1025311   Ie432af1fefc79f88ec67d212f8b9880355c4266d   cfg80211: support virtual interfaces with different beac
1043802   I3eb92f83b42b0fa28dc73f6e0d4f74ef50375855   ARM: dts: msm: add support for QBT1000 on msmcobalt
1082843   I6ab3992958a659995b7d5020287fd6e47e28f2a4   clk: msm: clock-debug: Print VDD level in clock_state tr
1082816   I475d1219ae62378a90c69642f2320149d0f13885   ASoc: wcd934x: correct MAD micbias setting
967547   I92b10e62be8129ead5859a285bf964ab0a3ae2fd   driver core: fix race between creating/querying glue dir
1084935   I31e8e0b5e9ae240ca031f625cf7c49f1bfe165d4   msm: secure_buffer: fix scm call argument layout
1074738   Ie7f8cee59b90f16f8a844d618a6f903b3e3c2f27   msm: mdss: lock mutex before setting backlight

Change-Id: Id13d60a1768a89563fa5209fc5fe3abfc2ea7bb0
CRs-Fixed: 1077179, 1075868, 1082476, 1083761, 1081711, 1043802, 1084935, 1049826, 1070067, 1082816, 1025311, 1074738, 1083524, 1075835, 1080024, 1750919, 1072541, 1084491, 1084009, 1077868, 967547, 1084236, 1080688, 1078910, 1082843
This commit is contained in:
Linux Build Service Account 2016-11-03 04:18:23 -06:00
commit 28f64cb2a6
45 changed files with 1553 additions and 206 deletions

View file

@ -0,0 +1,42 @@
Boot time creation of mapped devices
===================================
It is possible to configure a device mapper device to act as the root
device for your system in two ways.
The first is to build an initial ramdisk which boots to a minimal
userspace which configures the device, then pivot_root(8) in to it.
For simple device mapper configurations, it is possible to boot directly
using the following kernel command line:
dm="<name> <uuid> <ro>,table line 1,...,table line n"
name = the name to associate with the device
after boot, udev, if used, will use that name to label
the device node.
uuid = may be 'none' or the UUID desired for the device.
ro = may be "ro" or "rw". If "ro", the device and device table will be
marked read-only.
Each table line may be as normal when using the dmsetup tool except for
two variations:
1. Any use of commas will be interpreted as a newline
2. Quotation marks cannot be escaped and cannot be used without
terminating the dm= argument.
Unless renamed by udev, the device node created will be dm-0 as the
first minor number for the device-mapper is used during early creation.
Example
=======
- Booting to a linear array made up of user-mode linux block devices:
dm="lroot none 0, 0 4096 linear 98:16 0, 4096 4096 linear 98:32 0" \
root=/dev/dm-0
Will boot to a rw dm-linear target of 8192 sectors split across two
block devices identified by their major:minor numbers. After boot, udev
will rename this target to /dev/mapper/lroot (depending on the rules).
No uuid was assigned.

View file

@ -0,0 +1,195 @@
==========================================
ARM processors cache binding description
==========================================
Device tree bindings for ARM processor caches adhere to the cache bindings
described in [3], in section 3.8 for multi-level and shared caches.
On ARM based systems most of the cache properties related to cache
geometry are probeable in HW, hence, unless otherwise stated, the properties
defined in ePAPR for multi-level and shared caches are to be considered
optional by default.
On ARM, caches are either architected (directly controlled by the processor
through coprocessor instructions and tightly coupled with the processor
implementation) or unarchitected (controlled through a memory mapped
interface, implemented as a stand-alone IP external to the processor
implementation).
This document provides the device tree bindings for ARM architected caches.
- ARM architected cache node
Description: must be a direct child of the cpu node. A system
can contain multiple architected cache nodes per cpu node,
linked through the next-level-cache phandle. The
next-level-cache property in the cpu node points to
the first level of architected cache for the CPU.
The next-level-cache property in architected cache nodes
points to the respective next level of caching in the
hierarchy. An architected cache node with an empty or
missing next-level-cache property represents the last
architected cache level for the CPU.
On ARM v7 and v8 architectures, the order in which cache
nodes are linked through the next-level-cache phandle must
follow the ordering specified in the processors CLIDR (v7)
and CLIDR_EL1 (v8) registers, as described in [1][2],
implying that a cache node pointed at by a
next-level-cache phandle must correspond to a level
defined in CLIDR (v7) and CLIDR_EL1 (v8) greater than the
one the cache node containing the next-level-cache
phandle corresponds to.
Since on ARM most of the cache properties are probeable in HW the
properties described in [3] - section 3.8 multi-level and shared
caches - shall be considered optional, with the following properties
updates, specific for the ARM architected cache node.
- compatible
Usage: Required
Value type: <string>
Definition: value shall be "arm,arch-cache".
- interrupts
Usage: Optional
Value type: See definition
Definition: standard device tree property [3] that defines
the interrupt line associated with the cache.
The property can be accompanied by an
interrupt-names property, as described in [4].
- power-domain
Usage: Optional
Value type: phandle
Definition: A phandle and power domain specifier as defined by
bindings of power controller specified by the
phandle [5].
- qcom,dump-size
Usage: Optional
Value type: <integer>
Definition: The memory size needed to contain a copy of the
cache data and associated tag ram.
size = nways * nsets * (bytes per cache line +
bytes tag ram per line)
Example(dual-cluster big.LITTLE system 32-bit)
cpus {
#size-cells = <0>;
#address-cells = <1>;
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x0>;
next-level-cache = <&L1_0>;
L1_0: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_0>;
};
L2_0: l2-cache {
compatible = "arm,arch-cache";
};
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x1>;
next-level-cache = <&L1_1>;
L1_1: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_0>;
};
};
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x2>;
next-level-cache = <&L1_2>;
L1_2: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_0>;
};
};
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x3>;
next-level-cache = <&L1_3>;
L1_3: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_0>;
};
};
cpu@100 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x100>;
next-level-cache = <&L1_4>;
L1_4: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_1>;
};
L2_1: l2-cache {
compatible = "arm,arch-cache";
};
};
cpu@101 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x101>;
next-level-cache = <&L1_5>;
L1_5: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_1>;
};
};
cpu@102 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x102>;
next-level-cache = <&L1_6>;
L1_6: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_1>;
};
};
cpu@103 {
device_type = "cpu";
compatible = "arm,cortex-a7";
reg = <0x103>;
next-level-cache = <&L1_7>;
L1_7: l1-cache {
compatible = "arm,arch-cache";
next-level-cache = <&L2_1>;
};
};
};
[1] ARMv7-AR Reference Manual
http://infocenter.arm.com/help/index.jsp
[2] ARMv8-A Reference Manual
http://infocenter.arm.com/help/index.jsp
[3] ePAPR standard
https://www.power.org/documentation/epapr-version-1-1/
[4] Kernel documentation - resource property bindings
Documentation/devicetree/bindings/resource-names.txt
[5] Kernel documentation - power domain bindings
Documentation/devicetree/bindings/power/power_domain.txt

View file

@ -56,6 +56,7 @@ parameter is applicable:
BLACKFIN Blackfin architecture is enabled.
CLK Common clock infrastructure is enabled.
CMA Contiguous Memory Area support is enabled.
DM Device mapper support is enabled.
DRM Direct Rendering Management support is enabled.
DYNAMIC_DEBUG Build in debug messages and enable them at runtime
EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
@ -919,6 +920,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
dis_ucode_ldr [X86] Disable the microcode loader.
dm= [DM] Allows early creation of a device-mapper device.
See Documentation/device-mapper/boot.txt.
dma_debug=off If the kernel is compiled with DMA_API_DEBUG support,
this option disables the debugging code at boot.

View file

@ -113,6 +113,7 @@ dtb-$(CONFIG_ARCH_MSMCOBALT) += msmcobalt-sim.dtb \
msmcobalt-v2-cdp.dtb \
msmcobalt-v2-qrd.dtb \
msmcobalt-qrd-skuk.dtb \
msmcobalt-v2-qrd-skuk.dtb \
msmcobalt-qrd-vr1.dtb \
msmcobalt-v2-qrd-vr1.dtb \
apqcobalt-mtp.dtb \

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 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
@ -21,11 +21,6 @@
qcom,ion-heap-type = "SYSTEM";
};
system_contig_heap: qcom,ion-heap@21 {
reg = <21>;
qcom,ion-heap-type = "SYSTEM_CONTIG";
};
qcom,ion-heap@22 { /* ADSP HEAP */
reg = <22>;
memory-region = <&adsp_mem>;

View file

@ -21,11 +21,6 @@
qcom,ion-heap-type = "SYSTEM";
};
system_contig_heap: qcom,ion-heap@21 {
reg = <21>;
qcom,ion-heap-type = "SYSTEM_CONTIG";
};
qcom,ion-heap@22 { /* ADSP HEAP */
reg = <22>;
memory-region = <&adsp_mem>;

View file

@ -100,6 +100,16 @@
};
&pmcobalt_gpios {
/* GPIO 2 for Home Key */
gpio@c100 {
status = "okay";
qcom,mode = <0>;
qcom,pull = <0>;
qcom,vin-sel = <0>;
qcom,src-sel = <0>;
qcom,out-strength = <1>;
};
/* GPIO 6 for Vol+ Key */
gpio@c500 {
status = "okay";

View file

@ -0,0 +1,23 @@
/* Copyright (c) 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.
*/
/dts-v1/;
#include "msmcobalt-v2.dtsi"
#include "msmcobalt-qrd-skuk.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM COBALT V2 SKUK";
compatible = "qcom,msmcobalt-qrd", "qcom,msmcobalt", "qcom,qrd";
qcom,board-id = <0x01000b 0x80>;
};

View file

@ -2222,6 +2222,16 @@
qcom,sensors = <8>;
};
qcom,qbt1000 {
compatible = "qcom,qbt1000";
clock-names = "core", "iface";
clocks = <&clock_gcc clk_gcc_blsp2_qup6_spi_apps_clk>,
<&clock_gcc clk_gcc_blsp2_ahb_clk>;
clock-frequency = <15000000>;
qcom,ipc-gpio = <&tlmm 121 0>;
qcom,finger-detect-gpio = <&pmcobalt_gpios 2 0>;
};
qcom,sensor-information {
compatible = "qcom,sensor-information";
sensor_information0: qcom,sensor-information-0 {

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 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.
*/
#include "msmfalcon-pinctrl.dtsi"
/ {
aliases {
spi1 = &spi_1;
spi2 = &spi_2;
spi3 = &spi_3;
spi4 = &spi_4;
spi5 = &spi_5;
spi6 = &spi_6;
spi7 = &spi_7;
spi8 = &spi_8;
};
};
&soc {
spi_1: spi@c175000 { /* BLSP1 QUP1 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc175000 0x600>,
<0xc144000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 95 0>, <0 238 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <4>;
qcom,bam-producer-pipe-index = <5>;
qcom,master-id = <86>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_1_active>;
pinctrl-1 = <&spi_1_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>;
status = "disabled";
};
spi_2: spi@c176000 { /* BLSP1 QUP2 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc176000 0x600>,
<0xc144000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 96 0>, <0 238 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <6>;
qcom,bam-producer-pipe-index = <7>;
qcom,master-id = <86>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_2_active>;
pinctrl-1 = <&spi_2_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP2_SPI_APPS_CLK>;
status = "disabled";
};
spi_3: spi@c177000 { /* BLSP1 QUP3 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc177000 0x600>,
<0xc144000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 97 0>, <0 238 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <8>;
qcom,bam-producer-pipe-index = <9>;
qcom,master-id = <86>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_3_active>;
pinctrl-1 = <&spi_3_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP3_SPI_APPS_CLK>;
status = "disabled";
};
spi_4: spi@c178000 { /* BLSP1 QUP4 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc178000 0x600>,
<0xc144000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 98 0>, <0 238 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <10>;
qcom,bam-producer-pipe-index = <11>;
qcom,master-id = <86>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_4_active>;
pinctrl-1 = <&spi_4_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP1_AHB_CLK>,
<&clock_gcc GCC_BLSP1_QUP4_SPI_APPS_CLK>;
status = "disabled";
};
spi_5: spi@c1b5000 { /* BLSP2 QUP1 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc1b5000 0x600>,
<0xc184000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 101 0>, <0 239 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <4>;
qcom,bam-producer-pipe-index = <5>;
qcom,master-id = <84>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_5_active>;
pinctrl-1 = <&spi_5_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP1_SPI_APPS_CLK>;
status = "disabled";
};
spi_6: spi@c1b6000 { /* BLSP2 QUP2 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc1b6000 0x600>,
<0xc184000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 102 0>, <0 239 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <6>;
qcom,bam-producer-pipe-index = <7>;
qcom,master-id = <84>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_6_active>;
pinctrl-1 = <&spi_6_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>;
status = "disabled";
};
spi_7: spi@c1b7000 { /* BLSP2 QUP3 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc1b7000 0x600>,
<0xc184000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 103 0>, <0 239 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <8>;
qcom,bam-producer-pipe-index = <9>;
qcom,master-id = <84>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_7_active>;
pinctrl-1 = <&spi_7_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP3_SPI_APPS_CLK>;
status = "disabled";
};
spi_8: spi@c1b8000 { /* BLSP2 QUP4 */
compatible = "qcom,spi-qup-v2";
#address-cells = <1>;
#size-cells = <0>;
reg-names = "spi_physical", "spi_bam_physical";
reg = <0xc1b8000 0x600>,
<0xc184000 0x1f000>;
interrupt-names = "spi_irq", "spi_bam_irq";
interrupts = <0 104 0>, <0 239 0>;
spi-max-frequency = <50000000>;
qcom,use-bam;
qcom,ver-reg-exists;
qcom,bam-consumer-pipe-index = <10>;
qcom,bam-producer-pipe-index = <11>;
qcom,master-id = <84>;
qcom,use-pinctrl;
pinctrl-names = "spi_default", "spi_sleep";
pinctrl-0 = <&spi_8_active>;
pinctrl-1 = <&spi_8_sleep>;
clock-names = "iface_clk", "core_clk";
clocks = <&clock_gcc GCC_BLSP2_AHB_CLK>,
<&clock_gcc GCC_BLSP2_QUP4_SPI_APPS_CLK>;
status = "disabled";
};
};

View file

@ -21,11 +21,6 @@
qcom,ion-heap-type = "SYSTEM";
};
system_contig_heap: qcom,ion-heap@21 {
reg = <21>;
qcom,ion-heap-type = "SYSTEM_CONTIG";
};
qcom,ion-heap@22 { /* ADSP HEAP */
reg = <22>;
memory-region = <&adsp_mem>;

View file

@ -112,5 +112,262 @@
bias-pull-down; /* pull down */
};
};
/* SPI CONFIGURATION */
spi_1 {
spi_1_active: spi_1_active {
mux {
pins = "gpio0", "gpio1",
"gpio2", "gpio3";
function = "blsp_spi1";
};
config {
pins = "gpio0", "gpio1",
"gpio2", "gpio3";
drive-strength = <6>;
bias-disable;
};
};
spi_1_sleep: spi_1_sleep {
mux {
pins = "gpio0", "gpio1",
"gpio2", "gpio3";
function = "blsp_spi1";
};
config {
pins = "gpio0", "gpio1",
"gpio2", "gpio3";
drive-strength = <6>;
bias-disable;
};
};
};
spi_2 {
spi_2_active: spi_2_active {
mux {
pins = "gpio4", "gpio5",
"gpio6", "gpio7";
function = "blsp_spi2";
};
config {
pins = "gpio4", "gpio5",
"gpio6", "gpio7";
drive-strength = <6>;
bias-disable;
};
};
spi_2_sleep: spi_2_sleep {
mux {
pins = "gpio4", "gpio5",
"gpio6", "gpio7";
function = "blsp_spi2";
};
config {
pins = "gpio4", "gpio5",
"gpio6", "gpio7";
drive-strength = <6>;
bias-disable;
};
};
};
spi_3 {
spi_3_active: spi_3_active {
mux {
pins = "gpio8", "gpio9",
"gpio10", "gpio11";
function = "blsp_spi3";
};
config {
pins = "gpio8", "gpio9",
"gpio10", "gpio11";
drive-strength = <6>;
bias-disable;
};
};
spi_3_sleep: spi_3_sleep {
mux {
pins = "gpio8", "gpio9",
"gpio10", "gpio11";
function = "blsp_spi3";
};
config {
pins = "gpio8", "gpio9",
"gpio10", "gpio11";
drive-strength = <6>;
bias-disable;
};
};
};
spi_4 {
spi_4_active: spi_4_active {
mux {
pins = "gpio12", "gpio13",
"gpio14", "gpio15";
function = "blsp_spi4";
};
config {
pins = "gpio12", "gpio13",
"gpio14", "gpio15";
drive-strength = <6>;
bias-disable;
};
};
spi_4_sleep: spi_4_sleep {
mux {
pins = "gpio12", "gpio13",
"gpio14", "gpio15";
function = "blsp_spi4";
};
config {
pins = "gpio12", "gpio13",
"gpio14", "gpio15";
drive-strength = <6>;
bias-disable;
};
};
};
spi_5 {
spi_5_active: spi_5_active {
mux {
pins = "gpio16", "gpio17",
"gpio18", "gpio19";
function = "blsp_spi5";
};
config {
pins = "gpio16", "gpio17",
"gpio18", "gpio19";
drive-strength = <6>;
bias-disable;
};
};
spi_5_sleep: spi_5_sleep {
mux {
pins = "gpio16", "gpio17",
"gpio18", "gpio19";
function = "blsp_spi5";
};
config {
pins = "gpio16", "gpio17",
"gpio18", "gpio19";
drive-strength = <6>;
bias-disable;
};
};
};
spi_6 {
spi_6_active: spi_6_active {
mux {
pins = "gpio49", "gpio52",
"gpio22", "gpio23";
function = "blsp_spi6";
};
config {
pins = "gpio49", "gpio52",
"gpio22", "gpio23";
drive-strength = <6>;
bias-disable;
};
};
spi_6_sleep: spi_6_sleep {
mux {
pins = "gpio49", "gpio52",
"gpio22", "gpio23";
function = "blsp_spi6";
};
config {
pins = "gpio49", "gpio52",
"gpio22", "gpio23";
drive-strength = <6>;
bias-disable;
};
};
};
spi_7 {
spi_7_active: spi_7_active {
mux {
pins = "gpio24", "gpio25",
"gpio26", "gpio27";
function = "blsp_spi7";
};
config {
pins = "gpio24", "gpio25",
"gpio26", "gpio27";
drive-strength = <6>;
bias-disable;
};
};
spi_7_sleep: spi_7_sleep {
mux {
pins = "gpio24", "gpio25",
"gpio26", "gpio27";
function = "blsp_spi7";
};
config {
pins = "gpio24", "gpio25",
"gpio26", "gpio27";
drive-strength = <6>;
bias-disable;
};
};
};
spi_8 {
spi_8_active: spi_8_active {
mux {
pins = "gpio28", "gpio29",
"gpio30", "gpio31";
function = "blsp_spi8";
};
config {
pins = "gpio28", "gpio29",
"gpio30", "gpio31";
drive-strength = <6>;
bias-disable;
};
};
spi_8_sleep: spi_8_sleep {
mux {
pins = "gpio28", "gpio29",
"gpio30", "gpio31";
function = "blsp_spi8";
};
config {
pins = "gpio28", "gpio29",
"gpio30", "gpio31";
drive-strength = <6>;
bias-disable;
};
};
};
};
};

View file

@ -899,3 +899,4 @@
#include "msm-pm2falcon.dtsi"
#include "msm-arm-smmu-falcon.dtsi"
#include "msm-arm-smmu-impl-defs-falcon.dtsi"
#include "msmfalcon-blsp.dtsi"

View file

@ -21,11 +21,6 @@
qcom,ion-heap-type = "SYSTEM";
};
system_contig_heap: qcom,ion-heap@21 {
reg = <21>;
qcom,ion-heap-type = "SYSTEM_CONTIG";
};
qcom,ion-heap@22 { /* ADSP HEAP */
reg = <22>;
memory-region = <&adsp_mem>;

View file

@ -41,62 +41,62 @@
#address-cells = <2>;
#size-cells = <0>;
CPU0: cpu@0 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x0>;
enable-method = "psci";
};
CPU1: cpu@1 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x1>;
enable-method = "psci";
};
CPU2: cpu@2 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x2>;
enable-method = "psci";
};
CPU3: cpu@3 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x3>;
enable-method = "psci";
};
CPU4: cpu@100 {
CPU0: cpu@100 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x100>;
enable-method = "psci";
};
CPU5: cpu@101 {
CPU1: cpu@101 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x101>;
enable-method = "psci";
};
CPU6: cpu@102 {
CPU2: cpu@102 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x102>;
enable-method = "psci";
};
CPU7: cpu@103 {
CPU3: cpu@103 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x103>;
enable-method = "psci";
};
CPU4: cpu@0 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x0>;
enable-method = "psci";
};
CPU5: cpu@1 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x1>;
enable-method = "psci";
};
CPU6: cpu@2 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x2>;
enable-method = "psci";
};
CPU7: cpu@3 {
device_type = "cpu";
compatible = "arm,armv8";
reg = <0x0 0x3>;
enable-method = "psci";
};
cpu-map {
cluster0 {
core0 {

View file

@ -841,11 +841,29 @@ static struct kobject *get_device_parent(struct device *dev,
return NULL;
}
static inline bool live_in_glue_dir(struct kobject *kobj,
struct device *dev)
{
if (!kobj || !dev->class ||
kobj->kset != &dev->class->p->glue_dirs)
return false;
return true;
}
static inline struct kobject *get_glue_dir(struct device *dev)
{
return dev->kobj.parent;
}
/*
* make sure cleaning up dir as the last step, we need to make
* sure .release handler of kobject is run with holding the
* global lock
*/
static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
{
/* see if we live in a "glue" directory */
if (!glue_dir || !dev->class ||
glue_dir->kset != &dev->class->p->glue_dirs)
if (!live_in_glue_dir(glue_dir, dev))
return;
mutex_lock(&gdp_mutex);
@ -853,11 +871,6 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
mutex_unlock(&gdp_mutex);
}
static void cleanup_device_parent(struct device *dev)
{
cleanup_glue_dir(dev, dev->kobj.parent);
}
static int device_add_class_symlinks(struct device *dev)
{
struct device_node *of_node = dev_of_node(dev);
@ -1033,6 +1046,7 @@ int device_add(struct device *dev)
struct kobject *kobj;
struct class_interface *class_intf;
int error = -EINVAL;
struct kobject *glue_dir = NULL;
dev = get_device(dev);
if (!dev)
@ -1077,8 +1091,10 @@ int device_add(struct device *dev)
/* first, register with generic layer. */
/* we require the name to be set before, and pass NULL */
error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
if (error)
if (error) {
glue_dir = get_glue_dir(dev);
goto Error;
}
/* notify platform of device entry */
if (platform_notify)
@ -1159,9 +1175,10 @@ done:
device_remove_file(dev, &dev_attr_uevent);
attrError:
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
glue_dir = get_glue_dir(dev);
kobject_del(&dev->kobj);
Error:
cleanup_device_parent(dev);
cleanup_glue_dir(dev, glue_dir);
put_device(parent);
name_error:
kfree(dev->p);
@ -1237,6 +1254,7 @@ EXPORT_SYMBOL_GPL(put_device);
void device_del(struct device *dev)
{
struct device *parent = dev->parent;
struct kobject *glue_dir = NULL;
struct class_interface *class_intf;
/* Notify clients of device removal. This call must come
@ -1281,8 +1299,9 @@ void device_del(struct device *dev)
blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
BUS_NOTIFY_REMOVED_DEVICE, dev);
kobject_uevent(&dev->kobj, KOBJ_REMOVE);
cleanup_device_parent(dev);
glue_dir = get_glue_dir(dev);
kobject_del(&dev->kobj);
cleanup_glue_dir(dev, glue_dir);
put_device(parent);
}
EXPORT_SYMBOL_GPL(device_del);

View file

@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2007-2014, 2016, 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
@ -355,8 +355,12 @@ static int trace_clocks_show(struct seq_file *m, void *unused)
return 1;
}
list_for_each_entry(c, &clk_list, list) {
int vlevel = 0;
if (c->num_fmax)
vlevel = find_vdd_level(c, c->rate);
trace_clock_state(c->dbg_name, c->prepare_count, c->count,
c->rate);
c->rate, vlevel);
total_cnt++;
}
mutex_unlock(&clk_list_lock);

View file

@ -792,11 +792,14 @@ static int tmc_enable(struct tmc_drvdata *drvdata, enum tmc_mode mode)
drvdata->out_mode == TMC_ETR_OUT_MODE_USB) {
drvdata->usbch = usb_qdss_open("qdss", drvdata,
usb_notifier);
if (IS_ERR(drvdata->usbch)) {
if (IS_ERR_OR_NULL(drvdata->usbch)) {
dev_err(drvdata->dev, "usb_qdss_open failed\n");
ret = PTR_ERR(drvdata->usbch);
pm_runtime_put(drvdata->dev);
mutex_unlock(&drvdata->mem_lock);
if (!ret)
ret = -ENODEV;
return ret;
}
} else if (drvdata->config_type == TMC_CONFIG_TYPE_ETB ||
@ -1846,12 +1849,13 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
struct device_node *np = adev->dev.of_node;
struct coresight_cti_data *ctidata;
if (np) {
if (!np)
return -ENODEV;
pdata = of_get_coresight_platform_data(dev, np);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
adev->dev.platform_data = pdata;
}
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
if (!drvdata)

View file

@ -58,6 +58,7 @@
#define FLASH_LED_HDRM_VOL_MASK GENMASK(7, 4)
#define FLASH_LED_CURRENT_MASK GENMASK(6, 0)
#define FLASH_LED_ENABLE_MASK GENMASK(2, 0)
#define FLASH_HW_STROBE_MASK GENMASK(2, 0)
#define FLASH_LED_SAFETY_TMR_MASK GENMASK(7, 0)
#define FLASH_LED_INT_RT_STS_MASK GENMASK(7, 0)
#define FLASH_LED_ISC_WARMUP_DELAY_MASK GENMASK(1, 0)
@ -72,7 +73,7 @@
#define FLASH_LED_THERMAL_THRSH_MASK GENMASK(2, 0)
#define FLASH_LED_THERMAL_OTST_MASK GENMASK(2, 0)
#define FLASH_LED_MOD_CTRL_MASK BIT(7)
#define FLASH_LED_HW_SW_STROBE_SEL_MASK BIT(2)
#define FLASH_LED_HW_SW_STROBE_SEL_BIT BIT(2)
#define FLASH_LED_VPH_DROOP_FAULT_MASK BIT(4)
#define FLASH_LED_LMH_MITIGATION_EN_MASK BIT(0)
#define FLASH_LED_CHGR_MITIGATION_EN_MASK BIT(4)
@ -811,7 +812,7 @@ static int qpnp_flash_led_switch_disable(struct flash_switch_data *snode)
}
}
if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_MASK) {
if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
led->pdata->hw_strobe_option, false);
if (rc < 0) {
@ -831,7 +832,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
{
struct qpnp_flash_led *led = dev_get_drvdata(&snode->pdev->dev);
int rc, i, addr_offset;
u8 val;
u8 val, mask;
if (snode->enabled == on) {
dev_warn(&led->pdev->dev, "Switch node is already %s!\n",
@ -869,9 +870,13 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
continue;
addr_offset = led->fnode[i].id;
if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT)
mask = FLASH_HW_STROBE_MASK;
else
mask = FLASH_LED_HW_SW_STROBE_SEL_BIT;
rc = qpnp_flash_led_masked_write(led,
FLASH_LED_REG_STROBE_CTRL(led->base + addr_offset),
FLASH_LED_ENABLE_MASK, led->fnode[i].trigger);
mask, led->fnode[i].trigger);
if (rc < 0)
return rc;
@ -899,7 +904,7 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
}
}
if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_MASK) {
if (led->fnode[i].trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
rc = qpnp_flash_led_hw_strobe_enable(&led->fnode[i],
led->pdata->hw_strobe_option, true);
if (rc < 0) {
@ -1389,7 +1394,7 @@ static int qpnp_flash_led_parse_each_led_dt(struct qpnp_flash_led *led,
}
fnode->trigger = (strobe_sel << 2) | (edge_trigger << 1) | active_high;
if (fnode->trigger & FLASH_LED_HW_SW_STROBE_SEL_MASK) {
if (fnode->trigger & FLASH_LED_HW_SW_STROBE_SEL_BIT) {
if (of_find_property(node, "qcom,hw-strobe-gpio", NULL)) {
fnode->hw_strobe_gpio = of_get_named_gpio(node,
"qcom,hw-strobe-gpio", 0);

View file

@ -1923,6 +1923,45 @@ void dm_interface_exit(void)
dm_hash_exit();
}
/**
* dm_ioctl_export - Permanently export a mapped device via the ioctl interface
* @md: Pointer to mapped_device
* @name: Buffer (size DM_NAME_LEN) for name
* @uuid: Buffer (size DM_UUID_LEN) for uuid or NULL if not desired
*/
int dm_ioctl_export(struct mapped_device *md, const char *name,
const char *uuid)
{
int r = 0;
struct hash_cell *hc;
if (!md) {
r = -ENXIO;
goto out;
}
/* The name and uuid can only be set once. */
mutex_lock(&dm_hash_cells_mutex);
hc = dm_get_mdptr(md);
mutex_unlock(&dm_hash_cells_mutex);
if (hc) {
DMERR("%s: already exported", dm_device_name(md));
r = -ENXIO;
goto out;
}
r = dm_hash_insert(name, uuid, md);
if (r) {
DMERR("%s: could not bind to '%s'", dm_device_name(md), name);
goto out;
}
/* Let udev know we've changed. */
dm_kobject_uevent(md, KOBJ_CHANGE, dm_get_event_nr(md));
out:
return r;
}
/**
* dm_copy_name_and_uuid - Copy mapped device name & uuid into supplied buffers
* @md: Pointer to mapped_device

View file

@ -11,6 +11,7 @@
#include <linux/vmalloc.h>
#include <linux/blkdev.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/slab.h>

View file

@ -2344,7 +2344,6 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
return -EINVAL;
}
if (!new_frame->partial_frame_indicator) {
if (cpp_frame_msg[new_frame->msg_len - 1] !=
MSM_CPP_MSG_ID_TRAILER) {
pr_err("Invalid frame message\n");
@ -2359,7 +2358,6 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev,
new_frame->num_strips * stripe_size + 1));
return -EINVAL;
}
}
if (cpp_dev->iommu_state != CPP_IOMMU_STATE_ATTACHED) {
pr_err("IOMMU is not attached\n");

View file

@ -3705,6 +3705,10 @@ static void log_frame(struct msm_vidc_inst *inst, struct vidc_frame_data *data,
if (msm_comm_scale_clocks(inst->core))
dprintk(VIDC_WARN,
"Failed to scale clocks. Performance might be impacted\n");
if (msm_comm_vote_bus(inst->core))
dprintk(VIDC_WARN,
"Failed to scale bus. Performance might be impacted\n");
}
static int request_seq_header(struct msm_vidc_inst *inst,

View file

@ -157,7 +157,7 @@ struct dentry *msm_vidc_debugfs_init_drv(void)
struct dentry *f = debugfs_create_##__type(__name, S_IRUGO | S_IWUSR, \
dir, __value); \
if (IS_ERR_OR_NULL(f)) { \
dprintk(VIDC_ERR, "Failed creating debugfs file '%pKd/%s'\n", \
dprintk(VIDC_ERR, "Failed creating debugfs file '%pd/%s'\n", \
dir, __name); \
f = NULL; \
} \
@ -349,7 +349,7 @@ struct dentry *msm_vidc_debugfs_init_inst(struct msm_vidc_inst *inst,
dprintk(VIDC_ERR, "Invalid params, inst: %pK\n", inst);
goto failed_create_dir;
}
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst);
snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst);
dir = debugfs_create_dir(debugfs_name, parent);
if (!dir) {
dprintk(VIDC_ERR, "Failed to create debugfs for msm_vidc\n");

View file

@ -1323,6 +1323,9 @@ static void usb_bam_finish_suspend(enum usb_ctrl cur_bam)
__func__, ret);
goto no_lpm;
}
} else {
log_event_err("%s: pipe type is not B2B\n", __func__);
cons_empty = true;
}
spin_lock(&usb_bam_ipa_handshake_info_lock);
@ -1959,8 +1962,8 @@ static void usb_bam_finish_resume(struct work_struct *w)
spin_unlock(&usb_bam_ipa_handshake_info_lock);
mutex_unlock(&info[cur_bam].suspend_resume_mutex);
log_event_dbg("%s: done..PM Runtime PUT %d, count: %d\n",
__func__, idx, get_pm_runtime_counter(bam_dev));
log_event_dbg("%s: done..PM Runtime PUT :%d\n",
__func__, get_pm_runtime_counter(bam_dev));
/* Put to match _get at the beginning of this routine */
pm_runtime_put(&ctx->usb_bam_pdev->dev);
}
@ -2762,16 +2765,14 @@ static void usb_bam_sps_events(enum sps_callback_case sps_cb_case, void *user)
log_event_dbg("%s: received SPS_CALLBACK_BAM_TIMER_IRQ\n",
__func__);
spin_lock(&ctx->usb_bam_lock);
bam = get_bam_type_from_core_name((char *)user);
if (bam < 0 || bam >= MAX_BAMS) {
log_event_err("%s: Invalid bam, type=%d ,name=%s\n",
__func__, bam, (char *)user);
spin_unlock(&ctx->usb_bam_lock);
return;
}
ctx = &msm_usb_bam[bam];
spin_lock(&ctx->usb_bam_lock);
ctx->is_bam_inactivity = true;
log_event_dbg("%s: Inactivity happened on bam=%s,%d\n",

View file

@ -56,9 +56,16 @@ DEFINE_MUTEX(scm_lmh_lock);
#define SMC_ATOMIC_MASK 0x80000000
#define IS_CALL_AVAIL_CMD 1
#define SCM_BUF_LEN(__cmd_size, __resp_size) \
(sizeof(struct scm_command) + sizeof(struct scm_response) + \
__cmd_size + __resp_size)
#define SCM_BUF_LEN(__cmd_size, __resp_size) ({ \
size_t x = __cmd_size + __resp_size; \
size_t y = sizeof(struct scm_command) + sizeof(struct scm_response); \
size_t result; \
if (x < __cmd_size || (x + y) < x) \
result = 0; \
else \
result = x + y; \
result; \
})
/**
* struct scm_command - one SCM command buffer
* @len: total available memory for command and response
@ -356,8 +363,7 @@ int scm_call_noalloc(u32 svc_id, u32 cmd_id, const void *cmd_buf,
int ret;
size_t len = SCM_BUF_LEN(cmd_len, resp_len);
if (cmd_len > scm_buf_len || resp_len > scm_buf_len ||
len > scm_buf_len)
if (len == 0)
return -EINVAL;
if (!IS_ALIGNED((unsigned long)scm_buf, PAGE_SIZE))
@ -780,7 +786,7 @@ int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
int ret;
size_t len = SCM_BUF_LEN(cmd_len, resp_len);
if (cmd_len > len || resp_len > len)
if (len == 0 || PAGE_ALIGN(len) < len)
return -EINVAL;
cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);

View file

@ -52,7 +52,7 @@ struct mem_prot_info {
struct dest_vm_and_perm_info {
u32 vm;
u32 perm;
u32 *ctx;
u64 ctx;
u32 ctx_size;
};
@ -209,7 +209,7 @@ populate_dest_info(int *dest_vmids, int nelements, int *dest_perms,
for (i = 0; i < nelements; i++) {
dest_info[i].vm = dest_vmids[i];
dest_info[i].perm = dest_perms[i];
dest_info[i].ctx = NULL;
dest_info[i].ctx = 0x0;
dest_info[i].ctx_size = 0;
}

View file

@ -2,7 +2,7 @@
* drivers/staging/android/ion/ion_heap.c
*
* Copyright (C) 2011 Google, Inc.
* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
* Copyright (c) 2011-2016, 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
@ -325,8 +325,9 @@ struct ion_heap *ion_heap_create(struct ion_platform_heap *heap_data)
switch (heap_data->type) {
case ION_HEAP_TYPE_SYSTEM_CONTIG:
heap = ion_system_contig_heap_create(heap_data);
break;
pr_err("%s: Heap type is disabled: %d\n", __func__,
heap_data->type);
return ERR_PTR(-EINVAL);
case ION_HEAP_TYPE_SYSTEM:
heap = ion_system_heap_create(heap_data);
break;
@ -366,7 +367,8 @@ void ion_heap_destroy(struct ion_heap *heap)
switch (heap->type) {
case ION_HEAP_TYPE_SYSTEM_CONTIG:
ion_system_contig_heap_destroy(heap);
pr_err("%s: Heap type is disabled: %d\n", __func__,
heap->type);
break;
case ION_HEAP_TYPE_SYSTEM:
ion_system_heap_destroy(heap);

View file

@ -2130,24 +2130,11 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
struct dwc3 *dwc = gadget_to_dwc(g);
unsigned long flags;
pm_runtime_get_sync(dwc->dev);
dbg_event(0xFF, "Stop gsync",
atomic_read(&dwc->dev->power.usage_count));
dwc3_gadget_disable_irq(dwc);
spin_lock_irqsave(&dwc->lock, flags);
__dwc3_gadget_ep_disable(dwc->eps[0]);
__dwc3_gadget_ep_disable(dwc->eps[1]);
dwc->gadget_driver = NULL;
spin_unlock_irqrestore(&dwc->lock, flags);
pm_runtime_mark_last_busy(dwc->dev);
pm_runtime_put_autosuspend(dwc->dev);
dbg_event(0xFF, "Auto_susgsync", 0);
return 0;
}

View file

@ -2703,7 +2703,9 @@ static int mdss_fb_release_all(struct fb_info *info, bool release_all)
* enabling ahead of unblank. for some special cases like
* adb shell stop/start.
*/
mutex_lock(&mfd->bl_lock);
mdss_fb_set_backlight(mfd, 0);
mutex_unlock(&mfd->bl_lock);
ret = mdss_fb_blank_sub(FB_BLANK_POWERDOWN, info,
mfd->op_enable);

View file

@ -382,6 +382,12 @@ void dm_put(struct mapped_device *md);
void dm_set_mdptr(struct mapped_device *md, void *ptr);
void *dm_get_mdptr(struct mapped_device *md);
/*
* Export the device via the ioctl interface (uses mdptr).
*/
int dm_ioctl_export(struct mapped_device *md, const char *name,
const char *uuid);
/*
* A device can still be used while suspended, but I/O is deferred.
*/

View file

@ -796,11 +796,19 @@ struct cfg80211_csa_settings {
* @iftype_num: array with the number of interfaces of each interface
* type. The index is the interface type as specified in &enum
* nl80211_iftype.
* @beacon_int_gcd: a value specifying GCD of all beaconing interfaces,
* the GCD of a single value is considered the value itself, so for
* a single interface this should be set to that interface's beacon
* interval
* @beacon_int_different: a flag indicating whether or not all beacon
* intervals (of beaconing interfaces) are different or not.
*/
struct iface_combination_params {
int num_different_channels;
u8 radar_detect;
int iftype_num[NUM_NL80211_IFTYPES];
u32 beacon_int_gcd;
bool beacon_int_different;
};
/**
@ -2894,6 +2902,12 @@ struct ieee80211_iface_limit {
* only in special cases.
* @radar_detect_widths: bitmap of channel widths supported for radar detection
* @radar_detect_regions: bitmap of regions supported for radar detection
* @beacon_int_min_gcd: This interface combination supports different
* beacon intervals.
* = 0 - all beacon intervals for different interface must be same.
* > 0 - any beacon interval for the interface part of this combination AND
* *GCD* of all beacon intervals from beaconing interfaces of this
* combination must be greater or equal to this value.
*
* With this structure the driver can describe which interface
* combinations it supports concurrently.
@ -2952,6 +2966,7 @@ struct ieee80211_iface_combination {
bool beacon_int_infra_match;
u8 radar_detect_widths;
u8 radar_detect_regions;
u32 beacon_int_min_gcd;
};
struct ieee80211_txrx_stypes {

View file

@ -369,15 +369,17 @@ TRACE_EVENT(clock_set_parent,
TRACE_EVENT(clock_state,
TP_PROTO(const char *name, unsigned long prepare_count,
unsigned long count, unsigned long rate),
unsigned long count, unsigned long rate,
unsigned int vdd_level),
TP_ARGS(name, prepare_count, count, rate),
TP_ARGS(name, prepare_count, count, rate, vdd_level),
TP_STRUCT__entry(
__string(name, name)
__field(unsigned long, prepare_count)
__field(unsigned long, count)
__field(unsigned long, rate)
__field(unsigned int, vdd_level)
),
TP_fast_assign(
@ -385,10 +387,12 @@ TRACE_EVENT(clock_state,
__entry->prepare_count = prepare_count;
__entry->count = count;
__entry->rate = rate;
__entry->vdd_level = vdd_level;
),
TP_printk("%s\t[%lu:%lu]\t%lu", __get_str(name), __entry->prepare_count,
__entry->count, __entry->rate)
TP_printk("%s\tprepare:enable cnt [%lu:%lu]\trate: vdd level [%lu:%u]",
__get_str(name), __entry->prepare_count,
__entry->count, __entry->rate, __entry->vdd_level)
);
/*

View file

@ -4101,6 +4101,9 @@ enum nl80211_iface_limit_attrs {
* of supported channel widths for radar detection.
* @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
* of supported regulatory regions for radar detection.
* @NL80211_IFACE_COMB_BI_MIN_GCD: u32 attribute specifying the minimum GCD of
* different beacon intervals supported by all the interface combinations
* in this group (if not present, all beacon intervals be identical).
* @NUM_NL80211_IFACE_COMB: number of attributes
* @MAX_NL80211_IFACE_COMB: highest attribute number
*
@ -4108,8 +4111,8 @@ enum nl80211_iface_limit_attrs {
* limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2
* => allows an AP and a STA that must match BIs
*
* numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8
* => allows 8 of AP/GO
* numbers = [ #{AP, P2P-GO} <= 8 ], BI min gcd, channels = 1, max = 8,
* => allows 8 of AP/GO that can have BI gcd >= min gcd
*
* numbers = [ #{STA} <= 2 ], channels = 2, max = 2
* => allows two STAs on different channels
@ -4135,6 +4138,7 @@ enum nl80211_if_combination_attrs {
NL80211_IFACE_COMB_NUM_CHANNELS,
NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
NL80211_IFACE_COMB_BI_MIN_GCD,
/* keep last */
NUM_NL80211_IFACE_COMB,

View file

@ -15,6 +15,7 @@ mounts-y := do_mounts.o
mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o
mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o
mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o
mounts-$(CONFIG_BLK_DEV_DM) += do_mounts_dm.o
# dependencies on generated files need to be listed explicitly
$(obj)/version.o: include/generated/compile.h

View file

@ -566,6 +566,7 @@ void __init prepare_namespace(void)
wait_for_device_probe();
md_run_setup();
dm_run_setup();
if (saved_root_name[0]) {
root_device_name = saved_root_name;

View file

@ -13,9 +13,6 @@ void mount_block_root(char *name, int flags);
void mount_root(void);
extern int root_mountflags;
struct dm_table;
static inline void dm_table_put(struct dm_table *t) { }
static inline int create_dev(char *name, dev_t dev)
{
sys_unlink(name);
@ -77,3 +74,13 @@ void md_run_setup(void);
static inline void md_run_setup(void) {}
#endif
#ifdef CONFIG_BLK_DEV_DM
void dm_run_setup(void);
#else
static inline void dm_run_setup(void) {}
#endif

425
init/do_mounts_dm.c Normal file
View file

@ -0,0 +1,425 @@
/* do_mounts_dm.c
* Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org>
* All Rights Reserved.
* Based on do_mounts_md.c
*
* This file is released under the GPL.
*/
#include <linux/device-mapper.h>
#include <linux/fs.h>
#include <linux/string.h>
#include "do_mounts.h"
#include "../drivers/md/dm.h"
#define DM_MAX_NAME 32
#define DM_MAX_UUID 129
#define DM_NO_UUID "none"
#define DM_MSG_PREFIX "init"
/* Separators used for parsing the dm= argument. */
#define DM_FIELD_SEP ' '
#define DM_LINE_SEP ','
/*
* When the device-mapper and any targets are compiled into the kernel
* (not a module), one target may be created and used as the root device at
* boot time with the parameters given with the boot line dm=...
* The code for that is here.
*/
struct dm_setup_target {
sector_t begin;
sector_t length;
char *type;
char *params;
/* simple singly linked list */
struct dm_setup_target *next;
};
static struct {
int minor;
int ro;
char name[DM_MAX_NAME];
char uuid[DM_MAX_UUID];
char *targets;
struct dm_setup_target *target;
int target_count;
} dm_setup_args __initdata;
static __initdata int dm_early_setup;
static size_t __init get_dm_option(char *str, char **next, char sep)
{
size_t len = 0;
char *endp = NULL;
if (!str)
return 0;
endp = strchr(str, sep);
if (!endp) { /* act like strchrnul */
len = strlen(str);
endp = str + len;
} else {
len = endp - str;
}
if (endp == str)
return 0;
if (!next)
return len;
if (*endp == 0) {
/* Don't advance past the nul. */
*next = endp;
} else {
*next = endp + 1;
}
return len;
}
static int __init dm_setup_args_init(void)
{
dm_setup_args.minor = 0;
dm_setup_args.ro = 0;
dm_setup_args.target = NULL;
dm_setup_args.target_count = 0;
return 0;
}
static int __init dm_setup_cleanup(void)
{
struct dm_setup_target *target = dm_setup_args.target;
struct dm_setup_target *old_target = NULL;
while (target) {
kfree(target->type);
kfree(target->params);
old_target = target;
target = target->next;
kfree(old_target);
dm_setup_args.target_count--;
}
BUG_ON(dm_setup_args.target_count);
return 0;
}
static char * __init dm_setup_parse_device_args(char *str)
{
char *next = NULL;
size_t len = 0;
/* Grab the logical name of the device to be exported to udev */
len = get_dm_option(str, &next, DM_FIELD_SEP);
if (!len) {
DMERR("failed to parse device name");
goto parse_fail;
}
len = min(len + 1, sizeof(dm_setup_args.name));
strlcpy(dm_setup_args.name, str, len); /* includes nul */
str = skip_spaces(next);
/* Grab the UUID value or "none" */
len = get_dm_option(str, &next, DM_FIELD_SEP);
if (!len) {
DMERR("failed to parse device uuid");
goto parse_fail;
}
len = min(len + 1, sizeof(dm_setup_args.uuid));
strlcpy(dm_setup_args.uuid, str, len);
str = skip_spaces(next);
/* Determine if the table/device will be read only or read-write */
if (!strncmp("ro,", str, 3)) {
dm_setup_args.ro = 1;
} else if (!strncmp("rw,", str, 3)) {
dm_setup_args.ro = 0;
} else {
DMERR("failed to parse table mode");
goto parse_fail;
}
str = skip_spaces(str + 3);
return str;
parse_fail:
return NULL;
}
static void __init dm_substitute_devices(char *str, size_t str_len)
{
char *candidate = str;
char *candidate_end = str;
char old_char;
size_t len = 0;
dev_t dev;
if (str_len < 3)
return;
while (str && *str) {
candidate = strchr(str, '/');
if (!candidate)
break;
/* Avoid embedded slashes */
if (candidate != str && *(candidate - 1) != DM_FIELD_SEP) {
str = strchr(candidate, DM_FIELD_SEP);
continue;
}
len = get_dm_option(candidate, &candidate_end, DM_FIELD_SEP);
str = skip_spaces(candidate_end);
if (len < 3 || len > 37) /* name_to_dev_t max; maj:mix min */
continue;
/* Temporarily terminate with a nul */
candidate_end--;
old_char = *candidate_end;
*candidate_end = '\0';
DMDEBUG("converting candidate device '%s' to dev_t", candidate);
/* Use the boot-time specific device naming */
dev = name_to_dev_t(candidate);
*candidate_end = old_char;
DMDEBUG(" -> %u", dev);
/* No suitable replacement found */
if (!dev)
continue;
/* Rewrite the /dev/path as a major:minor */
len = snprintf(candidate, len, "%u:%u", MAJOR(dev), MINOR(dev));
if (!len) {
DMERR("error substituting device major/minor.");
break;
}
candidate += len;
/* Pad out with spaces (fixing our nul) */
while (candidate < candidate_end)
*(candidate++) = DM_FIELD_SEP;
}
}
static int __init dm_setup_parse_targets(char *str)
{
char *next = NULL;
size_t len = 0;
struct dm_setup_target **target = NULL;
/* Targets are defined as per the table format but with a
* comma as a newline separator. */
target = &dm_setup_args.target;
while (str && *str) {
*target = kzalloc(sizeof(struct dm_setup_target), GFP_KERNEL);
if (!*target) {
DMERR("failed to allocate memory for target %d",
dm_setup_args.target_count);
goto parse_fail;
}
dm_setup_args.target_count++;
(*target)->begin = simple_strtoull(str, &next, 10);
if (!next || *next != DM_FIELD_SEP) {
DMERR("failed to parse starting sector for target %d",
dm_setup_args.target_count - 1);
goto parse_fail;
}
str = skip_spaces(next + 1);
(*target)->length = simple_strtoull(str, &next, 10);
if (!next || *next != DM_FIELD_SEP) {
DMERR("failed to parse length for target %d",
dm_setup_args.target_count - 1);
goto parse_fail;
}
str = skip_spaces(next + 1);
len = get_dm_option(str, &next, DM_FIELD_SEP);
if (!len ||
!((*target)->type = kstrndup(str, len, GFP_KERNEL))) {
DMERR("failed to parse type for target %d",
dm_setup_args.target_count - 1);
goto parse_fail;
}
str = skip_spaces(next);
len = get_dm_option(str, &next, DM_LINE_SEP);
if (!len ||
!((*target)->params = kstrndup(str, len, GFP_KERNEL))) {
DMERR("failed to parse params for target %d",
dm_setup_args.target_count - 1);
goto parse_fail;
}
str = skip_spaces(next);
/* Before moving on, walk through the copied target and
* attempt to replace all /dev/xxx with the major:minor number.
* It may not be possible to resolve them traditionally at
* boot-time. */
dm_substitute_devices((*target)->params, len);
target = &((*target)->next);
}
DMDEBUG("parsed %d targets", dm_setup_args.target_count);
return 0;
parse_fail:
return 1;
}
/*
* Parse the command-line parameters given our kernel, but do not
* actually try to invoke the DM device now; that is handled by
* dm_setup_drive after the low-level disk drivers have initialised.
* dm format is as follows:
* dm="name uuid fmode,[table line 1],[table line 2],..."
* May be used with root=/dev/dm-0 as it always uses the first dm minor.
*/
static int __init dm_setup(char *str)
{
dm_setup_args_init();
str = dm_setup_parse_device_args(str);
if (!str) {
DMDEBUG("str is NULL");
goto parse_fail;
}
/* Target parsing is delayed until we have dynamic memory */
dm_setup_args.targets = str;
printk(KERN_INFO "dm: will configure '%s' on dm-%d\n",
dm_setup_args.name, dm_setup_args.minor);
dm_early_setup = 1;
return 1;
parse_fail:
printk(KERN_WARNING "dm: Invalid arguments supplied to dm=.\n");
return 0;
}
static void __init dm_setup_drive(void)
{
struct mapped_device *md = NULL;
struct dm_table *table = NULL;
struct dm_setup_target *target;
char *uuid = dm_setup_args.uuid;
fmode_t fmode = FMODE_READ;
/* Finish parsing the targets. */
if (dm_setup_parse_targets(dm_setup_args.targets))
goto parse_fail;
if (dm_create(dm_setup_args.minor, &md)) {
DMDEBUG("failed to create the device");
goto dm_create_fail;
}
DMDEBUG("created device '%s'", dm_device_name(md));
/* In addition to flagging the table below, the disk must be
* set explicitly ro/rw. */
set_disk_ro(dm_disk(md), dm_setup_args.ro);
if (!dm_setup_args.ro)
fmode |= FMODE_WRITE;
if (dm_table_create(&table, fmode, dm_setup_args.target_count, md)) {
DMDEBUG("failed to create the table");
goto dm_table_create_fail;
}
dm_lock_md_type(md);
target = dm_setup_args.target;
while (target) {
DMINFO("adding target '%llu %llu %s %s'",
(unsigned long long) target->begin,
(unsigned long long) target->length, target->type,
target->params);
if (dm_table_add_target(table, target->type, target->begin,
target->length, target->params)) {
DMDEBUG("failed to add the target to the table");
goto add_target_fail;
}
target = target->next;
}
if (dm_table_complete(table)) {
DMDEBUG("failed to complete the table");
goto table_complete_fail;
}
if (dm_get_md_type(md) == DM_TYPE_NONE) {
dm_set_md_type(md, dm_table_get_type(table));
if (dm_setup_md_queue(md)) {
DMWARN("unable to set up device queue for new table.");
goto setup_md_queue_fail;
}
} else if (dm_get_md_type(md) != dm_table_get_type(table)) {
DMWARN("can't change device type after initial table load.");
goto setup_md_queue_fail;
}
/* Suspend the device so that we can bind it to the table. */
if (dm_suspend(md, 0)) {
DMDEBUG("failed to suspend the device pre-bind");
goto suspend_fail;
}
/* Bind the table to the device. This is the only way to associate
* md->map with the table and set the disk capacity directly. */
if (dm_swap_table(md, table)) { /* should return NULL. */
DMDEBUG("failed to bind the device to the table");
goto table_bind_fail;
}
/* Finally, resume and the device should be ready. */
if (dm_resume(md)) {
DMDEBUG("failed to resume the device");
goto resume_fail;
}
/* Export the dm device via the ioctl interface */
if (!strcmp(DM_NO_UUID, dm_setup_args.uuid))
uuid = NULL;
if (dm_ioctl_export(md, dm_setup_args.name, uuid)) {
DMDEBUG("failed to export device with given name and uuid");
goto export_fail;
}
printk(KERN_INFO "dm: dm-%d is ready\n", dm_setup_args.minor);
dm_unlock_md_type(md);
dm_setup_cleanup();
return;
export_fail:
resume_fail:
table_bind_fail:
suspend_fail:
setup_md_queue_fail:
table_complete_fail:
add_target_fail:
dm_unlock_md_type(md);
dm_table_create_fail:
dm_put(md);
dm_create_fail:
dm_setup_cleanup();
parse_fail:
printk(KERN_WARNING "dm: starting dm-%d (%s) failed\n",
dm_setup_args.minor, dm_setup_args.name);
}
__setup("dm=", dm_setup);
void __init dm_run_setup(void)
{
if (!dm_early_setup)
return;
printk(KERN_INFO "dm: attempting early device configuration.\n");
dm_setup_drive();
}

View file

@ -2572,8 +2572,8 @@ void wake_up_new_task(struct task_struct *p)
unsigned long flags;
struct rq *rq;
raw_spin_lock_irqsave(&p->pi_lock, flags);
add_new_task_to_grp(p);
raw_spin_lock_irqsave(&p->pi_lock, flags);
/* Initialize new task's runnable average */
init_entity_runnable_average(&p->se);
#ifdef CONFIG_SMP

View file

@ -1396,16 +1396,6 @@ void reset_hmp_stats(struct hmp_sched_stats *stats, int reset_cra)
}
}
/*
* Invoked from three places:
* 1) try_to_wake_up() -> ... -> select_best_cpu()
* 2) scheduler_tick() -> ... -> migration_needed() -> select_best_cpu()
* 3) can_migrate_task()
*
* Its safe to de-reference p->grp in first case (since p->pi_lock is held)
* but not in other cases. p->grp is hence freed after a RCU grace period and
* accessed under rcu_read_lock()
*/
int preferred_cluster(struct sched_cluster *cluster, struct task_struct *p)
{
struct related_thread_group *grp;
@ -3883,7 +3873,12 @@ static void _set_preferred_cluster(struct related_thread_group *grp)
void set_preferred_cluster(struct related_thread_group *grp)
{
raw_spin_lock(&grp->lock);
/*
* Prevent possible deadlock with update_children(). Not updating
* the preferred cluster once is not a big deal.
*/
if (!raw_spin_trylock(&grp->lock))
return;
_set_preferred_cluster(grp);
raw_spin_unlock(&grp->lock);
}
@ -3904,7 +3899,7 @@ static int alloc_group_cputime(struct related_thread_group *grp)
struct rq *rq = cpu_rq(cpu);
u64 window_start = rq->window_start;
grp->cpu_time = alloc_percpu(struct group_cpu_time);
grp->cpu_time = alloc_percpu_gfp(struct group_cpu_time, GFP_ATOMIC);
if (!grp->cpu_time)
return -ENOMEM;
@ -4088,7 +4083,7 @@ struct related_thread_group *alloc_related_thread_group(int group_id)
{
struct related_thread_group *grp;
grp = kzalloc(sizeof(*grp), GFP_KERNEL);
grp = kzalloc(sizeof(*grp), GFP_ATOMIC);
if (!grp)
return ERR_PTR(-ENOMEM);
@ -4127,19 +4122,64 @@ static void free_related_thread_group(struct rcu_head *rcu)
kfree(grp);
}
/*
* The thread group for a task can change while we are here. However,
* add_new_task_to_grp() will take care of any tasks that we miss here.
* When a parent exits, and a child thread is simultaneously exiting,
* sched_set_group_id() will synchronize those operations.
*/
static void update_children(struct task_struct *leader,
struct related_thread_group *grp, int event)
{
struct task_struct *child;
struct rq *rq;
unsigned long flags;
if (!thread_group_leader(leader))
return;
if (event == ADD_TASK && !sysctl_sched_enable_thread_grouping)
return;
if (thread_group_empty(leader))
return;
child = next_thread(leader);
do {
rq = task_rq_lock(child, &flags);
if (event == REM_TASK && child->grp && grp == child->grp) {
transfer_busy_time(rq, grp, child, event);
list_del_init(&child->grp_list);
rcu_assign_pointer(child->grp, NULL);
} else if (event == ADD_TASK && !child->grp) {
transfer_busy_time(rq, grp, child, event);
list_add(&child->grp_list, &grp->tasks);
rcu_assign_pointer(child->grp, grp);
}
task_rq_unlock(rq, child, &flags);
} while_each_thread(leader, child);
}
static void remove_task_from_group(struct task_struct *p)
{
struct related_thread_group *grp = p->grp;
struct rq *rq;
int empty_group = 1;
unsigned long flags;
raw_spin_lock(&grp->lock);
rq = __task_rq_lock(p);
rq = task_rq_lock(p, &flags);
transfer_busy_time(rq, p->grp, p, REM_TASK);
list_del_init(&p->grp_list);
rcu_assign_pointer(p->grp, NULL);
__task_rq_unlock(rq);
task_rq_unlock(rq, p, &flags);
update_children(p, grp, REM_TASK);
if (!list_empty(&grp->tasks)) {
empty_group = 0;
@ -4158,6 +4198,7 @@ static int
add_task_to_group(struct task_struct *p, struct related_thread_group *grp)
{
struct rq *rq;
unsigned long flags;
raw_spin_lock(&grp->lock);
@ -4165,11 +4206,13 @@ add_task_to_group(struct task_struct *p, struct related_thread_group *grp)
* Change p->grp under rq->lock. Will prevent races with read-side
* reference of p->grp in various hot-paths
*/
rq = __task_rq_lock(p);
rq = task_rq_lock(p, &flags);
transfer_busy_time(rq, grp, p, ADD_TASK);
list_add(&p->grp_list, &grp->tasks);
rcu_assign_pointer(p->grp, grp);
__task_rq_unlock(rq);
task_rq_unlock(rq, p, &flags);
update_children(p, grp, ADD_TASK);
_set_preferred_cluster(grp);
@ -4192,82 +4235,62 @@ void add_new_task_to_grp(struct task_struct *new)
parent = new->group_leader;
/*
* The parent's pi_lock is required here to protect race
* against the parent task being removed from the
* group.
*/
raw_spin_lock_irqsave(&parent->pi_lock, flags);
write_lock_irqsave(&related_thread_group_lock, flags);
/* protected by pi_lock. */
rcu_read_lock();
grp = task_related_thread_group(parent);
if (!grp) {
raw_spin_unlock_irqrestore(&parent->pi_lock, flags);
rcu_read_unlock();
/* Its possible that update_children() already added us to the group */
if (!grp || new->grp) {
write_unlock_irqrestore(&related_thread_group_lock, flags);
return;
}
raw_spin_lock(&grp->lock);
rcu_assign_pointer(new->grp, grp);
list_add(&new->grp_list, &grp->tasks);
raw_spin_unlock(&grp->lock);
raw_spin_unlock_irqrestore(&parent->pi_lock, flags);
write_unlock_irqrestore(&related_thread_group_lock, flags);
}
int sched_set_group_id(struct task_struct *p, unsigned int group_id)
{
int rc = 0, destroy = 0;
int rc = 0;
unsigned long flags;
struct related_thread_group *grp = NULL, *new = NULL;
struct related_thread_group *grp = NULL;
redo:
raw_spin_lock_irqsave(&p->pi_lock, flags);
/* Prevents tasks from exiting while we are managing groups. */
write_lock_irqsave(&related_thread_group_lock, flags);
/* Switching from one group to another directly is not permitted */
if ((current != p && p->flags & PF_EXITING) ||
(!p->grp && !group_id) ||
(p->grp && p->grp->id == group_id))
(p->grp && group_id))
goto done;
write_lock(&related_thread_group_lock);
if (!group_id) {
remove_task_from_group(p);
write_unlock(&related_thread_group_lock);
goto done;
}
if (p->grp && p->grp->id != group_id)
remove_task_from_group(p);
grp = lookup_related_thread_group(group_id);
if (!grp && !new) {
/* New group */
write_unlock(&related_thread_group_lock);
raw_spin_unlock_irqrestore(&p->pi_lock, flags);
new = alloc_related_thread_group(group_id);
if (IS_ERR(new))
return -ENOMEM;
destroy = 1;
/* Rerun checks (like task exiting), since we dropped pi_lock */
goto redo;
} else if (!grp && new) {
/* New group - use object allocated before */
destroy = 0;
list_add(&new->list, &related_thread_groups);
grp = new;
if (!grp) {
grp = alloc_related_thread_group(group_id);
if (IS_ERR(grp)) {
rc = -ENOMEM;
goto done;
}
list_add(&grp->list, &related_thread_groups);
}
BUG_ON(!grp);
rc = add_task_to_group(p, grp);
write_unlock(&related_thread_group_lock);
done:
raw_spin_unlock_irqrestore(&p->pi_lock, flags);
if (new && destroy) {
free_group_cputime(new);
kfree(new);
}
write_unlock_irqrestore(&related_thread_group_lock, flags);
return rc;
}

View file

@ -466,7 +466,7 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
u32 *mask);
int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
u32 beacon_int);
enum nl80211_iftype iftype, u32 beacon_int);
void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
enum nl80211_iftype iftype, int num);

View file

@ -1003,6 +1003,10 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
c->radar_detect_regions)))
goto nla_put_failure;
if (c->beacon_int_min_gcd &&
nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
c->beacon_int_min_gcd))
goto nla_put_failure;
nla_nest_end(msg, nl_combi);
}
@ -3656,7 +3660,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
params.dtim_period =
nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
params.beacon_interval);
if (err)
return err;

View file

@ -1483,24 +1483,46 @@ bool ieee80211_chandef_to_operating_class(struct cfg80211_chan_def *chandef,
EXPORT_SYMBOL(ieee80211_chandef_to_operating_class);
int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
u32 beacon_int)
enum nl80211_iftype iftype, u32 beacon_int)
{
struct wireless_dev *wdev;
int res = 0;
struct iface_combination_params params = {
.beacon_int_gcd = beacon_int, /* GCD(n) = n */
};
if (!beacon_int)
return -EINVAL;
params.iftype_num[iftype] = 1;
list_for_each_entry(wdev, &rdev->wdev_list, list) {
if (!wdev->beacon_interval)
continue;
if (wdev->beacon_interval != beacon_int) {
res = -EINVAL;
break;
params.iftype_num[wdev->iftype]++;
}
list_for_each_entry(wdev, &rdev->wdev_list, list) {
u32 bi_prev = wdev->beacon_interval;
if (!wdev->beacon_interval)
continue;
/* slight optimisation - skip identical BIs */
if (wdev->beacon_interval == beacon_int)
continue;
params.beacon_int_different = true;
/* Get the GCD */
while (bi_prev != 0) {
u32 tmp_bi = bi_prev;
bi_prev = params.beacon_int_gcd % bi_prev;
params.beacon_int_gcd = tmp_bi;
}
}
return res;
return cfg80211_check_combinations(&rdev->wiphy, &params);
}
int cfg80211_iter_combinations(struct wiphy *wiphy,
@ -1576,6 +1598,17 @@ int cfg80211_iter_combinations(struct wiphy *wiphy,
if ((all_iftypes & used_iftypes) != used_iftypes)
goto cont;
if (params->beacon_int_gcd) {
if (c->beacon_int_min_gcd &&
params->beacon_int_gcd < c->beacon_int_min_gcd) {
kfree(limits);
return -EINVAL;
}
if (!c->beacon_int_min_gcd &&
params->beacon_int_different)
goto cont;
}
/* This combination covered all interface types and
* supported the requested numbers, so we're good.
*/

View file

@ -1015,6 +1015,7 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec,
0;
}
(*mbhc) = wcd934x_mbhc;
snd_soc_add_codec_controls(codec, impedance_detect_controls,
ARRAY_SIZE(impedance_detect_controls));
snd_soc_add_codec_controls(codec, hph_type_detect_controls,
@ -1023,8 +1024,6 @@ int tavil_mbhc_init(struct wcd934x_mbhc **mbhc, struct snd_soc_codec *codec,
snd_soc_update_bits(codec, WCD934X_MBHC_NEW_CTL_1, 0x04, 0x04);
snd_soc_update_bits(codec, WCD934X_MBHC_CTL_BCS, 0x01, 0x01);
(*mbhc) = wcd934x_mbhc;
return 0;
err:
devm_kfree(codec->dev, wcd934x_mbhc);

View file

@ -5136,7 +5136,7 @@ static int tavil_mad_input_put(struct snd_kcontrol *kcontrol,
snd_soc_update_bits(codec, WCD934X_SOC_MAD_INP_SEL,
0x0F, tavil_mad_input);
snd_soc_update_bits(codec, WCD934X_ANA_MAD_SETUP,
0x03, mic_bias_found);
0x07, mic_bias_found);
return 0;
}